Skip to content

Commit

Permalink
Add ability to jump to source for functions and classes (#2443)
Browse files Browse the repository at this point in the history
  • Loading branch information
patricklx authored Mar 11, 2024
1 parent d67eed1 commit 2f984a9
Show file tree
Hide file tree
Showing 22 changed files with 242 additions and 21 deletions.
18 changes: 16 additions & 2 deletions app/components/object-inspector.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,25 @@
type="button"
{{on
"click"
(fn this.sendObjectToConsole (get @model (sub @model.length 1)))
(fn this.sendObjectToConsole this.current)
}}
>
{{svg-jar "send-with-text" width="20px" height="10px"}}
</button>
{{#if this.isClass}}
<button
data-test-goto-class-source-btn
class="goto-source"
title="Goto Source"
type="button"
{{on
"click"
(fn this.gotoSource this.current)
}}
>
{{svg-jar "code-source" width="20px" height="10px"}}
</button>
{{/if}}
</div>

{{#if this.trail}}
Expand Down Expand Up @@ -103,4 +117,4 @@
No object selected
</Ui::EmptyMessage>
</div>
{{/if}}
{{/if}}
14 changes: 14 additions & 0 deletions app/components/object-inspector.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,13 @@ export default class ObjectInspector extends Component {
this.searchInputId = 'custom-filter-input';
}

get isClass() {
return this.current.mixins.length > 1;
}

get current() {
return this.args.model[this.args.model.length - 1];
}
get trail() {
let nested = this.args.model.slice(1);
if (nested.length === 0) {
Expand Down Expand Up @@ -55,6 +62,13 @@ export default class ObjectInspector extends Component {
});
}

@action gotoSource(obj) {
let objectId = obj.objectId;
this.port.send('objectInspector:gotoSource', {
objectId,
});
}

@action popStack() {
if (this.isNested) {
this.args.popMixinDetails();
Expand Down
1 change: 1 addition & 0 deletions app/components/object-inspector/properties-all.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
@model={{prop}}
@saveProperty={{this.saveProperty}}
@sendToConsole={{fn this.sendToConsole prop}}
@gotoSource={{fn this.gotoSource prop}}
/>
{{/each}}
</ObjectInspector::SortProperties>
Expand Down
10 changes: 10 additions & 0 deletions app/components/object-inspector/properties-base.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,16 @@ export default class PropertiesBase extends Component {
this.port.send('objectInspector:sendToConsole', data);
}

@action gotoSource({ name }) {
const data = {
objectId: this.args.model.objectId,
};
if (name !== '...') {
data.property = name;
}
this.port.send('objectInspector:gotoSource', data);
}

@action digDeeper({ name }) {
this.port.send('objectInspector:digDeeper', {
objectId: this.args.model.objectId,
Expand Down
1 change: 1 addition & 0 deletions app/components/object-inspector/properties-grouped.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
@digDeeper={{fn this.digDeeper prop}}
@saveProperty={{this.saveProperty}}
@sendToConsole={{fn this.sendToConsole prop}}
@gotoSource={{fn this.gotoSource prop}}
/>
{{else}}
<li class="mixin__property flex relative flex-row items-center truncate">No Properties</li>
Expand Down
13 changes: 12 additions & 1 deletion app/components/object-inspector/property.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -119,12 +119,23 @@
<button
data-test-send-to-console-btn
class="mixin__send-btn flex-shrink-0 send-to-console"
title="Send to console"
title="Send To Console"
type="button"
{{on "click" @sendToConsole}}
>
{{svg-jar "send-with-text" width="20px" height="10px"}}
</button>
{{#if this.isFunction}}
<button
data-test-goto-source-btn
class="mixin__send-btn flex-shrink-0 goto-source"
title="Goto Source"
type="button"
{{on "click" @gotoSource}}
>
{{svg-jar "code-source" width="20px" height="10px"}}
</button>
{{/if}}
</li>

{{#if this.showDependentKeys}}
Expand Down
2 changes: 2 additions & 0 deletions app/components/object-inspector/property.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import parseText from 'ember-inspector/utils/parse-text';
interface ObjectInspectorPropertyArgs {
model: any;
digDeeper: () => unknown;
gotoSource: () => void;
sendToConsole: () => void;
saveProperty: (
property: unknown,
value: unknown,
Expand Down
6 changes: 6 additions & 0 deletions app/controllers/component-tree.js
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,12 @@ class RenderItem {
this.send('view:inspectElement', { id: this.id });
}

@action inspectValue(event) {
event.stopPropagation();

this.send('view:inspectValue', { id: this.id });
}

show() {
let item = this.parentItem;

Expand Down
6 changes: 0 additions & 6 deletions app/routes/component-tree.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ export default class ComponentTreeRoute extends TabRoute {
this.port.on('view:cancelSelection', this, this.cancelSelection);
this.port.on('view:startInspecting', this, this.startInspecting);
this.port.on('view:stopInspecting', this, this.stopInspecting);
this.port.on('view:inspectDOMNode', this, this.inspectDOMNode);
}

deactivate() {
Expand All @@ -41,7 +40,6 @@ export default class ComponentTreeRoute extends TabRoute {
this.port.off('view:cancelSelection', this, this.cancelSelection);
this.port.off('view:startInspecting', this, this.startInspecting);
this.port.off('view:stopInspecting', this, this.stopInspecting);
this.port.off('view:inspectDOMNode', this, this.inspectDOMNode);
}

setRenderTree({ tree }) {
Expand All @@ -59,8 +57,4 @@ export default class ComponentTreeRoute extends TabRoute {
stopInspecting() {
this.controller.isInspecting = false;
}

inspectDOMNode({ name }) {
this.port.adapter.inspectDOMNode(name);
}
}
6 changes: 3 additions & 3 deletions app/services/adapters/web-extension.js
Original file line number Diff line number Diff line change
Expand Up @@ -107,12 +107,12 @@ export default class WebExtension extends BasicAdapter {
}

/**
* Open the devtools "Elements" tab and select a specific DOM node.
* Open the devtools "Elements" or "Sources" tab and select a specific DOM node or function.
*
* @method inspectDOMNode
* @method inspectJSValue
* @param {String} name
*/
inspectDOMNode(name) {
inspectJSValue(name) {
chrome.devtools.inspectedWindow.eval(`
inspect(window[${JSON.stringify(name)}]);
delete window[${JSON.stringify(name)}];
Expand Down
4 changes: 4 additions & 0 deletions app/services/port.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ export default class PortService extends Service.extend(Evented) {
this.trigger(message.type, message, applicationId);
}
});

this.on('view:inspectJSValue', this, ({ name }) =>
this.adapter.inspectJSValue(name)
);
}

selectApplication(applicationId) {
Expand Down
1 change: 1 addition & 0 deletions app/utils/parse-text.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@ export default function parseText(value: string): string {
}
return parsedValue;
}

8 changes: 4 additions & 4 deletions ember_debug/adapters/basic.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,17 +61,17 @@ export default class BasicAdapter extends BaseObject {
}

/**
Inspect a specific DOM node. This usually
Inspect a js value or specific DOM node. This usually
means using the current environment's tools
to inspect the node in the DOM.
For example, in chrome, `inspect(node)`
will open the Elements tab in dev tools
and highlight the DOM node.
@param {Node} node
For functions, it will open the sources tab and goto the definition
@param {Node|Function} node
*/
inspectNode(/* node */) {}
inspectValue(/* value */) {}

_messageReceived(message) {
this._messageCallbacks.forEach((callback) => {
Expand Down
8 changes: 4 additions & 4 deletions ember_debug/adapters/web-extension.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@ export default class extends BasicAdapter {
/**
* Open the devtools "Elements" and select an DOM node.
*
* @param {Node} node The DOM node to select
* @param {Node|Function} value The DOM node to select
*/
inspectNode(node) {
inspectValue(value) {
// NOTE:
//
// Basically, we are just trying to call `inspect(node)` here.
Expand All @@ -58,9 +58,9 @@ export default class extends BasicAdapter {

let name = `__EMBER_INSPECTOR_${(Math.random() * 100000000).toFixed(0)}`;

window[name] = node;
window[name] = value;

this.namespace.port.send('view:inspectDOMNode', { name });
this.namespace.port.send('view:inspectJSValue', { name });
}

_listen() {
Expand Down
28 changes: 28 additions & 0 deletions ember_debug/libs/view-inspection.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,22 @@ function makeStylesheet(id) {
color: rgb(168, 148, 166);
}
#${prefix}-tooltip-${id} .${prefix}-tooltip-detail-instance > .${prefix}-tooltip-token-tag {
cursor: pointer;
}
#${prefix}-tooltip-${id} .${prefix}-tooltip-detail-instance > .${prefix}-tooltip-token-tag:after {
content: "\\1F517"
}
#${prefix}-tooltip-${id} .${prefix}-tooltip-detail-controller > .${prefix}-tooltip-token-tag {
cursor: pointer;
}
#${prefix}-tooltip-${id} .${prefix}-tooltip-detail-controller > .${prefix}-tooltip-token-tag:after {
content: "\\1F517"
}
#${prefix}-tooltip-${id} .${prefix}-tooltip-token-name {
/* https://github.com/ChromeDevTools/devtools-frontend/blob/103326238685ac582d3bf2a02f1627a80e3fce5f/front_end/ui/inspectorSyntaxHighlight.css#L60 */
color: rgb(136, 18, 128);
Expand Down Expand Up @@ -505,6 +521,18 @@ export default class ViewInspection {
this._tokenizeItem(node.instance)
);
}
const detail =
tbody.querySelector(
'.ember-inspector-tooltip-detail-instance > .ember-inspector-tooltip-token-tag'
) ||
tbody.querySelector(
'.ember-inspector-tooltip-detail-controller > .ember-inspector-tooltip-token-tag'
);
if (detail) {
detail.onclick = () => {
this.objectInspector.sendToConsole(node.instance.id);
};
}
}
}

Expand Down
23 changes: 23 additions & 0 deletions ember_debug/object-inspector.js
Original file line number Diff line number Diff line change
Expand Up @@ -434,6 +434,9 @@ export default class extends DebugPort {
sendToConsole(message) {
this.sendToConsole(message.objectId, message.property);
},
gotoSource(message) {
this.gotoSource(message.objectId, message.property);
},
sendControllerToConsole(message) {
const container = this.namespace?.owner;
this.sendValueToConsole(container.lookup(`controller:${message.name}`));
Expand Down Expand Up @@ -519,6 +522,26 @@ export default class extends DebugPort {
});
}

gotoSource(objectId, prop) {
let object = this.sentObjects[objectId];
let value;

if (prop === null || prop === undefined) {
value = this.sentObjects[objectId];
} else {
value = calculateCP(object, { name: prop }, {});
}
// for functions and classes we want to show the source
if (typeof value === 'function') {
this.adapter.inspectValue(value);
}
// use typeOf to distinguish basic objects/classes and Date, Error etc.
// objects like {...} have the constructor set to Object
if (typeOf(value) === 'object' && value.constructor !== Object) {
this.adapter.inspectValue(value.constructor);
}
}

sendToConsole(objectId, prop) {
let object = this.sentObjects[objectId];
let value;
Expand Down
2 changes: 1 addition & 1 deletion ember_debug/view-debug.js
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ export default class extends DebugPort {
* @param {Node} node The DOM node to inspect
*/
inspectNode(node) {
this.adapter.inspectNode(node);
this.adapter.inspectValue(node);
}

sendTree(immediate = false) {
Expand Down
30 changes: 30 additions & 0 deletions lib/ui/addon/styles/_goto-source.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
.goto-source {
background: none;
border: none;
border-bottom: 1px solid transparent;
color: var(--base15);
cursor: pointer;
margin: 0;
outline: none;
padding: 0;

svg {
vertical-align: middle;
}

.send-chevron {
fill: var(--focus);
}

.send-text {
fill: var(--base12);
}
}

.goto-source:hover {
border-bottom-color: var(--focus);
}

.goto-source:active {
transform: translateY(1px);
}
1 change: 1 addition & 0 deletions lib/ui/addon/styles/addon.scss
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
@import 'nav';
@import 'pill';
@import 'send-to-console';
@import 'goto-source';
@import 'object-inspector-toggle';
@import 'split';
@import 'toolbar/index';
Expand Down
4 changes: 4 additions & 0 deletions lib/ui/addon/styles/toolbar/_index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@
margin-left: 5px;
margin-right: 5px;
}
.toolbar .goto-source {
margin-left: 5px;
margin-right: 5px;
}

@import 'checkbox';
@import 'divider';
Expand Down
9 changes: 9 additions & 0 deletions public/assets/svg/code-source.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 2f984a9

Please sign in to comment.