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.
- package/build-metadata.json +3 -3
- package/dist/dev/packages/@ember/-internals/deprecations/index.js +10 -0
- package/dist/dev/packages/@ember/-internals/glimmer/index.js +3 -3
- package/dist/dev/packages/@ember/-internals/routing/index.js +1 -1
- package/dist/dev/packages/@ember/-internals/runtime/lib/mixins/-proxy.js +1 -1
- package/dist/dev/packages/@ember/-internals/runtime/lib/mixins/comparable.js +5 -0
- package/dist/dev/packages/@ember/application/index.js +2 -2
- package/dist/dev/packages/@ember/application/instance.js +21 -1
- package/dist/dev/packages/@ember/component/helper.js +321 -1
- package/dist/dev/packages/@ember/component/index.js +1 -1
- package/dist/dev/packages/@ember/engine/index.js +2 -2
- package/dist/dev/packages/@ember/renderer/index.js +1 -1
- package/dist/dev/packages/@ember/routing/-internals.js +1 -1
- package/dist/dev/packages/@ember/routing/lib/routing-service.js +0 -1
- package/dist/dev/packages/@ember/routing/lib/utils.js +1 -1
- package/dist/dev/packages/@ember/routing/route.js +1 -1
- package/dist/dev/packages/@ember/routing/router-service.js +0 -1
- package/dist/dev/packages/@ember/routing/router.js +1 -1
- package/dist/dev/packages/@ember/utils/lib/compare.js +5 -2
- package/dist/dev/packages/ember/version.js +1 -1
- package/dist/dev/packages/router_js/index.js +2 -2
- package/dist/dev/packages/shared-chunks/{curly-Ei5G8jhk.js → curly-DGUCLOud.js} +4 -5
- package/dist/dev/packages/shared-chunks/curly-brand-B_F79Dep.js +12 -0
- package/dist/dev/packages/shared-chunks/helper-brand-C9_8vvOf.js +12 -0
- package/dist/dev/packages/shared-chunks/{index-B3pPx1fL.js → index-CCyXUNBa.js} +616 -1573
- package/dist/dev/packages/shared-chunks/outlet-CHFL7tun.js +135 -0
- package/dist/dev/packages/shared-chunks/setup-registry-BHdDJATP.js +951 -0
- package/dist/dev/packages/shared-chunks/{unrecognized-url-error-BJHjL30Q.js → unrecognized-url-error-B8loxkay.js} +1 -1
- package/dist/prod/packages/@ember/-internals/deprecations/index.js +10 -0
- package/dist/prod/packages/@ember/-internals/glimmer/index.js +3 -3
- package/dist/prod/packages/@ember/-internals/routing/index.js +1 -1
- package/dist/prod/packages/@ember/-internals/runtime/lib/mixins/-proxy.js +1 -1
- package/dist/prod/packages/@ember/-internals/runtime/lib/mixins/comparable.js +5 -0
- package/dist/prod/packages/@ember/application/index.js +2 -2
- package/dist/prod/packages/@ember/application/instance.js +17 -2
- package/dist/prod/packages/@ember/component/helper.js +305 -1
- package/dist/prod/packages/@ember/component/index.js +1 -1
- package/dist/prod/packages/@ember/engine/index.js +2 -2
- package/dist/prod/packages/@ember/renderer/index.js +1 -1
- package/dist/prod/packages/@ember/routing/lib/routing-service.js +0 -1
- package/dist/prod/packages/@ember/routing/lib/utils.js +1 -1
- package/dist/prod/packages/@ember/routing/route.js +1 -1
- package/dist/prod/packages/@ember/routing/router-service.js +0 -1
- package/dist/prod/packages/@ember/routing/router.js +1 -1
- package/dist/prod/packages/@ember/utils/lib/compare.js +5 -2
- package/dist/prod/packages/ember/version.js +1 -1
- package/dist/prod/packages/router_js/index.js +2 -2
- package/dist/prod/packages/shared-chunks/{curly-IY06zACp.js → curly-a6DP7r87.js} +4 -5
- package/dist/prod/packages/shared-chunks/curly-brand-B_F79Dep.js +12 -0
- package/dist/prod/packages/shared-chunks/helper-brand-C9_8vvOf.js +12 -0
- package/dist/prod/packages/shared-chunks/{index-CslMfEpb.js → index-npr2B-vu.js} +546 -1449
- package/dist/prod/packages/shared-chunks/outlet--lIm3q7t.js +132 -0
- package/dist/prod/packages/shared-chunks/setup-registry-Dfu8EyLU.js +886 -0
- package/dist/prod/packages/shared-chunks/{unrecognized-url-error-EgNrnFu_.js → unrecognized-url-error-jjQ-FqKB.js} +1 -1
- package/docs/data.json +279 -214
- package/package.json +6 -6
- package/types/stable/@ember/-internals/deprecations/index.d.ts +6 -0
- package/types/stable/@ember/-internals/glimmer/lib/base-renderer.d.ts +150 -0
- package/types/stable/@ember/-internals/glimmer/lib/component-managers/curly-brand.d.ts +10 -0
- package/types/stable/@ember/-internals/glimmer/lib/component-managers/curly.d.ts +3 -2
- package/types/stable/@ember/-internals/glimmer/lib/helper-brand.d.ts +10 -0
- package/types/stable/@ember/-internals/glimmer/lib/helper.d.ts +4 -6
- package/types/stable/@ember/-internals/glimmer/lib/renderer.d.ts +7 -154
- package/types/stable/@ember/-internals/glimmer/lib/router-resolver.d.ts +17 -0
- package/types/stable/@ember/renderer/index.d.ts +2 -2
- package/types/stable/index.d.ts +590 -586
- package/dist/dev/packages/shared-chunks/helper-DIj85_-f.js +0 -326
- package/dist/dev/packages/shared-chunks/setup-registry-9DCmHTFF.js +0 -77
- package/dist/prod/packages/shared-chunks/helper-DkXiTBjc.js +0 -310
- 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,
|
|
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 {
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
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 {
|
|
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 {
|
|
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
|
|
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
|
|
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
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
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
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
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
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
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
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
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
|
-
|
|
172
|
-
|
|
173
|
-
|
|
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
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
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
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
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
|
-
|
|
459
|
-
|
|
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
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
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
|
-
|
|
1246
|
-
|
|
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 `{{
|
|
1285
|
-
|
|
1286
|
-
|
|
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
|
-
```
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
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
|
-
|
|
1305
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
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
|
|
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
|
|
1472
|
-
// not really harm anything, since it's just a no-op
|
|
1473
|
-
//
|
|
1474
|
-
//
|
|
1475
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1516
|
-
|
|
823
|
+
constructor(keys, values) {
|
|
824
|
+
super(values.length);
|
|
825
|
+
this.keys = keys;
|
|
826
|
+
this.values = values;
|
|
1517
827
|
}
|
|
1518
|
-
|
|
1519
|
-
|
|
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
|
-
|
|
1530
|
-
return
|
|
831
|
+
memoFor(position) {
|
|
832
|
+
return this.keys[position];
|
|
1531
833
|
}
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1576
|
-
|
|
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
|
-
|
|
1593
|
-
|
|
853
|
+
isEmpty() {
|
|
854
|
+
return false;
|
|
1594
855
|
}
|
|
1595
|
-
|
|
856
|
+
next() {
|
|
1596
857
|
let {
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
} =
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
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
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
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
|
-
|
|
1653
|
-
|
|
879
|
+
memoFor(_result, position) {
|
|
880
|
+
return position;
|
|
1654
881
|
}
|
|
1655
|
-
|
|
1656
|
-
|
|
882
|
+
}
|
|
883
|
+
class MapLikeNativeIterator extends NativeIterator {
|
|
884
|
+
valueFor(result) {
|
|
885
|
+
return result.value[1];
|
|
1657
886
|
}
|
|
1658
|
-
|
|
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
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
}
|
|
1668
|
-
|
|
1669
|
-
return
|
|
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
|
-
|
|
1672
|
-
|
|
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
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
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(
|
|
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 {
|
|
1398
|
+
export { BaseRenderer as B, ResolverImpl as R, _resetRenderers as _, renderSettled as a, errorLoopTransaction as e, renderComponent as r };
|