@dotglitch/ngx-common 3.0.0-beta.1 → 3.0.0-beta.2
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/command-palette/breadcrumb/breadcrumb.component.d.ts +16 -0
- package/command-palette/command-palette.component.d.ts +38 -0
- package/command-palette/command-palette.service.d.ts +128 -0
- package/command-palette/index.d.ts +2 -0
- package/command-palette/shortcut/shortcut.component.d.ts +9 -0
- package/{components → core/components}/menu/menu.component.d.ts +2 -2
- package/{directives → core/components/menu}/menu.directive.d.ts +1 -1
- package/{types/menu.d.ts → core/components/menu/types.d.ts} +1 -1
- package/{components → core/components}/types.d.ts +0 -1
- package/{public-api.d.ts → core/index.d.ts} +8 -4
- package/{services → core/services}/navigation.service.d.ts +1 -1
- package/core/utils/index.d.ts +18 -0
- package/esm2022/command-palette/breadcrumb/breadcrumb.component.mjs +30 -0
- package/esm2022/command-palette/command-palette.component.mjs +257 -0
- package/esm2022/command-palette/command-palette.service.mjs +207 -0
- package/esm2022/command-palette/dotglitch-ngx-common-command-palette.mjs +5 -0
- package/esm2022/command-palette/index.mjs +3 -0
- package/esm2022/command-palette/shortcut/shortcut.component.mjs +19 -0
- package/esm2022/core/components/lazy-loader/lazy-loader.component.mjs +383 -0
- package/esm2022/core/components/lazy-loader/lazy-loader.module.mjs +33 -0
- package/esm2022/core/components/lazy-loader/lazy-loader.service.mjs +216 -0
- package/esm2022/core/components/lazy-loader/types.mjs +26 -0
- package/esm2022/core/components/menu/menu.component.mjs +433 -0
- package/esm2022/core/components/menu/menu.directive.mjs +159 -0
- package/esm2022/core/components/menu/types.mjs +2 -0
- package/esm2022/core/components/parallax-card/parallax-card.component.mjs +138 -0
- package/esm2022/core/components/types.mjs +3 -0
- package/esm2022/core/directives/image-cache.directive.mjs +143 -0
- package/esm2022/core/directives/utils.mjs +120 -0
- package/esm2022/core/dotglitch-ngx-common-core.mjs +5 -0
- package/esm2022/core/index.mjs +50 -0
- package/esm2022/core/pipes/html-bypass.pipe.mjs +27 -0
- package/esm2022/core/pipes/resource-bypass.pipe.mjs +27 -0
- package/esm2022/core/pipes/script-bypass.pipe.mjs +27 -0
- package/esm2022/core/pipes/style-bypass.pipe.mjs +27 -0
- package/esm2022/core/pipes/url-bypass.pipe.mjs +27 -0
- package/esm2022/core/services/dependency.service.mjs +55 -0
- package/esm2022/core/services/dialog.service.mjs +67 -0
- package/esm2022/core/services/fetch.service.mjs +74 -0
- package/esm2022/core/services/file.service.mjs +42 -0
- package/esm2022/core/services/keyboard.service.mjs +128 -0
- package/esm2022/core/services/navigation.service.mjs +50 -0
- package/esm2022/core/services/theme.service.mjs +64 -0
- package/esm2022/core/types/popup.mjs +2 -0
- package/esm2022/core/utils/index.mjs +69 -0
- package/esm2022/dotglitch-ngx-common.mjs +2 -2
- package/esm2022/filemanager/dotglitch-ngx-common-filemanager.mjs +5 -0
- package/esm2022/filemanager/file-grid/file-grid.component.mjs +676 -0
- package/esm2022/filemanager/filemanager.component.mjs +313 -0
- package/esm2022/filemanager/folder-rename/folder-rename.component.mjs +57 -0
- package/esm2022/filemanager/helpers.mjs +26 -0
- package/esm2022/filemanager/icon-resolver.mjs +155 -0
- package/esm2022/filemanager/index.mjs +2 -0
- package/esm2022/filemanager/mat-icons.mjs +5705 -0
- package/esm2022/filemanager/textextensions.mjs +294 -0
- package/esm2022/filemanager/toolbar/breadcrumb/breadcrumb.component.mjs +22 -0
- package/esm2022/filemanager/toolbar/icon-button/icon-button.component.mjs +32 -0
- package/esm2022/filemanager/toolbar/toolbar.component.mjs +165 -0
- package/esm2022/filemanager/tree-view/tree-view.component.mjs +51 -0
- package/esm2022/filemanager/types.mjs +2 -0
- package/esm2022/index.mjs +3 -0
- package/esm2022/monaco-editor/dotglitch-ngx-common-monaco-editor.mjs +5 -0
- package/esm2022/monaco-editor/index.mjs +2 -0
- package/esm2022/monaco-editor/monaco-editor.component.mjs +234 -0
- package/esm2022/monaco-editor/ts-type-resolver/dependency-parser.mjs +91 -0
- package/esm2022/monaco-editor/ts-type-resolver/dummy-source-cache.mjs +15 -0
- package/esm2022/monaco-editor/ts-type-resolver/import-resolver.mjs +311 -0
- package/esm2022/monaco-editor/ts-type-resolver/main.mjs +112 -0
- package/esm2022/monaco-editor/ts-type-resolver/recursion-depth.mjs +21 -0
- package/esm2022/monaco-editor/ts-type-resolver/types.mjs +14 -0
- package/esm2022/monaco-editor/ts-type-resolver/unpkg-source-resolver.mjs +21 -0
- package/esm2022/monaco-editor/ts-type-resolver/update-emitter.mjs +37 -0
- package/esm2022/overlay-wrapper/dotglitch-ngx-common-overlay-wrapper.mjs +5 -0
- package/esm2022/overlay-wrapper/index.mjs +2 -0
- package/esm2022/overlay-wrapper/overlay-wrapper.component.mjs +247 -0
- package/esm2022/tooltip/dotglitch-ngx-common-tooltip.mjs +5 -0
- package/esm2022/tooltip/index.mjs +4 -0
- package/esm2022/tooltip/tooltip.component.mjs +204 -0
- package/esm2022/tooltip/tooltip.directive.mjs +153 -0
- package/esm2022/tooltip/types.mjs +2 -0
- package/fesm2022/dotglitch-ngx-common-command-palette.mjs +508 -0
- package/fesm2022/dotglitch-ngx-common-command-palette.mjs.map +1 -0
- package/fesm2022/dotglitch-ngx-common-core.mjs +2280 -0
- package/fesm2022/dotglitch-ngx-common-core.mjs.map +1 -0
- package/fesm2022/dotglitch-ngx-common-filemanager-folder-rename.component-CnKuU8nn.mjs +60 -0
- package/fesm2022/dotglitch-ngx-common-filemanager-folder-rename.component-CnKuU8nn.mjs.map +1 -0
- package/fesm2022/dotglitch-ngx-common-filemanager.mjs +7403 -0
- package/fesm2022/dotglitch-ngx-common-filemanager.mjs.map +1 -0
- package/fesm2022/dotglitch-ngx-common-monaco-editor.mjs +850 -0
- package/fesm2022/dotglitch-ngx-common-monaco-editor.mjs.map +1 -0
- package/fesm2022/dotglitch-ngx-common-overlay-wrapper.mjs +254 -0
- package/fesm2022/dotglitch-ngx-common-overlay-wrapper.mjs.map +1 -0
- package/fesm2022/dotglitch-ngx-common-tooltip.mjs +357 -0
- package/fesm2022/dotglitch-ngx-common-tooltip.mjs.map +1 -0
- package/fesm2022/dotglitch-ngx-common.mjs +3 -2757
- package/fesm2022/dotglitch-ngx-common.mjs.map +1 -1
- package/filemanager/file-grid/file-grid.component.d.ts +94 -0
- package/filemanager/filemanager.component.d.ts +206 -0
- package/filemanager/folder-rename/folder-rename.component.d.ts +18 -0
- package/filemanager/helpers.d.ts +5 -0
- package/filemanager/icon-resolver.d.ts +13 -0
- package/filemanager/index.d.ts +1 -0
- package/filemanager/mat-icons.d.ts +5705 -0
- package/filemanager/textextensions.d.ts +3 -0
- package/filemanager/toolbar/breadcrumb/breadcrumb.component.d.ts +16 -0
- package/filemanager/toolbar/icon-button/icon-button.component.d.ts +11 -0
- package/filemanager/toolbar/toolbar.component.d.ts +31 -0
- package/filemanager/tree-view/tree-view.component.d.ts +21 -0
- package/filemanager/types.d.ts +1 -0
- package/index.d.ts +1 -5
- package/monaco-editor/README.md +3 -0
- package/monaco-editor/index.d.ts +1 -0
- package/monaco-editor/monaco-editor.component.d.ts +53 -0
- package/monaco-editor/ts-type-resolver/dependency-parser.d.ts +6 -0
- package/monaco-editor/ts-type-resolver/dummy-source-cache.d.ts +7 -0
- package/monaco-editor/ts-type-resolver/import-resolver.d.ts +28 -0
- package/monaco-editor/ts-type-resolver/main.d.ts +22 -0
- package/monaco-editor/ts-type-resolver/recursion-depth.d.ts +11 -0
- package/monaco-editor/ts-type-resolver/types.d.ts +179 -0
- package/monaco-editor/ts-type-resolver/unpkg-source-resolver.d.ts +5 -0
- package/monaco-editor/ts-type-resolver/update-emitter.d.ts +2 -0
- package/overlay-wrapper/index.d.ts +1 -0
- package/overlay-wrapper/overlay-wrapper.component.d.ts +11 -0
- package/package.json +104 -64
- package/tooltip/index.d.ts +3 -0
- package/{components/tooltip → tooltip}/tooltip.component.d.ts +3 -3
- package/{directives → tooltip}/tooltip.directive.d.ts +2 -2
- package/{types/tooltip.d.ts → tooltip/types.d.ts} +1 -1
- package/assets/lib/vs/base/browser/ui/codicons/codicon/codicon.ttf +0 -0
- package/assets/lib/vs/base/common/worker/simpleWorker.nls.de.js +0 -8
- package/assets/lib/vs/base/common/worker/simpleWorker.nls.es.js +0 -8
- package/assets/lib/vs/base/common/worker/simpleWorker.nls.fr.js +0 -8
- package/assets/lib/vs/base/common/worker/simpleWorker.nls.it.js +0 -8
- package/assets/lib/vs/base/common/worker/simpleWorker.nls.ja.js +0 -8
- package/assets/lib/vs/base/common/worker/simpleWorker.nls.js +0 -8
- package/assets/lib/vs/base/common/worker/simpleWorker.nls.ko.js +0 -8
- package/assets/lib/vs/base/common/worker/simpleWorker.nls.ru.js +0 -8
- package/assets/lib/vs/base/common/worker/simpleWorker.nls.zh-cn.js +0 -8
- package/assets/lib/vs/base/common/worker/simpleWorker.nls.zh-tw.js +0 -8
- package/assets/lib/vs/base/worker/workerMain.js +0 -24
- package/assets/lib/vs/basic-languages/abap/abap.js +0 -10
- package/assets/lib/vs/basic-languages/apex/apex.js +0 -10
- package/assets/lib/vs/basic-languages/azcli/azcli.js +0 -10
- package/assets/lib/vs/basic-languages/bat/bat.js +0 -10
- package/assets/lib/vs/basic-languages/bicep/bicep.js +0 -11
- package/assets/lib/vs/basic-languages/cameligo/cameligo.js +0 -10
- package/assets/lib/vs/basic-languages/clojure/clojure.js +0 -10
- package/assets/lib/vs/basic-languages/coffee/coffee.js +0 -10
- package/assets/lib/vs/basic-languages/cpp/cpp.js +0 -10
- package/assets/lib/vs/basic-languages/csharp/csharp.js +0 -10
- package/assets/lib/vs/basic-languages/csp/csp.js +0 -10
- package/assets/lib/vs/basic-languages/css/css.js +0 -12
- package/assets/lib/vs/basic-languages/cypher/cypher.js +0 -10
- package/assets/lib/vs/basic-languages/dart/dart.js +0 -10
- package/assets/lib/vs/basic-languages/dockerfile/dockerfile.js +0 -10
- package/assets/lib/vs/basic-languages/ecl/ecl.js +0 -10
- package/assets/lib/vs/basic-languages/elixir/elixir.js +0 -10
- package/assets/lib/vs/basic-languages/flow9/flow9.js +0 -10
- package/assets/lib/vs/basic-languages/freemarker2/freemarker2.js +0 -12
- package/assets/lib/vs/basic-languages/fsharp/fsharp.js +0 -10
- package/assets/lib/vs/basic-languages/go/go.js +0 -10
- package/assets/lib/vs/basic-languages/graphql/graphql.js +0 -10
- package/assets/lib/vs/basic-languages/handlebars/handlebars.js +0 -10
- package/assets/lib/vs/basic-languages/hcl/hcl.js +0 -10
- package/assets/lib/vs/basic-languages/html/html.js +0 -10
- package/assets/lib/vs/basic-languages/ini/ini.js +0 -10
- package/assets/lib/vs/basic-languages/java/java.js +0 -10
- package/assets/lib/vs/basic-languages/javascript/javascript.js +0 -10
- package/assets/lib/vs/basic-languages/julia/julia.js +0 -10
- package/assets/lib/vs/basic-languages/kotlin/kotlin.js +0 -10
- package/assets/lib/vs/basic-languages/less/less.js +0 -11
- package/assets/lib/vs/basic-languages/lexon/lexon.js +0 -10
- package/assets/lib/vs/basic-languages/liquid/liquid.js +0 -10
- package/assets/lib/vs/basic-languages/lua/lua.js +0 -10
- package/assets/lib/vs/basic-languages/m3/m3.js +0 -10
- package/assets/lib/vs/basic-languages/markdown/markdown.js +0 -10
- package/assets/lib/vs/basic-languages/mips/mips.js +0 -10
- package/assets/lib/vs/basic-languages/msdax/msdax.js +0 -10
- package/assets/lib/vs/basic-languages/mysql/mysql.js +0 -10
- package/assets/lib/vs/basic-languages/objective-c/objective-c.js +0 -10
- package/assets/lib/vs/basic-languages/pascal/pascal.js +0 -10
- package/assets/lib/vs/basic-languages/pascaligo/pascaligo.js +0 -10
- package/assets/lib/vs/basic-languages/perl/perl.js +0 -10
- package/assets/lib/vs/basic-languages/pgsql/pgsql.js +0 -10
- package/assets/lib/vs/basic-languages/php/php.js +0 -10
- package/assets/lib/vs/basic-languages/pla/pla.js +0 -10
- package/assets/lib/vs/basic-languages/postiats/postiats.js +0 -10
- package/assets/lib/vs/basic-languages/powerquery/powerquery.js +0 -10
- package/assets/lib/vs/basic-languages/powershell/powershell.js +0 -10
- package/assets/lib/vs/basic-languages/protobuf/protobuf.js +0 -11
- package/assets/lib/vs/basic-languages/pug/pug.js +0 -10
- package/assets/lib/vs/basic-languages/python/python.js +0 -10
- package/assets/lib/vs/basic-languages/qsharp/qsharp.js +0 -10
- package/assets/lib/vs/basic-languages/r/r.js +0 -10
- package/assets/lib/vs/basic-languages/razor/razor.js +0 -10
- package/assets/lib/vs/basic-languages/redis/redis.js +0 -10
- package/assets/lib/vs/basic-languages/redshift/redshift.js +0 -10
- package/assets/lib/vs/basic-languages/restructuredtext/restructuredtext.js +0 -10
- package/assets/lib/vs/basic-languages/ruby/ruby.js +0 -10
- package/assets/lib/vs/basic-languages/rust/rust.js +0 -10
- package/assets/lib/vs/basic-languages/sb/sb.js +0 -10
- package/assets/lib/vs/basic-languages/scala/scala.js +0 -10
- package/assets/lib/vs/basic-languages/scheme/scheme.js +0 -10
- package/assets/lib/vs/basic-languages/scss/scss.js +0 -12
- package/assets/lib/vs/basic-languages/shell/shell.js +0 -10
- package/assets/lib/vs/basic-languages/solidity/solidity.js +0 -10
- package/assets/lib/vs/basic-languages/sophia/sophia.js +0 -10
- package/assets/lib/vs/basic-languages/sparql/sparql.js +0 -10
- package/assets/lib/vs/basic-languages/sql/sql.js +0 -10
- package/assets/lib/vs/basic-languages/st/st.js +0 -10
- package/assets/lib/vs/basic-languages/swift/swift.js +0 -13
- package/assets/lib/vs/basic-languages/systemverilog/systemverilog.js +0 -10
- package/assets/lib/vs/basic-languages/tcl/tcl.js +0 -10
- package/assets/lib/vs/basic-languages/twig/twig.js +0 -10
- package/assets/lib/vs/basic-languages/typescript/typescript.js +0 -10
- package/assets/lib/vs/basic-languages/vb/vb.js +0 -10
- package/assets/lib/vs/basic-languages/wgsl/wgsl.js +0 -307
- package/assets/lib/vs/basic-languages/xml/xml.js +0 -10
- package/assets/lib/vs/basic-languages/yaml/yaml.js +0 -10
- package/assets/lib/vs/editor/editor.main.css +0 -6
- package/assets/lib/vs/editor/editor.main.js +0 -752
- package/assets/lib/vs/editor/editor.main.nls.de.js +0 -31
- package/assets/lib/vs/editor/editor.main.nls.es.js +0 -31
- package/assets/lib/vs/editor/editor.main.nls.fr.js +0 -29
- package/assets/lib/vs/editor/editor.main.nls.it.js +0 -29
- package/assets/lib/vs/editor/editor.main.nls.ja.js +0 -31
- package/assets/lib/vs/editor/editor.main.nls.js +0 -29
- package/assets/lib/vs/editor/editor.main.nls.ko.js +0 -29
- package/assets/lib/vs/editor/editor.main.nls.ru.js +0 -31
- package/assets/lib/vs/editor/editor.main.nls.zh-cn.js +0 -31
- package/assets/lib/vs/editor/editor.main.nls.zh-tw.js +0 -29
- package/assets/lib/vs/language/css/cssMode.js +0 -13
- package/assets/lib/vs/language/css/cssWorker.js +0 -81
- package/assets/lib/vs/language/html/htmlMode.js +0 -13
- package/assets/lib/vs/language/html/htmlWorker.js +0 -453
- package/assets/lib/vs/language/json/jsonMode.js +0 -15
- package/assets/lib/vs/language/json/jsonWorker.js +0 -36
- package/assets/lib/vs/language/typescript/tsMode.js +0 -20
- package/assets/lib/vs/language/typescript/tsWorker.js +0 -37016
- package/assets/lib/vs/loader.js +0 -11
- package/assets/mat-icons.ts +0 -5704
- package/assets/material/3d.svg +0 -1
- package/assets/material/abc.svg +0 -1
- package/assets/material/actionscript.svg +0 -1
- package/assets/material/ada.svg +0 -1
- package/assets/material/adonis.svg +0 -1
- package/assets/material/advpl_include.svg +0 -1
- package/assets/material/advpl_prw.svg +0 -1
- package/assets/material/advpl_ptm.svg +0 -1
- package/assets/material/advpl_tlpp.svg +0 -1
- package/assets/material/android.svg +0 -1
- package/assets/material/angular-component.svg +0 -1
- package/assets/material/angular-directive.svg +0 -1
- package/assets/material/angular-guard.svg +0 -1
- package/assets/material/angular-pipe.svg +0 -1
- package/assets/material/angular-resolver.svg +0 -1
- package/assets/material/angular-service.svg +0 -1
- package/assets/material/angular.svg +0 -1
- package/assets/material/antlr.svg +0 -1
- package/assets/material/apiblueprint.svg +0 -1
- package/assets/material/apollo.svg +0 -1
- package/assets/material/applescript.svg +0 -1
- package/assets/material/appveyor.svg +0 -1
- package/assets/material/architecture.svg +0 -1
- package/assets/material/arduino.svg +0 -1
- package/assets/material/asciidoc.svg +0 -1
- package/assets/material/assembly.svg +0 -1
- package/assets/material/astro.svg +0 -1
- package/assets/material/astyle.svg +0 -1
- package/assets/material/audio.svg +0 -1
- package/assets/material/aurelia.svg +0 -1
- package/assets/material/authors.svg +0 -1
- package/assets/material/auto.svg +0 -1
- package/assets/material/auto_light.svg +0 -1
- package/assets/material/autohotkey.svg +0 -1
- package/assets/material/autoit.svg +0 -1
- package/assets/material/azure-pipelines.svg +0 -1
- package/assets/material/azure.svg +0 -1
- package/assets/material/babel.svg +0 -1
- package/assets/material/ballerina.svg +0 -1
- package/assets/material/bazel.svg +0 -1
- package/assets/material/bicep.svg +0 -1
- package/assets/material/bitbucket.svg +0 -13
- package/assets/material/bithound.svg +0 -1
- package/assets/material/blink.svg +0 -1
- package/assets/material/blink_light.svg +0 -1
- package/assets/material/blitz.svg +0 -1
- package/assets/material/bower.svg +0 -1
- package/assets/material/brainfuck.svg +0 -1
- package/assets/material/browserlist.svg +0 -1
- package/assets/material/browserlist_light.svg +0 -1
- package/assets/material/buck.svg +0 -1
- package/assets/material/bucklescript.svg +0 -1
- package/assets/material/buildkite.svg +0 -1
- package/assets/material/bun.svg +0 -2
- package/assets/material/bun_light.svg +0 -2
- package/assets/material/c.svg +0 -4
- package/assets/material/cabal.svg +0 -1
- package/assets/material/caddy.svg +0 -1
- package/assets/material/cadence.svg +0 -1
- package/assets/material/cake.svg +0 -1
- package/assets/material/capacitor.svg +0 -1
- package/assets/material/certificate.svg +0 -1
- package/assets/material/changelog.svg +0 -1
- package/assets/material/chess.svg +0 -1
- package/assets/material/chess_light.svg +0 -1
- package/assets/material/circleci.svg +0 -1
- package/assets/material/circleci_light.svg +0 -1
- package/assets/material/clojure.svg +0 -1
- package/assets/material/cloudfoundry.svg +0 -1
- package/assets/material/cmake.svg +0 -1
- package/assets/material/coala.svg +0 -1
- package/assets/material/cobol.svg +0 -1
- package/assets/material/coconut.svg +0 -1
- package/assets/material/code-climate.svg +0 -1
- package/assets/material/code-climate_light.svg +0 -1
- package/assets/material/codecov.svg +0 -1
- package/assets/material/codeowners.svg +0 -1
- package/assets/material/coffee.svg +0 -1
- package/assets/material/coldfusion.svg +0 -1
- package/assets/material/command.svg +0 -1
- package/assets/material/commitlint.svg +0 -1
- package/assets/material/conduct.svg +0 -1
- package/assets/material/console.svg +0 -1
- package/assets/material/contributing.svg +0 -1
- package/assets/material/cpp.svg +0 -4
- package/assets/material/craco.svg +0 -45
- package/assets/material/credits.svg +0 -1
- package/assets/material/crystal.svg +0 -1
- package/assets/material/crystal_light.svg +0 -1
- package/assets/material/csharp.svg +0 -4
- package/assets/material/css-map.svg +0 -1
- package/assets/material/css.svg +0 -1
- package/assets/material/cucumber.svg +0 -1
- package/assets/material/cuda.svg +0 -1
- package/assets/material/cypress.svg +0 -1
- package/assets/material/d.svg +0 -1
- package/assets/material/dart.svg +0 -1
- package/assets/material/dart_generated.svg +0 -1
- package/assets/material/database.svg +0 -1
- package/assets/material/denizenscript.svg +0 -1
- package/assets/material/deno.svg +0 -1
- package/assets/material/deno_light.svg +0 -1
- package/assets/material/dependabot.svg +0 -1
- package/assets/material/dhall.svg +0 -1
- package/assets/material/diff.svg +0 -1
- package/assets/material/dinophp.svg +0 -1
- package/assets/material/disc.svg +0 -1
- package/assets/material/django.svg +0 -1
- package/assets/material/docker.svg +0 -1
- package/assets/material/document.svg +0 -1
- package/assets/material/dotjs.svg +0 -1
- package/assets/material/drawio.svg +0 -1
- package/assets/material/drone.svg +0 -1
- package/assets/material/drone_light.svg +0 -1
- package/assets/material/dune.svg +0 -1
- package/assets/material/edge.svg +0 -1
- package/assets/material/editorconfig.svg +0 -1
- package/assets/material/ejs.svg +0 -1
- package/assets/material/elixir.svg +0 -1
- package/assets/material/elm.svg +0 -1
- package/assets/material/email.svg +0 -1
- package/assets/material/ember.svg +0 -1
- package/assets/material/erlang.svg +0 -1
- package/assets/material/eslint.svg +0 -1
- package/assets/material/exe.svg +0 -1
- package/assets/material/fastlane.svg +0 -1
- package/assets/material/favicon.svg +0 -1
- package/assets/material/figma.svg +0 -1
- package/assets/material/file.svg +0 -1
- package/assets/material/firebase.svg +0 -1
- package/assets/material/flash.svg +0 -1
- package/assets/material/flow.svg +0 -1
- package/assets/material/folder-admin-open.svg +0 -1
- package/assets/material/folder-admin.svg +0 -1
- package/assets/material/folder-android-open.svg +0 -1
- package/assets/material/folder-android.svg +0 -1
- package/assets/material/folder-angular-open.svg +0 -1
- package/assets/material/folder-angular.svg +0 -1
- package/assets/material/folder-animation-open.svg +0 -1
- package/assets/material/folder-animation.svg +0 -1
- package/assets/material/folder-ansible-open.svg +0 -1
- package/assets/material/folder-ansible.svg +0 -1
- package/assets/material/folder-api-open.svg +0 -1
- package/assets/material/folder-api.svg +0 -1
- package/assets/material/folder-apollo-open.svg +0 -1
- package/assets/material/folder-apollo.svg +0 -1
- package/assets/material/folder-app-open.svg +0 -1
- package/assets/material/folder-app.svg +0 -1
- package/assets/material/folder-archive-open.svg +0 -1
- package/assets/material/folder-archive.svg +0 -1
- package/assets/material/folder-audio-open.svg +0 -1
- package/assets/material/folder-audio.svg +0 -1
- package/assets/material/folder-aurelia-open.svg +0 -1
- package/assets/material/folder-aurelia.svg +0 -1
- package/assets/material/folder-aws-open.svg +0 -1
- package/assets/material/folder-aws.svg +0 -1
- package/assets/material/folder-azure-pipelines-open.svg +0 -1
- package/assets/material/folder-azure-pipelines.svg +0 -1
- package/assets/material/folder-base-open.svg +0 -1
- package/assets/material/folder-base.svg +0 -1
- package/assets/material/folder-batch-open.svg +0 -1
- package/assets/material/folder-batch.svg +0 -1
- package/assets/material/folder-benchmark-open.svg +0 -1
- package/assets/material/folder-benchmark.svg +0 -1
- package/assets/material/folder-bower-open.svg +0 -1
- package/assets/material/folder-bower.svg +0 -1
- package/assets/material/folder-buildkite-open.svg +0 -1
- package/assets/material/folder-buildkite.svg +0 -1
- package/assets/material/folder-cart-open.svg +0 -1
- package/assets/material/folder-cart.svg +0 -1
- package/assets/material/folder-changesets-open.svg +0 -5
- package/assets/material/folder-changesets.svg +0 -2
- package/assets/material/folder-ci-open.svg +0 -1
- package/assets/material/folder-ci.svg +0 -1
- package/assets/material/folder-circleci-open.svg +0 -1
- package/assets/material/folder-circleci.svg +0 -1
- package/assets/material/folder-class-open.svg +0 -1
- package/assets/material/folder-class.svg +0 -1
- package/assets/material/folder-client-open.svg +0 -1
- package/assets/material/folder-client.svg +0 -1
- package/assets/material/folder-cluster-open.svg +0 -1
- package/assets/material/folder-cluster.svg +0 -1
- package/assets/material/folder-cobol-open.svg +0 -1
- package/assets/material/folder-cobol.svg +0 -1
- package/assets/material/folder-command-open.svg +0 -1
- package/assets/material/folder-command.svg +0 -1
- package/assets/material/folder-components-open.svg +0 -1
- package/assets/material/folder-components.svg +0 -1
- package/assets/material/folder-config-open.svg +0 -1
- package/assets/material/folder-config.svg +0 -1
- package/assets/material/folder-connection-open.svg +0 -1
- package/assets/material/folder-connection.svg +0 -1
- package/assets/material/folder-constant-open.svg +0 -1
- package/assets/material/folder-constant.svg +0 -1
- package/assets/material/folder-container-open.svg +0 -1
- package/assets/material/folder-container.svg +0 -1
- package/assets/material/folder-content-open.svg +0 -1
- package/assets/material/folder-content.svg +0 -1
- package/assets/material/folder-context-open.svg +0 -1
- package/assets/material/folder-context.svg +0 -1
- package/assets/material/folder-contract-open.svg +0 -1
- package/assets/material/folder-contract.svg +0 -1
- package/assets/material/folder-controller-open.svg +0 -1
- package/assets/material/folder-controller.svg +0 -1
- package/assets/material/folder-core-open.svg +0 -1
- package/assets/material/folder-core.svg +0 -1
- package/assets/material/folder-coverage-open.svg +0 -1
- package/assets/material/folder-coverage.svg +0 -1
- package/assets/material/folder-css-open.svg +0 -1
- package/assets/material/folder-css.svg +0 -1
- package/assets/material/folder-custom-open.svg +0 -1
- package/assets/material/folder-custom.svg +0 -1
- package/assets/material/folder-cypress-open.svg +0 -1
- package/assets/material/folder-cypress.svg +0 -1
- package/assets/material/folder-database-open.svg +0 -1
- package/assets/material/folder-database.svg +0 -1
- package/assets/material/folder-debug-open.svg +0 -1
- package/assets/material/folder-debug.svg +0 -1
- package/assets/material/folder-decorators-open.svg +0 -2
- package/assets/material/folder-decorators.svg +0 -5
- package/assets/material/folder-delta-open.svg +0 -1
- package/assets/material/folder-delta.svg +0 -1
- package/assets/material/folder-dist-open.svg +0 -1
- package/assets/material/folder-dist.svg +0 -1
- package/assets/material/folder-docker-open.svg +0 -1
- package/assets/material/folder-docker.svg +0 -1
- package/assets/material/folder-docs-open.svg +0 -1
- package/assets/material/folder-docs.svg +0 -1
- package/assets/material/folder-download-open.svg +0 -1
- package/assets/material/folder-download.svg +0 -1
- package/assets/material/folder-dump-open.svg +0 -1
- package/assets/material/folder-dump.svg +0 -1
- package/assets/material/folder-environment-open.svg +0 -1
- package/assets/material/folder-environment.svg +0 -1
- package/assets/material/folder-error-open.svg +0 -1
- package/assets/material/folder-error.svg +0 -1
- package/assets/material/folder-event-open.svg +0 -1
- package/assets/material/folder-event.svg +0 -1
- package/assets/material/folder-examples-open.svg +0 -1
- package/assets/material/folder-examples.svg +0 -1
- package/assets/material/folder-expo-open.svg +0 -1
- package/assets/material/folder-expo.svg +0 -1
- package/assets/material/folder-export-open.svg +0 -1
- package/assets/material/folder-export.svg +0 -1
- package/assets/material/folder-fastlane-open.svg +0 -1
- package/assets/material/folder-fastlane.svg +0 -1
- package/assets/material/folder-firebase-open.svg +0 -1
- package/assets/material/folder-firebase.svg +0 -1
- package/assets/material/folder-flow-open.svg +0 -1
- package/assets/material/folder-flow.svg +0 -1
- package/assets/material/folder-font-open.svg +0 -1
- package/assets/material/folder-font.svg +0 -1
- package/assets/material/folder-functions-open.svg +0 -1
- package/assets/material/folder-functions.svg +0 -1
- package/assets/material/folder-gamemaker-open.svg +0 -2
- package/assets/material/folder-gamemaker.svg +0 -2
- package/assets/material/folder-generator-open.svg +0 -1
- package/assets/material/folder-generator.svg +0 -1
- package/assets/material/folder-git-open.svg +0 -1
- package/assets/material/folder-git.svg +0 -1
- package/assets/material/folder-github-open.svg +0 -1
- package/assets/material/folder-github.svg +0 -1
- package/assets/material/folder-gitlab-open.svg +0 -1
- package/assets/material/folder-gitlab.svg +0 -1
- package/assets/material/folder-global-open.svg +0 -1
- package/assets/material/folder-global.svg +0 -1
- package/assets/material/folder-godot-open.svg +0 -2
- package/assets/material/folder-godot.svg +0 -8
- package/assets/material/folder-gradle-open.svg +0 -1
- package/assets/material/folder-gradle.svg +0 -1
- package/assets/material/folder-graphql-open.svg +0 -1
- package/assets/material/folder-graphql.svg +0 -1
- package/assets/material/folder-guard-open.svg +0 -1
- package/assets/material/folder-guard.svg +0 -1
- package/assets/material/folder-gulp-open.svg +0 -1
- package/assets/material/folder-gulp.svg +0 -1
- package/assets/material/folder-helper-open.svg +0 -1
- package/assets/material/folder-helper.svg +0 -1
- package/assets/material/folder-home-open.svg +0 -1
- package/assets/material/folder-home.svg +0 -1
- package/assets/material/folder-hook-open.svg +0 -1
- package/assets/material/folder-hook.svg +0 -1
- package/assets/material/folder-husky-open.svg +0 -1
- package/assets/material/folder-husky.svg +0 -1
- package/assets/material/folder-i18n-open.svg +0 -1
- package/assets/material/folder-i18n.svg +0 -1
- package/assets/material/folder-images-open.svg +0 -1
- package/assets/material/folder-images.svg +0 -1
- package/assets/material/folder-import-open.svg +0 -1
- package/assets/material/folder-import.svg +0 -1
- package/assets/material/folder-include-open.svg +0 -1
- package/assets/material/folder-include.svg +0 -1
- package/assets/material/folder-intellij-open.svg +0 -1
- package/assets/material/folder-intellij-open_light.svg +0 -1
- package/assets/material/folder-intellij.svg +0 -1
- package/assets/material/folder-intellij_light.svg +0 -1
- package/assets/material/folder-interface-open.svg +0 -1
- package/assets/material/folder-interface.svg +0 -1
- package/assets/material/folder-ios-open.svg +0 -1
- package/assets/material/folder-ios.svg +0 -1
- package/assets/material/folder-java-open.svg +0 -1
- package/assets/material/folder-java.svg +0 -1
- package/assets/material/folder-javascript-open.svg +0 -1
- package/assets/material/folder-javascript.svg +0 -1
- package/assets/material/folder-jinja-open.svg +0 -1
- package/assets/material/folder-jinja-open_light.svg +0 -1
- package/assets/material/folder-jinja.svg +0 -1
- package/assets/material/folder-jinja_light.svg +0 -1
- package/assets/material/folder-job-open.svg +0 -1
- package/assets/material/folder-job.svg +0 -1
- package/assets/material/folder-json-open.svg +0 -1
- package/assets/material/folder-json.svg +0 -1
- package/assets/material/folder-keys-open.svg +0 -1
- package/assets/material/folder-keys.svg +0 -1
- package/assets/material/folder-kubernetes-open.svg +0 -1
- package/assets/material/folder-kubernetes.svg +0 -1
- package/assets/material/folder-layout-open.svg +0 -1
- package/assets/material/folder-layout.svg +0 -1
- package/assets/material/folder-less-open.svg +0 -1
- package/assets/material/folder-less.svg +0 -1
- package/assets/material/folder-lib-open.svg +0 -1
- package/assets/material/folder-lib.svg +0 -1
- package/assets/material/folder-log-open.svg +0 -1
- package/assets/material/folder-log.svg +0 -1
- package/assets/material/folder-lua-open.svg +0 -1
- package/assets/material/folder-lua.svg +0 -1
- package/assets/material/folder-mail-open.svg +0 -1
- package/assets/material/folder-mail.svg +0 -1
- package/assets/material/folder-mappings-open.svg +0 -1
- package/assets/material/folder-mappings.svg +0 -1
- package/assets/material/folder-markdown-open.svg +0 -1
- package/assets/material/folder-markdown.svg +0 -1
- package/assets/material/folder-mercurial-open.svg +0 -5
- package/assets/material/folder-mercurial.svg +0 -2
- package/assets/material/folder-messages-open.svg +0 -1
- package/assets/material/folder-messages.svg +0 -1
- package/assets/material/folder-meta-open.svg +0 -1
- package/assets/material/folder-meta.svg +0 -1
- package/assets/material/folder-middleware-open.svg +0 -1
- package/assets/material/folder-middleware.svg +0 -1
- package/assets/material/folder-mjml-open.svg +0 -1
- package/assets/material/folder-mjml.svg +0 -1
- package/assets/material/folder-mobile-open.svg +0 -1
- package/assets/material/folder-mobile.svg +0 -1
- package/assets/material/folder-mock-open.svg +0 -1
- package/assets/material/folder-mock.svg +0 -1
- package/assets/material/folder-netlify-open.svg +0 -5
- package/assets/material/folder-netlify.svg +0 -2
- package/assets/material/folder-next-open.svg +0 -1
- package/assets/material/folder-next.svg +0 -1
- package/assets/material/folder-ngrx-actions-open.svg +0 -1
- package/assets/material/folder-ngrx-actions.svg +0 -1
- package/assets/material/folder-ngrx-effects-open.svg +0 -1
- package/assets/material/folder-ngrx-effects.svg +0 -1
- package/assets/material/folder-ngrx-entities-open.svg +0 -1
- package/assets/material/folder-ngrx-entities.svg +0 -1
- package/assets/material/folder-ngrx-reducer-open.svg +0 -1
- package/assets/material/folder-ngrx-reducer.svg +0 -1
- package/assets/material/folder-ngrx-selectors-open.svg +0 -1
- package/assets/material/folder-ngrx-selectors.svg +0 -1
- package/assets/material/folder-ngrx-state-open.svg +0 -1
- package/assets/material/folder-ngrx-state.svg +0 -1
- package/assets/material/folder-ngrx-store-open.svg +0 -1
- package/assets/material/folder-ngrx-store.svg +0 -1
- package/assets/material/folder-node-open.svg +0 -1
- package/assets/material/folder-node.svg +0 -1
- package/assets/material/folder-nuxt-open.svg +0 -1
- package/assets/material/folder-nuxt.svg +0 -1
- package/assets/material/folder-open.svg +0 -1
- package/assets/material/folder-other-open.svg +0 -1
- package/assets/material/folder-other.svg +0 -1
- package/assets/material/folder-packages-open.svg +0 -1
- package/assets/material/folder-packages.svg +0 -1
- package/assets/material/folder-pdf-open.svg +0 -1
- package/assets/material/folder-pdf.svg +0 -1
- package/assets/material/folder-php-open.svg +0 -1
- package/assets/material/folder-php.svg +0 -1
- package/assets/material/folder-phpmailer-open.svg +0 -1
- package/assets/material/folder-phpmailer.svg +0 -1
- package/assets/material/folder-pipe-open.svg +0 -1
- package/assets/material/folder-pipe.svg +0 -1
- package/assets/material/folder-plastic-open.svg +0 -8
- package/assets/material/folder-plastic.svg +0 -2
- package/assets/material/folder-plugin-open.svg +0 -1
- package/assets/material/folder-plugin.svg +0 -1
- package/assets/material/folder-prisma-open.svg +0 -1
- package/assets/material/folder-prisma.svg +0 -1
- package/assets/material/folder-private-open.svg +0 -1
- package/assets/material/folder-private.svg +0 -1
- package/assets/material/folder-project-open.svg +0 -1
- package/assets/material/folder-project.svg +0 -1
- package/assets/material/folder-proto-open.svg +0 -1
- package/assets/material/folder-proto.svg +0 -1
- package/assets/material/folder-public-open.svg +0 -1
- package/assets/material/folder-public.svg +0 -1
- package/assets/material/folder-python-open.svg +0 -1
- package/assets/material/folder-python.svg +0 -1
- package/assets/material/folder-quasar-open.svg +0 -1
- package/assets/material/folder-quasar.svg +0 -1
- package/assets/material/folder-queue-open.svg +0 -1
- package/assets/material/folder-queue.svg +0 -1
- package/assets/material/folder-react-components-open.svg +0 -1
- package/assets/material/folder-react-components.svg +0 -1
- package/assets/material/folder-redux-actions-open.svg +0 -1
- package/assets/material/folder-redux-actions.svg +0 -1
- package/assets/material/folder-redux-reducer-open.svg +0 -1
- package/assets/material/folder-redux-reducer.svg +0 -1
- package/assets/material/folder-redux-selector-open.svg +0 -1
- package/assets/material/folder-redux-selector.svg +0 -1
- package/assets/material/folder-redux-store-open.svg +0 -1
- package/assets/material/folder-redux-store.svg +0 -1
- package/assets/material/folder-resolver-open.svg +0 -1
- package/assets/material/folder-resolver.svg +0 -1
- package/assets/material/folder-resource-open.svg +0 -1
- package/assets/material/folder-resource.svg +0 -1
- package/assets/material/folder-review-open.svg +0 -1
- package/assets/material/folder-review.svg +0 -1
- package/assets/material/folder-root-open.svg +0 -1
- package/assets/material/folder-root.svg +0 -1
- package/assets/material/folder-routes-open.svg +0 -1
- package/assets/material/folder-routes.svg +0 -1
- package/assets/material/folder-rules-open.svg +0 -1
- package/assets/material/folder-rules.svg +0 -1
- package/assets/material/folder-sass-open.svg +0 -1
- package/assets/material/folder-sass.svg +0 -1
- package/assets/material/folder-scala-open.svg +0 -1
- package/assets/material/folder-scala.svg +0 -1
- package/assets/material/folder-scripts-open.svg +0 -1
- package/assets/material/folder-scripts.svg +0 -1
- package/assets/material/folder-secure-open.svg +0 -1
- package/assets/material/folder-secure.svg +0 -1
- package/assets/material/folder-server-open.svg +0 -1
- package/assets/material/folder-server.svg +0 -1
- package/assets/material/folder-serverless-open.svg +0 -1
- package/assets/material/folder-serverless.svg +0 -1
- package/assets/material/folder-shader-open.svg +0 -1
- package/assets/material/folder-shader.svg +0 -1
- package/assets/material/folder-shared-open.svg +0 -1
- package/assets/material/folder-shared.svg +0 -1
- package/assets/material/folder-src-open.svg +0 -1
- package/assets/material/folder-src.svg +0 -1
- package/assets/material/folder-stack-open.svg +0 -1
- package/assets/material/folder-stack.svg +0 -1
- package/assets/material/folder-stencil-open.svg +0 -1
- package/assets/material/folder-stencil.svg +0 -1
- package/assets/material/folder-storybook-open.svg +0 -1
- package/assets/material/folder-storybook.svg +0 -1
- package/assets/material/folder-stylus-open.svg +0 -1
- package/assets/material/folder-stylus.svg +0 -1
- package/assets/material/folder-sublime-open.svg +0 -1
- package/assets/material/folder-sublime.svg +0 -1
- package/assets/material/folder-supabase-open.svg +0 -5
- package/assets/material/folder-supabase.svg +0 -2
- package/assets/material/folder-svelte-open.svg +0 -1
- package/assets/material/folder-svelte.svg +0 -1
- package/assets/material/folder-svg-open.svg +0 -1
- package/assets/material/folder-svg.svg +0 -1
- package/assets/material/folder-syntax-open.svg +0 -1
- package/assets/material/folder-syntax.svg +0 -1
- package/assets/material/folder-target-open.svg +0 -1
- package/assets/material/folder-target.svg +0 -1
- package/assets/material/folder-tasks-open.svg +0 -1
- package/assets/material/folder-tasks.svg +0 -1
- package/assets/material/folder-temp-open.svg +0 -1
- package/assets/material/folder-temp.svg +0 -1
- package/assets/material/folder-template-open.svg +0 -1
- package/assets/material/folder-template.svg +0 -1
- package/assets/material/folder-terraform-open.svg +0 -1
- package/assets/material/folder-terraform.svg +0 -1
- package/assets/material/folder-test-open.svg +0 -1
- package/assets/material/folder-test.svg +0 -1
- package/assets/material/folder-theme-open.svg +0 -1
- package/assets/material/folder-theme.svg +0 -1
- package/assets/material/folder-tools-open.svg +0 -1
- package/assets/material/folder-tools.svg +0 -1
- package/assets/material/folder-typescript-open.svg +0 -1
- package/assets/material/folder-typescript.svg +0 -1
- package/assets/material/folder-unity-open.svg +0 -1
- package/assets/material/folder-unity.svg +0 -1
- package/assets/material/folder-update-open.svg +0 -1
- package/assets/material/folder-update.svg +0 -1
- package/assets/material/folder-upload-open.svg +0 -1
- package/assets/material/folder-upload.svg +0 -1
- package/assets/material/folder-utils-open.svg +0 -1
- package/assets/material/folder-utils.svg +0 -1
- package/assets/material/folder-vercel-open.svg +0 -1
- package/assets/material/folder-vercel.svg +0 -1
- package/assets/material/folder-verdaccio-open.svg +0 -1
- package/assets/material/folder-verdaccio.svg +0 -1
- package/assets/material/folder-video-open.svg +0 -1
- package/assets/material/folder-video.svg +0 -1
- package/assets/material/folder-views-open.svg +0 -1
- package/assets/material/folder-views.svg +0 -1
- package/assets/material/folder-vm-open.svg +0 -1
- package/assets/material/folder-vm.svg +0 -1
- package/assets/material/folder-vscode-open.svg +0 -1
- package/assets/material/folder-vscode.svg +0 -1
- package/assets/material/folder-vue-directives-open.svg +0 -1
- package/assets/material/folder-vue-directives.svg +0 -1
- package/assets/material/folder-vue-open.svg +0 -1
- package/assets/material/folder-vue.svg +0 -1
- package/assets/material/folder-vuepress-open.svg +0 -1
- package/assets/material/folder-vuepress.svg +0 -1
- package/assets/material/folder-vuex-store-open.svg +0 -1
- package/assets/material/folder-vuex-store.svg +0 -1
- package/assets/material/folder-wakatime-open.svg +0 -1
- package/assets/material/folder-wakatime.svg +0 -1
- package/assets/material/folder-webpack-open.svg +0 -1
- package/assets/material/folder-webpack.svg +0 -1
- package/assets/material/folder-wordpress-open.svg +0 -1
- package/assets/material/folder-wordpress.svg +0 -1
- package/assets/material/folder-yarn-open.svg +0 -1
- package/assets/material/folder-yarn.svg +0 -1
- package/assets/material/folder.svg +0 -1
- package/assets/material/font.svg +0 -1
- package/assets/material/forth.svg +0 -1
- package/assets/material/fortran.svg +0 -1
- package/assets/material/foxpro.svg +0 -1
- package/assets/material/fsharp.svg +0 -1
- package/assets/material/fusebox.svg +0 -1
- package/assets/material/gamemaker.svg +0 -4
- package/assets/material/gatsby.svg +0 -1
- package/assets/material/gcp.svg +0 -1
- package/assets/material/gemfile.svg +0 -1
- package/assets/material/gemini.svg +0 -1
- package/assets/material/git.svg +0 -1
- package/assets/material/gitlab.svg +0 -1
- package/assets/material/gitpod.svg +0 -1
- package/assets/material/gleam.svg +0 -1
- package/assets/material/go-mod.svg +0 -1
- package/assets/material/go.svg +0 -1
- package/assets/material/go_gopher.svg +0 -1
- package/assets/material/godot-assets.svg +0 -7
- package/assets/material/godot.svg +0 -7
- package/assets/material/gradle.svg +0 -1
- package/assets/material/grain.svg +0 -1
- package/assets/material/graphcool.svg +0 -1
- package/assets/material/graphql.svg +0 -1
- package/assets/material/gridsome.svg +0 -1
- package/assets/material/groovy.svg +0 -1
- package/assets/material/grunt.svg +0 -1
- package/assets/material/gulp.svg +0 -1
- package/assets/material/h.svg +0 -1
- package/assets/material/hack.svg +0 -1
- package/assets/material/haml.svg +0 -1
- package/assets/material/handlebars.svg +0 -1
- package/assets/material/hardhat.svg +0 -1
- package/assets/material/haskell.svg +0 -1
- package/assets/material/haxe.svg +0 -1
- package/assets/material/hcl.svg +0 -1
- package/assets/material/hcl_light.svg +0 -1
- package/assets/material/helm.svg +0 -1
- package/assets/material/heroku.svg +0 -1
- package/assets/material/hex.svg +0 -1
- package/assets/material/horusec.svg +0 -1
- package/assets/material/hpp.svg +0 -1
- package/assets/material/html.svg +0 -1
- package/assets/material/http.svg +0 -1
- package/assets/material/husky.svg +0 -1
- package/assets/material/i18n.svg +0 -1
- package/assets/material/idris.svg +0 -1
- package/assets/material/ifanr-cloud.svg +0 -10
- package/assets/material/image.svg +0 -1
- package/assets/material/imba.svg +0 -1
- package/assets/material/ionic.svg +0 -1
- package/assets/material/istanbul.svg +0 -1
- package/assets/material/jar.svg +0 -1
- package/assets/material/java.svg +0 -1
- package/assets/material/javaclass.svg +0 -1
- package/assets/material/javascript-map.svg +0 -1
- package/assets/material/javascript.svg +0 -1
- package/assets/material/jenkins.svg +0 -1
- package/assets/material/jest.svg +0 -1
- package/assets/material/jinja.svg +0 -1
- package/assets/material/jinja_light.svg +0 -1
- package/assets/material/jsconfig.svg +0 -1
- package/assets/material/json.svg +0 -1
- package/assets/material/julia.svg +0 -1
- package/assets/material/jupyter.svg +0 -1
- package/assets/material/karma.svg +0 -1
- package/assets/material/key.svg +0 -1
- package/assets/material/kivy.svg +0 -1
- package/assets/material/kl.svg +0 -1
- package/assets/material/kotlin.svg +0 -1
- package/assets/material/kusto.svg +0 -1
- package/assets/material/laravel.svg +0 -1
- package/assets/material/lerna.svg +0 -1
- package/assets/material/less.svg +0 -1
- package/assets/material/lib.svg +0 -1
- package/assets/material/lighthouse.svg +0 -1
- package/assets/material/lilypond.svg +0 -1
- package/assets/material/liquid.svg +0 -1
- package/assets/material/lisp.svg +0 -1
- package/assets/material/livescript.svg +0 -1
- package/assets/material/lock.svg +0 -1
- package/assets/material/log.svg +0 -1
- package/assets/material/lolcode.svg +0 -1
- package/assets/material/lua.svg +0 -1
- package/assets/material/makefile.svg +0 -1
- package/assets/material/markdown.svg +0 -1
- package/assets/material/markojs.svg +0 -1
- package/assets/material/mathematica.svg +0 -1
- package/assets/material/matlab.svg +0 -1
- package/assets/material/maven.svg +0 -1
- package/assets/material/mdsvex.svg +0 -1
- package/assets/material/mdx.svg +0 -1
- package/assets/material/mercurial.svg +0 -6
- package/assets/material/merlin.svg +0 -1
- package/assets/material/mermaid.svg +0 -4
- package/assets/material/meson.svg +0 -1
- package/assets/material/minecraft.svg +0 -1
- package/assets/material/mint.svg +0 -1
- package/assets/material/mjml.svg +0 -1
- package/assets/material/mocha.svg +0 -1
- package/assets/material/modernizr.svg +0 -1
- package/assets/material/moonscript.svg +0 -1
- package/assets/material/mxml.svg +0 -1
- package/assets/material/nano-staged.svg +0 -1
- package/assets/material/nano-staged_light.svg +0 -1
- package/assets/material/ndst.svg +0 -1
- package/assets/material/nest-controller.svg +0 -1
- package/assets/material/nest-decorator.svg +0 -1
- package/assets/material/nest-filter.svg +0 -1
- package/assets/material/nest-gateway.svg +0 -1
- package/assets/material/nest-guard.svg +0 -1
- package/assets/material/nest-middleware.svg +0 -1
- package/assets/material/nest-module.svg +0 -1
- package/assets/material/nest-pipe.svg +0 -1
- package/assets/material/nest-resolver.svg +0 -1
- package/assets/material/nest-service.svg +0 -1
- package/assets/material/nest.svg +0 -1
- package/assets/material/netlify.svg +0 -7
- package/assets/material/netlify_light.svg +0 -7
- package/assets/material/next.svg +0 -1
- package/assets/material/next_light.svg +0 -1
- package/assets/material/nginx.svg +0 -1
- package/assets/material/ngrx-actions.svg +0 -1
- package/assets/material/ngrx-effects.svg +0 -1
- package/assets/material/ngrx-entity.svg +0 -1
- package/assets/material/ngrx-reducer.svg +0 -1
- package/assets/material/ngrx-selectors.svg +0 -1
- package/assets/material/ngrx-state.svg +0 -1
- package/assets/material/nim.svg +0 -1
- package/assets/material/nix.svg +0 -1
- package/assets/material/nodejs.svg +0 -1
- package/assets/material/nodejs_alt.svg +0 -1
- package/assets/material/nodemon.svg +0 -1
- package/assets/material/npm.svg +0 -1
- package/assets/material/nrwl.svg +0 -1
- package/assets/material/nuget.svg +0 -1
- package/assets/material/nunjucks.svg +0 -1
- package/assets/material/nuxt.svg +0 -1
- package/assets/material/objective-c.svg +0 -4
- package/assets/material/objective-cpp.svg +0 -1
- package/assets/material/ocaml.svg +0 -1
- package/assets/material/odin.svg +0 -1
- package/assets/material/opa.svg +0 -1
- package/assets/material/opam.svg +0 -1
- package/assets/material/otne.svg +0 -1
- package/assets/material/parcel.svg +0 -1
- package/assets/material/pascal.svg +0 -6
- package/assets/material/pawn.svg +0 -1
- package/assets/material/pdf.svg +0 -1
- package/assets/material/percy.svg +0 -1
- package/assets/material/perl.svg +0 -1
- package/assets/material/php-cs-fixer.svg +0 -1
- package/assets/material/php.svg +0 -1
- package/assets/material/php_elephant.svg +0 -1
- package/assets/material/php_elephant_pink.svg +0 -1
- package/assets/material/phpunit.svg +0 -1
- package/assets/material/pinejs.svg +0 -1
- package/assets/material/pipeline.svg +0 -1
- package/assets/material/plastic.svg +0 -7
- package/assets/material/playwright.svg +0 -1
- package/assets/material/plop.svg +0 -1
- package/assets/material/pnpm.svg +0 -1
- package/assets/material/pnpm_light.svg +0 -1
- package/assets/material/poetry.svg +0 -1
- package/assets/material/postcss.svg +0 -1
- package/assets/material/posthtml.svg +0 -1
- package/assets/material/powerpoint.svg +0 -1
- package/assets/material/powershell.svg +0 -1
- package/assets/material/prettier.svg +0 -1
- package/assets/material/prisma.svg +0 -1
- package/assets/material/processing.svg +0 -1
- package/assets/material/prolog.svg +0 -1
- package/assets/material/proto.svg +0 -1
- package/assets/material/protractor.svg +0 -1
- package/assets/material/pug.svg +0 -1
- package/assets/material/puppet.svg +0 -1
- package/assets/material/purescript.svg +0 -1
- package/assets/material/python-misc.svg +0 -1
- package/assets/material/python.svg +0 -1
- package/assets/material/qsharp.svg +0 -1
- package/assets/material/quasar.svg +0 -1
- package/assets/material/qwik.svg +0 -2
- package/assets/material/r.svg +0 -1
- package/assets/material/racket.svg +0 -1
- package/assets/material/raml.svg +0 -1
- package/assets/material/razor.svg +0 -1
- package/assets/material/rc.svg +0 -2
- package/assets/material/react.svg +0 -1
- package/assets/material/react_ts.svg +0 -1
- package/assets/material/readme.svg +0 -1
- package/assets/material/reason.svg +0 -1
- package/assets/material/red.svg +0 -1
- package/assets/material/redux-action.svg +0 -1
- package/assets/material/redux-reducer.svg +0 -1
- package/assets/material/redux-selector.svg +0 -1
- package/assets/material/redux-store.svg +0 -1
- package/assets/material/remix.svg +0 -1
- package/assets/material/remix_light.svg +0 -1
- package/assets/material/renovate.svg +0 -1
- package/assets/material/replit.svg +0 -1
- package/assets/material/rescript-interface.svg +0 -1
- package/assets/material/rescript.svg +0 -1
- package/assets/material/restql.svg +0 -1
- package/assets/material/riot.svg +0 -1
- package/assets/material/roadmap.svg +0 -1
- package/assets/material/robot.svg +0 -1
- package/assets/material/robots.svg +0 -1
- package/assets/material/rollup.svg +0 -1
- package/assets/material/rome.svg +0 -1
- package/assets/material/routing.svg +0 -1
- package/assets/material/rubocop.svg +0 -1
- package/assets/material/rubocop_light.svg +0 -1
- package/assets/material/ruby.svg +0 -1
- package/assets/material/rust.svg +0 -1
- package/assets/material/salesforce.svg +0 -1
- package/assets/material/san.svg +0 -1
- package/assets/material/sas.svg +0 -1
- package/assets/material/sass.svg +0 -1
- package/assets/material/sbt.svg +0 -1
- package/assets/material/scala.svg +0 -1
- package/assets/material/scheme.svg +0 -1
- package/assets/material/search.svg +0 -1
- package/assets/material/semantic-release.svg +0 -1
- package/assets/material/semantic-release_light.svg +0 -1
- package/assets/material/sentry.svg +0 -1
- package/assets/material/sequelize.svg +0 -1
- package/assets/material/serverless.svg +0 -1
- package/assets/material/settings.svg +0 -1
- package/assets/material/shader.svg +0 -1
- package/assets/material/shaderlab.svg +0 -1
- package/assets/material/silverstripe.svg +0 -1
- package/assets/material/siyuan.svg +0 -1
- package/assets/material/sketch.svg +0 -1
- package/assets/material/slim.svg +0 -1
- package/assets/material/slug.svg +0 -1
- package/assets/material/smarty.svg +0 -1
- package/assets/material/sml.svg +0 -1
- package/assets/material/snowpack.svg +0 -1
- package/assets/material/snowpack_light.svg +0 -1
- package/assets/material/snyk.svg +0 -1
- package/assets/material/solidity.svg +0 -1
- package/assets/material/sonarcloud.svg +0 -4
- package/assets/material/steadybit.svg +0 -1
- package/assets/material/stencil.svg +0 -1
- package/assets/material/stitches.svg +0 -1
- package/assets/material/stitches_light.svg +0 -1
- package/assets/material/storybook.svg +0 -1
- package/assets/material/stryker.svg +0 -1
- package/assets/material/stylable.svg +0 -10
- package/assets/material/stylelint.svg +0 -1
- package/assets/material/stylelint_light.svg +0 -1
- package/assets/material/stylus.svg +0 -1
- package/assets/material/sublime.svg +0 -1
- package/assets/material/supabase.svg +0 -4
- package/assets/material/svelte.svg +0 -1
- package/assets/material/svg.svg +0 -1
- package/assets/material/svgo.svg +0 -1
- package/assets/material/svgr.svg +0 -1
- package/assets/material/swc.svg +0 -1
- package/assets/material/swift.svg +0 -1
- package/assets/material/table.svg +0 -1
- package/assets/material/tailwindcss.svg +0 -1
- package/assets/material/tauri.svg +0 -1
- package/assets/material/tcl.svg +0 -1
- package/assets/material/teal.svg +0 -1
- package/assets/material/template.svg +0 -1
- package/assets/material/terraform.svg +0 -1
- package/assets/material/test-js.svg +0 -1
- package/assets/material/test-jsx.svg +0 -1
- package/assets/material/test-ts.svg +0 -1
- package/assets/material/tex.svg +0 -1
- package/assets/material/textlint.svg +0 -1
- package/assets/material/tilt.svg +0 -1
- package/assets/material/tldraw.svg +0 -4
- package/assets/material/tldraw_light.svg +0 -4
- package/assets/material/tobi.svg +0 -1
- package/assets/material/tobimake.svg +0 -1
- package/assets/material/todo.svg +0 -1
- package/assets/material/travis.svg +0 -1
- package/assets/material/tree.svg +0 -1
- package/assets/material/tsconfig.svg +0 -1
- package/assets/material/tune.svg +0 -1
- package/assets/material/turborepo.svg +0 -1
- package/assets/material/turborepo_light.svg +0 -1
- package/assets/material/twig.svg +0 -1
- package/assets/material/twine.svg +0 -1
- package/assets/material/typescript-def.svg +0 -1
- package/assets/material/typescript.svg +0 -1
- package/assets/material/typst.svg +0 -2
- package/assets/material/uml.svg +0 -1
- package/assets/material/uml_light.svg +0 -1
- package/assets/material/url.svg +0 -1
- package/assets/material/vagrant.svg +0 -1
- package/assets/material/vala.svg +0 -1
- package/assets/material/velocity.svg +0 -1
- package/assets/material/vercel.svg +0 -1
- package/assets/material/vercel_light.svg +0 -1
- package/assets/material/verdaccio.svg +0 -1
- package/assets/material/verilog.svg +0 -1
- package/assets/material/vfl.svg +0 -1
- package/assets/material/video.svg +0 -1
- package/assets/material/vim.svg +0 -1
- package/assets/material/virtual.svg +0 -1
- package/assets/material/visualstudio.svg +0 -1
- package/assets/material/vite.svg +0 -1
- package/assets/material/vitest.svg +0 -6
- package/assets/material/vlang.svg +0 -1
- package/assets/material/vscode.svg +0 -1
- package/assets/material/vue-config.svg +0 -1
- package/assets/material/vue.svg +0 -1
- package/assets/material/vuex-store.svg +0 -1
- package/assets/material/wakatime.svg +0 -1
- package/assets/material/wakatime_light.svg +0 -1
- package/assets/material/wallaby.svg +0 -1
- package/assets/material/watchman.svg +0 -1
- package/assets/material/webassembly.svg +0 -1
- package/assets/material/webhint.svg +0 -1
- package/assets/material/webpack.svg +0 -1
- package/assets/material/wepy.svg +0 -1
- package/assets/material/windicss.svg +0 -1
- package/assets/material/wolframlanguage.svg +0 -1
- package/assets/material/word.svg +0 -1
- package/assets/material/xaml.svg +0 -1
- package/assets/material/xml.svg +0 -1
- package/assets/material/yaml.svg +0 -1
- package/assets/material/yang.svg +0 -1
- package/assets/material/yarn.svg +0 -1
- package/assets/material/zig.svg +0 -1
- package/assets/material/zip.svg +0 -1
- package/assets/pop/LICENSE +0 -2
- package/assets/pop/binary.svg +0 -1
- package/assets/pop/compressed.svg +0 -1
- package/assets/pop/database.svg +0 -1
- package/assets/pop/exts/7z.svg +0 -1
- package/assets/pop/exts/apk.svg +0 -1
- package/assets/pop/exts/arc.svg +0 -1
- package/assets/pop/exts/bz.svg +0 -1
- package/assets/pop/exts/deb.svg +0 -1
- package/assets/pop/exts/gz.svg +0 -1
- package/assets/pop/exts/pdf.svg +0 -1
- package/assets/pop/exts/rar.svg +0 -1
- package/assets/pop/exts/rpm.svg +0 -1
- package/assets/pop/exts/tar.svg +0 -1
- package/assets/pop/exts/xar.svg +0 -1
- package/assets/pop/exts/xz.svg +0 -1
- package/assets/pop/exts/zip.svg +0 -1
- package/assets/pop/folder-open.svg +0 -1
- package/assets/pop/folder.svg +0 -1
- package/assets/pop/generic.svg +0 -1
- package/assets/pop/presentation.svg +0 -1
- package/assets/pop/richtext.svg +0 -1
- package/assets/pop/spreadsheet.svg +0 -1
- package/assets/pop/text.svg +0 -1
- package/esm2022/components/lazy-loader/lazy-loader.component.mjs +0 -383
- package/esm2022/components/lazy-loader/lazy-loader.module.mjs +0 -33
- package/esm2022/components/lazy-loader/lazy-loader.service.mjs +0 -217
- package/esm2022/components/lazy-loader/types.mjs +0 -26
- package/esm2022/components/menu/menu.component.mjs +0 -433
- package/esm2022/components/parallax-card/parallax-card.component.mjs +0 -138
- package/esm2022/components/tooltip/tooltip.component.mjs +0 -205
- package/esm2022/components/types.mjs +0 -3
- package/esm2022/directives/image-cache.directive.mjs +0 -143
- package/esm2022/directives/menu.directive.mjs +0 -159
- package/esm2022/directives/tooltip.directive.mjs +0 -154
- package/esm2022/directives/utils.mjs +0 -120
- package/esm2022/pipes/html-bypass.pipe.mjs +0 -27
- package/esm2022/pipes/resource-bypass.pipe.mjs +0 -27
- package/esm2022/pipes/script-bypass.pipe.mjs +0 -27
- package/esm2022/pipes/style-bypass.pipe.mjs +0 -27
- package/esm2022/pipes/url-bypass.pipe.mjs +0 -27
- package/esm2022/public-api.mjs +0 -46
- package/esm2022/services/dependency.service.mjs +0 -55
- package/esm2022/services/dialog.service.mjs +0 -69
- package/esm2022/services/fetch.service.mjs +0 -74
- package/esm2022/services/file.service.mjs +0 -42
- package/esm2022/services/keyboard.service.mjs +0 -128
- package/esm2022/services/navigation.service.mjs +0 -52
- package/esm2022/services/theme.service.mjs +0 -64
- package/esm2022/types/menu.mjs +0 -2
- package/esm2022/types/popup.mjs +0 -2
- package/esm2022/types/tooltip.mjs +0 -2
- package/esm2022/utils/index.mjs +0 -205
- package/utils/index.d.ts +0 -128
- /package/{components → core/components}/lazy-loader/lazy-loader.component.d.ts +0 -0
- /package/{components → core/components}/lazy-loader/lazy-loader.module.d.ts +0 -0
- /package/{components → core/components}/lazy-loader/lazy-loader.service.d.ts +0 -0
- /package/{components → core/components}/lazy-loader/types.d.ts +0 -0
- /package/{components → core/components}/parallax-card/parallax-card.component.d.ts +0 -0
- /package/{directives → core/directives}/image-cache.directive.d.ts +0 -0
- /package/{directives → core/directives}/utils.d.ts +0 -0
- /package/{pipes → core/pipes}/html-bypass.pipe.d.ts +0 -0
- /package/{pipes → core/pipes}/resource-bypass.pipe.d.ts +0 -0
- /package/{pipes → core/pipes}/script-bypass.pipe.d.ts +0 -0
- /package/{pipes → core/pipes}/style-bypass.pipe.d.ts +0 -0
- /package/{pipes → core/pipes}/url-bypass.pipe.d.ts +0 -0
- /package/{services → core/services}/dependency.service.d.ts +0 -0
- /package/{services → core/services}/dialog.service.d.ts +0 -0
- /package/{services → core/services}/fetch.service.d.ts +0 -0
- /package/{services → core/services}/file.service.d.ts +0 -0
- /package/{services → core/services}/keyboard.service.d.ts +0 -0
- /package/{services → core/services}/theme.service.d.ts +0 -0
- /package/{types → core/types}/popup.d.ts +0 -0
|
@@ -0,0 +1,2280 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { InjectionToken, Input, Optional, Inject, Directive, Pipe, Injectable, EventEmitter, isDevMode, ViewContainerRef, Output, ViewChild, Component, HostListener, NgModule, TemplateRef, ContentChild } from '@angular/core';
|
|
3
|
+
import { createInstance, INDEXEDDB } from 'localforage';
|
|
4
|
+
import * as i1 from '@angular/platform-browser';
|
|
5
|
+
import { createApplication } from '@angular/platform-browser';
|
|
6
|
+
import { DOCUMENT, NgComponentOutlet, NgTemplateOutlet } from '@angular/common';
|
|
7
|
+
import * as i2$1 from '@angular/material/dialog';
|
|
8
|
+
import { MAT_DIALOG_DATA, MatDialog } from '@angular/material/dialog';
|
|
9
|
+
import { debounceTime, of, Subject, BehaviorSubject, firstValueFrom } from 'rxjs';
|
|
10
|
+
import * as i2 from '@angular/cdk/dialog';
|
|
11
|
+
import { retry } from 'rxjs/operators';
|
|
12
|
+
import * as i1$1 from '@angular/common/http';
|
|
13
|
+
import { __decorate, __param } from 'tslib';
|
|
14
|
+
import * as i4 from '@angular/material/icon';
|
|
15
|
+
import { MatIconModule } from '@angular/material/icon';
|
|
16
|
+
import * as i5 from '@angular/material/progress-spinner';
|
|
17
|
+
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
|
18
|
+
import * as i3 from '@angular/cdk/portal';
|
|
19
|
+
import { ComponentPortal, PortalModule } from '@angular/cdk/portal';
|
|
20
|
+
import { ulid } from 'ulidx';
|
|
21
|
+
|
|
22
|
+
const storage = createInstance({
|
|
23
|
+
name: "@dotglitch",
|
|
24
|
+
storeName: "image-cache",
|
|
25
|
+
driver: INDEXEDDB,
|
|
26
|
+
version: 1
|
|
27
|
+
});
|
|
28
|
+
const imageCache = {};
|
|
29
|
+
const loadingSvg = `data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="32px" height="32px" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid"><circle cx="50" cy="50" fill="none" stroke="%2340c4ff" stroke-width="10" r="35" stroke-dasharray="164.93361431346415 56.97787143782138"><animateTransform attributeName="transform" type="rotate" repeatCount="indefinite" dur="1s" values="0 50 50;360 50 50" keyTimes="0;1"></animateTransform></circle><!-- [ldio] generated by https://loading.io/ --></svg>`;
|
|
30
|
+
const brokenSvg = `data:image/svg+xml;utf8,<svg width="800" height="800" viewBox="0 0 24 24" version="1.1" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg"><line x1="10.08" y1="8.29" x2="10.18" y2="8.29" style="fill:none;stroke:#000000;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:round" /><path d="m 10.51,14.8 5.2,5.2 H 20 a 1,1 0 0 0 1,-1 V 15.73 L 15.29,10 Z M 3,16.71 V 19 a 1,1 0 0 0 1,1 h 11.71 l -8,-8 z M 21,5 v 14 a 1,1 0 0 1 -1,1 H 4 A 1,1 0 0 1 3,19 V 5 A 1,1 0 0 1 4,4 h 16 a 1,1 0 0 1 1,1 z" style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:round" /><path d="M 21.193388,21.193388 2.8066108,2.8066108 m 18.3867772,0 L 2.8066108,21.193388" style="stroke:%23ff0000;stroke-width:2.62668;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" /></svg>`;
|
|
31
|
+
const NGX_IMAGE_CACHE_CONFIG = new InjectionToken('ngx-image-cache-config');
|
|
32
|
+
class NgxImageCacheDirective {
|
|
33
|
+
get el() { return this.element.nativeElement; }
|
|
34
|
+
constructor(element, cacheConfig) {
|
|
35
|
+
this.element = element;
|
|
36
|
+
this.cacheConfig = cacheConfig;
|
|
37
|
+
}
|
|
38
|
+
ngOnChanges() {
|
|
39
|
+
this.getCachedImage();
|
|
40
|
+
}
|
|
41
|
+
async getCachedImage() {
|
|
42
|
+
if (this.el.src?.trim() == this.url?.trim() || // Check that there's an actual change
|
|
43
|
+
this.url?.trim().length == 0 // Check that there's an actual URL
|
|
44
|
+
)
|
|
45
|
+
return;
|
|
46
|
+
// Check if it's in the memory cache
|
|
47
|
+
if (imageCache[this.url]) {
|
|
48
|
+
const image = imageCache[this.url];
|
|
49
|
+
// If the image is currently loading, show the loader
|
|
50
|
+
// and add it to the reflist
|
|
51
|
+
if (image['_loading'] == true) {
|
|
52
|
+
image['_refs'].push(this.el);
|
|
53
|
+
this.el.setAttribute("loading", "true");
|
|
54
|
+
this.el.src = this.cacheConfig?.loadingPlaceholder || loadingSvg;
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
// The image is fully loaded, swap out the src with a data-uri
|
|
58
|
+
this.el.setAttribute("loading", "false");
|
|
59
|
+
this.el.src = image.src;
|
|
60
|
+
}
|
|
61
|
+
// If it's already in the image cache, we're going to trust that it loads properly.
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
// Check if it's in indexedDB
|
|
65
|
+
if (this.configuration?.cacheInIndexedDB != false) {
|
|
66
|
+
const cached = await storage.getItem(this.url);
|
|
67
|
+
if (cached) {
|
|
68
|
+
// Attempt to load the base64 data from indexeddb.
|
|
69
|
+
// If this fails, we'll fall back to attempting to download the image
|
|
70
|
+
this.el.src = cached.data;
|
|
71
|
+
const evt = await new Promise(res => {
|
|
72
|
+
this.el.addEventListener('load', res);
|
|
73
|
+
this.el.addEventListener('error', res);
|
|
74
|
+
});
|
|
75
|
+
// If the event isn't an error
|
|
76
|
+
if (evt.type == "load") {
|
|
77
|
+
this.el.setAttribute("loading", "false");
|
|
78
|
+
if (this.configuration?.cacheInMemory != false) {
|
|
79
|
+
// Successfully loaded into element
|
|
80
|
+
// Create an entry in the memory cache
|
|
81
|
+
const image = imageCache[this.url] = new Image();
|
|
82
|
+
image.src = cached.data;
|
|
83
|
+
image['_createdAt'] = Date.now();
|
|
84
|
+
}
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
// Else, we try to load again.
|
|
89
|
+
this.el.src = this.cacheConfig?.loadingPlaceholder || loadingSvg;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
const image = (() => {
|
|
94
|
+
if (this.configuration?.cacheInMemory != false) {
|
|
95
|
+
return imageCache[this.url] = new Image();
|
|
96
|
+
}
|
|
97
|
+
return new Image();
|
|
98
|
+
})();
|
|
99
|
+
// const clone = image.cloneNode(true) as HTMLImageElement;
|
|
100
|
+
image['_refs'] = image['_refs'] ?? [];
|
|
101
|
+
image['_refs'].push(this.el);
|
|
102
|
+
image['_loading'] = true;
|
|
103
|
+
image['_createdAt'] = Date.now();
|
|
104
|
+
// Show a loader while the image downloads.
|
|
105
|
+
this.el.setAttribute("loading", "true");
|
|
106
|
+
this.el.src = this.cacheConfig?.loadingPlaceholder || loadingSvg;
|
|
107
|
+
// Fetch the image via JS and cache it as base64
|
|
108
|
+
window.fetch(this.url)
|
|
109
|
+
.then(response => response.blob())
|
|
110
|
+
.then(blob => new Promise((resolve, reject) => {
|
|
111
|
+
const reader = new FileReader();
|
|
112
|
+
reader.onloadend = () => {
|
|
113
|
+
image.src = reader.result;
|
|
114
|
+
storage.setItem(this.url, {
|
|
115
|
+
timestamp: Date.now(),
|
|
116
|
+
data: reader.result
|
|
117
|
+
});
|
|
118
|
+
image['_refs'].forEach((ref) => {
|
|
119
|
+
ref.src = image.src;
|
|
120
|
+
});
|
|
121
|
+
image['_loading'] = false;
|
|
122
|
+
resolve(0);
|
|
123
|
+
};
|
|
124
|
+
reader.onerror = reject;
|
|
125
|
+
reader.readAsDataURL(blob);
|
|
126
|
+
}))
|
|
127
|
+
.catch(err => {
|
|
128
|
+
// If a failure occurs, purge this entry from the cache
|
|
129
|
+
// TODO: Render better "broken" image
|
|
130
|
+
delete imageCache[this.url];
|
|
131
|
+
image['_refs'].forEach((ref) => {
|
|
132
|
+
ref.src = this.cacheConfig?.brokenPlaceholder || brokenSvg;
|
|
133
|
+
ref.setAttribute("loading", "failed");
|
|
134
|
+
});
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NgxImageCacheDirective, deps: [{ token: i0.ElementRef }, { token: NGX_IMAGE_CACHE_CONFIG, optional: true }], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
138
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.12", type: NgxImageCacheDirective, isStandalone: true, selector: "img[ngx-cache]", inputs: { url: ["source", "url"], configuration: ["ngx-cache-config", "configuration"] }, usesOnChanges: true, ngImport: i0 }); }
|
|
139
|
+
}
|
|
140
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NgxImageCacheDirective, decorators: [{
|
|
141
|
+
type: Directive,
|
|
142
|
+
args: [{
|
|
143
|
+
selector: 'img[ngx-cache]',
|
|
144
|
+
standalone: true
|
|
145
|
+
}]
|
|
146
|
+
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: undefined, decorators: [{
|
|
147
|
+
type: Optional
|
|
148
|
+
}, {
|
|
149
|
+
type: Inject,
|
|
150
|
+
args: [NGX_IMAGE_CACHE_CONFIG]
|
|
151
|
+
}] }], propDecorators: { url: [{
|
|
152
|
+
type: Input,
|
|
153
|
+
args: ["source"]
|
|
154
|
+
}, {
|
|
155
|
+
type: Input,
|
|
156
|
+
args: ["ngx-cache"]
|
|
157
|
+
}], configuration: [{
|
|
158
|
+
type: Input,
|
|
159
|
+
args: ["ngx-cache-config"]
|
|
160
|
+
}] } });
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Url Sanitizer pipe.
|
|
164
|
+
*
|
|
165
|
+
* This trusts URLs that exist in a safe list defined in our environments.ts file.
|
|
166
|
+
* Any other URLs will NOT be trusted, thus will not be loaded.
|
|
167
|
+
*/
|
|
168
|
+
class HtmlBypass {
|
|
169
|
+
constructor(sanitizer) {
|
|
170
|
+
this.sanitizer = sanitizer;
|
|
171
|
+
}
|
|
172
|
+
transform(url) {
|
|
173
|
+
return this.sanitizer.bypassSecurityTrustHtml(url);
|
|
174
|
+
}
|
|
175
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: HtmlBypass, deps: [{ token: i1.DomSanitizer }], target: i0.ɵɵFactoryTarget.Pipe }); }
|
|
176
|
+
static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "17.3.12", ngImport: i0, type: HtmlBypass, isStandalone: true, name: "htmlbypass" }); }
|
|
177
|
+
}
|
|
178
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: HtmlBypass, decorators: [{
|
|
179
|
+
type: Pipe,
|
|
180
|
+
args: [{
|
|
181
|
+
name: 'htmlbypass',
|
|
182
|
+
standalone: true
|
|
183
|
+
}]
|
|
184
|
+
}], ctorParameters: () => [{ type: i1.DomSanitizer }] });
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Url Sanitizer pipe.
|
|
188
|
+
*
|
|
189
|
+
* This trusts URLs that exist in a safe list defined in our environments.ts file.
|
|
190
|
+
* Any other URLs will NOT be trusted, thus will not be loaded.
|
|
191
|
+
*/
|
|
192
|
+
class ResourceBypass {
|
|
193
|
+
constructor(sanitizer) {
|
|
194
|
+
this.sanitizer = sanitizer;
|
|
195
|
+
}
|
|
196
|
+
transform(url) {
|
|
197
|
+
return this.sanitizer.bypassSecurityTrustResourceUrl(url);
|
|
198
|
+
}
|
|
199
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ResourceBypass, deps: [{ token: i1.DomSanitizer }], target: i0.ɵɵFactoryTarget.Pipe }); }
|
|
200
|
+
static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "17.3.12", ngImport: i0, type: ResourceBypass, isStandalone: true, name: "resourcebypass" }); }
|
|
201
|
+
}
|
|
202
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ResourceBypass, decorators: [{
|
|
203
|
+
type: Pipe,
|
|
204
|
+
args: [{
|
|
205
|
+
name: 'resourcebypass',
|
|
206
|
+
standalone: true
|
|
207
|
+
}]
|
|
208
|
+
}], ctorParameters: () => [{ type: i1.DomSanitizer }] });
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Url Sanitizer pipe.
|
|
212
|
+
*
|
|
213
|
+
* This trusts URLs that exist in a safe list defined in our environments.ts file.
|
|
214
|
+
* Any other URLs will NOT be trusted, thus will not be loaded.
|
|
215
|
+
*/
|
|
216
|
+
class ScriptBypass {
|
|
217
|
+
constructor(sanitizer) {
|
|
218
|
+
this.sanitizer = sanitizer;
|
|
219
|
+
}
|
|
220
|
+
transform(url) {
|
|
221
|
+
return this.sanitizer.bypassSecurityTrustScript(url);
|
|
222
|
+
}
|
|
223
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ScriptBypass, deps: [{ token: i1.DomSanitizer }], target: i0.ɵɵFactoryTarget.Pipe }); }
|
|
224
|
+
static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "17.3.12", ngImport: i0, type: ScriptBypass, isStandalone: true, name: "scriptbypass" }); }
|
|
225
|
+
}
|
|
226
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ScriptBypass, decorators: [{
|
|
227
|
+
type: Pipe,
|
|
228
|
+
args: [{
|
|
229
|
+
name: 'scriptbypass',
|
|
230
|
+
standalone: true
|
|
231
|
+
}]
|
|
232
|
+
}], ctorParameters: () => [{ type: i1.DomSanitizer }] });
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Url Sanitizer pipe.
|
|
236
|
+
*
|
|
237
|
+
* This trusts URLs that exist in a safe list defined in our environments.ts file.
|
|
238
|
+
* Any other URLs will NOT be trusted, thus will not be loaded.
|
|
239
|
+
*/
|
|
240
|
+
class StyleBypass {
|
|
241
|
+
constructor(sanitizer) {
|
|
242
|
+
this.sanitizer = sanitizer;
|
|
243
|
+
}
|
|
244
|
+
transform(url) {
|
|
245
|
+
return this.sanitizer.bypassSecurityTrustStyle(url);
|
|
246
|
+
}
|
|
247
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: StyleBypass, deps: [{ token: i1.DomSanitizer }], target: i0.ɵɵFactoryTarget.Pipe }); }
|
|
248
|
+
static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "17.3.12", ngImport: i0, type: StyleBypass, isStandalone: true, name: "stylebypass" }); }
|
|
249
|
+
}
|
|
250
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: StyleBypass, decorators: [{
|
|
251
|
+
type: Pipe,
|
|
252
|
+
args: [{
|
|
253
|
+
name: 'stylebypass',
|
|
254
|
+
standalone: true
|
|
255
|
+
}]
|
|
256
|
+
}], ctorParameters: () => [{ type: i1.DomSanitizer }] });
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* Url Sanitizer pipe.
|
|
260
|
+
*
|
|
261
|
+
* This trusts URLs that exist in a safe list defined in our environments.ts file.
|
|
262
|
+
* Any other URLs will NOT be trusted, thus will not be loaded.
|
|
263
|
+
*/
|
|
264
|
+
class UrlBypass {
|
|
265
|
+
constructor(sanitizer) {
|
|
266
|
+
this.sanitizer = sanitizer;
|
|
267
|
+
}
|
|
268
|
+
transform(url) {
|
|
269
|
+
return this.sanitizer.bypassSecurityTrustUrl(url);
|
|
270
|
+
}
|
|
271
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: UrlBypass, deps: [{ token: i1.DomSanitizer }], target: i0.ɵɵFactoryTarget.Pipe }); }
|
|
272
|
+
static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "17.3.12", ngImport: i0, type: UrlBypass, isStandalone: true, name: "urlbypass" }); }
|
|
273
|
+
}
|
|
274
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: UrlBypass, decorators: [{
|
|
275
|
+
type: Pipe,
|
|
276
|
+
args: [{
|
|
277
|
+
name: 'urlbypass',
|
|
278
|
+
standalone: true
|
|
279
|
+
}]
|
|
280
|
+
}], ctorParameters: () => [{ type: i1.DomSanitizer }] });
|
|
281
|
+
|
|
282
|
+
const sleep = ms => new Promise(r => setTimeout(r, ms));
|
|
283
|
+
/**
|
|
284
|
+
* Prompt the user to save a json file of the given object.
|
|
285
|
+
*/
|
|
286
|
+
const saveObjectAsFile = (name, data) => {
|
|
287
|
+
const a = document.createElement("a");
|
|
288
|
+
const file = new Blob([JSON.stringify(data)], { type: "application/json" });
|
|
289
|
+
a.href = URL.createObjectURL(file);
|
|
290
|
+
a.download = name;
|
|
291
|
+
a.click();
|
|
292
|
+
a.remove();
|
|
293
|
+
};
|
|
294
|
+
/**
|
|
295
|
+
* Convert a string `fooBAR baz_160054''"1]"` into a slug: `foobar-baz-1600541`
|
|
296
|
+
*/
|
|
297
|
+
const stringToSlug = (text) => (text || '')
|
|
298
|
+
.trim()
|
|
299
|
+
.toLowerCase()
|
|
300
|
+
.replace(/[\-_+ ]/g, '-')
|
|
301
|
+
.replace(/[^a-z0-9\-\/]/g, '');
|
|
302
|
+
/**
|
|
303
|
+
* Helper to update the page URL.
|
|
304
|
+
* @param page component page ID to load.
|
|
305
|
+
* @param data string or JSON data for query params.
|
|
306
|
+
*/
|
|
307
|
+
const updateUrl = (page, data = {}, replaceState = false) => {
|
|
308
|
+
const [oldHash, qstring] = location.hash.split('?');
|
|
309
|
+
if (!page)
|
|
310
|
+
page = oldHash.split('/')[1];
|
|
311
|
+
const hash = `#/${page}`;
|
|
312
|
+
// Convert the data object to JSON.
|
|
313
|
+
if (data instanceof URLSearchParams) {
|
|
314
|
+
data = [...data.entries()].map(([k, v]) => ({ [k]: v })).reduce((a, b) => ({ ...a, ...b }), {});
|
|
315
|
+
}
|
|
316
|
+
const query = new URLSearchParams(data);
|
|
317
|
+
const prevParams = new URLSearchParams(qstring);
|
|
318
|
+
// If the hash is the same, retain params.
|
|
319
|
+
if (hash == oldHash) {
|
|
320
|
+
replaceState = true;
|
|
321
|
+
for (const [key, value] of prevParams.entries())
|
|
322
|
+
if (!query.has(key))
|
|
323
|
+
query.set(key, prevParams.get(key));
|
|
324
|
+
}
|
|
325
|
+
for (const [key, val] of query.entries()) {
|
|
326
|
+
if (val == null ||
|
|
327
|
+
val == undefined ||
|
|
328
|
+
val == '' ||
|
|
329
|
+
val == 'null' ||
|
|
330
|
+
Number.isNaN(val) ||
|
|
331
|
+
val == 'NaN')
|
|
332
|
+
query.delete(key);
|
|
333
|
+
}
|
|
334
|
+
if (!(hash.toLowerCase() == "#/frame") || data['id'] == -1)
|
|
335
|
+
query.delete('id');
|
|
336
|
+
const strQuery = query.toString();
|
|
337
|
+
console.log(data, hash, strQuery);
|
|
338
|
+
if (replaceState) {
|
|
339
|
+
window.history.replaceState(data, '', hash + (strQuery ? ('?' + strQuery) : ''));
|
|
340
|
+
}
|
|
341
|
+
else {
|
|
342
|
+
window.history.pushState(data, '', hash + (strQuery ? ('?' + strQuery) : ''));
|
|
343
|
+
}
|
|
344
|
+
};
|
|
345
|
+
const getUrlData = (source = window.location.hash) => {
|
|
346
|
+
const [hash, query] = source.split('?');
|
|
347
|
+
let data = new URLSearchParams(query);
|
|
348
|
+
return [...data.entries()].map(([k, v]) => ({ [k]: v })).reduce((a, b) => ({ ...a, ...b }), {});
|
|
349
|
+
};
|
|
350
|
+
|
|
351
|
+
const SCRIPT_INIT_TIMEOUT = 500; // ms
|
|
352
|
+
/**
|
|
353
|
+
* Service that installs CSS/JS dynamically
|
|
354
|
+
*/
|
|
355
|
+
class DependencyService {
|
|
356
|
+
constructor(document) {
|
|
357
|
+
this.document = document;
|
|
358
|
+
}
|
|
359
|
+
/**
|
|
360
|
+
* Install a Javascript file into the webpage on-demand
|
|
361
|
+
* @param id Unique identifier for the JS script
|
|
362
|
+
* @param src URL of the script
|
|
363
|
+
* @param globalkey A global object the script will provide.
|
|
364
|
+
* Providing this will ensure a promise only resolves after the
|
|
365
|
+
* specified global object is provided, with a timeout of 500ms
|
|
366
|
+
*/
|
|
367
|
+
loadScript(id, src, globalkey = null) {
|
|
368
|
+
return new Promise((res, rej) => {
|
|
369
|
+
if (this.document.getElementById(id))
|
|
370
|
+
return res();
|
|
371
|
+
const script = this.document.createElement('script');
|
|
372
|
+
script.id = id;
|
|
373
|
+
script.setAttribute("async", '');
|
|
374
|
+
script.setAttribute("src", src);
|
|
375
|
+
script.onload = async () => {
|
|
376
|
+
if (typeof globalkey == "string") {
|
|
377
|
+
let i = 0;
|
|
378
|
+
for (; !window[globalkey] && i < SCRIPT_INIT_TIMEOUT; i += 10)
|
|
379
|
+
await sleep(10);
|
|
380
|
+
if (i >= SCRIPT_INIT_TIMEOUT) {
|
|
381
|
+
return rej(new Error("Timed out waiting for script to self-initialize."));
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
res();
|
|
385
|
+
};
|
|
386
|
+
this.document.body.appendChild(script);
|
|
387
|
+
});
|
|
388
|
+
}
|
|
389
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: DependencyService, deps: [{ token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
390
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: DependencyService, providedIn: 'root' }); }
|
|
391
|
+
}
|
|
392
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: DependencyService, decorators: [{
|
|
393
|
+
type: Injectable,
|
|
394
|
+
args: [{
|
|
395
|
+
providedIn: 'root'
|
|
396
|
+
}]
|
|
397
|
+
}], ctorParameters: () => [{ type: Document, decorators: [{
|
|
398
|
+
type: Inject,
|
|
399
|
+
args: [DOCUMENT]
|
|
400
|
+
}] }] });
|
|
401
|
+
|
|
402
|
+
var ComponentResolveStrategy;
|
|
403
|
+
(function (ComponentResolveStrategy) {
|
|
404
|
+
/**
|
|
405
|
+
* Match the fist component we find
|
|
406
|
+
* (best used for standalone components)
|
|
407
|
+
* @default
|
|
408
|
+
*/
|
|
409
|
+
ComponentResolveStrategy[ComponentResolveStrategy["PickFirst"] = 0] = "PickFirst";
|
|
410
|
+
/**
|
|
411
|
+
* Perform an Exact ID to Classname of the Component
|
|
412
|
+
* case sensitive, zero tolerance.
|
|
413
|
+
*/
|
|
414
|
+
ComponentResolveStrategy[ComponentResolveStrategy["MatchIdToClassName"] = 1] = "MatchIdToClassName";
|
|
415
|
+
/**
|
|
416
|
+
* Perform a fuzzy ID to classname match
|
|
417
|
+
* case insensitive, mutes symbols
|
|
418
|
+
* ignores "Component" and "Module" postfixes on class
|
|
419
|
+
* names
|
|
420
|
+
*/
|
|
421
|
+
ComponentResolveStrategy[ComponentResolveStrategy["FuzzyIdClassName"] = 2] = "FuzzyIdClassName";
|
|
422
|
+
/**
|
|
423
|
+
* Use a user-provided component match function
|
|
424
|
+
*/
|
|
425
|
+
ComponentResolveStrategy[ComponentResolveStrategy["Custom"] = 3] = "Custom";
|
|
426
|
+
})(ComponentResolveStrategy || (ComponentResolveStrategy = {}));
|
|
427
|
+
|
|
428
|
+
// Monkey-patch the type of these symbols.
|
|
429
|
+
const $id = Symbol("id");
|
|
430
|
+
const $group = Symbol("group");
|
|
431
|
+
const NGX_LAZY_LOADER_CONFIG = new InjectionToken('lazyloader-config');
|
|
432
|
+
class LazyLoaderService {
|
|
433
|
+
get err() { return LazyLoaderService.config.logger.err; }
|
|
434
|
+
get log() { return LazyLoaderService.config.logger.log; }
|
|
435
|
+
get warn() { return LazyLoaderService.config.logger.warn; }
|
|
436
|
+
// A proxied registry that mutates reference keys
|
|
437
|
+
static { this.registry = {}; }
|
|
438
|
+
constructor(config = {}) {
|
|
439
|
+
// Ensure this is singleton and works regardless of special instancing requirements.
|
|
440
|
+
LazyLoaderService.configure(config);
|
|
441
|
+
}
|
|
442
|
+
static configure(config) {
|
|
443
|
+
this.config = {
|
|
444
|
+
componentResolveStrategy: ComponentResolveStrategy.PickFirst,
|
|
445
|
+
logger: {
|
|
446
|
+
log: console.log,
|
|
447
|
+
warn: console.warn,
|
|
448
|
+
err: console.error
|
|
449
|
+
},
|
|
450
|
+
...config
|
|
451
|
+
};
|
|
452
|
+
config?.entries?.forEach(e => this.addComponentToRegistry(e));
|
|
453
|
+
// If a custom resolution strategy is provided but no resolution function is passed,
|
|
454
|
+
// we throw an error
|
|
455
|
+
if (this.config.componentResolveStrategy == ComponentResolveStrategy.Custom &&
|
|
456
|
+
!this.config.customResolver) {
|
|
457
|
+
throw new Error("Cannot initialize. Configuration specifies a custom resolve matcher but none was provided");
|
|
458
|
+
}
|
|
459
|
+
if (this.config.loaderDistractorComponent && this.config.loaderDistractorTemplate)
|
|
460
|
+
throw new Error("Cannot have both a Component and Template for Distractor view.");
|
|
461
|
+
if (this.config.errorComponent && this.config.errorTemplate)
|
|
462
|
+
throw new Error("Cannot have both a Component and Template for Error view.");
|
|
463
|
+
if (this.config.notFoundComponent && this.config.notFoundTemplate)
|
|
464
|
+
throw new Error("Cannot have both a Component and Template for NotFound view.");
|
|
465
|
+
}
|
|
466
|
+
static addComponentToRegistry(registration) {
|
|
467
|
+
if (!registration)
|
|
468
|
+
throw new Error("Cannot add <undefined> component into registry.");
|
|
469
|
+
// Clone the object into our repository and transfer the id into a standardized slug format
|
|
470
|
+
const id = stringToSlug(registration.id ?? Date.now().toString()); // purge non-basic ASCII chars
|
|
471
|
+
const group = registration.group || "default";
|
|
472
|
+
registration[$id] = id;
|
|
473
|
+
registration[$group] = id;
|
|
474
|
+
if (!this.registry[group])
|
|
475
|
+
this.registry[group] = [];
|
|
476
|
+
// Check if we already have a registration for the component
|
|
477
|
+
// if (this.registry[group] && typeof this.registry[group]['load'] == "function") {
|
|
478
|
+
// // Warn the developer that the state is problematic
|
|
479
|
+
// this.config.logger.warn(
|
|
480
|
+
// `A previous entry already exists for ${id}! The old registration will be overridden.` +
|
|
481
|
+
// `Please ensure you use groups if you intend to have duplicate component ids. ` +
|
|
482
|
+
// `If this was intentional, first remove the old component from the registry before adding a new instance`
|
|
483
|
+
// );
|
|
484
|
+
// // If we're in dev mode, break the loader surface
|
|
485
|
+
// if (isDevMode())
|
|
486
|
+
// return;
|
|
487
|
+
// }
|
|
488
|
+
this.registry[group].push(registration);
|
|
489
|
+
}
|
|
490
|
+
/**
|
|
491
|
+
* Register an Angular component
|
|
492
|
+
* @param id identifier that is used to resolve the component
|
|
493
|
+
* @param group
|
|
494
|
+
* @param component Angular Component Class constructor
|
|
495
|
+
*/
|
|
496
|
+
registerComponent(args) {
|
|
497
|
+
if (this.isComponentRegistered(args.id, args.group)) {
|
|
498
|
+
this.log(`Will not re-register component '${args.id}' in group '${args.group || 'default'}' `);
|
|
499
|
+
return;
|
|
500
|
+
}
|
|
501
|
+
LazyLoaderService.addComponentToRegistry({
|
|
502
|
+
id: stringToSlug(args.id),
|
|
503
|
+
matcher: args.matcher,
|
|
504
|
+
group: stringToSlug(args.group || "default"),
|
|
505
|
+
load: args.load || (() => args.component)
|
|
506
|
+
});
|
|
507
|
+
}
|
|
508
|
+
/**
|
|
509
|
+
*
|
|
510
|
+
* @param id
|
|
511
|
+
* @param group
|
|
512
|
+
*/
|
|
513
|
+
unregisterComponent(id, group = "default") {
|
|
514
|
+
const _id = stringToSlug(id);
|
|
515
|
+
const _group = stringToSlug(group);
|
|
516
|
+
if (!this.resolveRegistrationEntry(id, group))
|
|
517
|
+
throw new Error("Cannot unregister component ${}! Component is not present in registry");
|
|
518
|
+
// TODO: handle clearing running instances
|
|
519
|
+
delete LazyLoaderService.registry[_group][_id];
|
|
520
|
+
}
|
|
521
|
+
/**
|
|
522
|
+
* Get the registration entry for a component.
|
|
523
|
+
* Returns null if component is not in the registry.
|
|
524
|
+
*/
|
|
525
|
+
resolveRegistrationEntry(value, group = "default") {
|
|
526
|
+
const _id = stringToSlug(value);
|
|
527
|
+
const _group = stringToSlug(group);
|
|
528
|
+
const targetGroup = (LazyLoaderService.registry[_group] || []);
|
|
529
|
+
let items = targetGroup.filter(t => {
|
|
530
|
+
if (!t)
|
|
531
|
+
return false;
|
|
532
|
+
// No matcher, check id
|
|
533
|
+
if (!t.matcher)
|
|
534
|
+
return t.id == value || t[$id] == _id;
|
|
535
|
+
// Matcher is regex
|
|
536
|
+
if (t.matcher instanceof RegExp)
|
|
537
|
+
return t.matcher.test(value) || t.matcher.test(_id);
|
|
538
|
+
// Matcher is string => regex
|
|
539
|
+
if (typeof t.matcher == 'string') {
|
|
540
|
+
const rx = new RegExp(t.matcher, 'ui');
|
|
541
|
+
return rx.test(value) || rx.test(_id);
|
|
542
|
+
}
|
|
543
|
+
// Matcher is array
|
|
544
|
+
if (Array.isArray(t.matcher)) {
|
|
545
|
+
return !!t.matcher.find(e => stringToSlug(e) == _id);
|
|
546
|
+
}
|
|
547
|
+
// Custom matcher function
|
|
548
|
+
if (typeof t.matcher == "function")
|
|
549
|
+
return t.matcher(_id);
|
|
550
|
+
return false;
|
|
551
|
+
});
|
|
552
|
+
if (items.length > 1) {
|
|
553
|
+
this.warn("Resolved multiple components for the provided `[component]` binding. This may cause UI conflicts.");
|
|
554
|
+
}
|
|
555
|
+
if (items.length == 0) {
|
|
556
|
+
return null;
|
|
557
|
+
}
|
|
558
|
+
const out = items[0];
|
|
559
|
+
if (out.matcher instanceof RegExp) {
|
|
560
|
+
const result = value.match(out.matcher) || _id.match(out.matcher);
|
|
561
|
+
return {
|
|
562
|
+
entry: out,
|
|
563
|
+
matchGroups: result?.groups
|
|
564
|
+
};
|
|
565
|
+
}
|
|
566
|
+
return { entry: out };
|
|
567
|
+
}
|
|
568
|
+
/**
|
|
569
|
+
* Check if a component is currently registered
|
|
570
|
+
* Can be used to validate regex matchers and aliases.
|
|
571
|
+
*/
|
|
572
|
+
isComponentRegistered(value, group = "default") {
|
|
573
|
+
return !!this.resolveRegistrationEntry(value, group);
|
|
574
|
+
}
|
|
575
|
+
/**
|
|
576
|
+
*
|
|
577
|
+
* @param bundle
|
|
578
|
+
* @returns The component `Object` if a component was resolved, `null` if no component was found
|
|
579
|
+
* `false` if the specified strategy was an invalid selection
|
|
580
|
+
*/
|
|
581
|
+
resolveComponent(id, group, modules) {
|
|
582
|
+
switch (LazyLoaderService.config.componentResolveStrategy) {
|
|
583
|
+
case ComponentResolveStrategy.PickFirst: {
|
|
584
|
+
return modules[0];
|
|
585
|
+
}
|
|
586
|
+
// Exact id -> classname match
|
|
587
|
+
case ComponentResolveStrategy.MatchIdToClassName: {
|
|
588
|
+
const matches = modules
|
|
589
|
+
.filter(k => k.name == id);
|
|
590
|
+
if (matches.length == 0)
|
|
591
|
+
return null;
|
|
592
|
+
return matches[0];
|
|
593
|
+
}
|
|
594
|
+
// Fuzzy id -> classname match
|
|
595
|
+
case ComponentResolveStrategy.FuzzyIdClassName: {
|
|
596
|
+
const _id = id.replace(/[^a-z0-9_\-]/ig, '');
|
|
597
|
+
if (_id.length == 0) {
|
|
598
|
+
LazyLoaderService.config.logger.err("Fuzzy classname matching stripped all symbols from the ID specified!");
|
|
599
|
+
return false;
|
|
600
|
+
}
|
|
601
|
+
const rx = new RegExp(`^${id}(component|module)?$`, "i");
|
|
602
|
+
const matches = modules
|
|
603
|
+
.filter(mod => {
|
|
604
|
+
let kid = mod.name.replace(/[^a-z0-9_\-]/ig, '');
|
|
605
|
+
return rx.test(kid);
|
|
606
|
+
});
|
|
607
|
+
if (matches.length > 1) {
|
|
608
|
+
LazyLoaderService.config.logger.err("Fuzzy classname matching resolved multiple targets!");
|
|
609
|
+
return false;
|
|
610
|
+
}
|
|
611
|
+
if (matches.length == 0) {
|
|
612
|
+
LazyLoaderService.config.logger.err("Fuzzy classname matching resolved no targets!");
|
|
613
|
+
return null;
|
|
614
|
+
}
|
|
615
|
+
return matches[0];
|
|
616
|
+
}
|
|
617
|
+
case ComponentResolveStrategy.Custom: {
|
|
618
|
+
return LazyLoaderService.config.customResolver(modules);
|
|
619
|
+
}
|
|
620
|
+
default: {
|
|
621
|
+
return false;
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: LazyLoaderService, deps: [{ token: NGX_LAZY_LOADER_CONFIG, optional: true }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
626
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: LazyLoaderService, providedIn: 'root' }); }
|
|
627
|
+
}
|
|
628
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: LazyLoaderService, decorators: [{
|
|
629
|
+
type: Injectable,
|
|
630
|
+
args: [{
|
|
631
|
+
providedIn: 'root'
|
|
632
|
+
}]
|
|
633
|
+
}], ctorParameters: () => [{ type: undefined, decorators: [{
|
|
634
|
+
type: Optional
|
|
635
|
+
}, {
|
|
636
|
+
type: Inject,
|
|
637
|
+
args: [NGX_LAZY_LOADER_CONFIG]
|
|
638
|
+
}] }] });
|
|
639
|
+
|
|
640
|
+
class LazyLoaderComponent {
|
|
641
|
+
/**
|
|
642
|
+
* The id of the component that will be lazy loaded
|
|
643
|
+
*/
|
|
644
|
+
set id(data) {
|
|
645
|
+
this.originalId = data;
|
|
646
|
+
const id = stringToSlug(data);
|
|
647
|
+
// Check if there is a change to the loaded component's id
|
|
648
|
+
// if it's updated, we destroy and rehydrate the entire container
|
|
649
|
+
if (this.initialized && this._id != id) {
|
|
650
|
+
this._id = id;
|
|
651
|
+
this.ngAfterViewInit();
|
|
652
|
+
}
|
|
653
|
+
else {
|
|
654
|
+
this._id = id;
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
;
|
|
658
|
+
set group(data) {
|
|
659
|
+
this.originalGroup = data;
|
|
660
|
+
const group = stringToSlug(data);
|
|
661
|
+
if (typeof group != "string" || !group)
|
|
662
|
+
return;
|
|
663
|
+
// If the group was updated, retry to bootstrap something into the container.
|
|
664
|
+
if (this.initialized && this._group != group) {
|
|
665
|
+
this._group = group;
|
|
666
|
+
this.ngAfterViewInit();
|
|
667
|
+
return;
|
|
668
|
+
}
|
|
669
|
+
this._group = group;
|
|
670
|
+
}
|
|
671
|
+
get group() { return this._group; }
|
|
672
|
+
/**
|
|
673
|
+
* A map of inputs to bind to the child.
|
|
674
|
+
* Supports change detection. (May fail on deep JSON changes)
|
|
675
|
+
*
|
|
676
|
+
* ```html
|
|
677
|
+
* <lazy-loader component="MyLazyComponent"
|
|
678
|
+
* [inputs]="{
|
|
679
|
+
* prop1: true,
|
|
680
|
+
* prop2: false,
|
|
681
|
+
* complex: {
|
|
682
|
+
* a: true,
|
|
683
|
+
* b: 0
|
|
684
|
+
* }
|
|
685
|
+
* }"
|
|
686
|
+
* >
|
|
687
|
+
* </lazy-loader>
|
|
688
|
+
* ```
|
|
689
|
+
*/
|
|
690
|
+
set inputs(data) {
|
|
691
|
+
if (data == undefined)
|
|
692
|
+
return;
|
|
693
|
+
let previous = this._inputs;
|
|
694
|
+
this._inputs = data;
|
|
695
|
+
if (data == undefined)
|
|
696
|
+
console.trace(data);
|
|
697
|
+
if (this.targetComponentFactory) {
|
|
698
|
+
const { inputs } = this.targetComponentFactory.ɵcmp;
|
|
699
|
+
const currentKeys = Object.keys(inputs);
|
|
700
|
+
const oldKeys = Object.keys(previous).filter(key => currentKeys.includes(key));
|
|
701
|
+
const newKeys = Object.keys(data).filter(key => currentKeys.includes(key));
|
|
702
|
+
const removed = oldKeys.filter(key => !newKeys.includes(key));
|
|
703
|
+
// ? perhaps set to null or undefined instead
|
|
704
|
+
removed.forEach(k => this.targetComponentInstance[k] = null);
|
|
705
|
+
this.bindInputs();
|
|
706
|
+
}
|
|
707
|
+
}
|
|
708
|
+
/**
|
|
709
|
+
* A map of outputs to bind from the child.
|
|
710
|
+
* Should support change detection.
|
|
711
|
+
* ```html
|
|
712
|
+
* <lazy-loader component="MyLazyComponent"
|
|
713
|
+
* [outputs]="{
|
|
714
|
+
* prop3: onOutputFire
|
|
715
|
+
* }"
|
|
716
|
+
* >
|
|
717
|
+
* </lazy-loader>
|
|
718
|
+
* ```
|
|
719
|
+
*/
|
|
720
|
+
set outputs(data) {
|
|
721
|
+
let previous = this._outputs;
|
|
722
|
+
this._outputs = data;
|
|
723
|
+
if (this.targetComponentFactory) {
|
|
724
|
+
const { inputs } = this.targetComponentFactory.ɵcmp;
|
|
725
|
+
const currentKeys = Object.keys(inputs);
|
|
726
|
+
const removed = Object.keys(previous).filter(key => !currentKeys.includes(key));
|
|
727
|
+
removed.forEach(k => {
|
|
728
|
+
// Unsubscribe from observable
|
|
729
|
+
this.outputSubscriptions[k]?.unsubscribe();
|
|
730
|
+
delete this.targetComponentInstance[k];
|
|
731
|
+
});
|
|
732
|
+
this.bindOutputs();
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
constructor(service, viewContainerRef, dialog, dialogArguments) {
|
|
736
|
+
this.service = service;
|
|
737
|
+
this.viewContainerRef = viewContainerRef;
|
|
738
|
+
this.dialog = dialog;
|
|
739
|
+
this.dialogArguments = dialogArguments;
|
|
740
|
+
this._group = "default";
|
|
741
|
+
this.outputSubscriptions = {};
|
|
742
|
+
/**
|
|
743
|
+
* Emits errors encountered when loading components
|
|
744
|
+
*/
|
|
745
|
+
this.componentLoadError = new EventEmitter();
|
|
746
|
+
/**
|
|
747
|
+
* Emits when the component is fully constructed
|
|
748
|
+
* and had it's inputs and outputs bound
|
|
749
|
+
* > before `OnInit`
|
|
750
|
+
*
|
|
751
|
+
* Returns the active class instance of the lazy-loaded component
|
|
752
|
+
*/
|
|
753
|
+
this.componentLoaded = new EventEmitter();
|
|
754
|
+
// Force 500ms delay before revealing the spinner
|
|
755
|
+
this.clearEmitter = new EventEmitter();
|
|
756
|
+
this.clearLoader$ = this.clearEmitter.pipe(debounceTime(300));
|
|
757
|
+
this.showEmitter = new EventEmitter();
|
|
758
|
+
this.showLoader$ = this.showEmitter.pipe(debounceTime(1));
|
|
759
|
+
this.subscriptions = [
|
|
760
|
+
this.clearLoader$.subscribe(() => {
|
|
761
|
+
this.isClearingLoader = true;
|
|
762
|
+
setTimeout(() => {
|
|
763
|
+
this.renderSpinner = false;
|
|
764
|
+
}, 300);
|
|
765
|
+
}),
|
|
766
|
+
this.showLoader$.subscribe(() => {
|
|
767
|
+
this.isClearingLoader = false;
|
|
768
|
+
this.renderSpinner = true;
|
|
769
|
+
})
|
|
770
|
+
];
|
|
771
|
+
this.renderSpinner = true; // whether we render the DOM for the spinner
|
|
772
|
+
this.isClearingLoader = false; // should the spinner start fading out
|
|
773
|
+
this.initialized = false;
|
|
774
|
+
this.config = LazyLoaderService.config;
|
|
775
|
+
this.err = LazyLoaderService.config.logger.err;
|
|
776
|
+
this.warn = LazyLoaderService.config.logger.warn;
|
|
777
|
+
this.log = LazyLoaderService.config.logger.log;
|
|
778
|
+
// First, check for dialog arguments
|
|
779
|
+
if (this.dialogArguments) {
|
|
780
|
+
this.inputs = this.dialogArguments.inputs || this.dialogArguments.data;
|
|
781
|
+
this.outputs = this.dialogArguments.outputs;
|
|
782
|
+
this.id = this.dialogArguments.id;
|
|
783
|
+
this.group = this.dialogArguments.group;
|
|
784
|
+
}
|
|
785
|
+
}
|
|
786
|
+
async ngAfterViewInit() {
|
|
787
|
+
this.ngOnDestroy(false);
|
|
788
|
+
this.isClearingLoader = false;
|
|
789
|
+
this.renderSpinner = true;
|
|
790
|
+
this.initialized = true;
|
|
791
|
+
if (!this._id) {
|
|
792
|
+
this.warn("No component was specified!");
|
|
793
|
+
return this.loadDefault();
|
|
794
|
+
}
|
|
795
|
+
try {
|
|
796
|
+
const _entry = this.service.resolveRegistrationEntry(this.originalId, this.originalGroup);
|
|
797
|
+
if (!_entry || !_entry.entry) {
|
|
798
|
+
this.err(`Failed to find Component '${this._id}' in group '${this._group}' in registry!`);
|
|
799
|
+
return this.loadDefault();
|
|
800
|
+
}
|
|
801
|
+
const { entry, matchGroups } = _entry;
|
|
802
|
+
this._matchGroups = matchGroups;
|
|
803
|
+
// Download the "module" (the standalone component)
|
|
804
|
+
const bundle = this.targetModule = await entry.load();
|
|
805
|
+
// Check if there is some corruption on the bundle.
|
|
806
|
+
if (!bundle || typeof bundle != 'object') {
|
|
807
|
+
this.err(`Failed to load component/module for '${this._id}'! Parsed resource is invalid.`);
|
|
808
|
+
return this.loadError();
|
|
809
|
+
}
|
|
810
|
+
const modules = Object.keys(bundle)
|
|
811
|
+
.map(k => {
|
|
812
|
+
const entry = bundle[k];
|
|
813
|
+
// Strictly check for exported modules or standalone components
|
|
814
|
+
if (typeof entry == "function" && typeof entry["ɵfac"] == "function")
|
|
815
|
+
return entry;
|
|
816
|
+
return null;
|
|
817
|
+
})
|
|
818
|
+
.filter(e => e != null)
|
|
819
|
+
.filter(entry => {
|
|
820
|
+
entry['_isModule'] = !!entry['ɵmod']; // module
|
|
821
|
+
entry['_isComponent'] = !!entry['ɵcmp']; // component
|
|
822
|
+
return (entry['_isModule'] || entry['_isComponent']);
|
|
823
|
+
});
|
|
824
|
+
if (modules.length == 0) {
|
|
825
|
+
this.err(`Component/Module loaded for '${this._id}' has no exported components or modules!`);
|
|
826
|
+
return this.loadError();
|
|
827
|
+
}
|
|
828
|
+
const component = this.targetComponentFactory = this.service.resolveComponent(this._id, "default", modules);
|
|
829
|
+
if (!component) {
|
|
830
|
+
this.err(`Component '${this._id}' is invalid or corrupted!`);
|
|
831
|
+
return this.loadError();
|
|
832
|
+
}
|
|
833
|
+
// const componentRef = this.targetComponentContainerRef = createComponent(component as any, {
|
|
834
|
+
// environmentInjector: this.appRef.injector,
|
|
835
|
+
// elementInjector: this.injector,
|
|
836
|
+
// hostElement: this.viewContainerRef.element.nativeElement,
|
|
837
|
+
// // projectableNodes:
|
|
838
|
+
// });
|
|
839
|
+
// // this.targetRef = this.targetContainer.insert(this.targetComponentContainerRef.hostView);
|
|
840
|
+
// this.appRef.attachView(componentRef.hostView);
|
|
841
|
+
// Bootstrap the component into the container
|
|
842
|
+
const componentRef = this.targetComponentContainerRef = this.targetContainer.createComponent(component);
|
|
843
|
+
this.targetRef = this.targetContainer.insert(this.targetComponentContainerRef.hostView);
|
|
844
|
+
const instance = this.targetComponentInstance = componentRef['instance'];
|
|
845
|
+
this.bindInputs();
|
|
846
|
+
this.bindOutputs();
|
|
847
|
+
this.componentLoaded.next(instance);
|
|
848
|
+
this.instance = instance;
|
|
849
|
+
// Look for an observable called isLoading$ that will make us show/hide
|
|
850
|
+
// the same distractor that is used on basic loading
|
|
851
|
+
const isLoading$ = instance['ngxShowDistractor$'];
|
|
852
|
+
if (isLoading$ && typeof isLoading$.subscribe == "function") {
|
|
853
|
+
this.distractorSubscription = isLoading$.subscribe(loading => {
|
|
854
|
+
loading ? this.showEmitter.emit() : this.clearEmitter.emit();
|
|
855
|
+
});
|
|
856
|
+
}
|
|
857
|
+
else {
|
|
858
|
+
this.clearEmitter.emit();
|
|
859
|
+
}
|
|
860
|
+
const name = Object.keys(bundle)[0];
|
|
861
|
+
this.log(`Loaded '${name}'`);
|
|
862
|
+
this.clearEmitter.emit();
|
|
863
|
+
return componentRef;
|
|
864
|
+
}
|
|
865
|
+
catch (ex) {
|
|
866
|
+
if (isDevMode()) {
|
|
867
|
+
console.warn("Component DDD " + this._id + " threw an error on mount!");
|
|
868
|
+
console.warn("This will cause you to see a 404 panel.");
|
|
869
|
+
console.error(ex);
|
|
870
|
+
}
|
|
871
|
+
// Network errors throw a toast and return an error component
|
|
872
|
+
if (ex && !isDevMode()) {
|
|
873
|
+
console.error("Uncaught error when loading component");
|
|
874
|
+
throw ex;
|
|
875
|
+
}
|
|
876
|
+
return this.loadDefault();
|
|
877
|
+
}
|
|
878
|
+
}
|
|
879
|
+
ngOnDestroy(clearAll = true) {
|
|
880
|
+
// unsubscribe from all subscriptions
|
|
881
|
+
Object.entries(this.outputSubscriptions).forEach(([key, sub]) => {
|
|
882
|
+
sub.unsubscribe();
|
|
883
|
+
});
|
|
884
|
+
this.outputSubscriptions = {};
|
|
885
|
+
// Clear all things
|
|
886
|
+
if (clearAll) {
|
|
887
|
+
Object.entries(this.subscriptions).forEach(([key, sub]) => {
|
|
888
|
+
sub.unsubscribe();
|
|
889
|
+
});
|
|
890
|
+
}
|
|
891
|
+
this.distractorSubscription?.unsubscribe();
|
|
892
|
+
// Clear target container
|
|
893
|
+
this.targetRef?.destroy();
|
|
894
|
+
this.targetComponentContainerRef?.destroy();
|
|
895
|
+
this.targetContainer?.clear();
|
|
896
|
+
// Wipe the rest of the state clean
|
|
897
|
+
this.targetRef = null;
|
|
898
|
+
this.targetComponentContainerRef = null;
|
|
899
|
+
}
|
|
900
|
+
/**
|
|
901
|
+
* Bind the input values to the child component.
|
|
902
|
+
*/
|
|
903
|
+
bindInputs() {
|
|
904
|
+
if (!this._inputs || !this.targetComponentInstance)
|
|
905
|
+
return;
|
|
906
|
+
// Merge match groups
|
|
907
|
+
if (typeof this._matchGroups == "object") {
|
|
908
|
+
Object.entries(this._matchGroups).forEach(([key, val]) => {
|
|
909
|
+
if (typeof this._inputs[key] == 'undefined')
|
|
910
|
+
this._inputs[key] = val;
|
|
911
|
+
});
|
|
912
|
+
}
|
|
913
|
+
// forward-bind inputs
|
|
914
|
+
const { inputs } = this.targetComponentFactory.ɵcmp;
|
|
915
|
+
// Returns a list of entries that need to be set
|
|
916
|
+
// This makes it so that unnecessary setters are not invoked.
|
|
917
|
+
const updated = Object.entries(inputs).filter(([parentKey, childKey]) => {
|
|
918
|
+
return this.targetComponentInstance[childKey] != this._inputs[parentKey];
|
|
919
|
+
});
|
|
920
|
+
updated.forEach(([parentKey, childKey]) => {
|
|
921
|
+
if (this._inputs.hasOwnProperty(parentKey)) {
|
|
922
|
+
// Angular 19.2+
|
|
923
|
+
if (Array.isArray(childKey)) {
|
|
924
|
+
this.targetComponentInstance[childKey[0]] = this._inputs[parentKey];
|
|
925
|
+
}
|
|
926
|
+
else {
|
|
927
|
+
this.targetComponentInstance[childKey] = this._inputs[parentKey];
|
|
928
|
+
}
|
|
929
|
+
}
|
|
930
|
+
});
|
|
931
|
+
}
|
|
932
|
+
/**
|
|
933
|
+
* Bind the output handlers to the loaded child component
|
|
934
|
+
*/
|
|
935
|
+
bindOutputs() {
|
|
936
|
+
if (!this._outputs || !this.targetComponentInstance)
|
|
937
|
+
return;
|
|
938
|
+
const { outputs } = this.targetComponentFactory.ɵcmp;
|
|
939
|
+
// Get a list of unregistered outputs
|
|
940
|
+
const newOutputs = Object.entries(outputs).filter(([parentKey, childKey]) => {
|
|
941
|
+
return !this.outputSubscriptions[parentKey];
|
|
942
|
+
});
|
|
943
|
+
// Reverse bind via subscription
|
|
944
|
+
newOutputs.forEach(([parentKey, childKey]) => {
|
|
945
|
+
if (this._outputs.hasOwnProperty(parentKey)) {
|
|
946
|
+
const target = this.targetComponentInstance[childKey];
|
|
947
|
+
const outputs = this._outputs;
|
|
948
|
+
// Angular folks, stop making this so difficult.
|
|
949
|
+
const ctx = this.viewContainerRef['_hostLView'][8];
|
|
950
|
+
const sub = target.subscribe(outputs[parentKey].bind(ctx)); // Subscription
|
|
951
|
+
this.outputSubscriptions[parentKey] = sub;
|
|
952
|
+
}
|
|
953
|
+
});
|
|
954
|
+
}
|
|
955
|
+
/**
|
|
956
|
+
* Load the "Default" component (404) screen normally.
|
|
957
|
+
* This is shown when the component id isn't in the
|
|
958
|
+
* registry or otherwise doesn't match
|
|
959
|
+
*
|
|
960
|
+
* This
|
|
961
|
+
*/
|
|
962
|
+
loadDefault() {
|
|
963
|
+
if (this.config.notFoundComponent)
|
|
964
|
+
this.targetContainer.createComponent(this.config.notFoundComponent);
|
|
965
|
+
this.clearEmitter.emit();
|
|
966
|
+
}
|
|
967
|
+
/**
|
|
968
|
+
* Load the "Error" component.
|
|
969
|
+
* This is shown when we are able to resolve the component
|
|
970
|
+
* in the registry, but have some issue boostrapping the
|
|
971
|
+
* component into the viewContainer
|
|
972
|
+
*/
|
|
973
|
+
loadError() {
|
|
974
|
+
if (this.config.errorComponent)
|
|
975
|
+
this.targetContainer.createComponent(this.config.errorComponent);
|
|
976
|
+
this.clearEmitter.emit();
|
|
977
|
+
}
|
|
978
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: LazyLoaderComponent, deps: [{ token: LazyLoaderService }, { token: i0.ViewContainerRef, optional: true }, { token: i2.DialogRef, optional: true }, { token: MAT_DIALOG_DATA, optional: true }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
979
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: LazyLoaderComponent, isStandalone: true, selector: "ngx-lazy-loader", inputs: { id: ["component", "id"], group: "group", inputs: "inputs", outputs: "outputs" }, outputs: { componentLoadError: "componentLoadError", componentLoaded: "componentLoaded" }, viewQueries: [{ propertyName: "targetContainer", first: true, predicate: ["content"], descendants: true, read: ViewContainerRef }], ngImport: i0, template: "<ng-container #content></ng-container>\n\n@if (renderSpinner) {\n <div\n class=\"ngx-lazy-loader-distractor\"\n [class.destroying]=\"isClearingLoader\"\n >\n @if (config.loaderDistractorComponent) {\n <ng-container\n [ngComponentOutlet]=\"config.loaderDistractorComponent\"\n />\n }\n @if (config.loaderDistractorTemplate) {\n <ng-container\n [ngTemplateOutlet]=\"config.loaderDistractorTemplate\"\n [ngTemplateOutletContext]=\"{ '$implicit': inputs }\"\n />\n }\n </div>\n}\n", styles: [":host{display:contents;contain:content;z-index:1;position:relative}.ngx-lazy-loader-distractor{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;flex-direction:column;background-color:var(--background-color, #212121);opacity:1;transition:opacity .3s ease;z-index:999999;animation:fade-in .3s ease}.ngx-lazy-loader-distractor.destroying{opacity:0;pointer-events:none}@keyframes fade-in{0%{opacity:0;pointer-events:none}to{opacity:1;pointer-events:all}}\n"], dependencies: [{ kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletContent", "ngComponentOutletNgModule", "ngComponentOutletNgModuleFactory"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] }); }
|
|
980
|
+
}
|
|
981
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: LazyLoaderComponent, decorators: [{
|
|
982
|
+
type: Component,
|
|
983
|
+
args: [{ selector: 'ngx-lazy-loader', imports: [NgComponentOutlet, NgTemplateOutlet], standalone: true, template: "<ng-container #content></ng-container>\n\n@if (renderSpinner) {\n <div\n class=\"ngx-lazy-loader-distractor\"\n [class.destroying]=\"isClearingLoader\"\n >\n @if (config.loaderDistractorComponent) {\n <ng-container\n [ngComponentOutlet]=\"config.loaderDistractorComponent\"\n />\n }\n @if (config.loaderDistractorTemplate) {\n <ng-container\n [ngTemplateOutlet]=\"config.loaderDistractorTemplate\"\n [ngTemplateOutletContext]=\"{ '$implicit': inputs }\"\n />\n }\n </div>\n}\n", styles: [":host{display:contents;contain:content;z-index:1;position:relative}.ngx-lazy-loader-distractor{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;flex-direction:column;background-color:var(--background-color, #212121);opacity:1;transition:opacity .3s ease;z-index:999999;animation:fade-in .3s ease}.ngx-lazy-loader-distractor.destroying{opacity:0;pointer-events:none}@keyframes fade-in{0%{opacity:0;pointer-events:none}to{opacity:1;pointer-events:all}}\n"] }]
|
|
984
|
+
}], ctorParameters: () => [{ type: LazyLoaderService }, { type: i0.ViewContainerRef, decorators: [{
|
|
985
|
+
type: Optional
|
|
986
|
+
}] }, { type: i2.DialogRef, decorators: [{
|
|
987
|
+
type: Optional
|
|
988
|
+
}] }, { type: undefined, decorators: [{
|
|
989
|
+
type: Optional
|
|
990
|
+
}, {
|
|
991
|
+
type: Inject,
|
|
992
|
+
args: [MAT_DIALOG_DATA]
|
|
993
|
+
}] }], propDecorators: { targetContainer: [{
|
|
994
|
+
type: ViewChild,
|
|
995
|
+
args: ["content", { read: ViewContainerRef }]
|
|
996
|
+
}], id: [{
|
|
997
|
+
type: Input,
|
|
998
|
+
args: ["component"]
|
|
999
|
+
}], group: [{
|
|
1000
|
+
type: Input,
|
|
1001
|
+
args: ["group"]
|
|
1002
|
+
}], inputs: [{
|
|
1003
|
+
type: Input,
|
|
1004
|
+
args: ["inputs"]
|
|
1005
|
+
}], outputs: [{
|
|
1006
|
+
type: Input,
|
|
1007
|
+
args: ["outputs"]
|
|
1008
|
+
}], componentLoadError: [{
|
|
1009
|
+
type: Output
|
|
1010
|
+
}], componentLoaded: [{
|
|
1011
|
+
type: Output
|
|
1012
|
+
}] } });
|
|
1013
|
+
|
|
1014
|
+
class DialogService {
|
|
1015
|
+
constructor(dialog, lazyLoader) {
|
|
1016
|
+
this.dialog = dialog;
|
|
1017
|
+
this.lazyLoader = lazyLoader;
|
|
1018
|
+
this.dialogs = [];
|
|
1019
|
+
}
|
|
1020
|
+
open(name, groupOrOptions, opts = {}) {
|
|
1021
|
+
const group = typeof groupOrOptions == "string" ? groupOrOptions : 'default';
|
|
1022
|
+
if (typeof groupOrOptions == 'object')
|
|
1023
|
+
opts = groupOrOptions;
|
|
1024
|
+
return new Promise((resolve, reject) => {
|
|
1025
|
+
const registration = this.lazyLoader.resolveRegistrationEntry(name, group);
|
|
1026
|
+
if (!registration)
|
|
1027
|
+
return reject(new Error("Cannot open dialog for " + name + ". Could not find in registry."));
|
|
1028
|
+
const args = {
|
|
1029
|
+
closeOnNavigation: true,
|
|
1030
|
+
restoreFocus: true,
|
|
1031
|
+
width: registration['width'],
|
|
1032
|
+
height: registration['height'],
|
|
1033
|
+
...opts,
|
|
1034
|
+
data: {
|
|
1035
|
+
id: name,
|
|
1036
|
+
inputs: opts.inputs || {},
|
|
1037
|
+
outputs: opts.outputs || {},
|
|
1038
|
+
group: group
|
|
1039
|
+
},
|
|
1040
|
+
panelClass: [
|
|
1041
|
+
"dialog-" + name,
|
|
1042
|
+
...(Array.isArray(opts.panelClass) ? opts.panelClass : [opts.panelClass])
|
|
1043
|
+
]
|
|
1044
|
+
};
|
|
1045
|
+
let dialog = this.dialog.open(LazyLoaderComponent, args);
|
|
1046
|
+
dialog['idx'] = name;
|
|
1047
|
+
this.dialogs.push(dialog);
|
|
1048
|
+
dialog.afterClosed().subscribe(result => {
|
|
1049
|
+
console.info("Dialog closed " + name, result);
|
|
1050
|
+
resolve(result);
|
|
1051
|
+
});
|
|
1052
|
+
});
|
|
1053
|
+
}
|
|
1054
|
+
// Close all dialogs matching the given name
|
|
1055
|
+
close(name) {
|
|
1056
|
+
const dialogs = this.dialogs.filter(d => d['idx'] == name);
|
|
1057
|
+
dialogs.forEach(dialog => dialog.close());
|
|
1058
|
+
}
|
|
1059
|
+
/**
|
|
1060
|
+
* Method to close _all_ dialogs.
|
|
1061
|
+
* Should be used sparingly.
|
|
1062
|
+
*/
|
|
1063
|
+
clearDialog() {
|
|
1064
|
+
this.dialogs.forEach(dialog => dialog.close());
|
|
1065
|
+
}
|
|
1066
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: DialogService, deps: [{ token: i2$1.MatDialog }, { token: LazyLoaderService }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1067
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: DialogService, providedIn: 'root' }); }
|
|
1068
|
+
}
|
|
1069
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: DialogService, decorators: [{
|
|
1070
|
+
type: Injectable,
|
|
1071
|
+
args: [{
|
|
1072
|
+
providedIn: 'root'
|
|
1073
|
+
}]
|
|
1074
|
+
}], ctorParameters: () => [{ type: i2$1.MatDialog }, { type: LazyLoaderService }] });
|
|
1075
|
+
|
|
1076
|
+
// Total number of _retries_ if there is a 429 response code.
|
|
1077
|
+
const retryCount = 2;
|
|
1078
|
+
class Fetch {
|
|
1079
|
+
constructor(http) {
|
|
1080
|
+
this.http = http;
|
|
1081
|
+
}
|
|
1082
|
+
// Public interface for making AJAX transactions
|
|
1083
|
+
get(url, options = {}, returnError = false) {
|
|
1084
|
+
return this.request("get", url, options, returnError);
|
|
1085
|
+
}
|
|
1086
|
+
put(url, body, options = {}, returnError = false) {
|
|
1087
|
+
options.body = (options.body && Object.keys(options.body).length > 0 ? options.body : body) || {};
|
|
1088
|
+
return this.request("put", url, options, returnError);
|
|
1089
|
+
}
|
|
1090
|
+
post(url, body, options = {}, returnError = false) {
|
|
1091
|
+
options.body = (options.body && Object.keys(options.body).length > 0 ? options.body : body) || {};
|
|
1092
|
+
return this.request("post", url, options, returnError);
|
|
1093
|
+
}
|
|
1094
|
+
patch(url, body, options = {}, returnError = false) {
|
|
1095
|
+
options.body = (options.body && Object.keys(options.body).length > 0 ? options.body : body) || {};
|
|
1096
|
+
return this.request("patch", url, options, returnError);
|
|
1097
|
+
}
|
|
1098
|
+
delete(url, options = {}, returnError = false) {
|
|
1099
|
+
return this.request("delete", url, options, returnError);
|
|
1100
|
+
}
|
|
1101
|
+
// Internally, handle the observable as a promise.
|
|
1102
|
+
request(method, url, options = {}, returnError = false) {
|
|
1103
|
+
options.reportProgress = true;
|
|
1104
|
+
// Allow support for different response types.
|
|
1105
|
+
// Generally we shouldn't need this to be anything other than JSON.
|
|
1106
|
+
options.responseType = options.responseType || "json";
|
|
1107
|
+
options.withCredentials = true;
|
|
1108
|
+
let abort = false;
|
|
1109
|
+
const p = new Promise((resolve, reject) => {
|
|
1110
|
+
const o = this.http.request(method, url, options)
|
|
1111
|
+
.pipe(retry({
|
|
1112
|
+
delay(error, retryCount) {
|
|
1113
|
+
// 429 and 502 are most common for overloaded
|
|
1114
|
+
// backends -- so we'll retry if we get these errors
|
|
1115
|
+
if (error.status == 429 || error.status == 502)
|
|
1116
|
+
return of({});
|
|
1117
|
+
if (error.status == 504 && isDevMode())
|
|
1118
|
+
alert("It looks like you can't reach your development backend anymore");
|
|
1119
|
+
abort = true;
|
|
1120
|
+
reject(error);
|
|
1121
|
+
throw error;
|
|
1122
|
+
},
|
|
1123
|
+
count: retryCount
|
|
1124
|
+
}))
|
|
1125
|
+
.subscribe(data => {
|
|
1126
|
+
resolve(data);
|
|
1127
|
+
// provide 3ms slacktime before releasing observable.
|
|
1128
|
+
setTimeout(() => {
|
|
1129
|
+
o.unsubscribe();
|
|
1130
|
+
}, 3);
|
|
1131
|
+
});
|
|
1132
|
+
});
|
|
1133
|
+
return p;
|
|
1134
|
+
}
|
|
1135
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: Fetch, deps: [{ token: i1$1.HttpClient }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1136
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: Fetch, providedIn: "root" }); }
|
|
1137
|
+
}
|
|
1138
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: Fetch, decorators: [{
|
|
1139
|
+
type: Injectable,
|
|
1140
|
+
args: [{
|
|
1141
|
+
providedIn: "root"
|
|
1142
|
+
}]
|
|
1143
|
+
}], ctorParameters: () => [{ type: i1$1.HttpClient }] });
|
|
1144
|
+
|
|
1145
|
+
/**
|
|
1146
|
+
* Service that listens for global keyboard events
|
|
1147
|
+
*/
|
|
1148
|
+
class FileService {
|
|
1149
|
+
constructor(fetch) {
|
|
1150
|
+
this.fetch = fetch;
|
|
1151
|
+
this.chooseFile = (accept, multiple = false, formMetadata = {}) => {
|
|
1152
|
+
return new Promise(r => {
|
|
1153
|
+
const inEl = document.createElement('input');
|
|
1154
|
+
inEl.setAttribute('type', 'file');
|
|
1155
|
+
if (multiple)
|
|
1156
|
+
inEl.setAttribute('multiple', '');
|
|
1157
|
+
if (accept)
|
|
1158
|
+
inEl.setAttribute('accept', accept);
|
|
1159
|
+
inEl.click();
|
|
1160
|
+
let formData = new FormData();
|
|
1161
|
+
inEl.addEventListener('change', () => {
|
|
1162
|
+
Object.keys(inEl.files).forEach(k => {
|
|
1163
|
+
const file = inEl.files[k];
|
|
1164
|
+
const name = file.name;
|
|
1165
|
+
formData.append(name, file);
|
|
1166
|
+
});
|
|
1167
|
+
formData.append("data", JSON.stringify(formMetadata));
|
|
1168
|
+
inEl.remove();
|
|
1169
|
+
r(formData);
|
|
1170
|
+
});
|
|
1171
|
+
});
|
|
1172
|
+
};
|
|
1173
|
+
}
|
|
1174
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: FileService, deps: [{ token: Fetch }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1175
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: FileService, providedIn: 'root' }); }
|
|
1176
|
+
}
|
|
1177
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: FileService, decorators: [{
|
|
1178
|
+
type: Injectable,
|
|
1179
|
+
args: [{
|
|
1180
|
+
providedIn: 'root'
|
|
1181
|
+
}]
|
|
1182
|
+
}], ctorParameters: () => [{ type: Fetch }] });
|
|
1183
|
+
|
|
1184
|
+
/**
|
|
1185
|
+
* Service that listens for global keyboard events
|
|
1186
|
+
*/
|
|
1187
|
+
class KeyboardService {
|
|
1188
|
+
constructor() {
|
|
1189
|
+
this.heldKeys = {};
|
|
1190
|
+
this.keyCommands = [];
|
|
1191
|
+
window.addEventListener("keydown", (evt) => this.onKeyDown(evt));
|
|
1192
|
+
window.addEventListener("keyup", (evt) => this.onKeyUp(evt));
|
|
1193
|
+
}
|
|
1194
|
+
onKeyDown(evt) {
|
|
1195
|
+
// console.log("keydown", evt.key)
|
|
1196
|
+
this.heldKeys[evt.key.toLowerCase()] = true;
|
|
1197
|
+
// Do a general filter where all of the modifiers must be matched if specified
|
|
1198
|
+
// Then check that the actual keys match what was specified
|
|
1199
|
+
let commands = this.keyCommands
|
|
1200
|
+
.filter(kc => (kc.ctrl == undefined || kc.ctrl === evt.ctrlKey) &&
|
|
1201
|
+
(kc.alt == undefined || kc.alt === evt.altKey) &&
|
|
1202
|
+
(kc.shift == undefined || kc.shift === evt.shiftKey) &&
|
|
1203
|
+
(kc.super == undefined || kc.super === evt.metaKey) &&
|
|
1204
|
+
kc.keys.length == kc.keys.filter(k => this.heldKeys[k])?.length);
|
|
1205
|
+
if (evt.ctrlKey && commands.length > 0 || commands.find(c => c.interrupt)) {
|
|
1206
|
+
evt.stopPropagation();
|
|
1207
|
+
evt.preventDefault();
|
|
1208
|
+
}
|
|
1209
|
+
if (evt.key == "Pause")
|
|
1210
|
+
debugger;
|
|
1211
|
+
commands.forEach(kc => kc.sub.next(evt));
|
|
1212
|
+
/**
|
|
1213
|
+
* Prevent CTRL+P and other standard key events from being handled by the browser.
|
|
1214
|
+
* Allow specific combonations:
|
|
1215
|
+
* CTRL+W
|
|
1216
|
+
* CTRL+T
|
|
1217
|
+
* CTRL+F5
|
|
1218
|
+
*/
|
|
1219
|
+
// if (evt.ctrlKey && !['w', 't', 'F5'].includes(evt.key)) {
|
|
1220
|
+
// evt.preventDefault();
|
|
1221
|
+
// }
|
|
1222
|
+
}
|
|
1223
|
+
onKeyUp(evt) {
|
|
1224
|
+
this.heldKeys[evt.key.toLowerCase()] = false;
|
|
1225
|
+
}
|
|
1226
|
+
onKeyPress(evt) {
|
|
1227
|
+
// this.heldKeys[evt.key] = false;
|
|
1228
|
+
}
|
|
1229
|
+
/**
|
|
1230
|
+
* Use this to subscribe to keyboard events throughout
|
|
1231
|
+
* the application. This is a passive listener and will
|
|
1232
|
+
* **NOT** interrupt the event chain.
|
|
1233
|
+
*/
|
|
1234
|
+
onKeyCommand(key) {
|
|
1235
|
+
const sub = new Subject();
|
|
1236
|
+
let item = {
|
|
1237
|
+
...key,
|
|
1238
|
+
keys: (Array.isArray(key.key) ? key.key : [key.key]),
|
|
1239
|
+
sub: sub
|
|
1240
|
+
};
|
|
1241
|
+
this.keyCommands.push(item);
|
|
1242
|
+
return {
|
|
1243
|
+
...sub,
|
|
1244
|
+
subscribe: ((...args) => {
|
|
1245
|
+
const s = sub.subscribe(...args);
|
|
1246
|
+
return {
|
|
1247
|
+
...s,
|
|
1248
|
+
unsubscribe: () => {
|
|
1249
|
+
s.unsubscribe();
|
|
1250
|
+
// Remove the keycommand from the list of listeners.
|
|
1251
|
+
const i = this.keyCommands.findIndex(c => c == item);
|
|
1252
|
+
this.keyCommands.splice(i, 1);
|
|
1253
|
+
}
|
|
1254
|
+
};
|
|
1255
|
+
})
|
|
1256
|
+
};
|
|
1257
|
+
}
|
|
1258
|
+
/**
|
|
1259
|
+
* Return `true` if shift is currently pressed.
|
|
1260
|
+
*/
|
|
1261
|
+
get isShiftPressed() {
|
|
1262
|
+
return !!this.heldKeys["shift"];
|
|
1263
|
+
}
|
|
1264
|
+
/**
|
|
1265
|
+
* Return `true` if ctrl is currently pressed.
|
|
1266
|
+
*/
|
|
1267
|
+
get isCtrlPressed() {
|
|
1268
|
+
return !!this.heldKeys["control"];
|
|
1269
|
+
}
|
|
1270
|
+
/**
|
|
1271
|
+
* Return `true` if alt is currently pressed.
|
|
1272
|
+
*/
|
|
1273
|
+
get isAltPressed() {
|
|
1274
|
+
return !!this.heldKeys["alt"];
|
|
1275
|
+
}
|
|
1276
|
+
/**
|
|
1277
|
+
* Return `true` if super (mac/linux) or the windows key is currently pressed.
|
|
1278
|
+
*/
|
|
1279
|
+
get isSuperPressed() {
|
|
1280
|
+
return !!this.heldKeys["super"];
|
|
1281
|
+
}
|
|
1282
|
+
/**
|
|
1283
|
+
* Return `true` if tab is currently pressed.
|
|
1284
|
+
*/
|
|
1285
|
+
get isTabPressed() {
|
|
1286
|
+
return !!this.heldKeys["tab"];
|
|
1287
|
+
}
|
|
1288
|
+
clearKeys() {
|
|
1289
|
+
Object.keys(this.heldKeys).forEach(k => {
|
|
1290
|
+
this.heldKeys[k] = false;
|
|
1291
|
+
});
|
|
1292
|
+
}
|
|
1293
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: KeyboardService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1294
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: KeyboardService, providedIn: 'root' }); }
|
|
1295
|
+
}
|
|
1296
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: KeyboardService, decorators: [{
|
|
1297
|
+
type: Injectable,
|
|
1298
|
+
args: [{
|
|
1299
|
+
providedIn: 'root'
|
|
1300
|
+
}]
|
|
1301
|
+
}], ctorParameters: () => [], propDecorators: { clearKeys: [{
|
|
1302
|
+
type: HostListener,
|
|
1303
|
+
args: ["window:blur"]
|
|
1304
|
+
}, {
|
|
1305
|
+
type: HostListener,
|
|
1306
|
+
args: ["window:resize"]
|
|
1307
|
+
}] } });
|
|
1308
|
+
|
|
1309
|
+
class NavigationService {
|
|
1310
|
+
constructor(lazyLoader) {
|
|
1311
|
+
this.lazyLoader = lazyLoader;
|
|
1312
|
+
this.virtualPath$ = new BehaviorSubject(null);
|
|
1313
|
+
// @ts-ignore
|
|
1314
|
+
window.onhashchange = () => this.loadRootPageFromUrl();
|
|
1315
|
+
this.loadRootPageFromUrl();
|
|
1316
|
+
}
|
|
1317
|
+
loadRootPageFromUrl() {
|
|
1318
|
+
const hash = location.hash.split("?")[0];
|
|
1319
|
+
const root = hash.replace(/^\/?#\//, '');
|
|
1320
|
+
// If the URL is imprecisely set, we restore it to the landing page
|
|
1321
|
+
if (!root || !root.trim())
|
|
1322
|
+
return this.loadRootPage("#/Landing");
|
|
1323
|
+
this.loadRootPage(location.hash);
|
|
1324
|
+
}
|
|
1325
|
+
loadRootPage(url, data = {}) {
|
|
1326
|
+
const [path, query] = url.split('?');
|
|
1327
|
+
const hash = path.replace(/^\/?#\/?/, '');
|
|
1328
|
+
const chunks = hash.split('/');
|
|
1329
|
+
// Get query params and pass them as @Input arguments.
|
|
1330
|
+
const params = query?.split('&')
|
|
1331
|
+
.reduce((pars, par) => {
|
|
1332
|
+
const [key, value] = par.split("=");
|
|
1333
|
+
const decoded = decodeURIComponent(value);
|
|
1334
|
+
pars[key] = decoded;
|
|
1335
|
+
return pars;
|
|
1336
|
+
}, {}) || {};
|
|
1337
|
+
console.info(`Root page navigate to '${hash}'`, { params, chunks });
|
|
1338
|
+
const root = hash.replace(/^\/?#\//, '');
|
|
1339
|
+
this.virtualPath$.next({
|
|
1340
|
+
root: hash,
|
|
1341
|
+
chunks: chunks,
|
|
1342
|
+
args: params
|
|
1343
|
+
});
|
|
1344
|
+
}
|
|
1345
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NavigationService, deps: [{ token: LazyLoaderService }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1346
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NavigationService, providedIn: 'root' }); }
|
|
1347
|
+
}
|
|
1348
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NavigationService, decorators: [{
|
|
1349
|
+
type: Injectable,
|
|
1350
|
+
args: [{
|
|
1351
|
+
providedIn: 'root'
|
|
1352
|
+
}]
|
|
1353
|
+
}], ctorParameters: () => [{ type: LazyLoaderService }] });
|
|
1354
|
+
|
|
1355
|
+
const verifyTheme = (theme) => {
|
|
1356
|
+
if (theme == 'dark' || theme == 'light')
|
|
1357
|
+
return theme;
|
|
1358
|
+
return 'auto';
|
|
1359
|
+
};
|
|
1360
|
+
const initialTheme = verifyTheme(localStorage['fiq.theme']);
|
|
1361
|
+
const initialDiscreteTheme = initialTheme != 'auto'
|
|
1362
|
+
? initialTheme
|
|
1363
|
+
: window.matchMedia('(prefers-color-scheme: dark)').matches
|
|
1364
|
+
? 'dark'
|
|
1365
|
+
: 'light';
|
|
1366
|
+
const getAutoTheme = () => {
|
|
1367
|
+
return window.matchMedia('(prefers-color-scheme: dark)').matches
|
|
1368
|
+
? 'dark'
|
|
1369
|
+
: 'light';
|
|
1370
|
+
};
|
|
1371
|
+
class ThemeService {
|
|
1372
|
+
constructor() {
|
|
1373
|
+
this.themes = [
|
|
1374
|
+
{ label: "Dark", id: 'dark' },
|
|
1375
|
+
{ label: "Light", id: 'light' },
|
|
1376
|
+
{ label: "Automatic", id: 'auto' },
|
|
1377
|
+
];
|
|
1378
|
+
this.selectedTheme = initialTheme;
|
|
1379
|
+
/**
|
|
1380
|
+
* This theme will always only be 'dark' or 'light'.
|
|
1381
|
+
* For use with canvases and similar libraries.
|
|
1382
|
+
*/
|
|
1383
|
+
this.theme = new BehaviorSubject(initialDiscreteTheme);
|
|
1384
|
+
this.theme.subscribe(t => {
|
|
1385
|
+
document.body.parentElement.classList.remove("theme-dark");
|
|
1386
|
+
document.body.parentElement.classList.remove("theme-light");
|
|
1387
|
+
document.body.parentElement.classList.add("theme-" + t);
|
|
1388
|
+
});
|
|
1389
|
+
// The system theme changed (either due to timed color themes or the user changing the mode)
|
|
1390
|
+
window.matchMedia('(prefers-color-scheme: dark)').addEventListener("change", ev => {
|
|
1391
|
+
if (localStorage['fiq.theme'] == "auto")
|
|
1392
|
+
this.theme.next(getAutoTheme());
|
|
1393
|
+
});
|
|
1394
|
+
}
|
|
1395
|
+
setTheme(t) {
|
|
1396
|
+
const theme = verifyTheme(t);
|
|
1397
|
+
localStorage['fiq.theme'] = theme;
|
|
1398
|
+
this.selectedTheme = theme;
|
|
1399
|
+
if (theme == 'auto') {
|
|
1400
|
+
this.theme.next(getAutoTheme());
|
|
1401
|
+
}
|
|
1402
|
+
else {
|
|
1403
|
+
this.theme.next(theme);
|
|
1404
|
+
}
|
|
1405
|
+
}
|
|
1406
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ThemeService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1407
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ThemeService, providedIn: 'root' }); }
|
|
1408
|
+
}
|
|
1409
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ThemeService, decorators: [{
|
|
1410
|
+
type: Injectable,
|
|
1411
|
+
args: [{
|
|
1412
|
+
providedIn: 'root'
|
|
1413
|
+
}]
|
|
1414
|
+
}], ctorParameters: () => [] });
|
|
1415
|
+
|
|
1416
|
+
class LazyLoaderModule {
|
|
1417
|
+
static forRoot(config) {
|
|
1418
|
+
return ({
|
|
1419
|
+
ngModule: LazyLoaderModule,
|
|
1420
|
+
providers: [
|
|
1421
|
+
{
|
|
1422
|
+
provide: NGX_LAZY_LOADER_CONFIG,
|
|
1423
|
+
useValue: config
|
|
1424
|
+
},
|
|
1425
|
+
LazyLoaderService
|
|
1426
|
+
]
|
|
1427
|
+
});
|
|
1428
|
+
}
|
|
1429
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: LazyLoaderModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
1430
|
+
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "17.3.12", ngImport: i0, type: LazyLoaderModule, imports: [LazyLoaderComponent], exports: [LazyLoaderComponent] }); }
|
|
1431
|
+
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: LazyLoaderModule }); }
|
|
1432
|
+
}
|
|
1433
|
+
__decorate([
|
|
1434
|
+
__param(0, Optional())
|
|
1435
|
+
], LazyLoaderModule, "forRoot", null);
|
|
1436
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: LazyLoaderModule, decorators: [{
|
|
1437
|
+
type: NgModule,
|
|
1438
|
+
args: [{
|
|
1439
|
+
imports: [LazyLoaderComponent],
|
|
1440
|
+
exports: [LazyLoaderComponent]
|
|
1441
|
+
}]
|
|
1442
|
+
}] });
|
|
1443
|
+
|
|
1444
|
+
class ParallaxCardComponent {
|
|
1445
|
+
get wrapper() { return this.element.nativeElement; }
|
|
1446
|
+
get cardFront() { return this.wrapper.querySelector('.card.front'); }
|
|
1447
|
+
get cardBack() { return this.wrapper.querySelector('.card.backface'); }
|
|
1448
|
+
get backgroundElement() { return this.cardFront.querySelector('.card-bg'); }
|
|
1449
|
+
get backfaceBackgroundElement() { return this.cardBack.querySelector('.card-bg'); }
|
|
1450
|
+
constructor(element, ngZone) {
|
|
1451
|
+
this.element = element;
|
|
1452
|
+
this.ngZone = ngZone;
|
|
1453
|
+
/**
|
|
1454
|
+
*
|
|
1455
|
+
*/
|
|
1456
|
+
this.loaded = new EventEmitter();
|
|
1457
|
+
/**
|
|
1458
|
+
* Width of the card
|
|
1459
|
+
* @default `240px`
|
|
1460
|
+
*/
|
|
1461
|
+
this.width = '240px';
|
|
1462
|
+
/**
|
|
1463
|
+
* Height of the card
|
|
1464
|
+
* @default `320px`
|
|
1465
|
+
*/
|
|
1466
|
+
this.height = '320px';
|
|
1467
|
+
/**
|
|
1468
|
+
* Inset padding of the parallax
|
|
1469
|
+
* @default 80
|
|
1470
|
+
*/
|
|
1471
|
+
this.bgInset = 80;
|
|
1472
|
+
/**
|
|
1473
|
+
* Duration for the flip animation in ms
|
|
1474
|
+
* @default 1200
|
|
1475
|
+
*/
|
|
1476
|
+
this.flipAnimationDuration = 1200;
|
|
1477
|
+
this.renderCardFront = true;
|
|
1478
|
+
this.renderCardBack = true;
|
|
1479
|
+
this.showBackOfCard = false;
|
|
1480
|
+
this.pointerX = 0;
|
|
1481
|
+
this.pointerY = 0;
|
|
1482
|
+
this.pointerLeave = 0;
|
|
1483
|
+
this.render = () => {
|
|
1484
|
+
const { width, height } = this.wrapper.getBoundingClientRect();
|
|
1485
|
+
const mousePX = this.pointerX / width;
|
|
1486
|
+
const mousePY = this.pointerY / height;
|
|
1487
|
+
// Rotation factors
|
|
1488
|
+
const rX = mousePX * this.bgInset / 1.75;
|
|
1489
|
+
const rY = mousePY * -this.bgInset / 1.75;
|
|
1490
|
+
// Translation factors
|
|
1491
|
+
const tX = mousePX * -this.bgInset * 2;
|
|
1492
|
+
const tY = mousePY * -this.bgInset * 2;
|
|
1493
|
+
if (this.renderCardFront) {
|
|
1494
|
+
this.backgroundElement.style.transform = `translateX(${tX}px) translateY(${tY}px)`;
|
|
1495
|
+
}
|
|
1496
|
+
if (this.renderCardBack) {
|
|
1497
|
+
this.backfaceBackgroundElement.style.transform = `translateX(${tX}px) translateY(${tY}px)`;
|
|
1498
|
+
}
|
|
1499
|
+
if (this.showBackOfCard) {
|
|
1500
|
+
this.cardFront.style.transform = `rotateY(180deg) rotateX(${-rY}deg)`;
|
|
1501
|
+
this.cardBack.style.transform = `rotateY(${-rX}deg) rotateX(${-rY}deg)`;
|
|
1502
|
+
}
|
|
1503
|
+
else {
|
|
1504
|
+
this.cardFront.style.transform = `rotateY(${rX}deg) rotateX(${rY}deg)`;
|
|
1505
|
+
this.cardBack.style.transform = `rotateY(180deg) rotateX(${-rY}deg)`;
|
|
1506
|
+
}
|
|
1507
|
+
};
|
|
1508
|
+
}
|
|
1509
|
+
ngAfterViewInit() {
|
|
1510
|
+
const el = this.wrapper;
|
|
1511
|
+
this.ngZone.runOutsideAngular(() => {
|
|
1512
|
+
// Directly attach events to the wrapper
|
|
1513
|
+
el.onpointermove = (e) => this.onPointerMove(e);
|
|
1514
|
+
el.onpointerenter = () => this.onPointerEnter();
|
|
1515
|
+
el.onpointerleave = () => this.onPointerLeave();
|
|
1516
|
+
});
|
|
1517
|
+
el.onclick = () => this.onClick();
|
|
1518
|
+
this.loaded.emit();
|
|
1519
|
+
}
|
|
1520
|
+
onPointerMove(e) {
|
|
1521
|
+
const { width, height, left, top } = this.wrapper.getBoundingClientRect();
|
|
1522
|
+
this.pointerX = e.pageX - left - (width / 2);
|
|
1523
|
+
this.pointerY = e.pageY - top - (height / 2);
|
|
1524
|
+
this.render();
|
|
1525
|
+
}
|
|
1526
|
+
onPointerEnter() {
|
|
1527
|
+
clearTimeout(this.pointerLeave);
|
|
1528
|
+
}
|
|
1529
|
+
onPointerLeave() {
|
|
1530
|
+
this.pointerLeave = setTimeout(() => {
|
|
1531
|
+
this.pointerX = 0;
|
|
1532
|
+
this.pointerY = 0;
|
|
1533
|
+
this.render();
|
|
1534
|
+
}, 600);
|
|
1535
|
+
}
|
|
1536
|
+
// TODO: This can get intercepted in some states
|
|
1537
|
+
onClick() {
|
|
1538
|
+
this.showBackOfCard = !this.showBackOfCard;
|
|
1539
|
+
this.render();
|
|
1540
|
+
}
|
|
1541
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ParallaxCardComponent, deps: [{ token: i0.ElementRef }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1542
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: ParallaxCardComponent, isStandalone: true, selector: "ngx-parallax-card", inputs: { width: "width", height: "height", bgInset: "bgInset", flipAnimationDuration: "flipAnimationDuration" }, outputs: { loaded: "loaded" }, host: { properties: { "style.width": "width", "style.height": "height", "style.--card-bg-inset": "-bgInset+\"px\"", "style.--flip-animation-duration": "flipAnimationDuration+\"ms\"", "class.flip": "showBackOfCard" } }, queries: [{ propertyName: "content", first: true, predicate: ["content"], descendants: true, read: TemplateRef }, { propertyName: "background", first: true, predicate: ["background"], descendants: true, read: TemplateRef }, { propertyName: "backContent", first: true, predicate: ["backContent"], descendants: true, read: TemplateRef }, { propertyName: "backBackground", first: true, predicate: ["backBackground"], descendants: true, read: TemplateRef }], ngImport: i0, template: "@if (renderCardBack) {\n <div class=\"card backface\">\n <div class=\"card-bg\" style=\"transform: translateX(0) translateY(0)\">\n <ng-template [ngTemplateOutlet]=\"backBackground\" />\n </div>\n <div class=\"card-content\">\n <ng-template [ngTemplateOutlet]=\"backContent\" />\n </div>\n </div>\n}\n\n@if (renderCardFront) {\n <div class=\"card front\">\n <div class=\"card-bg\" style=\"transform: translateX(0) translateY(0)\">\n <ng-template [ngTemplateOutlet]=\"background\" />\n </div>\n <div class=\"card-content\">\n @if (content) {\n <ng-template [ngTemplateOutlet]=\"content\"/>\n }\n @else {\n <ng-content/>\n }\n </div>\n </div>\n}\n\n\n", styles: [":host{display:block;position:relative;cursor:pointer;--easing-function: cubic-bezier(.23, 1, .32, 1);--border-radius: 9px}.card{position:absolute;height:100%;width:100%;background-color:#333;backface-visibility:hidden;overflow:hidden;box-shadow:#0000 0 0 40px 5px,#000000a8 0 30px 60px,inset #333 0 0 0 5px;border-radius:var(--border-radius);transition:transform var(--flip-animation-duration) var(--easing-function),box-shadow 2s var(--easing-function);transform-style:preserve-3d;will-change:transform}.card:hover{box-shadow:#fff6 0 0 40px 5px,#000000a8 0 30px 60px,inset #333 0 0 0 5px}.card:hover .card-content{border:2px solid #fff}.card-bg{inset:var(--card-bg-inset);position:absolute;pointer-events:none;transition:transform .6s var(--easing-function)}.card-content{position:absolute;top:0;color:#fff;height:100%;width:100%;z-index:1;border:2px solid rgba(255,255,255,0);border-radius:var(--border-radius);transition:transform .6s var(--easing-function),border-color .6s var(--easing-function)}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] }); }
|
|
1543
|
+
}
|
|
1544
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ParallaxCardComponent, decorators: [{
|
|
1545
|
+
type: Component,
|
|
1546
|
+
args: [{ selector: 'ngx-parallax-card', imports: [
|
|
1547
|
+
NgTemplateOutlet
|
|
1548
|
+
], host: {
|
|
1549
|
+
'[style.width]': 'width',
|
|
1550
|
+
'[style.height]': 'height',
|
|
1551
|
+
'[style.--card-bg-inset]': '-bgInset+"px"',
|
|
1552
|
+
'[style.--flip-animation-duration]': 'flipAnimationDuration+"ms"',
|
|
1553
|
+
'[class.flip]': 'showBackOfCard'
|
|
1554
|
+
}, standalone: true, template: "@if (renderCardBack) {\n <div class=\"card backface\">\n <div class=\"card-bg\" style=\"transform: translateX(0) translateY(0)\">\n <ng-template [ngTemplateOutlet]=\"backBackground\" />\n </div>\n <div class=\"card-content\">\n <ng-template [ngTemplateOutlet]=\"backContent\" />\n </div>\n </div>\n}\n\n@if (renderCardFront) {\n <div class=\"card front\">\n <div class=\"card-bg\" style=\"transform: translateX(0) translateY(0)\">\n <ng-template [ngTemplateOutlet]=\"background\" />\n </div>\n <div class=\"card-content\">\n @if (content) {\n <ng-template [ngTemplateOutlet]=\"content\"/>\n }\n @else {\n <ng-content/>\n }\n </div>\n </div>\n}\n\n\n", styles: [":host{display:block;position:relative;cursor:pointer;--easing-function: cubic-bezier(.23, 1, .32, 1);--border-radius: 9px}.card{position:absolute;height:100%;width:100%;background-color:#333;backface-visibility:hidden;overflow:hidden;box-shadow:#0000 0 0 40px 5px,#000000a8 0 30px 60px,inset #333 0 0 0 5px;border-radius:var(--border-radius);transition:transform var(--flip-animation-duration) var(--easing-function),box-shadow 2s var(--easing-function);transform-style:preserve-3d;will-change:transform}.card:hover{box-shadow:#fff6 0 0 40px 5px,#000000a8 0 30px 60px,inset #333 0 0 0 5px}.card:hover .card-content{border:2px solid #fff}.card-bg{inset:var(--card-bg-inset);position:absolute;pointer-events:none;transition:transform .6s var(--easing-function)}.card-content{position:absolute;top:0;color:#fff;height:100%;width:100%;z-index:1;border:2px solid rgba(255,255,255,0);border-radius:var(--border-radius);transition:transform .6s var(--easing-function),border-color .6s var(--easing-function)}\n"] }]
|
|
1555
|
+
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.NgZone }], propDecorators: { content: [{
|
|
1556
|
+
type: ContentChild,
|
|
1557
|
+
args: ['content', { read: TemplateRef }]
|
|
1558
|
+
}], background: [{
|
|
1559
|
+
type: ContentChild,
|
|
1560
|
+
args: ['background', { read: TemplateRef }]
|
|
1561
|
+
}], backContent: [{
|
|
1562
|
+
type: ContentChild,
|
|
1563
|
+
args: ['backContent', { read: TemplateRef }]
|
|
1564
|
+
}], backBackground: [{
|
|
1565
|
+
type: ContentChild,
|
|
1566
|
+
args: ['backBackground', { read: TemplateRef }]
|
|
1567
|
+
}], loaded: [{
|
|
1568
|
+
type: Output
|
|
1569
|
+
}], width: [{
|
|
1570
|
+
type: Input
|
|
1571
|
+
}], height: [{
|
|
1572
|
+
type: Input
|
|
1573
|
+
}], bgInset: [{
|
|
1574
|
+
type: Input
|
|
1575
|
+
}], flipAnimationDuration: [{
|
|
1576
|
+
type: Input
|
|
1577
|
+
}] } });
|
|
1578
|
+
|
|
1579
|
+
const NGX_WEB_COMPONENTS_CONFIG = new InjectionToken('webcomponents-config');
|
|
1580
|
+
|
|
1581
|
+
const zone = new Zone(Zone.current, { name: "@dotglitch_menu", properties: {} });
|
|
1582
|
+
const calcMenuItemBounds = async (menuItems, dataObj) => {
|
|
1583
|
+
const data = {
|
|
1584
|
+
data: dataObj,
|
|
1585
|
+
items: menuItems,
|
|
1586
|
+
config: {},
|
|
1587
|
+
selfCords: { left: "0px", top: "0px" },
|
|
1588
|
+
ownerCords: { x: 0, y: 0, width: 0, height: 0 },
|
|
1589
|
+
id: null
|
|
1590
|
+
};
|
|
1591
|
+
return calcComponentBounds(MenuComponent, data);
|
|
1592
|
+
};
|
|
1593
|
+
const calcComponentBounds = async (component, data) => {
|
|
1594
|
+
return new Promise((res, rej) => {
|
|
1595
|
+
zone.run(async () => {
|
|
1596
|
+
const app = await createApplication({
|
|
1597
|
+
providers: [
|
|
1598
|
+
{ provide: MAT_DIALOG_DATA, useValue: data }
|
|
1599
|
+
]
|
|
1600
|
+
});
|
|
1601
|
+
const del = document.createElement("div");
|
|
1602
|
+
del.classList.add("ngx-menu");
|
|
1603
|
+
del.style.position = "absolute";
|
|
1604
|
+
del.style.left = '-1000vw';
|
|
1605
|
+
document.body.append(del);
|
|
1606
|
+
const base = app.bootstrap(component, del);
|
|
1607
|
+
const { instance } = base;
|
|
1608
|
+
await firstValueFrom(app.isStable);
|
|
1609
|
+
const el = instance.viewContainer?.element?.nativeElement;
|
|
1610
|
+
const rect = el.getBoundingClientRect();
|
|
1611
|
+
app.destroy();
|
|
1612
|
+
del.remove();
|
|
1613
|
+
res(rect);
|
|
1614
|
+
});
|
|
1615
|
+
});
|
|
1616
|
+
};
|
|
1617
|
+
const $data = Symbol("data");
|
|
1618
|
+
const $hover = Symbol("hover");
|
|
1619
|
+
class MenuComponent {
|
|
1620
|
+
constructor(viewContainer, sanitizer, _data, dialog, // optional only for the purpose of estimating dimensions
|
|
1621
|
+
dialogRef) {
|
|
1622
|
+
this.viewContainer = viewContainer;
|
|
1623
|
+
this.sanitizer = sanitizer;
|
|
1624
|
+
this._data = _data;
|
|
1625
|
+
this.dialog = dialog;
|
|
1626
|
+
this.dialogRef = dialogRef;
|
|
1627
|
+
this.overlayOverlap = 32;
|
|
1628
|
+
this.hoverDelay = 400;
|
|
1629
|
+
this.showDebugOverlay = false;
|
|
1630
|
+
this.isLockedOpen = false;
|
|
1631
|
+
this.hasBootstrapped = false;
|
|
1632
|
+
this.pointerIsOnVoid = false;
|
|
1633
|
+
this.pointerHasBeenOverMask = false;
|
|
1634
|
+
this.parentIsNgxMenu = false;
|
|
1635
|
+
this.coverRectCords = {
|
|
1636
|
+
top: 0,
|
|
1637
|
+
left: 0,
|
|
1638
|
+
height: 0,
|
|
1639
|
+
width: 0
|
|
1640
|
+
};
|
|
1641
|
+
// Check if there are any slashes or dots -- that will clearly exclude it from being a mat icon
|
|
1642
|
+
this.matIconRx = /[\/\.]/i;
|
|
1643
|
+
this.showIconColumn = true;
|
|
1644
|
+
this.showShortcutColumn = true;
|
|
1645
|
+
this.childDialogs = [];
|
|
1646
|
+
// Defaults are set before @Input() hooks evaluate
|
|
1647
|
+
this.dialog = this.dialog || this._data?.dialog;
|
|
1648
|
+
this.data = this._data?.data;
|
|
1649
|
+
this.ownerCords = this._data?.ownerCords;
|
|
1650
|
+
this.selfCords = this._data?.selfCords;
|
|
1651
|
+
this.items = this._data?.items;
|
|
1652
|
+
this.config = this._data?.config;
|
|
1653
|
+
this.id = this._data?.id;
|
|
1654
|
+
this.parentItem = this._data?.parentItem;
|
|
1655
|
+
this.parentContext = this._data?.parentContext;
|
|
1656
|
+
this.isLockedOpen = this.isLockedOpen || this._data?.config?.['_isLockedOpen'];
|
|
1657
|
+
this.parentIsNgxMenu = this._data?.parentIsNgxMenu;
|
|
1658
|
+
this.targetBounds = this._data?.targetBounds;
|
|
1659
|
+
this.template = this._data?.template;
|
|
1660
|
+
this.templateType = this.template instanceof TemplateRef ? "template" : "component";
|
|
1661
|
+
if (this.templateType == "component") {
|
|
1662
|
+
this.componentPortal = new ComponentPortal(this.template);
|
|
1663
|
+
}
|
|
1664
|
+
}
|
|
1665
|
+
ngOnInit() {
|
|
1666
|
+
this.items?.forEach(i => {
|
|
1667
|
+
if (typeof i == "string")
|
|
1668
|
+
return;
|
|
1669
|
+
// Set defaults
|
|
1670
|
+
i['_disabled'] = false;
|
|
1671
|
+
i['_visible'] = true;
|
|
1672
|
+
i['_context'] = (typeof i.context == "function")
|
|
1673
|
+
? i.context(this.data)
|
|
1674
|
+
: i.context;
|
|
1675
|
+
if (i.label)
|
|
1676
|
+
try {
|
|
1677
|
+
i['_formattedLabel'] = this.formatLabel(i.label);
|
|
1678
|
+
}
|
|
1679
|
+
catch (e) {
|
|
1680
|
+
console.warn(e);
|
|
1681
|
+
}
|
|
1682
|
+
if (typeof i.isDisabled == "function")
|
|
1683
|
+
try {
|
|
1684
|
+
i['_disabled'] = i.isDisabled(this.data || {}, i['_context']);
|
|
1685
|
+
}
|
|
1686
|
+
catch (e) {
|
|
1687
|
+
console.warn(e);
|
|
1688
|
+
}
|
|
1689
|
+
if (typeof i.isVisible == "function")
|
|
1690
|
+
try {
|
|
1691
|
+
i['_visible'] = i.isVisible(this.data || {}, i['_context']);
|
|
1692
|
+
}
|
|
1693
|
+
catch (e) {
|
|
1694
|
+
console.warn(e);
|
|
1695
|
+
}
|
|
1696
|
+
if (typeof i.linkTemplate == "function")
|
|
1697
|
+
try {
|
|
1698
|
+
i['_link'] = i.linkTemplate(this.data || {}, i['_context']);
|
|
1699
|
+
}
|
|
1700
|
+
catch (e) {
|
|
1701
|
+
console.warn(e);
|
|
1702
|
+
}
|
|
1703
|
+
if (typeof i.iconTemplate == "function")
|
|
1704
|
+
try {
|
|
1705
|
+
i['_icon'] = i.iconTemplate(this.data || {}, i['_context']);
|
|
1706
|
+
}
|
|
1707
|
+
catch (e) {
|
|
1708
|
+
console.warn(e);
|
|
1709
|
+
}
|
|
1710
|
+
});
|
|
1711
|
+
// Show the icon column if there are any items with an icon
|
|
1712
|
+
this.showIconColumn = !!this.items?.find(i => typeof i == "object" &&
|
|
1713
|
+
typeof i['icon'] == "string" &&
|
|
1714
|
+
i['icon'].length > 2);
|
|
1715
|
+
this.showShortcutColumn = !!this.items?.find(i => typeof i == "object" &&
|
|
1716
|
+
typeof i['shortcut'] == "string" &&
|
|
1717
|
+
i['shortcut'].length > 2);
|
|
1718
|
+
if (this.ownerCords) {
|
|
1719
|
+
const selfY = parseInt(this.selfCords.top?.replace('px', '') || '0');
|
|
1720
|
+
const selfX = parseInt(this.selfCords.left?.replace('px', '') || '0');
|
|
1721
|
+
this.coverRectCords = {
|
|
1722
|
+
top: this.ownerCords.y - selfY - (this.overlayOverlap / 2),
|
|
1723
|
+
left: this.ownerCords.x - selfX - (this.overlayOverlap / 2),
|
|
1724
|
+
height: this.ownerCords.height + this.overlayOverlap,
|
|
1725
|
+
width: this.ownerCords.width + this.overlayOverlap
|
|
1726
|
+
};
|
|
1727
|
+
}
|
|
1728
|
+
if (this.config?.stayOpen)
|
|
1729
|
+
this.isLockedOpen = true;
|
|
1730
|
+
setTimeout(() => {
|
|
1731
|
+
this.hasBootstrapped = true;
|
|
1732
|
+
}, 200);
|
|
1733
|
+
}
|
|
1734
|
+
ngAfterViewInit() {
|
|
1735
|
+
const el = this.viewContainer.element.nativeElement;
|
|
1736
|
+
el.addEventListener("keydown", evt => {
|
|
1737
|
+
this.isLockedOpen = true;
|
|
1738
|
+
});
|
|
1739
|
+
el.addEventListener("pointerdown", evt => {
|
|
1740
|
+
this.isLockedOpen = true;
|
|
1741
|
+
});
|
|
1742
|
+
el.addEventListener("touch", evt => {
|
|
1743
|
+
this.isLockedOpen = true;
|
|
1744
|
+
});
|
|
1745
|
+
}
|
|
1746
|
+
ngOnDestroy() {
|
|
1747
|
+
//
|
|
1748
|
+
this.childDialogs.forEach(d => d.close({ [$data]: true }));
|
|
1749
|
+
}
|
|
1750
|
+
/**
|
|
1751
|
+
*
|
|
1752
|
+
*/
|
|
1753
|
+
async onMenuItemClick(item, row, keepOpen = false) {
|
|
1754
|
+
if (typeof item == 'string')
|
|
1755
|
+
return null;
|
|
1756
|
+
if (item.separator)
|
|
1757
|
+
return null;
|
|
1758
|
+
const context = await item['_context'];
|
|
1759
|
+
// If cache is enabled, only load if we don't have any children.
|
|
1760
|
+
const forceLoad = (item.cacheResolvedChildren ? !item.children : true);
|
|
1761
|
+
if (item.childrenResolver && forceLoad) {
|
|
1762
|
+
item['_isResolving'] = true;
|
|
1763
|
+
item['_children'] = await item.childrenResolver(this.data, context);
|
|
1764
|
+
item['_isResolving'] = false;
|
|
1765
|
+
}
|
|
1766
|
+
else if (typeof item.children == "function" && forceLoad) {
|
|
1767
|
+
item['_isResolving'] = true;
|
|
1768
|
+
item['_children'] = await item.children(this.data, context);
|
|
1769
|
+
item['_isResolving'] = false;
|
|
1770
|
+
}
|
|
1771
|
+
else {
|
|
1772
|
+
item['_children'] = item.children;
|
|
1773
|
+
}
|
|
1774
|
+
if (item['_children'] || item.childTemplate)
|
|
1775
|
+
row['_open'] = true;
|
|
1776
|
+
if (!item.childTemplate && !item.children) {
|
|
1777
|
+
if (typeof item.action == "function") {
|
|
1778
|
+
const res = await item.action(this.data, context);
|
|
1779
|
+
this.close(res === undefined ? true : res);
|
|
1780
|
+
return res;
|
|
1781
|
+
}
|
|
1782
|
+
// If no action, this is simply a text item.
|
|
1783
|
+
return null;
|
|
1784
|
+
}
|
|
1785
|
+
// Need X pos, Y pos, width and height
|
|
1786
|
+
const bounds = row.getBoundingClientRect();
|
|
1787
|
+
const cords = {
|
|
1788
|
+
top: null,
|
|
1789
|
+
left: null,
|
|
1790
|
+
bottom: null,
|
|
1791
|
+
// right: null
|
|
1792
|
+
};
|
|
1793
|
+
// Set position coordinates
|
|
1794
|
+
const targetBounds = await (item.childTemplate
|
|
1795
|
+
? calcComponentBounds(MenuComponent, { template: item.childTemplate })
|
|
1796
|
+
: calcMenuItemBounds(item['_children'], this.data));
|
|
1797
|
+
const { width, height } = targetBounds;
|
|
1798
|
+
if (bounds.y + height > window.innerHeight)
|
|
1799
|
+
cords.bottom = "0px";
|
|
1800
|
+
if (bounds.x + bounds.width + width > window.innerWidth)
|
|
1801
|
+
cords.left = ((bounds.x - width)) + "px";
|
|
1802
|
+
if (!cords.bottom)
|
|
1803
|
+
cords.top = bounds.y + "px";
|
|
1804
|
+
if (!cords.left)
|
|
1805
|
+
cords.left = bounds.x + bounds.width + "px";
|
|
1806
|
+
const config = structuredClone(this.config);
|
|
1807
|
+
config['_isLockedOpen'] = keepOpen;
|
|
1808
|
+
// Do not project in the top left corner -- this scenario
|
|
1809
|
+
// happens when a dialog opens as the parent is killed.
|
|
1810
|
+
if (cords.left == '0px' && cords.top == '0px')
|
|
1811
|
+
return;
|
|
1812
|
+
const dialogRef = this.dialog.open(MenuComponent, {
|
|
1813
|
+
position: cords,
|
|
1814
|
+
panelClass: ["ngx-menu"].concat(this.config?.customClass || []),
|
|
1815
|
+
backdropClass: "ngx-menu-backdrop",
|
|
1816
|
+
hasBackdrop: false,
|
|
1817
|
+
data: {
|
|
1818
|
+
data: this.data,
|
|
1819
|
+
ownerCords: row.getBoundingClientRect(),
|
|
1820
|
+
selfCords: cords,
|
|
1821
|
+
parentItem: item,
|
|
1822
|
+
parentContext: context,
|
|
1823
|
+
items: item['_children'],
|
|
1824
|
+
template: item.childTemplate,
|
|
1825
|
+
config: config,
|
|
1826
|
+
parentIsNgxMenu: true,
|
|
1827
|
+
targetBounds
|
|
1828
|
+
}
|
|
1829
|
+
});
|
|
1830
|
+
let _s = dialogRef
|
|
1831
|
+
.afterClosed()
|
|
1832
|
+
.subscribe(async (result) => {
|
|
1833
|
+
// Clicked "void" on a submenu
|
|
1834
|
+
if (typeof result == "object" && result[$data] == true) {
|
|
1835
|
+
this.close(result);
|
|
1836
|
+
}
|
|
1837
|
+
// Went back to parent menu -- do not close (same as result == null)
|
|
1838
|
+
else if (typeof result == "object" && result[$data] == false) {
|
|
1839
|
+
}
|
|
1840
|
+
// Got some other result value
|
|
1841
|
+
else if (result != null) {
|
|
1842
|
+
// Perform action callback
|
|
1843
|
+
if (typeof item.action == 'function') {
|
|
1844
|
+
this.close(await item.action(result, context));
|
|
1845
|
+
}
|
|
1846
|
+
// Just close.
|
|
1847
|
+
else {
|
|
1848
|
+
this.close();
|
|
1849
|
+
}
|
|
1850
|
+
}
|
|
1851
|
+
row['_open'] = false;
|
|
1852
|
+
this.childDialogs.splice(this.childDialogs.indexOf(dialogRef), 1);
|
|
1853
|
+
_s.unsubscribe();
|
|
1854
|
+
});
|
|
1855
|
+
this.childDialogs.push(dialogRef);
|
|
1856
|
+
return dialogRef;
|
|
1857
|
+
}
|
|
1858
|
+
/**
|
|
1859
|
+
*
|
|
1860
|
+
* @param label
|
|
1861
|
+
* @returns
|
|
1862
|
+
*/
|
|
1863
|
+
formatLabel(label) {
|
|
1864
|
+
return label.replace(/_([a-z0-9])_/i, (match, group) => `<u>${group}</u>`);
|
|
1865
|
+
}
|
|
1866
|
+
/**
|
|
1867
|
+
* Close the context menu under these circumstances
|
|
1868
|
+
*/
|
|
1869
|
+
// @HostListener("window:resize", ['event'])
|
|
1870
|
+
// @HostListener("window:blur", ['event'])
|
|
1871
|
+
close(result) {
|
|
1872
|
+
this.childDialogs.forEach(d => d.close());
|
|
1873
|
+
this.dialogRef?.close(result);
|
|
1874
|
+
}
|
|
1875
|
+
closeOnVoid(force = false) {
|
|
1876
|
+
if (!this.isLockedOpen || force) {
|
|
1877
|
+
this.close({ [$data]: force });
|
|
1878
|
+
}
|
|
1879
|
+
}
|
|
1880
|
+
startHoverTimer(item, row) {
|
|
1881
|
+
// Invert check to make the logic simpler
|
|
1882
|
+
// TL;DR: if (any) of these are true, we will do the hover action
|
|
1883
|
+
if (!(Array.isArray(item.children) && item.children.length > 0 ||
|
|
1884
|
+
typeof item.children == "function" ||
|
|
1885
|
+
item.childTemplate ||
|
|
1886
|
+
item.childrenResolver))
|
|
1887
|
+
return;
|
|
1888
|
+
item[$hover] = setTimeout(() => {
|
|
1889
|
+
delete item[$hover];
|
|
1890
|
+
if (!this.pointerIsOnVoid) {
|
|
1891
|
+
this.childDialogs.forEach(cd => cd.close());
|
|
1892
|
+
row['_open'] = true;
|
|
1893
|
+
this.onMenuItemClick(item, row);
|
|
1894
|
+
}
|
|
1895
|
+
}, this.hoverDelay);
|
|
1896
|
+
}
|
|
1897
|
+
stopHoverTimer(item) {
|
|
1898
|
+
item[$hover] && clearTimeout(item[$hover]);
|
|
1899
|
+
delete item[$hover];
|
|
1900
|
+
}
|
|
1901
|
+
startCloseTimer() {
|
|
1902
|
+
this.closeTimer = setTimeout(() => {
|
|
1903
|
+
this.closeOnVoid();
|
|
1904
|
+
}, 500);
|
|
1905
|
+
}
|
|
1906
|
+
stopCloseTimer() {
|
|
1907
|
+
clearTimeout(this.closeTimer);
|
|
1908
|
+
}
|
|
1909
|
+
/**
|
|
1910
|
+
* Check if the dialog is clipping offscreen
|
|
1911
|
+
* if so, move it back into view.
|
|
1912
|
+
*/
|
|
1913
|
+
onResize() {
|
|
1914
|
+
const el = this.viewContainer?.element?.nativeElement;
|
|
1915
|
+
if (!el)
|
|
1916
|
+
return;
|
|
1917
|
+
const { width, height, x, y } = el.getBoundingClientRect();
|
|
1918
|
+
const target = document.querySelector(".ngx-menu");
|
|
1919
|
+
if (!target)
|
|
1920
|
+
return;
|
|
1921
|
+
// Move back into view if we're clipping outside of the bottom
|
|
1922
|
+
if (y + height > window.innerHeight) {
|
|
1923
|
+
const newTop = (window.innerHeight - (height + (this.config.edgePadding || 12))) + "px";
|
|
1924
|
+
target.style['margin-top'] = newTop;
|
|
1925
|
+
}
|
|
1926
|
+
// Move back into view if we're clipping off the right
|
|
1927
|
+
if (x + width > window.innerWidth) {
|
|
1928
|
+
const newLeft = (window.innerWidth - (width + (this.config.edgePadding || 12))) + "px";
|
|
1929
|
+
target.style['margin-left'] = newLeft;
|
|
1930
|
+
}
|
|
1931
|
+
}
|
|
1932
|
+
// If the void element gets stuck open, make wheel events pass through.
|
|
1933
|
+
onWheel(evt) {
|
|
1934
|
+
const el = this.viewContainer.element.nativeElement;
|
|
1935
|
+
el.style.display = "none";
|
|
1936
|
+
const target = document.elementFromPoint(evt.clientX, evt.clientY);
|
|
1937
|
+
el.style.display = "block";
|
|
1938
|
+
target.scroll({
|
|
1939
|
+
top: evt.deltaY + target.scrollTop,
|
|
1940
|
+
left: evt.deltaX + target.scrollLeft,
|
|
1941
|
+
behavior: "smooth"
|
|
1942
|
+
});
|
|
1943
|
+
}
|
|
1944
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: MenuComponent, deps: [{ token: i0.ViewContainerRef }, { token: i1.DomSanitizer }, { token: MAT_DIALOG_DATA, optional: true }, { token: i2$1.MatDialog, optional: true }, { token: i2$1.MatDialogRef, optional: true }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1945
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: MenuComponent, isStandalone: true, selector: "ngx-menu", inputs: { data: "data", items: "items", config: "config", id: "id", overlayOverlap: "overlayOverlap", hoverDelay: "hoverDelay", showDebugOverlay: "showDebugOverlay", targetBounds: "targetBounds", ownerCords: "ownerCords", selfCords: "selfCords", parentItem: "parentItem", parentContext: "parentContext", isLockedOpen: "isLockedOpen" }, host: { listeners: { "window:resize": "onResize()" }, properties: { "attr.tx": "targetBounds?.x", "attr.ty": "targetBounds?.y", "attr.th": "targetBounds?.height", "attr.tw": "targetBounds?.width" } }, ngImport: i0, template: "<!-- Mouse event blocker for pointer leave -->\n@if (coverRectCords && !parentIsNgxMenu) {\n <div\n class=\"owner-mask\"\n [style.top]=\"coverRectCords.top + 'px'\"\n [style.left]=\"coverRectCords.left + 'px'\"\n [style.height]=\"coverRectCords.height + 'px'\"\n [style.width]=\"coverRectCords.width + 'px'\"\n [style.background]=\"showDebugOverlay ? '#f004' : '#0000'\"\n style=\"z-index: -1\"\n (pointerenter)=\"pointerHasBeenOverMask=true\"\n (pointerleave)=\"stopCloseTimer()\"\n (pointermove)=\"pointerHasBeenOverMask=true\"\n (click)=\"isLockedOpen = true\"\n ></div>\n}\n\n@if (!parentIsNgxMenu) {\n <div class=\"void\"\n [style.background]=\"showDebugOverlay ? '#00f4' : '#0000'\"\n (pointerenter)=\"pointerIsOnVoid = true; hasBootstrapped && !isLockedOpen && startCloseTimer()\"\n (pointerleave)=\"pointerIsOnVoid = false\"\n (pointerdown)=\"hasBootstrapped && closeOnVoid(true)\"\n (pointermove)=\"hasBootstrapped && !isLockedOpen && startCloseTimer()\"\n (click)=\"closeOnVoid(true)\"\n (wheel)=\"onWheel($event)\"\n ></div>\n}\n\n@if (!template) {\n <table (pointerenter)=\"stopCloseTimer()\">\n <tbody>\n @for (item of items; track item) {\n <!-- A row with a click action -->\n @if (item != 'separator' && item.separator != true && item['_visible']) {\n <tr #row\n [class.disabled]=\"item['_disabled']\"\n (click)=\"!item['_disabled'] && onMenuItemClick(item, row, true)\"\n [class.hover]=\"row['hover']\"\n [class.open]=\"row['_open']\"\n (pointerenter)=\"row['hover'] = true; startHoverTimer(item, row)\"\n (pointerleave)=\"row['hover'] = false; stopHoverTimer(item)\"\n >\n\n @if (showIconColumn) {\n <td class=\"icon\">\n @if (matIconRx.test(item['_icon'] ?? item.icon)) {\n <img [src]=\"item['_icon'] ?? item.icon\"/>\n }\n @else {\n <mat-icon\n [fontIcon]=\"item['_icon'] ?? item.icon\"\n [style.color]=\"item.iconColor\"\n />\n }\n </td>\n }\n\n <!-- 'Normal' action based item -->\n <td class=\"label\"\n [style.padding-left]=\"showIconColumn ? 0 : '16px'\"\n >\n <a\n #anchor\n [attr.target]=\"item.linkTarget\"\n [attr.href]=\"(item['_link'] || item.link) ? sanitizer.bypassSecurityTrustUrl(item['_link'] || item.link) : undefined\"\n >\n @if ($any(item.labelTemplate)?.prototype) {\n <ng-container\n [ngTemplateOutlet]=\"$any(item).labelTemplate\"\n [ngTemplateOutletContext]=\"{\n '$implicit': data,\n 'dialog': dialogRef,\n 'context': item['_context'],\n 'item': item,\n 'element': anchor,\n 'menu': this\n }\"\n />\n }\n @else {\n @if ($any(item)?.labelTemplate) {\n {{$any(item)?.labelTemplate(data || {})}}\n }\n @else {\n <div [innerHTML]=\"item['_formattedLabel']\"></div>\n }\n }\n </a>\n </td>\n\n @if (showShortcutColumn) {\n <td class=\"shortcut\">\n {{item.shortcutLabel}}\n </td>\n }\n\n <td style=\"min-width: 16px\">\n @if ((\n (item['children']?.length > 0) ||\n (item['_children']?.length > 0) ||\n item.childTemplate ||\n item.children?.['call'] ||\n item.childrenResolver\n ) &&\n !item['_isResolving']\n ) {\n <mat-icon\n style=\"transform: translateY(2px)\"\n >\n chevron_right\n </mat-icon>\n }\n\n @if (item['_isResolving']) {\n <mat-progress-spinner\n mode=\"indeterminate\"\n [diameter]=\"20\"\n style=\"margin-right: 4px\"\n />\n }\n </td>\n </tr>\n }\n @else if (item != 'separator' && item.separator == true) {\n <!-- Separator with label -->\n <tr\n class=\"disabled separator\"\n >\n <td\n class=\"center\"\n [attr.colspan]=\"2 + (showIconColumn ? 1 : 0) + (showShortcutColumn ? 1 : 0)\"\n >\n <span class=\"hr\">\n {{item['label'] || ''}}\n </span>\n </td>\n </tr>\n }\n @else if (item == 'separator') {\n <!-- Separator -->\n <tr\n class=\"disabled separator\"\n >\n <td\n [attr.colspan]=\"2 + (showIconColumn ? 1 : 0) + (showShortcutColumn ? 1 : 0)\"\n >\n <hr/>\n </td>\n </tr>\n }\n }\n </tbody>\n </table>\n}\n@else {\n @if (templateType == 'template') {\n <div style=\"display: contents;\" (pointerenter)=\"stopCloseTimer()\">\n <ng-container\n [ngTemplateOutlet]=\"template\"\n [ngTemplateOutletContext]=\"{\n '$implicit': data,\n 'dialog': dialogRef,\n 'context': parentContext,\n 'item': parentItem,\n 'element': this.viewContainer?.element?.nativeElement,\n 'menu': this\n }\"\n />\n </div>\n }\n @else {\n <div style=\"display: contents;\" (pointerenter)=\"stopCloseTimer()\">\n <ng-container\n [cdkPortalOutlet]=\"componentPortal\"\n />\n </div>\n }\n}\n\n@if (showDebugOverlay) {\n <div>\n <div>hbs: {{hasBootstrapped}}</div>\n <div>pov: {{pointerIsOnVoid}}</div>\n <div>ilo: {{isLockedOpen}}</div>\n <div>hbom: {{pointerHasBeenOverMask}}</div>\n\n <div>type: {{templateType}}</div>\n </div>\n}\n", styles: ["::ng-deep .cdk-overlay-container .ngx-menu{--mdc-dialog-container-color: var(--ngx-menu-background-color, #2f2f2f)}::ng-deep .cdk-overlay-container .ngx-menu .mdc-dialog__container{transform-origin:top left}::ng-deep .cdk-overlay-container .ngx-menu .mdc-dialog--open .mdc-dialog__container{transform:none}::ng-deep .cdk-overlay-pane.ngx-menu .mat-mdc-dialog-surface{overflow:visible}:host{-webkit-user-select:none;user-select:none;z-index:1;position:relative;display:block}table{border-spacing:0;border-radius:5px;padding:4px 0;overflow:hidden}tr{color:var(--ngx-menu-text-color, #ccc);font-size:var(--ngx-menu-font-size, 14px);cursor:pointer;transition:background-color 75ms ease,color 75ms ease}tr:not(.disabled).hover,tr:not(.disabled).open{background-color:var(--ngx-menu-hover-background-color, #94ebeb);color:var(--ngx-menu-hover-text-color, #000)}tr:not(.disabled).hover a,tr:not(.disabled).open a{color:var(--ngx-menu-hover-text-color, #000)}tr:not(.separator){height:36px}tr.disabled .label{color:var(--ngx-menu-disabled-text-color, #919191)}tr .center{text-align:center}tr a{outline:0;display:flex;align-items:center;gap:10px;justify-content:space-between;height:100%;width:100%;position:relative;left:-16px;width:calc(100% + 32px);padding:0 16px}tr .label{min-width:100px}tr img{max-width:100%;max-height:100%;aspect-ratio:1}.hr{height:1px;text-align:center;position:relative}.hr:before,.hr:after{content:\"\";background:var(--ngx-menu-separator-color, #2a2a2a);display:block;position:absolute;top:0;bottom:0;height:1px;margin:auto;width:300px}.hr:before{right:calc(100% + 4px)}.hr:after{left:calc(100% + 4px)}hr{background:var(--ngx-menu-separator-color, #2a2a2a);border:0;height:1px;margin:0}.icon{width:24px;height:24px;padding-left:10px}.icon mat-icon{transform:translateY(2px)}.shortcut{color:var(--ngx-menu-shortcut-text-color, #848484);text-align:end;padding-right:10px;padding-left:12px}.label{height:var(--ngx-menu-item-height, 30px)}td{vertical-align:middle}.void,.owner-mask{position:absolute}.void{top:-100vh;right:-100vw;bottom:-100vh;left:-100vw;z-index:-2}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: PortalModule }, { kind: "directive", type: i3.CdkPortalOutlet, selector: "[cdkPortalOutlet]", inputs: ["cdkPortalOutlet"], outputs: ["attached"], exportAs: ["cdkPortalOutlet"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatProgressSpinnerModule }, { kind: "component", type: i5.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }] }); }
|
|
1946
|
+
}
|
|
1947
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: MenuComponent, decorators: [{
|
|
1948
|
+
type: Component,
|
|
1949
|
+
args: [{ selector: 'ngx-menu', imports: [
|
|
1950
|
+
NgTemplateOutlet,
|
|
1951
|
+
PortalModule,
|
|
1952
|
+
MatIconModule,
|
|
1953
|
+
MatProgressSpinnerModule
|
|
1954
|
+
], standalone: true, host: {
|
|
1955
|
+
"[attr.tx]": "targetBounds?.x",
|
|
1956
|
+
"[attr.ty]": "targetBounds?.y",
|
|
1957
|
+
"[attr.th]": "targetBounds?.height",
|
|
1958
|
+
"[attr.tw]": "targetBounds?.width",
|
|
1959
|
+
}, template: "<!-- Mouse event blocker for pointer leave -->\n@if (coverRectCords && !parentIsNgxMenu) {\n <div\n class=\"owner-mask\"\n [style.top]=\"coverRectCords.top + 'px'\"\n [style.left]=\"coverRectCords.left + 'px'\"\n [style.height]=\"coverRectCords.height + 'px'\"\n [style.width]=\"coverRectCords.width + 'px'\"\n [style.background]=\"showDebugOverlay ? '#f004' : '#0000'\"\n style=\"z-index: -1\"\n (pointerenter)=\"pointerHasBeenOverMask=true\"\n (pointerleave)=\"stopCloseTimer()\"\n (pointermove)=\"pointerHasBeenOverMask=true\"\n (click)=\"isLockedOpen = true\"\n ></div>\n}\n\n@if (!parentIsNgxMenu) {\n <div class=\"void\"\n [style.background]=\"showDebugOverlay ? '#00f4' : '#0000'\"\n (pointerenter)=\"pointerIsOnVoid = true; hasBootstrapped && !isLockedOpen && startCloseTimer()\"\n (pointerleave)=\"pointerIsOnVoid = false\"\n (pointerdown)=\"hasBootstrapped && closeOnVoid(true)\"\n (pointermove)=\"hasBootstrapped && !isLockedOpen && startCloseTimer()\"\n (click)=\"closeOnVoid(true)\"\n (wheel)=\"onWheel($event)\"\n ></div>\n}\n\n@if (!template) {\n <table (pointerenter)=\"stopCloseTimer()\">\n <tbody>\n @for (item of items; track item) {\n <!-- A row with a click action -->\n @if (item != 'separator' && item.separator != true && item['_visible']) {\n <tr #row\n [class.disabled]=\"item['_disabled']\"\n (click)=\"!item['_disabled'] && onMenuItemClick(item, row, true)\"\n [class.hover]=\"row['hover']\"\n [class.open]=\"row['_open']\"\n (pointerenter)=\"row['hover'] = true; startHoverTimer(item, row)\"\n (pointerleave)=\"row['hover'] = false; stopHoverTimer(item)\"\n >\n\n @if (showIconColumn) {\n <td class=\"icon\">\n @if (matIconRx.test(item['_icon'] ?? item.icon)) {\n <img [src]=\"item['_icon'] ?? item.icon\"/>\n }\n @else {\n <mat-icon\n [fontIcon]=\"item['_icon'] ?? item.icon\"\n [style.color]=\"item.iconColor\"\n />\n }\n </td>\n }\n\n <!-- 'Normal' action based item -->\n <td class=\"label\"\n [style.padding-left]=\"showIconColumn ? 0 : '16px'\"\n >\n <a\n #anchor\n [attr.target]=\"item.linkTarget\"\n [attr.href]=\"(item['_link'] || item.link) ? sanitizer.bypassSecurityTrustUrl(item['_link'] || item.link) : undefined\"\n >\n @if ($any(item.labelTemplate)?.prototype) {\n <ng-container\n [ngTemplateOutlet]=\"$any(item).labelTemplate\"\n [ngTemplateOutletContext]=\"{\n '$implicit': data,\n 'dialog': dialogRef,\n 'context': item['_context'],\n 'item': item,\n 'element': anchor,\n 'menu': this\n }\"\n />\n }\n @else {\n @if ($any(item)?.labelTemplate) {\n {{$any(item)?.labelTemplate(data || {})}}\n }\n @else {\n <div [innerHTML]=\"item['_formattedLabel']\"></div>\n }\n }\n </a>\n </td>\n\n @if (showShortcutColumn) {\n <td class=\"shortcut\">\n {{item.shortcutLabel}}\n </td>\n }\n\n <td style=\"min-width: 16px\">\n @if ((\n (item['children']?.length > 0) ||\n (item['_children']?.length > 0) ||\n item.childTemplate ||\n item.children?.['call'] ||\n item.childrenResolver\n ) &&\n !item['_isResolving']\n ) {\n <mat-icon\n style=\"transform: translateY(2px)\"\n >\n chevron_right\n </mat-icon>\n }\n\n @if (item['_isResolving']) {\n <mat-progress-spinner\n mode=\"indeterminate\"\n [diameter]=\"20\"\n style=\"margin-right: 4px\"\n />\n }\n </td>\n </tr>\n }\n @else if (item != 'separator' && item.separator == true) {\n <!-- Separator with label -->\n <tr\n class=\"disabled separator\"\n >\n <td\n class=\"center\"\n [attr.colspan]=\"2 + (showIconColumn ? 1 : 0) + (showShortcutColumn ? 1 : 0)\"\n >\n <span class=\"hr\">\n {{item['label'] || ''}}\n </span>\n </td>\n </tr>\n }\n @else if (item == 'separator') {\n <!-- Separator -->\n <tr\n class=\"disabled separator\"\n >\n <td\n [attr.colspan]=\"2 + (showIconColumn ? 1 : 0) + (showShortcutColumn ? 1 : 0)\"\n >\n <hr/>\n </td>\n </tr>\n }\n }\n </tbody>\n </table>\n}\n@else {\n @if (templateType == 'template') {\n <div style=\"display: contents;\" (pointerenter)=\"stopCloseTimer()\">\n <ng-container\n [ngTemplateOutlet]=\"template\"\n [ngTemplateOutletContext]=\"{\n '$implicit': data,\n 'dialog': dialogRef,\n 'context': parentContext,\n 'item': parentItem,\n 'element': this.viewContainer?.element?.nativeElement,\n 'menu': this\n }\"\n />\n </div>\n }\n @else {\n <div style=\"display: contents;\" (pointerenter)=\"stopCloseTimer()\">\n <ng-container\n [cdkPortalOutlet]=\"componentPortal\"\n />\n </div>\n }\n}\n\n@if (showDebugOverlay) {\n <div>\n <div>hbs: {{hasBootstrapped}}</div>\n <div>pov: {{pointerIsOnVoid}}</div>\n <div>ilo: {{isLockedOpen}}</div>\n <div>hbom: {{pointerHasBeenOverMask}}</div>\n\n <div>type: {{templateType}}</div>\n </div>\n}\n", styles: ["::ng-deep .cdk-overlay-container .ngx-menu{--mdc-dialog-container-color: var(--ngx-menu-background-color, #2f2f2f)}::ng-deep .cdk-overlay-container .ngx-menu .mdc-dialog__container{transform-origin:top left}::ng-deep .cdk-overlay-container .ngx-menu .mdc-dialog--open .mdc-dialog__container{transform:none}::ng-deep .cdk-overlay-pane.ngx-menu .mat-mdc-dialog-surface{overflow:visible}:host{-webkit-user-select:none;user-select:none;z-index:1;position:relative;display:block}table{border-spacing:0;border-radius:5px;padding:4px 0;overflow:hidden}tr{color:var(--ngx-menu-text-color, #ccc);font-size:var(--ngx-menu-font-size, 14px);cursor:pointer;transition:background-color 75ms ease,color 75ms ease}tr:not(.disabled).hover,tr:not(.disabled).open{background-color:var(--ngx-menu-hover-background-color, #94ebeb);color:var(--ngx-menu-hover-text-color, #000)}tr:not(.disabled).hover a,tr:not(.disabled).open a{color:var(--ngx-menu-hover-text-color, #000)}tr:not(.separator){height:36px}tr.disabled .label{color:var(--ngx-menu-disabled-text-color, #919191)}tr .center{text-align:center}tr a{outline:0;display:flex;align-items:center;gap:10px;justify-content:space-between;height:100%;width:100%;position:relative;left:-16px;width:calc(100% + 32px);padding:0 16px}tr .label{min-width:100px}tr img{max-width:100%;max-height:100%;aspect-ratio:1}.hr{height:1px;text-align:center;position:relative}.hr:before,.hr:after{content:\"\";background:var(--ngx-menu-separator-color, #2a2a2a);display:block;position:absolute;top:0;bottom:0;height:1px;margin:auto;width:300px}.hr:before{right:calc(100% + 4px)}.hr:after{left:calc(100% + 4px)}hr{background:var(--ngx-menu-separator-color, #2a2a2a);border:0;height:1px;margin:0}.icon{width:24px;height:24px;padding-left:10px}.icon mat-icon{transform:translateY(2px)}.shortcut{color:var(--ngx-menu-shortcut-text-color, #848484);text-align:end;padding-right:10px;padding-left:12px}.label{height:var(--ngx-menu-item-height, 30px)}td{vertical-align:middle}.void,.owner-mask{position:absolute}.void{top:-100vh;right:-100vw;bottom:-100vh;left:-100vw;z-index:-2}\n"] }]
|
|
1960
|
+
}], ctorParameters: () => [{ type: i0.ViewContainerRef }, { type: i1.DomSanitizer }, { type: undefined, decorators: [{
|
|
1961
|
+
type: Optional
|
|
1962
|
+
}, {
|
|
1963
|
+
type: Inject,
|
|
1964
|
+
args: [MAT_DIALOG_DATA]
|
|
1965
|
+
}] }, { type: i2$1.MatDialog, decorators: [{
|
|
1966
|
+
type: Optional
|
|
1967
|
+
}] }, { type: i2$1.MatDialogRef, decorators: [{
|
|
1968
|
+
type: Optional
|
|
1969
|
+
}] }], propDecorators: { data: [{
|
|
1970
|
+
type: Input
|
|
1971
|
+
}], items: [{
|
|
1972
|
+
type: Input
|
|
1973
|
+
}], config: [{
|
|
1974
|
+
type: Input
|
|
1975
|
+
}], id: [{
|
|
1976
|
+
type: Input
|
|
1977
|
+
}], overlayOverlap: [{
|
|
1978
|
+
type: Input
|
|
1979
|
+
}], hoverDelay: [{
|
|
1980
|
+
type: Input
|
|
1981
|
+
}], showDebugOverlay: [{
|
|
1982
|
+
type: Input
|
|
1983
|
+
}], targetBounds: [{
|
|
1984
|
+
type: Input
|
|
1985
|
+
}], ownerCords: [{
|
|
1986
|
+
type: Input
|
|
1987
|
+
}], selfCords: [{
|
|
1988
|
+
type: Input
|
|
1989
|
+
}], parentItem: [{
|
|
1990
|
+
type: Input
|
|
1991
|
+
}], parentContext: [{
|
|
1992
|
+
type: Input
|
|
1993
|
+
}], isLockedOpen: [{
|
|
1994
|
+
type: Input
|
|
1995
|
+
}], onResize: [{
|
|
1996
|
+
type: HostListener,
|
|
1997
|
+
args: ["window:resize"]
|
|
1998
|
+
}] } });
|
|
1999
|
+
|
|
2000
|
+
/**
|
|
2001
|
+
* This utils file exists outside of the strict angular DI zone
|
|
2002
|
+
* This enables opening popups without requiring absolute DI bindings.
|
|
2003
|
+
*/
|
|
2004
|
+
const getPosition = (el, config = {}, bounds) => {
|
|
2005
|
+
// Bounds of the popup owner
|
|
2006
|
+
const src = !!el['nodeName']
|
|
2007
|
+
? el.getBoundingClientRect()
|
|
2008
|
+
: {
|
|
2009
|
+
// It's a pointer event, so we'll take the X and Y from the pointer.
|
|
2010
|
+
x: el['clientX'],
|
|
2011
|
+
y: el['clientY'],
|
|
2012
|
+
// Set a default tiny size, so we don't divide by zero.
|
|
2013
|
+
width: 0.0001,
|
|
2014
|
+
height: 0.0001
|
|
2015
|
+
};
|
|
2016
|
+
// Popup bounds
|
|
2017
|
+
const { width, height } = bounds;
|
|
2018
|
+
const winh = window.innerHeight;
|
|
2019
|
+
const winw = window.innerWidth;
|
|
2020
|
+
const cords = {
|
|
2021
|
+
top: null,
|
|
2022
|
+
left: null
|
|
2023
|
+
};
|
|
2024
|
+
if (config?.position == "left" || config?.position == "right" || !config?.position) {
|
|
2025
|
+
switch (config?.alignment) {
|
|
2026
|
+
case "end": {
|
|
2027
|
+
// vertically bind to bottom
|
|
2028
|
+
cords.top = src.y + src.height - height;
|
|
2029
|
+
break;
|
|
2030
|
+
}
|
|
2031
|
+
case "afterend": {
|
|
2032
|
+
// vertically bind below bottom
|
|
2033
|
+
cords.top = src.y + src.height;
|
|
2034
|
+
break;
|
|
2035
|
+
}
|
|
2036
|
+
case "beforestart": {
|
|
2037
|
+
// vertically bind above top
|
|
2038
|
+
cords.top = src.y - height;
|
|
2039
|
+
break;
|
|
2040
|
+
}
|
|
2041
|
+
case "start": {
|
|
2042
|
+
// vertically bind to top
|
|
2043
|
+
cords.top = src.y;
|
|
2044
|
+
break;
|
|
2045
|
+
}
|
|
2046
|
+
case "center":
|
|
2047
|
+
default: {
|
|
2048
|
+
// vertically center
|
|
2049
|
+
cords.top = (src.y + (src.height / 2)) - (height / 2);
|
|
2050
|
+
break;
|
|
2051
|
+
}
|
|
2052
|
+
}
|
|
2053
|
+
// Apply bounds to prevent the dialog from being cut-off screen
|
|
2054
|
+
// Lower bound
|
|
2055
|
+
cords.top = Math.max(config?.edgePadding || 0, cords.top);
|
|
2056
|
+
// Upper bound
|
|
2057
|
+
cords.top = Math.min(winh - height, cords.top);
|
|
2058
|
+
if (config?.position == "left") {
|
|
2059
|
+
cords.left = src.x - (width + (config?.arrowSize || 0) + (config?.arrowPadding || 0));
|
|
2060
|
+
}
|
|
2061
|
+
if (config?.position == "right" || !config?.position) {
|
|
2062
|
+
cords.left = src.x + (src.width + (config?.arrowSize || 0) + (config?.arrowPadding || 0));
|
|
2063
|
+
}
|
|
2064
|
+
// Lower bound
|
|
2065
|
+
cords.left = Math.max(config?.edgePadding || 0, cords.left);
|
|
2066
|
+
// Upper bound
|
|
2067
|
+
cords.left = Math.min(winw - width, cords.left);
|
|
2068
|
+
}
|
|
2069
|
+
else if (config?.position == "top" || config?.position == "bottom") {
|
|
2070
|
+
switch (config?.alignment) {
|
|
2071
|
+
case "end": {
|
|
2072
|
+
// vertically bind to right
|
|
2073
|
+
cords.left = src.x + src.width - width;
|
|
2074
|
+
break;
|
|
2075
|
+
}
|
|
2076
|
+
case "afterend": {
|
|
2077
|
+
// vertically bind past right
|
|
2078
|
+
cords.left = src.x + src.width;
|
|
2079
|
+
break;
|
|
2080
|
+
}
|
|
2081
|
+
case "beforestart": {
|
|
2082
|
+
// vertically bind before left
|
|
2083
|
+
cords.left = src.x - width;
|
|
2084
|
+
break;
|
|
2085
|
+
}
|
|
2086
|
+
case "start": {
|
|
2087
|
+
// vertically bind to left
|
|
2088
|
+
cords.left = src.x;
|
|
2089
|
+
break;
|
|
2090
|
+
}
|
|
2091
|
+
case "center":
|
|
2092
|
+
default: {
|
|
2093
|
+
// vertically center
|
|
2094
|
+
cords.left = (src.x + (src.width / 2)) - (width / 2);
|
|
2095
|
+
break;
|
|
2096
|
+
}
|
|
2097
|
+
}
|
|
2098
|
+
// Apply bounds to prevent the dialog from being cut-off screen
|
|
2099
|
+
// Lower bound
|
|
2100
|
+
cords.left = Math.max(config?.edgePadding || 0, cords.left);
|
|
2101
|
+
// Upper bound
|
|
2102
|
+
cords.left = Math.min(winw - width, cords.left);
|
|
2103
|
+
if (config?.position == "top") {
|
|
2104
|
+
cords.top = src.y - (height + (config?.arrowSize || 0) + (config?.arrowPadding || 0));
|
|
2105
|
+
}
|
|
2106
|
+
if (config?.position == "bottom") {
|
|
2107
|
+
cords.top = src.y + (src.height + (config?.arrowSize || 0) + (config?.arrowPadding || 0));
|
|
2108
|
+
}
|
|
2109
|
+
// Lower bound
|
|
2110
|
+
cords.top = Math.max(config?.edgePadding || 0, cords.top);
|
|
2111
|
+
// Upper bound
|
|
2112
|
+
cords.top = Math.min(winh - height, cords.top);
|
|
2113
|
+
}
|
|
2114
|
+
// Assign unit
|
|
2115
|
+
cords.top = cords.top + 'px';
|
|
2116
|
+
cords.left = cords.left + 'px';
|
|
2117
|
+
return cords;
|
|
2118
|
+
};
|
|
2119
|
+
|
|
2120
|
+
class MenuDirective {
|
|
2121
|
+
constructor(dialog, viewContainer) {
|
|
2122
|
+
this.dialog = dialog;
|
|
2123
|
+
this.viewContainer = viewContainer;
|
|
2124
|
+
/**
|
|
2125
|
+
* Configuration for opening the app menu
|
|
2126
|
+
*/
|
|
2127
|
+
this.config = {};
|
|
2128
|
+
this.triggers = [];
|
|
2129
|
+
}
|
|
2130
|
+
ngOnInit() {
|
|
2131
|
+
this.ngOnChanges();
|
|
2132
|
+
}
|
|
2133
|
+
ngOnChanges() {
|
|
2134
|
+
if (this.config.trigger) {
|
|
2135
|
+
this.triggers = Array.isArray(this.config.trigger) ? this.config.trigger : [this.config.trigger];
|
|
2136
|
+
}
|
|
2137
|
+
}
|
|
2138
|
+
ngAfterViewInit() {
|
|
2139
|
+
// const el = this.viewContainer.element.nativeElement as HTMLElement;
|
|
2140
|
+
// // Automatically attach context menu items to
|
|
2141
|
+
// // the contextmenu event
|
|
2142
|
+
// if (this.ctxMenuItems) {
|
|
2143
|
+
// el.addEventListener('contextmenu', (e) => {
|
|
2144
|
+
// e.preventDefault();
|
|
2145
|
+
// this.openMenu(e as any, this.ctxMenuItems, true);
|
|
2146
|
+
// });
|
|
2147
|
+
// }
|
|
2148
|
+
// if (this.menuItems?.length > 0) {
|
|
2149
|
+
// if (!this.config?.trigger) {
|
|
2150
|
+
// el.addEventListener('click', (e) => {
|
|
2151
|
+
// this.openMenu(e as any, this.menuItems, true);
|
|
2152
|
+
// });
|
|
2153
|
+
// }
|
|
2154
|
+
// else {
|
|
2155
|
+
// triggers.forEach(t => {
|
|
2156
|
+
// if (["contextmenu", "click"].includes(t)) {
|
|
2157
|
+
// el.addEventListener(t, (e) => {
|
|
2158
|
+
// e.preventDefault();
|
|
2159
|
+
// this.openMenu(e as any, this.ctxMenuItems, true);
|
|
2160
|
+
// });
|
|
2161
|
+
// }
|
|
2162
|
+
// else {
|
|
2163
|
+
// el.addEventListener(t, this.openMenu.bind(this));
|
|
2164
|
+
// }
|
|
2165
|
+
// });
|
|
2166
|
+
// }
|
|
2167
|
+
// }
|
|
2168
|
+
}
|
|
2169
|
+
async openMenu(evt, items = this.menuItems, keepOpen = false) {
|
|
2170
|
+
const el = this.viewContainer.element.nativeElement;
|
|
2171
|
+
el.classList.add("ngx-menu-open");
|
|
2172
|
+
const isCtxEvent = evt.button == 2;
|
|
2173
|
+
const config = structuredClone(this.config);
|
|
2174
|
+
config['_isLockedOpen'] = keepOpen;
|
|
2175
|
+
return openMenu(this.dialog, items, this.data, evt, this.config, isCtxEvent ? null : el)
|
|
2176
|
+
.then((...res) => {
|
|
2177
|
+
el.classList.remove("ngx-menu-open");
|
|
2178
|
+
return res;
|
|
2179
|
+
})
|
|
2180
|
+
.catch((ex) => {
|
|
2181
|
+
el.classList.remove("ngx-menu-open");
|
|
2182
|
+
throw ex;
|
|
2183
|
+
});
|
|
2184
|
+
}
|
|
2185
|
+
onCtxMenu(e) {
|
|
2186
|
+
if (this.ctxMenuItems || this.triggers.includes("contextmenu")) {
|
|
2187
|
+
e.preventDefault();
|
|
2188
|
+
this.openMenu(e, this.ctxMenuItems, true);
|
|
2189
|
+
}
|
|
2190
|
+
}
|
|
2191
|
+
onClick(e) {
|
|
2192
|
+
if (this.menuItems &&
|
|
2193
|
+
(this.triggers.length == 0 ||
|
|
2194
|
+
this.triggers.includes("click"))) {
|
|
2195
|
+
e.preventDefault();
|
|
2196
|
+
this.openMenu(e, this.menuItems, true);
|
|
2197
|
+
}
|
|
2198
|
+
}
|
|
2199
|
+
onDblClick(e) {
|
|
2200
|
+
if (this.menuItems && this.triggers.length == 0 ||
|
|
2201
|
+
this.menuItems && this.triggers.includes("dblclick")) {
|
|
2202
|
+
e.preventDefault();
|
|
2203
|
+
this.openMenu(e, this.menuItems, true);
|
|
2204
|
+
}
|
|
2205
|
+
}
|
|
2206
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: MenuDirective, deps: [{ token: i2$1.MatDialog }, { token: i0.ViewContainerRef }], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
2207
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.12", type: MenuDirective, isStandalone: true, selector: "[ngx-contextmenu],[ngx-menu]", inputs: { data: ["ngx-menu-context", "data"], ctxMenuItems: ["ngx-contextmenu", "ctxMenuItems"], menuItems: ["ngx-menu", "menuItems"], config: ["ngx-menu-config", "config"] }, host: { listeners: { "contextmenu": "onCtxMenu($event)", "click": "onClick($event)", "dblclick": "onDblClick($event)" } }, providers: [
|
|
2208
|
+
MatDialog
|
|
2209
|
+
], usesOnChanges: true, ngImport: i0 }); }
|
|
2210
|
+
}
|
|
2211
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: MenuDirective, decorators: [{
|
|
2212
|
+
type: Directive,
|
|
2213
|
+
args: [{
|
|
2214
|
+
selector: '[ngx-contextmenu],[ngx-menu]',
|
|
2215
|
+
providers: [
|
|
2216
|
+
MatDialog
|
|
2217
|
+
],
|
|
2218
|
+
standalone: true
|
|
2219
|
+
}]
|
|
2220
|
+
}], ctorParameters: () => [{ type: i2$1.MatDialog }, { type: i0.ViewContainerRef }], propDecorators: { data: [{
|
|
2221
|
+
type: Input,
|
|
2222
|
+
args: ["ngx-menu-context"]
|
|
2223
|
+
}], ctxMenuItems: [{
|
|
2224
|
+
type: Input,
|
|
2225
|
+
args: ["ngx-contextmenu"]
|
|
2226
|
+
}], menuItems: [{
|
|
2227
|
+
type: Input,
|
|
2228
|
+
args: ["ngx-menu"]
|
|
2229
|
+
}], config: [{
|
|
2230
|
+
type: Input,
|
|
2231
|
+
args: ["ngx-menu-config"]
|
|
2232
|
+
}], onCtxMenu: [{
|
|
2233
|
+
type: HostListener,
|
|
2234
|
+
args: ["contextmenu", ['$event']]
|
|
2235
|
+
}], onClick: [{
|
|
2236
|
+
type: HostListener,
|
|
2237
|
+
args: ["click", ['$event']]
|
|
2238
|
+
}], onDblClick: [{
|
|
2239
|
+
type: HostListener,
|
|
2240
|
+
args: ["dblclick", ['$event']]
|
|
2241
|
+
}] } });
|
|
2242
|
+
// Helper to open the menu without using the directive.
|
|
2243
|
+
const openMenu = async (dialog, menuItems, data, evt, config = {}, el) => {
|
|
2244
|
+
// console.log({ dialog, menuItems, data, evt, config, el });
|
|
2245
|
+
evt.preventDefault();
|
|
2246
|
+
evt.stopPropagation();
|
|
2247
|
+
// Apply defaults.
|
|
2248
|
+
if (!config.alignment)
|
|
2249
|
+
config.alignment = "start";
|
|
2250
|
+
const initialBounds = await calcMenuItemBounds(menuItems, data);
|
|
2251
|
+
const cords = getPosition(el || evt, config, initialBounds);
|
|
2252
|
+
const specificId = ulid();
|
|
2253
|
+
return firstValueFrom(dialog.open(MenuComponent, {
|
|
2254
|
+
data: {
|
|
2255
|
+
dialog,
|
|
2256
|
+
data: data,
|
|
2257
|
+
ownerCords: el?.getBoundingClientRect(),
|
|
2258
|
+
selfCords: cords,
|
|
2259
|
+
items: menuItems,
|
|
2260
|
+
config: config,
|
|
2261
|
+
id: specificId,
|
|
2262
|
+
targetBounds: initialBounds
|
|
2263
|
+
},
|
|
2264
|
+
panelClass: ["ngx-menu", 'ngx-' + specificId].concat(config?.customClass || []),
|
|
2265
|
+
position: cords,
|
|
2266
|
+
backdropClass: "ngx-menu-backdrop"
|
|
2267
|
+
})
|
|
2268
|
+
.afterClosed());
|
|
2269
|
+
};
|
|
2270
|
+
|
|
2271
|
+
; /*
|
|
2272
|
+
* Public API Surface of package
|
|
2273
|
+
*/
|
|
2274
|
+
|
|
2275
|
+
/**
|
|
2276
|
+
* Generated bundle index. Do not edit.
|
|
2277
|
+
*/
|
|
2278
|
+
|
|
2279
|
+
export { ComponentResolveStrategy, DependencyService, DialogService, Fetch, FileService, HtmlBypass, KeyboardService, LazyLoaderComponent, LazyLoaderModule, LazyLoaderService, MenuComponent, MenuDirective, NGX_IMAGE_CACHE_CONFIG, NGX_LAZY_LOADER_CONFIG, NGX_WEB_COMPONENTS_CONFIG, NavigationService, NgxImageCacheDirective, ParallaxCardComponent, ResourceBypass, ScriptBypass, StyleBypass, ThemeService, UrlBypass, calcMenuItemBounds, getPosition, getUrlData, openMenu, saveObjectAsFile, sleep, stringToSlug, updateUrl };
|
|
2280
|
+
//# sourceMappingURL=dotglitch-ngx-common-core.mjs.map
|