ember-inspector 4.11.0-alpha.2024.3.9 → 4.11.0-alpha.2024.4.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (77) hide show
  1. package/app/components/component-tree-arg.js +9 -0
  2. package/app/components/component-tree-item.hbs +18 -2
  3. package/app/components/object-inspector/properties-all.hbs +1 -0
  4. package/app/components/object-inspector/properties-base.js +10 -0
  5. package/app/components/object-inspector/properties-grouped.hbs +1 -0
  6. package/app/components/object-inspector/property.hbs +12 -1
  7. package/app/components/object-inspector/property.ts +4 -2
  8. package/app/components/object-inspector.hbs +16 -2
  9. package/app/components/object-inspector.js +14 -0
  10. package/app/controllers/component-tree.js +54 -3
  11. package/app/routes/component-tree.js +0 -6
  12. package/app/services/adapters/web-extension.js +3 -3
  13. package/app/services/port.js +4 -0
  14. package/app/styles/component_tree.scss +13 -0
  15. package/app/utils/parse-text.ts +1 -0
  16. package/dist/bookmarklet/panes-3-16-0/assets/{chunk.143.ac621af5331b75527946.js → chunk.143.9f3a22b07387ec438672.js} +4 -4
  17. package/dist/{firefox/panes-3-16-0/assets/chunk.178.e6b2f8bb19b9f072aa49.js → bookmarklet/panes-3-16-0/assets/chunk.178.4fe3df60bd7ba157b035.js} +3 -3
  18. package/dist/bookmarklet/panes-3-16-0/assets/ember-inspector.css +13 -0
  19. package/dist/bookmarklet/panes-3-16-0/assets/ember-inspector.js +27 -23
  20. package/dist/bookmarklet/panes-3-16-0/assets/svg/code-source.svg +9 -0
  21. package/dist/bookmarklet/panes-3-16-0/assets/vendor.css +33 -0
  22. package/dist/bookmarklet/panes-3-16-0/assets/vendor.js +12 -10
  23. package/dist/bookmarklet/panes-3-16-0/ember_debug.js +408 -538
  24. package/dist/bookmarklet/panes-3-16-0/index.html +2 -2
  25. package/dist/chrome/manifest.json +2 -2
  26. package/dist/{firefox/panes-3-16-0/assets/chunk.143.ac621af5331b75527946.js → chrome/panes-3-16-0/assets/chunk.143.9f3a22b07387ec438672.js} +4 -4
  27. package/dist/{bookmarklet/panes-3-16-0/assets/chunk.178.e6b2f8bb19b9f072aa49.js → chrome/panes-3-16-0/assets/chunk.178.4fe3df60bd7ba157b035.js} +3 -3
  28. package/dist/chrome/panes-3-16-0/assets/ember-inspector.css +13 -0
  29. package/dist/chrome/panes-3-16-0/assets/ember-inspector.js +27 -23
  30. package/dist/chrome/panes-3-16-0/assets/svg/code-source.svg +9 -0
  31. package/dist/chrome/panes-3-16-0/assets/vendor.css +33 -0
  32. package/dist/chrome/panes-3-16-0/assets/vendor.js +12 -10
  33. package/dist/chrome/panes-3-16-0/ember_debug.js +408 -538
  34. package/dist/chrome/panes-3-16-0/index.html +2 -2
  35. package/dist/firefox/manifest.json +2 -2
  36. package/dist/{chrome/panes-3-16-0/assets/chunk.143.ac621af5331b75527946.js → firefox/panes-3-16-0/assets/chunk.143.9f3a22b07387ec438672.js} +4 -4
  37. package/dist/{websocket/assets/chunk.178.e6b2f8bb19b9f072aa49.js → firefox/panes-3-16-0/assets/chunk.178.4fe3df60bd7ba157b035.js} +3 -3
  38. package/dist/firefox/panes-3-16-0/assets/ember-inspector.css +13 -0
  39. package/dist/firefox/panes-3-16-0/assets/ember-inspector.js +27 -23
  40. package/dist/firefox/panes-3-16-0/assets/svg/code-source.svg +9 -0
  41. package/dist/firefox/panes-3-16-0/assets/vendor.css +33 -0
  42. package/dist/firefox/panes-3-16-0/assets/vendor.js +12 -10
  43. package/dist/firefox/panes-3-16-0/ember_debug.js +408 -538
  44. package/dist/firefox/panes-3-16-0/index.html +2 -2
  45. package/dist/websocket/assets/{chunk.143.ac621af5331b75527946.js → chunk.143.9f3a22b07387ec438672.js} +4 -4
  46. package/dist/{chrome/panes-3-16-0/assets/chunk.178.e6b2f8bb19b9f072aa49.js → websocket/assets/chunk.178.4fe3df60bd7ba157b035.js} +3 -3
  47. package/dist/websocket/assets/ember-inspector.css +13 -0
  48. package/dist/websocket/assets/ember-inspector.js +27 -23
  49. package/dist/websocket/assets/svg/code-source.svg +9 -0
  50. package/dist/websocket/assets/vendor.css +33 -0
  51. package/dist/websocket/assets/vendor.js +12 -10
  52. package/dist/websocket/ember_debug.js +408 -538
  53. package/dist/websocket/index.html +2 -2
  54. package/ember-cli-build.js +3 -4
  55. package/ember_debug/adapters/basic.js +4 -4
  56. package/ember_debug/adapters/web-extension.js +9 -5
  57. package/ember_debug/general-debug.js +3 -1
  58. package/ember_debug/libs/capture-render-tree.js +7 -426
  59. package/ember_debug/libs/render-tree.js +210 -31
  60. package/ember_debug/libs/view-inspection.js +28 -0
  61. package/ember_debug/object-inspector.js +49 -88
  62. package/ember_debug/route-debug.js +2 -3
  63. package/ember_debug/utils/ember.js +16 -0
  64. package/ember_debug/utils/get-object-name.js +4 -0
  65. package/ember_debug/utils/name-functions.js +1 -1
  66. package/ember_debug/utils/type-check.js +82 -12
  67. package/ember_debug/utils/version.js +37 -0
  68. package/ember_debug/view-debug.js +1 -1
  69. package/lib/ui/addon/styles/_goto-source.scss +30 -0
  70. package/lib/ui/addon/styles/addon.scss +1 -0
  71. package/lib/ui/addon/styles/toolbar/_index.scss +4 -0
  72. package/package.json +1 -1
  73. package/public/assets/svg/code-source.svg +9 -0
  74. package/skeletons/web-extension/manifest.json +2 -2
  75. package/tests/acceptance/object-inspector-test.js +68 -0
  76. package/tests/ember_debug/view-debug-test.js +211 -69
  77. package/tests/index.html +1 -0
