gina 0.6.3 → 0.6.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +29 -0
- package/README.md +32 -40
- package/ROADMAP.md +3 -1
- package/framework/v0.6.4/VERSION +1 -0
- package/framework/v0.6.4/core/asset/plugin/dist/vendor/gina/css/gina.min.css +1 -0
- package/framework/v0.6.4/core/asset/plugin/dist/vendor/gina/css/gina.min.css.br +0 -0
- package/framework/v0.6.4/core/asset/plugin/dist/vendor/gina/css/gina.min.css.gz +0 -0
- package/framework/{v0.6.3 → v0.6.4}/core/asset/plugin/dist/vendor/gina/js/gina.js +1522 -79
- package/framework/v0.6.4/core/asset/plugin/dist/vendor/gina/js/gina.min.js +640 -0
- package/framework/v0.6.4/core/asset/plugin/dist/vendor/gina/js/gina.min.js.br +0 -0
- package/framework/v0.6.4/core/asset/plugin/dist/vendor/gina/js/gina.min.js.gz +0 -0
- package/framework/{v0.6.3 → v0.6.4}/core/config.js +22 -4
- package/framework/{v0.6.3 → v0.6.4}/core/controller/controller.js +62 -2
- package/framework/{v0.6.3 → v0.6.4}/core/controller/controller.render-nunjucks.js +11 -3
- package/framework/{v0.6.3 → v0.6.4}/core/controller/controller.render-swig.js +15 -1
- package/framework/{v0.6.3 → v0.6.4}/core/gna.js +33 -1
- package/framework/{v0.6.3 → v0.6.4}/core/plugins/lib/validator/src/main.js +892 -21
- package/framework/{v0.6.3 → v0.6.4}/core/server.js +60 -2
- package/framework/v0.6.4/core/template/_gitignore +27 -0
- package/framework/{v0.6.3 → v0.6.4}/lib/cmd/secrets/arguments.json +1 -0
- package/framework/v0.6.4/lib/cmd/secrets/check.js +861 -0
- package/framework/{v0.6.3 → v0.6.4}/lib/cmd/secrets/help.txt +29 -5
- package/framework/v0.6.4/lib/loading-state/package.json +7 -0
- package/framework/v0.6.4/lib/loading-state/src/main.js +366 -0
- package/framework/{v0.6.3 → v0.6.4}/lib/logger/src/containers/mq/listener.js +23 -0
- package/framework/{v0.6.3 → v0.6.4}/lib/logger/src/containers/mq/speaker.js +27 -0
- package/framework/v0.6.4/lib/secrets/src/backends/file.js +180 -0
- package/framework/v0.6.4/lib/secrets/src/env-file.js +220 -0
- package/framework/{v0.6.3 → v0.6.4}/lib/secrets/src/main.js +84 -1
- package/framework/{v0.6.3 → v0.6.4}/package.json +1 -1
- package/gna.js +4 -4
- package/llms.txt +7 -7
- package/package.json +3 -3
- package/schema/settings.json +14 -0
- package/framework/v0.6.3/VERSION +0 -1
- package/framework/v0.6.3/core/asset/plugin/dist/vendor/gina/css/gina.min.css +0 -1
- package/framework/v0.6.3/core/asset/plugin/dist/vendor/gina/css/gina.min.css.br +0 -0
- package/framework/v0.6.3/core/asset/plugin/dist/vendor/gina/css/gina.min.css.gz +0 -0
- package/framework/v0.6.3/core/asset/plugin/dist/vendor/gina/js/gina.min.js +0 -625
- package/framework/v0.6.3/core/asset/plugin/dist/vendor/gina/js/gina.min.js.br +0 -0
- package/framework/v0.6.3/core/asset/plugin/dist/vendor/gina/js/gina.min.js.gz +0 -0
- package/framework/v0.6.3/core/template/_gitignore +0 -19
- package/framework/v0.6.3/lib/cmd/secrets/check.js +0 -507
- /package/framework/{v0.6.3 → v0.6.4}/AUTHORS +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/LICENSE +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/asset/html/nolayout.html +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/asset/html/static.html +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/asset/img/android-chrome-192x192.png +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/asset/img/android-chrome-512x512.png +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/asset/img/apple-touch-icon.png +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/asset/img/favicon-16x16.png +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/asset/img/favicon-32x32.png +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/asset/img/favicon.ico +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/asset/plugin/README.md +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/asset/plugin/dist/vendor/gina/beemaster/beemaster.css +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/asset/plugin/dist/vendor/gina/beemaster/beemaster.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/asset/plugin/dist/vendor/gina/beemaster/index.html +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/asset/plugin/dist/vendor/gina/html/statusbar.html +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/asset/plugin/dist/vendor/gina/html/statusbar.html.br +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/asset/plugin/dist/vendor/gina/html/statusbar.html.gz +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/asset/plugin/dist/vendor/gina/inspector/have_heart_one-webfont.woff2 +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/asset/plugin/dist/vendor/gina/inspector/index.html +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/asset/plugin/dist/vendor/gina/inspector/inspector.css +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/asset/plugin/dist/vendor/gina/inspector/inspector.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/asset/plugin/dist/vendor/gina/inspector/logo.svg +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/asset/plugin/dist/vendor/gina/js/gina.onload.min.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/asset/plugin/dist/vendor/gina/js/gina.onload.min.js.br +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/asset/plugin/dist/vendor/gina/js/gina.onload.min.js.gz +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/connectors/ai/index.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/connectors/ai/lib/connector.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/connectors/couchbase/index.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/connectors/couchbase/lib/connector.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/connectors/couchbase/lib/connector.v3.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/connectors/couchbase/lib/connector.v4.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/connectors/couchbase/lib/n1ql.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/connectors/couchbase/lib/session-store.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/connectors/couchbase/lib/session-store.v3.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/connectors/couchbase/lib/session-store.v4.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/connectors/duckdb/index.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/connectors/duckdb/lib/connector.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/connectors/mongodb/index.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/connectors/mongodb/lib/connector.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/connectors/mongodb/lib/job-store.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/connectors/mongodb/lib/pipeline-loader.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/connectors/mongodb/lib/session-store.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/connectors/mysql/index.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/connectors/mysql/lib/connector.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/connectors/postgresql/index.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/connectors/postgresql/lib/connector.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/connectors/redis/index.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/connectors/redis/lib/connector.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/connectors/redis/lib/job-store.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/connectors/redis/lib/render-cache-store.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/connectors/redis/lib/session-store.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/connectors/scylladb/index.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/connectors/scylladb/lib/connector.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/connectors/scylladb/lib/session-store.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/connectors/sql-parser.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/connectors/sqlite/index.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/connectors/sqlite/lib/connector.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/connectors/sqlite/lib/job-store.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/connectors/sqlite/lib/session-store.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/content.encoding +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/controller/controller.framework.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/controller/controller.render-json.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/controller/controller.render-nunjucks-async.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/controller/controller.render-stream.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/controller/controller.render-swig-async.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/controller/controller.render-v1.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/controller/index.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/controller/inspector-window-emit.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/controller/release-banner.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/dev/index.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/dev/lib/class.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/dev/lib/factory.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/dev/lib/tools.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/locales/README.md +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/locales/currency.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/locales/dist/language/en.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/locales/dist/language/fr.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/locales/dist/region/en.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/locales/dist/region/fr.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/locales/index.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/mime.types +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/model/entity.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/model/index.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/model/template/entityFactory.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/model/template/index.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/plugins/README.md +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/plugins/index.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/plugins/lib/csrf/README.md +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/plugins/lib/csrf/package.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/plugins/lib/csrf/src/main.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/plugins/lib/security-headers/README.md +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/plugins/lib/security-headers/coep/README.md +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/plugins/lib/security-headers/coep/package.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/plugins/lib/security-headers/coep/src/main.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/plugins/lib/security-headers/coop/README.md +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/plugins/lib/security-headers/coop/package.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/plugins/lib/security-headers/coop/src/main.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/plugins/lib/security-headers/corp/README.md +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/plugins/lib/security-headers/corp/package.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/plugins/lib/security-headers/corp/src/main.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/plugins/lib/security-headers/csp/README.md +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/plugins/lib/security-headers/csp/package.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/plugins/lib/security-headers/csp/src/main.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/plugins/lib/security-headers/hide-powered-by/README.md +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/plugins/lib/security-headers/hide-powered-by/package.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/plugins/lib/security-headers/hide-powered-by/src/main.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/plugins/lib/security-headers/hsts/README.md +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/plugins/lib/security-headers/hsts/package.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/plugins/lib/security-headers/hsts/src/main.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/plugins/lib/security-headers/origin-agent-cluster/README.md +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/plugins/lib/security-headers/origin-agent-cluster/package.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/plugins/lib/security-headers/origin-agent-cluster/src/main.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/plugins/lib/security-headers/package.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/plugins/lib/security-headers/referrer-policy/README.md +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/plugins/lib/security-headers/referrer-policy/package.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/plugins/lib/security-headers/referrer-policy/src/main.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/plugins/lib/security-headers/src/main.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/plugins/lib/security-headers/x-content-type-options/README.md +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/plugins/lib/security-headers/x-content-type-options/package.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/plugins/lib/security-headers/x-content-type-options/src/main.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/plugins/lib/security-headers/x-dns-prefetch-control/README.md +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/plugins/lib/security-headers/x-dns-prefetch-control/package.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/plugins/lib/security-headers/x-dns-prefetch-control/src/main.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/plugins/lib/security-headers/x-download-options/README.md +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/plugins/lib/security-headers/x-download-options/package.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/plugins/lib/security-headers/x-download-options/src/main.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/plugins/lib/security-headers/x-frame-options/README.md +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/plugins/lib/security-headers/x-frame-options/package.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/plugins/lib/security-headers/x-frame-options/src/main.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/plugins/lib/security-headers/x-permitted-cross-domain-policies/README.md +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/plugins/lib/security-headers/x-permitted-cross-domain-policies/package.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/plugins/lib/security-headers/x-permitted-cross-domain-policies/src/main.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/plugins/lib/security-headers/x-xss-protection/README.md +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/plugins/lib/security-headers/x-xss-protection/package.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/plugins/lib/security-headers/x-xss-protection/src/main.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/plugins/lib/session/README.md +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/plugins/lib/session/package.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/plugins/lib/session/src/main.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/plugins/lib/storage/README.md +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/plugins/lib/storage/build.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/plugins/lib/storage/package.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/plugins/lib/storage/src/main.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/plugins/lib/validator/README.md +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/plugins/lib/validator/build.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/plugins/lib/validator/package.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/plugins/lib/validator/src/form-validator.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/router.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/server.express.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/server.isaac.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/status.codes +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/template/boilerplate/bundle/config/app.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/template/boilerplate/bundle/config/connectors.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/template/boilerplate/bundle/config/routing.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/template/boilerplate/bundle/config/settings.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/template/boilerplate/bundle/config/settings.server.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/template/boilerplate/bundle/config/templates.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/template/boilerplate/bundle/config/watchers.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/template/boilerplate/bundle/controllers/controller.content.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/template/boilerplate/bundle/controllers/controller.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/template/boilerplate/bundle/controllers/setup.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/template/boilerplate/bundle/index.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/template/boilerplate/bundle/locales/en.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/template/boilerplate/bundle_namespace/controllers/controller.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/template/boilerplate/bundle_public/css/default.css +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/template/boilerplate/bundle_public/css/home.css +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/template/boilerplate/bundle_public/css/vendor/readme.md +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/template/boilerplate/bundle_public/favicon.ico +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/template/boilerplate/bundle_public/js/components/x-checklist.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/template/boilerplate/bundle_public/js/vendor/readme.md +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/template/boilerplate/bundle_public/manifest.webmanifest +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/template/boilerplate/bundle_public/readme.md +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/template/boilerplate/bundle_public/sw.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/template/boilerplate/bundle_templates/handlers/main.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/template/boilerplate/bundle_templates/html/content/homepage.html +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/template/boilerplate/bundle_templates/html/includes/error-msg-noscript.html +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/template/boilerplate/bundle_templates/html/includes/error-msg-outdated-browser.html +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/template/boilerplate/bundle_templates/html/includes/x-checklist.html +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/template/boilerplate/bundle_templates/html/layouts/main.html +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/template/command/gina.bat.tpl +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/template/command/gina.tpl +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/template/conf/env.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/template/conf/manifest.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/template/conf/package.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/template/conf/settings.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/template/conf/statics.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/template/conf/templates.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/template/error/client/json/401.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/template/error/client/json/403.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/template/error/client/json/404.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/template/error/server/html/50x.html +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/template/error/server/json/500.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/template/error/server/json/503.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/core/template/extensions/logger/config.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/helpers/console.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/helpers/context.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/helpers/data/LICENSE +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/helpers/data/README.md +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/helpers/data/package.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/helpers/data/src/main.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/helpers/dateFormat.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/helpers/index.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/helpers/json/LICENSE +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/helpers/json/README.md +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/helpers/json/package.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/helpers/json/src/main.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/helpers/path.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/helpers/plugins/README.md +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/helpers/plugins/package.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/helpers/plugins/src/api-error.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/helpers/plugins/src/main.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/helpers/prototypes.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/helpers/task.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/helpers/text.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/admin/package.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/admin/src/main.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/archiver/README.md +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/archiver/build.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/archiver/package.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/archiver/src/dep/jszip.min.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/archiver/src/main.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/async/package.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/async/src/main.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/audit/package.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/audit/src/main.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/audit-store.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/authn/package.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/authn/src/lockout.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/authn/src/main.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/authn/src/totp.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/authz-gate/package.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/authz-gate/src/main.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cache/README.md +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cache/build.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cache/package.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cache/src/main.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/aliases.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/audit/arguments.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/audit/help.txt +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/audit/verify.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/bundle/add.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/bundle/arguments.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/bundle/build.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/bundle/copy.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/bundle/cp.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/bundle/help.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/bundle/help.txt +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/bundle/inc/name-rewrite.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/bundle/list.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/bundle/man.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/bundle/mcp-start.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/bundle/mcp.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/bundle/oas.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/bundle/openapi.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/bundle/remove.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/bundle/rename.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/bundle/restart.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/bundle/rm.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/bundle/start.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/bundle/status.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/bundle/stop.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/bundle/types.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/cache/arguments.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/cache/clear.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/cache/help.txt +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/cache/stats.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/connector/add.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/connector/arguments.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/connector/help.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/connector/help.txt +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/connector/infer.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/connector/list.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/connector/migrate.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/connector/models.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/connector/remove.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/connector/rm.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/connector/test.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/container/arguments.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/container/help.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/container/help.txt +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/container/man.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/container/ps.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/container/stop.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/controller/add.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/controller/arguments.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/controller/help.txt +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/controller/inc/args.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/controller/inc/namespace.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/controller/inc/reference-rewrite.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/controller/inc/reference-scan.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/controller/inc/scaffold.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/controller/remove.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/controller/rename.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/controller/rm.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/env/add.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/env/get.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/env/help.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/env/help.txt +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/env/link-dev.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/env/list.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/env/remove.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/env/rm.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/env/set.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/env/unset.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/env/use.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/framework/add.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/framework/arguments.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/framework/build.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/framework/dot.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/framework/get.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/framework/help.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/framework/help.txt +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/framework/init.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/framework/link-node-modules.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/framework/link.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/framework/list.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/framework/man.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/framework/msg.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/framework/open.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/framework/remove.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/framework/reset.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/framework/restart.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/framework/set.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/framework/start.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/framework/status.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/framework/stop.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/framework/tail.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/framework/update.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/framework/version.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/gina-dev.1.md +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/gina-framework.1.md +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/gina.1.md +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/helper.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/i18n/add.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/i18n/arguments.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/i18n/export.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/i18n/help.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/i18n/help.txt +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/i18n/import.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/i18n/scan.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/image/_host.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/image/arguments.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/image/build.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/image/help.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/image/help.txt +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/image/list.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/image/man.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/image/rm.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/image/run.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/index.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/inspector/help.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/inspector/help.txt +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/inspector/open.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/man-render.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/minion/arguments.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/minion/help.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/minion/help.txt +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/minion/kill.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/minion/list.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/msg.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/port/help.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/port/help.txt +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/port/inc/scan.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/port/list.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/port/reset.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/port/set.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/project/add.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/project/arguments.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/project/backup.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/project/build.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/project/help.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/project/help.txt +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/project/import.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/project/list.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/project/man.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/project/move.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/project/remove.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/project/rename.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/project/restart.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/project/restore.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/project/rm.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/project/start.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/project/status.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/project/stop.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/protocol/arguments.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/protocol/help.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/protocol/help.txt +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/protocol/list.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/protocol/remove.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/protocol/set.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/scope/add.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/scope/help.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/scope/help.txt +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/scope/link-local.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/scope/link-production.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/scope/list.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/scope/remove.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/scope/rm.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/scope/use.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/secrets/help.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/secrets/scan.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/service/help.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/service/help.txt +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/service/list.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/service/man.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/service/start.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd/view/add.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd-status-format/package.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cmd-status-format/src/main.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/collection/README.md +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/collection/build.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/collection/package.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/collection/src/main.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/config.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/connector-config/package.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/connector-config/src/main.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/connector-error/package.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/connector-error/src/main.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/connector-registry/package.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/connector-registry/src/main.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cron/README.md +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cron/package.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/cron/src/main.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/domain/LICENSE +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/domain/README.md +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/domain/package.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/domain/src/main.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/dto/package.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/dto/src/main.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/dto-pipe/package.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/dto-pipe/src/main.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/dto-types/package.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/dto-types/src/main.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/generator/index.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/i18n/package.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/i18n/src/main.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/image-build/package.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/image-build/src/main.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/index.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/inherits/LICENSE +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/inherits/README.md +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/inherits/package.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/inherits/src/main.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/inspector-events/package.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/inspector-events/src/main.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/inspector-redact/package.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/inspector-redact/src/main.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/instrument/package.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/instrument/src/main.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/job/package.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/job/src/main.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/job-store.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/json-config-header/package.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/json-config-header/src/main.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/logger/README.md +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/logger/package.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/logger/src/containers/default/index.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/logger/src/containers/file/index.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/logger/src/containers/file/lib/logrotator/README.md +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/logger/src/containers/file/lib/logrotator/index.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/logger/src/containers/mq/index.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/logger/src/helper.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/logger/src/main.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/math/index.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/mcp-dispatch/package.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/mcp-dispatch/src/main.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/mcp-http/package.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/mcp-http/src/main.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/mcp-server/package.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/mcp-server/src/main.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/merge/README.md +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/merge/package.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/merge/src/main.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/metrics/package.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/metrics/src/main.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/model.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/net-locality/package.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/net-locality/src/main.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/nunjucks-filters/README.md +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/nunjucks-filters/package.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/nunjucks-filters/src/main.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/nunjucks-resolver/package.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/nunjucks-resolver/src/main.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/proc.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/release-watch/package.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/release-watch/src/main.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/render-cache/package.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/render-cache/src/main.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/render-cache-store.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/routing/README.md +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/routing/build.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/routing/package.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/routing/src/main.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/routing/src/radix.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/routing-introspect/package.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/routing-introspect/src/main.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/secrets/package.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/secrets/src/backends/env.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/session-store.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/shell.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/sqlite-driver.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/state.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/swig-filters/README.md +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/swig-filters/package.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/swig-filters/src/main.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/swig-resolver/package.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/swig-resolver/src/main.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/template-loaders/package.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/template-loaders/src/loaders/http.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/template-loaders/src/loaders/memory.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/template-loaders/src/main.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/url/README.md +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/url/index.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/url/routing.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/uuid/package.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/uuid/src/main.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/validator.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/watcher/package.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/watcher/src/main.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/ws-framing/package.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/ws-framing/src/main.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/ws-query/package.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/ws-query/src/main.js +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/ws-session/package.json +0 -0
- /package/framework/{v0.6.3 → v0.6.4}/lib/ws-session/src/main.js +0 -0
|
@@ -106,6 +106,7 @@ function ValidatorPlugin(rules, data, formId, culture) {
|
|
|
106
106
|
var FormValidator = (isGFFCtx) ? require('lib/form-validator') : require('./form-validator');
|
|
107
107
|
//var Collection = (isGFFCtx) ? require('lib/collection') : require('../../../../../lib/collection');
|
|
108
108
|
var routing = (isGFFCtx) ? require('lib/routing') : require('../../../../../lib/routing');
|
|
109
|
+
var loadingState = (isGFFCtx) ? require('lib/loading-state') : require('../../../../../lib/loading-state');
|
|
109
110
|
|
|
110
111
|
|
|
111
112
|
/** definitions */
|
|
@@ -790,9 +791,14 @@ function ValidatorPlugin(rules, data, formId, culture) {
|
|
|
790
791
|
if (isErrorMessageHidden) {
|
|
791
792
|
// hide error messages
|
|
792
793
|
$children[c].className = $children[c].className +' hidden';
|
|
794
|
+
// #A11Y5 — this hide fires when the field regains focus, and it does not
|
|
795
|
+
// touch aria-invalid: a committed error stays asserted while its message
|
|
796
|
+
// would otherwise leave the a11y tree. Clip it instead.
|
|
797
|
+
clipErrorMessage($children[c]);
|
|
793
798
|
} else {
|
|
794
799
|
// display error messages
|
|
795
800
|
$children[c].className = $children[c].className.replace(/(\s+hidden|hidden)/, '');
|
|
801
|
+
revealErrorMessage($children[c]);
|
|
796
802
|
}
|
|
797
803
|
break
|
|
798
804
|
}
|
|
@@ -800,17 +806,38 @@ function ValidatorPlugin(rules, data, formId, culture) {
|
|
|
800
806
|
}
|
|
801
807
|
|
|
802
808
|
/**
|
|
803
|
-
* #
|
|
804
|
-
*
|
|
805
|
-
*
|
|
806
|
-
*
|
|
807
|
-
*
|
|
809
|
+
* #A11Y2 — create (or recover) a form's visually-hidden polite status region WITHOUT
|
|
810
|
+
* writing to it. Split out of announceA11yError so the region can exist LONG before the
|
|
811
|
+
* first error: a region that is inserted and populated in the same tick reaches assistive
|
|
812
|
+
* tech as a single mutation batch, which is commonly never spoken, so the very first
|
|
813
|
+
* announcement per form — the one that matters most — was the one most likely lost.
|
|
814
|
+
* bindForm calls this at bind time, which is what makes that first error audible.
|
|
815
|
+
*
|
|
816
|
+
* The region is a CHILD OF THE FORM deliberately. A popin renders its form inside a native
|
|
817
|
+
* `<dialog>` opened with showModal(), which leaves everything outside the top layer inert;
|
|
818
|
+
* a body-level region would sit in that inert subtree and go unspoken for exactly the forms
|
|
819
|
+
* that live in popins. Keeping it inside the form keeps it inside the dialog. The price is
|
|
820
|
+
* that a subtree replacement (a popin re-render's `innerHTML =`, or a nav fragment swap)
|
|
821
|
+
* destroys it — hence create-OR-RECOVER, and hence the deferred first write in
|
|
822
|
+
* announceA11yError, which is what stops a recovery from silently repeating the defect.
|
|
823
|
+
*
|
|
824
|
+
* The bookkeeping flag lives on the element rather than in a module-scope map so it dies
|
|
825
|
+
* WITH the region: a destroyed region leaves no stale entry behind, and no form id keeps
|
|
826
|
+
* an unbounded map alive. Browser-only, like readCsrfCookie — this engine is shared with
|
|
827
|
+
* the server form-body path, which has no document.
|
|
828
|
+
*
|
|
829
|
+
* @inner
|
|
808
830
|
* @param {object} $form - the HTMLFormElement the region belongs to
|
|
809
|
-
* @
|
|
810
|
-
* @
|
|
831
|
+
* @returns {object|null} the live-region element, or null outside a browser document
|
|
832
|
+
* @example
|
|
833
|
+
* // at bind time: the region is in the a11y tree before any error can occur
|
|
834
|
+
* ensureA11yLiveRegion($form.target);
|
|
811
835
|
*/
|
|
812
|
-
var
|
|
813
|
-
if ( !$form
|
|
836
|
+
var ensureA11yLiveRegion = function($form) {
|
|
837
|
+
if ( !$form ) return null;
|
|
838
|
+
if ( typeof(document) === 'undefined' || !document || typeof(document.getElementById) !== 'function' ) {
|
|
839
|
+
return null;
|
|
840
|
+
}
|
|
814
841
|
var _fid = ( typeof($form.id) != 'undefined' && $form.id ) ? $form.id : ( $form.getAttribute('id') || 'form' );
|
|
815
842
|
var _liveId = 'gina-aria-live-' + _fid;
|
|
816
843
|
var _live = document.getElementById(_liveId);
|
|
@@ -822,8 +849,55 @@ function ValidatorPlugin(rules, data, formId, culture) {
|
|
|
822
849
|
_live.setAttribute('aria-atomic', 'true');
|
|
823
850
|
_live.className = 'gina-visually-hidden';
|
|
824
851
|
_live.style.cssText = 'position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0;';
|
|
852
|
+
_live.ginaA11yFresh = true;
|
|
853
|
+
$form.appendChild(_live);
|
|
854
|
+
} else if ( _live.parentNode !== $form ) {
|
|
855
|
+
// Same id, different form node — a re-render replaced the form, or two forms share
|
|
856
|
+
// an id. Re-home it so the region always sits inside the form that announces, which
|
|
857
|
+
// is the property the inert reasoning above depends on; a move is a fresh insertion.
|
|
858
|
+
_live.ginaA11yFresh = true;
|
|
825
859
|
$form.appendChild(_live);
|
|
826
860
|
}
|
|
861
|
+
return _live;
|
|
862
|
+
};
|
|
863
|
+
|
|
864
|
+
/**
|
|
865
|
+
* #A11Y1 (slice 4) — announce a blur-time committed error through the region created at
|
|
866
|
+
* bind time. A CSS :user-invalid display toggle is not reliably announced by screen
|
|
867
|
+
* readers, and on blur the field has lost focus so its own aria-invalid /
|
|
868
|
+
* aria-errormessage are not re-read; the polite region decouples the announcement
|
|
869
|
+
* from visual display. Submit-time errors use focus (see onValidate), not this region.
|
|
870
|
+
*
|
|
871
|
+
* #A11Y2 — when the region had to be created (or re-homed) HERE rather than at bind time,
|
|
872
|
+
* the insertion and this write would land in the same tick and likely never be spoken, so
|
|
873
|
+
* that first write is deferred by one macrotask. Only the fresh case defers; an already
|
|
874
|
+
* bound region writes synchronously, exactly as before. While a deferred write is pending
|
|
875
|
+
* a later call replaces the pending text, so the LATEST error wins and a stale first
|
|
876
|
+
* message can never land on top of it. The timer re-enters this function, which then takes
|
|
877
|
+
* the synchronous branch — keeping exactly ONE textContent write site.
|
|
878
|
+
*
|
|
879
|
+
* @param {object} $form - the HTMLFormElement the region belongs to
|
|
880
|
+
* @param {string} text - the error text to announce
|
|
881
|
+
* @returns {object|null} the live-region element, or null when nothing was announced
|
|
882
|
+
* @example
|
|
883
|
+
* announceA11yError($form, 'This field is required');
|
|
884
|
+
*/
|
|
885
|
+
var announceA11yError = function($form, text) {
|
|
886
|
+
if ( !$form || !text ) return null;
|
|
887
|
+
var _live = ensureA11yLiveRegion($form);
|
|
888
|
+
if ( !_live ) return null;
|
|
889
|
+
if ( _live.ginaA11yFresh ) {
|
|
890
|
+
_live.ginaA11yPending = text;
|
|
891
|
+
if ( !_live.ginaA11yTimer ) {
|
|
892
|
+
_live.ginaA11yTimer = setTimeout(function() {
|
|
893
|
+
_live.ginaA11yTimer = null;
|
|
894
|
+
_live.ginaA11yFresh = false;
|
|
895
|
+
announceA11yError($form, _live.ginaA11yPending);
|
|
896
|
+
}, 0);
|
|
897
|
+
}
|
|
898
|
+
return _live;
|
|
899
|
+
}
|
|
900
|
+
text = a11yDistinctText(_live, text);
|
|
827
901
|
_live.textContent = text;
|
|
828
902
|
return _live;
|
|
829
903
|
};
|
|
@@ -851,6 +925,179 @@ function ValidatorPlugin(rules, data, formId, culture) {
|
|
|
851
925
|
return parts.join('. ');
|
|
852
926
|
};
|
|
853
927
|
|
|
928
|
+
/**
|
|
929
|
+
* A11Y_LABELS — English defaults for gina's own accessibility status strings.
|
|
930
|
+
*
|
|
931
|
+
* Deliberately separate from `setErrorLabels`, which owns per-culture overrides
|
|
932
|
+
* for *rule* error labels and is keyed by rule name. These are framework-authored
|
|
933
|
+
* announcements about what gina is doing, so they need a home of their own.
|
|
934
|
+
*
|
|
935
|
+
* `%s` in a value is replaced with a runtime detail (currently the file name);
|
|
936
|
+
* it follows the same placeholder convention the rule error labels already use,
|
|
937
|
+
* so a translation keeps control of where the detail lands in the sentence.
|
|
938
|
+
*
|
|
939
|
+
* @constant {object}
|
|
940
|
+
* @inner
|
|
941
|
+
*/
|
|
942
|
+
var A11Y_LABELS = {
|
|
943
|
+
submitting : 'Submitting…',
|
|
944
|
+
// #A11Y7/U2 — staged uploads announce only their TRANSITIONS (start and
|
|
945
|
+
// success), never per-tick progress: `aria-live="polite"` coalesces but does
|
|
946
|
+
// not throttle, and one announcement per onprogress event would bury every
|
|
947
|
+
// other message on the page. There is deliberately NO `uploadError` key —
|
|
948
|
+
// the error path announces the server's own message instead (#A11Y7/U3), and
|
|
949
|
+
// a generic second write in the same beat would clobber it (see the rationale
|
|
950
|
+
// on `releaseSubmitA11y`).
|
|
951
|
+
uploadStarted : 'Upload started',
|
|
952
|
+
uploadComplete : 'Upload complete',
|
|
953
|
+
// #A11Y7/U5 — spoken when a staged file's reset/delete control removes it.
|
|
954
|
+
fileRemoved : '%s removed'
|
|
955
|
+
};
|
|
956
|
+
|
|
957
|
+
/**
|
|
958
|
+
* a11yLabel — resolve one accessibility status string.
|
|
959
|
+
*
|
|
960
|
+
* Follows the same philosophy `setErrorLabels` documents: an English default
|
|
961
|
+
* ships inline and fills anything the project does not translate. A project
|
|
962
|
+
* overrides by assigning `gina.config.a11y`, typically once at boot keyed off
|
|
963
|
+
* the negotiated culture.
|
|
964
|
+
*
|
|
965
|
+
* @param {string} key - Label key, e.g. `submitting`.
|
|
966
|
+
* @returns {string} the project's override when it supplies a non-empty string,
|
|
967
|
+
* otherwise the English default (empty string for unknown keys).
|
|
968
|
+
*
|
|
969
|
+
* @example
|
|
970
|
+
* // project side, once at boot:
|
|
971
|
+
* gina.config.a11y = { submitting: 'Envoi…' };
|
|
972
|
+
*
|
|
973
|
+
* @inner
|
|
974
|
+
*/
|
|
975
|
+
var a11yLabel = function(key) {
|
|
976
|
+
var _over = ( typeof(gina) != 'undefined' && gina && gina.config && gina.config.a11y )
|
|
977
|
+
? gina.config.a11y
|
|
978
|
+
: null;
|
|
979
|
+
if ( _over && typeof(_over[key]) == 'string' && _over[key] ) {
|
|
980
|
+
return _over[key];
|
|
981
|
+
}
|
|
982
|
+
return A11Y_LABELS[key] || '';
|
|
983
|
+
};
|
|
984
|
+
|
|
985
|
+
/**
|
|
986
|
+
* announceA11yStatus — announce a non-error status through the form's region.
|
|
987
|
+
*
|
|
988
|
+
* The region #A11Y2 stands up at bind time is `role="status" aria-live="polite"`,
|
|
989
|
+
* i.e. already a status channel rather than an error-only one — so submit progress
|
|
990
|
+
* rides that same element instead of a second region competing with it. Kept as a
|
|
991
|
+
* named delegate purely so call sites read as status, not as errors.
|
|
992
|
+
*
|
|
993
|
+
* @param {object} $form - form target (HTMLFormElement), not the form instance.
|
|
994
|
+
* @param {string} text - resolved, human-readable status text.
|
|
995
|
+
* @returns {object|null} the live region, or null when it could not be resolved.
|
|
996
|
+
*
|
|
997
|
+
* @example
|
|
998
|
+
* announceA11yStatus($myForm, 'Envoi…');
|
|
999
|
+
*
|
|
1000
|
+
* @inner
|
|
1001
|
+
*/
|
|
1002
|
+
var announceA11yStatus = function($form, text) {
|
|
1003
|
+
return announceA11yError($form, text);
|
|
1004
|
+
};
|
|
1005
|
+
|
|
1006
|
+
/**
|
|
1007
|
+
* a11yDistinctText — make a repeated announcement observably new.
|
|
1008
|
+
*
|
|
1009
|
+
* An `aria-live="polite"` region is announced when its content CHANGES, so re-writing
|
|
1010
|
+
* byte-identical text is commonly not spoken at all. That is the normal case for a
|
|
1011
|
+
* validation message: blurring a field that still fails the same rule produces exactly
|
|
1012
|
+
* the same string, and the user heard nothing the second time. Appending a no-break
|
|
1013
|
+
* space makes the node's content differ while leaving what is read out unchanged, and
|
|
1014
|
+
* it self-cancels — the next identical announcement compares against the suffixed text,
|
|
1015
|
+
* differs, and writes the clean string again.
|
|
1016
|
+
*
|
|
1017
|
+
* Lives outside `announceA11yError` deliberately: that function sits inside a fixed
|
|
1018
|
+
* character window asserted by a source pin, and the rationale above does not fit in it.
|
|
1019
|
+
*
|
|
1020
|
+
* ⚠️ Unverified: that a screen reader actually re-announces as a result. The string
|
|
1021
|
+
* demonstrably changes; no assistive-technology pass has been run to confirm the effect.
|
|
1022
|
+
*
|
|
1023
|
+
* @param {object} $live - the live region node.
|
|
1024
|
+
* @param {string} text - the announcement about to be written.
|
|
1025
|
+
* @returns {string} `text`, suffixed only when it would otherwise be a no-op write.
|
|
1026
|
+
*
|
|
1027
|
+
* @example
|
|
1028
|
+
* var next = a11yDistinctText($region, 'This field is required');
|
|
1029
|
+
*
|
|
1030
|
+
* @inner
|
|
1031
|
+
*/
|
|
1032
|
+
var a11yDistinctText = function($live, text) {
|
|
1033
|
+
if ( !$live || typeof(text) != 'string' ) {
|
|
1034
|
+
return text;
|
|
1035
|
+
}
|
|
1036
|
+
return ( $live.textContent === text ) ? text + ' ' : text;
|
|
1037
|
+
};
|
|
1038
|
+
|
|
1039
|
+
/**
|
|
1040
|
+
* ERR_MSG_CLIP — inline declarations that hide an element from VIEW while leaving it
|
|
1041
|
+
* in the accessibility tree.
|
|
1042
|
+
*
|
|
1043
|
+
* `display` carries `!important` because gina's own `.hidden` helper is
|
|
1044
|
+
* `display: none !important`, and an inline `!important` is what outranks it (measured:
|
|
1045
|
+
* a plain inline `display:block` loses to it). The class is deliberately left in place
|
|
1046
|
+
* so consumer CSS keyed on `.hidden` keeps matching.
|
|
1047
|
+
*
|
|
1048
|
+
* @constant {string}
|
|
1049
|
+
* @inner
|
|
1050
|
+
*/
|
|
1051
|
+
var ERR_MSG_CLIP = 'display:block !important;position:absolute;width:1px;height:1px;'
|
|
1052
|
+
+ 'margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0;';
|
|
1053
|
+
|
|
1054
|
+
/**
|
|
1055
|
+
* clipErrorMessage — hide a validation message visually, but keep it reachable.
|
|
1056
|
+
*
|
|
1057
|
+
* `.hidden` is `display: none !important`, which removes the node from the
|
|
1058
|
+
* accessibility tree outright. That is the wrong tool wherever `aria-invalid="true"`
|
|
1059
|
+
* stays asserted on the field, because the `aria-errormessage` association then points
|
|
1060
|
+
* assistive tech at a target it cannot resolve — the field is announced invalid with no
|
|
1061
|
+
* retrievable reason. Both hide paths that can coexist with an asserted `aria-invalid`
|
|
1062
|
+
* (the focus-driven hide in `refreshWarning`, and the refresh re-create) clip instead.
|
|
1063
|
+
*
|
|
1064
|
+
* gina creates and owns this element, so replacing `style.cssText` wholesale is safe.
|
|
1065
|
+
*
|
|
1066
|
+
* @param {object} $err - the `form-item-error-message` element.
|
|
1067
|
+
* @returns {boolean} true when the clip was applied.
|
|
1068
|
+
*
|
|
1069
|
+
* @example
|
|
1070
|
+
* clipErrorMessage($someMessageDiv);
|
|
1071
|
+
*
|
|
1072
|
+
* @inner
|
|
1073
|
+
*/
|
|
1074
|
+
var clipErrorMessage = function($err) {
|
|
1075
|
+
if ( !$err || typeof($err.style) == 'undefined' || !$err.style ) {
|
|
1076
|
+
return false;
|
|
1077
|
+
}
|
|
1078
|
+
$err.style.cssText = ERR_MSG_CLIP;
|
|
1079
|
+
return true;
|
|
1080
|
+
};
|
|
1081
|
+
|
|
1082
|
+
/**
|
|
1083
|
+
* revealErrorMessage — undo `clipErrorMessage`, restoring normal visual flow.
|
|
1084
|
+
*
|
|
1085
|
+
* @param {object} $err - the `form-item-error-message` element.
|
|
1086
|
+
* @returns {boolean} true when the clip was cleared.
|
|
1087
|
+
*
|
|
1088
|
+
* @example
|
|
1089
|
+
* revealErrorMessage($someMessageDiv);
|
|
1090
|
+
*
|
|
1091
|
+
* @inner
|
|
1092
|
+
*/
|
|
1093
|
+
var revealErrorMessage = function($err) {
|
|
1094
|
+
if ( !$err || typeof($err.style) == 'undefined' || !$err.style ) {
|
|
1095
|
+
return false;
|
|
1096
|
+
}
|
|
1097
|
+
$err.style.cssText = '';
|
|
1098
|
+
return true;
|
|
1099
|
+
};
|
|
1100
|
+
|
|
854
1101
|
/**
|
|
855
1102
|
* handleErrorsDisplay
|
|
856
1103
|
* Attention: if you are going to handle errors display by hand, set data to `null` to prevent Toolbar refresh with empty data
|
|
@@ -1146,6 +1393,14 @@ function ValidatorPlugin(rules, data, formId, culture) {
|
|
|
1146
1393
|
// global pass, so without this focus guard it re-shows the message mid-typing.
|
|
1147
1394
|
// On blur (field no longer active) the message is created shown (focusout commits).
|
|
1148
1395
|
$err.setAttribute('class', ( document.activeElement && document.activeElement.name == name ) ? 'form-item-error-message hidden' : 'form-item-error-message');
|
|
1396
|
+
// #A11Y5 — the branch below re-asserts aria-invalid="true" on this same
|
|
1397
|
+
// field, so when the message is hidden it must stay resolvable: clip it
|
|
1398
|
+
// out of view rather than out of the accessibility tree. Reads the class
|
|
1399
|
+
// just written instead of re-deriving the condition, so the ternary above
|
|
1400
|
+
// stays exactly as pinned.
|
|
1401
|
+
if ( /hidden/.test($err.className) ) {
|
|
1402
|
+
clipErrorMessage($err);
|
|
1403
|
+
}
|
|
1149
1404
|
|
|
1150
1405
|
// #A11Y1 (slice 2) — preserve the aria-errormessage wire we own across refresh.
|
|
1151
1406
|
if ( _ginaOwnsErrMsg && _ariaErrId ) {
|
|
@@ -1475,6 +1730,231 @@ function ValidatorPlugin(rules, data, formId, culture) {
|
|
|
1475
1730
|
}
|
|
1476
1731
|
|
|
1477
1732
|
|
|
1733
|
+
/**
|
|
1734
|
+
* armSubmitLoading
|
|
1735
|
+
*
|
|
1736
|
+
* Marks `$trigger` as running (`data-gina-loading="true"`, or whatever
|
|
1737
|
+
* `gina.config.loadingAttribute` names) and remembers it on the form instance so
|
|
1738
|
+
* every terminal path can release it — including the ones that never reach an
|
|
1739
|
+
* XHR and therefore have no `$submitTrigger` of their own in scope.
|
|
1740
|
+
*
|
|
1741
|
+
* The element is stashed rather than re-derived because the two are NOT always
|
|
1742
|
+
* the same: `send()` resolves `$submitTrigger` once from `$form.submitTrigger`
|
|
1743
|
+
* (an id) at its own entry, which a rejected submit never reaches, and which a
|
|
1744
|
+
* second click on a different button would have overwritten by then. The stash
|
|
1745
|
+
* is a single reference per form, replaced on each arm and nulled on disarm, so
|
|
1746
|
+
* it can not retain a detached node past the submit that created it.
|
|
1747
|
+
*
|
|
1748
|
+
* @param {object} $formInstance - the form instance (`instance.$forms[id]`)
|
|
1749
|
+
* @param {object} $trigger - the element the user operated
|
|
1750
|
+
*
|
|
1751
|
+
* @returns {boolean} true when the trigger was marked
|
|
1752
|
+
*
|
|
1753
|
+
* FIRST ARM WINS until the state is released. A form runs one submit at a time — that
|
|
1754
|
+
* is what `withRateLimit` enforces — so a second attempt arriving mid-flight is about
|
|
1755
|
+
* to be refused, and must not take ownership: on a form with several submit buttons it
|
|
1756
|
+
* would move the stash to the refused trigger, leaving the trigger that actually owns
|
|
1757
|
+
* the request armed with nothing left to release it.
|
|
1758
|
+
*
|
|
1759
|
+
* @example
|
|
1760
|
+
* armSubmitLoading(instance.$forms[$form.id], loadingState.resolveTrigger($el, $target));
|
|
1761
|
+
*
|
|
1762
|
+
* @inner
|
|
1763
|
+
*/
|
|
1764
|
+
var armSubmitLoading = function($formInstance, $trigger) {
|
|
1765
|
+
if ( !$formInstance || !$trigger ) {
|
|
1766
|
+
return false;
|
|
1767
|
+
}
|
|
1768
|
+
if ($formInstance.loadingTrigger) {
|
|
1769
|
+
return false;
|
|
1770
|
+
}
|
|
1771
|
+
$formInstance.loadingTrigger = $trigger;
|
|
1772
|
+
return loadingState.arm($trigger);
|
|
1773
|
+
};
|
|
1774
|
+
|
|
1775
|
+
/**
|
|
1776
|
+
* disarmSubmitLoading
|
|
1777
|
+
*
|
|
1778
|
+
* Releases whatever `armSubmitLoading` marked for this form
|
|
1779
|
+
* (`data-gina-loading="false"`) and drops the stash. Idempotent and safe to call
|
|
1780
|
+
* on a form that was never armed — every terminal path calls it unconditionally
|
|
1781
|
+
* rather than trying to work out whether arming happened.
|
|
1782
|
+
*
|
|
1783
|
+
* #B247: the validation-rejected path is the one that stranded consumer loading
|
|
1784
|
+
* state, because a rejected submit sends nothing and so never reaches any XHR
|
|
1785
|
+
* settle. `send()`'s rate-limit early return is the same shape and is covered
|
|
1786
|
+
* too; `loadend` covers success, error, timeout and abort alike.
|
|
1787
|
+
*
|
|
1788
|
+
* @param {object} $formInstance - the form instance (`instance.$forms[id]`)
|
|
1789
|
+
*
|
|
1790
|
+
* @returns {boolean} true when a marked trigger was released
|
|
1791
|
+
*
|
|
1792
|
+
* @example
|
|
1793
|
+
* disarmSubmitLoading(instance.$forms[_id]); // on reject, settle, timeout or abort
|
|
1794
|
+
*
|
|
1795
|
+
* @inner
|
|
1796
|
+
*/
|
|
1797
|
+
var disarmSubmitLoading = function($formInstance) {
|
|
1798
|
+
if ( !$formInstance || !$formInstance.loadingTrigger ) {
|
|
1799
|
+
return false;
|
|
1800
|
+
}
|
|
1801
|
+
var released = loadingState.disarm($formInstance.loadingTrigger);
|
|
1802
|
+
$formInstance.loadingTrigger = null;
|
|
1803
|
+
return released;
|
|
1804
|
+
};
|
|
1805
|
+
|
|
1806
|
+
/**
|
|
1807
|
+
* holdTriggerFocus — remember the submit trigger gina is about to blur.
|
|
1808
|
+
*
|
|
1809
|
+
* A natively `disabled` control cannot hold focus: the instant gina disables an
|
|
1810
|
+
* in-flight submit trigger the browser moves focus to `<body>`, and re-enabling
|
|
1811
|
+
* does not bring it back (both measured). Every keyboard submit therefore loses
|
|
1812
|
+
* the user's place. Only the native-`disabled` branch is recorded — an `<a>`
|
|
1813
|
+
* receives `aria-disabled`, which does not blur (measured), so it needs no restore.
|
|
1814
|
+
*
|
|
1815
|
+
* @param {object} $form - the form instance, which carries the stash.
|
|
1816
|
+
* @param {object} $trigger - resolved submit trigger; may be null.
|
|
1817
|
+
* @returns {boolean} true when focus was captured for a later restore.
|
|
1818
|
+
*
|
|
1819
|
+
* @example
|
|
1820
|
+
* holdTriggerFocus($myFormInstance, $mySaveButton);
|
|
1821
|
+
*
|
|
1822
|
+
* @inner
|
|
1823
|
+
*/
|
|
1824
|
+
var holdTriggerFocus = function($form, $trigger) {
|
|
1825
|
+
if ( !$form || !$trigger ) {
|
|
1826
|
+
return false;
|
|
1827
|
+
}
|
|
1828
|
+
if ( typeof(document) === 'undefined' || !document ) {
|
|
1829
|
+
return false;
|
|
1830
|
+
}
|
|
1831
|
+
if ( document.activeElement !== $trigger ) {
|
|
1832
|
+
return false;
|
|
1833
|
+
}
|
|
1834
|
+
$form.ginaA11yFocusReturn = $trigger;
|
|
1835
|
+
return true;
|
|
1836
|
+
};
|
|
1837
|
+
|
|
1838
|
+
/**
|
|
1839
|
+
* releaseTriggerFocus — put focus back on the trigger gina blurred.
|
|
1840
|
+
*
|
|
1841
|
+
* Deliberately conservative: it restores ONLY when focus is still exactly where
|
|
1842
|
+
* the disable dropped it (`<body>`) and the trigger is still in the document. If
|
|
1843
|
+
* anything else claimed focus while the request was in flight — a popin opened, a
|
|
1844
|
+
* redirect ran, the failed-submit branch moved focus to the first invalid field —
|
|
1845
|
+
* that decision wins and gina undoes nothing. gina restores what gina took, never
|
|
1846
|
+
* more.
|
|
1847
|
+
*
|
|
1848
|
+
* @param {object} $form - the form instance holding the stash.
|
|
1849
|
+
* @returns {boolean} true when focus was actually restored.
|
|
1850
|
+
*
|
|
1851
|
+
* @example
|
|
1852
|
+
* releaseTriggerFocus($myFormInstance);
|
|
1853
|
+
*
|
|
1854
|
+
* @inner
|
|
1855
|
+
*/
|
|
1856
|
+
var releaseTriggerFocus = function($form) {
|
|
1857
|
+
if ( !$form || !$form.ginaA11yFocusReturn ) {
|
|
1858
|
+
return false;
|
|
1859
|
+
}
|
|
1860
|
+
var $trigger = $form.ginaA11yFocusReturn;
|
|
1861
|
+
$form.ginaA11yFocusReturn = null;
|
|
1862
|
+
if ( typeof(document) === 'undefined' || !document ) {
|
|
1863
|
+
return false;
|
|
1864
|
+
}
|
|
1865
|
+
// Nothing else may have claimed focus in the meantime.
|
|
1866
|
+
if ( document.activeElement && document.activeElement !== document.body ) {
|
|
1867
|
+
return false;
|
|
1868
|
+
}
|
|
1869
|
+
var _stillThere = ( typeof($trigger.isConnected) == 'boolean' )
|
|
1870
|
+
? $trigger.isConnected
|
|
1871
|
+
: ( document.body && document.body.contains($trigger) );
|
|
1872
|
+
if ( !_stillThere || typeof($trigger.focus) != 'function' ) {
|
|
1873
|
+
return false;
|
|
1874
|
+
}
|
|
1875
|
+
$trigger.focus();
|
|
1876
|
+
return true;
|
|
1877
|
+
};
|
|
1878
|
+
|
|
1879
|
+
/**
|
|
1880
|
+
* armSubmitA11y — expose an in-flight submit to assistive technology.
|
|
1881
|
+
*
|
|
1882
|
+
* Three things at once, all scoped to the request window: capture the trigger's
|
|
1883
|
+
* focus before the caller's native disable blurs it, mark the trigger busy, and
|
|
1884
|
+
* announce the start once through the form's polite region.
|
|
1885
|
+
*
|
|
1886
|
+
* Two placement decisions worth keeping:
|
|
1887
|
+
* - `aria-busy` goes on the TRIGGER, never the form. The live region lives inside
|
|
1888
|
+
* the form, and an ancestor marked busy MAY be treated as "defer announcements in
|
|
1889
|
+
* this subtree", which would silence the very region used to announce. ARIA 1.2
|
|
1890
|
+
* defines no normative behaviour here, so this is a cheap hedge, not a spec
|
|
1891
|
+
* requirement — and it is explicitly NOT a claim about what implementations do:
|
|
1892
|
+
* measured 2026-08-05 on VoiceOver/Chrome, an announcement from inside an
|
|
1893
|
+
* `aria-busy="true"` ancestor WAS spoken, so at least that pairing does not defer.
|
|
1894
|
+
* The placement costs nothing and still guards ATs that might; do not restate it
|
|
1895
|
+
* as "assistive tech commonly defers" — that wording was wrong and was corrected.
|
|
1896
|
+
* - This window is only ever reached once a request is genuinely in flight, so a
|
|
1897
|
+
* validation-rejected submit never arms and never announces. That is what keeps
|
|
1898
|
+
* the arm-before-validate loading state from producing a busy/not-busy flap.
|
|
1899
|
+
*
|
|
1900
|
+
* @param {object} $form - the form instance.
|
|
1901
|
+
* @param {object} $trigger - resolved submit trigger; may be null.
|
|
1902
|
+
* @returns {boolean} true when this call produced the announcement.
|
|
1903
|
+
*
|
|
1904
|
+
* @example
|
|
1905
|
+
* armSubmitA11y($myFormInstance, $mySaveButton);
|
|
1906
|
+
*
|
|
1907
|
+
* @inner
|
|
1908
|
+
*/
|
|
1909
|
+
var armSubmitA11y = function($form, $trigger) {
|
|
1910
|
+
if ( !$form ) {
|
|
1911
|
+
return false;
|
|
1912
|
+
}
|
|
1913
|
+
if ($trigger) {
|
|
1914
|
+
if ( !/^A$/i.test($trigger.tagName) ) {
|
|
1915
|
+
holdTriggerFocus($form, $trigger);
|
|
1916
|
+
}
|
|
1917
|
+
$trigger.setAttribute('aria-busy', 'true');
|
|
1918
|
+
}
|
|
1919
|
+
// readyState 1 and 3 both reach here; announce once per request.
|
|
1920
|
+
if ( $form.ginaA11yBusy ) {
|
|
1921
|
+
return false;
|
|
1922
|
+
}
|
|
1923
|
+
$form.ginaA11yBusy = true;
|
|
1924
|
+
if ( $form.target ) {
|
|
1925
|
+
announceA11yStatus($form.target, a11yLabel('submitting'));
|
|
1926
|
+
}
|
|
1927
|
+
return true;
|
|
1928
|
+
};
|
|
1929
|
+
|
|
1930
|
+
/**
|
|
1931
|
+
* releaseSubmitA11y — clear the in-flight submit exposure.
|
|
1932
|
+
*
|
|
1933
|
+
* Idempotent, because both the readyState-4 release and the `loadend` fail-safe
|
|
1934
|
+
* run it. Deliberately announces nothing on completion: an errored response is
|
|
1935
|
+
* already announced field-by-field by `handleErrorsDisplay`, and writing a second
|
|
1936
|
+
* status over a polite region in the same beat can cut that announcement off.
|
|
1937
|
+
*
|
|
1938
|
+
* @param {object} $form - the form instance.
|
|
1939
|
+
* @param {object} $trigger - resolved submit trigger; may be null.
|
|
1940
|
+
* @returns {boolean} true when focus was restored to the trigger.
|
|
1941
|
+
*
|
|
1942
|
+
* @example
|
|
1943
|
+
* releaseSubmitA11y($myFormInstance, $mySaveButton);
|
|
1944
|
+
*
|
|
1945
|
+
* @inner
|
|
1946
|
+
*/
|
|
1947
|
+
var releaseSubmitA11y = function($form, $trigger) {
|
|
1948
|
+
if ( !$form ) {
|
|
1949
|
+
return false;
|
|
1950
|
+
}
|
|
1951
|
+
if ($trigger) {
|
|
1952
|
+
$trigger.removeAttribute('aria-busy');
|
|
1953
|
+
}
|
|
1954
|
+
$form.ginaA11yBusy = false;
|
|
1955
|
+
return releaseTriggerFocus($form);
|
|
1956
|
+
};
|
|
1957
|
+
|
|
1478
1958
|
/**
|
|
1479
1959
|
* send
|
|
1480
1960
|
* N.B.: no validation here; if you want to validate against rules, use `.submit()` or `.validateFormById(formId)` before
|
|
@@ -1509,6 +1989,11 @@ function ValidatorPlugin(rules, data, formId, culture) {
|
|
|
1509
1989
|
&& typeof($form.sent) != 'undefined'
|
|
1510
1990
|
&& /^true$/i.test($form.sent)
|
|
1511
1991
|
) {
|
|
1992
|
+
// #B247 — deliberately NO loading-state release here. This return means a
|
|
1993
|
+
// request for this form is already in flight, so the trigger that owns it is
|
|
1994
|
+
// still legitimately loading and its own settle will release it. Releasing
|
|
1995
|
+
// here would clear the state mid-request; and because `armSubmitLoading` is
|
|
1996
|
+
// first-wins, the refused attempt never armed anything of its own to clear.
|
|
1512
1997
|
return;
|
|
1513
1998
|
}
|
|
1514
1999
|
|
|
@@ -1664,12 +2149,20 @@ function ValidatorPlugin(rules, data, formId, culture) {
|
|
|
1664
2149
|
}
|
|
1665
2150
|
}
|
|
1666
2151
|
$form.target.removeAttribute('data-gina-form-loading');
|
|
2152
|
+
// #B247 — the trigger-scoped release rides the same fail-safe:
|
|
2153
|
+
// `loadend` is the one hook that covers abort and error too.
|
|
2154
|
+
disarmSubmitLoading($form);
|
|
2155
|
+
// #A11Y4 — last, so focus lands on a trigger that is fully settled:
|
|
2156
|
+
// re-enabled above and no longer flagged loading.
|
|
2157
|
+
releaseSubmitA11y($form, $submitTrigger);
|
|
1667
2158
|
});
|
|
1668
2159
|
}
|
|
1669
2160
|
// catching ready state cb
|
|
1670
2161
|
// Data loading ...
|
|
1671
2162
|
if ( /^(1|3)$/.test(xhr.readyState) ) {
|
|
1672
2163
|
$form.target.setAttribute('data-gina-form-loading', true);
|
|
2164
|
+
// #A11Y4 — must run BEFORE the native disable below, which blurs the trigger.
|
|
2165
|
+
armSubmitA11y($form, $submitTrigger);
|
|
1673
2166
|
if ($submitTrigger) {
|
|
1674
2167
|
// For A tag: aria-disabled=true
|
|
1675
2168
|
if ( /^A$/i.test($submitTrigger.tagName) ) {
|
|
@@ -1698,6 +2191,8 @@ function ValidatorPlugin(rules, data, formId, culture) {
|
|
|
1698
2191
|
// Data loading ...
|
|
1699
2192
|
if ( /^(1|3)$/.test(xhr.readyState) ) {
|
|
1700
2193
|
$form.target.setAttribute('data-gina-form-loading', true);
|
|
2194
|
+
// #A11Y4 — must run BEFORE the native disable below, which blurs the trigger.
|
|
2195
|
+
armSubmitA11y($form, $submitTrigger);
|
|
1701
2196
|
if ($submitTrigger) {
|
|
1702
2197
|
// For A tag: aria-disabled=true
|
|
1703
2198
|
if ( /^A$/i.test($submitTrigger.tagName) ) {
|
|
@@ -1732,6 +2227,11 @@ function ValidatorPlugin(rules, data, formId, culture) {
|
|
|
1732
2227
|
}
|
|
1733
2228
|
}
|
|
1734
2229
|
$form.target.removeAttribute('data-gina-form-loading');
|
|
2230
|
+
// #B247 — idempotent with the `loadend` release above
|
|
2231
|
+
disarmSubmitLoading($form);
|
|
2232
|
+
// #A11Y4 — last, so focus lands on a fully settled trigger; idempotent
|
|
2233
|
+
// with the `loadend` release, which may already have restored it.
|
|
2234
|
+
releaseSubmitA11y($form, $submitTrigger);
|
|
1735
2235
|
|
|
1736
2236
|
var $popin = null;
|
|
1737
2237
|
var blob = null;
|
|
@@ -2510,7 +3010,16 @@ function ValidatorPlugin(rules, data, formId, culture) {
|
|
|
2510
3010
|
* computable) so the browser renders its native indeterminate animation;
|
|
2511
3011
|
* `error` empties the bar (value 0 — NOT indeterminate, whose animation
|
|
2512
3012
|
* would read as still working)
|
|
2513
|
-
* - any other element: `textContent` shows the integer percentage (`42%`)
|
|
3013
|
+
* - any other element: `textContent` shows the integer percentage (`42%`), and
|
|
3014
|
+
* `role="progressbar"` + `aria-valuemin="0"` / `aria-valuemax="100"` /
|
|
3015
|
+
* `aria-valuenow="<percent>"` give it the semantics a native `<progress>` gets
|
|
3016
|
+
* for free (#A11Y7/U2 — without them the indicator is unlabelled text to
|
|
3017
|
+
* assistive tech). `aria-valuenow` tracks `data-gina-upload-progress` exactly:
|
|
3018
|
+
* both are ABSENT while indeterminate and on `error`, because an absent
|
|
3019
|
+
* `aria-valuenow` is how a progressbar signals "unknown" — a stale or zero
|
|
3020
|
+
* value would read as real, stalled progress. A native `<progress>` is left
|
|
3021
|
+
* untouched: it already exposes all of this, and a redundant explicit role
|
|
3022
|
+
* risks overriding the implicit one.
|
|
2514
3023
|
*
|
|
2515
3024
|
* Every target also carries two data attributes as styling hooks:
|
|
2516
3025
|
* `data-gina-upload-progress` (integer percent, absent while indeterminate)
|
|
@@ -2546,10 +3055,28 @@ function ValidatorPlugin(rules, data, formId, culture) {
|
|
|
2546
3055
|
}
|
|
2547
3056
|
$indicator.removeAttribute('data-gina-upload-progress');
|
|
2548
3057
|
$indicator.removeAttribute('data-gina-upload-progress-state');
|
|
3058
|
+
// #A11Y7/U2 — `reset` strips everything this layer ever set, and the ARIA
|
|
3059
|
+
// below is part of "everything": leaving a stale `role="progressbar"` on a
|
|
3060
|
+
// cleared element would expose a permanently 0%-looking bar to assistive tech.
|
|
3061
|
+
if (!isNativeProgress) {
|
|
3062
|
+
$indicator.removeAttribute('role');
|
|
3063
|
+
$indicator.removeAttribute('aria-valuemin');
|
|
3064
|
+
$indicator.removeAttribute('aria-valuemax');
|
|
3065
|
+
$indicator.removeAttribute('aria-valuenow');
|
|
3066
|
+
}
|
|
2549
3067
|
return;
|
|
2550
3068
|
}
|
|
2551
3069
|
|
|
2552
3070
|
$indicator.setAttribute('data-gina-upload-progress-state', state);
|
|
3071
|
+
// #A11Y7/U2 — a native <progress> already carries implicit progressbar
|
|
3072
|
+
// semantics (and its own value/max), so it is deliberately left alone; every
|
|
3073
|
+
// other element is text with no role at all until we give it one. The bounds
|
|
3074
|
+
// are constant because `data-gina-upload-progress` is already a percentage.
|
|
3075
|
+
if (!isNativeProgress) {
|
|
3076
|
+
$indicator.setAttribute('role', 'progressbar');
|
|
3077
|
+
$indicator.setAttribute('aria-valuemin', '0');
|
|
3078
|
+
$indicator.setAttribute('aria-valuemax', '100');
|
|
3079
|
+
}
|
|
2553
3080
|
|
|
2554
3081
|
if (state == 'processing') {
|
|
2555
3082
|
// #R8 — byte-complete, server still post-processing. Advance the STATE only:
|
|
@@ -2571,6 +3098,9 @@ function ValidatorPlugin(rules, data, formId, culture) {
|
|
|
2571
3098
|
$indicator.textContent = '100%';
|
|
2572
3099
|
}
|
|
2573
3100
|
$indicator.setAttribute('data-gina-upload-progress', 100);
|
|
3101
|
+
if (!isNativeProgress) {
|
|
3102
|
+
$indicator.setAttribute('aria-valuenow', '100');
|
|
3103
|
+
}
|
|
2574
3104
|
return;
|
|
2575
3105
|
}
|
|
2576
3106
|
|
|
@@ -2584,6 +3114,13 @@ function ValidatorPlugin(rules, data, formId, culture) {
|
|
|
2584
3114
|
$indicator.textContent = '';
|
|
2585
3115
|
}
|
|
2586
3116
|
$indicator.removeAttribute('data-gina-upload-progress');
|
|
3117
|
+
// #A11Y7/U2 — an errored bar is EMPTY, not indeterminate (the native branch
|
|
3118
|
+
// above says the same about `value`): drop `aria-valuenow` so assistive tech
|
|
3119
|
+
// reports an unknown state rather than a confident 0% that reads as "no
|
|
3120
|
+
// progress yet, still working".
|
|
3121
|
+
if (!isNativeProgress) {
|
|
3122
|
+
$indicator.removeAttribute('aria-valuenow');
|
|
3123
|
+
}
|
|
2587
3124
|
return;
|
|
2588
3125
|
}
|
|
2589
3126
|
|
|
@@ -2592,6 +3129,12 @@ function ValidatorPlugin(rules, data, formId, culture) {
|
|
|
2592
3129
|
$indicator.removeAttribute('value'); // native indeterminate animation
|
|
2593
3130
|
}
|
|
2594
3131
|
$indicator.removeAttribute('data-gina-upload-progress');
|
|
3132
|
+
// #A11Y7/U2 — mirrors the `value` removal above: an absent `aria-valuenow`
|
|
3133
|
+
// on a progressbar IS the indeterminate signal, so this must track the
|
|
3134
|
+
// percent attribute exactly rather than reporting a stale last-known value.
|
|
3135
|
+
if (!isNativeProgress) {
|
|
3136
|
+
$indicator.removeAttribute('aria-valuenow');
|
|
3137
|
+
}
|
|
2595
3138
|
return;
|
|
2596
3139
|
}
|
|
2597
3140
|
|
|
@@ -2601,6 +3144,7 @@ function ValidatorPlugin(rules, data, formId, culture) {
|
|
|
2601
3144
|
$indicator.value = result.loaded;
|
|
2602
3145
|
} else {
|
|
2603
3146
|
$indicator.textContent = result.progress + '%';
|
|
3147
|
+
$indicator.setAttribute('aria-valuenow', result.progress);
|
|
2604
3148
|
}
|
|
2605
3149
|
$indicator.setAttribute('data-gina-upload-progress', result.progress);
|
|
2606
3150
|
};
|
|
@@ -2815,9 +3359,27 @@ function ValidatorPlugin(rules, data, formId, culture) {
|
|
|
2815
3359
|
|
|
2816
3360
|
$error.innerHTML = '<p>'+ errMsg +'</p>';
|
|
2817
3361
|
fadeIn($error);
|
|
3362
|
+
// #A11Y7/U3 — the container is `display:none` when the text is written and
|
|
3363
|
+
// only revealed by the fadeIn above, which is exactly the case where a
|
|
3364
|
+
// `role="alert"` on it is unreliable; route through the form's own polite
|
|
3365
|
+
// region instead — the same channel field validation errors already use.
|
|
3366
|
+
// Announce the RENDERED text, not `errMsg`: the message can carry markup
|
|
3367
|
+
// (the url-action checker substitutes `<br>`), and textContent is what a
|
|
3368
|
+
// user would actually read.
|
|
3369
|
+
if ( $uploadTriger && $uploadTriger.form ) {
|
|
3370
|
+
announceA11yError($uploadTriger.form, $error.textContent);
|
|
3371
|
+
}
|
|
2818
3372
|
} else if(!$error && status != 'success') {
|
|
2819
3373
|
throw new Error(errMsg)
|
|
2820
3374
|
} else {
|
|
3375
|
+
// #A11Y7/U2 — success is the other end of the `uploadStarted` transition.
|
|
3376
|
+
// It lives in this branch rather than at the indicator chokepoint above so
|
|
3377
|
+
// it can never fire alongside the error announcement and overwrite it: a
|
|
3378
|
+
// polite region is latest-wins, and a generic "complete" landing on top of
|
|
3379
|
+
// a specific server message would lose the message.
|
|
3380
|
+
if ( $uploadTriger && $uploadTriger.form ) {
|
|
3381
|
+
announceA11yStatus($uploadTriger.form, a11yLabel('uploadComplete'));
|
|
3382
|
+
}
|
|
2821
3383
|
|
|
2822
3384
|
var fieldsObjectList = null
|
|
2823
3385
|
, $li = null
|
|
@@ -2831,11 +3393,12 @@ function ValidatorPlugin(rules, data, formId, culture) {
|
|
|
2831
3393
|
let resetLinkNeedToBeAdded = false;
|
|
2832
3394
|
let $resetLink = document.getElementById(resetLinkId);
|
|
2833
3395
|
let defaultClassNameArr = ['reset','js-upload-reset'];
|
|
3396
|
+
let resetLabel = $uploadTriger.getAttribute('data-gina-form-upload-reset-label') || 'Reset';
|
|
2834
3397
|
if (!$resetLink) {
|
|
2835
3398
|
resetLinkNeedToBeAdded = true;
|
|
2836
3399
|
$resetLink = document.createElement('A');
|
|
2837
3400
|
$resetLink.href = '#';
|
|
2838
|
-
$resetLink.innerHTML =
|
|
3401
|
+
$resetLink.innerHTML = resetLabel;
|
|
2839
3402
|
$resetLink.className = defaultClassNameArr.join(' ');
|
|
2840
3403
|
$resetLink.id = resetLinkId;
|
|
2841
3404
|
} else {
|
|
@@ -2843,7 +3406,7 @@ function ValidatorPlugin(rules, data, formId, culture) {
|
|
|
2843
3406
|
$resetLink.href = '#';
|
|
2844
3407
|
}
|
|
2845
3408
|
if ( !$resetLink.innerHTML || $resetLink.innerHTML == '' ) {
|
|
2846
|
-
$resetLink.innerHTML =
|
|
3409
|
+
$resetLink.innerHTML = resetLabel;
|
|
2847
3410
|
}
|
|
2848
3411
|
if ( typeof($resetLink.className) == 'undefined' ) {
|
|
2849
3412
|
$resetLink.className = "";
|
|
@@ -2851,6 +3414,27 @@ function ValidatorPlugin(rules, data, formId, culture) {
|
|
|
2851
3414
|
let classNameArr = merge($resetLink.className.split(/\s+/g), defaultClassNameArr);
|
|
2852
3415
|
$resetLink.className = classNameArr.join(' ');
|
|
2853
3416
|
}
|
|
3417
|
+
// #A11Y7/U5 — the control gina generates is an anchor, so assistive tech
|
|
3418
|
+
// announces it as a link and Space does not activate it. Give it button
|
|
3419
|
+
// semantics; the matching Space handler lives with the click binding in
|
|
3420
|
+
// `bindUploadResetOrDeleteTrigger`, because a role that PROMISES button
|
|
3421
|
+
// behaviour without delivering the key is worse than no role at all.
|
|
3422
|
+
// Stamped only on an anchor: a consumer supplying their own <button> under
|
|
3423
|
+
// this id already has the right semantics, and overriding an implicit role
|
|
3424
|
+
// is a regression. Strict `/^a$/i` here, unlike the loose `/a/i` guarding
|
|
3425
|
+
// `href` above (that one also matches TEXTAREA, CANVAS, LABEL…).
|
|
3426
|
+
if ( /^a$/i.test($resetLink.tagName) ) {
|
|
3427
|
+
$resetLink.setAttribute('role', 'button');
|
|
3428
|
+
// The accessible name names the file it acts on: these controls stack
|
|
3429
|
+
// one per staged file and are otherwise identical, so a controls list
|
|
3430
|
+
// reads "Reset, Reset, Reset". The visible label stays the PREFIX so
|
|
3431
|
+
// the name still contains it (WCAG 2.5.3 Label in Name), and it reuses
|
|
3432
|
+
// the consumer's own `-reset-label`, so it is translated wherever that
|
|
3433
|
+
// already is.
|
|
3434
|
+
if ( files[f].originalFilename ) {
|
|
3435
|
+
$resetLink.setAttribute('aria-label', resetLabel + ' ' + files[f].originalFilename);
|
|
3436
|
+
}
|
|
3437
|
+
}
|
|
2854
3438
|
$resetLink.style.display = 'none';
|
|
2855
3439
|
|
|
2856
3440
|
// image preview
|
|
@@ -2861,6 +3445,12 @@ function ValidatorPlugin(rules, data, formId, culture) {
|
|
|
2861
3445
|
) {
|
|
2862
3446
|
let $img = document.createElement('IMG');
|
|
2863
3447
|
$img.src = files[f].tmpUri;
|
|
3448
|
+
// #A11Y7/U1 — the preview tells the user WHICH file is staged, so it is
|
|
3449
|
+
// informative content, not decoration; without a text alternative assistive
|
|
3450
|
+
// tech falls back to reading the temp URI aloud, once per staged file.
|
|
3451
|
+
// Empty string when the name is missing: a silently ignored image beats
|
|
3452
|
+
// announcing a placeholder.
|
|
3453
|
+
$img.alt = files[f].originalFilename || '';
|
|
2864
3454
|
$img.style.display = 'none';
|
|
2865
3455
|
$img.setAttribute('data-upload-original-filename', files[f].originalFilename);
|
|
2866
3456
|
$img.setAttribute('data-upload-reset-link-id', $resetLink.id);
|
|
@@ -2956,6 +3546,12 @@ function ValidatorPlugin(rules, data, formId, culture) {
|
|
|
2956
3546
|
// creating IMG tag
|
|
2957
3547
|
let $img = document.createElement('IMG');
|
|
2958
3548
|
$img.src = files[f][key].tmpUri;
|
|
3549
|
+
// #A11Y7/U1 — name the file the user actually chose, not the
|
|
3550
|
+
// server-generated preview variant recorded just below: the
|
|
3551
|
+
// generated name is an internal artefact and means nothing to
|
|
3552
|
+
// the person listening. Same empty-string fallback as the
|
|
3553
|
+
// no-preview branch.
|
|
3554
|
+
$img.alt = files[f].originalFilename || '';
|
|
2959
3555
|
$img.style.display = 'none';
|
|
2960
3556
|
// retrieve img `originalFilename` (not the preview img[key] `originalFilename`)
|
|
2961
3557
|
// these 2 metadatas will be used to remove files from the server
|
|
@@ -3196,6 +3792,39 @@ function ValidatorPlugin(rules, data, formId, culture) {
|
|
|
3196
3792
|
// display upload input
|
|
3197
3793
|
restoreUploadAffordance($uploadTrigger, uploadHiddenClass);
|
|
3198
3794
|
|
|
3795
|
+
// #A11Y7/U5 — the control about to be removed is the one the user
|
|
3796
|
+
// just activated, so it holds focus; removing a focused element
|
|
3797
|
+
// drops focus to <body> and the user loses their place with no
|
|
3798
|
+
// signal. Move focus first, onto the file input that owns the
|
|
3799
|
+
// staged files — which `restoreUploadAffordance` just made visible
|
|
3800
|
+
// again. Guarded on it actually holding focus, so a programmatic
|
|
3801
|
+
// reset never yanks focus away from wherever the user really is.
|
|
3802
|
+
if ( document.activeElement === $resetLink || $resetLink.contains(document.activeElement) ) {
|
|
3803
|
+
if ( typeof($uploadTrigger.focus) == 'function' ) {
|
|
3804
|
+
$uploadTrigger.focus();
|
|
3805
|
+
}
|
|
3806
|
+
// #A11Y5's lesson, applied: `typeof focus == 'function'` is true
|
|
3807
|
+
// for EVERY HTMLElement, and focus() is a silent no-op on one
|
|
3808
|
+
// that cannot take focus (hidden, disabled, detached) — so
|
|
3809
|
+
// confirm the move instead of assuming it. Signal-only: there is
|
|
3810
|
+
// no better fallback than the document, and failing loudly here
|
|
3811
|
+
// would break a removal that otherwise succeeded.
|
|
3812
|
+
if ( document.activeElement !== $uploadTrigger ) {
|
|
3813
|
+
console.debug('[FormValidator][upload]['+ ($uploadTrigger.id || '?') +'] '+ bindingType +': could not move focus to the file input before removing the '+ bindingType +' control; focus falls back to the document.');
|
|
3814
|
+
}
|
|
3815
|
+
}
|
|
3816
|
+
// Announce the removal. `aria-live="polite"` queues rather than
|
|
3817
|
+
// interrupts, so this lands after the focus move above has been
|
|
3818
|
+
// announced instead of racing it. Function replacer, not a string:
|
|
3819
|
+
// a file name may contain `$`, and a string replacement would expand
|
|
3820
|
+
// `$&` / `$1` patterns inside it.
|
|
3821
|
+
if ( $uploadTrigger.form && childNodeFile ) {
|
|
3822
|
+
announceA11yStatus(
|
|
3823
|
+
$uploadTrigger.form,
|
|
3824
|
+
a11yLabel('fileRemoved').replace('%s', function () { return childNodeFile; })
|
|
3825
|
+
);
|
|
3826
|
+
}
|
|
3827
|
+
|
|
3199
3828
|
// remove link & image - must be done last
|
|
3200
3829
|
// (the reset/delete link's own click listener dies with the node)
|
|
3201
3830
|
$resetLink.remove();
|
|
@@ -5205,6 +5834,19 @@ function ValidatorPlugin(rules, data, formId, culture) {
|
|
|
5205
5834
|
|
|
5206
5835
|
onUploadResetOrDelete($uploadTrigger, bindingType);
|
|
5207
5836
|
});
|
|
5837
|
+
// #A11Y7/U5 — the generated control is an anchor carrying `role="button"`,
|
|
5838
|
+
// and a button MUST activate on Space; an anchor natively answers Enter only,
|
|
5839
|
+
// so without this the role would advertise an interaction that does not work.
|
|
5840
|
+
// Anchors only: a real <button> already fires click on Space, and binding
|
|
5841
|
+
// this there would run the removal twice.
|
|
5842
|
+
if ( /^a$/i.test($uploadResetOrDeleteTrigger.tagName) ) {
|
|
5843
|
+
addListener(gina, $uploadResetOrDeleteTrigger, 'keydown', function onUploadResetOrDeleteTriggerKeydown(e) {
|
|
5844
|
+
if ( e.key === ' ' || e.keyCode === 32 ) {
|
|
5845
|
+
e.preventDefault(); // Space would otherwise scroll the page
|
|
5846
|
+
onUploadResetOrDelete($uploadTrigger, bindingType);
|
|
5847
|
+
}
|
|
5848
|
+
});
|
|
5849
|
+
}
|
|
5208
5850
|
$uploadResetOrDeleteTrigger.isBinded = true;
|
|
5209
5851
|
} else {
|
|
5210
5852
|
console.warn('[FormValidator::bindForm][upload]['+$uploadTrigger.id+'] : did not find `upload '+bindingType+' trigger`.\nPlease, make sure that your '+bindingType+' element ID is `'+ uploadResetOrDeleteTriggerId +'`, or add to your file input ('+ $uploadTrigger.id +') -> `data-gina-form-upload-'+bindingType+'-trigger="your-custom-id"` definition.');
|
|
@@ -5656,6 +6298,13 @@ function ValidatorPlugin(rules, data, formId, culture) {
|
|
|
5656
6298
|
throw new Error('Validator::bindForm($target, customRule) could not bind form `'+ $target +'`\n'+err.stack );
|
|
5657
6299
|
}
|
|
5658
6300
|
|
|
6301
|
+
// #A11Y2 — stand the polite live region up HERE, at bind time, rather than lazily on the
|
|
6302
|
+
// first error. Creating and populating it in one tick reaches assistive tech as a single
|
|
6303
|
+
// mutation batch that is commonly never spoken, so the first announcement per form used to
|
|
6304
|
+
// be the one most likely lost. Every registration path funnels through bindForm, so this
|
|
6305
|
+
// one call covers them all. Announcing stays announceA11yError's job; this only creates.
|
|
6306
|
+
ensureA11yLiveRegion($target);
|
|
6307
|
+
|
|
5659
6308
|
// console.debug('binding for: '+ _id);
|
|
5660
6309
|
var withRules = false, rule = null, evt = '', proceed = null;
|
|
5661
6310
|
|
|
@@ -6404,6 +7053,24 @@ function ValidatorPlugin(rules, data, formId, culture) {
|
|
|
6404
7053
|
updateUploadProgressIndicator($uploadForm.uploadProperties.progressContainer, 'preparing');
|
|
6405
7054
|
}
|
|
6406
7055
|
|
|
7056
|
+
// #A11Y7/U2 — announce the transition into "uploading". Note this
|
|
7057
|
+
// is deliberately NOT gated on `progressContainer`: the indicator is
|
|
7058
|
+
// opt-in by presence, but a user who cannot see it is precisely the
|
|
7059
|
+
// one who needs to be told the upload began.
|
|
7060
|
+
// The announcement targets the file input's REAL owning form, not
|
|
7061
|
+
// `$uploadForm` (the virtual one built just above): the real form is
|
|
7062
|
+
// where `bindForm` already stood up a live region, so upload status
|
|
7063
|
+
// and validation errors share one region instead of splitting across
|
|
7064
|
+
// two. Selection always sends today — the `.send()` below is
|
|
7065
|
+
// unconditional and `data-gina-file-autosend="false"` is still a TODO
|
|
7066
|
+
// — so this is a true start; gate it if that ever lands.
|
|
7067
|
+
if ( $uploadForm.uploadProperties && $uploadForm.uploadProperties.uploadTriggerId ) {
|
|
7068
|
+
var $a11yUploadInput = document.getElementById($uploadForm.uploadProperties.uploadTriggerId);
|
|
7069
|
+
if ( $a11yUploadInput && $a11yUploadInput.form ) {
|
|
7070
|
+
announceA11yStatus($a11yUploadInput.form, a11yLabel('uploadStarted'));
|
|
7071
|
+
}
|
|
7072
|
+
}
|
|
7073
|
+
|
|
6407
7074
|
// binding form
|
|
6408
7075
|
try {
|
|
6409
7076
|
var $uploadFormValidator = getFormById(uploadFormId);
|
|
@@ -7329,6 +7996,44 @@ function ValidatorPlugin(rules, data, formId, culture) {
|
|
|
7329
7996
|
_evt = 'reset.'+_evt
|
|
7330
7997
|
}
|
|
7331
7998
|
|
|
7999
|
+
// #B246 — a disabled submit trigger must not run the submit cycle.
|
|
8000
|
+
// `updateSubmitTriggerState()` marks an invalid form's trigger with
|
|
8001
|
+
// `aria-disabled="true"` and never with native `disabled`, precisely so
|
|
8002
|
+
// the click still reaches us. Nothing READ that marker, so the trigger
|
|
8003
|
+
// stayed fully operable: a click ran the collect -> validate ->
|
|
8004
|
+
// `validate.<id>` chain and only the `isValid()` gate stopped the send.
|
|
8005
|
+
// The trigger was inert in appearance ONLY, and that also contradicted
|
|
8006
|
+
// the `aria-disabled` contract it advertises to assistive tech (which
|
|
8007
|
+
// requires the author to suppress the action).
|
|
8008
|
+
//
|
|
8009
|
+
// Intercept HERE — before the `submit.<id>` dispatch below — so
|
|
8010
|
+
// `bindSubmitEl`'s handler never runs, `isSubmitting` is never latched
|
|
8011
|
+
// and no send path is reachable. The click is still answered with a
|
|
8012
|
+
// display-only reveal, so the user learns WHY the trigger is disabled
|
|
8013
|
+
// (which is what the operable-trigger design was bought for).
|
|
8014
|
+
// Checked on the CLICKED element, not `$formInstance.submitTrigger`:
|
|
8015
|
+
// a form may carry several submit buttons and only one registers.
|
|
8016
|
+
if ( /^submit\./i.test(_evt) && isTriggerDisabled($el) ) {
|
|
8017
|
+
cancelEvent(event);
|
|
8018
|
+
revealValidationState( instance.$forms[$form.id] || $form );
|
|
8019
|
+
return false;
|
|
8020
|
+
}
|
|
8021
|
+
|
|
8022
|
+
// #B247 — arm the loading state on the element the user actually
|
|
8023
|
+
// operated. DELIBERATELY after the #B246 gate above: a disabled
|
|
8024
|
+
// trigger returns without starting anything, so arming it there
|
|
8025
|
+
// would strand exactly the state this feature exists to release.
|
|
8026
|
+
// `resolveTrigger` climbs to the owning button/anchor, because a
|
|
8027
|
+
// click on a wrapped label (`<button><span>Save</span></button>`)
|
|
8028
|
+
// targets the inner node, and the state belongs on the control the
|
|
8029
|
+
// user perceives as the trigger.
|
|
8030
|
+
if ( /^submit\./i.test(_evt) ) {
|
|
8031
|
+
armSubmitLoading(
|
|
8032
|
+
instance.$forms[$form.id] || $form,
|
|
8033
|
+
loadingState.resolveTrigger($el, $target)
|
|
8034
|
+
);
|
|
8035
|
+
}
|
|
8036
|
+
|
|
7332
8037
|
if (gina.events[_evt]) {
|
|
7333
8038
|
cancelEvent(event);
|
|
7334
8039
|
|
|
@@ -7464,6 +8169,22 @@ function ValidatorPlugin(rules, data, formId, culture) {
|
|
|
7464
8169
|
instance.$forms[_id].isSubmitting = false;
|
|
7465
8170
|
}
|
|
7466
8171
|
|
|
8172
|
+
// #B247 — release the trigger-scoped loading state. THIS is the path
|
|
8173
|
+
// that stranded it: a rejected submit produces no request at all, so
|
|
8174
|
+
// none of the XHR releases can ever run, and only the framework knows
|
|
8175
|
+
// the submit was refused before it started. Left armed, the trigger
|
|
8176
|
+
// stays visually loading until the page or popin is reloaded.
|
|
8177
|
+
//
|
|
8178
|
+
// Gated on nothing being in flight: a form can be submitted again
|
|
8179
|
+
// while an earlier request is still running, and that later attempt
|
|
8180
|
+
// may well be the one that fails validation. Releasing unconditionally
|
|
8181
|
+
// would clear the state belonging to the request still in progress —
|
|
8182
|
+
// whose own settle is what must release it.
|
|
8183
|
+
var _loadingForm = instance.$forms[_id] || $form;
|
|
8184
|
+
if ( !/^true$/i.test(_loadingForm.isSending) ) {
|
|
8185
|
+
disarmSubmitLoading(_loadingForm);
|
|
8186
|
+
}
|
|
8187
|
+
|
|
7467
8188
|
// #A11Y1 (slice 3) — failed submit: move focus to the first invalid field so
|
|
7468
8189
|
// assistive tech announces it (accessible name + aria-invalid + the
|
|
7469
8190
|
// aria-errormessage text). DOM order; hidden / unfocusable fields are skipped.
|
|
@@ -7481,7 +8202,13 @@ function ValidatorPlugin(rules, data, formId, culture) {
|
|
|
7481
8202
|
&& typeof(_aField.focus) == 'function'
|
|
7482
8203
|
) {
|
|
7483
8204
|
_aField.focus();
|
|
7484
|
-
|
|
8205
|
+
// #A11Y5 (V8) — kept in step with focusFirstInvalidField:
|
|
8206
|
+
// only stop once focus actually moved, since focus() is a
|
|
8207
|
+
// no-op on an unfocusable host that still passes the
|
|
8208
|
+
// typeof-function gate above.
|
|
8209
|
+
if ( typeof(document) === 'undefined' || !document || document.activeElement === _aField ) {
|
|
8210
|
+
break;
|
|
8211
|
+
}
|
|
7485
8212
|
}
|
|
7486
8213
|
}
|
|
7487
8214
|
}
|
|
@@ -7702,6 +8429,27 @@ function ValidatorPlugin(rules, data, formId, culture) {
|
|
|
7702
8429
|
return false;
|
|
7703
8430
|
}
|
|
7704
8431
|
|
|
8432
|
+
// #B247 — a submit that never went through the click proxy still gets a
|
|
8433
|
+
// loading state: Enter inside a field, `form.submit()`, `$validator.submit()`,
|
|
8434
|
+
// and — less obviously — a click on a wrapped label such as
|
|
8435
|
+
// `<button type="submit"><span>Save</span></button>`, whose event.target is
|
|
8436
|
+
// the span (no `.type`), so the click proxy's submit branch never fires and
|
|
8437
|
+
// the event surfaces here instead. There is no clicked element on this path,
|
|
8438
|
+
// so the registered trigger is the best and only referent. Placed after the
|
|
8439
|
+
// disabled + defaultPrevented guards above, which both return first.
|
|
8440
|
+
// NB. the disabled check at the top of this handler reads a DOMParser copy of
|
|
8441
|
+
// the form's innerHTML, so it sees neither a live `disabled` set by JS nor the
|
|
8442
|
+
// `aria-disabled` marker `updateSubmitTriggerState` uses. Re-check the live
|
|
8443
|
+
// node with #B246's predicate: without it, every Enter-key submit on an
|
|
8444
|
+
// invalid live-check form would flash the trigger armed for the length of the
|
|
8445
|
+
// validation pass before the rejected branch released it.
|
|
8446
|
+
if ($formInstance) {
|
|
8447
|
+
var $loadingTrigger = document.getElementById($formInstance.submitTrigger);
|
|
8448
|
+
if ( !isTriggerDisabled($loadingTrigger) ) {
|
|
8449
|
+
armSubmitLoading($formInstance, $loadingTrigger);
|
|
8450
|
+
}
|
|
8451
|
+
}
|
|
8452
|
+
|
|
7705
8453
|
if (withRules || isBinded) {
|
|
7706
8454
|
cancelEvent(e);
|
|
7707
8455
|
}
|
|
@@ -7891,13 +8639,17 @@ function ValidatorPlugin(rules, data, formId, culture) {
|
|
|
7891
8639
|
} else if ( document.getElementById($formInstance.submitTrigger) ) {
|
|
7892
8640
|
// Represent the "invalid + live-check-on" state with aria-disabled + a class
|
|
7893
8641
|
// INSTEAD of the native `disabled` property. A natively-disabled <button>
|
|
7894
|
-
// emits no click event, so the
|
|
7895
|
-
//
|
|
7896
|
-
//
|
|
7897
|
-
//
|
|
7898
|
-
//
|
|
7899
|
-
//
|
|
7900
|
-
//
|
|
8642
|
+
// emits no click event at all, so the click cannot be observed and the user
|
|
8643
|
+
// gets no feedback about WHY the trigger is dead. aria-disabled keeps the
|
|
8644
|
+
// trigger focusable and perceivable, and clickProxyHandler INTERCEPTS the
|
|
8645
|
+
// click (#B246) to answer it with a display-only reveal: every invalid field
|
|
8646
|
+
// is rendered and the first is focused, while the submit cycle is never
|
|
8647
|
+
// entered. The trigger is therefore genuinely not operable — which is what
|
|
8648
|
+
// the aria-disabled contract promises assistive tech, and what the earlier
|
|
8649
|
+
// "keep it operable so the click can still validate" shape got wrong: it
|
|
8650
|
+
// left the real submit path reachable from a control announced as disabled.
|
|
8651
|
+
// Mirrors gina's own <a>-tag submit-trigger handling, which already uses
|
|
8652
|
+
// aria-disabled in-flight. The show branch KEEPS clearing native `disabled` so a trigger
|
|
7901
8653
|
// rendered `disabled` in markup still enables on valid / when live-check is off.
|
|
7902
8654
|
// Tag-agnostic: setAttribute/classList work for both <button> and <a> submit
|
|
7903
8655
|
// triggers. Consumers must style the [aria-disabled="true"] /
|
|
@@ -7918,6 +8670,125 @@ function ValidatorPlugin(rules, data, formId, culture) {
|
|
|
7918
8670
|
}
|
|
7919
8671
|
}
|
|
7920
8672
|
|
|
8673
|
+
/**
|
|
8674
|
+
* isTriggerDisabled
|
|
8675
|
+
*
|
|
8676
|
+
* Tells whether a submit trigger is currently marked as disabled.
|
|
8677
|
+
* `updateSubmitTriggerState()` marks an invalid form's trigger with
|
|
8678
|
+
* `aria-disabled="true"` rather than the native `disabled` property, so a
|
|
8679
|
+
* native-only check can never see it. The predicate shape mirrors the popin
|
|
8680
|
+
* plugin's own trigger gate, so both subsystems agree on what "disabled"
|
|
8681
|
+
* means for a trigger.
|
|
8682
|
+
*
|
|
8683
|
+
* @param {object} $el - candidate trigger (DOMObject)
|
|
8684
|
+
*
|
|
8685
|
+
* @returns {boolean} true when the trigger must not be operated
|
|
8686
|
+
*
|
|
8687
|
+
* @example
|
|
8688
|
+
* isTriggerDisabled($button); // true while aria-disabled="true" is set
|
|
8689
|
+
*
|
|
8690
|
+
* @inner
|
|
8691
|
+
*/
|
|
8692
|
+
var isTriggerDisabled = function($el) {
|
|
8693
|
+
if ( !$el || typeof($el.getAttribute) != 'function' ) {
|
|
8694
|
+
return false;
|
|
8695
|
+
}
|
|
8696
|
+
return (
|
|
8697
|
+
$el.getAttribute('disabled') != null && $el.getAttribute('disabled') != 'false'
|
|
8698
|
+
||
|
|
8699
|
+
$el.getAttribute('aria-disabled') == 'true'
|
|
8700
|
+
);
|
|
8701
|
+
};
|
|
8702
|
+
|
|
8703
|
+
/**
|
|
8704
|
+
* focusFirstInvalidField
|
|
8705
|
+
*
|
|
8706
|
+
* Moves focus to the first field carrying an error, in DOM order, skipping
|
|
8707
|
+
* hidden and unfocusable controls (#A11Y1) so assistive tech announces the
|
|
8708
|
+
* accessible name + `aria-invalid` + the `aria-errormessage` text.
|
|
8709
|
+
*
|
|
8710
|
+
* NB. the `validate.<id>` guard keeps its own inline twin of this loop rather
|
|
8711
|
+
* than calling here. That is DELIBERATE: the inline shape is locked by source
|
|
8712
|
+
* pins in `test/core/validator-aria-invalid.test.js` (`_a11yErrs`, `_aField`),
|
|
8713
|
+
* so collapsing the two would break pins unrelated to #B246. Keep the two in
|
|
8714
|
+
* step if the focus rule ever changes.
|
|
8715
|
+
*
|
|
8716
|
+
* @param {object} $form - form target (DOMObject), not the instance
|
|
8717
|
+
* @param {object} errors - error map keyed by field name
|
|
8718
|
+
*
|
|
8719
|
+
* @returns {boolean} true when a field was focused
|
|
8720
|
+
*
|
|
8721
|
+
* @example
|
|
8722
|
+
* focusFirstInvalidField($form, result['fields'] || result['error']);
|
|
8723
|
+
*
|
|
8724
|
+
* @inner
|
|
8725
|
+
*/
|
|
8726
|
+
var focusFirstInvalidField = function($form, errors) {
|
|
8727
|
+
if ( !$form || !errors ) {
|
|
8728
|
+
return false;
|
|
8729
|
+
}
|
|
8730
|
+
for (var i = 0, len = $form.length; i < len; ++i) {
|
|
8731
|
+
var $field = $form[i];
|
|
8732
|
+
var name = $field.getAttribute('name');
|
|
8733
|
+
if (
|
|
8734
|
+
name
|
|
8735
|
+
&& typeof(errors[name]) != 'undefined'
|
|
8736
|
+
&& ( typeof(errors[name].count) != 'function' || errors[name].count() > 0 )
|
|
8737
|
+
&& $field.type != 'hidden'
|
|
8738
|
+
&& typeof($field.focus) == 'function'
|
|
8739
|
+
) {
|
|
8740
|
+
$field.focus();
|
|
8741
|
+
// #A11Y5 (V8) — `typeof focus == 'function'` is true for EVERY HTMLElement,
|
|
8742
|
+
// a custom element with neither `tabindex` nor `delegatesFocus` included,
|
|
8743
|
+
// whose focus() is a silent no-op (measured). Without confirming the move,
|
|
8744
|
+
// the loop reported success and stopped on a control that never took focus,
|
|
8745
|
+
// so a failed submit announced nothing. Confirming it is also what makes the
|
|
8746
|
+
// "skips unfocusable controls" contract above true rather than aspirational.
|
|
8747
|
+
if ( typeof(document) === 'undefined' || !document || document.activeElement === $field ) {
|
|
8748
|
+
return true;
|
|
8749
|
+
}
|
|
8750
|
+
}
|
|
8751
|
+
}
|
|
8752
|
+
return false;
|
|
8753
|
+
};
|
|
8754
|
+
|
|
8755
|
+
/**
|
|
8756
|
+
* revealValidationState
|
|
8757
|
+
*
|
|
8758
|
+
* Display-only validation pass, used when a DISABLED submit trigger is
|
|
8759
|
+
* clicked (#B246). It runs the same collect + validate chain the submit path
|
|
8760
|
+
* uses, but routes the result straight to the error renderer instead of
|
|
8761
|
+
* dispatching `validate.<id>` — so `bindSubmitEl`'s handler never runs, the
|
|
8762
|
+
* `isSubmitting` latch is never set and the `isValid()` send gate is never
|
|
8763
|
+
* reached. No request can start from this path by construction.
|
|
8764
|
+
*
|
|
8765
|
+
* The trigger state is re-synced from the fresh result, which also self-heals
|
|
8766
|
+
* a stale disabled marker on a form that has since become valid.
|
|
8767
|
+
*
|
|
8768
|
+
* @param {object} $formInstance - form instance (carries `.target` / `.rules`)
|
|
8769
|
+
*
|
|
8770
|
+
* @returns {void}
|
|
8771
|
+
*
|
|
8772
|
+
* @example
|
|
8773
|
+
* revealValidationState(instance.$forms['myForm']);
|
|
8774
|
+
*
|
|
8775
|
+
* @inner
|
|
8776
|
+
*/
|
|
8777
|
+
var revealValidationState = function($formInstance) {
|
|
8778
|
+
if ( !$formInstance || !$formInstance.target ) {
|
|
8779
|
+
return;
|
|
8780
|
+
}
|
|
8781
|
+
var $target = $formInstance.target;
|
|
8782
|
+
var validationInfo = getFormValidationInfos($target, $formInstance.rules);
|
|
8783
|
+
|
|
8784
|
+
validate($target, validationInfo.fields, validationInfo.$fields, $formInstance.rules, function onDisabledTriggerReveal(result) {
|
|
8785
|
+
var errors = result['fields'] || result['error'];
|
|
8786
|
+
handleErrorsDisplay($target, errors, result['data']);
|
|
8787
|
+
focusFirstInvalidField($target, errors);
|
|
8788
|
+
updateSubmitTriggerState($formInstance, result.isValid());
|
|
8789
|
+
});
|
|
8790
|
+
};
|
|
8791
|
+
|
|
7921
8792
|
/**
|
|
7922
8793
|
* getFormValidationInfos
|
|
7923
8794
|
*
|
|
@@ -9476,5 +10347,5 @@ if ( ( typeof(module) !== 'undefined' ) && module.exports ) {
|
|
|
9476
10347
|
module.exports = ValidatorPlugin
|
|
9477
10348
|
} else if ( typeof(define) === 'function' && define.amd) {
|
|
9478
10349
|
// Publish as AMD module
|
|
9479
|
-
define('gina/validator', ['utils/events', 'utils/dom', 'utils/effects', 'utils/data', 'lib/form-validator', 'lib/routing'], function(){ return ValidatorPlugin })
|
|
10350
|
+
define('gina/validator', ['utils/events', 'utils/dom', 'utils/effects', 'utils/data', 'lib/form-validator', 'lib/routing', 'lib/loading-state'], function(){ return ValidatorPlugin })
|
|
9480
10351
|
}
|