ember-source 6.12.0-beta.3 → 7.0.0-alpha.1
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/blueprints/initializer-test/files/__root__/__testType__/__path__/__name__-test.ts +2 -2
- package/blueprints/instance-initializer-test/files/__root__/__testType__/__path__/__name__-test.ts +3 -3
- package/build-metadata.json +3 -3
- package/dist/{packages/shared-chunks/registry-XY5cfmbH.js → dev/packages/@ember/-internals/container/index.js} +28 -27
- package/dist/{packages → dev/packages}/@ember/-internals/deprecations/index.js +5 -16
- package/dist/{packages/shared-chunks/env-DEd6hPbj.js → dev/packages/@ember/-internals/environment/index.js} +31 -53
- package/dist/dev/packages/@ember/-internals/glimmer/index.js +42 -0
- package/dist/{packages → dev/packages}/@ember/-internals/meta/lib/meta.js +37 -38
- package/dist/dev/packages/@ember/-internals/metal/index.js +63 -0
- package/dist/{packages → dev/packages}/@ember/-internals/routing/index.js +7 -8
- package/dist/{packages → dev/packages}/@ember/-internals/runtime/lib/ext/rsvp.js +1 -2
- package/dist/{packages → dev/packages}/@ember/-internals/runtime/lib/mixins/-proxy.js +14 -15
- package/dist/{packages → dev/packages}/@ember/-internals/runtime/lib/mixins/action_handler.js +21 -9
- package/dist/{packages → dev/packages}/@ember/-internals/runtime/lib/mixins/registry_proxy.js +11 -2
- package/dist/{packages → dev/packages}/@ember/-internals/runtime/lib/mixins/target_action_support.js +22 -9
- package/dist/{packages → dev/packages}/@ember/-internals/string/index.js +1 -2
- package/dist/dev/packages/@ember/-internals/utils/index.js +34 -0
- package/dist/{packages → dev/packages}/@ember/-internals/views/lib/compat/fallback-view-registry.js +1 -2
- package/dist/{packages → dev/packages}/@ember/-internals/views/lib/mixins/action_support.js +16 -10
- package/dist/{packages → dev/packages}/@ember/-internals/views/lib/system/event_dispatcher.js +19 -20
- package/dist/{packages → dev/packages}/@ember/-internals/views/lib/system/utils.js +7 -23
- package/dist/{packages → dev/packages}/@ember/-internals/views/lib/views/core_view.js +6 -7
- package/dist/{packages → dev/packages}/@ember/-internals/views/lib/views/states.js +3 -4
- package/dist/{packages → dev/packages}/@ember/application/index.js +50 -121
- package/dist/{packages → dev/packages}/@ember/application/instance.js +17 -17
- package/dist/{packages → dev/packages}/@ember/application/namespace.js +27 -9
- package/dist/{packages → dev/packages}/@ember/array/index.js +34 -25
- package/dist/{packages → dev/packages}/@ember/array/proxy.js +19 -20
- package/dist/{packages → dev/packages}/@ember/canary-features/index.js +1 -1
- package/dist/dev/packages/@ember/component/helper.js +14 -0
- package/dist/{packages → dev/packages}/@ember/component/index.js +12 -12
- package/dist/{packages → dev/packages}/@ember/component/template-only.js +6 -6
- package/dist/{packages → dev/packages}/@ember/controller/index.js +7 -9
- package/dist/{packages → dev/packages}/@ember/debug/container-debug-adapter.js +6 -7
- package/dist/{packages → dev/packages}/@ember/debug/data-adapter.js +6 -7
- package/dist/{packages → dev/packages}/@ember/debug/index.js +4 -11
- package/dist/{packages → dev/packages}/@ember/debug/lib/assert.js +1 -3
- package/dist/{packages → dev/packages}/@ember/debug/lib/deprecate.js +7 -3
- package/dist/{packages → dev/packages}/@ember/debug/lib/handlers.js +1 -3
- package/dist/{packages → dev/packages}/@ember/debug/lib/warn.js +1 -2
- package/dist/{packages → dev/packages}/@ember/engine/index.js +22 -22
- package/dist/dev/packages/@ember/engine/instance.js +200 -0
- package/dist/{packages → dev/packages}/@ember/helper/index.js +12 -11
- package/dist/{packages → dev/packages}/@ember/instrumentation/index.js +3 -8
- package/dist/dev/packages/@ember/modifier/index.js +23 -0
- package/dist/{packages → dev/packages}/@ember/modifier/on.js +6 -6
- package/dist/dev/packages/@ember/object/-internals.js +49 -0
- package/dist/{packages → dev/packages}/@ember/object/compat.js +11 -12
- package/dist/{packages → dev/packages}/@ember/object/computed.js +7 -8
- package/dist/{packages → dev/packages}/@ember/object/core.js +28 -29
- package/dist/{packages → dev/packages}/@ember/object/evented.js +7 -8
- package/dist/dev/packages/@ember/object/events.js +11 -0
- package/dist/{packages → dev/packages}/@ember/object/index.js +18 -19
- package/dist/{packages → dev/packages}/@ember/object/internals.js +1 -1
- package/dist/{packages → dev/packages}/@ember/object/lib/computed/computed_macros.js +30 -27
- package/dist/{packages → dev/packages}/@ember/object/lib/computed/reduce_computed_macros.js +36 -37
- package/dist/{packages → dev/packages}/@ember/object/mixin.js +15 -23
- package/dist/dev/packages/@ember/object/observable.js +181 -0
- package/dist/dev/packages/@ember/object/observers.js +11 -0
- package/dist/{packages → dev/packages}/@ember/object/promise-proxy-mixin.js +7 -8
- package/dist/dev/packages/@ember/renderer/index.js +14 -0
- package/dist/dev/packages/@ember/routing/-internals.js +22 -0
- package/dist/{packages → dev/packages}/@ember/routing/hash-location.js +1 -1
- package/dist/{packages → dev/packages}/@ember/routing/history-location.js +9 -25
- package/dist/dev/packages/@ember/routing/index.js +14 -0
- package/dist/{packages → dev/packages}/@ember/routing/lib/dsl.js +5 -6
- package/dist/{packages → dev/packages}/@ember/routing/lib/generate_controller.js +22 -10
- package/dist/{packages → dev/packages}/@ember/routing/lib/location-utils.js +3 -16
- package/dist/{packages → dev/packages}/@ember/routing/lib/routing-service.js +19 -9
- package/dist/{packages → dev/packages}/@ember/routing/lib/utils.js +12 -13
- package/dist/{packages → dev/packages}/@ember/routing/none-location.js +2 -4
- package/dist/{packages → dev/packages}/@ember/routing/route.js +38 -39
- package/dist/{packages → dev/packages}/@ember/routing/router-service.js +13 -14
- package/dist/{packages → dev/packages}/@ember/routing/router.js +63 -71
- package/dist/{packages → dev/packages}/@ember/runloop/index.js +9 -8
- package/dist/{packages → dev/packages}/@ember/service/index.js +6 -7
- package/dist/dev/packages/@ember/template/index.js +14 -0
- package/dist/{packages → dev/packages}/@ember/template-compilation/index.js +3 -3
- package/dist/dev/packages/@ember/template-compiler/index.js +2 -0
- package/dist/{packages → dev/packages}/@ember/template-compiler/lib/compile-options.js +11 -6
- package/dist/{packages → dev/packages}/@ember/template-compiler/lib/dasherize-component-name.js +1 -2
- package/dist/dev/packages/@ember/template-compiler/lib/plugins/allowed-globals.js +56 -0
- package/dist/{packages → dev/packages}/@ember/template-compiler/lib/plugins/assert-against-attrs.js +19 -3
- package/dist/{packages → dev/packages}/@ember/template-compiler/lib/plugins/assert-against-named-outlets.js +11 -2
- package/dist/{packages → dev/packages}/@ember/template-compiler/lib/plugins/assert-input-helper-without-block.js +1 -2
- package/dist/{packages → dev/packages}/@ember/template-compiler/lib/plugins/assert-reserved-named-arguments.js +3 -4
- package/dist/dev/packages/@ember/template-compiler/lib/plugins/index.js +40 -0
- package/dist/{packages → dev/packages}/@ember/template-compiler/lib/plugins/transform-each-track-array.js +21 -2
- package/dist/dev/packages/@ember/template-compiler/lib/plugins/transform-in-element.js +50 -0
- package/dist/{packages → dev/packages}/@ember/template-compiler/lib/plugins/transform-resolutions.js +2 -3
- package/dist/dev/packages/@ember/template-compiler/lib/template.js +248 -0
- package/dist/dev/packages/@ember/template-factory/index.js +8 -0
- package/dist/dev/packages/@ember/test/index.js +18 -0
- package/dist/{packages → dev/packages}/@ember/utils/lib/compare.js +5 -6
- package/dist/{packages → dev/packages}/@ember/utils/lib/is_empty.js +6 -7
- package/dist/{packages → dev/packages}/@glimmer/destroyable/index.js +21 -16
- package/dist/{packages/shared-chunks/encoder-CT1wqYMF.js → dev/packages/@glimmer/encoder/index.js} +3 -4
- package/dist/{packages → dev/packages}/@glimmer/global-context/index.js +6 -5
- package/dist/{packages/shared-chunks/api-1B_9SjFR.js → dev/packages/@glimmer/manager/index.js} +17 -14
- package/dist/dev/packages/@glimmer/node/index.js +40 -0
- package/dist/{packages → dev/packages}/@glimmer/opcode-compiler/index.js +5 -6
- package/dist/dev/packages/@glimmer/program/index.js +12 -0
- package/dist/dev/packages/@glimmer/reference/index.js +208 -0
- package/dist/dev/packages/@glimmer/runtime/index.js +11 -0
- package/dist/dev/packages/@glimmer/tracking/index.js +137 -0
- package/dist/dev/packages/@glimmer/tracking/primitives/cache/index.js +11 -0
- package/dist/{packages → dev/packages}/@glimmer/util/index.js +2 -3
- package/dist/{packages → dev/packages}/@glimmer/validator/index.js +304 -372
- package/dist/{packages → dev/packages}/@glimmer/vm/index.js +1 -1
- package/dist/{packages → dev/packages}/ember/version.js +2 -2
- package/dist/dev/packages/ember-template-compiler/index.js +109 -0
- package/dist/{packages → dev/packages}/ember-testing/index.js +1 -3
- package/dist/dev/packages/ember-testing/lib/public-api.js +2 -0
- package/dist/dev/packages/ember-testing/lib/test/pending_requests.js +10 -0
- package/dist/dev/packages/ember-testing/lib/test.js +25 -0
- package/dist/{packages/shared-chunks/router-DSi8WnDi.js → dev/packages/router_js/index.js} +120 -58
- package/dist/{packages/shared-chunks/alias-BEMS3qgG.js → dev/packages/shared-chunks/alias-CSC0WIbj.js} +4 -5
- package/dist/{packages/shared-chunks/api-CkUl6KyJ.js → dev/packages/shared-chunks/api-BqXkkT0p.js} +14 -16
- package/dist/{packages/shared-chunks/args-proxy-B91L3LRK.js → dev/packages/shared-chunks/args-proxy-DgXMc9b5.js} +7 -8
- package/dist/{packages/shared-chunks/array-BqYCCatg.js → dev/packages/shared-chunks/array-D8PfjQHi.js} +3 -4
- package/dist/dev/packages/shared-chunks/capabilities-O_xc7Yqk.js +34 -0
- package/dist/{packages/shared-chunks/collections-B8me-ZlQ.js → dev/packages/shared-chunks/collections-D_nY_0UJ.js} +1 -2
- package/dist/{packages/@ember/template-compiler/lib/template.js → dev/packages/shared-chunks/compiler-CNj62pww.js} +22 -243
- package/dist/{packages/shared-chunks/constants-oDhF27qL.js → dev/packages/shared-chunks/constants-eoaL3OJQ.js} +9 -9
- package/dist/{packages/shared-chunks/debug-to-string-BsFOvUtQ.js → dev/packages/shared-chunks/debug-to-string-CFb7h0lY.js} +1 -3
- package/dist/{packages/shared-chunks/dynamic-CuBsUXX8.js → dev/packages/shared-chunks/dynamic-CFg3dljk.js} +108 -134
- package/dist/{packages/shared-chunks/element-builder-BuVym8EM.js → dev/packages/shared-chunks/element-builder-BOxP8emt.js} +4 -5
- package/dist/{packages/shared-chunks/flags-BsZlvEeR.js → dev/packages/shared-chunks/flags-B9qxc-pB.js} +1 -1
- package/dist/{packages/shared-chunks/capabilities-DHiXCCuB.js → dev/packages/shared-chunks/fragment-Cc5k9Oy4.js} +2 -33
- package/dist/{packages/shared-chunks/index-ByyoGpfz.js → dev/packages/shared-chunks/index-PxU6E7q8.js} +658 -214
- package/dist/{packages/shared-chunks/index-CQkjwqTv.js → dev/packages/shared-chunks/index-Q7JnrdBn.js} +20 -19
- package/dist/dev/packages/shared-chunks/invoke-DxRPE05O.js +67 -0
- package/dist/{packages/shared-chunks/is_proxy-C2q5rUMp.js → dev/packages/shared-chunks/is_proxy-B0smdQy8.js} +1 -1
- package/dist/{packages/shared-chunks/mandatory-setter-DLKyVs4Q.js → dev/packages/shared-chunks/mandatory-setter-DHZe7-kW.js} +47 -48
- package/dist/{packages/shared-chunks/name-DVtQREj6.js → dev/packages/shared-chunks/name-Z7dpqvzn.js} +1 -1
- package/dist/{packages/shared-chunks/namespace_search-ClQOZuFA.js → dev/packages/shared-chunks/namespace_search-uT8odThF.js} +3 -4
- package/dist/{packages/shared-chunks/observers-DhgQ6ba5.js → dev/packages/shared-chunks/observers-Bj9qLVau.js} +231 -87
- package/dist/{packages/shared-chunks/program-CcLlGnAU.js → dev/packages/shared-chunks/program-DfV0v8aa.js} +4 -6
- package/dist/{packages/shared-chunks/program-context-CZJnCFdo.js → dev/packages/shared-chunks/program-context-BRjCC_BA.js} +2 -2
- package/dist/{packages/shared-chunks/property_set-DrZnfGQ7.js → dev/packages/shared-chunks/property_set-DaoZXGM5.js} +11 -16
- package/dist/dev/packages/shared-chunks/public-api-C3KlJmEr.js +10 -0
- package/dist/{packages/shared-chunks/reference-B6HMX4y0.js → dev/packages/shared-chunks/reference-C3TKDRnP.js} +11 -12
- package/dist/{packages/@glimmer/runtime/index.js → dev/packages/shared-chunks/rehydrate-builder-DPImr9e9.js} +8 -16
- package/dist/{packages/shared-chunks/render-DTOhhssy.js → dev/packages/shared-chunks/render-sg8BuFaE.js} +16 -23
- package/dist/{packages/shared-chunks/serialize-builder-DEgRJgNQ.js → dev/packages/shared-chunks/serialize-builder-b_gSYCSS.js} +7 -7
- package/dist/{packages/shared-chunks/set_properties-Dag9Xz6u.js → dev/packages/shared-chunks/set_properties-kVGzZL_a.js} +2 -2
- package/dist/{packages/shared-chunks/setup-registry-Bbj8WQen.js → dev/packages/shared-chunks/setup-registry-DGdDOxrk.js} +12 -12
- package/dist/{packages/shared-chunks/simple-cast-BXTrayoV.js → dev/packages/shared-chunks/simple-cast-DCvJLSin.js} +1 -1
- package/dist/{packages/shared-chunks/template-CMHIG4cn.js → dev/packages/shared-chunks/template-kM-7TTcc.js} +3 -4
- package/dist/dev/packages/shared-chunks/to-string-C7M8LBLH.js +36 -0
- package/dist/{packages/shared-chunks/transform-resolutions-vHYYonpB.js → dev/packages/shared-chunks/transform-resolutions-fXGQKGsL.js} +331 -288
- package/dist/{packages/shared-chunks/unrecognized-url-error-BBMMZhBN.js → dev/packages/shared-chunks/unrecognized-url-error-B3wUTorp.js} +103 -39
- package/dist/prod/packages/@ember/-internals/browser-environment/index.js +2 -0
- package/dist/prod/packages/@ember/-internals/container/index.js +697 -0
- package/dist/prod/packages/@ember/-internals/deprecations/index.js +114 -0
- package/dist/prod/packages/@ember/-internals/environment/index.js +171 -0
- package/dist/prod/packages/@ember/-internals/error-handling/index.js +26 -0
- package/dist/prod/packages/@ember/-internals/glimmer/index.js +39 -0
- package/dist/prod/packages/@ember/-internals/meta/index.js +1 -0
- package/dist/prod/packages/@ember/-internals/meta/lib/meta.js +455 -0
- package/dist/prod/packages/@ember/-internals/metal/index.js +61 -0
- package/dist/prod/packages/@ember/-internals/owner/index.js +252 -0
- package/dist/prod/packages/@ember/-internals/routing/index.js +14 -0
- package/dist/prod/packages/@ember/-internals/runtime/index.js +9 -0
- package/dist/prod/packages/@ember/-internals/runtime/lib/ext/rsvp.js +51 -0
- package/dist/prod/packages/@ember/-internals/runtime/lib/mixins/-proxy.js +89 -0
- package/dist/prod/packages/@ember/-internals/runtime/lib/mixins/action_handler.js +187 -0
- package/dist/prod/packages/@ember/-internals/runtime/lib/mixins/comparable.js +37 -0
- package/dist/prod/packages/@ember/-internals/runtime/lib/mixins/container_proxy.js +44 -0
- package/dist/prod/packages/@ember/-internals/runtime/lib/mixins/registry_proxy.js +42 -0
- package/dist/prod/packages/@ember/-internals/runtime/lib/mixins/target_action_support.js +142 -0
- package/dist/prod/packages/@ember/-internals/string/index.js +93 -0
- package/dist/prod/packages/@ember/-internals/utility-types/index.js +12 -0
- package/dist/prod/packages/@ember/-internals/utils/index.js +75 -0
- package/dist/prod/packages/@ember/-internals/views/index.js +7 -0
- package/dist/prod/packages/@ember/-internals/views/lib/compat/attrs.js +3 -0
- package/dist/prod/packages/@ember/-internals/views/lib/compat/fallback-view-registry.js +7 -0
- package/dist/prod/packages/@ember/-internals/views/lib/component_lookup.js +14 -0
- package/dist/prod/packages/@ember/-internals/views/lib/mixins/action_support.js +35 -0
- package/dist/prod/packages/@ember/-internals/views/lib/system/event_dispatcher.js +227 -0
- package/dist/prod/packages/@ember/-internals/views/lib/system/utils.js +172 -0
- package/dist/prod/packages/@ember/-internals/views/lib/views/core_view.js +87 -0
- package/dist/prod/packages/@ember/-internals/views/lib/views/states.js +83 -0
- package/dist/prod/packages/@ember/application/index.js +899 -0
- package/dist/prod/packages/@ember/application/instance.js +438 -0
- package/dist/prod/packages/@ember/application/namespace.js +68 -0
- package/dist/prod/packages/@ember/array/-internals.js +9 -0
- package/dist/prod/packages/@ember/array/index.js +591 -0
- package/dist/prod/packages/@ember/array/lib/make-array.js +42 -0
- package/dist/prod/packages/@ember/array/make.js +1 -0
- package/dist/prod/packages/@ember/array/mutable.js +1 -0
- package/dist/prod/packages/@ember/array/proxy.js +267 -0
- package/dist/prod/packages/@ember/canary-features/index.js +67 -0
- package/dist/prod/packages/@ember/component/helper.js +12 -0
- package/dist/prod/packages/@ember/component/index.js +32 -0
- package/dist/prod/packages/@ember/component/template-only.js +39 -0
- package/dist/prod/packages/@ember/controller/index.js +177 -0
- package/dist/prod/packages/@ember/debug/container-debug-adapter.js +117 -0
- package/dist/prod/packages/@ember/debug/data-adapter.js +553 -0
- package/dist/prod/packages/@ember/debug/index.js +30 -0
- package/dist/prod/packages/@ember/debug/lib/assert.js +7 -0
- package/dist/prod/packages/@ember/debug/lib/capture-render-tree.js +28 -0
- package/dist/prod/packages/@ember/debug/lib/deprecate.js +56 -0
- package/dist/prod/packages/@ember/debug/lib/handlers.js +5 -0
- package/dist/prod/packages/@ember/debug/lib/inspect.js +120 -0
- package/dist/prod/packages/@ember/debug/lib/testing.js +9 -0
- package/dist/prod/packages/@ember/debug/lib/warn.js +6 -0
- package/dist/prod/packages/@ember/deprecated-features/index.js +7 -0
- package/dist/prod/packages/@ember/destroyable/index.js +251 -0
- package/dist/prod/packages/@ember/engine/index.js +450 -0
- package/dist/{packages → prod/packages}/@ember/engine/instance.js +24 -10
- package/dist/prod/packages/@ember/engine/lib/engine-parent.js +33 -0
- package/dist/prod/packages/@ember/engine/parent.js +1 -0
- package/dist/prod/packages/@ember/enumerable/index.js +20 -0
- package/dist/prod/packages/@ember/enumerable/mutable.js +22 -0
- package/dist/prod/packages/@ember/helper/index.js +489 -0
- package/dist/prod/packages/@ember/instrumentation/index.js +242 -0
- package/dist/prod/packages/@ember/modifier/index.js +21 -0
- package/dist/prod/packages/@ember/modifier/on.js +20 -0
- package/dist/prod/packages/@ember/object/-internals.js +28 -0
- package/dist/prod/packages/@ember/object/compat.js +128 -0
- package/dist/prod/packages/@ember/object/computed.js +10 -0
- package/dist/prod/packages/@ember/object/core.js +781 -0
- package/dist/prod/packages/@ember/object/evented.js +76 -0
- package/dist/prod/packages/@ember/object/events.js +6 -0
- package/dist/prod/packages/@ember/object/index.js +205 -0
- package/dist/prod/packages/@ember/object/internals.js +8 -0
- package/dist/prod/packages/@ember/object/lib/computed/computed_macros.js +776 -0
- package/dist/prod/packages/@ember/object/lib/computed/reduce_computed_macros.js +1032 -0
- package/dist/prod/packages/@ember/object/mixin.js +560 -0
- package/dist/{packages → prod/packages}/@ember/object/observable.js +80 -15
- package/dist/prod/packages/@ember/object/observers.js +6 -0
- package/dist/prod/packages/@ember/object/promise-proxy-mixin.js +138 -0
- package/dist/prod/packages/@ember/object/proxy.js +98 -0
- package/dist/prod/packages/@ember/owner/index.js +88 -0
- package/dist/prod/packages/@ember/reactive/collections.js +1 -0
- package/dist/prod/packages/@ember/reactive/index.js +12 -0
- package/dist/prod/packages/@ember/renderer/index.js +12 -0
- package/dist/prod/packages/@ember/routing/hash-location.js +153 -0
- package/dist/prod/packages/@ember/routing/history-location.js +250 -0
- package/dist/prod/packages/@ember/routing/index.js +12 -0
- package/dist/prod/packages/@ember/routing/lib/cache.js +37 -0
- package/dist/prod/packages/@ember/routing/lib/controller_for.js +16 -0
- package/dist/prod/packages/@ember/routing/lib/dsl.js +178 -0
- package/dist/prod/packages/@ember/routing/lib/generate_controller.js +62 -0
- package/dist/prod/packages/@ember/routing/lib/location-utils.js +48 -0
- package/dist/prod/packages/@ember/routing/lib/query_params.js +9 -0
- package/dist/prod/packages/@ember/routing/lib/router_state.js +26 -0
- package/dist/prod/packages/@ember/routing/lib/routing-service.js +125 -0
- package/dist/prod/packages/@ember/routing/lib/utils.js +236 -0
- package/dist/prod/packages/@ember/routing/none-location.js +120 -0
- package/dist/prod/packages/@ember/routing/route.js +1604 -0
- package/dist/prod/packages/@ember/routing/router-service.js +640 -0
- package/dist/prod/packages/@ember/routing/router.js +1335 -0
- package/dist/prod/packages/@ember/runloop/index.js +736 -0
- package/dist/prod/packages/@ember/service/index.js +124 -0
- package/dist/prod/packages/@ember/template/index.js +12 -0
- package/dist/prod/packages/@ember/template-compilation/index.js +20 -0
- package/dist/prod/packages/@ember/template-compiler/-internal-primitives.js +1 -0
- package/dist/prod/packages/@ember/template-compiler/-internal-utils.js +1 -0
- package/dist/prod/packages/@ember/template-compiler/index.js +2 -0
- package/dist/prod/packages/@ember/template-compiler/lib/-internal/primitives.js +1 -0
- package/dist/prod/packages/@ember/template-compiler/lib/compile-options.js +103 -0
- package/dist/prod/packages/@ember/template-compiler/lib/dasherize-component-name.js +21 -0
- package/dist/prod/packages/@ember/template-compiler/lib/plugins/allowed-globals.js +56 -0
- package/dist/prod/packages/@ember/template-compiler/lib/plugins/assert-against-attrs.js +49 -0
- package/dist/prod/packages/@ember/template-compiler/lib/plugins/assert-against-named-outlets.js +34 -0
- package/dist/prod/packages/@ember/template-compiler/lib/plugins/assert-input-helper-without-block.js +22 -0
- package/dist/prod/packages/@ember/template-compiler/lib/plugins/assert-reserved-named-arguments.js +37 -0
- package/dist/{packages → prod/packages}/@ember/template-compiler/lib/plugins/index.js +1 -1
- package/dist/prod/packages/@ember/template-compiler/lib/plugins/transform-action-syntax.js +65 -0
- package/dist/prod/packages/@ember/template-compiler/lib/plugins/transform-each-in-into-each.js +51 -0
- package/dist/prod/packages/@ember/template-compiler/lib/plugins/transform-each-track-array.js +50 -0
- package/dist/{packages → prod/packages}/@ember/template-compiler/lib/plugins/transform-in-element.js +20 -6
- package/dist/prod/packages/@ember/template-compiler/lib/plugins/transform-quoted-bindings-into-just-bindings.js +37 -0
- package/dist/prod/packages/@ember/template-compiler/lib/plugins/transform-resolutions.js +4 -0
- package/dist/prod/packages/@ember/template-compiler/lib/plugins/transform-wrap-mount-and-outlet.js +57 -0
- package/dist/prod/packages/@ember/template-compiler/lib/plugins/utils.js +55 -0
- package/dist/prod/packages/@ember/template-compiler/lib/public-api.js +1 -0
- package/dist/prod/packages/@ember/template-compiler/lib/runtime.js +1 -0
- package/dist/prod/packages/@ember/template-compiler/lib/system/calculate-location-display.js +28 -0
- package/dist/prod/packages/@ember/template-compiler/lib/template.js +245 -0
- package/dist/prod/packages/@ember/template-factory/index.js +5 -0
- package/dist/prod/packages/@ember/test/adapter.js +2 -0
- package/dist/prod/packages/@ember/test/index.js +18 -0
- package/dist/prod/packages/@ember/utils/index.js +7 -0
- package/dist/prod/packages/@ember/utils/lib/compare.js +159 -0
- package/dist/prod/packages/@ember/utils/lib/is-equal.js +60 -0
- package/dist/prod/packages/@ember/utils/lib/is_blank.js +36 -0
- package/dist/prod/packages/@ember/utils/lib/is_empty.js +67 -0
- package/dist/prod/packages/@ember/utils/lib/is_none.js +28 -0
- package/dist/prod/packages/@ember/utils/lib/is_present.js +39 -0
- package/dist/prod/packages/@ember/utils/lib/type-of.js +110 -0
- package/dist/prod/packages/@ember/version/index.js +1 -0
- package/dist/prod/packages/@glimmer/destroyable/index.js +128 -0
- package/dist/prod/packages/@glimmer/encoder/index.js +28 -0
- package/dist/prod/packages/@glimmer/env/index.js +4 -0
- package/dist/prod/packages/@glimmer/global-context/index.js +138 -0
- package/dist/prod/packages/@glimmer/manager/index.js +293 -0
- package/dist/{packages/shared-chunks/node-dom-helper-BYL7Plyj.js → prod/packages/@glimmer/node/index.js} +10 -12
- package/dist/prod/packages/@glimmer/opcode-compiler/index.js +40 -0
- package/dist/prod/packages/@glimmer/owner/index.js +19 -0
- package/dist/prod/packages/@glimmer/program/index.js +12 -0
- package/dist/{packages/shared-chunks/iterable-BKS7az3P.js → prod/packages/@glimmer/reference/index.js} +13 -12
- package/dist/prod/packages/@glimmer/runtime/index.js +9 -0
- package/dist/prod/packages/@glimmer/tracking/index.js +115 -0
- package/dist/prod/packages/@glimmer/tracking/primitives/cache/index.js +6 -0
- package/dist/prod/packages/@glimmer/util/index.js +129 -0
- package/dist/prod/packages/@glimmer/validator/index.js +1027 -0
- package/dist/prod/packages/@glimmer/vm/index.js +15 -0
- package/dist/prod/packages/@glimmer/wire-format/index.js +102 -0
- package/dist/prod/packages/@simple-dom/document/index.js +355 -0
- package/dist/prod/packages/backburner.js/index.js +939 -0
- package/dist/prod/packages/dag-map/index.js +202 -0
- package/dist/prod/packages/ember/version.js +4 -0
- package/dist/prod/packages/ember-template-compiler/index.js +100 -0
- package/dist/prod/packages/ember-testing/index.js +6 -0
- package/dist/prod/packages/ember-testing/lib/adapters/adapter.js +49 -0
- package/dist/prod/packages/ember-testing/lib/public-api.js +2 -0
- package/dist/prod/packages/ember-testing/lib/test/adapter.js +32 -0
- package/dist/prod/packages/ember-testing/lib/test/pending_requests.js +10 -0
- package/dist/prod/packages/ember-testing/lib/test/waiters.js +128 -0
- package/dist/prod/packages/ember-testing/lib/test.js +25 -0
- package/dist/prod/packages/route-recognizer/index.js +671 -0
- package/dist/prod/packages/router_js/index.js +1527 -0
- package/dist/prod/packages/rsvp/index.js +1 -0
- package/dist/prod/packages/shared-chunks/alias-BkT-0B1G.js +81 -0
- package/dist/prod/packages/shared-chunks/api-Co-k4HVs.js +200 -0
- package/dist/prod/packages/shared-chunks/args-proxy-Dl0A0YWI.js +131 -0
- package/dist/prod/packages/shared-chunks/array-EwekEvId.js +117 -0
- package/dist/prod/packages/shared-chunks/array-utils-CZQxrdD3.js +45 -0
- package/dist/prod/packages/shared-chunks/assert-CUCJBR2C.js +19 -0
- package/dist/prod/packages/shared-chunks/cache-qDyqAcpg.js +35 -0
- package/dist/prod/packages/shared-chunks/capabilities-DGmQ_mz4.js +26 -0
- package/dist/prod/packages/shared-chunks/chunk-3SQBS3Y5-Cj4eryg1.js +121 -0
- package/dist/prod/packages/shared-chunks/collections-GpG8lT2g.js +75 -0
- package/dist/prod/packages/shared-chunks/compiler-Ddfo5StE.js +6806 -0
- package/dist/prod/packages/shared-chunks/computed_cache-DmYKevAP.js +12 -0
- package/dist/prod/packages/shared-chunks/constants-b-2IVErl.js +210 -0
- package/dist/prod/packages/shared-chunks/debug-brand-B1TWjOCH.js +12 -0
- package/dist/prod/packages/shared-chunks/decorator-BdDDBUd2.js +123 -0
- package/dist/prod/packages/shared-chunks/dictionary-gc5gpyOG.js +13 -0
- package/dist/prod/packages/shared-chunks/element-builder-CiLTrXD6.js +776 -0
- package/dist/prod/packages/shared-chunks/flags-B9qxc-pB.js +24 -0
- package/dist/prod/packages/shared-chunks/fragment-EpVz5Xuc.js +910 -0
- package/dist/prod/packages/shared-chunks/get-debug-name-BDxIL2Y1.js +3 -0
- package/dist/prod/packages/shared-chunks/has-dom-DdQORPzI.js +4 -0
- package/dist/prod/packages/shared-chunks/index-CSVCFS_p.js +1904 -0
- package/dist/prod/packages/shared-chunks/index-Cc8WmrB-.js +21 -0
- package/dist/prod/packages/shared-chunks/index-DZLHQAlb.js +5842 -0
- package/dist/prod/packages/shared-chunks/injected_property-DL3vQoFA.js +58 -0
- package/dist/prod/packages/shared-chunks/invoke-DxL00a1D.js +53 -0
- package/dist/prod/packages/shared-chunks/is_proxy-Cr1qlMv_.js +16 -0
- package/dist/prod/packages/shared-chunks/lookup-descriptor-CwcVgaLv.js +13 -0
- package/dist/prod/packages/shared-chunks/name-C68GLLO3.js +11 -0
- package/dist/prod/packages/shared-chunks/namespace_search-Aog9nySA.js +1070 -0
- package/dist/prod/packages/shared-chunks/object-utils-AijlD-JH.js +12 -0
- package/dist/prod/packages/shared-chunks/observers-R1ZklwWy.js +714 -0
- package/dist/prod/packages/shared-chunks/on-CrTl7JQU.js +3329 -0
- package/dist/prod/packages/shared-chunks/program-B7SJZ5NF.js +176 -0
- package/dist/prod/packages/shared-chunks/program-context-C-JdYXRA.js +146 -0
- package/dist/prod/packages/shared-chunks/property_set-O080KTKZ.js +99 -0
- package/dist/prod/packages/shared-chunks/public-api-C3KlJmEr.js +10 -0
- package/dist/prod/packages/shared-chunks/reference-BNqcwZWH.js +151 -0
- package/dist/prod/packages/shared-chunks/registers-ylirb0dq.js +35 -0
- package/dist/prod/packages/shared-chunks/rehydrate-builder-CSn1aIO1.js +459 -0
- package/dist/prod/packages/shared-chunks/render-C1ZnScKH.js +1464 -0
- package/dist/prod/packages/shared-chunks/rsvp-CnCSY930.js +2306 -0
- package/dist/prod/packages/shared-chunks/serialize-builder-CVQ3q8rJ.js +124 -0
- package/dist/prod/packages/shared-chunks/set_properties-CjsDTRey.js +101 -0
- package/dist/prod/packages/shared-chunks/setup-registry-CMNYh2jY.js +53 -0
- package/dist/prod/packages/shared-chunks/simple-cast-DCvJLSin.js +33 -0
- package/dist/prod/packages/shared-chunks/super-Cm_a_cLQ.js +275 -0
- package/dist/prod/packages/shared-chunks/template-Dc_cBOoX.js +19 -0
- package/dist/prod/packages/shared-chunks/tracked-ChVNBE2f.js +131 -0
- package/dist/prod/packages/shared-chunks/transform-resolutions-C7wq_Q_c.js +6939 -0
- package/dist/prod/packages/shared-chunks/unrecognized-url-error-DDBwfzdm.js +537 -0
- package/docs/data.json +3009 -2358
- package/lib/index.js +157 -279
- package/package.json +27 -58
- package/types/stable/@ember/-internals/deprecations/index.d.ts +0 -6
- package/types/stable/@ember/-internals/environment/index.d.ts +0 -1
- package/types/stable/@ember/-internals/environment/lib/env.d.ts +0 -3
- package/types/stable/@ember/-internals/glimmer/lib/component-managers/curly.d.ts +3 -6
- package/types/stable/@ember/-internals/glimmer/lib/component-managers/root.d.ts +1 -2
- package/types/stable/@ember/-internals/glimmer/lib/helper.d.ts +22 -29
- package/types/stable/@ember/-internals/glimmer/lib/renderer.d.ts +2 -2
- package/types/stable/@ember/-internals/glimmer/lib/resolver.d.ts +0 -2
- package/types/stable/@ember/-internals/glimmer/lib/utils/bindings.d.ts +0 -1
- package/types/stable/@ember/-internals/meta/lib/meta.d.ts +1 -1
- package/types/stable/@ember/-internals/metal/lib/alias.d.ts +0 -11
- package/types/stable/@ember/-internals/metal/lib/decorator.d.ts +0 -1
- package/types/stable/@ember/-internals/metal/lib/each_proxy_events.d.ts +0 -1
- package/types/stable/@ember/-internals/metal/lib/observer.d.ts +0 -2
- package/types/stable/@ember/-internals/metal/lib/property_get.d.ts +4 -10
- package/types/stable/@ember/-internals/utils/index.d.ts +0 -1
- package/types/stable/@ember/-internals/views/lib/system/utils.d.ts +3 -15
- package/types/stable/@ember/application/index.d.ts +2 -63
- package/types/stable/@ember/routing/history-location.d.ts +0 -1
- package/types/stable/@ember/routing/lib/location-utils.d.ts +1 -2
- package/types/stable/@ember/routing/none-location.d.ts +1 -2
- package/types/stable/@ember/template-compiler/index.d.ts +1 -0
- package/types/stable/@ember/template-compiler/lib/plugins/allowed-globals.d.ts +26 -0
- package/types/stable/@ember/test/index.d.ts +0 -3
- package/types/stable/@glimmer/interfaces/lib/compile/wire-format/api.d.ts +1 -1
- package/types/stable/@glimmer/interfaces/lib/template.d.ts +1 -1
- package/types/stable/@glimmer/program/lib/program.d.ts +0 -1
- package/types/stable/@glimmer/validator/lib/collections/map.d.ts +1 -1
- package/types/stable/@handlebars/parser/types/ast.d.ts +148 -0
- package/types/stable/@handlebars/parser/types/index.d.ts +13 -0
- package/types/stable/ember-template-compiler/index.d.ts +0 -2
- package/types/stable/ember-template-compiler/lib/public-api.d.ts +0 -1
- package/types/stable/ember-testing/lib/public-api.d.ts +0 -6
- package/types/stable/ember-testing/lib/test/pending_requests.d.ts +0 -3
- package/types/stable/ember-testing/lib/test.d.ts +0 -23
- package/types/stable/index.d.ts +15 -32
- package/types/stable/router_js/index.d.ts +7 -0
- package/types/stable/router_js/lib/core.d.ts +9 -0
- package/types/stable/router_js/lib/route-info.d.ts +107 -0
- package/types/stable/router_js/lib/router.d.ts +245 -0
- package/types/stable/router_js/lib/transition-aborted-error.d.ts +15 -0
- package/types/stable/router_js/lib/transition-intent/named-transition-intent.d.ts +23 -0
- package/types/stable/router_js/lib/transition-intent/url-transition-intent.d.ts +12 -0
- package/types/stable/router_js/lib/transition-intent.d.ts +13 -0
- package/types/stable/router_js/lib/transition-state.d.ts +25 -0
- package/types/stable/router_js/lib/transition.d.ts +241 -0
- package/types/stable/router_js/lib/unrecognized-url-error.d.ts +11 -0
- package/types/stable/router_js/lib/utils.d.ts +41 -0
- package/dist/ember-template-compiler.js +0 -20631
- package/dist/ember-template-compiler.js.map +0 -1
- package/dist/ember-testing.js +0 -1351
- package/dist/ember-testing.js.map +0 -1
- package/dist/ember.debug.js +0 -52306
- package/dist/ember.debug.js.map +0 -1
- package/dist/ember.prod.js +0 -49369
- package/dist/ember.prod.js.map +0 -1
- package/dist/packages/@ember/-internals/container/index.js +0 -1
- package/dist/packages/@ember/-internals/environment/index.js +0 -1
- package/dist/packages/@ember/-internals/glimmer/index.js +0 -18
- package/dist/packages/@ember/-internals/metal/index.js +0 -51
- package/dist/packages/@ember/-internals/utils/index.js +0 -7
- package/dist/packages/@ember/application/lib/lazy_load.js +0 -68
- package/dist/packages/@ember/component/helper.js +0 -14
- package/dist/packages/@ember/modifier/index.js +0 -23
- package/dist/packages/@ember/object/-internals.js +0 -35
- package/dist/packages/@ember/object/events.js +0 -12
- package/dist/packages/@ember/object/observers.js +0 -12
- package/dist/packages/@ember/renderer/index.js +0 -14
- package/dist/packages/@ember/routing/index.js +0 -14
- package/dist/packages/@ember/template/index.js +0 -14
- package/dist/packages/@ember/template-factory/index.js +0 -8
- package/dist/packages/@ember/test/index.js +0 -27
- package/dist/packages/@glimmer/encoder/index.js +0 -1
- package/dist/packages/@glimmer/manager/index.js +0 -5
- package/dist/packages/@glimmer/node/index.js +0 -2
- package/dist/packages/@glimmer/program/index.js +0 -3
- package/dist/packages/@glimmer/reference/index.js +0 -2
- package/dist/packages/@glimmer/tracking/index.js +0 -48
- package/dist/packages/@glimmer/tracking/primitives/cache/index.js +0 -12
- package/dist/packages/ember/barrel.js +0 -511
- package/dist/packages/ember/index.js +0 -20
- package/dist/packages/ember-template-compiler/index.js +0 -17135
- package/dist/packages/ember-testing/lib/adapters/qunit.js +0 -53
- package/dist/packages/ember-testing/lib/ext/application.js +0 -174
- package/dist/packages/ember-testing/lib/ext/rsvp.js +0 -17
- package/dist/packages/ember-testing/lib/helpers/and_then.js +0 -11
- package/dist/packages/ember-testing/lib/helpers/current_path.js +0 -32
- package/dist/packages/ember-testing/lib/helpers/current_route_name.js +0 -32
- package/dist/packages/ember-testing/lib/helpers/current_url.js +0 -29
- package/dist/packages/ember-testing/lib/helpers/pause_test.js +0 -76
- package/dist/packages/ember-testing/lib/helpers/visit.js +0 -51
- package/dist/packages/ember-testing/lib/helpers/wait.js +0 -55
- package/dist/packages/ember-testing/lib/helpers.js +0 -17
- package/dist/packages/ember-testing/lib/initializers.js +0 -56
- package/dist/packages/ember-testing/lib/public-api.js +0 -8
- package/dist/packages/ember-testing/lib/setup_for_testing.js +0 -31
- package/dist/packages/ember-testing/lib/test/helpers.js +0 -133
- package/dist/packages/ember-testing/lib/test/on_inject_helpers.js +0 -39
- package/dist/packages/ember-testing/lib/test/pending_requests.js +0 -22
- package/dist/packages/ember-testing/lib/test/promise.js +0 -83
- package/dist/packages/ember-testing/lib/test/run.js +0 -11
- package/dist/packages/ember-testing/lib/test.js +0 -68
- package/dist/packages/router_js/index.js +0 -2
- package/dist/packages/shared-chunks/helpers-C1rIkuSd.js +0 -11
- package/dist/packages/shared-chunks/invoke-BjRgvK2V.js +0 -27
- package/dist/packages/shared-chunks/public-api-BQsJemZG.js +0 -20
- package/dist/packages/shared-chunks/template_registry-DigcUg9m.js +0 -24
- package/dist/packages/shared-chunks/to-string-CqD7_vQ4.js +0 -60
- package/types/stable/@ember/-internals/environment/lib/global.d.ts +0 -4
- package/types/stable/@ember/-internals/glimmer/lib/modifiers/internal.d.ts +0 -34
- package/types/stable/@ember/-internals/glimmer/lib/syntax/utils.d.ts +0 -5
- package/types/stable/@ember/-internals/glimmer/lib/templates/empty.d.ts +0 -4
- package/types/stable/@ember/-internals/glimmer/lib/utils/debug-render-message.d.ts +0 -4
- package/types/stable/@ember/-internals/metal/lib/dependent_keys.d.ts +0 -3
- package/types/stable/@ember/-internals/utils/lib/symbol.d.ts +0 -5
- package/types/stable/@ember/application/lib/lazy_load.d.ts +0 -38
- package/types/stable/@ember/template-compiler/lib/public-types.d.ts +0 -3
- package/types/stable/ember/barrel.d.ts +0 -358
- package/types/stable/ember/index.d.ts +0 -358
- package/types/stable/ember-template-compiler/lib/system/bootstrap.d.ts +0 -26
- package/types/stable/ember-template-compiler/lib/system/initializer.d.ts +0 -3
- package/types/stable/ember-testing/lib/adapters/qunit.d.ts +0 -22
- package/types/stable/ember-testing/lib/ext/application.d.ts +0 -12
- package/types/stable/ember-testing/lib/ext/rsvp.d.ts +0 -4
- package/types/stable/ember-testing/lib/helpers/and_then.d.ts +0 -4
- package/types/stable/ember-testing/lib/helpers/current_path.d.ts +0 -22
- package/types/stable/ember-testing/lib/helpers/current_route_name.d.ts +0 -21
- package/types/stable/ember-testing/lib/helpers/current_url.d.ts +0 -22
- package/types/stable/ember-testing/lib/helpers/pause_test.d.ts +0 -52
- package/types/stable/ember-testing/lib/helpers/visit.d.ts +0 -22
- package/types/stable/ember-testing/lib/helpers/wait.d.ts +0 -34
- package/types/stable/ember-testing/lib/helpers.d.ts +0 -3
- package/types/stable/ember-testing/lib/initializers.d.ts +0 -3
- package/types/stable/ember-testing/lib/setup_for_testing.d.ts +0 -15
- package/types/stable/ember-testing/lib/test/helpers.d.ts +0 -116
- package/types/stable/ember-testing/lib/test/on_inject_helpers.d.ts +0 -33
- package/types/stable/ember-testing/lib/test/promise.d.ts +0 -37
- package/types/stable/ember-testing/lib/test/run.d.ts +0 -3
- package/types/stable/loader/lib/index.d.ts +0 -4
- package/types/stable/require.d.ts +0 -4
- /package/dist/{packages → dev/packages}/@ember/-internals/browser-environment/index.js +0 -0
- /package/dist/{packages → dev/packages}/@ember/-internals/error-handling/index.js +0 -0
- /package/dist/{packages → dev/packages}/@ember/-internals/meta/index.js +0 -0
- /package/dist/{packages → dev/packages}/@ember/-internals/owner/index.js +0 -0
- /package/dist/{packages → dev/packages}/@ember/-internals/runtime/index.js +0 -0
- /package/dist/{packages → dev/packages}/@ember/-internals/runtime/lib/mixins/comparable.js +0 -0
- /package/dist/{packages → dev/packages}/@ember/-internals/runtime/lib/mixins/container_proxy.js +0 -0
- /package/dist/{packages → dev/packages}/@ember/-internals/utility-types/index.js +0 -0
- /package/dist/{packages → dev/packages}/@ember/-internals/views/index.js +0 -0
- /package/dist/{packages → dev/packages}/@ember/-internals/views/lib/compat/attrs.js +0 -0
- /package/dist/{packages → dev/packages}/@ember/-internals/views/lib/component_lookup.js +0 -0
- /package/dist/{packages → dev/packages}/@ember/array/-internals.js +0 -0
- /package/dist/{packages → dev/packages}/@ember/array/lib/make-array.js +0 -0
- /package/dist/{packages → dev/packages}/@ember/array/make.js +0 -0
- /package/dist/{packages → dev/packages}/@ember/array/mutable.js +0 -0
- /package/dist/{packages → dev/packages}/@ember/debug/lib/capture-render-tree.js +0 -0
- /package/dist/{packages → dev/packages}/@ember/debug/lib/inspect.js +0 -0
- /package/dist/{packages → dev/packages}/@ember/debug/lib/testing.js +0 -0
- /package/dist/{packages → dev/packages}/@ember/deprecated-features/index.js +0 -0
- /package/dist/{packages → dev/packages}/@ember/destroyable/index.js +0 -0
- /package/dist/{packages → dev/packages}/@ember/engine/lib/engine-parent.js +0 -0
- /package/dist/{packages → dev/packages}/@ember/engine/parent.js +0 -0
- /package/dist/{packages → dev/packages}/@ember/enumerable/index.js +0 -0
- /package/dist/{packages → dev/packages}/@ember/enumerable/mutable.js +0 -0
- /package/dist/{packages → dev/packages}/@ember/object/proxy.js +0 -0
- /package/dist/{packages → dev/packages}/@ember/owner/index.js +0 -0
- /package/dist/{packages → dev/packages}/@ember/reactive/collections.js +0 -0
- /package/dist/{packages → dev/packages}/@ember/reactive/index.js +0 -0
- /package/dist/{packages → dev/packages}/@ember/routing/lib/cache.js +0 -0
- /package/dist/{packages → dev/packages}/@ember/routing/lib/controller_for.js +0 -0
- /package/dist/{packages → dev/packages}/@ember/routing/lib/query_params.js +0 -0
- /package/dist/{packages → dev/packages}/@ember/routing/lib/router_state.js +0 -0
- /package/dist/{packages → dev/packages}/@ember/template-compiler/-internal-primitives.js +0 -0
- /package/dist/{packages → dev/packages}/@ember/template-compiler/-internal-utils.js +0 -0
- /package/dist/{packages → dev/packages}/@ember/template-compiler/lib/-internal/primitives.js +0 -0
- /package/dist/{packages → dev/packages}/@ember/template-compiler/lib/plugins/transform-action-syntax.js +0 -0
- /package/dist/{packages → dev/packages}/@ember/template-compiler/lib/plugins/transform-each-in-into-each.js +0 -0
- /package/dist/{packages → dev/packages}/@ember/template-compiler/lib/plugins/transform-quoted-bindings-into-just-bindings.js +0 -0
- /package/dist/{packages → dev/packages}/@ember/template-compiler/lib/plugins/transform-wrap-mount-and-outlet.js +0 -0
- /package/dist/{packages → dev/packages}/@ember/template-compiler/lib/plugins/utils.js +0 -0
- /package/dist/{packages → dev/packages}/@ember/template-compiler/lib/public-api.js +0 -0
- /package/dist/{packages → dev/packages}/@ember/template-compiler/lib/runtime.js +0 -0
- /package/dist/{packages → dev/packages}/@ember/template-compiler/lib/system/calculate-location-display.js +0 -0
- /package/dist/{packages → dev/packages}/@ember/template-compiler/runtime.js +0 -0
- /package/dist/{packages → dev/packages}/@ember/test/adapter.js +0 -0
- /package/dist/{packages → dev/packages}/@ember/utils/index.js +0 -0
- /package/dist/{packages → dev/packages}/@ember/utils/lib/is-equal.js +0 -0
- /package/dist/{packages → dev/packages}/@ember/utils/lib/is_blank.js +0 -0
- /package/dist/{packages → dev/packages}/@ember/utils/lib/is_none.js +0 -0
- /package/dist/{packages → dev/packages}/@ember/utils/lib/is_present.js +0 -0
- /package/dist/{packages → dev/packages}/@ember/utils/lib/type-of.js +0 -0
- /package/dist/{packages → dev/packages}/@ember/version/index.js +0 -0
- /package/dist/{packages → dev/packages}/@glimmer/env/index.js +0 -0
- /package/dist/{packages → dev/packages}/@glimmer/owner/index.js +0 -0
- /package/dist/{packages → dev/packages}/@glimmer/wire-format/index.js +0 -0
- /package/dist/{packages → dev/packages}/@simple-dom/document/index.js +0 -0
- /package/dist/{packages → dev/packages}/backburner.js/index.js +0 -0
- /package/dist/{packages → dev/packages}/dag-map/index.js +0 -0
- /package/dist/{packages → dev/packages}/ember-testing/lib/adapters/adapter.js +0 -0
- /package/dist/{packages → dev/packages}/ember-testing/lib/test/adapter.js +0 -0
- /package/dist/{packages → dev/packages}/ember-testing/lib/test/waiters.js +0 -0
- /package/dist/{packages → dev/packages}/route-recognizer/index.js +0 -0
- /package/dist/{packages → dev/packages}/rsvp/index.js +0 -0
- /package/dist/{packages → dev/packages}/shared-chunks/array-utils-CZQxrdD3.js +0 -0
- /package/dist/{packages → dev/packages}/shared-chunks/assert-CUCJBR2C.js +0 -0
- /package/dist/{packages → dev/packages}/shared-chunks/cache-qDyqAcpg.js +0 -0
- /package/dist/{packages → dev/packages}/shared-chunks/chunk-3SQBS3Y5-Cj4eryg1.js +0 -0
- /package/dist/{packages → dev/packages}/shared-chunks/computed_cache-DmYKevAP.js +0 -0
- /package/dist/{packages → dev/packages}/shared-chunks/debug-brand-B1TWjOCH.js +0 -0
- /package/dist/{packages → dev/packages}/shared-chunks/dictionary-gc5gpyOG.js +0 -0
- /package/dist/{packages → dev/packages}/shared-chunks/index-BGP1rw3B.js +0 -0
- /package/dist/{packages → dev/packages}/shared-chunks/object-utils-AijlD-JH.js +0 -0
- /package/dist/{packages → dev/packages}/shared-chunks/present-B1rrjAVM.js +0 -0
- /package/dist/{packages → dev/packages}/shared-chunks/registers-ylirb0dq.js +0 -0
- /package/dist/{packages → dev/packages}/shared-chunks/rsvp-CnCSY930.js +0 -0
- /package/dist/{packages → prod/packages}/@ember/routing/-internals.js +0 -0
- /package/dist/{packages/@ember/template-compiler/index.js → prod/packages/@ember/template-compiler/runtime.js} +0 -0
|
@@ -0,0 +1,3329 @@
|
|
|
1
|
+
import { r as VM_SYSCALL_SIZE, C as CURRIED_COMPONENT, s as VM_CHILD_SCOPE_OP, t as VM_POP_SCOPE_OP, u as VM_PUSH_DYNAMIC_SCOPE_OP, v as VM_POP_DYNAMIC_SCOPE_OP, w as VM_CONSTANT_OP, x as decodeHandle, y as VM_CONSTANT_REFERENCE_OP, z as VM_PRIMITIVE_OP, A as isHandle, B as decodeImmediate, D as VM_PRIMITIVE_REFERENCE_OP, E as VM_DUP_OP, F as VM_POP_OP, G as VM_LOAD_OP, H as VM_FETCH_OP, I as VM_BIND_DYNAMIC_SCOPE_OP, J as VM_ENTER_OP, K as VM_EXIT_OP, L as VM_PUSH_SYMBOL_TABLE_OP, M as VM_PUSH_BLOCK_SCOPE_OP, N as VM_COMPILE_BLOCK_OP, O as VM_INVOKE_YIELD_OP, P as VM_JUMP_IF_OP, Q as VM_JUMP_UNLESS_OP, R as VM_JUMP_EQ_OP, b as VM_ASSERT_SAME_OP, S as VM_TO_BOOLEAN_OP, T as VM_TEXT_OP, U as VM_COMMENT_OP, W as VM_OPEN_ELEMENT_OP, X as VM_OPEN_DYNAMIC_ELEMENT_OP, Y as VM_PUSH_REMOTE_ELEMENT_OP, Z as VM_POP_REMOTE_ELEMENT_OP, _ as VM_FLUSH_ELEMENT_OP, $ as VM_CLOSE_ELEMENT_OP, a0 as VM_MODIFIER_OP, a1 as VM_DYNAMIC_MODIFIER_OP, a2 as VM_STATIC_ATTR_OP, a3 as VM_DYNAMIC_ATTR_OP, a4 as CURRIED_MODIFIER, a5 as VM_PUSH_COMPONENT_DEFINITION_OP, a6 as VM_RESOLVE_DYNAMIC_COMPONENT_OP, f as VM_RESOLVE_CURRIED_COMPONENT_OP, g as VM_PUSH_DYNAMIC_COMPONENT_INSTANCE_OP, a7 as VM_PUSH_ARGS_OP, a8 as VM_PUSH_EMPTY_ARGS_OP, a9 as VM_CAPTURE_ARGS_OP, aa as VM_PREPARE_ARGS_OP, ab as VM_CREATE_COMPONENT_OP, ac as VM_REGISTER_COMPONENT_DESTRUCTOR_OP, ad as VM_BEGIN_COMPONENT_TRANSACTION_OP, ae as VM_PUT_COMPONENT_OPERATIONS_OP, af as VM_COMPONENT_ATTR_OP, ag as VM_STATIC_COMPONENT_ATTR_OP, ah as VM_DID_CREATE_ELEMENT_OP, ai as VM_GET_COMPONENT_SELF_OP, aj as VM_GET_COMPONENT_TAG_NAME_OP, ak as VM_GET_COMPONENT_LAYOUT_OP, V as VM_MAIN_OP, al as VM_POPULATE_LAYOUT_OP, am as VM_VIRTUAL_ROOT_SCOPE_OP, an as VM_SET_NAMED_VARIABLES_OP, ao as VM_SET_BLOCKS_OP, ap as VM_INVOKE_COMPONENT_LAYOUT_OP, aq as VM_DID_RENDER_LAYOUT_OP, ar as VM_COMMIT_COMPONENT_TRANSACTION_OP, as as VM_CURRY_OP, at as VM_DYNAMIC_HELPER_OP, au as CURRIED_HELPER, av as VM_HELPER_OP, aw as VM_GET_VARIABLE_OP, ax as VM_SET_VARIABLE_OP, ay as VM_SET_BLOCK_OP, az as VM_ROOT_SCOPE_OP, aA as VM_GET_PROPERTY_OP, aB as VM_GET_BLOCK_OP, aC as VM_SPREAD_BLOCK_OP, aD as VM_HAS_BLOCK_OP, aE as VM_HAS_BLOCK_PARAMS_OP, aF as VM_CONCAT_OP, aG as VM_IF_INLINE_OP, aH as VM_NOT_OP, aI as VM_GET_DYNAMIC_VAR_OP, aJ as VM_LOG_OP, a as VM_CONTENT_TYPE_OP, aK as VM_DYNAMIC_CONTENT_TYPE_OP, d as VM_APPEND_HTML_OP, h as VM_APPEND_SAFE_HTML_OP, e as VM_APPEND_TEXT_OP, i as VM_APPEND_DOCUMENT_FRAGMENT_OP, j as VM_APPEND_NODE_OP, aL as VM_DEBUGGER_OP, aM as VM_ENTER_LIST_OP, aN as VM_EXIT_LIST_OP, aO as VM_ITERATE_OP } from './fragment-EpVz5Xuc.js';
|
|
2
|
+
import { u as unwrap, c as isIndexable$1, e as expect, S as StackImpl, d as dict, i as isDict } from './collections-GpG8lT2g.js';
|
|
3
|
+
import { a as assign } from './object-utils-AijlD-JH.js';
|
|
4
|
+
import { toBool, setPath, getPath } from '../@glimmer/global-context/index.js';
|
|
5
|
+
import { CONSTANT_TAG, INITIAL, validateTag, consumeTag, valueForTag, beginTrackFrame, endTrackFrame, CURRENT_TAG, createUpdatableTag } from '../@glimmer/validator/index.js';
|
|
6
|
+
import { c as createComputeRef, v as valueForRef, a as createConstRef, d as createPrimitiveRef, i as isConstRef, U as UNDEFINED_REFERENCE, N as NULL_REFERENCE, T as TRUE_REFERENCE, F as FALSE_REFERENCE, R as REFERENCE, b as childRefFor, e as isInvokableRef, u as updateRef } from './reference-BNqcwZWH.js';
|
|
7
|
+
import { e as $v0, f as $t1, g as $t0, a as $pc, b as $ra, c as $fp, d as $sp, h as $s1, $ as $s0 } from './registers-ylirb0dq.js';
|
|
8
|
+
import { registerDestructor, destroy, associateDestroyableChild, _hasDestroyableChildren } from '../@glimmer/destroyable/index.js';
|
|
9
|
+
import { d as getInternalModifierManager, g as getInternalHelperManager, b as hasInternalComponentManager, f as hasInternalHelperManager, s as setInternalComponentManager, i as setInternalHelperManager, j as setInternalModifierManager } from './api-Co-k4HVs.js';
|
|
10
|
+
import { m as managerHasCapability } from './capabilities-DGmQ_mz4.js';
|
|
11
|
+
import { ContentType } from '../@glimmer/vm/index.js';
|
|
12
|
+
import { createIteratorRef } from '../@glimmer/reference/index.js';
|
|
13
|
+
import { s as setLocalDebugType } from './debug-brand-B1TWjOCH.js';
|
|
14
|
+
import { b as EMPTY_STRING_ARRAY, e as enumerate, c as emptyArray } from './array-utils-CZQxrdD3.js';
|
|
15
|
+
import { a as assert } from './assert-CUCJBR2C.js';
|
|
16
|
+
import { a as unwrapTemplate } from './constants-b-2IVErl.js';
|
|
17
|
+
import { I as InternalComponentCapabilities } from './flags-B9qxc-pB.js';
|
|
18
|
+
|
|
19
|
+
/* eslint-disable @typescript-eslint/no-empty-object-type */
|
|
20
|
+
function buildUntouchableThis(source) {
|
|
21
|
+
let context = null;
|
|
22
|
+
return context;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const ELEMENT_NODE = 1;
|
|
26
|
+
const TEXT_NODE = 3;
|
|
27
|
+
const COMMENT_NODE = 8;
|
|
28
|
+
const NS_MATHML = 'http://www.w3.org/1998/Math/MathML';
|
|
29
|
+
const NS_SVG = 'http://www.w3.org/2000/svg';
|
|
30
|
+
const INSERT_BEFORE_BEGIN = 'beforebegin';
|
|
31
|
+
const INSERT_BEFORE_END = 'beforeend';
|
|
32
|
+
|
|
33
|
+
function CheckInstanceof(Class) {
|
|
34
|
+
}
|
|
35
|
+
const CheckRegister = new class {
|
|
36
|
+
validate(value) {
|
|
37
|
+
switch (value) {
|
|
38
|
+
case $s0:
|
|
39
|
+
case $s1:
|
|
40
|
+
case $sp:
|
|
41
|
+
case $fp:
|
|
42
|
+
case $ra:
|
|
43
|
+
case $pc:
|
|
44
|
+
case $t0:
|
|
45
|
+
case $t1:
|
|
46
|
+
case $v0:
|
|
47
|
+
return true;
|
|
48
|
+
default:
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
expected() {
|
|
53
|
+
return `Register`;
|
|
54
|
+
}
|
|
55
|
+
}();
|
|
56
|
+
|
|
57
|
+
/*@__NO_SIDE_EFFECTS__*/
|
|
58
|
+
|
|
59
|
+
function check(value, checker, message) {
|
|
60
|
+
{
|
|
61
|
+
return value;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
class AppendOpcodes {
|
|
66
|
+
// This code is intentionally putting unsafe `null`s into the array that it
|
|
67
|
+
// will intentionally overwrite before anyone can see them.
|
|
68
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
69
|
+
evaluateOpcode = new Array(VM_SYSCALL_SIZE).fill(null);
|
|
70
|
+
constructor() {
|
|
71
|
+
}
|
|
72
|
+
add(name, evaluate, kind = 'syscall') {
|
|
73
|
+
this.evaluateOpcode[name] = {
|
|
74
|
+
syscall: kind !== 'machine',
|
|
75
|
+
evaluate
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
evaluate(vm, opcode, type) {
|
|
79
|
+
let operation = unwrap(this.evaluateOpcode[type]);
|
|
80
|
+
if (operation.syscall) {
|
|
81
|
+
assert(!opcode.isMachine, `BUG: Mismatch between operation.syscall (${operation.syscall}) and opcode.isMachine (${opcode.isMachine}) for ${opcode.type}`);
|
|
82
|
+
operation.evaluate(vm, opcode);
|
|
83
|
+
} else {
|
|
84
|
+
assert(opcode.isMachine, `BUG: Mismatch between operation.syscall (${operation.syscall}) and opcode.isMachine (${opcode.isMachine}) for ${opcode.type}`);
|
|
85
|
+
operation.evaluate(vm.lowlevel, opcode);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
function externs(vm) {
|
|
90
|
+
return undefined;
|
|
91
|
+
}
|
|
92
|
+
const APPEND_OPCODES = new AppendOpcodes();
|
|
93
|
+
|
|
94
|
+
const TYPE = Symbol('TYPE');
|
|
95
|
+
const INNER = Symbol('INNER');
|
|
96
|
+
const OWNER = Symbol('OWNER');
|
|
97
|
+
const ARGS = Symbol('ARGS');
|
|
98
|
+
const RESOLVED = Symbol('RESOLVED');
|
|
99
|
+
const CURRIED_VALUES = new WeakSet();
|
|
100
|
+
function isCurriedValue(value) {
|
|
101
|
+
return CURRIED_VALUES.has(value);
|
|
102
|
+
}
|
|
103
|
+
function isCurriedType(value, type) {
|
|
104
|
+
return isCurriedValue(value) && value[TYPE] === type;
|
|
105
|
+
}
|
|
106
|
+
class CurriedValue {
|
|
107
|
+
[TYPE];
|
|
108
|
+
[INNER];
|
|
109
|
+
[OWNER];
|
|
110
|
+
[ARGS];
|
|
111
|
+
[RESOLVED];
|
|
112
|
+
|
|
113
|
+
/** @internal */
|
|
114
|
+
constructor(type, inner, owner, args, resolved = false) {
|
|
115
|
+
CURRIED_VALUES.add(this);
|
|
116
|
+
this[TYPE] = type;
|
|
117
|
+
this[INNER] = inner;
|
|
118
|
+
this[OWNER] = owner;
|
|
119
|
+
this[ARGS] = args;
|
|
120
|
+
this[RESOLVED] = resolved;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
function resolveCurriedValue(curriedValue) {
|
|
124
|
+
let currentWrapper = curriedValue;
|
|
125
|
+
let positional;
|
|
126
|
+
let named;
|
|
127
|
+
let definition, owner, resolved;
|
|
128
|
+
while (true) {
|
|
129
|
+
let {
|
|
130
|
+
[ARGS]: curriedArgs,
|
|
131
|
+
[INNER]: inner
|
|
132
|
+
} = currentWrapper;
|
|
133
|
+
if (curriedArgs !== null) {
|
|
134
|
+
let {
|
|
135
|
+
named: curriedNamed,
|
|
136
|
+
positional: curriedPositional
|
|
137
|
+
} = curriedArgs;
|
|
138
|
+
if (curriedPositional.length > 0) {
|
|
139
|
+
positional = positional === undefined ? curriedPositional : curriedPositional.concat(positional);
|
|
140
|
+
}
|
|
141
|
+
if (named === undefined) {
|
|
142
|
+
named = [];
|
|
143
|
+
}
|
|
144
|
+
named.unshift(curriedNamed);
|
|
145
|
+
}
|
|
146
|
+
if (!isCurriedValue(inner)) {
|
|
147
|
+
// Save off the owner that this helper was curried with. Later on,
|
|
148
|
+
// we'll fetch the value of this register and set it as the owner on the
|
|
149
|
+
// new root scope.
|
|
150
|
+
definition = inner;
|
|
151
|
+
owner = currentWrapper[OWNER];
|
|
152
|
+
resolved = currentWrapper[RESOLVED];
|
|
153
|
+
break;
|
|
154
|
+
}
|
|
155
|
+
currentWrapper = inner;
|
|
156
|
+
}
|
|
157
|
+
return {
|
|
158
|
+
definition,
|
|
159
|
+
owner,
|
|
160
|
+
resolved,
|
|
161
|
+
positional,
|
|
162
|
+
named
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
function curry(type, spec, owner, args, resolved = false) {
|
|
166
|
+
return new CurriedValue(type, spec, owner, args, resolved);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
function createCurryRef(type, inner, owner, args, resolver, isStrict) {
|
|
170
|
+
let lastValue, curriedDefinition;
|
|
171
|
+
return createComputeRef(() => {
|
|
172
|
+
let value = valueForRef(inner);
|
|
173
|
+
if (value === lastValue) {
|
|
174
|
+
return curriedDefinition;
|
|
175
|
+
}
|
|
176
|
+
if (isCurriedType(value, type)) {
|
|
177
|
+
curriedDefinition = args ? curry(type, value, owner, args) : args;
|
|
178
|
+
} else if (type === CURRIED_COMPONENT && typeof value === 'string' && value) {
|
|
179
|
+
curriedDefinition = curry(type, value, owner, args);
|
|
180
|
+
} else if (isIndexable$1(value)) {
|
|
181
|
+
curriedDefinition = curry(type, value, owner, args);
|
|
182
|
+
} else {
|
|
183
|
+
curriedDefinition = null;
|
|
184
|
+
}
|
|
185
|
+
lastValue = value;
|
|
186
|
+
return curriedDefinition;
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
class CursorImpl {
|
|
191
|
+
constructor(element, nextSibling) {
|
|
192
|
+
this.element = element;
|
|
193
|
+
this.nextSibling = nextSibling;
|
|
194
|
+
setLocalDebugType('cursor', this);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
class ConcreteBounds {
|
|
198
|
+
constructor(parentNode, first, last) {
|
|
199
|
+
this.parentNode = parentNode;
|
|
200
|
+
this.first = first;
|
|
201
|
+
this.last = last;
|
|
202
|
+
}
|
|
203
|
+
parentElement() {
|
|
204
|
+
return this.parentNode;
|
|
205
|
+
}
|
|
206
|
+
firstNode() {
|
|
207
|
+
return this.first;
|
|
208
|
+
}
|
|
209
|
+
lastNode() {
|
|
210
|
+
return this.last;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
function move(bounds, reference) {
|
|
214
|
+
let parent = bounds.parentElement();
|
|
215
|
+
let first = bounds.firstNode();
|
|
216
|
+
let last = bounds.lastNode();
|
|
217
|
+
let current = first;
|
|
218
|
+
while (true) {
|
|
219
|
+
let next = current.nextSibling;
|
|
220
|
+
parent.insertBefore(current, reference);
|
|
221
|
+
if (current === last) {
|
|
222
|
+
return next;
|
|
223
|
+
}
|
|
224
|
+
current = expect(next);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
function clear(bounds) {
|
|
228
|
+
let parent = bounds.parentElement();
|
|
229
|
+
let first = bounds.firstNode();
|
|
230
|
+
let last = bounds.lastNode();
|
|
231
|
+
let current = first;
|
|
232
|
+
while (true) {
|
|
233
|
+
let next = current.nextSibling;
|
|
234
|
+
parent.removeChild(current);
|
|
235
|
+
if (current === last) {
|
|
236
|
+
return next;
|
|
237
|
+
}
|
|
238
|
+
current = expect(next);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/** @internal */
|
|
243
|
+
function hasCustomDebugRenderTreeLifecycle(manager) {
|
|
244
|
+
return 'getDebugCustomRenderTree' in manager;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
function resolveComponent(resolver, constants, name, owner) {
|
|
248
|
+
let definition = resolver?.lookupComponent?.(name, expect(owner)) ?? null;
|
|
249
|
+
|
|
250
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- @fixme
|
|
251
|
+
return constants.resolvedComponent(definition, name);
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
let GUID = 0;
|
|
255
|
+
class Ref {
|
|
256
|
+
id = GUID++;
|
|
257
|
+
value;
|
|
258
|
+
constructor(value) {
|
|
259
|
+
this.value = value;
|
|
260
|
+
}
|
|
261
|
+
get() {
|
|
262
|
+
return this.value;
|
|
263
|
+
}
|
|
264
|
+
release() {
|
|
265
|
+
this.value = null;
|
|
266
|
+
}
|
|
267
|
+
toString() {
|
|
268
|
+
let label = `Ref ${this.id}`;
|
|
269
|
+
if (this.value === null) {
|
|
270
|
+
return `${label} (released)`;
|
|
271
|
+
} else {
|
|
272
|
+
try {
|
|
273
|
+
// eslint-disable-next-line @typescript-eslint/no-base-to-string
|
|
274
|
+
return `${label}: ${this.value}`;
|
|
275
|
+
} catch {
|
|
276
|
+
return label;
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
class DebugRenderTreeImpl {
|
|
282
|
+
stack = new StackImpl();
|
|
283
|
+
refs = new WeakMap();
|
|
284
|
+
roots = new Set();
|
|
285
|
+
nodes = new WeakMap();
|
|
286
|
+
begin() {
|
|
287
|
+
this.reset();
|
|
288
|
+
}
|
|
289
|
+
create(state, node) {
|
|
290
|
+
let internalNode = assign({}, node, {
|
|
291
|
+
bounds: null,
|
|
292
|
+
refs: new Set()
|
|
293
|
+
});
|
|
294
|
+
this.nodes.set(state, internalNode);
|
|
295
|
+
this.appendChild(internalNode, state);
|
|
296
|
+
this.enter(state);
|
|
297
|
+
}
|
|
298
|
+
update(state) {
|
|
299
|
+
this.enter(state);
|
|
300
|
+
}
|
|
301
|
+
didRender(state, bounds) {
|
|
302
|
+
this.nodeFor(state).bounds = bounds;
|
|
303
|
+
this.exit();
|
|
304
|
+
}
|
|
305
|
+
willDestroy(state) {
|
|
306
|
+
expect(this.refs.get(state)).release();
|
|
307
|
+
}
|
|
308
|
+
commit() {
|
|
309
|
+
this.reset();
|
|
310
|
+
}
|
|
311
|
+
capture() {
|
|
312
|
+
return this.captureRefs(this.roots);
|
|
313
|
+
}
|
|
314
|
+
reset() {
|
|
315
|
+
if (this.stack.size !== 0) {
|
|
316
|
+
// We probably encountered an error during the rendering loop. This will
|
|
317
|
+
// likely trigger undefined behavior and memory leaks as the error left
|
|
318
|
+
// things in an inconsistent state. It is recommended that the user
|
|
319
|
+
// refresh the page.
|
|
320
|
+
|
|
321
|
+
// TODO: We could warn here? But this happens all the time in our tests?
|
|
322
|
+
|
|
323
|
+
// Clean up the root reference to prevent errors from happening if we
|
|
324
|
+
// attempt to capture the render tree (Ember Inspector may do this)
|
|
325
|
+
let root = expect(this.stack.toArray()[0]);
|
|
326
|
+
let ref = this.refs.get(root);
|
|
327
|
+
if (ref !== undefined) {
|
|
328
|
+
this.roots.delete(ref);
|
|
329
|
+
}
|
|
330
|
+
while (!this.stack.isEmpty()) {
|
|
331
|
+
this.stack.pop();
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
enter(state) {
|
|
336
|
+
this.stack.push(state);
|
|
337
|
+
}
|
|
338
|
+
exit() {
|
|
339
|
+
this.stack.pop();
|
|
340
|
+
}
|
|
341
|
+
nodeFor(state) {
|
|
342
|
+
return expect(this.nodes.get(state));
|
|
343
|
+
}
|
|
344
|
+
appendChild(node, state) {
|
|
345
|
+
let parent = this.stack.current;
|
|
346
|
+
let ref = new Ref(state);
|
|
347
|
+
this.refs.set(state, ref);
|
|
348
|
+
if (parent) {
|
|
349
|
+
let parentNode = this.nodeFor(parent);
|
|
350
|
+
parentNode.refs.add(ref);
|
|
351
|
+
node.parent = parentNode;
|
|
352
|
+
} else {
|
|
353
|
+
this.roots.add(ref);
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
captureRefs(refs) {
|
|
357
|
+
let captured = [];
|
|
358
|
+
refs.forEach(ref => {
|
|
359
|
+
let state = ref.get();
|
|
360
|
+
if (state) {
|
|
361
|
+
captured.push(this.captureNode(`render-node:${ref.id}`, state));
|
|
362
|
+
} else {
|
|
363
|
+
refs.delete(ref);
|
|
364
|
+
}
|
|
365
|
+
});
|
|
366
|
+
return captured;
|
|
367
|
+
}
|
|
368
|
+
captureNode(id, state) {
|
|
369
|
+
let node = this.nodeFor(state);
|
|
370
|
+
let {
|
|
371
|
+
type,
|
|
372
|
+
name,
|
|
373
|
+
args,
|
|
374
|
+
instance,
|
|
375
|
+
refs
|
|
376
|
+
} = node;
|
|
377
|
+
let template = this.captureTemplate(node);
|
|
378
|
+
let bounds = this.captureBounds(node);
|
|
379
|
+
let children = this.captureRefs(refs);
|
|
380
|
+
return {
|
|
381
|
+
id,
|
|
382
|
+
type,
|
|
383
|
+
name,
|
|
384
|
+
args: reifyArgsDebug(args),
|
|
385
|
+
instance,
|
|
386
|
+
template,
|
|
387
|
+
bounds,
|
|
388
|
+
children
|
|
389
|
+
};
|
|
390
|
+
}
|
|
391
|
+
captureTemplate({
|
|
392
|
+
template
|
|
393
|
+
}) {
|
|
394
|
+
return template || null;
|
|
395
|
+
}
|
|
396
|
+
captureBounds(node) {
|
|
397
|
+
let bounds = expect(node.bounds);
|
|
398
|
+
let parentElement = bounds.parentElement();
|
|
399
|
+
let firstNode = bounds.firstNode();
|
|
400
|
+
let lastNode = bounds.lastNode();
|
|
401
|
+
return {
|
|
402
|
+
parentElement,
|
|
403
|
+
firstNode,
|
|
404
|
+
lastNode
|
|
405
|
+
};
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
function getDebugName(definition, manager = definition.manager) {
|
|
409
|
+
return definition.resolvedName ?? definition.debugName ?? manager.getDebugName(definition.state);
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
function normalizeStringValue(value) {
|
|
413
|
+
if (isEmpty$1(value)) {
|
|
414
|
+
return '';
|
|
415
|
+
}
|
|
416
|
+
return String(value);
|
|
417
|
+
}
|
|
418
|
+
function shouldCoerce(value) {
|
|
419
|
+
return isString(value) || isEmpty$1(value) || typeof value === 'boolean' || typeof value === 'number';
|
|
420
|
+
}
|
|
421
|
+
function isEmpty$1(value) {
|
|
422
|
+
return value === null || value === undefined || typeof value.toString !== 'function';
|
|
423
|
+
}
|
|
424
|
+
function isIndexable(value) {
|
|
425
|
+
return value !== null && typeof value === 'object';
|
|
426
|
+
}
|
|
427
|
+
function isSafeString(value) {
|
|
428
|
+
return isIndexable(value) && typeof value['toHTML'] === 'function';
|
|
429
|
+
}
|
|
430
|
+
function isNode(value) {
|
|
431
|
+
return isIndexable(value) && typeof value['nodeType'] === 'number';
|
|
432
|
+
}
|
|
433
|
+
function isFragment(value) {
|
|
434
|
+
return isIndexable(value) && value['nodeType'] === 11;
|
|
435
|
+
}
|
|
436
|
+
function isString(value) {
|
|
437
|
+
return typeof value === 'string';
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
function createClassListRef(list) {
|
|
441
|
+
return createComputeRef(() => {
|
|
442
|
+
let ret = [];
|
|
443
|
+
for (const ref of list) {
|
|
444
|
+
let value = normalizeStringValue(typeof ref === 'string' ? ref : valueForRef(ref));
|
|
445
|
+
if (value) ret.push(value);
|
|
446
|
+
}
|
|
447
|
+
return ret.length === 0 ? null : ret.join(' ');
|
|
448
|
+
});
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
APPEND_OPCODES.add(VM_CHILD_SCOPE_OP, vm => vm.pushChildScope());
|
|
452
|
+
APPEND_OPCODES.add(VM_POP_SCOPE_OP, vm => vm.popScope());
|
|
453
|
+
APPEND_OPCODES.add(VM_PUSH_DYNAMIC_SCOPE_OP, vm => vm.pushDynamicScope());
|
|
454
|
+
APPEND_OPCODES.add(VM_POP_DYNAMIC_SCOPE_OP, vm => vm.popDynamicScope());
|
|
455
|
+
APPEND_OPCODES.add(VM_CONSTANT_OP, (vm, {
|
|
456
|
+
op1: other
|
|
457
|
+
}) => {
|
|
458
|
+
vm.stack.push(vm.constants.getValue(decodeHandle(other)));
|
|
459
|
+
});
|
|
460
|
+
APPEND_OPCODES.add(VM_CONSTANT_REFERENCE_OP, (vm, {
|
|
461
|
+
op1: other
|
|
462
|
+
}) => {
|
|
463
|
+
vm.stack.push(createConstRef(vm.constants.getValue(decodeHandle(other))));
|
|
464
|
+
});
|
|
465
|
+
APPEND_OPCODES.add(VM_PRIMITIVE_OP, (vm, {
|
|
466
|
+
op1: primitive
|
|
467
|
+
}) => {
|
|
468
|
+
let stack = vm.stack;
|
|
469
|
+
if (isHandle(primitive)) {
|
|
470
|
+
// it is a handle which does not already exist on the stack
|
|
471
|
+
let value = vm.constants.getValue(decodeHandle(primitive));
|
|
472
|
+
stack.push(value);
|
|
473
|
+
} else {
|
|
474
|
+
// is already an encoded immediate or primitive handle
|
|
475
|
+
stack.push(decodeImmediate(primitive));
|
|
476
|
+
}
|
|
477
|
+
});
|
|
478
|
+
APPEND_OPCODES.add(VM_PRIMITIVE_REFERENCE_OP, vm => {
|
|
479
|
+
let stack = vm.stack;
|
|
480
|
+
let value = check(stack.pop());
|
|
481
|
+
let ref;
|
|
482
|
+
if (value === undefined) {
|
|
483
|
+
ref = UNDEFINED_REFERENCE;
|
|
484
|
+
} else if (value === null) {
|
|
485
|
+
ref = NULL_REFERENCE;
|
|
486
|
+
} else if (value === true) {
|
|
487
|
+
ref = TRUE_REFERENCE;
|
|
488
|
+
} else if (value === false) {
|
|
489
|
+
ref = FALSE_REFERENCE;
|
|
490
|
+
} else {
|
|
491
|
+
ref = createPrimitiveRef(value);
|
|
492
|
+
}
|
|
493
|
+
stack.push(ref);
|
|
494
|
+
});
|
|
495
|
+
APPEND_OPCODES.add(VM_DUP_OP, (vm, {
|
|
496
|
+
op1: register,
|
|
497
|
+
op2: offset
|
|
498
|
+
}) => {
|
|
499
|
+
let position = check(vm.fetchValue(check(register, CheckRegister))) - offset;
|
|
500
|
+
vm.stack.dup(position);
|
|
501
|
+
});
|
|
502
|
+
APPEND_OPCODES.add(VM_POP_OP, (vm, {
|
|
503
|
+
op1: count
|
|
504
|
+
}) => {
|
|
505
|
+
vm.stack.pop(count);
|
|
506
|
+
});
|
|
507
|
+
APPEND_OPCODES.add(VM_LOAD_OP, (vm, {
|
|
508
|
+
op1: register
|
|
509
|
+
}) => {
|
|
510
|
+
vm.load(check(register));
|
|
511
|
+
});
|
|
512
|
+
APPEND_OPCODES.add(VM_FETCH_OP, (vm, {
|
|
513
|
+
op1: register
|
|
514
|
+
}) => {
|
|
515
|
+
vm.fetch(check(register));
|
|
516
|
+
});
|
|
517
|
+
APPEND_OPCODES.add(VM_BIND_DYNAMIC_SCOPE_OP, (vm, {
|
|
518
|
+
op1: _names
|
|
519
|
+
}) => {
|
|
520
|
+
let names = vm.constants.getArray(_names);
|
|
521
|
+
vm.bindDynamicScope(names);
|
|
522
|
+
});
|
|
523
|
+
APPEND_OPCODES.add(VM_ENTER_OP, (vm, {
|
|
524
|
+
op1: args
|
|
525
|
+
}) => {
|
|
526
|
+
vm.enter(args);
|
|
527
|
+
});
|
|
528
|
+
APPEND_OPCODES.add(VM_EXIT_OP, vm => {
|
|
529
|
+
vm.exit();
|
|
530
|
+
});
|
|
531
|
+
APPEND_OPCODES.add(VM_PUSH_SYMBOL_TABLE_OP, (vm, {
|
|
532
|
+
op1: _table
|
|
533
|
+
}) => {
|
|
534
|
+
let stack = vm.stack;
|
|
535
|
+
stack.push(vm.constants.getValue(_table));
|
|
536
|
+
});
|
|
537
|
+
APPEND_OPCODES.add(VM_PUSH_BLOCK_SCOPE_OP, vm => {
|
|
538
|
+
let stack = vm.stack;
|
|
539
|
+
stack.push(vm.scope());
|
|
540
|
+
});
|
|
541
|
+
APPEND_OPCODES.add(VM_COMPILE_BLOCK_OP, vm => {
|
|
542
|
+
let stack = vm.stack;
|
|
543
|
+
let block = stack.pop();
|
|
544
|
+
if (block) {
|
|
545
|
+
stack.push(vm.compile(block));
|
|
546
|
+
} else {
|
|
547
|
+
stack.push(null);
|
|
548
|
+
}
|
|
549
|
+
});
|
|
550
|
+
APPEND_OPCODES.add(VM_INVOKE_YIELD_OP, vm => {
|
|
551
|
+
let {
|
|
552
|
+
stack
|
|
553
|
+
} = vm;
|
|
554
|
+
let handle = check(stack.pop());
|
|
555
|
+
let scope = check(stack.pop());
|
|
556
|
+
let table = check(stack.pop());
|
|
557
|
+
let args = check(stack.pop());
|
|
558
|
+
if (table === null || handle === null) {
|
|
559
|
+
// To balance the pop{Frame,Scope}
|
|
560
|
+
vm.lowlevel.pushFrame();
|
|
561
|
+
vm.pushScope(scope ?? vm.scope());
|
|
562
|
+
return;
|
|
563
|
+
}
|
|
564
|
+
let invokingScope = expect(scope);
|
|
565
|
+
|
|
566
|
+
// If necessary, create a child scope
|
|
567
|
+
{
|
|
568
|
+
let locals = table.parameters;
|
|
569
|
+
let localsCount = locals.length;
|
|
570
|
+
if (localsCount > 0) {
|
|
571
|
+
invokingScope = invokingScope.child();
|
|
572
|
+
for (let i = 0; i < localsCount; i++) {
|
|
573
|
+
invokingScope.bindSymbol(unwrap(locals[i]), args.at(i));
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
vm.lowlevel.pushFrame();
|
|
578
|
+
vm.pushScope(invokingScope);
|
|
579
|
+
vm.call(handle);
|
|
580
|
+
});
|
|
581
|
+
APPEND_OPCODES.add(VM_JUMP_IF_OP, (vm, {
|
|
582
|
+
op1: target
|
|
583
|
+
}) => {
|
|
584
|
+
let reference = check(vm.stack.pop());
|
|
585
|
+
let value = Boolean(valueForRef(reference));
|
|
586
|
+
if (isConstRef(reference)) {
|
|
587
|
+
if (value) {
|
|
588
|
+
vm.lowlevel.goto(target);
|
|
589
|
+
}
|
|
590
|
+
} else {
|
|
591
|
+
if (value) {
|
|
592
|
+
vm.lowlevel.goto(target);
|
|
593
|
+
}
|
|
594
|
+
vm.updateWith(new Assert(reference));
|
|
595
|
+
}
|
|
596
|
+
});
|
|
597
|
+
APPEND_OPCODES.add(VM_JUMP_UNLESS_OP, (vm, {
|
|
598
|
+
op1: target
|
|
599
|
+
}) => {
|
|
600
|
+
let reference = check(vm.stack.pop());
|
|
601
|
+
let value = Boolean(valueForRef(reference));
|
|
602
|
+
if (isConstRef(reference)) {
|
|
603
|
+
if (!value) {
|
|
604
|
+
vm.lowlevel.goto(target);
|
|
605
|
+
}
|
|
606
|
+
} else {
|
|
607
|
+
if (!value) {
|
|
608
|
+
vm.lowlevel.goto(target);
|
|
609
|
+
}
|
|
610
|
+
vm.updateWith(new Assert(reference));
|
|
611
|
+
}
|
|
612
|
+
});
|
|
613
|
+
APPEND_OPCODES.add(VM_JUMP_EQ_OP, (vm, {
|
|
614
|
+
op1: target,
|
|
615
|
+
op2: comparison
|
|
616
|
+
}) => {
|
|
617
|
+
let other = check(vm.stack.peek());
|
|
618
|
+
if (other === comparison) {
|
|
619
|
+
vm.lowlevel.goto(target);
|
|
620
|
+
}
|
|
621
|
+
});
|
|
622
|
+
APPEND_OPCODES.add(VM_ASSERT_SAME_OP, vm => {
|
|
623
|
+
let reference = check(vm.stack.peek());
|
|
624
|
+
if (!isConstRef(reference)) {
|
|
625
|
+
vm.updateWith(new Assert(reference));
|
|
626
|
+
}
|
|
627
|
+
});
|
|
628
|
+
APPEND_OPCODES.add(VM_TO_BOOLEAN_OP, vm => {
|
|
629
|
+
let {
|
|
630
|
+
stack
|
|
631
|
+
} = vm;
|
|
632
|
+
let valueRef = check(stack.pop());
|
|
633
|
+
stack.push(createComputeRef(() => toBool(valueForRef(valueRef))));
|
|
634
|
+
});
|
|
635
|
+
class Assert {
|
|
636
|
+
last;
|
|
637
|
+
constructor(ref) {
|
|
638
|
+
this.ref = ref;
|
|
639
|
+
this.last = valueForRef(ref);
|
|
640
|
+
}
|
|
641
|
+
evaluate(vm) {
|
|
642
|
+
let {
|
|
643
|
+
last,
|
|
644
|
+
ref
|
|
645
|
+
} = this;
|
|
646
|
+
let current = valueForRef(ref);
|
|
647
|
+
if (last !== current) {
|
|
648
|
+
vm.throw();
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
}
|
|
652
|
+
class AssertFilter {
|
|
653
|
+
last;
|
|
654
|
+
constructor(ref, filter) {
|
|
655
|
+
this.ref = ref;
|
|
656
|
+
this.filter = filter;
|
|
657
|
+
this.last = filter(valueForRef(ref));
|
|
658
|
+
}
|
|
659
|
+
evaluate(vm) {
|
|
660
|
+
let {
|
|
661
|
+
last,
|
|
662
|
+
ref,
|
|
663
|
+
filter
|
|
664
|
+
} = this;
|
|
665
|
+
let current = filter(valueForRef(ref));
|
|
666
|
+
if (last !== current) {
|
|
667
|
+
vm.throw();
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
class JumpIfNotModifiedOpcode {
|
|
672
|
+
tag = CONSTANT_TAG;
|
|
673
|
+
lastRevision = INITIAL;
|
|
674
|
+
target;
|
|
675
|
+
finalize(tag, target) {
|
|
676
|
+
this.target = target;
|
|
677
|
+
this.didModify(tag);
|
|
678
|
+
}
|
|
679
|
+
evaluate(vm) {
|
|
680
|
+
let {
|
|
681
|
+
tag,
|
|
682
|
+
target,
|
|
683
|
+
lastRevision
|
|
684
|
+
} = this;
|
|
685
|
+
if (!vm.alwaysRevalidate && validateTag(tag, lastRevision)) {
|
|
686
|
+
consumeTag(tag);
|
|
687
|
+
vm.goto(expect(target));
|
|
688
|
+
}
|
|
689
|
+
}
|
|
690
|
+
didModify(tag) {
|
|
691
|
+
this.tag = tag;
|
|
692
|
+
this.lastRevision = valueForTag(this.tag);
|
|
693
|
+
consumeTag(tag);
|
|
694
|
+
}
|
|
695
|
+
}
|
|
696
|
+
class BeginTrackFrameOpcode {
|
|
697
|
+
constructor(debugLabel) {
|
|
698
|
+
this.debugLabel = debugLabel;
|
|
699
|
+
}
|
|
700
|
+
evaluate() {
|
|
701
|
+
beginTrackFrame(this.debugLabel);
|
|
702
|
+
}
|
|
703
|
+
}
|
|
704
|
+
class EndTrackFrameOpcode {
|
|
705
|
+
constructor(target) {
|
|
706
|
+
this.target = target;
|
|
707
|
+
}
|
|
708
|
+
evaluate() {
|
|
709
|
+
let tag = endTrackFrame();
|
|
710
|
+
this.target.didModify(tag);
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
APPEND_OPCODES.add(VM_TEXT_OP, (vm, {
|
|
715
|
+
op1: text
|
|
716
|
+
}) => {
|
|
717
|
+
vm.tree().appendText(vm.constants.getValue(text));
|
|
718
|
+
});
|
|
719
|
+
APPEND_OPCODES.add(VM_COMMENT_OP, (vm, {
|
|
720
|
+
op1: text
|
|
721
|
+
}) => {
|
|
722
|
+
vm.tree().appendComment(vm.constants.getValue(text));
|
|
723
|
+
});
|
|
724
|
+
APPEND_OPCODES.add(VM_OPEN_ELEMENT_OP, (vm, {
|
|
725
|
+
op1: tag
|
|
726
|
+
}) => {
|
|
727
|
+
vm.tree().openElement(vm.constants.getValue(tag));
|
|
728
|
+
});
|
|
729
|
+
APPEND_OPCODES.add(VM_OPEN_DYNAMIC_ELEMENT_OP, vm => {
|
|
730
|
+
let tagName = check(valueForRef(check(vm.stack.pop(), CheckReference)));
|
|
731
|
+
vm.tree().openElement(tagName);
|
|
732
|
+
});
|
|
733
|
+
APPEND_OPCODES.add(VM_PUSH_REMOTE_ELEMENT_OP, vm => {
|
|
734
|
+
let elementRef = check(vm.stack.pop());
|
|
735
|
+
let insertBeforeRef = check(vm.stack.pop());
|
|
736
|
+
let guidRef = check(vm.stack.pop());
|
|
737
|
+
let element = check(valueForRef(elementRef));
|
|
738
|
+
let insertBefore = check(valueForRef(insertBeforeRef));
|
|
739
|
+
let guid = valueForRef(guidRef);
|
|
740
|
+
if (!isConstRef(elementRef)) {
|
|
741
|
+
vm.updateWith(new Assert(elementRef));
|
|
742
|
+
}
|
|
743
|
+
if (insertBefore !== undefined && !isConstRef(insertBeforeRef)) {
|
|
744
|
+
vm.updateWith(new Assert(insertBeforeRef));
|
|
745
|
+
}
|
|
746
|
+
let block = vm.tree().pushRemoteElement(element, guid, insertBefore);
|
|
747
|
+
vm.associateDestroyable(block);
|
|
748
|
+
if (vm.env.debugRenderTree !== undefined) {
|
|
749
|
+
// Note that there is nothing to update – when the args for an
|
|
750
|
+
// {{#in-element}} changes it gets torn down and a new one is
|
|
751
|
+
// re-created/rendered in its place (see the `Assert`s above)
|
|
752
|
+
let args = createCapturedArgs(insertBefore === undefined ? {} : {
|
|
753
|
+
insertBefore: insertBeforeRef
|
|
754
|
+
}, [elementRef]);
|
|
755
|
+
vm.env.debugRenderTree.create(block, {
|
|
756
|
+
type: 'keyword',
|
|
757
|
+
name: 'in-element',
|
|
758
|
+
args,
|
|
759
|
+
instance: null
|
|
760
|
+
});
|
|
761
|
+
registerDestructor(block, () => {
|
|
762
|
+
vm.env.debugRenderTree?.willDestroy(block);
|
|
763
|
+
});
|
|
764
|
+
}
|
|
765
|
+
});
|
|
766
|
+
APPEND_OPCODES.add(VM_POP_REMOTE_ELEMENT_OP, vm => {
|
|
767
|
+
let bounds = vm.tree().popRemoteElement();
|
|
768
|
+
if (vm.env.debugRenderTree !== undefined) {
|
|
769
|
+
// The RemoteBlock is also its bounds
|
|
770
|
+
vm.env.debugRenderTree.didRender(bounds, bounds);
|
|
771
|
+
}
|
|
772
|
+
});
|
|
773
|
+
APPEND_OPCODES.add(VM_FLUSH_ELEMENT_OP, vm => {
|
|
774
|
+
let operations = check(vm.fetchValue($t0));
|
|
775
|
+
let modifiers = null;
|
|
776
|
+
if (operations) {
|
|
777
|
+
modifiers = operations.flush(vm);
|
|
778
|
+
vm.loadValue($t0, null);
|
|
779
|
+
}
|
|
780
|
+
vm.tree().flushElement(modifiers);
|
|
781
|
+
});
|
|
782
|
+
APPEND_OPCODES.add(VM_CLOSE_ELEMENT_OP, vm => {
|
|
783
|
+
let modifiers = vm.tree().closeElement();
|
|
784
|
+
if (modifiers !== null) {
|
|
785
|
+
modifiers.forEach(modifier => {
|
|
786
|
+
vm.env.scheduleInstallModifier(modifier);
|
|
787
|
+
const d = modifier.manager.getDestroyable(modifier.state);
|
|
788
|
+
if (d !== null) {
|
|
789
|
+
vm.associateDestroyable(d);
|
|
790
|
+
}
|
|
791
|
+
});
|
|
792
|
+
}
|
|
793
|
+
});
|
|
794
|
+
APPEND_OPCODES.add(VM_MODIFIER_OP, (vm, {
|
|
795
|
+
op1: handle
|
|
796
|
+
}) => {
|
|
797
|
+
let args = check(vm.stack.pop());
|
|
798
|
+
if (!vm.env.isInteractive) {
|
|
799
|
+
return;
|
|
800
|
+
}
|
|
801
|
+
let owner = vm.getOwner();
|
|
802
|
+
let definition = vm.constants.getValue(handle);
|
|
803
|
+
let {
|
|
804
|
+
manager
|
|
805
|
+
} = definition;
|
|
806
|
+
let {
|
|
807
|
+
constructing
|
|
808
|
+
} = vm.tree();
|
|
809
|
+
let capturedArgs = args.capture();
|
|
810
|
+
let state = manager.create(owner, expect(constructing), definition.state, capturedArgs);
|
|
811
|
+
let instance = {
|
|
812
|
+
manager,
|
|
813
|
+
state,
|
|
814
|
+
definition
|
|
815
|
+
};
|
|
816
|
+
let operations = expect(check(vm.fetchValue($t0)));
|
|
817
|
+
operations.addModifier(vm, instance, capturedArgs);
|
|
818
|
+
let tag = manager.getTag(state);
|
|
819
|
+
if (tag !== null) {
|
|
820
|
+
consumeTag(tag);
|
|
821
|
+
return vm.updateWith(new UpdateModifierOpcode(tag, instance));
|
|
822
|
+
}
|
|
823
|
+
});
|
|
824
|
+
APPEND_OPCODES.add(VM_DYNAMIC_MODIFIER_OP, vm => {
|
|
825
|
+
let {
|
|
826
|
+
stack
|
|
827
|
+
} = vm;
|
|
828
|
+
let ref = check(stack.pop());
|
|
829
|
+
let args = check(stack.pop());
|
|
830
|
+
if (!vm.env.isInteractive) {
|
|
831
|
+
return;
|
|
832
|
+
}
|
|
833
|
+
let capturedArgs = args.capture();
|
|
834
|
+
let {
|
|
835
|
+
positional: outerPositional,
|
|
836
|
+
named: outerNamed
|
|
837
|
+
} = capturedArgs;
|
|
838
|
+
let {
|
|
839
|
+
constructing
|
|
840
|
+
} = vm.tree();
|
|
841
|
+
let initialOwner = vm.getOwner();
|
|
842
|
+
let instanceRef = createComputeRef(() => {
|
|
843
|
+
let value = valueForRef(ref);
|
|
844
|
+
let owner;
|
|
845
|
+
if (!isIndexable$1(value)) {
|
|
846
|
+
return;
|
|
847
|
+
}
|
|
848
|
+
let hostDefinition;
|
|
849
|
+
if (isCurriedType(value, CURRIED_MODIFIER)) {
|
|
850
|
+
let {
|
|
851
|
+
definition: resolvedDefinition,
|
|
852
|
+
owner: curriedOwner,
|
|
853
|
+
positional,
|
|
854
|
+
named
|
|
855
|
+
} = resolveCurriedValue(value);
|
|
856
|
+
hostDefinition = resolvedDefinition;
|
|
857
|
+
owner = curriedOwner;
|
|
858
|
+
if (positional !== undefined) {
|
|
859
|
+
capturedArgs.positional = positional.concat(outerPositional);
|
|
860
|
+
}
|
|
861
|
+
if (named !== undefined) {
|
|
862
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
863
|
+
capturedArgs.named = Object.assign({}, ...named, outerNamed);
|
|
864
|
+
}
|
|
865
|
+
} else {
|
|
866
|
+
hostDefinition = value;
|
|
867
|
+
owner = initialOwner;
|
|
868
|
+
}
|
|
869
|
+
let manager = getInternalModifierManager(hostDefinition);
|
|
870
|
+
if (manager === null) {
|
|
871
|
+
{
|
|
872
|
+
throw new Error('BUG: modifier manager expected');
|
|
873
|
+
}
|
|
874
|
+
}
|
|
875
|
+
let definition = {
|
|
876
|
+
resolvedName: null,
|
|
877
|
+
manager,
|
|
878
|
+
state: hostDefinition
|
|
879
|
+
};
|
|
880
|
+
let state = manager.create(owner, expect(constructing), definition.state, capturedArgs);
|
|
881
|
+
return {
|
|
882
|
+
manager,
|
|
883
|
+
state,
|
|
884
|
+
definition
|
|
885
|
+
};
|
|
886
|
+
});
|
|
887
|
+
let instance = valueForRef(instanceRef);
|
|
888
|
+
let tag = null;
|
|
889
|
+
if (instance !== undefined) {
|
|
890
|
+
let operations = expect(check(vm.fetchValue($t0)));
|
|
891
|
+
operations.addModifier(vm, instance, capturedArgs);
|
|
892
|
+
tag = instance.manager.getTag(instance.state);
|
|
893
|
+
if (tag !== null) {
|
|
894
|
+
consumeTag(tag);
|
|
895
|
+
}
|
|
896
|
+
}
|
|
897
|
+
if (!isConstRef(ref) || tag) {
|
|
898
|
+
return vm.updateWith(new UpdateDynamicModifierOpcode(tag, instance, instanceRef));
|
|
899
|
+
}
|
|
900
|
+
});
|
|
901
|
+
class UpdateModifierOpcode {
|
|
902
|
+
lastUpdated;
|
|
903
|
+
constructor(tag, modifier) {
|
|
904
|
+
this.tag = tag;
|
|
905
|
+
this.modifier = modifier;
|
|
906
|
+
this.lastUpdated = valueForTag(tag);
|
|
907
|
+
}
|
|
908
|
+
evaluate(vm) {
|
|
909
|
+
let {
|
|
910
|
+
modifier,
|
|
911
|
+
tag,
|
|
912
|
+
lastUpdated
|
|
913
|
+
} = this;
|
|
914
|
+
consumeTag(tag);
|
|
915
|
+
if (!validateTag(tag, lastUpdated)) {
|
|
916
|
+
vm.env.scheduleUpdateModifier(modifier);
|
|
917
|
+
this.lastUpdated = valueForTag(tag);
|
|
918
|
+
}
|
|
919
|
+
}
|
|
920
|
+
}
|
|
921
|
+
class UpdateDynamicModifierOpcode {
|
|
922
|
+
lastUpdated;
|
|
923
|
+
constructor(tag, instance, instanceRef) {
|
|
924
|
+
this.tag = tag;
|
|
925
|
+
this.instance = instance;
|
|
926
|
+
this.instanceRef = instanceRef;
|
|
927
|
+
this.lastUpdated = valueForTag(tag ?? CURRENT_TAG);
|
|
928
|
+
}
|
|
929
|
+
evaluate(vm) {
|
|
930
|
+
let {
|
|
931
|
+
tag,
|
|
932
|
+
lastUpdated,
|
|
933
|
+
instance,
|
|
934
|
+
instanceRef
|
|
935
|
+
} = this;
|
|
936
|
+
let newInstance = valueForRef(instanceRef);
|
|
937
|
+
if (newInstance !== instance) {
|
|
938
|
+
if (instance !== undefined) {
|
|
939
|
+
let destroyable = instance.manager.getDestroyable(instance.state);
|
|
940
|
+
if (destroyable !== null) {
|
|
941
|
+
destroy(destroyable);
|
|
942
|
+
}
|
|
943
|
+
}
|
|
944
|
+
if (newInstance !== undefined) {
|
|
945
|
+
let {
|
|
946
|
+
manager,
|
|
947
|
+
state
|
|
948
|
+
} = newInstance;
|
|
949
|
+
let destroyable = manager.getDestroyable(state);
|
|
950
|
+
if (destroyable !== null) {
|
|
951
|
+
associateDestroyableChild(this, destroyable);
|
|
952
|
+
}
|
|
953
|
+
tag = manager.getTag(state);
|
|
954
|
+
if (tag !== null) {
|
|
955
|
+
this.lastUpdated = valueForTag(tag);
|
|
956
|
+
}
|
|
957
|
+
this.tag = tag;
|
|
958
|
+
vm.env.scheduleInstallModifier(newInstance);
|
|
959
|
+
}
|
|
960
|
+
this.instance = newInstance;
|
|
961
|
+
} else if (tag !== null && !validateTag(tag, lastUpdated)) {
|
|
962
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- @fixme
|
|
963
|
+
vm.env.scheduleUpdateModifier(instance);
|
|
964
|
+
this.lastUpdated = valueForTag(tag);
|
|
965
|
+
}
|
|
966
|
+
if (tag !== null) {
|
|
967
|
+
consumeTag(tag);
|
|
968
|
+
}
|
|
969
|
+
}
|
|
970
|
+
}
|
|
971
|
+
APPEND_OPCODES.add(VM_STATIC_ATTR_OP, (vm, {
|
|
972
|
+
op1: _name,
|
|
973
|
+
op2: _value,
|
|
974
|
+
op3: _namespace
|
|
975
|
+
}) => {
|
|
976
|
+
let name = vm.constants.getValue(_name);
|
|
977
|
+
let value = vm.constants.getValue(_value);
|
|
978
|
+
let namespace = _namespace ? vm.constants.getValue(_namespace) : null;
|
|
979
|
+
vm.tree().setStaticAttribute(name, value, namespace);
|
|
980
|
+
});
|
|
981
|
+
APPEND_OPCODES.add(VM_DYNAMIC_ATTR_OP, (vm, {
|
|
982
|
+
op1: _name,
|
|
983
|
+
op2: _trusting,
|
|
984
|
+
op3: _namespace
|
|
985
|
+
}) => {
|
|
986
|
+
let name = vm.constants.getValue(_name);
|
|
987
|
+
let trusting = vm.constants.getValue(_trusting);
|
|
988
|
+
let reference = check(vm.stack.pop());
|
|
989
|
+
let value = valueForRef(reference);
|
|
990
|
+
let namespace = _namespace ? vm.constants.getValue(_namespace) : null;
|
|
991
|
+
let attribute = vm.tree().setDynamicAttribute(name, value, trusting, namespace);
|
|
992
|
+
if (!isConstRef(reference)) {
|
|
993
|
+
vm.updateWith(new UpdateDynamicAttributeOpcode(reference, attribute, vm.env));
|
|
994
|
+
}
|
|
995
|
+
});
|
|
996
|
+
class UpdateDynamicAttributeOpcode {
|
|
997
|
+
updateRef;
|
|
998
|
+
constructor(reference, attribute, env) {
|
|
999
|
+
let initialized = false;
|
|
1000
|
+
this.updateRef = createComputeRef(() => {
|
|
1001
|
+
let value = valueForRef(reference);
|
|
1002
|
+
if (initialized) {
|
|
1003
|
+
attribute.update(value, env);
|
|
1004
|
+
} else {
|
|
1005
|
+
initialized = true;
|
|
1006
|
+
}
|
|
1007
|
+
});
|
|
1008
|
+
valueForRef(this.updateRef);
|
|
1009
|
+
}
|
|
1010
|
+
evaluate() {
|
|
1011
|
+
valueForRef(this.updateRef);
|
|
1012
|
+
}
|
|
1013
|
+
}
|
|
1014
|
+
|
|
1015
|
+
/**
|
|
1016
|
+
* The VM creates a new ComponentInstance data structure for every component
|
|
1017
|
+
* invocation it encounters.
|
|
1018
|
+
*
|
|
1019
|
+
* Similar to how a ComponentDefinition contains state about all components of a
|
|
1020
|
+
* particular type, a ComponentInstance contains state specific to a particular
|
|
1021
|
+
* instance of a component type. It also contains a pointer back to its
|
|
1022
|
+
* component type's ComponentDefinition.
|
|
1023
|
+
*/
|
|
1024
|
+
|
|
1025
|
+
APPEND_OPCODES.add(VM_PUSH_COMPONENT_DEFINITION_OP, (vm, {
|
|
1026
|
+
op1: handle
|
|
1027
|
+
}) => {
|
|
1028
|
+
let definition = vm.constants.getValue(handle);
|
|
1029
|
+
let {
|
|
1030
|
+
manager,
|
|
1031
|
+
capabilities
|
|
1032
|
+
} = definition;
|
|
1033
|
+
let instance = {
|
|
1034
|
+
definition,
|
|
1035
|
+
manager,
|
|
1036
|
+
capabilities,
|
|
1037
|
+
state: null,
|
|
1038
|
+
handle: null,
|
|
1039
|
+
table: null,
|
|
1040
|
+
lookup: null
|
|
1041
|
+
};
|
|
1042
|
+
vm.stack.push(instance);
|
|
1043
|
+
});
|
|
1044
|
+
APPEND_OPCODES.add(VM_RESOLVE_DYNAMIC_COMPONENT_OP, (vm, {
|
|
1045
|
+
op1: _isStrict
|
|
1046
|
+
}) => {
|
|
1047
|
+
let stack = vm.stack;
|
|
1048
|
+
let ref = check(stack.pop());
|
|
1049
|
+
let component = check(valueForRef(ref));
|
|
1050
|
+
let constants = vm.constants;
|
|
1051
|
+
let owner = vm.getOwner();
|
|
1052
|
+
constants.getValue(_isStrict);
|
|
1053
|
+
vm.loadValue($t1, null); // Clear the temp register
|
|
1054
|
+
|
|
1055
|
+
let definition;
|
|
1056
|
+
if (typeof component === 'string') {
|
|
1057
|
+
let resolvedDefinition = resolveComponent(vm.context.resolver, constants, component, owner);
|
|
1058
|
+
definition = expect(resolvedDefinition);
|
|
1059
|
+
} else if (isCurriedValue(component)) {
|
|
1060
|
+
definition = component;
|
|
1061
|
+
} else {
|
|
1062
|
+
definition = constants.component(component, owner);
|
|
1063
|
+
}
|
|
1064
|
+
stack.push(definition);
|
|
1065
|
+
});
|
|
1066
|
+
APPEND_OPCODES.add(VM_RESOLVE_CURRIED_COMPONENT_OP, vm => {
|
|
1067
|
+
let stack = vm.stack;
|
|
1068
|
+
let ref = check(stack.pop());
|
|
1069
|
+
let value = valueForRef(ref);
|
|
1070
|
+
let constants = vm.constants;
|
|
1071
|
+
let definition;
|
|
1072
|
+
if (isCurriedValue(value)) {
|
|
1073
|
+
definition = value;
|
|
1074
|
+
} else {
|
|
1075
|
+
definition = constants.component(value, vm.getOwner(), true);
|
|
1076
|
+
}
|
|
1077
|
+
stack.push(definition);
|
|
1078
|
+
});
|
|
1079
|
+
APPEND_OPCODES.add(VM_PUSH_DYNAMIC_COMPONENT_INSTANCE_OP, vm => {
|
|
1080
|
+
let {
|
|
1081
|
+
stack
|
|
1082
|
+
} = vm;
|
|
1083
|
+
let definition = stack.pop();
|
|
1084
|
+
let capabilities, manager;
|
|
1085
|
+
if (isCurriedValue(definition)) {
|
|
1086
|
+
manager = capabilities = null;
|
|
1087
|
+
} else {
|
|
1088
|
+
manager = definition.manager;
|
|
1089
|
+
capabilities = definition.capabilities;
|
|
1090
|
+
}
|
|
1091
|
+
stack.push({
|
|
1092
|
+
definition,
|
|
1093
|
+
capabilities,
|
|
1094
|
+
manager,
|
|
1095
|
+
state: null,
|
|
1096
|
+
handle: null,
|
|
1097
|
+
table: null
|
|
1098
|
+
});
|
|
1099
|
+
});
|
|
1100
|
+
APPEND_OPCODES.add(VM_PUSH_ARGS_OP, (vm, {
|
|
1101
|
+
op1: _names,
|
|
1102
|
+
op2: _blockNames,
|
|
1103
|
+
op3: flags
|
|
1104
|
+
}) => {
|
|
1105
|
+
let stack = vm.stack;
|
|
1106
|
+
let names = vm.constants.getArray(_names);
|
|
1107
|
+
let positionalCount = flags >> 4;
|
|
1108
|
+
let atNames = flags & 0b1000;
|
|
1109
|
+
let blockNames = flags & 0b0111 ? vm.constants.getArray(_blockNames) : EMPTY_STRING_ARRAY;
|
|
1110
|
+
vm.args.setup(stack, names, blockNames, positionalCount, !!atNames);
|
|
1111
|
+
stack.push(vm.args);
|
|
1112
|
+
});
|
|
1113
|
+
APPEND_OPCODES.add(VM_PUSH_EMPTY_ARGS_OP, vm => {
|
|
1114
|
+
let {
|
|
1115
|
+
stack
|
|
1116
|
+
} = vm;
|
|
1117
|
+
stack.push(vm.args.empty(stack));
|
|
1118
|
+
});
|
|
1119
|
+
APPEND_OPCODES.add(VM_CAPTURE_ARGS_OP, vm => {
|
|
1120
|
+
let stack = vm.stack;
|
|
1121
|
+
let args = check(stack.pop());
|
|
1122
|
+
let capturedArgs = args.capture();
|
|
1123
|
+
stack.push(capturedArgs);
|
|
1124
|
+
});
|
|
1125
|
+
APPEND_OPCODES.add(VM_PREPARE_ARGS_OP, (vm, {
|
|
1126
|
+
op1: register
|
|
1127
|
+
}) => {
|
|
1128
|
+
let stack = vm.stack;
|
|
1129
|
+
let instance = vm.fetchValue(check(register));
|
|
1130
|
+
let args = check(stack.pop());
|
|
1131
|
+
let {
|
|
1132
|
+
definition
|
|
1133
|
+
} = instance;
|
|
1134
|
+
if (isCurriedType(definition, CURRIED_COMPONENT)) {
|
|
1135
|
+
assert(!definition.manager);
|
|
1136
|
+
let constants = vm.constants;
|
|
1137
|
+
let {
|
|
1138
|
+
definition: resolvedDefinition,
|
|
1139
|
+
owner,
|
|
1140
|
+
resolved,
|
|
1141
|
+
positional,
|
|
1142
|
+
named
|
|
1143
|
+
} = resolveCurriedValue(definition);
|
|
1144
|
+
if (resolved) {
|
|
1145
|
+
definition = resolvedDefinition;
|
|
1146
|
+
} else if (typeof resolvedDefinition === 'string') {
|
|
1147
|
+
let resolvedValue = vm.context.resolver?.lookupComponent?.(resolvedDefinition, owner) ?? null;
|
|
1148
|
+
definition = constants.resolvedComponent(expect(resolvedValue), resolvedDefinition);
|
|
1149
|
+
} else {
|
|
1150
|
+
definition = constants.component(resolvedDefinition, owner);
|
|
1151
|
+
}
|
|
1152
|
+
if (named !== undefined) {
|
|
1153
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
1154
|
+
args.named.merge(assign({}, ...named));
|
|
1155
|
+
}
|
|
1156
|
+
if (positional !== undefined) {
|
|
1157
|
+
args.realloc(positional.length);
|
|
1158
|
+
args.positional.prepend(positional);
|
|
1159
|
+
}
|
|
1160
|
+
let {
|
|
1161
|
+
manager
|
|
1162
|
+
} = definition;
|
|
1163
|
+
instance.definition = definition;
|
|
1164
|
+
instance.manager = manager;
|
|
1165
|
+
instance.capabilities = definition.capabilities;
|
|
1166
|
+
|
|
1167
|
+
// Save off the owner that this component was curried with. Later on,
|
|
1168
|
+
// we'll fetch the value of this register and set it as the owner on the
|
|
1169
|
+
// new root scope.
|
|
1170
|
+
vm.loadValue($t1, owner);
|
|
1171
|
+
}
|
|
1172
|
+
let {
|
|
1173
|
+
manager,
|
|
1174
|
+
state
|
|
1175
|
+
} = definition;
|
|
1176
|
+
let capabilities = instance.capabilities;
|
|
1177
|
+
if (!managerHasCapability(manager, capabilities, InternalComponentCapabilities.prepareArgs)) {
|
|
1178
|
+
stack.push(args);
|
|
1179
|
+
return;
|
|
1180
|
+
}
|
|
1181
|
+
let blocks = args.blocks.values;
|
|
1182
|
+
let blockNames = args.blocks.names;
|
|
1183
|
+
let preparedArgs = manager.prepareArgs(state, args);
|
|
1184
|
+
if (preparedArgs) {
|
|
1185
|
+
args.clear();
|
|
1186
|
+
for (let i = 0; i < blocks.length; i++) {
|
|
1187
|
+
stack.push(blocks[i]);
|
|
1188
|
+
}
|
|
1189
|
+
let {
|
|
1190
|
+
positional,
|
|
1191
|
+
named
|
|
1192
|
+
} = preparedArgs;
|
|
1193
|
+
let positionalCount = positional.length;
|
|
1194
|
+
for (let i = 0; i < positionalCount; i++) {
|
|
1195
|
+
stack.push(positional[i]);
|
|
1196
|
+
}
|
|
1197
|
+
let names = Object.keys(named);
|
|
1198
|
+
for (let i = 0; i < names.length; i++) {
|
|
1199
|
+
stack.push(named[unwrap(names[i])]);
|
|
1200
|
+
}
|
|
1201
|
+
args.setup(stack, names, blockNames, positionalCount, false);
|
|
1202
|
+
}
|
|
1203
|
+
stack.push(args);
|
|
1204
|
+
});
|
|
1205
|
+
APPEND_OPCODES.add(VM_CREATE_COMPONENT_OP, (vm, {
|
|
1206
|
+
op1: flags
|
|
1207
|
+
}) => {
|
|
1208
|
+
let instance = check(vm.fetchValue($s0));
|
|
1209
|
+
let {
|
|
1210
|
+
definition,
|
|
1211
|
+
manager,
|
|
1212
|
+
capabilities
|
|
1213
|
+
} = instance;
|
|
1214
|
+
if (!managerHasCapability(manager, capabilities, InternalComponentCapabilities.createInstance)) {
|
|
1215
|
+
// TODO: Closure and Main components are always invoked dynamically, so this
|
|
1216
|
+
// opcode may run even if this capability is not enabled. In the future we
|
|
1217
|
+
// should handle this in a better way.
|
|
1218
|
+
return;
|
|
1219
|
+
}
|
|
1220
|
+
let dynamicScope = null;
|
|
1221
|
+
if (managerHasCapability(manager, capabilities, InternalComponentCapabilities.dynamicScope)) {
|
|
1222
|
+
dynamicScope = vm.dynamicScope();
|
|
1223
|
+
}
|
|
1224
|
+
let hasDefaultBlock = flags & 1;
|
|
1225
|
+
let args = null;
|
|
1226
|
+
if (managerHasCapability(manager, capabilities, InternalComponentCapabilities.createArgs)) {
|
|
1227
|
+
args = check(vm.stack.peek());
|
|
1228
|
+
}
|
|
1229
|
+
let self = null;
|
|
1230
|
+
if (managerHasCapability(manager, capabilities, InternalComponentCapabilities.createCaller)) {
|
|
1231
|
+
self = vm.getSelf();
|
|
1232
|
+
}
|
|
1233
|
+
let state = manager.create(vm.getOwner(), definition.state, args, vm.env, dynamicScope, self, !!hasDefaultBlock);
|
|
1234
|
+
|
|
1235
|
+
// We want to reuse the `state` POJO here, because we know that the opcodes
|
|
1236
|
+
// only transition at exactly one place.
|
|
1237
|
+
instance.state = state;
|
|
1238
|
+
if (managerHasCapability(manager, capabilities, InternalComponentCapabilities.updateHook)) {
|
|
1239
|
+
vm.updateWith(new UpdateComponentOpcode(state, manager, dynamicScope));
|
|
1240
|
+
}
|
|
1241
|
+
});
|
|
1242
|
+
APPEND_OPCODES.add(VM_REGISTER_COMPONENT_DESTRUCTOR_OP, (vm, {
|
|
1243
|
+
op1: register
|
|
1244
|
+
}) => {
|
|
1245
|
+
let {
|
|
1246
|
+
manager,
|
|
1247
|
+
state,
|
|
1248
|
+
capabilities
|
|
1249
|
+
} = check(vm.fetchValue(check(register, CheckRegister)));
|
|
1250
|
+
let d = manager.getDestroyable(state);
|
|
1251
|
+
if (d) vm.associateDestroyable(d);
|
|
1252
|
+
});
|
|
1253
|
+
APPEND_OPCODES.add(VM_BEGIN_COMPONENT_TRANSACTION_OP, (vm, {
|
|
1254
|
+
op1: register
|
|
1255
|
+
}) => {
|
|
1256
|
+
let name;
|
|
1257
|
+
vm.beginCacheGroup(name);
|
|
1258
|
+
vm.tree().pushAppendingBlock();
|
|
1259
|
+
});
|
|
1260
|
+
APPEND_OPCODES.add(VM_PUT_COMPONENT_OPERATIONS_OP, vm => {
|
|
1261
|
+
vm.loadValue($t0, new ComponentElementOperations());
|
|
1262
|
+
});
|
|
1263
|
+
APPEND_OPCODES.add(VM_COMPONENT_ATTR_OP, (vm, {
|
|
1264
|
+
op1: _name,
|
|
1265
|
+
op2: _trusting,
|
|
1266
|
+
op3: _namespace
|
|
1267
|
+
}) => {
|
|
1268
|
+
let name = vm.constants.getValue(_name);
|
|
1269
|
+
let trusting = vm.constants.getValue(_trusting);
|
|
1270
|
+
let reference = check(vm.stack.pop());
|
|
1271
|
+
let namespace = _namespace ? vm.constants.getValue(_namespace) : null;
|
|
1272
|
+
check(vm.fetchValue($t0), CheckInstanceof(ComponentElementOperations)).setAttribute(name, reference, trusting, namespace);
|
|
1273
|
+
});
|
|
1274
|
+
APPEND_OPCODES.add(VM_STATIC_COMPONENT_ATTR_OP, (vm, {
|
|
1275
|
+
op1: _name,
|
|
1276
|
+
op2: _value,
|
|
1277
|
+
op3: _namespace
|
|
1278
|
+
}) => {
|
|
1279
|
+
let name = vm.constants.getValue(_name);
|
|
1280
|
+
let value = vm.constants.getValue(_value);
|
|
1281
|
+
let namespace = _namespace ? vm.constants.getValue(_namespace) : null;
|
|
1282
|
+
check(vm.fetchValue($t0), CheckInstanceof(ComponentElementOperations)).setStaticAttribute(name, value, namespace);
|
|
1283
|
+
});
|
|
1284
|
+
class ComponentElementOperations {
|
|
1285
|
+
attributes = dict();
|
|
1286
|
+
classes = [];
|
|
1287
|
+
modifiers = [];
|
|
1288
|
+
setAttribute(name, value, trusting, namespace) {
|
|
1289
|
+
let deferred = {
|
|
1290
|
+
value,
|
|
1291
|
+
namespace,
|
|
1292
|
+
trusting
|
|
1293
|
+
};
|
|
1294
|
+
if (name === 'class') {
|
|
1295
|
+
this.classes.push(value);
|
|
1296
|
+
}
|
|
1297
|
+
this.attributes[name] = deferred;
|
|
1298
|
+
}
|
|
1299
|
+
setStaticAttribute(name, value, namespace) {
|
|
1300
|
+
let deferred = {
|
|
1301
|
+
value,
|
|
1302
|
+
namespace
|
|
1303
|
+
};
|
|
1304
|
+
if (name === 'class') {
|
|
1305
|
+
this.classes.push(value);
|
|
1306
|
+
}
|
|
1307
|
+
this.attributes[name] = deferred;
|
|
1308
|
+
}
|
|
1309
|
+
addModifier(vm, modifier, capturedArgs) {
|
|
1310
|
+
this.modifiers.push(modifier);
|
|
1311
|
+
if (vm.env.debugRenderTree !== undefined) {
|
|
1312
|
+
const {
|
|
1313
|
+
manager,
|
|
1314
|
+
definition,
|
|
1315
|
+
state
|
|
1316
|
+
} = modifier;
|
|
1317
|
+
|
|
1318
|
+
// TODO: we need a stable object for the debugRenderTree as the key, add support for
|
|
1319
|
+
// the case where the state is a primitive, or if in practice we always have/require
|
|
1320
|
+
// an object, then change the internal types to reflect that
|
|
1321
|
+
if (state === null || typeof state !== 'object' && typeof state !== 'function') {
|
|
1322
|
+
return;
|
|
1323
|
+
}
|
|
1324
|
+
let {
|
|
1325
|
+
element,
|
|
1326
|
+
constructing
|
|
1327
|
+
} = vm.tree();
|
|
1328
|
+
let name = definition.resolvedName ?? manager.getDebugName(definition.state);
|
|
1329
|
+
let instance = manager.getDebugInstance(state);
|
|
1330
|
+
let bounds = new ConcreteBounds(element, constructing, constructing);
|
|
1331
|
+
vm.env.debugRenderTree.create(state, {
|
|
1332
|
+
type: 'modifier',
|
|
1333
|
+
name,
|
|
1334
|
+
args: capturedArgs,
|
|
1335
|
+
instance
|
|
1336
|
+
});
|
|
1337
|
+
vm.env.debugRenderTree.didRender(state, bounds);
|
|
1338
|
+
|
|
1339
|
+
// For tearing down the debugRenderTree
|
|
1340
|
+
vm.associateDestroyable(state);
|
|
1341
|
+
vm.updateWith(new DebugRenderTreeUpdateOpcode(state));
|
|
1342
|
+
vm.updateWith(new DebugRenderTreeDidRenderOpcode(state, bounds));
|
|
1343
|
+
registerDestructor(state, () => {
|
|
1344
|
+
vm.env.debugRenderTree?.willDestroy(state);
|
|
1345
|
+
});
|
|
1346
|
+
}
|
|
1347
|
+
}
|
|
1348
|
+
flush(vm) {
|
|
1349
|
+
let type;
|
|
1350
|
+
let attributes = this.attributes;
|
|
1351
|
+
for (let name in this.attributes) {
|
|
1352
|
+
if (name === 'type') {
|
|
1353
|
+
type = attributes[name];
|
|
1354
|
+
continue;
|
|
1355
|
+
}
|
|
1356
|
+
let attr = unwrap(this.attributes[name]);
|
|
1357
|
+
if (name === 'class') {
|
|
1358
|
+
setDeferredAttr(vm, 'class', mergeClasses(this.classes), attr.namespace, attr.trusting);
|
|
1359
|
+
} else {
|
|
1360
|
+
setDeferredAttr(vm, name, attr.value, attr.namespace, attr.trusting);
|
|
1361
|
+
}
|
|
1362
|
+
}
|
|
1363
|
+
if (type !== undefined) {
|
|
1364
|
+
setDeferredAttr(vm, 'type', type.value, type.namespace, type.trusting);
|
|
1365
|
+
}
|
|
1366
|
+
return this.modifiers;
|
|
1367
|
+
}
|
|
1368
|
+
}
|
|
1369
|
+
function mergeClasses(classes) {
|
|
1370
|
+
if (classes.length === 0) {
|
|
1371
|
+
return '';
|
|
1372
|
+
}
|
|
1373
|
+
if (classes.length === 1) {
|
|
1374
|
+
return unwrap(classes[0]);
|
|
1375
|
+
}
|
|
1376
|
+
if (allStringClasses(classes)) {
|
|
1377
|
+
return classes.join(' ');
|
|
1378
|
+
}
|
|
1379
|
+
return createClassListRef(classes);
|
|
1380
|
+
}
|
|
1381
|
+
function allStringClasses(classes) {
|
|
1382
|
+
return classes.every(c => typeof c === 'string');
|
|
1383
|
+
}
|
|
1384
|
+
function setDeferredAttr(vm, name, value, namespace, trusting = false) {
|
|
1385
|
+
if (typeof value === 'string') {
|
|
1386
|
+
vm.tree().setStaticAttribute(name, value, namespace);
|
|
1387
|
+
} else {
|
|
1388
|
+
let attribute = vm.tree().setDynamicAttribute(name, valueForRef(value), trusting, namespace);
|
|
1389
|
+
if (!isConstRef(value)) {
|
|
1390
|
+
vm.updateWith(new UpdateDynamicAttributeOpcode(value, attribute, vm.env));
|
|
1391
|
+
}
|
|
1392
|
+
}
|
|
1393
|
+
}
|
|
1394
|
+
APPEND_OPCODES.add(VM_DID_CREATE_ELEMENT_OP, (vm, {
|
|
1395
|
+
op1: register
|
|
1396
|
+
}) => {
|
|
1397
|
+
let {
|
|
1398
|
+
definition,
|
|
1399
|
+
state
|
|
1400
|
+
} = check(vm.fetchValue(check(register, CheckRegister)));
|
|
1401
|
+
let {
|
|
1402
|
+
manager
|
|
1403
|
+
} = definition;
|
|
1404
|
+
let operations = check(vm.fetchValue($t0));
|
|
1405
|
+
manager.didCreateElement(state, expect(vm.tree().constructing), operations);
|
|
1406
|
+
});
|
|
1407
|
+
APPEND_OPCODES.add(VM_GET_COMPONENT_SELF_OP, (vm, {
|
|
1408
|
+
op1: register,
|
|
1409
|
+
op2: _names
|
|
1410
|
+
}) => {
|
|
1411
|
+
let instance = check(vm.fetchValue(check(register, CheckRegister)));
|
|
1412
|
+
let {
|
|
1413
|
+
definition,
|
|
1414
|
+
state
|
|
1415
|
+
} = instance;
|
|
1416
|
+
let {
|
|
1417
|
+
manager
|
|
1418
|
+
} = definition;
|
|
1419
|
+
let selfRef = manager.getSelf(state);
|
|
1420
|
+
if (vm.env.debugRenderTree !== undefined) {
|
|
1421
|
+
let instance = check(vm.fetchValue(check(register, CheckRegister)));
|
|
1422
|
+
let {
|
|
1423
|
+
definition,
|
|
1424
|
+
manager
|
|
1425
|
+
} = instance;
|
|
1426
|
+
let args;
|
|
1427
|
+
if (vm.stack.peek() === vm.args) {
|
|
1428
|
+
args = vm.args.capture();
|
|
1429
|
+
} else {
|
|
1430
|
+
let names = vm.constants.getArray(_names);
|
|
1431
|
+
vm.args.setup(vm.stack, names, [], 0, true);
|
|
1432
|
+
args = vm.args.capture();
|
|
1433
|
+
}
|
|
1434
|
+
let moduleName;
|
|
1435
|
+
let compilable = definition.compilable;
|
|
1436
|
+
if (compilable === null) {
|
|
1437
|
+
assert(managerHasCapability(manager, instance.capabilities, InternalComponentCapabilities.dynamicLayout));
|
|
1438
|
+
let resolver = vm.context.resolver;
|
|
1439
|
+
compilable = resolver === null ? null : manager.getDynamicLayout(state, resolver);
|
|
1440
|
+
if (compilable !== null) {
|
|
1441
|
+
moduleName = compilable.moduleName;
|
|
1442
|
+
} else {
|
|
1443
|
+
moduleName = '__default__.hbs';
|
|
1444
|
+
}
|
|
1445
|
+
} else {
|
|
1446
|
+
moduleName = compilable.moduleName;
|
|
1447
|
+
}
|
|
1448
|
+
|
|
1449
|
+
// For tearing down the debugRenderTree
|
|
1450
|
+
vm.associateDestroyable(instance);
|
|
1451
|
+
if (hasCustomDebugRenderTreeLifecycle(manager)) {
|
|
1452
|
+
let nodes = manager.getDebugCustomRenderTree(instance.definition.state, instance.state, args, moduleName);
|
|
1453
|
+
nodes.forEach(node => {
|
|
1454
|
+
let {
|
|
1455
|
+
bucket
|
|
1456
|
+
} = node;
|
|
1457
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- @fixme
|
|
1458
|
+
vm.env.debugRenderTree.create(bucket, node);
|
|
1459
|
+
registerDestructor(instance, () => {
|
|
1460
|
+
vm.env.debugRenderTree?.willDestroy(bucket);
|
|
1461
|
+
});
|
|
1462
|
+
vm.updateWith(new DebugRenderTreeUpdateOpcode(bucket));
|
|
1463
|
+
});
|
|
1464
|
+
} else {
|
|
1465
|
+
let name = getDebugName(definition, manager);
|
|
1466
|
+
vm.env.debugRenderTree.create(instance, {
|
|
1467
|
+
type: 'component',
|
|
1468
|
+
name,
|
|
1469
|
+
args,
|
|
1470
|
+
template: moduleName,
|
|
1471
|
+
instance: valueForRef(selfRef)
|
|
1472
|
+
});
|
|
1473
|
+
registerDestructor(instance, () => {
|
|
1474
|
+
vm.env.debugRenderTree?.willDestroy(instance);
|
|
1475
|
+
});
|
|
1476
|
+
vm.updateWith(new DebugRenderTreeUpdateOpcode(instance));
|
|
1477
|
+
}
|
|
1478
|
+
}
|
|
1479
|
+
vm.stack.push(selfRef);
|
|
1480
|
+
});
|
|
1481
|
+
APPEND_OPCODES.add(VM_GET_COMPONENT_TAG_NAME_OP, (vm, {
|
|
1482
|
+
op1: register
|
|
1483
|
+
}) => {
|
|
1484
|
+
let {
|
|
1485
|
+
definition,
|
|
1486
|
+
state
|
|
1487
|
+
} = check(vm.fetchValue(check(register, CheckRegister)));
|
|
1488
|
+
let {
|
|
1489
|
+
manager
|
|
1490
|
+
} = definition;
|
|
1491
|
+
let tagName = manager.getTagName(state);
|
|
1492
|
+
|
|
1493
|
+
// User provided value from JS, so we don't bother to encode
|
|
1494
|
+
vm.stack.push(tagName);
|
|
1495
|
+
});
|
|
1496
|
+
|
|
1497
|
+
// Dynamic Invocation Only
|
|
1498
|
+
APPEND_OPCODES.add(VM_GET_COMPONENT_LAYOUT_OP, (vm, {
|
|
1499
|
+
op1: register
|
|
1500
|
+
}) => {
|
|
1501
|
+
let instance = check(vm.fetchValue(check(register, CheckRegister)));
|
|
1502
|
+
let {
|
|
1503
|
+
manager,
|
|
1504
|
+
definition
|
|
1505
|
+
} = instance;
|
|
1506
|
+
let {
|
|
1507
|
+
stack
|
|
1508
|
+
} = vm;
|
|
1509
|
+
let {
|
|
1510
|
+
compilable
|
|
1511
|
+
} = definition;
|
|
1512
|
+
if (compilable === null) {
|
|
1513
|
+
let {
|
|
1514
|
+
capabilities
|
|
1515
|
+
} = instance;
|
|
1516
|
+
assert(managerHasCapability(manager, capabilities, InternalComponentCapabilities.dynamicLayout));
|
|
1517
|
+
let resolver = vm.context.resolver;
|
|
1518
|
+
compilable = resolver === null ? null : manager.getDynamicLayout(instance.state, resolver);
|
|
1519
|
+
if (compilable === null) {
|
|
1520
|
+
if (managerHasCapability(manager, capabilities, InternalComponentCapabilities.wrapped)) {
|
|
1521
|
+
compilable = unwrapTemplate(vm.constants.defaultTemplate).asWrappedLayout();
|
|
1522
|
+
} else {
|
|
1523
|
+
compilable = unwrapTemplate(vm.constants.defaultTemplate).asLayout();
|
|
1524
|
+
}
|
|
1525
|
+
}
|
|
1526
|
+
}
|
|
1527
|
+
let handle = compilable.compile(vm.context);
|
|
1528
|
+
stack.push(compilable.symbolTable);
|
|
1529
|
+
stack.push(handle);
|
|
1530
|
+
});
|
|
1531
|
+
APPEND_OPCODES.add(VM_MAIN_OP, (vm, {
|
|
1532
|
+
op1: register
|
|
1533
|
+
}) => {
|
|
1534
|
+
let definition = check(vm.stack.pop());
|
|
1535
|
+
let invocation = check(vm.stack.pop());
|
|
1536
|
+
let {
|
|
1537
|
+
manager,
|
|
1538
|
+
capabilities
|
|
1539
|
+
} = definition;
|
|
1540
|
+
let state = {
|
|
1541
|
+
definition,
|
|
1542
|
+
manager,
|
|
1543
|
+
capabilities,
|
|
1544
|
+
state: null,
|
|
1545
|
+
handle: invocation.handle,
|
|
1546
|
+
table: invocation.symbolTable,
|
|
1547
|
+
lookup: null
|
|
1548
|
+
};
|
|
1549
|
+
vm.loadValue(check(register), state);
|
|
1550
|
+
});
|
|
1551
|
+
APPEND_OPCODES.add(VM_POPULATE_LAYOUT_OP, (vm, {
|
|
1552
|
+
op1: register
|
|
1553
|
+
}) => {
|
|
1554
|
+
let {
|
|
1555
|
+
stack
|
|
1556
|
+
} = vm;
|
|
1557
|
+
|
|
1558
|
+
// In import.meta.env.DEV handles could be ErrHandle objects
|
|
1559
|
+
let handle = check(stack.pop());
|
|
1560
|
+
let table = check(stack.pop());
|
|
1561
|
+
let state = check(vm.fetchValue(check(register, CheckRegister)));
|
|
1562
|
+
state.handle = handle;
|
|
1563
|
+
state.table = table;
|
|
1564
|
+
});
|
|
1565
|
+
APPEND_OPCODES.add(VM_VIRTUAL_ROOT_SCOPE_OP, (vm, {
|
|
1566
|
+
op1: register
|
|
1567
|
+
}) => {
|
|
1568
|
+
let {
|
|
1569
|
+
table,
|
|
1570
|
+
manager,
|
|
1571
|
+
capabilities,
|
|
1572
|
+
state
|
|
1573
|
+
} = check(vm.fetchValue(check(register, CheckRegister)));
|
|
1574
|
+
let owner;
|
|
1575
|
+
if (managerHasCapability(manager, capabilities, InternalComponentCapabilities.hasSubOwner)) {
|
|
1576
|
+
owner = manager.getOwner(state);
|
|
1577
|
+
vm.loadValue($t1, null); // Clear the temp register
|
|
1578
|
+
} else {
|
|
1579
|
+
// Check the temp register to see if an owner was resolved from currying
|
|
1580
|
+
owner = vm.fetchValue($t1);
|
|
1581
|
+
if (owner === null) {
|
|
1582
|
+
// If an owner wasn't found, default to using the current owner. This
|
|
1583
|
+
// will happen for normal dynamic component invocation,
|
|
1584
|
+
// e.g. <SomeClassicEmberComponent/>
|
|
1585
|
+
owner = vm.getOwner();
|
|
1586
|
+
} else {
|
|
1587
|
+
// Else the owner was found, so clear the temp register. This will happen
|
|
1588
|
+
// if we are loading a curried component, e.g. <@someCurriedComponent/>
|
|
1589
|
+
vm.loadValue($t1, null);
|
|
1590
|
+
}
|
|
1591
|
+
}
|
|
1592
|
+
vm.pushRootScope(table.symbols.length + 1, owner);
|
|
1593
|
+
});
|
|
1594
|
+
APPEND_OPCODES.add(VM_SET_NAMED_VARIABLES_OP, (vm, {
|
|
1595
|
+
op1: register
|
|
1596
|
+
}) => {
|
|
1597
|
+
let state = check(vm.fetchValue(check(register, CheckRegister)));
|
|
1598
|
+
let scope = vm.scope();
|
|
1599
|
+
let args = check(vm.stack.peek());
|
|
1600
|
+
let callerNames = args.named.atNames;
|
|
1601
|
+
for (let i = callerNames.length - 1; i >= 0; i--) {
|
|
1602
|
+
let atName = unwrap(callerNames[i]);
|
|
1603
|
+
let symbol = state.table.symbols.indexOf(atName);
|
|
1604
|
+
let value = args.named.get(atName, true);
|
|
1605
|
+
if (symbol !== -1) scope.bindSymbol(symbol + 1, value);
|
|
1606
|
+
if (state.lookup) state.lookup[atName] = value;
|
|
1607
|
+
}
|
|
1608
|
+
});
|
|
1609
|
+
function bindBlock(symbolName, blockName, state, blocks, vm) {
|
|
1610
|
+
let symbol = state.table.symbols.indexOf(symbolName);
|
|
1611
|
+
let block = blocks.get(blockName);
|
|
1612
|
+
if (symbol !== -1) vm.scope().bindBlock(symbol + 1, block);
|
|
1613
|
+
if (state.lookup) state.lookup[symbolName] = block;
|
|
1614
|
+
}
|
|
1615
|
+
APPEND_OPCODES.add(VM_SET_BLOCKS_OP, (vm, {
|
|
1616
|
+
op1: register
|
|
1617
|
+
}) => {
|
|
1618
|
+
let state = check(vm.fetchValue(check(register, CheckRegister)));
|
|
1619
|
+
let {
|
|
1620
|
+
blocks
|
|
1621
|
+
} = check(vm.stack.peek());
|
|
1622
|
+
for (const [i] of enumerate(blocks.names)) {
|
|
1623
|
+
bindBlock(unwrap(blocks.symbolNames[i]), unwrap(blocks.names[i]), state, blocks, vm);
|
|
1624
|
+
}
|
|
1625
|
+
});
|
|
1626
|
+
|
|
1627
|
+
// Dynamic Invocation Only
|
|
1628
|
+
APPEND_OPCODES.add(VM_INVOKE_COMPONENT_LAYOUT_OP, (vm, {
|
|
1629
|
+
op1: register
|
|
1630
|
+
}) => {
|
|
1631
|
+
let state = check(vm.fetchValue(check(register, CheckRegister)));
|
|
1632
|
+
vm.call(state.handle);
|
|
1633
|
+
});
|
|
1634
|
+
APPEND_OPCODES.add(VM_DID_RENDER_LAYOUT_OP, (vm, {
|
|
1635
|
+
op1: register
|
|
1636
|
+
}) => {
|
|
1637
|
+
let instance = check(vm.fetchValue(check(register, CheckRegister)));
|
|
1638
|
+
let {
|
|
1639
|
+
manager,
|
|
1640
|
+
state,
|
|
1641
|
+
capabilities
|
|
1642
|
+
} = instance;
|
|
1643
|
+
let bounds = vm.tree().popBlock();
|
|
1644
|
+
if (vm.env.debugRenderTree !== undefined) {
|
|
1645
|
+
if (hasCustomDebugRenderTreeLifecycle(manager)) {
|
|
1646
|
+
let nodes = manager.getDebugCustomRenderTree(instance.definition.state, state, EMPTY_ARGS);
|
|
1647
|
+
nodes.reverse().forEach(node => {
|
|
1648
|
+
let {
|
|
1649
|
+
bucket
|
|
1650
|
+
} = node;
|
|
1651
|
+
|
|
1652
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- @fixme
|
|
1653
|
+
vm.env.debugRenderTree.didRender(bucket, bounds);
|
|
1654
|
+
vm.updateWith(new DebugRenderTreeDidRenderOpcode(bucket, bounds));
|
|
1655
|
+
});
|
|
1656
|
+
} else {
|
|
1657
|
+
vm.env.debugRenderTree.didRender(instance, bounds);
|
|
1658
|
+
vm.updateWith(new DebugRenderTreeDidRenderOpcode(instance, bounds));
|
|
1659
|
+
}
|
|
1660
|
+
}
|
|
1661
|
+
if (managerHasCapability(manager, capabilities, InternalComponentCapabilities.createInstance)) {
|
|
1662
|
+
let mgr = check(manager);
|
|
1663
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-call -- @fixme
|
|
1664
|
+
mgr.didRenderLayout(state, bounds);
|
|
1665
|
+
vm.env.didCreate(instance);
|
|
1666
|
+
vm.updateWith(new DidUpdateLayoutOpcode(instance, bounds));
|
|
1667
|
+
}
|
|
1668
|
+
});
|
|
1669
|
+
APPEND_OPCODES.add(VM_COMMIT_COMPONENT_TRANSACTION_OP, vm => {
|
|
1670
|
+
vm.commitCacheGroup();
|
|
1671
|
+
});
|
|
1672
|
+
class UpdateComponentOpcode {
|
|
1673
|
+
constructor(component, manager, dynamicScope) {
|
|
1674
|
+
this.component = component;
|
|
1675
|
+
this.manager = manager;
|
|
1676
|
+
this.dynamicScope = dynamicScope;
|
|
1677
|
+
}
|
|
1678
|
+
evaluate(_vm) {
|
|
1679
|
+
let {
|
|
1680
|
+
component,
|
|
1681
|
+
manager,
|
|
1682
|
+
dynamicScope
|
|
1683
|
+
} = this;
|
|
1684
|
+
manager.update(component, dynamicScope);
|
|
1685
|
+
}
|
|
1686
|
+
}
|
|
1687
|
+
class DidUpdateLayoutOpcode {
|
|
1688
|
+
constructor(component, bounds) {
|
|
1689
|
+
this.component = component;
|
|
1690
|
+
this.bounds = bounds;
|
|
1691
|
+
}
|
|
1692
|
+
evaluate(vm) {
|
|
1693
|
+
let {
|
|
1694
|
+
component,
|
|
1695
|
+
bounds
|
|
1696
|
+
} = this;
|
|
1697
|
+
let {
|
|
1698
|
+
manager,
|
|
1699
|
+
state
|
|
1700
|
+
} = component;
|
|
1701
|
+
manager.didUpdateLayout(state, bounds);
|
|
1702
|
+
vm.env.didUpdate(component);
|
|
1703
|
+
}
|
|
1704
|
+
}
|
|
1705
|
+
class DebugRenderTreeUpdateOpcode {
|
|
1706
|
+
constructor(bucket) {
|
|
1707
|
+
this.bucket = bucket;
|
|
1708
|
+
}
|
|
1709
|
+
evaluate(vm) {
|
|
1710
|
+
vm.env.debugRenderTree?.update(this.bucket);
|
|
1711
|
+
}
|
|
1712
|
+
}
|
|
1713
|
+
class DebugRenderTreeDidRenderOpcode {
|
|
1714
|
+
constructor(bucket, bounds) {
|
|
1715
|
+
this.bucket = bucket;
|
|
1716
|
+
this.bounds = bounds;
|
|
1717
|
+
}
|
|
1718
|
+
evaluate(vm) {
|
|
1719
|
+
vm.env.debugRenderTree?.didRender(this.bucket, this.bounds);
|
|
1720
|
+
}
|
|
1721
|
+
}
|
|
1722
|
+
|
|
1723
|
+
class ReferenceChecker {
|
|
1724
|
+
validate(value) {
|
|
1725
|
+
return typeof value === 'object' && value !== null && REFERENCE in value;
|
|
1726
|
+
}
|
|
1727
|
+
expected() {
|
|
1728
|
+
return `Reference`;
|
|
1729
|
+
}
|
|
1730
|
+
}
|
|
1731
|
+
const CheckReference = new ReferenceChecker();
|
|
1732
|
+
|
|
1733
|
+
/*
|
|
1734
|
+
The calling convention is:
|
|
1735
|
+
|
|
1736
|
+
* 0-N block arguments at the bottom
|
|
1737
|
+
* 0-N positional arguments next (left-to-right)
|
|
1738
|
+
* 0-N named arguments next
|
|
1739
|
+
*/
|
|
1740
|
+
|
|
1741
|
+
class VMArgumentsImpl {
|
|
1742
|
+
stack = null;
|
|
1743
|
+
positional = new PositionalArgumentsImpl();
|
|
1744
|
+
named = new NamedArgumentsImpl();
|
|
1745
|
+
blocks = new BlockArgumentsImpl();
|
|
1746
|
+
constructor() {
|
|
1747
|
+
setLocalDebugType('args', this);
|
|
1748
|
+
}
|
|
1749
|
+
empty(stack) {
|
|
1750
|
+
let base = stack.registers[$sp] + 1;
|
|
1751
|
+
this.named.empty(stack, base);
|
|
1752
|
+
this.positional.empty(stack, base);
|
|
1753
|
+
this.blocks.empty(stack, base);
|
|
1754
|
+
return this;
|
|
1755
|
+
}
|
|
1756
|
+
setup(stack, names, blockNames, positionalCount, atNames) {
|
|
1757
|
+
this.stack = stack;
|
|
1758
|
+
|
|
1759
|
+
/*
|
|
1760
|
+
| ... | blocks | positional | named |
|
|
1761
|
+
| ... | b0 b1 | p0 p1 p2 p3 | n0 n1 |
|
|
1762
|
+
index | ... | 4/5/6 7/8/9 | 10 11 12 13 | 14 15 |
|
|
1763
|
+
^ ^ ^ ^
|
|
1764
|
+
bbase pbase nbase sp
|
|
1765
|
+
*/
|
|
1766
|
+
|
|
1767
|
+
let named = this.named;
|
|
1768
|
+
let namedCount = names.length;
|
|
1769
|
+
let namedBase = stack.registers[$sp] - namedCount + 1;
|
|
1770
|
+
named.setup(stack, namedBase, namedCount, names, atNames);
|
|
1771
|
+
let positional = this.positional;
|
|
1772
|
+
let positionalBase = namedBase - positionalCount;
|
|
1773
|
+
positional.setup(stack, positionalBase, positionalCount);
|
|
1774
|
+
let blocks = this.blocks;
|
|
1775
|
+
let blocksCount = blockNames.length;
|
|
1776
|
+
let blocksBase = positionalBase - blocksCount * 3;
|
|
1777
|
+
blocks.setup(stack, blocksBase, blocksCount, blockNames);
|
|
1778
|
+
}
|
|
1779
|
+
get base() {
|
|
1780
|
+
return this.blocks.base;
|
|
1781
|
+
}
|
|
1782
|
+
get length() {
|
|
1783
|
+
return this.positional.length + this.named.length + this.blocks.length * 3;
|
|
1784
|
+
}
|
|
1785
|
+
at(pos) {
|
|
1786
|
+
return this.positional.at(pos);
|
|
1787
|
+
}
|
|
1788
|
+
realloc(offset) {
|
|
1789
|
+
let {
|
|
1790
|
+
stack
|
|
1791
|
+
} = this;
|
|
1792
|
+
if (offset > 0 && stack !== null) {
|
|
1793
|
+
let {
|
|
1794
|
+
positional,
|
|
1795
|
+
named
|
|
1796
|
+
} = this;
|
|
1797
|
+
let newBase = positional.base + offset;
|
|
1798
|
+
let length = positional.length + named.length;
|
|
1799
|
+
for (let i = length - 1; i >= 0; i--) {
|
|
1800
|
+
stack.copy(i + positional.base, i + newBase);
|
|
1801
|
+
}
|
|
1802
|
+
positional.base += offset;
|
|
1803
|
+
named.base += offset;
|
|
1804
|
+
stack.registers[$sp] += offset;
|
|
1805
|
+
}
|
|
1806
|
+
}
|
|
1807
|
+
capture() {
|
|
1808
|
+
let positional = this.positional.length === 0 ? EMPTY_POSITIONAL : this.positional.capture();
|
|
1809
|
+
let named = this.named.length === 0 ? EMPTY_NAMED : this.named.capture();
|
|
1810
|
+
return {
|
|
1811
|
+
named,
|
|
1812
|
+
positional
|
|
1813
|
+
};
|
|
1814
|
+
}
|
|
1815
|
+
clear() {
|
|
1816
|
+
let {
|
|
1817
|
+
stack,
|
|
1818
|
+
length
|
|
1819
|
+
} = this;
|
|
1820
|
+
if (length > 0 && stack !== null) stack.pop(length);
|
|
1821
|
+
}
|
|
1822
|
+
}
|
|
1823
|
+
const EMPTY_REFERENCES = emptyArray();
|
|
1824
|
+
class PositionalArgumentsImpl {
|
|
1825
|
+
base = 0;
|
|
1826
|
+
length = 0;
|
|
1827
|
+
stack = null;
|
|
1828
|
+
_references = null;
|
|
1829
|
+
constructor() {
|
|
1830
|
+
setLocalDebugType('args:positional', this);
|
|
1831
|
+
}
|
|
1832
|
+
empty(stack, base) {
|
|
1833
|
+
this.stack = stack;
|
|
1834
|
+
this.base = base;
|
|
1835
|
+
this.length = 0;
|
|
1836
|
+
this._references = EMPTY_REFERENCES;
|
|
1837
|
+
}
|
|
1838
|
+
setup(stack, base, length) {
|
|
1839
|
+
this.stack = stack;
|
|
1840
|
+
this.base = base;
|
|
1841
|
+
this.length = length;
|
|
1842
|
+
if (length === 0) {
|
|
1843
|
+
this._references = EMPTY_REFERENCES;
|
|
1844
|
+
} else {
|
|
1845
|
+
this._references = null;
|
|
1846
|
+
}
|
|
1847
|
+
}
|
|
1848
|
+
at(position) {
|
|
1849
|
+
let {
|
|
1850
|
+
base,
|
|
1851
|
+
length,
|
|
1852
|
+
stack
|
|
1853
|
+
} = this;
|
|
1854
|
+
if (position < 0 || position >= length) {
|
|
1855
|
+
return UNDEFINED_REFERENCE;
|
|
1856
|
+
}
|
|
1857
|
+
|
|
1858
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- @fixme
|
|
1859
|
+
return check(stack.get(position, base));
|
|
1860
|
+
}
|
|
1861
|
+
capture() {
|
|
1862
|
+
return this.references;
|
|
1863
|
+
}
|
|
1864
|
+
prepend(other) {
|
|
1865
|
+
let additions = other.length;
|
|
1866
|
+
if (additions > 0) {
|
|
1867
|
+
let {
|
|
1868
|
+
base,
|
|
1869
|
+
length,
|
|
1870
|
+
stack
|
|
1871
|
+
} = this;
|
|
1872
|
+
this.base = base = base - additions;
|
|
1873
|
+
this.length = length + additions;
|
|
1874
|
+
for (let i = 0; i < additions; i++) {
|
|
1875
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- @fixme
|
|
1876
|
+
stack.set(other[i], i, base);
|
|
1877
|
+
}
|
|
1878
|
+
this._references = null;
|
|
1879
|
+
}
|
|
1880
|
+
}
|
|
1881
|
+
get references() {
|
|
1882
|
+
let references = this._references;
|
|
1883
|
+
if (!references) {
|
|
1884
|
+
let {
|
|
1885
|
+
stack,
|
|
1886
|
+
base,
|
|
1887
|
+
length
|
|
1888
|
+
} = this;
|
|
1889
|
+
|
|
1890
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- @fixme
|
|
1891
|
+
references = this._references = stack.slice(base, base + length);
|
|
1892
|
+
}
|
|
1893
|
+
return references;
|
|
1894
|
+
}
|
|
1895
|
+
}
|
|
1896
|
+
class NamedArgumentsImpl {
|
|
1897
|
+
base = 0;
|
|
1898
|
+
length = 0;
|
|
1899
|
+
_references = null;
|
|
1900
|
+
_names = EMPTY_STRING_ARRAY;
|
|
1901
|
+
_atNames = EMPTY_STRING_ARRAY;
|
|
1902
|
+
constructor() {
|
|
1903
|
+
setLocalDebugType('args:named', this);
|
|
1904
|
+
}
|
|
1905
|
+
empty(stack, base) {
|
|
1906
|
+
this.stack = stack;
|
|
1907
|
+
this.base = base;
|
|
1908
|
+
this.length = 0;
|
|
1909
|
+
this._references = EMPTY_REFERENCES;
|
|
1910
|
+
this._names = EMPTY_STRING_ARRAY;
|
|
1911
|
+
this._atNames = EMPTY_STRING_ARRAY;
|
|
1912
|
+
}
|
|
1913
|
+
setup(stack, base, length, names, atNames) {
|
|
1914
|
+
this.stack = stack;
|
|
1915
|
+
this.base = base;
|
|
1916
|
+
this.length = length;
|
|
1917
|
+
if (length === 0) {
|
|
1918
|
+
this._references = EMPTY_REFERENCES;
|
|
1919
|
+
this._names = EMPTY_STRING_ARRAY;
|
|
1920
|
+
this._atNames = EMPTY_STRING_ARRAY;
|
|
1921
|
+
} else {
|
|
1922
|
+
this._references = null;
|
|
1923
|
+
if (atNames) {
|
|
1924
|
+
this._names = null;
|
|
1925
|
+
this._atNames = names;
|
|
1926
|
+
} else {
|
|
1927
|
+
this._names = names;
|
|
1928
|
+
this._atNames = null;
|
|
1929
|
+
}
|
|
1930
|
+
}
|
|
1931
|
+
}
|
|
1932
|
+
get names() {
|
|
1933
|
+
let names = this._names;
|
|
1934
|
+
if (!names) {
|
|
1935
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- @fixme
|
|
1936
|
+
names = this._names = this._atNames.map(this.toSyntheticName);
|
|
1937
|
+
}
|
|
1938
|
+
return names;
|
|
1939
|
+
}
|
|
1940
|
+
get atNames() {
|
|
1941
|
+
let atNames = this._atNames;
|
|
1942
|
+
if (!atNames) {
|
|
1943
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- @fixme
|
|
1944
|
+
atNames = this._atNames = this._names.map(this.toAtName);
|
|
1945
|
+
}
|
|
1946
|
+
return atNames;
|
|
1947
|
+
}
|
|
1948
|
+
has(name) {
|
|
1949
|
+
return this.names.indexOf(name) !== -1;
|
|
1950
|
+
}
|
|
1951
|
+
get(name, atNames = false) {
|
|
1952
|
+
let {
|
|
1953
|
+
base,
|
|
1954
|
+
stack
|
|
1955
|
+
} = this;
|
|
1956
|
+
let names = atNames ? this.atNames : this.names;
|
|
1957
|
+
let idx = names.indexOf(name);
|
|
1958
|
+
if (idx === -1) {
|
|
1959
|
+
return UNDEFINED_REFERENCE;
|
|
1960
|
+
}
|
|
1961
|
+
let ref = stack.get(idx, base);
|
|
1962
|
+
{
|
|
1963
|
+
return ref;
|
|
1964
|
+
}
|
|
1965
|
+
}
|
|
1966
|
+
capture() {
|
|
1967
|
+
let {
|
|
1968
|
+
names,
|
|
1969
|
+
references
|
|
1970
|
+
} = this;
|
|
1971
|
+
let map = dict();
|
|
1972
|
+
for (const [i, name] of enumerate(names)) {
|
|
1973
|
+
{
|
|
1974
|
+
map[name] = unwrap(references[i]);
|
|
1975
|
+
}
|
|
1976
|
+
}
|
|
1977
|
+
return map;
|
|
1978
|
+
}
|
|
1979
|
+
merge(other) {
|
|
1980
|
+
let keys = Object.keys(other);
|
|
1981
|
+
if (keys.length > 0) {
|
|
1982
|
+
let {
|
|
1983
|
+
names,
|
|
1984
|
+
length,
|
|
1985
|
+
stack
|
|
1986
|
+
} = this;
|
|
1987
|
+
let newNames = names.slice();
|
|
1988
|
+
for (const name of keys) {
|
|
1989
|
+
let idx = newNames.indexOf(name);
|
|
1990
|
+
if (idx === -1) {
|
|
1991
|
+
length = newNames.push(name);
|
|
1992
|
+
stack.push(other[name]);
|
|
1993
|
+
}
|
|
1994
|
+
}
|
|
1995
|
+
this.length = length;
|
|
1996
|
+
this._references = null;
|
|
1997
|
+
this._names = newNames;
|
|
1998
|
+
this._atNames = null;
|
|
1999
|
+
}
|
|
2000
|
+
}
|
|
2001
|
+
get references() {
|
|
2002
|
+
let references = this._references;
|
|
2003
|
+
if (!references) {
|
|
2004
|
+
let {
|
|
2005
|
+
base,
|
|
2006
|
+
length,
|
|
2007
|
+
stack
|
|
2008
|
+
} = this;
|
|
2009
|
+
references = this._references = stack.slice(base, base + length);
|
|
2010
|
+
}
|
|
2011
|
+
return references;
|
|
2012
|
+
}
|
|
2013
|
+
toSyntheticName(name) {
|
|
2014
|
+
return name.slice(1);
|
|
2015
|
+
}
|
|
2016
|
+
toAtName(name) {
|
|
2017
|
+
return `@${name}`;
|
|
2018
|
+
}
|
|
2019
|
+
}
|
|
2020
|
+
function toSymbolName(name) {
|
|
2021
|
+
return `&${name}`;
|
|
2022
|
+
}
|
|
2023
|
+
const EMPTY_BLOCK_VALUES = emptyArray();
|
|
2024
|
+
class BlockArgumentsImpl {
|
|
2025
|
+
internalValues = null;
|
|
2026
|
+
_symbolNames = null;
|
|
2027
|
+
internalTag = null;
|
|
2028
|
+
names = EMPTY_STRING_ARRAY;
|
|
2029
|
+
length = 0;
|
|
2030
|
+
base = 0;
|
|
2031
|
+
constructor() {
|
|
2032
|
+
setLocalDebugType('args:blocks', this);
|
|
2033
|
+
}
|
|
2034
|
+
empty(stack, base) {
|
|
2035
|
+
this.stack = stack;
|
|
2036
|
+
this.names = EMPTY_STRING_ARRAY;
|
|
2037
|
+
this.base = base;
|
|
2038
|
+
this.length = 0;
|
|
2039
|
+
this._symbolNames = null;
|
|
2040
|
+
this.internalTag = CONSTANT_TAG;
|
|
2041
|
+
this.internalValues = EMPTY_BLOCK_VALUES;
|
|
2042
|
+
}
|
|
2043
|
+
setup(stack, base, length, names) {
|
|
2044
|
+
this.stack = stack;
|
|
2045
|
+
this.names = names;
|
|
2046
|
+
this.base = base;
|
|
2047
|
+
this.length = length;
|
|
2048
|
+
this._symbolNames = null;
|
|
2049
|
+
if (length === 0) {
|
|
2050
|
+
this.internalTag = CONSTANT_TAG;
|
|
2051
|
+
this.internalValues = EMPTY_BLOCK_VALUES;
|
|
2052
|
+
} else {
|
|
2053
|
+
this.internalTag = null;
|
|
2054
|
+
this.internalValues = null;
|
|
2055
|
+
}
|
|
2056
|
+
}
|
|
2057
|
+
get values() {
|
|
2058
|
+
let values = this.internalValues;
|
|
2059
|
+
if (!values) {
|
|
2060
|
+
let {
|
|
2061
|
+
base,
|
|
2062
|
+
length,
|
|
2063
|
+
stack
|
|
2064
|
+
} = this;
|
|
2065
|
+
values = this.internalValues = stack.slice(base, base + length * 3);
|
|
2066
|
+
}
|
|
2067
|
+
return values;
|
|
2068
|
+
}
|
|
2069
|
+
has(name) {
|
|
2070
|
+
return this.names.indexOf(name) !== -1;
|
|
2071
|
+
}
|
|
2072
|
+
get(name) {
|
|
2073
|
+
let idx = this.names.indexOf(name);
|
|
2074
|
+
if (idx === -1) {
|
|
2075
|
+
return null;
|
|
2076
|
+
}
|
|
2077
|
+
let {
|
|
2078
|
+
base,
|
|
2079
|
+
stack
|
|
2080
|
+
} = this;
|
|
2081
|
+
let table = check(stack.get(idx * 3, base));
|
|
2082
|
+
let scope = check(stack.get(idx * 3 + 1, base));
|
|
2083
|
+
let handle = check(stack.get(idx * 3 + 2, base));
|
|
2084
|
+
return handle === null ? null : [handle, scope, table];
|
|
2085
|
+
}
|
|
2086
|
+
capture() {
|
|
2087
|
+
return new CapturedBlockArgumentsImpl(this.names, this.values);
|
|
2088
|
+
}
|
|
2089
|
+
get symbolNames() {
|
|
2090
|
+
let symbolNames = this._symbolNames;
|
|
2091
|
+
if (symbolNames === null) {
|
|
2092
|
+
symbolNames = this._symbolNames = this.names.map(toSymbolName);
|
|
2093
|
+
}
|
|
2094
|
+
return symbolNames;
|
|
2095
|
+
}
|
|
2096
|
+
}
|
|
2097
|
+
class CapturedBlockArgumentsImpl {
|
|
2098
|
+
length;
|
|
2099
|
+
constructor(names, values) {
|
|
2100
|
+
this.names = names;
|
|
2101
|
+
this.values = values;
|
|
2102
|
+
this.length = names.length;
|
|
2103
|
+
}
|
|
2104
|
+
has(name) {
|
|
2105
|
+
return this.names.indexOf(name) !== -1;
|
|
2106
|
+
}
|
|
2107
|
+
get(name) {
|
|
2108
|
+
let idx = this.names.indexOf(name);
|
|
2109
|
+
if (idx === -1) return null;
|
|
2110
|
+
return [this.values[idx * 3 + 2], this.values[idx * 3 + 1], this.values[idx * 3]];
|
|
2111
|
+
}
|
|
2112
|
+
}
|
|
2113
|
+
function createCapturedArgs(named, positional) {
|
|
2114
|
+
return {
|
|
2115
|
+
named,
|
|
2116
|
+
positional
|
|
2117
|
+
};
|
|
2118
|
+
}
|
|
2119
|
+
function reifyNamed(named) {
|
|
2120
|
+
let reified = dict();
|
|
2121
|
+
for (const [key, value] of Object.entries(named)) {
|
|
2122
|
+
reified[key] = valueForRef(value);
|
|
2123
|
+
}
|
|
2124
|
+
return reified;
|
|
2125
|
+
}
|
|
2126
|
+
function reifyPositional(positional) {
|
|
2127
|
+
return positional.map(valueForRef);
|
|
2128
|
+
}
|
|
2129
|
+
function reifyArgs(args) {
|
|
2130
|
+
return {
|
|
2131
|
+
named: reifyNamed(args.named),
|
|
2132
|
+
positional: reifyPositional(args.positional)
|
|
2133
|
+
};
|
|
2134
|
+
}
|
|
2135
|
+
const ARGUMENT_ERROR = Symbol('ARGUMENT_ERROR');
|
|
2136
|
+
function isArgumentError(arg) {
|
|
2137
|
+
return arg !== null && typeof arg === 'object' && arg[ARGUMENT_ERROR];
|
|
2138
|
+
}
|
|
2139
|
+
|
|
2140
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
2141
|
+
function ArgumentErrorImpl(error) {
|
|
2142
|
+
return {
|
|
2143
|
+
[ARGUMENT_ERROR]: true,
|
|
2144
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
2145
|
+
error
|
|
2146
|
+
};
|
|
2147
|
+
}
|
|
2148
|
+
function reifyNamedDebug(named) {
|
|
2149
|
+
let reified = dict();
|
|
2150
|
+
for (const [key, value] of Object.entries(named)) {
|
|
2151
|
+
try {
|
|
2152
|
+
reified[key] = valueForRef(value);
|
|
2153
|
+
} catch (e) {
|
|
2154
|
+
reified[key] = ArgumentErrorImpl(e);
|
|
2155
|
+
}
|
|
2156
|
+
}
|
|
2157
|
+
return reified;
|
|
2158
|
+
}
|
|
2159
|
+
function reifyPositionalDebug(positional) {
|
|
2160
|
+
return positional.map(p => {
|
|
2161
|
+
try {
|
|
2162
|
+
return valueForRef(p);
|
|
2163
|
+
} catch (e) {
|
|
2164
|
+
return ArgumentErrorImpl(e);
|
|
2165
|
+
}
|
|
2166
|
+
});
|
|
2167
|
+
}
|
|
2168
|
+
function reifyArgsDebug(args) {
|
|
2169
|
+
let named = reifyNamedDebug(args.named);
|
|
2170
|
+
let positional = reifyPositionalDebug(args.positional);
|
|
2171
|
+
return {
|
|
2172
|
+
named,
|
|
2173
|
+
positional
|
|
2174
|
+
};
|
|
2175
|
+
}
|
|
2176
|
+
const EMPTY_NAMED = Object.freeze(Object.create(null));
|
|
2177
|
+
const EMPTY_POSITIONAL = EMPTY_REFERENCES;
|
|
2178
|
+
const EMPTY_ARGS = createCapturedArgs(EMPTY_NAMED, EMPTY_POSITIONAL);
|
|
2179
|
+
|
|
2180
|
+
function createConcatRef(partsRefs) {
|
|
2181
|
+
return createComputeRef(() => {
|
|
2182
|
+
const parts = [];
|
|
2183
|
+
for (const ref of partsRefs) {
|
|
2184
|
+
const value = valueForRef(ref);
|
|
2185
|
+
if (value !== null && value !== undefined) {
|
|
2186
|
+
parts.push(castToString(value));
|
|
2187
|
+
}
|
|
2188
|
+
}
|
|
2189
|
+
if (parts.length > 0) {
|
|
2190
|
+
return parts.join('');
|
|
2191
|
+
}
|
|
2192
|
+
return null;
|
|
2193
|
+
});
|
|
2194
|
+
}
|
|
2195
|
+
function castToString(value) {
|
|
2196
|
+
if (typeof value === 'string') {
|
|
2197
|
+
return value;
|
|
2198
|
+
} else if (typeof value.toString !== 'function') {
|
|
2199
|
+
return '';
|
|
2200
|
+
}
|
|
2201
|
+
|
|
2202
|
+
// eslint-disable-next-line @typescript-eslint/no-base-to-string -- @fixme
|
|
2203
|
+
return String(value);
|
|
2204
|
+
}
|
|
2205
|
+
|
|
2206
|
+
APPEND_OPCODES.add(VM_CURRY_OP, (vm, {
|
|
2207
|
+
op1: type,
|
|
2208
|
+
op2: _isStrict
|
|
2209
|
+
}) => {
|
|
2210
|
+
let stack = vm.stack;
|
|
2211
|
+
let definition = check(stack.pop());
|
|
2212
|
+
let capturedArgs = check(stack.pop());
|
|
2213
|
+
let owner = vm.getOwner();
|
|
2214
|
+
vm.context.resolver;
|
|
2215
|
+
vm.loadValue($v0, createCurryRef(type, definition, owner, capturedArgs));
|
|
2216
|
+
});
|
|
2217
|
+
APPEND_OPCODES.add(VM_DYNAMIC_HELPER_OP, vm => {
|
|
2218
|
+
let stack = vm.stack;
|
|
2219
|
+
let ref = check(stack.pop());
|
|
2220
|
+
let args = check(stack.pop()).capture();
|
|
2221
|
+
let helperRef;
|
|
2222
|
+
let initialOwner = vm.getOwner();
|
|
2223
|
+
let helperInstanceRef = createComputeRef(() => {
|
|
2224
|
+
if (helperRef !== undefined) {
|
|
2225
|
+
destroy(helperRef);
|
|
2226
|
+
}
|
|
2227
|
+
let definition = valueForRef(ref);
|
|
2228
|
+
if (isCurriedType(definition, CURRIED_HELPER)) {
|
|
2229
|
+
let {
|
|
2230
|
+
definition: resolvedDef,
|
|
2231
|
+
owner,
|
|
2232
|
+
positional,
|
|
2233
|
+
named
|
|
2234
|
+
} = resolveCurriedValue(definition);
|
|
2235
|
+
let helper = resolveHelper(resolvedDef);
|
|
2236
|
+
if (named !== undefined) {
|
|
2237
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
2238
|
+
args.named = assign({}, ...named, args.named);
|
|
2239
|
+
}
|
|
2240
|
+
if (positional !== undefined) {
|
|
2241
|
+
args.positional = positional.concat(args.positional);
|
|
2242
|
+
}
|
|
2243
|
+
helperRef = helper(args, owner);
|
|
2244
|
+
associateDestroyableChild(helperInstanceRef, helperRef);
|
|
2245
|
+
} else if (isIndexable$1(definition)) {
|
|
2246
|
+
let helper = resolveHelper(definition);
|
|
2247
|
+
helperRef = helper(args, initialOwner);
|
|
2248
|
+
if (_hasDestroyableChildren(helperRef)) {
|
|
2249
|
+
associateDestroyableChild(helperInstanceRef, helperRef);
|
|
2250
|
+
}
|
|
2251
|
+
} else {
|
|
2252
|
+
helperRef = UNDEFINED_REFERENCE;
|
|
2253
|
+
}
|
|
2254
|
+
});
|
|
2255
|
+
let helperValueRef = createComputeRef(() => {
|
|
2256
|
+
valueForRef(helperInstanceRef);
|
|
2257
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- @fixme
|
|
2258
|
+
return valueForRef(helperRef);
|
|
2259
|
+
});
|
|
2260
|
+
vm.associateDestroyable(helperInstanceRef);
|
|
2261
|
+
vm.loadValue($v0, helperValueRef);
|
|
2262
|
+
});
|
|
2263
|
+
function resolveHelper(definition, ref) {
|
|
2264
|
+
let managerOrHelper = getInternalHelperManager(definition, true);
|
|
2265
|
+
let helper;
|
|
2266
|
+
if (managerOrHelper === null) {
|
|
2267
|
+
helper = null;
|
|
2268
|
+
} else {
|
|
2269
|
+
helper = typeof managerOrHelper === 'function' ? managerOrHelper : managerOrHelper.getHelper(definition);
|
|
2270
|
+
}
|
|
2271
|
+
return helper;
|
|
2272
|
+
}
|
|
2273
|
+
APPEND_OPCODES.add(VM_HELPER_OP, (vm, {
|
|
2274
|
+
op1: handle
|
|
2275
|
+
}) => {
|
|
2276
|
+
let stack = vm.stack;
|
|
2277
|
+
let helper = check(vm.constants.getValue(handle));
|
|
2278
|
+
let args = check(stack.pop());
|
|
2279
|
+
let value = helper(args.capture(), vm.getOwner(), vm.dynamicScope());
|
|
2280
|
+
if (_hasDestroyableChildren(value)) {
|
|
2281
|
+
vm.associateDestroyable(value);
|
|
2282
|
+
}
|
|
2283
|
+
vm.loadValue($v0, value);
|
|
2284
|
+
});
|
|
2285
|
+
APPEND_OPCODES.add(VM_GET_VARIABLE_OP, (vm, {
|
|
2286
|
+
op1: symbol
|
|
2287
|
+
}) => {
|
|
2288
|
+
let expr = vm.referenceForSymbol(symbol);
|
|
2289
|
+
vm.stack.push(expr);
|
|
2290
|
+
});
|
|
2291
|
+
APPEND_OPCODES.add(VM_SET_VARIABLE_OP, (vm, {
|
|
2292
|
+
op1: symbol
|
|
2293
|
+
}) => {
|
|
2294
|
+
let expr = check(vm.stack.pop());
|
|
2295
|
+
vm.scope().bindSymbol(symbol, expr);
|
|
2296
|
+
});
|
|
2297
|
+
APPEND_OPCODES.add(VM_SET_BLOCK_OP, (vm, {
|
|
2298
|
+
op1: symbol
|
|
2299
|
+
}) => {
|
|
2300
|
+
let handle = check(vm.stack.pop());
|
|
2301
|
+
let scope = check(vm.stack.pop());
|
|
2302
|
+
let table = check(vm.stack.pop());
|
|
2303
|
+
vm.scope().bindBlock(symbol, [handle, scope, table]);
|
|
2304
|
+
});
|
|
2305
|
+
APPEND_OPCODES.add(VM_ROOT_SCOPE_OP, (vm, {
|
|
2306
|
+
op1: size
|
|
2307
|
+
}) => {
|
|
2308
|
+
vm.pushRootScope(size, vm.getOwner());
|
|
2309
|
+
});
|
|
2310
|
+
APPEND_OPCODES.add(VM_GET_PROPERTY_OP, (vm, {
|
|
2311
|
+
op1: _key
|
|
2312
|
+
}) => {
|
|
2313
|
+
let key = vm.constants.getValue(_key);
|
|
2314
|
+
let expr = check(vm.stack.pop());
|
|
2315
|
+
vm.stack.push(childRefFor(expr, key));
|
|
2316
|
+
});
|
|
2317
|
+
APPEND_OPCODES.add(VM_GET_BLOCK_OP, (vm, {
|
|
2318
|
+
op1: _block
|
|
2319
|
+
}) => {
|
|
2320
|
+
let {
|
|
2321
|
+
stack
|
|
2322
|
+
} = vm;
|
|
2323
|
+
let block = vm.scope().getBlock(_block);
|
|
2324
|
+
stack.push(block);
|
|
2325
|
+
});
|
|
2326
|
+
APPEND_OPCODES.add(VM_SPREAD_BLOCK_OP, vm => {
|
|
2327
|
+
let {
|
|
2328
|
+
stack
|
|
2329
|
+
} = vm;
|
|
2330
|
+
let block = check(stack.pop());
|
|
2331
|
+
if (block && !isUndefinedReference(block)) {
|
|
2332
|
+
let [handleOrCompilable, scope, table] = block;
|
|
2333
|
+
stack.push(table);
|
|
2334
|
+
stack.push(scope);
|
|
2335
|
+
stack.push(handleOrCompilable);
|
|
2336
|
+
} else {
|
|
2337
|
+
stack.push(null);
|
|
2338
|
+
stack.push(null);
|
|
2339
|
+
stack.push(null);
|
|
2340
|
+
}
|
|
2341
|
+
});
|
|
2342
|
+
function isUndefinedReference(input) {
|
|
2343
|
+
return input === UNDEFINED_REFERENCE;
|
|
2344
|
+
}
|
|
2345
|
+
APPEND_OPCODES.add(VM_HAS_BLOCK_OP, vm => {
|
|
2346
|
+
let {
|
|
2347
|
+
stack
|
|
2348
|
+
} = vm;
|
|
2349
|
+
let block = check(stack.pop());
|
|
2350
|
+
if (block && !isUndefinedReference(block)) {
|
|
2351
|
+
stack.push(TRUE_REFERENCE);
|
|
2352
|
+
} else {
|
|
2353
|
+
stack.push(FALSE_REFERENCE);
|
|
2354
|
+
}
|
|
2355
|
+
});
|
|
2356
|
+
APPEND_OPCODES.add(VM_HAS_BLOCK_PARAMS_OP, vm => {
|
|
2357
|
+
// FIXME(mmun): should only need to push the symbol table
|
|
2358
|
+
vm.stack.pop();
|
|
2359
|
+
vm.stack.pop();
|
|
2360
|
+
let table = check(vm.stack.pop());
|
|
2361
|
+
let hasBlockParams = table && table.parameters.length;
|
|
2362
|
+
vm.stack.push(hasBlockParams ? TRUE_REFERENCE : FALSE_REFERENCE);
|
|
2363
|
+
});
|
|
2364
|
+
APPEND_OPCODES.add(VM_CONCAT_OP, (vm, {
|
|
2365
|
+
op1: count
|
|
2366
|
+
}) => {
|
|
2367
|
+
let out = new Array(count);
|
|
2368
|
+
for (let i = count; i > 0; i--) {
|
|
2369
|
+
let offset = i - 1;
|
|
2370
|
+
out[offset] = check(vm.stack.pop());
|
|
2371
|
+
}
|
|
2372
|
+
vm.stack.push(createConcatRef(out));
|
|
2373
|
+
});
|
|
2374
|
+
APPEND_OPCODES.add(VM_IF_INLINE_OP, vm => {
|
|
2375
|
+
let condition = check(vm.stack.pop());
|
|
2376
|
+
let truthy = check(vm.stack.pop());
|
|
2377
|
+
let falsy = check(vm.stack.pop());
|
|
2378
|
+
vm.stack.push(createComputeRef(() => {
|
|
2379
|
+
if (toBool(valueForRef(condition))) {
|
|
2380
|
+
return valueForRef(truthy);
|
|
2381
|
+
} else {
|
|
2382
|
+
return valueForRef(falsy);
|
|
2383
|
+
}
|
|
2384
|
+
}));
|
|
2385
|
+
});
|
|
2386
|
+
APPEND_OPCODES.add(VM_NOT_OP, vm => {
|
|
2387
|
+
let ref = check(vm.stack.pop());
|
|
2388
|
+
vm.stack.push(createComputeRef(() => {
|
|
2389
|
+
return !toBool(valueForRef(ref));
|
|
2390
|
+
}));
|
|
2391
|
+
});
|
|
2392
|
+
APPEND_OPCODES.add(VM_GET_DYNAMIC_VAR_OP, vm => {
|
|
2393
|
+
let scope = vm.dynamicScope();
|
|
2394
|
+
let stack = vm.stack;
|
|
2395
|
+
let nameRef = check(stack.pop());
|
|
2396
|
+
stack.push(createComputeRef(() => {
|
|
2397
|
+
let name = String(valueForRef(nameRef));
|
|
2398
|
+
return valueForRef(scope.get(name));
|
|
2399
|
+
}));
|
|
2400
|
+
});
|
|
2401
|
+
APPEND_OPCODES.add(VM_LOG_OP, vm => {
|
|
2402
|
+
let {
|
|
2403
|
+
positional
|
|
2404
|
+
} = check(vm.stack.pop()).capture();
|
|
2405
|
+
vm.loadValue($v0, createComputeRef(() => {
|
|
2406
|
+
// eslint-disable-next-line no-console
|
|
2407
|
+
console.log(...reifyPositional(positional));
|
|
2408
|
+
}));
|
|
2409
|
+
});
|
|
2410
|
+
|
|
2411
|
+
class DynamicTextContent {
|
|
2412
|
+
constructor(node, reference, lastValue) {
|
|
2413
|
+
this.node = node;
|
|
2414
|
+
this.reference = reference;
|
|
2415
|
+
this.lastValue = lastValue;
|
|
2416
|
+
}
|
|
2417
|
+
evaluate() {
|
|
2418
|
+
let value = valueForRef(this.reference);
|
|
2419
|
+
let {
|
|
2420
|
+
lastValue
|
|
2421
|
+
} = this;
|
|
2422
|
+
if (value === lastValue) return;
|
|
2423
|
+
let normalized;
|
|
2424
|
+
if (isEmpty$1(value)) {
|
|
2425
|
+
normalized = '';
|
|
2426
|
+
} else if (isString(value)) {
|
|
2427
|
+
normalized = value;
|
|
2428
|
+
} else {
|
|
2429
|
+
normalized = String(value);
|
|
2430
|
+
}
|
|
2431
|
+
if (normalized !== lastValue) {
|
|
2432
|
+
let textNode = this.node;
|
|
2433
|
+
textNode.nodeValue = this.lastValue = normalized;
|
|
2434
|
+
}
|
|
2435
|
+
}
|
|
2436
|
+
}
|
|
2437
|
+
|
|
2438
|
+
function toContentType(value) {
|
|
2439
|
+
if (shouldCoerce(value)) {
|
|
2440
|
+
return ContentType.String;
|
|
2441
|
+
} else if (isCurriedType(value, CURRIED_COMPONENT) || hasInternalComponentManager(value)) {
|
|
2442
|
+
return ContentType.Component;
|
|
2443
|
+
} else if (isCurriedType(value, CURRIED_HELPER) || hasInternalHelperManager(value)) {
|
|
2444
|
+
return ContentType.Helper;
|
|
2445
|
+
} else if (isSafeString(value)) {
|
|
2446
|
+
return ContentType.SafeString;
|
|
2447
|
+
} else if (isFragment(value)) {
|
|
2448
|
+
return ContentType.Fragment;
|
|
2449
|
+
} else if (isNode(value)) {
|
|
2450
|
+
return ContentType.Node;
|
|
2451
|
+
} else {
|
|
2452
|
+
return ContentType.String;
|
|
2453
|
+
}
|
|
2454
|
+
}
|
|
2455
|
+
function toDynamicContentType(value) {
|
|
2456
|
+
if (!isIndexable$1(value)) {
|
|
2457
|
+
return ContentType.String;
|
|
2458
|
+
}
|
|
2459
|
+
if (isCurriedType(value, CURRIED_COMPONENT) || hasInternalComponentManager(value)) {
|
|
2460
|
+
return ContentType.Component;
|
|
2461
|
+
} else {
|
|
2462
|
+
return ContentType.Helper;
|
|
2463
|
+
}
|
|
2464
|
+
}
|
|
2465
|
+
APPEND_OPCODES.add(VM_CONTENT_TYPE_OP, vm => {
|
|
2466
|
+
let reference = check(vm.stack.peek());
|
|
2467
|
+
vm.stack.push(toContentType(valueForRef(reference)));
|
|
2468
|
+
if (!isConstRef(reference)) {
|
|
2469
|
+
vm.updateWith(new AssertFilter(reference, toContentType));
|
|
2470
|
+
}
|
|
2471
|
+
});
|
|
2472
|
+
APPEND_OPCODES.add(VM_DYNAMIC_CONTENT_TYPE_OP, vm => {
|
|
2473
|
+
let reference = check(vm.stack.peek());
|
|
2474
|
+
vm.stack.push(toDynamicContentType(valueForRef(reference)));
|
|
2475
|
+
if (!isConstRef(reference)) {
|
|
2476
|
+
vm.updateWith(new AssertFilter(reference, toDynamicContentType));
|
|
2477
|
+
}
|
|
2478
|
+
});
|
|
2479
|
+
APPEND_OPCODES.add(VM_APPEND_HTML_OP, vm => {
|
|
2480
|
+
let reference = check(vm.stack.pop());
|
|
2481
|
+
let rawValue = valueForRef(reference);
|
|
2482
|
+
let value = isEmpty$1(rawValue) ? '' : String(rawValue);
|
|
2483
|
+
vm.tree().appendDynamicHTML(value);
|
|
2484
|
+
});
|
|
2485
|
+
APPEND_OPCODES.add(VM_APPEND_SAFE_HTML_OP, vm => {
|
|
2486
|
+
let reference = check(vm.stack.pop());
|
|
2487
|
+
let rawValue = check(valueForRef(reference)).toHTML();
|
|
2488
|
+
let value = isEmpty$1(rawValue) ? '' : check(rawValue);
|
|
2489
|
+
vm.tree().appendDynamicHTML(value);
|
|
2490
|
+
});
|
|
2491
|
+
APPEND_OPCODES.add(VM_APPEND_TEXT_OP, vm => {
|
|
2492
|
+
let reference = check(vm.stack.pop());
|
|
2493
|
+
let rawValue = valueForRef(reference);
|
|
2494
|
+
let value = isEmpty$1(rawValue) ? '' : String(rawValue);
|
|
2495
|
+
let node = vm.tree().appendDynamicText(value);
|
|
2496
|
+
if (!isConstRef(reference)) {
|
|
2497
|
+
vm.updateWith(new DynamicTextContent(node, reference, value));
|
|
2498
|
+
}
|
|
2499
|
+
});
|
|
2500
|
+
APPEND_OPCODES.add(VM_APPEND_DOCUMENT_FRAGMENT_OP, vm => {
|
|
2501
|
+
let reference = check(vm.stack.pop());
|
|
2502
|
+
let value = check(valueForRef(reference));
|
|
2503
|
+
vm.tree().appendDynamicFragment(value);
|
|
2504
|
+
});
|
|
2505
|
+
APPEND_OPCODES.add(VM_APPEND_NODE_OP, vm => {
|
|
2506
|
+
let reference = check(vm.stack.pop());
|
|
2507
|
+
let value = check(valueForRef(reference));
|
|
2508
|
+
vm.tree().appendDynamicNode(value);
|
|
2509
|
+
});
|
|
2510
|
+
|
|
2511
|
+
// Allow the contents of `debugCallback` without extra annotations
|
|
2512
|
+
/* eslint-disable @typescript-eslint/no-unused-expressions */
|
|
2513
|
+
|
|
2514
|
+
function debugCallback(context, get) {
|
|
2515
|
+
// eslint-disable-next-line no-console
|
|
2516
|
+
console.info('Use `context`, and `get(<path>)` to debug this template.');
|
|
2517
|
+
|
|
2518
|
+
// for example...
|
|
2519
|
+
context === get('this');
|
|
2520
|
+
|
|
2521
|
+
// eslint-disable-next-line no-debugger
|
|
2522
|
+
debugger;
|
|
2523
|
+
}
|
|
2524
|
+
let callback = debugCallback;
|
|
2525
|
+
|
|
2526
|
+
// For testing purposes
|
|
2527
|
+
function setDebuggerCallback(cb) {
|
|
2528
|
+
callback = cb;
|
|
2529
|
+
}
|
|
2530
|
+
function resetDebuggerCallback() {
|
|
2531
|
+
callback = debugCallback;
|
|
2532
|
+
}
|
|
2533
|
+
class ScopeInspector {
|
|
2534
|
+
#symbols;
|
|
2535
|
+
constructor(scope, symbols) {
|
|
2536
|
+
this.scope = scope;
|
|
2537
|
+
this.#symbols = symbols;
|
|
2538
|
+
}
|
|
2539
|
+
get(path) {
|
|
2540
|
+
let {
|
|
2541
|
+
scope
|
|
2542
|
+
} = this;
|
|
2543
|
+
let symbols = this.#symbols;
|
|
2544
|
+
let parts = path.split('.');
|
|
2545
|
+
let [head, ...tail] = path.split('.');
|
|
2546
|
+
let ref;
|
|
2547
|
+
if (head === 'this') {
|
|
2548
|
+
ref = scope.getSelf();
|
|
2549
|
+
} else if (symbols.locals[head]) {
|
|
2550
|
+
ref = unwrap(scope.getSymbol(symbols.locals[head]));
|
|
2551
|
+
} else {
|
|
2552
|
+
ref = this.scope.getSelf();
|
|
2553
|
+
tail = parts;
|
|
2554
|
+
}
|
|
2555
|
+
return tail.reduce((r, part) => childRefFor(r, part), ref);
|
|
2556
|
+
}
|
|
2557
|
+
}
|
|
2558
|
+
APPEND_OPCODES.add(VM_DEBUGGER_OP, (vm, {
|
|
2559
|
+
op1: _debugInfo
|
|
2560
|
+
}) => {
|
|
2561
|
+
let debuggerInfo = vm.constants.getValue(decodeHandle(_debugInfo));
|
|
2562
|
+
let inspector = new ScopeInspector(vm.scope(), debuggerInfo);
|
|
2563
|
+
callback(valueForRef(vm.getSelf()), path => valueForRef(inspector.get(path)));
|
|
2564
|
+
});
|
|
2565
|
+
|
|
2566
|
+
APPEND_OPCODES.add(VM_ENTER_LIST_OP, (vm, {
|
|
2567
|
+
op1: relativeStart,
|
|
2568
|
+
op2: elseTarget
|
|
2569
|
+
}) => {
|
|
2570
|
+
let stack = vm.stack;
|
|
2571
|
+
let listRef = check(stack.pop());
|
|
2572
|
+
let keyRef = check(stack.pop());
|
|
2573
|
+
let keyValue = valueForRef(keyRef);
|
|
2574
|
+
// eslint-disable-next-line @typescript-eslint/no-base-to-string -- @fixme
|
|
2575
|
+
let key = keyValue === null ? '@identity' : String(keyValue);
|
|
2576
|
+
let iteratorRef = createIteratorRef(listRef, key);
|
|
2577
|
+
let iterator = valueForRef(iteratorRef);
|
|
2578
|
+
vm.updateWith(new AssertFilter(iteratorRef, iterator => iterator.isEmpty()));
|
|
2579
|
+
if (iterator.isEmpty()) {
|
|
2580
|
+
// TODO: Fix this offset, should be accurate
|
|
2581
|
+
vm.lowlevel.goto(elseTarget + 1);
|
|
2582
|
+
} else {
|
|
2583
|
+
vm.enterList(iteratorRef, relativeStart);
|
|
2584
|
+
vm.stack.push(iterator);
|
|
2585
|
+
}
|
|
2586
|
+
});
|
|
2587
|
+
APPEND_OPCODES.add(VM_EXIT_LIST_OP, vm => {
|
|
2588
|
+
vm.exitList();
|
|
2589
|
+
});
|
|
2590
|
+
APPEND_OPCODES.add(VM_ITERATE_OP, (vm, {
|
|
2591
|
+
op1: breaks
|
|
2592
|
+
}) => {
|
|
2593
|
+
let stack = vm.stack;
|
|
2594
|
+
let iterator = check(stack.peek());
|
|
2595
|
+
let item = iterator.next();
|
|
2596
|
+
if (item !== null) {
|
|
2597
|
+
vm.registerItem(vm.enterItem(item));
|
|
2598
|
+
} else {
|
|
2599
|
+
vm.lowlevel.goto(breaks);
|
|
2600
|
+
}
|
|
2601
|
+
});
|
|
2602
|
+
|
|
2603
|
+
const CAPABILITIES = {
|
|
2604
|
+
dynamicLayout: false,
|
|
2605
|
+
dynamicTag: false,
|
|
2606
|
+
prepareArgs: false,
|
|
2607
|
+
createArgs: false,
|
|
2608
|
+
attributeHook: false,
|
|
2609
|
+
elementHook: false,
|
|
2610
|
+
createCaller: false,
|
|
2611
|
+
dynamicScope: false,
|
|
2612
|
+
updateHook: false,
|
|
2613
|
+
createInstance: false,
|
|
2614
|
+
wrapped: false,
|
|
2615
|
+
willDestroy: false,
|
|
2616
|
+
hasSubOwner: false
|
|
2617
|
+
};
|
|
2618
|
+
class TemplateOnlyComponentManager {
|
|
2619
|
+
getCapabilities() {
|
|
2620
|
+
return CAPABILITIES;
|
|
2621
|
+
}
|
|
2622
|
+
getDebugName({
|
|
2623
|
+
name
|
|
2624
|
+
}) {
|
|
2625
|
+
return name;
|
|
2626
|
+
}
|
|
2627
|
+
getSelf() {
|
|
2628
|
+
return NULL_REFERENCE;
|
|
2629
|
+
}
|
|
2630
|
+
getDestroyable() {
|
|
2631
|
+
return null;
|
|
2632
|
+
}
|
|
2633
|
+
}
|
|
2634
|
+
const TEMPLATE_ONLY_COMPONENT_MANAGER = new TemplateOnlyComponentManager();
|
|
2635
|
+
|
|
2636
|
+
// This is only exported for types, don't use this class directly
|
|
2637
|
+
class TemplateOnlyComponentDefinition {
|
|
2638
|
+
constructor(moduleName = '@glimmer/component/template-only', name = '(unknown template-only component)') {
|
|
2639
|
+
this.moduleName = moduleName;
|
|
2640
|
+
this.name = name;
|
|
2641
|
+
}
|
|
2642
|
+
toString() {
|
|
2643
|
+
return this.moduleName;
|
|
2644
|
+
}
|
|
2645
|
+
}
|
|
2646
|
+
setInternalComponentManager(TEMPLATE_ONLY_COMPONENT_MANAGER, TemplateOnlyComponentDefinition.prototype);
|
|
2647
|
+
|
|
2648
|
+
/**
|
|
2649
|
+
This utility function is used to declare a given component has no backing class. When the rendering engine detects this it
|
|
2650
|
+
is able to perform a number of optimizations. Templates that are associated with `templateOnly()` will be rendered _as is_
|
|
2651
|
+
without adding a wrapping `<div>` (or any of the other element customization behaviors of [@ember/component](/ember/release/classes/Component)).
|
|
2652
|
+
Specifically, this means that the template will be rendered as "outer HTML".
|
|
2653
|
+
|
|
2654
|
+
In general, this method will be used by build time tooling and would not be directly written in an application. However,
|
|
2655
|
+
at times it may be useful to use directly to leverage the "outer HTML" semantics mentioned above. For example, if an addon would like
|
|
2656
|
+
to use these semantics for its templates but cannot be certain it will only be consumed by applications that have enabled the
|
|
2657
|
+
`template-only-glimmer-components` optional feature.
|
|
2658
|
+
|
|
2659
|
+
@example
|
|
2660
|
+
|
|
2661
|
+
```js
|
|
2662
|
+
import { templateOnlyComponent } from '@glimmer/runtime';
|
|
2663
|
+
|
|
2664
|
+
export default templateOnlyComponent();
|
|
2665
|
+
```
|
|
2666
|
+
|
|
2667
|
+
@public
|
|
2668
|
+
@method templateOnly
|
|
2669
|
+
@param {String} moduleName the module name that the template only component represents, this will be used for debugging purposes
|
|
2670
|
+
@category EMBER_GLIMMER_SET_COMPONENT_TEMPLATE
|
|
2671
|
+
*/
|
|
2672
|
+
|
|
2673
|
+
function templateOnlyComponent(moduleName, name) {
|
|
2674
|
+
return new TemplateOnlyComponentDefinition(moduleName, name);
|
|
2675
|
+
}
|
|
2676
|
+
|
|
2677
|
+
// http://www.w3.org/TR/html/syntax.html#html-integration-point
|
|
2678
|
+
const SVG_INTEGRATION_POINTS = {
|
|
2679
|
+
foreignObject: 1,
|
|
2680
|
+
desc: 1,
|
|
2681
|
+
title: 1
|
|
2682
|
+
};
|
|
2683
|
+
|
|
2684
|
+
// http://www.w3.org/TR/html/syntax.html#adjust-svg-attributes
|
|
2685
|
+
// TODO: Adjust SVG attributes
|
|
2686
|
+
|
|
2687
|
+
// http://www.w3.org/TR/html/syntax.html#parsing-main-inforeign
|
|
2688
|
+
// TODO: Adjust SVG elements
|
|
2689
|
+
|
|
2690
|
+
// http://www.w3.org/TR/html/syntax.html#parsing-main-inforeign
|
|
2691
|
+
const BLACKLIST_TABLE = Object.create(null);
|
|
2692
|
+
class DOMOperations {
|
|
2693
|
+
// Set by this.setupUselessElement() in constructor
|
|
2694
|
+
|
|
2695
|
+
constructor(document) {
|
|
2696
|
+
this.document = document;
|
|
2697
|
+
this.setupUselessElement();
|
|
2698
|
+
}
|
|
2699
|
+
|
|
2700
|
+
// split into separate method so that NodeDOMTreeConstruction
|
|
2701
|
+
// can override it.
|
|
2702
|
+
setupUselessElement() {
|
|
2703
|
+
this.uselessElement = this.document.createElement('div');
|
|
2704
|
+
}
|
|
2705
|
+
createElement(tag, context) {
|
|
2706
|
+
let isElementInSVGNamespace, isHTMLIntegrationPoint, isElementInMathMlNamespace, ns;
|
|
2707
|
+
if (context) {
|
|
2708
|
+
isElementInSVGNamespace = context.namespaceURI === NS_SVG || tag === 'svg';
|
|
2709
|
+
isElementInMathMlNamespace = context.namespaceURI === NS_MATHML || tag === 'math';
|
|
2710
|
+
isHTMLIntegrationPoint = !!SVG_INTEGRATION_POINTS[context.tagName];
|
|
2711
|
+
} else {
|
|
2712
|
+
isElementInSVGNamespace = tag === 'svg';
|
|
2713
|
+
isElementInMathMlNamespace = tag === 'math';
|
|
2714
|
+
isHTMLIntegrationPoint = false;
|
|
2715
|
+
}
|
|
2716
|
+
if ((isElementInMathMlNamespace || isElementInSVGNamespace) && !isHTMLIntegrationPoint) {
|
|
2717
|
+
// FIXME: This does not properly handle <font> with color, face, or
|
|
2718
|
+
// size attributes, which is also disallowed by the spec. We should fix
|
|
2719
|
+
// this.
|
|
2720
|
+
if (BLACKLIST_TABLE[tag]) {
|
|
2721
|
+
throw new Error(`Cannot create a ${tag} inside an SVG context`);
|
|
2722
|
+
}
|
|
2723
|
+
if (isElementInMathMlNamespace) {
|
|
2724
|
+
ns = NS_MATHML;
|
|
2725
|
+
} else {
|
|
2726
|
+
ns = NS_SVG;
|
|
2727
|
+
}
|
|
2728
|
+
return this.document.createElementNS(ns, tag);
|
|
2729
|
+
} else {
|
|
2730
|
+
return this.document.createElement(tag);
|
|
2731
|
+
}
|
|
2732
|
+
}
|
|
2733
|
+
insertBefore(parent, node, reference) {
|
|
2734
|
+
parent.insertBefore(node, reference);
|
|
2735
|
+
}
|
|
2736
|
+
insertHTMLBefore(parent, nextSibling, html) {
|
|
2737
|
+
if (html === '') {
|
|
2738
|
+
const comment = this.createComment('');
|
|
2739
|
+
parent.insertBefore(comment, nextSibling);
|
|
2740
|
+
return new ConcreteBounds(parent, comment, comment);
|
|
2741
|
+
}
|
|
2742
|
+
const prev = nextSibling ? nextSibling.previousSibling : parent.lastChild;
|
|
2743
|
+
let last;
|
|
2744
|
+
if (nextSibling === null) {
|
|
2745
|
+
parent.insertAdjacentHTML(INSERT_BEFORE_END, html);
|
|
2746
|
+
last = expect(parent.lastChild);
|
|
2747
|
+
} else if (nextSibling instanceof HTMLElement) {
|
|
2748
|
+
nextSibling.insertAdjacentHTML('beforebegin', html);
|
|
2749
|
+
last = expect(nextSibling.previousSibling);
|
|
2750
|
+
} else {
|
|
2751
|
+
// Non-element nodes do not support insertAdjacentHTML, so add an
|
|
2752
|
+
// element and call it on that element. Then remove the element.
|
|
2753
|
+
const {
|
|
2754
|
+
uselessElement
|
|
2755
|
+
} = this;
|
|
2756
|
+
parent.insertBefore(uselessElement, nextSibling);
|
|
2757
|
+
uselessElement.insertAdjacentHTML(INSERT_BEFORE_BEGIN, html);
|
|
2758
|
+
last = expect(uselessElement.previousSibling);
|
|
2759
|
+
parent.removeChild(uselessElement);
|
|
2760
|
+
}
|
|
2761
|
+
const first = expect(prev ? prev.nextSibling : parent.firstChild);
|
|
2762
|
+
return new ConcreteBounds(parent, first, last);
|
|
2763
|
+
}
|
|
2764
|
+
createTextNode(text) {
|
|
2765
|
+
return this.document.createTextNode(text);
|
|
2766
|
+
}
|
|
2767
|
+
createComment(data) {
|
|
2768
|
+
return this.document.createComment(data);
|
|
2769
|
+
}
|
|
2770
|
+
}
|
|
2771
|
+
|
|
2772
|
+
['b', 'big', 'blockquote', 'body', 'br', 'center', 'code', 'dd', 'div', 'dl', 'dt', 'em', 'embed', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'hr', 'i', 'img', 'li', 'listing', 'main', 'meta', 'nobr', 'ol', 'p', 'pre', 'ruby', 's', 'small', 'span', 'strong', 'strike', 'sub', 'sup', 'table', 'tt', 'u', 'ul', 'var'].forEach(tag => BLACKLIST_TABLE[tag] = 1);
|
|
2773
|
+
const WHITESPACE = /[\t\n\v\f\r \xa0\u{1680}\u{180e}\u{2000}-\u{200a}\u{2028}\u{2029}\u{202f}\u{205f}\u{3000}\u{feff}]/u;
|
|
2774
|
+
function isWhitespace(string) {
|
|
2775
|
+
return WHITESPACE.test(string);
|
|
2776
|
+
}
|
|
2777
|
+
class DOMChangesImpl extends DOMOperations {
|
|
2778
|
+
namespace;
|
|
2779
|
+
constructor(document) {
|
|
2780
|
+
super(document);
|
|
2781
|
+
this.document = document;
|
|
2782
|
+
this.namespace = null;
|
|
2783
|
+
}
|
|
2784
|
+
setAttribute(element, name, value) {
|
|
2785
|
+
element.setAttribute(name, value);
|
|
2786
|
+
}
|
|
2787
|
+
removeAttribute(element, name) {
|
|
2788
|
+
element.removeAttribute(name);
|
|
2789
|
+
}
|
|
2790
|
+
insertAfter(element, node, reference) {
|
|
2791
|
+
this.insertBefore(element, node, reference.nextSibling);
|
|
2792
|
+
}
|
|
2793
|
+
}
|
|
2794
|
+
const DOMChanges = DOMChangesImpl;
|
|
2795
|
+
|
|
2796
|
+
function internalHelper(helper) {
|
|
2797
|
+
return setInternalHelperManager(helper, {});
|
|
2798
|
+
}
|
|
2799
|
+
|
|
2800
|
+
/**
|
|
2801
|
+
Use the `{{array}}` helper to create an array to pass as an option to your
|
|
2802
|
+
components.
|
|
2803
|
+
|
|
2804
|
+
```handlebars
|
|
2805
|
+
<MyComponent @people={{array
|
|
2806
|
+
'Tom Dale'
|
|
2807
|
+
'Yehuda Katz'
|
|
2808
|
+
this.myOtherPerson}}
|
|
2809
|
+
/>
|
|
2810
|
+
```
|
|
2811
|
+
or
|
|
2812
|
+
```handlebars
|
|
2813
|
+
{{my-component people=(array
|
|
2814
|
+
'Tom Dale'
|
|
2815
|
+
'Yehuda Katz'
|
|
2816
|
+
this.myOtherPerson)
|
|
2817
|
+
}}
|
|
2818
|
+
```
|
|
2819
|
+
|
|
2820
|
+
Would result in an object such as:
|
|
2821
|
+
|
|
2822
|
+
```js
|
|
2823
|
+
['Tom Dale', 'Yehuda Katz', this.get('myOtherPerson')]
|
|
2824
|
+
```
|
|
2825
|
+
|
|
2826
|
+
Where the 3rd item in the array is bound to updates of the `myOtherPerson` property.
|
|
2827
|
+
|
|
2828
|
+
@method array
|
|
2829
|
+
@param {Array} options
|
|
2830
|
+
@return {Array} Array
|
|
2831
|
+
@public
|
|
2832
|
+
*/
|
|
2833
|
+
|
|
2834
|
+
const array = internalHelper(({
|
|
2835
|
+
positional
|
|
2836
|
+
}) => {
|
|
2837
|
+
return createComputeRef(() => reifyPositional(positional), null, 'array');
|
|
2838
|
+
});
|
|
2839
|
+
|
|
2840
|
+
const isEmpty = value => {
|
|
2841
|
+
return value === null || value === undefined || typeof value.toString !== 'function';
|
|
2842
|
+
};
|
|
2843
|
+
const normalizeTextValue = value => {
|
|
2844
|
+
if (isEmpty(value)) {
|
|
2845
|
+
return '';
|
|
2846
|
+
}
|
|
2847
|
+
return String(value);
|
|
2848
|
+
};
|
|
2849
|
+
|
|
2850
|
+
/**
|
|
2851
|
+
Concatenates the given arguments into a string.
|
|
2852
|
+
|
|
2853
|
+
Example:
|
|
2854
|
+
|
|
2855
|
+
```handlebars
|
|
2856
|
+
{{some-component name=(concat firstName " " lastName)}}
|
|
2857
|
+
|
|
2858
|
+
{{! would pass name="<first name value> <last name value>" to the component}}
|
|
2859
|
+
```
|
|
2860
|
+
|
|
2861
|
+
or for angle bracket invocation, you actually don't need concat at all.
|
|
2862
|
+
|
|
2863
|
+
```handlebars
|
|
2864
|
+
<SomeComponent @name="{{firstName}} {{lastName}}" />
|
|
2865
|
+
```
|
|
2866
|
+
|
|
2867
|
+
@public
|
|
2868
|
+
@method concat
|
|
2869
|
+
*/
|
|
2870
|
+
const concat = internalHelper(({
|
|
2871
|
+
positional
|
|
2872
|
+
}) => {
|
|
2873
|
+
return createComputeRef(() => reifyPositional(positional).map(normalizeTextValue).join(''), null, 'concat');
|
|
2874
|
+
});
|
|
2875
|
+
|
|
2876
|
+
const context = buildUntouchableThis();
|
|
2877
|
+
|
|
2878
|
+
/**
|
|
2879
|
+
The `fn` helper allows you to ensure a function that you are passing off
|
|
2880
|
+
to another component, helper, or modifier has access to arguments that are
|
|
2881
|
+
available in the template.
|
|
2882
|
+
|
|
2883
|
+
For example, if you have an `each` helper looping over a number of items, you
|
|
2884
|
+
may need to pass a function that expects to receive the item as an argument
|
|
2885
|
+
to a component invoked within the loop. Here's how you could use the `fn`
|
|
2886
|
+
helper to pass both the function and its arguments together:
|
|
2887
|
+
|
|
2888
|
+
```app/templates/components/items-listing.hbs
|
|
2889
|
+
{{#each @items as |item|}}
|
|
2890
|
+
<DisplayItem @item=item @select={{fn this.handleSelected item}} />
|
|
2891
|
+
{{/each}}
|
|
2892
|
+
```
|
|
2893
|
+
|
|
2894
|
+
```app/components/items-list.js
|
|
2895
|
+
import Component from '@glimmer/component';
|
|
2896
|
+
import { action } from '@ember/object';
|
|
2897
|
+
|
|
2898
|
+
export default class ItemsList extends Component {
|
|
2899
|
+
handleSelected = (item) => {
|
|
2900
|
+
// ...snip...
|
|
2901
|
+
}
|
|
2902
|
+
}
|
|
2903
|
+
```
|
|
2904
|
+
|
|
2905
|
+
In this case the `display-item` component will receive a normal function
|
|
2906
|
+
that it can invoke. When it invokes the function, the `handleSelected`
|
|
2907
|
+
function will receive the `item` and any arguments passed, thanks to the
|
|
2908
|
+
`fn` helper.
|
|
2909
|
+
|
|
2910
|
+
Let's take look at what that means in a couple circumstances:
|
|
2911
|
+
|
|
2912
|
+
- When invoked as `this.args.select()` the `handleSelected` function will
|
|
2913
|
+
receive the `item` from the loop as its first and only argument.
|
|
2914
|
+
- When invoked as `this.args.select('foo')` the `handleSelected` function
|
|
2915
|
+
will receive the `item` from the loop as its first argument and the
|
|
2916
|
+
string `'foo'` as its second argument.
|
|
2917
|
+
|
|
2918
|
+
In the example above, we used an arrow function to ensure that
|
|
2919
|
+
`handleSelected` is properly bound to the `items-list`, but let's explore what
|
|
2920
|
+
happens if we left out the arrow function:
|
|
2921
|
+
|
|
2922
|
+
```app/components/items-list.js
|
|
2923
|
+
import Component from '@glimmer/component';
|
|
2924
|
+
|
|
2925
|
+
export default class ItemsList extends Component {
|
|
2926
|
+
handleSelected(item) {
|
|
2927
|
+
// ...snip...
|
|
2928
|
+
}
|
|
2929
|
+
}
|
|
2930
|
+
```
|
|
2931
|
+
|
|
2932
|
+
In this example, when `handleSelected` is invoked inside the `display-item`
|
|
2933
|
+
component, it will **not** have access to the component instance. In other
|
|
2934
|
+
words, it will have no `this` context, so please make sure your functions
|
|
2935
|
+
are bound (via an arrow function or other means) before passing into `fn`!
|
|
2936
|
+
|
|
2937
|
+
See also [partial application](https://en.wikipedia.org/wiki/Partial_application).
|
|
2938
|
+
|
|
2939
|
+
@method fn
|
|
2940
|
+
@public
|
|
2941
|
+
*/
|
|
2942
|
+
const fn = internalHelper(({
|
|
2943
|
+
positional
|
|
2944
|
+
}) => {
|
|
2945
|
+
let callbackRef = check(positional[0]);
|
|
2946
|
+
return createComputeRef(() => {
|
|
2947
|
+
return (...invocationArgs) => {
|
|
2948
|
+
let [fn, ...args] = reifyPositional(positional);
|
|
2949
|
+
if (isInvokableRef(callbackRef)) {
|
|
2950
|
+
let value = args.length > 0 ? args[0] : invocationArgs[0];
|
|
2951
|
+
return void updateRef(callbackRef, value);
|
|
2952
|
+
} else {
|
|
2953
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-return -- @fixme
|
|
2954
|
+
return fn.call(context, ...args, ...invocationArgs);
|
|
2955
|
+
}
|
|
2956
|
+
};
|
|
2957
|
+
}, null, 'fn');
|
|
2958
|
+
});
|
|
2959
|
+
|
|
2960
|
+
/**
|
|
2961
|
+
Dynamically look up a property on an object. The second argument to `{{get}}`
|
|
2962
|
+
should have a string value, although it can be bound.
|
|
2963
|
+
|
|
2964
|
+
For example, these two usages are equivalent:
|
|
2965
|
+
|
|
2966
|
+
```app/components/developer-detail.js
|
|
2967
|
+
import Component from '@glimmer/component';
|
|
2968
|
+
import { tracked } from '@glimmer/tracking';
|
|
2969
|
+
|
|
2970
|
+
export default class extends Component {
|
|
2971
|
+
@tracked developer = {
|
|
2972
|
+
name: "Sandi Metz",
|
|
2973
|
+
language: "Ruby"
|
|
2974
|
+
}
|
|
2975
|
+
}
|
|
2976
|
+
```
|
|
2977
|
+
|
|
2978
|
+
```handlebars
|
|
2979
|
+
{{this.developer.name}}
|
|
2980
|
+
{{get this.developer "name"}}
|
|
2981
|
+
```
|
|
2982
|
+
|
|
2983
|
+
If there were several facts about a person, the `{{get}}` helper can dynamically
|
|
2984
|
+
pick one:
|
|
2985
|
+
|
|
2986
|
+
```app/templates/application.hbs
|
|
2987
|
+
<DeveloperDetail @factName="language" />
|
|
2988
|
+
```
|
|
2989
|
+
|
|
2990
|
+
```handlebars
|
|
2991
|
+
{{get this.developer @factName}}
|
|
2992
|
+
```
|
|
2993
|
+
|
|
2994
|
+
For a more complex example, this template would allow the user to switch
|
|
2995
|
+
between showing the user's height and weight with a click:
|
|
2996
|
+
|
|
2997
|
+
```app/components/developer-detail.js
|
|
2998
|
+
import Component from '@glimmer/component';
|
|
2999
|
+
import { tracked } from '@glimmer/tracking';
|
|
3000
|
+
|
|
3001
|
+
export default class extends Component {
|
|
3002
|
+
@tracked developer = {
|
|
3003
|
+
name: "Sandi Metz",
|
|
3004
|
+
language: "Ruby"
|
|
3005
|
+
}
|
|
3006
|
+
|
|
3007
|
+
@tracked currentFact = 'name'
|
|
3008
|
+
|
|
3009
|
+
showFact = (fact) => {
|
|
3010
|
+
this.currentFact = fact;
|
|
3011
|
+
}
|
|
3012
|
+
}
|
|
3013
|
+
```
|
|
3014
|
+
|
|
3015
|
+
```app/components/developer-detail.js
|
|
3016
|
+
{{get this.developer this.currentFact}}
|
|
3017
|
+
|
|
3018
|
+
<button {{on 'click' (fn this.showFact "name")}}>Show name</button>
|
|
3019
|
+
<button {{on 'click' (fn this.showFact "language")}}>Show language</button>
|
|
3020
|
+
```
|
|
3021
|
+
|
|
3022
|
+
The `{{get}}` helper can also respect mutable values itself. For example:
|
|
3023
|
+
|
|
3024
|
+
```app/components/developer-detail.js
|
|
3025
|
+
<Input @value={{mut (get this.person this.currentFact)}} />
|
|
3026
|
+
|
|
3027
|
+
<button {{on 'click' (fn this.showFact "name")}}>Show name</button>
|
|
3028
|
+
<button {{on 'click' (fn this.showFact "language")}}>Show language</button>
|
|
3029
|
+
```
|
|
3030
|
+
|
|
3031
|
+
Would allow the user to swap what fact is being displayed, and also edit
|
|
3032
|
+
that fact via a two-way mutable binding.
|
|
3033
|
+
|
|
3034
|
+
@public
|
|
3035
|
+
@method get
|
|
3036
|
+
*/
|
|
3037
|
+
const get = internalHelper(({
|
|
3038
|
+
positional
|
|
3039
|
+
}) => {
|
|
3040
|
+
let sourceRef = positional[0] ?? UNDEFINED_REFERENCE;
|
|
3041
|
+
let pathRef = positional[1] ?? UNDEFINED_REFERENCE;
|
|
3042
|
+
return createComputeRef(() => {
|
|
3043
|
+
let source = valueForRef(sourceRef);
|
|
3044
|
+
if (isDict(source)) {
|
|
3045
|
+
return getPath(source, String(valueForRef(pathRef)));
|
|
3046
|
+
}
|
|
3047
|
+
}, value => {
|
|
3048
|
+
let source = valueForRef(sourceRef);
|
|
3049
|
+
if (isDict(source)) {
|
|
3050
|
+
return setPath(source, String(valueForRef(pathRef)), value);
|
|
3051
|
+
}
|
|
3052
|
+
}, 'get');
|
|
3053
|
+
});
|
|
3054
|
+
|
|
3055
|
+
/**
|
|
3056
|
+
Use the `{{hash}}` helper to create a hash to pass as an option to your
|
|
3057
|
+
components. This is specially useful for contextual components where you can
|
|
3058
|
+
just yield a hash:
|
|
3059
|
+
|
|
3060
|
+
```handlebars
|
|
3061
|
+
{{yield (hash
|
|
3062
|
+
name='Sarah'
|
|
3063
|
+
title=office
|
|
3064
|
+
)}}
|
|
3065
|
+
```
|
|
3066
|
+
|
|
3067
|
+
Would result in an object such as:
|
|
3068
|
+
|
|
3069
|
+
```js
|
|
3070
|
+
{ name: 'Sarah', title: this.get('office') }
|
|
3071
|
+
```
|
|
3072
|
+
|
|
3073
|
+
Where the `title` is bound to updates of the `office` property.
|
|
3074
|
+
|
|
3075
|
+
Note that the hash is an empty object with no prototype chain, therefore
|
|
3076
|
+
common methods like `toString` are not available in the resulting hash.
|
|
3077
|
+
If you need to use such a method, you can use the `call` or `apply`
|
|
3078
|
+
approach:
|
|
3079
|
+
|
|
3080
|
+
```js
|
|
3081
|
+
function toString(obj) {
|
|
3082
|
+
return Object.prototype.toString.apply(obj);
|
|
3083
|
+
}
|
|
3084
|
+
```
|
|
3085
|
+
|
|
3086
|
+
@method hash
|
|
3087
|
+
@param {Object} options
|
|
3088
|
+
@return {Object} Hash
|
|
3089
|
+
@public
|
|
3090
|
+
*/
|
|
3091
|
+
const hash = internalHelper(({
|
|
3092
|
+
named
|
|
3093
|
+
}) => {
|
|
3094
|
+
let ref = createComputeRef(() => {
|
|
3095
|
+
return reifyNamed(named);
|
|
3096
|
+
}, null, 'hash');
|
|
3097
|
+
|
|
3098
|
+
// Setup the children so that templates can bypass getting the value of
|
|
3099
|
+
// the reference and treat children lazily
|
|
3100
|
+
let children = new Map();
|
|
3101
|
+
for (let name in named) {
|
|
3102
|
+
children.set(name, named[name]);
|
|
3103
|
+
}
|
|
3104
|
+
ref.children = children;
|
|
3105
|
+
return ref;
|
|
3106
|
+
});
|
|
3107
|
+
|
|
3108
|
+
class OnModifierState {
|
|
3109
|
+
tag = createUpdatableTag();
|
|
3110
|
+
element;
|
|
3111
|
+
args;
|
|
3112
|
+
listener = null;
|
|
3113
|
+
constructor(element, args) {
|
|
3114
|
+
this.element = element;
|
|
3115
|
+
this.args = args;
|
|
3116
|
+
registerDestructor(this, () => {
|
|
3117
|
+
let {
|
|
3118
|
+
element,
|
|
3119
|
+
listener
|
|
3120
|
+
} = this;
|
|
3121
|
+
if (listener) {
|
|
3122
|
+
let {
|
|
3123
|
+
eventName,
|
|
3124
|
+
callback,
|
|
3125
|
+
options
|
|
3126
|
+
} = listener;
|
|
3127
|
+
removeEventListener(element, eventName, callback, options);
|
|
3128
|
+
}
|
|
3129
|
+
});
|
|
3130
|
+
}
|
|
3131
|
+
|
|
3132
|
+
// Update this.listener if needed
|
|
3133
|
+
updateListener() {
|
|
3134
|
+
let {
|
|
3135
|
+
element,
|
|
3136
|
+
args,
|
|
3137
|
+
listener
|
|
3138
|
+
} = this;
|
|
3139
|
+
let arg0 = args.positional[0];
|
|
3140
|
+
let eventName = check(arg0 ? valueForRef(arg0) : undefined);
|
|
3141
|
+
let arg1 = args.positional[1];
|
|
3142
|
+
let userProvidedCallback = check(arg1 ? valueForRef(arg1) : undefined);
|
|
3143
|
+
let once = undefined;
|
|
3144
|
+
let passive = undefined;
|
|
3145
|
+
let capture = undefined;
|
|
3146
|
+
{
|
|
3147
|
+
let {
|
|
3148
|
+
once: _once,
|
|
3149
|
+
passive: _passive,
|
|
3150
|
+
capture: _capture
|
|
3151
|
+
} = args.named;
|
|
3152
|
+
if (_once) {
|
|
3153
|
+
once = valueForRef(_once);
|
|
3154
|
+
}
|
|
3155
|
+
if (_passive) {
|
|
3156
|
+
passive = valueForRef(_passive);
|
|
3157
|
+
}
|
|
3158
|
+
if (_capture) {
|
|
3159
|
+
capture = valueForRef(_capture);
|
|
3160
|
+
}
|
|
3161
|
+
}
|
|
3162
|
+
let shouldUpdate = false;
|
|
3163
|
+
if (listener === null) {
|
|
3164
|
+
shouldUpdate = true;
|
|
3165
|
+
} else {
|
|
3166
|
+
shouldUpdate = eventName !== listener.eventName || userProvidedCallback !== listener.userProvidedCallback || once !== listener.once || passive !== listener.passive || capture !== listener.capture;
|
|
3167
|
+
}
|
|
3168
|
+
let options = undefined;
|
|
3169
|
+
|
|
3170
|
+
// we want to handle both `true` and `false` because both have a meaning:
|
|
3171
|
+
// https://bugs.chromium.org/p/chromium/issues/detail?id=770208
|
|
3172
|
+
if (shouldUpdate) {
|
|
3173
|
+
if (once !== undefined || passive !== undefined || capture !== undefined) {
|
|
3174
|
+
options = {
|
|
3175
|
+
once,
|
|
3176
|
+
passive,
|
|
3177
|
+
capture
|
|
3178
|
+
};
|
|
3179
|
+
}
|
|
3180
|
+
}
|
|
3181
|
+
if (shouldUpdate) {
|
|
3182
|
+
let callback = userProvidedCallback;
|
|
3183
|
+
this.listener = {
|
|
3184
|
+
eventName,
|
|
3185
|
+
callback,
|
|
3186
|
+
userProvidedCallback,
|
|
3187
|
+
once,
|
|
3188
|
+
passive,
|
|
3189
|
+
capture,
|
|
3190
|
+
options
|
|
3191
|
+
};
|
|
3192
|
+
if (listener) {
|
|
3193
|
+
removeEventListener(element, listener.eventName, listener.callback, listener.options);
|
|
3194
|
+
}
|
|
3195
|
+
addEventListener(element, eventName, callback, options);
|
|
3196
|
+
}
|
|
3197
|
+
}
|
|
3198
|
+
}
|
|
3199
|
+
let adds = 0;
|
|
3200
|
+
let removes = 0;
|
|
3201
|
+
function removeEventListener(element, eventName, callback, options) {
|
|
3202
|
+
removes++;
|
|
3203
|
+
element.removeEventListener(eventName, callback, options);
|
|
3204
|
+
}
|
|
3205
|
+
function addEventListener(element, eventName, callback, options) {
|
|
3206
|
+
adds++;
|
|
3207
|
+
element.addEventListener(eventName, callback, options);
|
|
3208
|
+
}
|
|
3209
|
+
|
|
3210
|
+
/**
|
|
3211
|
+
The `{{on}}` modifier lets you easily add event listeners (it uses
|
|
3212
|
+
[EventTarget.addEventListener](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener)
|
|
3213
|
+
internally).
|
|
3214
|
+
|
|
3215
|
+
For example, if you'd like to run a function on your component when a `<button>`
|
|
3216
|
+
in the components template is clicked you might do something like:
|
|
3217
|
+
|
|
3218
|
+
```app/components/like-post.hbs
|
|
3219
|
+
<button {{on 'click' this.saveLike}}>Like this post!</button>
|
|
3220
|
+
```
|
|
3221
|
+
|
|
3222
|
+
```app/components/like-post.js
|
|
3223
|
+
import Component from '@glimmer/component';
|
|
3224
|
+
import { action } from '@ember/object';
|
|
3225
|
+
|
|
3226
|
+
export default class LikePostComponent extends Component {
|
|
3227
|
+
saveLike = () => {
|
|
3228
|
+
// someone likes your post!
|
|
3229
|
+
// better send a request off to your server...
|
|
3230
|
+
}
|
|
3231
|
+
}
|
|
3232
|
+
```
|
|
3233
|
+
|
|
3234
|
+
### Arguments
|
|
3235
|
+
|
|
3236
|
+
`{{on}}` accepts two positional arguments, and a few named arguments.
|
|
3237
|
+
|
|
3238
|
+
The positional arguments are:
|
|
3239
|
+
|
|
3240
|
+
- `event` -- the name to use when calling `addEventListener`
|
|
3241
|
+
- `callback` -- the function to be passed to `addEventListener`
|
|
3242
|
+
|
|
3243
|
+
The named arguments are:
|
|
3244
|
+
|
|
3245
|
+
- capture -- a `true` value indicates that events of this type will be dispatched
|
|
3246
|
+
to the registered listener before being dispatched to any EventTarget beneath it
|
|
3247
|
+
in the DOM tree.
|
|
3248
|
+
- once -- indicates that the listener should be invoked at most once after being
|
|
3249
|
+
added. If true, the listener would be automatically removed when invoked.
|
|
3250
|
+
- passive -- if `true`, indicates that the function specified by listener will never
|
|
3251
|
+
call preventDefault(). If a passive listener does call preventDefault(), the user
|
|
3252
|
+
agent will do nothing other than generate a console warning. See
|
|
3253
|
+
[Improving scrolling performance with passive listeners](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#Improving_scrolling_performance_with_passive_listeners)
|
|
3254
|
+
to learn more.
|
|
3255
|
+
|
|
3256
|
+
The callback function passed to `{{on}}` will receive any arguments that are passed
|
|
3257
|
+
to the event handler. Most commonly this would be the `event` itself.
|
|
3258
|
+
|
|
3259
|
+
If you would like to pass additional arguments to the function you should use
|
|
3260
|
+
the `{{fn}}` helper.
|
|
3261
|
+
|
|
3262
|
+
For example, in our example case above if you'd like to pass in the post that
|
|
3263
|
+
was being liked when the button is clicked you could do something like:
|
|
3264
|
+
|
|
3265
|
+
```app/components/like-post.hbs
|
|
3266
|
+
<button {{on 'click' (fn this.saveLike @post)}}>Like this post!</button>
|
|
3267
|
+
```
|
|
3268
|
+
|
|
3269
|
+
In this case, the `saveLike` function will receive two arguments: the click event
|
|
3270
|
+
and the value of `@post`.
|
|
3271
|
+
|
|
3272
|
+
### Function Context
|
|
3273
|
+
|
|
3274
|
+
In the example above, we used an arrow function to ensure that `likePost` is
|
|
3275
|
+
properly bound to the `items-list`, but let's explore what happens if we
|
|
3276
|
+
left out the arrow function:
|
|
3277
|
+
|
|
3278
|
+
```app/components/like-post.js
|
|
3279
|
+
import Component from '@glimmer/component';
|
|
3280
|
+
|
|
3281
|
+
export default class LikePostComponent extends Component {
|
|
3282
|
+
saveLike() {
|
|
3283
|
+
// ...snip...
|
|
3284
|
+
}
|
|
3285
|
+
}
|
|
3286
|
+
```
|
|
3287
|
+
|
|
3288
|
+
In this example, when the button is clicked `saveLike` will be invoked,
|
|
3289
|
+
it will **not** have access to the component instance. In other
|
|
3290
|
+
words, it will have no `this` context, so please make sure your functions
|
|
3291
|
+
are bound (via an arrow function or other means) before passing into `on`!
|
|
3292
|
+
|
|
3293
|
+
@method on
|
|
3294
|
+
@public
|
|
3295
|
+
*/
|
|
3296
|
+
class OnModifierManager {
|
|
3297
|
+
getDebugName() {
|
|
3298
|
+
return 'on';
|
|
3299
|
+
}
|
|
3300
|
+
getDebugInstance() {
|
|
3301
|
+
return null;
|
|
3302
|
+
}
|
|
3303
|
+
get counters() {
|
|
3304
|
+
return {
|
|
3305
|
+
adds,
|
|
3306
|
+
removes
|
|
3307
|
+
};
|
|
3308
|
+
}
|
|
3309
|
+
create(_owner, element, _state, args) {
|
|
3310
|
+
return new OnModifierState(element, args);
|
|
3311
|
+
}
|
|
3312
|
+
getTag({
|
|
3313
|
+
tag
|
|
3314
|
+
}) {
|
|
3315
|
+
return tag;
|
|
3316
|
+
}
|
|
3317
|
+
install(state) {
|
|
3318
|
+
state.updateListener();
|
|
3319
|
+
}
|
|
3320
|
+
update(state) {
|
|
3321
|
+
state.updateListener();
|
|
3322
|
+
}
|
|
3323
|
+
getDestroyable(state) {
|
|
3324
|
+
return state;
|
|
3325
|
+
}
|
|
3326
|
+
}
|
|
3327
|
+
const on = setInternalModifierManager(new OnModifierManager(), {});
|
|
3328
|
+
|
|
3329
|
+
export { DOMOperations as A, isSafeString as B, ConcreteBounds as C, DOMChanges as D, EMPTY_ARGS as E, normalizeStringValue as F, DebugRenderTreeImpl as G, isArgumentError as H, APPEND_OPCODES as I, move as J, externs as K, JumpIfNotModifiedOpcode as L, BeginTrackFrameOpcode as M, NS_SVG as N, EndTrackFrameOpcode as O, TEMPLATE_ONLY_COMPONENT_MANAGER as T, VMArgumentsImpl as V, CurriedValue as a, CursorImpl as b, EMPTY_NAMED as c, EMPTY_POSITIONAL as d, DOMChangesImpl as e, TemplateOnlyComponentDefinition as f, TemplateOnlyComponentManager as g, array as h, clear as i, concat as j, createCapturedArgs as k, curry as l, fn as m, get as n, hash as o, isWhitespace as p, on as q, reifyArgs as r, reifyNamed as s, reifyPositional as t, resetDebuggerCallback as u, setDebuggerCallback as v, templateOnlyComponent as w, COMMENT_NODE as x, TEXT_NODE as y, ELEMENT_NODE as z };
|