diff --git a/CHANGELOG.md b/CHANGELOG.md index 46ef98170fcb6507eb1f02a51cc4ffc64e794575..a4adce8aacaf6d3e59a1bfd7e9b92904ae178d39 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,19 @@ +## [3.56.0] - 2024-25-26 + +### New Features + +- New ChangeButton Control [#147](https://gitlab.schukai.com/oss/libraries/javascript/monster/issues/147) +- New SaveButton Control [#148](https://gitlab.schukai.com/oss/libraries/javascript/monster/issues/148) +- Overlay has a new flag features.openButton [#149](https://gitlab.schukai.com/oss/libraries/javascript/monster/issues/149) +- New `ATTRIBUTE_UPDATER_BIND_TYPE` for the updater [#150](https://gitlab.schukai.com/oss/libraries/javascript/monster/issues/150) + +### Changes + +- Update of the node libraries to the latest version [#145](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/145) +- Update bob and version [#145](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/145) +- New api mock plugin for api tests in the playground [#146](https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/146) + ## [3.55.6] - 2024-01-26 ### Bug Fixes diff --git a/devenv.lock b/devenv.lock index 7c8e4e4d16db2b855dab4f3c7ada9175173a4437..850941bac23e3cd2bef04a60cbd981d304c0e380 100644 --- a/devenv.lock +++ b/devenv.lock @@ -2,14 +2,20 @@ "nodes": { "bob": { "inputs": { - "nixpkgs": "nixpkgs" + "devenv": "devenv", + "flake-parts": "flake-parts", + "flake-root": "flake-root", + "mk-shell-bin": "mk-shell-bin", + "nixpkgs": "nixpkgs_2", + "treefmt-nix": "treefmt-nix", + "versions-tool": "versions-tool" }, "locked": { - "lastModified": 1699307555, - "narHash": "sha256-Bwe/tUZRLsk0QXxIQvLqJddwvvBWwSRggcghEkGvnv8=", + "lastModified": 1706563779, + "narHash": "sha256-F6hgtCgEzy6Rx6sDLti72ZbFvOucnMLQ+yVb7GsqYQ4=", "ref": "refs/heads/master", - "rev": "d634e8f70af0e53735fee249cb5ed96880de4458", - "revCount": 84, + "rev": "7069c6702e8ccafd33f734f6e14f102dfd1b15ae", + "revCount": 114, "type": "git", "url": "https://gitlab.schukai.com/oss/bob.git" }, @@ -19,8 +25,13 @@ } }, "devenv": { + "inputs": { + "flake-compat": "flake-compat", + "nix": "nix", + "nixpkgs": "nixpkgs", + "pre-commit-hooks": "pre-commit-hooks" + }, "locked": { - "dir": "src/modules", "lastModified": 1706018268, "narHash": "sha256-d24+re0t8b6HYGzAPZCIJed85n23RUFXQa2yuHoW0uQ=", "owner": "cachix", @@ -28,6 +39,22 @@ "rev": "ad0ae333b210e31237e1fc4a7ddab71a01785add", "type": "github" }, + "original": { + "owner": "cachix", + "repo": "devenv", + "type": "github" + } + }, + "devenv_2": { + "locked": { + "dir": "src/modules", + "lastModified": 1708538593, + "narHash": "sha256-2q3tdg3TirbrTEPaVFTfxMG0TJdE77GsC6s5aHJhWkQ=", + "owner": "cachix", + "repo": "devenv", + "rev": "f5d594f79022f4468fae9d04418cb607890a9347", + "type": "github" + }, "original": { "dir": "src/modules", "owner": "cachix", @@ -36,6 +63,22 @@ } }, "flake-compat": { + "flake": false, + "locked": { + "lastModified": 1673956053, + "narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, + "flake-compat_2": { "flake": false, "locked": { "lastModified": 1696426674, @@ -51,10 +94,60 @@ "type": "github" } }, + "flake-parts": { + "inputs": { + "nixpkgs-lib": "nixpkgs-lib" + }, + "locked": { + "lastModified": 1706551415, + "narHash": "sha256-15s36w8kG2XIdhGBdQVuPiY+gQxWrvcGA9AszmvHBGQ=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "bffc4be17f13c1e43aac906a62e1a6e5ae369c6b", + "type": "github" + }, + "original": { + "id": "flake-parts", + "type": "indirect" + } + }, + "flake-root": { + "locked": { + "lastModified": 1692742795, + "narHash": "sha256-f+Y0YhVCIJ06LemO+3Xx00lIcqQxSKJHXT/yk1RTKxw=", + "owner": "srid", + "repo": "flake-root", + "rev": "d9a70d9c7a5fd7f3258ccf48da9335e9b47c3937", + "type": "github" + }, + "original": { + "owner": "srid", + "repo": "flake-root", + "type": "github" + } + }, "flake-utils": { "inputs": { "systems": "systems" }, + "locked": { + "lastModified": 1685518550, + "narHash": "sha256-o2d0KcvaXzTrPRIo0kOLV0/QXHhDQ5DTi+OxcjO8xqY=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "a1720a10a6cfe8234c0e93907ffe81be440f4cef", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_2": { + "inputs": { + "systems": "systems_2" + }, "locked": { "lastModified": 1701680307, "narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=", @@ -70,6 +163,29 @@ } }, "gitignore": { + "inputs": { + "nixpkgs": [ + "bob", + "devenv", + "pre-commit-hooks", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1660459072, + "narHash": "sha256-8DFJjXG8zqoONA1vXtgeKXy68KdJL5UaXR8NtVMUbx8=", + "owner": "hercules-ci", + "repo": "gitignore.nix", + "rev": "a20de23b925fd8264fd7fad6454652e142fd7f73", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "gitignore.nix", + "type": "github" + } + }, + "gitignore_2": { "inputs": { "nixpkgs": [ "pre-commit-hooks", @@ -90,22 +206,129 @@ "type": "github" } }, + "lowdown-src": { + "flake": false, + "locked": { + "lastModified": 1633514407, + "narHash": "sha256-Dw32tiMjdK9t3ETl5fzGrutQTzh2rufgZV4A/BbxuD4=", + "owner": "kristapsdz", + "repo": "lowdown", + "rev": "d2c2b44ff6c27b936ec27358a2653caaef8f73b8", + "type": "github" + }, + "original": { + "owner": "kristapsdz", + "repo": "lowdown", + "type": "github" + } + }, + "mk-shell-bin": { + "locked": { + "lastModified": 1677004959, + "narHash": "sha256-/uEkr1UkJrh11vD02aqufCxtbF5YnhRTIKlx5kyvf+I=", + "owner": "rrbutani", + "repo": "nix-mk-shell-bin", + "rev": "ff5d8bd4d68a347be5042e2f16caee391cd75887", + "type": "github" + }, + "original": { + "owner": "rrbutani", + "repo": "nix-mk-shell-bin", + "type": "github" + } + }, + "nix": { + "inputs": { + "lowdown-src": "lowdown-src", + "nixpkgs": [ + "bob", + "devenv", + "nixpkgs" + ], + "nixpkgs-regression": "nixpkgs-regression" + }, + "locked": { + "lastModified": 1676545802, + "narHash": "sha256-EK4rZ+Hd5hsvXnzSzk2ikhStJnD63odF7SzsQ8CuSPU=", + "owner": "domenkozar", + "repo": "nix", + "rev": "7c91803598ffbcfe4a55c44ac6d49b2cf07a527f", + "type": "github" + }, + "original": { + "owner": "domenkozar", + "ref": "relaxed-flakes", + "repo": "nix", + "type": "github" + } + }, "nixpkgs": { "locked": { - "lastModified": 1704290814, - "narHash": "sha256-LWvKHp7kGxk/GEtlrGYV68qIvPHkU9iToomNFGagixU=", + "lastModified": 1678875422, + "narHash": "sha256-T3o6NcQPwXjxJMn2shz86Chch4ljXgZn746c2caGxd8=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "70bdadeb94ffc8806c0570eb5c2695ad29f0e421", + "rev": "126f49a01de5b7e35a43fd43f891ecf6d3a51459", "type": "github" }, "original": { - "id": "nixpkgs", - "ref": "nixos-23.05", - "type": "indirect" + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-lib": { + "locked": { + "dir": "lib", + "lastModified": 1703961334, + "narHash": "sha256-M1mV/Cq+pgjk0rt6VxoyyD+O8cOUiai8t9Q6Yyq4noY=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "b0d36bd0a420ecee3bc916c91886caca87c894e9", + "type": "github" + }, + "original": { + "dir": "lib", + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-regression": { + "locked": { + "lastModified": 1643052045, + "narHash": "sha256-uGJ0VXIhWKGXxkeNnq4TvV3CIOkUJ3PAoLZ3HMzNVMw=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2", + "type": "github" + }, + "original": { + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2", + "type": "github" } }, "nixpkgs-stable": { + "locked": { + "lastModified": 1685801374, + "narHash": "sha256-otaSUoFEMM+LjBI1XL/xGB5ao6IwnZOXc47qhIgJe8U=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "c37ca420157f4abc31e26f436c1145f8951ff373", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-23.05", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-stable_2": { "locked": { "lastModified": 1704874635, "narHash": "sha256-YWuCrtsty5vVZvu+7BchAxmcYzTMfolSPP5io8+WYCg=", @@ -123,11 +346,58 @@ }, "nixpkgs_2": { "locked": { - "lastModified": 1705916986, - "narHash": "sha256-iBpfltu6QvN4xMpen6jGGEb6jOqmmVQKUrXdOJ32u8w=", + "lastModified": 1706373441, + "narHash": "sha256-S1hbgNbVYhuY2L05OANWqmRzj4cElcbLuIkXTb69xkk=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "56911ef3403a9318b7621ce745f5452fb9ef6867", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-23.11", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_3": { + "locked": { + "lastModified": 1705856552, + "narHash": "sha256-JXfnuEf5Yd6bhMs/uvM67/joxYKoysyE3M2k6T3eWbg=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "612f97239e2cc474c13c9dafa0df378058c5ad8d", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_4": { + "locked": { + "lastModified": 1704145853, + "narHash": "sha256-G/1AMt9ibpeMlcxvD1vNaC8imGaK+g7zZ99e29BLgWw=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "2d2ea8eab9e400618748ab1a6a108255233b602c", + "type": "github" + }, + "original": { + "id": "nixpkgs", + "ref": "nixos-23.11", + "type": "indirect" + } + }, + "nixpkgs_5": { + "locked": { + "lastModified": 1708440434, + "narHash": "sha256-XY+B9mbhL/i+Q6fP6gBQ6P76rv9rWtpjQiUJ+DGtaUg=", "owner": "nixos", "repo": "nixpkgs", - "rev": "d7f206b723e42edb09d9d753020a84b3061a79d8", + "rev": "526d051b128b82ae045a70e5ff1adf8e6dafa560", "type": "github" }, "original": { @@ -137,13 +407,13 @@ "type": "github" } }, - "nixpkgs_3": { + "nixpkgs_6": { "locked": { - "lastModified": 1705916986, - "narHash": "sha256-iBpfltu6QvN4xMpen6jGGEb6jOqmmVQKUrXdOJ32u8w=", + "lastModified": 1708440434, + "narHash": "sha256-XY+B9mbhL/i+Q6fP6gBQ6P76rv9rWtpjQiUJ+DGtaUg=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "d7f206b723e42edb09d9d753020a84b3061a79d8", + "rev": "526d051b128b82ae045a70e5ff1adf8e6dafa560", "type": "github" }, "original": { @@ -154,20 +424,50 @@ }, "pre-commit-hooks": { "inputs": { - "flake-compat": "flake-compat", + "flake-compat": [ + "bob", + "devenv", + "flake-compat" + ], "flake-utils": "flake-utils", "gitignore": "gitignore", "nixpkgs": [ + "bob", + "devenv", "nixpkgs" ], "nixpkgs-stable": "nixpkgs-stable" }, "locked": { - "lastModified": 1705757126, - "narHash": "sha256-Eksr+n4Q8EYZKAN0Scef5JK4H6FcHc+TKNHb95CWm+c=", + "lastModified": 1704725188, + "narHash": "sha256-qq8NbkhRZF1vVYQFt1s8Mbgo8knj+83+QlL5LBnYGpI=", "owner": "cachix", "repo": "pre-commit-hooks.nix", - "rev": "f56597d53fd174f796b5a7d3ee0b494f9e2285cc", + "rev": "ea96f0c05924341c551a797aaba8126334c505d2", + "type": "github" + }, + "original": { + "owner": "cachix", + "repo": "pre-commit-hooks.nix", + "type": "github" + } + }, + "pre-commit-hooks_2": { + "inputs": { + "flake-compat": "flake-compat_2", + "flake-utils": "flake-utils_2", + "gitignore": "gitignore_2", + "nixpkgs": [ + "nixpkgs" + ], + "nixpkgs-stable": "nixpkgs-stable_2" + }, + "locked": { + "lastModified": 1708018599, + "narHash": "sha256-M+Ng6+SePmA8g06CmUZWi1AjG2tFBX9WCXElBHEKnyM=", + "owner": "cachix", + "repo": "pre-commit-hooks.nix", + "rev": "5df5a70ad7575f6601d91f0efec95dd9bc619431", "type": "github" }, "original": { @@ -179,9 +479,9 @@ "root": { "inputs": { "bob": "bob", - "devenv": "devenv", - "nixpkgs": "nixpkgs_2", - "pre-commit-hooks": "pre-commit-hooks", + "devenv": "devenv_2", + "nixpkgs": "nixpkgs_5", + "pre-commit-hooks": "pre-commit-hooks_2", "version": "version" } }, @@ -200,10 +500,61 @@ "type": "github" } }, - "version": { + "systems_2": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "treefmt-nix": { "inputs": { "nixpkgs": "nixpkgs_3" }, + "locked": { + "lastModified": 1706462057, + "narHash": "sha256-7dG1D4iqqt0bEbBqUWk6lZiSqqwwAO0Hd1L5opVyhNM=", + "owner": "numtide", + "repo": "treefmt-nix", + "rev": "c6153c2a3ff4c38d231e3ae99af29b87f1df5901", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "treefmt-nix", + "type": "github" + } + }, + "version": { + "inputs": { + "nixpkgs": "nixpkgs_6" + }, + "locked": { + "lastModified": 1704542622, + "narHash": "sha256-HnFuaOXHoxv8tpBvMsEjfhcl/hFNxEY7GbBqoyJ1U8U=", + "ref": "refs/heads/master", + "rev": "6b4f85fe6d934429cf3055bbcd8cf15014730118", + "revCount": 114, + "type": "git", + "url": "https://gitlab.schukai.com/oss/utilities/version.git" + }, + "original": { + "type": "git", + "url": "https://gitlab.schukai.com/oss/utilities/version.git" + } + }, + "versions-tool": { + "inputs": { + "nixpkgs": "nixpkgs_4" + }, "locked": { "lastModified": 1704542622, "narHash": "sha256-HnFuaOXHoxv8tpBvMsEjfhcl/hFNxEY7GbBqoyJ1U8U=", diff --git a/devenv.nix b/devenv.nix index d23836d420831e7507c52a2070b0c46b522cc545..15d35e6b8d665de2ca3ce14af2d951987bdcc82d 100644 --- a/devenv.nix +++ b/devenv.nix @@ -1,22 +1,24 @@ -{ pkgs ? null, inputs ? null, phps ? null, lib ? null, config ? null -, modulesPath ? null, ... }: - -let - currentSystem = if pkgs.stdenv.system != null then - pkgs.stdenv.system - else - builtins.currentSystem; - +{ + pkgs ? null, + inputs ? null, + phps ? null, + lib ? null, + config ? null, + modulesPath ? null, + ... +}: let + currentSystem = + if pkgs.stdenv.system != null + then pkgs.stdenv.system + else builtins.currentSystem; in { - env.APP_NAME = "monster"; - env.dddd= "@schukai/monster"; + env.dddd = "@schukai/monster"; # https://devenv.sh/packages/ packages = with pkgs; [ - - (inputs.bob.defaultPackage."${currentSystem}") - (inputs.version.defaultPackage."${currentSystem}") + (inputs.version.packages."${builtins.currentSystem}".default) + (inputs.bob.packages."${builtins.currentSystem}".default) awscli2 appimage-run @@ -46,6 +48,7 @@ in { nodePackages.pnpm php82Extensions.xdebug plantuml-c4 + alejandra procps ranger unzip @@ -54,7 +57,7 @@ in { ]; languages = { - go = { enable = true; }; + go = {enable = true;}; javascript = { enable = true; package = pkgs.nodejs_20; @@ -62,286 +65,284 @@ in { }; }; + difftastic.enable = true; enterShell = '' -## check if node_modules exists -if [ ! -d node_modules ]; then - echo "node_modules does not exist. Installing dependencies." - ${pkgs.nodePackages.pnpm}/bin/pnpm install -fi + ## check if node_modules exists + if [ ! -d node_modules ]; then + echo "node_modules does not exist. Installing dependencies." + ${pkgs.nodePackages.pnpm}/bin/pnpm install + fi + + ${pkgs.nodejs_20}/bin/node ${config.devenv.root}/node_modules/jsdoc-plantuml/fixBrokenNodeJS.js + ''; -${pkgs.nodejs_20}/bin/node ${config.devenv.root}/node_modules/jsdoc-plantuml/fixBrokenNodeJS.js -''; - scripts.format-and-lint-code.exec = '' -${pkgs.nodejs_20}/bin/npx biome format --write ${config.devenv.root}/source/ -${pkgs.nodejs_20}/bin/npx biome lint --apply ${config.devenv.root}/source/ - -''; - + ${pkgs.nodejs_20}/bin/npx biome format --write ${config.devenv.root}/source/ + ${pkgs.nodejs_20}/bin/npx biome lint --apply ${config.devenv.root}/source/ + + ''; + scripts.build-changelog.exec = '' -${pkgs.git-chglog}/bin/git-chglog --config ${config.devenv.root}/.chglog/config.yml -o ${config.devenv.root}/CHANGELOG.md -''; + ${pkgs.git-chglog}/bin/git-chglog --config ${config.devenv.root}/.chglog/config.yml -o ${config.devenv.root}/CHANGELOG.md + ''; - scripts.build-and-publish.exec = '' -set -x -if [ -t 1 ]; then - RED='\033[0;31m' - GREEN='\033[0;32m' - RESET='\033[0m' - BOLD='\033[1m' -else - RED="" - GREEN="" - RESET="" -fi - - -if [[ -n "$(git status --porcelain)" ]]; then - echo -e "''${RED}✖ Git is not clean. Exiting.''${RESET}" - echo -e " You must commit all changes before you can publish a new version." - exit 1 -fi - - -NEXTVERSION="$(${inputs.version.defaultPackage."${builtins.currentSystem}"}/bin/version predict --git)" - -if [[ "$NEXTVERSION" =~ "No notable changes found." ]]; then - echo -e "''${RED}✖ No notable changes found. Exiting.''${RESET}" - echo -e " Check this repository for changes. You must add a new commit with" - echo -e " feat: or fix: in the commit message to trigger a new version." - exit 1 -fi - -echo -e "''${GREEN}✔''${RESET} New version: $NEXTVERSION" - -LASTVERSION=$(cat "${config.devenv.root}/package.json" | jq -r '.version') - -jq ".version = \"$NEXTVERSION\"" "${config.devenv.root}/package.json" | ${pkgs.moreutils}/bin/sponge "${config.devenv.root}/package.json" -update-versions - -PROJECT_ROOT="${config.devenv.root}/" -TEST_PATH="${config.devenv.root}/test/" -BUILD_PATH="${config.devenv.root}/dist/" - -if [ -d "$BUILD_PATH" ]; then - rm -rf "$BUILD_PATH" -fi - -mkdir -p "''${BUILD_PATH}" - -${pkgs.git-chglog}/bin/git-chglog --next-tag ''$NEXTVERSION --config "${config.devenv.root}/.chglog/config.yml" \ - -o "${config.devenv.root}/CHANGELOG.md" - -${pkgs.rsync}/bin/rsync -a --exclude-from="${config.devenv.root}/.gitignore" "${config.devenv.root}/source" "''${BUILD_PATH}" -${pkgs.rsync}/bin/rsync -a --exclude-from="${config.devenv.root}/.gitignore" "${config.devenv.root}/test" "''${BUILD_PATH}" -${pkgs.rsync}/bin/rsync -a --exclude-from="${config.devenv.root}/.gitignore" "${config.devenv.root}/example" "''${BUILD_PATH}" - -cp ${config.devenv.root}/README.md "''${BUILD_PATH}" -cp ${config.devenv.root}/LICENSE "''${BUILD_PATH}" -cp ${config.devenv.root}/CHANGELOG.md "''${BUILD_PATH}" - -jq 'del(.devDependencies)' ${config.devenv.root}/package.json > "''${BUILD_PATH}/package.json" - -git add ${config.devenv.root}/package.json -git add ${config.devenv.root}/source/types/version.mjs -git add ${config.devenv.root}/CHANGELOG.md -git add ${config.devenv.root}/test/cases/monster.mjs -if ! git commit -m "chore: release and publish to npm new version $NEXTVERSION" ; then - echo -e "''${RED}✖ Commit failed. Exiting.''${RESET}" - exit 1 -fi - -cd ''${BUILD_PATH} || exit 1 - -OPTIONS="" -if [ ! -f "${config.devenv.root}/.npmrc" ]; then - echo -e "''${RED}✖ No .npmrc file found.''${RESET}" - echo -e " If you want to publish to npm, you need to create a .npmrc file in the root of the project." - echo -e " //registry.npmjs.org/:_authToken=$NPM_TOKEN" - echo -e " You can find the token in the npm account settings." - echo -e "\n We run in dry-run mode now." - OPTIONS="--dry-run --no-git-checks" -fi - -pnpm publish $OPTIONS --access public -exitcode=$? -cd - || exit 1 - -if [ -n "$OPTIONS" ] || [ $exitcode -ne 0 ]; then - - ## reset to last version - jq ".version = \"$LASTVERSION\"" "${config.devenv.root}/package.json" | ${pkgs.moreutils}/bin/sponge "${config.devenv.root}/package.json" - update-versions - - echo -e "''${RED}✖ Publishing failed. Exiting.''${RESET}" - git reset --hard HEAD~1 - - exit 1 -fi - -git tag -a ''$NEXTVERSION -m "chore tag new version $NEXTVERSION" - -echo -e "''${GREEN}✔''${RESET} Publishing successful." - - - -''; + set -x + if [ -t 1 ]; then + RED='\033[0;31m' + GREEN='\033[0;32m' + RESET='\033[0m' + BOLD='\033[1m' + else + RED="" + GREEN="" + RESET="" + fi + + + if [[ -n "$(git status --porcelain)" ]]; then + echo -e "''${RED}✖ Git is not clean. Exiting.''${RESET}" + echo -e " You must commit all changes before you can publish a new version." + exit 1 + fi + + + NEXTVERSION="$(${inputs.version.defaultPackage."${builtins.currentSystem}"}/bin/version predict --git)" + + if [[ "$NEXTVERSION" =~ "No notable changes found." ]]; then + echo -e "''${RED}✖ No notable changes found. Exiting.''${RESET}" + echo -e " Check this repository for changes. You must add a new commit with" + echo -e " feat: or fix: in the commit message to trigger a new version." + exit 1 + fi + + echo -e "''${GREEN}✔''${RESET} New version: $NEXTVERSION" + + LASTVERSION=$(cat "${config.devenv.root}/package.json" | jq -r '.version') + + jq ".version = \"$NEXTVERSION\"" "${config.devenv.root}/package.json" | ${pkgs.moreutils}/bin/sponge "${config.devenv.root}/package.json" + update-versions + + PROJECT_ROOT="${config.devenv.root}/" + TEST_PATH="${config.devenv.root}/test/" + BUILD_PATH="${config.devenv.root}/dist/" + + if [ -d "$BUILD_PATH" ]; then + rm -rf "$BUILD_PATH" + fi + + mkdir -p "''${BUILD_PATH}" + + ${pkgs.git-chglog}/bin/git-chglog --next-tag ''$NEXTVERSION --config "${config.devenv.root}/.chglog/config.yml" \ + -o "${config.devenv.root}/CHANGELOG.md" + + ${pkgs.rsync}/bin/rsync -a --exclude-from="${config.devenv.root}/.gitignore" "${config.devenv.root}/source" "''${BUILD_PATH}" + ${pkgs.rsync}/bin/rsync -a --exclude-from="${config.devenv.root}/.gitignore" "${config.devenv.root}/test" "''${BUILD_PATH}" + ${pkgs.rsync}/bin/rsync -a --exclude-from="${config.devenv.root}/.gitignore" "${config.devenv.root}/example" "''${BUILD_PATH}" + + cp ${config.devenv.root}/README.md "''${BUILD_PATH}" + cp ${config.devenv.root}/LICENSE "''${BUILD_PATH}" + cp ${config.devenv.root}/CHANGELOG.md "''${BUILD_PATH}" + + jq 'del(.devDependencies)' ${config.devenv.root}/package.json > "''${BUILD_PATH}/package.json" + + git add ${config.devenv.root}/package.json + git add ${config.devenv.root}/source/types/version.mjs + git add ${config.devenv.root}/CHANGELOG.md + git add ${config.devenv.root}/test/cases/monster.mjs + if ! git commit -m "chore: release and publish to npm new version $NEXTVERSION" ; then + echo -e "''${RED}✖ Commit failed. Exiting.''${RESET}" + exit 1 + fi + + cd ''${BUILD_PATH} || exit 1 + + OPTIONS="" + if [ ! -f "${config.devenv.root}/.npmrc" ]; then + echo -e "''${RED}✖ No .npmrc file found.''${RESET}" + echo -e " If you want to publish to npm, you need to create a .npmrc file in the root of the project." + echo -e " //registry.npmjs.org/:_authToken=$NPM_TOKEN" + echo -e " You can find the token in the npm account settings." + echo -e "\n We run in dry-run mode now." + OPTIONS="--dry-run --no-git-checks" + fi + + pnpm publish $OPTIONS --access public + exitcode=$? + cd - || exit 1 + + if [ -n "$OPTIONS" ] || [ $exitcode -ne 0 ]; then + + ## reset to last version + jq ".version = \"$LASTVERSION\"" "${config.devenv.root}/package.json" | ${pkgs.moreutils}/bin/sponge "${config.devenv.root}/package.json" + update-versions + + echo -e "''${RED}✖ Publishing failed. Exiting.''${RESET}" + git reset --hard HEAD~1 + + exit 1 + fi + + git tag -a ''$NEXTVERSION -m "chore tag new version $NEXTVERSION" + + echo -e "''${GREEN}✔''${RESET} Publishing successful." + + + + ''; scripts.update-versions.exec = '' -VERSION=$(${pkgs.coreutils}/bin/cat "${config.devenv.root}/package.json" | jq -r '.version') + VERSION=$(${pkgs.coreutils}/bin/cat "${config.devenv.root}/package.json" | jq -r '.version') -${pkgs.jq}/bin/jq ".version = \"$VERSION\"" "${config.devenv.root}/package.json" | ${pkgs.moreutils}/bin/sponge "${config.devenv.root}/package.json" + ${pkgs.jq}/bin/jq ".version = \"$VERSION\"" "${config.devenv.root}/package.json" | ${pkgs.moreutils}/bin/sponge "${config.devenv.root}/package.json" -${pkgs.gnused}/bin/sed -i -E "s_(\"[0-9]+\.[0-9]+\.[0-9]+\")_\"''${VERSION}\"_g" "${config.devenv.root}/source/types/version.mjs" -${pkgs.gnused}/bin/sed -i -E "s_(\"[0-9]+\.[0-9]+\.[0-9]+\")_\"''${VERSION}\"_g" "${config.devenv.root}/test/cases/monster.mjs" - - -''; + ${pkgs.gnused}/bin/sed -i -E "s_(\"[0-9]+\.[0-9]+\.[0-9]+\")_\"''${VERSION}\"_g" "${config.devenv.root}/source/types/version.mjs" + ${pkgs.gnused}/bin/sed -i -E "s_(\"[0-9]+\.[0-9]+\.[0-9]+\")_\"''${VERSION}\"_g" "${config.devenv.root}/test/cases/monster.mjs" + + + ''; scripts.run-playground.exec = '' -if ! ${pkgs.nodePackages.pnpm}/bin/pnpx vite --config "${config.devenv.root}/playground/vite.config.js"; then - echo "ERROR: Vite build failed, check your JS!" - exit 1 -fi - - -''; + if ! ${pkgs.nodePackages.pnpm}/bin/pnpx vite --config "${config.devenv.root}/playground/vite.config.js"; then + echo "ERROR: Vite build failed, check your JS!" + exit 1 + fi + + + ''; scripts.create-polyfill.exec = '' -TMPFILE=${config.devenv.root}/.devenv/monster.js -touch $TMPFILE -##trap "rm -f $TMPFILE" 0 2 3 15 + TMPFILE=${config.devenv.root}/.devenv/monster.js + touch $TMPFILE + ##trap "rm -f $TMPFILE" 0 2 3 15 -${config.devenv.root}/node_modules/.bin/esbuild --platform=browser --bundle ${config.devenv.root}/source/monster.mjs --outfile=''${TMPFILE} + ${config.devenv.root}/node_modules/.bin/esbuild --platform=browser --bundle ${config.devenv.root}/source/monster.mjs --outfile=''${TMPFILE} -url="$(${pkgs.nodejs_20}/bin/npx create-polyfill-service-url analyse --file ".devenv/monster.js")" + url="$(${pkgs.nodejs_20}/bin/npx create-polyfill-service-url analyse --file ".devenv/monster.js")" -if [ ! -x {$url} ] -then - sed -i -E "/id=\"polyfill\"/s|.*| <script id=\"polyfill\" src=\"''${url}\"|g" ${config.devenv.root}/test/web/test.html - sed -i -E "/id=\"polyfill\"/s|.*|<script id=\"polyfill\" src=\"''${url}\"|g" ${config.devenv.root}/README.md -fi - -''; - + if [ ! -x {$url} ] + then + sed -i -E "/id=\"polyfill\"/s|.*| <script id=\"polyfill\" src=\"''${url}\"|g" ${config.devenv.root}/test/web/test.html + sed -i -E "/id=\"polyfill\"/s|.*|<script id=\"polyfill\" src=\"''${url}\"|g" ${config.devenv.root}/README.md + fi + + ''; + scripts.build-stylesheets.exec = '' - -components=$(${pkgs.coreutils}/bin/ls -d ${config.devenv.root}/source/components/*/ | \ - ${pkgs.gnused}/bin/sed -E "s|${config.devenv.root}/source/||g" | \ - ${pkgs.gnused}/bin/sed -E "s|/$||g" | ${pkgs.gnugrep}/bin/grep -v style ) -for component in $components; do - ${pkgs.nodejs_20}/bin/node ${config.devenv.root}/opt/scripts/build-stylesheets.cjs ${config.devenv.root} --rel-path $component -done - - ${pkgs.nodejs_20}/bin/node ${config.devenv.root}/opt/scripts/build-stylesheets.cjs ${config.devenv.root} --rel-path "components/" - - -''; + + components=$(${pkgs.coreutils}/bin/ls -d ${config.devenv.root}/source/components/*/ | \ + ${pkgs.gnused}/bin/sed -E "s|${config.devenv.root}/source/||g" | \ + ${pkgs.gnused}/bin/sed -E "s|/$||g" | ${pkgs.gnugrep}/bin/grep -v style ) + for component in $components; do + ${pkgs.nodejs_20}/bin/node ${config.devenv.root}/opt/scripts/build-stylesheets.cjs ${config.devenv.root} --rel-path $component + done + + ${pkgs.nodejs_20}/bin/node ${config.devenv.root}/opt/scripts/build-stylesheets.cjs ${config.devenv.root} --rel-path "components/" + + + ''; scripts.run-tests.exec = '' -update-versions -${pkgs.nodePackages.pnpm}/bin/pnpm mocha --colors --jobs 10 --bail --recursive test/cases/ + update-versions + ${pkgs.nodePackages.pnpm}/bin/pnpm mocha --colors --jobs 10 --bail --recursive test/cases/ ''; - + scripts.build-monster-mjs.exec = '' -$(${pkgs.nodejs_20}/bin/node ${config.devenv.root}/opt/scripts/build-exports.cjs) -''; + $(${pkgs.nodejs_20}/bin/node ${config.devenv.root}/opt/scripts/build-exports.cjs) + ''; - scripts.run-web-tests.exec = '' -PROJECT_ROOT="${config.devenv.root}" -TEST_PATH="${config.devenv.root}/test/" -TEST_CASES_PATH="${config.devenv.root}/test/cases/" - -VERSION=$(cat "${config.devenv.root}/package.json" | jq -r '.version') - -update-versions -build-monster-mjs -create-polyfill - - -find ''${TEST_CASES_PATH} -type f | sed "s|^$TEST_CASES_PATH||" > ''${TEST_PATH}web/import.js -sed -i 's|^|import "../cases/|' ''${TEST_PATH}web/import.js -sed -i 's|$|";|' ''${TEST_PATH}web/import.js -sed -i "1 i import \"./prepare.js\";" ''${TEST_PATH}web/import.js -sed -i "1 i /** this file was created automatically by the run-web-tests script */" ''${TEST_PATH}web/import.js - -npx esbuild --platform=browser --sourcemap=inline --external:ws --external:jsdom --external:process --external:crypto --bundle ''${TEST_PATH}web/import.js --outfile=''${TEST_PATH}web/tests.js - -sed -i '1s/^/try {\n/' ''${TEST_PATH}web/tests.js -echo "} catch (e) {" >> ''${TEST_PATH}web/tests.js -echo "document.getElementById('mocha-errors').insertAdjacentHTML('afterbegin', e );" >> ''${TEST_PATH}web/tests.js -echo "document.getElementById('mocha-stats').style.backgroundColor = 'red';" >> ''${TEST_PATH}web/tests.js -echo "}" >> ''${TEST_PATH}web/tests.js - -sed -i -E "/<h1/s_.*_ <h1 style='margin-bottom: 0.1em;'>Monster ''${VERSION}</h1>_" ''${TEST_PATH}web/test.html -sed -i -E "/id=\"lastupdate\"/s_.*_ <div id=\"lastupdate\" style='font-size:0.7em'>last update $(date)</div>_" ''${TEST_PATH}web/test.html -sed -i -E "s_src=\"([\"]*)\.js.*\"_src=\"\1.js?r=$(date +"%T")\"_" ''${TEST_PATH}web/test.html - - -${pkgs.xdg-utils}/bin/xdg-open ''${TEST_PATH}web/test.html - + PROJECT_ROOT="${config.devenv.root}" + TEST_PATH="${config.devenv.root}/test/" + TEST_CASES_PATH="${config.devenv.root}/test/cases/" + + VERSION=$(cat "${config.devenv.root}/package.json" | jq -r '.version') + + update-versions + build-monster-mjs + create-polyfill + + + find ''${TEST_CASES_PATH} -type f | sed "s|^$TEST_CASES_PATH||" > ''${TEST_PATH}web/import.js + sed -i 's|^|import "../cases/|' ''${TEST_PATH}web/import.js + sed -i 's|$|";|' ''${TEST_PATH}web/import.js + sed -i "1 i import \"./prepare.js\";" ''${TEST_PATH}web/import.js + sed -i "1 i /** this file was created automatically by the run-web-tests script */" ''${TEST_PATH}web/import.js + + npx esbuild --platform=browser --sourcemap=inline --external:ws --external:jsdom --external:process --external:crypto --bundle ''${TEST_PATH}web/import.js --outfile=''${TEST_PATH}web/tests.js + + sed -i '1s/^/try {\n/' ''${TEST_PATH}web/tests.js + echo "} catch (e) {" >> ''${TEST_PATH}web/tests.js + echo "document.getElementById('mocha-errors').insertAdjacentHTML('afterbegin', e );" >> ''${TEST_PATH}web/tests.js + echo "document.getElementById('mocha-stats').style.backgroundColor = 'red';" >> ''${TEST_PATH}web/tests.js + echo "}" >> ''${TEST_PATH}web/tests.js + + sed -i -E "/<h1/s_.*_ <h1 style='margin-bottom: 0.1em;'>Monster ''${VERSION}</h1>_" ''${TEST_PATH}web/test.html + sed -i -E "/id=\"lastupdate\"/s_.*_ <div id=\"lastupdate\" style='font-size:0.7em'>last update $(date)</div>_" ''${TEST_PATH}web/test.html + sed -i -E "s_src=\"([\"]*)\.js.*\"_src=\"\1.js?r=$(date +"%T")\"_" ''${TEST_PATH}web/test.html + + + ${pkgs.xdg-utils}/bin/xdg-open ''${TEST_PATH}web/test.html + ''; - - + scripts.publish-doc.exec = '' -#!${pkgs.bash}/bin/bash - -if [ -t 1 ]; then - RED='\033[0;31m' - GREEN='\033[0;32m' - RESET='\033[0m' - BOLD='\033[1m' -else - RED="" - GREEN="" - RESET="" -fi - -profileExists=$(aws configure list-profiles | grep shopcloud | wc -l) -if [ "$profileExists" -eq "0" ]; then - echo "No shopcloud profile found. Exiting." - echo "Please run: aws configure --profile=shopcloud" - exit 1 -fi - -if [ ! -d ${config.devenv.root}/dist/doc ]; then - echo -e "''${RED}✖ No doc found.''${RESET}" - exit 1 -fi - -${pkgs.awscli2}/bin/aws --profile=shopcloud s3 --recursive --only-show-errors cp ${config.devenv.root}/dist/doc/ s3://monsterjs.org/en/api/ -code=$? - -if [ "$code" -ne "0" ]; then - echo -e "''${RED}✖ Upload failed.''${RESET}" - exit 1 -fi -echo -e "''${GREEN}✔ Upload successful.''${RESET}" - - ''; - - scripts.build-doc.exec = '' -rm -rf ${config.devenv.root}/dist/doc + #!${pkgs.bash}/bin/bash -update-versions -create-polyfill + if [ -t 1 ]; then + RED='\033[0;31m' + GREEN='\033[0;32m' + RESET='\033[0m' + BOLD='\033[1m' + else + RED="" + GREEN="" + RESET="" + fi + + profileExists=$(aws configure list-profiles | grep shopcloud | wc -l) + if [ "$profileExists" -eq "0" ]; then + echo "No shopcloud profile found. Exiting." + echo "Please run: aws configure --profile=shopcloud" + exit 1 + fi + + if [ ! -d ${config.devenv.root}/dist/doc ]; then + echo -e "''${RED}✖ No doc found.''${RESET}" + exit 1 + fi + + ${pkgs.awscli2}/bin/aws --profile=shopcloud s3 --recursive --only-show-errors cp ${config.devenv.root}/dist/doc/ s3://monsterjs.org/en/api/ + code=$? + + if [ "$code" -ne "0" ]; then + echo -e "''${RED}✖ Upload failed.''${RESET}" + exit 1 + fi + echo -e "''${GREEN}✔ Upload successful.''${RESET}" -if [ -d ${config.devenv.root}/dist/doc ]; then + ''; + + scripts.build-doc.exec = '' rm -rf ${config.devenv.root}/dist/doc - mkdir -p ${config.devenv.root}/dist/doc -fi - -${config.devenv.root}/node_modules/.bin/jsdoc -c ${config.devenv.root}/doc/jsdoc.json -${pkgs.nodejs_20}/bin/node ${config.devenv.root}/opt/scripts/replace-skypack.cjs ${config.devenv.root} - -''; - + + update-versions + create-polyfill + + if [ -d ${config.devenv.root}/dist/doc ]; then + rm -rf ${config.devenv.root}/dist/doc + mkdir -p ${config.devenv.root}/dist/doc + fi + + ${config.devenv.root}/node_modules/.bin/jsdoc -c ${config.devenv.root}/doc/jsdoc.json + ${pkgs.nodejs_20}/bin/node ${config.devenv.root}/opt/scripts/replace-skypack.cjs ${config.devenv.root} + + ''; + scripts.do-commit.exec = '' #!/usr/bin/env bash @@ -486,7 +487,7 @@ ${pkgs.nodejs_20}/bin/node ${config.devenv.root}/opt/scripts/replace-skypack.cjs issue_text=$(gum input --placeholder "Enter issue title") echo -e "Enter issue description. ''${RED}End with Ctrl+D''${RESET}\n" issue_description=$(gum write --placeholder "Enter issue description. End with Ctrl+D") - + if [[ -z "$issue_text" ]]; then log_error_and_display "Issue title is empty. Exiting." printLogfileAndExit 1 @@ -525,7 +526,7 @@ ${pkgs.nodejs_20}/bin/node ${config.devenv.root}/opt/scripts/replace-skypack.cjs if [ ''${#work_on_issue_ids[@]} -eq 0 ]; then log_and_display "No issue selected. Exiting." printLogfileAndExit 0 - fi + fi # NEXT STEP COMMIT MESSAGE ############################################################################################################ # print work_on_issue_ids @@ -588,9 +589,9 @@ ${pkgs.nodejs_20}/bin/node ${config.devenv.root}/opt/scripts/replace-skypack.cjs while IFS= read -r line; do files+=("$line") done <<<"$git_status" - + selected_files=$(gum choose --no-limit "''${files[@]}") - + # no files selected if [[ -z "$selected_files" ]]; then log_and_display "No files selected. Exiting." @@ -605,10 +606,10 @@ ${pkgs.nodejs_20}/bin/node ${config.devenv.root}/opt/scripts/replace-skypack.cjs log_and_display "No file found in line: $line" continue fi - + git add "$file" done <<<"$selected_files" - + fi ## count staged changes again and print @@ -661,21 +662,19 @@ ${pkgs.nodejs_20}/bin/node ${config.devenv.root}/opt/scripts/replace-skypack.cjs print_headline "Closing issues" for issue_id in "''${work_on_issue_ids[@]}"; do - + gum confirm "Do you want to close issue #$issue_id?" if [ $? -eq 1 ]; then continue fi - + if ! glab issue close "$issue_id" ; then log_error_and_display "Closing issue $issue_id failed. Exiting." else - log_and_display "Closing issue $issue_id successful." + log_and_display "Closing issue $issue_id successful." fi done printLogfileAndExit 0 ''; - } - diff --git a/package.json b/package.json index 6f9b483007a5625833f17378cbc16199597b3144..0c2a793ba38226b7185d0bb4ac45a6e49f4c68d9 100644 --- a/package.json +++ b/package.json @@ -40,7 +40,7 @@ "author": "schukai GmbH", "license": "AGPL 3.0", "dependencies": { - "@floating-ui/dom": "^1.5.4", + "@floating-ui/dom": "^1.6.3", "@popperjs/core": "^2.11.8", "vite-plugin-directory-index": "^3.0.1" }, @@ -48,7 +48,7 @@ "@biomejs/biome": "1.3.3", "@peculiar/webcrypto": "^1.4.5", "autoprefixer": "^10.4.17", - "browserslist": "^4.22.2", + "browserslist": "^4.23.0", "btoa": "^1.2.1", "c8": "^8.0.1", "chai": "^4.4.1", @@ -56,7 +56,7 @@ "clean-jsdoc-theme": "^4.2.17", "create-polyfill-service-url": "^2.3.0", "crypt": "^0.0.2", - "cssnano": "^6.0.3", + "cssnano": "^6.0.5", "dom-storage": "^2.1.0", "element-internals-polyfill": "^1.3.10", "esbuild": "^0.19.12", @@ -72,21 +72,21 @@ "jsdoc-plantuml": "^1.0.3", "jsdom": "^22.1.0", "jsdom-global": "^3.0.2", - "mocha": "^10.2.0", + "mocha": "^10.3.0", "node-plantuml": "^0.9.0", - "postcss": "^8.4.33", + "postcss": "^8.4.35", "postcss-fluid": "^1.4.2", "postcss-for": "^2.1.1", "postcss-import": "^15.1.0", "postcss-load-config": "^4.0.2", "postcss-mixins": "^9.0.4", "postcss-nested": "^6.0.1", - "postcss-nesting": "^12.0.2", + "postcss-nesting": "^12.0.3", "postcss-normalize": "^10.0.1", "postcss-responsive-type": "^1.0.0", "postcss-rtlcss": "^4.0.9", "postcss-strip-units": "^2.0.1", - "puppeteer": "^21.9.0", + "puppeteer": "^21.11.0", "sinon": "^17.0.1", "url": "^0.11.3", "url-exist": "3.0.1", @@ -95,6 +95,7 @@ "vite-plugin-banner": "^0.7.1", "vite-plugin-list-directory-contents": "^1.4.5", "vite-plugin-minify": "^1.5.2", + "vite-plugin-mock": "^3.0.1", "ws": "^8.16.0" } } diff --git a/playground/bind-with-datasource/index.html b/playground/bind-with-datasource/index.html new file mode 100644 index 0000000000000000000000000000000000000000..dc118419654abea5bbcc7658a920a360b5669c64 --- /dev/null +++ b/playground/bind-with-datasource/index.html @@ -0,0 +1,166 @@ +<!doctype html> +<html lang="en"> + +<head> + <meta charset="utf-8"> + <meta name="viewport" content="width=device-width, initial-scale=1"> + <title>Monster-Bind mit Datasource</title> + <script src="main.mjs" type="module"></script> + +</head> + +<body> +<main> + <div> + <!-- + Datasource mit fest definieren Daten + --> + + <monster-datasource-rest id="data1" + data-monster-option-write-url="/demo/bind-with-datasource/data.json" + data-monster-option-read-url="/demo/bind-with-datasource/data.json"></monster-datasource-rest> + + <h1>Bestellungen</h1> + + + <!-- + Datatable stellt diese Daten dar + mit "data-monster-datasource-selector" wird die Datenquelle "#data1" definiert + --> + <monster-datatable id="test-datatable" data-monster-datasource-selector="#data1"> + + <monster-datasource-save-button slot="bar" data-monster-option-datasource-selector="#data1"> + </monster-datasource-save-button> + <monster-datasource-status slot="bar" data-monster-option-datasource-selector="#data1"> + </monster-datasource-status> + + <template id="test-datatable-row"> + + <div data-monster-head="erpName" data-monster-replace="path:test-datatable-row.erpName "></div> + <div data-monster-head="OID" data-monster-mode="fixed" data-monster-sortable="oid" + data-monster-replace="path:test-datatable-row.oid | tostring"></div> + <div data-monster-head="orderLastStatusChange" + data-monster-replace="path:test-datatable-row.orderLastStatusChange"></div> + <div data-monster-head="customerUID" data-monster-replace="path:test-datatable-row.customerUID"></div> + <div data-monster-head="resubmissionDate" + data-monster-replace="path:test-datatable-row.resubmissionDate"></div> + <div data-monster-head="billingAddressAID" + data-monster-replace="path:test-datatable-row.billingAddressAID"></div> + <div data-monster-head="deliveryAddressAID" + data-monster-replace="path:test-datatable-row.deliveryAddressAID"></div> + + <div data-monster-head=" " data-alvine-role="actionHolder" class="actionButtons"> + + <monster-datatable-change-button + style="height:100%;display:flex;margin-right:0.1rem;" + data-monster-option-dataset-selector="#dataset1" + data-monster-option-overlay-selector="#overlay1"> + + </monster-datatable-change-button> + <monster-datatable-change-button + style="height:100%;;display:flex;" + data-monster-option-labels-button="o2" + data-monster-option-dataset-selector="#dataset1" + data-monster-option-overlay-selector="#overlay2"> + + </monster-datatable-change-button> + + + <!--monster-button + data-alvine-role="changeButton" + data-monster-option-actions-click="" + data-monster-attributes="data-alvine-oid path:test-datatable-row.index"> + <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" + class="bi bi-grid" viewBox="0 0 16 16"> + <path d="M1 2.5A1.5 1.5 0 0 1 2.5 1h3A1.5 1.5 0 0 1 7 2.5v3A1.5 1.5 0 0 1 5.5 7h-3A1.5 1.5 0 0 1 1 5.5zM2.5 2a.5.5 0 0 0-.5.5v3a.5.5 0 0 0 .5.5h3a.5.5 0 0 0 .5-.5v-3a.5.5 0 0 0-.5-.5zm6.5.5A1.5 1.5 0 0 1 10.5 1h3A1.5 1.5 0 0 1 15 2.5v3A1.5 1.5 0 0 1 13.5 7h-3A1.5 1.5 0 0 1 9 5.5zm1.5-.5a.5.5 0 0 0-.5.5v3a.5.5 0 0 0 .5.5h3a.5.5 0 0 0 .5-.5v-3a.5.5 0 0 0-.5-.5zM1 10.5A1.5 1.5 0 0 1 2.5 9h3A1.5 1.5 0 0 1 7 10.5v3A1.5 1.5 0 0 1 5.5 15h-3A1.5 1.5 0 0 1 1 13.5zm1.5-.5a.5.5 0 0 0-.5.5v3a.5.5 0 0 0 .5.5h3a.5.5 0 0 0 .5-.5v-3a.5.5 0 0 0-.5-.5zm6.5.5A1.5 1.5 0 0 1 10.5 9h3a1.5 1.5 0 0 1 1.5 1.5v3a1.5 1.5 0 0 1-1.5 1.5h-3A1.5 1.5 0 0 1 9 13.5zm1.5-.5a.5.5 0 0 0-.5.5v3a.5.5 0 0 0 .5.5h3a.5.5 0 0 0 .5-.5v-3a.5.5 0 0 0-.5-.5z"/> + </svg> + </monster-button --> + </div> + </template> + </monster-datatable> + + <monster-overlay id="overlay1" data-monster-option-features-openbutton="false"> + + + <monster-dataset id="dataset1" data-monster-datasource-selector="#data1"> + + <div class="form-container"> + <h2>OVERLAY 1</h2> + <div class="inner-form"> + <label>test + <input data-monster-bind="path:data.oid" data-monster-bind-type="integer" + data-monster-attributes="value path:data.oid "></label> + <label>test + <input data-monster-bind="path:data.erpName" + data-monster-attributes="value path:data.erpName "></label> + <label>test + <input data-monster-bind="path:data.erpName" + data-monster-attributes="value path:data.erpNumber "></label> + + <div data-monster-replace="path:data.oid ">xx</div> + <div data-monster-replace="path:data.orderState ">xx</div> + <div data-monster-replace="path:data.orderLastStatusChange ">xx</div> + + <div class="buttons"> + <monster-button + data-monster-role="saveButton" + id="saveButton" + style="display:block;width:200px;">save + </monster-button> + <monster-button + data-monster-role="cancelButton" + id="cancelButton" + style="display:block;width:200px;">cancel + </monster-button> + + </div> + + </div> + </div> + + </monster-dataset> + </monster-overlay> + + + <monster-overlay id="overlay2" data-monster-option-features-openbutton="false"> + + + <monster-dataset id="dataset2" data-monster-datasource-selector="#data1"> + + <div class="form-container"> + <h2>OVERLAY 2</h2> + <div class="inner-form"> + <label>test + <input data-monster-bind="path:data.oid" data-monster-bind-type="integer" + data-monster-attributes="value path:data.oid "></label> + <label>test + <input data-monster-bind="path:data.erpName" + data-monster-attributes="value path:data.erpName "></label> + + + <div class="buttons"> + <monster-button + data-monster-role="saveButton" + id="saveButton" + style="display:block;width:200px;">save + </monster-button> + <monster-button + data-monster-role="cancelButton" + id="cancelButton" + style="display:block;width:200px;">cancel + </monster-button> + + </div> + + </div> + </div> + + </monster-dataset> + </monster-overlay> + </div> + + +</main> +</body> + +</html> \ No newline at end of file diff --git a/playground/bind-with-datasource/main.mjs b/playground/bind-with-datasource/main.mjs new file mode 100644 index 0000000000000000000000000000000000000000..9d38ce086a71b30fba9c4de1195db778e7845920 --- /dev/null +++ b/playground/bind-with-datasource/main.mjs @@ -0,0 +1,74 @@ + +import "../../source/components/form/button.mjs"; +import "../../source/components/host/overlay.mjs"; +import "../../source/components/datatable/datatable.mjs"; +import "../../source/components/datatable/dataset.mjs"; +import "../../source/components/datatable/datasource/dom.mjs"; +import "../../source/components/datatable/datasource/rest.mjs"; +import "../../source/components/datatable/save-button.mjs"; + +import "../../source/components/style/color.pcss"; +import "../../source/components/style/theme.pcss"; +import "../../source/components/style/table.pcss"; +import "../../source/components/style/property.pcss"; +import "../../source/components/style/badge.pcss"; +import "../../source/components/style/button.pcss"; +import "../../source/components/style/link.pcss"; +import "../../source/components/style/data-grid.pcss"; +import "../../source/components/style/property.pcss"; +import "../../source/components/style/typography.pcss"; +import "../../source/components/style/display.pcss"; +import "../../source/components/datatable/datasource/rest.mjs"; +import "../../source/components/datatable/filter.mjs"; +import "../../source/components/datatable/filter-button.mjs"; +import "../../source/components/datatable/embedded-pagination.mjs"; +import "../../source/components/datatable/datatable.mjs"; +import "../../source/components/datatable/dataset.mjs"; +import "../../source/components/datatable/status.mjs"; +import "../../source/components/datatable/save-button.mjs"; +import "../../source/components/datatable/change-button.mjs"; +import "../../source/components/datatable/filter/range.mjs"; +import "../../source/components/datatable/filter/select.mjs"; +import "../../source/components/datatable/filter/input.mjs"; +import "../../source/components/datatable/filter/date-range.mjs"; +import {windowReady} from "../../source/dom/ready.mjs"; +import "../../source/components/host/host.mjs"; +import "../../source/components/form/button.mjs"; +import "../../source/components/form/button-bar.mjs"; +import "../../source/components/form/popper-button.mjs"; +import "../../source/components/form/tabs.mjs"; +import "./main.pcss"; + + +import { findTargetElementFromEvent } from "../../source/dom/events.mjs"; + +let data = document.getElementById('data1'); +let dataset1 = document.getElementById('dataset1'); +//let dataset2 = document.getElementById('dataset2'); + +//console.log(data); + +let saveButton = document.getElementById('saveButton'); +saveButton.setOption('actions.click', () => { + dataset1.write(); +}) + +document.addEventListener("monster-button-clicked", (event) => { + document.getElementById('overlay1').close(); +}); + + + +/** + * customElementUpdaterLinkSymbol + * + * datsource > datenquelle + * + * dataset + * const updaters = getLinkedObjects(self, customElementUpdaterLinkSymbol); + * + * proxyObserver > Updater + * + * + * + */ diff --git a/playground/bind-with-datasource/main.pcss b/playground/bind-with-datasource/main.pcss new file mode 100644 index 0000000000000000000000000000000000000000..82df8dc929c67a133af862ee8685d2ca77957009 --- /dev/null +++ b/playground/bind-with-datasource/main.pcss @@ -0,0 +1,25 @@ +@import"../../source/components/style/mixin/form.pcss"; + + +.form-container { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + min-height: calc( 100vh - 100px ); + background-color: var(--monster-bg-color-primary-1); + color: var(--monster-color-primary-1); +} + +.inner-form { + @mixin form; + min-width: fit-content; +} + +.buttons { + display: flex; + justify-content: space-between; + gap: 1em; + width: 100%; + margin-top: 20px; +} diff --git a/playground/datatable/index.html b/playground/datatable/index.html index d2f9391fbbd38528d566431500c18e29af0e1cad..ef7de0aa6a552fb4bca90525df9eb32f2f8d927d 100644 --- a/playground/datatable/index.html +++ b/playground/datatable/index.html @@ -23,15 +23,15 @@ <monster-config-manager></monster-config-manager> <h1>Datatable with Pagination </h1> +<!-- "url": "http://localhost:8070/api/commerce/orders/search?q=${path:query | default:order.customerUID>0}&page=${page}&orderby=${path:order | default:oid}",--> <script id="id-for-this-config" type="application/json"> { "read": { - "url": "http://localhost:8070/api/commerce/orders/search?q=${path:query | default:order.customerUID>0}&page=${page}&orderby=${path:order | default:oid}", + "url": "http://localhost/api/wiremock", "init": { "method": "GET", "headers": { "Content-Type": "application/json", - "Authorization": "Basic YWRtaW5pc3RyYXRvcjpsYW5kc2JlcmllZA==", "Accept": "application/json" } }, @@ -53,6 +53,9 @@ <div data-monster-replace="path:data.oid | tostring">xx</div> <div data-monster-replace="path:data.orderState | tostring">xx</div> <div data-monster-replace="path:data.erpCreation | tostring">xx</div> + <form> + + </form> </monster-dataset> diff --git a/playground/filter/index.html b/playground/filter/index.html index 24e4419d1c5053b6c1275a5a9abd18cac6c0fa68..df4cec59edec419a572a49ec282c635c1e948d8d 100644 --- a/playground/filter/index.html +++ b/playground/filter/index.html @@ -27,12 +27,11 @@ <script id="id-for-this-config" type="application/json"> { "read": { - "url": "https://localhost.schukai.net:8443/api/commerce/orders/search?q=order.customerUID>0&page=${page}&orderby=${path:order | default:oid}", + "url": "http://localhost:8888/api/datatable?q=${path:query | default:order.customerUID>0}&page=${page}&orderby=${path:order | default:oid}", "init": { "method": "GET", "headers": { "Content-Type": "application/json", - "Authorization": "Basic ==YWRtaW46bGFuZHNiZXJpZWQK", "Accept": "application/json" } }, diff --git a/playground/i18n-debug1/index.html b/playground/i18n-debug1/index.html index 3d7eaa920ef034d2d5e94c89842fa65d4ad641a2..3781cdecf871135bfb33e79ecb3c13c06407abe2 100644 --- a/playground/i18n-debug1/index.html +++ b/playground/i18n-debug1/index.html @@ -26,12 +26,11 @@ <script id="id-for-this-config" type="application/json"> { "read": { - "url": "https://localhost.schukai.net:8443/api/commerce/orders/search?q=order.customerUID>0&page=${page}&orderby=${path:order | default:oid}", + "url": "http://localhost:8888/api/datatable?q=${path:query | default:order.customerUID>0}&page=${page}&orderby=${path:order | default:oid}", "init": { "method": "GET", "headers": { "Content-Type": "application/json", - "Authorization": "Basic ==YWRtaW46bGFuZHNiZXJpZWQK", "Accept": "application/json" } }, diff --git a/playground/mock/demo.js b/playground/mock/demo.js new file mode 100644 index 0000000000000000000000000000000000000000..4eed3d4c2b86e61479529abc2d3afcbeff0d9fe9 --- /dev/null +++ b/playground/mock/demo.js @@ -0,0 +1,199 @@ + +const json = + `{ + "dataset": [ + { + "erpID": "", + "erpName": "mix up erp1", + "erpNumber": "", + "erpLastUpdate": "2020-01-16T10:27:18", + "erpCreation": "2020-01-16T10:27:18", + "archived": false, + "oid": 88, + "orderDate": "2019-01-16T10:27:18", + "orderState": 57, + "orderLastStatusChange": "2019-01-16T10:38:53", + "customerUID": 30, + "customerNotice": "", + "billingAddressAID": 16, + "deliveryAddressAID": 16, + "deliveryNotice": "", + "paymentPID": 101, + "assigndTickets": "", + "resubmissionDate": "1970-01-01T12:00:00", + "resubmissionInfo": "", + "acquisitionPartnerID": 0, + "acquisitionInfo": "", + "acquisitionRedirect": null, + "acquisitionDate": "1970-01-01T12:00:00", + "shippingNotice": "", + "shippingDCID": 2, + "retoureRID": 0, + "companySHID": 1, + "salesmanUID": 0, + "channelOrderID": "", + "channelOrderState": "0", + "channelOrderDate": null, + "channelOrderData": {} + }, + { + "erpID": "", + "erpName": "erp 2", + "erpNumber": "", + "erpLastUpdate": "2020-01-16T10:27:18", + "erpCreation": "2020-01-16T10:27:18", + "archived": false, + "oid": 1000, + "orderDate": "2019-01-16T10:27:18", + "orderState": 57, + "orderLastStatusChange": "2019-01-16T10:38:53", + "customerUID": 30, + "customerNotice": "", + "billingAddressAID": 16, + "deliveryAddressAID": 16, + "deliveryNotice": "", + "paymentPID": 101, + "assigndTickets": "", + "resubmissionDate": "1970-01-01T12:00:00", + "resubmissionInfo": "", + "acquisitionPartnerID": 0, + "acquisitionInfo": "", + "acquisitionRedirect": null, + "acquisitionDate": "1970-01-01T12:00:00", + "shippingNotice": "", + "shippingDCID": 2, + "retoureRID": 0, + "companySHID": 1, + "salesmanUID": 0, + "channelOrderID": "", + "channelOrderState": "0", + "channelOrderDate": null, + "channelOrderData": {} + }, + { + "erpID": "", + "erpName": "erp4", + "erpNumber": "", + "erpLastUpdate": "2020-01-16T10:27:18", + "erpCreation": "2020-01-16T10:27:18", + "archived": false, + "oid": 1001, + "orderDate": "2019-01-16T10:27:18", + "orderState": 57, + "orderLastStatusChange": "2019-02-16T10:38:53", + "customerUID": 30, + "customerNotice": "", + "billingAddressAID": 16, + "deliveryAddressAID": 16, + "deliveryNotice": "", + "paymentPID": 101, + "assigndTickets": "", + "resubmissionDate": "1970-01-01T12:00:00", + "resubmissionInfo": "", + "acquisitionPartnerID": 0, + "acquisitionInfo": "", + "acquisitionRedirect": null, + "acquisitionDate": "1970-01-01T12:00:00", + "shippingNotice": "", + "shippingDCID": 2, + "retoureRID": 0, + "companySHID": 1, + "salesmanUID": 0, + "channelOrderID": "", + "channelOrderState": "0", + "channelOrderDate": null, + "channelOrderData": {} + }, + { + "erpID": "", + "erpName": "erpedsdf", + "erpNumber": "", + "erpLastUpdate": "2020-01-16T10:27:18", + "erpCreation": "2020-01-16T10:27:18", + "archived": false, + "oid": 1002, + "orderDate": "2019-01-16T10:27:18", + "orderState": 57, + "orderLastStatusChange": "2019-03-16T10:38:53", + "customerUID": 30, + "customerNotice": "", + "billingAddressAID": 16, + "deliveryAddressAID": 16, + "deliveryNotice": "", + "paymentPID": 101, + "assigndTickets": "", + "resubmissionDate": "1970-01-01T12:00:00", + "resubmissionInfo": "", + "acquisitionPartnerID": 0, + "acquisitionInfo": "", + "acquisitionRedirect": null, + "acquisitionDate": "1970-01-01T12:00:00", + "shippingNotice": "", + "shippingDCID": 2, + "retoureRID": 0, + "companySHID": 1, + "salesmanUID": 0, + "channelOrderID": "", + "channelOrderState": "0", + "channelOrderDate": null, + "channelOrderData": {} + } + ], + "sys": { + "pagination": { + "currentPage": 1, + "nextOffset": 3, + "pages": 1, + "prevOffset": null, + "offset": 0, + "objectsPerPage": 20, + "total": 3 + }, + "message": "200 OK", + "code": 200 + }}` + +const data = JSON.parse(json) + + +const requestDelay = 1000 + + +export default [ + { + url: '/demo/bind-with-datasource/data.json', + method: 'get', + rawResponse: async (req, res) => { + res.setHeader('Content-Type', 'application/json') + res.statusCode = 200 + + setTimeout(function() { + res.end(json) + }, requestDelay); + + + }, + + }, + { + url: '/demo/bind-with-datasource/data.json', + method: 'post', + rawResponse: async (req, res) => { + let reqbody = '' + await new Promise((resolve) => { + req.on('data', (chunk) => { + reqbody += chunk + }) + req.on('end', () => resolve(undefined)) + }) + res.setHeader('Content-Type', 'application/json') + res.statusCode = 200 + + setTimeout(function() { + res.end("{}") + }, requestDelay); + + + }, + }, +]; \ No newline at end of file diff --git a/playground/monster-bind-with-datasource/index.html b/playground/monster-bind-with-datasource/index.html deleted file mode 100644 index a60356c32192f97fa6236937474f83a80a1c4a90..0000000000000000000000000000000000000000 --- a/playground/monster-bind-with-datasource/index.html +++ /dev/null @@ -1,218 +0,0 @@ -<!doctype html> -<html lang="en"> - -<head> - <meta charset="utf-8"> - <meta name="viewport" content="width=device-width, initial-scale=1"> - <title>Monster-Bind mit Datasource</title> - <script src="main.mjs" type="module"></script> -</head> - -<body> - <main> - <div> - <!-- - Datasource mit fest definieren Daten - --> - - <monster-datasource-dom id="data1"> - <script id="data" type="application/json"> - { - "dataset": [ - { - "erpID": "", - "erpName": "", - "erpNumber": "", - "erpLastUpdate": "2020-01-16T10:27:18", - "erpCreation": "2020-01-16T10:27:18", - "archived": false, - "oid": 1000, - "orderDate": "2019-01-16T10:27:18", - "orderState": 57, - "orderLastStatusChange": "2019-01-16T10:38:53", - "customerUID": 30, - "customerNotice": "", - "billingAddressAID": 16, - "deliveryAddressAID": 16, - "deliveryNotice": "", - "paymentPID": 101, - "assigndTickets": "", - "resubmissionDate": "1970-01-01T12:00:00", - "resubmissionInfo": "", - "acquisitionPartnerID": 0, - "acquisitionInfo": "", - "acquisitionRedirect": null, - "acquisitionDate": "1970-01-01T12:00:00", - "shippingNotice": "", - "shippingDCID": 2, - "retoureRID": 0, - "companySHID": 1, - "salesmanUID": 0, - "channelOrderID": "", - "channelOrderState": "0", - "channelOrderDate": null, - "channelOrderData": {} - }, - { - "erpID": "", - "erpName": "", - "erpNumber": "", - "erpLastUpdate": "2020-01-16T10:27:18", - "erpCreation": "2020-01-16T10:27:18", - "archived": false, - "oid": 1000, - "orderDate": "2019-01-16T10:27:18", - "orderState": 57, - "orderLastStatusChange": "2019-01-16T10:38:53", - "customerUID": 30, - "customerNotice": "", - "billingAddressAID": 16, - "deliveryAddressAID": 16, - "deliveryNotice": "", - "paymentPID": 101, - "assigndTickets": "", - "resubmissionDate": "1970-01-01T12:00:00", - "resubmissionInfo": "", - "acquisitionPartnerID": 0, - "acquisitionInfo": "", - "acquisitionRedirect": null, - "acquisitionDate": "1970-01-01T12:00:00", - "shippingNotice": "", - "shippingDCID": 2, - "retoureRID": 0, - "companySHID": 1, - "salesmanUID": 0, - "channelOrderID": "", - "channelOrderState": "0", - "channelOrderDate": null, - "channelOrderData": {} - }, - { - "erpID": "", - "erpName": "", - "erpNumber": "", - "erpLastUpdate": "2020-01-16T10:27:18", - "erpCreation": "2020-01-16T10:27:18", - "archived": false, - "oid": 1001, - "orderDate": "2019-01-16T10:27:18", - "orderState": 57, - "orderLastStatusChange": "2019-02-16T10:38:53", - "customerUID": 30, - "customerNotice": "", - "billingAddressAID": 16, - "deliveryAddressAID": 16, - "deliveryNotice": "", - "paymentPID": 101, - "assigndTickets": "", - "resubmissionDate": "1970-01-01T12:00:00", - "resubmissionInfo": "", - "acquisitionPartnerID": 0, - "acquisitionInfo": "", - "acquisitionRedirect": null, - "acquisitionDate": "1970-01-01T12:00:00", - "shippingNotice": "", - "shippingDCID": 2, - "retoureRID": 0, - "companySHID": 1, - "salesmanUID": 0, - "channelOrderID": "", - "channelOrderState": "0", - "channelOrderDate": null, - "channelOrderData": {} - }, - { - "erpID": "", - "erpName": "", - "erpNumber": "", - "erpLastUpdate": "2020-01-16T10:27:18", - "erpCreation": "2020-01-16T10:27:18", - "archived": false, - "oid": 1002, - "orderDate": "2019-01-16T10:27:18", - "orderState": 57, - "orderLastStatusChange": "2019-03-16T10:38:53", - "customerUID": 30, - "customerNotice": "", - "billingAddressAID": 16, - "deliveryAddressAID": 16, - "deliveryNotice": "", - "paymentPID": 101, - "assigndTickets": "", - "resubmissionDate": "1970-01-01T12:00:00", - "resubmissionInfo": "", - "acquisitionPartnerID": 0, - "acquisitionInfo": "", - "acquisitionRedirect": null, - "acquisitionDate": "1970-01-01T12:00:00", - "shippingNotice": "", - "shippingDCID": 2, - "retoureRID": 0, - "companySHID": 1, - "salesmanUID": 0, - "channelOrderID": "", - "channelOrderState": "0", - "channelOrderDate": null, - "channelOrderData": {} - } - ], - "sys": { - "pagination": { - "currentPage": 1, - "nextOffset": 3, - "pages": 1, - "prevOffset": null, - "offset": 0, - "objectsPerPage": 20, - "total": 3 - }, - "message": "200 OK", - "code": 200 - } - } - </script> - </monster-datasource-dom> - - <h1>Bestellungen</h1> - - <!-- - Datatable stellt diese Daten dar - mit "data-monster-datasource-selector" wird die Datenquelle "#data1" definiert - --> - <monster-datatable id="test-datatable" data-monster-datasource-selector="#data1"> - <template id="test-datatable-row"> - - <div data-monster-head="martin" data-monster-replace="path:test-datatable-row.martin "></div> - <div data-monster-head="OID" data-monster-mode="fixed" data-monster-sortable="oid" data-monster-replace="path:test-datatable-row.oid | tostring"></div> - <div data-monster-head="orderLastStatusChange" data-monster-replace="path:test-datatable-row.orderLastStatusChange"></div> - <div data-monster-head="customerUID" data-monster-replace="path:test-datatable-row.customerUID"></div> - <div data-monster-head="resubmissionDate" data-monster-replace="path:test-datatable-row.resubmissionDate"></div> - <div data-monster-head="billingAddressAID" data-monster-replace="path:test-datatable-row.billingAddressAID"></div> - <div data-monster-head="deliveryAddressAID" data-monster-replace="path:test-datatable-row.deliveryAddressAID"></div> - - <div data-monster-head="aktion" data-alvine-role="actionHolder"> - <monster-button data-alvine-role="changeButon" data-monster-attributes="data-alvine-oid path:test-datatable-row.index"> - <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" class="bi bi-pencil-square" viewBox="0 0 16 16"> - <path d="M15.502 1.94a.5.5 0 0 1 0 .706L14.459 3.69l-2-2L13.502.646a.5.5 0 0 1 .707 0l1.293 1.293zm-1.75 2.456-2-2L4.939 9.21a.5.5 0 0 0-.121.196l-.805 2.414a.25.25 0 0 0 .316.316l2.414-.805a.5.5 0 0 0 .196-.12l6.813-6.814z"></path> - <path fill-rule="evenodd" d="M1 13.5A1.5 1.5 0 0 0 2.5 15h11a1.5 1.5 0 0 0 1.5-1.5v-6a.5.5 0 0 0-1 0v6a.5.5 0 0 1-.5.5h-11a.5.5 0 0 1-.5-.5v-11a.5.5 0 0 1 .5-.5H9a.5.5 0 0 0 0-1H2.5A1.5 1.5 0 0 0 1 2.5v11z"></path> - </svg> - </monster-button> - </div> - </template> - </monster-datatable> - - <h2>eine Bestellung im dataset</h2> - - <monster-dataset id="test-dataset" data-monster-datasource-selector="#data1" > - <div data-monster-replace="path:data.oid ">xx</div> - <div data-monster-replace="path:data.orderState ">xx</div> - <div data-monster-replace="path:data.orderLastStatusChange ">xx</div> - <input data-monster-bind="path:data.customerUID" data-monster-attributes="value path:data.customerUID "> - </monster-dataset> - - </div> - - </main> -</body> - -</html> \ No newline at end of file diff --git a/playground/monster-bind-with-datasource/main.mjs b/playground/monster-bind-with-datasource/main.mjs deleted file mode 100644 index ec3148b281bfcfe64b818b5e73a5c68e2ad84719..0000000000000000000000000000000000000000 --- a/playground/monster-bind-with-datasource/main.mjs +++ /dev/null @@ -1,60 +0,0 @@ - -import "../../source/components/form/button.mjs"; -import "../../source/components/datatable/datatable.mjs"; -import "../../source/components/datatable/dataset.mjs"; -import "../../source/components/datatable/datasource/dom.mjs"; - -import { findTargetElementFromEvent } from "../../source/dom/events.mjs"; - -document.addEventListener("monster-button-clicked", (event) => { - - let changeButon = findTargetElementFromEvent(event, 'data-alvine-role', 'changeButon'); - if (changeButon) { - //index des Datensatzes ermitteln - //aktuell 23.02.2024 nur über das attribute möglich - //der index steht immer hinten - let parent = changeButon.closest('[data-alvine-role="actionHolder"]') - let reference = parent.getAttribute("data-monster-insert-reference"); - let index = reference.split("-")[3]; - - // Index sezten - dataset.setOption('mapping.index', index); - } - -}); - -// let body = document.body; - -// let updater = new Updater( -// body, -// { -// a: { -// b: "hello" -// } -// } -// ); - -// /** -// * Events an schalten -// */ -// updater.enableEventProcessing(); -// updater.run().then(() => { -// console.log('done'); -// }); - - - - -/** - * customElementUpdaterLinkSymbol - * - * datsource > datenquelle - * - * dataset - * const updaters = getLinkedObjects(self, customElementUpdaterLinkSymbol); - * - * proxyObserver > Updater - * - * - * - */ diff --git a/playground/monster-state-button/index.html b/playground/state-button/index.html similarity index 100% rename from playground/monster-state-button/index.html rename to playground/state-button/index.html diff --git a/playground/monster-state-button/main.js b/playground/state-button/main.js similarity index 100% rename from playground/monster-state-button/main.js rename to playground/state-button/main.js diff --git a/playground/monster-state-button/main.pcss b/playground/state-button/main.pcss similarity index 100% rename from playground/monster-state-button/main.pcss rename to playground/state-button/main.pcss diff --git a/playground/vite.config.js b/playground/vite.config.js index 19eae15505c73e02d50b145f73a6233faaf1d8ff..8608de8e43133769f1f1edc887a3c0de82086cd8 100644 --- a/playground/vite.config.js +++ b/playground/vite.config.js @@ -15,22 +15,12 @@ import autoprefixer from 'autoprefixer'; import postcssMixins from 'postcss-mixins'; import postcssResponsiveType from 'postcss-responsive-type'; -//import {directoryPlugin} from "vite-plugin-list-directory-contents"; - -//import mkcert from 'vite-plugin-mkcert' import {ViteMinifyPlugin} from 'vite-plugin-minify' +import { viteMockServe } from 'vite-plugin-mock'; -import directoryIndex from 'vite-plugin-directory-index'; - - -//import {exec} from "child_process"; - -//let files = {}; -// -// const source = resolve(__dirname, '') -// const dist = resolve(__dirname, '') +import directoryIndex from 'vite-plugin-directory-index'; function getAppRootDir() { let currentDir = __dirname @@ -70,6 +60,10 @@ export default defineConfig({ // }), directoryIndex({ }), + viteMockServe({ + mockPath:playgroundDir+ "/mock", // Der Pfad zu Ihren Mock-Dateien + }) + ], css: { postcss: { @@ -128,6 +122,17 @@ export default defineConfig({ }, }, + + // middlewareMode: (middlewares, server) => { + // middlewares.use('/demo/bind-with-datasource/data.json', (req, res) => { + // if (req.method === 'GET') { + // res.writeHead(200, { 'Content-Type': 'application/json' }); + // res.end(JSON.stringify({ id: 1, name: 'Max Mustermann' })); + // } + // }); + // return middlewares; + // }, + // }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ce61c7f31b4b9128704fa81d39270d4ff1d1fd8d..13008bb1d3e3139af322770fcf534c3ad14df333 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -6,8 +6,8 @@ settings: dependencies: '@floating-ui/dom': - specifier: ^1.5.4 - version: 1.5.4 + specifier: ^1.6.3 + version: 1.6.3 '@popperjs/core': specifier: ^2.11.8 version: 2.11.8 @@ -24,10 +24,10 @@ devDependencies: version: 1.4.5 autoprefixer: specifier: ^10.4.17 - version: 10.4.17(postcss@8.4.33) + version: 10.4.17(postcss@8.4.35) browserslist: - specifier: ^4.22.2 - version: 4.22.2 + specifier: ^4.23.0 + version: 4.23.0 btoa: specifier: ^1.2.1 version: 1.2.1 @@ -50,8 +50,8 @@ devDependencies: specifier: ^0.0.2 version: 0.0.2 cssnano: - specifier: ^6.0.3 - version: 6.0.3(postcss@8.4.33) + specifier: ^6.0.5 + version: 6.0.5(postcss@8.4.35) dom-storage: specifier: ^2.1.0 version: 2.1.0 @@ -98,14 +98,14 @@ devDependencies: specifier: ^3.0.2 version: 3.0.2(jsdom@22.1.0) mocha: - specifier: ^10.2.0 - version: 10.2.0 + specifier: ^10.3.0 + version: 10.3.0 node-plantuml: specifier: ^0.9.0 version: 0.9.0 postcss: - specifier: ^8.4.33 - version: 8.4.33 + specifier: ^8.4.35 + version: 8.4.35 postcss-fluid: specifier: ^1.4.2 version: 1.4.2 @@ -114,34 +114,34 @@ devDependencies: version: 2.1.1 postcss-import: specifier: ^15.1.0 - version: 15.1.0(postcss@8.4.33) + version: 15.1.0(postcss@8.4.35) postcss-load-config: specifier: ^4.0.2 - version: 4.0.2(postcss@8.4.33) + version: 4.0.2(postcss@8.4.35) postcss-mixins: specifier: ^9.0.4 - version: 9.0.4(postcss@8.4.33) + version: 9.0.4(postcss@8.4.35) postcss-nested: specifier: ^6.0.1 - version: 6.0.1(postcss@8.4.33) + version: 6.0.1(postcss@8.4.35) postcss-nesting: - specifier: ^12.0.2 - version: 12.0.2(postcss@8.4.33) + specifier: ^12.0.3 + version: 12.0.3(postcss@8.4.35) postcss-normalize: specifier: ^10.0.1 - version: 10.0.1(browserslist@4.22.2)(postcss@8.4.33) + version: 10.0.1(browserslist@4.23.0)(postcss@8.4.35) postcss-responsive-type: specifier: ^1.0.0 version: 1.0.0 postcss-rtlcss: specifier: ^4.0.9 - version: 4.0.9(postcss@8.4.33) + version: 4.0.9(postcss@8.4.35) postcss-strip-units: specifier: ^2.0.1 version: 2.0.1 puppeteer: - specifier: ^21.9.0 - version: 21.9.0 + specifier: ^21.11.0 + version: 21.11.0 sinon: specifier: ^17.0.1 version: 17.0.1 @@ -156,7 +156,7 @@ devDependencies: version: 0.12.5 vite: specifier: ^4.5.2 - version: 4.5.2(@types/node@18.19.9) + version: 4.5.2(@types/node@18.19.18) vite-plugin-banner: specifier: ^0.7.1 version: 0.7.1 @@ -166,6 +166,9 @@ devDependencies: vite-plugin-minify: specifier: ^1.5.2 version: 1.5.2(vite@4.5.2) + vite-plugin-mock: + specifier: ^3.0.1 + version: 3.0.1(esbuild@0.19.12)(mockjs@1.1.0)(vite@4.5.2) ws: specifier: ^8.16.0 version: 8.16.0 @@ -176,8 +179,8 @@ packages: resolution: {integrity: sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==} engines: {node: '>=6.0.0'} dependencies: - '@jridgewell/gen-mapping': 0.3.3 - '@jridgewell/trace-mapping': 0.3.22 + '@jridgewell/gen-mapping': 0.3.4 + '@jridgewell/trace-mapping': 0.3.23 dev: true /@babel/code-frame@7.23.5: @@ -193,20 +196,20 @@ packages: engines: {node: '>=6.9.0'} dev: true - /@babel/core@7.23.7: - resolution: {integrity: sha512-+UpDgowcmqe36d4NwqvKsyPMlOLNGMsfMmQ5WGCu+siCe3t3dfe9njrzGfdN4qq+bcNUt0+Vw6haRxBOycs4dw==} + /@babel/core@7.23.9: + resolution: {integrity: sha512-5q0175NOjddqpvvzU+kDiSOAk4PfdO6FvwCWoQ6RO7rTzEe8vlo+4HVfcnAREhD4npMs0e9uZypjTwzZPCf/cw==} engines: {node: '>=6.9.0'} dependencies: '@ampproject/remapping': 2.2.1 '@babel/code-frame': 7.23.5 '@babel/generator': 7.23.6 '@babel/helper-compilation-targets': 7.23.6 - '@babel/helper-module-transforms': 7.23.3(@babel/core@7.23.7) - '@babel/helpers': 7.23.8 - '@babel/parser': 7.23.6 - '@babel/template': 7.22.15 - '@babel/traverse': 7.23.7 - '@babel/types': 7.23.6 + '@babel/helper-module-transforms': 7.23.3(@babel/core@7.23.9) + '@babel/helpers': 7.23.9 + '@babel/parser': 7.23.9 + '@babel/template': 7.23.9 + '@babel/traverse': 7.23.9 + '@babel/types': 7.23.9 convert-source-map: 2.0.0 debug: 4.3.4(supports-color@8.1.1) gensync: 1.0.0-beta.2 @@ -220,9 +223,9 @@ packages: resolution: {integrity: sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.23.6 - '@jridgewell/gen-mapping': 0.3.3 - '@jridgewell/trace-mapping': 0.3.22 + '@babel/types': 7.23.9 + '@jridgewell/gen-mapping': 0.3.4 + '@jridgewell/trace-mapping': 0.3.23 jsesc: 2.5.2 dev: true @@ -232,7 +235,7 @@ packages: dependencies: '@babel/compat-data': 7.23.5 '@babel/helper-validator-option': 7.23.5 - browserslist: 4.22.2 + browserslist: 4.23.0 lru-cache: 5.1.1 semver: 6.3.1 dev: true @@ -246,31 +249,31 @@ packages: resolution: {integrity: sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==} engines: {node: '>=6.9.0'} dependencies: - '@babel/template': 7.22.15 - '@babel/types': 7.23.6 + '@babel/template': 7.23.9 + '@babel/types': 7.23.9 dev: true /@babel/helper-hoist-variables@7.22.5: resolution: {integrity: sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.23.6 + '@babel/types': 7.23.9 dev: true /@babel/helper-module-imports@7.22.15: resolution: {integrity: sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.23.6 + '@babel/types': 7.23.9 dev: true - /@babel/helper-module-transforms@7.23.3(@babel/core@7.23.7): + /@babel/helper-module-transforms@7.23.3(@babel/core@7.23.9): resolution: {integrity: sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/core': 7.23.7 + '@babel/core': 7.23.9 '@babel/helper-environment-visitor': 7.22.20 '@babel/helper-module-imports': 7.22.15 '@babel/helper-simple-access': 7.22.5 @@ -282,14 +285,14 @@ packages: resolution: {integrity: sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.23.6 + '@babel/types': 7.23.9 dev: true /@babel/helper-split-export-declaration@7.22.6: resolution: {integrity: sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.23.6 + '@babel/types': 7.23.9 dev: true /@babel/helper-string-parser@7.23.4: @@ -307,13 +310,13 @@ packages: engines: {node: '>=6.9.0'} dev: true - /@babel/helpers@7.23.8: - resolution: {integrity: sha512-KDqYz4PiOWvDFrdHLPhKtCThtIcKVy6avWD2oG4GEvyQ+XDZwHD4YQd+H2vNMnq2rkdxsDkU82T+Vk8U/WXHRQ==} + /@babel/helpers@7.23.9: + resolution: {integrity: sha512-87ICKgU5t5SzOT7sBMfCOZQ2rHjRU+Pcb9BoILMYz600W6DkVRLFBPwQ18gwUVvggqXivaUakpnxWQGbpywbBQ==} engines: {node: '>=6.9.0'} dependencies: - '@babel/template': 7.22.15 - '@babel/traverse': 7.23.7 - '@babel/types': 7.23.6 + '@babel/template': 7.23.9 + '@babel/traverse': 7.23.9 + '@babel/types': 7.23.9 transitivePeerDependencies: - supports-color dev: true @@ -327,25 +330,25 @@ packages: js-tokens: 4.0.0 dev: true - /@babel/parser@7.23.6: - resolution: {integrity: sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ==} + /@babel/parser@7.23.9: + resolution: {integrity: sha512-9tcKgqKbs3xGJ+NtKF2ndOBBLVwPjl1SHxPQkd36r3Dlirw3xWUeGaTbqr7uGZcTaxkVNwc+03SVP7aCdWrTlA==} engines: {node: '>=6.0.0'} hasBin: true dependencies: - '@babel/types': 7.23.6 + '@babel/types': 7.23.9 dev: true - /@babel/template@7.22.15: - resolution: {integrity: sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==} + /@babel/template@7.23.9: + resolution: {integrity: sha512-+xrD2BWLpvHKNmX2QbpdpsBaWnRxahMwJjO+KZk2JOElj5nSmKezyS1B4u+QbHMTX69t4ukm6hh9lsYQ7GHCKA==} engines: {node: '>=6.9.0'} dependencies: '@babel/code-frame': 7.23.5 - '@babel/parser': 7.23.6 - '@babel/types': 7.23.6 + '@babel/parser': 7.23.9 + '@babel/types': 7.23.9 dev: true - /@babel/traverse@7.23.7: - resolution: {integrity: sha512-tY3mM8rH9jM0YHFGyfC0/xf+SB5eKUu7HPj7/k3fpi9dAlsMc5YbQvDi0Sh2QTPXqMhyaAtzAr807TIyfQrmyg==} + /@babel/traverse@7.23.9: + resolution: {integrity: sha512-I/4UJ9vs90OkBtY6iiiTORVMyIhJ4kAVmsKo9KFc8UOxMeUfi2hvtIBsET5u9GizXE6/GFSuKCTNfgCswuEjRg==} engines: {node: '>=6.9.0'} dependencies: '@babel/code-frame': 7.23.5 @@ -354,16 +357,16 @@ packages: '@babel/helper-function-name': 7.23.0 '@babel/helper-hoist-variables': 7.22.5 '@babel/helper-split-export-declaration': 7.22.6 - '@babel/parser': 7.23.6 - '@babel/types': 7.23.6 + '@babel/parser': 7.23.9 + '@babel/types': 7.23.9 debug: 4.3.4(supports-color@8.1.1) globals: 11.12.0 transitivePeerDependencies: - supports-color dev: true - /@babel/types@7.23.6: - resolution: {integrity: sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg==} + /@babel/types@7.23.9: + resolution: {integrity: sha512-dQjSq/7HaSjRM43FFGnv5keM2HsxpmyV1PfaSVm0nzzjwwTmjOe6J4bC8e3+pTEIgHaHj+1ZlLThRJ2auc/w1Q==} engines: {node: '>=6.9.0'} dependencies: '@babel/helper-string-parser': 7.23.4 @@ -447,8 +450,8 @@ packages: resolution: {integrity: sha512-YAYeJ+Xqh7fUou1d1j9XHl44BmsuThiTr4iNrgCQ3J27IbhXsxXDGZ1cXv8Qvs99d4rBbLiSKy3+WZiet32PcQ==} dev: true - /@csstools/selector-specificity@3.0.1(postcss-selector-parser@6.0.15): - resolution: {integrity: sha512-NPljRHkq4a14YzZ3YD406uaxh7s0g6eAq3L9aLOWywoqe8PkYamAvtsh7KNX6c++ihDrJ0RiU+/z7rGnhlZ5ww==} + /@csstools/selector-specificity@3.0.2(postcss-selector-parser@6.0.15): + resolution: {integrity: sha512-RpHaZ1h9LE7aALeQXmXrJkRG84ZxIsctEN2biEUmFyKpzFM3zZ35eUMcIzZFsw/2olQE6v69+esEqU2f1MKycg==} engines: {node: ^14 || ^16 || >=18} peerDependencies: postcss-selector-parser: ^6.0.13 @@ -844,7 +847,7 @@ packages: deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. hasBin: true dependencies: - '@babel/core': 7.23.7 + '@babel/core': 7.23.9 yargs: 13.3.2 transitivePeerDependencies: - supports-color @@ -856,23 +859,23 @@ packages: deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. dependencies: '@financial-times/useragent_parser': 1.6.3 - semver: 7.5.4 + semver: 7.6.0 dev: true /@financial-times/useragent_parser@1.6.3: resolution: {integrity: sha512-TlQiXt/vS5ZwY0V3salvlyQzIzMGZEyw9inmJA25A8heL2kBVENbToiEc64R6ETNf5YHa2lwnc2I7iNHP9SqeQ==} dev: true - /@floating-ui/core@1.5.3: - resolution: {integrity: sha512-O0WKDOo0yhJuugCx6trZQj5jVJ9yR0ystG2JaNAemYUWce+pmM6WUEFIibnWyEJKdrDxhm75NoSRME35FNaM/Q==} + /@floating-ui/core@1.6.0: + resolution: {integrity: sha512-PcF++MykgmTj3CIyOQbKA/hDzOAiqI3mhuoN44WRCopIs1sgoDoU4oty4Jtqaj/y3oDU6fnVSm4QG0a3t5i0+g==} dependencies: '@floating-ui/utils': 0.2.1 dev: false - /@floating-ui/dom@1.5.4: - resolution: {integrity: sha512-jByEsHIY+eEdCjnTVu+E3ephzTOzkQ8hgUfGwos+bg7NlH33Zc5uO+QHz1mrQUOgIKKDD1RtS201P9NvAfq3XQ==} + /@floating-ui/dom@1.6.3: + resolution: {integrity: sha512-RnDthu3mzPlQ31Ss/BTwQ1zjzIhr3lk1gZB1OC56h/1vEtaXkESrOqL5fQVMfXpwGtRwX+YsZBdyHtJMQnkArw==} dependencies: - '@floating-ui/core': 1.5.3 + '@floating-ui/core': 1.6.0 '@floating-ui/utils': 0.2.1 dev: false @@ -897,17 +900,17 @@ packages: engines: {node: '>=8'} dev: true - /@jridgewell/gen-mapping@0.3.3: - resolution: {integrity: sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==} + /@jridgewell/gen-mapping@0.3.4: + resolution: {integrity: sha512-Oud2QPM5dHviZNn4y/WhhYKSXksv+1xLEIsNrAbGcFzUN3ubqWRFT5gwPchNc5NuzILOU4tPBDTZ4VwhL8Y7cw==} engines: {node: '>=6.0.0'} dependencies: '@jridgewell/set-array': 1.1.2 '@jridgewell/sourcemap-codec': 1.4.15 - '@jridgewell/trace-mapping': 0.3.22 + '@jridgewell/trace-mapping': 0.3.23 dev: true - /@jridgewell/resolve-uri@3.1.1: - resolution: {integrity: sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==} + /@jridgewell/resolve-uri@3.1.2: + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} engines: {node: '>=6.0.0'} dev: true @@ -919,18 +922,18 @@ packages: /@jridgewell/source-map@0.3.5: resolution: {integrity: sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==} dependencies: - '@jridgewell/gen-mapping': 0.3.3 - '@jridgewell/trace-mapping': 0.3.22 + '@jridgewell/gen-mapping': 0.3.4 + '@jridgewell/trace-mapping': 0.3.23 dev: true /@jridgewell/sourcemap-codec@1.4.15: resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} dev: true - /@jridgewell/trace-mapping@0.3.22: - resolution: {integrity: sha512-Wf963MzWtA2sjrNt+g18IAln9lKnlRp+K2eH4jjIoF1wYeq3aMREpG09xhlhdzS0EjwU7qmUJYangWa+151vZw==} + /@jridgewell/trace-mapping@0.3.23: + resolution: {integrity: sha512-9/4foRoUKp8s96tSkh8DlAAc5A0Ty8vLXld+l9gjKKY6ckwI8G15f0hskGmuLZu78ZlGa1vtsfOa+lnB4vG6Jg==} dependencies: - '@jridgewell/resolve-uri': 3.1.1 + '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.4.15 dev: true @@ -941,27 +944,27 @@ packages: lodash: 4.17.21 dev: true - /@microsoft/api-extractor-model@7.28.6(@types/node@18.19.9): - resolution: {integrity: sha512-Jmz0PkQNvxMDpdL2Kea7GDLt5RL/nbKqI5lMkeftIfCAx9OtLqMnWHzKYBPFh/AR5GhmyLT3bJ/2Ml/ykCF8qQ==} + /@microsoft/api-extractor-model@7.28.13(@types/node@18.19.18): + resolution: {integrity: sha512-39v/JyldX4MS9uzHcdfmjjfS6cYGAoXV+io8B5a338pkHiSt+gy2eXQ0Q7cGFJ7quSa1VqqlMdlPrB6sLR/cAw==} dependencies: '@microsoft/tsdoc': 0.14.2 '@microsoft/tsdoc-config': 0.16.2 - '@rushstack/node-core-library': 3.64.1(@types/node@18.19.9) + '@rushstack/node-core-library': 4.0.2(@types/node@18.19.18) transitivePeerDependencies: - '@types/node' dev: true - /@microsoft/api-extractor@7.39.3(@types/node@18.19.9): - resolution: {integrity: sha512-Gh1NBS4Hh0fIfu8lfneaiBUq8IOm/0/yCy0t7+qq6XQEEfgVQNweCx7De0ISfhyqjL7J42qSIix4v77EWubCYg==} + /@microsoft/api-extractor@7.41.0(@types/node@18.19.18): + resolution: {integrity: sha512-Wk4fcSqO1i32FspStEm4ak+cfdo2xGsWk/K9uZoYIRQxjQH/roLU78waP+g+GhoAg5OxH63BfY37h6ISkNfQEQ==} hasBin: true dependencies: - '@microsoft/api-extractor-model': 7.28.6(@types/node@18.19.9) + '@microsoft/api-extractor-model': 7.28.13(@types/node@18.19.18) '@microsoft/tsdoc': 0.14.2 '@microsoft/tsdoc-config': 0.16.2 - '@rushstack/node-core-library': 3.64.1(@types/node@18.19.9) - '@rushstack/rig-package': 0.5.1 - '@rushstack/ts-command-line': 4.17.1 - colors: 1.2.5 + '@rushstack/node-core-library': 4.0.2(@types/node@18.19.18) + '@rushstack/rig-package': 0.5.2 + '@rushstack/terminal': 0.10.0(@types/node@18.19.18) + '@rushstack/ts-command-line': 4.17.4(@types/node@18.19.18) lodash: 4.17.21 resolve: 1.22.8 semver: 7.5.4 @@ -1002,7 +1005,7 @@ packages: engines: {node: '>= 8'} dependencies: '@nodelib/fs.scandir': 2.1.5 - fastq: 1.16.0 + fastq: 1.17.1 dev: true /@peculiar/asn1-schema@2.3.8: @@ -1072,15 +1075,15 @@ packages: picomatch: 2.3.1 dev: true - /@rushstack/node-core-library@3.64.1(@types/node@18.19.9): - resolution: {integrity: sha512-eC2OdAvH+1siC+H2gqS8QP+QWv9EUU0mfY0+84lWojl8wamYa5WIdVETIaHSc5gDlRTz4lk+sJUOoWCARpj5dw==} + /@rushstack/node-core-library@3.66.1(@types/node@18.19.18): + resolution: {integrity: sha512-ker69cVKAoar7MMtDFZC4CzcDxjwqIhFzqEnYI5NRN/8M3om6saWCVx/A7vL2t/jFCJsnzQplRDqA7c78pytng==} peerDependencies: '@types/node': '*' peerDependenciesMeta: '@types/node': optional: true dependencies: - '@types/node': 18.19.9 + '@types/node': 18.19.18 colors: 1.2.5 fs-extra: 7.0.1 import-lazy: 4.0.0 @@ -1090,59 +1093,91 @@ packages: z-schema: 5.0.5 dev: true - /@rushstack/rig-package@0.5.1: - resolution: {integrity: sha512-pXRYSe29TjRw7rqxD4WS3HN/sRSbfr+tJs4a9uuaSIBAITbUggygdhuG0VrO0EO+QqH91GhYMN4S6KRtOEmGVA==} + /@rushstack/node-core-library@4.0.2(@types/node@18.19.18): + resolution: {integrity: sha512-hyES82QVpkfQMeBMteQUnrhASL/KHPhd7iJ8euduwNJG4mu2GSOKybf0rOEjOm1Wz7CwJEUm9y0yD7jg2C1bfg==} + peerDependencies: + '@types/node': '*' + peerDependenciesMeta: + '@types/node': + optional: true + dependencies: + '@types/node': 18.19.18 + fs-extra: 7.0.1 + import-lazy: 4.0.0 + jju: 1.4.0 + resolve: 1.22.8 + semver: 7.5.4 + z-schema: 5.0.5 + dev: true + + /@rushstack/rig-package@0.5.2: + resolution: {integrity: sha512-mUDecIJeH3yYGZs2a48k+pbhM6JYwWlgjs2Ca5f2n1G2/kgdgP9D/07oglEGf6mRyXEnazhEENeYTSNDRCwdqA==} dependencies: resolve: 1.22.8 strip-json-comments: 3.1.1 dev: true - /@rushstack/ts-command-line@4.17.1: - resolution: {integrity: sha512-2jweO1O57BYP5qdBGl6apJLB+aRIn5ccIRTPDyULh0KMwVzFqWtw6IZWt1qtUoZD/pD2RNkIOosH6Cq45rIYeg==} + /@rushstack/terminal@0.10.0(@types/node@18.19.18): + resolution: {integrity: sha512-UbELbXnUdc7EKwfH2sb8ChqNgapUOdqcCIdQP4NGxBpTZV2sQyeekuK3zmfQSa/MN+/7b4kBogl2wq0vpkpYGw==} + peerDependencies: + '@types/node': '*' + peerDependenciesMeta: + '@types/node': + optional: true + dependencies: + '@rushstack/node-core-library': 4.0.2(@types/node@18.19.18) + '@types/node': 18.19.18 + supports-color: 8.1.1 + dev: true + + /@rushstack/ts-command-line@4.17.4(@types/node@18.19.18): + resolution: {integrity: sha512-XPQQDaxgFqRHFRgt7jjCKnr0vrC75s/+ISU6kGhWpDlGzWl4vig6ZfZTs3HgM6Kh1Bb3wUKSyKQOV+G36cyZfg==} dependencies: + '@rushstack/terminal': 0.10.0(@types/node@18.19.18) '@types/argparse': 1.0.38 argparse: 1.0.10 - colors: 1.2.5 string-argv: 0.3.2 + transitivePeerDependencies: + - '@types/node' dev: true - /@sentry-internal/tracing@7.95.0: - resolution: {integrity: sha512-YKiLPMnEgTsTh7u/W1Zep9HtV1rJqAetqJ4ekaIxyUUB6ppi6V00MacSjb01o++fwlNNDYFxNpJlgQqNPqsCNA==} + /@sentry-internal/tracing@7.102.1: + resolution: {integrity: sha512-RkFlFyAC0fQOvBbBqnq0CLmFW5m3JJz9pKbZd5vXPraWAlniKSb1bC/4DF9SlNx0FN1LWG+IU3ISdpzwwTeAGg==} engines: {node: '>=8'} dependencies: - '@sentry/core': 7.95.0 - '@sentry/types': 7.95.0 - '@sentry/utils': 7.95.0 + '@sentry/core': 7.102.1 + '@sentry/types': 7.102.1 + '@sentry/utils': 7.102.1 dev: true - /@sentry/core@7.95.0: - resolution: {integrity: sha512-z+ffO6jK/ZUxnRbBGmnj5sOouKZ4mvRY0KJa33kbyqcmeiJKrN81M7Ecj1IJUCamo/6RqX0GCwDDxgUPZZZBwA==} + /@sentry/core@7.102.1: + resolution: {integrity: sha512-QjY+LSP3du3J/C8x/FfEbRxgZgsWd0jfTJ4P7s9f219I1csK4OeBMC3UA1HwEa0pY/9OF6H/egW2CjOcMM5Pdg==} engines: {node: '>=8'} dependencies: - '@sentry/types': 7.95.0 - '@sentry/utils': 7.95.0 + '@sentry/types': 7.102.1 + '@sentry/utils': 7.102.1 dev: true - /@sentry/node@7.95.0: - resolution: {integrity: sha512-3fbN+4ajPly9rhbuJtuZ+o2FGmka8Y7A3T/ooHuhCGoWegKtn3OzaOIrdwcYoBIy1fO6SuldTi/P72Y7wgIPtw==} + /@sentry/node@7.102.1: + resolution: {integrity: sha512-mb3vmM3SGuCruckPiv/Vafeh89UQavTfpPFoU6Jwe6dSpQ39BO8fO8k8Zev+/nP6r/FKLtX17mJobErHECXsYw==} engines: {node: '>=8'} dependencies: - '@sentry-internal/tracing': 7.95.0 - '@sentry/core': 7.95.0 - '@sentry/types': 7.95.0 - '@sentry/utils': 7.95.0 + '@sentry-internal/tracing': 7.102.1 + '@sentry/core': 7.102.1 + '@sentry/types': 7.102.1 + '@sentry/utils': 7.102.1 dev: true - /@sentry/types@7.95.0: - resolution: {integrity: sha512-ouU7NsEcrwmcnXHMNBGmKZEmKMzmgPGoBydZn1gukCI67Ci71fAYpPNrbtmjai6+jtsY21o45rVLqExru2sdfw==} + /@sentry/types@7.102.1: + resolution: {integrity: sha512-htKorf3t/D0XYtM7foTcmG+rM47rDP6XdbvCcX5gBCuCYlzpM1vqCt2rl3FLktZC6TaIpFRJw1TLfx6m+x5jdA==} engines: {node: '>=8'} dev: true - /@sentry/utils@7.95.0: - resolution: {integrity: sha512-0zget8AOaQWLIEA9cTx/qiQQYpx2x0UfnaW5xRmQg12QGTSngo/cUm9O04zuHw5gpBBGG0ocMDHxwwr+UCCBiw==} + /@sentry/utils@7.102.1: + resolution: {integrity: sha512-+8WcFjHVV/HROXSAwMuUzveElBFC43EiTG7SNEBNgOUeQzQVTmbUZXyTVgLrUmtoWqvnIxCacoLxtZo1o67kdg==} engines: {node: '>=8'} dependencies: - '@sentry/types': 7.95.0 + '@sentry/types': 7.102.1 dev: true /@sinonjs/commons@2.0.0: @@ -1229,13 +1264,17 @@ packages: resolution: {integrity: sha512-6L6VymKTzYSrEf4Nev4Xa1LCHKrlTlYCBMTlQKFuddo1CvQcE52I0mwfOJayueUC7MJuXOeHTcIU683lzd0cUA==} dev: true - /@types/node@18.19.9: - resolution: {integrity: sha512-oZFKlC8l5YtzGQNT4zC2PiSSKzQVZ8bAwwd+EYdPLtyk0nSEq6O16SkK+rkkT2eflDAbormJgEF3QnH3oDrTSw==} + /@types/mockjs@1.0.10: + resolution: {integrity: sha512-SXgrhajHG7boLv6oU93CcmdDm0HYRiceuz6b+7z+/2lCJPTWDv0V5YiwFHT2ejE4bQqgSXQiVPQYPWv7LGsK1g==} + dev: true + + /@types/node@18.19.18: + resolution: {integrity: sha512-80CP7B8y4PzZF0GWx15/gVWRrB5y/bIjNI84NK3cmQJu0WZwvmj2WMA5LcofQFVfLqqCSp545+U2LsrVzX36Zg==} dependencies: undici-types: 5.26.5 - /@types/node@20.11.6: - resolution: {integrity: sha512-+EOokTnksGVgip2PbYbr3xnR7kZigh4LbybAfBAw5BpnQ+FqBYUsvCEjYd70IXKlbohQ64mzEYmMtlWUY8q//Q==} + /@types/node@20.11.20: + resolution: {integrity: sha512-7/rR21OS+fq8IyHTgtLkDK949uzsa6n8BkziAKtPVpugIkO6D+/ooXMvzXxDnZrmtXVfjb1bKQafYpb8s89LOg==} dependencies: undici-types: 5.26.5 dev: true @@ -1244,16 +1283,16 @@ packages: resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==} requiresBuild: true dependencies: - '@types/node': 20.11.6 + '@types/node': 20.11.20 dev: true optional: true /@wesbos/code-icons@1.2.4: resolution: {integrity: sha512-ZiU0xf7epnCRrLDQIPnFstzoNWDvcUTtKoDU3VhpjsaGRzVClSmsi39c4kHxIOdfxvg4zwdW+goH96xr/vMTQQ==} dependencies: - '@types/node': 18.19.9 - vite: 4.5.2(@types/node@18.19.9) - vite-plugin-dts: 1.7.3(@types/node@18.19.9)(vite@4.5.2) + '@types/node': 18.19.18 + vite: 4.5.2(@types/node@18.19.18) + vite-plugin-dts: 1.7.3(@types/node@18.19.18)(vite@4.5.2) vscode-icons-js: 11.6.1 transitivePeerDependencies: - less @@ -1445,25 +1484,27 @@ packages: engines: {node: '>= 4.0.0'} dev: true - /autoprefixer@10.4.17(postcss@8.4.33): + /autoprefixer@10.4.17(postcss@8.4.35): resolution: {integrity: sha512-/cpVNRLSfhOtcGflT13P2794gVSgmPgTR+erw5ifnMLZb0UnSlkK4tquLmkd3BhA+nLo5tX8Cu0upUsGKvKbmg==} engines: {node: ^10 || ^12 || >=14} hasBin: true peerDependencies: postcss: ^8.1.0 dependencies: - browserslist: 4.22.2 - caniuse-lite: 1.0.30001579 + browserslist: 4.23.0 + caniuse-lite: 1.0.30001589 fraction.js: 4.3.7 normalize-range: 0.1.2 picocolors: 1.0.0 - postcss: 8.4.33 + postcss: 8.4.35 postcss-value-parser: 4.2.0 dev: true - /available-typed-arrays@1.0.5: - resolution: {integrity: sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==} + /available-typed-arrays@1.0.7: + resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} engines: {node: '>= 0.4'} + dependencies: + possible-typed-array-names: 1.0.0 dev: true /aws-sign2@0.7.0: @@ -1478,8 +1519,8 @@ packages: dev: true optional: true - /b4a@1.6.4: - resolution: {integrity: sha512-fpWrvyVHEKyeEvbKZTVOeZF3VSKKWtJxFIxX/jaVPf+cLbGUSitjb49pHLqPV2BUNNZ0LcoeEGfE/YCpyDYHIw==} + /b4a@1.6.6: + resolution: {integrity: sha512-5Tk1HLk6b6ctmjIkAcU/Ujv/1WqiDl0F0JdRCR80VsOcUlHcu7pWeWRlOqQLHfDEsVx9YH/aif5AG4ehoCtTmg==} dev: true /babel-code-frame@6.26.0: @@ -1561,6 +1602,12 @@ packages: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} dev: true + /bare-events@2.2.0: + resolution: {integrity: sha512-Yyyqff4PIFfSuthCZqLlPISTWHmnQxoPuAvkmgzsJEmG3CesdIv6Xweayl0JkCZJSB2yYIdJyEz97tpxNhgjbg==} + requiresBuild: true + dev: true + optional: true + /base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} dev: true @@ -1619,15 +1666,15 @@ packages: resolution: {integrity: sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==} dev: true - /browserslist@4.22.2: - resolution: {integrity: sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==} + /browserslist@4.23.0: + resolution: {integrity: sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true dependencies: - caniuse-lite: 1.0.30001579 - electron-to-chromium: 1.4.643 + caniuse-lite: 1.0.30001589 + electron-to-chromium: 1.4.681 node-releases: 2.0.14 - update-browserslist-db: 1.0.13(browserslist@4.22.2) + update-browserslist-db: 1.0.13(browserslist@4.23.0) dev: true /btoa@1.2.1: @@ -1651,6 +1698,16 @@ packages: ieee754: 1.2.1 dev: true + /bundle-require@4.0.2(esbuild@0.19.12): + resolution: {integrity: sha512-jwzPOChofl67PSTW2SGubV9HBQAhhR2i6nskiOThauo9dzwDUgOWQScFVaJkjEfYX+UXiD+LEx8EblQMc2wIag==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + peerDependencies: + esbuild: '>=0.17' + dependencies: + esbuild: 0.19.12 + load-tsconfig: 0.2.5 + dev: true + /c8@8.0.1: resolution: {integrity: sha512-EINpopxZNH1mETuI0DzRA4MZpAUH+IFiRhnmFD3vFr3vdrgxqi3VfE3KL0AIL+zDq8rC9bZqwM/VDmmoe04y7w==} engines: {node: '>=12'} @@ -1662,7 +1719,7 @@ packages: foreground-child: 2.0.0 istanbul-lib-coverage: 3.2.2 istanbul-lib-report: 3.0.1 - istanbul-reports: 3.1.6 + istanbul-reports: 3.1.7 rimraf: 3.0.2 test-exclude: 6.0.0 v8-to-istanbul: 9.2.0 @@ -1670,12 +1727,15 @@ packages: yargs-parser: 21.1.1 dev: true - /call-bind@1.0.5: - resolution: {integrity: sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==} + /call-bind@1.0.7: + resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==} + engines: {node: '>= 0.4'} dependencies: + es-define-property: 1.0.0 + es-errors: 1.3.0 function-bind: 1.1.2 - get-intrinsic: 1.2.2 - set-function-length: 1.2.0 + get-intrinsic: 1.2.4 + set-function-length: 1.2.1 dev: true /callsites@3.1.0: @@ -1708,14 +1768,14 @@ packages: /caniuse-api@3.0.0: resolution: {integrity: sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==} dependencies: - browserslist: 4.22.2 - caniuse-lite: 1.0.30001579 + browserslist: 4.23.0 + caniuse-lite: 1.0.30001589 lodash.memoize: 4.1.2 lodash.uniq: 4.5.0 dev: true - /caniuse-lite@1.0.30001579: - resolution: {integrity: sha512-u5AUVkixruKHJjw/pj9wISlcMpgFWzSrczLZbrqBSxukQixmg0SJ5sZTpvaFvxU0HoQKd4yoyAogyrAz9pzJnA==} + /caniuse-lite@1.0.30001589: + resolution: {integrity: sha512-vNQWS6kI+q6sBlHbh71IIeC+sRwK2N3EDySc/updIGhIee2x5z00J4c1242/5/d6EpEMdOnk/m+6tuk4/tcsqg==} dev: true /caseless@0.12.0: @@ -1849,14 +1909,29 @@ packages: fsevents: 2.3.3 dev: true - /chromium-bidi@0.5.4(devtools-protocol@0.0.1232444): - resolution: {integrity: sha512-p9CdiHl0xNh4P7oVa44zXgJJw+pvnHXFDB+tVdo25xaPLgQDVf2kQO+TDxD2fp2Evqi7vs/vGRINMzl1qJrWiw==} + /chokidar@3.6.0: + resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} + engines: {node: '>= 8.10.0'} + dependencies: + anymatch: 3.1.3 + braces: 3.0.2 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.3 + dev: true + + /chromium-bidi@0.5.8(devtools-protocol@0.0.1232444): + resolution: {integrity: sha512-blqh+1cEQbHBKmok3rVJkBlBxt9beKBgOsxbFgs7UJcoVbbeZ+K7+6liAsjgpc8l1Xd55cQUy14fXZdGSb4zIw==} peerDependencies: devtools-protocol: '*' dependencies: devtools-protocol: 0.0.1232444 mitt: 3.0.1 - urlpattern-polyfill: 9.0.0 + urlpattern-polyfill: 10.0.0 dev: true /clean-css@5.3.3: @@ -1959,6 +2034,11 @@ packages: engines: {node: '>=14'} dev: true + /commander@12.0.0: + resolution: {integrity: sha512-MwVNWlYjDTtOjX5PiD7o5pK0UrFU/OYgcJfjjK4RaHZETNtjJqrZa9Y9ds88+A+f+d5lv+561eZ+yCKoS3gbAA==} + engines: {node: '>=18'} + dev: true + /commander@2.20.3: resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} dev: true @@ -1982,6 +2062,18 @@ packages: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} dev: true + /connect@3.7.0: + resolution: {integrity: sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==} + engines: {node: '>= 0.10.0'} + dependencies: + debug: 2.6.9 + finalhandler: 1.1.2 + parseurl: 1.3.3 + utils-merge: 1.0.1 + transitivePeerDependencies: + - supports-color + dev: true + /convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} dev: true @@ -2021,13 +2113,13 @@ packages: resolution: {integrity: sha512-cJCreaZcaGhyLEn3L+LZpX4PVH4o/7+M84+G0Nd1eO4m9ltPgsn2b7Xanfi7+fRy4bU82hmvCcOcPhRb8ZlFcg==} hasBin: true dependencies: - '@babel/core': 7.23.7 + '@babel/core': 7.23.9 '@financial-times/js-features-analyser': 0.4.3 - browserslist: 4.22.2 + browserslist: 4.23.0 execa: 7.2.0 polyfill-library: 4.8.0 - semver: 7.5.4 - snyk: 1.1274.0 + semver: 7.6.0 + snyk: 1.1280.1 yargs: 17.7.2 transitivePeerDependencies: - supports-color @@ -2054,13 +2146,13 @@ packages: resolution: {integrity: sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==} dev: true - /css-declaration-sorter@7.1.1(postcss@8.4.33): + /css-declaration-sorter@7.1.1(postcss@8.4.35): resolution: {integrity: sha512-dZ3bVTEEc1vxr3Bek9vGwfB5Z6ESPULhcRvO472mfjVnj8jRcTnKO8/JTczlvxM10Myb+wBM++1MtdO76eWcaQ==} engines: {node: ^14 || ^16 || >=18} peerDependencies: postcss: ^8.0.9 dependencies: - postcss: 8.4.33 + postcss: 8.4.35 dev: true /css-select@1.2.0: @@ -2113,62 +2205,62 @@ packages: hasBin: true dev: true - /cssnano-preset-default@6.0.3(postcss@8.4.33): - resolution: {integrity: sha512-4y3H370aZCkT9Ev8P4SO4bZbt+AExeKhh8wTbms/X7OLDo5E7AYUUy6YPxa/uF5Grf+AJwNcCnxKhZynJ6luBA==} + /cssnano-preset-default@6.0.5(postcss@8.4.35): + resolution: {integrity: sha512-M+qRDEr5QZrfNl0B2ySdbTLGyNb8kBcSjuwR7WBamYBOEREH9t2efnB/nblekqhdGLZdkf4oZNetykG2JWRdZQ==} engines: {node: ^14 || ^16 || >=18.0} peerDependencies: postcss: ^8.4.31 dependencies: - css-declaration-sorter: 7.1.1(postcss@8.4.33) - cssnano-utils: 4.0.1(postcss@8.4.33) - postcss: 8.4.33 - postcss-calc: 9.0.1(postcss@8.4.33) - postcss-colormin: 6.0.2(postcss@8.4.33) - postcss-convert-values: 6.0.2(postcss@8.4.33) - postcss-discard-comments: 6.0.1(postcss@8.4.33) - postcss-discard-duplicates: 6.0.1(postcss@8.4.33) - postcss-discard-empty: 6.0.1(postcss@8.4.33) - postcss-discard-overridden: 6.0.1(postcss@8.4.33) - postcss-merge-longhand: 6.0.2(postcss@8.4.33) - postcss-merge-rules: 6.0.3(postcss@8.4.33) - postcss-minify-font-values: 6.0.1(postcss@8.4.33) - postcss-minify-gradients: 6.0.1(postcss@8.4.33) - postcss-minify-params: 6.0.2(postcss@8.4.33) - postcss-minify-selectors: 6.0.2(postcss@8.4.33) - postcss-normalize-charset: 6.0.1(postcss@8.4.33) - postcss-normalize-display-values: 6.0.1(postcss@8.4.33) - postcss-normalize-positions: 6.0.1(postcss@8.4.33) - postcss-normalize-repeat-style: 6.0.1(postcss@8.4.33) - postcss-normalize-string: 6.0.1(postcss@8.4.33) - postcss-normalize-timing-functions: 6.0.1(postcss@8.4.33) - postcss-normalize-unicode: 6.0.2(postcss@8.4.33) - postcss-normalize-url: 6.0.1(postcss@8.4.33) - postcss-normalize-whitespace: 6.0.1(postcss@8.4.33) - postcss-ordered-values: 6.0.1(postcss@8.4.33) - postcss-reduce-initial: 6.0.2(postcss@8.4.33) - postcss-reduce-transforms: 6.0.1(postcss@8.4.33) - postcss-svgo: 6.0.2(postcss@8.4.33) - postcss-unique-selectors: 6.0.2(postcss@8.4.33) - dev: true - - /cssnano-utils@4.0.1(postcss@8.4.33): + css-declaration-sorter: 7.1.1(postcss@8.4.35) + cssnano-utils: 4.0.1(postcss@8.4.35) + postcss: 8.4.35 + postcss-calc: 9.0.1(postcss@8.4.35) + postcss-colormin: 6.0.3(postcss@8.4.35) + postcss-convert-values: 6.0.4(postcss@8.4.35) + postcss-discard-comments: 6.0.1(postcss@8.4.35) + postcss-discard-duplicates: 6.0.2(postcss@8.4.35) + postcss-discard-empty: 6.0.2(postcss@8.4.35) + postcss-discard-overridden: 6.0.1(postcss@8.4.35) + postcss-merge-longhand: 6.0.3(postcss@8.4.35) + postcss-merge-rules: 6.0.4(postcss@8.4.35) + postcss-minify-font-values: 6.0.2(postcss@8.4.35) + postcss-minify-gradients: 6.0.2(postcss@8.4.35) + postcss-minify-params: 6.0.3(postcss@8.4.35) + postcss-minify-selectors: 6.0.2(postcss@8.4.35) + postcss-normalize-charset: 6.0.1(postcss@8.4.35) + postcss-normalize-display-values: 6.0.1(postcss@8.4.35) + postcss-normalize-positions: 6.0.1(postcss@8.4.35) + postcss-normalize-repeat-style: 6.0.1(postcss@8.4.35) + postcss-normalize-string: 6.0.1(postcss@8.4.35) + postcss-normalize-timing-functions: 6.0.1(postcss@8.4.35) + postcss-normalize-unicode: 6.0.3(postcss@8.4.35) + postcss-normalize-url: 6.0.1(postcss@8.4.35) + postcss-normalize-whitespace: 6.0.1(postcss@8.4.35) + postcss-ordered-values: 6.0.1(postcss@8.4.35) + postcss-reduce-initial: 6.0.3(postcss@8.4.35) + postcss-reduce-transforms: 6.0.1(postcss@8.4.35) + postcss-svgo: 6.0.2(postcss@8.4.35) + postcss-unique-selectors: 6.0.2(postcss@8.4.35) + dev: true + + /cssnano-utils@4.0.1(postcss@8.4.35): resolution: {integrity: sha512-6qQuYDqsGoiXssZ3zct6dcMxiqfT6epy7x4R0TQJadd4LWO3sPR6JH6ZByOvVLoZ6EdwPGgd7+DR1EmX3tiXQQ==} engines: {node: ^14 || ^16 || >=18.0} peerDependencies: postcss: ^8.4.31 dependencies: - postcss: 8.4.33 + postcss: 8.4.35 dev: true - /cssnano@6.0.3(postcss@8.4.33): - resolution: {integrity: sha512-MRq4CIj8pnyZpcI2qs6wswoYoDD1t0aL28n+41c1Ukcpm56m1h6mCexIHBGjfZfnTqtGSSCP4/fB1ovxgjBOiw==} + /cssnano@6.0.5(postcss@8.4.35): + resolution: {integrity: sha512-tpTp/ukgrElwu3ESFY4IvWnGn8eTt8cJhC2aAbtA3lvUlxp6t6UPv8YCLjNnEGiFreT1O0LiOM1U3QyTBVFl2A==} engines: {node: ^14 || ^16 || >=18.0} peerDependencies: postcss: ^8.4.31 dependencies: - cssnano-preset-default: 6.0.3(postcss@8.4.33) - lilconfig: 3.0.0 - postcss: 8.4.33 + cssnano-preset-default: 6.0.5(postcss@8.4.35) + lilconfig: 3.1.1 + postcss: 8.4.35 dev: true /csso@5.0.5: @@ -2213,8 +2305,8 @@ packages: engines: {node: '>= 12'} dev: true - /data-uri-to-buffer@6.0.1: - resolution: {integrity: sha512-MZd3VlchQkp8rdend6vrx7MmVDJzSNTBvghvKjirLkD+WTChA3KUf0jkE68Q4UyctNqI11zZO9/x2Yx+ub5Cvg==} + /data-uri-to-buffer@6.0.2: + resolution: {integrity: sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==} engines: {node: '>= 14'} dev: true @@ -2278,21 +2370,21 @@ packages: dev: true optional: true - /define-data-property@1.1.1: - resolution: {integrity: sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==} + /define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} engines: {node: '>= 0.4'} dependencies: - get-intrinsic: 1.2.2 + es-define-property: 1.0.0 + es-errors: 1.3.0 gopd: 1.0.1 - has-property-descriptors: 1.0.1 dev: true /define-properties@1.2.1: resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} engines: {node: '>= 0.4'} dependencies: - define-data-property: 1.1.1 - has-property-descriptors: 1.0.1 + define-data-property: 1.1.4 + has-property-descriptors: 1.0.2 object-keys: 1.1.1 dev: true @@ -2340,8 +2432,8 @@ packages: engines: {node: '>=0.3.1'} dev: true - /diff@5.1.0: - resolution: {integrity: sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==} + /diff@5.2.0: + resolution: {integrity: sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==} engines: {node: '>=0.3.1'} dev: true @@ -2448,8 +2540,12 @@ packages: dev: true optional: true - /electron-to-chromium@1.4.643: - resolution: {integrity: sha512-QHscvvS7gt155PtoRC0dR2ilhL8E9LHhfTQEq1uD5AL0524rBLAwpAREFH06f87/e45B9XkR6Ki5dbhbCsVEIg==} + /ee-first@1.1.1: + resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} + dev: true + + /electron-to-chromium@1.4.681: + resolution: {integrity: sha512-1PpuqJUFWoXZ1E54m8bsLPVYwIVCRzvaL+n5cjigGga4z854abDnFRc+cTa2th4S79kyGqya/1xoR7h+Y5G5lg==} dev: true /element-internals-polyfill@1.3.10: @@ -2468,6 +2564,11 @@ packages: resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} dev: true + /encodeurl@1.0.2: + resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==} + engines: {node: '>= 0.8'} + dev: true + /end-of-stream@1.4.4: resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} dependencies: @@ -2502,6 +2603,18 @@ packages: is-arrayish: 0.2.1 dev: true + /es-define-property@1.0.0: + resolution: {integrity: sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==} + engines: {node: '>= 0.4'} + dependencies: + get-intrinsic: 1.2.4 + dev: true + + /es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + dev: true + /es6-error@4.1.1: resolution: {integrity: sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==} dev: true @@ -2566,8 +2679,8 @@ packages: '@esbuild/win32-x64': 0.19.12 dev: true - /escalade@3.1.1: - resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} + /escalade@3.1.2: + resolution: {integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==} engines: {node: '>=6'} dev: true @@ -2763,7 +2876,7 @@ packages: human-signals: 4.3.1 is-stream: 3.0.0 merge-stream: 2.0.0 - npm-run-path: 5.2.0 + npm-run-path: 5.3.0 onetime: 6.0.0 signal-exit: 3.0.7 strip-final-newline: 3.0.0 @@ -2827,8 +2940,8 @@ packages: dev: true optional: true - /fastq@1.16.0: - resolution: {integrity: sha512-ifCoaXsDrsdkWTtiNJX5uzHDsrck5TzfKKDcuFFTIrrc/BS076qgEIfoIy1VeZqViznfKiysPYTh/QeHtnIsYA==} + /fastq@1.17.1: + resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} dependencies: reusify: 1.0.4 dev: true @@ -2844,7 +2957,7 @@ packages: engines: {node: ^12.20 || >= 14.13} dependencies: node-domexception: 1.0.0 - web-streams-polyfill: 3.3.2 + web-streams-polyfill: 3.3.3 dev: true /fill-range@7.0.1: @@ -2854,6 +2967,21 @@ packages: to-regex-range: 5.0.1 dev: true + /finalhandler@1.1.2: + resolution: {integrity: sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==} + engines: {node: '>= 0.8'} + dependencies: + debug: 2.6.9 + encodeurl: 1.0.2 + escape-html: 1.0.3 + on-finished: 2.3.0 + parseurl: 1.3.3 + statuses: 1.5.0 + unpipe: 1.0.0 + transitivePeerDependencies: + - supports-color + dev: true + /find-up@3.0.0: resolution: {integrity: sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==} engines: {node: '>=6'} @@ -2969,25 +3097,25 @@ packages: universalify: 2.0.1 dev: true - /fs-extra@5.0.0: - resolution: {integrity: sha512-66Pm4RYbjzdyeuqudYqhFiNBbCIuI9kgRqLPSHIlXHidW8NIQtVdkM1yeZ4lXwuhbTETv3EUGMNHAAw6hiundQ==} + /fs-extra@11.2.0: + resolution: {integrity: sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==} + engines: {node: '>=14.14'} dependencies: graceful-fs: 4.2.11 - jsonfile: 4.0.0 - universalify: 0.1.2 + jsonfile: 6.1.0 + universalify: 2.0.1 dev: true - /fs-extra@7.0.1: - resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==} - engines: {node: '>=6 <7 || >=8'} + /fs-extra@5.0.0: + resolution: {integrity: sha512-66Pm4RYbjzdyeuqudYqhFiNBbCIuI9kgRqLPSHIlXHidW8NIQtVdkM1yeZ4lXwuhbTETv3EUGMNHAAw6hiundQ==} dependencies: graceful-fs: 4.2.11 jsonfile: 4.0.0 universalify: 0.1.2 dev: true - /fs-extra@8.1.0: - resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==} + /fs-extra@7.0.1: + resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==} engines: {node: '>=6 <7 || >=8'} dependencies: graceful-fs: 4.2.11 @@ -3038,13 +3166,15 @@ packages: resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==} dev: true - /get-intrinsic@1.2.2: - resolution: {integrity: sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==} + /get-intrinsic@1.2.4: + resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==} + engines: {node: '>= 0.4'} dependencies: + es-errors: 1.3.0 function-bind: 1.1.2 - has-proto: 1.0.1 + has-proto: 1.0.3 has-symbols: 1.0.3 - hasown: 2.0.0 + hasown: 2.0.1 dev: true /get-stdin@4.0.1: @@ -3064,14 +3194,14 @@ packages: engines: {node: '>=10'} dev: true - /get-uri@6.0.2: - resolution: {integrity: sha512-5KLucCJobh8vBY1K07EFV4+cPZH3mrV9YeAruUseCQKHB58SGjjT2l9/eA9LD082IiuMjSlFJEcdJ27TXvbZNw==} + /get-uri@6.0.3: + resolution: {integrity: sha512-BzUrJBS9EcUb4cFol8r4W3v1cPsSyajLSthNkz5BxbpDcHN5tIrM10E2eNvfnvBn3DaT3DUgx0OpsBKkaOpanw==} engines: {node: '>= 14'} dependencies: basic-ftp: 5.0.4 - data-uri-to-buffer: 6.0.1 + data-uri-to-buffer: 6.0.2 debug: 4.3.4(supports-color@8.1.1) - fs-extra: 8.1.0 + fs-extra: 11.2.0 transitivePeerDependencies: - supports-color dev: true @@ -3103,8 +3233,8 @@ packages: path-scurry: 1.10.1 dev: true - /glob@7.2.0: - resolution: {integrity: sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==} + /glob@7.2.3: + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} dependencies: fs.realpath: 1.0.0 inflight: 1.0.6 @@ -3114,15 +3244,15 @@ packages: path-is-absolute: 1.0.1 dev: true - /glob@7.2.3: - resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + /glob@8.1.0: + resolution: {integrity: sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==} + engines: {node: '>=12'} dependencies: fs.realpath: 1.0.0 inflight: 1.0.6 inherits: 2.0.4 - minimatch: 3.1.2 + minimatch: 5.0.1 once: 1.4.0 - path-is-absolute: 1.0.1 dev: true /global-agent@3.0.0: @@ -3133,7 +3263,7 @@ packages: es6-error: 4.1.1 matcher: 3.0.0 roarr: 2.15.4 - semver: 7.5.4 + semver: 7.6.0 serialize-error: 7.0.1 dev: true @@ -3157,7 +3287,7 @@ packages: /gopd@1.0.1: resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} dependencies: - get-intrinsic: 1.2.2 + get-intrinsic: 1.2.4 dev: true /graceful-fs@4.2.11: @@ -3211,14 +3341,14 @@ packages: engines: {node: '>=8'} dev: true - /has-property-descriptors@1.0.1: - resolution: {integrity: sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==} + /has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} dependencies: - get-intrinsic: 1.2.2 + es-define-property: 1.0.0 dev: true - /has-proto@1.0.1: - resolution: {integrity: sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==} + /has-proto@1.0.3: + resolution: {integrity: sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==} engines: {node: '>= 0.4'} dev: true @@ -3227,15 +3357,15 @@ packages: engines: {node: '>= 0.4'} dev: true - /has-tostringtag@1.0.0: - resolution: {integrity: sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==} + /has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} engines: {node: '>= 0.4'} dependencies: has-symbols: 1.0.3 dev: true - /hasown@2.0.0: - resolution: {integrity: sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==} + /hasown@2.0.1: + resolution: {integrity: sha512-1/th4MHjnwncwXsIW6QMzlvYL9kG5e/CpVvLRZe4XPa8TOUNbCELqmvhDmnkNsAjwaG4+I8gJJL0JBvTTLO9qA==} engines: {node: '>= 0.4'} dependencies: function-bind: 1.1.2 @@ -3268,7 +3398,7 @@ packages: he: 1.2.0 param-case: 3.0.4 relateurl: 0.2.7 - terser: 5.27.0 + terser: 5.28.1 dev: true /html-minifier-terser@7.2.0: @@ -3282,7 +3412,7 @@ packages: entities: 4.5.0 param-case: 3.0.4 relateurl: 0.2.7 - terser: 5.27.0 + terser: 5.28.1 dev: true /htmlparser2@3.10.1: @@ -3317,8 +3447,8 @@ packages: - supports-color dev: true - /http-proxy-agent@7.0.0: - resolution: {integrity: sha512-+ZT+iBxVUQ1asugqnD6oWoRiS25AkjNfG085dKJGtGxkdwLQrMKU5wJr2bOOFAXzKcTuqq+7fZlTMgG3SRfIYQ==} + /http-proxy-agent@7.0.2: + resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==} engines: {node: '>= 14'} dependencies: agent-base: 7.1.0 @@ -3348,8 +3478,8 @@ packages: - supports-color dev: true - /https-proxy-agent@7.0.2: - resolution: {integrity: sha512-NmLNjm6ucYwtcUmL7JQC1ZQ57LmHP4lT15FQ8D61nak1rO6DH+fz5qNK2Ap5UN4ZapYICE3/0KodcLYSPsPbaA==} + /https-proxy-agent@7.0.4: + resolution: {integrity: sha512-wlwpilI7YdjSkWaQ/7omYBMTliDcmCN8OLihO6I9B86g06lMyAoqgoDpV0XqoaPOKj+0DIdAvnsWfyAAhmimcg==} engines: {node: '>= 14'} dependencies: agent-base: 7.1.0 @@ -3411,20 +3541,20 @@ packages: loose-envify: 1.4.0 dev: true - /ip@1.1.8: - resolution: {integrity: sha512-PuExPYUiu6qMBQb4l06ecm6T6ujzhmh+MeJcW9wa89PoAz5pvd4zPgN5WJV104mb6S2T1AwNIAaB70JNrLQWhg==} - dev: true - - /ip@2.0.0: - resolution: {integrity: sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==} + /ip-address@9.0.5: + resolution: {integrity: sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==} + engines: {node: '>= 12'} + dependencies: + jsbn: 1.1.0 + sprintf-js: 1.1.3 dev: true /is-arguments@1.1.1: resolution: {integrity: sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.5 - has-tostringtag: 1.0.0 + call-bind: 1.0.7 + has-tostringtag: 1.0.2 dev: true /is-arrayish@0.2.1: @@ -3446,7 +3576,7 @@ packages: /is-core-module@2.13.1: resolution: {integrity: sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==} dependencies: - hasown: 2.0.0 + hasown: 2.0.1 dev: true /is-extglob@2.1.1: @@ -3473,7 +3603,7 @@ packages: resolution: {integrity: sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==} engines: {node: '>= 0.4'} dependencies: - has-tostringtag: 1.0.0 + has-tostringtag: 1.0.2 dev: true /is-glob@4.0.3: @@ -3502,11 +3632,11 @@ packages: engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} dev: true - /is-typed-array@1.1.12: - resolution: {integrity: sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==} + /is-typed-array@1.1.13: + resolution: {integrity: sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==} engines: {node: '>= 0.4'} dependencies: - which-typed-array: 1.1.13 + which-typed-array: 1.1.14 dev: true /is-typedarray@1.0.0: @@ -3557,8 +3687,8 @@ packages: supports-color: 7.2.0 dev: true - /istanbul-reports@3.1.6: - resolution: {integrity: sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==} + /istanbul-reports@3.1.7: + resolution: {integrity: sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==} engines: {node: '>=8'} dependencies: html-escaper: 2.0.2 @@ -3609,6 +3739,10 @@ packages: dev: true optional: true + /jsbn@1.1.0: + resolution: {integrity: sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==} + dev: true + /jsdoc-mermaid@1.0.0: resolution: {integrity: sha512-WgXR/E1369RurPVFkyNzUWP5wB5xQkm0p+vdIh/cX6ZtEQBb5KdeukDje47Du++IehwztkR3GJcwYhM+eaq/4w==} dependencies: @@ -3632,7 +3766,7 @@ packages: engines: {node: '>=12.0.0'} hasBin: true dependencies: - '@babel/parser': 7.23.6 + '@babel/parser': 7.23.9 '@jsdoc/salty': 0.2.7 '@types/markdown-it': 12.2.3 bluebird: 3.7.2 @@ -3841,8 +3975,8 @@ packages: dev: true optional: true - /lilconfig@3.0.0: - resolution: {integrity: sha512-K2U4W2Ff5ibV7j7ydLr+zLAkIg5JJ4lPn1Ltsdt+Tz/IjQ8buJ55pZAxoP34lqIiwtF9iAvtLv3JGv7CAyAg+g==} + /lilconfig@3.1.1: + resolution: {integrity: sha512-O18pf7nyvHTckunPWCV1XUNXU1piu01y2b7ATJ0ppkUkk8ocqVWBrYjJBCwHDjD/ZWcfyrA0P4gKhzWGi5EINQ==} engines: {node: '>=14'} dev: true @@ -3856,6 +3990,11 @@ packages: uc.micro: 1.0.6 dev: true + /load-tsconfig@0.2.5: + resolution: {integrity: sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dev: true + /locate-path@3.0.0: resolution: {integrity: sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==} engines: {node: '>=6'} @@ -3966,8 +4105,8 @@ packages: tslib: 2.6.2 dev: true - /lru-cache@10.1.0: - resolution: {integrity: sha512-/1clY/ui8CzjKFyjdvwPWJUYKiFVXG2I2cY0ssG7h4+hwk+XOIX7ZSG9Q7TW8TW3Kp3BUSqgFWBLgL4PJ+Blag==} + /lru-cache@10.2.0: + resolution: {integrity: sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==} engines: {node: 14 || >=16.14} dev: true @@ -3993,7 +4132,7 @@ packages: resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} engines: {node: '>=10'} dependencies: - semver: 7.5.4 + semver: 7.6.0 dev: true /markdown-it-anchor@8.6.7(@types/markdown-it@12.2.3)(markdown-it@12.3.2): @@ -4136,14 +4275,14 @@ packages: hasBin: true dev: true - /mnemonist@0.39.7: - resolution: {integrity: sha512-ix3FwHWZgdXUt0dHM8bCrI4r1KMeYx8bCunPCYmvKXq4tn6gbNsqrsb4q0kDbDqbpIOvEaW5Sn+dmDwGydfrwA==} + /mnemonist@0.39.8: + resolution: {integrity: sha512-vyWo2K3fjrUw8YeeZ1zF0fy6Mu59RHokURlld8ymdUPjMlD9EC9ov1/YPqTgqRvUN9nTr3Gqfz29LYAmu0PHPQ==} dependencies: obliterator: 2.0.4 dev: true - /mocha@10.2.0: - resolution: {integrity: sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg==} + /mocha@10.3.0: + resolution: {integrity: sha512-uF2XJs+7xSLsrmIvn37i/wnc91nw7XjOQB8ccyx5aEgdnohr7n+rEiZP23WkCYHjilR6+EboEnbq/ZQDz4LSbg==} engines: {node: '>= 14.0.0'} hasBin: true dependencies: @@ -4154,13 +4293,12 @@ packages: diff: 5.0.0 escape-string-regexp: 4.0.0 find-up: 5.0.0 - glob: 7.2.0 + glob: 8.1.0 he: 1.2.0 js-yaml: 4.1.0 log-symbols: 4.1.0 minimatch: 5.0.1 ms: 2.1.3 - nanoid: 3.3.3 serialize-javascript: 6.0.0 strip-json-comments: 3.1.1 supports-color: 8.1.1 @@ -4170,6 +4308,13 @@ packages: yargs-unparser: 2.0.0 dev: true + /mockjs@1.1.0: + resolution: {integrity: sha512-eQsKcWzIaZzEZ07NuEyO4Nw65g0hdWAyurVol1IPl1gahRwY+svqzfgfey8U8dahLwG44d6/RwEzuK52rSa/JQ==} + hasBin: true + dependencies: + commander: 12.0.0 + dev: true + /ms@2.0.0: resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} dev: true @@ -4182,12 +4327,6 @@ packages: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} dev: true - /nanoid@3.3.3: - resolution: {integrity: sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==} - engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} - hasBin: true - dev: true - /nanoid@3.3.7: resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} @@ -4198,8 +4337,8 @@ packages: engines: {node: '>= 0.4.0'} dev: true - /nise@5.1.7: - resolution: {integrity: sha512-wWtNUhkT7k58uvWTB/Gy26eA/EJKtPZFVAhEilN5UYVmmGRYOURbejRUyKm0Uu9XVEW7K5nBOZfR8VMB4QR2RQ==} + /nise@5.1.9: + resolution: {integrity: sha512-qOnoujW4SV6e40dYxJOb3uvuoPHtmLzIk4TFo+j0jPJoC+5Z9xja5qH5JZobEPsa8+YYphMrOSwnrshEhG2qww==} dependencies: '@sinonjs/commons': 3.0.1 '@sinonjs/fake-timers': 11.2.2 @@ -4292,8 +4431,8 @@ packages: engines: {node: '>=0.10.0'} dev: true - /npm-run-path@5.2.0: - resolution: {integrity: sha512-W4/tgAXFqFA0iL7fk0+uQ3g7wkL8xJmx3XdK0VGb4cHW//eZTtKGvFBBoRKVTpY7n6ze4NL9ly7rgXcHufqXKg==} + /npm-run-path@5.3.0: + resolution: {integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} dependencies: path-key: 4.0.0 @@ -4340,6 +4479,13 @@ packages: resolution: {integrity: sha512-lgHwxlxV1qIg1Eap7LgIeoBWIMFibOjbrYPIPJZcI1mmGAI2m3lNYpK12Y+GBdPQ0U1hRwSord7GIaawz962qQ==} dev: true + /on-finished@2.3.0: + resolution: {integrity: sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==} + engines: {node: '>= 0.8'} + dependencies: + ee-first: 1.1.1 + dev: true + /once@1.4.0: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} dependencies: @@ -4407,21 +4553,20 @@ packages: '@tootallnate/quickjs-emscripten': 0.23.0 agent-base: 7.1.0 debug: 4.3.4(supports-color@8.1.1) - get-uri: 6.0.2 - http-proxy-agent: 7.0.0 - https-proxy-agent: 7.0.2 - pac-resolver: 7.0.0 + get-uri: 6.0.3 + http-proxy-agent: 7.0.2 + https-proxy-agent: 7.0.4 + pac-resolver: 7.0.1 socks-proxy-agent: 8.0.2 transitivePeerDependencies: - supports-color dev: true - /pac-resolver@7.0.0: - resolution: {integrity: sha512-Fd9lT9vJbHYRACT8OhCbZBbxr6KRSawSovFpy8nDGshaK99S/EBhVIHp9+crhxrsZOuvLpgL1n23iyPg6Rl2hg==} + /pac-resolver@7.0.1: + resolution: {integrity: sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==} engines: {node: '>= 14'} dependencies: degenerator: 5.0.1 - ip: 1.1.8 netmask: 2.0.2 dev: true @@ -4458,7 +4603,7 @@ packages: /parse5@3.0.3: resolution: {integrity: sha512-rgO9Zg5LLLkfJF9E6CCmXlSE4UVceloys8JrFqCcHloC3usd/kJCyPDwH2SOlzix2j3xaP9sUX3e8+kvkuleAA==} dependencies: - '@types/node': 20.11.6 + '@types/node': 20.11.20 dev: true /parse5@7.1.2: @@ -4467,6 +4612,11 @@ packages: entities: 4.5.0 dev: true + /parseurl@1.3.3: + resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} + engines: {node: '>= 0.8'} + dev: true + /pascal-case@3.1.2: resolution: {integrity: sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==} dependencies: @@ -4511,7 +4661,7 @@ packages: resolution: {integrity: sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==} engines: {node: '>=16 || 14 >=14.17'} dependencies: - lru-cache: 10.1.0 + lru-cache: 10.2.0 minipass: 7.0.4 dev: true @@ -4557,92 +4707,97 @@ packages: from2-string: 1.1.0 graceful-fs: 4.2.11 merge2: 1.4.1 - mnemonist: 0.39.7 + mnemonist: 0.39.8 stream-from-promise: 1.0.0 stream-to-string: 1.2.1 toposort: 2.0.2 dev: true - /postcss-browser-comments@4.0.0(browserslist@4.22.2)(postcss@8.4.33): + /possible-typed-array-names@1.0.0: + resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==} + engines: {node: '>= 0.4'} + dev: true + + /postcss-browser-comments@4.0.0(browserslist@4.23.0)(postcss@8.4.35): resolution: {integrity: sha512-X9X9/WN3KIvY9+hNERUqX9gncsgBA25XaeR+jshHz2j8+sYyHktHw1JdKuMjeLpGktXidqDhA7b/qm1mrBDmgg==} engines: {node: '>=8'} peerDependencies: browserslist: '>=4' postcss: '>=8' dependencies: - browserslist: 4.22.2 - postcss: 8.4.33 + browserslist: 4.23.0 + postcss: 8.4.35 dev: true - /postcss-calc@9.0.1(postcss@8.4.33): + /postcss-calc@9.0.1(postcss@8.4.35): resolution: {integrity: sha512-TipgjGyzP5QzEhsOZUaIkeO5mKeMFpebWzRogWG/ysonUlnHcq5aJe0jOjpfzUU8PeSaBQnrE8ehR0QA5vs8PQ==} engines: {node: ^14 || ^16 || >=18.0} peerDependencies: postcss: ^8.2.2 dependencies: - postcss: 8.4.33 + postcss: 8.4.35 postcss-selector-parser: 6.0.15 postcss-value-parser: 4.2.0 dev: true - /postcss-colormin@6.0.2(postcss@8.4.33): - resolution: {integrity: sha512-TXKOxs9LWcdYo5cgmcSHPkyrLAh86hX1ijmyy6J8SbOhyv6ua053M3ZAM/0j44UsnQNIWdl8gb5L7xX2htKeLw==} + /postcss-colormin@6.0.3(postcss@8.4.35): + resolution: {integrity: sha512-ECpkS+UZRyAtu/kjive2/1mihP+GNtgC8kcdU8ueWZi1ZVxMNnRziCLdhrWECJhEtSWijfX2Cl9XTTCK/hjGaA==} engines: {node: ^14 || ^16 || >=18.0} peerDependencies: postcss: ^8.4.31 dependencies: - browserslist: 4.22.2 + browserslist: 4.23.0 caniuse-api: 3.0.0 colord: 2.9.3 - postcss: 8.4.33 + postcss: 8.4.35 postcss-value-parser: 4.2.0 dev: true - /postcss-convert-values@6.0.2(postcss@8.4.33): - resolution: {integrity: sha512-aeBmaTnGQ+NUSVQT8aY0sKyAD/BaLJenEKZ03YK0JnDE1w1Rr8XShoxdal2V2H26xTJKr3v5haByOhJuyT4UYw==} + /postcss-convert-values@6.0.4(postcss@8.4.35): + resolution: {integrity: sha512-YT2yrGzPXoQD3YeA2kBo/696qNwn7vI+15AOS2puXWEvSWqdCqlOyDWRy5GNnOc9ACRGOkuQ4ESQEqPJBWt/GA==} engines: {node: ^14 || ^16 || >=18.0} peerDependencies: postcss: ^8.4.31 dependencies: - browserslist: 4.22.2 - postcss: 8.4.33 + browserslist: 4.23.0 + postcss: 8.4.35 postcss-value-parser: 4.2.0 dev: true - /postcss-discard-comments@6.0.1(postcss@8.4.33): + /postcss-discard-comments@6.0.1(postcss@8.4.35): resolution: {integrity: sha512-f1KYNPtqYLUeZGCHQPKzzFtsHaRuECe6jLakf/RjSRqvF5XHLZnM2+fXLhb8Qh/HBFHs3M4cSLb1k3B899RYIg==} engines: {node: ^14 || ^16 || >=18.0} peerDependencies: postcss: ^8.4.31 dependencies: - postcss: 8.4.33 + postcss: 8.4.35 dev: true - /postcss-discard-duplicates@6.0.1(postcss@8.4.33): - resolution: {integrity: sha512-1hvUs76HLYR8zkScbwyJ8oJEugfPV+WchpnA+26fpJ7Smzs51CzGBHC32RS03psuX/2l0l0UKh2StzNxOrKCYg==} + /postcss-discard-duplicates@6.0.2(postcss@8.4.35): + resolution: {integrity: sha512-U2rsj4w6pAGROCCcD13LP2eBIi1whUsXs4kgE6xkIuGfkbxCBSKhkCTWyowFd66WdVlLv0uM1euJKIgmdmZObg==} engines: {node: ^14 || ^16 || >=18.0} peerDependencies: postcss: ^8.4.31 dependencies: - postcss: 8.4.33 + postcss: 8.4.35 dev: true - /postcss-discard-empty@6.0.1(postcss@8.4.33): - resolution: {integrity: sha512-yitcmKwmVWtNsrrRqGJ7/C0YRy53i0mjexBDQ9zYxDwTWVBgbU4+C9jIZLmQlTDT9zhml+u0OMFJh8+31krmOg==} + /postcss-discard-empty@6.0.2(postcss@8.4.35): + resolution: {integrity: sha512-rj6pVC2dVCJrP0Y2RkYTQEbYaCf4HEm+R/2StQgJqGHxAa3+KcYslNQhcRqjLHtl/4wpzipJluaJLqBj6d5eDQ==} engines: {node: ^14 || ^16 || >=18.0} peerDependencies: postcss: ^8.4.31 dependencies: - postcss: 8.4.33 + postcss: 8.4.35 dev: true - /postcss-discard-overridden@6.0.1(postcss@8.4.33): + /postcss-discard-overridden@6.0.1(postcss@8.4.35): resolution: {integrity: sha512-qs0ehZMMZpSESbRkw1+inkf51kak6OOzNRaoLd/U7Fatp0aN2HQ1rxGOrJvYcRAN9VpX8kUF13R2ofn8OlvFVA==} engines: {node: ^14 || ^16 || >=18.0} peerDependencies: postcss: ^8.4.31 dependencies: - postcss: 8.4.33 + postcss: 8.4.35 dev: true /postcss-fluid@1.4.2: @@ -4656,29 +4811,29 @@ packages: postcss-simple-vars: 2.0.0 dev: true - /postcss-import@15.1.0(postcss@8.4.33): + /postcss-import@15.1.0(postcss@8.4.35): resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==} engines: {node: '>=14.0.0'} peerDependencies: postcss: ^8.0.0 dependencies: - postcss: 8.4.33 + postcss: 8.4.35 postcss-value-parser: 4.2.0 read-cache: 1.0.0 resolve: 1.22.8 dev: true - /postcss-js@4.0.1(postcss@8.4.33): + /postcss-js@4.0.1(postcss@8.4.35): resolution: {integrity: sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==} engines: {node: ^12 || ^14 || >= 16} peerDependencies: postcss: ^8.4.21 dependencies: camelcase-css: 2.0.1 - postcss: 8.4.33 + postcss: 8.4.35 dev: true - /postcss-load-config@4.0.2(postcss@8.4.33): + /postcss-load-config@4.0.2(postcss@8.4.35): resolution: {integrity: sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==} engines: {node: '>= 14'} peerDependencies: @@ -4690,204 +4845,204 @@ packages: ts-node: optional: true dependencies: - lilconfig: 3.0.0 - postcss: 8.4.33 - yaml: 2.3.4 + lilconfig: 3.1.1 + postcss: 8.4.35 + yaml: 2.4.0 dev: true - /postcss-merge-longhand@6.0.2(postcss@8.4.33): - resolution: {integrity: sha512-+yfVB7gEM8SrCo9w2lCApKIEzrTKl5yS1F4yGhV3kSim6JzbfLGJyhR1B6X+6vOT0U33Mgx7iv4X9MVWuaSAfw==} + /postcss-merge-longhand@6.0.3(postcss@8.4.35): + resolution: {integrity: sha512-kF/y3DU8CRt+SX3tP/aG+2gkZI2Z7OXDsPU7FgxIJmuyhQQ1EHceIYcsp/alvzCm2P4c37Sfdu8nNrHc+YeyLg==} engines: {node: ^14 || ^16 || >=18.0} peerDependencies: postcss: ^8.4.31 dependencies: - postcss: 8.4.33 + postcss: 8.4.35 postcss-value-parser: 4.2.0 - stylehacks: 6.0.2(postcss@8.4.33) + stylehacks: 6.0.3(postcss@8.4.35) dev: true - /postcss-merge-rules@6.0.3(postcss@8.4.33): - resolution: {integrity: sha512-yfkDqSHGohy8sGYIJwBmIGDv4K4/WrJPX355XrxQb/CSsT4Kc/RxDi6akqn5s9bap85AWgv21ArcUWwWdGNSHA==} + /postcss-merge-rules@6.0.4(postcss@8.4.35): + resolution: {integrity: sha512-97iF3UJ5v8N1BWy38y+0l+Z8o5/9uGlEgtWic2PJPzoRrLB6Gxg8TVG93O0EK52jcLeMsywre26AUlX1YAYeHA==} engines: {node: ^14 || ^16 || >=18.0} peerDependencies: postcss: ^8.4.31 dependencies: - browserslist: 4.22.2 + browserslist: 4.23.0 caniuse-api: 3.0.0 - cssnano-utils: 4.0.1(postcss@8.4.33) - postcss: 8.4.33 + cssnano-utils: 4.0.1(postcss@8.4.35) + postcss: 8.4.35 postcss-selector-parser: 6.0.15 dev: true - /postcss-minify-font-values@6.0.1(postcss@8.4.33): - resolution: {integrity: sha512-tIwmF1zUPoN6xOtA/2FgVk1ZKrLcCvE0dpZLtzyyte0j9zUeB8RTbCqrHZGjJlxOvNWKMYtunLrrl7HPOiR46w==} + /postcss-minify-font-values@6.0.2(postcss@8.4.35): + resolution: {integrity: sha512-IedzbVMoX0a7VZWjSYr5qJ6C37rws8kl8diPBeMZLJfWKkgXuMFY5R/OxPegn/q9tK9ztd0XRH3aR0u2t+A7uQ==} engines: {node: ^14 || ^16 || >=18.0} peerDependencies: postcss: ^8.4.31 dependencies: - postcss: 8.4.33 + postcss: 8.4.35 postcss-value-parser: 4.2.0 dev: true - /postcss-minify-gradients@6.0.1(postcss@8.4.33): - resolution: {integrity: sha512-M1RJWVjd6IOLPl1hYiOd5HQHgpp6cvJVLrieQYS9y07Yo8itAr6jaekzJphaJFR0tcg4kRewCk3kna9uHBxn/w==} + /postcss-minify-gradients@6.0.2(postcss@8.4.35): + resolution: {integrity: sha512-vP5mF7iI6/5fcpv+rSfwWQekOE+8I1i7/7RjZPGuIjj6eUaZVeG4XZYZrroFuw1WQd51u2V32wyQFZ+oYdE7CA==} engines: {node: ^14 || ^16 || >=18.0} peerDependencies: postcss: ^8.4.31 dependencies: colord: 2.9.3 - cssnano-utils: 4.0.1(postcss@8.4.33) - postcss: 8.4.33 + cssnano-utils: 4.0.1(postcss@8.4.35) + postcss: 8.4.35 postcss-value-parser: 4.2.0 dev: true - /postcss-minify-params@6.0.2(postcss@8.4.33): - resolution: {integrity: sha512-zwQtbrPEBDj+ApELZ6QylLf2/c5zmASoOuA4DzolyVGdV38iR2I5QRMsZcHkcdkZzxpN8RS4cN7LPskOkTwTZw==} + /postcss-minify-params@6.0.3(postcss@8.4.35): + resolution: {integrity: sha512-j4S74d3AAeCK5eGdQndXSrkxusV2ekOxbXGnlnZthMyZBBvSDiU34CihTASbJxuVB3bugudmwolS7+Dgs5OyOQ==} engines: {node: ^14 || ^16 || >=18.0} peerDependencies: postcss: ^8.4.31 dependencies: - browserslist: 4.22.2 - cssnano-utils: 4.0.1(postcss@8.4.33) - postcss: 8.4.33 + browserslist: 4.23.0 + cssnano-utils: 4.0.1(postcss@8.4.35) + postcss: 8.4.35 postcss-value-parser: 4.2.0 dev: true - /postcss-minify-selectors@6.0.2(postcss@8.4.33): + /postcss-minify-selectors@6.0.2(postcss@8.4.35): resolution: {integrity: sha512-0b+m+w7OAvZejPQdN2GjsXLv5o0jqYHX3aoV0e7RBKPCsB7TYG5KKWBFhGnB/iP3213Ts8c5H4wLPLMm7z28Sg==} engines: {node: ^14 || ^16 || >=18.0} peerDependencies: postcss: ^8.4.31 dependencies: - postcss: 8.4.33 + postcss: 8.4.35 postcss-selector-parser: 6.0.15 dev: true - /postcss-mixins@9.0.4(postcss@8.4.33): + /postcss-mixins@9.0.4(postcss@8.4.35): resolution: {integrity: sha512-XVq5jwQJDRu5M1XGkdpgASqLk37OqkH4JCFDXl/Dn7janOJjCTEKL+36cnRVy7bMtoBzALfO7bV7nTIsFnUWLA==} engines: {node: '>=14.0'} peerDependencies: postcss: ^8.2.14 dependencies: fast-glob: 3.3.2 - postcss: 8.4.33 - postcss-js: 4.0.1(postcss@8.4.33) - postcss-simple-vars: 7.0.1(postcss@8.4.33) - sugarss: 4.0.1(postcss@8.4.33) + postcss: 8.4.35 + postcss-js: 4.0.1(postcss@8.4.35) + postcss-simple-vars: 7.0.1(postcss@8.4.35) + sugarss: 4.0.1(postcss@8.4.35) dev: true - /postcss-nested@6.0.1(postcss@8.4.33): + /postcss-nested@6.0.1(postcss@8.4.35): resolution: {integrity: sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==} engines: {node: '>=12.0'} peerDependencies: postcss: ^8.2.14 dependencies: - postcss: 8.4.33 + postcss: 8.4.35 postcss-selector-parser: 6.0.15 dev: true - /postcss-nesting@12.0.2(postcss@8.4.33): - resolution: {integrity: sha512-63PpJHSeNs93S3ZUIyi+7kKx4JqOIEJ6QYtG3x+0qA4J03+4n0iwsyA1GAHyWxsHYljQS4/4ZK1o2sMi70b5wQ==} + /postcss-nesting@12.0.3(postcss@8.4.35): + resolution: {integrity: sha512-yrtMRPFNkfZMv9ikBvZ/Eh3RxhpMBKQ3KzD7LCY8+jYVlgju/Mdcxi4JY8bW2Y7ISXw8GTLuF/o+kFtp+yaVfQ==} engines: {node: ^14 || ^16 || >=18} peerDependencies: postcss: ^8.4 dependencies: - '@csstools/selector-specificity': 3.0.1(postcss-selector-parser@6.0.15) - postcss: 8.4.33 + '@csstools/selector-specificity': 3.0.2(postcss-selector-parser@6.0.15) + postcss: 8.4.35 postcss-selector-parser: 6.0.15 dev: true - /postcss-normalize-charset@6.0.1(postcss@8.4.33): + /postcss-normalize-charset@6.0.1(postcss@8.4.35): resolution: {integrity: sha512-aW5LbMNRZ+oDV57PF9K+WI1Z8MPnF+A8qbajg/T8PP126YrGX1f9IQx21GI2OlGz7XFJi/fNi0GTbY948XJtXg==} engines: {node: ^14 || ^16 || >=18.0} peerDependencies: postcss: ^8.4.31 dependencies: - postcss: 8.4.33 + postcss: 8.4.35 dev: true - /postcss-normalize-display-values@6.0.1(postcss@8.4.33): + /postcss-normalize-display-values@6.0.1(postcss@8.4.35): resolution: {integrity: sha512-mc3vxp2bEuCb4LgCcmG1y6lKJu1Co8T+rKHrcbShJwUmKJiEl761qb/QQCfFwlrvSeET3jksolCR/RZuMURudw==} engines: {node: ^14 || ^16 || >=18.0} peerDependencies: postcss: ^8.4.31 dependencies: - postcss: 8.4.33 + postcss: 8.4.35 postcss-value-parser: 4.2.0 dev: true - /postcss-normalize-positions@6.0.1(postcss@8.4.33): + /postcss-normalize-positions@6.0.1(postcss@8.4.35): resolution: {integrity: sha512-HRsq8u/0unKNvm0cvwxcOUEcakFXqZ41fv3FOdPn916XFUrympjr+03oaLkuZENz3HE9RrQE9yU0Xv43ThWjQg==} engines: {node: ^14 || ^16 || >=18.0} peerDependencies: postcss: ^8.4.31 dependencies: - postcss: 8.4.33 + postcss: 8.4.35 postcss-value-parser: 4.2.0 dev: true - /postcss-normalize-repeat-style@6.0.1(postcss@8.4.33): + /postcss-normalize-repeat-style@6.0.1(postcss@8.4.35): resolution: {integrity: sha512-Gbb2nmCy6tTiA7Sh2MBs3fj9W8swonk6lw+dFFeQT68B0Pzwp1kvisJQkdV6rbbMSd9brMlS8I8ts52tAGWmGQ==} engines: {node: ^14 || ^16 || >=18.0} peerDependencies: postcss: ^8.4.31 dependencies: - postcss: 8.4.33 + postcss: 8.4.35 postcss-value-parser: 4.2.0 dev: true - /postcss-normalize-string@6.0.1(postcss@8.4.33): + /postcss-normalize-string@6.0.1(postcss@8.4.35): resolution: {integrity: sha512-5Fhx/+xzALJD9EI26Aq23hXwmv97Zfy2VFrt5PLT8lAhnBIZvmaT5pQk+NuJ/GWj/QWaKSKbnoKDGLbV6qnhXg==} engines: {node: ^14 || ^16 || >=18.0} peerDependencies: postcss: ^8.4.31 dependencies: - postcss: 8.4.33 + postcss: 8.4.35 postcss-value-parser: 4.2.0 dev: true - /postcss-normalize-timing-functions@6.0.1(postcss@8.4.33): + /postcss-normalize-timing-functions@6.0.1(postcss@8.4.35): resolution: {integrity: sha512-4zcczzHqmCU7L5dqTB9rzeqPWRMc0K2HoR+Bfl+FSMbqGBUcP5LRfgcH4BdRtLuzVQK1/FHdFoGT3F7rkEnY+g==} engines: {node: ^14 || ^16 || >=18.0} peerDependencies: postcss: ^8.4.31 dependencies: - postcss: 8.4.33 + postcss: 8.4.35 postcss-value-parser: 4.2.0 dev: true - /postcss-normalize-unicode@6.0.2(postcss@8.4.33): - resolution: {integrity: sha512-Ff2VdAYCTGyMUwpevTZPZ4w0+mPjbZzLLyoLh/RMpqUqeQKZ+xMm31hkxBavDcGKcxm6ACzGk0nBfZ8LZkStKA==} + /postcss-normalize-unicode@6.0.3(postcss@8.4.35): + resolution: {integrity: sha512-T2Bb3gXz0ASgc3ori2dzjv6j/P2IantreaC6fT8tWjqYUiqMAh5jGIkdPwEV2FaucjQlCLeFJDJh2BeSugE1ig==} engines: {node: ^14 || ^16 || >=18.0} peerDependencies: postcss: ^8.4.31 dependencies: - browserslist: 4.22.2 - postcss: 8.4.33 + browserslist: 4.23.0 + postcss: 8.4.35 postcss-value-parser: 4.2.0 dev: true - /postcss-normalize-url@6.0.1(postcss@8.4.33): + /postcss-normalize-url@6.0.1(postcss@8.4.35): resolution: {integrity: sha512-jEXL15tXSvbjm0yzUV7FBiEXwhIa9H88JOXDGQzmcWoB4mSjZIsmtto066s2iW9FYuIrIF4k04HA2BKAOpbsaQ==} engines: {node: ^14 || ^16 || >=18.0} peerDependencies: postcss: ^8.4.31 dependencies: - postcss: 8.4.33 + postcss: 8.4.35 postcss-value-parser: 4.2.0 dev: true - /postcss-normalize-whitespace@6.0.1(postcss@8.4.33): + /postcss-normalize-whitespace@6.0.1(postcss@8.4.35): resolution: {integrity: sha512-76i3NpWf6bB8UHlVuLRxG4zW2YykF9CTEcq/9LGAiz2qBuX5cBStadkk0jSkg9a9TCIXbMQz7yzrygKoCW9JuA==} engines: {node: ^14 || ^16 || >=18.0} peerDependencies: postcss: ^8.4.31 dependencies: - postcss: 8.4.33 + postcss: 8.4.35 postcss-value-parser: 4.2.0 dev: true - /postcss-normalize@10.0.1(browserslist@4.22.2)(postcss@8.4.33): + /postcss-normalize@10.0.1(browserslist@4.23.0)(postcss@8.4.35): resolution: {integrity: sha512-+5w18/rDev5mqERcG3W5GZNMJa1eoYYNGo8gB7tEwaos0ajk3ZXAI4mHGcNT47NE+ZnZD1pEpUOFLvltIwmeJA==} engines: {node: '>= 12'} peerDependencies: @@ -4895,41 +5050,41 @@ packages: postcss: '>= 8' dependencies: '@csstools/normalize.css': 12.1.1 - browserslist: 4.22.2 - postcss: 8.4.33 - postcss-browser-comments: 4.0.0(browserslist@4.22.2)(postcss@8.4.33) + browserslist: 4.23.0 + postcss: 8.4.35 + postcss-browser-comments: 4.0.0(browserslist@4.23.0)(postcss@8.4.35) sanitize.css: 13.0.0 dev: true - /postcss-ordered-values@6.0.1(postcss@8.4.33): + /postcss-ordered-values@6.0.1(postcss@8.4.35): resolution: {integrity: sha512-XXbb1O/MW9HdEhnBxitZpPFbIvDgbo9NK4c/5bOfiKpnIGZDoL2xd7/e6jW5DYLsWxBbs+1nZEnVgnjnlFViaA==} engines: {node: ^14 || ^16 || >=18.0} peerDependencies: postcss: ^8.4.31 dependencies: - cssnano-utils: 4.0.1(postcss@8.4.33) - postcss: 8.4.33 + cssnano-utils: 4.0.1(postcss@8.4.35) + postcss: 8.4.35 postcss-value-parser: 4.2.0 dev: true - /postcss-reduce-initial@6.0.2(postcss@8.4.33): - resolution: {integrity: sha512-YGKalhNlCLcjcLvjU5nF8FyeCTkCO5UtvJEt0hrPZVCTtRLSOH4z00T1UntQPj4dUmIYZgMj8qK77JbSX95hSw==} + /postcss-reduce-initial@6.0.3(postcss@8.4.35): + resolution: {integrity: sha512-w4QIR9pEa1N4xMx3k30T1vLZl6udVK2RmNqrDXhBXX9L0mBj2a8ADs8zkbaEH7eUy1m30Wyr5EBgHN31Yq1JvA==} engines: {node: ^14 || ^16 || >=18.0} peerDependencies: postcss: ^8.4.31 dependencies: - browserslist: 4.22.2 + browserslist: 4.23.0 caniuse-api: 3.0.0 - postcss: 8.4.33 + postcss: 8.4.35 dev: true - /postcss-reduce-transforms@6.0.1(postcss@8.4.33): + /postcss-reduce-transforms@6.0.1(postcss@8.4.35): resolution: {integrity: sha512-fUbV81OkUe75JM+VYO1gr/IoA2b/dRiH6HvMwhrIBSUrxq3jNZQZitSnugcTLDi1KkQh1eR/zi+iyxviUNBkcQ==} engines: {node: ^14 || ^16 || >=18.0} peerDependencies: postcss: ^8.4.31 dependencies: - postcss: 8.4.33 + postcss: 8.4.35 postcss-value-parser: 4.2.0 dev: true @@ -4939,13 +5094,13 @@ packages: postcss: 6.0.23 dev: true - /postcss-rtlcss@4.0.9(postcss@8.4.33): + /postcss-rtlcss@4.0.9(postcss@8.4.35): resolution: {integrity: sha512-dCNKEf+FgTv+EA3XI8ysg2RnpS5s3/iZmU+9qpCNFxHU/BhK+4hz7jyCsCAfo0CLnDrMPtaQENhwb+EGm1wh7Q==} engines: {node: '>=18.0.0'} peerDependencies: postcss: ^8.4.21 dependencies: - postcss: 8.4.33 + postcss: 8.4.35 rtlcss: 4.1.1 dev: true @@ -4963,13 +5118,13 @@ packages: postcss: 5.2.18 dev: true - /postcss-simple-vars@7.0.1(postcss@8.4.33): + /postcss-simple-vars@7.0.1(postcss@8.4.35): resolution: {integrity: sha512-5GLLXaS8qmzHMOjVxqkk1TZPf1jMqesiI7qLhnlyERalG0sMbHIbJqrcnrpmZdKCLglHnRHoEBB61RtGTsj++A==} engines: {node: '>=14.0'} peerDependencies: postcss: ^8.2.1 dependencies: - postcss: 8.4.33 + postcss: 8.4.35 dev: true /postcss-strip-units@2.0.1: @@ -4979,24 +5134,24 @@ packages: reduce-function-call: 1.0.3 dev: true - /postcss-svgo@6.0.2(postcss@8.4.33): + /postcss-svgo@6.0.2(postcss@8.4.35): resolution: {integrity: sha512-IH5R9SjkTkh0kfFOQDImyy1+mTCb+E830+9SV1O+AaDcoHTvfsvt6WwJeo7KwcHbFnevZVCsXhDmjFiGVuwqFQ==} engines: {node: ^14 || ^16 || >= 18} peerDependencies: postcss: ^8.4.31 dependencies: - postcss: 8.4.33 + postcss: 8.4.35 postcss-value-parser: 4.2.0 svgo: 3.2.0 dev: true - /postcss-unique-selectors@6.0.2(postcss@8.4.33): + /postcss-unique-selectors@6.0.2(postcss@8.4.35): resolution: {integrity: sha512-8IZGQ94nechdG7Y9Sh9FlIY2b4uS8/k8kdKRX040XHsS3B6d1HrJAkXrBSsSu4SuARruSsUjW3nlSw8BHkaAYQ==} engines: {node: ^14 || ^16 || >=18.0} peerDependencies: postcss: ^8.4.31 dependencies: - postcss: 8.4.33 + postcss: 8.4.35 postcss-selector-parser: 6.0.15 dev: true @@ -5023,8 +5178,8 @@ packages: supports-color: 5.5.0 dev: true - /postcss@8.4.33: - resolution: {integrity: sha512-Kkpbhhdjw2qQs2O2DGX+8m5OVqEcbB9HRBvuYM9pgrjEFUg30A9LmXNlTAUj4S9kgtGyrMbTzVjH7E+s5Re2yg==} + /postcss@8.4.35: + resolution: {integrity: sha512-u5U8qYpBCpN13BsiEB0CbR1Hhh4Gc0zLFuedrHJKMctHCHAGrMdG0PRM/KErzAL3CU6/eckEtmHNB3x6e3c0vA==} engines: {node: ^10 || ^12 || >=14} dependencies: nanoid: 3.3.7 @@ -5062,8 +5217,8 @@ packages: dependencies: agent-base: 7.1.0 debug: 4.3.4(supports-color@8.1.1) - http-proxy-agent: 7.0.0 - https-proxy-agent: 7.0.2 + http-proxy-agent: 7.0.2 + https-proxy-agent: 7.0.4 lru-cache: 7.18.3 pac-proxy-agent: 7.0.1 proxy-from-env: 1.1.0 @@ -5096,12 +5251,12 @@ packages: engines: {node: '>=6'} dev: true - /puppeteer-core@21.9.0: - resolution: {integrity: sha512-QgowcczLAoLWlV38s3y3VuEvjJGfKU5rR6Q23GUbiGOaiQi+QpaWQ+aXdzP9LHVSUPmHdAaWhcvMztYSw3f8gQ==} + /puppeteer-core@21.11.0: + resolution: {integrity: sha512-ArbnyA3U5SGHokEvkfWjW+O8hOxV1RSJxOgriX/3A4xZRqixt9ZFHD0yPgZQF05Qj0oAqi8H/7stDorjoHY90Q==} engines: {node: '>=16.13.2'} dependencies: '@puppeteer/browsers': 1.9.1 - chromium-bidi: 0.5.4(devtools-protocol@0.0.1232444) + chromium-bidi: 0.5.8(devtools-protocol@0.0.1232444) cross-fetch: 4.0.0 debug: 4.3.4(supports-color@8.1.1) devtools-protocol: 0.0.1232444 @@ -5113,15 +5268,15 @@ packages: - utf-8-validate dev: true - /puppeteer@21.9.0: - resolution: {integrity: sha512-vcLR81Rp+MBrgqhiXZfpwEBbyKTa88Hd+8Al3+emWzcJb9evLLSfUYli0QUqhofPFrXsO2A/dAF9OunyOivL6w==} + /puppeteer@21.11.0: + resolution: {integrity: sha512-9jTHuYe22TD3sNxy0nEIzC7ZrlRnDgeX3xPkbS7PnbdwYjl2o/z/YuCrRBwezdKpbTDTJ4VqIggzNyeRcKq3cg==} engines: {node: '>=16.13.2'} hasBin: true requiresBuild: true dependencies: '@puppeteer/browsers': 1.9.1 cosmiconfig: 9.0.0 - puppeteer-core: 21.9.0 + puppeteer-core: 21.11.0 transitivePeerDependencies: - bufferutil - encoding @@ -5145,7 +5300,7 @@ packages: resolution: {integrity: sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==} engines: {node: '>=0.6'} dependencies: - side-channel: 1.0.4 + side-channel: 1.0.5 dev: true /qs@6.5.3: @@ -5355,9 +5510,9 @@ packages: engines: {node: '>=12.0.0'} hasBin: true dependencies: - escalade: 3.1.1 + escalade: 3.1.2 picocolors: 1.0.0 - postcss: 8.4.33 + postcss: 8.4.35 strip-json-comments: 3.1.1 dev: true @@ -5413,6 +5568,14 @@ packages: lru-cache: 6.0.0 dev: true + /semver@7.6.0: + resolution: {integrity: sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==} + engines: {node: '>=10'} + hasBin: true + dependencies: + lru-cache: 6.0.0 + dev: true + /serialize-error@7.0.1: resolution: {integrity: sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==} engines: {node: '>=10'} @@ -5430,15 +5593,16 @@ packages: resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} dev: true - /set-function-length@1.2.0: - resolution: {integrity: sha512-4DBHDoyHlM1IRPGYcoxexgh67y4ueR53FKV1yyxwFMY7aCqcN/38M1+SwZ/qJQ8iLv7+ck385ot4CcisOAPT9w==} + /set-function-length@1.2.1: + resolution: {integrity: sha512-j4t6ccc+VsKwYHso+kElc5neZpjtq9EnRICFZtWyBsLojhmeF/ZBd/elqm22WJh/BziDe/SBiOeAt0m2mfLD0g==} engines: {node: '>= 0.4'} dependencies: - define-data-property: 1.1.1 + define-data-property: 1.1.4 + es-errors: 1.3.0 function-bind: 1.1.2 - get-intrinsic: 1.2.2 + get-intrinsic: 1.2.4 gopd: 1.0.1 - has-property-descriptors: 1.0.1 + has-property-descriptors: 1.0.2 dev: true /shebang-command@2.0.0: @@ -5460,11 +5624,13 @@ packages: commander: 9.5.0 dev: true - /side-channel@1.0.4: - resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==} + /side-channel@1.0.5: + resolution: {integrity: sha512-QcgiIWV4WV7qWExbN5llt6frQB/lBven9pqliLXfGPB+K9ZYXxDozp0wLkHS24kWCm+6YXH/f0HhnObZnZOBnQ==} + engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.5 - get-intrinsic: 1.2.2 + call-bind: 1.0.7 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 object-inspect: 1.13.1 dev: true @@ -5483,8 +5649,8 @@ packages: '@sinonjs/commons': 3.0.1 '@sinonjs/fake-timers': 11.2.2 '@sinonjs/samsam': 8.0.0 - diff: 5.1.0 - nise: 5.1.7 + diff: 5.2.0 + nise: 5.1.9 supports-color: 7.2.0 dev: true @@ -5493,13 +5659,13 @@ packages: engines: {node: '>= 6.0.0', npm: '>= 3.0.0'} dev: true - /snyk@1.1274.0: - resolution: {integrity: sha512-dArVJ6SFu2coqWEDoSALs+Qxw/W8pogJ20MzQAnPcXDSlWEaY2Et/VsIUexg0wageOmfOqDkNyeXSN8DJTHUqA==} + /snyk@1.1280.1: + resolution: {integrity: sha512-Q40IVrnpe3Aejp8I1pM6QMwtiz1L86/3P9ducn388P/pOEDXunupwJwyZ/kOe7FxL895GvvGfi3IsELHxRjffw==} engines: {node: '>=12'} hasBin: true requiresBuild: true dependencies: - '@sentry/node': 7.95.0 + '@sentry/node': 7.102.1 global-agent: 3.0.0 dev: true @@ -5509,16 +5675,16 @@ packages: dependencies: agent-base: 7.1.0 debug: 4.3.4(supports-color@8.1.1) - socks: 2.7.1 + socks: 2.8.1 transitivePeerDependencies: - supports-color dev: true - /socks@2.7.1: - resolution: {integrity: sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==} - engines: {node: '>= 10.13.0', npm: '>= 3.0.0'} + /socks@2.8.1: + resolution: {integrity: sha512-B6w7tkwNid7ToxjZ08rQMT8M9BJAf8DKx8Ft4NivzH0zBUfd6jldGcisJn/RLgxcX3FPNDdNQCUEMMT79b+oCQ==} + engines: {node: '>= 10.0.0', npm: '>= 3.0.0'} dependencies: - ip: 2.0.0 + ip-address: 9.0.5 smart-buffer: 4.2.0 dev: true @@ -5569,6 +5735,11 @@ packages: dev: true optional: true + /statuses@1.5.0: + resolution: {integrity: sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==} + engines: {node: '>= 0.6'} + dev: true + /stream-from-promise@1.0.0: resolution: {integrity: sha512-j84KLkudt+gr8KJ21RB02btPLx61uGbrLnewsWz6QKmsz8/c4ZFqXw6mJh5+G4oRN7DgDxdbjPxnpySpg1mUig==} engines: {node: '>=0.10.0'} @@ -5580,11 +5751,13 @@ packages: promise-polyfill: 1.1.6 dev: true - /streamx@2.15.6: - resolution: {integrity: sha512-q+vQL4AAz+FdfT137VF69Cc/APqUbxy+MDOImRrMvchJpigHj9GksgDU2LYbO9rx7RX6osWgxJB2WxhYv4SZAw==} + /streamx@2.16.1: + resolution: {integrity: sha512-m9QYj6WygWyWa3H1YY69amr4nVgy61xfjys7xO7kviL5rfIEc2naf+ewFiOA+aEJD7y0JO3h2GoiUv4TDwEGzQ==} dependencies: fast-fifo: 1.3.2 queue-tick: 1.0.1 + optionalDependencies: + bare-events: 2.2.0 dev: true /string-argv@0.3.2: @@ -5673,24 +5846,24 @@ packages: engines: {node: '>=8'} dev: true - /stylehacks@6.0.2(postcss@8.4.33): - resolution: {integrity: sha512-00zvJGnCu64EpMjX8b5iCZ3us2Ptyw8+toEkb92VdmkEaRaSGBNKAoK6aWZckhXxmQP8zWiTaFaiMGIU8Ve8sg==} + /stylehacks@6.0.3(postcss@8.4.35): + resolution: {integrity: sha512-KzBqjnqktc8/I0ERCb+lGq06giF/JxDbw2r9kEVhen9noHeIDRtMWUp9r62sOk+/2bbX6sFG1GhsS7ToXG0PEg==} engines: {node: ^14 || ^16 || >=18.0} peerDependencies: postcss: ^8.4.31 dependencies: - browserslist: 4.22.2 - postcss: 8.4.33 + browserslist: 4.23.0 + postcss: 8.4.35 postcss-selector-parser: 6.0.15 dev: true - /sugarss@4.0.1(postcss@8.4.33): + /sugarss@4.0.1(postcss@8.4.35): resolution: {integrity: sha512-WCjS5NfuVJjkQzK10s8WOBY+hhDxxNt/N6ZaGwxFZ+wN3/lKKFSaaKUNecULcTTvE4urLcKaZFQD8vO0mOZujw==} engines: {node: '>=12.0'} peerDependencies: postcss: ^8.3.3 dependencies: - postcss: 8.4.33 + postcss: 8.4.35 dev: true /supports-color@2.0.0: @@ -5768,9 +5941,9 @@ packages: /tar-stream@3.1.7: resolution: {integrity: sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==} dependencies: - b4a: 1.6.4 + b4a: 1.6.6 fast-fifo: 1.3.2 - streamx: 2.15.6 + streamx: 2.16.1 dev: true /temp@0.4.0: @@ -5778,8 +5951,8 @@ packages: engines: {'0': node >=0.4.0} dev: true - /terser@5.27.0: - resolution: {integrity: sha512-bi1HRwVRskAjheeYl291n3JC4GgO/Ty4z1nVs5AAsmonJulGxpSektecnNedrwK9C7vpvVtcX3cw00VSLt7U2A==} + /terser@5.28.1: + resolution: {integrity: sha512-wM+bZp54v/E9eRRGXb5ZFDvinrJIOaTapx3WUokyVGZu5ucVCK55zEgGd5Dl2fSr3jUo5sDiERErUWLY6QPFyA==} engines: {node: '>=10'} hasBin: true dependencies: @@ -5943,14 +6116,19 @@ packages: engines: {node: '>= 10.0.0'} dev: true - /update-browserslist-db@1.0.13(browserslist@4.22.2): + /unpipe@1.0.0: + resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} + engines: {node: '>= 0.8'} + dev: true + + /update-browserslist-db@1.0.13(browserslist@4.23.0): resolution: {integrity: sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==} hasBin: true peerDependencies: browserslist: '>= 4.21.0' dependencies: - browserslist: 4.22.2 - escalade: 3.1.1 + browserslist: 4.23.0 + escalade: 3.1.2 picocolors: 1.0.0 dev: true @@ -5986,8 +6164,8 @@ packages: qs: 6.11.2 dev: true - /urlpattern-polyfill@9.0.0: - resolution: {integrity: sha512-WHN8KDQblxd32odxeIgo83rdVDE2bvdkb86it7bMhYZwWKJz0+O0RK/eZiHYnM+zgt/U7hAHOlCQGfjjvSkw2g==} + /urlpattern-polyfill@10.0.0: + resolution: {integrity: sha512-H/A06tKD7sS1O1X2SshBVeA5FLycRpjqiBeqGKmBwBDBy28EnRjORxTNe269KSSr5un5qyWi1iL61wLxpd+ZOg==} dev: true /util-deprecate@1.0.2: @@ -6000,8 +6178,13 @@ packages: inherits: 2.0.4 is-arguments: 1.1.1 is-generator-function: 1.0.10 - is-typed-array: 1.1.12 - which-typed-array: 1.1.13 + is-typed-array: 1.1.13 + which-typed-array: 1.1.14 + dev: true + + /utils-merge@1.0.1: + resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} + engines: {node: '>= 0.4.0'} dev: true /uuid@3.4.0: @@ -6016,7 +6199,7 @@ packages: resolution: {integrity: sha512-/EH/sDgxU2eGxajKdwLCDmQ4FWq+kpi3uCmBGpw1xJtnAxEjlD8j8PEiGWpCIMIs3ciNAgH0d3TTJiUkYzyZjA==} engines: {node: '>=10.12.0'} dependencies: - '@jridgewell/trace-mapping': 0.3.22 + '@jridgewell/trace-mapping': 0.3.23 '@types/istanbul-lib-coverage': 2.0.6 convert-source-map: 2.0.0 dev: true @@ -6048,24 +6231,24 @@ packages: dependencies: picomatch: 2.3.1 pretty-bytes: 6.1.1 - vite: 4.5.2(@types/node@18.19.9) + vite: 4.5.2(@types/node@18.19.18) dev: false - /vite-plugin-dts@1.7.3(@types/node@18.19.9)(vite@4.5.2): + /vite-plugin-dts@1.7.3(@types/node@18.19.18)(vite@4.5.2): resolution: {integrity: sha512-u3t45p6fTbzUPMkwYe0ESwuUeiRMlwdPfD3dRyDKUwLe2WmEYcFyVp2o9/ke2EMrM51lQcmNWdV9eLcgjD1/ng==} engines: {node: ^14.18.0 || >=16.0.0} peerDependencies: vite: '>=2.9.0' dependencies: - '@microsoft/api-extractor': 7.39.3(@types/node@18.19.9) + '@microsoft/api-extractor': 7.41.0(@types/node@18.19.18) '@rollup/pluginutils': 5.1.0 - '@rushstack/node-core-library': 3.64.1(@types/node@18.19.9) + '@rushstack/node-core-library': 3.66.1(@types/node@18.19.18) debug: 4.3.4(supports-color@8.1.1) fast-glob: 3.3.2 fs-extra: 10.1.0 kolorist: 1.8.0 ts-morph: 17.0.1 - vite: 4.5.2(@types/node@18.19.9) + vite: 4.5.2(@types/node@18.19.18) transitivePeerDependencies: - '@types/node' - rollup @@ -6076,8 +6259,8 @@ packages: resolution: {integrity: sha512-67Abh1X9rhJq7u9Hxq9CJznM0acAPynvumkQ33wzvigW1aaPfsHNNMnhArABYryXnqASlmiZHpbhYOtDI9KfYw==} dependencies: '@wesbos/code-icons': 1.2.4 - vite: 4.5.2(@types/node@18.19.9) - vite-plugin-dts: 1.7.3(@types/node@18.19.9)(vite@4.5.2) + vite: 4.5.2(@types/node@18.19.18) + vite-plugin-dts: 1.7.3(@types/node@18.19.18)(vite@4.5.2) vscode-icons-js: 11.6.1 transitivePeerDependencies: - '@types/node' @@ -6097,10 +6280,32 @@ packages: vite: '*' dependencies: html-minifier-terser: 6.1.0 - vite: 4.5.2(@types/node@18.19.9) + vite: 4.5.2(@types/node@18.19.18) + dev: true + + /vite-plugin-mock@3.0.1(esbuild@0.19.12)(mockjs@1.1.0)(vite@4.5.2): + resolution: {integrity: sha512-jEqRkX6Ts6z9e3sPrktcmujLGTIjxMwMZUhcgoo1q0dEMcljMBkZgJK1vMaetTm+GfOy2NkGVQOwVqLS/Vy6Uw==} + engines: {node: '>=16.0.0'} + peerDependencies: + mockjs: '>=1.1.0' + vite: '>=4.0.0' + dependencies: + '@types/mockjs': 1.0.10 + bundle-require: 4.0.2(esbuild@0.19.12) + chokidar: 3.6.0 + connect: 3.7.0 + debug: 4.3.4(supports-color@8.1.1) + fast-glob: 3.3.2 + mockjs: 1.1.0 + path-to-regexp: 6.2.1 + picocolors: 1.0.0 + vite: 4.5.2(@types/node@18.19.18) + transitivePeerDependencies: + - esbuild + - supports-color dev: true - /vite@4.5.2(@types/node@18.19.9): + /vite@4.5.2(@types/node@18.19.18): resolution: {integrity: sha512-tBCZBNSBbHQkaGyhGCDUGqeo2ph8Fstyp6FMSvTtsXeZSPpSMGlviAOav2hxVTqFcx8Hj/twtWKsMJXNY0xI8w==} engines: {node: ^14.18.0 || >=16.0.0} hasBin: true @@ -6128,9 +6333,9 @@ packages: terser: optional: true dependencies: - '@types/node': 18.19.9 + '@types/node': 18.19.18 esbuild: 0.18.20 - postcss: 8.4.33 + postcss: 8.4.35 rollup: 3.29.4 optionalDependencies: fsevents: 2.3.3 @@ -6148,8 +6353,8 @@ packages: xml-name-validator: 4.0.0 dev: true - /web-streams-polyfill@3.3.2: - resolution: {integrity: sha512-3pRGuxRF5gpuZc0W+EpwQRmCD7gRqcDOMt688KmdlDAgAyaB1XlN0zq2njfDNm44XVdIouE7pZ6GzbdyH47uIQ==} + /web-streams-polyfill@3.3.3: + resolution: {integrity: sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==} engines: {node: '>= 8'} dev: true @@ -6217,15 +6422,15 @@ packages: resolution: {integrity: sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==} dev: true - /which-typed-array@1.1.13: - resolution: {integrity: sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow==} + /which-typed-array@1.1.14: + resolution: {integrity: sha512-VnXFiIW8yNn9kIHN88xvZ4yOWchftKDsRJ8fEPacX/wl1lOvBrhsJ/OeJCXq7B0AaijRuqgzSKalJoPk+D8MPg==} engines: {node: '>= 0.4'} dependencies: - available-typed-arrays: 1.0.5 - call-bind: 1.0.5 + available-typed-arrays: 1.0.7 + call-bind: 1.0.7 for-each: 0.3.3 gopd: 1.0.1 - has-tostringtag: 1.0.0 + has-tostringtag: 1.0.2 dev: true /which@2.0.2: @@ -6327,9 +6532,10 @@ packages: resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} dev: true - /yaml@2.3.4: - resolution: {integrity: sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA==} + /yaml@2.4.0: + resolution: {integrity: sha512-j9iR8g+/t0lArF4V6NE/QCfT+CO7iLqrXAHZbJdo+LfjqP1vR8Fg5bSiaq6Q2lOD1AUEVrEVIgABvBFYojJVYQ==} engines: {node: '>= 14'} + hasBin: true dev: true /yargs-parser@13.1.2: @@ -6379,7 +6585,7 @@ packages: engines: {node: '>=10'} dependencies: cliui: 7.0.4 - escalade: 3.1.1 + escalade: 3.1.2 get-caller-file: 2.0.5 require-directory: 2.1.1 string-width: 4.2.3 @@ -6392,7 +6598,7 @@ packages: engines: {node: '>=12'} dependencies: cliui: 8.0.1 - escalade: 3.1.1 + escalade: 3.1.2 get-caller-file: 2.0.5 require-directory: 2.1.1 string-width: 4.2.3 diff --git a/source/components/datatable/change-button.mjs b/source/components/datatable/change-button.mjs new file mode 100644 index 0000000000000000000000000000000000000000..eddd78d1a2b93abffa41f0ed050d20d5adede76e --- /dev/null +++ b/source/components/datatable/change-button.mjs @@ -0,0 +1,284 @@ +/** + * Copyright 2023 schukai GmbH + * SPDX-License-Identifier: AGPL-3.0 + */ + +import {instanceSymbol} from "../../constants.mjs"; +import {diff} from "../../data/diff.mjs"; +import { + assembleMethodSymbol, + CustomElement, + registerCustomElement, +} from "../../dom/customelement.mjs"; +import {isString, isArray} from "../../types/is.mjs"; +import {Observer} from "../../types/observer.mjs"; +import {clone} from "../../util/clone.mjs"; +import {State} from "../form/types/state.mjs"; +import { + ATTRIBUTE_DATASOURCE_SELECTOR, +} from "./constants.mjs"; +import {ChangeButtonStyleSheet} from "./stylesheet/change-button.mjs"; + + +export {ChangeButton}; + + +/** + * @private + * @type {symbol} + */ +const stateButtonElementSymbol = Symbol("stateButtonElement"); + +/** + * @private + * @type {symbol} + */ +const datasetLinkedElementSymbol = Symbol("datasetLinkedElement"); +/** + * @private + * @type {symbol} + */ +const overlayLinkedElementSymbol = Symbol("overlayLinkedElement"); + + +class ChangeButton extends CustomElement { + /** + * This method is called by the `instanceof` operator. + * @returns {symbol} + */ + static get [instanceSymbol]() { + return Symbol.for("@schukai/monster/components/datasource/change-button@@instance"); + } + + /** + * To set the options via the html tag the attribute `data-monster-options` must be used. + * @see {@link https://monsterjs.org/en/doc/#configurate-a-monster-control} + * + * The individual configuration values can be found in the table. + * + * @property {Object} templates Template definitions + * @property {string} templates.main Main template + * @property {object} datasource The datasource + * @property {string} datasource.selector The selector of the datasource + * @property {object} mapping The mapping + * @property {string} mapping.data The data + * @property {number} mapping.index The index + * @property {Array} data The data + * @return {Object} + */ + get defaults() { + const obj = Object.assign({}, super.defaults, { + templates: { + main: getTemplate(), + }, + + labels: { + button: `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" + class="bi bi-grid" viewBox="0 0 16 16"> + <path d="M1 2.5A1.5 1.5 0 0 1 2.5 1h3A1.5 1.5 0 0 1 7 2.5v3A1.5 1.5 0 0 1 5.5 7h-3A1.5 1.5 0 0 1 1 5.5zM2.5 2a.5.5 0 0 0-.5.5v3a.5.5 0 0 0 .5.5h3a.5.5 0 0 0 .5-.5v-3a.5.5 0 0 0-.5-.5zm6.5.5A1.5 1.5 0 0 1 10.5 1h3A1.5 1.5 0 0 1 15 2.5v3A1.5 1.5 0 0 1 13.5 7h-3A1.5 1.5 0 0 1 9 5.5zm1.5-.5a.5.5 0 0 0-.5.5v3a.5.5 0 0 0 .5.5h3a.5.5 0 0 0 .5-.5v-3a.5.5 0 0 0-.5-.5zM1 10.5A1.5 1.5 0 0 1 2.5 9h3A1.5 1.5 0 0 1 7 10.5v3A1.5 1.5 0 0 1 5.5 15h-3A1.5 1.5 0 0 1 1 13.5zm1.5-.5a.5.5 0 0 0-.5.5v3a.5.5 0 0 0 .5.5h3a.5.5 0 0 0 .5-.5v-3a.5.5 0 0 0-.5-.5zm6.5.5A1.5 1.5 0 0 1 10.5 9h3a1.5 1.5 0 0 1 1.5 1.5v3a1.5 1.5 0 0 1-1.5 1.5h-3A1.5 1.5 0 0 1 9 13.5zm1.5-.5a.5.5 0 0 0-.5.5v3a.5.5 0 0 0 .5.5h3a.5.5 0 0 0 .5-.5v-3a.5.5 0 0 0-.5-.5z"/> + </svg>`, + }, + + classes: { + bar: "monster-button-primary", + }, + + dataset: { + selector: null, + }, + + overlay: { + selector: null, + }, + + mapping: { + data: "dataset", + index: 0, + }, + + data: {}, + + disabled: false, + }); + + updateOptionsFromArguments.call(this, obj); + return obj; + } + + /** + * + * @return {string} + */ + static getTag() { + return "monster-datatable-change-button"; + } + + + /** + * This method is responsible for assembling the component. + */ + [assembleMethodSymbol]() { + super[assembleMethodSymbol](); + const self = this; + + initControlReferences.call(this); + initEventHandler.call(this); + + } + + /** + * + * @return [CSSStyleSheet] + */ + static getCSSStyleSheet() { + return [ChangeButtonStyleSheet]; + } +} + +/** + * @private + * @return {Monster.Components.Datatable.Form} + */ +function initControlReferences() { + if (!this.shadowRoot) { + throw new Error("no shadow-root is defined"); + } + + const selector = this.getOption("dataset.selector"); + + if (isString(selector)) { + const elements = document.querySelectorAll(selector); + if (elements.length !== 1) { + throw new Error("the selector must match exactly one element"); + } + + const element = elements[0]; + if (!(element instanceof HTMLElement)) { + throw new TypeError("the element must be a dataset"); + } + + this[datasetLinkedElementSymbol] = element; + + } + + + const selector2 = this.getOption("overlay.selector"); + + if (isString(selector2)) { + const elements = document.querySelectorAll(selector2); + if (elements.length !== 1) { + throw new Error("the selector must match exactly one element"); + } + + const element = elements[0]; + if (!(element instanceof HTMLElement)) { + throw new TypeError("the element must be a overlay"); + } + + this[overlayLinkedElementSymbol] = element; + + } + + this[stateButtonElementSymbol] = this.shadowRoot.querySelector( + "[data-monster-role=state-button]" + ); + + if (this[stateButtonElementSymbol]) { + setTimeout(() => { + const states = { + "changed": new State( + "changed", + `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-record-circle" viewBox="0 0 16 16"> + <path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14m0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16"/> + <path d="M11 8a3 3 0 1 1-6 0 3 3 0 0 1 6 0"/> + </svg>`, + ) + } + + this[stateButtonElementSymbol].removeState(); + this[stateButtonElementSymbol].setOption("states", states); + this[stateButtonElementSymbol].setOption("labels.button", this.getOption("labels.button")); + + }, 1); + + } + + + return this; +} + +function getIndex() { + + if (!(this instanceof HTMLElement)) { + return; + } + + const row = this.closest('[data-monster-insert-reference]'); + if (!row) { + return; + } + + const ref = row.getAttribute('data-monster-insert-reference'); + if (!ref) { + return; + } + + let index = Number(ref.split("-")[3]); + if (isNaN(index)) { + return; + } + + return index; + +} + +/** + * @private + */ +function initEventHandler() { + + setTimeout(() => { + this[stateButtonElementSymbol].setOption("actions.click", () => { + const index = getIndex.call(this); + + if (!isNaN(index)) { + + this[datasetLinkedElementSymbol].setOption("mapping.index", index); + this[overlayLinkedElementSymbol].open(); + + } + + + }); + }, 1); + + +} + +/** + * @param {Object} options + */ +function updateOptionsFromArguments(options) { + const selector = this.getAttribute(ATTRIBUTE_DATASOURCE_SELECTOR); + if (selector) { + options.datasource.selector = selector; + } +} + +/** + * @private + * @return {string} + */ +function getTemplate() { + // language=HTML + return ` + <div data-monster-role="control" part="control" + data-monster-attributes="disabled path:disabled | if:true"> + <monster-state-button data-monster-role="state-button"></monster-state-button> + + </div> + `; +} + +registerCustomElement(ChangeButton); + diff --git a/source/components/datatable/dataset.mjs b/source/components/datatable/dataset.mjs index 39d2c03676d02458f0cb64b8d0d3cfcdda384a91..7c66469d91007953a235d3716193172c83fb42a6 100644 --- a/source/components/datatable/dataset.mjs +++ b/source/components/datatable/dataset.mjs @@ -3,27 +3,32 @@ * SPDX-License-Identifier: AGPL-3.0 */ -import { instanceSymbol } from "../../constants.mjs"; +import {instanceSymbol, internalSymbol} from "../../constants.mjs"; +import {Pathfinder} from "../../data/pathfinder.mjs"; +import {getLinkedObjects, hasObjectLink} from "../../dom/attributes.mjs"; +import {customElementUpdaterLinkSymbol} from "../../dom/constants.mjs"; import { - assembleMethodSymbol, - CustomElement, - attributeObserverSymbol, - registerCustomElement, + assembleMethodSymbol, + CustomElement, + attributeObserverSymbol, + registerCustomElement, } from "../../dom/customelement.mjs"; -import { isString } from "../../types/is.mjs"; -import { Observer } from "../../types/observer.mjs"; +import {isString} from "../../types/is.mjs"; +import {Observer} from "../../types/observer.mjs"; +import {clone} from "../../util/clone.mjs"; import { - ATTRIBUTE_DATASOURCE_SELECTOR, - ATTRIBUTE_DATATABLE_INDEX, + ATTRIBUTE_DATASOURCE_SELECTOR, + ATTRIBUTE_DATATABLE_INDEX, } from "./constants.mjs"; -import { Datasource } from "./datasource.mjs"; -import { DatasetStyleSheet } from "./stylesheet/dataset.mjs"; +import {Datasource} from "./datasource.mjs"; +import {DatasetStyleSheet} from "./stylesheet/dataset.mjs"; import { - handleDataSourceChanges, - datasourceLinkedElementSymbol, + handleDataSourceChanges, + datasourceLinkedElementSymbol, } from "./util.mjs"; +import {FormStyleSheet} from "../stylesheet/form.mjs"; -export { DataSet }; +export {DataSet}; /** * The data set component is used to show the data of a data source. @@ -66,139 +71,207 @@ export { DataSet }; * @summary A data set */ class DataSet extends CustomElement { - /** - * This method is called by the `instanceof` operator. - * @returns {symbol} - */ - static get [instanceSymbol]() { - return Symbol.for("@schukai/monster/components/dataset@@instance"); - } - - /** - * This method determines which attributes are to be monitored by `attributeChangedCallback()`. - * - * @return {string[]} - * @since 1.15.0 - */ - static get observedAttributes() { - const attributes = super.observedAttributes; - attributes.push(ATTRIBUTE_DATATABLE_INDEX); - return attributes; - } - - /** - * To set the options via the html tag the attribute `data-monster-options` must be used. - * @see {@link https://monsterjs.org/en/doc/#configurate-a-monster-control} - * - * The individual configuration values can be found in the table. - * - * @property {Object} templates Template definitions - * @property {string} templates.main Main template - * @property {object} datasource The datasource - */ - get defaults() { - const obj = Object.assign({}, super.defaults, { - templates: { - main: getTemplate(), - }, - - datasource: { - selector: null, - }, - - mapping: { - data: "dataset", - index: 0, - }, - - data: [], - }); - - updateOptionsFromArguments.call(this, obj); - return obj; - } - - /** - * - * @return {string} - */ - static getTag() { - return "monster-dataset"; - } - - /** - * - * @return {Monster.Components.Form.Form} - */ - [assembleMethodSymbol]() { - super[assembleMethodSymbol](); - - // initControlReferences.call(self); - initEventHandler.call(this); - - const selector = this.getOption("datasource.selector"); - - if (isString(selector)) { - const elements = document.querySelectorAll(selector); - if (elements.length !== 1) { - throw new Error("the selector must match exactly one element"); - } - - const element = elements[0]; - if (!(element instanceof Datasource)) { - throw new TypeError("the element must be a datasource"); - } - - this[datasourceLinkedElementSymbol] = element; - element.datasource.attachObserver( - new Observer(handleDataSourceChanges.bind(this)), - ); - } - - this.attachObserver( - new Observer(() => { - handleDataSourceChanges.call(this); - }), - ); - } - - /** - * - * @return [CSSStyleSheet] - */ - static getCSSStyleSheet() { - return [DatasetStyleSheet]; - } + /** + * This method is called by the `instanceof` operator. + * @returns {symbol} + */ + static get [instanceSymbol]() { + return Symbol.for("@schukai/monster/components/dataset@@instance"); + } + + /** + * This method determines which attributes are to be monitored by `attributeChangedCallback()`. + * + * @return {string[]} + * @since 1.15.0 + */ + static get observedAttributes() { + const attributes = super.observedAttributes; + attributes.push(ATTRIBUTE_DATATABLE_INDEX); + return attributes; + } + + /** + * To set the options via the html tag the attribute `data-monster-options` must be used. + * @see {@link https://monsterjs.org/en/doc/#configurate-a-monster-control} + * + * The individual configuration values can be found in the table. + * + * @property {Object} templates Template definitions + * @property {string} templates.main Main template + * @property {object} datasource The datasource + * @property {string} datasource.selector The selector of the datasource + * @property {object} mapping The mapping + * @property {string} mapping.data The data + * @property {number} mapping.index The index + * @property {Array} data The data + */ + get defaults() { + const obj = Object.assign({}, super.defaults, { + templates: { + main: getTemplate(), + }, + + datasource: { + selector: null, + }, + + mapping: { + data: "dataset", + index: 0, + }, + + data: {}, + }); + + updateOptionsFromArguments.call(this, obj); + return obj; + } + + /** + * + * @return {string} + */ + static getTag() { + return "monster-dataset"; + } + + write() { + const self = this; + + return new Promise((resolve, reject) => { + + if (!this[datasourceLinkedElementSymbol]) { + reject(new Error("No datasource")); + return; + } + + const internalUpdateCloneData = this.getInternalUpdateCloneData(); + if (!internalUpdateCloneData) { + reject(new Error("No update data")); + return; + } + + const internalData = internalUpdateCloneData?.['data']; + if (internalData === undefined || internalData === null || internalData === "") { + reject(new Error("No data")); + return; + } + + setTimeout(() => { + + const path = self.getOption("mapping.data"); + const index = self.getOption("mapping.index"); + + let pathWithIndex; + + if (isString(path) && path !== "") { + pathWithIndex = path + "." + index; + } else { + pathWithIndex = index; + } + + let data = self[datasourceLinkedElementSymbol].data + const unref = JSON.stringify(data); + let ref = JSON.parse(unref); + + new Pathfinder(ref).setVia(pathWithIndex, internalData); + + + self[datasourceLinkedElementSymbol].data = ref; + + resolve(); + }, 0); + + }); + } + + /** + * This method is responsible for assembling the component. + * + * It calls the parent's assemble method first, then initializes control references and event handlers. + * If the `datasource.selector` option is provided and is a string, it searches for the corresponding + * element in the DOM using that selector. + * + * If the selector matches exactly one element, it checks if the element is an instance of the `Datasource` class. + * + * If it is, the component's `datasourceLinkedElementSymbol` property is set to the element, and the component + * attaches an observer to the datasource's changes. + * + * The observer is a function that calls the `handleDataSourceChanges` method in the context of the component. + * Additionally, the component attaches an observer to itself, which also calls the `handleDataSourceChanges` + * method in the component's context. + */ + [assembleMethodSymbol]() { + super[assembleMethodSymbol](); + + // initControlReferences.call(self); + initEventHandler.call(this); + + const selector = this.getOption("datasource.selector"); + + if (isString(selector)) { + const elements = document.querySelectorAll(selector); + if (elements.length !== 1) { + throw new Error("the selector must match exactly one element"); + } + + const element = elements[0]; + if (!(element instanceof Datasource)) { + throw new TypeError("the element must be a datasource"); + } + + this[datasourceLinkedElementSymbol] = element; + element.datasource.attachObserver( + new Observer(handleDataSourceChanges.bind(this)), + ); + } + + this.attachObserver( + new Observer(() => { + handleDataSourceChanges.call(this); + }), + ); + + } + + /** + * + * @return [CSSStyleSheet] + */ + static getCSSStyleSheet() { + return [FormStyleSheet,DatasetStyleSheet]; + } } /** * @private */ function initEventHandler() { - this[attributeObserverSymbol][ATTRIBUTE_DATATABLE_INDEX] = () => { - const index = this.getAttribute(ATTRIBUTE_DATATABLE_INDEX); - if (index) { - this.setOption("mapping.index", parseInt(index, 10)); - } - }; + this[attributeObserverSymbol][ATTRIBUTE_DATATABLE_INDEX] = () => { + const index = this.getAttribute(ATTRIBUTE_DATATABLE_INDEX); + if (index) { + this.setOption("mapping.index", parseInt(index, 10)); + } + }; } /** * - * @param {Onject} options + * @param {Object} options */ function updateOptionsFromArguments(options) { - const index = this.getAttribute(ATTRIBUTE_DATATABLE_INDEX); + const index = this.getAttribute(ATTRIBUTE_DATATABLE_INDEX); - if (index !== null && index !== undefined) { - options.mapping.index = parseInt(index, 10); - } + if (index !== null && index !== undefined) { + options.mapping.index = parseInt(index, 10); + } - const selector = this.getAttribute(ATTRIBUTE_DATASOURCE_SELECTOR); + const selector = this.getAttribute(ATTRIBUTE_DATASOURCE_SELECTOR); - if (selector) { - options.datasource.selector = selector; - } + if (selector) { + options.datasource.selector = selector; + } } /** @@ -206,8 +279,8 @@ function updateOptionsFromArguments(options) { * @return {string} */ function getTemplate() { - // language=HTML - return ` + // language=HTML + return ` <div data-monster-role="control" part="control"> <slot></slot> </div> diff --git a/source/components/datatable/datasource.mjs b/source/components/datatable/datasource.mjs index 363c28275e0f78763583eabeb8c16bb7edf96779..c1c538d777eff7dbceeef2619db758f752f27f99 100644 --- a/source/components/datatable/datasource.mjs +++ b/source/components/datatable/datasource.mjs @@ -99,4 +99,12 @@ class Datasource extends CustomElement { get datasource() { return this[dataSourceSymbol]; } + + write() { + this[dataSourceSymbol].write(); + } + + read() { + this[dataSourceSymbol].read(); + } } diff --git a/source/components/datatable/datasource/dom.mjs b/source/components/datatable/datasource/dom.mjs index c91ebef096f5555187f997754537660ff9e2ead7..a488190bce242915b8fbd26c23628b362a2dcdf0 100644 --- a/source/components/datatable/datasource/dom.mjs +++ b/source/components/datatable/datasource/dom.mjs @@ -46,7 +46,7 @@ class Dom extends Datasource { * @returns {symbol} */ static get [instanceSymbol]() { - return Symbol.for("@schukai/monster/components/datasource/dom"); + return Symbol.for("@schukai/monster/components/datasource/dom@@instance"); } /** diff --git a/source/components/datatable/datasource/rest.mjs b/source/components/datatable/datasource/rest.mjs index a0470a2e9351602e9bf11aba3b99307b0d3725bb..ab0c144e9e553d7873877f84fef15e5b962322c9 100644 --- a/source/components/datatable/datasource/rest.mjs +++ b/source/components/datatable/datasource/rest.mjs @@ -293,6 +293,59 @@ class Rest extends Datasource { super.disconnectedCallback(); removeFilter.call(this); } + + + read() { + return this.fetch(); + } + + + /** + * Fetches the data from the rest api + * @returns {Promise<never>|*} + */ + write() { + const opt = clone(this.getOption("write")); + this[dataSourceSymbol].setOption("write", opt); + + let url = this.getOption("write.url"); + const formatter = new Formatter(this.getOption("write.parameters")); + + if (!url) { + return Promise.reject(new Error("No url defined")); + } + + url = formatter.format(url); + + this[dataSourceSymbol].setOption("write.url", url); + + return new Promise((resolve, reject) => { + fireCustomEvent(this, "monster-datasource-fetch", { + datasource: this, + }); + + setTimeout(() => { + this[dataSourceSymbol] + .write() + .then((response) => { + fireCustomEvent(this, "monster-datasource-fetched", { + datasource: this, + }); + + resolve(response); + }) + .catch((error) => { + fireCustomEvent(this, "monster-datasource-error", { + error: error, + }); + + addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, error.toString()); + reject(error); + }); + }, 0); + }); + } + } /** @@ -356,7 +409,7 @@ function initFilter() { return Promise.reject(e); } - return handleIntersectionObserver.call(this,json, response, filterControl); + return handleIntersectionObserver.call(this, json, response, filterControl); }) @@ -426,6 +479,7 @@ function initAutoInit() { } function initEventHandler() { + this[intersectionObserverHandlerSymbol] = (entries) => { entries.forEach((entry) => { if (entry.isIntersecting) { diff --git a/source/components/datatable/filter/range.mjs b/source/components/datatable/filter/range.mjs index 42846b90f2701ec6fa7619252127524299e8800c..3305ce34c19f5c2218c2e3584b7466bb6b8d609f 100644 --- a/source/components/datatable/filter/range.mjs +++ b/source/components/datatable/filter/range.mjs @@ -402,9 +402,7 @@ function initEventHandler() { this.addEventListener("keydown", (event) => { // if key code esc than hide dialog if (event.key === "Escape") { - console.log("esc"); hide.call(this); - setTimeout(() => { this[inputElementSymbol].focus(); }, 10); @@ -417,7 +415,7 @@ function initEventHandler() { "data-monster-role", "input", ); - console.log(input, event, event.keyCode); + if (!input) { return; } diff --git a/source/components/datatable/save-button.mjs b/source/components/datatable/save-button.mjs new file mode 100644 index 0000000000000000000000000000000000000000..808237fafdc41cc4113e1eecf3826ab2561b27a6 --- /dev/null +++ b/source/components/datatable/save-button.mjs @@ -0,0 +1,298 @@ +/** + * Copyright 2023 schukai GmbH + * SPDX-License-Identifier: AGPL-3.0 + */ + +import {instanceSymbol, internalSymbol} from "../../constants.mjs"; +import {diff} from "../../data/diff.mjs"; +import { + assembleMethodSymbol, + CustomElement, + attributeObserverSymbol, + registerCustomElement, +} from "../../dom/customelement.mjs"; +import {isString, isArray} from "../../types/is.mjs"; +import {Observer} from "../../types/observer.mjs"; +import {TokenList} from "../../types/tokenlist.mjs"; +import {clone} from "../../util/clone.mjs"; +import {State} from "../form/types/state.mjs"; +import { + ATTRIBUTE_DATASOURCE_SELECTOR, +} from "./constants.mjs"; +import {Datasource} from "./datasource.mjs"; +import {BadgeStyleSheet} from "../stylesheet/badge.mjs"; +import {SaveButtonStyleSheet} from "./stylesheet/save-button.mjs"; + +import { + handleDataSourceChanges, + datasourceLinkedElementSymbol, +} from "./util.mjs"; + + +export {SaveButton}; + + +/** + * @private + * @type {symbol} + */ +const stateButtonElementSymbol = Symbol("stateButtonElement"); + + +/** + * @private + * @type {symbol} + */ +const badgeElementSymbol = Symbol("badgeElement"); + + +class SaveButton extends CustomElement { + /** + * This method is called by the `instanceof` operator. + * @returns {symbol} + */ + static get [instanceSymbol]() { + return Symbol.for("@schukai/monster/components/datasource/save-button@@instance"); + } + + /** + * To set the options via the html tag the attribute `data-monster-options` must be used. + * @see {@link https://monsterjs.org/en/doc/#configurate-a-monster-control} + * + * The individual configuration values can be found in the table. + * + * @property {Object} templates Template definitions + * @property {string} templates.main Main template + * @property {object} datasource The datasource + * @property {string} datasource.selector The selector of the datasource + * @property {object} mapping The mapping + * @property {string} mapping.data The data + * @property {number} mapping.index The index + * @property {Array} data The data + * @return {Object} + */ + get defaults() { + const obj = Object.assign({}, super.defaults, { + templates: { + main: getTemplate(), + }, + + labels: { + button: "save", + }, + + classes: { + bar: "monster-button-primary", + badge: "monster-badge-secondary hidden", + }, + + datasource: { + selector: null, + }, + + changes: "0", + + mapping: { + data: "dataset", + index: 0, + }, + + data: {}, + + disabled: false, + }); + + updateOptionsFromArguments.call(this, obj); + return obj; + } + + /** + * + * @return {string} + */ + static getTag() { + return "monster-datasource-save-button"; + } + + + /** + * This method is responsible for assembling the component. + * + * It calls the parent's assemble method first, then initializes control references and event handlers. + * If the `datasource.selector` option is provided and is a string, it searches for the corresponding + * element in the DOM using that selector. + * + * If the selector matches exactly one element, it checks if the element is an instance of the `Datasource` class. + * + * If it is, the component's `datasourceLinkedElementSymbol` property is set to the element, and the component + * attaches an observer to the datasource's changes. + * + * The observer is a function that calls the `handleDataSourceChanges` method in the context of the component. + * Additionally, the component attaches an observer to itself, which also calls the `handleDataSourceChanges` + * method in the component's context. + */ + [assembleMethodSymbol]() { + super[assembleMethodSymbol](); + const self = this; + + initControlReferences.call(this); + initEventHandler.call(this); + + const selector = this.getOption("datasource.selector"); + + if (isString(selector)) { + const elements = document.querySelectorAll(selector); + if (elements.length !== 1) { + throw new Error("the selector must match exactly one element"); + } + + const element = elements[0]; + if (!(element instanceof Datasource)) { + throw new TypeError("the element must be a datasource"); + } + + this[datasourceLinkedElementSymbol] = element; + element.datasource.attachObserver( + new Observer(handleDataSourceChanges.bind(this)), + ); + + let originValues; + + element.datasource.attachObserver( + new Observer(function () { + + if (!originValues) { + originValues = clone(self[datasourceLinkedElementSymbol].data); + } + + let currentValues = this.getRealSubject(); + + const result = diff(originValues, currentValues); + if (isArray(result) && result.length > 0) { + self[stateButtonElementSymbol].setState("changed"); + self[stateButtonElementSymbol].setOption("disabled", false); + self.setOption("changes", result.length); + self.setOption("classes.badge", new TokenList(self.getOption("classes.badge")).remove("hidden").toString()) + + } else { + self[stateButtonElementSymbol].removeState(); + self[stateButtonElementSymbol].setOption("disabled", true); + self.setOption("changes", 0); + self.setOption("classes.badge", new TokenList(self.getOption("classes.badge")).add("hidden").toString()) + } + + + }), + ); + } + + this.attachObserver( + new Observer(() => { + handleDataSourceChanges.call(this); + }), + ); + + } + + /** + * + * @return [CSSStyleSheet] + */ + static getCSSStyleSheet() { + return [SaveButtonStyleSheet, BadgeStyleSheet]; + } +} + +/** + * @private + * @return {Monster.Components.Datatable.Form} + */ +function initControlReferences() { + if (!this.shadowRoot) { + throw new Error("no shadow-root is defined"); + } + + this[stateButtonElementSymbol] = this.shadowRoot.querySelector( + "[data-monster-role=state-button]" + ); + + this[badgeElementSymbol] = this.shadowRoot.querySelector( + "[data-monster-role=badge]" + ); + + if (this[stateButtonElementSymbol]) { + setTimeout(() => { + const states = { + "changed": new State( + "changed", + '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-cloud-arrow-up" viewBox="0 0 16 16">\n' + + ' <path fill-rule="evenodd" d="M7.646 5.146a.5.5 0 0 1 .708 0l2 2a.5.5 0 0 1-.708.708L8.5 6.707V10.5a.5.5 0 0 1-1 0V6.707L6.354 7.854a.5.5 0 1 1-.708-.708z"/>\n' + + ' <path d="M4.406 3.342A5.53 5.53 0 0 1 8 2c2.69 0 4.923 2 5.166 4.579C14.758 6.804 16 8.137 16 9.773 16 11.569 14.502 13 12.687 13H3.781C1.708 13 0 11.366 0 9.318c0-1.763 1.266-3.223 2.942-3.593.143-.863.698-1.723 1.464-2.383m.653.757c-.757.653-1.153 1.44-1.153 2.056v.448l-.445.049C2.064 6.805 1 7.952 1 9.318 1 10.785 2.23 12 3.781 12h8.906C13.98 12 15 10.988 15 9.773c0-1.216-1.02-2.228-2.313-2.228h-.5v-.5C12.188 4.825 10.328 3 8 3a4.53 4.53 0 0 0-2.941 1.1z"/>\n' + + '</svg>', + ) + } + + this[stateButtonElementSymbol].removeState(); + this[stateButtonElementSymbol].setOption("disabled", 'disabled'); + this[stateButtonElementSymbol].setOption("states", states); + this[stateButtonElementSymbol].setOption("labels.button", this.getOption("labels.button")); + + }, 1); + + } + + + return this; +} + +/** + * @private + */ +function initEventHandler() { + + setTimeout(() => { + this[stateButtonElementSymbol].setOption("actions.click", () => { + this[datasourceLinkedElementSymbol].write().then(() => { + this[stateButtonElementSymbol].removeState(); + this[stateButtonElementSymbol].setOption("disabled", true); + this.setOption("changes", 0); + this.setOption("classes.badge", new TokenList(this.getOption("classes.badge")).add("hidden").toString()) + }).catch((error) => { + console.error(error); + }) + }); + }, 1); + + + +} + +/** + * @param {Object} options + */ +function updateOptionsFromArguments(options) { + const selector = this.getAttribute(ATTRIBUTE_DATASOURCE_SELECTOR); + if (selector) { + options.datasource.selector = selector; + } +} + +/** + * @private + * @return {string} + */ +function getTemplate() { + // language=HTML + return ` + <div data-monster-role="control" part="control" + data-monster-attributes="disabled path:disabled | if:true"> + <monster-state-button data-monster-role="state-button">save</monster-state-button> + <div data-monster-attributes="disabled path:disabled | if:true, class path:classes.badge" + data-monster-role="badge" + data-monster-replace="path:changes"></div> + </div> + `; +} + +registerCustomElement(SaveButton); + diff --git a/source/components/datatable/status.mjs b/source/components/datatable/status.mjs index abb4f38dea8be96c2714d3ae7783ec1f64855e0e..7d09fb15ce813a1848606ed77fb8140607819f88 100644 --- a/source/components/datatable/status.mjs +++ b/source/components/datatable/status.mjs @@ -79,7 +79,7 @@ class DatasourceStatus extends CustomElement { * @returns {symbol} */ static get [instanceSymbol]() { - return Symbol.for("@schukai/monster/components/datatables/status"); + return Symbol.for("@schukai/monster/components/datatables/status@@instance"); } /** @@ -181,6 +181,7 @@ function initEventHandler() { element.addEventListener("monster-datasource-fetch", function () { self.setOption("state.spinner", "show"); }); + element.addEventListener("monster-datasource-error", function (event) { self.setOption("state.spinner", "hide"); @@ -214,7 +215,8 @@ function initEventHandler() { function getTemplate() { // language=HTML return ` - <div data-monster-role="control"> + <div data-monster-role="control" part="control" + data-monster-attributes="disabled path:disabled | if:true"> <monster-context-error data-monster-option-classes-button="monster-theme-error-2 monster-bg-color-primary-2"></monster-context-error> <div class="monster-spinner monster-theme-primary-4" diff --git a/source/components/datatable/style/change-button.pcss b/source/components/datatable/style/change-button.pcss new file mode 100644 index 0000000000000000000000000000000000000000..feb26b95c06678e8edda4b3a8bd5609ee3e5d2dc --- /dev/null +++ b/source/components/datatable/style/change-button.pcss @@ -0,0 +1,19 @@ +@import "../../style/normalize.pcss"; +@import "../../style/display.pcss"; +@import "../../style/mixin/button.pcss"; +@import "../../style/button.pcss"; +@import "../../style/mixin/typography.pcss"; +@import "../../style/mixin/hover.pcss"; +@import "../../style/control.pcss"; +@import "../../style/property.pcss"; +@import "../../style/ripple.pcss"; + + +[data-monster-role=control] { + + +} + +:host { + +} diff --git a/source/components/datatable/style/save-button.pcss b/source/components/datatable/style/save-button.pcss new file mode 100644 index 0000000000000000000000000000000000000000..50c7f4c95c55a73c6ac7b7f91d66e59fbf9e1989 --- /dev/null +++ b/source/components/datatable/style/save-button.pcss @@ -0,0 +1,44 @@ +@import "../../style/normalize.pcss"; +@import "../../style/display.pcss"; +@import "../../style/mixin/button.pcss"; +@import "../../style/button.pcss"; +@import "../../style/mixin/typography.pcss"; +@import "../../style/mixin/hover.pcss"; +@import "../../style/control.pcss"; +@import "../../style/property.pcss"; +@import "../../style/ripple.pcss"; + + +[data-monster-role=control] { + position: relative; + align-items: center; + display: flex; + flex-direction: row; + justify-content: center; + flex-wrap: nowrap; + width: fit-content; + + + & [data-monster-role=badge] { + z-index: var(--monster-z-index-sticky); + position: absolute; + top: 0; + left: 0; + transform: translate(-4px, -7px); + + &.hidden { + display: none !important; + } + } + +} + +:host { + align-items: center; + display: flex; + flex-direction: row; + justify-content: center; + flex-wrap: nowrap; + width: fit-content; + align-self: center; +} diff --git a/source/components/datatable/stylesheet/change-button.mjs b/source/components/datatable/stylesheet/change-button.mjs new file mode 100644 index 0000000000000000000000000000000000000000..e1a254db0b036ee0a391f4c6056c4cb71e0e0448 --- /dev/null +++ b/source/components/datatable/stylesheet/change-button.mjs @@ -0,0 +1,27 @@ + +/** + * Copyright schukai GmbH and contributors 2024. All Rights Reserved. + * Node module: @schukai/monster + * This file is licensed under the AGPLv3 License. + * License text available at https://www.gnu.org/licenses/agpl-3.0.en.html + */ + +import {addAttributeToken} from "../../../dom/attributes.mjs"; +import {ATTRIBUTE_ERRORMESSAGE} from "../../../dom/constants.mjs"; + +export {ChangeButtonStyleSheet} + +/** + * @private + * @type {CSSStyleSheet} + */ +const ChangeButtonStyleSheet = new CSSStyleSheet(); + +try { + ChangeButtonStyleSheet.insertRule(` +@layer changebutton { +:where(html){line-height:1.15;-webkit-text-size-adjust:100%;-moz-text-size-adjust:100%;text-size-adjust:100%}:where(h1){font-size:2em;margin-block-end:.67em;margin-block-start:.67em}:where(dl,ol,ul) :where(dl,ol,ul){margin-block-end:0;margin-block-start:0}:where(hr){box-sizing:content-box;color:inherit;height:0}:where(abbr[title]){text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted}:where(b,strong){font-weight:bolder}:where(code,kbd,pre,samp){font-family:monospace,monospace;font-size:1em}:where(small){font-size:80%}:where(table){border-color:currentColor;text-indent:0}:where(button,input,select){margin:0}:where(button){text-transform:none}:where(button,input:is([type=button i],[type=reset i],[type=submit i])){-webkit-appearance:button}:where(progress){vertical-align:baseline}:where(select){text-transform:none}:where(textarea){margin:0}:where(input[type=search i]){-webkit-appearance:textfield;outline-offset:-2px}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}::-webkit-input-placeholder{color:inherit;opacity:.54}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}:where(button,input:is([type=button i],[type=color i],[type=reset i],[type=submit i]))::-moz-focus-inner{border-style:none;padding:0}:where(button,input:is([type=button i],[type=color i],[type=reset i],[type=submit i]))::-moz-focusring{outline:1px dotted ButtonText}:where(:-moz-ui-invalid){box-shadow:none}:where(dialog){background-color:#fff;border:solid;color:#000;height:-moz-fit-content;height:fit-content;left:0;margin:auto;padding:1em;position:absolute;right:0;width:-moz-fit-content;width:fit-content}:where(dialog:not([open])){display:none}:where(summary){display:list-item}html{height:100%}body,html{min-height:calc(100vh - 40px)}body{box-sizing:border-box;margin:0;padding:0;word-break:break-word}.block{display:block}.inline{display:inline}.inline-block{display:inline-block}.grid{display:grid}.inline-grid{display:inline-grid}.flex{display:flex}.inline-flex{display:inline-flex}.hidden,.hide,.none{display:none}.visible{visibility:visible}.invisible{visibility:hidden}.monster-button-primary,button{align-items:center;background-position:50%;border-radius:var(--monster-border-radius);border-style:var(--monster-border-style);border-width:var(--monster-border-width);box-shadow:var(--monster-box-shadow-1);cursor:pointer;display:flex;font-family:var(--monster-font-family);font-size:1rem;font-weight:400;gap:.4rem;justify-content:center;line-height:1.5;outline:none;overflow:hidden;padding:.375rem .75rem;position:relative;text-align:center;text-decoration:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;vertical-align:middle;width:-webkit-fill-available;width:-moz-available;width:stretch}.monster-button-primary{background-color:var(--monster-bg-color-primary-4);border-color:var(--monster-bg-color-primary-4);color:var(--monster-color-primary-4)}.monster-button-secondary{background-color:var(--monster-bg-color-secondary-4);border-color:var(--monster-bg-color-secondary-4);border-radius:var(--monster-border-radius);border-style:var(--monster-border-style);border-width:var(--monster-border-width);color:var(--monster-color-secondary-4)}.monster-button-secondary,.monster-button-tertiary{align-items:center;background-position:50%;box-shadow:var(--monster-box-shadow-1);cursor:pointer;display:flex;font-family:var(--monster-font-family);font-size:1rem;font-weight:400;gap:.4rem;justify-content:center;line-height:1.5;outline:none;overflow:hidden;padding:.375rem .75rem;position:relative;text-align:center;text-decoration:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;vertical-align:middle;width:-webkit-fill-available;width:-moz-available;width:stretch}.monster-button-tertiary{background-color:var(--monster-bg-color-tertiary-4);border-color:var(--monster-bg-color-tertiary-4);border-radius:var(--monster-border-radius);border-style:var(--monster-border-style);border-width:var(--monster-border-width);color:var(--monster-color-tertiary-4)}.monster-button-outline-primary{background-color:var(--monster-color-primary-4);border-color:var(--monster-bg-color-primary-4);border-radius:var(--monster-border-radius);border-style:var(--monster-border-style);border-width:var(--monster-border-width);color:var(--monster-bg-color-primary-4)}.monster-button-outline-primary,.monster-button-outline-secondary{align-items:center;background-position:50%;box-shadow:var(--monster-box-shadow-1);cursor:pointer;display:flex;font-family:var(--monster-font-family);font-size:1rem;font-weight:400;gap:.4rem;justify-content:center;line-height:1.5;outline:none;overflow:hidden;padding:.375rem .75rem;position:relative;text-align:center;text-decoration:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;vertical-align:middle;width:-webkit-fill-available;width:-moz-available;width:stretch}.monster-button-outline-secondary{background-color:var(--monster-color-secondary-4);border-color:var(--monster-bg-color-secondary-4);border-radius:var(--monster-border-radius);border-style:var(--monster-border-style);border-width:var(--monster-border-width);color:var(--monster-bg-color-secondary-4)}.monster-button-outline-tertiary{align-items:center;background-color:var(--monster-color-tertiary-4);background-position:50%;border-color:var(--monster-bg-color-tertiary-4);border-radius:var(--monster-border-radius);border-style:var(--monster-border-style);border-width:var(--monster-border-width);box-shadow:var(--monster-box-shadow-1);color:var(--monster-bg-color-tertiary-4);cursor:pointer;display:flex;font-family:var(--monster-font-family);font-size:1rem;font-weight:400;gap:.4rem;justify-content:center;line-height:1.5;outline:none;overflow:hidden;padding:.375rem .75rem;position:relative;text-align:center;text-decoration:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;vertical-align:middle;width:-webkit-fill-available;width:-moz-available;width:stretch}button:active,button:hover{box-shadow:var(--monster-box-shadow-2);transition:background .8s,color .25s .0833333333s}button:active{z-index:var(--monster-z-index-outline)}.monster-button-bar,.monster-button-group{align-content:center;align-items:stretch;display:flex;flex-direction:row;flex-wrap:nowrap;justify-content:space-between}.monster-button-group{box-sizing:border-box;gap:0;margin:1rem 0}.monster-button-group>:not(:last-child){margin-right:calc(var(--monster-border-width)*-1)}.monster-button-group :hover{box-shadow:none}button:focus{outline:1px dashed var(--monster-color-selection-4);outline-offset:2px;z-index:var(--monster-z-index-outline)}@media (prefers-color-scheme:light){button:focus{outline:1px dashed var(--monster-color-selection-3);outline-offset:2px;z-index:var(--monster-z-index-outline)}}[data-monster-role=control]{outline:none;width:100%}[data-monster-role=control].flex{align-items:center;display:flex;flex-direction:row}:after,:before,:root{--monster-font-family:-apple-system,BlinkMacSystemFont,\"Quicksand\",\"Segoe UI\",\"Roboto\",\"Oxygen\",\"Ubuntu\",\"Cantarell\",\"Fira Sans\",\"Droid Sans\",\"Helvetica Neue\",Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\",\"Segoe UI Symbol\";--monster-color-primary-1:var(--monster-color-gray-6);--monster-color-primary-2:var(--monster-color-gray-6);--monster-color-primary-3:var(--monster-color-gray-1);--monster-color-primary-4:var(--monster-color-gray-1);--monster-bg-color-primary-1:var(--monster-color-gray-1);--monster-bg-color-primary-2:var(--monster-color-gray-2);--monster-bg-color-primary-3:var(--monster-color-gray-3);--monster-bg-color-primary-4:var(--monster-color-gray-6);--monster-color-secondary-1:var(--monster-color-red-4);--monster-color-secondary-2:var(--monster-color-red-4);--monster-color-secondary-3:var(--monster-color-red-1);--monster-color-secondary-4:var(--monster-color-red-1);--monster-bg-color-secondary-1:var(--monster-color-gray-1);--monster-bg-color-secondary-2:var(--monster-color-red-2);--monster-bg-color-secondary-3:var(--monster-color-red-3);--monster-bg-color-secondary-4:var(--monster-color-red-6);--monster-color-tertiary-1:var(--monster-color-magenta-4);--monster-color-tertiary-2:var(--monster-color-magenta-4);--monster-color-tertiary-3:var(--monster-color-magenta-6);--monster-color-tertiary-4:var(--monster-color-magenta-1);--monster-bg-color-tertiary-1:var(--monster-color-gray-1);--monster-bg-color-tertiary-2:var(--monster-color-magenta-1);--monster-bg-color-tertiary-3:var(--monster-color-magenta-2);--monster-bg-color-tertiary-4:var(--monster-color-magenta-6);--monster-color-destructive-1:var(--monster-color-red-1);--monster-color-destructive-2:var(--monster-color-red-4);--monster-color-destructive-3:var(--monster-color-red-6);--monster-color-destructive-4:var(--monster-color-red-1);--monster-bg-color-destructive-1:var(--monster-color-red-4);--monster-bg-color-destructive-2:var(--monster-color-gray-1);--monster-bg-color-destructive-3:var(--monster-color-red-2);--monster-bg-color-destructive-4:var(--monster-color-red-5);--monster-color-success-1:var(--monster-color-green-1);--monster-color-success-2:var(--monster-color-green-4);--monster-color-success-3:var(--monster-color-green-6);--monster-color-success-4:var(--monster-color-green-1);--monster-bg-color-success-1:var(--monster-color-green-3);--monster-bg-color-success-2:var(--monster-color-gray-1);--monster-bg-color-success-3:var(--monster-color-green-2);--monster-bg-color-success-4:var(--monster-color-green-5);--monster-color-warning-1:var(--monster-color-orange-1);--monster-color-warning-2:var(--monster-color-orange-4);--monster-color-warning-3:var(--monster-color-orange-6);--monster-color-warning-4:var(--monster-color-orange-1);--monster-bg-color-warning-1:var(--monster-color-orange-3);--monster-bg-color-warning-2:var(--monster-color-gray-1);--monster-bg-color-warning-3:var(--monster-color-orange-2);--monster-bg-color-warning-4:var(--monster-color-orange-5);--monster-color-error-1:var(--monster-color-red-1);--monster-color-error-2:var(--monster-color-red-4);--monster-color-error-3:var(--monster-color-red-6);--monster-color-error-4:var(--monster-color-red-1);--monster-bg-color-error-1:var(--monster-color-red-4);--monster-bg-color-error-2:var(--monster-color-gray-1);--monster-bg-color-error-3:var(--monster-color-red-2);--monster-bg-color-error-4:var(--monster-color-red-5);--monster-color-selection-1:var(--monster-color-gray-6);--monster-color-selection-2:var(--monster-color-gray-6);--monster-color-selection-3:var(--monster-color-gray-6);--monster-color-selection-4:var(--monster-color-gray-1);--monster-bg-color-selection-1:var(--monster-color-yellow-2);--monster-bg-color-selection-2:var(--monster-color-yellow-1);--monster-bg-color-selection-3:var(--monster-color-yellow-2);--monster-bg-color-selection-4:var(--monster-color-yellow-6);--monster-color-primary-disabled-1:var(--monster-color-gray-3);--monster-color-primary-disabled-2:var(--monster-color-gray-1);--monster-color-primary-disabled-3:var(--monster-color-gray-4);--monster-color-primary-disabled-4:var(--monster-color-gray-4);--monster-bg-color-primary-disabled-1:var(--monster-color-gray-1);--monster-bg-color-primary-disabled-2:var(--monster-color-gray-2);--monster-bg-color-primary-disabled-3:var(--monster-color-gray-3);--monster-bg-color-primary-disabled-4:var(--monster-color-gray-6);--monster-color-gradient-1:#833ab4;--monster-color-gradient-2:#fd1d1d;--monster-color-gradient-3:#fcb045;--monster-box-shadow-1:none;--monster-box-shadow-2:-1px 1px 10px 1px hsla(0,0%,76%,.61);--monster-text-shadow:none;--monster-border-style:solid;--monster-border-width:2px;--monster-border-radius:0;--monster-popper-witharrrow-distance:-4px;--monster-z-index-default:0;--monster-z-index-outline:10;--monster-z-index-dropdown:200;--monster-z-index-dropdown-overlay:210;--monster-z-index-sticky:300;--monster-z-index-sticky-overlay:310;--monster-z-index-fixed:400;--monster-z-index-fixed-overlay:410;--monster-z-index-modal-backdrop:500;--monster-z-index-modal-backdrop-overlay:510;--monster-z-index-offcanvas:600;--monster-z-index-offcanvas-overlay:610;--monster-z-index-modal:700;--monster-z-index-modal-overlay:710;--monster-z-index-popover:800;--monster-z-index-popover-overlay:810;--monster-z-index-tooltip:800;--monster-z-index-tooltip-overlay:910;--monster-space-0:0;--monster-space-1:2px;--monster-space-2:4px;--monster-space-3:6px;--monster-space-4:10px;--monster-space-5:16px;--monster-space-6:26px;--monster-space-7:42px;--monster-breakpoint-0:480px;--monster-breakpoint-4:480px;--monster-breakpoint-7:768px;--monster-breakpoint-9:992px;--monster-breakpoint-12:1200px}@media (prefers-color-scheme:dark){:after,:before,:root{--monster-color-primary-1:var(--monster-color-gray-1);--monster-color-primary-2:var(--monster-color-gray-1);--monster-color-primary-3:var(--monster-color-gray-6);--monster-color-primary-4:var(--monster-color-gray-6);--monster-bg-color-primary-1:var(--monster-color-gray-6);--monster-bg-color-primary-2:var(--monster-color-gray-3);--monster-bg-color-primary-3:var(--monster-color-gray-2);--monster-bg-color-primary-4:var(--monster-color-gray-1);--monster-color-secondary-1:var(--monster-color-red-1);--monster-color-secondary-2:var(--monster-color-red-1);--monster-color-secondary-3:var(--monster-color-red-6);--monster-color-secondary-4:var(--monster-color-red-4);--monster-bg-color-secondary-1:var(--monster-color-gray-6);--monster-bg-color-secondary-2:var(--monster-color-red-3);--monster-bg-color-secondary-3:var(--monster-color-red-2);--monster-bg-color-secondary-4:var(--monster-color-red-1);--monster-color-tertiary-1:var(--monster-color-magenta-1);--monster-color-tertiary-2:var(--monster-color-magenta-6);--monster-color-tertiary-3:var(--monster-color-magenta-4);--monster-color-tertiary-4:var(--monster-color-magenta-4);--monster-bg-color-tertiary-1:var(--monster-color-gray-6);--monster-bg-color-tertiary-2:var(--monster-color-magenta-2);--monster-bg-color-tertiary-3:var(--monster-color-magenta-1);--monster-bg-color-tertiary-4:var(--monster-color-magenta-1);--monster-color-destructive-1:var(--monster-color-red-1);--monster-color-destructive-2:var(--monster-color-red-3);--monster-color-destructive-3:var(--monster-color-red-4);--monster-color-destructive-4:var(--monster-color-red-1);--monster-bg-color-destructive-1:var(--monster-color-red-5);--monster-bg-color-destructive-2:var(--monster-color-gray-6);--monster-bg-color-destructive-3:var(--monster-color-red-1);--monster-bg-color-destructive-4:var(--monster-color-red-4);--monster-color-success-1:var(--monster-color-green-1);--monster-color-success-2:var(--monster-color-green-2);--monster-color-success-3:var(--monster-color-green-4);--monster-color-success-4:var(--monster-color-green-1);--monster-bg-color-success-1:var(--monster-color-green-5);--monster-bg-color-success-2:var(--monster-color-gray-6);--monster-bg-color-success-3:var(--monster-color-green-1);--monster-bg-color-success-4:var(--monster-color-green-3);--monster-color-warning-1:var(--monster-color-orange-1);--monster-color-warning-2:var(--monster-color-orange-3);--monster-color-warning-3:var(--monster-color-orange-4);--monster-color-warning-4:var(--monster-color-orange-1);--monster-bg-color-warning-1:var(--monster-color-orange-5);--monster-bg-color-warning-2:var(--monster-color-gray-6);--monster-bg-color-warning-3:var(--monster-color-orange-1);--monster-bg-color-warning-4:var(--monster-color-orange-3);--monster-color-error-1:var(--monster-color-red-1);--monster-color-error-2:var(--monster-color-red-3);--monster-color-error-3:var(--monster-color-red-4);--monster-color-error-4:var(--monster-color-red-1);--monster-bg-color-error-1:var(--monster-color-red-5);--monster-bg-color-error-2:var(--monster-color-gray-6);--monster-bg-color-error-3:var(--monster-color-red-1);--monster-bg-color-error-4:var(--monster-color-red-4);--monster-color-selection-1:var(--monster-color-gray-6);--monster-color-selection-2:var(--monster-color-gray-6);--monster-color-selection-3:var(--monster-color-gray-6);--monster-color-selection-4:var(--monster-color-gray-1);--monster-bg-color-selection-1:var(--monster-color-yellow-2);--monster-bg-color-selection-2:var(--monster-color-yellow-1);--monster-bg-color-selection-3:var(--monster-color-yellow-2);--monster-bg-color-selection-4:var(--monster-color-yellow-6);--monster-color-primary-disabled-1:var(--monster-color-gray-4);--monster-color-primary-disabled-2:var(--monster-color-gray-4);--monster-color-primary-disabled-3:var(--monster-color-gray-3);--monster-color-primary-disabled-4:var(--monster-color-gray-3);--monster-bg-color-primary-disabled-1:var(--monster-color-gray-6);--monster-bg-color-primary-disabled-2:var(--monster-color-gray-3);--monster-bg-color-primary-disabled-3:var(--monster-color-gray-2);--monster-bg-color-primary-disabled-4:var(--monster-color-gray-1)}}span.monster-fx-ripple{animation:monster-fx-ripple .6s linear;background-color:hsla(0,0%,100%,.7);border-radius:50%;position:absolute;transform:scale(0)}@keyframes monster-fx-ripple{to{opacity:0;transform:scale(4)}} +}`, 0); +} catch (e) { + addAttributeToken(document.getRootNode().querySelector('html'), ATTRIBUTE_ERRORMESSAGE, e + ""); +} diff --git a/source/components/datatable/stylesheet/save-button.mjs b/source/components/datatable/stylesheet/save-button.mjs new file mode 100644 index 0000000000000000000000000000000000000000..53e96998a4be8c9af4b3d2dcb8628185a3d19b3e --- /dev/null +++ b/source/components/datatable/stylesheet/save-button.mjs @@ -0,0 +1,27 @@ + +/** + * Copyright schukai GmbH and contributors 2024. All Rights Reserved. + * Node module: @schukai/monster + * This file is licensed under the AGPLv3 License. + * License text available at https://www.gnu.org/licenses/agpl-3.0.en.html + */ + +import {addAttributeToken} from "../../../dom/attributes.mjs"; +import {ATTRIBUTE_ERRORMESSAGE} from "../../../dom/constants.mjs"; + +export {SaveButtonStyleSheet} + +/** + * @private + * @type {CSSStyleSheet} + */ +const SaveButtonStyleSheet = new CSSStyleSheet(); + +try { + SaveButtonStyleSheet.insertRule(` +@layer savebutton { +:where(html){line-height:1.15;-webkit-text-size-adjust:100%;-moz-text-size-adjust:100%;text-size-adjust:100%}:where(h1){font-size:2em;margin-block-end:.67em;margin-block-start:.67em}:where(dl,ol,ul) :where(dl,ol,ul){margin-block-end:0;margin-block-start:0}:where(hr){box-sizing:content-box;color:inherit;height:0}:where(abbr[title]){text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted}:where(b,strong){font-weight:bolder}:where(code,kbd,pre,samp){font-family:monospace,monospace;font-size:1em}:where(small){font-size:80%}:where(table){border-color:currentColor;text-indent:0}:where(button,input,select){margin:0}:where(button){text-transform:none}:where(button,input:is([type=button i],[type=reset i],[type=submit i])){-webkit-appearance:button}:where(progress){vertical-align:baseline}:where(select){text-transform:none}:where(textarea){margin:0}:where(input[type=search i]){-webkit-appearance:textfield;outline-offset:-2px}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}::-webkit-input-placeholder{color:inherit;opacity:.54}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}:where(button,input:is([type=button i],[type=color i],[type=reset i],[type=submit i]))::-moz-focus-inner{border-style:none;padding:0}:where(button,input:is([type=button i],[type=color i],[type=reset i],[type=submit i]))::-moz-focusring{outline:1px dotted ButtonText}:where(:-moz-ui-invalid){box-shadow:none}:where(dialog){background-color:#fff;border:solid;color:#000;height:-moz-fit-content;height:fit-content;left:0;margin:auto;padding:1em;position:absolute;right:0;width:-moz-fit-content;width:fit-content}:where(dialog:not([open])){display:none}:where(summary){display:list-item}html{height:100%}body,html{min-height:calc(100vh - 40px)}body{box-sizing:border-box;margin:0;padding:0;word-break:break-word}.block{display:block}.inline{display:inline}.inline-block{display:inline-block}.grid{display:grid}.inline-grid{display:inline-grid}.flex{display:flex}.inline-flex{display:inline-flex}.hidden,.hide,.none{display:none}.visible{visibility:visible}.invisible{visibility:hidden}.monster-button-primary,button{align-items:center;background-position:50%;border-radius:var(--monster-border-radius);border-style:var(--monster-border-style);border-width:var(--monster-border-width);box-shadow:var(--monster-box-shadow-1);cursor:pointer;display:flex;font-family:var(--monster-font-family);font-size:1rem;font-weight:400;gap:.4rem;justify-content:center;line-height:1.5;outline:none;overflow:hidden;padding:.375rem .75rem;position:relative;text-align:center;text-decoration:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;vertical-align:middle;width:-webkit-fill-available;width:-moz-available;width:stretch}.monster-button-primary{background-color:var(--monster-bg-color-primary-4);border-color:var(--monster-bg-color-primary-4);color:var(--monster-color-primary-4)}.monster-button-secondary{background-color:var(--monster-bg-color-secondary-4);border-color:var(--monster-bg-color-secondary-4);border-radius:var(--monster-border-radius);border-style:var(--monster-border-style);border-width:var(--monster-border-width);color:var(--monster-color-secondary-4)}.monster-button-secondary,.monster-button-tertiary{align-items:center;background-position:50%;box-shadow:var(--monster-box-shadow-1);cursor:pointer;display:flex;font-family:var(--monster-font-family);font-size:1rem;font-weight:400;gap:.4rem;justify-content:center;line-height:1.5;outline:none;overflow:hidden;padding:.375rem .75rem;position:relative;text-align:center;text-decoration:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;vertical-align:middle;width:-webkit-fill-available;width:-moz-available;width:stretch}.monster-button-tertiary{background-color:var(--monster-bg-color-tertiary-4);border-color:var(--monster-bg-color-tertiary-4);border-radius:var(--monster-border-radius);border-style:var(--monster-border-style);border-width:var(--monster-border-width);color:var(--monster-color-tertiary-4)}.monster-button-outline-primary{background-color:var(--monster-color-primary-4);border-color:var(--monster-bg-color-primary-4);border-radius:var(--monster-border-radius);border-style:var(--monster-border-style);border-width:var(--monster-border-width);color:var(--monster-bg-color-primary-4)}.monster-button-outline-primary,.monster-button-outline-secondary{align-items:center;background-position:50%;box-shadow:var(--monster-box-shadow-1);cursor:pointer;display:flex;font-family:var(--monster-font-family);font-size:1rem;font-weight:400;gap:.4rem;justify-content:center;line-height:1.5;outline:none;overflow:hidden;padding:.375rem .75rem;position:relative;text-align:center;text-decoration:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;vertical-align:middle;width:-webkit-fill-available;width:-moz-available;width:stretch}.monster-button-outline-secondary{background-color:var(--monster-color-secondary-4);border-color:var(--monster-bg-color-secondary-4);border-radius:var(--monster-border-radius);border-style:var(--monster-border-style);border-width:var(--monster-border-width);color:var(--monster-bg-color-secondary-4)}.monster-button-outline-tertiary{align-items:center;background-color:var(--monster-color-tertiary-4);background-position:50%;border-color:var(--monster-bg-color-tertiary-4);border-radius:var(--monster-border-radius);border-style:var(--monster-border-style);border-width:var(--monster-border-width);box-shadow:var(--monster-box-shadow-1);color:var(--monster-bg-color-tertiary-4);cursor:pointer;display:flex;font-family:var(--monster-font-family);font-size:1rem;font-weight:400;gap:.4rem;justify-content:center;line-height:1.5;outline:none;overflow:hidden;padding:.375rem .75rem;position:relative;text-align:center;text-decoration:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;vertical-align:middle;width:-webkit-fill-available;width:-moz-available;width:stretch}button:active,button:hover{box-shadow:var(--monster-box-shadow-2);transition:background .8s,color .25s .0833333333s}button:active{z-index:var(--monster-z-index-outline)}.monster-button-bar,.monster-button-group{align-content:center;align-items:stretch;display:flex;flex-direction:row;flex-wrap:nowrap;justify-content:space-between}.monster-button-group{box-sizing:border-box;gap:0;margin:1rem 0}.monster-button-group>:not(:last-child){margin-right:calc(var(--monster-border-width)*-1)}.monster-button-group :hover{box-shadow:none}button:focus{outline:1px dashed var(--monster-color-selection-4);outline-offset:2px;z-index:var(--monster-z-index-outline)}@media (prefers-color-scheme:light){button:focus{outline:1px dashed var(--monster-color-selection-3);outline-offset:2px;z-index:var(--monster-z-index-outline)}}[data-monster-role=control]{outline:none;width:100%}[data-monster-role=control].flex{align-items:center;display:flex;flex-direction:row}:after,:before,:root{--monster-font-family:-apple-system,BlinkMacSystemFont,\"Quicksand\",\"Segoe UI\",\"Roboto\",\"Oxygen\",\"Ubuntu\",\"Cantarell\",\"Fira Sans\",\"Droid Sans\",\"Helvetica Neue\",Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\",\"Segoe UI Symbol\";--monster-color-primary-1:var(--monster-color-gray-6);--monster-color-primary-2:var(--monster-color-gray-6);--monster-color-primary-3:var(--monster-color-gray-1);--monster-color-primary-4:var(--monster-color-gray-1);--monster-bg-color-primary-1:var(--monster-color-gray-1);--monster-bg-color-primary-2:var(--monster-color-gray-2);--monster-bg-color-primary-3:var(--monster-color-gray-3);--monster-bg-color-primary-4:var(--monster-color-gray-6);--monster-color-secondary-1:var(--monster-color-red-4);--monster-color-secondary-2:var(--monster-color-red-4);--monster-color-secondary-3:var(--monster-color-red-1);--monster-color-secondary-4:var(--monster-color-red-1);--monster-bg-color-secondary-1:var(--monster-color-gray-1);--monster-bg-color-secondary-2:var(--monster-color-red-2);--monster-bg-color-secondary-3:var(--monster-color-red-3);--monster-bg-color-secondary-4:var(--monster-color-red-6);--monster-color-tertiary-1:var(--monster-color-magenta-4);--monster-color-tertiary-2:var(--monster-color-magenta-4);--monster-color-tertiary-3:var(--monster-color-magenta-6);--monster-color-tertiary-4:var(--monster-color-magenta-1);--monster-bg-color-tertiary-1:var(--monster-color-gray-1);--monster-bg-color-tertiary-2:var(--monster-color-magenta-1);--monster-bg-color-tertiary-3:var(--monster-color-magenta-2);--monster-bg-color-tertiary-4:var(--monster-color-magenta-6);--monster-color-destructive-1:var(--monster-color-red-1);--monster-color-destructive-2:var(--monster-color-red-4);--monster-color-destructive-3:var(--monster-color-red-6);--monster-color-destructive-4:var(--monster-color-red-1);--monster-bg-color-destructive-1:var(--monster-color-red-4);--monster-bg-color-destructive-2:var(--monster-color-gray-1);--monster-bg-color-destructive-3:var(--monster-color-red-2);--monster-bg-color-destructive-4:var(--monster-color-red-5);--monster-color-success-1:var(--monster-color-green-1);--monster-color-success-2:var(--monster-color-green-4);--monster-color-success-3:var(--monster-color-green-6);--monster-color-success-4:var(--monster-color-green-1);--monster-bg-color-success-1:var(--monster-color-green-3);--monster-bg-color-success-2:var(--monster-color-gray-1);--monster-bg-color-success-3:var(--monster-color-green-2);--monster-bg-color-success-4:var(--monster-color-green-5);--monster-color-warning-1:var(--monster-color-orange-1);--monster-color-warning-2:var(--monster-color-orange-4);--monster-color-warning-3:var(--monster-color-orange-6);--monster-color-warning-4:var(--monster-color-orange-1);--monster-bg-color-warning-1:var(--monster-color-orange-3);--monster-bg-color-warning-2:var(--monster-color-gray-1);--monster-bg-color-warning-3:var(--monster-color-orange-2);--monster-bg-color-warning-4:var(--monster-color-orange-5);--monster-color-error-1:var(--monster-color-red-1);--monster-color-error-2:var(--monster-color-red-4);--monster-color-error-3:var(--monster-color-red-6);--monster-color-error-4:var(--monster-color-red-1);--monster-bg-color-error-1:var(--monster-color-red-4);--monster-bg-color-error-2:var(--monster-color-gray-1);--monster-bg-color-error-3:var(--monster-color-red-2);--monster-bg-color-error-4:var(--monster-color-red-5);--monster-color-selection-1:var(--monster-color-gray-6);--monster-color-selection-2:var(--monster-color-gray-6);--monster-color-selection-3:var(--monster-color-gray-6);--monster-color-selection-4:var(--monster-color-gray-1);--monster-bg-color-selection-1:var(--monster-color-yellow-2);--monster-bg-color-selection-2:var(--monster-color-yellow-1);--monster-bg-color-selection-3:var(--monster-color-yellow-2);--monster-bg-color-selection-4:var(--monster-color-yellow-6);--monster-color-primary-disabled-1:var(--monster-color-gray-3);--monster-color-primary-disabled-2:var(--monster-color-gray-1);--monster-color-primary-disabled-3:var(--monster-color-gray-4);--monster-color-primary-disabled-4:var(--monster-color-gray-4);--monster-bg-color-primary-disabled-1:var(--monster-color-gray-1);--monster-bg-color-primary-disabled-2:var(--monster-color-gray-2);--monster-bg-color-primary-disabled-3:var(--monster-color-gray-3);--monster-bg-color-primary-disabled-4:var(--monster-color-gray-6);--monster-color-gradient-1:#833ab4;--monster-color-gradient-2:#fd1d1d;--monster-color-gradient-3:#fcb045;--monster-box-shadow-1:none;--monster-box-shadow-2:-1px 1px 10px 1px hsla(0,0%,76%,.61);--monster-text-shadow:none;--monster-border-style:solid;--monster-border-width:2px;--monster-border-radius:0;--monster-popper-witharrrow-distance:-4px;--monster-z-index-default:0;--monster-z-index-outline:10;--monster-z-index-dropdown:200;--monster-z-index-dropdown-overlay:210;--monster-z-index-sticky:300;--monster-z-index-sticky-overlay:310;--monster-z-index-fixed:400;--monster-z-index-fixed-overlay:410;--monster-z-index-modal-backdrop:500;--monster-z-index-modal-backdrop-overlay:510;--monster-z-index-offcanvas:600;--monster-z-index-offcanvas-overlay:610;--monster-z-index-modal:700;--monster-z-index-modal-overlay:710;--monster-z-index-popover:800;--monster-z-index-popover-overlay:810;--monster-z-index-tooltip:800;--monster-z-index-tooltip-overlay:910;--monster-space-0:0;--monster-space-1:2px;--monster-space-2:4px;--monster-space-3:6px;--monster-space-4:10px;--monster-space-5:16px;--monster-space-6:26px;--monster-space-7:42px;--monster-breakpoint-0:480px;--monster-breakpoint-4:480px;--monster-breakpoint-7:768px;--monster-breakpoint-9:992px;--monster-breakpoint-12:1200px}@media (prefers-color-scheme:dark){:after,:before,:root{--monster-color-primary-1:var(--monster-color-gray-1);--monster-color-primary-2:var(--monster-color-gray-1);--monster-color-primary-3:var(--monster-color-gray-6);--monster-color-primary-4:var(--monster-color-gray-6);--monster-bg-color-primary-1:var(--monster-color-gray-6);--monster-bg-color-primary-2:var(--monster-color-gray-3);--monster-bg-color-primary-3:var(--monster-color-gray-2);--monster-bg-color-primary-4:var(--monster-color-gray-1);--monster-color-secondary-1:var(--monster-color-red-1);--monster-color-secondary-2:var(--monster-color-red-1);--monster-color-secondary-3:var(--monster-color-red-6);--monster-color-secondary-4:var(--monster-color-red-4);--monster-bg-color-secondary-1:var(--monster-color-gray-6);--monster-bg-color-secondary-2:var(--monster-color-red-3);--monster-bg-color-secondary-3:var(--monster-color-red-2);--monster-bg-color-secondary-4:var(--monster-color-red-1);--monster-color-tertiary-1:var(--monster-color-magenta-1);--monster-color-tertiary-2:var(--monster-color-magenta-6);--monster-color-tertiary-3:var(--monster-color-magenta-4);--monster-color-tertiary-4:var(--monster-color-magenta-4);--monster-bg-color-tertiary-1:var(--monster-color-gray-6);--monster-bg-color-tertiary-2:var(--monster-color-magenta-2);--monster-bg-color-tertiary-3:var(--monster-color-magenta-1);--monster-bg-color-tertiary-4:var(--monster-color-magenta-1);--monster-color-destructive-1:var(--monster-color-red-1);--monster-color-destructive-2:var(--monster-color-red-3);--monster-color-destructive-3:var(--monster-color-red-4);--monster-color-destructive-4:var(--monster-color-red-1);--monster-bg-color-destructive-1:var(--monster-color-red-5);--monster-bg-color-destructive-2:var(--monster-color-gray-6);--monster-bg-color-destructive-3:var(--monster-color-red-1);--monster-bg-color-destructive-4:var(--monster-color-red-4);--monster-color-success-1:var(--monster-color-green-1);--monster-color-success-2:var(--monster-color-green-2);--monster-color-success-3:var(--monster-color-green-4);--monster-color-success-4:var(--monster-color-green-1);--monster-bg-color-success-1:var(--monster-color-green-5);--monster-bg-color-success-2:var(--monster-color-gray-6);--monster-bg-color-success-3:var(--monster-color-green-1);--monster-bg-color-success-4:var(--monster-color-green-3);--monster-color-warning-1:var(--monster-color-orange-1);--monster-color-warning-2:var(--monster-color-orange-3);--monster-color-warning-3:var(--monster-color-orange-4);--monster-color-warning-4:var(--monster-color-orange-1);--monster-bg-color-warning-1:var(--monster-color-orange-5);--monster-bg-color-warning-2:var(--monster-color-gray-6);--monster-bg-color-warning-3:var(--monster-color-orange-1);--monster-bg-color-warning-4:var(--monster-color-orange-3);--monster-color-error-1:var(--monster-color-red-1);--monster-color-error-2:var(--monster-color-red-3);--monster-color-error-3:var(--monster-color-red-4);--monster-color-error-4:var(--monster-color-red-1);--monster-bg-color-error-1:var(--monster-color-red-5);--monster-bg-color-error-2:var(--monster-color-gray-6);--monster-bg-color-error-3:var(--monster-color-red-1);--monster-bg-color-error-4:var(--monster-color-red-4);--monster-color-selection-1:var(--monster-color-gray-6);--monster-color-selection-2:var(--monster-color-gray-6);--monster-color-selection-3:var(--monster-color-gray-6);--monster-color-selection-4:var(--monster-color-gray-1);--monster-bg-color-selection-1:var(--monster-color-yellow-2);--monster-bg-color-selection-2:var(--monster-color-yellow-1);--monster-bg-color-selection-3:var(--monster-color-yellow-2);--monster-bg-color-selection-4:var(--monster-color-yellow-6);--monster-color-primary-disabled-1:var(--monster-color-gray-4);--monster-color-primary-disabled-2:var(--monster-color-gray-4);--monster-color-primary-disabled-3:var(--monster-color-gray-3);--monster-color-primary-disabled-4:var(--monster-color-gray-3);--monster-bg-color-primary-disabled-1:var(--monster-color-gray-6);--monster-bg-color-primary-disabled-2:var(--monster-color-gray-3);--monster-bg-color-primary-disabled-3:var(--monster-color-gray-2);--monster-bg-color-primary-disabled-4:var(--monster-color-gray-1)}}span.monster-fx-ripple{animation:monster-fx-ripple .6s linear;background-color:hsla(0,0%,100%,.7);border-radius:50%;position:absolute;transform:scale(0)}@keyframes monster-fx-ripple{to{opacity:0;transform:scale(4)}}[data-monster-role=control]{align-items:center;display:flex;flex-direction:row;flex-wrap:nowrap;justify-content:center;position:relative;width:-moz-fit-content;width:fit-content}[data-monster-role=control] [data-monster-role=badge]{left:0;position:absolute;top:0;transform:translate(-4px,-7px);z-index:var(--monster-z-index-sticky)}[data-monster-role=control] .hidden[data-monster-role=badge]{display:none!important}:host{align-items:center;align-self:center;display:flex;flex-direction:row;flex-wrap:nowrap;justify-content:center;width:-moz-fit-content;width:fit-content} +}`, 0); +} catch (e) { + addAttributeToken(document.getRootNode().querySelector('html'), ATTRIBUTE_ERRORMESSAGE, e + ""); +} diff --git a/source/components/datatable/util.mjs b/source/components/datatable/util.mjs index cc63d365dfb25fd20a32f32b53296271f2b70709..aa2dcb2f66284c3e8893aab5b2827e47d56295a5 100644 --- a/source/components/datatable/util.mjs +++ b/source/components/datatable/util.mjs @@ -55,5 +55,8 @@ function handleDataSourceChanges() { return; } - this.setOption("data", data); + setTimeout(() => { + this.setOption("data", data); + }, 0); } + diff --git a/source/components/form/button-bar.mjs b/source/components/form/button-bar.mjs index 7d16b13f9ca6c415c0090216b51e7e852397c15b..4387dce634bc197b5e38cd81b8e1ee1e07f3cbcd 100644 --- a/source/components/form/button-bar.mjs +++ b/source/components/form/button-bar.mjs @@ -483,11 +483,11 @@ function calculateButtonBarDimensions() { width = computedStyle.getPropertyValue("width"); this[dimensionsSymbol].setVia("data.space", convertToPixels(width)); } else { - const borderWidth = getComputedStyle(this).getPropertyValue( + let borderWidth = getComputedStyle(this).getPropertyValue( "--monster-border-width", ); - if (borderWidth === null) { - throw new Error("border-width not defined"); + if (borderWidth === null||borderWidth === "") { + borderWidth = "0px"; } const borderWidthWithoutUnit = convertToPixels(borderWidth); diff --git a/source/components/form/button.mjs b/source/components/form/button.mjs index ceb3a727f81c32027bc8378644b558c9fec7ee53..bd499d4494c17e68d7f3e6cdbedc40a67a6bd2b2 100644 --- a/source/components/form/button.mjs +++ b/source/components/form/button.mjs @@ -22,7 +22,7 @@ import { ATTRIBUTE_BUTTON_CLASS } from "./constants.mjs"; import { ButtonStyleSheet } from "./stylesheet/button.mjs"; import { RippleStyleSheet } from "../stylesheet/ripple.mjs"; import { fireCustomEvent } from "../../dom/events.mjs"; -import { isString } from "../../types/is.mjs"; + export { Button }; @@ -228,7 +228,7 @@ class Button extends CustomControl { }, disabled: false, actions: { - click: (e) => { + click: () => { throw new Error("the click action is not defined"); }, }, diff --git a/source/components/form/form.mjs b/source/components/form/form.mjs index bc3b0c2f4d1f424d47560c2d9560bdad0bfad2d0..f2f25fa6d3509cd605a52fe7525c61877520efc0 100644 --- a/source/components/form/form.mjs +++ b/source/components/form/form.mjs @@ -25,6 +25,7 @@ import { assembleMethodSymbol, CustomElement, registerCustomElement, + getSlottedElements, } from "../../dom/customelement.mjs"; import { addObjectWithUpdaterToElement } from "../../dom/updater.mjs"; import { isFunction, isString } from "../../types/is.mjs"; @@ -37,7 +38,6 @@ import { ATTRIBUTE_FORM_DATASOURCE_ARGUMENTS, } from "./constants.mjs"; import { StateButton } from "./state-button.mjs"; -import { getSlottedElements } from "../../dom/customelement.mjs"; import { FormStyleSheet } from "./stylesheet/form.mjs"; export { Form }; diff --git a/source/components/form/message-state-button.mjs b/source/components/form/message-state-button.mjs index 8a0ebb5320f337de35866c2257d768e8a93d464c..80a7903748e8cdb99d8677d6c6b284df56d09ac2 100644 --- a/source/components/form/message-state-button.mjs +++ b/source/components/form/message-state-button.mjs @@ -75,7 +75,7 @@ class MessageStateButton extends Popper { /** * - * @param {state} state + * @param {string} state * @param {number} timeout * @return {Monster.Components.Form.MessageStateButton} * @throws {TypeError} value is not a string diff --git a/source/components/form/state-button.mjs b/source/components/form/state-button.mjs index 33808cfafbd3669534e2d1bf656458e8a06341d4..d6e22b9c618875e5943824fe2e91f6cfd92ff1bf 100644 --- a/source/components/form/state-button.mjs +++ b/source/components/form/state-button.mjs @@ -101,7 +101,7 @@ class StateButton extends Button { * * @since 3.18.0 a previously set timeout is cleared * - * @param {state} state + * @param {string} state * @param {number} timeout * @return {Monster.Components.Form.StateButton} * @throws {TypeError} value is not a string diff --git a/source/components/host/overlay.mjs b/source/components/host/overlay.mjs index 5f7bf0391abf0d4bd406f66d092429ab9a179152..08e38ba233f5e2bca1f141a0d2d28d767c4e48a9 100644 --- a/source/components/host/overlay.mjs +++ b/source/components/host/overlay.mjs @@ -127,6 +127,7 @@ class Overlay extends CustomElement { * @property {string} classes.overlay Css class to hide the overlay. This class is removed when the component is ready. * @property {Object} features Feature definitions * @property {boolean} features.escapeKey If true the overlay can be closed with the escape key + * @property {boolean} features.openButton If true the overlay can be opened with a button */ get defaults() { return Object.assign({}, super.defaults, { @@ -146,6 +147,7 @@ class Overlay extends CustomElement { }, features: { escapeKey: true, + openButton: true, }, }); } @@ -326,7 +328,8 @@ function getTemplate() { data-monster-attributes="part path:host-overlay.name, data-monster-role path:host-container.overlay"></div> </template> - <div data-monster-role="overlay-open" part="open"></div> + <div data-monster-role="overlay-open" part="open" + data-monster-attributes="class path:features.openButton | if:visible:hidden"></div> <div id="overlay" data-monster-role="overlay" part="overlay" data-monster-insert="host-overlay path:overlay" data-monster-attributes="class path:classes.overlay"> diff --git a/source/components/tree-menu/tree-menu.mjs b/source/components/tree-menu/tree-menu.mjs index 96c5e36b2d4acf423f6e4d1269b57cd77cace66a..41f6d380b4acdae93b35599ba6a0b170af677d0c 100644 --- a/source/components/tree-menu/tree-menu.mjs +++ b/source/components/tree-menu/tree-menu.mjs @@ -515,7 +515,6 @@ function switchToConfig() { }; this[dragEventHandlerSymbol] = (event) => { - console.log(event); event.preventDefault(); }; diff --git a/source/data/datasource.mjs b/source/data/datasource.mjs index 2b57d541acc0e2356eb171994990f458f0495921..a55b8dcd6568172c3ac27086f06008772d533738 100644 --- a/source/data/datasource.mjs +++ b/source/data/datasource.mjs @@ -35,7 +35,7 @@ export { Datasource }; * @since 1.24.0 */ const internalDataSymbol = Symbol.for( - "@schukai/monster/data/datasource/@@data", + "@schukai/monster/data/datasource/@@data" ); /** diff --git a/source/data/datasource/server.mjs b/source/data/datasource/server.mjs index 57ae8becc4dcd26484feb95721de9fe7e7a04068..edb77abbce56ae89eeb5a3751aff566ea15ffb04 100644 --- a/source/data/datasource/server.mjs +++ b/source/data/datasource/server.mjs @@ -81,7 +81,7 @@ class Server extends Datasource { */ function doTransform(type, obj) { const transformation = this.getOption(`${type}.mapping.transformer`); - if (transformation !== undefined) { + if (transformation !== undefined && transformation !== null) { const pipe = new Pipe(transformation); const callbacks = this.getOption(`${type}.mapping.callbacks`); diff --git a/source/data/datasource/server/restapi.mjs b/source/data/datasource/server/restapi.mjs index dbce0b746fc0fb5f866170b8c60bef338d035510..a88e93b5adddda887da6c439ba94c53a2c7a29f0 100644 --- a/source/data/datasource/server/restapi.mjs +++ b/source/data/datasource/server/restapi.mjs @@ -88,7 +88,7 @@ class RestAPI extends Server { }, responseCallback: undefined, acceptedStatus: [200, 201], - url: undefined, + url: null, mapping: { transformer: undefined, callbacks: [], @@ -107,7 +107,7 @@ class RestAPI extends Server { }, responseCallback: undefined, acceptedStatus: [200], - url: undefined, + url: null, mapping: { transformer: undefined, callbacks: [], diff --git a/source/data/pathfinder.mjs b/source/data/pathfinder.mjs index c40f68be539dcc13c4bcece58807fbacdbf8f318..6137483d88b70ce0ea12b251c97b2b23f10e92f6 100644 --- a/source/data/pathfinder.mjs +++ b/source/data/pathfinder.mjs @@ -82,11 +82,14 @@ const WILDCARD = "*"; * @memberOf Monster.Data */ class Pathfinder extends Base { + /** - * @param {array|object|Map|Set} value - * @since 1.4.0 - * @throws {Error} the parameter must not be a simple type - **/ + * Creates a new instance of the constructor. + * + * @param {object} object - The object parameter for the constructor. + * + * @throws {Error} Throws an error if the provided object parameter is a simple type. + */ constructor(object) { super(); diff --git a/source/dom/constants.mjs b/source/dom/constants.mjs index 0c7aae9e172c13aa047c9674a3b3a30cd5126cf9..1c4edc1347d1fed350d56d83610973c7df130d46 100644 --- a/source/dom/constants.mjs +++ b/source/dom/constants.mjs @@ -19,6 +19,7 @@ export { ATTRIBUTE_UPDATER_INSERT_REFERENCE, ATTRIBUTE_UPDATER_REMOVE, ATTRIBUTE_UPDATER_BIND, + ATTRIBUTE_UPDATER_BIND_TYPE, ATTRIBUTE_TEMPLATE_PREFIX, ATTRIBUTE_ROLE, ATTRIBUTE_DISABLED, @@ -199,6 +200,14 @@ const ATTRIBUTE_UPDATER_REMOVE = `${ATTRIBUTE_PREFIX}remove`; */ const ATTRIBUTE_UPDATER_BIND = `${ATTRIBUTE_PREFIX}bind`; +/** + * @memberOf Monster.DOM + * @type {string} + * @license AGPLv3 + * @since 1.9.0 + */ +const ATTRIBUTE_UPDATER_BIND_TYPE = `${ATTRIBUTE_UPDATER_BIND}-type`; + /** * @memberOf Monster.DOM * @type {string} diff --git a/source/dom/customelement.mjs b/source/dom/customelement.mjs index b8af29a641e57c2a06e6de640dbf4c3e97bad75d..55b105186a9f080ea3d019bccae7f4b790f08a15 100644 --- a/source/dom/customelement.mjs +++ b/source/dom/customelement.mjs @@ -5,63 +5,63 @@ * License text available at https://www.gnu.org/licenses/agpl-3.0.en.html */ -import { findElementWithIdUpwards } from "./util.mjs"; -import { internalSymbol } from "../constants.mjs"; -import { extend } from "../data/extend.mjs"; -import { Pathfinder } from "../data/pathfinder.mjs"; -import { Formatter } from "../text/formatter.mjs"; - -import { parseDataURL } from "../types/dataurl.mjs"; -import { getGlobalObject } from "../types/global.mjs"; +import {findElementWithIdUpwards} from "./util.mjs"; +import {internalSymbol} from "../constants.mjs"; +import {extend} from "../data/extend.mjs"; +import {Pathfinder} from "../data/pathfinder.mjs"; +import {Formatter} from "../text/formatter.mjs"; + +import {parseDataURL} from "../types/dataurl.mjs"; +import {getGlobalObject} from "../types/global.mjs"; import { - isArray, - isFunction, - isIterable, - isObject, - isString, + isArray, + isFunction, + isIterable, + isObject, + isString, } from "../types/is.mjs"; -import { Observer } from "../types/observer.mjs"; -import { ProxyObserver } from "../types/proxyobserver.mjs"; +import {Observer} from "../types/observer.mjs"; +import {ProxyObserver} from "../types/proxyobserver.mjs"; import { - validateFunction, - validateInstance, - validateObject, - validateString, + validateFunction, + validateInstance, + validateObject, + validateString, } from "../types/validate.mjs"; -import { clone } from "../util/clone.mjs"; +import {clone} from "../util/clone.mjs"; import { - addAttributeToken, - getLinkedObjects, - hasObjectLink, + addAttributeToken, + getLinkedObjects, + hasObjectLink, } from "./attributes.mjs"; import { - ATTRIBUTE_DISABLED, - ATTRIBUTE_ERRORMESSAGE, - ATTRIBUTE_OPTIONS, - ATTRIBUTE_INIT_CALLBACK, - ATTRIBUTE_OPTIONS_SELECTOR, - ATTRIBUTE_SCRIPT_HOST, - customElementUpdaterLinkSymbol, - initControlCallbackName, + ATTRIBUTE_DISABLED, + ATTRIBUTE_ERRORMESSAGE, + ATTRIBUTE_OPTIONS, + ATTRIBUTE_INIT_CALLBACK, + ATTRIBUTE_OPTIONS_SELECTOR, + ATTRIBUTE_SCRIPT_HOST, + customElementUpdaterLinkSymbol, + initControlCallbackName, } from "./constants.mjs"; -import { findDocumentTemplate, Template } from "./template.mjs"; -import { addObjectWithUpdaterToElement } from "./updater.mjs"; -import { instanceSymbol } from "../constants.mjs"; +import {findDocumentTemplate, Template} from "./template.mjs"; +import {addObjectWithUpdaterToElement} from "./updater.mjs"; +import {instanceSymbol} from "../constants.mjs"; import { - getDocumentTranslations, - Translations, + getDocumentTranslations, + Translations, } from "../i18n/translations.mjs"; -import { getSlottedElements } from "./slotted.mjs"; -import { initOptionsFromAttributes } from "./util/init-options-from-attributes.mjs"; -import { setOptionFromAttribute } from "./util/set-option-from-attribute.mjs"; +import {getSlottedElements} from "./slotted.mjs"; +import {initOptionsFromAttributes} from "./util/init-options-from-attributes.mjs"; +import {setOptionFromAttribute} from "./util/set-option-from-attribute.mjs"; export { - CustomElement, - initMethodSymbol, - assembleMethodSymbol, - attributeObserverSymbol, - registerCustomElement, - getSlottedElements, + CustomElement, + initMethodSymbol, + assembleMethodSymbol, + attributeObserverSymbol, + registerCustomElement, + getSlottedElements, }; /** @@ -75,7 +75,7 @@ const initMethodSymbol = Symbol.for("@schukai/monster/dom/@@initMethodSymbol"); * @type {symbol} */ const assembleMethodSymbol = Symbol.for( - "@schukai/monster/dom/@@assembleMethodSymbol", + "@schukai/monster/dom/@@assembleMethodSymbol", ); /** @@ -84,7 +84,7 @@ const assembleMethodSymbol = Symbol.for( * @type {symbol} */ const attributeObserverSymbol = Symbol.for( - "@schukai/monster/dom/@@attributeObserver", + "@schukai/monster/dom/@@attributeObserver", ); /** @@ -92,7 +92,15 @@ const attributeObserverSymbol = Symbol.for( * @type {symbol} */ const attributeMutationObserverSymbol = Symbol( - "@schukai/monster/dom/@@mutationObserver", + "@schukai/monster/dom/@@mutationObserver", +); + +/** + * @private + * @type {symbol} + */ +const updateCloneDataSymbol = Symbol( + "@schukai/monster/dom/@@updateCloneData", ); /** @@ -225,468 +233,484 @@ const scriptHostElementSymbol = Symbol("scriptHostElement"); * @summary A base class for HTML5 custom controls. */ class CustomElement extends HTMLElement { - /** - * A new object is created. First the `initOptions` method is called. Here the - * options can be defined in derived classes. Subsequently, the shadowRoot is initialized. - * - * IMPORTANT: CustomControls instances are not created via the constructor, but either via a tag in the HTML or via <code>document.createElement()</code>. - * - * @throws {Error} the options attribute does not contain a valid json definition. - * @since 1.7.0 - */ - constructor() { - super(); - - this[attributeObserverSymbol] = {}; - this[internalSymbol] = new ProxyObserver({ - options: initOptionsFromAttributes(this, extend({}, this.defaults)), - }); - this[initMethodSymbol](); - initOptionObserver.call(this); - this[scriptHostElementSymbol] = []; - } - - /** - * This method is called by the `instanceof` operator. - * @returns {symbol} - * @since 2.1.0 - */ - static get [instanceSymbol]() { - return Symbol.for("@schukai/monster/dom/custom-element@@instance"); - } - - /** - * This method determines which attributes are to be - * monitored by `attributeChangedCallback()`. Unfortunately, this method is static. - * Therefore, the `observedAttributes` property cannot be changed during runtime. - * - * @return {string[]} - * @since 1.15.0 - */ - static get observedAttributes() { - return []; - } - - /** - * - * @param attribute - * @param callback - * @returns {Monster.DOM.CustomElement} - */ - addAttributeObserver(attribute, callback) { - validateFunction(callback); - this[attributeObserverSymbol][attribute] = callback; - return this; - } - - /** - * - * @param attribute - * @returns {Monster.DOM.CustomElement} - */ - removeAttributeObserver(attribute) { - delete this[attributeObserverSymbol][attribute]; - return this; - } - - /** - * The `defaults` property defines the default values for a control. If you want to override these, - * you can use various methods, which are described in the documentation available at - * {@link https://monsterjs.orgendocconfigurate-a-monster-control}. - * - * The individual configuration values are listed below: - * - * More information about the shadowRoot can be found in the [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/API/Element/attachShadow), - * in the [HTML Standard](https://html.spec.whatwg.org/multipage/custom-elements.html#custom-elements) or in the [WHATWG Wiki](https://wiki.whatwg.org/wiki/Custom_Elements). - * - * More information about the template element can be found in the [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/template). - * - * More information about the slot element can be found in the [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/slot). - * - * @property {boolean} disabled=false Specifies whether the control is disabled. When present, it makes the element non-mutable, non-focusable, and non-submittable with the form. - * @property {string} shadowMode=open Specifies the mode of the shadow root. When set to `open`, elements in the shadow root are accessible from JavaScript outside the root, while setting it to `closed` denies access to the root's nodes from JavaScript outside it. - * @property {Boolean} delegatesFocus=true Specifies the behavior of the control with respect to focusability. When set to `true`, it mitigates custom element issues around focusability. When a non-focusable part of the shadow DOM is clicked, the first focusable part is given focus, and the shadow host is given any available :focus styling. - * @property {Object} templates Specifies the templates used by the control. - * @property {string} templates.main=undefined Specifies the main template used by the control. - * @property {Object} templateMapping Specifies the mapping of templates. - * @since 1.8.0 - */ - get defaults() { - return { - disabled: false, - shadowMode: "open", - delegatesFocus: true, - templates: { - main: undefined, - }, - templateMapping: {}, - }; - } - - /** - * This method updates the labels of the element. - * The labels are defined in the options object. - * The key of the label is used to retrieve the translation from the document. - * If the translation is different from the label, the label is updated. - * - * Before you can use this method, you must have loaded the translations. - * - * @returns {Monster.DOM.CustomElement} - * @throws {Error} Cannot find element with translations. Add a translations object to the document. - */ - updateI18n() { - const translations = getDocumentTranslations(); - if (!translations) { - return this; - } - - const labels = this.getOption("labels"); - if (!(isObject(labels) || isIterable(labels))) { - return this; - } - - for (const key in labels) { - const def = labels[key]; - - if (isString(def)) { - const text = translations.getText(key, def); - if (text !== def) { - this.setOption(`labels.${key}`, text); - } - continue; - } else if (isObject(def)) { - for (const k in def) { - const d = def[k]; - - const text = translations.getPluralRuleText(key, k, d); - if (!isString(text)) { - throw new Error("Invalid labels definition"); - } - if (text !== d) { - this.setOption(`labels.${key}.${k}`, text); - } - } - continue; - } - - throw new Error("Invalid labels definition"); - } - return this; - } - - /** - * The `getTag()` method returns the tag name associated with the custom element. This method should be overwritten - * by the derived class. - * - * Note that there is no check on the name of the tag in this class. It is the responsibility of - * the developer to assign an appropriate tag name. If the name is not valid, the - * `registerCustomElement()` method will issue an error. - * - * @see https://html.spec.whatwg.org/multipage/custom-elements.html#valid-custom-element-name - * @throws {Error} This method must be overridden by the derived class. - * @return {string} The tag name associated with the custom element. - * @since 1.7.0 - */ - static getTag() { - throw new Error( - "The method `getTag()` must be overridden by the derived class.", - ); - } - - /** - * The `getCSSStyleSheet()` method returns a `CSSStyleSheet` object that defines the styles for the custom element. - * If the environment does not support the `CSSStyleSheet` constructor, then an object can be built using the provided detour. - * - * If `undefined` is returned, then the shadow root does not receive a stylesheet. - * - * Example usage: - * - * ```js - * static getCSSStyleSheet() { - * const sheet = new CSSStyleSheet(); - * sheet.replaceSync("p { color: red; }"); - * return sheet; - * } - * ``` - * - * If the environment does not support the `CSSStyleSheet` constructor, - * you can use the following workaround to create the stylesheet: - * - * ```js - * const doc = document.implementation.createHTMLDocument('title'); - * let style = doc.createElement("style"); - * style.innerHTML = "p { color: red; }"; - * style.appendChild(document.createTextNode("")); - * doc.head.appendChild(style); - * return doc.styleSheets[0]; - * ``` - * - * @return {CSSStyleSheet|CSSStyleSheet[]|string|undefined} A `CSSStyleSheet` object or an array of such objects that define the styles for the custom element, or `undefined` if no stylesheet should be applied. - */ - static getCSSStyleSheet() { - return undefined; - } - - /** - * attach a new observer - * - * @param {Observer} observer - * @returns {CustomElement} - */ - attachObserver(observer) { - this[internalSymbol].attachObserver(observer); - return this; - } - - /** - * detach a observer - * - * @param {Observer} observer - * @returns {CustomElement} - */ - detachObserver(observer) { - this[internalSymbol].detachObserver(observer); - return this; - } - - /** - * @param {Observer} observer - * @returns {ProxyObserver} - */ - containsObserver(observer) { - return this[internalSymbol].containsObserver(observer); - } - - /** - * nested options can be specified by path `a.b.c` - * - * @param {string} path - * @param {*} defaultValue - * @return {*} - * @since 1.10.0 - */ - getOption(path, defaultValue=undefined) { - let value; - - try { - value = new Pathfinder( - this[internalSymbol].getRealSubject()["options"], - ).getVia(path); - } catch (e) {} - - if (value === undefined) return defaultValue; - return value; - } - - /** - * Set option and inform elements - * - * @param {string} path - * @param {*} value - * @return {CustomElement} - * @since 1.14.0 - */ - setOption(path, value) { - new Pathfinder(this[internalSymbol].getSubject()["options"]).setVia( - path, - value, - ); - return this; - } - - /** - * @since 1.15.0 - * @param {string|object} options - * @return {CustomElement} - */ - setOptions(options) { - if (isString(options)) { - options = parseOptionsJSON.call(this, options); - } - // 2024-01-21: remove this.defaults, otherwise it will overwrite - // the current settings that have already been made. - // https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/136 - extend( - this[internalSymbol].getSubject()["options"], - options, - ); - - return this; - } - - /** - * Is called once via the constructor - * - * @return {CustomElement} - * @since 1.8.0 - */ - [initMethodSymbol]() { - return this; - } - - /** - * This method is called once when the object is included in the DOM for the first time. It performs the following actions: - * 1. Extracts the options from the attributes and the script tag of the element and sets them. - * 2. Initializes the shadow root and its CSS stylesheet (if specified). - * 3. Initializes the HTML content of the element. - * 4. Initializes the custom elements inside the shadow root and the slotted elements. - * 5. Attaches a mutation observer to observe changes to the attributes of the element. - * - * @return {CustomElement} - The updated custom element. - * @since 1.8.0 - */ - [assembleMethodSymbol]() { - let elements; - let nodeList; - - // Extract options from attributes and set them - const AttributeOptions = getOptionsFromAttributes.call(this); - if ( - isObject(AttributeOptions) && - Object.keys(AttributeOptions).length > 0 - ) { - this.setOptions(AttributeOptions); - } - - // Extract options from script tag and set them - const ScriptOptions = getOptionsFromScriptTag.call(this); - if (isObject(ScriptOptions) && Object.keys(ScriptOptions).length > 0) { - this.setOptions(ScriptOptions); - } - - // Initialize the shadow root and its CSS stylesheet - if (this.getOption("shadowMode", false) !== false) { - try { - initShadowRoot.call(this); - elements = this.shadowRoot.childNodes; - } catch (e) { - addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, e.toString()); - } - - try { - initCSSStylesheet.call(this); - } catch (e) { - addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, e.toString()); - } - } - - // If the elements are not found inside the shadow root, initialize the HTML content of the element - if (!(elements instanceof NodeList)) { - initHtmlContent.call(this); - elements = this.childNodes; - } - - // Initialize the custom elements inside the shadow root and the slotted elements - initFromCallbackHost.call(this); - try { - nodeList = new Set([...elements, ...getSlottedElements.call(this)]); - } catch (e) { - nodeList = elements; - } - addObjectWithUpdaterToElement.call( - this, - nodeList, - customElementUpdaterLinkSymbol, - clone(this[internalSymbol].getRealSubject()["options"]), - ); - - // Attach a mutation observer to observe changes to the attributes of the element - attachAttributeChangeMutationObserver.call(this); - - return this; - } - - /** - * This method is called every time the element is inserted into the DOM. It checks if the custom element - * has already been initialized and if not, calls the assembleMethod to initialize it. - * - * @return {void} - * @since 1.7.0 - * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/connectedCallback - */ - connectedCallback() { - // Check if the object has already been initialized - if (!hasObjectLink(this, customElementUpdaterLinkSymbol)) { - // If not, call the assembleMethod to initialize the object - this[assembleMethodSymbol](); - } - } - - /** - * Called every time the element is removed from the DOM. Useful for running clean up code. - * - * @return {void} - * @since 1.7.0 - */ - disconnectedCallback() {} - - /** - * The custom element has been moved into a new document (e.g. someone called document.adoptNode(el)). - * - * @return {void} - * @since 1.7.0 - */ - adoptedCallback() {} - - /** - * Called when an observed attribute has been added, removed, updated, or replaced. Also called for initial - * values when an element is created by the parser, or upgraded. Note: only attributes listed in the observedAttributes - * property will receive this callback. - * - * @param {string} attrName - * @param {string} oldVal - * @param {string} newVal - * @return {void} - * @since 1.15.0 - */ - attributeChangedCallback(attrName, oldVal, newVal) { - if (attrName.startsWith("data-monster-option-")) { - setOptionFromAttribute( - this, - attrName, - this[internalSymbol].getSubject()["options"], - ); - } - - const callback = this[attributeObserverSymbol]?.[attrName]; - if (isFunction(callback)) { - try { - callback.call(this, newVal, oldVal); - } catch (e) { - addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, e.toString()); - } - } - } - - /** - * - * @param {Node} node - * @return {boolean} - * @throws {TypeError} value is not an instance of - * @since 1.19.0 - */ - hasNode(node) { - if (containChildNode.call(this, validateInstance(node, Node))) { - return true; - } - - if (!(this.shadowRoot instanceof ShadowRoot)) { - return false; - } - - return containChildNode.call(this.shadowRoot, node); - } - - /** - * Calls a callback function if it exists. - * - * @param {string} name - * @param {*} args - * @returns {*} - */ - callCallback(name, args) { - return callControlCallback.call(this, name, ...args); - } + /** + * A new object is created. First the `initOptions` method is called. Here the + * options can be defined in derived classes. Subsequently, the shadowRoot is initialized. + * + * IMPORTANT: CustomControls instances are not created via the constructor, but either via a tag in the HTML or via <code>document.createElement()</code>. + * + * @throws {Error} the options attribute does not contain a valid json definition. + * @since 1.7.0 + */ + constructor() { + super(); + + this[attributeObserverSymbol] = {}; + this[internalSymbol] = new ProxyObserver({ + options: initOptionsFromAttributes(this, extend({}, this.defaults)), + }); + this[initMethodSymbol](); + initOptionObserver.call(this); + this[scriptHostElementSymbol] = []; + } + + /** + * This method is called by the `instanceof` operator. + * @returns {symbol} + * @since 2.1.0 + */ + static get [instanceSymbol]() { + return Symbol.for("@schukai/monster/dom/custom-element@@instance"); + } + + /** + * This method determines which attributes are to be + * monitored by `attributeChangedCallback()`. Unfortunately, this method is static. + * Therefore, the `observedAttributes` property cannot be changed during runtime. + * + * @return {string[]} + * @since 1.15.0 + */ + static get observedAttributes() { + return []; + } + + /** + * + * @param attribute + * @param callback + * @returns {Monster.DOM.CustomElement} + */ + addAttributeObserver(attribute, callback) { + validateFunction(callback); + this[attributeObserverSymbol][attribute] = callback; + return this; + } + + /** + * + * @param attribute + * @returns {Monster.DOM.CustomElement} + */ + removeAttributeObserver(attribute) { + delete this[attributeObserverSymbol][attribute]; + return this; + } + + /** + * The `defaults` property defines the default values for a control. If you want to override these, + * you can use various methods, which are described in the documentation available at + * {@link https://monsterjs.orgendocconfigurate-a-monster-control}. + * + * The individual configuration values are listed below: + * + * More information about the shadowRoot can be found in the [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/API/Element/attachShadow), + * in the [HTML Standard](https://html.spec.whatwg.org/multipage/custom-elements.html#custom-elements) or in the [WHATWG Wiki](https://wiki.whatwg.org/wiki/Custom_Elements). + * + * More information about the template element can be found in the [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/template). + * + * More information about the slot element can be found in the [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/slot). + * + * @property {boolean} disabled=false Specifies whether the control is disabled. When present, it makes the element non-mutable, non-focusable, and non-submittable with the form. + * @property {string} shadowMode=open Specifies the mode of the shadow root. When set to `open`, elements in the shadow root are accessible from JavaScript outside the root, while setting it to `closed` denies access to the root's nodes from JavaScript outside it. + * @property {Boolean} delegatesFocus=true Specifies the behavior of the control with respect to focusability. When set to `true`, it mitigates custom element issues around focusability. When a non-focusable part of the shadow DOM is clicked, the first focusable part is given focus, and the shadow host is given any available :focus styling. + * @property {Object} templates Specifies the templates used by the control. + * @property {string} templates.main=undefined Specifies the main template used by the control. + * @property {Object} templateMapping Specifies the mapping of templates. + * @since 1.8.0 + */ + get defaults() { + return { + disabled: false, + shadowMode: "open", + delegatesFocus: true, + templates: { + main: undefined, + }, + templateMapping: {}, + }; + } + + /** + * This method updates the labels of the element. + * The labels are defined in the options object. + * The key of the label is used to retrieve the translation from the document. + * If the translation is different from the label, the label is updated. + * + * Before you can use this method, you must have loaded the translations. + * + * @returns {Monster.DOM.CustomElement} + * @throws {Error} Cannot find element with translations. Add a translations object to the document. + */ + updateI18n() { + const translations = getDocumentTranslations(); + if (!translations) { + return this; + } + + const labels = this.getOption("labels"); + if (!(isObject(labels) || isIterable(labels))) { + return this; + } + + for (const key in labels) { + const def = labels[key]; + + if (isString(def)) { + const text = translations.getText(key, def); + if (text !== def) { + this.setOption(`labels.${key}`, text); + } + continue; + } else if (isObject(def)) { + for (const k in def) { + const d = def[k]; + + const text = translations.getPluralRuleText(key, k, d); + if (!isString(text)) { + throw new Error("Invalid labels definition"); + } + if (text !== d) { + this.setOption(`labels.${key}.${k}`, text); + } + } + continue; + } + + throw new Error("Invalid labels definition"); + } + return this; + } + + /** + * The `getTag()` method returns the tag name associated with the custom element. This method should be overwritten + * by the derived class. + * + * Note that there is no check on the name of the tag in this class. It is the responsibility of + * the developer to assign an appropriate tag name. If the name is not valid, the + * `registerCustomElement()` method will issue an error. + * + * @see https://html.spec.whatwg.org/multipage/custom-elements.html#valid-custom-element-name + * @throws {Error} This method must be overridden by the derived class. + * @return {string} The tag name associated with the custom element. + * @since 1.7.0 + */ + static getTag() { + throw new Error( + "The method `getTag()` must be overridden by the derived class.", + ); + } + + /** + * The `getCSSStyleSheet()` method returns a `CSSStyleSheet` object that defines the styles for the custom element. + * If the environment does not support the `CSSStyleSheet` constructor, then an object can be built using the provided detour. + * + * If `undefined` is returned, then the shadow root does not receive a stylesheet. + * + * Example usage: + * + * ```js + * static getCSSStyleSheet() { + * const sheet = new CSSStyleSheet(); + * sheet.replaceSync("p { color: red; }"); + * return sheet; + * } + * ``` + * + * If the environment does not support the `CSSStyleSheet` constructor, + * you can use the following workaround to create the stylesheet: + * + * ```js + * const doc = document.implementation.createHTMLDocument('title'); + * let style = doc.createElement("style"); + * style.innerHTML = "p { color: red; }"; + * style.appendChild(document.createTextNode("")); + * doc.head.appendChild(style); + * return doc.styleSheets[0]; + * ``` + * + * @return {CSSStyleSheet|CSSStyleSheet[]|string|undefined} A `CSSStyleSheet` object or an array of such objects that define the styles for the custom element, or `undefined` if no stylesheet should be applied. + */ + static getCSSStyleSheet() { + return undefined; + } + + /** + * attach a new observer + * + * @param {Observer} observer + * @returns {CustomElement} + */ + attachObserver(observer) { + this[internalSymbol].attachObserver(observer); + return this; + } + + /** + * detach a observer + * + * @param {Observer} observer + * @returns {CustomElement} + */ + detachObserver(observer) { + this[internalSymbol].detachObserver(observer); + return this; + } + + /** + * @param {Observer} observer + * @returns {ProxyObserver} + */ + containsObserver(observer) { + return this[internalSymbol].containsObserver(observer); + } + + /** + * nested options can be specified by path `a.b.c` + * + * @param {string} path + * @param {*} defaultValue + * @return {*} + * @since 1.10.0 + */ + getOption(path, defaultValue = undefined) { + let value; + + try { + value = new Pathfinder( + this[internalSymbol].getRealSubject()["options"], + ).getVia(path); + } catch (e) { + } + + if (value === undefined) return defaultValue; + return value; + } + + /** + * Set option and inform elements + * + * @param {string} path + * @param {*} value + * @return {CustomElement} + * @since 1.14.0 + */ + setOption(path, value) { + new Pathfinder(this[internalSymbol].getSubject()["options"]).setVia( + path, + value, + ); + return this; + } + + /** + * @since 1.15.0 + * @param {string|object} options + * @return {CustomElement} + */ + setOptions(options) { + if (isString(options)) { + options = parseOptionsJSON.call(this, options); + } + // 2024-01-21: remove this.defaults, otherwise it will overwrite + // the current settings that have already been made. + // https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/136 + extend( + this[internalSymbol].getSubject()["options"], + options, + ); + + return this; + } + + /** + * Is called once via the constructor + * + * @return {CustomElement} + * @since 1.8.0 + */ + [initMethodSymbol]() { + return this; + } + + /** + * This method is called once when the object is included in the DOM for the first time. It performs the following actions: + * 1. Extracts the options from the attributes and the script tag of the element and sets them. + * 2. Initializes the shadow root and its CSS stylesheet (if specified). + * 3. Initializes the HTML content of the element. + * 4. Initializes the custom elements inside the shadow root and the slotted elements. + * 5. Attaches a mutation observer to observe changes to the attributes of the element. + * + * @return {CustomElement} - The updated custom element. + * @since 1.8.0 + */ + [assembleMethodSymbol]() { + let elements; + let nodeList; + + // Extract options from attributes and set them + const AttributeOptions = getOptionsFromAttributes.call(this); + if ( + isObject(AttributeOptions) && + Object.keys(AttributeOptions).length > 0 + ) { + this.setOptions(AttributeOptions); + } + + // Extract options from script tag and set them + const ScriptOptions = getOptionsFromScriptTag.call(this); + if (isObject(ScriptOptions) && Object.keys(ScriptOptions).length > 0) { + this.setOptions(ScriptOptions); + } + + // Initialize the shadow root and its CSS stylesheet + if (this.getOption("shadowMode", false) !== false) { + try { + initShadowRoot.call(this); + elements = this.shadowRoot.childNodes; + } catch (e) { + addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, e.toString()); + } + + try { + initCSSStylesheet.call(this); + } catch (e) { + addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, e.toString()); + } + } + + // If the elements are not found inside the shadow root, initialize the HTML content of the element + if (!(elements instanceof NodeList)) { + initHtmlContent.call(this); + elements = this.childNodes; + } + + // Initialize the custom elements inside the shadow root and the slotted elements + initFromCallbackHost.call(this); + try { + nodeList = new Set([...elements, ...getSlottedElements.call(this)]); + } catch (e) { + nodeList = elements; + } + + this[updateCloneDataSymbol] = clone(this[internalSymbol].getRealSubject()["options"]) + + addObjectWithUpdaterToElement.call( + this, + nodeList, + customElementUpdaterLinkSymbol, + this[updateCloneDataSymbol], + ); + + // Attach a mutation observer to observe changes to the attributes of the element + attachAttributeChangeMutationObserver.call(this); + + return this; + } + + /** + * You know what you are doing? This function is only for advanced users. + * The result is a clone of the internal data. + * + * @returns {*} + */ + getInternalUpdateCloneData() { + return clone (this[updateCloneDataSymbol]); + } + + /** + * This method is called every time the element is inserted into the DOM. It checks if the custom element + * has already been initialized and if not, calls the assembleMethod to initialize it. + * + * @return {void} + * @since 1.7.0 + * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/connectedCallback + */ + connectedCallback() { + // Check if the object has already been initialized + if (!hasObjectLink(this, customElementUpdaterLinkSymbol)) { + // If not, call the assembleMethod to initialize the object + this[assembleMethodSymbol](); + } + } + + /** + * Called every time the element is removed from the DOM. Useful for running clean up code. + * + * @return {void} + * @since 1.7.0 + */ + disconnectedCallback() { + } + + /** + * The custom element has been moved into a new document (e.g. someone called document.adoptNode(el)). + * + * @return {void} + * @since 1.7.0 + */ + adoptedCallback() { + } + + /** + * Called when an observed attribute has been added, removed, updated, or replaced. Also called for initial + * values when an element is created by the parser, or upgraded. Note: only attributes listed in the observedAttributes + * property will receive this callback. + * + * @param {string} attrName + * @param {string} oldVal + * @param {string} newVal + * @return {void} + * @since 1.15.0 + */ + attributeChangedCallback(attrName, oldVal, newVal) { + if (attrName.startsWith("data-monster-option-")) { + setOptionFromAttribute( + this, + attrName, + this[internalSymbol].getSubject()["options"], + ); + } + + const callback = this[attributeObserverSymbol]?.[attrName]; + if (isFunction(callback)) { + try { + callback.call(this, newVal, oldVal); + } catch (e) { + addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, e.toString()); + } + } + } + + /** + * + * @param {Node} node + * @return {boolean} + * @throws {TypeError} value is not an instance of + * @since 1.19.0 + */ + hasNode(node) { + if (containChildNode.call(this, validateInstance(node, Node))) { + return true; + } + + if (!(this.shadowRoot instanceof ShadowRoot)) { + return false; + } + + return containChildNode.call(this.shadowRoot, node); + } + + /** + * Calls a callback function if it exists. + * + * @param {string} name + * @param {*} args + * @returns {*} + */ + callCallback(name, args) { + return callControlCallback.call(this, name, ...args); + } } /** @@ -695,50 +719,50 @@ class CustomElement extends HTMLElement { * @return {any} */ function callControlCallback(callBackFunctionName, ...args) { - if (!isString(callBackFunctionName) || callBackFunctionName === "") { - return; - } - - if (callBackFunctionName in this) { - return this[callBackFunctionName](this, ...args); - } - - if (!this.hasAttribute(ATTRIBUTE_SCRIPT_HOST)) { - return; - } - - if (this[scriptHostElementSymbol].length === 0) { - const targetId = this.getAttribute(ATTRIBUTE_SCRIPT_HOST); - if (!targetId) { - return; - } - - const list = targetId.split(","); - for (const id of list) { - const host = findElementWithIdUpwards(this, targetId); - if (!(host instanceof HTMLElement)) { - continue; - } - - this[scriptHostElementSymbol].push(host); - } - } - - for (const host of this[scriptHostElementSymbol]) { - if (callBackFunctionName in host) { - try { - return host[callBackFunctionName](this, ...args); - } catch (e) { - addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, e.toString()); - } - } - } - - addAttributeToken( - this, - ATTRIBUTE_ERRORMESSAGE, - `callback ${callBackFunctionName} not found`, - ); + if (!isString(callBackFunctionName) || callBackFunctionName === "") { + return; + } + + if (callBackFunctionName in this) { + return this[callBackFunctionName](this, ...args); + } + + if (!this.hasAttribute(ATTRIBUTE_SCRIPT_HOST)) { + return; + } + + if (this[scriptHostElementSymbol].length === 0) { + const targetId = this.getAttribute(ATTRIBUTE_SCRIPT_HOST); + if (!targetId) { + return; + } + + const list = targetId.split(","); + for (const id of list) { + const host = findElementWithIdUpwards(this, targetId); + if (!(host instanceof HTMLElement)) { + continue; + } + + this[scriptHostElementSymbol].push(host); + } + } + + for (const host of this[scriptHostElementSymbol]) { + if (callBackFunctionName in host) { + try { + return host[callBackFunctionName](this, ...args); + } catch (e) { + addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, e.toString()); + } + } + } + + addAttributeToken( + this, + ATTRIBUTE_ERRORMESSAGE, + `callback ${callBackFunctionName} not found`, + ); } /** @@ -755,16 +779,16 @@ function callControlCallback(callBackFunctionName, ...args) { * @since 1.8.0 */ function initFromCallbackHost() { - // Set the default callback function name - let callBackFunctionName = initControlCallbackName; + // Set the default callback function name + let callBackFunctionName = initControlCallbackName; - // If the `data-monster-option-callback` attribute is set, use its value as the callback function name - if (this.hasAttribute(ATTRIBUTE_INIT_CALLBACK)) { - callBackFunctionName = this.getAttribute(ATTRIBUTE_INIT_CALLBACK); - } + // If the `data-monster-option-callback` attribute is set, use its value as the callback function name + if (this.hasAttribute(ATTRIBUTE_INIT_CALLBACK)) { + callBackFunctionName = this.getAttribute(ATTRIBUTE_INIT_CALLBACK); + } - // Call the callback function with the element as a parameter if it exists - callControlCallback.call(this, callBackFunctionName); + // Call the callback function with the element as a parameter if it exists + callControlCallback.call(this, callBackFunctionName); } /** @@ -774,35 +798,35 @@ function initFromCallbackHost() { * @this CustomElement */ function attachAttributeChangeMutationObserver() { - const self = this; - - if (typeof self[attributeMutationObserverSymbol] !== "undefined") { - return; - } - - self[attributeMutationObserverSymbol] = new MutationObserver(function ( - mutations, - observer, - ) { - for (const mutation of mutations) { - if (mutation.type === "attributes") { - self.attributeChangedCallback( - mutation.attributeName, - mutation.oldValue, - mutation.target.getAttribute(mutation.attributeName), - ); - } - } - }); - - try { - self[attributeMutationObserverSymbol].observe(self, { - attributes: true, - attributeOldValue: true, - }); - } catch (e) { - addAttributeToken(self, ATTRIBUTE_ERRORMESSAGE, e.toString()); - } + const self = this; + + if (typeof self[attributeMutationObserverSymbol] !== "undefined") { + return; + } + + self[attributeMutationObserverSymbol] = new MutationObserver(function ( + mutations, + observer, + ) { + for (const mutation of mutations) { + if (mutation.type === "attributes") { + self.attributeChangedCallback( + mutation.attributeName, + mutation.oldValue, + mutation.target.getAttribute(mutation.attributeName), + ); + } + } + }); + + try { + self[attributeMutationObserverSymbol].observe(self, { + attributes: true, + attributeOldValue: true, + }); + } catch (e) { + addAttributeToken(self, ATTRIBUTE_ERRORMESSAGE, e.toString()); + } } /** @@ -812,19 +836,19 @@ function attachAttributeChangeMutationObserver() { * @return {boolean} */ function containChildNode(node) { - if (this.contains(node)) { - return true; - } + if (this.contains(node)) { + return true; + } - for (const [, e] of Object.entries(this.childNodes)) { - if (e.contains(node)) { - return true; - } + for (const [, e] of Object.entries(this.childNodes)) { + if (e.contains(node)) { + return true; + } - containChildNode.call(e, node); - } + containChildNode.call(e, node); + } - return false; + return false; } /** @@ -834,89 +858,89 @@ function containChildNode(node) { * @this CustomElement */ function initOptionObserver() { - const self = this; - - let lastDisabledValue = undefined; - self.attachObserver( - new Observer(function () { - const flag = self.getOption("disabled"); - - if (flag === lastDisabledValue) { - return; - } - - lastDisabledValue = flag; - - if (!(self.shadowRoot instanceof ShadowRoot)) { - return; - } - - const query = - "button, command, fieldset, keygen, optgroup, option, select, textarea, input, [data-monster-objectlink]"; - const elements = self.shadowRoot.querySelectorAll(query); - - let nodeList; - try { - nodeList = new Set([ - ...elements, - ...getSlottedElements.call(self, query), - ]); - } catch (e) { - nodeList = elements; - } - - for (const element of [...nodeList]) { - if (flag === true) { - element.setAttribute(ATTRIBUTE_DISABLED, ""); - } else { - element.removeAttribute(ATTRIBUTE_DISABLED); - } - } - }), - ); - - self.attachObserver( - new Observer(function () { - // not initialised - if (!hasObjectLink(self, customElementUpdaterLinkSymbol)) { - return; - } - // inform every element - const updaters = getLinkedObjects(self, customElementUpdaterLinkSymbol); - - for (const list of updaters) { - for (const updater of list) { - const d = clone(self[internalSymbol].getRealSubject()["options"]); - Object.assign(updater.getSubject(), d); - } - } - }), - ); - - // disabled - self[attributeObserverSymbol][ATTRIBUTE_DISABLED] = () => { - if (self.hasAttribute(ATTRIBUTE_DISABLED)) { - self.setOption(ATTRIBUTE_DISABLED, true); - } else { - self.setOption(ATTRIBUTE_DISABLED, undefined); - } - }; - - // data-monster-options - self[attributeObserverSymbol][ATTRIBUTE_OPTIONS] = () => { - const options = getOptionsFromAttributes.call(self); - if (isObject(options) && Object.keys(options).length > 0) { - self.setOptions(options); - } - }; - - // data-monster-options-selector - self[attributeObserverSymbol][ATTRIBUTE_OPTIONS_SELECTOR] = () => { - const options = getOptionsFromScriptTag.call(self); - if (isObject(options) && Object.keys(options).length > 0) { - self.setOptions(options); - } - }; + const self = this; + + let lastDisabledValue = undefined; + self.attachObserver( + new Observer(function () { + const flag = self.getOption("disabled"); + + if (flag === lastDisabledValue) { + return; + } + + lastDisabledValue = flag; + + if (!(self.shadowRoot instanceof ShadowRoot)) { + return; + } + + const query = + "button, command, fieldset, keygen, optgroup, option, select, textarea, input, [data-monster-objectlink]"; + const elements = self.shadowRoot.querySelectorAll(query); + + let nodeList; + try { + nodeList = new Set([ + ...elements, + ...getSlottedElements.call(self, query), + ]); + } catch (e) { + nodeList = elements; + } + + for (const element of [...nodeList]) { + if (flag === true) { + element.setAttribute(ATTRIBUTE_DISABLED, ""); + } else { + element.removeAttribute(ATTRIBUTE_DISABLED); + } + } + }), + ); + + self.attachObserver( + new Observer(function () { + // not initialised + if (!hasObjectLink(self, customElementUpdaterLinkSymbol)) { + return; + } + // inform every element + const updaters = getLinkedObjects(self, customElementUpdaterLinkSymbol); + + for (const list of updaters) { + for (const updater of list) { + const d = clone(self[internalSymbol].getRealSubject()["options"]); + Object.assign(updater.getSubject(), d); + } + } + }), + ); + + // disabled + self[attributeObserverSymbol][ATTRIBUTE_DISABLED] = () => { + if (self.hasAttribute(ATTRIBUTE_DISABLED)) { + self.setOption(ATTRIBUTE_DISABLED, true); + } else { + self.setOption(ATTRIBUTE_DISABLED, undefined); + } + }; + + // data-monster-options + self[attributeObserverSymbol][ATTRIBUTE_OPTIONS] = () => { + const options = getOptionsFromAttributes.call(self); + if (isObject(options) && Object.keys(options).length > 0) { + self.setOptions(options); + } + }; + + // data-monster-options-selector + self[attributeObserverSymbol][ATTRIBUTE_OPTIONS_SELECTOR] = () => { + const options = getOptionsFromScriptTag.call(self); + if (isObject(options) && Object.keys(options).length > 0) { + self.setOptions(options); + } + }; } /** @@ -925,37 +949,37 @@ function initOptionObserver() { * @throws {TypeError} value is not a object */ function getOptionsFromScriptTag() { - if (!this.hasAttribute(ATTRIBUTE_OPTIONS_SELECTOR)) { - return {}; - } - - const node = document.querySelector( - this.getAttribute(ATTRIBUTE_OPTIONS_SELECTOR), - ); - if (!(node instanceof HTMLScriptElement)) { - addAttributeToken( - this, - ATTRIBUTE_ERRORMESSAGE, - `the selector ${ATTRIBUTE_OPTIONS_SELECTOR} for options was specified (${this.getAttribute( - ATTRIBUTE_OPTIONS_SELECTOR, - )}) but not found.`, - ); - return {}; - } - - let obj = {}; - - try { - obj = parseOptionsJSON.call(this, node.textContent.trim()); - } catch (e) { - addAttributeToken( - this, - ATTRIBUTE_ERRORMESSAGE, - `when analyzing the configuration from the script tag there was an error. ${e}`, - ); - } - - return obj; + if (!this.hasAttribute(ATTRIBUTE_OPTIONS_SELECTOR)) { + return {}; + } + + const node = document.querySelector( + this.getAttribute(ATTRIBUTE_OPTIONS_SELECTOR), + ); + if (!(node instanceof HTMLScriptElement)) { + addAttributeToken( + this, + ATTRIBUTE_ERRORMESSAGE, + `the selector ${ATTRIBUTE_OPTIONS_SELECTOR} for options was specified (${this.getAttribute( + ATTRIBUTE_OPTIONS_SELECTOR, + )}) but not found.`, + ); + return {}; + } + + let obj = {}; + + try { + obj = parseOptionsJSON.call(this, node.textContent.trim()); + } catch (e) { + addAttributeToken( + this, + ATTRIBUTE_ERRORMESSAGE, + `when analyzing the configuration from the script tag there was an error. ${e}`, + ); + } + + return obj; } /** @@ -963,21 +987,21 @@ function getOptionsFromScriptTag() { * @return {object} */ function getOptionsFromAttributes() { - if (this.hasAttribute(ATTRIBUTE_OPTIONS)) { - try { - return parseOptionsJSON.call(this, this.getAttribute(ATTRIBUTE_OPTIONS)); - } catch (e) { - addAttributeToken( - this, - ATTRIBUTE_ERRORMESSAGE, - `the options attribute ${ATTRIBUTE_OPTIONS} does not contain a valid json definition (actual: ${this.getAttribute( - ATTRIBUTE_OPTIONS, - )}).${e}`, - ); - } - } - - return {}; + if (this.hasAttribute(ATTRIBUTE_OPTIONS)) { + try { + return parseOptionsJSON.call(this, this.getAttribute(ATTRIBUTE_OPTIONS)); + } catch (e) { + addAttributeToken( + this, + ATTRIBUTE_ERRORMESSAGE, + `the options attribute ${ATTRIBUTE_OPTIONS} does not contain a valid json definition (actual: ${this.getAttribute( + ATTRIBUTE_OPTIONS, + )}).${e}`, + ); + } + } + + return {}; } /** @@ -989,25 +1013,26 @@ function getOptionsFromAttributes() { * @throws {error} Throws an error if the JSON data is not valid. */ function parseOptionsJSON(data) { - let obj = {}; - - if (!isString(data)) { - return obj; - } - - // the configuration can be specified as a data url. - try { - const dataUrl = parseDataURL(data); - data = dataUrl.content; - } catch (e) {} - - try { - obj = JSON.parse(data); - } catch (e) { - throw e; - } - - return validateObject(obj); + let obj = {}; + + if (!isString(data)) { + return obj; + } + + // the configuration can be specified as a data url. + try { + const dataUrl = parseDataURL(data); + data = dataUrl.content; + } catch (e) { + } + + try { + obj = JSON.parse(data); + } catch (e) { + throw e; + } + + return validateObject(obj); } /** @@ -1015,21 +1040,21 @@ function parseOptionsJSON(data) { * @return {initHtmlContent} */ function initHtmlContent() { - try { - const template = findDocumentTemplate(this.constructor.getTag()); - this.appendChild(template.createDocumentFragment()); - } catch (e) { - let html = this.getOption("templates.main", ""); - if (isString(html) && html.length > 0) { - const mapping = this.getOption("templateMapping", {}); - if (isObject(mapping)) { - html = new Formatter(mapping, {}).format(html); - } - this.innerHTML = html; - } - } - - return this; + try { + const template = findDocumentTemplate(this.constructor.getTag()); + this.appendChild(template.createDocumentFragment()); + } catch (e) { + let html = this.getOption("templates.main", ""); + if (isString(html) && html.length > 0) { + const mapping = this.getOption("templateMapping", {}); + if (isObject(mapping)) { + html = new Formatter(mapping, {}).format(html); + } + this.innerHTML = html; + } + } + + return this; } /** @@ -1042,49 +1067,49 @@ function initHtmlContent() { * @throws {TypeError} value is not an instance of */ function initCSSStylesheet() { - if (!(this.shadowRoot instanceof ShadowRoot)) { - return this; - } - - const styleSheet = this.constructor.getCSSStyleSheet(); - - if (styleSheet instanceof CSSStyleSheet) { - if (styleSheet.cssRules.length > 0) { - this.shadowRoot.adoptedStyleSheets = [styleSheet]; - } - } else if (isArray(styleSheet)) { - const assign = []; - for (const s of styleSheet) { - if (isString(s)) { - const trimedStyleSheet = s.trim(); - if (trimedStyleSheet !== "") { - const style = document.createElement("style"); - style.innerHTML = trimedStyleSheet; - this.shadowRoot.prepend(style); - } - continue; - } - - validateInstance(s, CSSStyleSheet); - - if (s.cssRules.length > 0) { - assign.push(s); - } - } - - if (assign.length > 0) { - this.shadowRoot.adoptedStyleSheets = assign; - } - } else if (isString(styleSheet)) { - const trimedStyleSheet = styleSheet.trim(); - if (trimedStyleSheet !== "") { - const style = document.createElement("style"); - style.innerHTML = styleSheet; - this.shadowRoot.prepend(style); - } - } - - return this; + if (!(this.shadowRoot instanceof ShadowRoot)) { + return this; + } + + const styleSheet = this.constructor.getCSSStyleSheet(); + + if (styleSheet instanceof CSSStyleSheet) { + if (styleSheet.cssRules.length > 0) { + this.shadowRoot.adoptedStyleSheets = [styleSheet]; + } + } else if (isArray(styleSheet)) { + const assign = []; + for (const s of styleSheet) { + if (isString(s)) { + const trimedStyleSheet = s.trim(); + if (trimedStyleSheet !== "") { + const style = document.createElement("style"); + style.innerHTML = trimedStyleSheet; + this.shadowRoot.prepend(style); + } + continue; + } + + validateInstance(s, CSSStyleSheet); + + if (s.cssRules.length > 0) { + assign.push(s); + } + } + + if (assign.length > 0) { + this.shadowRoot.adoptedStyleSheets = assign; + } + } else if (isString(styleSheet)) { + const trimedStyleSheet = styleSheet.trim(); + if (trimedStyleSheet !== "") { + const style = document.createElement("style"); + style.innerHTML = styleSheet; + this.shadowRoot.prepend(style); + } + } + + return this; } /** @@ -1097,35 +1122,35 @@ function initCSSStylesheet() { * @since 1.8.0 */ function initShadowRoot() { - let template; - let html; - - try { - template = findDocumentTemplate(this.constructor.getTag()); - } catch (e) { - html = this.getOption("templates.main", ""); - if (!isString(html) || html === undefined || html === "") { - throw new Error("html is not set."); - } - } - - this.attachShadow({ - mode: this.getOption("shadowMode", "open"), - delegatesFocus: this.getOption("delegatesFocus", true), - }); - - if (template instanceof Template) { - this.shadowRoot.appendChild(template.createDocumentFragment()); - return this; - } - - const mapping = this.getOption("templateMapping", {}); - if (isObject(mapping)) { - html = new Formatter(mapping).format(html); - } - - this.shadowRoot.innerHTML = html; - return this; + let template; + let html; + + try { + template = findDocumentTemplate(this.constructor.getTag()); + } catch (e) { + html = this.getOption("templates.main", ""); + if (!isString(html) || html === undefined || html === "") { + throw new Error("html is not set."); + } + } + + this.attachShadow({ + mode: this.getOption("shadowMode", "open"), + delegatesFocus: this.getOption("delegatesFocus", true), + }); + + if (template instanceof Template) { + this.shadowRoot.appendChild(template.createDocumentFragment()); + return this; + } + + const mapping = this.getOption("templateMapping", {}); + if (isObject(mapping)) { + html = new Formatter(mapping).format(html); + } + + this.shadowRoot.innerHTML = html; + return this; } /** @@ -1140,20 +1165,20 @@ function initShadowRoot() { * @throws {DOMException} Failed to execute 'define' on 'CustomElementRegistry': is not a valid custom element name */ function registerCustomElement(element) { - validateFunction(element); - const customElements = getGlobalObject("customElements"); - if (customElements === undefined) { - throw new Error("customElements is not supported."); - } - - const tag = element?.getTag(); - if (!isString(tag) || tag === "") { - throw new Error("tag is not set."); - } - - if (customElements.get(tag) !== undefined) { - return; - } - - customElements.define(tag, element); + validateFunction(element); + const customElements = getGlobalObject("customElements"); + if (customElements === undefined) { + throw new Error("customElements is not supported."); + } + + const tag = element?.getTag(); + if (!isString(tag) || tag === "") { + throw new Error("tag is not set."); + } + + if (customElements.get(tag) !== undefined) { + return; + } + + customElements.define(tag, element); } diff --git a/source/dom/updater.mjs b/source/dom/updater.mjs index 2651e1f63afca206071b057c988a304db5f65a28..8872ce3565498f20e97498fde299ad4c15b3c3b3 100644 --- a/source/dom/updater.mjs +++ b/source/dom/updater.mjs @@ -5,34 +5,35 @@ * License text available at https://www.gnu.org/licenses/agpl-3.0.en.html */ -import { internalSymbol } from "../constants.mjs"; -import { diff } from "../data/diff.mjs"; -import { Pathfinder } from "../data/pathfinder.mjs"; -import { Pipe } from "../data/pipe.mjs"; +import {internalSymbol} from "../constants.mjs"; +import {diff} from "../data/diff.mjs"; +import {Pathfinder} from "../data/pathfinder.mjs"; +import {Pipe} from "../data/pipe.mjs"; import { - ATTRIBUTE_ERRORMESSAGE, - ATTRIBUTE_UPDATER_ATTRIBUTES, - ATTRIBUTE_UPDATER_BIND, - ATTRIBUTE_UPDATER_INSERT, - ATTRIBUTE_UPDATER_INSERT_REFERENCE, - ATTRIBUTE_UPDATER_REMOVE, - ATTRIBUTE_UPDATER_REPLACE, - ATTRIBUTE_UPDATER_SELECT_THIS, + ATTRIBUTE_ERRORMESSAGE, + ATTRIBUTE_UPDATER_ATTRIBUTES, + ATTRIBUTE_UPDATER_BIND, + ATTRIBUTE_UPDATER_BIND_TYPE, + ATTRIBUTE_UPDATER_INSERT, + ATTRIBUTE_UPDATER_INSERT_REFERENCE, + ATTRIBUTE_UPDATER_REMOVE, + ATTRIBUTE_UPDATER_REPLACE, + ATTRIBUTE_UPDATER_SELECT_THIS, } from "./constants.mjs"; -import { Base } from "../types/base.mjs"; -import { isArray, isInstance, isIterable } from "../types/is.mjs"; -import { Observer } from "../types/observer.mjs"; -import { ProxyObserver } from "../types/proxyobserver.mjs"; -import { validateArray, validateInstance } from "../types/validate.mjs"; -import { Sleep } from "../util/sleep.mjs"; -import { clone } from "../util/clone.mjs"; -import { trimSpaces } from "../util/trimspaces.mjs"; -import { addToObjectLink } from "./attributes.mjs"; -import { findTargetElementFromEvent } from "./events.mjs"; -import { findDocumentTemplate } from "./template.mjs"; +import {Base} from "../types/base.mjs"; +import {isArray, isString, isInstance, isIterable} from "../types/is.mjs"; +import {Observer} from "../types/observer.mjs"; +import {ProxyObserver} from "../types/proxyobserver.mjs"; +import {validateArray, validateInstance} from "../types/validate.mjs"; +import {Sleep} from "../util/sleep.mjs"; +import {clone} from "../util/clone.mjs"; +import {trimSpaces} from "../util/trimspaces.mjs"; +import {addToObjectLink} from "./attributes.mjs"; +import {findTargetElementFromEvent} from "./events.mjs"; +import {findDocumentTemplate} from "./template.mjs"; -export { Updater, addObjectWithUpdaterToElement }; +export {Updater, addObjectWithUpdaterToElement}; /** * The updater class connects an object with the dom. In this way, structures and contents in the DOM can be programmatically adapted via attributes. @@ -57,182 +58,182 @@ export { Updater, addObjectWithUpdaterToElement }; * @summary The updater class connects an object with the dom */ class Updater extends Base { - /** - * @since 1.8.0 - * @param {HTMLElement} element - * @param {object|ProxyObserver|undefined} subject - * @throws {TypeError} value is not a object - * @throws {TypeError} value is not an instance of HTMLElement - * @see {@link Monster.DOM.findDocumentTemplate} - */ - constructor(element, subject) { - super(); - - /** - * @type {HTMLElement} - */ - if (subject === undefined) subject = {}; - if (!isInstance(subject, ProxyObserver)) { - subject = new ProxyObserver(subject); - } - - this[internalSymbol] = { - element: validateInstance(element, HTMLElement), - last: {}, - callbacks: new Map(), - eventTypes: ["keyup", "click", "change", "drop", "touchend", "input"], - subject: subject, - }; - - this[internalSymbol].callbacks.set( - "checkstate", - getCheckStateCallback.call(this), - ); - - this[internalSymbol].subject.attachObserver( - new Observer(() => { - const s = this[internalSymbol].subject.getRealSubject(); - - const diffResult = diff(this[internalSymbol].last, s); - this[internalSymbol].last = clone(s); - - const promises = []; - - for (const [, change] of Object.entries(diffResult)) { - promises.push( - Sleep(1).then(() => { - removeElement.call(this, change); - insertElement.call(this, change); - updateContent.call(this, change); - updateAttributes.call(this, change); - }), - ); - } - - return Promise.all(promises); - }), - ); - } - - /** - * Defaults: 'keyup', 'click', 'change', 'drop', 'touchend' - * - * @see {@link https://developer.mozilla.org/de/docs/Web/Events} - * @since 1.9.0 - * @param {Array} types - * @return {Updater} - */ - setEventTypes(types) { - this[internalSymbol].eventTypes = validateArray(types); - return this; - } - - /** - * With this method, the eventlisteners are hooked in and the magic begins. - * - * ``` - * updater.run().then(() => { - * updater.enableEventProcessing(); - * }); - * ``` - * - * @since 1.9.0 - * @return {Updater} - * @throws {Error} the bind argument must start as a value with a path - */ - enableEventProcessing() { - this.disableEventProcessing(); - - for (const type of this[internalSymbol].eventTypes) { - // @see https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener - this[internalSymbol].element.addEventListener( - type, - getControlEventHandler.call(this), - { - capture: true, - passive: true, - }, - ); - } - - return this; - } - - /** - * This method turns off the magic or who loves it more profane it removes the eventListener. - * - * @since 1.9.0 - * @return {Updater} - */ - disableEventProcessing() { - for (const type of this[internalSymbol].eventTypes) { - this[internalSymbol].element.removeEventListener( - type, - getControlEventHandler.call(this), - ); - } - - return this; - } - - /** - * The run method must be called for the update to start working. - * The method ensures that changes are detected. - * - * ``` - * updater.run().then(() => { - * updater.enableEventProcessing(); - * }); - * ``` - * - * @summary Let the magic begin - * @return {Promise} - */ - run() { - // the key __init__has no further meaning and is only - // used to create the diff for empty objects. - this[internalSymbol].last = { __init__: true }; - return this[internalSymbol].subject.notifyObservers(); - } - - /** - * Gets the values of bound elements and changes them in subject - * - * @since 1.27.0 - * @return {Monster.DOM.Updater} - */ - retrieve() { - retrieveFromBindings.call(this); - return this; - } - - /** - * If you have passed a ProxyObserver in the constructor, you will get the object that the ProxyObserver manages here. - * However, if you passed a simple object, here you will get a proxy for that object. - * - * For changes the ProxyObserver must be used. - * - * @since 1.8.0 - * @return {Proxy} - */ - getSubject() { - return this[internalSymbol].subject.getSubject(); - } - - /** - * This method can be used to register commands that can be called via call: instruction. - * This can be used to provide a pipe with its own functionality. - * - * @param {string} name - * @param {function} callback - * @returns {Transformer} - * @throws {TypeError} value is not a string - * @throws {TypeError} value is not a function - */ - setCallback(name, callback) { - this[internalSymbol].callbacks.set(name, callback); - return this; - } + /** + * @since 1.8.0 + * @param {HTMLElement} element + * @param {object|ProxyObserver|undefined} subject + * @throws {TypeError} value is not a object + * @throws {TypeError} value is not an instance of HTMLElement + * @see {@link Monster.DOM.findDocumentTemplate} + */ + constructor(element, subject) { + super(); + + /** + * @type {HTMLElement} + */ + if (subject === undefined) subject = {}; + if (!isInstance(subject, ProxyObserver)) { + subject = new ProxyObserver(subject); + } + + this[internalSymbol] = { + element: validateInstance(element, HTMLElement), + last: {}, + callbacks: new Map(), + eventTypes: ["keyup", "click", "change", "drop", "touchend", "input"], + subject: subject, + }; + + this[internalSymbol].callbacks.set( + "checkstate", + getCheckStateCallback.call(this), + ); + + this[internalSymbol].subject.attachObserver( + new Observer(() => { + const s = this[internalSymbol].subject.getRealSubject(); + + const diffResult = diff(this[internalSymbol].last, s); + this[internalSymbol].last = clone(s); + + const promises = []; + + for (const [, change] of Object.entries(diffResult)) { + promises.push( + Sleep(1).then(() => { + removeElement.call(this, change); + insertElement.call(this, change); + updateContent.call(this, change); + updateAttributes.call(this, change); + }), + ); + } + + return Promise.all(promises); + }), + ); + } + + /** + * Defaults: 'keyup', 'click', 'change', 'drop', 'touchend' + * + * @see {@link https://developer.mozilla.org/de/docs/Web/Events} + * @since 1.9.0 + * @param {Array} types + * @return {Updater} + */ + setEventTypes(types) { + this[internalSymbol].eventTypes = validateArray(types); + return this; + } + + /** + * With this method, the eventlisteners are hooked in and the magic begins. + * + * ``` + * updater.run().then(() => { + * updater.enableEventProcessing(); + * }); + * ``` + * + * @since 1.9.0 + * @return {Updater} + * @throws {Error} the bind argument must start as a value with a path + */ + enableEventProcessing() { + this.disableEventProcessing(); + + for (const type of this[internalSymbol].eventTypes) { + // @see https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener + this[internalSymbol].element.addEventListener( + type, + getControlEventHandler.call(this), + { + capture: true, + passive: true, + }, + ); + } + + return this; + } + + /** + * This method turns off the magic or who loves it more profane it removes the eventListener. + * + * @since 1.9.0 + * @return {Updater} + */ + disableEventProcessing() { + for (const type of this[internalSymbol].eventTypes) { + this[internalSymbol].element.removeEventListener( + type, + getControlEventHandler.call(this), + ); + } + + return this; + } + + /** + * The run method must be called for the update to start working. + * The method ensures that changes are detected. + * + * ``` + * updater.run().then(() => { + * updater.enableEventProcessing(); + * }); + * ``` + * + * @summary Let the magic begin + * @return {Promise} + */ + run() { + // the key __init__has no further meaning and is only + // used to create the diff for empty objects. + this[internalSymbol].last = {__init__: true}; + return this[internalSymbol].subject.notifyObservers(); + } + + /** + * Gets the values of bound elements and changes them in subject + * + * @since 1.27.0 + * @return {Monster.DOM.Updater} + */ + retrieve() { + retrieveFromBindings.call(this); + return this; + } + + /** + * If you have passed a ProxyObserver in the constructor, you will get the object that the ProxyObserver manages here. + * However, if you passed a simple object, here you will get a proxy for that object. + * + * For changes the ProxyObserver must be used. + * + * @since 1.8.0 + * @return {Proxy} + */ + getSubject() { + return this[internalSymbol].subject.getSubject(); + } + + /** + * This method can be used to register commands that can be called via call: instruction. + * This can be used to provide a pipe with its own functionality. + * + * @param {string} name + * @param {function} callback + * @returns {Transformer} + * @throws {TypeError} value is not a string + * @throws {TypeError} value is not a function + */ + setCallback(name, callback) { + this[internalSymbol].callbacks.set(name, callback); + return this; + } } /** @@ -243,20 +244,20 @@ class Updater extends Base { * @this Updater */ function getCheckStateCallback() { - return function (current) { - // this is a reference to the current object (therefore no array function here) - if (this instanceof HTMLInputElement) { - if (["radio", "checkbox"].indexOf(this.type) !== -1) { - return `${this.value}` === `${current}` ? "true" : undefined; - } - } else if (this instanceof HTMLOptionElement) { - if (isArray(current) && current.indexOf(this.value) !== -1) { - return "true"; - } - - return undefined; - } - }; + return function (current) { + // this is a reference to the current object (therefore no array function here) + if (this instanceof HTMLInputElement) { + if (["radio", "checkbox"].indexOf(this.type) !== -1) { + return `${this.value}` === `${current}` ? "true" : undefined; + } + } else if (this instanceof HTMLOptionElement) { + if (isArray(current) && current.indexOf(this.value) !== -1) { + return "true"; + } + + return undefined; + } + }; } /** @@ -271,26 +272,26 @@ const symbol = Symbol("@schukai/monster/updater@@EventHandler"); * @throws {Error} the bind argument must start as a value with a path */ function getControlEventHandler() { - if (this[symbol]) { - return this[symbol]; - } - - /** - * @throws {Error} the bind argument must start as a value with a path. - * @throws {Error} unsupported object - * @param {Event} event - */ - this[symbol] = (event) => { - const element = findTargetElementFromEvent(event, ATTRIBUTE_UPDATER_BIND); - - if (element === undefined) { - return; - } - - retrieveAndSetValue.call(this, element); - }; - - return this[symbol]; + if (this[symbol]) { + return this[symbol]; + } + + /** + * @throws {Error} the bind argument must start as a value with a path. + * @throws {Error} unsupported object + * @param {Event} event + */ + this[symbol] = (event) => { + const element = findTargetElementFromEvent(event, ATTRIBUTE_UPDATER_BIND); + + if (element === undefined) { + return; + } + + retrieveAndSetValue.call(this, element); + }; + + return this[symbol]; } /** @@ -301,70 +302,100 @@ function getControlEventHandler() { * @private */ function retrieveAndSetValue(element) { - const pathfinder = new Pathfinder(this[internalSymbol].subject.getSubject()); - - let path = element.getAttribute(ATTRIBUTE_UPDATER_BIND); - if (path === null) - throw new Error("the bind argument must start as a value with a path"); - - if (path.indexOf("path:") !== 0) { - throw new Error("the bind argument must start as a value with a path"); - } - - path = path.substring(5); - - let value; - - if (element instanceof HTMLInputElement) { - switch (element.type) { - case "checkbox": - value = element.checked ? element.value : undefined; - break; - default: - value = element.value; - break; - } - } else if (element instanceof HTMLTextAreaElement) { - value = element.value; - } else if (element instanceof HTMLSelectElement) { - switch (element.type) { - case "select-one": - value = element.value; - break; - case "select-multiple": - value = element.value; - - let options = element?.selectedOptions; - if (options === undefined) - options = element.querySelectorAll(":scope option:checked"); - value = Array.from(options).map(({ value }) => value); - - break; - } - - // values from customelements - } else if ( - (element?.constructor?.prototype && - !!Object.getOwnPropertyDescriptor( - element.constructor.prototype, - "value", - )?.["get"]) || - element.hasOwnProperty("value") - ) { - value = element?.["value"]; - } else { - throw new Error("unsupported object"); - } - - const copy = clone(this[internalSymbol].subject.getRealSubject()); - const pf = new Pathfinder(copy); - pf.setVia(path, value); - - const diffResult = diff(copy, this[internalSymbol].subject.getRealSubject()); - - if (diffResult.length > 0) { - pathfinder.setVia(path, value); - } + const pathfinder = new Pathfinder(this[internalSymbol].subject.getSubject()); + + let path = element.getAttribute(ATTRIBUTE_UPDATER_BIND); + if (path === null) + throw new Error("the bind argument must start as a value with a path"); + + if (path.indexOf("path:") !== 0) { + throw new Error("the bind argument must start as a value with a path"); + } + + path = path.substring(5); // remove path: from the string + + let value; + + if (element instanceof HTMLInputElement) { + switch (element.type) { + case "checkbox": + value = element.checked ? element.value : undefined; + break; + default: + value = element.value; + break; + } + } else if (element instanceof HTMLTextAreaElement) { + value = element.value; + } else if (element instanceof HTMLSelectElement) { + switch (element.type) { + case "select-one": + value = element.value; + break; + case "select-multiple": + value = element.value; + + let options = element?.selectedOptions; + if (options === undefined) + options = element.querySelectorAll(":scope option:checked"); + value = Array.from(options).map(({value}) => value); + + break; + } + + // values from custom elements + } else if ( + (element?.constructor?.prototype && + !!Object.getOwnPropertyDescriptor( + element.constructor.prototype, + "value", + )?.["get"]) || + element.hasOwnProperty("value") + ) { + value = element?.["value"]; + } else { + throw new Error("unsupported object"); + } + + if (isString(value)) { + let type = element.getAttribute(ATTRIBUTE_UPDATER_BIND_TYPE); + switch (type) { + case "number": + case "int": + case "float": + case "integer": + value = Number(value); + if (isNaN(value)) { + value = 0; + } + break; + case "boolean": + case "bool": + case "checkbox": + value = value === "true" || value === "1" || value === "on"; + break; + case "array": + case "list": + value = value.split(","); + break; + case "object": + case "json": + value = JSON.parse(value); + break; + default: + break; + } + } + + const copy = clone(this[internalSymbol].subject.getRealSubject()); + const pf = new Pathfinder(copy); + pf.setVia(path, value); + + const diffResult = diff(copy, this[internalSymbol].subject.getRealSubject()); + + if (diffResult.length > 0) { + pathfinder.setVia(path, value); + } } /** @@ -374,15 +405,15 @@ function retrieveAndSetValue(element) { * @private */ function retrieveFromBindings() { - if (this[internalSymbol].element.matches(`[${ATTRIBUTE_UPDATER_BIND}]`)) { - retrieveAndSetValue.call(this, this[internalSymbol].element); - } - - for (const [, element] of this[internalSymbol].element - .querySelectorAll(`[${ATTRIBUTE_UPDATER_BIND}]`) - .entries()) { - retrieveAndSetValue.call(this, element); - } + if (this[internalSymbol].element.matches(`[${ATTRIBUTE_UPDATER_BIND}]`)) { + retrieveAndSetValue.call(this, this[internalSymbol].element); + } + + for (const [, element] of this[internalSymbol].element + .querySelectorAll(`[${ATTRIBUTE_UPDATER_BIND}]`) + .entries()) { + retrieveAndSetValue.call(this, element); + } } /** @@ -393,11 +424,11 @@ function retrieveFromBindings() { * @return {void} */ function removeElement(change) { - for (const [, element] of this[internalSymbol].element - .querySelectorAll(`:scope [${ATTRIBUTE_UPDATER_REMOVE}]`) - .entries()) { - element.parentNode.removeChild(element); - } + for (const [, element] of this[internalSymbol].element + .querySelectorAll(`:scope [${ATTRIBUTE_UPDATER_REMOVE}]`) + .entries()) { + element.parentNode.removeChild(element); + } } /** @@ -413,133 +444,133 @@ function removeElement(change) { * @this Updater */ function insertElement(change) { - const subject = this[internalSymbol].subject.getRealSubject(); + const subject = this[internalSymbol].subject.getRealSubject(); - const mem = new WeakSet(); - let wd = 0; + const mem = new WeakSet(); + let wd = 0; - const container = this[internalSymbol].element; + const container = this[internalSymbol].element; - while (true) { - let found = false; - wd++; - - const p = clone(change?.["path"]); - if (!isArray(p)) return; - - while (p.length > 0) { - const current = p.join("."); - - let iterator = new Set(); - const query = `[${ATTRIBUTE_UPDATER_INSERT}*="path:${current}"]`; - - const e = container.querySelectorAll(query); - - if (e.length > 0) { - iterator = new Set([...e]); - } - - if (container.matches(query)) { - iterator.add(container); - } - - for (const [, containerElement] of iterator.entries()) { - if (mem.has(containerElement)) continue; - mem.add(containerElement); - - found = true; - - const attributes = containerElement.getAttribute( - ATTRIBUTE_UPDATER_INSERT, - ); - if (attributes === null) continue; - - const def = trimSpaces(attributes); - const i = def.indexOf(" "); - const key = trimSpaces(def.substr(0, i)); - const refPrefix = `${key}-`; - const cmd = trimSpaces(def.substr(i)); - - // this case is actually excluded by the query but is nevertheless checked again here - if (cmd.indexOf("|") > 0) { - throw new Error("pipes are not allowed when cloning a node."); - } - - const pipe = new Pipe(cmd); - this[internalSymbol].callbacks.forEach((f, n) => { - pipe.setCallback(n, f); - }); - - let value; - try { - containerElement.removeAttribute(ATTRIBUTE_ERRORMESSAGE); - value = pipe.run(subject); - } catch (e) { - containerElement.setAttribute(ATTRIBUTE_ERRORMESSAGE, e.message); - } - - const dataPath = cmd.split(":").pop(); - - let insertPoint; - if (containerElement.hasChildNodes()) { - insertPoint = containerElement.lastChild; - } - - if (!isIterable(value)) { - throw new Error("the value is not iterable"); - } - - const available = new Set(); - - for (const [i, obj] of Object.entries(value)) { - const ref = refPrefix + i; - const currentPath = `${dataPath}.${i}`; - - available.add(ref); - const refElement = containerElement.querySelector( - `[${ATTRIBUTE_UPDATER_INSERT_REFERENCE}="${ref}"]`, - ); - - if (refElement instanceof HTMLElement) { - insertPoint = refElement; - continue; - } - - appendNewDocumentFragment(containerElement, key, ref, currentPath); - } - - const nodes = containerElement.querySelectorAll( - `[${ATTRIBUTE_UPDATER_INSERT_REFERENCE}*="${refPrefix}"]`, - ); - - for (const [, node] of Object.entries(nodes)) { - if ( - !available.has( - node.getAttribute(ATTRIBUTE_UPDATER_INSERT_REFERENCE), - ) - ) { - try { - containerElement.removeChild(node); - } catch (e) { - containerElement.setAttribute( - ATTRIBUTE_ERRORMESSAGE, - `${containerElement.getAttribute(ATTRIBUTE_ERRORMESSAGE)}, ${ - e.message - }`.trim(), - ); - } - } - } - } - - p.pop(); - } - - if (found === false) break; - if (wd++ > 200) { - throw new Error("the maximum depth for the recursion is reached."); - } - } + while (true) { + let found = false; + wd++; + + const p = clone(change?.["path"]); + if (!isArray(p)) return; + + while (p.length > 0) { + const current = p.join("."); + + let iterator = new Set(); + const query = `[${ATTRIBUTE_UPDATER_INSERT}*="path:${current}"]`; + + const e = container.querySelectorAll(query); + + if (e.length > 0) { + iterator = new Set([...e]); + } + + if (container.matches(query)) { + iterator.add(container); + } + + for (const [, containerElement] of iterator.entries()) { + if (mem.has(containerElement)) continue; + mem.add(containerElement); + + found = true; + + const attributes = containerElement.getAttribute( + ATTRIBUTE_UPDATER_INSERT, + ); + if (attributes === null) continue; + + const def = trimSpaces(attributes); + const i = def.indexOf(" "); + const key = trimSpaces(def.substr(0, i)); + const refPrefix = `${key}-`; + const cmd = trimSpaces(def.substr(i)); + + // this case is actually excluded by the query but is nevertheless checked again here + if (cmd.indexOf("|") > 0) { + throw new Error("pipes are not allowed when cloning a node."); + } + + const pipe = new Pipe(cmd); + this[internalSymbol].callbacks.forEach((f, n) => { + pipe.setCallback(n, f); + }); + + let value; + try { + containerElement.removeAttribute(ATTRIBUTE_ERRORMESSAGE); + value = pipe.run(subject); + } catch (e) { + containerElement.setAttribute(ATTRIBUTE_ERRORMESSAGE, e.message); + } + + const dataPath = cmd.split(":").pop(); + + let insertPoint; + if (containerElement.hasChildNodes()) { + insertPoint = containerElement.lastChild; + } + + if (!isIterable(value)) { + throw new Error("the value is not iterable"); + } + + const available = new Set(); + + for (const [i, obj] of Object.entries(value)) { + const ref = refPrefix + i; + const currentPath = `${dataPath}.${i}`; + + available.add(ref); + const refElement = containerElement.querySelector( + `[${ATTRIBUTE_UPDATER_INSERT_REFERENCE}="${ref}"]`, + ); + + if (refElement instanceof HTMLElement) { + insertPoint = refElement; + continue; + } + + appendNewDocumentFragment(containerElement, key, ref, currentPath); + } + + const nodes = containerElement.querySelectorAll( + `[${ATTRIBUTE_UPDATER_INSERT_REFERENCE}*="${refPrefix}"]`, + ); + + for (const [, node] of Object.entries(nodes)) { + if ( + !available.has( + node.getAttribute(ATTRIBUTE_UPDATER_INSERT_REFERENCE), + ) + ) { + try { + containerElement.removeChild(node); + } catch (e) { + containerElement.setAttribute( + ATTRIBUTE_ERRORMESSAGE, + `${containerElement.getAttribute(ATTRIBUTE_ERRORMESSAGE)}, ${ + e.message + }`.trim(), + ); + } + } + } + } + + p.pop(); + } + + if (found === false) break; + if (wd++ > 200) { + throw new Error("the maximum depth for the recursion is reached."); + } + } } /** @@ -554,17 +585,17 @@ function insertElement(change) { * @throws {Error} no template was found with the specified key. */ function appendNewDocumentFragment(container, key, ref, path) { - const template = findDocumentTemplate(key, container); + const template = findDocumentTemplate(key, container); - const nodes = template.createDocumentFragment(); - for (const [, node] of Object.entries(nodes.childNodes)) { - if (node instanceof HTMLElement) { - applyRecursive(node, key, path); - node.setAttribute(ATTRIBUTE_UPDATER_INSERT_REFERENCE, ref); - } + const nodes = template.createDocumentFragment(); + for (const [, node] of Object.entries(nodes.childNodes)) { + if (node instanceof HTMLElement) { + applyRecursive(node, key, path); + node.setAttribute(ATTRIBUTE_UPDATER_INSERT_REFERENCE, ref); + } - container.appendChild(node); - } + container.appendChild(node); + } } /** @@ -577,27 +608,27 @@ function appendNewDocumentFragment(container, key, ref, path) { * @return {void} */ function applyRecursive(node, key, path) { - if (node instanceof HTMLElement) { - if (node.hasAttribute(ATTRIBUTE_UPDATER_REPLACE)) { - const value = node.getAttribute(ATTRIBUTE_UPDATER_REPLACE); - node.setAttribute( - ATTRIBUTE_UPDATER_REPLACE, - value.replaceAll(`path:${key}`, `path:${path}`), - ); - } - - if (node.hasAttribute(ATTRIBUTE_UPDATER_ATTRIBUTES)) { - const value = node.getAttribute(ATTRIBUTE_UPDATER_ATTRIBUTES); - node.setAttribute( - ATTRIBUTE_UPDATER_ATTRIBUTES, - value.replaceAll(`path:${key}`, `path:${path}`), - ); - } - - for (const [, child] of Object.entries(node.childNodes)) { - applyRecursive(child, key, path); - } - } + if (node instanceof HTMLElement) { + if (node.hasAttribute(ATTRIBUTE_UPDATER_REPLACE)) { + const value = node.getAttribute(ATTRIBUTE_UPDATER_REPLACE); + node.setAttribute( + ATTRIBUTE_UPDATER_REPLACE, + value.replaceAll(`path:${key}`, `path:${path}`), + ); + } + + if (node.hasAttribute(ATTRIBUTE_UPDATER_ATTRIBUTES)) { + const value = node.getAttribute(ATTRIBUTE_UPDATER_ATTRIBUTES); + node.setAttribute( + ATTRIBUTE_UPDATER_ATTRIBUTES, + value.replaceAll(`path:${key}`, `path:${path}`), + ); + } + + for (const [, child] of Object.entries(node.childNodes)) { + applyRecursive(child, key, path); + } + } } /** @@ -609,19 +640,19 @@ function applyRecursive(node, key, path) { * @this Updater */ function updateContent(change) { - const subject = this[internalSymbol].subject.getRealSubject(); - - const p = clone(change?.["path"]); - runUpdateContent.call(this, this[internalSymbol].element, p, subject); - - const slots = this[internalSymbol].element.querySelectorAll("slot"); - if (slots.length > 0) { - for (const [, slot] of Object.entries(slots)) { - for (const [, element] of Object.entries(slot.assignedNodes())) { - runUpdateContent.call(this, element, p, subject); - } - } - } + const subject = this[internalSymbol].subject.getRealSubject(); + + const p = clone(change?.["path"]); + runUpdateContent.call(this, this[internalSymbol].element, p, subject); + + const slots = this[internalSymbol].element.querySelectorAll("slot"); + if (slots.length > 0) { + for (const [, slot] of Object.entries(slots)) { + for (const [, element] of Object.entries(slot.assignedNodes())) { + runUpdateContent.call(this, element, p, subject); + } + } + } } /** @@ -634,69 +665,69 @@ function updateContent(change) { * @return {void} */ function runUpdateContent(container, parts, subject) { - if (!isArray(parts)) return; - if (!(container instanceof HTMLElement)) return; - parts = clone(parts); - - const mem = new WeakSet(); - - while (parts.length > 0) { - const current = parts.join("."); - parts.pop(); - - // Unfortunately, static data is always changed as well, since it is not possible to react to changes here. - const query = `[${ATTRIBUTE_UPDATER_REPLACE}^="path:${current}"], [${ATTRIBUTE_UPDATER_REPLACE}^="static:"], [${ATTRIBUTE_UPDATER_REPLACE}^="i18n:"]`; - const e = container.querySelectorAll(`${query}`); - - const iterator = new Set([...e]); - - if (container.matches(query)) { - iterator.add(container); - } - - /** - * @type {HTMLElement} - */ - for (const [element] of iterator.entries()) { - if (mem.has(element)) return; - mem.add(element); - - const attributes = element.getAttribute(ATTRIBUTE_UPDATER_REPLACE); - const cmd = trimSpaces(attributes); - - const pipe = new Pipe(cmd); - this[internalSymbol].callbacks.forEach((f, n) => { - pipe.setCallback(n, f); - }); - - let value; - try { - element.removeAttribute(ATTRIBUTE_ERRORMESSAGE); - value = pipe.run(subject); - } catch (e) { - element.setAttribute(ATTRIBUTE_ERRORMESSAGE, e.message); - } - - if (value instanceof HTMLElement) { - while (element.firstChild) { - element.removeChild(element.firstChild); - } - - try { - element.appendChild(value); - } catch (e) { - element.setAttribute( - ATTRIBUTE_ERRORMESSAGE, - `${element.getAttribute(ATTRIBUTE_ERRORMESSAGE)}, ${ - e.message - }`.trim(), - ); - } - } else { - element.innerHTML = value; - } - } - } + if (!isArray(parts)) return; + if (!(container instanceof HTMLElement)) return; + parts = clone(parts); + + const mem = new WeakSet(); + + while (parts.length > 0) { + const current = parts.join("."); + parts.pop(); + + // Unfortunately, static data is always changed as well, since it is not possible to react to changes here. + const query = `[${ATTRIBUTE_UPDATER_REPLACE}^="path:${current}"], [${ATTRIBUTE_UPDATER_REPLACE}^="static:"], [${ATTRIBUTE_UPDATER_REPLACE}^="i18n:"]`; + const e = container.querySelectorAll(`${query}`); + + const iterator = new Set([...e]); + + if (container.matches(query)) { + iterator.add(container); + } + + /** + * @type {HTMLElement} + */ + for (const [element] of iterator.entries()) { + if (mem.has(element)) return; + mem.add(element); + + const attributes = element.getAttribute(ATTRIBUTE_UPDATER_REPLACE); + const cmd = trimSpaces(attributes); + + const pipe = new Pipe(cmd); + this[internalSymbol].callbacks.forEach((f, n) => { + pipe.setCallback(n, f); + }); + + let value; + try { + element.removeAttribute(ATTRIBUTE_ERRORMESSAGE); + value = pipe.run(subject); + } catch (e) { + element.setAttribute(ATTRIBUTE_ERRORMESSAGE, e.message); + } + + if (value instanceof HTMLElement) { + while (element.firstChild) { + element.removeChild(element.firstChild); + } + + try { + element.appendChild(value); + } catch (e) { + element.setAttribute( + ATTRIBUTE_ERRORMESSAGE, + `${element.getAttribute(ATTRIBUTE_ERRORMESSAGE)}, ${ + e.message + }`.trim(), + ); + } + } else { + element.innerHTML = value; + } + } + } } /** @@ -708,9 +739,9 @@ function runUpdateContent(container, parts, subject) { * @return {void} */ function updateAttributes(change) { - const subject = this[internalSymbol].subject.getRealSubject(); - const p = clone(change?.["path"]); - runUpdateAttributes.call(this, this[internalSymbol].element, p, subject); + const subject = this[internalSymbol].subject.getRealSubject(); + const p = clone(change?.["path"]); + runUpdateAttributes.call(this, this[internalSymbol].element, p, subject); } /** @@ -722,70 +753,70 @@ function updateAttributes(change) { * @this Updater */ function runUpdateAttributes(container, parts, subject) { - if (!isArray(parts)) return; - parts = clone(parts); + if (!isArray(parts)) return; + parts = clone(parts); - const mem = new WeakSet(); + const mem = new WeakSet(); - while (parts.length > 0) { - const current = parts.join("."); - parts.pop(); + while (parts.length > 0) { + const current = parts.join("."); + parts.pop(); - let iterator = new Set(); + let iterator = new Set(); - const query = `[${ATTRIBUTE_UPDATER_SELECT_THIS}][${ATTRIBUTE_UPDATER_ATTRIBUTES}], [${ATTRIBUTE_UPDATER_ATTRIBUTES}*="path:${current}"], [${ATTRIBUTE_UPDATER_ATTRIBUTES}^="static:"], [${ATTRIBUTE_UPDATER_ATTRIBUTES}^="i18n:"]`; + const query = `[${ATTRIBUTE_UPDATER_SELECT_THIS}][${ATTRIBUTE_UPDATER_ATTRIBUTES}], [${ATTRIBUTE_UPDATER_ATTRIBUTES}*="path:${current}"], [${ATTRIBUTE_UPDATER_ATTRIBUTES}^="static:"], [${ATTRIBUTE_UPDATER_ATTRIBUTES}^="i18n:"]`; - const e = container.querySelectorAll(query); + const e = container.querySelectorAll(query); - if (e.length > 0) { - iterator = new Set([...e]); - } + if (e.length > 0) { + iterator = new Set([...e]); + } - if (container.matches(query)) { - iterator.add(container); - } + if (container.matches(query)) { + iterator.add(container); + } - for (const [element] of iterator.entries()) { - if (mem.has(element)) return; - mem.add(element); + for (const [element] of iterator.entries()) { + if (mem.has(element)) return; + mem.add(element); - // this case occurs when the ATTRIBUTE_UPDATER_SELECT_THIS attribute is set - if (!element.hasAttribute(ATTRIBUTE_UPDATER_ATTRIBUTES)) { - continue; - } + // this case occurs when the ATTRIBUTE_UPDATER_SELECT_THIS attribute is set + if (!element.hasAttribute(ATTRIBUTE_UPDATER_ATTRIBUTES)) { + continue; + } - const attributes = element.getAttribute(ATTRIBUTE_UPDATER_ATTRIBUTES); + const attributes = element.getAttribute(ATTRIBUTE_UPDATER_ATTRIBUTES); - for (let [, def] of Object.entries(attributes.split(","))) { - def = trimSpaces(def); - const i = def.indexOf(" "); - const name = trimSpaces(def.substr(0, i)); - const cmd = trimSpaces(def.substr(i)); + for (let [, def] of Object.entries(attributes.split(","))) { + def = trimSpaces(def); + const i = def.indexOf(" "); + const name = trimSpaces(def.substr(0, i)); + const cmd = trimSpaces(def.substr(i)); - const pipe = new Pipe(cmd); + const pipe = new Pipe(cmd); - this[internalSymbol].callbacks.forEach((f, n) => { - pipe.setCallback(n, f, element); - }); + this[internalSymbol].callbacks.forEach((f, n) => { + pipe.setCallback(n, f, element); + }); - let value; - try { - element.removeAttribute(ATTRIBUTE_ERRORMESSAGE); - value = pipe.run(subject); - } catch (e) { - element.setAttribute(ATTRIBUTE_ERRORMESSAGE, e.message); - } + let value; + try { + element.removeAttribute(ATTRIBUTE_ERRORMESSAGE); + value = pipe.run(subject); + } catch (e) { + element.setAttribute(ATTRIBUTE_ERRORMESSAGE, e.message); + } - if (value === undefined) { - element.removeAttribute(name); - } else if (element.getAttribute(name) !== value) { - element.setAttribute(name, value); - } + if (value === undefined) { + element.removeAttribute(name); + } else if (element.getAttribute(name) !== value) { + element.setAttribute(name, value); + } - handleInputControlAttributeUpdate.call(this, element, name, value); - } - } - } + handleInputControlAttributeUpdate.call(this, element, name, value); + } + } + } } /** @@ -798,66 +829,66 @@ function runUpdateAttributes(container, parts, subject) { */ function handleInputControlAttributeUpdate(element, name, value) { - if (element instanceof HTMLSelectElement) { - switch (element.type) { - case "select-multiple": - for (const [index, opt] of Object.entries(element.options)) { - if (value.indexOf(opt.value) !== -1) { - opt.selected = true; - } else { - opt.selected = false; - } - } - - break; - case "select-one": - // Only one value may be selected - - for (const [index, opt] of Object.entries(element.options)) { - if (opt.value === value) { - element.selectedIndex = index; - break; - } - } - - break; - } - } else if (element instanceof HTMLInputElement) { - switch (element.type) { - case "radio": - if (name === "checked") { - if (value !== undefined) { - element.checked = true; - } else { - element.checked = false; - } - } - - break; - - case "checkbox": - if (name === "checked") { - if (value !== undefined) { - element.checked = true; - } else { - element.checked = false; - } - } - - break; - case "text": - default: - if (name === "value") { - element.value = value === undefined ? "" : value; - } - - break; - } - } else if (element instanceof HTMLTextAreaElement) { - if (name === "value") { - element.value = value === undefined ? "" : value; - } - } + if (element instanceof HTMLSelectElement) { + switch (element.type) { + case "select-multiple": + for (const [index, opt] of Object.entries(element.options)) { + if (value.indexOf(opt.value) !== -1) { + opt.selected = true; + } else { + opt.selected = false; + } + } + + break; + case "select-one": + // Only one value may be selected + + for (const [index, opt] of Object.entries(element.options)) { + if (opt.value === value) { + element.selectedIndex = index; + break; + } + } + + break; + } + } else if (element instanceof HTMLInputElement) { + switch (element.type) { + case "radio": + if (name === "checked") { + if (value !== undefined) { + element.checked = true; + } else { + element.checked = false; + } + } + + break; + + case "checkbox": + if (name === "checked") { + if (value !== undefined) { + element.checked = true; + } else { + element.checked = false; + } + } + + break; + case "text": + default: + if (name === "value") { + element.value = value === undefined ? "" : value; + } + + break; + } + } else if (element instanceof HTMLTextAreaElement) { + if (name === "value") { + element.value = value === undefined ? "" : value; + } + } } /** @@ -873,48 +904,48 @@ function handleInputControlAttributeUpdate(element, name, value) { * @throws {TypeError} symbol must be an instance of Symbol */ function addObjectWithUpdaterToElement(elements, symbol, object) { - if (!(this instanceof HTMLElement)) { - throw new TypeError( - "the context of this function must be an instance of HTMLElement", - ); - } - - if (!(typeof symbol === "symbol")) { - throw new TypeError("symbol must be an instance of Symbol"); - } - - const updaters = new Set(); - - if (elements instanceof NodeList) { - elements = new Set([...elements]); - } else if (elements instanceof HTMLElement) { - elements = new Set([elements]); - } else if (elements instanceof Set) { - } else { - throw new TypeError( - `elements is not a valid type. (actual: ${typeof elements})`, - ); - } - - const result = []; - - elements.forEach((element) => { - if (!(element instanceof HTMLElement)) return; - if (element instanceof HTMLTemplateElement) return; - - const u = new Updater(element, object); - updaters.add(u); - - result.push( - u.run().then(() => { - return u.enableEventProcessing(); - }), - ); - }); - - if (updaters.size > 0) { - addToObjectLink(this, symbol, updaters); - } - - return result; + if (!(this instanceof HTMLElement)) { + throw new TypeError( + "the context of this function must be an instance of HTMLElement", + ); + } + + if (!(typeof symbol === "symbol")) { + throw new TypeError("symbol must be an instance of Symbol"); + } + + const updaters = new Set(); + + if (elements instanceof NodeList) { + elements = new Set([...elements]); + } else if (elements instanceof HTMLElement) { + elements = new Set([elements]); + } else if (elements instanceof Set) { + } else { + throw new TypeError( + `elements is not a valid type. (actual: ${typeof elements})`, + ); + } + + const result = []; + + elements.forEach((element) => { + if (!(element instanceof HTMLElement)) return; + if (element instanceof HTMLTemplateElement) return; + + const u = new Updater(element, object); + updaters.add(u); + + result.push( + u.run().then(() => { + return u.enableEventProcessing(); + }), + ); + }); + + if (updaters.size > 0) { + addToObjectLink(this, symbol, updaters); + } + + return result; } diff --git a/source/i18n/translations.mjs b/source/i18n/translations.mjs index 3c1831f482587e7f243f2fb3aeb6a73d7a354573..fa28af39f2080bcaf41dd794dc54ea66f0d7a1a0 100644 --- a/source/i18n/translations.mjs +++ b/source/i18n/translations.mjs @@ -90,7 +90,7 @@ class Translations extends Base { * The appropriate text for this number is then selected. If no suitable key is found, `defaultText` is taken. * * @param {string} key - * @param {integer|count} count + * @param {integer|string} count * @param {string|undefined} defaultText * @return {string} */