Skip to content

Commit 7b3b9c7

Browse files
Remove pushObjects from RenderTree
1 parent f3b2de0 commit 7b3b9c7

File tree

8 files changed

+172
-127
lines changed

8 files changed

+172
-127
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);

app/controllers/render-tree.js app/controllers/render-tree.ts

+51-43
Original file line numberDiff line numberDiff line change
@@ -3,63 +3,68 @@ import { tracked } from '@glimmer/tracking';
33
import { isEmpty } from '@ember/utils';
44
import Controller from '@ember/controller';
55
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';
6+
7+
import escapeRegExp from '../utils/escape-reg-exp';
8+
// @ts-expect-error TODO: not yet typed
9+
import debounceComputed from '../computed/debounce';
10+
import type WebExtension from '../services/adapters/web-extension';
11+
import type PortService from '../services/port';
12+
import type StorageService from '../services/storage';
13+
import type { RenderTreeModel } from '../routes/render-tree';
14+
import { isNullish } from '../utils/nullish';
915

1016
export default class RenderTreeController extends Controller {
11-
@service adapter;
12-
@service port;
17+
@service declare adapter: WebExtension;
18+
@service declare port: PortService;
1319
/**
1420
* Storage is needed for remembering if the user closed the warning
15-
*
16-
* @property storage
17-
* @type {Service}
1821
*/
19-
@service storage;
22+
@service declare storage: StorageService;
23+
24+
declare model: RenderTreeModel;
2025

21-
initialEmpty = false;
26+
@tracked initialEmpty = false;
2227
@tracked shouldHighlightRender = false;
2328
@tracked search = '';
2429

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

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

3144
/**
3245
* Checks if the user previously closed the warning by referencing localStorage
33-
*
34-
* @property isWarningClosed
35-
* @type {Boolean}
3646
*/
3747
get isWarningClosed() {
3848
return !!this.storage.getItem('is-render-tree-warning-closed');
3949
}
4050

4151
set isWarningClosed(value) {
52+
// @ts-expect-error Ignore this boolean/string mismatch for now.
4253
this.storage.setItem('is-render-tree-warning-closed', value);
4354
}
4455

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;
56+
get modelEmpty() {
57+
return this.model.profiles.length === 0;
58+
}
59+
60+
get showEmpty() {
61+
return this.initialEmpty && this.modelEmpty;
5362
}
5463

5564
// bound to the input field, updates the `search` property
5665
// 300ms after changing
5766
@debounceComputed('search', 300)
58-
searchValue;
59-
60-
get escapedSearch() {
61-
return escapeRegExp(this.search?.toLowerCase());
62-
}
67+
searchValue: any;
6368

6469
@computed('model.isHighlightSupported')
6570
get isHighlightEnabled() {
@@ -68,14 +73,16 @@ export default class RenderTreeController extends Controller {
6873

6974
@computed('escapedSearch', 'model.profiles.@each.name', 'search')
7075
get filtered() {
71-
if (isEmpty(this.escapedSearch)) {
76+
if (isNullish(this.escapedSearch)) {
7277
return this.model.profiles;
7378
}
7479

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

8188
@action
@@ -85,7 +92,7 @@ export default class RenderTreeController extends Controller {
8592

8693
@action
8794
closeWarning() {
88-
this.set('isWarningClosed', true);
95+
this.isWarningClosed = true;
8996
}
9097

9198
@action
@@ -98,18 +105,19 @@ export default class RenderTreeController extends Controller {
98105
}
99106
}
100107

101-
function recursiveMatch(item, regExp) {
102-
let children, child;
103-
let name = item.name;
104-
if (name.toLowerCase().match(regExp)) {
108+
function recursiveMatch(
109+
item: RenderTreeModel['profiles'][number],
110+
regExp: string | RegExp,
111+
) {
112+
if (item.name.toLowerCase().match(regExp)) {
105113
return true;
106114
}
107-
children = item.children;
108-
for (let i = 0; i < children.length; i++) {
109-
child = children[i];
115+
116+
for (const child of item.children) {
110117
if (recursiveMatch(child, regExp)) {
111118
return true;
112119
}
113120
}
121+
114122
return false;
115123
}

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.

app/routes/tab.ts

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import type Controller from '@ember/controller';
2+
import Route from '@ember/routing/route';
3+
import { scheduleOnce } from '@ember/runloop';
4+
import type Transition from '@ember/routing/transition';
5+
6+
export default class TabRoute extends Route {
7+
setupController(
8+
controller: Controller,
9+
model: unknown,
10+
transition: Transition,
11+
) {
12+
super.setupController(controller, model, transition);
13+
14+
function setToolbarContainer() {
15+
// @ts-expect-error The controller could be different types.
16+
controller.set('toolbarContainer', document.querySelector('#toolbar'));
17+
}
18+
19+
scheduleOnce('afterRender', this, setToolbarContainer);
20+
}
21+
}

app/services/port.ts

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ export interface Message {
1414
frameId?: any;
1515
from: string;
1616
name?: string;
17+
shouldHighlightRender?: boolean;
1718
tabId?: number;
1819
type: string;
1920
unloading?: boolean;

app/utils/escape-reg-exp.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
/* eslint-disable no-useless-escape */
2-
export default function (str: string) {
2+
export default function (str?: string) {
33
if (typeof str === 'string') {
44
return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&');
55
}
6+
7+
return undefined;
68
}

0 commit comments

Comments
 (0)