ember-source 7.2.0-beta.1 → 7.3.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.
Files changed (70) hide show
  1. package/build-metadata.json +3 -3
  2. package/dist/dev/packages/@ember/-internals/deprecations/index.js +10 -0
  3. package/dist/dev/packages/@ember/-internals/glimmer/index.js +3 -3
  4. package/dist/dev/packages/@ember/-internals/routing/index.js +1 -1
  5. package/dist/dev/packages/@ember/-internals/runtime/lib/mixins/-proxy.js +1 -1
  6. package/dist/dev/packages/@ember/-internals/runtime/lib/mixins/comparable.js +5 -0
  7. package/dist/dev/packages/@ember/application/index.js +2 -2
  8. package/dist/dev/packages/@ember/application/instance.js +21 -1
  9. package/dist/dev/packages/@ember/component/helper.js +321 -1
  10. package/dist/dev/packages/@ember/component/index.js +1 -1
  11. package/dist/dev/packages/@ember/engine/index.js +2 -2
  12. package/dist/dev/packages/@ember/renderer/index.js +1 -1
  13. package/dist/dev/packages/@ember/routing/-internals.js +1 -1
  14. package/dist/dev/packages/@ember/routing/lib/routing-service.js +0 -1
  15. package/dist/dev/packages/@ember/routing/lib/utils.js +1 -1
  16. package/dist/dev/packages/@ember/routing/route.js +1 -1
  17. package/dist/dev/packages/@ember/routing/router-service.js +0 -1
  18. package/dist/dev/packages/@ember/routing/router.js +1 -1
  19. package/dist/dev/packages/@ember/utils/lib/compare.js +5 -2
  20. package/dist/dev/packages/ember/version.js +1 -1
  21. package/dist/dev/packages/router_js/index.js +2 -2
  22. package/dist/dev/packages/shared-chunks/{curly-Ei5G8jhk.js → curly-DGUCLOud.js} +4 -5
  23. package/dist/dev/packages/shared-chunks/curly-brand-B_F79Dep.js +12 -0
  24. package/dist/dev/packages/shared-chunks/helper-brand-C9_8vvOf.js +12 -0
  25. package/dist/dev/packages/shared-chunks/{index-B3pPx1fL.js → index-CCyXUNBa.js} +616 -1573
  26. package/dist/dev/packages/shared-chunks/outlet-CHFL7tun.js +135 -0
  27. package/dist/dev/packages/shared-chunks/setup-registry-BHdDJATP.js +951 -0
  28. package/dist/dev/packages/shared-chunks/{unrecognized-url-error-BJHjL30Q.js → unrecognized-url-error-B8loxkay.js} +1 -1
  29. package/dist/prod/packages/@ember/-internals/deprecations/index.js +10 -0
  30. package/dist/prod/packages/@ember/-internals/glimmer/index.js +3 -3
  31. package/dist/prod/packages/@ember/-internals/routing/index.js +1 -1
  32. package/dist/prod/packages/@ember/-internals/runtime/lib/mixins/-proxy.js +1 -1
  33. package/dist/prod/packages/@ember/-internals/runtime/lib/mixins/comparable.js +5 -0
  34. package/dist/prod/packages/@ember/application/index.js +2 -2
  35. package/dist/prod/packages/@ember/application/instance.js +17 -2
  36. package/dist/prod/packages/@ember/component/helper.js +305 -1
  37. package/dist/prod/packages/@ember/component/index.js +1 -1
  38. package/dist/prod/packages/@ember/engine/index.js +2 -2
  39. package/dist/prod/packages/@ember/renderer/index.js +1 -1
  40. package/dist/prod/packages/@ember/routing/lib/routing-service.js +0 -1
  41. package/dist/prod/packages/@ember/routing/lib/utils.js +1 -1
  42. package/dist/prod/packages/@ember/routing/route.js +1 -1
  43. package/dist/prod/packages/@ember/routing/router-service.js +0 -1
  44. package/dist/prod/packages/@ember/routing/router.js +1 -1
  45. package/dist/prod/packages/@ember/utils/lib/compare.js +5 -2
  46. package/dist/prod/packages/ember/version.js +1 -1
  47. package/dist/prod/packages/router_js/index.js +2 -2
  48. package/dist/prod/packages/shared-chunks/{curly-IY06zACp.js → curly-a6DP7r87.js} +4 -5
  49. package/dist/prod/packages/shared-chunks/curly-brand-B_F79Dep.js +12 -0
  50. package/dist/prod/packages/shared-chunks/helper-brand-C9_8vvOf.js +12 -0
  51. package/dist/prod/packages/shared-chunks/{index-CslMfEpb.js → index-npr2B-vu.js} +546 -1449
  52. package/dist/prod/packages/shared-chunks/outlet--lIm3q7t.js +132 -0
  53. package/dist/prod/packages/shared-chunks/setup-registry-Dfu8EyLU.js +886 -0
  54. package/dist/prod/packages/shared-chunks/{unrecognized-url-error-EgNrnFu_.js → unrecognized-url-error-jjQ-FqKB.js} +1 -1
  55. package/docs/data.json +279 -214
  56. package/package.json +6 -6
  57. package/types/stable/@ember/-internals/deprecations/index.d.ts +6 -0
  58. package/types/stable/@ember/-internals/glimmer/lib/base-renderer.d.ts +150 -0
  59. package/types/stable/@ember/-internals/glimmer/lib/component-managers/curly-brand.d.ts +10 -0
  60. package/types/stable/@ember/-internals/glimmer/lib/component-managers/curly.d.ts +3 -2
  61. package/types/stable/@ember/-internals/glimmer/lib/helper-brand.d.ts +10 -0
  62. package/types/stable/@ember/-internals/glimmer/lib/helper.d.ts +4 -6
  63. package/types/stable/@ember/-internals/glimmer/lib/renderer.d.ts +7 -154
  64. package/types/stable/@ember/-internals/glimmer/lib/router-resolver.d.ts +17 -0
  65. package/types/stable/@ember/renderer/index.d.ts +2 -2
  66. package/types/stable/index.d.ts +590 -586
  67. package/dist/dev/packages/shared-chunks/helper-DIj85_-f.js +0 -326
  68. package/dist/dev/packages/shared-chunks/setup-registry-9DCmHTFF.js +0 -77
  69. package/dist/prod/packages/shared-chunks/helper-DkXiTBjc.js +0 -310
  70. package/dist/prod/packages/shared-chunks/setup-registry-U-6VaNQG.js +0 -74
@@ -1,234 +1,125 @@
1
- import { privatize } from '../@ember/-internals/container/index.js';
2
1
  import { E as ENV } from './env-DXxsTFkM.js';
3
- import { isFactory, getOwner } from '../@ember/-internals/owner/index.js';
4
- import { g as guidFor } from './guid-Cbq2sNV_.js';
5
- import { getViewId, getViewElement } from '../@ember/-internals/views/lib/system/utils.js';
6
2
  import { h as hasDOM } from './has-dom-DdQORPzI.js';
7
3
  import { assert } from '../@ember/debug/lib/assert.js';
8
4
  import { schedule, _backburner, _getCurrentRunLoop } from '../@ember/runloop/index.js';
9
- import { associateDestroyableChild, isDestroyed, destroy, registerDestructor, isDestroying } from '../@glimmer/destroyable/index.js';
5
+ import { associateDestroyableChild, destroy, registerDestructor, isDestroyed, isDestroying } from '../@glimmer/destroyable/index.js';
10
6
  import { artifacts } from '../@glimmer/program/index.js';
11
7
  import { R as RuntimeOpImpl } from './program-BAh__OXZ.js';
12
- import { v as valueForRef, U as UNDEFINED_REFERENCE, c as createComputeRef, a as createConstRef, h as createInvokableRef, j as createReadOnlyRef, k as createUnboundRef, g as childRefFromParts, u as updateRef } from './reference-CG0yPgLy.js';
13
8
  import { c as clientBuilder } from './api-CQexacBn.js';
14
- import { E as EMPTY_ARGS, c as createCapturedArgs, b as EMPTY_POSITIONAL, d as curry } from './arguments-BzAkZVBa.js';
15
- import { g as runtimeOptions, i as inTransaction, r as renderComponent$1, d as renderMain } from './render-Dx7lr1hR.js';
16
- import { d as dict } from './collections-GpG8lT2g.js';
17
- import { u as unwrapTemplate, a as CurlyComponentManager, i as initialRenderInstrumentDetails, b as ComponentStateBucket, D as DIRTY_TAG, c as isCurlyManager, B as BOUNDS } from './curly-IY06zACp.js';
18
- import { C as CONSTANT_TAG, c as consumeTag, f as isTracking, D as DIRTY_TAG$1, r as createTag, a as valueForTag, k as CURRENT_TAG, v as validateTag } from './cache-CofLhaS4.js';
19
- import { _instrumentStart } from '../@ember/instrumentation/index.js';
20
- import { c as capabilityFlagsFrom } from './capabilities-BuVYh-vx.js';
21
- import { t as templateFactory } from './index-Bf53M8eS.js';
22
- import { g as getFactoryFor } from './container-BYOnjnwz.js';
23
- import { g as get, a as _getProp } from './property_get-DAKgbeJX.js';
9
+ import { g as runtimeOptions, i as inTransaction, r as renderComponent$1 } from './render-Dx7lr1hR.js';
10
+ import { c as consumeTag, f as isTracking, a as valueForTag, k as CURRENT_TAG, v as validateTag } from './cache-CofLhaS4.js';
11
+ import { g as get$1, a as _getProp } from './property_get-DAKgbeJX.js';
24
12
  import { _ as _setProp, s as set } from './property_set-BaQJdVfS.js';
13
+ import './guid-Cbq2sNV_.js';
25
14
  import setGlobalContext from '../@glimmer/global-context/index.js';
26
- import { t as tagForObject, o as objectAt, a as tagForProperty } from './chain-tags-B2J7DsxO.js';
15
+ import { a as tagForProperty, t as tagForObject, o as objectAt } from './chain-tags-B2J7DsxO.js';
27
16
  import { isEmberArray } from '../@ember/array/-internals.js';
28
17
  import { i as isObject } from './spec-BXl1reqK.js';
29
18
  import { t as tagFor } from './meta-BJtIZDir.js';
30
19
  import { contentFor } from '../@ember/-internals/runtime/lib/mixins/-proxy.js';
31
20
  import { i as isProxy } from './is_proxy-Bzg0d4m4.js';
