Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
8d3a885
fix(b-components-panel): improve rendering of tree
shining-mind Nov 16, 2023
2e7ea9b
chore: update v4fire/client
shining-mind Nov 16, 2023
bcf2f57
chore(p-components): use throttle to load selected component data
shining-mind Nov 16, 2023
bd0f750
fix(eval-component-meta): check componentId of the node
shining-mind Nov 16, 2023
e28ec62
feat(p-root): set --header-height css variable
shining-mind Nov 16, 2023
2114260
chore(p-components): improve height of children with `overflow: auto`
shining-mind Nov 16, 2023
b2dd2e5
feat(b-tree): create pretty theme
shining-mind Nov 16, 2023
b54682d
chore(devtools-backend/serialize): pass value to isRestrictedKey
shining-mind Nov 16, 2023
cf07e72
chore(eval-component-meta): improve restricted key
shining-mind Nov 16, 2023
335b46f
chore(b-components-panel): add padding for level 0 nodes
shining-mind Nov 16, 2023
233bb79
chore(b-components-tree): highlight active item
shining-mind Nov 16, 2023
35d0716
chore: set eslint ignores correctly
shining-mind Nov 17, 2023
d88c7c6
fix(p-root): set header height variable for root node
shining-mind Nov 27, 2023
62ce126
feat(devtools-backend): create search module
shining-mind Nov 27, 2023
4785d84
feat(devtools-backend): create ui module
shining-mind Nov 27, 2023
c9f4a21
feat(devtools-backend): export ui and search modules
shining-mind Nov 27, 2023
9af9f5b
feat(b-components-tree): add mouseenter and mouseleave props to item
shining-mind Nov 27, 2023
599d2f6
fix(eval-components-tree): log missing parent in map
shining-mind Nov 27, 2023
33d7a05
chore(eval-component-meta): use findComponentNode
shining-mind Nov 27, 2023
ebad7ec
chore(p-devtools): render p-root on idle
shining-mind Nov 27, 2023
d2340e8
chore(devtools-extension): highlight component's node
shining-mind Nov 27, 2023
02c6dcd
feat(b-header): add reload button
shining-mind Dec 8, 2023
384c77a
fix(b-components-tree): re-export from super
shining-mind Dec 8, 2023
72558c7
chore(b-components-panel): add componentId to ComponentData type
shining-mind Dec 8, 2023
f42ebf9
feat(b-components-panel): use icons for actions
shining-mind Dec 8, 2023
7f09c6b
feat(b-components-panel): implement onInspect method
shining-mind Dec 8, 2023
598a7b7
chore: update components lock
shining-mind Dec 8, 2023
03476bb
chore(p-devtools): do not inject backend for window without tabId
shining-mind Dec 8, 2023
de9b30e
chore: update @v4fire/client
shining-mind Dec 8, 2023
9c23e91
chore(devtools-backend): make component-highlight a singleton
shining-mind Dec 11, 2023
bc57902
chore(devtools-backend): disable pointer events for component highlight
shining-mind Dec 11, 2023
505d9f3
feat(devtools-backend): create ComponentLocate class
shining-mind Dec 11, 2023
91e7018
chore(devtools-core): add crosshair icon
shining-mind Dec 11, 2023
665e713
feat(devtools-core): create b-components-actions
shining-mind Dec 11, 2023
8d56c3d
chore(b-header): integrate b-components-actions
shining-mind Dec 11, 2023
f7b29b2
chore(b-components-actions): add override for devtools-extension
shining-mind Dec 11, 2023
61acbe2
chore: update components lock
shining-mind Dec 11, 2023
9bfc09d
fix(b-components-panel): hint position
shining-mind Dec 11, 2023
8438268
chore: add hints for components actions
shining-mind Dec 12, 2023
cb3c59a
refactor(BrowserTabManager): create helpers and handle proxy connections
shining-mind Dec 12, 2023
fd07195
fix(CouldNotFindV4FireOnThePageError): fix name
shining-mind Dec 12, 2023
5e94b50
feat(p-devtools): listen for messages from proxy
shining-mind Dec 12, 2023
cef55e1
chore(component-locate): send message to devtools on component select
shining-mind Dec 12, 2023
5835262
refactor(b-components-tree): add scrollToItem method
shining-mind Dec 12, 2023
5b9448b
feat(scripts/proxy): connect to extension's service worker
shining-mind Dec 12, 2023
2fa6d6f
feat: handle `bridge.select-component` event
shining-mind Dec 12, 2023
91bf06b
docs: add test-cases for components page
shining-mind Dec 12, 2023
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
5 changes: 0 additions & 5 deletions .eslintignore

This file was deleted.

