├── .gitignore ├── .vscode ├── launch.json ├── settings.json └── tasks.json ├── .vscodeignore ├── CHANGELOG.md ├── LICENSE ├── README.md ├── ReactION-0.1.4.vsix ├── client ├── App.tsx ├── components │ ├── NodeLabel.tsx │ └── TreeView.tsx └── index.tsx ├── out ├── EmbeddedViewPanel.js ├── EmbeddedViewPanel.js.map ├── TreeData.js ├── TreeData.js.map ├── TreeNode.js ├── TreeNode.js.map ├── build │ └── bundle.js ├── client │ ├── App.js │ ├── App.js.map │ ├── components │ │ ├── NodeLabel.js │ │ ├── NodeLabel.js.map │ │ ├── TreeView.js │ │ └── TreeView.js.map │ ├── index.js │ └── index.js.map ├── extension.js ├── extension.js.map ├── htmlPreviewPanel.js ├── htmlPreviewPanel.js.map ├── htmlViewPanel.js ├── htmlViewPanel.js.map ├── puppeteer.js ├── puppeteer.js.map ├── src │ ├── EmbeddedViewPanel.js │ ├── EmbeddedViewPanel.js.map │ ├── TreeNode.js │ ├── TreeNode.js.map │ ├── TreeViewPanel.js │ ├── TreeViewPanel.js.map │ ├── ViewPanel.js │ ├── ViewPanel.js.map │ ├── extension.js │ ├── extension.js.map │ ├── htmlViewPanel.js │ ├── htmlViewPanel.js.map │ ├── puppeteer.js │ ├── puppeteer.js.map │ ├── startExtensionProvider.js │ ├── startExtensionProvider.js.map │ └── test │ │ ├── TreeView.test.js │ │ ├── TreeView.test.js.map │ │ ├── extension.test.js │ │ ├── extension.test.js.map │ │ ├── index.js │ │ ├── index.js.map │ │ ├── puppeteer.test.js │ │ └── puppeteer.test.js.map ├── startExtensionProvider.js ├── startExtensionProvider.js.map ├── test │ ├── extension.test.js │ ├── extension.test.js.map │ ├── index.js │ ├── index.js.map │ ├── puppeteer.test.js │ └── puppeteer.test.js.map ├── treeviewpanel.js ├── treeviewpanel.js.map ├── viewPanel.js └── viewPanel.js.map ├── package-lock.json ├── package.json ├── reactION-config.json ├── resources ├── Text_1.png ├── Text_2.png ├── black.png ├── color.png └── reactionlogo.svg ├── src ├── Demo.gif ├── EmbeddedViewPanel.ts ├── ReactION-sample.png ├── TreeNode.ts ├── TreeViewPanel.ts ├── ViewPanel.ts ├── extension.ts ├── global.d.ts ├── htmlViewPanel.ts ├── puppeteer.ts ├── startExtensionProvider.ts └── test │ ├── TreeView.test.ts │ ├── extension.test.ts │ ├── index.ts │ └── puppeteer.test.ts ├── tsconfig.json ├── tslint.json ├── webpack.config.js └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | # testing 3 | /coverage 4 | # production 5 | /build 6 | # misc 7 | .DS_Store 8 | .env.local 9 | .env.development.local 10 | .env.test.local 11 | .env.production.local 12 | .vscode-test 13 | npm-debug.log* 14 | yarn-debug.log* 15 | yarn-error.log* 16 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "Run Extension - ReactION", 9 | "type": "extensionHost", 10 | "request": "launch", 11 | "runtimeExecutable": "${execPath}", 12 | "args": [ 13 | "--extensionDevelopmentPath=${workspaceRoot}" 14 | ], 15 | "outFiles": [ 16 | "${workspaceFolder}/src" 17 | ], 18 | "preLaunchTask": "npm: watch", 19 | "stopOnEntry": false, 20 | "sourceMaps": true, 21 | }, 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.insertSpaces": false 3 | } -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | // See https://go.microsoft.com/fwlink/?LinkId=733558 2 | // for the documentation about the tasks.json format 3 | { 4 | "version": "2.0.0", 5 | "tasks": [ 6 | { 7 | "type": "npm", 8 | "script": "watch", 9 | "problemMatcher": "$tsc-watch", 10 | "isBackground": true, 11 | "presentation": { 12 | "reveal": "never" 13 | }, 14 | "group": { 15 | "kind": "build", 16 | "isDefault": true 17 | } 18 | }, 19 | // { 20 | // "type": "npm", 21 | // "script": "react-devtools", 22 | // // "problemMatcher": "$tsc-watch", 23 | // "isBackground": true, 24 | // "presentation": { 25 | // "reveal": "never" 26 | // }, 27 | // "group": { 28 | // "kind": "build", 29 | // "isDefault": true 30 | // } 31 | // } 32 | ] 33 | } 34 | -------------------------------------------------------------------------------- /.vscodeignore: -------------------------------------------------------------------------------- 1 | **/*.ts 2 | **/tsconfig.json 3 | !file.ts 4 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | All notable changes to the "ReactION" extension will be documented in this file. 3 | 4 | Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how to structure this file. 5 | 6 | ## [Unreleased] 7 | - Initial release -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2019 ReactION 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 |
3 | logo 4 |
5 | Dedicated React IDE in VS Code 6 |
7 |
8 |

