Skip to content

Commit fa9e503

Browse files
Remove pushObjects from RenderTree (#2620)
1 parent e0daadd commit fa9e503

File tree

9 files changed

+180
-132
lines changed

9 files changed

+180
-132
lines changed

app/computed/debounce.js app/computed/debounce.ts

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
import { debounce } from '@ember/runloop';
22
import { computed } from '@ember/object';
3+
import type { AnyFn } from 'ember/-private/type-utils';
34

45
// Use this if you want a property to debounce
56
// another property with a certain delay.
67
// This means that every time this prop changes,
78
// the other prop will change to the same val after [delay]
8-
export default function (prop, delay, callback) {
9-
let value;
9+
export default function (prop: string, delay: number, callback?: AnyFn) {
10+
let value: unknown;
1011

11-
let updateVal = function () {
12+
let updateVal = function (this: any) {
1213
this.set(prop, value);
1314
if (callback) {
1415
callback.call(this);
Original file line numberDiff line numberDiff line change
@@ -1,65 +1,68 @@
11
import { action, computed } from '@ember/object';
22
import { tracked } from '@glimmer/tracking';
3-
import { isEmpty } from '@ember/utils';
43
import Controller from '@ember/controller';
54
import { inject as service } from '@ember/service';
6-
import escapeRegExp from 'ember-inspector/utils/escape-reg-exp';
7-
import debounceComputed from 'ember-inspector/computed/debounce';
8-
import { and, equal } from '@ember/object/computed';
5+
6+
import escapeRegExp from '../utils/escape-reg-exp';
7+
import debounceComputed from '../computed/debounce';
8+
import type WebExtension from '../services/adapters/web-extension';
9+
import type PortService from '../services/port';
10+
import type StorageService from '../services/storage';
11+
import type { RenderTreeModel } from '../routes/render-tree';
12+
import { isNullish } from '../utils/nullish';
913

1014
export default class RenderTreeController extends Controller {
11-
@service adapter;
12-
@service port;
15+
@service declare adapter: WebExtension;
16+
@service declare port: PortService;
1317
/**
1418
* Storage is needed for remembering if the user closed the warning
15-
*
16-
* @property storage
17-
* @type {Service}
1819
*/
19-
@service storage;
20+
@service declare storage: StorageService;
21+
22+
declare model: RenderTreeModel;
2023

21-
initialEmpty = false;
24+
@tracked initialEmpty = false;
2225
@tracked shouldHighlightRender = false;
2326
@tracked search = '';
2427

25-
@equal('model.profiles.length', 0)
26-
modelEmpty;
28+
get escapedSearch() {
29+
return escapeRegExp(this.search?.toLowerCase());
30+
}
2731

28-
@and('initialEmpty', 'modelEmpty')
29-
showEmpty;
32+
/**
33+
* Indicate the table's header's height in pixels.
34+
*
35+
* @property headerHeight
36+
* @type {Number}
37+
*/
38+
get headerHeight() {
39+
return this.isWarningClosed ? 31 : 56;
40+
}
3041

3142
/**
3243
* Checks if the user previously closed the warning by referencing localStorage
33-
*
34-
* @property isWarningClosed
35-
* @type {Boolean}
3644
*/
3745
get isWarningClosed() {
3846
return !!this.storage.getItem('is-render-tree-warning-closed');
3947
}
4048

4149
set isWarningClosed(value) {
50+
// @ts-expect-error Ignore this boolean/string mismatch for now.
4251
this.storage.setItem('is-render-tree-warning-closed', value);
4352
}
4453

45-
/**
46-
* Indicate the table's header's height in pixels.
47-
*
48-
* @property headerHeight
49-
* @type {Number}
50-
*/
51-
get headerHeight() {
52-
return this.isWarningClosed ? 31 : 56;
54+
get modelEmpty() {
55+
return this.model.profiles.length === 0;
56+
}
57+
58+
get showEmpty() {
59+
return this.initialEmpty && this.modelEmpty;
5360
}
5461

5562
// bound to the input field, updates the `search` property
5663
// 300ms after changing
5764
@debounceComputed('search', 300)
58-
searchValue;
59-
60-
get escapedSearch() {
61-
return escapeRegExp(this.search?.toLowerCase());
62-
}
65+
declare searchValue: string;
6366

6467
@computed('model.isHighlightSupported')
6568
get isHighlightEnabled() {
@@ -68,14 +71,16 @@ export default class RenderTreeController extends Controller {
6871

6972
@computed('escapedSearch', 'model.profiles.@each.name', 'search')
7073
get filtered() {
71-
if (isEmpty(this.escapedSearch)) {
74+
if (isNullish(this.escapedSearch)) {
7275
return this.model.profiles;
7376
}
7477

75-
return this.model.profiles.filter((item) => {
76-
const regExp = new RegExp(this.escapedSearch);
77-
return recursiveMatch(item, regExp);
78-
});
78+
return this.model.profiles.filter(
79+
(item: RenderTreeModel['profiles'][number]) => {
80+
const regExp = new RegExp(this.escapedSearch as string);
81+
return recursiveMatch(item, regExp);
82+
},
83+
);
7984
}
8085

8186
@action
@@ -85,7 +90,7 @@ export default class RenderTreeController extends Controller {
8590

8691
@action
8792
closeWarning() {
88-
this.set('isWarningClosed', true);
93+
this.isWarningClosed = true;
8994
}
9095

9196
@action
@@ -98,18 +103,19 @@ export default class RenderTreeController extends Controller {
98103
}
99104
}
100105

101-
function recursiveMatch(item, regExp) {
102-
let children, child;
103-
let name = item.name;
104-
if (name.toLowerCase().match(regExp)) {
106+
function recursiveMatch(
107+
item: RenderTreeModel['profiles'][number],
108+
regExp: string | RegExp,
109+
) {
110+
if (item.name.toLowerCase().match(regExp)) {
105111
return true;
106112
}
107-
children = item.children;
108-
for (let i = 0; i < children.length; i++) {
109-
child = children[i];
113+
114+
for (const child of item.children) {
110115
if (recursiveMatch(child, regExp)) {
111116
return true;
112117
}
113118
}
119+
114120
return false;
115121
}

app/routes/promise-tree.ts

+9-4
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1+
import type Controller from '@ember/controller';
12
import { set } from '@ember/object';
23
import { inject as service } from '@ember/service';
34
import { Promise } from 'rsvp';
4-
// @ts-expect-error TODO: not yet typed
5-
import TabRoute from 'ember-inspector/routes/tab';
5+
import type Transition from '@ember/routing/transition';
66

77
import PromiseAssembler from '../libs/promise-assembler';
88
import type PortService from '../services/port';
9+
import TabRoute from '../routes/tab';
910

1011
export default class PromiseTreeRoute extends TabRoute {
1112
@service declare port: PortService;
@@ -31,8 +32,12 @@ export default class PromiseTreeRoute extends TabRoute {
3132
});
3233
}
3334

34-
setupController() {
35-
super.setupController(...arguments);
35+
setupController(
36+
controller: Controller,
37+
model: unknown,
38+
transition: Transition,
39+
) {
40+
super.setupController(controller, model, transition);
3641

3742
this.port.on(
3843
'promise:instrumentWithStack',

app/routes/render-tree.js

-66
This file was deleted.

app/routes/render-tree.ts

+92
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
import EmberObject, { get, set } from '@ember/object';
2+
import { inject as service } from '@ember/service';
3+
import { Promise } from 'rsvp';
4+
import type Transition from '@ember/routing/transition';
5+
6+
import { TrackedArray } from 'tracked-built-ins';
7+
8+
import type PortService from '../services/port';
9+
import type RenderTreeController from '../controllers/render-tree';
10+
import TabRoute from './tab';
11+
12+
export interface Profile {
13+
children: Array<Profile>;
14+
name: string;
15+
}
16+
17+
export interface RenderTreeModel {
18+
isHighlightSupported: boolean;
19+
profiles: Array<Profile>;
20+
}
21+
22+
export default class RenderTreeRoute extends TabRoute {
23+
@service declare port: PortService;
24+
25+
declare controller: RenderTreeController;
26+
27+
model() {
28+
return new Promise((resolve) => {
29+
this.port.one(
30+
'render:profilesAdded',
31+
function ({ profiles, isHighlightSupported }) {
32+
resolve(
33+
EmberObject.create({
34+
profiles: new TrackedArray(profiles),
35+
isHighlightSupported,
36+
}),
37+
);
38+
},
39+
);
40+
this.port.send('render:watchProfiles');
41+
});
42+
}
43+
44+
setupController(
45+
controller: RenderTreeController,
46+
model: RenderTreeModel,
47+
transition: Transition,
48+
) {
49+
super.setupController(controller, model, transition);
50+
51+
if (model.profiles.length === 0) {
52+
controller.initialEmpty = true;
53+
}
54+
55+
this.port.on('render:profilesUpdated', this, this.profilesUpdated);
56+
this.port.on('render:profilesAdded', this, this.profilesAdded);
57+
}
58+
59+
deactivate(transition: Transition) {
60+
super.deactivate(transition);
61+
62+
this.port.off('render:profilesUpdated', this, this.profilesUpdated);
63+
this.port.off('render:profilesAdded', this, this.profilesAdded);
64+
this.port.send('render:releaseProfiles');
65+
}
66+
67+
profilesUpdated(message: RenderTreeModel) {
68+
set(this.controller.model, 'profiles', message.profiles);
69+
}
70+
71+
profilesAdded(message: RenderTreeModel) {
72+
const currentProfiles = get(this.controller.model, 'profiles');
73+
const profiles = message.profiles;
74+
if (
75+
message.isHighlightSupported !== undefined &&
76+
message.isHighlightSupported !==
77+
get(this.controller.model, 'isHighlightSupported')
78+
) {
79+
set(
80+
this.controller.model,
81+
'isHighlightSupported',
82+
message.isHighlightSupported,
83+
);
84+
}
85+
86+
// @ts-expect-error TODO: fix this type error
87+
currentProfiles.push(profiles);
88+
if (currentProfiles.length > 100) {
89+
set(this.controller.model, 'profiles', currentProfiles.slice(0, 100));
90+
}
91+
}
92+
}

app/routes/tab.js

-14
This file was deleted.

0 commit comments

Comments
 (0)