21
+ import { v as valueForRef, c as createComputeRef, a as createConstRef, h as createInvokableRef, j as createReadOnlyRef, k as createUnboundRef } from './reference-CG0yPgLy.js';
32
22
  import { i as internalHelper } from './internal-helper-Bz1lpDXr.js';
33
23
  import { i as isHTMLSafe } from './index-D-xTBV4B.js';
34
24
  import isArray from '../@ember/array/lib/is-array.js';
25
+ import { isFactory } from '../@ember/-internals/owner/index.js';
26
+ import { _instrumentStart } from '../@ember/instrumentation/index.js';
35
27
  import { g as getComponentTemplate } from './template-Dc_cBOoX.js';
36
- import { c as hasInternalComponentManager, j as setInternalHelperManager, g as getInternalComponentManager } from './api-DlJKfm_f.js';
28
+ import { a as getInternalHelperManager, j as setInternalHelperManager, g as getInternalComponentManager } from './api-DlJKfm_f.js';
37
29
  import { h as hash, f as fn, a as array } from './hash-gEXIsSO4.js';
38
- import { g as get$1, c as concat } from './get-Dago5uGl.js';
30
+ import { g as get, c as concat } from './get-Dago5uGl.js';
39
31
  import { o as on } from './on-BZHAxzdq.js';
40
32
  import { T as TEMPLATE_ONLY_COMPONENT_MANAGER, t as templateOnlyComponent } from './template-only-DKNcKM5b.js';
41
- import { i as isClassicHelper, C as CLASSIC_HELPER_MANAGER } from './helper-DkXiTBjc.js';
33
+ import { i as isCurlyManager } from './curly-brand-B_F79Dep.js';
34
+ import { i as isClassicHelper } from './helper-brand-C9_8vvOf.js';
42
35
  import { dasherize } from '../@ember/-internals/string/index.js';
43
36
  import { a as uniqueId } from './unique-id-o2pS74go.js';
44
- import { generateControllerFactory } from '../@ember/routing/lib/generate_controller.js';
45
37
  import { E as EvaluationContextImpl } from './program-context-COSioH46.js';
46
38
 