19 changes: 19 additions & 0 deletions docs/ru/tests/01-components.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Тесты страницы "Components"

## 1. Выбор компонента на странице

### Кейс 1.1

1. Открыть приложение V4Fire
2. Открыть devtools
3. Открыть вкладку `v4fire` в devtools
4. Кликнуть на иконку прицела и выбрать компонент на странице -> Данные компонента отобразились в панели

### Кейс 1.2

1. Открыть приложение V4Fire
2. Открыть devtools
3. Открыть вкладку `v4fire` в devtools
4. Сменить вкладку в браузере
5. Вернуться на вкладку с приложением V4Fire
6. Кликнуть на иконку прицела и выбрать компонент на странице -> Данные компонента отобразились в панели
17 changes: 17 additions & 0 deletions eslint.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,24 @@ const copyrightTemplate = [
' '
];

const ignore = [
'**/src/**/@(i-|b-|p-|g-|v-)*/index.js',
'**/src/**/test/**/*.js',

'**/assets/**',
'**/src/assets/**',

'**/tmp/**',
'**/src/entries/tmp/**',

'**/docs/**',
'**/dist/**',
'**/node_modules/**'
];

base.forEach((item) => {
item.ignores = ignore;

if (item.plugins) {
item.plugins['header'] = headerPlugin;
}
Expand Down
2 changes: 2 additions & 0 deletions packages/devtools-backend/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,5 @@
*/

export * from './serialize';
export * from './search';
export * from './ui';
5 changes: 5 additions & 0 deletions packages/devtools-backend/src/search/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Search

These modules provide search API:

- find component node
28 changes: 28 additions & 0 deletions packages/devtools-backend/src/search/find-component-node.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*!
* V4Fire DevTools
* https://github.com/V4Fire/DevTools
*
* Released under the MIT license
* https://github.com/V4Fire/DevTools/blob/main/LICENSE
*/

/**
* Find component DOM node
*
* @param id - component id
* @param name - component name
*/
export default function findComponentNode<T extends Element>(id: string, name?: string): T | null {
let node = Array.prototype.find.call(
document.querySelectorAll(`.i-block-helper.${id}`),
(node) => node.component?.componentId === id
);

if (node == null && name != null) {
// Maybe it's a functional component
const nodes = document.querySelectorAll(`.i-block-helper.${name}`);
node = Array.prototype.find.call(nodes, (node) => node.component?.componentId === id);
}

return node;
}
8 changes: 8 additions & 0 deletions packages/devtools-backend/src/search/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/*!
* V4Fire DevTools
* https://github.com/V4Fire/DevTools
*
* Released under the MIT license
* https://github.com/V4Fire/DevTools/blob/main/LICENSE
*/
export { default as findComponentNode } from './find-component-node';
4 changes: 2 additions & 2 deletions packages/devtools-backend/src/serialize/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export function getType<T = unknown>(value: T): string {
*/
export function serialize<T = unknown>(
value: T,
isRestrictedKey?: (key: string) => boolean
isRestrictedKey?: (key: string, value?: unknown) => boolean
): string {
let refCounter = 1;

Expand All @@ -49,7 +49,7 @@ export function serialize<T = unknown>(
return JSON.stringify(value, expandedStringify);

function expandedStringify(this: any, key: string, value: unknown): unknown {
if (isRestrictedKey?.(key)) {
if (isRestrictedKey?.(key, value)) {
return '[Restricted]';
}

Expand Down
5 changes: 5 additions & 0 deletions packages/devtools-backend/src/ui/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# UI

These modules provide API to modify the UI of inspected window:

- componentHighlight - displays an overlay over the component
118 changes: 118 additions & 0 deletions packages/devtools-backend/src/ui/component-highlight.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
/*!
* V4Fire DevTools
* https://github.com/V4Fire/DevTools
*
* Released under the MIT license
* https://github.com/V4Fire/DevTools/blob/main/LICENSE
*/

import findComponentNode from '../search/find-component-node';

interface HideOptions {
animate?: boolean;
delay?: number;
}

const
highlightNodeId = 'v4fire-devtools-highlight',
highlightAnimationDuration = 300;

class ComponentHighlight {
/**
* Highlight animation timeout
*/
#animationTimeout: any;

/**
* Show highlight for the component
*
* @param componentId
* @param componentName
*/
show(componentId: string, componentName: string): void {
const node = findComponentNode<HTMLElement>(componentId, componentName);

if (node == null) {
return;
}

clearTimeout(this.#animationTimeout);

const highlightNode = getOrCreateHighlightNode();

const {width, height, top, left} = node.getBoundingClientRect();
highlightNode.style.width = `${width}px`;
highlightNode.style.height = `${height}px`;
highlightNode.style.top = `${(globalThis.scrollY + top)}px`;
highlightNode.style.left = `${left}px`;
highlightNode.style.opacity = '1';
highlightNode.style.display = 'block';
}

/**
* Hide component's highlight
* @param animateOrOptions
*/
hide(animateOrOptions?: boolean | HideOptions): void {
let animate = false;
let delay: number | null = null;

if (typeof animateOrOptions === 'boolean') {
animate = animateOrOptions;

} else if (typeof animateOrOptions === 'object') {
({animate = false, delay = null} = animateOrOptions);
}

const node = document.getElementById(highlightNodeId);

if (node == null) {
return;
}

if (animate) {
clearTimeout(this.#animationTimeout);

const end = () => {
this.#animationTimeout = setTimeout(() => {
node.style.display = 'none';
}, highlightAnimationDuration);
};

const start = () => {
node.style.opacity = '0';

end();
};

if (delay != null) {
this.#animationTimeout = setTimeout(start, delay);
} else {
start();
}

} else {
node.style.display = 'none';
}
}
}

export const componentHighlight = new ComponentHighlight();

function getOrCreateHighlightNode(): HTMLElement {
let highlightNode = document.getElementById(highlightNodeId);

if (highlightNode == null) {
highlightNode = document.createElement('div');
highlightNode.id = highlightNodeId;
highlightNode.style.position = 'absolute';
highlightNode.style.display = 'none';
highlightNode.style.backgroundColor = 'rgba(250, 0, 250, 0.3)';
highlightNode.style.zIndex = '9999';
highlightNode.style.transition = `opacity ${highlightAnimationDuration}ms ease`;
highlightNode.style.pointerEvents = 'none';
document.body.appendChild(highlightNode);
}

return highlightNode;
}
99 changes: 99 additions & 0 deletions packages/devtools-backend/src/ui/component-locate.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
/*!
* V4Fire DevTools
* https://github.com/V4Fire/DevTools
*
* Released under the MIT license
* https://github.com/V4Fire/DevTools/blob/main/LICENSE
*/

import { componentHighlight } from './component-highlight';

interface ComponentInterface {
componentId: string;
componentName: string;
}

class ComponentLocate {
#mouseoverListener: ((e: MouseEvent) => void) | null = null;

#clickListener: ((e: MouseEvent) => void) | null = null;

enable() {
this.disable();

let component: ComponentInterface | null = null;

this.#mouseoverListener = (e: MouseEvent) => {
component = e.target instanceof Element ? findComponent(e.target) : null;

if (component != null) {
const {componentId, componentName} = component;
componentHighlight.show(componentId, componentName);

} else {
componentHighlight.hide();
}
};

this.#clickListener = (e) => {
e.preventDefault();
e.stopPropagation();

this.disable();

if (component != null) {
componentHighlight.hide({animate: true});

const {componentId, componentName} = component;

// TODO: create bridge
globalThis.postMessage({
source: 'v4fire-devtools-bridge',
payload: {
event: 'select-component',
payload: {componentId, componentName}
}
}, '*');
}
};

document.addEventListener('mouseover', this.#mouseoverListener);
document.addEventListener('click', this.#clickListener, {capture: true});
}

disable() {
if (this.#mouseoverListener != null) {
document.removeEventListener('mouseover', this.#mouseoverListener);
this.#mouseoverListener = null;
}

if (this.#clickListener != null) {
document.removeEventListener('click', this.#clickListener, {capture: true});
this.#clickListener = null;
}
}
}

export const componentLocate = new ComponentLocate();

function findComponent(target: Element | null): ComponentInterface | null {
let component: ComponentInterface | null = null;

while (component == null && target != null) {
const node: Element & {component?: ComponentInterface} | null = target.closest('.i-block-helper');

if (node == null) {
break;
}

if (node.component != null) {
({component} = node);

} else {
// If `component` property is missing - search higher in hierarchy
target = <Element>node.parentNode;
}
}

return component;
}
9 changes: 9 additions & 0 deletions packages/devtools-backend/src/ui/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/*!
* V4Fire DevTools
* https://github.com/V4Fire/DevTools
*
* Released under the MIT license
* https://github.com/V4Fire/DevTools/blob/main/LICENSE
*/
export { componentHighlight } from './component-highlight';
export { componentLocate } from './component-locate';
5 changes: 5 additions & 0 deletions packages/devtools-core/src/assets/svg/circle-dashed.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions packages/devtools-core/src/assets/svg/circle.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions packages/devtools-core/src/assets/svg/crosshair.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions packages/devtools-core/src/assets/svg/inspect.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading