Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove pushObjects from RenderTree #2620

Merged
merged 2 commits into from
Jan 23, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions app/computed/debounce.js → app/computed/debounce.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import { debounce } from '@ember/runloop';
import { computed } from '@ember/object';
import type { AnyFn } from 'ember/-private/type-utils';

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

let updateVal = function () {
let updateVal = function (this: any) {
this.set(prop, value);
if (callback) {
callback.call(this);
Expand Down
94 changes: 50 additions & 44 deletions app/controllers/render-tree.js → app/controllers/render-tree.ts
Original file line number Diff line number Diff line change
@@ -1,65 +1,68 @@
import { action, computed } from '@ember/object';
import { tracked } from '@glimmer/tracking';
import { isEmpty } from '@ember/utils';
import Controller from '@ember/controller';
import { inject as service } from '@ember/service';
import escapeRegExp from 'ember-inspector/utils/escape-reg-exp';
import debounceComputed from 'ember-inspector/computed/debounce';
import { and, equal } from '@ember/object/computed';

import escapeRegExp from '../utils/escape-reg-exp';
import debounceComputed from '../computed/debounce';
import type WebExtension from '../services/adapters/web-extension';
import type PortService from '../services/port';
import type StorageService from '../services/storage';
import type { RenderTreeModel } from '../routes/render-tree';
import { isNullish } from '../utils/nullish';

export default class RenderTreeController extends Controller {
@service adapter;
@service port;
@service declare adapter: WebExtension;
@service declare port: PortService;
/**
* Storage is needed for remembering if the user closed the warning
*
* @property storage
* @type {Service}
*/
@service storage;
@service declare storage: StorageService;

declare model: RenderTreeModel;

initialEmpty = false;
@tracked initialEmpty = false;
@tracked shouldHighlightRender = false;
@tracked search = '';

@equal('model.profiles.length', 0)
modelEmpty;
get escapedSearch() {
return escapeRegExp(this.search?.toLowerCase());
}

@and('initialEmpty', 'modelEmpty')
showEmpty;
/**
* Indicate the table's header's height in pixels.
*
* @property headerHeight
* @type {Number}
*/
get headerHeight() {
return this.isWarningClosed ? 31 : 56;
}

/**
* Checks if the user previously closed the warning by referencing localStorage
*
* @property isWarningClosed
* @type {Boolean}
*/
get isWarningClosed() {
return !!this.storage.getItem('is-render-tree-warning-closed');
}

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

/**
* Indicate the table's header's height in pixels.
*
* @property headerHeight
* @type {Number}
*/
get headerHeight() {
return this.isWarningClosed ? 31 : 56;
get modelEmpty() {
return this.model.profiles.length === 0;
}

get showEmpty() {
return this.initialEmpty && this.modelEmpty;
}

// bound to the input field, updates the `search` property
// 300ms after changing
@debounceComputed('search', 300)
searchValue;

get escapedSearch() {
return escapeRegExp(this.search?.toLowerCase());
}
declare searchValue: string;

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

@computed('escapedSearch', 'model.profiles.@each.name', 'search')
get filtered() {
if (isEmpty(this.escapedSearch)) {
if (isNullish(this.escapedSearch)) {
return this.model.profiles;
}

return this.model.profiles.filter((item) => {
const regExp = new RegExp(this.escapedSearch);
return recursiveMatch(item, regExp);
});
return this.model.profiles.filter(
(item: RenderTreeModel['profiles'][number]) => {
const regExp = new RegExp(this.escapedSearch as string);
return recursiveMatch(item, regExp);
},
);
}

@action
Expand All @@ -85,7 +90,7 @@ export default class RenderTreeController extends Controller {

@action
closeWarning() {
this.set('isWarningClosed', true);
this.isWarningClosed = true;
}

@action
Expand All @@ -98,18 +103,19 @@ export default class RenderTreeController extends Controller {
}
}

function recursiveMatch(item, regExp) {
let children, child;
let name = item.name;
if (name.toLowerCase().match(regExp)) {
function recursiveMatch(
item: RenderTreeModel['profiles'][number],
regExp: string | RegExp,
) {
if (item.name.toLowerCase().match(regExp)) {
return true;
}
children = item.children;
for (let i = 0; i < children.length; i++) {
child = children[i];

for (const child of item.children) {
if (recursiveMatch(child, regExp)) {
return true;
}
}

return false;
}
13 changes: 9 additions & 4 deletions app/routes/promise-tree.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import type Controller from '@ember/controller';
import { set } from '@ember/object';
import { inject as service } from '@ember/service';
import { Promise } from 'rsvp';
// @ts-expect-error TODO: not yet typed
import TabRoute from 'ember-inspector/routes/tab';
import type Transition from '@ember/routing/transition';

import PromiseAssembler from '../libs/promise-assembler';
import type PortService from '../services/port';
import TabRoute from '../routes/tab';

export default class PromiseTreeRoute extends TabRoute {
@service declare port: PortService;
Expand All @@ -31,8 +32,12 @@ export default class PromiseTreeRoute extends TabRoute {
});
}

setupController() {
super.setupController(...arguments);
setupController(
controller: Controller,
model: unknown,
transition: Transition,
) {
super.setupController(controller, model, transition);

this.port.on(
'promise:instrumentWithStack',
Expand Down
66 changes: 0 additions & 66 deletions app/routes/render-tree.js

This file was deleted.

92 changes: 92 additions & 0 deletions app/routes/render-tree.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import EmberObject, { get, set } from '@ember/object';
import { inject as service } from '@ember/service';
import { Promise } from 'rsvp';
import type Transition from '@ember/routing/transition';

import { TrackedArray } from 'tracked-built-ins';

import type PortService from '../services/port';
import type RenderTreeController from '../controllers/render-tree';
import TabRoute from './tab';

export interface Profile {
children: Array<Profile>;
name: string;
}

export interface RenderTreeModel {
isHighlightSupported: boolean;
profiles: Array<Profile>;
}

export default class RenderTreeRoute extends TabRoute {
@service declare port: PortService;

declare controller: RenderTreeController;

model() {
return new Promise((resolve) => {
this.port.one(
'render:profilesAdded',
function ({ profiles, isHighlightSupported }) {
resolve(
EmberObject.create({
profiles: new TrackedArray(profiles),
isHighlightSupported,
}),
);
},
);
this.port.send('render:watchProfiles');
});
}

setupController(
controller: RenderTreeController,
model: RenderTreeModel,
transition: Transition,
) {
super.setupController(controller, model, transition);

if (model.profiles.length === 0) {
controller.initialEmpty = true;
}

this.port.on('render:profilesUpdated', this, this.profilesUpdated);
this.port.on('render:profilesAdded', this, this.profilesAdded);
}

deactivate(transition: Transition) {
super.deactivate(transition);

this.port.off('render:profilesUpdated', this, this.profilesUpdated);
this.port.off('render:profilesAdded', this, this.profilesAdded);
this.port.send('render:releaseProfiles');
}

profilesUpdated(message: RenderTreeModel) {
set(this.controller.model, 'profiles', message.profiles);
}

profilesAdded(message: RenderTreeModel) {
const currentProfiles = get(this.controller.model, 'profiles');
const profiles = message.profiles;
if (
message.isHighlightSupported !== undefined &&
message.isHighlightSupported !==
get(this.controller.model, 'isHighlightSupported')
) {
set(
this.controller.model,
'isHighlightSupported',
message.isHighlightSupported,
);
}

// @ts-expect-error TODO: fix this type error
currentProfiles.push(profiles);
if (currentProfiles.length > 100) {
set(this.controller.model, 'profiles', currentProfiles.slice(0, 100));
}
}
}
14 changes: 0 additions & 14 deletions app/routes/tab.js

This file was deleted.

Loading
Loading