47
- function instrumentationPayload$1(def) {
48
- // "main" used to be the outlet name, keeping it around for compatibility
49
- return {
50
- object: `${def.name}:main`
39
+ /**
40
+ @module ember
41
+ */
42
+ const disallowDynamicResolution = internalHelper(({
43
+ positional,
44
+ named
45
+ }) => {
46
+ const nameOrValueRef = positional[0];
47
+ let typeRef = named['type'];
48
+ let locRef = named['loc'];
49
+ let originalRef = named['original'];
50
+ // assert('[BUG] expecting a string literal for the `type` argument', isConstRef(typeRef));
51
+ // assert('[BUG] expecting a string literal for the `loc` argument', isConstRef(locRef));
52
+ // assert('[BUG] expecting a string literal for the `original` argument', isConstRef(originalRef));
53
+ valueForRef(typeRef);
54
+ valueForRef(locRef);
55
+ valueForRef(originalRef);
56
+ return createComputeRef(() => {
57
+ let nameOrValue = valueForRef(nameOrValueRef);
58
+ return nameOrValue;
59
+ });
60
+ });
61
+
62
+ let helper;
63
+ {
64
+ helper = args => {
65
+ let arg = args.positional[0];
66
+ return arg;
51
67
  };
52
68
  }
53
- const CAPABILITIES$2 = {
54
- dynamicLayout: false,
55
- dynamicTag: false,
56
- prepareArgs: false,
57
- createArgs: false,
58
- attributeHook: false,
59
- elementHook: false,
60
- createCaller: false,
61
- dynamicScope: true,
62
- updateHook: false,
63
- createInstance: true,
64
- wrapped: false,
65
- willDestroy: false,
66
- hasSubOwner: false
67
- };
68
- const CAPABILITIES_MASK$1 = capabilityFlagsFrom(CAPABILITIES$2);
69
- class OutletComponentManager {
70
- create(_owner, definition, _args, env, dynamicScope) {
71
- let parentStateRef = dynamicScope.get('outletState');
72
- let currentStateRef = definition.ref;
73
-
74
- // This is the actual primary responsibility of the outlet component –
75
- // it represents the switching from one route component/template into
76
- // the next. The rest only exists to support the debug render tree and
77
- // the old-school (and unreliable) instrumentation.
78
- dynamicScope.set('outletState', currentStateRef);
79
- let state = {
80
- finalize: _instrumentStart('render.outlet', instrumentationPayload$1, definition)
81
- };
82
- if (env.debugRenderTree !== undefined) {
83
- let parentState = valueForRef(parentStateRef);
84
- let parentOwner = parentState?.render?.owner;
85
- let currentState = valueForRef(currentStateRef);
86
- let currentOwner = currentState?.render?.owner;
87
- if (parentOwner && parentOwner !== currentOwner) {
88
- let engineInstance = currentOwner;
89
- let {
90
- mountPoint
91
- } = engineInstance;
92
- if (mountPoint) {
93
- state.engine = {
94
- mountPoint,
95
- instance: engineInstance
96
- };
97
- }
98
- }
99
- }
100
- return state;
101
- }
102
- getDebugName({
103
- name
104
- }) {
105
- return `{{outlet}} for ${name}`;
106
- }
107
- getDebugCustomRenderTree(_definition, state) {
108
- let nodes = [];
109
- nodes.push({
110
- bucket: state,
111
- type: 'outlet',
112
- // "main" used to be the outlet name, keeping it around for compatibility
113
- name: 'main',
114
- args: EMPTY_ARGS,
115
- instance: undefined
116
- });
117
- if (state.engine) {
118
- nodes.push({
119
- bucket: state.engine,
120
- type: 'engine',
121
- name: state.engine.mountPoint,
122
- args: EMPTY_ARGS,
123
- instance: state.engine.instance
124
- });
69
+ const inElementNullCheckHelper = internalHelper(helper);
70
+
71
+ const normalizeClassHelper = internalHelper(({
72
+ positional
73
+ }) => {
74
+ return createComputeRef(() => {
75
+ let classNameArg = positional[0];
76
+ let valueArg = positional[1];
77
+ let classNameParts = valueForRef(classNameArg).split('.');
78
+ let className = classNameParts[classNameParts.length - 1];
79
+ let value = valueForRef(valueArg);
80
+ if (value === true) {
81
+ return dasherize(className);
82
+ } else if (!value && value !== 0) {
83
+ return '';
84
+ } else {
85
+ return String(value);
125
86
  }
126
- return nodes;
127
- }
128
- getCapabilities() {
129
- return CAPABILITIES$2;
130
- }
131
- getSelf() {
132
- return UNDEFINED_REFERENCE;
133
- }
134
- didCreate() {}
135
- didUpdate() {}
136
- didRenderLayout(state) {
137
- state.finalize();
138
- }
139
- didUpdateLayout() {}
140
- getDestroyable() {
141
- return null;
142
- }
143
- }
144
- const OUTLET_MANAGER = new OutletComponentManager();
145
- const OUTLET_COMPONENT_TEMPLATE = templateFactory(
146
- /*
147
- <@Component @controller={{@controller}} @model={{@model}} />
87
+ });
88
+ });
89
+
90
+ /**
91
+ @module ember
148
92
  */
149
- {
150
- "id": null,
151
- "block": "[[[8,[30,1],null,[[\"@controller\",\"@model\"],[[30,2],[30,3]]],null]],[\"@Component\",\"@controller\",\"@model\"],[]]",
152
- "moduleName": "(unknown template module)",
153
- "isStrictMode": true
93
+
94
+ const resolve = internalHelper(({
95
+ positional
96
+ }, owner) => {
97
+ let fullNameRef = positional[0];
98
+ let fullName = valueForRef(fullNameRef);
99
+ return createConstRef(owner.factoryFor(fullName)?.class);
154
100
  });
155
- class OutletComponent {
156
- // handle is not used by this custom definition
157
- handle = -1;
158
- resolvedName = null;
159
- manager = OUTLET_MANAGER;
160
- capabilities = CAPABILITIES_MASK$1;
161
- compilable;
162
- constructor(owner, state) {
163
- this.state = state;
164
- this.compilable = unwrapTemplate(OUTLET_COMPONENT_TEMPLATE(owner)).asLayout();
165
- }
166
- }
167
- function createRootOutlet(outletView) {
168
- return new OutletComponent(outletView.owner, outletView.state);
169
- }
170
101
 
171
- class RootComponentManager extends CurlyComponentManager {
172
- component;
173
- constructor(component) {
174
- super();
175
- this.component = component;
176
- }
177
- create(_owner, _state, _args, {
178
- isInteractive
179
- }, dynamicScope) {
180
- let component = this.component;
181
- let finalizer = _instrumentStart('render.component', initialRenderInstrumentDetails, component);
182
- dynamicScope.view = component;
183
- let hasWrappedElement = component.tagName !== '';
184
-
185
- // We usually do this in the `didCreateElement`, but that hook doesn't fire for tagless components
186
- if (!hasWrappedElement) {
187
- if (isInteractive) {
188
- component.trigger('willRender');
189
- }
190
- component._transitionTo('hasElement');
191
- if (isInteractive) {
192
- component.trigger('willInsertElement');
193
- }
194
- }
195
- let bucket = new ComponentStateBucket(component, null, CONSTANT_TAG, finalizer, hasWrappedElement, isInteractive);
196
- consumeTag(component[DIRTY_TAG]);
197
- return bucket;
198
- }
199
- }
102
+ /**
103
+ @module ember
104
+ */
200
105
 
201
- // ROOT is the top-level template it has nothing but one yield.
202
- // it is supposed to have a dummy element
203
- const ROOT_CAPABILITIES = {
204
- dynamicLayout: true,
205
- dynamicTag: true,
206
- prepareArgs: false,
207
- createArgs: false,
208
- attributeHook: true,
209
- elementHook: true,
210
- createCaller: true,
211
- dynamicScope: true,
212
- updateHook: true,
213
- createInstance: true,
214
- wrapped: true,
215
- willDestroy: false,
216
- hasSubOwner: false
217
- };
218
- class RootComponentDefinition {
219
- // handle is not used by this custom definition
220
- handle = -1;
221
- resolvedName = '-top-level';
222
- state;
223
- manager;
224
- capabilities = capabilityFlagsFrom(ROOT_CAPABILITIES);
225
- compilable = null;
226
- constructor(component) {
227
- this.manager = new RootComponentManager(component);
228
- let factory = getFactoryFor(component);
229
- this.state = factory;
230
- }
231
- }
106
+ /**
107
+ This reference is used to get the `[]` tag of iterables, so we can trigger
108
+ updates to `{{each}}` when it changes. It is put into place by a template
109
+ transform at build time, similar to the (-each-in) helper
110
+ */
111
+ const trackArray = internalHelper(({
112
+ positional
113
+ }) => {
114
+ const inner = positional[0];
115
+ return createComputeRef(() => {
116
+ let iterable = valueForRef(inner);
117
+ if (isObject(iterable)) {
118
+ consumeTag(tagForProperty(iterable, '[]'));
119
+ }
120
+ return iterable;
121
+ });
122
+ });
232
123
 
233
124
  /**
234
125
  @module ember
@@ -410,449 +301,90 @@ const eachIn = internalHelper(({
410
301
  });
411
302
  });
412
303
 
413
- function toIterator(iterable) {
414
- if (iterable instanceof EachInWrapper) {
415
- return toEachInIterator(iterable.inner);
416
- } else {
417
- return toEachIterator(iterable);
418
- }
419
- }
420
- function toEachInIterator(iterable) {
421
- if (!isIndexable(iterable)) {
422
- return null;
423
- }
424
- if (Array.isArray(iterable) || isEmberArray(iterable)) {
425
- return ObjectIterator.fromIndexable(iterable);
426
- } else if (isNativeIterable(iterable)) {
427
- return MapLikeNativeIterator.from(iterable);
428
- } else if (hasForEach(iterable)) {
429
- return ObjectIterator.fromForEachable(iterable);
430
- } else {
431
- return ObjectIterator.fromIndexable(iterable);
432
- }
433
- }
434
- function toEachIterator(iterable) {
435
- if (!isObject(iterable)) {
436
- return null;
437
- }
438
- if (Array.isArray(iterable)) {
439
- return ArrayIterator.from(iterable);
440
- } else if (isEmberArray(iterable)) {
441
- return EmberArrayIterator.from(iterable);
442
- } else if (isNativeIterable(iterable)) {
443
- return ArrayLikeNativeIterator.from(iterable);
444
- } else if (hasForEach(iterable)) {
445
- return ArrayIterator.fromForEachable(iterable);
446
- } else {
447
- return null;
448
- }
449
- }
450
- class BoundedIterator {
451
- position = 0;
452
- constructor(length) {
453
- this.length = length;
454
- }
455
- isEmpty() {
456
- return false;
304
+ /**
305
+ @module ember
306
+ */
307
+
308
+ /**
309
+ The `mut` helper is a shortcut for updating for args.
310
+
311
+ However, defining update functions on your backing class is preferable to using `mut`.
312
+
313
+ More directly: Don't use `mut`.
314
+
315
+ The `mut` helper, when used with `fn`, will return a function that
316
+ sets the value passed to `mut` to its first argument. As an example, we can create a
317
+ button that increments a value passing the value directly to the `fn`:
318
+
319
+ ```handlebars
320
+ <MyChild @childClickCount={{this.totalClicks}} @clickCountChange={{fn (mut this.totalClicks)}} />
321
+ ```
322
+
323
+ The child `Component` would invoke the function with the new click count:
324
+
325
+ ```app/components/my-child.gjs
326
+ import Component from '@glimmer/component';
327
+ import { action } from '@ember/object';
328
+
329
+ export default class MyChild extends Component {
330
+ @action
331
+ update() {
332
+ this.args.clickCountChange(this.args.childClickCount + 1);
333
+ }
334
+
335
+ <template>
336
+ <button {{on "click" this.update}}>
337
+ Click me!
338
+ </button>
339
+ </template>
457
340
  }
458
- memoFor(position) {
459
- return position;
341
+ ```
342
+
343
+ The `mut` helper changes the `totalClicks` value to what was provided as the `fn` argument.
344
+
345
+ @method mut
346
+ @param {Object} [attr] the "two-way" attribute that can be modified.
347
+ @for Ember.Templates.helpers
348
+ @public
349
+ */
350
+
351
+ const mut = internalHelper(({
352
+ positional
353
+ }) => {
354
+ let ref = positional[0];
355
+ return createInvokableRef(ref);
356
+ });
357
+
358
+ /**
359
+ @module ember
360
+ */
361
+
362
+
363
+ /**
364
+ The `readonly` helper let's you specify that a binding is one-way only,
365
+ instead of two-way.
366
+
367
+ This is a vestigial helper from the days of `@ember/component` and does not apply to
368
+ components extending from `@glimmer/component`.
369
+
370
+ When you pass a `readonly` binding from an outer context (e.g. parent component),
371
+ to to an inner context (e.g. child component), you are saying that changing that
372
+ property in the inner context does not change the value in the outer context.
373
+
374
+ To specify that a binding is read-only, when invoking the child `Component`:
375
+
376
+ ```app/components/my-parent.js
377
+ export default class MyParent extends Component {
378
+ totalClicks = 3;
460
379
  }
461
- next() {
462
- let {
463
- length,
464
- position
465
- } = this;
466
- if (position >= length) {
467
- return null;
468
- }
469
- let value = this.valueFor(position);
470
- let memo = this.memoFor(position);
471
- this.position++;
472
- return {
473
- value,
474
- memo
475
- };
476
- }
477
- }
478
- class ArrayIterator extends BoundedIterator {
479
- static from(iterable) {
480
- return iterable.length > 0 ? new this(iterable) : null;
481
- }
482
- static fromForEachable(object) {
483
- let array = [];
484
- object.forEach(item => array.push(item));
485
- return this.from(array);
486
- }
487
- constructor(array) {
488
- super(array.length);
489
- this.array = array;
490
- }
491
- valueFor(position) {
492
- return this.array[position];
493
- }
494
- }
495
- class EmberArrayIterator extends BoundedIterator {
496
- static from(iterable) {
497
- return iterable.length > 0 ? new this(iterable) : null;
498
- }
499
- constructor(array) {
500
- super(array.length);
501
- this.array = array;
502
- }
503
- valueFor(position) {
504
- return objectAt(this.array, position);
505
- }
506
- }
507
- class ObjectIterator extends BoundedIterator {
508
- static fromIndexable(obj) {
509
- let keys = Object.keys(obj);
510
- if (keys.length === 0) {
511
- return null;
512
- } else {
513
- let values = [];
514
- for (let key of keys) {
515
- let value;
516
- value = obj[key];
517
-
518
- // Add the tag of the returned value if it is an array, since arrays
519
- // should always cause updates if they are consumed and then changed
520
- if (isTracking()) {
521
- consumeTag(tagFor(obj, key));
522
- if (Array.isArray(value)) {
523
- consumeTag(tagFor(value, '[]'));
524
- }
525
- }
526
- values.push(value);
527
- }
528
- return new this(keys, values);
529
- }
530
- }
531
- static fromForEachable(obj) {
532
- let keys = [];
533
- let values = [];
534
- let length = 0;
535
- let isMapLike = false;
536
-
537
- // Not using an arrow function here so we can get an accurate `arguments`
538
- obj.forEach(function (value, key) {
539
- isMapLike = isMapLike || arguments.length >= 2;
540
- if (isMapLike) {
541
- keys.push(key);
542
- }
543
- values.push(value);
544
- length++;
545
- });
546
- if (length === 0) {
547
- return null;
548
- } else if (isMapLike) {
549
- return new this(keys, values);
550
- } else {
551
- return new ArrayIterator(values);
552
- }
553
- }
554
- constructor(keys, values) {
555
- super(values.length);
556
- this.keys = keys;
557
- this.values = values;
558
- }
559
- valueFor(position) {
560
- return this.values[position];
561
- }
562
- memoFor(position) {
563
- return this.keys[position];
564
- }
565
- }
566
- class NativeIterator {
567
- static from(iterable) {
568
- let iterator = iterable[Symbol.iterator]();
569
- let result = iterator.next();
570
- let {
571
- done
572
- } = result;
573
- if (done) {
574
- return null;
575
- } else {
576
- return new this(iterator, result);
577
- }
578
- }
579
- position = 0;
580
- constructor(iterable, result) {
581
- this.iterable = iterable;
582
- this.result = result;
583
- }
584
- isEmpty() {
585
- return false;
586
- }
587
- next() {
588
- let {
589
- iterable,
590
- result,
591
- position
592
- } = this;
593
- if (result.done) {
594
- return null;
595
- }
596
- let value = this.valueFor(result, position);
597
- let memo = this.memoFor(result, position);
598
- this.position++;
599
- this.result = iterable.next();
600
- return {
601
- value,
602
- memo
603
- };
604
- }
605
- }
606
- class ArrayLikeNativeIterator extends NativeIterator {
607
- valueFor(result) {
608
- return result.value;
609
- }
610
- memoFor(_result, position) {
611
- return position;
612
- }
613
- }
614
- class MapLikeNativeIterator extends NativeIterator {
615
- valueFor(result) {
616
- return result.value[1];
617
- }
618
- memoFor(result) {
619
- return result.value[0];
620
- }
621
- }
622
- function hasForEach(value) {
623
- return value != null && typeof value['forEach'] === 'function';
624
- }
625
- function isNativeIterable(value) {
626
- return value != null && typeof value[Symbol.iterator] === 'function';
627
- }
628
- function isIndexable(value) {
629
- return value !== null && (typeof value === 'object' || typeof value === 'function');
630
- }
631
-
632
- function toBool(predicate) {
633
- if (isProxy(predicate)) {
634
- consumeTag(tagForProperty(predicate, 'content'));
635
- return Boolean(get(predicate, 'isTruthy'));
636
- } else if (isArray(predicate)) {
637
- consumeTag(tagForProperty(predicate, '[]'));
638
- return predicate.length !== 0;
639
- } else if (isHTMLSafe(predicate)) {
640
- return Boolean(predicate.toString());
641
- } else {
642
- return Boolean(predicate);
643
- }
644
- }
645
-
646
- ///////////
647
-
648
- // Setup global context
649
-
650
- setGlobalContext({
651
- scheduleRevalidate() {
652
- _backburner.ensureInstance();
653
- },
654
- toBool,
655
- toIterator,
656
- getProp: _getProp,
657
- setProp: _setProp,
658
- getPath: get,
659
- setPath: set,
660
- scheduleDestroy(destroyable, destructor) {
661
- schedule('actions', null, destructor, destroyable);
662
- },
663
- scheduleDestroyed(finalizeDestructor) {
664
- schedule('destroy', null, finalizeDestructor);
665
- },
666
- warnIfStyleNotTrusted(value) {
667
- },
668
- assert(test, msg, options) {
669
- },
670
- deprecate(msg, test, options) {
671
- }
672
- });
673
-
674
- ///////////
675
-
676
- // Define environment delegate
677
-
678
- class EmberEnvironmentDelegate {
679
- enableDebugTooling = ENV._DEBUG_RENDER_TREE;
680
- constructor(owner, isInteractive) {
681
- this.owner = owner;
682
- this.isInteractive = isInteractive;
683
- }
684
- onTransactionCommit() {}
685
- }
686
-
687
- /**
688
- @module ember
689
- */
690
- const disallowDynamicResolution = internalHelper(({
691
- positional,
692
- named
693
- }) => {
694
- const nameOrValueRef = positional[0];
695
- let typeRef = named['type'];
696
- let locRef = named['loc'];
697
- let originalRef = named['original'];
698
- // assert('[BUG] expecting a string literal for the `type` argument', isConstRef(typeRef));
699
- // assert('[BUG] expecting a string literal for the `loc` argument', isConstRef(locRef));
700
- // assert('[BUG] expecting a string literal for the `original` argument', isConstRef(originalRef));
701
- valueForRef(typeRef);
702
- valueForRef(locRef);
703
- valueForRef(originalRef);
704
- return createComputeRef(() => {
705
- let nameOrValue = valueForRef(nameOrValueRef);
706
- return nameOrValue;
707
- });
708
- });
709
-
710
- let helper;
711
- {
712
- helper = args => {
713
- let arg = args.positional[0];
714
- return arg;
715
- };
716
- }
717
- const inElementNullCheckHelper = internalHelper(helper);
718
-
719
- const normalizeClassHelper = internalHelper(({
720
- positional
721
- }) => {
722
- return createComputeRef(() => {
723
- let classNameArg = positional[0];
724
- let valueArg = positional[1];
725
- let classNameParts = valueForRef(classNameArg).split('.');
726
- let className = classNameParts[classNameParts.length - 1];
727
- let value = valueForRef(valueArg);
728
- if (value === true) {
729
- return dasherize(className);
730
- } else if (!value && value !== 0) {
731
- return '';
732
- } else {
733
- return String(value);
734
- }
735
- });
736
- });
737
-
738
- /**
739
- @module ember
740
- */
741
-
742
- const resolve = internalHelper(({
743
- positional
744
- }, owner) => {
745
- let fullNameRef = positional[0];
746
- let fullName = valueForRef(fullNameRef);
747
- return createConstRef(owner.factoryFor(fullName)?.class);
748
- });
749
-
750
- /**
751
- @module ember
752
- */
753
-
754
- /**
755
- This reference is used to get the `[]` tag of iterables, so we can trigger
756
- updates to `{{each}}` when it changes. It is put into place by a template
757
- transform at build time, similar to the (-each-in) helper
758
- */
759
- const trackArray = internalHelper(({
760
- positional
761
- }) => {
762
- const inner = positional[0];
763
- return createComputeRef(() => {
764
- let iterable = valueForRef(inner);
765
- if (isObject(iterable)) {
766
- consumeTag(tagForProperty(iterable, '[]'));
767
- }
768
- return iterable;
769
- });
770
- });
771
-
772
- /**
773
- @module ember
774
- */
775
-
776
- /**
777
- The `mut` helper is a shortcut for updating for args.
778
-
779
- However, defining update functions on your backing class is preferable to using `mut`.
780
-
781
- More directly: Don't use `mut`.
782
-
783
- The `mut` helper, when used with `fn`, will return a function that
784
- sets the value passed to `mut` to its first argument. As an example, we can create a
785
- button that increments a value passing the value directly to the `fn`:
786
-
787
- ```handlebars
788
- <MyChild @childClickCount={{this.totalClicks}} @clickCountChange={{fn (mut this.totalClicks)}} />
789
- ```
790
-
791
- The child `Component` would invoke the function with the new click count:
792
-
793
- ```app/components/my-child.gjs
794
- import Component from '@glimmer/component';
795
- import { action } from '@ember/object';
796
-
797
- export default class MyChild extends Component {
798
- @action
799
- update() {
800
- this.args.clickCountChange(this.args.childClickCount + 1);
801
- }
802
-
803
- <template>
804
- <button {{on "click" this.update}}>
805
- Click me!
806
- </button>
807
- </template>
808
- }
809
- ```
810
-
811
- The `mut` helper changes the `totalClicks` value to what was provided as the `fn` argument.
812
-
813
- @method mut
814
- @param {Object} [attr] the "two-way" attribute that can be modified.
815
- @for Ember.Templates.helpers
816
- @public
817
- */
818
-
819
- const mut = internalHelper(({
820
- positional
821
- }) => {
822
- let ref = positional[0];
823
- return createInvokableRef(ref);
824
- });
825
-
826
- /**
827
- @module ember
828
- */
829
-
830
-
831
- /**
832
- The `readonly` helper let's you specify that a binding is one-way only,
833
- instead of two-way.
834
-
835
- This is a vestigial helper from the days of `@ember/component` and does not apply to
836
- components extending from `@glimmer/component`.
837
-
838
- When you pass a `readonly` binding from an outer context (e.g. parent component),
839
- to to an inner context (e.g. child component), you are saying that changing that
840
- property in the inner context does not change the value in the outer context.
841
-
842
- To specify that a binding is read-only, when invoking the child `Component`:
843
-
844
- ```app/components/my-parent.js
845
- export default class MyParent extends Component {
846
- totalClicks = 3;
847
- }
848
- ```
849
-
850
- Now, when you update `childClickCount`:
851
-
852
- ```app/components/my-child.js
853
- export default class MyChild extends Component {
854
- click() {
855
- this.incrementProperty('childClickCount');
380
+ ```
381
+
382
+ Now, when you update `childClickCount`:
383
+
384
+ ```app/components/my-child.js
385
+ export default class MyChild extends Component {
386
+ click() {
387
+ this.incrementProperty('childClickCount');
856
388
  }
857
389
  }
858
390
  ```
@@ -939,478 +471,52 @@ const mut = internalHelper(({
939
471
  @for Ember.Templates.helpers
940
472
  @private
941
473
  */
942
- const readonly = internalHelper(({
943
- positional
944
- }) => {
945
- let firstArg = positional[0];
946
- return createReadOnlyRef(firstArg);
947
- });
948
-
949
- /**
950
- @module ember
951
- */
952
-
953
-
954
- /**
955
- The `{{unbound}}` helper disconnects the one-way binding of a property,
956
- essentially freezing its value at the moment of rendering. For example,
957
- in this example the display of the variable `name` will not change even
958
- if it is set with a new value:
959
-
960
- ```handlebars
961
- {{unbound this.name}}
962
- ```
963
-
964
- Like any helper, the `unbound` helper can accept a nested helper expression.
965
- This allows for custom helpers to be rendered unbound:
966
-
967
- ```handlebars
968
- {{unbound (some-custom-helper)}}
969
- {{unbound (capitalize this.name)}}
970
- {{! You can use any helper, including unbound, in a nested expression }}
971
- {{capitalize (unbound this.name)}}
972
- ```
973
-
974
- The `unbound` helper only accepts a single argument, and it return an
975
- unbound value.
976
-
977
- @method unbound
978
- @for Ember.Templates.helpers
979
- @public
980
- */
981
-
982
- const unbound = internalHelper(({
983
- positional,
984
- named
985
- }) => {
986
- return createUnboundRef(valueForRef(positional[0]));
987
- });
988
-
989
- const CAPABILITIES$1 = {
990
- dynamicLayout: true,
991
- dynamicTag: false,
992
- prepareArgs: false,
993
- createArgs: true,
994
- attributeHook: false,
995
- elementHook: false,
996
- createCaller: true,
997
- dynamicScope: true,
998
- updateHook: true,
999
- createInstance: true,
1000
- wrapped: false,
1001
- willDestroy: false,
1002
- hasSubOwner: true
1003
- };
1004
- class MountManager {
1005
- getDynamicLayout(state) {
1006
- let templateFactory = state.engine.lookup('template:application');
1007
- return unwrapTemplate(templateFactory(state.engine)).asLayout();
1008
- }
1009
- getCapabilities() {
1010
- return CAPABILITIES$1;
1011
- }
1012
- getOwner(state) {
1013
- return state.engine;
1014
- }
1015
- create(owner, {
1016
- name
1017
- }, args, env) {
1018
- let engine = owner.buildChildEngineInstance(name);
1019
- engine.boot();
1020
- let applicationFactory = engine.factoryFor(`controller:application`);
1021
- let controllerFactory = applicationFactory || generateControllerFactory(engine, 'application');
1022
- let controller;
1023
- let self;
1024
- let bucket;
1025
- let modelRef;
1026
- if (args.named.has('model')) {
1027
- modelRef = args.named.get('model');
1028
- }
1029
- if (modelRef === undefined) {
1030
- controller = controllerFactory.create();
1031
- self = createConstRef(controller);
1032
- bucket = {
1033
- engine,
1034
- controller,
1035
- self,
1036
- modelRef
1037
- };
1038
- } else {
1039
- let model = valueForRef(modelRef);
1040
- controller = controllerFactory.create({
1041
- model
1042
- });
1043
- self = createConstRef(controller);
1044
- bucket = {
1045
- engine,
1046
- controller,
1047
- self,
1048
- modelRef
1049
- };
1050
- }
1051
- if (env.debugRenderTree) {
1052
- associateDestroyableChild(engine, controller);
1053
- }
1054
- return bucket;
1055
- }
1056
- getDebugName({
1057
- name
1058
- }) {
1059
- return name;
1060
- }
1061
- getDebugCustomRenderTree(definition, state, args) {
1062
- return [{
1063
- bucket: state.engine,
1064
- instance: state.engine,
1065
- type: 'engine',
1066
- name: definition.name,
1067
- args
1068
- }, {
1069
- bucket: state.controller,
1070
- instance: state.controller,
1071
- type: 'route-template',
1072
- name: 'application',
1073
- args
1074
- }];
1075
- }
1076
- getSelf({
1077
- self
1078
- }) {
1079
- return self;
1080
- }
1081
- getDestroyable(bucket) {
1082
- return bucket.engine;
1083
- }
1084
- didCreate() {}
1085
- didUpdate() {}
1086
- didRenderLayout() {}
1087
- didUpdateLayout() {}
1088
- update(bucket) {
1089
- let {
1090
- controller,
1091
- modelRef
1092
- } = bucket;
1093
- if (modelRef !== undefined) {
1094
- controller.set('model', valueForRef(modelRef));
1095
- }
1096
- }
1097
- }
1098
- const MOUNT_MANAGER = new MountManager();
1099
- class MountDefinition {
1100
- // handle is not used by this custom definition
1101
- handle = -1;
1102
- state;
1103
- manager = MOUNT_MANAGER;
1104
- compilable = null;
1105
- capabilities = capabilityFlagsFrom(CAPABILITIES$1);
1106
- constructor(resolvedName) {
1107
- this.resolvedName = resolvedName;
1108
- this.state = {
1109
- name: resolvedName
1110
- };
1111
- }
1112
- }
1113
-
1114
- /**
1115
- @module ember
1116
- */
1117
-
1118
-
1119
- /**
1120
- The `{{mount}}` helper lets you embed a routeless engine in a template.
1121
- Mounting an engine will cause an instance to be booted and its `application`
1122
- template to be rendered.
1123
-
1124
- For example, the following template mounts the `ember-chat` engine:
1125
-
1126
- ```app/templates/application.gjs
1127
- {{mount "ember-chat"}}
1128
- ```
1129
-
1130
- Additionally, you can also pass in a `model` argument that will be
1131
- set as the engines model. This can be an existing object:
1132
-
1133
- ```hbs
1134
- <div>
1135
- {{mount 'admin' model=userSettings}}
1136
- </div>
1137
- ```
1138
-
1139
- Or an inline `hash`, and you can even pass components:
1140
-
1141
- ```gjs
1142
- import SignInButton from '../components/sign-in-button';
1143
- <template>
1144
- <div>
1145
- <h1>Application template!</h1>
1146
- {{mount 'admin' model=(hash
1147
- title='Secret Admin'
1148
- signInButton=SignInButton
1149
- )}}
1150
- </div>
1151
- </template>
1152
- ```
1153
-
1154
- `mount` is built-in and does not need to be imported.
1155
-
1156
- @method mount
1157
- @param {String} name Name of the engine to mount.
1158
- @param {Object} [model] Object that will be set as
1159
- the model of the engine.
1160
- @for Ember.Templates.helpers
1161
- @public
1162
- */
1163
- const mountHelper = internalHelper((args, owner) => {
1164
- let nameRef = args.positional[0];
1165
- let captured;
1166
- captured = createCapturedArgs(args.named, EMPTY_POSITIONAL);
1167
- let lastName, lastDef;
1168
- return createComputeRef(() => {
1169
- let name = valueForRef(nameRef);
1170
- if (typeof name === 'string') {
1171
- if (lastName === name) {
1172
- return lastDef;
1173
- }
1174
- lastName = name;
1175
- lastDef = curry(0, new MountDefinition(name), owner, captured, true);
1176
- return lastDef;
1177
- } else {
1178
- lastDef = null;
1179
- lastName = null;
1180
- return null;
1181
- }
1182
- });
474
+ const readonly = internalHelper(({
475
+ positional
476
+ }) => {
477
+ let firstArg = positional[0];
478
+ return createReadOnlyRef(firstArg);
1183
479
  });
1184
480
 
1185
- const CAPABILITIES = {
1186
- dynamicLayout: false,
1187
- dynamicTag: false,
1188
- prepareArgs: false,
1189
- createArgs: true,
1190
- attributeHook: false,
1191
- elementHook: false,
1192
- createCaller: false,
1193
- dynamicScope: false,
1194
- updateHook: false,
1195
- createInstance: true,
1196
- wrapped: false,
1197
- willDestroy: false,
1198
- hasSubOwner: false
1199
- };
1200
- const CAPABILITIES_MASK = capabilityFlagsFrom(CAPABILITIES);
1201
- class RouteTemplateManager {
1202
- create(_owner, _definition, args) {
1203
- let self = args.named.get('controller');
1204
- let controller = valueForRef(self);
1205
- return {
1206
- self,
1207
- controller
1208
- };
1209
- }
1210
- getSelf({
1211
- self
1212
- }) {
1213
- return self;
1214
- }
1215
- getDebugName({
1216
- name
1217
- }) {
1218
- return `route-template (${name})`;
1219
- }
1220
- getDebugCustomRenderTree({
1221
- name
1222
- }, state, args) {
1223
- return [{
1224
- bucket: state,
1225
- type: 'route-template',
1226
- name,
1227
- args,
1228
- instance: state.controller
1229
- }];
1230
- }
1231
- getCapabilities() {
1232
- return CAPABILITIES;
1233
- }
1234
- didRenderLayout() {}
1235
- didUpdateLayout() {}
1236
- didCreate() {}
1237
- didUpdate() {}
1238
- getDestroyable() {
1239
- return null;
1240
- }
1241
- }
1242
- const ROUTE_TEMPLATE_MANAGER = new RouteTemplateManager();
1243
-
1244
481
  /**
1245
- * This "upgrades" a route template into a invocable component. Conceptually
1246
- * it can be 1:1 for each unique `Template`, but it's also cheap to construct,
1247
- * so unless the stability is desirable for other reasons, it's probably not
1248
- * worth caching this.
1249
- */
1250
- class RouteTemplate {
1251
- // handle is not used by this custom definition
1252
- handle = -1;
1253
- resolvedName;
1254
- state;
1255
- manager = ROUTE_TEMPLATE_MANAGER;
1256
- capabilities = CAPABILITIES_MASK;
1257
- compilable;
1258
- constructor(name, template) {
1259
- let unwrapped = unwrapTemplate(template);
1260
- // TODO This actually seems inaccurate – it ultimately came from the
1261
- // outlet's name. Also, setting this overrides `getDebugName()` in that
1262
- // message. Is that desirable?
1263
- this.resolvedName = name;
1264
- this.state = {
1265
- name
1266
- };
1267
- this.compilable = unwrapped.asLayout();
1268
- }
1269
- }
482
+ @module ember
483
+ */
1270
484
 
1271
- // TODO a lot these fields are copied from the adjacent existing components
1272
- // implementation, haven't looked into who cares about `ComponentDefinition`
1273
- // and if it is appropriate here. It seems like this version is intended to
1274
- // be used with `curry` which probably isn't necessary here. It could be the
1275
- // case that we just want to do something more similar to `InternalComponent`
1276
- // (the one we used to implement `Input` and `LinkTo`). For now it follows
1277
- // the same pattern to get things going.
1278
- function makeRouteTemplate(owner, name, template) {
1279
- let routeTemplate = new RouteTemplate(name, template);
1280
- return curry(0, routeTemplate, owner, null, true);
1281
- }
1282
485
 
1283
486
  /**
1284
- The `{{outlet}}` helper lets you specify where a child route will render in
1285
- your template. An important use of the `{{outlet}}` helper is in your
1286
- application's `application.gjs` file:
487
+ The `{{unbound}}` helper disconnects the one-way binding of a property,
488
+ essentially freezing its value at the moment of rendering. For example,
489
+ in this example the display of the variable `name` will not change even
490
+ if it is set with a new value:
1287
491
 
1288
- ```app/templates/application.gjs
1289
- import MyHeader from '../components/my-header';
1290
- import MyFooter from '../components/my-footer';
1291
-
1292
- <template>
1293
- <MyHeader />
1294
-
1295
- <div class="my-dynamic-content">
1296
- <!-- this content will change based on the current route, which depends on the current URL -->
1297
- {{outlet}}
1298
- </div>
1299
-
1300
- <MyFooter />
1301
- </template>
492
+ ```handlebars
493
+ {{unbound this.name}}
494
+ ```
495
+
496
+ Like any helper, the `unbound` helper can accept a nested helper expression.
497
+ This allows for custom helpers to be rendered unbound:
498
+
499
+ ```handlebars
500
+ {{unbound (some-custom-helper)}}
501
+ {{unbound (capitalize this.name)}}
502
+ {{! You can use any helper, including unbound, in a nested expression }}
503
+ {{capitalize (unbound this.name)}}
1302
504
  ```
1303
505
 
1304
- See the [routing guide](https://guides.emberjs.com/release/routing/rendering-a-template/) for more
1305
- information on how your `route` interacts with the `{{outlet}}` helper.
1306
- Note: Your content __will not render__ if there isn't an `{{outlet}}` for it.
506
+ The `unbound` helper only accepts a single argument, and it return an
507
+ unbound value.
1307
508
 
1308
- `outlet` is built-in and does not need to be imported.
1309
-
1310
- @method outlet
509
+ @method unbound
1311
510
  @for Ember.Templates.helpers
1312
511
  @public
1313
512
  */
1314
- const outletHelper = internalHelper((_args, owner, scope) => {
1315
- let outletRef = createComputeRef(() => {
1316
- let state = valueForRef(scope.get('outletState'));
1317
- return state?.outlets?.main;
1318
- });
1319
- let lastState = null;
1320
- let outlet = null;
1321
- return createComputeRef(() => {
1322
- let outletState = valueForRef(outletRef);
1323
- let state = stateFor(outletRef, outletState);
1324
-
1325
- // This code is deliberately using the behavior in glimmer-vm where in
1326
- // <@Component />, the component is considered stabled via `===`, and
1327
- // will continue to re-render in-place as long as the `===` holds, but
1328
- // when it changes to a different object, it teardown the old component
1329
- // (running destructors, etc), and render the component in its place (or
1330
- // nothing if the new value is nullish. Here we are carefully exploiting
1331
- // that fact, and returns the same stable object so long as it is the
1332
- // same route, but return a different one when the route changes. On the
1333
- // other hand, changing the model only intentionally do not teardown the
1334
- // component and instead re-render in-place.
1335
- if (!isStable(state, lastState)) {
1336
- lastState = state;
1337
- if (state !== null) {
1338
- // If we are crossing an engine mount point, this is how the owner
1339
- // gets switched.
1340
- let outletOwner = outletState?.render?.owner ?? owner;
1341
- let named = dict();
1342
-
1343
- // Here we either have a raw template that needs to be normalized,
1344
- // or a component that we can render as-is. `RouteTemplate` upgrades
1345
- // the template into a component so we can have a unified code path.
1346
- // We still store the original `template` value, because we rely on
1347
- // its identity for the stability check, and the `RouteTemplate`
1348
- // wrapper doesn't dedup for us.
1349
- let template = state.template;
1350
- let component;
1351
- if (hasInternalComponentManager(template)) {
1352
- component = template;
1353
- } else {
1354
- component = makeRouteTemplate(outletOwner, state.name, template);
1355
- }
1356
-
1357
- // Component is stable for the lifetime of the outlet
1358
- named['Component'] = createConstRef(component);
1359
513
 
1360
- // Controller is stable for the lifetime of the outlet
1361
- named['controller'] = createConstRef(state.controller);
1362
-
1363
- // Create a ref for the model
1364
- let modelRef = childRefFromParts(outletRef, ['render', 'model']);
1365
-
1366
- // Store the value of the model
1367
- let model = valueForRef(modelRef);
1368
-
1369
- // Create a compute ref which we pass in as the `{{@model}}` reference
1370
- // for the outlet. This ref will update and return the value of the
1371
- // model _until_ the outlet itself changes. Once the outlet changes,
1372
- // dynamic scope also changes, and so the original model ref would not
1373
- // provide the correct updated value. So we stop updating and return
1374
- // the _last_ model value for that outlet.
1375
- named['model'] = createComputeRef(() => {
1376
- if (lastState === state) {
1377
- model = valueForRef(modelRef);
1378
- }
1379
- return model;
1380
- });
1381
- let args = createCapturedArgs(named, EMPTY_POSITIONAL);
1382
-
1383
- // Package up everything
1384
- outlet = curry(0, new OutletComponent(owner, state), outletOwner, args, true);
1385
- } else {
1386
- outlet = null;
1387
- }
1388
- }
1389
- return outlet;
1390
- });
514
+ const unbound = internalHelper(({
515
+ positional,
516
+ named
517
+ }) => {
518
+ return createUnboundRef(valueForRef(positional[0]));
1391
519
  });
1392
- function stateFor(ref, outlet) {
1393
- if (outlet === undefined) return null;
1394
- let render = outlet.render;
1395
- if (render === undefined) return null;
1396
- let template = render.template;
1397
- // The type doesn't actually allow for `null`, but if we make it past this
1398
- // point it is really important that we have _something_ to render. We could
1399
- // assert, but that is probably overly strict for very little to gain.
1400
- if (template === undefined || template === null) return null;
1401
- return {
1402
- ref,
1403
- name: render.name,
1404
- template,
1405
- controller: render.controller
1406
- };
1407
- }
1408
- function isStable(state, lastState) {
1409
- if (state === null || lastState === null) {
1410
- return false;
1411
- }
1412
- return state.template === lastState.template && state.controller === lastState.controller;
1413
- }
1414
520
 
1415
521
  function instrumentationPayload(name) {
1416
522
  return {
@@ -1450,8 +556,6 @@ const BUILTIN_KEYWORD_HELPERS = {
1450
556
  '-normalize-class': normalizeClassHelper,
1451
557
  '-resolve': resolve,
1452
558
  '-track-array': trackArray,
1453
- '-mount': mountHelper,
1454
- '-outlet': outletHelper,
1455
559
  '-in-el-null': inElementNullCheckHelper
1456
560
  };
1457
561
  const BUILTIN_HELPERS = {
@@ -1459,21 +563,19 @@ const BUILTIN_HELPERS = {
1459
563
  array,
1460
564
  concat,
1461
565
  fn,
1462
- get: get$1,
566
+ get,
1463
567
  hash,
1464
- 'unique-id': uniqueId
1465
- };
1466
- {
1467
- // Bug: this may be a quirk of our test setup?
568
+ 'unique-id': uniqueId,
1468
569
  // In prod builds, this is a no-op helper and is unused in practice. We shouldn't need
1469
570
  // to add it at all, but the current test build doesn't produce a "prod compiler", so
1470
571
  // we ended up running the debug-build for the template compliler in prod tests. Once
1471
- // that is fixed, this can be removed. For now, this allows the test to work and does
1472
- // not really harm anything, since it's just a no-op pass-through helper and the bytes
1473
- // has to be included anyway. In the future, perhaps we can avoid the latter by using
1474
- // `import(...)`?
1475
- BUILTIN_HELPERS['-disallow-dynamic-resolution'] = disallowDynamicResolution;
1476
- }
572
+ // that is fixed, this can be conditionally included only in DEBUG. For now, this
573
+ // allows the test to work and does not really harm anything, since it's just a no-op
574
+ // pass-through helper. Keeping it inside the object literal (rather than a top-level
575
+ // conditional assignment) keeps this module free of top-level side effects so that
576
+ // consumers that never resolve anything dynamically can tree-shake the whole table.
577
+ '-disallow-dynamic-resolution': disallowDynamicResolution
578
+ };
1477
579
 
1478
580
  // With the implementation of RFC #1006(https://rfcs.emberjs.com/id/1006-deprecate-action-template-helper), the `action` modifer was removed. It was the
1479
581
  // only built-in keyword modifier, so this object is currently empty.
@@ -1500,182 +602,357 @@ class ResolverImpl {
1500
602
  if (definition === undefined) {
1501
603
  return null;
1502
604
  }
1503
- if (typeof definition === 'function' && isClassicHelper(definition)) {
1504
- // For classic class based helpers, we need to pass the factoryFor result itself rather
1505
- // than the raw value (`factoryFor(...).class`). This is because injections are already
1506
- // bound in the factoryFor result, including type-based injections
605
+ if (typeof definition === 'function' && isClassicHelper(definition)) {
606
+ // For classic class based helpers, we need to pass the factoryFor result itself rather
607
+ // than the raw value (`factoryFor(...).class`). This is because injections are already
608
+ // bound in the factoryFor result, including type-based injections
609
+
610
+ // The classic helper manager is registered on the classic `Helper` base
611
+ // class; deriving it from the definition (rather than importing it from
612
+ // the module that defines `Helper`) keeps this module from pulling in
613
+ // the classic object model when no classic helpers are in use.
614
+ let manager = getInternalHelperManager(definition);
615
+ {
616
+ setInternalHelperManager(manager, factory);
617
+ }
618
+ return factory;
619
+ }
620
+ return definition;
621
+ }
622
+ lookupBuiltInHelper(name) {
623
+ return BUILTIN_KEYWORD_HELPERS[name] ?? null;
624
+ }
625
+ lookupModifier(name, owner) {
626
+ let builtin = BUILTIN_MODIFIERS[name];
627
+ if (builtin !== undefined) {
628
+ return builtin;
629
+ }
630
+ let modifier = owner.factoryFor(`modifier:${name}`);
631
+ if (modifier === undefined) {
632
+ return null;
633
+ }
634
+ return modifier.class || null;
635
+ }
636
+ lookupBuiltInModifier(name) {
637
+ return BUILTIN_KEYWORD_MODIFIERS[name] ?? null;
638
+ }
639
+ lookupComponent(name, owner) {
640
+ let pair = lookupComponentPair(owner, name);
641
+ if (pair === null) {
642
+ return null;
643
+ }
644
+ let template = null;
645
+ let key;
646
+ if (pair.component === null) {
647
+ key = template = pair.layout(owner);
648
+ } else {
649
+ key = pair.component;
650
+ }
651
+ let cachedComponentDefinition = this.componentDefinitionCache.get(key);
652
+ if (cachedComponentDefinition !== undefined) {
653
+ return cachedComponentDefinition;
654
+ }
655
+ if (template === null && pair.layout !== null) {
656
+ template = pair.layout(owner);
657
+ }
658
+ let finalizer = _instrumentStart('render.getComponentDefinition', instrumentationPayload, name);
659
+ let definition = null;
660
+ if (pair.component === null) {
661
+ definition = {
662
+ state: templateOnlyComponent(undefined, name),
663
+ manager: TEMPLATE_ONLY_COMPONENT_MANAGER,
664
+ template
665
+ };
666
+ } else {
667
+ let factory = pair.component;
668
+ let ComponentClass = factory.class;
669
+ let manager = getInternalComponentManager(ComponentClass);
670
+ definition = {
671
+ state: isCurlyManager(manager) ? factory : ComponentClass,
672
+ manager,
673
+ template
674
+ };
675
+ }
676
+ finalizer();
677
+ this.componentDefinitionCache.set(key, definition);
678
+ return definition;
679
+ }
680
+ }
681
+
682
+ function toIterator(iterable) {
683
+ if (iterable instanceof EachInWrapper) {
684
+ return toEachInIterator(iterable.inner);
685
+ } else {
686
+ return toEachIterator(iterable);
687
+ }
688
+ }
689
+ function toEachInIterator(iterable) {
690
+ if (!isIndexable(iterable)) {
691
+ return null;
692
+ }
693
+ if (Array.isArray(iterable) || isEmberArray(iterable)) {
694
+ return ObjectIterator.fromIndexable(iterable);
695
+ } else if (isNativeIterable(iterable)) {
696
+ return MapLikeNativeIterator.from(iterable);
697
+ } else if (hasForEach(iterable)) {
698
+ return ObjectIterator.fromForEachable(iterable);
699
+ } else {
700
+ return ObjectIterator.fromIndexable(iterable);
701
+ }
702
+ }
703
+ function toEachIterator(iterable) {
704
+ if (!isObject(iterable)) {
705
+ return null;
706
+ }
707
+ if (Array.isArray(iterable)) {
708
+ return ArrayIterator.from(iterable);
709
+ } else if (isEmberArray(iterable)) {
710
+ return EmberArrayIterator.from(iterable);
711
+ } else if (isNativeIterable(iterable)) {
712
+ return ArrayLikeNativeIterator.from(iterable);
713
+ } else if (hasForEach(iterable)) {
714
+ return ArrayIterator.fromForEachable(iterable);
715
+ } else {
716
+ return null;
717
+ }
718
+ }
719
+ class BoundedIterator {
720
+ position = 0;
721
+ constructor(length) {
722
+ this.length = length;
723
+ }
724
+ isEmpty() {
725
+ return false;
726
+ }
727
+ memoFor(position) {
728
+ return position;
729
+ }
730
+ next() {
731
+ let {
732
+ length,
733
+ position
734
+ } = this;
735
+ if (position >= length) {
736
+ return null;
737
+ }
738
+ let value = this.valueFor(position);
739
+ let memo = this.memoFor(position);
740
+ this.position++;
741
+ return {
742
+ value,
743
+ memo
744
+ };
745
+ }
746
+ }
747
+ class ArrayIterator extends BoundedIterator {
748
+ static from(iterable) {
749
+ return iterable.length > 0 ? new this(iterable) : null;
750
+ }
751
+ static fromForEachable(object) {
752
+ let array = [];
753
+ object.forEach(item => array.push(item));
754
+ return this.from(array);
755
+ }
756
+ constructor(array) {
757
+ super(array.length);
758
+ this.array = array;
759
+ }
760
+ valueFor(position) {
761
+ return this.array[position];
762
+ }
763
+ }
764
+ class EmberArrayIterator extends BoundedIterator {
765
+ static from(iterable) {
766
+ return iterable.length > 0 ? new this(iterable) : null;
767
+ }
768
+ constructor(array) {
769
+ super(array.length);
770
+ this.array = array;
771
+ }
772
+ valueFor(position) {
773
+ return objectAt(this.array, position);
774
+ }
775
+ }
776
+ class ObjectIterator extends BoundedIterator {
777
+ static fromIndexable(obj) {
778
+ let keys = Object.keys(obj);
779
+ if (keys.length === 0) {
780
+ return null;
781
+ } else {
782
+ let values = [];
783
+ for (let key of keys) {
784
+ let value;
785
+ value = obj[key];
786
+
787
+ // Add the tag of the returned value if it is an array, since arrays
788
+ // should always cause updates if they are consumed and then changed
789
+ if (isTracking()) {
790
+ consumeTag(tagFor(obj, key));
791
+ if (Array.isArray(value)) {
792
+ consumeTag(tagFor(value, '[]'));
793
+ }
794
+ }
795
+ values.push(value);
796
+ }
797
+ return new this(keys, values);
798
+ }
799
+ }
800
+ static fromForEachable(obj) {
801
+ let keys = [];
802
+ let values = [];
803
+ let length = 0;
804
+ let isMapLike = false;
1507
805
 
1508
- {
1509
- setInternalHelperManager(CLASSIC_HELPER_MANAGER, factory);
806
+ // Not using an arrow function here so we can get an accurate `arguments`
807
+ obj.forEach(function (value, key) {
808
+ isMapLike = isMapLike || arguments.length >= 2;
809
+ if (isMapLike) {
810
+ keys.push(key);
1510
811
  }
1511
- return factory;
812
+ values.push(value);
813
+ length++;
814
+ });
815
+ if (length === 0) {
816
+ return null;
817
+ } else if (isMapLike) {
818
+ return new this(keys, values);
819
+ } else {
820
+ return new ArrayIterator(values);
1512
821
  }
1513
- return definition;
1514
822
  }
1515
- lookupBuiltInHelper(name) {
1516
- return BUILTIN_KEYWORD_HELPERS[name] ?? null;
823
+ constructor(keys, values) {
824
+ super(values.length);
825
+ this.keys = keys;
826
+ this.values = values;
1517
827
  }
1518
- lookupModifier(name, owner) {
1519
- let builtin = BUILTIN_MODIFIERS[name];
1520
- if (builtin !== undefined) {
1521
- return builtin;
1522
- }
1523
- let modifier = owner.factoryFor(`modifier:${name}`);
1524
- if (modifier === undefined) {
1525
- return null;
1526
- }
1527
- return modifier.class || null;
828
+ valueFor(position) {
829
+ return this.values[position];
1528
830
  }
1529
- lookupBuiltInModifier(name) {
1530
- return BUILTIN_KEYWORD_MODIFIERS[name] ?? null;
831
+ memoFor(position) {
832
+ return this.keys[position];
1531
833
  }
1532
- lookupComponent(name, owner) {
1533
- let pair = lookupComponentPair(owner, name);
1534
- if (pair === null) {
834
+ }
835
+ class NativeIterator {
836
+ static from(iterable) {
837
+ let iterator = iterable[Symbol.iterator]();
838
+ let result = iterator.next();
839
+ let {
840
+ done
841
+ } = result;
842
+ if (done) {
1535
843
  return null;
1536
- }
1537
- let template = null;
1538
- let key;
1539
- if (pair.component === null) {
1540
- key = template = pair.layout(owner);
1541
- } else {
1542
- key = pair.component;
1543
- }
1544
- let cachedComponentDefinition = this.componentDefinitionCache.get(key);
1545
- if (cachedComponentDefinition !== undefined) {
1546
- return cachedComponentDefinition;
1547
- }
1548
- if (template === null && pair.layout !== null) {
1549
- template = pair.layout(owner);
1550
- }
1551
- let finalizer = _instrumentStart('render.getComponentDefinition', instrumentationPayload, name);
1552
- let definition = null;
1553
- if (pair.component === null) {
1554
- definition = {
1555
- state: templateOnlyComponent(undefined, name),
1556
- manager: TEMPLATE_ONLY_COMPONENT_MANAGER,
1557
- template
1558
- };
1559
844
  } else {
1560
- let factory = pair.component;
1561
- let ComponentClass = factory.class;
1562
- let manager = getInternalComponentManager(ComponentClass);
1563
- definition = {
1564
- state: isCurlyManager(manager) ? factory : ComponentClass,
1565
- manager,
1566
- template
1567
- };
845
+ return new this(iterator, result);
1568
846
  }
1569
- finalizer();
1570
- this.componentDefinitionCache.set(key, definition);
1571
- return definition;
1572
847
  }
1573
- }
1574
-
1575
- // We use the `InternalOwner` notion here because we actually need all of its
1576
- // API for using with renderers (normally, it will be `EngineInstance`).
1577
- // We use `getOwner` from our internal home for it rather than the narrower
1578
- // public API for the same reason.
1579
- const TOP_LEVEL_NAME = '-top-level';
1580
- class OutletView {
1581
- static extend(injections) {
1582
- return class extends OutletView {
1583
- static create(options) {
1584
- if (options) {
1585
- return super.create(Object.assign({}, injections, options));
1586
- } else {
1587
- return super.create(injections);
1588
- }
1589
- }
1590
- };
848
+ position = 0;
849
+ constructor(iterable, result) {
850
+ this.iterable = iterable;
851
+ this.result = result;
1591
852
  }
1592
- static reopenClass(injections) {
1593
- Object.assign(this, injections);
853
+ isEmpty() {
854
+ return false;
1594
855
  }
1595
- static create(options) {
856
+ next() {
1596
857
  let {
1597
- environment: _environment,
1598
- application: namespace,
1599
- template: templateFactory
1600
- } = options;
1601
- let owner = getOwner(options);
1602
- let template = templateFactory(owner);
1603
- return new OutletView(_environment, owner, template, namespace);
1604
- }
1605
- ref;
1606
- state;
1607
- constructor(_environment, owner, template, namespace) {
1608
- this._environment = _environment;
1609
- this.owner = owner;
1610
- this.template = template;
1611
- this.namespace = namespace;
1612
- let outletStateTag = createTag();
1613
- let outletState = {
1614
- outlets: {
1615
- main: undefined
1616
- },
1617
- render: {
1618
- owner: owner,
1619
- name: TOP_LEVEL_NAME,
1620
- controller: undefined,
1621
- model: undefined,
1622
- template
1623
- }
1624
- };
1625
- let ref = this.ref = createComputeRef(() => {
1626
- consumeTag(outletStateTag);
1627
- return outletState;
1628
- }, state => {
1629
- DIRTY_TAG$1(outletStateTag);
1630
- outletState.outlets['main'] = state;
1631
- });
1632
- this.state = {
1633
- ref,
1634
- name: TOP_LEVEL_NAME,
1635
- template,
1636
- controller: undefined
858
+ iterable,
859
+ result,
860
+ position
861
+ } = this;
862
+ if (result.done) {
863
+ return null;
864
+ }
865
+ let value = this.valueFor(result, position);
866
+ let memo = this.memoFor(result, position);
867
+ this.position++;
868
+ this.result = iterable.next();
869
+ return {
870
+ value,
871
+ memo
1637
872
  };
1638
873
  }
1639
- appendTo(selector) {
1640
- let target;
1641
- if (this._environment.hasDOM) {
1642
- target = typeof selector === 'string' ? document.querySelector(selector) : selector;
1643
- } else {
1644
- target = selector;
1645
- }
1646
- let renderer = this.owner.lookup('renderer:-dom');
1647
-
1648
- // SAFETY: It's not clear that this cast is safe.
1649
- // The types for appendOutletView may be incorrect or this is a potential bug.
1650
- schedule('render', renderer, 'appendOutletView', this, target);
874
+ }
875
+ class ArrayLikeNativeIterator extends NativeIterator {
876
+ valueFor(result) {
877
+ return result.value;
1651
878
  }
1652
- rerender() {
1653
- /**/
879
+ memoFor(_result, position) {
880
+ return position;
1654
881
  }
1655
- setOutletState(state) {
1656
- updateRef(this.ref, state);
882
+ }
883
+ class MapLikeNativeIterator extends NativeIterator {
884
+ valueFor(result) {
885
+ return result.value[1];
1657
886
  }
1658
- destroy() {
1659
- /**/
887
+ memoFor(result) {
888
+ return result.value[0];
1660
889
  }
1661
890
  }
891
+ function hasForEach(value) {
892
+ return value != null && typeof value['forEach'] === 'function';
893
+ }
894
+ function isNativeIterable(value) {
895
+ return value != null && typeof value[Symbol.iterator] === 'function';
896
+ }
897
+ function isIndexable(value) {
898
+ return value !== null && (typeof value === 'object' || typeof value === 'function');
899
+ }
1662
900
 
1663
- class DynamicScope {
1664
- constructor(view, outletState) {
1665
- this.view = view;
1666
- this.outletState = outletState;
1667
- }
1668
- child() {
1669
- return new DynamicScope(this.view, this.outletState);
901
+ function toBool(predicate) {
902
+ if (isProxy(predicate)) {
903
+ consumeTag(tagForProperty(predicate, 'content'));
904
+ return Boolean(get$1(predicate, 'isTruthy'));
905
+ } else if (isArray(predicate)) {
906
+ consumeTag(tagForProperty(predicate, '[]'));
907
+ return predicate.length !== 0;
908
+ } else if (isHTMLSafe(predicate)) {
909
+ return Boolean(predicate.toString());
910
+ } else {
911
+ return Boolean(predicate);
1670
912
  }
1671
- get(key) {
1672
- return this.outletState;
913
+ }
914
+
915
+ ///////////
916
+
917
+ // Setup global context
918
+
919
+ setGlobalContext({
920
+ scheduleRevalidate() {
921
+ _backburner.ensureInstance();
922
+ },
923
+ toBool,
924
+ toIterator,
925
+ getProp: _getProp,
926
+ setProp: _setProp,
927
+ getPath: get$1,
928
+ setPath: set,
929
+ scheduleDestroy(destroyable, destructor) {
930
+ schedule('actions', null, destructor, destroyable);
931
+ },
932
+ scheduleDestroyed(finalizeDestructor) {
933
+ schedule('destroy', null, finalizeDestructor);
934
+ },
935
+ warnIfStyleNotTrusted(value) {
936
+ },
937
+ assert(test, msg, options) {
938
+ },
939
+ deprecate(msg, test, options) {
1673
940
  }
1674
- set(key, value) {
1675
- this.outletState = value;
1676
- return value;
941
+ });
942
+
943
+ ///////////
944
+
945
+ // Define environment delegate
946
+
947
+ class EmberEnvironmentDelegate {
948
+ enableDebugTooling = ENV._DEBUG_RENDER_TREE;
949
+ constructor(owner, isInteractive) {
950
+ this.owner = owner;
951
+ this.isInteractive = isInteractive;
1677
952
  }
953
+ onTransactionCommit() {}
1678
954
  }
955
+
1679
956
  const NO_OP = () => {};
1680
957
 
1681
958
  // This wrapper logic prevents us from rerendering in case of a hard failure
@@ -1686,6 +963,13 @@ function errorLoopTransaction(fn) {
1686
963
  return fn;
1687
964
  }
1688
965
  }
966
+
967
+ /**
968
+ * The interface the `RendererState` needs from a render root. The base
969
+ * renderer only ever creates `ComponentRootState`s; the classic renderer
970
+ * (`./renderer`) adds `ClassicRootState` for outlet/classic-component roots.
971
+ */
972
+
1689
973
  class ComponentRootState {
1690
974
  type = 'component';
1691
975
  #result;
@@ -1703,7 +987,7 @@ class ComponentRootState {
1703
987
  });
1704
988
  });
1705
989
  }
1706
- isFor(_component) {
990
+ isFor(_possibleRoot) {
1707
991
  return false;
1708
992
  }
1709
993
  render() {
@@ -1719,61 +1003,6 @@ class ComponentRootState {
1719
1003
  return this.#result;
1720
1004
  }
1721
1005
  }
1722
- class ClassicRootState {
1723
- type = 'classic';
1724
- id;
1725
- result;
1726
- destroyed;
1727
- render;
1728
- env;
1729
- constructor(root, context, owner, template, self, parentElement, dynamicScope, builder) {
1730
- this.root = root;
1731
- this.id = root instanceof OutletView ? guidFor(root) : getViewId(root);
1732
- this.result = undefined;
1733
- this.destroyed = false;
1734
- this.env = context.env;
1735
- this.render = errorLoopTransaction(() => {
1736
- let layout = unwrapTemplate(template).asLayout();
1737
- let iterator = renderMain(context, owner, self, builder(context.env, {
1738
- element: parentElement,
1739
- nextSibling: null
1740
- }), layout, dynamicScope);
1741
- let result = this.result = iterator.sync();
1742
- associateDestroyableChild(this, result);
1743
- this.render = errorLoopTransaction(() => {
1744
- if (isDestroying(result) || isDestroyed(result)) return;
1745
- return result.rerender({
1746
- alwaysRevalidate: false
1747
- });
1748
- });
1749
- });
1750
- }
1751
- isFor(possibleRoot) {
1752
- return this.root === possibleRoot;
1753
- }
1754
- destroy() {
1755
- let {
1756
- result,
1757
- env
1758
- } = this;
1759
- this.destroyed = true;
1760
- this.root = null;
1761
- this.result = undefined;
1762
- this.render = undefined;
1763
- if (result !== undefined) {
1764
- /*
1765
- Handles these scenarios:
1766
- * When roots are removed during standard rendering process, a transaction exists already
1767
- `.begin()` / `.commit()` are not needed.
1768
- * When roots are being destroyed manually (`component.append(); component.destroy() case), no
1769
- transaction exists already.
1770
- * When roots are being destroyed during `Renderer#destroy`, no transaction exists
1771
- */
1772
-
1773
- inTransaction(env, () => destroy(result));
1774
- }
1775
- }
1776
- }
1777
1006
  const renderers = [];
1778
1007
  function _resetRenderers() {
1779
1008
  renderers.length = 0;
@@ -2164,138 +1393,6 @@ class BaseRenderer {
2164
1393
  rerender() {
2165
1394
  this.state.scheduleRevalidate(this);
2166
1395
  }
2167
-
2168
- // render(component: Component, options: { into: Cursor; args?: Record<string, unknown> }): void {
2169
- // this.state.renderRoot(component);
2170
- // }
2171
- }
2172
- class Renderer extends BaseRenderer {
2173
- static strict(owner, document, options) {
2174
- return new BaseRenderer(owner, {
2175
- hasDOM: hasDOM,
2176
- ...options
2177
- }, document, new ResolverImpl(), clientBuilder);
2178
- }
2179
- _rootTemplate;
2180
- _viewRegistry;
2181
- static create(props) {
2182
- let {
2183
- _viewRegistry
2184
- } = props;
2185
- let owner = getOwner(props);
2186
- let document = owner.lookup('service:-document');
2187
- let env = owner.lookup('-environment:main');
2188
- let rootTemplate = owner.lookup(privatize`template:-root`);
2189
- let builder = owner.lookup('service:-dom-builder');
2190
- return new this(owner, document, env, rootTemplate, _viewRegistry, builder);
2191
- }
2192
- constructor(owner, document, env, rootTemplate, viewRegistry, builder = clientBuilder, resolver = new ResolverImpl()) {
2193
- super(owner, env, document, resolver, builder);
2194
- this._rootTemplate = rootTemplate(owner);
2195
- this._viewRegistry = viewRegistry || owner.lookup('-view-registry:main');
2196
- }
2197
-
2198
- // renderer HOOKS
2199
-
2200
- appendOutletView(view, target) {
2201
- // TODO: This bypasses the {{outlet}} syntax so logically duplicates
2202
- // some of the set up code. Since this is all internal (or is it?),
2203
- // we can refactor this to do something more direct/less convoluted
2204
- // and with less setup, but get it working first
2205
- let outlet = createRootOutlet(view);
2206
- let {
2207
- name,
2208
- /* controller, */template
2209
- } = view.state;
2210
- let named = dict();
2211
- named['Component'] = createConstRef(makeRouteTemplate(view.owner, name, template));
2212
-
2213
- // TODO: is this guaranteed to be undefined? It seems to be the
2214
- // case in the `OutletView` class. Investigate how much that class
2215
- // exists as an internal implementation detail only, or if it was
2216
- // used outside of core. As far as I can tell, test-helpers uses
2217
- // it but only for `setOutletState`.
2218
- // named['controller'] = createConstRef(controller, '@controller');
2219
- // Update: at least according to the debug render tree tests, we
2220
- // appear to always expect this to be undefined. Not a definitive
2221
- // source by any means, but is useful evidence
2222
- named['controller'] = UNDEFINED_REFERENCE;
2223
- named['model'] = UNDEFINED_REFERENCE;
2224
- let args = createCapturedArgs(named, EMPTY_POSITIONAL);
2225
- this._appendDefinition(view, curry(0, outlet, view.owner, args, true), target);
2226
- }
2227
- appendTo(view, target) {
2228
- let definition = new RootComponentDefinition(view);
2229
- this._appendDefinition(view, curry(0, definition, this.state.owner, null, true), target);
2230
- }
2231
- _appendDefinition(root, definition, target) {
2232
- let self = createConstRef(definition);
2233
- let dynamicScope = new DynamicScope(null, UNDEFINED_REFERENCE);
2234
- let rootState = new ClassicRootState(root, this.state.context, this.state.owner, this._rootTemplate, self, target, dynamicScope, this.state.builder);
2235
- this.state.renderRoot(rootState, this);
2236
- }
2237
- cleanupRootFor(component) {
2238
- // no need to cleanup roots if we have already been destroyed
2239
- if (isDestroyed(this)) {
2240
- return;
2241
- }
2242
- let roots = this.state.roots;
2243
-
2244
- // traverse in reverse so we can remove items
2245
- // without mucking up the index
2246
- let i = roots.length;
2247
- while (i--) {
2248
- let root = roots[i];
2249
- if (root.type === 'classic' && root.isFor(component)) {
2250
- root.destroy();
2251
- roots.splice(i, 1);
2252
- }
2253
- }
2254
- }
2255
- remove(view) {
2256
- view._transitionTo('destroying');
2257
- this.cleanupRootFor(view);
2258
- if (this.state.isInteractive) {
2259
- view.trigger('didDestroyElement');
2260
- }
2261
- }
2262
- get _roots() {
2263
- return this.state.debug.roots;
2264
- }
2265
- get _inRenderTransaction() {
2266
- return this.state.debug.inRenderTransaction;
2267
- }
2268
- get _isInteractive() {
2269
- return this.state.debug.isInteractive;
2270
- }
2271
- get _context() {
2272
- return this.state.context;
2273
- }
2274
- register(view) {
2275
- let id = getViewId(view);
2276
- this._viewRegistry[id] = view;
2277
- }
2278
- unregister(view) {
2279
- delete this._viewRegistry[getViewId(view)];
2280
- }
2281
- getElement(component) {
2282
- if (this._isInteractive) {
2283
- return getViewElement(component);
2284
- } else {
2285
- throw new Error('Accessing `this.element` is not allowed in non-interactive environments (such as FastBoot).');
2286
- }
2287
- }
2288
- getBounds(component) {
2289
- let bounds = component[BOUNDS];
2290
- let parentElement = bounds.parentElement();
2291
- let firstNode = bounds.firstNode();
2292
- let lastNode = bounds.lastNode();
2293
- return {
2294
- parentElement,
2295
- firstNode,
2296
- lastNode
2297
- };
2298
- }
2299
1396
  }
2300
1397
 
2301
- export { OutletView as O, Renderer as R, _resetRenderers as _, renderSettled as a, outletHelper as o, renderComponent as r };
1398
+ export { BaseRenderer as B, ResolverImpl as R, _resetRenderers as _, renderSettled as a, errorLoopTransaction as e, renderComponent as r };