@@ -9,7 +9,7 @@
9
9
  <meta name="viewport" content="width=device-width, initial-scale=1">
10
10
 
11
11
 
12
- <meta name="ember-inspector/config/environment" content="%7B%22modulePrefix%22%3A%22ember-inspector%22%2C%22environment%22%3A%22production%22%2C%22rootURL%22%3A%22%22%2C%22locationType%22%3A%22hash%22%2C%22version%22%3A%224.11.0-alpha.2024.3.9%2B56575c0%22%2C%22emberVersionsSupported%22%3A%5B%223.16.0%22%2C%22%22%5D%2C%22previousEmberVersionsSupported%22%3A%5B%220.0.0%22%2C%222.7.0%22%2C%223.4.0%22%5D%2C%22EmberENV%22%3A%7B%22FEATURES%22%3A%7B%7D%2C%22_APPLICATION_TEMPLATE_WRAPPER%22%3Afalse%2C%22_DEFAULT_ASYNC_OBSERVERS%22%3Atrue%2C%22_JQUERY_INTEGRATION%22%3Afalse%2C%22_TEMPLATE_ONLY_GLIMMER_COMPONENTS%22%3Atrue%7D%2C%22APP%22%3A%7B%22name%22%3A%22ember-inspector%22%2C%22version%22%3A%224.11.0-alpha.2024.3.9%2B56575c0%2B56575c08%22%7D%7D" />
12
+ <meta name="ember-inspector/config/environment" content="%7B%22modulePrefix%22%3A%22ember-inspector%22%2C%22environment%22%3A%22production%22%2C%22rootURL%22%3A%22%22%2C%22locationType%22%3A%22hash%22%2C%22version%22%3A%224.11.0-alpha.2024.4.2%2Be4d8062%22%2C%22emberVersionsSupported%22%3A%5B%223.16.0%22%2C%22%22%5D%2C%22previousEmberVersionsSupported%22%3A%5B%220.0.0%22%2C%222.7.0%22%2C%223.4.0%22%5D%2C%22EmberENV%22%3A%7B%22FEATURES%22%3A%7B%7D%2C%22_APPLICATION_TEMPLATE_WRAPPER%22%3Afalse%2C%22_DEFAULT_ASYNC_OBSERVERS%22%3Atrue%2C%22_JQUERY_INTEGRATION%22%3Afalse%2C%22_TEMPLATE_ONLY_GLIMMER_COMPONENTS%22%3Atrue%7D%2C%22APP%22%3A%7B%22name%22%3A%22ember-inspector%22%2C%22version%22%3A%224.11.0-alpha.2024.4.2%2Be4d8062%2Be4d8062b%22%7D%7D" />
13
13
 
