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
@@ -0,0 +1,886 @@
1
+ import { privatize } from '../@ember/-internals/container/index.js';
2
+ import { getOwner } from '../@ember/-internals/owner/index.js';
3
+ import { I as Input, T as Textarea } from './textarea-DOmZ1x0E.js';
4
+ import { LinkTo } from '../@ember/routing/index.js';
5
+ import { i as inTransaction, d as renderMain } from './render-Dx7lr1hR.js';
6
+ import { c as clientBuilder } from './api-CQexacBn.js';
7
+ import { r as rehydrationBuilder } from './rehydrate-builder-Blt1x9MP.js';
8
+ import { s as serializeBuilder } from './serialize-builder-BvAXYHTr.js';
9
+ import { g as guidFor } from './guid-Cbq2sNV_.js';
10
+ import { getViewId, getViewElement } from '../@ember/-internals/views/lib/system/utils.js';
11
+ import { associateDestroyableChild, isDestroyed, destroy, isDestroying } from '../@glimmer/destroyable/index.js';
12
+ import { a as createConstRef, v as valueForRef, c as createComputeRef, g as childRefFromParts, u as updateRef, U as UNDEFINED_REFERENCE } from './reference-CG0yPgLy.js';
13
+ import { c as createCapturedArgs, b as EMPTY_POSITIONAL, d as curry } from './arguments-BzAkZVBa.js';
14
+ import { d as dict } from './collections-GpG8lT2g.js';
15
+ import { C as CurlyComponentManager, i as initialRenderInstrumentDetails, a as ComponentStateBucket, D as DIRTY_TAG, u as unwrapTemplate, B as BOUNDS } from './curly-a6DP7r87.js';
16
+ import { O as OutletComponent, c as createRootOutlet } from './outlet--lIm3q7t.js';
17
+ import { g as getFactoryFor } from './container-BYOnjnwz.js';
18
+ import { _instrumentStart } from '../@ember/instrumentation/index.js';
19
+ import { c as capabilityFlagsFrom } from './capabilities-BuVYh-vx.js';
20
+ import { C as CONSTANT_TAG, c as consumeTag, D as DIRTY_TAG$1, r as createTag } from './cache-CofLhaS4.js';
21
+ import { R as ResolverImpl, B as BaseRenderer, e as errorLoopTransaction } from './index-npr2B-vu.js';
22
+ import { generateControllerFactory } from '../@ember/routing/lib/generate_controller.js';
23
+ import { i as internalHelper } from './internal-helper-Bz1lpDXr.js';
24
+ import { c as hasInternalComponentManager } from './api-DlJKfm_f.js';
25
+ import { schedule } from '../@ember/runloop/index.js';
26
+ import { t as templateFactory } from './index-Bf53M8eS.js';
27
+
28
+ const RootTemplate = templateFactory(
29
+ /*
30
+ {{component this}}
31
+ */
32
+ {
33
+ "id": null,
34
+ "block": "[[[46,[30,0],null,null,null]],[],[\"component\"]]",
35
+ "moduleName": "packages/@ember/-internals/glimmer/lib/templates/root.hbs",
36
+ "isStrictMode": true
37
+ });
38
+
39
+ class RootComponentManager extends CurlyComponentManager {
40
+ component;
41
+ constructor(component) {
42
+ super();
43
+ this.component = component;
44
+ }
45
+ create(_owner, _state, _args, {
46
+ isInteractive
47
+ }, dynamicScope) {
48
+ let component = this.component;
49
+ let finalizer = _instrumentStart('render.component', initialRenderInstrumentDetails, component);
50
+ dynamicScope.view = component;
51
+ let hasWrappedElement = component.tagName !== '';
52
+
53
+ // We usually do this in the `didCreateElement`, but that hook doesn't fire for tagless components
54
+ if (!hasWrappedElement) {
55
+ if (isInteractive) {
56
+ component.trigger('willRender');
57
+ }
58
+ component._transitionTo('hasElement');
59
+ if (isInteractive) {
60
+ component.trigger('willInsertElement');
61
+ }
62
+ }
63
+ let bucket = new ComponentStateBucket(component, null, CONSTANT_TAG, finalizer, hasWrappedElement, isInteractive);
64
+ consumeTag(component[DIRTY_TAG]);
65
+ return bucket;
66
+ }
67
+ }
68
+
69
+ // ROOT is the top-level template it has nothing but one yield.
70
+ // it is supposed to have a dummy element
71
+ const ROOT_CAPABILITIES = {
72
+ dynamicLayout: true,
73
+ dynamicTag: true,
74
+ prepareArgs: false,
75
+ createArgs: false,
76
+ attributeHook: true,
77
+ elementHook: true,
78
+ createCaller: true,
79
+ dynamicScope: true,
80
+ updateHook: true,
81
+ createInstance: true,
82
+ wrapped: true,
83
+ willDestroy: false,
84
+ hasSubOwner: false
85
+ };
86
+ class RootComponentDefinition {
87
+ // handle is not used by this custom definition
88
+ handle = -1;
89
+ resolvedName = '-top-level';
90
+ state;
91
+ manager;
92
+ capabilities = capabilityFlagsFrom(ROOT_CAPABILITIES);
93
+ compilable = null;
94
+ constructor(component) {
95
+ this.manager = new RootComponentManager(component);
96
+ let factory = getFactoryFor(component);
97
+ this.state = factory;
98
+ }
99
+ }
100
+
101
+ const CAPABILITIES$1 = {
102
+ dynamicLayout: true,
103
+ dynamicTag: false,
104
+ prepareArgs: false,
105
+ createArgs: true,
106
+ attributeHook: false,
107
+ elementHook: false,
108
+ createCaller: true,
109
+ dynamicScope: true,
110
+ updateHook: true,
111
+ createInstance: true,
112
+ wrapped: false,
113
+ willDestroy: false,
114
+ hasSubOwner: true
115
+ };
116
+ class MountManager {
117
+ getDynamicLayout(state) {
118
+ let templateFactory = state.engine.lookup('template:application');
119
+ return unwrapTemplate(templateFactory(state.engine)).asLayout();
120
+ }
121
+ getCapabilities() {
122
+ return CAPABILITIES$1;
123
+ }
124
+ getOwner(state) {
125
+ return state.engine;
126
+ }
127
+ create(owner, {
128
+ name
129
+ }, args, env) {
130
+ let engine = owner.buildChildEngineInstance(name);
131
+ engine.boot();
132
+ let applicationFactory = engine.factoryFor(`controller:application`);
133
+ let controllerFactory = applicationFactory || generateControllerFactory(engine, 'application');
134
+ let controller;
135
+ let self;
136
+ let bucket;
137
+ let modelRef;
138
+ if (args.named.has('model')) {
139
+ modelRef = args.named.get('model');
140
+ }
141
+ if (modelRef === undefined) {
142
+ controller = controllerFactory.create();
143
+ self = createConstRef(controller);
144
+ bucket = {
145
+ engine,
146
+ controller,
147
+ self,
148
+ modelRef
149
+ };
150
+ } else {
151
+ let model = valueForRef(modelRef);
152
+ controller = controllerFactory.create({
153
+ model
154
+ });
155
+ self = createConstRef(controller);
156
+ bucket = {
157
+ engine,
158
+ controller,
159
+ self,
160
+ modelRef
161
+ };
162
+ }
163
+ if (env.debugRenderTree) {
164
+ associateDestroyableChild(engine, controller);
165
+ }
166
+ return bucket;
167
+ }
168
+ getDebugName({
169
+ name
170
+ }) {
171
+ return name;
172
+ }
173
+ getDebugCustomRenderTree(definition, state, args) {
174
+ return [{
175
+ bucket: state.engine,
176
+ instance: state.engine,
177
+ type: 'engine',
178
+ name: definition.name,
179
+ args
180
+ }, {
181
+ bucket: state.controller,
182
+ instance: state.controller,
183
+ type: 'route-template',
184
+ name: 'application',
185
+ args
186
+ }];
187
+ }
188
+ getSelf({
189
+ self
190
+ }) {
191
+ return self;
192
+ }
193
+ getDestroyable(bucket) {
194
+ return bucket.engine;
195
+ }
196
+ didCreate() {}
197
+ didUpdate() {}
198
+ didRenderLayout() {}
199
+ didUpdateLayout() {}
200
+ update(bucket) {
201
+ let {
202
+ controller,
203
+ modelRef
204
+ } = bucket;
205
+ if (modelRef !== undefined) {
206
+ controller.set('model', valueForRef(modelRef));
207
+ }
208
+ }
209
+ }
210
+ const MOUNT_MANAGER = /*@__PURE__*/new MountManager();
211
+ class MountDefinition {
212
+ // handle is not used by this custom definition
213
+ handle = -1;
214
+ state;
215
+ manager = MOUNT_MANAGER;
216
+ compilable = null;
217
+ capabilities = capabilityFlagsFrom(CAPABILITIES$1);
218
+ constructor(resolvedName) {
219
+ this.resolvedName = resolvedName;
220
+ this.state = {
221
+ name: resolvedName
222
+ };
223
+ }
224
+ }
225
+
226
+ /**
227
+ @module ember
228
+ */
229
+
230
+
231
+ /**
232
+ The `{{mount}}` helper lets you embed a routeless engine in a template.
233
+ Mounting an engine will cause an instance to be booted and its `application`
234
+ template to be rendered.
235
+
236
+ For example, the following template mounts the `ember-chat` engine:
237
+
238
+ ```app/templates/application.gjs
239
+ {{mount "ember-chat"}}
240
+ ```
241
+
242
+ Additionally, you can also pass in a `model` argument that will be
243
+ set as the engines model. This can be an existing object:
244
+
245
+ ```hbs
246
+ <div>
247
+ {{mount 'admin' model=userSettings}}
248
+ </div>
249
+ ```
250
+
251
+ Or an inline `hash`, and you can even pass components:
252
+
253
+ ```gjs
254
+ import SignInButton from '../components/sign-in-button';
255
+ <template>
256
+ <div>
257
+ <h1>Application template!</h1>
258
+ {{mount 'admin' model=(hash
259
+ title='Secret Admin'
260
+ signInButton=SignInButton
261
+ )}}
262
+ </div>
263
+ </template>
264
+ ```
265
+
266
+ `mount` is built-in and does not need to be imported.
267
+
268
+ @method mount
269
+ @param {String} name Name of the engine to mount.
270
+ @param {Object} [model] Object that will be set as
271
+ the model of the engine.
272
+ @for Ember.Templates.helpers
273
+ @public
274
+ */
275
+ const mountHelper = /*@__PURE__*/internalHelper((args, owner) => {
276
+ let nameRef = args.positional[0];
277
+ let captured;
278
+ captured = createCapturedArgs(args.named, EMPTY_POSITIONAL);
279
+ let lastName, lastDef;
280
+ return createComputeRef(() => {
281
+ let name = valueForRef(nameRef);
282
+ if (typeof name === 'string') {
283
+ if (lastName === name) {
284
+ return lastDef;
285
+ }
286
+ lastName = name;
287
+ lastDef = curry(0, new MountDefinition(name), owner, captured, true);
288
+ return lastDef;
289
+ } else {
290
+ lastDef = null;
291
+ lastName = null;
292
+ return null;
293
+ }
294
+ });
295
+ });
296
+
297
+ const CAPABILITIES = {
298
+ dynamicLayout: false,
299
+ dynamicTag: false,
300
+ prepareArgs: false,
301
+ createArgs: true,
302
+ attributeHook: false,
303
+ elementHook: false,
304
+ createCaller: false,
305
+ dynamicScope: false,
306
+ updateHook: false,
307
+ createInstance: true,
308
+ wrapped: false,
309
+ willDestroy: false,
310
+ hasSubOwner: false
311
+ };
312
+ const CAPABILITIES_MASK = /*@__PURE__*/capabilityFlagsFrom(CAPABILITIES);
313
+ class RouteTemplateManager {
314
+ create(_owner, _definition, args) {
315
+ let self = args.named.get('controller');
316
+ let controller = valueForRef(self);
317
+ return {
318
+ self,
319
+ controller
320
+ };
321
+ }
322
+ getSelf({
323
+ self
324
+ }) {
325
+ return self;
326
+ }
327
+ getDebugName({
328
+ name
329
+ }) {
330
+ return `route-template (${name})`;
331
+ }
332
+ getDebugCustomRenderTree({
333
+ name
334
+ }, state, args) {
335
+ return [{
336
+ bucket: state,
337
+ type: 'route-template',
338
+ name,
339
+ args,
340
+ instance: state.controller
341
+ }];
342
+ }
343
+ getCapabilities() {
344
+ return CAPABILITIES;
345
+ }
346
+ didRenderLayout() {}
347
+ didUpdateLayout() {}
348
+ didCreate() {}
349
+ didUpdate() {}
350
+ getDestroyable() {
351
+ return null;
352
+ }
353
+ }
354
+ const ROUTE_TEMPLATE_MANAGER = /*@__PURE__*/new RouteTemplateManager();
355
+
356
+ /**
357
+ * This "upgrades" a route template into a invocable component. Conceptually
358
+ * it can be 1:1 for each unique `Template`, but it's also cheap to construct,
359
+ * so unless the stability is desirable for other reasons, it's probably not
360
+ * worth caching this.
361
+ */
362
+ class RouteTemplate {
363
+ // handle is not used by this custom definition
364
+ handle = -1;
365
+ resolvedName;
366
+ state;
367
+ manager = ROUTE_TEMPLATE_MANAGER;
368
+ capabilities = CAPABILITIES_MASK;
369
+ compilable;
370
+ constructor(name, template) {
371
+ let unwrapped = unwrapTemplate(template);
372
+ // TODO This actually seems inaccurate – it ultimately came from the
373
+ // outlet's name. Also, setting this overrides `getDebugName()` in that
374
+ // message. Is that desirable?
375
+ this.resolvedName = name;
376
+ this.state = {
377
+ name
378
+ };
379
+ this.compilable = unwrapped.asLayout();
380
+ }
381
+ }
382
+
383
+ // TODO a lot these fields are copied from the adjacent existing components
384
+ // implementation, haven't looked into who cares about `ComponentDefinition`
385
+ // and if it is appropriate here. It seems like this version is intended to
386
+ // be used with `curry` which probably isn't necessary here. It could be the
387
+ // case that we just want to do something more similar to `InternalComponent`
388
+ // (the one we used to implement `Input` and `LinkTo`). For now it follows
389
+ // the same pattern to get things going.
390
+ function makeRouteTemplate(owner, name, template) {
391
+ let routeTemplate = new RouteTemplate(name, template);
392
+ return curry(0, routeTemplate, owner, null, true);
393
+ }
394
+
395
+ /**
396
+ The `{{outlet}}` helper lets you specify where a child route will render in
397
+ your template. An important use of the `{{outlet}}` helper is in your
398
+ application's `application.gjs` file:
399
+
400
+ ```app/templates/application.gjs
401
+ import MyHeader from '../components/my-header';
402
+ import MyFooter from '../components/my-footer';
403
+
404
+ <template>
405
+ <MyHeader />
406
+
407
+ <div class="my-dynamic-content">
408
+ <!-- this content will change based on the current route, which depends on the current URL -->
409
+ {{outlet}}
410
+ </div>
411
+
412
+ <MyFooter />
413
+ </template>
414
+ ```
415
+
416
+ See the [routing guide](https://guides.emberjs.com/release/routing/rendering-a-template/) for more
417
+ information on how your `route` interacts with the `{{outlet}}` helper.
418
+ Note: Your content __will not render__ if there isn't an `{{outlet}}` for it.
419
+
420
+ `outlet` is built-in and does not need to be imported.
421
+
422
+ @method outlet
423
+ @for Ember.Templates.helpers
424
+ @public
425
+ */
426
+ const outletHelper = /*@__PURE__*/internalHelper((_args, owner, scope) => {
427
+ let outletRef = createComputeRef(() => {
428
+ let state = valueForRef(scope.get('outletState'));
429
+ return state?.outlets?.main;
430
+ });
431
+ let lastState = null;
432
+ let outlet = null;
433
+ return createComputeRef(() => {
434
+ let outletState = valueForRef(outletRef);
435
+ let state = stateFor(outletRef, outletState);
436
+
437
+ // This code is deliberately using the behavior in glimmer-vm where in
438
+ // <@Component />, the component is considered stabled via `===`, and
439
+ // will continue to re-render in-place as long as the `===` holds, but
440
+ // when it changes to a different object, it teardown the old component
441
+ // (running destructors, etc), and render the component in its place (or
442
+ // nothing if the new value is nullish. Here we are carefully exploiting
443
+ // that fact, and returns the same stable object so long as it is the
444
+ // same route, but return a different one when the route changes. On the
445
+ // other hand, changing the model only intentionally do not teardown the
446
+ // component and instead re-render in-place.
447
+ if (!isStable(state, lastState)) {
448
+ lastState = state;
449
+ if (state !== null) {
450
+ // If we are crossing an engine mount point, this is how the owner
451
+ // gets switched.
452
+ let outletOwner = outletState?.render?.owner ?? owner;
453
+ let named = dict();
454
+
455
+ // Here we either have a raw template that needs to be normalized,
456
+ // or a component that we can render as-is. `RouteTemplate` upgrades
457
+ // the template into a component so we can have a unified code path.
458
+ // We still store the original `template` value, because we rely on
459
+ // its identity for the stability check, and the `RouteTemplate`
460
+ // wrapper doesn't dedup for us.
461
+ let template = state.template;
462
+ let component;
463
+ if (hasInternalComponentManager(template)) {
464
+ component = template;
465
+ } else {
466
+ component = makeRouteTemplate(outletOwner, state.name, template);
467
+ }
468
+
469
+ // Component is stable for the lifetime of the outlet
470
+ named['Component'] = createConstRef(component);
471
+
472
+ // Controller is stable for the lifetime of the outlet
473
+ named['controller'] = createConstRef(state.controller);
474
+
475
+ // Create a ref for the model
476
+ let modelRef = childRefFromParts(outletRef, ['render', 'model']);
477
+
478
+ // Store the value of the model
479
+ let model = valueForRef(modelRef);
480
+
481
+ // Create a compute ref which we pass in as the `{{@model}}` reference
482
+ // for the outlet. This ref will update and return the value of the
483
+ // model _until_ the outlet itself changes. Once the outlet changes,
484
+ // dynamic scope also changes, and so the original model ref would not
485
+ // provide the correct updated value. So we stop updating and return
486
+ // the _last_ model value for that outlet.
487
+ named['model'] = createComputeRef(() => {
488
+ if (lastState === state) {
489
+ model = valueForRef(modelRef);
490
+ }
491
+ return model;
492
+ });
493
+ let args = createCapturedArgs(named, EMPTY_POSITIONAL);
494
+
495
+ // Package up everything
496
+ outlet = curry(0, new OutletComponent(owner, state), outletOwner, args, true);
497
+ } else {
498
+ outlet = null;
499
+ }
500
+ }
501
+ return outlet;
502
+ });
503
+ });
504
+ function stateFor(ref, outlet) {
505
+ if (outlet === undefined) return null;
506
+ let render = outlet.render;
507
+ if (render === undefined) return null;
508
+ let template = render.template;
509
+ // The type doesn't actually allow for `null`, but if we make it past this
510
+ // point it is really important that we have _something_ to render. We could
511
+ // assert, but that is probably overly strict for very little to gain.
512
+ if (template === undefined || template === null) return null;
513
+ return {
514
+ ref,
515
+ name: render.name,
516
+ template,
517
+ controller: render.controller
518
+ };
519
+ }
520
+ function isStable(state, lastState) {
521
+ if (state === null || lastState === null) {
522
+ return false;
523
+ }
524
+ return state.template === lastState.template && state.controller === lastState.controller;
525
+ }
526
+
527
+ const ROUTER_KEYWORD_HELPERS = {
528
+ '-mount': mountHelper,
529
+ '-outlet': outletHelper
530
+ };
531
+
532
+ /**
533
+ * The resolver used by the classic application `Renderer`. It extends the
534
+ * shared `ResolverImpl` with the keywords that require the router and engine
535
+ * infrastructure (`{{outlet}}` and `{{mount}}`). Keeping these out of the
536
+ * base resolver means renderers that have no router (e.g. `renderComponent`)
537
+ * do not pull the outlet/engine machinery into the build.
538
+ */
539
+ class RouterResolver extends ResolverImpl {
540
+ lookupBuiltInHelper(name) {
541
+ return ROUTER_KEYWORD_HELPERS[name] ?? super.lookupBuiltInHelper(name);
542
+ }
543
+
544
+ // Loose-mode templates resolve the wrapped `{{outlet}}` / `{{mount}}`
545
+ // keywords (`{{component (-outlet)}}`) through `lookupHelper`, not
546
+ // `lookupBuiltInHelper`, so the router keywords have to be added to both
547
+ // lookup paths.
548
+ lookupHelper(name, owner) {
549
+ return ROUTER_KEYWORD_HELPERS[name] ?? super.lookupHelper(name, owner);
550
+ }
551
+ }
552
+
553
+ // We use the `InternalOwner` notion here because we actually need all of its
554
+ // API for using with renderers (normally, it will be `EngineInstance`).
555
+ // We use `getOwner` from our internal home for it rather than the narrower
556
+ // public API for the same reason.
557
+ const TOP_LEVEL_NAME = '-top-level';
558
+ class OutletView {
559
+ static extend(injections) {
560
+ return class extends OutletView {
561
+ static create(options) {
562
+ if (options) {
563
+ return super.create(Object.assign({}, injections, options));
564
+ } else {
565
+ return super.create(injections);
566
+ }
567
+ }
568
+ };
569
+ }
570
+ static reopenClass(injections) {
571
+ Object.assign(this, injections);
572
+ }
573
+ static create(options) {
574
+ let {
575
+ environment: _environment,
576
+ application: namespace,
577
+ template: templateFactory
578
+ } = options;
579
+ let owner = getOwner(options);
580
+ let template = templateFactory(owner);
581
+ return new OutletView(_environment, owner, template, namespace);
582
+ }
583
+ ref;
584
+ state;
585
+ constructor(_environment, owner, template, namespace) {
586
+ this._environment = _environment;
587
+ this.owner = owner;
588
+ this.template = template;
589
+ this.namespace = namespace;
590
+ let outletStateTag = createTag();
591
+ let outletState = {
592
+ outlets: {
593
+ main: undefined
594
+ },
595
+ render: {
596
+ owner: owner,
597
+ name: TOP_LEVEL_NAME,
598
+ controller: undefined,
599
+ model: undefined,
600
+ template
601
+ }
602
+ };
603
+ let ref = this.ref = createComputeRef(() => {
604
+ consumeTag(outletStateTag);
605
+ return outletState;
606
+ }, state => {
607
+ DIRTY_TAG$1(outletStateTag);
608
+ outletState.outlets['main'] = state;
609
+ });
610
+ this.state = {
611
+ ref,
612
+ name: TOP_LEVEL_NAME,
613
+ template,
614
+ controller: undefined
615
+ };
616
+ }
617
+ appendTo(selector) {
618
+ let target;
619
+ if (this._environment.hasDOM) {
620
+ target = typeof selector === 'string' ? document.querySelector(selector) : selector;
621
+ } else {
622
+ target = selector;
623
+ }
624
+ let renderer = this.owner.lookup('renderer:-dom');
625
+
626
+ // SAFETY: It's not clear that this cast is safe.
627
+ // The types for appendOutletView may be incorrect or this is a potential bug.
628
+ schedule('render', renderer, 'appendOutletView', this, target);
629
+ }
630
+ rerender() {
631
+ /**/
632
+ }
633
+ setOutletState(state) {
634
+ updateRef(this.ref, state);
635
+ }
636
+ destroy() {
637
+ /**/
638
+ }
639
+ }
640
+
641
+ class DynamicScope {
642
+ constructor(view, outletState) {
643
+ this.view = view;
644
+ this.outletState = outletState;
645
+ }
646
+ child() {
647
+ return new DynamicScope(this.view, this.outletState);
648
+ }
649
+ get(key) {
650
+ return this.outletState;
651
+ }
652
+ set(key, value) {
653
+ this.outletState = value;
654
+ return value;
655
+ }
656
+ }
657
+ class ClassicRootState {
658
+ type = 'classic';
659
+ id;
660
+ result;
661
+ destroyed;
662
+ render;
663
+ env;
664
+ constructor(root, context, owner, template, self, parentElement, dynamicScope, builder) {
665
+ this.root = root;
666
+ this.id = root instanceof OutletView ? guidFor(root) : getViewId(root);
667
+ this.result = undefined;
668
+ this.destroyed = false;
669
+ this.env = context.env;
670
+ this.render = errorLoopTransaction(() => {
671
+ let layout = unwrapTemplate(template).asLayout();
672
+ let iterator = renderMain(context, owner, self, builder(context.env, {
673
+ element: parentElement,
674
+ nextSibling: null
675
+ }), layout, dynamicScope);
676
+ let result = this.result = iterator.sync();
677
+ associateDestroyableChild(this, result);
678
+ this.render = errorLoopTransaction(() => {
679
+ if (isDestroying(result) || isDestroyed(result)) return;
680
+ return result.rerender({
681
+ alwaysRevalidate: false
682
+ });
683
+ });
684
+ });
685
+ }
686
+ isFor(possibleRoot) {
687
+ return this.root === possibleRoot;
688
+ }
689
+ destroy() {
690
+ let {
691
+ result,
692
+ env
693
+ } = this;
694
+ this.destroyed = true;
695
+ this.root = null;
696
+ this.result = undefined;
697
+ this.render = undefined;
698
+ if (result !== undefined) {
699
+ /*
700
+ Handles these scenarios:
701
+ * When roots are removed during standard rendering process, a transaction exists already
702
+ `.begin()` / `.commit()` are not needed.
703
+ * When roots are being destroyed manually (`component.append(); component.destroy() case), no
704
+ transaction exists already.
705
+ * When roots are being destroyed during `Renderer#destroy`, no transaction exists
706
+ */
707
+
708
+ inTransaction(env, () => destroy(result));
709
+ }
710
+ }
711
+ }
712
+ class Renderer extends BaseRenderer {
713
+ _rootTemplate;
714
+ _viewRegistry;
715
+ static create(props) {
716
+ let {
717
+ _viewRegistry
718
+ } = props;
719
+ let owner = getOwner(props);
720
+ let document = owner.lookup('service:-document');
721
+ let env = owner.lookup('-environment:main');
722
+ let rootTemplate = owner.lookup(privatize`template:-root`);
723
+ let builder = owner.lookup('service:-dom-builder');
724
+ return new this(owner, document, env, rootTemplate, _viewRegistry, builder);
725
+ }
726
+ constructor(owner, document, env, rootTemplate, viewRegistry, builder = clientBuilder, resolver = new RouterResolver()) {
727
+ super(owner, env, document, resolver, builder);
728
+ this._rootTemplate = rootTemplate(owner);
729
+ this._viewRegistry = viewRegistry || owner.lookup('-view-registry:main');
730
+ }
731
+
732
+ // renderer HOOKS
733
+
734
+ appendOutletView(view, target) {
735
+ // TODO: This bypasses the {{outlet}} syntax so logically duplicates
736
+ // some of the set up code. Since this is all internal (or is it?),
737
+ // we can refactor this to do something more direct/less convoluted
738
+ // and with less setup, but get it working first
739
+ let outlet = createRootOutlet(view);
740
+ let {
741
+ name,
742
+ /* controller, */template
743
+ } = view.state;
744
+ let named = dict();
745
+ named['Component'] = createConstRef(makeRouteTemplate(view.owner, name, template));
746
+
747
+ // TODO: is this guaranteed to be undefined? It seems to be the
748
+ // case in the `OutletView` class. Investigate how much that class
749
+ // exists as an internal implementation detail only, or if it was
750
+ // used outside of core. As far as I can tell, test-helpers uses
751
+ // it but only for `setOutletState`.
752
+ // named['controller'] = createConstRef(controller, '@controller');
753
+ // Update: at least according to the debug render tree tests, we
754
+ // appear to always expect this to be undefined. Not a definitive
755
+ // source by any means, but is useful evidence
756
+ named['controller'] = UNDEFINED_REFERENCE;
757
+ named['model'] = UNDEFINED_REFERENCE;
758
+ let args = createCapturedArgs(named, EMPTY_POSITIONAL);
759
+ this._appendDefinition(view, curry(0, outlet, view.owner, args, true), target);
760
+ }
761
+ appendTo(view, target) {
762
+ let definition = new RootComponentDefinition(view);
763
+ this._appendDefinition(view, curry(0, definition, this.state.owner, null, true), target);
764
+ }
765
+ _appendDefinition(root, definition, target) {
766
+ let self = createConstRef(definition);
767
+ let dynamicScope = new DynamicScope(null, UNDEFINED_REFERENCE);
768
+ let rootState = new ClassicRootState(root, this.state.context, this.state.owner, this._rootTemplate, self, target, dynamicScope, this.state.builder);
769
+ this.state.renderRoot(rootState, this);
770
+ }
771
+ cleanupRootFor(component) {
772
+ // no need to cleanup roots if we have already been destroyed
773
+ if (isDestroyed(this)) {
774
+ return;
775
+ }
776
+ let roots = this.state.roots;
777
+
778
+ // traverse in reverse so we can remove items
779
+ // without mucking up the index
780
+ let i = roots.length;
781
+ while (i--) {
782
+ let root = roots[i];
783
+ if (root.type === 'classic' && root.isFor(component)) {
784
+ root.destroy();
785
+ roots.splice(i, 1);
786
+ }
787
+ }
788
+ }
789
+ remove(view) {
790
+ view._transitionTo('destroying');
791
+ this.cleanupRootFor(view);
792
+ if (this.state.isInteractive) {
793
+ view.trigger('didDestroyElement');
794
+ }
795
+ }
796
+ get _roots() {
797
+ return this.state.debug.roots;
798
+ }
799
+ get _inRenderTransaction() {
800
+ return this.state.debug.inRenderTransaction;
801
+ }
802
+ get _isInteractive() {
803
+ return this.state.debug.isInteractive;
804
+ }
805
+ get _context() {
806
+ return this.state.context;
807
+ }
808
+ register(view) {
809
+ let id = getViewId(view);
810
+ this._viewRegistry[id] = view;
811
+ }
812
+ unregister(view) {
813
+ delete this._viewRegistry[getViewId(view)];
814
+ }
815
+ getElement(component) {
816
+ if (this._isInteractive) {
817
+ return getViewElement(component);
818
+ } else {
819
+ throw new Error('Accessing `this.element` is not allowed in non-interactive environments (such as FastBoot).');
820
+ }
821
+ }
822
+ getBounds(component) {
823
+ let bounds = component[BOUNDS];
824
+ let parentElement = bounds.parentElement();
825
+ let firstNode = bounds.firstNode();
826
+ let lastNode = bounds.lastNode();
827
+ return {
828
+ parentElement,
829
+ firstNode,
830
+ lastNode
831
+ };
832
+ }
833
+ }
834
+
835
+ const OutletTemplate = templateFactory(
836
+ /*
837
+ {{component (outletHelper)}}
838
+ */
839
+ {
840
+ "id": null,
841
+ "block": "[[[46,[28,[32,0],null,null],null,null,null]],[],[\"component\"]]",
842
+ "moduleName": "packages/@ember/-internals/glimmer/lib/templates/outlet.hbs",
843
+ "scope": () => ({
844
+ outletHelper
845
+ }),
846
+ "isStrictMode": true
847
+ });
848
+
849
+ function setupApplicationRegistry(registry) {
850
+ // because we are using injections we can't use instantiate false
851
+ // we need to use bind() to copy the function so factory for
852
+ // association won't leak
853
+ registry.register('service:-dom-builder', {
854
+ // Additionally, we *must* constrain this to require `props` on create, else
855
+ // we *know* it cannot have an owner.
856
+ create(props) {
857
+ let owner = getOwner(props);
858
+ let env = owner.lookup('-environment:main');
859
+ switch (env._renderMode) {
860
+ case 'serialize':
861
+ return serializeBuilder.bind(null);
862
+ case 'rehydrate':
863
+ return rehydrationBuilder.bind(null);
864
+ default:
865
+ return clientBuilder.bind(null);
866
+ }
867
+ }
868
+ });
869
+ registry.register(privatize`template:-root`, RootTemplate);
870
+ registry.register('renderer:-dom', Renderer);
871
+ }
872
+ function setupEngineRegistry(registry) {
873
+ registry.optionsForType('template', {
874
+ instantiate: false
875
+ });
876
+ registry.register('view:-outlet', OutletView);
877
+ registry.register('template:-outlet', OutletTemplate);
878
+ registry.optionsForType('helper', {
879
+ instantiate: false
880
+ });
881
+ registry.register('component:input', Input);
882
+ registry.register('component:link-to', LinkTo);
883
+ registry.register('component:textarea', Textarea);
884
+ }
885
+
886
+ export { OutletView as O, Renderer as R, RootTemplate as a, setupEngineRegistry as b, setupApplicationRegistry as s };