9 | 10 | [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://github.com/ReactION-js/ReactION/pulls) 11 | [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/ReactION-js/ReactION/LICENSE) 12 | 13 |

A React development environment inside your VS Code editor.

14 | 15 | [ReactION](https://reactionjs.io/)'s hot-reloading HTML previewer and component visualizer helps you streamline your React development workflow. ReactION is currently in active development so we welcome any constructive feedback or contributions to this product. Please follow this repo for contribution guidelines and our development road map. 16 | 17 | ## Features in the pipeline 18 | features 19 |
20 | 21 | 1. **Works with any React application** - ReactION supports React 16.1+ (including React Fiber) and React Router v4. 22 | 2. **Visualize your app** - ReactION shows the current structure of your application in real time with hot reloading. 23 | 3. **Preview your HTML** - Live render of your App through the in-editor HTML preview in sync with the tree view. 24 | 4. **From Tree to Codes** - ReactION will open up the React file that is associated with the particular component on the tree view when you click it. 25 | 5. **Gain quick insights into your React tree state** - the React tree nodes will have different colors based on its current state and props, including the latest component change. 26 | 6. **Debug your React** - With ReactION, you can travel through different state changes of your React application 27 | 28 | ## Prerequisite 29 | - Make sure you have [Google Chrome](https://www.google.com/chrome/) installed on your computer. Also, our extension currently only runs in VS Code environment, so make sure you are using VS Code as the code editor. 30 | - Also, you will need a React application. Feel free to fork and clone our sample app [here!](https://github.com/ReactION-js/sample-project-react) 31 | 32 | ## Demo of current product 33 | ![](src/Demo.gif) 34 | 35 | ## Current Features 36 | - [x] No setup required! ReactION requires NO modification to your codebase, but installing the VS Code extension. 37 | - [x] React Fiber Tree structure shown inside VS Code (Powered by [Chrome Headless](https://developers.google.com/web/updates/2017/04/headless)). 38 | - [x] Ability to edit components on the HTML preview and see the component hierarchy on the side panel. 39 | - [x] Alternatable theme based on user preference (i.e., Light and Dark). 40 | 41 | ## In Progress 42 | - [ ] In-editor HTML preview in sync with the tree view 43 | - [ ] Clicking on the node triggering associated React component file 44 | - [ ] Re-rendering on save 45 | - [ ] Node color difference based on its status 46 | - [ ] Time Traveling your React application 47 | 48 | ## How to Use 49 | #### [Download Directly from GitHub] 50 | 1. Clone the repo and run ```npm install``` 51 | 2. Run ```npm run build ``` 52 | 3. Open VS Code Extension mode by pressing ```F5``` or ```ctr+5``` 53 | 4. When a new VS Code window pops up, open the React code file that you want to run the extension on 54 | 5. ```npm start``` your React file and run your application in ```localhost:3000``` (default) 55 | 6. Run the main extension by clicking on the ReactION logo on the side panel or ```ReactION:Launch``` 56 | 7. Run the embedded HTML webview version with the command ```cmd + shift + p``` then ```ReactION: Embedded Webview``` 57 | 8. Enjoy the tree view! 58 | 59 | #### [Download From VS Code Marketplace] 60 | You can download the extension directly from the [Marketplace](https://marketplace.visualstudio.com/items?itemName=ReactION-js.ReactION). 61 | 62 | ## Configuring ReactION's Default Settings 63 | You can change the following default settings in the Configuration file: 64 | - React Tree View Theme 65 | - Change the server port that ReactION listens to 66 | - Change whether or not to have an external Chrome instance 67 | 68 | You can configure ReactION's default settings through the ReactION-config.json file as such: 69 | 70 | ```json 71 | { 72 | "system": "darwin", 73 | "executablePath": "", 74 | "localhost": "localhost:3000", 75 | "headless_browser": false, 76 | "headless_embedded": true, 77 | "reactTheme": "dark" 78 | } 79 | ``` 80 | 81 | ## Built With 82 | - [TypeScript](https://www.typescriptlang.org/) - For the codebase 83 | - [Node.js](https://nodejs.org/en/) - File system, testing, core extension functionality 84 | - [Puppeteer](https://pptr.dev/) - Headless Chrome browser 85 | - [WebSockets](https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API) - Connection between HTML and tree view 86 | - [React](https://reactjs.org/) - Webview 87 | - [React-D3-Tree](https://github.com/bkrem/react-d3-tree) - Visualize components 88 | - [Mocha](https://mochajs.org/) - Testing 89 | - Love ❤️ 90 | 91 | ## Contributing 92 | ReactION is currently in beta release. Please let us know about bugs and suggestions at the [issue](https://github.com/ReactION-js/ReactION/issues) section. Feel free to fork this repo and submit pull requests! 93 | 94 | ## Team 95 | [Andy Tran](http://github.com/andyxtran) | 96 | [Carson Chen](http://github.com/CarsonCYChen) | 97 | [Daniel Wu](http://github.com/wdanni) | 98 | [Jinsung Park](http://github.com/jsliapark) 99 | 100 | ## Designer 101 | [Yoojin Jung](https://github.com/jsliapark/ReactION/blob/staging/resources/Text_2.png) 102 | 103 | ## License 104 | MIT - check out [license](https://github.com/ReactION-js/ReactION/LICENSE) page for more details 105 | 106 | -------------------------------------------------------------------------------- /ReactION-0.1.4.vsix: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ReactION-js/ReactION/d5ec81e69a4634b0d8d0a0be2e72e808a1cf08fa/ReactION-0.1.4.vsix -------------------------------------------------------------------------------- /client/App.tsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import D3TreeChart from './components/TreeView'; 3 | 4 | interface Props {} 5 | 6 | class App extends Component { 7 | render() { 8 | return ( 9 |
10 | 11 |
12 | ); 13 | } 14 | } 15 | 16 | export default App; 17 | -------------------------------------------------------------------------------- /client/components/NodeLabel.tsx: -------------------------------------------------------------------------------- 1 | import React, { useState, CSSProperties } from 'react'; 2 | 3 | interface NodeLabelProps { 4 | className: string; 5 | nodeData: { 6 | name: string; 7 | attributes: string[]; 8 | }; 9 | } 10 | 11 | const NodeLabel: React.FC = ({ className, nodeData }) => { 12 | const [divStyle, setDivStyle] = useState({ 13 | display: "none", 14 | flexDirection: 'column' 15 | }); 16 | 17 | const mouseEnter = () => { 18 | setDivStyle({ 19 | display: "flex", 20 | flexDirection: 'column' 21 | }); 22 | }; 23 | 24 | const mouseOut = () => { 25 | setDivStyle({ 26 | display: "none", 27 | flexDirection: 'column' 28 | }); 29 | }; 30 | 31 | const elArr = nodeData.attributes.map((el, index) => ( 32 |

{el}

33 | )); 34 | 35 | return ( 36 |
37 |

{nodeData.name}

38 |
39 | {elArr} 40 |
41 |
42 | ); 43 | }; 44 | 45 | export default NodeLabel; 46 | -------------------------------------------------------------------------------- /client/components/TreeView.tsx: -------------------------------------------------------------------------------- 1 | import React, { useState, useCallback } from 'react'; 2 | import Tree from 'react-d3-tree'; 3 | import NodeLabel from './NodeLabel'; 4 | import styled from 'styled-components'; 5 | 6 | const TreeStyled = styled.div` 7 | .linkBase { 8 | fill: none; 9 | stroke: #d3d3d3; 10 | stroke-width: 2px; 11 | } 12 | font-family: 'Crimson Text', serif; 13 | `; 14 | 15 | const Name = styled.g<{ theme: string }>` 16 | .nodenamebase { 17 | stroke: ${(props) => (props.theme === 'light' ? '#181818' : '#f8f8f8')}; 18 | font-size: large; 19 | fill: ${(props) => (props.theme === 'light' ? '#181818' : '#f8f8f8')}; 20 | } 21 | .nodeAttributesBase { 22 | stroke: ${(props) => (props.theme === 'light' ? '#181818' : '#f8f8f8')}; 23 | } 24 | `; 25 | 26 | const myTreeData = (window as any)._TREE_DATA; 27 | 28 | const D3TreeChart: React.FC = () => { 29 | const [orientation, setOrientation] = useState<'vertical' | 'horizontal'>('vertical'); 30 | const [x, setX] = useState(200); 31 | const [y, setY] = useState(100); 32 | const [nodeSvgShape, setNodeSvgShape] = useState({ 33 | shape: 'circle', 34 | shapeProps: { 35 | r: 10, 36 | fill: '#1e1e1e', 37 | stroke: '#181818', 38 | strokeWidth: '0px', 39 | nodenamebase: '#1e1e1e', 40 | }, 41 | theme: 'light', 42 | background: 'rgb(255,255,255)', 43 | }); 44 | 45 | const changeOrientation = useCallback(() => { 46 | if (orientation === 'vertical') { 47 | setOrientation('horizontal'); 48 | setX(100); 49 | setY(100); 50 | } else { 51 | setOrientation('vertical'); 52 | setX(200); 53 | setY(100); 54 | } 55 | }, [orientation]); 56 | 57 | return ( 58 |
68 | 71 | {/* 75 |

*/} 76 |
77 | 78 | 79 | , 87 | }} 88 | textLayout={{ textAnchor: 'start', x: 13, y: 0, transform: undefined }} 89 | /> 90 | 91 | 92 |
93 |
94 | ); 95 | }; 96 | 97 | export default D3TreeChart; 98 | -------------------------------------------------------------------------------- /client/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { createRoot } from 'react-dom/client'; 3 | import App from './App'; 4 | 5 | const rootElement = document.getElementById('root'); 6 | 7 | if (rootElement) { 8 | const root = createRoot(rootElement); 9 | root.render(); 10 | } else { 11 | console.error('Root element not found'); 12 | } 13 | -------------------------------------------------------------------------------- /out/EmbeddedViewPanel.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | const vscode = require("vscode"); 4 | const Puppeteer_1 = require("./Puppeteer"); 5 | const treeViewPanel_1 = require("./treeViewPanel"); 6 | const htmlViewPanel_1 = require("./htmlViewPanel"); 7 | const TreeNode_1 = require("./TreeNode"); 8 | class EmbeddedViewPanel { 9 | // Constructor for tree view and html panel 10 | constructor(htmlPanel, treePanel, parseInfo) { 11 | this._disposables = []; 12 | this._htmlPanel = htmlPanel; 13 | this._treePanel = treePanel; 14 | this._parseInfo = parseInfo; 15 | // Starts the instance of the embedded webview 16 | this._htmlPanel.webview.html = this._getPreviewHtmlForWebview(); 17 | // Running Puppeteer to access React page context 18 | this._page = new Puppeteer_1.default(parseInfo); 19 | this._page.start(); 20 | setInterval(() => { 21 | this._update(); 22 | }, 1000); 23 | this._treePanel.onDidDispose(() => this.dispose(), null, this._disposables); 24 | } 25 | static createOrShow(extensionPath, parseInfo) { 26 | const treeColumn = vscode.ViewColumn.Three; 27 | const htmlColumn = vscode.ViewColumn.Two; 28 | if (EmbeddedViewPanel.currentPanel) { 29 | EmbeddedViewPanel.currentPanel._htmlPanel.reveal(htmlColumn); 30 | EmbeddedViewPanel.currentPanel._treePanel.reveal(treeColumn); 31 | return; 32 | } 33 | // Show HTML Preview in VS Code 34 | const htmlPanel = vscode.window.createWebviewPanel(EmbeddedViewPanel.viewType, "HTML Preview", htmlColumn, { 35 | // Enable javascript in the webview 36 | enableScripts: true, 37 | retainContextWhenHidden: true, 38 | enableCommandUris: true 39 | }); 40 | // Show Virtual DOM Tree in VS Code 41 | const treePanel = vscode.window.createWebviewPanel(EmbeddedViewPanel.viewType, "Virtual DOM Tree", treeColumn, { 42 | // Enable javascript in the webview 43 | enableScripts: true, 44 | retainContextWhenHidden: true, 45 | enableCommandUris: true 46 | }); 47 | EmbeddedViewPanel.currentPanel = new EmbeddedViewPanel(htmlPanel, treePanel, parseInfo); 48 | } 49 | dispose() { 50 | EmbeddedViewPanel.currentPanel = undefined; 51 | // Clean up our resources 52 | this._htmlPanel.dispose(); 53 | this._treePanel.dispose(); 54 | while (this._disposables.length) { 55 | const x = this._disposables.pop(); 56 | if (x) { 57 | x.dispose(); 58 | } 59 | } 60 | } 61 | async _update() { 62 | let rawReactData = await this._page.scrape(); 63 | // Build out TreeNode class for React D3 Tree. 64 | function buildTree(rawReactData) { 65 | let tree = new TreeNode_1.default(rawReactData[0]); 66 | const freeNodes = []; 67 | rawReactData.forEach((el) => { 68 | const parentNode = tree._find(tree, el.parentId); 69 | if (parentNode) { 70 | parentNode._add(el); 71 | } 72 | else { 73 | freeNodes.push(el); 74 | } 75 | }); 76 | while (freeNodes.length > 0) { 77 | const curEl = freeNodes[0]; 78 | const parentNode = tree._find(tree, curEl.parentId); 79 | if (parentNode) { 80 | parentNode._add(curEl); 81 | } 82 | freeNodes.shift(); 83 | } 84 | return tree; 85 | } 86 | const treeData = await buildTree(rawReactData); 87 | this._treePanel.webview.html = this._getHtmlForWebview(treeData); 88 | } 89 | // Putting scraped meta-data to D3 tree diagram 90 | _getHtmlForWebview(treeData) { 91 | const stringifiedFlatData = JSON.stringify(treeData); 92 | return treeViewPanel_1.default.generateD3(stringifiedFlatData, this._parseInfo); 93 | } 94 | _getPreviewHtmlForWebview() { 95 | return htmlViewPanel_1.default.html; 96 | } 97 | } 98 | EmbeddedViewPanel.viewType = 'ReactION'; 99 | exports.default = EmbeddedViewPanel; 100 | //# sourceMappingURL=EmbeddedViewPanel.js.map -------------------------------------------------------------------------------- /out/EmbeddedViewPanel.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"EmbeddedViewPanel.js","sourceRoot":"","sources":["../src/EmbeddedViewPanel.ts"],"names":[],"mappings":"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"} -------------------------------------------------------------------------------- /out/TreeData.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | class TreeNode { 4 | constructor(node) { 5 | this._name = node.name; 6 | this._id = node.id; 7 | this._props = node.props; 8 | this._children = []; 9 | } 10 | } 11 | exports.default = TreeNode; 12 | //# sourceMappingURL=TreeData.js.map -------------------------------------------------------------------------------- /out/TreeData.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"TreeData.js","sourceRoot":"","sources":["../src/TreeData.ts"],"names":[],"mappings":";;AAAA,MAAqB,QAAQ;IAG5B,YAAmB,IAAI;QACtB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC;QACvB,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,EAAE,CAAC;QACnB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC;QACzB,IAAI,CAAC,SAAS,GAAG,EAAE,CAAC;IACrB,CAAC;CACD;AATD,2BASC"} -------------------------------------------------------------------------------- /out/TreeNode.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | class TreeNode { 4 | constructor(node) { 5 | this.name = node.name; 6 | this.id = node.id; 7 | this.attributes = node.props; 8 | this.parentId = node.parentId; 9 | this.display = node.display; 10 | this.children = []; 11 | } 12 | // Add new node to the tree 13 | _add(node) { 14 | const newNode = new TreeNode(node); 15 | this.children.push(newNode); 16 | } 17 | // Search if there is a node with matching id. 18 | _find(root, parentId) { 19 | let curNode = root; 20 | if (curNode.id === parentId) { 21 | return curNode; 22 | } 23 | if (curNode.children.length !== 0) { 24 | for (let el of curNode.children) { 25 | const findParent = this._find(el, parentId); 26 | if (findParent) { 27 | return findParent; 28 | } 29 | } 30 | } 31 | return false; 32 | } 33 | } 34 | exports.default = TreeNode; 35 | //# sourceMappingURL=TreeNode.js.map -------------------------------------------------------------------------------- /out/TreeNode.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"TreeNode.js","sourceRoot":"","sources":["../src/TreeNode.ts"],"names":[],"mappings":";;AAAA,MAAqB,QAAQ;IAQ5B,YAAmB,IAAS;QAC3B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;QACtB,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC;QAClB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC;QAC7B,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC9B,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;QAC5B,IAAI,CAAC,QAAQ,GAAG,EAAE,CAAC;IACpB,CAAC;IAED,2BAA2B;IACpB,IAAI,CAAC,IAAS;QACpB,MAAM,OAAO,GAAG,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC;QACnC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC7B,CAAC;IAED,8CAA8C;IACvC,KAAK,CAAC,IAAS,EAAE,QAAa;QACpC,IAAI,OAAO,GAAG,IAAI,CAAC;QACnB,IAAI,OAAO,CAAC,EAAE,KAAK,QAAQ,EAAE;YAC5B,OAAO,OAAO,CAAC;SACf;QACD,IAAI,OAAO,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE;YAClC,KAAK,IAAI,EAAE,IAAI,OAAO,CAAC,QAAQ,EAAE;gBAChC,MAAM,UAAU,GAAQ,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC;gBACjD,IAAI,UAAU,EAAE;oBACf,OAAO,UAAU,CAAC;iBAClB;aACD;SACD;QACD,OAAO,KAAK,CAAC;IACd,CAAC;CACD;AAvCD,2BAuCC"} -------------------------------------------------------------------------------- /out/client/App.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { 3 | if (k2 === undefined) k2 = k; 4 | var desc = Object.getOwnPropertyDescriptor(m, k); 5 | if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { 6 | desc = { enumerable: true, get: function() { return m[k]; } }; 7 | } 8 | Object.defineProperty(o, k2, desc); 9 | }) : (function(o, m, k, k2) { 10 | if (k2 === undefined) k2 = k; 11 | o[k2] = m[k]; 12 | })); 13 | var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { 14 | Object.defineProperty(o, "default", { enumerable: true, value: v }); 15 | }) : function(o, v) { 16 | o["default"] = v; 17 | }); 18 | var __importStar = (this && this.__importStar) || function (mod) { 19 | if (mod && mod.__esModule) return mod; 20 | var result = {}; 21 | if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); 22 | __setModuleDefault(result, mod); 23 | return result; 24 | }; 25 | var __importDefault = (this && this.__importDefault) || function (mod) { 26 | return (mod && mod.__esModule) ? mod : { "default": mod }; 27 | }; 28 | Object.defineProperty(exports, "__esModule", { value: true }); 29 | const react_1 = __importStar(require("react")); 30 | const TreeView_1 = __importDefault(require("./components/TreeView")); 31 | class App extends react_1.Component { 32 | render() { 33 | return (react_1.default.createElement("div", null, 34 | react_1.default.createElement(TreeView_1.default, null))); 35 | } 36 | } 37 | exports.default = App; 38 | //# sourceMappingURL=App.js.map -------------------------------------------------------------------------------- /out/client/App.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"App.js","sourceRoot":"","sources":["../../client/App.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,+CAAyC;AACzC,qEAAgD;AAIhD,MAAM,GAAI,SAAQ,iBAAgB;IACjC,MAAM;QACL,OAAO,CACN;YACC,8BAAC,kBAAW,OAAG,CACV,CACN,CAAC;IACH,CAAC;CACD;AAED,kBAAe,GAAG,CAAC"} -------------------------------------------------------------------------------- /out/client/components/NodeLabel.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { 3 | if (k2 === undefined) k2 = k; 4 | var desc = Object.getOwnPropertyDescriptor(m, k); 5 | if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { 6 | desc = { enumerable: true, get: function() { return m[k]; } }; 7 | } 8 | Object.defineProperty(o, k2, desc); 9 | }) : (function(o, m, k, k2) { 10 | if (k2 === undefined) k2 = k; 11 | o[k2] = m[k]; 12 | })); 13 | var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { 14 | Object.defineProperty(o, "default", { enumerable: true, value: v }); 15 | }) : function(o, v) { 16 | o["default"] = v; 17 | }); 18 | var __importStar = (this && this.__importStar) || function (mod) { 19 | if (mod && mod.__esModule) return mod; 20 | var result = {}; 21 | if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); 22 | __setModuleDefault(result, mod); 23 | return result; 24 | }; 25 | Object.defineProperty(exports, "__esModule", { value: true }); 26 | const react_1 = __importStar(require("react")); 27 | const NodeLabel = ({ className, nodeData }) => { 28 | const [divStyle, setDivStyle] = (0, react_1.useState)({ 29 | display: "none", 30 | flexDirection: 'column' 31 | }); 32 | const mouseEnter = () => { 33 | setDivStyle({ 34 | display: "flex", 35 | flexDirection: 'column' 36 | }); 37 | }; 38 | const mouseOut = () => { 39 | setDivStyle({ 40 | display: "none", 41 | flexDirection: 'column' 42 | }); 43 | }; 44 | const elArr = nodeData.attributes.map((el, index) => (react_1.default.createElement("p", { key: index }, el))); 45 | return (react_1.default.createElement("div", { className: className, onMouseEnter: mouseEnter, onMouseOut: mouseOut }, 46 | react_1.default.createElement("h2", null, nodeData.name), 47 | react_1.default.createElement("div", { style: divStyle }, elArr))); 48 | }; 49 | exports.default = NodeLabel; 50 | //# sourceMappingURL=NodeLabel.js.map -------------------------------------------------------------------------------- /out/client/components/NodeLabel.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"NodeLabel.js","sourceRoot":"","sources":["../../../client/components/NodeLabel.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAAA,+CAAuD;AAUvD,MAAM,SAAS,GAA6B,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,EAAE,EAAE;IACtE,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,IAAA,gBAAQ,EAAgB;QACtD,OAAO,EAAE,MAAM;QACf,aAAa,EAAE,QAAQ;KACxB,CAAC,CAAC;IAEH,MAAM,UAAU,GAAG,GAAG,EAAE;QACtB,WAAW,CAAC;YACV,OAAO,EAAE,MAAM;YACf,aAAa,EAAE,QAAQ;SACxB,CAAC,CAAC;IACL,CAAC,CAAC;IAEF,MAAM,QAAQ,GAAG,GAAG,EAAE;QACpB,WAAW,CAAC;YACV,OAAO,EAAE,MAAM;YACf,aAAa,EAAE,QAAQ;SACxB,CAAC,CAAC;IACL,CAAC,CAAC;IAEF,MAAM,KAAK,GAAG,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,KAAK,EAAE,EAAE,CAAC,CACnD,qCAAG,GAAG,EAAE,KAAK,IAAG,EAAE,CAAK,CACxB,CAAC,CAAC;IAEH,OAAO,CACL,uCAAK,SAAS,EAAE,SAAS,EAAE,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,QAAQ;QACvE,0CAAK,QAAQ,CAAC,IAAI,CAAM;QACxB,uCAAK,KAAK,EAAE,QAAQ,IACjB,KAAK,CACF,CACF,CACP,CAAC;AACJ,CAAC,CAAC;AAEF,kBAAe,SAAS,CAAC"} -------------------------------------------------------------------------------- /out/client/components/TreeView.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { 3 | if (k2 === undefined) k2 = k; 4 | var desc = Object.getOwnPropertyDescriptor(m, k); 5 | if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { 6 | desc = { enumerable: true, get: function() { return m[k]; } }; 7 | } 8 | Object.defineProperty(o, k2, desc); 9 | }) : (function(o, m, k, k2) { 10 | if (k2 === undefined) k2 = k; 11 | o[k2] = m[k]; 12 | })); 13 | var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { 14 | Object.defineProperty(o, "default", { enumerable: true, value: v }); 15 | }) : function(o, v) { 16 | o["default"] = v; 17 | }); 18 | var __importStar = (this && this.__importStar) || function (mod) { 19 | if (mod && mod.__esModule) return mod; 20 | var result = {}; 21 | if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); 22 | __setModuleDefault(result, mod); 23 | return result; 24 | }; 25 | var __importDefault = (this && this.__importDefault) || function (mod) { 26 | return (mod && mod.__esModule) ? mod : { "default": mod }; 27 | }; 28 | Object.defineProperty(exports, "__esModule", { value: true }); 29 | const react_1 = __importStar(require("react")); 30 | const react_d3_tree_1 = __importDefault(require("react-d3-tree")); 31 | const NodeLabel_1 = __importDefault(require("./NodeLabel")); 32 | const styled_components_1 = __importDefault(require("styled-components")); 33 | const TreeStyled = styled_components_1.default.div ` 34 | .linkBase { 35 | fill: none; 36 | stroke: #d3d3d3; 37 | stroke-width: 2px; 38 | } 39 | font-family: 'Crimson Text', serif; 40 | `; 41 | const Name = styled_components_1.default.g ` 42 | .nodenamebase { 43 | stroke: ${(props) => (props.theme === 'light' ? '#181818' : '#f8f8f8')}; 44 | font-size: large; 45 | fill: ${(props) => (props.theme === 'light' ? '#181818' : '#f8f8f8')}; 46 | } 47 | .nodeAttributesBase { 48 | stroke: ${(props) => (props.theme === 'light' ? '#181818' : '#f8f8f8')}; 49 | } 50 | `; 51 | const myTreeData = window._TREE_DATA; 52 | const D3TreeChart = () => { 53 | const [orientation, setOrientation] = (0, react_1.useState)('vertical'); 54 | const [x, setX] = (0, react_1.useState)(200); 55 | const [y, setY] = (0, react_1.useState)(100); 56 | const [nodeSvgShape, setNodeSvgShape] = (0, react_1.useState)({ 57 | shape: 'circle', 58 | shapeProps: { 59 | r: 10, 60 | fill: '#1e1e1e', 61 | stroke: '#181818', 62 | strokeWidth: '0px', 63 | nodenamebase: '#1e1e1e', 64 | }, 65 | theme: 'light', 66 | background: 'rgb(255,255,255)', 67 | }); 68 | const changeOrientation = (0, react_1.useCallback)(() => { 69 | if (orientation === 'vertical') { 70 | setOrientation('horizontal'); 71 | setX(100); 72 | setY(100); 73 | } 74 | else { 75 | setOrientation('vertical'); 76 | setX(200); 77 | setY(100); 78 | } 79 | }, [orientation]); 80 | return (react_1.default.createElement("div", { className: "treeChart", style: { 81 | width: '100%', 82 | height: '100em', 83 | display: 'flex', 84 | flexDirection: 'column', 85 | backgroundColor: nodeSvgShape.background, 86 | } }, 87 | react_1.default.createElement("button", { onClick: changeOrientation }, "Click to change orientation"), 88 | react_1.default.createElement("div", { style: { width: '100%', height: '98em' } }, 89 | react_1.default.createElement(TreeStyled, null, 90 | react_1.default.createElement(Name, { theme: nodeSvgShape.theme }, 91 | react_1.default.createElement(react_d3_tree_1.default, { translate: { x, y }, data: myTreeData, orientation: orientation, nodeSvgShape: nodeSvgShape, allowForeignObjects: true, nodeLabelComponent: { 92 | render: react_1.default.createElement(NodeLabel_1.default, { className: "myLabelComponentInSvg", nodeData: { name: 'Node Name', attributes: [] } }), 93 | }, textLayout: { textAnchor: 'start', x: 13, y: 0, transform: undefined } })))))); 94 | }; 95 | exports.default = D3TreeChart; 96 | //# sourceMappingURL=TreeView.js.map -------------------------------------------------------------------------------- /out/client/components/TreeView.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"TreeView.js","sourceRoot":"","sources":["../../../client/components/TreeView.tsx"],"names":[],"mappings":"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"} -------------------------------------------------------------------------------- /out/client/index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __importDefault = (this && this.__importDefault) || function (mod) { 3 | return (mod && mod.__esModule) ? mod : { "default": mod }; 4 | }; 5 | Object.defineProperty(exports, "__esModule", { value: true }); 6 | const react_1 = __importDefault(require("react")); 7 | const client_1 = require("react-dom/client"); 8 | const App_1 = __importDefault(require("./App")); 9 | const rootElement = document.getElementById('root'); 10 | if (rootElement) { 11 | const root = (0, client_1.createRoot)(rootElement); 12 | root.render(react_1.default.createElement(App_1.default, null)); 13 | } 14 | else { 15 | console.error('Root element not found'); 16 | } 17 | //# sourceMappingURL=index.js.map -------------------------------------------------------------------------------- /out/client/index.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"index.js","sourceRoot":"","sources":["../../client/index.tsx"],"names":[],"mappings":";;;;;AAAA,kDAA0B;AAC1B,6CAA8C;AAC9C,gDAAwB;AAExB,MAAM,WAAW,GAAG,QAAQ,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;AAEpD,IAAI,WAAW,EAAE,CAAC;IAChB,MAAM,IAAI,GAAG,IAAA,mBAAU,EAAC,WAAW,CAAC,CAAC;IACrC,IAAI,CAAC,MAAM,CAAC,8BAAC,aAAG,OAAG,CAAC,CAAC;AACvB,CAAC;KAAM,CAAC;IACN,OAAO,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAC;AAC1C,CAAC"} -------------------------------------------------------------------------------- /out/extension.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | exports.deactivate = exports.activate = void 0; 4 | const vscode = require("vscode"); 5 | const StartExtensionProvider_1 = require("./StartExtensionProvider"); 6 | const EmbeddedViewPanel_1 = require("./EmbeddedViewPanel"); 7 | const ViewPanel_1 = require("./ViewPanel"); 8 | const fs = require('fs'); 9 | const path = require('path'); 10 | // const os = require('os'); 11 | let parseInfo; 12 | // Method called when extension is activated 13 | function activate(context) { 14 | const rootPath = vscode.workspace.rootPath; 15 | const configPath = path.join(rootPath, "reactION-config.json"); 16 | const setup = {}; 17 | setup.system = process.platform; 18 | // Setting the executable path on config file based on user's OS. 19 | switch (setup.system) { 20 | // For iOS environment. 21 | case 'darwin': 22 | setup.executablePath = '/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome'; 23 | break; 24 | // For Linux environment. 25 | case 'linux': 26 | setup.executablePath = ''; 27 | vscode.window.showInformationMessage('Please specify your Chrominum executablePath in reactION.config.json file created in your local directory.'); 28 | break; 29 | // For Window 10 environment. 30 | case 'win32': 31 | setup.executablePath = 'C:\Program Files (x86)\Google\Chrome\Application\chrome.exe'; 32 | break; 33 | default: 34 | vscode.window.showInformationMessage('Current Operating System is not supported.'); 35 | } 36 | setup.localhost = 'localhost:3000'; 37 | setup.headless_browser = false; 38 | setup.headless_embedded = true; 39 | setup.reactTheme = 'dark'; 40 | fs.stat(configPath, (err, stats) => { 41 | if (err) { 42 | console.log(err); 43 | } 44 | if (!stats) { 45 | fs.writeFileSync(configPath, JSON.stringify(setup, null, '\t')); 46 | } 47 | else { 48 | // else read off and apply config to the running instance 49 | parseInfo = JSON.parse(fs.readFileSync(configPath)); 50 | } 51 | }); 52 | context.subscriptions.push(vscode.commands.registerCommand('ReactION.openTree', () => { 53 | ViewPanel_1.default.createOrShow(context.extensionPath, parseInfo); 54 | })); 55 | context.subscriptions.push(vscode.commands.registerCommand('ReactION.openWeb', () => { 56 | EmbeddedViewPanel_1.default.createOrShow(context.extensionPath, parseInfo); 57 | })); 58 | vscode.window.registerTreeDataProvider('startExtension', new StartExtensionProvider_1.default()); 59 | } 60 | exports.activate = activate; 61 | // This method is called when your extension is deactivated 62 | function deactivate() { } 63 | exports.deactivate = deactivate; 64 | //# sourceMappingURL=extension.js.map -------------------------------------------------------------------------------- /out/extension.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"extension.js","sourceRoot":"","sources":["../src/extension.ts"],"names":[],"mappings":";;;AAAA,iCAAiC;AACjC,qEAA8D;AAC9D,2DAAoD;AACpD,2CAAoC;AACpC,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AACzB,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;AAC7B,4BAA4B;AAE5B,IAAI,SAAa,CAAC;AAElB,4CAA4C;AAC5C,SAAgB,QAAQ,CAAC,OAAgC;IAExD,MAAM,QAAQ,GAAG,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC;IAC3C,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,sBAAsB,CAAC,CAAC;IAC/D,MAAM,KAAK,GAAQ,EAAE,CAAC;IAEtB,KAAK,CAAC,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;IAEhC,iEAAiE;IACjE,QAAO,KAAK,CAAC,MAAM,EAAE;QAEpB,uBAAuB;QACvB,KAAK,QAAQ;YACZ,KAAK,CAAC,cAAc,GAAG,gEAAgE,CAAC;YACxF,MAAM;QAEP,yBAAyB;QACzB,KAAK,OAAO;YACX,KAAK,CAAC,cAAc,GAAG,EAAE,CAAC;YAC1B,MAAM,CAAC,MAAM,CAAC,sBAAsB,CAAC,4GAA4G,CAAC,CAAC;YACnJ,MAAM;QAEP,6BAA6B;QAC7B,KAAK,OAAO;YACX,KAAK,CAAC,cAAc,GAAG,6DAA6D,CAAC;YACrF,MAAM;QACP;YACC,MAAM,CAAC,MAAM,CAAC,sBAAsB,CAAC,4CAA4C,CAAC,CAAC;KACpF;IACD,KAAK,CAAC,SAAS,GAAG,gBAAgB,CAAC;IACnC,KAAK,CAAC,gBAAgB,GAAG,KAAK,CAAC;IAC/B,KAAK,CAAC,iBAAiB,GAAG,IAAI,CAAC;IAC/B,KAAK,CAAC,UAAU,GAAG,MAAM,CAAC;IAE1B,EAAE,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,GAAQ,EAAE,KAAU,EAAE,EAAE;QAC5C,IAAI,GAAG,EAAE;YACR,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;SACjB;QACD,IAAI,CAAC,KAAK,EAAE;YACX,EAAE,CAAC,aAAa,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;SAChE;aACI;YACJ,yDAAyD;YACzD,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC;SAEpD;IACF,CAAC,CAAC,CAAC;IAGH,OAAO,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,eAAe,CAAC,mBAAmB,EAAE,GAAG,EAAE;QACpF,mBAAS,CAAC,YAAY,CAAC,OAAO,CAAC,aAAa,EAAE,SAAS,CAAC,CAAC;IAC1D,CAAC,CAAC,CAAC,CAAC;IAEJ,OAAO,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,eAAe,CAAC,kBAAkB,EAAE,GAAG,EAAE;QACnF,2BAAiB,CAAC,YAAY,CAAC,OAAO,CAAC,aAAa,EAAE,SAAS,CAAC,CAAC;IAClE,CAAC,CAAC,CAAC,CAAC;IAEJ,MAAM,CAAC,MAAM,CAAC,wBAAwB,CAAC,gBAAgB,EAAE,IAAI,gCAAsB,EAAE,CAAC,CAAC;AACxF,CAAC;AA1DD,4BA0DC;AAED,2DAA2D;AAC3D,SAAgB,UAAU,KAAK,CAAC;AAAhC,gCAAgC"} -------------------------------------------------------------------------------- /out/htmlPreviewPanel.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | exports.default = { 4 | html: ` 5 | 17 | 18 | 19 | ` 20 | }; 21 | //# sourceMappingURL=htmlPreviewPanel.js.map -------------------------------------------------------------------------------- /out/htmlPreviewPanel.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"htmlPreviewPanel.js","sourceRoot":"","sources":["../../src/htmlPreviewPanel.ts"],"names":[],"mappings":";;AAAA,kBAAe;IACd,IAAI,EACL;;;;;;;;;;;;;;;CAeC;CACA,CAAC"} -------------------------------------------------------------------------------- /out/htmlViewPanel.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | exports.default = { 4 | html: ` 5 | 17 | 18 | 19 | ` 20 | }; 21 | //# sourceMappingURL=htmlViewPanel.js.map -------------------------------------------------------------------------------- /out/htmlViewPanel.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"htmlViewPanel.js","sourceRoot":"","sources":["../src/htmlViewPanel.ts"],"names":[],"mappings":";;AAAA,kBAAe;IACd,IAAI,EACL;;;;;;;;;;;;;;;CAeC;CACA,CAAC"} -------------------------------------------------------------------------------- /out/puppeteer.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | const puppeteer = require('puppeteer-core'); 4 | class Puppeteer { 5 | // Default properties for the Puppeteer class. 6 | constructor(parseInfo) { 7 | this._headless = false; 8 | this._executablePath = parseInfo.executablePath; 9 | this._pipe = true; 10 | this._url = parseInfo.localhost; 11 | this._page = ''; 12 | this._browser = ''; 13 | } 14 | // Creates an instance of puppeteer browser and page, 15 | // opens to _url, defaults to localhost:3000 16 | async start() { 17 | this._browser = await puppeteer.launch({ 18 | headless: this._headless, 19 | executablePath: this._executablePath, 20 | pipe: this._pipe, 21 | }).catch((err) => console.log(err)); 22 | this._page = await this._browser.pages() 23 | .then((pageArr) => { 24 | return pageArr[0]; 25 | }); 26 | this._page.goto(this._url); 27 | return await this._page; 28 | } 29 | // Recursive React component scraping algorithm 30 | scrape() { 31 | // All code inside .evaluate is executed in the pages context 32 | const reactData = this._page.evaluate(async () => { 33 | // Access the React Dom 34 | // & create entry point for fiber node through DOM element 35 | const _entry = (() => { 36 | // @ts-ignore 37 | const domElements = document.querySelector('body').children; 38 | for (let el of domElements) { 39 | // @ts-ignore 40 | if (el._reactRootContainer) { 41 | // @ts-ignore 42 | return el._reactRootContainer._internalRoot.current; 43 | } 44 | } 45 | })(); 46 | // Define function that traverses the fiber tree, starting from the entry point 47 | function fiberWalk(entry) { 48 | let dataArr = [], globalId = 1; 49 | // Recursively traversing through the fiber tree, pushing the node object into the dataArr array 50 | function traverse(root, level, parentId) { 51 | if (root.sibling !== null) { 52 | globalId += 1; 53 | dataArr.push({ 54 | "name": root.sibling, 55 | "level": `${level}`, 56 | "id": `${globalId}`, 57 | "parentId": `${parentId}`, 58 | "props": Object.keys(root.sibling.memoizedProps) 59 | }); 60 | traverse(root.sibling, level, parentId); 61 | } 62 | if (root.child !== null) { 63 | parentId += 1; 64 | globalId += 1; 65 | dataArr.push({ 66 | "name": root.child, 67 | "level": `${level}`, 68 | "id": `${globalId}`, 69 | "parentId": `${parentId}`, 70 | "display": "none", 71 | "props": Object.keys(root.child.memoizedProps) 72 | }); 73 | traverse(root.child, level + 1, parentId); 74 | } 75 | } 76 | traverse(entry, 0, 0); 77 | // Extracts the type name of each fiber node 78 | dataArr.forEach((el) => { 79 | if (typeof el.name.type === null) { 80 | el.name = ''; 81 | } 82 | else if (typeof el.name.type === 'function' && el.name.type.name) { 83 | el.name = el.name.type.name; 84 | } 85 | else if (typeof el.name.type === 'function') { 86 | el.name = 'function'; 87 | } 88 | else if (typeof el.name.type === 'object') { 89 | el.name = 'function'; 90 | } 91 | else if (typeof el.name.type === 'string') { 92 | el.name = el.name.type; 93 | } 94 | }); 95 | // Setting root parent to an empty string 96 | dataArr[0].parentId = ''; 97 | return dataArr; 98 | } 99 | return fiberWalk(_entry); 100 | }).catch((err) => { console.log(err); }); 101 | return reactData; 102 | } 103 | } 104 | exports.default = Puppeteer; 105 | //# sourceMappingURL=Puppeteer.js.map -------------------------------------------------------------------------------- /out/puppeteer.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"Puppeteer.js","sourceRoot":"","sources":["../src/Puppeteer.ts"],"names":[],"mappings":"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"} -------------------------------------------------------------------------------- /out/src/EmbeddedViewPanel.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { 3 | if (k2 === undefined) k2 = k; 4 | var desc = Object.getOwnPropertyDescriptor(m, k); 5 | if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { 6 | desc = { enumerable: true, get: function() { return m[k]; } }; 7 | } 8 | Object.defineProperty(o, k2, desc); 9 | }) : (function(o, m, k, k2) { 10 | if (k2 === undefined) k2 = k; 11 | o[k2] = m[k]; 12 | })); 13 | var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { 14 | Object.defineProperty(o, "default", { enumerable: true, value: v }); 15 | }) : function(o, v) { 16 | o["default"] = v; 17 | }); 18 | var __importStar = (this && this.__importStar) || function (mod) { 19 | if (mod && mod.__esModule) return mod; 20 | var result = {}; 21 | if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); 22 | __setModuleDefault(result, mod); 23 | return result; 24 | }; 25 | var __importDefault = (this && this.__importDefault) || function (mod) { 26 | return (mod && mod.__esModule) ? mod : { "default": mod }; 27 | }; 28 | Object.defineProperty(exports, "__esModule", { value: true }); 29 | const vscode = __importStar(require("vscode")); 30 | const puppeteer_1 = __importDefault(require("./puppeteer")); 31 | const TreeViewPanel_1 = __importDefault(require("./TreeViewPanel")); 32 | const htmlViewPanel_1 = __importDefault(require("./htmlViewPanel")); 33 | const TreeNode_1 = __importDefault(require("./TreeNode")); 34 | class EmbeddedViewPanel { 35 | // Constructor for tree view and html panel 36 | constructor(htmlPanel, treePanel, parseInfo) { 37 | this._disposables = []; 38 | this._htmlPanel = htmlPanel; 39 | this._treePanel = treePanel; 40 | this._parseInfo = parseInfo; 41 | // Starts the instance of the embedded webview 42 | this._htmlPanel.webview.html = this._getPreviewHtmlForWebview(); 43 | // Running Puppeteer to access React page context 44 | this._page = new puppeteer_1.default(parseInfo); 45 | this._page.start(); 46 | setInterval(() => { 47 | this._update(); 48 | }, 1000); 49 | this._treePanel.onDidDispose(() => this.dispose(), null, this._disposables); 50 | } 51 | static createOrShow(extensionPath, parseInfo) { 52 | const treeColumn = vscode.ViewColumn.Three; 53 | const htmlColumn = vscode.ViewColumn.Two; 54 | if (EmbeddedViewPanel.currentPanel) { 55 | EmbeddedViewPanel.currentPanel._htmlPanel.reveal(htmlColumn); 56 | EmbeddedViewPanel.currentPanel._treePanel.reveal(treeColumn); 57 | return; 58 | } 59 | // Show HTML Preview in VS Code 60 | const htmlPanel = vscode.window.createWebviewPanel(EmbeddedViewPanel.viewType, "HTML Preview", htmlColumn, { 61 | // Enable javascript in the webview 62 | enableScripts: true, 63 | retainContextWhenHidden: true, 64 | enableCommandUris: true 65 | }); 66 | // Show Virtual DOM Tree in VS Code 67 | const treePanel = vscode.window.createWebviewPanel(EmbeddedViewPanel.viewType, "Virtual DOM Tree", treeColumn, { 68 | // Enable javascript in the webview 69 | enableScripts: true, 70 | retainContextWhenHidden: true, 71 | enableCommandUris: true 72 | }); 73 | EmbeddedViewPanel.currentPanel = new EmbeddedViewPanel(htmlPanel, treePanel, parseInfo); 74 | } 75 | dispose() { 76 | EmbeddedViewPanel.currentPanel = undefined; 77 | // Clean up our resources 78 | this._htmlPanel.dispose(); 79 | this._treePanel.dispose(); 80 | while (this._disposables.length) { 81 | const x = this._disposables.pop(); 82 | if (x) { 83 | x.dispose(); 84 | } 85 | } 86 | } 87 | async _update() { 88 | let rawReactData = await this._page.scrape(); 89 | // Build out TreeNode class for React D3 Tree. 90 | function buildTree(rawReactData) { 91 | let tree = new TreeNode_1.default(rawReactData[0]); 92 | const freeNodes = []; 93 | rawReactData.forEach((el) => { 94 | const parentNode = tree._find(tree, el.parentId); 95 | if (parentNode) { 96 | parentNode._add(el); 97 | } 98 | else { 99 | freeNodes.push(el); 100 | } 101 | }); 102 | while (freeNodes.length > 0) { 103 | const curEl = freeNodes.shift(); 104 | if (curEl) { 105 | const parentNode = tree._find(tree, curEl.parentId); 106 | if (parentNode) { 107 | parentNode._add(curEl); 108 | } 109 | } 110 | } 111 | return tree; 112 | } 113 | const treeData = await buildTree(rawReactData); 114 | this._treePanel.webview.html = this._getHtmlForWebview(treeData); 115 | } 116 | // Putting scraped meta-data to D3 tree diagram 117 | _getHtmlForWebview(treeData) { 118 | const stringifiedFlatData = JSON.stringify(treeData); 119 | return TreeViewPanel_1.default.generateD3(stringifiedFlatData, this._parseInfo); 120 | } 121 | _getPreviewHtmlForWebview() { 122 | return htmlViewPanel_1.default.html; 123 | } 124 | } 125 | EmbeddedViewPanel.viewType = 'ReactION'; 126 | exports.default = EmbeddedViewPanel; 127 | //# sourceMappingURL=EmbeddedViewPanel.js.map -------------------------------------------------------------------------------- /out/src/EmbeddedViewPanel.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"EmbeddedViewPanel.js","sourceRoot":"","sources":["../../src/EmbeddedViewPanel.ts"],"names":[],"mappings":"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"} -------------------------------------------------------------------------------- /out/src/TreeNode.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | class TreeNode { 4 | constructor(node) { 5 | this.name = node.name; 6 | this.id = node.id; 7 | this.attributes = node.props; 8 | this.parentId = node.parentId; 9 | this.display = node.display; 10 | this.children = []; 11 | } 12 | // Add new node to the tree 13 | _add(node) { 14 | const newNode = new TreeNode(node); 15 | this.children.push(newNode); 16 | } 17 | // Search if there is a node with matching id. 18 | _find(root, parentId) { 19 | let curNode = root; 20 | if (curNode.id === parentId) { 21 | return curNode; 22 | } 23 | if (curNode.children.length !== 0) { 24 | for (let el of curNode.children) { 25 | const findParent = this._find(el, parentId); 26 | if (findParent) { 27 | return findParent; 28 | } 29 | } 30 | } 31 | return false; 32 | } 33 | } 34 | exports.default = TreeNode; 35 | //# sourceMappingURL=TreeNode.js.map -------------------------------------------------------------------------------- /out/src/TreeNode.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"TreeNode.js","sourceRoot":"","sources":["../../src/TreeNode.ts"],"names":[],"mappings":";;AAAA,MAAqB,QAAQ;IAQ5B,YAAmB,IAAS;QAC3B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;QACtB,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC;QAClB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC;QAC7B,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC9B,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;QAC5B,IAAI,CAAC,QAAQ,GAAG,EAAE,CAAC;IACpB,CAAC;IAED,2BAA2B;IACpB,IAAI,CAAC,IAAS;QACpB,MAAM,OAAO,GAAG,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC;QACnC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC7B,CAAC;IAED,8CAA8C;IACvC,KAAK,CAAC,IAAS,EAAE,QAAa;QACpC,IAAI,OAAO,GAAG,IAAI,CAAC;QACnB,IAAI,OAAO,CAAC,EAAE,KAAK,QAAQ,EAAE,CAAC;YAC7B,OAAO,OAAO,CAAC;QAChB,CAAC;QACD,IAAI,OAAO,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACnC,KAAK,IAAI,EAAE,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;gBACjC,MAAM,UAAU,GAAQ,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC;gBACjD,IAAI,UAAU,EAAE,CAAC;oBAChB,OAAO,UAAU,CAAC;gBACnB,CAAC;YACF,CAAC;QACF,CAAC;QACD,OAAO,KAAK,CAAC;IACd,CAAC;CACD;AAvCD,2BAuCC"} -------------------------------------------------------------------------------- /out/src/TreeViewPanel.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { 3 | if (k2 === undefined) k2 = k; 4 | var desc = Object.getOwnPropertyDescriptor(m, k); 5 | if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { 6 | desc = { enumerable: true, get: function() { return m[k]; } }; 7 | } 8 | Object.defineProperty(o, k2, desc); 9 | }) : (function(o, m, k, k2) { 10 | if (k2 === undefined) k2 = k; 11 | o[k2] = m[k]; 12 | })); 13 | var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { 14 | Object.defineProperty(o, "default", { enumerable: true, value: v }); 15 | }) : function(o, v) { 16 | o["default"] = v; 17 | }); 18 | var __importStar = (this && this.__importStar) || function (mod) { 19 | if (mod && mod.__esModule) return mod; 20 | var result = {}; 21 | if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); 22 | __setModuleDefault(result, mod); 23 | return result; 24 | }; 25 | Object.defineProperty(exports, "__esModule", { value: true }); 26 | const vscode = __importStar(require("vscode")); 27 | const path = __importStar(require("path")); 28 | exports.default = { 29 | generateD3: function (stringifiedTreeData, parseInfo) { 30 | const bundle = vscode.Uri.file(path.join(__dirname, 'build', 'bundle.js')); 31 | const bundleUri = bundle.with({ 32 | scheme: 'vscode-resource' 33 | }); 34 | console.log(stringifiedTreeData); 35 | return ` 36 | 37 | 38 | 39 | 40 | 41 | Tree Example 42 | 46 | 47 | 48 |
49 | 50 | 51 | 52 | `; 53 | } 54 | }; 55 | //# sourceMappingURL=TreeViewPanel.js.map -------------------------------------------------------------------------------- /out/src/TreeViewPanel.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"TreeViewPanel.js","sourceRoot":"","sources":["../../src/TreeViewPanel.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAAA,+CAAiC;AACjC,2CAA6B;AAE7B,kBAAe;IACd,UAAU,EACT,UAAU,mBAA2B,EAAE,SAAc;QACpD,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,EAAE,WAAW,CAAC,CAAC,CAAC;QAC3E,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC;YAC7B,MAAM,EAAE,iBAAiB;SACzB,CAAC,CAAC;QAEH,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAA;QAEhC,OAAO;;;;;;;;2BAQiB,mBAAmB;0BACpB,SAAS;;;;;mBAKhB,SAAS;;;GAGzB,CAAC;IACF,CAAC;CACF,CAAA"} -------------------------------------------------------------------------------- /out/src/ViewPanel.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { 3 | if (k2 === undefined) k2 = k; 4 | var desc = Object.getOwnPropertyDescriptor(m, k); 5 | if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { 6 | desc = { enumerable: true, get: function() { return m[k]; } }; 7 | } 8 | Object.defineProperty(o, k2, desc); 9 | }) : (function(o, m, k, k2) { 10 | if (k2 === undefined) k2 = k; 11 | o[k2] = m[k]; 12 | })); 13 | var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { 14 | Object.defineProperty(o, "default", { enumerable: true, value: v }); 15 | }) : function(o, v) { 16 | o["default"] = v; 17 | }); 18 | var __importStar = (this && this.__importStar) || function (mod) { 19 | if (mod && mod.__esModule) return mod; 20 | var result = {}; 21 | if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); 22 | __setModuleDefault(result, mod); 23 | return result; 24 | }; 25 | var __importDefault = (this && this.__importDefault) || function (mod) { 26 | return (mod && mod.__esModule) ? mod : { "default": mod }; 27 | }; 28 | Object.defineProperty(exports, "__esModule", { value: true }); 29 | const vscode = __importStar(require("vscode")); 30 | const TreeViewPanel_1 = __importDefault(require("./TreeViewPanel")); 31 | const puppeteer_1 = __importDefault(require("./puppeteer")); 32 | const TreeNode_1 = __importDefault(require("./TreeNode")); 33 | class ViewPanel { 34 | // Constructor for tree view and html panel 35 | constructor(treePanel, parseInfo) { 36 | this._disposables = []; 37 | this._treePanel = treePanel; 38 | this._parseInfo = parseInfo; 39 | // Running Puppeteer to access React page context 40 | this._page = new puppeteer_1.default(parseInfo); 41 | this._page.start(); 42 | setInterval(() => { 43 | this._update(); 44 | }, 1000); 45 | this._treePanel.onDidDispose(() => this.dispose(), null, this._disposables); 46 | } 47 | static createOrShow(extensionPath, parseInfo) { 48 | const treeColumn = vscode.ViewColumn.Two; 49 | if (ViewPanel.currentPanel) { 50 | ViewPanel.currentPanel._treePanel.reveal(treeColumn); 51 | return; 52 | } 53 | // Show Virtual DOM Tree in VS Code 54 | const treePanel = vscode.window.createWebviewPanel(ViewPanel.viewType, "Virtual DOM Tree", treeColumn, { 55 | // Enable javascript in the webview 56 | enableScripts: true, 57 | retainContextWhenHidden: true, 58 | enableCommandUris: true 59 | }); 60 | ViewPanel.currentPanel = new ViewPanel(treePanel, parseInfo); 61 | } 62 | dispose() { 63 | ViewPanel.currentPanel = undefined; 64 | // Clean up our resources 65 | this._treePanel.dispose(); 66 | while (this._disposables.length) { 67 | const x = this._disposables.pop(); 68 | if (x) { 69 | x.dispose(); 70 | } 71 | } 72 | } 73 | async _update() { 74 | let rawReactData = await this._page.scrape(); 75 | // Build out TreeNode class for React D3 Tree. 76 | function buildTree(rawReactData) { 77 | let tree = new TreeNode_1.default(rawReactData[0]); 78 | const freeNodes = []; 79 | rawReactData.forEach((el) => { 80 | const parentNode = tree._find(tree, el.parentId); 81 | if (parentNode) { 82 | parentNode._add(el); 83 | } 84 | else { 85 | freeNodes.push(el); 86 | } 87 | }); 88 | while (freeNodes.length > 0) { 89 | const curEl = freeNodes[0]; 90 | const parentNode = tree._find(tree, curEl.parentId); 91 | if (parentNode) { 92 | parentNode._add(curEl); 93 | } 94 | freeNodes.shift(); 95 | } 96 | return tree; 97 | } 98 | const treeData = await buildTree(rawReactData); 99 | this._treePanel.webview.html = this._getHtmlForWebview(treeData); 100 | } 101 | // Putting scraped meta-data to D3 tree diagram 102 | _getHtmlForWebview(treeData) { 103 | const stringifiedFlatData = JSON.stringify(treeData); 104 | return TreeViewPanel_1.default.generateD3(stringifiedFlatData, this._parseInfo); 105 | } 106 | } 107 | ViewPanel.viewType = 'ReactION'; 108 | exports.default = ViewPanel; 109 | //# sourceMappingURL=ViewPanel.js.map -------------------------------------------------------------------------------- /out/src/ViewPanel.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"ViewPanel.js","sourceRoot":"","sources":["../../src/ViewPanel.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,+CAAiC;AACjC,oEAAuC;AACvC,4DAAoC;AACpC,0DAAkC;AAElC,MAAqB,SAAS;IAS7B,2CAA2C;IAC3C,YACC,SAA8B,EAC9B,SAAc;QAPP,iBAAY,GAAwB,EAAE,CAAC;QAS9C,IAAI,CAAC,UAAU,GAAG,SAAS,CAAC;QAC5B,IAAI,CAAC,UAAU,GAAG,SAAS,CAAC;QAE5B,iDAAiD;QACjD,IAAI,CAAC,KAAK,GAAG,IAAI,mBAAS,CAAC,SAAS,CAAC,CAAC;QACtC,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QACnB,WAAW,CAAC,GAAG,EAAE;YAChB,IAAI,CAAC,OAAO,EAAE,CAAC;QAChB,CAAC,EAAE,IAAI,CAAC,CAAC;QACT,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;IAC7E,CAAC;IAGM,MAAM,CAAC,YAAY,CAAC,aAAqB,EAAE,SAAc;QAC/D,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC;QACzC,IAAI,SAAS,CAAC,YAAY,EAAE,CAAC;YAC5B,SAAS,CAAC,YAAY,CAAC,UAAU,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;YACrD,OAAO;QACR,CAAC;QAED,mCAAmC;QACnC,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,kBAAkB,CAAC,SAAS,CAAC,QAAQ,EAAE,kBAAkB,EAAE,UAAU,EAAE;YAEtG,mCAAmC;YACnC,aAAa,EAAE,IAAI;YACnB,uBAAuB,EAAE,IAAI;YAC7B,iBAAiB,EAAE,IAAI;SACvB,CAAC,CAAC;QAEH,SAAS,CAAC,YAAY,GAAG,IAAI,SAAS,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;IAC9D,CAAC;IAEM,OAAO;QACb,SAAS,CAAC,YAAY,GAAG,SAAS,CAAC;QAEnC,yBAAyB;QACzB,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC;QAE1B,OAAO,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,CAAC;YACjC,MAAM,CAAC,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,EAAE,CAAC;YAClC,IAAI,CAAC,EAAE,CAAC;gBACP,CAAC,CAAC,OAAO,EAAE,CAAC;YACb,CAAC;QACF,CAAC;IACF,CAAC;IAEO,KAAK,CAAC,OAAO;QACpB,IAAI,YAAY,GAAkB,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;QAE5D,8CAA8C;QAC9C,SAAS,SAAS,CAAC,YAA2B;YAC7C,IAAI,IAAI,GAAa,IAAI,kBAAQ,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;YACnD,MAAM,SAAS,GAAQ,EAAE,CAAC;YAE1B,YAAY,CAAC,OAAO,CAAC,CAAC,EAAO,EAAE,EAAE;gBAChC,MAAM,UAAU,GAAa,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC;gBAC3D,IAAI,UAAU,EAAE,CAAC;oBAChB,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;gBACrB,CAAC;qBAAM,CAAC;oBACP,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;gBACpB,CAAC;YACF,CAAC,CAAC,CAAC;YAEH,OAAO,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC7B,MAAM,KAAK,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;gBAC3B,MAAM,UAAU,GAAa,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC;gBAC9D,IAAI,UAAU,EAAE,CAAC;oBAChB,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBACxB,CAAC;gBACD,SAAS,CAAC,KAAK,EAAE,CAAC;YACnB,CAAC;YACD,OAAO,IAAI,CAAC;QACb,CAAC;QACD,MAAM,QAAQ,GAAa,MAAM,SAAS,CAAC,YAAY,CAAC,CAAC;QACzD,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,kBAAkB,CAAC,QAAQ,CAAC,CAAC;IAClE,CAAC;IAED,+CAA+C;IACvC,kBAAkB,CAAC,QAAkB;QAC5C,MAAM,mBAAmB,GAAW,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;QAC7D,OAAO,uBAAQ,CAAC,UAAU,CAAC,mBAAmB,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;IAClE,CAAC;;AA5FsB,kBAAQ,GAAG,UAAU,AAAb,CAAc;kBAHzB,SAAS"} -------------------------------------------------------------------------------- /out/src/extension.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { 3 | if (k2 === undefined) k2 = k; 4 | var desc = Object.getOwnPropertyDescriptor(m, k); 5 | if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { 6 | desc = { enumerable: true, get: function() { return m[k]; } }; 7 | } 8 | Object.defineProperty(o, k2, desc); 9 | }) : (function(o, m, k, k2) { 10 | if (k2 === undefined) k2 = k; 11 | o[k2] = m[k]; 12 | })); 13 | var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { 14 | Object.defineProperty(o, "default", { enumerable: true, value: v }); 15 | }) : function(o, v) { 16 | o["default"] = v; 17 | }); 18 | var __importStar = (this && this.__importStar) || function (mod) { 19 | if (mod && mod.__esModule) return mod; 20 | var result = {}; 21 | if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); 22 | __setModuleDefault(result, mod); 23 | return result; 24 | }; 25 | var __importDefault = (this && this.__importDefault) || function (mod) { 26 | return (mod && mod.__esModule) ? mod : { "default": mod }; 27 | }; 28 | Object.defineProperty(exports, "__esModule", { value: true }); 29 | exports.activate = activate; 30 | exports.deactivate = deactivate; 31 | const vscode = __importStar(require("vscode")); 32 | const startExtensionProvider_1 = __importDefault(require("./startExtensionProvider")); 33 | const EmbeddedViewPanel_1 = __importDefault(require("./EmbeddedViewPanel")); 34 | const ViewPanel_1 = __importDefault(require("./ViewPanel")); 35 | const fs = require('fs'); 36 | const path = require('path'); 37 | let parseInfo; 38 | let subscriptions = []; 39 | // Method called when extension is activated 40 | function activate(context) { 41 | const workspaceFolders = vscode.workspace.workspaceFolders; 42 | if (!workspaceFolders) { 43 | vscode.window.showErrorMessage("No workspace is opened. Please open a workspace and try again."); 44 | return; 45 | } 46 | const rootPath = workspaceFolders[0].uri.fsPath; 47 | const configPath = path.join(rootPath, "reactION-config.json"); 48 | const setup = {}; 49 | setup.system = process.platform; 50 | // Setting the executable path on config file based on user's OS. 51 | switch (setup.system) { 52 | // For iOS environment. 53 | case 'darwin': 54 | setup.executablePath = '/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome'; 55 | break; 56 | // For Linux environment. 57 | case 'linux': 58 | setup.executablePath = ''; 59 | vscode.window.showInformationMessage('Please specify your Chrominum executablePath in reactION.config.json file created in your local directory.'); 60 | break; 61 | // For Window 10 environment. 62 | case 'win32': 63 | setup.executablePath = 'C:\Program Files (x86)\Google\Chrome\Application\chrome.exe'; 64 | break; 65 | default: 66 | vscode.window.showInformationMessage('Current Operating System is not supported.'); 67 | } 68 | setup.localhost = 'localhost:3000'; 69 | setup.headless_browser = false; 70 | setup.headless_embedded = true; 71 | setup.reactTheme = 'dark'; 72 | fs.stat(configPath, (err, stats) => { 73 | if (err) { 74 | console.log(err); 75 | } 76 | if (!stats) { 77 | fs.writeFileSync(configPath, JSON.stringify(setup, null, '\t')); 78 | } 79 | else { 80 | // else read off and apply config to the running instance 81 | parseInfo = JSON.parse(fs.readFileSync(configPath)); 82 | } 83 | }); 84 | subscriptions.push(vscode.commands.registerCommand('ReactION.openTree', () => { 85 | ViewPanel_1.default.createOrShow(context.extensionPath, parseInfo); 86 | })); 87 | subscriptions.push(vscode.commands.registerCommand('ReactION.openWeb', () => { 88 | EmbeddedViewPanel_1.default.createOrShow(context.extensionPath, parseInfo); 89 | })); 90 | vscode.window.registerTreeDataProvider('startExtension', new startExtensionProvider_1.default()); 91 | context.subscriptions.push(...subscriptions); 92 | } 93 | // This method is called when your extension is deactivated 94 | function deactivate() { 95 | // Dispose of subscriptions 96 | subscriptions.forEach(subscription => subscription.dispose()); 97 | subscriptions = []; 98 | console.log("Extension has been deactivated"); 99 | } 100 | //# sourceMappingURL=extension.js.map -------------------------------------------------------------------------------- /out/src/extension.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"extension.js","sourceRoot":"","sources":["../../src/extension.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAWA,4BAiEC;AAGD,gCAKC;AApFD,+CAAiC;AACjC,sFAA8D;AAC9D,4EAAoD;AACpD,4DAAoC;AACpC,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AACzB,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;AAE7B,IAAI,SAAa,CAAC;AAClB,IAAI,aAAa,GAA8B,EAAE,CAAC;AAElD,4CAA4C;AAC5C,SAAgB,QAAQ,CAAC,OAAgC;IACxD,MAAM,gBAAgB,GAAG,MAAM,CAAC,SAAS,CAAC,gBAAgB,CAAC;IAC3D,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACvB,MAAM,CAAC,MAAM,CAAC,gBAAgB,CAAC,gEAAgE,CAAC,CAAC;QACjG,OAAO;IACR,CAAC;IAED,MAAM,QAAQ,GAAG,gBAAgB,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC;IAChD,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,sBAAsB,CAAC,CAAC;IAC/D,MAAM,KAAK,GAAQ,EAAE,CAAC;IAEtB,KAAK,CAAC,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;IAEhC,iEAAiE;IACjE,QAAO,KAAK,CAAC,MAAM,EAAE,CAAC;QAErB,uBAAuB;QACvB,KAAK,QAAQ;YACZ,KAAK,CAAC,cAAc,GAAG,gEAAgE,CAAC;YACxF,MAAM;QAEP,yBAAyB;QACzB,KAAK,OAAO;YACX,KAAK,CAAC,cAAc,GAAG,EAAE,CAAC;YAC1B,MAAM,CAAC,MAAM,CAAC,sBAAsB,CAAC,4GAA4G,CAAC,CAAC;YACnJ,MAAM;QAEP,6BAA6B;QAC7B,KAAK,OAAO;YACX,KAAK,CAAC,cAAc,GAAG,6DAA6D,CAAC;YACrF,MAAM;QACP;YACC,MAAM,CAAC,MAAM,CAAC,sBAAsB,CAAC,4CAA4C,CAAC,CAAC;IACrF,CAAC;IACD,KAAK,CAAC,SAAS,GAAG,gBAAgB,CAAC;IACnC,KAAK,CAAC,gBAAgB,GAAG,KAAK,CAAC;IAC/B,KAAK,CAAC,iBAAiB,GAAG,IAAI,CAAC;IAC/B,KAAK,CAAC,UAAU,GAAG,MAAM,CAAC;IAE1B,EAAE,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,GAAQ,EAAE,KAAU,EAAE,EAAE;QAC5C,IAAI,GAAG,EAAE,CAAC;YACT,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAClB,CAAC;QACD,IAAI,CAAC,KAAK,EAAE,CAAC;YACZ,EAAE,CAAC,aAAa,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;QACjE,CAAC;aACI,CAAC;YACL,yDAAyD;YACzD,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC;QAErD,CAAC;IACF,CAAC,CAAC,CAAC;IAGH,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,eAAe,CAAC,mBAAmB,EAAE,GAAG,EAAE;QAC5E,mBAAS,CAAC,YAAY,CAAC,OAAO,CAAC,aAAa,EAAE,SAAS,CAAC,CAAC;IAC1D,CAAC,CAAC,CAAC,CAAC;IAEJ,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,eAAe,CAAC,kBAAkB,EAAE,GAAG,EAAE;QAC3E,2BAAiB,CAAC,YAAY,CAAC,OAAO,CAAC,aAAa,EAAE,SAAS,CAAC,CAAC;IAClE,CAAC,CAAC,CAAC,CAAC;IAEJ,MAAM,CAAC,MAAM,CAAC,wBAAwB,CAAC,gBAAgB,EAAE,IAAI,gCAAsB,EAAE,CAAC,CAAC;IAEvF,OAAO,CAAC,aAAa,CAAC,IAAI,CAAC,GAAG,aAAa,CAAC,CAAC;AAC9C,CAAC;AAED,2DAA2D;AAC3D,SAAgB,UAAU;IACtB,2BAA2B;IAC3B,aAAa,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,CAAC,CAAC;IAC9D,aAAa,GAAG,EAAE,CAAC;IACnB,OAAO,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAC;AAClD,CAAC"} -------------------------------------------------------------------------------- /out/src/htmlViewPanel.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | exports.default = { 4 | html: ` 5 | 17 | 18 | 19 | ` 20 | }; 21 | //# sourceMappingURL=htmlViewPanel.js.map -------------------------------------------------------------------------------- /out/src/htmlViewPanel.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"htmlViewPanel.js","sourceRoot":"","sources":["../../src/htmlViewPanel.ts"],"names":[],"mappings":";;AAAA,kBAAe;IACd,IAAI,EACL;;;;;;;;;;;;;;;CAeC;CACA,CAAC"} -------------------------------------------------------------------------------- /out/src/puppeteer.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | const puppeteer = require('puppeteer-core'); 4 | class Puppeteer { 5 | // Default properties for the Puppeteer class. 6 | constructor(parseInfo) { 7 | this._headless = false; 8 | this._executablePath = parseInfo.executablePath; 9 | this._pipe = true; 10 | this._url = parseInfo.localhost; 11 | this._page = ''; 12 | this._browser = ''; 13 | } 14 | // Creates an instance of puppeteer browser and page, 15 | // opens to _url, defaults to localhost:3000 16 | async start() { 17 | this._browser = await puppeteer.launch({ 18 | headless: this._headless, 19 | executablePath: this._executablePath, 20 | pipe: this._pipe, 21 | }).catch((err) => console.log(err)); 22 | this._page = await this._browser.pages() 23 | .then((pageArr) => { 24 | return pageArr[0]; 25 | }); 26 | this._page.goto(this._url); 27 | return await this._page; 28 | } 29 | // Recursive React component scraping algorithm 30 | scrape() { 31 | // All code inside .evaluate is executed in the pages context 32 | const reactData = this._page.evaluate(async () => { 33 | // Access the React Dom 34 | // & create entry point for fiber node through DOM element 35 | const _entry = (() => { 36 | // @ts-ignore 37 | const domElements = document.querySelector('body').children; 38 | for (let el of domElements) { 39 | // @ts-ignore 40 | if (el._reactRootContainer) { 41 | // @ts-ignore 42 | return el._reactRootContainer._internalRoot.current; 43 | } 44 | } 45 | })(); 46 | // Define function that traverses the fiber tree, starting from the entry point 47 | function fiberWalk(entry) { 48 | let dataArr = [], globalId = 1; 49 | // Recursively traversing through the fiber tree, pushing the node object into the dataArr array 50 | function traverse(root, level, parentId) { 51 | if (root.sibling !== null) { 52 | globalId += 1; 53 | dataArr.push({ 54 | "name": root.sibling, 55 | "level": `${level}`, 56 | "id": `${globalId}`, 57 | "parentId": `${parentId}`, 58 | "props": Object.keys(root.sibling.memoizedProps) 59 | }); 60 | traverse(root.sibling, level, parentId); 61 | } 62 | if (root.child !== null) { 63 | parentId += 1; 64 | globalId += 1; 65 | dataArr.push({ 66 | "name": root.child, 67 | "level": `${level}`, 68 | "id": `${globalId}`, 69 | "parentId": `${parentId}`, 70 | "display": "none", 71 | "props": Object.keys(root.child.memoizedProps) 72 | }); 73 | traverse(root.child, level + 1, parentId); 74 | } 75 | } 76 | traverse(entry, 0, 0); 77 | // Extracts the type name of each fiber node 78 | dataArr.forEach((el) => { 79 | if (typeof el.name.type === null) { 80 | el.name = ''; 81 | } 82 | else if (typeof el.name.type === 'function' && el.name.type.name) { 83 | el.name = el.name.type.name; 84 | } 85 | else if (typeof el.name.type === 'function') { 86 | el.name = 'function'; 87 | } 88 | else if (typeof el.name.type === 'object') { 89 | el.name = 'function'; 90 | } 91 | else if (typeof el.name.type === 'string') { 92 | el.name = el.name.type; 93 | } 94 | }); 95 | // Setting root parent to an empty string 96 | dataArr[0].parentId = ''; 97 | return dataArr; 98 | } 99 | return fiberWalk(_entry); 100 | }).catch((err) => { console.log(err); }); 101 | return reactData; 102 | } 103 | } 104 | exports.default = Puppeteer; 105 | //# sourceMappingURL=puppeteer.js.map -------------------------------------------------------------------------------- /out/src/puppeteer.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"puppeteer.js","sourceRoot":"","sources":["../../src/puppeteer.ts"],"names":[],"mappings":"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"} -------------------------------------------------------------------------------- /out/src/startExtensionProvider.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { 3 | if (k2 === undefined) k2 = k; 4 | var desc = Object.getOwnPropertyDescriptor(m, k); 5 | if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { 6 | desc = { enumerable: true, get: function() { return m[k]; } }; 7 | } 8 | Object.defineProperty(o, k2, desc); 9 | }) : (function(o, m, k, k2) { 10 | if (k2 === undefined) k2 = k; 11 | o[k2] = m[k]; 12 | })); 13 | var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { 14 | Object.defineProperty(o, "default", { enumerable: true, value: v }); 15 | }) : function(o, v) { 16 | o["default"] = v; 17 | }); 18 | var __importStar = (this && this.__importStar) || function (mod) { 19 | if (mod && mod.__esModule) return mod; 20 | var result = {}; 21 | if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); 22 | __setModuleDefault(result, mod); 23 | return result; 24 | }; 25 | Object.defineProperty(exports, "__esModule", { value: true }); 26 | const vscode = __importStar(require("vscode")); 27 | class StartExtensionProvider { 28 | constructor() { 29 | this._onDidChangeTreeData = new vscode.EventEmitter(); 30 | this.onDidChangeTreeData = this._onDidChangeTreeData.event; 31 | } 32 | refresh() { 33 | this._onDidChangeTreeData.fire(); 34 | this._onDidChangeTreeData.dispose(); 35 | } 36 | getTreeItem(element) { 37 | return element; 38 | } 39 | getChildren(element) { 40 | vscode.commands.executeCommand('ReactION.openTree'); 41 | vscode.commands.executeCommand('workbench.view.explorer'); 42 | this._onDidChangeTreeData.fire(); 43 | this._onDidChangeTreeData.dispose(); 44 | return Promise.reject([]); 45 | } 46 | } 47 | exports.default = StartExtensionProvider; 48 | //# sourceMappingURL=startExtensionProvider.js.map -------------------------------------------------------------------------------- /out/src/startExtensionProvider.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"startExtensionProvider.js","sourceRoot":"","sources":["../../src/startExtensionProvider.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAAA,+CAAiC;AAEjC,MAAqB,sBAAsB;IAIzC;QAHQ,yBAAoB,GAA4C,IAAI,MAAM,CAAC,YAAY,EAAsB,CAAC;QAC7G,wBAAmB,GAAqC,IAAI,CAAC,oBAAoB,CAAC,KAAK,CAAC;IAElF,CAAC;IAEhB,OAAO;QACL,IAAI,CAAC,oBAAoB,CAAC,IAAI,EAAE,CAAA;QAChC,IAAI,CAAC,oBAAoB,CAAC,OAAO,EAAE,CAAC;IACtC,CAAC;IAED,WAAW,CAAC,OAAe;QACzB,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,WAAW,CAAC,OAAgB;QAC1B,MAAM,CAAC,QAAQ,CAAC,cAAc,CAAC,mBAAmB,CAAC,CAAC;QACpD,MAAM,CAAC,QAAQ,CAAC,cAAc,CAAC,yBAAyB,CAAC,CAAC;QAE1D,IAAI,CAAC,oBAAoB,CAAC,IAAI,EAAE,CAAC;QACjC,IAAI,CAAC,oBAAoB,CAAC,OAAO,EAAE,CAAC;QACpC,OAAO,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IAC5B,CAAC;CACF;AAvBD,yCAuBC"} -------------------------------------------------------------------------------- /out/src/test/TreeView.test.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __importDefault = (this && this.__importDefault) || function (mod) { 3 | return (mod && mod.__esModule) ? mod : { "default": mod }; 4 | }; 5 | Object.defineProperty(exports, "__esModule", { value: true }); 6 | const puppeteer_1 = __importDefault(require("puppeteer")); 7 | const chai_1 = require("chai"); 8 | // Puppeteer options 9 | const opts = { 10 | headless: false, 11 | slowMo: 100, 12 | defaultViewport: null, 13 | args: ['--no-sandbox', '--disable-setuid-sandbox'], 14 | }; 15 | describe('sample test', function () { 16 | let browser; 17 | let page; 18 | // Setup before running the tests 19 | before(async function () { 20 | browser = await puppeteer_1.default.launch(opts); 21 | page = await browser.newPage(); 22 | await page.goto('http://localhost:3000'); 23 | }); 24 | // Cleanup after running the tests 25 | after(async function () { 26 | if (page) { 27 | await page.close(); 28 | } 29 | if (browser) { 30 | await browser.close(); 31 | } 32 | }); 33 | it('Should have the correct page title', async function () { 34 | const title = await page.title(); 35 | (0, chai_1.expect)(title).to.eql('Tree Example'); 36 | }); 37 | it('should have a single content section', async function () { 38 | const TREE_SELECTOR = '.treeChart'; 39 | await page.waitForSelector(TREE_SELECTOR); 40 | const elements = await page.$$(TREE_SELECTOR); 41 | (0, chai_1.expect)(elements).to.have.lengthOf(1); 42 | }); 43 | }); 44 | //# sourceMappingURL=TreeView.test.js.map -------------------------------------------------------------------------------- /out/src/test/TreeView.test.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"TreeView.test.js","sourceRoot":"","sources":["../../../src/test/TreeView.test.ts"],"names":[],"mappings":";;;;;AAAA,0DAA6E;AAC7E,+BAA4C;AAE5C,oBAAoB;AACpB,MAAM,IAAI,GAA2B;IACnC,QAAQ,EAAE,KAAK;IACf,MAAM,EAAE,GAAG;IACX,eAAe,EAAE,IAAI;IACrB,IAAI,EAAE,CAAC,cAAc,EAAE,0BAA0B,CAAC;CACnD,CAAC;AAEF,QAAQ,CAAC,aAAa,EAAE;IACtB,IAAI,OAAgB,CAAC;IACrB,IAAI,IAAU,CAAC;IAEf,iCAAiC;IACjC,MAAM,CAAC,KAAK;QACV,OAAO,GAAG,MAAM,mBAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACvC,IAAI,GAAG,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC;QAC/B,MAAM,IAAI,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;IAC3C,CAAC,CAAC,CAAC;IAEH,kCAAkC;IAClC,KAAK,CAAC,KAAK;QACT,IAAI,IAAI,EAAE,CAAC;YACT,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC;QACrB,CAAC;QACD,IAAI,OAAO,EAAE,CAAC;YACZ,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;QACxB,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oCAAoC,EAAE,KAAK;QAC5C,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC;QACjC,IAAA,aAAU,EAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAC3C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sCAAsC,EAAE,KAAK;QAC9C,MAAM,aAAa,GAAG,YAAY,CAAC;QAEnC,MAAM,IAAI,CAAC,eAAe,CAAC,aAAa,CAAC,CAAC;QAE1C,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC;QAC9C,IAAA,aAAU,EAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IAC3C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"} -------------------------------------------------------------------------------- /out/src/test/extension.test.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { 3 | if (k2 === undefined) k2 = k; 4 | var desc = Object.getOwnPropertyDescriptor(m, k); 5 | if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { 6 | desc = { enumerable: true, get: function() { return m[k]; } }; 7 | } 8 | Object.defineProperty(o, k2, desc); 9 | }) : (function(o, m, k, k2) { 10 | if (k2 === undefined) k2 = k; 11 | o[k2] = m[k]; 12 | })); 13 | var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { 14 | Object.defineProperty(o, "default", { enumerable: true, value: v }); 15 | }) : function(o, v) { 16 | o["default"] = v; 17 | }); 18 | var __importStar = (this && this.__importStar) || function (mod) { 19 | if (mod && mod.__esModule) return mod; 20 | var result = {}; 21 | if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); 22 | __setModuleDefault(result, mod); 23 | return result; 24 | }; 25 | Object.defineProperty(exports, "__esModule", { value: true }); 26 | // The module 'assert' provides assertion methods from node 27 | const vscode = __importStar(require("vscode")); 28 | const assert = __importStar(require("assert")); 29 | // You can import and use all API from the 'vscode' module 30 | // as well as import your extension to test it 31 | // import * as vscode from 'vscode'; 32 | const treeColumn = vscode.ViewColumn.Two; 33 | // Show Virtual DOM Tree in VS Code 34 | // const treePanel: any = vscode.window.createWebviewPanel(ViewPanel.viewType, "Virtual DOM Tree", treeColumn, { 35 | // // Enable javascript in the webview 36 | // enableScripts: true, 37 | // retainContextWhenHidden: true, 38 | // enableCommandUris: true 39 | // }); 40 | // Defines a Mocha test suite to group tests of similar kind together 41 | suite("Extension Tests", function () { 42 | // Defines a Mocha unit test 43 | test("Extension Running", function () { 44 | assert.equal(2, 1 + 1); 45 | }); 46 | }); 47 | //# sourceMappingURL=extension.test.js.map -------------------------------------------------------------------------------- /out/src/test/extension.test.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"extension.test.js","sourceRoot":"","sources":["../../../src/test/extension.test.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AACA,2DAA2D;AAC3D,+CAAiC;AACjC,+CAAiC;AAEjC,0DAA0D;AAC1D,8CAA8C;AAC9C,oCAAoC;AAEpC,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC;AACzC,mCAAmC;AACnC,gHAAgH;AAEhH,0CAA0C;AAC1C,2BAA2B;AAC3B,qCAAqC;AACrC,8BAA8B;AAC9B,MAAM;AAEN,qEAAqE;AACrE,KAAK,CAAC,iBAAiB,EAAE;IAErB,4BAA4B;IAC5B,IAAI,CAAC,mBAAmB,EAAE;QACtB,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC3B,CAAC,CAAC,CAAC;AACP,CAAC,CAAC,CAAC"} -------------------------------------------------------------------------------- /out/src/test/index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | // 3 | // PLEASE DO NOT MODIFY / DELETE UNLESS YOU KNOW WHAT YOU ARE DOING 4 | // 5 | // This file is providing the test runner to use when running extension tests. 6 | // By default the test runner in use is Mocha based. 7 | // 8 | // You can provide your own test runner if you want to override it by exporting 9 | // a function run(testRoot: string, clb: (error:Error) => void) that the extension 10 | // host can call to run the tests. The test runner is expected to use console.log 11 | // to report the results back to the caller. When the tests are finished, return 12 | // a possible error to the callback or null if none. 13 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { 14 | if (k2 === undefined) k2 = k; 15 | var desc = Object.getOwnPropertyDescriptor(m, k); 16 | if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { 17 | desc = { enumerable: true, get: function() { return m[k]; } }; 18 | } 19 | Object.defineProperty(o, k2, desc); 20 | }) : (function(o, m, k, k2) { 21 | if (k2 === undefined) k2 = k; 22 | o[k2] = m[k]; 23 | })); 24 | var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { 25 | Object.defineProperty(o, "default", { enumerable: true, value: v }); 26 | }) : function(o, v) { 27 | o["default"] = v; 28 | }); 29 | var __importStar = (this && this.__importStar) || function (mod) { 30 | if (mod && mod.__esModule) return mod; 31 | var result = {}; 32 | if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); 33 | __setModuleDefault(result, mod); 34 | return result; 35 | }; 36 | Object.defineProperty(exports, "__esModule", { value: true }); 37 | const testRunner = __importStar(require("vscode/lib/testrunner")); 38 | // You can directly control Mocha options by configuring the test runner below 39 | // See https://github.com/mochajs/mocha/wiki/Using-mocha-programmatically#set-options 40 | // for more info 41 | testRunner.configure({ 42 | ui: 'tdd', // the TDD UI is being used in extension.test.ts (suite, test, etc.) 43 | useColors: true // colored output from test results 44 | }); 45 | module.exports = testRunner; 46 | //# sourceMappingURL=index.js.map -------------------------------------------------------------------------------- /out/src/test/index.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/test/index.ts"],"names":[],"mappings":";AAAA,EAAE;AACF,mEAAmE;AACnE,EAAE;AACF,8EAA8E;AAC9E,oDAAoD;AACpD,EAAE;AACF,+EAA+E;AAC/E,kFAAkF;AAClF,iFAAiF;AACjF,gFAAgF;AAChF,oDAAoD;;;;;;;;;;;;;;;;;;;;;;;;;AAEpD,kEAAoD;AAEpD,8EAA8E;AAC9E,qFAAqF;AACrF,gBAAgB;AAChB,UAAU,CAAC,SAAS,CAAC;IACjB,EAAE,EAAE,KAAK,EAAI,oEAAoE;IACjF,SAAS,EAAE,IAAI,CAAC,mCAAmC;CACtD,CAAC,CAAC;AAEH,MAAM,CAAC,OAAO,GAAG,UAAU,CAAC"} -------------------------------------------------------------------------------- /out/src/test/puppeteer.test.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { 3 | if (k2 === undefined) k2 = k; 4 | var desc = Object.getOwnPropertyDescriptor(m, k); 5 | if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { 6 | desc = { enumerable: true, get: function() { return m[k]; } }; 7 | } 8 | Object.defineProperty(o, k2, desc); 9 | }) : (function(o, m, k, k2) { 10 | if (k2 === undefined) k2 = k; 11 | o[k2] = m[k]; 12 | })); 13 | var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { 14 | Object.defineProperty(o, "default", { enumerable: true, value: v }); 15 | }) : function(o, v) { 16 | o["default"] = v; 17 | }); 18 | var __importStar = (this && this.__importStar) || function (mod) { 19 | if (mod && mod.__esModule) return mod; 20 | var result = {}; 21 | if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); 22 | __setModuleDefault(result, mod); 23 | return result; 24 | }; 25 | var __importDefault = (this && this.__importDefault) || function (mod) { 26 | return (mod && mod.__esModule) ? mod : { "default": mod }; 27 | }; 28 | Object.defineProperty(exports, "__esModule", { value: true }); 29 | const assert = __importStar(require("assert")); 30 | const puppeteer_1 = __importDefault(require("puppeteer")); 31 | const { describe, it, before } = require('mocha'); 32 | describe('on page load', () => { 33 | it('h1 loads correctly', async () => { 34 | let browser = await puppeteer_1.default.launch({}); 35 | let page = await browser.newPage(); 36 | assert.ok(browser); 37 | await page.emulate({ 38 | viewport: { 39 | width: 500, 40 | height: 2400, 41 | }, 42 | userAgent: '' 43 | }); 44 | await browser.close(); // Don't forget to close the browser after tests 45 | }); 46 | }); 47 | describe('Simple test suite:', function () { 48 | it('1 === 1 should be true', function () { 49 | assert.strictEqual(1, 1); 50 | }); 51 | }); 52 | //# sourceMappingURL=puppeteer.test.js.map -------------------------------------------------------------------------------- /out/src/test/puppeteer.test.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"puppeteer.test.js","sourceRoot":"","sources":["../../../src/test/puppeteer.test.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,+CAAiC;AACjC,0DAAkC;AAClC,MAAM,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;AAElD,QAAQ,CAAC,cAAc,EAAE,GAAG,EAAE;IAC5B,EAAE,CAAC,oBAAoB,EAAE,KAAK,IAAI,EAAE;QAClC,IAAI,OAAO,GAAG,MAAM,mBAAS,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACzC,IAAI,IAAI,GAAG,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC;QACnC,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC;QAEnB,MAAM,IAAI,CAAC,OAAO,CAAC;YACjB,QAAQ,EAAE;gBACR,KAAK,EAAE,GAAG;gBACV,MAAM,EAAE,IAAI;aACb;YACD,SAAS,EAAE,EAAE;SACd,CAAC,CAAC;QAEH,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,gDAAgD;IACzE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,oBAAoB,EAAE;IAC7B,EAAE,CAAC,wBAAwB,EAAE;QAC3B,MAAM,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAC3B,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"} -------------------------------------------------------------------------------- /out/startExtensionProvider.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | const vscode = require("vscode"); 4 | class StartExtensionProvider { 5 | constructor() { 6 | this._onDidChangeTreeData = new vscode.EventEmitter(); 7 | this.onDidChangeTreeData = this._onDidChangeTreeData.event; 8 | } 9 | refresh() { 10 | this._onDidChangeTreeData.fire(); 11 | this._onDidChangeTreeData.dispose(); 12 | } 13 | getTreeItem(element) { 14 | return element; 15 | } 16 | getChildren(element) { 17 | vscode.commands.executeCommand('ReactION.openTree'); 18 | vscode.commands.executeCommand('workbench.view.explorer'); 19 | this._onDidChangeTreeData.fire(); 20 | this._onDidChangeTreeData.dispose(); 21 | return Promise.reject([]); 22 | } 23 | } 24 | exports.default = StartExtensionProvider; 25 | //# sourceMappingURL=StartExtensionProvider.js.map -------------------------------------------------------------------------------- /out/startExtensionProvider.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"StartExtensionProvider.js","sourceRoot":"","sources":["../src/StartExtensionProvider.ts"],"names":[],"mappings":";;AAAA,iCAAiC;AAEjC,MAAqB,sBAAsB;IAIzC;QAHQ,yBAAoB,GAA4C,IAAI,MAAM,CAAC,YAAY,EAAsB,CAAC;QAC7G,wBAAmB,GAAqC,IAAI,CAAC,oBAAoB,CAAC,KAAK,CAAC;IAElF,CAAC;IAEhB,OAAO;QACL,IAAI,CAAC,oBAAoB,CAAC,IAAI,EAAE,CAAA;QAChC,IAAI,CAAC,oBAAoB,CAAC,OAAO,EAAE,CAAC;IACtC,CAAC;IAED,WAAW,CAAC,OAAe;QACzB,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,WAAW,CAAC,OAAgB;QAC1B,MAAM,CAAC,QAAQ,CAAC,cAAc,CAAC,mBAAmB,CAAC,CAAC;QACpD,MAAM,CAAC,QAAQ,CAAC,cAAc,CAAC,yBAAyB,CAAC,CAAC;QAE1D,IAAI,CAAC,oBAAoB,CAAC,IAAI,EAAE,CAAC;QACjC,IAAI,CAAC,oBAAoB,CAAC,OAAO,EAAE,CAAC;QACpC,OAAO,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IAC5B,CAAC;CACF;AAvBD,yCAuBC"} -------------------------------------------------------------------------------- /out/test/extension.test.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | // The module 'assert' provides assertion methods from node 4 | const vscode = require("vscode"); 5 | const assert = require("assert"); 6 | // You can import and use all API from the 'vscode' module 7 | // as well as import your extension to test it 8 | // import * as vscode from 'vscode'; 9 | const treeColumn = vscode.ViewColumn.Two; 10 | // Show Virtual DOM Tree in VS Code 11 | // const treePanel: any = vscode.window.createWebviewPanel(ViewPanel.viewType, "Virtual DOM Tree", treeColumn, { 12 | // // Enable javascript in the webview 13 | // enableScripts: true, 14 | // retainContextWhenHidden: true, 15 | // enableCommandUris: true 16 | // }); 17 | // Defines a Mocha test suite to group tests of similar kind together 18 | suite("Extension Tests", function () { 19 | // Defines a Mocha unit test 20 | test("Extension Running", function () { 21 | assert.equal(2, 1 + 1); 22 | }); 23 | }); 24 | //# sourceMappingURL=extension.test.js.map -------------------------------------------------------------------------------- /out/test/extension.test.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"extension.test.js","sourceRoot":"","sources":["../../src/test/extension.test.ts"],"names":[],"mappings":";;AACA,2DAA2D;AAC3D,iCAAiC;AACjC,iCAAiC;AAEjC,0DAA0D;AAC1D,8CAA8C;AAC9C,oCAAoC;AAEpC,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC;AACzC,mCAAmC;AACnC,gHAAgH;AAEhH,0CAA0C;AAC1C,2BAA2B;AAC3B,qCAAqC;AACrC,8BAA8B;AAC9B,MAAM;AAEN,qEAAqE;AACrE,KAAK,CAAC,iBAAiB,EAAE;IAErB,4BAA4B;IAC5B,IAAI,CAAC,mBAAmB,EAAE;QACtB,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC3B,CAAC,CAAC,CAAC;AACP,CAAC,CAAC,CAAC"} -------------------------------------------------------------------------------- /out/test/index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | // 3 | // PLEASE DO NOT MODIFY / DELETE UNLESS YOU KNOW WHAT YOU ARE DOING 4 | // 5 | // This file is providing the test runner to use when running extension tests. 6 | // By default the test runner in use is Mocha based. 7 | // 8 | // You can provide your own test runner if you want to override it by exporting 9 | // a function run(testRoot: string, clb: (error:Error) => void) that the extension 10 | // host can call to run the tests. The test runner is expected to use console.log 11 | // to report the results back to the caller. When the tests are finished, return 12 | // a possible error to the callback or null if none. 13 | Object.defineProperty(exports, "__esModule", { value: true }); 14 | const testRunner = require("vscode/lib/testrunner"); 15 | // You can directly control Mocha options by configuring the test runner below 16 | // See https://github.com/mochajs/mocha/wiki/Using-mocha-programmatically#set-options 17 | // for more info 18 | testRunner.configure({ 19 | ui: 'tdd', 20 | useColors: true // colored output from test results 21 | }); 22 | module.exports = testRunner; 23 | //# sourceMappingURL=index.js.map -------------------------------------------------------------------------------- /out/test/index.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/test/index.ts"],"names":[],"mappings":";AAAA,EAAE;AACF,mEAAmE;AACnE,EAAE;AACF,8EAA8E;AAC9E,oDAAoD;AACpD,EAAE;AACF,+EAA+E;AAC/E,kFAAkF;AAClF,iFAAiF;AACjF,gFAAgF;AAChF,oDAAoD;;AAEpD,oDAAoD;AAEpD,8EAA8E;AAC9E,qFAAqF;AACrF,gBAAgB;AAChB,UAAU,CAAC,SAAS,CAAC;IACjB,EAAE,EAAE,KAAK;IACT,SAAS,EAAE,IAAI,CAAC,mCAAmC;CACtD,CAAC,CAAC;AAEH,MAAM,CAAC,OAAO,GAAG,UAAU,CAAC"} -------------------------------------------------------------------------------- /out/test/puppeteer.test.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | const assert = require("assert"); 4 | const puppeteer = require('puppeteer'); 5 | const { describe, it, before } = require('mocha'); 6 | // const { expect } = require('chai'); 7 | // const global: any = undefined; 8 | describe('on page load', () => { 9 | test('h1 loads correctly', async () => { 10 | let browser = await puppeteer.launch({}); 11 | let page = await browser.newPage(); 12 | assert(browser); 13 | page.emulate({ 14 | viewport: { 15 | width: 500, 16 | height: 2400, 17 | }, 18 | userAgent: '' 19 | }); 20 | }); 21 | }); 22 | describe('Simple test suite:', function () { 23 | it('1 === 1 should be true', function () { 24 | assert(1 === 1); 25 | }); 26 | }); 27 | //# sourceMappingURL=puppeteer.test.js.map -------------------------------------------------------------------------------- /out/test/puppeteer.test.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"puppeteer.test.js","sourceRoot":"","sources":["../../src/test/puppeteer.test.ts"],"names":[],"mappings":";;AAAA,iCAAiC;AACjC,MAAM,SAAS,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;AACvC,MAAM,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;AAClD,sCAAsC;AACtC,iCAAiC;AAEjC,QAAQ,CAAC,cAAc,EAAE,GAAG,EAAE;IAC5B,IAAI,CAAC,oBAAoB,EAAE,KAAK,IAAI,EAAE;QACpC,IAAI,OAAO,GAAG,MAAM,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACzC,IAAI,IAAI,GAAG,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC;QACnC,MAAM,CAAC,OAAO,CAAC,CAAC;QAEhB,IAAI,CAAC,OAAO,CAAC;YACX,QAAQ,EAAE;gBACR,KAAK,EAAE,GAAG;gBACV,MAAM,EAAE,IAAI;aACb;YACD,SAAS,EAAE,EAAE;SACd,CAAC,CAAC;IAEL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,oBAAoB,EAAE;IAC7B,EAAE,CAAC,wBAAwB,EAAE;QAC3B,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"} -------------------------------------------------------------------------------- /out/treeviewpanel.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | const vscode = require("vscode"); 4 | const path = require("path"); 5 | exports.default = { 6 | generateD3: function (stringifiedTreeData, parseInfo) { 7 | const bundle = vscode.Uri.file(path.join(__dirname, 'build', 'bundle.js')); 8 | const bundleUri = bundle.with({ 9 | scheme: 'vscode-resource' 10 | }); 11 | console.log(stringifiedTreeData); 12 | return ` 13 | 14 | 15 | 16 | 17 | 18 | Tree Example 19 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | `; 30 | } 31 | }; 32 | //# sourceMappingURL=treeViewPanel.js.map -------------------------------------------------------------------------------- /out/treeviewpanel.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"treeViewPanel.js","sourceRoot":"","sources":["../src/treeViewPanel.ts"],"names":[],"mappings":";;AAAA,iCAAiC;AACjC,6BAA6B;AAE7B,kBAAe;IACd,UAAU,EACT,UAAU,mBAA2B,EAAE,SAAc;QACpD,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,EAAE,WAAW,CAAC,CAAC,CAAC;QAC3E,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC;YAC7B,MAAM,EAAE,iBAAiB;SACzB,CAAC,CAAC;QAEH,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAA;QAEhC,OAAO;;;;;;;;2BAQiB,mBAAmB;0BACpB,SAAS;;;;;mBAKhB,SAAS;;;GAGzB,CAAC;IACF,CAAC;CACF,CAAA"} -------------------------------------------------------------------------------- /out/viewPanel.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | const vscode = require("vscode"); 4 | const treeViewPanel_1 = require("./treeViewPanel"); 5 | const Puppeteer_1 = require("./Puppeteer"); 6 | const TreeNode_1 = require("./TreeNode"); 7 | class ViewPanel { 8 | // Constructor for tree view and html panel 9 | constructor(treePanel, parseInfo) { 10 | this._disposables = []; 11 | this._treePanel = treePanel; 12 | this._parseInfo = parseInfo; 13 | // Running Puppeteer to access React page context 14 | this._page = new Puppeteer_1.default(parseInfo); 15 | this._page.start(); 16 | setInterval(() => { 17 | this._update(); 18 | }, 1000); 19 | this._treePanel.onDidDispose(() => this.dispose(), null, this._disposables); 20 | } 21 | static createOrShow(extensionPath, parseInfo) { 22 | const treeColumn = vscode.ViewColumn.Two; 23 | if (ViewPanel.currentPanel) { 24 | ViewPanel.currentPanel._treePanel.reveal(treeColumn); 25 | return; 26 | } 27 | // Show Virtual DOM Tree in VS Code 28 | const treePanel = vscode.window.createWebviewPanel(ViewPanel.viewType, "Virtual DOM Tree", treeColumn, { 29 | // Enable javascript in the webview 30 | enableScripts: true, 31 | retainContextWhenHidden: true, 32 | enableCommandUris: true 33 | }); 34 | ViewPanel.currentPanel = new ViewPanel(treePanel, parseInfo); 35 | } 36 | dispose() { 37 | ViewPanel.currentPanel = undefined; 38 | // Clean up our resources 39 | this._treePanel.dispose(); 40 | while (this._disposables.length) { 41 | const x = this._disposables.pop(); 42 | if (x) { 43 | x.dispose(); 44 | } 45 | } 46 | } 47 | async _update() { 48 | let rawReactData = await this._page.scrape(); 49 | // Build out TreeNode class for React D3 Tree. 50 | function buildTree(rawReactData) { 51 | let tree = new TreeNode_1.default(rawReactData[0]); 52 | const freeNodes = []; 53 | rawReactData.forEach((el) => { 54 | const parentNode = tree._find(tree, el.parentId); 55 | if (parentNode) { 56 | parentNode._add(el); 57 | } 58 | else { 59 | freeNodes.push(el); 60 | } 61 | }); 62 | while (freeNodes.length > 0) { 63 | const curEl = freeNodes[0]; 64 | const parentNode = tree._find(tree, curEl.parentId); 65 | if (parentNode) { 66 | parentNode._add(curEl); 67 | } 68 | freeNodes.shift(); 69 | } 70 | return tree; 71 | } 72 | const treeData = await buildTree(rawReactData); 73 | this._treePanel.webview.html = this._getHtmlForWebview(treeData); 74 | } 75 | // Putting scraped meta-data to D3 tree diagram 76 | _getHtmlForWebview(treeData) { 77 | const stringifiedFlatData = JSON.stringify(treeData); 78 | return treeViewPanel_1.default.generateD3(stringifiedFlatData, this._parseInfo); 79 | } 80 | } 81 | ViewPanel.viewType = 'ReactION'; 82 | exports.default = ViewPanel; 83 | //# sourceMappingURL=ViewPanel.js.map -------------------------------------------------------------------------------- /out/viewPanel.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"ViewPanel.js","sourceRoot":"","sources":["../src/ViewPanel.ts"],"names":[],"mappings":";;AAAA,iCAAiC;AACjC,mDAAuC;AACvC,2CAAoC;AACpC,yCAAkC;AAElC,MAAqB,SAAS;IAS7B,2CAA2C;IAC3C,YACC,SAA8B,EAC9B,SAAc;QAPP,iBAAY,GAAwB,EAAE,CAAC;QAS9C,IAAI,CAAC,UAAU,GAAG,SAAS,CAAC;QAC5B,IAAI,CAAC,UAAU,GAAG,SAAS,CAAC;QAE5B,iDAAiD;QACjD,IAAI,CAAC,KAAK,GAAG,IAAI,mBAAS,CAAC,SAAS,CAAC,CAAC;QACtC,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QACnB,WAAW,CAAC,GAAG,EAAE;YAChB,IAAI,CAAC,OAAO,EAAE,CAAC;QAChB,CAAC,EAAE,IAAI,CAAC,CAAC;QACT,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;IAC7E,CAAC;IAGM,MAAM,CAAC,YAAY,CAAC,aAAqB,EAAE,SAAc;QAC/D,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC;QACzC,IAAI,SAAS,CAAC,YAAY,EAAE;YAC3B,SAAS,CAAC,YAAY,CAAC,UAAU,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;YACrD,OAAO;SACP;QAED,mCAAmC;QACnC,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,kBAAkB,CAAC,SAAS,CAAC,QAAQ,EAAE,kBAAkB,EAAE,UAAU,EAAE;YAEtG,mCAAmC;YACnC,aAAa,EAAE,IAAI;YACnB,uBAAuB,EAAE,IAAI;YAC7B,iBAAiB,EAAE,IAAI;SACvB,CAAC,CAAC;QAEH,SAAS,CAAC,YAAY,GAAG,IAAI,SAAS,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;IAC9D,CAAC;IAEM,OAAO;QACb,SAAS,CAAC,YAAY,GAAG,SAAS,CAAC;QAEnC,yBAAyB;QACzB,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC;QAE1B,OAAO,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE;YAChC,MAAM,CAAC,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,EAAE,CAAC;YAClC,IAAI,CAAC,EAAE;gBACN,CAAC,CAAC,OAAO,EAAE,CAAC;aACZ;SACD;IACF,CAAC;IAEO,KAAK,CAAC,OAAO;QACpB,IAAI,YAAY,GAAkB,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;QAE5D,8CAA8C;QAC9C,SAAS,SAAS,CAAC,YAA2B;YAC7C,IAAI,IAAI,GAAa,IAAI,kBAAQ,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;YACnD,MAAM,SAAS,GAAQ,EAAE,CAAC;YAE1B,YAAY,CAAC,OAAO,CAAC,CAAC,EAAO,EAAE,EAAE;gBAChC,MAAM,UAAU,GAAa,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC;gBAC3D,IAAI,UAAU,EAAE;oBACf,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;iBACpB;qBAAM;oBACN,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;iBACnB;YACF,CAAC,CAAC,CAAC;YAEH,OAAO,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE;gBAC5B,MAAM,KAAK,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;gBAC3B,MAAM,UAAU,GAAa,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC;gBAC9D,IAAI,UAAU,EAAE;oBACf,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;iBACvB;gBACD,SAAS,CAAC,KAAK,EAAE,CAAC;aAClB;YACD,OAAO,IAAI,CAAC;QACb,CAAC;QACD,MAAM,QAAQ,GAAa,MAAM,SAAS,CAAC,YAAY,CAAC,CAAC;QACzD,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,kBAAkB,CAAC,QAAQ,CAAC,CAAC;IAClE,CAAC;IAED,+CAA+C;IACvC,kBAAkB,CAAC,QAAkB;QAC5C,MAAM,mBAAmB,GAAW,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;QAC7D,OAAO,uBAAQ,CAAC,UAAU,CAAC,mBAAmB,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;IAClE,CAAC;;AA5FsB,kBAAQ,GAAG,UAAU,AAAb,CAAc;kBAHzB,SAAS"} -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ReactION", 3 | "displayName": "ReactION-BETA", 4 | "publisher": "ReactION-JS", 5 | "description": "React Component Visualizer for VS Code", 6 | "version": "0.1.4", 7 | "icon": "resources/color.png", 8 | "engines": { 9 | "vscode": "^1.31.0" 10 | }, 11 | "categories": [ 12 | "Other" 13 | ], 14 | "activationEvents": [ 15 | "onWebviewPanel:ReactION" 16 | ], 17 | "main": "./out/extension.js", 18 | "contributes": { 19 | "views": { 20 | "ReactION-button": [ 21 | { 22 | "id": "startExtension", 23 | "name": "Launch" 24 | } 25 | ] 26 | }, 27 | "viewsContainers": { 28 | "activitybar": [ 29 | { 30 | "id": "ReactION-button", 31 | "title": "ReactION", 32 | "icon": "resources/reactionlogo.svg" 33 | } 34 | ] 35 | }, 36 | "commands": [ 37 | { 38 | "command": "ReactION.openTree", 39 | "title": "ReactION: Launch" 40 | }, 41 | { 42 | "command": "ReactION.openWeb", 43 | "title": "ReactION: Embedded Webview" 44 | } 45 | ] 46 | }, 47 | "repository": { 48 | "type": "git", 49 | "url": "https://github.com/ReactION-js/ReactION" 50 | }, 51 | "scripts": { 52 | "vscode:prepublish": "npm run compile", 53 | "compile": "tsc -p ./", 54 | "watch": "tsc -watch -p ./", 55 | "postinstall": "node ./node_modules/vscode/bin/install", 56 | "test": "npm run compile && node ./node_modules/vscode/bin/test", 57 | "build": "webpack --watch" 58 | }, 59 | "devDependencies": { 60 | "@babel/core": "^7.2.2", 61 | "@babel/preset-env": "^7.3.1", 62 | "@babel/preset-react": "^7.0.0", 63 | "@babel/preset-typescript": "^7.3.3", 64 | "@types/babel__traverse": "^7.20.6", 65 | "@types/chai": "^4.3.16", 66 | "@types/lodash": "^4.17.6", 67 | "@types/mocha": "^2.2.42", 68 | "@types/node": "^10.12.21", 69 | "@types/puppeteer": "^7.0.4", 70 | "@types/react": "^18.3.3", 71 | "@types/react-dom": "^18.3.0", 72 | "@types/styled-components": "^5.1.34", 73 | "babel-jest": "^24.5.0", 74 | "babel-loader": "^8.0.5", 75 | "css-loader": "^2.1.0", 76 | "puppeteer": "^22.12.1", 77 | "style-loader": "^0.23.1", 78 | "tslint": "^5.12.1", 79 | "typescript": "^5.5.3", 80 | "vscode": "^1.1.28", 81 | "webpack": "^4.29.2", 82 | "webpack-cli": "^3.2.3" 83 | }, 84 | "dependencies": { 85 | "electron-devtools-installer": "^2.2.4", 86 | "puppeteer-core": "^14.4.0", 87 | "react": "^16.5.2", 88 | "react-d3-tree": "^1.12.2", 89 | "react-dom": "^16.5.2", 90 | "styled-components": "^4.1.3" 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /reactION-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "system": "darwin", 3 | "executablePath": "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome", 4 | "localhost": "localhost:3000", 5 | "headless_browser": false, 6 | "headless_embedded": true, 7 | "reactTheme": "dark" 8 | } -------------------------------------------------------------------------------- /resources/Text_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ReactION-js/ReactION/d5ec81e69a4634b0d8d0a0be2e72e808a1cf08fa/resources/Text_1.png -------------------------------------------------------------------------------- /resources/Text_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ReactION-js/ReactION/d5ec81e69a4634b0d8d0a0be2e72e808a1cf08fa/resources/Text_2.png -------------------------------------------------------------------------------- /resources/black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ReactION-js/ReactION/d5ec81e69a4634b0d8d0a0be2e72e808a1cf08fa/resources/black.png -------------------------------------------------------------------------------- /resources/color.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ReactION-js/ReactION/d5ec81e69a4634b0d8d0a0be2e72e808a1cf08fa/resources/color.png -------------------------------------------------------------------------------- /resources/reactionlogo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 9 | 11 | 14 | 16 | 18 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/Demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ReactION-js/ReactION/d5ec81e69a4634b0d8d0a0be2e72e808a1cf08fa/src/Demo.gif -------------------------------------------------------------------------------- /src/EmbeddedViewPanel.ts: -------------------------------------------------------------------------------- 1 | import * as vscode from 'vscode'; 2 | import Puppeteer from './puppeteer'; 3 | import treeView from './TreeViewPanel'; 4 | import htmlView from './htmlViewPanel'; 5 | import TreeNode from './TreeNode'; 6 | 7 | interface ParseInfo { 8 | [key: string]: any; 9 | } 10 | 11 | interface RawReactData { 12 | parentId: string; 13 | [key: string]: any; 14 | } 15 | 16 | export default class EmbeddedViewPanel { 17 | 18 | public static currentPanel: EmbeddedViewPanel | undefined; 19 | public static readonly viewType = 'ReactION'; 20 | private readonly _htmlPanel: vscode.WebviewPanel; 21 | private readonly _treePanel: vscode.WebviewPanel; 22 | private _disposables: vscode.Disposable[] = []; 23 | public readonly _page: Puppeteer; 24 | public readonly _parseInfo: ParseInfo; 25 | 26 | // Constructor for tree view and html panel 27 | public constructor( 28 | htmlPanel: vscode.WebviewPanel, 29 | treePanel: vscode.WebviewPanel, 30 | parseInfo: ParseInfo 31 | ) { 32 | this._htmlPanel = htmlPanel; 33 | this._treePanel = treePanel; 34 | this._parseInfo = parseInfo; 35 | 36 | // Starts the instance of the embedded webview 37 | this._htmlPanel.webview.html = this._getPreviewHtmlForWebview(); 38 | 39 | // Running Puppeteer to access React page context 40 | this._page = new Puppeteer(parseInfo); 41 | this._page.start(); 42 | 43 | setInterval(() => { 44 | this._update(); 45 | }, 1000); 46 | 47 | this._treePanel.onDidDispose(() => this.dispose(), null, this._disposables); 48 | } 49 | 50 | public static createOrShow(extensionPath: string, parseInfo: any) { 51 | const treeColumn = vscode.ViewColumn.Three; 52 | const htmlColumn = vscode.ViewColumn.Two; 53 | 54 | if (EmbeddedViewPanel.currentPanel) { 55 | EmbeddedViewPanel.currentPanel._htmlPanel.reveal(htmlColumn); 56 | EmbeddedViewPanel.currentPanel._treePanel.reveal(treeColumn); 57 | return; 58 | } 59 | 60 | // Show HTML Preview in VS Code 61 | const htmlPanel = vscode.window.createWebviewPanel(EmbeddedViewPanel.viewType, "HTML Preview", htmlColumn, { 62 | // Enable javascript in the webview 63 | enableScripts: true, 64 | retainContextWhenHidden: true, 65 | enableCommandUris: true 66 | }); 67 | 68 | // Show Virtual DOM Tree in VS Code 69 | const treePanel = vscode.window.createWebviewPanel(EmbeddedViewPanel.viewType, "Virtual DOM Tree", treeColumn, { 70 | // Enable javascript in the webview 71 | enableScripts: true, 72 | retainContextWhenHidden: true, 73 | enableCommandUris: true 74 | }); 75 | 76 | EmbeddedViewPanel.currentPanel = new EmbeddedViewPanel(htmlPanel, treePanel, parseInfo); 77 | } 78 | 79 | public dispose(): void { 80 | EmbeddedViewPanel.currentPanel = undefined; 81 | 82 | // Clean up our resources 83 | this._htmlPanel.dispose(); 84 | this._treePanel.dispose(); 85 | 86 | while (this._disposables.length) { 87 | const x = this._disposables.pop(); 88 | if (x) { 89 | x.dispose(); 90 | } 91 | } 92 | } 93 | 94 | private async _update(): Promise { 95 | let rawReactData: RawReactData[] = await this._page.scrape(); 96 | 97 | // Build out TreeNode class for React D3 Tree. 98 | function buildTree(rawReactData: RawReactData[]): TreeNode { 99 | let tree: TreeNode = new TreeNode(rawReactData[0]); 100 | const freeNodes: RawReactData[] = []; 101 | 102 | rawReactData.forEach((el) => { 103 | const parentNode: TreeNode = tree._find(tree, el.parentId); 104 | if (parentNode) { 105 | parentNode._add(el); 106 | } else { 107 | freeNodes.push(el); 108 | } 109 | }); 110 | 111 | while (freeNodes.length > 0) { 112 | const curEl = freeNodes.shift(); 113 | if (curEl) { 114 | const parentNode = tree._find(tree, curEl.parentId); 115 | if (parentNode) { 116 | parentNode._add(curEl); 117 | } 118 | } 119 | } 120 | return tree; 121 | } 122 | const treeData: TreeNode = await buildTree(rawReactData); 123 | this._treePanel.webview.html = this._getHtmlForWebview(treeData); 124 | } 125 | 126 | // Putting scraped meta-data to D3 tree diagram 127 | private _getHtmlForWebview(treeData: TreeNode): string { 128 | const stringifiedFlatData = JSON.stringify(treeData); 129 | return treeView.generateD3(stringifiedFlatData, this._parseInfo); 130 | } 131 | 132 | private _getPreviewHtmlForWebview(): string { 133 | return htmlView.html; 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /src/ReactION-sample.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ReactION-js/ReactION/d5ec81e69a4634b0d8d0a0be2e72e808a1cf08fa/src/ReactION-sample.png -------------------------------------------------------------------------------- /src/TreeNode.ts: -------------------------------------------------------------------------------- 1 | export default class TreeNode { 2 | public name: string; 3 | public id: string; 4 | public attributes: any; 5 | public parentId: any; 6 | public children: any[]; 7 | public display: string; 8 | 9 | public constructor(node: any) { 10 | this.name = node.name; 11 | this.id = node.id; 12 | this.attributes = node.props; 13 | this.parentId = node.parentId; 14 | this.display = node.display; 15 | this.children = []; 16 | } 17 | 18 | // Add new node to the tree 19 | public _add(node: any) { 20 | const newNode = new TreeNode(node); 21 | this.children.push(newNode); 22 | } 23 | 24 | // Search if there is a node with matching id. 25 | public _find(root: any, parentId: any) { 26 | let curNode = root; 27 | if (curNode.id === parentId) { 28 | return curNode; 29 | } 30 | if (curNode.children.length !== 0) { 31 | for (let el of curNode.children) { 32 | const findParent: any = this._find(el, parentId); 33 | if (findParent) { 34 | return findParent; 35 | } 36 | } 37 | } 38 | return false; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/TreeViewPanel.ts: -------------------------------------------------------------------------------- 1 | import * as vscode from 'vscode'; 2 | import * as path from 'path'; 3 | 4 | export default { 5 | generateD3: 6 | function (stringifiedTreeData: string, parseInfo: any): string { 7 | const bundle = vscode.Uri.file(path.join(__dirname, 'build', 'bundle.js')); 8 | const bundleUri = bundle.with({ 9 | scheme: 'vscode-resource' 10 | }); 11 | 12 | console.log(stringifiedTreeData) 13 | 14 | return ` 15 | 16 | 17 | 18 | 19 | 20 | Tree Example 21 | 25 | 26 | 27 |
28 | 29 | 30 | 31 | `; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/ViewPanel.ts: -------------------------------------------------------------------------------- 1 | import * as vscode from 'vscode'; 2 | import treeView from './TreeViewPanel'; 3 | import Puppeteer from './puppeteer'; 4 | import TreeNode from './TreeNode'; 5 | 6 | export default class ViewPanel { 7 | 8 | public static currentPanel: ViewPanel | undefined; 9 | public static readonly viewType = 'ReactION'; 10 | private readonly _treePanel: vscode.WebviewPanel; 11 | private _disposables: vscode.Disposable[] = []; 12 | public readonly _page: Puppeteer; 13 | public readonly _parseInfo: any; 14 | 15 | // Constructor for tree view and html panel 16 | public constructor( 17 | treePanel: vscode.WebviewPanel, 18 | parseInfo: any 19 | ) { 20 | this._treePanel = treePanel; 21 | this._parseInfo = parseInfo; 22 | 23 | // Running Puppeteer to access React page context 24 | this._page = new Puppeteer(parseInfo); 25 | this._page.start(); 26 | setInterval(() => { 27 | this._update(); 28 | }, 1000); 29 | this._treePanel.onDidDispose(() => this.dispose(), null, this._disposables); 30 | } 31 | 32 | 33 | public static createOrShow(extensionPath: string, parseInfo: any) { 34 | const treeColumn = vscode.ViewColumn.Two; 35 | if (ViewPanel.currentPanel) { 36 | ViewPanel.currentPanel._treePanel.reveal(treeColumn); 37 | return; 38 | } 39 | 40 | // Show Virtual DOM Tree in VS Code 41 | const treePanel = vscode.window.createWebviewPanel(ViewPanel.viewType, "Virtual DOM Tree", treeColumn, { 42 | 43 | // Enable javascript in the webview 44 | enableScripts: true, 45 | retainContextWhenHidden: true, 46 | enableCommandUris: true 47 | }); 48 | 49 | ViewPanel.currentPanel = new ViewPanel(treePanel, parseInfo); 50 | } 51 | 52 | public dispose(): void { 53 | ViewPanel.currentPanel = undefined; 54 | 55 | // Clean up our resources 56 | this._treePanel.dispose(); 57 | 58 | while (this._disposables.length) { 59 | const x = this._disposables.pop(); 60 | if (x) { 61 | x.dispose(); 62 | } 63 | } 64 | } 65 | 66 | private async _update(): Promise { 67 | let rawReactData: Array = await this._page.scrape(); 68 | 69 | // Build out TreeNode class for React D3 Tree. 70 | function buildTree(rawReactData: Array) { 71 | let tree: TreeNode = new TreeNode(rawReactData[0]); 72 | const freeNodes: any = []; 73 | 74 | rawReactData.forEach((el: any) => { 75 | const parentNode: TreeNode = tree._find(tree, el.parentId); 76 | if (parentNode) { 77 | parentNode._add(el); 78 | } else { 79 | freeNodes.push(el); 80 | } 81 | }); 82 | 83 | while (freeNodes.length > 0) { 84 | const curEl = freeNodes[0]; 85 | const parentNode: TreeNode = tree._find(tree, curEl.parentId); 86 | if (parentNode) { 87 | parentNode._add(curEl); 88 | } 89 | freeNodes.shift(); 90 | } 91 | return tree; 92 | } 93 | const treeData: TreeNode = await buildTree(rawReactData); 94 | this._treePanel.webview.html = this._getHtmlForWebview(treeData); 95 | } 96 | 97 | // Putting scraped meta-data to D3 tree diagram 98 | private _getHtmlForWebview(treeData: TreeNode): string { 99 | const stringifiedFlatData: string = JSON.stringify(treeData); 100 | return treeView.generateD3(stringifiedFlatData, this._parseInfo); 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /src/extension.ts: -------------------------------------------------------------------------------- 1 | import * as vscode from 'vscode'; 2 | import StartExtensionProvider from './startExtensionProvider'; 3 | import EmbeddedViewPanel from './EmbeddedViewPanel'; 4 | import ViewPanel from './ViewPanel'; 5 | const fs = require('fs'); 6 | const path = require('path'); 7 | 8 | let parseInfo: {}; 9 | let subscriptions: { dispose: () => void }[] = []; 10 | 11 | // Method called when extension is activated 12 | export function activate(context: vscode.ExtensionContext) { 13 | const workspaceFolders = vscode.workspace.workspaceFolders; 14 | if (!workspaceFolders) { 15 | vscode.window.showErrorMessage("No workspace is opened. Please open a workspace and try again."); 16 | return; 17 | } 18 | 19 | const rootPath = workspaceFolders[0].uri.fsPath; 20 | const configPath = path.join(rootPath, "reactION-config.json"); 21 | const setup: any = {}; 22 | 23 | setup.system = process.platform; 24 | 25 | // Setting the executable path on config file based on user's OS. 26 | switch(setup.system) { 27 | 28 | // For iOS environment. 29 | case 'darwin': 30 | setup.executablePath = '/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome'; 31 | break; 32 | 33 | // For Linux environment. 34 | case 'linux': 35 | setup.executablePath = ''; 36 | vscode.window.showInformationMessage('Please specify your Chrominum executablePath in reactION.config.json file created in your local directory.'); 37 | break; 38 | 39 | // For Window 10 environment. 40 | case 'win32': 41 | setup.executablePath = 'C:\Program Files (x86)\Google\Chrome\Application\chrome.exe'; 42 | break; 43 | default: 44 | vscode.window.showInformationMessage('Current Operating System is not supported.'); 45 | } 46 | setup.localhost = 'localhost:3000'; 47 | setup.headless_browser = false; 48 | setup.headless_embedded = true; 49 | setup.reactTheme = 'dark'; 50 | 51 | fs.stat(configPath, (err: any, stats: any) => { 52 | if (err) { 53 | console.log(err); 54 | } 55 | if (!stats) { 56 | fs.writeFileSync(configPath, JSON.stringify(setup, null, '\t')); 57 | } 58 | else { 59 | // else read off and apply config to the running instance 60 | parseInfo = JSON.parse(fs.readFileSync(configPath)); 61 | 62 | } 63 | }); 64 | 65 | 66 | subscriptions.push(vscode.commands.registerCommand('ReactION.openTree', () => { 67 | ViewPanel.createOrShow(context.extensionPath, parseInfo); 68 | })); 69 | 70 | subscriptions.push(vscode.commands.registerCommand('ReactION.openWeb', () => { 71 | EmbeddedViewPanel.createOrShow(context.extensionPath, parseInfo); 72 | })); 73 | 74 | vscode.window.registerTreeDataProvider('startExtension', new StartExtensionProvider()); 75 | 76 | context.subscriptions.push(...subscriptions); 77 | } 78 | 79 | // This method is called when your extension is deactivated 80 | export function deactivate() { 81 | // Dispose of subscriptions 82 | subscriptions.forEach(subscription => subscription.dispose()); 83 | subscriptions = []; 84 | console.log("Extension has been deactivated"); 85 | } 86 | -------------------------------------------------------------------------------- /src/global.d.ts: -------------------------------------------------------------------------------- 1 | import { Browser } from 'puppeteer'; 2 | import { expect as chaiExpect } from 'chai'; 3 | 4 | declare global { 5 | var browser: Browser; 6 | var expect: typeof chaiExpect; 7 | } 8 | 9 | export {}; 10 | -------------------------------------------------------------------------------- /src/htmlViewPanel.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | html: 3 | ` 4 | 16 | 17 | 18 | ` 19 | }; 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/puppeteer.ts: -------------------------------------------------------------------------------- 1 | const puppeteer = require('puppeteer-core'); 2 | 3 | export default class Puppeteer { 4 | 5 | public _headless: boolean; 6 | private _executablePath: string; 7 | private _pipe: boolean; 8 | public _url: string; 9 | private _page: any; 10 | private _browser: any; 11 | 12 | // Default properties for the Puppeteer class. 13 | public constructor(parseInfo: any) { 14 | this._headless = false; 15 | this._executablePath = parseInfo.executablePath; 16 | this._pipe = true; 17 | this._url = parseInfo.localhost; 18 | this._page = ''; 19 | this._browser = ''; 20 | } 21 | 22 | // Creates an instance of puppeteer browser and page, 23 | // opens to _url, defaults to localhost:3000 24 | public async start() { 25 | this._browser = await puppeteer.launch( 26 | { 27 | headless: this._headless, 28 | executablePath: this._executablePath, 29 | pipe: this._pipe, 30 | } 31 | ).catch((err: any) => console.log(err)); 32 | 33 | this._page = await this._browser.pages() 34 | .then((pageArr: any) => { 35 | return pageArr[0]; 36 | }); 37 | this._page.goto(this._url); 38 | 39 | return await this._page; 40 | } 41 | 42 | // Recursive React component scraping algorithm 43 | public scrape() { 44 | 45 | // All code inside .evaluate is executed in the pages context 46 | const reactData = this._page.evaluate( 47 | async (): Promise> => { 48 | 49 | // Access the React Dom 50 | // & create entry point for fiber node through DOM element 51 | const _entry = ((): any => { 52 | 53 | // @ts-ignore 54 | const domElements = document.querySelector('body').children; 55 | for (let el of domElements) { 56 | 57 | // @ts-ignore 58 | if (el._reactRootContainer) { 59 | 60 | // @ts-ignore 61 | return el._reactRootContainer._internalRoot.current; 62 | } 63 | } 64 | })(); 65 | 66 | // Define function that traverses the fiber tree, starting from the entry point 67 | function fiberWalk(entry: any) { 68 | let dataArr: any = [], globalId = 1; 69 | 70 | // Recursively traversing through the fiber tree, pushing the node object into the dataArr array 71 | function traverse(root: any, level: number, parentId: number) { 72 | if (root.sibling !== null) { 73 | globalId += 1; 74 | dataArr.push( 75 | { 76 | "name": root.sibling, 77 | "level": `${level}`, 78 | "id": `${globalId}`, 79 | "parentId": `${parentId}`, 80 | "props": Object.keys(root.sibling.memoizedProps) 81 | } 82 | ); 83 | traverse(root.sibling, level, parentId); 84 | } 85 | if (root.child !== null) { 86 | parentId += 1; 87 | globalId += 1; 88 | dataArr.push( 89 | { 90 | "name": root.child, 91 | "level": `${level}`, 92 | "id": `${globalId}`, 93 | "parentId": `${parentId}`, 94 | "display": "none", 95 | "props": Object.keys(root.child.memoizedProps) 96 | } 97 | ); 98 | traverse(root.child, level + 1, parentId); 99 | } 100 | } 101 | 102 | traverse(entry, 0, 0); 103 | 104 | // Extracts the type name of each fiber node 105 | dataArr.forEach((el: any) => { 106 | if (typeof el.name.type === null) { 107 | el.name = ''; 108 | } else if (typeof el.name.type === 'function' && el.name.type.name) { 109 | el.name = el.name.type.name; 110 | } else if (typeof el.name.type === 'function') { 111 | el.name = 'function'; 112 | } else if (typeof el.name.type === 'object') { 113 | el.name = 'function'; 114 | } else if (typeof el.name.type === 'string') { 115 | el.name = el.name.type; 116 | } 117 | }); 118 | 119 | // Setting root parent to an empty string 120 | dataArr[0].parentId = ''; 121 | 122 | return dataArr; 123 | } 124 | return fiberWalk(_entry); 125 | }).catch((err: any) => { console.log(err); }); 126 | 127 | return reactData; 128 | } 129 | } 130 | 131 | -------------------------------------------------------------------------------- /src/startExtensionProvider.ts: -------------------------------------------------------------------------------- 1 | import * as vscode from 'vscode'; 2 | 3 | export default class StartExtensionProvider implements vscode.TreeDataProvider { 4 | private _onDidChangeTreeData: vscode.EventEmitter = new vscode.EventEmitter(); 5 | readonly onDidChangeTreeData: vscode.Event = this._onDidChangeTreeData.event; 6 | 7 | constructor() {} 8 | 9 | refresh(): void { 10 | this._onDidChangeTreeData.fire() 11 | this._onDidChangeTreeData.dispose(); 12 | } 13 | 14 | getTreeItem(element: object): vscode.TreeItem { 15 | return element; 16 | } 17 | 18 | getChildren(element?: object): Thenable { 19 | vscode.commands.executeCommand('ReactION.openTree'); 20 | vscode.commands.executeCommand('workbench.view.explorer'); 21 | 22 | this._onDidChangeTreeData.fire(); 23 | this._onDidChangeTreeData.dispose(); 24 | return Promise.reject([]); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/test/TreeView.test.ts: -------------------------------------------------------------------------------- 1 | import puppeteer, { Browser, Page, PuppeteerLaunchOptions } from 'puppeteer'; 2 | import { expect as chaiExpect } from 'chai'; 3 | 4 | // Puppeteer options 5 | const opts: PuppeteerLaunchOptions = { 6 | headless: false, 7 | slowMo: 100, 8 | defaultViewport: null, 9 | args: ['--no-sandbox', '--disable-setuid-sandbox'], 10 | }; 11 | 12 | describe('sample test', function () { 13 | let browser: Browser; 14 | let page: Page; 15 | 16 | // Setup before running the tests 17 | before(async function () { 18 | browser = await puppeteer.launch(opts); 19 | page = await browser.newPage(); 20 | await page.goto('http://localhost:3000'); 21 | }); 22 | 23 | // Cleanup after running the tests 24 | after(async function () { 25 | if (page) { 26 | await page.close(); 27 | } 28 | if (browser) { 29 | await browser.close(); 30 | } 31 | }); 32 | 33 | it('Should have the correct page title', async function () { 34 | const title = await page.title(); 35 | chaiExpect(title).to.eql('Tree Example'); 36 | }); 37 | 38 | it('should have a single content section', async function () { 39 | const TREE_SELECTOR = '.treeChart'; 40 | 41 | await page.waitForSelector(TREE_SELECTOR); 42 | 43 | const elements = await page.$$(TREE_SELECTOR); 44 | chaiExpect(elements).to.have.lengthOf(1); 45 | }); 46 | }); 47 | -------------------------------------------------------------------------------- /src/test/extension.test.ts: -------------------------------------------------------------------------------- 1 | 2 | // The module 'assert' provides assertion methods from node 3 | import * as vscode from 'vscode'; 4 | import * as assert from 'assert'; 5 | 6 | // You can import and use all API from the 'vscode' module 7 | // as well as import your extension to test it 8 | // import * as vscode from 'vscode'; 9 | 10 | const treeColumn = vscode.ViewColumn.Two; 11 | // Show Virtual DOM Tree in VS Code 12 | // const treePanel: any = vscode.window.createWebviewPanel(ViewPanel.viewType, "Virtual DOM Tree", treeColumn, { 13 | 14 | // // Enable javascript in the webview 15 | // enableScripts: true, 16 | // retainContextWhenHidden: true, 17 | // enableCommandUris: true 18 | // }); 19 | 20 | // Defines a Mocha test suite to group tests of similar kind together 21 | suite("Extension Tests", function () { 22 | 23 | // Defines a Mocha unit test 24 | test("Extension Running", function () { 25 | assert.equal(2, 1 + 1); 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /src/test/index.ts: -------------------------------------------------------------------------------- 1 | // 2 | // PLEASE DO NOT MODIFY / DELETE UNLESS YOU KNOW WHAT YOU ARE DOING 3 | // 4 | // This file is providing the test runner to use when running extension tests. 5 | // By default the test runner in use is Mocha based. 6 | // 7 | // You can provide your own test runner if you want to override it by exporting 8 | // a function run(testRoot: string, clb: (error:Error) => void) that the extension 9 | // host can call to run the tests. The test runner is expected to use console.log 10 | // to report the results back to the caller. When the tests are finished, return 11 | // a possible error to the callback or null if none. 12 | 13 | import * as testRunner from 'vscode/lib/testrunner'; 14 | 15 | // You can directly control Mocha options by configuring the test runner below 16 | // See https://github.com/mochajs/mocha/wiki/Using-mocha-programmatically#set-options 17 | // for more info 18 | testRunner.configure({ 19 | ui: 'tdd', // the TDD UI is being used in extension.test.ts (suite, test, etc.) 20 | useColors: true // colored output from test results 21 | }); 22 | 23 | module.exports = testRunner; 24 | -------------------------------------------------------------------------------- /src/test/puppeteer.test.ts: -------------------------------------------------------------------------------- 1 | import * as assert from 'assert'; 2 | import puppeteer from 'puppeteer'; 3 | const { describe, it, before } = require('mocha'); 4 | 5 | describe('on page load', () => { 6 | it('h1 loads correctly', async () => { 7 | let browser = await puppeteer.launch({}); 8 | let page = await browser.newPage(); 9 | assert.ok(browser); 10 | 11 | await page.emulate({ 12 | viewport: { 13 | width: 500, 14 | height: 2400, 15 | }, 16 | userAgent: '' 17 | }); 18 | 19 | await browser.close(); // Don't forget to close the browser after tests 20 | }); 21 | }); 22 | 23 | describe('Simple test suite:', function () { 24 | it('1 === 1 should be true', function () { 25 | assert.strictEqual(1, 1); 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "jsx": "react", 4 | "module": "commonjs", 5 | "target": "ES2018", 6 | "outDir": "out", 7 | "lib": [ 8 | "es6", 9 | "dom", 10 | "dom.iterable" 11 | ], 12 | "sourceMap": true, 13 | "strict": true, 14 | "esModuleInterop": true, // Enable esModuleInterop 15 | "allowSyntheticDefaultImports": true, // Enable allowSyntheticDefaultImports 16 | "moduleResolution": "node", 17 | "skipLibCheck": true, 18 | "forceConsistentCasingInFileNames": true 19 | }, 20 | "include": [ 21 | "src/**/*", 22 | "client/**/*", 23 | "global.d.ts" 24 | ], 25 | "exclude": [ 26 | "node_modules", 27 | ".vscode-test", 28 | "dist" 29 | ] 30 | } 31 | -------------------------------------------------------------------------------- /tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": { 3 | "no-string-throw": true, 4 | "no-unused-expression": true, 5 | "no-duplicate-variable": true, 6 | "curly": true, 7 | "class-name": true, 8 | "semicolon": [ 9 | true, 10 | "always" 11 | ], 12 | "triple-equals": true 13 | }, 14 | "defaultSeverity": "warning" 15 | } 16 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | 3 | module.exports = { 4 | mode: 'development', 5 | entry: './client/index.js', 6 | output: { 7 | path: path.resolve(__dirname, 'out', 'build'), 8 | filename: 'bundle.js' 9 | }, 10 | module: { 11 | rules: [ 12 | { 13 | test: /.(js|jsx)$/, 14 | exclude: /node_modules/, 15 | use: { 16 | loader: 'babel-loader', 17 | options: { 18 | presets: 19 | [ 20 | '@babel/preset-react', 21 | '@babel/preset-env' 22 | ] 23 | } 24 | } 25 | }, 26 | { 27 | test: /.css$/, 28 | exclude: /node_modules/, 29 | use: ['style-loader', 'css-loader'] 30 | } 31 | ] 32 | }, 33 | resolve: { 34 | extensions: ['*', '.js', '.jsx'] 35 | } 36 | } --------------------------------------------------------------------------------