@fc3/mmcadi 0.1.0
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/LICENSE +673 -0
- package/README.md +5 -0
- package/bin/compile +63 -0
- package/bin/copy-static-files +13 -0
- package/bin/install +5 -0
- package/bin/precompile +55 -0
- package/bin/prepublish +7 -0
- package/bin/remap-paths +113 -0
- package/bin/test +9 -0
- package/config/tsconfig.json +37 -0
- package/package.json +33 -0
- package/src/bootstrap/start.ts +12 -0
- package/src/client/bootstrap.ts +5 -0
- package/src/client/client.ts +54 -0
- package/src/client/enum/key-code.ts +34 -0
- package/src/client/enum/page-type.ts +19 -0
- package/src/client/factory/page.ts +61 -0
- package/src/client/page/confirm-delete-block.ts +30 -0
- package/src/client/page/create-block.ts +6 -0
- package/src/client/page/day.ts +8 -0
- package/src/client/page/edit-block.ts +43 -0
- package/src/client/page/edit-custom.ts +16 -0
- package/src/client/page/home.ts +8 -0
- package/src/client/page/login.ts +8 -0
- package/src/client/page/logout.ts +8 -0
- package/src/client/page/month.ts +8 -0
- package/src/client/page/move-block.ts +8 -0
- package/src/client/page/select-block-type.ts +56 -0
- package/src/client/page/settings.ts +8 -0
- package/src/client/page/view-custom.ts +665 -0
- package/src/client/page/week.ts +8 -0
- package/src/client/page/year.ts +8 -0
- package/src/client/page.ts +128 -0
- package/src/client/shim/execute.ts +5 -0
- package/src/client/shim/logger.ts +44 -0
- package/src/client/utility/get-meta-value.ts +23 -0
- package/src/common/builder/block/background.ts +25 -0
- package/src/common/builder/block/folder.ts +43 -0
- package/src/common/builder/block/header.ts +15 -0
- package/src/common/builder/block/link.ts +32 -0
- package/src/common/builder/block/multicolumn.ts +16 -0
- package/src/common/builder/block/note.ts +13 -0
- package/src/common/builder/block/whitespace.ts +13 -0
- package/src/common/utility/get-parent-path.ts +29 -0
- package/src/constant/month-names.ts +16 -0
- package/src/enum/action-type.ts +11 -0
- package/src/enum/block-type.ts +18 -0
- package/src/enum/calendar-view-mode.ts +9 -0
- package/src/enum/color.ts +15 -0
- package/src/enum/default-role.ts +6 -0
- package/src/enum/directory-item-type.ts +6 -0
- package/src/enum/emoji.ts +94 -0
- package/src/enum/field-type.ts +8 -0
- package/src/enum/header-size.ts +7 -0
- package/src/enum/permission-type.ts +8 -0
- package/src/enum/time-place-visibility.ts +8 -0
- package/src/enum/tool-type.ts +14 -0
- package/src/index.ts +8 -0
- package/src/interface/hydration-callback.ts +7 -0
- package/src/interface/provider.ts +8 -0
- package/src/interface/repository.ts +12 -0
- package/src/lib/array/add.ts +10 -0
- package/src/lib/array/assert-is-empty.ts +23 -0
- package/src/lib/array/clone.ts +5 -0
- package/src/lib/array/difference.ts +8 -0
- package/src/lib/array/empty.ts +6 -0
- package/src/lib/array/equal.ts +24 -0
- package/src/lib/array/get-first-value.ts +5 -0
- package/src/lib/array/get-last-value.ts +5 -0
- package/src/lib/array/get-max-value.ts +5 -0
- package/src/lib/array/get-value-after.ts +23 -0
- package/src/lib/array/get-value-before.ts +23 -0
- package/src/lib/array/get-values-between.ts +18 -0
- package/src/lib/array/index.ts +5 -0
- package/src/lib/array/is-empty.ts +6 -0
- package/src/lib/array/remove.ts +19 -0
- package/src/lib/array/sum.ts +11 -0
- package/src/lib/array/unique.ts +13 -0
- package/src/lib/environment/bootstrap.ts +1 -0
- package/src/lib/environment/enum/environment-type.ts +8 -0
- package/src/lib/environment/enum/service-type.ts +5 -0
- package/src/lib/environment/index.ts +7 -0
- package/src/lib/environment/utility/get-environment-type.ts +28 -0
- package/src/lib/environment/utility/is-browser.ts +5 -0
- package/src/lib/environment/utility/is-development.ts +10 -0
- package/src/lib/environment/utility/is-production-or-staging.ts +8 -0
- package/src/lib/environment/utility/is-production.ts +10 -0
- package/src/lib/environment/utility/is-staging.ts +10 -0
- package/src/lib/errors/enum/error-type.ts +13 -0
- package/src/lib/errors/error/base.ts +40 -0
- package/src/lib/errors/error/conflict.ts +16 -0
- package/src/lib/errors/error/generic.ts +23 -0
- package/src/lib/errors/error/invalid.ts +14 -0
- package/src/lib/errors/error/invariant-violation.ts +5 -0
- package/src/lib/errors/error/not-allowed.ts +14 -0
- package/src/lib/errors/error/not-found.ts +16 -0
- package/src/lib/errors/error/not-implemented.ts +20 -0
- package/src/lib/errors/error/omitted.ts +14 -0
- package/src/lib/errors/error/timeout.ts +14 -0
- package/src/lib/errors/error/unauthorized.ts +14 -0
- package/src/lib/errors/index.ts +18 -0
- package/src/lib/errors/sugar/invariant.ts +7 -0
- package/src/lib/errors/type/coded-error.ts +7 -0
- package/src/lib/errors/type/error-data.ts +11 -0
- package/src/lib/errors/utility/create-error-for-error-type.ts +60 -0
- package/src/lib/errors/utility/create-error-from-ambiguous-json-data.ts +26 -0
- package/src/lib/errors/utility/error-matches.ts +28 -0
- package/src/lib/errors/utility/get-error-type-for-posix-error-code.ts +37 -0
- package/src/lib/errors/utility/get-error-type-for-status-code.ts +38 -0
- package/src/lib/errors/utility/get-message-for-error-type.ts +29 -0
- package/src/lib/errors/utility/matches-posix-error-code.ts +11 -0
- package/src/lib/errors/utility/wrap-error.ts +39 -0
- package/src/lib/event-emitter/index.ts +63 -0
- package/src/lib/execution-context/execution-context.ts +90 -0
- package/src/lib/execution-context/index.ts +8 -0
- package/src/lib/execution-context/type/session.ts +7 -0
- package/src/lib/feature/feature.ts +108 -0
- package/src/lib/feature/index.ts +3 -0
- package/src/lib/filesystem/bootstrap.ts +1 -0
- package/src/lib/filesystem/enum/file-extension.ts +19 -0
- package/src/lib/filesystem/index.ts +4 -0
- package/src/lib/filesystem/utility/exists.ts +21 -0
- package/src/lib/filesystem/utility/get-extension-for-filepath.ts +20 -0
- package/src/lib/filesystem/utility/strip-extension.ts +26 -0
- package/src/lib/grammar/index.ts +3 -0
- package/src/lib/grammar/noun-inflector.ts +104 -0
- package/src/lib/grammar/utility/get-words-from-identifier.ts +9 -0
- package/src/lib/grammar/verb-inflector.ts +344 -0
- package/src/lib/http/buffer-stream.ts +76 -0
- package/src/lib/http/enum/content-type.ts +19 -0
- package/src/lib/http/enum/cookie-attribute.ts +11 -0
- package/src/lib/http/enum/header.ts +29 -0
- package/src/lib/http/enum/method.ts +11 -0
- package/src/lib/http/enum/same-site-policy.ts +7 -0
- package/src/lib/http/enum/status-code.ts +9 -0
- package/src/lib/http/factory/body-parser.ts +55 -0
- package/src/lib/http/index.ts +24 -0
- package/src/lib/http/interface/client-request.ts +15 -0
- package/src/lib/http/interface/incoming-message.ts +24 -0
- package/src/lib/http/interface/network-library.ts +9 -0
- package/src/lib/http/interface/request-callback.ts +7 -0
- package/src/lib/http/isomorphic/request.ts +77 -0
- package/src/lib/http/isomorphic/response.ts +77 -0
- package/src/lib/http/isomorphic.ts +20 -0
- package/src/lib/http/parser/accept-header.ts +35 -0
- package/src/lib/http/parser/basic-auth-header.ts +48 -0
- package/src/lib/http/parser/body/json.ts +14 -0
- package/src/lib/http/parser/body/multipart.ts +89 -0
- package/src/lib/http/parser/body/url-encoded.ts +16 -0
- package/src/lib/http/parser/body.ts +44 -0
- package/src/lib/http/parser/cookie.ts +114 -0
- package/src/lib/http/parser/querystring.ts +92 -0
- package/src/lib/http/parser/url.ts +76 -0
- package/src/lib/http/request/incoming.ts +299 -0
- package/src/lib/http/request/outgoing.ts +276 -0
- package/src/lib/http/request.ts +26 -0
- package/src/lib/http/response/incoming.ts +243 -0
- package/src/lib/http/response/outgoing.ts +160 -0
- package/src/lib/http/response.ts +74 -0
- package/src/lib/http/serializer/basic-auth-header.ts +27 -0
- package/src/lib/http/serializer/cookie.ts +90 -0
- package/src/lib/http/serializer/query-data.ts +54 -0
- package/src/lib/http/transaction.ts +320 -0
- package/src/lib/http/type/basic-auth-credentials.ts +6 -0
- package/src/lib/http/type/header-map.ts +5 -0
- package/src/lib/http/type/log-attributes.ts +12 -0
- package/src/lib/http/type/path-parameters.ts +5 -0
- package/src/lib/http/type/query-data.ts +7 -0
- package/src/lib/http/type/query-value.ts +11 -0
- package/src/lib/http/type/request-options.ts +16 -0
- package/src/lib/http/type/transaction-data.ts +4 -0
- package/src/lib/http/utility/get-content-type-for-extension.ts +47 -0
- package/src/lib/http/utility/get-library-for-protocol.ts +25 -0
- package/src/lib/http/utility/get-status-code-for-error-type.ts +37 -0
- package/src/lib/http/utility/get-status-code-for-error.ts +13 -0
- package/src/lib/http/utility/is-client-error-status.ts +15 -0
- package/src/lib/http/utility/is-error-status.ts +9 -0
- package/src/lib/http/utility/is-server-error-status.ts +7 -0
- package/src/lib/http/utility/is-success-status.ts +7 -0
- package/src/lib/http/utility/proxy-request.ts +58 -0
- package/src/lib/http/utility/serialize-request-options.ts +9 -0
- package/src/lib/http/utility/slug-generator.ts +20 -0
- package/src/lib/key-generator/index.ts +3 -0
- package/src/lib/key-generator/key-generator.ts +7 -0
- package/src/lib/logger/enum/ansi-escape-code.ts +14 -0
- package/src/lib/logger/enum/log-level.ts +8 -0
- package/src/lib/logger/formatter.ts +59 -0
- package/src/lib/logger/index.ts +7 -0
- package/src/lib/logger/interface/error-reporter.ts +7 -0
- package/src/lib/logger/interface/logger.ts +13 -0
- package/src/lib/logger/logger.ts +239 -0
- package/src/lib/logger/type/error-parameters.ts +9 -0
- package/src/lib/logger/type/loggable-data.ts +5 -0
- package/src/lib/logger/type/loggable-value.ts +1 -0
- package/src/lib/metrics/dispatcher.ts +264 -0
- package/src/lib/metrics/enum/dispatch-mode.ts +6 -0
- package/src/lib/metrics/index.ts +2 -0
- package/src/lib/metrics/settings-hydrator.ts +51 -0
- package/src/lib/metrics/type/dispatcher-settings.ts +12 -0
- package/src/lib/metrics/type/tag-map.ts +5 -0
- package/src/lib/network/bootstrap.ts +1 -0
- package/src/lib/network/enum/connection-status.ts +14 -0
- package/src/lib/network/enum/http-status-code.ts +75 -0
- package/src/lib/network/enum/network-protocol.ts +10 -0
- package/src/lib/network/event-emitter.ts +63 -0
- package/src/lib/network/index.ts +7 -0
- package/src/lib/network/interface/socket.ts +42 -0
- package/src/lib/network/type/socket-options.ts +6 -0
- package/src/lib/network/utility/get-protocol-from-url.ts +15 -0
- package/src/lib/operation/index.ts +6 -0
- package/src/lib/operation/operation/auto-logging.ts +94 -0
- package/src/lib/operation/operation/silent.ts +17 -0
- package/src/lib/operation/operation.ts +80 -0
- package/src/lib/process/bootstrap.ts +1 -0
- package/src/lib/process/enum/posix-error-code.ts +138 -0
- package/src/lib/process/enum/process-signal.ts +68 -0
- package/src/lib/process/error.ts +6 -0
- package/src/lib/process/execute.ts +77 -0
- package/src/lib/process/index.ts +4 -0
- package/src/lib/process/type/command-options.ts +9 -0
- package/src/lib/process/utility/bind-process-lifespan-to.ts +10 -0
- package/src/lib/promise-wrapper/index.ts +3 -0
- package/src/lib/promise-wrapper/promise-wrapper.ts +51 -0
- package/src/lib/random/chance.ts +5 -0
- package/src/lib/random/element.ts +7 -0
- package/src/lib/random/elements.ts +12 -0
- package/src/lib/random/enum.ts +34 -0
- package/src/lib/random/enums.ts +11 -0
- package/src/lib/random/index.ts +3 -0
- package/src/lib/random/number.ts +8 -0
- package/src/lib/server/base.ts +194 -0
- package/src/lib/server/enum/server-event.ts +5 -0
- package/src/lib/server/enum/server-status.ts +10 -0
- package/src/lib/server/http/endpoint/ping.ts +21 -0
- package/src/lib/server/http/endpoint.ts +345 -0
- package/src/lib/server/http/interface/endpoint-constructor.ts +12 -0
- package/src/lib/server/http/interface/result-serializer.ts +5 -0
- package/src/lib/server/http/middleware.ts +18 -0
- package/src/lib/server/http/result-serializer/html.ts +92 -0
- package/src/lib/server/http/result-serializer/json.ts +23 -0
- package/src/lib/server/http/route.ts +104 -0
- package/src/lib/server/http/router.ts +125 -0
- package/src/lib/server/http/type/session-resolver.ts +8 -0
- package/src/lib/server/http/utility/create-server.ts +34 -0
- package/src/lib/server/http/utility/path-parser.ts +49 -0
- package/src/lib/server/http/utility/standardize-html-indentation.ts +54 -0
- package/src/lib/server/http/websocket-wrapper.ts +83 -0
- package/src/lib/server/http.ts +301 -0
- package/src/lib/server/index.ts +5 -0
- package/src/lib/server/tcp.ts +53 -0
- package/src/lib/server/type/server-options.ts +10 -0
- package/src/lib/string/calculate-length.ts +17 -0
- package/src/lib/string/capitalize.ts +8 -0
- package/src/lib/string/create-slug.ts +14 -0
- package/src/lib/string/enum/ansi-escape-code.ts +14 -0
- package/src/lib/string/enum/string-encoding.ts +9 -0
- package/src/lib/string/hyphenate.ts +5 -0
- package/src/lib/string/index.ts +3 -0
- package/src/lib/string/pad.ts +14 -0
- package/src/lib/string/trim-multiline.ts +21 -0
- package/src/lib/string/trim.ts +8 -0
- package/src/lib/tcp/channel.ts +13 -0
- package/src/lib/tcp/connection/incoming.ts +72 -0
- package/src/lib/tcp/connection/outgoing.ts +219 -0
- package/src/lib/tcp/connection.ts +360 -0
- package/src/lib/tcp/enum/connection-event.ts +12 -0
- package/src/lib/tcp/enum/message-type.ts +9 -0
- package/src/lib/tcp/index.ts +1 -0
- package/src/lib/tcp/type/connection-parameters.ts +6 -0
- package/src/lib/tcp/type/message/channel-close.ts +9 -0
- package/src/lib/tcp/type/message/channel-open.ts +9 -0
- package/src/lib/tcp/type/message.ts +10 -0
- package/src/lib/test/index.ts +2 -0
- package/src/lib/test/utility/build-config.ts +17 -0
- package/src/lib/test/utility/build-execution-context.ts +11 -0
- package/src/lib/time/bootstrap.ts +1 -0
- package/src/lib/time/enum/time-interval.ts +12 -0
- package/src/lib/time/index.ts +4 -0
- package/src/lib/time/utility/format-duration.ts +139 -0
- package/src/lib/time/utility/format-relative-duration.ts +22 -0
- package/src/lib/time/utility/sleep.ts +9 -0
- package/src/operation.ts +18 -0
- package/src/server/endpoint/abstract-page.ts +126 -0
- package/src/server/endpoint/action/create.ts +545 -0
- package/src/server/endpoint/action/get.ts +231 -0
- package/src/server/endpoint/base.ts +51 -0
- package/src/server/endpoint/day.ts +13 -0
- package/src/server/endpoint/generic-page.ts +14 -0
- package/src/server/endpoint/index.ts +11 -0
- package/src/server/endpoint/login.ts +45 -0
- package/src/server/endpoint/logout.ts +38 -0
- package/src/server/endpoint/month.ts +35 -0
- package/src/server/endpoint/robots.ts +18 -0
- package/src/server/endpoint/session/create.ts +62 -0
- package/src/server/endpoint/settings/get.ts +40 -0
- package/src/server/endpoint/settings/update.ts +44 -0
- package/src/server/endpoint/today.ts +15 -0
- package/src/server/endpoint/week.ts +34 -0
- package/src/server/endpoint/year.ts +34 -0
- package/src/server/enum/custom-page-type.ts +10 -0
- package/src/server/factory/block-result-serializer.ts +115 -0
- package/src/server/middleware/base.ts +6 -0
- package/src/server/middleware/error-handler.ts +177 -0
- package/src/server/middleware/static-file.ts +83 -0
- package/src/server/operation/add-block.ts +110 -0
- package/src/server/operation/create-session.ts +43 -0
- package/src/server/operation/delete-block.ts +96 -0
- package/src/server/operation/demote-block.ts +108 -0
- package/src/server/operation/destroy-session.ts +26 -0
- package/src/server/operation/load-account.ts +30 -0
- package/src/server/operation/load-block.ts +48 -0
- package/src/server/operation/load-directory-items.ts +75 -0
- package/src/server/operation/load-page.ts +368 -0
- package/src/server/operation/promote-block.ts +104 -0
- package/src/server/operation/save-page.ts +60 -0
- package/src/server/operation/update-account-settings.ts +52 -0
- package/src/server/operation/update-block.ts +124 -0
- package/src/server/repository/memory.ts +112 -0
- package/src/server/result-serializer/action.ts +939 -0
- package/src/server/result-serializer/base.ts +1267 -0
- package/src/server/result-serializer/block/audio.ts +33 -0
- package/src/server/result-serializer/block/background.ts +20 -0
- package/src/server/result-serializer/block/calendar.ts +148 -0
- package/src/server/result-serializer/block/directory.ts +57 -0
- package/src/server/result-serializer/block/ephemeral.ts +14 -0
- package/src/server/result-serializer/block/folder.ts +106 -0
- package/src/server/result-serializer/block/header.ts +31 -0
- package/src/server/result-serializer/block/image.ts +46 -0
- package/src/server/result-serializer/block/link.ts +40 -0
- package/src/server/result-serializer/block/list.ts +140 -0
- package/src/server/result-serializer/block/multi-column.ts +97 -0
- package/src/server/result-serializer/block/note.ts +44 -0
- package/src/server/result-serializer/block/todo.ts +78 -0
- package/src/server/result-serializer/block/whitespace.ts +15 -0
- package/src/server/result-serializer/block.ts +248 -0
- package/src/server/result-serializer/common/time-place-options.ts +33 -0
- package/src/server/result-serializer/login.ts +58 -0
- package/src/server/result-serializer/month.ts +170 -0
- package/src/server/result-serializer/page.ts +548 -0
- package/src/server/result-serializer/settings.ts +85 -0
- package/src/server/result-serializer/week.ts +195 -0
- package/src/server/result-serializer/year.ts +160 -0
- package/src/server/utility/accepts-content-type.ts +16 -0
- package/src/server/utility/accepts-html.ts +9 -0
- package/src/server/utility/accepts-json.ts +9 -0
- package/src/server/utility/add-days.ts +11 -0
- package/src/server/utility/create-date.ts +23 -0
- package/src/server/utility/create-index-path.ts +5 -0
- package/src/server/utility/create-slug.ts +9 -0
- package/src/server/utility/create-toast-path.ts +19 -0
- package/src/server/utility/date-less-than.ts +5 -0
- package/src/server/utility/date-occurs-before.ts +22 -0
- package/src/server/utility/date-to-key.ts +7 -0
- package/src/server/utility/date-to-label.ts +5 -0
- package/src/server/utility/date-to-path.ts +9 -0
- package/src/server/utility/dates-are-equal.ts +22 -0
- package/src/server/utility/dates-are-in-order.ts +9 -0
- package/src/server/utility/dates-are-on-the-same-day.ts +9 -0
- package/src/server/utility/dates-in-same-month.ts +8 -0
- package/src/server/utility/day-to-date.ts +40 -0
- package/src/server/utility/decrement-date.ts +11 -0
- package/src/server/utility/get-block-at-index-path.ts +32 -0
- package/src/server/utility/get-block-permissions.ts +15 -0
- package/src/server/utility/get-compact-label-for-date.ts +8 -0
- package/src/server/utility/get-custom-page-type-for-path.ts +37 -0
- package/src/server/utility/get-element-id-for-block.ts +15 -0
- package/src/server/utility/get-emoji-for-block-type.ts +39 -0
- package/src/server/utility/get-emoji-for-tool-type.ts +20 -0
- package/src/server/utility/get-end-of-month.ts +13 -0
- package/src/server/utility/get-end-of-week.ts +13 -0
- package/src/server/utility/get-filepath-for-folder-block.ts +23 -0
- package/src/server/utility/get-hex-for-color.ts +31 -0
- package/src/server/utility/get-label-for-time-place-visibility.ts +23 -0
- package/src/server/utility/get-month-name.ts +18 -0
- package/src/server/utility/get-next-day.ts +7 -0
- package/src/server/utility/get-next-month.ts +12 -0
- package/src/server/utility/get-next-week.ts +12 -0
- package/src/server/utility/get-next-year.ts +13 -0
- package/src/server/utility/get-ordinal-label-for-week.ts +11 -0
- package/src/server/utility/get-ordinal-of-week-within-month.ts +15 -0
- package/src/server/utility/get-padded-date.ts +11 -0
- package/src/server/utility/get-parent-index-path.ts +18 -0
- package/src/server/utility/get-path-for-folder-block.ts +25 -0
- package/src/server/utility/get-path-from-url.ts +13 -0
- package/src/server/utility/get-previous-index-path.ts +27 -0
- package/src/server/utility/get-previous-month.ts +12 -0
- package/src/server/utility/get-previous-week.ts +11 -0
- package/src/server/utility/get-previous-year.ts +13 -0
- package/src/server/utility/get-random-emoji-for-date.ts +109 -0
- package/src/server/utility/get-short-label-for-date.ts +11 -0
- package/src/server/utility/get-short-month-name.ts +9 -0
- package/src/server/utility/get-short-ordinal.ts +26 -0
- package/src/server/utility/get-siblings-and-index-for-index-path.ts +67 -0
- package/src/server/utility/get-start-of-month.ts +11 -0
- package/src/server/utility/get-start-of-week.ts +12 -0
- package/src/server/utility/get-start-of-year.ts +12 -0
- package/src/server/utility/get-weekday-name.ts +24 -0
- package/src/server/utility/increment-date.ts +15 -0
- package/src/server/utility/is-index-path.ts +5 -0
- package/src/server/utility/key-to-date.ts +25 -0
- package/src/server/utility/month-has-week-containing-date.ts +13 -0
- package/src/server/utility/month-to-date.ts +28 -0
- package/src/server/utility/month-to-path.ts +10 -0
- package/src/server/utility/months-are-equal.ts +8 -0
- package/src/server/utility/parse-index-path.ts +23 -0
- package/src/server/utility/path-is-date.ts +13 -0
- package/src/server/utility/path-to-date.ts +24 -0
- package/src/server/utility/subtract-days.ts +7 -0
- package/src/server/utility/validate-month.ts +10 -0
- package/src/server/utility/validate-page.ts +46 -0
- package/src/server/utility/validate-path.ts +9 -0
- package/src/server/utility/validate-url.ts +12 -0
- package/src/server/utility/week-greater-than.ts +10 -0
- package/src/server/utility/week-to-date.ts +8 -0
- package/src/server/utility/week-to-path.ts +12 -0
- package/src/server/utility/weeks-are-equal.ts +8 -0
- package/src/server/utility/year-to-date.ts +26 -0
- package/src/server/utility/year-to-path.ts +7 -0
- package/src/server/utility/years-are-equal.ts +8 -0
- package/src/server.ts +140 -0
- package/src/test.ts +195 -0
- package/src/type/account-settings.ts +9 -0
- package/src/type/account.ts +11 -0
- package/src/type/action/add-block.ts +74 -0
- package/src/type/action/complete-block.ts +10 -0
- package/src/type/action/delete-block.ts +11 -0
- package/src/type/action/demote-block.ts +9 -0
- package/src/type/action/edit-block.ts +11 -0
- package/src/type/action/promote-block.ts +9 -0
- package/src/type/action.ts +9 -0
- package/src/type/block/audio.ts +8 -0
- package/src/type/block/background.ts +10 -0
- package/src/type/block/directory.ts +18 -0
- package/src/type/block/ephemeral.ts +9 -0
- package/src/type/block/folder.ts +14 -0
- package/src/type/block/header.ts +11 -0
- package/src/type/block/image.ts +8 -0
- package/src/type/block/link.ts +12 -0
- package/src/type/block/list.ts +24 -0
- package/src/type/block/multi-column.ts +10 -0
- package/src/type/block/note.ts +9 -0
- package/src/type/block/todo.ts +10 -0
- package/src/type/block/whitespace.ts +9 -0
- package/src/type/block-metadata.ts +14 -0
- package/src/type/block.ts +18 -0
- package/src/type/day.ts +5 -0
- package/src/type/field-definition.ts +8 -0
- package/src/type/field-value.ts +5 -0
- package/src/type/file.ts +6 -0
- package/src/type/month.ts +5 -0
- package/src/type/page.ts +8 -0
- package/src/type/price.ts +11 -0
- package/src/type/resource.ts +5 -0
- package/src/type/runtime-config.ts +13 -0
- package/src/type/server-settings.ts +17 -0
- package/src/type/toast.ts +8 -0
- package/src/type/week.ts +5 -0
- package/src/type/year.ts +5 -0
- package/test/unit/index.ts +11 -0
- package/test/unit/server/operation/promote-block.ts +84 -0
|
@@ -0,0 +1,665 @@
|
|
|
1
|
+
import {InvariantViolation} from 'lib/errors';
|
|
2
|
+
import {getFirstValue, getLastValue} from 'lib/array';
|
|
3
|
+
import {TimeInterval} from 'lib/time';
|
|
4
|
+
|
|
5
|
+
import Page from 'client/page';
|
|
6
|
+
import BlockType from 'enum/block-type';
|
|
7
|
+
import KeyCode from 'client/enum/key-code';
|
|
8
|
+
import getMetaValue from 'client/utility/get-meta-value';
|
|
9
|
+
import getParentPath from 'common/utility/get-parent-path';
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
function getAttributeForElement(element: Element, attribute: string): string {
|
|
13
|
+
const value = element.getAttribute(attribute);
|
|
14
|
+
|
|
15
|
+
if (value === null) {
|
|
16
|
+
throw new InvariantViolation(`
|
|
17
|
+
Tried to read ${attribute} for element, but it was not set
|
|
18
|
+
`);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return value;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function getBlockActivationHref(block_element: Element): string {
|
|
25
|
+
const link_nodes = block_element.getElementsByTagName('a');
|
|
26
|
+
const links = Array.from(link_nodes);
|
|
27
|
+
const matching_link = links.find((link) => {
|
|
28
|
+
const role = link.getAttribute('data-role');
|
|
29
|
+
|
|
30
|
+
return role === 'block_activation';
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
if (matching_link === undefined) {
|
|
34
|
+
throw new InvariantViolation(`
|
|
35
|
+
Tried to activate link for folder block, but it was not set
|
|
36
|
+
`);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const href = matching_link.getAttribute('href');
|
|
40
|
+
|
|
41
|
+
if (href === null) {
|
|
42
|
+
throw new InvariantViolation(`
|
|
43
|
+
Tried to activate link for folder block, but its href was not set
|
|
44
|
+
`);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return href;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function getIndexPathForElement(element: Element): string {
|
|
51
|
+
return getAttributeForElement(element, 'data-index-path');
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function getBlockTypeForElement(element: Element): string {
|
|
55
|
+
return getAttributeForElement(element, 'data-block-type');
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
class ViewCustomPage extends Page {
|
|
59
|
+
private logged_in = false;
|
|
60
|
+
private scroll_focusing_timer: NodeJS.Timeout | undefined;
|
|
61
|
+
private scroll_focusing_enabled = true;
|
|
62
|
+
private has_touch_event = false;
|
|
63
|
+
|
|
64
|
+
protected initEvents(): void {
|
|
65
|
+
super.initEvents();
|
|
66
|
+
|
|
67
|
+
window.addEventListener('touchstart', () => {
|
|
68
|
+
this.has_touch_event = true;
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
window.addEventListener('wheel', () => {
|
|
72
|
+
this.handleWheel();
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
window.addEventListener('scroll', () => {
|
|
76
|
+
this.handleScroll();
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
private handleWheel(): void {
|
|
81
|
+
this.enableScrollFocusing();
|
|
82
|
+
this.queueDisableScrollFocusing();
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
private handleScroll(): void {
|
|
86
|
+
if (!this.scrollFocusingEnabled()) {
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
if (this.hasTouchEvent()) {
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const scroll_element = this.getBlockElementFromScrollPosition();
|
|
95
|
+
|
|
96
|
+
if (scroll_element === null) {
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const index_path = getIndexPathForElement(scroll_element);
|
|
101
|
+
|
|
102
|
+
this.navigateToIndex(index_path);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
protected initView(): void {
|
|
106
|
+
this.focusCurrentBlockElement();
|
|
107
|
+
|
|
108
|
+
const meta_value = getMetaValue('logged_in');
|
|
109
|
+
|
|
110
|
+
this.logged_in = meta_value === 'true';
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
private getBlockElementFromScrollPosition(): Element | null {
|
|
114
|
+
const block_elements = this.getBlockElements();
|
|
115
|
+
const scroll_y = window.scrollY;
|
|
116
|
+
const view_height = window.innerHeight;
|
|
117
|
+
const page_height = document.documentElement.scrollHeight;
|
|
118
|
+
const total_scrollable_height = page_height - view_height;
|
|
119
|
+
const scroll_ratio = scroll_y / total_scrollable_height;
|
|
120
|
+
|
|
121
|
+
let total_area = 0;
|
|
122
|
+
|
|
123
|
+
block_elements.forEach((block_element) => {
|
|
124
|
+
const block_type = getBlockTypeForElement(block_element);
|
|
125
|
+
|
|
126
|
+
if (block_type === BlockType.MULTI_COLUMN) {
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
const rect = block_element.getBoundingClientRect();
|
|
131
|
+
const block_area = rect.width * rect.height;
|
|
132
|
+
|
|
133
|
+
total_area += block_area;
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
let index = 0;
|
|
137
|
+
let cumulative_area = 0;
|
|
138
|
+
|
|
139
|
+
while (index < block_elements.length) {
|
|
140
|
+
const block_element = block_elements[index++];
|
|
141
|
+
const block_type = getBlockTypeForElement(block_element);
|
|
142
|
+
|
|
143
|
+
if (block_type === BlockType.MULTI_COLUMN) {
|
|
144
|
+
continue;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
const rect = block_element.getBoundingClientRect();
|
|
148
|
+
const area = rect.width * rect.height;
|
|
149
|
+
|
|
150
|
+
cumulative_area += area;
|
|
151
|
+
|
|
152
|
+
const cumulative_ratio = cumulative_area / total_area;
|
|
153
|
+
|
|
154
|
+
if (cumulative_ratio >= scroll_ratio) {
|
|
155
|
+
return block_element;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
return null;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
private focusCurrentBlockElement(): void {
|
|
163
|
+
const element = this.getCurrentBlockElement();
|
|
164
|
+
|
|
165
|
+
if (element === null) {
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
this.focusElement(element);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
private enableScrollFocusing(): void {
|
|
173
|
+
if (this.scroll_focusing_timer !== undefined) {
|
|
174
|
+
clearTimeout(this.scroll_focusing_timer);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
this.scroll_focusing_enabled = true;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
private queueDisableScrollFocusing(): void {
|
|
181
|
+
if (this.scroll_focusing_timer !== undefined) {
|
|
182
|
+
clearTimeout(this.scroll_focusing_timer);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
const delay = TimeInterval.ONE_SECOND / 2;
|
|
186
|
+
|
|
187
|
+
this.scroll_focusing_timer = setTimeout(() => {
|
|
188
|
+
this.disableScrollFocusing();
|
|
189
|
+
}, delay);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
private disableScrollFocusing(): void {
|
|
193
|
+
if (this.scroll_focusing_timer !== undefined) {
|
|
194
|
+
clearTimeout(this.scroll_focusing_timer);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
this.scroll_focusing_enabled = false;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
protected handleKey(key_code: KeyCode): void {
|
|
201
|
+
switch (key_code) {
|
|
202
|
+
case KeyCode.ENTER:
|
|
203
|
+
case KeyCode.O:
|
|
204
|
+
return this.activateBlock();
|
|
205
|
+
|
|
206
|
+
case KeyCode.L:
|
|
207
|
+
return this.toggleEditMode();
|
|
208
|
+
|
|
209
|
+
case KeyCode.G:
|
|
210
|
+
return this.performPageJump();
|
|
211
|
+
|
|
212
|
+
case KeyCode.M:
|
|
213
|
+
return this.showModificationMenu();
|
|
214
|
+
|
|
215
|
+
case KeyCode.J:
|
|
216
|
+
return this.selectNextBlock();
|
|
217
|
+
|
|
218
|
+
case KeyCode.K:
|
|
219
|
+
return this.selectPreviousBlock();
|
|
220
|
+
|
|
221
|
+
case KeyCode.U:
|
|
222
|
+
return this.navigateToParentPage();
|
|
223
|
+
|
|
224
|
+
case KeyCode.D:
|
|
225
|
+
return this.deleteCurrentBlock();
|
|
226
|
+
|
|
227
|
+
case KeyCode.A:
|
|
228
|
+
return this.addBlock();
|
|
229
|
+
|
|
230
|
+
case KeyCode.E:
|
|
231
|
+
return this.beginEditingBlock();
|
|
232
|
+
|
|
233
|
+
default:
|
|
234
|
+
return super.handleKey(key_code);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
private beginEditingBlock(): void {
|
|
239
|
+
if (!this.isLoggedIn()) {
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
const block_element = this.getCurrentBlockElement();
|
|
244
|
+
|
|
245
|
+
if (block_element === null) {
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
const block_id = block_element.id;
|
|
250
|
+
const link_id = `${block_id}-edit`;
|
|
251
|
+
const link_element = document.getElementById(link_id) as HTMLFormElement;
|
|
252
|
+
|
|
253
|
+
if (link_element === null) {
|
|
254
|
+
throw new InvariantViolation(`
|
|
255
|
+
Unable to find edit link element for block: ${block_id}
|
|
256
|
+
`);
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
const href = link_element.getAttribute('href');
|
|
260
|
+
|
|
261
|
+
if (href === null) {
|
|
262
|
+
throw new InvariantViolation(`
|
|
263
|
+
Unable to find edit link href for block: ${block_id}
|
|
264
|
+
`);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
window.location.href = href;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
private addBlock(): void {
|
|
271
|
+
if (!this.isLoggedIn()) {
|
|
272
|
+
return;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
const current_path = this.getCurrentBlockIndex();
|
|
276
|
+
const top_level_index = parseInt(current_path, 10);
|
|
277
|
+
|
|
278
|
+
if (isNaN(top_level_index)) {
|
|
279
|
+
throw new InvariantViolation(`Invalid index path: ${current_path}`);
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
const add_block_links = document.querySelectorAll('[data-role="add_block_link"]');
|
|
283
|
+
|
|
284
|
+
const link_index = (() => {
|
|
285
|
+
if (this.shiftIsPressed()) {
|
|
286
|
+
return top_level_index;
|
|
287
|
+
} else {
|
|
288
|
+
return top_level_index + 1;
|
|
289
|
+
}
|
|
290
|
+
})();
|
|
291
|
+
|
|
292
|
+
const link = add_block_links[link_index];
|
|
293
|
+
|
|
294
|
+
if (link === undefined) {
|
|
295
|
+
throw new InvariantViolation(`
|
|
296
|
+
Tried to read link at index ${link_index},
|
|
297
|
+
but it was not found
|
|
298
|
+
`);
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
const href = link.getAttribute('href');
|
|
302
|
+
|
|
303
|
+
if (href === null) {
|
|
304
|
+
throw new InvariantViolation(`
|
|
305
|
+
Tried to read href for link at index ${link_index},
|
|
306
|
+
but it was not set
|
|
307
|
+
`);
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
window.location.href = href;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
private deleteCurrentBlock(): void {
|
|
314
|
+
if (!this.isLoggedIn()) {
|
|
315
|
+
return;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
const block_element = this.getCurrentBlockElement();
|
|
319
|
+
|
|
320
|
+
if (block_element === null) {
|
|
321
|
+
return;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
const block_id = block_element.id;
|
|
325
|
+
const link_id = `${block_id}-delete`;
|
|
326
|
+
const link_element = document.getElementById(link_id) as HTMLFormElement;
|
|
327
|
+
|
|
328
|
+
if (link_element === null) {
|
|
329
|
+
throw new InvariantViolation(`
|
|
330
|
+
Unable to find deletion link element for block: ${block_id}
|
|
331
|
+
`);
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
const href = link_element.getAttribute('href');
|
|
335
|
+
|
|
336
|
+
if (href === null) {
|
|
337
|
+
throw new InvariantViolation(`
|
|
338
|
+
Unable to find deletion link href for block: ${block_id}
|
|
339
|
+
`);
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
window.location.href = href;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
private promoteCurrentBlock(): void {
|
|
346
|
+
if (!this.isLoggedIn()) {
|
|
347
|
+
return;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
const block_element = this.getCurrentBlockElement();
|
|
351
|
+
|
|
352
|
+
if (block_element === null) {
|
|
353
|
+
return;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
const block_id = block_element.id;
|
|
357
|
+
const form_id = `${block_id}-promote`;
|
|
358
|
+
const form_element = document.getElementById(form_id) as HTMLFormElement;
|
|
359
|
+
|
|
360
|
+
if (form_element === null) {
|
|
361
|
+
throw new InvariantViolation(`
|
|
362
|
+
Unable to find promotion form element for block: ${block_id}
|
|
363
|
+
`);
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
form_element.submit();
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
private demoteCurrentBlock(): void {
|
|
370
|
+
if (!this.isLoggedIn()) {
|
|
371
|
+
return;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
const block_element = this.getCurrentBlockElement();
|
|
375
|
+
|
|
376
|
+
if (block_element === null) {
|
|
377
|
+
return;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
const block_id = block_element.id;
|
|
381
|
+
const form_id = `${block_id}-demote`;
|
|
382
|
+
const form_element = document.getElementById(form_id) as HTMLFormElement;
|
|
383
|
+
|
|
384
|
+
if (form_element === null) {
|
|
385
|
+
throw new InvariantViolation(`
|
|
386
|
+
Unable to find demotion form element for block: ${block_id}
|
|
387
|
+
`);
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
form_element.submit();
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
private performPageJump(): void {
|
|
394
|
+
if (!this.shiftIsPressed()) {
|
|
395
|
+
return;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
const previous_key_code = this.getPreviousKeyCode();
|
|
399
|
+
|
|
400
|
+
if (previous_key_code === KeyCode.ONE) {
|
|
401
|
+
this.jumpToPageTop();
|
|
402
|
+
} else {
|
|
403
|
+
this.jumpToPageBottom();
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
private jumpToPageTop(): void {
|
|
408
|
+
this.navigateToIndex(this.getFirstBlockIndex());
|
|
409
|
+
this.focusCurrentBlockElement();
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
private jumpToPageBottom(): void {
|
|
413
|
+
this.navigateToIndex(this.getLastBlockIndex());
|
|
414
|
+
this.focusCurrentBlockElement();
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
private navigateToParentPage(): void {
|
|
418
|
+
const parent_path = getParentPath(window.location.pathname);
|
|
419
|
+
|
|
420
|
+
window.location.href = parent_path;
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
private navigateToIndex(index_path: string | null): void {
|
|
424
|
+
this.disableScrollFocusing();
|
|
425
|
+
|
|
426
|
+
if (index_path === null) {
|
|
427
|
+
return;
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
const block_elements = this.getBlockElements();
|
|
431
|
+
|
|
432
|
+
let found = false;
|
|
433
|
+
|
|
434
|
+
block_elements.forEach((block_element) => {
|
|
435
|
+
const sibling_path = getIndexPathForElement(block_element);
|
|
436
|
+
const is_match = sibling_path === index_path;
|
|
437
|
+
|
|
438
|
+
block_element.classList.toggle('selected', is_match);
|
|
439
|
+
|
|
440
|
+
if (is_match) {
|
|
441
|
+
found = true;
|
|
442
|
+
}
|
|
443
|
+
});
|
|
444
|
+
|
|
445
|
+
if (!found) {
|
|
446
|
+
throw new InvariantViolation(`
|
|
447
|
+
Tried to navigate to element at index path ${index_path},
|
|
448
|
+
but matching element was not found
|
|
449
|
+
`);
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
const url = new URL(window.location.href);
|
|
453
|
+
|
|
454
|
+
url.searchParams.set('index_path', index_path);
|
|
455
|
+
window.history.replaceState({}, '', url);
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
protected selectPreviousBlock(): void {
|
|
459
|
+
if (this.shiftIsPressed()) {
|
|
460
|
+
this.promoteCurrentBlock();
|
|
461
|
+
} else {
|
|
462
|
+
this.navigateToIndex(this.getPreviousBlockIndex());
|
|
463
|
+
this.focusCurrentBlockElement();
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
protected selectNextBlock(): void {
|
|
468
|
+
if (this.shiftIsPressed()) {
|
|
469
|
+
this.demoteCurrentBlock();
|
|
470
|
+
} else {
|
|
471
|
+
this.navigateToIndex(this.getNextBlockIndex());
|
|
472
|
+
this.focusCurrentBlockElement();
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
protected toggleEditMode(): void {
|
|
477
|
+
const editing_flag = this.getQueryParameter('editing');
|
|
478
|
+
const editing = editing_flag === 'true';
|
|
479
|
+
const new_value = editing ? 'false' : 'true';
|
|
480
|
+
|
|
481
|
+
this.setQueryParameter('editing', new_value);
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
protected getCurrentBlockIndex(): string {
|
|
485
|
+
const element = this.getCurrentBlockElement();
|
|
486
|
+
|
|
487
|
+
if (element === null) {
|
|
488
|
+
return '0';
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
return getIndexPathForElement(element);
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
protected getCurrentBlockNumericIndex(): number {
|
|
495
|
+
const index = this.getCurrentBlockIndex();
|
|
496
|
+
|
|
497
|
+
return parseInt(index);
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
private getBlockElements(): Element[] {
|
|
501
|
+
const elements = document.getElementsByClassName('block');
|
|
502
|
+
|
|
503
|
+
return Array.from(elements);
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
protected getCurrentBlockElement(): Element | null {
|
|
507
|
+
const block_elements = this.getBlockElements();
|
|
508
|
+
|
|
509
|
+
const selected_element = block_elements.find((element) => {
|
|
510
|
+
return element.classList.contains('selected');
|
|
511
|
+
});
|
|
512
|
+
|
|
513
|
+
if (selected_element !== undefined) {
|
|
514
|
+
return selected_element;
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
const index_path = (() => {
|
|
518
|
+
const query_path = this.getQueryParameter('index_path');
|
|
519
|
+
|
|
520
|
+
if (query_path !== undefined) {
|
|
521
|
+
return query_path;
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
return this.getFirstBlockIndex();
|
|
525
|
+
})();
|
|
526
|
+
|
|
527
|
+
if (index_path === null) {
|
|
528
|
+
return null;
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
const element = block_elements.find((element) => {
|
|
532
|
+
const attribute = getIndexPathForElement(element);
|
|
533
|
+
|
|
534
|
+
return attribute === index_path;
|
|
535
|
+
});
|
|
536
|
+
|
|
537
|
+
return element || null;
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
protected getFirstBlockIndex(): string | null {
|
|
541
|
+
const blocks = this.getBlockElements();
|
|
542
|
+
const first_block = getFirstValue(blocks);
|
|
543
|
+
|
|
544
|
+
if (first_block === undefined) {
|
|
545
|
+
return null;
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
return getIndexPathForElement(first_block);
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
protected getLastBlockIndex(): string | null {
|
|
552
|
+
const blocks = this.getBlockElements();
|
|
553
|
+
const last_block = getLastValue(blocks);
|
|
554
|
+
|
|
555
|
+
if (last_block === undefined) {
|
|
556
|
+
return null;
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
return getIndexPathForElement(last_block);
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
protected getNextBlockIndex(): string | null {
|
|
563
|
+
const current_block = this.getCurrentBlockElement();
|
|
564
|
+
const blocks = this.getBlockElements();
|
|
565
|
+
const current_index = current_block ? blocks.indexOf(current_block) : -1;
|
|
566
|
+
const next_block = blocks[current_index + 1];
|
|
567
|
+
|
|
568
|
+
if (next_block === undefined) {
|
|
569
|
+
return null;
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
return getIndexPathForElement(next_block);
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
protected getPreviousBlockIndex(): string | null {
|
|
576
|
+
const current_block = this.getCurrentBlockElement();
|
|
577
|
+
const blocks = this.getBlockElements();
|
|
578
|
+
const current_index = current_block ? blocks.indexOf(current_block) : -1;
|
|
579
|
+
const previous_block = blocks[current_index - 1];
|
|
580
|
+
|
|
581
|
+
if (previous_block === undefined) {
|
|
582
|
+
return null;
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
return previous_block.getAttribute('data-index-path');
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
private activateBlock(): void {
|
|
589
|
+
const block_element = this.getCurrentBlockElement();
|
|
590
|
+
|
|
591
|
+
if (block_element === null) {
|
|
592
|
+
return;
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
const attribute = block_element.getAttribute('data-block-type');
|
|
596
|
+
|
|
597
|
+
if (attribute === null) {
|
|
598
|
+
throw new InvariantViolation(`
|
|
599
|
+
Tried to activate current block, but it did not have a block type
|
|
600
|
+
`);
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
const block_type = attribute as BlockType;
|
|
604
|
+
const block_types = Object.values(BlockType);
|
|
605
|
+
|
|
606
|
+
if (!block_types.includes(block_type)) {
|
|
607
|
+
throw new InvariantViolation(`
|
|
608
|
+
Invalid block type: ${block_type}
|
|
609
|
+
`);
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
switch (block_type) {
|
|
613
|
+
case BlockType.FOLDER:
|
|
614
|
+
return this.activateFolderBlock(block_element);
|
|
615
|
+
case BlockType.TODO:
|
|
616
|
+
return this.activateTodoBlock(block_element);
|
|
617
|
+
case BlockType.IMAGE:
|
|
618
|
+
return this.activateImageBlock(block_element);
|
|
619
|
+
default:
|
|
620
|
+
return console.warn(`no-op activation for block of type ${block_type}`);
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
private activateTodoBlock(block_element: Element): void {
|
|
625
|
+
const forms = block_element.getElementsByTagName('form');
|
|
626
|
+
const form = forms[0];
|
|
627
|
+
|
|
628
|
+
if (form === undefined) {
|
|
629
|
+
throw new InvariantViolation(`
|
|
630
|
+
Tried to activate form for todo block, but it was not set
|
|
631
|
+
`);
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
form.submit();
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
private activateFolderBlock(block_element: Element): void {
|
|
638
|
+
const href = getBlockActivationHref(block_element);
|
|
639
|
+
|
|
640
|
+
window.location.href = href;
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
private activateImageBlock(block_element: Element): void {
|
|
644
|
+
const href = getBlockActivationHref(block_element);
|
|
645
|
+
|
|
646
|
+
window.location.href = href;
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
private showModificationMenu(): void {
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
private isLoggedIn(): boolean {
|
|
653
|
+
return this.logged_in;
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
private scrollFocusingEnabled(): boolean {
|
|
657
|
+
return this.scroll_focusing_enabled;
|
|
658
|
+
}
|
|
659
|
+
|
|
660
|
+
private hasTouchEvent(): boolean {
|
|
661
|
+
return this.has_touch_event;
|
|
662
|
+
}
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
export default ViewCustomPage;
|