From 80e66a8cbea1741b5d201ecbce2d8ce358cbf6d3 Mon Sep 17 00:00:00 2001 From: aden Date: Fri, 31 Jan 2025 07:34:51 +0700 Subject: [PATCH] upgrade to symfony 7.2 --- Dockerfile | 6 +- README.md | 40 +- Taskfile.yml | 2 +- composer.json | 121 +- composer.lock | 7311 +++++---- config/bundles.php | 1 - .../packages/gesdinet_jwt_refresh_token.yaml | 3 - config/packages/nelmio_cors.yaml | 2 +- config/packages/routing.yaml | 2 +- config/packages/security.yaml | 12 - config/routes/annotations.yaml | 10 +- config/services.yaml | 4 +- docker-compose.prod.yml | 1 - docker-compose.yml | 1 - fixtures/menu.yaml | 12 +- fixtures/permission.yaml | 20 +- fixtures/user.yaml | 2 +- lib/ApiClient/ApiClientRequestService.php | 13 +- lib/ApiClient/Message/RequestLog.php | 2 + lib/Controller/ApiClient/Audit.php | 2 +- lib/Controller/ApiClient/Delete.php | 2 +- lib/Controller/ApiClient/Get.php | 2 +- lib/Controller/ApiClient/GetAll.php | 2 +- lib/Controller/ApiClient/Post.php | 2 +- lib/Controller/ApiClient/Report.php | 2 +- lib/Controller/Cron/Audit.php | 2 +- lib/Controller/Cron/Delete.php | 2 +- lib/Controller/Cron/Get.php | 2 +- lib/Controller/Cron/GetAll.php | 2 +- lib/Controller/Cron/Post.php | 2 +- lib/Controller/Cron/Put.php | 2 +- lib/Controller/Cron/Report.php | 2 +- lib/Controller/Cron/Run.php | 2 +- lib/Controller/Group/Audit.php | 2 +- lib/Controller/Group/Delete.php | 2 +- lib/Controller/Group/Get.php | 2 +- lib/Controller/Group/GetAll.php | 2 +- lib/Controller/Group/Permission.php | 2 +- lib/Controller/Group/PermissionPut.php | 2 +- lib/Controller/Group/Post.php | 2 +- lib/Controller/Group/Put.php | 2 +- lib/Controller/Me/CreateApiClient.php | 2 +- lib/Controller/Me/DeleteApiClient.php | 2 +- lib/Controller/Me/GetApiClient.php | 2 +- lib/Controller/Me/Menu.php | 2 +- lib/Controller/Me/Profile.php | 2 +- lib/Controller/Me/Put.php | 2 +- lib/Controller/Media/Audit.php | 2 +- lib/Controller/Media/Delete.php | 2 +- lib/Controller/Media/Get.php | 2 +- lib/Controller/Media/GetAll.php | 2 +- lib/Controller/Media/Post.php | 2 +- lib/Controller/Menu/Audit.php | 2 +- lib/Controller/Menu/Delete.php | 2 +- lib/Controller/Menu/Get.php | 2 +- lib/Controller/Menu/GetAll.php | 2 +- lib/Controller/Menu/Post.php | 2 +- lib/Controller/Menu/Put.php | 2 +- lib/Controller/RefreshTokenController.php | 47 - lib/Controller/Setting/Audit.php | 2 +- lib/Controller/Setting/Delete.php | 2 +- lib/Controller/Setting/Get.php | 2 +- lib/Controller/Setting/GetAll.php | 2 +- lib/Controller/Setting/Post.php | 2 +- lib/Controller/Setting/Put.php | 2 +- lib/Controller/User/Audit.php | 2 +- lib/Controller/User/Delete.php | 2 +- lib/Controller/User/Get.php | 2 +- lib/Controller/User/GetAll.php | 2 +- lib/Controller/User/Post.php | 2 +- lib/Controller/User/Put.php | 2 +- lib/DataFixtures/AbstractFixture.php | 5 +- lib/Entity/Menu.php | 7 +- lib/EventSubscriber/LoadUrlPathSubscriber.php | 26 +- lib/EventSubscriber/PermissionSubscriber.php | 15 +- lib/EventSubscriber/SetFileUrlSubscriber.php | 26 +- lib/Media/AbstractStorage.php | 85 + lib/Media/Model/MediaRepositoryInterface.php | 2 +- lib/Media/Storage.php | 3 +- lib/Repository/AbstractRepository.php | 14 +- lib/Repository/MediaRepository.php | 2 +- lib/Repository/PermissionRepository.php | 44 +- lib/Repository/UserRepository.php | 4 +- lib/Security/AdminAuthenticator.php | 13 +- lib/Security/GroupIdGenerator.php | 4 +- lib/Security/Message/PasswordHistory.php | 2 + .../Service/GroupPermissionService.php | 23 +- .../Service/MenuPermissionService.php | 23 +- lib/Security/Service/MenuService.php | 2 +- .../Service/PasswordHistoryService.php | 13 +- lib/Security/Service/PermissionService.php | 14 +- lib/Security/Service/UserService.php | 32 +- lib/Service/AbstractService.php | 23 +- lib/Service/Message/EntityPersisted.php | 3 + lib/Service/Message/EntityRemoved.php | 3 + public/index.php | 16 - .../overlayScrollbars/js/OverlayScrollbars.js | 13306 ++++++++-------- .../js/jquery.overlayScrollbars.js | 11142 ++++++------- rector.php | 4 +- symfony.lock | 9 - templates/apiclient/all.html.twig | 124 +- templates/apiclient/audit.html.twig | 66 +- templates/apiclient/report.html.twig | 60 +- templates/base.html.twig | 16 +- .../SwaggerUi/index.html.twig | 14 +- templates/cron/all.html.twig | 126 +- templates/cron/audit.html.twig | 72 +- templates/cron/report.html.twig | 82 +- templates/cron/view.html.twig | 102 +- templates/dashboard/layout.html.twig | 8 +- templates/generator/admin/audit.php.twig | 24 +- templates/generator/admin/delete.php.twig | 30 +- templates/generator/admin/download.php.twig | 20 +- templates/generator/admin/get.php.twig | 36 +- templates/generator/admin/main.php.twig | 40 +- templates/generator/admin/put.php.twig | 28 +- templates/generator/admin/view/all.html.stub | 108 +- .../generator/admin/view/audit.html.stub | 56 +- .../admin/view/select2-all.html.stub | 114 +- templates/generator/admin/view/view.html.stub | 66 +- templates/generator/api/audit.php.twig | 24 +- templates/generator/api/delete.php.twig | 34 +- templates/generator/api/get.php.twig | 38 +- templates/generator/api/get_all.php.twig | 30 +- templates/generator/api/post.php.twig | 44 +- templates/generator/api/put.php.twig | 46 +- templates/generator/form.php.twig | 38 +- templates/generator/repository.php.twig | 18 +- templates/generator/repository_model.php.twig | 6 +- templates/generator/search_query.php.twig | 10 +- templates/generator/service.php.twig | 10 +- templates/group/all.html.twig | 110 +- templates/group/audit.html.twig | 56 +- templates/group/permission.html.twig | 146 +- templates/group/view.html.twig | 68 +- templates/layout/child_menu.html.twig | 6 +- templates/layout/content.html.twig | 10 +- templates/layout/footer.html.twig | 10 +- templates/layout/head.html.twig | 14 +- templates/layout/javascript.html.twig | 10 +- templates/layout/login.html.twig | 28 +- templates/layout/main.html.twig | 26 +- templates/layout/menu.html.twig | 18 +- templates/layout/navigation.html.twig | 6 +- templates/layout/notification.html.twig | 20 +- templates/layout/pagination.html.twig | 46 +- templates/media/all.html.twig | 128 +- templates/media/audit.html.twig | 78 +- templates/menu/all.html.twig | 146 +- templates/menu/audit.html.twig | 94 +- templates/menu/view.html.twig | 104 +- templates/profile/view.html.twig | 120 +- templates/setting/all.html.twig | 132 +- templates/setting/audit.html.twig | 72 +- templates/setting/view.html.twig | 82 +- templates/user/all.html.twig | 140 +- templates/user/audit.html.twig | 84 +- templates/user/view.html.twig | 96 +- 158 files changed, 18291 insertions(+), 17628 deletions(-) delete mode 100755 config/packages/gesdinet_jwt_refresh_token.yaml delete mode 100755 lib/Controller/RefreshTokenController.php create mode 100644 lib/Media/AbstractStorage.php diff --git a/Dockerfile b/Dockerfile index 9e233467..ba60a5a2 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,5 @@ FROM openswoole/swoole:latest-alpine -MAINTAINER Muhammad Surya Ihsanuddin - # Install Dependencies RUN apk update RUN apk add --no-cache supervisor vim autoconf gcc make g++ inotify-tools bash git @@ -15,8 +13,8 @@ RUN pecl bundle redis && cd redis && phpize && ./configure --enable-redis-igbina RUN docker-php-ext-enable igbinary redis inotify amqp apcu # Install PHP Core Extensions -RUN docker-php-ext-install curl intl mbstring zip bcmath imap opcache gd pdo_pgsql pcntl iconv sockets -RUN docker-php-ext-enable curl intl mbstring zip bcmath imap opcache gd pdo_pgsql pcntl iconv sockets +RUN docker-php-ext-install curl intl mbstring zip bcmath imap opcache gd pdo_pgsql pcntl sockets +RUN docker-php-ext-enable curl intl mbstring zip bcmath imap opcache gd pdo_pgsql pcntl sockets # Install Composer ADD docker/composer.sh /composer.sh diff --git a/README.md b/README.md index c3e0dd6b..74173ac2 100644 --- a/README.md +++ b/README.md @@ -444,37 +444,37 @@ Secara default, SemartApiSkeleton akan mengubah `bool` menjadi `string` (direpre Kita dapat mengubahnya melalui file `templates/todo/all.html.twig` sebagai berikut: ```twig -{% for property in properties %} - {% if 'id' != property.name %} +{%- for property in properties -%} + {%- if 'id' != property.name -%} - {{ ('sas.table.column.' ~ context ~ '.' ~ property.name) | trans({}, 'tables') }} + {{- ('sas.table.column.' ~ context ~ '.' ~ property.name) | trans({}, 'tables') -}} : - {% if 'done' == property.name %} - {% if todo.done %}Selesai{% else %}Belum Selesai{% endif %} - {% else %} - {{ semart_print(attribute(data, property.name)) }} - {% endif %} + {%- if 'done' == property.name -%} + {%- if todo.done -%} Selesai{%- else -%} Belum Selesai{%- endif -%} + {%- else -%} + {{- semart_print(attribute(data, property.name)) -}} + {%- endif -%} - {% endif %} -{% endfor %} + {%- endif -%} +{%- endfor -%} ``` Selain itu, kita juga perlu mengubah file `templates/todo/view.html.twig` sebagai berikut: ```twig -{% for property in properties %} - {% if 'id' != property.name %} +{%- for property in properties -%} + {%- if 'id' != property.name -%} - {{ ('sas.table.column.' ~ context ~ '.' ~ property.name) | trans({}, 'tables') }} + {{- ('sas.table.column.' ~ context ~ '.' ~ property.name) | trans({}, 'tables') -}} : - {% if 'done' == property.name %} - {% if data.done %}Selesai{% else %}Belum Selesai{% endif %} - {% else %} - {{ semart_print(attribute(data, property.name)) }} - {% endif %} + {%- if 'done' == property.name -%} + {%- if data.done -%} Selesai{%- else -%} Belum Selesai{%- endif -%} + {%- else -%} + {{- semart_print(attribute(data, property.name)) -}} + {%- endif -%} - {% endif %} -{% endfor %} + {%- endif -%} +{%- endfor -%} ``` Untuk lebih jelas tentang Twig Template, kamu dapat membaca dokumentasi resmi [Twig Template](https://twig.symfony.com) diff --git a/Taskfile.yml b/Taskfile.yml index a6b370df..08e79a41 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -8,7 +8,7 @@ tasks: - docker compose -f docker-compose.yml up --remove-orphans start: cmds: - - docker compose -f docker-compose.yml up --remove-orphans + - docker compose -f docker-compose.yml up -d --remove-orphans stop: cmds: - docker compose -f docker-compose.yml stop diff --git a/composer.json b/composer.json index 429e4f6f..a7b4c34b 100644 --- a/composer.json +++ b/composer.json @@ -16,74 +16,73 @@ } ], "require": { - "php": ">=8.1", + "php": "^8.4", "ext-ctype": "*", "ext-iconv": "*", "ext-json": "*", "ext-openssl": "*", "ext-pdo": "*", "ext-redis": "*", - "composer/composer": ">=2.0", - "cron/cron": ">=1.4", - "damienharper/auditor-bundle": ">=4.0", - "doctrine/annotations": ">=1.13", - "doctrine/dbal": "^2.13.6", - "doctrine/doctrine-bundle": ">=2.4", - "doctrine/orm": ">=2.9", - "friendsofphp/proxy-manager-lts": ">=1.0", - "friendsofsymfony/rest-bundle": ">=3.0", - "gesdinet/jwt-refresh-token-bundle": ">=v1.0.0", - "lexik/jwt-authentication-bundle": ">=2.11", - "nelmio/api-doc-bundle": ">=v4.0.1", - "nelmio/cors-bundle": ">=2.2", - "phpdocumentor/reflection-docblock": ">=5.2", - "ramsey/uuid-doctrine": ">=1.6", - "runtime/swoole": ">=0.2.1", - "snc/redis-bundle": ">=3.0", - "stof/doctrine-extensions-bundle": ">=1.4", - "symfony/amqp-messenger": ">=5.4", - "symfony/asset": ">=5.4", - "symfony/console": ">=5.4", - "symfony/doctrine-messenger": ">=5.4", - "symfony/dotenv": ">=5.4", - "symfony/flex": ">=1.3.1", - "symfony/form": ">=5.4", - "symfony/framework-bundle": ">=5.4", - "symfony/http-client": ">=5.4", - "symfony/lock": ">=5.4", - "symfony/messenger": ">=5.4", - "symfony/mime": ">=5.4", - "symfony/monolog-bundle": ">=3.5", - "symfony/property-access": ">=5.4", - "symfony/property-info": ">=5.4", - "symfony/rate-limiter": ">=5.4", - "symfony/runtime": ">=5.4", - "symfony/serializer": ">=5.4", - "symfony/string": ">=5.4", - "symfony/twig-bundle": ">=5.4", - "symfony/validator": ">=5.4", - "symfony/web-link": ">=5.4", - "symfony/yaml": ">=5.4", - "twig/extra-bundle": ">=3.0", - "twig/twig": ">=3.0", - "vich/uploader-bundle": ">=1.13" + "composer/composer": "^2.8", + "ad3n/cron": "^1.0", + "damienharper/auditor-bundle": "^6.2", + "doctrine/annotations": "^2.0", + "doctrine/dbal": "^4.2", + "doctrine/doctrine-bundle": "^2.13", + "doctrine/orm": "^3.3", + "friendsofphp/proxy-manager-lts": "^1.0", + "friendsofsymfony/rest-bundle": "^3.8", + "lexik/jwt-authentication-bundle": "^3.1", + "nelmio/api-doc-bundle": "^4.36", + "nelmio/cors-bundle": "^2.5", + "phpdocumentor/reflection-docblock": "^5.6", + "ramsey/uuid-doctrine": "^2.1", + "runtime/swoole": "^0.4", + "snc/redis-bundle": "^4.8", + "stof/doctrine-extensions-bundle": "^1.13", + "symfony/amqp-messenger": "^7.2", + "symfony/asset": "^7.2", + "symfony/console": "^7.2", + "symfony/doctrine-messenger": "^7.2", + "symfony/dotenv": "^7.2", + "symfony/flex": "^2.4", + "symfony/form": "^7.2", + "symfony/framework-bundle": "^7.2", + "symfony/http-client": "^7.2", + "symfony/lock": "^7.2", + "symfony/messenger": "^7.2", + "symfony/mime": "^7.2", + "symfony/monolog-bundle": "^3.10", + "symfony/property-access": "^7.2", + "symfony/property-info": "^7.2", + "symfony/rate-limiter": "^7.2", + "symfony/runtime": "^7.2", + "symfony/serializer": "^7.2", + "symfony/string": "^7.2", + "symfony/twig-bundle": "^7.2", + "symfony/validator": "^7.2", + "symfony/web-link": "^7.2", + "symfony/yaml": "^7.2", + "twig/extra-bundle": "^3.19", + "twig/twig": "^3.19", + "vich/uploader-bundle": "^2.5" }, "require-dev": { - "dg/bypass-finals": ">=1.3", - "doctrine/doctrine-fixtures-bundle": ">=3.3", - "friendsofphp/php-cs-fixer": ">=2.16", - "nunomaduro/phpinsights": ">=2.0", - "phpstan/phpstan": ">=1.1", - "phpunit/phpunit": ">=9.5", - "rector/rector": ">=0.12.7", - "swoole/ide-helper": ">=4.7", - "symfony/browser-kit": ">=5.4", - "symfony/css-selector": ">=5.4", - "symfony/debug-bundle": ">=5.4", - "symfony/maker-bundle": ">=1.19", - "symfony/phpunit-bridge": ">=5.4", - "symfony/stopwatch": ">=5.4", - "symfony/web-profiler-bundle": ">=5.4" + "dg/bypass-finals": "^1.9", + "doctrine/doctrine-fixtures-bundle": "^4.0", + "friendsofphp/php-cs-fixer": "^3.68", + "nunomaduro/phpinsights": "^2.12", + "phpstan/phpstan": "^2.1", + "phpunit/phpunit": "^11.5", + "rector/rector": "^2.0", + "swoole/ide-helper": "^6.0", + "symfony/browser-kit": "^7.2", + "symfony/css-selector": "^7.2", + "symfony/debug-bundle": "^7.2", + "symfony/maker-bundle": "^1.62", + "symfony/phpunit-bridge": "^7.2", + "symfony/stopwatch": "^7.2", + "symfony/web-profiler-bundle": "^7.2" }, "config": { "preferred-install": { @@ -138,7 +137,7 @@ "extra": { "symfony": { "allow-contrib": true, - "require": ">=5.4" + "require": "^7.2" } } } diff --git a/composer.lock b/composer.lock index 647c7c16..73e25854 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,57 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "7a3349c3e91e4c988186618705024449", + "content-hash": "61442d2c21ebd29c71cd8bbfc57acca4", "packages": [ + { + "name": "ad3n/cron", + "version": "v1.0.0", + "source": { + "type": "git", + "url": "https://github.com/ad3n/Cron.git", + "reference": "31a4956ada6c228bea4a21a1fa7a439e7e66a8b6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ad3n/Cron/zipball/31a4956ada6c228bea4a21a1fa7a439e7e66a8b6", + "reference": "31a4956ada6c228bea4a21a1fa7a439e7e66a8b6", + "shasum": "" + }, + "require": { + "php": "^8.0", + "symfony/process": "^4.0|^5.0|^6.0|^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^10.0", + "rector/rector": "^2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-4": { + "Cron\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Dries De Peuter", + "email": "dries@nousefreak.be" + } + ], + "description": "Cronjobs", + "support": { + "source": "https://github.com/ad3n/Cron/tree/v1.0.0" + }, + "time": "2025-01-30T13:21:31+00:00" + }, { "name": "behat/transliterator", "version": "v1.5.0", @@ -57,26 +106,25 @@ }, { "name": "brick/math", - "version": "0.10.2", + "version": "0.12.1", "source": { "type": "git", "url": "https://github.com/brick/math.git", - "reference": "459f2781e1a08d52ee56b0b1444086e038561e3f" + "reference": "f510c0a40911935b77b86859eb5223d58d660df1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/brick/math/zipball/459f2781e1a08d52ee56b0b1444086e038561e3f", - "reference": "459f2781e1a08d52ee56b0b1444086e038561e3f", + "url": "https://api.github.com/repos/brick/math/zipball/f510c0a40911935b77b86859eb5223d58d660df1", + "reference": "f510c0a40911935b77b86859eb5223d58d660df1", "shasum": "" }, "require": { - "ext-json": "*", - "php": "^7.4 || ^8.0" + "php": "^8.1" }, "require-dev": { "php-coveralls/php-coveralls": "^2.2", - "phpunit/phpunit": "^9.0", - "vimeo/psalm": "4.25.0" + "phpunit/phpunit": "^10.1", + "vimeo/psalm": "5.16.0" }, "type": "library", "autoload": { @@ -96,12 +144,17 @@ "arithmetic", "bigdecimal", "bignum", + "bignumber", "brick", - "math" + "decimal", + "integer", + "math", + "mathematics", + "rational" ], "support": { "issues": "https://github.com/brick/math/issues", - "source": "https://github.com/brick/math/tree/0.10.2" + "source": "https://github.com/brick/math/tree/0.12.1" }, "funding": [ { @@ -109,32 +162,32 @@ "type": "github" } ], - "time": "2022-08-10T22:54:19+00:00" + "time": "2023-11-29T23:19:16+00:00" }, { "name": "composer/ca-bundle", - "version": "1.3.3", + "version": "1.5.5", "source": { "type": "git", "url": "https://github.com/composer/ca-bundle.git", - "reference": "30897edbfb15e784fe55587b4f73ceefd3c4d98c" + "reference": "08c50d5ec4c6ced7d0271d2862dec8c1033283e6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/ca-bundle/zipball/30897edbfb15e784fe55587b4f73ceefd3c4d98c", - "reference": "30897edbfb15e784fe55587b4f73ceefd3c4d98c", + "url": "https://api.github.com/repos/composer/ca-bundle/zipball/08c50d5ec4c6ced7d0271d2862dec8c1033283e6", + "reference": "08c50d5ec4c6ced7d0271d2862dec8c1033283e6", "shasum": "" }, "require": { "ext-openssl": "*", "ext-pcre": "*", - "php": "^5.3.2 || ^7.0 || ^8.0" + "php": "^7.2 || ^8.0" }, "require-dev": { - "phpstan/phpstan": "^0.12.55", - "psr/log": "^1.0", - "symfony/phpunit-bridge": "^4.2 || ^5", - "symfony/process": "^2.5 || ^3.0 || ^4.0 || ^5.0 || ^6.0" + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^8 || ^9", + "psr/log": "^1.0 || ^2.0 || ^3.0", + "symfony/process": "^4.0 || ^5.0 || ^6.0 || ^7.0" }, "type": "library", "extra": { @@ -169,7 +222,7 @@ "support": { "irc": "irc://irc.freenode.org/composer", "issues": "https://github.com/composer/ca-bundle/issues", - "source": "https://github.com/composer/ca-bundle/tree/1.3.3" + "source": "https://github.com/composer/ca-bundle/tree/1.5.5" }, "funding": [ { @@ -185,34 +238,34 @@ "type": "tidelift" } ], - "time": "2022-07-20T07:14:26+00:00" + "time": "2025-01-08T16:17:16+00:00" }, { "name": "composer/class-map-generator", - "version": "1.0.0", + "version": "1.5.0", "source": { "type": "git", "url": "https://github.com/composer/class-map-generator.git", - "reference": "1e1cb2b791facb2dfe32932a7718cf2571187513" + "reference": "4b0a223cf5be7c9ee7e0ef1bc7db42b4a97c9915" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/class-map-generator/zipball/1e1cb2b791facb2dfe32932a7718cf2571187513", - "reference": "1e1cb2b791facb2dfe32932a7718cf2571187513", + "url": "https://api.github.com/repos/composer/class-map-generator/zipball/4b0a223cf5be7c9ee7e0ef1bc7db42b4a97c9915", + "reference": "4b0a223cf5be7c9ee7e0ef1bc7db42b4a97c9915", "shasum": "" }, "require": { - "composer/pcre": "^2 || ^3", + "composer/pcre": "^2.1 || ^3.1", "php": "^7.2 || ^8.0", - "symfony/finder": "^4.4 || ^5.3 || ^6" + "symfony/finder": "^4.4 || ^5.3 || ^6 || ^7" }, "require-dev": { - "phpstan/phpstan": "^1.6", - "phpstan/phpstan-deprecation-rules": "^1", - "phpstan/phpstan-phpunit": "^1", - "phpstan/phpstan-strict-rules": "^1.1", - "symfony/filesystem": "^5.4 || ^6", - "symfony/phpunit-bridge": "^5" + "phpstan/phpstan": "^1.12 || ^2", + "phpstan/phpstan-deprecation-rules": "^1 || ^2", + "phpstan/phpstan-phpunit": "^1 || ^2", + "phpstan/phpstan-strict-rules": "^1.1 || ^2", + "phpunit/phpunit": "^8", + "symfony/filesystem": "^5.4 || ^6" }, "type": "library", "extra": { @@ -242,7 +295,7 @@ ], "support": { "issues": "https://github.com/composer/class-map-generator/issues", - "source": "https://github.com/composer/class-map-generator/tree/1.0.0" + "source": "https://github.com/composer/class-map-generator/tree/1.5.0" }, "funding": [ { @@ -258,51 +311,52 @@ "type": "tidelift" } ], - "time": "2022-06-19T11:31:27+00:00" + "time": "2024-11-25T16:11:06+00:00" }, { "name": "composer/composer", - "version": "2.4.1", + "version": "2.8.5", "source": { "type": "git", "url": "https://github.com/composer/composer.git", - "reference": "777d542e3af65f8e7a66a4d98ce7a697da339414" + "reference": "ae208dc1e182bd45d99fcecb956501da212454a1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/composer/zipball/777d542e3af65f8e7a66a4d98ce7a697da339414", - "reference": "777d542e3af65f8e7a66a4d98ce7a697da339414", + "url": "https://api.github.com/repos/composer/composer/zipball/ae208dc1e182bd45d99fcecb956501da212454a1", + "reference": "ae208dc1e182bd45d99fcecb956501da212454a1", "shasum": "" }, "require": { - "composer/ca-bundle": "^1.0", - "composer/class-map-generator": "^1.0", + "composer/ca-bundle": "^1.5", + "composer/class-map-generator": "^1.4.0", "composer/metadata-minifier": "^1.0", - "composer/pcre": "^2 || ^3", - "composer/semver": "^3.0", + "composer/pcre": "^2.2 || ^3.2", + "composer/semver": "^3.3", "composer/spdx-licenses": "^1.5.7", "composer/xdebug-handler": "^2.0.2 || ^3.0.3", - "justinrainbow/json-schema": "^5.2.11", + "justinrainbow/json-schema": "^5.3", "php": "^7.2.5 || ^8.0", "psr/log": "^1.0 || ^2.0 || ^3.0", - "react/promise": "^2.8", + "react/promise": "^2.11 || ^3.2", "seld/jsonlint": "^1.4", "seld/phar-utils": "^1.2", "seld/signal-handler": "^2.0", - "symfony/console": "^5.4.11 || ^6.0.11", - "symfony/filesystem": "^5.4 || ^6.0", - "symfony/finder": "^5.4 || ^6.0", + "symfony/console": "^5.4.35 || ^6.3.12 || ^7.0.3", + "symfony/filesystem": "^5.4.35 || ^6.3.12 || ^7.0.3", + "symfony/finder": "^5.4.35 || ^6.3.12 || ^7.0.3", "symfony/polyfill-php73": "^1.24", "symfony/polyfill-php80": "^1.24", - "symfony/process": "^5.4 || ^6.0" + "symfony/polyfill-php81": "^1.24", + "symfony/process": "^5.4.35 || ^6.3.12 || ^7.0.3" }, "require-dev": { - "phpstan/phpstan": "^1.4.1", - "phpstan/phpstan-deprecation-rules": "^1", - "phpstan/phpstan-phpunit": "^1.0", - "phpstan/phpstan-strict-rules": "^1", - "phpstan/phpstan-symfony": "^1.1", - "symfony/phpunit-bridge": "^6.0" + "phpstan/phpstan": "^1.11.8", + "phpstan/phpstan-deprecation-rules": "^1.2.0", + "phpstan/phpstan-phpunit": "^1.4.0", + "phpstan/phpstan-strict-rules": "^1.6.0", + "phpstan/phpstan-symfony": "^1.4.0", + "symfony/phpunit-bridge": "^6.4.3 || ^7.0.1" }, "suggest": { "ext-openssl": "Enabling the openssl extension allows you to access https URLs for repositories and packages", @@ -314,18 +368,18 @@ ], "type": "library", "extra": { - "branch-alias": { - "dev-main": "2.4-dev" - }, "phpstan": { "includes": [ "phpstan/rules.neon" ] + }, + "branch-alias": { + "dev-main": "2.8-dev" } }, "autoload": { "psr-4": { - "Composer\\": "src/Composer" + "Composer\\": "src/Composer/" } }, "notification-url": "https://packagist.org/downloads/", @@ -354,7 +408,8 @@ "support": { "irc": "ircs://irc.libera.chat:6697/composer", "issues": "https://github.com/composer/composer/issues", - "source": "https://github.com/composer/composer/tree/2.4.1" + "security": "https://github.com/composer/composer/security/policy", + "source": "https://github.com/composer/composer/tree/2.8.5" }, "funding": [ { @@ -370,7 +425,7 @@ "type": "tidelift" } ], - "time": "2022-08-20T09:44:50+00:00" + "time": "2025-01-21T14:23:40+00:00" }, { "name": "composer/metadata-minifier", @@ -443,28 +498,36 @@ }, { "name": "composer/pcre", - "version": "3.0.0", + "version": "3.3.2", "source": { "type": "git", "url": "https://github.com/composer/pcre.git", - "reference": "e300eb6c535192decd27a85bc72a9290f0d6b3bd" + "reference": "b2bed4734f0cc156ee1fe9c0da2550420d99a21e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/pcre/zipball/e300eb6c535192decd27a85bc72a9290f0d6b3bd", - "reference": "e300eb6c535192decd27a85bc72a9290f0d6b3bd", + "url": "https://api.github.com/repos/composer/pcre/zipball/b2bed4734f0cc156ee1fe9c0da2550420d99a21e", + "reference": "b2bed4734f0cc156ee1fe9c0da2550420d99a21e", "shasum": "" }, "require": { "php": "^7.4 || ^8.0" }, + "conflict": { + "phpstan/phpstan": "<1.11.10" + }, "require-dev": { - "phpstan/phpstan": "^1.3", - "phpstan/phpstan-strict-rules": "^1.1", - "symfony/phpunit-bridge": "^5" + "phpstan/phpstan": "^1.12 || ^2", + "phpstan/phpstan-strict-rules": "^1 || ^2", + "phpunit/phpunit": "^8 || ^9" }, "type": "library", "extra": { + "phpstan": { + "includes": [ + "extension.neon" + ] + }, "branch-alias": { "dev-main": "3.x-dev" } @@ -494,7 +557,7 @@ ], "support": { "issues": "https://github.com/composer/pcre/issues", - "source": "https://github.com/composer/pcre/tree/3.0.0" + "source": "https://github.com/composer/pcre/tree/3.3.2" }, "funding": [ { @@ -510,28 +573,28 @@ "type": "tidelift" } ], - "time": "2022-02-25T20:21:48+00:00" + "time": "2024-11-12T16:29:46+00:00" }, { "name": "composer/semver", - "version": "3.3.2", + "version": "3.4.3", "source": { "type": "git", "url": "https://github.com/composer/semver.git", - "reference": "3953f23262f2bff1919fc82183ad9acb13ff62c9" + "reference": "4313d26ada5e0c4edfbd1dc481a92ff7bff91f12" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/semver/zipball/3953f23262f2bff1919fc82183ad9acb13ff62c9", - "reference": "3953f23262f2bff1919fc82183ad9acb13ff62c9", + "url": "https://api.github.com/repos/composer/semver/zipball/4313d26ada5e0c4edfbd1dc481a92ff7bff91f12", + "reference": "4313d26ada5e0c4edfbd1dc481a92ff7bff91f12", "shasum": "" }, "require": { "php": "^5.3.2 || ^7.0 || ^8.0" }, "require-dev": { - "phpstan/phpstan": "^1.4", - "symfony/phpunit-bridge": "^4.2 || ^5" + "phpstan/phpstan": "^1.11", + "symfony/phpunit-bridge": "^3 || ^7" }, "type": "library", "extra": { @@ -573,9 +636,9 @@ "versioning" ], "support": { - "irc": "irc://irc.freenode.org/composer", + "irc": "ircs://irc.libera.chat:6697/composer", "issues": "https://github.com/composer/semver/issues", - "source": "https://github.com/composer/semver/tree/3.3.2" + "source": "https://github.com/composer/semver/tree/3.4.3" }, "funding": [ { @@ -591,20 +654,20 @@ "type": "tidelift" } ], - "time": "2022-04-01T19:23:25+00:00" + "time": "2024-09-19T14:15:21+00:00" }, { "name": "composer/spdx-licenses", - "version": "1.5.7", + "version": "1.5.8", "source": { "type": "git", "url": "https://github.com/composer/spdx-licenses.git", - "reference": "c848241796da2abf65837d51dce1fae55a960149" + "reference": "560bdcf8deb88ae5d611c80a2de8ea9d0358cc0a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/spdx-licenses/zipball/c848241796da2abf65837d51dce1fae55a960149", - "reference": "c848241796da2abf65837d51dce1fae55a960149", + "url": "https://api.github.com/repos/composer/spdx-licenses/zipball/560bdcf8deb88ae5d611c80a2de8ea9d0358cc0a", + "reference": "560bdcf8deb88ae5d611c80a2de8ea9d0358cc0a", "shasum": "" }, "require": { @@ -653,9 +716,9 @@ "validator" ], "support": { - "irc": "irc://irc.freenode.org/composer", + "irc": "ircs://irc.libera.chat:6697/composer", "issues": "https://github.com/composer/spdx-licenses/issues", - "source": "https://github.com/composer/spdx-licenses/tree/1.5.7" + "source": "https://github.com/composer/spdx-licenses/tree/1.5.8" }, "funding": [ { @@ -671,20 +734,20 @@ "type": "tidelift" } ], - "time": "2022-05-23T07:37:50+00:00" + "time": "2023-11-20T07:44:33+00:00" }, { "name": "composer/xdebug-handler", - "version": "3.0.3", + "version": "3.0.5", "source": { "type": "git", "url": "https://github.com/composer/xdebug-handler.git", - "reference": "ced299686f41dce890debac69273b47ffe98a40c" + "reference": "6c1925561632e83d60a44492e0b344cf48ab85ef" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/ced299686f41dce890debac69273b47ffe98a40c", - "reference": "ced299686f41dce890debac69273b47ffe98a40c", + "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/6c1925561632e83d60a44492e0b344cf48ab85ef", + "reference": "6c1925561632e83d60a44492e0b344cf48ab85ef", "shasum": "" }, "require": { @@ -695,7 +758,7 @@ "require-dev": { "phpstan/phpstan": "^1.0", "phpstan/phpstan-strict-rules": "^1.1", - "symfony/phpunit-bridge": "^6.0" + "phpunit/phpunit": "^8.5 || ^9.6 || ^10.5" }, "type": "library", "autoload": { @@ -719,9 +782,9 @@ "performance" ], "support": { - "irc": "irc://irc.freenode.org/composer", + "irc": "ircs://irc.libera.chat:6697/composer", "issues": "https://github.com/composer/xdebug-handler/issues", - "source": "https://github.com/composer/xdebug-handler/tree/3.0.3" + "source": "https://github.com/composer/xdebug-handler/tree/3.0.5" }, "funding": [ { @@ -737,89 +800,37 @@ "type": "tidelift" } ], - "time": "2022-02-25T21:32:43+00:00" - }, - { - "name": "cron/cron", - "version": "1.6.0", - "source": { - "type": "git", - "url": "https://github.com/Cron/Cron.git", - "reference": "103d8562aca8a5fd135c69b3fe93aad0b5b701d4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Cron/Cron/zipball/103d8562aca8a5fd135c69b3fe93aad0b5b701d4", - "reference": "103d8562aca8a5fd135c69b3fe93aad0b5b701d4", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0", - "symfony/process": "^4.0|^5.0|^6.0" - }, - "require-dev": { - "phpunit/phpunit": "^8.0 || ^9.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0-dev" - } - }, - "autoload": { - "psr-4": { - "Cron\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Dries De Peuter", - "email": "dries@nousefreak.be" - } - ], - "description": "Cronjobs", - "support": { - "issues": "https://github.com/Cron/Cron/issues", - "source": "https://github.com/Cron/Cron/tree/1.6.0" - }, - "time": "2021-12-29T12:06:58+00:00" + "time": "2024-05-06T16:37:16+00:00" }, { "name": "damienharper/auditor", - "version": "2.0.5", + "version": "3.3.3", "source": { "type": "git", "url": "https://github.com/DamienHarper/auditor.git", - "reference": "1dc7a65015f5943048afd298291c61da4251cbbf" + "reference": "7ef7125a0aef1436ad545c8e6c7ab3672320e76b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/DamienHarper/auditor/zipball/1dc7a65015f5943048afd298291c61da4251cbbf", - "reference": "1dc7a65015f5943048afd298291c61da4251cbbf", + "url": "https://api.github.com/repos/DamienHarper/auditor/zipball/7ef7125a0aef1436ad545c8e6c7ab3672320e76b", + "reference": "7ef7125a0aef1436ad545c8e6c7ab3672320e76b", "shasum": "" }, "require": { - "doctrine/annotations": "^1.8", - "doctrine/orm": "^2.7", - "ext-json": "*", - "php": ">=7.4", - "symfony/cache": "^4.0|^5.0|^6.0", - "symfony/event-dispatcher": "^4.0|^5.0|^6.0", - "symfony/lock": "^4.0|^5.0|^6.0", - "symfony/options-resolver": "^4.0|^5.0|^6.0" - }, - "conflict": { - "doctrine/persistence": "<1.3" + "doctrine/dbal": "^3.2|^4.0", + "doctrine/orm": "^2.13|^3.2", + "php": ">=8.2", + "symfony/cache": "^5.4|^6.0|^7.0", + "symfony/event-dispatcher": "^5.4|^6.0|^7.0", + "symfony/lock": "^5.4|^6.0|^7.0", + "symfony/options-resolver": "^5.4|^6.0|^7.0" }, "require-dev": { - "doctrine/data-fixtures": "^1.4.4", - "gedmo/doctrine-extensions": "^2.4|^3.0", - "phpunit/phpunit": "^9.0", - "symfony/var-dumper": "^4.0|^5.0|^6.0" + "doctrine/data-fixtures": "^1.5.3", + "ext-pdo": "*", + "gedmo/doctrine-extensions": "^3.0", + "phpunit/phpunit": "^11.0", + "symfony/var-dumper": "^5.4|^6.0|^7.0" }, "suggest": { "damienharper/auditor-bundle": "Integrate auditor library in your Symfony projects." @@ -827,8 +838,9 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.x-dev", - "dev-1.x": "1.x-dev" + "dev-1.x": "1.x-dev", + "dev-2.x": "2.x-dev", + "dev-master": "3.x-dev" } }, "autoload": { @@ -855,61 +867,57 @@ ], "support": { "issues": "https://github.com/DamienHarper/auditor/issues", - "source": "https://github.com/DamienHarper/auditor/tree/2.0.5" + "source": "https://github.com/DamienHarper/auditor/tree/3.3.3" }, - "time": "2022-08-07T15:10:30+00:00" + "time": "2025-01-14T07:47:19+00:00" }, { "name": "damienharper/auditor-bundle", - "version": "5.0.3", + "version": "6.2.1", "source": { "type": "git", "url": "https://github.com/DamienHarper/auditor-bundle.git", - "reference": "687f6c8e8251e54e45e3a6df8d04ca2a8b9a5a77" + "reference": "092f35aade375d1e6bbacec31b5a84cd0b044cc0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/DamienHarper/auditor-bundle/zipball/687f6c8e8251e54e45e3a6df8d04ca2a8b9a5a77", - "reference": "687f6c8e8251e54e45e3a6df8d04ca2a8b9a5a77", + "url": "https://api.github.com/repos/DamienHarper/auditor-bundle/zipball/092f35aade375d1e6bbacec31b5a84cd0b044cc0", + "reference": "092f35aade375d1e6bbacec31b5a84cd0b044cc0", "shasum": "" }, "require": { - "damienharper/auditor": "^2.0", - "doctrine/annotations": "^1.8", - "doctrine/doctrine-bundle": "^1.9|^2.0", - "doctrine/orm": "^2.7", - "ext-json": "*", - "php": ">=7.4", - "symfony/asset": "^4.0|^5.0|^6.0", - "symfony/doctrine-bridge": "^4.4.19|^5.2.2|^6.0", - "symfony/event-dispatcher": "^4.0|^5.0|^6.0", - "symfony/lock": "^4.0|^5.0|^6.0", - "symfony/security-bundle": "^4.0|^5.0|^6.0", - "symfony/translation": "^4.0|^5.0|^6.0", - "symfony/twig-bundle": "^4.0|^5.0|^6.0", + "damienharper/auditor": "^3.2", + "doctrine/doctrine-bundle": "^2.0", + "ext-intl": "*", + "php": ">=8.2", + "symfony/asset": "^5.4|^6.4|^7.0", + "symfony/doctrine-bridge": "^5.4|^6.4|^7.0", + "symfony/event-dispatcher": "^5.4|^6.4|^7.0", + "symfony/lock": "^5.4|^6.4|^7.0", + "symfony/security-bundle": "^5.4|^6.4|^7.0", + "symfony/translation": "^5.4|^6.4|^7.0", + "symfony/twig-bundle": "^5.4|^6.4|^7.0", "twig/extra-bundle": "^3.3", "twig/intl-extra": "^3.3" }, - "conflict": { - "doctrine/persistence": "<1.3" - }, "require-dev": { + "doctrine/data-fixtures": "^1.4", "gedmo/doctrine-extensions": "^2.4|^3.0", - "matthiasnoback/symfony-dependency-injection-test": "^3.1|^4.0", - "nyholm/symfony-bundle-test": "1.x-dev", - "phpunit/phpunit": "^8.0|^9.0", - "symfony/browser-kit": "^4.0|^5.1|^6.0", - "symfony/css-selector": "^5.1|^6.0", - "symfony/framework-bundle": "^4.4|^5.0|^6.0", - "symfony/var-dumper": "^4.0|^5.0|^6.0", - "symfony/webpack-encore-bundle": "^1.12", - "twig/extensions": "^1.5" + "matthiasnoback/symfony-dependency-injection-test": "^6.0", + "nyholm/symfony-bundle-test": "^2.0|^3.0", + "phpunit/phpunit": "^11.0", + "symfony/browser-kit": "^5.4|^6.4|^7.0", + "symfony/css-selector": "^5.4|^6.4|^7.0", + "symfony/framework-bundle": "^5.4|^6.4|^7.0", + "symfony/var-dumper": "^5.4|^6.4|^7.0", + "symfony/webpack-encore-bundle": "^1.12|^2.0" }, "type": "symfony-bundle", "extra": { "branch-alias": { - "dev-master": "5.x-dev", - "dev-4.x": "4.x-dev" + "dev-4.x": "4.x-dev", + "dev-5.x": "5.x-dev", + "dev-master": "6.x-dev" } }, "autoload": { @@ -937,37 +945,40 @@ ], "support": { "issues": "https://github.com/DamienHarper/auditor-bundle/issues", - "source": "https://github.com/DamienHarper/auditor-bundle/tree/5.0.3" + "source": "https://github.com/DamienHarper/auditor-bundle/tree/6.2.1" }, - "time": "2022-08-07T15:42:55+00:00" + "time": "2025-01-16T08:18:12+00:00" }, { "name": "doctrine/annotations", - "version": "1.13.3", + "version": "2.0.2", "source": { "type": "git", "url": "https://github.com/doctrine/annotations.git", - "reference": "648b0343343565c4a056bfc8392201385e8d89f0" + "reference": "901c2ee5d26eb64ff43c47976e114bf00843acf7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/annotations/zipball/648b0343343565c4a056bfc8392201385e8d89f0", - "reference": "648b0343343565c4a056bfc8392201385e8d89f0", + "url": "https://api.github.com/repos/doctrine/annotations/zipball/901c2ee5d26eb64ff43c47976e114bf00843acf7", + "reference": "901c2ee5d26eb64ff43c47976e114bf00843acf7", "shasum": "" }, "require": { - "doctrine/lexer": "1.*", + "doctrine/lexer": "^2 || ^3", "ext-tokenizer": "*", - "php": "^7.1 || ^8.0", + "php": "^7.2 || ^8.0", "psr/cache": "^1 || ^2 || ^3" }, "require-dev": { - "doctrine/cache": "^1.11 || ^2.0", - "doctrine/coding-standard": "^6.0 || ^8.1", - "phpstan/phpstan": "^1.4.10 || ^1.8.0", - "phpunit/phpunit": "^7.5 || ^8.0 || ^9.1.5", - "symfony/cache": "^4.4 || ^5.2", - "vimeo/psalm": "^4.10" + "doctrine/cache": "^2.0", + "doctrine/coding-standard": "^10", + "phpstan/phpstan": "^1.10.28", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "symfony/cache": "^5.4 || ^6.4 || ^7", + "vimeo/psalm": "^4.30 || ^5.14" + }, + "suggest": { + "php": "PHP 8.0 or higher comes with attributes, a native replacement for annotations" }, "type": "library", "autoload": { @@ -1010,9 +1021,9 @@ ], "support": { "issues": "https://github.com/doctrine/annotations/issues", - "source": "https://github.com/doctrine/annotations/tree/1.13.3" + "source": "https://github.com/doctrine/annotations/tree/2.0.2" }, - "time": "2022-07-02T10:48:51+00:00" + "time": "2024-09-05T10:17:24+00:00" }, { "name": "doctrine/cache", @@ -1109,32 +1120,34 @@ }, { "name": "doctrine/collections", - "version": "1.7.2", + "version": "2.2.2", "source": { "type": "git", "url": "https://github.com/doctrine/collections.git", - "reference": "3fe77330f5591108bbf1315da7377a7e704ed8a0" + "reference": "d8af7f248c74f195f7347424600fd9e17b57af59" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/collections/zipball/3fe77330f5591108bbf1315da7377a7e704ed8a0", - "reference": "3fe77330f5591108bbf1315da7377a7e704ed8a0", + "url": "https://api.github.com/repos/doctrine/collections/zipball/d8af7f248c74f195f7347424600fd9e17b57af59", + "reference": "d8af7f248c74f195f7347424600fd9e17b57af59", "shasum": "" }, "require": { - "doctrine/deprecations": "^0.5.3 || ^1", - "php": "^7.1.3 || ^8.0" + "doctrine/deprecations": "^1", + "php": "^8.1" }, "require-dev": { - "doctrine/coding-standard": "^9.0 || ^10.0", - "phpstan/phpstan": "^1.4.8", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.1.5", - "vimeo/psalm": "^4.22" + "doctrine/coding-standard": "^12", + "ext-json": "*", + "phpstan/phpstan": "^1.8", + "phpstan/phpstan-phpunit": "^1.0", + "phpunit/phpunit": "^10.5", + "vimeo/psalm": "^5.11" }, "type": "library", "autoload": { "psr-4": { - "Doctrine\\Common\\Collections\\": "lib/Doctrine/Common/Collections" + "Doctrine\\Common\\Collections\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -1173,36 +1186,50 @@ ], "support": { "issues": "https://github.com/doctrine/collections/issues", - "source": "https://github.com/doctrine/collections/tree/1.7.2" + "source": "https://github.com/doctrine/collections/tree/2.2.2" }, - "time": "2022-08-27T16:08:58+00:00" + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fcollections", + "type": "tidelift" + } + ], + "time": "2024-04-18T06:56:21+00:00" }, { "name": "doctrine/common", - "version": "3.4.0", + "version": "3.5.0", "source": { "type": "git", "url": "https://github.com/doctrine/common.git", - "reference": "e09556bbdf95b8420e649162b19ae9da2d1a80f3" + "reference": "d9ea4a54ca2586db781f0265d36bea731ac66ec5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/common/zipball/e09556bbdf95b8420e649162b19ae9da2d1a80f3", - "reference": "e09556bbdf95b8420e649162b19ae9da2d1a80f3", + "url": "https://api.github.com/repos/doctrine/common/zipball/d9ea4a54ca2586db781f0265d36bea731ac66ec5", + "reference": "d9ea4a54ca2586db781f0265d36bea731ac66ec5", "shasum": "" }, "require": { - "doctrine/persistence": "^2.0 || ^3.0", + "doctrine/persistence": "^2.0 || ^3.0 || ^4.0", "php": "^7.1 || ^8.0" }, "require-dev": { - "doctrine/coding-standard": "^9.0", + "doctrine/coding-standard": "^9.0 || ^10.0", "doctrine/collections": "^1", "phpstan/phpstan": "^1.4.1", "phpstan/phpstan-phpunit": "^1", "phpunit/phpunit": "^7.5.20 || ^8.5 || ^9.0", "squizlabs/php_codesniffer": "^3.0", - "symfony/phpunit-bridge": "^4.0.5", + "symfony/phpunit-bridge": "^6.1", "vimeo/psalm": "^4.4" }, "type": "library", @@ -1250,7 +1277,7 @@ ], "support": { "issues": "https://github.com/doctrine/common/issues", - "source": "https://github.com/doctrine/common/tree/3.4.0" + "source": "https://github.com/doctrine/common/tree/3.5.0" }, "funding": [ { @@ -1266,50 +1293,48 @@ "type": "tidelift" } ], - "time": "2022-08-23T19:46:56+00:00" + "time": "2025-01-01T22:12:03+00:00" }, { "name": "doctrine/dbal", - "version": "2.13.9", + "version": "4.2.2", "source": { "type": "git", "url": "https://github.com/doctrine/dbal.git", - "reference": "c480849ca3ad6706a39c970cdfe6888fa8a058b8" + "reference": "19a2b7deb5fe8c2df0ff817ecea305e50acb62ec" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/dbal/zipball/c480849ca3ad6706a39c970cdfe6888fa8a058b8", - "reference": "c480849ca3ad6706a39c970cdfe6888fa8a058b8", + "url": "https://api.github.com/repos/doctrine/dbal/zipball/19a2b7deb5fe8c2df0ff817ecea305e50acb62ec", + "reference": "19a2b7deb5fe8c2df0ff817ecea305e50acb62ec", "shasum": "" }, "require": { - "doctrine/cache": "^1.0|^2.0", "doctrine/deprecations": "^0.5.3|^1", - "doctrine/event-manager": "^1.0", - "ext-pdo": "*", - "php": "^7.1 || ^8" + "php": "^8.1", + "psr/cache": "^1|^2|^3", + "psr/log": "^1|^2|^3" }, "require-dev": { - "doctrine/coding-standard": "9.0.0", - "jetbrains/phpstorm-stubs": "2021.1", - "phpstan/phpstan": "1.4.6", - "phpunit/phpunit": "^7.5.20|^8.5|9.5.16", - "psalm/plugin-phpunit": "0.16.1", - "squizlabs/php_codesniffer": "3.6.2", - "symfony/cache": "^4.4", - "symfony/console": "^2.0.5|^3.0|^4.0|^5.0", - "vimeo/psalm": "4.22.0" + "doctrine/coding-standard": "12.0.0", + "fig/log-test": "^1", + "jetbrains/phpstorm-stubs": "2023.2", + "phpstan/phpstan": "2.1.1", + "phpstan/phpstan-phpunit": "2.0.3", + "phpstan/phpstan-strict-rules": "^2", + "phpunit/phpunit": "10.5.39", + "slevomat/coding-standard": "8.13.1", + "squizlabs/php_codesniffer": "3.10.2", + "symfony/cache": "^6.3.8|^7.0", + "symfony/console": "^5.4|^6.3|^7.0" }, "suggest": { "symfony/console": "For helpful console commands such as SQL execution and import of files." }, - "bin": [ - "bin/doctrine-dbal" - ], "type": "library", "autoload": { "psr-4": { - "Doctrine\\DBAL\\": "lib/Doctrine/DBAL" + "Doctrine\\DBAL\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -1352,14 +1377,13 @@ "queryobject", "sasql", "sql", - "sqlanywhere", "sqlite", "sqlserver", "sqlsrv" ], "support": { "issues": "https://github.com/doctrine/dbal/issues", - "source": "https://github.com/doctrine/dbal/tree/2.13.9" + "source": "https://github.com/doctrine/dbal/tree/4.2.2" }, "funding": [ { @@ -1375,29 +1399,31 @@ "type": "tidelift" } ], - "time": "2022-05-02T20:28:55+00:00" + "time": "2025-01-16T08:40:56+00:00" }, { "name": "doctrine/deprecations", - "version": "v1.0.0", + "version": "1.1.4", "source": { "type": "git", "url": "https://github.com/doctrine/deprecations.git", - "reference": "0e2a4f1f8cdfc7a92ec3b01c9334898c806b30de" + "reference": "31610dbb31faa98e6b5447b62340826f54fbc4e9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/deprecations/zipball/0e2a4f1f8cdfc7a92ec3b01c9334898c806b30de", - "reference": "0e2a4f1f8cdfc7a92ec3b01c9334898c806b30de", + "url": "https://api.github.com/repos/doctrine/deprecations/zipball/31610dbb31faa98e6b5447b62340826f54fbc4e9", + "reference": "31610dbb31faa98e6b5447b62340826f54fbc4e9", "shasum": "" }, "require": { - "php": "^7.1|^8.0" + "php": "^7.1 || ^8.0" }, "require-dev": { - "doctrine/coding-standard": "^9", - "phpunit/phpunit": "^7.5|^8.5|^9.5", - "psr/log": "^1|^2|^3" + "doctrine/coding-standard": "^9 || ^12", + "phpstan/phpstan": "1.4.10 || 2.0.3", + "phpstan/phpstan-phpunit": "^1.0 || ^2", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "psr/log": "^1 || ^2 || ^3" }, "suggest": { "psr/log": "Allows logging deprecations via PSR-3 logger implementation" @@ -1405,7 +1431,7 @@ "type": "library", "autoload": { "psr-4": { - "Doctrine\\Deprecations\\": "lib/Doctrine/Deprecations" + "Doctrine\\Deprecations\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -1416,62 +1442,68 @@ "homepage": "https://www.doctrine-project.org/", "support": { "issues": "https://github.com/doctrine/deprecations/issues", - "source": "https://github.com/doctrine/deprecations/tree/v1.0.0" + "source": "https://github.com/doctrine/deprecations/tree/1.1.4" }, - "time": "2022-05-02T15:47:09+00:00" + "time": "2024-12-07T21:18:45+00:00" }, { "name": "doctrine/doctrine-bundle", - "version": "2.7.0", + "version": "2.13.2", "source": { "type": "git", "url": "https://github.com/doctrine/DoctrineBundle.git", - "reference": "d2088fc50494e4e7441fecca54732245a613eeb6" + "reference": "2363c43d9815a11657e452625cd64172d5587486" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/DoctrineBundle/zipball/d2088fc50494e4e7441fecca54732245a613eeb6", - "reference": "d2088fc50494e4e7441fecca54732245a613eeb6", + "url": "https://api.github.com/repos/doctrine/DoctrineBundle/zipball/2363c43d9815a11657e452625cd64172d5587486", + "reference": "2363c43d9815a11657e452625cd64172d5587486", "shasum": "" }, "require": { - "doctrine/annotations": "^1", "doctrine/cache": "^1.11 || ^2.0", - "doctrine/dbal": "^2.13.1|^3.3.2", - "doctrine/persistence": "^2.2|^3", + "doctrine/dbal": "^3.7.0 || ^4.0", + "doctrine/persistence": "^2.2 || ^3", "doctrine/sql-formatter": "^1.0.1", - "php": "^7.1 || ^8.0", - "symfony/cache": "^4.3.3|^5.0|^6.0", - "symfony/config": "^4.4.3|^5.0|^6.0", - "symfony/console": "^3.4.30|^4.3.3|^5.0|^6.0", - "symfony/dependency-injection": "^4.4.18|^5.0|^6.0", - "symfony/deprecation-contracts": "^2.1|^3", - "symfony/doctrine-bridge": "^4.4.22|^5.2.7|^6.0", - "symfony/framework-bundle": "^3.4.30|^4.3.3|^5.0|^6.0", - "symfony/service-contracts": "^1.1.1|^2.0|^3" + "php": "^7.4 || ^8.0", + "symfony/cache": "^5.4 || ^6.0 || ^7.0", + "symfony/config": "^5.4 || ^6.0 || ^7.0", + "symfony/console": "^5.4 || ^6.0 || ^7.0", + "symfony/dependency-injection": "^5.4 || ^6.0 || ^7.0", + "symfony/deprecation-contracts": "^2.1 || ^3", + "symfony/doctrine-bridge": "^5.4.46 || ~6.3.12 || ^6.4.3 || ^7.0.3", + "symfony/framework-bundle": "^5.4 || ^6.0 || ^7.0", + "symfony/polyfill-php80": "^1.15", + "symfony/service-contracts": "^1.1.1 || ^2.0 || ^3" }, "conflict": { - "doctrine/orm": "<2.10|>=3.0", - "twig/twig": "<1.34|>=2.0,<2.4" + "doctrine/annotations": ">=3.0", + "doctrine/orm": "<2.17 || >=4.0", + "twig/twig": "<1.34 || >=2.0 <2.4" }, "require-dev": { - "doctrine/coding-standard": "^9.0", - "doctrine/orm": "^2.11 || ^3.0", + "doctrine/annotations": "^1 || ^2", + "doctrine/coding-standard": "^12", + "doctrine/deprecations": "^1.0", + "doctrine/orm": "^2.17 || ^3.0", "friendsofphp/proxy-manager-lts": "^1.0", - "phpunit/phpunit": "^7.5 || ^8.0 || ^9.3 || ^10.0", - "psalm/plugin-phpunit": "^0.16.1", - "psalm/plugin-symfony": "^3", - "psr/log": "^1.1.4|^2.0|^3.0", - "symfony/phpunit-bridge": "^5.2|^6.0", - "symfony/property-info": "^4.3.3|^5.0|^6.0", - "symfony/proxy-manager-bridge": "^3.4|^4.3.3|^5.0|^6.0", - "symfony/security-bundle": "^4.4|^5.0|^6.0", - "symfony/twig-bridge": "^3.4.30|^4.3.3|^5.0|^6.0", - "symfony/validator": "^3.4.30|^4.3.3|^5.0|^6.0", - "symfony/web-profiler-bundle": "^3.4.30|^4.3.3|^5.0|^6.0", - "symfony/yaml": "^3.4.30|^4.3.3|^5.0|^6.0", - "twig/twig": "^1.34|^2.12|^3.0", - "vimeo/psalm": "^4.7" + "phpstan/phpstan": "2.1.1", + "phpstan/phpstan-phpunit": "2.0.3", + "phpstan/phpstan-strict-rules": "^2", + "phpunit/phpunit": "^9.5.26", + "psr/log": "^1.1.4 || ^2.0 || ^3.0", + "symfony/phpunit-bridge": "^6.1 || ^7.0", + "symfony/property-info": "^5.4 || ^6.0 || ^7.0", + "symfony/proxy-manager-bridge": "^5.4 || ^6.0", + "symfony/security-bundle": "^5.4 || ^6.0 || ^7.0", + "symfony/stopwatch": "^5.4 || ^6.0 || ^7.0", + "symfony/string": "^5.4 || ^6.0 || ^7.0", + "symfony/twig-bridge": "^5.4 || ^6.0 || ^7.0", + "symfony/validator": "^5.4 || ^6.0 || ^7.0", + "symfony/var-exporter": "^5.4 || ^6.2 || ^7.0", + "symfony/web-profiler-bundle": "^5.4 || ^6.0 || ^7.0", + "symfony/yaml": "^5.4 || ^6.0 || ^7.0", + "twig/twig": "^1.34 || ^2.12 || ^3.0" }, "suggest": { "doctrine/orm": "The Doctrine ORM integration is optional in the bundle.", @@ -1481,7 +1513,7 @@ "type": "symfony-bundle", "autoload": { "psr-4": { - "Doctrine\\Bundle\\DoctrineBundle\\": "" + "Doctrine\\Bundle\\DoctrineBundle\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -1516,7 +1548,7 @@ ], "support": { "issues": "https://github.com/doctrine/DoctrineBundle/issues", - "source": "https://github.com/doctrine/DoctrineBundle/tree/2.7.0" + "source": "https://github.com/doctrine/DoctrineBundle/tree/2.13.2" }, "funding": [ { @@ -1532,38 +1564,38 @@ "type": "tidelift" } ], - "time": "2022-06-10T10:55:26+00:00" + "time": "2025-01-15T11:12:38+00:00" }, { "name": "doctrine/event-manager", - "version": "1.1.2", + "version": "2.0.1", "source": { "type": "git", "url": "https://github.com/doctrine/event-manager.git", - "reference": "eb2ecf80e3093e8f3c2769ac838e27d8ede8e683" + "reference": "b680156fa328f1dfd874fd48c7026c41570b9c6e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/event-manager/zipball/eb2ecf80e3093e8f3c2769ac838e27d8ede8e683", - "reference": "eb2ecf80e3093e8f3c2769ac838e27d8ede8e683", + "url": "https://api.github.com/repos/doctrine/event-manager/zipball/b680156fa328f1dfd874fd48c7026c41570b9c6e", + "reference": "b680156fa328f1dfd874fd48c7026c41570b9c6e", "shasum": "" }, "require": { - "php": "^7.1 || ^8.0" + "php": "^8.1" }, "conflict": { "doctrine/common": "<2.9" }, "require-dev": { - "doctrine/coding-standard": "^9", - "phpstan/phpstan": "~1.4.10 || ^1.5.4", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", - "vimeo/psalm": "^4.22" + "doctrine/coding-standard": "^12", + "phpstan/phpstan": "^1.8.8", + "phpunit/phpunit": "^10.5", + "vimeo/psalm": "^5.24" }, "type": "library", "autoload": { "psr-4": { - "Doctrine\\Common\\": "lib/Doctrine/Common" + "Doctrine\\Common\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -1607,7 +1639,7 @@ ], "support": { "issues": "https://github.com/doctrine/event-manager/issues", - "source": "https://github.com/doctrine/event-manager/tree/1.1.2" + "source": "https://github.com/doctrine/event-manager/tree/2.0.1" }, "funding": [ { @@ -1623,32 +1655,32 @@ "type": "tidelift" } ], - "time": "2022-07-27T22:18:11+00:00" + "time": "2024-05-22T20:47:39+00:00" }, { "name": "doctrine/inflector", - "version": "2.0.5", + "version": "2.0.10", "source": { "type": "git", "url": "https://github.com/doctrine/inflector.git", - "reference": "ade2b3bbfb776f27f0558e26eed43b5d9fe1b392" + "reference": "5817d0659c5b50c9b950feb9af7b9668e2c436bc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/inflector/zipball/ade2b3bbfb776f27f0558e26eed43b5d9fe1b392", - "reference": "ade2b3bbfb776f27f0558e26eed43b5d9fe1b392", + "url": "https://api.github.com/repos/doctrine/inflector/zipball/5817d0659c5b50c9b950feb9af7b9668e2c436bc", + "reference": "5817d0659c5b50c9b950feb9af7b9668e2c436bc", "shasum": "" }, "require": { "php": "^7.2 || ^8.0" }, "require-dev": { - "doctrine/coding-standard": "^9", + "doctrine/coding-standard": "^11.0", "phpstan/phpstan": "^1.8", "phpstan/phpstan-phpunit": "^1.1", "phpstan/phpstan-strict-rules": "^1.3", "phpunit/phpunit": "^8.5 || ^9.5", - "vimeo/psalm": "^4.25" + "vimeo/psalm": "^4.25 || ^5.4" }, "type": "library", "autoload": { @@ -1698,7 +1730,7 @@ ], "support": { "issues": "https://github.com/doctrine/inflector/issues", - "source": "https://github.com/doctrine/inflector/tree/2.0.5" + "source": "https://github.com/doctrine/inflector/tree/2.0.10" }, "funding": [ { @@ -1714,34 +1746,34 @@ "type": "tidelift" } ], - "time": "2022-09-07T09:01:28+00:00" + "time": "2024-02-18T20:23:39+00:00" }, { "name": "doctrine/instantiator", - "version": "1.4.1", + "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/doctrine/instantiator.git", - "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc" + "reference": "c6222283fa3f4ac679f8b9ced9a4e23f163e80d0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/10dcfce151b967d20fde1b34ae6640712c3891bc", - "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/c6222283fa3f4ac679f8b9ced9a4e23f163e80d0", + "reference": "c6222283fa3f4ac679f8b9ced9a4e23f163e80d0", "shasum": "" }, "require": { - "php": "^7.1 || ^8.0" + "php": "^8.1" }, "require-dev": { - "doctrine/coding-standard": "^9", + "doctrine/coding-standard": "^11", "ext-pdo": "*", "ext-phar": "*", - "phpbench/phpbench": "^0.16 || ^1", - "phpstan/phpstan": "^1.4", - "phpstan/phpstan-phpunit": "^1", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", - "vimeo/psalm": "^4.22" + "phpbench/phpbench": "^1.2", + "phpstan/phpstan": "^1.9.4", + "phpstan/phpstan-phpunit": "^1.3", + "phpunit/phpunit": "^9.5.27", + "vimeo/psalm": "^5.4" }, "type": "library", "autoload": { @@ -1768,7 +1800,7 @@ ], "support": { "issues": "https://github.com/doctrine/instantiator/issues", - "source": "https://github.com/doctrine/instantiator/tree/1.4.1" + "source": "https://github.com/doctrine/instantiator/tree/2.0.0" }, "funding": [ { @@ -1784,35 +1816,36 @@ "type": "tidelift" } ], - "time": "2022-03-03T08:28:38+00:00" + "time": "2022-12-30T00:23:10+00:00" }, { "name": "doctrine/lexer", - "version": "1.2.3", + "version": "3.0.1", "source": { "type": "git", "url": "https://github.com/doctrine/lexer.git", - "reference": "c268e882d4dbdd85e36e4ad69e02dc284f89d229" + "reference": "31ad66abc0fc9e1a1f2d9bc6a42668d2fbbcd6dd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/lexer/zipball/c268e882d4dbdd85e36e4ad69e02dc284f89d229", - "reference": "c268e882d4dbdd85e36e4ad69e02dc284f89d229", + "url": "https://api.github.com/repos/doctrine/lexer/zipball/31ad66abc0fc9e1a1f2d9bc6a42668d2fbbcd6dd", + "reference": "31ad66abc0fc9e1a1f2d9bc6a42668d2fbbcd6dd", "shasum": "" }, "require": { - "php": "^7.1 || ^8.0" + "php": "^8.1" }, "require-dev": { - "doctrine/coding-standard": "^9.0", - "phpstan/phpstan": "^1.3", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", - "vimeo/psalm": "^4.11" + "doctrine/coding-standard": "^12", + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^10.5", + "psalm/plugin-phpunit": "^0.18.3", + "vimeo/psalm": "^5.21" }, "type": "library", "autoload": { "psr-4": { - "Doctrine\\Common\\Lexer\\": "lib/Doctrine/Common/Lexer" + "Doctrine\\Common\\Lexer\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -1844,7 +1877,7 @@ ], "support": { "issues": "https://github.com/doctrine/lexer/issues", - "source": "https://github.com/doctrine/lexer/tree/1.2.3" + "source": "https://github.com/doctrine/lexer/tree/3.0.1" }, "funding": [ { @@ -1860,68 +1893,58 @@ "type": "tidelift" } ], - "time": "2022-02-28T11:07:21+00:00" + "time": "2024-02-05T11:56:58+00:00" }, { "name": "doctrine/orm", - "version": "2.13.1", + "version": "3.3.1", "source": { "type": "git", "url": "https://github.com/doctrine/orm.git", - "reference": "35c44a56677adb3ce796138b6e4934ce93ec6811" + "reference": "b1f8253105aa5382c495e5f9f8ef34e297775428" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/orm/zipball/35c44a56677adb3ce796138b6e4934ce93ec6811", - "reference": "35c44a56677adb3ce796138b6e4934ce93ec6811", + "url": "https://api.github.com/repos/doctrine/orm/zipball/b1f8253105aa5382c495e5f9f8ef34e297775428", + "reference": "b1f8253105aa5382c495e5f9f8ef34e297775428", "shasum": "" }, "require": { "composer-runtime-api": "^2", - "doctrine/cache": "^1.12.1 || ^2.1.1", - "doctrine/collections": "^1.5", - "doctrine/common": "^3.0.3", - "doctrine/dbal": "^2.13.1 || ^3.2", + "doctrine/collections": "^2.2", + "doctrine/dbal": "^3.8.2 || ^4", "doctrine/deprecations": "^0.5.3 || ^1", - "doctrine/event-manager": "^1.1", + "doctrine/event-manager": "^1.2 || ^2", "doctrine/inflector": "^1.4 || ^2.0", - "doctrine/instantiator": "^1.3", - "doctrine/lexer": "^1.2.3", - "doctrine/persistence": "^2.4 || ^3", + "doctrine/instantiator": "^1.3 || ^2", + "doctrine/lexer": "^3", + "doctrine/persistence": "^3.3.1 || ^4", "ext-ctype": "*", - "php": "^7.1 || ^8.0", + "php": "^8.1", "psr/cache": "^1 || ^2 || ^3", - "symfony/console": "^3.0 || ^4.0 || ^5.0 || ^6.0", - "symfony/polyfill-php72": "^1.23", - "symfony/polyfill-php80": "^1.16" - }, - "conflict": { - "doctrine/annotations": "<1.13 || >= 2.0" + "symfony/console": "^5.4 || ^6.0 || ^7.0", + "symfony/var-exporter": "^6.3.9 || ^7.0" }, "require-dev": { - "doctrine/annotations": "^1.13", - "doctrine/coding-standard": "^9.0", - "phpbench/phpbench": "^0.16.10 || ^1.0", - "phpstan/phpstan": "~1.4.10 || 1.8.2", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "doctrine/coding-standard": "^12.0", + "phpbench/phpbench": "^1.0", + "phpdocumentor/guides-cli": "^1.4", + "phpstan/extension-installer": "^1.4", + "phpstan/phpstan": "2.0.3", + "phpstan/phpstan-deprecation-rules": "^2", + "phpunit/phpunit": "^10.4.0", "psr/log": "^1 || ^2 || ^3", - "squizlabs/php_codesniffer": "3.7.1", - "symfony/cache": "^4.4 || ^5.4 || ^6.0", - "symfony/yaml": "^3.4 || ^4.0 || ^5.0 || ^6.0", - "vimeo/psalm": "4.26.0" + "squizlabs/php_codesniffer": "3.7.2", + "symfony/cache": "^5.4 || ^6.2 || ^7.0" }, "suggest": { "ext-dom": "Provides support for XSD validation for XML mapping files", - "symfony/cache": "Provides cache support for Setup Tool with doctrine/cache 2.0", - "symfony/yaml": "If you want to use YAML Metadata Mapping Driver" + "symfony/cache": "Provides cache support for Setup Tool with doctrine/cache 2.0" }, - "bin": [ - "bin/doctrine" - ], "type": "library", "autoload": { "psr-4": { - "Doctrine\\ORM\\": "lib/Doctrine/ORM" + "Doctrine\\ORM\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -1958,44 +1981,40 @@ ], "support": { "issues": "https://github.com/doctrine/orm/issues", - "source": "https://github.com/doctrine/orm/tree/2.13.1" + "source": "https://github.com/doctrine/orm/tree/3.3.1" }, - "time": "2022-08-08T09:00:16+00:00" + "time": "2024-12-19T07:08:14+00:00" }, { "name": "doctrine/persistence", - "version": "3.0.3", + "version": "3.4.0", "source": { "type": "git", "url": "https://github.com/doctrine/persistence.git", - "reference": "ac6fce61f037d7e54dbb2435f5b5648d86548e23" + "reference": "0ea965320cec355dba75031c1b23d4c78362e3ff" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/persistence/zipball/ac6fce61f037d7e54dbb2435f5b5648d86548e23", - "reference": "ac6fce61f037d7e54dbb2435f5b5648d86548e23", + "url": "https://api.github.com/repos/doctrine/persistence/zipball/0ea965320cec355dba75031c1b23d4c78362e3ff", + "reference": "0ea965320cec355dba75031c1b23d4c78362e3ff", "shasum": "" }, "require": { - "doctrine/event-manager": "^1.0", + "doctrine/event-manager": "^1 || ^2", "php": "^7.2 || ^8.0", "psr/cache": "^1.0 || ^2.0 || ^3.0" }, "conflict": { - "doctrine/annotations": "<1.7 || >=2.0", "doctrine/common": "<2.10" }, "require-dev": { - "composer/package-versions-deprecated": "^1.11", - "doctrine/annotations": "^1.7", - "doctrine/coding-standard": "^9.0", + "doctrine/coding-standard": "^12", "doctrine/common": "^3.0", - "phpstan/phpstan": "1.5.0", + "phpstan/phpstan": "1.12.7", "phpstan/phpstan-phpunit": "^1", "phpstan/phpstan-strict-rules": "^1.1", - "phpunit/phpunit": "^8.5 || ^9.5", - "symfony/cache": "^4.4 || ^5.4 || ^6.0", - "vimeo/psalm": "4.22.0" + "phpunit/phpunit": "^8.5.38 || ^9.5", + "symfony/cache": "^4.4 || ^5.4 || ^6.0 || ^7.0" }, "type": "library", "autoload": { @@ -2044,7 +2063,7 @@ ], "support": { "issues": "https://github.com/doctrine/persistence/issues", - "source": "https://github.com/doctrine/persistence/tree/3.0.3" + "source": "https://github.com/doctrine/persistence/tree/3.4.0" }, "funding": [ { @@ -2060,27 +2079,30 @@ "type": "tidelift" } ], - "time": "2022-08-04T21:14:21+00:00" + "time": "2024-10-30T19:48:12+00:00" }, { "name": "doctrine/sql-formatter", - "version": "1.1.3", + "version": "1.5.2", "source": { "type": "git", "url": "https://github.com/doctrine/sql-formatter.git", - "reference": "25a06c7bf4c6b8218f47928654252863ffc890a5" + "reference": "d6d00aba6fd2957fe5216fe2b7673e9985db20c8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/sql-formatter/zipball/25a06c7bf4c6b8218f47928654252863ffc890a5", - "reference": "25a06c7bf4c6b8218f47928654252863ffc890a5", + "url": "https://api.github.com/repos/doctrine/sql-formatter/zipball/d6d00aba6fd2957fe5216fe2b7673e9985db20c8", + "reference": "d6d00aba6fd2957fe5216fe2b7673e9985db20c8", "shasum": "" }, "require": { - "php": "^7.1 || ^8.0" + "php": "^8.1" }, "require-dev": { - "bamarni/composer-bin-plugin": "^1.4" + "doctrine/coding-standard": "^12", + "ergebnis/phpunit-slow-test-detector": "^2.14", + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^10.5" }, "bin": [ "bin/sql-formatter" @@ -2110,28 +2132,28 @@ ], "support": { "issues": "https://github.com/doctrine/sql-formatter/issues", - "source": "https://github.com/doctrine/sql-formatter/tree/1.1.3" + "source": "https://github.com/doctrine/sql-formatter/tree/1.5.2" }, - "time": "2022-05-23T21:33:49+00:00" + "time": "2025-01-24T11:45:48+00:00" }, { "name": "friendsofphp/proxy-manager-lts", - "version": "v1.0.12", + "version": "v1.0.18", "source": { "type": "git", "url": "https://github.com/FriendsOfPHP/proxy-manager-lts.git", - "reference": "8419f0158715b30d4b99a5bd37c6a39671994ad7" + "reference": "2c8a6cffc3220e99352ad958fe7cf06bf6f7690f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/FriendsOfPHP/proxy-manager-lts/zipball/8419f0158715b30d4b99a5bd37c6a39671994ad7", - "reference": "8419f0158715b30d4b99a5bd37c6a39671994ad7", + "url": "https://api.github.com/repos/FriendsOfPHP/proxy-manager-lts/zipball/2c8a6cffc3220e99352ad958fe7cf06bf6f7690f", + "reference": "2c8a6cffc3220e99352ad958fe7cf06bf6f7690f", "shasum": "" }, "require": { "laminas/laminas-code": "~3.4.1|^4.0", "php": ">=7.1", - "symfony/filesystem": "^4.4.17|^5.0|^6.0" + "symfony/filesystem": "^4.4.17|^5.0|^6.0|^7.0" }, "conflict": { "laminas/laminas-stdlib": "<3.2.1", @@ -2142,13 +2164,13 @@ }, "require-dev": { "ext-phar": "*", - "symfony/phpunit-bridge": "^5.4|^6.0" + "symfony/phpunit-bridge": "^5.4|^6.0|^7.0" }, "type": "library", "extra": { "thanks": { - "name": "ocramius/proxy-manager", - "url": "https://github.com/Ocramius/ProxyManager" + "url": "https://github.com/Ocramius/ProxyManager", + "name": "ocramius/proxy-manager" } }, "autoload": { @@ -2182,7 +2204,7 @@ ], "support": { "issues": "https://github.com/FriendsOfPHP/proxy-manager-lts/issues", - "source": "https://github.com/FriendsOfPHP/proxy-manager-lts/tree/v1.0.12" + "source": "https://github.com/FriendsOfPHP/proxy-manager-lts/tree/v1.0.18" }, "funding": [ { @@ -2194,32 +2216,33 @@ "type": "tidelift" } ], - "time": "2022-05-05T09:31:05+00:00" + "time": "2024-03-20T12:50:41+00:00" }, { "name": "friendsofsymfony/rest-bundle", - "version": "3.3.0", + "version": "3.8.0", "source": { "type": "git", "url": "https://github.com/FriendsOfSymfony/FOSRestBundle.git", - "reference": "54f5ffec4bff71b727a2aa4877915ad81358defc" + "reference": "d24736896518bae817bf0de8a6b682cb6535044b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/FriendsOfSymfony/FOSRestBundle/zipball/54f5ffec4bff71b727a2aa4877915ad81358defc", - "reference": "54f5ffec4bff71b727a2aa4877915ad81358defc", + "url": "https://api.github.com/repos/FriendsOfSymfony/FOSRestBundle/zipball/d24736896518bae817bf0de8a6b682cb6535044b", + "reference": "d24736896518bae817bf0de8a6b682cb6535044b", "shasum": "" }, "require": { - "php": "^7.2|^8.0", - "symfony/config": "^4.4|^5.3|^6.0", - "symfony/dependency-injection": "^4.4|^5.3|^6.0", - "symfony/event-dispatcher": "^4.4|^5.3|^6.0", - "symfony/framework-bundle": "^4.4.1|^5.0|^6.0", - "symfony/http-foundation": "^4.4|^5.3|^6.0", - "symfony/http-kernel": "^4.4|^5.3|^6.0", - "symfony/routing": "^4.4|^5.3|^6.0", - "symfony/security-core": "^4.4|^5.3|^6.0", + "php": "^7.4|^8.0", + "symfony/config": "^5.4|^6.4|^7.0", + "symfony/dependency-injection": "^5.4|^6.4|^7.0", + "symfony/deprecation-contracts": "^2.1|^3.0", + "symfony/event-dispatcher": "^5.4|^6.4|^7.0", + "symfony/framework-bundle": "^5.4|^6.4|^7.0", + "symfony/http-foundation": "^5.4|^6.4|^7.0", + "symfony/http-kernel": "^5.4|^6.4|^7.0", + "symfony/routing": "^5.4|^6.4|^7.0", + "symfony/security-core": "^5.4|^6.4|^7.0", "willdurand/jsonp-callback-validator": "^1.0|^2.0", "willdurand/negotiation": "^2.0|^3.0" }, @@ -2227,36 +2250,35 @@ "doctrine/annotations": "<1.12", "jms/serializer": "<1.13.0", "jms/serializer-bundle": "<2.4.3|3.0.0", - "sensio/framework-extra-bundle": "<6.1", - "symfony/error-handler": "<4.4.1" + "sensio/framework-extra-bundle": "<6.1" }, "require-dev": { - "doctrine/annotations": "^1.13.2", - "friendsofphp/php-cs-fixer": "^3.0", + "doctrine/annotations": "^1.13.2|^2.0", + "friendsofphp/php-cs-fixer": "^3.43", "jms/serializer": "^1.13|^2.0|^3.0", - "jms/serializer-bundle": "^2.4.3|^3.0.1|^4.0", + "jms/serializer-bundle": "^2.4.3|^3.0.1|^4.0|^5.0", "psr/http-message": "^1.0", "psr/log": "^1.0|^2.0|^3.0", "sensio/framework-extra-bundle": "^6.1", - "symfony/asset": "^4.4|^5.3|^6.0", - "symfony/browser-kit": "^4.4|^5.3|^6.0", - "symfony/css-selector": "^4.4|^5.3|^6.0", - "symfony/expression-language": "^4.4|^5.3|^6.0", - "symfony/form": "^4.4|^5.3|^6.0", - "symfony/mime": "^4.4|^5.3|^6.0", - "symfony/phpunit-bridge": "^5.3|^6.0", - "symfony/security-bundle": "^4.4|^5.3|^6.0", - "symfony/serializer": "^4.4|^5.3|^6.0", - "symfony/twig-bundle": "^4.4|^5.3|^6.0", - "symfony/validator": "^4.4|^5.3|^6.0", - "symfony/web-profiler-bundle": "^4.4|^5.3|^6.0", - "symfony/yaml": "^4.4|^5.3|^6.0" + "symfony/asset": "^5.4|^6.4|^7.0", + "symfony/browser-kit": "^5.4|^6.4|^7.0", + "symfony/css-selector": "^5.4|^6.4|^7.0", + "symfony/expression-language": "^5.4|^6.4|^7.0", + "symfony/form": "^5.4|^6.4|^7.0", + "symfony/mime": "^5.4|^6.4|^7.0", + "symfony/phpunit-bridge": "^7.0.1", + "symfony/security-bundle": "^5.4|^6.4|^7.0", + "symfony/serializer": "^5.4|^6.4|^7.0", + "symfony/twig-bundle": "^5.4|^6.4|^7.0", + "symfony/validator": "^5.4|^6.4|^7.0", + "symfony/web-profiler-bundle": "^5.4|^6.4|^7.0", + "symfony/yaml": "^5.4|^6.4|^7.0" }, "suggest": { - "jms/serializer-bundle": "Add support for advanced serialization capabilities, recommended, requires ^2.0|^3.0", - "sensio/framework-extra-bundle": "Add support for the request body converter and the view response listener, requires ^3.0", - "symfony/serializer": "Add support for basic serialization capabilities and xml decoding, requires ^2.7|^3.0", - "symfony/validator": "Add support for validation capabilities in the ParamFetcher, requires ^2.7|^3.0" + "jms/serializer-bundle": "Add support for advanced serialization capabilities, recommended", + "sensio/framework-extra-bundle": "Add support for the request body converter and the view response listener, not supported with Symfony >=7.0", + "symfony/serializer": "Add support for basic serialization capabilities and xml decoding", + "symfony/validator": "Add support for validation capabilities in the ParamFetcher" }, "type": "symfony-bundle", "extra": { @@ -2298,67 +2320,70 @@ ], "support": { "issues": "https://github.com/FriendsOfSymfony/FOSRestBundle/issues", - "source": "https://github.com/FriendsOfSymfony/FOSRestBundle/tree/3.3.0" + "source": "https://github.com/FriendsOfSymfony/FOSRestBundle/tree/3.8.0" }, - "time": "2022-02-03T20:06:00+00:00" + "time": "2024-11-04T08:41:36+00:00" }, { "name": "gedmo/doctrine-extensions", - "version": "v3.8.0", + "version": "v3.17.1", "source": { "type": "git", "url": "https://github.com/doctrine-extensions/DoctrineExtensions.git", - "reference": "4ba5377b1a1d9a988205c4e37f5d5287eb8ebd28" + "reference": "eabb45018c5a4362b46c5beae3881261da89f900" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine-extensions/DoctrineExtensions/zipball/4ba5377b1a1d9a988205c4e37f5d5287eb8ebd28", - "reference": "4ba5377b1a1d9a988205c4e37f5d5287eb8ebd28", + "url": "https://api.github.com/repos/doctrine-extensions/DoctrineExtensions/zipball/eabb45018c5a4362b46c5beae3881261da89f900", + "reference": "eabb45018c5a4362b46c5beae3881261da89f900", "shasum": "" }, "require": { - "behat/transliterator": "~1.2", - "doctrine/annotations": "^1.13", - "doctrine/collections": "^1.0", + "behat/transliterator": "^1.2", + "doctrine/collections": "^1.2 || ^2.0", "doctrine/common": "^2.13 || ^3.0", - "doctrine/event-manager": "^1.0", + "doctrine/deprecations": "^1.0", + "doctrine/event-manager": "^1.2 || ^2.0", "doctrine/persistence": "^2.2 || ^3.0", - "php": "^7.2 || ^8.0", + "php": "^7.4 || ^8.0", "psr/cache": "^1 || ^2 || ^3", - "symfony/cache": "^4.4 || ^5.3 || ^6.0" + "psr/clock": "^1", + "symfony/cache": "^5.4 || ^6.0 || ^7.0" }, "conflict": { - "doctrine/cache": "<1.11", - "doctrine/dbal": "<2.13.1 || ^3.0 <3.2", - "doctrine/mongodb-odm": "<2.3", - "doctrine/orm": "<2.10.2", - "sebastian/comparator": "<2.0" + "doctrine/annotations": "<1.13 || >=3.0", + "doctrine/dbal": "<3.7 || >=5.0", + "doctrine/mongodb-odm": "<2.3 || >=3.0", + "doctrine/orm": "<2.14.0 || 2.16.0 || 2.16.1 || >=4.0" }, "require-dev": { + "doctrine/annotations": "^1.13 || ^2.0", "doctrine/cache": "^1.11 || ^2.0", - "doctrine/dbal": "^2.13.1 || ^3.2", + "doctrine/dbal": "^3.7 || ^4.0", "doctrine/doctrine-bundle": "^2.3", "doctrine/mongodb-odm": "^2.3", - "doctrine/orm": "^2.10.2", - "friendsofphp/php-cs-fixer": "^3.4.0", - "nesbot/carbon": "^2.55", - "phpstan/phpstan": "^1.1", - "phpstan/phpstan-doctrine": "^1.0", - "phpstan/phpstan-phpunit": "^1.0", - "phpunit/phpunit": "^8.5 || ^9.5", - "symfony/console": "^4.4 || ^5.3 || ^6.0", - "symfony/phpunit-bridge": "^6.0", - "symfony/yaml": "^4.4 || ^5.3 || ^6.0" + "doctrine/orm": "^2.14.0 || ^3.0", + "friendsofphp/php-cs-fixer": "^3.14.0", + "nesbot/carbon": "^2.71 || ^3.0", + "phpstan/phpstan": "^1.11", + "phpstan/phpstan-doctrine": "^1.4", + "phpstan/phpstan-phpunit": "^1.4", + "phpunit/phpunit": "^9.6", + "rector/rector": "^1.1", + "symfony/console": "^5.4 || ^6.0 || ^7.0", + "symfony/doctrine-bridge": "^5.4 || ^6.0 || ^7.0", + "symfony/phpunit-bridge": "^6.0 || ^7.0", + "symfony/uid": "^5.4 || ^6.0 || ^7.0", + "symfony/yaml": "^5.4 || ^6.0 || ^7.0" }, "suggest": { "doctrine/mongodb-odm": "to use the extensions with the MongoDB ODM", - "doctrine/orm": "to use the extensions with the ORM", - "symfony/cache": "to cache parsed annotations" + "doctrine/orm": "to use the extensions with the ORM" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "3.8-dev" + "dev-main": "3.x-dev" } }, "autoload": { @@ -2384,16 +2409,18 @@ "email": "david@liip.ch" } ], - "description": "Doctrine2 behavioral extensions", + "description": "Doctrine behavioral extensions", "homepage": "http://gediminasm.org/", "keywords": [ "Blameable", "behaviors", - "doctrine2", + "doctrine", "extensions", "gedmo", "loggable", "nestedset", + "odm", + "orm", "sluggable", "sortable", "timestampable", @@ -2404,103 +2431,41 @@ "support": { "email": "gediminas.morkevicius@gmail.com", "issues": "https://github.com/doctrine-extensions/DoctrineExtensions/issues", - "source": "https://github.com/doctrine-extensions/DoctrineExtensions/tree/v3.8.0", + "source": "https://github.com/doctrine-extensions/DoctrineExtensions/tree/v3.17.1", "wiki": "https://github.com/Atlantic18/DoctrineExtensions/tree/main/doc" }, - "time": "2022-07-17T12:04:16+00:00" - }, - { - "name": "gesdinet/jwt-refresh-token-bundle", - "version": "v1.1.1", - "source": { - "type": "git", - "url": "https://github.com/markitosgv/JWTRefreshTokenBundle.git", - "reference": "8970ae1a602fb74e434964d03c969d883cfed376" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/markitosgv/JWTRefreshTokenBundle/zipball/8970ae1a602fb74e434964d03c969d883cfed376", - "reference": "8970ae1a602fb74e434964d03c969d883cfed376", - "shasum": "" - }, - "require": { - "lexik/jwt-authentication-bundle": "^2.0", - "php": ">=7.4", - "symfony/config": "^4.4|^5.4|^6.0", - "symfony/console": "^4.4|^5.4|^6.0", - "symfony/dependency-injection": "^4.4|^5.4|^6.0", - "symfony/deprecation-contracts": "^2.1|^3.0", - "symfony/event-dispatcher": "^4.4|^5.4|^6.0", - "symfony/http-foundation": "^4.4|^5.4|^6.0", - "symfony/http-kernel": "^4.4|^5.4|^6.0", - "symfony/polyfill-php80": "^1.15", - "symfony/property-access": "^4.4|^5.4|^6.0", - "symfony/security-bundle": "^4.4|^5.4|^6.0", - "symfony/security-core": "^4.4|^5.4|^6.0", - "symfony/security-http": "^4.4|^5.4|^6.0" - }, - "conflict": { - "doctrine/mongodb-odm": "<2.0", - "doctrine/orm": "<2.7", - "doctrine/persistence": "<1.3.3" - }, - "require-dev": { - "doctrine/cache": "^1.11|^2.0", - "doctrine/mongodb-odm": "^2.0", - "doctrine/orm": "^2.7", - "doctrine/persistence": "^1.3.3|^2.0", - "matthiasnoback/symfony-config-test": "^4.2", - "matthiasnoback/symfony-dependency-injection-test": "^4.2", - "phpunit/phpunit": "^9.5", - "symfony/cache": "^4.4|^5.4|^6.0", - "symfony/security-guard": "^4.4|^5.4" - }, - "type": "symfony-bundle", - "extra": { - "branch-alias": { - "dev-master": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "Gesdinet\\JWTRefreshTokenBundle\\": "" + "funding": [ + { + "url": "https://github.com/l3pp4rd", + "type": "github" + }, + { + "url": "https://github.com/mbabker", + "type": "github" + }, + { + "url": "https://github.com/phansys", + "type": "github" }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ { - "name": "Marcos Gómez Vilches", - "email": "marcos@gesdinet.com" + "url": "https://github.com/stof", + "type": "github" } ], - "description": "Implements a refresh token system over Json Web Tokens in Symfony", - "keywords": [ - "jwt refresh token bundle symfony json web" - ], - "support": { - "issues": "https://github.com/markitosgv/JWTRefreshTokenBundle/issues", - "source": "https://github.com/markitosgv/JWTRefreshTokenBundle/tree/v1.1.1" - }, - "time": "2022-04-11T14:46:00+00:00" + "time": "2024-10-07T22:30:27+00:00" }, { "name": "jms/metadata", - "version": "2.6.1", + "version": "2.8.0", "source": { "type": "git", "url": "https://github.com/schmittjoh/metadata.git", - "reference": "c3a3214354b5a765a19875f7b7c5ebcd94e462e5" + "reference": "7ca240dcac0c655eb15933ee55736ccd2ea0d7a6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/schmittjoh/metadata/zipball/c3a3214354b5a765a19875f7b7c5ebcd94e462e5", - "reference": "c3a3214354b5a765a19875f7b7c5ebcd94e462e5", + "url": "https://api.github.com/repos/schmittjoh/metadata/zipball/7ca240dcac0c655eb15933ee55736ccd2ea0d7a6", + "reference": "7ca240dcac0c655eb15933ee55736ccd2ea0d7a6", "shasum": "" }, "require": { @@ -2511,7 +2476,7 @@ "doctrine/coding-standard": "^8.0", "mikey179/vfsstream": "^1.6.7", "phpunit/phpunit": "^8.5|^9.0", - "psr/container": "^1.0", + "psr/container": "^1.0|^2.0", "symfony/cache": "^3.1|^4.0|^5.0", "symfony/dependency-injection": "^3.1|^4.0|^5.0" }, @@ -2549,26 +2514,26 @@ ], "support": { "issues": "https://github.com/schmittjoh/metadata/issues", - "source": "https://github.com/schmittjoh/metadata/tree/2.6.1" + "source": "https://github.com/schmittjoh/metadata/tree/2.8.0" }, - "time": "2021-11-22T12:27:42+00:00" + "time": "2023-02-15T13:44:18+00:00" }, { "name": "justinrainbow/json-schema", - "version": "5.2.12", + "version": "5.3.0", "source": { "type": "git", - "url": "https://github.com/justinrainbow/json-schema.git", - "reference": "ad87d5a5ca981228e0e205c2bc7dfb8e24559b60" + "url": "https://github.com/jsonrainbow/json-schema.git", + "reference": "feb2ca6dd1cebdaf1ed60a4c8de2e53ce11c4fd8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/justinrainbow/json-schema/zipball/ad87d5a5ca981228e0e205c2bc7dfb8e24559b60", - "reference": "ad87d5a5ca981228e0e205c2bc7dfb8e24559b60", + "url": "https://api.github.com/repos/jsonrainbow/json-schema/zipball/feb2ca6dd1cebdaf1ed60a4c8de2e53ce11c4fd8", + "reference": "feb2ca6dd1cebdaf1ed60a4c8de2e53ce11c4fd8", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=7.1" }, "require-dev": { "friendsofphp/php-cs-fixer": "~2.2.20||~2.15.1", @@ -2579,11 +2544,6 @@ "bin/validate-json" ], "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.0.x-dev" - } - }, "autoload": { "psr-4": { "JsonSchema\\": "src/JsonSchema/" @@ -2618,36 +2578,36 @@ "schema" ], "support": { - "issues": "https://github.com/justinrainbow/json-schema/issues", - "source": "https://github.com/justinrainbow/json-schema/tree/5.2.12" + "issues": "https://github.com/jsonrainbow/json-schema/issues", + "source": "https://github.com/jsonrainbow/json-schema/tree/5.3.0" }, - "time": "2022-04-13T08:02:27+00:00" + "time": "2024-07-06T21:00:26+00:00" }, { "name": "laminas/laminas-code", - "version": "4.6.0", + "version": "4.16.0", "source": { "type": "git", "url": "https://github.com/laminas/laminas-code.git", - "reference": "16ec7577ff315d53ac2e1b1f03a344d8fe680a6e" + "reference": "1793e78dad4108b594084d05d1fb818b85b110af" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-code/zipball/16ec7577ff315d53ac2e1b1f03a344d8fe680a6e", - "reference": "16ec7577ff315d53ac2e1b1f03a344d8fe680a6e", + "url": "https://api.github.com/repos/laminas/laminas-code/zipball/1793e78dad4108b594084d05d1fb818b85b110af", + "reference": "1793e78dad4108b594084d05d1fb818b85b110af", "shasum": "" }, "require": { - "php": ">=7.4, <8.2" + "php": "~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0" }, "require-dev": { - "doctrine/annotations": "^1.13.2", + "doctrine/annotations": "^2.0.1", "ext-phar": "*", - "laminas/laminas-coding-standard": "^2.3.0", - "laminas/laminas-stdlib": "^3.6.1", - "phpunit/phpunit": "^9.5.10", - "psalm/plugin-phpunit": "^0.17.0", - "vimeo/psalm": "^4.13.1" + "laminas/laminas-coding-standard": "^3.0.0", + "laminas/laminas-stdlib": "^3.18.0", + "phpunit/phpunit": "^10.5.37", + "psalm/plugin-phpunit": "^0.19.0", + "vimeo/psalm": "^5.15.0" }, "suggest": { "doctrine/annotations": "Doctrine\\Common\\Annotations >=1.0 for annotation features", @@ -2655,9 +2615,6 @@ }, "type": "library", "autoload": { - "files": [ - "polyfill/ReflectionEnumPolyfill.php" - ], "psr-4": { "Laminas\\Code\\": "src/" } @@ -2687,35 +2644,38 @@ "type": "community_bridge" } ], - "time": "2022-07-28T22:46:52+00:00" + "time": "2024-11-20T13:15:13+00:00" }, { "name": "lcobucci/clock", - "version": "2.2.0", + "version": "3.3.1", "source": { "type": "git", "url": "https://github.com/lcobucci/clock.git", - "reference": "fb533e093fd61321bfcbac08b131ce805fe183d3" + "reference": "db3713a61addfffd615b79bf0bc22f0ccc61b86b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/lcobucci/clock/zipball/fb533e093fd61321bfcbac08b131ce805fe183d3", - "reference": "fb533e093fd61321bfcbac08b131ce805fe183d3", + "url": "https://api.github.com/repos/lcobucci/clock/zipball/db3713a61addfffd615b79bf0bc22f0ccc61b86b", + "reference": "db3713a61addfffd615b79bf0bc22f0ccc61b86b", "shasum": "" }, "require": { - "php": "^8.0", - "stella-maris/clock": "^0.1.4" + "php": "~8.2.0 || ~8.3.0 || ~8.4.0", + "psr/clock": "^1.0" + }, + "provide": { + "psr/clock-implementation": "1.0" }, "require-dev": { - "infection/infection": "^0.26", - "lcobucci/coding-standard": "^8.0", - "phpstan/extension-installer": "^1.1", - "phpstan/phpstan": "^0.12", - "phpstan/phpstan-deprecation-rules": "^0.12", - "phpstan/phpstan-phpunit": "^0.12", - "phpstan/phpstan-strict-rules": "^0.12", - "phpunit/phpunit": "^9.5" + "infection/infection": "^0.29", + "lcobucci/coding-standard": "^11.1.0", + "phpstan/extension-installer": "^1.3.1", + "phpstan/phpstan": "^1.10.25", + "phpstan/phpstan-deprecation-rules": "^1.1.3", + "phpstan/phpstan-phpunit": "^1.3.13", + "phpstan/phpstan-strict-rules": "^1.5.1", + "phpunit/phpunit": "^11.3.6" }, "type": "library", "autoload": { @@ -2736,7 +2696,7 @@ "description": "Yet another clock abstraction", "support": { "issues": "https://github.com/lcobucci/clock/issues", - "source": "https://github.com/lcobucci/clock/tree/2.2.0" + "source": "https://github.com/lcobucci/clock/tree/3.3.1" }, "funding": [ { @@ -2748,43 +2708,42 @@ "type": "patreon" } ], - "time": "2022-04-19T19:34:17+00:00" + "time": "2024-09-24T20:45:14+00:00" }, { "name": "lcobucci/jwt", - "version": "4.2.1", + "version": "5.5.0", "source": { "type": "git", "url": "https://github.com/lcobucci/jwt.git", - "reference": "72ac6d807ee51a70ad376ee03a2387e8646e10f3" + "reference": "a835af59b030d3f2967725697cf88300f579088e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/lcobucci/jwt/zipball/72ac6d807ee51a70ad376ee03a2387e8646e10f3", - "reference": "72ac6d807ee51a70ad376ee03a2387e8646e10f3", + "url": "https://api.github.com/repos/lcobucci/jwt/zipball/a835af59b030d3f2967725697cf88300f579088e", + "reference": "a835af59b030d3f2967725697cf88300f579088e", "shasum": "" }, "require": { - "ext-hash": "*", - "ext-json": "*", - "ext-mbstring": "*", "ext-openssl": "*", "ext-sodium": "*", - "lcobucci/clock": "^2.0", - "php": "^7.4 || ^8.0" + "php": "~8.2.0 || ~8.3.0 || ~8.4.0", + "psr/clock": "^1.0" }, "require-dev": { - "infection/infection": "^0.21", - "lcobucci/coding-standard": "^6.0", - "mikey179/vfsstream": "^1.6.7", + "infection/infection": "^0.29", + "lcobucci/clock": "^3.2", + "lcobucci/coding-standard": "^11.0", "phpbench/phpbench": "^1.2", - "phpstan/extension-installer": "^1.0", - "phpstan/phpstan": "^1.4", - "phpstan/phpstan-deprecation-rules": "^1.0", - "phpstan/phpstan-phpunit": "^1.0", - "phpstan/phpstan-strict-rules": "^1.0", - "phpunit/php-invoker": "^3.1", - "phpunit/phpunit": "^9.5" + "phpstan/extension-installer": "^1.2", + "phpstan/phpstan": "^1.10.7", + "phpstan/phpstan-deprecation-rules": "^1.1.3", + "phpstan/phpstan-phpunit": "^1.3.10", + "phpstan/phpstan-strict-rules": "^1.5.0", + "phpunit/phpunit": "^11.1" + }, + "suggest": { + "lcobucci/clock": ">= 3.2" }, "type": "library", "autoload": { @@ -2810,7 +2769,7 @@ ], "support": { "issues": "https://github.com/lcobucci/jwt/issues", - "source": "https://github.com/lcobucci/jwt/tree/4.2.1" + "source": "https://github.com/lcobucci/jwt/tree/5.5.0" }, "funding": [ { @@ -2822,52 +2781,48 @@ "type": "patreon" } ], - "time": "2022-08-19T23:14:07+00:00" + "time": "2025-01-26T21:29:45+00:00" }, { "name": "lexik/jwt-authentication-bundle", - "version": "v2.16.0", + "version": "v3.1.1", "source": { "type": "git", "url": "https://github.com/lexik/LexikJWTAuthenticationBundle.git", - "reference": "0a0922a2442c52724c09deb099b263300cc12d54" + "reference": "ebe0e2c6a0ae17b4702feffc89e32e3aaba6cb61" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/lexik/LexikJWTAuthenticationBundle/zipball/0a0922a2442c52724c09deb099b263300cc12d54", - "reference": "0a0922a2442c52724c09deb099b263300cc12d54", + "url": "https://api.github.com/repos/lexik/LexikJWTAuthenticationBundle/zipball/ebe0e2c6a0ae17b4702feffc89e32e3aaba6cb61", + "reference": "ebe0e2c6a0ae17b4702feffc89e32e3aaba6cb61", "shasum": "" }, "require": { "ext-openssl": "*", - "lcobucci/jwt": "^3.4|^4.0", - "namshi/jose": "^7.2", - "php": ">=7.1", - "symfony/config": "^4.4|^5.3|^6.0", - "symfony/dependency-injection": "^4.4|^5.3|^6.0", + "lcobucci/clock": "^3.0", + "lcobucci/jwt": "^5.0", + "php": ">=8.2", + "symfony/config": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", "symfony/deprecation-contracts": "^2.4|^3.0", - "symfony/event-dispatcher": "^4.4|^5.3|^6.0", - "symfony/http-foundation": "^4.4|^5.3|^6.0", - "symfony/http-kernel": "^4.4|^5.3|^6.0", - "symfony/property-access": "^4.4|^5.3|^6.0", - "symfony/security-bundle": "^4.4|^5.3|^6.0", - "symfony/security-core": "^4.4|^5.3|^6.0", - "symfony/security-http": "^4.4|^5.3|^6.0", + "symfony/event-dispatcher": "^6.4|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/property-access": "^6.4|^7.0", + "symfony/security-bundle": "^6.4|^7.0", "symfony/translation-contracts": "^1.0|^2.0|^3.0" }, - "conflict": { - "symfony/console": "<4.4" - }, "require-dev": { - "symfony/browser-kit": "^4.4|^5.3|^6.0", - "symfony/console": "^4.4|^5.3|^6.0", - "symfony/dom-crawler": "^4.4|^5.3|^6.0", - "symfony/filesystem": "^4.4|^5.3|^6.0", - "symfony/framework-bundle": "^4.4|^5.3|^6.0", - "symfony/phpunit-bridge": "^4.4|^5.3|^6.0", - "symfony/security-guard": "^4.4|^5.3", - "symfony/var-dumper": "^4.4|^5.3|^6.0", - "symfony/yaml": "^4.4|^5.3|^6.0" + "api-platform/core": "^3.0|^4.0", + "rector/rector": "^1.2", + "symfony/browser-kit": "^6.4|^7.0", + "symfony/console": "^6.4|^7.0", + "symfony/dom-crawler": "^6.4|^7.0", + "symfony/filesystem": "^6.4|^7.0", + "symfony/framework-bundle": "^6.4|^7.0", + "symfony/phpunit-bridge": "^6.4|^7.0", + "symfony/var-dumper": "^6.4|^7.0", + "symfony/yaml": "^6.4|^7.0" }, "suggest": { "gesdinet/jwt-refresh-token-bundle": "Implements a refresh token system over Json Web Tokens in Symfony", @@ -2930,7 +2885,7 @@ ], "support": { "issues": "https://github.com/lexik/LexikJWTAuthenticationBundle/issues", - "source": "https://github.com/lexik/LexikJWTAuthenticationBundle/tree/v2.16.0" + "source": "https://github.com/lexik/LexikJWTAuthenticationBundle/tree/v3.1.1" }, "funding": [ { @@ -2942,20 +2897,20 @@ "type": "tidelift" } ], - "time": "2022-06-12T16:22:12+00:00" + "time": "2025-01-06T16:34:57+00:00" }, { "name": "monolog/monolog", - "version": "3.2.0", + "version": "3.8.1", "source": { "type": "git", "url": "https://github.com/Seldaek/monolog.git", - "reference": "305444bc6fb6c89e490f4b34fa6e979584d7fa81" + "reference": "aef6ee73a77a66e404dd6540934a9ef1b3c855b4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Seldaek/monolog/zipball/305444bc6fb6c89e490f4b34fa6e979584d7fa81", - "reference": "305444bc6fb6c89e490f4b34fa6e979584d7fa81", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/aef6ee73a77a66e404dd6540934a9ef1b3c855b4", + "reference": "aef6ee73a77a66e404dd6540934a9ef1b3c855b4", "shasum": "" }, "require": { @@ -2970,17 +2925,19 @@ "doctrine/couchdb": "~1.0@dev", "elasticsearch/elasticsearch": "^7 || ^8", "ext-json": "*", - "graylog2/gelf-php": "^1.4.2", - "guzzlehttp/guzzle": "^7.4", + "graylog2/gelf-php": "^1.4.2 || ^2.0", + "guzzlehttp/guzzle": "^7.4.5", "guzzlehttp/psr7": "^2.2", "mongodb/mongodb": "^1.8", "php-amqplib/php-amqplib": "~2.4 || ^3", - "phpstan/phpstan": "^1.4", - "phpstan/phpstan-deprecation-rules": "^1.0", - "phpstan/phpstan-strict-rules": "^1.1", - "phpunit/phpunit": "^9.5.16", - "predis/predis": "^1.1", - "ruflin/elastica": "^7", + "php-console/php-console": "^3.1.8", + "phpstan/phpstan": "^2", + "phpstan/phpstan-deprecation-rules": "^2", + "phpstan/phpstan-strict-rules": "^2", + "phpunit/phpunit": "^10.5.17 || ^11.0.7", + "predis/predis": "^1.1 || ^2", + "rollbar/rollbar": "^4.0", + "ruflin/elastica": "^7 || ^8", "symfony/mailer": "^5.4 || ^6", "symfony/mime": "^5.4 || ^6" }, @@ -3031,7 +2988,7 @@ ], "support": { "issues": "https://github.com/Seldaek/monolog/issues", - "source": "https://github.com/Seldaek/monolog/tree/3.2.0" + "source": "https://github.com/Seldaek/monolog/tree/3.8.1" }, "funding": [ { @@ -3043,143 +3000,88 @@ "type": "tidelift" } ], - "time": "2022-07-24T12:00:55+00:00" - }, - { - "name": "namshi/jose", - "version": "7.2.3", - "source": { - "type": "git", - "url": "https://github.com/namshi/jose.git", - "reference": "89a24d7eb3040e285dd5925fcad992378b82bcff" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/namshi/jose/zipball/89a24d7eb3040e285dd5925fcad992378b82bcff", - "reference": "89a24d7eb3040e285dd5925fcad992378b82bcff", - "shasum": "" - }, - "require": { - "ext-date": "*", - "ext-hash": "*", - "ext-json": "*", - "ext-pcre": "*", - "ext-spl": "*", - "php": ">=5.5", - "symfony/polyfill-php56": "^1.0" - }, - "require-dev": { - "phpseclib/phpseclib": "^2.0", - "phpunit/phpunit": "^4.5|^5.0", - "satooshi/php-coveralls": "^1.0" - }, - "suggest": { - "ext-openssl": "Allows to use OpenSSL as crypto engine.", - "phpseclib/phpseclib": "Allows to use Phpseclib as crypto engine, use version ^2.0." - }, - "type": "library", - "autoload": { - "psr-4": { - "Namshi\\JOSE\\": "src/Namshi/JOSE/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Alessandro Nadalin", - "email": "alessandro.nadalin@gmail.com" - }, - { - "name": "Alessandro Cinelli (cirpo)", - "email": "alessandro.cinelli@gmail.com" - } - ], - "description": "JSON Object Signing and Encryption library for PHP.", - "keywords": [ - "JSON Web Signature", - "JSON Web Token", - "JWS", - "json", - "jwt", - "token" - ], - "support": { - "issues": "https://github.com/namshi/jose/issues", - "source": "https://github.com/namshi/jose/tree/master" - }, - "time": "2016-12-05T07:27:31+00:00" + "time": "2024-12-05T17:15:07+00:00" }, { "name": "nelmio/api-doc-bundle", - "version": "v4.9.0", + "version": "v4.36.1", "source": { "type": "git", "url": "https://github.com/nelmio/NelmioApiDocBundle.git", - "reference": "da02f3ad339437b939a6d309e9c98b62afe53c6c" + "reference": "cdc855ef8e6a811336c3a6c72fe99fbe13a78e37" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nelmio/NelmioApiDocBundle/zipball/da02f3ad339437b939a6d309e9c98b62afe53c6c", - "reference": "da02f3ad339437b939a6d309e9c98b62afe53c6c", + "url": "https://api.github.com/repos/nelmio/NelmioApiDocBundle/zipball/cdc855ef8e6a811336c3a6c72fe99fbe13a78e37", + "reference": "cdc855ef8e6a811336c3a6c72fe99fbe13a78e37", "shasum": "" }, "require": { - "doctrine/annotations": "^1.11", "ext-json": "*", - "php": ">=7.2", - "phpdocumentor/reflection-docblock": "^3.1|^4.0|^5.0", - "psr/cache": "^1.0|^2.0|^3.0", - "psr/container": "^1.0|^2.0", - "psr/log": "^1.0|^2.0|^3.0", - "symfony/config": "^4.4|^5.0|^6.0", - "symfony/console": "^4.4|^5.0|^6.0", - "symfony/dependency-injection": "^4.4|^5.0|^6.0", - "symfony/framework-bundle": "^4.4|^5.0|^6.0", - "symfony/http-foundation": "^4.4|^5.0|^6.0", - "symfony/http-kernel": "^4.4|^5.0|^6.0", - "symfony/options-resolver": "^4.4|^5.0|^6.0", - "symfony/property-info": "^4.4|^5.0|^6.0", - "symfony/routing": "^4.4|^5.0|^6.0", - "zircote/swagger-php": "^3.2|^4.0" + "php": ">=7.4", + "phpdocumentor/reflection-docblock": "^4.3.4 || ^5.0", + "phpdocumentor/type-resolver": "^1.8.2", + "psr/cache": "^1.0 || ^2.0 || ^3.0", + "psr/container": "^1.0 || ^2.0", + "psr/log": "^1.0 || ^2.0 || ^3.0", + "symfony/config": "^5.4 || ^6.4 || ^7.1", + "symfony/console": "^5.4 || ^6.4 || ^7.1", + "symfony/dependency-injection": "^5.4 || ^6.4 || ^7.1", + "symfony/deprecation-contracts": "^2.1 || ^3", + "symfony/framework-bundle": "^5.4.24 || ^6.4 || ^7.1", + "symfony/http-foundation": "^5.4 || ^6.4 || ^7.1", + "symfony/http-kernel": "^5.4 || ^6.4 || ^7.1", + "symfony/options-resolver": "^5.4 || ^6.4 || ^7.1", + "symfony/property-info": "^5.4.10 || ^6.4 || ^7.1", + "symfony/routing": "^5.4 || ^6.4 || ^7.1", + "zircote/swagger-php": "^4.11.1 || ^5.0" }, "conflict": { - "symfony/framework-bundle": "4.2.7" + "zircote/swagger-php": "4.8.7" }, "require-dev": { - "api-platform/core": "^2.6.8", + "api-platform/core": "^2.7.0 || ^3", "composer/package-versions-deprecated": "1.11.99.1", - "friendsofsymfony/rest-bundle": "^2.8|^3.0", - "jms/serializer": "^1.14|^3.0", - "jms/serializer-bundle": "^2.3|^3.0|^4.0", - "sensio/framework-extra-bundle": "^4.4|^5.2|^6.0", - "symfony/asset": "^4.4|^5.2|^6.0", - "symfony/browser-kit": "^4.4|^5.2|^6.0", - "symfony/cache": "^4.4|^5.2|^6.0", - "symfony/dom-crawler": "^4.4|^5.2|^6.0", - "symfony/form": "^4.4|^5.2|^6.0", - "symfony/phpunit-bridge": "^5.2", - "symfony/property-access": "^4.4|^5.2|^6.0", - "symfony/serializer": "^4.4|^5.2|^6.0", - "symfony/stopwatch": "^4.4|^5.2|^6.0", - "symfony/templating": "^4.4|^5.2|^6.0", - "symfony/twig-bundle": "^4.4|^5.2|^6.0", - "symfony/validator": "^4.4|^5.2|^6.0", - "willdurand/hateoas-bundle": "^1.0|^2.0" + "doctrine/annotations": "^2.0", + "friendsofphp/php-cs-fixer": "^3.52", + "friendsofsymfony/rest-bundle": "^2.8 || ^3.0", + "jms/serializer": "^1.14 || ^3.0", + "jms/serializer-bundle": "^2.3 || ^3.0 || ^4.0 || ^5.0", + "phpstan/phpstan": "^1.10", + "phpstan/phpstan-phpunit": "^1.3", + "phpstan/phpstan-strict-rules": "^1.5", + "phpstan/phpstan-symfony": "^1.3", + "phpunit/phpunit": "^9.6 || ^10.5", + "symfony/asset": "^5.4 || ^6.4 || ^7.1", + "symfony/browser-kit": "^5.4 || ^6.4 || ^7.1", + "symfony/cache": "^5.4 || ^6.4 || ^7.1", + "symfony/dom-crawler": "^5.4 || ^6.4 || ^7.1", + "symfony/expression-language": "^5.4 || ^6.4 || ^7.1", + "symfony/form": "^5.4 || ^6.4 || ^7.1", + "symfony/phpunit-bridge": "^6.4", + "symfony/property-access": "^5.4 || ^6.4 || ^7.1", + "symfony/security-csrf": "^5.4 || ^6.4 || ^7.1", + "symfony/serializer": "^5.4 || ^6.4 || ^7.1", + "symfony/stopwatch": "^5.4 || ^6.4 || ^7.1", + "symfony/templating": "^5.4 || ^6.4 || ^7.1", + "symfony/twig-bundle": "^5.4 || ^6.4 || ^7.1", + "symfony/uid": "^5.4 || ^6.4 || ^7.1", + "symfony/validator": "^5.4 || ^6.4 || ^7.1", + "willdurand/hateoas-bundle": "^1.0 || ^2.0" }, "suggest": { "api-platform/core": "For using an API oriented framework.", + "doctrine/annotations": "For using doctrine annotations", "friendsofsymfony/rest-bundle": "For using the parameters annotations.", "jms/serializer-bundle": "For describing your models.", "symfony/asset": "For using the Swagger UI.", "symfony/cache": "For using a PSR-6 compatible cache implementation with the API doc generator.", "symfony/form": "For describing your form type models.", "symfony/monolog-bundle": "For using a PSR-3 compatible logger implementation with the API PHP describer.", + "symfony/security-csrf": "For using csrf protection tokens in forms.", "symfony/serializer": "For describing your models.", + "symfony/twig-bundle": "For using the Swagger UI.", "symfony/validator": "For describing the validation constraints in your models.", - "twig/twig-bundle": "For using the Swagger UI.", "willdurand/hateoas-bundle": "For extracting HATEOAS metadata." }, "type": "symfony-bundle", @@ -3190,27 +3092,20 @@ }, "autoload": { "psr-4": { - "Nelmio\\ApiDocBundle\\": "" - }, - "exclude-from-classmap": [ - "Tests/" - ] + "Nelmio\\ApiDocBundle\\": "src/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ - { - "name": "Nelmio", - "homepage": "http://nelm.io" - }, { "name": "Symfony Community", "homepage": "https://github.com/nelmio/NelmioApiDocBundle/contributors" } ], - "description": "Generates documentation for your REST API from annotations", + "description": "Generates documentation for your REST API from annotations and attributes", "keywords": [ "api", "doc", @@ -3219,35 +3114,42 @@ ], "support": { "issues": "https://github.com/nelmio/NelmioApiDocBundle/issues", - "source": "https://github.com/nelmio/NelmioApiDocBundle/tree/v4.9.0" + "source": "https://github.com/nelmio/NelmioApiDocBundle/tree/v4.36.1" }, - "time": "2022-04-30T18:28:05+00:00" + "funding": [ + { + "url": "https://github.com/DjordyKoert", + "type": "github" + } + ], + "time": "2025-01-19T17:01:30+00:00" }, { "name": "nelmio/cors-bundle", - "version": "2.2.0", + "version": "2.5.0", "source": { "type": "git", "url": "https://github.com/nelmio/NelmioCorsBundle.git", - "reference": "0ee5ee30b0ee08ea122d431ae6e0ddeb87f035c0" + "reference": "3a526fe025cd20e04a6a11370cf5ab28dbb5a544" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nelmio/NelmioCorsBundle/zipball/0ee5ee30b0ee08ea122d431ae6e0ddeb87f035c0", - "reference": "0ee5ee30b0ee08ea122d431ae6e0ddeb87f035c0", + "url": "https://api.github.com/repos/nelmio/NelmioCorsBundle/zipball/3a526fe025cd20e04a6a11370cf5ab28dbb5a544", + "reference": "3a526fe025cd20e04a6a11370cf5ab28dbb5a544", "shasum": "" }, "require": { - "symfony/framework-bundle": "^4.3 || ^5.0 || ^6.0" + "psr/log": "^1.0 || ^2.0 || ^3.0", + "symfony/framework-bundle": "^5.4 || ^6.0 || ^7.0" }, "require-dev": { - "mockery/mockery": "^1.2", - "symfony/phpunit-bridge": "^4.3 || ^5.0 || ^6.0" + "mockery/mockery": "^1.3.6", + "symfony/phpunit-bridge": "^5.4 || ^6.0 || ^7.0" }, "type": "symfony-bundle", "extra": { "branch-alias": { - "dev-master": "2.0.x-dev" + "dev-master": "2.x-dev" } }, "autoload": { @@ -3280,9 +3182,67 @@ ], "support": { "issues": "https://github.com/nelmio/NelmioCorsBundle/issues", - "source": "https://github.com/nelmio/NelmioCorsBundle/tree/2.2.0" + "source": "https://github.com/nelmio/NelmioCorsBundle/tree/2.5.0" + }, + "time": "2024-06-24T21:25:28+00:00" + }, + { + "name": "nikic/php-parser", + "version": "v5.4.0", + "source": { + "type": "git", + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "447a020a1f875a434d62f2a401f53b82a396e494" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/447a020a1f875a434d62f2a401f53b82a396e494", + "reference": "447a020a1f875a434d62f2a401f53b82a396e494", + "shasum": "" + }, + "require": { + "ext-ctype": "*", + "ext-json": "*", + "ext-tokenizer": "*", + "php": ">=7.4" + }, + "require-dev": { + "ircmaxell/php-yacc": "^0.0.7", + "phpunit/phpunit": "^9.0" + }, + "bin": [ + "bin/php-parse" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.0-dev" + } + }, + "autoload": { + "psr-4": { + "PhpParser\\": "lib/PhpParser" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Nikita Popov" + } + ], + "description": "A PHP parser written in PHP", + "keywords": [ + "parser", + "php" + ], + "support": { + "issues": "https://github.com/nikic/PHP-Parser/issues", + "source": "https://github.com/nikic/PHP-Parser/tree/v5.4.0" }, - "time": "2021-12-01T09:34:27+00:00" + "time": "2024-12-30T11:07:19+00:00" }, { "name": "phpdocumentor/reflection-common", @@ -3339,28 +3299,35 @@ }, { "name": "phpdocumentor/reflection-docblock", - "version": "5.3.0", + "version": "5.6.1", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "622548b623e81ca6d78b721c5e029f4ce664f170" + "reference": "e5e784149a09bd69d9a5e3b01c5cbd2e2bd653d8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/622548b623e81ca6d78b721c5e029f4ce664f170", - "reference": "622548b623e81ca6d78b721c5e029f4ce664f170", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/e5e784149a09bd69d9a5e3b01c5cbd2e2bd653d8", + "reference": "e5e784149a09bd69d9a5e3b01c5cbd2e2bd653d8", "shasum": "" }, "require": { + "doctrine/deprecations": "^1.1", "ext-filter": "*", - "php": "^7.2 || ^8.0", + "php": "^7.4 || ^8.0", "phpdocumentor/reflection-common": "^2.2", - "phpdocumentor/type-resolver": "^1.3", + "phpdocumentor/type-resolver": "^1.7", + "phpstan/phpdoc-parser": "^1.7|^2.0", "webmozart/assert": "^1.9.1" }, "require-dev": { - "mockery/mockery": "~1.3.2", - "psalm/phar": "^4.8" + "mockery/mockery": "~1.3.5 || ~1.6.0", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan": "^1.8", + "phpstan/phpstan-mockery": "^1.1", + "phpstan/phpstan-webmozart-assert": "^1.2", + "phpunit/phpunit": "^9.5", + "psalm/phar": "^5.26" }, "type": "library", "extra": { @@ -3384,37 +3351,45 @@ }, { "name": "Jaap van Otterdijk", - "email": "account@ijaap.nl" + "email": "opensource@ijaap.nl" } ], "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", "support": { "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", - "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.3.0" + "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.6.1" }, - "time": "2021-10-19T17:43:47+00:00" + "time": "2024-12-07T09:39:29+00:00" }, { "name": "phpdocumentor/type-resolver", - "version": "1.6.1", + "version": "1.10.0", "source": { "type": "git", "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "77a32518733312af16a44300404e945338981de3" + "reference": "679e3ce485b99e84c775d28e2e96fade9a7fb50a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/77a32518733312af16a44300404e945338981de3", - "reference": "77a32518733312af16a44300404e945338981de3", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/679e3ce485b99e84c775d28e2e96fade9a7fb50a", + "reference": "679e3ce485b99e84c775d28e2e96fade9a7fb50a", "shasum": "" }, "require": { - "php": "^7.2 || ^8.0", - "phpdocumentor/reflection-common": "^2.0" + "doctrine/deprecations": "^1.0", + "php": "^7.3 || ^8.0", + "phpdocumentor/reflection-common": "^2.0", + "phpstan/phpdoc-parser": "^1.18|^2.0" }, "require-dev": { "ext-tokenizer": "*", - "psalm/phar": "^4.8" + "phpbench/phpbench": "^1.2", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan": "^1.8", + "phpstan/phpstan-phpunit": "^1.1", + "phpunit/phpunit": "^9.5", + "rector/rector": "^0.13.9", + "vimeo/psalm": "^4.25" }, "type": "library", "extra": { @@ -3440,9 +3415,56 @@ "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", "support": { "issues": "https://github.com/phpDocumentor/TypeResolver/issues", - "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.6.1" + "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.10.0" + }, + "time": "2024-11-09T15:12:26+00:00" + }, + { + "name": "phpstan/phpdoc-parser", + "version": "1.33.0", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpdoc-parser.git", + "reference": "82a311fd3690fb2bf7b64d5c98f912b3dd746140" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/82a311fd3690fb2bf7b64d5c98f912b3dd746140", + "reference": "82a311fd3690fb2bf7b64d5c98f912b3dd746140", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "require-dev": { + "doctrine/annotations": "^2.0", + "nikic/php-parser": "^4.15", + "php-parallel-lint/php-parallel-lint": "^1.2", + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "^1.5", + "phpstan/phpstan-phpunit": "^1.1", + "phpstan/phpstan-strict-rules": "^1.0", + "phpunit/phpunit": "^9.5", + "symfony/process": "^5.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "PHPStan\\PhpDocParser\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHPDoc parser with support for nullable, intersection and generic types", + "support": { + "issues": "https://github.com/phpstan/phpdoc-parser/issues", + "source": "https://github.com/phpstan/phpdoc-parser/tree/1.33.0" }, - "time": "2022-03-15T21:29:03+00:00" + "time": "2024-10-13T11:25:22+00:00" }, { "name": "psr/cache", @@ -3493,6 +3515,54 @@ }, "time": "2021-02-03T23:26:27+00:00" }, + { + "name": "psr/clock", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/clock.git", + "reference": "e41a24703d4560fd0acb709162f73b8adfc3aa0d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/clock/zipball/e41a24703d4560fd0acb709162f73b8adfc3aa0d", + "reference": "e41a24703d4560fd0acb709162f73b8adfc3aa0d", + "shasum": "" + }, + "require": { + "php": "^7.0 || ^8.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Psr\\Clock\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for reading the clock.", + "homepage": "https://github.com/php-fig/clock", + "keywords": [ + "clock", + "now", + "psr", + "psr-20", + "time" + ], + "support": { + "issues": "https://github.com/php-fig/clock/issues", + "source": "https://github.com/php-fig/clock/tree/1.0.0" + }, + "time": "2022-11-25T14:36:26+00:00" + }, { "name": "psr/container", "version": "2.0.2", @@ -3654,16 +3724,16 @@ }, { "name": "psr/log", - "version": "3.0.0", + "version": "3.0.2", "source": { "type": "git", "url": "https://github.com/php-fig/log.git", - "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001" + "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/fe5ea303b0887d5caefd3d431c3e61ad47037001", - "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001", + "url": "https://api.github.com/repos/php-fig/log/zipball/f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", + "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", "shasum": "" }, "require": { @@ -3698,48 +3768,58 @@ "psr-3" ], "support": { - "source": "https://github.com/php-fig/log/tree/3.0.0" + "source": "https://github.com/php-fig/log/tree/3.0.2" }, - "time": "2021-07-14T16:46:02+00:00" + "time": "2024-09-11T13:17:53+00:00" }, { "name": "ramsey/collection", - "version": "1.2.2", + "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/ramsey/collection.git", - "reference": "cccc74ee5e328031b15640b51056ee8d3bb66c0a" + "reference": "a4b48764bfbb8f3a6a4d1aeb1a35bb5e9ecac4a5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ramsey/collection/zipball/cccc74ee5e328031b15640b51056ee8d3bb66c0a", - "reference": "cccc74ee5e328031b15640b51056ee8d3bb66c0a", + "url": "https://api.github.com/repos/ramsey/collection/zipball/a4b48764bfbb8f3a6a4d1aeb1a35bb5e9ecac4a5", + "reference": "a4b48764bfbb8f3a6a4d1aeb1a35bb5e9ecac4a5", "shasum": "" }, "require": { - "php": "^7.3 || ^8", - "symfony/polyfill-php81": "^1.23" + "php": "^8.1" }, "require-dev": { - "captainhook/captainhook": "^5.3", - "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0", - "ergebnis/composer-normalize": "^2.6", - "fakerphp/faker": "^1.5", - "hamcrest/hamcrest-php": "^2", - "jangregor/phpstan-prophecy": "^0.8", - "mockery/mockery": "^1.3", + "captainhook/plugin-composer": "^5.3", + "ergebnis/composer-normalize": "^2.28.3", + "fakerphp/faker": "^1.21", + "hamcrest/hamcrest-php": "^2.0", + "jangregor/phpstan-prophecy": "^1.0", + "mockery/mockery": "^1.5", + "php-parallel-lint/php-console-highlighter": "^1.0", + "php-parallel-lint/php-parallel-lint": "^1.3", + "phpcsstandards/phpcsutils": "^1.0.0-rc1", "phpspec/prophecy-phpunit": "^2.0", - "phpstan/extension-installer": "^1", - "phpstan/phpstan": "^0.12.32", - "phpstan/phpstan-mockery": "^0.12.5", - "phpstan/phpstan-phpunit": "^0.12.11", - "phpunit/phpunit": "^8.5 || ^9", - "psy/psysh": "^0.10.4", - "slevomat/coding-standard": "^6.3", - "squizlabs/php_codesniffer": "^3.5", - "vimeo/psalm": "^4.4" + "phpstan/extension-installer": "^1.2", + "phpstan/phpstan": "^1.9", + "phpstan/phpstan-mockery": "^1.1", + "phpstan/phpstan-phpunit": "^1.3", + "phpunit/phpunit": "^9.5", + "psalm/plugin-mockery": "^1.1", + "psalm/plugin-phpunit": "^0.18.4", + "ramsey/coding-standard": "^2.0.3", + "ramsey/conventional-commits": "^1.3", + "vimeo/psalm": "^5.4" }, "type": "library", + "extra": { + "captainhook": { + "force-install": true + }, + "ramsey/conventional-commits": { + "configFile": "conventional-commits.json" + } + }, "autoload": { "psr-4": { "Ramsey\\Collection\\": "src/" @@ -3767,7 +3847,7 @@ ], "support": { "issues": "https://github.com/ramsey/collection/issues", - "source": "https://github.com/ramsey/collection/tree/1.2.2" + "source": "https://github.com/ramsey/collection/tree/2.0.0" }, "funding": [ { @@ -3779,28 +3859,27 @@ "type": "tidelift" } ], - "time": "2021-10-10T03:01:02+00:00" + "time": "2022-12-31T21:50:55+00:00" }, { "name": "ramsey/uuid", - "version": "4.4.0", + "version": "4.7.6", "source": { "type": "git", "url": "https://github.com/ramsey/uuid.git", - "reference": "373f7bacfcf3de038778ff27dcce5672ddbf4c8a" + "reference": "91039bc1faa45ba123c4328958e620d382ec7088" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ramsey/uuid/zipball/373f7bacfcf3de038778ff27dcce5672ddbf4c8a", - "reference": "373f7bacfcf3de038778ff27dcce5672ddbf4c8a", + "url": "https://api.github.com/repos/ramsey/uuid/zipball/91039bc1faa45ba123c4328958e620d382ec7088", + "reference": "91039bc1faa45ba123c4328958e620d382ec7088", "shasum": "" }, "require": { - "brick/math": "^0.8 || ^0.9 || ^0.10", - "ext-ctype": "*", + "brick/math": "^0.8.8 || ^0.9 || ^0.10 || ^0.11 || ^0.12", "ext-json": "*", "php": "^8.0", - "ramsey/collection": "^1.0" + "ramsey/collection": "^1.2 || ^2.0" }, "replace": { "rhumsaa/uuid": "self.version" @@ -3817,18 +3896,18 @@ "php-mock/php-mock-mockery": "^1.3", "php-parallel-lint/php-parallel-lint": "^1.1", "phpbench/phpbench": "^1.0", - "phpstan/extension-installer": "^1.0", - "phpstan/phpstan": "^0.12", - "phpstan/phpstan-mockery": "^0.12", - "phpstan/phpstan-phpunit": "^0.12", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan": "^1.8", + "phpstan/phpstan-mockery": "^1.1", + "phpstan/phpstan-phpunit": "^1.1", "phpunit/phpunit": "^8.5 || ^9", - "slevomat/coding-standard": "^7.0", + "ramsey/composer-repl": "^1.4", + "slevomat/coding-standard": "^8.4", "squizlabs/php_codesniffer": "^3.5", "vimeo/psalm": "^4.9" }, "suggest": { "ext-bcmath": "Enables faster math with arbitrary-precision integers using BCMath.", - "ext-ctype": "Enables faster processing of character classification using ctype functions.", "ext-gmp": "Enables faster math with arbitrary-precision integers using GMP.", "ext-uuid": "Enables the use of PeclUuidTimeGenerator and PeclUuidRandomGenerator.", "paragonie/random-lib": "Provides RandomLib for use with the RandomLibAdapter", @@ -3860,7 +3939,7 @@ ], "support": { "issues": "https://github.com/ramsey/uuid/issues", - "source": "https://github.com/ramsey/uuid/tree/4.4.0" + "source": "https://github.com/ramsey/uuid/tree/4.7.6" }, "funding": [ { @@ -3872,37 +3951,54 @@ "type": "tidelift" } ], - "time": "2022-08-05T17:58:37+00:00" + "time": "2024-04-27T21:32:50+00:00" }, { "name": "ramsey/uuid-doctrine", - "version": "1.8.1", + "version": "2.1.0", "source": { "type": "git", "url": "https://github.com/ramsey/uuid-doctrine.git", - "reference": "1a6f235ba3faf1cd9ba18daf5b54d8dc9d3bc7d0" + "reference": "491e1bfa4d9d81e52a60470fa92c871f7eef919e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ramsey/uuid-doctrine/zipball/1a6f235ba3faf1cd9ba18daf5b54d8dc9d3bc7d0", - "reference": "1a6f235ba3faf1cd9ba18daf5b54d8dc9d3bc7d0", + "url": "https://api.github.com/repos/ramsey/uuid-doctrine/zipball/491e1bfa4d9d81e52a60470fa92c871f7eef919e", + "reference": "491e1bfa4d9d81e52a60470fa92c871f7eef919e", "shasum": "" }, "require": { - "doctrine/dbal": "^2.5 || ^3.0", - "php": "^5.4 || ^7 || ^8", - "ramsey/uuid": "^3.5 || ^4" + "doctrine/dbal": "^2.8 || ^3.0 || ^4.0", + "php": "^8.1", + "ramsey/uuid": "^3.9.7 || ^4.0" }, "require-dev": { - "doctrine/orm": "^2.5", - "mockery/mockery": "^0.9.11 || ^1", - "php-parallel-lint/php-parallel-lint": "^1", - "phpunit/phpunit": "^4.8.36 || ^5.7 || ^6.5 || ^7 || ^8 || ^9", - "squizlabs/php_codesniffer": "^3.5" + "captainhook/plugin-composer": "^5.3", + "doctrine/orm": "^2.5 || ^3.0", + "ergebnis/composer-normalize": "^2.28.3", + "mockery/mockery": "^1.5", + "php-parallel-lint/php-console-highlighter": "^1.0", + "php-parallel-lint/php-parallel-lint": "^1.3", + "phpcsstandards/phpcsutils": "^1.0.0-alpha4", + "phpstan/extension-installer": "^1.2", + "phpstan/phpstan": "^1.9", + "phpstan/phpstan-mockery": "^1.1", + "phpstan/phpstan-phpunit": "^1.3", + "phpunit/phpunit": "^10.5", + "ramsey/coding-standard": "^2.0.3", + "ramsey/conventional-commits": "^1.3" }, "type": "library", - "autoload": { - "psr-4": { + "extra": { + "captainhook": { + "force-install": true + }, + "ramsey/conventional-commits": { + "configFile": "conventional-commits.json" + } + }, + "autoload": { + "psr-4": { "Ramsey\\Uuid\\Doctrine\\": "src/" } }, @@ -3927,7 +4023,7 @@ ], "support": { "issues": "https://github.com/ramsey/uuid-doctrine/issues", - "source": "https://github.com/ramsey/uuid-doctrine/tree/1.8.1" + "source": "https://github.com/ramsey/uuid-doctrine/tree/2.1.0" }, "funding": [ { @@ -3939,27 +4035,28 @@ "type": "tidelift" } ], - "time": "2022-01-15T23:54:44+00:00" + "time": "2024-05-27T00:00:21+00:00" }, { "name": "react/promise", - "version": "v2.9.0", + "version": "v3.2.0", "source": { "type": "git", "url": "https://github.com/reactphp/promise.git", - "reference": "234f8fd1023c9158e2314fa9d7d0e6a83db42910" + "reference": "8a164643313c71354582dc850b42b33fa12a4b63" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/reactphp/promise/zipball/234f8fd1023c9158e2314fa9d7d0e6a83db42910", - "reference": "234f8fd1023c9158e2314fa9d7d0e6a83db42910", + "url": "https://api.github.com/repos/reactphp/promise/zipball/8a164643313c71354582dc850b42b33fa12a4b63", + "reference": "8a164643313c71354582dc850b42b33fa12a4b63", "shasum": "" }, "require": { - "php": ">=5.4.0" + "php": ">=7.1.0" }, "require-dev": { - "phpunit/phpunit": "^9.3 || ^5.7 || ^4.8.36" + "phpstan/phpstan": "1.10.39 || 1.4.10", + "phpunit/phpunit": "^9.6 || ^7.5" }, "type": "library", "autoload": { @@ -4003,46 +4100,43 @@ ], "support": { "issues": "https://github.com/reactphp/promise/issues", - "source": "https://github.com/reactphp/promise/tree/v2.9.0" + "source": "https://github.com/reactphp/promise/tree/v3.2.0" }, "funding": [ { - "url": "https://github.com/WyriHaximus", - "type": "github" - }, - { - "url": "https://github.com/clue", - "type": "github" + "url": "https://opencollective.com/reactphp", + "type": "open_collective" } ], - "time": "2022-02-11T10:27:51+00:00" + "time": "2024-05-24T10:39:05+00:00" }, { "name": "runtime/swoole", - "version": "0.3.1", + "version": "0.4.0", "source": { "type": "git", "url": "https://github.com/php-runtime/swoole.git", - "reference": "eeba8e5987a00b02cc6732a64a948956b5362942" + "reference": "d27c224770b16e9ac6a6752ef862fe83cadf87f6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-runtime/swoole/zipball/eeba8e5987a00b02cc6732a64a948956b5362942", - "reference": "eeba8e5987a00b02cc6732a64a948956b5362942", + "url": "https://api.github.com/repos/php-runtime/swoole/zipball/d27c224770b16e9ac6a6752ef862fe83cadf87f6", + "reference": "d27c224770b16e9ac6a6752ef862fe83cadf87f6", "shasum": "" }, "require": { - "symfony/runtime": "^5.3 || ^6.0" + "php": ">=8.1", + "symfony/runtime": "^5.4.26 || ^6.3.2 || ^7.0" }, "conflict": { "ext-swoole": "<4.6.0" }, "require-dev": { - "illuminate/http": "^8.48", + "illuminate/http": "^9.14", + "phpunit/phpunit": "^9.6.15", "swoole/ide-helper": "^4.6", - "symfony/http-foundation": "^5.3 || ^6.0", - "symfony/http-kernel": "^5.4 || ^6.0", - "symfony/phpunit-bridge": "^5.3" + "symfony/http-foundation": "^5.4.32 || ^6.3.9 || ^7.0", + "symfony/http-kernel": "^5.4.33 || ^6.3.10 || ^7.0" }, "type": "library", "autoload": { @@ -4062,7 +4156,7 @@ ], "description": "Swoole runtime", "support": { - "source": "https://github.com/php-runtime/swoole/tree/0.3.1" + "source": "https://github.com/php-runtime/swoole/tree/0.4.0" }, "funding": [ { @@ -4070,27 +4164,27 @@ "type": "github" } ], - "time": "2022-02-26T17:19:48+00:00" + "time": "2023-12-12T11:39:12+00:00" }, { "name": "seld/jsonlint", - "version": "1.9.0", + "version": "1.11.0", "source": { "type": "git", "url": "https://github.com/Seldaek/jsonlint.git", - "reference": "4211420d25eba80712bff236a98960ef68b866b7" + "reference": "1748aaf847fc731cfad7725aec413ee46f0cc3a2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Seldaek/jsonlint/zipball/4211420d25eba80712bff236a98960ef68b866b7", - "reference": "4211420d25eba80712bff236a98960ef68b866b7", + "url": "https://api.github.com/repos/Seldaek/jsonlint/zipball/1748aaf847fc731cfad7725aec413ee46f0cc3a2", + "reference": "1748aaf847fc731cfad7725aec413ee46f0cc3a2", "shasum": "" }, "require": { "php": "^5.3 || ^7.0 || ^8.0" }, "require-dev": { - "phpstan/phpstan": "^1.5", + "phpstan/phpstan": "^1.11", "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0 || ^8.5.13" }, "bin": [ @@ -4110,7 +4204,7 @@ { "name": "Jordi Boggiano", "email": "j.boggiano@seld.be", - "homepage": "http://seld.be" + "homepage": "https://seld.be" } ], "description": "JSON Linter", @@ -4122,7 +4216,7 @@ ], "support": { "issues": "https://github.com/Seldaek/jsonlint/issues", - "source": "https://github.com/Seldaek/jsonlint/tree/1.9.0" + "source": "https://github.com/Seldaek/jsonlint/tree/1.11.0" }, "funding": [ { @@ -4134,7 +4228,7 @@ "type": "tidelift" } ], - "time": "2022-04-01T13:37:23+00:00" + "time": "2024-07-11T14:55:45+00:00" }, { "name": "seld/phar-utils", @@ -4186,16 +4280,16 @@ }, { "name": "seld/signal-handler", - "version": "2.0.1", + "version": "2.0.2", "source": { "type": "git", "url": "https://github.com/Seldaek/signal-handler.git", - "reference": "f69d119511dc0360440cdbdaa71829c149b7be75" + "reference": "04a6112e883ad76c0ada8e4a9f7520bbfdb6bb98" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Seldaek/signal-handler/zipball/f69d119511dc0360440cdbdaa71829c149b7be75", - "reference": "f69d119511dc0360440cdbdaa71829c149b7be75", + "url": "https://api.github.com/repos/Seldaek/signal-handler/zipball/04a6112e883ad76c0ada8e4a9f7520bbfdb6bb98", + "reference": "04a6112e883ad76c0ada8e4a9f7520bbfdb6bb98", "shasum": "" }, "require": { @@ -4241,61 +4335,62 @@ ], "support": { "issues": "https://github.com/Seldaek/signal-handler/issues", - "source": "https://github.com/Seldaek/signal-handler/tree/2.0.1" + "source": "https://github.com/Seldaek/signal-handler/tree/2.0.2" }, - "time": "2022-07-20T18:31:45+00:00" + "time": "2023-09-03T09:24:00+00:00" }, { "name": "snc/redis-bundle", - "version": "4.3.0", + "version": "4.8.0", "source": { "type": "git", "url": "https://github.com/snc/SncRedisBundle.git", - "reference": "5ac15ab0824a4a4448ba27edd2e2773c159c373d" + "reference": "1577b80bda8b488c45ebe14fdb72e42273c3aa8b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/snc/SncRedisBundle/zipball/5ac15ab0824a4a4448ba27edd2e2773c159c373d", - "reference": "5ac15ab0824a4a4448ba27edd2e2773c159c373d", + "url": "https://api.github.com/repos/snc/SncRedisBundle/zipball/1577b80bda8b488c45ebe14fdb72e42273c3aa8b", + "reference": "1577b80bda8b488c45ebe14fdb72e42273c3aa8b", "shasum": "" }, "require": { "php": "^7.4 || ^8.0", - "symfony/framework-bundle": "^4.4 || ^5.3 || ^6.0", - "symfony/http-foundation": "^4.4 || ^5.3 || ^6.0", - "symfony/var-dumper": "^4.4 || ^5.3 || ^6.0" + "symfony/deprecation-contracts": "^2 || ^3", + "symfony/framework-bundle": "^5.4.20 ||^6.0 || ^7.0", + "symfony/http-foundation": "^5.4.20 ||^6.0 || ^7.0", + "symfony/service-contracts": ">=1.0", + "symfony/var-dumper": "^5.4.20 ||^6.0 || ^7.0" }, "conflict": { - "ext-redis": "<5.3", - "predis/predis": "<1.1,>=2.0" + "ext-redis": "<5.3.2", + "predis/predis": "<2.0" }, "require-dev": { - "doctrine/annotations": "^1.13", - "doctrine/coding-standard": "^9.0", + "doctrine/annotations": "^2.0", + "doctrine/coding-standard": "^12.0", "ext-pdo_sqlite": "*", "ext-redis": "*", "friendsofphp/proxy-manager-lts": "^1.0.6", "monolog/monolog": "*", - "phpunit/phpunit": "^8.5 || ^9.5", - "predis/predis": ">=1.1", - "symfony/browser-kit": "^4.4 || ^5.3 || ^6.0", - "symfony/cache": "^4.4 || ^5.3 || ^6.0", - "symfony/console": "^4.4 || ^5.3 || ^6.0", - "symfony/dom-crawler": "^4.4 || ^5.3 || ^6.0", - "symfony/filesystem": "^4.4 || ^5.3 || ^6.0", - "symfony/phpunit-bridge": "^6.0", - "symfony/profiler-pack": "^1.0", - "symfony/proxy-manager-bridge": "^4.4 || ^5.3 || ^6.0", - "symfony/stopwatch": "^4.4 || ^5.3 || ^6.0", - "symfony/twig-bundle": "^4.4 || ^5.3 || ^6.0", - "symfony/yaml": "^4.4 || ^5.3 || ^6.0", - "vimeo/psalm": "^4.13" + "phpunit/phpunit": "^9.5.28 || ^10", + "predis/predis": "^2.0", + "seec/phpunit-consecutive-params": "dev-master", + "symfony/browser-kit": "^5.4.20 ||^6.0 || ^7.0", + "symfony/cache": "^5.4.20 ||^6.0 || ^7.0", + "symfony/config": "^5.4.20 ||^6.0 || ^7.0", + "symfony/console": "^5.4.20 ||^6.0 || ^7.0", + "symfony/dom-crawler": "^5.4.20 ||^6.0 || ^7.0", + "symfony/filesystem": "^5.4.20 ||^6.0 || ^7.0", + "symfony/stopwatch": "^5.4.20 ||^6.0 || ^7.0", + "symfony/twig-bundle": "^5.4.20 ||^6.0 || ^7.0", + "symfony/web-profiler-bundle": "^5.4.20 ||^6.0 || ^7.0", + "symfony/yaml": "^5.4.20 ||^6.0 || ^7.0", + "vimeo/psalm": "^5.2" }, "suggest": { "monolog/monolog": "If you want to use the monolog redis handler.", "predis/predis": "If you want to use predis.", - "symfony/console": "If you want to use commands to interact with the redis database", - "symfony/proxy-manager-bridge": "If you want to lazy-load some services" + "symfony/console": "If you want to use commands to interact with the redis database" }, "type": "symfony-bundle", "extra": { @@ -4331,79 +4426,42 @@ ], "support": { "issues": "https://github.com/snc/SncRedisBundle/issues", - "source": "https://github.com/snc/SncRedisBundle/tree/4.3.0" - }, - "time": "2022-07-13T20:58:05+00:00" - }, - { - "name": "stella-maris/clock", - "version": "0.1.5", - "source": { - "type": "git", - "url": "git@gitlab.com:stella-maris/clock.git", - "reference": "447879c53ca0b2a762cdbfba5e76ccf4deca9158" - }, - "dist": { - "type": "zip", - "url": "https://gitlab.com/api/v4/projects/stella-maris%2Fclock/repository/archive.zip?sha=447879c53ca0b2a762cdbfba5e76ccf4deca9158", - "reference": "447879c53ca0b2a762cdbfba5e76ccf4deca9158", - "shasum": "" + "source": "https://github.com/snc/SncRedisBundle/tree/4.8.0" }, - "require": { - "php": "^7.0|^8.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "StellaMaris\\Clock\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Andreas Heigl", - "role": "Maintainer" - } - ], - "description": "A pre-release of the proposed PSR-20 Clock-Interface", - "homepage": "https://gitlab.com/stella-maris/clock", - "keywords": [ - "clock", - "datetime", - "point in time", - "psr20" - ], - "time": "2022-08-05T07:21:25+00:00" + "time": "2024-12-13T13:33:19+00:00" }, { "name": "stof/doctrine-extensions-bundle", - "version": "v1.7.0", + "version": "v1.13.0", "source": { "type": "git", "url": "https://github.com/stof/StofDoctrineExtensionsBundle.git", - "reference": "a2bffca41974d1c968557b343e269a60a8d5ffa4" + "reference": "bf00701bff3f2b7c4bf6d963101c9ea6968d694f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/stof/StofDoctrineExtensionsBundle/zipball/a2bffca41974d1c968557b343e269a60a8d5ffa4", - "reference": "a2bffca41974d1c968557b343e269a60a8d5ffa4", + "url": "https://api.github.com/repos/stof/StofDoctrineExtensionsBundle/zipball/bf00701bff3f2b7c4bf6d963101c9ea6968d694f", + "reference": "bf00701bff3f2b7c4bf6d963101c9ea6968d694f", "shasum": "" }, "require": { - "gedmo/doctrine-extensions": "^2.3.4 || ^3.0.0", - "php": "^7.1.3 || ^8.0", - "symfony/config": "^4.4 || ^5.2 || ^6.0", - "symfony/dependency-injection": "^4.4 || ^5.2 || ^6.0", - "symfony/event-dispatcher": "^4.4 || ^5.2 || ^6.0", - "symfony/http-kernel": "^4.4 || ^5.2 || ^6.0" - }, - "require-dev": { - "symfony/mime": "^4.4 || ^5.2 || ^6.0", - "symfony/phpunit-bridge": "^v5.2.4 || ^6.0", - "symfony/security-core": "^4.4 || ^5.2 || ^6.0" + "gedmo/doctrine-extensions": "^3.15.0", + "php": "^7.4 || ^8.0", + "symfony/cache": "^5.4 || ^6.0 || ^7.0", + "symfony/config": "^5.4 || ^6.0 || ^7.0", + "symfony/dependency-injection": "^5.4 || ^6.0 || ^7.0", + "symfony/event-dispatcher": "^5.4 || ^6.0 || ^7.0", + "symfony/http-kernel": "^5.4 || ^6.0 || ^7.0" + }, + "require-dev": { + "phpstan/phpstan": "^1.10", + "phpstan/phpstan-deprecation-rules": "^1.1", + "phpstan/phpstan-phpunit": "^1.3", + "phpstan/phpstan-strict-rules": "^1.5", + "phpstan/phpstan-symfony": "^1.3", + "symfony/mime": "^5.4 || ^6.0 || ^7.0", + "symfony/phpunit-bridge": "^v6.4.1 || ^7.0.1", + "symfony/security-core": "^5.4 || ^6.0 || ^7.0" }, "suggest": { "doctrine/doctrine-bundle": "to use the ORM extensions", @@ -4448,34 +4506,34 @@ ], "support": { "issues": "https://github.com/stof/StofDoctrineExtensionsBundle/issues", - "source": "https://github.com/stof/StofDoctrineExtensionsBundle/tree/v1.7.0" + "source": "https://github.com/stof/StofDoctrineExtensionsBundle/tree/v1.13.0" }, - "time": "2021-11-22T15:17:44+00:00" + "time": "2025-01-07T08:10:54+00:00" }, { "name": "symfony/amqp-messenger", - "version": "v6.1.3", + "version": "v7.2.3", "source": { "type": "git", "url": "https://github.com/symfony/amqp-messenger.git", - "reference": "7362b11e45346ea1ee93391a901c10621c42a37d" + "reference": "a90a95cef8e8290157aa97a74e4f03c34b575e12" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/amqp-messenger/zipball/7362b11e45346ea1ee93391a901c10621c42a37d", - "reference": "7362b11e45346ea1ee93391a901c10621c42a37d", + "url": "https://api.github.com/repos/symfony/amqp-messenger/zipball/a90a95cef8e8290157aa97a74e4f03c34b575e12", + "reference": "a90a95cef8e8290157aa97a74e4f03c34b575e12", "shasum": "" }, "require": { "ext-amqp": "*", - "php": ">=8.1", - "symfony/messenger": "^6.1" + "php": ">=8.2", + "symfony/messenger": "^6.4|^7.0" }, "require-dev": { - "symfony/event-dispatcher": "^5.4|^6.0", - "symfony/process": "^5.4|^6.0", - "symfony/property-access": "^5.4|^6.0", - "symfony/serializer": "^5.4|^6.0" + "symfony/event-dispatcher": "^6.4|^7.0", + "symfony/process": "^6.4|^7.0", + "symfony/property-access": "^6.4|^7.0", + "symfony/serializer": "^6.4|^7.0" }, "type": "symfony-messenger-bridge", "autoload": { @@ -4503,7 +4561,7 @@ "description": "Symfony AMQP extension Messenger Bridge", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/amqp-messenger/tree/v6.1.3" + "source": "https://github.com/symfony/amqp-messenger/tree/v7.2.3" }, "funding": [ { @@ -4519,35 +4577,32 @@ "type": "tidelift" } ], - "time": "2022-06-27T17:24:16+00:00" + "time": "2025-01-17T10:56:55+00:00" }, { "name": "symfony/asset", - "version": "v6.1.0", + "version": "v7.2.0", "source": { "type": "git", "url": "https://github.com/symfony/asset.git", - "reference": "dc6f572f142627d42ba88a42ea34f79d3776ee6c" + "reference": "cb926cd59fefa1f9b4900b3695f0f846797ba5c0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/asset/zipball/dc6f572f142627d42ba88a42ea34f79d3776ee6c", - "reference": "dc6f572f142627d42ba88a42ea34f79d3776ee6c", + "url": "https://api.github.com/repos/symfony/asset/zipball/cb926cd59fefa1f9b4900b3695f0f846797ba5c0", + "reference": "cb926cd59fefa1f9b4900b3695f0f846797ba5c0", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.2" }, "conflict": { - "symfony/http-foundation": "<5.4" + "symfony/http-foundation": "<6.4" }, "require-dev": { - "symfony/http-client": "^5.4|^6.0", - "symfony/http-foundation": "^5.4|^6.0", - "symfony/http-kernel": "^5.4|^6.0" - }, - "suggest": { - "symfony/http-foundation": "" + "symfony/http-client": "^6.4|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0" }, "type": "library", "autoload": { @@ -4575,7 +4630,7 @@ "description": "Manages URL generation and versioning of web assets such as CSS stylesheets, JavaScript files and image files", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/asset/tree/v6.1.0" + "source": "https://github.com/symfony/asset/tree/v7.2.0" }, "funding": [ { @@ -4591,35 +4646,36 @@ "type": "tidelift" } ], - "time": "2022-04-14T08:23:11+00:00" + "time": "2024-10-25T15:15:23+00:00" }, { "name": "symfony/cache", - "version": "v6.1.3", + "version": "v7.2.3", "source": { "type": "git", "url": "https://github.com/symfony/cache.git", - "reference": "5cf8e75f02932818889e0609380b8d5427a6c86c" + "reference": "8d773a575e446de220dca03d600b2d8e1c1c10ec" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/cache/zipball/5cf8e75f02932818889e0609380b8d5427a6c86c", - "reference": "5cf8e75f02932818889e0609380b8d5427a6c86c", + "url": "https://api.github.com/repos/symfony/cache/zipball/8d773a575e446de220dca03d600b2d8e1c1c10ec", + "reference": "8d773a575e446de220dca03d600b2d8e1c1c10ec", "shasum": "" }, "require": { - "php": ">=8.1", + "php": ">=8.2", "psr/cache": "^2.0|^3.0", "psr/log": "^1.1|^2|^3", - "symfony/cache-contracts": "^1.1.7|^2|^3", - "symfony/service-contracts": "^1.1|^2|^3", - "symfony/var-exporter": "^5.4|^6.0" + "symfony/cache-contracts": "^2.5|^3", + "symfony/deprecation-contracts": "^2.5|^3.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/var-exporter": "^6.4|^7.0" }, "conflict": { - "doctrine/dbal": "<2.13.1", - "symfony/dependency-injection": "<5.4", - "symfony/http-kernel": "<5.4", - "symfony/var-dumper": "<5.4" + "doctrine/dbal": "<3.6", + "symfony/dependency-injection": "<6.4", + "symfony/http-kernel": "<6.4", + "symfony/var-dumper": "<6.4" }, "provide": { "psr/cache-implementation": "2.0|3.0", @@ -4628,15 +4684,16 @@ }, "require-dev": { "cache/integration-tests": "dev-master", - "doctrine/dbal": "^2.13.1|^3.0", - "predis/predis": "^1.1", + "doctrine/dbal": "^3.6|^4", + "predis/predis": "^1.1|^2.0", "psr/simple-cache": "^1.0|^2.0|^3.0", - "symfony/config": "^5.4|^6.0", - "symfony/dependency-injection": "^5.4|^6.0", - "symfony/filesystem": "^5.4|^6.0", - "symfony/http-kernel": "^5.4|^6.0", - "symfony/messenger": "^5.4|^6.0", - "symfony/var-dumper": "^5.4|^6.0" + "symfony/clock": "^6.4|^7.0", + "symfony/config": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/filesystem": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/messenger": "^6.4|^7.0", + "symfony/var-dumper": "^6.4|^7.0" }, "type": "library", "autoload": { @@ -4664,14 +4721,14 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Provides an extended PSR-6, PSR-16 (and tags) implementation", + "description": "Provides extended PSR-6, PSR-16 (and tags) implementations", "homepage": "https://symfony.com", "keywords": [ "caching", "psr6" ], "support": { - "source": "https://github.com/symfony/cache/tree/v6.1.3" + "source": "https://github.com/symfony/cache/tree/v7.2.3" }, "funding": [ { @@ -4687,37 +4744,34 @@ "type": "tidelift" } ], - "time": "2022-07-29T07:42:06+00:00" + "time": "2025-01-27T11:08:17+00:00" }, { "name": "symfony/cache-contracts", - "version": "v3.1.1", + "version": "v3.5.1", "source": { "type": "git", "url": "https://github.com/symfony/cache-contracts.git", - "reference": "2eab7fa459af6d75c6463e63e633b667a9b761d3" + "reference": "15a4f8e5cd3bce9aeafc882b1acab39ec8de2c1b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/cache-contracts/zipball/2eab7fa459af6d75c6463e63e633b667a9b761d3", - "reference": "2eab7fa459af6d75c6463e63e633b667a9b761d3", + "url": "https://api.github.com/repos/symfony/cache-contracts/zipball/15a4f8e5cd3bce9aeafc882b1acab39ec8de2c1b", + "reference": "15a4f8e5cd3bce9aeafc882b1acab39ec8de2c1b", "shasum": "" }, "require": { "php": ">=8.1", "psr/cache": "^3.0" }, - "suggest": { - "symfony/cache-implementation": "" - }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "3.1-dev" - }, "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.5-dev" } }, "autoload": { @@ -4750,7 +4804,81 @@ "standards" ], "support": { - "source": "https://github.com/symfony/cache-contracts/tree/v3.1.1" + "source": "https://github.com/symfony/cache-contracts/tree/v3.5.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-25T14:20:29+00:00" + }, + { + "name": "symfony/clock", + "version": "v7.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/clock.git", + "reference": "b81435fbd6648ea425d1ee96a2d8e68f4ceacd24" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/clock/zipball/b81435fbd6648ea425d1ee96a2d8e68f4ceacd24", + "reference": "b81435fbd6648ea425d1ee96a2d8e68f4ceacd24", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "psr/clock": "^1.0", + "symfony/polyfill-php83": "^1.28" + }, + "provide": { + "psr/clock-implementation": "1.0" + }, + "type": "library", + "autoload": { + "files": [ + "Resources/now.php" + ], + "psr-4": { + "Symfony\\Component\\Clock\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Decouples applications from the system clock", + "homepage": "https://symfony.com", + "keywords": [ + "clock", + "psr20", + "time" + ], + "support": { + "source": "https://github.com/symfony/clock/tree/v7.2.0" }, "funding": [ { @@ -4766,40 +4894,38 @@ "type": "tidelift" } ], - "time": "2022-02-25T11:15:52+00:00" + "time": "2024-09-25T14:21:43+00:00" }, { "name": "symfony/config", - "version": "v6.1.3", + "version": "v7.2.3", "source": { "type": "git", "url": "https://github.com/symfony/config.git", - "reference": "a0645dc585d378b73c01115dd7ab9348f7d40c85" + "reference": "7716594aaae91d9141be080240172a92ecca4d44" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/a0645dc585d378b73c01115dd7ab9348f7d40c85", - "reference": "a0645dc585d378b73c01115dd7ab9348f7d40c85", + "url": "https://api.github.com/repos/symfony/config/zipball/7716594aaae91d9141be080240172a92ecca4d44", + "reference": "7716594aaae91d9141be080240172a92ecca4d44", "shasum": "" }, "require": { - "php": ">=8.1", - "symfony/deprecation-contracts": "^2.1|^3", - "symfony/filesystem": "^5.4|^6.0", + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/filesystem": "^7.1", "symfony/polyfill-ctype": "~1.8" }, "conflict": { - "symfony/finder": "<5.4" + "symfony/finder": "<6.4", + "symfony/service-contracts": "<2.5" }, "require-dev": { - "symfony/event-dispatcher": "^5.4|^6.0", - "symfony/finder": "^5.4|^6.0", - "symfony/messenger": "^5.4|^6.0", - "symfony/service-contracts": "^1.1|^2|^3", - "symfony/yaml": "^5.4|^6.0" - }, - "suggest": { - "symfony/yaml": "To use the yaml reference dumper" + "symfony/event-dispatcher": "^6.4|^7.0", + "symfony/finder": "^6.4|^7.0", + "symfony/messenger": "^6.4|^7.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/yaml": "^6.4|^7.0" }, "type": "library", "autoload": { @@ -4827,7 +4953,7 @@ "description": "Helps you find, load, combine, autofill and validate configuration values of any kind", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/config/tree/v6.1.3" + "source": "https://github.com/symfony/config/tree/v7.2.3" }, "funding": [ { @@ -4843,53 +4969,50 @@ "type": "tidelift" } ], - "time": "2022-07-20T15:00:40+00:00" + "time": "2025-01-22T12:07:01+00:00" }, { "name": "symfony/console", - "version": "v6.1.4", + "version": "v7.2.1", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "7fccea8728aa2d431a6725b02b3ce759049fc84d" + "reference": "fefcc18c0f5d0efe3ab3152f15857298868dc2c3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/7fccea8728aa2d431a6725b02b3ce759049fc84d", - "reference": "7fccea8728aa2d431a6725b02b3ce759049fc84d", + "url": "https://api.github.com/repos/symfony/console/zipball/fefcc18c0f5d0efe3ab3152f15857298868dc2c3", + "reference": "fefcc18c0f5d0efe3ab3152f15857298868dc2c3", "shasum": "" }, "require": { - "php": ">=8.1", - "symfony/deprecation-contracts": "^2.1|^3", + "php": ">=8.2", "symfony/polyfill-mbstring": "~1.0", - "symfony/service-contracts": "^1.1|^2|^3", - "symfony/string": "^5.4|^6.0" + "symfony/service-contracts": "^2.5|^3", + "symfony/string": "^6.4|^7.0" }, "conflict": { - "symfony/dependency-injection": "<5.4", - "symfony/dotenv": "<5.4", - "symfony/event-dispatcher": "<5.4", - "symfony/lock": "<5.4", - "symfony/process": "<5.4" + "symfony/dependency-injection": "<6.4", + "symfony/dotenv": "<6.4", + "symfony/event-dispatcher": "<6.4", + "symfony/lock": "<6.4", + "symfony/process": "<6.4" }, "provide": { "psr/log-implementation": "1.0|2.0|3.0" }, "require-dev": { "psr/log": "^1|^2|^3", - "symfony/config": "^5.4|^6.0", - "symfony/dependency-injection": "^5.4|^6.0", - "symfony/event-dispatcher": "^5.4|^6.0", - "symfony/lock": "^5.4|^6.0", - "symfony/process": "^5.4|^6.0", - "symfony/var-dumper": "^5.4|^6.0" - }, - "suggest": { - "psr/log": "For using the console logger", - "symfony/event-dispatcher": "", - "symfony/lock": "", - "symfony/process": "" + "symfony/config": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/event-dispatcher": "^6.4|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/lock": "^6.4|^7.0", + "symfony/messenger": "^6.4|^7.0", + "symfony/process": "^6.4|^7.0", + "symfony/stopwatch": "^6.4|^7.0", + "symfony/var-dumper": "^6.4|^7.0" }, "type": "library", "autoload": { @@ -4918,12 +5041,12 @@ "homepage": "https://symfony.com", "keywords": [ "cli", - "command line", + "command-line", "console", "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v6.1.4" + "source": "https://github.com/symfony/console/tree/v7.2.1" }, "funding": [ { @@ -4939,50 +5062,43 @@ "type": "tidelift" } ], - "time": "2022-08-26T10:32:31+00:00" + "time": "2024-12-11T03:49:26+00:00" }, { "name": "symfony/dependency-injection", - "version": "v6.1.3", + "version": "v7.2.3", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "079e336a1880f457b219aecc3d41bef2f1093b0b" + "reference": "1d321c4bc3fe926fd4c38999a4c9af4f5d61ddfc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/079e336a1880f457b219aecc3d41bef2f1093b0b", - "reference": "079e336a1880f457b219aecc3d41bef2f1093b0b", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/1d321c4bc3fe926fd4c38999a4c9af4f5d61ddfc", + "reference": "1d321c4bc3fe926fd4c38999a4c9af4f5d61ddfc", "shasum": "" }, "require": { - "php": ">=8.1", + "php": ">=8.2", "psr/container": "^1.1|^2.0", - "symfony/deprecation-contracts": "^2.1|^3", - "symfony/service-contracts": "^1.1.6|^2.0|^3.0" + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/service-contracts": "^3.5", + "symfony/var-exporter": "^6.4|^7.0" }, "conflict": { "ext-psr": "<1.1|>=2", - "symfony/config": "<6.1", - "symfony/finder": "<5.4", - "symfony/proxy-manager-bridge": "<5.4", - "symfony/yaml": "<5.4" + "symfony/config": "<6.4", + "symfony/finder": "<6.4", + "symfony/yaml": "<6.4" }, "provide": { "psr/container-implementation": "1.1|2.0", "symfony/service-implementation": "1.1|2.0|3.0" }, "require-dev": { - "symfony/config": "^6.1", - "symfony/expression-language": "^5.4|^6.0", - "symfony/yaml": "^5.4|^6.0" - }, - "suggest": { - "symfony/config": "", - "symfony/expression-language": "For using expressions in service container configuration", - "symfony/finder": "For using double-star glob patterns or when GLOB_BRACE portability is required", - "symfony/proxy-manager-bridge": "Generate service proxies to lazy load them", - "symfony/yaml": "" + "symfony/config": "^6.4|^7.0", + "symfony/expression-language": "^6.4|^7.0", + "symfony/yaml": "^6.4|^7.0" }, "type": "library", "autoload": { @@ -5010,7 +5126,7 @@ "description": "Allows you to standardize and centralize the way objects are constructed in your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/dependency-injection/tree/v6.1.3" + "source": "https://github.com/symfony/dependency-injection/tree/v7.2.3" }, "funding": [ { @@ -5026,20 +5142,20 @@ "type": "tidelift" } ], - "time": "2022-07-20T13:46:29+00:00" + "time": "2025-01-17T10:56:55+00:00" }, { "name": "symfony/deprecation-contracts", - "version": "v3.1.1", + "version": "v3.5.1", "source": { "type": "git", "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "07f1b9cc2ffee6aaafcf4b710fbc38ff736bd918" + "reference": "74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/07f1b9cc2ffee6aaafcf4b710fbc38ff736bd918", - "reference": "07f1b9cc2ffee6aaafcf4b710fbc38ff736bd918", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6", + "reference": "74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6", "shasum": "" }, "require": { @@ -5047,12 +5163,12 @@ }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "3.1-dev" - }, "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.5-dev" } }, "autoload": { @@ -5077,7 +5193,7 @@ "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v3.1.1" + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.5.1" }, "funding": [ { @@ -5093,78 +5209,72 @@ "type": "tidelift" } ], - "time": "2022-02-25T11:15:52+00:00" + "time": "2024-09-25T14:20:29+00:00" }, { "name": "symfony/doctrine-bridge", - "version": "v6.1.3", + "version": "v7.2.3", "source": { "type": "git", "url": "https://github.com/symfony/doctrine-bridge.git", - "reference": "68b53b14f337dbc6f92cf6f1656a0adad42482e0" + "reference": "7a183fdfb472c5487480baa128a41ed47367723e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/doctrine-bridge/zipball/68b53b14f337dbc6f92cf6f1656a0adad42482e0", - "reference": "68b53b14f337dbc6f92cf6f1656a0adad42482e0", + "url": "https://api.github.com/repos/symfony/doctrine-bridge/zipball/7a183fdfb472c5487480baa128a41ed47367723e", + "reference": "7a183fdfb472c5487480baa128a41ed47367723e", "shasum": "" }, "require": { - "doctrine/event-manager": "~1.0", - "doctrine/persistence": "^2|^3", - "php": ">=8.1", - "symfony/deprecation-contracts": "^2.1|^3", + "doctrine/event-manager": "^2", + "doctrine/persistence": "^3.1|^4", + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3", "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-mbstring": "~1.0", - "symfony/service-contracts": "^1.1|^2|^3" + "symfony/service-contracts": "^2.5|^3" }, "conflict": { - "doctrine/dbal": "<2.13.1", + "doctrine/collections": "<1.8", + "doctrine/dbal": "<3.6", "doctrine/lexer": "<1.1", - "doctrine/orm": "<2.7.4", - "phpunit/phpunit": "<5.4.3", - "symfony/cache": "<5.4", - "symfony/dependency-injection": "<5.4", - "symfony/form": "<5.4", - "symfony/http-kernel": "<5.4", - "symfony/messenger": "<5.4", - "symfony/property-info": "<5.4", - "symfony/security-bundle": "<5.4", - "symfony/security-core": "<6.0", - "symfony/validator": "<5.4" - }, - "require-dev": { - "doctrine/annotations": "^1.10.4", - "doctrine/collections": "~1.0", - "doctrine/data-fixtures": "^1.1", - "doctrine/dbal": "^2.13.1|^3.0", - "doctrine/orm": "^2.7.4", + "doctrine/orm": "<2.15", + "symfony/cache": "<6.4", + "symfony/dependency-injection": "<6.4", + "symfony/form": "<6.4.6|>=7,<7.0.6", + "symfony/http-foundation": "<6.4", + "symfony/http-kernel": "<6.4", + "symfony/lock": "<6.4", + "symfony/messenger": "<6.4", + "symfony/property-info": "<6.4", + "symfony/security-bundle": "<6.4", + "symfony/security-core": "<6.4", + "symfony/validator": "<6.4" + }, + "require-dev": { + "doctrine/collections": "^1.8|^2.0", + "doctrine/data-fixtures": "^1.1|^2", + "doctrine/dbal": "^3.6|^4", + "doctrine/orm": "^2.15|^3", "psr/log": "^1|^2|^3", - "symfony/cache": "^5.4|^6.0", - "symfony/config": "^5.4|^6.0", - "symfony/dependency-injection": "^5.4|^6.0", - "symfony/doctrine-messenger": "^5.4|^6.0", - "symfony/expression-language": "^5.4|^6.0", - "symfony/form": "^5.4.9|^6.0.9", - "symfony/http-kernel": "^5.4|^6.0", - "symfony/messenger": "^5.4|^6.0", - "symfony/property-access": "^5.4|^6.0", - "symfony/property-info": "^5.4|^6.0", - "symfony/proxy-manager-bridge": "^5.4|^6.0", - "symfony/security-core": "^6.0", - "symfony/stopwatch": "^5.4|^6.0", - "symfony/translation": "^5.4|^6.0", - "symfony/uid": "^5.4|^6.0", - "symfony/validator": "^5.4|^6.0", - "symfony/var-dumper": "^5.4|^6.0" - }, - "suggest": { - "doctrine/data-fixtures": "", - "doctrine/dbal": "", - "doctrine/orm": "", - "symfony/form": "", - "symfony/property-info": "", - "symfony/validator": "" + "symfony/cache": "^6.4|^7.0", + "symfony/config": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/doctrine-messenger": "^6.4|^7.0", + "symfony/expression-language": "^6.4|^7.0", + "symfony/form": "^6.4.6|^7.0.6", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/lock": "^6.4|^7.0", + "symfony/messenger": "^6.4|^7.0", + "symfony/property-access": "^6.4|^7.0", + "symfony/property-info": "^6.4|^7.0", + "symfony/security-core": "^6.4|^7.0", + "symfony/stopwatch": "^6.4|^7.0", + "symfony/translation": "^6.4|^7.0", + "symfony/type-info": "^7.1", + "symfony/uid": "^6.4|^7.0", + "symfony/validator": "^6.4|^7.0", + "symfony/var-dumper": "^6.4|^7.0" }, "type": "symfony-bridge", "autoload": { @@ -5192,7 +5302,7 @@ "description": "Provides integration for Doctrine with various Symfony components", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/doctrine-bridge/tree/v6.1.3" + "source": "https://github.com/symfony/doctrine-bridge/tree/v7.2.3" }, "funding": [ { @@ -5208,35 +5318,35 @@ "type": "tidelift" } ], - "time": "2022-07-29T07:42:06+00:00" + "time": "2025-01-27T11:08:17+00:00" }, { "name": "symfony/doctrine-messenger", - "version": "v6.1.4", + "version": "v7.2.3", "source": { "type": "git", "url": "https://github.com/symfony/doctrine-messenger.git", - "reference": "b7587ed78b788a65958592ec5dccd226a0f6fd8e" + "reference": "55cd0f79415b3ae18587df903926c8e5d2b51f25" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/doctrine-messenger/zipball/b7587ed78b788a65958592ec5dccd226a0f6fd8e", - "reference": "b7587ed78b788a65958592ec5dccd226a0f6fd8e", + "url": "https://api.github.com/repos/symfony/doctrine-messenger/zipball/55cd0f79415b3ae18587df903926c8e5d2b51f25", + "reference": "55cd0f79415b3ae18587df903926c8e5d2b51f25", "shasum": "" }, "require": { - "doctrine/dbal": "^2.13|^3.0", - "php": ">=8.1", - "symfony/messenger": "^5.4|^6.0", - "symfony/service-contracts": "^1.1|^2|^3" + "doctrine/dbal": "^3.6|^4", + "php": ">=8.2", + "symfony/messenger": "^6.4|^7.0", + "symfony/service-contracts": "^2.5|^3" }, "conflict": { "doctrine/persistence": "<1.3" }, "require-dev": { "doctrine/persistence": "^1.3|^2|^3", - "symfony/property-access": "^5.4|^6.0", - "symfony/serializer": "^5.4|^6.0" + "symfony/property-access": "^6.4|^7.0", + "symfony/serializer": "^6.4|^7.0" }, "type": "symfony-messenger-bridge", "autoload": { @@ -5264,7 +5374,7 @@ "description": "Symfony Doctrine Messenger Bridge", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/doctrine-messenger/tree/v6.1.4" + "source": "https://github.com/symfony/doctrine-messenger/tree/v7.2.3" }, "funding": [ { @@ -5280,31 +5390,32 @@ "type": "tidelift" } ], - "time": "2022-08-12T13:09:07+00:00" + "time": "2025-01-07T09:39:55+00:00" }, { "name": "symfony/dotenv", - "version": "v6.1.0", + "version": "v7.2.0", "source": { "type": "git", "url": "https://github.com/symfony/dotenv.git", - "reference": "568c11bcedf419e7e61f663912c3547b54de51df" + "reference": "28347a897771d0c28e99b75166dd2689099f3045" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dotenv/zipball/568c11bcedf419e7e61f663912c3547b54de51df", - "reference": "568c11bcedf419e7e61f663912c3547b54de51df", + "url": "https://api.github.com/repos/symfony/dotenv/zipball/28347a897771d0c28e99b75166dd2689099f3045", + "reference": "28347a897771d0c28e99b75166dd2689099f3045", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.2" }, "conflict": { - "symfony/console": "<5.4" + "symfony/console": "<6.4", + "symfony/process": "<6.4" }, "require-dev": { - "symfony/console": "^5.4|^6.0", - "symfony/process": "^5.4|^6.0" + "symfony/console": "^6.4|^7.0", + "symfony/process": "^6.4|^7.0" }, "type": "library", "autoload": { @@ -5337,7 +5448,7 @@ "environment" ], "support": { - "source": "https://github.com/symfony/dotenv/tree/v6.1.0" + "source": "https://github.com/symfony/dotenv/tree/v7.2.0" }, "funding": [ { @@ -5353,31 +5464,35 @@ "type": "tidelift" } ], - "time": "2022-04-01T07:15:35+00:00" + "time": "2024-11-27T11:18:42+00:00" }, { "name": "symfony/error-handler", - "version": "v6.1.3", + "version": "v7.2.3", "source": { "type": "git", "url": "https://github.com/symfony/error-handler.git", - "reference": "736e42db3fd586d91820355988698e434e1d8419" + "reference": "959a74d044a6db21f4caa6d695648dcb5584cb49" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/error-handler/zipball/736e42db3fd586d91820355988698e434e1d8419", - "reference": "736e42db3fd586d91820355988698e434e1d8419", + "url": "https://api.github.com/repos/symfony/error-handler/zipball/959a74d044a6db21f4caa6d695648dcb5584cb49", + "reference": "959a74d044a6db21f4caa6d695648dcb5584cb49", "shasum": "" }, "require": { - "php": ">=8.1", + "php": ">=8.2", "psr/log": "^1|^2|^3", - "symfony/var-dumper": "^5.4|^6.0" + "symfony/var-dumper": "^6.4|^7.0" + }, + "conflict": { + "symfony/deprecation-contracts": "<2.5", + "symfony/http-kernel": "<6.4" }, "require-dev": { - "symfony/deprecation-contracts": "^2.1|^3", - "symfony/http-kernel": "^5.4|^6.0", - "symfony/serializer": "^5.4|^6.0" + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/serializer": "^6.4|^7.0" }, "bin": [ "Resources/bin/patch-type-declarations" @@ -5408,7 +5523,7 @@ "description": "Provides tools to manage errors and ease debugging PHP code", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/error-handler/tree/v6.1.3" + "source": "https://github.com/symfony/error-handler/tree/v7.2.3" }, "funding": [ { @@ -5424,28 +5539,29 @@ "type": "tidelift" } ], - "time": "2022-07-29T07:42:06+00:00" + "time": "2025-01-07T09:39:55+00:00" }, { "name": "symfony/event-dispatcher", - "version": "v6.1.0", + "version": "v7.2.0", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "a0449a7ad7daa0f7c0acd508259f80544ab5a347" + "reference": "910c5db85a5356d0fea57680defec4e99eb9c8c1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/a0449a7ad7daa0f7c0acd508259f80544ab5a347", - "reference": "a0449a7ad7daa0f7c0acd508259f80544ab5a347", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/910c5db85a5356d0fea57680defec4e99eb9c8c1", + "reference": "910c5db85a5356d0fea57680defec4e99eb9c8c1", "shasum": "" }, "require": { - "php": ">=8.1", - "symfony/event-dispatcher-contracts": "^2|^3" + "php": ">=8.2", + "symfony/event-dispatcher-contracts": "^2.5|^3" }, "conflict": { - "symfony/dependency-injection": "<5.4" + "symfony/dependency-injection": "<6.4", + "symfony/service-contracts": "<2.5" }, "provide": { "psr/event-dispatcher-implementation": "1.0", @@ -5453,17 +5569,13 @@ }, "require-dev": { "psr/log": "^1|^2|^3", - "symfony/config": "^5.4|^6.0", - "symfony/dependency-injection": "^5.4|^6.0", - "symfony/error-handler": "^5.4|^6.0", - "symfony/expression-language": "^5.4|^6.0", - "symfony/http-foundation": "^5.4|^6.0", - "symfony/service-contracts": "^1.1|^2|^3", - "symfony/stopwatch": "^5.4|^6.0" - }, - "suggest": { - "symfony/dependency-injection": "", - "symfony/http-kernel": "" + "symfony/config": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/error-handler": "^6.4|^7.0", + "symfony/expression-language": "^6.4|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/stopwatch": "^6.4|^7.0" }, "type": "library", "autoload": { @@ -5491,7 +5603,7 @@ "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/event-dispatcher/tree/v6.1.0" + "source": "https://github.com/symfony/event-dispatcher/tree/v7.2.0" }, "funding": [ { @@ -5507,37 +5619,34 @@ "type": "tidelift" } ], - "time": "2022-05-05T16:51:07+00:00" + "time": "2024-09-25T14:21:43+00:00" }, { "name": "symfony/event-dispatcher-contracts", - "version": "v3.1.1", + "version": "v3.5.1", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher-contracts.git", - "reference": "02ff5eea2f453731cfbc6bc215e456b781480448" + "reference": "7642f5e970b672283b7823222ae8ef8bbc160b9f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/02ff5eea2f453731cfbc6bc215e456b781480448", - "reference": "02ff5eea2f453731cfbc6bc215e456b781480448", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/7642f5e970b672283b7823222ae8ef8bbc160b9f", + "reference": "7642f5e970b672283b7823222ae8ef8bbc160b9f", "shasum": "" }, "require": { "php": ">=8.1", "psr/event-dispatcher": "^1" }, - "suggest": { - "symfony/event-dispatcher-implementation": "" - }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "3.1-dev" - }, "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.5-dev" } }, "autoload": { @@ -5570,7 +5679,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.1.1" + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.5.1" }, "funding": [ { @@ -5586,27 +5695,30 @@ "type": "tidelift" } ], - "time": "2022-02-25T11:15:52+00:00" + "time": "2024-09-25T14:20:29+00:00" }, { "name": "symfony/filesystem", - "version": "v6.1.4", + "version": "v7.2.0", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "3f39c04d2630c34019907b02f85672dac99f8659" + "reference": "b8dce482de9d7c9fe2891155035a7248ab5c7fdb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/3f39c04d2630c34019907b02f85672dac99f8659", - "reference": "3f39c04d2630c34019907b02f85672dac99f8659", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/b8dce482de9d7c9fe2891155035a7248ab5c7fdb", + "reference": "b8dce482de9d7c9fe2891155035a7248ab5c7fdb", "shasum": "" }, "require": { - "php": ">=8.1", + "php": ">=8.2", "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-mbstring": "~1.8" }, + "require-dev": { + "symfony/process": "^6.4|^7.0" + }, "type": "library", "autoload": { "psr-4": { @@ -5633,7 +5745,7 @@ "description": "Provides basic utilities for the filesystem", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/filesystem/tree/v6.1.4" + "source": "https://github.com/symfony/filesystem/tree/v7.2.0" }, "funding": [ { @@ -5649,27 +5761,27 @@ "type": "tidelift" } ], - "time": "2022-08-02T16:17:38+00:00" + "time": "2024-10-25T15:15:23+00:00" }, { "name": "symfony/finder", - "version": "v6.1.3", + "version": "v7.2.2", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "39696bff2c2970b3779a5cac7bf9f0b88fc2b709" + "reference": "87a71856f2f56e4100373e92529eed3171695cfb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/39696bff2c2970b3779a5cac7bf9f0b88fc2b709", - "reference": "39696bff2c2970b3779a5cac7bf9f0b88fc2b709", + "url": "https://api.github.com/repos/symfony/finder/zipball/87a71856f2f56e4100373e92529eed3171695cfb", + "reference": "87a71856f2f56e4100373e92529eed3171695cfb", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.2" }, "require-dev": { - "symfony/filesystem": "^6.0" + "symfony/filesystem": "^6.4|^7.0" }, "type": "library", "autoload": { @@ -5697,7 +5809,7 @@ "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/finder/tree/v6.1.3" + "source": "https://github.com/symfony/finder/tree/v7.2.2" }, "funding": [ { @@ -5713,26 +5825,29 @@ "type": "tidelift" } ], - "time": "2022-07-29T07:42:06+00:00" + "time": "2024-12-30T19:00:17+00:00" }, { "name": "symfony/flex", - "version": "v2.2.3", + "version": "v2.4.7", "source": { "type": "git", "url": "https://github.com/symfony/flex.git", - "reference": "0763da1bdcce1d48c06778d48249905c26d34a72" + "reference": "92f4fba342161ff36072bd3b8e0b3c6c23160402" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/flex/zipball/0763da1bdcce1d48c06778d48249905c26d34a72", - "reference": "0763da1bdcce1d48c06778d48249905c26d34a72", + "url": "https://api.github.com/repos/symfony/flex/zipball/92f4fba342161ff36072bd3b8e0b3c6c23160402", + "reference": "92f4fba342161ff36072bd3b8e0b3c6c23160402", "shasum": "" }, "require": { "composer-plugin-api": "^2.1", "php": ">=8.0" }, + "conflict": { + "composer/semver": "<1.7.2" + }, "require-dev": { "composer/composer": "^2.1", "symfony/dotenv": "^5.4|^6.0", @@ -5762,7 +5877,7 @@ "description": "Composer plugin for Symfony", "support": { "issues": "https://github.com/symfony/flex/issues", - "source": "https://github.com/symfony/flex/tree/v2.2.3" + "source": "https://github.com/symfony/flex/tree/v2.4.7" }, "funding": [ { @@ -5778,65 +5893,60 @@ "type": "tidelift" } ], - "time": "2022-08-07T09:39:47+00:00" + "time": "2024-10-07T08:51:54+00:00" }, { "name": "symfony/form", - "version": "v6.1.4", + "version": "v7.2.3", "source": { "type": "git", "url": "https://github.com/symfony/form.git", - "reference": "0a1a3ea071a216e2902cebe0b47750ca51f12f27" + "reference": "092a89345db25f8e4fc1804a4d3f184766e36e69" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/form/zipball/0a1a3ea071a216e2902cebe0b47750ca51f12f27", - "reference": "0a1a3ea071a216e2902cebe0b47750ca51f12f27", + "url": "https://api.github.com/repos/symfony/form/zipball/092a89345db25f8e4fc1804a4d3f184766e36e69", + "reference": "092a89345db25f8e4fc1804a4d3f184766e36e69", "shasum": "" }, "require": { - "php": ">=8.1", - "symfony/deprecation-contracts": "^2.1|^3", - "symfony/event-dispatcher": "^5.4|^6.0", - "symfony/options-resolver": "^5.4|^6.0", + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/event-dispatcher": "^6.4|^7.0", + "symfony/options-resolver": "^6.4|^7.0", "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-intl-icu": "^1.21", "symfony/polyfill-mbstring": "~1.0", - "symfony/property-access": "^5.4|^6.0", - "symfony/service-contracts": "^1.1|^2|^3" + "symfony/property-access": "^6.4|^7.0", + "symfony/service-contracts": "^2.5|^3" }, "conflict": { - "phpunit/phpunit": "<5.4.3", - "symfony/console": "<5.4", - "symfony/dependency-injection": "<5.4", - "symfony/doctrine-bridge": "<5.4", - "symfony/error-handler": "<5.4", - "symfony/framework-bundle": "<5.4", - "symfony/http-kernel": "<5.4", - "symfony/translation": "<5.4", - "symfony/translation-contracts": "<1.1.7", - "symfony/twig-bridge": "<5.4" - }, - "require-dev": { - "doctrine/collections": "~1.0", - "symfony/config": "^5.4|^6.0", - "symfony/console": "^5.4|^6.0", - "symfony/dependency-injection": "^5.4|^6.0", - "symfony/expression-language": "^5.4|^6.0", - "symfony/html-sanitizer": "^6.1", - "symfony/http-foundation": "^5.4|^6.0", - "symfony/http-kernel": "^5.4|^6.0", - "symfony/intl": "^5.4|^6.0", - "symfony/security-csrf": "^5.4|^6.0", - "symfony/translation": "^5.4|^6.0", - "symfony/uid": "^5.4|^6.0", - "symfony/validator": "^5.4|^6.0", - "symfony/var-dumper": "^5.4|^6.0" - }, - "suggest": { - "symfony/security-csrf": "For protecting forms against CSRF attacks.", - "symfony/twig-bridge": "For templating with Twig.", - "symfony/validator": "For form validation." + "symfony/console": "<6.4", + "symfony/dependency-injection": "<6.4", + "symfony/doctrine-bridge": "<6.4", + "symfony/error-handler": "<6.4", + "symfony/framework-bundle": "<6.4", + "symfony/http-kernel": "<6.4", + "symfony/translation": "<6.4.3|>=7.0,<7.0.3", + "symfony/translation-contracts": "<2.5", + "symfony/twig-bridge": "<6.4" + }, + "require-dev": { + "doctrine/collections": "^1.0|^2.0", + "symfony/config": "^6.4|^7.0", + "symfony/console": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/expression-language": "^6.4|^7.0", + "symfony/html-sanitizer": "^6.4|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/intl": "^6.4|^7.0", + "symfony/security-core": "^6.4|^7.0", + "symfony/security-csrf": "^6.4|^7.0", + "symfony/translation": "^6.4.3|^7.0.3", + "symfony/uid": "^6.4|^7.0", + "symfony/validator": "^6.4|^7.0", + "symfony/var-dumper": "^6.4|^7.0" }, "type": "library", "autoload": { @@ -5864,7 +5974,7 @@ "description": "Allows to easily create, process and reuse HTML forms", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/form/tree/v6.1.4" + "source": "https://github.com/symfony/form/tree/v7.2.3" }, "funding": [ { @@ -5880,114 +5990,113 @@ "type": "tidelift" } ], - "time": "2022-08-09T09:57:18+00:00" + "time": "2024-12-24T12:02:08+00:00" }, { "name": "symfony/framework-bundle", - "version": "v6.1.4", + "version": "v7.2.3", "source": { "type": "git", "url": "https://github.com/symfony/framework-bundle.git", - "reference": "4fabea93ce983b0d86512764ca852c683cc4730b" + "reference": "d37a43dd0b2079605fcab3056dac71934f06dc0f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/framework-bundle/zipball/4fabea93ce983b0d86512764ca852c683cc4730b", - "reference": "4fabea93ce983b0d86512764ca852c683cc4730b", + "url": "https://api.github.com/repos/symfony/framework-bundle/zipball/d37a43dd0b2079605fcab3056dac71934f06dc0f", + "reference": "d37a43dd0b2079605fcab3056dac71934f06dc0f", "shasum": "" }, "require": { "composer-runtime-api": ">=2.1", "ext-xml": "*", - "php": ">=8.1", - "symfony/cache": "^5.4|^6.0", - "symfony/config": "^6.1", - "symfony/dependency-injection": "^6.1", - "symfony/deprecation-contracts": "^2.1|^3", - "symfony/error-handler": "^6.1", - "symfony/event-dispatcher": "^5.4|^6.0", - "symfony/filesystem": "^5.4|^6.0", - "symfony/finder": "^5.4|^6.0", - "symfony/http-foundation": "^5.4|^6.0", - "symfony/http-kernel": "^6.1", + "php": ">=8.2", + "symfony/cache": "^6.4|^7.0", + "symfony/config": "^6.4|^7.0", + "symfony/dependency-injection": "^7.2", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/error-handler": "^6.4|^7.0", + "symfony/event-dispatcher": "^6.4|^7.0", + "symfony/filesystem": "^7.1", + "symfony/finder": "^6.4|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/http-kernel": "^7.2", "symfony/polyfill-mbstring": "~1.0", - "symfony/routing": "^5.4|^6.0" + "symfony/routing": "^6.4|^7.0" }, "conflict": { - "doctrine/annotations": "<1.13.1", "doctrine/persistence": "<1.3", "phpdocumentor/reflection-docblock": "<3.2.2", "phpdocumentor/type-resolver": "<1.4.0", - "phpunit/phpunit": "<5.4.3", - "symfony/asset": "<5.4", - "symfony/console": "<5.4", - "symfony/dom-crawler": "<5.4", - "symfony/dotenv": "<5.4", - "symfony/form": "<5.4", - "symfony/http-client": "<5.4", - "symfony/lock": "<5.4", - "symfony/mailer": "<5.4", - "symfony/messenger": "<5.4", - "symfony/mime": "<5.4", - "symfony/property-access": "<5.4", - "symfony/property-info": "<5.4", - "symfony/security-core": "<5.4", - "symfony/security-csrf": "<5.4", - "symfony/serializer": "<6.1", - "symfony/stopwatch": "<5.4", - "symfony/translation": "<5.4", - "symfony/twig-bridge": "<5.4", - "symfony/twig-bundle": "<5.4", - "symfony/validator": "<5.4", - "symfony/web-profiler-bundle": "<5.4", - "symfony/workflow": "<5.4" - }, - "require-dev": { - "doctrine/annotations": "^1.13.1", + "symfony/asset": "<6.4", + "symfony/asset-mapper": "<6.4", + "symfony/clock": "<6.4", + "symfony/console": "<6.4", + "symfony/dom-crawler": "<6.4", + "symfony/dotenv": "<6.4", + "symfony/form": "<6.4", + "symfony/http-client": "<6.4", + "symfony/lock": "<6.4", + "symfony/mailer": "<6.4", + "symfony/messenger": "<6.4", + "symfony/mime": "<6.4", + "symfony/property-access": "<6.4", + "symfony/property-info": "<6.4", + "symfony/runtime": "<6.4.13|>=7.0,<7.1.6", + "symfony/scheduler": "<6.4.4|>=7.0.0,<7.0.4", + "symfony/security-core": "<6.4", + "symfony/security-csrf": "<7.2", + "symfony/serializer": "<7.1", + "symfony/stopwatch": "<6.4", + "symfony/translation": "<6.4", + "symfony/twig-bridge": "<6.4", + "symfony/twig-bundle": "<6.4", + "symfony/validator": "<6.4", + "symfony/web-profiler-bundle": "<6.4", + "symfony/webhook": "<7.2", + "symfony/workflow": "<6.4" + }, + "require-dev": { "doctrine/persistence": "^1.3|^2|^3", + "dragonmantank/cron-expression": "^3.1", "phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0", - "symfony/asset": "^5.4|^6.0", - "symfony/browser-kit": "^5.4|^6.0", - "symfony/console": "^5.4.9|^6.0.9", - "symfony/css-selector": "^5.4|^6.0", - "symfony/dom-crawler": "^5.4|^6.0", - "symfony/dotenv": "^5.4|^6.0", - "symfony/expression-language": "^5.4|^6.0", - "symfony/form": "^5.4|^6.0", - "symfony/html-sanitizer": "^6.1", - "symfony/http-client": "^5.4|^6.0", - "symfony/lock": "^5.4|^6.0", - "symfony/mailer": "^5.4|^6.0", - "symfony/messenger": "^5.4|^6.0", - "symfony/mime": "^5.4|^6.0", - "symfony/notifier": "^5.4|^6.0", + "seld/jsonlint": "^1.10", + "symfony/asset": "^6.4|^7.0", + "symfony/asset-mapper": "^6.4|^7.0", + "symfony/browser-kit": "^6.4|^7.0", + "symfony/clock": "^6.4|^7.0", + "symfony/console": "^6.4|^7.0", + "symfony/css-selector": "^6.4|^7.0", + "symfony/dom-crawler": "^6.4|^7.0", + "symfony/dotenv": "^6.4|^7.0", + "symfony/expression-language": "^6.4|^7.0", + "symfony/form": "^6.4|^7.0", + "symfony/html-sanitizer": "^6.4|^7.0", + "symfony/http-client": "^6.4|^7.0", + "symfony/lock": "^6.4|^7.0", + "symfony/mailer": "^6.4|^7.0", + "symfony/messenger": "^6.4|^7.0", + "symfony/mime": "^6.4|^7.0", + "symfony/notifier": "^6.4|^7.0", "symfony/polyfill-intl-icu": "~1.0", - "symfony/process": "^5.4|^6.0", - "symfony/property-info": "^5.4|^6.0", - "symfony/rate-limiter": "^5.4|^6.0", - "symfony/security-bundle": "^5.4|^6.0", - "symfony/semaphore": "^5.4|^6.0", - "symfony/serializer": "^6.1", - "symfony/stopwatch": "^5.4|^6.0", - "symfony/string": "^5.4|^6.0", - "symfony/translation": "^5.4|^6.0", - "symfony/twig-bundle": "^5.4|^6.0", - "symfony/uid": "^5.4|^6.0", - "symfony/validator": "^5.4|^6.0", - "symfony/web-link": "^5.4|^6.0", - "symfony/workflow": "^5.4|^6.0", - "symfony/yaml": "^5.4|^6.0", - "twig/twig": "^2.10|^3.0" - }, - "suggest": { - "ext-apcu": "For best performance of the system caches", - "symfony/console": "For using the console commands", - "symfony/form": "For using forms", - "symfony/property-info": "For using the property_info service", - "symfony/serializer": "For using the serializer service", - "symfony/validator": "For using validation", - "symfony/web-link": "For using web links, features such as preloading, prefetching or prerendering", - "symfony/yaml": "For using the debug:config and lint:yaml commands" + "symfony/process": "^6.4|^7.0", + "symfony/property-info": "^6.4|^7.0", + "symfony/rate-limiter": "^6.4|^7.0", + "symfony/scheduler": "^6.4.4|^7.0.4", + "symfony/security-bundle": "^6.4|^7.0", + "symfony/semaphore": "^6.4|^7.0", + "symfony/serializer": "^7.1", + "symfony/stopwatch": "^6.4|^7.0", + "symfony/string": "^6.4|^7.0", + "symfony/translation": "^6.4|^7.0", + "symfony/twig-bundle": "^6.4|^7.0", + "symfony/type-info": "^7.1", + "symfony/uid": "^6.4|^7.0", + "symfony/validator": "^6.4|^7.0", + "symfony/web-link": "^6.4|^7.0", + "symfony/webhook": "^7.2", + "symfony/workflow": "^6.4|^7.0", + "symfony/yaml": "^6.4|^7.0", + "twig/twig": "^3.12" }, "type": "symfony-bundle", "autoload": { @@ -6015,7 +6124,7 @@ "description": "Provides a tight integration between Symfony components and the Symfony full-stack framework", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/framework-bundle/tree/v6.1.4" + "source": "https://github.com/symfony/framework-bundle/tree/v7.2.3" }, "funding": [ { @@ -6031,27 +6140,33 @@ "type": "tidelift" } ], - "time": "2022-08-26T10:32:31+00:00" + "time": "2025-01-29T07:13:55+00:00" }, { "name": "symfony/http-client", - "version": "v6.1.4", + "version": "v7.2.3", "source": { "type": "git", "url": "https://github.com/symfony/http-client.git", - "reference": "06dc27cbdcee26d6796c226db5266a0d58359739" + "reference": "7ce6078c79a4a7afff931c413d2959d3bffbfb8d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-client/zipball/06dc27cbdcee26d6796c226db5266a0d58359739", - "reference": "06dc27cbdcee26d6796c226db5266a0d58359739", + "url": "https://api.github.com/repos/symfony/http-client/zipball/7ce6078c79a4a7afff931c413d2959d3bffbfb8d", + "reference": "7ce6078c79a4a7afff931c413d2959d3bffbfb8d", "shasum": "" }, "require": { - "php": ">=8.1", + "php": ">=8.2", "psr/log": "^1|^2|^3", - "symfony/http-client-contracts": "^3", - "symfony/service-contracts": "^1.0|^2|^3" + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/http-client-contracts": "~3.4.4|^3.5.2", + "symfony/service-contracts": "^2.5|^3" + }, + "conflict": { + "amphp/amp": "<2.5", + "php-http/discovery": "<1.15", + "symfony/http-foundation": "<6.4" }, "provide": { "php-http/async-client-implementation": "*", @@ -6060,18 +6175,20 @@ "symfony/http-client-implementation": "3.0" }, "require-dev": { - "amphp/amp": "^2.5", - "amphp/http-client": "^4.2.1", - "amphp/http-tunnel": "^1.0", + "amphp/http-client": "^4.2.1|^5.0", + "amphp/http-tunnel": "^1.0|^2.0", "amphp/socket": "^1.1", - "guzzlehttp/promises": "^1.4", + "guzzlehttp/promises": "^1.4|^2.0", "nyholm/psr7": "^1.0", "php-http/httplug": "^1.0|^2.0", "psr/http-client": "^1.0", - "symfony/dependency-injection": "^5.4|^6.0", - "symfony/http-kernel": "^5.4|^6.0", - "symfony/process": "^5.4|^6.0", - "symfony/stopwatch": "^5.4|^6.0" + "symfony/amphp-http-client-meta": "^1.0|^2.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/messenger": "^6.4|^7.0", + "symfony/process": "^6.4|^7.0", + "symfony/rate-limiter": "^6.4|^7.0", + "symfony/stopwatch": "^6.4|^7.0" }, "type": "library", "autoload": { @@ -6098,8 +6215,11 @@ ], "description": "Provides powerful methods to fetch HTTP resources synchronously or asynchronously", "homepage": "https://symfony.com", + "keywords": [ + "http" + ], "support": { - "source": "https://github.com/symfony/http-client/tree/v6.1.4" + "source": "https://github.com/symfony/http-client/tree/v7.2.3" }, "funding": [ { @@ -6115,36 +6235,33 @@ "type": "tidelift" } ], - "time": "2022-08-02T16:17:38+00:00" + "time": "2025-01-28T15:51:35+00:00" }, { "name": "symfony/http-client-contracts", - "version": "v3.1.1", + "version": "v3.5.2", "source": { "type": "git", "url": "https://github.com/symfony/http-client-contracts.git", - "reference": "fd038f08c623ab5d22b26e9ba35afe8c79071800" + "reference": "ee8d807ab20fcb51267fdace50fbe3494c31e645" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/fd038f08c623ab5d22b26e9ba35afe8c79071800", - "reference": "fd038f08c623ab5d22b26e9ba35afe8c79071800", + "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/ee8d807ab20fcb51267fdace50fbe3494c31e645", + "reference": "ee8d807ab20fcb51267fdace50fbe3494c31e645", "shasum": "" }, "require": { "php": ">=8.1" }, - "suggest": { - "symfony/http-client-implementation": "" - }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "3.1-dev" - }, "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.5-dev" } }, "autoload": { @@ -6180,7 +6297,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/http-client-contracts/tree/v3.1.1" + "source": "https://github.com/symfony/http-client-contracts/tree/v3.5.2" }, "funding": [ { @@ -6196,38 +6313,41 @@ "type": "tidelift" } ], - "time": "2022-04-22T07:30:54+00:00" + "time": "2024-12-07T08:49:48+00:00" }, { "name": "symfony/http-foundation", - "version": "v6.1.4", + "version": "v7.2.3", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "18e0f106a32887bcebef757e5b39c88e39a08f20" + "reference": "ee1b504b8926198be89d05e5b6fc4c3810c090f0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/18e0f106a32887bcebef757e5b39c88e39a08f20", - "reference": "18e0f106a32887bcebef757e5b39c88e39a08f20", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/ee1b504b8926198be89d05e5b6fc4c3810c090f0", + "reference": "ee1b504b8926198be89d05e5b6fc4c3810c090f0", "shasum": "" }, "require": { - "php": ">=8.1", - "symfony/deprecation-contracts": "^2.1|^3", - "symfony/polyfill-mbstring": "~1.1" + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3.0", + "symfony/polyfill-mbstring": "~1.1", + "symfony/polyfill-php83": "^1.27" }, - "require-dev": { - "predis/predis": "~1.0", - "symfony/cache": "^5.4|^6.0", - "symfony/dependency-injection": "^5.4|^6.0", - "symfony/expression-language": "^5.4|^6.0", - "symfony/http-kernel": "^5.4.12|^6.0.12|^6.1.4", - "symfony/mime": "^5.4|^6.0", - "symfony/rate-limiter": "^5.2|^6.0" + "conflict": { + "doctrine/dbal": "<3.6", + "symfony/cache": "<6.4.12|>=7.0,<7.1.5" }, - "suggest": { - "symfony/mime": "To use the file extension guesser" + "require-dev": { + "doctrine/dbal": "^3.6|^4", + "predis/predis": "^1.1|^2.0", + "symfony/cache": "^6.4.12|^7.1.5", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/expression-language": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/mime": "^6.4|^7.0", + "symfony/rate-limiter": "^6.4|^7.0" }, "type": "library", "autoload": { @@ -6255,7 +6375,7 @@ "description": "Defines an object-oriented layer for the HTTP specification", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-foundation/tree/v6.1.4" + "source": "https://github.com/symfony/http-foundation/tree/v7.2.3" }, "funding": [ { @@ -6271,73 +6391,77 @@ "type": "tidelift" } ], - "time": "2022-08-19T14:27:04+00:00" + "time": "2025-01-17T10:56:55+00:00" }, { "name": "symfony/http-kernel", - "version": "v6.1.4", + "version": "v7.2.3", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "2144c53a278254af57fa1e6f71427be656fab6f4" + "reference": "caae9807f8e25a9b43ce8cc6fafab6cf91f0cc9b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/2144c53a278254af57fa1e6f71427be656fab6f4", - "reference": "2144c53a278254af57fa1e6f71427be656fab6f4", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/caae9807f8e25a9b43ce8cc6fafab6cf91f0cc9b", + "reference": "caae9807f8e25a9b43ce8cc6fafab6cf91f0cc9b", "shasum": "" }, "require": { - "php": ">=8.1", + "php": ">=8.2", "psr/log": "^1|^2|^3", - "symfony/error-handler": "^6.1", - "symfony/event-dispatcher": "^5.4|^6.0", - "symfony/http-foundation": "^5.4|^6.0", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/error-handler": "^6.4|^7.0", + "symfony/event-dispatcher": "^6.4|^7.0", + "symfony/http-foundation": "^6.4|^7.0", "symfony/polyfill-ctype": "^1.8" }, "conflict": { - "symfony/browser-kit": "<5.4", - "symfony/cache": "<5.4", - "symfony/config": "<6.1", - "symfony/console": "<5.4", - "symfony/dependency-injection": "<6.1", - "symfony/doctrine-bridge": "<5.4", - "symfony/form": "<5.4", - "symfony/http-client": "<5.4", - "symfony/mailer": "<5.4", - "symfony/messenger": "<5.4", - "symfony/translation": "<5.4", - "symfony/twig-bridge": "<5.4", - "symfony/validator": "<5.4", - "twig/twig": "<2.13" + "symfony/browser-kit": "<6.4", + "symfony/cache": "<6.4", + "symfony/config": "<6.4", + "symfony/console": "<6.4", + "symfony/dependency-injection": "<6.4", + "symfony/doctrine-bridge": "<6.4", + "symfony/form": "<6.4", + "symfony/http-client": "<6.4", + "symfony/http-client-contracts": "<2.5", + "symfony/mailer": "<6.4", + "symfony/messenger": "<6.4", + "symfony/translation": "<6.4", + "symfony/translation-contracts": "<2.5", + "symfony/twig-bridge": "<6.4", + "symfony/validator": "<6.4", + "symfony/var-dumper": "<6.4", + "twig/twig": "<3.12" }, "provide": { "psr/log-implementation": "1.0|2.0|3.0" }, "require-dev": { "psr/cache": "^1.0|^2.0|^3.0", - "symfony/browser-kit": "^5.4|^6.0", - "symfony/config": "^6.1", - "symfony/console": "^5.4|^6.0", - "symfony/css-selector": "^5.4|^6.0", - "symfony/dependency-injection": "^6.1", - "symfony/dom-crawler": "^5.4|^6.0", - "symfony/expression-language": "^5.4|^6.0", - "symfony/finder": "^5.4|^6.0", - "symfony/http-client-contracts": "^1.1|^2|^3", - "symfony/process": "^5.4|^6.0", - "symfony/routing": "^5.4|^6.0", - "symfony/stopwatch": "^5.4|^6.0", - "symfony/translation": "^5.4|^6.0", - "symfony/translation-contracts": "^1.1|^2|^3", - "symfony/uid": "^5.4|^6.0", - "twig/twig": "^2.13|^3.0.4" - }, - "suggest": { - "symfony/browser-kit": "", - "symfony/config": "", - "symfony/console": "", - "symfony/dependency-injection": "" + "symfony/browser-kit": "^6.4|^7.0", + "symfony/clock": "^6.4|^7.0", + "symfony/config": "^6.4|^7.0", + "symfony/console": "^6.4|^7.0", + "symfony/css-selector": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/dom-crawler": "^6.4|^7.0", + "symfony/expression-language": "^6.4|^7.0", + "symfony/finder": "^6.4|^7.0", + "symfony/http-client-contracts": "^2.5|^3", + "symfony/process": "^6.4|^7.0", + "symfony/property-access": "^7.1", + "symfony/routing": "^6.4|^7.0", + "symfony/serializer": "^7.1", + "symfony/stopwatch": "^6.4|^7.0", + "symfony/translation": "^6.4|^7.0", + "symfony/translation-contracts": "^2.5|^3", + "symfony/uid": "^6.4|^7.0", + "symfony/validator": "^6.4|^7.0", + "symfony/var-dumper": "^6.4|^7.0", + "symfony/var-exporter": "^6.4|^7.0", + "twig/twig": "^3.12" }, "type": "library", "autoload": { @@ -6365,7 +6489,7 @@ "description": "Provides a structured process for converting a Request into a Response", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-kernel/tree/v6.1.4" + "source": "https://github.com/symfony/http-kernel/tree/v7.2.3" }, "funding": [ { @@ -6381,27 +6505,32 @@ "type": "tidelift" } ], - "time": "2022-08-26T14:50:30+00:00" + "time": "2025-01-29T07:40:13+00:00" }, { "name": "symfony/intl", - "version": "v6.1.0", + "version": "v7.2.0", "source": { "type": "git", "url": "https://github.com/symfony/intl.git", - "reference": "9fc07ba57eb33d44c6b3b86b4e1ef927620d1a39" + "reference": "76bb3462c6c308f8bd97d3c178c2626ae44d4dea" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/intl/zipball/9fc07ba57eb33d44c6b3b86b4e1ef927620d1a39", - "reference": "9fc07ba57eb33d44c6b3b86b4e1ef927620d1a39", + "url": "https://api.github.com/repos/symfony/intl/zipball/76bb3462c6c308f8bd97d3c178c2626ae44d4dea", + "reference": "76bb3462c6c308f8bd97d3c178c2626ae44d4dea", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3" + }, + "conflict": { + "symfony/string": "<7.1" }, "require-dev": { - "symfony/filesystem": "^5.4|^6.0" + "symfony/filesystem": "^6.4|^7.0", + "symfony/var-exporter": "^6.4|^7.0" }, "type": "library", "autoload": { @@ -6409,7 +6538,8 @@ "Symfony\\Component\\Intl\\": "" }, "exclude-from-classmap": [ - "/Tests/" + "/Tests/", + "/Resources/data/" ] }, "notification-url": "https://packagist.org/downloads/", @@ -6434,7 +6564,7 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Provides a PHP replacement layer for the C intl extension that includes additional data from the ICU library", + "description": "Provides access to the localization data of the ICU library", "homepage": "https://symfony.com", "keywords": [ "i18n", @@ -6445,7 +6575,7 @@ "localization" ], "support": { - "source": "https://github.com/symfony/intl/tree/v6.1.0" + "source": "https://github.com/symfony/intl/tree/v7.2.0" }, "funding": [ { @@ -6461,32 +6591,33 @@ "type": "tidelift" } ], - "time": "2022-04-12T16:22:53+00:00" + "time": "2024-11-25T14:26:33+00:00" }, { "name": "symfony/lock", - "version": "v6.1.3", + "version": "v7.2.3", "source": { "type": "git", "url": "https://github.com/symfony/lock.git", - "reference": "6e8c324132f8ebb47a1a8506031a55f0020783fc" + "reference": "4f6e8b0e03e4a76095f7d058d72e72d30d5f59e5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/lock/zipball/6e8c324132f8ebb47a1a8506031a55f0020783fc", - "reference": "6e8c324132f8ebb47a1a8506031a55f0020783fc", + "url": "https://api.github.com/repos/symfony/lock/zipball/4f6e8b0e03e4a76095f7d058d72e72d30d5f59e5", + "reference": "4f6e8b0e03e4a76095f7d058d72e72d30d5f59e5", "shasum": "" }, "require": { - "php": ">=8.1", + "php": ">=8.2", "psr/log": "^1|^2|^3" }, "conflict": { - "doctrine/dbal": "<2.13" + "doctrine/dbal": "<3.6", + "symfony/cache": "<6.4" }, "require-dev": { - "doctrine/dbal": "^2.13|^3.0", - "predis/predis": "~1.0" + "doctrine/dbal": "^3.6|^4", + "predis/predis": "^1.1|^2.0" }, "type": "library", "autoload": { @@ -6522,7 +6653,7 @@ "semaphore" ], "support": { - "source": "https://github.com/symfony/lock/tree/v6.1.3" + "source": "https://github.com/symfony/lock/tree/v7.2.3" }, "funding": [ { @@ -6538,49 +6669,50 @@ "type": "tidelift" } ], - "time": "2022-06-27T17:24:16+00:00" + "time": "2025-01-17T06:59:03+00:00" }, { "name": "symfony/messenger", - "version": "v6.1.3", + "version": "v7.2.3", "source": { "type": "git", "url": "https://github.com/symfony/messenger.git", - "reference": "8d36b2447ed50a92a21f031bc6d3a3fefbe73bf3" + "reference": "8e5b72deb81e57c8868eb9fe7b1dcb4af694ef10" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/messenger/zipball/8d36b2447ed50a92a21f031bc6d3a3fefbe73bf3", - "reference": "8d36b2447ed50a92a21f031bc6d3a3fefbe73bf3", + "url": "https://api.github.com/repos/symfony/messenger/zipball/8e5b72deb81e57c8868eb9fe7b1dcb4af694ef10", + "reference": "8e5b72deb81e57c8868eb9fe7b1dcb4af694ef10", "shasum": "" }, "require": { - "php": ">=8.1", - "psr/log": "^1|^2|^3" + "php": ">=8.2", + "psr/log": "^1|^2|^3", + "symfony/clock": "^6.4|^7.0", + "symfony/deprecation-contracts": "^2.5|^3" }, "conflict": { - "symfony/event-dispatcher": "<5.4", - "symfony/event-dispatcher-contracts": "<2", - "symfony/framework-bundle": "<5.4", - "symfony/http-kernel": "<5.4", - "symfony/serializer": "<5.4" + "symfony/console": "<7.2", + "symfony/event-dispatcher": "<6.4", + "symfony/event-dispatcher-contracts": "<2.5", + "symfony/framework-bundle": "<6.4", + "symfony/http-kernel": "<6.4", + "symfony/serializer": "<6.4" }, "require-dev": { "psr/cache": "^1.0|^2.0|^3.0", - "symfony/console": "^5.4|^6.0", - "symfony/dependency-injection": "^5.4|^6.0", - "symfony/event-dispatcher": "^5.4|^6.0", - "symfony/http-kernel": "^5.4|^6.0", - "symfony/process": "^5.4|^6.0", - "symfony/property-access": "^5.4|^6.0", - "symfony/routing": "^5.4|^6.0", - "symfony/serializer": "^5.4|^6.0", - "symfony/service-contracts": "^1.1|^2|^3", - "symfony/stopwatch": "^5.4|^6.0", - "symfony/validator": "^5.4|^6.0" - }, - "suggest": { - "enqueue/messenger-adapter": "For using the php-enqueue library as a transport." + "symfony/console": "^7.2", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/event-dispatcher": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/process": "^6.4|^7.0", + "symfony/property-access": "^6.4|^7.0", + "symfony/rate-limiter": "^6.4|^7.0", + "symfony/routing": "^6.4|^7.0", + "symfony/serializer": "^6.4|^7.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/stopwatch": "^6.4|^7.0", + "symfony/validator": "^6.4|^7.0" }, "type": "library", "autoload": { @@ -6608,7 +6740,7 @@ "description": "Helps applications send and receive messages to/from other applications or via message queues", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/messenger/tree/v6.1.3" + "source": "https://github.com/symfony/messenger/tree/v7.2.3" }, "funding": [ { @@ -6624,24 +6756,24 @@ "type": "tidelift" } ], - "time": "2022-07-20T13:46:29+00:00" + "time": "2025-01-17T10:17:27+00:00" }, { "name": "symfony/mime", - "version": "v6.1.4", + "version": "v7.2.3", "source": { "type": "git", "url": "https://github.com/symfony/mime.git", - "reference": "5d1de2d3c52f8ca469c488f4b9e007e9e9cee0b3" + "reference": "2fc3b4bd67e4747e45195bc4c98bea4628476204" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mime/zipball/5d1de2d3c52f8ca469c488f4b9e007e9e9cee0b3", - "reference": "5d1de2d3c52f8ca469c488f4b9e007e9e9cee0b3", + "url": "https://api.github.com/repos/symfony/mime/zipball/2fc3b4bd67e4747e45195bc4c98bea4628476204", + "reference": "2fc3b4bd67e4747e45195bc4c98bea4628476204", "shasum": "" }, "require": { - "php": ">=8.1", + "php": ">=8.2", "symfony/polyfill-intl-idn": "^1.10", "symfony/polyfill-mbstring": "^1.0" }, @@ -6649,15 +6781,18 @@ "egulias/email-validator": "~3.0.0", "phpdocumentor/reflection-docblock": "<3.2.2", "phpdocumentor/type-resolver": "<1.4.0", - "symfony/mailer": "<5.4" + "symfony/mailer": "<6.4", + "symfony/serializer": "<6.4.3|>7.0,<7.0.3" }, "require-dev": { - "egulias/email-validator": "^2.1.10|^3.1", + "egulias/email-validator": "^2.1.10|^3.1|^4", + "league/html-to-markdown": "^5.0", "phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0", - "symfony/dependency-injection": "^5.4|^6.0", - "symfony/property-access": "^5.4|^6.0", - "symfony/property-info": "^5.4|^6.0", - "symfony/serializer": "^5.4|^6.0" + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/process": "^6.4|^7.0", + "symfony/property-access": "^6.4|^7.0", + "symfony/property-info": "^6.4|^7.0", + "symfony/serializer": "^6.4.3|^7.0.3" }, "type": "library", "autoload": { @@ -6689,7 +6824,7 @@ "mime-type" ], "support": { - "source": "https://github.com/symfony/mime/tree/v6.1.4" + "source": "https://github.com/symfony/mime/tree/v7.2.3" }, "funding": [ { @@ -6705,46 +6840,41 @@ "type": "tidelift" } ], - "time": "2022-08-19T14:27:04+00:00" + "time": "2025-01-27T11:08:17+00:00" }, { "name": "symfony/monolog-bridge", - "version": "v6.1.2", + "version": "v7.2.0", "source": { "type": "git", "url": "https://github.com/symfony/monolog-bridge.git", - "reference": "1efd6a42b1dc80e03bd74d4a2fdc85e728dc2627" + "reference": "bbae784f0456c5a87c89d7c1a3fcc9cbee976c1d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/monolog-bridge/zipball/1efd6a42b1dc80e03bd74d4a2fdc85e728dc2627", - "reference": "1efd6a42b1dc80e03bd74d4a2fdc85e728dc2627", + "url": "https://api.github.com/repos/symfony/monolog-bridge/zipball/bbae784f0456c5a87c89d7c1a3fcc9cbee976c1d", + "reference": "bbae784f0456c5a87c89d7c1a3fcc9cbee976c1d", "shasum": "" }, "require": { - "monolog/monolog": "^1.25.1|^2|^3", - "php": ">=8.1", - "symfony/http-kernel": "^5.4|^6.0", - "symfony/service-contracts": "^1.1|^2|^3" + "monolog/monolog": "^3", + "php": ">=8.2", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/service-contracts": "^2.5|^3" }, "conflict": { - "symfony/console": "<5.4", - "symfony/http-foundation": "<5.4", - "symfony/security-core": "<6.0" + "symfony/console": "<6.4", + "symfony/http-foundation": "<6.4", + "symfony/security-core": "<6.4" }, "require-dev": { - "symfony/console": "^5.4|^6.0", - "symfony/http-client": "^5.4|^6.0", - "symfony/mailer": "^5.4|^6.0", - "symfony/messenger": "^5.4|^6.0", - "symfony/mime": "^5.4|^6.0", - "symfony/security-core": "^6.0", - "symfony/var-dumper": "^5.4|^6.0" - }, - "suggest": { - "symfony/console": "For the possibility to show log messages in console commands depending on verbosity settings.", - "symfony/http-kernel": "For using the debugging handlers together with the response life cycle of the HTTP kernel.", - "symfony/var-dumper": "For using the debugging handlers like the console handler or the log server handler." + "symfony/console": "^6.4|^7.0", + "symfony/http-client": "^6.4|^7.0", + "symfony/mailer": "^6.4|^7.0", + "symfony/messenger": "^6.4|^7.0", + "symfony/mime": "^6.4|^7.0", + "symfony/security-core": "^6.4|^7.0", + "symfony/var-dumper": "^6.4|^7.0" }, "type": "symfony-bridge", "autoload": { @@ -6772,7 +6902,7 @@ "description": "Provides integration for Monolog with various Symfony components", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/monolog-bridge/tree/v6.1.2" + "source": "https://github.com/symfony/monolog-bridge/tree/v7.2.0" }, "funding": [ { @@ -6788,34 +6918,34 @@ "type": "tidelift" } ], - "time": "2022-06-21T08:28:57+00:00" + "time": "2024-10-14T18:16:08+00:00" }, { "name": "symfony/monolog-bundle", - "version": "v3.8.0", + "version": "v3.10.0", "source": { "type": "git", "url": "https://github.com/symfony/monolog-bundle.git", - "reference": "a41bbcdc1105603b6d73a7d9a43a3788f8e0fb7d" + "reference": "414f951743f4aa1fd0f5bf6a0e9c16af3fe7f181" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/monolog-bundle/zipball/a41bbcdc1105603b6d73a7d9a43a3788f8e0fb7d", - "reference": "a41bbcdc1105603b6d73a7d9a43a3788f8e0fb7d", + "url": "https://api.github.com/repos/symfony/monolog-bundle/zipball/414f951743f4aa1fd0f5bf6a0e9c16af3fe7f181", + "reference": "414f951743f4aa1fd0f5bf6a0e9c16af3fe7f181", "shasum": "" }, "require": { - "monolog/monolog": "^1.22 || ^2.0 || ^3.0", - "php": ">=7.1.3", - "symfony/config": "~4.4 || ^5.0 || ^6.0", - "symfony/dependency-injection": "^4.4 || ^5.0 || ^6.0", - "symfony/http-kernel": "~4.4 || ^5.0 || ^6.0", - "symfony/monolog-bridge": "~4.4 || ^5.0 || ^6.0" + "monolog/monolog": "^1.25.1 || ^2.0 || ^3.0", + "php": ">=7.2.5", + "symfony/config": "^5.4 || ^6.0 || ^7.0", + "symfony/dependency-injection": "^5.4 || ^6.0 || ^7.0", + "symfony/http-kernel": "^5.4 || ^6.0 || ^7.0", + "symfony/monolog-bridge": "^5.4 || ^6.0 || ^7.0" }, "require-dev": { - "symfony/console": "~4.4 || ^5.0 || ^6.0", - "symfony/phpunit-bridge": "^5.2 || ^6.0", - "symfony/yaml": "~4.4 || ^5.0 || ^6.0" + "symfony/console": "^5.4 || ^6.0 || ^7.0", + "symfony/phpunit-bridge": "^6.3 || ^7.0", + "symfony/yaml": "^5.4 || ^6.0 || ^7.0" }, "type": "symfony-bundle", "extra": { @@ -6853,7 +6983,7 @@ ], "support": { "issues": "https://github.com/symfony/monolog-bundle/issues", - "source": "https://github.com/symfony/monolog-bundle/tree/v3.8.0" + "source": "https://github.com/symfony/monolog-bundle/tree/v3.10.0" }, "funding": [ { @@ -6869,25 +6999,25 @@ "type": "tidelift" } ], - "time": "2022-05-10T14:24:36+00:00" + "time": "2023-11-06T17:08:13+00:00" }, { "name": "symfony/options-resolver", - "version": "v6.1.0", + "version": "v7.2.0", "source": { "type": "git", "url": "https://github.com/symfony/options-resolver.git", - "reference": "a3016f5442e28386ded73c43a32a5b68586dd1c4" + "reference": "7da8fbac9dcfef75ffc212235d76b2754ce0cf50" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/options-resolver/zipball/a3016f5442e28386ded73c43a32a5b68586dd1c4", - "reference": "a3016f5442e28386ded73c43a32a5b68586dd1c4", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/7da8fbac9dcfef75ffc212235d76b2754ce0cf50", + "reference": "7da8fbac9dcfef75ffc212235d76b2754ce0cf50", "shasum": "" }, "require": { - "php": ">=8.1", - "symfony/deprecation-contracts": "^2.1|^3" + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3" }, "type": "library", "autoload": { @@ -6920,7 +7050,7 @@ "options" ], "support": { - "source": "https://github.com/symfony/options-resolver/tree/v6.1.0" + "source": "https://github.com/symfony/options-resolver/tree/v7.2.0" }, "funding": [ { @@ -6936,31 +7066,31 @@ "type": "tidelift" } ], - "time": "2022-02-25T11:15:52+00:00" + "time": "2024-11-20T11:17:29+00:00" }, { "name": "symfony/password-hasher", - "version": "v6.1.3", + "version": "v7.2.0", "source": { "type": "git", "url": "https://github.com/symfony/password-hasher.git", - "reference": "264894821636b77bb8282db6ec33b8b07b7a0678" + "reference": "d8bd3d66d074c0acba1214a0d42f5941a8e1e94d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/password-hasher/zipball/264894821636b77bb8282db6ec33b8b07b7a0678", - "reference": "264894821636b77bb8282db6ec33b8b07b7a0678", + "url": "https://api.github.com/repos/symfony/password-hasher/zipball/d8bd3d66d074c0acba1214a0d42f5941a8e1e94d", + "reference": "d8bd3d66d074c0acba1214a0d42f5941a8e1e94d", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.2" }, "conflict": { - "symfony/security-core": "<5.4" + "symfony/security-core": "<6.4" }, "require-dev": { - "symfony/console": "^5.4|^6.0", - "symfony/security-core": "^5.4|^6.0" + "symfony/console": "^6.4|^7.0", + "symfony/security-core": "^6.4|^7.0" }, "type": "library", "autoload": { @@ -6992,7 +7122,7 @@ "password" ], "support": { - "source": "https://github.com/symfony/password-hasher/tree/v6.1.3" + "source": "https://github.com/symfony/password-hasher/tree/v7.2.0" }, "funding": [ { @@ -7008,36 +7138,33 @@ "type": "tidelift" } ], - "time": "2022-07-20T14:45:06+00:00" + "time": "2024-09-25T14:21:43+00:00" }, { "name": "symfony/polyfill-intl-grapheme", - "version": "v1.26.0", + "version": "v1.31.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-grapheme.git", - "reference": "433d05519ce6990bf3530fba6957499d327395c2" + "reference": "b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/433d05519ce6990bf3530fba6957499d327395c2", - "reference": "433d05519ce6990bf3530fba6957499d327395c2", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe", + "reference": "b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "suggest": { "ext-intl": "For best performance" }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.26-dev" - }, "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -7073,7 +7200,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.26.0" + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.31.0" }, "funding": [ { @@ -7089,36 +7216,33 @@ "type": "tidelift" } ], - "time": "2022-05-24T11:49:31+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { "name": "symfony/polyfill-intl-icu", - "version": "v1.26.0", + "version": "v1.31.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-icu.git", - "reference": "e407643d610e5f2c8a4b14189150f68934bf5e48" + "reference": "d80a05e9904d2c2b9b95929f3e4b5d3a8f418d78" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-icu/zipball/e407643d610e5f2c8a4b14189150f68934bf5e48", - "reference": "e407643d610e5f2c8a4b14189150f68934bf5e48", + "url": "https://api.github.com/repos/symfony/polyfill-intl-icu/zipball/d80a05e9904d2c2b9b95929f3e4b5d3a8f418d78", + "reference": "d80a05e9904d2c2b9b95929f3e4b5d3a8f418d78", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "suggest": { "ext-intl": "For best performance and support of other locales than \"en\"" }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.26-dev" - }, "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -7160,7 +7284,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-icu/tree/v1.26.0" + "source": "https://github.com/symfony/polyfill-intl-icu/tree/v1.31.0" }, "funding": [ { @@ -7176,38 +7300,34 @@ "type": "tidelift" } ], - "time": "2022-05-24T11:49:31+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { "name": "symfony/polyfill-intl-idn", - "version": "v1.26.0", + "version": "v1.31.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-idn.git", - "reference": "59a8d271f00dd0e4c2e518104cc7963f655a1aa8" + "reference": "c36586dcf89a12315939e00ec9b4474adcb1d773" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/59a8d271f00dd0e4c2e518104cc7963f655a1aa8", - "reference": "59a8d271f00dd0e4c2e518104cc7963f655a1aa8", + "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/c36586dcf89a12315939e00ec9b4474adcb1d773", + "reference": "c36586dcf89a12315939e00ec9b4474adcb1d773", "shasum": "" }, "require": { - "php": ">=7.1", - "symfony/polyfill-intl-normalizer": "^1.10", - "symfony/polyfill-php72": "^1.10" + "php": ">=7.2", + "symfony/polyfill-intl-normalizer": "^1.10" }, "suggest": { "ext-intl": "For best performance" }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.26-dev" - }, "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -7247,7 +7367,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.26.0" + "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.31.0" }, "funding": [ { @@ -7263,36 +7383,33 @@ "type": "tidelift" } ], - "time": "2022-05-24T11:49:31+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { "name": "symfony/polyfill-intl-normalizer", - "version": "v1.26.0", + "version": "v1.31.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "219aa369ceff116e673852dce47c3a41794c14bd" + "reference": "3833d7255cc303546435cb650316bff708a1c75c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/219aa369ceff116e673852dce47c3a41794c14bd", - "reference": "219aa369ceff116e673852dce47c3a41794c14bd", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/3833d7255cc303546435cb650316bff708a1c75c", + "reference": "3833d7255cc303546435cb650316bff708a1c75c", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "suggest": { "ext-intl": "For best performance" }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.26-dev" - }, "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -7331,7 +7448,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.26.0" + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.31.0" }, "funding": [ { @@ -7347,24 +7464,24 @@ "type": "tidelift" } ], - "time": "2022-05-24T11:49:31+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.26.0", + "version": "v1.31.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e" + "reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e", - "reference": "9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/85181ba99b2345b0ef10ce42ecac37612d9fd341", + "reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "provide": { "ext-mbstring": "*" @@ -7374,12 +7491,9 @@ }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.26-dev" - }, "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -7414,7 +7528,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.26.0" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.31.0" }, "funding": [ { @@ -7430,33 +7544,30 @@ "type": "tidelift" } ], - "time": "2022-05-24T11:49:31+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { "name": "symfony/polyfill-php73", - "version": "v1.26.0", + "version": "v1.31.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php73.git", - "reference": "e440d35fa0286f77fb45b79a03fedbeda9307e85" + "reference": "0f68c03565dcaaf25a890667542e8bd75fe7e5bb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/e440d35fa0286f77fb45b79a03fedbeda9307e85", - "reference": "e440d35fa0286f77fb45b79a03fedbeda9307e85", + "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/0f68c03565dcaaf25a890667542e8bd75fe7e5bb", + "reference": "0f68c03565dcaaf25a890667542e8bd75fe7e5bb", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.26-dev" - }, "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -7493,7 +7604,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php73/tree/v1.26.0" + "source": "https://github.com/symfony/polyfill-php73/tree/v1.31.0" }, "funding": [ { @@ -7509,33 +7620,30 @@ "type": "tidelift" } ], - "time": "2022-05-24T11:49:31+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { "name": "symfony/polyfill-php80", - "version": "v1.26.0", + "version": "v1.31.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "cfa0ae98841b9e461207c13ab093d76b0fa7bace" + "reference": "60328e362d4c2c802a54fcbf04f9d3fb892b4cf8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/cfa0ae98841b9e461207c13ab093d76b0fa7bace", - "reference": "cfa0ae98841b9e461207c13ab093d76b0fa7bace", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/60328e362d4c2c802a54fcbf04f9d3fb892b4cf8", + "reference": "60328e362d4c2c802a54fcbf04f9d3fb892b4cf8", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.26-dev" - }, "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -7576,7 +7684,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.26.0" + "source": "https://github.com/symfony/polyfill-php80/tree/v1.31.0" }, "funding": [ { @@ -7592,33 +7700,30 @@ "type": "tidelift" } ], - "time": "2022-05-10T07:21:04+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { "name": "symfony/polyfill-php81", - "version": "v1.26.0", + "version": "v1.31.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php81.git", - "reference": "13f6d1271c663dc5ae9fb843a8f16521db7687a1" + "reference": "4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/13f6d1271c663dc5ae9fb843a8f16521db7687a1", - "reference": "13f6d1271c663dc5ae9fb843a8f16521db7687a1", + "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c", + "reference": "4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.26-dev" - }, "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -7655,7 +7760,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php81/tree/v1.26.0" + "source": "https://github.com/symfony/polyfill-php81/tree/v1.31.0" }, "funding": [ { @@ -7671,32 +7776,108 @@ "type": "tidelift" } ], - "time": "2022-05-24T11:49:31+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { - "name": "symfony/process", - "version": "v6.1.3", + "name": "symfony/polyfill-php83", + "version": "v1.31.0", "source": { "type": "git", - "url": "https://github.com/symfony/process.git", - "reference": "a6506e99cfad7059b1ab5cab395854a0a0c21292" + "url": "https://github.com/symfony/polyfill-php83.git", + "reference": "2fb86d65e2d424369ad2905e83b236a8805ba491" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/a6506e99cfad7059b1ab5cab395854a0a0c21292", - "reference": "a6506e99cfad7059b1ab5cab395854a0a0c21292", + "url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/2fb86d65e2d424369ad2905e83b236a8805ba491", + "reference": "2fb86d65e2d424369ad2905e83b236a8805ba491", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=7.2" }, "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, "autoload": { + "files": [ + "bootstrap.php" + ], "psr-4": { - "Symfony\\Component\\Process\\": "" + "Symfony\\Polyfill\\Php83\\": "" }, - "exclude-from-classmap": [ - "/Tests/" + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.3+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php83/tree/v1.31.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-09T11:45:10+00:00" + }, + { + "name": "symfony/process", + "version": "v7.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/process.git", + "reference": "d34b22ba9390ec19d2dd966c40aa9e8462f27a7e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/process/zipball/d34b22ba9390ec19d2dd966c40aa9e8462f27a7e", + "reference": "d34b22ba9390ec19d2dd966c40aa9e8462f27a7e", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Process\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" ] }, "notification-url": "https://packagist.org/downloads/", @@ -7716,7 +7897,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v6.1.3" + "source": "https://github.com/symfony/process/tree/v7.2.0" }, "funding": [ { @@ -7732,31 +7913,28 @@ "type": "tidelift" } ], - "time": "2022-06-27T17:24:16+00:00" + "time": "2024-11-06T14:24:19+00:00" }, { "name": "symfony/property-access", - "version": "v6.1.3", + "version": "v7.2.3", "source": { "type": "git", "url": "https://github.com/symfony/property-access.git", - "reference": "25108ee9b62d6ef0815007d9c7cf6a7ba40bb7c5" + "reference": "b28732e315d81fbec787f838034de7d6c9b2b902" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/property-access/zipball/25108ee9b62d6ef0815007d9c7cf6a7ba40bb7c5", - "reference": "25108ee9b62d6ef0815007d9c7cf6a7ba40bb7c5", + "url": "https://api.github.com/repos/symfony/property-access/zipball/b28732e315d81fbec787f838034de7d6c9b2b902", + "reference": "b28732e315d81fbec787f838034de7d6c9b2b902", "shasum": "" }, "require": { - "php": ">=8.1", - "symfony/property-info": "^5.4|^6.0" + "php": ">=8.2", + "symfony/property-info": "^6.4|^7.0" }, "require-dev": { - "symfony/cache": "^5.4|^6.0" - }, - "suggest": { - "psr/cache-implementation": "To cache access methods." + "symfony/cache": "^6.4|^7.0" }, "type": "library", "autoload": { @@ -7791,11 +7969,11 @@ "injection", "object", "property", - "property path", + "property-path", "reflection" ], "support": { - "source": "https://github.com/symfony/property-access/tree/v6.1.3" + "source": "https://github.com/symfony/property-access/tree/v7.2.3" }, "funding": [ { @@ -7811,44 +7989,40 @@ "type": "tidelift" } ], - "time": "2022-06-27T17:24:16+00:00" + "time": "2025-01-17T10:56:55+00:00" }, { "name": "symfony/property-info", - "version": "v6.1.3", + "version": "v7.2.3", "source": { "type": "git", "url": "https://github.com/symfony/property-info.git", - "reference": "2fc363ed2f2b5d3b231ed0824e066d140d3fd1d8" + "reference": "dedb118fd588a92f226b390250b384d25f4192fe" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/property-info/zipball/2fc363ed2f2b5d3b231ed0824e066d140d3fd1d8", - "reference": "2fc363ed2f2b5d3b231ed0824e066d140d3fd1d8", + "url": "https://api.github.com/repos/symfony/property-info/zipball/dedb118fd588a92f226b390250b384d25f4192fe", + "reference": "dedb118fd588a92f226b390250b384d25f4192fe", "shasum": "" }, "require": { - "php": ">=8.1", - "symfony/string": "^5.4|^6.0" + "php": ">=8.2", + "symfony/string": "^6.4|^7.0", + "symfony/type-info": "~7.1.9|^7.2.2" }, "conflict": { "phpdocumentor/reflection-docblock": "<5.2", "phpdocumentor/type-resolver": "<1.5.1", - "symfony/dependency-injection": "<5.4" + "symfony/cache": "<6.4", + "symfony/dependency-injection": "<6.4", + "symfony/serializer": "<6.4" }, "require-dev": { - "doctrine/annotations": "^1.10.4", "phpdocumentor/reflection-docblock": "^5.2", - "phpstan/phpdoc-parser": "^1.0", - "symfony/cache": "^5.4|^6.0", - "symfony/dependency-injection": "^5.4|^6.0", - "symfony/serializer": "^5.4|^6.0" - }, - "suggest": { - "phpdocumentor/reflection-docblock": "To use the PHPDoc", - "psr/cache-implementation": "To cache results", - "symfony/doctrine-bridge": "To use Doctrine metadata", - "symfony/serializer": "To use Serializer metadata" + "phpstan/phpdoc-parser": "^1.0|^2.0", + "symfony/cache": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/serializer": "^6.4|^7.0" }, "type": "library", "autoload": { @@ -7884,7 +8058,7 @@ "validator" ], "support": { - "source": "https://github.com/symfony/property-info/tree/v6.1.3" + "source": "https://github.com/symfony/property-info/tree/v7.2.3" }, "funding": [ { @@ -7900,29 +8074,29 @@ "type": "tidelift" } ], - "time": "2022-07-19T08:34:05+00:00" + "time": "2025-01-27T11:08:17+00:00" }, { "name": "symfony/rate-limiter", - "version": "v6.1.3", + "version": "v7.2.0", "source": { "type": "git", "url": "https://github.com/symfony/rate-limiter.git", - "reference": "9e75706446f7c3686773c408f422ffb5ec4ba32b" + "reference": "bb6b14ee6c1c4d2722a30d46fb92714943526804" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/rate-limiter/zipball/9e75706446f7c3686773c408f422ffb5ec4ba32b", - "reference": "9e75706446f7c3686773c408f422ffb5ec4ba32b", + "url": "https://api.github.com/repos/symfony/rate-limiter/zipball/bb6b14ee6c1c4d2722a30d46fb92714943526804", + "reference": "bb6b14ee6c1c4d2722a30d46fb92714943526804", "shasum": "" }, "require": { - "php": ">=8.1", - "symfony/lock": "^5.4|^6.0", - "symfony/options-resolver": "^5.4|^6.0" + "php": ">=8.2", + "symfony/options-resolver": "^6.4|^7.0" }, "require-dev": { - "psr/cache": "^1.0|^2.0|^3.0" + "psr/cache": "^1.0|^2.0|^3.0", + "symfony/lock": "^6.4|^7.0" }, "type": "library", "autoload": { @@ -7954,7 +8128,7 @@ "rate-limiter" ], "support": { - "source": "https://github.com/symfony/rate-limiter/tree/v6.1.3" + "source": "https://github.com/symfony/rate-limiter/tree/v7.2.0" }, "funding": [ { @@ -7970,45 +8144,38 @@ "type": "tidelift" } ], - "time": "2022-07-20T13:46:29+00:00" + "time": "2024-11-09T09:29:03+00:00" }, { "name": "symfony/routing", - "version": "v6.1.3", + "version": "v7.2.3", "source": { "type": "git", "url": "https://github.com/symfony/routing.git", - "reference": "ef9108b3a88045b7546e808fb404ddb073dd35ea" + "reference": "ee9a67edc6baa33e5fae662f94f91fd262930996" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/routing/zipball/ef9108b3a88045b7546e808fb404ddb073dd35ea", - "reference": "ef9108b3a88045b7546e808fb404ddb073dd35ea", + "url": "https://api.github.com/repos/symfony/routing/zipball/ee9a67edc6baa33e5fae662f94f91fd262930996", + "reference": "ee9a67edc6baa33e5fae662f94f91fd262930996", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3" }, "conflict": { - "doctrine/annotations": "<1.12", - "symfony/config": "<5.4", - "symfony/dependency-injection": "<5.4", - "symfony/yaml": "<5.4" + "symfony/config": "<6.4", + "symfony/dependency-injection": "<6.4", + "symfony/yaml": "<6.4" }, "require-dev": { - "doctrine/annotations": "^1.12", "psr/log": "^1|^2|^3", - "symfony/config": "^5.4|^6.0", - "symfony/dependency-injection": "^5.4|^6.0", - "symfony/expression-language": "^5.4|^6.0", - "symfony/http-foundation": "^5.4|^6.0", - "symfony/yaml": "^5.4|^6.0" - }, - "suggest": { - "symfony/config": "For using the all-in-one router or any loader", - "symfony/expression-language": "For using expression matching", - "symfony/http-foundation": "For using a Symfony Request object", - "symfony/yaml": "For using the YAML loader" + "symfony/config": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/expression-language": "^6.4|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/yaml": "^6.4|^7.0" }, "type": "library", "autoload": { @@ -8042,7 +8209,7 @@ "url" ], "support": { - "source": "https://github.com/symfony/routing/tree/v6.1.3" + "source": "https://github.com/symfony/routing/tree/v7.2.3" }, "funding": [ { @@ -8058,35 +8225,35 @@ "type": "tidelift" } ], - "time": "2022-07-20T15:00:40+00:00" + "time": "2025-01-17T10:56:55+00:00" }, { "name": "symfony/runtime", - "version": "v6.1.3", + "version": "v7.2.3", "source": { "type": "git", "url": "https://github.com/symfony/runtime.git", - "reference": "e5d4d848656cbb1812d5f911b1bdec205c6e2fac" + "reference": "8e8d09bd69b7f6c0260dd3d58f37bd4fbdeab5ad" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/runtime/zipball/e5d4d848656cbb1812d5f911b1bdec205c6e2fac", - "reference": "e5d4d848656cbb1812d5f911b1bdec205c6e2fac", + "url": "https://api.github.com/repos/symfony/runtime/zipball/8e8d09bd69b7f6c0260dd3d58f37bd4fbdeab5ad", + "reference": "8e8d09bd69b7f6c0260dd3d58f37bd4fbdeab5ad", "shasum": "" }, "require": { "composer-plugin-api": "^1.0|^2.0", - "php": ">=8.1" + "php": ">=8.2" }, "conflict": { - "symfony/dotenv": "<5.4" + "symfony/dotenv": "<6.4" }, "require-dev": { - "composer/composer": "^1.0.2|^2.0", - "symfony/console": "^5.4|^6.0", - "symfony/dotenv": "^5.4|^6.0", - "symfony/http-foundation": "^5.4|^6.0", - "symfony/http-kernel": "^5.4|^6.0" + "composer/composer": "^2.6", + "symfony/console": "^6.4|^7.0", + "symfony/dotenv": "^6.4|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0" }, "type": "composer-plugin", "extra": { @@ -8117,8 +8284,11 @@ ], "description": "Enables decoupling PHP applications from global state", "homepage": "https://symfony.com", + "keywords": [ + "runtime" + ], "support": { - "source": "https://github.com/symfony/runtime/tree/v6.1.3" + "source": "https://github.com/symfony/runtime/tree/v7.2.3" }, "funding": [ { @@ -8134,63 +8304,69 @@ "type": "tidelift" } ], - "time": "2022-06-27T17:24:16+00:00" + "time": "2024-12-29T21:39:47+00:00" }, { "name": "symfony/security-bundle", - "version": "v6.1.3", + "version": "v7.2.3", "source": { "type": "git", "url": "https://github.com/symfony/security-bundle.git", - "reference": "1410129e36e5d0cf4bde73f4ed5d9e18acff06b3" + "reference": "721de227035c6e4c322fb7dd4839586d58bc0cf5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/security-bundle/zipball/1410129e36e5d0cf4bde73f4ed5d9e18acff06b3", - "reference": "1410129e36e5d0cf4bde73f4ed5d9e18acff06b3", + "url": "https://api.github.com/repos/symfony/security-bundle/zipball/721de227035c6e4c322fb7dd4839586d58bc0cf5", + "reference": "721de227035c6e4c322fb7dd4839586d58bc0cf5", "shasum": "" }, "require": { "composer-runtime-api": ">=2.1", "ext-xml": "*", - "php": ">=8.1", - "symfony/config": "^5.4|^6.0", - "symfony/dependency-injection": "^5.4|^6.0", - "symfony/event-dispatcher": "^5.4|^6.0", - "symfony/http-foundation": "^5.4|^6.0", - "symfony/http-kernel": "^5.4|^6.0", - "symfony/password-hasher": "^5.4|^6.0", - "symfony/security-core": "^5.4|^6.0", - "symfony/security-csrf": "^5.4|^6.0", - "symfony/security-http": "^5.4|^6.0" + "php": ">=8.2", + "symfony/clock": "^6.4|^7.0", + "symfony/config": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4.11|^7.1.4", + "symfony/event-dispatcher": "^6.4|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/password-hasher": "^6.4|^7.0", + "symfony/security-core": "^7.2", + "symfony/security-csrf": "^6.4|^7.0", + "symfony/security-http": "^7.2", + "symfony/service-contracts": "^2.5|^3" }, "conflict": { - "symfony/browser-kit": "<5.4", - "symfony/console": "<5.4", - "symfony/framework-bundle": "<5.4", - "symfony/ldap": "<5.4", - "symfony/twig-bundle": "<5.4" - }, - "require-dev": { - "doctrine/annotations": "^1.10.4", - "symfony/asset": "^5.4|^6.0", - "symfony/browser-kit": "^5.4|^6.0", - "symfony/console": "^5.4|^6.0", - "symfony/css-selector": "^5.4|^6.0", - "symfony/dom-crawler": "^5.4|^6.0", - "symfony/expression-language": "^5.4|^6.0", - "symfony/form": "^5.4|^6.0", - "symfony/framework-bundle": "^5.4|^6.0", - "symfony/ldap": "^5.4|^6.0", - "symfony/process": "^5.4|^6.0", - "symfony/rate-limiter": "^5.4|^6.0", - "symfony/serializer": "^5.4|^6.0", - "symfony/translation": "^5.4|^6.0", - "symfony/twig-bridge": "^5.4|^6.0", - "symfony/twig-bundle": "^5.4|^6.0", - "symfony/validator": "^5.4|^6.0", - "symfony/yaml": "^5.4|^6.0", - "twig/twig": "^2.13|^3.0.4" + "symfony/browser-kit": "<6.4", + "symfony/console": "<6.4", + "symfony/framework-bundle": "<6.4", + "symfony/http-client": "<6.4", + "symfony/ldap": "<6.4", + "symfony/serializer": "<6.4", + "symfony/twig-bundle": "<6.4", + "symfony/validator": "<6.4" + }, + "require-dev": { + "symfony/asset": "^6.4|^7.0", + "symfony/browser-kit": "^6.4|^7.0", + "symfony/console": "^6.4|^7.0", + "symfony/css-selector": "^6.4|^7.0", + "symfony/dom-crawler": "^6.4|^7.0", + "symfony/expression-language": "^6.4|^7.0", + "symfony/form": "^6.4|^7.0", + "symfony/framework-bundle": "^6.4|^7.0", + "symfony/http-client": "^6.4|^7.0", + "symfony/ldap": "^6.4|^7.0", + "symfony/process": "^6.4|^7.0", + "symfony/rate-limiter": "^6.4|^7.0", + "symfony/serializer": "^6.4|^7.0", + "symfony/translation": "^6.4|^7.0", + "symfony/twig-bridge": "^6.4|^7.0", + "symfony/twig-bundle": "^6.4|^7.0", + "symfony/validator": "^6.4|^7.0", + "symfony/yaml": "^6.4|^7.0", + "twig/twig": "^3.12", + "web-token/jwt-library": "^3.3.2|^4.0" }, "type": "symfony-bundle", "autoload": { @@ -8218,7 +8394,7 @@ "description": "Provides a tight integration of the Security component into the Symfony full-stack framework", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/security-bundle/tree/v6.1.3" + "source": "https://github.com/symfony/security-bundle/tree/v7.2.3" }, "funding": [ { @@ -8234,54 +8410,50 @@ "type": "tidelift" } ], - "time": "2022-07-20T13:46:29+00:00" + "time": "2025-01-07T09:39:55+00:00" }, { "name": "symfony/security-core", - "version": "v6.1.4", + "version": "v7.2.3", "source": { "type": "git", "url": "https://github.com/symfony/security-core.git", - "reference": "a3e6ee1e0bafb22418fb602445631c9d5849055c" + "reference": "466784ffcd0b5a16e05394335897f790b17d07e4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/security-core/zipball/a3e6ee1e0bafb22418fb602445631c9d5849055c", - "reference": "a3e6ee1e0bafb22418fb602445631c9d5849055c", + "url": "https://api.github.com/repos/symfony/security-core/zipball/466784ffcd0b5a16e05394335897f790b17d07e4", + "reference": "466784ffcd0b5a16e05394335897f790b17d07e4", "shasum": "" }, "require": { - "php": ">=8.1", - "symfony/event-dispatcher-contracts": "^1.1|^2|^3", - "symfony/password-hasher": "^5.4|^6.0", - "symfony/service-contracts": "^1.1.6|^2|^3" + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/event-dispatcher-contracts": "^2.5|^3", + "symfony/password-hasher": "^6.4|^7.0", + "symfony/service-contracts": "^2.5|^3" }, "conflict": { - "symfony/event-dispatcher": "<5.4", - "symfony/http-foundation": "<5.4", - "symfony/ldap": "<5.4", - "symfony/security-guard": "<5.4", - "symfony/validator": "<5.4" + "symfony/dependency-injection": "<6.4", + "symfony/event-dispatcher": "<6.4", + "symfony/http-foundation": "<6.4", + "symfony/ldap": "<6.4", + "symfony/translation": "<6.4.3|>=7.0,<7.0.3", + "symfony/validator": "<6.4" }, "require-dev": { "psr/cache": "^1.0|^2.0|^3.0", "psr/container": "^1.1|^2.0", "psr/log": "^1|^2|^3", - "symfony/cache": "^5.4|^6.0", - "symfony/event-dispatcher": "^5.4|^6.0", - "symfony/expression-language": "^5.4|^6.0", - "symfony/http-foundation": "^5.4|^6.0", - "symfony/ldap": "^5.4|^6.0", - "symfony/translation": "^5.4|^6.0", - "symfony/validator": "^5.4|^6.0" - }, - "suggest": { - "psr/container-implementation": "To instantiate the Security class", - "symfony/event-dispatcher": "", - "symfony/expression-language": "For using the expression voter", - "symfony/http-foundation": "", - "symfony/ldap": "For using LDAP integration", - "symfony/validator": "For using the user password constraint" + "symfony/cache": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/event-dispatcher": "^6.4|^7.0", + "symfony/expression-language": "^6.4|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/ldap": "^6.4|^7.0", + "symfony/string": "^6.4|^7.0", + "symfony/translation": "^6.4.3|^7.0.3", + "symfony/validator": "^6.4|^7.0" }, "type": "library", "autoload": { @@ -8309,7 +8481,7 @@ "description": "Symfony Security Component - Core Library", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/security-core/tree/v6.1.4" + "source": "https://github.com/symfony/security-core/tree/v7.2.3" }, "funding": [ { @@ -8325,34 +8497,33 @@ "type": "tidelift" } ], - "time": "2022-08-19T14:27:04+00:00" + "time": "2025-01-27T11:08:17+00:00" }, { "name": "symfony/security-csrf", - "version": "v6.1.0", + "version": "v7.2.3", "source": { "type": "git", "url": "https://github.com/symfony/security-csrf.git", - "reference": "b44d74295a5651298de8c2760ba50bef3b97f34b" + "reference": "2b4b0c46c901729e4e90719eacd980381f53e0a3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/security-csrf/zipball/b44d74295a5651298de8c2760ba50bef3b97f34b", - "reference": "b44d74295a5651298de8c2760ba50bef3b97f34b", + "url": "https://api.github.com/repos/symfony/security-csrf/zipball/2b4b0c46c901729e4e90719eacd980381f53e0a3", + "reference": "2b4b0c46c901729e4e90719eacd980381f53e0a3", "shasum": "" }, "require": { - "php": ">=8.1", - "symfony/security-core": "^5.4|^6.0" + "php": ">=8.2", + "symfony/security-core": "^6.4|^7.0" }, "conflict": { - "symfony/http-foundation": "<5.4" + "symfony/http-foundation": "<6.4" }, "require-dev": { - "symfony/http-foundation": "^5.4|^6.0" - }, - "suggest": { - "symfony/http-foundation": "For using the class SessionTokenStorage." + "psr/log": "^1|^2|^3", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0" }, "type": "library", "autoload": { @@ -8380,7 +8551,7 @@ "description": "Symfony Security Component - CSRF Library", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/security-csrf/tree/v6.1.0" + "source": "https://github.com/symfony/security-csrf/tree/v7.2.3" }, "funding": [ { @@ -8396,46 +8567,51 @@ "type": "tidelift" } ], - "time": "2022-05-14T12:53:54+00:00" + "time": "2025-01-02T18:42:10+00:00" }, { "name": "symfony/security-http", - "version": "v6.1.4", + "version": "v7.2.3", "source": { "type": "git", "url": "https://github.com/symfony/security-http.git", - "reference": "a106f0f55e9942da5aa9181fbf2175512f583449" + "reference": "d185c4126ef2ca8b89b6e81d67bf14a52532657f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/security-http/zipball/a106f0f55e9942da5aa9181fbf2175512f583449", - "reference": "a106f0f55e9942da5aa9181fbf2175512f583449", + "url": "https://api.github.com/repos/symfony/security-http/zipball/d185c4126ef2ca8b89b6e81d67bf14a52532657f", + "reference": "d185c4126ef2ca8b89b6e81d67bf14a52532657f", "shasum": "" }, "require": { - "php": ">=8.1", - "symfony/http-foundation": "^5.4|^6.0", - "symfony/http-kernel": "^6.1", + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", "symfony/polyfill-mbstring": "~1.0", - "symfony/property-access": "^5.4|^6.0", - "symfony/security-core": "^5.4.7|^6.0" + "symfony/property-access": "^6.4|^7.0", + "symfony/security-core": "^7.2", + "symfony/service-contracts": "^2.5|^3" }, "conflict": { - "symfony/event-dispatcher": "<5.4.9|>=6,<6.0.9", - "symfony/security-bundle": "<5.4", - "symfony/security-csrf": "<5.4" + "symfony/clock": "<6.4", + "symfony/event-dispatcher": "<6.4", + "symfony/http-client-contracts": "<3.0", + "symfony/security-bundle": "<6.4", + "symfony/security-csrf": "<6.4" }, "require-dev": { "psr/log": "^1|^2|^3", - "symfony/cache": "^5.4|^6.0", - "symfony/rate-limiter": "^5.4|^6.0", - "symfony/routing": "^5.4|^6.0", - "symfony/security-csrf": "^5.4|^6.0", - "symfony/translation": "^5.4|^6.0" - }, - "suggest": { - "symfony/routing": "For using the HttpUtils class to create sub-requests, redirect the user, and match URLs", - "symfony/security-csrf": "For using tokens to protect authentication/logout attempts" + "symfony/cache": "^6.4|^7.0", + "symfony/clock": "^6.4|^7.0", + "symfony/expression-language": "^6.4|^7.0", + "symfony/http-client": "^6.4|^7.0", + "symfony/http-client-contracts": "^3.0", + "symfony/rate-limiter": "^6.4|^7.0", + "symfony/routing": "^6.4|^7.0", + "symfony/security-csrf": "^6.4|^7.0", + "symfony/translation": "^6.4|^7.0", + "web-token/jwt-library": "^3.3.2|^4.0" }, "type": "library", "autoload": { @@ -8463,7 +8639,7 @@ "description": "Symfony Security Component - HTTP Integration", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/security-http/tree/v6.1.4" + "source": "https://github.com/symfony/security-http/tree/v7.2.3" }, "funding": [ { @@ -8479,64 +8655,61 @@ "type": "tidelift" } ], - "time": "2022-08-26T10:32:31+00:00" + "time": "2025-01-28T15:51:35+00:00" }, { "name": "symfony/serializer", - "version": "v6.1.4", + "version": "v7.2.3", "source": { "type": "git", "url": "https://github.com/symfony/serializer.git", - "reference": "03e5987dd9bb98038c60c7af3e58500c81c4aec1" + "reference": "320f30beb419ce4f96363ada5e225c41f1ef08ab" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/serializer/zipball/03e5987dd9bb98038c60c7af3e58500c81c4aec1", - "reference": "03e5987dd9bb98038c60c7af3e58500c81c4aec1", + "url": "https://api.github.com/repos/symfony/serializer/zipball/320f30beb419ce4f96363ada5e225c41f1ef08ab", + "reference": "320f30beb419ce4f96363ada5e225c41f1ef08ab", "shasum": "" }, "require": { - "php": ">=8.1", + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3", "symfony/polyfill-ctype": "~1.8" }, "conflict": { - "doctrine/annotations": "<1.12", "phpdocumentor/reflection-docblock": "<3.2.2", "phpdocumentor/type-resolver": "<1.4.0", - "symfony/dependency-injection": "<5.4", - "symfony/property-access": "<5.4", - "symfony/property-info": "<5.4", - "symfony/uid": "<5.4", - "symfony/yaml": "<5.4" + "symfony/dependency-injection": "<6.4", + "symfony/property-access": "<6.4", + "symfony/property-info": "<6.4", + "symfony/uid": "<6.4", + "symfony/validator": "<6.4", + "symfony/yaml": "<6.4" }, "require-dev": { - "doctrine/annotations": "^1.12", "phpdocumentor/reflection-docblock": "^3.2|^4.0|^5.0", - "symfony/cache": "^5.4|^6.0", - "symfony/config": "^5.4|^6.0", - "symfony/dependency-injection": "^5.4|^6.0", - "symfony/error-handler": "^5.4|^6.0", - "symfony/filesystem": "^5.4|^6.0", - "symfony/form": "^5.4|^6.0", - "symfony/http-foundation": "^5.4|^6.0", - "symfony/http-kernel": "^5.4|^6.0", - "symfony/mime": "^5.4|^6.0", - "symfony/property-access": "^5.4|^6.0", - "symfony/property-info": "^5.4|^6.0", - "symfony/uid": "^5.4|^6.0", - "symfony/validator": "^5.4|^6.0", - "symfony/var-dumper": "^5.4|^6.0", - "symfony/var-exporter": "^5.4|^6.0", - "symfony/yaml": "^5.4|^6.0" - }, - "suggest": { - "psr/cache-implementation": "For using the metadata cache.", - "symfony/config": "For using the XML mapping loader.", - "symfony/mime": "For using a MIME type guesser within the DataUriNormalizer.", - "symfony/property-access": "For using the ObjectNormalizer.", - "symfony/property-info": "To deserialize relations.", - "symfony/var-exporter": "For using the metadata compiler.", - "symfony/yaml": "For using the default YAML mapping loader." + "phpstan/phpdoc-parser": "^1.0|^2.0", + "seld/jsonlint": "^1.10", + "symfony/cache": "^6.4|^7.0", + "symfony/config": "^6.4|^7.0", + "symfony/console": "^6.4|^7.0", + "symfony/dependency-injection": "^7.2", + "symfony/error-handler": "^6.4|^7.0", + "symfony/filesystem": "^6.4|^7.0", + "symfony/form": "^6.4|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/messenger": "^6.4|^7.0", + "symfony/mime": "^6.4|^7.0", + "symfony/property-access": "^6.4|^7.0", + "symfony/property-info": "^6.4|^7.0", + "symfony/translation-contracts": "^2.5|^3", + "symfony/type-info": "^7.1", + "symfony/uid": "^6.4|^7.0", + "symfony/validator": "^6.4|^7.0", + "symfony/var-dumper": "^6.4|^7.0", + "symfony/var-exporter": "^6.4|^7.0", + "symfony/yaml": "^6.4|^7.0" }, "type": "library", "autoload": { @@ -8564,7 +8737,7 @@ "description": "Handles serializing and deserializing data structures, including object graphs, into array structures or other formats like XML and JSON.", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/serializer/tree/v6.1.4" + "source": "https://github.com/symfony/serializer/tree/v7.2.3" }, "funding": [ { @@ -8580,40 +8753,38 @@ "type": "tidelift" } ], - "time": "2022-08-26T10:32:31+00:00" + "time": "2025-01-29T07:13:55+00:00" }, { "name": "symfony/service-contracts", - "version": "v3.1.1", + "version": "v3.5.1", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "925e713fe8fcacf6bc05e936edd8dd5441a21239" + "reference": "e53260aabf78fb3d63f8d79d69ece59f80d5eda0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/925e713fe8fcacf6bc05e936edd8dd5441a21239", - "reference": "925e713fe8fcacf6bc05e936edd8dd5441a21239", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/e53260aabf78fb3d63f8d79d69ece59f80d5eda0", + "reference": "e53260aabf78fb3d63f8d79d69ece59f80d5eda0", "shasum": "" }, "require": { "php": ">=8.1", - "psr/container": "^2.0" + "psr/container": "^1.1|^2.0", + "symfony/deprecation-contracts": "^2.5|^3" }, "conflict": { "ext-psr": "<1.1|>=2" }, - "suggest": { - "symfony/service-implementation": "" - }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "3.1-dev" - }, "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.5-dev" } }, "autoload": { @@ -8649,7 +8820,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/service-contracts/tree/v3.1.1" + "source": "https://github.com/symfony/service-contracts/tree/v3.5.1" }, "funding": [ { @@ -8665,37 +8836,39 @@ "type": "tidelift" } ], - "time": "2022-05-30T19:18:58+00:00" + "time": "2024-09-25T14:20:29+00:00" }, { "name": "symfony/string", - "version": "v6.1.4", + "version": "v7.2.0", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "290972cad7b364e3befaa74ba0ec729800fb161c" + "reference": "446e0d146f991dde3e73f45f2c97a9faad773c82" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/290972cad7b364e3befaa74ba0ec729800fb161c", - "reference": "290972cad7b364e3befaa74ba0ec729800fb161c", + "url": "https://api.github.com/repos/symfony/string/zipball/446e0d146f991dde3e73f45f2c97a9faad773c82", + "reference": "446e0d146f991dde3e73f45f2c97a9faad773c82", "shasum": "" }, "require": { - "php": ">=8.1", + "php": ">=8.2", "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-intl-grapheme": "~1.0", "symfony/polyfill-intl-normalizer": "~1.0", "symfony/polyfill-mbstring": "~1.0" }, "conflict": { - "symfony/translation-contracts": "<2.0" + "symfony/translation-contracts": "<2.5" }, "require-dev": { - "symfony/error-handler": "^5.4|^6.0", - "symfony/http-client": "^5.4|^6.0", - "symfony/translation-contracts": "^2.0|^3.0", - "symfony/var-exporter": "^5.4|^6.0" + "symfony/emoji": "^7.1", + "symfony/error-handler": "^6.4|^7.0", + "symfony/http-client": "^6.4|^7.0", + "symfony/intl": "^6.4|^7.0", + "symfony/translation-contracts": "^2.5|^3.0", + "symfony/var-exporter": "^6.4|^7.0" }, "type": "library", "autoload": { @@ -8734,7 +8907,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v6.1.4" + "source": "https://github.com/symfony/string/tree/v7.2.0" }, "funding": [ { @@ -8750,56 +8923,55 @@ "type": "tidelift" } ], - "time": "2022-08-12T18:05:43+00:00" + "time": "2024-11-13T13:31:26+00:00" }, { "name": "symfony/translation", - "version": "v6.1.4", + "version": "v7.2.2", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", - "reference": "45d0f5bb8df7255651ca91c122fab604e776af03" + "reference": "e2674a30132b7cc4d74540d6c2573aa363f05923" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/45d0f5bb8df7255651ca91c122fab604e776af03", - "reference": "45d0f5bb8df7255651ca91c122fab604e776af03", + "url": "https://api.github.com/repos/symfony/translation/zipball/e2674a30132b7cc4d74540d6c2573aa363f05923", + "reference": "e2674a30132b7cc4d74540d6c2573aa363f05923", "shasum": "" }, "require": { - "php": ">=8.1", + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3", "symfony/polyfill-mbstring": "~1.0", - "symfony/translation-contracts": "^2.3|^3.0" + "symfony/translation-contracts": "^2.5|^3.0" }, "conflict": { - "symfony/config": "<5.4", - "symfony/console": "<5.4", - "symfony/dependency-injection": "<5.4", - "symfony/http-kernel": "<5.4", - "symfony/twig-bundle": "<5.4", - "symfony/yaml": "<5.4" + "symfony/config": "<6.4", + "symfony/console": "<6.4", + "symfony/dependency-injection": "<6.4", + "symfony/http-client-contracts": "<2.5", + "symfony/http-kernel": "<6.4", + "symfony/service-contracts": "<2.5", + "symfony/twig-bundle": "<6.4", + "symfony/yaml": "<6.4" }, "provide": { "symfony/translation-implementation": "2.3|3.0" }, "require-dev": { + "nikic/php-parser": "^4.18|^5.0", "psr/log": "^1|^2|^3", - "symfony/config": "^5.4|^6.0", - "symfony/console": "^5.4|^6.0", - "symfony/dependency-injection": "^5.4|^6.0", - "symfony/finder": "^5.4|^6.0", - "symfony/http-client-contracts": "^1.1|^2.0|^3.0", - "symfony/http-kernel": "^5.4|^6.0", - "symfony/intl": "^5.4|^6.0", + "symfony/config": "^6.4|^7.0", + "symfony/console": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/finder": "^6.4|^7.0", + "symfony/http-client-contracts": "^2.5|^3.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/intl": "^6.4|^7.0", "symfony/polyfill-intl-icu": "^1.21", - "symfony/routing": "^5.4|^6.0", - "symfony/service-contracts": "^1.1.2|^2|^3", - "symfony/yaml": "^5.4|^6.0" - }, - "suggest": { - "psr/log-implementation": "To use logging capability in translator", - "symfony/config": "", - "symfony/yaml": "" + "symfony/routing": "^6.4|^7.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/yaml": "^6.4|^7.0" }, "type": "library", "autoload": { @@ -8830,7 +9002,7 @@ "description": "Provides tools to internationalize your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/translation/tree/v6.1.4" + "source": "https://github.com/symfony/translation/tree/v7.2.2" }, "funding": [ { @@ -8846,36 +9018,33 @@ "type": "tidelift" } ], - "time": "2022-08-02T16:17:38+00:00" + "time": "2024-12-07T08:18:10+00:00" }, { "name": "symfony/translation-contracts", - "version": "v3.1.1", + "version": "v3.5.1", "source": { "type": "git", "url": "https://github.com/symfony/translation-contracts.git", - "reference": "606be0f48e05116baef052f7f3abdb345c8e02cc" + "reference": "4667ff3bd513750603a09c8dedbea942487fb07c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/606be0f48e05116baef052f7f3abdb345c8e02cc", - "reference": "606be0f48e05116baef052f7f3abdb345c8e02cc", + "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/4667ff3bd513750603a09c8dedbea942487fb07c", + "reference": "4667ff3bd513750603a09c8dedbea942487fb07c", "shasum": "" }, "require": { "php": ">=8.1" }, - "suggest": { - "symfony/translation-implementation": "" - }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "3.1-dev" - }, "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.5-dev" } }, "autoload": { @@ -8911,7 +9080,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/translation-contracts/tree/v3.1.1" + "source": "https://github.com/symfony/translation-contracts/tree/v3.5.1" }, "funding": [ { @@ -8927,86 +9096,74 @@ "type": "tidelift" } ], - "time": "2022-06-27T17:24:16+00:00" + "time": "2024-09-25T14:20:29+00:00" }, { "name": "symfony/twig-bridge", - "version": "v6.1.4", + "version": "v7.2.2", "source": { "type": "git", "url": "https://github.com/symfony/twig-bridge.git", - "reference": "ec8da630a439a233817412fca93d14aa1813cc5d" + "reference": "29e4c66de9618e67dc1f5f13bc667aca2a228f1e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/twig-bridge/zipball/ec8da630a439a233817412fca93d14aa1813cc5d", - "reference": "ec8da630a439a233817412fca93d14aa1813cc5d", + "url": "https://api.github.com/repos/symfony/twig-bridge/zipball/29e4c66de9618e67dc1f5f13bc667aca2a228f1e", + "reference": "29e4c66de9618e67dc1f5f13bc667aca2a228f1e", "shasum": "" }, "require": { - "php": ">=8.1", - "symfony/translation-contracts": "^1.1|^2|^3", - "twig/twig": "^2.13|^3.0.4" + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/translation-contracts": "^2.5|^3", + "twig/twig": "^3.12" }, "conflict": { "phpdocumentor/reflection-docblock": "<3.2.2", "phpdocumentor/type-resolver": "<1.4.0", - "symfony/console": "<5.4", - "symfony/form": "<6.1", - "symfony/http-foundation": "<5.4", - "symfony/http-kernel": "<5.4", - "symfony/translation": "<5.4", - "symfony/workflow": "<5.4" - }, - "require-dev": { - "doctrine/annotations": "^1.12", - "egulias/email-validator": "^2.1.10|^3", + "symfony/console": "<6.4", + "symfony/form": "<6.4", + "symfony/http-foundation": "<6.4", + "symfony/http-kernel": "<6.4", + "symfony/mime": "<6.4", + "symfony/serializer": "<6.4", + "symfony/translation": "<6.4", + "symfony/workflow": "<6.4" + }, + "require-dev": { + "egulias/email-validator": "^2.1.10|^3|^4", + "league/html-to-markdown": "^5.0", "phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0", - "symfony/asset": "^5.4|^6.0", - "symfony/console": "^5.4|^6.0", - "symfony/dependency-injection": "^5.4|^6.0", - "symfony/expression-language": "^5.4|^6.0", - "symfony/finder": "^5.4|^6.0", - "symfony/form": "^6.1", - "symfony/html-sanitizer": "^6.1", - "symfony/http-foundation": "^5.4|^6.0", - "symfony/http-kernel": "^5.4|^6.0", - "symfony/intl": "^5.4|^6.0", - "symfony/mime": "^5.4|^6.0", + "symfony/asset": "^6.4|^7.0", + "symfony/asset-mapper": "^6.4|^7.0", + "symfony/console": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/emoji": "^7.1", + "symfony/expression-language": "^6.4|^7.0", + "symfony/finder": "^6.4|^7.0", + "symfony/form": "^6.4|^7.0", + "symfony/html-sanitizer": "^6.4|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/intl": "^6.4|^7.0", + "symfony/mime": "^6.4|^7.0", "symfony/polyfill-intl-icu": "~1.0", - "symfony/property-info": "^5.4|^6.0", - "symfony/routing": "^5.4|^6.0", + "symfony/property-info": "^6.4|^7.0", + "symfony/routing": "^6.4|^7.0", "symfony/security-acl": "^2.8|^3.0", - "symfony/security-core": "^5.4|^6.0", - "symfony/security-csrf": "^5.4|^6.0", - "symfony/security-http": "^5.4|^6.0", - "symfony/serializer": "^5.4|^6.0", - "symfony/stopwatch": "^5.4|^6.0", - "symfony/translation": "^5.4|^6.0", - "symfony/web-link": "^5.4|^6.0", - "symfony/workflow": "^5.4|^6.0", - "symfony/yaml": "^5.4|^6.0", + "symfony/security-core": "^6.4|^7.0", + "symfony/security-csrf": "^6.4|^7.0", + "symfony/security-http": "^6.4|^7.0", + "symfony/serializer": "^6.4.3|^7.0.3", + "symfony/stopwatch": "^6.4|^7.0", + "symfony/translation": "^6.4|^7.0", + "symfony/web-link": "^6.4|^7.0", + "symfony/workflow": "^6.4|^7.0", + "symfony/yaml": "^6.4|^7.0", "twig/cssinliner-extra": "^2.12|^3", "twig/inky-extra": "^2.12|^3", "twig/markdown-extra": "^2.12|^3" }, - "suggest": { - "symfony/asset": "For using the AssetExtension", - "symfony/expression-language": "For using the ExpressionExtension", - "symfony/finder": "", - "symfony/form": "For using the FormExtension", - "symfony/html-sanitizer": "For using the HtmlSanitizerExtension", - "symfony/http-kernel": "For using the HttpKernelExtension", - "symfony/routing": "For using the RoutingExtension", - "symfony/security-core": "For using the SecurityExtension", - "symfony/security-csrf": "For using the CsrfExtension", - "symfony/security-http": "For using the LogoutUrlExtension", - "symfony/stopwatch": "For using the StopwatchExtension", - "symfony/translation": "For using the TranslationExtension", - "symfony/var-dumper": "For using the DumpExtension", - "symfony/web-link": "For using the WebLinkExtension", - "symfony/yaml": "For using the YamlExtension" - }, "type": "symfony-bridge", "autoload": { "psr-4": { @@ -9033,7 +9190,7 @@ "description": "Provides integration for Twig with various Symfony components", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/twig-bridge/tree/v6.1.4" + "source": "https://github.com/symfony/twig-bridge/tree/v7.2.2" }, "funding": [ { @@ -9049,49 +9206,47 @@ "type": "tidelift" } ], - "time": "2022-08-04T19:19:00+00:00" + "time": "2024-12-19T14:25:03+00:00" }, { "name": "symfony/twig-bundle", - "version": "v6.1.1", + "version": "v7.2.0", "source": { "type": "git", "url": "https://github.com/symfony/twig-bundle.git", - "reference": "a2abab10068525a7f5a879e40e411d369d688545" + "reference": "cd2be4563afaef5285bb6e0a06c5445e644a5c01" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/twig-bundle/zipball/a2abab10068525a7f5a879e40e411d369d688545", - "reference": "a2abab10068525a7f5a879e40e411d369d688545", + "url": "https://api.github.com/repos/symfony/twig-bundle/zipball/cd2be4563afaef5285bb6e0a06c5445e644a5c01", + "reference": "cd2be4563afaef5285bb6e0a06c5445e644a5c01", "shasum": "" }, "require": { "composer-runtime-api": ">=2.1", - "php": ">=8.1", - "symfony/config": "^5.4|^6.0", - "symfony/dependency-injection": "^5.4|^6.0", - "symfony/http-foundation": "^5.4|^6.0", - "symfony/http-kernel": "^5.4|^6.0", - "symfony/polyfill-ctype": "~1.8", - "symfony/twig-bridge": "^5.4|^6.0", - "twig/twig": "^2.13|^3.0.4" + "php": ">=8.2", + "symfony/config": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/twig-bridge": "^6.4|^7.0", + "twig/twig": "^3.12" }, "conflict": { - "symfony/framework-bundle": "<5.4", - "symfony/translation": "<5.4" - }, - "require-dev": { - "doctrine/annotations": "^1.10.4", - "symfony/asset": "^5.4|^6.0", - "symfony/expression-language": "^5.4|^6.0", - "symfony/finder": "^5.4|^6.0", - "symfony/form": "^5.4|^6.0", - "symfony/framework-bundle": "^5.4|^6.0", - "symfony/routing": "^5.4|^6.0", - "symfony/stopwatch": "^5.4|^6.0", - "symfony/translation": "^5.4|^6.0", - "symfony/web-link": "^5.4|^6.0", - "symfony/yaml": "^5.4|^6.0" + "symfony/framework-bundle": "<6.4", + "symfony/translation": "<6.4" + }, + "require-dev": { + "symfony/asset": "^6.4|^7.0", + "symfony/expression-language": "^6.4|^7.0", + "symfony/finder": "^6.4|^7.0", + "symfony/form": "^6.4|^7.0", + "symfony/framework-bundle": "^6.4|^7.0", + "symfony/routing": "^6.4|^7.0", + "symfony/stopwatch": "^6.4|^7.0", + "symfony/translation": "^6.4|^7.0", + "symfony/web-link": "^6.4|^7.0", + "symfony/yaml": "^6.4|^7.0" }, "type": "symfony-bundle", "autoload": { @@ -9119,7 +9274,82 @@ "description": "Provides a tight integration of Twig into the Symfony full-stack framework", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/twig-bundle/tree/v6.1.1" + "source": "https://github.com/symfony/twig-bundle/tree/v7.2.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-10-23T08:11:15+00:00" + }, + { + "name": "symfony/type-info", + "version": "v7.2.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/type-info.git", + "reference": "3b5a17470fff0034f25fd4287cbdaa0010d2f749" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/type-info/zipball/3b5a17470fff0034f25fd4287cbdaa0010d2f749", + "reference": "3b5a17470fff0034f25fd4287cbdaa0010d2f749", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "psr/container": "^1.1|^2.0" + }, + "require-dev": { + "phpstan/phpdoc-parser": "^1.0|^2.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\TypeInfo\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mathias Arlaud", + "email": "mathias.arlaud@gmail.com" + }, + { + "name": "Baptiste LEDUC", + "email": "baptiste.leduc@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Extracts PHP types information.", + "homepage": "https://symfony.com", + "keywords": [ + "PHPStan", + "phpdoc", + "symfony", + "type" + ], + "support": { + "source": "https://github.com/symfony/type-info/tree/v7.2.2" }, "funding": [ { @@ -9135,71 +9365,59 @@ "type": "tidelift" } ], - "time": "2022-05-27T16:55:36+00:00" + "time": "2024-12-20T13:38:37+00:00" }, { "name": "symfony/validator", - "version": "v6.1.4", + "version": "v7.2.3", "source": { "type": "git", "url": "https://github.com/symfony/validator.git", - "reference": "14ec426b9c8ca8cf02bd863a645fb0cc0d73db79" + "reference": "6faf9f671d522b76ce87e46a1d2d7740b4385c6f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/validator/zipball/14ec426b9c8ca8cf02bd863a645fb0cc0d73db79", - "reference": "14ec426b9c8ca8cf02bd863a645fb0cc0d73db79", + "url": "https://api.github.com/repos/symfony/validator/zipball/6faf9f671d522b76ce87e46a1d2d7740b4385c6f", + "reference": "6faf9f671d522b76ce87e46a1d2d7740b4385c6f", "shasum": "" }, "require": { - "php": ">=8.1", - "symfony/deprecation-contracts": "^2.1|^3", + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3", "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-mbstring": "~1.0", - "symfony/translation-contracts": "^1.1|^2|^3" + "symfony/polyfill-php83": "^1.27", + "symfony/translation-contracts": "^2.5|^3" }, "conflict": { - "doctrine/annotations": "<1.13", "doctrine/lexer": "<1.1", - "phpunit/phpunit": "<5.4.3", - "symfony/dependency-injection": "<5.4", - "symfony/expression-language": "<5.4", - "symfony/http-kernel": "<5.4", - "symfony/intl": "<5.4", - "symfony/property-info": "<5.4", - "symfony/translation": "<5.4", - "symfony/yaml": "<5.4" - }, - "require-dev": { - "doctrine/annotations": "^1.13", - "egulias/email-validator": "^2.1.10|^3", - "symfony/cache": "^5.4|^6.0", - "symfony/config": "^5.4|^6.0", - "symfony/console": "^5.4|^6.0", - "symfony/dependency-injection": "^5.4|^6.0", - "symfony/expression-language": "^5.4|^6.0", - "symfony/finder": "^5.4|^6.0", - "symfony/http-client": "^5.4|^6.0", - "symfony/http-foundation": "^5.4|^6.0", - "symfony/http-kernel": "^5.4|^6.0", - "symfony/intl": "^5.4|^6.0", - "symfony/mime": "^5.4|^6.0", - "symfony/property-access": "^5.4|^6.0", - "symfony/property-info": "^5.4|^6.0", - "symfony/translation": "^5.4|^6.0", - "symfony/yaml": "^5.4|^6.0" - }, - "suggest": { - "egulias/email-validator": "Strict (RFC compliant) email validation", - "psr/cache-implementation": "For using the mapping cache.", - "symfony/config": "", - "symfony/expression-language": "For using the Expression validator and the ExpressionLanguageSyntax constraints", - "symfony/http-foundation": "", - "symfony/intl": "", - "symfony/property-access": "For accessing properties within comparison constraints", - "symfony/property-info": "To automatically add NotNull and Type constraints", - "symfony/translation": "For translating validation errors.", - "symfony/yaml": "" + "symfony/dependency-injection": "<6.4", + "symfony/doctrine-bridge": "<7.0", + "symfony/expression-language": "<6.4", + "symfony/http-kernel": "<6.4", + "symfony/intl": "<6.4", + "symfony/property-info": "<6.4", + "symfony/translation": "<6.4.3|>=7.0,<7.0.3", + "symfony/yaml": "<6.4" + }, + "require-dev": { + "egulias/email-validator": "^2.1.10|^3|^4", + "symfony/cache": "^6.4|^7.0", + "symfony/config": "^6.4|^7.0", + "symfony/console": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/expression-language": "^6.4|^7.0", + "symfony/finder": "^6.4|^7.0", + "symfony/http-client": "^6.4|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/intl": "^6.4|^7.0", + "symfony/mime": "^6.4|^7.0", + "symfony/property-access": "^6.4|^7.0", + "symfony/property-info": "^6.4|^7.0", + "symfony/translation": "^6.4.3|^7.0.3", + "symfony/type-info": "^7.1", + "symfony/yaml": "^6.4|^7.0" }, "type": "library", "autoload": { @@ -9207,7 +9425,8 @@ "Symfony\\Component\\Validator\\": "" }, "exclude-from-classmap": [ - "/Tests/" + "/Tests/", + "/Resources/bin/" ] }, "notification-url": "https://packagist.org/downloads/", @@ -9227,7 +9446,7 @@ "description": "Provides tools to validate values", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/validator/tree/v6.1.4" + "source": "https://github.com/symfony/validator/tree/v7.2.3" }, "funding": [ { @@ -9243,41 +9462,36 @@ "type": "tidelift" } ], - "time": "2022-08-12T13:09:07+00:00" + "time": "2025-01-28T15:51:35+00:00" }, { "name": "symfony/var-dumper", - "version": "v6.1.3", + "version": "v7.2.3", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "d5a5e44a2260c5eb5e746bf4f1fbd12ee6ceb427" + "reference": "82b478c69745d8878eb60f9a049a4d584996f73a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/d5a5e44a2260c5eb5e746bf4f1fbd12ee6ceb427", - "reference": "d5a5e44a2260c5eb5e746bf4f1fbd12ee6ceb427", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/82b478c69745d8878eb60f9a049a4d584996f73a", + "reference": "82b478c69745d8878eb60f9a049a4d584996f73a", "shasum": "" }, "require": { - "php": ">=8.1", + "php": ">=8.2", "symfony/polyfill-mbstring": "~1.0" }, "conflict": { - "phpunit/phpunit": "<5.4.3", - "symfony/console": "<5.4" + "symfony/console": "<6.4" }, "require-dev": { "ext-iconv": "*", - "symfony/console": "^5.4|^6.0", - "symfony/process": "^5.4|^6.0", - "symfony/uid": "^5.4|^6.0", - "twig/twig": "^2.13|^3.0.4" - }, - "suggest": { - "ext-iconv": "To convert non-UTF-8 strings to UTF-8 (or symfony/polyfill-iconv in case ext-iconv cannot be used).", - "ext-intl": "To show region name in time zone dump", - "symfony/console": "To use the ServerDumpCommand and/or the bin/var-dump-server script" + "symfony/console": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/process": "^6.4|^7.0", + "symfony/uid": "^6.4|^7.0", + "twig/twig": "^3.12" }, "bin": [ "Resources/bin/var-dump-server" @@ -9315,7 +9529,7 @@ "dump" ], "support": { - "source": "https://github.com/symfony/var-dumper/tree/v6.1.3" + "source": "https://github.com/symfony/var-dumper/tree/v7.2.3" }, "funding": [ { @@ -9331,27 +9545,29 @@ "type": "tidelift" } ], - "time": "2022-07-20T13:46:29+00:00" + "time": "2025-01-17T11:39:41+00:00" }, { "name": "symfony/var-exporter", - "version": "v6.1.3", + "version": "v7.2.0", "source": { "type": "git", "url": "https://github.com/symfony/var-exporter.git", - "reference": "b49350f45cebbba6e5286485264b912f2bcfc9ef" + "reference": "1a6a89f95a46af0f142874c9d650a6358d13070d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-exporter/zipball/b49350f45cebbba6e5286485264b912f2bcfc9ef", - "reference": "b49350f45cebbba6e5286485264b912f2bcfc9ef", + "url": "https://api.github.com/repos/symfony/var-exporter/zipball/1a6a89f95a46af0f142874c9d650a6358d13070d", + "reference": "1a6a89f95a46af0f142874c9d650a6358d13070d", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.2" }, "require-dev": { - "symfony/var-dumper": "^5.4|^6.0" + "symfony/property-access": "^6.4|^7.0", + "symfony/serializer": "^6.4|^7.0", + "symfony/var-dumper": "^6.4|^7.0" }, "type": "library", "autoload": { @@ -9384,10 +9600,12 @@ "export", "hydrate", "instantiate", + "lazy-loading", + "proxy", "serialize" ], "support": { - "source": "https://github.com/symfony/var-exporter/tree/v6.1.3" + "source": "https://github.com/symfony/var-exporter/tree/v7.2.0" }, "funding": [ { @@ -9403,37 +9621,34 @@ "type": "tidelift" } ], - "time": "2022-07-04T16:01:56+00:00" + "time": "2024-10-18T07:58:17+00:00" }, { "name": "symfony/web-link", - "version": "v6.1.0", + "version": "v7.2.0", "source": { "type": "git", "url": "https://github.com/symfony/web-link.git", - "reference": "d6ef738f97b60d859652d92f10bf8645bca28cd6" + "reference": "f537556a885e14a1d28f6c759d41e57e93d0a532" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/web-link/zipball/d6ef738f97b60d859652d92f10bf8645bca28cd6", - "reference": "d6ef738f97b60d859652d92f10bf8645bca28cd6", + "url": "https://api.github.com/repos/symfony/web-link/zipball/f537556a885e14a1d28f6c759d41e57e93d0a532", + "reference": "f537556a885e14a1d28f6c759d41e57e93d0a532", "shasum": "" }, "require": { - "php": ">=8.1", + "php": ">=8.2", "psr/link": "^1.1|^2.0" }, "conflict": { - "symfony/http-kernel": "<5.4" + "symfony/http-kernel": "<6.4" }, "provide": { "psr/link-implementation": "1.0|2.0" }, "require-dev": { - "symfony/http-kernel": "^5.4|^6.0" - }, - "suggest": { - "symfony/http-kernel": "" + "symfony/http-kernel": "^6.4|^7.0" }, "type": "library", "autoload": { @@ -9473,7 +9688,7 @@ "push" ], "support": { - "source": "https://github.com/symfony/web-link/tree/v6.1.0" + "source": "https://github.com/symfony/web-link/tree/v7.2.0" }, "funding": [ { @@ -9489,34 +9704,32 @@ "type": "tidelift" } ], - "time": "2022-02-25T11:15:52+00:00" + "time": "2024-09-25T14:21:43+00:00" }, { "name": "symfony/yaml", - "version": "v6.1.4", + "version": "v7.2.3", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "86ee4d8fa594ed45e40d86eedfda1bcb66c8d919" + "reference": "ac238f173df0c9c1120f862d0f599e17535a87ec" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/86ee4d8fa594ed45e40d86eedfda1bcb66c8d919", - "reference": "86ee4d8fa594ed45e40d86eedfda1bcb66c8d919", + "url": "https://api.github.com/repos/symfony/yaml/zipball/ac238f173df0c9c1120f862d0f599e17535a87ec", + "reference": "ac238f173df0c9c1120f862d0f599e17535a87ec", "shasum": "" }, "require": { - "php": ">=8.1", + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3.0", "symfony/polyfill-ctype": "^1.8" }, "conflict": { - "symfony/console": "<5.4" + "symfony/console": "<6.4" }, "require-dev": { - "symfony/console": "^5.4|^6.0" - }, - "suggest": { - "symfony/console": "For validating YAML files using the lint command" + "symfony/console": "^6.4|^7.0" }, "bin": [ "Resources/bin/yaml-lint" @@ -9547,7 +9760,7 @@ "description": "Loads and dumps YAML files", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/yaml/tree/v6.1.4" + "source": "https://github.com/symfony/yaml/tree/v7.2.3" }, "funding": [ { @@ -9563,45 +9776,40 @@ "type": "tidelift" } ], - "time": "2022-08-02T16:17:38+00:00" + "time": "2025-01-07T12:55:42+00:00" }, { "name": "twig/extra-bundle", - "version": "v3.4.0", + "version": "v3.19.0", "source": { "type": "git", "url": "https://github.com/twigphp/twig-extra-bundle.git", - "reference": "2e58256b0e9fe52f30149347c0547e4633304765" + "reference": "9746573ca4bc1cd03a767a183faadaf84e0c31fa" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/twig-extra-bundle/zipball/2e58256b0e9fe52f30149347c0547e4633304765", - "reference": "2e58256b0e9fe52f30149347c0547e4633304765", + "url": "https://api.github.com/repos/twigphp/twig-extra-bundle/zipball/9746573ca4bc1cd03a767a183faadaf84e0c31fa", + "reference": "9746573ca4bc1cd03a767a183faadaf84e0c31fa", "shasum": "" }, "require": { - "php": ">=7.2.5", - "symfony/framework-bundle": "^4.4|^5.0|^6.0", - "symfony/twig-bundle": "^4.4|^5.0|^6.0", - "twig/twig": "^2.7|^3.0" + "php": ">=8.0.2", + "symfony/framework-bundle": "^5.4|^6.4|^7.0", + "symfony/twig-bundle": "^5.4|^6.4|^7.0", + "twig/twig": "^3.2|^4.0" }, "require-dev": { "league/commonmark": "^1.0|^2.0", - "symfony/phpunit-bridge": "^4.4.9|^5.0.9|^6.0", + "symfony/phpunit-bridge": "^6.4|^7.0", "twig/cache-extra": "^3.0", - "twig/cssinliner-extra": "^2.12|^3.0", - "twig/html-extra": "^2.12|^3.0", - "twig/inky-extra": "^2.12|^3.0", - "twig/intl-extra": "^2.12|^3.0", - "twig/markdown-extra": "^2.12|^3.0", - "twig/string-extra": "^2.12|^3.0" + "twig/cssinliner-extra": "^3.0", + "twig/html-extra": "^3.0", + "twig/inky-extra": "^3.0", + "twig/intl-extra": "^3.0", + "twig/markdown-extra": "^3.0", + "twig/string-extra": "^3.0" }, "type": "symfony-bundle", - "extra": { - "branch-alias": { - "dev-master": "3.2-dev" - } - }, "autoload": { "psr-4": { "Twig\\Extra\\TwigExtraBundle\\": "" @@ -9630,7 +9838,7 @@ "twig" ], "support": { - "source": "https://github.com/twigphp/twig-extra-bundle/tree/v3.4.0" + "source": "https://github.com/twigphp/twig-extra-bundle/tree/v3.19.0" }, "funding": [ { @@ -9642,36 +9850,31 @@ "type": "tidelift" } ], - "time": "2022-01-04T13:58:53+00:00" + "time": "2024-09-26T19:22:23+00:00" }, { "name": "twig/intl-extra", - "version": "v3.4.2", + "version": "v3.19.0", "source": { "type": "git", "url": "https://github.com/twigphp/intl-extra.git", - "reference": "151e50fad9c7915bd56f0adf3f0cb3c47e6ed28a" + "reference": "79a1bea7254783b540d51de10dc5e9f310110794" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/intl-extra/zipball/151e50fad9c7915bd56f0adf3f0cb3c47e6ed28a", - "reference": "151e50fad9c7915bd56f0adf3f0cb3c47e6ed28a", + "url": "https://api.github.com/repos/twigphp/intl-extra/zipball/79a1bea7254783b540d51de10dc5e9f310110794", + "reference": "79a1bea7254783b540d51de10dc5e9f310110794", "shasum": "" }, "require": { - "php": ">=7.1.3", - "symfony/intl": "^4.4|^5.0|^6.0", - "twig/twig": "^2.7|^3.0" + "php": ">=8.0.2", + "symfony/intl": "^5.4|^6.4|^7.0", + "twig/twig": "^3.13|^4.0" }, "require-dev": { - "symfony/phpunit-bridge": "^4.4.9|^5.0.9|^6.0" + "symfony/phpunit-bridge": "^6.4|^7.0" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.2-dev" - } - }, "autoload": { "psr-4": { "Twig\\Extra\\Intl\\": "" @@ -9699,7 +9902,7 @@ "twig" ], "support": { - "source": "https://github.com/twigphp/intl-extra/tree/v3.4.2" + "source": "https://github.com/twigphp/intl-extra/tree/v3.19.0" }, "funding": [ { @@ -9711,38 +9914,42 @@ "type": "tidelift" } ], - "time": "2022-06-10T08:33:05+00:00" + "time": "2025-01-24T20:20:33+00:00" }, { "name": "twig/twig", - "version": "v3.4.3", + "version": "v3.19.0", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "c38fd6b0b7f370c198db91ffd02e23b517426b58" + "reference": "d4f8c2b86374f08efc859323dbcd95c590f7124e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/c38fd6b0b7f370c198db91ffd02e23b517426b58", - "reference": "c38fd6b0b7f370c198db91ffd02e23b517426b58", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/d4f8c2b86374f08efc859323dbcd95c590f7124e", + "reference": "d4f8c2b86374f08efc859323dbcd95c590f7124e", "shasum": "" }, "require": { - "php": ">=7.2.5", + "php": ">=8.0.2", + "symfony/deprecation-contracts": "^2.5|^3", "symfony/polyfill-ctype": "^1.8", - "symfony/polyfill-mbstring": "^1.3" + "symfony/polyfill-mbstring": "^1.3", + "symfony/polyfill-php81": "^1.29" }, "require-dev": { - "psr/container": "^1.0", - "symfony/phpunit-bridge": "^4.4.9|^5.0.9|^6.0" + "phpstan/phpstan": "^2.0", + "psr/container": "^1.0|^2.0", + "symfony/phpunit-bridge": "^5.4.9|^6.4|^7.0" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.4-dev" - } - }, "autoload": { + "files": [ + "src/Resources/core.php", + "src/Resources/debug.php", + "src/Resources/escaper.php", + "src/Resources/string_loader.php" + ], "psr-4": { "Twig\\": "src/" } @@ -9775,7 +9982,7 @@ ], "support": { "issues": "https://github.com/twigphp/Twig/issues", - "source": "https://github.com/twigphp/Twig/tree/v3.4.3" + "source": "https://github.com/twigphp/Twig/tree/v3.19.0" }, "funding": [ { @@ -9787,68 +9994,69 @@ "type": "tidelift" } ], - "time": "2022-09-28T08:42:51+00:00" + "time": "2025-01-29T07:06:14+00:00" }, { "name": "vich/uploader-bundle", - "version": "1.21.1", + "version": "v2.5.1", "source": { "type": "git", "url": "https://github.com/dustin10/VichUploaderBundle.git", - "reference": "6b428642694cbfeb1be6e956ba59382d89ae1ee6" + "reference": "79fd69ad8f32d4a33ac8783d7720e16e78bb8098" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/dustin10/VichUploaderBundle/zipball/6b428642694cbfeb1be6e956ba59382d89ae1ee6", - "reference": "6b428642694cbfeb1be6e956ba59382d89ae1ee6", + "url": "https://api.github.com/repos/dustin10/VichUploaderBundle/zipball/79fd69ad8f32d4a33ac8783d7720e16e78bb8098", + "reference": "79fd69ad8f32d4a33ac8783d7720e16e78bb8098", "shasum": "" }, "require": { - "doctrine/persistence": "^1.3 || ^2 || ^3", + "doctrine/persistence": "^3.0", "ext-simplexml": "*", - "jms/metadata": "^1.7 || ^2.4", - "php": "^7.3 || ^8.0", - "symfony/config": "^4.4 || ^5.0 || ^6.0", - "symfony/console": "^4.4 || ^5.0 || ^6.0", - "symfony/dependency-injection": "^4.4 || ^5.0 || ^6.0", - "symfony/event-dispatcher-contracts": "^1.1 || ^2.0 || ^3.0", - "symfony/http-foundation": "^4.4 || ^5.0 || ^6.0", - "symfony/http-kernel": "^4.4 || ^5.0 || ^6.0", - "symfony/mime": "^4.4 || ^5.0 || ^6.0", - "symfony/property-access": "^4.4 || ^5.0 || ^6.0", - "symfony/string": "^5.0 || ^6.0" + "jms/metadata": "^2.4", + "php": "^8.1", + "symfony/config": "^5.4 || ^6.0 || ^7.0", + "symfony/console": "^5.4 || ^6.0 || ^7.0", + "symfony/dependency-injection": "^5.4 || ^6.0 || ^7.0", + "symfony/event-dispatcher-contracts": "^3.1", + "symfony/http-foundation": "^5.4 || ^6.0 || ^7.0", + "symfony/http-kernel": "^5.4 || ^6.0 || ^7.0", + "symfony/mime": "^5.4 || ^6.0 || ^7.0", + "symfony/property-access": "^5.4 || ^6.0 || ^7.0", + "symfony/string": "^5.4 || ^6.0 || ^7.0" }, "conflict": { "doctrine/annotations": "<1.12", "league/flysystem": "<2.0" }, "require-dev": { - "alcaeus/mongo-php-adapter": "^1.2", - "doctrine/doctrine-bundle": "^2.2", - "doctrine/mongodb-odm": "^1.2 || ^2.0", - "doctrine/orm": "^2.7", + "dg/bypass-finals": "^1.8", + "doctrine/doctrine-bundle": "^2.7", + "doctrine/mongodb-odm": "^2.4", + "doctrine/orm": "^2.13", "ext-sqlite3": "*", "knplabs/knp-gaufrette-bundle": "dev-master", - "league/flysystem-bundle": "^2.0", - "league/flysystem-memory": "^2.0", - "matthiasnoback/symfony-dependency-injection-test": "^4.1", - "mikey179/vfsstream": "^1.6.8", - "phpunit/phpunit": "^9.5", - "symfony/asset": "^4.4 || ^5.0 || ^6.0", - "symfony/browser-kit": "^4.4 || ^5.0 || ^6.0", - "symfony/css-selector": "^4.4 || ^5.0 || ^6.0", - "symfony/doctrine-bridge": "^4.4 || ^5.0 || ^6.0", - "symfony/dom-crawler": "^4.4 || ^5.0 || ^6.0", - "symfony/form": "^4.4 || ^5.0 || ^6.0", - "symfony/framework-bundle": "^4.4 || ^5.0 || ^6.0", - "symfony/phpunit-bridge": "^6.0", - "symfony/security-csrf": "^4.4 || ^5.0 || ^6.0", - "symfony/translation": "^4.4 || ^5.0 || ^6.0", - "symfony/twig-bridge": "^4.4 || ^5.0 || ^6.0", - "symfony/twig-bundle": "^4.4 || ^5.0 || ^6.0", - "symfony/validator": "^4.4 || ^5.0 || ^6.0", - "symfony/var-dumper": "^4.4 || ^5.0 || ^6.0", - "symfony/yaml": "^4.4 || ^5.0 || ^6.0" + "league/flysystem-bundle": "^2.4 || ^3.0", + "league/flysystem-memory": "^2.0 || ^3.0", + "matthiasnoback/symfony-dependency-injection-test": "^5.1", + "mikey179/vfsstream": "^1.6.11", + "phpunit/phpunit": "^9.6", + "symfony/asset": "^5.4 || ^6.0 || ^7.0", + "symfony/browser-kit": "^5.4 || ^6.0 || ^7.0", + "symfony/css-selector": "^5.4 || ^6.0 || ^7.0", + "symfony/doctrine-bridge": "^5.4 || ^6.0 || ^7.0", + "symfony/dom-crawler": "^5.4 || ^6.0 || ^7.0", + "symfony/form": "^5.4 || ^6.0 || ^7.0", + "symfony/framework-bundle": "^5.4 || ^6.0 || ^7.0", + "symfony/phpunit-bridge": "^7.0", + "symfony/security-csrf": "^5.4 || ^6.0 || ^7.0", + "symfony/translation": "^5.4 || ^6.0 || ^7.0", + "symfony/twig-bridge": "^5.4 || ^6.0 || ^7.0", + "symfony/twig-bundle": "^5.4 || ^6.0 || ^7.0", + "symfony/validator": "^5.4 || ^6.0 || ^7.0", + "symfony/var-dumper": "^5.4 || ^6.0 || ^7.0", + "symfony/yaml": "^5.4 || ^6.0 || ^7.0", + "yoast/phpunit-polyfills": "^2.0" }, "suggest": { "doctrine/doctrine-bundle": "For integration with Doctrine", @@ -9858,7 +10066,6 @@ "knplabs/knp-gaufrette-bundle": "For integration with Gaufrette", "league/flysystem-bundle": "For integration with Flysystem", "liip/imagine-bundle": "To generate image thumbnails", - "ocramius/proxy-manager": "To use lazy services", "oneup/flysystem-bundle": "For integration with Flysystem", "symfony/asset": "To generate better links", "symfony/form": "To handle uploads in forms", @@ -9867,7 +10074,7 @@ "type": "symfony-bundle", "extra": { "branch-alias": { - "dev-master": "1.x-dev" + "dev-master": "2.x-dev" } }, "autoload": { @@ -9893,9 +10100,9 @@ ], "support": { "issues": "https://github.com/dustin10/VichUploaderBundle/issues", - "source": "https://github.com/dustin10/VichUploaderBundle/tree/1.21.1" + "source": "https://github.com/dustin10/VichUploaderBundle/tree/v2.5.1" }, - "time": "2022-08-12T07:38:44+00:00" + "time": "2024-12-31T08:59:03+00:00" }, { "name": "webmozart/assert", @@ -10056,32 +10263,41 @@ }, { "name": "zircote/swagger-php", - "version": "4.4.8", + "version": "5.0.3", "source": { "type": "git", "url": "https://github.com/zircote/swagger-php.git", - "reference": "34c0980c4cd4f32a1a43f995463001e450d18896" + "reference": "7708510b17502a416214148edaa8c9958b23b6cd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zircote/swagger-php/zipball/34c0980c4cd4f32a1a43f995463001e450d18896", - "reference": "34c0980c4cd4f32a1a43f995463001e450d18896", + "url": "https://api.github.com/repos/zircote/swagger-php/zipball/7708510b17502a416214148edaa8c9958b23b6cd", + "reference": "7708510b17502a416214148edaa8c9958b23b6cd", "shasum": "" }, "require": { - "doctrine/annotations": "^1.7", "ext-json": "*", - "php": ">=7.2", + "nikic/php-parser": "^4.19 || ^5.0", + "php": ">=7.4", "psr/log": "^1.1 || ^2.0 || ^3.0", - "symfony/finder": ">=2.2", - "symfony/yaml": ">=3.3" + "symfony/deprecation-contracts": "^2 || ^3", + "symfony/finder": "^5.0 || ^6.0 || ^7.0", + "symfony/yaml": "^5.0 || ^6.0 || ^7.0" + }, + "conflict": { + "symfony/process": ">=6, <6.4.14" }, "require-dev": { "composer/package-versions-deprecated": "^1.11", - "friendsofphp/php-cs-fixer": "^2.17 || ^3.0", - "phpstan/phpstan": "^1.6", - "phpunit/phpunit": ">=8", - "vimeo/psalm": "^4.23" + "doctrine/annotations": "^2.0", + "friendsofphp/php-cs-fixer": "^3.62.0", + "phpstan/phpstan": "^1.6 || ^2.0", + "phpunit/phpunit": "^9.0", + "rector/rector": "^1.0 || ^2.0", + "vimeo/psalm": "^4.30 || ^5.0" + }, + "suggest": { + "doctrine/annotations": "^2.0" }, "bin": [ "bin/openapi" @@ -10089,7 +10305,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.x-dev" + "dev-master": "5.x-dev" } }, "autoload": { @@ -10127,43 +10343,38 @@ ], "support": { "issues": "https://github.com/zircote/swagger-php/issues", - "source": "https://github.com/zircote/swagger-php/tree/4.4.8" + "source": "https://github.com/zircote/swagger-php/tree/5.0.3" }, - "time": "2022-08-16T23:21:13+00:00" + "time": "2025-01-15T21:02:43+00:00" } ], "packages-dev": [ { - "name": "dealerdirect/phpcodesniffer-composer-installer", - "version": "v0.7.2", + "name": "clue/ndjson-react", + "version": "v1.3.0", "source": { "type": "git", - "url": "https://github.com/Dealerdirect/phpcodesniffer-composer-installer.git", - "reference": "1c968e542d8843d7cd71de3c5c9c3ff3ad71a1db" + "url": "https://github.com/clue/reactphp-ndjson.git", + "reference": "392dc165fce93b5bb5c637b67e59619223c931b0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Dealerdirect/phpcodesniffer-composer-installer/zipball/1c968e542d8843d7cd71de3c5c9c3ff3ad71a1db", - "reference": "1c968e542d8843d7cd71de3c5c9c3ff3ad71a1db", + "url": "https://api.github.com/repos/clue/reactphp-ndjson/zipball/392dc165fce93b5bb5c637b67e59619223c931b0", + "reference": "392dc165fce93b5bb5c637b67e59619223c931b0", "shasum": "" }, "require": { - "composer-plugin-api": "^1.0 || ^2.0", "php": ">=5.3", - "squizlabs/php_codesniffer": "^2.0 || ^3.1.0 || ^4.0" + "react/stream": "^1.2" }, "require-dev": { - "composer/composer": "*", - "php-parallel-lint/php-parallel-lint": "^1.3.1", - "phpcompatibility/php-compatibility": "^9.0" - }, - "type": "composer-plugin", - "extra": { - "class": "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\Plugin" + "phpunit/phpunit": "^9.5 || ^5.7 || ^4.8.35", + "react/event-loop": "^1.2" }, + "type": "library", "autoload": { "psr-4": { - "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\": "src/" + "Clue\\React\\NDJson\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -10172,21 +10383,158 @@ ], "authors": [ { - "name": "Franck Nijhof", - "email": "franck.nijhof@dealerdirect.com", - "homepage": "http://www.frenck.nl", - "role": "Developer / IT Manager" + "name": "Christian Lück", + "email": "christian@clue.engineering" + } + ], + "description": "Streaming newline-delimited JSON (NDJSON) parser and encoder for ReactPHP.", + "homepage": "https://github.com/clue/reactphp-ndjson", + "keywords": [ + "NDJSON", + "json", + "jsonlines", + "newline", + "reactphp", + "streaming" + ], + "support": { + "issues": "https://github.com/clue/reactphp-ndjson/issues", + "source": "https://github.com/clue/reactphp-ndjson/tree/v1.3.0" + }, + "funding": [ + { + "url": "https://clue.engineering/support", + "type": "custom" }, { - "name": "Contributors", - "homepage": "https://github.com/Dealerdirect/phpcodesniffer-composer-installer/graphs/contributors" + "url": "https://github.com/clue", + "type": "github" } ], - "description": "PHP_CodeSniffer Standards Composer Installer Plugin", - "homepage": "http://www.dealerdirect.com", - "keywords": [ - "PHPCodeSniffer", - "PHP_CodeSniffer", + "time": "2022-12-23T10:58:28+00:00" + }, + { + "name": "cmgmyr/phploc", + "version": "8.0.4", + "source": { + "type": "git", + "url": "https://github.com/cmgmyr/phploc.git", + "reference": "b0c4ec71f40ef84c9893e1a7212a72e1098b90f7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/cmgmyr/phploc/zipball/b0c4ec71f40ef84c9893e1a7212a72e1098b90f7", + "reference": "b0c4ec71f40ef84c9893e1a7212a72e1098b90f7", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-json": "*", + "php": "^7.4 || ^8.0", + "phpunit/php-file-iterator": "^3.0|^4.0|^5.0", + "sebastian/cli-parser": "^1.0|^2.0|^3.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.2", + "phpunit/phpunit": "^9.0|^10.0", + "vimeo/psalm": "^5.7" + }, + "bin": [ + "phploc" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "8.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Chris Gmyr", + "email": "cmgmyr@gmail.com", + "role": "lead" + } + ], + "description": "A tool for quickly measuring the size of a PHP project.", + "homepage": "https://github.com/cmgmyr/phploc", + "support": { + "issues": "https://github.com/cmgmyr/phploc/issues", + "source": "https://github.com/cmgmyr/phploc/tree/8.0.4" + }, + "funding": [ + { + "url": "https://github.com/cmgmyr", + "type": "github" + } + ], + "time": "2024-10-31T19:26:53+00:00" + }, + { + "name": "dealerdirect/phpcodesniffer-composer-installer", + "version": "v1.0.0", + "source": { + "type": "git", + "url": "https://github.com/PHPCSStandards/composer-installer.git", + "reference": "4be43904336affa5c2f70744a348312336afd0da" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHPCSStandards/composer-installer/zipball/4be43904336affa5c2f70744a348312336afd0da", + "reference": "4be43904336affa5c2f70744a348312336afd0da", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.0 || ^2.0", + "php": ">=5.4", + "squizlabs/php_codesniffer": "^2.0 || ^3.1.0 || ^4.0" + }, + "require-dev": { + "composer/composer": "*", + "ext-json": "*", + "ext-zip": "*", + "php-parallel-lint/php-parallel-lint": "^1.3.1", + "phpcompatibility/php-compatibility": "^9.0", + "yoast/phpunit-polyfills": "^1.0" + }, + "type": "composer-plugin", + "extra": { + "class": "PHPCSStandards\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\Plugin" + }, + "autoload": { + "psr-4": { + "PHPCSStandards\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Franck Nijhof", + "email": "franck.nijhof@dealerdirect.com", + "homepage": "http://www.frenck.nl", + "role": "Developer / IT Manager" + }, + { + "name": "Contributors", + "homepage": "https://github.com/PHPCSStandards/composer-installer/graphs/contributors" + } + ], + "description": "PHP_CodeSniffer Standards Composer Installer Plugin", + "homepage": "http://www.dealerdirect.com", + "keywords": [ + "PHPCodeSniffer", + "PHP_CodeSniffer", "code quality", "codesniffer", "composer", @@ -10203,23 +10551,23 @@ "tests" ], "support": { - "issues": "https://github.com/dealerdirect/phpcodesniffer-composer-installer/issues", - "source": "https://github.com/dealerdirect/phpcodesniffer-composer-installer" + "issues": "https://github.com/PHPCSStandards/composer-installer/issues", + "source": "https://github.com/PHPCSStandards/composer-installer" }, - "time": "2022-02-04T12:51:07+00:00" + "time": "2023-01-05T11:28:13+00:00" }, { "name": "dg/bypass-finals", - "version": "v1.3.1", + "version": "v1.9.0", "source": { "type": "git", "url": "https://github.com/dg/bypass-finals.git", - "reference": "495f5bc762e7bf30a13ed8253f44bb3a701767bb" + "reference": "920a7da2f3c1422fd83f9ec4df007af53dc4018b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/dg/bypass-finals/zipball/495f5bc762e7bf30a13ed8253f44bb3a701767bb", - "reference": "495f5bc762e7bf30a13ed8253f44bb3a701767bb", + "url": "https://api.github.com/repos/dg/bypass-finals/zipball/920a7da2f3c1422fd83f9ec4df007af53dc4018b", + "reference": "920a7da2f3c1422fd83f9ec4df007af53dc4018b", "shasum": "" }, "require": { @@ -10238,8 +10586,8 @@ "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause", - "GPL-2.0", - "GPL-3.0" + "GPL-2.0-only", + "GPL-3.0-only" ], "authors": [ { @@ -10257,44 +10605,45 @@ ], "support": { "issues": "https://github.com/dg/bypass-finals/issues", - "source": "https://github.com/dg/bypass-finals/tree/v1.3.1" + "source": "https://github.com/dg/bypass-finals/tree/v1.9.0" }, - "time": "2021-04-09T10:42:55+00:00" + "time": "2025-01-16T00:46:05+00:00" }, { "name": "doctrine/data-fixtures", - "version": "1.5.3", + "version": "2.0.2", "source": { "type": "git", "url": "https://github.com/doctrine/data-fixtures.git", - "reference": "ba37bfb776de763c5bf04a36d074cd5f5a083c42" + "reference": "f7f1e12d6bceb58c204b3e77210a103c1c57601e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/data-fixtures/zipball/ba37bfb776de763c5bf04a36d074cd5f5a083c42", - "reference": "ba37bfb776de763c5bf04a36d074cd5f5a083c42", + "url": "https://api.github.com/repos/doctrine/data-fixtures/zipball/f7f1e12d6bceb58c204b3e77210a103c1c57601e", + "reference": "f7f1e12d6bceb58c204b3e77210a103c1c57601e", "shasum": "" }, "require": { - "doctrine/common": "^2.13|^3.0", - "doctrine/persistence": "^1.3.3|^2.0|^3.0", - "php": "^7.2 || ^8.0" + "doctrine/persistence": "^3.1 || ^4.0", + "php": "^8.1", + "psr/log": "^1.1 || ^2 || ^3" }, "conflict": { - "doctrine/dbal": "<2.13", + "doctrine/dbal": "<3.5 || >=5", + "doctrine/orm": "<2.14 || >=4", "doctrine/phpcr-odm": "<1.3.0" }, "require-dev": { - "doctrine/coding-standard": "^9.0", - "doctrine/dbal": "^2.13 || ^3.0", + "doctrine/coding-standard": "^12", + "doctrine/dbal": "^3.5 || ^4", "doctrine/mongodb-odm": "^1.3.0 || ^2.0.0", - "doctrine/orm": "^2.7.0", + "doctrine/orm": "^2.14 || ^3", "ext-sqlite3": "*", - "jangregor/phpstan-prophecy": "^1", - "phpstan/phpstan": "^1.5", - "phpunit/phpunit": "^8.5 || ^9.5", - "symfony/cache": "^5.0 || ^6.0", - "vimeo/psalm": "^4.10" + "fig/log-test": "^1", + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^10.5.3", + "symfony/cache": "^6.4 || ^7", + "symfony/var-exporter": "^6.4 || ^7" }, "suggest": { "alcaeus/mongo-php-adapter": "For using MongoDB ODM 1.3 with PHP 7 (deprecated)", @@ -10305,7 +10654,7 @@ "type": "library", "autoload": { "psr-4": { - "Doctrine\\Common\\DataFixtures\\": "lib/Doctrine/Common/DataFixtures" + "Doctrine\\Common\\DataFixtures\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -10325,7 +10674,7 @@ ], "support": { "issues": "https://github.com/doctrine/data-fixtures/issues", - "source": "https://github.com/doctrine/data-fixtures/tree/1.5.3" + "source": "https://github.com/doctrine/data-fixtures/tree/2.0.2" }, "funding": [ { @@ -10341,45 +10690,48 @@ "type": "tidelift" } ], - "time": "2022-04-19T10:01:44+00:00" + "time": "2025-01-21T13:21:31+00:00" }, { "name": "doctrine/doctrine-fixtures-bundle", - "version": "3.4.2", + "version": "4.0.0", "source": { "type": "git", "url": "https://github.com/doctrine/DoctrineFixturesBundle.git", - "reference": "601988c5b46dbd20a0f886f967210aba378a6fd5" + "reference": "90185317e6bb3d845667c5ebd444d9c83ae19a01" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/DoctrineFixturesBundle/zipball/601988c5b46dbd20a0f886f967210aba378a6fd5", - "reference": "601988c5b46dbd20a0f886f967210aba378a6fd5", + "url": "https://api.github.com/repos/doctrine/DoctrineFixturesBundle/zipball/90185317e6bb3d845667c5ebd444d9c83ae19a01", + "reference": "90185317e6bb3d845667c5ebd444d9c83ae19a01", "shasum": "" }, "require": { - "doctrine/data-fixtures": "^1.3", - "doctrine/doctrine-bundle": "^1.11|^2.0", - "doctrine/orm": "^2.6.0", - "doctrine/persistence": "^1.3.7|^2.0|^3.0", - "php": "^7.1 || ^8.0", - "symfony/config": "^3.4|^4.3|^5.0|^6.0", - "symfony/console": "^3.4|^4.3|^5.0|^6.0", - "symfony/dependency-injection": "^3.4.47|^4.3|^5.0|^6.0", - "symfony/doctrine-bridge": "^3.4|^4.1|^5.0|^6.0", - "symfony/http-kernel": "^3.4|^4.3|^5.0|^6.0" + "doctrine/data-fixtures": "^2.0", + "doctrine/doctrine-bundle": "^2.2", + "doctrine/orm": "^2.14.0 || ^3.0", + "doctrine/persistence": "^2.4 || ^3.0", + "php": "^8.1", + "psr/log": "^2 || ^3", + "symfony/config": "^5.4 || ^6.0 || ^7.0", + "symfony/console": "^5.4 || ^6.0 || ^7.0", + "symfony/dependency-injection": "^5.4 || ^6.0 || ^7.0", + "symfony/deprecation-contracts": "^2.1 || ^3", + "symfony/doctrine-bridge": "^5.4.48 || ^6.4.16 || ^7.1.9", + "symfony/http-kernel": "^5.4 || ^6.0 || ^7.0" + }, + "conflict": { + "doctrine/dbal": "< 3" }, "require-dev": { - "doctrine/coding-standard": "^9", - "phpstan/phpstan": "^1.4.10", - "phpunit/phpunit": "^7.5.20 || ^8.5.26 || ^9.5.20", - "symfony/phpunit-bridge": "^6.0.8", - "vimeo/psalm": "^4.22" + "doctrine/coding-standard": "^12", + "phpstan/phpstan": "^2", + "phpunit/phpunit": "^10.5.38 || ^11" }, "type": "symfony-bundle", "autoload": { "psr-4": { - "Doctrine\\Bundle\\FixturesBundle\\": "" + "Doctrine\\Bundle\\FixturesBundle\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -10408,7 +10760,7 @@ ], "support": { "issues": "https://github.com/doctrine/DoctrineFixturesBundle/issues", - "source": "https://github.com/doctrine/DoctrineFixturesBundle/tree/3.4.2" + "source": "https://github.com/doctrine/DoctrineFixturesBundle/tree/4.0.0" }, "funding": [ { @@ -10424,56 +10776,169 @@ "type": "tidelift" } ], - "time": "2022-04-28T17:58:29+00:00" + "time": "2024-12-05T18:35:55+00:00" + }, + { + "name": "evenement/evenement", + "version": "v3.0.2", + "source": { + "type": "git", + "url": "https://github.com/igorw/evenement.git", + "reference": "0a16b0d71ab13284339abb99d9d2bd813640efbc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/igorw/evenement/zipball/0a16b0d71ab13284339abb99d9d2bd813640efbc", + "reference": "0a16b0d71ab13284339abb99d9d2bd813640efbc", + "shasum": "" + }, + "require": { + "php": ">=7.0" + }, + "require-dev": { + "phpunit/phpunit": "^9 || ^6" + }, + "type": "library", + "autoload": { + "psr-4": { + "Evenement\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Igor Wiedler", + "email": "igor@wiedler.ch" + } + ], + "description": "Événement is a very simple event dispatching library for PHP", + "keywords": [ + "event-dispatcher", + "event-emitter" + ], + "support": { + "issues": "https://github.com/igorw/evenement/issues", + "source": "https://github.com/igorw/evenement/tree/v3.0.2" + }, + "time": "2023-08-08T05:53:35+00:00" + }, + { + "name": "fidry/cpu-core-counter", + "version": "1.2.0", + "source": { + "type": "git", + "url": "https://github.com/theofidry/cpu-core-counter.git", + "reference": "8520451a140d3f46ac33042715115e290cf5785f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theofidry/cpu-core-counter/zipball/8520451a140d3f46ac33042715115e290cf5785f", + "reference": "8520451a140d3f46ac33042715115e290cf5785f", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "require-dev": { + "fidry/makefile": "^0.2.0", + "fidry/php-cs-fixer-config": "^1.1.2", + "phpstan/extension-installer": "^1.2.0", + "phpstan/phpstan": "^1.9.2", + "phpstan/phpstan-deprecation-rules": "^1.0.0", + "phpstan/phpstan-phpunit": "^1.2.2", + "phpstan/phpstan-strict-rules": "^1.4.4", + "phpunit/phpunit": "^8.5.31 || ^9.5.26", + "webmozarts/strict-phpunit": "^7.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "Fidry\\CpuCoreCounter\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Théo FIDRY", + "email": "theo.fidry@gmail.com" + } + ], + "description": "Tiny utility to get the number of CPU cores.", + "keywords": [ + "CPU", + "core" + ], + "support": { + "issues": "https://github.com/theofidry/cpu-core-counter/issues", + "source": "https://github.com/theofidry/cpu-core-counter/tree/1.2.0" + }, + "funding": [ + { + "url": "https://github.com/theofidry", + "type": "github" + } + ], + "time": "2024-08-06T10:04:20+00:00" }, { "name": "friendsofphp/php-cs-fixer", - "version": "v3.11.0", + "version": "v3.68.5", "source": { "type": "git", - "url": "https://github.com/FriendsOfPHP/PHP-CS-Fixer.git", - "reference": "7dcdea3f2f5f473464e835be9be55283ff8cfdc3" + "url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git", + "reference": "7bedb718b633355272428c60736dc97fb96daf27" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/7dcdea3f2f5f473464e835be9be55283ff8cfdc3", - "reference": "7dcdea3f2f5f473464e835be9be55283ff8cfdc3", + "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/7bedb718b633355272428c60736dc97fb96daf27", + "reference": "7bedb718b633355272428c60736dc97fb96daf27", "shasum": "" }, "require": { - "composer/semver": "^3.2", + "clue/ndjson-react": "^1.0", + "composer/semver": "^3.4", "composer/xdebug-handler": "^3.0.3", - "doctrine/annotations": "^1.13", + "ext-filter": "*", "ext-json": "*", "ext-tokenizer": "*", + "fidry/cpu-core-counter": "^1.2", "php": "^7.4 || ^8.0", - "sebastian/diff": "^4.0", - "symfony/console": "^5.4 || ^6.0", - "symfony/event-dispatcher": "^5.4 || ^6.0", - "symfony/filesystem": "^5.4 || ^6.0", - "symfony/finder": "^5.4 || ^6.0", - "symfony/options-resolver": "^5.4 || ^6.0", - "symfony/polyfill-mbstring": "^1.23", - "symfony/polyfill-php80": "^1.25", - "symfony/polyfill-php81": "^1.25", - "symfony/process": "^5.4 || ^6.0", - "symfony/stopwatch": "^5.4 || ^6.0" - }, - "require-dev": { - "justinrainbow/json-schema": "^5.2", - "keradus/cli-executor": "^1.5", - "mikey179/vfsstream": "^1.6.10", - "php-coveralls/php-coveralls": "^2.5.2", + "react/child-process": "^0.6.5", + "react/event-loop": "^1.0", + "react/promise": "^2.0 || ^3.0", + "react/socket": "^1.0", + "react/stream": "^1.0", + "sebastian/diff": "^4.0 || ^5.1 || ^6.0", + "symfony/console": "^5.4 || ^6.4 || ^7.0", + "symfony/event-dispatcher": "^5.4 || ^6.4 || ^7.0", + "symfony/filesystem": "^5.4 || ^6.4 || ^7.0", + "symfony/finder": "^5.4 || ^6.4 || ^7.0", + "symfony/options-resolver": "^5.4 || ^6.4 || ^7.0", + "symfony/polyfill-mbstring": "^1.31", + "symfony/polyfill-php80": "^1.31", + "symfony/polyfill-php81": "^1.31", + "symfony/process": "^5.4 || ^6.4 || ^7.2", + "symfony/stopwatch": "^5.4 || ^6.4 || ^7.0" + }, + "require-dev": { + "facile-it/paraunit": "^1.3.1 || ^2.4", + "infection/infection": "^0.29.8", + "justinrainbow/json-schema": "^5.3 || ^6.0", + "keradus/cli-executor": "^2.1", + "mikey179/vfsstream": "^1.6.12", + "php-coveralls/php-coveralls": "^2.7", "php-cs-fixer/accessible-object": "^1.1", - "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.2", - "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.2.1", - "phpspec/prophecy": "^1.15", - "phpspec/prophecy-phpunit": "^2.0", - "phpunit/phpunit": "^9.5", - "phpunitgoodpractices/polyfill": "^1.5", - "phpunitgoodpractices/traits": "^1.9.1", - "symfony/phpunit-bridge": "^6.0", - "symfony/yaml": "^5.4 || ^6.0" + "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.5", + "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.5", + "phpunit/phpunit": "^9.6.22 || ^10.5.40 || ^11.5.2", + "symfony/var-dumper": "^5.4.48 || ^6.4.15 || ^7.2.0", + "symfony/yaml": "^5.4.45 || ^6.4.13 || ^7.2.0" }, "suggest": { "ext-dom": "For handling output formats in XML", @@ -10486,7 +10951,10 @@ "autoload": { "psr-4": { "PhpCsFixer\\": "src/" - } + }, + "exclude-from-classmap": [ + "src/Fixer/Internal/*" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -10503,9 +10971,15 @@ } ], "description": "A tool to automatically fix PHP code style", + "keywords": [ + "Static code analysis", + "fixer", + "standards", + "static analysis" + ], "support": { - "issues": "https://github.com/FriendsOfPHP/PHP-CS-Fixer/issues", - "source": "https://github.com/FriendsOfPHP/PHP-CS-Fixer/tree/v3.11.0" + "issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues", + "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.68.5" }, "funding": [ { @@ -10513,20 +10987,20 @@ "type": "github" } ], - "time": "2022-09-01T18:24:51+00:00" + "time": "2025-01-30T17:00:50+00:00" }, { "name": "league/container", - "version": "4.2.0", + "version": "4.2.4", "source": { "type": "git", "url": "https://github.com/thephpleague/container.git", - "reference": "375d13cb828649599ef5d48a339c4af7a26cd0ab" + "reference": "7ea728b013b9a156c409c6f0fc3624071b742dec" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/container/zipball/375d13cb828649599ef5d48a339c4af7a26cd0ab", - "reference": "375d13cb828649599ef5d48a339c4af7a26cd0ab", + "url": "https://api.github.com/repos/thephpleague/container/zipball/7ea728b013b9a156c409c6f0fc3624071b742dec", + "reference": "7ea728b013b9a156c409c6f0fc3624071b742dec", "shasum": "" }, "require": { @@ -10551,11 +11025,11 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.x-dev", - "dev-4.x": "4.x-dev", - "dev-3.x": "3.x-dev", + "dev-1.x": "1.x-dev", "dev-2.x": "2.x-dev", - "dev-1.x": "1.x-dev" + "dev-3.x": "3.x-dev", + "dev-4.x": "4.x-dev", + "dev-master": "4.x-dev" } }, "autoload": { @@ -10587,7 +11061,7 @@ ], "support": { "issues": "https://github.com/thephpleague/container/issues", - "source": "https://github.com/thephpleague/container/tree/4.2.0" + "source": "https://github.com/thephpleague/container/tree/4.2.4" }, "funding": [ { @@ -10595,30 +11069,28 @@ "type": "github" } ], - "time": "2021-11-16T10:29:06+00:00" + "time": "2024-11-10T12:42:13+00:00" }, { "name": "masterminds/html5", - "version": "2.7.6", + "version": "2.9.0", "source": { "type": "git", "url": "https://github.com/Masterminds/html5-php.git", - "reference": "897eb517a343a2281f11bc5556d6548db7d93947" + "reference": "f5ac2c0b0a2eefca70b2ce32a5809992227e75a6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Masterminds/html5-php/zipball/897eb517a343a2281f11bc5556d6548db7d93947", - "reference": "897eb517a343a2281f11bc5556d6548db7d93947", + "url": "https://api.github.com/repos/Masterminds/html5-php/zipball/f5ac2c0b0a2eefca70b2ce32a5809992227e75a6", + "reference": "f5ac2c0b0a2eefca70b2ce32a5809992227e75a6", "shasum": "" }, "require": { - "ext-ctype": "*", "ext-dom": "*", - "ext-libxml": "*", "php": ">=5.3.0" }, "require-dev": { - "phpunit/phpunit": "^4.8.35 || ^5.7.21 || ^6 || ^7" + "phpunit/phpunit": "^4.8.35 || ^5.7.21 || ^6 || ^7 || ^8 || ^9" }, "type": "library", "extra": { @@ -10662,22 +11134,22 @@ ], "support": { "issues": "https://github.com/Masterminds/html5-php/issues", - "source": "https://github.com/Masterminds/html5-php/tree/2.7.6" + "source": "https://github.com/Masterminds/html5-php/tree/2.9.0" }, - "time": "2022-08-18T16:18:26+00:00" + "time": "2024-03-31T07:05:07+00:00" }, { "name": "myclabs/deep-copy", - "version": "1.11.0", + "version": "1.12.1", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614" + "reference": "123267b2c49fbf30d78a7b2d333f6be754b94845" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/14daed4296fae74d9e3201d2c4925d1acb7aa614", - "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/123267b2c49fbf30d78a7b2d333f6be754b94845", + "reference": "123267b2c49fbf30d78a7b2d333f6be754b94845", "shasum": "" }, "require": { @@ -10685,11 +11157,12 @@ }, "conflict": { "doctrine/collections": "<1.6.8", - "doctrine/common": "<2.13.3 || >=3,<3.2.2" + "doctrine/common": "<2.13.3 || >=3 <3.2.2" }, "require-dev": { "doctrine/collections": "^1.6.8", "doctrine/common": "^2.13.3 || ^3.2.2", + "phpspec/prophecy": "^1.10", "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" }, "type": "library", @@ -10715,7 +11188,7 @@ ], "support": { "issues": "https://github.com/myclabs/DeepCopy/issues", - "source": "https://github.com/myclabs/DeepCopy/tree/1.11.0" + "source": "https://github.com/myclabs/DeepCopy/tree/1.12.1" }, "funding": [ { @@ -10723,111 +11196,55 @@ "type": "tidelift" } ], - "time": "2022-03-03T13:19:32+00:00" - }, - { - "name": "nikic/php-parser", - "version": "v4.15.1", - "source": { - "type": "git", - "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "0ef6c55a3f47f89d7a374e6f835197a0b5fcf900" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/0ef6c55a3f47f89d7a374e6f835197a0b5fcf900", - "reference": "0ef6c55a3f47f89d7a374e6f835197a0b5fcf900", - "shasum": "" - }, - "require": { - "ext-tokenizer": "*", - "php": ">=7.0" - }, - "require-dev": { - "ircmaxell/php-yacc": "^0.0.7", - "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0" - }, - "bin": [ - "bin/php-parse" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.9-dev" - } - }, - "autoload": { - "psr-4": { - "PhpParser\\": "lib/PhpParser" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Nikita Popov" - } - ], - "description": "A PHP parser written in PHP", - "keywords": [ - "parser", - "php" - ], - "support": { - "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v4.15.1" - }, - "time": "2022-09-04T07:30:47+00:00" + "time": "2024-11-08T17:47:46+00:00" }, { "name": "nunomaduro/phpinsights", - "version": "v2.6.0", + "version": "v2.12.0", "source": { "type": "git", "url": "https://github.com/nunomaduro/phpinsights.git", - "reference": "4d00775737cf91bea3ddc327f349238762c784a2" + "reference": "5c12a8d626712de6db5e6d2db52b1eb4e9596650" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nunomaduro/phpinsights/zipball/4d00775737cf91bea3ddc327f349238762c784a2", - "reference": "4d00775737cf91bea3ddc327f349238762c784a2", + "url": "https://api.github.com/repos/nunomaduro/phpinsights/zipball/5c12a8d626712de6db5e6d2db52b1eb4e9596650", + "reference": "5c12a8d626712de6db5e6d2db52b1eb4e9596650", "shasum": "" }, "require": { - "composer/semver": "^3.3", + "cmgmyr/phploc": "^8.0.3", + "composer/semver": "^3.4", "ext-iconv": "*", "ext-json": "*", "ext-mbstring": "*", "ext-tokenizer": "*", - "friendsofphp/php-cs-fixer": "^3.0.0", - "justinrainbow/json-schema": "^5.1", + "friendsofphp/php-cs-fixer": "^3.40.0", + "justinrainbow/json-schema": "^5.2.13", "league/container": "^3.2|^4.2", - "php": "^7.4 || ^8.0", - "php-parallel-lint/php-parallel-lint": "^1.3", - "phploc/phploc": "^5.0|^6.0|^7.0", - "psr/container": "^1.0|^2.0", + "php": "^7.4|^8.0", + "php-parallel-lint/php-parallel-lint": "^1.3.2", + "psr/container": "^1.0|^2.0.2", "psr/simple-cache": "^1.0|^2.0|^3.0", - "sebastian/diff": "^4.0", - "slevomat/coding-standard": "^7.0.8", - "squizlabs/php_codesniffer": "^3.5", - "symfony/cache": "^4.4|^5.0|^6.0", - "symfony/console": "^4.2|^5.0|^6.0", - "symfony/finder": "^4.2|^5.0|^6.0", - "symfony/http-client": "^4.3|^5.0|^6.0", - "symfony/process": "^5.4|^6.0" - }, - "require-dev": { - "ergebnis/phpstan-rules": "^0.15.0", - "illuminate/console": "^5.8|^6.0|^7.0|^8.0|^9.0", - "illuminate/support": "^5.8|^6.0|^7.0|^8.0|^9.0", - "mockery/mockery": "^1.0", - "phpstan/phpstan-strict-rules": "^0.12", - "phpunit/phpunit": "^8.0|^9.0", + "sebastian/diff": "^4.0|^5.0.3|^6.0", + "slevomat/coding-standard": "^8.14.1", + "squizlabs/php_codesniffer": "^3.7.2", + "symfony/cache": "^5.4|^6.0|^7.0", + "symfony/console": "^5.4|^6.4|^7.0", + "symfony/finder": "^5.4|^6.0|^7.0", + "symfony/http-client": "^5.4|^6.0|^7.0", + "symfony/process": "^5.4|^6.4|^7.0" + }, + "require-dev": { + "ergebnis/phpstan-rules": "^0.15.3", + "illuminate/console": "^5.8|^6.0|^7.0|^8.0|^9.20|^10.0", + "illuminate/support": "^5.8|^6.0|^7.0|^8.0|^9.52.16|^10.0", + "mockery/mockery": "^1.6.6", + "phpstan/phpstan-strict-rules": "^0.12.11", + "phpunit/phpunit": "^8.0|^9.0|^10.4.2", "rector/rector": "0.11.56", - "symfony/var-dumper": "^4.2|^5.0|^6.0", - "thecodingmachine/phpstan-strict-rules": "^0.12.0" + "symfony/var-dumper": "^5.4|^6.0|^7.0", + "thecodingmachine/phpstan-strict-rules": "^0.12.2" }, "suggest": { "ext-simplexml": "It is needed for the checkstyle formatter" @@ -10869,7 +11286,7 @@ ], "support": { "issues": "https://github.com/nunomaduro/phpinsights/issues", - "source": "https://github.com/nunomaduro/phpinsights/tree/v2.6.0" + "source": "https://github.com/nunomaduro/phpinsights/tree/v2.12.0" }, "funding": [ { @@ -10885,24 +11302,25 @@ "type": "github" } ], - "time": "2022-09-07T17:38:54+00:00" + "time": "2024-11-11T14:42:55+00:00" }, { "name": "phar-io/manifest", - "version": "2.0.3", + "version": "2.0.4", "source": { "type": "git", "url": "https://github.com/phar-io/manifest.git", - "reference": "97803eca37d319dfa7826cc2437fc020857acb53" + "reference": "54750ef60c58e43759730615a392c31c80e23176" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phar-io/manifest/zipball/97803eca37d319dfa7826cc2437fc020857acb53", - "reference": "97803eca37d319dfa7826cc2437fc020857acb53", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/54750ef60c58e43759730615a392c31c80e23176", + "reference": "54750ef60c58e43759730615a392c31c80e23176", "shasum": "" }, "require": { "ext-dom": "*", + "ext-libxml": "*", "ext-phar": "*", "ext-xmlwriter": "*", "phar-io/version": "^3.0.1", @@ -10943,9 +11361,15 @@ "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", "support": { "issues": "https://github.com/phar-io/manifest/issues", - "source": "https://github.com/phar-io/manifest/tree/2.0.3" + "source": "https://github.com/phar-io/manifest/tree/2.0.4" }, - "time": "2021-07-20T11:28:43+00:00" + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2024-03-03T12:33:53+00:00" }, { "name": "phar-io/version", @@ -11000,16 +11424,16 @@ }, { "name": "php-parallel-lint/php-parallel-lint", - "version": "v1.3.2", + "version": "v1.4.0", "source": { "type": "git", "url": "https://github.com/php-parallel-lint/PHP-Parallel-Lint.git", - "reference": "6483c9832e71973ed29cf71bd6b3f4fde438a9de" + "reference": "6db563514f27e19595a19f45a4bf757b6401194e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-parallel-lint/PHP-Parallel-Lint/zipball/6483c9832e71973ed29cf71bd6b3f4fde438a9de", - "reference": "6483c9832e71973ed29cf71bd6b3f4fde438a9de", + "url": "https://api.github.com/repos/php-parallel-lint/PHP-Parallel-Lint/zipball/6db563514f27e19595a19f45a4bf757b6401194e", + "reference": "6db563514f27e19595a19f45a4bf757b6401194e", "shasum": "" }, "require": { @@ -11047,136 +11471,34 @@ "email": "ahoj@jakubonderka.cz" } ], - "description": "This tool check syntax of PHP files about 20x faster than serial check.", + "description": "This tool checks the syntax of PHP files about 20x faster than serial check.", "homepage": "https://github.com/php-parallel-lint/PHP-Parallel-Lint", - "support": { - "issues": "https://github.com/php-parallel-lint/PHP-Parallel-Lint/issues", - "source": "https://github.com/php-parallel-lint/PHP-Parallel-Lint/tree/v1.3.2" - }, - "time": "2022-02-21T12:50:22+00:00" - }, - { - "name": "phploc/phploc", - "version": "7.0.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/phploc.git", - "reference": "af0d5fc84f3f7725513ba59cdcbe670ac2a4532a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phploc/zipball/af0d5fc84f3f7725513ba59cdcbe670ac2a4532a", - "reference": "af0d5fc84f3f7725513ba59cdcbe670ac2a4532a", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-json": "*", - "php": ">=7.3", - "phpunit/php-file-iterator": "^3.0", - "sebastian/cli-parser": "^1.0", - "sebastian/version": "^3.0" - }, - "bin": [ - "phploc" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "7.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "A tool for quickly measuring the size of a PHP project.", - "homepage": "https://github.com/sebastianbergmann/phploc", - "support": { - "issues": "https://github.com/sebastianbergmann/phploc/issues", - "source": "https://github.com/sebastianbergmann/phploc/tree/7.0.2" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-12-07T05:51:20+00:00" - }, - { - "name": "phpstan/phpdoc-parser", - "version": "1.8.0", - "source": { - "type": "git", - "url": "https://github.com/phpstan/phpdoc-parser.git", - "reference": "8dd908dd6156e974b9a0f8bb4cd5ad0707830f04" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/8dd908dd6156e974b9a0f8bb4cd5ad0707830f04", - "reference": "8dd908dd6156e974b9a0f8bb4cd5ad0707830f04", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0" - }, - "require-dev": { - "php-parallel-lint/php-parallel-lint": "^1.2", - "phpstan/extension-installer": "^1.0", - "phpstan/phpstan": "^1.5", - "phpstan/phpstan-phpunit": "^1.1", - "phpstan/phpstan-strict-rules": "^1.0", - "phpunit/phpunit": "^9.5", - "symfony/process": "^5.2" - }, - "type": "library", - "autoload": { - "psr-4": { - "PHPStan\\PhpDocParser\\": [ - "src/" - ] - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" + "keywords": [ + "lint", + "static analysis" ], - "description": "PHPDoc parser with support for nullable, intersection and generic types", "support": { - "issues": "https://github.com/phpstan/phpdoc-parser/issues", - "source": "https://github.com/phpstan/phpdoc-parser/tree/1.8.0" + "issues": "https://github.com/php-parallel-lint/PHP-Parallel-Lint/issues", + "source": "https://github.com/php-parallel-lint/PHP-Parallel-Lint/tree/v1.4.0" }, - "time": "2022-09-04T18:59:06+00:00" + "time": "2024-03-27T12:14:49+00:00" }, { "name": "phpstan/phpstan", - "version": "1.8.5", + "version": "2.1.2", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "f6598a5ff12ca4499a836815e08b4d77a2ddeb20" + "reference": "7d08f569e582ade182a375c366cbd896eccadd3a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/f6598a5ff12ca4499a836815e08b4d77a2ddeb20", - "reference": "f6598a5ff12ca4499a836815e08b4d77a2ddeb20", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/7d08f569e582ade182a375c366cbd896eccadd3a", + "reference": "7d08f569e582ade182a375c366cbd896eccadd3a", "shasum": "" }, "require": { - "php": "^7.2|^8.0" + "php": "^7.4|^8.0" }, "conflict": { "phpstan/phpstan-shim": "*" @@ -11201,8 +11523,11 @@ "static analysis" ], "support": { + "docs": "https://phpstan.org/user-guide/getting-started", + "forum": "https://github.com/phpstan/phpstan/discussions", "issues": "https://github.com/phpstan/phpstan/issues", - "source": "https://github.com/phpstan/phpstan/tree/1.8.5" + "security": "https://github.com/phpstan/phpstan/security/policy", + "source": "https://github.com/phpstan/phpstan-src" }, "funding": [ { @@ -11212,54 +11537,50 @@ { "url": "https://github.com/phpstan", "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/phpstan/phpstan", - "type": "tidelift" } ], - "time": "2022-09-07T16:05:32+00:00" + "time": "2025-01-21T14:54:06+00:00" }, { "name": "phpunit/php-code-coverage", - "version": "9.2.17", + "version": "11.0.8", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "aa94dc41e8661fe90c7316849907cba3007b10d8" + "reference": "418c59fd080954f8c4aa5631d9502ecda2387118" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/aa94dc41e8661fe90c7316849907cba3007b10d8", - "reference": "aa94dc41e8661fe90c7316849907cba3007b10d8", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/418c59fd080954f8c4aa5631d9502ecda2387118", + "reference": "418c59fd080954f8c4aa5631d9502ecda2387118", "shasum": "" }, "require": { "ext-dom": "*", "ext-libxml": "*", "ext-xmlwriter": "*", - "nikic/php-parser": "^4.14", - "php": ">=7.3", - "phpunit/php-file-iterator": "^3.0.3", - "phpunit/php-text-template": "^2.0.2", - "sebastian/code-unit-reverse-lookup": "^2.0.2", - "sebastian/complexity": "^2.0", - "sebastian/environment": "^5.1.2", - "sebastian/lines-of-code": "^1.0.3", - "sebastian/version": "^3.0.1", - "theseer/tokenizer": "^1.2.0" + "nikic/php-parser": "^5.3.1", + "php": ">=8.2", + "phpunit/php-file-iterator": "^5.1.0", + "phpunit/php-text-template": "^4.0.1", + "sebastian/code-unit-reverse-lookup": "^4.0.1", + "sebastian/complexity": "^4.0.1", + "sebastian/environment": "^7.2.0", + "sebastian/lines-of-code": "^3.0.1", + "sebastian/version": "^5.0.2", + "theseer/tokenizer": "^1.2.3" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^11.5.0" }, "suggest": { - "ext-pcov": "*", - "ext-xdebug": "*" + "ext-pcov": "PHP extension that provides line coverage", + "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "9.2-dev" + "dev-main": "11.0.x-dev" } }, "autoload": { @@ -11287,7 +11608,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.17" + "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/11.0.8" }, "funding": [ { @@ -11295,32 +11617,32 @@ "type": "github" } ], - "time": "2022-08-30T12:24:04+00:00" + "time": "2024-12-11T12:34:27+00:00" }, { "name": "phpunit/php-file-iterator", - "version": "3.0.6", + "version": "5.1.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf" + "reference": "118cfaaa8bc5aef3287bf315b6060b1174754af6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", - "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/118cfaaa8bc5aef3287bf315b6060b1174754af6", + "reference": "118cfaaa8bc5aef3287bf315b6060b1174754af6", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-main": "5.0-dev" } }, "autoload": { @@ -11347,7 +11669,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", - "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.6" + "security": "https://github.com/sebastianbergmann/php-file-iterator/security/policy", + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/5.1.0" }, "funding": [ { @@ -11355,28 +11678,28 @@ "type": "github" } ], - "time": "2021-12-02T12:48:52+00:00" + "time": "2024-08-27T05:02:59+00:00" }, { "name": "phpunit/php-invoker", - "version": "3.1.1", + "version": "5.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-invoker.git", - "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67" + "reference": "c1ca3814734c07492b3d4c5f794f4b0995333da2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/5a10147d0aaf65b58940a0b72f71c9ac0423cc67", - "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67", + "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/c1ca3814734c07492b3d4c5f794f4b0995333da2", + "reference": "c1ca3814734c07492b3d4c5f794f4b0995333da2", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.2" }, "require-dev": { "ext-pcntl": "*", - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^11.0" }, "suggest": { "ext-pcntl": "*" @@ -11384,7 +11707,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.1-dev" + "dev-main": "5.0-dev" } }, "autoload": { @@ -11410,7 +11733,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-invoker/issues", - "source": "https://github.com/sebastianbergmann/php-invoker/tree/3.1.1" + "security": "https://github.com/sebastianbergmann/php-invoker/security/policy", + "source": "https://github.com/sebastianbergmann/php-invoker/tree/5.0.1" }, "funding": [ { @@ -11418,32 +11742,32 @@ "type": "github" } ], - "time": "2020-09-28T05:58:55+00:00" + "time": "2024-07-03T05:07:44+00:00" }, { "name": "phpunit/php-text-template", - "version": "2.0.4", + "version": "4.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28" + "reference": "3e0404dc6b300e6bf56415467ebcb3fe4f33e964" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", - "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/3e0404dc6b300e6bf56415467ebcb3fe4f33e964", + "reference": "3e0404dc6b300e6bf56415467ebcb3fe4f33e964", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0-dev" + "dev-main": "4.0-dev" } }, "autoload": { @@ -11469,7 +11793,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-text-template/issues", - "source": "https://github.com/sebastianbergmann/php-text-template/tree/2.0.4" + "security": "https://github.com/sebastianbergmann/php-text-template/security/policy", + "source": "https://github.com/sebastianbergmann/php-text-template/tree/4.0.1" }, "funding": [ { @@ -11477,32 +11802,32 @@ "type": "github" } ], - "time": "2020-10-26T05:33:50+00:00" + "time": "2024-07-03T05:08:43+00:00" }, { "name": "phpunit/php-timer", - "version": "5.0.3", + "version": "7.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2" + "reference": "3b415def83fbcb41f991d9ebf16ae4ad8b7837b3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", - "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3b415def83fbcb41f991d9ebf16ae4ad8b7837b3", + "reference": "3b415def83fbcb41f991d9ebf16ae4ad8b7837b3", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "5.0-dev" + "dev-main": "7.0-dev" } }, "autoload": { @@ -11528,7 +11853,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-timer/issues", - "source": "https://github.com/sebastianbergmann/php-timer/tree/5.0.3" + "security": "https://github.com/sebastianbergmann/php-timer/security/policy", + "source": "https://github.com/sebastianbergmann/php-timer/tree/7.0.1" }, "funding": [ { @@ -11536,54 +11862,52 @@ "type": "github" } ], - "time": "2020-10-26T13:16:10+00:00" + "time": "2024-07-03T05:09:35+00:00" }, { "name": "phpunit/phpunit", - "version": "9.5.24", + "version": "11.5.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "d0aa6097bef9fd42458a9b3c49da32c6ce6129c5" + "reference": "b9a975972f580c0491f834eb0818ad2b32fd8bba" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/d0aa6097bef9fd42458a9b3c49da32c6ce6129c5", - "reference": "d0aa6097bef9fd42458a9b3c49da32c6ce6129c5", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/b9a975972f580c0491f834eb0818ad2b32fd8bba", + "reference": "b9a975972f580c0491f834eb0818ad2b32fd8bba", "shasum": "" }, "require": { - "doctrine/instantiator": "^1.3.1", "ext-dom": "*", "ext-json": "*", "ext-libxml": "*", "ext-mbstring": "*", "ext-xml": "*", "ext-xmlwriter": "*", - "myclabs/deep-copy": "^1.10.1", - "phar-io/manifest": "^2.0.3", - "phar-io/version": "^3.0.2", - "php": ">=7.3", - "phpunit/php-code-coverage": "^9.2.13", - "phpunit/php-file-iterator": "^3.0.5", - "phpunit/php-invoker": "^3.1.1", - "phpunit/php-text-template": "^2.0.3", - "phpunit/php-timer": "^5.0.2", - "sebastian/cli-parser": "^1.0.1", - "sebastian/code-unit": "^1.0.6", - "sebastian/comparator": "^4.0.5", - "sebastian/diff": "^4.0.3", - "sebastian/environment": "^5.1.3", - "sebastian/exporter": "^4.0.3", - "sebastian/global-state": "^5.0.1", - "sebastian/object-enumerator": "^4.0.3", - "sebastian/resource-operations": "^3.0.3", - "sebastian/type": "^3.1", - "sebastian/version": "^3.0.2" + "myclabs/deep-copy": "^1.12.1", + "phar-io/manifest": "^2.0.4", + "phar-io/version": "^3.2.1", + "php": ">=8.2", + "phpunit/php-code-coverage": "^11.0.8", + "phpunit/php-file-iterator": "^5.1.0", + "phpunit/php-invoker": "^5.0.1", + "phpunit/php-text-template": "^4.0.1", + "phpunit/php-timer": "^7.0.1", + "sebastian/cli-parser": "^3.0.2", + "sebastian/code-unit": "^3.0.2", + "sebastian/comparator": "^6.3.0", + "sebastian/diff": "^6.0.2", + "sebastian/environment": "^7.2.0", + "sebastian/exporter": "^6.3.0", + "sebastian/global-state": "^7.0.2", + "sebastian/object-enumerator": "^6.0.1", + "sebastian/type": "^5.1.0", + "sebastian/version": "^5.0.2", + "staabm/side-effects-detector": "^1.0.5" }, "suggest": { - "ext-soap": "*", - "ext-xdebug": "*" + "ext-soap": "To be able to generate mocks based on WSDL files" }, "bin": [ "phpunit" @@ -11591,77 +11915,509 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "9.5-dev" + "dev-main": "11.5-dev" + } + }, + "autoload": { + "files": [ + "src/Framework/Assert/Functions.php" + ], + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/phpunit/issues", + "security": "https://github.com/sebastianbergmann/phpunit/security/policy", + "source": "https://github.com/sebastianbergmann/phpunit/tree/11.5.5" + }, + "funding": [ + { + "url": "https://phpunit.de/sponsors.html", + "type": "custom" + }, + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit", + "type": "tidelift" + } + ], + "time": "2025-01-29T14:01:11+00:00" + }, + { + "name": "psr/simple-cache", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/simple-cache.git", + "reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/764e0b3939f5ca87cb904f570ef9be2d78a07865", + "reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\SimpleCache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interfaces for simple caching", + "keywords": [ + "cache", + "caching", + "psr", + "psr-16", + "simple-cache" + ], + "support": { + "source": "https://github.com/php-fig/simple-cache/tree/3.0.0" + }, + "time": "2021-10-29T13:26:27+00:00" + }, + { + "name": "react/cache", + "version": "v1.2.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/cache.git", + "reference": "d47c472b64aa5608225f47965a484b75c7817d5b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/cache/zipball/d47c472b64aa5608225f47965a484b75c7817d5b", + "reference": "d47c472b64aa5608225f47965a484b75c7817d5b", + "shasum": "" + }, + "require": { + "php": ">=5.3.0", + "react/promise": "^3.0 || ^2.0 || ^1.1" + }, + "require-dev": { + "phpunit/phpunit": "^9.5 || ^5.7 || ^4.8.35" + }, + "type": "library", + "autoload": { + "psr-4": { + "React\\Cache\\": "src/" } }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" + } + ], + "description": "Async, Promise-based cache interface for ReactPHP", + "keywords": [ + "cache", + "caching", + "promise", + "reactphp" + ], + "support": { + "issues": "https://github.com/reactphp/cache/issues", + "source": "https://github.com/reactphp/cache/tree/v1.2.0" + }, + "funding": [ + { + "url": "https://opencollective.com/reactphp", + "type": "open_collective" + } + ], + "time": "2022-11-30T15:59:55+00:00" + }, + { + "name": "react/child-process", + "version": "v0.6.6", + "source": { + "type": "git", + "url": "https://github.com/reactphp/child-process.git", + "reference": "1721e2b93d89b745664353b9cfc8f155ba8a6159" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/child-process/zipball/1721e2b93d89b745664353b9cfc8f155ba8a6159", + "reference": "1721e2b93d89b745664353b9cfc8f155ba8a6159", + "shasum": "" + }, + "require": { + "evenement/evenement": "^3.0 || ^2.0 || ^1.0", + "php": ">=5.3.0", + "react/event-loop": "^1.2", + "react/stream": "^1.4" + }, + "require-dev": { + "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36", + "react/socket": "^1.16", + "sebastian/environment": "^5.0 || ^3.0 || ^2.0 || ^1.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "React\\ChildProcess\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" + } + ], + "description": "Event-driven library for executing child processes with ReactPHP.", + "keywords": [ + "event-driven", + "process", + "reactphp" + ], + "support": { + "issues": "https://github.com/reactphp/child-process/issues", + "source": "https://github.com/reactphp/child-process/tree/v0.6.6" + }, + "funding": [ + { + "url": "https://opencollective.com/reactphp", + "type": "open_collective" + } + ], + "time": "2025-01-01T16:37:48+00:00" + }, + { + "name": "react/dns", + "version": "v1.13.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/dns.git", + "reference": "eb8ae001b5a455665c89c1df97f6fb682f8fb0f5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/dns/zipball/eb8ae001b5a455665c89c1df97f6fb682f8fb0f5", + "reference": "eb8ae001b5a455665c89c1df97f6fb682f8fb0f5", + "shasum": "" + }, + "require": { + "php": ">=5.3.0", + "react/cache": "^1.0 || ^0.6 || ^0.5", + "react/event-loop": "^1.2", + "react/promise": "^3.2 || ^2.7 || ^1.2.1" + }, + "require-dev": { + "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36", + "react/async": "^4.3 || ^3 || ^2", + "react/promise-timer": "^1.11" + }, + "type": "library", + "autoload": { + "psr-4": { + "React\\Dns\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" + } + ], + "description": "Async DNS resolver for ReactPHP", + "keywords": [ + "async", + "dns", + "dns-resolver", + "reactphp" + ], + "support": { + "issues": "https://github.com/reactphp/dns/issues", + "source": "https://github.com/reactphp/dns/tree/v1.13.0" + }, + "funding": [ + { + "url": "https://opencollective.com/reactphp", + "type": "open_collective" + } + ], + "time": "2024-06-13T14:18:03+00:00" + }, + { + "name": "react/event-loop", + "version": "v1.5.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/event-loop.git", + "reference": "bbe0bd8c51ffc05ee43f1729087ed3bdf7d53354" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/event-loop/zipball/bbe0bd8c51ffc05ee43f1729087ed3bdf7d53354", + "reference": "bbe0bd8c51ffc05ee43f1729087ed3bdf7d53354", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36" + }, + "suggest": { + "ext-pcntl": "For signal handling support when using the StreamSelectLoop" + }, + "type": "library", + "autoload": { + "psr-4": { + "React\\EventLoop\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" + } + ], + "description": "ReactPHP's core reactor event loop that libraries can use for evented I/O.", + "keywords": [ + "asynchronous", + "event-loop" + ], + "support": { + "issues": "https://github.com/reactphp/event-loop/issues", + "source": "https://github.com/reactphp/event-loop/tree/v1.5.0" + }, + "funding": [ + { + "url": "https://opencollective.com/reactphp", + "type": "open_collective" + } + ], + "time": "2023-11-13T13:48:05+00:00" + }, + { + "name": "react/socket", + "version": "v1.16.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/socket.git", + "reference": "23e4ff33ea3e160d2d1f59a0e6050e4b0fb0eac1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/socket/zipball/23e4ff33ea3e160d2d1f59a0e6050e4b0fb0eac1", + "reference": "23e4ff33ea3e160d2d1f59a0e6050e4b0fb0eac1", + "shasum": "" + }, + "require": { + "evenement/evenement": "^3.0 || ^2.0 || ^1.0", + "php": ">=5.3.0", + "react/dns": "^1.13", + "react/event-loop": "^1.2", + "react/promise": "^3.2 || ^2.6 || ^1.2.1", + "react/stream": "^1.4" + }, + "require-dev": { + "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36", + "react/async": "^4.3 || ^3.3 || ^2", + "react/promise-stream": "^1.4", + "react/promise-timer": "^1.11" + }, + "type": "library", "autoload": { - "files": [ - "src/Framework/Assert/Functions.php" - ], - "classmap": [ - "src/" - ] + "psr-4": { + "React\\Socket\\": "src/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" } ], - "description": "The PHP Unit Testing framework.", - "homepage": "https://phpunit.de/", + "description": "Async, streaming plaintext TCP/IP and secure TLS socket server and client connections for ReactPHP", "keywords": [ - "phpunit", - "testing", - "xunit" + "Connection", + "Socket", + "async", + "reactphp", + "stream" ], "support": { - "issues": "https://github.com/sebastianbergmann/phpunit/issues", - "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.24" + "issues": "https://github.com/reactphp/socket/issues", + "source": "https://github.com/reactphp/socket/tree/v1.16.0" }, "funding": [ { - "url": "https://phpunit.de/sponsors.html", - "type": "custom" - }, - { - "url": "https://github.com/sebastianbergmann", - "type": "github" + "url": "https://opencollective.com/reactphp", + "type": "open_collective" } ], - "time": "2022-08-30T07:42:16+00:00" + "time": "2024-07-26T10:38:09+00:00" }, { - "name": "psr/simple-cache", - "version": "3.0.0", + "name": "react/stream", + "version": "v1.4.0", "source": { "type": "git", - "url": "https://github.com/php-fig/simple-cache.git", - "reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865" + "url": "https://github.com/reactphp/stream.git", + "reference": "1e5b0acb8fe55143b5b426817155190eb6f5b18d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/764e0b3939f5ca87cb904f570ef9be2d78a07865", - "reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865", + "url": "https://api.github.com/repos/reactphp/stream/zipball/1e5b0acb8fe55143b5b426817155190eb6f5b18d", + "reference": "1e5b0acb8fe55143b5b426817155190eb6f5b18d", "shasum": "" }, "require": { - "php": ">=8.0.0" + "evenement/evenement": "^3.0 || ^2.0 || ^1.0", + "php": ">=5.3.8", + "react/event-loop": "^1.2" }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0.x-dev" - } + "require-dev": { + "clue/stream-filter": "~1.2", + "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36" }, + "type": "library", "autoload": { "psr-4": { - "Psr\\SimpleCache\\": "src/" + "React\\Stream\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -11670,59 +12426,80 @@ ], "authors": [ { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" } ], - "description": "Common interfaces for simple caching", + "description": "Event-driven readable and writable streams for non-blocking I/O in ReactPHP", "keywords": [ - "cache", - "caching", - "psr", - "psr-16", - "simple-cache" + "event-driven", + "io", + "non-blocking", + "pipe", + "reactphp", + "readable", + "stream", + "writable" ], "support": { - "source": "https://github.com/php-fig/simple-cache/tree/3.0.0" + "issues": "https://github.com/reactphp/stream/issues", + "source": "https://github.com/reactphp/stream/tree/v1.4.0" }, - "time": "2021-10-29T13:26:27+00:00" + "funding": [ + { + "url": "https://opencollective.com/reactphp", + "type": "open_collective" + } + ], + "time": "2024-06-11T12:45:25+00:00" }, { "name": "rector/rector", - "version": "0.14.2", + "version": "2.0.7", "source": { "type": "git", "url": "https://github.com/rectorphp/rector.git", - "reference": "55915c3dea8ea39ee8ad6964b2bf2b5226d47131" + "reference": "e70d681f6a0c361a63e6825897cd97746436f015" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/rectorphp/rector/zipball/55915c3dea8ea39ee8ad6964b2bf2b5226d47131", - "reference": "55915c3dea8ea39ee8ad6964b2bf2b5226d47131", + "url": "https://api.github.com/repos/rectorphp/rector/zipball/e70d681f6a0c361a63e6825897cd97746436f015", + "reference": "e70d681f6a0c361a63e6825897cd97746436f015", "shasum": "" }, "require": { - "php": "^7.2|^8.0", - "phpstan/phpstan": "^1.8.3" + "php": "^7.4|^8.0", + "phpstan/phpstan": "^2.1.1" }, "conflict": { - "phpstan/phpdoc-parser": "<1.7", - "rector/rector-cakephp": "*", "rector/rector-doctrine": "*", - "rector/rector-laravel": "*", - "rector/rector-phpoffice": "*", + "rector/rector-downgrade-php": "*", "rector/rector-phpunit": "*", "rector/rector-symfony": "*" }, + "suggest": { + "ext-dom": "To manipulate phpunit.xml via the custom-rule command" + }, "bin": [ "bin/rector" ], "type": "library", - "extra": { - "branch-alias": { - "dev-main": "0.14-dev" - } - }, "autoload": { "files": [ "bootstrap.php" @@ -11733,9 +12510,15 @@ "MIT" ], "description": "Instant Upgrade and Automated Refactoring of any PHP code", + "keywords": [ + "automation", + "dev", + "migration", + "refactoring" + ], "support": { "issues": "https://github.com/rectorphp/rector/issues", - "source": "https://github.com/rectorphp/rector/tree/0.14.2" + "source": "https://github.com/rectorphp/rector/tree/2.0.7" }, "funding": [ { @@ -11743,32 +12526,32 @@ "type": "github" } ], - "time": "2022-09-04T16:13:03+00:00" + "time": "2025-01-19T09:41:28+00:00" }, { "name": "sebastian/cli-parser", - "version": "1.0.1", + "version": "3.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/cli-parser.git", - "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2" + "reference": "15c5dd40dc4f38794d383bb95465193f5e0ae180" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/442e7c7e687e42adc03470c7b668bc4b2402c0b2", - "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2", + "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/15c5dd40dc4f38794d383bb95465193f5e0ae180", + "reference": "15c5dd40dc4f38794d383bb95465193f5e0ae180", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0-dev" + "dev-main": "3.0-dev" } }, "autoload": { @@ -11791,7 +12574,8 @@ "homepage": "https://github.com/sebastianbergmann/cli-parser", "support": { "issues": "https://github.com/sebastianbergmann/cli-parser/issues", - "source": "https://github.com/sebastianbergmann/cli-parser/tree/1.0.1" + "security": "https://github.com/sebastianbergmann/cli-parser/security/policy", + "source": "https://github.com/sebastianbergmann/cli-parser/tree/3.0.2" }, "funding": [ { @@ -11799,32 +12583,32 @@ "type": "github" } ], - "time": "2020-09-28T06:08:49+00:00" + "time": "2024-07-03T04:41:36+00:00" }, { "name": "sebastian/code-unit", - "version": "1.0.8", + "version": "3.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/code-unit.git", - "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120" + "reference": "ee88b0cdbe74cf8dd3b54940ff17643c0d6543ca" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/1fc9f64c0927627ef78ba436c9b17d967e68e120", - "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/ee88b0cdbe74cf8dd3b54940ff17643c0d6543ca", + "reference": "ee88b0cdbe74cf8dd3b54940ff17643c0d6543ca", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^11.5" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0-dev" + "dev-main": "3.0-dev" } }, "autoload": { @@ -11847,7 +12631,8 @@ "homepage": "https://github.com/sebastianbergmann/code-unit", "support": { "issues": "https://github.com/sebastianbergmann/code-unit/issues", - "source": "https://github.com/sebastianbergmann/code-unit/tree/1.0.8" + "security": "https://github.com/sebastianbergmann/code-unit/security/policy", + "source": "https://github.com/sebastianbergmann/code-unit/tree/3.0.2" }, "funding": [ { @@ -11855,32 +12640,32 @@ "type": "github" } ], - "time": "2020-10-26T13:08:54+00:00" + "time": "2024-12-12T09:59:06+00:00" }, { "name": "sebastian/code-unit-reverse-lookup", - "version": "2.0.3", + "version": "4.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", - "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5" + "reference": "183a9b2632194febd219bb9246eee421dad8d45e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", - "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/183a9b2632194febd219bb9246eee421dad8d45e", + "reference": "183a9b2632194febd219bb9246eee421dad8d45e", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0-dev" + "dev-main": "4.0-dev" } }, "autoload": { @@ -11902,7 +12687,8 @@ "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", "support": { "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", - "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/2.0.3" + "security": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/security/policy", + "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/4.0.1" }, "funding": [ { @@ -11910,34 +12696,39 @@ "type": "github" } ], - "time": "2020-09-28T05:30:19+00:00" + "time": "2024-07-03T04:45:54+00:00" }, { "name": "sebastian/comparator", - "version": "4.0.6", + "version": "6.3.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "55f4261989e546dc112258c7a75935a81a7ce382" + "reference": "d4e47a769525c4dd38cea90e5dcd435ddbbc7115" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/55f4261989e546dc112258c7a75935a81a7ce382", - "reference": "55f4261989e546dc112258c7a75935a81a7ce382", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/d4e47a769525c4dd38cea90e5dcd435ddbbc7115", + "reference": "d4e47a769525c4dd38cea90e5dcd435ddbbc7115", "shasum": "" }, "require": { - "php": ">=7.3", - "sebastian/diff": "^4.0", - "sebastian/exporter": "^4.0" + "ext-dom": "*", + "ext-mbstring": "*", + "php": ">=8.2", + "sebastian/diff": "^6.0", + "sebastian/exporter": "^6.0" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^11.4" + }, + "suggest": { + "ext-bcmath": "For comparing BcMath\\Number objects" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0-dev" + "dev-main": "6.2-dev" } }, "autoload": { @@ -11976,7 +12767,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/comparator/issues", - "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.6" + "security": "https://github.com/sebastianbergmann/comparator/security/policy", + "source": "https://github.com/sebastianbergmann/comparator/tree/6.3.0" }, "funding": [ { @@ -11984,33 +12776,33 @@ "type": "github" } ], - "time": "2020-10-26T15:49:45+00:00" + "time": "2025-01-06T10:28:19+00:00" }, { "name": "sebastian/complexity", - "version": "2.0.2", + "version": "4.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/complexity.git", - "reference": "739b35e53379900cc9ac327b2147867b8b6efd88" + "reference": "ee41d384ab1906c68852636b6de493846e13e5a0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/739b35e53379900cc9ac327b2147867b8b6efd88", - "reference": "739b35e53379900cc9ac327b2147867b8b6efd88", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/ee41d384ab1906c68852636b6de493846e13e5a0", + "reference": "ee41d384ab1906c68852636b6de493846e13e5a0", "shasum": "" }, "require": { - "nikic/php-parser": "^4.7", - "php": ">=7.3" + "nikic/php-parser": "^5.0", + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0-dev" + "dev-main": "4.0-dev" } }, "autoload": { @@ -12033,7 +12825,8 @@ "homepage": "https://github.com/sebastianbergmann/complexity", "support": { "issues": "https://github.com/sebastianbergmann/complexity/issues", - "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.2" + "security": "https://github.com/sebastianbergmann/complexity/security/policy", + "source": "https://github.com/sebastianbergmann/complexity/tree/4.0.1" }, "funding": [ { @@ -12041,33 +12834,33 @@ "type": "github" } ], - "time": "2020-10-26T15:52:27+00:00" + "time": "2024-07-03T04:49:50+00:00" }, { "name": "sebastian/diff", - "version": "4.0.4", + "version": "6.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d" + "reference": "b4ccd857127db5d41a5b676f24b51371d76d8544" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/3461e3fccc7cfdfc2720be910d3bd73c69be590d", - "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/b4ccd857127db5d41a5b676f24b51371d76d8544", + "reference": "b4ccd857127db5d41a5b676f24b51371d76d8544", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^9.3", + "phpunit/phpunit": "^11.0", "symfony/process": "^4.2 || ^5" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0-dev" + "dev-main": "6.0-dev" } }, "autoload": { @@ -12099,7 +12892,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/diff/issues", - "source": "https://github.com/sebastianbergmann/diff/tree/4.0.4" + "security": "https://github.com/sebastianbergmann/diff/security/policy", + "source": "https://github.com/sebastianbergmann/diff/tree/6.0.2" }, "funding": [ { @@ -12107,27 +12901,27 @@ "type": "github" } ], - "time": "2020-10-26T13:10:38+00:00" + "time": "2024-07-03T04:53:05+00:00" }, { "name": "sebastian/environment", - "version": "5.1.4", + "version": "7.2.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "1b5dff7bb151a4db11d49d90e5408e4e938270f7" + "reference": "855f3ae0ab316bbafe1ba4e16e9f3c078d24a0c5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/1b5dff7bb151a4db11d49d90e5408e4e938270f7", - "reference": "1b5dff7bb151a4db11d49d90e5408e4e938270f7", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/855f3ae0ab316bbafe1ba4e16e9f3c078d24a0c5", + "reference": "855f3ae0ab316bbafe1ba4e16e9f3c078d24a0c5", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^11.0" }, "suggest": { "ext-posix": "*" @@ -12135,7 +12929,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "5.1-dev" + "dev-main": "7.2-dev" } }, "autoload": { @@ -12154,7 +12948,7 @@ } ], "description": "Provides functionality to handle HHVM/PHP environments", - "homepage": "http://www.github.com/sebastianbergmann/environment", + "homepage": "https://github.com/sebastianbergmann/environment", "keywords": [ "Xdebug", "environment", @@ -12162,7 +12956,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/environment/issues", - "source": "https://github.com/sebastianbergmann/environment/tree/5.1.4" + "security": "https://github.com/sebastianbergmann/environment/security/policy", + "source": "https://github.com/sebastianbergmann/environment/tree/7.2.0" }, "funding": [ { @@ -12170,34 +12965,34 @@ "type": "github" } ], - "time": "2022-04-03T09:37:03+00:00" + "time": "2024-07-03T04:54:44+00:00" }, { "name": "sebastian/exporter", - "version": "4.0.4", + "version": "6.3.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "65e8b7db476c5dd267e65eea9cab77584d3cfff9" + "reference": "3473f61172093b2da7de1fb5782e1f24cc036dc3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/65e8b7db476c5dd267e65eea9cab77584d3cfff9", - "reference": "65e8b7db476c5dd267e65eea9cab77584d3cfff9", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/3473f61172093b2da7de1fb5782e1f24cc036dc3", + "reference": "3473f61172093b2da7de1fb5782e1f24cc036dc3", "shasum": "" }, "require": { - "php": ">=7.3", - "sebastian/recursion-context": "^4.0" + "ext-mbstring": "*", + "php": ">=8.2", + "sebastian/recursion-context": "^6.0" }, "require-dev": { - "ext-mbstring": "*", - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^11.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0-dev" + "dev-main": "6.1-dev" } }, "autoload": { @@ -12239,7 +13034,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/exporter/issues", - "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.4" + "security": "https://github.com/sebastianbergmann/exporter/security/policy", + "source": "https://github.com/sebastianbergmann/exporter/tree/6.3.0" }, "funding": [ { @@ -12247,38 +13043,35 @@ "type": "github" } ], - "time": "2021-11-11T14:18:36+00:00" + "time": "2024-12-05T09:17:50+00:00" }, { "name": "sebastian/global-state", - "version": "5.0.5", + "version": "7.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2" + "reference": "3be331570a721f9a4b5917f4209773de17f747d7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/0ca8db5a5fc9c8646244e629625ac486fa286bf2", - "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/3be331570a721f9a4b5917f4209773de17f747d7", + "reference": "3be331570a721f9a4b5917f4209773de17f747d7", "shasum": "" }, "require": { - "php": ">=7.3", - "sebastian/object-reflector": "^2.0", - "sebastian/recursion-context": "^4.0" + "php": ">=8.2", + "sebastian/object-reflector": "^4.0", + "sebastian/recursion-context": "^6.0" }, "require-dev": { "ext-dom": "*", - "phpunit/phpunit": "^9.3" - }, - "suggest": { - "ext-uopz": "*" + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "5.0-dev" + "dev-main": "7.0-dev" } }, "autoload": { @@ -12297,13 +13090,14 @@ } ], "description": "Snapshotting of global state", - "homepage": "http://www.github.com/sebastianbergmann/global-state", + "homepage": "https://www.github.com/sebastianbergmann/global-state", "keywords": [ "global state" ], "support": { "issues": "https://github.com/sebastianbergmann/global-state/issues", - "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.5" + "security": "https://github.com/sebastianbergmann/global-state/security/policy", + "source": "https://github.com/sebastianbergmann/global-state/tree/7.0.2" }, "funding": [ { @@ -12311,33 +13105,33 @@ "type": "github" } ], - "time": "2022-02-14T08:28:10+00:00" + "time": "2024-07-03T04:57:36+00:00" }, { "name": "sebastian/lines-of-code", - "version": "1.0.3", + "version": "3.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/lines-of-code.git", - "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc" + "reference": "d36ad0d782e5756913e42ad87cb2890f4ffe467a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/c1c2e997aa3146983ed888ad08b15470a2e22ecc", - "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/d36ad0d782e5756913e42ad87cb2890f4ffe467a", + "reference": "d36ad0d782e5756913e42ad87cb2890f4ffe467a", "shasum": "" }, "require": { - "nikic/php-parser": "^4.6", - "php": ">=7.3" + "nikic/php-parser": "^5.0", + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0-dev" + "dev-main": "3.0-dev" } }, "autoload": { @@ -12360,7 +13154,8 @@ "homepage": "https://github.com/sebastianbergmann/lines-of-code", "support": { "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", - "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.3" + "security": "https://github.com/sebastianbergmann/lines-of-code/security/policy", + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/3.0.1" }, "funding": [ { @@ -12368,34 +13163,34 @@ "type": "github" } ], - "time": "2020-11-28T06:42:11+00:00" + "time": "2024-07-03T04:58:38+00:00" }, { "name": "sebastian/object-enumerator", - "version": "4.0.4", + "version": "6.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-enumerator.git", - "reference": "5c9eeac41b290a3712d88851518825ad78f45c71" + "reference": "f5b498e631a74204185071eb41f33f38d64608aa" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/5c9eeac41b290a3712d88851518825ad78f45c71", - "reference": "5c9eeac41b290a3712d88851518825ad78f45c71", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/f5b498e631a74204185071eb41f33f38d64608aa", + "reference": "f5b498e631a74204185071eb41f33f38d64608aa", "shasum": "" }, "require": { - "php": ">=7.3", - "sebastian/object-reflector": "^2.0", - "sebastian/recursion-context": "^4.0" + "php": ">=8.2", + "sebastian/object-reflector": "^4.0", + "sebastian/recursion-context": "^6.0" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0-dev" + "dev-main": "6.0-dev" } }, "autoload": { @@ -12417,7 +13212,8 @@ "homepage": "https://github.com/sebastianbergmann/object-enumerator/", "support": { "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", - "source": "https://github.com/sebastianbergmann/object-enumerator/tree/4.0.4" + "security": "https://github.com/sebastianbergmann/object-enumerator/security/policy", + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/6.0.1" }, "funding": [ { @@ -12425,32 +13221,32 @@ "type": "github" } ], - "time": "2020-10-26T13:12:34+00:00" + "time": "2024-07-03T05:00:13+00:00" }, { "name": "sebastian/object-reflector", - "version": "2.0.4", + "version": "4.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-reflector.git", - "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7" + "reference": "6e1a43b411b2ad34146dee7524cb13a068bb35f9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", - "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/6e1a43b411b2ad34146dee7524cb13a068bb35f9", + "reference": "6e1a43b411b2ad34146dee7524cb13a068bb35f9", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0-dev" + "dev-main": "4.0-dev" } }, "autoload": { @@ -12472,7 +13268,8 @@ "homepage": "https://github.com/sebastianbergmann/object-reflector/", "support": { "issues": "https://github.com/sebastianbergmann/object-reflector/issues", - "source": "https://github.com/sebastianbergmann/object-reflector/tree/2.0.4" + "security": "https://github.com/sebastianbergmann/object-reflector/security/policy", + "source": "https://github.com/sebastianbergmann/object-reflector/tree/4.0.1" }, "funding": [ { @@ -12480,32 +13277,32 @@ "type": "github" } ], - "time": "2020-10-26T13:14:26+00:00" + "time": "2024-07-03T05:01:32+00:00" }, { "name": "sebastian/recursion-context", - "version": "4.0.4", + "version": "6.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172" + "reference": "694d156164372abbd149a4b85ccda2e4670c0e16" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/cd9d8cf3c5804de4341c283ed787f099f5506172", - "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/694d156164372abbd149a4b85ccda2e4670c0e16", + "reference": "694d156164372abbd149a4b85ccda2e4670c0e16", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0-dev" + "dev-main": "6.0-dev" } }, "autoload": { @@ -12532,65 +13329,11 @@ } ], "description": "Provides functionality to recursively process PHP variables", - "homepage": "http://www.github.com/sebastianbergmann/recursion-context", + "homepage": "https://github.com/sebastianbergmann/recursion-context", "support": { "issues": "https://github.com/sebastianbergmann/recursion-context/issues", - "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.4" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T13:17:30+00:00" - }, - { - "name": "sebastian/resource-operations", - "version": "3.0.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/resource-operations.git", - "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", - "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Provides a list of PHP built-in functions that operate on resources", - "homepage": "https://www.github.com/sebastianbergmann/resource-operations", - "support": { - "issues": "https://github.com/sebastianbergmann/resource-operations/issues", - "source": "https://github.com/sebastianbergmann/resource-operations/tree/3.0.3" + "security": "https://github.com/sebastianbergmann/recursion-context/security/policy", + "source": "https://github.com/sebastianbergmann/recursion-context/tree/6.0.2" }, "funding": [ { @@ -12598,32 +13341,32 @@ "type": "github" } ], - "time": "2020-09-28T06:45:17+00:00" + "time": "2024-07-03T05:10:34+00:00" }, { "name": "sebastian/type", - "version": "3.1.0", + "version": "5.1.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/type.git", - "reference": "fb44e1cc6e557418387ad815780360057e40753e" + "reference": "461b9c5da241511a2a0e8f240814fb23ce5c0aac" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/fb44e1cc6e557418387ad815780360057e40753e", - "reference": "fb44e1cc6e557418387ad815780360057e40753e", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/461b9c5da241511a2a0e8f240814fb23ce5c0aac", + "reference": "461b9c5da241511a2a0e8f240814fb23ce5c0aac", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^9.5" + "phpunit/phpunit": "^11.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.1-dev" + "dev-main": "5.1-dev" } }, "autoload": { @@ -12646,7 +13389,8 @@ "homepage": "https://github.com/sebastianbergmann/type", "support": { "issues": "https://github.com/sebastianbergmann/type/issues", - "source": "https://github.com/sebastianbergmann/type/tree/3.1.0" + "security": "https://github.com/sebastianbergmann/type/security/policy", + "source": "https://github.com/sebastianbergmann/type/tree/5.1.0" }, "funding": [ { @@ -12654,29 +13398,29 @@ "type": "github" } ], - "time": "2022-08-29T06:55:37+00:00" + "time": "2024-09-17T13:12:04+00:00" }, { "name": "sebastian/version", - "version": "3.0.2", + "version": "5.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/version.git", - "reference": "c6c1022351a901512170118436c764e473f6de8c" + "reference": "c687e3387b99f5b03b6caa64c74b63e2936ff874" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c6c1022351a901512170118436c764e473f6de8c", - "reference": "c6c1022351a901512170118436c764e473f6de8c", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c687e3387b99f5b03b6caa64c74b63e2936ff874", + "reference": "c687e3387b99f5b03b6caa64c74b63e2936ff874", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.2" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-main": "5.0-dev" } }, "autoload": { @@ -12699,7 +13443,8 @@ "homepage": "https://github.com/sebastianbergmann/version", "support": { "issues": "https://github.com/sebastianbergmann/version/issues", - "source": "https://github.com/sebastianbergmann/version/tree/3.0.2" + "security": "https://github.com/sebastianbergmann/version/security/policy", + "source": "https://github.com/sebastianbergmann/version/tree/5.0.2" }, "funding": [ { @@ -12707,46 +13452,46 @@ "type": "github" } ], - "time": "2020-09-28T06:39:44+00:00" + "time": "2024-10-09T05:16:32+00:00" }, { "name": "slevomat/coding-standard", - "version": "7.2.1", + "version": "8.15.0", "source": { "type": "git", "url": "https://github.com/slevomat/coding-standard.git", - "reference": "aff06ae7a84e4534bf6f821dc982a93a5d477c90" + "reference": "7d1d957421618a3803b593ec31ace470177d7817" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/slevomat/coding-standard/zipball/aff06ae7a84e4534bf6f821dc982a93a5d477c90", - "reference": "aff06ae7a84e4534bf6f821dc982a93a5d477c90", + "url": "https://api.github.com/repos/slevomat/coding-standard/zipball/7d1d957421618a3803b593ec31ace470177d7817", + "reference": "7d1d957421618a3803b593ec31ace470177d7817", "shasum": "" }, "require": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.6.2 || ^0.7", + "dealerdirect/phpcodesniffer-composer-installer": "^0.6.2 || ^0.7 || ^1.0", "php": "^7.2 || ^8.0", - "phpstan/phpdoc-parser": "^1.5.1", - "squizlabs/php_codesniffer": "^3.6.2" + "phpstan/phpdoc-parser": "^1.23.1", + "squizlabs/php_codesniffer": "^3.9.0" }, "require-dev": { - "phing/phing": "2.17.3", + "phing/phing": "2.17.4", "php-parallel-lint/php-parallel-lint": "1.3.2", - "phpstan/phpstan": "1.4.10|1.7.1", - "phpstan/phpstan-deprecation-rules": "1.0.0", - "phpstan/phpstan-phpunit": "1.0.0|1.1.1", - "phpstan/phpstan-strict-rules": "1.2.3", - "phpunit/phpunit": "7.5.20|8.5.21|9.5.20" + "phpstan/phpstan": "1.10.60", + "phpstan/phpstan-deprecation-rules": "1.1.4", + "phpstan/phpstan-phpunit": "1.3.16", + "phpstan/phpstan-strict-rules": "1.5.2", + "phpunit/phpunit": "8.5.21|9.6.8|10.5.11" }, "type": "phpcodesniffer-standard", "extra": { "branch-alias": { - "dev-master": "7.x-dev" + "dev-master": "8.x-dev" } }, "autoload": { "psr-4": { - "SlevomatCodingStandard\\": "SlevomatCodingStandard" + "SlevomatCodingStandard\\": "SlevomatCodingStandard/" } }, "notification-url": "https://packagist.org/downloads/", @@ -12754,9 +13499,13 @@ "MIT" ], "description": "Slevomat Coding Standard for PHP_CodeSniffer complements Consistence Coding Standard by providing sniffs with additional checks.", + "keywords": [ + "dev", + "phpcs" + ], "support": { "issues": "https://github.com/slevomat/coding-standard/issues", - "source": "https://github.com/slevomat/coding-standard/tree/7.2.1" + "source": "https://github.com/slevomat/coding-standard/tree/8.15.0" }, "funding": [ { @@ -12768,20 +13517,20 @@ "type": "tidelift" } ], - "time": "2022-05-25T10:58:12+00:00" + "time": "2024-03-09T15:20:58+00:00" }, { "name": "squizlabs/php_codesniffer", - "version": "3.7.1", + "version": "3.11.3", "source": { "type": "git", - "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", - "reference": "1359e176e9307e906dc3d890bcc9603ff6d90619" + "url": "https://github.com/PHPCSStandards/PHP_CodeSniffer.git", + "reference": "ba05f990e79cbe69b9f35c8c1ac8dca7eecc3a10" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/1359e176e9307e906dc3d890bcc9603ff6d90619", - "reference": "1359e176e9307e906dc3d890bcc9603ff6d90619", + "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/ba05f990e79cbe69b9f35c8c1ac8dca7eecc3a10", + "reference": "ba05f990e79cbe69b9f35c8c1ac8dca7eecc3a10", "shasum": "" }, "require": { @@ -12791,11 +13540,11 @@ "php": ">=5.4.0" }, "require-dev": { - "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0" + "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0 || ^8.0 || ^9.3.4" }, "bin": [ - "bin/phpcs", - "bin/phpcbf" + "bin/phpcbf", + "bin/phpcs" ], "type": "library", "extra": { @@ -12810,34 +13559,114 @@ "authors": [ { "name": "Greg Sherwood", - "role": "lead" + "role": "Former lead" + }, + { + "name": "Juliette Reinders Folmer", + "role": "Current lead" + }, + { + "name": "Contributors", + "homepage": "https://github.com/PHPCSStandards/PHP_CodeSniffer/graphs/contributors" } ], "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", - "homepage": "https://github.com/squizlabs/PHP_CodeSniffer", + "homepage": "https://github.com/PHPCSStandards/PHP_CodeSniffer", "keywords": [ "phpcs", - "standards" + "standards", + "static analysis" + ], + "support": { + "issues": "https://github.com/PHPCSStandards/PHP_CodeSniffer/issues", + "security": "https://github.com/PHPCSStandards/PHP_CodeSniffer/security/policy", + "source": "https://github.com/PHPCSStandards/PHP_CodeSniffer", + "wiki": "https://github.com/PHPCSStandards/PHP_CodeSniffer/wiki" + }, + "funding": [ + { + "url": "https://github.com/PHPCSStandards", + "type": "github" + }, + { + "url": "https://github.com/jrfnl", + "type": "github" + }, + { + "url": "https://opencollective.com/php_codesniffer", + "type": "open_collective" + }, + { + "url": "https://thanks.dev/phpcsstandards", + "type": "thanks_dev" + } + ], + "time": "2025-01-23T17:04:15+00:00" + }, + { + "name": "staabm/side-effects-detector", + "version": "1.0.5", + "source": { + "type": "git", + "url": "https://github.com/staabm/side-effects-detector.git", + "reference": "d8334211a140ce329c13726d4a715adbddd0a163" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/staabm/side-effects-detector/zipball/d8334211a140ce329c13726d4a715adbddd0a163", + "reference": "d8334211a140ce329c13726d4a715adbddd0a163", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "phpstan/extension-installer": "^1.4.3", + "phpstan/phpstan": "^1.12.6", + "phpunit/phpunit": "^9.6.21", + "symfony/var-dumper": "^5.4.43", + "tomasvotruba/type-coverage": "1.0.0", + "tomasvotruba/unused-public": "1.0.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "lib/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A static analysis tool to detect side effects in PHP code", + "keywords": [ + "static analysis" ], "support": { - "issues": "https://github.com/squizlabs/PHP_CodeSniffer/issues", - "source": "https://github.com/squizlabs/PHP_CodeSniffer", - "wiki": "https://github.com/squizlabs/PHP_CodeSniffer/wiki" + "issues": "https://github.com/staabm/side-effects-detector/issues", + "source": "https://github.com/staabm/side-effects-detector/tree/1.0.5" }, - "time": "2022-06-18T07:21:10+00:00" + "funding": [ + { + "url": "https://github.com/staabm", + "type": "github" + } + ], + "time": "2024-10-20T05:08:20+00:00" }, { "name": "swoole/ide-helper", - "version": "5.0.0", + "version": "6.0.0", "source": { "type": "git", "url": "https://github.com/swoole/ide-helper.git", - "reference": "939352ede9e8cddce96897d18b4fbd0c1e2110a3" + "reference": "86a61562a1f1634339ee52f3b8988591f51a2799" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/swoole/ide-helper/zipball/939352ede9e8cddce96897d18b4fbd0c1e2110a3", - "reference": "939352ede9e8cddce96897d18b4fbd0c1e2110a3", + "url": "https://api.github.com/repos/swoole/ide-helper/zipball/86a61562a1f1634339ee52f3b8988591f51a2799", + "reference": "86a61562a1f1634339ee52f3b8988591f51a2799", "shasum": "" }, "type": "library", @@ -12854,46 +13683,33 @@ "description": "IDE help files for Swoole.", "support": { "issues": "https://github.com/swoole/ide-helper/issues", - "source": "https://github.com/swoole/ide-helper/tree/5.0.0" + "source": "https://github.com/swoole/ide-helper/tree/6.0.0" }, - "funding": [ - { - "url": "https://gitee.com/swoole/swoole?donate=true", - "type": "custom" - }, - { - "url": "https://github.com/swoole", - "type": "github" - } - ], - "time": "2022-08-10T05:32:06+00:00" + "time": "2025-01-03T19:08:24+00:00" }, { "name": "symfony/browser-kit", - "version": "v6.1.3", + "version": "v7.2.0", "source": { "type": "git", "url": "https://github.com/symfony/browser-kit.git", - "reference": "2e3b6a4406c2af963c634d7bd0457402b67dcc56" + "reference": "8d64d17e198082f8f198d023a6b634e7b5fdda94" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/browser-kit/zipball/2e3b6a4406c2af963c634d7bd0457402b67dcc56", - "reference": "2e3b6a4406c2af963c634d7bd0457402b67dcc56", + "url": "https://api.github.com/repos/symfony/browser-kit/zipball/8d64d17e198082f8f198d023a6b634e7b5fdda94", + "reference": "8d64d17e198082f8f198d023a6b634e7b5fdda94", "shasum": "" }, "require": { - "php": ">=8.1", - "symfony/dom-crawler": "^5.4|^6.0" + "php": ">=8.2", + "symfony/dom-crawler": "^6.4|^7.0" }, "require-dev": { - "symfony/css-selector": "^5.4|^6.0", - "symfony/http-client": "^5.4|^6.0", - "symfony/mime": "^5.4|^6.0", - "symfony/process": "^5.4|^6.0" - }, - "suggest": { - "symfony/process": "" + "symfony/css-selector": "^6.4|^7.0", + "symfony/http-client": "^6.4|^7.0", + "symfony/mime": "^6.4|^7.0", + "symfony/process": "^6.4|^7.0" }, "type": "library", "autoload": { @@ -12921,7 +13737,7 @@ "description": "Simulates the behavior of a web browser, allowing you to make requests, click on links and submit forms programmatically", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/browser-kit/tree/v6.1.3" + "source": "https://github.com/symfony/browser-kit/tree/v7.2.0" }, "funding": [ { @@ -12937,24 +13753,24 @@ "type": "tidelift" } ], - "time": "2022-07-27T15:50:51+00:00" + "time": "2024-10-25T15:15:23+00:00" }, { "name": "symfony/css-selector", - "version": "v6.1.3", + "version": "v7.2.0", "source": { "type": "git", "url": "https://github.com/symfony/css-selector.git", - "reference": "0dd5e36b80e1de97f8f74ed7023ac2b837a36443" + "reference": "601a5ce9aaad7bf10797e3663faefce9e26c24e2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/css-selector/zipball/0dd5e36b80e1de97f8f74ed7023ac2b837a36443", - "reference": "0dd5e36b80e1de97f8f74ed7023ac2b837a36443", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/601a5ce9aaad7bf10797e3663faefce9e26c24e2", + "reference": "601a5ce9aaad7bf10797e3663faefce9e26c24e2", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.2" }, "type": "library", "autoload": { @@ -12986,7 +13802,7 @@ "description": "Converts CSS selectors to XPath expressions", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/css-selector/tree/v6.1.3" + "source": "https://github.com/symfony/css-selector/tree/v7.2.0" }, "funding": [ { @@ -13002,41 +13818,37 @@ "type": "tidelift" } ], - "time": "2022-06-27T17:24:16+00:00" + "time": "2024-09-25T14:21:43+00:00" }, { "name": "symfony/debug-bundle", - "version": "v6.1.3", + "version": "v7.2.0", "source": { "type": "git", "url": "https://github.com/symfony/debug-bundle.git", - "reference": "4084f86639bf0270d6dd2225fc8d7c317780dd6b" + "reference": "2dade0d1415c08b627379b5ec214ec8424cb2e32" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/debug-bundle/zipball/4084f86639bf0270d6dd2225fc8d7c317780dd6b", - "reference": "4084f86639bf0270d6dd2225fc8d7c317780dd6b", + "url": "https://api.github.com/repos/symfony/debug-bundle/zipball/2dade0d1415c08b627379b5ec214ec8424cb2e32", + "reference": "2dade0d1415c08b627379b5ec214ec8424cb2e32", "shasum": "" }, "require": { "ext-xml": "*", - "php": ">=8.1", - "symfony/dependency-injection": "^5.4|^6.0", - "symfony/http-kernel": "^5.4|^6.0", - "symfony/twig-bridge": "^5.4|^6.0", - "symfony/var-dumper": "^5.4|^6.0" + "php": ">=8.2", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/twig-bridge": "^6.4|^7.0", + "symfony/var-dumper": "^6.4|^7.0" }, "conflict": { - "symfony/config": "<5.4", - "symfony/dependency-injection": "<5.4" + "symfony/config": "<6.4", + "symfony/dependency-injection": "<6.4" }, "require-dev": { - "symfony/config": "^5.4|^6.0", - "symfony/web-profiler-bundle": "^5.4|^6.0" - }, - "suggest": { - "symfony/config": "For service container configuration", - "symfony/dependency-injection": "For using as a service from the container" + "symfony/config": "^6.4|^7.0", + "symfony/web-profiler-bundle": "^6.4|^7.0" }, "type": "symfony-bundle", "autoload": { @@ -13064,7 +13876,7 @@ "description": "Provides a tight integration of the Symfony VarDumper component and the ServerLogCommand from MonologBridge into the Symfony full-stack framework", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/debug-bundle/tree/v6.1.3" + "source": "https://github.com/symfony/debug-bundle/tree/v7.2.0" }, "funding": [ { @@ -13080,33 +13892,30 @@ "type": "tidelift" } ], - "time": "2022-07-20T13:46:29+00:00" + "time": "2024-09-25T14:21:43+00:00" }, { "name": "symfony/dom-crawler", - "version": "v6.1.4", + "version": "v7.2.3", "source": { "type": "git", "url": "https://github.com/symfony/dom-crawler.git", - "reference": "8cb4c6e6c8d30c26f70529ed5e50d79a09576c0c" + "reference": "700a880e5089280c7cf3ca1ccf9d9de6630f5d25" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/8cb4c6e6c8d30c26f70529ed5e50d79a09576c0c", - "reference": "8cb4c6e6c8d30c26f70529ed5e50d79a09576c0c", + "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/700a880e5089280c7cf3ca1ccf9d9de6630f5d25", + "reference": "700a880e5089280c7cf3ca1ccf9d9de6630f5d25", "shasum": "" }, "require": { "masterminds/html5": "^2.6", - "php": ">=8.1", + "php": ">=8.2", "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-mbstring": "~1.0" }, "require-dev": { - "symfony/css-selector": "^5.4|^6.0" - }, - "suggest": { - "symfony/css-selector": "" + "symfony/css-selector": "^6.4|^7.0" }, "type": "library", "autoload": { @@ -13134,7 +13943,7 @@ "description": "Eases DOM navigation for HTML and XML documents", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/dom-crawler/tree/v6.1.4" + "source": "https://github.com/symfony/dom-crawler/tree/v7.2.3" }, "funding": [ { @@ -13150,56 +13959,54 @@ "type": "tidelift" } ], - "time": "2022-08-04T19:19:00+00:00" + "time": "2025-01-27T11:08:17+00:00" }, { "name": "symfony/maker-bundle", - "version": "v1.45.0", + "version": "v1.62.1", "source": { "type": "git", "url": "https://github.com/symfony/maker-bundle.git", - "reference": "7ae4ff28ac1b6d6d55591999026040d58b8a3967" + "reference": "468ff2708200c95ebc0d85d3174b6c6711b8a590" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/maker-bundle/zipball/7ae4ff28ac1b6d6d55591999026040d58b8a3967", - "reference": "7ae4ff28ac1b6d6d55591999026040d58b8a3967", + "url": "https://api.github.com/repos/symfony/maker-bundle/zipball/468ff2708200c95ebc0d85d3174b6c6711b8a590", + "reference": "468ff2708200c95ebc0d85d3174b6c6711b8a590", "shasum": "" }, "require": { "doctrine/inflector": "^2.0", - "nikic/php-parser": "^4.11", - "php": ">=8.0", - "symfony/config": "^5.4.7|^6.0", - "symfony/console": "^5.4.7|^6.0", - "symfony/dependency-injection": "^5.4.7|^6.0", + "nikic/php-parser": "^4.18|^5.0", + "php": ">=8.1", + "symfony/config": "^6.4|^7.0", + "symfony/console": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", "symfony/deprecation-contracts": "^2.2|^3", - "symfony/filesystem": "^5.4.7|^6.0", - "symfony/finder": "^5.4.3|^6.0", - "symfony/framework-bundle": "^5.4.7|^6.0", - "symfony/http-kernel": "^5.4.7|^6.0" + "symfony/filesystem": "^6.4|^7.0", + "symfony/finder": "^6.4|^7.0", + "symfony/framework-bundle": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/process": "^6.4|^7.0" }, "conflict": { - "doctrine/doctrine-bundle": "<2.4", - "doctrine/orm": "<2.10", - "symfony/doctrine-bridge": "<5.4" + "doctrine/doctrine-bundle": "<2.10", + "doctrine/orm": "<2.15" }, "require-dev": { "composer/semver": "^3.0", - "doctrine/doctrine-bundle": "^2.4", - "doctrine/orm": "^2.10.0", - "symfony/http-client": "^5.4.7|^6.0", - "symfony/phpunit-bridge": "^5.4.7|^6.0", - "symfony/polyfill-php80": "^1.16.0", - "symfony/process": "^5.4.7|^6.0", - "symfony/security-core": "^5.4.7|^6.0", - "symfony/yaml": "^5.4.3|^6.0", - "twig/twig": "^2.0|^3.0" + "doctrine/doctrine-bundle": "^2.5.0", + "doctrine/orm": "^2.15|^3", + "symfony/http-client": "^6.4|^7.0", + "symfony/phpunit-bridge": "^6.4.1|^7.0", + "symfony/security-core": "^6.4|^7.0", + "symfony/yaml": "^6.4|^7.0", + "twig/twig": "^3.0|^4.x-dev" }, "type": "symfony-bundle", "extra": { "branch-alias": { - "dev-main": "1.0-dev" + "dev-main": "1.x-dev" } }, "autoload": { @@ -13221,13 +14028,14 @@ "homepage": "https://symfony.com/doc/current/bundles/SymfonyMakerBundle/index.html", "keywords": [ "code generator", + "dev", "generator", "scaffold", "scaffolding" ], "support": { "issues": "https://github.com/symfony/maker-bundle/issues", - "source": "https://github.com/symfony/maker-bundle/tree/v1.45.0" + "source": "https://github.com/symfony/maker-bundle/tree/v1.62.1" }, "funding": [ { @@ -13243,34 +14051,32 @@ "type": "tidelift" } ], - "time": "2022-07-26T12:31:45+00:00" + "time": "2025-01-15T00:21:40+00:00" }, { "name": "symfony/phpunit-bridge", - "version": "v6.1.3", + "version": "v7.2.0", "source": { "type": "git", "url": "https://github.com/symfony/phpunit-bridge.git", - "reference": "75c2fa71d049c1f48e39d208c0cefba97e66335a" + "reference": "2bbde92ab25a0e2c88160857af7be9db5da0d145" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/phpunit-bridge/zipball/75c2fa71d049c1f48e39d208c0cefba97e66335a", - "reference": "75c2fa71d049c1f48e39d208c0cefba97e66335a", + "url": "https://api.github.com/repos/symfony/phpunit-bridge/zipball/2bbde92ab25a0e2c88160857af7be9db5da0d145", + "reference": "2bbde92ab25a0e2c88160857af7be9db5da0d145", "shasum": "" }, "require": { - "php": ">=7.1.3" + "php": ">=7.2.5" }, "conflict": { "phpunit/phpunit": "<7.5|9.1.2" }, "require-dev": { - "symfony/deprecation-contracts": "^2.1|^3.0", - "symfony/error-handler": "^5.4|^6.0" - }, - "suggest": { - "symfony/error-handler": "For tracking deprecated interfaces usages at runtime with DebugClassLoader" + "symfony/deprecation-contracts": "^2.5|^3.0", + "symfony/error-handler": "^5.4|^6.4|^7.0", + "symfony/polyfill-php81": "^1.27" }, "bin": [ "bin/simple-phpunit" @@ -13278,8 +14084,8 @@ "type": "symfony-bridge", "extra": { "thanks": { - "name": "phpunit/phpunit", - "url": "https://github.com/sebastianbergmann/phpunit" + "url": "https://github.com/sebastianbergmann/phpunit", + "name": "phpunit/phpunit" } }, "autoload": { @@ -13290,7 +14096,8 @@ "Symfony\\Bridge\\PhpUnit\\": "" }, "exclude-from-classmap": [ - "/Tests/" + "/Tests/", + "/bin/" ] }, "notification-url": "https://packagist.org/downloads/", @@ -13310,7 +14117,7 @@ "description": "Provides utilities for PHPUnit, especially user deprecation notices management", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/phpunit-bridge/tree/v6.1.3" + "source": "https://github.com/symfony/phpunit-bridge/tree/v7.2.0" }, "funding": [ { @@ -13326,25 +14133,25 @@ "type": "tidelift" } ], - "time": "2022-07-28T13:40:41+00:00" + "time": "2024-11-13T16:15:23+00:00" }, { "name": "symfony/stopwatch", - "version": "v6.1.0", + "version": "v7.2.2", "source": { "type": "git", "url": "https://github.com/symfony/stopwatch.git", - "reference": "77dedae82ce2a26e2e9b481855473fc3b3e4e54d" + "reference": "e46690d5b9d7164a6d061cab1e8d46141b9f49df" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/stopwatch/zipball/77dedae82ce2a26e2e9b481855473fc3b3e4e54d", - "reference": "77dedae82ce2a26e2e9b481855473fc3b3e4e54d", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/e46690d5b9d7164a6d061cab1e8d46141b9f49df", + "reference": "e46690d5b9d7164a6d061cab1e8d46141b9f49df", "shasum": "" }, "require": { - "php": ">=8.1", - "symfony/service-contracts": "^1|^2|^3" + "php": ">=8.2", + "symfony/service-contracts": "^2.5|^3" }, "type": "library", "autoload": { @@ -13372,7 +14179,7 @@ "description": "Provides a way to profile code", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/stopwatch/tree/v6.1.0" + "source": "https://github.com/symfony/stopwatch/tree/v7.2.2" }, "funding": [ { @@ -13388,41 +14195,42 @@ "type": "tidelift" } ], - "time": "2022-02-25T11:15:52+00:00" + "time": "2024-12-18T14:28:33+00:00" }, { "name": "symfony/web-profiler-bundle", - "version": "v6.1.2", + "version": "v7.2.3", "source": { "type": "git", "url": "https://github.com/symfony/web-profiler-bundle.git", - "reference": "6589c2ee4b94d7df2f8ca160ec41265fee3f33eb" + "reference": "cd60cb3664954a1593872f6f199bffac99e8c11e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/web-profiler-bundle/zipball/6589c2ee4b94d7df2f8ca160ec41265fee3f33eb", - "reference": "6589c2ee4b94d7df2f8ca160ec41265fee3f33eb", + "url": "https://api.github.com/repos/symfony/web-profiler-bundle/zipball/cd60cb3664954a1593872f6f199bffac99e8c11e", + "reference": "cd60cb3664954a1593872f6f199bffac99e8c11e", "shasum": "" }, "require": { - "php": ">=8.1", - "symfony/config": "^5.4|^6.0", - "symfony/framework-bundle": "^5.4|^6.0", - "symfony/http-kernel": "^6.1", - "symfony/routing": "^5.4|^6.0", - "symfony/twig-bundle": "^5.4|^6.0", - "twig/twig": "^2.13|^3.0.4" + "php": ">=8.2", + "symfony/config": "^6.4|^7.0", + "symfony/framework-bundle": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/routing": "^6.4|^7.0", + "symfony/twig-bundle": "^6.4|^7.0", + "twig/twig": "^3.12" }, "conflict": { - "symfony/form": "<5.4", - "symfony/mailer": "<5.4", - "symfony/messenger": "<5.4" + "symfony/form": "<6.4", + "symfony/mailer": "<6.4", + "symfony/messenger": "<6.4", + "symfony/serializer": "<7.2" }, "require-dev": { - "symfony/browser-kit": "^5.4|^6.0", - "symfony/console": "^5.4|^6.0", - "symfony/css-selector": "^5.4|^6.0", - "symfony/stopwatch": "^5.4|^6.0" + "symfony/browser-kit": "^6.4|^7.0", + "symfony/console": "^6.4|^7.0", + "symfony/css-selector": "^6.4|^7.0", + "symfony/stopwatch": "^6.4|^7.0" }, "type": "symfony-bundle", "autoload": { @@ -13449,8 +14257,11 @@ ], "description": "Provides a development tool that gives detailed information about the execution of any request", "homepage": "https://symfony.com", + "keywords": [ + "dev" + ], "support": { - "source": "https://github.com/symfony/web-profiler-bundle/tree/v6.1.2" + "source": "https://github.com/symfony/web-profiler-bundle/tree/v7.2.3" }, "funding": [ { @@ -13466,20 +14277,20 @@ "type": "tidelift" } ], - "time": "2022-06-12T09:53:37+00:00" + "time": "2025-01-07T09:39:55+00:00" }, { "name": "theseer/tokenizer", - "version": "1.2.1", + "version": "1.2.3", "source": { "type": "git", "url": "https://github.com/theseer/tokenizer.git", - "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e" + "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/theseer/tokenizer/zipball/34a41e998c2183e22995f158c581e7b5e755ab9e", - "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2", + "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2", "shasum": "" }, "require": { @@ -13508,7 +14319,7 @@ "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", "support": { "issues": "https://github.com/theseer/tokenizer/issues", - "source": "https://github.com/theseer/tokenizer/tree/1.2.1" + "source": "https://github.com/theseer/tokenizer/tree/1.2.3" }, "funding": [ { @@ -13516,16 +14327,16 @@ "type": "github" } ], - "time": "2021-07-28T10:34:58+00:00" + "time": "2024-03-03T12:36:25+00:00" } ], "aliases": [], "minimum-stability": "stable", - "stability-flags": [], + "stability-flags": {}, "prefer-stable": false, "prefer-lowest": false, "platform": { - "php": ">=8.1", + "php": "^8.4", "ext-ctype": "*", "ext-iconv": "*", "ext-json": "*", @@ -13533,6 +14344,6 @@ "ext-pdo": "*", "ext-redis": "*" }, - "platform-dev": [], - "plugin-api-version": "2.3.0" + "platform-dev": {}, + "plugin-api-version": "2.6.0" } diff --git a/config/bundles.php b/config/bundles.php index 52928ea0..1f881f9f 100755 --- a/config/bundles.php +++ b/config/bundles.php @@ -18,6 +18,5 @@ Vich\UploaderBundle\VichUploaderBundle::class => ['all' => true], DH\AuditorBundle\DHAuditorBundle::class => ['all' => true], Symfony\Bundle\DebugBundle\DebugBundle::class => ['dev' => true], - Gesdinet\JWTRefreshTokenBundle\GesdinetJWTRefreshTokenBundle::class => ['all' => true], Nelmio\CorsBundle\NelmioCorsBundle::class => ['all' => true], ]; diff --git a/config/packages/gesdinet_jwt_refresh_token.yaml b/config/packages/gesdinet_jwt_refresh_token.yaml deleted file mode 100755 index b2aaecb5..00000000 --- a/config/packages/gesdinet_jwt_refresh_token.yaml +++ /dev/null @@ -1,3 +0,0 @@ -gesdinet_jwt_refresh_token: - single_use: true - ttl_update: true diff --git a/config/packages/nelmio_cors.yaml b/config/packages/nelmio_cors.yaml index cd0bef24..7f5ee624 100755 --- a/config/packages/nelmio_cors.yaml +++ b/config/packages/nelmio_cors.yaml @@ -4,7 +4,7 @@ nelmio_cors: allow_origin: ['%env(CORS_ALLOW_ORIGIN)%'] allow_methods: ['GET', 'OPTIONS', 'POST', 'PUT', 'PATCH', 'DELETE'] allow_headers: ['Content-Type', 'Authorization'] - expose_headers: ['Link'] + expose_headers: ['Link', 'X-Debug-Token', 'X-Debug-Token-Link'] max_age: 3600 paths: '^/api': null diff --git a/config/packages/routing.yaml b/config/packages/routing.yaml index 4b766ce5..5f529f20 100755 --- a/config/packages/routing.yaml +++ b/config/packages/routing.yaml @@ -4,7 +4,7 @@ framework: # Configure how to generate URLs in non-HTTP contexts, such as CLI commands. # See https://symfony.com/doc/current/routing.html#generating-urls-in-commands - #default_uri: http://localhost + default_uri: https://localhost:8000 when@prod: framework: diff --git a/config/packages/security.yaml b/config/packages/security.yaml index 39b644c1..24856b35 100755 --- a/config/packages/security.yaml +++ b/config/packages/security.yaml @@ -1,17 +1,10 @@ security: - enable_authenticator_manager: true - # https://symfony.com/doc/current/security.html#registering-the-user-hashing-passwords password_hashers: Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface: 'auto' - # https://symfony.com/doc/current/security.html#loading-the-user-the-user-provider providers: user_provider: id: KejawenLab\ApiSkeleton\Security\Service\UserProviderFactory firewalls: - api_token_refresh: - pattern: ^/api/token/refresh - stateless: true - refresh_jwt: ~ dev: pattern: ^/(_(profiler|wdt)|css|images|img|js|lib|fonts|bundles)/ security: false @@ -66,7 +59,6 @@ security: jwt: ~ access_control: - - { path: ^/api/token/refresh, roles: IS_AUTHENTICATED_ANONYMOUSLY } - { path: ^/api/login$, roles: IS_AUTHENTICATED_ANONYMOUSLY, methods: ['POST'] } - { path: ^/admin/login$, roles: IS_AUTHENTICATED_ANONYMOUSLY, methods: ['GET', 'POST'] } - { path: ^/api/doc$, roles: IS_AUTHENTICATED_ANONYMOUSLY, methods: ['GET'] } @@ -80,10 +72,6 @@ security: when@test: security: password_hashers: - # By default, password hashers are resource intensive and take time. This is - # important to generate secure password hashes. In tests however, secure hashes - # are not important, waste resources and increase test times. The following - # reduces the work factor to the lowest possible values. Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface: algorithm: auto cost: 4 # Lowest possible value for bcrypt diff --git a/config/routes/annotations.yaml b/config/routes/annotations.yaml index 4c81723e..c28cf1e9 100755 --- a/config/routes/annotations.yaml +++ b/config/routes/annotations.yaml @@ -1,26 +1,26 @@ semart_api: prefix: /api resource: ../../lib/Controller/ - type: annotation + type: attribute semart_admin: prefix: /admin resource: ../../lib/Admin/Controller/ - type: annotation + type: attribute app_api: prefix: /api resource: ../../app/Controller/ - type: annotation + type: attribute app_admin: prefix: /admin resource: ../../app/Admin/Controller/ - type: annotation + type: attribute admin_logout: path: /admin/logout kernel: resource: ../../lib/Kernel.php - type: annotation + type: attribute diff --git a/config/services.yaml b/config/services.yaml index bfe48152..07338757 100755 --- a/config/services.yaml +++ b/config/services.yaml @@ -45,9 +45,6 @@ services: tags: [ 'controller.service_arguments' ] _instanceof: - Doctrine\Common\EventSubscriber: - tags: - - { name: doctrine.event_subscriber } KejawenLab\ApiSkeleton\Security\Model\UserProviderInterface: tags: - { name: semart.user_provider } @@ -74,6 +71,7 @@ services: semart_login_rate_limiter: class: Symfony\Component\Security\Http\RateLimiter\DefaultLoginRateLimiter arguments: + $secret: '%env(resolve:APP_SECRET)%' $globalFactory: '@limiter.ip_login' $localFactory: '@limiter.username_ip_login' Cron\Validator\CrontabValidator: diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index 8e6a626a..0eca967d 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -1,4 +1,3 @@ -version: '3.8' services: app: build: diff --git a/docker-compose.yml b/docker-compose.yml index 6ca365a6..15841e48 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,4 +1,3 @@ -version: '3.8' services: app: build: diff --git a/fixtures/menu.yaml b/fixtures/menu.yaml index 9230ea67..16ea26e0 100644 --- a/fixtures/menu.yaml +++ b/fixtures/menu.yaml @@ -1,10 +1,10 @@ - { parent: null, code: 'PROFILE', name: 'Profile', sortOrder: 0, routeName: 'KejawenLab\ApiSkeleton\Controller\Me\Profile', iconClass: 'cil-user', ref: 'profile' } - { parent: null, code: 'ADMIN', name: 'Administrator', sortOrder: 1, routeName: '#', iconClass: 'cib-adguard', ref: 'administrator' } -- { parent: 'ref:menu#administrator', code: 'USER', sortOrder: 1, name: 'User', routeName: 'KejawenLab\ApiSkeleton\Controller\User\GetAll', ref: 'administrator_user' } -- { parent: 'ref:menu#administrator', code: 'GROUP', sortOrder: 2, name: 'Group', routeName: 'KejawenLab\ApiSkeleton\Controller\Group\GetAll', ref: 'administrator_group' } -- { parent: 'ref:menu#administrator', code: 'MENU', sortOrder: 3, name: 'Menu', routeName: 'KejawenLab\ApiSkeleton\Controller\Menu\GetAll', ref: 'administrator_menu' } -- { parent: 'ref:menu#administrator', code: 'SETTING', sortOrder: 4, name: 'Setting', routeName: 'KejawenLab\ApiSkeleton\Controller\Setting\GetAll', ref: 'administrator_setting' } -- { parent: 'ref:menu#administrator', code: 'APICLIENT', sortOrder: 5, name: 'Api Client', routeName: 'KejawenLab\ApiSkeleton\Controller\ApiClient\GetAll', showable: false, ref: 'administrator_apiclient' } -- { parent: 'ref:menu#administrator', code: 'CRON', sortOrder: 6, name: 'Cronjob', routeName: 'KejawenLab\ApiSkeleton\Controller\Cron\GetAll', ref: 'administrator_cronjob' } +- { parent: 'ref:KejawenLab_ApiSkeleton_Entity_Menu@menu#administrator', code: 'USER', sortOrder: 1, name: 'User', routeName: 'KejawenLab\ApiSkeleton\Controller\User\GetAll', ref: 'administrator_user' } +- { parent: 'ref:KejawenLab_ApiSkeleton_Entity_Menu@menu#administrator', code: 'GROUP', sortOrder: 2, name: 'Group', routeName: 'KejawenLab\ApiSkeleton\Controller\Group\GetAll', ref: 'administrator_group' } +- { parent: 'ref:KejawenLab_ApiSkeleton_Entity_Menu@menu#administrator', code: 'MENU', sortOrder: 3, name: 'Menu', routeName: 'KejawenLab\ApiSkeleton\Controller\Menu\GetAll', ref: 'administrator_menu' } +- { parent: 'ref:KejawenLab_ApiSkeleton_Entity_Menu@menu#administrator', code: 'SETTING', sortOrder: 4, name: 'Setting', routeName: 'KejawenLab\ApiSkeleton\Controller\Setting\GetAll', ref: 'administrator_setting' } +- { parent: 'ref:KejawenLab_ApiSkeleton_Entity_Menu@menu#administrator', code: 'APICLIENT', sortOrder: 5, name: 'Api Client', routeName: 'KejawenLab\ApiSkeleton\Controller\ApiClient\GetAll', showable: false, ref: 'administrator_apiclient' } +- { parent: 'ref:KejawenLab_ApiSkeleton_Entity_Menu@menu#administrator', code: 'CRON', sortOrder: 6, name: 'Cronjob', routeName: 'KejawenLab\ApiSkeleton\Controller\Cron\GetAll', ref: 'administrator_cronjob' } - { parent: null, code: 'MEDIA', name: 'Media', sortOrder: 2, routeName: 'KejawenLab\ApiSkeleton\Controller\Media\GetAll', iconClass: 'cil-folder-open', ref: 'media' } - { parent: null, code: 'AUDIT', name: 'Audit', sortOrder: -99, routeName: '#', showable: false, ref: 'audit' } diff --git a/fixtures/permission.yaml b/fixtures/permission.yaml index cce3c995..d0bb8219 100644 --- a/fixtures/permission.yaml +++ b/fixtures/permission.yaml @@ -1,10 +1,10 @@ -- { group: 'ref:group#group1', menu: 'ref:menu#profile', addable: true, editable: true, viewable: true, deletable: true } -- { group: 'ref:group#group1', menu: 'ref:menu#administrator', addable: true, editable: true, viewable: true, deletable: true } -- { group: 'ref:group#group1', menu: 'ref:menu#administrator_user', addable: true, editable: true, viewable: true, deletable: true } -- { group: 'ref:group#group1', menu: 'ref:menu#administrator_group', addable: true, editable: true, viewable: true, deletable: true } -- { group: 'ref:group#group1', menu: 'ref:menu#administrator_menu', addable: true, editable: true, viewable: true, deletable: true } -- { group: 'ref:group#group1', menu: 'ref:menu#administrator_setting', addable: true, editable: true, viewable: true, deletable: true } -- { group: 'ref:group#group1', menu: 'ref:menu#administrator_apiclient', addable: true, editable: true, viewable: true, deletable: true } -- { group: 'ref:group#group1', menu: 'ref:menu#administrator_cronjob', addable: true, editable: true, viewable: true, deletable: true } -- { group: 'ref:group#group1', menu: 'ref:menu#media', addable: true, editable: true, viewable: true, deletable: true } -- { group: 'ref:group#group1', menu: 'ref:menu#audit', addable: true, editable: true, viewable: true, deletable: true } +- { group: 'ref:KejawenLab_ApiSkeleton_Entity_Group@group#group1', menu: 'ref:KejawenLab_ApiSkeleton_Entity_Menu@menu#profile', addable: true, editable: true, viewable: true, deletable: true } +- { group: 'ref:KejawenLab_ApiSkeleton_Entity_Group@group#group1', menu: 'ref:KejawenLab_ApiSkeleton_Entity_Menu@menu#administrator', addable: true, editable: true, viewable: true, deletable: true } +- { group: 'ref:KejawenLab_ApiSkeleton_Entity_Group@group#group1', menu: 'ref:KejawenLab_ApiSkeleton_Entity_Menu@menu#administrator_user', addable: true, editable: true, viewable: true, deletable: true } +- { group: 'ref:KejawenLab_ApiSkeleton_Entity_Group@group#group1', menu: 'ref:KejawenLab_ApiSkeleton_Entity_Menu@menu#administrator_group', addable: true, editable: true, viewable: true, deletable: true } +- { group: 'ref:KejawenLab_ApiSkeleton_Entity_Group@group#group1', menu: 'ref:KejawenLab_ApiSkeleton_Entity_Menu@menu#administrator_menu', addable: true, editable: true, viewable: true, deletable: true } +- { group: 'ref:KejawenLab_ApiSkeleton_Entity_Group@group#group1', menu: 'ref:KejawenLab_ApiSkeleton_Entity_Menu@menu#administrator_setting', addable: true, editable: true, viewable: true, deletable: true } +- { group: 'ref:KejawenLab_ApiSkeleton_Entity_Group@group#group1', menu: 'ref:KejawenLab_ApiSkeleton_Entity_Menu@menu#administrator_apiclient', addable: true, editable: true, viewable: true, deletable: true } +- { group: 'ref:KejawenLab_ApiSkeleton_Entity_Group@group#group1', menu: 'ref:KejawenLab_ApiSkeleton_Entity_Menu@menu#administrator_cronjob', addable: true, editable: true, viewable: true, deletable: true } +- { group: 'ref:KejawenLab_ApiSkeleton_Entity_Group@group#group1', menu: 'ref:KejawenLab_ApiSkeleton_Entity_Menu@menu#media', addable: true, editable: true, viewable: true, deletable: true } +- { group: 'ref:KejawenLab_ApiSkeleton_Entity_Group@group#group1', menu: 'ref:KejawenLab_ApiSkeleton_Entity_Menu@menu#audit', addable: true, editable: true, viewable: true, deletable: true } diff --git a/fixtures/user.yaml b/fixtures/user.yaml index 2da32041..0f6d1ede 100644 --- a/fixtures/user.yaml +++ b/fixtures/user.yaml @@ -1 +1 @@ -- { username: 'admin', fullName: 'KejawenLab Super Admin', email: 'dev@kejawenlab.com', plainPassword: 'admin', group: 'ref:group#group1' } +- { username: 'admin', fullName: 'KejawenLab Super Admin', email: 'dev@kejawenlab.com', plainPassword: 'admin', group: 'ref:KejawenLab_ApiSkeleton_Entity_Group@group#group1' } diff --git a/lib/ApiClient/ApiClientRequestService.php b/lib/ApiClient/ApiClientRequestService.php index ffe1ea79..ae1ae9e9 100755 --- a/lib/ApiClient/ApiClientRequestService.php +++ b/lib/ApiClient/ApiClientRequestService.php @@ -13,13 +13,14 @@ use KejawenLab\ApiSkeleton\Pagination\AliasHelper; use KejawenLab\ApiSkeleton\Service\AbstractService; use KejawenLab\ApiSkeleton\Service\Model\ServiceInterface; -use Symfony\Component\Messenger\Handler\MessageSubscriberInterface; +use Symfony\Component\Messenger\Attribute\AsMessageHandler; use Symfony\Component\Messenger\MessageBusInterface; /** * @author Muhamad Surya Iksanudin */ -final class ApiClientRequestService extends AbstractService implements ServiceInterface, MessageSubscriberInterface +#[AsMessageHandler] +final class ApiClientRequestService extends AbstractService implements ServiceInterface { public function __construct( MessageBusInterface $messageBus, @@ -45,14 +46,6 @@ public function __invoke(RequestLog $message): void $this->save($apiClientRequest); } - /** - * @return Iterator - */ - public static function getHandledMessages(): iterable - { - yield RequestLog::class; - } - private function createFromMessage(RequestLog $message): ApiClientRequestInterface { /** @var ApiClientRequestInterface $apiClientRequest */ diff --git a/lib/ApiClient/Message/RequestLog.php b/lib/ApiClient/Message/RequestLog.php index 799b7b52..80412caa 100644 --- a/lib/ApiClient/Message/RequestLog.php +++ b/lib/ApiClient/Message/RequestLog.php @@ -7,10 +7,12 @@ use KejawenLab\ApiSkeleton\ApiClient\Model\ApiClientInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\Messenger\Attribute\AsMessage; /** * @author Muhamad Surya Iksanudin */ +#[AsMessage('sync')] final class RequestLog { private readonly string $apiClientId; diff --git a/lib/Controller/ApiClient/Audit.php b/lib/Controller/ApiClient/Audit.php index 743fea03..58dc7e68 100755 --- a/lib/Controller/ApiClient/Audit.php +++ b/lib/Controller/ApiClient/Audit.php @@ -15,7 +15,7 @@ use KejawenLab\ApiSkeleton\Security\Model\UserInterface; use KejawenLab\ApiSkeleton\Security\Service\UserService; use Nelmio\ApiDocBundle\Annotation\Model; -use Nelmio\ApiDocBundle\Annotation\Security; +use Nelmio\ApiDocBundle\Attribute\Security; use OpenApi\Attributes as OA; use OpenApi\Attributes\Response; use OpenApi\Attributes\Tag; diff --git a/lib/Controller/ApiClient/Delete.php b/lib/Controller/ApiClient/Delete.php index a059d870..1a313eef 100755 --- a/lib/Controller/ApiClient/Delete.php +++ b/lib/Controller/ApiClient/Delete.php @@ -12,7 +12,7 @@ use KejawenLab\ApiSkeleton\Security\Annotation\Permission; use KejawenLab\ApiSkeleton\Security\Model\UserInterface; use KejawenLab\ApiSkeleton\Security\Service\UserService; -use Nelmio\ApiDocBundle\Annotation\Security; +use Nelmio\ApiDocBundle\Attribute\Security; use OpenApi\Attributes\Tag; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; diff --git a/lib/Controller/ApiClient/Get.php b/lib/Controller/ApiClient/Get.php index 59184a46..8ddeaa9b 100755 --- a/lib/Controller/ApiClient/Get.php +++ b/lib/Controller/ApiClient/Get.php @@ -14,7 +14,7 @@ use KejawenLab\ApiSkeleton\Security\Model\UserInterface; use KejawenLab\ApiSkeleton\Security\Service\UserService; use Nelmio\ApiDocBundle\Annotation\Model; -use Nelmio\ApiDocBundle\Annotation\Security; +use Nelmio\ApiDocBundle\Attribute\Security; use OpenApi\Attributes as OA; use OpenApi\Attributes\Response; use OpenApi\Attributes\Tag; diff --git a/lib/Controller/ApiClient/GetAll.php b/lib/Controller/ApiClient/GetAll.php index 445baa95..1b288a8e 100755 --- a/lib/Controller/ApiClient/GetAll.php +++ b/lib/Controller/ApiClient/GetAll.php @@ -14,7 +14,7 @@ use KejawenLab\ApiSkeleton\Security\Model\UserInterface; use KejawenLab\ApiSkeleton\Security\Service\UserService; use Nelmio\ApiDocBundle\Annotation\Model; -use Nelmio\ApiDocBundle\Annotation\Security; +use Nelmio\ApiDocBundle\Attribute\Security; use OpenApi\Attributes as OA; use OpenApi\Attributes\Parameter; use OpenApi\Attributes\Response; diff --git a/lib/Controller/ApiClient/Post.php b/lib/Controller/ApiClient/Post.php index ef3cf2fd..b877e3fa 100755 --- a/lib/Controller/ApiClient/Post.php +++ b/lib/Controller/ApiClient/Post.php @@ -16,7 +16,7 @@ use KejawenLab\ApiSkeleton\Security\Model\UserInterface; use KejawenLab\ApiSkeleton\Security\Service\UserService; use Nelmio\ApiDocBundle\Annotation\Model; -use Nelmio\ApiDocBundle\Annotation\Security; +use Nelmio\ApiDocBundle\Attribute\Security; use OpenApi\Attributes as OA; use OpenApi\Attributes\RequestBody; use OpenApi\Attributes\Tag; diff --git a/lib/Controller/ApiClient/Report.php b/lib/Controller/ApiClient/Report.php index 0843456c..5bda5886 100755 --- a/lib/Controller/ApiClient/Report.php +++ b/lib/Controller/ApiClient/Report.php @@ -14,7 +14,7 @@ use KejawenLab\ApiSkeleton\Security\Model\UserInterface; use KejawenLab\ApiSkeleton\Security\Service\UserService; use Nelmio\ApiDocBundle\Annotation\Model; -use Nelmio\ApiDocBundle\Annotation\Security; +use Nelmio\ApiDocBundle\Attribute\Security; use OpenApi\Attributes as OA; use OpenApi\Attributes\Response; use OpenApi\Attributes\Tag; diff --git a/lib/Controller/Cron/Audit.php b/lib/Controller/Cron/Audit.php index a17afb3c..b50ce02f 100755 --- a/lib/Controller/Cron/Audit.php +++ b/lib/Controller/Cron/Audit.php @@ -13,7 +13,7 @@ use KejawenLab\ApiSkeleton\Entity\Cron; use KejawenLab\ApiSkeleton\Security\Annotation\Permission; use Nelmio\ApiDocBundle\Annotation\Model; -use Nelmio\ApiDocBundle\Annotation\Security; +use Nelmio\ApiDocBundle\Attribute\Security; use OpenApi\Attributes as OA; use OpenApi\Attributes\Response; use OpenApi\Attributes\Tag; diff --git a/lib/Controller/Cron/Delete.php b/lib/Controller/Cron/Delete.php index 3ed6166e..d4c3a48a 100755 --- a/lib/Controller/Cron/Delete.php +++ b/lib/Controller/Cron/Delete.php @@ -10,7 +10,7 @@ use KejawenLab\ApiSkeleton\Cron\CronService; use KejawenLab\ApiSkeleton\Cron\Model\CronInterface; use KejawenLab\ApiSkeleton\Security\Annotation\Permission; -use Nelmio\ApiDocBundle\Annotation\Security; +use Nelmio\ApiDocBundle\Attribute\Security; use OpenApi\Attributes\Tag; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; diff --git a/lib/Controller/Cron/Get.php b/lib/Controller/Cron/Get.php index eb5bcaa8..41707263 100755 --- a/lib/Controller/Cron/Get.php +++ b/lib/Controller/Cron/Get.php @@ -12,7 +12,7 @@ use KejawenLab\ApiSkeleton\Entity\Cron; use KejawenLab\ApiSkeleton\Security\Annotation\Permission; use Nelmio\ApiDocBundle\Annotation\Model; -use Nelmio\ApiDocBundle\Annotation\Security; +use Nelmio\ApiDocBundle\Attribute\Security; use OpenApi\Attributes as OA; use OpenApi\Attributes\Response; use OpenApi\Attributes\Tag; diff --git a/lib/Controller/Cron/GetAll.php b/lib/Controller/Cron/GetAll.php index 64678a41..bb497790 100755 --- a/lib/Controller/Cron/GetAll.php +++ b/lib/Controller/Cron/GetAll.php @@ -12,7 +12,7 @@ use KejawenLab\ApiSkeleton\Pagination\Paginator; use KejawenLab\ApiSkeleton\Security\Annotation\Permission; use Nelmio\ApiDocBundle\Annotation\Model; -use Nelmio\ApiDocBundle\Annotation\Security; +use Nelmio\ApiDocBundle\Attribute\Security; use OpenApi\Attributes as OA; use OpenApi\Attributes\Parameter; use OpenApi\Attributes\Response; diff --git a/lib/Controller/Cron/Post.php b/lib/Controller/Cron/Post.php index a4c5748b..a7fea64f 100755 --- a/lib/Controller/Cron/Post.php +++ b/lib/Controller/Cron/Post.php @@ -14,7 +14,7 @@ use KejawenLab\ApiSkeleton\Form\FormFactory; use KejawenLab\ApiSkeleton\Security\Annotation\Permission; use Nelmio\ApiDocBundle\Annotation\Model; -use Nelmio\ApiDocBundle\Annotation\Security; +use Nelmio\ApiDocBundle\Attribute\Security; use OpenApi\Attributes as OA; use OpenApi\Attributes\RequestBody; use OpenApi\Attributes\Tag; diff --git a/lib/Controller/Cron/Put.php b/lib/Controller/Cron/Put.php index a246adbc..55a085b1 100755 --- a/lib/Controller/Cron/Put.php +++ b/lib/Controller/Cron/Put.php @@ -14,7 +14,7 @@ use KejawenLab\ApiSkeleton\Form\FormFactory; use KejawenLab\ApiSkeleton\Security\Annotation\Permission; use Nelmio\ApiDocBundle\Annotation\Model; -use Nelmio\ApiDocBundle\Annotation\Security; +use Nelmio\ApiDocBundle\Attribute\Security; use OpenApi\Attributes as OA; use OpenApi\Attributes\RequestBody; use OpenApi\Attributes\Tag; diff --git a/lib/Controller/Cron/Report.php b/lib/Controller/Cron/Report.php index f9f47ded..f20737de 100755 --- a/lib/Controller/Cron/Report.php +++ b/lib/Controller/Cron/Report.php @@ -12,7 +12,7 @@ use KejawenLab\ApiSkeleton\Pagination\Paginator; use KejawenLab\ApiSkeleton\Security\Annotation\Permission; use Nelmio\ApiDocBundle\Annotation\Model; -use Nelmio\ApiDocBundle\Annotation\Security; +use Nelmio\ApiDocBundle\Attribute\Security; use OpenApi\Attributes as OA; use OpenApi\Attributes\Response; use OpenApi\Attributes\Tag; diff --git a/lib/Controller/Cron/Run.php b/lib/Controller/Cron/Run.php index dc188886..e8a30542 100755 --- a/lib/Controller/Cron/Run.php +++ b/lib/Controller/Cron/Run.php @@ -10,7 +10,7 @@ use KejawenLab\ApiSkeleton\Cron\CronService; use KejawenLab\ApiSkeleton\Entity\Cron; use KejawenLab\ApiSkeleton\Security\Annotation\Permission; -use Nelmio\ApiDocBundle\Annotation\Security; +use Nelmio\ApiDocBundle\Attribute\Security; use OpenApi\Attributes as OA; use OpenApi\Attributes\Response; use OpenApi\Attributes\Tag; diff --git a/lib/Controller/Group/Audit.php b/lib/Controller/Group/Audit.php index 1ffaf4fb..311788e5 100755 --- a/lib/Controller/Group/Audit.php +++ b/lib/Controller/Group/Audit.php @@ -13,7 +13,7 @@ use KejawenLab\ApiSkeleton\Security\Annotation\Permission; use KejawenLab\ApiSkeleton\Security\Service\GroupService; use Nelmio\ApiDocBundle\Annotation\Model; -use Nelmio\ApiDocBundle\Annotation\Security; +use Nelmio\ApiDocBundle\Attribute\Security; use OpenApi\Attributes as OA; use OpenApi\Attributes\Response; use OpenApi\Attributes\Tag; diff --git a/lib/Controller/Group/Delete.php b/lib/Controller/Group/Delete.php index 952b1140..c633d890 100755 --- a/lib/Controller/Group/Delete.php +++ b/lib/Controller/Group/Delete.php @@ -10,7 +10,7 @@ use KejawenLab\ApiSkeleton\Security\Annotation\Permission; use KejawenLab\ApiSkeleton\Security\Model\GroupInterface; use KejawenLab\ApiSkeleton\Security\Service\GroupService; -use Nelmio\ApiDocBundle\Annotation\Security; +use Nelmio\ApiDocBundle\Attribute\Security; use OpenApi\Attributes\Tag; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; diff --git a/lib/Controller/Group/Get.php b/lib/Controller/Group/Get.php index 5fc43c99..6170cfe0 100755 --- a/lib/Controller/Group/Get.php +++ b/lib/Controller/Group/Get.php @@ -12,7 +12,7 @@ use KejawenLab\ApiSkeleton\Security\Model\GroupInterface; use KejawenLab\ApiSkeleton\Security\Service\GroupService; use Nelmio\ApiDocBundle\Annotation\Model; -use Nelmio\ApiDocBundle\Annotation\Security; +use Nelmio\ApiDocBundle\Attribute\Security; use OpenApi\Attributes as OA; use OpenApi\Attributes\Response; use OpenApi\Attributes\Tag; diff --git a/lib/Controller/Group/GetAll.php b/lib/Controller/Group/GetAll.php index 9f885c23..5916dc2e 100755 --- a/lib/Controller/Group/GetAll.php +++ b/lib/Controller/Group/GetAll.php @@ -12,7 +12,7 @@ use KejawenLab\ApiSkeleton\Security\Annotation\Permission; use KejawenLab\ApiSkeleton\Security\Service\GroupService; use Nelmio\ApiDocBundle\Annotation\Model; -use Nelmio\ApiDocBundle\Annotation\Security; +use Nelmio\ApiDocBundle\Attribute\Security; use OpenApi\Attributes as OA; use OpenApi\Attributes\Parameter; use OpenApi\Attributes\Response; diff --git a/lib/Controller/Group/Permission.php b/lib/Controller/Group/Permission.php index 243f7191..ef52a50b 100755 --- a/lib/Controller/Group/Permission.php +++ b/lib/Controller/Group/Permission.php @@ -12,7 +12,7 @@ use KejawenLab\ApiSkeleton\Security\Annotation as Semart; use KejawenLab\ApiSkeleton\Security\Service\PermissionService; use Nelmio\ApiDocBundle\Annotation\Model; -use Nelmio\ApiDocBundle\Annotation\Security; +use Nelmio\ApiDocBundle\Attribute\Security; use OpenApi\Attributes as OA; use OpenApi\Attributes\Parameter; use OpenApi\Attributes\Response; diff --git a/lib/Controller/Group/PermissionPut.php b/lib/Controller/Group/PermissionPut.php index efcc5ab0..062564ac 100755 --- a/lib/Controller/Group/PermissionPut.php +++ b/lib/Controller/Group/PermissionPut.php @@ -16,7 +16,7 @@ use KejawenLab\ApiSkeleton\Security\Service\GroupService; use KejawenLab\ApiSkeleton\Security\Service\PermissionService; use Nelmio\ApiDocBundle\Annotation\Model; -use Nelmio\ApiDocBundle\Annotation\Security; +use Nelmio\ApiDocBundle\Attribute\Security; use OpenApi\Attributes as OA; use OpenApi\Attributes\RequestBody; use OpenApi\Attributes\Tag; diff --git a/lib/Controller/Group/Post.php b/lib/Controller/Group/Post.php index 154b10a7..16897ec8 100755 --- a/lib/Controller/Group/Post.php +++ b/lib/Controller/Group/Post.php @@ -14,7 +14,7 @@ use KejawenLab\ApiSkeleton\Security\Model\GroupInterface; use KejawenLab\ApiSkeleton\Security\Service\GroupService; use Nelmio\ApiDocBundle\Annotation\Model; -use Nelmio\ApiDocBundle\Annotation\Security; +use Nelmio\ApiDocBundle\Attribute\Security; use OpenApi\Attributes as OA; use OpenApi\Attributes\RequestBody; use OpenApi\Attributes\Tag; diff --git a/lib/Controller/Group/Put.php b/lib/Controller/Group/Put.php index 920a4251..fa8ccfe2 100755 --- a/lib/Controller/Group/Put.php +++ b/lib/Controller/Group/Put.php @@ -14,7 +14,7 @@ use KejawenLab\ApiSkeleton\Security\Model\GroupInterface; use KejawenLab\ApiSkeleton\Security\Service\GroupService; use Nelmio\ApiDocBundle\Annotation\Model; -use Nelmio\ApiDocBundle\Annotation\Security; +use Nelmio\ApiDocBundle\Attribute\Security; use OpenApi\Attributes as OA; use OpenApi\Attributes\RequestBody; use OpenApi\Attributes\Tag; diff --git a/lib/Controller/Me/CreateApiClient.php b/lib/Controller/Me/CreateApiClient.php index bdd67077..e9399d42 100644 --- a/lib/Controller/Me/CreateApiClient.php +++ b/lib/Controller/Me/CreateApiClient.php @@ -18,7 +18,7 @@ use KejawenLab\ApiSkeleton\Security\User; use KejawenLab\ApiSkeleton\Setting\SettingService; use Nelmio\ApiDocBundle\Annotation\Model; -use Nelmio\ApiDocBundle\Annotation\Security; +use Nelmio\ApiDocBundle\Attribute\Security; use OpenApi\Attributes as OA; use OpenApi\Attributes\RequestBody; use OpenApi\Attributes\Tag; diff --git a/lib/Controller/Me/DeleteApiClient.php b/lib/Controller/Me/DeleteApiClient.php index f3906fd8..adce3a7e 100644 --- a/lib/Controller/Me/DeleteApiClient.php +++ b/lib/Controller/Me/DeleteApiClient.php @@ -13,7 +13,7 @@ use KejawenLab\ApiSkeleton\Security\Model\UserInterface; use KejawenLab\ApiSkeleton\Security\Service\UserProviderFactory; use KejawenLab\ApiSkeleton\Security\User; -use Nelmio\ApiDocBundle\Annotation\Security; +use Nelmio\ApiDocBundle\Attribute\Security; use OpenApi\Attributes\Tag; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; diff --git a/lib/Controller/Me/GetApiClient.php b/lib/Controller/Me/GetApiClient.php index 19e9fbb7..5c271688 100644 --- a/lib/Controller/Me/GetApiClient.php +++ b/lib/Controller/Me/GetApiClient.php @@ -15,7 +15,7 @@ use KejawenLab\ApiSkeleton\Security\Service\UserProviderFactory; use KejawenLab\ApiSkeleton\Security\User; use Nelmio\ApiDocBundle\Annotation\Model; -use Nelmio\ApiDocBundle\Annotation\Security; +use Nelmio\ApiDocBundle\Attribute\Security; use OpenApi\Attributes as OA; use OpenApi\Attributes\Response; use OpenApi\Attributes\Tag; diff --git a/lib/Controller/Me/Menu.php b/lib/Controller/Me/Menu.php index f29bc894..07f77e04 100755 --- a/lib/Controller/Me/Menu.php +++ b/lib/Controller/Me/Menu.php @@ -13,7 +13,7 @@ use KejawenLab\ApiSkeleton\Security\Service\UserProviderFactory; use KejawenLab\ApiSkeleton\Security\User; use Nelmio\ApiDocBundle\Annotation\Model; -use Nelmio\ApiDocBundle\Annotation\Security; +use Nelmio\ApiDocBundle\Attribute\Security; use OpenApi\Attributes as OA; use OpenApi\Attributes\Response; use OpenApi\Attributes\Tag; diff --git a/lib/Controller/Me/Profile.php b/lib/Controller/Me/Profile.php index 316091a0..e7d58840 100755 --- a/lib/Controller/Me/Profile.php +++ b/lib/Controller/Me/Profile.php @@ -12,7 +12,7 @@ use KejawenLab\ApiSkeleton\Security\Service\UserProviderFactory; use KejawenLab\ApiSkeleton\Security\User as AuthUser; use Nelmio\ApiDocBundle\Annotation\Model; -use Nelmio\ApiDocBundle\Annotation\Security; +use Nelmio\ApiDocBundle\Attribute\Security; use OpenApi\Attributes as OA; use OpenApi\Attributes\Response; use OpenApi\Attributes\Tag; diff --git a/lib/Controller/Me/Put.php b/lib/Controller/Me/Put.php index 5e1f1148..53f4a450 100755 --- a/lib/Controller/Me/Put.php +++ b/lib/Controller/Me/Put.php @@ -16,7 +16,7 @@ use KejawenLab\ApiSkeleton\Security\Service\UserService; use KejawenLab\ApiSkeleton\Security\User as AuthUser; use Nelmio\ApiDocBundle\Annotation\Model; -use Nelmio\ApiDocBundle\Annotation\Security; +use Nelmio\ApiDocBundle\Attribute\Security; use OpenApi\Attributes as OA; use OpenApi\Attributes\RequestBody; use OpenApi\Attributes\Tag; diff --git a/lib/Controller/Media/Audit.php b/lib/Controller/Media/Audit.php index 9e6bd0cf..aa04d61d 100755 --- a/lib/Controller/Media/Audit.php +++ b/lib/Controller/Media/Audit.php @@ -14,7 +14,7 @@ use KejawenLab\ApiSkeleton\Media\Model\MediaInterface; use KejawenLab\ApiSkeleton\Security\Annotation\Permission; use Nelmio\ApiDocBundle\Annotation\Model; -use Nelmio\ApiDocBundle\Annotation\Security; +use Nelmio\ApiDocBundle\Attribute\Security; use OpenApi\Attributes as OA; use OpenApi\Attributes\Response; use OpenApi\Attributes\Tag; diff --git a/lib/Controller/Media/Delete.php b/lib/Controller/Media/Delete.php index ebad21c3..f5984701 100755 --- a/lib/Controller/Media/Delete.php +++ b/lib/Controller/Media/Delete.php @@ -10,7 +10,7 @@ use KejawenLab\ApiSkeleton\Media\MediaService; use KejawenLab\ApiSkeleton\Media\Model\MediaInterface; use KejawenLab\ApiSkeleton\Security\Annotation\Permission; -use Nelmio\ApiDocBundle\Annotation\Security; +use Nelmio\ApiDocBundle\Attribute\Security; use OpenApi\Attributes\Tag; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; diff --git a/lib/Controller/Media/Get.php b/lib/Controller/Media/Get.php index 506e05ec..55d95a76 100755 --- a/lib/Controller/Media/Get.php +++ b/lib/Controller/Media/Get.php @@ -9,7 +9,7 @@ use KejawenLab\ApiSkeleton\Media\MediaService; use KejawenLab\ApiSkeleton\Media\Model\MediaInterface; use KejawenLab\ApiSkeleton\SemartApiSkeleton; -use Nelmio\ApiDocBundle\Annotation\Security; +use Nelmio\ApiDocBundle\Attribute\Security; use OpenApi\Attributes as OA; use OpenApi\Attributes\Tag; use Symfony\Component\HttpFoundation\BinaryFileResponse; diff --git a/lib/Controller/Media/GetAll.php b/lib/Controller/Media/GetAll.php index 0fefa99e..f8b9ca01 100755 --- a/lib/Controller/Media/GetAll.php +++ b/lib/Controller/Media/GetAll.php @@ -12,7 +12,7 @@ use KejawenLab\ApiSkeleton\Pagination\Paginator; use KejawenLab\ApiSkeleton\Security\Annotation\Permission; use Nelmio\ApiDocBundle\Annotation\Model; -use Nelmio\ApiDocBundle\Annotation\Security; +use Nelmio\ApiDocBundle\Attribute\Security; use OpenApi\Attributes as OA; use OpenApi\Attributes\Parameter; use OpenApi\Attributes\Response; diff --git a/lib/Controller/Media/Post.php b/lib/Controller/Media/Post.php index 468bf52a..9f0b9f61 100755 --- a/lib/Controller/Media/Post.php +++ b/lib/Controller/Media/Post.php @@ -12,7 +12,7 @@ use KejawenLab\ApiSkeleton\Media\MediaService; use KejawenLab\ApiSkeleton\Security\Annotation\Permission; use Nelmio\ApiDocBundle\Annotation\Model; -use Nelmio\ApiDocBundle\Annotation\Security; +use Nelmio\ApiDocBundle\Attribute\Security; use OpenApi\Attributes as OA; use OpenApi\Attributes\RequestBody; use OpenApi\Attributes\Tag; diff --git a/lib/Controller/Menu/Audit.php b/lib/Controller/Menu/Audit.php index 275e7995..d1d54e63 100755 --- a/lib/Controller/Menu/Audit.php +++ b/lib/Controller/Menu/Audit.php @@ -13,7 +13,7 @@ use KejawenLab\ApiSkeleton\Security\Annotation\Permission; use KejawenLab\ApiSkeleton\Security\Service\MenuService; use Nelmio\ApiDocBundle\Annotation\Model; -use Nelmio\ApiDocBundle\Annotation\Security; +use Nelmio\ApiDocBundle\Attribute\Security; use OpenApi\Attributes as OA; use OpenApi\Attributes\Response; use OpenApi\Attributes\Tag; diff --git a/lib/Controller/Menu/Delete.php b/lib/Controller/Menu/Delete.php index 507a346a..c670796e 100755 --- a/lib/Controller/Menu/Delete.php +++ b/lib/Controller/Menu/Delete.php @@ -10,7 +10,7 @@ use KejawenLab\ApiSkeleton\Security\Annotation\Permission; use KejawenLab\ApiSkeleton\Security\Model\MenuInterface; use KejawenLab\ApiSkeleton\Security\Service\MenuService; -use Nelmio\ApiDocBundle\Annotation\Security; +use Nelmio\ApiDocBundle\Attribute\Security; use OpenApi\Attributes\Tag; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; diff --git a/lib/Controller/Menu/Get.php b/lib/Controller/Menu/Get.php index 947f8edd..69a49afb 100755 --- a/lib/Controller/Menu/Get.php +++ b/lib/Controller/Menu/Get.php @@ -12,7 +12,7 @@ use KejawenLab\ApiSkeleton\Security\Model\MenuInterface; use KejawenLab\ApiSkeleton\Security\Service\MenuService; use Nelmio\ApiDocBundle\Annotation\Model; -use Nelmio\ApiDocBundle\Annotation\Security; +use Nelmio\ApiDocBundle\Attribute\Security; use OpenApi\Attributes as OA; use OpenApi\Attributes\Response; use OpenApi\Attributes\Tag; diff --git a/lib/Controller/Menu/GetAll.php b/lib/Controller/Menu/GetAll.php index 4f71319f..01750e77 100755 --- a/lib/Controller/Menu/GetAll.php +++ b/lib/Controller/Menu/GetAll.php @@ -12,7 +12,7 @@ use KejawenLab\ApiSkeleton\Security\Annotation\Permission; use KejawenLab\ApiSkeleton\Security\Service\MenuService; use Nelmio\ApiDocBundle\Annotation\Model; -use Nelmio\ApiDocBundle\Annotation\Security; +use Nelmio\ApiDocBundle\Attribute\Security; use OpenApi\Attributes as OA; use OpenApi\Attributes\Parameter; use OpenApi\Attributes\Response; diff --git a/lib/Controller/Menu/Post.php b/lib/Controller/Menu/Post.php index 188ef5ea..05e02a71 100755 --- a/lib/Controller/Menu/Post.php +++ b/lib/Controller/Menu/Post.php @@ -14,7 +14,7 @@ use KejawenLab\ApiSkeleton\Security\Model\MenuInterface; use KejawenLab\ApiSkeleton\Security\Service\MenuService; use Nelmio\ApiDocBundle\Annotation\Model; -use Nelmio\ApiDocBundle\Annotation\Security; +use Nelmio\ApiDocBundle\Attribute\Security; use OpenApi\Attributes as OA; use OpenApi\Attributes\RequestBody; use OpenApi\Attributes\Tag; diff --git a/lib/Controller/Menu/Put.php b/lib/Controller/Menu/Put.php index 172e63bc..3cb174e3 100755 --- a/lib/Controller/Menu/Put.php +++ b/lib/Controller/Menu/Put.php @@ -14,7 +14,7 @@ use KejawenLab\ApiSkeleton\Security\Model\MenuInterface; use KejawenLab\ApiSkeleton\Security\Service\MenuService; use Nelmio\ApiDocBundle\Annotation\Model; -use Nelmio\ApiDocBundle\Annotation\Security; +use Nelmio\ApiDocBundle\Attribute\Security; use OpenApi\Attributes as OA; use OpenApi\Attributes\RequestBody; use OpenApi\Attributes\Tag; diff --git a/lib/Controller/RefreshTokenController.php b/lib/Controller/RefreshTokenController.php deleted file mode 100755 index e8fcb6b5..00000000 --- a/lib/Controller/RefreshTokenController.php +++ /dev/null @@ -1,47 +0,0 @@ - - */ -#[Tag(name: 'Security')] -final class RefreshTokenController extends AbstractFOSRestController -{ - #[Post(data: '/token/refresh', name: self::class, priority: 17)] - #[RequestBody( - content: new OA\MediaType( - mediaType: 'application/json', - schema: new OA\Schema( - properties: [new OA\Property(property: 'refresh_token', type: 'string')], - ), - ) - )] - #[Response( - response: 200, - description: 'JWT Token', - content: new OA\MediaType( - mediaType: 'application/json', - schema: new OA\Schema( - properties: [ - new OA\Property(property: 'token', type: 'string'), - new OA\Property(property: 'refresh_token', type: 'string'), - ], - ), - ), - )] - public function __invoke(): never - { - throw new RuntimeException('Invalid security configuration'); - } -} diff --git a/lib/Controller/Setting/Audit.php b/lib/Controller/Setting/Audit.php index 12017d1a..6465ed4f 100755 --- a/lib/Controller/Setting/Audit.php +++ b/lib/Controller/Setting/Audit.php @@ -13,7 +13,7 @@ use KejawenLab\ApiSkeleton\Security\Annotation\Permission; use KejawenLab\ApiSkeleton\Setting\SettingService; use Nelmio\ApiDocBundle\Annotation\Model; -use Nelmio\ApiDocBundle\Annotation\Security; +use Nelmio\ApiDocBundle\Attribute\Security; use OpenApi\Attributes as OA; use OpenApi\Attributes\Response; use OpenApi\Attributes\Tag; diff --git a/lib/Controller/Setting/Delete.php b/lib/Controller/Setting/Delete.php index 05df12ff..0552a081 100755 --- a/lib/Controller/Setting/Delete.php +++ b/lib/Controller/Setting/Delete.php @@ -10,7 +10,7 @@ use KejawenLab\ApiSkeleton\Security\Annotation\Permission; use KejawenLab\ApiSkeleton\Setting\Model\SettingInterface; use KejawenLab\ApiSkeleton\Setting\SettingService; -use Nelmio\ApiDocBundle\Annotation\Security; +use Nelmio\ApiDocBundle\Attribute\Security; use OpenApi\Attributes\Tag; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; diff --git a/lib/Controller/Setting/Get.php b/lib/Controller/Setting/Get.php index fcd8c0f5..e082b5ac 100755 --- a/lib/Controller/Setting/Get.php +++ b/lib/Controller/Setting/Get.php @@ -12,7 +12,7 @@ use KejawenLab\ApiSkeleton\Setting\Model\SettingInterface; use KejawenLab\ApiSkeleton\Setting\SettingService; use Nelmio\ApiDocBundle\Annotation\Model; -use Nelmio\ApiDocBundle\Annotation\Security; +use Nelmio\ApiDocBundle\Attribute\Security; use OpenApi\Attributes as OA; use OpenApi\Attributes\Response; use OpenApi\Attributes\Tag; diff --git a/lib/Controller/Setting/GetAll.php b/lib/Controller/Setting/GetAll.php index 61772129..89da08fe 100755 --- a/lib/Controller/Setting/GetAll.php +++ b/lib/Controller/Setting/GetAll.php @@ -12,7 +12,7 @@ use KejawenLab\ApiSkeleton\Security\Annotation\Permission; use KejawenLab\ApiSkeleton\Setting\SettingService; use Nelmio\ApiDocBundle\Annotation\Model; -use Nelmio\ApiDocBundle\Annotation\Security; +use Nelmio\ApiDocBundle\Attribute\Security; use OpenApi\Attributes as OA; use OpenApi\Attributes\Parameter; use OpenApi\Attributes\Response; diff --git a/lib/Controller/Setting/Post.php b/lib/Controller/Setting/Post.php index 5df67ae9..b4a19961 100755 --- a/lib/Controller/Setting/Post.php +++ b/lib/Controller/Setting/Post.php @@ -14,7 +14,7 @@ use KejawenLab\ApiSkeleton\Setting\Model\SettingInterface; use KejawenLab\ApiSkeleton\Setting\SettingService; use Nelmio\ApiDocBundle\Annotation\Model; -use Nelmio\ApiDocBundle\Annotation\Security; +use Nelmio\ApiDocBundle\Attribute\Security; use OpenApi\Attributes as OA; use OpenApi\Attributes\RequestBody; use OpenApi\Attributes\Tag; diff --git a/lib/Controller/Setting/Put.php b/lib/Controller/Setting/Put.php index 781e3d2d..2155caf2 100755 --- a/lib/Controller/Setting/Put.php +++ b/lib/Controller/Setting/Put.php @@ -14,7 +14,7 @@ use KejawenLab\ApiSkeleton\Setting\Model\SettingInterface; use KejawenLab\ApiSkeleton\Setting\SettingService; use Nelmio\ApiDocBundle\Annotation\Model; -use Nelmio\ApiDocBundle\Annotation\Security; +use Nelmio\ApiDocBundle\Attribute\Security; use OpenApi\Attributes as OA; use OpenApi\Attributes\RequestBody; use OpenApi\Attributes\Tag; diff --git a/lib/Controller/User/Audit.php b/lib/Controller/User/Audit.php index cbb994a0..80feef50 100755 --- a/lib/Controller/User/Audit.php +++ b/lib/Controller/User/Audit.php @@ -13,7 +13,7 @@ use KejawenLab\ApiSkeleton\Security\Annotation\Permission; use KejawenLab\ApiSkeleton\Security\Service\UserService; use Nelmio\ApiDocBundle\Annotation\Model; -use Nelmio\ApiDocBundle\Annotation\Security; +use Nelmio\ApiDocBundle\Attribute\Security; use OpenApi\Attributes as OA; use OpenApi\Attributes\Response; use OpenApi\Attributes\Tag; diff --git a/lib/Controller/User/Delete.php b/lib/Controller/User/Delete.php index f9f47e72..f4869ea6 100755 --- a/lib/Controller/User/Delete.php +++ b/lib/Controller/User/Delete.php @@ -10,7 +10,7 @@ use KejawenLab\ApiSkeleton\Security\Annotation\Permission; use KejawenLab\ApiSkeleton\Security\Model\UserInterface; use KejawenLab\ApiSkeleton\Security\Service\UserService; -use Nelmio\ApiDocBundle\Annotation\Security; +use Nelmio\ApiDocBundle\Attribute\Security; use OpenApi\Attributes\Tag; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; diff --git a/lib/Controller/User/Get.php b/lib/Controller/User/Get.php index 2174e35a..e44ae01c 100755 --- a/lib/Controller/User/Get.php +++ b/lib/Controller/User/Get.php @@ -12,7 +12,7 @@ use KejawenLab\ApiSkeleton\Security\Model\UserInterface; use KejawenLab\ApiSkeleton\Security\Service\UserService; use Nelmio\ApiDocBundle\Annotation\Model; -use Nelmio\ApiDocBundle\Annotation\Security; +use Nelmio\ApiDocBundle\Attribute\Security; use OpenApi\Attributes as OA; use OpenApi\Attributes\Response; use OpenApi\Attributes\Tag; diff --git a/lib/Controller/User/GetAll.php b/lib/Controller/User/GetAll.php index 632ad8b4..1a16d457 100755 --- a/lib/Controller/User/GetAll.php +++ b/lib/Controller/User/GetAll.php @@ -12,7 +12,7 @@ use KejawenLab\ApiSkeleton\Security\Annotation\Permission; use KejawenLab\ApiSkeleton\Security\Service\UserService; use Nelmio\ApiDocBundle\Annotation\Model; -use Nelmio\ApiDocBundle\Annotation\Security; +use Nelmio\ApiDocBundle\Attribute\Security; use OpenApi\Attributes as OA; use OpenApi\Attributes\Parameter; use OpenApi\Attributes\Response; diff --git a/lib/Controller/User/Post.php b/lib/Controller/User/Post.php index 5d9f9d22..88546e13 100755 --- a/lib/Controller/User/Post.php +++ b/lib/Controller/User/Post.php @@ -14,7 +14,7 @@ use KejawenLab\ApiSkeleton\Security\Model\UserInterface; use KejawenLab\ApiSkeleton\Security\Service\UserService; use Nelmio\ApiDocBundle\Annotation\Model; -use Nelmio\ApiDocBundle\Annotation\Security; +use Nelmio\ApiDocBundle\Attribute\Security; use OpenApi\Attributes as OA; use OpenApi\Attributes\RequestBody; use OpenApi\Attributes\Tag; diff --git a/lib/Controller/User/Put.php b/lib/Controller/User/Put.php index 5b9ce807..4dedc6f7 100755 --- a/lib/Controller/User/Put.php +++ b/lib/Controller/User/Put.php @@ -14,7 +14,7 @@ use KejawenLab\ApiSkeleton\Security\Model\UserInterface; use KejawenLab\ApiSkeleton\Security\Service\UserService; use Nelmio\ApiDocBundle\Annotation\Model; -use Nelmio\ApiDocBundle\Annotation\Security; +use Nelmio\ApiDocBundle\Attribute\Security; use OpenApi\Attributes as OA; use OpenApi\Attributes\RequestBody; use OpenApi\Attributes\Tag; diff --git a/lib/DataFixtures/AbstractFixture.php b/lib/DataFixtures/AbstractFixture.php index 8a45e188..260ea4a3 100755 --- a/lib/DataFixtures/AbstractFixture.php +++ b/lib/DataFixtures/AbstractFixture.php @@ -39,10 +39,11 @@ public function load(ObjectManager $manager): void foreach ($fixtures as $key => $value) { if (static::REF_KEY === sprintf('%s:', $key)) { - $this->setReference(StringUtil::uppercase(sprintf('%s#%s', $this->getReferenceKey(), $value)), $entity); + $this->addReference(StringUtil::uppercase(sprintf('%s#%s', $this->getReferenceKey(), $value)), $entity); } else { if (\is_string($value) && str_contains($value, (string) static::REF_KEY)) { - $value = $this->getReference(StringUtil::uppercase(str_replace('ref:', '', $value))); + $references = explode('@', str_replace('ref:', '', $value)); + $value = $this->getReference(StringUtil::uppercase($references[1]), str_replace('_', '\\', $references[0])); } if (\is_string($value) && str_contains($value, 'date:')) { diff --git a/lib/Entity/Menu.php b/lib/Entity/Menu.php index 8da509ac..5bb3d086 100755 --- a/lib/Entity/Menu.php +++ b/lib/Entity/Menu.php @@ -81,9 +81,10 @@ class Menu implements MenuInterface private bool $adminOnly; #[Groups(groups: ['read'])] - private ?string $apiPath; + private ?string $apiPath = '#'; - private ?string $adminPath; + #[Groups(groups: ['read'])] + private ?string $adminPath = '#'; public function __construct() { @@ -95,8 +96,6 @@ public function __construct() $this->iconClass = null; $this->showable = true; $this->adminOnly = false; - $this->apiPath = '#'; - $this->adminPath = '#'; } public function getId(): ?string diff --git a/lib/EventSubscriber/LoadUrlPathSubscriber.php b/lib/EventSubscriber/LoadUrlPathSubscriber.php index 24a6809d..2be04b64 100755 --- a/lib/EventSubscriber/LoadUrlPathSubscriber.php +++ b/lib/EventSubscriber/LoadUrlPathSubscriber.php @@ -4,9 +4,9 @@ namespace KejawenLab\ApiSkeleton\EventSubscriber; -use Doctrine\Common\EventSubscriber; +use Doctrine\Bundle\DoctrineBundle\Attribute\AsEntityListener; +use Doctrine\ORM\Event\PostLoadEventArgs; use Doctrine\ORM\Events; -use Doctrine\Persistence\Event\LifecycleEventArgs; use KejawenLab\ApiSkeleton\Controller\ApiClient\GetAll as ApiClient; use KejawenLab\ApiSkeleton\Controller\Cron\GetAll as Cron; use KejawenLab\ApiSkeleton\Controller\Group\GetAll as Group; @@ -15,7 +15,7 @@ use KejawenLab\ApiSkeleton\Controller\Menu\GetAll as Menu; use KejawenLab\ApiSkeleton\Controller\Setting\GetAll as Setting; use KejawenLab\ApiSkeleton\Controller\User\GetAll; -use KejawenLab\ApiSkeleton\Security\Model\MenuInterface; +use KejawenLab\ApiSkeleton\Entity\Menu as Entity; use KejawenLab\ApiSkeleton\Util\StringUtil; use Symfony\Component\Routing\Exception\RouteNotFoundException; use Symfony\Component\Routing\Generator\UrlGeneratorInterface; @@ -23,7 +23,8 @@ /** * @author Muhamad Surya Iksanudin */ -final class LoadUrlPathSubscriber implements EventSubscriber +#[AsEntityListener(event: Events::postLoad, method: 'postLoad', entity: Entity::class)] +final class LoadUrlPathSubscriber { private const ROUTE_NAMESPACE_PREFIX = 'KejawenLab\\Application\\Controller\\'; @@ -36,13 +37,8 @@ public function __construct(private readonly UrlGeneratorInterface $urlGenerator { } - public function postLoad(LifecycleEventArgs $args): void + public function postLoad(Entity $object, PostLoadEventArgs $args): void { - $object = $args->getObject(); - if (!$object instanceof MenuInterface) { - return; - } - $apiPath = '#'; $path = $object->getRouteName(); $adminPath = '#'; @@ -78,14 +74,4 @@ public function postLoad(LifecycleEventArgs $args): void $object->setApiPath($apiPath); $object->setAdminPath($adminPath); } - - /** - * @return string[] - */ - public function getSubscribedEvents(): array - { - return [ - Events::postLoad, - ]; - } } diff --git a/lib/EventSubscriber/PermissionSubscriber.php b/lib/EventSubscriber/PermissionSubscriber.php index 15a05fd0..91a6adc2 100755 --- a/lib/EventSubscriber/PermissionSubscriber.php +++ b/lib/EventSubscriber/PermissionSubscriber.php @@ -4,7 +4,6 @@ namespace KejawenLab\ApiSkeleton\EventSubscriber; -use KejawenLab\ApiSkeleton\Security\Annotation\Parser; use KejawenLab\ApiSkeleton\Security\Annotation\Permission; use KejawenLab\ApiSkeleton\Security\Authorization\Ownership; use KejawenLab\ApiSkeleton\Security\Service\Authorization; @@ -18,7 +17,7 @@ */ final class PermissionSubscriber implements EventSubscriberInterface { - public function __construct(private readonly Parser $parser, private readonly Authorization $authorization, private readonly Ownership $ownership) + public function __construct(private readonly Authorization $authorization, private readonly Ownership $ownership) { } @@ -34,21 +33,21 @@ public function validate(ControllerEvent $event): void return; } - $controllerReflection = new ReflectionObject($controller); - $permission = $this->parser->parse($controllerReflection); - if (!$permission instanceof Permission) { + $attributes = $event->getAttributes(); + $permission = $attributes[Permission::class] ?? null; + if (!$permission) { return; } - $namespaceArray = explode('\\', $controllerReflection->getNamespaceName()); + $namespaceArray = explode('\\', new ReflectionObject($controller)->getNamespaceName()); $entity = array_pop($namespaceArray); - $authorize = $this->authorization->authorize($permission); + $authorize = $this->authorization->authorize($permission[0]); if (!$authorize) { throw new AccessDeniedException(); } $id = $event->getRequest()->attributes->get('id'); - if (!$permission->isOwnership()) { + if (!$permission[0]->isOwnership()) { return; } diff --git a/lib/EventSubscriber/SetFileUrlSubscriber.php b/lib/EventSubscriber/SetFileUrlSubscriber.php index cf836701..255a2a27 100755 --- a/lib/EventSubscriber/SetFileUrlSubscriber.php +++ b/lib/EventSubscriber/SetFileUrlSubscriber.php @@ -4,36 +4,24 @@ namespace KejawenLab\ApiSkeleton\EventSubscriber; -use Doctrine\Common\EventSubscriber; +use Doctrine\Bundle\DoctrineBundle\Attribute\AsEntityListener; +use Doctrine\ORM\Event\PostLoadEventArgs; use Doctrine\ORM\Events; -use Doctrine\Persistence\Event\LifecycleEventArgs; -use KejawenLab\ApiSkeleton\Media\Model\MediaInterface; +use KejawenLab\ApiSkeleton\Entity\Media as Entity; use Vich\UploaderBundle\Storage\StorageInterface; /** * @author Muhamad Surya Iksanudin */ -final class SetFileUrlSubscriber implements EventSubscriber +#[AsEntityListener(event: Events::postLoad, method: 'postLoad', entity: Entity::class)] +final class SetFileUrlSubscriber { public function __construct(private readonly StorageInterface $storage) { } - public function postLoad(LifecycleEventArgs $args): void + public function postLoad(Entity $object, PostLoadEventArgs $args): void { - $object = $args->getObject(); - if ($object instanceof MediaInterface) { - $object->setFileUrl($this->storage->resolveUri($object, MediaInterface::FILE_FIELD)); - } - } - - /** - * @return string[] - */ - public function getSubscribedEvents(): array - { - return [ - Events::postLoad, - ]; + $object->setFileUrl($this->storage->resolveUri($object, MediaInterface::FILE_FIELD)); } } diff --git a/lib/Media/AbstractStorage.php b/lib/Media/AbstractStorage.php new file mode 100644 index 00000000..03608ad7 --- /dev/null +++ b/lib/Media/AbstractStorage.php @@ -0,0 +1,85 @@ + + */ +abstract class AbstractStorage extends Base +{ + protected function doUpload(PropertyMapping $mapping, File $file, ?string $dir, string $name): ?File + { + $uploadDir = $mapping->getUploadDestination().\DIRECTORY_SEPARATOR.$dir; + + if (!\file_exists($uploadDir)) { + if (!\mkdir($uploadDir, recursive: true)) { + throw new \Exception('Could not create directory "'.$uploadDir.'"'); + } + } + if (!\is_dir($uploadDir)) { + throw new \Exception('Tried to move file to directory "'.$uploadDir.'" but it is a file'); + } + + if ($file instanceof UploadedFile) { + return $file->move($uploadDir, $name); + } + $targetPathname = $uploadDir.\DIRECTORY_SEPARATOR.$name; + if (!\copy($file->getPathname(), $targetPathname)) { + throw new \RuntimeException('Could not copy file'); + } + + return new File($targetPathname); + } + + protected function doRemove(PropertyMapping $mapping, ?string $dir, string $name): ?bool + { + $file = $this->doResolvePath($mapping, $dir, $name); + + if (!\file_exists($file) || !\unlink($file)) { + throw new \Exception('Cannot remove file '.$file); + } + + return true; + } + + protected function doResolvePath( + PropertyMapping $mapping, + ?string $dir, + string $name, + ?bool $relative = false + ): string { + $path = !empty($dir) ? $dir.\DIRECTORY_SEPARATOR.$name : $name; + + if ($relative) { + return $path; + } + + return $mapping->getUploadDestination().\DIRECTORY_SEPARATOR.$path; + } + + public function resolveUri(object|array $obj, ?string $fieldName = null, ?string $className = null): ?string + { + [$mapping, $name] = $this->getFilename($obj, $fieldName, $className); + + if (empty($name)) { + return null; + } + + $uploadDir = $this->convertWindowsDirectorySeparator($mapping->getUploadDir($obj)); + $uploadDir = empty($uploadDir) ? '' : $uploadDir.'/'; + + return \sprintf('%s/%s', $mapping->getUriPrefix(), $uploadDir.$name); + } + + private function convertWindowsDirectorySeparator(string $string): string + { + return \str_replace('\\', '/', $string); + } +} diff --git a/lib/Media/Model/MediaRepositoryInterface.php b/lib/Media/Model/MediaRepositoryInterface.php index c7523b7a..6456679d 100755 --- a/lib/Media/Model/MediaRepositoryInterface.php +++ b/lib/Media/Model/MediaRepositoryInterface.php @@ -11,5 +11,5 @@ */ interface MediaRepositoryInterface extends PaginatableRepositoryInterface { - public function findByFilename(string $fileName, ?string $folder = null): ?MediaInterface; + public function findByFilename(string $fileName, ?string $folder): ?MediaInterface; } diff --git a/lib/Media/Storage.php b/lib/Media/Storage.php index 443a94d5..089b4f24 100755 --- a/lib/Media/Storage.php +++ b/lib/Media/Storage.php @@ -9,12 +9,11 @@ use Symfony\Component\Filesystem\Filesystem; use Symfony\Component\HttpFoundation\File\UploadedFile; use Vich\UploaderBundle\Mapping\PropertyMapping; -use Vich\UploaderBundle\Storage\FileSystemStorage; /** * @author Muhamad Surya Iksanudin */ -final class Storage extends FileSystemStorage +final class Storage extends AbstractStorage { public function remove($obj, PropertyMapping $mapping, ?string $forcedFilename = null): ?bool { diff --git a/lib/Repository/AbstractRepository.php b/lib/Repository/AbstractRepository.php index 513fb43d..7a3fd39b 100755 --- a/lib/Repository/AbstractRepository.php +++ b/lib/Repository/AbstractRepository.php @@ -5,6 +5,7 @@ namespace KejawenLab\ApiSkeleton\Repository; use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; +use Doctrine\DBAL\LockMode; use Doctrine\ORM\NonUniqueResultException; use Doctrine\ORM\QueryBuilder; use Doctrine\Persistence\ManagerRegistry; @@ -30,11 +31,11 @@ public function __construct( } /** - * @return mixed|null + * @return object|null * * @throws NonUniqueResultException */ - public function find($id, $lockMode = null, $lockVersion = null) + public function find(mixed $id, LockMode|int|null $lockMode = null, ?int $lockVersion = null): ?object { $deviceId = $this->getDeviceId(); $cacheLifetime = self::MICRO_CACHE; @@ -55,7 +56,7 @@ public function find($id, $lockMode = null, $lockVersion = null) return $query->getOneOrNullResult(); } - public function findAll(): iterable + public function findAll(): array { $deviceId = $this->getDeviceId(); $cacheLifetime = self::MICRO_CACHE; @@ -80,17 +81,18 @@ public function countRecords(): int public function persist(object $object): void { - $this->_em->persist($object); + $this->getEntityManager()->persist($object); } public function remove(object $object): void { - $this->_em->remove($object); + $this->getEntityManager()->remove($object); + $this->getEntityManager()->flush(); } public function commit(): void { - $this->_em->flush(); + $this->getEntityManager()->flush(); } public function queryBuilder(string $alias): QueryBuilder diff --git a/lib/Repository/MediaRepository.php b/lib/Repository/MediaRepository.php index 54102e17..653161cd 100755 --- a/lib/Repository/MediaRepository.php +++ b/lib/Repository/MediaRepository.php @@ -26,7 +26,7 @@ public function __construct(RequestStack $requestStack, ManagerRegistry $registr parent::__construct($requestStack, $registry, Media::class); } - public function findByFilename(string $fileName, string $folder = null): ?MediaInterface + public function findByFilename(string $fileName, ?string $folder): ?MediaInterface { $deviceId = $this->getDeviceId(); $cacheLifetime = self::MICRO_CACHE; diff --git a/lib/Repository/PermissionRepository.php b/lib/Repository/PermissionRepository.php index 0c4a1ed8..11d76bf5 100755 --- a/lib/Repository/PermissionRepository.php +++ b/lib/Repository/PermissionRepository.php @@ -6,6 +6,7 @@ use DateTime; use Doctrine\Persistence\ManagerRegistry; +use Doctrine\Persistence\Proxy; use Iterator; use KejawenLab\ApiSkeleton\Entity\Permission; use KejawenLab\ApiSkeleton\Security\Model\GroupInterface; @@ -13,7 +14,6 @@ use KejawenLab\ApiSkeleton\Security\Model\PermissionInterface; use KejawenLab\ApiSkeleton\Security\Model\PermissionRepositoryInterface; use KejawenLab\ApiSkeleton\SemartApiSkeleton; -use Swoole\Coroutine; use Symfony\Component\HttpFoundation\RequestStack; /** @@ -121,7 +121,12 @@ public function findAllowedMenusByGroup(GroupInterface $group, bool $parentOnly /** @var PermissionInterface[] $permissions */ $permissions = $query->getResult(); foreach ($permissions as $permission) { - yield $permission->getMenu(); + $menu = $permission->getMenu(); + if ($menu instanceof Proxy) { + $menu->__load(); + } + + yield $menu; } } @@ -159,33 +164,34 @@ public function findAllowedChildMenusByGroupAndMenu(GroupInterface $group, MenuI /** @var PermissionInterface[] $permissions */ $permissions = $query->getResult(); foreach ($permissions as $permission) { - yield $permission->getMenu(); + $menu = $permission->getMenu(); + if ($menu instanceof Proxy) { + $menu->__load(); + } + + yield $menu; } } public function removeByGroup(GroupInterface $group): void { $queryBuilder = $this->createQueryBuilder('o'); - Coroutine::create(function () use ($queryBuilder, $group): void { - $queryBuilder->update(); - $queryBuilder->set('o.deletedAt', ':now'); - $queryBuilder->where('o.group = :group'); - $queryBuilder->setParameter('now', new DateTime()); - $queryBuilder->setParameter('group', $group); - $queryBuilder->getQuery()->execute(); - }); + $queryBuilder->update(); + $queryBuilder->set('o.deletedAt', ':now'); + $queryBuilder->where('o.group = :group'); + $queryBuilder->setParameter('now', new DateTime()); + $queryBuilder->setParameter('group', $group); + $queryBuilder->getQuery()->execute(); } public function removeByMenu(MenuInterface $menu): void { $queryBuilder = $this->createQueryBuilder('o'); - Coroutine::create(function () use ($queryBuilder, $menu): void { - $queryBuilder->update(); - $queryBuilder->set('o.deletedAt', ':now'); - $queryBuilder->where('o.menu= :menu'); - $queryBuilder->setParameter('menu', $menu); - $queryBuilder->setParameter('now', new DateTime()); - $queryBuilder->getQuery()->execute(); - }); + $queryBuilder->update(); + $queryBuilder->set('o.deletedAt', ':now'); + $queryBuilder->where('o.menu= :menu'); + $queryBuilder->setParameter('menu', $menu); + $queryBuilder->setParameter('now', new DateTime()); + $queryBuilder->getQuery()->execute(); } } diff --git a/lib/Repository/UserRepository.php b/lib/Repository/UserRepository.php index 8115951d..00cef8af 100755 --- a/lib/Repository/UserRepository.php +++ b/lib/Repository/UserRepository.php @@ -43,8 +43,8 @@ public function upgradePassword(PasswordAuthenticatedUserInterface $user, string } $user->setPassword($newHashedPassword); - $this->_em->persist($user); - $this->_em->flush(); + $this->getEntityManager()->persist($user); + $this->getEntityManager()->flush(); } public function isSupervisor(UserInterface $user, UserInterface $supervisor): bool diff --git a/lib/Security/AdminAuthenticator.php b/lib/Security/AdminAuthenticator.php index ada1d147..76b29a0d 100644 --- a/lib/Security/AdminAuthenticator.php +++ b/lib/Security/AdminAuthenticator.php @@ -21,6 +21,7 @@ use Symfony\Component\Routing\Generator\UrlGeneratorInterface; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; use Symfony\Component\Security\Core\Security; +use Symfony\Component\Security\Http\Authentication\AuthenticationUtils; use Symfony\Component\Security\Http\Authenticator\AbstractLoginFormAuthenticator; use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge; use Symfony\Component\Security\Http\Authenticator\Passport\Credentials\PasswordCredentials; @@ -46,12 +47,10 @@ public function __construct( public function authenticate(Request $request): Passport { $credentials = [ - 'username' => $request->request->get('_username', ''), - 'password' => $request->request->get('_password', ''), + 'username' => $request->getPayload()->get('_username', ''), + 'password' => $request->getPayload()->get('_password', ''), ]; - $request->getSession()->set(Security::LAST_USERNAME, $credentials['username']); - return new Passport( new UserBadge($credentials['username'], fn (string $userIdentifier): User => $this->userProviderFactory->loadUserByIdentifier($userIdentifier)), new PasswordCredentials($credentials['password']), @@ -82,6 +81,7 @@ public function onAuthenticationSuccess(Request $request, TokenInterface $token, $this->cache->deleteItem(SettingInterface::CACHE_ID_PER_PAGE_FIELD); $this->cache->deleteItem(SettingInterface::CACHE_ID_PER_PAGE); $this->cache->deleteItem(SettingInterface::CACHE_ID_MAX_API_PER_USER); + $configuration = $this->entityManager->getConfiguration(); $configuration->getQueryCache()->clear(); @@ -103,4 +103,9 @@ private function redirect(SessionInterface $session, string $firewallName): Redi return new RedirectResponse($this->urlGenerator->generate(AdminContext::ADMIN_ROUTE)); } + + public function supports(Request $request): bool + { + return AdminContext::ADMIN_ROUTE === $request->attributes->get('_route') && $request->isMethod('POST'); + } } diff --git a/lib/Security/GroupIdGenerator.php b/lib/Security/GroupIdGenerator.php index b9ccdc32..e462c6cb 100644 --- a/lib/Security/GroupIdGenerator.php +++ b/lib/Security/GroupIdGenerator.php @@ -4,7 +4,7 @@ namespace KejawenLab\ApiSkeleton\Security; -use Doctrine\ORM\EntityManager; +use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\Id\AbstractIdGenerator; use KejawenLab\ApiSkeleton\Security\Model\GroupInterface; use Ramsey\Uuid\Uuid; @@ -15,7 +15,7 @@ */ final class GroupIdGenerator extends AbstractIdGenerator { - public function generate(EntityManager $em, $entity): UuidInterface + public function generateId(EntityManagerInterface $em, object|null $entity): mixed { if (!$entity instanceof GroupInterface) { return Uuid::uuid4(); diff --git a/lib/Security/Message/PasswordHistory.php b/lib/Security/Message/PasswordHistory.php index 0140b1e6..c9b6a307 100644 --- a/lib/Security/Message/PasswordHistory.php +++ b/lib/Security/Message/PasswordHistory.php @@ -5,10 +5,12 @@ namespace KejawenLab\ApiSkeleton\Security\Message; use KejawenLab\ApiSkeleton\Security\User; +use Symfony\Component\Messenger\Attribute\AsMessage; /** * @author Muhamad Surya Iksanudin */ +#[AsMessage('async')] final class PasswordHistory { public function __construct(private readonly User $user, private readonly string $password) diff --git a/lib/Security/Service/GroupPermissionService.php b/lib/Security/Service/GroupPermissionService.php index 2aac932e..7881056f 100755 --- a/lib/Security/Service/GroupPermissionService.php +++ b/lib/Security/Service/GroupPermissionService.php @@ -10,7 +10,6 @@ use KejawenLab\ApiSkeleton\Security\Model\PermissionInitiatorInterface; use KejawenLab\ApiSkeleton\Security\Model\PermissionRemoverInterface; use KejawenLab\ApiSkeleton\Security\Model\PermissionRepositoryInterface; -use Swoole\Coroutine; /** * @author Muhamad Surya Iksanudin @@ -32,21 +31,19 @@ public function initiate(PermissionableInterface $object): void { $permissionRepository = $this->permissionRepository; foreach ($this->menuRepository->findAll() as $key => $menu) { - Coroutine::create(function () use ($permissionRepository, $object, $key, $menu): void { - if (0 === $key % 7) { - $permissionRepository->commit(); - } + if (0 === $key % 7) { + $permissionRepository->commit(); + } - $permission = $permissionRepository->findPermission($object, $menu, false); - if (null === $permission) { - $permission = new $this->class(); - } + $permission = $permissionRepository->findPermission($object, $menu, false); + if (null === $permission) { + $permission = new $this->class(); + } - $permission->setMenu($menu); - $permission->setGroup($object); + $permission->setMenu($menu); + $permission->setGroup($object); - $permissionRepository->persist($permission); - }); + $permissionRepository->persist($permission); } } diff --git a/lib/Security/Service/MenuPermissionService.php b/lib/Security/Service/MenuPermissionService.php index 4e160741..a2cc351a 100755 --- a/lib/Security/Service/MenuPermissionService.php +++ b/lib/Security/Service/MenuPermissionService.php @@ -10,7 +10,6 @@ use KejawenLab\ApiSkeleton\Security\Model\PermissionInitiatorInterface; use KejawenLab\ApiSkeleton\Security\Model\PermissionRemoverInterface; use KejawenLab\ApiSkeleton\Security\Model\PermissionRepositoryInterface; -use Swoole\Coroutine; /** * @author Muhamad Surya Iksanudin @@ -32,21 +31,19 @@ public function initiate(PermissionableInterface $object): void { $permissionRepository = $this->permissionRepository; foreach ($this->groupRepository->findAll() as $key => $group) { - Coroutine::create(function () use ($permissionRepository, $object, $key, $group): void { - if (0 === $key % 7) { - $permissionRepository->commit(); - } + if (0 === $key % 7) { + $permissionRepository->commit(); + } - $permission = $permissionRepository->findPermission($group, $object, false); - if (null === $permission) { - $permission = new $this->class(); - } + $permission = $permissionRepository->findPermission($group, $object, false); + if (null === $permission) { + $permission = new $this->class(); + } - $permission->setMenu($object); - $permission->setGroup($group); + $permission->setMenu($object); + $permission->setGroup($group); - $permissionRepository->persist($permission); - }); + $permissionRepository->persist($permission); } } diff --git a/lib/Security/Service/MenuService.php b/lib/Security/Service/MenuService.php index bea016e6..5e2bd411 100755 --- a/lib/Security/Service/MenuService.php +++ b/lib/Security/Service/MenuService.php @@ -58,7 +58,7 @@ public function hasChildMenu(MenuInterface $menu): bool public function getChildsMenu(MenuInterface $menu): iterable { - if (($group = $this->getGroup()) === null) { + if (null === $group = $this->getGroup()) { return []; } diff --git a/lib/Security/Service/PasswordHistoryService.php b/lib/Security/Service/PasswordHistoryService.php index 262a20db..6d37e448 100755 --- a/lib/Security/Service/PasswordHistoryService.php +++ b/lib/Security/Service/PasswordHistoryService.php @@ -13,13 +13,14 @@ use KejawenLab\ApiSkeleton\Security\Model\UserInterface; use KejawenLab\ApiSkeleton\Service\AbstractService; use KejawenLab\ApiSkeleton\Service\Model\ServiceInterface; -use Symfony\Component\Messenger\Handler\MessageSubscriberInterface; +use Symfony\Component\Messenger\Attribute\AsMessageHandler; use Symfony\Component\Messenger\MessageBusInterface; /** * @author Muhamad Surya Iksanudin */ -final class PasswordHistoryService extends AbstractService implements ServiceInterface, MessageSubscriberInterface +#[AsMessageHandler] +final class PasswordHistoryService extends AbstractService implements ServiceInterface { public function __construct(MessageBusInterface $messageBus, PasswordHistoryRepositoryInterface $repository, AliasHelper $aliasHelper) { @@ -43,12 +44,4 @@ public function getPasswords(UserInterface $user): iterable { return $this->repository->findPasswords($user); } - - /** - * @return Iterator - */ - public static function getHandledMessages(): iterable - { - yield PasswordHistory::class; - } } diff --git a/lib/Security/Service/PermissionService.php b/lib/Security/Service/PermissionService.php index 49f2b61f..3c75ccba 100755 --- a/lib/Security/Service/PermissionService.php +++ b/lib/Security/Service/PermissionService.php @@ -20,13 +20,14 @@ use KejawenLab\ApiSkeleton\Service\Message\EntityPersisted; use KejawenLab\ApiSkeleton\Service\Message\EntityRemoved; use KejawenLab\ApiSkeleton\Service\Model\ServiceInterface; -use Symfony\Component\Messenger\Handler\MessageSubscriberInterface; +use Symfony\Component\Messenger\Attribute\AsMessageHandler; use Symfony\Component\Messenger\MessageBusInterface; /** * @author Muhamad Surya Iksanudin */ -final class PermissionService extends AbstractService implements ServiceInterface, MessageSubscriberInterface +#[AsMessageHandler] +final class PermissionService extends AbstractService implements ServiceInterface { private const FILTER_NAME = 'semart_softdeletable'; @@ -100,15 +101,6 @@ public function getByUser(AuthInterface $user): iterable } } - /** - * @return Iterator - */ - public static function getHandledMessages(): iterable - { - yield EntityPersisted::class; - yield EntityRemoved::class; - } - private function getPermissions(GroupInterface $group, iterable $menus): iterable { return $this->repository->findPermissions($group, $menus); diff --git a/lib/Security/Service/UserService.php b/lib/Security/Service/UserService.php index 88e9508b..636ad38e 100755 --- a/lib/Security/Service/UserService.php +++ b/lib/Security/Service/UserService.php @@ -15,15 +15,15 @@ use KejawenLab\ApiSkeleton\Service\AbstractService; use KejawenLab\ApiSkeleton\Service\Message\EntityPersisted; use KejawenLab\ApiSkeleton\Service\Model\ServiceInterface; -use Swoole\Coroutine; -use Symfony\Component\Messenger\Handler\MessageSubscriberInterface; +use Symfony\Component\Messenger\Attribute\AsMessageHandler; use Symfony\Component\Messenger\MessageBusInterface; use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface; /** * @author Muhamad Surya Iksanudin */ -final class UserService extends AbstractService implements ServiceInterface, MessageSubscriberInterface +#[AsMessageHandler] +final class UserService extends AbstractService implements ServiceInterface { public function __construct( private readonly MessageBusInterface $messageBus, @@ -44,17 +44,16 @@ public function __invoke(EntityPersisted $message): void if (null !== $user->getFile()) { $mediaService = $this->mediaService; - Coroutine::create(function () use ($mediaService, $user): void { - $media = new Media(); - $media->setFolder(UserInterface::PROFILE_MEDIA_FOLDER); - $media->setHidden(true); - $media->setPublic(false); - $media->setFile($user->getFile()); - $mediaService->save($media); + $media = new Media(); + $media->setFolder(UserInterface::PROFILE_MEDIA_FOLDER); + $media->setHidden(true); + $media->setPublic(false); + $media->setFile($user->getFile()); - $user->setProfileImage($media->getFileName()); - }); + $mediaService->save($media); + + $user->setProfileImage($media->getFileName()); } $plainPassword = $user->getPlainPassword(); @@ -62,6 +61,7 @@ public function __invoke(EntityPersisted $message): void $holder = new User($user); $password = $this->passwordHasher->hashPassword($holder, $plainPassword); + $user->setPassword($password); $this->messageBus->dispatch(new PasswordHistory($holder, $password)); @@ -72,12 +72,4 @@ public function getByDeviceId(string $deviceId): ?UserInterface { return $this->repository->findByDeviceId($deviceId); } - - /** - * @return Iterator - */ - public static function getHandledMessages(): iterable - { - yield EntityPersisted::class; - } } diff --git a/lib/Service/AbstractService.php b/lib/Service/AbstractService.php index 304abaf6..70df6224 100755 --- a/lib/Service/AbstractService.php +++ b/lib/Service/AbstractService.php @@ -12,7 +12,6 @@ use KejawenLab\ApiSkeleton\Service\Model\ServiceableRepositoryInterface; use KejawenLab\ApiSkeleton\Service\Model\ServiceInterface; use Ramsey\Uuid\Uuid; -use Swoole\Coroutine; use Symfony\Component\Messenger\MessageBusInterface; /** @@ -50,22 +49,24 @@ public function save(EntityInterface $object): void { $repository = $this->repository; $bus = $this->messageBus; - Coroutine::create(function () use ($repository, $bus, $object): void { - $repository->persist($object); - $bus->dispatch(new EntityPersisted($object)); - $repository->commit(); - }); + + $repository->persist($object); + + $bus->dispatch(new EntityPersisted($object)); + + $repository->commit(); } public function remove(EntityInterface $object): void { $repository = $this->repository; $bus = $this->messageBus; - Coroutine::create(function () use ($repository, $bus, $object): void { - $repository->remove($object); - $bus->dispatch(new EntityRemoved($object)); - $repository->commit(); - }); + + $repository->remove($object); + + $bus->dispatch(new EntityRemoved($object)); + + $repository->commit(); } public function getQueryBuilder(): QueryBuilder diff --git a/lib/Service/Message/EntityPersisted.php b/lib/Service/Message/EntityPersisted.php index f57759db..885ab63d 100755 --- a/lib/Service/Message/EntityPersisted.php +++ b/lib/Service/Message/EntityPersisted.php @@ -4,9 +4,12 @@ namespace KejawenLab\ApiSkeleton\Service\Message; +use Symfony\Component\Messenger\Attribute\AsMessage; + /** * @author Muhamad Surya Iksanudin */ +#[AsMessage('sync')] class EntityPersisted { public function __construct(private readonly object $entity) diff --git a/lib/Service/Message/EntityRemoved.php b/lib/Service/Message/EntityRemoved.php index 5c10445d..fff454f6 100755 --- a/lib/Service/Message/EntityRemoved.php +++ b/lib/Service/Message/EntityRemoved.php @@ -4,9 +4,12 @@ namespace KejawenLab\ApiSkeleton\Service\Message; +use Symfony\Component\Messenger\Attribute\AsMessage; + /** * @author Muhamad Surya Iksanudin */ +#[AsMessage('async')] final class EntityRemoved extends EntityPersisted { } diff --git a/public/index.php b/public/index.php index 7dc5768a..b012b5e2 100755 --- a/public/index.php +++ b/public/index.php @@ -2,25 +2,9 @@ use KejawenLab\ApiSkeleton\CachedKernel; use KejawenLab\ApiSkeleton\Kernel; -use Swoole\Constant; $root = dirname(__DIR__); -$_SERVER['APP_RUNTIME_OPTIONS'] = [ - 'host' => '0.0.0.0', - 'port' => 9501, - 'mode' => SWOOLE_PROCESS, - 'settings' => [ - Constant::OPTION_WORKER_NUM => swoole_cpu_num() * 2, - Constant::OPTION_ENABLE_STATIC_HANDLER => true, - Constant::OPTION_DOCUMENT_ROOT => sprintf('%s/%s', $root, 'public'), - Constant::OPTION_HTTP_COMPRESSION => true, - Constant::OPTION_COMPRESSION_MIN_LENGTH => 20, - Constant::OPTION_HTTP_COMPRESSION_LEVEL => 7, - Constant::OPTION_OPEN_HTTP2_PROTOCOL => true, - ], -]; - require_once sprintf('%s/%s', $root, 'vendor/autoload_runtime.php'); return function (array $context) { diff --git a/public/plugins/overlayScrollbars/js/OverlayScrollbars.js b/public/plugins/overlayScrollbars/js/OverlayScrollbars.js index bf7c1f45..fb53fca5 100755 --- a/public/plugins/overlayScrollbars/js/OverlayScrollbars.js +++ b/public/plugins/overlayScrollbars/js/OverlayScrollbars.js @@ -1,6653 +1,6653 @@ -/*! - * OverlayScrollbars - * https://github.com/KingSora/OverlayScrollbars - * - * Version: 1.11.0 - * - * Copyright KingSora | Rene Haas. - * https://github.com/KingSora - * - * Released under the MIT license. - * Date: 29.02.2020 - */ - -(function (global, factory) { - if (typeof define === 'function' && define.amd) - define(function () { return factory(global, global.document, undefined); }); - else if (typeof module === 'object' && typeof module.exports === 'object') - module.exports = factory(global, global.document, undefined); - else - factory(global, global.document, undefined); -}(typeof window !== 'undefined' ? window : this, - function (window, document, undefined) { - 'use strict'; - var PLUGINNAME = 'OverlayScrollbars'; - var TYPES = { - o: 'object', - f: 'function', - a: 'array', - s: 'string', - b: 'boolean', - n: 'number', - u: 'undefined', - z: 'null' - //d : 'date', - //e : 'error', - //r : 'regexp', - //y : 'symbol' - }; - var LEXICON = { - c: 'class', - s: 'style', - i: 'id', - l: 'length', - p: 'prototype', - ti: 'tabindex', - oH: 'offsetHeight', - cH: 'clientHeight', - sH: 'scrollHeight', - oW: 'offsetWidth', - cW: 'clientWidth', - sW: 'scrollWidth', - hOP: 'hasOwnProperty', - bCR: 'getBoundingClientRect' - }; - var VENDORS = (function () { - //https://developer.mozilla.org/en-US/docs/Glossary/Vendor_Prefix - var jsCache = {}; - var cssCache = {}; - var cssPrefixes = ['-webkit-', '-moz-', '-o-', '-ms-']; - var jsPrefixes = ['WebKit', 'Moz', 'O', 'MS']; - function firstLetterToUpper(str) { - return str.charAt(0).toUpperCase() + str.slice(1); - } - - return { - _cssPrefixes: cssPrefixes, - _jsPrefixes: jsPrefixes, - _cssProperty: function (name) { - var result = cssCache[name]; - - if (cssCache[LEXICON.hOP](name)) - return result; - - var uppercasedName = firstLetterToUpper(name); - var elmStyle = document.createElement('div')[LEXICON.s]; - var resultPossibilities; - var i = 0; - var v; - var currVendorWithoutDashes; - - for (; i < cssPrefixes.length; i++) { - currVendorWithoutDashes = cssPrefixes[i].replace(/-/g, ''); - resultPossibilities = [ - name, //transition - cssPrefixes[i] + name, //-webkit-transition - currVendorWithoutDashes + uppercasedName, //webkitTransition - firstLetterToUpper(currVendorWithoutDashes) + uppercasedName //WebkitTransition - ]; - for (v = 0; v < resultPossibilities[LEXICON.l]; v++) { - if (elmStyle[resultPossibilities[v]] !== undefined) { - result = resultPossibilities[v]; - break; - } - } - } - - cssCache[name] = result; - return result; - }, - _jsAPI: function (name, isInterface, fallback) { - var i = 0; - var result = jsCache[name]; - - if (!jsCache[LEXICON.hOP](name)) { - result = window[name]; - for (; i < jsPrefixes[LEXICON.l]; i++) - result = result || window[(isInterface ? jsPrefixes[i] : jsPrefixes[i].toLowerCase()) + firstLetterToUpper(name)]; - jsCache[name] = result; - } - return result || fallback; - } - - } - })(); - var COMPATIBILITY = (function () { - function windowSize(x) { - return x ? window.innerWidth || document.documentElement[LEXICON.cW] || document.body[LEXICON.cW] : window.innerHeight || document.documentElement[LEXICON.cH] || document.body[LEXICON.cH]; - } - function bind(func, thisObj) { - if (typeof func != TYPES.f) { - throw "Can't bind function!"; - // closest thing possible to the ECMAScript 5 - // internal IsCallable function - //throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable'); - } - var proto = LEXICON.p; - var aArgs = Array[proto].slice.call(arguments, 2); - var fNOP = function () { }; - var fBound = function () { return func.apply(this instanceof fNOP ? this : thisObj, aArgs.concat(Array[proto].slice.call(arguments))); }; - - if (func[proto]) - fNOP[proto] = func[proto]; // Function.prototype doesn't have a prototype property - fBound[proto] = new fNOP(); - - return fBound; - } - - return { - /** - * Gets the current window width. - * @returns {Number|number} The current window width in pixel. - */ - wW: bind(windowSize, 0, true), - - /** - * Gets the current window height. - * @returns {Number|number} The current window height in pixel. - */ - wH: bind(windowSize, 0), - - /** - * Gets the MutationObserver Object or undefined if not supported. - * @returns {MutationObserver|*|undefined} The MutationsObserver Object or undefined. - */ - mO: bind(VENDORS._jsAPI, 0, 'MutationObserver', true), - - /** - * Gets the ResizeObserver Object or undefined if not supported. - * @returns {MutationObserver|*|undefined} The ResizeObserver Object or undefined. - */ - rO: bind(VENDORS._jsAPI, 0, 'ResizeObserver', true), - - /** - * Gets the RequestAnimationFrame method or it's corresponding polyfill. - * @returns {*|Function} The RequestAnimationFrame method or it's corresponding polyfill. - */ - rAF: bind(VENDORS._jsAPI, 0, 'requestAnimationFrame', false, function (func) { return window.setTimeout(func, 1000 / 60); }), - - /** - * Gets the CancelAnimationFrame method or it's corresponding polyfill. - * @returns {*|Function} The CancelAnimationFrame method or it's corresponding polyfill. - */ - cAF: bind(VENDORS._jsAPI, 0, 'cancelAnimationFrame', false, function (id) { return window.clearTimeout(id); }), - - /** - * Gets the current time. - * @returns {number} The current time. - */ - now: function () { - return Date.now && Date.now() || new Date().getTime(); - }, - - /** - * Stops the propagation of the given event. - * @param event The event of which the propagation shall be stoped. - */ - stpP: function (event) { - if (event.stopPropagation) - event.stopPropagation(); - else - event.cancelBubble = true; - }, - - /** - * Prevents the default action of the given event. - * @param event The event of which the default action shall be prevented. - */ - prvD: function (event) { - if (event.preventDefault && event.cancelable) - event.preventDefault(); - else - event.returnValue = false; - }, - - /** - * Gets the pageX and pageY values of the given mouse event. - * @param event The mouse event of which the pageX and pageX shall be got. - * @returns {{x: number, y: number}} x = pageX value, y = pageY value. - */ - page: function (event) { - event = event.originalEvent || event; - - var strPage = 'page'; - var strClient = 'client'; - var strX = 'X'; - var strY = 'Y'; - var target = event.target || event.srcElement || document; - var eventDoc = target.ownerDocument || document; - var doc = eventDoc.documentElement; - var body = eventDoc.body; - - //if touch event return return pageX/Y of it - if (event.touches !== undefined) { - var touch = event.touches[0]; - return { - x: touch[strPage + strX], - y: touch[strPage + strY] - } - } - - // Calculate pageX/Y if not native supported - if (!event[strPage + strX] && event[strClient + strX] && event[strClient + strX] != null) { - - return { - x: event[strClient + strX] + - (doc && doc.scrollLeft || body && body.scrollLeft || 0) - - (doc && doc.clientLeft || body && body.clientLeft || 0), - y: event[strClient + strY] + - (doc && doc.scrollTop || body && body.scrollTop || 0) - - (doc && doc.clientTop || body && body.clientTop || 0) - } - } - return { - x: event[strPage + strX], - y: event[strPage + strY] - }; - }, - - /** - * Gets the clicked mouse button of the given mouse event. - * @param event The mouse event of which the clicked button shal be got. - * @returns {number} The number of the clicked mouse button. (0 : none | 1 : leftButton | 2 : middleButton | 3 : rightButton) - */ - mBtn: function (event) { - var button = event.button; - if (!event.which && button !== undefined) - return (button & 1 ? 1 : (button & 2 ? 3 : (button & 4 ? 2 : 0))); - else - return event.which; - }, - - /** - * Checks whether a item is in the given array and returns its index. - * @param item The item of which the position in the array shall be determined. - * @param arr The array. - * @returns {number} The zero based index of the item or -1 if the item isn't in the array. - */ - inA: function (item, arr) { - for (var i = 0; i < arr[LEXICON.l]; i++) - //Sometiems in IE a "SCRIPT70" Permission denied error occurs if HTML elements in a iFrame are compared - try { - if (arr[i] === item) - return i; - } - catch (e) { } - return -1; - }, - - /** - * Returns true if the given value is a array. - * @param arr The potential array. - * @returns {boolean} True if the given value is a array, false otherwise. - */ - isA: function (arr) { - var def = Array.isArray; - return def ? def(arr) : this.type(arr) == TYPES.a; - }, - - /** - * Determine the internal JavaScript [[Class]] of the given object. - * @param obj The object of which the type shall be determined. - * @returns {string} The type of the given object. - */ - type: function (obj) { - if (obj === undefined) - return obj + ''; - if (obj === null) - return obj + ''; - return Object[LEXICON.p].toString.call(obj).replace(/^\[object (.+)\]$/, '$1').toLowerCase(); - }, - - - bind: bind - - /** - * Gets the vendor-prefixed CSS property by the given name. - * For example the given name is "transform" and you're using a old Firefox browser then the returned value would be "-moz-transform". - * If the browser doesn't need a vendor-prefix, then the returned string is the given name. - * If the browser doesn't support the given property name at all (not even with a vendor-prefix) the returned value is null. - * @param propName The unprefixed CSS property name. - * @returns {string|null} The vendor-prefixed CSS property or null if the browser doesn't support the given CSS property. - - cssProp: function(propName) { - return VENDORS._cssProperty(propName); - } - */ - } - })(); - - var MATH = Math; - var JQUERY = window.jQuery; - var EASING = (function () { - var _easingsMath = { - p: MATH.PI, - c: MATH.cos, - s: MATH.sin, - w: MATH.pow, - t: MATH.sqrt, - n: MATH.asin, - a: MATH.abs, - o: 1.70158 - }; - - /* - x : current percent (0 - 1), - t : current time (duration * percent), - b : start value (from), - c : end value (to), - d : duration - - easingName : function(x, t, b, c, d) { return easedValue; } - */ - - return { - swing: function (x, t, b, c, d) { - return 0.5 - _easingsMath.c(x * _easingsMath.p) / 2; - }, - linear: function (x, t, b, c, d) { - return x; - }, - easeInQuad: function (x, t, b, c, d) { - return c * (t /= d) * t + b; - }, - easeOutQuad: function (x, t, b, c, d) { - return -c * (t /= d) * (t - 2) + b; - }, - easeInOutQuad: function (x, t, b, c, d) { - return ((t /= d / 2) < 1) ? c / 2 * t * t + b : -c / 2 * ((--t) * (t - 2) - 1) + b; - }, - easeInCubic: function (x, t, b, c, d) { - return c * (t /= d) * t * t + b; - }, - easeOutCubic: function (x, t, b, c, d) { - return c * ((t = t / d - 1) * t * t + 1) + b; - }, - easeInOutCubic: function (x, t, b, c, d) { - return ((t /= d / 2) < 1) ? c / 2 * t * t * t + b : c / 2 * ((t -= 2) * t * t + 2) + b; - }, - easeInQuart: function (x, t, b, c, d) { - return c * (t /= d) * t * t * t + b; - }, - easeOutQuart: function (x, t, b, c, d) { - return -c * ((t = t / d - 1) * t * t * t - 1) + b; - }, - easeInOutQuart: function (x, t, b, c, d) { - return ((t /= d / 2) < 1) ? c / 2 * t * t * t * t + b : -c / 2 * ((t -= 2) * t * t * t - 2) + b; - }, - easeInQuint: function (x, t, b, c, d) { - return c * (t /= d) * t * t * t * t + b; - }, - easeOutQuint: function (x, t, b, c, d) { - return c * ((t = t / d - 1) * t * t * t * t + 1) + b; - }, - easeInOutQuint: function (x, t, b, c, d) { - return ((t /= d / 2) < 1) ? c / 2 * t * t * t * t * t + b : c / 2 * ((t -= 2) * t * t * t * t + 2) + b; - }, - easeInSine: function (x, t, b, c, d) { - return -c * _easingsMath.c(t / d * (_easingsMath.p / 2)) + c + b; - }, - easeOutSine: function (x, t, b, c, d) { - return c * _easingsMath.s(t / d * (_easingsMath.p / 2)) + b; - }, - easeInOutSine: function (x, t, b, c, d) { - return -c / 2 * (_easingsMath.c(_easingsMath.p * t / d) - 1) + b; - }, - easeInExpo: function (x, t, b, c, d) { - return (t == 0) ? b : c * _easingsMath.w(2, 10 * (t / d - 1)) + b; - }, - easeOutExpo: function (x, t, b, c, d) { - return (t == d) ? b + c : c * (-_easingsMath.w(2, -10 * t / d) + 1) + b; - }, - easeInOutExpo: function (x, t, b, c, d) { - if (t == 0) return b; - if (t == d) return b + c; - if ((t /= d / 2) < 1) return c / 2 * _easingsMath.w(2, 10 * (t - 1)) + b; - return c / 2 * (-_easingsMath.w(2, -10 * --t) + 2) + b; - }, - easeInCirc: function (x, t, b, c, d) { - return -c * (_easingsMath.t(1 - (t /= d) * t) - 1) + b; - }, - easeOutCirc: function (x, t, b, c, d) { - return c * _easingsMath.t(1 - (t = t / d - 1) * t) + b; - }, - easeInOutCirc: function (x, t, b, c, d) { - return ((t /= d / 2) < 1) ? -c / 2 * (_easingsMath.t(1 - t * t) - 1) + b : c / 2 * (_easingsMath.t(1 - (t -= 2) * t) + 1) + b; - }, - easeInElastic: function (x, t, b, c, d) { - var s = _easingsMath.o; var p = 0; var a = c; - if (t == 0) return b; if ((t /= d) == 1) return b + c; if (!p) p = d * .3; - if (a < _easingsMath.a(c)) { a = c; s = p / 4; } - else s = p / (2 * _easingsMath.p) * _easingsMath.n(c / a); - return -(a * _easingsMath.w(2, 10 * (t -= 1)) * _easingsMath.s((t * d - s) * (2 * _easingsMath.p) / p)) + b; - }, - easeOutElastic: function (x, t, b, c, d) { - var s = _easingsMath.o; var p = 0; var a = c; - if (t == 0) return b; - if ((t /= d) == 1) return b + c; - if (!p) p = d * .3; - if (a < _easingsMath.a(c)) { a = c; s = p / 4; } - else s = p / (2 * _easingsMath.p) * _easingsMath.n(c / a); - return a * _easingsMath.w(2, -10 * t) * _easingsMath.s((t * d - s) * (2 * _easingsMath.p) / p) + c + b; - }, - easeInOutElastic: function (x, t, b, c, d) { - var s = _easingsMath.o; var p = 0; var a = c; - if (t == 0) return b; - if ((t /= d / 2) == 2) return b + c; - if (!p) p = d * (.3 * 1.5); - if (a < _easingsMath.a(c)) { a = c; s = p / 4; } - else s = p / (2 * _easingsMath.p) * _easingsMath.n(c / a); - if (t < 1) return -.5 * (a * _easingsMath.w(2, 10 * (t -= 1)) * _easingsMath.s((t * d - s) * (2 * _easingsMath.p) / p)) + b; - return a * _easingsMath.w(2, -10 * (t -= 1)) * _easingsMath.s((t * d - s) * (2 * _easingsMath.p) / p) * .5 + c + b; - }, - easeInBack: function (x, t, b, c, d, s) { - s = s || _easingsMath.o; - return c * (t /= d) * t * ((s + 1) * t - s) + b; - }, - easeOutBack: function (x, t, b, c, d, s) { - s = s || _easingsMath.o; - return c * ((t = t / d - 1) * t * ((s + 1) * t + s) + 1) + b; - }, - easeInOutBack: function (x, t, b, c, d, s) { - s = s || _easingsMath.o; - return ((t /= d / 2) < 1) ? c / 2 * (t * t * (((s *= (1.525)) + 1) * t - s)) + b : c / 2 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2) + b; - }, - easeInBounce: function (x, t, b, c, d) { - return c - this.easeOutBounce(x, d - t, 0, c, d) + b; - }, - easeOutBounce: function (x, t, b, c, d) { - var o = 7.5625; - if ((t /= d) < (1 / 2.75)) { - return c * (o * t * t) + b; - } else if (t < (2 / 2.75)) { - return c * (o * (t -= (1.5 / 2.75)) * t + .75) + b; - } else if (t < (2.5 / 2.75)) { - return c * (o * (t -= (2.25 / 2.75)) * t + .9375) + b; - } else { - return c * (o * (t -= (2.625 / 2.75)) * t + .984375) + b; - } - }, - easeInOutBounce: function (x, t, b, c, d) { - return (t < d / 2) ? this.easeInBounce(x, t * 2, 0, c, d) * .5 + b : this.easeOutBounce(x, t * 2 - d, 0, c, d) * .5 + c * .5 + b; - } - }; - /* - * - * TERMS OF USE - EASING EQUATIONS - * - * Open source under the BSD License. - * - * Copyright © 2001 Robert Penner - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * Neither the name of the author nor the names of contributors may be used to endorse - * or promote products derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - })(); - var FRAMEWORK = (function () { - var _rnothtmlwhite = (/[^\x20\t\r\n\f]+/g); - var _strSpace = ' '; - var _strEmpty = ''; - var _strScrollLeft = 'scrollLeft'; - var _strScrollTop = 'scrollTop'; - var _animations = []; - var _type = COMPATIBILITY.type; - var _cssNumber = { - animationIterationCount: true, - columnCount: true, - fillOpacity: true, - flexGrow: true, - flexShrink: true, - fontWeight: true, - lineHeight: true, - opacity: true, - order: true, - orphans: true, - widows: true, - zIndex: true, - zoom: true - }; - - function extend() { - var src, copyIsArray, copy, name, options, clone, target = arguments[0] || {}, - i = 1, - length = arguments[LEXICON.l], - deep = false; - - // Handle a deep copy situation - if (_type(target) == TYPES.b) { - deep = target; - target = arguments[1] || {}; - // skip the boolean and the target - i = 2; - } - - // Handle case when target is a string or something (possible in deep copy) - if (_type(target) != TYPES.o && !_type(target) == TYPES.f) { - target = {}; - } - - // extend jQuery itself if only one argument is passed - if (length === i) { - target = FakejQuery; - --i; - } - - for (; i < length; i++) { - // Only deal with non-null/undefined values - if ((options = arguments[i]) != null) { - // Extend the base object - for (name in options) { - src = target[name]; - copy = options[name]; - - // Prevent never-ending loop - if (target === copy) { - continue; - } - - // Recurse if we're merging plain objects or arrays - if (deep && copy && (isPlainObject(copy) || (copyIsArray = COMPATIBILITY.isA(copy)))) { - if (copyIsArray) { - copyIsArray = false; - clone = src && COMPATIBILITY.isA(src) ? src : []; - - } else { - clone = src && isPlainObject(src) ? src : {}; - } - - // Never move original objects, clone them - target[name] = extend(deep, clone, copy); - - // Don't bring in undefined values - } else if (copy !== undefined) { - target[name] = copy; - } - } - } - } - - // Return the modified object - return target; - }; - - function inArray(item, arr, fromIndex) { - for (var i = fromIndex || 0; i < arr[LEXICON.l]; i++) - if (arr[i] === item) - return i; - return -1; - } - - function isFunction(obj) { - return _type(obj) == TYPES.f; - }; - - function isEmptyObject(obj) { - for (var name in obj) - return false; - return true; - }; - - function isPlainObject(obj) { - if (!obj || _type(obj) != TYPES.o) - return false; - - var key; - var proto = LEXICON.p; - var hasOwnProperty = Object[proto].hasOwnProperty; - var hasOwnConstructor = hasOwnProperty.call(obj, 'constructor'); - var hasIsPrototypeOf = obj.constructor && obj.constructor[proto] && hasOwnProperty.call(obj.constructor[proto], 'isPrototypeOf'); - - if (obj.constructor && !hasOwnConstructor && !hasIsPrototypeOf) { - return false; - } - - - for (key in obj) { /**/ } - - return _type(key) == TYPES.u || hasOwnProperty.call(obj, key); - }; - - function each(obj, callback) { - var i = 0; - - if (isArrayLike(obj)) { - for (; i < obj[LEXICON.l]; i++) { - if (callback.call(obj[i], i, obj[i]) === false) - break; - } - } - else { - for (i in obj) { - if (callback.call(obj[i], i, obj[i]) === false) - break; - } - } - - return obj; - }; - - function isArrayLike(obj) { - var length = !!obj && [LEXICON.l] in obj && obj[LEXICON.l]; - var t = _type(obj); - return isFunction(t) ? false : (t == TYPES.a || length === 0 || _type(length) == TYPES.n && length > 0 && (length - 1) in obj); - } - - function stripAndCollapse(value) { - var tokens = value.match(_rnothtmlwhite) || []; - return tokens.join(_strSpace); - } - - function matches(elem, selector) { - var nodeList = (elem.parentNode || document).querySelectorAll(selector) || []; - var i = nodeList[LEXICON.l]; - - while (i--) - if (nodeList[i] == elem) - return true; - - return false; - } - - function insertAdjacentElement(el, strategy, child) { - if (_type(child) == TYPES.a) { - for (var i = 0; i < child[LEXICON.l]; i++) - insertAdjacentElement(el, strategy, child[i]); - } - else if (_type(child) == TYPES.s) - el.insertAdjacentHTML(strategy, child); - else - el.insertAdjacentElement(strategy, child.nodeType ? child : child[0]); - } - - function setCSSVal(el, prop, val) { - try { - if (el[LEXICON.s][prop] !== undefined) - el[LEXICON.s][prop] = parseCSSVal(prop, val); - } catch (e) { } - } - - function parseCSSVal(prop, val) { - if (!_cssNumber[prop.toLowerCase()] && _type(val) == TYPES.n) - val += 'px'; - return val; - } - - function startNextAnimationInQ(animObj, removeFromQ) { - var index; - var nextAnim; - if (removeFromQ !== false) - animObj.q.splice(0, 1); - if (animObj.q[LEXICON.l] > 0) { - nextAnim = animObj.q[0]; - animate(animObj.el, nextAnim.props, nextAnim.duration, nextAnim.easing, nextAnim.complete, true); - } - else { - index = inArray(animObj, _animations); - if (index > -1) - _animations.splice(index, 1); - } - } - - function setAnimationValue(el, prop, value) { - if (prop === _strScrollLeft || prop === _strScrollTop) - el[prop] = value; - else - setCSSVal(el, prop, value); - } - - function animate(el, props, options, easing, complete, guaranteedNext) { - var hasOptions = isPlainObject(options); - var from = {}; - var to = {}; - var i = 0; - var key; - var animObj; - var start; - var progress; - var step; - var specialEasing; - var duration; - if (hasOptions) { - easing = options.easing; - start = options.start; - progress = options.progress; - step = options.step; - specialEasing = options.specialEasing; - complete = options.complete; - duration = options.duration; - } - else - duration = options; - specialEasing = specialEasing || {}; - duration = duration || 400; - easing = easing || 'swing'; - guaranteedNext = guaranteedNext || false; - - for (; i < _animations[LEXICON.l]; i++) { - if (_animations[i].el === el) { - animObj = _animations[i]; - break; - } - } - - if (!animObj) { - animObj = { - el: el, - q: [] - }; - _animations.push(animObj); - } - - for (key in props) { - if (key === _strScrollLeft || key === _strScrollTop) - from[key] = el[key]; - else - from[key] = FakejQuery(el).css(key); - } - - for (key in from) { - if (from[key] !== props[key] && props[key] !== undefined) - to[key] = props[key]; - } - - if (!isEmptyObject(to)) { - var timeNow; - var end; - var percent; - var fromVal; - var toVal; - var easedVal; - var timeStart; - var frame; - var elapsed; - var qPos = guaranteedNext ? 0 : inArray(qObj, animObj.q); - var qObj = { - props: to, - duration: hasOptions ? options : duration, - easing: easing, - complete: complete - }; - if (qPos === -1) { - qPos = animObj.q[LEXICON.l]; - animObj.q.push(qObj); - } - - if (qPos === 0) { - if (duration > 0) { - timeStart = COMPATIBILITY.now(); - frame = function () { - timeNow = COMPATIBILITY.now(); - elapsed = (timeNow - timeStart); - end = qObj.stop || elapsed >= duration; - percent = 1 - ((MATH.max(0, timeStart + duration - timeNow) / duration) || 0); - - for (key in to) { - fromVal = parseFloat(from[key]); - toVal = parseFloat(to[key]); - easedVal = (toVal - fromVal) * EASING[specialEasing[key] || easing](percent, percent * duration, 0, 1, duration) + fromVal; - setAnimationValue(el, key, easedVal); - if (isFunction(step)) { - step(easedVal, { - elem: el, - prop: key, - start: fromVal, - now: easedVal, - end: toVal, - pos: percent, - options: { - easing: easing, - speacialEasing: specialEasing, - duration: duration, - complete: complete, - step: step - }, - startTime: timeStart - }); - } - } - - if (isFunction(progress)) - progress({}, percent, MATH.max(0, duration - elapsed)); - - if (end) { - startNextAnimationInQ(animObj); - if (isFunction(complete)) - complete(); - } - else - qObj.frame = COMPATIBILITY.rAF()(frame); - }; - qObj.frame = COMPATIBILITY.rAF()(frame); - } - else { - for (key in to) - setAnimationValue(el, key, to[key]); - startNextAnimationInQ(animObj); - } - } - } - else if (guaranteedNext) - startNextAnimationInQ(animObj); - } - - function stop(el, clearQ, jumpToEnd) { - var animObj; - var qObj; - var key; - var i = 0; - for (; i < _animations[LEXICON.l]; i++) { - animObj = _animations[i]; - if (animObj.el === el) { - if (animObj.q[LEXICON.l] > 0) { - qObj = animObj.q[0]; - qObj.stop = true; - COMPATIBILITY.cAF()(qObj.frame); - animObj.q.splice(0, 1); - - if (jumpToEnd) - for (key in qObj.props) - setAnimationValue(el, key, qObj.props[key]); - - if (clearQ) - animObj.q = []; - else - startNextAnimationInQ(animObj, false); - } - break; - } - } - } - - function elementIsVisible(el) { - return !!(el[LEXICON.oW] || el[LEXICON.oH] || el.getClientRects()[LEXICON.l]); - } - - function FakejQuery(selector) { - if (arguments[LEXICON.l] === 0) - return this; - - var base = new FakejQuery(); - var elements = selector; - var i = 0; - var elms; - var el; - - if (_type(selector) == TYPES.s) { - elements = []; - if (selector.charAt(0) === '<') { - el = document.createElement('div'); - el.innerHTML = selector; - elms = el.children; - } - else { - elms = document.querySelectorAll(selector); - } - - for (; i < elms[LEXICON.l]; i++) - elements.push(elms[i]); - } - - if (elements) { - if (_type(elements) != TYPES.s && (!isArrayLike(elements) || elements === window || elements === elements.self)) - elements = [elements]; - - for (i = 0; i < elements[LEXICON.l]; i++) - base[i] = elements[i]; - - base[LEXICON.l] = elements[LEXICON.l]; - } - - return base; - }; - - FakejQuery[LEXICON.p] = { - - //EVENTS: - - on: function (eventName, handler) { - eventName = (eventName || _strEmpty).match(_rnothtmlwhite) || [_strEmpty]; - - var eventNameLength = eventName[LEXICON.l]; - var i = 0; - var el; - return this.each(function () { - el = this; - try { - if (el.addEventListener) { - for (; i < eventNameLength; i++) - el.addEventListener(eventName[i], handler); - } - else if (el.detachEvent) { - for (; i < eventNameLength; i++) - el.attachEvent('on' + eventName[i], handler); - } - } catch (e) { } - }); - }, - - off: function (eventName, handler) { - eventName = (eventName || _strEmpty).match(_rnothtmlwhite) || [_strEmpty]; - - var eventNameLength = eventName[LEXICON.l]; - var i = 0; - var el; - return this.each(function () { - el = this; - try { - if (el.removeEventListener) { - for (; i < eventNameLength; i++) - el.removeEventListener(eventName[i], handler); - } - else if (el.detachEvent) { - for (; i < eventNameLength; i++) - el.detachEvent('on' + eventName[i], handler); - } - } catch (e) { } - }); - }, - - one: function (eventName, handler) { - eventName = (eventName || _strEmpty).match(_rnothtmlwhite) || [_strEmpty]; - return this.each(function () { - var el = FakejQuery(this); - FakejQuery.each(eventName, function (i, oneEventName) { - var oneHandler = function (e) { - handler.call(this, e); - el.off(oneEventName, oneHandler); - }; - el.on(oneEventName, oneHandler); - }); - }); - }, - - trigger: function (eventName) { - var el; - var event; - return this.each(function () { - el = this; - if (document.createEvent) { - event = document.createEvent('HTMLEvents'); - event.initEvent(eventName, true, false); - el.dispatchEvent(event); - } - else { - el.fireEvent('on' + eventName); - } - }); - }, - - //DOM NODE INSERTING / REMOVING: - - append: function (child) { - return this.each(function () { insertAdjacentElement(this, 'beforeend', child); }); - }, - - prepend: function (child) { - return this.each(function () { insertAdjacentElement(this, 'afterbegin', child); }); - }, - - before: function (child) { - return this.each(function () { insertAdjacentElement(this, 'beforebegin', child); }); - }, - - after: function (child) { - return this.each(function () { insertAdjacentElement(this, 'afterend', child); }); - }, - - remove: function () { - return this.each(function () { - var el = this; - var parentNode = el.parentNode; - if (parentNode != null) - parentNode.removeChild(el); - }); - }, - - unwrap: function () { - var parents = []; - var i; - var el; - var parent; - - this.each(function () { - parent = this.parentNode; - if (inArray(parent, parents) === - 1) - parents.push(parent); - }); - - for (i = 0; i < parents[LEXICON.l]; i++) { - el = parents[i]; - parent = el.parentNode; - while (el.firstChild) - parent.insertBefore(el.firstChild, el); - parent.removeChild(el); - } - - return this; - }, - - wrapAll: function (wrapperHTML) { - var i; - var nodes = this; - var wrapper = FakejQuery(wrapperHTML)[0]; - var deepest = wrapper; - var parent = nodes[0].parentNode; - var previousSibling = nodes[0].previousSibling; - while (deepest.childNodes[LEXICON.l] > 0) - deepest = deepest.childNodes[0]; - - for (i = 0; nodes[LEXICON.l] - i; deepest.firstChild === nodes[0] && i++) - deepest.appendChild(nodes[i]); - - var nextSibling = previousSibling ? previousSibling.nextSibling : parent.firstChild; - parent.insertBefore(wrapper, nextSibling); - - return this; - }, - - wrapInner: function (wrapperHTML) { - return this.each(function () { - var el = FakejQuery(this); - var contents = el.contents(); - - if (contents[LEXICON.l]) - contents.wrapAll(wrapperHTML); - else - el.append(wrapperHTML); - }); - }, - - wrap: function (wrapperHTML) { - return this.each(function () { FakejQuery(this).wrapAll(wrapperHTML); }); - }, - - - //DOM NODE MANIPULATION / INFORMATION: - - css: function (styles, val) { - var el; - var key; - var cptStyle; - var getCptStyle = window.getComputedStyle; - if (_type(styles) == TYPES.s) { - if (val === undefined) { - el = this[0]; - cptStyle = getCptStyle ? getCptStyle(el, null) : el.currentStyle[styles]; - - //https://bugzilla.mozilla.org/show_bug.cgi?id=548397 can be null sometimes if iframe with display: none (firefox only!) - return getCptStyle ? cptStyle != null ? cptStyle.getPropertyValue(styles) : el[LEXICON.s][styles] : cptStyle; - } - else { - return this.each(function () { - setCSSVal(this, styles, val); - }); - } - } - else { - return this.each(function () { - for (key in styles) - setCSSVal(this, key, styles[key]); - }); - } - }, - - hasClass: function (className) { - var elem, i = 0; - var classNamePrepared = _strSpace + className + _strSpace; - var classList; - - while ((elem = this[i++])) { - classList = elem.classList; - if (classList && classList.contains(className)) - return true; - else if (elem.nodeType === 1 && (_strSpace + stripAndCollapse(elem.className + _strEmpty) + _strSpace).indexOf(classNamePrepared) > -1) - return true; - } - - return false; - }, - - addClass: function (className) { - var classes; - var elem; - var cur; - var curValue; - var clazz; - var finalValue; - var supportClassList; - var elmClassList; - var i = 0; - var v = 0; - - if (className) { - classes = className.match(_rnothtmlwhite) || []; - - while ((elem = this[i++])) { - elmClassList = elem.classList; - if (supportClassList === undefined) - supportClassList = elmClassList !== undefined; - - if (supportClassList) { - while ((clazz = classes[v++])) - elmClassList.add(clazz); - } - else { - curValue = elem.className + _strEmpty; - cur = elem.nodeType === 1 && (_strSpace + stripAndCollapse(curValue) + _strSpace); - - if (cur) { - while ((clazz = classes[v++])) - if (cur.indexOf(_strSpace + clazz + _strSpace) < 0) - cur += clazz + _strSpace; - - finalValue = stripAndCollapse(cur); - if (curValue !== finalValue) - elem.className = finalValue; - } - } - } - } - - return this; - }, - - removeClass: function (className) { - var classes; - var elem; - var cur; - var curValue; - var clazz; - var finalValue; - var supportClassList; - var elmClassList; - var i = 0; - var v = 0; - - if (className) { - classes = className.match(_rnothtmlwhite) || []; - - while ((elem = this[i++])) { - elmClassList = elem.classList; - if (supportClassList === undefined) - supportClassList = elmClassList !== undefined; - - if (supportClassList) { - while ((clazz = classes[v++])) - elmClassList.remove(clazz); - } - else { - curValue = elem.className + _strEmpty; - cur = elem.nodeType === 1 && (_strSpace + stripAndCollapse(curValue) + _strSpace); - - if (cur) { - while ((clazz = classes[v++])) - while (cur.indexOf(_strSpace + clazz + _strSpace) > -1) - cur = cur.replace(_strSpace + clazz + _strSpace, _strSpace); - - finalValue = stripAndCollapse(cur); - if (curValue !== finalValue) - elem.className = finalValue; - } - } - } - } - - return this; - }, - - hide: function () { - return this.each(function () { this[LEXICON.s].display = 'none'; }); - }, - - show: function () { - return this.each(function () { this[LEXICON.s].display = 'block'; }); - }, - - attr: function (attrName, value) { - var i = 0; - var el; - while (el = this[i++]) { - if (value === undefined) - return el.getAttribute(attrName); - el.setAttribute(attrName, value); - } - return this; - }, - - removeAttr: function (attrName) { - return this.each(function () { this.removeAttribute(attrName); }); - }, - - offset: function () { - var el = this[0]; - var rect = el[LEXICON.bCR](); - var scrollLeft = window.pageXOffset || document.documentElement[_strScrollLeft]; - var scrollTop = window.pageYOffset || document.documentElement[_strScrollTop]; - return { - top: rect.top + scrollTop, - left: rect.left + scrollLeft - }; - }, - - position: function () { - var el = this[0]; - return { - top: el.offsetTop, - left: el.offsetLeft - }; - }, - - scrollLeft: function (value) { - var i = 0; - var el; - while (el = this[i++]) { - if (value === undefined) - return el[_strScrollLeft]; - el[_strScrollLeft] = value; - } - return this; - }, - - scrollTop: function (value) { - var i = 0; - var el; - while (el = this[i++]) { - if (value === undefined) - return el[_strScrollTop]; - el[_strScrollTop] = value; - } - return this; - }, - - val: function (value) { - var el = this[0]; - if (!value) - return el.value; - el.value = value; - return this; - }, - - - //DOM TRAVERSAL / FILTERING: - - first: function () { - return this.eq(0); - }, - - last: function () { - return this.eq(-1); - }, - - eq: function (index) { - return FakejQuery(this[index >= 0 ? index : this[LEXICON.l] + index]); - }, - - find: function (selector) { - var children = []; - var i; - this.each(function () { - var el = this; - var ch = el.querySelectorAll(selector); - for (i = 0; i < ch[LEXICON.l]; i++) - children.push(ch[i]); - }); - return FakejQuery(children); - }, - - children: function (selector) { - var children = []; - var el; - var ch; - var i; - - this.each(function () { - ch = this.children; - for (i = 0; i < ch[LEXICON.l]; i++) { - el = ch[i]; - if (selector) { - if ((el.matches && el.matches(selector)) || matches(el, selector)) - children.push(el); - } - else - children.push(el); - } - }); - return FakejQuery(children); - }, - - parent: function (selector) { - var parents = []; - var parent; - this.each(function () { - parent = this.parentNode; - if (selector ? FakejQuery(parent).is(selector) : true) - parents.push(parent); - }); - return FakejQuery(parents); - }, - - is: function (selector) { - - var el; - var i; - for (i = 0; i < this[LEXICON.l]; i++) { - el = this[i]; - if (selector === ':visible') - return elementIsVisible(el); - if (selector === ':hidden') - return !elementIsVisible(el); - if ((el.matches && el.matches(selector)) || matches(el, selector)) - return true; - } - return false; - }, - - contents: function () { - var contents = []; - var childs; - var i; - - this.each(function () { - childs = this.childNodes; - for (i = 0; i < childs[LEXICON.l]; i++) - contents.push(childs[i]); - }); - - return FakejQuery(contents); - }, - - each: function (callback) { - return each(this, callback); - }, - - - //ANIMATION: - - animate: function (props, duration, easing, complete) { - return this.each(function () { animate(this, props, duration, easing, complete); }); - }, - - stop: function (clearQ, jump) { - return this.each(function () { stop(this, clearQ, jump); }); - } - }; - - extend(FakejQuery, { - extend: extend, - inArray: inArray, - isEmptyObject: isEmptyObject, - isPlainObject: isPlainObject, - each: each - }); - - return FakejQuery; - })(); - var INSTANCES = (function () { - var _targets = []; - var _instancePropertyString = '__overlayScrollbars__'; - - /** - * Register, unregister or get a certain (or all) instances. - * Register: Pass the target and the instance. - * Unregister: Pass the target and null. - * Get Instance: Pass the target from which the instance shall be got. - * Get Targets: Pass no arguments. - * @param target The target to which the instance shall be registered / from which the instance shall be unregistered / the instance shall be got - * @param instance The instance. - * @returns {*|void} Returns the instance from the given target. - */ - return function (target, instance) { - var argLen = arguments[LEXICON.l]; - if (argLen < 1) { - //return all targets - return _targets; - } - else { - if (instance) { - //register instance - target[_instancePropertyString] = instance; - _targets.push(target); - } - else { - var index = COMPATIBILITY.inA(target, _targets); - if (index > -1) { - if (argLen > 1) { - //unregister instance - delete target[_instancePropertyString]; - _targets.splice(index, 1); - } - else { - //get instance from target - return _targets[index][_instancePropertyString]; - } - } - } - } - } - })(); - var PLUGIN = (function () { - var _plugin; - var _pluginsGlobals; - var _pluginsAutoUpdateLoop; - var _pluginsExtensions = []; - var _pluginsOptions = (function () { - var type = COMPATIBILITY.type; - var possibleTemplateTypes = [ - TYPES.b, //boolean - TYPES.n, //number - TYPES.s, //string - TYPES.a, //array - TYPES.o, //object - TYPES.f, //function - TYPES.z //null - ]; - var restrictedStringsSplit = ' '; - var restrictedStringsPossibilitiesSplit = ':'; - var classNameAllowedValues = [TYPES.z, TYPES.s]; - var numberAllowedValues = TYPES.n; - var booleanNullAllowedValues = [TYPES.z, TYPES.b]; - var booleanTrueTemplate = [true, TYPES.b]; - var booleanFalseTemplate = [false, TYPES.b]; - var callbackTemplate = [null, [TYPES.z, TYPES.f]]; - var inheritedAttrsTemplate = [['style', 'class'], [TYPES.s, TYPES.a, TYPES.z]]; - var resizeAllowedValues = 'n:none b:both h:horizontal v:vertical'; - var overflowBehaviorAllowedValues = 'v-h:visible-hidden v-s:visible-scroll s:scroll h:hidden'; - var scrollbarsVisibilityAllowedValues = 'v:visible h:hidden a:auto'; - var scrollbarsAutoHideAllowedValues = 'n:never s:scroll l:leave m:move'; - var optionsDefaultsAndTemplate = { - className: ['os-theme-dark', classNameAllowedValues], //null || string - resize: ['none', resizeAllowedValues], //none || both || horizontal || vertical || n || b || h || v - sizeAutoCapable: booleanTrueTemplate, //true || false - clipAlways: booleanTrueTemplate, //true || false - normalizeRTL: booleanTrueTemplate, //true || false - paddingAbsolute: booleanFalseTemplate, //true || false - autoUpdate: [null, booleanNullAllowedValues], //true || false || null - autoUpdateInterval: [33, numberAllowedValues], //number - nativeScrollbarsOverlaid: { - showNativeScrollbars: booleanFalseTemplate, //true || false - initialize: booleanTrueTemplate //true || false - }, - overflowBehavior: { - x: ['scroll', overflowBehaviorAllowedValues], //visible-hidden || visible-scroll || hidden || scroll || v-h || v-s || h || s - y: ['scroll', overflowBehaviorAllowedValues] //visible-hidden || visible-scroll || hidden || scroll || v-h || v-s || h || s - }, - scrollbars: { - visibility: ['auto', scrollbarsVisibilityAllowedValues], //visible || hidden || auto || v || h || a - autoHide: ['never', scrollbarsAutoHideAllowedValues], //never || scroll || leave || move || n || s || l || m - autoHideDelay: [800, numberAllowedValues], //number - dragScrolling: booleanTrueTemplate, //true || false - clickScrolling: booleanFalseTemplate, //true || false - touchSupport: booleanTrueTemplate, //true || false - snapHandle: booleanFalseTemplate //true || false - }, - textarea: { - dynWidth: booleanFalseTemplate, //true || false - dynHeight: booleanFalseTemplate, //true || false - inheritedAttrs: inheritedAttrsTemplate //string || array || null - }, - callbacks: { - onInitialized: callbackTemplate, //null || function - onInitializationWithdrawn: callbackTemplate, //null || function - onDestroyed: callbackTemplate, //null || function - onScrollStart: callbackTemplate, //null || function - onScroll: callbackTemplate, //null || function - onScrollStop: callbackTemplate, //null || function - onOverflowChanged: callbackTemplate, //null || function - onOverflowAmountChanged: callbackTemplate, //null || function - onDirectionChanged: callbackTemplate, //null || function - onContentSizeChanged: callbackTemplate, //null || function - onHostSizeChanged: callbackTemplate, //null || function - onUpdated: callbackTemplate //null || function - } - }; - var convert = function (template) { - var recursive = function (obj) { - var key; - var val; - var valType; - for (key in obj) { - if (!obj[LEXICON.hOP](key)) - continue; - val = obj[key]; - valType = type(val); - if (valType == TYPES.a) - obj[key] = val[template ? 1 : 0]; - else if (valType == TYPES.o) - obj[key] = recursive(val); - } - return obj; - }; - return recursive(FRAMEWORK.extend(true, {}, optionsDefaultsAndTemplate)); - }; - - return { - _defaults: convert(), - - _template: convert(true), - - /** - * Validates the passed object by the passed template. - * @param obj The object which shall be validated. - * @param template The template which defines the allowed values and types. - * @param writeErrors True if errors shall be logged to the console. - * @param diffObj If a object is passed then only valid differences to this object will be returned. - * @returns {{}} A object which contains two objects called "default" and "prepared" which contains only the valid properties of the passed original object and discards not different values compared to the passed diffObj. - */ - _validate: function (obj, template, writeErrors, diffObj) { - var validatedOptions = {}; - var validatedOptionsPrepared = {}; - var objectCopy = FRAMEWORK.extend(true, {}, obj); - var inArray = FRAMEWORK.inArray; - var isEmptyObj = FRAMEWORK.isEmptyObject; - var checkObjectProps = function (data, template, diffData, validatedOptions, validatedOptionsPrepared, prevPropName) { - for (var prop in template) { - if (template[LEXICON.hOP](prop) && data[LEXICON.hOP](prop)) { - var isValid = false; - var isDiff = false; - var templateValue = template[prop]; - var templateValueType = type(templateValue); - var templateIsComplex = templateValueType == TYPES.o; - var templateTypes = type(templateValue) != TYPES.a ? [templateValue] : templateValue; - var dataDiffValue = diffData[prop]; - var dataValue = data[prop]; - var dataValueType = type(dataValue); - var propPrefix = prevPropName ? prevPropName + '.' : ''; - var error = "The option \"" + propPrefix + prop + "\" wasn't set, because"; - var errorPossibleTypes = []; - var errorRestrictedStrings = []; - var restrictedStringValuesSplit; - var restrictedStringValuesPossibilitiesSplit; - var isRestrictedValue; - var mainPossibility; - var currType; - var i; - var v; - var j; - - dataDiffValue = dataDiffValue === undefined ? {} : dataDiffValue; - - //if the template has a object as value, it means that the options are complex (verschachtelt) - if (templateIsComplex && dataValueType == TYPES.o) { - validatedOptions[prop] = {}; - validatedOptionsPrepared[prop] = {}; - checkObjectProps(dataValue, templateValue, dataDiffValue, validatedOptions[prop], validatedOptionsPrepared[prop], propPrefix + prop); - FRAMEWORK.each([data, validatedOptions, validatedOptionsPrepared], function (index, value) { - if (isEmptyObj(value[prop])) { - delete value[prop]; - } - }); - } - else if (!templateIsComplex) { - for (i = 0; i < templateTypes[LEXICON.l]; i++) { - currType = templateTypes[i]; - templateValueType = type(currType); - //if currtype is string and starts with restrictedStringPrefix and end with restrictedStringSuffix - isRestrictedValue = templateValueType == TYPES.s && inArray(currType, possibleTemplateTypes) === -1; - if (isRestrictedValue) { - errorPossibleTypes.push(TYPES.s); - - //split it into a array which contains all possible values for example: ["y:yes", "n:no", "m:maybe"] - restrictedStringValuesSplit = currType.split(restrictedStringsSplit); - errorRestrictedStrings = errorRestrictedStrings.concat(restrictedStringValuesSplit); - for (v = 0; v < restrictedStringValuesSplit[LEXICON.l]; v++) { - //split the possible values into their possibiliteis for example: ["y", "yes"] -> the first is always the mainPossibility - restrictedStringValuesPossibilitiesSplit = restrictedStringValuesSplit[v].split(restrictedStringsPossibilitiesSplit); - mainPossibility = restrictedStringValuesPossibilitiesSplit[0]; - for (j = 0; j < restrictedStringValuesPossibilitiesSplit[LEXICON.l]; j++) { - //if any possibility matches with the dataValue, its valid - if (dataValue === restrictedStringValuesPossibilitiesSplit[j]) { - isValid = true; - break; - } - } - if (isValid) - break; - } - } - else { - errorPossibleTypes.push(currType); - - if (dataValueType === currType) { - isValid = true; - break; - } - } - } - - if (isValid) { - isDiff = dataValue !== dataDiffValue; - - if (isDiff) - validatedOptions[prop] = dataValue; - - if (isRestrictedValue ? inArray(dataDiffValue, restrictedStringValuesPossibilitiesSplit) < 0 : isDiff) - validatedOptionsPrepared[prop] = isRestrictedValue ? mainPossibility : dataValue; - } - else if (writeErrors) { - console.warn(error + " it doesn't accept the type [ " + dataValueType.toUpperCase() + " ] with the value of \"" + dataValue + "\".\r\n" + - "Accepted types are: [ " + errorPossibleTypes.join(', ').toUpperCase() + " ]." + - (errorRestrictedStrings[length] > 0 ? "\r\nValid strings are: [ " + errorRestrictedStrings.join(', ').split(restrictedStringsPossibilitiesSplit).join(', ') + " ]." : '')); - } - delete data[prop]; - } - } - } - }; - checkObjectProps(objectCopy, template, diffObj || {}, validatedOptions, validatedOptionsPrepared); - - //add values which aren't specified in the template to the finished validated object to prevent them from being discarded - /* - if(keepForeignProps) { - FRAMEWORK.extend(true, validatedOptions, objectCopy); - FRAMEWORK.extend(true, validatedOptionsPrepared, objectCopy); - } - */ - - if (!isEmptyObj(objectCopy) && writeErrors) - console.warn('The following options are discarded due to invalidity:\r\n' + window.JSON.stringify(objectCopy, null, 2)); - - return { - _default: validatedOptions, - _prepared: validatedOptionsPrepared - }; - } - } - }()); - - /** - * Initializes the object which contains global information about the plugin and each instance of it. - */ - function initOverlayScrollbarsStatics() { - if (!_pluginsGlobals) - _pluginsGlobals = new OverlayScrollbarsGlobals(_pluginsOptions._defaults); - if (!_pluginsAutoUpdateLoop) - _pluginsAutoUpdateLoop = new OverlayScrollbarsAutoUpdateLoop(_pluginsGlobals); - } - - /** - * The global object for the OverlayScrollbars objects. It contains resources which every OverlayScrollbars object needs. This object is initialized only once: if the first OverlayScrollbars object gets initialized. - * @param defaultOptions - * @constructor - */ - function OverlayScrollbarsGlobals(defaultOptions) { - var _base = this; - var strOverflow = 'overflow'; - var strHidden = 'hidden'; - var strScroll = 'scroll'; - var bodyElement = FRAMEWORK('body'); - var scrollbarDummyElement = FRAMEWORK('
'); - var scrollbarDummyElement0 = scrollbarDummyElement[0]; - var dummyContainerChild = FRAMEWORK(scrollbarDummyElement.children('div').eq(0)); - - bodyElement.append(scrollbarDummyElement); - scrollbarDummyElement.hide().show(); //fix IE8 bug (incorrect measuring) - - var nativeScrollbarSize = calcNativeScrollbarSize(scrollbarDummyElement0); - var nativeScrollbarIsOverlaid = { - x: nativeScrollbarSize.x === 0, - y: nativeScrollbarSize.y === 0 - }; - var msie = (function () { - var ua = window.navigator.userAgent; - var strIndexOf = 'indexOf'; - var strSubString = 'substring'; - var msie = ua[strIndexOf]('MSIE '); - var trident = ua[strIndexOf]('Trident/'); - var edge = ua[strIndexOf]('Edge/'); - var rv = ua[strIndexOf]('rv:'); - var result; - var parseIntFunc = parseInt; - - // IE 10 or older => return version number - if (msie > 0) - result = parseIntFunc(ua[strSubString](msie + 5, ua[strIndexOf]('.', msie)), 10); - - // IE 11 => return version number - else if (trident > 0) - result = parseIntFunc(ua[strSubString](rv + 3, ua[strIndexOf]('.', rv)), 10); - - // Edge (IE 12+) => return version number - else if (edge > 0) - result = parseIntFunc(ua[strSubString](edge + 5, ua[strIndexOf]('.', edge)), 10); - - // other browser - return result; - })(); - - FRAMEWORK.extend(_base, { - defaultOptions: defaultOptions, - msie: msie, - autoUpdateLoop: false, - autoUpdateRecommended: !COMPATIBILITY.mO(), - nativeScrollbarSize: nativeScrollbarSize, - nativeScrollbarIsOverlaid: nativeScrollbarIsOverlaid, - nativeScrollbarStyling: (function () { - var result = false; - scrollbarDummyElement.addClass('os-viewport-native-scrollbars-invisible'); - try { - result = (scrollbarDummyElement.css('scrollbar-width') === 'none' && (msie > 9 || !msie)) || window.getComputedStyle(scrollbarDummyElement0, '::-webkit-scrollbar').getPropertyValue('display') === 'none'; - } catch (ex) { } - - //fix opera bug: scrollbar styles will only appear if overflow value is scroll or auto during the activation of the style. - //and set overflow to scroll - //scrollbarDummyElement.css(strOverflow, strHidden).hide().css(strOverflow, strScroll).show(); - //return (scrollbarDummyElement0[LEXICON.oH] - scrollbarDummyElement0[LEXICON.cH]) === 0 && (scrollbarDummyElement0[LEXICON.oW] - scrollbarDummyElement0[LEXICON.cW]) === 0; - - return result; - })(), - overlayScrollbarDummySize: { x: 30, y: 30 }, - cssCalc: (function () { - var dummyStyle = document.createElement('div')[LEXICON.s]; - var strCalc = 'calc'; - var i = -1; - var prop; - - for (; i < VENDORS._cssPrefixes[LEXICON.l]; i++) { - prop = i < 0 ? strCalc : VENDORS._cssPrefixes[i] + strCalc; - dummyStyle.cssText = 'width:' + prop + '(1px);'; - if (dummyStyle[LEXICON.l]) - return prop; - } - return null; - })(), - restrictedMeasuring: (function () { - //https://bugzilla.mozilla.org/show_bug.cgi?id=1439305 - //since 1.11.0 always false -> fixed via CSS (hopefully) - scrollbarDummyElement.css(strOverflow, strHidden); - var scrollSize = { - w: scrollbarDummyElement0[LEXICON.sW], - h: scrollbarDummyElement0[LEXICON.sH] - }; - scrollbarDummyElement.css(strOverflow, 'visible'); - var scrollSize2 = { - w: scrollbarDummyElement0[LEXICON.sW], - h: scrollbarDummyElement0[LEXICON.sH] - }; - return (scrollSize.w - scrollSize2.w) !== 0 || (scrollSize.h - scrollSize2.h) !== 0; - })(), - rtlScrollBehavior: (function () { - scrollbarDummyElement.css({ 'overflow-y': strHidden, 'overflow-x': strScroll, 'direction': 'rtl' }).scrollLeft(0); - var dummyContainerOffset = scrollbarDummyElement.offset(); - var dummyContainerChildOffset = dummyContainerChild.offset(); - //https://github.com/KingSora/OverlayScrollbars/issues/187 - scrollbarDummyElement.scrollLeft(-999); - var dummyContainerChildOffsetAfterScroll = dummyContainerChild.offset(); - return { - //origin direction = determines if the zero scroll position is on the left or right side - //'i' means 'invert' (i === true means that the axis must be inverted to be correct) - //true = on the left side - //false = on the right side - i: dummyContainerOffset.left === dummyContainerChildOffset.left, - //negative = determines if the maximum scroll is positive or negative - //'n' means 'negate' (n === true means that the axis must be negated to be correct) - //true = negative - //false = positive - n: dummyContainerChildOffset.left !== dummyContainerChildOffsetAfterScroll.left - }; - })(), - supportTransform: VENDORS._cssProperty('transform') !== undefined, - supportTransition: VENDORS._cssProperty('transition') !== undefined, - supportPassiveEvents: (function () { - var supportsPassive = false; - try { - window.addEventListener('test', null, Object.defineProperty({}, 'passive', { - get: function () { - supportsPassive = true; - } - })); - } catch (e) { } - return supportsPassive; - })(), - supportResizeObserver: !!COMPATIBILITY.rO(), - supportMutationObserver: !!COMPATIBILITY.mO() - }); - - scrollbarDummyElement.removeAttr(LEXICON.s).remove(); - - //Catch zoom event: - (function () { - if (nativeScrollbarIsOverlaid.x && nativeScrollbarIsOverlaid.y) - return; - - var abs = MATH.abs; - var windowWidth = COMPATIBILITY.wW(); - var windowHeight = COMPATIBILITY.wH(); - var windowDpr = getWindowDPR(); - var onResize = function () { - if (INSTANCES().length > 0) { - var newW = COMPATIBILITY.wW(); - var newH = COMPATIBILITY.wH(); - var deltaW = newW - windowWidth; - var deltaH = newH - windowHeight; - - if (deltaW === 0 && deltaH === 0) - return; - - var deltaWRatio = MATH.round(newW / (windowWidth / 100.0)); - var deltaHRatio = MATH.round(newH / (windowHeight / 100.0)); - var absDeltaW = abs(deltaW); - var absDeltaH = abs(deltaH); - var absDeltaWRatio = abs(deltaWRatio); - var absDeltaHRatio = abs(deltaHRatio); - var newDPR = getWindowDPR(); - - var deltaIsBigger = absDeltaW > 2 && absDeltaH > 2; - var difference = !differenceIsBiggerThanOne(absDeltaWRatio, absDeltaHRatio); - var dprChanged = newDPR !== windowDpr && windowDpr > 0; - var isZoom = deltaIsBigger && difference && dprChanged; - var oldScrollbarSize = _base.nativeScrollbarSize; - var newScrollbarSize; - - if (isZoom) { - bodyElement.append(scrollbarDummyElement); - newScrollbarSize = _base.nativeScrollbarSize = calcNativeScrollbarSize(scrollbarDummyElement[0]); - scrollbarDummyElement.remove(); - if (oldScrollbarSize.x !== newScrollbarSize.x || oldScrollbarSize.y !== newScrollbarSize.y) { - FRAMEWORK.each(INSTANCES(), function () { - if (INSTANCES(this)) - INSTANCES(this).update('zoom'); - }); - } - } - - windowWidth = newW; - windowHeight = newH; - windowDpr = newDPR; - } - }; - - function differenceIsBiggerThanOne(valOne, valTwo) { - var absValOne = abs(valOne); - var absValTwo = abs(valTwo); - return !(absValOne === absValTwo || absValOne + 1 === absValTwo || absValOne - 1 === absValTwo); - } - - function getWindowDPR() { - var dDPI = window.screen.deviceXDPI || 0; - var sDPI = window.screen.logicalXDPI || 1; - return window.devicePixelRatio || (dDPI / sDPI); - } - - FRAMEWORK(window).on('resize', onResize); - })(); - - function calcNativeScrollbarSize(measureElement) { - return { - x: measureElement[LEXICON.oH] - measureElement[LEXICON.cH], - y: measureElement[LEXICON.oW] - measureElement[LEXICON.cW] - }; - } - } - - /** - * The object which manages the auto update loop for all OverlayScrollbars objects. This object is initialized only once: if the first OverlayScrollbars object gets initialized. - * @constructor - */ - function OverlayScrollbarsAutoUpdateLoop(globals) { - var _base = this; - var _inArray = FRAMEWORK.inArray; - var _getNow = COMPATIBILITY.now; - var _strAutoUpdate = 'autoUpdate'; - var _strAutoUpdateInterval = _strAutoUpdate + 'Interval'; - var _strLength = LEXICON.l; - var _loopingInstances = []; - var _loopingInstancesIntervalCache = []; - var _loopIsActive = false; - var _loopIntervalDefault = 33; - var _loopInterval = _loopIntervalDefault; - var _loopTimeOld = _getNow(); - var _loopID; - - - /** - * The auto update loop which will run every 50 milliseconds or less if the update interval of a instance is lower than 50 milliseconds. - */ - var loop = function () { - if (_loopingInstances[_strLength] > 0 && _loopIsActive) { - _loopID = COMPATIBILITY.rAF()(function () { - loop(); - }); - var timeNew = _getNow(); - var timeDelta = timeNew - _loopTimeOld; - var lowestInterval; - var instance; - var instanceOptions; - var instanceAutoUpdateAllowed; - var instanceAutoUpdateInterval; - var now; - - if (timeDelta > _loopInterval) { - _loopTimeOld = timeNew - (timeDelta % _loopInterval); - lowestInterval = _loopIntervalDefault; - for (var i = 0; i < _loopingInstances[_strLength]; i++) { - instance = _loopingInstances[i]; - if (instance !== undefined) { - instanceOptions = instance.options(); - instanceAutoUpdateAllowed = instanceOptions[_strAutoUpdate]; - instanceAutoUpdateInterval = MATH.max(1, instanceOptions[_strAutoUpdateInterval]); - now = _getNow(); - - if ((instanceAutoUpdateAllowed === true || instanceAutoUpdateAllowed === null) && (now - _loopingInstancesIntervalCache[i]) > instanceAutoUpdateInterval) { - instance.update('auto'); - _loopingInstancesIntervalCache[i] = new Date(now += instanceAutoUpdateInterval); - } - - lowestInterval = MATH.max(1, MATH.min(lowestInterval, instanceAutoUpdateInterval)); - } - } - _loopInterval = lowestInterval; - } - } else { - _loopInterval = _loopIntervalDefault; - } - }; - - /** - * Add OverlayScrollbars instance to the auto update loop. Only successful if the instance isn't already added. - * @param instance The instance which shall be updated in a loop automatically. - */ - _base.add = function (instance) { - if (_inArray(instance, _loopingInstances) === -1) { - _loopingInstances.push(instance); - _loopingInstancesIntervalCache.push(_getNow()); - if (_loopingInstances[_strLength] > 0 && !_loopIsActive) { - _loopIsActive = true; - globals.autoUpdateLoop = _loopIsActive; - loop(); - } - } - }; - - /** - * Remove OverlayScrollbars instance from the auto update loop. Only successful if the instance was added before. - * @param instance The instance which shall be updated in a loop automatically. - */ - _base.remove = function (instance) { - var index = _inArray(instance, _loopingInstances); - if (index > -1) { - //remove from loopingInstances list - _loopingInstancesIntervalCache.splice(index, 1); - _loopingInstances.splice(index, 1); - - //correct update loop behavior - if (_loopingInstances[_strLength] === 0 && _loopIsActive) { - _loopIsActive = false; - globals.autoUpdateLoop = _loopIsActive; - if (_loopID !== undefined) { - COMPATIBILITY.cAF()(_loopID); - _loopID = -1; - } - } - } - }; - } - - /** - * A object which manages the scrollbars visibility of the target element. - * @param pluginTargetElement The element from which the scrollbars shall be hidden. - * @param options The custom options. - * @param extensions The custom extensions. - * @param globals - * @param autoUpdateLoop - * @returns {*} - * @constructor - */ - function OverlayScrollbarsInstance(pluginTargetElement, options, extensions, globals, autoUpdateLoop) { - //shortcuts - var type = COMPATIBILITY.type; - var inArray = FRAMEWORK.inArray; - var each = FRAMEWORK.each; - - //make correct instanceof - var _base = new _plugin(); - var _frameworkProto = FRAMEWORK[LEXICON.p]; - - //if passed element is no HTML element: skip and return - if (!isHTMLElement(pluginTargetElement)) - return; - - //if passed element is already initialized: set passed options if there are any and return its instance - if (INSTANCES(pluginTargetElement)) { - var inst = INSTANCES(pluginTargetElement); - inst.options(options); - return inst; - } - - //globals: - var _nativeScrollbarIsOverlaid; - var _overlayScrollbarDummySize; - var _rtlScrollBehavior; - var _autoUpdateRecommended; - var _msieVersion; - var _nativeScrollbarStyling; - var _cssCalc; - var _nativeScrollbarSize; - var _supportTransition; - var _supportTransform; - var _supportPassiveEvents; - var _supportResizeObserver; - var _supportMutationObserver; - var _restrictedMeasuring; - - //general readonly: - var _initialized; - var _destroyed; - var _isTextarea; - var _isBody; - var _documentMixed; - var _domExists; - - //general: - var _isBorderBox; - var _sizeAutoObserverAdded; - var _paddingX; - var _paddingY; - var _borderX; - var _borderY; - var _marginX; - var _marginY; - var _isRTL; - var _sleeping; - var _contentBorderSize = {}; - var _scrollHorizontalInfo = {}; - var _scrollVerticalInfo = {}; - var _viewportSize = {}; - var _nativeScrollbarMinSize = {}; - - //naming: - var _strMinusHidden = '-hidden'; - var _strMarginMinus = 'margin-'; - var _strPaddingMinus = 'padding-'; - var _strBorderMinus = 'border-'; - var _strTop = 'top'; - var _strRight = 'right'; - var _strBottom = 'bottom'; - var _strLeft = 'left'; - var _strMinMinus = 'min-'; - var _strMaxMinus = 'max-'; - var _strWidth = 'width'; - var _strHeight = 'height'; - var _strFloat = 'float'; - var _strEmpty = ''; - var _strAuto = 'auto'; - var _strSync = 'sync'; - var _strScroll = 'scroll'; - var _strHundredPercent = '100%'; - var _strX = 'x'; - var _strY = 'y'; - var _strDot = '.'; - var _strSpace = ' '; - var _strScrollbar = 'scrollbar'; - var _strMinusHorizontal = '-horizontal'; - var _strMinusVertical = '-vertical'; - var _strScrollLeft = _strScroll + 'Left'; - var _strScrollTop = _strScroll + 'Top'; - var _strMouseTouchDownEvent = 'mousedown touchstart'; - var _strMouseTouchUpEvent = 'mouseup touchend touchcancel'; - var _strMouseTouchMoveEvent = 'mousemove touchmove'; - var _strMouseTouchEnter = 'mouseenter'; - var _strMouseTouchLeave = 'mouseleave'; - var _strKeyDownEvent = 'keydown'; - var _strKeyUpEvent = 'keyup'; - var _strSelectStartEvent = 'selectstart'; - var _strTransitionEndEvent = 'transitionend webkitTransitionEnd oTransitionEnd'; - var _strResizeObserverProperty = '__overlayScrollbarsRO__'; - - //class names: - var _cassNamesPrefix = 'os-'; - var _classNameHTMLElement = _cassNamesPrefix + 'html'; - var _classNameHostElement = _cassNamesPrefix + 'host'; - var _classNameHostTextareaElement = _classNameHostElement + '-textarea'; - var _classNameHostScrollbarHorizontalHidden = _classNameHostElement + '-' + _strScrollbar + _strMinusHorizontal + _strMinusHidden; - var _classNameHostScrollbarVerticalHidden = _classNameHostElement + '-' + _strScrollbar + _strMinusVertical + _strMinusHidden; - var _classNameHostTransition = _classNameHostElement + '-transition'; - var _classNameHostRTL = _classNameHostElement + '-rtl'; - var _classNameHostResizeDisabled = _classNameHostElement + '-resize-disabled'; - var _classNameHostScrolling = _classNameHostElement + '-scrolling'; - var _classNameHostOverflow = _classNameHostElement + '-overflow'; - var _classNameHostOverflowX = _classNameHostOverflow + '-x'; - var _classNameHostOverflowY = _classNameHostOverflow + '-y'; - var _classNameTextareaElement = _cassNamesPrefix + 'textarea'; - var _classNameTextareaCoverElement = _classNameTextareaElement + '-cover'; - var _classNamePaddingElement = _cassNamesPrefix + 'padding'; - var _classNameViewportElement = _cassNamesPrefix + 'viewport'; - var _classNameViewportNativeScrollbarsInvisible = _classNameViewportElement + '-native-scrollbars-invisible'; - var _classNameViewportNativeScrollbarsOverlaid = _classNameViewportElement + '-native-scrollbars-overlaid'; - var _classNameContentElement = _cassNamesPrefix + 'content'; - var _classNameContentArrangeElement = _cassNamesPrefix + 'content-arrange'; - var _classNameContentGlueElement = _cassNamesPrefix + 'content-glue'; - var _classNameSizeAutoObserverElement = _cassNamesPrefix + 'size-auto-observer'; - var _classNameResizeObserverElement = _cassNamesPrefix + 'resize-observer'; - var _classNameResizeObserverItemElement = _cassNamesPrefix + 'resize-observer-item'; - var _classNameResizeObserverItemFinalElement = _classNameResizeObserverItemElement + '-final'; - var _classNameTextInherit = _cassNamesPrefix + 'text-inherit'; - var _classNameScrollbar = _cassNamesPrefix + _strScrollbar; - var _classNameScrollbarTrack = _classNameScrollbar + '-track'; - var _classNameScrollbarTrackOff = _classNameScrollbarTrack + '-off'; - var _classNameScrollbarHandle = _classNameScrollbar + '-handle'; - var _classNameScrollbarHandleOff = _classNameScrollbarHandle + '-off'; - var _classNameScrollbarUnusable = _classNameScrollbar + '-unusable'; - var _classNameScrollbarAutoHidden = _classNameScrollbar + '-' + _strAuto + _strMinusHidden; - var _classNameScrollbarCorner = _classNameScrollbar + '-corner'; - var _classNameScrollbarCornerResize = _classNameScrollbarCorner + '-resize'; - var _classNameScrollbarCornerResizeB = _classNameScrollbarCornerResize + '-both'; - var _classNameScrollbarCornerResizeH = _classNameScrollbarCornerResize + _strMinusHorizontal; - var _classNameScrollbarCornerResizeV = _classNameScrollbarCornerResize + _strMinusVertical; - var _classNameScrollbarHorizontal = _classNameScrollbar + _strMinusHorizontal; - var _classNameScrollbarVertical = _classNameScrollbar + _strMinusVertical; - var _classNameDragging = _cassNamesPrefix + 'dragging'; - var _classNameThemeNone = _cassNamesPrefix + 'theme-none'; - var _classNamesDynamicDestroy = [ - _classNameViewportNativeScrollbarsInvisible, - _classNameViewportNativeScrollbarsOverlaid, - _classNameScrollbarTrackOff, - _classNameScrollbarHandleOff, - _classNameScrollbarUnusable, - _classNameScrollbarAutoHidden, - _classNameScrollbarCornerResize, - _classNameScrollbarCornerResizeB, - _classNameScrollbarCornerResizeH, - _classNameScrollbarCornerResizeV, - _classNameDragging].join(_strSpace); - - //callbacks: - var _callbacksInitQeueue = []; - - //attrs viewport shall inherit from target - var _viewportAttrsFromTarget = [LEXICON.ti]; - - //options: - var _defaultOptions; - var _currentOptions; - var _currentPreparedOptions; - - //extensions: - var _extensions = {}; - var _extensionsPrivateMethods = 'added removed on contract'; - - //update - var _lastUpdateTime; - var _swallowedUpdateHints = {}; - var _swallowedUpdateTimeout; - var _swallowUpdateLag = 42; - var _imgs = []; - - //DOM elements: - var _windowElement; - var _documentElement; - var _htmlElement; - var _bodyElement; - var _targetElement; //the target element of this OverlayScrollbars object - var _hostElement; //the host element of this OverlayScrollbars object -> may be the same as targetElement - var _sizeAutoObserverElement; //observes size auto changes - var _sizeObserverElement; //observes size and padding changes - var _paddingElement; //manages the padding - var _viewportElement; //is the viewport of our scrollbar model - var _contentElement; //the element which holds the content - var _contentArrangeElement; //is needed for correct sizing of the content element (only if native scrollbars are overlays) - var _contentGlueElement; //has always the size of the content element - var _textareaCoverElement; //only applied if target is a textarea element. Used for correct size calculation and for prevention of uncontrolled scrolling - var _scrollbarCornerElement; - var _scrollbarHorizontalElement; - var _scrollbarHorizontalTrackElement; - var _scrollbarHorizontalHandleElement; - var _scrollbarVerticalElement; - var _scrollbarVerticalTrackElement; - var _scrollbarVerticalHandleElement; - var _windowElementNative; - var _documentElementNative; - var _targetElementNative; - var _hostElementNative; - var _sizeAutoObserverElementNative; - var _sizeObserverElementNative; - var _paddingElementNative; - var _viewportElementNative; - var _contentElementNative; - - //Cache: - var _hostSizeCache; - var _contentScrollSizeCache; - var _arrangeContentSizeCache; - var _hasOverflowCache; - var _hideOverflowCache; - var _widthAutoCache; - var _heightAutoCache; - var _cssMaxValueCache; - var _cssBoxSizingCache; - var _cssPaddingCache; - var _cssBorderCache; - var _cssMarginCache; - var _cssDirectionCache; - var _cssDirectionDetectedCache; - var _paddingAbsoluteCache; - var _clipAlwaysCache; - var _contentGlueSizeCache; - var _overflowBehaviorCache; - var _overflowAmountCache; - var _ignoreOverlayScrollbarHidingCache; - var _autoUpdateCache; - var _sizeAutoCapableCache; - var _contentElementScrollSizeChangeDetectedCache; - var _hostElementSizeChangeDetectedCache; - var _scrollbarsVisibilityCache; - var _scrollbarsAutoHideCache; - var _scrollbarsClickScrollingCache; - var _scrollbarsDragScrollingCache; - var _resizeCache; - var _normalizeRTLCache; - var _classNameCache; - var _oldClassName; - var _textareaAutoWrappingCache; - var _textareaInfoCache; - var _textareaSizeCache; - var _textareaDynHeightCache; - var _textareaDynWidthCache; - var _bodyMinSizeCache; - var _displayIsHiddenCache; - var _updateAutoCache = {}; - - //MutationObserver: - var _mutationObserverHost; - var _mutationObserverContent; - var _mutationObserverHostCallback; - var _mutationObserverContentCallback; - var _mutationObserversConnected; - var _mutationObserverAttrsTextarea = ['wrap', 'cols', 'rows']; - var _mutationObserverAttrsHost = [LEXICON.i, LEXICON.c, LEXICON.s, 'open'].concat(_viewportAttrsFromTarget); - - //events: - var _destroyEvents = []; - - //textarea: - var _textareaHasFocus; - - //scrollbars: - var _scrollbarsAutoHideTimeoutId; - var _scrollbarsAutoHideMoveTimeoutId; - var _scrollbarsAutoHideDelay; - var _scrollbarsAutoHideNever; - var _scrollbarsAutoHideScroll; - var _scrollbarsAutoHideMove; - var _scrollbarsAutoHideLeave; - var _scrollbarsHandleHovered; - var _scrollbarsHandlesDefineScrollPos; - - //resize - var _resizeNone; - var _resizeBoth; - var _resizeHorizontal; - var _resizeVertical; - - - //==== Event Listener ====// - - /** - * Adds or removes a event listener from the given element. - * @param element The element to which the event listener shall be applied or removed. - * @param eventNames The name(s) of the events. - * @param listener The method which shall be called. - * @param remove True if the handler shall be removed, false or undefined if the handler shall be added. - */ - function setupResponsiveEventListener(element, eventNames, listener, remove, passive) { - var collected = type(eventNames) == TYPES.a && type(listener) == TYPES.a; - var method = remove ? 'removeEventListener' : 'addEventListener'; - var onOff = remove ? 'off' : 'on'; - var events = collected ? false : eventNames.split(_strSpace) - var i = 0; - - if (collected) { - for (; i < eventNames[LEXICON.l]; i++) - setupResponsiveEventListener(element, eventNames[i], listener[i], remove); - } - else { - for (; i < events[LEXICON.l]; i++) { - if (_supportPassiveEvents) - element[0][method](events[i], listener, { passive: passive || false }); - else - element[onOff](events[i], listener); - } - } - } - - - function addDestroyEventListener(element, eventNames, listener, passive) { - setupResponsiveEventListener(element, eventNames, listener, false, passive); - _destroyEvents.push(COMPATIBILITY.bind(setupResponsiveEventListener, 0, element, eventNames, listener, true, passive)); - } - - //==== Resize Observer ====// - - /** - * Adds or removes a resize observer from the given element. - * @param targetElement The element to which the resize observer shall be added or removed. - * @param onElementResizedCallback The callback which is fired every time the resize observer registers a size change or false / undefined if the resizeObserver shall be removed. - */ - function setupResizeObserver(targetElement, onElementResizedCallback) { - if (targetElement) { - var resizeObserver = COMPATIBILITY.rO(); - var strAnimationStartEvent = 'animationstart mozAnimationStart webkitAnimationStart MSAnimationStart'; - var strChildNodes = 'childNodes'; - var constScroll = 3333333; - var callback = function () { - targetElement[_strScrollTop](constScroll)[_strScrollLeft](_isRTL ? _rtlScrollBehavior.n ? -constScroll : _rtlScrollBehavior.i ? 0 : constScroll : constScroll); - onElementResizedCallback(); - }; - //add resize observer: - if (onElementResizedCallback) { - if (_supportResizeObserver) { - var element = targetElement.addClass('observed').append(generateDiv(_classNameResizeObserverElement)).contents()[0]; - var observer = element[_strResizeObserverProperty] = new resizeObserver(callback); - observer.observe(element); - } - else { - if (_msieVersion > 9 || !_autoUpdateRecommended) { - targetElement.prepend( - generateDiv(_classNameResizeObserverElement, - generateDiv({ c: _classNameResizeObserverItemElement, dir: 'ltr' }, - generateDiv(_classNameResizeObserverItemElement, - generateDiv(_classNameResizeObserverItemFinalElement) - ) + - generateDiv(_classNameResizeObserverItemElement, - generateDiv({ c: _classNameResizeObserverItemFinalElement, style: 'width: 200%; height: 200%' }) - ) - ) - ) - ); - - var observerElement = targetElement[0][strChildNodes][0][strChildNodes][0]; - var shrinkElement = FRAMEWORK(observerElement[strChildNodes][1]); - var expandElement = FRAMEWORK(observerElement[strChildNodes][0]); - var expandElementChild = FRAMEWORK(expandElement[0][strChildNodes][0]); - var widthCache = observerElement[LEXICON.oW]; - var heightCache = observerElement[LEXICON.oH]; - var isDirty; - var rAFId; - var currWidth; - var currHeight; - var factor = 2; - var nativeScrollbarSize = globals.nativeScrollbarSize; //care don't make changes to this object!!! - var reset = function () { - /* - var sizeResetWidth = observerElement[LEXICON.oW] + nativeScrollbarSize.x * factor + nativeScrollbarSize.y * factor + _overlayScrollbarDummySize.x + _overlayScrollbarDummySize.y; - var sizeResetHeight = observerElement[LEXICON.oH] + nativeScrollbarSize.x * factor + nativeScrollbarSize.y * factor + _overlayScrollbarDummySize.x + _overlayScrollbarDummySize.y; - var expandChildCSS = {}; - expandChildCSS[_strWidth] = sizeResetWidth; - expandChildCSS[_strHeight] = sizeResetHeight; - expandElementChild.css(expandChildCSS); - - - expandElement[_strScrollLeft](sizeResetWidth)[_strScrollTop](sizeResetHeight); - shrinkElement[_strScrollLeft](sizeResetWidth)[_strScrollTop](sizeResetHeight); - */ - expandElement[_strScrollLeft](constScroll)[_strScrollTop](constScroll); - shrinkElement[_strScrollLeft](constScroll)[_strScrollTop](constScroll); - }; - var onResized = function () { - rAFId = 0; - if (!isDirty) - return; - - widthCache = currWidth; - heightCache = currHeight; - callback(); - }; - var onScroll = function (event) { - currWidth = observerElement[LEXICON.oW]; - currHeight = observerElement[LEXICON.oH]; - isDirty = currWidth != widthCache || currHeight != heightCache; - - if (event && isDirty && !rAFId) { - COMPATIBILITY.cAF()(rAFId); - rAFId = COMPATIBILITY.rAF()(onResized); - } - else if (!event) - onResized(); - - reset(); - if (event) { - COMPATIBILITY.prvD(event); - COMPATIBILITY.stpP(event); - } - return false; - }; - var expandChildCSS = {}; - var observerElementCSS = {}; - - setTopRightBottomLeft(observerElementCSS, _strEmpty, [ - -((nativeScrollbarSize.y + 1) * factor), - nativeScrollbarSize.x * -factor, - nativeScrollbarSize.y * -factor, - -((nativeScrollbarSize.x + 1) * factor) - ]); - - FRAMEWORK(observerElement).css(observerElementCSS); - expandElement.on(_strScroll, onScroll); - shrinkElement.on(_strScroll, onScroll); - targetElement.on(strAnimationStartEvent, function () { - onScroll(false); - }); - //lets assume that the divs will never be that large and a constant value is enough - expandChildCSS[_strWidth] = constScroll; - expandChildCSS[_strHeight] = constScroll; - expandElementChild.css(expandChildCSS); - - reset(); - } - else { - var attachEvent = _documentElementNative.attachEvent; - var isIE = _msieVersion !== undefined; - if (attachEvent) { - targetElement.prepend(generateDiv(_classNameResizeObserverElement)); - findFirst(targetElement, _strDot + _classNameResizeObserverElement)[0].attachEvent('onresize', callback); - } - else { - var obj = _documentElementNative.createElement(TYPES.o); - obj.setAttribute(LEXICON.ti, '-1'); - obj.setAttribute(LEXICON.c, _classNameResizeObserverElement); - obj.onload = function () { - var wnd = this.contentDocument.defaultView; - wnd.addEventListener('resize', callback); - wnd.document.documentElement.style.display = 'none'; - }; - obj.type = 'text/html'; - if (isIE) - targetElement.prepend(obj); - obj.data = 'about:blank'; - if (!isIE) - targetElement.prepend(obj); - targetElement.on(strAnimationStartEvent, callback); - } - } - } - - if (targetElement[0] === _sizeObserverElementNative) { - var directionChanged = function () { - var dir = _hostElement.css('direction'); - var css = {}; - var scrollLeftValue = 0; - var result = false; - if (dir !== _cssDirectionDetectedCache) { - if (dir === 'ltr') { - css[_strLeft] = 0; - css[_strRight] = _strAuto; - scrollLeftValue = constScroll; - } - else { - css[_strLeft] = _strAuto; - css[_strRight] = 0; - scrollLeftValue = _rtlScrollBehavior.n ? -constScroll : _rtlScrollBehavior.i ? 0 : constScroll; - } - //execution order is important for IE!!! - _sizeObserverElement.children().eq(0).css(css); - _sizeObserverElement[_strScrollLeft](scrollLeftValue)[_strScrollTop](constScroll); - _cssDirectionDetectedCache = dir; - result = true; - } - return result; - }; - directionChanged(); - addDestroyEventListener(targetElement, _strScroll, function (event) { - if (directionChanged()) - update(); - COMPATIBILITY.prvD(event); - COMPATIBILITY.stpP(event); - return false; - }); - } - } - //remove resize observer: - else { - if (_supportResizeObserver) { - var element = targetElement.contents()[0]; - var resizeObserverObj = element[_strResizeObserverProperty]; - if (resizeObserverObj) { - resizeObserverObj.disconnect(); - delete element[_strResizeObserverProperty]; - } - } - else { - remove(targetElement.children(_strDot + _classNameResizeObserverElement).eq(0)); - } - } - } - } - - /** - * Freezes or unfreezes the given resize observer. - * @param targetElement The element to which the target resize observer is applied. - * @param freeze True if the resize observer shall be frozen, false otherwise. - - function freezeResizeObserver(targetElement, freeze) { - if (targetElement !== undefined) { - if(freeze) { - if (_supportResizeObserver) { - var element = targetElement.contents()[0]; - element[_strResizeObserverProperty].unobserve(element); - } - else { - targetElement = targetElement.children(_strDot + _classNameResizeObserverElement).eq(0); - var w = targetElement.css(_strWidth); - var h = targetElement.css(_strHeight); - var css = {}; - css[_strWidth] = w; - css[_strHeight] = h; - targetElement.css(css); - } - } - else { - if (_supportResizeObserver) { - var element = targetElement.contents()[0]; - element[_strResizeObserverProperty].observe(element); - } - else { - var css = { }; - css[_strHeight] = _strEmpty; - css[_strWidth] = _strEmpty; - targetElement.children(_strDot + _classNameResizeObserverElement).eq(0).css(css); - } - } - } - } - */ - - - //==== Mutation Observers ====// - - /** - * Creates MutationObservers for the host and content Element if they are supported. - */ - function createMutationObservers() { - if (_supportMutationObserver) { - var mutationObserverContentLag = 11; - var mutationObserver = COMPATIBILITY.mO(); - var contentLastUpdate = COMPATIBILITY.now(); - var mutationTarget; - var mutationAttrName; - var contentTimeout; - var now; - var sizeAuto; - var action; - - _mutationObserverHostCallback = function (mutations) { - var doUpdate = false; - var mutation; - var mutatedAttrs = []; - - if (_initialized && !_sleeping) { - each(mutations, function () { - mutation = this; - mutationTarget = mutation.target; - mutationAttrName = mutation.attributeName; - - if(!doUpdate) { - if (mutationAttrName === LEXICON.c) - doUpdate = hostClassNamesChanged(mutation.oldValue, mutationTarget.className); - else if (mutationAttrName === LEXICON.s) - doUpdate = mutation.oldValue !== mutationTarget[LEXICON.s].cssText; - else - doUpdate = true; - } - - mutatedAttrs.push(mutationAttrName); - }); - - updateViewportAttrsFromTarget(mutatedAttrs); - - if (doUpdate) - _base.update(_strAuto); - } - return doUpdate; - }; - _mutationObserverContentCallback = function (mutations) { - var doUpdate = false; - var mutation; - - if (_initialized && !_sleeping) { - each(mutations, function () { - mutation = this; - doUpdate = isUnknownMutation(mutation); - return !doUpdate; - }); - - if (doUpdate) { - now = COMPATIBILITY.now(); - sizeAuto = (_heightAutoCache || _widthAutoCache); - action = function () { - if (!_destroyed) { - contentLastUpdate = now; - - //if cols, rows or wrap attr was changed - if (_isTextarea) - textareaUpdate(); - - if (sizeAuto) - update(); - else - _base.update(_strAuto); - } - }; - clearTimeout(contentTimeout); - if (mutationObserverContentLag <= 0 || now - contentLastUpdate > mutationObserverContentLag || !sizeAuto) - action(); - else - contentTimeout = setTimeout(action, mutationObserverContentLag); - } - } - return doUpdate; - } - - _mutationObserverHost = new mutationObserver(_mutationObserverHostCallback); - _mutationObserverContent = new mutationObserver(_mutationObserverContentCallback); - } - } - - /** - * Connects the MutationObservers if they are supported. - */ - function connectMutationObservers() { - if (_supportMutationObserver && !_mutationObserversConnected) { - _mutationObserverHost.observe(_hostElementNative, { - attributes: true, - attributeOldValue: true, - attributeFilter: _mutationObserverAttrsHost - }); - - _mutationObserverContent.observe(_isTextarea ? _targetElementNative : _contentElementNative, { - attributes: true, - attributeOldValue: true, - subtree: !_isTextarea, - childList: !_isTextarea, - characterData: !_isTextarea, - attributeFilter: _isTextarea ? _mutationObserverAttrsTextarea : _mutationObserverAttrsHost - }); - - _mutationObserversConnected = true; - } - } - - /** - * Disconnects the MutationObservers if they are supported. - */ - function disconnectMutationObservers() { - if (_supportMutationObserver && _mutationObserversConnected) { - _mutationObserverHost.disconnect(); - _mutationObserverContent.disconnect(); - - _mutationObserversConnected = false; - } - } - - - //==== Events of elements ====// - - /** - * This method gets called every time the host element gets resized. IMPORTANT: Padding changes are detected too!! - * It refreshes the hostResizedEventArgs and the hostSizeResizeCache. - * If there are any size changes, the update method gets called. - */ - function hostOnResized() { - if (!_sleeping) { - var changed; - var hostSize = { - w: _sizeObserverElementNative[LEXICON.sW], - h: _sizeObserverElementNative[LEXICON.sH] - }; - - changed = checkCache(hostSize, _hostElementSizeChangeDetectedCache); - _hostElementSizeChangeDetectedCache = hostSize; - if (changed) - update({ _hostSizeChanged: true }); - } - } - - /** - * The mouse enter event of the host element. This event is only needed for the autoHide feature. - */ - function hostOnMouseEnter() { - if (_scrollbarsAutoHideLeave) - refreshScrollbarsAutoHide(true); - } - - /** - * The mouse leave event of the host element. This event is only needed for the autoHide feature. - */ - function hostOnMouseLeave() { - if (_scrollbarsAutoHideLeave && !_bodyElement.hasClass(_classNameDragging)) - refreshScrollbarsAutoHide(false); - } - - /** - * The mouse move event of the host element. This event is only needed for the autoHide "move" feature. - */ - function hostOnMouseMove() { - if (_scrollbarsAutoHideMove) { - refreshScrollbarsAutoHide(true); - clearTimeout(_scrollbarsAutoHideMoveTimeoutId); - _scrollbarsAutoHideMoveTimeoutId = setTimeout(function () { - if (_scrollbarsAutoHideMove && !_destroyed) - refreshScrollbarsAutoHide(false); - }, 100); - } - } - - /** - * Prevents text from deselection if attached to the document element on the mousedown event of a DOM element. - * @param event The select start event. - */ - function documentOnSelectStart(event) { - COMPATIBILITY.prvD(event); - return false; - } - - /** - * A callback which will be called after a img element has downloaded its src asynchronous. - */ - function imgOnLoad() { - update({ _contentSizeChanged: true }); - } - - /** - * Adds or removes mouse & touch events of the host element. (for handling auto-hiding of the scrollbars) - * @param destroy Indicates whether the events shall be added or removed. - */ - function setupHostMouseTouchEvents(destroy) { - setupResponsiveEventListener(_hostElement, - _strMouseTouchMoveEvent, - hostOnMouseMove, - (_scrollbarsAutoHideMove ? destroy : true), true); - setupResponsiveEventListener(_hostElement, - [_strMouseTouchEnter, _strMouseTouchLeave], - [hostOnMouseEnter, hostOnMouseLeave], - (_scrollbarsAutoHideMove ? true : destroy), true); - - //if the plugin is initialized and the mouse is over the host element, make the scrollbars visible - if (!_initialized && !destroy) - _hostElement.one('mouseover', hostOnMouseEnter); - } - - - //==== Update Detection ====// - - /** - * Measures the min width and min height of the body element and refreshes the related cache. - * @returns {boolean} True if the min width or min height has changed, false otherwise. - */ - function bodyMinSizeChanged() { - var bodyMinSize = {}; - if (_isBody && _contentArrangeElement) { - bodyMinSize.w = parseToZeroOrNumber(_contentArrangeElement.css(_strMinMinus + _strWidth)); - bodyMinSize.h = parseToZeroOrNumber(_contentArrangeElement.css(_strMinMinus + _strHeight)); - bodyMinSize.c = checkCache(bodyMinSize, _bodyMinSizeCache); - bodyMinSize.f = true; //flag for "measured at least once" - } - _bodyMinSizeCache = bodyMinSize; - return !!bodyMinSize.c; - } - - /** - * Returns true if the class names really changed (new class without plugin host prefix) - * @param oldCassNames The old ClassName string. - * @param newClassNames The new ClassName string. - * @returns {boolean} True if the class names has really changed, false otherwise. - */ - function hostClassNamesChanged(oldCassNames, newClassNames) { - var currClasses = (newClassNames !== undefined && newClassNames !== null) ? newClassNames.split(_strSpace) : _strEmpty; - var oldClasses = (oldCassNames !== undefined && oldCassNames !== null) ? oldCassNames.split(_strSpace) : _strEmpty; - if (currClasses === _strEmpty && oldClasses === _strEmpty) - return false; - var diff = getArrayDifferences(oldClasses, currClasses); - var changed = false; - var oldClassNames = _oldClassName !== undefined && _oldClassName !== null ? _oldClassName.split(_strSpace) : [_strEmpty]; - var currClassNames = _classNameCache !== undefined && _classNameCache !== null ? _classNameCache.split(_strSpace) : [_strEmpty]; - - //remove none theme from diff list to prevent update - var idx = inArray(_classNameThemeNone, diff); - var curr; - var i; - var v; - var o; - var c; - - if (idx > -1) - diff.splice(idx, 1); - - for (i = 0; i < diff.length; i++) { - curr = diff[i]; - if (curr.indexOf(_classNameHostElement) !== 0) { - o = true; - c = true; - for (v = 0; v < oldClassNames.length; v++) { - if (curr === oldClassNames[v]) { - o = false; - break; - } - } - for (v = 0; v < currClassNames.length; v++) { - if (curr === currClassNames[v]) { - c = false; - break; - } - } - if (o && c) { - changed = true; - break; - } - } - - } - return changed; - } - - /** - * Returns true if the given mutation is not from a from the plugin generated element. If the target element is a textarea the mutation is always unknown. - * @param mutation The mutation which shall be checked. - * @returns {boolean} True if the mutation is from a unknown element, false otherwise. - */ - function isUnknownMutation(mutation) { - var attributeName = mutation.attributeName; - var mutationTarget = mutation.target; - var mutationType = mutation.type; - var strClosest = 'closest'; - - if (mutationTarget === _contentElementNative) - return attributeName === null; - if (mutationType === 'attributes' && (attributeName === LEXICON.c || attributeName === LEXICON.s) && !_isTextarea) { - //ignore className changes by the plugin - if (attributeName === LEXICON.c && FRAMEWORK(mutationTarget).hasClass(_classNameHostElement)) - return hostClassNamesChanged(mutation.oldValue, mutationTarget.getAttribute(LEXICON.c)); - - //only do it of browser support it natively - if (typeof mutationTarget[strClosest] != TYPES.f) - return true; - if (mutationTarget[strClosest](_strDot + _classNameResizeObserverElement) !== null || - mutationTarget[strClosest](_strDot + _classNameScrollbar) !== null || - mutationTarget[strClosest](_strDot + _classNameScrollbarCorner) !== null) - return false; - } - return true; - } - - /** - * Returns true if the content size was changed since the last time this method was called. - * @returns {boolean} True if the content size was changed, false otherwise. - */ - function updateAutoContentSizeChanged() { - if (_sleeping) - return false; - - var contentMeasureElement = getContentMeasureElement(); - var textareaValueLength = _isTextarea && _widthAutoCache && !_textareaAutoWrappingCache ? _targetElement.val().length : 0; - var setCSS = !_mutationObserversConnected && _widthAutoCache && !_isTextarea; - var css = {}; - var float; - var bodyMinSizeC; - var changed; - var contentElementScrollSize; - - if (setCSS) { - float = _contentElement.css(_strFloat); - css[_strFloat] = _isRTL ? _strRight : _strLeft; - css[_strWidth] = _strAuto; - _contentElement.css(css); - } - contentElementScrollSize = { - w: contentMeasureElement[LEXICON.sW] + textareaValueLength, - h: contentMeasureElement[LEXICON.sH] + textareaValueLength - }; - if (setCSS) { - css[_strFloat] = float; - css[_strWidth] = _strHundredPercent; - _contentElement.css(css); - } - - bodyMinSizeC = bodyMinSizeChanged(); - changed = checkCache(contentElementScrollSize, _contentElementScrollSizeChangeDetectedCache); - - _contentElementScrollSizeChangeDetectedCache = contentElementScrollSize; - - return changed || bodyMinSizeC; - } - - /** - * Returns true when a attribute which the MutationObserver would observe has changed. - * @returns {boolean} True if one of the attributes which a MutationObserver would observe has changed, false or undefined otherwise. - */ - function meaningfulAttrsChanged() { - if (_sleeping || _mutationObserversConnected) - return; - - var elem; - var curr; - var cache; - var changedAttrs = []; - var checks = [ - { - _elem: _hostElement, - _attrs: _mutationObserverAttrsHost.concat(':visible') - }, - { - _elem: _isTextarea ? _targetElement : undefined, - _attrs: _mutationObserverAttrsTextarea - } - ]; - - each(checks, function (index, check) { - elem = check._elem; - if (elem) { - each(check._attrs, function (index, attr) { - curr = attr.charAt(0) === ':' ? elem.is(attr) : elem.attr(attr); - cache = _updateAutoCache[attr]; - - if(checkCache(curr, cache)) { - changedAttrs.push(attr); - } - - _updateAutoCache[attr] = curr; - }); - } - }); - - updateViewportAttrsFromTarget(changedAttrs); - - return changedAttrs[LEXICON.l] > 0; - } - - /** - * Checks is a CSS Property of a child element is affecting the scroll size of the content. - * @param propertyName The CSS property name. - * @returns {boolean} True if the property is affecting the content scroll size, false otherwise. - */ - function isSizeAffectingCSSProperty(propertyName) { - if (!_initialized) - return true; - var flexGrow = 'flex-grow'; - var flexShrink = 'flex-shrink'; - var flexBasis = 'flex-basis'; - var affectingPropsX = [ - _strWidth, - _strMinMinus + _strWidth, - _strMaxMinus + _strWidth, - _strMarginMinus + _strLeft, - _strMarginMinus + _strRight, - _strLeft, - _strRight, - 'font-weight', - 'word-spacing', - flexGrow, - flexShrink, - flexBasis - ]; - var affectingPropsXContentBox = [ - _strPaddingMinus + _strLeft, - _strPaddingMinus + _strRight, - _strBorderMinus + _strLeft + _strWidth, - _strBorderMinus + _strRight + _strWidth - ]; - var affectingPropsY = [ - _strHeight, - _strMinMinus + _strHeight, - _strMaxMinus + _strHeight, - _strMarginMinus + _strTop, - _strMarginMinus + _strBottom, - _strTop, - _strBottom, - 'line-height', - flexGrow, - flexShrink, - flexBasis - ]; - var affectingPropsYContentBox = [ - _strPaddingMinus + _strTop, - _strPaddingMinus + _strBottom, - _strBorderMinus + _strTop + _strWidth, - _strBorderMinus + _strBottom + _strWidth - ]; - var _strS = 's'; - var _strVS = 'v-s'; - var checkX = _overflowBehaviorCache.x === _strS || _overflowBehaviorCache.x === _strVS; - var checkY = _overflowBehaviorCache.y === _strS || _overflowBehaviorCache.y === _strVS; - var sizeIsAffected = false; - var checkPropertyName = function (arr, name) { - for (var i = 0; i < arr[LEXICON.l]; i++) { - if (arr[i] === name) - return true; - } - return false; - }; - - if (checkY) { - sizeIsAffected = checkPropertyName(affectingPropsY, propertyName); - if (!sizeIsAffected && !_isBorderBox) - sizeIsAffected = checkPropertyName(affectingPropsYContentBox, propertyName); - } - if (checkX && !sizeIsAffected) { - sizeIsAffected = checkPropertyName(affectingPropsX, propertyName); - if (!sizeIsAffected && !_isBorderBox) - sizeIsAffected = checkPropertyName(affectingPropsXContentBox, propertyName); - } - return sizeIsAffected; - } - - - //==== Update ====// - - /** - * Sets the attribute values of the viewport element to the values from the target element. - * The value of a attribute is only set if the attribute is whitelisted. - * @attrs attrs The array of attributes which shall be set or undefined if all whitelisted shall be set. - */ - function updateViewportAttrsFromTarget(attrs) { - attrs = attrs || _viewportAttrsFromTarget; - each(attrs, function (index, attr) { - if (COMPATIBILITY.inA(attr, _viewportAttrsFromTarget) > -1) { - var targetAttr = _targetElement.attr(attr); - if(type(targetAttr) == TYPES.s) { - _viewportElement.attr(attr, targetAttr); - } - else { - _viewportElement.removeAttr(attr); - } - } - }); - } - - /** - * Updates the variables and size of the textarea element, and manages the scroll on new line or new character. - */ - function textareaUpdate() { - if (!_sleeping) { - var wrapAttrOff = !_textareaAutoWrappingCache; - var minWidth = _viewportSize.w; - var minHeight = _viewportSize.h; - var css = {}; - var doMeasure = _widthAutoCache || wrapAttrOff; - var origWidth; - var width; - var origHeight; - var height; - - //reset min size - css[_strMinMinus + _strWidth] = _strEmpty; - css[_strMinMinus + _strHeight] = _strEmpty; - - //set width auto - css[_strWidth] = _strAuto; - _targetElement.css(css); - - //measure width - origWidth = _targetElementNative[LEXICON.oW]; - width = doMeasure ? MATH.max(origWidth, _targetElementNative[LEXICON.sW] - 1) : 1; - /*width += (_widthAutoCache ? _marginX + (!_isBorderBox ? wrapAttrOff ? 0 : _paddingX + _borderX : 0) : 0);*/ - - //set measured width - css[_strWidth] = _widthAutoCache ? _strAuto /*width*/ : _strHundredPercent; - css[_strMinMinus + _strWidth] = _strHundredPercent; - - //set height auto - css[_strHeight] = _strAuto; - _targetElement.css(css); - - //measure height - origHeight = _targetElementNative[LEXICON.oH]; - height = MATH.max(origHeight, _targetElementNative[LEXICON.sH] - 1); - - //append correct size values - css[_strWidth] = width; - css[_strHeight] = height; - _textareaCoverElement.css(css); - - //apply min width / min height to prevent textarea collapsing - css[_strMinMinus + _strWidth] = minWidth /*+ (!_isBorderBox && _widthAutoCache ? _paddingX + _borderX : 0)*/; - css[_strMinMinus + _strHeight] = minHeight /*+ (!_isBorderBox && _heightAutoCache ? _paddingY + _borderY : 0)*/; - _targetElement.css(css); - - return { - _originalWidth: origWidth, - _originalHeight: origHeight, - _dynamicWidth: width, - _dynamicHeight: height - }; - } - } - - /** - * Updates the plugin and DOM to the current options. - * This method should only be called if a update is 100% required. - * @param updateHints A objects which contains hints for this update: - * { - * _hostSizeChanged : boolean, - * _contentSizeChanged : boolean, - * _force : boolean, == preventSwallowing - * _changedOptions : { }, == preventSwallowing && preventSleep - * } - */ - function update(updateHints) { - clearTimeout(_swallowedUpdateTimeout); - updateHints = updateHints || {}; - _swallowedUpdateHints._hostSizeChanged |= updateHints._hostSizeChanged; - _swallowedUpdateHints._contentSizeChanged |= updateHints._contentSizeChanged; - _swallowedUpdateHints._force |= updateHints._force; - - var now = COMPATIBILITY.now(); - var hostSizeChanged = !!_swallowedUpdateHints._hostSizeChanged; - var contentSizeChanged = !!_swallowedUpdateHints._contentSizeChanged; - var force = !!_swallowedUpdateHints._force; - var changedOptions = updateHints._changedOptions; - var swallow = _swallowUpdateLag > 0 && _initialized && !_destroyed && !force && !changedOptions && (now - _lastUpdateTime) < _swallowUpdateLag && (!_heightAutoCache && !_widthAutoCache); - var displayIsHidden; - - if (swallow) - _swallowedUpdateTimeout = setTimeout(update, _swallowUpdateLag); - - //abort update due to: - //destroyed - //swallowing - //sleeping - //host is hidden or has false display - if (_destroyed || swallow || (_sleeping && !changedOptions) || (_initialized && !force && (displayIsHidden = _hostElement.is(':hidden'))) || _hostElement.css('display') === 'inline') - return; - - _lastUpdateTime = now; - _swallowedUpdateHints = {}; - - //if scrollbar styling is possible and native scrollbars aren't overlaid the scrollbar styling will be applied which hides the native scrollbars completely. - if (_nativeScrollbarStyling && !(_nativeScrollbarIsOverlaid.x && _nativeScrollbarIsOverlaid.y)) { - //native scrollbars are hidden, so change the values to zero - _nativeScrollbarSize.x = 0; - _nativeScrollbarSize.y = 0; - } - else { - //refresh native scrollbar size (in case of zoom) - _nativeScrollbarSize = extendDeep({}, globals.nativeScrollbarSize); - } - - // Scrollbar padding is needed for firefox, because firefox hides scrollbar automatically if the size of the div is too small. - // The calculation: [scrollbar size +3 *3] - // (+3 because of possible decoration e.g. borders, margins etc., but only if native scrollbar is NOT a overlaid scrollbar) - // (*3 because (1)increase / (2)decrease -button and (3)resize handle) - _nativeScrollbarMinSize = { - x: (_nativeScrollbarSize.x + (_nativeScrollbarIsOverlaid.x ? 0 : 3)) * 3, - y: (_nativeScrollbarSize.y + (_nativeScrollbarIsOverlaid.y ? 0 : 3)) * 3 - }; - - //changedOptions = changedOptions || { }; - //freezeResizeObserver(_sizeObserverElement, true); - //freezeResizeObserver(_sizeAutoObserverElement, true); - - var checkCacheAutoForce = function () { - return checkCache.apply(this, [].slice.call(arguments).concat([force])); - }; - - //save current scroll offset - var currScroll = { - x: _viewportElement[_strScrollLeft](), - y: _viewportElement[_strScrollTop]() - }; - - var currentPreparedOptionsScrollbars = _currentPreparedOptions.scrollbars; - var currentPreparedOptionsTextarea = _currentPreparedOptions.textarea; - - //scrollbars visibility: - var scrollbarsVisibility = currentPreparedOptionsScrollbars.visibility; - var scrollbarsVisibilityChanged = checkCacheAutoForce(scrollbarsVisibility, _scrollbarsVisibilityCache); - - //scrollbars autoHide: - var scrollbarsAutoHide = currentPreparedOptionsScrollbars.autoHide; - var scrollbarsAutoHideChanged = checkCacheAutoForce(scrollbarsAutoHide, _scrollbarsAutoHideCache); - - //scrollbars click scrolling - var scrollbarsClickScrolling = currentPreparedOptionsScrollbars.clickScrolling; - var scrollbarsClickScrollingChanged = checkCacheAutoForce(scrollbarsClickScrolling, _scrollbarsClickScrollingCache); - - //scrollbars drag scrolling - var scrollbarsDragScrolling = currentPreparedOptionsScrollbars.dragScrolling; - var scrollbarsDragScrollingChanged = checkCacheAutoForce(scrollbarsDragScrolling, _scrollbarsDragScrollingCache); - - //className - var className = _currentPreparedOptions.className; - var classNameChanged = checkCacheAutoForce(className, _classNameCache); - - //resize - var resize = _currentPreparedOptions.resize; - var resizeChanged = checkCacheAutoForce(resize, _resizeCache) && !_isBody; //body can't be resized since the window itself acts as resize possibility. - - //paddingAbsolute - var paddingAbsolute = _currentPreparedOptions.paddingAbsolute; - var paddingAbsoluteChanged = checkCacheAutoForce(paddingAbsolute, _paddingAbsoluteCache); - - //clipAlways - var clipAlways = _currentPreparedOptions.clipAlways; - var clipAlwaysChanged = checkCacheAutoForce(clipAlways, _clipAlwaysCache); - - //sizeAutoCapable - var sizeAutoCapable = _currentPreparedOptions.sizeAutoCapable && !_isBody; //body can never be size auto, because it shall be always as big as the viewport. - var sizeAutoCapableChanged = checkCacheAutoForce(sizeAutoCapable, _sizeAutoCapableCache); - - //showNativeScrollbars - var ignoreOverlayScrollbarHiding = _currentPreparedOptions.nativeScrollbarsOverlaid.showNativeScrollbars; - var ignoreOverlayScrollbarHidingChanged = checkCacheAutoForce(ignoreOverlayScrollbarHiding, _ignoreOverlayScrollbarHidingCache); - - //autoUpdate - var autoUpdate = _currentPreparedOptions.autoUpdate; - var autoUpdateChanged = checkCacheAutoForce(autoUpdate, _autoUpdateCache); - - //overflowBehavior - var overflowBehavior = _currentPreparedOptions.overflowBehavior; - var overflowBehaviorChanged = checkCacheAutoForce(overflowBehavior, _overflowBehaviorCache, force); - - //dynWidth: - var textareaDynWidth = currentPreparedOptionsTextarea.dynWidth; - var textareaDynWidthChanged = checkCacheAutoForce(_textareaDynWidthCache, textareaDynWidth); - - //dynHeight: - var textareaDynHeight = currentPreparedOptionsTextarea.dynHeight; - var textareaDynHeightChanged = checkCacheAutoForce(_textareaDynHeightCache, textareaDynHeight); - - //scrollbars visibility - _scrollbarsAutoHideNever = scrollbarsAutoHide === 'n'; - _scrollbarsAutoHideScroll = scrollbarsAutoHide === 's'; - _scrollbarsAutoHideMove = scrollbarsAutoHide === 'm'; - _scrollbarsAutoHideLeave = scrollbarsAutoHide === 'l'; - - //scrollbars autoHideDelay - _scrollbarsAutoHideDelay = currentPreparedOptionsScrollbars.autoHideDelay; - - //old className - _oldClassName = _classNameCache; - - //resize - _resizeNone = resize === 'n'; - _resizeBoth = resize === 'b'; - _resizeHorizontal = resize === 'h'; - _resizeVertical = resize === 'v'; - - //normalizeRTL - _normalizeRTLCache = _currentPreparedOptions.normalizeRTL; - - //ignore overlay scrollbar hiding - ignoreOverlayScrollbarHiding = ignoreOverlayScrollbarHiding && (_nativeScrollbarIsOverlaid.x && _nativeScrollbarIsOverlaid.y); - - //refresh options cache - _scrollbarsVisibilityCache = scrollbarsVisibility; - _scrollbarsAutoHideCache = scrollbarsAutoHide; - _scrollbarsClickScrollingCache = scrollbarsClickScrolling; - _scrollbarsDragScrollingCache = scrollbarsDragScrolling; - _classNameCache = className; - _resizeCache = resize; - _paddingAbsoluteCache = paddingAbsolute; - _clipAlwaysCache = clipAlways; - _sizeAutoCapableCache = sizeAutoCapable; - _ignoreOverlayScrollbarHidingCache = ignoreOverlayScrollbarHiding; - _autoUpdateCache = autoUpdate; - _overflowBehaviorCache = extendDeep({}, overflowBehavior); - _textareaDynWidthCache = textareaDynWidth; - _textareaDynHeightCache = textareaDynHeight; - _hasOverflowCache = _hasOverflowCache || { x: false, y: false }; - - //set correct class name to the host element - if (classNameChanged) { - removeClass(_hostElement, _oldClassName + _strSpace + _classNameThemeNone); - addClass(_hostElement, className !== undefined && className !== null && className.length > 0 ? className : _classNameThemeNone); - } - - //set correct auto Update - if (autoUpdateChanged) { - if (autoUpdate === true) { - disconnectMutationObservers(); - autoUpdateLoop.add(_base); - } - else if (autoUpdate === null) { - if (_autoUpdateRecommended) { - disconnectMutationObservers(); - autoUpdateLoop.add(_base); - } - else { - autoUpdateLoop.remove(_base); - connectMutationObservers(); - } - } - else { - autoUpdateLoop.remove(_base); - connectMutationObservers(); - } - } - - //activate or deactivate size auto capability - if (sizeAutoCapableChanged) { - if (sizeAutoCapable) { - if (!_contentGlueElement) { - _contentGlueElement = FRAMEWORK(generateDiv(_classNameContentGlueElement)); - _paddingElement.before(_contentGlueElement); - } - else { - _contentGlueElement.show(); - } - if (_sizeAutoObserverAdded) { - _sizeAutoObserverElement.show(); - } - else { - _sizeAutoObserverElement = FRAMEWORK(generateDiv(_classNameSizeAutoObserverElement)); - _sizeAutoObserverElementNative = _sizeAutoObserverElement[0]; - - _contentGlueElement.before(_sizeAutoObserverElement); - var oldSize = { w: -1, h: -1 }; - setupResizeObserver(_sizeAutoObserverElement, function () { - var newSize = { - w: _sizeAutoObserverElementNative[LEXICON.oW], - h: _sizeAutoObserverElementNative[LEXICON.oH] - }; - if (checkCache(newSize, oldSize)) { - if (_initialized && (_heightAutoCache && newSize.h > 0) || (_widthAutoCache && newSize.w > 0)) { - update(); - } - else if (_initialized && (!_heightAutoCache && newSize.h === 0) || (!_widthAutoCache && newSize.w === 0)) { - update(); - } - } - oldSize = newSize; - }); - _sizeAutoObserverAdded = true; - //fix heightAuto detector bug if height is fixed but contentHeight is 0. - //the probability this bug will ever happen is very very low, thats why its ok if we use calc which isn't supported in IE8. - if (_cssCalc !== null) - _sizeAutoObserverElement.css(_strHeight, _cssCalc + '(100% + 1px)'); - } - } - else { - if (_sizeAutoObserverAdded) - _sizeAutoObserverElement.hide(); - if (_contentGlueElement) - _contentGlueElement.hide(); - } - } - - //if force, update all resizeObservers too - if (force) { - _sizeObserverElement.find('*').trigger(_strScroll); - if (_sizeAutoObserverAdded) - _sizeAutoObserverElement.find('*').trigger(_strScroll); - } - - //display hidden: - displayIsHidden = displayIsHidden === undefined ? _hostElement.is(':hidden') : displayIsHidden; - var displayIsHiddenChanged = checkCacheAutoForce(displayIsHidden, _displayIsHiddenCache); - - //textarea AutoWrapping: - var textareaAutoWrapping = _isTextarea ? _targetElement.attr('wrap') !== 'off' : false; - var textareaAutoWrappingChanged = checkCacheAutoForce(textareaAutoWrapping, _textareaAutoWrappingCache); - - //detect direction: - var cssDirection = _hostElement.css('direction'); - var cssDirectionChanged = checkCacheAutoForce(cssDirection, _cssDirectionCache); - - //detect box-sizing: - var boxSizing = _hostElement.css('box-sizing'); - var boxSizingChanged = checkCacheAutoForce(boxSizing, _cssBoxSizingCache); - - //detect padding: - var padding = { - c: force, - t: parseToZeroOrNumber(_hostElement.css(_strPaddingMinus + _strTop)), - r: parseToZeroOrNumber(_hostElement.css(_strPaddingMinus + _strRight)), - b: parseToZeroOrNumber(_hostElement.css(_strPaddingMinus + _strBottom)), - l: parseToZeroOrNumber(_hostElement.css(_strPaddingMinus + _strLeft)) - }; - - //width + height auto detecting var: - var sizeAutoObserverElementBCRect; - //exception occurs in IE8 sometimes (unknown exception) - try { - sizeAutoObserverElementBCRect = _sizeAutoObserverAdded ? _sizeAutoObserverElementNative[LEXICON.bCR]() : null; - } catch (ex) { - return; - } - - _isRTL = cssDirection === 'rtl'; - _isBorderBox = (boxSizing === 'border-box'); - var isRTLLeft = _isRTL ? _strLeft : _strRight; - var isRTLRight = _isRTL ? _strRight : _strLeft; - - //detect width auto: - var widthAutoResizeDetection = false; - var widthAutoObserverDetection = (_sizeAutoObserverAdded && (_hostElement.css(_strFloat) !== 'none' /*|| _isTextarea */)) ? (MATH.round(sizeAutoObserverElementBCRect.right - sizeAutoObserverElementBCRect.left) === 0) && (!paddingAbsolute ? (_hostElementNative[LEXICON.cW] - _paddingX) > 0 : true) : false; - if (sizeAutoCapable && !widthAutoObserverDetection) { - var tmpCurrHostWidth = _hostElementNative[LEXICON.oW]; - var tmpCurrContentGlueWidth = _contentGlueElement.css(_strWidth); - _contentGlueElement.css(_strWidth, _strAuto); - - var tmpNewHostWidth = _hostElementNative[LEXICON.oW]; - _contentGlueElement.css(_strWidth, tmpCurrContentGlueWidth); - widthAutoResizeDetection = tmpCurrHostWidth !== tmpNewHostWidth; - if (!widthAutoResizeDetection) { - _contentGlueElement.css(_strWidth, tmpCurrHostWidth + 1); - tmpNewHostWidth = _hostElementNative[LEXICON.oW]; - _contentGlueElement.css(_strWidth, tmpCurrContentGlueWidth); - widthAutoResizeDetection = tmpCurrHostWidth !== tmpNewHostWidth; - } - } - var widthAuto = (widthAutoObserverDetection || widthAutoResizeDetection) && sizeAutoCapable && !displayIsHidden; - var widthAutoChanged = checkCacheAutoForce(widthAuto, _widthAutoCache); - var wasWidthAuto = !widthAuto && _widthAutoCache; - - //detect height auto: - var heightAuto = _sizeAutoObserverAdded && sizeAutoCapable && !displayIsHidden ? (MATH.round(sizeAutoObserverElementBCRect.bottom - sizeAutoObserverElementBCRect.top) === 0) /* && (!paddingAbsolute && (_msieVersion > 9 || !_msieVersion) ? true : true) */ : false; - var heightAutoChanged = checkCacheAutoForce(heightAuto, _heightAutoCache); - var wasHeightAuto = !heightAuto && _heightAutoCache; - - //detect border: - //we need the border only if border box and auto size - var strMinusWidth = '-' + _strWidth; - var updateBorderX = (widthAuto && _isBorderBox) || !_isBorderBox; - var updateBorderY = (heightAuto && _isBorderBox) || !_isBorderBox; - var border = { - c: force, - t: updateBorderY ? parseToZeroOrNumber(_hostElement.css(_strBorderMinus + _strTop + strMinusWidth), true) : 0, - r: updateBorderX ? parseToZeroOrNumber(_hostElement.css(_strBorderMinus + _strRight + strMinusWidth), true) : 0, - b: updateBorderY ? parseToZeroOrNumber(_hostElement.css(_strBorderMinus + _strBottom + strMinusWidth), true) : 0, - l: updateBorderX ? parseToZeroOrNumber(_hostElement.css(_strBorderMinus + _strLeft + strMinusWidth), true) : 0 - }; - - //detect margin: - var margin = { - c: force, - t: parseToZeroOrNumber(_hostElement.css(_strMarginMinus + _strTop)), - r: parseToZeroOrNumber(_hostElement.css(_strMarginMinus + _strRight)), - b: parseToZeroOrNumber(_hostElement.css(_strMarginMinus + _strBottom)), - l: parseToZeroOrNumber(_hostElement.css(_strMarginMinus + _strLeft)) - }; - - //detect css max width & height: - var cssMaxValue = { - h: String(_hostElement.css(_strMaxMinus + _strHeight)), - w: String(_hostElement.css(_strMaxMinus + _strWidth)) - }; - - //vars to apply correct css - var contentElementCSS = {}; - var contentGlueElementCSS = {}; - - //funcs - var getHostSize = function () { - //has to be clientSize because offsetSize respect borders - return { - w: _hostElementNative[LEXICON.cW], - h: _hostElementNative[LEXICON.cH] - }; - }; - var getViewportSize = function () { - //viewport size is padding container because it never has padding, margin and a border - //determine zoom rounding error -> sometimes scrollWidth/Height is smaller than clientWidth/Height - //if this happens add the difference to the viewportSize to compensate the rounding error - return { - w: _paddingElementNative[LEXICON.oW] + MATH.max(0, _contentElementNative[LEXICON.cW] - _contentElementNative[LEXICON.sW]), - h: _paddingElementNative[LEXICON.oH] + MATH.max(0, _contentElementNative[LEXICON.cH] - _contentElementNative[LEXICON.sH]) - }; - }; - - //set info for padding - var paddingAbsoluteX = _paddingX = padding.l + padding.r; - var paddingAbsoluteY = _paddingY = padding.t + padding.b; - paddingAbsoluteX *= paddingAbsolute ? 1 : 0; - paddingAbsoluteY *= paddingAbsolute ? 1 : 0; - padding.c = checkCacheAutoForce(padding, _cssPaddingCache); - - //set info for border - _borderX = border.l + border.r; - _borderY = border.t + border.b; - border.c = checkCacheAutoForce(border, _cssBorderCache); - - //set info for margin - _marginX = margin.l + margin.r; - _marginY = margin.t + margin.b; - margin.c = checkCacheAutoForce(margin, _cssMarginCache); - - //set info for css max value - cssMaxValue.ih = parseToZeroOrNumber(cssMaxValue.h); //ih = integer height - cssMaxValue.iw = parseToZeroOrNumber(cssMaxValue.w); //iw = integer width - cssMaxValue.ch = cssMaxValue.h.indexOf('px') > -1; //ch = correct height - cssMaxValue.cw = cssMaxValue.w.indexOf('px') > -1; //cw = correct width - cssMaxValue.c = checkCacheAutoForce(cssMaxValue, _cssMaxValueCache); - - //refresh cache - _displayIsHiddenCache = displayIsHidden; - _textareaAutoWrappingCache = textareaAutoWrapping; - _cssDirectionCache = cssDirection; - _cssBoxSizingCache = boxSizing; - _widthAutoCache = widthAuto; - _heightAutoCache = heightAuto; - _cssPaddingCache = padding; - _cssBorderCache = border; - _cssMarginCache = margin; - _cssMaxValueCache = cssMaxValue; - - //IEFix direction changed - if (cssDirectionChanged && _sizeAutoObserverAdded) - _sizeAutoObserverElement.css(_strFloat, isRTLRight); - - //apply padding: - if (padding.c || cssDirectionChanged || paddingAbsoluteChanged || widthAutoChanged || heightAutoChanged || boxSizingChanged || sizeAutoCapableChanged) { - var paddingElementCSS = {}; - var textareaCSS = {}; - setTopRightBottomLeft(contentGlueElementCSS, _strMarginMinus, [-padding.t, -padding.r, -padding.b, -padding.l]); - if (paddingAbsolute) { - setTopRightBottomLeft(paddingElementCSS, _strEmpty, [padding.t, padding.r, padding.b, padding.l]); - if (_isTextarea) - setTopRightBottomLeft(textareaCSS, _strPaddingMinus); - else - setTopRightBottomLeft(contentElementCSS, _strPaddingMinus); - } - else { - setTopRightBottomLeft(paddingElementCSS, _strEmpty); - if (_isTextarea) - setTopRightBottomLeft(textareaCSS, _strPaddingMinus, [padding.t, padding.r, padding.b, padding.l]); - else - setTopRightBottomLeft(contentElementCSS, _strPaddingMinus, [padding.t, padding.r, padding.b, padding.l]); - } - _paddingElement.css(paddingElementCSS); - _targetElement.css(textareaCSS); - } - - //viewport size is padding container because it never has padding, margin and a border. - _viewportSize = getViewportSize(); - - //update Textarea - var textareaSize = _isTextarea ? textareaUpdate() : false; - var textareaSizeChanged = _isTextarea && checkCacheAutoForce(textareaSize, _textareaSizeCache); - var textareaDynOrigSize = _isTextarea && textareaSize ? { - w: textareaDynWidth ? textareaSize._dynamicWidth : textareaSize._originalWidth, - h: textareaDynHeight ? textareaSize._dynamicHeight : textareaSize._originalHeight - } : {}; - _textareaSizeCache = textareaSize; - - //fix height auto / width auto in cooperation with current padding & boxSizing behavior: - if (heightAuto && (heightAutoChanged || paddingAbsoluteChanged || boxSizingChanged || cssMaxValue.c || padding.c || border.c)) { - /* - if (cssMaxValue.ch) - contentElementCSS[_strMaxMinus + _strHeight] = - (cssMaxValue.ch ? (cssMaxValue.ih - paddingAbsoluteY + (_isBorderBox ? -_borderY : _paddingY)) - : _strEmpty); - */ - contentElementCSS[_strHeight] = _strAuto; - } - else if (heightAutoChanged || paddingAbsoluteChanged) { - contentElementCSS[_strMaxMinus + _strHeight] = _strEmpty; - contentElementCSS[_strHeight] = _strHundredPercent; - } - if (widthAuto && (widthAutoChanged || paddingAbsoluteChanged || boxSizingChanged || cssMaxValue.c || padding.c || border.c || cssDirectionChanged)) { - /* - if (cssMaxValue.cw) - contentElementCSS[_strMaxMinus + _strWidth] = - (cssMaxValue.cw ? (cssMaxValue.iw - paddingAbsoluteX + (_isBorderBox ? -_borderX : _paddingX)) + - (_nativeScrollbarIsOverlaid.y ? _overlayScrollbarDummySize.y : 0) - : _strEmpty); - */ - contentElementCSS[_strWidth] = _strAuto; - contentGlueElementCSS[_strMaxMinus + _strWidth] = _strHundredPercent; //IE Fix - } - else if (widthAutoChanged || paddingAbsoluteChanged) { - contentElementCSS[_strMaxMinus + _strWidth] = _strEmpty; - contentElementCSS[_strWidth] = _strHundredPercent; - contentElementCSS[_strFloat] = _strEmpty; - contentGlueElementCSS[_strMaxMinus + _strWidth] = _strEmpty; //IE Fix - } - if (widthAuto) { - if (!cssMaxValue.cw) - contentElementCSS[_strMaxMinus + _strWidth] = _strEmpty; - //textareaDynOrigSize.w || _strAuto :: doesnt works because applied margin will shift width - contentGlueElementCSS[_strWidth] = _strAuto; - - contentElementCSS[_strWidth] = _strAuto; - contentElementCSS[_strFloat] = isRTLRight; - } - else { - contentGlueElementCSS[_strWidth] = _strEmpty; - } - if (heightAuto) { - if (!cssMaxValue.ch) - contentElementCSS[_strMaxMinus + _strHeight] = _strEmpty; - //textareaDynOrigSize.h || _contentElementNative[LEXICON.cH] :: use for anti scroll jumping - contentGlueElementCSS[_strHeight] = textareaDynOrigSize.h || _contentElementNative[LEXICON.cH]; - } - else { - contentGlueElementCSS[_strHeight] = _strEmpty; - } - if (sizeAutoCapable) - _contentGlueElement.css(contentGlueElementCSS); - _contentElement.css(contentElementCSS); - - //CHECKPOINT HERE ~ - contentElementCSS = {}; - contentGlueElementCSS = {}; - - //if [content(host) client / scroll size, or target element direction, or content(host) max-sizes] changed, or force is true - if (hostSizeChanged || contentSizeChanged || textareaSizeChanged || cssDirectionChanged || boxSizingChanged || paddingAbsoluteChanged || widthAutoChanged || widthAuto || heightAutoChanged || heightAuto || cssMaxValue.c || ignoreOverlayScrollbarHidingChanged || overflowBehaviorChanged || clipAlwaysChanged || resizeChanged || scrollbarsVisibilityChanged || scrollbarsAutoHideChanged || scrollbarsDragScrollingChanged || scrollbarsClickScrollingChanged || textareaDynWidthChanged || textareaDynHeightChanged || textareaAutoWrappingChanged) { - var strOverflow = 'overflow'; - var strOverflowX = strOverflow + '-x'; - var strOverflowY = strOverflow + '-y'; - var strHidden = 'hidden'; - var strVisible = 'visible'; - - //Reset the viewport (very important for natively overlaid scrollbars and zoom change - //don't change the overflow prop as it is very expensive and affects performance !A LOT! - if(!_nativeScrollbarStyling) { - var viewportElementResetCSS = {}; - var resetXTmp = _hasOverflowCache.y && _hideOverflowCache.ys && !ignoreOverlayScrollbarHiding ? (_nativeScrollbarIsOverlaid.y ? _viewportElement.css(isRTLLeft) : -_nativeScrollbarSize.y) : 0; - var resetBottomTmp = _hasOverflowCache.x && _hideOverflowCache.xs && !ignoreOverlayScrollbarHiding ? (_nativeScrollbarIsOverlaid.x ? _viewportElement.css(_strBottom) : -_nativeScrollbarSize.x) : 0; - setTopRightBottomLeft(viewportElementResetCSS, _strEmpty); - _viewportElement.css(viewportElementResetCSS); - } - - //measure several sizes: - var contentMeasureElement = getContentMeasureElement(); - //in Firefox content element has to have overflow hidden, else element margins aren't calculated properly, this element prevents this bug, but only if scrollbars aren't overlaid - var contentSize = { - //use clientSize because natively overlaidScrollbars add borders - w: textareaDynOrigSize.w || contentMeasureElement[LEXICON.cW], - h: textareaDynOrigSize.h || contentMeasureElement[LEXICON.cH] - }; - var scrollSize = { - w: contentMeasureElement[LEXICON.sW], - h: contentMeasureElement[LEXICON.sH] - }; - - //apply the correct viewport style and measure viewport size - if(!_nativeScrollbarStyling) { - viewportElementResetCSS[_strBottom] = wasHeightAuto ? _strEmpty : resetBottomTmp; - viewportElementResetCSS[isRTLLeft] = wasWidthAuto ? _strEmpty : resetXTmp; - _viewportElement.css(viewportElementResetCSS); - } - _viewportSize = getViewportSize(); - - //measure and correct several sizes - var hostSize = getHostSize(); - var contentGlueSize = { - //client/scrollSize + AbsolutePadding -> because padding is only applied to the paddingElement if its absolute, so you have to add it manually - //hostSize is clientSize -> so padding should be added manually, right? FALSE! Because content glue is inside hostElement, so we don't have to worry about padding - w: MATH.max((widthAuto ? contentSize.w : scrollSize.w) + paddingAbsoluteX, hostSize.w), - h: MATH.max((heightAuto ? contentSize.h : scrollSize.h) + paddingAbsoluteY, hostSize.h) - }; - contentGlueSize.c = checkCacheAutoForce(contentGlueSize, _contentGlueSizeCache); - _contentGlueSizeCache = contentGlueSize; - - //apply correct contentGlue size - if (sizeAutoCapable) { - //size contentGlue correctly to make sure the element has correct size if the sizing switches to auto - if (contentGlueSize.c || (heightAuto || widthAuto)) { - contentGlueElementCSS[_strWidth] = contentGlueSize.w; - contentGlueElementCSS[_strHeight] = contentGlueSize.h; - - //textarea-sizes are already calculated correctly at this point - if (!_isTextarea) { - contentSize = { - //use clientSize because natively overlaidScrollbars add borders - w: contentMeasureElement[LEXICON.cW], - h: contentMeasureElement[LEXICON.cH] - }; - } - } - var textareaCoverCSS = {}; - var setContentGlueElementCSSfunction = function (horizontal) { - var scrollbarVars = getScrollbarVars(horizontal); - var wh = scrollbarVars._w_h; - var strWH = scrollbarVars._width_height; - var autoSize = horizontal ? widthAuto : heightAuto; - var borderSize = horizontal ? _borderX : _borderY; - var paddingSize = horizontal ? _paddingX : _paddingY; - var marginSize = horizontal ? _marginX : _marginY; - var maxSize = contentGlueElementCSS[strWH] + (_isBorderBox ? borderSize : -paddingSize); - - //make contentGlue size -1 if element is not auto sized, to make sure that a resize event happens when the element shrinks - if (!autoSize || (!autoSize && border.c)) - contentGlueElementCSS[strWH] = hostSize[wh] - (_isBorderBox ? 0 : paddingSize + borderSize) - 1 - marginSize; - - //if size is auto and host is same size as max size, make content glue size +1 to make sure size changes will be detected - if (autoSize && cssMaxValue['c' + wh] && cssMaxValue['i' + wh] === maxSize) - contentGlueElementCSS[strWH] = maxSize + (_isBorderBox ? 0 : paddingSize) + 1; - - //if size is auto and host is smaller than size as min size, make content glue size -1 to make sure size changes will be detected (this is only needed if padding is 0) - if (autoSize && (contentSize[wh] < _viewportSize[wh]) && (horizontal && _isTextarea ? !textareaAutoWrapping : true)) { - if (_isTextarea) - textareaCoverCSS[strWH] = parseToZeroOrNumber(_textareaCoverElement.css(strWH)) - 1; - contentGlueElementCSS[strWH] -= 1; - } - - //make sure content glue size is at least 1 - if (contentSize[wh] > 0) - contentGlueElementCSS[strWH] = MATH.max(1, contentGlueElementCSS[strWH]); - }; - setContentGlueElementCSSfunction(true); - setContentGlueElementCSSfunction(false); - - if (_isTextarea) - _textareaCoverElement.css(textareaCoverCSS); - _contentGlueElement.css(contentGlueElementCSS); - } - if (widthAuto) - contentElementCSS[_strWidth] = _strHundredPercent; - if (widthAuto && !_isBorderBox && !_mutationObserversConnected) - contentElementCSS[_strFloat] = 'none'; - - //apply and reset content style - _contentElement.css(contentElementCSS); - contentElementCSS = {}; - - //measure again, but this time all correct sizes: - var contentScrollSize = { - w: contentMeasureElement[LEXICON.sW], - h: contentMeasureElement[LEXICON.sH], - }; - contentScrollSize.c = contentSizeChanged = checkCacheAutoForce(contentScrollSize, _contentScrollSizeCache); - _contentScrollSizeCache = contentScrollSize; - - //refresh viewport size after correct measuring - _viewportSize = getViewportSize(); - - hostSize = getHostSize(); - hostSizeChanged = checkCacheAutoForce(hostSize, _hostSizeCache); - _hostSizeCache = hostSize; - - var hideOverflowForceTextarea = _isTextarea && (_viewportSize.w === 0 || _viewportSize.h === 0); - var previousOverflowAmount = _overflowAmountCache; - var overflowBehaviorIsVS = {}; - var overflowBehaviorIsVH = {}; - var overflowBehaviorIsS = {}; - var overflowAmount = {}; - var hasOverflow = {}; - var hideOverflow = {}; - var canScroll = {}; - var viewportRect = _paddingElementNative[LEXICON.bCR](); - var setOverflowVariables = function (horizontal) { - var scrollbarVars = getScrollbarVars(horizontal); - var scrollbarVarsInverted = getScrollbarVars(!horizontal); - var xyI = scrollbarVarsInverted._x_y; - var xy = scrollbarVars._x_y; - var wh = scrollbarVars._w_h; - var widthHeight = scrollbarVars._width_height; - var scrollMax = _strScroll + scrollbarVars._Left_Top + 'Max'; - var fractionalOverflowAmount = viewportRect[widthHeight] ? MATH.abs(viewportRect[widthHeight] - _viewportSize[wh]) : 0; - var checkFractionalOverflowAmount = previousOverflowAmount && previousOverflowAmount[xy] > 0 && _viewportElementNative[scrollMax] === 0; - overflowBehaviorIsVS[xy] = overflowBehavior[xy] === 'v-s'; - overflowBehaviorIsVH[xy] = overflowBehavior[xy] === 'v-h'; - overflowBehaviorIsS[xy] = overflowBehavior[xy] === 's'; - overflowAmount[xy] = MATH.max(0, MATH.round((contentScrollSize[wh] - _viewportSize[wh]) * 100) / 100); - overflowAmount[xy] *= (hideOverflowForceTextarea || (checkFractionalOverflowAmount && fractionalOverflowAmount > 0 && fractionalOverflowAmount < 1)) ? 0 : 1; - hasOverflow[xy] = overflowAmount[xy] > 0; - - //hideOverflow: - //x || y : true === overflow is hidden by "overflow: scroll" OR "overflow: hidden" - //xs || ys : true === overflow is hidden by "overflow: scroll" - hideOverflow[xy] = overflowBehaviorIsVS[xy] || overflowBehaviorIsVH[xy] ? (hasOverflow[xyI] && !overflowBehaviorIsVS[xyI] && !overflowBehaviorIsVH[xyI]) : hasOverflow[xy]; - hideOverflow[xy + 's'] = hideOverflow[xy] ? (overflowBehaviorIsS[xy] || overflowBehaviorIsVS[xy]) : false; - - canScroll[xy] = hasOverflow[xy] && hideOverflow[xy + 's']; - }; - setOverflowVariables(true); - setOverflowVariables(false); - - overflowAmount.c = checkCacheAutoForce(overflowAmount, _overflowAmountCache); - _overflowAmountCache = overflowAmount; - hasOverflow.c = checkCacheAutoForce(hasOverflow, _hasOverflowCache); - _hasOverflowCache = hasOverflow; - hideOverflow.c = checkCacheAutoForce(hideOverflow, _hideOverflowCache); - _hideOverflowCache = hideOverflow; - - //if native scrollbar is overlay at x OR y axis, prepare DOM - if (_nativeScrollbarIsOverlaid.x || _nativeScrollbarIsOverlaid.y) { - var borderDesign = 'px solid transparent'; - var contentArrangeElementCSS = {}; - var arrangeContent = {}; - var arrangeChanged = force; - var setContentElementCSS; - - if (hasOverflow.x || hasOverflow.y) { - arrangeContent.w = _nativeScrollbarIsOverlaid.y && hasOverflow.y ? contentScrollSize.w + _overlayScrollbarDummySize.y : _strEmpty; - arrangeContent.h = _nativeScrollbarIsOverlaid.x && hasOverflow.x ? contentScrollSize.h + _overlayScrollbarDummySize.x : _strEmpty; - arrangeChanged = checkCacheAutoForce(arrangeContent, _arrangeContentSizeCache); - _arrangeContentSizeCache = arrangeContent; - } - - if (hasOverflow.c || hideOverflow.c || contentScrollSize.c || cssDirectionChanged || widthAutoChanged || heightAutoChanged || widthAuto || heightAuto || ignoreOverlayScrollbarHidingChanged) { - contentElementCSS[_strMarginMinus + isRTLRight] = contentElementCSS[_strBorderMinus + isRTLRight] = _strEmpty; - setContentElementCSS = function (horizontal) { - var scrollbarVars = getScrollbarVars(horizontal); - var scrollbarVarsInverted = getScrollbarVars(!horizontal); - var xy = scrollbarVars._x_y; - var strDirection = horizontal ? _strBottom : isRTLLeft; - var invertedAutoSize = horizontal ? heightAuto : widthAuto; - - if (_nativeScrollbarIsOverlaid[xy] && hasOverflow[xy] && hideOverflow[xy + 's']) { - contentElementCSS[_strMarginMinus + strDirection] = invertedAutoSize ? (ignoreOverlayScrollbarHiding ? _strEmpty : _overlayScrollbarDummySize[xy]) : _strEmpty; - contentElementCSS[_strBorderMinus + strDirection] = ((horizontal ? !invertedAutoSize : true) && !ignoreOverlayScrollbarHiding) ? (_overlayScrollbarDummySize[xy] + borderDesign) : _strEmpty; - } - else { - arrangeContent[scrollbarVarsInverted._w_h] = - contentElementCSS[_strMarginMinus + strDirection] = - contentElementCSS[_strBorderMinus + strDirection] = _strEmpty; - arrangeChanged = true; - } - }; - - if (_nativeScrollbarStyling) { - if (ignoreOverlayScrollbarHiding) - removeClass(_viewportElement, _classNameViewportNativeScrollbarsInvisible); - else - addClass(_viewportElement, _classNameViewportNativeScrollbarsInvisible); - } - else { - setContentElementCSS(true); - setContentElementCSS(false); - } - } - if (ignoreOverlayScrollbarHiding) { - arrangeContent.w = arrangeContent.h = _strEmpty; - arrangeChanged = true; - } - if (arrangeChanged && !_nativeScrollbarStyling) { - contentArrangeElementCSS[_strWidth] = hideOverflow.y ? arrangeContent.w : _strEmpty; - contentArrangeElementCSS[_strHeight] = hideOverflow.x ? arrangeContent.h : _strEmpty; - - if (!_contentArrangeElement) { - _contentArrangeElement = FRAMEWORK(generateDiv(_classNameContentArrangeElement)); - _viewportElement.prepend(_contentArrangeElement); - } - _contentArrangeElement.css(contentArrangeElementCSS); - } - _contentElement.css(contentElementCSS); - } - - var viewportElementCSS = {}; - var paddingElementCSS = {}; - var setViewportCSS; - if (hostSizeChanged || hasOverflow.c || hideOverflow.c || contentScrollSize.c || overflowBehaviorChanged || boxSizingChanged || ignoreOverlayScrollbarHidingChanged || cssDirectionChanged || clipAlwaysChanged || heightAutoChanged) { - viewportElementCSS[isRTLRight] = _strEmpty; - setViewportCSS = function (horizontal) { - var scrollbarVars = getScrollbarVars(horizontal); - var scrollbarVarsInverted = getScrollbarVars(!horizontal); - var xy = scrollbarVars._x_y; - var XY = scrollbarVars._X_Y; - var strDirection = horizontal ? _strBottom : isRTLLeft; - - var reset = function () { - viewportElementCSS[strDirection] = _strEmpty; - _contentBorderSize[scrollbarVarsInverted._w_h] = 0; - }; - if (hasOverflow[xy] && hideOverflow[xy + 's']) { - viewportElementCSS[strOverflow + XY] = _strScroll; - if (ignoreOverlayScrollbarHiding || _nativeScrollbarStyling) { - reset(); - } - else { - viewportElementCSS[strDirection] = -(_nativeScrollbarIsOverlaid[xy] ? _overlayScrollbarDummySize[xy] : _nativeScrollbarSize[xy]); - _contentBorderSize[scrollbarVarsInverted._w_h] = _nativeScrollbarIsOverlaid[xy] ? _overlayScrollbarDummySize[scrollbarVarsInverted._x_y] : 0; - } - } else { - viewportElementCSS[strOverflow + XY] = _strEmpty; - reset(); - } - }; - setViewportCSS(true); - setViewportCSS(false); - - // if the scroll container is too small and if there is any overflow with no overlay scrollbar (and scrollbar styling isn't possible), - // make viewport element greater in size (Firefox hide Scrollbars fix) - // because firefox starts hiding scrollbars on too small elements - // with this behavior the overflow calculation may be incorrect or the scrollbars would appear suddenly - // https://bugzilla.mozilla.org/show_bug.cgi?id=292284 - if (!_nativeScrollbarStyling - && (_viewportSize.h < _nativeScrollbarMinSize.x || _viewportSize.w < _nativeScrollbarMinSize.y) - && ((hasOverflow.x && hideOverflow.x && !_nativeScrollbarIsOverlaid.x) || (hasOverflow.y && hideOverflow.y && !_nativeScrollbarIsOverlaid.y))) { - viewportElementCSS[_strPaddingMinus + _strTop] = _nativeScrollbarMinSize.x; - viewportElementCSS[_strMarginMinus + _strTop] = -_nativeScrollbarMinSize.x; - - viewportElementCSS[_strPaddingMinus + isRTLRight] = _nativeScrollbarMinSize.y; - viewportElementCSS[_strMarginMinus + isRTLRight] = -_nativeScrollbarMinSize.y; - } - else { - viewportElementCSS[_strPaddingMinus + _strTop] = - viewportElementCSS[_strMarginMinus + _strTop] = - viewportElementCSS[_strPaddingMinus + isRTLRight] = - viewportElementCSS[_strMarginMinus + isRTLRight] = _strEmpty; - } - viewportElementCSS[_strPaddingMinus + isRTLLeft] = - viewportElementCSS[_strMarginMinus + isRTLLeft] = _strEmpty; - - //if there is any overflow (x OR y axis) and this overflow shall be hidden, make overflow hidden, else overflow visible - if ((hasOverflow.x && hideOverflow.x) || (hasOverflow.y && hideOverflow.y) || hideOverflowForceTextarea) { - //only hide if is Textarea - if (_isTextarea && hideOverflowForceTextarea) { - paddingElementCSS[strOverflowX] = - paddingElementCSS[strOverflowY] = strHidden; - } - } - else { - if (!clipAlways || (overflowBehaviorIsVH.x || overflowBehaviorIsVS.x || overflowBehaviorIsVH.y || overflowBehaviorIsVS.y)) { - //only un-hide if Textarea - if (_isTextarea) { - paddingElementCSS[strOverflowX] = - paddingElementCSS[strOverflowY] = _strEmpty; - } - viewportElementCSS[strOverflowX] = - viewportElementCSS[strOverflowY] = strVisible; - } - } - - _paddingElement.css(paddingElementCSS); - _viewportElement.css(viewportElementCSS); - viewportElementCSS = {}; - - //force soft redraw in webkit because without the scrollbars will may appear because DOM wont be redrawn under special conditions - if ((hasOverflow.c || boxSizingChanged || widthAutoChanged || heightAutoChanged) && !(_nativeScrollbarIsOverlaid.x && _nativeScrollbarIsOverlaid.y)) { - var elementStyle = _contentElementNative[LEXICON.s]; - var dump; - elementStyle.webkitTransform = 'scale(1)'; - elementStyle.display = 'run-in'; - dump = _contentElementNative[LEXICON.oH]; - elementStyle.display = _strEmpty; //|| dump; //use dump to prevent it from deletion if minify - elementStyle.webkitTransform = _strEmpty; - } - /* - //force hard redraw in webkit if native overlaid scrollbars shall appear - if (ignoreOverlayScrollbarHidingChanged && ignoreOverlayScrollbarHiding) { - _hostElement.hide(); - var dump = _hostElementNative[LEXICON.oH]; - _hostElement.show(); - } - */ - } - - //change to direction RTL and width auto Bugfix in Webkit - //without this fix, the DOM still thinks the scrollbar is LTR and thus the content is shifted to the left - contentElementCSS = {}; - if (cssDirectionChanged || widthAutoChanged || heightAutoChanged) { - if (_isRTL && widthAuto) { - var floatTmp = _contentElement.css(_strFloat); - var posLeftWithoutFloat = MATH.round(_contentElement.css(_strFloat, _strEmpty).css(_strLeft, _strEmpty).position().left); - _contentElement.css(_strFloat, floatTmp); - var posLeftWithFloat = MATH.round(_contentElement.position().left); - - if (posLeftWithoutFloat !== posLeftWithFloat) - contentElementCSS[_strLeft] = posLeftWithoutFloat; - } - else { - contentElementCSS[_strLeft] = _strEmpty; - } - } - _contentElement.css(contentElementCSS); - - //handle scroll position - if (_isTextarea && contentSizeChanged) { - var textareaInfo = getTextareaInfo(); - if (textareaInfo) { - var textareaRowsChanged = _textareaInfoCache === undefined ? true : textareaInfo._rows !== _textareaInfoCache._rows; - var cursorRow = textareaInfo._cursorRow; - var cursorCol = textareaInfo._cursorColumn; - var widestRow = textareaInfo._widestRow; - var lastRow = textareaInfo._rows; - var lastCol = textareaInfo._columns; - var cursorPos = textareaInfo._cursorPosition; - var cursorMax = textareaInfo._cursorMax; - var cursorIsLastPosition = (cursorPos >= cursorMax && _textareaHasFocus); - var textareaScrollAmount = { - x: (!textareaAutoWrapping && (cursorCol === lastCol && cursorRow === widestRow)) ? _overflowAmountCache.x : -1, - y: (textareaAutoWrapping ? cursorIsLastPosition || textareaRowsChanged && (previousOverflowAmount ? (currScroll.y === previousOverflowAmount.y) : false) : (cursorIsLastPosition || textareaRowsChanged) && cursorRow === lastRow) ? _overflowAmountCache.y : -1 - }; - currScroll.x = textareaScrollAmount.x > -1 ? (_isRTL && _normalizeRTLCache && _rtlScrollBehavior.i ? 0 : textareaScrollAmount.x) : currScroll.x; //if inverted, scroll to 0 -> normalized this means to max scroll offset. - currScroll.y = textareaScrollAmount.y > -1 ? textareaScrollAmount.y : currScroll.y; - } - _textareaInfoCache = textareaInfo; - } - if (_isRTL && _rtlScrollBehavior.i && _nativeScrollbarIsOverlaid.y && hasOverflow.x && _normalizeRTLCache) - currScroll.x += _contentBorderSize.w || 0; - if (widthAuto) - _hostElement[_strScrollLeft](0); - if (heightAuto) - _hostElement[_strScrollTop](0); - _viewportElement[_strScrollLeft](currScroll.x)[_strScrollTop](currScroll.y); - - //scrollbars management: - var scrollbarsVisibilityVisible = scrollbarsVisibility === 'v'; - var scrollbarsVisibilityHidden = scrollbarsVisibility === 'h'; - var scrollbarsVisibilityAuto = scrollbarsVisibility === 'a'; - - var showScrollbarH = COMPATIBILITY.bind(refreshScrollbarAppearance, 0, true, true, canScroll.x); - var showScrollbarV = COMPATIBILITY.bind(refreshScrollbarAppearance, 0, false, true, canScroll.y); - var hideScrollbarH = COMPATIBILITY.bind(refreshScrollbarAppearance, 0, true, false, canScroll.x); - var hideScrollbarV = COMPATIBILITY.bind(refreshScrollbarAppearance, 0, false, false, canScroll.y); - - //manage class name which indicates scrollable overflow - if (hideOverflow.x || hideOverflow.y) - addClass(_hostElement, _classNameHostOverflow); - else - removeClass(_hostElement, _classNameHostOverflow); - if (hideOverflow.x) - addClass(_hostElement, _classNameHostOverflowX); - else - removeClass(_hostElement, _classNameHostOverflowX); - if (hideOverflow.y) - addClass(_hostElement, _classNameHostOverflowY); - else - removeClass(_hostElement, _classNameHostOverflowY); - - //add or remove rtl class name for styling purposes - if (cssDirectionChanged) { - if (_isRTL) - addClass(_hostElement, _classNameHostRTL); - else - removeClass(_hostElement, _classNameHostRTL); - } - - //manage the resize feature (CSS3 resize "polyfill" for this plugin) - if (_isBody) - addClass(_hostElement, _classNameHostResizeDisabled); - if (resizeChanged) { - removeClass(_scrollbarCornerElement, [ - _classNameScrollbarCornerResize, - _classNameScrollbarCornerResizeB, - _classNameScrollbarCornerResizeH, - _classNameScrollbarCornerResizeV].join(_strSpace)); - if (_resizeNone) { - addClass(_hostElement, _classNameHostResizeDisabled); - } - else { - removeClass(_hostElement, _classNameHostResizeDisabled); - addClass(_scrollbarCornerElement, _classNameScrollbarCornerResize); - if (_resizeBoth) - addClass(_scrollbarCornerElement, _classNameScrollbarCornerResizeB); - else if (_resizeHorizontal) - addClass(_scrollbarCornerElement, _classNameScrollbarCornerResizeH); - else if (_resizeVertical) - addClass(_scrollbarCornerElement, _classNameScrollbarCornerResizeV); - } - } - - //manage the scrollbars general visibility + the scrollbar interactivity (unusable class name) - if (scrollbarsVisibilityChanged || overflowBehaviorChanged || hideOverflow.c || hasOverflow.c || ignoreOverlayScrollbarHidingChanged) { - if (ignoreOverlayScrollbarHiding) { - if (ignoreOverlayScrollbarHidingChanged) { - removeClass(_hostElement, _classNameHostScrolling); - if (ignoreOverlayScrollbarHiding) { - hideScrollbarH(); - hideScrollbarV(); - } - } - } - else if (scrollbarsVisibilityAuto) { - if (canScroll.x) - showScrollbarH(); - else - hideScrollbarH(); - - if (canScroll.y) - showScrollbarV(); - else - hideScrollbarV(); - } - else if (scrollbarsVisibilityVisible) { - showScrollbarH(); - showScrollbarV(); - } - else if (scrollbarsVisibilityHidden) { - hideScrollbarH(); - hideScrollbarV(); - } - } - - //manage the scrollbars auto hide feature (auto hide them after specific actions) - if (scrollbarsAutoHideChanged || ignoreOverlayScrollbarHidingChanged) { - if (_scrollbarsAutoHideLeave || _scrollbarsAutoHideMove) { - setupHostMouseTouchEvents(true); - setupHostMouseTouchEvents(); - } - else { - setupHostMouseTouchEvents(true); - } - - if (_scrollbarsAutoHideNever) - refreshScrollbarsAutoHide(true); - else - refreshScrollbarsAutoHide(false, true); - } - - //manage scrollbars handle length & offset - don't remove! - if (hostSizeChanged || overflowAmount.c || heightAutoChanged || widthAutoChanged || resizeChanged || boxSizingChanged || paddingAbsoluteChanged || ignoreOverlayScrollbarHidingChanged || cssDirectionChanged) { - refreshScrollbarHandleLength(true); - refreshScrollbarHandleOffset(true); - refreshScrollbarHandleLength(false); - refreshScrollbarHandleOffset(false); - } - - //manage interactivity - if (scrollbarsClickScrollingChanged) - refreshScrollbarsInteractive(true, scrollbarsClickScrolling); - if (scrollbarsDragScrollingChanged) - refreshScrollbarsInteractive(false, scrollbarsDragScrolling); - - //callbacks: - if (cssDirectionChanged) { - dispatchCallback('onDirectionChanged', { - isRTL: _isRTL, - dir: cssDirection - }); - } - if (hostSizeChanged) { - dispatchCallback('onHostSizeChanged', { - width: _hostSizeCache.w, - height: _hostSizeCache.h - }); - } - if (contentSizeChanged) { - dispatchCallback('onContentSizeChanged', { - width: _contentScrollSizeCache.w, - height: _contentScrollSizeCache.h - }); - } - if (hasOverflow.c || hideOverflow.c) { - dispatchCallback('onOverflowChanged', { - x: hasOverflow.x, - y: hasOverflow.y, - xScrollable: hideOverflow.xs, - yScrollable: hideOverflow.ys, - clipped: hideOverflow.x || hideOverflow.y - }); - } - if (overflowAmount.c) { - dispatchCallback('onOverflowAmountChanged', { - x: overflowAmount.x, - y: overflowAmount.y - }); - } - } - - //fix body min size - if (_isBody && _bodyMinSizeCache && (_hasOverflowCache.c || _bodyMinSizeCache.c)) { - //its possible that no min size was measured until now, because the content arrange element was just added now, in this case, measure now the min size. - if (!_bodyMinSizeCache.f) - bodyMinSizeChanged(); - if (_nativeScrollbarIsOverlaid.y && _hasOverflowCache.x) - _contentElement.css(_strMinMinus + _strWidth, _bodyMinSizeCache.w + _overlayScrollbarDummySize.y); - if (_nativeScrollbarIsOverlaid.x && _hasOverflowCache.y) - _contentElement.css(_strMinMinus + _strHeight, _bodyMinSizeCache.h + _overlayScrollbarDummySize.x); - _bodyMinSizeCache.c = false; - } - - //freezeResizeObserver(_sizeObserverElement, false); - //freezeResizeObserver(_sizeAutoObserverElement, false); - - dispatchCallback('onUpdated', { forced: force }); - } - - - //==== Options ====// - - /** - * Sets new options but doesn't call the update method. - * @param newOptions The object which contains the new options. - * @returns {*} A object which contains the changed options. - */ - function setOptions(newOptions) { - var validatedOpts = _pluginsOptions._validate(newOptions, _pluginsOptions._template, true, _currentOptions) - - _currentOptions = extendDeep({}, _currentOptions, validatedOpts._default); - _currentPreparedOptions = extendDeep({}, _currentPreparedOptions, validatedOpts._prepared); - - return validatedOpts._prepared; - } - - - //==== Structure ====// - - /** - * Builds or destroys the wrapper and helper DOM elements. - * @param destroy Indicates whether the DOM shall be build or destroyed. - */ - function setupStructureDOM(destroy) { - var strParent = 'parent'; - var classNameResizeObserverHost = 'os-resize-observer-host'; - var classNameTextareaElementFull = _classNameTextareaElement + _strSpace + _classNameTextInherit; - var textareaClass = _isTextarea ? _strSpace + _classNameTextInherit : _strEmpty; - var adoptAttrs = _currentPreparedOptions.textarea.inheritedAttrs; - var adoptAttrsMap = {}; - var applyAdoptedAttrs = function () { - var applyAdoptedAttrsElm = destroy ? _targetElement : _hostElement; - each(adoptAttrsMap, function (key, value) { - if (type(value) == TYPES.s) { - if (key == LEXICON.c) - applyAdoptedAttrsElm.addClass(value); - else - applyAdoptedAttrsElm.attr(key, value); - } - }); - }; - var hostElementClassNames = [ - _classNameHostElement, - _classNameHostTextareaElement, - _classNameHostResizeDisabled, - _classNameHostRTL, - _classNameHostScrollbarHorizontalHidden, - _classNameHostScrollbarVerticalHidden, - _classNameHostTransition, - _classNameHostScrolling, - _classNameHostOverflow, - _classNameHostOverflowX, - _classNameHostOverflowY, - _classNameThemeNone, - _classNameTextareaElement, - _classNameTextInherit, - _classNameCache].join(_strSpace); - var hostElementCSS = {}; - - //get host element as first element, because that's the most upper element and required for the other elements - _hostElement = _hostElement || (_isTextarea ? (_domExists ? _targetElement[strParent]()[strParent]()[strParent]()[strParent]() : FRAMEWORK(generateDiv(_classNameHostTextareaElement))) : _targetElement); - _contentElement = _contentElement || selectOrGenerateDivByClass(_classNameContentElement + textareaClass); - _viewportElement = _viewportElement || selectOrGenerateDivByClass(_classNameViewportElement + textareaClass); - _paddingElement = _paddingElement || selectOrGenerateDivByClass(_classNamePaddingElement + textareaClass); - _sizeObserverElement = _sizeObserverElement || selectOrGenerateDivByClass(classNameResizeObserverHost); - _textareaCoverElement = _textareaCoverElement || (_isTextarea ? selectOrGenerateDivByClass(_classNameTextareaCoverElement) : undefined); - - //on destroy, remove all generated class names from the host element before collecting the adopted attributes - //to prevent adopting generated class names - if (destroy) - removeClass(_hostElement, hostElementClassNames); - - //collect all adopted attributes - adoptAttrs = type(adoptAttrs) == TYPES.s ? adoptAttrs.split(_strSpace) : adoptAttrs; - if (type(adoptAttrs) == TYPES.a && _isTextarea) { - each(adoptAttrs, function (i, v) { - if (type(v) == TYPES.s) { - adoptAttrsMap[v] = destroy ? _hostElement.attr(v) : _targetElement.attr(v); - } - }); - } - - if (!destroy) { - if (_isTextarea) { - if (!_currentPreparedOptions.sizeAutoCapable) { - hostElementCSS[_strWidth] = _targetElement.css(_strWidth); - hostElementCSS[_strHeight] = _targetElement.css(_strHeight); - } - - if (!_domExists) - _targetElement.addClass(_classNameTextInherit).wrap(_hostElement); - - //jQuery clones elements in wrap functions, so we have to select them again - _hostElement = _targetElement[strParent]().css(hostElementCSS); - } - - if (!_domExists) { - //add the correct class to the target element - addClass(_targetElement, _isTextarea ? classNameTextareaElementFull : _classNameHostElement); - - //wrap the content into the generated elements to create the required DOM - _hostElement.wrapInner(_contentElement) - .wrapInner(_viewportElement) - .wrapInner(_paddingElement) - .prepend(_sizeObserverElement); - - //jQuery clones elements in wrap functions, so we have to select them again - _contentElement = findFirst(_hostElement, _strDot + _classNameContentElement); - _viewportElement = findFirst(_hostElement, _strDot + _classNameViewportElement); - _paddingElement = findFirst(_hostElement, _strDot + _classNamePaddingElement); - - if (_isTextarea) { - _contentElement.prepend(_textareaCoverElement); - applyAdoptedAttrs(); - } - } - - if (_nativeScrollbarStyling) - addClass(_viewportElement, _classNameViewportNativeScrollbarsInvisible); - if (_nativeScrollbarIsOverlaid.x && _nativeScrollbarIsOverlaid.y) - addClass(_viewportElement, _classNameViewportNativeScrollbarsOverlaid); - if (_isBody) - addClass(_htmlElement, _classNameHTMLElement); - - _sizeObserverElementNative = _sizeObserverElement[0]; - _hostElementNative = _hostElement[0]; - _paddingElementNative = _paddingElement[0]; - _viewportElementNative = _viewportElement[0]; - _contentElementNative = _contentElement[0]; - - updateViewportAttrsFromTarget(); - } - else { - if (_domExists && _initialized) { - //clear size observer - _sizeObserverElement.children().remove(); - - //remove the style property and classes from already generated elements - each([_paddingElement, _viewportElement, _contentElement, _textareaCoverElement], function (i, elm) { - if (elm) { - removeClass(elm.removeAttr(LEXICON.s), _classNamesDynamicDestroy); - } - }); - - //add classes to the host element which was removed previously to match the expected DOM - addClass(_hostElement, _isTextarea ? _classNameHostTextareaElement : _classNameHostElement); - } - else { - //remove size observer - remove(_sizeObserverElement); - - //unwrap the content to restore DOM - _contentElement.contents() - .unwrap() - .unwrap() - .unwrap(); - - if (_isTextarea) { - _targetElement.unwrap(); - remove(_hostElement); - remove(_textareaCoverElement); - applyAdoptedAttrs(); - } - } - - if (_isTextarea) - _targetElement.removeAttr(LEXICON.s); - - if (_isBody) - removeClass(_htmlElement, _classNameHTMLElement); - } - } - - /** - * Adds or removes all wrapper elements interactivity events. - * @param destroy Indicates whether the Events shall be added or removed. - */ - function setupStructureEvents() { - var textareaKeyDownRestrictedKeyCodes = [ - 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 123, //F1 to F12 - 33, 34, //page up, page down - 37, 38, 39, 40, //left, up, right, down arrows - 16, 17, 18, 19, 20, 144 //Shift, Ctrl, Alt, Pause, CapsLock, NumLock - ]; - var textareaKeyDownKeyCodesList = []; - var textareaUpdateIntervalID; - var scrollStopTimeoutId; - var scrollStopDelay = 175; - var strFocus = 'focus'; - - function updateTextarea(doClearInterval) { - textareaUpdate(); - _base.update(_strAuto); - if (doClearInterval && _autoUpdateRecommended) - clearInterval(textareaUpdateIntervalID); - } - function textareaOnScroll(event) { - _targetElement[_strScrollLeft](_rtlScrollBehavior.i && _normalizeRTLCache ? 9999999 : 0); - _targetElement[_strScrollTop](0); - COMPATIBILITY.prvD(event); - COMPATIBILITY.stpP(event); - return false; - } - function textareaOnDrop(event) { - setTimeout(function () { - if (!_destroyed) - updateTextarea(); - }, 50); - } - function textareaOnFocus() { - _textareaHasFocus = true; - addClass(_hostElement, strFocus); - } - function textareaOnFocusout() { - _textareaHasFocus = false; - textareaKeyDownKeyCodesList = []; - removeClass(_hostElement, strFocus); - updateTextarea(true); - } - function textareaOnKeyDown(event) { - var keyCode = event.keyCode; - - if (inArray(keyCode, textareaKeyDownRestrictedKeyCodes) < 0) { - if (!textareaKeyDownKeyCodesList[LEXICON.l]) { - updateTextarea(); - textareaUpdateIntervalID = setInterval(updateTextarea, 1000 / 60); - } - if (inArray(keyCode, textareaKeyDownKeyCodesList) < 0) - textareaKeyDownKeyCodesList.push(keyCode); - } - } - function textareaOnKeyUp(event) { - var keyCode = event.keyCode; - var index = inArray(keyCode, textareaKeyDownKeyCodesList); - - if (inArray(keyCode, textareaKeyDownRestrictedKeyCodes) < 0) { - if (index > -1) - textareaKeyDownKeyCodesList.splice(index, 1); - if (!textareaKeyDownKeyCodesList[LEXICON.l]) - updateTextarea(true); - } - } - function contentOnTransitionEnd(event) { - if (_autoUpdateCache === true) - return; - event = event.originalEvent || event; - if (isSizeAffectingCSSProperty(event.propertyName)) - _base.update(_strAuto); - } - function viewportOnScroll(event) { - if (!_sleeping) { - if (scrollStopTimeoutId !== undefined) - clearTimeout(scrollStopTimeoutId); - else { - if (_scrollbarsAutoHideScroll || _scrollbarsAutoHideMove) - refreshScrollbarsAutoHide(true); - - if (!nativeOverlayScrollbarsAreActive()) - addClass(_hostElement, _classNameHostScrolling); - - dispatchCallback('onScrollStart', event); - } - - //if a scrollbars handle gets dragged, the mousemove event is responsible for refreshing the handle offset - //because if CSS scroll-snap is used, the handle offset gets only refreshed on every snap point - //this looks laggy & clunky, it looks much better if the offset refreshes with the mousemove - if (!_scrollbarsHandlesDefineScrollPos) { - refreshScrollbarHandleOffset(true); - refreshScrollbarHandleOffset(false); - } - dispatchCallback('onScroll', event); - - scrollStopTimeoutId = setTimeout(function () { - if (!_destroyed) { - //OnScrollStop: - clearTimeout(scrollStopTimeoutId); - scrollStopTimeoutId = undefined; - - if (_scrollbarsAutoHideScroll || _scrollbarsAutoHideMove) - refreshScrollbarsAutoHide(false); - - if (!nativeOverlayScrollbarsAreActive()) - removeClass(_hostElement, _classNameHostScrolling); - - dispatchCallback('onScrollStop', event); - } - }, scrollStopDelay); - } - } - - - if (_isTextarea) { - if (_msieVersion > 9 || !_autoUpdateRecommended) { - addDestroyEventListener(_targetElement, 'input', updateTextarea); - } - else { - addDestroyEventListener(_targetElement, - [_strKeyDownEvent, _strKeyUpEvent], - [textareaOnKeyDown, textareaOnKeyUp]); - } - - addDestroyEventListener(_targetElement, - [_strScroll, 'drop', strFocus, strFocus + 'out'], - [textareaOnScroll, textareaOnDrop, textareaOnFocus, textareaOnFocusout]); - } - else { - addDestroyEventListener(_contentElement, _strTransitionEndEvent, contentOnTransitionEnd); - } - addDestroyEventListener(_viewportElement, _strScroll, viewportOnScroll, true); - } - - - //==== Scrollbars ====// - - /** - * Builds or destroys all scrollbar DOM elements (scrollbar, track, handle) - * @param destroy Indicates whether the DOM shall be build or destroyed. - */ - function setupScrollbarsDOM(destroy) { - var selectOrGenerateScrollbarDOM = function (isHorizontal) { - var scrollbarClassName = isHorizontal ? _classNameScrollbarHorizontal : _classNameScrollbarVertical; - var scrollbar = selectOrGenerateDivByClass(_classNameScrollbar + _strSpace + scrollbarClassName, true); - var track = selectOrGenerateDivByClass(_classNameScrollbarTrack, scrollbar); - var handle = selectOrGenerateDivByClass(_classNameScrollbarHandle, scrollbar); - - if (!_domExists && !destroy) { - scrollbar.append(track); - track.append(handle); - } - - return { - _scrollbar: scrollbar, - _track: track, - _handle: handle - }; - }; - function resetScrollbarDOM(isHorizontal) { - var scrollbarVars = getScrollbarVars(isHorizontal); - var scrollbar = scrollbarVars._scrollbar; - var track = scrollbarVars._track; - var handle = scrollbarVars._handle; - - if (_domExists && _initialized) { - each([scrollbar, track, handle], function (i, elm) { - removeClass(elm.removeAttr(LEXICON.s), _classNamesDynamicDestroy); - }); - } - else { - remove(scrollbar || selectOrGenerateScrollbarDOM(isHorizontal)._scrollbar); - } - } - var horizontalElements; - var verticalElements; - - if (!destroy) { - horizontalElements = selectOrGenerateScrollbarDOM(true); - verticalElements = selectOrGenerateScrollbarDOM(); - - _scrollbarHorizontalElement = horizontalElements._scrollbar; - _scrollbarHorizontalTrackElement = horizontalElements._track; - _scrollbarHorizontalHandleElement = horizontalElements._handle; - _scrollbarVerticalElement = verticalElements._scrollbar; - _scrollbarVerticalTrackElement = verticalElements._track; - _scrollbarVerticalHandleElement = verticalElements._handle; - - if (!_domExists) { - _paddingElement.after(_scrollbarVerticalElement); - _paddingElement.after(_scrollbarHorizontalElement); - } - } - else { - resetScrollbarDOM(true); - resetScrollbarDOM(); - } - } - - /** - * Initializes all scrollbar interactivity events. (track and handle dragging, clicking, scrolling) - * @param isHorizontal True if the target scrollbar is the horizontal scrollbar, false if the target scrollbar is the vertical scrollbar. - */ - function setupScrollbarEvents(isHorizontal) { - var scrollbarVars = getScrollbarVars(isHorizontal); - var scrollbarVarsInfo = scrollbarVars._info; - var insideIFrame = _windowElementNative.top !== _windowElementNative; - var xy = scrollbarVars._x_y; - var XY = scrollbarVars._X_Y; - var scroll = _strScroll + scrollbarVars._Left_Top; - var strActive = 'active'; - var strSnapHandle = 'snapHandle'; - var scrollDurationFactor = 1; - var increaseDecreaseScrollAmountKeyCodes = [16, 17]; //shift, ctrl - var trackTimeout; - var mouseDownScroll; - var mouseDownOffset; - var mouseDownInvertedScale; - - function getPointerPosition(event) { - return _msieVersion && insideIFrame ? event['screen' + XY] : COMPATIBILITY.page(event)[xy]; //use screen coordinates in EDGE & IE because the page values are incorrect in frames. - } - function getPreparedScrollbarsOption(name) { - return _currentPreparedOptions.scrollbars[name]; - } - function increaseTrackScrollAmount() { - scrollDurationFactor = 0.5; - } - function decreaseTrackScrollAmount() { - scrollDurationFactor = 1; - } - function documentKeyDown(event) { - if (inArray(event.keyCode, increaseDecreaseScrollAmountKeyCodes) > -1) - increaseTrackScrollAmount(); - } - function documentKeyUp(event) { - if (inArray(event.keyCode, increaseDecreaseScrollAmountKeyCodes) > -1) - decreaseTrackScrollAmount(); - } - function onMouseTouchDownContinue(event) { - var originalEvent = event.originalEvent || event; - var isTouchEvent = originalEvent.touches !== undefined; - return _sleeping || _destroyed || nativeOverlayScrollbarsAreActive() || !_scrollbarsDragScrollingCache || (isTouchEvent && !getPreparedScrollbarsOption('touchSupport')) ? false : COMPATIBILITY.mBtn(event) === 1 || isTouchEvent; - } - function documentDragMove(event) { - if (onMouseTouchDownContinue(event)) { - var trackLength = scrollbarVarsInfo._trackLength; - var handleLength = scrollbarVarsInfo._handleLength; - var scrollRange = scrollbarVarsInfo._maxScroll; - var scrollRaw = (getPointerPosition(event) - mouseDownOffset) * mouseDownInvertedScale; - var scrollDeltaPercent = scrollRaw / (trackLength - handleLength); - var scrollDelta = (scrollRange * scrollDeltaPercent); - scrollDelta = isFinite(scrollDelta) ? scrollDelta : 0; - if (_isRTL && isHorizontal && !_rtlScrollBehavior.i) - scrollDelta *= -1; - - _viewportElement[scroll](MATH.round(mouseDownScroll + scrollDelta)); - - if (_scrollbarsHandlesDefineScrollPos) - refreshScrollbarHandleOffset(isHorizontal, mouseDownScroll + scrollDelta); - - if (!_supportPassiveEvents) - COMPATIBILITY.prvD(event); - } - else - documentMouseTouchUp(event); - } - function documentMouseTouchUp(event) { - event = event || event.originalEvent; - - setupResponsiveEventListener(_documentElement, - [_strMouseTouchMoveEvent, _strMouseTouchUpEvent, _strKeyDownEvent, _strKeyUpEvent, _strSelectStartEvent], - [documentDragMove, documentMouseTouchUp, documentKeyDown, documentKeyUp, documentOnSelectStart], - true); - - if (_scrollbarsHandlesDefineScrollPos) - refreshScrollbarHandleOffset(isHorizontal, true); - - _scrollbarsHandlesDefineScrollPos = false; - removeClass(_bodyElement, _classNameDragging); - removeClass(scrollbarVars._handle, strActive); - removeClass(scrollbarVars._track, strActive); - removeClass(scrollbarVars._scrollbar, strActive); - - mouseDownScroll = undefined; - mouseDownOffset = undefined; - mouseDownInvertedScale = 1; - - decreaseTrackScrollAmount(); - - if (trackTimeout !== undefined) { - _base.scrollStop(); - clearTimeout(trackTimeout); - trackTimeout = undefined; - } - - if (event) { - var rect = _hostElementNative[LEXICON.bCR](); - var mouseInsideHost = event.clientX >= rect.left && event.clientX <= rect.right && event.clientY >= rect.top && event.clientY <= rect.bottom; - - //if mouse is outside host element - if (!mouseInsideHost) - hostOnMouseLeave(); - - if (_scrollbarsAutoHideScroll || _scrollbarsAutoHideMove) - refreshScrollbarsAutoHide(false); - } - } - function onHandleMouseTouchDown(event) { - if (onMouseTouchDownContinue(event)) - onHandleMouseTouchDownAction(event); - } - function onHandleMouseTouchDownAction(event) { - mouseDownScroll = _viewportElement[scroll](); - mouseDownScroll = isNaN(mouseDownScroll) ? 0 : mouseDownScroll; - if (_isRTL && isHorizontal && !_rtlScrollBehavior.n || !_isRTL) - mouseDownScroll = mouseDownScroll < 0 ? 0 : mouseDownScroll; - - mouseDownInvertedScale = getHostElementInvertedScale()[xy]; - mouseDownOffset = getPointerPosition(event); - - _scrollbarsHandlesDefineScrollPos = !getPreparedScrollbarsOption(strSnapHandle); - addClass(_bodyElement, _classNameDragging); - addClass(scrollbarVars._handle, strActive); - addClass(scrollbarVars._scrollbar, strActive); - - setupResponsiveEventListener(_documentElement, - [_strMouseTouchMoveEvent, _strMouseTouchUpEvent, _strSelectStartEvent], - [documentDragMove, documentMouseTouchUp, documentOnSelectStart]); - - if (_msieVersion || !_documentMixed) - COMPATIBILITY.prvD(event); - COMPATIBILITY.stpP(event); - } - function onTrackMouseTouchDown(event) { - if (onMouseTouchDownContinue(event)) { - var scrollDistance = MATH.round(_viewportSize[scrollbarVars._w_h]); - var trackOffset = scrollbarVars._track.offset()[scrollbarVars._left_top]; - var ctrlKey = event.ctrlKey; - var instantScroll = event.shiftKey; - var instantScrollTransition = instantScroll && ctrlKey; - var isFirstIteration = true; - var easing = 'linear'; - var decreaseScroll; - var finishedCondition; - var scrollActionFinsished = function (transition) { - if (_scrollbarsHandlesDefineScrollPos) - refreshScrollbarHandleOffset(isHorizontal, transition); - }; - var scrollActionInstantFinished = function () { - scrollActionFinsished(); - onHandleMouseTouchDownAction(event); - }; - var scrollAction = function () { - if (!_destroyed) { - var mouseOffset = (mouseDownOffset - trackOffset) * mouseDownInvertedScale; - var handleOffset = scrollbarVarsInfo._handleOffset; - var trackLength = scrollbarVarsInfo._trackLength; - var handleLength = scrollbarVarsInfo._handleLength; - var scrollRange = scrollbarVarsInfo._maxScroll; - var currScroll = scrollbarVarsInfo._currentScroll; - var scrollDuration = 270 * scrollDurationFactor; - var timeoutDelay = isFirstIteration ? MATH.max(400, scrollDuration) : scrollDuration; - var instantScrollPosition = scrollRange * ((mouseOffset - (handleLength / 2)) / (trackLength - handleLength)); // 100% * positionPercent - var rtlIsNormal = _isRTL && isHorizontal && ((!_rtlScrollBehavior.i && !_rtlScrollBehavior.n) || _normalizeRTLCache); - var decreaseScrollCondition = rtlIsNormal ? handleOffset < mouseOffset : handleOffset > mouseOffset; - var scrollObj = {}; - var animationObj = { - easing: easing, - step: function (now) { - if (_scrollbarsHandlesDefineScrollPos) { - _viewportElement[scroll](now); //https://github.com/jquery/jquery/issues/4340 - refreshScrollbarHandleOffset(isHorizontal, now); - } - } - }; - instantScrollPosition = isFinite(instantScrollPosition) ? instantScrollPosition : 0; - instantScrollPosition = _isRTL && isHorizontal && !_rtlScrollBehavior.i ? (scrollRange - instantScrollPosition) : instantScrollPosition; - - //_base.scrollStop(); - - if (instantScroll) { - _viewportElement[scroll](instantScrollPosition); //scroll instantly to new position - if (instantScrollTransition) { - //get the scroll position after instant scroll (in case CSS Snap Points are used) to get the correct snapped scroll position - //and the animation stops at the correct point - instantScrollPosition = _viewportElement[scroll](); - //scroll back to the position before instant scrolling so animation can be performed - _viewportElement[scroll](currScroll); - - instantScrollPosition = rtlIsNormal && _rtlScrollBehavior.i ? (scrollRange - instantScrollPosition) : instantScrollPosition; - instantScrollPosition = rtlIsNormal && _rtlScrollBehavior.n ? -instantScrollPosition : instantScrollPosition; - - scrollObj[xy] = instantScrollPosition; - _base.scroll(scrollObj, extendDeep(animationObj, { - duration: 130, - complete: scrollActionInstantFinished - })); - } - else - scrollActionInstantFinished(); - } - else { - decreaseScroll = isFirstIteration ? decreaseScrollCondition : decreaseScroll; - finishedCondition = rtlIsNormal - ? (decreaseScroll ? handleOffset + handleLength >= mouseOffset : handleOffset <= mouseOffset) - : (decreaseScroll ? handleOffset <= mouseOffset : handleOffset + handleLength >= mouseOffset); - - if (finishedCondition) { - clearTimeout(trackTimeout); - _base.scrollStop(); - trackTimeout = undefined; - scrollActionFinsished(true); - } - else { - trackTimeout = setTimeout(scrollAction, timeoutDelay); - - scrollObj[xy] = (decreaseScroll ? '-=' : '+=') + scrollDistance; - _base.scroll(scrollObj, extendDeep(animationObj, { - duration: scrollDuration - })); - } - isFirstIteration = false; - } - } - }; - if (ctrlKey) - increaseTrackScrollAmount(); - - mouseDownInvertedScale = getHostElementInvertedScale()[xy]; - mouseDownOffset = COMPATIBILITY.page(event)[xy]; - - _scrollbarsHandlesDefineScrollPos = !getPreparedScrollbarsOption(strSnapHandle); - addClass(_bodyElement, _classNameDragging); - addClass(scrollbarVars._track, strActive); - addClass(scrollbarVars._scrollbar, strActive); - - setupResponsiveEventListener(_documentElement, - [_strMouseTouchUpEvent, _strKeyDownEvent, _strKeyUpEvent, _strSelectStartEvent], - [documentMouseTouchUp, documentKeyDown, documentKeyUp, documentOnSelectStart]); - - scrollAction(); - COMPATIBILITY.prvD(event); - COMPATIBILITY.stpP(event); - } - } - function onTrackMouseTouchEnter(event) { - //make sure both scrollbars will stay visible if one scrollbar is hovered if autoHide is "scroll" or "move". - _scrollbarsHandleHovered = true; - if (_scrollbarsAutoHideScroll || _scrollbarsAutoHideMove) - refreshScrollbarsAutoHide(true); - } - function onTrackMouseTouchLeave(event) { - _scrollbarsHandleHovered = false; - if (_scrollbarsAutoHideScroll || _scrollbarsAutoHideMove) - refreshScrollbarsAutoHide(false); - } - function onScrollbarMouseTouchDown(event) { - COMPATIBILITY.stpP(event); - } - - addDestroyEventListener(scrollbarVars._handle, - _strMouseTouchDownEvent, - onHandleMouseTouchDown); - addDestroyEventListener(scrollbarVars._track, - [_strMouseTouchDownEvent, _strMouseTouchEnter, _strMouseTouchLeave], - [onTrackMouseTouchDown, onTrackMouseTouchEnter, onTrackMouseTouchLeave]); - addDestroyEventListener(scrollbarVars._scrollbar, - _strMouseTouchDownEvent, - onScrollbarMouseTouchDown); - - if (_supportTransition) { - addDestroyEventListener(scrollbarVars._scrollbar, _strTransitionEndEvent, function (event) { - if (event.target !== scrollbarVars._scrollbar[0]) - return; - refreshScrollbarHandleLength(isHorizontal); - refreshScrollbarHandleOffset(isHorizontal); - }); - } - } - - /** - * Shows or hides the given scrollbar and applied a class name which indicates if the scrollbar is scrollable or not. - * @param isHorizontal True if the horizontal scrollbar is the target, false if the vertical scrollbar is the target. - * @param shallBeVisible True if the scrollbar shall be shown, false if hidden. - * @param canScroll True if the scrollbar is scrollable, false otherwise. - */ - function refreshScrollbarAppearance(isHorizontal, shallBeVisible, canScroll) { - var scrollbarClassName = isHorizontal ? _classNameHostScrollbarHorizontalHidden : _classNameHostScrollbarVerticalHidden; - var scrollbarElement = isHorizontal ? _scrollbarHorizontalElement : _scrollbarVerticalElement; - - if (shallBeVisible) - removeClass(_hostElement, scrollbarClassName); - else - addClass(_hostElement, scrollbarClassName); - - if (canScroll) - removeClass(scrollbarElement, _classNameScrollbarUnusable); - else - addClass(scrollbarElement, _classNameScrollbarUnusable); - } - - /** - * Autoshows / autohides both scrollbars with. - * @param shallBeVisible True if the scrollbars shall be autoshown (only the case if they are hidden by a autohide), false if the shall be auto hidden. - * @param delayfree True if the scrollbars shall be hidden without a delay, false or undefined otherwise. - */ - function refreshScrollbarsAutoHide(shallBeVisible, delayfree) { - clearTimeout(_scrollbarsAutoHideTimeoutId); - if (shallBeVisible) { - //if(_hasOverflowCache.x && _hideOverflowCache.xs) - removeClass(_scrollbarHorizontalElement, _classNameScrollbarAutoHidden); - //if(_hasOverflowCache.y && _hideOverflowCache.ys) - removeClass(_scrollbarVerticalElement, _classNameScrollbarAutoHidden); - } - else { - var anyActive; - var strActive = 'active'; - var hide = function () { - if (!_scrollbarsHandleHovered && !_destroyed) { - anyActive = _scrollbarHorizontalHandleElement.hasClass(strActive) || _scrollbarVerticalHandleElement.hasClass(strActive); - if (!anyActive && (_scrollbarsAutoHideScroll || _scrollbarsAutoHideMove || _scrollbarsAutoHideLeave)) - addClass(_scrollbarHorizontalElement, _classNameScrollbarAutoHidden); - if (!anyActive && (_scrollbarsAutoHideScroll || _scrollbarsAutoHideMove || _scrollbarsAutoHideLeave)) - addClass(_scrollbarVerticalElement, _classNameScrollbarAutoHidden); - } - }; - if (_scrollbarsAutoHideDelay > 0 && delayfree !== true) - _scrollbarsAutoHideTimeoutId = setTimeout(hide, _scrollbarsAutoHideDelay); - else - hide(); - } - } - - /** - * Refreshes the handle length of the given scrollbar. - * @param isHorizontal True if the horizontal scrollbar handle shall be refreshed, false if the vertical one shall be refreshed. - */ - function refreshScrollbarHandleLength(isHorizontal) { - var handleCSS = {}; - var scrollbarVars = getScrollbarVars(isHorizontal); - var scrollbarVarsInfo = scrollbarVars._info; - var digit = 1000000; - //get and apply intended handle length - var handleRatio = MATH.min(1, (_hostSizeCache[scrollbarVars._w_h] - (_paddingAbsoluteCache ? (isHorizontal ? _paddingX : _paddingY) : 0)) / _contentScrollSizeCache[scrollbarVars._w_h]); - handleCSS[scrollbarVars._width_height] = (MATH.floor(handleRatio * 100 * digit) / digit) + '%'; //the last * digit / digit is for flooring to the 4th digit - - if (!nativeOverlayScrollbarsAreActive()) - scrollbarVars._handle.css(handleCSS); - - //measure the handle length to respect min & max length - scrollbarVarsInfo._handleLength = scrollbarVars._handle[0]['offset' + scrollbarVars._Width_Height]; - scrollbarVarsInfo._handleLengthRatio = handleRatio; - } - - /** - * Refreshes the handle offset of the given scrollbar. - * @param isHorizontal True if the horizontal scrollbar handle shall be refreshed, false if the vertical one shall be refreshed. - * @param scrollOrTransition The scroll position of the given scrollbar axis to which the handle shall be moved or a boolean which indicates whether a transition shall be applied. If undefined or boolean if the current scroll-offset is taken. (if isHorizontal ? scrollLeft : scrollTop) - */ - function refreshScrollbarHandleOffset(isHorizontal, scrollOrTransition) { - var transition = type(scrollOrTransition) == TYPES.b; - var transitionDuration = 250; - var isRTLisHorizontal = _isRTL && isHorizontal; - var scrollbarVars = getScrollbarVars(isHorizontal); - var scrollbarVarsInfo = scrollbarVars._info; - var strTranslateBrace = 'translate('; - var strTransform = VENDORS._cssProperty('transform'); - var strTransition = VENDORS._cssProperty('transition'); - var nativeScroll = isHorizontal ? _viewportElement[_strScrollLeft]() : _viewportElement[_strScrollTop](); - var currentScroll = scrollOrTransition === undefined || transition ? nativeScroll : scrollOrTransition; - - //measure the handle length to respect min & max length - var handleLength = scrollbarVarsInfo._handleLength; - var trackLength = scrollbarVars._track[0]['offset' + scrollbarVars._Width_Height]; - var handleTrackDiff = trackLength - handleLength; - var handleCSS = {}; - var transformOffset; - var translateValue; - - //DONT use the variable '_contentScrollSizeCache[scrollbarVars._w_h]' instead of '_viewportElement[0]['scroll' + scrollbarVars._Width_Height]' - // because its a bit behind during the small delay when content size updates - //(delay = mutationObserverContentLag, if its 0 then this var could be used) - var maxScroll = (_viewportElementNative[_strScroll + scrollbarVars._Width_Height] - _viewportElementNative['client' + scrollbarVars._Width_Height]) * (_rtlScrollBehavior.n && isRTLisHorizontal ? -1 : 1); //* -1 if rtl scroll max is negative - var getScrollRatio = function (base) { - return isNaN(base / maxScroll) ? 0 : MATH.max(0, MATH.min(1, base / maxScroll)); - }; - var getHandleOffset = function (scrollRatio) { - var offset = handleTrackDiff * scrollRatio; - offset = isNaN(offset) ? 0 : offset; - offset = (isRTLisHorizontal && !_rtlScrollBehavior.i) ? (trackLength - handleLength - offset) : offset; - offset = MATH.max(0, offset); - return offset; - }; - var scrollRatio = getScrollRatio(nativeScroll); - var unsnappedScrollRatio = getScrollRatio(currentScroll); - var handleOffset = getHandleOffset(unsnappedScrollRatio); - var snappedHandleOffset = getHandleOffset(scrollRatio); - - scrollbarVarsInfo._maxScroll = maxScroll; - scrollbarVarsInfo._currentScroll = nativeScroll; - scrollbarVarsInfo._currentScrollRatio = scrollRatio; - - if (_supportTransform) { - transformOffset = isRTLisHorizontal ? -(trackLength - handleLength - handleOffset) : handleOffset; //in px - //transformOffset = (transformOffset / trackLength * 100) * (trackLength / handleLength); //in % - translateValue = isHorizontal ? strTranslateBrace + transformOffset + 'px, 0)' : strTranslateBrace + '0, ' + transformOffset + 'px)'; - - handleCSS[strTransform] = translateValue; - - //apply or clear up transition - if (_supportTransition) - handleCSS[strTransition] = transition && MATH.abs(handleOffset - scrollbarVarsInfo._handleOffset) > 1 ? getCSSTransitionString(scrollbarVars._handle) + ', ' + (strTransform + _strSpace + transitionDuration + 'ms') : _strEmpty; - } - else - handleCSS[scrollbarVars._left_top] = handleOffset; - - - //only apply css if offset has changed and overflow exists. - if (!nativeOverlayScrollbarsAreActive()) { - scrollbarVars._handle.css(handleCSS); - - //clear up transition - if (_supportTransform && _supportTransition && transition) { - scrollbarVars._handle.one(_strTransitionEndEvent, function () { - if (!_destroyed) - scrollbarVars._handle.css(strTransition, _strEmpty); - }); - } - } - - scrollbarVarsInfo._handleOffset = handleOffset; - scrollbarVarsInfo._snappedHandleOffset = snappedHandleOffset; - scrollbarVarsInfo._trackLength = trackLength; - } - - /** - * Refreshes the interactivity of the given scrollbar element. - * @param isTrack True if the track element is the target, false if the handle element is the target. - * @param value True for interactivity false for no interactivity. - */ - function refreshScrollbarsInteractive(isTrack, value) { - var action = value ? 'removeClass' : 'addClass'; - var element1 = isTrack ? _scrollbarHorizontalTrackElement : _scrollbarHorizontalHandleElement; - var element2 = isTrack ? _scrollbarVerticalTrackElement : _scrollbarVerticalHandleElement; - var className = isTrack ? _classNameScrollbarTrackOff : _classNameScrollbarHandleOff; - - element1[action](className); - element2[action](className); - } - - /** - * Returns a object which is used for fast access for specific variables. - * @param isHorizontal True if the horizontal scrollbar vars shall be accessed, false if the vertical scrollbar vars shall be accessed. - * @returns {{wh: string, WH: string, lt: string, _wh: string, _lt: string, t: *, h: *, c: {}, s: *}} - */ - function getScrollbarVars(isHorizontal) { - return { - _width_height: isHorizontal ? _strWidth : _strHeight, - _Width_Height: isHorizontal ? 'Width' : 'Height', - _left_top: isHorizontal ? _strLeft : _strTop, - _Left_Top: isHorizontal ? 'Left' : 'Top', - _x_y: isHorizontal ? _strX : _strY, - _X_Y: isHorizontal ? 'X' : 'Y', - _w_h: isHorizontal ? 'w' : 'h', - _l_t: isHorizontal ? 'l' : 't', - _track: isHorizontal ? _scrollbarHorizontalTrackElement : _scrollbarVerticalTrackElement, - _handle: isHorizontal ? _scrollbarHorizontalHandleElement : _scrollbarVerticalHandleElement, - _scrollbar: isHorizontal ? _scrollbarHorizontalElement : _scrollbarVerticalElement, - _info: isHorizontal ? _scrollHorizontalInfo : _scrollVerticalInfo - }; - } - - - //==== Scrollbar Corner ====// - - /** - * Builds or destroys the scrollbar corner DOM element. - * @param destroy Indicates whether the DOM shall be build or destroyed. - */ - function setupScrollbarCornerDOM(destroy) { - _scrollbarCornerElement = _scrollbarCornerElement || selectOrGenerateDivByClass(_classNameScrollbarCorner, true); - - if (!destroy) { - if (!_domExists) { - _hostElement.append(_scrollbarCornerElement); - } - } - else { - if (_domExists && _initialized) { - removeClass(_scrollbarCornerElement.removeAttr(LEXICON.s), _classNamesDynamicDestroy); - } - else { - remove(_scrollbarCornerElement); - } - } - } - - /** - * Initializes all scrollbar corner interactivity events. - */ - function setupScrollbarCornerEvents() { - var insideIFrame = _windowElementNative.top !== _windowElementNative; - var mouseDownPosition = {}; - var mouseDownSize = {}; - var mouseDownInvertedScale = {}; - var reconnectMutationObserver; - - function documentDragMove(event) { - if (onMouseTouchDownContinue(event)) { - var pageOffset = getCoordinates(event); - var hostElementCSS = {}; - if (_resizeHorizontal || _resizeBoth) - hostElementCSS[_strWidth] = (mouseDownSize.w + (pageOffset.x - mouseDownPosition.x) * mouseDownInvertedScale.x); - if (_resizeVertical || _resizeBoth) - hostElementCSS[_strHeight] = (mouseDownSize.h + (pageOffset.y - mouseDownPosition.y) * mouseDownInvertedScale.y); - _hostElement.css(hostElementCSS); - COMPATIBILITY.stpP(event); - } - else { - documentMouseTouchUp(event); - } - } - function documentMouseTouchUp(event) { - var eventIsTrusted = event !== undefined; - - setupResponsiveEventListener(_documentElement, - [_strSelectStartEvent, _strMouseTouchMoveEvent, _strMouseTouchUpEvent], - [documentOnSelectStart, documentDragMove, documentMouseTouchUp], - true); - - removeClass(_bodyElement, _classNameDragging); - if (_scrollbarCornerElement.releaseCapture) - _scrollbarCornerElement.releaseCapture(); - - if (eventIsTrusted) { - if (reconnectMutationObserver) - connectMutationObservers(); - _base.update(_strAuto); - } - reconnectMutationObserver = false; - } - function onMouseTouchDownContinue(event) { - var originalEvent = event.originalEvent || event; - var isTouchEvent = originalEvent.touches !== undefined; - return _sleeping || _destroyed ? false : COMPATIBILITY.mBtn(event) === 1 || isTouchEvent; - } - function getCoordinates(event) { - return _msieVersion && insideIFrame ? { x: event.screenX, y: event.screenY } : COMPATIBILITY.page(event); - } - - addDestroyEventListener(_scrollbarCornerElement, _strMouseTouchDownEvent, function (event) { - if (onMouseTouchDownContinue(event) && !_resizeNone) { - if (_mutationObserversConnected) { - reconnectMutationObserver = true; - disconnectMutationObservers(); - } - - mouseDownPosition = getCoordinates(event); - - mouseDownSize.w = _hostElementNative[LEXICON.oW] - (!_isBorderBox ? _paddingX : 0); - mouseDownSize.h = _hostElementNative[LEXICON.oH] - (!_isBorderBox ? _paddingY : 0); - mouseDownInvertedScale = getHostElementInvertedScale(); - - setupResponsiveEventListener(_documentElement, - [_strSelectStartEvent, _strMouseTouchMoveEvent, _strMouseTouchUpEvent], - [documentOnSelectStart, documentDragMove, documentMouseTouchUp]); - - addClass(_bodyElement, _classNameDragging); - if (_scrollbarCornerElement.setCapture) - _scrollbarCornerElement.setCapture(); - - COMPATIBILITY.prvD(event); - COMPATIBILITY.stpP(event); - } - }); - } - - - //==== Utils ====// - - /** - * Calls the callback with the given name. The Context of this callback is always _base (this). - * @param name The name of the target which shall be called. - * @param args The args with which the callback shall be called. - */ - function dispatchCallback(name, args) { - if (_initialized) { - var callback = _currentPreparedOptions.callbacks[name]; - var extensionOnName = name; - var ext; - - if (extensionOnName.substr(0, 2) === 'on') - extensionOnName = extensionOnName.substr(2, 1).toLowerCase() + extensionOnName.substr(3); - - if (type(callback) == TYPES.f) - callback.call(_base, args); - - each(_extensions, function () { - ext = this; - if (type(ext.on) == TYPES.f) - ext.on(extensionOnName, args); - }); - } - else if (!_destroyed) - _callbacksInitQeueue.push({ n: name, a: args }); - } - - /** - * Sets the "top, right, bottom, left" properties, with a given prefix, of the given css object. - * @param targetCSSObject The css object to which the values shall be applied. - * @param prefix The prefix of the "top, right, bottom, left" css properties. (example: 'padding-' is a valid prefix) - * @param values A array of values which shall be applied to the "top, right, bottom, left" -properties. The array order is [top, right, bottom, left]. - * If this argument is undefined the value '' (empty string) will be applied to all properties. - */ - function setTopRightBottomLeft(targetCSSObject, prefix, values) { - if (values === undefined) - values = [_strEmpty, _strEmpty, _strEmpty, _strEmpty]; - - targetCSSObject[prefix + _strTop] = values[0]; - targetCSSObject[prefix + _strRight] = values[1]; - targetCSSObject[prefix + _strBottom] = values[2]; - targetCSSObject[prefix + _strLeft] = values[3]; - } - - /** - * Returns the computed CSS transition string from the given element. - * @param element The element from which the transition string shall be returned. - * @returns {string} The CSS transition string from the given element. - */ - function getCSSTransitionString(element) { - var transitionStr = VENDORS._cssProperty('transition'); - var assembledValue = element.css(transitionStr); - if (assembledValue) - return assembledValue; - var regExpString = '\\s*(' + '([^,(]+(\\(.+?\\))?)+' + ')[\\s,]*'; - var regExpMain = new RegExp(regExpString); - var regExpValidate = new RegExp('^(' + regExpString + ')+$'); - var properties = 'property duration timing-function delay'.split(' '); - var result = []; - var strResult; - var valueArray; - var i = 0; - var j; - var splitCssStyleByComma = function (str) { - strResult = []; - if (!str.match(regExpValidate)) - return str; - while (str.match(regExpMain)) { - strResult.push(RegExp.$1); - str = str.replace(regExpMain, _strEmpty); - } - - return strResult; - }; - for (; i < properties[LEXICON.l]; i++) { - valueArray = splitCssStyleByComma(element.css(transitionStr + '-' + properties[i])); - for (j = 0; j < valueArray[LEXICON.l]; j++) - result[j] = (result[j] ? result[j] + _strSpace : _strEmpty) + valueArray[j]; - } - return result.join(', '); - } - - /** - * Calculates the host-elements inverted scale. (invertedScale = 1 / scale) - * @returns {{x: number, y: number}} The scale of the host-element. - */ - function getHostElementInvertedScale() { - var rect = _paddingElementNative[LEXICON.bCR](); - return { - x: _supportTransform ? 1 / (MATH.round(rect.width) / _paddingElementNative[LEXICON.oW]) || 1 : 1, - y: _supportTransform ? 1 / (MATH.round(rect.height) / _paddingElementNative[LEXICON.oH]) || 1 : 1 - }; - } - - /** - * Checks whether the given object is a HTMLElement. - * @param o The object which shall be checked. - * @returns {boolean} True the given object is a HTMLElement, false otherwise. - */ - function isHTMLElement(o) { - var strOwnerDocument = 'ownerDocument'; - var strHTMLElement = 'HTMLElement'; - var wnd = o && o[strOwnerDocument] ? (o[strOwnerDocument].parentWindow || window) : window; - return ( - typeof wnd[strHTMLElement] == TYPES.o ? o instanceof wnd[strHTMLElement] : //DOM2 - o && typeof o == TYPES.o && o !== null && o.nodeType === 1 && typeof o.nodeName == TYPES.s - ); - } - - /** - * Compares 2 arrays and returns the differences between them as a array. - * @param a1 The first array which shall be compared. - * @param a2 The second array which shall be compared. - * @returns {Array} The differences between the two arrays. - */ - function getArrayDifferences(a1, a2) { - var a = []; - var diff = []; - var i; - var k; - for (i = 0; i < a1.length; i++) - a[a1[i]] = true; - for (i = 0; i < a2.length; i++) { - if (a[a2[i]]) - delete a[a2[i]]; - else - a[a2[i]] = true; - } - for (k in a) - diff.push(k); - return diff; - } - - /** - * Returns Zero or the number to which the value can be parsed. - * @param value The value which shall be parsed. - * @param toFloat Indicates whether the number shall be parsed to a float. - */ - function parseToZeroOrNumber(value, toFloat) { - var num = toFloat ? parseFloat(value) : parseInt(value, 10); - return isNaN(num) ? 0 : num; - } - - /** - * Gets several information of the textarea and returns them as a object or undefined if the browser doesn't support it. - * @returns {{cursorRow: Number, cursorCol, rows: Number, cols: number, wRow: number, pos: number, max : number}} or undefined if not supported. - */ - function getTextareaInfo() { - //read needed values - var textareaCursorPosition = _targetElementNative.selectionStart; - if (textareaCursorPosition === undefined) - return; - - var textareaValue = _targetElement.val(); - var textareaLength = textareaValue[LEXICON.l]; - var textareaRowSplit = textareaValue.split('\n'); - var textareaLastRow = textareaRowSplit[LEXICON.l]; - var textareaCurrentCursorRowSplit = textareaValue.substr(0, textareaCursorPosition).split('\n'); - var widestRow = 0; - var textareaLastCol = 0; - var cursorRow = textareaCurrentCursorRowSplit[LEXICON.l]; - var cursorCol = textareaCurrentCursorRowSplit[textareaCurrentCursorRowSplit[LEXICON.l] - 1][LEXICON.l]; - var rowCols; - var i; - - //get widest Row and the last column of the textarea - for (i = 0; i < textareaRowSplit[LEXICON.l]; i++) { - rowCols = textareaRowSplit[i][LEXICON.l]; - if (rowCols > textareaLastCol) { - widestRow = i + 1; - textareaLastCol = rowCols; - } - } - - return { - _cursorRow: cursorRow, //cursorRow - _cursorColumn: cursorCol, //cursorCol - _rows: textareaLastRow, //rows - _columns: textareaLastCol, //cols - _widestRow: widestRow, //wRow - _cursorPosition: textareaCursorPosition, //pos - _cursorMax: textareaLength //max - }; - } - - /** - * Determines whether native overlay scrollbars are active. - * @returns {boolean} True if native overlay scrollbars are active, false otherwise. - */ - function nativeOverlayScrollbarsAreActive() { - return (_ignoreOverlayScrollbarHidingCache && (_nativeScrollbarIsOverlaid.x && _nativeScrollbarIsOverlaid.y)); - } - - /** - * Gets the element which is used to measure the content size. - * @returns {*} TextareaCover if target element is textarea else the ContentElement. - */ - function getContentMeasureElement() { - return _isTextarea ? _textareaCoverElement[0] : _contentElementNative; - } - - /** - * Generates a string which represents a HTML div with the given classes or attributes. - * @param classesOrAttrs The class of the div as string or a object which represents the attributes of the div. (The class attribute can also be written as "className".) - * @param content The content of the div as string. - * @returns {string} The concated string which represents a HTML div and its content. - */ - function generateDiv(classesOrAttrs, content) { - return '
' + - (content || _strEmpty) + - '
'; - } - - /** - * Selects or generates a div with the given class attribute. - * @param className The class names (divided by spaces) of the div which shall be selected or generated. - * @param selectParentOrOnlyChildren The parent element from which of the element shall be selected. (if undefined or boolean its hostElement) - * If its a boolean it decides whether only the children of the host element shall be selected. - * @returns {*} The generated or selected element. - */ - function selectOrGenerateDivByClass(className, selectParentOrOnlyChildren) { - var onlyChildren = type(selectParentOrOnlyChildren) == TYPES.b; - var selectParent = onlyChildren ? _hostElement : (selectParentOrOnlyChildren || _hostElement); - - return (_domExists && !selectParent[LEXICON.l]) - ? null - : _domExists - ? selectParent[onlyChildren ? 'children' : 'find'](_strDot + className.replace(/\s/g, _strDot)).eq(0) - : FRAMEWORK(generateDiv(className)) - } - - /** - * Gets the value of the given property from the given object. - * @param obj The object from which the property value shall be got. - * @param path The property of which the value shall be got. - * @returns {*} Returns the value of the searched property or undefined of the property wasn't found. - */ - function getObjectPropVal(obj, path) { - var splits = path.split(_strDot); - var i = 0; - var val; - for (; i < splits.length; i++) { - if (!obj[LEXICON.hOP](splits[i])) - return; - val = obj[splits[i]]; - if (i < splits.length && type(val) == TYPES.o) - obj = val; - } - return val; - } - - /** - * Sets the value of the given property from the given object. - * @param obj The object from which the property value shall be set. - * @param path The property of which the value shall be set. - * @param val The value of the property which shall be set. - */ - function setObjectPropVal(obj, path, val) { - var splits = path.split(_strDot); - var splitsLength = splits.length; - var i = 0; - var extendObj = {}; - var extendObjRoot = extendObj; - for (; i < splitsLength; i++) - extendObj = extendObj[splits[i]] = i + 1 < splitsLength ? {} : val; - FRAMEWORK.extend(obj, extendObjRoot, true); - } - - - //==== Utils Cache ====// - - /** - * Compares two values or objects and returns true if they aren't equal. - * @param current The first value or object which shall be compared. - * @param cache The second value or object which shall be compared. - * @param force If true the returned value is always true. - * @returns {boolean} True if both values or objects aren't equal or force is true, false otherwise. - */ - function checkCache(current, cache, force) { - if (force) - return force; - if (type(current) == TYPES.o && type(cache) == TYPES.o) { - for (var prop in current) { - if (prop !== 'c') { - if (current[LEXICON.hOP](prop) && cache[LEXICON.hOP](prop)) { - if (checkCache(current[prop], cache[prop])) - return true; - } - else { - return true; - } - } - } - } - else { - return current !== cache; - } - return false; - } - - - //==== Shortcuts ====// - - /** - * jQuery extend method shortcut with a appended "true" as first argument. - */ - function extendDeep() { - return FRAMEWORK.extend.apply(this, [true].concat([].slice.call(arguments))); - } - - /** - * jQuery addClass method shortcut. - */ - function addClass(el, classes) { - return _frameworkProto.addClass.call(el, classes); - } - - /** - * jQuery removeClass method shortcut. - */ - function removeClass(el, classes) { - return _frameworkProto.removeClass.call(el, classes); - } - - /** - * jQuery remove method shortcut. - */ - function remove(el) { - return _frameworkProto.remove.call(el); - } - - /** - * Finds the first child element with the given selector of the given element. - * @param el The root element from which the selector shall be valid. - * @param selector The selector of the searched element. - * @returns {*} The first element which is a child of the given element and matches the givens selector. - */ - function findFirst(el, selector) { - return _frameworkProto.find.call(el, selector).eq(0); - } - - - //==== API ====// - - /** - * Puts the instance to sleep. It wont respond to any changes in the DOM and won't update. Scrollbar Interactivity is also disabled as well as the resize handle. - * This behavior can be reset by calling the update method. - */ - _base.sleep = function () { - _sleeping = true; - }; - - /** - * Updates the plugin and DOM to the current options. - * This method should only be called if a update is 100% required. - * @param force True if every property shall be updated and the cache shall be ignored. - * !INTERNAL USAGE! : force can be a string "auto", "sync" or "zoom" too - * if "auto" then before a real update the content size and host element attributes gets checked, and if they changed only then the update method will be called. - * if "sync" then the async update process (MutationObserver or UpdateLoop) gets synchronized and a corresponding update takes place if one was needed due to pending changes. - * if "zoom" then a update takes place where it's assumed that content and host size changed - * @returns {boolean|undefined} - * If force is "sync" then a boolean is returned which indicates whether a update was needed due to pending changes. - * If force is "auto" then a boolean is returned whether a update was needed due to attribute or size changes. - * undefined otherwise. - */ - _base.update = function (force) { - if (_destroyed) - return; - - var attrsChanged; - var contentSizeC; - var isString = type(force) == TYPES.s; - var imgElementSelector = 'img'; - var imgElementLoadEvent = 'load'; - var doUpdateAuto; - var mutHost; - var mutContent; - - if (isString) { - if (force === _strAuto) { - attrsChanged = meaningfulAttrsChanged(); - contentSizeC = updateAutoContentSizeChanged(); - doUpdateAuto = attrsChanged || contentSizeC; - if (doUpdateAuto) { - update({ - _contentSizeChanged: contentSizeC, - _changedOptions: _initialized ? undefined : _currentPreparedOptions - }); - } - } - else if (force === _strSync) { - if (_mutationObserversConnected) { - mutHost = _mutationObserverHostCallback(_mutationObserverHost.takeRecords()); - mutContent = _mutationObserverContentCallback(_mutationObserverContent.takeRecords()); - } - else { - mutHost = _base.update(_strAuto); - } - } - else if (force === 'zoom') { - update({ - _hostSizeChanged: true, - _contentSizeChanged: true - }); - } - } - else { - force = _sleeping || force; - _sleeping = false; - if (!_base.update(_strSync) || force) - update({ _force: force }); - } - if (!_isTextarea) { - _contentElement.find(imgElementSelector).each(function (i, el) { - var index = COMPATIBILITY.inA(el, _imgs); - if (index === -1) - FRAMEWORK(el).off(imgElementLoadEvent, imgOnLoad).on(imgElementLoadEvent, imgOnLoad); - }); - } - return doUpdateAuto || mutHost || mutContent; - }; - - /** - Gets or sets the current options. The update method will be called automatically if new options were set. - * @param newOptions If new options are given, then the new options will be set, if new options aren't given (undefined or a not a plain object) then the current options will be returned. - * @param value If new options is a property path string, then this value will be used to set the option to which the property path string leads. - * @returns {*} - */ - _base.options = function (newOptions, value) { - var option = {}; - var changedOps; - - //return current options if newOptions are undefined or empty - if (FRAMEWORK.isEmptyObject(newOptions) || !FRAMEWORK.isPlainObject(newOptions)) { - if (type(newOptions) == TYPES.s) { - if (arguments.length > 1) { - setObjectPropVal(option, newOptions, value); - changedOps = setOptions(option); - } - else - return getObjectPropVal(_currentOptions, newOptions); - } - else - return _currentOptions; - } - else { - changedOps = setOptions(newOptions); - } - - if (!FRAMEWORK.isEmptyObject(changedOps)) { - update({ _changedOptions: changedOps }); - } - }; - - /** - * Restore the DOM, disconnects all observers, remove all resize observers and put the instance to sleep. - */ - _base.destroy = function () { - if (_destroyed) - return; - - //remove this instance from auto update loop - autoUpdateLoop.remove(_base); - - //disconnect all mutation observers - disconnectMutationObservers(); - - //remove all resize observers - setupResizeObserver(_sizeObserverElement); - setupResizeObserver(_sizeAutoObserverElement); - - //remove all extensions - for (var extName in _extensions) - _base.removeExt(extName); - - //remove all 'destroy' events - while (_destroyEvents[LEXICON.l] > 0) - _destroyEvents.pop()(); - - //remove all events from host element - setupHostMouseTouchEvents(true); - - //remove all helper / detection elements - if (_contentGlueElement) - remove(_contentGlueElement); - if (_contentArrangeElement) - remove(_contentArrangeElement); - if (_sizeAutoObserverAdded) - remove(_sizeAutoObserverElement); - - //remove all generated DOM - setupScrollbarsDOM(true); - setupScrollbarCornerDOM(true); - setupStructureDOM(true); - - //remove all generated image load events - for (var i = 0; i < _imgs[LEXICON.l]; i++) - FRAMEWORK(_imgs[i]).off('load', imgOnLoad); - _imgs = undefined; - - _destroyed = true; - _sleeping = true; - - //remove this instance from the instances list - INSTANCES(pluginTargetElement, 0); - dispatchCallback('onDestroyed'); - - //remove all properties and methods - //for (var property in _base) - // delete _base[property]; - //_base = undefined; - }; - - /** - * Scrolls to a given position or element. - * @param coordinates - * 1. Can be "coordinates" which looks like: - * { x : ?, y : ? } OR Object with x and y properties - * { left : ?, top : ? } OR Object with left and top properties - * { l : ?, t : ? } OR Object with l and t properties - * [ ?, ? ] OR Array where the first two element are the coordinates (first is x, second is y) - * ? A single value which stays for both axis - * A value can be a number, a string or a calculation. - * - * Operators: - * [NONE] The current scroll will be overwritten by the value. - * '+=' The value will be added to the current scroll offset - * '-=' The value will be subtracted from the current scroll offset - * '*=' The current scroll wil be multiplicated by the value. - * '/=' The current scroll wil be divided by the value. - * - * Units: - * [NONE] The value is the final scroll amount. final = (value * 1) - * 'px' Same as none - * '%' The value is dependent on the current scroll value. final = ((currentScrollValue / 100) * value) - * 'vw' The value is multiplicated by the viewport width. final = (value * viewportWidth) - * 'vh' The value is multiplicated by the viewport height. final = (value * viewportHeight) - * - * example final values: - * 200, '200px', '50%', '1vw', '1vh', '+=200', '/=1vw', '*=2px', '-=5vh', '+=33%', '+= 50% - 2px', '-= 1vw - 50%' - * - * 2. Can be a HTML or jQuery element: - * The final scroll offset is the offset (without margin) of the given HTML / jQuery element. - * - * 3. Can be a object with a HTML or jQuery element with additional settings: - * { - * el : [HTMLElement, jQuery element], MUST be specified, else this object isn't valid. - * scroll : [string, array, object], Default value is 'always'. - * block : [string, array, object], Default value is 'begin'. - * margin : [number, boolean, array, object] Default value is false. - * } - * - * Possible scroll settings are: - * 'always' Scrolls always. - * 'ifneeded' Scrolls only if the element isnt fully in view. - * 'never' Scrolls never. - * - * Possible block settings are: - * 'begin' Both axis shall be docked to the "begin" edge. - The element will be docked to the top and left edge of the viewport. - * 'end' Both axis shall be docked to the "end" edge. - The element will be docked to the bottom and right edge of the viewport. (If direction is RTL to the bottom and left edge.) - * 'center' Both axis shall be docked to "center". - The element will be centered in the viewport. - * 'nearest' The element will be docked to the nearest edge(s). - * - * Possible margin settings are: -- The actual margin of the element wont be affect, this option affects only the final scroll offset. - * [BOOLEAN] If true the css margin of the element will be used, if false no margin will be used. - * [NUMBER] The margin will be used for all edges. - * - * @param duration The duration of the scroll animation, OR a jQuery animation configuration object. - * @param easing The animation easing. - * @param complete The animation complete callback. - * @returns {{ - * position: {x: number, y: number}, - * ratio: {x: number, y: number}, - * max: {x: number, y: number}, - * handleOffset: {x: number, y: number}, - * handleLength: {x: number, y: number}, - * handleLengthRatio: {x: number, y: number}, t - * rackLength: {x: number, y: number}, - * isRTL: boolean, - * isRTLNormalized: boolean - * }} - */ - _base.scroll = function (coordinates, duration, easing, complete) { - if (arguments.length === 0 || coordinates === undefined) { - var infoX = _scrollHorizontalInfo; - var infoY = _scrollVerticalInfo; - var normalizeInvert = _normalizeRTLCache && _isRTL && _rtlScrollBehavior.i; - var normalizeNegate = _normalizeRTLCache && _isRTL && _rtlScrollBehavior.n; - var scrollX = infoX._currentScroll; - var scrollXRatio = infoX._currentScrollRatio; - var maxScrollX = infoX._maxScroll; - scrollXRatio = normalizeInvert ? 1 - scrollXRatio : scrollXRatio; - scrollX = normalizeInvert ? maxScrollX - scrollX : scrollX; - scrollX *= normalizeNegate ? -1 : 1; - maxScrollX *= normalizeNegate ? -1 : 1; - - return { - position: { - x: scrollX, - y: infoY._currentScroll - }, - ratio: { - x: scrollXRatio, - y: infoY._currentScrollRatio - }, - max: { - x: maxScrollX, - y: infoY._maxScroll - }, - handleOffset: { - x: infoX._handleOffset, - y: infoY._handleOffset - }, - handleLength: { - x: infoX._handleLength, - y: infoY._handleLength - }, - handleLengthRatio: { - x: infoX._handleLengthRatio, - y: infoY._handleLengthRatio - }, - trackLength: { - x: infoX._trackLength, - y: infoY._trackLength - }, - snappedHandleOffset: { - x: infoX._snappedHandleOffset, - y: infoY._snappedHandleOffset - }, - isRTL: _isRTL, - isRTLNormalized: _normalizeRTLCache - }; - } - - _base.update(_strSync); - - var normalizeRTL = _normalizeRTLCache; - var coordinatesXAxisProps = [_strX, _strLeft, 'l']; - var coordinatesYAxisProps = [_strY, _strTop, 't']; - var coordinatesOperators = ['+=', '-=', '*=', '/=']; - var durationIsObject = type(duration) == TYPES.o; - var completeCallback = durationIsObject ? duration.complete : complete; - var i; - var finalScroll = {}; - var specialEasing = {}; - var doScrollLeft; - var doScrollTop; - var animationOptions; - var strEnd = 'end'; - var strBegin = 'begin'; - var strCenter = 'center'; - var strNearest = 'nearest'; - var strAlways = 'always'; - var strNever = 'never'; - var strIfNeeded = 'ifneeded'; - var strLength = LEXICON.l; - var settingsAxis; - var settingsScroll; - var settingsBlock; - var settingsMargin; - var finalElement; - var elementObjSettingsAxisValues = [_strX, _strY, 'xy', 'yx']; - var elementObjSettingsBlockValues = [strBegin, strEnd, strCenter, strNearest]; - var elementObjSettingsScrollValues = [strAlways, strNever, strIfNeeded]; - var coordinatesIsElementObj = coordinates[LEXICON.hOP]('el'); - var possibleElement = coordinatesIsElementObj ? coordinates.el : coordinates; - var possibleElementIsJQuery = possibleElement instanceof FRAMEWORK || JQUERY ? possibleElement instanceof JQUERY : false; - var possibleElementIsHTMLElement = possibleElementIsJQuery ? false : isHTMLElement(possibleElement); - var updateScrollbarInfos = function () { - if (doScrollLeft) - refreshScrollbarHandleOffset(true); - if (doScrollTop) - refreshScrollbarHandleOffset(false); - }; - var proxyCompleteCallback = type(completeCallback) != TYPES.f ? undefined : function () { - updateScrollbarInfos(); - completeCallback(); - }; - function checkSettingsStringValue(currValue, allowedValues) { - for (i = 0; i < allowedValues[strLength]; i++) { - if (currValue === allowedValues[i]) - return true; - } - return false; - } - function getRawScroll(isX, coordinates) { - var coordinateProps = isX ? coordinatesXAxisProps : coordinatesYAxisProps; - coordinates = type(coordinates) == TYPES.s || type(coordinates) == TYPES.n ? [coordinates, coordinates] : coordinates; - - if (type(coordinates) == TYPES.a) - return isX ? coordinates[0] : coordinates[1]; - else if (type(coordinates) == TYPES.o) { - //decides RTL normalization "hack" with .n - //normalizeRTL = type(coordinates.n) == TYPES.b ? coordinates.n : normalizeRTL; - for (i = 0; i < coordinateProps[strLength]; i++) - if (coordinateProps[i] in coordinates) - return coordinates[coordinateProps[i]]; - } - } - function getFinalScroll(isX, rawScroll) { - var isString = type(rawScroll) == TYPES.s; - var operator; - var amount; - var scrollInfo = isX ? _scrollHorizontalInfo : _scrollVerticalInfo; - var currScroll = scrollInfo._currentScroll; - var maxScroll = scrollInfo._maxScroll; - var mult = ' * '; - var finalValue; - var isRTLisX = _isRTL && isX; - var normalizeShortcuts = isRTLisX && _rtlScrollBehavior.n && !normalizeRTL; - var strReplace = 'replace'; - var evalFunc = eval; - var possibleOperator; - if (isString) { - //check operator - if (rawScroll[strLength] > 2) { - possibleOperator = rawScroll.substr(0, 2); - if (inArray(possibleOperator, coordinatesOperators) > -1) - operator = possibleOperator; - } - - //calculate units and shortcuts - rawScroll = operator ? rawScroll.substr(2) : rawScroll; - rawScroll = rawScroll - [strReplace](/min/g, 0) //'min' = 0% - [strReplace](//g, (normalizeShortcuts ? '-' : _strEmpty) + _strHundredPercent) //'>' = 100% - [strReplace](/px/g, _strEmpty) - [strReplace](/%/g, mult + (maxScroll * (isRTLisX && _rtlScrollBehavior.n ? -1 : 1) / 100.0)) - [strReplace](/vw/g, mult + _viewportSize.w) - [strReplace](/vh/g, mult + _viewportSize.h); - amount = parseToZeroOrNumber(isNaN(rawScroll) ? parseToZeroOrNumber(evalFunc(rawScroll), true).toFixed() : rawScroll); - } - else { - amount = rawScroll; - } - - if (amount !== undefined && !isNaN(amount) && type(amount) == TYPES.n) { - var normalizeIsRTLisX = normalizeRTL && isRTLisX; - var operatorCurrScroll = currScroll * (normalizeIsRTLisX && _rtlScrollBehavior.n ? -1 : 1); - var invert = normalizeIsRTLisX && _rtlScrollBehavior.i; - var negate = normalizeIsRTLisX && _rtlScrollBehavior.n; - operatorCurrScroll = invert ? (maxScroll - operatorCurrScroll) : operatorCurrScroll; - switch (operator) { - case '+=': - finalValue = operatorCurrScroll + amount; - break; - case '-=': - finalValue = operatorCurrScroll - amount; - break; - case '*=': - finalValue = operatorCurrScroll * amount; - break; - case '/=': - finalValue = operatorCurrScroll / amount; - break; - default: - finalValue = amount; - break; - } - finalValue = invert ? maxScroll - finalValue : finalValue; - finalValue *= negate ? -1 : 1; - finalValue = isRTLisX && _rtlScrollBehavior.n ? MATH.min(0, MATH.max(maxScroll, finalValue)) : MATH.max(0, MATH.min(maxScroll, finalValue)); - } - return finalValue === currScroll ? undefined : finalValue; - } - function getPerAxisValue(value, valueInternalType, defaultValue, allowedValues) { - var resultDefault = [defaultValue, defaultValue]; - var valueType = type(value); - var valueArrLength; - var valueArrItem; - - //value can be [ string, or array of two strings ] - if (valueType == valueInternalType) { - value = [value, value]; - } - else if (valueType == TYPES.a) { - valueArrLength = value[strLength]; - if (valueArrLength > 2 || valueArrLength < 1) - value = resultDefault; - else { - if (valueArrLength === 1) - value[1] = defaultValue; - for (i = 0; i < valueArrLength; i++) { - valueArrItem = value[i]; - if (type(valueArrItem) != valueInternalType || !checkSettingsStringValue(valueArrItem, allowedValues)) { - value = resultDefault; - break; - } - } - } - } - else if (valueType == TYPES.o) - value = [value[_strX] || defaultValue, value[_strY] || defaultValue]; - else - value = resultDefault; - return { x: value[0], y: value[1] }; - } - function generateMargin(marginTopRightBottomLeftArray) { - var result = []; - var currValue; - var currValueType; - var valueDirections = [_strTop, _strRight, _strBottom, _strLeft]; - for (i = 0; i < marginTopRightBottomLeftArray[strLength]; i++) { - if (i === valueDirections[strLength]) - break; - currValue = marginTopRightBottomLeftArray[i]; - currValueType = type(currValue); - if (currValueType == TYPES.b) - result.push(currValue ? parseToZeroOrNumber(finalElement.css(_strMarginMinus + valueDirections[i])) : 0); - else - result.push(currValueType == TYPES.n ? currValue : 0); - } - return result; - } - - if (possibleElementIsJQuery || possibleElementIsHTMLElement) { - //get settings - var margin = coordinatesIsElementObj ? coordinates.margin : 0; - var axis = coordinatesIsElementObj ? coordinates.axis : 0; - var scroll = coordinatesIsElementObj ? coordinates.scroll : 0; - var block = coordinatesIsElementObj ? coordinates.block : 0; - var marginDefault = [0, 0, 0, 0]; - var marginType = type(margin); - var marginLength; - finalElement = possibleElementIsJQuery ? possibleElement : FRAMEWORK(possibleElement); - - if (finalElement[strLength] > 0) { - //margin can be [ boolean, number, array of 2, array of 4, object ] - if (marginType == TYPES.n || marginType == TYPES.b) - margin = generateMargin([margin, margin, margin, margin]); - else if (marginType == TYPES.a) { - marginLength = margin[strLength]; - if (marginLength === 2) - margin = generateMargin([margin[0], margin[1], margin[0], margin[1]]); - else if (marginLength >= 4) - margin = generateMargin(margin); - else - margin = marginDefault; - } - else if (marginType == TYPES.o) - margin = generateMargin([margin[_strTop], margin[_strRight], margin[_strBottom], margin[_strLeft]]); - else - margin = marginDefault; - - //block = type(block) === TYPES.b ? block ? [ strNearest, strBegin ] : [ strNearest, strEnd ] : block; - settingsAxis = checkSettingsStringValue(axis, elementObjSettingsAxisValues) ? axis : 'xy'; - settingsScroll = getPerAxisValue(scroll, TYPES.s, strAlways, elementObjSettingsScrollValues); - settingsBlock = getPerAxisValue(block, TYPES.s, strBegin, elementObjSettingsBlockValues); - settingsMargin = margin; - - var viewportScroll = { - l: _scrollHorizontalInfo._currentScroll, - t: _scrollVerticalInfo._currentScroll - }; - // use padding element instead of viewport element because padding element has never padding, margin or position applied. - var viewportOffset = _paddingElement.offset(); - - //get coordinates - var elementOffset = finalElement.offset(); - var doNotScroll = { - x: settingsScroll.x == strNever || settingsAxis == _strY, - y: settingsScroll.y == strNever || settingsAxis == _strX - }; - elementOffset[_strTop] -= settingsMargin[0]; - elementOffset[_strLeft] -= settingsMargin[3]; - var elementScrollCoordinates = { - x: MATH.round(elementOffset[_strLeft] - viewportOffset[_strLeft] + viewportScroll.l), - y: MATH.round(elementOffset[_strTop] - viewportOffset[_strTop] + viewportScroll.t) - }; - if (_isRTL) { - if (!_rtlScrollBehavior.n && !_rtlScrollBehavior.i) - elementScrollCoordinates.x = MATH.round(viewportOffset[_strLeft] - elementOffset[_strLeft] + viewportScroll.l); - if (_rtlScrollBehavior.n && normalizeRTL) - elementScrollCoordinates.x *= -1; - if (_rtlScrollBehavior.i && normalizeRTL) - elementScrollCoordinates.x = MATH.round(viewportOffset[_strLeft] - elementOffset[_strLeft] + (_scrollHorizontalInfo._maxScroll - viewportScroll.l)); - } - - //measuring is required - if (settingsBlock.x != strBegin || settingsBlock.y != strBegin || settingsScroll.x == strIfNeeded || settingsScroll.y == strIfNeeded || _isRTL) { - var measuringElm = finalElement[0]; - var rawElementSize = _supportTransform ? measuringElm[LEXICON.bCR]() : { - width: measuringElm[LEXICON.oW], - height: measuringElm[LEXICON.oH] - }; - var elementSize = { - w: rawElementSize[_strWidth] + settingsMargin[3] + settingsMargin[1], - h: rawElementSize[_strHeight] + settingsMargin[0] + settingsMargin[2] - }; - var finalizeBlock = function (isX) { - var vars = getScrollbarVars(isX); - var wh = vars._w_h; - var lt = vars._left_top; - var xy = vars._x_y; - var blockIsEnd = settingsBlock[xy] == (isX ? _isRTL ? strBegin : strEnd : strEnd); - var blockIsCenter = settingsBlock[xy] == strCenter; - var blockIsNearest = settingsBlock[xy] == strNearest; - var scrollNever = settingsScroll[xy] == strNever; - var scrollIfNeeded = settingsScroll[xy] == strIfNeeded; - var vpSize = _viewportSize[wh]; - var vpOffset = viewportOffset[lt]; - var elSize = elementSize[wh]; - var elOffset = elementOffset[lt]; - var divide = blockIsCenter ? 2 : 1; - var elementCenterOffset = elOffset + (elSize / 2); - var viewportCenterOffset = vpOffset + (vpSize / 2); - var isInView = - elSize <= vpSize - && elOffset >= vpOffset - && elOffset + elSize <= vpOffset + vpSize; - - if (scrollNever) - doNotScroll[xy] = true; - else if (!doNotScroll[xy]) { - if (blockIsNearest || scrollIfNeeded) { - doNotScroll[xy] = scrollIfNeeded ? isInView : false; - blockIsEnd = elSize < vpSize ? elementCenterOffset > viewportCenterOffset : elementCenterOffset < viewportCenterOffset; - } - elementScrollCoordinates[xy] -= blockIsEnd || blockIsCenter ? ((vpSize / divide) - (elSize / divide)) * (isX && _isRTL && normalizeRTL ? -1 : 1) : 0; - } - }; - finalizeBlock(true); - finalizeBlock(false); - } - - if (doNotScroll.y) - delete elementScrollCoordinates.y; - if (doNotScroll.x) - delete elementScrollCoordinates.x; - - coordinates = elementScrollCoordinates; - } - } - - finalScroll[_strScrollLeft] = getFinalScroll(true, getRawScroll(true, coordinates)); - finalScroll[_strScrollTop] = getFinalScroll(false, getRawScroll(false, coordinates)); - doScrollLeft = finalScroll[_strScrollLeft] !== undefined; - doScrollTop = finalScroll[_strScrollTop] !== undefined; - - if ((doScrollLeft || doScrollTop) && (duration > 0 || durationIsObject)) { - if (durationIsObject) { - duration.complete = proxyCompleteCallback; - _viewportElement.animate(finalScroll, duration); - } - else { - animationOptions = { - duration: duration, - complete: proxyCompleteCallback - }; - if (type(easing) == TYPES.a || FRAMEWORK.isPlainObject(easing)) { - specialEasing[_strScrollLeft] = easing[0] || easing.x; - specialEasing[_strScrollTop] = easing[1] || easing.y; - animationOptions.specialEasing = specialEasing; - } - else { - animationOptions.easing = easing; - } - _viewportElement.animate(finalScroll, animationOptions); - } - } - else { - if (doScrollLeft) - _viewportElement[_strScrollLeft](finalScroll[_strScrollLeft]); - if (doScrollTop) - _viewportElement[_strScrollTop](finalScroll[_strScrollTop]); - updateScrollbarInfos(); - } - }; - - /** - * Stops all scroll animations. - * @returns {*} The current OverlayScrollbars instance (for chaining). - */ - _base.scrollStop = function (param1, param2, param3) { - _viewportElement.stop(param1, param2, param3); - return _base; - }; - - /** - * Returns all relevant elements. - * @param elementName The name of the element which shall be returned. - * @returns {{target: *, host: *, padding: *, viewport: *, content: *, scrollbarHorizontal: {scrollbar: *, track: *, handle: *}, scrollbarVertical: {scrollbar: *, track: *, handle: *}, scrollbarCorner: *} | *} - */ - _base.getElements = function (elementName) { - var obj = { - target: _targetElementNative, - host: _hostElementNative, - padding: _paddingElementNative, - viewport: _viewportElementNative, - content: _contentElementNative, - scrollbarHorizontal: { - scrollbar: _scrollbarHorizontalElement[0], - track: _scrollbarHorizontalTrackElement[0], - handle: _scrollbarHorizontalHandleElement[0] - }, - scrollbarVertical: { - scrollbar: _scrollbarVerticalElement[0], - track: _scrollbarVerticalTrackElement[0], - handle: _scrollbarVerticalHandleElement[0] - }, - scrollbarCorner: _scrollbarCornerElement[0] - }; - return type(elementName) == TYPES.s ? getObjectPropVal(obj, elementName) : obj; - }; - - /** - * Returns a object which describes the current state of this instance. - * @param stateProperty A specific property from the state object which shall be returned. - * @returns {{widthAuto, heightAuto, overflowAmount, hideOverflow, hasOverflow, contentScrollSize, viewportSize, hostSize, autoUpdate} | *} - */ - _base.getState = function (stateProperty) { - function prepare(obj) { - if (!FRAMEWORK.isPlainObject(obj)) - return obj; - var extended = extendDeep({}, obj); - var changePropertyName = function (from, to) { - if (extended[LEXICON.hOP](from)) { - extended[to] = extended[from]; - delete extended[from]; - } - }; - changePropertyName('w', _strWidth); //change w to width - changePropertyName('h', _strHeight); //change h to height - delete extended.c; //delete c (the 'changed' prop) - return extended; - }; - var obj = { - destroyed: !!prepare(_destroyed), - sleeping: !!prepare(_sleeping), - autoUpdate: prepare(!_mutationObserversConnected), - widthAuto: prepare(_widthAutoCache), - heightAuto: prepare(_heightAutoCache), - padding: prepare(_cssPaddingCache), - overflowAmount: prepare(_overflowAmountCache), - hideOverflow: prepare(_hideOverflowCache), - hasOverflow: prepare(_hasOverflowCache), - contentScrollSize: prepare(_contentScrollSizeCache), - viewportSize: prepare(_viewportSize), - hostSize: prepare(_hostSizeCache), - documentMixed: prepare(_documentMixed) - }; - return type(stateProperty) == TYPES.s ? getObjectPropVal(obj, stateProperty) : obj; - }; - - /** - * Gets all or specific extension instance. - * @param extName The name of the extension from which the instance shall be got. - * @returns {{}} The instance of the extension with the given name or undefined if the instance couldn't be found. - */ - _base.ext = function (extName) { - var result; - var privateMethods = _extensionsPrivateMethods.split(' '); - var i = 0; - if (type(extName) == TYPES.s) { - if (_extensions[LEXICON.hOP](extName)) { - result = extendDeep({}, _extensions[extName]); - for (; i < privateMethods.length; i++) - delete result[privateMethods[i]]; - } - } - else { - result = {}; - for (i in _extensions) - result[i] = extendDeep({}, _base.ext(i)); - } - return result; - }; - - /** - * Adds a extension to this instance. - * @param extName The name of the extension which shall be added. - * @param extensionOptions The extension options which shall be used. - * @returns {{}} The instance of the added extension or undefined if the extension couldn't be added properly. - */ - _base.addExt = function (extName, extensionOptions) { - var registeredExtensionObj = _plugin.extension(extName); - var instance; - var instanceAdded; - var instanceContract; - var contractResult; - var contractFulfilled = true; - if (registeredExtensionObj) { - if (!_extensions[LEXICON.hOP](extName)) { - instance = registeredExtensionObj.extensionFactory.call(_base, - extendDeep({}, registeredExtensionObj.defaultOptions), - FRAMEWORK, - COMPATIBILITY); - - if (instance) { - instanceContract = instance.contract; - if (type(instanceContract) == TYPES.f) { - contractResult = instanceContract(window); - contractFulfilled = type(contractResult) == TYPES.b ? contractResult : contractFulfilled; - } - if (contractFulfilled) { - _extensions[extName] = instance; - instanceAdded = instance.added; - if (type(instanceAdded) == TYPES.f) - instanceAdded(extensionOptions); - - return _base.ext(extName); - } - } - } - else - return _base.ext(extName); - } - else - console.warn("A extension with the name \"" + extName + "\" isn't registered."); - }; - - /** - * Removes a extension from this instance. - * @param extName The name of the extension which shall be removed. - * @returns {boolean} True if the extension was removed, false otherwise e.g. if the extension wasn't added before. - */ - _base.removeExt = function (extName) { - var instance = _extensions[extName]; - var instanceRemoved; - if (instance) { - delete _extensions[extName]; - - instanceRemoved = instance.removed; - if (type(instanceRemoved) == TYPES.f) - instanceRemoved(); - - return true; - } - return false; - }; - - /** - * Constructs the plugin. - * @param targetElement The element to which the plugin shall be applied. - * @param options The initial options of the plugin. - * @param extensions The extension(s) which shall be added right after the initialization. - * @returns {boolean} True if the plugin was successfully initialized, false otherwise. - */ - function construct(targetElement, options, extensions) { - _defaultOptions = globals.defaultOptions; - _nativeScrollbarStyling = globals.nativeScrollbarStyling; - _nativeScrollbarSize = extendDeep({}, globals.nativeScrollbarSize); - _nativeScrollbarIsOverlaid = extendDeep({}, globals.nativeScrollbarIsOverlaid); - _overlayScrollbarDummySize = extendDeep({}, globals.overlayScrollbarDummySize); - _rtlScrollBehavior = extendDeep({}, globals.rtlScrollBehavior); - - //parse & set options but don't update - setOptions(extendDeep({}, _defaultOptions, options)); - - _cssCalc = globals.cssCalc; - _msieVersion = globals.msie; - _autoUpdateRecommended = globals.autoUpdateRecommended; - _supportTransition = globals.supportTransition; - _supportTransform = globals.supportTransform; - _supportPassiveEvents = globals.supportPassiveEvents; - _supportResizeObserver = globals.supportResizeObserver; - _supportMutationObserver = globals.supportMutationObserver; - _restrictedMeasuring = globals.restrictedMeasuring; - _documentElement = FRAMEWORK(targetElement.ownerDocument); - _documentElementNative = _documentElement[0]; - _windowElement = FRAMEWORK(_documentElementNative.defaultView || _documentElementNative.parentWindow); - _windowElementNative = _windowElement[0]; - _htmlElement = findFirst(_documentElement, 'html'); - _bodyElement = findFirst(_htmlElement, 'body'); - _targetElement = FRAMEWORK(targetElement); - _targetElementNative = _targetElement[0]; - _isTextarea = _targetElement.is('textarea'); - _isBody = _targetElement.is('body'); - _documentMixed = _documentElementNative !== document; - - /* On a div Element The if checks only whether: - * - the targetElement has the class "os-host" - * - the targetElement has a a child with the class "os-padding" - * - * If that's the case, its assumed the DOM has already the following structure: - * (The ".os-host" element is the targetElement) - * - *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- * - * ===================================================================================== - * - * On a Textarea Element The if checks only whether: - * - the targetElement has the class "os-textarea" - * - the targetElement is inside a element with the class "os-content" - * - * If that's the case, its assumed the DOM has already the following structure: - * (The ".os-textarea" (textarea) element is the targetElement) - * - *
- *
- *
- *
- *
- *
- * - *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- */ - _domExists = _isTextarea - ? _targetElement.hasClass(_classNameTextareaElement) && _targetElement.parent().hasClass(_classNameContentElement) - : _targetElement.hasClass(_classNameHostElement) && _targetElement.children(_strDot + _classNamePaddingElement)[LEXICON.l]; - - var initBodyScroll; - var bodyMouseTouchDownListener; - - //check if the plugin hasn't to be initialized - if (_nativeScrollbarIsOverlaid.x && _nativeScrollbarIsOverlaid.y && !_currentPreparedOptions.nativeScrollbarsOverlaid.initialize) { - dispatchCallback('onInitializationWithdrawn'); - if (_domExists) { - setupStructureDOM(true); - setupScrollbarsDOM(true); - setupScrollbarCornerDOM(true); - } - - _destroyed = true; - _sleeping = true; - - return _base; - } - - if (_isBody) { - initBodyScroll = {}; - initBodyScroll.l = MATH.max(_targetElement[_strScrollLeft](), _htmlElement[_strScrollLeft](), _windowElement[_strScrollLeft]()); - initBodyScroll.t = MATH.max(_targetElement[_strScrollTop](), _htmlElement[_strScrollTop](), _windowElement[_strScrollTop]()); - - bodyMouseTouchDownListener = function () { - _viewportElement.removeAttr(LEXICON.ti); - setupResponsiveEventListener(_viewportElement, _strMouseTouchDownEvent, bodyMouseTouchDownListener, true, true); - } - } - - //build OverlayScrollbars DOM - setupStructureDOM(); - setupScrollbarsDOM(); - setupScrollbarCornerDOM(); - - //create OverlayScrollbars events - setupStructureEvents(); - setupScrollbarEvents(true); - setupScrollbarEvents(false); - setupScrollbarCornerEvents(); - - //create mutation observers - createMutationObservers(); - - //build resize observer for the host element - setupResizeObserver(_sizeObserverElement, hostOnResized); - - if (_isBody) { - //apply the body scroll to handle it right in the update method - _viewportElement[_strScrollLeft](initBodyScroll.l)[_strScrollTop](initBodyScroll.t); - - //set the focus on the viewport element so you dont have to click on the page to use keyboard keys (up / down / space) for scrolling - if (document.activeElement == targetElement && _viewportElementNative.focus) { - //set a tabindex to make the viewportElement focusable - _viewportElement.attr(LEXICON.ti, '-1'); - _viewportElementNative.focus(); - - /* the tabindex has to be removed due to; - * If you set the tabindex attribute on an
, then its child content cannot be scrolled with the arrow keys unless you set tabindex on the content, too - * https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex - */ - setupResponsiveEventListener(_viewportElement, _strMouseTouchDownEvent, bodyMouseTouchDownListener, false, true); - } - } - - //update for the first time & initialize cache - _base.update(_strAuto); - - //the plugin is initialized now! - _initialized = true; - dispatchCallback('onInitialized'); - - //call all callbacks which would fire before the initialized was complete - each(_callbacksInitQeueue, function (index, value) { dispatchCallback(value.n, value.a); }); - _callbacksInitQeueue = []; - - //add extensions - if (type(extensions) == TYPES.s) - extensions = [extensions]; - if (COMPATIBILITY.isA(extensions)) - each(extensions, function (index, value) { _base.addExt(value); }); - else if (FRAMEWORK.isPlainObject(extensions)) - each(extensions, function (key, value) { _base.addExt(key, value); }); - - //add the transition class for transitions AFTER the first update & AFTER the applied extensions (for preventing unwanted transitions) - setTimeout(function () { - if (_supportTransition && !_destroyed) - addClass(_hostElement, _classNameHostTransition); - }, 333); - - return _base; - } - - if (_plugin.valid(construct(pluginTargetElement, options, extensions))) { - INSTANCES(pluginTargetElement, _base); - } - - return _base; - } - - /** - * Initializes a new OverlayScrollbarsInstance object or changes options if already initialized or returns the current instance. - * @param pluginTargetElements The elements to which the Plugin shall be initialized. - * @param options The custom options with which the plugin shall be initialized. - * @param extensions The extension(s) which shall be added right after initialization. - * @returns {*} - */ - _plugin = window[PLUGINNAME] = function (pluginTargetElements, options, extensions) { - if (arguments[LEXICON.l] === 0) - return this; - - var arr = []; - var optsIsPlainObj = FRAMEWORK.isPlainObject(options); - var inst; - var result; - - //pluginTargetElements is null or undefined - if (!pluginTargetElements) - return optsIsPlainObj || !options ? result : arr; - - /* - pluginTargetElements will be converted to: - 1. A jQueryElement Array - 2. A HTMLElement Array - 3. A Array with a single HTML Element - so pluginTargetElements is always a array. - */ - pluginTargetElements = pluginTargetElements[LEXICON.l] != undefined ? pluginTargetElements : [pluginTargetElements[0] || pluginTargetElements]; - initOverlayScrollbarsStatics(); - - if (pluginTargetElements[LEXICON.l] > 0) { - if (optsIsPlainObj) { - FRAMEWORK.each(pluginTargetElements, function (i, v) { - inst = v; - if (inst !== undefined) - arr.push(OverlayScrollbarsInstance(inst, options, extensions, _pluginsGlobals, _pluginsAutoUpdateLoop)); - }); - } - else { - FRAMEWORK.each(pluginTargetElements, function (i, v) { - inst = INSTANCES(v); - if ((options === '!' && _plugin.valid(inst)) || (COMPATIBILITY.type(options) == TYPES.f && options(v, inst))) - arr.push(inst); - else if (options === undefined) - arr.push(inst); - }); - } - result = arr[LEXICON.l] === 1 ? arr[0] : arr; - } - return result; - }; - - /** - * Returns a object which contains global information about the plugin and each instance of it. - * The returned object is just a copy, that means that changes to the returned object won't have any effect to the original object. - */ - _plugin.globals = function () { - initOverlayScrollbarsStatics(); - var globals = FRAMEWORK.extend(true, {}, _pluginsGlobals); - delete globals['msie']; - return globals; - }; - - /** - * Gets or Sets the default options for each new plugin initialization. - * @param newDefaultOptions The object with which the default options shall be extended. - */ - _plugin.defaultOptions = function (newDefaultOptions) { - initOverlayScrollbarsStatics(); - var currDefaultOptions = _pluginsGlobals.defaultOptions; - if (newDefaultOptions === undefined) - return FRAMEWORK.extend(true, {}, currDefaultOptions); - - //set the new default options - _pluginsGlobals.defaultOptions = FRAMEWORK.extend(true, {}, currDefaultOptions, _pluginsOptions._validate(newDefaultOptions, _pluginsOptions._template, true, currDefaultOptions)._default); - }; - - /** - * Checks whether the passed instance is a non-destroyed OverlayScrollbars instance. - * @param osInstance The potential OverlayScrollbars instance which shall be checked. - * @returns {boolean} True if the passed value is a non-destroyed OverlayScrollbars instance, false otherwise. - */ - _plugin.valid = function (osInstance) { - return osInstance instanceof _plugin && !osInstance.getState().destroyed; - }; - - /** - * Registers, Unregisters or returns a extension. - * Register: Pass the name and the extension. (defaultOptions is optional) - * Unregister: Pass the name and anything except a function as extension parameter. - * Get extension: Pass the name of the extension which shall be got. - * Get all extensions: Pass no arguments. - * @param extensionName The name of the extension which shall be registered, unregistered or returned. - * @param extension A function which generates the instance of the extension or anything other to remove a already registered extension. - * @param defaultOptions The default options which shall be used for the registered extension. - */ - _plugin.extension = function (extensionName, extension, defaultOptions) { - var extNameTypeString = COMPATIBILITY.type(extensionName) == TYPES.s; - var argLen = arguments[LEXICON.l]; - var i = 0; - if (argLen < 1 || !extNameTypeString) { - //return a copy of all extension objects - return FRAMEWORK.extend(true, { length: _pluginsExtensions[LEXICON.l] }, _pluginsExtensions); - } - else if (extNameTypeString) { - if (COMPATIBILITY.type(extension) == TYPES.f) { - //register extension - _pluginsExtensions.push({ - name: extensionName, - extensionFactory: extension, - defaultOptions: defaultOptions - }); - } - else { - for (; i < _pluginsExtensions[LEXICON.l]; i++) { - if (_pluginsExtensions[i].name === extensionName) { - if (argLen > 1) - _pluginsExtensions.splice(i, 1); //remove extension - else - return FRAMEWORK.extend(true, {}, _pluginsExtensions[i]); //return extension with the given name - } - } - } - } - }; - - return _plugin; - })(); - - if (JQUERY && JQUERY.fn) { - /** - * The jQuery initialization interface. - * @param options The initial options for the construction of the plugin. To initialize the plugin, this option has to be a object! If it isn't a object, the instance(s) are returned and the plugin wont be initialized. - * @param extensions The extension(s) which shall be added right after initialization. - * @returns {*} After initialization it returns the jQuery element array, else it returns the instance(s) of the elements which are selected. - */ - JQUERY.fn.overlayScrollbars = function (options, extensions) { - var _elements = this; - if (JQUERY.isPlainObject(options)) { - JQUERY.each(_elements, function () { PLUGIN(this, options, extensions); }); - return _elements; - } - else - return PLUGIN(_elements, options); - }; - } - return PLUGIN; - } -)); \ No newline at end of file +/*! + * OverlayScrollbars + * https://github.com/KingSora/OverlayScrollbars + * + * Version: 1.11.0 + * + * Copyright KingSora | Rene Haas. + * https://github.com/KingSora + * + * Released under the MIT license. + * Date: 29.02.2020 + */ + +(function (global, factory) { + if (typeof define === 'function' && define.amd) + define(function () { return factory(global, global.document, undefined); }); + else if (typeof module === 'object' && typeof module.exports === 'object') + module.exports = factory(global, global.document, undefined); + else + factory(global, global.document, undefined); +}(typeof window !== 'undefined' ? window : this, + function (window, document, undefined) { + 'use strict'; + var PLUGINNAME = 'OverlayScrollbars'; + var TYPES = { + o: 'object', + f: 'function', + a: 'array', + s: 'string', + b: 'boolean', + n: 'number', + u: 'undefined', + z: 'null' + //d : 'date', + //e : 'error', + //r : 'regexp', + //y : 'symbol' + }; + var LEXICON = { + c: 'class', + s: 'style', + i: 'id', + l: 'length', + p: 'prototype', + ti: 'tabindex', + oH: 'offsetHeight', + cH: 'clientHeight', + sH: 'scrollHeight', + oW: 'offsetWidth', + cW: 'clientWidth', + sW: 'scrollWidth', + hOP: 'hasOwnProperty', + bCR: 'getBoundingClientRect' + }; + var VENDORS = (function () { + //https://developer.mozilla.org/en-US/docs/Glossary/Vendor_Prefix + var jsCache = {}; + var cssCache = {}; + var cssPrefixes = ['-webkit-', '-moz-', '-o-', '-ms-']; + var jsPrefixes = ['WebKit', 'Moz', 'O', 'MS']; + function firstLetterToUpper(str) { + return str.charAt(0).toUpperCase() + str.slice(1); + } + + return { + _cssPrefixes: cssPrefixes, + _jsPrefixes: jsPrefixes, + _cssProperty: function (name) { + var result = cssCache[name]; + + if (cssCache[LEXICON.hOP](name)) + return result; + + var uppercasedName = firstLetterToUpper(name); + var elmStyle = document.createElement('div')[LEXICON.s]; + var resultPossibilities; + var i = 0; + var v; + var currVendorWithoutDashes; + + for (; i < cssPrefixes.length; i++) { + currVendorWithoutDashes = cssPrefixes[i].replace(/-/g, ''); + resultPossibilities = [ + name, //transition + cssPrefixes[i] + name, //-webkit-transition + currVendorWithoutDashes + uppercasedName, //webkitTransition + firstLetterToUpper(currVendorWithoutDashes) + uppercasedName //WebkitTransition + ]; + for (v = 0; v < resultPossibilities[LEXICON.l]; v++) { + if (elmStyle[resultPossibilities[v]] !== undefined) { + result = resultPossibilities[v]; + break; + } + } + } + + cssCache[name] = result; + return result; + }, + _jsAPI: function (name, isInterface, fallback) { + var i = 0; + var result = jsCache[name]; + + if (!jsCache[LEXICON.hOP](name)) { + result = window[name]; + for (; i < jsPrefixes[LEXICON.l]; i++) + result = result || window[(isInterface ? jsPrefixes[i] : jsPrefixes[i].toLowerCase()) + firstLetterToUpper(name)]; + jsCache[name] = result; + } + return result || fallback; + } + + } + })(); + var COMPATIBILITY = (function () { + function windowSize(x) { + return x ? window.innerWidth || document.documentElement[LEXICON.cW] || document.body[LEXICON.cW] : window.innerHeight || document.documentElement[LEXICON.cH] || document.body[LEXICON.cH]; + } + function bind(func, thisObj) { + if (typeof func != TYPES.f) { + throw "Can't bind function!"; + // closest thing possible to the ECMAScript 5 + // internal IsCallable function + //throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable'); + } + var proto = LEXICON.p; + var aArgs = Array[proto].slice.call(arguments, 2); + var fNOP = function () { }; + var fBound = function () { return func.apply(this instanceof fNOP ? this : thisObj, aArgs.concat(Array[proto].slice.call(arguments))); }; + + if (func[proto]) + fNOP[proto] = func[proto]; // Function.prototype doesn't have a prototype property + fBound[proto] = new fNOP(); + + return fBound; + } + + return { + /** + * Gets the current window width. + * @returns {Number|number} The current window width in pixel. + */ + wW: bind(windowSize, 0, true), + + /** + * Gets the current window height. + * @returns {Number|number} The current window height in pixel. + */ + wH: bind(windowSize, 0), + + /** + * Gets the MutationObserver Object or undefined if not supported. + * @returns {MutationObserver|*|undefined} The MutationsObserver Object or undefined. + */ + mO: bind(VENDORS._jsAPI, 0, 'MutationObserver', true), + + /** + * Gets the ResizeObserver Object or undefined if not supported. + * @returns {MutationObserver|*|undefined} The ResizeObserver Object or undefined. + */ + rO: bind(VENDORS._jsAPI, 0, 'ResizeObserver', true), + + /** + * Gets the RequestAnimationFrame method or it's corresponding polyfill. + * @returns {*|Function} The RequestAnimationFrame method or it's corresponding polyfill. + */ + rAF: bind(VENDORS._jsAPI, 0, 'requestAnimationFrame', false, function (func) { return window.setTimeout(func, 1000 / 60); }), + + /** + * Gets the CancelAnimationFrame method or it's corresponding polyfill. + * @returns {*|Function} The CancelAnimationFrame method or it's corresponding polyfill. + */ + cAF: bind(VENDORS._jsAPI, 0, 'cancelAnimationFrame', false, function (id) { return window.clearTimeout(id); }), + + /** + * Gets the current time. + * @returns {number} The current time. + */ + now: function () { + return Date.now && Date.now() || new Date().getTime(); + }, + + /** + * Stops the propagation of the given event. + * @param event The event of which the propagation shall be stoped. + */ + stpP: function (event) { + if (event.stopPropagation) + event.stopPropagation(); + else + event.cancelBubble = true; + }, + + /** + * Prevents the default action of the given event. + * @param event The event of which the default action shall be prevented. + */ + prvD: function (event) { + if (event.preventDefault && event.cancelable) + event.preventDefault(); + else + event.returnValue = false; + }, + + /** + * Gets the pageX and pageY values of the given mouse event. + * @param event The mouse event of which the pageX and pageX shall be got. + * @returns {{x: number, y: number}} x = pageX value, y = pageY value. + */ + page: function (event) { + event = event.originalEvent || event; + + var strPage = 'page'; + var strClient = 'client'; + var strX = 'X'; + var strY = 'Y'; + var target = event.target || event.srcElement || document; + var eventDoc = target.ownerDocument || document; + var doc = eventDoc.documentElement; + var body = eventDoc.body; + + //if touch event return return pageX/Y of it + if (event.touches !== undefined) { + var touch = event.touches[0]; + return { + x: touch[strPage + strX], + y: touch[strPage + strY] + } + } + + // Calculate pageX/Y if not native supported + if (!event[strPage + strX] && event[strClient + strX] && event[strClient + strX] != null) { + + return { + x: event[strClient + strX] + + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - + (doc && doc.clientLeft || body && body.clientLeft || 0), + y: event[strClient + strY] + + (doc && doc.scrollTop || body && body.scrollTop || 0) - + (doc && doc.clientTop || body && body.clientTop || 0) + } + } + return { + x: event[strPage + strX], + y: event[strPage + strY] + }; + }, + + /** + * Gets the clicked mouse button of the given mouse event. + * @param event The mouse event of which the clicked button shal be got. + * @returns {number} The number of the clicked mouse button. (0 : none | 1 : leftButton | 2 : middleButton | 3 : rightButton) + */ + mBtn: function (event) { + var button = event.button; + if (!event.which && button !== undefined) + return (button & 1 ? 1 : (button & 2 ? 3 : (button & 4 ? 2 : 0))); + else + return event.which; + }, + + /** + * Checks whether a item is in the given array and returns its index. + * @param item The item of which the position in the array shall be determined. + * @param arr The array. + * @returns {number} The zero based index of the item or -1 if the item isn't in the array. + */ + inA: function (item, arr) { + for (var i = 0; i < arr[LEXICON.l]; i++) + //Sometiems in IE a "SCRIPT70" Permission denied error occurs if HTML elements in a iFrame are compared + try { + if (arr[i] === item) + return i; + } + catch (e) { } + return -1; + }, + + /** + * Returns true if the given value is a array. + * @param arr The potential array. + * @returns {boolean} True if the given value is a array, false otherwise. + */ + isA: function (arr) { + var def = Array.isArray; + return def ? def(arr) : this.type(arr) == TYPES.a; + }, + + /** + * Determine the internal JavaScript [[Class]] of the given object. + * @param obj The object of which the type shall be determined. + * @returns {string} The type of the given object. + */ + type: function (obj) { + if (obj === undefined) + return obj + ''; + if (obj === null) + return obj + ''; + return Object[LEXICON.p].toString.call(obj).replace(/^\[object (.+)\]$/, '$1').toLowerCase(); + }, + + + bind: bind + + /** + * Gets the vendor-prefixed CSS property by the given name. + * For example the given name is "transform" and you're using a old Firefox browser then the returned value would be "-moz-transform". + * If the browser doesn't need a vendor-prefix, then the returned string is the given name. + * If the browser doesn't support the given property name at all (not even with a vendor-prefix) the returned value is null. + * @param propName The unprefixed CSS property name. + * @returns {string|null} The vendor-prefixed CSS property or null if the browser doesn't support the given CSS property. + + cssProp: function(propName) { + return VENDORS._cssProperty(propName); + } + */ + } + })(); + + var MATH = Math; + var JQUERY = window.jQuery; + var EASING = (function () { + var _easingsMath = { + p: MATH.PI, + c: MATH.cos, + s: MATH.sin, + w: MATH.pow, + t: MATH.sqrt, + n: MATH.asin, + a: MATH.abs, + o: 1.70158 + }; + + /* + x : current percent (0 - 1), + t : current time (duration * percent), + b : start value (from), + c : end value (to), + d : duration + + easingName : function(x, t, b, c, d) { return easedValue; } + */ + + return { + swing: function (x, t, b, c, d) { + return 0.5 - _easingsMath.c(x * _easingsMath.p) / 2; + }, + linear: function (x, t, b, c, d) { + return x; + }, + easeInQuad: function (x, t, b, c, d) { + return c * (t /= d) * t + b; + }, + easeOutQuad: function (x, t, b, c, d) { + return -c * (t /= d) * (t - 2) + b; + }, + easeInOutQuad: function (x, t, b, c, d) { + return ((t /= d / 2) < 1) ? c / 2 * t * t + b : -c / 2 * ((--t) * (t - 2) - 1) + b; + }, + easeInCubic: function (x, t, b, c, d) { + return c * (t /= d) * t * t + b; + }, + easeOutCubic: function (x, t, b, c, d) { + return c * ((t = t / d - 1) * t * t + 1) + b; + }, + easeInOutCubic: function (x, t, b, c, d) { + return ((t /= d / 2) < 1) ? c / 2 * t * t * t + b : c / 2 * ((t -= 2) * t * t + 2) + b; + }, + easeInQuart: function (x, t, b, c, d) { + return c * (t /= d) * t * t * t + b; + }, + easeOutQuart: function (x, t, b, c, d) { + return -c * ((t = t / d - 1) * t * t * t - 1) + b; + }, + easeInOutQuart: function (x, t, b, c, d) { + return ((t /= d / 2) < 1) ? c / 2 * t * t * t * t + b : -c / 2 * ((t -= 2) * t * t * t - 2) + b; + }, + easeInQuint: function (x, t, b, c, d) { + return c * (t /= d) * t * t * t * t + b; + }, + easeOutQuint: function (x, t, b, c, d) { + return c * ((t = t / d - 1) * t * t * t * t + 1) + b; + }, + easeInOutQuint: function (x, t, b, c, d) { + return ((t /= d / 2) < 1) ? c / 2 * t * t * t * t * t + b : c / 2 * ((t -= 2) * t * t * t * t + 2) + b; + }, + easeInSine: function (x, t, b, c, d) { + return -c * _easingsMath.c(t / d * (_easingsMath.p / 2)) + c + b; + }, + easeOutSine: function (x, t, b, c, d) { + return c * _easingsMath.s(t / d * (_easingsMath.p / 2)) + b; + }, + easeInOutSine: function (x, t, b, c, d) { + return -c / 2 * (_easingsMath.c(_easingsMath.p * t / d) - 1) + b; + }, + easeInExpo: function (x, t, b, c, d) { + return (t == 0) ? b : c * _easingsMath.w(2, 10 * (t / d - 1)) + b; + }, + easeOutExpo: function (x, t, b, c, d) { + return (t == d) ? b + c : c * (-_easingsMath.w(2, -10 * t / d) + 1) + b; + }, + easeInOutExpo: function (x, t, b, c, d) { + if (t == 0) return b; + if (t == d) return b + c; + if ((t /= d / 2) < 1) return c / 2 * _easingsMath.w(2, 10 * (t - 1)) + b; + return c / 2 * (-_easingsMath.w(2, -10 * --t) + 2) + b; + }, + easeInCirc: function (x, t, b, c, d) { + return -c * (_easingsMath.t(1 - (t /= d) * t) - 1) + b; + }, + easeOutCirc: function (x, t, b, c, d) { + return c * _easingsMath.t(1 - (t = t / d - 1) * t) + b; + }, + easeInOutCirc: function (x, t, b, c, d) { + return ((t /= d / 2) < 1) ? -c / 2 * (_easingsMath.t(1 - t * t) - 1) + b : c / 2 * (_easingsMath.t(1 - (t -= 2) * t) + 1) + b; + }, + easeInElastic: function (x, t, b, c, d) { + var s = _easingsMath.o; var p = 0; var a = c; + if (t == 0) return b; if ((t /= d) == 1) return b + c; if (!p) p = d * .3; + if (a < _easingsMath.a(c)) { a = c; s = p / 4; } + else s = p / (2 * _easingsMath.p) * _easingsMath.n(c / a); + return -(a * _easingsMath.w(2, 10 * (t -= 1)) * _easingsMath.s((t * d - s) * (2 * _easingsMath.p) / p)) + b; + }, + easeOutElastic: function (x, t, b, c, d) { + var s = _easingsMath.o; var p = 0; var a = c; + if (t == 0) return b; + if ((t /= d) == 1) return b + c; + if (!p) p = d * .3; + if (a < _easingsMath.a(c)) { a = c; s = p / 4; } + else s = p / (2 * _easingsMath.p) * _easingsMath.n(c / a); + return a * _easingsMath.w(2, -10 * t) * _easingsMath.s((t * d - s) * (2 * _easingsMath.p) / p) + c + b; + }, + easeInOutElastic: function (x, t, b, c, d) { + var s = _easingsMath.o; var p = 0; var a = c; + if (t == 0) return b; + if ((t /= d / 2) == 2) return b + c; + if (!p) p = d * (.3 * 1.5); + if (a < _easingsMath.a(c)) { a = c; s = p / 4; } + else s = p / (2 * _easingsMath.p) * _easingsMath.n(c / a); + if (t < 1) return -.5 * (a * _easingsMath.w(2, 10 * (t -= 1)) * _easingsMath.s((t * d - s) * (2 * _easingsMath.p) / p)) + b; + return a * _easingsMath.w(2, -10 * (t -= 1)) * _easingsMath.s((t * d - s) * (2 * _easingsMath.p) / p) * .5 + c + b; + }, + easeInBack: function (x, t, b, c, d, s) { + s = s || _easingsMath.o; + return c * (t /= d) * t * ((s + 1) * t - s) + b; + }, + easeOutBack: function (x, t, b, c, d, s) { + s = s || _easingsMath.o; + return c * ((t = t / d - 1) * t * ((s + 1) * t + s) + 1) + b; + }, + easeInOutBack: function (x, t, b, c, d, s) { + s = s || _easingsMath.o; + return ((t /= d / 2) < 1) ? c / 2 * (t * t * (((s *= (1.525)) + 1) * t - s)) + b : c / 2 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2) + b; + }, + easeInBounce: function (x, t, b, c, d) { + return c - this.easeOutBounce(x, d - t, 0, c, d) + b; + }, + easeOutBounce: function (x, t, b, c, d) { + var o = 7.5625; + if ((t /= d) < (1 / 2.75)) { + return c * (o * t * t) + b; + } else if (t < (2 / 2.75)) { + return c * (o * (t -= (1.5 / 2.75)) * t + .75) + b; + } else if (t < (2.5 / 2.75)) { + return c * (o * (t -= (2.25 / 2.75)) * t + .9375) + b; + } else { + return c * (o * (t -= (2.625 / 2.75)) * t + .984375) + b; + } + }, + easeInOutBounce: function (x, t, b, c, d) { + return (t < d / 2) ? this.easeInBounce(x, t * 2, 0, c, d) * .5 + b : this.easeOutBounce(x, t * 2 - d, 0, c, d) * .5 + c * .5 + b; + } + }; + /* + * + * TERMS OF USE - EASING EQUATIONS + * + * Open source under the BSD License. + * + * Copyright © 2001 Robert Penner + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the author nor the names of contributors may be used to endorse + * or promote products derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + })(); + var FRAMEWORK = (function () { + var _rnothtmlwhite = (/[^\x20\t\r\n\f]+/g); + var _strSpace = ' '; + var _strEmpty = ''; + var _strScrollLeft = 'scrollLeft'; + var _strScrollTop = 'scrollTop'; + var _animations = []; + var _type = COMPATIBILITY.type; + var _cssNumber = { + animationIterationCount: true, + columnCount: true, + fillOpacity: true, + flexGrow: true, + flexShrink: true, + fontWeight: true, + lineHeight: true, + opacity: true, + order: true, + orphans: true, + widows: true, + zIndex: true, + zoom: true + }; + + function extend() { + var src, copyIsArray, copy, name, options, clone, target = arguments[0] || {}, + i = 1, + length = arguments[LEXICON.l], + deep = false; + + // Handle a deep copy situation + if (_type(target) == TYPES.b) { + deep = target; + target = arguments[1] || {}; + // skip the boolean and the target + i = 2; + } + + // Handle case when target is a string or something (possible in deep copy) + if (_type(target) != TYPES.o && !_type(target) == TYPES.f) { + target = {}; + } + + // extend jQuery itself if only one argument is passed + if (length === i) { + target = FakejQuery; + --i; + } + + for (; i < length; i++) { + // Only deal with non-null/undefined values + if ((options = arguments[i]) != null) { + // Extend the base object + for (name in options) { + src = target[name]; + copy = options[name]; + + // Prevent never-ending loop + if (target === copy) { + continue; + } + + // Recurse if we're merging plain objects or arrays + if (deep && copy && (isPlainObject(copy) || (copyIsArray = COMPATIBILITY.isA(copy)))) { + if (copyIsArray) { + copyIsArray = false; + clone = src && COMPATIBILITY.isA(src) ? src : []; + + } else { + clone = src && isPlainObject(src) ? src : {}; + } + + // Never move original objects, clone them + target[name] = extend(deep, clone, copy); + + // Don't bring in undefined values + } else if (copy !== undefined) { + target[name] = copy; + } + } + } + } + + // Return the modified object + return target; + }; + + function inArray(item, arr, fromIndex) { + for (var i = fromIndex || 0; i < arr[LEXICON.l]; i++) + if (arr[i] === item) + return i; + return -1; + } + + function isFunction(obj) { + return _type(obj) == TYPES.f; + }; + + function isEmptyObject(obj) { + for (var name in obj) + return false; + return true; + }; + + function isPlainObject(obj) { + if (!obj || _type(obj) != TYPES.o) + return false; + + var key; + var proto = LEXICON.p; + var hasOwnProperty = Object[proto].hasOwnProperty; + var hasOwnConstructor = hasOwnProperty.call(obj, 'constructor'); + var hasIsPrototypeOf = obj.constructor && obj.constructor[proto] && hasOwnProperty.call(obj.constructor[proto], 'isPrototypeOf'); + + if (obj.constructor && !hasOwnConstructor && !hasIsPrototypeOf) { + return false; + } + + + for (key in obj) { /**/ } + + return _type(key) == TYPES.u || hasOwnProperty.call(obj, key); + }; + + function each(obj, callback) { + var i = 0; + + if (isArrayLike(obj)) { + for (; i < obj[LEXICON.l]; i++) { + if (callback.call(obj[i], i, obj[i]) === false) + break; + } + } + else { + for (i in obj) { + if (callback.call(obj[i], i, obj[i]) === false) + break; + } + } + + return obj; + }; + + function isArrayLike(obj) { + var length = !!obj && [LEXICON.l] in obj && obj[LEXICON.l]; + var t = _type(obj); + return isFunction(t) ? false : (t == TYPES.a || length === 0 || _type(length) == TYPES.n && length > 0 && (length - 1) in obj); + } + + function stripAndCollapse(value) { + var tokens = value.match(_rnothtmlwhite) || []; + return tokens.join(_strSpace); + } + + function matches(elem, selector) { + var nodeList = (elem.parentNode || document).querySelectorAll(selector) || []; + var i = nodeList[LEXICON.l]; + + while (i--) + if (nodeList[i] == elem) + return true; + + return false; + } + + function insertAdjacentElement(el, strategy, child) { + if (_type(child) == TYPES.a) { + for (var i = 0; i < child[LEXICON.l]; i++) + insertAdjacentElement(el, strategy, child[i]); + } + else if (_type(child) == TYPES.s) + el.insertAdjacentHTML(strategy, child); + else + el.insertAdjacentElement(strategy, child.nodeType ? child : child[0]); + } + + function setCSSVal(el, prop, val) { + try { + if (el[LEXICON.s][prop] !== undefined) + el[LEXICON.s][prop] = parseCSSVal(prop, val); + } catch (e) { } + } + + function parseCSSVal(prop, val) { + if (!_cssNumber[prop.toLowerCase()] && _type(val) == TYPES.n) + val += 'px'; + return val; + } + + function startNextAnimationInQ(animObj, removeFromQ) { + var index; + var nextAnim; + if (removeFromQ !== false) + animObj.q.splice(0, 1); + if (animObj.q[LEXICON.l] > 0) { + nextAnim = animObj.q[0]; + animate(animObj.el, nextAnim.props, nextAnim.duration, nextAnim.easing, nextAnim.complete, true); + } + else { + index = inArray(animObj, _animations); + if (index > -1) + _animations.splice(index, 1); + } + } + + function setAnimationValue(el, prop, value) { + if (prop === _strScrollLeft || prop === _strScrollTop) + el[prop] = value; + else + setCSSVal(el, prop, value); + } + + function animate(el, props, options, easing, complete, guaranteedNext) { + var hasOptions = isPlainObject(options); + var from = {}; + var to = {}; + var i = 0; + var key; + var animObj; + var start; + var progress; + var step; + var specialEasing; + var duration; + if (hasOptions) { + easing = options.easing; + start = options.start; + progress = options.progress; + step = options.step; + specialEasing = options.specialEasing; + complete = options.complete; + duration = options.duration; + } + else + duration = options; + specialEasing = specialEasing || {}; + duration = duration || 400; + easing = easing || 'swing'; + guaranteedNext = guaranteedNext || false; + + for (; i < _animations[LEXICON.l]; i++) { + if (_animations[i].el === el) { + animObj = _animations[i]; + break; + } + } + + if (!animObj) { + animObj = { + el: el, + q: [] + }; + _animations.push(animObj); + } + + for (key in props) { + if (key === _strScrollLeft || key === _strScrollTop) + from[key] = el[key]; + else + from[key] = FakejQuery(el).css(key); + } + + for (key in from) { + if (from[key] !== props[key] && props[key] !== undefined) + to[key] = props[key]; + } + + if (!isEmptyObject(to)) { + var timeNow; + var end; + var percent; + var fromVal; + var toVal; + var easedVal; + var timeStart; + var frame; + var elapsed; + var qPos = guaranteedNext ? 0 : inArray(qObj, animObj.q); + var qObj = { + props: to, + duration: hasOptions ? options : duration, + easing: easing, + complete: complete + }; + if (qPos === -1) { + qPos = animObj.q[LEXICON.l]; + animObj.q.push(qObj); + } + + if (qPos === 0) { + if (duration > 0) { + timeStart = COMPATIBILITY.now(); + frame = function () { + timeNow = COMPATIBILITY.now(); + elapsed = (timeNow - timeStart); + end = qObj.stop || elapsed >= duration; + percent = 1 - ((MATH.max(0, timeStart + duration - timeNow) / duration) || 0); + + for (key in to) { + fromVal = parseFloat(from[key]); + toVal = parseFloat(to[key]); + easedVal = (toVal - fromVal) * EASING[specialEasing[key] || easing](percent, percent * duration, 0, 1, duration) + fromVal; + setAnimationValue(el, key, easedVal); + if (isFunction(step)) { + step(easedVal, { + elem: el, + prop: key, + start: fromVal, + now: easedVal, + end: toVal, + pos: percent, + options: { + easing: easing, + speacialEasing: specialEasing, + duration: duration, + complete: complete, + step: step + }, + startTime: timeStart + }); + } + } + + if (isFunction(progress)) + progress({}, percent, MATH.max(0, duration - elapsed)); + + if (end) { + startNextAnimationInQ(animObj); + if (isFunction(complete)) + complete(); + } + else + qObj.frame = COMPATIBILITY.rAF()(frame); + }; + qObj.frame = COMPATIBILITY.rAF()(frame); + } + else { + for (key in to) + setAnimationValue(el, key, to[key]); + startNextAnimationInQ(animObj); + } + } + } + else if (guaranteedNext) + startNextAnimationInQ(animObj); + } + + function stop(el, clearQ, jumpToEnd) { + var animObj; + var qObj; + var key; + var i = 0; + for (; i < _animations[LEXICON.l]; i++) { + animObj = _animations[i]; + if (animObj.el === el) { + if (animObj.q[LEXICON.l] > 0) { + qObj = animObj.q[0]; + qObj.stop = true; + COMPATIBILITY.cAF()(qObj.frame); + animObj.q.splice(0, 1); + + if (jumpToEnd) + for (key in qObj.props) + setAnimationValue(el, key, qObj.props[key]); + + if (clearQ) + animObj.q = []; + else + startNextAnimationInQ(animObj, false); + } + break; + } + } + } + + function elementIsVisible(el) { + return !!(el[LEXICON.oW] || el[LEXICON.oH] || el.getClientRects()[LEXICON.l]); + } + + function FakejQuery(selector) { + if (arguments[LEXICON.l] === 0) + return this; + + var base = new FakejQuery(); + var elements = selector; + var i = 0; + var elms; + var el; + + if (_type(selector) == TYPES.s) { + elements = []; + if (selector.charAt(0) === '<') { + el = document.createElement('div'); + el.innerHTML = selector; + elms = el.children; + } + else { + elms = document.querySelectorAll(selector); + } + + for (; i < elms[LEXICON.l]; i++) + elements.push(elms[i]); + } + + if (elements) { + if (_type(elements) != TYPES.s && (!isArrayLike(elements) || elements === window || elements === elements.self)) + elements = [elements]; + + for (i = 0; i < elements[LEXICON.l]; i++) + base[i] = elements[i]; + + base[LEXICON.l] = elements[LEXICON.l]; + } + + return base; + }; + + FakejQuery[LEXICON.p] = { + + //EVENTS: + + on: function (eventName, handler) { + eventName = (eventName || _strEmpty).match(_rnothtmlwhite) || [_strEmpty]; + + var eventNameLength = eventName[LEXICON.l]; + var i = 0; + var el; + return this.each(function () { + el = this; + try { + if (el.addEventListener) { + for (; i < eventNameLength; i++) + el.addEventListener(eventName[i], handler); + } + else if (el.detachEvent) { + for (; i < eventNameLength; i++) + el.attachEvent('on' + eventName[i], handler); + } + } catch (e) { } + }); + }, + + off: function (eventName, handler) { + eventName = (eventName || _strEmpty).match(_rnothtmlwhite) || [_strEmpty]; + + var eventNameLength = eventName[LEXICON.l]; + var i = 0; + var el; + return this.each(function () { + el = this; + try { + if (el.removeEventListener) { + for (; i < eventNameLength; i++) + el.removeEventListener(eventName[i], handler); + } + else if (el.detachEvent) { + for (; i < eventNameLength; i++) + el.detachEvent('on' + eventName[i], handler); + } + } catch (e) { } + }); + }, + + one: function (eventName, handler) { + eventName = (eventName || _strEmpty).match(_rnothtmlwhite) || [_strEmpty]; + return this.each(function () { + var el = FakejQuery(this); + FakejQuery.each(eventName, function (i, oneEventName) { + var oneHandler = function (e) { + handler.call(this, e); + el.off(oneEventName, oneHandler); + }; + el.on(oneEventName, oneHandler); + }); + }); + }, + + trigger: function (eventName) { + var el; + var event; + return this.each(function () { + el = this; + if (document.createEvent) { + event = document.createEvent('HTMLEvents'); + event.initEvent(eventName, true, false); + el.dispatchEvent(event); + } + else { + el.fireEvent('on' + eventName); + } + }); + }, + + //DOM NODE INSERTING / REMOVING: + + append: function (child) { + return this.each(function () { insertAdjacentElement(this, 'beforeend', child); }); + }, + + prepend: function (child) { + return this.each(function () { insertAdjacentElement(this, 'afterbegin', child); }); + }, + + before: function (child) { + return this.each(function () { insertAdjacentElement(this, 'beforebegin', child); }); + }, + + after: function (child) { + return this.each(function () { insertAdjacentElement(this, 'afterend', child); }); + }, + + remove: function () { + return this.each(function () { + var el = this; + var parentNode = el.parentNode; + if (parentNode != null) + parentNode.removeChild(el); + }); + }, + + unwrap: function () { + var parents = []; + var i; + var el; + var parent; + + this.each(function () { + parent = this.parentNode; + if (inArray(parent, parents) === - 1) + parents.push(parent); + }); + + for (i = 0; i < parents[LEXICON.l]; i++) { + el = parents[i]; + parent = el.parentNode; + while (el.firstChild) + parent.insertBefore(el.firstChild, el); + parent.removeChild(el); + } + + return this; + }, + + wrapAll: function (wrapperHTML) { + var i; + var nodes = this; + var wrapper = FakejQuery(wrapperHTML)[0]; + var deepest = wrapper; + var parent = nodes[0].parentNode; + var previousSibling = nodes[0].previousSibling; + while (deepest.childNodes[LEXICON.l] > 0) + deepest = deepest.childNodes[0]; + + for (i = 0; nodes[LEXICON.l] - i; deepest.firstChild === nodes[0] && i++) + deepest.appendChild(nodes[i]); + + var nextSibling = previousSibling ? previousSibling.nextSibling : parent.firstChild; + parent.insertBefore(wrapper, nextSibling); + + return this; + }, + + wrapInner: function (wrapperHTML) { + return this.each(function () { + var el = FakejQuery(this); + var contents = el.contents(); + + if (contents[LEXICON.l]) + contents.wrapAll(wrapperHTML); + else + el.append(wrapperHTML); + }); + }, + + wrap: function (wrapperHTML) { + return this.each(function () { FakejQuery(this).wrapAll(wrapperHTML); }); + }, + + + //DOM NODE MANIPULATION / INFORMATION: + + css: function (styles, val) { + var el; + var key; + var cptStyle; + var getCptStyle = window.getComputedStyle; + if (_type(styles) == TYPES.s) { + if (val === undefined) { + el = this[0]; + cptStyle = getCptStyle ? getCptStyle(el, null) : el.currentStyle[styles]; + + //https://bugzilla.mozilla.org/show_bug.cgi?id=548397 can be null sometimes if iframe with display: none (firefox only!) + return getCptStyle ? cptStyle != null ? cptStyle.getPropertyValue(styles) : el[LEXICON.s][styles] : cptStyle; + } + else { + return this.each(function () { + setCSSVal(this, styles, val); + }); + } + } + else { + return this.each(function () { + for (key in styles) + setCSSVal(this, key, styles[key]); + }); + } + }, + + hasClass: function (className) { + var elem, i = 0; + var classNamePrepared = _strSpace + className + _strSpace; + var classList; + + while ((elem = this[i++])) { + classList = elem.classList; + if (classList && classList.contains(className)) + return true; + else if (elem.nodeType === 1 && (_strSpace + stripAndCollapse(elem.className + _strEmpty) + _strSpace).indexOf(classNamePrepared) > -1) + return true; + } + + return false; + }, + + addClass: function (className) { + var classes; + var elem; + var cur; + var curValue; + var clazz; + var finalValue; + var supportClassList; + var elmClassList; + var i = 0; + var v = 0; + + if (className) { + classes = className.match(_rnothtmlwhite) || []; + + while ((elem = this[i++])) { + elmClassList = elem.classList; + if (supportClassList === undefined) + supportClassList = elmClassList !== undefined; + + if (supportClassList) { + while ((clazz = classes[v++])) + elmClassList.add(clazz); + } + else { + curValue = elem.className + _strEmpty; + cur = elem.nodeType === 1 && (_strSpace + stripAndCollapse(curValue) + _strSpace); + + if (cur) { + while ((clazz = classes[v++])) + if (cur.indexOf(_strSpace + clazz + _strSpace) < 0) + cur += clazz + _strSpace; + + finalValue = stripAndCollapse(cur); + if (curValue !== finalValue) + elem.className = finalValue; + } + } + } + } + + return this; + }, + + removeClass: function (className) { + var classes; + var elem; + var cur; + var curValue; + var clazz; + var finalValue; + var supportClassList; + var elmClassList; + var i = 0; + var v = 0; + + if (className) { + classes = className.match(_rnothtmlwhite) || []; + + while ((elem = this[i++])) { + elmClassList = elem.classList; + if (supportClassList === undefined) + supportClassList = elmClassList !== undefined; + + if (supportClassList) { + while ((clazz = classes[v++])) + elmClassList.remove(clazz); + } + else { + curValue = elem.className + _strEmpty; + cur = elem.nodeType === 1 && (_strSpace + stripAndCollapse(curValue) + _strSpace); + + if (cur) { + while ((clazz = classes[v++])) + while (cur.indexOf(_strSpace + clazz + _strSpace) > -1) + cur = cur.replace(_strSpace + clazz + _strSpace, _strSpace); + + finalValue = stripAndCollapse(cur); + if (curValue !== finalValue) + elem.className = finalValue; + } + } + } + } + + return this; + }, + + hide: function () { + return this.each(function () { this[LEXICON.s].display = 'none'; }); + }, + + show: function () { + return this.each(function () { this[LEXICON.s].display = 'block'; }); + }, + + attr: function (attrName, value) { + var i = 0; + var el; + while (el = this[i++]) { + if (value === undefined) + return el.getAttribute(attrName); + el.setAttribute(attrName, value); + } + return this; + }, + + removeAttr: function (attrName) { + return this.each(function () { this.removeAttribute(attrName); }); + }, + + offset: function () { + var el = this[0]; + var rect = el[LEXICON.bCR](); + var scrollLeft = window.pageXOffset || document.documentElement[_strScrollLeft]; + var scrollTop = window.pageYOffset || document.documentElement[_strScrollTop]; + return { + top: rect.top + scrollTop, + left: rect.left + scrollLeft + }; + }, + + position: function () { + var el = this[0]; + return { + top: el.offsetTop, + left: el.offsetLeft + }; + }, + + scrollLeft: function (value) { + var i = 0; + var el; + while (el = this[i++]) { + if (value === undefined) + return el[_strScrollLeft]; + el[_strScrollLeft] = value; + } + return this; + }, + + scrollTop: function (value) { + var i = 0; + var el; + while (el = this[i++]) { + if (value === undefined) + return el[_strScrollTop]; + el[_strScrollTop] = value; + } + return this; + }, + + val: function (value) { + var el = this[0]; + if (!value) + return el.value; + el.value = value; + return this; + }, + + + //DOM TRAVERSAL / FILTERING: + + first: function () { + return this.eq(0); + }, + + last: function () { + return this.eq(-1); + }, + + eq: function (index) { + return FakejQuery(this[index >= 0 ? index : this[LEXICON.l] + index]); + }, + + find: function (selector) { + var children = []; + var i; + this.each(function () { + var el = this; + var ch = el.querySelectorAll(selector); + for (i = 0; i < ch[LEXICON.l]; i++) + children.push(ch[i]); + }); + return FakejQuery(children); + }, + + children: function (selector) { + var children = []; + var el; + var ch; + var i; + + this.each(function () { + ch = this.children; + for (i = 0; i < ch[LEXICON.l]; i++) { + el = ch[i]; + if (selector) { + if ((el.matches && el.matches(selector)) || matches(el, selector)) + children.push(el); + } + else + children.push(el); + } + }); + return FakejQuery(children); + }, + + parent: function (selector) { + var parents = []; + var parent; + this.each(function () { + parent = this.parentNode; + if (selector ? FakejQuery(parent).is(selector) : true) + parents.push(parent); + }); + return FakejQuery(parents); + }, + + is: function (selector) { + + var el; + var i; + for (i = 0; i < this[LEXICON.l]; i++) { + el = this[i]; + if (selector === ':visible') + return elementIsVisible(el); + if (selector === ':hidden') + return !elementIsVisible(el); + if ((el.matches && el.matches(selector)) || matches(el, selector)) + return true; + } + return false; + }, + + contents: function () { + var contents = []; + var childs; + var i; + + this.each(function () { + childs = this.childNodes; + for (i = 0; i < childs[LEXICON.l]; i++) + contents.push(childs[i]); + }); + + return FakejQuery(contents); + }, + + each: function (callback) { + return each(this, callback); + }, + + + //ANIMATION: + + animate: function (props, duration, easing, complete) { + return this.each(function () { animate(this, props, duration, easing, complete); }); + }, + + stop: function (clearQ, jump) { + return this.each(function () { stop(this, clearQ, jump); }); + } + }; + + extend(FakejQuery, { + extend: extend, + inArray: inArray, + isEmptyObject: isEmptyObject, + isPlainObject: isPlainObject, + each: each + }); + + return FakejQuery; + })(); + var INSTANCES = (function () { + var _targets = []; + var _instancePropertyString = '__overlayScrollbars__'; + + /** + * Register, unregister or get a certain (or all) instances. + * Register: Pass the target and the instance. + * Unregister: Pass the target and null. + * Get Instance: Pass the target from which the instance shall be got. + * Get Targets: Pass no arguments. + * @param target The target to which the instance shall be registered / from which the instance shall be unregistered / the instance shall be got + * @param instance The instance. + * @returns {*|void} Returns the instance from the given target. + */ + return function (target, instance) { + var argLen = arguments[LEXICON.l]; + if (argLen < 1) { + //return all targets + return _targets; + } + else { + if (instance) { + //register instance + target[_instancePropertyString] = instance; + _targets.push(target); + } + else { + var index = COMPATIBILITY.inA(target, _targets); + if (index > -1) { + if (argLen > 1) { + //unregister instance + delete target[_instancePropertyString]; + _targets.splice(index, 1); + } + else { + //get instance from target + return _targets[index][_instancePropertyString]; + } + } + } + } + } + })(); + var PLUGIN = (function () { + var _plugin; + var _pluginsGlobals; + var _pluginsAutoUpdateLoop; + var _pluginsExtensions = []; + var _pluginsOptions = (function () { + var type = COMPATIBILITY.type; + var possibleTemplateTypes = [ + TYPES.b, //boolean + TYPES.n, //number + TYPES.s, //string + TYPES.a, //array + TYPES.o, //object + TYPES.f, //function + TYPES.z //null + ]; + var restrictedStringsSplit = ' '; + var restrictedStringsPossibilitiesSplit = ':'; + var classNameAllowedValues = [TYPES.z, TYPES.s]; + var numberAllowedValues = TYPES.n; + var booleanNullAllowedValues = [TYPES.z, TYPES.b]; + var booleanTrueTemplate = [true, TYPES.b]; + var booleanFalseTemplate = [false, TYPES.b]; + var callbackTemplate = [null, [TYPES.z, TYPES.f]]; + var inheritedAttrsTemplate = [['style', 'class'], [TYPES.s, TYPES.a, TYPES.z]]; + var resizeAllowedValues = 'n:none b:both h:horizontal v:vertical'; + var overflowBehaviorAllowedValues = 'v-h:visible-hidden v-s:visible-scroll s:scroll h:hidden'; + var scrollbarsVisibilityAllowedValues = 'v:visible h:hidden a:auto'; + var scrollbarsAutoHideAllowedValues = 'n:never s:scroll l:leave m:move'; + var optionsDefaultsAndTemplate = { + className: ['os-theme-dark', classNameAllowedValues], //null || string + resize: ['none', resizeAllowedValues], //none || both || horizontal || vertical || n || b || h || v + sizeAutoCapable: booleanTrueTemplate, //true || false + clipAlways: booleanTrueTemplate, //true || false + normalizeRTL: booleanTrueTemplate, //true || false + paddingAbsolute: booleanFalseTemplate, //true || false + autoUpdate: [null, booleanNullAllowedValues], //true || false || null + autoUpdateInterval: [33, numberAllowedValues], //number + nativeScrollbarsOverlaid: { + showNativeScrollbars: booleanFalseTemplate, //true || false + initialize: booleanTrueTemplate //true || false + }, + overflowBehavior: { + x: ['scroll', overflowBehaviorAllowedValues], //visible-hidden || visible-scroll || hidden || scroll || v-h || v-s || h || s + y: ['scroll', overflowBehaviorAllowedValues] //visible-hidden || visible-scroll || hidden || scroll || v-h || v-s || h || s + }, + scrollbars: { + visibility: ['auto', scrollbarsVisibilityAllowedValues], //visible || hidden || auto || v || h || a + autoHide: ['never', scrollbarsAutoHideAllowedValues], //never || scroll || leave || move || n || s || l || m + autoHideDelay: [800, numberAllowedValues], //number + dragScrolling: booleanTrueTemplate, //true || false + clickScrolling: booleanFalseTemplate, //true || false + touchSupport: booleanTrueTemplate, //true || false + snapHandle: booleanFalseTemplate //true || false + }, + textarea: { + dynWidth: booleanFalseTemplate, //true || false + dynHeight: booleanFalseTemplate, //true || false + inheritedAttrs: inheritedAttrsTemplate //string || array || null + }, + callbacks: { + onInitialized: callbackTemplate, //null || function + onInitializationWithdrawn: callbackTemplate, //null || function + onDestroyed: callbackTemplate, //null || function + onScrollStart: callbackTemplate, //null || function + onScroll: callbackTemplate, //null || function + onScrollStop: callbackTemplate, //null || function + onOverflowChanged: callbackTemplate, //null || function + onOverflowAmountChanged: callbackTemplate, //null || function + onDirectionChanged: callbackTemplate, //null || function + onContentSizeChanged: callbackTemplate, //null || function + onHostSizeChanged: callbackTemplate, //null || function + onUpdated: callbackTemplate //null || function + } + }; + var convert = function (template) { + var recursive = function (obj) { + var key; + var val; + var valType; + for (key in obj) { + if (!obj[LEXICON.hOP](key)) + continue; + val = obj[key]; + valType = type(val); + if (valType == TYPES.a) + obj[key] = val[template ? 1 : 0]; + else if (valType == TYPES.o) + obj[key] = recursive(val); + } + return obj; + }; + return recursive(FRAMEWORK.extend(true, {}, optionsDefaultsAndTemplate)); + }; + + return { + _defaults: convert(), + + _template: convert(true), + + /** + * Validates the passed object by the passed template. + * @param obj The object which shall be validated. + * @param template The template which defines the allowed values and types. + * @param writeErrors True if errors shall be logged to the console. + * @param diffObj If a object is passed then only valid differences to this object will be returned. + * @returns {{}} A object which contains two objects called "default" and "prepared" which contains only the valid properties of the passed original object and discards not different values compared to the passed diffObj. + */ + _validate: function (obj, template, writeErrors, diffObj) { + var validatedOptions = {}; + var validatedOptionsPrepared = {}; + var objectCopy = FRAMEWORK.extend(true, {}, obj); + var inArray = FRAMEWORK.inArray; + var isEmptyObj = FRAMEWORK.isEmptyObject; + var checkObjectProps = function (data, template, diffData, validatedOptions, validatedOptionsPrepared, prevPropName) { + for (var prop in template) { + if (template[LEXICON.hOP](prop) && data[LEXICON.hOP](prop)) { + var isValid = false; + var isDiff = false; + var templateValue = template[prop]; + var templateValueType = type(templateValue); + var templateIsComplex = templateValueType == TYPES.o; + var templateTypes = type(templateValue) != TYPES.a ? [templateValue] : templateValue; + var dataDiffValue = diffData[prop]; + var dataValue = data[prop]; + var dataValueType = type(dataValue); + var propPrefix = prevPropName ? prevPropName + '.' : ''; + var error = "The option \"" + propPrefix + prop + "\" wasn't set, because"; + var errorPossibleTypes = []; + var errorRestrictedStrings = []; + var restrictedStringValuesSplit; + var restrictedStringValuesPossibilitiesSplit; + var isRestrictedValue; + var mainPossibility; + var currType; + var i; + var v; + var j; + + dataDiffValue = dataDiffValue === undefined ? {} : dataDiffValue; + + //if the template has a object as value, it means that the options are complex (verschachtelt) + if (templateIsComplex && dataValueType == TYPES.o) { + validatedOptions[prop] = {}; + validatedOptionsPrepared[prop] = {}; + checkObjectProps(dataValue, templateValue, dataDiffValue, validatedOptions[prop], validatedOptionsPrepared[prop], propPrefix + prop); + FRAMEWORK.each([data, validatedOptions, validatedOptionsPrepared], function (index, value) { + if (isEmptyObj(value[prop])) { + delete value[prop]; + } + }); + } + else if (!templateIsComplex) { + for (i = 0; i < templateTypes[LEXICON.l]; i++) { + currType = templateTypes[i]; + templateValueType = type(currType); + //if currtype is string and starts with restrictedStringPrefix and end with restrictedStringSuffix + isRestrictedValue = templateValueType == TYPES.s && inArray(currType, possibleTemplateTypes) === -1; + if (isRestrictedValue) { + errorPossibleTypes.push(TYPES.s); + + //split it into a array which contains all possible values for example: ["y:yes", "n:no", "m:maybe"] + restrictedStringValuesSplit = currType.split(restrictedStringsSplit); + errorRestrictedStrings = errorRestrictedStrings.concat(restrictedStringValuesSplit); + for (v = 0; v < restrictedStringValuesSplit[LEXICON.l]; v++) { + //split the possible values into their possibiliteis for example: ["y", "yes"] -> the first is always the mainPossibility + restrictedStringValuesPossibilitiesSplit = restrictedStringValuesSplit[v].split(restrictedStringsPossibilitiesSplit); + mainPossibility = restrictedStringValuesPossibilitiesSplit[0]; + for (j = 0; j < restrictedStringValuesPossibilitiesSplit[LEXICON.l]; j++) { + //if any possibility matches with the dataValue, its valid + if (dataValue === restrictedStringValuesPossibilitiesSplit[j]) { + isValid = true; + break; + } + } + if (isValid) + break; + } + } + else { + errorPossibleTypes.push(currType); + + if (dataValueType === currType) { + isValid = true; + break; + } + } + } + + if (isValid) { + isDiff = dataValue !== dataDiffValue; + + if (isDiff) + validatedOptions[prop] = dataValue; + + if (isRestrictedValue ? inArray(dataDiffValue, restrictedStringValuesPossibilitiesSplit) < 0 : isDiff) + validatedOptionsPrepared[prop] = isRestrictedValue ? mainPossibility : dataValue; + } + else if (writeErrors) { + console.warn(error + " it doesn't accept the type [ " + dataValueType.toUpperCase() + " ] with the value of \"" + dataValue + "\".\r\n" + + "Accepted types are: [ " + errorPossibleTypes.join(', ').toUpperCase() + " ]." + + (errorRestrictedStrings[length] > 0 ? "\r\nValid strings are: [ " + errorRestrictedStrings.join(', ').split(restrictedStringsPossibilitiesSplit).join(', ') + " ]." : '')); + } + delete data[prop]; + } + } + } + }; + checkObjectProps(objectCopy, template, diffObj || {}, validatedOptions, validatedOptionsPrepared); + + //add values which aren't specified in the template to the finished validated object to prevent them from being discarded + /* + if(keepForeignProps) { + FRAMEWORK.extend(true, validatedOptions, objectCopy); + FRAMEWORK.extend(true, validatedOptionsPrepared, objectCopy); + } + */ + + if (!isEmptyObj(objectCopy) && writeErrors) + console.warn('The following options are discarded due to invalidity:\r\n' + window.JSON.stringify(objectCopy, null, 2)); + + return { + _default: validatedOptions, + _prepared: validatedOptionsPrepared + }; + } + } + }()); + + /** + * Initializes the object which contains global information about the plugin and each instance of it. + */ + function initOverlayScrollbarsStatics() { + if (!_pluginsGlobals) + _pluginsGlobals = new OverlayScrollbarsGlobals(_pluginsOptions._defaults); + if (!_pluginsAutoUpdateLoop) + _pluginsAutoUpdateLoop = new OverlayScrollbarsAutoUpdateLoop(_pluginsGlobals); + } + + /** + * The global object for the OverlayScrollbars objects. It contains resources which every OverlayScrollbars object needs. This object is initialized only once: if the first OverlayScrollbars object gets initialized. + * @param defaultOptions + * @constructor + */ + function OverlayScrollbarsGlobals(defaultOptions) { + var _base = this; + var strOverflow = 'overflow'; + var strHidden = 'hidden'; + var strScroll = 'scroll'; + var bodyElement = FRAMEWORK('body'); + var scrollbarDummyElement = FRAMEWORK('
'); + var scrollbarDummyElement0 = scrollbarDummyElement[0]; + var dummyContainerChild = FRAMEWORK(scrollbarDummyElement.children('div').eq(0)); + + bodyElement.append(scrollbarDummyElement); + scrollbarDummyElement.hide().show(); //fix IE8 bug (incorrect measuring) + + var nativeScrollbarSize = calcNativeScrollbarSize(scrollbarDummyElement0); + var nativeScrollbarIsOverlaid = { + x: nativeScrollbarSize.x === 0, + y: nativeScrollbarSize.y === 0 + }; + var msie = (function () { + var ua = window.navigator.userAgent; + var strIndexOf = 'indexOf'; + var strSubString = 'substring'; + var msie = ua[strIndexOf]('MSIE '); + var trident = ua[strIndexOf]('Trident/'); + var edge = ua[strIndexOf]('Edge/'); + var rv = ua[strIndexOf]('rv:'); + var result; + var parseIntFunc = parseInt; + + // IE 10 or older => return version number + if (msie > 0) + result = parseIntFunc(ua[strSubString](msie + 5, ua[strIndexOf]('.', msie)), 10); + + // IE 11 => return version number + else if (trident > 0) + result = parseIntFunc(ua[strSubString](rv + 3, ua[strIndexOf]('.', rv)), 10); + + // Edge (IE 12+) => return version number + else if (edge > 0) + result = parseIntFunc(ua[strSubString](edge + 5, ua[strIndexOf]('.', edge)), 10); + + // other browser + return result; + })(); + + FRAMEWORK.extend(_base, { + defaultOptions: defaultOptions, + msie: msie, + autoUpdateLoop: false, + autoUpdateRecommended: !COMPATIBILITY.mO(), + nativeScrollbarSize: nativeScrollbarSize, + nativeScrollbarIsOverlaid: nativeScrollbarIsOverlaid, + nativeScrollbarStyling: (function () { + var result = false; + scrollbarDummyElement.addClass('os-viewport-native-scrollbars-invisible'); + try { + result = (scrollbarDummyElement.css('scrollbar-width') === 'none' && (msie > 9 || !msie)) || window.getComputedStyle(scrollbarDummyElement0, '::-webkit-scrollbar').getPropertyValue('display') === 'none'; + } catch (ex) { } + + //fix opera bug: scrollbar styles will only appear if overflow value is scroll or auto during the activation of the style. + //and set overflow to scroll + //scrollbarDummyElement.css(strOverflow, strHidden).hide().css(strOverflow, strScroll).show(); + //return (scrollbarDummyElement0[LEXICON.oH] - scrollbarDummyElement0[LEXICON.cH]) === 0 && (scrollbarDummyElement0[LEXICON.oW] - scrollbarDummyElement0[LEXICON.cW]) === 0; + + return result; + })(), + overlayScrollbarDummySize: { x: 30, y: 30 }, + cssCalc: (function () { + var dummyStyle = document.createElement('div')[LEXICON.s]; + var strCalc = 'calc'; + var i = -1; + var prop; + + for (; i < VENDORS._cssPrefixes[LEXICON.l]; i++) { + prop = i < 0 ? strCalc : VENDORS._cssPrefixes[i] + strCalc; + dummyStyle.cssText = 'width:' + prop + '(1px);'; + if (dummyStyle[LEXICON.l]) + return prop; + } + return null; + })(), + restrictedMeasuring: (function () { + //https://bugzilla.mozilla.org/show_bug.cgi?id=1439305 + //since 1.11.0 always false -> fixed via CSS (hopefully) + scrollbarDummyElement.css(strOverflow, strHidden); + var scrollSize = { + w: scrollbarDummyElement0[LEXICON.sW], + h: scrollbarDummyElement0[LEXICON.sH] + }; + scrollbarDummyElement.css(strOverflow, 'visible'); + var scrollSize2 = { + w: scrollbarDummyElement0[LEXICON.sW], + h: scrollbarDummyElement0[LEXICON.sH] + }; + return (scrollSize.w - scrollSize2.w) !== 0 || (scrollSize.h - scrollSize2.h) !== 0; + })(), + rtlScrollBehavior: (function () { + scrollbarDummyElement.css({ 'overflow-y': strHidden, 'overflow-x': strScroll, 'direction': 'rtl' }).scrollLeft(0); + var dummyContainerOffset = scrollbarDummyElement.offset(); + var dummyContainerChildOffset = dummyContainerChild.offset(); + //https://github.com/KingSora/OverlayScrollbars/issues/187 + scrollbarDummyElement.scrollLeft(-999); + var dummyContainerChildOffsetAfterScroll = dummyContainerChild.offset(); + return { + //origin direction = determines if the zero scroll position is on the left or right side + //'i' means 'invert' (i === true means that the axis must be inverted to be correct) + //true = on the left side + //false = on the right side + i: dummyContainerOffset.left === dummyContainerChildOffset.left, + //negative = determines if the maximum scroll is positive or negative + //'n' means 'negate' (n === true means that the axis must be negated to be correct) + //true = negative + //false = positive + n: dummyContainerChildOffset.left !== dummyContainerChildOffsetAfterScroll.left + }; + })(), + supportTransform: VENDORS._cssProperty('transform') !== undefined, + supportTransition: VENDORS._cssProperty('transition') !== undefined, + supportPassiveEvents: (function () { + var supportsPassive = false; + try { + window.addEventListener('test', null, Object.defineProperty({}, 'passive', { + get: function () { + supportsPassive = true; + } + })); + } catch (e) { } + return supportsPassive; + })(), + supportResizeObserver: !!COMPATIBILITY.rO(), + supportMutationObserver: !!COMPATIBILITY.mO() + }); + + scrollbarDummyElement.removeAttr(LEXICON.s).remove(); + + //Catch zoom event: + (function () { + if (nativeScrollbarIsOverlaid.x && nativeScrollbarIsOverlaid.y) + return; + + var abs = MATH.abs; + var windowWidth = COMPATIBILITY.wW(); + var windowHeight = COMPATIBILITY.wH(); + var windowDpr = getWindowDPR(); + var onResize = function () { + if (INSTANCES().length > 0) { + var newW = COMPATIBILITY.wW(); + var newH = COMPATIBILITY.wH(); + var deltaW = newW - windowWidth; + var deltaH = newH - windowHeight; + + if (deltaW === 0 && deltaH === 0) + return; + + var deltaWRatio = MATH.round(newW / (windowWidth / 100.0)); + var deltaHRatio = MATH.round(newH / (windowHeight / 100.0)); + var absDeltaW = abs(deltaW); + var absDeltaH = abs(deltaH); + var absDeltaWRatio = abs(deltaWRatio); + var absDeltaHRatio = abs(deltaHRatio); + var newDPR = getWindowDPR(); + + var deltaIsBigger = absDeltaW > 2 && absDeltaH > 2; + var difference = !differenceIsBiggerThanOne(absDeltaWRatio, absDeltaHRatio); + var dprChanged = newDPR !== windowDpr && windowDpr > 0; + var isZoom = deltaIsBigger && difference && dprChanged; + var oldScrollbarSize = _base.nativeScrollbarSize; + var newScrollbarSize; + + if (isZoom) { + bodyElement.append(scrollbarDummyElement); + newScrollbarSize = _base.nativeScrollbarSize = calcNativeScrollbarSize(scrollbarDummyElement[0]); + scrollbarDummyElement.remove(); + if (oldScrollbarSize.x !== newScrollbarSize.x || oldScrollbarSize.y !== newScrollbarSize.y) { + FRAMEWORK.each(INSTANCES(), function () { + if (INSTANCES(this)) + INSTANCES(this).update('zoom'); + }); + } + } + + windowWidth = newW; + windowHeight = newH; + windowDpr = newDPR; + } + }; + + function differenceIsBiggerThanOne(valOne, valTwo) { + var absValOne = abs(valOne); + var absValTwo = abs(valTwo); + return !(absValOne === absValTwo || absValOne + 1 === absValTwo || absValOne - 1 === absValTwo); + } + + function getWindowDPR() { + var dDPI = window.screen.deviceXDPI || 0; + var sDPI = window.screen.logicalXDPI || 1; + return window.devicePixelRatio || (dDPI / sDPI); + } + + FRAMEWORK(window).on('resize', onResize); + })(); + + function calcNativeScrollbarSize(measureElement) { + return { + x: measureElement[LEXICON.oH] - measureElement[LEXICON.cH], + y: measureElement[LEXICON.oW] - measureElement[LEXICON.cW] + }; + } + } + + /** + * The object which manages the auto update loop for all OverlayScrollbars objects. This object is initialized only once: if the first OverlayScrollbars object gets initialized. + * @constructor + */ + function OverlayScrollbarsAutoUpdateLoop(globals) { + var _base = this; + var _inArray = FRAMEWORK.inArray; + var _getNow = COMPATIBILITY.now; + var _strAutoUpdate = 'autoUpdate'; + var _strAutoUpdateInterval = _strAutoUpdate + 'Interval'; + var _strLength = LEXICON.l; + var _loopingInstances = []; + var _loopingInstancesIntervalCache = []; + var _loopIsActive = false; + var _loopIntervalDefault = 33; + var _loopInterval = _loopIntervalDefault; + var _loopTimeOld = _getNow(); + var _loopID; + + + /** + * The auto update loop which will run every 50 milliseconds or less if the update interval of a instance is lower than 50 milliseconds. + */ + var loop = function () { + if (_loopingInstances[_strLength] > 0 && _loopIsActive) { + _loopID = COMPATIBILITY.rAF()(function () { + loop(); + }); + var timeNew = _getNow(); + var timeDelta = timeNew - _loopTimeOld; + var lowestInterval; + var instance; + var instanceOptions; + var instanceAutoUpdateAllowed; + var instanceAutoUpdateInterval; + var now; + + if (timeDelta > _loopInterval) { + _loopTimeOld = timeNew - (timeDelta % _loopInterval); + lowestInterval = _loopIntervalDefault; + for (var i = 0; i < _loopingInstances[_strLength]; i++) { + instance = _loopingInstances[i]; + if (instance !== undefined) { + instanceOptions = instance.options(); + instanceAutoUpdateAllowed = instanceOptions[_strAutoUpdate]; + instanceAutoUpdateInterval = MATH.max(1, instanceOptions[_strAutoUpdateInterval]); + now = _getNow(); + + if ((instanceAutoUpdateAllowed === true || instanceAutoUpdateAllowed === null) && (now - _loopingInstancesIntervalCache[i]) > instanceAutoUpdateInterval) { + instance.update('auto'); + _loopingInstancesIntervalCache[i] = new Date(now += instanceAutoUpdateInterval); + } + + lowestInterval = MATH.max(1, MATH.min(lowestInterval, instanceAutoUpdateInterval)); + } + } + _loopInterval = lowestInterval; + } + } else { + _loopInterval = _loopIntervalDefault; + } + }; + + /** + * Add OverlayScrollbars instance to the auto update loop. Only successful if the instance isn't already added. + * @param instance The instance which shall be updated in a loop automatically. + */ + _base.add = function (instance) { + if (_inArray(instance, _loopingInstances) === -1) { + _loopingInstances.push(instance); + _loopingInstancesIntervalCache.push(_getNow()); + if (_loopingInstances[_strLength] > 0 && !_loopIsActive) { + _loopIsActive = true; + globals.autoUpdateLoop = _loopIsActive; + loop(); + } + } + }; + + /** + * Remove OverlayScrollbars instance from the auto update loop. Only successful if the instance was added before. + * @param instance The instance which shall be updated in a loop automatically. + */ + _base.remove = function (instance) { + var index = _inArray(instance, _loopingInstances); + if (index > -1) { + //remove from loopingInstances list + _loopingInstancesIntervalCache.splice(index, 1); + _loopingInstances.splice(index, 1); + + //correct update loop behavior + if (_loopingInstances[_strLength] === 0 && _loopIsActive) { + _loopIsActive = false; + globals.autoUpdateLoop = _loopIsActive; + if (_loopID !== undefined) { + COMPATIBILITY.cAF()(_loopID); + _loopID = -1; + } + } + } + }; + } + + /** + * A object which manages the scrollbars visibility of the target element. + * @param pluginTargetElement The element from which the scrollbars shall be hidden. + * @param options The custom options. + * @param extensions The custom extensions. + * @param globals + * @param autoUpdateLoop + * @returns {*} + * @constructor + */ + function OverlayScrollbarsInstance(pluginTargetElement, options, extensions, globals, autoUpdateLoop) { + //shortcuts + var type = COMPATIBILITY.type; + var inArray = FRAMEWORK.inArray; + var each = FRAMEWORK.each; + + //make correct instanceof + var _base = new _plugin(); + var _frameworkProto = FRAMEWORK[LEXICON.p]; + + //if passed element is no HTML element: skip and return + if (!isHTMLElement(pluginTargetElement)) + return; + + //if passed element is already initialized: set passed options if there are any and return its instance + if (INSTANCES(pluginTargetElement)) { + var inst = INSTANCES(pluginTargetElement); + inst.options(options); + return inst; + } + + //globals: + var _nativeScrollbarIsOverlaid; + var _overlayScrollbarDummySize; + var _rtlScrollBehavior; + var _autoUpdateRecommended; + var _msieVersion; + var _nativeScrollbarStyling; + var _cssCalc; + var _nativeScrollbarSize; + var _supportTransition; + var _supportTransform; + var _supportPassiveEvents; + var _supportResizeObserver; + var _supportMutationObserver; + var _restrictedMeasuring; + + //general readonly: + var _initialized; + var _destroyed; + var _isTextarea; + var _isBody; + var _documentMixed; + var _domExists; + + //general: + var _isBorderBox; + var _sizeAutoObserverAdded; + var _paddingX; + var _paddingY; + var _borderX; + var _borderY; + var _marginX; + var _marginY; + var _isRTL; + var _sleeping; + var _contentBorderSize = {}; + var _scrollHorizontalInfo = {}; + var _scrollVerticalInfo = {}; + var _viewportSize = {}; + var _nativeScrollbarMinSize = {}; + + //naming: + var _strMinusHidden = '-hidden'; + var _strMarginMinus = 'margin-'; + var _strPaddingMinus = 'padding-'; + var _strBorderMinus = 'border-'; + var _strTop = 'top'; + var _strRight = 'right'; + var _strBottom = 'bottom'; + var _strLeft = 'left'; + var _strMinMinus = 'min-'; + var _strMaxMinus = 'max-'; + var _strWidth = 'width'; + var _strHeight = 'height'; + var _strFloat = 'float'; + var _strEmpty = ''; + var _strAuto = 'auto'; + var _strSync = 'sync'; + var _strScroll = 'scroll'; + var _strHundredPercent = '100%'; + var _strX = 'x'; + var _strY = 'y'; + var _strDot = '.'; + var _strSpace = ' '; + var _strScrollbar = 'scrollbar'; + var _strMinusHorizontal = '-horizontal'; + var _strMinusVertical = '-vertical'; + var _strScrollLeft = _strScroll + 'Left'; + var _strScrollTop = _strScroll + 'Top'; + var _strMouseTouchDownEvent = 'mousedown touchstart'; + var _strMouseTouchUpEvent = 'mouseup touchend touchcancel'; + var _strMouseTouchMoveEvent = 'mousemove touchmove'; + var _strMouseTouchEnter = 'mouseenter'; + var _strMouseTouchLeave = 'mouseleave'; + var _strKeyDownEvent = 'keydown'; + var _strKeyUpEvent = 'keyup'; + var _strSelectStartEvent = 'selectstart'; + var _strTransitionEndEvent = 'transitionend webkitTransitionEnd oTransitionEnd'; + var _strResizeObserverProperty = '__overlayScrollbarsRO__'; + + //class names: + var _cassNamesPrefix = 'os-'; + var _classNameHTMLElement = _cassNamesPrefix + 'html'; + var _classNameHostElement = _cassNamesPrefix + 'host'; + var _classNameHostTextareaElement = _classNameHostElement + '-textarea'; + var _classNameHostScrollbarHorizontalHidden = _classNameHostElement + '-' + _strScrollbar + _strMinusHorizontal + _strMinusHidden; + var _classNameHostScrollbarVerticalHidden = _classNameHostElement + '-' + _strScrollbar + _strMinusVertical + _strMinusHidden; + var _classNameHostTransition = _classNameHostElement + '-transition'; + var _classNameHostRTL = _classNameHostElement + '-rtl'; + var _classNameHostResizeDisabled = _classNameHostElement + '-resize-disabled'; + var _classNameHostScrolling = _classNameHostElement + '-scrolling'; + var _classNameHostOverflow = _classNameHostElement + '-overflow'; + var _classNameHostOverflowX = _classNameHostOverflow + '-x'; + var _classNameHostOverflowY = _classNameHostOverflow + '-y'; + var _classNameTextareaElement = _cassNamesPrefix + 'textarea'; + var _classNameTextareaCoverElement = _classNameTextareaElement + '-cover'; + var _classNamePaddingElement = _cassNamesPrefix + 'padding'; + var _classNameViewportElement = _cassNamesPrefix + 'viewport'; + var _classNameViewportNativeScrollbarsInvisible = _classNameViewportElement + '-native-scrollbars-invisible'; + var _classNameViewportNativeScrollbarsOverlaid = _classNameViewportElement + '-native-scrollbars-overlaid'; + var _classNameContentElement = _cassNamesPrefix + 'content'; + var _classNameContentArrangeElement = _cassNamesPrefix + 'content-arrange'; + var _classNameContentGlueElement = _cassNamesPrefix + 'content-glue'; + var _classNameSizeAutoObserverElement = _cassNamesPrefix + 'size-auto-observer'; + var _classNameResizeObserverElement = _cassNamesPrefix + 'resize-observer'; + var _classNameResizeObserverItemElement = _cassNamesPrefix + 'resize-observer-item'; + var _classNameResizeObserverItemFinalElement = _classNameResizeObserverItemElement + '-final'; + var _classNameTextInherit = _cassNamesPrefix + 'text-inherit'; + var _classNameScrollbar = _cassNamesPrefix + _strScrollbar; + var _classNameScrollbarTrack = _classNameScrollbar + '-track'; + var _classNameScrollbarTrackOff = _classNameScrollbarTrack + '-off'; + var _classNameScrollbarHandle = _classNameScrollbar + '-handle'; + var _classNameScrollbarHandleOff = _classNameScrollbarHandle + '-off'; + var _classNameScrollbarUnusable = _classNameScrollbar + '-unusable'; + var _classNameScrollbarAutoHidden = _classNameScrollbar + '-' + _strAuto + _strMinusHidden; + var _classNameScrollbarCorner = _classNameScrollbar + '-corner'; + var _classNameScrollbarCornerResize = _classNameScrollbarCorner + '-resize'; + var _classNameScrollbarCornerResizeB = _classNameScrollbarCornerResize + '-both'; + var _classNameScrollbarCornerResizeH = _classNameScrollbarCornerResize + _strMinusHorizontal; + var _classNameScrollbarCornerResizeV = _classNameScrollbarCornerResize + _strMinusVertical; + var _classNameScrollbarHorizontal = _classNameScrollbar + _strMinusHorizontal; + var _classNameScrollbarVertical = _classNameScrollbar + _strMinusVertical; + var _classNameDragging = _cassNamesPrefix + 'dragging'; + var _classNameThemeNone = _cassNamesPrefix + 'theme-none'; + var _classNamesDynamicDestroy = [ + _classNameViewportNativeScrollbarsInvisible, + _classNameViewportNativeScrollbarsOverlaid, + _classNameScrollbarTrackOff, + _classNameScrollbarHandleOff, + _classNameScrollbarUnusable, + _classNameScrollbarAutoHidden, + _classNameScrollbarCornerResize, + _classNameScrollbarCornerResizeB, + _classNameScrollbarCornerResizeH, + _classNameScrollbarCornerResizeV, + _classNameDragging].join(_strSpace); + + //callbacks: + var _callbacksInitQeueue = []; + + //attrs viewport shall inherit from target + var _viewportAttrsFromTarget = [LEXICON.ti]; + + //options: + var _defaultOptions; + var _currentOptions; + var _currentPreparedOptions; + + //extensions: + var _extensions = {}; + var _extensionsPrivateMethods = 'added removed on contract'; + + //update + var _lastUpdateTime; + var _swallowedUpdateHints = {}; + var _swallowedUpdateTimeout; + var _swallowUpdateLag = 42; + var _imgs = []; + + //DOM elements: + var _windowElement; + var _documentElement; + var _htmlElement; + var _bodyElement; + var _targetElement; //the target element of this OverlayScrollbars object + var _hostElement; //the host element of this OverlayScrollbars object -> may be the same as targetElement + var _sizeAutoObserverElement; //observes size auto changes + var _sizeObserverElement; //observes size and padding changes + var _paddingElement; //manages the padding + var _viewportElement; //is the viewport of our scrollbar model + var _contentElement; //the element which holds the content + var _contentArrangeElement; //is needed for correct sizing of the content element (only if native scrollbars are overlays) + var _contentGlueElement; //has always the size of the content element + var _textareaCoverElement; //only applied if target is a textarea element. Used for correct size calculation and for prevention of uncontrolled scrolling + var _scrollbarCornerElement; + var _scrollbarHorizontalElement; + var _scrollbarHorizontalTrackElement; + var _scrollbarHorizontalHandleElement; + var _scrollbarVerticalElement; + var _scrollbarVerticalTrackElement; + var _scrollbarVerticalHandleElement; + var _windowElementNative; + var _documentElementNative; + var _targetElementNative; + var _hostElementNative; + var _sizeAutoObserverElementNative; + var _sizeObserverElementNative; + var _paddingElementNative; + var _viewportElementNative; + var _contentElementNative; + + //Cache: + var _hostSizeCache; + var _contentScrollSizeCache; + var _arrangeContentSizeCache; + var _hasOverflowCache; + var _hideOverflowCache; + var _widthAutoCache; + var _heightAutoCache; + var _cssMaxValueCache; + var _cssBoxSizingCache; + var _cssPaddingCache; + var _cssBorderCache; + var _cssMarginCache; + var _cssDirectionCache; + var _cssDirectionDetectedCache; + var _paddingAbsoluteCache; + var _clipAlwaysCache; + var _contentGlueSizeCache; + var _overflowBehaviorCache; + var _overflowAmountCache; + var _ignoreOverlayScrollbarHidingCache; + var _autoUpdateCache; + var _sizeAutoCapableCache; + var _contentElementScrollSizeChangeDetectedCache; + var _hostElementSizeChangeDetectedCache; + var _scrollbarsVisibilityCache; + var _scrollbarsAutoHideCache; + var _scrollbarsClickScrollingCache; + var _scrollbarsDragScrollingCache; + var _resizeCache; + var _normalizeRTLCache; + var _classNameCache; + var _oldClassName; + var _textareaAutoWrappingCache; + var _textareaInfoCache; + var _textareaSizeCache; + var _textareaDynHeightCache; + var _textareaDynWidthCache; + var _bodyMinSizeCache; + var _displayIsHiddenCache; + var _updateAutoCache = {}; + + //MutationObserver: + var _mutationObserverHost; + var _mutationObserverContent; + var _mutationObserverHostCallback; + var _mutationObserverContentCallback; + var _mutationObserversConnected; + var _mutationObserverAttrsTextarea = ['wrap', 'cols', 'rows']; + var _mutationObserverAttrsHost = [LEXICON.i, LEXICON.c, LEXICON.s, 'open'].concat(_viewportAttrsFromTarget); + + //events: + var _destroyEvents = []; + + //textarea: + var _textareaHasFocus; + + //scrollbars: + var _scrollbarsAutoHideTimeoutId; + var _scrollbarsAutoHideMoveTimeoutId; + var _scrollbarsAutoHideDelay; + var _scrollbarsAutoHideNever; + var _scrollbarsAutoHideScroll; + var _scrollbarsAutoHideMove; + var _scrollbarsAutoHideLeave; + var _scrollbarsHandleHovered; + var _scrollbarsHandlesDefineScrollPos; + + //resize + var _resizeNone; + var _resizeBoth; + var _resizeHorizontal; + var _resizeVertical; + + + //==== Event Listener ====// + + /** + * Adds or removes a event listener from the given element. + * @param element The element to which the event listener shall be applied or removed. + * @param eventNames The name(s) of the events. + * @param listener The method which shall be called. + * @param remove True if the handler shall be removed, false or undefined if the handler shall be added. + */ + function setupResponsiveEventListener(element, eventNames, listener, remove, passive) { + var collected = type(eventNames) == TYPES.a && type(listener) == TYPES.a; + var method = remove ? 'removeEventListener' : 'addEventListener'; + var onOff = remove ? 'off' : 'on'; + var events = collected ? false : eventNames.split(_strSpace) + var i = 0; + + if (collected) { + for (; i < eventNames[LEXICON.l]; i++) + setupResponsiveEventListener(element, eventNames[i], listener[i], remove); + } + else { + for (; i < events[LEXICON.l]; i++) { + if (_supportPassiveEvents) + element[0][method](events[i], listener, { passive: passive || false }); + else + element[onOff](events[i], listener); + } + } + } + + + function addDestroyEventListener(element, eventNames, listener, passive) { + setupResponsiveEventListener(element, eventNames, listener, false, passive); + _destroyEvents.push(COMPATIBILITY.bind(setupResponsiveEventListener, 0, element, eventNames, listener, true, passive)); + } + + //==== Resize Observer ====// + + /** + * Adds or removes a resize observer from the given element. + * @param targetElement The element to which the resize observer shall be added or removed. + * @param onElementResizedCallback The callback which is fired every time the resize observer registers a size change or false / undefined if the resizeObserver shall be removed. + */ + function setupResizeObserver(targetElement, onElementResizedCallback) { + if (targetElement) { + var resizeObserver = COMPATIBILITY.rO(); + var strAnimationStartEvent = 'animationstart mozAnimationStart webkitAnimationStart MSAnimationStart'; + var strChildNodes = 'childNodes'; + var constScroll = 3333333; + var callback = function () { + targetElement[_strScrollTop](constScroll)[_strScrollLeft](_isRTL ? _rtlScrollBehavior.n ? -constScroll : _rtlScrollBehavior.i ? 0 : constScroll : constScroll); + onElementResizedCallback(); + }; + //add resize observer: + if (onElementResizedCallback) { + if (_supportResizeObserver) { + var element = targetElement.addClass('observed').append(generateDiv(_classNameResizeObserverElement)).contents()[0]; + var observer = element[_strResizeObserverProperty] = new resizeObserver(callback); + observer.observe(element); + } + else { + if (_msieVersion > 9 || !_autoUpdateRecommended) { + targetElement.prepend( + generateDiv(_classNameResizeObserverElement, + generateDiv({ c: _classNameResizeObserverItemElement, dir: 'ltr' }, + generateDiv(_classNameResizeObserverItemElement, + generateDiv(_classNameResizeObserverItemFinalElement) + ) + + generateDiv(_classNameResizeObserverItemElement, + generateDiv({ c: _classNameResizeObserverItemFinalElement, style: 'width: 200%; height: 200%' }) + ) + ) + ) + ); + + var observerElement = targetElement[0][strChildNodes][0][strChildNodes][0]; + var shrinkElement = FRAMEWORK(observerElement[strChildNodes][1]); + var expandElement = FRAMEWORK(observerElement[strChildNodes][0]); + var expandElementChild = FRAMEWORK(expandElement[0][strChildNodes][0]); + var widthCache = observerElement[LEXICON.oW]; + var heightCache = observerElement[LEXICON.oH]; + var isDirty; + var rAFId; + var currWidth; + var currHeight; + var factor = 2; + var nativeScrollbarSize = globals.nativeScrollbarSize; //care don't make changes to this object!!! + var reset = function () { + /* + var sizeResetWidth = observerElement[LEXICON.oW] + nativeScrollbarSize.x * factor + nativeScrollbarSize.y * factor + _overlayScrollbarDummySize.x + _overlayScrollbarDummySize.y; + var sizeResetHeight = observerElement[LEXICON.oH] + nativeScrollbarSize.x * factor + nativeScrollbarSize.y * factor + _overlayScrollbarDummySize.x + _overlayScrollbarDummySize.y; + var expandChildCSS = {}; + expandChildCSS[_strWidth] = sizeResetWidth; + expandChildCSS[_strHeight] = sizeResetHeight; + expandElementChild.css(expandChildCSS); + + + expandElement[_strScrollLeft](sizeResetWidth)[_strScrollTop](sizeResetHeight); + shrinkElement[_strScrollLeft](sizeResetWidth)[_strScrollTop](sizeResetHeight); + */ + expandElement[_strScrollLeft](constScroll)[_strScrollTop](constScroll); + shrinkElement[_strScrollLeft](constScroll)[_strScrollTop](constScroll); + }; + var onResized = function () { + rAFId = 0; + if (!isDirty) + return; + + widthCache = currWidth; + heightCache = currHeight; + callback(); + }; + var onScroll = function (event) { + currWidth = observerElement[LEXICON.oW]; + currHeight = observerElement[LEXICON.oH]; + isDirty = currWidth != widthCache || currHeight != heightCache; + + if (event && isDirty && !rAFId) { + COMPATIBILITY.cAF()(rAFId); + rAFId = COMPATIBILITY.rAF()(onResized); + } + else if (!event) + onResized(); + + reset(); + if (event) { + COMPATIBILITY.prvD(event); + COMPATIBILITY.stpP(event); + } + return false; + }; + var expandChildCSS = {}; + var observerElementCSS = {}; + + setTopRightBottomLeft(observerElementCSS, _strEmpty, [ + -((nativeScrollbarSize.y + 1) * factor), + nativeScrollbarSize.x * -factor, + nativeScrollbarSize.y * -factor, + -((nativeScrollbarSize.x + 1) * factor) + ]); + + FRAMEWORK(observerElement).css(observerElementCSS); + expandElement.on(_strScroll, onScroll); + shrinkElement.on(_strScroll, onScroll); + targetElement.on(strAnimationStartEvent, function () { + onScroll(false); + }); + //lets assume that the divs will never be that large and a constant value is enough + expandChildCSS[_strWidth] = constScroll; + expandChildCSS[_strHeight] = constScroll; + expandElementChild.css(expandChildCSS); + + reset(); + } + else { + var attachEvent = _documentElementNative.attachEvent; + var isIE = _msieVersion !== undefined; + if (attachEvent) { + targetElement.prepend(generateDiv(_classNameResizeObserverElement)); + findFirst(targetElement, _strDot + _classNameResizeObserverElement)[0].attachEvent('onresize', callback); + } + else { + var obj = _documentElementNative.createElement(TYPES.o); + obj.setAttribute(LEXICON.ti, '-1'); + obj.setAttribute(LEXICON.c, _classNameResizeObserverElement); + obj.onload = function () { + var wnd = this.contentDocument.defaultView; + wnd.addEventListener('resize', callback); + wnd.document.documentElement.style.display = 'none'; + }; + obj.type = 'text/html'; + if (isIE) + targetElement.prepend(obj); + obj.data = 'about:blank'; + if (!isIE) + targetElement.prepend(obj); + targetElement.on(strAnimationStartEvent, callback); + } + } + } + + if (targetElement[0] === _sizeObserverElementNative) { + var directionChanged = function () { + var dir = _hostElement.css('direction'); + var css = {}; + var scrollLeftValue = 0; + var result = false; + if (dir !== _cssDirectionDetectedCache) { + if (dir === 'ltr') { + css[_strLeft] = 0; + css[_strRight] = _strAuto; + scrollLeftValue = constScroll; + } + else { + css[_strLeft] = _strAuto; + css[_strRight] = 0; + scrollLeftValue = _rtlScrollBehavior.n ? -constScroll : _rtlScrollBehavior.i ? 0 : constScroll; + } + //execution order is important for IE!!! + _sizeObserverElement.children().eq(0).css(css); + _sizeObserverElement[_strScrollLeft](scrollLeftValue)[_strScrollTop](constScroll); + _cssDirectionDetectedCache = dir; + result = true; + } + return result; + }; + directionChanged(); + addDestroyEventListener(targetElement, _strScroll, function (event) { + if (directionChanged()) + update(); + COMPATIBILITY.prvD(event); + COMPATIBILITY.stpP(event); + return false; + }); + } + } + //remove resize observer: + else { + if (_supportResizeObserver) { + var element = targetElement.contents()[0]; + var resizeObserverObj = element[_strResizeObserverProperty]; + if (resizeObserverObj) { + resizeObserverObj.disconnect(); + delete element[_strResizeObserverProperty]; + } + } + else { + remove(targetElement.children(_strDot + _classNameResizeObserverElement).eq(0)); + } + } + } + } + + /** + * Freezes or unfreezes the given resize observer. + * @param targetElement The element to which the target resize observer is applied. + * @param freeze True if the resize observer shall be frozen, false otherwise. + + function freezeResizeObserver(targetElement, freeze) { + if (targetElement !== undefined) { + if(freeze) { + if (_supportResizeObserver) { + var element = targetElement.contents()[0]; + element[_strResizeObserverProperty].unobserve(element); + } + else { + targetElement = targetElement.children(_strDot + _classNameResizeObserverElement).eq(0); + var w = targetElement.css(_strWidth); + var h = targetElement.css(_strHeight); + var css = {}; + css[_strWidth] = w; + css[_strHeight] = h; + targetElement.css(css); + } + } + else { + if (_supportResizeObserver) { + var element = targetElement.contents()[0]; + element[_strResizeObserverProperty].observe(element); + } + else { + var css = { }; + css[_strHeight] = _strEmpty; + css[_strWidth] = _strEmpty; + targetElement.children(_strDot + _classNameResizeObserverElement).eq(0).css(css); + } + } + } + } + */ + + + //==== Mutation Observers ====// + + /** + * Creates MutationObservers for the host and content Element if they are supported. + */ + function createMutationObservers() { + if (_supportMutationObserver) { + var mutationObserverContentLag = 11; + var mutationObserver = COMPATIBILITY.mO(); + var contentLastUpdate = COMPATIBILITY.now(); + var mutationTarget; + var mutationAttrName; + var contentTimeout; + var now; + var sizeAuto; + var action; + + _mutationObserverHostCallback = function (mutations) { + var doUpdate = false; + var mutation; + var mutatedAttrs = []; + + if (_initialized && !_sleeping) { + each(mutations, function () { + mutation = this; + mutationTarget = mutation.target; + mutationAttrName = mutation.attributeName; + + if(!doUpdate) { + if (mutationAttrName === LEXICON.c) + doUpdate = hostClassNamesChanged(mutation.oldValue, mutationTarget.className); + else if (mutationAttrName === LEXICON.s) + doUpdate = mutation.oldValue !== mutationTarget[LEXICON.s].cssText; + else + doUpdate = true; + } + + mutatedAttrs.push(mutationAttrName); + }); + + updateViewportAttrsFromTarget(mutatedAttrs); + + if (doUpdate) + _base.update(_strAuto); + } + return doUpdate; + }; + _mutationObserverContentCallback = function (mutations) { + var doUpdate = false; + var mutation; + + if (_initialized && !_sleeping) { + each(mutations, function () { + mutation = this; + doUpdate = isUnknownMutation(mutation); + return !doUpdate; + }); + + if (doUpdate) { + now = COMPATIBILITY.now(); + sizeAuto = (_heightAutoCache || _widthAutoCache); + action = function () { + if (!_destroyed) { + contentLastUpdate = now; + + //if cols, rows or wrap attr was changed + if (_isTextarea) + textareaUpdate(); + + if (sizeAuto) + update(); + else + _base.update(_strAuto); + } + }; + clearTimeout(contentTimeout); + if (mutationObserverContentLag <= 0 || now - contentLastUpdate > mutationObserverContentLag || !sizeAuto) + action(); + else + contentTimeout = setTimeout(action, mutationObserverContentLag); + } + } + return doUpdate; + } + + _mutationObserverHost = new mutationObserver(_mutationObserverHostCallback); + _mutationObserverContent = new mutationObserver(_mutationObserverContentCallback); + } + } + + /** + * Connects the MutationObservers if they are supported. + */ + function connectMutationObservers() { + if (_supportMutationObserver && !_mutationObserversConnected) { + _mutationObserverHost.observe(_hostElementNative, { + attributes: true, + attributeOldValue: true, + attributeFilter: _mutationObserverAttrsHost + }); + + _mutationObserverContent.observe(_isTextarea ? _targetElementNative : _contentElementNative, { + attributes: true, + attributeOldValue: true, + subtree: !_isTextarea, + childList: !_isTextarea, + characterData: !_isTextarea, + attributeFilter: _isTextarea ? _mutationObserverAttrsTextarea : _mutationObserverAttrsHost + }); + + _mutationObserversConnected = true; + } + } + + /** + * Disconnects the MutationObservers if they are supported. + */ + function disconnectMutationObservers() { + if (_supportMutationObserver && _mutationObserversConnected) { + _mutationObserverHost.disconnect(); + _mutationObserverContent.disconnect(); + + _mutationObserversConnected = false; + } + } + + + //==== Events of elements ====// + + /** + * This method gets called every time the host element gets resized. IMPORTANT: Padding changes are detected too!! + * It refreshes the hostResizedEventArgs and the hostSizeResizeCache. + * If there are any size changes, the update method gets called. + */ + function hostOnResized() { + if (!_sleeping) { + var changed; + var hostSize = { + w: _sizeObserverElementNative[LEXICON.sW], + h: _sizeObserverElementNative[LEXICON.sH] + }; + + changed = checkCache(hostSize, _hostElementSizeChangeDetectedCache); + _hostElementSizeChangeDetectedCache = hostSize; + if (changed) + update({ _hostSizeChanged: true }); + } + } + + /** + * The mouse enter event of the host element. This event is only needed for the autoHide feature. + */ + function hostOnMouseEnter() { + if (_scrollbarsAutoHideLeave) + refreshScrollbarsAutoHide(true); + } + + /** + * The mouse leave event of the host element. This event is only needed for the autoHide feature. + */ + function hostOnMouseLeave() { + if (_scrollbarsAutoHideLeave && !_bodyElement.hasClass(_classNameDragging)) + refreshScrollbarsAutoHide(false); + } + + /** + * The mouse move event of the host element. This event is only needed for the autoHide "move" feature. + */ + function hostOnMouseMove() { + if (_scrollbarsAutoHideMove) { + refreshScrollbarsAutoHide(true); + clearTimeout(_scrollbarsAutoHideMoveTimeoutId); + _scrollbarsAutoHideMoveTimeoutId = setTimeout(function () { + if (_scrollbarsAutoHideMove && !_destroyed) + refreshScrollbarsAutoHide(false); + }, 100); + } + } + + /** + * Prevents text from deselection if attached to the document element on the mousedown event of a DOM element. + * @param event The select start event. + */ + function documentOnSelectStart(event) { + COMPATIBILITY.prvD(event); + return false; + } + + /** + * A callback which will be called after a img element has downloaded its src asynchronous. + */ + function imgOnLoad() { + update({ _contentSizeChanged: true }); + } + + /** + * Adds or removes mouse & touch events of the host element. (for handling auto-hiding of the scrollbars) + * @param destroy Indicates whether the events shall be added or removed. + */ + function setupHostMouseTouchEvents(destroy) { + setupResponsiveEventListener(_hostElement, + _strMouseTouchMoveEvent, + hostOnMouseMove, + (_scrollbarsAutoHideMove ? destroy : true), true); + setupResponsiveEventListener(_hostElement, + [_strMouseTouchEnter, _strMouseTouchLeave], + [hostOnMouseEnter, hostOnMouseLeave], + (_scrollbarsAutoHideMove ? true : destroy), true); + + //if the plugin is initialized and the mouse is over the host element, make the scrollbars visible + if (!_initialized && !destroy) + _hostElement.one('mouseover', hostOnMouseEnter); + } + + + //==== Update Detection ====// + + /** + * Measures the min width and min height of the body element and refreshes the related cache. + * @returns {boolean} True if the min width or min height has changed, false otherwise. + */ + function bodyMinSizeChanged() { + var bodyMinSize = {}; + if (_isBody && _contentArrangeElement) { + bodyMinSize.w = parseToZeroOrNumber(_contentArrangeElement.css(_strMinMinus + _strWidth)); + bodyMinSize.h = parseToZeroOrNumber(_contentArrangeElement.css(_strMinMinus + _strHeight)); + bodyMinSize.c = checkCache(bodyMinSize, _bodyMinSizeCache); + bodyMinSize.f = true; //flag for "measured at least once" + } + _bodyMinSizeCache = bodyMinSize; + return !!bodyMinSize.c; + } + + /** + * Returns true if the class names really changed (new class without plugin host prefix) + * @param oldCassNames The old ClassName string. + * @param newClassNames The new ClassName string. + * @returns {boolean} True if the class names has really changed, false otherwise. + */ + function hostClassNamesChanged(oldCassNames, newClassNames) { + var currClasses = (newClassNames !== undefined && newClassNames !== null) ? newClassNames.split(_strSpace) : _strEmpty; + var oldClasses = (oldCassNames !== undefined && oldCassNames !== null) ? oldCassNames.split(_strSpace) : _strEmpty; + if (currClasses === _strEmpty && oldClasses === _strEmpty) + return false; + var diff = getArrayDifferences(oldClasses, currClasses); + var changed = false; + var oldClassNames = _oldClassName !== undefined && _oldClassName !== null ? _oldClassName.split(_strSpace) : [_strEmpty]; + var currClassNames = _classNameCache !== undefined && _classNameCache !== null ? _classNameCache.split(_strSpace) : [_strEmpty]; + + //remove none theme from diff list to prevent update + var idx = inArray(_classNameThemeNone, diff); + var curr; + var i; + var v; + var o; + var c; + + if (idx > -1) + diff.splice(idx, 1); + + for (i = 0; i < diff.length; i++) { + curr = diff[i]; + if (curr.indexOf(_classNameHostElement) !== 0) { + o = true; + c = true; + for (v = 0; v < oldClassNames.length; v++) { + if (curr === oldClassNames[v]) { + o = false; + break; + } + } + for (v = 0; v < currClassNames.length; v++) { + if (curr === currClassNames[v]) { + c = false; + break; + } + } + if (o && c) { + changed = true; + break; + } + } + + } + return changed; + } + + /** + * Returns true if the given mutation is not from a from the plugin generated element. If the target element is a textarea the mutation is always unknown. + * @param mutation The mutation which shall be checked. + * @returns {boolean} True if the mutation is from a unknown element, false otherwise. + */ + function isUnknownMutation(mutation) { + var attributeName = mutation.attributeName; + var mutationTarget = mutation.target; + var mutationType = mutation.type; + var strClosest = 'closest'; + + if (mutationTarget === _contentElementNative) + return attributeName === null; + if (mutationType === 'attributes' && (attributeName === LEXICON.c || attributeName === LEXICON.s) && !_isTextarea) { + //ignore className changes by the plugin + if (attributeName === LEXICON.c && FRAMEWORK(mutationTarget).hasClass(_classNameHostElement)) + return hostClassNamesChanged(mutation.oldValue, mutationTarget.getAttribute(LEXICON.c)); + + //only do it of browser support it natively + if (typeof mutationTarget[strClosest] != TYPES.f) + return true; + if (mutationTarget[strClosest](_strDot + _classNameResizeObserverElement) !== null || + mutationTarget[strClosest](_strDot + _classNameScrollbar) !== null || + mutationTarget[strClosest](_strDot + _classNameScrollbarCorner) !== null) + return false; + } + return true; + } + + /** + * Returns true if the content size was changed since the last time this method was called. + * @returns {boolean} True if the content size was changed, false otherwise. + */ + function updateAutoContentSizeChanged() { + if (_sleeping) + return false; + + var contentMeasureElement = getContentMeasureElement(); + var textareaValueLength = _isTextarea && _widthAutoCache && !_textareaAutoWrappingCache ? _targetElement.val().length : 0; + var setCSS = !_mutationObserversConnected && _widthAutoCache && !_isTextarea; + var css = {}; + var float; + var bodyMinSizeC; + var changed; + var contentElementScrollSize; + + if (setCSS) { + float = _contentElement.css(_strFloat); + css[_strFloat] = _isRTL ? _strRight : _strLeft; + css[_strWidth] = _strAuto; + _contentElement.css(css); + } + contentElementScrollSize = { + w: contentMeasureElement[LEXICON.sW] + textareaValueLength, + h: contentMeasureElement[LEXICON.sH] + textareaValueLength + }; + if (setCSS) { + css[_strFloat] = float; + css[_strWidth] = _strHundredPercent; + _contentElement.css(css); + } + + bodyMinSizeC = bodyMinSizeChanged(); + changed = checkCache(contentElementScrollSize, _contentElementScrollSizeChangeDetectedCache); + + _contentElementScrollSizeChangeDetectedCache = contentElementScrollSize; + + return changed || bodyMinSizeC; + } + + /** + * Returns true when a attribute which the MutationObserver would observe has changed. + * @returns {boolean} True if one of the attributes which a MutationObserver would observe has changed, false or undefined otherwise. + */ + function meaningfulAttrsChanged() { + if (_sleeping || _mutationObserversConnected) + return; + + var elem; + var curr; + var cache; + var changedAttrs = []; + var checks = [ + { + _elem: _hostElement, + _attrs: _mutationObserverAttrsHost.concat(':visible') + }, + { + _elem: _isTextarea ? _targetElement : undefined, + _attrs: _mutationObserverAttrsTextarea + } + ]; + + each(checks, function (index, check) { + elem = check._elem; + if (elem) { + each(check._attrs, function (index, attr) { + curr = attr.charAt(0) === ':' ? elem.is(attr) : elem.attr(attr); + cache = _updateAutoCache[attr]; + + if(checkCache(curr, cache)) { + changedAttrs.push(attr); + } + + _updateAutoCache[attr] = curr; + }); + } + }); + + updateViewportAttrsFromTarget(changedAttrs); + + return changedAttrs[LEXICON.l] > 0; + } + + /** + * Checks is a CSS Property of a child element is affecting the scroll size of the content. + * @param propertyName The CSS property name. + * @returns {boolean} True if the property is affecting the content scroll size, false otherwise. + */ + function isSizeAffectingCSSProperty(propertyName) { + if (!_initialized) + return true; + var flexGrow = 'flex-grow'; + var flexShrink = 'flex-shrink'; + var flexBasis = 'flex-basis'; + var affectingPropsX = [ + _strWidth, + _strMinMinus + _strWidth, + _strMaxMinus + _strWidth, + _strMarginMinus + _strLeft, + _strMarginMinus + _strRight, + _strLeft, + _strRight, + 'font-weight', + 'word-spacing', + flexGrow, + flexShrink, + flexBasis + ]; + var affectingPropsXContentBox = [ + _strPaddingMinus + _strLeft, + _strPaddingMinus + _strRight, + _strBorderMinus + _strLeft + _strWidth, + _strBorderMinus + _strRight + _strWidth + ]; + var affectingPropsY = [ + _strHeight, + _strMinMinus + _strHeight, + _strMaxMinus + _strHeight, + _strMarginMinus + _strTop, + _strMarginMinus + _strBottom, + _strTop, + _strBottom, + 'line-height', + flexGrow, + flexShrink, + flexBasis + ]; + var affectingPropsYContentBox = [ + _strPaddingMinus + _strTop, + _strPaddingMinus + _strBottom, + _strBorderMinus + _strTop + _strWidth, + _strBorderMinus + _strBottom + _strWidth + ]; + var _strS = 's'; + var _strVS = 'v-s'; + var checkX = _overflowBehaviorCache.x === _strS || _overflowBehaviorCache.x === _strVS; + var checkY = _overflowBehaviorCache.y === _strS || _overflowBehaviorCache.y === _strVS; + var sizeIsAffected = false; + var checkPropertyName = function (arr, name) { + for (var i = 0; i < arr[LEXICON.l]; i++) { + if (arr[i] === name) + return true; + } + return false; + }; + + if (checkY) { + sizeIsAffected = checkPropertyName(affectingPropsY, propertyName); + if (!sizeIsAffected && !_isBorderBox) + sizeIsAffected = checkPropertyName(affectingPropsYContentBox, propertyName); + } + if (checkX && !sizeIsAffected) { + sizeIsAffected = checkPropertyName(affectingPropsX, propertyName); + if (!sizeIsAffected && !_isBorderBox) + sizeIsAffected = checkPropertyName(affectingPropsXContentBox, propertyName); + } + return sizeIsAffected; + } + + + //==== Update ====// + + /** + * Sets the attribute values of the viewport element to the values from the target element. + * The value of a attribute is only set if the attribute is whitelisted. + * @attrs attrs The array of attributes which shall be set or undefined if all whitelisted shall be set. + */ + function updateViewportAttrsFromTarget(attrs) { + attrs = attrs || _viewportAttrsFromTarget; + each(attrs, function (index, attr) { + if (COMPATIBILITY.inA(attr, _viewportAttrsFromTarget) > -1) { + var targetAttr = _targetElement.attr(attr); + if(type(targetAttr) == TYPES.s) { + _viewportElement.attr(attr, targetAttr); + } + else { + _viewportElement.removeAttr(attr); + } + } + }); + } + + /** + * Updates the variables and size of the textarea element, and manages the scroll on new line or new character. + */ + function textareaUpdate() { + if (!_sleeping) { + var wrapAttrOff = !_textareaAutoWrappingCache; + var minWidth = _viewportSize.w; + var minHeight = _viewportSize.h; + var css = {}; + var doMeasure = _widthAutoCache || wrapAttrOff; + var origWidth; + var width; + var origHeight; + var height; + + //reset min size + css[_strMinMinus + _strWidth] = _strEmpty; + css[_strMinMinus + _strHeight] = _strEmpty; + + //set width auto + css[_strWidth] = _strAuto; + _targetElement.css(css); + + //measure width + origWidth = _targetElementNative[LEXICON.oW]; + width = doMeasure ? MATH.max(origWidth, _targetElementNative[LEXICON.sW] - 1) : 1; + /*width += (_widthAutoCache ? _marginX + (!_isBorderBox ? wrapAttrOff ? 0 : _paddingX + _borderX : 0) : 0);*/ + + //set measured width + css[_strWidth] = _widthAutoCache ? _strAuto /*width*/ : _strHundredPercent; + css[_strMinMinus + _strWidth] = _strHundredPercent; + + //set height auto + css[_strHeight] = _strAuto; + _targetElement.css(css); + + //measure height + origHeight = _targetElementNative[LEXICON.oH]; + height = MATH.max(origHeight, _targetElementNative[LEXICON.sH] - 1); + + //append correct size values + css[_strWidth] = width; + css[_strHeight] = height; + _textareaCoverElement.css(css); + + //apply min width / min height to prevent textarea collapsing + css[_strMinMinus + _strWidth] = minWidth /*+ (!_isBorderBox && _widthAutoCache ? _paddingX + _borderX : 0)*/; + css[_strMinMinus + _strHeight] = minHeight /*+ (!_isBorderBox && _heightAutoCache ? _paddingY + _borderY : 0)*/; + _targetElement.css(css); + + return { + _originalWidth: origWidth, + _originalHeight: origHeight, + _dynamicWidth: width, + _dynamicHeight: height + }; + } + } + + /** + * Updates the plugin and DOM to the current options. + * This method should only be called if a update is 100% required. + * @param updateHints A objects which contains hints for this update: + * { + * _hostSizeChanged : boolean, + * _contentSizeChanged : boolean, + * _force : boolean, == preventSwallowing + * _changedOptions : { }, == preventSwallowing && preventSleep + * } + */ + function update(updateHints) { + clearTimeout(_swallowedUpdateTimeout); + updateHints = updateHints || {}; + _swallowedUpdateHints._hostSizeChanged |= updateHints._hostSizeChanged; + _swallowedUpdateHints._contentSizeChanged |= updateHints._contentSizeChanged; + _swallowedUpdateHints._force |= updateHints._force; + + var now = COMPATIBILITY.now(); + var hostSizeChanged = !!_swallowedUpdateHints._hostSizeChanged; + var contentSizeChanged = !!_swallowedUpdateHints._contentSizeChanged; + var force = !!_swallowedUpdateHints._force; + var changedOptions = updateHints._changedOptions; + var swallow = _swallowUpdateLag > 0 && _initialized && !_destroyed && !force && !changedOptions && (now - _lastUpdateTime) < _swallowUpdateLag && (!_heightAutoCache && !_widthAutoCache); + var displayIsHidden; + + if (swallow) + _swallowedUpdateTimeout = setTimeout(update, _swallowUpdateLag); + + //abort update due to: + //destroyed + //swallowing + //sleeping + //host is hidden or has false display + if (_destroyed || swallow || (_sleeping && !changedOptions) || (_initialized && !force && (displayIsHidden = _hostElement.is(':hidden'))) || _hostElement.css('display') === 'inline') + return; + + _lastUpdateTime = now; + _swallowedUpdateHints = {}; + + //if scrollbar styling is possible and native scrollbars aren't overlaid the scrollbar styling will be applied which hides the native scrollbars completely. + if (_nativeScrollbarStyling && !(_nativeScrollbarIsOverlaid.x && _nativeScrollbarIsOverlaid.y)) { + //native scrollbars are hidden, so change the values to zero + _nativeScrollbarSize.x = 0; + _nativeScrollbarSize.y = 0; + } + else { + //refresh native scrollbar size (in case of zoom) + _nativeScrollbarSize = extendDeep({}, globals.nativeScrollbarSize); + } + + // Scrollbar padding is needed for firefox, because firefox hides scrollbar automatically if the size of the div is too small. + // The calculation: [scrollbar size +3 *3] + // (+3 because of possible decoration e.g. borders, margins etc., but only if native scrollbar is NOT a overlaid scrollbar) + // (*3 because (1)increase / (2)decrease -button and (3)resize handle) + _nativeScrollbarMinSize = { + x: (_nativeScrollbarSize.x + (_nativeScrollbarIsOverlaid.x ? 0 : 3)) * 3, + y: (_nativeScrollbarSize.y + (_nativeScrollbarIsOverlaid.y ? 0 : 3)) * 3 + }; + + //changedOptions = changedOptions || { }; + //freezeResizeObserver(_sizeObserverElement, true); + //freezeResizeObserver(_sizeAutoObserverElement, true); + + var checkCacheAutoForce = function () { + return checkCache.apply(this, [].slice.call(arguments).concat([force])); + }; + + //save current scroll offset + var currScroll = { + x: _viewportElement[_strScrollLeft](), + y: _viewportElement[_strScrollTop]() + }; + + var currentPreparedOptionsScrollbars = _currentPreparedOptions.scrollbars; + var currentPreparedOptionsTextarea = _currentPreparedOptions.textarea; + + //scrollbars visibility: + var scrollbarsVisibility = currentPreparedOptionsScrollbars.visibility; + var scrollbarsVisibilityChanged = checkCacheAutoForce(scrollbarsVisibility, _scrollbarsVisibilityCache); + + //scrollbars autoHide: + var scrollbarsAutoHide = currentPreparedOptionsScrollbars.autoHide; + var scrollbarsAutoHideChanged = checkCacheAutoForce(scrollbarsAutoHide, _scrollbarsAutoHideCache); + + //scrollbars click scrolling + var scrollbarsClickScrolling = currentPreparedOptionsScrollbars.clickScrolling; + var scrollbarsClickScrollingChanged = checkCacheAutoForce(scrollbarsClickScrolling, _scrollbarsClickScrollingCache); + + //scrollbars drag scrolling + var scrollbarsDragScrolling = currentPreparedOptionsScrollbars.dragScrolling; + var scrollbarsDragScrollingChanged = checkCacheAutoForce(scrollbarsDragScrolling, _scrollbarsDragScrollingCache); + + //className + var className = _currentPreparedOptions.className; + var classNameChanged = checkCacheAutoForce(className, _classNameCache); + + //resize + var resize = _currentPreparedOptions.resize; + var resizeChanged = checkCacheAutoForce(resize, _resizeCache) && !_isBody; //body can't be resized since the window itself acts as resize possibility. + + //paddingAbsolute + var paddingAbsolute = _currentPreparedOptions.paddingAbsolute; + var paddingAbsoluteChanged = checkCacheAutoForce(paddingAbsolute, _paddingAbsoluteCache); + + //clipAlways + var clipAlways = _currentPreparedOptions.clipAlways; + var clipAlwaysChanged = checkCacheAutoForce(clipAlways, _clipAlwaysCache); + + //sizeAutoCapable + var sizeAutoCapable = _currentPreparedOptions.sizeAutoCapable && !_isBody; //body can never be size auto, because it shall be always as big as the viewport. + var sizeAutoCapableChanged = checkCacheAutoForce(sizeAutoCapable, _sizeAutoCapableCache); + + //showNativeScrollbars + var ignoreOverlayScrollbarHiding = _currentPreparedOptions.nativeScrollbarsOverlaid.showNativeScrollbars; + var ignoreOverlayScrollbarHidingChanged = checkCacheAutoForce(ignoreOverlayScrollbarHiding, _ignoreOverlayScrollbarHidingCache); + + //autoUpdate + var autoUpdate = _currentPreparedOptions.autoUpdate; + var autoUpdateChanged = checkCacheAutoForce(autoUpdate, _autoUpdateCache); + + //overflowBehavior + var overflowBehavior = _currentPreparedOptions.overflowBehavior; + var overflowBehaviorChanged = checkCacheAutoForce(overflowBehavior, _overflowBehaviorCache, force); + + //dynWidth: + var textareaDynWidth = currentPreparedOptionsTextarea.dynWidth; + var textareaDynWidthChanged = checkCacheAutoForce(_textareaDynWidthCache, textareaDynWidth); + + //dynHeight: + var textareaDynHeight = currentPreparedOptionsTextarea.dynHeight; + var textareaDynHeightChanged = checkCacheAutoForce(_textareaDynHeightCache, textareaDynHeight); + + //scrollbars visibility + _scrollbarsAutoHideNever = scrollbarsAutoHide === 'n'; + _scrollbarsAutoHideScroll = scrollbarsAutoHide === 's'; + _scrollbarsAutoHideMove = scrollbarsAutoHide === 'm'; + _scrollbarsAutoHideLeave = scrollbarsAutoHide === 'l'; + + //scrollbars autoHideDelay + _scrollbarsAutoHideDelay = currentPreparedOptionsScrollbars.autoHideDelay; + + //old className + _oldClassName = _classNameCache; + + //resize + _resizeNone = resize === 'n'; + _resizeBoth = resize === 'b'; + _resizeHorizontal = resize === 'h'; + _resizeVertical = resize === 'v'; + + //normalizeRTL + _normalizeRTLCache = _currentPreparedOptions.normalizeRTL; + + //ignore overlay scrollbar hiding + ignoreOverlayScrollbarHiding = ignoreOverlayScrollbarHiding && (_nativeScrollbarIsOverlaid.x && _nativeScrollbarIsOverlaid.y); + + //refresh options cache + _scrollbarsVisibilityCache = scrollbarsVisibility; + _scrollbarsAutoHideCache = scrollbarsAutoHide; + _scrollbarsClickScrollingCache = scrollbarsClickScrolling; + _scrollbarsDragScrollingCache = scrollbarsDragScrolling; + _classNameCache = className; + _resizeCache = resize; + _paddingAbsoluteCache = paddingAbsolute; + _clipAlwaysCache = clipAlways; + _sizeAutoCapableCache = sizeAutoCapable; + _ignoreOverlayScrollbarHidingCache = ignoreOverlayScrollbarHiding; + _autoUpdateCache = autoUpdate; + _overflowBehaviorCache = extendDeep({}, overflowBehavior); + _textareaDynWidthCache = textareaDynWidth; + _textareaDynHeightCache = textareaDynHeight; + _hasOverflowCache = _hasOverflowCache || { x: false, y: false }; + + //set correct class name to the host element + if (classNameChanged) { + removeClass(_hostElement, _oldClassName + _strSpace + _classNameThemeNone); + addClass(_hostElement, className !== undefined && className !== null && className.length > 0 ? className : _classNameThemeNone); + } + + //set correct auto Update + if (autoUpdateChanged) { + if (autoUpdate === true) { + disconnectMutationObservers(); + autoUpdateLoop.add(_base); + } + else if (autoUpdate === null) { + if (_autoUpdateRecommended) { + disconnectMutationObservers(); + autoUpdateLoop.add(_base); + } + else { + autoUpdateLoop.remove(_base); + connectMutationObservers(); + } + } + else { + autoUpdateLoop.remove(_base); + connectMutationObservers(); + } + } + + //activate or deactivate size auto capability + if (sizeAutoCapableChanged) { + if (sizeAutoCapable) { + if (!_contentGlueElement) { + _contentGlueElement = FRAMEWORK(generateDiv(_classNameContentGlueElement)); + _paddingElement.before(_contentGlueElement); + } + else { + _contentGlueElement.show(); + } + if (_sizeAutoObserverAdded) { + _sizeAutoObserverElement.show(); + } + else { + _sizeAutoObserverElement = FRAMEWORK(generateDiv(_classNameSizeAutoObserverElement)); + _sizeAutoObserverElementNative = _sizeAutoObserverElement[0]; + + _contentGlueElement.before(_sizeAutoObserverElement); + var oldSize = { w: -1, h: -1 }; + setupResizeObserver(_sizeAutoObserverElement, function () { + var newSize = { + w: _sizeAutoObserverElementNative[LEXICON.oW], + h: _sizeAutoObserverElementNative[LEXICON.oH] + }; + if (checkCache(newSize, oldSize)) { + if (_initialized && (_heightAutoCache && newSize.h > 0) || (_widthAutoCache && newSize.w > 0)) { + update(); + } + else if (_initialized && (!_heightAutoCache && newSize.h === 0) || (!_widthAutoCache && newSize.w === 0)) { + update(); + } + } + oldSize = newSize; + }); + _sizeAutoObserverAdded = true; + //fix heightAuto detector bug if height is fixed but contentHeight is 0. + //the probability this bug will ever happen is very very low, thats why its ok if we use calc which isn't supported in IE8. + if (_cssCalc !== null) + _sizeAutoObserverElement.css(_strHeight, _cssCalc + '(100% + 1px)'); + } + } + else { + if (_sizeAutoObserverAdded) + _sizeAutoObserverElement.hide(); + if (_contentGlueElement) + _contentGlueElement.hide(); + } + } + + //if force, update all resizeObservers too + if (force) { + _sizeObserverElement.find('*').trigger(_strScroll); + if (_sizeAutoObserverAdded) + _sizeAutoObserverElement.find('*').trigger(_strScroll); + } + + //display hidden: + displayIsHidden = displayIsHidden === undefined ? _hostElement.is(':hidden') : displayIsHidden; + var displayIsHiddenChanged = checkCacheAutoForce(displayIsHidden, _displayIsHiddenCache); + + //textarea AutoWrapping: + var textareaAutoWrapping = _isTextarea ? _targetElement.attr('wrap') !== 'off' : false; + var textareaAutoWrappingChanged = checkCacheAutoForce(textareaAutoWrapping, _textareaAutoWrappingCache); + + //detect direction: + var cssDirection = _hostElement.css('direction'); + var cssDirectionChanged = checkCacheAutoForce(cssDirection, _cssDirectionCache); + + //detect box-sizing: + var boxSizing = _hostElement.css('box-sizing'); + var boxSizingChanged = checkCacheAutoForce(boxSizing, _cssBoxSizingCache); + + //detect padding: + var padding = { + c: force, + t: parseToZeroOrNumber(_hostElement.css(_strPaddingMinus + _strTop)), + r: parseToZeroOrNumber(_hostElement.css(_strPaddingMinus + _strRight)), + b: parseToZeroOrNumber(_hostElement.css(_strPaddingMinus + _strBottom)), + l: parseToZeroOrNumber(_hostElement.css(_strPaddingMinus + _strLeft)) + }; + + //width + height auto detecting var: + var sizeAutoObserverElementBCRect; + //exception occurs in IE8 sometimes (unknown exception) + try { + sizeAutoObserverElementBCRect = _sizeAutoObserverAdded ? _sizeAutoObserverElementNative[LEXICON.bCR]() : null; + } catch (ex) { + return; + } + + _isRTL = cssDirection === 'rtl'; + _isBorderBox = (boxSizing === 'border-box'); + var isRTLLeft = _isRTL ? _strLeft : _strRight; + var isRTLRight = _isRTL ? _strRight : _strLeft; + + //detect width auto: + var widthAutoResizeDetection = false; + var widthAutoObserverDetection = (_sizeAutoObserverAdded && (_hostElement.css(_strFloat) !== 'none' /*|| _isTextarea */)) ? (MATH.round(sizeAutoObserverElementBCRect.right - sizeAutoObserverElementBCRect.left) === 0) && (!paddingAbsolute ? (_hostElementNative[LEXICON.cW] - _paddingX) > 0 : true) : false; + if (sizeAutoCapable && !widthAutoObserverDetection) { + var tmpCurrHostWidth = _hostElementNative[LEXICON.oW]; + var tmpCurrContentGlueWidth = _contentGlueElement.css(_strWidth); + _contentGlueElement.css(_strWidth, _strAuto); + + var tmpNewHostWidth = _hostElementNative[LEXICON.oW]; + _contentGlueElement.css(_strWidth, tmpCurrContentGlueWidth); + widthAutoResizeDetection = tmpCurrHostWidth !== tmpNewHostWidth; + if (!widthAutoResizeDetection) { + _contentGlueElement.css(_strWidth, tmpCurrHostWidth + 1); + tmpNewHostWidth = _hostElementNative[LEXICON.oW]; + _contentGlueElement.css(_strWidth, tmpCurrContentGlueWidth); + widthAutoResizeDetection = tmpCurrHostWidth !== tmpNewHostWidth; + } + } + var widthAuto = (widthAutoObserverDetection || widthAutoResizeDetection) && sizeAutoCapable && !displayIsHidden; + var widthAutoChanged = checkCacheAutoForce(widthAuto, _widthAutoCache); + var wasWidthAuto = !widthAuto && _widthAutoCache; + + //detect height auto: + var heightAuto = _sizeAutoObserverAdded && sizeAutoCapable && !displayIsHidden ? (MATH.round(sizeAutoObserverElementBCRect.bottom - sizeAutoObserverElementBCRect.top) === 0) /* && (!paddingAbsolute && (_msieVersion > 9 || !_msieVersion) ? true : true) */ : false; + var heightAutoChanged = checkCacheAutoForce(heightAuto, _heightAutoCache); + var wasHeightAuto = !heightAuto && _heightAutoCache; + + //detect border: + //we need the border only if border box and auto size + var strMinusWidth = '-' + _strWidth; + var updateBorderX = (widthAuto && _isBorderBox) || !_isBorderBox; + var updateBorderY = (heightAuto && _isBorderBox) || !_isBorderBox; + var border = { + c: force, + t: updateBorderY ? parseToZeroOrNumber(_hostElement.css(_strBorderMinus + _strTop + strMinusWidth), true) : 0, + r: updateBorderX ? parseToZeroOrNumber(_hostElement.css(_strBorderMinus + _strRight + strMinusWidth), true) : 0, + b: updateBorderY ? parseToZeroOrNumber(_hostElement.css(_strBorderMinus + _strBottom + strMinusWidth), true) : 0, + l: updateBorderX ? parseToZeroOrNumber(_hostElement.css(_strBorderMinus + _strLeft + strMinusWidth), true) : 0 + }; + + //detect margin: + var margin = { + c: force, + t: parseToZeroOrNumber(_hostElement.css(_strMarginMinus + _strTop)), + r: parseToZeroOrNumber(_hostElement.css(_strMarginMinus + _strRight)), + b: parseToZeroOrNumber(_hostElement.css(_strMarginMinus + _strBottom)), + l: parseToZeroOrNumber(_hostElement.css(_strMarginMinus + _strLeft)) + }; + + //detect css max width & height: + var cssMaxValue = { + h: String(_hostElement.css(_strMaxMinus + _strHeight)), + w: String(_hostElement.css(_strMaxMinus + _strWidth)) + }; + + //vars to apply correct css + var contentElementCSS = {}; + var contentGlueElementCSS = {}; + + //funcs + var getHostSize = function () { + //has to be clientSize because offsetSize respect borders + return { + w: _hostElementNative[LEXICON.cW], + h: _hostElementNative[LEXICON.cH] + }; + }; + var getViewportSize = function () { + //viewport size is padding container because it never has padding, margin and a border + //determine zoom rounding error -> sometimes scrollWidth/Height is smaller than clientWidth/Height + //if this happens add the difference to the viewportSize to compensate the rounding error + return { + w: _paddingElementNative[LEXICON.oW] + MATH.max(0, _contentElementNative[LEXICON.cW] - _contentElementNative[LEXICON.sW]), + h: _paddingElementNative[LEXICON.oH] + MATH.max(0, _contentElementNative[LEXICON.cH] - _contentElementNative[LEXICON.sH]) + }; + }; + + //set info for padding + var paddingAbsoluteX = _paddingX = padding.l + padding.r; + var paddingAbsoluteY = _paddingY = padding.t + padding.b; + paddingAbsoluteX *= paddingAbsolute ? 1 : 0; + paddingAbsoluteY *= paddingAbsolute ? 1 : 0; + padding.c = checkCacheAutoForce(padding, _cssPaddingCache); + + //set info for border + _borderX = border.l + border.r; + _borderY = border.t + border.b; + border.c = checkCacheAutoForce(border, _cssBorderCache); + + //set info for margin + _marginX = margin.l + margin.r; + _marginY = margin.t + margin.b; + margin.c = checkCacheAutoForce(margin, _cssMarginCache); + + //set info for css max value + cssMaxValue.ih = parseToZeroOrNumber(cssMaxValue.h); //ih = integer height + cssMaxValue.iw = parseToZeroOrNumber(cssMaxValue.w); //iw = integer width + cssMaxValue.ch = cssMaxValue.h.indexOf('px') > -1; //ch = correct height + cssMaxValue.cw = cssMaxValue.w.indexOf('px') > -1; //cw = correct width + cssMaxValue.c = checkCacheAutoForce(cssMaxValue, _cssMaxValueCache); + + //refresh cache + _displayIsHiddenCache = displayIsHidden; + _textareaAutoWrappingCache = textareaAutoWrapping; + _cssDirectionCache = cssDirection; + _cssBoxSizingCache = boxSizing; + _widthAutoCache = widthAuto; + _heightAutoCache = heightAuto; + _cssPaddingCache = padding; + _cssBorderCache = border; + _cssMarginCache = margin; + _cssMaxValueCache = cssMaxValue; + + //IEFix direction changed + if (cssDirectionChanged && _sizeAutoObserverAdded) + _sizeAutoObserverElement.css(_strFloat, isRTLRight); + + //apply padding: + if (padding.c || cssDirectionChanged || paddingAbsoluteChanged || widthAutoChanged || heightAutoChanged || boxSizingChanged || sizeAutoCapableChanged) { + var paddingElementCSS = {}; + var textareaCSS = {}; + setTopRightBottomLeft(contentGlueElementCSS, _strMarginMinus, [-padding.t, -padding.r, -padding.b, -padding.l]); + if (paddingAbsolute) { + setTopRightBottomLeft(paddingElementCSS, _strEmpty, [padding.t, padding.r, padding.b, padding.l]); + if (_isTextarea) + setTopRightBottomLeft(textareaCSS, _strPaddingMinus); + else + setTopRightBottomLeft(contentElementCSS, _strPaddingMinus); + } + else { + setTopRightBottomLeft(paddingElementCSS, _strEmpty); + if (_isTextarea) + setTopRightBottomLeft(textareaCSS, _strPaddingMinus, [padding.t, padding.r, padding.b, padding.l]); + else + setTopRightBottomLeft(contentElementCSS, _strPaddingMinus, [padding.t, padding.r, padding.b, padding.l]); + } + _paddingElement.css(paddingElementCSS); + _targetElement.css(textareaCSS); + } + + //viewport size is padding container because it never has padding, margin and a border. + _viewportSize = getViewportSize(); + + //update Textarea + var textareaSize = _isTextarea ? textareaUpdate() : false; + var textareaSizeChanged = _isTextarea && checkCacheAutoForce(textareaSize, _textareaSizeCache); + var textareaDynOrigSize = _isTextarea && textareaSize ? { + w: textareaDynWidth ? textareaSize._dynamicWidth : textareaSize._originalWidth, + h: textareaDynHeight ? textareaSize._dynamicHeight : textareaSize._originalHeight + } : {}; + _textareaSizeCache = textareaSize; + + //fix height auto / width auto in cooperation with current padding & boxSizing behavior: + if (heightAuto && (heightAutoChanged || paddingAbsoluteChanged || boxSizingChanged || cssMaxValue.c || padding.c || border.c)) { + /* + if (cssMaxValue.ch) + contentElementCSS[_strMaxMinus + _strHeight] = + (cssMaxValue.ch ? (cssMaxValue.ih - paddingAbsoluteY + (_isBorderBox ? -_borderY : _paddingY)) + : _strEmpty); + */ + contentElementCSS[_strHeight] = _strAuto; + } + else if (heightAutoChanged || paddingAbsoluteChanged) { + contentElementCSS[_strMaxMinus + _strHeight] = _strEmpty; + contentElementCSS[_strHeight] = _strHundredPercent; + } + if (widthAuto && (widthAutoChanged || paddingAbsoluteChanged || boxSizingChanged || cssMaxValue.c || padding.c || border.c || cssDirectionChanged)) { + /* + if (cssMaxValue.cw) + contentElementCSS[_strMaxMinus + _strWidth] = + (cssMaxValue.cw ? (cssMaxValue.iw - paddingAbsoluteX + (_isBorderBox ? -_borderX : _paddingX)) + + (_nativeScrollbarIsOverlaid.y ? _overlayScrollbarDummySize.y : 0) + : _strEmpty); + */ + contentElementCSS[_strWidth] = _strAuto; + contentGlueElementCSS[_strMaxMinus + _strWidth] = _strHundredPercent; //IE Fix + } + else if (widthAutoChanged || paddingAbsoluteChanged) { + contentElementCSS[_strMaxMinus + _strWidth] = _strEmpty; + contentElementCSS[_strWidth] = _strHundredPercent; + contentElementCSS[_strFloat] = _strEmpty; + contentGlueElementCSS[_strMaxMinus + _strWidth] = _strEmpty; //IE Fix + } + if (widthAuto) { + if (!cssMaxValue.cw) + contentElementCSS[_strMaxMinus + _strWidth] = _strEmpty; + //textareaDynOrigSize.w || _strAuto :: doesnt works because applied margin will shift width + contentGlueElementCSS[_strWidth] = _strAuto; + + contentElementCSS[_strWidth] = _strAuto; + contentElementCSS[_strFloat] = isRTLRight; + } + else { + contentGlueElementCSS[_strWidth] = _strEmpty; + } + if (heightAuto) { + if (!cssMaxValue.ch) + contentElementCSS[_strMaxMinus + _strHeight] = _strEmpty; + //textareaDynOrigSize.h || _contentElementNative[LEXICON.cH] :: use for anti scroll jumping + contentGlueElementCSS[_strHeight] = textareaDynOrigSize.h || _contentElementNative[LEXICON.cH]; + } + else { + contentGlueElementCSS[_strHeight] = _strEmpty; + } + if (sizeAutoCapable) + _contentGlueElement.css(contentGlueElementCSS); + _contentElement.css(contentElementCSS); + + //CHECKPOINT HERE ~ + contentElementCSS = {}; + contentGlueElementCSS = {}; + + //if [content(host) client / scroll size, or target element direction, or content(host) max-sizes] changed, or force is true + if (hostSizeChanged || contentSizeChanged || textareaSizeChanged || cssDirectionChanged || boxSizingChanged || paddingAbsoluteChanged || widthAutoChanged || widthAuto || heightAutoChanged || heightAuto || cssMaxValue.c || ignoreOverlayScrollbarHidingChanged || overflowBehaviorChanged || clipAlwaysChanged || resizeChanged || scrollbarsVisibilityChanged || scrollbarsAutoHideChanged || scrollbarsDragScrollingChanged || scrollbarsClickScrollingChanged || textareaDynWidthChanged || textareaDynHeightChanged || textareaAutoWrappingChanged) { + var strOverflow = 'overflow'; + var strOverflowX = strOverflow + '-x'; + var strOverflowY = strOverflow + '-y'; + var strHidden = 'hidden'; + var strVisible = 'visible'; + + //Reset the viewport (very important for natively overlaid scrollbars and zoom change + //don't change the overflow prop as it is very expensive and affects performance !A LOT! + if(!_nativeScrollbarStyling) { + var viewportElementResetCSS = {}; + var resetXTmp = _hasOverflowCache.y && _hideOverflowCache.ys && !ignoreOverlayScrollbarHiding ? (_nativeScrollbarIsOverlaid.y ? _viewportElement.css(isRTLLeft) : -_nativeScrollbarSize.y) : 0; + var resetBottomTmp = _hasOverflowCache.x && _hideOverflowCache.xs && !ignoreOverlayScrollbarHiding ? (_nativeScrollbarIsOverlaid.x ? _viewportElement.css(_strBottom) : -_nativeScrollbarSize.x) : 0; + setTopRightBottomLeft(viewportElementResetCSS, _strEmpty); + _viewportElement.css(viewportElementResetCSS); + } + + //measure several sizes: + var contentMeasureElement = getContentMeasureElement(); + //in Firefox content element has to have overflow hidden, else element margins aren't calculated properly, this element prevents this bug, but only if scrollbars aren't overlaid + var contentSize = { + //use clientSize because natively overlaidScrollbars add borders + w: textareaDynOrigSize.w || contentMeasureElement[LEXICON.cW], + h: textareaDynOrigSize.h || contentMeasureElement[LEXICON.cH] + }; + var scrollSize = { + w: contentMeasureElement[LEXICON.sW], + h: contentMeasureElement[LEXICON.sH] + }; + + //apply the correct viewport style and measure viewport size + if(!_nativeScrollbarStyling) { + viewportElementResetCSS[_strBottom] = wasHeightAuto ? _strEmpty : resetBottomTmp; + viewportElementResetCSS[isRTLLeft] = wasWidthAuto ? _strEmpty : resetXTmp; + _viewportElement.css(viewportElementResetCSS); + } + _viewportSize = getViewportSize(); + + //measure and correct several sizes + var hostSize = getHostSize(); + var contentGlueSize = { + //client/scrollSize + AbsolutePadding -> because padding is only applied to the paddingElement if its absolute, so you have to add it manually + //hostSize is clientSize -> so padding should be added manually, right? FALSE! Because content glue is inside hostElement, so we don't have to worry about padding + w: MATH.max((widthAuto ? contentSize.w : scrollSize.w) + paddingAbsoluteX, hostSize.w), + h: MATH.max((heightAuto ? contentSize.h : scrollSize.h) + paddingAbsoluteY, hostSize.h) + }; + contentGlueSize.c = checkCacheAutoForce(contentGlueSize, _contentGlueSizeCache); + _contentGlueSizeCache = contentGlueSize; + + //apply correct contentGlue size + if (sizeAutoCapable) { + //size contentGlue correctly to make sure the element has correct size if the sizing switches to auto + if (contentGlueSize.c || (heightAuto || widthAuto)) { + contentGlueElementCSS[_strWidth] = contentGlueSize.w; + contentGlueElementCSS[_strHeight] = contentGlueSize.h; + + //textarea-sizes are already calculated correctly at this point + if (!_isTextarea) { + contentSize = { + //use clientSize because natively overlaidScrollbars add borders + w: contentMeasureElement[LEXICON.cW], + h: contentMeasureElement[LEXICON.cH] + }; + } + } + var textareaCoverCSS = {}; + var setContentGlueElementCSSfunction = function (horizontal) { + var scrollbarVars = getScrollbarVars(horizontal); + var wh = scrollbarVars._w_h; + var strWH = scrollbarVars._width_height; + var autoSize = horizontal ? widthAuto : heightAuto; + var borderSize = horizontal ? _borderX : _borderY; + var paddingSize = horizontal ? _paddingX : _paddingY; + var marginSize = horizontal ? _marginX : _marginY; + var maxSize = contentGlueElementCSS[strWH] + (_isBorderBox ? borderSize : -paddingSize); + + //make contentGlue size -1 if element is not auto sized, to make sure that a resize event happens when the element shrinks + if (!autoSize || (!autoSize && border.c)) + contentGlueElementCSS[strWH] = hostSize[wh] - (_isBorderBox ? 0 : paddingSize + borderSize) - 1 - marginSize; + + //if size is auto and host is same size as max size, make content glue size +1 to make sure size changes will be detected + if (autoSize && cssMaxValue['c' + wh] && cssMaxValue['i' + wh] === maxSize) + contentGlueElementCSS[strWH] = maxSize + (_isBorderBox ? 0 : paddingSize) + 1; + + //if size is auto and host is smaller than size as min size, make content glue size -1 to make sure size changes will be detected (this is only needed if padding is 0) + if (autoSize && (contentSize[wh] < _viewportSize[wh]) && (horizontal && _isTextarea ? !textareaAutoWrapping : true)) { + if (_isTextarea) + textareaCoverCSS[strWH] = parseToZeroOrNumber(_textareaCoverElement.css(strWH)) - 1; + contentGlueElementCSS[strWH] -= 1; + } + + //make sure content glue size is at least 1 + if (contentSize[wh] > 0) + contentGlueElementCSS[strWH] = MATH.max(1, contentGlueElementCSS[strWH]); + }; + setContentGlueElementCSSfunction(true); + setContentGlueElementCSSfunction(false); + + if (_isTextarea) + _textareaCoverElement.css(textareaCoverCSS); + _contentGlueElement.css(contentGlueElementCSS); + } + if (widthAuto) + contentElementCSS[_strWidth] = _strHundredPercent; + if (widthAuto && !_isBorderBox && !_mutationObserversConnected) + contentElementCSS[_strFloat] = 'none'; + + //apply and reset content style + _contentElement.css(contentElementCSS); + contentElementCSS = {}; + + //measure again, but this time all correct sizes: + var contentScrollSize = { + w: contentMeasureElement[LEXICON.sW], + h: contentMeasureElement[LEXICON.sH], + }; + contentScrollSize.c = contentSizeChanged = checkCacheAutoForce(contentScrollSize, _contentScrollSizeCache); + _contentScrollSizeCache = contentScrollSize; + + //refresh viewport size after correct measuring + _viewportSize = getViewportSize(); + + hostSize = getHostSize(); + hostSizeChanged = checkCacheAutoForce(hostSize, _hostSizeCache); + _hostSizeCache = hostSize; + + var hideOverflowForceTextarea = _isTextarea && (_viewportSize.w === 0 || _viewportSize.h === 0); + var previousOverflowAmount = _overflowAmountCache; + var overflowBehaviorIsVS = {}; + var overflowBehaviorIsVH = {}; + var overflowBehaviorIsS = {}; + var overflowAmount = {}; + var hasOverflow = {}; + var hideOverflow = {}; + var canScroll = {}; + var viewportRect = _paddingElementNative[LEXICON.bCR](); + var setOverflowVariables = function (horizontal) { + var scrollbarVars = getScrollbarVars(horizontal); + var scrollbarVarsInverted = getScrollbarVars(!horizontal); + var xyI = scrollbarVarsInverted._x_y; + var xy = scrollbarVars._x_y; + var wh = scrollbarVars._w_h; + var widthHeight = scrollbarVars._width_height; + var scrollMax = _strScroll + scrollbarVars._Left_Top + 'Max'; + var fractionalOverflowAmount = viewportRect[widthHeight] ? MATH.abs(viewportRect[widthHeight] - _viewportSize[wh]) : 0; + var checkFractionalOverflowAmount = previousOverflowAmount && previousOverflowAmount[xy] > 0 && _viewportElementNative[scrollMax] === 0; + overflowBehaviorIsVS[xy] = overflowBehavior[xy] === 'v-s'; + overflowBehaviorIsVH[xy] = overflowBehavior[xy] === 'v-h'; + overflowBehaviorIsS[xy] = overflowBehavior[xy] === 's'; + overflowAmount[xy] = MATH.max(0, MATH.round((contentScrollSize[wh] - _viewportSize[wh]) * 100) / 100); + overflowAmount[xy] *= (hideOverflowForceTextarea || (checkFractionalOverflowAmount && fractionalOverflowAmount > 0 && fractionalOverflowAmount < 1)) ? 0 : 1; + hasOverflow[xy] = overflowAmount[xy] > 0; + + //hideOverflow: + //x || y : true === overflow is hidden by "overflow: scroll" OR "overflow: hidden" + //xs || ys : true === overflow is hidden by "overflow: scroll" + hideOverflow[xy] = overflowBehaviorIsVS[xy] || overflowBehaviorIsVH[xy] ? (hasOverflow[xyI] && !overflowBehaviorIsVS[xyI] && !overflowBehaviorIsVH[xyI]) : hasOverflow[xy]; + hideOverflow[xy + 's'] = hideOverflow[xy] ? (overflowBehaviorIsS[xy] || overflowBehaviorIsVS[xy]) : false; + + canScroll[xy] = hasOverflow[xy] && hideOverflow[xy + 's']; + }; + setOverflowVariables(true); + setOverflowVariables(false); + + overflowAmount.c = checkCacheAutoForce(overflowAmount, _overflowAmountCache); + _overflowAmountCache = overflowAmount; + hasOverflow.c = checkCacheAutoForce(hasOverflow, _hasOverflowCache); + _hasOverflowCache = hasOverflow; + hideOverflow.c = checkCacheAutoForce(hideOverflow, _hideOverflowCache); + _hideOverflowCache = hideOverflow; + + //if native scrollbar is overlay at x OR y axis, prepare DOM + if (_nativeScrollbarIsOverlaid.x || _nativeScrollbarIsOverlaid.y) { + var borderDesign = 'px solid transparent'; + var contentArrangeElementCSS = {}; + var arrangeContent = {}; + var arrangeChanged = force; + var setContentElementCSS; + + if (hasOverflow.x || hasOverflow.y) { + arrangeContent.w = _nativeScrollbarIsOverlaid.y && hasOverflow.y ? contentScrollSize.w + _overlayScrollbarDummySize.y : _strEmpty; + arrangeContent.h = _nativeScrollbarIsOverlaid.x && hasOverflow.x ? contentScrollSize.h + _overlayScrollbarDummySize.x : _strEmpty; + arrangeChanged = checkCacheAutoForce(arrangeContent, _arrangeContentSizeCache); + _arrangeContentSizeCache = arrangeContent; + } + + if (hasOverflow.c || hideOverflow.c || contentScrollSize.c || cssDirectionChanged || widthAutoChanged || heightAutoChanged || widthAuto || heightAuto || ignoreOverlayScrollbarHidingChanged) { + contentElementCSS[_strMarginMinus + isRTLRight] = contentElementCSS[_strBorderMinus + isRTLRight] = _strEmpty; + setContentElementCSS = function (horizontal) { + var scrollbarVars = getScrollbarVars(horizontal); + var scrollbarVarsInverted = getScrollbarVars(!horizontal); + var xy = scrollbarVars._x_y; + var strDirection = horizontal ? _strBottom : isRTLLeft; + var invertedAutoSize = horizontal ? heightAuto : widthAuto; + + if (_nativeScrollbarIsOverlaid[xy] && hasOverflow[xy] && hideOverflow[xy + 's']) { + contentElementCSS[_strMarginMinus + strDirection] = invertedAutoSize ? (ignoreOverlayScrollbarHiding ? _strEmpty : _overlayScrollbarDummySize[xy]) : _strEmpty; + contentElementCSS[_strBorderMinus + strDirection] = ((horizontal ? !invertedAutoSize : true) && !ignoreOverlayScrollbarHiding) ? (_overlayScrollbarDummySize[xy] + borderDesign) : _strEmpty; + } + else { + arrangeContent[scrollbarVarsInverted._w_h] = + contentElementCSS[_strMarginMinus + strDirection] = + contentElementCSS[_strBorderMinus + strDirection] = _strEmpty; + arrangeChanged = true; + } + }; + + if (_nativeScrollbarStyling) { + if (ignoreOverlayScrollbarHiding) + removeClass(_viewportElement, _classNameViewportNativeScrollbarsInvisible); + else + addClass(_viewportElement, _classNameViewportNativeScrollbarsInvisible); + } + else { + setContentElementCSS(true); + setContentElementCSS(false); + } + } + if (ignoreOverlayScrollbarHiding) { + arrangeContent.w = arrangeContent.h = _strEmpty; + arrangeChanged = true; + } + if (arrangeChanged && !_nativeScrollbarStyling) { + contentArrangeElementCSS[_strWidth] = hideOverflow.y ? arrangeContent.w : _strEmpty; + contentArrangeElementCSS[_strHeight] = hideOverflow.x ? arrangeContent.h : _strEmpty; + + if (!_contentArrangeElement) { + _contentArrangeElement = FRAMEWORK(generateDiv(_classNameContentArrangeElement)); + _viewportElement.prepend(_contentArrangeElement); + } + _contentArrangeElement.css(contentArrangeElementCSS); + } + _contentElement.css(contentElementCSS); + } + + var viewportElementCSS = {}; + var paddingElementCSS = {}; + var setViewportCSS; + if (hostSizeChanged || hasOverflow.c || hideOverflow.c || contentScrollSize.c || overflowBehaviorChanged || boxSizingChanged || ignoreOverlayScrollbarHidingChanged || cssDirectionChanged || clipAlwaysChanged || heightAutoChanged) { + viewportElementCSS[isRTLRight] = _strEmpty; + setViewportCSS = function (horizontal) { + var scrollbarVars = getScrollbarVars(horizontal); + var scrollbarVarsInverted = getScrollbarVars(!horizontal); + var xy = scrollbarVars._x_y; + var XY = scrollbarVars._X_Y; + var strDirection = horizontal ? _strBottom : isRTLLeft; + + var reset = function () { + viewportElementCSS[strDirection] = _strEmpty; + _contentBorderSize[scrollbarVarsInverted._w_h] = 0; + }; + if (hasOverflow[xy] && hideOverflow[xy + 's']) { + viewportElementCSS[strOverflow + XY] = _strScroll; + if (ignoreOverlayScrollbarHiding || _nativeScrollbarStyling) { + reset(); + } + else { + viewportElementCSS[strDirection] = -(_nativeScrollbarIsOverlaid[xy] ? _overlayScrollbarDummySize[xy] : _nativeScrollbarSize[xy]); + _contentBorderSize[scrollbarVarsInverted._w_h] = _nativeScrollbarIsOverlaid[xy] ? _overlayScrollbarDummySize[scrollbarVarsInverted._x_y] : 0; + } + } else { + viewportElementCSS[strOverflow + XY] = _strEmpty; + reset(); + } + }; + setViewportCSS(true); + setViewportCSS(false); + + // if the scroll container is too small and if there is any overflow with no overlay scrollbar (and scrollbar styling isn't possible), + // make viewport element greater in size (Firefox hide Scrollbars fix) + // because firefox starts hiding scrollbars on too small elements + // with this behavior the overflow calculation may be incorrect or the scrollbars would appear suddenly + // https://bugzilla.mozilla.org/show_bug.cgi?id=292284 + if (!_nativeScrollbarStyling + && (_viewportSize.h < _nativeScrollbarMinSize.x || _viewportSize.w < _nativeScrollbarMinSize.y) + && ((hasOverflow.x && hideOverflow.x && !_nativeScrollbarIsOverlaid.x) || (hasOverflow.y && hideOverflow.y && !_nativeScrollbarIsOverlaid.y))) { + viewportElementCSS[_strPaddingMinus + _strTop] = _nativeScrollbarMinSize.x; + viewportElementCSS[_strMarginMinus + _strTop] = -_nativeScrollbarMinSize.x; + + viewportElementCSS[_strPaddingMinus + isRTLRight] = _nativeScrollbarMinSize.y; + viewportElementCSS[_strMarginMinus + isRTLRight] = -_nativeScrollbarMinSize.y; + } + else { + viewportElementCSS[_strPaddingMinus + _strTop] = + viewportElementCSS[_strMarginMinus + _strTop] = + viewportElementCSS[_strPaddingMinus + isRTLRight] = + viewportElementCSS[_strMarginMinus + isRTLRight] = _strEmpty; + } + viewportElementCSS[_strPaddingMinus + isRTLLeft] = + viewportElementCSS[_strMarginMinus + isRTLLeft] = _strEmpty; + + //if there is any overflow (x OR y axis) and this overflow shall be hidden, make overflow hidden, else overflow visible + if ((hasOverflow.x && hideOverflow.x) || (hasOverflow.y && hideOverflow.y) || hideOverflowForceTextarea) { + //only hide if is Textarea + if (_isTextarea && hideOverflowForceTextarea) { + paddingElementCSS[strOverflowX] = + paddingElementCSS[strOverflowY] = strHidden; + } + } + else { + if (!clipAlways || (overflowBehaviorIsVH.x || overflowBehaviorIsVS.x || overflowBehaviorIsVH.y || overflowBehaviorIsVS.y)) { + //only un-hide if Textarea + if (_isTextarea) { + paddingElementCSS[strOverflowX] = + paddingElementCSS[strOverflowY] = _strEmpty; + } + viewportElementCSS[strOverflowX] = + viewportElementCSS[strOverflowY] = strVisible; + } + } + + _paddingElement.css(paddingElementCSS); + _viewportElement.css(viewportElementCSS); + viewportElementCSS = {}; + + //force soft redraw in webkit because without the scrollbars will may appear because DOM wont be redrawn under special conditions + if ((hasOverflow.c || boxSizingChanged || widthAutoChanged || heightAutoChanged) && !(_nativeScrollbarIsOverlaid.x && _nativeScrollbarIsOverlaid.y)) { + var elementStyle = _contentElementNative[LEXICON.s]; + var dump; + elementStyle.webkitTransform = 'scale(1)'; + elementStyle.display = 'run-in'; + dump = _contentElementNative[LEXICON.oH]; + elementStyle.display = _strEmpty; //|| dump; //use dump to prevent it from deletion if minify + elementStyle.webkitTransform = _strEmpty; + } + /* + //force hard redraw in webkit if native overlaid scrollbars shall appear + if (ignoreOverlayScrollbarHidingChanged && ignoreOverlayScrollbarHiding) { + _hostElement.hide(); + var dump = _hostElementNative[LEXICON.oH]; + _hostElement.show(); + } + */ + } + + //change to direction RTL and width auto Bugfix in Webkit + //without this fix, the DOM still thinks the scrollbar is LTR and thus the content is shifted to the left + contentElementCSS = {}; + if (cssDirectionChanged || widthAutoChanged || heightAutoChanged) { + if (_isRTL && widthAuto) { + var floatTmp = _contentElement.css(_strFloat); + var posLeftWithoutFloat = MATH.round(_contentElement.css(_strFloat, _strEmpty).css(_strLeft, _strEmpty).position().left); + _contentElement.css(_strFloat, floatTmp); + var posLeftWithFloat = MATH.round(_contentElement.position().left); + + if (posLeftWithoutFloat !== posLeftWithFloat) + contentElementCSS[_strLeft] = posLeftWithoutFloat; + } + else { + contentElementCSS[_strLeft] = _strEmpty; + } + } + _contentElement.css(contentElementCSS); + + //handle scroll position + if (_isTextarea && contentSizeChanged) { + var textareaInfo = getTextareaInfo(); + if (textareaInfo) { + var textareaRowsChanged = _textareaInfoCache === undefined ? true : textareaInfo._rows !== _textareaInfoCache._rows; + var cursorRow = textareaInfo._cursorRow; + var cursorCol = textareaInfo._cursorColumn; + var widestRow = textareaInfo._widestRow; + var lastRow = textareaInfo._rows; + var lastCol = textareaInfo._columns; + var cursorPos = textareaInfo._cursorPosition; + var cursorMax = textareaInfo._cursorMax; + var cursorIsLastPosition = (cursorPos >= cursorMax && _textareaHasFocus); + var textareaScrollAmount = { + x: (!textareaAutoWrapping && (cursorCol === lastCol && cursorRow === widestRow)) ? _overflowAmountCache.x : -1, + y: (textareaAutoWrapping ? cursorIsLastPosition || textareaRowsChanged && (previousOverflowAmount ? (currScroll.y === previousOverflowAmount.y) : false) : (cursorIsLastPosition || textareaRowsChanged) && cursorRow === lastRow) ? _overflowAmountCache.y : -1 + }; + currScroll.x = textareaScrollAmount.x > -1 ? (_isRTL && _normalizeRTLCache && _rtlScrollBehavior.i ? 0 : textareaScrollAmount.x) : currScroll.x; //if inverted, scroll to 0 -> normalized this means to max scroll offset. + currScroll.y = textareaScrollAmount.y > -1 ? textareaScrollAmount.y : currScroll.y; + } + _textareaInfoCache = textareaInfo; + } + if (_isRTL && _rtlScrollBehavior.i && _nativeScrollbarIsOverlaid.y && hasOverflow.x && _normalizeRTLCache) + currScroll.x += _contentBorderSize.w || 0; + if (widthAuto) + _hostElement[_strScrollLeft](0); + if (heightAuto) + _hostElement[_strScrollTop](0); + _viewportElement[_strScrollLeft](currScroll.x)[_strScrollTop](currScroll.y); + + //scrollbars management: + var scrollbarsVisibilityVisible = scrollbarsVisibility === 'v'; + var scrollbarsVisibilityHidden = scrollbarsVisibility === 'h'; + var scrollbarsVisibilityAuto = scrollbarsVisibility === 'a'; + + var showScrollbarH = COMPATIBILITY.bind(refreshScrollbarAppearance, 0, true, true, canScroll.x); + var showScrollbarV = COMPATIBILITY.bind(refreshScrollbarAppearance, 0, false, true, canScroll.y); + var hideScrollbarH = COMPATIBILITY.bind(refreshScrollbarAppearance, 0, true, false, canScroll.x); + var hideScrollbarV = COMPATIBILITY.bind(refreshScrollbarAppearance, 0, false, false, canScroll.y); + + //manage class name which indicates scrollable overflow + if (hideOverflow.x || hideOverflow.y) + addClass(_hostElement, _classNameHostOverflow); + else + removeClass(_hostElement, _classNameHostOverflow); + if (hideOverflow.x) + addClass(_hostElement, _classNameHostOverflowX); + else + removeClass(_hostElement, _classNameHostOverflowX); + if (hideOverflow.y) + addClass(_hostElement, _classNameHostOverflowY); + else + removeClass(_hostElement, _classNameHostOverflowY); + + //add or remove rtl class name for styling purposes + if (cssDirectionChanged) { + if (_isRTL) + addClass(_hostElement, _classNameHostRTL); + else + removeClass(_hostElement, _classNameHostRTL); + } + + //manage the resize feature (CSS3 resize "polyfill" for this plugin) + if (_isBody) + addClass(_hostElement, _classNameHostResizeDisabled); + if (resizeChanged) { + removeClass(_scrollbarCornerElement, [ + _classNameScrollbarCornerResize, + _classNameScrollbarCornerResizeB, + _classNameScrollbarCornerResizeH, + _classNameScrollbarCornerResizeV].join(_strSpace)); + if (_resizeNone) { + addClass(_hostElement, _classNameHostResizeDisabled); + } + else { + removeClass(_hostElement, _classNameHostResizeDisabled); + addClass(_scrollbarCornerElement, _classNameScrollbarCornerResize); + if (_resizeBoth) + addClass(_scrollbarCornerElement, _classNameScrollbarCornerResizeB); + else if (_resizeHorizontal) + addClass(_scrollbarCornerElement, _classNameScrollbarCornerResizeH); + else if (_resizeVertical) + addClass(_scrollbarCornerElement, _classNameScrollbarCornerResizeV); + } + } + + //manage the scrollbars general visibility + the scrollbar interactivity (unusable class name) + if (scrollbarsVisibilityChanged || overflowBehaviorChanged || hideOverflow.c || hasOverflow.c || ignoreOverlayScrollbarHidingChanged) { + if (ignoreOverlayScrollbarHiding) { + if (ignoreOverlayScrollbarHidingChanged) { + removeClass(_hostElement, _classNameHostScrolling); + if (ignoreOverlayScrollbarHiding) { + hideScrollbarH(); + hideScrollbarV(); + } + } + } + else if (scrollbarsVisibilityAuto) { + if (canScroll.x) + showScrollbarH(); + else + hideScrollbarH(); + + if (canScroll.y) + showScrollbarV(); + else + hideScrollbarV(); + } + else if (scrollbarsVisibilityVisible) { + showScrollbarH(); + showScrollbarV(); + } + else if (scrollbarsVisibilityHidden) { + hideScrollbarH(); + hideScrollbarV(); + } + } + + //manage the scrollbars auto hide feature (auto hide them after specific actions) + if (scrollbarsAutoHideChanged || ignoreOverlayScrollbarHidingChanged) { + if (_scrollbarsAutoHideLeave || _scrollbarsAutoHideMove) { + setupHostMouseTouchEvents(true); + setupHostMouseTouchEvents(); + } + else { + setupHostMouseTouchEvents(true); + } + + if (_scrollbarsAutoHideNever) + refreshScrollbarsAutoHide(true); + else + refreshScrollbarsAutoHide(false, true); + } + + //manage scrollbars handle length & offset - don't remove! + if (hostSizeChanged || overflowAmount.c || heightAutoChanged || widthAutoChanged || resizeChanged || boxSizingChanged || paddingAbsoluteChanged || ignoreOverlayScrollbarHidingChanged || cssDirectionChanged) { + refreshScrollbarHandleLength(true); + refreshScrollbarHandleOffset(true); + refreshScrollbarHandleLength(false); + refreshScrollbarHandleOffset(false); + } + + //manage interactivity + if (scrollbarsClickScrollingChanged) + refreshScrollbarsInteractive(true, scrollbarsClickScrolling); + if (scrollbarsDragScrollingChanged) + refreshScrollbarsInteractive(false, scrollbarsDragScrolling); + + //callbacks: + if (cssDirectionChanged) { + dispatchCallback('onDirectionChanged', { + isRTL: _isRTL, + dir: cssDirection + }); + } + if (hostSizeChanged) { + dispatchCallback('onHostSizeChanged', { + width: _hostSizeCache.w, + height: _hostSizeCache.h + }); + } + if (contentSizeChanged) { + dispatchCallback('onContentSizeChanged', { + width: _contentScrollSizeCache.w, + height: _contentScrollSizeCache.h + }); + } + if (hasOverflow.c || hideOverflow.c) { + dispatchCallback('onOverflowChanged', { + x: hasOverflow.x, + y: hasOverflow.y, + xScrollable: hideOverflow.xs, + yScrollable: hideOverflow.ys, + clipped: hideOverflow.x || hideOverflow.y + }); + } + if (overflowAmount.c) { + dispatchCallback('onOverflowAmountChanged', { + x: overflowAmount.x, + y: overflowAmount.y + }); + } + } + + //fix body min size + if (_isBody && _bodyMinSizeCache && (_hasOverflowCache.c || _bodyMinSizeCache.c)) { + //its possible that no min size was measured until now, because the content arrange element was just added now, in this case, measure now the min size. + if (!_bodyMinSizeCache.f) + bodyMinSizeChanged(); + if (_nativeScrollbarIsOverlaid.y && _hasOverflowCache.x) + _contentElement.css(_strMinMinus + _strWidth, _bodyMinSizeCache.w + _overlayScrollbarDummySize.y); + if (_nativeScrollbarIsOverlaid.x && _hasOverflowCache.y) + _contentElement.css(_strMinMinus + _strHeight, _bodyMinSizeCache.h + _overlayScrollbarDummySize.x); + _bodyMinSizeCache.c = false; + } + + //freezeResizeObserver(_sizeObserverElement, false); + //freezeResizeObserver(_sizeAutoObserverElement, false); + + dispatchCallback('onUpdated', { forced: force }); + } + + + //==== Options ====// + + /** + * Sets new options but doesn't call the update method. + * @param newOptions The object which contains the new options. + * @returns {*} A object which contains the changed options. + */ + function setOptions(newOptions) { + var validatedOpts = _pluginsOptions._validate(newOptions, _pluginsOptions._template, true, _currentOptions) + + _currentOptions = extendDeep({}, _currentOptions, validatedOpts._default); + _currentPreparedOptions = extendDeep({}, _currentPreparedOptions, validatedOpts._prepared); + + return validatedOpts._prepared; + } + + + //==== Structure ====// + + /** + * Builds or destroys the wrapper and helper DOM elements. + * @param destroy Indicates whether the DOM shall be build or destroyed. + */ + function setupStructureDOM(destroy) { + var strParent = 'parent'; + var classNameResizeObserverHost = 'os-resize-observer-host'; + var classNameTextareaElementFull = _classNameTextareaElement + _strSpace + _classNameTextInherit; + var textareaClass = _isTextarea ? _strSpace + _classNameTextInherit : _strEmpty; + var adoptAttrs = _currentPreparedOptions.textarea.inheritedAttrs; + var adoptAttrsMap = {}; + var applyAdoptedAttrs = function () { + var applyAdoptedAttrsElm = destroy ? _targetElement : _hostElement; + each(adoptAttrsMap, function (key, value) { + if (type(value) == TYPES.s) { + if (key == LEXICON.c) + applyAdoptedAttrsElm.addClass(value); + else + applyAdoptedAttrsElm.attr(key, value); + } + }); + }; + var hostElementClassNames = [ + _classNameHostElement, + _classNameHostTextareaElement, + _classNameHostResizeDisabled, + _classNameHostRTL, + _classNameHostScrollbarHorizontalHidden, + _classNameHostScrollbarVerticalHidden, + _classNameHostTransition, + _classNameHostScrolling, + _classNameHostOverflow, + _classNameHostOverflowX, + _classNameHostOverflowY, + _classNameThemeNone, + _classNameTextareaElement, + _classNameTextInherit, + _classNameCache].join(_strSpace); + var hostElementCSS = {}; + + //get host element as first element, because that's the most upper element and required for the other elements + _hostElement = _hostElement || (_isTextarea ? (_domExists ? _targetElement[strParent]()[strParent]()[strParent]()[strParent]() : FRAMEWORK(generateDiv(_classNameHostTextareaElement))) : _targetElement); + _contentElement = _contentElement || selectOrGenerateDivByClass(_classNameContentElement + textareaClass); + _viewportElement = _viewportElement || selectOrGenerateDivByClass(_classNameViewportElement + textareaClass); + _paddingElement = _paddingElement || selectOrGenerateDivByClass(_classNamePaddingElement + textareaClass); + _sizeObserverElement = _sizeObserverElement || selectOrGenerateDivByClass(classNameResizeObserverHost); + _textareaCoverElement = _textareaCoverElement || (_isTextarea ? selectOrGenerateDivByClass(_classNameTextareaCoverElement) : undefined); + + //on destroy, remove all generated class names from the host element before collecting the adopted attributes + //to prevent adopting generated class names + if (destroy) + removeClass(_hostElement, hostElementClassNames); + + //collect all adopted attributes + adoptAttrs = type(adoptAttrs) == TYPES.s ? adoptAttrs.split(_strSpace) : adoptAttrs; + if (type(adoptAttrs) == TYPES.a && _isTextarea) { + each(adoptAttrs, function (i, v) { + if (type(v) == TYPES.s) { + adoptAttrsMap[v] = destroy ? _hostElement.attr(v) : _targetElement.attr(v); + } + }); + } + + if (!destroy) { + if (_isTextarea) { + if (!_currentPreparedOptions.sizeAutoCapable) { + hostElementCSS[_strWidth] = _targetElement.css(_strWidth); + hostElementCSS[_strHeight] = _targetElement.css(_strHeight); + } + + if (!_domExists) + _targetElement.addClass(_classNameTextInherit).wrap(_hostElement); + + //jQuery clones elements in wrap functions, so we have to select them again + _hostElement = _targetElement[strParent]().css(hostElementCSS); + } + + if (!_domExists) { + //add the correct class to the target element + addClass(_targetElement, _isTextarea ? classNameTextareaElementFull : _classNameHostElement); + + //wrap the content into the generated elements to create the required DOM + _hostElement.wrapInner(_contentElement) + .wrapInner(_viewportElement) + .wrapInner(_paddingElement) + .prepend(_sizeObserverElement); + + //jQuery clones elements in wrap functions, so we have to select them again + _contentElement = findFirst(_hostElement, _strDot + _classNameContentElement); + _viewportElement = findFirst(_hostElement, _strDot + _classNameViewportElement); + _paddingElement = findFirst(_hostElement, _strDot + _classNamePaddingElement); + + if (_isTextarea) { + _contentElement.prepend(_textareaCoverElement); + applyAdoptedAttrs(); + } + } + + if (_nativeScrollbarStyling) + addClass(_viewportElement, _classNameViewportNativeScrollbarsInvisible); + if (_nativeScrollbarIsOverlaid.x && _nativeScrollbarIsOverlaid.y) + addClass(_viewportElement, _classNameViewportNativeScrollbarsOverlaid); + if (_isBody) + addClass(_htmlElement, _classNameHTMLElement); + + _sizeObserverElementNative = _sizeObserverElement[0]; + _hostElementNative = _hostElement[0]; + _paddingElementNative = _paddingElement[0]; + _viewportElementNative = _viewportElement[0]; + _contentElementNative = _contentElement[0]; + + updateViewportAttrsFromTarget(); + } + else { + if (_domExists && _initialized) { + //clear size observer + _sizeObserverElement.children().remove(); + + //remove the style property and classes from already generated elements + each([_paddingElement, _viewportElement, _contentElement, _textareaCoverElement], function (i, elm) { + if (elm) { + removeClass(elm.removeAttr(LEXICON.s), _classNamesDynamicDestroy); + } + }); + + //add classes to the host element which was removed previously to match the expected DOM + addClass(_hostElement, _isTextarea ? _classNameHostTextareaElement : _classNameHostElement); + } + else { + //remove size observer + remove(_sizeObserverElement); + + //unwrap the content to restore DOM + _contentElement.contents() + .unwrap() + .unwrap() + .unwrap(); + + if (_isTextarea) { + _targetElement.unwrap(); + remove(_hostElement); + remove(_textareaCoverElement); + applyAdoptedAttrs(); + } + } + + if (_isTextarea) + _targetElement.removeAttr(LEXICON.s); + + if (_isBody) + removeClass(_htmlElement, _classNameHTMLElement); + } + } + + /** + * Adds or removes all wrapper elements interactivity events. + * @param destroy Indicates whether the Events shall be added or removed. + */ + function setupStructureEvents() { + var textareaKeyDownRestrictedKeyCodes = [ + 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 123, //F1 to F12 + 33, 34, //page up, page down + 37, 38, 39, 40, //left, up, right, down arrows + 16, 17, 18, 19, 20, 144 //Shift, Ctrl, Alt, Pause, CapsLock, NumLock + ]; + var textareaKeyDownKeyCodesList = []; + var textareaUpdateIntervalID; + var scrollStopTimeoutId; + var scrollStopDelay = 175; + var strFocus = 'focus'; + + function updateTextarea(doClearInterval) { + textareaUpdate(); + _base.update(_strAuto); + if (doClearInterval && _autoUpdateRecommended) + clearInterval(textareaUpdateIntervalID); + } + function textareaOnScroll(event) { + _targetElement[_strScrollLeft](_rtlScrollBehavior.i && _normalizeRTLCache ? 9999999 : 0); + _targetElement[_strScrollTop](0); + COMPATIBILITY.prvD(event); + COMPATIBILITY.stpP(event); + return false; + } + function textareaOnDrop(event) { + setTimeout(function () { + if (!_destroyed) + updateTextarea(); + }, 50); + } + function textareaOnFocus() { + _textareaHasFocus = true; + addClass(_hostElement, strFocus); + } + function textareaOnFocusout() { + _textareaHasFocus = false; + textareaKeyDownKeyCodesList = []; + removeClass(_hostElement, strFocus); + updateTextarea(true); + } + function textareaOnKeyDown(event) { + var keyCode = event.keyCode; + + if (inArray(keyCode, textareaKeyDownRestrictedKeyCodes) < 0) { + if (!textareaKeyDownKeyCodesList[LEXICON.l]) { + updateTextarea(); + textareaUpdateIntervalID = setInterval(updateTextarea, 1000 / 60); + } + if (inArray(keyCode, textareaKeyDownKeyCodesList) < 0) + textareaKeyDownKeyCodesList.push(keyCode); + } + } + function textareaOnKeyUp(event) { + var keyCode = event.keyCode; + var index = inArray(keyCode, textareaKeyDownKeyCodesList); + + if (inArray(keyCode, textareaKeyDownRestrictedKeyCodes) < 0) { + if (index > -1) + textareaKeyDownKeyCodesList.splice(index, 1); + if (!textareaKeyDownKeyCodesList[LEXICON.l]) + updateTextarea(true); + } + } + function contentOnTransitionEnd(event) { + if (_autoUpdateCache === true) + return; + event = event.originalEvent || event; + if (isSizeAffectingCSSProperty(event.propertyName)) + _base.update(_strAuto); + } + function viewportOnScroll(event) { + if (!_sleeping) { + if (scrollStopTimeoutId !== undefined) + clearTimeout(scrollStopTimeoutId); + else { + if (_scrollbarsAutoHideScroll || _scrollbarsAutoHideMove) + refreshScrollbarsAutoHide(true); + + if (!nativeOverlayScrollbarsAreActive()) + addClass(_hostElement, _classNameHostScrolling); + + dispatchCallback('onScrollStart', event); + } + + //if a scrollbars handle gets dragged, the mousemove event is responsible for refreshing the handle offset + //because if CSS scroll-snap is used, the handle offset gets only refreshed on every snap point + //this looks laggy & clunky, it looks much better if the offset refreshes with the mousemove + if (!_scrollbarsHandlesDefineScrollPos) { + refreshScrollbarHandleOffset(true); + refreshScrollbarHandleOffset(false); + } + dispatchCallback('onScroll', event); + + scrollStopTimeoutId = setTimeout(function () { + if (!_destroyed) { + //OnScrollStop: + clearTimeout(scrollStopTimeoutId); + scrollStopTimeoutId = undefined; + + if (_scrollbarsAutoHideScroll || _scrollbarsAutoHideMove) + refreshScrollbarsAutoHide(false); + + if (!nativeOverlayScrollbarsAreActive()) + removeClass(_hostElement, _classNameHostScrolling); + + dispatchCallback('onScrollStop', event); + } + }, scrollStopDelay); + } + } + + + if (_isTextarea) { + if (_msieVersion > 9 || !_autoUpdateRecommended) { + addDestroyEventListener(_targetElement, 'input', updateTextarea); + } + else { + addDestroyEventListener(_targetElement, + [_strKeyDownEvent, _strKeyUpEvent], + [textareaOnKeyDown, textareaOnKeyUp]); + } + + addDestroyEventListener(_targetElement, + [_strScroll, 'drop', strFocus, strFocus + 'out'], + [textareaOnScroll, textareaOnDrop, textareaOnFocus, textareaOnFocusout]); + } + else { + addDestroyEventListener(_contentElement, _strTransitionEndEvent, contentOnTransitionEnd); + } + addDestroyEventListener(_viewportElement, _strScroll, viewportOnScroll, true); + } + + + //==== Scrollbars ====// + + /** + * Builds or destroys all scrollbar DOM elements (scrollbar, track, handle) + * @param destroy Indicates whether the DOM shall be build or destroyed. + */ + function setupScrollbarsDOM(destroy) { + var selectOrGenerateScrollbarDOM = function (isHorizontal) { + var scrollbarClassName = isHorizontal ? _classNameScrollbarHorizontal : _classNameScrollbarVertical; + var scrollbar = selectOrGenerateDivByClass(_classNameScrollbar + _strSpace + scrollbarClassName, true); + var track = selectOrGenerateDivByClass(_classNameScrollbarTrack, scrollbar); + var handle = selectOrGenerateDivByClass(_classNameScrollbarHandle, scrollbar); + + if (!_domExists && !destroy) { + scrollbar.append(track); + track.append(handle); + } + + return { + _scrollbar: scrollbar, + _track: track, + _handle: handle + }; + }; + function resetScrollbarDOM(isHorizontal) { + var scrollbarVars = getScrollbarVars(isHorizontal); + var scrollbar = scrollbarVars._scrollbar; + var track = scrollbarVars._track; + var handle = scrollbarVars._handle; + + if (_domExists && _initialized) { + each([scrollbar, track, handle], function (i, elm) { + removeClass(elm.removeAttr(LEXICON.s), _classNamesDynamicDestroy); + }); + } + else { + remove(scrollbar || selectOrGenerateScrollbarDOM(isHorizontal)._scrollbar); + } + } + var horizontalElements; + var verticalElements; + + if (!destroy) { + horizontalElements = selectOrGenerateScrollbarDOM(true); + verticalElements = selectOrGenerateScrollbarDOM(); + + _scrollbarHorizontalElement = horizontalElements._scrollbar; + _scrollbarHorizontalTrackElement = horizontalElements._track; + _scrollbarHorizontalHandleElement = horizontalElements._handle; + _scrollbarVerticalElement = verticalElements._scrollbar; + _scrollbarVerticalTrackElement = verticalElements._track; + _scrollbarVerticalHandleElement = verticalElements._handle; + + if (!_domExists) { + _paddingElement.after(_scrollbarVerticalElement); + _paddingElement.after(_scrollbarHorizontalElement); + } + } + else { + resetScrollbarDOM(true); + resetScrollbarDOM(); + } + } + + /** + * Initializes all scrollbar interactivity events. (track and handle dragging, clicking, scrolling) + * @param isHorizontal True if the target scrollbar is the horizontal scrollbar, false if the target scrollbar is the vertical scrollbar. + */ + function setupScrollbarEvents(isHorizontal) { + var scrollbarVars = getScrollbarVars(isHorizontal); + var scrollbarVarsInfo = scrollbarVars._info; + var insideIFrame = _windowElementNative.top !== _windowElementNative; + var xy = scrollbarVars._x_y; + var XY = scrollbarVars._X_Y; + var scroll = _strScroll + scrollbarVars._Left_Top; + var strActive = 'active'; + var strSnapHandle = 'snapHandle'; + var scrollDurationFactor = 1; + var increaseDecreaseScrollAmountKeyCodes = [16, 17]; //shift, ctrl + var trackTimeout; + var mouseDownScroll; + var mouseDownOffset; + var mouseDownInvertedScale; + + function getPointerPosition(event) { + return _msieVersion && insideIFrame ? event['screen' + XY] : COMPATIBILITY.page(event)[xy]; //use screen coordinates in EDGE & IE because the page values are incorrect in frames. + } + function getPreparedScrollbarsOption(name) { + return _currentPreparedOptions.scrollbars[name]; + } + function increaseTrackScrollAmount() { + scrollDurationFactor = 0.5; + } + function decreaseTrackScrollAmount() { + scrollDurationFactor = 1; + } + function documentKeyDown(event) { + if (inArray(event.keyCode, increaseDecreaseScrollAmountKeyCodes) > -1) + increaseTrackScrollAmount(); + } + function documentKeyUp(event) { + if (inArray(event.keyCode, increaseDecreaseScrollAmountKeyCodes) > -1) + decreaseTrackScrollAmount(); + } + function onMouseTouchDownContinue(event) { + var originalEvent = event.originalEvent || event; + var isTouchEvent = originalEvent.touches !== undefined; + return _sleeping || _destroyed || nativeOverlayScrollbarsAreActive() || !_scrollbarsDragScrollingCache || (isTouchEvent && !getPreparedScrollbarsOption('touchSupport')) ? false : COMPATIBILITY.mBtn(event) === 1 || isTouchEvent; + } + function documentDragMove(event) { + if (onMouseTouchDownContinue(event)) { + var trackLength = scrollbarVarsInfo._trackLength; + var handleLength = scrollbarVarsInfo._handleLength; + var scrollRange = scrollbarVarsInfo._maxScroll; + var scrollRaw = (getPointerPosition(event) - mouseDownOffset) * mouseDownInvertedScale; + var scrollDeltaPercent = scrollRaw / (trackLength - handleLength); + var scrollDelta = (scrollRange * scrollDeltaPercent); + scrollDelta = isFinite(scrollDelta) ? scrollDelta : 0; + if (_isRTL && isHorizontal && !_rtlScrollBehavior.i) + scrollDelta *= -1; + + _viewportElement[scroll](MATH.round(mouseDownScroll + scrollDelta)); + + if (_scrollbarsHandlesDefineScrollPos) + refreshScrollbarHandleOffset(isHorizontal, mouseDownScroll + scrollDelta); + + if (!_supportPassiveEvents) + COMPATIBILITY.prvD(event); + } + else + documentMouseTouchUp(event); + } + function documentMouseTouchUp(event) { + event = event || event.originalEvent; + + setupResponsiveEventListener(_documentElement, + [_strMouseTouchMoveEvent, _strMouseTouchUpEvent, _strKeyDownEvent, _strKeyUpEvent, _strSelectStartEvent], + [documentDragMove, documentMouseTouchUp, documentKeyDown, documentKeyUp, documentOnSelectStart], + true); + + if (_scrollbarsHandlesDefineScrollPos) + refreshScrollbarHandleOffset(isHorizontal, true); + + _scrollbarsHandlesDefineScrollPos = false; + removeClass(_bodyElement, _classNameDragging); + removeClass(scrollbarVars._handle, strActive); + removeClass(scrollbarVars._track, strActive); + removeClass(scrollbarVars._scrollbar, strActive); + + mouseDownScroll = undefined; + mouseDownOffset = undefined; + mouseDownInvertedScale = 1; + + decreaseTrackScrollAmount(); + + if (trackTimeout !== undefined) { + _base.scrollStop(); + clearTimeout(trackTimeout); + trackTimeout = undefined; + } + + if (event) { + var rect = _hostElementNative[LEXICON.bCR](); + var mouseInsideHost = event.clientX >= rect.left && event.clientX <= rect.right && event.clientY >= rect.top && event.clientY <= rect.bottom; + + //if mouse is outside host element + if (!mouseInsideHost) + hostOnMouseLeave(); + + if (_scrollbarsAutoHideScroll || _scrollbarsAutoHideMove) + refreshScrollbarsAutoHide(false); + } + } + function onHandleMouseTouchDown(event) { + if (onMouseTouchDownContinue(event)) + onHandleMouseTouchDownAction(event); + } + function onHandleMouseTouchDownAction(event) { + mouseDownScroll = _viewportElement[scroll](); + mouseDownScroll = isNaN(mouseDownScroll) ? 0 : mouseDownScroll; + if (_isRTL && isHorizontal && !_rtlScrollBehavior.n || !_isRTL) + mouseDownScroll = mouseDownScroll < 0 ? 0 : mouseDownScroll; + + mouseDownInvertedScale = getHostElementInvertedScale()[xy]; + mouseDownOffset = getPointerPosition(event); + + _scrollbarsHandlesDefineScrollPos = !getPreparedScrollbarsOption(strSnapHandle); + addClass(_bodyElement, _classNameDragging); + addClass(scrollbarVars._handle, strActive); + addClass(scrollbarVars._scrollbar, strActive); + + setupResponsiveEventListener(_documentElement, + [_strMouseTouchMoveEvent, _strMouseTouchUpEvent, _strSelectStartEvent], + [documentDragMove, documentMouseTouchUp, documentOnSelectStart]); + + if (_msieVersion || !_documentMixed) + COMPATIBILITY.prvD(event); + COMPATIBILITY.stpP(event); + } + function onTrackMouseTouchDown(event) { + if (onMouseTouchDownContinue(event)) { + var scrollDistance = MATH.round(_viewportSize[scrollbarVars._w_h]); + var trackOffset = scrollbarVars._track.offset()[scrollbarVars._left_top]; + var ctrlKey = event.ctrlKey; + var instantScroll = event.shiftKey; + var instantScrollTransition = instantScroll && ctrlKey; + var isFirstIteration = true; + var easing = 'linear'; + var decreaseScroll; + var finishedCondition; + var scrollActionFinsished = function (transition) { + if (_scrollbarsHandlesDefineScrollPos) + refreshScrollbarHandleOffset(isHorizontal, transition); + }; + var scrollActionInstantFinished = function () { + scrollActionFinsished(); + onHandleMouseTouchDownAction(event); + }; + var scrollAction = function () { + if (!_destroyed) { + var mouseOffset = (mouseDownOffset - trackOffset) * mouseDownInvertedScale; + var handleOffset = scrollbarVarsInfo._handleOffset; + var trackLength = scrollbarVarsInfo._trackLength; + var handleLength = scrollbarVarsInfo._handleLength; + var scrollRange = scrollbarVarsInfo._maxScroll; + var currScroll = scrollbarVarsInfo._currentScroll; + var scrollDuration = 270 * scrollDurationFactor; + var timeoutDelay = isFirstIteration ? MATH.max(400, scrollDuration) : scrollDuration; + var instantScrollPosition = scrollRange * ((mouseOffset - (handleLength / 2)) / (trackLength - handleLength)); // 100% * positionPercent + var rtlIsNormal = _isRTL && isHorizontal && ((!_rtlScrollBehavior.i && !_rtlScrollBehavior.n) || _normalizeRTLCache); + var decreaseScrollCondition = rtlIsNormal ? handleOffset < mouseOffset : handleOffset > mouseOffset; + var scrollObj = {}; + var animationObj = { + easing: easing, + step: function (now) { + if (_scrollbarsHandlesDefineScrollPos) { + _viewportElement[scroll](now); //https://github.com/jquery/jquery/issues/4340 + refreshScrollbarHandleOffset(isHorizontal, now); + } + } + }; + instantScrollPosition = isFinite(instantScrollPosition) ? instantScrollPosition : 0; + instantScrollPosition = _isRTL && isHorizontal && !_rtlScrollBehavior.i ? (scrollRange - instantScrollPosition) : instantScrollPosition; + + //_base.scrollStop(); + + if (instantScroll) { + _viewportElement[scroll](instantScrollPosition); //scroll instantly to new position + if (instantScrollTransition) { + //get the scroll position after instant scroll (in case CSS Snap Points are used) to get the correct snapped scroll position + //and the animation stops at the correct point + instantScrollPosition = _viewportElement[scroll](); + //scroll back to the position before instant scrolling so animation can be performed + _viewportElement[scroll](currScroll); + + instantScrollPosition = rtlIsNormal && _rtlScrollBehavior.i ? (scrollRange - instantScrollPosition) : instantScrollPosition; + instantScrollPosition = rtlIsNormal && _rtlScrollBehavior.n ? -instantScrollPosition : instantScrollPosition; + + scrollObj[xy] = instantScrollPosition; + _base.scroll(scrollObj, extendDeep(animationObj, { + duration: 130, + complete: scrollActionInstantFinished + })); + } + else + scrollActionInstantFinished(); + } + else { + decreaseScroll = isFirstIteration ? decreaseScrollCondition : decreaseScroll; + finishedCondition = rtlIsNormal + ? (decreaseScroll ? handleOffset + handleLength >= mouseOffset : handleOffset <= mouseOffset) + : (decreaseScroll ? handleOffset <= mouseOffset : handleOffset + handleLength >= mouseOffset); + + if (finishedCondition) { + clearTimeout(trackTimeout); + _base.scrollStop(); + trackTimeout = undefined; + scrollActionFinsished(true); + } + else { + trackTimeout = setTimeout(scrollAction, timeoutDelay); + + scrollObj[xy] = (decreaseScroll ? '-=' : '+=') + scrollDistance; + _base.scroll(scrollObj, extendDeep(animationObj, { + duration: scrollDuration + })); + } + isFirstIteration = false; + } + } + }; + if (ctrlKey) + increaseTrackScrollAmount(); + + mouseDownInvertedScale = getHostElementInvertedScale()[xy]; + mouseDownOffset = COMPATIBILITY.page(event)[xy]; + + _scrollbarsHandlesDefineScrollPos = !getPreparedScrollbarsOption(strSnapHandle); + addClass(_bodyElement, _classNameDragging); + addClass(scrollbarVars._track, strActive); + addClass(scrollbarVars._scrollbar, strActive); + + setupResponsiveEventListener(_documentElement, + [_strMouseTouchUpEvent, _strKeyDownEvent, _strKeyUpEvent, _strSelectStartEvent], + [documentMouseTouchUp, documentKeyDown, documentKeyUp, documentOnSelectStart]); + + scrollAction(); + COMPATIBILITY.prvD(event); + COMPATIBILITY.stpP(event); + } + } + function onTrackMouseTouchEnter(event) { + //make sure both scrollbars will stay visible if one scrollbar is hovered if autoHide is "scroll" or "move". + _scrollbarsHandleHovered = true; + if (_scrollbarsAutoHideScroll || _scrollbarsAutoHideMove) + refreshScrollbarsAutoHide(true); + } + function onTrackMouseTouchLeave(event) { + _scrollbarsHandleHovered = false; + if (_scrollbarsAutoHideScroll || _scrollbarsAutoHideMove) + refreshScrollbarsAutoHide(false); + } + function onScrollbarMouseTouchDown(event) { + COMPATIBILITY.stpP(event); + } + + addDestroyEventListener(scrollbarVars._handle, + _strMouseTouchDownEvent, + onHandleMouseTouchDown); + addDestroyEventListener(scrollbarVars._track, + [_strMouseTouchDownEvent, _strMouseTouchEnter, _strMouseTouchLeave], + [onTrackMouseTouchDown, onTrackMouseTouchEnter, onTrackMouseTouchLeave]); + addDestroyEventListener(scrollbarVars._scrollbar, + _strMouseTouchDownEvent, + onScrollbarMouseTouchDown); + + if (_supportTransition) { + addDestroyEventListener(scrollbarVars._scrollbar, _strTransitionEndEvent, function (event) { + if (event.target !== scrollbarVars._scrollbar[0]) + return; + refreshScrollbarHandleLength(isHorizontal); + refreshScrollbarHandleOffset(isHorizontal); + }); + } + } + + /** + * Shows or hides the given scrollbar and applied a class name which indicates if the scrollbar is scrollable or not. + * @param isHorizontal True if the horizontal scrollbar is the target, false if the vertical scrollbar is the target. + * @param shallBeVisible True if the scrollbar shall be shown, false if hidden. + * @param canScroll True if the scrollbar is scrollable, false otherwise. + */ + function refreshScrollbarAppearance(isHorizontal, shallBeVisible, canScroll) { + var scrollbarClassName = isHorizontal ? _classNameHostScrollbarHorizontalHidden : _classNameHostScrollbarVerticalHidden; + var scrollbarElement = isHorizontal ? _scrollbarHorizontalElement : _scrollbarVerticalElement; + + if (shallBeVisible) + removeClass(_hostElement, scrollbarClassName); + else + addClass(_hostElement, scrollbarClassName); + + if (canScroll) + removeClass(scrollbarElement, _classNameScrollbarUnusable); + else + addClass(scrollbarElement, _classNameScrollbarUnusable); + } + + /** + * Autoshows / autohides both scrollbars with. + * @param shallBeVisible True if the scrollbars shall be autoshown (only the case if they are hidden by a autohide), false if the shall be auto hidden. + * @param delayfree True if the scrollbars shall be hidden without a delay, false or undefined otherwise. + */ + function refreshScrollbarsAutoHide(shallBeVisible, delayfree) { + clearTimeout(_scrollbarsAutoHideTimeoutId); + if (shallBeVisible) { + //if(_hasOverflowCache.x && _hideOverflowCache.xs) + removeClass(_scrollbarHorizontalElement, _classNameScrollbarAutoHidden); + //if(_hasOverflowCache.y && _hideOverflowCache.ys) + removeClass(_scrollbarVerticalElement, _classNameScrollbarAutoHidden); + } + else { + var anyActive; + var strActive = 'active'; + var hide = function () { + if (!_scrollbarsHandleHovered && !_destroyed) { + anyActive = _scrollbarHorizontalHandleElement.hasClass(strActive) || _scrollbarVerticalHandleElement.hasClass(strActive); + if (!anyActive && (_scrollbarsAutoHideScroll || _scrollbarsAutoHideMove || _scrollbarsAutoHideLeave)) + addClass(_scrollbarHorizontalElement, _classNameScrollbarAutoHidden); + if (!anyActive && (_scrollbarsAutoHideScroll || _scrollbarsAutoHideMove || _scrollbarsAutoHideLeave)) + addClass(_scrollbarVerticalElement, _classNameScrollbarAutoHidden); + } + }; + if (_scrollbarsAutoHideDelay > 0 && delayfree !== true) + _scrollbarsAutoHideTimeoutId = setTimeout(hide, _scrollbarsAutoHideDelay); + else + hide(); + } + } + + /** + * Refreshes the handle length of the given scrollbar. + * @param isHorizontal True if the horizontal scrollbar handle shall be refreshed, false if the vertical one shall be refreshed. + */ + function refreshScrollbarHandleLength(isHorizontal) { + var handleCSS = {}; + var scrollbarVars = getScrollbarVars(isHorizontal); + var scrollbarVarsInfo = scrollbarVars._info; + var digit = 1000000; + //get and apply intended handle length + var handleRatio = MATH.min(1, (_hostSizeCache[scrollbarVars._w_h] - (_paddingAbsoluteCache ? (isHorizontal ? _paddingX : _paddingY) : 0)) / _contentScrollSizeCache[scrollbarVars._w_h]); + handleCSS[scrollbarVars._width_height] = (MATH.floor(handleRatio * 100 * digit) / digit) + '%'; //the last * digit / digit is for flooring to the 4th digit + + if (!nativeOverlayScrollbarsAreActive()) + scrollbarVars._handle.css(handleCSS); + + //measure the handle length to respect min & max length + scrollbarVarsInfo._handleLength = scrollbarVars._handle[0]['offset' + scrollbarVars._Width_Height]; + scrollbarVarsInfo._handleLengthRatio = handleRatio; + } + + /** + * Refreshes the handle offset of the given scrollbar. + * @param isHorizontal True if the horizontal scrollbar handle shall be refreshed, false if the vertical one shall be refreshed. + * @param scrollOrTransition The scroll position of the given scrollbar axis to which the handle shall be moved or a boolean which indicates whether a transition shall be applied. If undefined or boolean if the current scroll-offset is taken. (if isHorizontal ? scrollLeft : scrollTop) + */ + function refreshScrollbarHandleOffset(isHorizontal, scrollOrTransition) { + var transition = type(scrollOrTransition) == TYPES.b; + var transitionDuration = 250; + var isRTLisHorizontal = _isRTL && isHorizontal; + var scrollbarVars = getScrollbarVars(isHorizontal); + var scrollbarVarsInfo = scrollbarVars._info; + var strTranslateBrace = 'translate('; + var strTransform = VENDORS._cssProperty('transform'); + var strTransition = VENDORS._cssProperty('transition'); + var nativeScroll = isHorizontal ? _viewportElement[_strScrollLeft]() : _viewportElement[_strScrollTop](); + var currentScroll = scrollOrTransition === undefined || transition ? nativeScroll : scrollOrTransition; + + //measure the handle length to respect min & max length + var handleLength = scrollbarVarsInfo._handleLength; + var trackLength = scrollbarVars._track[0]['offset' + scrollbarVars._Width_Height]; + var handleTrackDiff = trackLength - handleLength; + var handleCSS = {}; + var transformOffset; + var translateValue; + + //DONT use the variable '_contentScrollSizeCache[scrollbarVars._w_h]' instead of '_viewportElement[0]['scroll' + scrollbarVars._Width_Height]' + // because its a bit behind during the small delay when content size updates + //(delay = mutationObserverContentLag, if its 0 then this var could be used) + var maxScroll = (_viewportElementNative[_strScroll + scrollbarVars._Width_Height] - _viewportElementNative['client' + scrollbarVars._Width_Height]) * (_rtlScrollBehavior.n && isRTLisHorizontal ? -1 : 1); //* -1 if rtl scroll max is negative + var getScrollRatio = function (base) { + return isNaN(base / maxScroll) ? 0 : MATH.max(0, MATH.min(1, base / maxScroll)); + }; + var getHandleOffset = function (scrollRatio) { + var offset = handleTrackDiff * scrollRatio; + offset = isNaN(offset) ? 0 : offset; + offset = (isRTLisHorizontal && !_rtlScrollBehavior.i) ? (trackLength - handleLength - offset) : offset; + offset = MATH.max(0, offset); + return offset; + }; + var scrollRatio = getScrollRatio(nativeScroll); + var unsnappedScrollRatio = getScrollRatio(currentScroll); + var handleOffset = getHandleOffset(unsnappedScrollRatio); + var snappedHandleOffset = getHandleOffset(scrollRatio); + + scrollbarVarsInfo._maxScroll = maxScroll; + scrollbarVarsInfo._currentScroll = nativeScroll; + scrollbarVarsInfo._currentScrollRatio = scrollRatio; + + if (_supportTransform) { + transformOffset = isRTLisHorizontal ? -(trackLength - handleLength - handleOffset) : handleOffset; //in px + //transformOffset = (transformOffset / trackLength * 100) * (trackLength / handleLength); //in % + translateValue = isHorizontal ? strTranslateBrace + transformOffset + 'px, 0)' : strTranslateBrace + '0, ' + transformOffset + 'px)'; + + handleCSS[strTransform] = translateValue; + + //apply or clear up transition + if (_supportTransition) + handleCSS[strTransition] = transition && MATH.abs(handleOffset - scrollbarVarsInfo._handleOffset) > 1 ? getCSSTransitionString(scrollbarVars._handle) + ', ' + (strTransform + _strSpace + transitionDuration + 'ms') : _strEmpty; + } + else + handleCSS[scrollbarVars._left_top] = handleOffset; + + + //only apply css if offset has changed and overflow exists. + if (!nativeOverlayScrollbarsAreActive()) { + scrollbarVars._handle.css(handleCSS); + + //clear up transition + if (_supportTransform && _supportTransition && transition) { + scrollbarVars._handle.one(_strTransitionEndEvent, function () { + if (!_destroyed) + scrollbarVars._handle.css(strTransition, _strEmpty); + }); + } + } + + scrollbarVarsInfo._handleOffset = handleOffset; + scrollbarVarsInfo._snappedHandleOffset = snappedHandleOffset; + scrollbarVarsInfo._trackLength = trackLength; + } + + /** + * Refreshes the interactivity of the given scrollbar element. + * @param isTrack True if the track element is the target, false if the handle element is the target. + * @param value True for interactivity false for no interactivity. + */ + function refreshScrollbarsInteractive(isTrack, value) { + var action = value ? 'removeClass' : 'addClass'; + var element1 = isTrack ? _scrollbarHorizontalTrackElement : _scrollbarHorizontalHandleElement; + var element2 = isTrack ? _scrollbarVerticalTrackElement : _scrollbarVerticalHandleElement; + var className = isTrack ? _classNameScrollbarTrackOff : _classNameScrollbarHandleOff; + + element1[action](className); + element2[action](className); + } + + /** + * Returns a object which is used for fast access for specific variables. + * @param isHorizontal True if the horizontal scrollbar vars shall be accessed, false if the vertical scrollbar vars shall be accessed. + * @returns {{wh: string, WH: string, lt: string, _wh: string, _lt: string, t: *, h: *, c: {}, s: *}} + */ + function getScrollbarVars(isHorizontal) { + return { + _width_height: isHorizontal ? _strWidth : _strHeight, + _Width_Height: isHorizontal ? 'Width' : 'Height', + _left_top: isHorizontal ? _strLeft : _strTop, + _Left_Top: isHorizontal ? 'Left' : 'Top', + _x_y: isHorizontal ? _strX : _strY, + _X_Y: isHorizontal ? 'X' : 'Y', + _w_h: isHorizontal ? 'w' : 'h', + _l_t: isHorizontal ? 'l' : 't', + _track: isHorizontal ? _scrollbarHorizontalTrackElement : _scrollbarVerticalTrackElement, + _handle: isHorizontal ? _scrollbarHorizontalHandleElement : _scrollbarVerticalHandleElement, + _scrollbar: isHorizontal ? _scrollbarHorizontalElement : _scrollbarVerticalElement, + _info: isHorizontal ? _scrollHorizontalInfo : _scrollVerticalInfo + }; + } + + + //==== Scrollbar Corner ====// + + /** + * Builds or destroys the scrollbar corner DOM element. + * @param destroy Indicates whether the DOM shall be build or destroyed. + */ + function setupScrollbarCornerDOM(destroy) { + _scrollbarCornerElement = _scrollbarCornerElement || selectOrGenerateDivByClass(_classNameScrollbarCorner, true); + + if (!destroy) { + if (!_domExists) { + _hostElement.append(_scrollbarCornerElement); + } + } + else { + if (_domExists && _initialized) { + removeClass(_scrollbarCornerElement.removeAttr(LEXICON.s), _classNamesDynamicDestroy); + } + else { + remove(_scrollbarCornerElement); + } + } + } + + /** + * Initializes all scrollbar corner interactivity events. + */ + function setupScrollbarCornerEvents() { + var insideIFrame = _windowElementNative.top !== _windowElementNative; + var mouseDownPosition = {}; + var mouseDownSize = {}; + var mouseDownInvertedScale = {}; + var reconnectMutationObserver; + + function documentDragMove(event) { + if (onMouseTouchDownContinue(event)) { + var pageOffset = getCoordinates(event); + var hostElementCSS = {}; + if (_resizeHorizontal || _resizeBoth) + hostElementCSS[_strWidth] = (mouseDownSize.w + (pageOffset.x - mouseDownPosition.x) * mouseDownInvertedScale.x); + if (_resizeVertical || _resizeBoth) + hostElementCSS[_strHeight] = (mouseDownSize.h + (pageOffset.y - mouseDownPosition.y) * mouseDownInvertedScale.y); + _hostElement.css(hostElementCSS); + COMPATIBILITY.stpP(event); + } + else { + documentMouseTouchUp(event); + } + } + function documentMouseTouchUp(event) { + var eventIsTrusted = event !== undefined; + + setupResponsiveEventListener(_documentElement, + [_strSelectStartEvent, _strMouseTouchMoveEvent, _strMouseTouchUpEvent], + [documentOnSelectStart, documentDragMove, documentMouseTouchUp], + true); + + removeClass(_bodyElement, _classNameDragging); + if (_scrollbarCornerElement.releaseCapture) + _scrollbarCornerElement.releaseCapture(); + + if (eventIsTrusted) { + if (reconnectMutationObserver) + connectMutationObservers(); + _base.update(_strAuto); + } + reconnectMutationObserver = false; + } + function onMouseTouchDownContinue(event) { + var originalEvent = event.originalEvent || event; + var isTouchEvent = originalEvent.touches !== undefined; + return _sleeping || _destroyed ? false : COMPATIBILITY.mBtn(event) === 1 || isTouchEvent; + } + function getCoordinates(event) { + return _msieVersion && insideIFrame ? { x: event.screenX, y: event.screenY } : COMPATIBILITY.page(event); + } + + addDestroyEventListener(_scrollbarCornerElement, _strMouseTouchDownEvent, function (event) { + if (onMouseTouchDownContinue(event) && !_resizeNone) { + if (_mutationObserversConnected) { + reconnectMutationObserver = true; + disconnectMutationObservers(); + } + + mouseDownPosition = getCoordinates(event); + + mouseDownSize.w = _hostElementNative[LEXICON.oW] - (!_isBorderBox ? _paddingX : 0); + mouseDownSize.h = _hostElementNative[LEXICON.oH] - (!_isBorderBox ? _paddingY : 0); + mouseDownInvertedScale = getHostElementInvertedScale(); + + setupResponsiveEventListener(_documentElement, + [_strSelectStartEvent, _strMouseTouchMoveEvent, _strMouseTouchUpEvent], + [documentOnSelectStart, documentDragMove, documentMouseTouchUp]); + + addClass(_bodyElement, _classNameDragging); + if (_scrollbarCornerElement.setCapture) + _scrollbarCornerElement.setCapture(); + + COMPATIBILITY.prvD(event); + COMPATIBILITY.stpP(event); + } + }); + } + + + //==== Utils ====// + + /** + * Calls the callback with the given name. The Context of this callback is always _base (this). + * @param name The name of the target which shall be called. + * @param args The args with which the callback shall be called. + */ + function dispatchCallback(name, args) { + if (_initialized) { + var callback = _currentPreparedOptions.callbacks[name]; + var extensionOnName = name; + var ext; + + if (extensionOnName.substr(0, 2) === 'on') + extensionOnName = extensionOnName.substr(2, 1).toLowerCase() + extensionOnName.substr(3); + + if (type(callback) == TYPES.f) + callback.call(_base, args); + + each(_extensions, function () { + ext = this; + if (type(ext.on) == TYPES.f) + ext.on(extensionOnName, args); + }); + } + else if (!_destroyed) + _callbacksInitQeueue.push({ n: name, a: args }); + } + + /** + * Sets the "top, right, bottom, left" properties, with a given prefix, of the given css object. + * @param targetCSSObject The css object to which the values shall be applied. + * @param prefix The prefix of the "top, right, bottom, left" css properties. (example: 'padding-' is a valid prefix) + * @param values A array of values which shall be applied to the "top, right, bottom, left" -properties. The array order is [top, right, bottom, left]. + * If this argument is undefined the value '' (empty string) will be applied to all properties. + */ + function setTopRightBottomLeft(targetCSSObject, prefix, values) { + if (values === undefined) + values = [_strEmpty, _strEmpty, _strEmpty, _strEmpty]; + + targetCSSObject[prefix + _strTop] = values[0]; + targetCSSObject[prefix + _strRight] = values[1]; + targetCSSObject[prefix + _strBottom] = values[2]; + targetCSSObject[prefix + _strLeft] = values[3]; + } + + /** + * Returns the computed CSS transition string from the given element. + * @param element The element from which the transition string shall be returned. + * @returns {string} The CSS transition string from the given element. + */ + function getCSSTransitionString(element) { + var transitionStr = VENDORS._cssProperty('transition'); + var assembledValue = element.css(transitionStr); + if (assembledValue) + return assembledValue; + var regExpString = '\\s*(' + '([^,(]+(\\(.+?\\))?)+' + ')[\\s,]*'; + var regExpMain = new RegExp(regExpString); + var regExpValidate = new RegExp('^(' + regExpString + ')+$'); + var properties = 'property duration timing-function delay'.split(' '); + var result = []; + var strResult; + var valueArray; + var i = 0; + var j; + var splitCssStyleByComma = function (str) { + strResult = []; + if (!str.match(regExpValidate)) + return str; + while (str.match(regExpMain)) { + strResult.push(RegExp.$1); + str = str.replace(regExpMain, _strEmpty); + } + + return strResult; + }; + for (; i < properties[LEXICON.l]; i++) { + valueArray = splitCssStyleByComma(element.css(transitionStr + '-' + properties[i])); + for (j = 0; j < valueArray[LEXICON.l]; j++) + result[j] = (result[j] ? result[j] + _strSpace : _strEmpty) + valueArray[j]; + } + return result.join(', '); + } + + /** + * Calculates the host-elements inverted scale. (invertedScale = 1 / scale) + * @returns {{x: number, y: number}} The scale of the host-element. + */ + function getHostElementInvertedScale() { + var rect = _paddingElementNative[LEXICON.bCR](); + return { + x: _supportTransform ? 1 / (MATH.round(rect.width) / _paddingElementNative[LEXICON.oW]) || 1 : 1, + y: _supportTransform ? 1 / (MATH.round(rect.height) / _paddingElementNative[LEXICON.oH]) || 1 : 1 + }; + } + + /** + * Checks whether the given object is a HTMLElement. + * @param o The object which shall be checked. + * @returns {boolean} True the given object is a HTMLElement, false otherwise. + */ + function isHTMLElement(o) { + var strOwnerDocument = 'ownerDocument'; + var strHTMLElement = 'HTMLElement'; + var wnd = o && o[strOwnerDocument] ? (o[strOwnerDocument].parentWindow || window) : window; + return ( + typeof wnd[strHTMLElement] == TYPES.o ? o instanceof wnd[strHTMLElement] : //DOM2 + o && typeof o == TYPES.o && o !== null && o.nodeType === 1 && typeof o.nodeName == TYPES.s + ); + } + + /** + * Compares 2 arrays and returns the differences between them as a array. + * @param a1 The first array which shall be compared. + * @param a2 The second array which shall be compared. + * @returns {Array} The differences between the two arrays. + */ + function getArrayDifferences(a1, a2) { + var a = []; + var diff = []; + var i; + var k; + for (i = 0; i < a1.length; i++) + a[a1[i]] = true; + for (i = 0; i < a2.length; i++) { + if (a[a2[i]]) + delete a[a2[i]]; + else + a[a2[i]] = true; + } + for (k in a) + diff.push(k); + return diff; + } + + /** + * Returns Zero or the number to which the value can be parsed. + * @param value The value which shall be parsed. + * @param toFloat Indicates whether the number shall be parsed to a float. + */ + function parseToZeroOrNumber(value, toFloat) { + var num = toFloat ? parseFloat(value) : parseInt(value, 10); + return isNaN(num) ? 0 : num; + } + + /** + * Gets several information of the textarea and returns them as a object or undefined if the browser doesn't support it. + * @returns {{cursorRow: Number, cursorCol, rows: Number, cols: number, wRow: number, pos: number, max : number}} or undefined if not supported. + */ + function getTextareaInfo() { + //read needed values + var textareaCursorPosition = _targetElementNative.selectionStart; + if (textareaCursorPosition === undefined) + return; + + var textareaValue = _targetElement.val(); + var textareaLength = textareaValue[LEXICON.l]; + var textareaRowSplit = textareaValue.split('\n'); + var textareaLastRow = textareaRowSplit[LEXICON.l]; + var textareaCurrentCursorRowSplit = textareaValue.substr(0, textareaCursorPosition).split('\n'); + var widestRow = 0; + var textareaLastCol = 0; + var cursorRow = textareaCurrentCursorRowSplit[LEXICON.l]; + var cursorCol = textareaCurrentCursorRowSplit[textareaCurrentCursorRowSplit[LEXICON.l] - 1][LEXICON.l]; + var rowCols; + var i; + + //get widest Row and the last column of the textarea + for (i = 0; i < textareaRowSplit[LEXICON.l]; i++) { + rowCols = textareaRowSplit[i][LEXICON.l]; + if (rowCols > textareaLastCol) { + widestRow = i + 1; + textareaLastCol = rowCols; + } + } + + return { + _cursorRow: cursorRow, //cursorRow + _cursorColumn: cursorCol, //cursorCol + _rows: textareaLastRow, //rows + _columns: textareaLastCol, //cols + _widestRow: widestRow, //wRow + _cursorPosition: textareaCursorPosition, //pos + _cursorMax: textareaLength //max + }; + } + + /** + * Determines whether native overlay scrollbars are active. + * @returns {boolean} True if native overlay scrollbars are active, false otherwise. + */ + function nativeOverlayScrollbarsAreActive() { + return (_ignoreOverlayScrollbarHidingCache && (_nativeScrollbarIsOverlaid.x && _nativeScrollbarIsOverlaid.y)); + } + + /** + * Gets the element which is used to measure the content size. + * @returns {*} TextareaCover if target element is textarea else the ContentElement. + */ + function getContentMeasureElement() { + return _isTextarea ? _textareaCoverElement[0] : _contentElementNative; + } + + /** + * Generates a string which represents a HTML div with the given classes or attributes. + * @param classesOrAttrs The class of the div as string or a object which represents the attributes of the div. (The class attribute can also be written as "className".) + * @param content The content of the div as string. + * @returns {string} The concated string which represents a HTML div and its content. + */ + function generateDiv(classesOrAttrs, content) { + return '
' + + (content || _strEmpty) + + '
'; + } + + /** + * Selects or generates a div with the given class attribute. + * @param className The class names (divided by spaces) of the div which shall be selected or generated. + * @param selectParentOrOnlyChildren The parent element from which of the element shall be selected. (if undefined or boolean its hostElement) + * If its a boolean it decides whether only the children of the host element shall be selected. + * @returns {*} The generated or selected element. + */ + function selectOrGenerateDivByClass(className, selectParentOrOnlyChildren) { + var onlyChildren = type(selectParentOrOnlyChildren) == TYPES.b; + var selectParent = onlyChildren ? _hostElement : (selectParentOrOnlyChildren || _hostElement); + + return (_domExists && !selectParent[LEXICON.l]) + ? null + : _domExists + ? selectParent[onlyChildren ? 'children' : 'find'](_strDot + className.replace(/\s/g, _strDot)).eq(0) + : FRAMEWORK(generateDiv(className)) + } + + /** + * Gets the value of the given property from the given object. + * @param obj The object from which the property value shall be got. + * @param path The property of which the value shall be got. + * @returns {*} Returns the value of the searched property or undefined of the property wasn't found. + */ + function getObjectPropVal(obj, path) { + var splits = path.split(_strDot); + var i = 0; + var val; + for (; i < splits.length; i++) { + if (!obj[LEXICON.hOP](splits[i])) + return; + val = obj[splits[i]]; + if (i < splits.length && type(val) == TYPES.o) + obj = val; + } + return val; + } + + /** + * Sets the value of the given property from the given object. + * @param obj The object from which the property value shall be set. + * @param path The property of which the value shall be set. + * @param val The value of the property which shall be set. + */ + function setObjectPropVal(obj, path, val) { + var splits = path.split(_strDot); + var splitsLength = splits.length; + var i = 0; + var extendObj = {}; + var extendObjRoot = extendObj; + for (; i < splitsLength; i++) + extendObj = extendObj[splits[i]] = i + 1 < splitsLength ? {} : val; + FRAMEWORK.extend(obj, extendObjRoot, true); + } + + + //==== Utils Cache ====// + + /** + * Compares two values or objects and returns true if they aren't equal. + * @param current The first value or object which shall be compared. + * @param cache The second value or object which shall be compared. + * @param force If true the returned value is always true. + * @returns {boolean} True if both values or objects aren't equal or force is true, false otherwise. + */ + function checkCache(current, cache, force) { + if (force) + return force; + if (type(current) == TYPES.o && type(cache) == TYPES.o) { + for (var prop in current) { + if (prop !== 'c') { + if (current[LEXICON.hOP](prop) && cache[LEXICON.hOP](prop)) { + if (checkCache(current[prop], cache[prop])) + return true; + } + else { + return true; + } + } + } + } + else { + return current !== cache; + } + return false; + } + + + //==== Shortcuts ====// + + /** + * jQuery extend method shortcut with a appended "true" as first argument. + */ + function extendDeep() { + return FRAMEWORK.extend.apply(this, [true].concat([].slice.call(arguments))); + } + + /** + * jQuery addClass method shortcut. + */ + function addClass(el, classes) { + return _frameworkProto.addClass.call(el, classes); + } + + /** + * jQuery removeClass method shortcut. + */ + function removeClass(el, classes) { + return _frameworkProto.removeClass.call(el, classes); + } + + /** + * jQuery remove method shortcut. + */ + function remove(el) { + return _frameworkProto.remove.call(el); + } + + /** + * Finds the first child element with the given selector of the given element. + * @param el The root element from which the selector shall be valid. + * @param selector The selector of the searched element. + * @returns {*} The first element which is a child of the given element and matches the givens selector. + */ + function findFirst(el, selector) { + return _frameworkProto.find.call(el, selector).eq(0); + } + + + //==== API ====// + + /** + * Puts the instance to sleep. It wont respond to any changes in the DOM and won't update. Scrollbar Interactivity is also disabled as well as the resize handle. + * This behavior can be reset by calling the update method. + */ + _base.sleep = function () { + _sleeping = true; + }; + + /** + * Updates the plugin and DOM to the current options. + * This method should only be called if a update is 100% required. + * @param force True if every property shall be updated and the cache shall be ignored. + * !INTERNAL USAGE! : force can be a string "auto", "sync" or "zoom" too + * if "auto" then before a real update the content size and host element attributes gets checked, and if they changed only then the update method will be called. + * if "sync" then the async update process (MutationObserver or UpdateLoop) gets synchronized and a corresponding update takes place if one was needed due to pending changes. + * if "zoom" then a update takes place where it's assumed that content and host size changed + * @returns {boolean|undefined} + * If force is "sync" then a boolean is returned which indicates whether a update was needed due to pending changes. + * If force is "auto" then a boolean is returned whether a update was needed due to attribute or size changes. + * undefined otherwise. + */ + _base.update = function (force) { + if (_destroyed) + return; + + var attrsChanged; + var contentSizeC; + var isString = type(force) == TYPES.s; + var imgElementSelector = 'img'; + var imgElementLoadEvent = 'load'; + var doUpdateAuto; + var mutHost; + var mutContent; + + if (isString) { + if (force === _strAuto) { + attrsChanged = meaningfulAttrsChanged(); + contentSizeC = updateAutoContentSizeChanged(); + doUpdateAuto = attrsChanged || contentSizeC; + if (doUpdateAuto) { + update({ + _contentSizeChanged: contentSizeC, + _changedOptions: _initialized ? undefined : _currentPreparedOptions + }); + } + } + else if (force === _strSync) { + if (_mutationObserversConnected) { + mutHost = _mutationObserverHostCallback(_mutationObserverHost.takeRecords()); + mutContent = _mutationObserverContentCallback(_mutationObserverContent.takeRecords()); + } + else { + mutHost = _base.update(_strAuto); + } + } + else if (force === 'zoom') { + update({ + _hostSizeChanged: true, + _contentSizeChanged: true + }); + } + } + else { + force = _sleeping || force; + _sleeping = false; + if (!_base.update(_strSync) || force) + update({ _force: force }); + } + if (!_isTextarea) { + _contentElement.find(imgElementSelector).each(function (i, el) { + var index = COMPATIBILITY.inA(el, _imgs); + if (index === -1) + FRAMEWORK(el).off(imgElementLoadEvent, imgOnLoad).on(imgElementLoadEvent, imgOnLoad); + }); + } + return doUpdateAuto || mutHost || mutContent; + }; + + /** + Gets or sets the current options. The update method will be called automatically if new options were set. + * @param newOptions If new options are given, then the new options will be set, if new options aren't given (undefined or a not a plain object) then the current options will be returned. + * @param value If new options is a property path string, then this value will be used to set the option to which the property path string leads. + * @returns {*} + */ + _base.options = function (newOptions, value) { + var option = {}; + var changedOps; + + //return current options if newOptions are undefined or empty + if (FRAMEWORK.isEmptyObject(newOptions) || !FRAMEWORK.isPlainObject(newOptions)) { + if (type(newOptions) == TYPES.s) { + if (arguments.length > 1) { + setObjectPropVal(option, newOptions, value); + changedOps = setOptions(option); + } + else + return getObjectPropVal(_currentOptions, newOptions); + } + else + return _currentOptions; + } + else { + changedOps = setOptions(newOptions); + } + + if (!FRAMEWORK.isEmptyObject(changedOps)) { + update({ _changedOptions: changedOps }); + } + }; + + /** + * Restore the DOM, disconnects all observers, remove all resize observers and put the instance to sleep. + */ + _base.destroy = function () { + if (_destroyed) + return; + + //remove this instance from auto update loop + autoUpdateLoop.remove(_base); + + //disconnect all mutation observers + disconnectMutationObservers(); + + //remove all resize observers + setupResizeObserver(_sizeObserverElement); + setupResizeObserver(_sizeAutoObserverElement); + + //remove all extensions + for (var extName in _extensions) + _base.removeExt(extName); + + //remove all 'destroy' events + while (_destroyEvents[LEXICON.l] > 0) + _destroyEvents.pop()(); + + //remove all events from host element + setupHostMouseTouchEvents(true); + + //remove all helper / detection elements + if (_contentGlueElement) + remove(_contentGlueElement); + if (_contentArrangeElement) + remove(_contentArrangeElement); + if (_sizeAutoObserverAdded) + remove(_sizeAutoObserverElement); + + //remove all generated DOM + setupScrollbarsDOM(true); + setupScrollbarCornerDOM(true); + setupStructureDOM(true); + + //remove all generated image load events + for (var i = 0; i < _imgs[LEXICON.l]; i++) + FRAMEWORK(_imgs[i]).off('load', imgOnLoad); + _imgs = undefined; + + _destroyed = true; + _sleeping = true; + + //remove this instance from the instances list + INSTANCES(pluginTargetElement, 0); + dispatchCallback('onDestroyed'); + + //remove all properties and methods + //for (var property in _base) + // delete _base[property]; + //_base = undefined; + }; + + /** + * Scrolls to a given position or element. + * @param coordinates + * 1. Can be "coordinates" which looks like: + * { x : ?, y : ? } OR Object with x and y properties + * { left : ?, top : ? } OR Object with left and top properties + * { l : ?, t : ? } OR Object with l and t properties + * [ ?, ? ] OR Array where the first two element are the coordinates (first is x, second is y) + * ? A single value which stays for both axis + * A value can be a number, a string or a calculation. + * + * Operators: + * [NONE] The current scroll will be overwritten by the value. + * '+=' The value will be added to the current scroll offset + * '-=' The value will be subtracted from the current scroll offset + * '*=' The current scroll wil be multiplicated by the value. + * '/=' The current scroll wil be divided by the value. + * + * Units: + * [NONE] The value is the final scroll amount. final = (value * 1) + * 'px' Same as none + * '%' The value is dependent on the current scroll value. final = ((currentScrollValue / 100) * value) + * 'vw' The value is multiplicated by the viewport width. final = (value * viewportWidth) + * 'vh' The value is multiplicated by the viewport height. final = (value * viewportHeight) + * + * example final values: + * 200, '200px', '50%', '1vw', '1vh', '+=200', '/=1vw', '*=2px', '-=5vh', '+=33%', '+= 50% - 2px', '-= 1vw - 50%' + * + * 2. Can be a HTML or jQuery element: + * The final scroll offset is the offset (without margin) of the given HTML / jQuery element. + * + * 3. Can be a object with a HTML or jQuery element with additional settings: + * { + * el : [HTMLElement, jQuery element], MUST be specified, else this object isn't valid. + * scroll : [string, array, object], Default value is 'always'. + * block : [string, array, object], Default value is 'begin'. + * margin : [number, boolean, array, object] Default value is false. + * } + * + * Possible scroll settings are: + * 'always' Scrolls always. + * 'ifneeded' Scrolls only if the element isnt fully in view. + * 'never' Scrolls never. + * + * Possible block settings are: + * 'begin' Both axis shall be docked to the "begin" edge. - The element will be docked to the top and left edge of the viewport. + * 'end' Both axis shall be docked to the "end" edge. - The element will be docked to the bottom and right edge of the viewport. (If direction is RTL to the bottom and left edge.) + * 'center' Both axis shall be docked to "center". - The element will be centered in the viewport. + * 'nearest' The element will be docked to the nearest edge(s). + * + * Possible margin settings are: -- The actual margin of the element wont be affect, this option affects only the final scroll offset. + * [BOOLEAN] If true the css margin of the element will be used, if false no margin will be used. + * [NUMBER] The margin will be used for all edges. + * + * @param duration The duration of the scroll animation, OR a jQuery animation configuration object. + * @param easing The animation easing. + * @param complete The animation complete callback. + * @returns {{ + * position: {x: number, y: number}, + * ratio: {x: number, y: number}, + * max: {x: number, y: number}, + * handleOffset: {x: number, y: number}, + * handleLength: {x: number, y: number}, + * handleLengthRatio: {x: number, y: number}, t + * rackLength: {x: number, y: number}, + * isRTL: boolean, + * isRTLNormalized: boolean + * -}} + */ + _base.scroll = function (coordinates, duration, easing, complete) { + if (arguments.length === 0 || coordinates === undefined) { + var infoX = _scrollHorizontalInfo; + var infoY = _scrollVerticalInfo; + var normalizeInvert = _normalizeRTLCache && _isRTL && _rtlScrollBehavior.i; + var normalizeNegate = _normalizeRTLCache && _isRTL && _rtlScrollBehavior.n; + var scrollX = infoX._currentScroll; + var scrollXRatio = infoX._currentScrollRatio; + var maxScrollX = infoX._maxScroll; + scrollXRatio = normalizeInvert ? 1 - scrollXRatio : scrollXRatio; + scrollX = normalizeInvert ? maxScrollX - scrollX : scrollX; + scrollX *= normalizeNegate ? -1 : 1; + maxScrollX *= normalizeNegate ? -1 : 1; + + return { + position: { + x: scrollX, + y: infoY._currentScroll + }, + ratio: { + x: scrollXRatio, + y: infoY._currentScrollRatio + }, + max: { + x: maxScrollX, + y: infoY._maxScroll + }, + handleOffset: { + x: infoX._handleOffset, + y: infoY._handleOffset + }, + handleLength: { + x: infoX._handleLength, + y: infoY._handleLength + }, + handleLengthRatio: { + x: infoX._handleLengthRatio, + y: infoY._handleLengthRatio + }, + trackLength: { + x: infoX._trackLength, + y: infoY._trackLength + }, + snappedHandleOffset: { + x: infoX._snappedHandleOffset, + y: infoY._snappedHandleOffset + }, + isRTL: _isRTL, + isRTLNormalized: _normalizeRTLCache + }; + } + + _base.update(_strSync); + + var normalizeRTL = _normalizeRTLCache; + var coordinatesXAxisProps = [_strX, _strLeft, 'l']; + var coordinatesYAxisProps = [_strY, _strTop, 't']; + var coordinatesOperators = ['+=', '-=', '*=', '/=']; + var durationIsObject = type(duration) == TYPES.o; + var completeCallback = durationIsObject ? duration.complete : complete; + var i; + var finalScroll = {}; + var specialEasing = {}; + var doScrollLeft; + var doScrollTop; + var animationOptions; + var strEnd = 'end'; + var strBegin = 'begin'; + var strCenter = 'center'; + var strNearest = 'nearest'; + var strAlways = 'always'; + var strNever = 'never'; + var strIfNeeded = 'ifneeded'; + var strLength = LEXICON.l; + var settingsAxis; + var settingsScroll; + var settingsBlock; + var settingsMargin; + var finalElement; + var elementObjSettingsAxisValues = [_strX, _strY, 'xy', 'yx']; + var elementObjSettingsBlockValues = [strBegin, strEnd, strCenter, strNearest]; + var elementObjSettingsScrollValues = [strAlways, strNever, strIfNeeded]; + var coordinatesIsElementObj = coordinates[LEXICON.hOP]('el'); + var possibleElement = coordinatesIsElementObj ? coordinates.el : coordinates; + var possibleElementIsJQuery = possibleElement instanceof FRAMEWORK || JQUERY ? possibleElement instanceof JQUERY : false; + var possibleElementIsHTMLElement = possibleElementIsJQuery ? false : isHTMLElement(possibleElement); + var updateScrollbarInfos = function () { + if (doScrollLeft) + refreshScrollbarHandleOffset(true); + if (doScrollTop) + refreshScrollbarHandleOffset(false); + }; + var proxyCompleteCallback = type(completeCallback) != TYPES.f ? undefined : function () { + updateScrollbarInfos(); + completeCallback(); + }; + function checkSettingsStringValue(currValue, allowedValues) { + for (i = 0; i < allowedValues[strLength]; i++) { + if (currValue === allowedValues[i]) + return true; + } + return false; + } + function getRawScroll(isX, coordinates) { + var coordinateProps = isX ? coordinatesXAxisProps : coordinatesYAxisProps; + coordinates = type(coordinates) == TYPES.s || type(coordinates) == TYPES.n ? [coordinates, coordinates] : coordinates; + + if (type(coordinates) == TYPES.a) + return isX ? coordinates[0] : coordinates[1]; + else if (type(coordinates) == TYPES.o) { + //decides RTL normalization "hack" with .n + //normalizeRTL = type(coordinates.n) == TYPES.b ? coordinates.n : normalizeRTL; + for (i = 0; i < coordinateProps[strLength]; i++) + if (coordinateProps[i] in coordinates) + return coordinates[coordinateProps[i]]; + } + } + function getFinalScroll(isX, rawScroll) { + var isString = type(rawScroll) == TYPES.s; + var operator; + var amount; + var scrollInfo = isX ? _scrollHorizontalInfo : _scrollVerticalInfo; + var currScroll = scrollInfo._currentScroll; + var maxScroll = scrollInfo._maxScroll; + var mult = ' * '; + var finalValue; + var isRTLisX = _isRTL && isX; + var normalizeShortcuts = isRTLisX && _rtlScrollBehavior.n && !normalizeRTL; + var strReplace = 'replace'; + var evalFunc = eval; + var possibleOperator; + if (isString) { + //check operator + if (rawScroll[strLength] > 2) { + possibleOperator = rawScroll.substr(0, 2); + if (inArray(possibleOperator, coordinatesOperators) > -1) + operator = possibleOperator; + } + + //calculate units and shortcuts + rawScroll = operator ? rawScroll.substr(2) : rawScroll; + rawScroll = rawScroll + [strReplace](/min/g, 0) //'min' = 0% + [strReplace](//g, (normalizeShortcuts ? '-' : _strEmpty) + _strHundredPercent) //'>' = 100% + [strReplace](/px/g, _strEmpty) + [strReplace](/%/g, mult + (maxScroll * (isRTLisX && _rtlScrollBehavior.n ? -1 : 1) / 100.0)) + [strReplace](/vw/g, mult + _viewportSize.w) + [strReplace](/vh/g, mult + _viewportSize.h); + amount = parseToZeroOrNumber(isNaN(rawScroll) ? parseToZeroOrNumber(evalFunc(rawScroll), true).toFixed() : rawScroll); + } + else { + amount = rawScroll; + } + + if (amount !== undefined && !isNaN(amount) && type(amount) == TYPES.n) { + var normalizeIsRTLisX = normalizeRTL && isRTLisX; + var operatorCurrScroll = currScroll * (normalizeIsRTLisX && _rtlScrollBehavior.n ? -1 : 1); + var invert = normalizeIsRTLisX && _rtlScrollBehavior.i; + var negate = normalizeIsRTLisX && _rtlScrollBehavior.n; + operatorCurrScroll = invert ? (maxScroll - operatorCurrScroll) : operatorCurrScroll; + switch (operator) { + case '+=': + finalValue = operatorCurrScroll + amount; + break; + case '-=': + finalValue = operatorCurrScroll - amount; + break; + case '*=': + finalValue = operatorCurrScroll * amount; + break; + case '/=': + finalValue = operatorCurrScroll / amount; + break; + default: + finalValue = amount; + break; + } + finalValue = invert ? maxScroll - finalValue : finalValue; + finalValue *= negate ? -1 : 1; + finalValue = isRTLisX && _rtlScrollBehavior.n ? MATH.min(0, MATH.max(maxScroll, finalValue)) : MATH.max(0, MATH.min(maxScroll, finalValue)); + } + return finalValue === currScroll ? undefined : finalValue; + } + function getPerAxisValue(value, valueInternalType, defaultValue, allowedValues) { + var resultDefault = [defaultValue, defaultValue]; + var valueType = type(value); + var valueArrLength; + var valueArrItem; + + //value can be [ string, or array of two strings ] + if (valueType == valueInternalType) { + value = [value, value]; + } + else if (valueType == TYPES.a) { + valueArrLength = value[strLength]; + if (valueArrLength > 2 || valueArrLength < 1) + value = resultDefault; + else { + if (valueArrLength === 1) + value[1] = defaultValue; + for (i = 0; i < valueArrLength; i++) { + valueArrItem = value[i]; + if (type(valueArrItem) != valueInternalType || !checkSettingsStringValue(valueArrItem, allowedValues)) { + value = resultDefault; + break; + } + } + } + } + else if (valueType == TYPES.o) + value = [value[_strX] || defaultValue, value[_strY] || defaultValue]; + else + value = resultDefault; + return { x: value[0], y: value[1] }; + } + function generateMargin(marginTopRightBottomLeftArray) { + var result = []; + var currValue; + var currValueType; + var valueDirections = [_strTop, _strRight, _strBottom, _strLeft]; + for (i = 0; i < marginTopRightBottomLeftArray[strLength]; i++) { + if (i === valueDirections[strLength]) + break; + currValue = marginTopRightBottomLeftArray[i]; + currValueType = type(currValue); + if (currValueType == TYPES.b) + result.push(currValue ? parseToZeroOrNumber(finalElement.css(_strMarginMinus + valueDirections[i])) : 0); + else + result.push(currValueType == TYPES.n ? currValue : 0); + } + return result; + } + + if (possibleElementIsJQuery || possibleElementIsHTMLElement) { + //get settings + var margin = coordinatesIsElementObj ? coordinates.margin : 0; + var axis = coordinatesIsElementObj ? coordinates.axis : 0; + var scroll = coordinatesIsElementObj ? coordinates.scroll : 0; + var block = coordinatesIsElementObj ? coordinates.block : 0; + var marginDefault = [0, 0, 0, 0]; + var marginType = type(margin); + var marginLength; + finalElement = possibleElementIsJQuery ? possibleElement : FRAMEWORK(possibleElement); + + if (finalElement[strLength] > 0) { + //margin can be [ boolean, number, array of 2, array of 4, object ] + if (marginType == TYPES.n || marginType == TYPES.b) + margin = generateMargin([margin, margin, margin, margin]); + else if (marginType == TYPES.a) { + marginLength = margin[strLength]; + if (marginLength === 2) + margin = generateMargin([margin[0], margin[1], margin[0], margin[1]]); + else if (marginLength >= 4) + margin = generateMargin(margin); + else + margin = marginDefault; + } + else if (marginType == TYPES.o) + margin = generateMargin([margin[_strTop], margin[_strRight], margin[_strBottom], margin[_strLeft]]); + else + margin = marginDefault; + + //block = type(block) === TYPES.b ? block ? [ strNearest, strBegin ] : [ strNearest, strEnd ] : block; + settingsAxis = checkSettingsStringValue(axis, elementObjSettingsAxisValues) ? axis : 'xy'; + settingsScroll = getPerAxisValue(scroll, TYPES.s, strAlways, elementObjSettingsScrollValues); + settingsBlock = getPerAxisValue(block, TYPES.s, strBegin, elementObjSettingsBlockValues); + settingsMargin = margin; + + var viewportScroll = { + l: _scrollHorizontalInfo._currentScroll, + t: _scrollVerticalInfo._currentScroll + }; + // use padding element instead of viewport element because padding element has never padding, margin or position applied. + var viewportOffset = _paddingElement.offset(); + + //get coordinates + var elementOffset = finalElement.offset(); + var doNotScroll = { + x: settingsScroll.x == strNever || settingsAxis == _strY, + y: settingsScroll.y == strNever || settingsAxis == _strX + }; + elementOffset[_strTop] -= settingsMargin[0]; + elementOffset[_strLeft] -= settingsMargin[3]; + var elementScrollCoordinates = { + x: MATH.round(elementOffset[_strLeft] - viewportOffset[_strLeft] + viewportScroll.l), + y: MATH.round(elementOffset[_strTop] - viewportOffset[_strTop] + viewportScroll.t) + }; + if (_isRTL) { + if (!_rtlScrollBehavior.n && !_rtlScrollBehavior.i) + elementScrollCoordinates.x = MATH.round(viewportOffset[_strLeft] - elementOffset[_strLeft] + viewportScroll.l); + if (_rtlScrollBehavior.n && normalizeRTL) + elementScrollCoordinates.x *= -1; + if (_rtlScrollBehavior.i && normalizeRTL) + elementScrollCoordinates.x = MATH.round(viewportOffset[_strLeft] - elementOffset[_strLeft] + (_scrollHorizontalInfo._maxScroll - viewportScroll.l)); + } + + //measuring is required + if (settingsBlock.x != strBegin || settingsBlock.y != strBegin || settingsScroll.x == strIfNeeded || settingsScroll.y == strIfNeeded || _isRTL) { + var measuringElm = finalElement[0]; + var rawElementSize = _supportTransform ? measuringElm[LEXICON.bCR]() : { + width: measuringElm[LEXICON.oW], + height: measuringElm[LEXICON.oH] + }; + var elementSize = { + w: rawElementSize[_strWidth] + settingsMargin[3] + settingsMargin[1], + h: rawElementSize[_strHeight] + settingsMargin[0] + settingsMargin[2] + }; + var finalizeBlock = function (isX) { + var vars = getScrollbarVars(isX); + var wh = vars._w_h; + var lt = vars._left_top; + var xy = vars._x_y; + var blockIsEnd = settingsBlock[xy] == (isX ? _isRTL ? strBegin : strEnd : strEnd); + var blockIsCenter = settingsBlock[xy] == strCenter; + var blockIsNearest = settingsBlock[xy] == strNearest; + var scrollNever = settingsScroll[xy] == strNever; + var scrollIfNeeded = settingsScroll[xy] == strIfNeeded; + var vpSize = _viewportSize[wh]; + var vpOffset = viewportOffset[lt]; + var elSize = elementSize[wh]; + var elOffset = elementOffset[lt]; + var divide = blockIsCenter ? 2 : 1; + var elementCenterOffset = elOffset + (elSize / 2); + var viewportCenterOffset = vpOffset + (vpSize / 2); + var isInView = + elSize <= vpSize + && elOffset >= vpOffset + && elOffset + elSize <= vpOffset + vpSize; + + if (scrollNever) + doNotScroll[xy] = true; + else if (!doNotScroll[xy]) { + if (blockIsNearest || scrollIfNeeded) { + doNotScroll[xy] = scrollIfNeeded ? isInView : false; + blockIsEnd = elSize < vpSize ? elementCenterOffset > viewportCenterOffset : elementCenterOffset < viewportCenterOffset; + } + elementScrollCoordinates[xy] -= blockIsEnd || blockIsCenter ? ((vpSize / divide) - (elSize / divide)) * (isX && _isRTL && normalizeRTL ? -1 : 1) : 0; + } + }; + finalizeBlock(true); + finalizeBlock(false); + } + + if (doNotScroll.y) + delete elementScrollCoordinates.y; + if (doNotScroll.x) + delete elementScrollCoordinates.x; + + coordinates = elementScrollCoordinates; + } + } + + finalScroll[_strScrollLeft] = getFinalScroll(true, getRawScroll(true, coordinates)); + finalScroll[_strScrollTop] = getFinalScroll(false, getRawScroll(false, coordinates)); + doScrollLeft = finalScroll[_strScrollLeft] !== undefined; + doScrollTop = finalScroll[_strScrollTop] !== undefined; + + if ((doScrollLeft || doScrollTop) && (duration > 0 || durationIsObject)) { + if (durationIsObject) { + duration.complete = proxyCompleteCallback; + _viewportElement.animate(finalScroll, duration); + } + else { + animationOptions = { + duration: duration, + complete: proxyCompleteCallback + }; + if (type(easing) == TYPES.a || FRAMEWORK.isPlainObject(easing)) { + specialEasing[_strScrollLeft] = easing[0] || easing.x; + specialEasing[_strScrollTop] = easing[1] || easing.y; + animationOptions.specialEasing = specialEasing; + } + else { + animationOptions.easing = easing; + } + _viewportElement.animate(finalScroll, animationOptions); + } + } + else { + if (doScrollLeft) + _viewportElement[_strScrollLeft](finalScroll[_strScrollLeft]); + if (doScrollTop) + _viewportElement[_strScrollTop](finalScroll[_strScrollTop]); + updateScrollbarInfos(); + } + }; + + /** + * Stops all scroll animations. + * @returns {*} The current OverlayScrollbars instance (for chaining). + */ + _base.scrollStop = function (param1, param2, param3) { + _viewportElement.stop(param1, param2, param3); + return _base; + }; + + /** + * Returns all relevant elements. + * @param elementName The name of the element which shall be returned. + * @returns {{target: *, host: *, padding: *, viewport: *, content: *, scrollbarHorizontal: {scrollbar: *, track: *, handle: *}, scrollbarVertical: {scrollbar: *, track: *, handle: *}, scrollbarCorner: *} | *} + */ + _base.getElements = function (elementName) { + var obj = { + target: _targetElementNative, + host: _hostElementNative, + padding: _paddingElementNative, + viewport: _viewportElementNative, + content: _contentElementNative, + scrollbarHorizontal: { + scrollbar: _scrollbarHorizontalElement[0], + track: _scrollbarHorizontalTrackElement[0], + handle: _scrollbarHorizontalHandleElement[0] + }, + scrollbarVertical: { + scrollbar: _scrollbarVerticalElement[0], + track: _scrollbarVerticalTrackElement[0], + handle: _scrollbarVerticalHandleElement[0] + }, + scrollbarCorner: _scrollbarCornerElement[0] + }; + return type(elementName) == TYPES.s ? getObjectPropVal(obj, elementName) : obj; + }; + + /** + * Returns a object which describes the current state of this instance. + * @param stateProperty A specific property from the state object which shall be returned. + * @returns {{widthAuto, heightAuto, overflowAmount, hideOverflow, hasOverflow, contentScrollSize, viewportSize, hostSize, autoUpdate} | *} + */ + _base.getState = function (stateProperty) { + function prepare(obj) { + if (!FRAMEWORK.isPlainObject(obj)) + return obj; + var extended = extendDeep({}, obj); + var changePropertyName = function (from, to) { + if (extended[LEXICON.hOP](from)) { + extended[to] = extended[from]; + delete extended[from]; + } + }; + changePropertyName('w', _strWidth); //change w to width + changePropertyName('h', _strHeight); //change h to height + delete extended.c; //delete c (the 'changed' prop) + return extended; + }; + var obj = { + destroyed: !!prepare(_destroyed), + sleeping: !!prepare(_sleeping), + autoUpdate: prepare(!_mutationObserversConnected), + widthAuto: prepare(_widthAutoCache), + heightAuto: prepare(_heightAutoCache), + padding: prepare(_cssPaddingCache), + overflowAmount: prepare(_overflowAmountCache), + hideOverflow: prepare(_hideOverflowCache), + hasOverflow: prepare(_hasOverflowCache), + contentScrollSize: prepare(_contentScrollSizeCache), + viewportSize: prepare(_viewportSize), + hostSize: prepare(_hostSizeCache), + documentMixed: prepare(_documentMixed) + }; + return type(stateProperty) == TYPES.s ? getObjectPropVal(obj, stateProperty) : obj; + }; + + /** + * Gets all or specific extension instance. + * @param extName The name of the extension from which the instance shall be got. + * @returns {{}} The instance of the extension with the given name or undefined if the instance couldn't be found. + */ + _base.ext = function (extName) { + var result; + var privateMethods = _extensionsPrivateMethods.split(' '); + var i = 0; + if (type(extName) == TYPES.s) { + if (_extensions[LEXICON.hOP](extName)) { + result = extendDeep({}, _extensions[extName]); + for (; i < privateMethods.length; i++) + delete result[privateMethods[i]]; + } + } + else { + result = {}; + for (i in _extensions) + result[i] = extendDeep({}, _base.ext(i)); + } + return result; + }; + + /** + * Adds a extension to this instance. + * @param extName The name of the extension which shall be added. + * @param extensionOptions The extension options which shall be used. + * @returns {{}} The instance of the added extension or undefined if the extension couldn't be added properly. + */ + _base.addExt = function (extName, extensionOptions) { + var registeredExtensionObj = _plugin.extension(extName); + var instance; + var instanceAdded; + var instanceContract; + var contractResult; + var contractFulfilled = true; + if (registeredExtensionObj) { + if (!_extensions[LEXICON.hOP](extName)) { + instance = registeredExtensionObj.extensionFactory.call(_base, + extendDeep({}, registeredExtensionObj.defaultOptions), + FRAMEWORK, + COMPATIBILITY); + + if (instance) { + instanceContract = instance.contract; + if (type(instanceContract) == TYPES.f) { + contractResult = instanceContract(window); + contractFulfilled = type(contractResult) == TYPES.b ? contractResult : contractFulfilled; + } + if (contractFulfilled) { + _extensions[extName] = instance; + instanceAdded = instance.added; + if (type(instanceAdded) == TYPES.f) + instanceAdded(extensionOptions); + + return _base.ext(extName); + } + } + } + else + return _base.ext(extName); + } + else + console.warn("A extension with the name \"" + extName + "\" isn't registered."); + }; + + /** + * Removes a extension from this instance. + * @param extName The name of the extension which shall be removed. + * @returns {boolean} True if the extension was removed, false otherwise e.g. if the extension wasn't added before. + */ + _base.removeExt = function (extName) { + var instance = _extensions[extName]; + var instanceRemoved; + if (instance) { + delete _extensions[extName]; + + instanceRemoved = instance.removed; + if (type(instanceRemoved) == TYPES.f) + instanceRemoved(); + + return true; + } + return false; + }; + + /** + * Constructs the plugin. + * @param targetElement The element to which the plugin shall be applied. + * @param options The initial options of the plugin. + * @param extensions The extension(s) which shall be added right after the initialization. + * @returns {boolean} True if the plugin was successfully initialized, false otherwise. + */ + function construct(targetElement, options, extensions) { + _defaultOptions = globals.defaultOptions; + _nativeScrollbarStyling = globals.nativeScrollbarStyling; + _nativeScrollbarSize = extendDeep({}, globals.nativeScrollbarSize); + _nativeScrollbarIsOverlaid = extendDeep({}, globals.nativeScrollbarIsOverlaid); + _overlayScrollbarDummySize = extendDeep({}, globals.overlayScrollbarDummySize); + _rtlScrollBehavior = extendDeep({}, globals.rtlScrollBehavior); + + //parse & set options but don't update + setOptions(extendDeep({}, _defaultOptions, options)); + + _cssCalc = globals.cssCalc; + _msieVersion = globals.msie; + _autoUpdateRecommended = globals.autoUpdateRecommended; + _supportTransition = globals.supportTransition; + _supportTransform = globals.supportTransform; + _supportPassiveEvents = globals.supportPassiveEvents; + _supportResizeObserver = globals.supportResizeObserver; + _supportMutationObserver = globals.supportMutationObserver; + _restrictedMeasuring = globals.restrictedMeasuring; + _documentElement = FRAMEWORK(targetElement.ownerDocument); + _documentElementNative = _documentElement[0]; + _windowElement = FRAMEWORK(_documentElementNative.defaultView || _documentElementNative.parentWindow); + _windowElementNative = _windowElement[0]; + _htmlElement = findFirst(_documentElement, 'html'); + _bodyElement = findFirst(_htmlElement, 'body'); + _targetElement = FRAMEWORK(targetElement); + _targetElementNative = _targetElement[0]; + _isTextarea = _targetElement.is('textarea'); + _isBody = _targetElement.is('body'); + _documentMixed = _documentElementNative !== document; + + /* On a div Element The if checks only whether: + * - the targetElement has the class "os-host" + * - the targetElement has a a child with the class "os-padding" + * + * If that's the case, its assumed the DOM has already the following structure: + * (The ".os-host" element is the targetElement) + * + *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ * + * ===================================================================================== + * + * On a Textarea Element The if checks only whether: + * - the targetElement has the class "os-textarea" + * - the targetElement is inside a element with the class "os-content" + * + * If that's the case, its assumed the DOM has already the following structure: + * (The ".os-textarea" (textarea) element is the targetElement) + * + *
+ *
+ *
+ *
+ *
+ *
+ * + *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ */ + _domExists = _isTextarea + ? _targetElement.hasClass(_classNameTextareaElement) && _targetElement.parent().hasClass(_classNameContentElement) + : _targetElement.hasClass(_classNameHostElement) && _targetElement.children(_strDot + _classNamePaddingElement)[LEXICON.l]; + + var initBodyScroll; + var bodyMouseTouchDownListener; + + //check if the plugin hasn't to be initialized + if (_nativeScrollbarIsOverlaid.x && _nativeScrollbarIsOverlaid.y && !_currentPreparedOptions.nativeScrollbarsOverlaid.initialize) { + dispatchCallback('onInitializationWithdrawn'); + if (_domExists) { + setupStructureDOM(true); + setupScrollbarsDOM(true); + setupScrollbarCornerDOM(true); + } + + _destroyed = true; + _sleeping = true; + + return _base; + } + + if (_isBody) { + initBodyScroll = {}; + initBodyScroll.l = MATH.max(_targetElement[_strScrollLeft](), _htmlElement[_strScrollLeft](), _windowElement[_strScrollLeft]()); + initBodyScroll.t = MATH.max(_targetElement[_strScrollTop](), _htmlElement[_strScrollTop](), _windowElement[_strScrollTop]()); + + bodyMouseTouchDownListener = function () { + _viewportElement.removeAttr(LEXICON.ti); + setupResponsiveEventListener(_viewportElement, _strMouseTouchDownEvent, bodyMouseTouchDownListener, true, true); + } + } + + //build OverlayScrollbars DOM + setupStructureDOM(); + setupScrollbarsDOM(); + setupScrollbarCornerDOM(); + + //create OverlayScrollbars events + setupStructureEvents(); + setupScrollbarEvents(true); + setupScrollbarEvents(false); + setupScrollbarCornerEvents(); + + //create mutation observers + createMutationObservers(); + + //build resize observer for the host element + setupResizeObserver(_sizeObserverElement, hostOnResized); + + if (_isBody) { + //apply the body scroll to handle it right in the update method + _viewportElement[_strScrollLeft](initBodyScroll.l)[_strScrollTop](initBodyScroll.t); + + //set the focus on the viewport element so you dont have to click on the page to use keyboard keys (up / down / space) for scrolling + if (document.activeElement == targetElement && _viewportElementNative.focus) { + //set a tabindex to make the viewportElement focusable + _viewportElement.attr(LEXICON.ti, '-1'); + _viewportElementNative.focus(); + + /* the tabindex has to be removed due to; + * If you set the tabindex attribute on an
, then its child content cannot be scrolled with the arrow keys unless you set tabindex on the content, too + * https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex + */ + setupResponsiveEventListener(_viewportElement, _strMouseTouchDownEvent, bodyMouseTouchDownListener, false, true); + } + } + + //update for the first time & initialize cache + _base.update(_strAuto); + + //the plugin is initialized now! + _initialized = true; + dispatchCallback('onInitialized'); + + //call all callbacks which would fire before the initialized was complete + each(_callbacksInitQeueue, function (index, value) { dispatchCallback(value.n, value.a); }); + _callbacksInitQeueue = []; + + //add extensions + if (type(extensions) == TYPES.s) + extensions = [extensions]; + if (COMPATIBILITY.isA(extensions)) + each(extensions, function (index, value) { _base.addExt(value); }); + else if (FRAMEWORK.isPlainObject(extensions)) + each(extensions, function (key, value) { _base.addExt(key, value); }); + + //add the transition class for transitions AFTER the first update & AFTER the applied extensions (for preventing unwanted transitions) + setTimeout(function () { + if (_supportTransition && !_destroyed) + addClass(_hostElement, _classNameHostTransition); + }, 333); + + return _base; + } + + if (_plugin.valid(construct(pluginTargetElement, options, extensions))) { + INSTANCES(pluginTargetElement, _base); + } + + return _base; + } + + /** + * Initializes a new OverlayScrollbarsInstance object or changes options if already initialized or returns the current instance. + * @param pluginTargetElements The elements to which the Plugin shall be initialized. + * @param options The custom options with which the plugin shall be initialized. + * @param extensions The extension(s) which shall be added right after initialization. + * @returns {*} + */ + _plugin = window[PLUGINNAME] = function (pluginTargetElements, options, extensions) { + if (arguments[LEXICON.l] === 0) + return this; + + var arr = []; + var optsIsPlainObj = FRAMEWORK.isPlainObject(options); + var inst; + var result; + + //pluginTargetElements is null or undefined + if (!pluginTargetElements) + return optsIsPlainObj || !options ? result : arr; + + /* + pluginTargetElements will be converted to: + 1. A jQueryElement Array + 2. A HTMLElement Array + 3. A Array with a single HTML Element + so pluginTargetElements is always a array. + */ + pluginTargetElements = pluginTargetElements[LEXICON.l] != undefined ? pluginTargetElements : [pluginTargetElements[0] || pluginTargetElements]; + initOverlayScrollbarsStatics(); + + if (pluginTargetElements[LEXICON.l] > 0) { + if (optsIsPlainObj) { + FRAMEWORK.each(pluginTargetElements, function (i, v) { + inst = v; + if (inst !== undefined) + arr.push(OverlayScrollbarsInstance(inst, options, extensions, _pluginsGlobals, _pluginsAutoUpdateLoop)); + }); + } + else { + FRAMEWORK.each(pluginTargetElements, function (i, v) { + inst = INSTANCES(v); + if ((options === '!' && _plugin.valid(inst)) || (COMPATIBILITY.type(options) == TYPES.f && options(v, inst))) + arr.push(inst); + else if (options === undefined) + arr.push(inst); + }); + } + result = arr[LEXICON.l] === 1 ? arr[0] : arr; + } + return result; + }; + + /** + * Returns a object which contains global information about the plugin and each instance of it. + * The returned object is just a copy, that means that changes to the returned object won't have any effect to the original object. + */ + _plugin.globals = function () { + initOverlayScrollbarsStatics(); + var globals = FRAMEWORK.extend(true, {}, _pluginsGlobals); + delete globals['msie']; + return globals; + }; + + /** + * Gets or Sets the default options for each new plugin initialization. + * @param newDefaultOptions The object with which the default options shall be extended. + */ + _plugin.defaultOptions = function (newDefaultOptions) { + initOverlayScrollbarsStatics(); + var currDefaultOptions = _pluginsGlobals.defaultOptions; + if (newDefaultOptions === undefined) + return FRAMEWORK.extend(true, {}, currDefaultOptions); + + //set the new default options + _pluginsGlobals.defaultOptions = FRAMEWORK.extend(true, {}, currDefaultOptions, _pluginsOptions._validate(newDefaultOptions, _pluginsOptions._template, true, currDefaultOptions)._default); + }; + + /** + * Checks whether the passed instance is a non-destroyed OverlayScrollbars instance. + * @param osInstance The potential OverlayScrollbars instance which shall be checked. + * @returns {boolean} True if the passed value is a non-destroyed OverlayScrollbars instance, false otherwise. + */ + _plugin.valid = function (osInstance) { + return osInstance instanceof _plugin && !osInstance.getState().destroyed; + }; + + /** + * Registers, Unregisters or returns a extension. + * Register: Pass the name and the extension. (defaultOptions is optional) + * Unregister: Pass the name and anything except a function as extension parameter. + * Get extension: Pass the name of the extension which shall be got. + * Get all extensions: Pass no arguments. + * @param extensionName The name of the extension which shall be registered, unregistered or returned. + * @param extension A function which generates the instance of the extension or anything other to remove a already registered extension. + * @param defaultOptions The default options which shall be used for the registered extension. + */ + _plugin.extension = function (extensionName, extension, defaultOptions) { + var extNameTypeString = COMPATIBILITY.type(extensionName) == TYPES.s; + var argLen = arguments[LEXICON.l]; + var i = 0; + if (argLen < 1 || !extNameTypeString) { + //return a copy of all extension objects + return FRAMEWORK.extend(true, { length: _pluginsExtensions[LEXICON.l] }, _pluginsExtensions); + } + else if (extNameTypeString) { + if (COMPATIBILITY.type(extension) == TYPES.f) { + //register extension + _pluginsExtensions.push({ + name: extensionName, + extensionFactory: extension, + defaultOptions: defaultOptions + }); + } + else { + for (; i < _pluginsExtensions[LEXICON.l]; i++) { + if (_pluginsExtensions[i].name === extensionName) { + if (argLen > 1) + _pluginsExtensions.splice(i, 1); //remove extension + else + return FRAMEWORK.extend(true, {}, _pluginsExtensions[i]); //return extension with the given name + } + } + } + } + }; + + return _plugin; + })(); + + if (JQUERY && JQUERY.fn) { + /** + * The jQuery initialization interface. + * @param options The initial options for the construction of the plugin. To initialize the plugin, this option has to be a object! If it isn't a object, the instance(s) are returned and the plugin wont be initialized. + * @param extensions The extension(s) which shall be added right after initialization. + * @returns {*} After initialization it returns the jQuery element array, else it returns the instance(s) of the elements which are selected. + */ + JQUERY.fn.overlayScrollbars = function (options, extensions) { + var _elements = this; + if (JQUERY.isPlainObject(options)) { + JQUERY.each(_elements, function () { PLUGIN(this, options, extensions); }); + return _elements; + } + else + return PLUGIN(_elements, options); + }; + } + return PLUGIN; + } +)); diff --git a/public/plugins/overlayScrollbars/js/jquery.overlayScrollbars.js b/public/plugins/overlayScrollbars/js/jquery.overlayScrollbars.js index 4383b712..8c2ed4f5 100755 --- a/public/plugins/overlayScrollbars/js/jquery.overlayScrollbars.js +++ b/public/plugins/overlayScrollbars/js/jquery.overlayScrollbars.js @@ -1,5571 +1,5571 @@ -/*! - * OverlayScrollbars - * https://github.com/KingSora/OverlayScrollbars - * - * Version: 1.11.0 - * - * Copyright KingSora | Rene Haas. - * https://github.com/KingSora - * - * Released under the MIT license. - * Date: 29.02.2020 - */ - -(function (global, factory) { - if (typeof define === 'function' && define.amd) - define(['jquery'], function(framework) { return factory(global, global.document, undefined, framework); }); - else if (typeof module === 'object' && typeof module.exports === 'object') - module.exports = factory(global, global.document, undefined, require('jquery')); - else - factory(global, global.document, undefined, global.jQuery); -}(typeof window !== 'undefined' ? window : this, - function(window, document, undefined, framework) { - 'use strict'; - var PLUGINNAME = 'OverlayScrollbars'; - var TYPES = { - o : 'object', - f : 'function', - a : 'array', - s : 'string', - b : 'boolean', - n : 'number', - u : 'undefined', - z : 'null' - //d : 'date', - //e : 'error', - //r : 'regexp', - //y : 'symbol' - }; - var LEXICON = { - c: 'class', - s: 'style', - i: 'id', - l: 'length', - p: 'prototype', - ti: 'tabindex', - oH: 'offsetHeight', - cH: 'clientHeight', - sH: 'scrollHeight', - oW: 'offsetWidth', - cW: 'clientWidth', - sW: 'scrollWidth', - hOP: 'hasOwnProperty', - bCR: 'getBoundingClientRect' - }; - var VENDORS = (function() { - //https://developer.mozilla.org/en-US/docs/Glossary/Vendor_Prefix - var jsCache = { }; - var cssCache = { }; - var cssPrefixes = ['-webkit-', '-moz-', '-o-', '-ms-']; - var jsPrefixes = ['WebKit', 'Moz', 'O', 'MS']; - function firstLetterToUpper(str) { - return str.charAt(0).toUpperCase() + str.slice(1); - } - - return { - _cssPrefixes: cssPrefixes, - _jsPrefixes: jsPrefixes, - _cssProperty : function(name) { - var result = cssCache[name]; - - if(cssCache[LEXICON.hOP](name)) - return result; - - var uppercasedName = firstLetterToUpper(name); - var elmStyle = document.createElement('div')[LEXICON.s]; - var resultPossibilities; - var i = 0; - var v; - var currVendorWithoutDashes; - - for (; i < cssPrefixes.length; i++) { - currVendorWithoutDashes = cssPrefixes[i].replace(/-/g, ''); - resultPossibilities = [ - name, //transition - cssPrefixes[i] + name, //-webkit-transition - currVendorWithoutDashes + uppercasedName, //webkitTransition - firstLetterToUpper(currVendorWithoutDashes) + uppercasedName //WebkitTransition - ]; - for(v = 0; v < resultPossibilities[LEXICON.l]; v++) { - if(elmStyle[resultPossibilities[v]] !== undefined) { - result = resultPossibilities[v]; - break; - } - } - } - - cssCache[name] = result; - return result; - }, - _jsAPI : function(name, isInterface, fallback) { - var i = 0; - var result = jsCache[name]; - - if(!jsCache[LEXICON.hOP](name)) { - result = window[name]; - for(; i < jsPrefixes[LEXICON.l]; i++) - result = result || window[(isInterface ? jsPrefixes[i] : jsPrefixes[i].toLowerCase()) + firstLetterToUpper(name)]; - jsCache[name] = result; - } - return result || fallback; - } - - } - })(); - var COMPATIBILITY = (function() { - function windowSize(x) { - return x ? window.innerWidth || document.documentElement[LEXICON.cW] || document.body[LEXICON.cW] : window.innerHeight || document.documentElement[LEXICON.cH] || document.body[LEXICON.cH]; - } - function bind(func, thisObj) { - if (typeof func != TYPES.f) { - throw "Can't bind function!"; - // closest thing possible to the ECMAScript 5 - // internal IsCallable function - //throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable'); - } - var proto = LEXICON.p; - var aArgs = Array[proto].slice.call(arguments, 2); - var fNOP = function() {}; - var fBound = function() { return func.apply(this instanceof fNOP ? this : thisObj, aArgs.concat(Array[proto].slice.call(arguments))); }; - - if (func[proto]) - fNOP[proto] = func[proto]; // Function.prototype doesn't have a prototype property - fBound[proto] = new fNOP(); - - return fBound; - } - - return { - /** - * Gets the current window width. - * @returns {Number|number} The current window width in pixel. - */ - wW: bind(windowSize, 0, true), - - /** - * Gets the current window height. - * @returns {Number|number} The current window height in pixel. - */ - wH: bind(windowSize, 0), - - /** - * Gets the MutationObserver Object or undefined if not supported. - * @returns {MutationObserver|*|undefined} The MutationsObserver Object or undefined. - */ - mO: bind(VENDORS._jsAPI, 0, 'MutationObserver', true), - - /** - * Gets the ResizeObserver Object or undefined if not supported. - * @returns {MutationObserver|*|undefined} The ResizeObserver Object or undefined. - */ - rO: bind(VENDORS._jsAPI, 0, 'ResizeObserver', true), - - /** - * Gets the RequestAnimationFrame method or it's corresponding polyfill. - * @returns {*|Function} The RequestAnimationFrame method or it's corresponding polyfill. - */ - rAF: bind(VENDORS._jsAPI, 0, 'requestAnimationFrame', false, function (func) { return window.setTimeout(func, 1000 / 60); }), - - /** - * Gets the CancelAnimationFrame method or it's corresponding polyfill. - * @returns {*|Function} The CancelAnimationFrame method or it's corresponding polyfill. - */ - cAF: bind(VENDORS._jsAPI, 0, 'cancelAnimationFrame', false, function (id) { return window.clearTimeout(id); }), - - /** - * Gets the current time. - * @returns {number} The current time. - */ - now: function() { - return Date.now && Date.now() || new Date().getTime(); - }, - - /** - * Stops the propagation of the given event. - * @param event The event of which the propagation shall be stoped. - */ - stpP: function(event) { - if(event.stopPropagation) - event.stopPropagation(); - else - event.cancelBubble = true; - }, - - /** - * Prevents the default action of the given event. - * @param event The event of which the default action shall be prevented. - */ - prvD: function(event) { - if(event.preventDefault && event.cancelable) - event.preventDefault(); - else - event.returnValue = false; - }, - - /** - * Gets the pageX and pageY values of the given mouse event. - * @param event The mouse event of which the pageX and pageX shall be got. - * @returns {{x: number, y: number}} x = pageX value, y = pageY value. - */ - page: function(event) { - event = event.originalEvent || event; - - var strPage = 'page'; - var strClient = 'client'; - var strX = 'X'; - var strY = 'Y'; - var target = event.target || event.srcElement || document; - var eventDoc = target.ownerDocument || document; - var doc = eventDoc.documentElement; - var body = eventDoc.body; - - //if touch event return return pageX/Y of it - if(event.touches !== undefined) { - var touch = event.touches[0]; - return { - x : touch[strPage + strX], - y : touch[strPage + strY] - } - } - - // Calculate pageX/Y if not native supported - if (!event[strPage + strX] && event[strClient + strX] && event[strClient + strX] != null) { - - return { - x : event[strClient + strX] + - (doc && doc.scrollLeft || body && body.scrollLeft || 0) - - (doc && doc.clientLeft || body && body.clientLeft || 0), - y : event[strClient + strY] + - (doc && doc.scrollTop || body && body.scrollTop || 0) - - (doc && doc.clientTop || body && body.clientTop || 0) - } - } - return { - x : event[strPage + strX], - y : event[strPage + strY] - }; - }, - - /** - * Gets the clicked mouse button of the given mouse event. - * @param event The mouse event of which the clicked button shal be got. - * @returns {number} The number of the clicked mouse button. (0 : none | 1 : leftButton | 2 : middleButton | 3 : rightButton) - */ - mBtn: function(event) { - var button = event.button; - if (!event.which && button !== undefined) - return (button & 1 ? 1 : (button & 2 ? 3 : (button & 4 ? 2 : 0))); - else - return event.which; - }, - - /** - * Checks whether a item is in the given array and returns its index. - * @param item The item of which the position in the array shall be determined. - * @param arr The array. - * @returns {number} The zero based index of the item or -1 if the item isn't in the array. - */ - inA : function(item, arr) { - for (var i = 0; i < arr[LEXICON.l]; i++) - //Sometiems in IE a "SCRIPT70" Permission denied error occurs if HTML elements in a iFrame are compared - try { - if (arr[i] === item) - return i; - } - catch(e) { } - return -1; - }, - - /** - * Returns true if the given value is a array. - * @param arr The potential array. - * @returns {boolean} True if the given value is a array, false otherwise. - */ - isA: function(arr) { - var def = Array.isArray; - return def ? def(arr) : this.type(arr) == TYPES.a; - }, - - /** - * Determine the internal JavaScript [[Class]] of the given object. - * @param obj The object of which the type shall be determined. - * @returns {string} The type of the given object. - */ - type: function(obj) { - if (obj === undefined) - return obj + ''; - if (obj === null) - return obj + ''; - return Object[LEXICON.p].toString.call(obj).replace(/^\[object (.+)\]$/, '$1').toLowerCase(); - }, - - - bind: bind - - /** - * Gets the vendor-prefixed CSS property by the given name. - * For example the given name is "transform" and you're using a old Firefox browser then the returned value would be "-moz-transform". - * If the browser doesn't need a vendor-prefix, then the returned string is the given name. - * If the browser doesn't support the given property name at all (not even with a vendor-prefix) the returned value is null. - * @param propName The unprefixed CSS property name. - * @returns {string|null} The vendor-prefixed CSS property or null if the browser doesn't support the given CSS property. - - cssProp: function(propName) { - return VENDORS._cssProperty(propName); - } - */ - } - })(); - - var MATH = Math; - var JQUERY = framework; - var EASING = framework.easing; - var FRAMEWORK = framework; - var INSTANCES = (function () { - var _targets = []; - var _instancePropertyString = '__overlayScrollbars__'; - - /** - * Register, unregister or get a certain (or all) instances. - * Register: Pass the target and the instance. - * Unregister: Pass the target and null. - * Get Instance: Pass the target from which the instance shall be got. - * Get Targets: Pass no arguments. - * @param target The target to which the instance shall be registered / from which the instance shall be unregistered / the instance shall be got - * @param instance The instance. - * @returns {*|void} Returns the instance from the given target. - */ - return function (target, instance) { - var argLen = arguments[LEXICON.l]; - if (argLen < 1) { - //return all targets - return _targets; - } - else { - if (instance) { - //register instance - target[_instancePropertyString] = instance; - _targets.push(target); - } - else { - var index = COMPATIBILITY.inA(target, _targets); - if (index > -1) { - if (argLen > 1) { - //unregister instance - delete target[_instancePropertyString]; - _targets.splice(index, 1); - } - else { - //get instance from target - return _targets[index][_instancePropertyString]; - } - } - } - } - } - })(); - var PLUGIN = (function () { - var _plugin; - var _pluginsGlobals; - var _pluginsAutoUpdateLoop; - var _pluginsExtensions = []; - var _pluginsOptions = (function () { - var type = COMPATIBILITY.type; - var possibleTemplateTypes = [ - TYPES.b, //boolean - TYPES.n, //number - TYPES.s, //string - TYPES.a, //array - TYPES.o, //object - TYPES.f, //function - TYPES.z //null - ]; - var restrictedStringsSplit = ' '; - var restrictedStringsPossibilitiesSplit = ':'; - var classNameAllowedValues = [TYPES.z, TYPES.s]; - var numberAllowedValues = TYPES.n; - var booleanNullAllowedValues = [TYPES.z, TYPES.b]; - var booleanTrueTemplate = [true, TYPES.b]; - var booleanFalseTemplate = [false, TYPES.b]; - var callbackTemplate = [null, [TYPES.z, TYPES.f]]; - var inheritedAttrsTemplate = [['style', 'class'], [TYPES.s, TYPES.a, TYPES.z]]; - var resizeAllowedValues = 'n:none b:both h:horizontal v:vertical'; - var overflowBehaviorAllowedValues = 'v-h:visible-hidden v-s:visible-scroll s:scroll h:hidden'; - var scrollbarsVisibilityAllowedValues = 'v:visible h:hidden a:auto'; - var scrollbarsAutoHideAllowedValues = 'n:never s:scroll l:leave m:move'; - var optionsDefaultsAndTemplate = { - className: ['os-theme-dark', classNameAllowedValues], //null || string - resize: ['none', resizeAllowedValues], //none || both || horizontal || vertical || n || b || h || v - sizeAutoCapable: booleanTrueTemplate, //true || false - clipAlways: booleanTrueTemplate, //true || false - normalizeRTL: booleanTrueTemplate, //true || false - paddingAbsolute: booleanFalseTemplate, //true || false - autoUpdate: [null, booleanNullAllowedValues], //true || false || null - autoUpdateInterval: [33, numberAllowedValues], //number - nativeScrollbarsOverlaid: { - showNativeScrollbars: booleanFalseTemplate, //true || false - initialize: booleanTrueTemplate //true || false - }, - overflowBehavior: { - x: ['scroll', overflowBehaviorAllowedValues], //visible-hidden || visible-scroll || hidden || scroll || v-h || v-s || h || s - y: ['scroll', overflowBehaviorAllowedValues] //visible-hidden || visible-scroll || hidden || scroll || v-h || v-s || h || s - }, - scrollbars: { - visibility: ['auto', scrollbarsVisibilityAllowedValues], //visible || hidden || auto || v || h || a - autoHide: ['never', scrollbarsAutoHideAllowedValues], //never || scroll || leave || move || n || s || l || m - autoHideDelay: [800, numberAllowedValues], //number - dragScrolling: booleanTrueTemplate, //true || false - clickScrolling: booleanFalseTemplate, //true || false - touchSupport: booleanTrueTemplate, //true || false - snapHandle: booleanFalseTemplate //true || false - }, - textarea: { - dynWidth: booleanFalseTemplate, //true || false - dynHeight: booleanFalseTemplate, //true || false - inheritedAttrs: inheritedAttrsTemplate //string || array || null - }, - callbacks: { - onInitialized: callbackTemplate, //null || function - onInitializationWithdrawn: callbackTemplate, //null || function - onDestroyed: callbackTemplate, //null || function - onScrollStart: callbackTemplate, //null || function - onScroll: callbackTemplate, //null || function - onScrollStop: callbackTemplate, //null || function - onOverflowChanged: callbackTemplate, //null || function - onOverflowAmountChanged: callbackTemplate, //null || function - onDirectionChanged: callbackTemplate, //null || function - onContentSizeChanged: callbackTemplate, //null || function - onHostSizeChanged: callbackTemplate, //null || function - onUpdated: callbackTemplate //null || function - } - }; - var convert = function (template) { - var recursive = function (obj) { - var key; - var val; - var valType; - for (key in obj) { - if (!obj[LEXICON.hOP](key)) - continue; - val = obj[key]; - valType = type(val); - if (valType == TYPES.a) - obj[key] = val[template ? 1 : 0]; - else if (valType == TYPES.o) - obj[key] = recursive(val); - } - return obj; - }; - return recursive(FRAMEWORK.extend(true, {}, optionsDefaultsAndTemplate)); - }; - - return { - _defaults: convert(), - - _template: convert(true), - - /** - * Validates the passed object by the passed template. - * @param obj The object which shall be validated. - * @param template The template which defines the allowed values and types. - * @param writeErrors True if errors shall be logged to the console. - * @param diffObj If a object is passed then only valid differences to this object will be returned. - * @returns {{}} A object which contains two objects called "default" and "prepared" which contains only the valid properties of the passed original object and discards not different values compared to the passed diffObj. - */ - _validate: function (obj, template, writeErrors, diffObj) { - var validatedOptions = {}; - var validatedOptionsPrepared = {}; - var objectCopy = FRAMEWORK.extend(true, {}, obj); - var inArray = FRAMEWORK.inArray; - var isEmptyObj = FRAMEWORK.isEmptyObject; - var checkObjectProps = function (data, template, diffData, validatedOptions, validatedOptionsPrepared, prevPropName) { - for (var prop in template) { - if (template[LEXICON.hOP](prop) && data[LEXICON.hOP](prop)) { - var isValid = false; - var isDiff = false; - var templateValue = template[prop]; - var templateValueType = type(templateValue); - var templateIsComplex = templateValueType == TYPES.o; - var templateTypes = type(templateValue) != TYPES.a ? [templateValue] : templateValue; - var dataDiffValue = diffData[prop]; - var dataValue = data[prop]; - var dataValueType = type(dataValue); - var propPrefix = prevPropName ? prevPropName + '.' : ''; - var error = "The option \"" + propPrefix + prop + "\" wasn't set, because"; - var errorPossibleTypes = []; - var errorRestrictedStrings = []; - var restrictedStringValuesSplit; - var restrictedStringValuesPossibilitiesSplit; - var isRestrictedValue; - var mainPossibility; - var currType; - var i; - var v; - var j; - - dataDiffValue = dataDiffValue === undefined ? {} : dataDiffValue; - - //if the template has a object as value, it means that the options are complex (verschachtelt) - if (templateIsComplex && dataValueType == TYPES.o) { - validatedOptions[prop] = {}; - validatedOptionsPrepared[prop] = {}; - checkObjectProps(dataValue, templateValue, dataDiffValue, validatedOptions[prop], validatedOptionsPrepared[prop], propPrefix + prop); - FRAMEWORK.each([data, validatedOptions, validatedOptionsPrepared], function (index, value) { - if (isEmptyObj(value[prop])) { - delete value[prop]; - } - }); - } - else if (!templateIsComplex) { - for (i = 0; i < templateTypes[LEXICON.l]; i++) { - currType = templateTypes[i]; - templateValueType = type(currType); - //if currtype is string and starts with restrictedStringPrefix and end with restrictedStringSuffix - isRestrictedValue = templateValueType == TYPES.s && inArray(currType, possibleTemplateTypes) === -1; - if (isRestrictedValue) { - errorPossibleTypes.push(TYPES.s); - - //split it into a array which contains all possible values for example: ["y:yes", "n:no", "m:maybe"] - restrictedStringValuesSplit = currType.split(restrictedStringsSplit); - errorRestrictedStrings = errorRestrictedStrings.concat(restrictedStringValuesSplit); - for (v = 0; v < restrictedStringValuesSplit[LEXICON.l]; v++) { - //split the possible values into their possibiliteis for example: ["y", "yes"] -> the first is always the mainPossibility - restrictedStringValuesPossibilitiesSplit = restrictedStringValuesSplit[v].split(restrictedStringsPossibilitiesSplit); - mainPossibility = restrictedStringValuesPossibilitiesSplit[0]; - for (j = 0; j < restrictedStringValuesPossibilitiesSplit[LEXICON.l]; j++) { - //if any possibility matches with the dataValue, its valid - if (dataValue === restrictedStringValuesPossibilitiesSplit[j]) { - isValid = true; - break; - } - } - if (isValid) - break; - } - } - else { - errorPossibleTypes.push(currType); - - if (dataValueType === currType) { - isValid = true; - break; - } - } - } - - if (isValid) { - isDiff = dataValue !== dataDiffValue; - - if (isDiff) - validatedOptions[prop] = dataValue; - - if (isRestrictedValue ? inArray(dataDiffValue, restrictedStringValuesPossibilitiesSplit) < 0 : isDiff) - validatedOptionsPrepared[prop] = isRestrictedValue ? mainPossibility : dataValue; - } - else if (writeErrors) { - console.warn(error + " it doesn't accept the type [ " + dataValueType.toUpperCase() + " ] with the value of \"" + dataValue + "\".\r\n" + - "Accepted types are: [ " + errorPossibleTypes.join(', ').toUpperCase() + " ]." + - (errorRestrictedStrings[length] > 0 ? "\r\nValid strings are: [ " + errorRestrictedStrings.join(', ').split(restrictedStringsPossibilitiesSplit).join(', ') + " ]." : '')); - } - delete data[prop]; - } - } - } - }; - checkObjectProps(objectCopy, template, diffObj || {}, validatedOptions, validatedOptionsPrepared); - - //add values which aren't specified in the template to the finished validated object to prevent them from being discarded - /* - if(keepForeignProps) { - FRAMEWORK.extend(true, validatedOptions, objectCopy); - FRAMEWORK.extend(true, validatedOptionsPrepared, objectCopy); - } - */ - - if (!isEmptyObj(objectCopy) && writeErrors) - console.warn('The following options are discarded due to invalidity:\r\n' + window.JSON.stringify(objectCopy, null, 2)); - - return { - _default: validatedOptions, - _prepared: validatedOptionsPrepared - }; - } - } - }()); - - /** - * Initializes the object which contains global information about the plugin and each instance of it. - */ - function initOverlayScrollbarsStatics() { - if (!_pluginsGlobals) - _pluginsGlobals = new OverlayScrollbarsGlobals(_pluginsOptions._defaults); - if (!_pluginsAutoUpdateLoop) - _pluginsAutoUpdateLoop = new OverlayScrollbarsAutoUpdateLoop(_pluginsGlobals); - } - - /** - * The global object for the OverlayScrollbars objects. It contains resources which every OverlayScrollbars object needs. This object is initialized only once: if the first OverlayScrollbars object gets initialized. - * @param defaultOptions - * @constructor - */ - function OverlayScrollbarsGlobals(defaultOptions) { - var _base = this; - var strOverflow = 'overflow'; - var strHidden = 'hidden'; - var strScroll = 'scroll'; - var bodyElement = FRAMEWORK('body'); - var scrollbarDummyElement = FRAMEWORK('
'); - var scrollbarDummyElement0 = scrollbarDummyElement[0]; - var dummyContainerChild = FRAMEWORK(scrollbarDummyElement.children('div').eq(0)); - - bodyElement.append(scrollbarDummyElement); - scrollbarDummyElement.hide().show(); //fix IE8 bug (incorrect measuring) - - var nativeScrollbarSize = calcNativeScrollbarSize(scrollbarDummyElement0); - var nativeScrollbarIsOverlaid = { - x: nativeScrollbarSize.x === 0, - y: nativeScrollbarSize.y === 0 - }; - var msie = (function () { - var ua = window.navigator.userAgent; - var strIndexOf = 'indexOf'; - var strSubString = 'substring'; - var msie = ua[strIndexOf]('MSIE '); - var trident = ua[strIndexOf]('Trident/'); - var edge = ua[strIndexOf]('Edge/'); - var rv = ua[strIndexOf]('rv:'); - var result; - var parseIntFunc = parseInt; - - // IE 10 or older => return version number - if (msie > 0) - result = parseIntFunc(ua[strSubString](msie + 5, ua[strIndexOf]('.', msie)), 10); - - // IE 11 => return version number - else if (trident > 0) - result = parseIntFunc(ua[strSubString](rv + 3, ua[strIndexOf]('.', rv)), 10); - - // Edge (IE 12+) => return version number - else if (edge > 0) - result = parseIntFunc(ua[strSubString](edge + 5, ua[strIndexOf]('.', edge)), 10); - - // other browser - return result; - })(); - - FRAMEWORK.extend(_base, { - defaultOptions: defaultOptions, - msie: msie, - autoUpdateLoop: false, - autoUpdateRecommended: !COMPATIBILITY.mO(), - nativeScrollbarSize: nativeScrollbarSize, - nativeScrollbarIsOverlaid: nativeScrollbarIsOverlaid, - nativeScrollbarStyling: (function () { - var result = false; - scrollbarDummyElement.addClass('os-viewport-native-scrollbars-invisible'); - try { - result = (scrollbarDummyElement.css('scrollbar-width') === 'none' && (msie > 9 || !msie)) || window.getComputedStyle(scrollbarDummyElement0, '::-webkit-scrollbar').getPropertyValue('display') === 'none'; - } catch (ex) { } - - //fix opera bug: scrollbar styles will only appear if overflow value is scroll or auto during the activation of the style. - //and set overflow to scroll - //scrollbarDummyElement.css(strOverflow, strHidden).hide().css(strOverflow, strScroll).show(); - //return (scrollbarDummyElement0[LEXICON.oH] - scrollbarDummyElement0[LEXICON.cH]) === 0 && (scrollbarDummyElement0[LEXICON.oW] - scrollbarDummyElement0[LEXICON.cW]) === 0; - - return result; - })(), - overlayScrollbarDummySize: { x: 30, y: 30 }, - cssCalc: (function () { - var dummyStyle = document.createElement('div')[LEXICON.s]; - var strCalc = 'calc'; - var i = -1; - var prop; - - for (; i < VENDORS._cssPrefixes[LEXICON.l]; i++) { - prop = i < 0 ? strCalc : VENDORS._cssPrefixes[i] + strCalc; - dummyStyle.cssText = 'width:' + prop + '(1px);'; - if (dummyStyle[LEXICON.l]) - return prop; - } - return null; - })(), - restrictedMeasuring: (function () { - //https://bugzilla.mozilla.org/show_bug.cgi?id=1439305 - //since 1.11.0 always false -> fixed via CSS (hopefully) - scrollbarDummyElement.css(strOverflow, strHidden); - var scrollSize = { - w: scrollbarDummyElement0[LEXICON.sW], - h: scrollbarDummyElement0[LEXICON.sH] - }; - scrollbarDummyElement.css(strOverflow, 'visible'); - var scrollSize2 = { - w: scrollbarDummyElement0[LEXICON.sW], - h: scrollbarDummyElement0[LEXICON.sH] - }; - return (scrollSize.w - scrollSize2.w) !== 0 || (scrollSize.h - scrollSize2.h) !== 0; - })(), - rtlScrollBehavior: (function () { - scrollbarDummyElement.css({ 'overflow-y': strHidden, 'overflow-x': strScroll, 'direction': 'rtl' }).scrollLeft(0); - var dummyContainerOffset = scrollbarDummyElement.offset(); - var dummyContainerChildOffset = dummyContainerChild.offset(); - //https://github.com/KingSora/OverlayScrollbars/issues/187 - scrollbarDummyElement.scrollLeft(-999); - var dummyContainerChildOffsetAfterScroll = dummyContainerChild.offset(); - return { - //origin direction = determines if the zero scroll position is on the left or right side - //'i' means 'invert' (i === true means that the axis must be inverted to be correct) - //true = on the left side - //false = on the right side - i: dummyContainerOffset.left === dummyContainerChildOffset.left, - //negative = determines if the maximum scroll is positive or negative - //'n' means 'negate' (n === true means that the axis must be negated to be correct) - //true = negative - //false = positive - n: dummyContainerChildOffset.left !== dummyContainerChildOffsetAfterScroll.left - }; - })(), - supportTransform: VENDORS._cssProperty('transform') !== undefined, - supportTransition: VENDORS._cssProperty('transition') !== undefined, - supportPassiveEvents: (function () { - var supportsPassive = false; - try { - window.addEventListener('test', null, Object.defineProperty({}, 'passive', { - get: function () { - supportsPassive = true; - } - })); - } catch (e) { } - return supportsPassive; - })(), - supportResizeObserver: !!COMPATIBILITY.rO(), - supportMutationObserver: !!COMPATIBILITY.mO() - }); - - scrollbarDummyElement.removeAttr(LEXICON.s).remove(); - - //Catch zoom event: - (function () { - if (nativeScrollbarIsOverlaid.x && nativeScrollbarIsOverlaid.y) - return; - - var abs = MATH.abs; - var windowWidth = COMPATIBILITY.wW(); - var windowHeight = COMPATIBILITY.wH(); - var windowDpr = getWindowDPR(); - var onResize = function () { - if (INSTANCES().length > 0) { - var newW = COMPATIBILITY.wW(); - var newH = COMPATIBILITY.wH(); - var deltaW = newW - windowWidth; - var deltaH = newH - windowHeight; - - if (deltaW === 0 && deltaH === 0) - return; - - var deltaWRatio = MATH.round(newW / (windowWidth / 100.0)); - var deltaHRatio = MATH.round(newH / (windowHeight / 100.0)); - var absDeltaW = abs(deltaW); - var absDeltaH = abs(deltaH); - var absDeltaWRatio = abs(deltaWRatio); - var absDeltaHRatio = abs(deltaHRatio); - var newDPR = getWindowDPR(); - - var deltaIsBigger = absDeltaW > 2 && absDeltaH > 2; - var difference = !differenceIsBiggerThanOne(absDeltaWRatio, absDeltaHRatio); - var dprChanged = newDPR !== windowDpr && windowDpr > 0; - var isZoom = deltaIsBigger && difference && dprChanged; - var oldScrollbarSize = _base.nativeScrollbarSize; - var newScrollbarSize; - - if (isZoom) { - bodyElement.append(scrollbarDummyElement); - newScrollbarSize = _base.nativeScrollbarSize = calcNativeScrollbarSize(scrollbarDummyElement[0]); - scrollbarDummyElement.remove(); - if (oldScrollbarSize.x !== newScrollbarSize.x || oldScrollbarSize.y !== newScrollbarSize.y) { - FRAMEWORK.each(INSTANCES(), function () { - if (INSTANCES(this)) - INSTANCES(this).update('zoom'); - }); - } - } - - windowWidth = newW; - windowHeight = newH; - windowDpr = newDPR; - } - }; - - function differenceIsBiggerThanOne(valOne, valTwo) { - var absValOne = abs(valOne); - var absValTwo = abs(valTwo); - return !(absValOne === absValTwo || absValOne + 1 === absValTwo || absValOne - 1 === absValTwo); - } - - function getWindowDPR() { - var dDPI = window.screen.deviceXDPI || 0; - var sDPI = window.screen.logicalXDPI || 1; - return window.devicePixelRatio || (dDPI / sDPI); - } - - FRAMEWORK(window).on('resize', onResize); - })(); - - function calcNativeScrollbarSize(measureElement) { - return { - x: measureElement[LEXICON.oH] - measureElement[LEXICON.cH], - y: measureElement[LEXICON.oW] - measureElement[LEXICON.cW] - }; - } - } - - /** - * The object which manages the auto update loop for all OverlayScrollbars objects. This object is initialized only once: if the first OverlayScrollbars object gets initialized. - * @constructor - */ - function OverlayScrollbarsAutoUpdateLoop(globals) { - var _base = this; - var _inArray = FRAMEWORK.inArray; - var _getNow = COMPATIBILITY.now; - var _strAutoUpdate = 'autoUpdate'; - var _strAutoUpdateInterval = _strAutoUpdate + 'Interval'; - var _strLength = LEXICON.l; - var _loopingInstances = []; - var _loopingInstancesIntervalCache = []; - var _loopIsActive = false; - var _loopIntervalDefault = 33; - var _loopInterval = _loopIntervalDefault; - var _loopTimeOld = _getNow(); - var _loopID; - - - /** - * The auto update loop which will run every 50 milliseconds or less if the update interval of a instance is lower than 50 milliseconds. - */ - var loop = function () { - if (_loopingInstances[_strLength] > 0 && _loopIsActive) { - _loopID = COMPATIBILITY.rAF()(function () { - loop(); - }); - var timeNew = _getNow(); - var timeDelta = timeNew - _loopTimeOld; - var lowestInterval; - var instance; - var instanceOptions; - var instanceAutoUpdateAllowed; - var instanceAutoUpdateInterval; - var now; - - if (timeDelta > _loopInterval) { - _loopTimeOld = timeNew - (timeDelta % _loopInterval); - lowestInterval = _loopIntervalDefault; - for (var i = 0; i < _loopingInstances[_strLength]; i++) { - instance = _loopingInstances[i]; - if (instance !== undefined) { - instanceOptions = instance.options(); - instanceAutoUpdateAllowed = instanceOptions[_strAutoUpdate]; - instanceAutoUpdateInterval = MATH.max(1, instanceOptions[_strAutoUpdateInterval]); - now = _getNow(); - - if ((instanceAutoUpdateAllowed === true || instanceAutoUpdateAllowed === null) && (now - _loopingInstancesIntervalCache[i]) > instanceAutoUpdateInterval) { - instance.update('auto'); - _loopingInstancesIntervalCache[i] = new Date(now += instanceAutoUpdateInterval); - } - - lowestInterval = MATH.max(1, MATH.min(lowestInterval, instanceAutoUpdateInterval)); - } - } - _loopInterval = lowestInterval; - } - } else { - _loopInterval = _loopIntervalDefault; - } - }; - - /** - * Add OverlayScrollbars instance to the auto update loop. Only successful if the instance isn't already added. - * @param instance The instance which shall be updated in a loop automatically. - */ - _base.add = function (instance) { - if (_inArray(instance, _loopingInstances) === -1) { - _loopingInstances.push(instance); - _loopingInstancesIntervalCache.push(_getNow()); - if (_loopingInstances[_strLength] > 0 && !_loopIsActive) { - _loopIsActive = true; - globals.autoUpdateLoop = _loopIsActive; - loop(); - } - } - }; - - /** - * Remove OverlayScrollbars instance from the auto update loop. Only successful if the instance was added before. - * @param instance The instance which shall be updated in a loop automatically. - */ - _base.remove = function (instance) { - var index = _inArray(instance, _loopingInstances); - if (index > -1) { - //remove from loopingInstances list - _loopingInstancesIntervalCache.splice(index, 1); - _loopingInstances.splice(index, 1); - - //correct update loop behavior - if (_loopingInstances[_strLength] === 0 && _loopIsActive) { - _loopIsActive = false; - globals.autoUpdateLoop = _loopIsActive; - if (_loopID !== undefined) { - COMPATIBILITY.cAF()(_loopID); - _loopID = -1; - } - } - } - }; - } - - /** - * A object which manages the scrollbars visibility of the target element. - * @param pluginTargetElement The element from which the scrollbars shall be hidden. - * @param options The custom options. - * @param extensions The custom extensions. - * @param globals - * @param autoUpdateLoop - * @returns {*} - * @constructor - */ - function OverlayScrollbarsInstance(pluginTargetElement, options, extensions, globals, autoUpdateLoop) { - //shortcuts - var type = COMPATIBILITY.type; - var inArray = FRAMEWORK.inArray; - var each = FRAMEWORK.each; - - //make correct instanceof - var _base = new _plugin(); - var _frameworkProto = FRAMEWORK[LEXICON.p]; - - //if passed element is no HTML element: skip and return - if (!isHTMLElement(pluginTargetElement)) - return; - - //if passed element is already initialized: set passed options if there are any and return its instance - if (INSTANCES(pluginTargetElement)) { - var inst = INSTANCES(pluginTargetElement); - inst.options(options); - return inst; - } - - //globals: - var _nativeScrollbarIsOverlaid; - var _overlayScrollbarDummySize; - var _rtlScrollBehavior; - var _autoUpdateRecommended; - var _msieVersion; - var _nativeScrollbarStyling; - var _cssCalc; - var _nativeScrollbarSize; - var _supportTransition; - var _supportTransform; - var _supportPassiveEvents; - var _supportResizeObserver; - var _supportMutationObserver; - var _restrictedMeasuring; - - //general readonly: - var _initialized; - var _destroyed; - var _isTextarea; - var _isBody; - var _documentMixed; - var _domExists; - - //general: - var _isBorderBox; - var _sizeAutoObserverAdded; - var _paddingX; - var _paddingY; - var _borderX; - var _borderY; - var _marginX; - var _marginY; - var _isRTL; - var _sleeping; - var _contentBorderSize = {}; - var _scrollHorizontalInfo = {}; - var _scrollVerticalInfo = {}; - var _viewportSize = {}; - var _nativeScrollbarMinSize = {}; - - //naming: - var _strMinusHidden = '-hidden'; - var _strMarginMinus = 'margin-'; - var _strPaddingMinus = 'padding-'; - var _strBorderMinus = 'border-'; - var _strTop = 'top'; - var _strRight = 'right'; - var _strBottom = 'bottom'; - var _strLeft = 'left'; - var _strMinMinus = 'min-'; - var _strMaxMinus = 'max-'; - var _strWidth = 'width'; - var _strHeight = 'height'; - var _strFloat = 'float'; - var _strEmpty = ''; - var _strAuto = 'auto'; - var _strSync = 'sync'; - var _strScroll = 'scroll'; - var _strHundredPercent = '100%'; - var _strX = 'x'; - var _strY = 'y'; - var _strDot = '.'; - var _strSpace = ' '; - var _strScrollbar = 'scrollbar'; - var _strMinusHorizontal = '-horizontal'; - var _strMinusVertical = '-vertical'; - var _strScrollLeft = _strScroll + 'Left'; - var _strScrollTop = _strScroll + 'Top'; - var _strMouseTouchDownEvent = 'mousedown touchstart'; - var _strMouseTouchUpEvent = 'mouseup touchend touchcancel'; - var _strMouseTouchMoveEvent = 'mousemove touchmove'; - var _strMouseTouchEnter = 'mouseenter'; - var _strMouseTouchLeave = 'mouseleave'; - var _strKeyDownEvent = 'keydown'; - var _strKeyUpEvent = 'keyup'; - var _strSelectStartEvent = 'selectstart'; - var _strTransitionEndEvent = 'transitionend webkitTransitionEnd oTransitionEnd'; - var _strResizeObserverProperty = '__overlayScrollbarsRO__'; - - //class names: - var _cassNamesPrefix = 'os-'; - var _classNameHTMLElement = _cassNamesPrefix + 'html'; - var _classNameHostElement = _cassNamesPrefix + 'host'; - var _classNameHostTextareaElement = _classNameHostElement + '-textarea'; - var _classNameHostScrollbarHorizontalHidden = _classNameHostElement + '-' + _strScrollbar + _strMinusHorizontal + _strMinusHidden; - var _classNameHostScrollbarVerticalHidden = _classNameHostElement + '-' + _strScrollbar + _strMinusVertical + _strMinusHidden; - var _classNameHostTransition = _classNameHostElement + '-transition'; - var _classNameHostRTL = _classNameHostElement + '-rtl'; - var _classNameHostResizeDisabled = _classNameHostElement + '-resize-disabled'; - var _classNameHostScrolling = _classNameHostElement + '-scrolling'; - var _classNameHostOverflow = _classNameHostElement + '-overflow'; - var _classNameHostOverflowX = _classNameHostOverflow + '-x'; - var _classNameHostOverflowY = _classNameHostOverflow + '-y'; - var _classNameTextareaElement = _cassNamesPrefix + 'textarea'; - var _classNameTextareaCoverElement = _classNameTextareaElement + '-cover'; - var _classNamePaddingElement = _cassNamesPrefix + 'padding'; - var _classNameViewportElement = _cassNamesPrefix + 'viewport'; - var _classNameViewportNativeScrollbarsInvisible = _classNameViewportElement + '-native-scrollbars-invisible'; - var _classNameViewportNativeScrollbarsOverlaid = _classNameViewportElement + '-native-scrollbars-overlaid'; - var _classNameContentElement = _cassNamesPrefix + 'content'; - var _classNameContentArrangeElement = _cassNamesPrefix + 'content-arrange'; - var _classNameContentGlueElement = _cassNamesPrefix + 'content-glue'; - var _classNameSizeAutoObserverElement = _cassNamesPrefix + 'size-auto-observer'; - var _classNameResizeObserverElement = _cassNamesPrefix + 'resize-observer'; - var _classNameResizeObserverItemElement = _cassNamesPrefix + 'resize-observer-item'; - var _classNameResizeObserverItemFinalElement = _classNameResizeObserverItemElement + '-final'; - var _classNameTextInherit = _cassNamesPrefix + 'text-inherit'; - var _classNameScrollbar = _cassNamesPrefix + _strScrollbar; - var _classNameScrollbarTrack = _classNameScrollbar + '-track'; - var _classNameScrollbarTrackOff = _classNameScrollbarTrack + '-off'; - var _classNameScrollbarHandle = _classNameScrollbar + '-handle'; - var _classNameScrollbarHandleOff = _classNameScrollbarHandle + '-off'; - var _classNameScrollbarUnusable = _classNameScrollbar + '-unusable'; - var _classNameScrollbarAutoHidden = _classNameScrollbar + '-' + _strAuto + _strMinusHidden; - var _classNameScrollbarCorner = _classNameScrollbar + '-corner'; - var _classNameScrollbarCornerResize = _classNameScrollbarCorner + '-resize'; - var _classNameScrollbarCornerResizeB = _classNameScrollbarCornerResize + '-both'; - var _classNameScrollbarCornerResizeH = _classNameScrollbarCornerResize + _strMinusHorizontal; - var _classNameScrollbarCornerResizeV = _classNameScrollbarCornerResize + _strMinusVertical; - var _classNameScrollbarHorizontal = _classNameScrollbar + _strMinusHorizontal; - var _classNameScrollbarVertical = _classNameScrollbar + _strMinusVertical; - var _classNameDragging = _cassNamesPrefix + 'dragging'; - var _classNameThemeNone = _cassNamesPrefix + 'theme-none'; - var _classNamesDynamicDestroy = [ - _classNameViewportNativeScrollbarsInvisible, - _classNameViewportNativeScrollbarsOverlaid, - _classNameScrollbarTrackOff, - _classNameScrollbarHandleOff, - _classNameScrollbarUnusable, - _classNameScrollbarAutoHidden, - _classNameScrollbarCornerResize, - _classNameScrollbarCornerResizeB, - _classNameScrollbarCornerResizeH, - _classNameScrollbarCornerResizeV, - _classNameDragging].join(_strSpace); - - //callbacks: - var _callbacksInitQeueue = []; - - //attrs viewport shall inherit from target - var _viewportAttrsFromTarget = [LEXICON.ti]; - - //options: - var _defaultOptions; - var _currentOptions; - var _currentPreparedOptions; - - //extensions: - var _extensions = {}; - var _extensionsPrivateMethods = 'added removed on contract'; - - //update - var _lastUpdateTime; - var _swallowedUpdateHints = {}; - var _swallowedUpdateTimeout; - var _swallowUpdateLag = 42; - var _imgs = []; - - //DOM elements: - var _windowElement; - var _documentElement; - var _htmlElement; - var _bodyElement; - var _targetElement; //the target element of this OverlayScrollbars object - var _hostElement; //the host element of this OverlayScrollbars object -> may be the same as targetElement - var _sizeAutoObserverElement; //observes size auto changes - var _sizeObserverElement; //observes size and padding changes - var _paddingElement; //manages the padding - var _viewportElement; //is the viewport of our scrollbar model - var _contentElement; //the element which holds the content - var _contentArrangeElement; //is needed for correct sizing of the content element (only if native scrollbars are overlays) - var _contentGlueElement; //has always the size of the content element - var _textareaCoverElement; //only applied if target is a textarea element. Used for correct size calculation and for prevention of uncontrolled scrolling - var _scrollbarCornerElement; - var _scrollbarHorizontalElement; - var _scrollbarHorizontalTrackElement; - var _scrollbarHorizontalHandleElement; - var _scrollbarVerticalElement; - var _scrollbarVerticalTrackElement; - var _scrollbarVerticalHandleElement; - var _windowElementNative; - var _documentElementNative; - var _targetElementNative; - var _hostElementNative; - var _sizeAutoObserverElementNative; - var _sizeObserverElementNative; - var _paddingElementNative; - var _viewportElementNative; - var _contentElementNative; - - //Cache: - var _hostSizeCache; - var _contentScrollSizeCache; - var _arrangeContentSizeCache; - var _hasOverflowCache; - var _hideOverflowCache; - var _widthAutoCache; - var _heightAutoCache; - var _cssMaxValueCache; - var _cssBoxSizingCache; - var _cssPaddingCache; - var _cssBorderCache; - var _cssMarginCache; - var _cssDirectionCache; - var _cssDirectionDetectedCache; - var _paddingAbsoluteCache; - var _clipAlwaysCache; - var _contentGlueSizeCache; - var _overflowBehaviorCache; - var _overflowAmountCache; - var _ignoreOverlayScrollbarHidingCache; - var _autoUpdateCache; - var _sizeAutoCapableCache; - var _contentElementScrollSizeChangeDetectedCache; - var _hostElementSizeChangeDetectedCache; - var _scrollbarsVisibilityCache; - var _scrollbarsAutoHideCache; - var _scrollbarsClickScrollingCache; - var _scrollbarsDragScrollingCache; - var _resizeCache; - var _normalizeRTLCache; - var _classNameCache; - var _oldClassName; - var _textareaAutoWrappingCache; - var _textareaInfoCache; - var _textareaSizeCache; - var _textareaDynHeightCache; - var _textareaDynWidthCache; - var _bodyMinSizeCache; - var _displayIsHiddenCache; - var _updateAutoCache = {}; - - //MutationObserver: - var _mutationObserverHost; - var _mutationObserverContent; - var _mutationObserverHostCallback; - var _mutationObserverContentCallback; - var _mutationObserversConnected; - var _mutationObserverAttrsTextarea = ['wrap', 'cols', 'rows']; - var _mutationObserverAttrsHost = [LEXICON.i, LEXICON.c, LEXICON.s, 'open'].concat(_viewportAttrsFromTarget); - - //events: - var _destroyEvents = []; - - //textarea: - var _textareaHasFocus; - - //scrollbars: - var _scrollbarsAutoHideTimeoutId; - var _scrollbarsAutoHideMoveTimeoutId; - var _scrollbarsAutoHideDelay; - var _scrollbarsAutoHideNever; - var _scrollbarsAutoHideScroll; - var _scrollbarsAutoHideMove; - var _scrollbarsAutoHideLeave; - var _scrollbarsHandleHovered; - var _scrollbarsHandlesDefineScrollPos; - - //resize - var _resizeNone; - var _resizeBoth; - var _resizeHorizontal; - var _resizeVertical; - - - //==== Event Listener ====// - - /** - * Adds or removes a event listener from the given element. - * @param element The element to which the event listener shall be applied or removed. - * @param eventNames The name(s) of the events. - * @param listener The method which shall be called. - * @param remove True if the handler shall be removed, false or undefined if the handler shall be added. - */ - function setupResponsiveEventListener(element, eventNames, listener, remove, passive) { - var collected = type(eventNames) == TYPES.a && type(listener) == TYPES.a; - var method = remove ? 'removeEventListener' : 'addEventListener'; - var onOff = remove ? 'off' : 'on'; - var events = collected ? false : eventNames.split(_strSpace) - var i = 0; - - if (collected) { - for (; i < eventNames[LEXICON.l]; i++) - setupResponsiveEventListener(element, eventNames[i], listener[i], remove); - } - else { - for (; i < events[LEXICON.l]; i++) { - if (_supportPassiveEvents) - element[0][method](events[i], listener, { passive: passive || false }); - else - element[onOff](events[i], listener); - } - } - } - - - function addDestroyEventListener(element, eventNames, listener, passive) { - setupResponsiveEventListener(element, eventNames, listener, false, passive); - _destroyEvents.push(COMPATIBILITY.bind(setupResponsiveEventListener, 0, element, eventNames, listener, true, passive)); - } - - //==== Resize Observer ====// - - /** - * Adds or removes a resize observer from the given element. - * @param targetElement The element to which the resize observer shall be added or removed. - * @param onElementResizedCallback The callback which is fired every time the resize observer registers a size change or false / undefined if the resizeObserver shall be removed. - */ - function setupResizeObserver(targetElement, onElementResizedCallback) { - if (targetElement) { - var resizeObserver = COMPATIBILITY.rO(); - var strAnimationStartEvent = 'animationstart mozAnimationStart webkitAnimationStart MSAnimationStart'; - var strChildNodes = 'childNodes'; - var constScroll = 3333333; - var callback = function () { - targetElement[_strScrollTop](constScroll)[_strScrollLeft](_isRTL ? _rtlScrollBehavior.n ? -constScroll : _rtlScrollBehavior.i ? 0 : constScroll : constScroll); - onElementResizedCallback(); - }; - //add resize observer: - if (onElementResizedCallback) { - if (_supportResizeObserver) { - var element = targetElement.addClass('observed').append(generateDiv(_classNameResizeObserverElement)).contents()[0]; - var observer = element[_strResizeObserverProperty] = new resizeObserver(callback); - observer.observe(element); - } - else { - if (_msieVersion > 9 || !_autoUpdateRecommended) { - targetElement.prepend( - generateDiv(_classNameResizeObserverElement, - generateDiv({ c: _classNameResizeObserverItemElement, dir: 'ltr' }, - generateDiv(_classNameResizeObserverItemElement, - generateDiv(_classNameResizeObserverItemFinalElement) - ) + - generateDiv(_classNameResizeObserverItemElement, - generateDiv({ c: _classNameResizeObserverItemFinalElement, style: 'width: 200%; height: 200%' }) - ) - ) - ) - ); - - var observerElement = targetElement[0][strChildNodes][0][strChildNodes][0]; - var shrinkElement = FRAMEWORK(observerElement[strChildNodes][1]); - var expandElement = FRAMEWORK(observerElement[strChildNodes][0]); - var expandElementChild = FRAMEWORK(expandElement[0][strChildNodes][0]); - var widthCache = observerElement[LEXICON.oW]; - var heightCache = observerElement[LEXICON.oH]; - var isDirty; - var rAFId; - var currWidth; - var currHeight; - var factor = 2; - var nativeScrollbarSize = globals.nativeScrollbarSize; //care don't make changes to this object!!! - var reset = function () { - /* - var sizeResetWidth = observerElement[LEXICON.oW] + nativeScrollbarSize.x * factor + nativeScrollbarSize.y * factor + _overlayScrollbarDummySize.x + _overlayScrollbarDummySize.y; - var sizeResetHeight = observerElement[LEXICON.oH] + nativeScrollbarSize.x * factor + nativeScrollbarSize.y * factor + _overlayScrollbarDummySize.x + _overlayScrollbarDummySize.y; - var expandChildCSS = {}; - expandChildCSS[_strWidth] = sizeResetWidth; - expandChildCSS[_strHeight] = sizeResetHeight; - expandElementChild.css(expandChildCSS); - - - expandElement[_strScrollLeft](sizeResetWidth)[_strScrollTop](sizeResetHeight); - shrinkElement[_strScrollLeft](sizeResetWidth)[_strScrollTop](sizeResetHeight); - */ - expandElement[_strScrollLeft](constScroll)[_strScrollTop](constScroll); - shrinkElement[_strScrollLeft](constScroll)[_strScrollTop](constScroll); - }; - var onResized = function () { - rAFId = 0; - if (!isDirty) - return; - - widthCache = currWidth; - heightCache = currHeight; - callback(); - }; - var onScroll = function (event) { - currWidth = observerElement[LEXICON.oW]; - currHeight = observerElement[LEXICON.oH]; - isDirty = currWidth != widthCache || currHeight != heightCache; - - if (event && isDirty && !rAFId) { - COMPATIBILITY.cAF()(rAFId); - rAFId = COMPATIBILITY.rAF()(onResized); - } - else if (!event) - onResized(); - - reset(); - if (event) { - COMPATIBILITY.prvD(event); - COMPATIBILITY.stpP(event); - } - return false; - }; - var expandChildCSS = {}; - var observerElementCSS = {}; - - setTopRightBottomLeft(observerElementCSS, _strEmpty, [ - -((nativeScrollbarSize.y + 1) * factor), - nativeScrollbarSize.x * -factor, - nativeScrollbarSize.y * -factor, - -((nativeScrollbarSize.x + 1) * factor) - ]); - - FRAMEWORK(observerElement).css(observerElementCSS); - expandElement.on(_strScroll, onScroll); - shrinkElement.on(_strScroll, onScroll); - targetElement.on(strAnimationStartEvent, function () { - onScroll(false); - }); - //lets assume that the divs will never be that large and a constant value is enough - expandChildCSS[_strWidth] = constScroll; - expandChildCSS[_strHeight] = constScroll; - expandElementChild.css(expandChildCSS); - - reset(); - } - else { - var attachEvent = _documentElementNative.attachEvent; - var isIE = _msieVersion !== undefined; - if (attachEvent) { - targetElement.prepend(generateDiv(_classNameResizeObserverElement)); - findFirst(targetElement, _strDot + _classNameResizeObserverElement)[0].attachEvent('onresize', callback); - } - else { - var obj = _documentElementNative.createElement(TYPES.o); - obj.setAttribute(LEXICON.ti, '-1'); - obj.setAttribute(LEXICON.c, _classNameResizeObserverElement); - obj.onload = function () { - var wnd = this.contentDocument.defaultView; - wnd.addEventListener('resize', callback); - wnd.document.documentElement.style.display = 'none'; - }; - obj.type = 'text/html'; - if (isIE) - targetElement.prepend(obj); - obj.data = 'about:blank'; - if (!isIE) - targetElement.prepend(obj); - targetElement.on(strAnimationStartEvent, callback); - } - } - } - - if (targetElement[0] === _sizeObserverElementNative) { - var directionChanged = function () { - var dir = _hostElement.css('direction'); - var css = {}; - var scrollLeftValue = 0; - var result = false; - if (dir !== _cssDirectionDetectedCache) { - if (dir === 'ltr') { - css[_strLeft] = 0; - css[_strRight] = _strAuto; - scrollLeftValue = constScroll; - } - else { - css[_strLeft] = _strAuto; - css[_strRight] = 0; - scrollLeftValue = _rtlScrollBehavior.n ? -constScroll : _rtlScrollBehavior.i ? 0 : constScroll; - } - //execution order is important for IE!!! - _sizeObserverElement.children().eq(0).css(css); - _sizeObserverElement[_strScrollLeft](scrollLeftValue)[_strScrollTop](constScroll); - _cssDirectionDetectedCache = dir; - result = true; - } - return result; - }; - directionChanged(); - addDestroyEventListener(targetElement, _strScroll, function (event) { - if (directionChanged()) - update(); - COMPATIBILITY.prvD(event); - COMPATIBILITY.stpP(event); - return false; - }); - } - } - //remove resize observer: - else { - if (_supportResizeObserver) { - var element = targetElement.contents()[0]; - var resizeObserverObj = element[_strResizeObserverProperty]; - if (resizeObserverObj) { - resizeObserverObj.disconnect(); - delete element[_strResizeObserverProperty]; - } - } - else { - remove(targetElement.children(_strDot + _classNameResizeObserverElement).eq(0)); - } - } - } - } - - /** - * Freezes or unfreezes the given resize observer. - * @param targetElement The element to which the target resize observer is applied. - * @param freeze True if the resize observer shall be frozen, false otherwise. - - function freezeResizeObserver(targetElement, freeze) { - if (targetElement !== undefined) { - if(freeze) { - if (_supportResizeObserver) { - var element = targetElement.contents()[0]; - element[_strResizeObserverProperty].unobserve(element); - } - else { - targetElement = targetElement.children(_strDot + _classNameResizeObserverElement).eq(0); - var w = targetElement.css(_strWidth); - var h = targetElement.css(_strHeight); - var css = {}; - css[_strWidth] = w; - css[_strHeight] = h; - targetElement.css(css); - } - } - else { - if (_supportResizeObserver) { - var element = targetElement.contents()[0]; - element[_strResizeObserverProperty].observe(element); - } - else { - var css = { }; - css[_strHeight] = _strEmpty; - css[_strWidth] = _strEmpty; - targetElement.children(_strDot + _classNameResizeObserverElement).eq(0).css(css); - } - } - } - } - */ - - - //==== Mutation Observers ====// - - /** - * Creates MutationObservers for the host and content Element if they are supported. - */ - function createMutationObservers() { - if (_supportMutationObserver) { - var mutationObserverContentLag = 11; - var mutationObserver = COMPATIBILITY.mO(); - var contentLastUpdate = COMPATIBILITY.now(); - var mutationTarget; - var mutationAttrName; - var contentTimeout; - var now; - var sizeAuto; - var action; - - _mutationObserverHostCallback = function (mutations) { - var doUpdate = false; - var mutation; - var mutatedAttrs = []; - - if (_initialized && !_sleeping) { - each(mutations, function () { - mutation = this; - mutationTarget = mutation.target; - mutationAttrName = mutation.attributeName; - - if(!doUpdate) { - if (mutationAttrName === LEXICON.c) - doUpdate = hostClassNamesChanged(mutation.oldValue, mutationTarget.className); - else if (mutationAttrName === LEXICON.s) - doUpdate = mutation.oldValue !== mutationTarget[LEXICON.s].cssText; - else - doUpdate = true; - } - - mutatedAttrs.push(mutationAttrName); - }); - - updateViewportAttrsFromTarget(mutatedAttrs); - - if (doUpdate) - _base.update(_strAuto); - } - return doUpdate; - }; - _mutationObserverContentCallback = function (mutations) { - var doUpdate = false; - var mutation; - - if (_initialized && !_sleeping) { - each(mutations, function () { - mutation = this; - doUpdate = isUnknownMutation(mutation); - return !doUpdate; - }); - - if (doUpdate) { - now = COMPATIBILITY.now(); - sizeAuto = (_heightAutoCache || _widthAutoCache); - action = function () { - if (!_destroyed) { - contentLastUpdate = now; - - //if cols, rows or wrap attr was changed - if (_isTextarea) - textareaUpdate(); - - if (sizeAuto) - update(); - else - _base.update(_strAuto); - } - }; - clearTimeout(contentTimeout); - if (mutationObserverContentLag <= 0 || now - contentLastUpdate > mutationObserverContentLag || !sizeAuto) - action(); - else - contentTimeout = setTimeout(action, mutationObserverContentLag); - } - } - return doUpdate; - } - - _mutationObserverHost = new mutationObserver(_mutationObserverHostCallback); - _mutationObserverContent = new mutationObserver(_mutationObserverContentCallback); - } - } - - /** - * Connects the MutationObservers if they are supported. - */ - function connectMutationObservers() { - if (_supportMutationObserver && !_mutationObserversConnected) { - _mutationObserverHost.observe(_hostElementNative, { - attributes: true, - attributeOldValue: true, - attributeFilter: _mutationObserverAttrsHost - }); - - _mutationObserverContent.observe(_isTextarea ? _targetElementNative : _contentElementNative, { - attributes: true, - attributeOldValue: true, - subtree: !_isTextarea, - childList: !_isTextarea, - characterData: !_isTextarea, - attributeFilter: _isTextarea ? _mutationObserverAttrsTextarea : _mutationObserverAttrsHost - }); - - _mutationObserversConnected = true; - } - } - - /** - * Disconnects the MutationObservers if they are supported. - */ - function disconnectMutationObservers() { - if (_supportMutationObserver && _mutationObserversConnected) { - _mutationObserverHost.disconnect(); - _mutationObserverContent.disconnect(); - - _mutationObserversConnected = false; - } - } - - - //==== Events of elements ====// - - /** - * This method gets called every time the host element gets resized. IMPORTANT: Padding changes are detected too!! - * It refreshes the hostResizedEventArgs and the hostSizeResizeCache. - * If there are any size changes, the update method gets called. - */ - function hostOnResized() { - if (!_sleeping) { - var changed; - var hostSize = { - w: _sizeObserverElementNative[LEXICON.sW], - h: _sizeObserverElementNative[LEXICON.sH] - }; - - changed = checkCache(hostSize, _hostElementSizeChangeDetectedCache); - _hostElementSizeChangeDetectedCache = hostSize; - if (changed) - update({ _hostSizeChanged: true }); - } - } - - /** - * The mouse enter event of the host element. This event is only needed for the autoHide feature. - */ - function hostOnMouseEnter() { - if (_scrollbarsAutoHideLeave) - refreshScrollbarsAutoHide(true); - } - - /** - * The mouse leave event of the host element. This event is only needed for the autoHide feature. - */ - function hostOnMouseLeave() { - if (_scrollbarsAutoHideLeave && !_bodyElement.hasClass(_classNameDragging)) - refreshScrollbarsAutoHide(false); - } - - /** - * The mouse move event of the host element. This event is only needed for the autoHide "move" feature. - */ - function hostOnMouseMove() { - if (_scrollbarsAutoHideMove) { - refreshScrollbarsAutoHide(true); - clearTimeout(_scrollbarsAutoHideMoveTimeoutId); - _scrollbarsAutoHideMoveTimeoutId = setTimeout(function () { - if (_scrollbarsAutoHideMove && !_destroyed) - refreshScrollbarsAutoHide(false); - }, 100); - } - } - - /** - * Prevents text from deselection if attached to the document element on the mousedown event of a DOM element. - * @param event The select start event. - */ - function documentOnSelectStart(event) { - COMPATIBILITY.prvD(event); - return false; - } - - /** - * A callback which will be called after a img element has downloaded its src asynchronous. - */ - function imgOnLoad() { - update({ _contentSizeChanged: true }); - } - - /** - * Adds or removes mouse & touch events of the host element. (for handling auto-hiding of the scrollbars) - * @param destroy Indicates whether the events shall be added or removed. - */ - function setupHostMouseTouchEvents(destroy) { - setupResponsiveEventListener(_hostElement, - _strMouseTouchMoveEvent, - hostOnMouseMove, - (_scrollbarsAutoHideMove ? destroy : true), true); - setupResponsiveEventListener(_hostElement, - [_strMouseTouchEnter, _strMouseTouchLeave], - [hostOnMouseEnter, hostOnMouseLeave], - (_scrollbarsAutoHideMove ? true : destroy), true); - - //if the plugin is initialized and the mouse is over the host element, make the scrollbars visible - if (!_initialized && !destroy) - _hostElement.one('mouseover', hostOnMouseEnter); - } - - - //==== Update Detection ====// - - /** - * Measures the min width and min height of the body element and refreshes the related cache. - * @returns {boolean} True if the min width or min height has changed, false otherwise. - */ - function bodyMinSizeChanged() { - var bodyMinSize = {}; - if (_isBody && _contentArrangeElement) { - bodyMinSize.w = parseToZeroOrNumber(_contentArrangeElement.css(_strMinMinus + _strWidth)); - bodyMinSize.h = parseToZeroOrNumber(_contentArrangeElement.css(_strMinMinus + _strHeight)); - bodyMinSize.c = checkCache(bodyMinSize, _bodyMinSizeCache); - bodyMinSize.f = true; //flag for "measured at least once" - } - _bodyMinSizeCache = bodyMinSize; - return !!bodyMinSize.c; - } - - /** - * Returns true if the class names really changed (new class without plugin host prefix) - * @param oldCassNames The old ClassName string. - * @param newClassNames The new ClassName string. - * @returns {boolean} True if the class names has really changed, false otherwise. - */ - function hostClassNamesChanged(oldCassNames, newClassNames) { - var currClasses = (newClassNames !== undefined && newClassNames !== null) ? newClassNames.split(_strSpace) : _strEmpty; - var oldClasses = (oldCassNames !== undefined && oldCassNames !== null) ? oldCassNames.split(_strSpace) : _strEmpty; - if (currClasses === _strEmpty && oldClasses === _strEmpty) - return false; - var diff = getArrayDifferences(oldClasses, currClasses); - var changed = false; - var oldClassNames = _oldClassName !== undefined && _oldClassName !== null ? _oldClassName.split(_strSpace) : [_strEmpty]; - var currClassNames = _classNameCache !== undefined && _classNameCache !== null ? _classNameCache.split(_strSpace) : [_strEmpty]; - - //remove none theme from diff list to prevent update - var idx = inArray(_classNameThemeNone, diff); - var curr; - var i; - var v; - var o; - var c; - - if (idx > -1) - diff.splice(idx, 1); - - for (i = 0; i < diff.length; i++) { - curr = diff[i]; - if (curr.indexOf(_classNameHostElement) !== 0) { - o = true; - c = true; - for (v = 0; v < oldClassNames.length; v++) { - if (curr === oldClassNames[v]) { - o = false; - break; - } - } - for (v = 0; v < currClassNames.length; v++) { - if (curr === currClassNames[v]) { - c = false; - break; - } - } - if (o && c) { - changed = true; - break; - } - } - - } - return changed; - } - - /** - * Returns true if the given mutation is not from a from the plugin generated element. If the target element is a textarea the mutation is always unknown. - * @param mutation The mutation which shall be checked. - * @returns {boolean} True if the mutation is from a unknown element, false otherwise. - */ - function isUnknownMutation(mutation) { - var attributeName = mutation.attributeName; - var mutationTarget = mutation.target; - var mutationType = mutation.type; - var strClosest = 'closest'; - - if (mutationTarget === _contentElementNative) - return attributeName === null; - if (mutationType === 'attributes' && (attributeName === LEXICON.c || attributeName === LEXICON.s) && !_isTextarea) { - //ignore className changes by the plugin - if (attributeName === LEXICON.c && FRAMEWORK(mutationTarget).hasClass(_classNameHostElement)) - return hostClassNamesChanged(mutation.oldValue, mutationTarget.getAttribute(LEXICON.c)); - - //only do it of browser support it natively - if (typeof mutationTarget[strClosest] != TYPES.f) - return true; - if (mutationTarget[strClosest](_strDot + _classNameResizeObserverElement) !== null || - mutationTarget[strClosest](_strDot + _classNameScrollbar) !== null || - mutationTarget[strClosest](_strDot + _classNameScrollbarCorner) !== null) - return false; - } - return true; - } - - /** - * Returns true if the content size was changed since the last time this method was called. - * @returns {boolean} True if the content size was changed, false otherwise. - */ - function updateAutoContentSizeChanged() { - if (_sleeping) - return false; - - var contentMeasureElement = getContentMeasureElement(); - var textareaValueLength = _isTextarea && _widthAutoCache && !_textareaAutoWrappingCache ? _targetElement.val().length : 0; - var setCSS = !_mutationObserversConnected && _widthAutoCache && !_isTextarea; - var css = {}; - var float; - var bodyMinSizeC; - var changed; - var contentElementScrollSize; - - if (setCSS) { - float = _contentElement.css(_strFloat); - css[_strFloat] = _isRTL ? _strRight : _strLeft; - css[_strWidth] = _strAuto; - _contentElement.css(css); - } - contentElementScrollSize = { - w: contentMeasureElement[LEXICON.sW] + textareaValueLength, - h: contentMeasureElement[LEXICON.sH] + textareaValueLength - }; - if (setCSS) { - css[_strFloat] = float; - css[_strWidth] = _strHundredPercent; - _contentElement.css(css); - } - - bodyMinSizeC = bodyMinSizeChanged(); - changed = checkCache(contentElementScrollSize, _contentElementScrollSizeChangeDetectedCache); - - _contentElementScrollSizeChangeDetectedCache = contentElementScrollSize; - - return changed || bodyMinSizeC; - } - - /** - * Returns true when a attribute which the MutationObserver would observe has changed. - * @returns {boolean} True if one of the attributes which a MutationObserver would observe has changed, false or undefined otherwise. - */ - function meaningfulAttrsChanged() { - if (_sleeping || _mutationObserversConnected) - return; - - var elem; - var curr; - var cache; - var changedAttrs = []; - var checks = [ - { - _elem: _hostElement, - _attrs: _mutationObserverAttrsHost.concat(':visible') - }, - { - _elem: _isTextarea ? _targetElement : undefined, - _attrs: _mutationObserverAttrsTextarea - } - ]; - - each(checks, function (index, check) { - elem = check._elem; - if (elem) { - each(check._attrs, function (index, attr) { - curr = attr.charAt(0) === ':' ? elem.is(attr) : elem.attr(attr); - cache = _updateAutoCache[attr]; - - if(checkCache(curr, cache)) { - changedAttrs.push(attr); - } - - _updateAutoCache[attr] = curr; - }); - } - }); - - updateViewportAttrsFromTarget(changedAttrs); - - return changedAttrs[LEXICON.l] > 0; - } - - /** - * Checks is a CSS Property of a child element is affecting the scroll size of the content. - * @param propertyName The CSS property name. - * @returns {boolean} True if the property is affecting the content scroll size, false otherwise. - */ - function isSizeAffectingCSSProperty(propertyName) { - if (!_initialized) - return true; - var flexGrow = 'flex-grow'; - var flexShrink = 'flex-shrink'; - var flexBasis = 'flex-basis'; - var affectingPropsX = [ - _strWidth, - _strMinMinus + _strWidth, - _strMaxMinus + _strWidth, - _strMarginMinus + _strLeft, - _strMarginMinus + _strRight, - _strLeft, - _strRight, - 'font-weight', - 'word-spacing', - flexGrow, - flexShrink, - flexBasis - ]; - var affectingPropsXContentBox = [ - _strPaddingMinus + _strLeft, - _strPaddingMinus + _strRight, - _strBorderMinus + _strLeft + _strWidth, - _strBorderMinus + _strRight + _strWidth - ]; - var affectingPropsY = [ - _strHeight, - _strMinMinus + _strHeight, - _strMaxMinus + _strHeight, - _strMarginMinus + _strTop, - _strMarginMinus + _strBottom, - _strTop, - _strBottom, - 'line-height', - flexGrow, - flexShrink, - flexBasis - ]; - var affectingPropsYContentBox = [ - _strPaddingMinus + _strTop, - _strPaddingMinus + _strBottom, - _strBorderMinus + _strTop + _strWidth, - _strBorderMinus + _strBottom + _strWidth - ]; - var _strS = 's'; - var _strVS = 'v-s'; - var checkX = _overflowBehaviorCache.x === _strS || _overflowBehaviorCache.x === _strVS; - var checkY = _overflowBehaviorCache.y === _strS || _overflowBehaviorCache.y === _strVS; - var sizeIsAffected = false; - var checkPropertyName = function (arr, name) { - for (var i = 0; i < arr[LEXICON.l]; i++) { - if (arr[i] === name) - return true; - } - return false; - }; - - if (checkY) { - sizeIsAffected = checkPropertyName(affectingPropsY, propertyName); - if (!sizeIsAffected && !_isBorderBox) - sizeIsAffected = checkPropertyName(affectingPropsYContentBox, propertyName); - } - if (checkX && !sizeIsAffected) { - sizeIsAffected = checkPropertyName(affectingPropsX, propertyName); - if (!sizeIsAffected && !_isBorderBox) - sizeIsAffected = checkPropertyName(affectingPropsXContentBox, propertyName); - } - return sizeIsAffected; - } - - - //==== Update ====// - - /** - * Sets the attribute values of the viewport element to the values from the target element. - * The value of a attribute is only set if the attribute is whitelisted. - * @attrs attrs The array of attributes which shall be set or undefined if all whitelisted shall be set. - */ - function updateViewportAttrsFromTarget(attrs) { - attrs = attrs || _viewportAttrsFromTarget; - each(attrs, function (index, attr) { - if (COMPATIBILITY.inA(attr, _viewportAttrsFromTarget) > -1) { - var targetAttr = _targetElement.attr(attr); - if(type(targetAttr) == TYPES.s) { - _viewportElement.attr(attr, targetAttr); - } - else { - _viewportElement.removeAttr(attr); - } - } - }); - } - - /** - * Updates the variables and size of the textarea element, and manages the scroll on new line or new character. - */ - function textareaUpdate() { - if (!_sleeping) { - var wrapAttrOff = !_textareaAutoWrappingCache; - var minWidth = _viewportSize.w; - var minHeight = _viewportSize.h; - var css = {}; - var doMeasure = _widthAutoCache || wrapAttrOff; - var origWidth; - var width; - var origHeight; - var height; - - //reset min size - css[_strMinMinus + _strWidth] = _strEmpty; - css[_strMinMinus + _strHeight] = _strEmpty; - - //set width auto - css[_strWidth] = _strAuto; - _targetElement.css(css); - - //measure width - origWidth = _targetElementNative[LEXICON.oW]; - width = doMeasure ? MATH.max(origWidth, _targetElementNative[LEXICON.sW] - 1) : 1; - /*width += (_widthAutoCache ? _marginX + (!_isBorderBox ? wrapAttrOff ? 0 : _paddingX + _borderX : 0) : 0);*/ - - //set measured width - css[_strWidth] = _widthAutoCache ? _strAuto /*width*/ : _strHundredPercent; - css[_strMinMinus + _strWidth] = _strHundredPercent; - - //set height auto - css[_strHeight] = _strAuto; - _targetElement.css(css); - - //measure height - origHeight = _targetElementNative[LEXICON.oH]; - height = MATH.max(origHeight, _targetElementNative[LEXICON.sH] - 1); - - //append correct size values - css[_strWidth] = width; - css[_strHeight] = height; - _textareaCoverElement.css(css); - - //apply min width / min height to prevent textarea collapsing - css[_strMinMinus + _strWidth] = minWidth /*+ (!_isBorderBox && _widthAutoCache ? _paddingX + _borderX : 0)*/; - css[_strMinMinus + _strHeight] = minHeight /*+ (!_isBorderBox && _heightAutoCache ? _paddingY + _borderY : 0)*/; - _targetElement.css(css); - - return { - _originalWidth: origWidth, - _originalHeight: origHeight, - _dynamicWidth: width, - _dynamicHeight: height - }; - } - } - - /** - * Updates the plugin and DOM to the current options. - * This method should only be called if a update is 100% required. - * @param updateHints A objects which contains hints for this update: - * { - * _hostSizeChanged : boolean, - * _contentSizeChanged : boolean, - * _force : boolean, == preventSwallowing - * _changedOptions : { }, == preventSwallowing && preventSleep - * } - */ - function update(updateHints) { - clearTimeout(_swallowedUpdateTimeout); - updateHints = updateHints || {}; - _swallowedUpdateHints._hostSizeChanged |= updateHints._hostSizeChanged; - _swallowedUpdateHints._contentSizeChanged |= updateHints._contentSizeChanged; - _swallowedUpdateHints._force |= updateHints._force; - - var now = COMPATIBILITY.now(); - var hostSizeChanged = !!_swallowedUpdateHints._hostSizeChanged; - var contentSizeChanged = !!_swallowedUpdateHints._contentSizeChanged; - var force = !!_swallowedUpdateHints._force; - var changedOptions = updateHints._changedOptions; - var swallow = _swallowUpdateLag > 0 && _initialized && !_destroyed && !force && !changedOptions && (now - _lastUpdateTime) < _swallowUpdateLag && (!_heightAutoCache && !_widthAutoCache); - var displayIsHidden; - - if (swallow) - _swallowedUpdateTimeout = setTimeout(update, _swallowUpdateLag); - - //abort update due to: - //destroyed - //swallowing - //sleeping - //host is hidden or has false display - if (_destroyed || swallow || (_sleeping && !changedOptions) || (_initialized && !force && (displayIsHidden = _hostElement.is(':hidden'))) || _hostElement.css('display') === 'inline') - return; - - _lastUpdateTime = now; - _swallowedUpdateHints = {}; - - //if scrollbar styling is possible and native scrollbars aren't overlaid the scrollbar styling will be applied which hides the native scrollbars completely. - if (_nativeScrollbarStyling && !(_nativeScrollbarIsOverlaid.x && _nativeScrollbarIsOverlaid.y)) { - //native scrollbars are hidden, so change the values to zero - _nativeScrollbarSize.x = 0; - _nativeScrollbarSize.y = 0; - } - else { - //refresh native scrollbar size (in case of zoom) - _nativeScrollbarSize = extendDeep({}, globals.nativeScrollbarSize); - } - - // Scrollbar padding is needed for firefox, because firefox hides scrollbar automatically if the size of the div is too small. - // The calculation: [scrollbar size +3 *3] - // (+3 because of possible decoration e.g. borders, margins etc., but only if native scrollbar is NOT a overlaid scrollbar) - // (*3 because (1)increase / (2)decrease -button and (3)resize handle) - _nativeScrollbarMinSize = { - x: (_nativeScrollbarSize.x + (_nativeScrollbarIsOverlaid.x ? 0 : 3)) * 3, - y: (_nativeScrollbarSize.y + (_nativeScrollbarIsOverlaid.y ? 0 : 3)) * 3 - }; - - //changedOptions = changedOptions || { }; - //freezeResizeObserver(_sizeObserverElement, true); - //freezeResizeObserver(_sizeAutoObserverElement, true); - - var checkCacheAutoForce = function () { - return checkCache.apply(this, [].slice.call(arguments).concat([force])); - }; - - //save current scroll offset - var currScroll = { - x: _viewportElement[_strScrollLeft](), - y: _viewportElement[_strScrollTop]() - }; - - var currentPreparedOptionsScrollbars = _currentPreparedOptions.scrollbars; - var currentPreparedOptionsTextarea = _currentPreparedOptions.textarea; - - //scrollbars visibility: - var scrollbarsVisibility = currentPreparedOptionsScrollbars.visibility; - var scrollbarsVisibilityChanged = checkCacheAutoForce(scrollbarsVisibility, _scrollbarsVisibilityCache); - - //scrollbars autoHide: - var scrollbarsAutoHide = currentPreparedOptionsScrollbars.autoHide; - var scrollbarsAutoHideChanged = checkCacheAutoForce(scrollbarsAutoHide, _scrollbarsAutoHideCache); - - //scrollbars click scrolling - var scrollbarsClickScrolling = currentPreparedOptionsScrollbars.clickScrolling; - var scrollbarsClickScrollingChanged = checkCacheAutoForce(scrollbarsClickScrolling, _scrollbarsClickScrollingCache); - - //scrollbars drag scrolling - var scrollbarsDragScrolling = currentPreparedOptionsScrollbars.dragScrolling; - var scrollbarsDragScrollingChanged = checkCacheAutoForce(scrollbarsDragScrolling, _scrollbarsDragScrollingCache); - - //className - var className = _currentPreparedOptions.className; - var classNameChanged = checkCacheAutoForce(className, _classNameCache); - - //resize - var resize = _currentPreparedOptions.resize; - var resizeChanged = checkCacheAutoForce(resize, _resizeCache) && !_isBody; //body can't be resized since the window itself acts as resize possibility. - - //paddingAbsolute - var paddingAbsolute = _currentPreparedOptions.paddingAbsolute; - var paddingAbsoluteChanged = checkCacheAutoForce(paddingAbsolute, _paddingAbsoluteCache); - - //clipAlways - var clipAlways = _currentPreparedOptions.clipAlways; - var clipAlwaysChanged = checkCacheAutoForce(clipAlways, _clipAlwaysCache); - - //sizeAutoCapable - var sizeAutoCapable = _currentPreparedOptions.sizeAutoCapable && !_isBody; //body can never be size auto, because it shall be always as big as the viewport. - var sizeAutoCapableChanged = checkCacheAutoForce(sizeAutoCapable, _sizeAutoCapableCache); - - //showNativeScrollbars - var ignoreOverlayScrollbarHiding = _currentPreparedOptions.nativeScrollbarsOverlaid.showNativeScrollbars; - var ignoreOverlayScrollbarHidingChanged = checkCacheAutoForce(ignoreOverlayScrollbarHiding, _ignoreOverlayScrollbarHidingCache); - - //autoUpdate - var autoUpdate = _currentPreparedOptions.autoUpdate; - var autoUpdateChanged = checkCacheAutoForce(autoUpdate, _autoUpdateCache); - - //overflowBehavior - var overflowBehavior = _currentPreparedOptions.overflowBehavior; - var overflowBehaviorChanged = checkCacheAutoForce(overflowBehavior, _overflowBehaviorCache, force); - - //dynWidth: - var textareaDynWidth = currentPreparedOptionsTextarea.dynWidth; - var textareaDynWidthChanged = checkCacheAutoForce(_textareaDynWidthCache, textareaDynWidth); - - //dynHeight: - var textareaDynHeight = currentPreparedOptionsTextarea.dynHeight; - var textareaDynHeightChanged = checkCacheAutoForce(_textareaDynHeightCache, textareaDynHeight); - - //scrollbars visibility - _scrollbarsAutoHideNever = scrollbarsAutoHide === 'n'; - _scrollbarsAutoHideScroll = scrollbarsAutoHide === 's'; - _scrollbarsAutoHideMove = scrollbarsAutoHide === 'm'; - _scrollbarsAutoHideLeave = scrollbarsAutoHide === 'l'; - - //scrollbars autoHideDelay - _scrollbarsAutoHideDelay = currentPreparedOptionsScrollbars.autoHideDelay; - - //old className - _oldClassName = _classNameCache; - - //resize - _resizeNone = resize === 'n'; - _resizeBoth = resize === 'b'; - _resizeHorizontal = resize === 'h'; - _resizeVertical = resize === 'v'; - - //normalizeRTL - _normalizeRTLCache = _currentPreparedOptions.normalizeRTL; - - //ignore overlay scrollbar hiding - ignoreOverlayScrollbarHiding = ignoreOverlayScrollbarHiding && (_nativeScrollbarIsOverlaid.x && _nativeScrollbarIsOverlaid.y); - - //refresh options cache - _scrollbarsVisibilityCache = scrollbarsVisibility; - _scrollbarsAutoHideCache = scrollbarsAutoHide; - _scrollbarsClickScrollingCache = scrollbarsClickScrolling; - _scrollbarsDragScrollingCache = scrollbarsDragScrolling; - _classNameCache = className; - _resizeCache = resize; - _paddingAbsoluteCache = paddingAbsolute; - _clipAlwaysCache = clipAlways; - _sizeAutoCapableCache = sizeAutoCapable; - _ignoreOverlayScrollbarHidingCache = ignoreOverlayScrollbarHiding; - _autoUpdateCache = autoUpdate; - _overflowBehaviorCache = extendDeep({}, overflowBehavior); - _textareaDynWidthCache = textareaDynWidth; - _textareaDynHeightCache = textareaDynHeight; - _hasOverflowCache = _hasOverflowCache || { x: false, y: false }; - - //set correct class name to the host element - if (classNameChanged) { - removeClass(_hostElement, _oldClassName + _strSpace + _classNameThemeNone); - addClass(_hostElement, className !== undefined && className !== null && className.length > 0 ? className : _classNameThemeNone); - } - - //set correct auto Update - if (autoUpdateChanged) { - if (autoUpdate === true) { - disconnectMutationObservers(); - autoUpdateLoop.add(_base); - } - else if (autoUpdate === null) { - if (_autoUpdateRecommended) { - disconnectMutationObservers(); - autoUpdateLoop.add(_base); - } - else { - autoUpdateLoop.remove(_base); - connectMutationObservers(); - } - } - else { - autoUpdateLoop.remove(_base); - connectMutationObservers(); - } - } - - //activate or deactivate size auto capability - if (sizeAutoCapableChanged) { - if (sizeAutoCapable) { - if (!_contentGlueElement) { - _contentGlueElement = FRAMEWORK(generateDiv(_classNameContentGlueElement)); - _paddingElement.before(_contentGlueElement); - } - else { - _contentGlueElement.show(); - } - if (_sizeAutoObserverAdded) { - _sizeAutoObserverElement.show(); - } - else { - _sizeAutoObserverElement = FRAMEWORK(generateDiv(_classNameSizeAutoObserverElement)); - _sizeAutoObserverElementNative = _sizeAutoObserverElement[0]; - - _contentGlueElement.before(_sizeAutoObserverElement); - var oldSize = { w: -1, h: -1 }; - setupResizeObserver(_sizeAutoObserverElement, function () { - var newSize = { - w: _sizeAutoObserverElementNative[LEXICON.oW], - h: _sizeAutoObserverElementNative[LEXICON.oH] - }; - if (checkCache(newSize, oldSize)) { - if (_initialized && (_heightAutoCache && newSize.h > 0) || (_widthAutoCache && newSize.w > 0)) { - update(); - } - else if (_initialized && (!_heightAutoCache && newSize.h === 0) || (!_widthAutoCache && newSize.w === 0)) { - update(); - } - } - oldSize = newSize; - }); - _sizeAutoObserverAdded = true; - //fix heightAuto detector bug if height is fixed but contentHeight is 0. - //the probability this bug will ever happen is very very low, thats why its ok if we use calc which isn't supported in IE8. - if (_cssCalc !== null) - _sizeAutoObserverElement.css(_strHeight, _cssCalc + '(100% + 1px)'); - } - } - else { - if (_sizeAutoObserverAdded) - _sizeAutoObserverElement.hide(); - if (_contentGlueElement) - _contentGlueElement.hide(); - } - } - - //if force, update all resizeObservers too - if (force) { - _sizeObserverElement.find('*').trigger(_strScroll); - if (_sizeAutoObserverAdded) - _sizeAutoObserverElement.find('*').trigger(_strScroll); - } - - //display hidden: - displayIsHidden = displayIsHidden === undefined ? _hostElement.is(':hidden') : displayIsHidden; - var displayIsHiddenChanged = checkCacheAutoForce(displayIsHidden, _displayIsHiddenCache); - - //textarea AutoWrapping: - var textareaAutoWrapping = _isTextarea ? _targetElement.attr('wrap') !== 'off' : false; - var textareaAutoWrappingChanged = checkCacheAutoForce(textareaAutoWrapping, _textareaAutoWrappingCache); - - //detect direction: - var cssDirection = _hostElement.css('direction'); - var cssDirectionChanged = checkCacheAutoForce(cssDirection, _cssDirectionCache); - - //detect box-sizing: - var boxSizing = _hostElement.css('box-sizing'); - var boxSizingChanged = checkCacheAutoForce(boxSizing, _cssBoxSizingCache); - - //detect padding: - var padding = { - c: force, - t: parseToZeroOrNumber(_hostElement.css(_strPaddingMinus + _strTop)), - r: parseToZeroOrNumber(_hostElement.css(_strPaddingMinus + _strRight)), - b: parseToZeroOrNumber(_hostElement.css(_strPaddingMinus + _strBottom)), - l: parseToZeroOrNumber(_hostElement.css(_strPaddingMinus + _strLeft)) - }; - - //width + height auto detecting var: - var sizeAutoObserverElementBCRect; - //exception occurs in IE8 sometimes (unknown exception) - try { - sizeAutoObserverElementBCRect = _sizeAutoObserverAdded ? _sizeAutoObserverElementNative[LEXICON.bCR]() : null; - } catch (ex) { - return; - } - - _isRTL = cssDirection === 'rtl'; - _isBorderBox = (boxSizing === 'border-box'); - var isRTLLeft = _isRTL ? _strLeft : _strRight; - var isRTLRight = _isRTL ? _strRight : _strLeft; - - //detect width auto: - var widthAutoResizeDetection = false; - var widthAutoObserverDetection = (_sizeAutoObserverAdded && (_hostElement.css(_strFloat) !== 'none' /*|| _isTextarea */)) ? (MATH.round(sizeAutoObserverElementBCRect.right - sizeAutoObserverElementBCRect.left) === 0) && (!paddingAbsolute ? (_hostElementNative[LEXICON.cW] - _paddingX) > 0 : true) : false; - if (sizeAutoCapable && !widthAutoObserverDetection) { - var tmpCurrHostWidth = _hostElementNative[LEXICON.oW]; - var tmpCurrContentGlueWidth = _contentGlueElement.css(_strWidth); - _contentGlueElement.css(_strWidth, _strAuto); - - var tmpNewHostWidth = _hostElementNative[LEXICON.oW]; - _contentGlueElement.css(_strWidth, tmpCurrContentGlueWidth); - widthAutoResizeDetection = tmpCurrHostWidth !== tmpNewHostWidth; - if (!widthAutoResizeDetection) { - _contentGlueElement.css(_strWidth, tmpCurrHostWidth + 1); - tmpNewHostWidth = _hostElementNative[LEXICON.oW]; - _contentGlueElement.css(_strWidth, tmpCurrContentGlueWidth); - widthAutoResizeDetection = tmpCurrHostWidth !== tmpNewHostWidth; - } - } - var widthAuto = (widthAutoObserverDetection || widthAutoResizeDetection) && sizeAutoCapable && !displayIsHidden; - var widthAutoChanged = checkCacheAutoForce(widthAuto, _widthAutoCache); - var wasWidthAuto = !widthAuto && _widthAutoCache; - - //detect height auto: - var heightAuto = _sizeAutoObserverAdded && sizeAutoCapable && !displayIsHidden ? (MATH.round(sizeAutoObserverElementBCRect.bottom - sizeAutoObserverElementBCRect.top) === 0) /* && (!paddingAbsolute && (_msieVersion > 9 || !_msieVersion) ? true : true) */ : false; - var heightAutoChanged = checkCacheAutoForce(heightAuto, _heightAutoCache); - var wasHeightAuto = !heightAuto && _heightAutoCache; - - //detect border: - //we need the border only if border box and auto size - var strMinusWidth = '-' + _strWidth; - var updateBorderX = (widthAuto && _isBorderBox) || !_isBorderBox; - var updateBorderY = (heightAuto && _isBorderBox) || !_isBorderBox; - var border = { - c: force, - t: updateBorderY ? parseToZeroOrNumber(_hostElement.css(_strBorderMinus + _strTop + strMinusWidth), true) : 0, - r: updateBorderX ? parseToZeroOrNumber(_hostElement.css(_strBorderMinus + _strRight + strMinusWidth), true) : 0, - b: updateBorderY ? parseToZeroOrNumber(_hostElement.css(_strBorderMinus + _strBottom + strMinusWidth), true) : 0, - l: updateBorderX ? parseToZeroOrNumber(_hostElement.css(_strBorderMinus + _strLeft + strMinusWidth), true) : 0 - }; - - //detect margin: - var margin = { - c: force, - t: parseToZeroOrNumber(_hostElement.css(_strMarginMinus + _strTop)), - r: parseToZeroOrNumber(_hostElement.css(_strMarginMinus + _strRight)), - b: parseToZeroOrNumber(_hostElement.css(_strMarginMinus + _strBottom)), - l: parseToZeroOrNumber(_hostElement.css(_strMarginMinus + _strLeft)) - }; - - //detect css max width & height: - var cssMaxValue = { - h: String(_hostElement.css(_strMaxMinus + _strHeight)), - w: String(_hostElement.css(_strMaxMinus + _strWidth)) - }; - - //vars to apply correct css - var contentElementCSS = {}; - var contentGlueElementCSS = {}; - - //funcs - var getHostSize = function () { - //has to be clientSize because offsetSize respect borders - return { - w: _hostElementNative[LEXICON.cW], - h: _hostElementNative[LEXICON.cH] - }; - }; - var getViewportSize = function () { - //viewport size is padding container because it never has padding, margin and a border - //determine zoom rounding error -> sometimes scrollWidth/Height is smaller than clientWidth/Height - //if this happens add the difference to the viewportSize to compensate the rounding error - return { - w: _paddingElementNative[LEXICON.oW] + MATH.max(0, _contentElementNative[LEXICON.cW] - _contentElementNative[LEXICON.sW]), - h: _paddingElementNative[LEXICON.oH] + MATH.max(0, _contentElementNative[LEXICON.cH] - _contentElementNative[LEXICON.sH]) - }; - }; - - //set info for padding - var paddingAbsoluteX = _paddingX = padding.l + padding.r; - var paddingAbsoluteY = _paddingY = padding.t + padding.b; - paddingAbsoluteX *= paddingAbsolute ? 1 : 0; - paddingAbsoluteY *= paddingAbsolute ? 1 : 0; - padding.c = checkCacheAutoForce(padding, _cssPaddingCache); - - //set info for border - _borderX = border.l + border.r; - _borderY = border.t + border.b; - border.c = checkCacheAutoForce(border, _cssBorderCache); - - //set info for margin - _marginX = margin.l + margin.r; - _marginY = margin.t + margin.b; - margin.c = checkCacheAutoForce(margin, _cssMarginCache); - - //set info for css max value - cssMaxValue.ih = parseToZeroOrNumber(cssMaxValue.h); //ih = integer height - cssMaxValue.iw = parseToZeroOrNumber(cssMaxValue.w); //iw = integer width - cssMaxValue.ch = cssMaxValue.h.indexOf('px') > -1; //ch = correct height - cssMaxValue.cw = cssMaxValue.w.indexOf('px') > -1; //cw = correct width - cssMaxValue.c = checkCacheAutoForce(cssMaxValue, _cssMaxValueCache); - - //refresh cache - _displayIsHiddenCache = displayIsHidden; - _textareaAutoWrappingCache = textareaAutoWrapping; - _cssDirectionCache = cssDirection; - _cssBoxSizingCache = boxSizing; - _widthAutoCache = widthAuto; - _heightAutoCache = heightAuto; - _cssPaddingCache = padding; - _cssBorderCache = border; - _cssMarginCache = margin; - _cssMaxValueCache = cssMaxValue; - - //IEFix direction changed - if (cssDirectionChanged && _sizeAutoObserverAdded) - _sizeAutoObserverElement.css(_strFloat, isRTLRight); - - //apply padding: - if (padding.c || cssDirectionChanged || paddingAbsoluteChanged || widthAutoChanged || heightAutoChanged || boxSizingChanged || sizeAutoCapableChanged) { - var paddingElementCSS = {}; - var textareaCSS = {}; - setTopRightBottomLeft(contentGlueElementCSS, _strMarginMinus, [-padding.t, -padding.r, -padding.b, -padding.l]); - if (paddingAbsolute) { - setTopRightBottomLeft(paddingElementCSS, _strEmpty, [padding.t, padding.r, padding.b, padding.l]); - if (_isTextarea) - setTopRightBottomLeft(textareaCSS, _strPaddingMinus); - else - setTopRightBottomLeft(contentElementCSS, _strPaddingMinus); - } - else { - setTopRightBottomLeft(paddingElementCSS, _strEmpty); - if (_isTextarea) - setTopRightBottomLeft(textareaCSS, _strPaddingMinus, [padding.t, padding.r, padding.b, padding.l]); - else - setTopRightBottomLeft(contentElementCSS, _strPaddingMinus, [padding.t, padding.r, padding.b, padding.l]); - } - _paddingElement.css(paddingElementCSS); - _targetElement.css(textareaCSS); - } - - //viewport size is padding container because it never has padding, margin and a border. - _viewportSize = getViewportSize(); - - //update Textarea - var textareaSize = _isTextarea ? textareaUpdate() : false; - var textareaSizeChanged = _isTextarea && checkCacheAutoForce(textareaSize, _textareaSizeCache); - var textareaDynOrigSize = _isTextarea && textareaSize ? { - w: textareaDynWidth ? textareaSize._dynamicWidth : textareaSize._originalWidth, - h: textareaDynHeight ? textareaSize._dynamicHeight : textareaSize._originalHeight - } : {}; - _textareaSizeCache = textareaSize; - - //fix height auto / width auto in cooperation with current padding & boxSizing behavior: - if (heightAuto && (heightAutoChanged || paddingAbsoluteChanged || boxSizingChanged || cssMaxValue.c || padding.c || border.c)) { - /* - if (cssMaxValue.ch) - contentElementCSS[_strMaxMinus + _strHeight] = - (cssMaxValue.ch ? (cssMaxValue.ih - paddingAbsoluteY + (_isBorderBox ? -_borderY : _paddingY)) - : _strEmpty); - */ - contentElementCSS[_strHeight] = _strAuto; - } - else if (heightAutoChanged || paddingAbsoluteChanged) { - contentElementCSS[_strMaxMinus + _strHeight] = _strEmpty; - contentElementCSS[_strHeight] = _strHundredPercent; - } - if (widthAuto && (widthAutoChanged || paddingAbsoluteChanged || boxSizingChanged || cssMaxValue.c || padding.c || border.c || cssDirectionChanged)) { - /* - if (cssMaxValue.cw) - contentElementCSS[_strMaxMinus + _strWidth] = - (cssMaxValue.cw ? (cssMaxValue.iw - paddingAbsoluteX + (_isBorderBox ? -_borderX : _paddingX)) + - (_nativeScrollbarIsOverlaid.y ? _overlayScrollbarDummySize.y : 0) - : _strEmpty); - */ - contentElementCSS[_strWidth] = _strAuto; - contentGlueElementCSS[_strMaxMinus + _strWidth] = _strHundredPercent; //IE Fix - } - else if (widthAutoChanged || paddingAbsoluteChanged) { - contentElementCSS[_strMaxMinus + _strWidth] = _strEmpty; - contentElementCSS[_strWidth] = _strHundredPercent; - contentElementCSS[_strFloat] = _strEmpty; - contentGlueElementCSS[_strMaxMinus + _strWidth] = _strEmpty; //IE Fix - } - if (widthAuto) { - if (!cssMaxValue.cw) - contentElementCSS[_strMaxMinus + _strWidth] = _strEmpty; - //textareaDynOrigSize.w || _strAuto :: doesnt works because applied margin will shift width - contentGlueElementCSS[_strWidth] = _strAuto; - - contentElementCSS[_strWidth] = _strAuto; - contentElementCSS[_strFloat] = isRTLRight; - } - else { - contentGlueElementCSS[_strWidth] = _strEmpty; - } - if (heightAuto) { - if (!cssMaxValue.ch) - contentElementCSS[_strMaxMinus + _strHeight] = _strEmpty; - //textareaDynOrigSize.h || _contentElementNative[LEXICON.cH] :: use for anti scroll jumping - contentGlueElementCSS[_strHeight] = textareaDynOrigSize.h || _contentElementNative[LEXICON.cH]; - } - else { - contentGlueElementCSS[_strHeight] = _strEmpty; - } - if (sizeAutoCapable) - _contentGlueElement.css(contentGlueElementCSS); - _contentElement.css(contentElementCSS); - - //CHECKPOINT HERE ~ - contentElementCSS = {}; - contentGlueElementCSS = {}; - - //if [content(host) client / scroll size, or target element direction, or content(host) max-sizes] changed, or force is true - if (hostSizeChanged || contentSizeChanged || textareaSizeChanged || cssDirectionChanged || boxSizingChanged || paddingAbsoluteChanged || widthAutoChanged || widthAuto || heightAutoChanged || heightAuto || cssMaxValue.c || ignoreOverlayScrollbarHidingChanged || overflowBehaviorChanged || clipAlwaysChanged || resizeChanged || scrollbarsVisibilityChanged || scrollbarsAutoHideChanged || scrollbarsDragScrollingChanged || scrollbarsClickScrollingChanged || textareaDynWidthChanged || textareaDynHeightChanged || textareaAutoWrappingChanged) { - var strOverflow = 'overflow'; - var strOverflowX = strOverflow + '-x'; - var strOverflowY = strOverflow + '-y'; - var strHidden = 'hidden'; - var strVisible = 'visible'; - - //Reset the viewport (very important for natively overlaid scrollbars and zoom change - //don't change the overflow prop as it is very expensive and affects performance !A LOT! - if(!_nativeScrollbarStyling) { - var viewportElementResetCSS = {}; - var resetXTmp = _hasOverflowCache.y && _hideOverflowCache.ys && !ignoreOverlayScrollbarHiding ? (_nativeScrollbarIsOverlaid.y ? _viewportElement.css(isRTLLeft) : -_nativeScrollbarSize.y) : 0; - var resetBottomTmp = _hasOverflowCache.x && _hideOverflowCache.xs && !ignoreOverlayScrollbarHiding ? (_nativeScrollbarIsOverlaid.x ? _viewportElement.css(_strBottom) : -_nativeScrollbarSize.x) : 0; - setTopRightBottomLeft(viewportElementResetCSS, _strEmpty); - _viewportElement.css(viewportElementResetCSS); - } - - //measure several sizes: - var contentMeasureElement = getContentMeasureElement(); - //in Firefox content element has to have overflow hidden, else element margins aren't calculated properly, this element prevents this bug, but only if scrollbars aren't overlaid - var contentSize = { - //use clientSize because natively overlaidScrollbars add borders - w: textareaDynOrigSize.w || contentMeasureElement[LEXICON.cW], - h: textareaDynOrigSize.h || contentMeasureElement[LEXICON.cH] - }; - var scrollSize = { - w: contentMeasureElement[LEXICON.sW], - h: contentMeasureElement[LEXICON.sH] - }; - - //apply the correct viewport style and measure viewport size - if(!_nativeScrollbarStyling) { - viewportElementResetCSS[_strBottom] = wasHeightAuto ? _strEmpty : resetBottomTmp; - viewportElementResetCSS[isRTLLeft] = wasWidthAuto ? _strEmpty : resetXTmp; - _viewportElement.css(viewportElementResetCSS); - } - _viewportSize = getViewportSize(); - - //measure and correct several sizes - var hostSize = getHostSize(); - var contentGlueSize = { - //client/scrollSize + AbsolutePadding -> because padding is only applied to the paddingElement if its absolute, so you have to add it manually - //hostSize is clientSize -> so padding should be added manually, right? FALSE! Because content glue is inside hostElement, so we don't have to worry about padding - w: MATH.max((widthAuto ? contentSize.w : scrollSize.w) + paddingAbsoluteX, hostSize.w), - h: MATH.max((heightAuto ? contentSize.h : scrollSize.h) + paddingAbsoluteY, hostSize.h) - }; - contentGlueSize.c = checkCacheAutoForce(contentGlueSize, _contentGlueSizeCache); - _contentGlueSizeCache = contentGlueSize; - - //apply correct contentGlue size - if (sizeAutoCapable) { - //size contentGlue correctly to make sure the element has correct size if the sizing switches to auto - if (contentGlueSize.c || (heightAuto || widthAuto)) { - contentGlueElementCSS[_strWidth] = contentGlueSize.w; - contentGlueElementCSS[_strHeight] = contentGlueSize.h; - - //textarea-sizes are already calculated correctly at this point - if (!_isTextarea) { - contentSize = { - //use clientSize because natively overlaidScrollbars add borders - w: contentMeasureElement[LEXICON.cW], - h: contentMeasureElement[LEXICON.cH] - }; - } - } - var textareaCoverCSS = {}; - var setContentGlueElementCSSfunction = function (horizontal) { - var scrollbarVars = getScrollbarVars(horizontal); - var wh = scrollbarVars._w_h; - var strWH = scrollbarVars._width_height; - var autoSize = horizontal ? widthAuto : heightAuto; - var borderSize = horizontal ? _borderX : _borderY; - var paddingSize = horizontal ? _paddingX : _paddingY; - var marginSize = horizontal ? _marginX : _marginY; - var maxSize = contentGlueElementCSS[strWH] + (_isBorderBox ? borderSize : -paddingSize); - - //make contentGlue size -1 if element is not auto sized, to make sure that a resize event happens when the element shrinks - if (!autoSize || (!autoSize && border.c)) - contentGlueElementCSS[strWH] = hostSize[wh] - (_isBorderBox ? 0 : paddingSize + borderSize) - 1 - marginSize; - - //if size is auto and host is same size as max size, make content glue size +1 to make sure size changes will be detected - if (autoSize && cssMaxValue['c' + wh] && cssMaxValue['i' + wh] === maxSize) - contentGlueElementCSS[strWH] = maxSize + (_isBorderBox ? 0 : paddingSize) + 1; - - //if size is auto and host is smaller than size as min size, make content glue size -1 to make sure size changes will be detected (this is only needed if padding is 0) - if (autoSize && (contentSize[wh] < _viewportSize[wh]) && (horizontal && _isTextarea ? !textareaAutoWrapping : true)) { - if (_isTextarea) - textareaCoverCSS[strWH] = parseToZeroOrNumber(_textareaCoverElement.css(strWH)) - 1; - contentGlueElementCSS[strWH] -= 1; - } - - //make sure content glue size is at least 1 - if (contentSize[wh] > 0) - contentGlueElementCSS[strWH] = MATH.max(1, contentGlueElementCSS[strWH]); - }; - setContentGlueElementCSSfunction(true); - setContentGlueElementCSSfunction(false); - - if (_isTextarea) - _textareaCoverElement.css(textareaCoverCSS); - _contentGlueElement.css(contentGlueElementCSS); - } - if (widthAuto) - contentElementCSS[_strWidth] = _strHundredPercent; - if (widthAuto && !_isBorderBox && !_mutationObserversConnected) - contentElementCSS[_strFloat] = 'none'; - - //apply and reset content style - _contentElement.css(contentElementCSS); - contentElementCSS = {}; - - //measure again, but this time all correct sizes: - var contentScrollSize = { - w: contentMeasureElement[LEXICON.sW], - h: contentMeasureElement[LEXICON.sH], - }; - contentScrollSize.c = contentSizeChanged = checkCacheAutoForce(contentScrollSize, _contentScrollSizeCache); - _contentScrollSizeCache = contentScrollSize; - - //refresh viewport size after correct measuring - _viewportSize = getViewportSize(); - - hostSize = getHostSize(); - hostSizeChanged = checkCacheAutoForce(hostSize, _hostSizeCache); - _hostSizeCache = hostSize; - - var hideOverflowForceTextarea = _isTextarea && (_viewportSize.w === 0 || _viewportSize.h === 0); - var previousOverflowAmount = _overflowAmountCache; - var overflowBehaviorIsVS = {}; - var overflowBehaviorIsVH = {}; - var overflowBehaviorIsS = {}; - var overflowAmount = {}; - var hasOverflow = {}; - var hideOverflow = {}; - var canScroll = {}; - var viewportRect = _paddingElementNative[LEXICON.bCR](); - var setOverflowVariables = function (horizontal) { - var scrollbarVars = getScrollbarVars(horizontal); - var scrollbarVarsInverted = getScrollbarVars(!horizontal); - var xyI = scrollbarVarsInverted._x_y; - var xy = scrollbarVars._x_y; - var wh = scrollbarVars._w_h; - var widthHeight = scrollbarVars._width_height; - var scrollMax = _strScroll + scrollbarVars._Left_Top + 'Max'; - var fractionalOverflowAmount = viewportRect[widthHeight] ? MATH.abs(viewportRect[widthHeight] - _viewportSize[wh]) : 0; - var checkFractionalOverflowAmount = previousOverflowAmount && previousOverflowAmount[xy] > 0 && _viewportElementNative[scrollMax] === 0; - overflowBehaviorIsVS[xy] = overflowBehavior[xy] === 'v-s'; - overflowBehaviorIsVH[xy] = overflowBehavior[xy] === 'v-h'; - overflowBehaviorIsS[xy] = overflowBehavior[xy] === 's'; - overflowAmount[xy] = MATH.max(0, MATH.round((contentScrollSize[wh] - _viewportSize[wh]) * 100) / 100); - overflowAmount[xy] *= (hideOverflowForceTextarea || (checkFractionalOverflowAmount && fractionalOverflowAmount > 0 && fractionalOverflowAmount < 1)) ? 0 : 1; - hasOverflow[xy] = overflowAmount[xy] > 0; - - //hideOverflow: - //x || y : true === overflow is hidden by "overflow: scroll" OR "overflow: hidden" - //xs || ys : true === overflow is hidden by "overflow: scroll" - hideOverflow[xy] = overflowBehaviorIsVS[xy] || overflowBehaviorIsVH[xy] ? (hasOverflow[xyI] && !overflowBehaviorIsVS[xyI] && !overflowBehaviorIsVH[xyI]) : hasOverflow[xy]; - hideOverflow[xy + 's'] = hideOverflow[xy] ? (overflowBehaviorIsS[xy] || overflowBehaviorIsVS[xy]) : false; - - canScroll[xy] = hasOverflow[xy] && hideOverflow[xy + 's']; - }; - setOverflowVariables(true); - setOverflowVariables(false); - - overflowAmount.c = checkCacheAutoForce(overflowAmount, _overflowAmountCache); - _overflowAmountCache = overflowAmount; - hasOverflow.c = checkCacheAutoForce(hasOverflow, _hasOverflowCache); - _hasOverflowCache = hasOverflow; - hideOverflow.c = checkCacheAutoForce(hideOverflow, _hideOverflowCache); - _hideOverflowCache = hideOverflow; - - //if native scrollbar is overlay at x OR y axis, prepare DOM - if (_nativeScrollbarIsOverlaid.x || _nativeScrollbarIsOverlaid.y) { - var borderDesign = 'px solid transparent'; - var contentArrangeElementCSS = {}; - var arrangeContent = {}; - var arrangeChanged = force; - var setContentElementCSS; - - if (hasOverflow.x || hasOverflow.y) { - arrangeContent.w = _nativeScrollbarIsOverlaid.y && hasOverflow.y ? contentScrollSize.w + _overlayScrollbarDummySize.y : _strEmpty; - arrangeContent.h = _nativeScrollbarIsOverlaid.x && hasOverflow.x ? contentScrollSize.h + _overlayScrollbarDummySize.x : _strEmpty; - arrangeChanged = checkCacheAutoForce(arrangeContent, _arrangeContentSizeCache); - _arrangeContentSizeCache = arrangeContent; - } - - if (hasOverflow.c || hideOverflow.c || contentScrollSize.c || cssDirectionChanged || widthAutoChanged || heightAutoChanged || widthAuto || heightAuto || ignoreOverlayScrollbarHidingChanged) { - contentElementCSS[_strMarginMinus + isRTLRight] = contentElementCSS[_strBorderMinus + isRTLRight] = _strEmpty; - setContentElementCSS = function (horizontal) { - var scrollbarVars = getScrollbarVars(horizontal); - var scrollbarVarsInverted = getScrollbarVars(!horizontal); - var xy = scrollbarVars._x_y; - var strDirection = horizontal ? _strBottom : isRTLLeft; - var invertedAutoSize = horizontal ? heightAuto : widthAuto; - - if (_nativeScrollbarIsOverlaid[xy] && hasOverflow[xy] && hideOverflow[xy + 's']) { - contentElementCSS[_strMarginMinus + strDirection] = invertedAutoSize ? (ignoreOverlayScrollbarHiding ? _strEmpty : _overlayScrollbarDummySize[xy]) : _strEmpty; - contentElementCSS[_strBorderMinus + strDirection] = ((horizontal ? !invertedAutoSize : true) && !ignoreOverlayScrollbarHiding) ? (_overlayScrollbarDummySize[xy] + borderDesign) : _strEmpty; - } - else { - arrangeContent[scrollbarVarsInverted._w_h] = - contentElementCSS[_strMarginMinus + strDirection] = - contentElementCSS[_strBorderMinus + strDirection] = _strEmpty; - arrangeChanged = true; - } - }; - - if (_nativeScrollbarStyling) { - if (ignoreOverlayScrollbarHiding) - removeClass(_viewportElement, _classNameViewportNativeScrollbarsInvisible); - else - addClass(_viewportElement, _classNameViewportNativeScrollbarsInvisible); - } - else { - setContentElementCSS(true); - setContentElementCSS(false); - } - } - if (ignoreOverlayScrollbarHiding) { - arrangeContent.w = arrangeContent.h = _strEmpty; - arrangeChanged = true; - } - if (arrangeChanged && !_nativeScrollbarStyling) { - contentArrangeElementCSS[_strWidth] = hideOverflow.y ? arrangeContent.w : _strEmpty; - contentArrangeElementCSS[_strHeight] = hideOverflow.x ? arrangeContent.h : _strEmpty; - - if (!_contentArrangeElement) { - _contentArrangeElement = FRAMEWORK(generateDiv(_classNameContentArrangeElement)); - _viewportElement.prepend(_contentArrangeElement); - } - _contentArrangeElement.css(contentArrangeElementCSS); - } - _contentElement.css(contentElementCSS); - } - - var viewportElementCSS = {}; - var paddingElementCSS = {}; - var setViewportCSS; - if (hostSizeChanged || hasOverflow.c || hideOverflow.c || contentScrollSize.c || overflowBehaviorChanged || boxSizingChanged || ignoreOverlayScrollbarHidingChanged || cssDirectionChanged || clipAlwaysChanged || heightAutoChanged) { - viewportElementCSS[isRTLRight] = _strEmpty; - setViewportCSS = function (horizontal) { - var scrollbarVars = getScrollbarVars(horizontal); - var scrollbarVarsInverted = getScrollbarVars(!horizontal); - var xy = scrollbarVars._x_y; - var XY = scrollbarVars._X_Y; - var strDirection = horizontal ? _strBottom : isRTLLeft; - - var reset = function () { - viewportElementCSS[strDirection] = _strEmpty; - _contentBorderSize[scrollbarVarsInverted._w_h] = 0; - }; - if (hasOverflow[xy] && hideOverflow[xy + 's']) { - viewportElementCSS[strOverflow + XY] = _strScroll; - if (ignoreOverlayScrollbarHiding || _nativeScrollbarStyling) { - reset(); - } - else { - viewportElementCSS[strDirection] = -(_nativeScrollbarIsOverlaid[xy] ? _overlayScrollbarDummySize[xy] : _nativeScrollbarSize[xy]); - _contentBorderSize[scrollbarVarsInverted._w_h] = _nativeScrollbarIsOverlaid[xy] ? _overlayScrollbarDummySize[scrollbarVarsInverted._x_y] : 0; - } - } else { - viewportElementCSS[strOverflow + XY] = _strEmpty; - reset(); - } - }; - setViewportCSS(true); - setViewportCSS(false); - - // if the scroll container is too small and if there is any overflow with no overlay scrollbar (and scrollbar styling isn't possible), - // make viewport element greater in size (Firefox hide Scrollbars fix) - // because firefox starts hiding scrollbars on too small elements - // with this behavior the overflow calculation may be incorrect or the scrollbars would appear suddenly - // https://bugzilla.mozilla.org/show_bug.cgi?id=292284 - if (!_nativeScrollbarStyling - && (_viewportSize.h < _nativeScrollbarMinSize.x || _viewportSize.w < _nativeScrollbarMinSize.y) - && ((hasOverflow.x && hideOverflow.x && !_nativeScrollbarIsOverlaid.x) || (hasOverflow.y && hideOverflow.y && !_nativeScrollbarIsOverlaid.y))) { - viewportElementCSS[_strPaddingMinus + _strTop] = _nativeScrollbarMinSize.x; - viewportElementCSS[_strMarginMinus + _strTop] = -_nativeScrollbarMinSize.x; - - viewportElementCSS[_strPaddingMinus + isRTLRight] = _nativeScrollbarMinSize.y; - viewportElementCSS[_strMarginMinus + isRTLRight] = -_nativeScrollbarMinSize.y; - } - else { - viewportElementCSS[_strPaddingMinus + _strTop] = - viewportElementCSS[_strMarginMinus + _strTop] = - viewportElementCSS[_strPaddingMinus + isRTLRight] = - viewportElementCSS[_strMarginMinus + isRTLRight] = _strEmpty; - } - viewportElementCSS[_strPaddingMinus + isRTLLeft] = - viewportElementCSS[_strMarginMinus + isRTLLeft] = _strEmpty; - - //if there is any overflow (x OR y axis) and this overflow shall be hidden, make overflow hidden, else overflow visible - if ((hasOverflow.x && hideOverflow.x) || (hasOverflow.y && hideOverflow.y) || hideOverflowForceTextarea) { - //only hide if is Textarea - if (_isTextarea && hideOverflowForceTextarea) { - paddingElementCSS[strOverflowX] = - paddingElementCSS[strOverflowY] = strHidden; - } - } - else { - if (!clipAlways || (overflowBehaviorIsVH.x || overflowBehaviorIsVS.x || overflowBehaviorIsVH.y || overflowBehaviorIsVS.y)) { - //only un-hide if Textarea - if (_isTextarea) { - paddingElementCSS[strOverflowX] = - paddingElementCSS[strOverflowY] = _strEmpty; - } - viewportElementCSS[strOverflowX] = - viewportElementCSS[strOverflowY] = strVisible; - } - } - - _paddingElement.css(paddingElementCSS); - _viewportElement.css(viewportElementCSS); - viewportElementCSS = {}; - - //force soft redraw in webkit because without the scrollbars will may appear because DOM wont be redrawn under special conditions - if ((hasOverflow.c || boxSizingChanged || widthAutoChanged || heightAutoChanged) && !(_nativeScrollbarIsOverlaid.x && _nativeScrollbarIsOverlaid.y)) { - var elementStyle = _contentElementNative[LEXICON.s]; - var dump; - elementStyle.webkitTransform = 'scale(1)'; - elementStyle.display = 'run-in'; - dump = _contentElementNative[LEXICON.oH]; - elementStyle.display = _strEmpty; //|| dump; //use dump to prevent it from deletion if minify - elementStyle.webkitTransform = _strEmpty; - } - /* - //force hard redraw in webkit if native overlaid scrollbars shall appear - if (ignoreOverlayScrollbarHidingChanged && ignoreOverlayScrollbarHiding) { - _hostElement.hide(); - var dump = _hostElementNative[LEXICON.oH]; - _hostElement.show(); - } - */ - } - - //change to direction RTL and width auto Bugfix in Webkit - //without this fix, the DOM still thinks the scrollbar is LTR and thus the content is shifted to the left - contentElementCSS = {}; - if (cssDirectionChanged || widthAutoChanged || heightAutoChanged) { - if (_isRTL && widthAuto) { - var floatTmp = _contentElement.css(_strFloat); - var posLeftWithoutFloat = MATH.round(_contentElement.css(_strFloat, _strEmpty).css(_strLeft, _strEmpty).position().left); - _contentElement.css(_strFloat, floatTmp); - var posLeftWithFloat = MATH.round(_contentElement.position().left); - - if (posLeftWithoutFloat !== posLeftWithFloat) - contentElementCSS[_strLeft] = posLeftWithoutFloat; - } - else { - contentElementCSS[_strLeft] = _strEmpty; - } - } - _contentElement.css(contentElementCSS); - - //handle scroll position - if (_isTextarea && contentSizeChanged) { - var textareaInfo = getTextareaInfo(); - if (textareaInfo) { - var textareaRowsChanged = _textareaInfoCache === undefined ? true : textareaInfo._rows !== _textareaInfoCache._rows; - var cursorRow = textareaInfo._cursorRow; - var cursorCol = textareaInfo._cursorColumn; - var widestRow = textareaInfo._widestRow; - var lastRow = textareaInfo._rows; - var lastCol = textareaInfo._columns; - var cursorPos = textareaInfo._cursorPosition; - var cursorMax = textareaInfo._cursorMax; - var cursorIsLastPosition = (cursorPos >= cursorMax && _textareaHasFocus); - var textareaScrollAmount = { - x: (!textareaAutoWrapping && (cursorCol === lastCol && cursorRow === widestRow)) ? _overflowAmountCache.x : -1, - y: (textareaAutoWrapping ? cursorIsLastPosition || textareaRowsChanged && (previousOverflowAmount ? (currScroll.y === previousOverflowAmount.y) : false) : (cursorIsLastPosition || textareaRowsChanged) && cursorRow === lastRow) ? _overflowAmountCache.y : -1 - }; - currScroll.x = textareaScrollAmount.x > -1 ? (_isRTL && _normalizeRTLCache && _rtlScrollBehavior.i ? 0 : textareaScrollAmount.x) : currScroll.x; //if inverted, scroll to 0 -> normalized this means to max scroll offset. - currScroll.y = textareaScrollAmount.y > -1 ? textareaScrollAmount.y : currScroll.y; - } - _textareaInfoCache = textareaInfo; - } - if (_isRTL && _rtlScrollBehavior.i && _nativeScrollbarIsOverlaid.y && hasOverflow.x && _normalizeRTLCache) - currScroll.x += _contentBorderSize.w || 0; - if (widthAuto) - _hostElement[_strScrollLeft](0); - if (heightAuto) - _hostElement[_strScrollTop](0); - _viewportElement[_strScrollLeft](currScroll.x)[_strScrollTop](currScroll.y); - - //scrollbars management: - var scrollbarsVisibilityVisible = scrollbarsVisibility === 'v'; - var scrollbarsVisibilityHidden = scrollbarsVisibility === 'h'; - var scrollbarsVisibilityAuto = scrollbarsVisibility === 'a'; - - var showScrollbarH = COMPATIBILITY.bind(refreshScrollbarAppearance, 0, true, true, canScroll.x); - var showScrollbarV = COMPATIBILITY.bind(refreshScrollbarAppearance, 0, false, true, canScroll.y); - var hideScrollbarH = COMPATIBILITY.bind(refreshScrollbarAppearance, 0, true, false, canScroll.x); - var hideScrollbarV = COMPATIBILITY.bind(refreshScrollbarAppearance, 0, false, false, canScroll.y); - - //manage class name which indicates scrollable overflow - if (hideOverflow.x || hideOverflow.y) - addClass(_hostElement, _classNameHostOverflow); - else - removeClass(_hostElement, _classNameHostOverflow); - if (hideOverflow.x) - addClass(_hostElement, _classNameHostOverflowX); - else - removeClass(_hostElement, _classNameHostOverflowX); - if (hideOverflow.y) - addClass(_hostElement, _classNameHostOverflowY); - else - removeClass(_hostElement, _classNameHostOverflowY); - - //add or remove rtl class name for styling purposes - if (cssDirectionChanged) { - if (_isRTL) - addClass(_hostElement, _classNameHostRTL); - else - removeClass(_hostElement, _classNameHostRTL); - } - - //manage the resize feature (CSS3 resize "polyfill" for this plugin) - if (_isBody) - addClass(_hostElement, _classNameHostResizeDisabled); - if (resizeChanged) { - removeClass(_scrollbarCornerElement, [ - _classNameScrollbarCornerResize, - _classNameScrollbarCornerResizeB, - _classNameScrollbarCornerResizeH, - _classNameScrollbarCornerResizeV].join(_strSpace)); - if (_resizeNone) { - addClass(_hostElement, _classNameHostResizeDisabled); - } - else { - removeClass(_hostElement, _classNameHostResizeDisabled); - addClass(_scrollbarCornerElement, _classNameScrollbarCornerResize); - if (_resizeBoth) - addClass(_scrollbarCornerElement, _classNameScrollbarCornerResizeB); - else if (_resizeHorizontal) - addClass(_scrollbarCornerElement, _classNameScrollbarCornerResizeH); - else if (_resizeVertical) - addClass(_scrollbarCornerElement, _classNameScrollbarCornerResizeV); - } - } - - //manage the scrollbars general visibility + the scrollbar interactivity (unusable class name) - if (scrollbarsVisibilityChanged || overflowBehaviorChanged || hideOverflow.c || hasOverflow.c || ignoreOverlayScrollbarHidingChanged) { - if (ignoreOverlayScrollbarHiding) { - if (ignoreOverlayScrollbarHidingChanged) { - removeClass(_hostElement, _classNameHostScrolling); - if (ignoreOverlayScrollbarHiding) { - hideScrollbarH(); - hideScrollbarV(); - } - } - } - else if (scrollbarsVisibilityAuto) { - if (canScroll.x) - showScrollbarH(); - else - hideScrollbarH(); - - if (canScroll.y) - showScrollbarV(); - else - hideScrollbarV(); - } - else if (scrollbarsVisibilityVisible) { - showScrollbarH(); - showScrollbarV(); - } - else if (scrollbarsVisibilityHidden) { - hideScrollbarH(); - hideScrollbarV(); - } - } - - //manage the scrollbars auto hide feature (auto hide them after specific actions) - if (scrollbarsAutoHideChanged || ignoreOverlayScrollbarHidingChanged) { - if (_scrollbarsAutoHideLeave || _scrollbarsAutoHideMove) { - setupHostMouseTouchEvents(true); - setupHostMouseTouchEvents(); - } - else { - setupHostMouseTouchEvents(true); - } - - if (_scrollbarsAutoHideNever) - refreshScrollbarsAutoHide(true); - else - refreshScrollbarsAutoHide(false, true); - } - - //manage scrollbars handle length & offset - don't remove! - if (hostSizeChanged || overflowAmount.c || heightAutoChanged || widthAutoChanged || resizeChanged || boxSizingChanged || paddingAbsoluteChanged || ignoreOverlayScrollbarHidingChanged || cssDirectionChanged) { - refreshScrollbarHandleLength(true); - refreshScrollbarHandleOffset(true); - refreshScrollbarHandleLength(false); - refreshScrollbarHandleOffset(false); - } - - //manage interactivity - if (scrollbarsClickScrollingChanged) - refreshScrollbarsInteractive(true, scrollbarsClickScrolling); - if (scrollbarsDragScrollingChanged) - refreshScrollbarsInteractive(false, scrollbarsDragScrolling); - - //callbacks: - if (cssDirectionChanged) { - dispatchCallback('onDirectionChanged', { - isRTL: _isRTL, - dir: cssDirection - }); - } - if (hostSizeChanged) { - dispatchCallback('onHostSizeChanged', { - width: _hostSizeCache.w, - height: _hostSizeCache.h - }); - } - if (contentSizeChanged) { - dispatchCallback('onContentSizeChanged', { - width: _contentScrollSizeCache.w, - height: _contentScrollSizeCache.h - }); - } - if (hasOverflow.c || hideOverflow.c) { - dispatchCallback('onOverflowChanged', { - x: hasOverflow.x, - y: hasOverflow.y, - xScrollable: hideOverflow.xs, - yScrollable: hideOverflow.ys, - clipped: hideOverflow.x || hideOverflow.y - }); - } - if (overflowAmount.c) { - dispatchCallback('onOverflowAmountChanged', { - x: overflowAmount.x, - y: overflowAmount.y - }); - } - } - - //fix body min size - if (_isBody && _bodyMinSizeCache && (_hasOverflowCache.c || _bodyMinSizeCache.c)) { - //its possible that no min size was measured until now, because the content arrange element was just added now, in this case, measure now the min size. - if (!_bodyMinSizeCache.f) - bodyMinSizeChanged(); - if (_nativeScrollbarIsOverlaid.y && _hasOverflowCache.x) - _contentElement.css(_strMinMinus + _strWidth, _bodyMinSizeCache.w + _overlayScrollbarDummySize.y); - if (_nativeScrollbarIsOverlaid.x && _hasOverflowCache.y) - _contentElement.css(_strMinMinus + _strHeight, _bodyMinSizeCache.h + _overlayScrollbarDummySize.x); - _bodyMinSizeCache.c = false; - } - - //freezeResizeObserver(_sizeObserverElement, false); - //freezeResizeObserver(_sizeAutoObserverElement, false); - - dispatchCallback('onUpdated', { forced: force }); - } - - - //==== Options ====// - - /** - * Sets new options but doesn't call the update method. - * @param newOptions The object which contains the new options. - * @returns {*} A object which contains the changed options. - */ - function setOptions(newOptions) { - var validatedOpts = _pluginsOptions._validate(newOptions, _pluginsOptions._template, true, _currentOptions) - - _currentOptions = extendDeep({}, _currentOptions, validatedOpts._default); - _currentPreparedOptions = extendDeep({}, _currentPreparedOptions, validatedOpts._prepared); - - return validatedOpts._prepared; - } - - - //==== Structure ====// - - /** - * Builds or destroys the wrapper and helper DOM elements. - * @param destroy Indicates whether the DOM shall be build or destroyed. - */ - function setupStructureDOM(destroy) { - var strParent = 'parent'; - var classNameResizeObserverHost = 'os-resize-observer-host'; - var classNameTextareaElementFull = _classNameTextareaElement + _strSpace + _classNameTextInherit; - var textareaClass = _isTextarea ? _strSpace + _classNameTextInherit : _strEmpty; - var adoptAttrs = _currentPreparedOptions.textarea.inheritedAttrs; - var adoptAttrsMap = {}; - var applyAdoptedAttrs = function () { - var applyAdoptedAttrsElm = destroy ? _targetElement : _hostElement; - each(adoptAttrsMap, function (key, value) { - if (type(value) == TYPES.s) { - if (key == LEXICON.c) - applyAdoptedAttrsElm.addClass(value); - else - applyAdoptedAttrsElm.attr(key, value); - } - }); - }; - var hostElementClassNames = [ - _classNameHostElement, - _classNameHostTextareaElement, - _classNameHostResizeDisabled, - _classNameHostRTL, - _classNameHostScrollbarHorizontalHidden, - _classNameHostScrollbarVerticalHidden, - _classNameHostTransition, - _classNameHostScrolling, - _classNameHostOverflow, - _classNameHostOverflowX, - _classNameHostOverflowY, - _classNameThemeNone, - _classNameTextareaElement, - _classNameTextInherit, - _classNameCache].join(_strSpace); - var hostElementCSS = {}; - - //get host element as first element, because that's the most upper element and required for the other elements - _hostElement = _hostElement || (_isTextarea ? (_domExists ? _targetElement[strParent]()[strParent]()[strParent]()[strParent]() : FRAMEWORK(generateDiv(_classNameHostTextareaElement))) : _targetElement); - _contentElement = _contentElement || selectOrGenerateDivByClass(_classNameContentElement + textareaClass); - _viewportElement = _viewportElement || selectOrGenerateDivByClass(_classNameViewportElement + textareaClass); - _paddingElement = _paddingElement || selectOrGenerateDivByClass(_classNamePaddingElement + textareaClass); - _sizeObserverElement = _sizeObserverElement || selectOrGenerateDivByClass(classNameResizeObserverHost); - _textareaCoverElement = _textareaCoverElement || (_isTextarea ? selectOrGenerateDivByClass(_classNameTextareaCoverElement) : undefined); - - //on destroy, remove all generated class names from the host element before collecting the adopted attributes - //to prevent adopting generated class names - if (destroy) - removeClass(_hostElement, hostElementClassNames); - - //collect all adopted attributes - adoptAttrs = type(adoptAttrs) == TYPES.s ? adoptAttrs.split(_strSpace) : adoptAttrs; - if (type(adoptAttrs) == TYPES.a && _isTextarea) { - each(adoptAttrs, function (i, v) { - if (type(v) == TYPES.s) { - adoptAttrsMap[v] = destroy ? _hostElement.attr(v) : _targetElement.attr(v); - } - }); - } - - if (!destroy) { - if (_isTextarea) { - if (!_currentPreparedOptions.sizeAutoCapable) { - hostElementCSS[_strWidth] = _targetElement.css(_strWidth); - hostElementCSS[_strHeight] = _targetElement.css(_strHeight); - } - - if (!_domExists) - _targetElement.addClass(_classNameTextInherit).wrap(_hostElement); - - //jQuery clones elements in wrap functions, so we have to select them again - _hostElement = _targetElement[strParent]().css(hostElementCSS); - } - - if (!_domExists) { - //add the correct class to the target element - addClass(_targetElement, _isTextarea ? classNameTextareaElementFull : _classNameHostElement); - - //wrap the content into the generated elements to create the required DOM - _hostElement.wrapInner(_contentElement) - .wrapInner(_viewportElement) - .wrapInner(_paddingElement) - .prepend(_sizeObserverElement); - - //jQuery clones elements in wrap functions, so we have to select them again - _contentElement = findFirst(_hostElement, _strDot + _classNameContentElement); - _viewportElement = findFirst(_hostElement, _strDot + _classNameViewportElement); - _paddingElement = findFirst(_hostElement, _strDot + _classNamePaddingElement); - - if (_isTextarea) { - _contentElement.prepend(_textareaCoverElement); - applyAdoptedAttrs(); - } - } - - if (_nativeScrollbarStyling) - addClass(_viewportElement, _classNameViewportNativeScrollbarsInvisible); - if (_nativeScrollbarIsOverlaid.x && _nativeScrollbarIsOverlaid.y) - addClass(_viewportElement, _classNameViewportNativeScrollbarsOverlaid); - if (_isBody) - addClass(_htmlElement, _classNameHTMLElement); - - _sizeObserverElementNative = _sizeObserverElement[0]; - _hostElementNative = _hostElement[0]; - _paddingElementNative = _paddingElement[0]; - _viewportElementNative = _viewportElement[0]; - _contentElementNative = _contentElement[0]; - - updateViewportAttrsFromTarget(); - } - else { - if (_domExists && _initialized) { - //clear size observer - _sizeObserverElement.children().remove(); - - //remove the style property and classes from already generated elements - each([_paddingElement, _viewportElement, _contentElement, _textareaCoverElement], function (i, elm) { - if (elm) { - removeClass(elm.removeAttr(LEXICON.s), _classNamesDynamicDestroy); - } - }); - - //add classes to the host element which was removed previously to match the expected DOM - addClass(_hostElement, _isTextarea ? _classNameHostTextareaElement : _classNameHostElement); - } - else { - //remove size observer - remove(_sizeObserverElement); - - //unwrap the content to restore DOM - _contentElement.contents() - .unwrap() - .unwrap() - .unwrap(); - - if (_isTextarea) { - _targetElement.unwrap(); - remove(_hostElement); - remove(_textareaCoverElement); - applyAdoptedAttrs(); - } - } - - if (_isTextarea) - _targetElement.removeAttr(LEXICON.s); - - if (_isBody) - removeClass(_htmlElement, _classNameHTMLElement); - } - } - - /** - * Adds or removes all wrapper elements interactivity events. - * @param destroy Indicates whether the Events shall be added or removed. - */ - function setupStructureEvents() { - var textareaKeyDownRestrictedKeyCodes = [ - 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 123, //F1 to F12 - 33, 34, //page up, page down - 37, 38, 39, 40, //left, up, right, down arrows - 16, 17, 18, 19, 20, 144 //Shift, Ctrl, Alt, Pause, CapsLock, NumLock - ]; - var textareaKeyDownKeyCodesList = []; - var textareaUpdateIntervalID; - var scrollStopTimeoutId; - var scrollStopDelay = 175; - var strFocus = 'focus'; - - function updateTextarea(doClearInterval) { - textareaUpdate(); - _base.update(_strAuto); - if (doClearInterval && _autoUpdateRecommended) - clearInterval(textareaUpdateIntervalID); - } - function textareaOnScroll(event) { - _targetElement[_strScrollLeft](_rtlScrollBehavior.i && _normalizeRTLCache ? 9999999 : 0); - _targetElement[_strScrollTop](0); - COMPATIBILITY.prvD(event); - COMPATIBILITY.stpP(event); - return false; - } - function textareaOnDrop(event) { - setTimeout(function () { - if (!_destroyed) - updateTextarea(); - }, 50); - } - function textareaOnFocus() { - _textareaHasFocus = true; - addClass(_hostElement, strFocus); - } - function textareaOnFocusout() { - _textareaHasFocus = false; - textareaKeyDownKeyCodesList = []; - removeClass(_hostElement, strFocus); - updateTextarea(true); - } - function textareaOnKeyDown(event) { - var keyCode = event.keyCode; - - if (inArray(keyCode, textareaKeyDownRestrictedKeyCodes) < 0) { - if (!textareaKeyDownKeyCodesList[LEXICON.l]) { - updateTextarea(); - textareaUpdateIntervalID = setInterval(updateTextarea, 1000 / 60); - } - if (inArray(keyCode, textareaKeyDownKeyCodesList) < 0) - textareaKeyDownKeyCodesList.push(keyCode); - } - } - function textareaOnKeyUp(event) { - var keyCode = event.keyCode; - var index = inArray(keyCode, textareaKeyDownKeyCodesList); - - if (inArray(keyCode, textareaKeyDownRestrictedKeyCodes) < 0) { - if (index > -1) - textareaKeyDownKeyCodesList.splice(index, 1); - if (!textareaKeyDownKeyCodesList[LEXICON.l]) - updateTextarea(true); - } - } - function contentOnTransitionEnd(event) { - if (_autoUpdateCache === true) - return; - event = event.originalEvent || event; - if (isSizeAffectingCSSProperty(event.propertyName)) - _base.update(_strAuto); - } - function viewportOnScroll(event) { - if (!_sleeping) { - if (scrollStopTimeoutId !== undefined) - clearTimeout(scrollStopTimeoutId); - else { - if (_scrollbarsAutoHideScroll || _scrollbarsAutoHideMove) - refreshScrollbarsAutoHide(true); - - if (!nativeOverlayScrollbarsAreActive()) - addClass(_hostElement, _classNameHostScrolling); - - dispatchCallback('onScrollStart', event); - } - - //if a scrollbars handle gets dragged, the mousemove event is responsible for refreshing the handle offset - //because if CSS scroll-snap is used, the handle offset gets only refreshed on every snap point - //this looks laggy & clunky, it looks much better if the offset refreshes with the mousemove - if (!_scrollbarsHandlesDefineScrollPos) { - refreshScrollbarHandleOffset(true); - refreshScrollbarHandleOffset(false); - } - dispatchCallback('onScroll', event); - - scrollStopTimeoutId = setTimeout(function () { - if (!_destroyed) { - //OnScrollStop: - clearTimeout(scrollStopTimeoutId); - scrollStopTimeoutId = undefined; - - if (_scrollbarsAutoHideScroll || _scrollbarsAutoHideMove) - refreshScrollbarsAutoHide(false); - - if (!nativeOverlayScrollbarsAreActive()) - removeClass(_hostElement, _classNameHostScrolling); - - dispatchCallback('onScrollStop', event); - } - }, scrollStopDelay); - } - } - - - if (_isTextarea) { - if (_msieVersion > 9 || !_autoUpdateRecommended) { - addDestroyEventListener(_targetElement, 'input', updateTextarea); - } - else { - addDestroyEventListener(_targetElement, - [_strKeyDownEvent, _strKeyUpEvent], - [textareaOnKeyDown, textareaOnKeyUp]); - } - - addDestroyEventListener(_targetElement, - [_strScroll, 'drop', strFocus, strFocus + 'out'], - [textareaOnScroll, textareaOnDrop, textareaOnFocus, textareaOnFocusout]); - } - else { - addDestroyEventListener(_contentElement, _strTransitionEndEvent, contentOnTransitionEnd); - } - addDestroyEventListener(_viewportElement, _strScroll, viewportOnScroll, true); - } - - - //==== Scrollbars ====// - - /** - * Builds or destroys all scrollbar DOM elements (scrollbar, track, handle) - * @param destroy Indicates whether the DOM shall be build or destroyed. - */ - function setupScrollbarsDOM(destroy) { - var selectOrGenerateScrollbarDOM = function (isHorizontal) { - var scrollbarClassName = isHorizontal ? _classNameScrollbarHorizontal : _classNameScrollbarVertical; - var scrollbar = selectOrGenerateDivByClass(_classNameScrollbar + _strSpace + scrollbarClassName, true); - var track = selectOrGenerateDivByClass(_classNameScrollbarTrack, scrollbar); - var handle = selectOrGenerateDivByClass(_classNameScrollbarHandle, scrollbar); - - if (!_domExists && !destroy) { - scrollbar.append(track); - track.append(handle); - } - - return { - _scrollbar: scrollbar, - _track: track, - _handle: handle - }; - }; - function resetScrollbarDOM(isHorizontal) { - var scrollbarVars = getScrollbarVars(isHorizontal); - var scrollbar = scrollbarVars._scrollbar; - var track = scrollbarVars._track; - var handle = scrollbarVars._handle; - - if (_domExists && _initialized) { - each([scrollbar, track, handle], function (i, elm) { - removeClass(elm.removeAttr(LEXICON.s), _classNamesDynamicDestroy); - }); - } - else { - remove(scrollbar || selectOrGenerateScrollbarDOM(isHorizontal)._scrollbar); - } - } - var horizontalElements; - var verticalElements; - - if (!destroy) { - horizontalElements = selectOrGenerateScrollbarDOM(true); - verticalElements = selectOrGenerateScrollbarDOM(); - - _scrollbarHorizontalElement = horizontalElements._scrollbar; - _scrollbarHorizontalTrackElement = horizontalElements._track; - _scrollbarHorizontalHandleElement = horizontalElements._handle; - _scrollbarVerticalElement = verticalElements._scrollbar; - _scrollbarVerticalTrackElement = verticalElements._track; - _scrollbarVerticalHandleElement = verticalElements._handle; - - if (!_domExists) { - _paddingElement.after(_scrollbarVerticalElement); - _paddingElement.after(_scrollbarHorizontalElement); - } - } - else { - resetScrollbarDOM(true); - resetScrollbarDOM(); - } - } - - /** - * Initializes all scrollbar interactivity events. (track and handle dragging, clicking, scrolling) - * @param isHorizontal True if the target scrollbar is the horizontal scrollbar, false if the target scrollbar is the vertical scrollbar. - */ - function setupScrollbarEvents(isHorizontal) { - var scrollbarVars = getScrollbarVars(isHorizontal); - var scrollbarVarsInfo = scrollbarVars._info; - var insideIFrame = _windowElementNative.top !== _windowElementNative; - var xy = scrollbarVars._x_y; - var XY = scrollbarVars._X_Y; - var scroll = _strScroll + scrollbarVars._Left_Top; - var strActive = 'active'; - var strSnapHandle = 'snapHandle'; - var scrollDurationFactor = 1; - var increaseDecreaseScrollAmountKeyCodes = [16, 17]; //shift, ctrl - var trackTimeout; - var mouseDownScroll; - var mouseDownOffset; - var mouseDownInvertedScale; - - function getPointerPosition(event) { - return _msieVersion && insideIFrame ? event['screen' + XY] : COMPATIBILITY.page(event)[xy]; //use screen coordinates in EDGE & IE because the page values are incorrect in frames. - } - function getPreparedScrollbarsOption(name) { - return _currentPreparedOptions.scrollbars[name]; - } - function increaseTrackScrollAmount() { - scrollDurationFactor = 0.5; - } - function decreaseTrackScrollAmount() { - scrollDurationFactor = 1; - } - function documentKeyDown(event) { - if (inArray(event.keyCode, increaseDecreaseScrollAmountKeyCodes) > -1) - increaseTrackScrollAmount(); - } - function documentKeyUp(event) { - if (inArray(event.keyCode, increaseDecreaseScrollAmountKeyCodes) > -1) - decreaseTrackScrollAmount(); - } - function onMouseTouchDownContinue(event) { - var originalEvent = event.originalEvent || event; - var isTouchEvent = originalEvent.touches !== undefined; - return _sleeping || _destroyed || nativeOverlayScrollbarsAreActive() || !_scrollbarsDragScrollingCache || (isTouchEvent && !getPreparedScrollbarsOption('touchSupport')) ? false : COMPATIBILITY.mBtn(event) === 1 || isTouchEvent; - } - function documentDragMove(event) { - if (onMouseTouchDownContinue(event)) { - var trackLength = scrollbarVarsInfo._trackLength; - var handleLength = scrollbarVarsInfo._handleLength; - var scrollRange = scrollbarVarsInfo._maxScroll; - var scrollRaw = (getPointerPosition(event) - mouseDownOffset) * mouseDownInvertedScale; - var scrollDeltaPercent = scrollRaw / (trackLength - handleLength); - var scrollDelta = (scrollRange * scrollDeltaPercent); - scrollDelta = isFinite(scrollDelta) ? scrollDelta : 0; - if (_isRTL && isHorizontal && !_rtlScrollBehavior.i) - scrollDelta *= -1; - - _viewportElement[scroll](MATH.round(mouseDownScroll + scrollDelta)); - - if (_scrollbarsHandlesDefineScrollPos) - refreshScrollbarHandleOffset(isHorizontal, mouseDownScroll + scrollDelta); - - if (!_supportPassiveEvents) - COMPATIBILITY.prvD(event); - } - else - documentMouseTouchUp(event); - } - function documentMouseTouchUp(event) { - event = event || event.originalEvent; - - setupResponsiveEventListener(_documentElement, - [_strMouseTouchMoveEvent, _strMouseTouchUpEvent, _strKeyDownEvent, _strKeyUpEvent, _strSelectStartEvent], - [documentDragMove, documentMouseTouchUp, documentKeyDown, documentKeyUp, documentOnSelectStart], - true); - - if (_scrollbarsHandlesDefineScrollPos) - refreshScrollbarHandleOffset(isHorizontal, true); - - _scrollbarsHandlesDefineScrollPos = false; - removeClass(_bodyElement, _classNameDragging); - removeClass(scrollbarVars._handle, strActive); - removeClass(scrollbarVars._track, strActive); - removeClass(scrollbarVars._scrollbar, strActive); - - mouseDownScroll = undefined; - mouseDownOffset = undefined; - mouseDownInvertedScale = 1; - - decreaseTrackScrollAmount(); - - if (trackTimeout !== undefined) { - _base.scrollStop(); - clearTimeout(trackTimeout); - trackTimeout = undefined; - } - - if (event) { - var rect = _hostElementNative[LEXICON.bCR](); - var mouseInsideHost = event.clientX >= rect.left && event.clientX <= rect.right && event.clientY >= rect.top && event.clientY <= rect.bottom; - - //if mouse is outside host element - if (!mouseInsideHost) - hostOnMouseLeave(); - - if (_scrollbarsAutoHideScroll || _scrollbarsAutoHideMove) - refreshScrollbarsAutoHide(false); - } - } - function onHandleMouseTouchDown(event) { - if (onMouseTouchDownContinue(event)) - onHandleMouseTouchDownAction(event); - } - function onHandleMouseTouchDownAction(event) { - mouseDownScroll = _viewportElement[scroll](); - mouseDownScroll = isNaN(mouseDownScroll) ? 0 : mouseDownScroll; - if (_isRTL && isHorizontal && !_rtlScrollBehavior.n || !_isRTL) - mouseDownScroll = mouseDownScroll < 0 ? 0 : mouseDownScroll; - - mouseDownInvertedScale = getHostElementInvertedScale()[xy]; - mouseDownOffset = getPointerPosition(event); - - _scrollbarsHandlesDefineScrollPos = !getPreparedScrollbarsOption(strSnapHandle); - addClass(_bodyElement, _classNameDragging); - addClass(scrollbarVars._handle, strActive); - addClass(scrollbarVars._scrollbar, strActive); - - setupResponsiveEventListener(_documentElement, - [_strMouseTouchMoveEvent, _strMouseTouchUpEvent, _strSelectStartEvent], - [documentDragMove, documentMouseTouchUp, documentOnSelectStart]); - - if (_msieVersion || !_documentMixed) - COMPATIBILITY.prvD(event); - COMPATIBILITY.stpP(event); - } - function onTrackMouseTouchDown(event) { - if (onMouseTouchDownContinue(event)) { - var scrollDistance = MATH.round(_viewportSize[scrollbarVars._w_h]); - var trackOffset = scrollbarVars._track.offset()[scrollbarVars._left_top]; - var ctrlKey = event.ctrlKey; - var instantScroll = event.shiftKey; - var instantScrollTransition = instantScroll && ctrlKey; - var isFirstIteration = true; - var easing = 'linear'; - var decreaseScroll; - var finishedCondition; - var scrollActionFinsished = function (transition) { - if (_scrollbarsHandlesDefineScrollPos) - refreshScrollbarHandleOffset(isHorizontal, transition); - }; - var scrollActionInstantFinished = function () { - scrollActionFinsished(); - onHandleMouseTouchDownAction(event); - }; - var scrollAction = function () { - if (!_destroyed) { - var mouseOffset = (mouseDownOffset - trackOffset) * mouseDownInvertedScale; - var handleOffset = scrollbarVarsInfo._handleOffset; - var trackLength = scrollbarVarsInfo._trackLength; - var handleLength = scrollbarVarsInfo._handleLength; - var scrollRange = scrollbarVarsInfo._maxScroll; - var currScroll = scrollbarVarsInfo._currentScroll; - var scrollDuration = 270 * scrollDurationFactor; - var timeoutDelay = isFirstIteration ? MATH.max(400, scrollDuration) : scrollDuration; - var instantScrollPosition = scrollRange * ((mouseOffset - (handleLength / 2)) / (trackLength - handleLength)); // 100% * positionPercent - var rtlIsNormal = _isRTL && isHorizontal && ((!_rtlScrollBehavior.i && !_rtlScrollBehavior.n) || _normalizeRTLCache); - var decreaseScrollCondition = rtlIsNormal ? handleOffset < mouseOffset : handleOffset > mouseOffset; - var scrollObj = {}; - var animationObj = { - easing: easing, - step: function (now) { - if (_scrollbarsHandlesDefineScrollPos) { - _viewportElement[scroll](now); //https://github.com/jquery/jquery/issues/4340 - refreshScrollbarHandleOffset(isHorizontal, now); - } - } - }; - instantScrollPosition = isFinite(instantScrollPosition) ? instantScrollPosition : 0; - instantScrollPosition = _isRTL && isHorizontal && !_rtlScrollBehavior.i ? (scrollRange - instantScrollPosition) : instantScrollPosition; - - //_base.scrollStop(); - - if (instantScroll) { - _viewportElement[scroll](instantScrollPosition); //scroll instantly to new position - if (instantScrollTransition) { - //get the scroll position after instant scroll (in case CSS Snap Points are used) to get the correct snapped scroll position - //and the animation stops at the correct point - instantScrollPosition = _viewportElement[scroll](); - //scroll back to the position before instant scrolling so animation can be performed - _viewportElement[scroll](currScroll); - - instantScrollPosition = rtlIsNormal && _rtlScrollBehavior.i ? (scrollRange - instantScrollPosition) : instantScrollPosition; - instantScrollPosition = rtlIsNormal && _rtlScrollBehavior.n ? -instantScrollPosition : instantScrollPosition; - - scrollObj[xy] = instantScrollPosition; - _base.scroll(scrollObj, extendDeep(animationObj, { - duration: 130, - complete: scrollActionInstantFinished - })); - } - else - scrollActionInstantFinished(); - } - else { - decreaseScroll = isFirstIteration ? decreaseScrollCondition : decreaseScroll; - finishedCondition = rtlIsNormal - ? (decreaseScroll ? handleOffset + handleLength >= mouseOffset : handleOffset <= mouseOffset) - : (decreaseScroll ? handleOffset <= mouseOffset : handleOffset + handleLength >= mouseOffset); - - if (finishedCondition) { - clearTimeout(trackTimeout); - _base.scrollStop(); - trackTimeout = undefined; - scrollActionFinsished(true); - } - else { - trackTimeout = setTimeout(scrollAction, timeoutDelay); - - scrollObj[xy] = (decreaseScroll ? '-=' : '+=') + scrollDistance; - _base.scroll(scrollObj, extendDeep(animationObj, { - duration: scrollDuration - })); - } - isFirstIteration = false; - } - } - }; - if (ctrlKey) - increaseTrackScrollAmount(); - - mouseDownInvertedScale = getHostElementInvertedScale()[xy]; - mouseDownOffset = COMPATIBILITY.page(event)[xy]; - - _scrollbarsHandlesDefineScrollPos = !getPreparedScrollbarsOption(strSnapHandle); - addClass(_bodyElement, _classNameDragging); - addClass(scrollbarVars._track, strActive); - addClass(scrollbarVars._scrollbar, strActive); - - setupResponsiveEventListener(_documentElement, - [_strMouseTouchUpEvent, _strKeyDownEvent, _strKeyUpEvent, _strSelectStartEvent], - [documentMouseTouchUp, documentKeyDown, documentKeyUp, documentOnSelectStart]); - - scrollAction(); - COMPATIBILITY.prvD(event); - COMPATIBILITY.stpP(event); - } - } - function onTrackMouseTouchEnter(event) { - //make sure both scrollbars will stay visible if one scrollbar is hovered if autoHide is "scroll" or "move". - _scrollbarsHandleHovered = true; - if (_scrollbarsAutoHideScroll || _scrollbarsAutoHideMove) - refreshScrollbarsAutoHide(true); - } - function onTrackMouseTouchLeave(event) { - _scrollbarsHandleHovered = false; - if (_scrollbarsAutoHideScroll || _scrollbarsAutoHideMove) - refreshScrollbarsAutoHide(false); - } - function onScrollbarMouseTouchDown(event) { - COMPATIBILITY.stpP(event); - } - - addDestroyEventListener(scrollbarVars._handle, - _strMouseTouchDownEvent, - onHandleMouseTouchDown); - addDestroyEventListener(scrollbarVars._track, - [_strMouseTouchDownEvent, _strMouseTouchEnter, _strMouseTouchLeave], - [onTrackMouseTouchDown, onTrackMouseTouchEnter, onTrackMouseTouchLeave]); - addDestroyEventListener(scrollbarVars._scrollbar, - _strMouseTouchDownEvent, - onScrollbarMouseTouchDown); - - if (_supportTransition) { - addDestroyEventListener(scrollbarVars._scrollbar, _strTransitionEndEvent, function (event) { - if (event.target !== scrollbarVars._scrollbar[0]) - return; - refreshScrollbarHandleLength(isHorizontal); - refreshScrollbarHandleOffset(isHorizontal); - }); - } - } - - /** - * Shows or hides the given scrollbar and applied a class name which indicates if the scrollbar is scrollable or not. - * @param isHorizontal True if the horizontal scrollbar is the target, false if the vertical scrollbar is the target. - * @param shallBeVisible True if the scrollbar shall be shown, false if hidden. - * @param canScroll True if the scrollbar is scrollable, false otherwise. - */ - function refreshScrollbarAppearance(isHorizontal, shallBeVisible, canScroll) { - var scrollbarClassName = isHorizontal ? _classNameHostScrollbarHorizontalHidden : _classNameHostScrollbarVerticalHidden; - var scrollbarElement = isHorizontal ? _scrollbarHorizontalElement : _scrollbarVerticalElement; - - if (shallBeVisible) - removeClass(_hostElement, scrollbarClassName); - else - addClass(_hostElement, scrollbarClassName); - - if (canScroll) - removeClass(scrollbarElement, _classNameScrollbarUnusable); - else - addClass(scrollbarElement, _classNameScrollbarUnusable); - } - - /** - * Autoshows / autohides both scrollbars with. - * @param shallBeVisible True if the scrollbars shall be autoshown (only the case if they are hidden by a autohide), false if the shall be auto hidden. - * @param delayfree True if the scrollbars shall be hidden without a delay, false or undefined otherwise. - */ - function refreshScrollbarsAutoHide(shallBeVisible, delayfree) { - clearTimeout(_scrollbarsAutoHideTimeoutId); - if (shallBeVisible) { - //if(_hasOverflowCache.x && _hideOverflowCache.xs) - removeClass(_scrollbarHorizontalElement, _classNameScrollbarAutoHidden); - //if(_hasOverflowCache.y && _hideOverflowCache.ys) - removeClass(_scrollbarVerticalElement, _classNameScrollbarAutoHidden); - } - else { - var anyActive; - var strActive = 'active'; - var hide = function () { - if (!_scrollbarsHandleHovered && !_destroyed) { - anyActive = _scrollbarHorizontalHandleElement.hasClass(strActive) || _scrollbarVerticalHandleElement.hasClass(strActive); - if (!anyActive && (_scrollbarsAutoHideScroll || _scrollbarsAutoHideMove || _scrollbarsAutoHideLeave)) - addClass(_scrollbarHorizontalElement, _classNameScrollbarAutoHidden); - if (!anyActive && (_scrollbarsAutoHideScroll || _scrollbarsAutoHideMove || _scrollbarsAutoHideLeave)) - addClass(_scrollbarVerticalElement, _classNameScrollbarAutoHidden); - } - }; - if (_scrollbarsAutoHideDelay > 0 && delayfree !== true) - _scrollbarsAutoHideTimeoutId = setTimeout(hide, _scrollbarsAutoHideDelay); - else - hide(); - } - } - - /** - * Refreshes the handle length of the given scrollbar. - * @param isHorizontal True if the horizontal scrollbar handle shall be refreshed, false if the vertical one shall be refreshed. - */ - function refreshScrollbarHandleLength(isHorizontal) { - var handleCSS = {}; - var scrollbarVars = getScrollbarVars(isHorizontal); - var scrollbarVarsInfo = scrollbarVars._info; - var digit = 1000000; - //get and apply intended handle length - var handleRatio = MATH.min(1, (_hostSizeCache[scrollbarVars._w_h] - (_paddingAbsoluteCache ? (isHorizontal ? _paddingX : _paddingY) : 0)) / _contentScrollSizeCache[scrollbarVars._w_h]); - handleCSS[scrollbarVars._width_height] = (MATH.floor(handleRatio * 100 * digit) / digit) + '%'; //the last * digit / digit is for flooring to the 4th digit - - if (!nativeOverlayScrollbarsAreActive()) - scrollbarVars._handle.css(handleCSS); - - //measure the handle length to respect min & max length - scrollbarVarsInfo._handleLength = scrollbarVars._handle[0]['offset' + scrollbarVars._Width_Height]; - scrollbarVarsInfo._handleLengthRatio = handleRatio; - } - - /** - * Refreshes the handle offset of the given scrollbar. - * @param isHorizontal True if the horizontal scrollbar handle shall be refreshed, false if the vertical one shall be refreshed. - * @param scrollOrTransition The scroll position of the given scrollbar axis to which the handle shall be moved or a boolean which indicates whether a transition shall be applied. If undefined or boolean if the current scroll-offset is taken. (if isHorizontal ? scrollLeft : scrollTop) - */ - function refreshScrollbarHandleOffset(isHorizontal, scrollOrTransition) { - var transition = type(scrollOrTransition) == TYPES.b; - var transitionDuration = 250; - var isRTLisHorizontal = _isRTL && isHorizontal; - var scrollbarVars = getScrollbarVars(isHorizontal); - var scrollbarVarsInfo = scrollbarVars._info; - var strTranslateBrace = 'translate('; - var strTransform = VENDORS._cssProperty('transform'); - var strTransition = VENDORS._cssProperty('transition'); - var nativeScroll = isHorizontal ? _viewportElement[_strScrollLeft]() : _viewportElement[_strScrollTop](); - var currentScroll = scrollOrTransition === undefined || transition ? nativeScroll : scrollOrTransition; - - //measure the handle length to respect min & max length - var handleLength = scrollbarVarsInfo._handleLength; - var trackLength = scrollbarVars._track[0]['offset' + scrollbarVars._Width_Height]; - var handleTrackDiff = trackLength - handleLength; - var handleCSS = {}; - var transformOffset; - var translateValue; - - //DONT use the variable '_contentScrollSizeCache[scrollbarVars._w_h]' instead of '_viewportElement[0]['scroll' + scrollbarVars._Width_Height]' - // because its a bit behind during the small delay when content size updates - //(delay = mutationObserverContentLag, if its 0 then this var could be used) - var maxScroll = (_viewportElementNative[_strScroll + scrollbarVars._Width_Height] - _viewportElementNative['client' + scrollbarVars._Width_Height]) * (_rtlScrollBehavior.n && isRTLisHorizontal ? -1 : 1); //* -1 if rtl scroll max is negative - var getScrollRatio = function (base) { - return isNaN(base / maxScroll) ? 0 : MATH.max(0, MATH.min(1, base / maxScroll)); - }; - var getHandleOffset = function (scrollRatio) { - var offset = handleTrackDiff * scrollRatio; - offset = isNaN(offset) ? 0 : offset; - offset = (isRTLisHorizontal && !_rtlScrollBehavior.i) ? (trackLength - handleLength - offset) : offset; - offset = MATH.max(0, offset); - return offset; - }; - var scrollRatio = getScrollRatio(nativeScroll); - var unsnappedScrollRatio = getScrollRatio(currentScroll); - var handleOffset = getHandleOffset(unsnappedScrollRatio); - var snappedHandleOffset = getHandleOffset(scrollRatio); - - scrollbarVarsInfo._maxScroll = maxScroll; - scrollbarVarsInfo._currentScroll = nativeScroll; - scrollbarVarsInfo._currentScrollRatio = scrollRatio; - - if (_supportTransform) { - transformOffset = isRTLisHorizontal ? -(trackLength - handleLength - handleOffset) : handleOffset; //in px - //transformOffset = (transformOffset / trackLength * 100) * (trackLength / handleLength); //in % - translateValue = isHorizontal ? strTranslateBrace + transformOffset + 'px, 0)' : strTranslateBrace + '0, ' + transformOffset + 'px)'; - - handleCSS[strTransform] = translateValue; - - //apply or clear up transition - if (_supportTransition) - handleCSS[strTransition] = transition && MATH.abs(handleOffset - scrollbarVarsInfo._handleOffset) > 1 ? getCSSTransitionString(scrollbarVars._handle) + ', ' + (strTransform + _strSpace + transitionDuration + 'ms') : _strEmpty; - } - else - handleCSS[scrollbarVars._left_top] = handleOffset; - - - //only apply css if offset has changed and overflow exists. - if (!nativeOverlayScrollbarsAreActive()) { - scrollbarVars._handle.css(handleCSS); - - //clear up transition - if (_supportTransform && _supportTransition && transition) { - scrollbarVars._handle.one(_strTransitionEndEvent, function () { - if (!_destroyed) - scrollbarVars._handle.css(strTransition, _strEmpty); - }); - } - } - - scrollbarVarsInfo._handleOffset = handleOffset; - scrollbarVarsInfo._snappedHandleOffset = snappedHandleOffset; - scrollbarVarsInfo._trackLength = trackLength; - } - - /** - * Refreshes the interactivity of the given scrollbar element. - * @param isTrack True if the track element is the target, false if the handle element is the target. - * @param value True for interactivity false for no interactivity. - */ - function refreshScrollbarsInteractive(isTrack, value) { - var action = value ? 'removeClass' : 'addClass'; - var element1 = isTrack ? _scrollbarHorizontalTrackElement : _scrollbarHorizontalHandleElement; - var element2 = isTrack ? _scrollbarVerticalTrackElement : _scrollbarVerticalHandleElement; - var className = isTrack ? _classNameScrollbarTrackOff : _classNameScrollbarHandleOff; - - element1[action](className); - element2[action](className); - } - - /** - * Returns a object which is used for fast access for specific variables. - * @param isHorizontal True if the horizontal scrollbar vars shall be accessed, false if the vertical scrollbar vars shall be accessed. - * @returns {{wh: string, WH: string, lt: string, _wh: string, _lt: string, t: *, h: *, c: {}, s: *}} - */ - function getScrollbarVars(isHorizontal) { - return { - _width_height: isHorizontal ? _strWidth : _strHeight, - _Width_Height: isHorizontal ? 'Width' : 'Height', - _left_top: isHorizontal ? _strLeft : _strTop, - _Left_Top: isHorizontal ? 'Left' : 'Top', - _x_y: isHorizontal ? _strX : _strY, - _X_Y: isHorizontal ? 'X' : 'Y', - _w_h: isHorizontal ? 'w' : 'h', - _l_t: isHorizontal ? 'l' : 't', - _track: isHorizontal ? _scrollbarHorizontalTrackElement : _scrollbarVerticalTrackElement, - _handle: isHorizontal ? _scrollbarHorizontalHandleElement : _scrollbarVerticalHandleElement, - _scrollbar: isHorizontal ? _scrollbarHorizontalElement : _scrollbarVerticalElement, - _info: isHorizontal ? _scrollHorizontalInfo : _scrollVerticalInfo - }; - } - - - //==== Scrollbar Corner ====// - - /** - * Builds or destroys the scrollbar corner DOM element. - * @param destroy Indicates whether the DOM shall be build or destroyed. - */ - function setupScrollbarCornerDOM(destroy) { - _scrollbarCornerElement = _scrollbarCornerElement || selectOrGenerateDivByClass(_classNameScrollbarCorner, true); - - if (!destroy) { - if (!_domExists) { - _hostElement.append(_scrollbarCornerElement); - } - } - else { - if (_domExists && _initialized) { - removeClass(_scrollbarCornerElement.removeAttr(LEXICON.s), _classNamesDynamicDestroy); - } - else { - remove(_scrollbarCornerElement); - } - } - } - - /** - * Initializes all scrollbar corner interactivity events. - */ - function setupScrollbarCornerEvents() { - var insideIFrame = _windowElementNative.top !== _windowElementNative; - var mouseDownPosition = {}; - var mouseDownSize = {}; - var mouseDownInvertedScale = {}; - var reconnectMutationObserver; - - function documentDragMove(event) { - if (onMouseTouchDownContinue(event)) { - var pageOffset = getCoordinates(event); - var hostElementCSS = {}; - if (_resizeHorizontal || _resizeBoth) - hostElementCSS[_strWidth] = (mouseDownSize.w + (pageOffset.x - mouseDownPosition.x) * mouseDownInvertedScale.x); - if (_resizeVertical || _resizeBoth) - hostElementCSS[_strHeight] = (mouseDownSize.h + (pageOffset.y - mouseDownPosition.y) * mouseDownInvertedScale.y); - _hostElement.css(hostElementCSS); - COMPATIBILITY.stpP(event); - } - else { - documentMouseTouchUp(event); - } - } - function documentMouseTouchUp(event) { - var eventIsTrusted = event !== undefined; - - setupResponsiveEventListener(_documentElement, - [_strSelectStartEvent, _strMouseTouchMoveEvent, _strMouseTouchUpEvent], - [documentOnSelectStart, documentDragMove, documentMouseTouchUp], - true); - - removeClass(_bodyElement, _classNameDragging); - if (_scrollbarCornerElement.releaseCapture) - _scrollbarCornerElement.releaseCapture(); - - if (eventIsTrusted) { - if (reconnectMutationObserver) - connectMutationObservers(); - _base.update(_strAuto); - } - reconnectMutationObserver = false; - } - function onMouseTouchDownContinue(event) { - var originalEvent = event.originalEvent || event; - var isTouchEvent = originalEvent.touches !== undefined; - return _sleeping || _destroyed ? false : COMPATIBILITY.mBtn(event) === 1 || isTouchEvent; - } - function getCoordinates(event) { - return _msieVersion && insideIFrame ? { x: event.screenX, y: event.screenY } : COMPATIBILITY.page(event); - } - - addDestroyEventListener(_scrollbarCornerElement, _strMouseTouchDownEvent, function (event) { - if (onMouseTouchDownContinue(event) && !_resizeNone) { - if (_mutationObserversConnected) { - reconnectMutationObserver = true; - disconnectMutationObservers(); - } - - mouseDownPosition = getCoordinates(event); - - mouseDownSize.w = _hostElementNative[LEXICON.oW] - (!_isBorderBox ? _paddingX : 0); - mouseDownSize.h = _hostElementNative[LEXICON.oH] - (!_isBorderBox ? _paddingY : 0); - mouseDownInvertedScale = getHostElementInvertedScale(); - - setupResponsiveEventListener(_documentElement, - [_strSelectStartEvent, _strMouseTouchMoveEvent, _strMouseTouchUpEvent], - [documentOnSelectStart, documentDragMove, documentMouseTouchUp]); - - addClass(_bodyElement, _classNameDragging); - if (_scrollbarCornerElement.setCapture) - _scrollbarCornerElement.setCapture(); - - COMPATIBILITY.prvD(event); - COMPATIBILITY.stpP(event); - } - }); - } - - - //==== Utils ====// - - /** - * Calls the callback with the given name. The Context of this callback is always _base (this). - * @param name The name of the target which shall be called. - * @param args The args with which the callback shall be called. - */ - function dispatchCallback(name, args) { - if (_initialized) { - var callback = _currentPreparedOptions.callbacks[name]; - var extensionOnName = name; - var ext; - - if (extensionOnName.substr(0, 2) === 'on') - extensionOnName = extensionOnName.substr(2, 1).toLowerCase() + extensionOnName.substr(3); - - if (type(callback) == TYPES.f) - callback.call(_base, args); - - each(_extensions, function () { - ext = this; - if (type(ext.on) == TYPES.f) - ext.on(extensionOnName, args); - }); - } - else if (!_destroyed) - _callbacksInitQeueue.push({ n: name, a: args }); - } - - /** - * Sets the "top, right, bottom, left" properties, with a given prefix, of the given css object. - * @param targetCSSObject The css object to which the values shall be applied. - * @param prefix The prefix of the "top, right, bottom, left" css properties. (example: 'padding-' is a valid prefix) - * @param values A array of values which shall be applied to the "top, right, bottom, left" -properties. The array order is [top, right, bottom, left]. - * If this argument is undefined the value '' (empty string) will be applied to all properties. - */ - function setTopRightBottomLeft(targetCSSObject, prefix, values) { - if (values === undefined) - values = [_strEmpty, _strEmpty, _strEmpty, _strEmpty]; - - targetCSSObject[prefix + _strTop] = values[0]; - targetCSSObject[prefix + _strRight] = values[1]; - targetCSSObject[prefix + _strBottom] = values[2]; - targetCSSObject[prefix + _strLeft] = values[3]; - } - - /** - * Returns the computed CSS transition string from the given element. - * @param element The element from which the transition string shall be returned. - * @returns {string} The CSS transition string from the given element. - */ - function getCSSTransitionString(element) { - var transitionStr = VENDORS._cssProperty('transition'); - var assembledValue = element.css(transitionStr); - if (assembledValue) - return assembledValue; - var regExpString = '\\s*(' + '([^,(]+(\\(.+?\\))?)+' + ')[\\s,]*'; - var regExpMain = new RegExp(regExpString); - var regExpValidate = new RegExp('^(' + regExpString + ')+$'); - var properties = 'property duration timing-function delay'.split(' '); - var result = []; - var strResult; - var valueArray; - var i = 0; - var j; - var splitCssStyleByComma = function (str) { - strResult = []; - if (!str.match(regExpValidate)) - return str; - while (str.match(regExpMain)) { - strResult.push(RegExp.$1); - str = str.replace(regExpMain, _strEmpty); - } - - return strResult; - }; - for (; i < properties[LEXICON.l]; i++) { - valueArray = splitCssStyleByComma(element.css(transitionStr + '-' + properties[i])); - for (j = 0; j < valueArray[LEXICON.l]; j++) - result[j] = (result[j] ? result[j] + _strSpace : _strEmpty) + valueArray[j]; - } - return result.join(', '); - } - - /** - * Calculates the host-elements inverted scale. (invertedScale = 1 / scale) - * @returns {{x: number, y: number}} The scale of the host-element. - */ - function getHostElementInvertedScale() { - var rect = _paddingElementNative[LEXICON.bCR](); - return { - x: _supportTransform ? 1 / (MATH.round(rect.width) / _paddingElementNative[LEXICON.oW]) || 1 : 1, - y: _supportTransform ? 1 / (MATH.round(rect.height) / _paddingElementNative[LEXICON.oH]) || 1 : 1 - }; - } - - /** - * Checks whether the given object is a HTMLElement. - * @param o The object which shall be checked. - * @returns {boolean} True the given object is a HTMLElement, false otherwise. - */ - function isHTMLElement(o) { - var strOwnerDocument = 'ownerDocument'; - var strHTMLElement = 'HTMLElement'; - var wnd = o && o[strOwnerDocument] ? (o[strOwnerDocument].parentWindow || window) : window; - return ( - typeof wnd[strHTMLElement] == TYPES.o ? o instanceof wnd[strHTMLElement] : //DOM2 - o && typeof o == TYPES.o && o !== null && o.nodeType === 1 && typeof o.nodeName == TYPES.s - ); - } - - /** - * Compares 2 arrays and returns the differences between them as a array. - * @param a1 The first array which shall be compared. - * @param a2 The second array which shall be compared. - * @returns {Array} The differences between the two arrays. - */ - function getArrayDifferences(a1, a2) { - var a = []; - var diff = []; - var i; - var k; - for (i = 0; i < a1.length; i++) - a[a1[i]] = true; - for (i = 0; i < a2.length; i++) { - if (a[a2[i]]) - delete a[a2[i]]; - else - a[a2[i]] = true; - } - for (k in a) - diff.push(k); - return diff; - } - - /** - * Returns Zero or the number to which the value can be parsed. - * @param value The value which shall be parsed. - * @param toFloat Indicates whether the number shall be parsed to a float. - */ - function parseToZeroOrNumber(value, toFloat) { - var num = toFloat ? parseFloat(value) : parseInt(value, 10); - return isNaN(num) ? 0 : num; - } - - /** - * Gets several information of the textarea and returns them as a object or undefined if the browser doesn't support it. - * @returns {{cursorRow: Number, cursorCol, rows: Number, cols: number, wRow: number, pos: number, max : number}} or undefined if not supported. - */ - function getTextareaInfo() { - //read needed values - var textareaCursorPosition = _targetElementNative.selectionStart; - if (textareaCursorPosition === undefined) - return; - - var textareaValue = _targetElement.val(); - var textareaLength = textareaValue[LEXICON.l]; - var textareaRowSplit = textareaValue.split('\n'); - var textareaLastRow = textareaRowSplit[LEXICON.l]; - var textareaCurrentCursorRowSplit = textareaValue.substr(0, textareaCursorPosition).split('\n'); - var widestRow = 0; - var textareaLastCol = 0; - var cursorRow = textareaCurrentCursorRowSplit[LEXICON.l]; - var cursorCol = textareaCurrentCursorRowSplit[textareaCurrentCursorRowSplit[LEXICON.l] - 1][LEXICON.l]; - var rowCols; - var i; - - //get widest Row and the last column of the textarea - for (i = 0; i < textareaRowSplit[LEXICON.l]; i++) { - rowCols = textareaRowSplit[i][LEXICON.l]; - if (rowCols > textareaLastCol) { - widestRow = i + 1; - textareaLastCol = rowCols; - } - } - - return { - _cursorRow: cursorRow, //cursorRow - _cursorColumn: cursorCol, //cursorCol - _rows: textareaLastRow, //rows - _columns: textareaLastCol, //cols - _widestRow: widestRow, //wRow - _cursorPosition: textareaCursorPosition, //pos - _cursorMax: textareaLength //max - }; - } - - /** - * Determines whether native overlay scrollbars are active. - * @returns {boolean} True if native overlay scrollbars are active, false otherwise. - */ - function nativeOverlayScrollbarsAreActive() { - return (_ignoreOverlayScrollbarHidingCache && (_nativeScrollbarIsOverlaid.x && _nativeScrollbarIsOverlaid.y)); - } - - /** - * Gets the element which is used to measure the content size. - * @returns {*} TextareaCover if target element is textarea else the ContentElement. - */ - function getContentMeasureElement() { - return _isTextarea ? _textareaCoverElement[0] : _contentElementNative; - } - - /** - * Generates a string which represents a HTML div with the given classes or attributes. - * @param classesOrAttrs The class of the div as string or a object which represents the attributes of the div. (The class attribute can also be written as "className".) - * @param content The content of the div as string. - * @returns {string} The concated string which represents a HTML div and its content. - */ - function generateDiv(classesOrAttrs, content) { - return '
' + - (content || _strEmpty) + - '
'; - } - - /** - * Selects or generates a div with the given class attribute. - * @param className The class names (divided by spaces) of the div which shall be selected or generated. - * @param selectParentOrOnlyChildren The parent element from which of the element shall be selected. (if undefined or boolean its hostElement) - * If its a boolean it decides whether only the children of the host element shall be selected. - * @returns {*} The generated or selected element. - */ - function selectOrGenerateDivByClass(className, selectParentOrOnlyChildren) { - var onlyChildren = type(selectParentOrOnlyChildren) == TYPES.b; - var selectParent = onlyChildren ? _hostElement : (selectParentOrOnlyChildren || _hostElement); - - return (_domExists && !selectParent[LEXICON.l]) - ? null - : _domExists - ? selectParent[onlyChildren ? 'children' : 'find'](_strDot + className.replace(/\s/g, _strDot)).eq(0) - : FRAMEWORK(generateDiv(className)) - } - - /** - * Gets the value of the given property from the given object. - * @param obj The object from which the property value shall be got. - * @param path The property of which the value shall be got. - * @returns {*} Returns the value of the searched property or undefined of the property wasn't found. - */ - function getObjectPropVal(obj, path) { - var splits = path.split(_strDot); - var i = 0; - var val; - for (; i < splits.length; i++) { - if (!obj[LEXICON.hOP](splits[i])) - return; - val = obj[splits[i]]; - if (i < splits.length && type(val) == TYPES.o) - obj = val; - } - return val; - } - - /** - * Sets the value of the given property from the given object. - * @param obj The object from which the property value shall be set. - * @param path The property of which the value shall be set. - * @param val The value of the property which shall be set. - */ - function setObjectPropVal(obj, path, val) { - var splits = path.split(_strDot); - var splitsLength = splits.length; - var i = 0; - var extendObj = {}; - var extendObjRoot = extendObj; - for (; i < splitsLength; i++) - extendObj = extendObj[splits[i]] = i + 1 < splitsLength ? {} : val; - FRAMEWORK.extend(obj, extendObjRoot, true); - } - - - //==== Utils Cache ====// - - /** - * Compares two values or objects and returns true if they aren't equal. - * @param current The first value or object which shall be compared. - * @param cache The second value or object which shall be compared. - * @param force If true the returned value is always true. - * @returns {boolean} True if both values or objects aren't equal or force is true, false otherwise. - */ - function checkCache(current, cache, force) { - if (force) - return force; - if (type(current) == TYPES.o && type(cache) == TYPES.o) { - for (var prop in current) { - if (prop !== 'c') { - if (current[LEXICON.hOP](prop) && cache[LEXICON.hOP](prop)) { - if (checkCache(current[prop], cache[prop])) - return true; - } - else { - return true; - } - } - } - } - else { - return current !== cache; - } - return false; - } - - - //==== Shortcuts ====// - - /** - * jQuery extend method shortcut with a appended "true" as first argument. - */ - function extendDeep() { - return FRAMEWORK.extend.apply(this, [true].concat([].slice.call(arguments))); - } - - /** - * jQuery addClass method shortcut. - */ - function addClass(el, classes) { - return _frameworkProto.addClass.call(el, classes); - } - - /** - * jQuery removeClass method shortcut. - */ - function removeClass(el, classes) { - return _frameworkProto.removeClass.call(el, classes); - } - - /** - * jQuery remove method shortcut. - */ - function remove(el) { - return _frameworkProto.remove.call(el); - } - - /** - * Finds the first child element with the given selector of the given element. - * @param el The root element from which the selector shall be valid. - * @param selector The selector of the searched element. - * @returns {*} The first element which is a child of the given element and matches the givens selector. - */ - function findFirst(el, selector) { - return _frameworkProto.find.call(el, selector).eq(0); - } - - - //==== API ====// - - /** - * Puts the instance to sleep. It wont respond to any changes in the DOM and won't update. Scrollbar Interactivity is also disabled as well as the resize handle. - * This behavior can be reset by calling the update method. - */ - _base.sleep = function () { - _sleeping = true; - }; - - /** - * Updates the plugin and DOM to the current options. - * This method should only be called if a update is 100% required. - * @param force True if every property shall be updated and the cache shall be ignored. - * !INTERNAL USAGE! : force can be a string "auto", "sync" or "zoom" too - * if "auto" then before a real update the content size and host element attributes gets checked, and if they changed only then the update method will be called. - * if "sync" then the async update process (MutationObserver or UpdateLoop) gets synchronized and a corresponding update takes place if one was needed due to pending changes. - * if "zoom" then a update takes place where it's assumed that content and host size changed - * @returns {boolean|undefined} - * If force is "sync" then a boolean is returned which indicates whether a update was needed due to pending changes. - * If force is "auto" then a boolean is returned whether a update was needed due to attribute or size changes. - * undefined otherwise. - */ - _base.update = function (force) { - if (_destroyed) - return; - - var attrsChanged; - var contentSizeC; - var isString = type(force) == TYPES.s; - var imgElementSelector = 'img'; - var imgElementLoadEvent = 'load'; - var doUpdateAuto; - var mutHost; - var mutContent; - - if (isString) { - if (force === _strAuto) { - attrsChanged = meaningfulAttrsChanged(); - contentSizeC = updateAutoContentSizeChanged(); - doUpdateAuto = attrsChanged || contentSizeC; - if (doUpdateAuto) { - update({ - _contentSizeChanged: contentSizeC, - _changedOptions: _initialized ? undefined : _currentPreparedOptions - }); - } - } - else if (force === _strSync) { - if (_mutationObserversConnected) { - mutHost = _mutationObserverHostCallback(_mutationObserverHost.takeRecords()); - mutContent = _mutationObserverContentCallback(_mutationObserverContent.takeRecords()); - } - else { - mutHost = _base.update(_strAuto); - } - } - else if (force === 'zoom') { - update({ - _hostSizeChanged: true, - _contentSizeChanged: true - }); - } - } - else { - force = _sleeping || force; - _sleeping = false; - if (!_base.update(_strSync) || force) - update({ _force: force }); - } - if (!_isTextarea) { - _contentElement.find(imgElementSelector).each(function (i, el) { - var index = COMPATIBILITY.inA(el, _imgs); - if (index === -1) - FRAMEWORK(el).off(imgElementLoadEvent, imgOnLoad).on(imgElementLoadEvent, imgOnLoad); - }); - } - return doUpdateAuto || mutHost || mutContent; - }; - - /** - Gets or sets the current options. The update method will be called automatically if new options were set. - * @param newOptions If new options are given, then the new options will be set, if new options aren't given (undefined or a not a plain object) then the current options will be returned. - * @param value If new options is a property path string, then this value will be used to set the option to which the property path string leads. - * @returns {*} - */ - _base.options = function (newOptions, value) { - var option = {}; - var changedOps; - - //return current options if newOptions are undefined or empty - if (FRAMEWORK.isEmptyObject(newOptions) || !FRAMEWORK.isPlainObject(newOptions)) { - if (type(newOptions) == TYPES.s) { - if (arguments.length > 1) { - setObjectPropVal(option, newOptions, value); - changedOps = setOptions(option); - } - else - return getObjectPropVal(_currentOptions, newOptions); - } - else - return _currentOptions; - } - else { - changedOps = setOptions(newOptions); - } - - if (!FRAMEWORK.isEmptyObject(changedOps)) { - update({ _changedOptions: changedOps }); - } - }; - - /** - * Restore the DOM, disconnects all observers, remove all resize observers and put the instance to sleep. - */ - _base.destroy = function () { - if (_destroyed) - return; - - //remove this instance from auto update loop - autoUpdateLoop.remove(_base); - - //disconnect all mutation observers - disconnectMutationObservers(); - - //remove all resize observers - setupResizeObserver(_sizeObserverElement); - setupResizeObserver(_sizeAutoObserverElement); - - //remove all extensions - for (var extName in _extensions) - _base.removeExt(extName); - - //remove all 'destroy' events - while (_destroyEvents[LEXICON.l] > 0) - _destroyEvents.pop()(); - - //remove all events from host element - setupHostMouseTouchEvents(true); - - //remove all helper / detection elements - if (_contentGlueElement) - remove(_contentGlueElement); - if (_contentArrangeElement) - remove(_contentArrangeElement); - if (_sizeAutoObserverAdded) - remove(_sizeAutoObserverElement); - - //remove all generated DOM - setupScrollbarsDOM(true); - setupScrollbarCornerDOM(true); - setupStructureDOM(true); - - //remove all generated image load events - for (var i = 0; i < _imgs[LEXICON.l]; i++) - FRAMEWORK(_imgs[i]).off('load', imgOnLoad); - _imgs = undefined; - - _destroyed = true; - _sleeping = true; - - //remove this instance from the instances list - INSTANCES(pluginTargetElement, 0); - dispatchCallback('onDestroyed'); - - //remove all properties and methods - //for (var property in _base) - // delete _base[property]; - //_base = undefined; - }; - - /** - * Scrolls to a given position or element. - * @param coordinates - * 1. Can be "coordinates" which looks like: - * { x : ?, y : ? } OR Object with x and y properties - * { left : ?, top : ? } OR Object with left and top properties - * { l : ?, t : ? } OR Object with l and t properties - * [ ?, ? ] OR Array where the first two element are the coordinates (first is x, second is y) - * ? A single value which stays for both axis - * A value can be a number, a string or a calculation. - * - * Operators: - * [NONE] The current scroll will be overwritten by the value. - * '+=' The value will be added to the current scroll offset - * '-=' The value will be subtracted from the current scroll offset - * '*=' The current scroll wil be multiplicated by the value. - * '/=' The current scroll wil be divided by the value. - * - * Units: - * [NONE] The value is the final scroll amount. final = (value * 1) - * 'px' Same as none - * '%' The value is dependent on the current scroll value. final = ((currentScrollValue / 100) * value) - * 'vw' The value is multiplicated by the viewport width. final = (value * viewportWidth) - * 'vh' The value is multiplicated by the viewport height. final = (value * viewportHeight) - * - * example final values: - * 200, '200px', '50%', '1vw', '1vh', '+=200', '/=1vw', '*=2px', '-=5vh', '+=33%', '+= 50% - 2px', '-= 1vw - 50%' - * - * 2. Can be a HTML or jQuery element: - * The final scroll offset is the offset (without margin) of the given HTML / jQuery element. - * - * 3. Can be a object with a HTML or jQuery element with additional settings: - * { - * el : [HTMLElement, jQuery element], MUST be specified, else this object isn't valid. - * scroll : [string, array, object], Default value is 'always'. - * block : [string, array, object], Default value is 'begin'. - * margin : [number, boolean, array, object] Default value is false. - * } - * - * Possible scroll settings are: - * 'always' Scrolls always. - * 'ifneeded' Scrolls only if the element isnt fully in view. - * 'never' Scrolls never. - * - * Possible block settings are: - * 'begin' Both axis shall be docked to the "begin" edge. - The element will be docked to the top and left edge of the viewport. - * 'end' Both axis shall be docked to the "end" edge. - The element will be docked to the bottom and right edge of the viewport. (If direction is RTL to the bottom and left edge.) - * 'center' Both axis shall be docked to "center". - The element will be centered in the viewport. - * 'nearest' The element will be docked to the nearest edge(s). - * - * Possible margin settings are: -- The actual margin of the element wont be affect, this option affects only the final scroll offset. - * [BOOLEAN] If true the css margin of the element will be used, if false no margin will be used. - * [NUMBER] The margin will be used for all edges. - * - * @param duration The duration of the scroll animation, OR a jQuery animation configuration object. - * @param easing The animation easing. - * @param complete The animation complete callback. - * @returns {{ - * position: {x: number, y: number}, - * ratio: {x: number, y: number}, - * max: {x: number, y: number}, - * handleOffset: {x: number, y: number}, - * handleLength: {x: number, y: number}, - * handleLengthRatio: {x: number, y: number}, t - * rackLength: {x: number, y: number}, - * isRTL: boolean, - * isRTLNormalized: boolean - * }} - */ - _base.scroll = function (coordinates, duration, easing, complete) { - if (arguments.length === 0 || coordinates === undefined) { - var infoX = _scrollHorizontalInfo; - var infoY = _scrollVerticalInfo; - var normalizeInvert = _normalizeRTLCache && _isRTL && _rtlScrollBehavior.i; - var normalizeNegate = _normalizeRTLCache && _isRTL && _rtlScrollBehavior.n; - var scrollX = infoX._currentScroll; - var scrollXRatio = infoX._currentScrollRatio; - var maxScrollX = infoX._maxScroll; - scrollXRatio = normalizeInvert ? 1 - scrollXRatio : scrollXRatio; - scrollX = normalizeInvert ? maxScrollX - scrollX : scrollX; - scrollX *= normalizeNegate ? -1 : 1; - maxScrollX *= normalizeNegate ? -1 : 1; - - return { - position: { - x: scrollX, - y: infoY._currentScroll - }, - ratio: { - x: scrollXRatio, - y: infoY._currentScrollRatio - }, - max: { - x: maxScrollX, - y: infoY._maxScroll - }, - handleOffset: { - x: infoX._handleOffset, - y: infoY._handleOffset - }, - handleLength: { - x: infoX._handleLength, - y: infoY._handleLength - }, - handleLengthRatio: { - x: infoX._handleLengthRatio, - y: infoY._handleLengthRatio - }, - trackLength: { - x: infoX._trackLength, - y: infoY._trackLength - }, - snappedHandleOffset: { - x: infoX._snappedHandleOffset, - y: infoY._snappedHandleOffset - }, - isRTL: _isRTL, - isRTLNormalized: _normalizeRTLCache - }; - } - - _base.update(_strSync); - - var normalizeRTL = _normalizeRTLCache; - var coordinatesXAxisProps = [_strX, _strLeft, 'l']; - var coordinatesYAxisProps = [_strY, _strTop, 't']; - var coordinatesOperators = ['+=', '-=', '*=', '/=']; - var durationIsObject = type(duration) == TYPES.o; - var completeCallback = durationIsObject ? duration.complete : complete; - var i; - var finalScroll = {}; - var specialEasing = {}; - var doScrollLeft; - var doScrollTop; - var animationOptions; - var strEnd = 'end'; - var strBegin = 'begin'; - var strCenter = 'center'; - var strNearest = 'nearest'; - var strAlways = 'always'; - var strNever = 'never'; - var strIfNeeded = 'ifneeded'; - var strLength = LEXICON.l; - var settingsAxis; - var settingsScroll; - var settingsBlock; - var settingsMargin; - var finalElement; - var elementObjSettingsAxisValues = [_strX, _strY, 'xy', 'yx']; - var elementObjSettingsBlockValues = [strBegin, strEnd, strCenter, strNearest]; - var elementObjSettingsScrollValues = [strAlways, strNever, strIfNeeded]; - var coordinatesIsElementObj = coordinates[LEXICON.hOP]('el'); - var possibleElement = coordinatesIsElementObj ? coordinates.el : coordinates; - var possibleElementIsJQuery = possibleElement instanceof FRAMEWORK || JQUERY ? possibleElement instanceof JQUERY : false; - var possibleElementIsHTMLElement = possibleElementIsJQuery ? false : isHTMLElement(possibleElement); - var updateScrollbarInfos = function () { - if (doScrollLeft) - refreshScrollbarHandleOffset(true); - if (doScrollTop) - refreshScrollbarHandleOffset(false); - }; - var proxyCompleteCallback = type(completeCallback) != TYPES.f ? undefined : function () { - updateScrollbarInfos(); - completeCallback(); - }; - function checkSettingsStringValue(currValue, allowedValues) { - for (i = 0; i < allowedValues[strLength]; i++) { - if (currValue === allowedValues[i]) - return true; - } - return false; - } - function getRawScroll(isX, coordinates) { - var coordinateProps = isX ? coordinatesXAxisProps : coordinatesYAxisProps; - coordinates = type(coordinates) == TYPES.s || type(coordinates) == TYPES.n ? [coordinates, coordinates] : coordinates; - - if (type(coordinates) == TYPES.a) - return isX ? coordinates[0] : coordinates[1]; - else if (type(coordinates) == TYPES.o) { - //decides RTL normalization "hack" with .n - //normalizeRTL = type(coordinates.n) == TYPES.b ? coordinates.n : normalizeRTL; - for (i = 0; i < coordinateProps[strLength]; i++) - if (coordinateProps[i] in coordinates) - return coordinates[coordinateProps[i]]; - } - } - function getFinalScroll(isX, rawScroll) { - var isString = type(rawScroll) == TYPES.s; - var operator; - var amount; - var scrollInfo = isX ? _scrollHorizontalInfo : _scrollVerticalInfo; - var currScroll = scrollInfo._currentScroll; - var maxScroll = scrollInfo._maxScroll; - var mult = ' * '; - var finalValue; - var isRTLisX = _isRTL && isX; - var normalizeShortcuts = isRTLisX && _rtlScrollBehavior.n && !normalizeRTL; - var strReplace = 'replace'; - var evalFunc = eval; - var possibleOperator; - if (isString) { - //check operator - if (rawScroll[strLength] > 2) { - possibleOperator = rawScroll.substr(0, 2); - if (inArray(possibleOperator, coordinatesOperators) > -1) - operator = possibleOperator; - } - - //calculate units and shortcuts - rawScroll = operator ? rawScroll.substr(2) : rawScroll; - rawScroll = rawScroll - [strReplace](/min/g, 0) //'min' = 0% - [strReplace](//g, (normalizeShortcuts ? '-' : _strEmpty) + _strHundredPercent) //'>' = 100% - [strReplace](/px/g, _strEmpty) - [strReplace](/%/g, mult + (maxScroll * (isRTLisX && _rtlScrollBehavior.n ? -1 : 1) / 100.0)) - [strReplace](/vw/g, mult + _viewportSize.w) - [strReplace](/vh/g, mult + _viewportSize.h); - amount = parseToZeroOrNumber(isNaN(rawScroll) ? parseToZeroOrNumber(evalFunc(rawScroll), true).toFixed() : rawScroll); - } - else { - amount = rawScroll; - } - - if (amount !== undefined && !isNaN(amount) && type(amount) == TYPES.n) { - var normalizeIsRTLisX = normalizeRTL && isRTLisX; - var operatorCurrScroll = currScroll * (normalizeIsRTLisX && _rtlScrollBehavior.n ? -1 : 1); - var invert = normalizeIsRTLisX && _rtlScrollBehavior.i; - var negate = normalizeIsRTLisX && _rtlScrollBehavior.n; - operatorCurrScroll = invert ? (maxScroll - operatorCurrScroll) : operatorCurrScroll; - switch (operator) { - case '+=': - finalValue = operatorCurrScroll + amount; - break; - case '-=': - finalValue = operatorCurrScroll - amount; - break; - case '*=': - finalValue = operatorCurrScroll * amount; - break; - case '/=': - finalValue = operatorCurrScroll / amount; - break; - default: - finalValue = amount; - break; - } - finalValue = invert ? maxScroll - finalValue : finalValue; - finalValue *= negate ? -1 : 1; - finalValue = isRTLisX && _rtlScrollBehavior.n ? MATH.min(0, MATH.max(maxScroll, finalValue)) : MATH.max(0, MATH.min(maxScroll, finalValue)); - } - return finalValue === currScroll ? undefined : finalValue; - } - function getPerAxisValue(value, valueInternalType, defaultValue, allowedValues) { - var resultDefault = [defaultValue, defaultValue]; - var valueType = type(value); - var valueArrLength; - var valueArrItem; - - //value can be [ string, or array of two strings ] - if (valueType == valueInternalType) { - value = [value, value]; - } - else if (valueType == TYPES.a) { - valueArrLength = value[strLength]; - if (valueArrLength > 2 || valueArrLength < 1) - value = resultDefault; - else { - if (valueArrLength === 1) - value[1] = defaultValue; - for (i = 0; i < valueArrLength; i++) { - valueArrItem = value[i]; - if (type(valueArrItem) != valueInternalType || !checkSettingsStringValue(valueArrItem, allowedValues)) { - value = resultDefault; - break; - } - } - } - } - else if (valueType == TYPES.o) - value = [value[_strX] || defaultValue, value[_strY] || defaultValue]; - else - value = resultDefault; - return { x: value[0], y: value[1] }; - } - function generateMargin(marginTopRightBottomLeftArray) { - var result = []; - var currValue; - var currValueType; - var valueDirections = [_strTop, _strRight, _strBottom, _strLeft]; - for (i = 0; i < marginTopRightBottomLeftArray[strLength]; i++) { - if (i === valueDirections[strLength]) - break; - currValue = marginTopRightBottomLeftArray[i]; - currValueType = type(currValue); - if (currValueType == TYPES.b) - result.push(currValue ? parseToZeroOrNumber(finalElement.css(_strMarginMinus + valueDirections[i])) : 0); - else - result.push(currValueType == TYPES.n ? currValue : 0); - } - return result; - } - - if (possibleElementIsJQuery || possibleElementIsHTMLElement) { - //get settings - var margin = coordinatesIsElementObj ? coordinates.margin : 0; - var axis = coordinatesIsElementObj ? coordinates.axis : 0; - var scroll = coordinatesIsElementObj ? coordinates.scroll : 0; - var block = coordinatesIsElementObj ? coordinates.block : 0; - var marginDefault = [0, 0, 0, 0]; - var marginType = type(margin); - var marginLength; - finalElement = possibleElementIsJQuery ? possibleElement : FRAMEWORK(possibleElement); - - if (finalElement[strLength] > 0) { - //margin can be [ boolean, number, array of 2, array of 4, object ] - if (marginType == TYPES.n || marginType == TYPES.b) - margin = generateMargin([margin, margin, margin, margin]); - else if (marginType == TYPES.a) { - marginLength = margin[strLength]; - if (marginLength === 2) - margin = generateMargin([margin[0], margin[1], margin[0], margin[1]]); - else if (marginLength >= 4) - margin = generateMargin(margin); - else - margin = marginDefault; - } - else if (marginType == TYPES.o) - margin = generateMargin([margin[_strTop], margin[_strRight], margin[_strBottom], margin[_strLeft]]); - else - margin = marginDefault; - - //block = type(block) === TYPES.b ? block ? [ strNearest, strBegin ] : [ strNearest, strEnd ] : block; - settingsAxis = checkSettingsStringValue(axis, elementObjSettingsAxisValues) ? axis : 'xy'; - settingsScroll = getPerAxisValue(scroll, TYPES.s, strAlways, elementObjSettingsScrollValues); - settingsBlock = getPerAxisValue(block, TYPES.s, strBegin, elementObjSettingsBlockValues); - settingsMargin = margin; - - var viewportScroll = { - l: _scrollHorizontalInfo._currentScroll, - t: _scrollVerticalInfo._currentScroll - }; - // use padding element instead of viewport element because padding element has never padding, margin or position applied. - var viewportOffset = _paddingElement.offset(); - - //get coordinates - var elementOffset = finalElement.offset(); - var doNotScroll = { - x: settingsScroll.x == strNever || settingsAxis == _strY, - y: settingsScroll.y == strNever || settingsAxis == _strX - }; - elementOffset[_strTop] -= settingsMargin[0]; - elementOffset[_strLeft] -= settingsMargin[3]; - var elementScrollCoordinates = { - x: MATH.round(elementOffset[_strLeft] - viewportOffset[_strLeft] + viewportScroll.l), - y: MATH.round(elementOffset[_strTop] - viewportOffset[_strTop] + viewportScroll.t) - }; - if (_isRTL) { - if (!_rtlScrollBehavior.n && !_rtlScrollBehavior.i) - elementScrollCoordinates.x = MATH.round(viewportOffset[_strLeft] - elementOffset[_strLeft] + viewportScroll.l); - if (_rtlScrollBehavior.n && normalizeRTL) - elementScrollCoordinates.x *= -1; - if (_rtlScrollBehavior.i && normalizeRTL) - elementScrollCoordinates.x = MATH.round(viewportOffset[_strLeft] - elementOffset[_strLeft] + (_scrollHorizontalInfo._maxScroll - viewportScroll.l)); - } - - //measuring is required - if (settingsBlock.x != strBegin || settingsBlock.y != strBegin || settingsScroll.x == strIfNeeded || settingsScroll.y == strIfNeeded || _isRTL) { - var measuringElm = finalElement[0]; - var rawElementSize = _supportTransform ? measuringElm[LEXICON.bCR]() : { - width: measuringElm[LEXICON.oW], - height: measuringElm[LEXICON.oH] - }; - var elementSize = { - w: rawElementSize[_strWidth] + settingsMargin[3] + settingsMargin[1], - h: rawElementSize[_strHeight] + settingsMargin[0] + settingsMargin[2] - }; - var finalizeBlock = function (isX) { - var vars = getScrollbarVars(isX); - var wh = vars._w_h; - var lt = vars._left_top; - var xy = vars._x_y; - var blockIsEnd = settingsBlock[xy] == (isX ? _isRTL ? strBegin : strEnd : strEnd); - var blockIsCenter = settingsBlock[xy] == strCenter; - var blockIsNearest = settingsBlock[xy] == strNearest; - var scrollNever = settingsScroll[xy] == strNever; - var scrollIfNeeded = settingsScroll[xy] == strIfNeeded; - var vpSize = _viewportSize[wh]; - var vpOffset = viewportOffset[lt]; - var elSize = elementSize[wh]; - var elOffset = elementOffset[lt]; - var divide = blockIsCenter ? 2 : 1; - var elementCenterOffset = elOffset + (elSize / 2); - var viewportCenterOffset = vpOffset + (vpSize / 2); - var isInView = - elSize <= vpSize - && elOffset >= vpOffset - && elOffset + elSize <= vpOffset + vpSize; - - if (scrollNever) - doNotScroll[xy] = true; - else if (!doNotScroll[xy]) { - if (blockIsNearest || scrollIfNeeded) { - doNotScroll[xy] = scrollIfNeeded ? isInView : false; - blockIsEnd = elSize < vpSize ? elementCenterOffset > viewportCenterOffset : elementCenterOffset < viewportCenterOffset; - } - elementScrollCoordinates[xy] -= blockIsEnd || blockIsCenter ? ((vpSize / divide) - (elSize / divide)) * (isX && _isRTL && normalizeRTL ? -1 : 1) : 0; - } - }; - finalizeBlock(true); - finalizeBlock(false); - } - - if (doNotScroll.y) - delete elementScrollCoordinates.y; - if (doNotScroll.x) - delete elementScrollCoordinates.x; - - coordinates = elementScrollCoordinates; - } - } - - finalScroll[_strScrollLeft] = getFinalScroll(true, getRawScroll(true, coordinates)); - finalScroll[_strScrollTop] = getFinalScroll(false, getRawScroll(false, coordinates)); - doScrollLeft = finalScroll[_strScrollLeft] !== undefined; - doScrollTop = finalScroll[_strScrollTop] !== undefined; - - if ((doScrollLeft || doScrollTop) && (duration > 0 || durationIsObject)) { - if (durationIsObject) { - duration.complete = proxyCompleteCallback; - _viewportElement.animate(finalScroll, duration); - } - else { - animationOptions = { - duration: duration, - complete: proxyCompleteCallback - }; - if (type(easing) == TYPES.a || FRAMEWORK.isPlainObject(easing)) { - specialEasing[_strScrollLeft] = easing[0] || easing.x; - specialEasing[_strScrollTop] = easing[1] || easing.y; - animationOptions.specialEasing = specialEasing; - } - else { - animationOptions.easing = easing; - } - _viewportElement.animate(finalScroll, animationOptions); - } - } - else { - if (doScrollLeft) - _viewportElement[_strScrollLeft](finalScroll[_strScrollLeft]); - if (doScrollTop) - _viewportElement[_strScrollTop](finalScroll[_strScrollTop]); - updateScrollbarInfos(); - } - }; - - /** - * Stops all scroll animations. - * @returns {*} The current OverlayScrollbars instance (for chaining). - */ - _base.scrollStop = function (param1, param2, param3) { - _viewportElement.stop(param1, param2, param3); - return _base; - }; - - /** - * Returns all relevant elements. - * @param elementName The name of the element which shall be returned. - * @returns {{target: *, host: *, padding: *, viewport: *, content: *, scrollbarHorizontal: {scrollbar: *, track: *, handle: *}, scrollbarVertical: {scrollbar: *, track: *, handle: *}, scrollbarCorner: *} | *} - */ - _base.getElements = function (elementName) { - var obj = { - target: _targetElementNative, - host: _hostElementNative, - padding: _paddingElementNative, - viewport: _viewportElementNative, - content: _contentElementNative, - scrollbarHorizontal: { - scrollbar: _scrollbarHorizontalElement[0], - track: _scrollbarHorizontalTrackElement[0], - handle: _scrollbarHorizontalHandleElement[0] - }, - scrollbarVertical: { - scrollbar: _scrollbarVerticalElement[0], - track: _scrollbarVerticalTrackElement[0], - handle: _scrollbarVerticalHandleElement[0] - }, - scrollbarCorner: _scrollbarCornerElement[0] - }; - return type(elementName) == TYPES.s ? getObjectPropVal(obj, elementName) : obj; - }; - - /** - * Returns a object which describes the current state of this instance. - * @param stateProperty A specific property from the state object which shall be returned. - * @returns {{widthAuto, heightAuto, overflowAmount, hideOverflow, hasOverflow, contentScrollSize, viewportSize, hostSize, autoUpdate} | *} - */ - _base.getState = function (stateProperty) { - function prepare(obj) { - if (!FRAMEWORK.isPlainObject(obj)) - return obj; - var extended = extendDeep({}, obj); - var changePropertyName = function (from, to) { - if (extended[LEXICON.hOP](from)) { - extended[to] = extended[from]; - delete extended[from]; - } - }; - changePropertyName('w', _strWidth); //change w to width - changePropertyName('h', _strHeight); //change h to height - delete extended.c; //delete c (the 'changed' prop) - return extended; - }; - var obj = { - destroyed: !!prepare(_destroyed), - sleeping: !!prepare(_sleeping), - autoUpdate: prepare(!_mutationObserversConnected), - widthAuto: prepare(_widthAutoCache), - heightAuto: prepare(_heightAutoCache), - padding: prepare(_cssPaddingCache), - overflowAmount: prepare(_overflowAmountCache), - hideOverflow: prepare(_hideOverflowCache), - hasOverflow: prepare(_hasOverflowCache), - contentScrollSize: prepare(_contentScrollSizeCache), - viewportSize: prepare(_viewportSize), - hostSize: prepare(_hostSizeCache), - documentMixed: prepare(_documentMixed) - }; - return type(stateProperty) == TYPES.s ? getObjectPropVal(obj, stateProperty) : obj; - }; - - /** - * Gets all or specific extension instance. - * @param extName The name of the extension from which the instance shall be got. - * @returns {{}} The instance of the extension with the given name or undefined if the instance couldn't be found. - */ - _base.ext = function (extName) { - var result; - var privateMethods = _extensionsPrivateMethods.split(' '); - var i = 0; - if (type(extName) == TYPES.s) { - if (_extensions[LEXICON.hOP](extName)) { - result = extendDeep({}, _extensions[extName]); - for (; i < privateMethods.length; i++) - delete result[privateMethods[i]]; - } - } - else { - result = {}; - for (i in _extensions) - result[i] = extendDeep({}, _base.ext(i)); - } - return result; - }; - - /** - * Adds a extension to this instance. - * @param extName The name of the extension which shall be added. - * @param extensionOptions The extension options which shall be used. - * @returns {{}} The instance of the added extension or undefined if the extension couldn't be added properly. - */ - _base.addExt = function (extName, extensionOptions) { - var registeredExtensionObj = _plugin.extension(extName); - var instance; - var instanceAdded; - var instanceContract; - var contractResult; - var contractFulfilled = true; - if (registeredExtensionObj) { - if (!_extensions[LEXICON.hOP](extName)) { - instance = registeredExtensionObj.extensionFactory.call(_base, - extendDeep({}, registeredExtensionObj.defaultOptions), - FRAMEWORK, - COMPATIBILITY); - - if (instance) { - instanceContract = instance.contract; - if (type(instanceContract) == TYPES.f) { - contractResult = instanceContract(window); - contractFulfilled = type(contractResult) == TYPES.b ? contractResult : contractFulfilled; - } - if (contractFulfilled) { - _extensions[extName] = instance; - instanceAdded = instance.added; - if (type(instanceAdded) == TYPES.f) - instanceAdded(extensionOptions); - - return _base.ext(extName); - } - } - } - else - return _base.ext(extName); - } - else - console.warn("A extension with the name \"" + extName + "\" isn't registered."); - }; - - /** - * Removes a extension from this instance. - * @param extName The name of the extension which shall be removed. - * @returns {boolean} True if the extension was removed, false otherwise e.g. if the extension wasn't added before. - */ - _base.removeExt = function (extName) { - var instance = _extensions[extName]; - var instanceRemoved; - if (instance) { - delete _extensions[extName]; - - instanceRemoved = instance.removed; - if (type(instanceRemoved) == TYPES.f) - instanceRemoved(); - - return true; - } - return false; - }; - - /** - * Constructs the plugin. - * @param targetElement The element to which the plugin shall be applied. - * @param options The initial options of the plugin. - * @param extensions The extension(s) which shall be added right after the initialization. - * @returns {boolean} True if the plugin was successfully initialized, false otherwise. - */ - function construct(targetElement, options, extensions) { - _defaultOptions = globals.defaultOptions; - _nativeScrollbarStyling = globals.nativeScrollbarStyling; - _nativeScrollbarSize = extendDeep({}, globals.nativeScrollbarSize); - _nativeScrollbarIsOverlaid = extendDeep({}, globals.nativeScrollbarIsOverlaid); - _overlayScrollbarDummySize = extendDeep({}, globals.overlayScrollbarDummySize); - _rtlScrollBehavior = extendDeep({}, globals.rtlScrollBehavior); - - //parse & set options but don't update - setOptions(extendDeep({}, _defaultOptions, options)); - - _cssCalc = globals.cssCalc; - _msieVersion = globals.msie; - _autoUpdateRecommended = globals.autoUpdateRecommended; - _supportTransition = globals.supportTransition; - _supportTransform = globals.supportTransform; - _supportPassiveEvents = globals.supportPassiveEvents; - _supportResizeObserver = globals.supportResizeObserver; - _supportMutationObserver = globals.supportMutationObserver; - _restrictedMeasuring = globals.restrictedMeasuring; - _documentElement = FRAMEWORK(targetElement.ownerDocument); - _documentElementNative = _documentElement[0]; - _windowElement = FRAMEWORK(_documentElementNative.defaultView || _documentElementNative.parentWindow); - _windowElementNative = _windowElement[0]; - _htmlElement = findFirst(_documentElement, 'html'); - _bodyElement = findFirst(_htmlElement, 'body'); - _targetElement = FRAMEWORK(targetElement); - _targetElementNative = _targetElement[0]; - _isTextarea = _targetElement.is('textarea'); - _isBody = _targetElement.is('body'); - _documentMixed = _documentElementNative !== document; - - /* On a div Element The if checks only whether: - * - the targetElement has the class "os-host" - * - the targetElement has a a child with the class "os-padding" - * - * If that's the case, its assumed the DOM has already the following structure: - * (The ".os-host" element is the targetElement) - * - *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- * - * ===================================================================================== - * - * On a Textarea Element The if checks only whether: - * - the targetElement has the class "os-textarea" - * - the targetElement is inside a element with the class "os-content" - * - * If that's the case, its assumed the DOM has already the following structure: - * (The ".os-textarea" (textarea) element is the targetElement) - * - *
- *
- *
- *
- *
- *
- * - *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- */ - _domExists = _isTextarea - ? _targetElement.hasClass(_classNameTextareaElement) && _targetElement.parent().hasClass(_classNameContentElement) - : _targetElement.hasClass(_classNameHostElement) && _targetElement.children(_strDot + _classNamePaddingElement)[LEXICON.l]; - - var initBodyScroll; - var bodyMouseTouchDownListener; - - //check if the plugin hasn't to be initialized - if (_nativeScrollbarIsOverlaid.x && _nativeScrollbarIsOverlaid.y && !_currentPreparedOptions.nativeScrollbarsOverlaid.initialize) { - dispatchCallback('onInitializationWithdrawn'); - if (_domExists) { - setupStructureDOM(true); - setupScrollbarsDOM(true); - setupScrollbarCornerDOM(true); - } - - _destroyed = true; - _sleeping = true; - - return _base; - } - - if (_isBody) { - initBodyScroll = {}; - initBodyScroll.l = MATH.max(_targetElement[_strScrollLeft](), _htmlElement[_strScrollLeft](), _windowElement[_strScrollLeft]()); - initBodyScroll.t = MATH.max(_targetElement[_strScrollTop](), _htmlElement[_strScrollTop](), _windowElement[_strScrollTop]()); - - bodyMouseTouchDownListener = function () { - _viewportElement.removeAttr(LEXICON.ti); - setupResponsiveEventListener(_viewportElement, _strMouseTouchDownEvent, bodyMouseTouchDownListener, true, true); - } - } - - //build OverlayScrollbars DOM - setupStructureDOM(); - setupScrollbarsDOM(); - setupScrollbarCornerDOM(); - - //create OverlayScrollbars events - setupStructureEvents(); - setupScrollbarEvents(true); - setupScrollbarEvents(false); - setupScrollbarCornerEvents(); - - //create mutation observers - createMutationObservers(); - - //build resize observer for the host element - setupResizeObserver(_sizeObserverElement, hostOnResized); - - if (_isBody) { - //apply the body scroll to handle it right in the update method - _viewportElement[_strScrollLeft](initBodyScroll.l)[_strScrollTop](initBodyScroll.t); - - //set the focus on the viewport element so you dont have to click on the page to use keyboard keys (up / down / space) for scrolling - if (document.activeElement == targetElement && _viewportElementNative.focus) { - //set a tabindex to make the viewportElement focusable - _viewportElement.attr(LEXICON.ti, '-1'); - _viewportElementNative.focus(); - - /* the tabindex has to be removed due to; - * If you set the tabindex attribute on an
, then its child content cannot be scrolled with the arrow keys unless you set tabindex on the content, too - * https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex - */ - setupResponsiveEventListener(_viewportElement, _strMouseTouchDownEvent, bodyMouseTouchDownListener, false, true); - } - } - - //update for the first time & initialize cache - _base.update(_strAuto); - - //the plugin is initialized now! - _initialized = true; - dispatchCallback('onInitialized'); - - //call all callbacks which would fire before the initialized was complete - each(_callbacksInitQeueue, function (index, value) { dispatchCallback(value.n, value.a); }); - _callbacksInitQeueue = []; - - //add extensions - if (type(extensions) == TYPES.s) - extensions = [extensions]; - if (COMPATIBILITY.isA(extensions)) - each(extensions, function (index, value) { _base.addExt(value); }); - else if (FRAMEWORK.isPlainObject(extensions)) - each(extensions, function (key, value) { _base.addExt(key, value); }); - - //add the transition class for transitions AFTER the first update & AFTER the applied extensions (for preventing unwanted transitions) - setTimeout(function () { - if (_supportTransition && !_destroyed) - addClass(_hostElement, _classNameHostTransition); - }, 333); - - return _base; - } - - if (_plugin.valid(construct(pluginTargetElement, options, extensions))) { - INSTANCES(pluginTargetElement, _base); - } - - return _base; - } - - /** - * Initializes a new OverlayScrollbarsInstance object or changes options if already initialized or returns the current instance. - * @param pluginTargetElements The elements to which the Plugin shall be initialized. - * @param options The custom options with which the plugin shall be initialized. - * @param extensions The extension(s) which shall be added right after initialization. - * @returns {*} - */ - _plugin = window[PLUGINNAME] = function (pluginTargetElements, options, extensions) { - if (arguments[LEXICON.l] === 0) - return this; - - var arr = []; - var optsIsPlainObj = FRAMEWORK.isPlainObject(options); - var inst; - var result; - - //pluginTargetElements is null or undefined - if (!pluginTargetElements) - return optsIsPlainObj || !options ? result : arr; - - /* - pluginTargetElements will be converted to: - 1. A jQueryElement Array - 2. A HTMLElement Array - 3. A Array with a single HTML Element - so pluginTargetElements is always a array. - */ - pluginTargetElements = pluginTargetElements[LEXICON.l] != undefined ? pluginTargetElements : [pluginTargetElements[0] || pluginTargetElements]; - initOverlayScrollbarsStatics(); - - if (pluginTargetElements[LEXICON.l] > 0) { - if (optsIsPlainObj) { - FRAMEWORK.each(pluginTargetElements, function (i, v) { - inst = v; - if (inst !== undefined) - arr.push(OverlayScrollbarsInstance(inst, options, extensions, _pluginsGlobals, _pluginsAutoUpdateLoop)); - }); - } - else { - FRAMEWORK.each(pluginTargetElements, function (i, v) { - inst = INSTANCES(v); - if ((options === '!' && _plugin.valid(inst)) || (COMPATIBILITY.type(options) == TYPES.f && options(v, inst))) - arr.push(inst); - else if (options === undefined) - arr.push(inst); - }); - } - result = arr[LEXICON.l] === 1 ? arr[0] : arr; - } - return result; - }; - - /** - * Returns a object which contains global information about the plugin and each instance of it. - * The returned object is just a copy, that means that changes to the returned object won't have any effect to the original object. - */ - _plugin.globals = function () { - initOverlayScrollbarsStatics(); - var globals = FRAMEWORK.extend(true, {}, _pluginsGlobals); - delete globals['msie']; - return globals; - }; - - /** - * Gets or Sets the default options for each new plugin initialization. - * @param newDefaultOptions The object with which the default options shall be extended. - */ - _plugin.defaultOptions = function (newDefaultOptions) { - initOverlayScrollbarsStatics(); - var currDefaultOptions = _pluginsGlobals.defaultOptions; - if (newDefaultOptions === undefined) - return FRAMEWORK.extend(true, {}, currDefaultOptions); - - //set the new default options - _pluginsGlobals.defaultOptions = FRAMEWORK.extend(true, {}, currDefaultOptions, _pluginsOptions._validate(newDefaultOptions, _pluginsOptions._template, true, currDefaultOptions)._default); - }; - - /** - * Checks whether the passed instance is a non-destroyed OverlayScrollbars instance. - * @param osInstance The potential OverlayScrollbars instance which shall be checked. - * @returns {boolean} True if the passed value is a non-destroyed OverlayScrollbars instance, false otherwise. - */ - _plugin.valid = function (osInstance) { - return osInstance instanceof _plugin && !osInstance.getState().destroyed; - }; - - /** - * Registers, Unregisters or returns a extension. - * Register: Pass the name and the extension. (defaultOptions is optional) - * Unregister: Pass the name and anything except a function as extension parameter. - * Get extension: Pass the name of the extension which shall be got. - * Get all extensions: Pass no arguments. - * @param extensionName The name of the extension which shall be registered, unregistered or returned. - * @param extension A function which generates the instance of the extension or anything other to remove a already registered extension. - * @param defaultOptions The default options which shall be used for the registered extension. - */ - _plugin.extension = function (extensionName, extension, defaultOptions) { - var extNameTypeString = COMPATIBILITY.type(extensionName) == TYPES.s; - var argLen = arguments[LEXICON.l]; - var i = 0; - if (argLen < 1 || !extNameTypeString) { - //return a copy of all extension objects - return FRAMEWORK.extend(true, { length: _pluginsExtensions[LEXICON.l] }, _pluginsExtensions); - } - else if (extNameTypeString) { - if (COMPATIBILITY.type(extension) == TYPES.f) { - //register extension - _pluginsExtensions.push({ - name: extensionName, - extensionFactory: extension, - defaultOptions: defaultOptions - }); - } - else { - for (; i < _pluginsExtensions[LEXICON.l]; i++) { - if (_pluginsExtensions[i].name === extensionName) { - if (argLen > 1) - _pluginsExtensions.splice(i, 1); //remove extension - else - return FRAMEWORK.extend(true, {}, _pluginsExtensions[i]); //return extension with the given name - } - } - } - } - }; - - return _plugin; - })(); - - if (JQUERY && JQUERY.fn) { - /** - * The jQuery initialization interface. - * @param options The initial options for the construction of the plugin. To initialize the plugin, this option has to be a object! If it isn't a object, the instance(s) are returned and the plugin wont be initialized. - * @param extensions The extension(s) which shall be added right after initialization. - * @returns {*} After initialization it returns the jQuery element array, else it returns the instance(s) of the elements which are selected. - */ - JQUERY.fn.overlayScrollbars = function (options, extensions) { - var _elements = this; - if (JQUERY.isPlainObject(options)) { - JQUERY.each(_elements, function () { PLUGIN(this, options, extensions); }); - return _elements; - } - else - return PLUGIN(_elements, options); - }; - } - return PLUGIN; - } -)); \ No newline at end of file +/*! + * OverlayScrollbars + * https://github.com/KingSora/OverlayScrollbars + * + * Version: 1.11.0 + * + * Copyright KingSora | Rene Haas. + * https://github.com/KingSora + * + * Released under the MIT license. + * Date: 29.02.2020 + */ + +(function (global, factory) { + if (typeof define === 'function' && define.amd) + define(['jquery'], function(framework) { return factory(global, global.document, undefined, framework); }); + else if (typeof module === 'object' && typeof module.exports === 'object') + module.exports = factory(global, global.document, undefined, require('jquery')); + else + factory(global, global.document, undefined, global.jQuery); +}(typeof window !== 'undefined' ? window : this, + function(window, document, undefined, framework) { + 'use strict'; + var PLUGINNAME = 'OverlayScrollbars'; + var TYPES = { + o : 'object', + f : 'function', + a : 'array', + s : 'string', + b : 'boolean', + n : 'number', + u : 'undefined', + z : 'null' + //d : 'date', + //e : 'error', + //r : 'regexp', + //y : 'symbol' + }; + var LEXICON = { + c: 'class', + s: 'style', + i: 'id', + l: 'length', + p: 'prototype', + ti: 'tabindex', + oH: 'offsetHeight', + cH: 'clientHeight', + sH: 'scrollHeight', + oW: 'offsetWidth', + cW: 'clientWidth', + sW: 'scrollWidth', + hOP: 'hasOwnProperty', + bCR: 'getBoundingClientRect' + }; + var VENDORS = (function() { + //https://developer.mozilla.org/en-US/docs/Glossary/Vendor_Prefix + var jsCache = { }; + var cssCache = { }; + var cssPrefixes = ['-webkit-', '-moz-', '-o-', '-ms-']; + var jsPrefixes = ['WebKit', 'Moz', 'O', 'MS']; + function firstLetterToUpper(str) { + return str.charAt(0).toUpperCase() + str.slice(1); + } + + return { + _cssPrefixes: cssPrefixes, + _jsPrefixes: jsPrefixes, + _cssProperty : function(name) { + var result = cssCache[name]; + + if(cssCache[LEXICON.hOP](name)) + return result; + + var uppercasedName = firstLetterToUpper(name); + var elmStyle = document.createElement('div')[LEXICON.s]; + var resultPossibilities; + var i = 0; + var v; + var currVendorWithoutDashes; + + for (; i < cssPrefixes.length; i++) { + currVendorWithoutDashes = cssPrefixes[i].replace(/-/g, ''); + resultPossibilities = [ + name, //transition + cssPrefixes[i] + name, //-webkit-transition + currVendorWithoutDashes + uppercasedName, //webkitTransition + firstLetterToUpper(currVendorWithoutDashes) + uppercasedName //WebkitTransition + ]; + for(v = 0; v < resultPossibilities[LEXICON.l]; v++) { + if(elmStyle[resultPossibilities[v]] !== undefined) { + result = resultPossibilities[v]; + break; + } + } + } + + cssCache[name] = result; + return result; + }, + _jsAPI : function(name, isInterface, fallback) { + var i = 0; + var result = jsCache[name]; + + if(!jsCache[LEXICON.hOP](name)) { + result = window[name]; + for(; i < jsPrefixes[LEXICON.l]; i++) + result = result || window[(isInterface ? jsPrefixes[i] : jsPrefixes[i].toLowerCase()) + firstLetterToUpper(name)]; + jsCache[name] = result; + } + return result || fallback; + } + + } + })(); + var COMPATIBILITY = (function() { + function windowSize(x) { + return x ? window.innerWidth || document.documentElement[LEXICON.cW] || document.body[LEXICON.cW] : window.innerHeight || document.documentElement[LEXICON.cH] || document.body[LEXICON.cH]; + } + function bind(func, thisObj) { + if (typeof func != TYPES.f) { + throw "Can't bind function!"; + // closest thing possible to the ECMAScript 5 + // internal IsCallable function + //throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable'); + } + var proto = LEXICON.p; + var aArgs = Array[proto].slice.call(arguments, 2); + var fNOP = function() {}; + var fBound = function() { return func.apply(this instanceof fNOP ? this : thisObj, aArgs.concat(Array[proto].slice.call(arguments))); }; + + if (func[proto]) + fNOP[proto] = func[proto]; // Function.prototype doesn't have a prototype property + fBound[proto] = new fNOP(); + + return fBound; + } + + return { + /** + * Gets the current window width. + * @returns {Number|number} The current window width in pixel. + */ + wW: bind(windowSize, 0, true), + + /** + * Gets the current window height. + * @returns {Number|number} The current window height in pixel. + */ + wH: bind(windowSize, 0), + + /** + * Gets the MutationObserver Object or undefined if not supported. + * @returns {MutationObserver|*|undefined} The MutationsObserver Object or undefined. + */ + mO: bind(VENDORS._jsAPI, 0, 'MutationObserver', true), + + /** + * Gets the ResizeObserver Object or undefined if not supported. + * @returns {MutationObserver|*|undefined} The ResizeObserver Object or undefined. + */ + rO: bind(VENDORS._jsAPI, 0, 'ResizeObserver', true), + + /** + * Gets the RequestAnimationFrame method or it's corresponding polyfill. + * @returns {*|Function} The RequestAnimationFrame method or it's corresponding polyfill. + */ + rAF: bind(VENDORS._jsAPI, 0, 'requestAnimationFrame', false, function (func) { return window.setTimeout(func, 1000 / 60); }), + + /** + * Gets the CancelAnimationFrame method or it's corresponding polyfill. + * @returns {*|Function} The CancelAnimationFrame method or it's corresponding polyfill. + */ + cAF: bind(VENDORS._jsAPI, 0, 'cancelAnimationFrame', false, function (id) { return window.clearTimeout(id); }), + + /** + * Gets the current time. + * @returns {number} The current time. + */ + now: function() { + return Date.now && Date.now() || new Date().getTime(); + }, + + /** + * Stops the propagation of the given event. + * @param event The event of which the propagation shall be stoped. + */ + stpP: function(event) { + if(event.stopPropagation) + event.stopPropagation(); + else + event.cancelBubble = true; + }, + + /** + * Prevents the default action of the given event. + * @param event The event of which the default action shall be prevented. + */ + prvD: function(event) { + if(event.preventDefault && event.cancelable) + event.preventDefault(); + else + event.returnValue = false; + }, + + /** + * Gets the pageX and pageY values of the given mouse event. + * @param event The mouse event of which the pageX and pageX shall be got. + * @returns {{x: number, y: number}} x = pageX value, y = pageY value. + */ + page: function(event) { + event = event.originalEvent || event; + + var strPage = 'page'; + var strClient = 'client'; + var strX = 'X'; + var strY = 'Y'; + var target = event.target || event.srcElement || document; + var eventDoc = target.ownerDocument || document; + var doc = eventDoc.documentElement; + var body = eventDoc.body; + + //if touch event return return pageX/Y of it + if(event.touches !== undefined) { + var touch = event.touches[0]; + return { + x : touch[strPage + strX], + y : touch[strPage + strY] + } + } + + // Calculate pageX/Y if not native supported + if (!event[strPage + strX] && event[strClient + strX] && event[strClient + strX] != null) { + + return { + x : event[strClient + strX] + + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - + (doc && doc.clientLeft || body && body.clientLeft || 0), + y : event[strClient + strY] + + (doc && doc.scrollTop || body && body.scrollTop || 0) - + (doc && doc.clientTop || body && body.clientTop || 0) + } + } + return { + x : event[strPage + strX], + y : event[strPage + strY] + }; + }, + + /** + * Gets the clicked mouse button of the given mouse event. + * @param event The mouse event of which the clicked button shal be got. + * @returns {number} The number of the clicked mouse button. (0 : none | 1 : leftButton | 2 : middleButton | 3 : rightButton) + */ + mBtn: function(event) { + var button = event.button; + if (!event.which && button !== undefined) + return (button & 1 ? 1 : (button & 2 ? 3 : (button & 4 ? 2 : 0))); + else + return event.which; + }, + + /** + * Checks whether a item is in the given array and returns its index. + * @param item The item of which the position in the array shall be determined. + * @param arr The array. + * @returns {number} The zero based index of the item or -1 if the item isn't in the array. + */ + inA : function(item, arr) { + for (var i = 0; i < arr[LEXICON.l]; i++) + //Sometiems in IE a "SCRIPT70" Permission denied error occurs if HTML elements in a iFrame are compared + try { + if (arr[i] === item) + return i; + } + catch(e) { } + return -1; + }, + + /** + * Returns true if the given value is a array. + * @param arr The potential array. + * @returns {boolean} True if the given value is a array, false otherwise. + */ + isA: function(arr) { + var def = Array.isArray; + return def ? def(arr) : this.type(arr) == TYPES.a; + }, + + /** + * Determine the internal JavaScript [[Class]] of the given object. + * @param obj The object of which the type shall be determined. + * @returns {string} The type of the given object. + */ + type: function(obj) { + if (obj === undefined) + return obj + ''; + if (obj === null) + return obj + ''; + return Object[LEXICON.p].toString.call(obj).replace(/^\[object (.+)\]$/, '$1').toLowerCase(); + }, + + + bind: bind + + /** + * Gets the vendor-prefixed CSS property by the given name. + * For example the given name is "transform" and you're using a old Firefox browser then the returned value would be "-moz-transform". + * If the browser doesn't need a vendor-prefix, then the returned string is the given name. + * If the browser doesn't support the given property name at all (not even with a vendor-prefix) the returned value is null. + * @param propName The unprefixed CSS property name. + * @returns {string|null} The vendor-prefixed CSS property or null if the browser doesn't support the given CSS property. + + cssProp: function(propName) { + return VENDORS._cssProperty(propName); + } + */ + } + })(); + + var MATH = Math; + var JQUERY = framework; + var EASING = framework.easing; + var FRAMEWORK = framework; + var INSTANCES = (function () { + var _targets = []; + var _instancePropertyString = '__overlayScrollbars__'; + + /** + * Register, unregister or get a certain (or all) instances. + * Register: Pass the target and the instance. + * Unregister: Pass the target and null. + * Get Instance: Pass the target from which the instance shall be got. + * Get Targets: Pass no arguments. + * @param target The target to which the instance shall be registered / from which the instance shall be unregistered / the instance shall be got + * @param instance The instance. + * @returns {*|void} Returns the instance from the given target. + */ + return function (target, instance) { + var argLen = arguments[LEXICON.l]; + if (argLen < 1) { + //return all targets + return _targets; + } + else { + if (instance) { + //register instance + target[_instancePropertyString] = instance; + _targets.push(target); + } + else { + var index = COMPATIBILITY.inA(target, _targets); + if (index > -1) { + if (argLen > 1) { + //unregister instance + delete target[_instancePropertyString]; + _targets.splice(index, 1); + } + else { + //get instance from target + return _targets[index][_instancePropertyString]; + } + } + } + } + } + })(); + var PLUGIN = (function () { + var _plugin; + var _pluginsGlobals; + var _pluginsAutoUpdateLoop; + var _pluginsExtensions = []; + var _pluginsOptions = (function () { + var type = COMPATIBILITY.type; + var possibleTemplateTypes = [ + TYPES.b, //boolean + TYPES.n, //number + TYPES.s, //string + TYPES.a, //array + TYPES.o, //object + TYPES.f, //function + TYPES.z //null + ]; + var restrictedStringsSplit = ' '; + var restrictedStringsPossibilitiesSplit = ':'; + var classNameAllowedValues = [TYPES.z, TYPES.s]; + var numberAllowedValues = TYPES.n; + var booleanNullAllowedValues = [TYPES.z, TYPES.b]; + var booleanTrueTemplate = [true, TYPES.b]; + var booleanFalseTemplate = [false, TYPES.b]; + var callbackTemplate = [null, [TYPES.z, TYPES.f]]; + var inheritedAttrsTemplate = [['style', 'class'], [TYPES.s, TYPES.a, TYPES.z]]; + var resizeAllowedValues = 'n:none b:both h:horizontal v:vertical'; + var overflowBehaviorAllowedValues = 'v-h:visible-hidden v-s:visible-scroll s:scroll h:hidden'; + var scrollbarsVisibilityAllowedValues = 'v:visible h:hidden a:auto'; + var scrollbarsAutoHideAllowedValues = 'n:never s:scroll l:leave m:move'; + var optionsDefaultsAndTemplate = { + className: ['os-theme-dark', classNameAllowedValues], //null || string + resize: ['none', resizeAllowedValues], //none || both || horizontal || vertical || n || b || h || v + sizeAutoCapable: booleanTrueTemplate, //true || false + clipAlways: booleanTrueTemplate, //true || false + normalizeRTL: booleanTrueTemplate, //true || false + paddingAbsolute: booleanFalseTemplate, //true || false + autoUpdate: [null, booleanNullAllowedValues], //true || false || null + autoUpdateInterval: [33, numberAllowedValues], //number + nativeScrollbarsOverlaid: { + showNativeScrollbars: booleanFalseTemplate, //true || false + initialize: booleanTrueTemplate //true || false + }, + overflowBehavior: { + x: ['scroll', overflowBehaviorAllowedValues], //visible-hidden || visible-scroll || hidden || scroll || v-h || v-s || h || s + y: ['scroll', overflowBehaviorAllowedValues] //visible-hidden || visible-scroll || hidden || scroll || v-h || v-s || h || s + }, + scrollbars: { + visibility: ['auto', scrollbarsVisibilityAllowedValues], //visible || hidden || auto || v || h || a + autoHide: ['never', scrollbarsAutoHideAllowedValues], //never || scroll || leave || move || n || s || l || m + autoHideDelay: [800, numberAllowedValues], //number + dragScrolling: booleanTrueTemplate, //true || false + clickScrolling: booleanFalseTemplate, //true || false + touchSupport: booleanTrueTemplate, //true || false + snapHandle: booleanFalseTemplate //true || false + }, + textarea: { + dynWidth: booleanFalseTemplate, //true || false + dynHeight: booleanFalseTemplate, //true || false + inheritedAttrs: inheritedAttrsTemplate //string || array || null + }, + callbacks: { + onInitialized: callbackTemplate, //null || function + onInitializationWithdrawn: callbackTemplate, //null || function + onDestroyed: callbackTemplate, //null || function + onScrollStart: callbackTemplate, //null || function + onScroll: callbackTemplate, //null || function + onScrollStop: callbackTemplate, //null || function + onOverflowChanged: callbackTemplate, //null || function + onOverflowAmountChanged: callbackTemplate, //null || function + onDirectionChanged: callbackTemplate, //null || function + onContentSizeChanged: callbackTemplate, //null || function + onHostSizeChanged: callbackTemplate, //null || function + onUpdated: callbackTemplate //null || function + } + }; + var convert = function (template) { + var recursive = function (obj) { + var key; + var val; + var valType; + for (key in obj) { + if (!obj[LEXICON.hOP](key)) + continue; + val = obj[key]; + valType = type(val); + if (valType == TYPES.a) + obj[key] = val[template ? 1 : 0]; + else if (valType == TYPES.o) + obj[key] = recursive(val); + } + return obj; + }; + return recursive(FRAMEWORK.extend(true, {}, optionsDefaultsAndTemplate)); + }; + + return { + _defaults: convert(), + + _template: convert(true), + + /** + * Validates the passed object by the passed template. + * @param obj The object which shall be validated. + * @param template The template which defines the allowed values and types. + * @param writeErrors True if errors shall be logged to the console. + * @param diffObj If a object is passed then only valid differences to this object will be returned. + * @returns {{}} A object which contains two objects called "default" and "prepared" which contains only the valid properties of the passed original object and discards not different values compared to the passed diffObj. + */ + _validate: function (obj, template, writeErrors, diffObj) { + var validatedOptions = {}; + var validatedOptionsPrepared = {}; + var objectCopy = FRAMEWORK.extend(true, {}, obj); + var inArray = FRAMEWORK.inArray; + var isEmptyObj = FRAMEWORK.isEmptyObject; + var checkObjectProps = function (data, template, diffData, validatedOptions, validatedOptionsPrepared, prevPropName) { + for (var prop in template) { + if (template[LEXICON.hOP](prop) && data[LEXICON.hOP](prop)) { + var isValid = false; + var isDiff = false; + var templateValue = template[prop]; + var templateValueType = type(templateValue); + var templateIsComplex = templateValueType == TYPES.o; + var templateTypes = type(templateValue) != TYPES.a ? [templateValue] : templateValue; + var dataDiffValue = diffData[prop]; + var dataValue = data[prop]; + var dataValueType = type(dataValue); + var propPrefix = prevPropName ? prevPropName + '.' : ''; + var error = "The option \"" + propPrefix + prop + "\" wasn't set, because"; + var errorPossibleTypes = []; + var errorRestrictedStrings = []; + var restrictedStringValuesSplit; + var restrictedStringValuesPossibilitiesSplit; + var isRestrictedValue; + var mainPossibility; + var currType; + var i; + var v; + var j; + + dataDiffValue = dataDiffValue === undefined ? {} : dataDiffValue; + + //if the template has a object as value, it means that the options are complex (verschachtelt) + if (templateIsComplex && dataValueType == TYPES.o) { + validatedOptions[prop] = {}; + validatedOptionsPrepared[prop] = {}; + checkObjectProps(dataValue, templateValue, dataDiffValue, validatedOptions[prop], validatedOptionsPrepared[prop], propPrefix + prop); + FRAMEWORK.each([data, validatedOptions, validatedOptionsPrepared], function (index, value) { + if (isEmptyObj(value[prop])) { + delete value[prop]; + } + }); + } + else if (!templateIsComplex) { + for (i = 0; i < templateTypes[LEXICON.l]; i++) { + currType = templateTypes[i]; + templateValueType = type(currType); + //if currtype is string and starts with restrictedStringPrefix and end with restrictedStringSuffix + isRestrictedValue = templateValueType == TYPES.s && inArray(currType, possibleTemplateTypes) === -1; + if (isRestrictedValue) { + errorPossibleTypes.push(TYPES.s); + + //split it into a array which contains all possible values for example: ["y:yes", "n:no", "m:maybe"] + restrictedStringValuesSplit = currType.split(restrictedStringsSplit); + errorRestrictedStrings = errorRestrictedStrings.concat(restrictedStringValuesSplit); + for (v = 0; v < restrictedStringValuesSplit[LEXICON.l]; v++) { + //split the possible values into their possibiliteis for example: ["y", "yes"] -> the first is always the mainPossibility + restrictedStringValuesPossibilitiesSplit = restrictedStringValuesSplit[v].split(restrictedStringsPossibilitiesSplit); + mainPossibility = restrictedStringValuesPossibilitiesSplit[0]; + for (j = 0; j < restrictedStringValuesPossibilitiesSplit[LEXICON.l]; j++) { + //if any possibility matches with the dataValue, its valid + if (dataValue === restrictedStringValuesPossibilitiesSplit[j]) { + isValid = true; + break; + } + } + if (isValid) + break; + } + } + else { + errorPossibleTypes.push(currType); + + if (dataValueType === currType) { + isValid = true; + break; + } + } + } + + if (isValid) { + isDiff = dataValue !== dataDiffValue; + + if (isDiff) + validatedOptions[prop] = dataValue; + + if (isRestrictedValue ? inArray(dataDiffValue, restrictedStringValuesPossibilitiesSplit) < 0 : isDiff) + validatedOptionsPrepared[prop] = isRestrictedValue ? mainPossibility : dataValue; + } + else if (writeErrors) { + console.warn(error + " it doesn't accept the type [ " + dataValueType.toUpperCase() + " ] with the value of \"" + dataValue + "\".\r\n" + + "Accepted types are: [ " + errorPossibleTypes.join(', ').toUpperCase() + " ]." + + (errorRestrictedStrings[length] > 0 ? "\r\nValid strings are: [ " + errorRestrictedStrings.join(', ').split(restrictedStringsPossibilitiesSplit).join(', ') + " ]." : '')); + } + delete data[prop]; + } + } + } + }; + checkObjectProps(objectCopy, template, diffObj || {}, validatedOptions, validatedOptionsPrepared); + + //add values which aren't specified in the template to the finished validated object to prevent them from being discarded + /* + if(keepForeignProps) { + FRAMEWORK.extend(true, validatedOptions, objectCopy); + FRAMEWORK.extend(true, validatedOptionsPrepared, objectCopy); + } + */ + + if (!isEmptyObj(objectCopy) && writeErrors) + console.warn('The following options are discarded due to invalidity:\r\n' + window.JSON.stringify(objectCopy, null, 2)); + + return { + _default: validatedOptions, + _prepared: validatedOptionsPrepared + }; + } + } + }()); + + /** + * Initializes the object which contains global information about the plugin and each instance of it. + */ + function initOverlayScrollbarsStatics() { + if (!_pluginsGlobals) + _pluginsGlobals = new OverlayScrollbarsGlobals(_pluginsOptions._defaults); + if (!_pluginsAutoUpdateLoop) + _pluginsAutoUpdateLoop = new OverlayScrollbarsAutoUpdateLoop(_pluginsGlobals); + } + + /** + * The global object for the OverlayScrollbars objects. It contains resources which every OverlayScrollbars object needs. This object is initialized only once: if the first OverlayScrollbars object gets initialized. + * @param defaultOptions + * @constructor + */ + function OverlayScrollbarsGlobals(defaultOptions) { + var _base = this; + var strOverflow = 'overflow'; + var strHidden = 'hidden'; + var strScroll = 'scroll'; + var bodyElement = FRAMEWORK('body'); + var scrollbarDummyElement = FRAMEWORK('
'); + var scrollbarDummyElement0 = scrollbarDummyElement[0]; + var dummyContainerChild = FRAMEWORK(scrollbarDummyElement.children('div').eq(0)); + + bodyElement.append(scrollbarDummyElement); + scrollbarDummyElement.hide().show(); //fix IE8 bug (incorrect measuring) + + var nativeScrollbarSize = calcNativeScrollbarSize(scrollbarDummyElement0); + var nativeScrollbarIsOverlaid = { + x: nativeScrollbarSize.x === 0, + y: nativeScrollbarSize.y === 0 + }; + var msie = (function () { + var ua = window.navigator.userAgent; + var strIndexOf = 'indexOf'; + var strSubString = 'substring'; + var msie = ua[strIndexOf]('MSIE '); + var trident = ua[strIndexOf]('Trident/'); + var edge = ua[strIndexOf]('Edge/'); + var rv = ua[strIndexOf]('rv:'); + var result; + var parseIntFunc = parseInt; + + // IE 10 or older => return version number + if (msie > 0) + result = parseIntFunc(ua[strSubString](msie + 5, ua[strIndexOf]('.', msie)), 10); + + // IE 11 => return version number + else if (trident > 0) + result = parseIntFunc(ua[strSubString](rv + 3, ua[strIndexOf]('.', rv)), 10); + + // Edge (IE 12+) => return version number + else if (edge > 0) + result = parseIntFunc(ua[strSubString](edge + 5, ua[strIndexOf]('.', edge)), 10); + + // other browser + return result; + })(); + + FRAMEWORK.extend(_base, { + defaultOptions: defaultOptions, + msie: msie, + autoUpdateLoop: false, + autoUpdateRecommended: !COMPATIBILITY.mO(), + nativeScrollbarSize: nativeScrollbarSize, + nativeScrollbarIsOverlaid: nativeScrollbarIsOverlaid, + nativeScrollbarStyling: (function () { + var result = false; + scrollbarDummyElement.addClass('os-viewport-native-scrollbars-invisible'); + try { + result = (scrollbarDummyElement.css('scrollbar-width') === 'none' && (msie > 9 || !msie)) || window.getComputedStyle(scrollbarDummyElement0, '::-webkit-scrollbar').getPropertyValue('display') === 'none'; + } catch (ex) { } + + //fix opera bug: scrollbar styles will only appear if overflow value is scroll or auto during the activation of the style. + //and set overflow to scroll + //scrollbarDummyElement.css(strOverflow, strHidden).hide().css(strOverflow, strScroll).show(); + //return (scrollbarDummyElement0[LEXICON.oH] - scrollbarDummyElement0[LEXICON.cH]) === 0 && (scrollbarDummyElement0[LEXICON.oW] - scrollbarDummyElement0[LEXICON.cW]) === 0; + + return result; + })(), + overlayScrollbarDummySize: { x: 30, y: 30 }, + cssCalc: (function () { + var dummyStyle = document.createElement('div')[LEXICON.s]; + var strCalc = 'calc'; + var i = -1; + var prop; + + for (; i < VENDORS._cssPrefixes[LEXICON.l]; i++) { + prop = i < 0 ? strCalc : VENDORS._cssPrefixes[i] + strCalc; + dummyStyle.cssText = 'width:' + prop + '(1px);'; + if (dummyStyle[LEXICON.l]) + return prop; + } + return null; + })(), + restrictedMeasuring: (function () { + //https://bugzilla.mozilla.org/show_bug.cgi?id=1439305 + //since 1.11.0 always false -> fixed via CSS (hopefully) + scrollbarDummyElement.css(strOverflow, strHidden); + var scrollSize = { + w: scrollbarDummyElement0[LEXICON.sW], + h: scrollbarDummyElement0[LEXICON.sH] + }; + scrollbarDummyElement.css(strOverflow, 'visible'); + var scrollSize2 = { + w: scrollbarDummyElement0[LEXICON.sW], + h: scrollbarDummyElement0[LEXICON.sH] + }; + return (scrollSize.w - scrollSize2.w) !== 0 || (scrollSize.h - scrollSize2.h) !== 0; + })(), + rtlScrollBehavior: (function () { + scrollbarDummyElement.css({ 'overflow-y': strHidden, 'overflow-x': strScroll, 'direction': 'rtl' }).scrollLeft(0); + var dummyContainerOffset = scrollbarDummyElement.offset(); + var dummyContainerChildOffset = dummyContainerChild.offset(); + //https://github.com/KingSora/OverlayScrollbars/issues/187 + scrollbarDummyElement.scrollLeft(-999); + var dummyContainerChildOffsetAfterScroll = dummyContainerChild.offset(); + return { + //origin direction = determines if the zero scroll position is on the left or right side + //'i' means 'invert' (i === true means that the axis must be inverted to be correct) + //true = on the left side + //false = on the right side + i: dummyContainerOffset.left === dummyContainerChildOffset.left, + //negative = determines if the maximum scroll is positive or negative + //'n' means 'negate' (n === true means that the axis must be negated to be correct) + //true = negative + //false = positive + n: dummyContainerChildOffset.left !== dummyContainerChildOffsetAfterScroll.left + }; + })(), + supportTransform: VENDORS._cssProperty('transform') !== undefined, + supportTransition: VENDORS._cssProperty('transition') !== undefined, + supportPassiveEvents: (function () { + var supportsPassive = false; + try { + window.addEventListener('test', null, Object.defineProperty({}, 'passive', { + get: function () { + supportsPassive = true; + } + })); + } catch (e) { } + return supportsPassive; + })(), + supportResizeObserver: !!COMPATIBILITY.rO(), + supportMutationObserver: !!COMPATIBILITY.mO() + }); + + scrollbarDummyElement.removeAttr(LEXICON.s).remove(); + + //Catch zoom event: + (function () { + if (nativeScrollbarIsOverlaid.x && nativeScrollbarIsOverlaid.y) + return; + + var abs = MATH.abs; + var windowWidth = COMPATIBILITY.wW(); + var windowHeight = COMPATIBILITY.wH(); + var windowDpr = getWindowDPR(); + var onResize = function () { + if (INSTANCES().length > 0) { + var newW = COMPATIBILITY.wW(); + var newH = COMPATIBILITY.wH(); + var deltaW = newW - windowWidth; + var deltaH = newH - windowHeight; + + if (deltaW === 0 && deltaH === 0) + return; + + var deltaWRatio = MATH.round(newW / (windowWidth / 100.0)); + var deltaHRatio = MATH.round(newH / (windowHeight / 100.0)); + var absDeltaW = abs(deltaW); + var absDeltaH = abs(deltaH); + var absDeltaWRatio = abs(deltaWRatio); + var absDeltaHRatio = abs(deltaHRatio); + var newDPR = getWindowDPR(); + + var deltaIsBigger = absDeltaW > 2 && absDeltaH > 2; + var difference = !differenceIsBiggerThanOne(absDeltaWRatio, absDeltaHRatio); + var dprChanged = newDPR !== windowDpr && windowDpr > 0; + var isZoom = deltaIsBigger && difference && dprChanged; + var oldScrollbarSize = _base.nativeScrollbarSize; + var newScrollbarSize; + + if (isZoom) { + bodyElement.append(scrollbarDummyElement); + newScrollbarSize = _base.nativeScrollbarSize = calcNativeScrollbarSize(scrollbarDummyElement[0]); + scrollbarDummyElement.remove(); + if (oldScrollbarSize.x !== newScrollbarSize.x || oldScrollbarSize.y !== newScrollbarSize.y) { + FRAMEWORK.each(INSTANCES(), function () { + if (INSTANCES(this)) + INSTANCES(this).update('zoom'); + }); + } + } + + windowWidth = newW; + windowHeight = newH; + windowDpr = newDPR; + } + }; + + function differenceIsBiggerThanOne(valOne, valTwo) { + var absValOne = abs(valOne); + var absValTwo = abs(valTwo); + return !(absValOne === absValTwo || absValOne + 1 === absValTwo || absValOne - 1 === absValTwo); + } + + function getWindowDPR() { + var dDPI = window.screen.deviceXDPI || 0; + var sDPI = window.screen.logicalXDPI || 1; + return window.devicePixelRatio || (dDPI / sDPI); + } + + FRAMEWORK(window).on('resize', onResize); + })(); + + function calcNativeScrollbarSize(measureElement) { + return { + x: measureElement[LEXICON.oH] - measureElement[LEXICON.cH], + y: measureElement[LEXICON.oW] - measureElement[LEXICON.cW] + }; + } + } + + /** + * The object which manages the auto update loop for all OverlayScrollbars objects. This object is initialized only once: if the first OverlayScrollbars object gets initialized. + * @constructor + */ + function OverlayScrollbarsAutoUpdateLoop(globals) { + var _base = this; + var _inArray = FRAMEWORK.inArray; + var _getNow = COMPATIBILITY.now; + var _strAutoUpdate = 'autoUpdate'; + var _strAutoUpdateInterval = _strAutoUpdate + 'Interval'; + var _strLength = LEXICON.l; + var _loopingInstances = []; + var _loopingInstancesIntervalCache = []; + var _loopIsActive = false; + var _loopIntervalDefault = 33; + var _loopInterval = _loopIntervalDefault; + var _loopTimeOld = _getNow(); + var _loopID; + + + /** + * The auto update loop which will run every 50 milliseconds or less if the update interval of a instance is lower than 50 milliseconds. + */ + var loop = function () { + if (_loopingInstances[_strLength] > 0 && _loopIsActive) { + _loopID = COMPATIBILITY.rAF()(function () { + loop(); + }); + var timeNew = _getNow(); + var timeDelta = timeNew - _loopTimeOld; + var lowestInterval; + var instance; + var instanceOptions; + var instanceAutoUpdateAllowed; + var instanceAutoUpdateInterval; + var now; + + if (timeDelta > _loopInterval) { + _loopTimeOld = timeNew - (timeDelta % _loopInterval); + lowestInterval = _loopIntervalDefault; + for (var i = 0; i < _loopingInstances[_strLength]; i++) { + instance = _loopingInstances[i]; + if (instance !== undefined) { + instanceOptions = instance.options(); + instanceAutoUpdateAllowed = instanceOptions[_strAutoUpdate]; + instanceAutoUpdateInterval = MATH.max(1, instanceOptions[_strAutoUpdateInterval]); + now = _getNow(); + + if ((instanceAutoUpdateAllowed === true || instanceAutoUpdateAllowed === null) && (now - _loopingInstancesIntervalCache[i]) > instanceAutoUpdateInterval) { + instance.update('auto'); + _loopingInstancesIntervalCache[i] = new Date(now += instanceAutoUpdateInterval); + } + + lowestInterval = MATH.max(1, MATH.min(lowestInterval, instanceAutoUpdateInterval)); + } + } + _loopInterval = lowestInterval; + } + } else { + _loopInterval = _loopIntervalDefault; + } + }; + + /** + * Add OverlayScrollbars instance to the auto update loop. Only successful if the instance isn't already added. + * @param instance The instance which shall be updated in a loop automatically. + */ + _base.add = function (instance) { + if (_inArray(instance, _loopingInstances) === -1) { + _loopingInstances.push(instance); + _loopingInstancesIntervalCache.push(_getNow()); + if (_loopingInstances[_strLength] > 0 && !_loopIsActive) { + _loopIsActive = true; + globals.autoUpdateLoop = _loopIsActive; + loop(); + } + } + }; + + /** + * Remove OverlayScrollbars instance from the auto update loop. Only successful if the instance was added before. + * @param instance The instance which shall be updated in a loop automatically. + */ + _base.remove = function (instance) { + var index = _inArray(instance, _loopingInstances); + if (index > -1) { + //remove from loopingInstances list + _loopingInstancesIntervalCache.splice(index, 1); + _loopingInstances.splice(index, 1); + + //correct update loop behavior + if (_loopingInstances[_strLength] === 0 && _loopIsActive) { + _loopIsActive = false; + globals.autoUpdateLoop = _loopIsActive; + if (_loopID !== undefined) { + COMPATIBILITY.cAF()(_loopID); + _loopID = -1; + } + } + } + }; + } + + /** + * A object which manages the scrollbars visibility of the target element. + * @param pluginTargetElement The element from which the scrollbars shall be hidden. + * @param options The custom options. + * @param extensions The custom extensions. + * @param globals + * @param autoUpdateLoop + * @returns {*} + * @constructor + */ + function OverlayScrollbarsInstance(pluginTargetElement, options, extensions, globals, autoUpdateLoop) { + //shortcuts + var type = COMPATIBILITY.type; + var inArray = FRAMEWORK.inArray; + var each = FRAMEWORK.each; + + //make correct instanceof + var _base = new _plugin(); + var _frameworkProto = FRAMEWORK[LEXICON.p]; + + //if passed element is no HTML element: skip and return + if (!isHTMLElement(pluginTargetElement)) + return; + + //if passed element is already initialized: set passed options if there are any and return its instance + if (INSTANCES(pluginTargetElement)) { + var inst = INSTANCES(pluginTargetElement); + inst.options(options); + return inst; + } + + //globals: + var _nativeScrollbarIsOverlaid; + var _overlayScrollbarDummySize; + var _rtlScrollBehavior; + var _autoUpdateRecommended; + var _msieVersion; + var _nativeScrollbarStyling; + var _cssCalc; + var _nativeScrollbarSize; + var _supportTransition; + var _supportTransform; + var _supportPassiveEvents; + var _supportResizeObserver; + var _supportMutationObserver; + var _restrictedMeasuring; + + //general readonly: + var _initialized; + var _destroyed; + var _isTextarea; + var _isBody; + var _documentMixed; + var _domExists; + + //general: + var _isBorderBox; + var _sizeAutoObserverAdded; + var _paddingX; + var _paddingY; + var _borderX; + var _borderY; + var _marginX; + var _marginY; + var _isRTL; + var _sleeping; + var _contentBorderSize = {}; + var _scrollHorizontalInfo = {}; + var _scrollVerticalInfo = {}; + var _viewportSize = {}; + var _nativeScrollbarMinSize = {}; + + //naming: + var _strMinusHidden = '-hidden'; + var _strMarginMinus = 'margin-'; + var _strPaddingMinus = 'padding-'; + var _strBorderMinus = 'border-'; + var _strTop = 'top'; + var _strRight = 'right'; + var _strBottom = 'bottom'; + var _strLeft = 'left'; + var _strMinMinus = 'min-'; + var _strMaxMinus = 'max-'; + var _strWidth = 'width'; + var _strHeight = 'height'; + var _strFloat = 'float'; + var _strEmpty = ''; + var _strAuto = 'auto'; + var _strSync = 'sync'; + var _strScroll = 'scroll'; + var _strHundredPercent = '100%'; + var _strX = 'x'; + var _strY = 'y'; + var _strDot = '.'; + var _strSpace = ' '; + var _strScrollbar = 'scrollbar'; + var _strMinusHorizontal = '-horizontal'; + var _strMinusVertical = '-vertical'; + var _strScrollLeft = _strScroll + 'Left'; + var _strScrollTop = _strScroll + 'Top'; + var _strMouseTouchDownEvent = 'mousedown touchstart'; + var _strMouseTouchUpEvent = 'mouseup touchend touchcancel'; + var _strMouseTouchMoveEvent = 'mousemove touchmove'; + var _strMouseTouchEnter = 'mouseenter'; + var _strMouseTouchLeave = 'mouseleave'; + var _strKeyDownEvent = 'keydown'; + var _strKeyUpEvent = 'keyup'; + var _strSelectStartEvent = 'selectstart'; + var _strTransitionEndEvent = 'transitionend webkitTransitionEnd oTransitionEnd'; + var _strResizeObserverProperty = '__overlayScrollbarsRO__'; + + //class names: + var _cassNamesPrefix = 'os-'; + var _classNameHTMLElement = _cassNamesPrefix + 'html'; + var _classNameHostElement = _cassNamesPrefix + 'host'; + var _classNameHostTextareaElement = _classNameHostElement + '-textarea'; + var _classNameHostScrollbarHorizontalHidden = _classNameHostElement + '-' + _strScrollbar + _strMinusHorizontal + _strMinusHidden; + var _classNameHostScrollbarVerticalHidden = _classNameHostElement + '-' + _strScrollbar + _strMinusVertical + _strMinusHidden; + var _classNameHostTransition = _classNameHostElement + '-transition'; + var _classNameHostRTL = _classNameHostElement + '-rtl'; + var _classNameHostResizeDisabled = _classNameHostElement + '-resize-disabled'; + var _classNameHostScrolling = _classNameHostElement + '-scrolling'; + var _classNameHostOverflow = _classNameHostElement + '-overflow'; + var _classNameHostOverflowX = _classNameHostOverflow + '-x'; + var _classNameHostOverflowY = _classNameHostOverflow + '-y'; + var _classNameTextareaElement = _cassNamesPrefix + 'textarea'; + var _classNameTextareaCoverElement = _classNameTextareaElement + '-cover'; + var _classNamePaddingElement = _cassNamesPrefix + 'padding'; + var _classNameViewportElement = _cassNamesPrefix + 'viewport'; + var _classNameViewportNativeScrollbarsInvisible = _classNameViewportElement + '-native-scrollbars-invisible'; + var _classNameViewportNativeScrollbarsOverlaid = _classNameViewportElement + '-native-scrollbars-overlaid'; + var _classNameContentElement = _cassNamesPrefix + 'content'; + var _classNameContentArrangeElement = _cassNamesPrefix + 'content-arrange'; + var _classNameContentGlueElement = _cassNamesPrefix + 'content-glue'; + var _classNameSizeAutoObserverElement = _cassNamesPrefix + 'size-auto-observer'; + var _classNameResizeObserverElement = _cassNamesPrefix + 'resize-observer'; + var _classNameResizeObserverItemElement = _cassNamesPrefix + 'resize-observer-item'; + var _classNameResizeObserverItemFinalElement = _classNameResizeObserverItemElement + '-final'; + var _classNameTextInherit = _cassNamesPrefix + 'text-inherit'; + var _classNameScrollbar = _cassNamesPrefix + _strScrollbar; + var _classNameScrollbarTrack = _classNameScrollbar + '-track'; + var _classNameScrollbarTrackOff = _classNameScrollbarTrack + '-off'; + var _classNameScrollbarHandle = _classNameScrollbar + '-handle'; + var _classNameScrollbarHandleOff = _classNameScrollbarHandle + '-off'; + var _classNameScrollbarUnusable = _classNameScrollbar + '-unusable'; + var _classNameScrollbarAutoHidden = _classNameScrollbar + '-' + _strAuto + _strMinusHidden; + var _classNameScrollbarCorner = _classNameScrollbar + '-corner'; + var _classNameScrollbarCornerResize = _classNameScrollbarCorner + '-resize'; + var _classNameScrollbarCornerResizeB = _classNameScrollbarCornerResize + '-both'; + var _classNameScrollbarCornerResizeH = _classNameScrollbarCornerResize + _strMinusHorizontal; + var _classNameScrollbarCornerResizeV = _classNameScrollbarCornerResize + _strMinusVertical; + var _classNameScrollbarHorizontal = _classNameScrollbar + _strMinusHorizontal; + var _classNameScrollbarVertical = _classNameScrollbar + _strMinusVertical; + var _classNameDragging = _cassNamesPrefix + 'dragging'; + var _classNameThemeNone = _cassNamesPrefix + 'theme-none'; + var _classNamesDynamicDestroy = [ + _classNameViewportNativeScrollbarsInvisible, + _classNameViewportNativeScrollbarsOverlaid, + _classNameScrollbarTrackOff, + _classNameScrollbarHandleOff, + _classNameScrollbarUnusable, + _classNameScrollbarAutoHidden, + _classNameScrollbarCornerResize, + _classNameScrollbarCornerResizeB, + _classNameScrollbarCornerResizeH, + _classNameScrollbarCornerResizeV, + _classNameDragging].join(_strSpace); + + //callbacks: + var _callbacksInitQeueue = []; + + //attrs viewport shall inherit from target + var _viewportAttrsFromTarget = [LEXICON.ti]; + + //options: + var _defaultOptions; + var _currentOptions; + var _currentPreparedOptions; + + //extensions: + var _extensions = {}; + var _extensionsPrivateMethods = 'added removed on contract'; + + //update + var _lastUpdateTime; + var _swallowedUpdateHints = {}; + var _swallowedUpdateTimeout; + var _swallowUpdateLag = 42; + var _imgs = []; + + //DOM elements: + var _windowElement; + var _documentElement; + var _htmlElement; + var _bodyElement; + var _targetElement; //the target element of this OverlayScrollbars object + var _hostElement; //the host element of this OverlayScrollbars object -> may be the same as targetElement + var _sizeAutoObserverElement; //observes size auto changes + var _sizeObserverElement; //observes size and padding changes + var _paddingElement; //manages the padding + var _viewportElement; //is the viewport of our scrollbar model + var _contentElement; //the element which holds the content + var _contentArrangeElement; //is needed for correct sizing of the content element (only if native scrollbars are overlays) + var _contentGlueElement; //has always the size of the content element + var _textareaCoverElement; //only applied if target is a textarea element. Used for correct size calculation and for prevention of uncontrolled scrolling + var _scrollbarCornerElement; + var _scrollbarHorizontalElement; + var _scrollbarHorizontalTrackElement; + var _scrollbarHorizontalHandleElement; + var _scrollbarVerticalElement; + var _scrollbarVerticalTrackElement; + var _scrollbarVerticalHandleElement; + var _windowElementNative; + var _documentElementNative; + var _targetElementNative; + var _hostElementNative; + var _sizeAutoObserverElementNative; + var _sizeObserverElementNative; + var _paddingElementNative; + var _viewportElementNative; + var _contentElementNative; + + //Cache: + var _hostSizeCache; + var _contentScrollSizeCache; + var _arrangeContentSizeCache; + var _hasOverflowCache; + var _hideOverflowCache; + var _widthAutoCache; + var _heightAutoCache; + var _cssMaxValueCache; + var _cssBoxSizingCache; + var _cssPaddingCache; + var _cssBorderCache; + var _cssMarginCache; + var _cssDirectionCache; + var _cssDirectionDetectedCache; + var _paddingAbsoluteCache; + var _clipAlwaysCache; + var _contentGlueSizeCache; + var _overflowBehaviorCache; + var _overflowAmountCache; + var _ignoreOverlayScrollbarHidingCache; + var _autoUpdateCache; + var _sizeAutoCapableCache; + var _contentElementScrollSizeChangeDetectedCache; + var _hostElementSizeChangeDetectedCache; + var _scrollbarsVisibilityCache; + var _scrollbarsAutoHideCache; + var _scrollbarsClickScrollingCache; + var _scrollbarsDragScrollingCache; + var _resizeCache; + var _normalizeRTLCache; + var _classNameCache; + var _oldClassName; + var _textareaAutoWrappingCache; + var _textareaInfoCache; + var _textareaSizeCache; + var _textareaDynHeightCache; + var _textareaDynWidthCache; + var _bodyMinSizeCache; + var _displayIsHiddenCache; + var _updateAutoCache = {}; + + //MutationObserver: + var _mutationObserverHost; + var _mutationObserverContent; + var _mutationObserverHostCallback; + var _mutationObserverContentCallback; + var _mutationObserversConnected; + var _mutationObserverAttrsTextarea = ['wrap', 'cols', 'rows']; + var _mutationObserverAttrsHost = [LEXICON.i, LEXICON.c, LEXICON.s, 'open'].concat(_viewportAttrsFromTarget); + + //events: + var _destroyEvents = []; + + //textarea: + var _textareaHasFocus; + + //scrollbars: + var _scrollbarsAutoHideTimeoutId; + var _scrollbarsAutoHideMoveTimeoutId; + var _scrollbarsAutoHideDelay; + var _scrollbarsAutoHideNever; + var _scrollbarsAutoHideScroll; + var _scrollbarsAutoHideMove; + var _scrollbarsAutoHideLeave; + var _scrollbarsHandleHovered; + var _scrollbarsHandlesDefineScrollPos; + + //resize + var _resizeNone; + var _resizeBoth; + var _resizeHorizontal; + var _resizeVertical; + + + //==== Event Listener ====// + + /** + * Adds or removes a event listener from the given element. + * @param element The element to which the event listener shall be applied or removed. + * @param eventNames The name(s) of the events. + * @param listener The method which shall be called. + * @param remove True if the handler shall be removed, false or undefined if the handler shall be added. + */ + function setupResponsiveEventListener(element, eventNames, listener, remove, passive) { + var collected = type(eventNames) == TYPES.a && type(listener) == TYPES.a; + var method = remove ? 'removeEventListener' : 'addEventListener'; + var onOff = remove ? 'off' : 'on'; + var events = collected ? false : eventNames.split(_strSpace) + var i = 0; + + if (collected) { + for (; i < eventNames[LEXICON.l]; i++) + setupResponsiveEventListener(element, eventNames[i], listener[i], remove); + } + else { + for (; i < events[LEXICON.l]; i++) { + if (_supportPassiveEvents) + element[0][method](events[i], listener, { passive: passive || false }); + else + element[onOff](events[i], listener); + } + } + } + + + function addDestroyEventListener(element, eventNames, listener, passive) { + setupResponsiveEventListener(element, eventNames, listener, false, passive); + _destroyEvents.push(COMPATIBILITY.bind(setupResponsiveEventListener, 0, element, eventNames, listener, true, passive)); + } + + //==== Resize Observer ====// + + /** + * Adds or removes a resize observer from the given element. + * @param targetElement The element to which the resize observer shall be added or removed. + * @param onElementResizedCallback The callback which is fired every time the resize observer registers a size change or false / undefined if the resizeObserver shall be removed. + */ + function setupResizeObserver(targetElement, onElementResizedCallback) { + if (targetElement) { + var resizeObserver = COMPATIBILITY.rO(); + var strAnimationStartEvent = 'animationstart mozAnimationStart webkitAnimationStart MSAnimationStart'; + var strChildNodes = 'childNodes'; + var constScroll = 3333333; + var callback = function () { + targetElement[_strScrollTop](constScroll)[_strScrollLeft](_isRTL ? _rtlScrollBehavior.n ? -constScroll : _rtlScrollBehavior.i ? 0 : constScroll : constScroll); + onElementResizedCallback(); + }; + //add resize observer: + if (onElementResizedCallback) { + if (_supportResizeObserver) { + var element = targetElement.addClass('observed').append(generateDiv(_classNameResizeObserverElement)).contents()[0]; + var observer = element[_strResizeObserverProperty] = new resizeObserver(callback); + observer.observe(element); + } + else { + if (_msieVersion > 9 || !_autoUpdateRecommended) { + targetElement.prepend( + generateDiv(_classNameResizeObserverElement, + generateDiv({ c: _classNameResizeObserverItemElement, dir: 'ltr' }, + generateDiv(_classNameResizeObserverItemElement, + generateDiv(_classNameResizeObserverItemFinalElement) + ) + + generateDiv(_classNameResizeObserverItemElement, + generateDiv({ c: _classNameResizeObserverItemFinalElement, style: 'width: 200%; height: 200%' }) + ) + ) + ) + ); + + var observerElement = targetElement[0][strChildNodes][0][strChildNodes][0]; + var shrinkElement = FRAMEWORK(observerElement[strChildNodes][1]); + var expandElement = FRAMEWORK(observerElement[strChildNodes][0]); + var expandElementChild = FRAMEWORK(expandElement[0][strChildNodes][0]); + var widthCache = observerElement[LEXICON.oW]; + var heightCache = observerElement[LEXICON.oH]; + var isDirty; + var rAFId; + var currWidth; + var currHeight; + var factor = 2; + var nativeScrollbarSize = globals.nativeScrollbarSize; //care don't make changes to this object!!! + var reset = function () { + /* + var sizeResetWidth = observerElement[LEXICON.oW] + nativeScrollbarSize.x * factor + nativeScrollbarSize.y * factor + _overlayScrollbarDummySize.x + _overlayScrollbarDummySize.y; + var sizeResetHeight = observerElement[LEXICON.oH] + nativeScrollbarSize.x * factor + nativeScrollbarSize.y * factor + _overlayScrollbarDummySize.x + _overlayScrollbarDummySize.y; + var expandChildCSS = {}; + expandChildCSS[_strWidth] = sizeResetWidth; + expandChildCSS[_strHeight] = sizeResetHeight; + expandElementChild.css(expandChildCSS); + + + expandElement[_strScrollLeft](sizeResetWidth)[_strScrollTop](sizeResetHeight); + shrinkElement[_strScrollLeft](sizeResetWidth)[_strScrollTop](sizeResetHeight); + */ + expandElement[_strScrollLeft](constScroll)[_strScrollTop](constScroll); + shrinkElement[_strScrollLeft](constScroll)[_strScrollTop](constScroll); + }; + var onResized = function () { + rAFId = 0; + if (!isDirty) + return; + + widthCache = currWidth; + heightCache = currHeight; + callback(); + }; + var onScroll = function (event) { + currWidth = observerElement[LEXICON.oW]; + currHeight = observerElement[LEXICON.oH]; + isDirty = currWidth != widthCache || currHeight != heightCache; + + if (event && isDirty && !rAFId) { + COMPATIBILITY.cAF()(rAFId); + rAFId = COMPATIBILITY.rAF()(onResized); + } + else if (!event) + onResized(); + + reset(); + if (event) { + COMPATIBILITY.prvD(event); + COMPATIBILITY.stpP(event); + } + return false; + }; + var expandChildCSS = {}; + var observerElementCSS = {}; + + setTopRightBottomLeft(observerElementCSS, _strEmpty, [ + -((nativeScrollbarSize.y + 1) * factor), + nativeScrollbarSize.x * -factor, + nativeScrollbarSize.y * -factor, + -((nativeScrollbarSize.x + 1) * factor) + ]); + + FRAMEWORK(observerElement).css(observerElementCSS); + expandElement.on(_strScroll, onScroll); + shrinkElement.on(_strScroll, onScroll); + targetElement.on(strAnimationStartEvent, function () { + onScroll(false); + }); + //lets assume that the divs will never be that large and a constant value is enough + expandChildCSS[_strWidth] = constScroll; + expandChildCSS[_strHeight] = constScroll; + expandElementChild.css(expandChildCSS); + + reset(); + } + else { + var attachEvent = _documentElementNative.attachEvent; + var isIE = _msieVersion !== undefined; + if (attachEvent) { + targetElement.prepend(generateDiv(_classNameResizeObserverElement)); + findFirst(targetElement, _strDot + _classNameResizeObserverElement)[0].attachEvent('onresize', callback); + } + else { + var obj = _documentElementNative.createElement(TYPES.o); + obj.setAttribute(LEXICON.ti, '-1'); + obj.setAttribute(LEXICON.c, _classNameResizeObserverElement); + obj.onload = function () { + var wnd = this.contentDocument.defaultView; + wnd.addEventListener('resize', callback); + wnd.document.documentElement.style.display = 'none'; + }; + obj.type = 'text/html'; + if (isIE) + targetElement.prepend(obj); + obj.data = 'about:blank'; + if (!isIE) + targetElement.prepend(obj); + targetElement.on(strAnimationStartEvent, callback); + } + } + } + + if (targetElement[0] === _sizeObserverElementNative) { + var directionChanged = function () { + var dir = _hostElement.css('direction'); + var css = {}; + var scrollLeftValue = 0; + var result = false; + if (dir !== _cssDirectionDetectedCache) { + if (dir === 'ltr') { + css[_strLeft] = 0; + css[_strRight] = _strAuto; + scrollLeftValue = constScroll; + } + else { + css[_strLeft] = _strAuto; + css[_strRight] = 0; + scrollLeftValue = _rtlScrollBehavior.n ? -constScroll : _rtlScrollBehavior.i ? 0 : constScroll; + } + //execution order is important for IE!!! + _sizeObserverElement.children().eq(0).css(css); + _sizeObserverElement[_strScrollLeft](scrollLeftValue)[_strScrollTop](constScroll); + _cssDirectionDetectedCache = dir; + result = true; + } + return result; + }; + directionChanged(); + addDestroyEventListener(targetElement, _strScroll, function (event) { + if (directionChanged()) + update(); + COMPATIBILITY.prvD(event); + COMPATIBILITY.stpP(event); + return false; + }); + } + } + //remove resize observer: + else { + if (_supportResizeObserver) { + var element = targetElement.contents()[0]; + var resizeObserverObj = element[_strResizeObserverProperty]; + if (resizeObserverObj) { + resizeObserverObj.disconnect(); + delete element[_strResizeObserverProperty]; + } + } + else { + remove(targetElement.children(_strDot + _classNameResizeObserverElement).eq(0)); + } + } + } + } + + /** + * Freezes or unfreezes the given resize observer. + * @param targetElement The element to which the target resize observer is applied. + * @param freeze True if the resize observer shall be frozen, false otherwise. + + function freezeResizeObserver(targetElement, freeze) { + if (targetElement !== undefined) { + if(freeze) { + if (_supportResizeObserver) { + var element = targetElement.contents()[0]; + element[_strResizeObserverProperty].unobserve(element); + } + else { + targetElement = targetElement.children(_strDot + _classNameResizeObserverElement).eq(0); + var w = targetElement.css(_strWidth); + var h = targetElement.css(_strHeight); + var css = {}; + css[_strWidth] = w; + css[_strHeight] = h; + targetElement.css(css); + } + } + else { + if (_supportResizeObserver) { + var element = targetElement.contents()[0]; + element[_strResizeObserverProperty].observe(element); + } + else { + var css = { }; + css[_strHeight] = _strEmpty; + css[_strWidth] = _strEmpty; + targetElement.children(_strDot + _classNameResizeObserverElement).eq(0).css(css); + } + } + } + } + */ + + + //==== Mutation Observers ====// + + /** + * Creates MutationObservers for the host and content Element if they are supported. + */ + function createMutationObservers() { + if (_supportMutationObserver) { + var mutationObserverContentLag = 11; + var mutationObserver = COMPATIBILITY.mO(); + var contentLastUpdate = COMPATIBILITY.now(); + var mutationTarget; + var mutationAttrName; + var contentTimeout; + var now; + var sizeAuto; + var action; + + _mutationObserverHostCallback = function (mutations) { + var doUpdate = false; + var mutation; + var mutatedAttrs = []; + + if (_initialized && !_sleeping) { + each(mutations, function () { + mutation = this; + mutationTarget = mutation.target; + mutationAttrName = mutation.attributeName; + + if(!doUpdate) { + if (mutationAttrName === LEXICON.c) + doUpdate = hostClassNamesChanged(mutation.oldValue, mutationTarget.className); + else if (mutationAttrName === LEXICON.s) + doUpdate = mutation.oldValue !== mutationTarget[LEXICON.s].cssText; + else + doUpdate = true; + } + + mutatedAttrs.push(mutationAttrName); + }); + + updateViewportAttrsFromTarget(mutatedAttrs); + + if (doUpdate) + _base.update(_strAuto); + } + return doUpdate; + }; + _mutationObserverContentCallback = function (mutations) { + var doUpdate = false; + var mutation; + + if (_initialized && !_sleeping) { + each(mutations, function () { + mutation = this; + doUpdate = isUnknownMutation(mutation); + return !doUpdate; + }); + + if (doUpdate) { + now = COMPATIBILITY.now(); + sizeAuto = (_heightAutoCache || _widthAutoCache); + action = function () { + if (!_destroyed) { + contentLastUpdate = now; + + //if cols, rows or wrap attr was changed + if (_isTextarea) + textareaUpdate(); + + if (sizeAuto) + update(); + else + _base.update(_strAuto); + } + }; + clearTimeout(contentTimeout); + if (mutationObserverContentLag <= 0 || now - contentLastUpdate > mutationObserverContentLag || !sizeAuto) + action(); + else + contentTimeout = setTimeout(action, mutationObserverContentLag); + } + } + return doUpdate; + } + + _mutationObserverHost = new mutationObserver(_mutationObserverHostCallback); + _mutationObserverContent = new mutationObserver(_mutationObserverContentCallback); + } + } + + /** + * Connects the MutationObservers if they are supported. + */ + function connectMutationObservers() { + if (_supportMutationObserver && !_mutationObserversConnected) { + _mutationObserverHost.observe(_hostElementNative, { + attributes: true, + attributeOldValue: true, + attributeFilter: _mutationObserverAttrsHost + }); + + _mutationObserverContent.observe(_isTextarea ? _targetElementNative : _contentElementNative, { + attributes: true, + attributeOldValue: true, + subtree: !_isTextarea, + childList: !_isTextarea, + characterData: !_isTextarea, + attributeFilter: _isTextarea ? _mutationObserverAttrsTextarea : _mutationObserverAttrsHost + }); + + _mutationObserversConnected = true; + } + } + + /** + * Disconnects the MutationObservers if they are supported. + */ + function disconnectMutationObservers() { + if (_supportMutationObserver && _mutationObserversConnected) { + _mutationObserverHost.disconnect(); + _mutationObserverContent.disconnect(); + + _mutationObserversConnected = false; + } + } + + + //==== Events of elements ====// + + /** + * This method gets called every time the host element gets resized. IMPORTANT: Padding changes are detected too!! + * It refreshes the hostResizedEventArgs and the hostSizeResizeCache. + * If there are any size changes, the update method gets called. + */ + function hostOnResized() { + if (!_sleeping) { + var changed; + var hostSize = { + w: _sizeObserverElementNative[LEXICON.sW], + h: _sizeObserverElementNative[LEXICON.sH] + }; + + changed = checkCache(hostSize, _hostElementSizeChangeDetectedCache); + _hostElementSizeChangeDetectedCache = hostSize; + if (changed) + update({ _hostSizeChanged: true }); + } + } + + /** + * The mouse enter event of the host element. This event is only needed for the autoHide feature. + */ + function hostOnMouseEnter() { + if (_scrollbarsAutoHideLeave) + refreshScrollbarsAutoHide(true); + } + + /** + * The mouse leave event of the host element. This event is only needed for the autoHide feature. + */ + function hostOnMouseLeave() { + if (_scrollbarsAutoHideLeave && !_bodyElement.hasClass(_classNameDragging)) + refreshScrollbarsAutoHide(false); + } + + /** + * The mouse move event of the host element. This event is only needed for the autoHide "move" feature. + */ + function hostOnMouseMove() { + if (_scrollbarsAutoHideMove) { + refreshScrollbarsAutoHide(true); + clearTimeout(_scrollbarsAutoHideMoveTimeoutId); + _scrollbarsAutoHideMoveTimeoutId = setTimeout(function () { + if (_scrollbarsAutoHideMove && !_destroyed) + refreshScrollbarsAutoHide(false); + }, 100); + } + } + + /** + * Prevents text from deselection if attached to the document element on the mousedown event of a DOM element. + * @param event The select start event. + */ + function documentOnSelectStart(event) { + COMPATIBILITY.prvD(event); + return false; + } + + /** + * A callback which will be called after a img element has downloaded its src asynchronous. + */ + function imgOnLoad() { + update({ _contentSizeChanged: true }); + } + + /** + * Adds or removes mouse & touch events of the host element. (for handling auto-hiding of the scrollbars) + * @param destroy Indicates whether the events shall be added or removed. + */ + function setupHostMouseTouchEvents(destroy) { + setupResponsiveEventListener(_hostElement, + _strMouseTouchMoveEvent, + hostOnMouseMove, + (_scrollbarsAutoHideMove ? destroy : true), true); + setupResponsiveEventListener(_hostElement, + [_strMouseTouchEnter, _strMouseTouchLeave], + [hostOnMouseEnter, hostOnMouseLeave], + (_scrollbarsAutoHideMove ? true : destroy), true); + + //if the plugin is initialized and the mouse is over the host element, make the scrollbars visible + if (!_initialized && !destroy) + _hostElement.one('mouseover', hostOnMouseEnter); + } + + + //==== Update Detection ====// + + /** + * Measures the min width and min height of the body element and refreshes the related cache. + * @returns {boolean} True if the min width or min height has changed, false otherwise. + */ + function bodyMinSizeChanged() { + var bodyMinSize = {}; + if (_isBody && _contentArrangeElement) { + bodyMinSize.w = parseToZeroOrNumber(_contentArrangeElement.css(_strMinMinus + _strWidth)); + bodyMinSize.h = parseToZeroOrNumber(_contentArrangeElement.css(_strMinMinus + _strHeight)); + bodyMinSize.c = checkCache(bodyMinSize, _bodyMinSizeCache); + bodyMinSize.f = true; //flag for "measured at least once" + } + _bodyMinSizeCache = bodyMinSize; + return !!bodyMinSize.c; + } + + /** + * Returns true if the class names really changed (new class without plugin host prefix) + * @param oldCassNames The old ClassName string. + * @param newClassNames The new ClassName string. + * @returns {boolean} True if the class names has really changed, false otherwise. + */ + function hostClassNamesChanged(oldCassNames, newClassNames) { + var currClasses = (newClassNames !== undefined && newClassNames !== null) ? newClassNames.split(_strSpace) : _strEmpty; + var oldClasses = (oldCassNames !== undefined && oldCassNames !== null) ? oldCassNames.split(_strSpace) : _strEmpty; + if (currClasses === _strEmpty && oldClasses === _strEmpty) + return false; + var diff = getArrayDifferences(oldClasses, currClasses); + var changed = false; + var oldClassNames = _oldClassName !== undefined && _oldClassName !== null ? _oldClassName.split(_strSpace) : [_strEmpty]; + var currClassNames = _classNameCache !== undefined && _classNameCache !== null ? _classNameCache.split(_strSpace) : [_strEmpty]; + + //remove none theme from diff list to prevent update + var idx = inArray(_classNameThemeNone, diff); + var curr; + var i; + var v; + var o; + var c; + + if (idx > -1) + diff.splice(idx, 1); + + for (i = 0; i < diff.length; i++) { + curr = diff[i]; + if (curr.indexOf(_classNameHostElement) !== 0) { + o = true; + c = true; + for (v = 0; v < oldClassNames.length; v++) { + if (curr === oldClassNames[v]) { + o = false; + break; + } + } + for (v = 0; v < currClassNames.length; v++) { + if (curr === currClassNames[v]) { + c = false; + break; + } + } + if (o && c) { + changed = true; + break; + } + } + + } + return changed; + } + + /** + * Returns true if the given mutation is not from a from the plugin generated element. If the target element is a textarea the mutation is always unknown. + * @param mutation The mutation which shall be checked. + * @returns {boolean} True if the mutation is from a unknown element, false otherwise. + */ + function isUnknownMutation(mutation) { + var attributeName = mutation.attributeName; + var mutationTarget = mutation.target; + var mutationType = mutation.type; + var strClosest = 'closest'; + + if (mutationTarget === _contentElementNative) + return attributeName === null; + if (mutationType === 'attributes' && (attributeName === LEXICON.c || attributeName === LEXICON.s) && !_isTextarea) { + //ignore className changes by the plugin + if (attributeName === LEXICON.c && FRAMEWORK(mutationTarget).hasClass(_classNameHostElement)) + return hostClassNamesChanged(mutation.oldValue, mutationTarget.getAttribute(LEXICON.c)); + + //only do it of browser support it natively + if (typeof mutationTarget[strClosest] != TYPES.f) + return true; + if (mutationTarget[strClosest](_strDot + _classNameResizeObserverElement) !== null || + mutationTarget[strClosest](_strDot + _classNameScrollbar) !== null || + mutationTarget[strClosest](_strDot + _classNameScrollbarCorner) !== null) + return false; + } + return true; + } + + /** + * Returns true if the content size was changed since the last time this method was called. + * @returns {boolean} True if the content size was changed, false otherwise. + */ + function updateAutoContentSizeChanged() { + if (_sleeping) + return false; + + var contentMeasureElement = getContentMeasureElement(); + var textareaValueLength = _isTextarea && _widthAutoCache && !_textareaAutoWrappingCache ? _targetElement.val().length : 0; + var setCSS = !_mutationObserversConnected && _widthAutoCache && !_isTextarea; + var css = {}; + var float; + var bodyMinSizeC; + var changed; + var contentElementScrollSize; + + if (setCSS) { + float = _contentElement.css(_strFloat); + css[_strFloat] = _isRTL ? _strRight : _strLeft; + css[_strWidth] = _strAuto; + _contentElement.css(css); + } + contentElementScrollSize = { + w: contentMeasureElement[LEXICON.sW] + textareaValueLength, + h: contentMeasureElement[LEXICON.sH] + textareaValueLength + }; + if (setCSS) { + css[_strFloat] = float; + css[_strWidth] = _strHundredPercent; + _contentElement.css(css); + } + + bodyMinSizeC = bodyMinSizeChanged(); + changed = checkCache(contentElementScrollSize, _contentElementScrollSizeChangeDetectedCache); + + _contentElementScrollSizeChangeDetectedCache = contentElementScrollSize; + + return changed || bodyMinSizeC; + } + + /** + * Returns true when a attribute which the MutationObserver would observe has changed. + * @returns {boolean} True if one of the attributes which a MutationObserver would observe has changed, false or undefined otherwise. + */ + function meaningfulAttrsChanged() { + if (_sleeping || _mutationObserversConnected) + return; + + var elem; + var curr; + var cache; + var changedAttrs = []; + var checks = [ + { + _elem: _hostElement, + _attrs: _mutationObserverAttrsHost.concat(':visible') + }, + { + _elem: _isTextarea ? _targetElement : undefined, + _attrs: _mutationObserverAttrsTextarea + } + ]; + + each(checks, function (index, check) { + elem = check._elem; + if (elem) { + each(check._attrs, function (index, attr) { + curr = attr.charAt(0) === ':' ? elem.is(attr) : elem.attr(attr); + cache = _updateAutoCache[attr]; + + if(checkCache(curr, cache)) { + changedAttrs.push(attr); + } + + _updateAutoCache[attr] = curr; + }); + } + }); + + updateViewportAttrsFromTarget(changedAttrs); + + return changedAttrs[LEXICON.l] > 0; + } + + /** + * Checks is a CSS Property of a child element is affecting the scroll size of the content. + * @param propertyName The CSS property name. + * @returns {boolean} True if the property is affecting the content scroll size, false otherwise. + */ + function isSizeAffectingCSSProperty(propertyName) { + if (!_initialized) + return true; + var flexGrow = 'flex-grow'; + var flexShrink = 'flex-shrink'; + var flexBasis = 'flex-basis'; + var affectingPropsX = [ + _strWidth, + _strMinMinus + _strWidth, + _strMaxMinus + _strWidth, + _strMarginMinus + _strLeft, + _strMarginMinus + _strRight, + _strLeft, + _strRight, + 'font-weight', + 'word-spacing', + flexGrow, + flexShrink, + flexBasis + ]; + var affectingPropsXContentBox = [ + _strPaddingMinus + _strLeft, + _strPaddingMinus + _strRight, + _strBorderMinus + _strLeft + _strWidth, + _strBorderMinus + _strRight + _strWidth + ]; + var affectingPropsY = [ + _strHeight, + _strMinMinus + _strHeight, + _strMaxMinus + _strHeight, + _strMarginMinus + _strTop, + _strMarginMinus + _strBottom, + _strTop, + _strBottom, + 'line-height', + flexGrow, + flexShrink, + flexBasis + ]; + var affectingPropsYContentBox = [ + _strPaddingMinus + _strTop, + _strPaddingMinus + _strBottom, + _strBorderMinus + _strTop + _strWidth, + _strBorderMinus + _strBottom + _strWidth + ]; + var _strS = 's'; + var _strVS = 'v-s'; + var checkX = _overflowBehaviorCache.x === _strS || _overflowBehaviorCache.x === _strVS; + var checkY = _overflowBehaviorCache.y === _strS || _overflowBehaviorCache.y === _strVS; + var sizeIsAffected = false; + var checkPropertyName = function (arr, name) { + for (var i = 0; i < arr[LEXICON.l]; i++) { + if (arr[i] === name) + return true; + } + return false; + }; + + if (checkY) { + sizeIsAffected = checkPropertyName(affectingPropsY, propertyName); + if (!sizeIsAffected && !_isBorderBox) + sizeIsAffected = checkPropertyName(affectingPropsYContentBox, propertyName); + } + if (checkX && !sizeIsAffected) { + sizeIsAffected = checkPropertyName(affectingPropsX, propertyName); + if (!sizeIsAffected && !_isBorderBox) + sizeIsAffected = checkPropertyName(affectingPropsXContentBox, propertyName); + } + return sizeIsAffected; + } + + + //==== Update ====// + + /** + * Sets the attribute values of the viewport element to the values from the target element. + * The value of a attribute is only set if the attribute is whitelisted. + * @attrs attrs The array of attributes which shall be set or undefined if all whitelisted shall be set. + */ + function updateViewportAttrsFromTarget(attrs) { + attrs = attrs || _viewportAttrsFromTarget; + each(attrs, function (index, attr) { + if (COMPATIBILITY.inA(attr, _viewportAttrsFromTarget) > -1) { + var targetAttr = _targetElement.attr(attr); + if(type(targetAttr) == TYPES.s) { + _viewportElement.attr(attr, targetAttr); + } + else { + _viewportElement.removeAttr(attr); + } + } + }); + } + + /** + * Updates the variables and size of the textarea element, and manages the scroll on new line or new character. + */ + function textareaUpdate() { + if (!_sleeping) { + var wrapAttrOff = !_textareaAutoWrappingCache; + var minWidth = _viewportSize.w; + var minHeight = _viewportSize.h; + var css = {}; + var doMeasure = _widthAutoCache || wrapAttrOff; + var origWidth; + var width; + var origHeight; + var height; + + //reset min size + css[_strMinMinus + _strWidth] = _strEmpty; + css[_strMinMinus + _strHeight] = _strEmpty; + + //set width auto + css[_strWidth] = _strAuto; + _targetElement.css(css); + + //measure width + origWidth = _targetElementNative[LEXICON.oW]; + width = doMeasure ? MATH.max(origWidth, _targetElementNative[LEXICON.sW] - 1) : 1; + /*width += (_widthAutoCache ? _marginX + (!_isBorderBox ? wrapAttrOff ? 0 : _paddingX + _borderX : 0) : 0);*/ + + //set measured width + css[_strWidth] = _widthAutoCache ? _strAuto /*width*/ : _strHundredPercent; + css[_strMinMinus + _strWidth] = _strHundredPercent; + + //set height auto + css[_strHeight] = _strAuto; + _targetElement.css(css); + + //measure height + origHeight = _targetElementNative[LEXICON.oH]; + height = MATH.max(origHeight, _targetElementNative[LEXICON.sH] - 1); + + //append correct size values + css[_strWidth] = width; + css[_strHeight] = height; + _textareaCoverElement.css(css); + + //apply min width / min height to prevent textarea collapsing + css[_strMinMinus + _strWidth] = minWidth /*+ (!_isBorderBox && _widthAutoCache ? _paddingX + _borderX : 0)*/; + css[_strMinMinus + _strHeight] = minHeight /*+ (!_isBorderBox && _heightAutoCache ? _paddingY + _borderY : 0)*/; + _targetElement.css(css); + + return { + _originalWidth: origWidth, + _originalHeight: origHeight, + _dynamicWidth: width, + _dynamicHeight: height + }; + } + } + + /** + * Updates the plugin and DOM to the current options. + * This method should only be called if a update is 100% required. + * @param updateHints A objects which contains hints for this update: + * { + * _hostSizeChanged : boolean, + * _contentSizeChanged : boolean, + * _force : boolean, == preventSwallowing + * _changedOptions : { }, == preventSwallowing && preventSleep + * } + */ + function update(updateHints) { + clearTimeout(_swallowedUpdateTimeout); + updateHints = updateHints || {}; + _swallowedUpdateHints._hostSizeChanged |= updateHints._hostSizeChanged; + _swallowedUpdateHints._contentSizeChanged |= updateHints._contentSizeChanged; + _swallowedUpdateHints._force |= updateHints._force; + + var now = COMPATIBILITY.now(); + var hostSizeChanged = !!_swallowedUpdateHints._hostSizeChanged; + var contentSizeChanged = !!_swallowedUpdateHints._contentSizeChanged; + var force = !!_swallowedUpdateHints._force; + var changedOptions = updateHints._changedOptions; + var swallow = _swallowUpdateLag > 0 && _initialized && !_destroyed && !force && !changedOptions && (now - _lastUpdateTime) < _swallowUpdateLag && (!_heightAutoCache && !_widthAutoCache); + var displayIsHidden; + + if (swallow) + _swallowedUpdateTimeout = setTimeout(update, _swallowUpdateLag); + + //abort update due to: + //destroyed + //swallowing + //sleeping + //host is hidden or has false display + if (_destroyed || swallow || (_sleeping && !changedOptions) || (_initialized && !force && (displayIsHidden = _hostElement.is(':hidden'))) || _hostElement.css('display') === 'inline') + return; + + _lastUpdateTime = now; + _swallowedUpdateHints = {}; + + //if scrollbar styling is possible and native scrollbars aren't overlaid the scrollbar styling will be applied which hides the native scrollbars completely. + if (_nativeScrollbarStyling && !(_nativeScrollbarIsOverlaid.x && _nativeScrollbarIsOverlaid.y)) { + //native scrollbars are hidden, so change the values to zero + _nativeScrollbarSize.x = 0; + _nativeScrollbarSize.y = 0; + } + else { + //refresh native scrollbar size (in case of zoom) + _nativeScrollbarSize = extendDeep({}, globals.nativeScrollbarSize); + } + + // Scrollbar padding is needed for firefox, because firefox hides scrollbar automatically if the size of the div is too small. + // The calculation: [scrollbar size +3 *3] + // (+3 because of possible decoration e.g. borders, margins etc., but only if native scrollbar is NOT a overlaid scrollbar) + // (*3 because (1)increase / (2)decrease -button and (3)resize handle) + _nativeScrollbarMinSize = { + x: (_nativeScrollbarSize.x + (_nativeScrollbarIsOverlaid.x ? 0 : 3)) * 3, + y: (_nativeScrollbarSize.y + (_nativeScrollbarIsOverlaid.y ? 0 : 3)) * 3 + }; + + //changedOptions = changedOptions || { }; + //freezeResizeObserver(_sizeObserverElement, true); + //freezeResizeObserver(_sizeAutoObserverElement, true); + + var checkCacheAutoForce = function () { + return checkCache.apply(this, [].slice.call(arguments).concat([force])); + }; + + //save current scroll offset + var currScroll = { + x: _viewportElement[_strScrollLeft](), + y: _viewportElement[_strScrollTop]() + }; + + var currentPreparedOptionsScrollbars = _currentPreparedOptions.scrollbars; + var currentPreparedOptionsTextarea = _currentPreparedOptions.textarea; + + //scrollbars visibility: + var scrollbarsVisibility = currentPreparedOptionsScrollbars.visibility; + var scrollbarsVisibilityChanged = checkCacheAutoForce(scrollbarsVisibility, _scrollbarsVisibilityCache); + + //scrollbars autoHide: + var scrollbarsAutoHide = currentPreparedOptionsScrollbars.autoHide; + var scrollbarsAutoHideChanged = checkCacheAutoForce(scrollbarsAutoHide, _scrollbarsAutoHideCache); + + //scrollbars click scrolling + var scrollbarsClickScrolling = currentPreparedOptionsScrollbars.clickScrolling; + var scrollbarsClickScrollingChanged = checkCacheAutoForce(scrollbarsClickScrolling, _scrollbarsClickScrollingCache); + + //scrollbars drag scrolling + var scrollbarsDragScrolling = currentPreparedOptionsScrollbars.dragScrolling; + var scrollbarsDragScrollingChanged = checkCacheAutoForce(scrollbarsDragScrolling, _scrollbarsDragScrollingCache); + + //className + var className = _currentPreparedOptions.className; + var classNameChanged = checkCacheAutoForce(className, _classNameCache); + + //resize + var resize = _currentPreparedOptions.resize; + var resizeChanged = checkCacheAutoForce(resize, _resizeCache) && !_isBody; //body can't be resized since the window itself acts as resize possibility. + + //paddingAbsolute + var paddingAbsolute = _currentPreparedOptions.paddingAbsolute; + var paddingAbsoluteChanged = checkCacheAutoForce(paddingAbsolute, _paddingAbsoluteCache); + + //clipAlways + var clipAlways = _currentPreparedOptions.clipAlways; + var clipAlwaysChanged = checkCacheAutoForce(clipAlways, _clipAlwaysCache); + + //sizeAutoCapable + var sizeAutoCapable = _currentPreparedOptions.sizeAutoCapable && !_isBody; //body can never be size auto, because it shall be always as big as the viewport. + var sizeAutoCapableChanged = checkCacheAutoForce(sizeAutoCapable, _sizeAutoCapableCache); + + //showNativeScrollbars + var ignoreOverlayScrollbarHiding = _currentPreparedOptions.nativeScrollbarsOverlaid.showNativeScrollbars; + var ignoreOverlayScrollbarHidingChanged = checkCacheAutoForce(ignoreOverlayScrollbarHiding, _ignoreOverlayScrollbarHidingCache); + + //autoUpdate + var autoUpdate = _currentPreparedOptions.autoUpdate; + var autoUpdateChanged = checkCacheAutoForce(autoUpdate, _autoUpdateCache); + + //overflowBehavior + var overflowBehavior = _currentPreparedOptions.overflowBehavior; + var overflowBehaviorChanged = checkCacheAutoForce(overflowBehavior, _overflowBehaviorCache, force); + + //dynWidth: + var textareaDynWidth = currentPreparedOptionsTextarea.dynWidth; + var textareaDynWidthChanged = checkCacheAutoForce(_textareaDynWidthCache, textareaDynWidth); + + //dynHeight: + var textareaDynHeight = currentPreparedOptionsTextarea.dynHeight; + var textareaDynHeightChanged = checkCacheAutoForce(_textareaDynHeightCache, textareaDynHeight); + + //scrollbars visibility + _scrollbarsAutoHideNever = scrollbarsAutoHide === 'n'; + _scrollbarsAutoHideScroll = scrollbarsAutoHide === 's'; + _scrollbarsAutoHideMove = scrollbarsAutoHide === 'm'; + _scrollbarsAutoHideLeave = scrollbarsAutoHide === 'l'; + + //scrollbars autoHideDelay + _scrollbarsAutoHideDelay = currentPreparedOptionsScrollbars.autoHideDelay; + + //old className + _oldClassName = _classNameCache; + + //resize + _resizeNone = resize === 'n'; + _resizeBoth = resize === 'b'; + _resizeHorizontal = resize === 'h'; + _resizeVertical = resize === 'v'; + + //normalizeRTL + _normalizeRTLCache = _currentPreparedOptions.normalizeRTL; + + //ignore overlay scrollbar hiding + ignoreOverlayScrollbarHiding = ignoreOverlayScrollbarHiding && (_nativeScrollbarIsOverlaid.x && _nativeScrollbarIsOverlaid.y); + + //refresh options cache + _scrollbarsVisibilityCache = scrollbarsVisibility; + _scrollbarsAutoHideCache = scrollbarsAutoHide; + _scrollbarsClickScrollingCache = scrollbarsClickScrolling; + _scrollbarsDragScrollingCache = scrollbarsDragScrolling; + _classNameCache = className; + _resizeCache = resize; + _paddingAbsoluteCache = paddingAbsolute; + _clipAlwaysCache = clipAlways; + _sizeAutoCapableCache = sizeAutoCapable; + _ignoreOverlayScrollbarHidingCache = ignoreOverlayScrollbarHiding; + _autoUpdateCache = autoUpdate; + _overflowBehaviorCache = extendDeep({}, overflowBehavior); + _textareaDynWidthCache = textareaDynWidth; + _textareaDynHeightCache = textareaDynHeight; + _hasOverflowCache = _hasOverflowCache || { x: false, y: false }; + + //set correct class name to the host element + if (classNameChanged) { + removeClass(_hostElement, _oldClassName + _strSpace + _classNameThemeNone); + addClass(_hostElement, className !== undefined && className !== null && className.length > 0 ? className : _classNameThemeNone); + } + + //set correct auto Update + if (autoUpdateChanged) { + if (autoUpdate === true) { + disconnectMutationObservers(); + autoUpdateLoop.add(_base); + } + else if (autoUpdate === null) { + if (_autoUpdateRecommended) { + disconnectMutationObservers(); + autoUpdateLoop.add(_base); + } + else { + autoUpdateLoop.remove(_base); + connectMutationObservers(); + } + } + else { + autoUpdateLoop.remove(_base); + connectMutationObservers(); + } + } + + //activate or deactivate size auto capability + if (sizeAutoCapableChanged) { + if (sizeAutoCapable) { + if (!_contentGlueElement) { + _contentGlueElement = FRAMEWORK(generateDiv(_classNameContentGlueElement)); + _paddingElement.before(_contentGlueElement); + } + else { + _contentGlueElement.show(); + } + if (_sizeAutoObserverAdded) { + _sizeAutoObserverElement.show(); + } + else { + _sizeAutoObserverElement = FRAMEWORK(generateDiv(_classNameSizeAutoObserverElement)); + _sizeAutoObserverElementNative = _sizeAutoObserverElement[0]; + + _contentGlueElement.before(_sizeAutoObserverElement); + var oldSize = { w: -1, h: -1 }; + setupResizeObserver(_sizeAutoObserverElement, function () { + var newSize = { + w: _sizeAutoObserverElementNative[LEXICON.oW], + h: _sizeAutoObserverElementNative[LEXICON.oH] + }; + if (checkCache(newSize, oldSize)) { + if (_initialized && (_heightAutoCache && newSize.h > 0) || (_widthAutoCache && newSize.w > 0)) { + update(); + } + else if (_initialized && (!_heightAutoCache && newSize.h === 0) || (!_widthAutoCache && newSize.w === 0)) { + update(); + } + } + oldSize = newSize; + }); + _sizeAutoObserverAdded = true; + //fix heightAuto detector bug if height is fixed but contentHeight is 0. + //the probability this bug will ever happen is very very low, thats why its ok if we use calc which isn't supported in IE8. + if (_cssCalc !== null) + _sizeAutoObserverElement.css(_strHeight, _cssCalc + '(100% + 1px)'); + } + } + else { + if (_sizeAutoObserverAdded) + _sizeAutoObserverElement.hide(); + if (_contentGlueElement) + _contentGlueElement.hide(); + } + } + + //if force, update all resizeObservers too + if (force) { + _sizeObserverElement.find('*').trigger(_strScroll); + if (_sizeAutoObserverAdded) + _sizeAutoObserverElement.find('*').trigger(_strScroll); + } + + //display hidden: + displayIsHidden = displayIsHidden === undefined ? _hostElement.is(':hidden') : displayIsHidden; + var displayIsHiddenChanged = checkCacheAutoForce(displayIsHidden, _displayIsHiddenCache); + + //textarea AutoWrapping: + var textareaAutoWrapping = _isTextarea ? _targetElement.attr('wrap') !== 'off' : false; + var textareaAutoWrappingChanged = checkCacheAutoForce(textareaAutoWrapping, _textareaAutoWrappingCache); + + //detect direction: + var cssDirection = _hostElement.css('direction'); + var cssDirectionChanged = checkCacheAutoForce(cssDirection, _cssDirectionCache); + + //detect box-sizing: + var boxSizing = _hostElement.css('box-sizing'); + var boxSizingChanged = checkCacheAutoForce(boxSizing, _cssBoxSizingCache); + + //detect padding: + var padding = { + c: force, + t: parseToZeroOrNumber(_hostElement.css(_strPaddingMinus + _strTop)), + r: parseToZeroOrNumber(_hostElement.css(_strPaddingMinus + _strRight)), + b: parseToZeroOrNumber(_hostElement.css(_strPaddingMinus + _strBottom)), + l: parseToZeroOrNumber(_hostElement.css(_strPaddingMinus + _strLeft)) + }; + + //width + height auto detecting var: + var sizeAutoObserverElementBCRect; + //exception occurs in IE8 sometimes (unknown exception) + try { + sizeAutoObserverElementBCRect = _sizeAutoObserverAdded ? _sizeAutoObserverElementNative[LEXICON.bCR]() : null; + } catch (ex) { + return; + } + + _isRTL = cssDirection === 'rtl'; + _isBorderBox = (boxSizing === 'border-box'); + var isRTLLeft = _isRTL ? _strLeft : _strRight; + var isRTLRight = _isRTL ? _strRight : _strLeft; + + //detect width auto: + var widthAutoResizeDetection = false; + var widthAutoObserverDetection = (_sizeAutoObserverAdded && (_hostElement.css(_strFloat) !== 'none' /*|| _isTextarea */)) ? (MATH.round(sizeAutoObserverElementBCRect.right - sizeAutoObserverElementBCRect.left) === 0) && (!paddingAbsolute ? (_hostElementNative[LEXICON.cW] - _paddingX) > 0 : true) : false; + if (sizeAutoCapable && !widthAutoObserverDetection) { + var tmpCurrHostWidth = _hostElementNative[LEXICON.oW]; + var tmpCurrContentGlueWidth = _contentGlueElement.css(_strWidth); + _contentGlueElement.css(_strWidth, _strAuto); + + var tmpNewHostWidth = _hostElementNative[LEXICON.oW]; + _contentGlueElement.css(_strWidth, tmpCurrContentGlueWidth); + widthAutoResizeDetection = tmpCurrHostWidth !== tmpNewHostWidth; + if (!widthAutoResizeDetection) { + _contentGlueElement.css(_strWidth, tmpCurrHostWidth + 1); + tmpNewHostWidth = _hostElementNative[LEXICON.oW]; + _contentGlueElement.css(_strWidth, tmpCurrContentGlueWidth); + widthAutoResizeDetection = tmpCurrHostWidth !== tmpNewHostWidth; + } + } + var widthAuto = (widthAutoObserverDetection || widthAutoResizeDetection) && sizeAutoCapable && !displayIsHidden; + var widthAutoChanged = checkCacheAutoForce(widthAuto, _widthAutoCache); + var wasWidthAuto = !widthAuto && _widthAutoCache; + + //detect height auto: + var heightAuto = _sizeAutoObserverAdded && sizeAutoCapable && !displayIsHidden ? (MATH.round(sizeAutoObserverElementBCRect.bottom - sizeAutoObserverElementBCRect.top) === 0) /* && (!paddingAbsolute && (_msieVersion > 9 || !_msieVersion) ? true : true) */ : false; + var heightAutoChanged = checkCacheAutoForce(heightAuto, _heightAutoCache); + var wasHeightAuto = !heightAuto && _heightAutoCache; + + //detect border: + //we need the border only if border box and auto size + var strMinusWidth = '-' + _strWidth; + var updateBorderX = (widthAuto && _isBorderBox) || !_isBorderBox; + var updateBorderY = (heightAuto && _isBorderBox) || !_isBorderBox; + var border = { + c: force, + t: updateBorderY ? parseToZeroOrNumber(_hostElement.css(_strBorderMinus + _strTop + strMinusWidth), true) : 0, + r: updateBorderX ? parseToZeroOrNumber(_hostElement.css(_strBorderMinus + _strRight + strMinusWidth), true) : 0, + b: updateBorderY ? parseToZeroOrNumber(_hostElement.css(_strBorderMinus + _strBottom + strMinusWidth), true) : 0, + l: updateBorderX ? parseToZeroOrNumber(_hostElement.css(_strBorderMinus + _strLeft + strMinusWidth), true) : 0 + }; + + //detect margin: + var margin = { + c: force, + t: parseToZeroOrNumber(_hostElement.css(_strMarginMinus + _strTop)), + r: parseToZeroOrNumber(_hostElement.css(_strMarginMinus + _strRight)), + b: parseToZeroOrNumber(_hostElement.css(_strMarginMinus + _strBottom)), + l: parseToZeroOrNumber(_hostElement.css(_strMarginMinus + _strLeft)) + }; + + //detect css max width & height: + var cssMaxValue = { + h: String(_hostElement.css(_strMaxMinus + _strHeight)), + w: String(_hostElement.css(_strMaxMinus + _strWidth)) + }; + + //vars to apply correct css + var contentElementCSS = {}; + var contentGlueElementCSS = {}; + + //funcs + var getHostSize = function () { + //has to be clientSize because offsetSize respect borders + return { + w: _hostElementNative[LEXICON.cW], + h: _hostElementNative[LEXICON.cH] + }; + }; + var getViewportSize = function () { + //viewport size is padding container because it never has padding, margin and a border + //determine zoom rounding error -> sometimes scrollWidth/Height is smaller than clientWidth/Height + //if this happens add the difference to the viewportSize to compensate the rounding error + return { + w: _paddingElementNative[LEXICON.oW] + MATH.max(0, _contentElementNative[LEXICON.cW] - _contentElementNative[LEXICON.sW]), + h: _paddingElementNative[LEXICON.oH] + MATH.max(0, _contentElementNative[LEXICON.cH] - _contentElementNative[LEXICON.sH]) + }; + }; + + //set info for padding + var paddingAbsoluteX = _paddingX = padding.l + padding.r; + var paddingAbsoluteY = _paddingY = padding.t + padding.b; + paddingAbsoluteX *= paddingAbsolute ? 1 : 0; + paddingAbsoluteY *= paddingAbsolute ? 1 : 0; + padding.c = checkCacheAutoForce(padding, _cssPaddingCache); + + //set info for border + _borderX = border.l + border.r; + _borderY = border.t + border.b; + border.c = checkCacheAutoForce(border, _cssBorderCache); + + //set info for margin + _marginX = margin.l + margin.r; + _marginY = margin.t + margin.b; + margin.c = checkCacheAutoForce(margin, _cssMarginCache); + + //set info for css max value + cssMaxValue.ih = parseToZeroOrNumber(cssMaxValue.h); //ih = integer height + cssMaxValue.iw = parseToZeroOrNumber(cssMaxValue.w); //iw = integer width + cssMaxValue.ch = cssMaxValue.h.indexOf('px') > -1; //ch = correct height + cssMaxValue.cw = cssMaxValue.w.indexOf('px') > -1; //cw = correct width + cssMaxValue.c = checkCacheAutoForce(cssMaxValue, _cssMaxValueCache); + + //refresh cache + _displayIsHiddenCache = displayIsHidden; + _textareaAutoWrappingCache = textareaAutoWrapping; + _cssDirectionCache = cssDirection; + _cssBoxSizingCache = boxSizing; + _widthAutoCache = widthAuto; + _heightAutoCache = heightAuto; + _cssPaddingCache = padding; + _cssBorderCache = border; + _cssMarginCache = margin; + _cssMaxValueCache = cssMaxValue; + + //IEFix direction changed + if (cssDirectionChanged && _sizeAutoObserverAdded) + _sizeAutoObserverElement.css(_strFloat, isRTLRight); + + //apply padding: + if (padding.c || cssDirectionChanged || paddingAbsoluteChanged || widthAutoChanged || heightAutoChanged || boxSizingChanged || sizeAutoCapableChanged) { + var paddingElementCSS = {}; + var textareaCSS = {}; + setTopRightBottomLeft(contentGlueElementCSS, _strMarginMinus, [-padding.t, -padding.r, -padding.b, -padding.l]); + if (paddingAbsolute) { + setTopRightBottomLeft(paddingElementCSS, _strEmpty, [padding.t, padding.r, padding.b, padding.l]); + if (_isTextarea) + setTopRightBottomLeft(textareaCSS, _strPaddingMinus); + else + setTopRightBottomLeft(contentElementCSS, _strPaddingMinus); + } + else { + setTopRightBottomLeft(paddingElementCSS, _strEmpty); + if (_isTextarea) + setTopRightBottomLeft(textareaCSS, _strPaddingMinus, [padding.t, padding.r, padding.b, padding.l]); + else + setTopRightBottomLeft(contentElementCSS, _strPaddingMinus, [padding.t, padding.r, padding.b, padding.l]); + } + _paddingElement.css(paddingElementCSS); + _targetElement.css(textareaCSS); + } + + //viewport size is padding container because it never has padding, margin and a border. + _viewportSize = getViewportSize(); + + //update Textarea + var textareaSize = _isTextarea ? textareaUpdate() : false; + var textareaSizeChanged = _isTextarea && checkCacheAutoForce(textareaSize, _textareaSizeCache); + var textareaDynOrigSize = _isTextarea && textareaSize ? { + w: textareaDynWidth ? textareaSize._dynamicWidth : textareaSize._originalWidth, + h: textareaDynHeight ? textareaSize._dynamicHeight : textareaSize._originalHeight + } : {}; + _textareaSizeCache = textareaSize; + + //fix height auto / width auto in cooperation with current padding & boxSizing behavior: + if (heightAuto && (heightAutoChanged || paddingAbsoluteChanged || boxSizingChanged || cssMaxValue.c || padding.c || border.c)) { + /* + if (cssMaxValue.ch) + contentElementCSS[_strMaxMinus + _strHeight] = + (cssMaxValue.ch ? (cssMaxValue.ih - paddingAbsoluteY + (_isBorderBox ? -_borderY : _paddingY)) + : _strEmpty); + */ + contentElementCSS[_strHeight] = _strAuto; + } + else if (heightAutoChanged || paddingAbsoluteChanged) { + contentElementCSS[_strMaxMinus + _strHeight] = _strEmpty; + contentElementCSS[_strHeight] = _strHundredPercent; + } + if (widthAuto && (widthAutoChanged || paddingAbsoluteChanged || boxSizingChanged || cssMaxValue.c || padding.c || border.c || cssDirectionChanged)) { + /* + if (cssMaxValue.cw) + contentElementCSS[_strMaxMinus + _strWidth] = + (cssMaxValue.cw ? (cssMaxValue.iw - paddingAbsoluteX + (_isBorderBox ? -_borderX : _paddingX)) + + (_nativeScrollbarIsOverlaid.y ? _overlayScrollbarDummySize.y : 0) + : _strEmpty); + */ + contentElementCSS[_strWidth] = _strAuto; + contentGlueElementCSS[_strMaxMinus + _strWidth] = _strHundredPercent; //IE Fix + } + else if (widthAutoChanged || paddingAbsoluteChanged) { + contentElementCSS[_strMaxMinus + _strWidth] = _strEmpty; + contentElementCSS[_strWidth] = _strHundredPercent; + contentElementCSS[_strFloat] = _strEmpty; + contentGlueElementCSS[_strMaxMinus + _strWidth] = _strEmpty; //IE Fix + } + if (widthAuto) { + if (!cssMaxValue.cw) + contentElementCSS[_strMaxMinus + _strWidth] = _strEmpty; + //textareaDynOrigSize.w || _strAuto :: doesnt works because applied margin will shift width + contentGlueElementCSS[_strWidth] = _strAuto; + + contentElementCSS[_strWidth] = _strAuto; + contentElementCSS[_strFloat] = isRTLRight; + } + else { + contentGlueElementCSS[_strWidth] = _strEmpty; + } + if (heightAuto) { + if (!cssMaxValue.ch) + contentElementCSS[_strMaxMinus + _strHeight] = _strEmpty; + //textareaDynOrigSize.h || _contentElementNative[LEXICON.cH] :: use for anti scroll jumping + contentGlueElementCSS[_strHeight] = textareaDynOrigSize.h || _contentElementNative[LEXICON.cH]; + } + else { + contentGlueElementCSS[_strHeight] = _strEmpty; + } + if (sizeAutoCapable) + _contentGlueElement.css(contentGlueElementCSS); + _contentElement.css(contentElementCSS); + + //CHECKPOINT HERE ~ + contentElementCSS = {}; + contentGlueElementCSS = {}; + + //if [content(host) client / scroll size, or target element direction, or content(host) max-sizes] changed, or force is true + if (hostSizeChanged || contentSizeChanged || textareaSizeChanged || cssDirectionChanged || boxSizingChanged || paddingAbsoluteChanged || widthAutoChanged || widthAuto || heightAutoChanged || heightAuto || cssMaxValue.c || ignoreOverlayScrollbarHidingChanged || overflowBehaviorChanged || clipAlwaysChanged || resizeChanged || scrollbarsVisibilityChanged || scrollbarsAutoHideChanged || scrollbarsDragScrollingChanged || scrollbarsClickScrollingChanged || textareaDynWidthChanged || textareaDynHeightChanged || textareaAutoWrappingChanged) { + var strOverflow = 'overflow'; + var strOverflowX = strOverflow + '-x'; + var strOverflowY = strOverflow + '-y'; + var strHidden = 'hidden'; + var strVisible = 'visible'; + + //Reset the viewport (very important for natively overlaid scrollbars and zoom change + //don't change the overflow prop as it is very expensive and affects performance !A LOT! + if(!_nativeScrollbarStyling) { + var viewportElementResetCSS = {}; + var resetXTmp = _hasOverflowCache.y && _hideOverflowCache.ys && !ignoreOverlayScrollbarHiding ? (_nativeScrollbarIsOverlaid.y ? _viewportElement.css(isRTLLeft) : -_nativeScrollbarSize.y) : 0; + var resetBottomTmp = _hasOverflowCache.x && _hideOverflowCache.xs && !ignoreOverlayScrollbarHiding ? (_nativeScrollbarIsOverlaid.x ? _viewportElement.css(_strBottom) : -_nativeScrollbarSize.x) : 0; + setTopRightBottomLeft(viewportElementResetCSS, _strEmpty); + _viewportElement.css(viewportElementResetCSS); + } + + //measure several sizes: + var contentMeasureElement = getContentMeasureElement(); + //in Firefox content element has to have overflow hidden, else element margins aren't calculated properly, this element prevents this bug, but only if scrollbars aren't overlaid + var contentSize = { + //use clientSize because natively overlaidScrollbars add borders + w: textareaDynOrigSize.w || contentMeasureElement[LEXICON.cW], + h: textareaDynOrigSize.h || contentMeasureElement[LEXICON.cH] + }; + var scrollSize = { + w: contentMeasureElement[LEXICON.sW], + h: contentMeasureElement[LEXICON.sH] + }; + + //apply the correct viewport style and measure viewport size + if(!_nativeScrollbarStyling) { + viewportElementResetCSS[_strBottom] = wasHeightAuto ? _strEmpty : resetBottomTmp; + viewportElementResetCSS[isRTLLeft] = wasWidthAuto ? _strEmpty : resetXTmp; + _viewportElement.css(viewportElementResetCSS); + } + _viewportSize = getViewportSize(); + + //measure and correct several sizes + var hostSize = getHostSize(); + var contentGlueSize = { + //client/scrollSize + AbsolutePadding -> because padding is only applied to the paddingElement if its absolute, so you have to add it manually + //hostSize is clientSize -> so padding should be added manually, right? FALSE! Because content glue is inside hostElement, so we don't have to worry about padding + w: MATH.max((widthAuto ? contentSize.w : scrollSize.w) + paddingAbsoluteX, hostSize.w), + h: MATH.max((heightAuto ? contentSize.h : scrollSize.h) + paddingAbsoluteY, hostSize.h) + }; + contentGlueSize.c = checkCacheAutoForce(contentGlueSize, _contentGlueSizeCache); + _contentGlueSizeCache = contentGlueSize; + + //apply correct contentGlue size + if (sizeAutoCapable) { + //size contentGlue correctly to make sure the element has correct size if the sizing switches to auto + if (contentGlueSize.c || (heightAuto || widthAuto)) { + contentGlueElementCSS[_strWidth] = contentGlueSize.w; + contentGlueElementCSS[_strHeight] = contentGlueSize.h; + + //textarea-sizes are already calculated correctly at this point + if (!_isTextarea) { + contentSize = { + //use clientSize because natively overlaidScrollbars add borders + w: contentMeasureElement[LEXICON.cW], + h: contentMeasureElement[LEXICON.cH] + }; + } + } + var textareaCoverCSS = {}; + var setContentGlueElementCSSfunction = function (horizontal) { + var scrollbarVars = getScrollbarVars(horizontal); + var wh = scrollbarVars._w_h; + var strWH = scrollbarVars._width_height; + var autoSize = horizontal ? widthAuto : heightAuto; + var borderSize = horizontal ? _borderX : _borderY; + var paddingSize = horizontal ? _paddingX : _paddingY; + var marginSize = horizontal ? _marginX : _marginY; + var maxSize = contentGlueElementCSS[strWH] + (_isBorderBox ? borderSize : -paddingSize); + + //make contentGlue size -1 if element is not auto sized, to make sure that a resize event happens when the element shrinks + if (!autoSize || (!autoSize && border.c)) + contentGlueElementCSS[strWH] = hostSize[wh] - (_isBorderBox ? 0 : paddingSize + borderSize) - 1 - marginSize; + + //if size is auto and host is same size as max size, make content glue size +1 to make sure size changes will be detected + if (autoSize && cssMaxValue['c' + wh] && cssMaxValue['i' + wh] === maxSize) + contentGlueElementCSS[strWH] = maxSize + (_isBorderBox ? 0 : paddingSize) + 1; + + //if size is auto and host is smaller than size as min size, make content glue size -1 to make sure size changes will be detected (this is only needed if padding is 0) + if (autoSize && (contentSize[wh] < _viewportSize[wh]) && (horizontal && _isTextarea ? !textareaAutoWrapping : true)) { + if (_isTextarea) + textareaCoverCSS[strWH] = parseToZeroOrNumber(_textareaCoverElement.css(strWH)) - 1; + contentGlueElementCSS[strWH] -= 1; + } + + //make sure content glue size is at least 1 + if (contentSize[wh] > 0) + contentGlueElementCSS[strWH] = MATH.max(1, contentGlueElementCSS[strWH]); + }; + setContentGlueElementCSSfunction(true); + setContentGlueElementCSSfunction(false); + + if (_isTextarea) + _textareaCoverElement.css(textareaCoverCSS); + _contentGlueElement.css(contentGlueElementCSS); + } + if (widthAuto) + contentElementCSS[_strWidth] = _strHundredPercent; + if (widthAuto && !_isBorderBox && !_mutationObserversConnected) + contentElementCSS[_strFloat] = 'none'; + + //apply and reset content style + _contentElement.css(contentElementCSS); + contentElementCSS = {}; + + //measure again, but this time all correct sizes: + var contentScrollSize = { + w: contentMeasureElement[LEXICON.sW], + h: contentMeasureElement[LEXICON.sH], + }; + contentScrollSize.c = contentSizeChanged = checkCacheAutoForce(contentScrollSize, _contentScrollSizeCache); + _contentScrollSizeCache = contentScrollSize; + + //refresh viewport size after correct measuring + _viewportSize = getViewportSize(); + + hostSize = getHostSize(); + hostSizeChanged = checkCacheAutoForce(hostSize, _hostSizeCache); + _hostSizeCache = hostSize; + + var hideOverflowForceTextarea = _isTextarea && (_viewportSize.w === 0 || _viewportSize.h === 0); + var previousOverflowAmount = _overflowAmountCache; + var overflowBehaviorIsVS = {}; + var overflowBehaviorIsVH = {}; + var overflowBehaviorIsS = {}; + var overflowAmount = {}; + var hasOverflow = {}; + var hideOverflow = {}; + var canScroll = {}; + var viewportRect = _paddingElementNative[LEXICON.bCR](); + var setOverflowVariables = function (horizontal) { + var scrollbarVars = getScrollbarVars(horizontal); + var scrollbarVarsInverted = getScrollbarVars(!horizontal); + var xyI = scrollbarVarsInverted._x_y; + var xy = scrollbarVars._x_y; + var wh = scrollbarVars._w_h; + var widthHeight = scrollbarVars._width_height; + var scrollMax = _strScroll + scrollbarVars._Left_Top + 'Max'; + var fractionalOverflowAmount = viewportRect[widthHeight] ? MATH.abs(viewportRect[widthHeight] - _viewportSize[wh]) : 0; + var checkFractionalOverflowAmount = previousOverflowAmount && previousOverflowAmount[xy] > 0 && _viewportElementNative[scrollMax] === 0; + overflowBehaviorIsVS[xy] = overflowBehavior[xy] === 'v-s'; + overflowBehaviorIsVH[xy] = overflowBehavior[xy] === 'v-h'; + overflowBehaviorIsS[xy] = overflowBehavior[xy] === 's'; + overflowAmount[xy] = MATH.max(0, MATH.round((contentScrollSize[wh] - _viewportSize[wh]) * 100) / 100); + overflowAmount[xy] *= (hideOverflowForceTextarea || (checkFractionalOverflowAmount && fractionalOverflowAmount > 0 && fractionalOverflowAmount < 1)) ? 0 : 1; + hasOverflow[xy] = overflowAmount[xy] > 0; + + //hideOverflow: + //x || y : true === overflow is hidden by "overflow: scroll" OR "overflow: hidden" + //xs || ys : true === overflow is hidden by "overflow: scroll" + hideOverflow[xy] = overflowBehaviorIsVS[xy] || overflowBehaviorIsVH[xy] ? (hasOverflow[xyI] && !overflowBehaviorIsVS[xyI] && !overflowBehaviorIsVH[xyI]) : hasOverflow[xy]; + hideOverflow[xy + 's'] = hideOverflow[xy] ? (overflowBehaviorIsS[xy] || overflowBehaviorIsVS[xy]) : false; + + canScroll[xy] = hasOverflow[xy] && hideOverflow[xy + 's']; + }; + setOverflowVariables(true); + setOverflowVariables(false); + + overflowAmount.c = checkCacheAutoForce(overflowAmount, _overflowAmountCache); + _overflowAmountCache = overflowAmount; + hasOverflow.c = checkCacheAutoForce(hasOverflow, _hasOverflowCache); + _hasOverflowCache = hasOverflow; + hideOverflow.c = checkCacheAutoForce(hideOverflow, _hideOverflowCache); + _hideOverflowCache = hideOverflow; + + //if native scrollbar is overlay at x OR y axis, prepare DOM + if (_nativeScrollbarIsOverlaid.x || _nativeScrollbarIsOverlaid.y) { + var borderDesign = 'px solid transparent'; + var contentArrangeElementCSS = {}; + var arrangeContent = {}; + var arrangeChanged = force; + var setContentElementCSS; + + if (hasOverflow.x || hasOverflow.y) { + arrangeContent.w = _nativeScrollbarIsOverlaid.y && hasOverflow.y ? contentScrollSize.w + _overlayScrollbarDummySize.y : _strEmpty; + arrangeContent.h = _nativeScrollbarIsOverlaid.x && hasOverflow.x ? contentScrollSize.h + _overlayScrollbarDummySize.x : _strEmpty; + arrangeChanged = checkCacheAutoForce(arrangeContent, _arrangeContentSizeCache); + _arrangeContentSizeCache = arrangeContent; + } + + if (hasOverflow.c || hideOverflow.c || contentScrollSize.c || cssDirectionChanged || widthAutoChanged || heightAutoChanged || widthAuto || heightAuto || ignoreOverlayScrollbarHidingChanged) { + contentElementCSS[_strMarginMinus + isRTLRight] = contentElementCSS[_strBorderMinus + isRTLRight] = _strEmpty; + setContentElementCSS = function (horizontal) { + var scrollbarVars = getScrollbarVars(horizontal); + var scrollbarVarsInverted = getScrollbarVars(!horizontal); + var xy = scrollbarVars._x_y; + var strDirection = horizontal ? _strBottom : isRTLLeft; + var invertedAutoSize = horizontal ? heightAuto : widthAuto; + + if (_nativeScrollbarIsOverlaid[xy] && hasOverflow[xy] && hideOverflow[xy + 's']) { + contentElementCSS[_strMarginMinus + strDirection] = invertedAutoSize ? (ignoreOverlayScrollbarHiding ? _strEmpty : _overlayScrollbarDummySize[xy]) : _strEmpty; + contentElementCSS[_strBorderMinus + strDirection] = ((horizontal ? !invertedAutoSize : true) && !ignoreOverlayScrollbarHiding) ? (_overlayScrollbarDummySize[xy] + borderDesign) : _strEmpty; + } + else { + arrangeContent[scrollbarVarsInverted._w_h] = + contentElementCSS[_strMarginMinus + strDirection] = + contentElementCSS[_strBorderMinus + strDirection] = _strEmpty; + arrangeChanged = true; + } + }; + + if (_nativeScrollbarStyling) { + if (ignoreOverlayScrollbarHiding) + removeClass(_viewportElement, _classNameViewportNativeScrollbarsInvisible); + else + addClass(_viewportElement, _classNameViewportNativeScrollbarsInvisible); + } + else { + setContentElementCSS(true); + setContentElementCSS(false); + } + } + if (ignoreOverlayScrollbarHiding) { + arrangeContent.w = arrangeContent.h = _strEmpty; + arrangeChanged = true; + } + if (arrangeChanged && !_nativeScrollbarStyling) { + contentArrangeElementCSS[_strWidth] = hideOverflow.y ? arrangeContent.w : _strEmpty; + contentArrangeElementCSS[_strHeight] = hideOverflow.x ? arrangeContent.h : _strEmpty; + + if (!_contentArrangeElement) { + _contentArrangeElement = FRAMEWORK(generateDiv(_classNameContentArrangeElement)); + _viewportElement.prepend(_contentArrangeElement); + } + _contentArrangeElement.css(contentArrangeElementCSS); + } + _contentElement.css(contentElementCSS); + } + + var viewportElementCSS = {}; + var paddingElementCSS = {}; + var setViewportCSS; + if (hostSizeChanged || hasOverflow.c || hideOverflow.c || contentScrollSize.c || overflowBehaviorChanged || boxSizingChanged || ignoreOverlayScrollbarHidingChanged || cssDirectionChanged || clipAlwaysChanged || heightAutoChanged) { + viewportElementCSS[isRTLRight] = _strEmpty; + setViewportCSS = function (horizontal) { + var scrollbarVars = getScrollbarVars(horizontal); + var scrollbarVarsInverted = getScrollbarVars(!horizontal); + var xy = scrollbarVars._x_y; + var XY = scrollbarVars._X_Y; + var strDirection = horizontal ? _strBottom : isRTLLeft; + + var reset = function () { + viewportElementCSS[strDirection] = _strEmpty; + _contentBorderSize[scrollbarVarsInverted._w_h] = 0; + }; + if (hasOverflow[xy] && hideOverflow[xy + 's']) { + viewportElementCSS[strOverflow + XY] = _strScroll; + if (ignoreOverlayScrollbarHiding || _nativeScrollbarStyling) { + reset(); + } + else { + viewportElementCSS[strDirection] = -(_nativeScrollbarIsOverlaid[xy] ? _overlayScrollbarDummySize[xy] : _nativeScrollbarSize[xy]); + _contentBorderSize[scrollbarVarsInverted._w_h] = _nativeScrollbarIsOverlaid[xy] ? _overlayScrollbarDummySize[scrollbarVarsInverted._x_y] : 0; + } + } else { + viewportElementCSS[strOverflow + XY] = _strEmpty; + reset(); + } + }; + setViewportCSS(true); + setViewportCSS(false); + + // if the scroll container is too small and if there is any overflow with no overlay scrollbar (and scrollbar styling isn't possible), + // make viewport element greater in size (Firefox hide Scrollbars fix) + // because firefox starts hiding scrollbars on too small elements + // with this behavior the overflow calculation may be incorrect or the scrollbars would appear suddenly + // https://bugzilla.mozilla.org/show_bug.cgi?id=292284 + if (!_nativeScrollbarStyling + && (_viewportSize.h < _nativeScrollbarMinSize.x || _viewportSize.w < _nativeScrollbarMinSize.y) + && ((hasOverflow.x && hideOverflow.x && !_nativeScrollbarIsOverlaid.x) || (hasOverflow.y && hideOverflow.y && !_nativeScrollbarIsOverlaid.y))) { + viewportElementCSS[_strPaddingMinus + _strTop] = _nativeScrollbarMinSize.x; + viewportElementCSS[_strMarginMinus + _strTop] = -_nativeScrollbarMinSize.x; + + viewportElementCSS[_strPaddingMinus + isRTLRight] = _nativeScrollbarMinSize.y; + viewportElementCSS[_strMarginMinus + isRTLRight] = -_nativeScrollbarMinSize.y; + } + else { + viewportElementCSS[_strPaddingMinus + _strTop] = + viewportElementCSS[_strMarginMinus + _strTop] = + viewportElementCSS[_strPaddingMinus + isRTLRight] = + viewportElementCSS[_strMarginMinus + isRTLRight] = _strEmpty; + } + viewportElementCSS[_strPaddingMinus + isRTLLeft] = + viewportElementCSS[_strMarginMinus + isRTLLeft] = _strEmpty; + + //if there is any overflow (x OR y axis) and this overflow shall be hidden, make overflow hidden, else overflow visible + if ((hasOverflow.x && hideOverflow.x) || (hasOverflow.y && hideOverflow.y) || hideOverflowForceTextarea) { + //only hide if is Textarea + if (_isTextarea && hideOverflowForceTextarea) { + paddingElementCSS[strOverflowX] = + paddingElementCSS[strOverflowY] = strHidden; + } + } + else { + if (!clipAlways || (overflowBehaviorIsVH.x || overflowBehaviorIsVS.x || overflowBehaviorIsVH.y || overflowBehaviorIsVS.y)) { + //only un-hide if Textarea + if (_isTextarea) { + paddingElementCSS[strOverflowX] = + paddingElementCSS[strOverflowY] = _strEmpty; + } + viewportElementCSS[strOverflowX] = + viewportElementCSS[strOverflowY] = strVisible; + } + } + + _paddingElement.css(paddingElementCSS); + _viewportElement.css(viewportElementCSS); + viewportElementCSS = {}; + + //force soft redraw in webkit because without the scrollbars will may appear because DOM wont be redrawn under special conditions + if ((hasOverflow.c || boxSizingChanged || widthAutoChanged || heightAutoChanged) && !(_nativeScrollbarIsOverlaid.x && _nativeScrollbarIsOverlaid.y)) { + var elementStyle = _contentElementNative[LEXICON.s]; + var dump; + elementStyle.webkitTransform = 'scale(1)'; + elementStyle.display = 'run-in'; + dump = _contentElementNative[LEXICON.oH]; + elementStyle.display = _strEmpty; //|| dump; //use dump to prevent it from deletion if minify + elementStyle.webkitTransform = _strEmpty; + } + /* + //force hard redraw in webkit if native overlaid scrollbars shall appear + if (ignoreOverlayScrollbarHidingChanged && ignoreOverlayScrollbarHiding) { + _hostElement.hide(); + var dump = _hostElementNative[LEXICON.oH]; + _hostElement.show(); + } + */ + } + + //change to direction RTL and width auto Bugfix in Webkit + //without this fix, the DOM still thinks the scrollbar is LTR and thus the content is shifted to the left + contentElementCSS = {}; + if (cssDirectionChanged || widthAutoChanged || heightAutoChanged) { + if (_isRTL && widthAuto) { + var floatTmp = _contentElement.css(_strFloat); + var posLeftWithoutFloat = MATH.round(_contentElement.css(_strFloat, _strEmpty).css(_strLeft, _strEmpty).position().left); + _contentElement.css(_strFloat, floatTmp); + var posLeftWithFloat = MATH.round(_contentElement.position().left); + + if (posLeftWithoutFloat !== posLeftWithFloat) + contentElementCSS[_strLeft] = posLeftWithoutFloat; + } + else { + contentElementCSS[_strLeft] = _strEmpty; + } + } + _contentElement.css(contentElementCSS); + + //handle scroll position + if (_isTextarea && contentSizeChanged) { + var textareaInfo = getTextareaInfo(); + if (textareaInfo) { + var textareaRowsChanged = _textareaInfoCache === undefined ? true : textareaInfo._rows !== _textareaInfoCache._rows; + var cursorRow = textareaInfo._cursorRow; + var cursorCol = textareaInfo._cursorColumn; + var widestRow = textareaInfo._widestRow; + var lastRow = textareaInfo._rows; + var lastCol = textareaInfo._columns; + var cursorPos = textareaInfo._cursorPosition; + var cursorMax = textareaInfo._cursorMax; + var cursorIsLastPosition = (cursorPos >= cursorMax && _textareaHasFocus); + var textareaScrollAmount = { + x: (!textareaAutoWrapping && (cursorCol === lastCol && cursorRow === widestRow)) ? _overflowAmountCache.x : -1, + y: (textareaAutoWrapping ? cursorIsLastPosition || textareaRowsChanged && (previousOverflowAmount ? (currScroll.y === previousOverflowAmount.y) : false) : (cursorIsLastPosition || textareaRowsChanged) && cursorRow === lastRow) ? _overflowAmountCache.y : -1 + }; + currScroll.x = textareaScrollAmount.x > -1 ? (_isRTL && _normalizeRTLCache && _rtlScrollBehavior.i ? 0 : textareaScrollAmount.x) : currScroll.x; //if inverted, scroll to 0 -> normalized this means to max scroll offset. + currScroll.y = textareaScrollAmount.y > -1 ? textareaScrollAmount.y : currScroll.y; + } + _textareaInfoCache = textareaInfo; + } + if (_isRTL && _rtlScrollBehavior.i && _nativeScrollbarIsOverlaid.y && hasOverflow.x && _normalizeRTLCache) + currScroll.x += _contentBorderSize.w || 0; + if (widthAuto) + _hostElement[_strScrollLeft](0); + if (heightAuto) + _hostElement[_strScrollTop](0); + _viewportElement[_strScrollLeft](currScroll.x)[_strScrollTop](currScroll.y); + + //scrollbars management: + var scrollbarsVisibilityVisible = scrollbarsVisibility === 'v'; + var scrollbarsVisibilityHidden = scrollbarsVisibility === 'h'; + var scrollbarsVisibilityAuto = scrollbarsVisibility === 'a'; + + var showScrollbarH = COMPATIBILITY.bind(refreshScrollbarAppearance, 0, true, true, canScroll.x); + var showScrollbarV = COMPATIBILITY.bind(refreshScrollbarAppearance, 0, false, true, canScroll.y); + var hideScrollbarH = COMPATIBILITY.bind(refreshScrollbarAppearance, 0, true, false, canScroll.x); + var hideScrollbarV = COMPATIBILITY.bind(refreshScrollbarAppearance, 0, false, false, canScroll.y); + + //manage class name which indicates scrollable overflow + if (hideOverflow.x || hideOverflow.y) + addClass(_hostElement, _classNameHostOverflow); + else + removeClass(_hostElement, _classNameHostOverflow); + if (hideOverflow.x) + addClass(_hostElement, _classNameHostOverflowX); + else + removeClass(_hostElement, _classNameHostOverflowX); + if (hideOverflow.y) + addClass(_hostElement, _classNameHostOverflowY); + else + removeClass(_hostElement, _classNameHostOverflowY); + + //add or remove rtl class name for styling purposes + if (cssDirectionChanged) { + if (_isRTL) + addClass(_hostElement, _classNameHostRTL); + else + removeClass(_hostElement, _classNameHostRTL); + } + + //manage the resize feature (CSS3 resize "polyfill" for this plugin) + if (_isBody) + addClass(_hostElement, _classNameHostResizeDisabled); + if (resizeChanged) { + removeClass(_scrollbarCornerElement, [ + _classNameScrollbarCornerResize, + _classNameScrollbarCornerResizeB, + _classNameScrollbarCornerResizeH, + _classNameScrollbarCornerResizeV].join(_strSpace)); + if (_resizeNone) { + addClass(_hostElement, _classNameHostResizeDisabled); + } + else { + removeClass(_hostElement, _classNameHostResizeDisabled); + addClass(_scrollbarCornerElement, _classNameScrollbarCornerResize); + if (_resizeBoth) + addClass(_scrollbarCornerElement, _classNameScrollbarCornerResizeB); + else if (_resizeHorizontal) + addClass(_scrollbarCornerElement, _classNameScrollbarCornerResizeH); + else if (_resizeVertical) + addClass(_scrollbarCornerElement, _classNameScrollbarCornerResizeV); + } + } + + //manage the scrollbars general visibility + the scrollbar interactivity (unusable class name) + if (scrollbarsVisibilityChanged || overflowBehaviorChanged || hideOverflow.c || hasOverflow.c || ignoreOverlayScrollbarHidingChanged) { + if (ignoreOverlayScrollbarHiding) { + if (ignoreOverlayScrollbarHidingChanged) { + removeClass(_hostElement, _classNameHostScrolling); + if (ignoreOverlayScrollbarHiding) { + hideScrollbarH(); + hideScrollbarV(); + } + } + } + else if (scrollbarsVisibilityAuto) { + if (canScroll.x) + showScrollbarH(); + else + hideScrollbarH(); + + if (canScroll.y) + showScrollbarV(); + else + hideScrollbarV(); + } + else if (scrollbarsVisibilityVisible) { + showScrollbarH(); + showScrollbarV(); + } + else if (scrollbarsVisibilityHidden) { + hideScrollbarH(); + hideScrollbarV(); + } + } + + //manage the scrollbars auto hide feature (auto hide them after specific actions) + if (scrollbarsAutoHideChanged || ignoreOverlayScrollbarHidingChanged) { + if (_scrollbarsAutoHideLeave || _scrollbarsAutoHideMove) { + setupHostMouseTouchEvents(true); + setupHostMouseTouchEvents(); + } + else { + setupHostMouseTouchEvents(true); + } + + if (_scrollbarsAutoHideNever) + refreshScrollbarsAutoHide(true); + else + refreshScrollbarsAutoHide(false, true); + } + + //manage scrollbars handle length & offset - don't remove! + if (hostSizeChanged || overflowAmount.c || heightAutoChanged || widthAutoChanged || resizeChanged || boxSizingChanged || paddingAbsoluteChanged || ignoreOverlayScrollbarHidingChanged || cssDirectionChanged) { + refreshScrollbarHandleLength(true); + refreshScrollbarHandleOffset(true); + refreshScrollbarHandleLength(false); + refreshScrollbarHandleOffset(false); + } + + //manage interactivity + if (scrollbarsClickScrollingChanged) + refreshScrollbarsInteractive(true, scrollbarsClickScrolling); + if (scrollbarsDragScrollingChanged) + refreshScrollbarsInteractive(false, scrollbarsDragScrolling); + + //callbacks: + if (cssDirectionChanged) { + dispatchCallback('onDirectionChanged', { + isRTL: _isRTL, + dir: cssDirection + }); + } + if (hostSizeChanged) { + dispatchCallback('onHostSizeChanged', { + width: _hostSizeCache.w, + height: _hostSizeCache.h + }); + } + if (contentSizeChanged) { + dispatchCallback('onContentSizeChanged', { + width: _contentScrollSizeCache.w, + height: _contentScrollSizeCache.h + }); + } + if (hasOverflow.c || hideOverflow.c) { + dispatchCallback('onOverflowChanged', { + x: hasOverflow.x, + y: hasOverflow.y, + xScrollable: hideOverflow.xs, + yScrollable: hideOverflow.ys, + clipped: hideOverflow.x || hideOverflow.y + }); + } + if (overflowAmount.c) { + dispatchCallback('onOverflowAmountChanged', { + x: overflowAmount.x, + y: overflowAmount.y + }); + } + } + + //fix body min size + if (_isBody && _bodyMinSizeCache && (_hasOverflowCache.c || _bodyMinSizeCache.c)) { + //its possible that no min size was measured until now, because the content arrange element was just added now, in this case, measure now the min size. + if (!_bodyMinSizeCache.f) + bodyMinSizeChanged(); + if (_nativeScrollbarIsOverlaid.y && _hasOverflowCache.x) + _contentElement.css(_strMinMinus + _strWidth, _bodyMinSizeCache.w + _overlayScrollbarDummySize.y); + if (_nativeScrollbarIsOverlaid.x && _hasOverflowCache.y) + _contentElement.css(_strMinMinus + _strHeight, _bodyMinSizeCache.h + _overlayScrollbarDummySize.x); + _bodyMinSizeCache.c = false; + } + + //freezeResizeObserver(_sizeObserverElement, false); + //freezeResizeObserver(_sizeAutoObserverElement, false); + + dispatchCallback('onUpdated', { forced: force }); + } + + + //==== Options ====// + + /** + * Sets new options but doesn't call the update method. + * @param newOptions The object which contains the new options. + * @returns {*} A object which contains the changed options. + */ + function setOptions(newOptions) { + var validatedOpts = _pluginsOptions._validate(newOptions, _pluginsOptions._template, true, _currentOptions) + + _currentOptions = extendDeep({}, _currentOptions, validatedOpts._default); + _currentPreparedOptions = extendDeep({}, _currentPreparedOptions, validatedOpts._prepared); + + return validatedOpts._prepared; + } + + + //==== Structure ====// + + /** + * Builds or destroys the wrapper and helper DOM elements. + * @param destroy Indicates whether the DOM shall be build or destroyed. + */ + function setupStructureDOM(destroy) { + var strParent = 'parent'; + var classNameResizeObserverHost = 'os-resize-observer-host'; + var classNameTextareaElementFull = _classNameTextareaElement + _strSpace + _classNameTextInherit; + var textareaClass = _isTextarea ? _strSpace + _classNameTextInherit : _strEmpty; + var adoptAttrs = _currentPreparedOptions.textarea.inheritedAttrs; + var adoptAttrsMap = {}; + var applyAdoptedAttrs = function () { + var applyAdoptedAttrsElm = destroy ? _targetElement : _hostElement; + each(adoptAttrsMap, function (key, value) { + if (type(value) == TYPES.s) { + if (key == LEXICON.c) + applyAdoptedAttrsElm.addClass(value); + else + applyAdoptedAttrsElm.attr(key, value); + } + }); + }; + var hostElementClassNames = [ + _classNameHostElement, + _classNameHostTextareaElement, + _classNameHostResizeDisabled, + _classNameHostRTL, + _classNameHostScrollbarHorizontalHidden, + _classNameHostScrollbarVerticalHidden, + _classNameHostTransition, + _classNameHostScrolling, + _classNameHostOverflow, + _classNameHostOverflowX, + _classNameHostOverflowY, + _classNameThemeNone, + _classNameTextareaElement, + _classNameTextInherit, + _classNameCache].join(_strSpace); + var hostElementCSS = {}; + + //get host element as first element, because that's the most upper element and required for the other elements + _hostElement = _hostElement || (_isTextarea ? (_domExists ? _targetElement[strParent]()[strParent]()[strParent]()[strParent]() : FRAMEWORK(generateDiv(_classNameHostTextareaElement))) : _targetElement); + _contentElement = _contentElement || selectOrGenerateDivByClass(_classNameContentElement + textareaClass); + _viewportElement = _viewportElement || selectOrGenerateDivByClass(_classNameViewportElement + textareaClass); + _paddingElement = _paddingElement || selectOrGenerateDivByClass(_classNamePaddingElement + textareaClass); + _sizeObserverElement = _sizeObserverElement || selectOrGenerateDivByClass(classNameResizeObserverHost); + _textareaCoverElement = _textareaCoverElement || (_isTextarea ? selectOrGenerateDivByClass(_classNameTextareaCoverElement) : undefined); + + //on destroy, remove all generated class names from the host element before collecting the adopted attributes + //to prevent adopting generated class names + if (destroy) + removeClass(_hostElement, hostElementClassNames); + + //collect all adopted attributes + adoptAttrs = type(adoptAttrs) == TYPES.s ? adoptAttrs.split(_strSpace) : adoptAttrs; + if (type(adoptAttrs) == TYPES.a && _isTextarea) { + each(adoptAttrs, function (i, v) { + if (type(v) == TYPES.s) { + adoptAttrsMap[v] = destroy ? _hostElement.attr(v) : _targetElement.attr(v); + } + }); + } + + if (!destroy) { + if (_isTextarea) { + if (!_currentPreparedOptions.sizeAutoCapable) { + hostElementCSS[_strWidth] = _targetElement.css(_strWidth); + hostElementCSS[_strHeight] = _targetElement.css(_strHeight); + } + + if (!_domExists) + _targetElement.addClass(_classNameTextInherit).wrap(_hostElement); + + //jQuery clones elements in wrap functions, so we have to select them again + _hostElement = _targetElement[strParent]().css(hostElementCSS); + } + + if (!_domExists) { + //add the correct class to the target element + addClass(_targetElement, _isTextarea ? classNameTextareaElementFull : _classNameHostElement); + + //wrap the content into the generated elements to create the required DOM + _hostElement.wrapInner(_contentElement) + .wrapInner(_viewportElement) + .wrapInner(_paddingElement) + .prepend(_sizeObserverElement); + + //jQuery clones elements in wrap functions, so we have to select them again + _contentElement = findFirst(_hostElement, _strDot + _classNameContentElement); + _viewportElement = findFirst(_hostElement, _strDot + _classNameViewportElement); + _paddingElement = findFirst(_hostElement, _strDot + _classNamePaddingElement); + + if (_isTextarea) { + _contentElement.prepend(_textareaCoverElement); + applyAdoptedAttrs(); + } + } + + if (_nativeScrollbarStyling) + addClass(_viewportElement, _classNameViewportNativeScrollbarsInvisible); + if (_nativeScrollbarIsOverlaid.x && _nativeScrollbarIsOverlaid.y) + addClass(_viewportElement, _classNameViewportNativeScrollbarsOverlaid); + if (_isBody) + addClass(_htmlElement, _classNameHTMLElement); + + _sizeObserverElementNative = _sizeObserverElement[0]; + _hostElementNative = _hostElement[0]; + _paddingElementNative = _paddingElement[0]; + _viewportElementNative = _viewportElement[0]; + _contentElementNative = _contentElement[0]; + + updateViewportAttrsFromTarget(); + } + else { + if (_domExists && _initialized) { + //clear size observer + _sizeObserverElement.children().remove(); + + //remove the style property and classes from already generated elements + each([_paddingElement, _viewportElement, _contentElement, _textareaCoverElement], function (i, elm) { + if (elm) { + removeClass(elm.removeAttr(LEXICON.s), _classNamesDynamicDestroy); + } + }); + + //add classes to the host element which was removed previously to match the expected DOM + addClass(_hostElement, _isTextarea ? _classNameHostTextareaElement : _classNameHostElement); + } + else { + //remove size observer + remove(_sizeObserverElement); + + //unwrap the content to restore DOM + _contentElement.contents() + .unwrap() + .unwrap() + .unwrap(); + + if (_isTextarea) { + _targetElement.unwrap(); + remove(_hostElement); + remove(_textareaCoverElement); + applyAdoptedAttrs(); + } + } + + if (_isTextarea) + _targetElement.removeAttr(LEXICON.s); + + if (_isBody) + removeClass(_htmlElement, _classNameHTMLElement); + } + } + + /** + * Adds or removes all wrapper elements interactivity events. + * @param destroy Indicates whether the Events shall be added or removed. + */ + function setupStructureEvents() { + var textareaKeyDownRestrictedKeyCodes = [ + 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 123, //F1 to F12 + 33, 34, //page up, page down + 37, 38, 39, 40, //left, up, right, down arrows + 16, 17, 18, 19, 20, 144 //Shift, Ctrl, Alt, Pause, CapsLock, NumLock + ]; + var textareaKeyDownKeyCodesList = []; + var textareaUpdateIntervalID; + var scrollStopTimeoutId; + var scrollStopDelay = 175; + var strFocus = 'focus'; + + function updateTextarea(doClearInterval) { + textareaUpdate(); + _base.update(_strAuto); + if (doClearInterval && _autoUpdateRecommended) + clearInterval(textareaUpdateIntervalID); + } + function textareaOnScroll(event) { + _targetElement[_strScrollLeft](_rtlScrollBehavior.i && _normalizeRTLCache ? 9999999 : 0); + _targetElement[_strScrollTop](0); + COMPATIBILITY.prvD(event); + COMPATIBILITY.stpP(event); + return false; + } + function textareaOnDrop(event) { + setTimeout(function () { + if (!_destroyed) + updateTextarea(); + }, 50); + } + function textareaOnFocus() { + _textareaHasFocus = true; + addClass(_hostElement, strFocus); + } + function textareaOnFocusout() { + _textareaHasFocus = false; + textareaKeyDownKeyCodesList = []; + removeClass(_hostElement, strFocus); + updateTextarea(true); + } + function textareaOnKeyDown(event) { + var keyCode = event.keyCode; + + if (inArray(keyCode, textareaKeyDownRestrictedKeyCodes) < 0) { + if (!textareaKeyDownKeyCodesList[LEXICON.l]) { + updateTextarea(); + textareaUpdateIntervalID = setInterval(updateTextarea, 1000 / 60); + } + if (inArray(keyCode, textareaKeyDownKeyCodesList) < 0) + textareaKeyDownKeyCodesList.push(keyCode); + } + } + function textareaOnKeyUp(event) { + var keyCode = event.keyCode; + var index = inArray(keyCode, textareaKeyDownKeyCodesList); + + if (inArray(keyCode, textareaKeyDownRestrictedKeyCodes) < 0) { + if (index > -1) + textareaKeyDownKeyCodesList.splice(index, 1); + if (!textareaKeyDownKeyCodesList[LEXICON.l]) + updateTextarea(true); + } + } + function contentOnTransitionEnd(event) { + if (_autoUpdateCache === true) + return; + event = event.originalEvent || event; + if (isSizeAffectingCSSProperty(event.propertyName)) + _base.update(_strAuto); + } + function viewportOnScroll(event) { + if (!_sleeping) { + if (scrollStopTimeoutId !== undefined) + clearTimeout(scrollStopTimeoutId); + else { + if (_scrollbarsAutoHideScroll || _scrollbarsAutoHideMove) + refreshScrollbarsAutoHide(true); + + if (!nativeOverlayScrollbarsAreActive()) + addClass(_hostElement, _classNameHostScrolling); + + dispatchCallback('onScrollStart', event); + } + + //if a scrollbars handle gets dragged, the mousemove event is responsible for refreshing the handle offset + //because if CSS scroll-snap is used, the handle offset gets only refreshed on every snap point + //this looks laggy & clunky, it looks much better if the offset refreshes with the mousemove + if (!_scrollbarsHandlesDefineScrollPos) { + refreshScrollbarHandleOffset(true); + refreshScrollbarHandleOffset(false); + } + dispatchCallback('onScroll', event); + + scrollStopTimeoutId = setTimeout(function () { + if (!_destroyed) { + //OnScrollStop: + clearTimeout(scrollStopTimeoutId); + scrollStopTimeoutId = undefined; + + if (_scrollbarsAutoHideScroll || _scrollbarsAutoHideMove) + refreshScrollbarsAutoHide(false); + + if (!nativeOverlayScrollbarsAreActive()) + removeClass(_hostElement, _classNameHostScrolling); + + dispatchCallback('onScrollStop', event); + } + }, scrollStopDelay); + } + } + + + if (_isTextarea) { + if (_msieVersion > 9 || !_autoUpdateRecommended) { + addDestroyEventListener(_targetElement, 'input', updateTextarea); + } + else { + addDestroyEventListener(_targetElement, + [_strKeyDownEvent, _strKeyUpEvent], + [textareaOnKeyDown, textareaOnKeyUp]); + } + + addDestroyEventListener(_targetElement, + [_strScroll, 'drop', strFocus, strFocus + 'out'], + [textareaOnScroll, textareaOnDrop, textareaOnFocus, textareaOnFocusout]); + } + else { + addDestroyEventListener(_contentElement, _strTransitionEndEvent, contentOnTransitionEnd); + } + addDestroyEventListener(_viewportElement, _strScroll, viewportOnScroll, true); + } + + + //==== Scrollbars ====// + + /** + * Builds or destroys all scrollbar DOM elements (scrollbar, track, handle) + * @param destroy Indicates whether the DOM shall be build or destroyed. + */ + function setupScrollbarsDOM(destroy) { + var selectOrGenerateScrollbarDOM = function (isHorizontal) { + var scrollbarClassName = isHorizontal ? _classNameScrollbarHorizontal : _classNameScrollbarVertical; + var scrollbar = selectOrGenerateDivByClass(_classNameScrollbar + _strSpace + scrollbarClassName, true); + var track = selectOrGenerateDivByClass(_classNameScrollbarTrack, scrollbar); + var handle = selectOrGenerateDivByClass(_classNameScrollbarHandle, scrollbar); + + if (!_domExists && !destroy) { + scrollbar.append(track); + track.append(handle); + } + + return { + _scrollbar: scrollbar, + _track: track, + _handle: handle + }; + }; + function resetScrollbarDOM(isHorizontal) { + var scrollbarVars = getScrollbarVars(isHorizontal); + var scrollbar = scrollbarVars._scrollbar; + var track = scrollbarVars._track; + var handle = scrollbarVars._handle; + + if (_domExists && _initialized) { + each([scrollbar, track, handle], function (i, elm) { + removeClass(elm.removeAttr(LEXICON.s), _classNamesDynamicDestroy); + }); + } + else { + remove(scrollbar || selectOrGenerateScrollbarDOM(isHorizontal)._scrollbar); + } + } + var horizontalElements; + var verticalElements; + + if (!destroy) { + horizontalElements = selectOrGenerateScrollbarDOM(true); + verticalElements = selectOrGenerateScrollbarDOM(); + + _scrollbarHorizontalElement = horizontalElements._scrollbar; + _scrollbarHorizontalTrackElement = horizontalElements._track; + _scrollbarHorizontalHandleElement = horizontalElements._handle; + _scrollbarVerticalElement = verticalElements._scrollbar; + _scrollbarVerticalTrackElement = verticalElements._track; + _scrollbarVerticalHandleElement = verticalElements._handle; + + if (!_domExists) { + _paddingElement.after(_scrollbarVerticalElement); + _paddingElement.after(_scrollbarHorizontalElement); + } + } + else { + resetScrollbarDOM(true); + resetScrollbarDOM(); + } + } + + /** + * Initializes all scrollbar interactivity events. (track and handle dragging, clicking, scrolling) + * @param isHorizontal True if the target scrollbar is the horizontal scrollbar, false if the target scrollbar is the vertical scrollbar. + */ + function setupScrollbarEvents(isHorizontal) { + var scrollbarVars = getScrollbarVars(isHorizontal); + var scrollbarVarsInfo = scrollbarVars._info; + var insideIFrame = _windowElementNative.top !== _windowElementNative; + var xy = scrollbarVars._x_y; + var XY = scrollbarVars._X_Y; + var scroll = _strScroll + scrollbarVars._Left_Top; + var strActive = 'active'; + var strSnapHandle = 'snapHandle'; + var scrollDurationFactor = 1; + var increaseDecreaseScrollAmountKeyCodes = [16, 17]; //shift, ctrl + var trackTimeout; + var mouseDownScroll; + var mouseDownOffset; + var mouseDownInvertedScale; + + function getPointerPosition(event) { + return _msieVersion && insideIFrame ? event['screen' + XY] : COMPATIBILITY.page(event)[xy]; //use screen coordinates in EDGE & IE because the page values are incorrect in frames. + } + function getPreparedScrollbarsOption(name) { + return _currentPreparedOptions.scrollbars[name]; + } + function increaseTrackScrollAmount() { + scrollDurationFactor = 0.5; + } + function decreaseTrackScrollAmount() { + scrollDurationFactor = 1; + } + function documentKeyDown(event) { + if (inArray(event.keyCode, increaseDecreaseScrollAmountKeyCodes) > -1) + increaseTrackScrollAmount(); + } + function documentKeyUp(event) { + if (inArray(event.keyCode, increaseDecreaseScrollAmountKeyCodes) > -1) + decreaseTrackScrollAmount(); + } + function onMouseTouchDownContinue(event) { + var originalEvent = event.originalEvent || event; + var isTouchEvent = originalEvent.touches !== undefined; + return _sleeping || _destroyed || nativeOverlayScrollbarsAreActive() || !_scrollbarsDragScrollingCache || (isTouchEvent && !getPreparedScrollbarsOption('touchSupport')) ? false : COMPATIBILITY.mBtn(event) === 1 || isTouchEvent; + } + function documentDragMove(event) { + if (onMouseTouchDownContinue(event)) { + var trackLength = scrollbarVarsInfo._trackLength; + var handleLength = scrollbarVarsInfo._handleLength; + var scrollRange = scrollbarVarsInfo._maxScroll; + var scrollRaw = (getPointerPosition(event) - mouseDownOffset) * mouseDownInvertedScale; + var scrollDeltaPercent = scrollRaw / (trackLength - handleLength); + var scrollDelta = (scrollRange * scrollDeltaPercent); + scrollDelta = isFinite(scrollDelta) ? scrollDelta : 0; + if (_isRTL && isHorizontal && !_rtlScrollBehavior.i) + scrollDelta *= -1; + + _viewportElement[scroll](MATH.round(mouseDownScroll + scrollDelta)); + + if (_scrollbarsHandlesDefineScrollPos) + refreshScrollbarHandleOffset(isHorizontal, mouseDownScroll + scrollDelta); + + if (!_supportPassiveEvents) + COMPATIBILITY.prvD(event); + } + else + documentMouseTouchUp(event); + } + function documentMouseTouchUp(event) { + event = event || event.originalEvent; + + setupResponsiveEventListener(_documentElement, + [_strMouseTouchMoveEvent, _strMouseTouchUpEvent, _strKeyDownEvent, _strKeyUpEvent, _strSelectStartEvent], + [documentDragMove, documentMouseTouchUp, documentKeyDown, documentKeyUp, documentOnSelectStart], + true); + + if (_scrollbarsHandlesDefineScrollPos) + refreshScrollbarHandleOffset(isHorizontal, true); + + _scrollbarsHandlesDefineScrollPos = false; + removeClass(_bodyElement, _classNameDragging); + removeClass(scrollbarVars._handle, strActive); + removeClass(scrollbarVars._track, strActive); + removeClass(scrollbarVars._scrollbar, strActive); + + mouseDownScroll = undefined; + mouseDownOffset = undefined; + mouseDownInvertedScale = 1; + + decreaseTrackScrollAmount(); + + if (trackTimeout !== undefined) { + _base.scrollStop(); + clearTimeout(trackTimeout); + trackTimeout = undefined; + } + + if (event) { + var rect = _hostElementNative[LEXICON.bCR](); + var mouseInsideHost = event.clientX >= rect.left && event.clientX <= rect.right && event.clientY >= rect.top && event.clientY <= rect.bottom; + + //if mouse is outside host element + if (!mouseInsideHost) + hostOnMouseLeave(); + + if (_scrollbarsAutoHideScroll || _scrollbarsAutoHideMove) + refreshScrollbarsAutoHide(false); + } + } + function onHandleMouseTouchDown(event) { + if (onMouseTouchDownContinue(event)) + onHandleMouseTouchDownAction(event); + } + function onHandleMouseTouchDownAction(event) { + mouseDownScroll = _viewportElement[scroll](); + mouseDownScroll = isNaN(mouseDownScroll) ? 0 : mouseDownScroll; + if (_isRTL && isHorizontal && !_rtlScrollBehavior.n || !_isRTL) + mouseDownScroll = mouseDownScroll < 0 ? 0 : mouseDownScroll; + + mouseDownInvertedScale = getHostElementInvertedScale()[xy]; + mouseDownOffset = getPointerPosition(event); + + _scrollbarsHandlesDefineScrollPos = !getPreparedScrollbarsOption(strSnapHandle); + addClass(_bodyElement, _classNameDragging); + addClass(scrollbarVars._handle, strActive); + addClass(scrollbarVars._scrollbar, strActive); + + setupResponsiveEventListener(_documentElement, + [_strMouseTouchMoveEvent, _strMouseTouchUpEvent, _strSelectStartEvent], + [documentDragMove, documentMouseTouchUp, documentOnSelectStart]); + + if (_msieVersion || !_documentMixed) + COMPATIBILITY.prvD(event); + COMPATIBILITY.stpP(event); + } + function onTrackMouseTouchDown(event) { + if (onMouseTouchDownContinue(event)) { + var scrollDistance = MATH.round(_viewportSize[scrollbarVars._w_h]); + var trackOffset = scrollbarVars._track.offset()[scrollbarVars._left_top]; + var ctrlKey = event.ctrlKey; + var instantScroll = event.shiftKey; + var instantScrollTransition = instantScroll && ctrlKey; + var isFirstIteration = true; + var easing = 'linear'; + var decreaseScroll; + var finishedCondition; + var scrollActionFinsished = function (transition) { + if (_scrollbarsHandlesDefineScrollPos) + refreshScrollbarHandleOffset(isHorizontal, transition); + }; + var scrollActionInstantFinished = function () { + scrollActionFinsished(); + onHandleMouseTouchDownAction(event); + }; + var scrollAction = function () { + if (!_destroyed) { + var mouseOffset = (mouseDownOffset - trackOffset) * mouseDownInvertedScale; + var handleOffset = scrollbarVarsInfo._handleOffset; + var trackLength = scrollbarVarsInfo._trackLength; + var handleLength = scrollbarVarsInfo._handleLength; + var scrollRange = scrollbarVarsInfo._maxScroll; + var currScroll = scrollbarVarsInfo._currentScroll; + var scrollDuration = 270 * scrollDurationFactor; + var timeoutDelay = isFirstIteration ? MATH.max(400, scrollDuration) : scrollDuration; + var instantScrollPosition = scrollRange * ((mouseOffset - (handleLength / 2)) / (trackLength - handleLength)); // 100% * positionPercent + var rtlIsNormal = _isRTL && isHorizontal && ((!_rtlScrollBehavior.i && !_rtlScrollBehavior.n) || _normalizeRTLCache); + var decreaseScrollCondition = rtlIsNormal ? handleOffset < mouseOffset : handleOffset > mouseOffset; + var scrollObj = {}; + var animationObj = { + easing: easing, + step: function (now) { + if (_scrollbarsHandlesDefineScrollPos) { + _viewportElement[scroll](now); //https://github.com/jquery/jquery/issues/4340 + refreshScrollbarHandleOffset(isHorizontal, now); + } + } + }; + instantScrollPosition = isFinite(instantScrollPosition) ? instantScrollPosition : 0; + instantScrollPosition = _isRTL && isHorizontal && !_rtlScrollBehavior.i ? (scrollRange - instantScrollPosition) : instantScrollPosition; + + //_base.scrollStop(); + + if (instantScroll) { + _viewportElement[scroll](instantScrollPosition); //scroll instantly to new position + if (instantScrollTransition) { + //get the scroll position after instant scroll (in case CSS Snap Points are used) to get the correct snapped scroll position + //and the animation stops at the correct point + instantScrollPosition = _viewportElement[scroll](); + //scroll back to the position before instant scrolling so animation can be performed + _viewportElement[scroll](currScroll); + + instantScrollPosition = rtlIsNormal && _rtlScrollBehavior.i ? (scrollRange - instantScrollPosition) : instantScrollPosition; + instantScrollPosition = rtlIsNormal && _rtlScrollBehavior.n ? -instantScrollPosition : instantScrollPosition; + + scrollObj[xy] = instantScrollPosition; + _base.scroll(scrollObj, extendDeep(animationObj, { + duration: 130, + complete: scrollActionInstantFinished + })); + } + else + scrollActionInstantFinished(); + } + else { + decreaseScroll = isFirstIteration ? decreaseScrollCondition : decreaseScroll; + finishedCondition = rtlIsNormal + ? (decreaseScroll ? handleOffset + handleLength >= mouseOffset : handleOffset <= mouseOffset) + : (decreaseScroll ? handleOffset <= mouseOffset : handleOffset + handleLength >= mouseOffset); + + if (finishedCondition) { + clearTimeout(trackTimeout); + _base.scrollStop(); + trackTimeout = undefined; + scrollActionFinsished(true); + } + else { + trackTimeout = setTimeout(scrollAction, timeoutDelay); + + scrollObj[xy] = (decreaseScroll ? '-=' : '+=') + scrollDistance; + _base.scroll(scrollObj, extendDeep(animationObj, { + duration: scrollDuration + })); + } + isFirstIteration = false; + } + } + }; + if (ctrlKey) + increaseTrackScrollAmount(); + + mouseDownInvertedScale = getHostElementInvertedScale()[xy]; + mouseDownOffset = COMPATIBILITY.page(event)[xy]; + + _scrollbarsHandlesDefineScrollPos = !getPreparedScrollbarsOption(strSnapHandle); + addClass(_bodyElement, _classNameDragging); + addClass(scrollbarVars._track, strActive); + addClass(scrollbarVars._scrollbar, strActive); + + setupResponsiveEventListener(_documentElement, + [_strMouseTouchUpEvent, _strKeyDownEvent, _strKeyUpEvent, _strSelectStartEvent], + [documentMouseTouchUp, documentKeyDown, documentKeyUp, documentOnSelectStart]); + + scrollAction(); + COMPATIBILITY.prvD(event); + COMPATIBILITY.stpP(event); + } + } + function onTrackMouseTouchEnter(event) { + //make sure both scrollbars will stay visible if one scrollbar is hovered if autoHide is "scroll" or "move". + _scrollbarsHandleHovered = true; + if (_scrollbarsAutoHideScroll || _scrollbarsAutoHideMove) + refreshScrollbarsAutoHide(true); + } + function onTrackMouseTouchLeave(event) { + _scrollbarsHandleHovered = false; + if (_scrollbarsAutoHideScroll || _scrollbarsAutoHideMove) + refreshScrollbarsAutoHide(false); + } + function onScrollbarMouseTouchDown(event) { + COMPATIBILITY.stpP(event); + } + + addDestroyEventListener(scrollbarVars._handle, + _strMouseTouchDownEvent, + onHandleMouseTouchDown); + addDestroyEventListener(scrollbarVars._track, + [_strMouseTouchDownEvent, _strMouseTouchEnter, _strMouseTouchLeave], + [onTrackMouseTouchDown, onTrackMouseTouchEnter, onTrackMouseTouchLeave]); + addDestroyEventListener(scrollbarVars._scrollbar, + _strMouseTouchDownEvent, + onScrollbarMouseTouchDown); + + if (_supportTransition) { + addDestroyEventListener(scrollbarVars._scrollbar, _strTransitionEndEvent, function (event) { + if (event.target !== scrollbarVars._scrollbar[0]) + return; + refreshScrollbarHandleLength(isHorizontal); + refreshScrollbarHandleOffset(isHorizontal); + }); + } + } + + /** + * Shows or hides the given scrollbar and applied a class name which indicates if the scrollbar is scrollable or not. + * @param isHorizontal True if the horizontal scrollbar is the target, false if the vertical scrollbar is the target. + * @param shallBeVisible True if the scrollbar shall be shown, false if hidden. + * @param canScroll True if the scrollbar is scrollable, false otherwise. + */ + function refreshScrollbarAppearance(isHorizontal, shallBeVisible, canScroll) { + var scrollbarClassName = isHorizontal ? _classNameHostScrollbarHorizontalHidden : _classNameHostScrollbarVerticalHidden; + var scrollbarElement = isHorizontal ? _scrollbarHorizontalElement : _scrollbarVerticalElement; + + if (shallBeVisible) + removeClass(_hostElement, scrollbarClassName); + else + addClass(_hostElement, scrollbarClassName); + + if (canScroll) + removeClass(scrollbarElement, _classNameScrollbarUnusable); + else + addClass(scrollbarElement, _classNameScrollbarUnusable); + } + + /** + * Autoshows / autohides both scrollbars with. + * @param shallBeVisible True if the scrollbars shall be autoshown (only the case if they are hidden by a autohide), false if the shall be auto hidden. + * @param delayfree True if the scrollbars shall be hidden without a delay, false or undefined otherwise. + */ + function refreshScrollbarsAutoHide(shallBeVisible, delayfree) { + clearTimeout(_scrollbarsAutoHideTimeoutId); + if (shallBeVisible) { + //if(_hasOverflowCache.x && _hideOverflowCache.xs) + removeClass(_scrollbarHorizontalElement, _classNameScrollbarAutoHidden); + //if(_hasOverflowCache.y && _hideOverflowCache.ys) + removeClass(_scrollbarVerticalElement, _classNameScrollbarAutoHidden); + } + else { + var anyActive; + var strActive = 'active'; + var hide = function () { + if (!_scrollbarsHandleHovered && !_destroyed) { + anyActive = _scrollbarHorizontalHandleElement.hasClass(strActive) || _scrollbarVerticalHandleElement.hasClass(strActive); + if (!anyActive && (_scrollbarsAutoHideScroll || _scrollbarsAutoHideMove || _scrollbarsAutoHideLeave)) + addClass(_scrollbarHorizontalElement, _classNameScrollbarAutoHidden); + if (!anyActive && (_scrollbarsAutoHideScroll || _scrollbarsAutoHideMove || _scrollbarsAutoHideLeave)) + addClass(_scrollbarVerticalElement, _classNameScrollbarAutoHidden); + } + }; + if (_scrollbarsAutoHideDelay > 0 && delayfree !== true) + _scrollbarsAutoHideTimeoutId = setTimeout(hide, _scrollbarsAutoHideDelay); + else + hide(); + } + } + + /** + * Refreshes the handle length of the given scrollbar. + * @param isHorizontal True if the horizontal scrollbar handle shall be refreshed, false if the vertical one shall be refreshed. + */ + function refreshScrollbarHandleLength(isHorizontal) { + var handleCSS = {}; + var scrollbarVars = getScrollbarVars(isHorizontal); + var scrollbarVarsInfo = scrollbarVars._info; + var digit = 1000000; + //get and apply intended handle length + var handleRatio = MATH.min(1, (_hostSizeCache[scrollbarVars._w_h] - (_paddingAbsoluteCache ? (isHorizontal ? _paddingX : _paddingY) : 0)) / _contentScrollSizeCache[scrollbarVars._w_h]); + handleCSS[scrollbarVars._width_height] = (MATH.floor(handleRatio * 100 * digit) / digit) + '%'; //the last * digit / digit is for flooring to the 4th digit + + if (!nativeOverlayScrollbarsAreActive()) + scrollbarVars._handle.css(handleCSS); + + //measure the handle length to respect min & max length + scrollbarVarsInfo._handleLength = scrollbarVars._handle[0]['offset' + scrollbarVars._Width_Height]; + scrollbarVarsInfo._handleLengthRatio = handleRatio; + } + + /** + * Refreshes the handle offset of the given scrollbar. + * @param isHorizontal True if the horizontal scrollbar handle shall be refreshed, false if the vertical one shall be refreshed. + * @param scrollOrTransition The scroll position of the given scrollbar axis to which the handle shall be moved or a boolean which indicates whether a transition shall be applied. If undefined or boolean if the current scroll-offset is taken. (if isHorizontal ? scrollLeft : scrollTop) + */ + function refreshScrollbarHandleOffset(isHorizontal, scrollOrTransition) { + var transition = type(scrollOrTransition) == TYPES.b; + var transitionDuration = 250; + var isRTLisHorizontal = _isRTL && isHorizontal; + var scrollbarVars = getScrollbarVars(isHorizontal); + var scrollbarVarsInfo = scrollbarVars._info; + var strTranslateBrace = 'translate('; + var strTransform = VENDORS._cssProperty('transform'); + var strTransition = VENDORS._cssProperty('transition'); + var nativeScroll = isHorizontal ? _viewportElement[_strScrollLeft]() : _viewportElement[_strScrollTop](); + var currentScroll = scrollOrTransition === undefined || transition ? nativeScroll : scrollOrTransition; + + //measure the handle length to respect min & max length + var handleLength = scrollbarVarsInfo._handleLength; + var trackLength = scrollbarVars._track[0]['offset' + scrollbarVars._Width_Height]; + var handleTrackDiff = trackLength - handleLength; + var handleCSS = {}; + var transformOffset; + var translateValue; + + //DONT use the variable '_contentScrollSizeCache[scrollbarVars._w_h]' instead of '_viewportElement[0]['scroll' + scrollbarVars._Width_Height]' + // because its a bit behind during the small delay when content size updates + //(delay = mutationObserverContentLag, if its 0 then this var could be used) + var maxScroll = (_viewportElementNative[_strScroll + scrollbarVars._Width_Height] - _viewportElementNative['client' + scrollbarVars._Width_Height]) * (_rtlScrollBehavior.n && isRTLisHorizontal ? -1 : 1); //* -1 if rtl scroll max is negative + var getScrollRatio = function (base) { + return isNaN(base / maxScroll) ? 0 : MATH.max(0, MATH.min(1, base / maxScroll)); + }; + var getHandleOffset = function (scrollRatio) { + var offset = handleTrackDiff * scrollRatio; + offset = isNaN(offset) ? 0 : offset; + offset = (isRTLisHorizontal && !_rtlScrollBehavior.i) ? (trackLength - handleLength - offset) : offset; + offset = MATH.max(0, offset); + return offset; + }; + var scrollRatio = getScrollRatio(nativeScroll); + var unsnappedScrollRatio = getScrollRatio(currentScroll); + var handleOffset = getHandleOffset(unsnappedScrollRatio); + var snappedHandleOffset = getHandleOffset(scrollRatio); + + scrollbarVarsInfo._maxScroll = maxScroll; + scrollbarVarsInfo._currentScroll = nativeScroll; + scrollbarVarsInfo._currentScrollRatio = scrollRatio; + + if (_supportTransform) { + transformOffset = isRTLisHorizontal ? -(trackLength - handleLength - handleOffset) : handleOffset; //in px + //transformOffset = (transformOffset / trackLength * 100) * (trackLength / handleLength); //in % + translateValue = isHorizontal ? strTranslateBrace + transformOffset + 'px, 0)' : strTranslateBrace + '0, ' + transformOffset + 'px)'; + + handleCSS[strTransform] = translateValue; + + //apply or clear up transition + if (_supportTransition) + handleCSS[strTransition] = transition && MATH.abs(handleOffset - scrollbarVarsInfo._handleOffset) > 1 ? getCSSTransitionString(scrollbarVars._handle) + ', ' + (strTransform + _strSpace + transitionDuration + 'ms') : _strEmpty; + } + else + handleCSS[scrollbarVars._left_top] = handleOffset; + + + //only apply css if offset has changed and overflow exists. + if (!nativeOverlayScrollbarsAreActive()) { + scrollbarVars._handle.css(handleCSS); + + //clear up transition + if (_supportTransform && _supportTransition && transition) { + scrollbarVars._handle.one(_strTransitionEndEvent, function () { + if (!_destroyed) + scrollbarVars._handle.css(strTransition, _strEmpty); + }); + } + } + + scrollbarVarsInfo._handleOffset = handleOffset; + scrollbarVarsInfo._snappedHandleOffset = snappedHandleOffset; + scrollbarVarsInfo._trackLength = trackLength; + } + + /** + * Refreshes the interactivity of the given scrollbar element. + * @param isTrack True if the track element is the target, false if the handle element is the target. + * @param value True for interactivity false for no interactivity. + */ + function refreshScrollbarsInteractive(isTrack, value) { + var action = value ? 'removeClass' : 'addClass'; + var element1 = isTrack ? _scrollbarHorizontalTrackElement : _scrollbarHorizontalHandleElement; + var element2 = isTrack ? _scrollbarVerticalTrackElement : _scrollbarVerticalHandleElement; + var className = isTrack ? _classNameScrollbarTrackOff : _classNameScrollbarHandleOff; + + element1[action](className); + element2[action](className); + } + + /** + * Returns a object which is used for fast access for specific variables. + * @param isHorizontal True if the horizontal scrollbar vars shall be accessed, false if the vertical scrollbar vars shall be accessed. + * @returns {{wh: string, WH: string, lt: string, _wh: string, _lt: string, t: *, h: *, c: {}, s: *}} + */ + function getScrollbarVars(isHorizontal) { + return { + _width_height: isHorizontal ? _strWidth : _strHeight, + _Width_Height: isHorizontal ? 'Width' : 'Height', + _left_top: isHorizontal ? _strLeft : _strTop, + _Left_Top: isHorizontal ? 'Left' : 'Top', + _x_y: isHorizontal ? _strX : _strY, + _X_Y: isHorizontal ? 'X' : 'Y', + _w_h: isHorizontal ? 'w' : 'h', + _l_t: isHorizontal ? 'l' : 't', + _track: isHorizontal ? _scrollbarHorizontalTrackElement : _scrollbarVerticalTrackElement, + _handle: isHorizontal ? _scrollbarHorizontalHandleElement : _scrollbarVerticalHandleElement, + _scrollbar: isHorizontal ? _scrollbarHorizontalElement : _scrollbarVerticalElement, + _info: isHorizontal ? _scrollHorizontalInfo : _scrollVerticalInfo + }; + } + + + //==== Scrollbar Corner ====// + + /** + * Builds or destroys the scrollbar corner DOM element. + * @param destroy Indicates whether the DOM shall be build or destroyed. + */ + function setupScrollbarCornerDOM(destroy) { + _scrollbarCornerElement = _scrollbarCornerElement || selectOrGenerateDivByClass(_classNameScrollbarCorner, true); + + if (!destroy) { + if (!_domExists) { + _hostElement.append(_scrollbarCornerElement); + } + } + else { + if (_domExists && _initialized) { + removeClass(_scrollbarCornerElement.removeAttr(LEXICON.s), _classNamesDynamicDestroy); + } + else { + remove(_scrollbarCornerElement); + } + } + } + + /** + * Initializes all scrollbar corner interactivity events. + */ + function setupScrollbarCornerEvents() { + var insideIFrame = _windowElementNative.top !== _windowElementNative; + var mouseDownPosition = {}; + var mouseDownSize = {}; + var mouseDownInvertedScale = {}; + var reconnectMutationObserver; + + function documentDragMove(event) { + if (onMouseTouchDownContinue(event)) { + var pageOffset = getCoordinates(event); + var hostElementCSS = {}; + if (_resizeHorizontal || _resizeBoth) + hostElementCSS[_strWidth] = (mouseDownSize.w + (pageOffset.x - mouseDownPosition.x) * mouseDownInvertedScale.x); + if (_resizeVertical || _resizeBoth) + hostElementCSS[_strHeight] = (mouseDownSize.h + (pageOffset.y - mouseDownPosition.y) * mouseDownInvertedScale.y); + _hostElement.css(hostElementCSS); + COMPATIBILITY.stpP(event); + } + else { + documentMouseTouchUp(event); + } + } + function documentMouseTouchUp(event) { + var eventIsTrusted = event !== undefined; + + setupResponsiveEventListener(_documentElement, + [_strSelectStartEvent, _strMouseTouchMoveEvent, _strMouseTouchUpEvent], + [documentOnSelectStart, documentDragMove, documentMouseTouchUp], + true); + + removeClass(_bodyElement, _classNameDragging); + if (_scrollbarCornerElement.releaseCapture) + _scrollbarCornerElement.releaseCapture(); + + if (eventIsTrusted) { + if (reconnectMutationObserver) + connectMutationObservers(); + _base.update(_strAuto); + } + reconnectMutationObserver = false; + } + function onMouseTouchDownContinue(event) { + var originalEvent = event.originalEvent || event; + var isTouchEvent = originalEvent.touches !== undefined; + return _sleeping || _destroyed ? false : COMPATIBILITY.mBtn(event) === 1 || isTouchEvent; + } + function getCoordinates(event) { + return _msieVersion && insideIFrame ? { x: event.screenX, y: event.screenY } : COMPATIBILITY.page(event); + } + + addDestroyEventListener(_scrollbarCornerElement, _strMouseTouchDownEvent, function (event) { + if (onMouseTouchDownContinue(event) && !_resizeNone) { + if (_mutationObserversConnected) { + reconnectMutationObserver = true; + disconnectMutationObservers(); + } + + mouseDownPosition = getCoordinates(event); + + mouseDownSize.w = _hostElementNative[LEXICON.oW] - (!_isBorderBox ? _paddingX : 0); + mouseDownSize.h = _hostElementNative[LEXICON.oH] - (!_isBorderBox ? _paddingY : 0); + mouseDownInvertedScale = getHostElementInvertedScale(); + + setupResponsiveEventListener(_documentElement, + [_strSelectStartEvent, _strMouseTouchMoveEvent, _strMouseTouchUpEvent], + [documentOnSelectStart, documentDragMove, documentMouseTouchUp]); + + addClass(_bodyElement, _classNameDragging); + if (_scrollbarCornerElement.setCapture) + _scrollbarCornerElement.setCapture(); + + COMPATIBILITY.prvD(event); + COMPATIBILITY.stpP(event); + } + }); + } + + + //==== Utils ====// + + /** + * Calls the callback with the given name. The Context of this callback is always _base (this). + * @param name The name of the target which shall be called. + * @param args The args with which the callback shall be called. + */ + function dispatchCallback(name, args) { + if (_initialized) { + var callback = _currentPreparedOptions.callbacks[name]; + var extensionOnName = name; + var ext; + + if (extensionOnName.substr(0, 2) === 'on') + extensionOnName = extensionOnName.substr(2, 1).toLowerCase() + extensionOnName.substr(3); + + if (type(callback) == TYPES.f) + callback.call(_base, args); + + each(_extensions, function () { + ext = this; + if (type(ext.on) == TYPES.f) + ext.on(extensionOnName, args); + }); + } + else if (!_destroyed) + _callbacksInitQeueue.push({ n: name, a: args }); + } + + /** + * Sets the "top, right, bottom, left" properties, with a given prefix, of the given css object. + * @param targetCSSObject The css object to which the values shall be applied. + * @param prefix The prefix of the "top, right, bottom, left" css properties. (example: 'padding-' is a valid prefix) + * @param values A array of values which shall be applied to the "top, right, bottom, left" -properties. The array order is [top, right, bottom, left]. + * If this argument is undefined the value '' (empty string) will be applied to all properties. + */ + function setTopRightBottomLeft(targetCSSObject, prefix, values) { + if (values === undefined) + values = [_strEmpty, _strEmpty, _strEmpty, _strEmpty]; + + targetCSSObject[prefix + _strTop] = values[0]; + targetCSSObject[prefix + _strRight] = values[1]; + targetCSSObject[prefix + _strBottom] = values[2]; + targetCSSObject[prefix + _strLeft] = values[3]; + } + + /** + * Returns the computed CSS transition string from the given element. + * @param element The element from which the transition string shall be returned. + * @returns {string} The CSS transition string from the given element. + */ + function getCSSTransitionString(element) { + var transitionStr = VENDORS._cssProperty('transition'); + var assembledValue = element.css(transitionStr); + if (assembledValue) + return assembledValue; + var regExpString = '\\s*(' + '([^,(]+(\\(.+?\\))?)+' + ')[\\s,]*'; + var regExpMain = new RegExp(regExpString); + var regExpValidate = new RegExp('^(' + regExpString + ')+$'); + var properties = 'property duration timing-function delay'.split(' '); + var result = []; + var strResult; + var valueArray; + var i = 0; + var j; + var splitCssStyleByComma = function (str) { + strResult = []; + if (!str.match(regExpValidate)) + return str; + while (str.match(regExpMain)) { + strResult.push(RegExp.$1); + str = str.replace(regExpMain, _strEmpty); + } + + return strResult; + }; + for (; i < properties[LEXICON.l]; i++) { + valueArray = splitCssStyleByComma(element.css(transitionStr + '-' + properties[i])); + for (j = 0; j < valueArray[LEXICON.l]; j++) + result[j] = (result[j] ? result[j] + _strSpace : _strEmpty) + valueArray[j]; + } + return result.join(', '); + } + + /** + * Calculates the host-elements inverted scale. (invertedScale = 1 / scale) + * @returns {{x: number, y: number}} The scale of the host-element. + */ + function getHostElementInvertedScale() { + var rect = _paddingElementNative[LEXICON.bCR](); + return { + x: _supportTransform ? 1 / (MATH.round(rect.width) / _paddingElementNative[LEXICON.oW]) || 1 : 1, + y: _supportTransform ? 1 / (MATH.round(rect.height) / _paddingElementNative[LEXICON.oH]) || 1 : 1 + }; + } + + /** + * Checks whether the given object is a HTMLElement. + * @param o The object which shall be checked. + * @returns {boolean} True the given object is a HTMLElement, false otherwise. + */ + function isHTMLElement(o) { + var strOwnerDocument = 'ownerDocument'; + var strHTMLElement = 'HTMLElement'; + var wnd = o && o[strOwnerDocument] ? (o[strOwnerDocument].parentWindow || window) : window; + return ( + typeof wnd[strHTMLElement] == TYPES.o ? o instanceof wnd[strHTMLElement] : //DOM2 + o && typeof o == TYPES.o && o !== null && o.nodeType === 1 && typeof o.nodeName == TYPES.s + ); + } + + /** + * Compares 2 arrays and returns the differences between them as a array. + * @param a1 The first array which shall be compared. + * @param a2 The second array which shall be compared. + * @returns {Array} The differences between the two arrays. + */ + function getArrayDifferences(a1, a2) { + var a = []; + var diff = []; + var i; + var k; + for (i = 0; i < a1.length; i++) + a[a1[i]] = true; + for (i = 0; i < a2.length; i++) { + if (a[a2[i]]) + delete a[a2[i]]; + else + a[a2[i]] = true; + } + for (k in a) + diff.push(k); + return diff; + } + + /** + * Returns Zero or the number to which the value can be parsed. + * @param value The value which shall be parsed. + * @param toFloat Indicates whether the number shall be parsed to a float. + */ + function parseToZeroOrNumber(value, toFloat) { + var num = toFloat ? parseFloat(value) : parseInt(value, 10); + return isNaN(num) ? 0 : num; + } + + /** + * Gets several information of the textarea and returns them as a object or undefined if the browser doesn't support it. + * @returns {{cursorRow: Number, cursorCol, rows: Number, cols: number, wRow: number, pos: number, max : number}} or undefined if not supported. + */ + function getTextareaInfo() { + //read needed values + var textareaCursorPosition = _targetElementNative.selectionStart; + if (textareaCursorPosition === undefined) + return; + + var textareaValue = _targetElement.val(); + var textareaLength = textareaValue[LEXICON.l]; + var textareaRowSplit = textareaValue.split('\n'); + var textareaLastRow = textareaRowSplit[LEXICON.l]; + var textareaCurrentCursorRowSplit = textareaValue.substr(0, textareaCursorPosition).split('\n'); + var widestRow = 0; + var textareaLastCol = 0; + var cursorRow = textareaCurrentCursorRowSplit[LEXICON.l]; + var cursorCol = textareaCurrentCursorRowSplit[textareaCurrentCursorRowSplit[LEXICON.l] - 1][LEXICON.l]; + var rowCols; + var i; + + //get widest Row and the last column of the textarea + for (i = 0; i < textareaRowSplit[LEXICON.l]; i++) { + rowCols = textareaRowSplit[i][LEXICON.l]; + if (rowCols > textareaLastCol) { + widestRow = i + 1; + textareaLastCol = rowCols; + } + } + + return { + _cursorRow: cursorRow, //cursorRow + _cursorColumn: cursorCol, //cursorCol + _rows: textareaLastRow, //rows + _columns: textareaLastCol, //cols + _widestRow: widestRow, //wRow + _cursorPosition: textareaCursorPosition, //pos + _cursorMax: textareaLength //max + }; + } + + /** + * Determines whether native overlay scrollbars are active. + * @returns {boolean} True if native overlay scrollbars are active, false otherwise. + */ + function nativeOverlayScrollbarsAreActive() { + return (_ignoreOverlayScrollbarHidingCache && (_nativeScrollbarIsOverlaid.x && _nativeScrollbarIsOverlaid.y)); + } + + /** + * Gets the element which is used to measure the content size. + * @returns {*} TextareaCover if target element is textarea else the ContentElement. + */ + function getContentMeasureElement() { + return _isTextarea ? _textareaCoverElement[0] : _contentElementNative; + } + + /** + * Generates a string which represents a HTML div with the given classes or attributes. + * @param classesOrAttrs The class of the div as string or a object which represents the attributes of the div. (The class attribute can also be written as "className".) + * @param content The content of the div as string. + * @returns {string} The concated string which represents a HTML div and its content. + */ + function generateDiv(classesOrAttrs, content) { + return '
' + + (content || _strEmpty) + + '
'; + } + + /** + * Selects or generates a div with the given class attribute. + * @param className The class names (divided by spaces) of the div which shall be selected or generated. + * @param selectParentOrOnlyChildren The parent element from which of the element shall be selected. (if undefined or boolean its hostElement) + * If its a boolean it decides whether only the children of the host element shall be selected. + * @returns {*} The generated or selected element. + */ + function selectOrGenerateDivByClass(className, selectParentOrOnlyChildren) { + var onlyChildren = type(selectParentOrOnlyChildren) == TYPES.b; + var selectParent = onlyChildren ? _hostElement : (selectParentOrOnlyChildren || _hostElement); + + return (_domExists && !selectParent[LEXICON.l]) + ? null + : _domExists + ? selectParent[onlyChildren ? 'children' : 'find'](_strDot + className.replace(/\s/g, _strDot)).eq(0) + : FRAMEWORK(generateDiv(className)) + } + + /** + * Gets the value of the given property from the given object. + * @param obj The object from which the property value shall be got. + * @param path The property of which the value shall be got. + * @returns {*} Returns the value of the searched property or undefined of the property wasn't found. + */ + function getObjectPropVal(obj, path) { + var splits = path.split(_strDot); + var i = 0; + var val; + for (; i < splits.length; i++) { + if (!obj[LEXICON.hOP](splits[i])) + return; + val = obj[splits[i]]; + if (i < splits.length && type(val) == TYPES.o) + obj = val; + } + return val; + } + + /** + * Sets the value of the given property from the given object. + * @param obj The object from which the property value shall be set. + * @param path The property of which the value shall be set. + * @param val The value of the property which shall be set. + */ + function setObjectPropVal(obj, path, val) { + var splits = path.split(_strDot); + var splitsLength = splits.length; + var i = 0; + var extendObj = {}; + var extendObjRoot = extendObj; + for (; i < splitsLength; i++) + extendObj = extendObj[splits[i]] = i + 1 < splitsLength ? {} : val; + FRAMEWORK.extend(obj, extendObjRoot, true); + } + + + //==== Utils Cache ====// + + /** + * Compares two values or objects and returns true if they aren't equal. + * @param current The first value or object which shall be compared. + * @param cache The second value or object which shall be compared. + * @param force If true the returned value is always true. + * @returns {boolean} True if both values or objects aren't equal or force is true, false otherwise. + */ + function checkCache(current, cache, force) { + if (force) + return force; + if (type(current) == TYPES.o && type(cache) == TYPES.o) { + for (var prop in current) { + if (prop !== 'c') { + if (current[LEXICON.hOP](prop) && cache[LEXICON.hOP](prop)) { + if (checkCache(current[prop], cache[prop])) + return true; + } + else { + return true; + } + } + } + } + else { + return current !== cache; + } + return false; + } + + + //==== Shortcuts ====// + + /** + * jQuery extend method shortcut with a appended "true" as first argument. + */ + function extendDeep() { + return FRAMEWORK.extend.apply(this, [true].concat([].slice.call(arguments))); + } + + /** + * jQuery addClass method shortcut. + */ + function addClass(el, classes) { + return _frameworkProto.addClass.call(el, classes); + } + + /** + * jQuery removeClass method shortcut. + */ + function removeClass(el, classes) { + return _frameworkProto.removeClass.call(el, classes); + } + + /** + * jQuery remove method shortcut. + */ + function remove(el) { + return _frameworkProto.remove.call(el); + } + + /** + * Finds the first child element with the given selector of the given element. + * @param el The root element from which the selector shall be valid. + * @param selector The selector of the searched element. + * @returns {*} The first element which is a child of the given element and matches the givens selector. + */ + function findFirst(el, selector) { + return _frameworkProto.find.call(el, selector).eq(0); + } + + + //==== API ====// + + /** + * Puts the instance to sleep. It wont respond to any changes in the DOM and won't update. Scrollbar Interactivity is also disabled as well as the resize handle. + * This behavior can be reset by calling the update method. + */ + _base.sleep = function () { + _sleeping = true; + }; + + /** + * Updates the plugin and DOM to the current options. + * This method should only be called if a update is 100% required. + * @param force True if every property shall be updated and the cache shall be ignored. + * !INTERNAL USAGE! : force can be a string "auto", "sync" or "zoom" too + * if "auto" then before a real update the content size and host element attributes gets checked, and if they changed only then the update method will be called. + * if "sync" then the async update process (MutationObserver or UpdateLoop) gets synchronized and a corresponding update takes place if one was needed due to pending changes. + * if "zoom" then a update takes place where it's assumed that content and host size changed + * @returns {boolean|undefined} + * If force is "sync" then a boolean is returned which indicates whether a update was needed due to pending changes. + * If force is "auto" then a boolean is returned whether a update was needed due to attribute or size changes. + * undefined otherwise. + */ + _base.update = function (force) { + if (_destroyed) + return; + + var attrsChanged; + var contentSizeC; + var isString = type(force) == TYPES.s; + var imgElementSelector = 'img'; + var imgElementLoadEvent = 'load'; + var doUpdateAuto; + var mutHost; + var mutContent; + + if (isString) { + if (force === _strAuto) { + attrsChanged = meaningfulAttrsChanged(); + contentSizeC = updateAutoContentSizeChanged(); + doUpdateAuto = attrsChanged || contentSizeC; + if (doUpdateAuto) { + update({ + _contentSizeChanged: contentSizeC, + _changedOptions: _initialized ? undefined : _currentPreparedOptions + }); + } + } + else if (force === _strSync) { + if (_mutationObserversConnected) { + mutHost = _mutationObserverHostCallback(_mutationObserverHost.takeRecords()); + mutContent = _mutationObserverContentCallback(_mutationObserverContent.takeRecords()); + } + else { + mutHost = _base.update(_strAuto); + } + } + else if (force === 'zoom') { + update({ + _hostSizeChanged: true, + _contentSizeChanged: true + }); + } + } + else { + force = _sleeping || force; + _sleeping = false; + if (!_base.update(_strSync) || force) + update({ _force: force }); + } + if (!_isTextarea) { + _contentElement.find(imgElementSelector).each(function (i, el) { + var index = COMPATIBILITY.inA(el, _imgs); + if (index === -1) + FRAMEWORK(el).off(imgElementLoadEvent, imgOnLoad).on(imgElementLoadEvent, imgOnLoad); + }); + } + return doUpdateAuto || mutHost || mutContent; + }; + + /** + Gets or sets the current options. The update method will be called automatically if new options were set. + * @param newOptions If new options are given, then the new options will be set, if new options aren't given (undefined or a not a plain object) then the current options will be returned. + * @param value If new options is a property path string, then this value will be used to set the option to which the property path string leads. + * @returns {*} + */ + _base.options = function (newOptions, value) { + var option = {}; + var changedOps; + + //return current options if newOptions are undefined or empty + if (FRAMEWORK.isEmptyObject(newOptions) || !FRAMEWORK.isPlainObject(newOptions)) { + if (type(newOptions) == TYPES.s) { + if (arguments.length > 1) { + setObjectPropVal(option, newOptions, value); + changedOps = setOptions(option); + } + else + return getObjectPropVal(_currentOptions, newOptions); + } + else + return _currentOptions; + } + else { + changedOps = setOptions(newOptions); + } + + if (!FRAMEWORK.isEmptyObject(changedOps)) { + update({ _changedOptions: changedOps }); + } + }; + + /** + * Restore the DOM, disconnects all observers, remove all resize observers and put the instance to sleep. + */ + _base.destroy = function () { + if (_destroyed) + return; + + //remove this instance from auto update loop + autoUpdateLoop.remove(_base); + + //disconnect all mutation observers + disconnectMutationObservers(); + + //remove all resize observers + setupResizeObserver(_sizeObserverElement); + setupResizeObserver(_sizeAutoObserverElement); + + //remove all extensions + for (var extName in _extensions) + _base.removeExt(extName); + + //remove all 'destroy' events + while (_destroyEvents[LEXICON.l] > 0) + _destroyEvents.pop()(); + + //remove all events from host element + setupHostMouseTouchEvents(true); + + //remove all helper / detection elements + if (_contentGlueElement) + remove(_contentGlueElement); + if (_contentArrangeElement) + remove(_contentArrangeElement); + if (_sizeAutoObserverAdded) + remove(_sizeAutoObserverElement); + + //remove all generated DOM + setupScrollbarsDOM(true); + setupScrollbarCornerDOM(true); + setupStructureDOM(true); + + //remove all generated image load events + for (var i = 0; i < _imgs[LEXICON.l]; i++) + FRAMEWORK(_imgs[i]).off('load', imgOnLoad); + _imgs = undefined; + + _destroyed = true; + _sleeping = true; + + //remove this instance from the instances list + INSTANCES(pluginTargetElement, 0); + dispatchCallback('onDestroyed'); + + //remove all properties and methods + //for (var property in _base) + // delete _base[property]; + //_base = undefined; + }; + + /** + * Scrolls to a given position or element. + * @param coordinates + * 1. Can be "coordinates" which looks like: + * { x : ?, y : ? } OR Object with x and y properties + * { left : ?, top : ? } OR Object with left and top properties + * { l : ?, t : ? } OR Object with l and t properties + * [ ?, ? ] OR Array where the first two element are the coordinates (first is x, second is y) + * ? A single value which stays for both axis + * A value can be a number, a string or a calculation. + * + * Operators: + * [NONE] The current scroll will be overwritten by the value. + * '+=' The value will be added to the current scroll offset + * '-=' The value will be subtracted from the current scroll offset + * '*=' The current scroll wil be multiplicated by the value. + * '/=' The current scroll wil be divided by the value. + * + * Units: + * [NONE] The value is the final scroll amount. final = (value * 1) + * 'px' Same as none + * '%' The value is dependent on the current scroll value. final = ((currentScrollValue / 100) * value) + * 'vw' The value is multiplicated by the viewport width. final = (value * viewportWidth) + * 'vh' The value is multiplicated by the viewport height. final = (value * viewportHeight) + * + * example final values: + * 200, '200px', '50%', '1vw', '1vh', '+=200', '/=1vw', '*=2px', '-=5vh', '+=33%', '+= 50% - 2px', '-= 1vw - 50%' + * + * 2. Can be a HTML or jQuery element: + * The final scroll offset is the offset (without margin) of the given HTML / jQuery element. + * + * 3. Can be a object with a HTML or jQuery element with additional settings: + * { + * el : [HTMLElement, jQuery element], MUST be specified, else this object isn't valid. + * scroll : [string, array, object], Default value is 'always'. + * block : [string, array, object], Default value is 'begin'. + * margin : [number, boolean, array, object] Default value is false. + * } + * + * Possible scroll settings are: + * 'always' Scrolls always. + * 'ifneeded' Scrolls only if the element isnt fully in view. + * 'never' Scrolls never. + * + * Possible block settings are: + * 'begin' Both axis shall be docked to the "begin" edge. - The element will be docked to the top and left edge of the viewport. + * 'end' Both axis shall be docked to the "end" edge. - The element will be docked to the bottom and right edge of the viewport. (If direction is RTL to the bottom and left edge.) + * 'center' Both axis shall be docked to "center". - The element will be centered in the viewport. + * 'nearest' The element will be docked to the nearest edge(s). + * + * Possible margin settings are: -- The actual margin of the element wont be affect, this option affects only the final scroll offset. + * [BOOLEAN] If true the css margin of the element will be used, if false no margin will be used. + * [NUMBER] The margin will be used for all edges. + * + * @param duration The duration of the scroll animation, OR a jQuery animation configuration object. + * @param easing The animation easing. + * @param complete The animation complete callback. + * @returns {{ + * position: {x: number, y: number}, + * ratio: {x: number, y: number}, + * max: {x: number, y: number}, + * handleOffset: {x: number, y: number}, + * handleLength: {x: number, y: number}, + * handleLengthRatio: {x: number, y: number}, t + * rackLength: {x: number, y: number}, + * isRTL: boolean, + * isRTLNormalized: boolean + * -}} + */ + _base.scroll = function (coordinates, duration, easing, complete) { + if (arguments.length === 0 || coordinates === undefined) { + var infoX = _scrollHorizontalInfo; + var infoY = _scrollVerticalInfo; + var normalizeInvert = _normalizeRTLCache && _isRTL && _rtlScrollBehavior.i; + var normalizeNegate = _normalizeRTLCache && _isRTL && _rtlScrollBehavior.n; + var scrollX = infoX._currentScroll; + var scrollXRatio = infoX._currentScrollRatio; + var maxScrollX = infoX._maxScroll; + scrollXRatio = normalizeInvert ? 1 - scrollXRatio : scrollXRatio; + scrollX = normalizeInvert ? maxScrollX - scrollX : scrollX; + scrollX *= normalizeNegate ? -1 : 1; + maxScrollX *= normalizeNegate ? -1 : 1; + + return { + position: { + x: scrollX, + y: infoY._currentScroll + }, + ratio: { + x: scrollXRatio, + y: infoY._currentScrollRatio + }, + max: { + x: maxScrollX, + y: infoY._maxScroll + }, + handleOffset: { + x: infoX._handleOffset, + y: infoY._handleOffset + }, + handleLength: { + x: infoX._handleLength, + y: infoY._handleLength + }, + handleLengthRatio: { + x: infoX._handleLengthRatio, + y: infoY._handleLengthRatio + }, + trackLength: { + x: infoX._trackLength, + y: infoY._trackLength + }, + snappedHandleOffset: { + x: infoX._snappedHandleOffset, + y: infoY._snappedHandleOffset + }, + isRTL: _isRTL, + isRTLNormalized: _normalizeRTLCache + }; + } + + _base.update(_strSync); + + var normalizeRTL = _normalizeRTLCache; + var coordinatesXAxisProps = [_strX, _strLeft, 'l']; + var coordinatesYAxisProps = [_strY, _strTop, 't']; + var coordinatesOperators = ['+=', '-=', '*=', '/=']; + var durationIsObject = type(duration) == TYPES.o; + var completeCallback = durationIsObject ? duration.complete : complete; + var i; + var finalScroll = {}; + var specialEasing = {}; + var doScrollLeft; + var doScrollTop; + var animationOptions; + var strEnd = 'end'; + var strBegin = 'begin'; + var strCenter = 'center'; + var strNearest = 'nearest'; + var strAlways = 'always'; + var strNever = 'never'; + var strIfNeeded = 'ifneeded'; + var strLength = LEXICON.l; + var settingsAxis; + var settingsScroll; + var settingsBlock; + var settingsMargin; + var finalElement; + var elementObjSettingsAxisValues = [_strX, _strY, 'xy', 'yx']; + var elementObjSettingsBlockValues = [strBegin, strEnd, strCenter, strNearest]; + var elementObjSettingsScrollValues = [strAlways, strNever, strIfNeeded]; + var coordinatesIsElementObj = coordinates[LEXICON.hOP]('el'); + var possibleElement = coordinatesIsElementObj ? coordinates.el : coordinates; + var possibleElementIsJQuery = possibleElement instanceof FRAMEWORK || JQUERY ? possibleElement instanceof JQUERY : false; + var possibleElementIsHTMLElement = possibleElementIsJQuery ? false : isHTMLElement(possibleElement); + var updateScrollbarInfos = function () { + if (doScrollLeft) + refreshScrollbarHandleOffset(true); + if (doScrollTop) + refreshScrollbarHandleOffset(false); + }; + var proxyCompleteCallback = type(completeCallback) != TYPES.f ? undefined : function () { + updateScrollbarInfos(); + completeCallback(); + }; + function checkSettingsStringValue(currValue, allowedValues) { + for (i = 0; i < allowedValues[strLength]; i++) { + if (currValue === allowedValues[i]) + return true; + } + return false; + } + function getRawScroll(isX, coordinates) { + var coordinateProps = isX ? coordinatesXAxisProps : coordinatesYAxisProps; + coordinates = type(coordinates) == TYPES.s || type(coordinates) == TYPES.n ? [coordinates, coordinates] : coordinates; + + if (type(coordinates) == TYPES.a) + return isX ? coordinates[0] : coordinates[1]; + else if (type(coordinates) == TYPES.o) { + //decides RTL normalization "hack" with .n + //normalizeRTL = type(coordinates.n) == TYPES.b ? coordinates.n : normalizeRTL; + for (i = 0; i < coordinateProps[strLength]; i++) + if (coordinateProps[i] in coordinates) + return coordinates[coordinateProps[i]]; + } + } + function getFinalScroll(isX, rawScroll) { + var isString = type(rawScroll) == TYPES.s; + var operator; + var amount; + var scrollInfo = isX ? _scrollHorizontalInfo : _scrollVerticalInfo; + var currScroll = scrollInfo._currentScroll; + var maxScroll = scrollInfo._maxScroll; + var mult = ' * '; + var finalValue; + var isRTLisX = _isRTL && isX; + var normalizeShortcuts = isRTLisX && _rtlScrollBehavior.n && !normalizeRTL; + var strReplace = 'replace'; + var evalFunc = eval; + var possibleOperator; + if (isString) { + //check operator + if (rawScroll[strLength] > 2) { + possibleOperator = rawScroll.substr(0, 2); + if (inArray(possibleOperator, coordinatesOperators) > -1) + operator = possibleOperator; + } + + //calculate units and shortcuts + rawScroll = operator ? rawScroll.substr(2) : rawScroll; + rawScroll = rawScroll + [strReplace](/min/g, 0) //'min' = 0% + [strReplace](//g, (normalizeShortcuts ? '-' : _strEmpty) + _strHundredPercent) //'>' = 100% + [strReplace](/px/g, _strEmpty) + [strReplace](/%/g, mult + (maxScroll * (isRTLisX && _rtlScrollBehavior.n ? -1 : 1) / 100.0)) + [strReplace](/vw/g, mult + _viewportSize.w) + [strReplace](/vh/g, mult + _viewportSize.h); + amount = parseToZeroOrNumber(isNaN(rawScroll) ? parseToZeroOrNumber(evalFunc(rawScroll), true).toFixed() : rawScroll); + } + else { + amount = rawScroll; + } + + if (amount !== undefined && !isNaN(amount) && type(amount) == TYPES.n) { + var normalizeIsRTLisX = normalizeRTL && isRTLisX; + var operatorCurrScroll = currScroll * (normalizeIsRTLisX && _rtlScrollBehavior.n ? -1 : 1); + var invert = normalizeIsRTLisX && _rtlScrollBehavior.i; + var negate = normalizeIsRTLisX && _rtlScrollBehavior.n; + operatorCurrScroll = invert ? (maxScroll - operatorCurrScroll) : operatorCurrScroll; + switch (operator) { + case '+=': + finalValue = operatorCurrScroll + amount; + break; + case '-=': + finalValue = operatorCurrScroll - amount; + break; + case '*=': + finalValue = operatorCurrScroll * amount; + break; + case '/=': + finalValue = operatorCurrScroll / amount; + break; + default: + finalValue = amount; + break; + } + finalValue = invert ? maxScroll - finalValue : finalValue; + finalValue *= negate ? -1 : 1; + finalValue = isRTLisX && _rtlScrollBehavior.n ? MATH.min(0, MATH.max(maxScroll, finalValue)) : MATH.max(0, MATH.min(maxScroll, finalValue)); + } + return finalValue === currScroll ? undefined : finalValue; + } + function getPerAxisValue(value, valueInternalType, defaultValue, allowedValues) { + var resultDefault = [defaultValue, defaultValue]; + var valueType = type(value); + var valueArrLength; + var valueArrItem; + + //value can be [ string, or array of two strings ] + if (valueType == valueInternalType) { + value = [value, value]; + } + else if (valueType == TYPES.a) { + valueArrLength = value[strLength]; + if (valueArrLength > 2 || valueArrLength < 1) + value = resultDefault; + else { + if (valueArrLength === 1) + value[1] = defaultValue; + for (i = 0; i < valueArrLength; i++) { + valueArrItem = value[i]; + if (type(valueArrItem) != valueInternalType || !checkSettingsStringValue(valueArrItem, allowedValues)) { + value = resultDefault; + break; + } + } + } + } + else if (valueType == TYPES.o) + value = [value[_strX] || defaultValue, value[_strY] || defaultValue]; + else + value = resultDefault; + return { x: value[0], y: value[1] }; + } + function generateMargin(marginTopRightBottomLeftArray) { + var result = []; + var currValue; + var currValueType; + var valueDirections = [_strTop, _strRight, _strBottom, _strLeft]; + for (i = 0; i < marginTopRightBottomLeftArray[strLength]; i++) { + if (i === valueDirections[strLength]) + break; + currValue = marginTopRightBottomLeftArray[i]; + currValueType = type(currValue); + if (currValueType == TYPES.b) + result.push(currValue ? parseToZeroOrNumber(finalElement.css(_strMarginMinus + valueDirections[i])) : 0); + else + result.push(currValueType == TYPES.n ? currValue : 0); + } + return result; + } + + if (possibleElementIsJQuery || possibleElementIsHTMLElement) { + //get settings + var margin = coordinatesIsElementObj ? coordinates.margin : 0; + var axis = coordinatesIsElementObj ? coordinates.axis : 0; + var scroll = coordinatesIsElementObj ? coordinates.scroll : 0; + var block = coordinatesIsElementObj ? coordinates.block : 0; + var marginDefault = [0, 0, 0, 0]; + var marginType = type(margin); + var marginLength; + finalElement = possibleElementIsJQuery ? possibleElement : FRAMEWORK(possibleElement); + + if (finalElement[strLength] > 0) { + //margin can be [ boolean, number, array of 2, array of 4, object ] + if (marginType == TYPES.n || marginType == TYPES.b) + margin = generateMargin([margin, margin, margin, margin]); + else if (marginType == TYPES.a) { + marginLength = margin[strLength]; + if (marginLength === 2) + margin = generateMargin([margin[0], margin[1], margin[0], margin[1]]); + else if (marginLength >= 4) + margin = generateMargin(margin); + else + margin = marginDefault; + } + else if (marginType == TYPES.o) + margin = generateMargin([margin[_strTop], margin[_strRight], margin[_strBottom], margin[_strLeft]]); + else + margin = marginDefault; + + //block = type(block) === TYPES.b ? block ? [ strNearest, strBegin ] : [ strNearest, strEnd ] : block; + settingsAxis = checkSettingsStringValue(axis, elementObjSettingsAxisValues) ? axis : 'xy'; + settingsScroll = getPerAxisValue(scroll, TYPES.s, strAlways, elementObjSettingsScrollValues); + settingsBlock = getPerAxisValue(block, TYPES.s, strBegin, elementObjSettingsBlockValues); + settingsMargin = margin; + + var viewportScroll = { + l: _scrollHorizontalInfo._currentScroll, + t: _scrollVerticalInfo._currentScroll + }; + // use padding element instead of viewport element because padding element has never padding, margin or position applied. + var viewportOffset = _paddingElement.offset(); + + //get coordinates + var elementOffset = finalElement.offset(); + var doNotScroll = { + x: settingsScroll.x == strNever || settingsAxis == _strY, + y: settingsScroll.y == strNever || settingsAxis == _strX + }; + elementOffset[_strTop] -= settingsMargin[0]; + elementOffset[_strLeft] -= settingsMargin[3]; + var elementScrollCoordinates = { + x: MATH.round(elementOffset[_strLeft] - viewportOffset[_strLeft] + viewportScroll.l), + y: MATH.round(elementOffset[_strTop] - viewportOffset[_strTop] + viewportScroll.t) + }; + if (_isRTL) { + if (!_rtlScrollBehavior.n && !_rtlScrollBehavior.i) + elementScrollCoordinates.x = MATH.round(viewportOffset[_strLeft] - elementOffset[_strLeft] + viewportScroll.l); + if (_rtlScrollBehavior.n && normalizeRTL) + elementScrollCoordinates.x *= -1; + if (_rtlScrollBehavior.i && normalizeRTL) + elementScrollCoordinates.x = MATH.round(viewportOffset[_strLeft] - elementOffset[_strLeft] + (_scrollHorizontalInfo._maxScroll - viewportScroll.l)); + } + + //measuring is required + if (settingsBlock.x != strBegin || settingsBlock.y != strBegin || settingsScroll.x == strIfNeeded || settingsScroll.y == strIfNeeded || _isRTL) { + var measuringElm = finalElement[0]; + var rawElementSize = _supportTransform ? measuringElm[LEXICON.bCR]() : { + width: measuringElm[LEXICON.oW], + height: measuringElm[LEXICON.oH] + }; + var elementSize = { + w: rawElementSize[_strWidth] + settingsMargin[3] + settingsMargin[1], + h: rawElementSize[_strHeight] + settingsMargin[0] + settingsMargin[2] + }; + var finalizeBlock = function (isX) { + var vars = getScrollbarVars(isX); + var wh = vars._w_h; + var lt = vars._left_top; + var xy = vars._x_y; + var blockIsEnd = settingsBlock[xy] == (isX ? _isRTL ? strBegin : strEnd : strEnd); + var blockIsCenter = settingsBlock[xy] == strCenter; + var blockIsNearest = settingsBlock[xy] == strNearest; + var scrollNever = settingsScroll[xy] == strNever; + var scrollIfNeeded = settingsScroll[xy] == strIfNeeded; + var vpSize = _viewportSize[wh]; + var vpOffset = viewportOffset[lt]; + var elSize = elementSize[wh]; + var elOffset = elementOffset[lt]; + var divide = blockIsCenter ? 2 : 1; + var elementCenterOffset = elOffset + (elSize / 2); + var viewportCenterOffset = vpOffset + (vpSize / 2); + var isInView = + elSize <= vpSize + && elOffset >= vpOffset + && elOffset + elSize <= vpOffset + vpSize; + + if (scrollNever) + doNotScroll[xy] = true; + else if (!doNotScroll[xy]) { + if (blockIsNearest || scrollIfNeeded) { + doNotScroll[xy] = scrollIfNeeded ? isInView : false; + blockIsEnd = elSize < vpSize ? elementCenterOffset > viewportCenterOffset : elementCenterOffset < viewportCenterOffset; + } + elementScrollCoordinates[xy] -= blockIsEnd || blockIsCenter ? ((vpSize / divide) - (elSize / divide)) * (isX && _isRTL && normalizeRTL ? -1 : 1) : 0; + } + }; + finalizeBlock(true); + finalizeBlock(false); + } + + if (doNotScroll.y) + delete elementScrollCoordinates.y; + if (doNotScroll.x) + delete elementScrollCoordinates.x; + + coordinates = elementScrollCoordinates; + } + } + + finalScroll[_strScrollLeft] = getFinalScroll(true, getRawScroll(true, coordinates)); + finalScroll[_strScrollTop] = getFinalScroll(false, getRawScroll(false, coordinates)); + doScrollLeft = finalScroll[_strScrollLeft] !== undefined; + doScrollTop = finalScroll[_strScrollTop] !== undefined; + + if ((doScrollLeft || doScrollTop) && (duration > 0 || durationIsObject)) { + if (durationIsObject) { + duration.complete = proxyCompleteCallback; + _viewportElement.animate(finalScroll, duration); + } + else { + animationOptions = { + duration: duration, + complete: proxyCompleteCallback + }; + if (type(easing) == TYPES.a || FRAMEWORK.isPlainObject(easing)) { + specialEasing[_strScrollLeft] = easing[0] || easing.x; + specialEasing[_strScrollTop] = easing[1] || easing.y; + animationOptions.specialEasing = specialEasing; + } + else { + animationOptions.easing = easing; + } + _viewportElement.animate(finalScroll, animationOptions); + } + } + else { + if (doScrollLeft) + _viewportElement[_strScrollLeft](finalScroll[_strScrollLeft]); + if (doScrollTop) + _viewportElement[_strScrollTop](finalScroll[_strScrollTop]); + updateScrollbarInfos(); + } + }; + + /** + * Stops all scroll animations. + * @returns {*} The current OverlayScrollbars instance (for chaining). + */ + _base.scrollStop = function (param1, param2, param3) { + _viewportElement.stop(param1, param2, param3); + return _base; + }; + + /** + * Returns all relevant elements. + * @param elementName The name of the element which shall be returned. + * @returns {{target: *, host: *, padding: *, viewport: *, content: *, scrollbarHorizontal: {scrollbar: *, track: *, handle: *}, scrollbarVertical: {scrollbar: *, track: *, handle: *}, scrollbarCorner: *} | *} + */ + _base.getElements = function (elementName) { + var obj = { + target: _targetElementNative, + host: _hostElementNative, + padding: _paddingElementNative, + viewport: _viewportElementNative, + content: _contentElementNative, + scrollbarHorizontal: { + scrollbar: _scrollbarHorizontalElement[0], + track: _scrollbarHorizontalTrackElement[0], + handle: _scrollbarHorizontalHandleElement[0] + }, + scrollbarVertical: { + scrollbar: _scrollbarVerticalElement[0], + track: _scrollbarVerticalTrackElement[0], + handle: _scrollbarVerticalHandleElement[0] + }, + scrollbarCorner: _scrollbarCornerElement[0] + }; + return type(elementName) == TYPES.s ? getObjectPropVal(obj, elementName) : obj; + }; + + /** + * Returns a object which describes the current state of this instance. + * @param stateProperty A specific property from the state object which shall be returned. + * @returns {{widthAuto, heightAuto, overflowAmount, hideOverflow, hasOverflow, contentScrollSize, viewportSize, hostSize, autoUpdate} | *} + */ + _base.getState = function (stateProperty) { + function prepare(obj) { + if (!FRAMEWORK.isPlainObject(obj)) + return obj; + var extended = extendDeep({}, obj); + var changePropertyName = function (from, to) { + if (extended[LEXICON.hOP](from)) { + extended[to] = extended[from]; + delete extended[from]; + } + }; + changePropertyName('w', _strWidth); //change w to width + changePropertyName('h', _strHeight); //change h to height + delete extended.c; //delete c (the 'changed' prop) + return extended; + }; + var obj = { + destroyed: !!prepare(_destroyed), + sleeping: !!prepare(_sleeping), + autoUpdate: prepare(!_mutationObserversConnected), + widthAuto: prepare(_widthAutoCache), + heightAuto: prepare(_heightAutoCache), + padding: prepare(_cssPaddingCache), + overflowAmount: prepare(_overflowAmountCache), + hideOverflow: prepare(_hideOverflowCache), + hasOverflow: prepare(_hasOverflowCache), + contentScrollSize: prepare(_contentScrollSizeCache), + viewportSize: prepare(_viewportSize), + hostSize: prepare(_hostSizeCache), + documentMixed: prepare(_documentMixed) + }; + return type(stateProperty) == TYPES.s ? getObjectPropVal(obj, stateProperty) : obj; + }; + + /** + * Gets all or specific extension instance. + * @param extName The name of the extension from which the instance shall be got. + * @returns {{}} The instance of the extension with the given name or undefined if the instance couldn't be found. + */ + _base.ext = function (extName) { + var result; + var privateMethods = _extensionsPrivateMethods.split(' '); + var i = 0; + if (type(extName) == TYPES.s) { + if (_extensions[LEXICON.hOP](extName)) { + result = extendDeep({}, _extensions[extName]); + for (; i < privateMethods.length; i++) + delete result[privateMethods[i]]; + } + } + else { + result = {}; + for (i in _extensions) + result[i] = extendDeep({}, _base.ext(i)); + } + return result; + }; + + /** + * Adds a extension to this instance. + * @param extName The name of the extension which shall be added. + * @param extensionOptions The extension options which shall be used. + * @returns {{}} The instance of the added extension or undefined if the extension couldn't be added properly. + */ + _base.addExt = function (extName, extensionOptions) { + var registeredExtensionObj = _plugin.extension(extName); + var instance; + var instanceAdded; + var instanceContract; + var contractResult; + var contractFulfilled = true; + if (registeredExtensionObj) { + if (!_extensions[LEXICON.hOP](extName)) { + instance = registeredExtensionObj.extensionFactory.call(_base, + extendDeep({}, registeredExtensionObj.defaultOptions), + FRAMEWORK, + COMPATIBILITY); + + if (instance) { + instanceContract = instance.contract; + if (type(instanceContract) == TYPES.f) { + contractResult = instanceContract(window); + contractFulfilled = type(contractResult) == TYPES.b ? contractResult : contractFulfilled; + } + if (contractFulfilled) { + _extensions[extName] = instance; + instanceAdded = instance.added; + if (type(instanceAdded) == TYPES.f) + instanceAdded(extensionOptions); + + return _base.ext(extName); + } + } + } + else + return _base.ext(extName); + } + else + console.warn("A extension with the name \"" + extName + "\" isn't registered."); + }; + + /** + * Removes a extension from this instance. + * @param extName The name of the extension which shall be removed. + * @returns {boolean} True if the extension was removed, false otherwise e.g. if the extension wasn't added before. + */ + _base.removeExt = function (extName) { + var instance = _extensions[extName]; + var instanceRemoved; + if (instance) { + delete _extensions[extName]; + + instanceRemoved = instance.removed; + if (type(instanceRemoved) == TYPES.f) + instanceRemoved(); + + return true; + } + return false; + }; + + /** + * Constructs the plugin. + * @param targetElement The element to which the plugin shall be applied. + * @param options The initial options of the plugin. + * @param extensions The extension(s) which shall be added right after the initialization. + * @returns {boolean} True if the plugin was successfully initialized, false otherwise. + */ + function construct(targetElement, options, extensions) { + _defaultOptions = globals.defaultOptions; + _nativeScrollbarStyling = globals.nativeScrollbarStyling; + _nativeScrollbarSize = extendDeep({}, globals.nativeScrollbarSize); + _nativeScrollbarIsOverlaid = extendDeep({}, globals.nativeScrollbarIsOverlaid); + _overlayScrollbarDummySize = extendDeep({}, globals.overlayScrollbarDummySize); + _rtlScrollBehavior = extendDeep({}, globals.rtlScrollBehavior); + + //parse & set options but don't update + setOptions(extendDeep({}, _defaultOptions, options)); + + _cssCalc = globals.cssCalc; + _msieVersion = globals.msie; + _autoUpdateRecommended = globals.autoUpdateRecommended; + _supportTransition = globals.supportTransition; + _supportTransform = globals.supportTransform; + _supportPassiveEvents = globals.supportPassiveEvents; + _supportResizeObserver = globals.supportResizeObserver; + _supportMutationObserver = globals.supportMutationObserver; + _restrictedMeasuring = globals.restrictedMeasuring; + _documentElement = FRAMEWORK(targetElement.ownerDocument); + _documentElementNative = _documentElement[0]; + _windowElement = FRAMEWORK(_documentElementNative.defaultView || _documentElementNative.parentWindow); + _windowElementNative = _windowElement[0]; + _htmlElement = findFirst(_documentElement, 'html'); + _bodyElement = findFirst(_htmlElement, 'body'); + _targetElement = FRAMEWORK(targetElement); + _targetElementNative = _targetElement[0]; + _isTextarea = _targetElement.is('textarea'); + _isBody = _targetElement.is('body'); + _documentMixed = _documentElementNative !== document; + + /* On a div Element The if checks only whether: + * - the targetElement has the class "os-host" + * - the targetElement has a a child with the class "os-padding" + * + * If that's the case, its assumed the DOM has already the following structure: + * (The ".os-host" element is the targetElement) + * + *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ * + * ===================================================================================== + * + * On a Textarea Element The if checks only whether: + * - the targetElement has the class "os-textarea" + * - the targetElement is inside a element with the class "os-content" + * + * If that's the case, its assumed the DOM has already the following structure: + * (The ".os-textarea" (textarea) element is the targetElement) + * + *
+ *
+ *
+ *
+ *
+ *
+ * + *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ */ + _domExists = _isTextarea + ? _targetElement.hasClass(_classNameTextareaElement) && _targetElement.parent().hasClass(_classNameContentElement) + : _targetElement.hasClass(_classNameHostElement) && _targetElement.children(_strDot + _classNamePaddingElement)[LEXICON.l]; + + var initBodyScroll; + var bodyMouseTouchDownListener; + + //check if the plugin hasn't to be initialized + if (_nativeScrollbarIsOverlaid.x && _nativeScrollbarIsOverlaid.y && !_currentPreparedOptions.nativeScrollbarsOverlaid.initialize) { + dispatchCallback('onInitializationWithdrawn'); + if (_domExists) { + setupStructureDOM(true); + setupScrollbarsDOM(true); + setupScrollbarCornerDOM(true); + } + + _destroyed = true; + _sleeping = true; + + return _base; + } + + if (_isBody) { + initBodyScroll = {}; + initBodyScroll.l = MATH.max(_targetElement[_strScrollLeft](), _htmlElement[_strScrollLeft](), _windowElement[_strScrollLeft]()); + initBodyScroll.t = MATH.max(_targetElement[_strScrollTop](), _htmlElement[_strScrollTop](), _windowElement[_strScrollTop]()); + + bodyMouseTouchDownListener = function () { + _viewportElement.removeAttr(LEXICON.ti); + setupResponsiveEventListener(_viewportElement, _strMouseTouchDownEvent, bodyMouseTouchDownListener, true, true); + } + } + + //build OverlayScrollbars DOM + setupStructureDOM(); + setupScrollbarsDOM(); + setupScrollbarCornerDOM(); + + //create OverlayScrollbars events + setupStructureEvents(); + setupScrollbarEvents(true); + setupScrollbarEvents(false); + setupScrollbarCornerEvents(); + + //create mutation observers + createMutationObservers(); + + //build resize observer for the host element + setupResizeObserver(_sizeObserverElement, hostOnResized); + + if (_isBody) { + //apply the body scroll to handle it right in the update method + _viewportElement[_strScrollLeft](initBodyScroll.l)[_strScrollTop](initBodyScroll.t); + + //set the focus on the viewport element so you dont have to click on the page to use keyboard keys (up / down / space) for scrolling + if (document.activeElement == targetElement && _viewportElementNative.focus) { + //set a tabindex to make the viewportElement focusable + _viewportElement.attr(LEXICON.ti, '-1'); + _viewportElementNative.focus(); + + /* the tabindex has to be removed due to; + * If you set the tabindex attribute on an
, then its child content cannot be scrolled with the arrow keys unless you set tabindex on the content, too + * https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex + */ + setupResponsiveEventListener(_viewportElement, _strMouseTouchDownEvent, bodyMouseTouchDownListener, false, true); + } + } + + //update for the first time & initialize cache + _base.update(_strAuto); + + //the plugin is initialized now! + _initialized = true; + dispatchCallback('onInitialized'); + + //call all callbacks which would fire before the initialized was complete + each(_callbacksInitQeueue, function (index, value) { dispatchCallback(value.n, value.a); }); + _callbacksInitQeueue = []; + + //add extensions + if (type(extensions) == TYPES.s) + extensions = [extensions]; + if (COMPATIBILITY.isA(extensions)) + each(extensions, function (index, value) { _base.addExt(value); }); + else if (FRAMEWORK.isPlainObject(extensions)) + each(extensions, function (key, value) { _base.addExt(key, value); }); + + //add the transition class for transitions AFTER the first update & AFTER the applied extensions (for preventing unwanted transitions) + setTimeout(function () { + if (_supportTransition && !_destroyed) + addClass(_hostElement, _classNameHostTransition); + }, 333); + + return _base; + } + + if (_plugin.valid(construct(pluginTargetElement, options, extensions))) { + INSTANCES(pluginTargetElement, _base); + } + + return _base; + } + + /** + * Initializes a new OverlayScrollbarsInstance object or changes options if already initialized or returns the current instance. + * @param pluginTargetElements The elements to which the Plugin shall be initialized. + * @param options The custom options with which the plugin shall be initialized. + * @param extensions The extension(s) which shall be added right after initialization. + * @returns {*} + */ + _plugin = window[PLUGINNAME] = function (pluginTargetElements, options, extensions) { + if (arguments[LEXICON.l] === 0) + return this; + + var arr = []; + var optsIsPlainObj = FRAMEWORK.isPlainObject(options); + var inst; + var result; + + //pluginTargetElements is null or undefined + if (!pluginTargetElements) + return optsIsPlainObj || !options ? result : arr; + + /* + pluginTargetElements will be converted to: + 1. A jQueryElement Array + 2. A HTMLElement Array + 3. A Array with a single HTML Element + so pluginTargetElements is always a array. + */ + pluginTargetElements = pluginTargetElements[LEXICON.l] != undefined ? pluginTargetElements : [pluginTargetElements[0] || pluginTargetElements]; + initOverlayScrollbarsStatics(); + + if (pluginTargetElements[LEXICON.l] > 0) { + if (optsIsPlainObj) { + FRAMEWORK.each(pluginTargetElements, function (i, v) { + inst = v; + if (inst !== undefined) + arr.push(OverlayScrollbarsInstance(inst, options, extensions, _pluginsGlobals, _pluginsAutoUpdateLoop)); + }); + } + else { + FRAMEWORK.each(pluginTargetElements, function (i, v) { + inst = INSTANCES(v); + if ((options === '!' && _plugin.valid(inst)) || (COMPATIBILITY.type(options) == TYPES.f && options(v, inst))) + arr.push(inst); + else if (options === undefined) + arr.push(inst); + }); + } + result = arr[LEXICON.l] === 1 ? arr[0] : arr; + } + return result; + }; + + /** + * Returns a object which contains global information about the plugin and each instance of it. + * The returned object is just a copy, that means that changes to the returned object won't have any effect to the original object. + */ + _plugin.globals = function () { + initOverlayScrollbarsStatics(); + var globals = FRAMEWORK.extend(true, {}, _pluginsGlobals); + delete globals['msie']; + return globals; + }; + + /** + * Gets or Sets the default options for each new plugin initialization. + * @param newDefaultOptions The object with which the default options shall be extended. + */ + _plugin.defaultOptions = function (newDefaultOptions) { + initOverlayScrollbarsStatics(); + var currDefaultOptions = _pluginsGlobals.defaultOptions; + if (newDefaultOptions === undefined) + return FRAMEWORK.extend(true, {}, currDefaultOptions); + + //set the new default options + _pluginsGlobals.defaultOptions = FRAMEWORK.extend(true, {}, currDefaultOptions, _pluginsOptions._validate(newDefaultOptions, _pluginsOptions._template, true, currDefaultOptions)._default); + }; + + /** + * Checks whether the passed instance is a non-destroyed OverlayScrollbars instance. + * @param osInstance The potential OverlayScrollbars instance which shall be checked. + * @returns {boolean} True if the passed value is a non-destroyed OverlayScrollbars instance, false otherwise. + */ + _plugin.valid = function (osInstance) { + return osInstance instanceof _plugin && !osInstance.getState().destroyed; + }; + + /** + * Registers, Unregisters or returns a extension. + * Register: Pass the name and the extension. (defaultOptions is optional) + * Unregister: Pass the name and anything except a function as extension parameter. + * Get extension: Pass the name of the extension which shall be got. + * Get all extensions: Pass no arguments. + * @param extensionName The name of the extension which shall be registered, unregistered or returned. + * @param extension A function which generates the instance of the extension or anything other to remove a already registered extension. + * @param defaultOptions The default options which shall be used for the registered extension. + */ + _plugin.extension = function (extensionName, extension, defaultOptions) { + var extNameTypeString = COMPATIBILITY.type(extensionName) == TYPES.s; + var argLen = arguments[LEXICON.l]; + var i = 0; + if (argLen < 1 || !extNameTypeString) { + //return a copy of all extension objects + return FRAMEWORK.extend(true, { length: _pluginsExtensions[LEXICON.l] }, _pluginsExtensions); + } + else if (extNameTypeString) { + if (COMPATIBILITY.type(extension) == TYPES.f) { + //register extension + _pluginsExtensions.push({ + name: extensionName, + extensionFactory: extension, + defaultOptions: defaultOptions + }); + } + else { + for (; i < _pluginsExtensions[LEXICON.l]; i++) { + if (_pluginsExtensions[i].name === extensionName) { + if (argLen > 1) + _pluginsExtensions.splice(i, 1); //remove extension + else + return FRAMEWORK.extend(true, {}, _pluginsExtensions[i]); //return extension with the given name + } + } + } + } + }; + + return _plugin; + })(); + + if (JQUERY && JQUERY.fn) { + /** + * The jQuery initialization interface. + * @param options The initial options for the construction of the plugin. To initialize the plugin, this option has to be a object! If it isn't a object, the instance(s) are returned and the plugin wont be initialized. + * @param extensions The extension(s) which shall be added right after initialization. + * @returns {*} After initialization it returns the jQuery element array, else it returns the instance(s) of the elements which are selected. + */ + JQUERY.fn.overlayScrollbars = function (options, extensions) { + var _elements = this; + if (JQUERY.isPlainObject(options)) { + JQUERY.each(_elements, function () { PLUGIN(this, options, extensions); }); + return _elements; + } + else + return PLUGIN(_elements, options); + }; + } + return PLUGIN; + } +)); diff --git a/rector.php b/rector.php index 51b3aafb..18371564 100755 --- a/rector.php +++ b/rector.php @@ -15,11 +15,11 @@ $containerConfigurator->import(DoctrineSetList::ANNOTATIONS_TO_ATTRIBUTES); $containerConfigurator->import(SetList::CODE_QUALITY); $containerConfigurator->import(SetList::DEAD_CODE); - $containerConfigurator->import(LevelSetList::UP_TO_PHP_81); + $containerConfigurator->import(LevelSetList::UP_TO_PHP_84); $containerConfigurator->import(SetList::EARLY_RETURN); $containerConfigurator->import(Setlist::TYPE_DECLARATION); $containerConfigurator->import(SetList::TYPE_DECLARATION_STRICT); - $containerConfigurator->import(SymfonyLevelSetList::UP_TO_SYMFONY_54); + $containerConfigurator->import(SymfonyLevelSetList::SYMFONY_72); $services = $containerConfigurator->services(); // tidify lines after apply annotation to attribute that make remove lines diff --git a/symfony.lock b/symfony.lock index e61aabb5..f91b66f1 100644 --- a/symfony.lock +++ b/symfony.lock @@ -29,9 +29,6 @@ "composer/xdebug-handler": { "version": "1.4.1" }, - "cron/cron": { - "version": "1.4.2" - }, "cweagans/composer-patches": { "version": "1.7.1" }, @@ -175,9 +172,6 @@ "gedmo/doctrine-extensions": { "version": "v2.4.41" }, - "gesdinet/jwt-refresh-token-bundle": { - "version": "v0.12.0" - }, "helmich/typo3-typoscript-parser": { "version": "v2.3.1" }, @@ -792,9 +786,6 @@ "symfony/security-csrf": { "version": "v5.0.8" }, - "symfony/security-guard": { - "version": "v5.0.8" - }, "symfony/security-http": { "version": "v5.0.8" }, diff --git a/templates/apiclient/all.html.twig b/templates/apiclient/all.html.twig index c782d834..bdfdf14f 100644 --- a/templates/apiclient/all.html.twig +++ b/templates/apiclient/all.html.twig @@ -1,106 +1,105 @@ -{% extends 'layout/main.html.twig' %} +{%- extends 'layout/main.html.twig' -%} -{% block stylesheets %} - -{% endblock %} -{% block content %} - {% apply spaceless %} - {% set menu = convert_to_menu(context) %} +{%- block stylesheets -%} + +{%- endblock -%} +{%- block content -%} + {%- set menu = convert_to_menu(context) -%}
- - {% endapply %} -{% endblock %} -{% block javascripts %} - {% apply spaceless %} - +{%- endblock -%} +{%- block javascripts -%} + - {% endapply %} -{% endblock %} +{%- endblock -%} diff --git a/templates/apiclient/audit.html.twig b/templates/apiclient/audit.html.twig index e585d714..a00b9b57 100644 --- a/templates/apiclient/audit.html.twig +++ b/templates/apiclient/audit.html.twig @@ -1,65 +1,63 @@ -{% extends 'layout/main.html.twig' %} +{%- extends 'layout/main.html.twig' -%} -{% block stylesheets %} - -{% endblock %} -{% block content %} - {% apply spaceless %} +{%- block stylesheets -%} + +{%- endblock -%} +{%- block content -%}
-

{{ page_title | trans({}, 'pages') }}

+

{{- page_title | trans({}, 'pages') -}}

- {% for key, data in audits %} + {%- for key, data in audits -%}
    - {% for property in data | keys %} + {%- for property in data | keys -%}
  • - {{ ('sas.table.column.audit.' ~ property) | trans({}, 'tables') }} - {% if 'data' == property %} -
    - {% else %} - {{ data[property] }} - {% endif %} + {{- ('sas.table.column.audit.' ~ property) | trans({}, 'tables') -}} + {%- if 'data' == property -%} +
    + {%- else -%} + {{- data[property] -}} + {%- endif -%}
  • - {% endfor %} + {%- endfor -%}
- {% endfor %} + {%- endfor -%}
- {% endapply %} -{% endblock %} -{% block javascripts %} - +{%- endblock -%} +{%- block javascripts -%} + -{% endblock %} +{%- endblock -%} diff --git a/templates/apiclient/report.html.twig b/templates/apiclient/report.html.twig index 0f163ce2..0128cbe9 100644 --- a/templates/apiclient/report.html.twig +++ b/templates/apiclient/report.html.twig @@ -1,68 +1,66 @@ -{% extends 'layout/main.html.twig' %} +{%- extends 'layout/main.html.twig' -%} -{% block stylesheets %} - -{% endblock %} -{% block content %} - {% apply spaceless %} - {% set menu = convert_to_menu(context) %} +{%- block stylesheets -%} + +{%- endblock -%} +{%- block content -%} + {%- set menu = convert_to_menu(context) -%}
- {% for key, data in paginator['items'] %} + {%- for key, data in paginator['items'] -%}
- {% endfor %} + {%- endfor -%}
- {% endapply %} -{% endblock %} -{% block javascripts %} - +{%- endblock -%} +{%- block javascripts -%} + -{% endblock %} +{%- endblock -%} diff --git a/templates/base.html.twig b/templates/base.html.twig index d4f83f7f..465224f5 100644 --- a/templates/base.html.twig +++ b/templates/base.html.twig @@ -2,18 +2,18 @@ - {% block title %}Welcome!{% endblock %} + {%- block title -%} Welcome!{%- endblock -%} {# Run `composer require symfony/webpack-encore-bundle` to start using Symfony UX #} - {% block stylesheets %} - {{ encore_entry_link_tags('app') }} - {% endblock %} + {%- block stylesheets -%} + {{- encore_entry_link_tags('app') -}} + {%- endblock -%} - {% block javascripts %} - {{ encore_entry_script_tags('app') }} - {% endblock %} + {%- block javascripts -%} + {{- encore_entry_script_tags('app') -}} + {%- endblock -%} - {% block body %}{% endblock %} + {%- block body -%} {%- endblock -%} diff --git a/templates/bundles/NelmioApiDocBundle/SwaggerUi/index.html.twig b/templates/bundles/NelmioApiDocBundle/SwaggerUi/index.html.twig index 54f804a2..0f247e74 100644 --- a/templates/bundles/NelmioApiDocBundle/SwaggerUi/index.html.twig +++ b/templates/bundles/NelmioApiDocBundle/SwaggerUi/index.html.twig @@ -1,12 +1,12 @@ -{% extends '@!NelmioApiDoc/SwaggerUi/index.html.twig' %} +{%- extends '@!NelmioApiDoc/SwaggerUi/index.html.twig' -%} -{% block stylesheets %} - {{ parent() }} +{%- block stylesheets -%} + {{- parent() -}} -{% endblock stylesheets %} +{%- endblock stylesheets -%} -{% block header %} - -{% endblock header %} +{%- endblock header -%} diff --git a/templates/cron/all.html.twig b/templates/cron/all.html.twig index ee2b4b90..f7de821a 100644 --- a/templates/cron/all.html.twig +++ b/templates/cron/all.html.twig @@ -1,106 +1,105 @@ -{% extends 'layout/main.html.twig' %} +{%- extends 'layout/main.html.twig' -%} -{% block stylesheets %} - -{% endblock %} -{% block content %} - {% apply spaceless %} - {% set menu = convert_to_menu(context) %} +{%- block stylesheets -%} + +{%- endblock -%} +{%- block content -%} + {%- set menu = convert_to_menu(context) -%}
- - {% endapply %} -{% endblock %} -{% block javascripts %} - {% apply spaceless %} - +{%- endblock -%} +{%- block javascripts -%} + - {% endapply %} -{% endblock %} +{%- endblock -%} diff --git a/templates/cron/audit.html.twig b/templates/cron/audit.html.twig index 9f75a106..9fd0f743 100644 --- a/templates/cron/audit.html.twig +++ b/templates/cron/audit.html.twig @@ -1,70 +1,68 @@ -{% extends 'layout/main.html.twig' %} +{%- extends 'layout/main.html.twig' -%} -{% block stylesheets %} - -{% endblock %} -{% block content %} - {% apply spaceless %} +{%- block stylesheets -%} + +{%- endblock -%} +{%- block content -%}
-

{{ page_title | trans({}, 'pages') }}

+

{{- page_title | trans({}, 'pages') -}}

- {% for key, data in audits %} + {%- for key, data in audits -%}
    - {% for property in data | keys %} + {%- for property in data | keys -%}
  • - {{ ('sas.table.column.audit.' ~ property) | trans({}, 'tables') }} - {% if 'data' == property %} -
    - {% else %} - {{ data[property] }} - {% endif %} + {{- ('sas.table.column.audit.' ~ property) | trans({}, 'tables') -}} + {%- if 'data' == property -%} +
    + {%- else -%} + {{- data[property] -}} + {%- endif -%}
  • - {% endfor %} + {%- endfor -%}
- {% endfor %} + {%- endfor -%}
- {% endapply %} -{% endblock %} -{% block javascripts %} - +{%- endblock -%} +{%- block javascripts -%} + -{% endblock %} +{%- endblock -%} diff --git a/templates/cron/report.html.twig b/templates/cron/report.html.twig index e61470ba..47d010b4 100644 --- a/templates/cron/report.html.twig +++ b/templates/cron/report.html.twig @@ -1,77 +1,75 @@ -{% extends 'layout/main.html.twig' %} +{%- extends 'layout/main.html.twig' -%} -{% block stylesheets %} - - -{% endblock %} -{% block content %} - {% apply spaceless %} - {% set menu = convert_to_menu(context) %} +{%- block stylesheets -%} + + +{%- endblock -%} +{%- block content -%} + {%- set menu = convert_to_menu(context) -%}
- {% for key, data in paginator['items'] %} + {%- for key, data in paginator['items'] -%}
- {% endfor %} + {%- endfor -%}
- {% endapply %} -{% endblock %} -{% block javascripts %} - - +{%- endblock -%} +{%- block javascripts -%} + + -{% endblock %} +{%- endblock -%} diff --git a/templates/cron/view.html.twig b/templates/cron/view.html.twig index 5a43a86f..d5e1a9b0 100644 --- a/templates/cron/view.html.twig +++ b/templates/cron/view.html.twig @@ -1,80 +1,78 @@ -{% extends 'layout/main.html.twig' %} +{%- extends 'layout/main.html.twig' -%} -{% block stylesheets %} - - -{% endblock %} -{% block content %} - {% apply spaceless %} +{%- block stylesheets -%} + + +{%- endblock -%} +{%- block content -%}
-
+
-

{{ page_title | trans({}, 'pages') }}

+

{{- page_title | trans({}, 'pages') -}}

- {% if is_auditable(data) %} + {%- if is_auditable(data) -%}
-

{{ 'sas.page.audit.last_changes' | trans({}, 'pages') }}

+

{{- 'sas.page.audit.last_changes' | trans({}, 'pages') -}}

- {% for key, data in audits %} + {%- for key, data in audits -%}
    - {% for property in data | keys %} + {%- for property in data | keys -%}
  • - {{ ('sas.table.column.audit.' ~ property) | trans({}, 'tables') }} - {% if 'data' == property %} -
    - {% else %} - {{ data[property] }} - {% endif %} + {{- ('sas.table.column.audit.' ~ property) | trans({}, 'tables') -}} + {%- if 'data' == property -%} +
    + {%- else -%} + {{- data[property] -}} + {%- endif -%}
  • - {% endfor %} + {%- endfor -%}
- {% endfor %} + {%- endfor -%}
- {% endif %} + {%- endif -%}
- {% endapply %} -{% endblock %} -{% block javascripts %} - - +{%- endblock -%} +{%- block javascripts -%} + + -{% endblock %} +{%- endblock -%} diff --git a/templates/dashboard/layout.html.twig b/templates/dashboard/layout.html.twig index 6cfe035c..1e3204b9 100644 --- a/templates/dashboard/layout.html.twig +++ b/templates/dashboard/layout.html.twig @@ -1,5 +1,5 @@ -{% extends 'layout/main.html.twig' %} +{%- extends 'layout/main.html.twig' -%} -{% block stylesheets %}{% endblock %} -{% block content %}{% endblock %} -{% block javascripts %}{% endblock %} +{%- block stylesheets -%} {%- endblock -%} +{%- block content -%} {%- endblock -%} +{%- block javascripts -%} {%- endblock -%} diff --git a/templates/generator/admin/audit.php.twig b/templates/generator/admin/audit.php.twig index 39d7c0a4..ea85d2e4 100644 --- a/templates/generator/admin/audit.php.twig +++ b/templates/generator/admin/audit.php.twig @@ -1,17 +1,17 @@ -{% set entityHumanize = entity | humanize %} -{% set entityLowerize = entity | lower %} -{% set entityUpper = entity | upper %} -{% set entityPluralDash = entity | pluralize | dash %} +{%- set entityHumanize = entity | humanize -%} +{%- set entityLowerize = entity | lower -%} +{%- set entityUpper = entity | upper -%} +{%- set entityPluralDash = entity | pluralize | dash -%} requestStack->getCurrentRequest(), $this->service, $this->cache); } - #[Route(path: '/{{ entityPluralDash }}/{id}/audit', name: self::class, methods: ['GET'], priority: -255)] + #[Route(path: '/{{- entityPluralDash -}}/{id}/audit', name: self::class, methods: ['GET'], priority: -255)] public function __invoke(string $id): Response { if (!$entity = $this->service->get($id)) { - $this->addFlash('error', 'sas.page.{{ entityLowerize }}.not_found'); + $this->addFlash('error', 'sas.page.{{- entityLowerize -}}.not_found'); return new RedirectResponse($this->generateUrl(Main::class)); } - if (!$this->reader->getProvider()->isAuditable({{ entityHumanize }}::class)) { + if (!$this->reader->getProvider()->isAuditable({{- entityHumanize -}}::class)) { $this->addFlash('error', 'sas.page.audit.not_found'); return new RedirectResponse($this->generateUrl(Main::class)); } - return $this->renderAudit($this->audit->getAudits($entity, $id), new ReflectionClass({{ entityHumanize }}::class)); + return $this->renderAudit($this->audit->getAudits($entity, $id), new ReflectionClass({{- entityHumanize -}}::class)); } } diff --git a/templates/generator/admin/delete.php.twig b/templates/generator/admin/delete.php.twig index 79108fa3..c60719ba 100644 --- a/templates/generator/admin/delete.php.twig +++ b/templates/generator/admin/delete.php.twig @@ -1,15 +1,15 @@ -{% set entityHumanize = entity | humanize %} -{% set entityLowerize = entity | lower %} -{% set entityUpper = entity | upper %} -{% set entityPluralDash = entity | pluralize | dash %} +{%- set entityHumanize = entity | humanize -%} +{%- set entityLowerize = entity | lower -%} +{%- set entityUpper = entity | upper -%} +{%- set entityPluralDash = entity | pluralize | dash -%} */ -#[Permission(menu: '{{ entityUpper }}', actions: [Permission::DELETE])] +#[Permission(menu: '{{- entityUpper -}}', actions: [Permission::DELETE])] final class Delete extends AbstractController { - public function __construct(private {{ entityHumanize }}Service $service) + public function __construct(private {{- entityHumanize -}}Service $service) { } - #[Route(path: '/{{ entityPluralDash }}/{id}/delete', name: self::class, methods: ['GET'])] + #[Route(path: '/{{- entityPluralDash -}}/{id}/delete', name: self::class, methods: ['GET'])] public function __invoke(string $id): Response { - ${{ entityLowerize }} = $this->service->get($id); - if (!${{ entityLowerize }} instanceof {{ entityHumanize }}Interface) { - $this->addFlash('error', 'sas.page.{{ entityLowerize }}.not_found'); + ${{- entityLowerize -}} = $this->service->get($id); + if (!${{- entityLowerize -}} instanceof {{- entityHumanize -}}Interface) { + $this->addFlash('error', 'sas.page.{{- entityLowerize -}}.not_found'); return new RedirectResponse($this->generateUrl(Main::class)); } - $this->service->remove(${{ entityLowerize }}); + $this->service->remove(${{- entityLowerize -}}); - $this->addFlash('info', 'sas.page.{{ entityLowerize }}.deleted'); + $this->addFlash('info', 'sas.page.{{- entityLowerize -}}.deleted'); return new RedirectResponse($this->generateUrl(Main::class)); } diff --git a/templates/generator/admin/download.php.twig b/templates/generator/admin/download.php.twig index adfcad64..4809ec10 100644 --- a/templates/generator/admin/download.php.twig +++ b/templates/generator/admin/download.php.twig @@ -1,14 +1,14 @@ -{% set entityHumanize = entity | humanize %} -{% set entityLowerize = entity | lower %} -{% set entityUpper = entity | upper %} -{% set entityPluralDash = entity | pluralize | dash %} +{%- set entityHumanize = entity | humanize -%} +{%- set entityLowerize = entity | lower -%} +{%- set entityUpper = entity | upper -%} +{%- set entityPluralDash = entity | pluralize | dash -%} */ -#[Permission(menu: '{{ entityUpper }}', actions: [Permission::VIEW])] +#[Permission(menu: '{{- entityUpper -}}', actions: [Permission::VIEW])] final class Download extends AbstractController { - public function __construct(private {{ entityHumanize }}Service $service, private SerializerInterface $serializer) + public function __construct(private {{- entityHumanize -}}Service $service, private SerializerInterface $serializer) { } - #[Route(path: '/{{ entityPluralDash }}/download', name: self::class, methods: ['GET'])] + #[Route(path: '/{{- entityPluralDash -}}/download', name: self::class, methods: ['GET'])] public function __invoke(): Response { $records = $this->service->total(); @@ -39,7 +39,7 @@ final class Download extends AbstractController $response = new Response(); $response->headers->set('Cache-Control', 'private'); $response->headers->set('Content-type', 'text/csv'); - $response->headers->set('Content-Disposition', sprintf('attachment; filename="%s_%s.csv"', '{{ entityPluralDash }}', date('YmdHis'))); + $response->headers->set('Content-Disposition', sprintf('attachment; filename="%s_%s.csv"', '{{- entityPluralDash -}}', date('YmdHis'))); $response->setContent($this->serializer->serialize($this->service->all(), 'csv', ['groups' => 'read'])); diff --git a/templates/generator/admin/get.php.twig b/templates/generator/admin/get.php.twig index 0ba0c037..4bfabe04 100644 --- a/templates/generator/admin/get.php.twig +++ b/templates/generator/admin/get.php.twig @@ -1,19 +1,19 @@ -{% set entityHumanize = entity | humanize %} -{% set entityLowerize = entity | lower %} -{% set entityUpper = entity | upper %} -{% set entityPluralDash = entity | pluralize | dash %} +{%- set entityHumanize = entity | humanize -%} +{%- set entityLowerize = entity | lower -%} +{%- set entityUpper = entity | upper -%} +{%- set entityPluralDash = entity | pluralize | dash -%} */ -#[Permission(menu: '{{ entityUpper }}', actions: [Permission::VIEW])] +#[Permission(menu: '{{- entityUpper -}}', actions: [Permission::VIEW])] final class Get extends AbstractController { public function __construct( private readonly RequestStack $requestStack, - private {{ entityHumanize }}Service $service, + private {{- entityHumanize -}}Service $service, private readonly CacheItemPoolInterface $cache, private AuditService $audit, private Reader $reader, @@ -39,21 +39,21 @@ final class Get extends AbstractController parent::__construct($this->requestStack->getCurrentRequest(), $this->service, $this->cache); } - #[Route(path: '/{{ entityPluralDash }}/{id}', name: self::class, methods: ['GET'])] + #[Route(path: '/{{- entityPluralDash -}}/{id}', name: self::class, methods: ['GET'])] public function __invoke(string $id): Response { - ${{ entityLowerize }} = $this->service->get($id); - if (!${{ entityLowerize }} instanceof {{ entityHumanize }}Interface) { - $this->addFlash('error', 'sas.page.{{ entityLowerize }}.not_found'); + ${{- entityLowerize -}} = $this->service->get($id); + if (!${{- entityLowerize -}} instanceof {{- entityHumanize -}}Interface) { + $this->addFlash('error', 'sas.page.{{- entityLowerize -}}.not_found'); return new RedirectResponse($this->generateUrl(Main::class)); } - $audit = new Record(${{ entityLowerize }}); - if ($this->reader->getProvider()->isAuditable({{ entityHumanize }}::class)) { - $audit = $this->audit->getAudits(${{ entityLowerize }}, $id, 1); + $audit = new Record(${{- entityLowerize -}}); + if ($this->reader->getProvider()->isAuditable({{- entityHumanize -}}::class)) { + $audit = $this->audit->getAudits(${{- entityLowerize -}}, $id, 1); } - return $this->renderDetail($audit, new ReflectionClass({{ entityHumanize }}::class)); + return $this->renderDetail($audit, new ReflectionClass({{- entityHumanize -}}::class)); } } diff --git a/templates/generator/admin/main.php.twig b/templates/generator/admin/main.php.twig index 302c50ab..9a459531 100644 --- a/templates/generator/admin/main.php.twig +++ b/templates/generator/admin/main.php.twig @@ -1,17 +1,17 @@ -{% set entityHumanize = entity | humanize %} -{% set entityLowerize = entity | lower %} -{% set entityUpper = entity | upper %} -{% set entityPluralDash = entity | pluralize | dash %} +{%- set entityHumanize = entity | humanize -%} +{%- set entityLowerize = entity | lower -%} +{%- set entityUpper = entity | upper -%} +{%- set entityPluralDash = entity | pluralize | dash -%} */ -#[Permission(menu: '{{ entityUpper }}', actions: [Permission::VIEW])] +#[Permission(menu: '{{- entityUpper -}}', actions: [Permission::VIEW])] final class Main extends AbstractController { public function __construct( private readonly RequestStack $requestStack, - private readonly {{ entityHumanize }}Service $service, + private readonly {{- entityHumanize -}}Service $service, private readonly CacheItemPoolInterface $cache, private readonly Paginator $paginator, ) { parent::__construct($this->requestStack->getCurrentRequest(), $this->service, $this->cache, $this->paginator); } - #[Route(path: '/{{ entityPluralDash }}', name: self::class, methods: ['GET', 'POST'])] + #[Route(path: '/{{- entityPluralDash -}}', name: self::class, methods: ['GET', 'POST'])] public function __invoke(Request $request): Response { - ${{ entityLowerize }} = new {{ entityHumanize }}(); + ${{- entityLowerize -}} = new {{- entityHumanize -}}(); if ($request->isMethod(Request::METHOD_POST)) { $id = $request->getSession()->get('id'); if (null !== $id) { - ${{ entityLowerize }} = $this->service->get($id); + ${{- entityLowerize -}} = $this->service->get($id); } } else { $flashes = $request->getSession()->getFlashBag()->get('id'); foreach ($flashes as $flash) { - ${{ entityLowerize }} = $this->service->get($flash); - if (null !== ${{ entityLowerize }}) { - $request->getSession()->set('id', ${{ entityLowerize }}->getId()); + ${{- entityLowerize -}} = $this->service->get($flash); + if (null !== ${{- entityLowerize -}}) { + $request->getSession()->set('id', ${{- entityLowerize -}}->getId()); break; } } } - $form = $this->createForm({{ entityHumanize }}Type::class, ${{ entityLowerize }}); + $form = $this->createForm({{- entityHumanize -}}Type::class, ${{- entityLowerize -}}); if ($request->isMethod(Request::METHOD_POST)) { $form->handleRequest($request); if ($form->isValid()) { $this->service->save($form->getData()); - $this->addFlash('info', 'sas.page.{{ entityLowerize }}.saved'); + $this->addFlash('info', 'sas.page.{{- entityLowerize -}}.saved'); - $form = $this->createForm({{ entityHumanize }}Type::class); + $form = $this->createForm({{- entityHumanize -}}Type::class); } } - return $this->renderList($form, $request, new ReflectionClass({{ entityHumanize }}::class)); + return $this->renderList($form, $request, new ReflectionClass({{- entityHumanize -}}::class)); } } diff --git a/templates/generator/admin/put.php.twig b/templates/generator/admin/put.php.twig index 90c8344b..93182c57 100644 --- a/templates/generator/admin/put.php.twig +++ b/templates/generator/admin/put.php.twig @@ -1,15 +1,15 @@ -{% set entityHumanize = entity | humanize %} -{% set entityLowerize = entity | lower %} -{% set entityUpper = entity | upper %} -{% set entityPluralDash = entity | pluralize | dash %} +{%- set entityHumanize = entity | humanize -%} +{%- set entityLowerize = entity | lower -%} +{%- set entityUpper = entity | upper -%} +{%- set entityPluralDash = entity | pluralize | dash -%} */ -#[Permission(menu: '{{ entityUpper }}', actions: [Permission::EDIT])] +#[Permission(menu: '{{- entityUpper -}}', actions: [Permission::EDIT])] final class Put extends AbstractController { - public function __construct(private {{ entityHumanize }}Service $service) + public function __construct(private {{- entityHumanize -}}Service $service) { } - #[Route(path: '/{{ entityPluralDash }}/{id}/edit', name: self::class, methods: ['GET'], priority: 1)] + #[Route(path: '/{{- entityPluralDash -}}/{id}/edit', name: self::class, methods: ['GET'], priority: 1)] public function __invoke(Request $request, string $id): Response { - ${{ entityLowerize }} = $this->service->get($id); - if (!${{ entityLowerize }} instanceof {{ entityHumanize }}Interface) { - $this->addFlash('error', 'sas.page.{{ entityLowerize }}.not_found'); + ${{- entityLowerize -}} = $this->service->get($id); + if (!${{- entityLowerize -}} instanceof {{- entityHumanize -}}Interface) { + $this->addFlash('error', 'sas.page.{{- entityLowerize -}}.not_found'); return new RedirectResponse($this->generateUrl(Main::class, $request->query->all())); } - $this->addFlash('id', ${{ entityLowerize }}->getId()); + $this->addFlash('id', ${{- entityLowerize -}}->getId()); return new RedirectResponse($this->generateUrl(Main::class, $request->query->all())); } diff --git a/templates/generator/admin/view/all.html.stub b/templates/generator/admin/view/all.html.stub index e376da27..0994cc67 100644 --- a/templates/generator/admin/view/all.html.stub +++ b/templates/generator/admin/view/all.html.stub @@ -1,93 +1,92 @@ -{% extends 'layout/main.html.twig' %} +{%- extends 'layout/main.html.twig' -%} -{% block stylesheets %} - -{% endblock %} -{% block content %} - {% apply spaceless %} - {% set menu = convert_to_menu(context) %} +{%- block stylesheets -%} + +{%- endblock -%} +{%- block content -%} + {%- set menu = convert_to_menu(context) -%}
- - {% endapply %} -{% endblock %} -{% block javascripts %} - {% apply spaceless %} - +{%- endblock -%} +{%- block javascripts -%} + - {% endapply %} -{% endblock %} +{%- endblock -%} diff --git a/templates/generator/admin/view/audit.html.stub b/templates/generator/admin/view/audit.html.stub index d3390e18..856c1cd5 100644 --- a/templates/generator/admin/view/audit.html.stub +++ b/templates/generator/admin/view/audit.html.stub @@ -1,60 +1,58 @@ -{% extends 'layout/main.html.twig' %} +{%- extends 'layout/main.html.twig' -%} -{% block stylesheets %} - -{% endblock %} -{% block content %} - {% apply spaceless %} +{%- block stylesheets -%} + +{%- endblock -%} +{%- block content -%}
-

{{ page_title | trans({}, 'pages') }}

+

{{- page_title | trans({}, 'pages') -}}

    - {% for property in properties %} - {% if 'id' != property.name %} + {%- for property in properties -%} + {%- if 'id' != property.name -%}
  • - {{ ('sas.table.column.' ~ context ~ '.' ~ property.name) | trans({}, 'tables') }} - {{ attribute(data, property.name) }} + {{- ('sas.table.column.' ~ context ~ '.' ~ property.name) | trans({}, 'tables') -}} + {{- attribute(data, property.name) -}}
  • - {% endif %} - {% endfor %} + {%- endif -%} + {%- endfor -%}
- {% for key, data in audits %} + {%- for key, data in audits -%}
    - {% for property in data | keys %} + {%- for property in data | keys -%}
  • - {{ ('sas.table.column.audit.' ~ property) | trans({}, 'tables') }} - {% if 'data' == property %} -
    - {% else %} - {{ data[property] }} - {% endif %} + {{- ('sas.table.column.audit.' ~ property) | trans({}, 'tables') -}} + {%- if 'data' == property -%} +
    + {%- else -%} + {{- data[property] -}} + {%- endif -%}
  • - {% endfor %} + {%- endfor -%}
- {% endfor %} + {%- endfor -%}
- {% endapply %} -{% endblock %} -{% block javascripts %} - +{%- endblock -%} +{%- block javascripts -%} + -{% endblock %} +{%- endblock -%} diff --git a/templates/generator/admin/view/select2-all.html.stub b/templates/generator/admin/view/select2-all.html.stub index 7652614e..70383999 100644 --- a/templates/generator/admin/view/select2-all.html.stub +++ b/templates/generator/admin/view/select2-all.html.stub @@ -1,95 +1,94 @@ -{% extends 'layout/main.html.twig' %} +{%- extends 'layout/main.html.twig' -%} -{% block stylesheets %} - - - -{% endblock %} -{% block content %} - {% apply spaceless %} - {% set menu = convert_to_menu(context) %} +{%- block stylesheets -%} + + + +{%- endblock -%} +{%- block content -%} + {%- set menu = convert_to_menu(context) -%}
- - {% endapply %} -{% endblock %} -{% block javascripts %} - {% apply spaceless %} - - +{%- endblock -%} +{%- block javascripts -%} + + - {% endapply %} -{% endblock %} +{%- endblock -%} diff --git a/templates/generator/admin/view/view.html.stub b/templates/generator/admin/view/view.html.stub index 98632973..7355dc51 100644 --- a/templates/generator/admin/view/view.html.stub +++ b/templates/generator/admin/view/view.html.stub @@ -1,66 +1,64 @@ -{% extends 'layout/main.html.twig' %} +{%- extends 'layout/main.html.twig' -%} -{% block stylesheets %} - -{% endblock %} -{% block content %} - {% apply spaceless %} +{%- block stylesheets -%} + +{%- endblock -%} +{%- block content -%}
-
+
-

{{ page_title | trans({}, 'pages') }}

+

{{- page_title | trans({}, 'pages') -}}

    - {% for property in properties %} - {% if 'id' != property.name %} + {%- for property in properties -%} + {%- if 'id' != property.name -%}
  • - {{ ('sas.table.column.' ~ context ~ '.' ~ property.name) | trans({}, 'tables') }} - {{ attribute(data, property.name) }} + {{- ('sas.table.column.' ~ context ~ '.' ~ property.name) | trans({}, 'tables') -}} + {{- attribute(data, property.name) -}}
  • - {% endif %} - {% endfor %} + {%- endif -%} + {%- endfor -%}
- {% if is_auditable(data) and can_view_audit() %} + {%- if is_auditable(data) and can_view_audit() -%}
-

{{ 'sas.page.audit.last_changes' | trans({}, 'pages') }}

+

{{- 'sas.page.audit.last_changes' | trans({}, 'pages') -}}

- {% for key, data in audits %} + {%- for key, data in audits -%}
    - {% for property in data | keys %} + {%- for property in data | keys -%}
  • - {{ ('sas.table.column.audit.' ~ property) | trans({}, 'tables') }} - {% if 'data' == property %} -
    - {% else %} - {{ data[property] }} - {% endif %} + {{- ('sas.table.column.audit.' ~ property) | trans({}, 'tables') -}} + {%- if 'data' == property -%} +
    + {%- else -%} + {{- data[property] -}} + {%- endif -%}
  • - {% endfor %} + {%- endfor -%}
- {% endfor %} + {%- endfor -%}
- {% endif %} + {%- endif -%}
- {% endapply %} -{% endblock %} -{% block javascripts %} - +{%- endblock -%} +{%- block javascripts -%} + -{% endblock %} +{%- endblock -%} diff --git a/templates/generator/api/audit.php.twig b/templates/generator/api/audit.php.twig index 6e270ab9..389fbad7 100644 --- a/templates/generator/api/audit.php.twig +++ b/templates/generator/api/audit.php.twig @@ -1,22 +1,22 @@ -{% set entityHumanize = entity | humanize %} -{% set entityUpper = entity | upper %} -{% set entityPluralDash = entity | pluralize | dash %} +{%- set entityHumanize = entity | humanize -%} +{%- set entityUpper = entity | upper -%} +{%- set entityPluralDash = entity | pluralize | dash -%} */ #[Permission(menu: 'AUDIT', actions: [Permission::VIEW])] -#[Tag(name: '{{ entityHumanize }}')] +#[Tag(name: '{{- entityHumanize -}}')] final class Audit extends AbstractFOSRestController { - public function __construct(private {{ entityHumanize }}Service $service, private AuditService $audit, private Reader $reader) + public function __construct(private {{- entityHumanize -}}Service $service, private AuditService $audit, private Reader $reader) { } - #[Get(data: '/{{ entityPluralDash }}/{id}/audit', name: self::class, priority: -255)] + #[Get(data: '/{{- entityPluralDash -}}/{id}/audit', name: self::class, priority: -255)] #[Security(name: 'Bearer')] #[Response( response: 200, @@ -46,7 +46,7 @@ final class Audit extends AbstractFOSRestController properties: [ new OA\Property( property: 'entity', - ref: new Model(type: {{ entityHumanize }}::class, groups: ['read']), + ref: new Model(type: {{- entityHumanize -}}::class, groups: ['read']), type: 'object', ), new OA\Property(property: 'type', type: 'string'), @@ -74,7 +74,7 @@ final class Audit extends AbstractFOSRestController throw new NotFoundHttpException(); } - if (!$this->reader->getProvider()->isAuditable({{ entityHumanize }}::class)) { + if (!$this->reader->getProvider()->isAuditable({{- entityHumanize -}}::class)) { return $this->view([]); } diff --git a/templates/generator/api/delete.php.twig b/templates/generator/api/delete.php.twig index 1a971c03..a11d83a6 100644 --- a/templates/generator/api/delete.php.twig +++ b/templates/generator/api/delete.php.twig @@ -1,20 +1,20 @@ -{% set entityHumanize = entity | humanize %} -{% set entityLowerize = entity | lower %} -{% set entityUpper = entity | upper %} -{% set entityPluralDash = entity | pluralize | dash %} +{%- set entityHumanize = entity | humanize -%} +{%- set entityLowerize = entity | lower -%} +{%- set entityUpper = entity | upper -%} +{%- set entityPluralDash = entity | pluralize | dash -%} */ -#[Permission(menu: '{{ entityUpper }}', actions: [Permission::DELETE])] -#[Tag(name: '{{ entityHumanize }}')] +#[Permission(menu: '{{- entityUpper -}}', actions: [Permission::DELETE])] +#[Tag(name: '{{- entityHumanize -}}')] final class Delete extends AbstractFOSRestController { - public function __construct(private {{ entityHumanize }}Service $service, private TranslatorInterface $translator) + public function __construct(private {{- entityHumanize -}}Service $service, private TranslatorInterface $translator) { } - #[Route(data: '/{{ entityPluralDash }}/{id}', name: self::class)] + #[Route(data: '/{{- entityPluralDash -}}/{id}', name: self::class)] #[Security(name: 'Bearer')] - #[\OpenApi\Attributes\Response(response: 204, description: 'Delete {{ entityLowerize }}')] + #[\OpenApi\Attributes\Response(response: 204, description: 'Delete {{- entityLowerize -}}')] public function __invoke(string $id): View { - ${{ entityLowerize }} = $this->service->get($id); - if (!${{ entityLowerize }} instanceof {{ entityHumanize }}Interface) { - throw new NotFoundHttpException($this->translator->trans('sas.page.{{ entityLowerize }}.not_found', [], 'pages')); + ${{- entityLowerize -}} = $this->service->get($id); + if (!${{- entityLowerize -}} instanceof {{- entityHumanize -}}Interface) { + throw new NotFoundHttpException($this->translator->trans('sas.page.{{- entityLowerize -}}.not_found', [], 'pages')); } - $this->service->remove(${{ entityLowerize }}); + $this->service->remove(${{- entityLowerize -}}); return $this->view(null, Response::HTTP_NO_CONTENT); } diff --git a/templates/generator/api/get.php.twig b/templates/generator/api/get.php.twig index 64e72650..a4772015 100644 --- a/templates/generator/api/get.php.twig +++ b/templates/generator/api/get.php.twig @@ -1,22 +1,22 @@ -{% set entityHumanize = entity | humanize %} -{% set entityLowerize = entity | lower %} -{% set entityUpper = entity | upper %} -{% set entityPluralDash = entity | pluralize | dash %} +{%- set entityHumanize = entity | humanize -%} +{%- set entityLowerize = entity | lower -%} +{%- set entityUpper = entity | upper -%} +{%- set entityPluralDash = entity | pluralize | dash -%} */ -#[Permission(menu: '{{ entityUpper }}', actions: [Permission::VIEW])] -#[Tag(name: '{{ entityHumanize }}')] +#[Permission(menu: '{{- entityUpper -}}', actions: [Permission::VIEW])] +#[Tag(name: '{{- entityHumanize -}}')] final class Get extends AbstractFOSRestController { - public function __construct(private {{ entityHumanize }}Service $service, private TranslatorInterface $translator) + public function __construct(private {{- entityHumanize -}}Service $service, private TranslatorInterface $translator) { } - #[Route(data: '/{{ entityPluralDash }}/{id}', name: self::class)] + #[Route(data: '/{{- entityPluralDash -}}/{id}', name: self::class)] #[Security(name: 'Bearer')] #[Response( response: 200, - description: '{{ entityHumanize }} detail', + description: '{{- entityHumanize -}} detail', content: new OA\MediaType( mediaType: 'application/json', - schema: new OA\Schema(ref: new Model(type: {{ entityHumanize }}::class, groups: ['read']), type: 'object'), + schema: new OA\Schema(ref: new Model(type: {{- entityHumanize -}}::class, groups: ['read']), type: 'object'), ), )] public function __invoke(string $id): View { - ${{ entityLowerize }} = $this->service->get($id); - if (!${{ entityLowerize }} instanceof {{ entityHumanize }}Interface) { - throw new NotFoundHttpException($this->translator->trans('sas.page.{{ entityLowerize }}.not_found', [], 'pages')); + ${{- entityLowerize -}} = $this->service->get($id); + if (!${{- entityLowerize -}} instanceof {{- entityHumanize -}}Interface) { + throw new NotFoundHttpException($this->translator->trans('sas.page.{{- entityLowerize -}}.not_found', [], 'pages')); } - return $this->view(${{ entityLowerize }}); + return $this->view(${{- entityLowerize -}}); } } diff --git a/templates/generator/api/get_all.php.twig b/templates/generator/api/get_all.php.twig index 2ebcbc42..b4c9a33e 100644 --- a/templates/generator/api/get_all.php.twig +++ b/templates/generator/api/get_all.php.twig @@ -1,22 +1,22 @@ -{% set entityHumanize = entity | humanize %} -{% set entityLowerize = entity | lower %} -{% set entityUpper = entity | upper %} -{% set entityPluralDash = entity | pluralize | dash %} +{%- set entityHumanize = entity | humanize -%} +{%- set entityLowerize = entity | lower -%} +{%- set entityUpper = entity | upper -%} +{%- set entityPluralDash = entity | pluralize | dash -%} */ -#[Permission(menu: '{{ entityUpper }}', actions: [Permission::VIEW])] -#[Tag(name: '{{ entityHumanize }}')] +#[Permission(menu: '{{- entityUpper -}}', actions: [Permission::VIEW])] +#[Tag(name: '{{- entityHumanize -}}')] final class GetAll extends AbstractFOSRestController { - public function __construct(private {{ entityHumanize }}Service $service, private Paginator $paginator) + public function __construct(private {{- entityHumanize -}}Service $service, private Paginator $paginator) { } - #[Get(data: '/{{ entityPluralDash }}', name: self::class)] + #[Get(data: '/{{- entityPluralDash -}}', name: self::class)] #[Security(name: 'Bearer')] #[Parameter(name: 'page', in: 'query', schema: new OA\Schema(type: 'integer', format: 'int32'))] #[Parameter(name: 'limit', in: 'query', schema: new OA\Schema(type: 'integer', format: 'int32'))] #[Response( response: 200, - description: '{{ entityHumanize }} list', + description: '{{- entityHumanize -}} list', content: new OA\MediaType( mediaType: 'application/json', schema: new OA\Schema( type: 'array', - items: new OA\Items(ref: new Model(type: {{ entityHumanize }}::class, groups: ['read'])), + items: new OA\Items(ref: new Model(type: {{- entityHumanize -}}::class, groups: ['read'])), ), ), )] public function __invoke(Request $request): View { - return $this->view($this->paginator->paginate($this->service->getQueryBuilder(), $request, {{ entityHumanize }}::class)); + return $this->view($this->paginator->paginate($this->service->getQueryBuilder(), $request, {{- entityHumanize -}}::class)); } } diff --git a/templates/generator/api/post.php.twig b/templates/generator/api/post.php.twig index 8accbac9..b53d0132 100644 --- a/templates/generator/api/post.php.twig +++ b/templates/generator/api/post.php.twig @@ -1,24 +1,24 @@ -{% set entityHumanize = entity | humanize %} -{% set entityLowerize = entity | lower %} -{% set entityUpper = entity | upper %} -{% set entityPluralDash = entity | pluralize | dash %} +{%- set entityHumanize = entity | humanize -%} +{%- set entityLowerize = entity | lower -%} +{%- set entityUpper = entity | upper -%} +{%- set entityPluralDash = entity | pluralize | dash -%} */ -#[Permission(menu: '{{ entityUpper }}', actions: [Permission::ADD])] -#[Tag(name: '{{ entityHumanize }}')] +#[Permission(menu: '{{- entityUpper -}}', actions: [Permission::ADD])] +#[Tag(name: '{{- entityHumanize -}}')] final class Post extends AbstractFOSRestController { - public function __construct(private FormFactory $formFactory, private {{ entityHumanize }}Service $service) + public function __construct(private FormFactory $formFactory, private {{- entityHumanize -}}Service $service) { } - #[Route(data: '/{{ entityPluralDash }}', name: self::class)] + #[Route(data: '/{{- entityPluralDash -}}', name: self::class)] #[Security(name: 'Bearer')] #[RequestBody( content: new OA\MediaType( mediaType: 'application/json', - schema: new OA\Schema(ref: new Model(type: {{ entityHumanize }}Type::class), type: 'object'), + schema: new OA\Schema(ref: new Model(type: {{- entityHumanize -}}Type::class), type: 'object'), ), )] #[OA\Response( response: 201, - description: '{{ entityHumanize }} created', + description: '{{- entityHumanize -}} created', content: new OA\MediaType( mediaType: 'application/json', - schema: new OA\Schema(ref: new Model(type: {{ entityHumanize }}::class, groups: ['read']), type: 'object'), + schema: new OA\Schema(ref: new Model(type: {{- entityHumanize -}}::class, groups: ['read']), type: 'object'), ), )] public function __invoke(Request $request): View { - $form = $this->formFactory->submitRequest({{ entityHumanize }}Type::class, $request); + $form = $this->formFactory->submitRequest({{- entityHumanize -}}Type::class, $request); if (!$form->isValid()) { return $this->view((array) $form->getErrors(), Response::HTTP_BAD_REQUEST); } - /** @var {{ entityHumanize }}Interface ${{ entityLowerize }} */ - ${{ entityLowerize }} = $form->getData(); - $this->service->save(${{ entityLowerize }}); + /** @var {{- entityHumanize -}}Interface ${{- entityLowerize -}} */ + ${{- entityLowerize -}} = $form->getData(); + $this->service->save(${{- entityLowerize -}}); - return $this->view($this->service->get(${{ entityLowerize }}->getId()), Response::HTTP_CREATED); + return $this->view($this->service->get(${{- entityLowerize -}}->getId()), Response::HTTP_CREATED); } } diff --git a/templates/generator/api/put.php.twig b/templates/generator/api/put.php.twig index 96a92d1a..ea91747c 100644 --- a/templates/generator/api/put.php.twig +++ b/templates/generator/api/put.php.twig @@ -1,24 +1,24 @@ -{% set entityHumanize = entity | humanize %} -{% set entityLowerize = entity | lower %} -{% set entityUpper = entity | upper %} -{% set entityPluralDash = entity | pluralize | dash %} +{%- set entityHumanize = entity | humanize -%} +{%- set entityLowerize = entity | lower -%} +{%- set entityUpper = entity | upper -%} +{%- set entityPluralDash = entity | pluralize | dash -%} */ -#[Permission(menu: '{{ entityUpper }}', actions: [Permission::EDIT])] -#[Tag(name: '{{ entityHumanize }}')] +#[Permission(menu: '{{- entityUpper -}}', actions: [Permission::EDIT])] +#[Tag(name: '{{- entityHumanize -}}')] final class Put extends AbstractFOSRestController { public function __construct( private FormFactory $formFactory, - private {{ entityHumanize }}Service $service, + private {{- entityHumanize -}}Service $service, private TranslatorInterface $translator, ) { } - #[Route(data: '/{{ entityPluralDash }}/{id}', name: self::class)] + #[Route(data: '/{{- entityPluralDash -}}/{id}', name: self::class)] #[Security(name: 'Bearer')] #[RequestBody( content: new OA\MediaType( mediaType: 'application/json', - schema: new OA\Schema(ref: new Model(type: {{ entityHumanize }}Type::class), type: 'object'), + schema: new OA\Schema(ref: new Model(type: {{- entityHumanize -}}Type::class), type: 'object'), ), )] #[OA\Response( response: 200, - description: '{{ entityHumanize }} updated', + description: '{{- entityHumanize -}} updated', content: new OA\MediaType( mediaType: 'application/json', - schema: new OA\Schema(ref: new Model(type: {{ entityHumanize }}::class, groups: ['read']), type: 'object'), + schema: new OA\Schema(ref: new Model(type: {{- entityHumanize -}}::class, groups: ['read']), type: 'object'), ), )] public function __invoke(Request $request, string $id): View { - ${{ entityLowerize }} = $this->service->get($id); - if (!${{ entityLowerize }} instanceof {{ entityHumanize }}Interface) { - throw new NotFoundHttpException($this->translator->trans('sas.page.{{ entityLowerize }}.not_found', [], 'pages')); + ${{- entityLowerize -}} = $this->service->get($id); + if (!${{- entityLowerize -}} instanceof {{- entityHumanize -}}Interface) { + throw new NotFoundHttpException($this->translator->trans('sas.page.{{- entityLowerize -}}.not_found', [], 'pages')); } - $form = $this->formFactory->submitRequest({{ entityHumanize }}Type::class, $request, ${{ entityLowerize }}); + $form = $this->formFactory->submitRequest({{- entityHumanize -}}Type::class, $request, ${{- entityLowerize -}}); if (!$form->isValid()) { return $this->view((array) $form->getErrors(), Response::HTTP_BAD_REQUEST); } - $this->service->save(${{ entityLowerize }}); + $this->service->save(${{- entityLowerize -}}); - return $this->view($this->service->get(${{ entityLowerize }}->getId())); + return $this->view($this->service->get(${{- entityLowerize -}}->getId())); } } diff --git a/templates/generator/form.php.twig b/templates/generator/form.php.twig index 837998fa..11c96af8 100644 --- a/templates/generator/form.php.twig +++ b/templates/generator/form.php.twig @@ -1,11 +1,11 @@ -{% set entityHumanize = entity.shortName | humanize %} +{%- set entityHumanize = entity.shortName | humanize -%} */ -final class {{ entityHumanize }}Type extends AbstractType +final class {{- entityHumanize -}}Type extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options) { -{% for i, property in properties %} -{% if 'id' != property.name %} -{% if semart_association(entity, property) %} - $builder->add('{{ property.name }}', null, [ +{%- for i, property in properties -%} +{%- if 'id' != property.name -%} +{%- if semart_association(entity, property) -%} + $builder->add('{{- property.name -}}', null, [ 'required' => false, - 'label' => 'sas.form.field.{{ entity.shortName | lower }}.{{ property.name }}', - 'choice_label' => function (${{ property.name }}) { - if (${{ property.name }} instanceof EntityInterface) { - return ${{ property.name }}->getNullOrString(); + 'label' => 'sas.form.field.{{- entity.shortName | lower -}}.{{- property.name -}}', + 'choice_label' => function (${{- property.name -}}) { + if (${{- property.name -}} instanceof EntityInterface) { + return ${{- property.name -}}->getNullOrString(); } - return (string) ${{ property.name }}; + return (string) ${{- property.name -}}; }, 'attr' => [ 'class' => 'select2', ], 'placeholder' => 'sas.form.field.empty_select', ]); -{% else %} - $builder->add('{{ property.name }}', null, [ +{%- else -%} + $builder->add('{{- property.name -}}', null, [ 'required' => true, - 'label' => 'sas.form.field.{{ entity.shortName | lower }}.{{ property.name }}', + 'label' => 'sas.form.field.{{- entity.shortName | lower -}}.{{- property.name -}}', ]); -{% endif %} -{% endif %} -{% endfor %} +{%- endif -%} +{%- endif -%} +{%- endfor -%} } public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults([ - 'data_class' => {{ entityHumanize }}::class, + 'data_class' => {{- entityHumanize -}}::class, 'translation_domain' => 'forms', ]); } diff --git a/templates/generator/repository.php.twig b/templates/generator/repository.php.twig index 5d69a5bd..3ff0efd9 100644 --- a/templates/generator/repository.php.twig +++ b/templates/generator/repository.php.twig @@ -1,4 +1,4 @@ -{% set entityHumanize = entity | humanize %} +{%- set entityHumanize = entity | humanize -%} */ -final class {{ entityHumanize }}Repository extends AbstractRepository implements {{ entityHumanize }}RepositoryInterface +final class {{- entityHumanize -}}Repository extends AbstractRepository implements {{- entityHumanize -}}RepositoryInterface { public function __construct(RequestStack $requestStack, ManagerRegistry $registry) { - parent::__construct($requestStack, $registry, {{ entityHumanize }}::class); + parent::__construct($requestStack, $registry, {{- entityHumanize -}}::class); } } diff --git a/templates/generator/repository_model.php.twig b/templates/generator/repository_model.php.twig index afcdc7eb..d40f9619 100644 --- a/templates/generator/repository_model.php.twig +++ b/templates/generator/repository_model.php.twig @@ -1,15 +1,15 @@ -{% set entityHumanize = entity | humanize %} +{%- set entityHumanize = entity | humanize -%} */ -interface {{ entityHumanize }}RepositoryInterface extends PaginatableRepositoryInterface +interface {{- entityHumanize -}}RepositoryInterface extends PaginatableRepositoryInterface { } diff --git a/templates/generator/search_query.php.twig b/templates/generator/search_query.php.twig index 6ea136de..76c8d2eb 100644 --- a/templates/generator/search_query.php.twig +++ b/templates/generator/search_query.php.twig @@ -1,12 +1,12 @@ -{% set entityHumanize = entity | humanize %} +{%- set entityHumanize = entity | humanize -%} */ -final class {{ entityHumanize }}QueryExtension extends AbstractQueryExtension +final class {{- entityHumanize -}}QueryExtension extends AbstractQueryExtension { public function apply(QueryBuilder $queryBuilder, Request $request): void { @@ -32,6 +32,6 @@ final class {{ entityHumanize }}QueryExtension extends AbstractQueryExtension public function support(string $class, Request $request): bool { - return in_array({{ entityHumanize }}Interface::class, class_implements($class)); + return in_array({{- entityHumanize -}}Interface::class, class_implements($class)); } } diff --git a/templates/generator/service.php.twig b/templates/generator/service.php.twig index 90836ddb..49ed897e 100644 --- a/templates/generator/service.php.twig +++ b/templates/generator/service.php.twig @@ -1,11 +1,11 @@ -{% set entityHumanize = entity | humanize %} +{%- set entityHumanize = entity | humanize -%} */ -final class {{ entityHumanize }}Service extends AbstractService implements ServiceInterface +final class {{- entityHumanize -}}Service extends AbstractService implements ServiceInterface { - public function __construct(MessageBusInterface $messageBus, {{ entityHumanize }}RepositoryInterface $repository, AliasHelper $aliasHelper) + public function __construct(MessageBusInterface $messageBus, {{- entityHumanize -}}RepositoryInterface $repository, AliasHelper $aliasHelper) { parent::__construct($messageBus, $repository, $aliasHelper); } diff --git a/templates/group/all.html.twig b/templates/group/all.html.twig index 85bb61a7..1fc46e79 100644 --- a/templates/group/all.html.twig +++ b/templates/group/all.html.twig @@ -1,96 +1,95 @@ -{% extends 'layout/main.html.twig' %} +{%- extends 'layout/main.html.twig' -%} -{% block stylesheets %} - -{% endblock %} -{% block content %} - {% apply spaceless %} - {% set menu = convert_to_menu(context) %} +{%- block stylesheets -%} + +{%- endblock -%} +{%- block content -%} + {%- set menu = convert_to_menu(context) -%}
- - {% endapply %} -{% endblock %} -{% block javascripts %} - {% apply spaceless %} - +{%- endblock -%} +{%- block javascripts -%} + - {% endapply %} -{% endblock %} +{%- endblock -%} diff --git a/templates/group/audit.html.twig b/templates/group/audit.html.twig index 95976e9c..9598999f 100644 --- a/templates/group/audit.html.twig +++ b/templates/group/audit.html.twig @@ -1,60 +1,58 @@ -{% extends 'layout/main.html.twig' %} +{%- extends 'layout/main.html.twig' -%} -{% block stylesheets %} - -{% endblock %} -{% block content %} - {% apply spaceless %} +{%- block stylesheets -%} + +{%- endblock -%} +{%- block content -%}
-

{{ page_title | trans({}, 'pages') }}

+

{{- page_title | trans({}, 'pages') -}}

    - {% for property in properties %} - {% if 'id' != property.name %} + {%- for property in properties -%} + {%- if 'id' != property.name -%}
  • - {{ ('sas.table.column.' ~ context ~ '.' ~ property.name) | trans({}, 'tables') }} - {{ attribute(data, property.name) }} + {{- ('sas.table.column.' ~ context ~ '.' ~ property.name) | trans({}, 'tables') -}} + {{- attribute(data, property.name) -}}
  • - {% endif %} - {% endfor %} + {%- endif -%} + {%- endfor -%}
- {% for key, data in audits %} + {%- for key, data in audits -%}
    - {% for property in data | keys %} + {%- for property in data | keys -%}
  • - {{ ('sas.table.column.audit.' ~ property) | trans({}, 'tables') }} - {% if 'data' == property %} -
    - {% else %} - {{ data[property] }} - {% endif %} + {{- ('sas.table.column.audit.' ~ property) | trans({}, 'tables') -}} + {%- if 'data' == property -%} +
    + {%- else -%} + {{- data[property] -}} + {%- endif -%}
  • - {% endfor %} + {%- endfor -%}
- {% endfor %} + {%- endfor -%}
- {% endapply %} -{% endblock %} -{% block javascripts %} - +{%- endblock -%} +{%- block javascripts -%} + -{% endblock %} +{%- endblock -%} diff --git a/templates/group/permission.html.twig b/templates/group/permission.html.twig index 2b757808..1f6f5ede 100644 --- a/templates/group/permission.html.twig +++ b/templates/group/permission.html.twig @@ -1,155 +1,152 @@ -{% extends 'layout/main.html.twig' %} - -{% block stylesheets %} - - -{% endblock %} -{% block content %} - {% apply spaceless %} - {% set menu = convert_to_menu(context) %} +{%- extends 'layout/main.html.twig' -%} + +{%- block stylesheets -%} + + +{%- endblock -%} +{%- block content -%} + {%- set menu = convert_to_menu(context) -%}
- +
- +
- {% for key, data in paginator['items'] %} - {% if 0 == key % 2 %} + {%- for key, data in paginator['items'] -%} + {%- if 0 == key % 2 -%}
- {% else %} + {%- else -%}
- {% endif %} - {% endfor %} + {%- endif -%} + {%- endfor -%}
- {% endapply %} -{% endblock %} -{% block javascripts %} - {% apply spaceless %} - - +{%- endblock -%} +{%- block javascripts -%} + + - {% endapply %} -{% endblock %} +{%- endblock -%} diff --git a/templates/group/view.html.twig b/templates/group/view.html.twig index acc303be..6dd3da7f 100644 --- a/templates/group/view.html.twig +++ b/templates/group/view.html.twig @@ -1,67 +1,65 @@ -{% extends 'layout/main.html.twig' %} +{%- extends 'layout/main.html.twig' -%} -{% block stylesheets %} - -{% endblock %} -{% block content %} - {% apply spaceless %} +{%- block stylesheets -%} + +{%- endblock -%} +{%- block content -%}
-
+
-

{{ page_title | trans({}, 'pages') }}

+

{{- page_title | trans({}, 'pages') -}}

    - {% for property in properties %} - {% if 'id' != property.name %} + {%- for property in properties -%} + {%- if 'id' != property.name -%}
  • - {{ ('sas.table.column.' ~ context ~ '.' ~ property.name) | trans({}, 'tables') }} - {{ attribute(data, property.name) }} + {{- ('sas.table.column.' ~ context ~ '.' ~ property.name) | trans({}, 'tables') -}} + {{- attribute(data, property.name) -}}
  • - {% endif %} - {% endfor %} + {%- endif -%} + {%- endfor -%}
- {% if is_auditable(data) and can_view_audit() %} + {%- if is_auditable(data) and can_view_audit() -%}
-

{{ 'sas.page.audit.last_changes' | trans({}, 'pages') }}

+

{{- 'sas.page.audit.last_changes' | trans({}, 'pages') -}}

- {% for key, data in audits %} + {%- for key, data in audits -%}
    - {% for property in data | keys %} + {%- for property in data | keys -%}
  • - {{ ('sas.table.column.audit.' ~ property) | trans({}, 'tables') }} - {% if 'data' == property %} -
    - {% else %} - {{ data[property] }} - {% endif %} + {{- ('sas.table.column.audit.' ~ property) | trans({}, 'tables') -}} + {%- if 'data' == property -%} +
    + {%- else -%} + {{- data[property] -}} + {%- endif -%}
  • - {% endfor %} + {%- endfor -%}
- {% endfor %} + {%- endfor -%}
- {% endif %} + {%- endif -%}
- {% endapply %} -{% endblock %} -{% block javascripts %} - +{%- endblock -%} +{%- block javascripts -%} + -{% endblock %} +{%- endblock -%} diff --git a/templates/layout/child_menu.html.twig b/templates/layout/child_menu.html.twig index 20aa149a..e13a5832 100644 --- a/templates/layout/child_menu.html.twig +++ b/templates/layout/child_menu.html.twig @@ -1,7 +1,5 @@ -{% apply spaceless %} -{% endapply %} diff --git a/templates/layout/content.html.twig b/templates/layout/content.html.twig index 53ae44f6..d773caaa 100644 --- a/templates/layout/content.html.twig +++ b/templates/layout/content.html.twig @@ -1,21 +1,19 @@ -{% apply spaceless %} -
+
-
{{ content | raw }}
+
{{- content | raw -}}
-{% endapply %} diff --git a/templates/layout/footer.html.twig b/templates/layout/footer.html.twig index 85ead533..17ebe203 100644 --- a/templates/layout/footer.html.twig +++ b/templates/layout/footer.html.twig @@ -1,9 +1,7 @@ -{% apply spaceless %} -