ember-inspector 4.11.0-alpha.2024.3.9 → 4.11.0-alpha.2024.4.1
Sign up to get free protection for your applications and to get access to all the features.
- package/app/components/component-tree-arg.js +9 -0
- package/app/components/component-tree-item.hbs +18 -2
- package/app/components/object-inspector/properties-all.hbs +1 -0
- package/app/components/object-inspector/properties-base.js +10 -0
- package/app/components/object-inspector/properties-grouped.hbs +1 -0
- package/app/components/object-inspector/property.hbs +12 -1
- package/app/components/object-inspector/property.ts +4 -2
- package/app/components/object-inspector.hbs +16 -2
- package/app/components/object-inspector.js +14 -0
- package/app/controllers/component-tree.js +54 -3
- package/app/routes/component-tree.js +0 -6
- package/app/services/adapters/web-extension.js +3 -3
- package/app/services/port.js +4 -0
- package/app/styles/component_tree.scss +13 -0
- package/app/utils/parse-text.ts +1 -0
- package/dist/bookmarklet/panes-3-16-0/assets/{chunk.143.ac621af5331b75527946.js → chunk.143.113e8b75c912ce3c25a2.js} +4 -4
- package/dist/{firefox/panes-3-16-0/assets/chunk.178.e6b2f8bb19b9f072aa49.js → bookmarklet/panes-3-16-0/assets/chunk.178.d4c26666ebefd8cf7ed3.js} +3 -3
- package/dist/bookmarklet/panes-3-16-0/assets/ember-inspector.css +13 -0
- package/dist/bookmarklet/panes-3-16-0/assets/ember-inspector.js +27 -23
- package/dist/bookmarklet/panes-3-16-0/assets/svg/code-source.svg +9 -0
- package/dist/bookmarklet/panes-3-16-0/assets/vendor.css +33 -0
- package/dist/bookmarklet/panes-3-16-0/assets/vendor.js +12 -10
- package/dist/bookmarklet/panes-3-16-0/ember_debug.js +408 -538
- package/dist/bookmarklet/panes-3-16-0/index.html +2 -2
- package/dist/chrome/manifest.json +2 -2
- package/dist/{firefox/panes-3-16-0/assets/chunk.143.ac621af5331b75527946.js → chrome/panes-3-16-0/assets/chunk.143.113e8b75c912ce3c25a2.js} +4 -4
- package/dist/{bookmarklet/panes-3-16-0/assets/chunk.178.e6b2f8bb19b9f072aa49.js → chrome/panes-3-16-0/assets/chunk.178.d4c26666ebefd8cf7ed3.js} +3 -3
- package/dist/chrome/panes-3-16-0/assets/ember-inspector.css +13 -0
- package/dist/chrome/panes-3-16-0/assets/ember-inspector.js +27 -23
- package/dist/chrome/panes-3-16-0/assets/svg/code-source.svg +9 -0
- package/dist/chrome/panes-3-16-0/assets/vendor.css +33 -0
- package/dist/chrome/panes-3-16-0/assets/vendor.js +12 -10
- package/dist/chrome/panes-3-16-0/ember_debug.js +408 -538
- package/dist/chrome/panes-3-16-0/index.html +2 -2
- package/dist/firefox/manifest.json +2 -2
- package/dist/{chrome/panes-3-16-0/assets/chunk.143.ac621af5331b75527946.js → firefox/panes-3-16-0/assets/chunk.143.113e8b75c912ce3c25a2.js} +4 -4
- package/dist/{websocket/assets/chunk.178.e6b2f8bb19b9f072aa49.js → firefox/panes-3-16-0/assets/chunk.178.d4c26666ebefd8cf7ed3.js} +3 -3
- package/dist/firefox/panes-3-16-0/assets/ember-inspector.css +13 -0
- package/dist/firefox/panes-3-16-0/assets/ember-inspector.js +27 -23
- package/dist/firefox/panes-3-16-0/assets/svg/code-source.svg +9 -0
- package/dist/firefox/panes-3-16-0/assets/vendor.css +33 -0
- package/dist/firefox/panes-3-16-0/assets/vendor.js +12 -10
- package/dist/firefox/panes-3-16-0/ember_debug.js +408 -538
- package/dist/firefox/panes-3-16-0/index.html +2 -2
- package/dist/websocket/assets/{chunk.143.ac621af5331b75527946.js → chunk.143.113e8b75c912ce3c25a2.js} +4 -4
- package/dist/{chrome/panes-3-16-0/assets/chunk.178.e6b2f8bb19b9f072aa49.js → websocket/assets/chunk.178.d4c26666ebefd8cf7ed3.js} +3 -3
- package/dist/websocket/assets/ember-inspector.css +13 -0
- package/dist/websocket/assets/ember-inspector.js +27 -23
- package/dist/websocket/assets/svg/code-source.svg +9 -0
- package/dist/websocket/assets/vendor.css +33 -0
- package/dist/websocket/assets/vendor.js +12 -10
- package/dist/websocket/ember_debug.js +408 -538
- package/dist/websocket/index.html +2 -2
- package/ember-cli-build.js +3 -4
- package/ember_debug/adapters/basic.js +4 -4
- package/ember_debug/adapters/web-extension.js +9 -5
- package/ember_debug/general-debug.js +3 -1
- package/ember_debug/libs/capture-render-tree.js +7 -426
- package/ember_debug/libs/render-tree.js +210 -31
- package/ember_debug/libs/view-inspection.js +28 -0
- package/ember_debug/object-inspector.js +49 -88
- package/ember_debug/route-debug.js +2 -3
- package/ember_debug/utils/ember.js +16 -0
- package/ember_debug/utils/get-object-name.js +4 -0
- package/ember_debug/utils/name-functions.js +1 -1
- package/ember_debug/utils/type-check.js +82 -12
- package/ember_debug/utils/version.js +37 -0
- package/ember_debug/view-debug.js +1 -1
- package/lib/ui/addon/styles/_goto-source.scss +30 -0
- package/lib/ui/addon/styles/addon.scss +1 -0
- package/lib/ui/addon/styles/toolbar/_index.scss +4 -0
- package/package.json +1 -1
- package/public/assets/svg/code-source.svg +9 -0
- package/skeletons/web-extension/manifest.json +2 -2
- package/tests/acceptance/object-inspector-test.js +68 -0
- package/tests/ember_debug/view-debug-test.js +211 -69
- package/tests/index.html +1 -0
@@ -1,6 +1,9 @@
|
|
1
1
|
import captureRenderTree from './capture-render-tree';
|
2
2
|
import { guidFor } from 'ember-debug/utils/ember/object/internals';
|
3
|
-
import { EmberLoader } from 'ember-debug/utils/ember/loader';
|
3
|
+
import { EmberLoader, emberSafeRequire } from 'ember-debug/utils/ember/loader';
|
4
|
+
import { inspect } from 'ember-debug/utils/type-check';
|
5
|
+
import { isInVersionSpecifier } from 'ember-debug/utils/version';
|
6
|
+
import { VERSION } from 'ember-debug/utils/ember';
|
4
7
|
|
5
8
|
class InElementSupportProvider {
|
6
9
|
constructor(owner) {
|
@@ -14,6 +17,12 @@ class InElementSupportProvider {
|
|
14
17
|
// nope
|
15
18
|
}
|
16
19
|
|
20
|
+
this.DESTROY = emberSafeRequire('@glimmer/util')?.DESTROY;
|
21
|
+
this.registerDestructor =
|
22
|
+
emberSafeRequire('@glimmer/destroyable')?.registerDestructor ||
|
23
|
+
emberSafeRequire('@ember/destroyable')?.registerDestructor ||
|
24
|
+
emberSafeRequire('@ember/runtime')?.registerDestructor;
|
25
|
+
|
17
26
|
this.debugRenderTree =
|
18
27
|
owner.lookup('renderer:-dom')?.debugRenderTree ||
|
19
28
|
owner.lookup('service:-glimmer-environment')._debugRenderTree;
|
@@ -31,9 +40,10 @@ class InElementSupportProvider {
|
|
31
40
|
const self = this;
|
32
41
|
|
33
42
|
const NewElementBuilder = this.NewElementBuilder;
|
34
|
-
const remoteStack = [];
|
35
43
|
const componentStack = [];
|
36
44
|
|
45
|
+
const enableModifierSupport = isInVersionSpecifier('>3.28.0', VERSION);
|
46
|
+
|
37
47
|
function createRef(value) {
|
38
48
|
if (self.reference.createUnboundRef) {
|
39
49
|
return self.reference.createUnboundRef(value);
|
@@ -42,6 +52,16 @@ class InElementSupportProvider {
|
|
42
52
|
}
|
43
53
|
}
|
44
54
|
|
55
|
+
function createArgs(args) {
|
56
|
+
if (self.reference.createUnboundRef) {
|
57
|
+
return args;
|
58
|
+
} else {
|
59
|
+
return {
|
60
|
+
value: () => args,
|
61
|
+
};
|
62
|
+
}
|
63
|
+
}
|
64
|
+
|
45
65
|
const appendChild = this.debugRenderTree.appendChild;
|
46
66
|
this.debugRenderTree.appendChild = function (node, state) {
|
47
67
|
if (node.type === 'component') {
|
@@ -56,7 +76,7 @@ class InElementSupportProvider {
|
|
56
76
|
if (node?.type === 'component') {
|
57
77
|
componentStack.pop();
|
58
78
|
}
|
59
|
-
exit.call(this, state);
|
79
|
+
return exit.call(this, state);
|
60
80
|
};
|
61
81
|
|
62
82
|
const didAppendNode = NewElementBuilder.prototype.didAppendNode;
|
@@ -71,13 +91,91 @@ class InElementSupportProvider {
|
|
71
91
|
args[0].__emberInspectorParentNode = componentStack.at(-1);
|
72
92
|
};
|
73
93
|
|
94
|
+
const pushModifiers = NewElementBuilder.prototype.pushModifiers;
|
95
|
+
if (enableModifierSupport) {
|
96
|
+
NewElementBuilder.prototype.pushModifiers = function (modifiers) {
|
97
|
+
const debugRenderTree = self.debugRenderTree;
|
98
|
+
if (debugRenderTree) {
|
99
|
+
modifiers = modifiers || [];
|
100
|
+
const modifier = modifiers[0];
|
101
|
+
let element = null;
|
102
|
+
if (modifiers.length) {
|
103
|
+
element = modifier[1]?.element || modifier.state.element;
|
104
|
+
}
|
105
|
+
for (const modifier of modifiers) {
|
106
|
+
const state = {};
|
107
|
+
const modifierState =
|
108
|
+
modifier.state?.instance || modifier.state || modifier[1];
|
109
|
+
const instance = modifierState?.instance || modifierState?.delegate;
|
110
|
+
let name =
|
111
|
+
modifier.definition?.resolvedName ||
|
112
|
+
modifierState?.debugName ||
|
113
|
+
instance?.name;
|
114
|
+
if (!name) {
|
115
|
+
try {
|
116
|
+
name = modifier.manager?.getDebugName?.();
|
117
|
+
} catch (e) {
|
118
|
+
// failed
|
119
|
+
}
|
120
|
+
name = name || 'unknown-modifier';
|
121
|
+
}
|
122
|
+
const args = {
|
123
|
+
positional: [],
|
124
|
+
named: {},
|
125
|
+
};
|
126
|
+
const positional =
|
127
|
+
modifierState?.args?.positional?.references ||
|
128
|
+
modifierState?.args?.positional ||
|
129
|
+
[];
|
130
|
+
for (const value of positional) {
|
131
|
+
if (value && value[self.reference.REFERENCE]) {
|
132
|
+
args.positional.push(value);
|
133
|
+
} else {
|
134
|
+
args.positional.push(createRef(value));
|
135
|
+
}
|
136
|
+
}
|
137
|
+
let named = modifierState?.args?.named;
|
138
|
+
if (!self.reference.createUnboundRef) {
|
139
|
+
try {
|
140
|
+
named = modifierState?.args?.named?.constructor;
|
141
|
+
} catch (e) {
|
142
|
+
//
|
143
|
+
}
|
144
|
+
try {
|
145
|
+
named = named || modifierState?.args?.named?.map;
|
146
|
+
} catch (e) {
|
147
|
+
//
|
148
|
+
}
|
149
|
+
}
|
150
|
+
for (const [key, value] of Object.entries(named || {})) {
|
151
|
+
args.named[key] = createRef(value);
|
152
|
+
}
|
153
|
+
debugRenderTree?.create(state, {
|
154
|
+
type: 'modifier',
|
155
|
+
name,
|
156
|
+
args: createArgs(args),
|
157
|
+
instance: instance,
|
158
|
+
});
|
159
|
+
debugRenderTree?.didRender(state, {
|
160
|
+
parentElement: () => element.parentElement,
|
161
|
+
firstNode: () => element,
|
162
|
+
lastNode: () => element,
|
163
|
+
});
|
164
|
+
self.registerDestructor(modifier.state, () => {
|
165
|
+
debugRenderTree?.willDestroy(state);
|
166
|
+
});
|
167
|
+
}
|
168
|
+
}
|
169
|
+
return pushModifiers.call(this, modifiers);
|
170
|
+
};
|
171
|
+
}
|
172
|
+
|
74
173
|
const pushRemoteElement = NewElementBuilder.prototype.pushRemoteElement;
|
75
174
|
NewElementBuilder.prototype.pushRemoteElement = function (
|
76
175
|
element,
|
77
176
|
guid,
|
78
177
|
insertBefore
|
79
178
|
) {
|
80
|
-
remoteStack.push({ element });
|
81
179
|
const ref = createRef(element);
|
82
180
|
const capturedArgs = {
|
83
181
|
positional: [ref],
|
@@ -86,18 +184,27 @@ class InElementSupportProvider {
|
|
86
184
|
if (insertBefore) {
|
87
185
|
capturedArgs.named.insertBefore = insertBefore;
|
88
186
|
}
|
89
|
-
const inElementArgs = self.reference.createUnboundRef
|
90
|
-
? capturedArgs
|
91
|
-
: {
|
92
|
-
value() {
|
93
|
-
return capturedArgs;
|
94
|
-
},
|
95
|
-
};
|
96
187
|
const debugRenderTree = self.debugRenderTree;
|
97
|
-
|
188
|
+
|
189
|
+
const r = pushRemoteElement.call(this, element, guid, insertBefore);
|
190
|
+
const block = this.blockStack.current;
|
191
|
+
|
192
|
+
if (this.DESTROY) {
|
193
|
+
const destructor = block[this.DESTROY];
|
194
|
+
block[this.DESTROY] = function () {
|
195
|
+
self.debugRenderTree?.willDestroy(block);
|
196
|
+
destructor.call(this);
|
197
|
+
};
|
198
|
+
} else {
|
199
|
+
self.registerDestructor?.(block, () => {
|
200
|
+
self.debugRenderTree?.willDestroy(block);
|
201
|
+
});
|
202
|
+
}
|
203
|
+
|
204
|
+
debugRenderTree?.create(block, {
|
98
205
|
type: 'keyword',
|
99
206
|
name: 'in-element',
|
100
|
-
args:
|
207
|
+
args: createArgs(capturedArgs),
|
101
208
|
instance: {
|
102
209
|
args: {
|
103
210
|
named: {
|
@@ -110,21 +217,20 @@ class InElementSupportProvider {
|
|
110
217
|
},
|
111
218
|
},
|
112
219
|
});
|
113
|
-
return
|
220
|
+
return r;
|
114
221
|
};
|
115
222
|
|
116
223
|
const popRemoteElement = NewElementBuilder.prototype.popRemoteElement;
|
117
224
|
NewElementBuilder.prototype.popRemoteElement = function (...args) {
|
118
|
-
const
|
225
|
+
const block = this.blockStack.current;
|
119
226
|
popRemoteElement.call(this, ...args);
|
120
227
|
const parentElement = this.element;
|
121
228
|
const debugRenderTree = self.debugRenderTree;
|
122
|
-
debugRenderTree?.didRender(
|
229
|
+
debugRenderTree?.didRender(block, {
|
123
230
|
parentElement: () => parentElement,
|
124
|
-
firstNode: () =>
|
125
|
-
lastNode: () =>
|
231
|
+
firstNode: () => block.firstNode(),
|
232
|
+
lastNode: () => block.lastNode(),
|
126
233
|
});
|
127
|
-
remoteStack.pop();
|
128
234
|
};
|
129
235
|
|
130
236
|
this.debugRenderTreeFunctions = {
|
@@ -136,6 +242,7 @@ class InElementSupportProvider {
|
|
136
242
|
pushRemoteElement,
|
137
243
|
popRemoteElement,
|
138
244
|
didAppendNode,
|
245
|
+
pushModifiers,
|
139
246
|
};
|
140
247
|
}
|
141
248
|
|
@@ -148,6 +255,7 @@ class InElementSupportProvider {
|
|
148
255
|
this.NewElementBuilder.prototype,
|
149
256
|
this.NewElementBuilderFunctions
|
150
257
|
);
|
258
|
+
this.NewElementBuilderFunctions = null;
|
151
259
|
}
|
152
260
|
|
153
261
|
require(req) {
|
@@ -175,7 +283,8 @@ export default class RenderTree {
|
|
175
283
|
try {
|
176
284
|
this.inElementSupport = new InElementSupportProvider(owner);
|
177
285
|
} catch (e) {
|
178
|
-
console.error('failed to setup in element support'
|
286
|
+
console.error('failed to setup in element support');
|
287
|
+
console.error(e);
|
179
288
|
// not supported
|
180
289
|
}
|
181
290
|
|
@@ -408,18 +517,47 @@ export default class RenderTree {
|
|
408
517
|
this.retainedObjects = new Map();
|
409
518
|
}
|
410
519
|
|
411
|
-
|
520
|
+
_createSimpleInstance(name, args) {
|
412
521
|
const obj = Object.create(null);
|
413
522
|
obj.args = args;
|
414
523
|
obj.constructor = {
|
415
|
-
name:
|
524
|
+
name: name,
|
416
525
|
comment: 'fake constructor',
|
417
526
|
};
|
418
527
|
return obj;
|
419
528
|
}
|
420
529
|
|
530
|
+
_insertHtmlElementNode(node, parentNode) {
|
531
|
+
const element = node.bounds.firstNode;
|
532
|
+
const htmlNode = {
|
533
|
+
id: node.id + 'html-element',
|
534
|
+
type: 'html-element',
|
535
|
+
name: element.tagName.toLowerCase(),
|
536
|
+
instance: element,
|
537
|
+
template: null,
|
538
|
+
bounds: {
|
539
|
+
firstNode: element,
|
540
|
+
lastNode: element,
|
541
|
+
parentElement: element.parentElement,
|
542
|
+
},
|
543
|
+
args: {
|
544
|
+
named: {},
|
545
|
+
positional: [],
|
546
|
+
},
|
547
|
+
children: [],
|
548
|
+
};
|
549
|
+
const idx = parentNode.children.indexOf(node);
|
550
|
+
parentNode.children.splice(idx, 0, htmlNode);
|
551
|
+
return this._serializeRenderNode(htmlNode, parentNode);
|
552
|
+
}
|
553
|
+
|
421
554
|
_serializeRenderNodes(nodes, parentNode = null) {
|
422
|
-
|
555
|
+
const mapped = [];
|
556
|
+
// nodes can be mutated during serialize, which is why we use indexing instead of .map
|
557
|
+
for (let i = 0; i < nodes.length; i++) {
|
558
|
+
mapped.push(this._serializeRenderNode(nodes[i], parentNode));
|
559
|
+
}
|
560
|
+
return mapped;
|
423
561
|
}
|
424
562
|
|
425
563
|
_serializeRenderNode(node, parentNode = null) {
|
@@ -460,15 +598,49 @@ export default class RenderTree {
|
|
460
598
|
this.parentNodes[node.id] = parentNode;
|
461
599
|
}
|
462
600
|
|
601
|
+
if (node.type === 'html-element') {
|
602
|
+
// show set attributes in inspector
|
603
|
+
Array.from(node.instance.attributes).forEach((attr) => {
|
604
|
+
node.args.named[attr.nodeName] = attr.nodeValue;
|
605
|
+
});
|
606
|
+
// move modifiers and components into the element children
|
607
|
+
parentNode.children.forEach((child) => {
|
608
|
+
if (
|
609
|
+
child.bounds.parentElement === node.instance ||
|
610
|
+
(child.type === 'modifier' &&
|
611
|
+
child.bounds.firstNode === node.instance)
|
612
|
+
) {
|
613
|
+
node.children.push(child);
|
614
|
+
}
|
615
|
+
});
|
616
|
+
node.children.forEach((child) => {
|
617
|
+
const idx = parentNode.children.indexOf(child);
|
618
|
+
if (idx >= 0) {
|
619
|
+
parentNode.children.splice(idx, 1);
|
620
|
+
}
|
621
|
+
});
|
622
|
+
}
|
623
|
+
|
624
|
+
if (node.type === 'component' && !node.instance) {
|
625
|
+
node.instance = this._createSimpleInstance(
|
626
|
+
'TemplateOnlyComponent',
|
627
|
+
node.args.named
|
628
|
+
);
|
629
|
+
}
|
630
|
+
|
631
|
+
if (node.type === 'modifier') {
|
632
|
+
node.instance =
|
633
|
+
node.instance || this._createSimpleInstance(node.name, node.args);
|
634
|
+
node.instance.toString = () => node.name;
|
635
|
+
if (parentNode.instance !== node.bounds.firstNode) {
|
636
|
+
return this._insertHtmlElementNode(node, parentNode);
|
637
|
+
}
|
638
|
+
}
|
639
|
+
|
463
640
|
this.serialized[node.id] = serialized = {
|
464
641
|
...node,
|
465
642
|
args: this._serializeArgs(node.args),
|
466
|
-
instance: this._serializeItem(
|
467
|
-
node.instance ||
|
468
|
-
(node.type === 'component'
|
469
|
-
? this._createTemplateOnlyComponent(node.args.named)
|
470
|
-
: undefined)
|
471
|
-
),
|
643
|
+
instance: this._serializeItem(node.instance),
|
472
644
|
bounds: this._serializeBounds(node.bounds),
|
473
645
|
children: this._serializeRenderNodes(node.children, node),
|
474
646
|
};
|
@@ -535,7 +707,7 @@ export default class RenderTree {
|
|
535
707
|
|
536
708
|
this.retainedObjects.set(object, id);
|
537
709
|
|
538
|
-
return { id };
|
710
|
+
return { id, type: typeof object, inspect: inspect(object) };
|
539
711
|
}
|
540
712
|
|
541
713
|
_releaseStaleObjects() {
|
@@ -578,8 +750,15 @@ export default class RenderTree {
|
|
578
750
|
while (candidates.length > 0) {
|
579
751
|
let candidate = candidates.shift();
|
580
752
|
let range = this.getRange(candidate.id);
|
753
|
+
const isAllowed =
|
754
|
+
candidate.type !== 'modifier' && candidate.type !== 'html-element';
|
755
|
+
|
756
|
+
if (!isAllowed) {
|
757
|
+
candidates.push(...candidate.children);
|
758
|
+
continue;
|
759
|
+
}
|
581
760
|
|
582
|
-
if (range && range.isPointInRange(dom, 0)) {
|
761
|
+
if (isAllowed && range && range.isPointInRange(dom, 0)) {
|
583
762
|
// We may be able to find a more exact match in one of the children.
|
584
763
|
return (
|
585
764
|
this._matchRenderNodes(candidate.children, dom, false) || candidate
|
@@ -78,6 +78,22 @@ function makeStylesheet(id) {
|
|
78
78
|
color: rgb(168, 148, 166);
|
79
79
|
}
|
80
80
|
|
81
|
+
#${prefix}-tooltip-${id} .${prefix}-tooltip-detail-instance > .${prefix}-tooltip-token-tag {
|
82
|
+
cursor: pointer;
|
83
|
+
}
|
84
|
+
|
85
|
+
#${prefix}-tooltip-${id} .${prefix}-tooltip-detail-instance > .${prefix}-tooltip-token-tag:after {
|
86
|
+
content: "\\1F517"
|
87
|
+
}
|
88
|
+
|
89
|
+
#${prefix}-tooltip-${id} .${prefix}-tooltip-detail-controller > .${prefix}-tooltip-token-tag {
|
90
|
+
cursor: pointer;
|
91
|
+
}
|
92
|
+
|
93
|
+
#${prefix}-tooltip-${id} .${prefix}-tooltip-detail-controller > .${prefix}-tooltip-token-tag:after {
|
94
|
+
content: "\\1F517"
|
95
|
+
}
|
96
|
+
|
81
97
|
#${prefix}-tooltip-${id} .${prefix}-tooltip-token-name {
|
82
98
|
/* https://github.com/ChromeDevTools/devtools-frontend/blob/103326238685ac582d3bf2a02f1627a80e3fce5f/front_end/ui/inspectorSyntaxHighlight.css#L60 */
|
83
99
|
color: rgb(136, 18, 128);
|
@@ -505,6 +521,18 @@ export default class ViewInspection {
|
|
505
521
|
this._tokenizeItem(node.instance)
|
506
522
|
);
|
507
523
|
}
|
524
|
+
const detail =
|
525
|
+
tbody.querySelector(
|
526
|
+
'.ember-inspector-tooltip-detail-instance > .ember-inspector-tooltip-token-tag'
|
527
|
+
) ||
|
528
|
+
tbody.querySelector(
|
529
|
+
'.ember-inspector-tooltip-detail-controller > .ember-inspector-tooltip-token-tag'
|
530
|
+
);
|
531
|
+
if (detail) {
|
532
|
+
detail.onclick = () => {
|
533
|
+
this.objectInspector.sendToConsole(node.instance.id);
|
534
|
+
};
|
535
|
+
}
|
508
536
|
}
|
509
537
|
}
|
510
538
|
|
@@ -3,21 +3,27 @@ import DebugPort from './debug-port';
|
|
3
3
|
import bound from 'ember-debug/utils/bound-method';
|
4
4
|
import {
|
5
5
|
isComputed,
|
6
|
-
isDescriptor,
|
7
6
|
getDescriptorFor,
|
8
7
|
typeOf,
|
8
|
+
inspect,
|
9
9
|
} from 'ember-debug/utils/type-check';
|
10
10
|
import { compareVersion } from 'ember-debug/utils/version';
|
11
|
-
import {
|
12
|
-
|
11
|
+
import {
|
12
|
+
EmberObject,
|
13
|
+
meta as emberMeta,
|
14
|
+
VERSION,
|
15
|
+
CoreObject,
|
16
|
+
ObjectProxy,
|
17
|
+
ArrayProxy,
|
18
|
+
Service,
|
19
|
+
Component,
|
20
|
+
} from 'ember-debug/utils/ember';
|
13
21
|
import { cacheFor, guidFor } from 'ember-debug/utils/ember/object/internals';
|
14
22
|
import { _backburner, join } from 'ember-debug/utils/ember/runloop';
|
15
23
|
import emberNames from './utils/ember-object-names';
|
16
24
|
import getObjectName from './utils/get-object-name';
|
17
25
|
import { EmberLoader } from 'ember-debug/utils/ember/loader';
|
18
26
|
|
19
|
-
const { meta: emberMeta, VERSION, CoreObject, ObjectProxy } = Ember;
|
20
|
-
|
21
27
|
const GlimmerComponent = (() => {
|
22
28
|
try {
|
23
29
|
return EmberLoader.require('@glimmer/component').default;
|
@@ -88,7 +94,7 @@ try {
|
|
88
94
|
|
89
95
|
const HAS_GLIMMER_TRACKING = tagValue && tagValidate && track && tagForProperty;
|
90
96
|
|
91
|
-
const keys = Object.keys
|
97
|
+
const keys = Object.keys;
|
92
98
|
|
93
99
|
/**
|
94
100
|
* Determine the type and get the value of the passed property
|
@@ -107,6 +113,12 @@ function inspectValue(object, key, computedValue) {
|
|
107
113
|
|
108
114
|
// TODO: this is not very clean. We should refactor calculateCP, etc, rather than passing computedValue
|
109
115
|
if (computedValue !== undefined) {
|
116
|
+
if (value instanceof HTMLElement) {
|
117
|
+
return {
|
118
|
+
type: 'type-object',
|
119
|
+
inspect: `<${value.tagName.toLowerCase()}>`,
|
120
|
+
};
|
121
|
+
}
|
110
122
|
return { type: `type-${typeOf(value)}`, inspect: inspect(value) };
|
111
123
|
}
|
112
124
|
|
@@ -115,89 +127,16 @@ function inspectValue(object, key, computedValue) {
|
|
115
127
|
} else if (isComputed(object, key)) {
|
116
128
|
string = '<computed>';
|
117
129
|
return { type: 'type-descriptor', inspect: string };
|
118
|
-
} else if (isDescriptor
|
130
|
+
} else if (value?.isDescriptor) {
|
119
131
|
return { type: 'type-descriptor', inspect: value.toString() };
|
132
|
+
} else if (value instanceof HTMLElement) {
|
133
|
+
return { type: 'type-object', inspect: value.tagName.toLowerCase() };
|
120
134
|
} else {
|
121
135
|
return { type: `type-${typeOf(value)}`, inspect: inspect(value) };
|
122
136
|
}
|
123
137
|
}
|
124
138
|
|
125
|
-
function inspect(value) {
|
126
|
-
if (typeof value === 'function') {
|
127
|
-
return 'function() { ... }';
|
128
|
-
} else if (value instanceof EmberObject) {
|
129
|
-
return value.toString();
|
130
|
-
} else if (typeOf(value) === 'array') {
|
131
|
-
if (value.length === 0) {
|
132
|
-
return '[]';
|
133
|
-
} else if (value.length === 1) {
|
134
|
-
return `[ ${inspect(value[0])} ]`;
|
135
|
-
} else {
|
136
|
-
return `[ ${inspect(value[0])}, ... ]`;
|
137
|
-
}
|
138
|
-
} else if (value instanceof Error) {
|
139
|
-
return `Error: ${value.message}`;
|
140
|
-
} else if (value === null) {
|
141
|
-
return 'null';
|
142
|
-
} else if (typeOf(value) === 'date') {
|
143
|
-
return value.toString();
|
144
|
-
} else if (typeof value === 'object') {
|
145
|
-
// `Ember.inspect` is able to handle this use case,
|
146
|
-
// but it is very slow as it loops over all props,
|
147
|
-
// so summarize to just first 2 props
|
148
|
-
// if it defines a toString, we use that instead
|
149
|
-
if (
|
150
|
-
typeof value.toString === 'function' &&
|
151
|
-
value.toString !== Object.prototype.toString &&
|
152
|
-
value.toString !== Function.prototype.toString
|
153
|
-
) {
|
154
|
-
try {
|
155
|
-
return `<Object:${value.toString()}>`;
|
156
|
-
} catch (e) {
|
157
|
-
//
|
158
|
-
}
|
159
|
-
}
|
160
|
-
let ret = [];
|
161
|
-
let v;
|
162
|
-
let count = 0;
|
163
|
-
let broken = false;
|
164
|
-
|
165
|
-
for (let key in value) {
|
166
|
-
if (!('hasOwnProperty' in value) || value.hasOwnProperty(key)) {
|
167
|
-
if (count++ > 1) {
|
168
|
-
broken = true;
|
169
|
-
break;
|
170
|
-
}
|
171
|
-
v = value[key];
|
172
|
-
if (v === 'toString') {
|
173
|
-
continue;
|
174
|
-
} // ignore useless items
|
175
|
-
if (typeOf(v).includes('function')) {
|
176
|
-
v = 'function() { ... }';
|
177
|
-
}
|
178
|
-
if (typeOf(v) === 'array') {
|
179
|
-
v = `[Array : ${v.length}]`;
|
180
|
-
}
|
181
|
-
if (typeOf(v) === 'object') {
|
182
|
-
v = '[Object]';
|
183
|
-
}
|
184
|
-
ret.push(`${key}: ${v}`);
|
185
|
-
}
|
186
|
-
}
|
187
|
-
let suffix = ' }';
|
188
|
-
if (broken) {
|
189
|
-
suffix = ' ...}';
|
190
|
-
}
|
191
|
-
return `{ ${ret.join(', ')}${suffix}`;
|
192
|
-
} else {
|
193
|
-
return emberInspect(value);
|
194
|
-
}
|
195
|
-
}
|
196
|
-
|
197
139
|
function isMandatorySetter(descriptor) {
|
198
|
-
if (descriptor.set && descriptor.set === Ember.MANDATORY_SETTER_FUNCTION) {
|
199
|
-
return true;
|
200
|
-
}
|
201
140
|
if (
|
202
141
|
descriptor.set &&
|
203
142
|
Function.prototype.toString
|
@@ -431,6 +370,9 @@ export default class extends DebugPort {
|
|
431
370
|
sendToConsole(message) {
|
432
371
|
this.sendToConsole(message.objectId, message.property);
|
433
372
|
},
|
373
|
+
gotoSource(message) {
|
374
|
+
this.gotoSource(message.objectId, message.property);
|
375
|
+
},
|
434
376
|
sendControllerToConsole(message) {
|
435
377
|
const container = this.namespace?.owner;
|
436
378
|
this.sendValueToConsole(container.lookup(`controller:${message.name}`));
|
@@ -516,6 +458,26 @@ export default class extends DebugPort {
|
|
516
458
|
});
|
517
459
|
}
|
518
460
|
|
461
|
+
gotoSource(objectId, prop) {
|
462
|
+
let object = this.sentObjects[objectId];
|
463
|
+
let value;
|
464
|
+
|
465
|
+
if (prop === null || prop === undefined) {
|
466
|
+
value = this.sentObjects[objectId];
|
467
|
+
} else {
|
468
|
+
value = calculateCP(object, { name: prop }, {});
|
469
|
+
}
|
470
|
+
// for functions and classes we want to show the source
|
471
|
+
if (typeof value === 'function') {
|
472
|
+
this.adapter.inspectValue(value);
|
473
|
+
}
|
474
|
+
// use typeOf to distinguish basic objects/classes and Date, Error etc.
|
475
|
+
// objects like {...} have the constructor set to Object
|
476
|
+
if (typeOf(value) === 'object' && value.constructor !== Object) {
|
477
|
+
this.adapter.inspectValue(value.constructor);
|
478
|
+
}
|
479
|
+
}
|
480
|
+
|
519
481
|
sendToConsole(objectId, prop) {
|
520
482
|
let object = this.sentObjects[objectId];
|
521
483
|
let value;
|
@@ -675,7 +637,6 @@ export default class extends DebugPort {
|
|
675
637
|
// insert ember mixins
|
676
638
|
for (let mixin of own) {
|
677
639
|
let name = (
|
678
|
-
mixin[Ember.NAME_KEY] ||
|
679
640
|
mixin.ownerConstructor ||
|
680
641
|
emberNames.get(mixin) ||
|
681
642
|
''
|
@@ -722,7 +683,7 @@ export default class extends DebugPort {
|
|
722
683
|
}
|
723
684
|
|
724
685
|
if (
|
725
|
-
object instanceof
|
686
|
+
object instanceof ArrayProxy &&
|
726
687
|
object.content &&
|
727
688
|
!object._showProxyDetails
|
728
689
|
) {
|
@@ -941,7 +902,7 @@ function addProperties(properties, hash) {
|
|
941
902
|
}
|
942
903
|
|
943
904
|
if (!options.isService) {
|
944
|
-
options.isService = desc.value instanceof
|
905
|
+
options.isService = desc.value instanceof Service;
|
945
906
|
}
|
946
907
|
}
|
947
908
|
if (options.isService) {
|
@@ -1272,7 +1233,7 @@ function getDebugInfo(object) {
|
|
1272
1233
|
let debugInfo = null;
|
1273
1234
|
let objectDebugInfo = object._debugInfo;
|
1274
1235
|
if (objectDebugInfo && typeof objectDebugInfo === 'function') {
|
1275
|
-
if (object instanceof
|
1236
|
+
if (object instanceof ObjectProxy && object.content) {
|
1276
1237
|
object = object.content;
|
1277
1238
|
}
|
1278
1239
|
debugInfo = objectDebugInfo.call(object);
|
@@ -1285,7 +1246,7 @@ function getDebugInfo(object) {
|
|
1285
1246
|
skipProperties.push('isDestroyed', 'isDestroying', 'container');
|
1286
1247
|
// 'currentState' and 'state' are un-observable private properties.
|
1287
1248
|
// The rest are skipped to reduce noise in the inspector.
|
1288
|
-
if (
|
1249
|
+
if (Component && object instanceof Component) {
|
1289
1250
|
skipProperties.push(
|
1290
1251
|
'currentState',
|
1291
1252
|
'state',
|
@@ -1320,7 +1281,7 @@ function calculateCP(object, item, errorsForObject) {
|
|
1320
1281
|
const property = item.name;
|
1321
1282
|
delete errorsForObject[property];
|
1322
1283
|
try {
|
1323
|
-
if (object instanceof
|
1284
|
+
if (object instanceof ArrayProxy && property == parseInt(property)) {
|
1324
1285
|
return object.objectAt(property);
|
1325
1286
|
}
|
1326
1287
|
return item.isGetter || property.includes?.('.')
|
@@ -1,10 +1,9 @@
|
|
1
1
|
/* eslint-disable ember/no-private-routing-service */
|
2
2
|
import DebugPort from './debug-port';
|
3
3
|
import { compareVersion } from 'ember-debug/utils/version';
|
4
|
+
import { VERSION } from 'ember-debug/utils/ember';
|
4
5
|
import classify from 'ember-debug/utils/classify';
|
5
6
|
import dasherize from 'ember-debug/utils/dasherize';
|
6
|
-
|
7
|
-
import Ember from 'ember-debug/utils/ember';
|
8
7
|
import { _backburner, later } from 'ember-debug/utils/ember/runloop';
|
9
8
|
import bound from 'ember-debug/utils/bound-method';
|
10
9
|
|
@@ -202,7 +201,7 @@ function buildSubTree(routeTree, route) {
|
|
202
201
|
// 3.9.0 removed intimate APIs from router
|
203
202
|
// https://github.com/emberjs/ember.js/pull/17843
|
204
203
|
// https://deprecations.emberjs.com/v3.x/#toc_remove-handler-infos
|
205
|
-
if (compareVersion(
|
204
|
+
if (compareVersion(VERSION, '3.9.0') !== -1) {
|
206
205
|
// Ember >= 3.9.0
|
207
206
|
routeHandler = routerLib.getRoute(handler);
|
208
207
|
} else {
|