14
14
  <style type="text/css">
15
15
  @font-face {
@@ -39,7 +39,7 @@
39
39
 
40
40
  <script src="assets/vendor.js"></script>
41
41
  <script src="assets/chunk.359.0be5d21f60d2b5d6d423.js"></script>
42
- <script src="assets/chunk.143.ac621af5331b75527946.js"></script>
42
+ <script src="assets/chunk.143.9f3a22b07387ec438672.js"></script>
43
43
  <script src="assets/ember-inspector.js"></script>
44
44
 
45
45
 
@@ -381,19 +381,18 @@ module.exports = function (defaults) {
381
381
  if (env === 'test') {
382
382
  // `ember test` expects the index.html file to be in the
383
383
  // output directory.
384
- output = mergeTrees([dists.basic, dists.chrome]);
385
- } else {
386
384
  // Change base tag for running tests in development env.
387
385
  dists.basic = replace(dists.basic, {
388
386
  files: ['tests/index.html'],
389
387
  patterns: [
390
388
  {
391
389
  match: /<base.*\/>/,
392
- replacement: '<base href="../" />',
390
+ replacement: '',
393
391
  },
394
392
  ],
395
393
  });
396
-
394
+ output = mergeTrees([dists.basic, dists.chrome]);
395
+ } else {
397
396
  dists.testing = mergeTrees([dists.basic, dists.chrome]);
398
397
 
399
398
  output = mergeTrees([
@@ -61,17 +61,17 @@ export default class BasicAdapter extends BaseObject {
61
61
  }
62
62
 
63
63
  /**
64
- Inspect a specific DOM node. This usually
64
+ Inspect a js value or specific DOM node. This usually
65
65
  means using the current environment's tools
66
66
  to inspect the node in the DOM.
67
67
 
68
68
  For example, in chrome, `inspect(node)`
69
69
  will open the Elements tab in dev tools
70
70
  and highlight the DOM node.
71
-
72
- @param {Node} node
71
+ For functions, it will open the sources tab and goto the definition
72
+ @param {Node|Function} node
73
73
  */
74
- inspectNode(/* node */) {}
74
+ inspectValue(/* value */) {}
75
75
 
76
76
  _messageReceived(message) {
77
77
  this._messageCallbacks.forEach((callback) => {
@@ -28,15 +28,19 @@ export default class extends BasicAdapter {
28
28
  // "clone" them through postMessage unless they are converted to a
29
29
  // native array.
30
30
  options = deepClone(options);
31
- this._chromePort.postMessage(options);
31
+ try {
32
+ this._chromePort.postMessage(options);
33
+ } catch (e) {
34
+ console.log('failed to send message', e);
35
+ }
32
36
  }
33
37
 
34
38
  /**
35
39
  * Open the devtools "Elements" and select an DOM node.
36
40
  *
37
- * @param {Node} node The DOM node to select
41
+ * @param {Node|Function} value The DOM node to select
38
42
  */
39
- inspectNode(node) {
43
+ inspectValue(value) {
40
44
  // NOTE:
41
45
  //
42
46
  // Basically, we are just trying to call `inspect(node)` here.
@@ -58,9 +62,9 @@ export default class extends BasicAdapter {
58
62
 
59
63
  let name = `__EMBER_INSPECTOR_${(Math.random() * 100000000).toFixed(0)}`;
60
64
 
61
- window[name] = node;
65
+ window[name] = value;
62
66
 
63
- this.namespace.port.send('view:inspectDOMNode', { name });
67
+ this.namespace.port.send('view:inspectJSValue', { name });
64
68
  }
65
69
 
66
70
  _listen() {
@@ -87,7 +87,9 @@ export default class extends DebugPort {
87
87
  * the info tab.
88
88
  */
89
89
  getLibraries() {
90
- this.sendMessage('libraries', { libraries: Ember.libraries._registry });
90
+ this.sendMessage('libraries', {
91
+ libraries: Ember.libraries?._registry,
92
+ });
91
93
  },
92
94
 
93
95
  getEmberCliConfig() {
@@ -1,434 +1,15 @@
1
- import { compareVersion } from 'ember-debug/utils/version';
2
- import Ember from 'ember-debug/utils/ember';
1
+ import { captureRenderTree, getEnv } from 'ember-debug/utils/ember';
3
2
 
4
3
  /* eslint-disable no-console, no-inner-declarations */
5
-
6
- let captureRenderTree;
7
-
4
+ let capture = captureRenderTree;
8
5
  // Ember 3.14+ comes with debug render tree, but the version in 3.14.0/3.14.1 is buggy
9
- if (Ember._captureRenderTree && compareVersion(Ember.VERSION, '3.14.1') > 0) {
10
- if (Ember.ENV._DEBUG_RENDER_TREE) {
11
- captureRenderTree = Ember._captureRenderTree;
6
+ if (captureRenderTree) {
7
+ if (getEnv()._DEBUG_RENDER_TREE) {
8
+ capture = captureRenderTree;
12
9
  } else {
13
- captureRenderTree = function captureRenderTree() {
10
+ capture = function captureRenderTree() {
14
11
  return [];
15
12
  };
16
13
  }
17
- } else {
18
- /**
19
- * Best-effort polyfill for `Ember._captureRenderTree`.
20
- *
21
- * Just like the Ember API, it takes an owner (`ApplicationInstance`, specifically)
22
- * and return an array of render nodes:
23
- *
24
- * interface CapturedRenderNode {
25
- * id: string;
26
- * type: 'outlet' | 'engine' | 'route-template' | 'component';
27
- * name: string;
28
- * args: {
29
- * named: Dict<unknown>;
30
- * positional: unknown[];
31
- * };
32
- * instance: unknown;
33
- * template: Option<string>;
34
- * bounds: Option<{
35
- * parentElement: Simple.Element;
36
- * firstNode: Simple.Node;
37
- * lastNode: Simple.Node;
38
- * }>;
39
- * children: CapturedRenderNode[];
40
- * }
41
- *
42
- * While the API is identical, there are some differences and limitations:
43
- *
44
- * 1. `args` property is not available (it always report empty args).
45
- * 2. `bounds` property is only available on component nodes (`null` everywhere else).
46
- * 3. `{{mount}}` does not insert an `engine` node.
47
- * 4. `Ember.Component` (classic components) are the only type of component in the tree
48
- * (other components are skipped over).
49
- * 5. Ordering of `children` may be different (but this is also not guarenteed in the
50
- * Ember API).
51
- */
52
-
53
- const { Controller, ViewUtils, get, getOwner, guidFor } = Ember;
54
- const { getRootViews, getChildViews, getViewBounds } = ViewUtils;
55
-
56
- /**
57
- * We are building the final tree by doing the following steps:
58
- *
59
- * 1. Get the "outlet state" tree from the router.
60
- * 2. Collect the "top level" components. That is, components rendered directly from within
61
- * a route template.
62
- * 3. Do an "interleaved walk" down the outlet and (classic) component tree and map things
63
- * into render nodes.
64
- * 4. Return the array of render nodes we captured.
65
- *
66
- * Usually, this function returns an array of exactly one render node, which is the "root"
67
- * outlet. However, sometimes there may be other top-level components in the app (e.g.
68
- * rendered using the `Ember.Component#appendTo` API).
69
- */
70
- captureRenderTree = function captureRenderTree(owner) {
71
- let tree = [];
72
- let outletState = getOutletState(owner);
73
- let components = getTopLevelComponents(owner);
74
-
75
- if (outletState && components) {
76
- tree.push(captureOutlet('root', owner, components, outletState));
77
- }
78
-
79
- return tree;
80
- };
81
-
82
- /**
83
- * Get the "outlet state" tree from the router. It corresponds to the "settled",
84
- * app state after resolving all the hooks, redirects, etc. The rendering layer
85
- * takes this tree from the router and render it on screen.
86
- *
87
- * It has the following format:
88
- *
89
- * interface OutletState {
90
- * render: {
91
- * // The current owner, could be the app or an engine
92
- * owner: Owner;
93
- *
94
- * // The name of the route
95
- * name: string;
96
- *
97
- * // The controller for the route
98
- * controller: Controller;
99
- *
100
- * // The template (or template factory?) for the route (can this really be undefined?)
101
- * template: OwnedTemplate | undefined;
102
- *
103
- * // The name of the outlet this was rendered into (in the parent route template)
104
- * outlet: string;
105
- *
106
- * // The name of the parent route (we don't use this)
107
- * into: string | undefined;
108
- * },
109
- *
110
- * // The children outlets of this route, keyed by the outlet names (e.g. "main", "sidebar", ...)
111
- * outlets: Dict<OutletState | undefined>;
112
- * }
113
- *
114
- * This function returns the "root" outlet state.
115
- */
116
- function getOutletState(owner) {
117
- try {
118
- // eslint-disable-next-line ember/no-private-routing-service
119
- return owner.lookup('router:main')._toplevelView.state.ref.value();
120
- } catch (error) {
121
- console.log('[Ember Inspector] failed to capture render tree');
122
- console.log(error);
123
- return undefined;
124
- }
125
- }
126
-
127
- /**
128
- * Collect the "top level" components. That is, components rendered directly
129
- * from within a route template.
130
- *
131
- * We do this by walking the classic component tree and identify components
132
- * that has its "target" (~= the parent template's `{{this}}` object) set to
133
- * a controller (or undefined, for root components rendered outside of the
134
- * application route).
135
- *
136
- * This function returns a `Map` keyed by controllers (`undefiend` is also a
137
- * possible key) to arrays of top-level components for that route/controller.
138
- */
139
- function getTopLevelComponents(owner) {
140
- try {
141
- let map = new Map();
142
- collectComponentsByController(map, null, getRootViews(owner));
143
- return map;
144
- } catch (error) {
145
- console.log('[Ember Inspector] failed to capture render tree');
146
- console.log(error);
147
- return undefined;
148
- }
149
- }
150
-
151
- /**
152
- * Returns the "target" of a (classic) component.
153
- */
154
- function targetForComponent(component) {
155
- return get(component, '_target') || get(component, '_targetObject');
156
- }
157
-
158
- /**
159
- * Recursively walk an array of components and add any "top level" components
160
- * to the map keyed by their controller.
161
- */
162
- function collectComponentsByController(map, controller, components) {
163
- components.forEach((component) => {
164
- let target = targetForComponent(component);
165
-
166
- if (target === undefined || target instanceof Controller) {
167
- /**
168
- * If our parent is already added, don't add ourself again.
169
- *
170
- * This is to prevent something like this:
171
- *
172
- * {{!-- app/templates/application.hbs}}
173
- * <Parent>
174
- * <Child />
175
- * </Parent>
176
- *
177
- * Without this check, both the parent and the yielded child will be
178
- * considered "top level" since they both have the controller as their
179
- * target.
180
- */
181
- if (target !== controller) {
182
- if (!map.has(target)) {
183
- map.set(target, []);
184
- }
185
-
186
- map.get(target).push(component);
187
- }
188
-
189
- collectComponentsByController(map, target, getChildViews(component));
190
- } else {
191
- collectComponentsByController(
192
- map,
193
- controller,
194
- getChildViews(component)
195
- );
196
- }
197
- });
198
- }
199
-
200
- const EMPTY_ARGS = {
201
- named: Object.create(null),
202
- positional: [],
203
- };
204
-
205
- /**
206
- * Return the module name (e.g. `my-app/templates/application.hbs`) for a
207
- * template or template factory, if available. This may not be present for,
208
- * e.g. templates compiled using the "inline" `hbs` tagged string method.
209
- */
210
- function nameForTemplate(template) {
211
- if (template.meta) {
212
- // Factory
213
- return template.meta.moduleName || null;
214
- } else if (template.referrer) {
215
- // Instance
216
- return template.referrer.moduleName || null;
217
- } else {
218
- return null;
219
- }
220
- }
221
-
222
- /**
223
- * Walk an outlet tree (the last parameter) and map its content into render nodes.
224
- *
225
- * For each level of the outlet tree, we also have to walk the (classic) component
226
- * tree to attach any components for the current level (and their children) to the
227
- * resulting render nodes tree.
228
- *
229
- * We also check if the owner has changed between the current level and the previous
230
- * level, and if so, we infer that we must have just crossed an engine boundary and
231
- * insert an engine render node to account for that.
232
- *
233
- * Because we don't have a good way to generate a stable ID for the outlet nodes, we
234
- * also pass down a "path" of the routes/outlets we have encountered so far which we
235
- * use to generate the ID.
236
- */
237
- function captureOutlet(path, owner, components, { outlets, render }) {
238
- let outlet = {
239
- id: `render-node:${path}@${render.outlet}`,
240
- type: 'outlet',
241
- name: render.outlet,
242
- args: EMPTY_ARGS,
243
- instance: undefined,
244
- template: null,
245
- bounds: null,
246
- children: [],
247
- };
248
-
249
- let parent = outlet;
250
-
251
- if (owner !== render.owner) {
252
- let engine = {
253
- id: `render-node:${guidFor(render.owner)}`,
254
- type: 'engine',
255
- name: render.owner.mountPoint,
256
- args: EMPTY_ARGS,
257
- instance: render.owner,
258
- template: null,
259
- bounds: null,
260
- children: [],
261
- };
262
-
263
- parent.children.push(engine);
264
- parent = engine;
265
- }
266
-
267
- let subpath = `${path}@${render.outlet}/${render.name}`;
268
-
269
- let route = {
270
- id: `render-node:${subpath}`,
271
- type: 'route-template',
272
- name: render.name,
273
- args: EMPTY_ARGS,
274
- instance: render.controller,
275
- template: nameForTemplate(render.template),
276
- bounds: null,
277
- children: [],
278
- };
279
-
280
- parent.children.push(route);
281
- parent = route;
282
-
283
- let childOutlets = Object.keys(outlets).map((name) =>
284
- captureOutlet(subpath, render.owner, components, outlets[name])
285
- );
286
-
287
- let childComponents = captureComponents(
288
- components.get(render.controller) || [],
289
- render.controller
290
- );
291
-
292
- parent.children.push(
293
- ...mergeOutletChildren(render.controller, childOutlets, childComponents)
294
- );
295
-
296
- return outlet;
297
- }
298
-
299
- /**
300
- * Its is possible to nest an outlet inside a component, one pretty common example
301
- * is a "layout" component:
302
- *
303
- * <SidebarWrapper>
304
- * {{outlet "sidebar"}}
305
- * </SidebarWrapper>
306
- *
307
- * On the other hand, it's not possible to put a component inside an outlet anymore
308
- * when we get to this point. Try to find a suitable parent for each child outlet
309
- * taking the above into account.
310
- */
311
- function mergeOutletChildren(controller, outlets, components) {
312
- let merged = [];
313
-
314
- for (let outlet of outlets) {
315
- if (controller) {
316
- let parentComponent = findOutletComponentParent(outlet.children);
317
-
318
- if (controllerForComponent(parentComponent) === controller) {
319
- let parentNode = findOutletComponentNode(components, parentComponent);
320
-
321
- if (parentNode) {
322
- parentNode.children.unshift(outlet);
323
- continue;
324
- }
325
- }
326
- }
327
-
328
- merged.push(outlet);
329
- }
330
-
331
- merged.push(...components);
332
-
333
- return merged;
334
- }
335
-
336
- function findOutletComponentParent(nodes) {
337
- let result;
338
-
339
- for (let node of nodes) {
340
- if (node.type === 'component') {
341
- result = node.instance.parentView;
342
- } else if (node.type === 'engine' || node.type === 'route-template') {
343
- result = findOutletComponentParent(node.children);
344
- }
345
-
346
- if (result !== undefined) {
347
- return result;
348
- }
349
- }
350
- }
351
-
352
- function findOutletComponentNode(nodes, instance) {
353
- let result;
354
-
355
- for (let node of nodes) {
356
- if (node.type === 'component') {
357
- if (node.instance === instance) {
358
- result = node;
359
- } else {
360
- result = findOutletComponentNode(node.children, instance);
361
- }
362
- }
363
-
364
- if (result !== undefined) {
365
- return result;
366
- }
367
- }
368
- }
369
-
370
- /**
371
- * Returns the name of a (classic) component.
372
- */
373
- function nameForComponent(component) {
374
- // remove "component:" prefix
375
- return component._debugContainerKey.slice(10);
376
- }
377
-
378
- /**
379
- * Returns the nearest controller of a (classic) component. This is so that we know
380
- * whether a given component belongs to the current level (the route that we are
381
- * processing right now) or not.
382
- */
383
- function controllerForComponent(component) {
384
- let target = component;
385
-
386
- while (target && !(target instanceof Controller)) {
387
- target = targetForComponent(target);
388
- }
389
-
390
- return target;
391
- }
392
-
393
- /**
394
- * Returns the template (or template factory?) for a (classic) component.
395
- */
396
- function templateForComponent(component) {
397
- let layout = get(component, 'layout');
398
-
399
- if (layout) {
400
- return nameForTemplate(layout);
401
- }
402
-
403
- let layoutName = get(component, 'layoutName');
404
-
405
- if (layoutName) {
406
- let owner = getOwner(component);
407
- let template = owner.lookup(`template:${layoutName}`);
408
- return nameForTemplate(template);
409
- }
410
-
411
- return null;
412
- }
413
-
414
- /**
415
- * Return the render node for a given (classic) component, and its children up
416
- * until the next route boundary.
417
- */
418
- function captureComponents(components, controller) {
419
- return components
420
- .filter((component) => controllerForComponent(component) === controller)
421
- .map((component) => ({
422
- id: `render-node:${guidFor(component)}`,
423
- type: 'component',
424
- name: nameForComponent(component),
425
- args: EMPTY_ARGS,
426
- instance: component,
427
- template: templateForComponent(component),
428
- bounds: getViewBounds(component),
429
- children: captureComponents(getChildViews(component), controller),
430
- }));
431
- }
432
14
  }
433
-
434
- export default captureRenderTree;
15
+ export default capture;