├── .eslintignore ├── .eslintrc ├── .gitignore ├── .jpmignore ├── .jshintrc ├── .travis.yml ├── README.md ├── chrome.manifest ├── chrome ├── content │ ├── connections-window.xul │ └── inspector-window.xul ├── icons │ └── default │ │ └── rdpinspectorconsole.ico ├── locale │ ├── en-US │ │ ├── connections.properties │ │ ├── inspector.properties │ │ └── toolbox.properties │ ├── nl │ │ ├── inspector.properties │ │ └── toolbox.properties │ ├── pt-BR │ │ ├── inspector.properties │ │ └── toolbox.properties │ └── zh-CN │ │ ├── inspector.properties │ │ └── toolbox.properties └── skin │ └── classic │ └── shared │ ├── icon16.png │ ├── icon32.png │ ├── icon32.svg │ ├── icon64.png │ └── search.svg ├── data ├── .eslintrc ├── connection-list │ ├── actions.js │ ├── components │ │ └── connection-list.js │ ├── config.js │ ├── containers │ │ └── main-panel.js │ ├── css │ │ └── connection-list.css │ ├── index.html │ ├── index.js │ ├── reducers.js │ └── store.js ├── inspector │ ├── actions │ │ ├── actors.js │ │ ├── global.js │ │ ├── index.js │ │ └── packets.js │ ├── components │ │ ├── actors-panel.js │ │ ├── actors-toolbar.js │ │ ├── factories.js │ │ ├── main-tabbed-area.js │ │ ├── packet-details.js │ │ ├── packet-editor.js │ │ ├── packet-list.js │ │ ├── packet-stack-sidepanel.js │ │ ├── packet.js │ │ ├── packets-limit.js │ │ ├── packets-message.js │ │ ├── packets-panel.js │ │ ├── packets-sidebar.js │ │ ├── packets-summary.js │ │ ├── packets-toolbar.js │ │ ├── pools.js │ │ ├── search-box.js │ │ ├── stack-frame-rep.js │ │ ├── text-with-tooltip.js │ │ └── tree-editor-view.js │ ├── config.js │ ├── containers │ │ └── app.js │ ├── css │ │ ├── actors-panel.css │ │ ├── base.css │ │ ├── packets-panel.css │ │ ├── search-box.css │ │ ├── toolbar.css │ │ ├── toolbox.css │ │ └── tree-editor-view.css │ ├── frame-script.js │ ├── main.html │ ├── main.js │ ├── reducers │ │ ├── actors.js │ │ ├── global.js │ │ ├── index.js │ │ └── packets.js │ ├── res │ │ ├── arrow.svg │ │ ├── icon-16.png │ │ ├── received-arrow-selected.png │ │ ├── received-arrow.png │ │ ├── sent-arrow-selected.png │ │ └── sent-arrow.png │ ├── search.js │ └── store.js ├── lib │ ├── bootstrap │ │ ├── css │ │ │ └── bootstrap.css │ │ ├── fonts │ │ │ ├── glyphicons-halflings-regular.eot │ │ │ ├── glyphicons-halflings-regular.svg │ │ │ ├── glyphicons-halflings-regular.ttf │ │ │ ├── glyphicons-halflings-regular.woff │ │ │ └── glyphicons-halflings-regular.woff2 │ │ └── js │ │ │ └── bootstrap.js │ ├── immutable │ │ └── immutable.js │ ├── jquery │ │ └── jquery.js │ ├── react-bootstrap │ │ └── react-bootstrap.js │ ├── react │ │ ├── react-dom.js │ │ └── react.js │ ├── redux │ │ ├── react-redux.js │ │ └── redux.js │ └── requirejs │ │ └── require.js └── shared │ ├── rdp-inspector-window.js │ ├── react-bootstrap-factories.js │ ├── react-helpers.js │ └── resizer.js ├── index.js ├── karma-tests ├── .eslintrc ├── components │ ├── actors-panel-spec.js │ ├── main-tabbed-area-spec.js │ ├── packet-spec.js │ ├── packets-panel-spec.js │ ├── packets-sidebar-spec.js │ └── packets-toolbar-spec.js ├── custom-react-matchers.js ├── lib │ ├── firebug-sdk-shims.js │ └── react-with-addons.js └── test-main.js ├── karma.conf.js ├── lib ├── .eslintrc ├── connection-list-window.js ├── inspector-actor.js ├── inspector-front.js ├── inspector-service.js ├── inspector-window.js ├── main.js ├── start-button.js ├── toolbox-overlay.js ├── transport-observer.js └── webide-connections-monitor.js ├── package.json └── test ├── .eslintrc └── test-inspector-service.js /.eslintignore: -------------------------------------------------------------------------------- 1 | coverage/ 2 | data/lib/ 3 | karma-tests/lib/ 4 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "rules": { 3 | "indent": [2, 2], // check 2 space indentation 4 | "no-mixed-spaces-and-tabs": [2], 5 | "quotes": [2, "double"], 6 | "semi": [1, "always"], 7 | 8 | // disabled rule which enforce unix or windows line breaks 9 | "linebreak-style": [0], 10 | 11 | // disabled comma-dangle is safe for our use case 12 | "comma-dangle": [0], 13 | 14 | // disabled eqeqeq and no-use-before-define are safe if you use them correctly 15 | "eqeqeq": [0], 16 | "no-use-before-define": [0], 17 | }, 18 | "env": { 19 | "es6": true 20 | }, 21 | "globals": { 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Junk that could exist anywhere: 3 | .DS_Store 4 | *.swp 5 | *.tmp 6 | .*.gz 7 | *.patch 8 | *~ 9 | 10 | # Temporary files created by Eclipse 11 | .tmp* 12 | 13 | # Editor junk 14 | *.project 15 | /.pydevproject 16 | /.settings/ 17 | /.settings.xml 18 | /.settings.xml.old 19 | /.idea/ 20 | *.iws 21 | *.ids 22 | *.iml 23 | *.ipr 24 | 25 | # Build Files 26 | /build/ 27 | /release/ 28 | *.graphml 29 | *.xpi 30 | 31 | # Files from NPM 32 | /node_modules/ 33 | 34 | # Extensions 35 | /firebug@software.joehewitt.com 36 | 37 | # Bash 38 | *.sh 39 | *.bat 40 | 41 | # code coverage logs & reports 42 | /coverage/ 43 | 44 | bootstrap.js 45 | install.rdf 46 | npm-debug.log 47 | -------------------------------------------------------------------------------- /.jpmignore: -------------------------------------------------------------------------------- 1 | # Doc Files 2 | /docs/ 3 | README.md 4 | 5 | # Test Files 6 | /test/ 7 | 8 | karma.conf.js 9 | /karma-tests/ 10 | 11 | # GIT 12 | /.git/ 13 | 14 | # exclude hidden files 15 | .* 16 | 17 | # Existing packages 18 | *.xpi 19 | 20 | # npm debug log file 21 | npm-debug.log 22 | 23 | # Excludes npm devDependecies 24 | /node_modules/ 25 | 26 | # Includes firebug.sdk 27 | !/node_modules/firebug.sdk 28 | 29 | # Code Coverage logs & reports 30 | /coverage/ 31 | -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "esnext": "true", 3 | "predef": [ "require", "exports", "module" ], 4 | "curly": "true" 5 | } 6 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | language: node_js 3 | node_js: 4 | - "0.10" 5 | env: 6 | ## Firefox Developer Edition 7 | - FIREFOX_VERSION=aurora-latest 8 | - FIREFOX_VERSION=fx-team 9 | 10 | before_install: 11 | - "export DISPLAY=:99.0" 12 | - "sh -e /etc/init.d/xvfb start" 13 | - "/sbin/start-stop-daemon --start --quiet --pidfile /tmp/custom_xvfb_99.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :99 -ac -screen 0 1280x1024x16 -extension RANDR" 14 | - npm install -g npm 15 | - npm --version 16 | 17 | before_script: 18 | - npm install jpm -g 19 | - '( [[ "$FIREFOX_VERSION" = "fx-team" ]] && npm install mozilla-download -g && mozilla-download --branch fx-team --product firefox $TRAVIS_BUILD_DIR/../ ) || echo "Building on release $FIREFOX_VERSION"' 20 | - '( [[ "$FIREFOX_VERSION" != "fx-team" ]] && wget "https://download.mozilla.org/?product=firefox-$FIREFOX_VERSION-ssl&os=linux64&lang=en-US" -O $TRAVIS_BUILD_DIR/../firefox.tar.bz2 && cd $TRAVIS_BUILD_DIR/../ && tar xvf firefox.tar.bz2 ) || echo "Building on release $FIREFOX_VERSION"' 21 | - cd $TRAVIS_BUILD_DIR 22 | 23 | script: 24 | - export JPM_FIREFOX_BINARY=$TRAVIS_BUILD_DIR/../firefox/firefox 25 | - export FIREFOX_BIN=$JPM_FIREFOX_BINARY 26 | - npm run travis-ci 27 | - npm run jpm-tests 28 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | RDP Inspector 2 | ============= 3 | Remote debugger protocol inspector 4 | 5 | Instructions 6 | ------------ 7 | You should see a new RDP Inspector button at the top-right corner of your 8 | browser window after installation. Click the icon to open RDP Inspector 9 | console and operate developer tools Toolbox to generate some traffic 10 | over RDP. Sent and received packets are visible in the console window. 11 | 12 | * [Learn more](https://github.com/firebug/rdp-inspector/wiki) 13 | * [Download](https://github.com/firebug/rdp-inspector/releases) 14 | 15 | Further Resources 16 | ----------------- 17 | * Remote Debugging Protocol: https://wiki.mozilla.org/Remote_Debugging_Protocol 18 | * Add-on SDK: https://developer.mozilla.org/en-US/Add-ons/SDK 19 | * DevTools API: https://developer.mozilla.org/en-US/docs/Tools/DevToolsAPI 20 | * Coding Style: https://github.com/mozilla/addon-sdk/wiki/Coding-style-guide 21 | * DevTools Extension Examples: https://github.com/firebug/devtools-extension-examples 22 | * DevTools/Hacking: https://wiki.mozilla.org/DevTools/Hacking 23 | -------------------------------------------------------------------------------- /chrome.manifest: -------------------------------------------------------------------------------- 1 | content rdpinspector chrome/content/ 2 | skin rdpinspector classic/1.0 chrome/skin/classic/shared/ 3 | skin rdpinspector-firebug.sdk classic/1.0 node_modules/firebug.sdk/skin/classic/shared/ 4 | 5 | locale rdpinspector en-US chrome/locale/en-US/ 6 | locale rdpinspector zh-CN chrome/locale/zh-CN/ 7 | locale rdpinspector nl chrome/locale/nl/ 8 | locale rdpinspector pt-BR chrome/locale/pt-BR/ 9 | 10 | locale rdpinspector-firebug.sdk en-US node_modules/firebug.sdk/locale/en-US/ 11 | locale rdpinspector-firebug.sdk zh-CN node_modules/firebug.sdk/locale/zh-CN/ 12 | locale rdpinspector-firebug.sdk nl node_modules/firebug.sdk/locale/nl/ 13 | locale rdpinspector-firebug.sdk pt-BR node_modules/firebug.sdk/locale/pt-BR/ 14 | -------------------------------------------------------------------------------- /chrome/content/connections-window.xul: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 15 | 16 | 17 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /chrome/content/inspector-window.xul: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 14 | 15 | 16 | 46 | 47 | 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /chrome/icons/default/rdpinspectorconsole.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firebug/rdp-inspector/60b22d880d9ea334e638b14c69102e8ed5c5c1e6/chrome/icons/default/rdpinspectorconsole.ico -------------------------------------------------------------------------------- /chrome/locale/en-US/connections.properties: -------------------------------------------------------------------------------- 1 | # LOCALIZATION NOTE (rdpConnections.tab.LocalTabs, rdpConnections.tab.WebIDE) 2 | # A label for "Connect To..." window tabs. 3 | rdpConnections.tab.LocalTabs=Local Tabs 4 | rdpConnections.tab.WebIDE=WebIDE 5 | -------------------------------------------------------------------------------- /chrome/locale/en-US/inspector.properties: -------------------------------------------------------------------------------- 1 | # LOCALIZATION NOTE (rdpInspector.tab.Packets, rdpInspector.tab.Actors) 2 | # A label for main application tabs. 3 | rdpInspector.tab.Packets=Packets 4 | rdpInspector.tab.Actors=Actors 5 | 6 | # LOCALIZATION NOTE (rdpInspector.option.showInlineDetails, 7 | # rdpInspector.option.showInlineDetails): Label and 8 | # tooltip for an option that can be set within the Packets tab. If set to true 9 | # every packet display inline preview of packet properties (collapsed 10 | # by default) 11 | rdpInspector.option.showInlineDetails=Show Packet Details Inline 12 | rdpInspector.option.showInlineDetails.tip=Show a detailed tree view of the Packet content. 13 | 14 | # LOCALIZATION NOTE (rdpInspector.option.packetCacheEnabled, rdpInspector.options.packetCacheEnabled.tip): Label and 15 | # tooltip for an option that can be set within the Packets tab. If set to true 16 | # the inspector caches packets that are sent/received before the 17 | # inspector window is opened (to see also packets that happens 18 | # at the very beginning) 19 | rdpInspector.option.packetCacheEnabled=Packet Cache 20 | rdpInspector.option.packetCacheEnabled.tip=Store packets in a cache before the console is opened. 21 | 22 | # LOCALIZATION NOTE (rdpInspector.cmd.clear): Label for a toolbar button 23 | # in the Packets tab. This command clears the packet list. 24 | rdpInspector.cmd.clear=Clear 25 | 26 | # LOCALIZATION NOTE (rdpInspector.cmd.find): Label for a toolbar button 27 | # in the Packets tab. This command opens standard Find bar at the bottom 28 | # of the Inspector window. 29 | rdpInspector.cmd.find=Find 30 | 31 | # LOCALIZATION NOTE (rdpInspector.cmd.summary): Label for a toolbar button 32 | # in the Packets tab. This command inserts a summary separator in the 33 | # packets list. 34 | rdpInspector.cmd.summary=Summary 35 | 36 | # LOCALIZATION NOTE (rdpInspector.tooltip.sizeSent, rdpInspector.tooltip.sizeReceived, 37 | # rdpInspector.tooltip.packetsSent, rdpInspector.tooltip.packetsReceived): 38 | # A tooltip for summary info in the packet list. 39 | rdpInspector.tooltip.sizeSent=Total amount of data sent to the debugger server 40 | rdpInspector.tooltip.sizeReceived=Total amount of data received from the debugger server 41 | rdpInspector.tooltip.packetsSent=Number of packets sent to the debugger server 42 | rdpInspector.tooltip.packetsReceived=Number of packets received from the debugger server 43 | 44 | # LOCALIZATION NOTE (rdpInspector.label.packets, rdpInspector.label.data) 45 | # A label for summary info in the packet list. 46 | rdpInspector.label.packets=Packets 47 | rdpInspector.label.data=Data 48 | 49 | # LOCALIZATION NOTE (rdpInspector.cmd.refresh) A label used on Actor's 50 | # tab toolbar. It's used to refresh the tab's content. 51 | rdpInspector.cmd.refresh=Refresh 52 | 53 | # LOCALIZATION NOTE (rdpInspector.label.sent, rdpInspector.label.to, 54 | # rdpInspector.label.received, rdpInspector.label.from): A label for 55 | # packets displayed in the packet list. 56 | rdpInspector.label.sent=Sent 57 | rdpInspector.label.to=to 58 | rdpInspector.label.received=Received 59 | rdpInspector.label.from=from 60 | 61 | # LOCALIZATION NOTE (rdpInspector.label.outOfLimit) A label displayed 62 | # at the top of the packet list in case the number of displayed packets 63 | # reached maximum limit. 64 | rdpInspector.label.outOfLimit=packets removed 65 | 66 | # LOCALIZATION NOTE (rdpInspector.label.Paused, rdpInspector.label.Unpaused): 67 | # A label used for pause/unpause packet collecting. The label is for a message 68 | # that is printed into the packet list when the user click the Pause button 69 | # in the toolbar. 70 | rdpInspector.label.Paused=Paused 71 | rdpInspector.label.Unpaused=Unpaused 72 | 73 | # LOCALIZATION NOTE (rdpInspector.label.MainProcess, rdpInspector.label.ChildProcess, 74 | # rdpInspector.ActorsFactories): 75 | # Labels used for the actors sub-panel selector in the actors panel toolbar. 76 | rdpInspector.label.MainProcess=Main Process 77 | rdpInspector.label.ChildProcess=Child Process 78 | rdpInspector.label.ActorsFactories=Actors Factories 79 | 80 | # LOCALIZATION NOTE (rdpInspector.menu.File, rdpInspector.menu.Options, 81 | # rdpInspector.cmd.load, rdpInspector.cmd.save): 82 | # Labels for the dropdown menus in the packets panel toolbar. 83 | rdpInspector.menu.File=File 84 | rdpInspector.menu.Options=Options 85 | rdpInspector.cmd.load=Load 86 | rdpInspector.cmd.save=Save 87 | -------------------------------------------------------------------------------- /chrome/locale/en-US/toolbox.properties: -------------------------------------------------------------------------------- 1 | # LOCALIZATION NOTE (rdpInspector.title): RDP Inspector extension title 2 | rdpInspector.title=RDP Inspector 3 | 4 | # LOCALIZATION NOTE (rdpInspector.button.title, rdpInspector.button.tip): 5 | # Label and a tooltip for RDP Inspector start button available in the 6 | # Firefox toolbar and Style Editor panel. This button opens RDP Inspector 7 | # window. 8 | rdpInspector.startButton.title=RDP Inspector 9 | rdpInspector.startButton.tip=Remote debugging protocol inspector. 10 | 11 | # LOCALIZATION NOTE (rdpInspector.menu.about.label, rdpInspector.menu.about.tip): 12 | # RDP Inspector menu label. The menu is available in RDP Inspector start 13 | # button located in Firefox toolbar. 14 | rdpInspector.menu.about.label=About RDP Inspector... 15 | rdpInspector.menu.about.tip=Information about RDP Inspector 16 | 17 | # LOCALIZATION NOTE (rdpInspector.menu.visitHomePage.label, rdpInspector.menu.visitHomePage.tip): 18 | # RDP Inspector menu label. The menu is available in RDP Inspector start 19 | # button located in Firefox toolbar. 20 | rdpInspector.menu.visitHomePage.label=Visit Home Page... 21 | rdpInspector.menu.visitHomePage.tip=Learn more about RDP Inspector 22 | 23 | # LOCALIZATION NOTE (rdpInspector.menu.reportIssue.label, rdpInspector.menu.reportIssue.tip): 24 | # RDP Inspector menu label. The menu is available in RDP Inspector start 25 | # button located in Firefox toolbar. 26 | rdpInspector.menu.reportIssue.label=Report Issue... 27 | rdpInspector.menu.reportIssue.tip=Did you find a bug or do you need a new feature? Let us know! 28 | 29 | # LOCALIZATION NOTE (rdpInspector.menu.group.label, rdpInspector.menu.group.tip): 30 | # RDP Inspector menu label. The menu is available in RDP Inspector start 31 | # button located in Firefox toolbar. 32 | rdpInspector.menu.group.label=Discussion Group... 33 | rdpInspector.menu.group.tip=Open the discussion group site (shared with Firebug) 34 | 35 | # LOCALIZATION NOTE (rdpInspector.menu.options.label): 36 | # RDP Inspector menu label. The menu is available in RDP Inspector start button locate in Firefox toolbar. 37 | rdpInspector.menu.options.label=Options 38 | 39 | # LOCALIZATION NOTE (rdpInspector.menu.packetCache.label,rdpInspector.menu.packetCache.tip): 40 | # RDP Inspector menu label. The menu is available in RDP Inspector start 41 | # button located in Firefox toolbar, inside the Options sub-menu. 42 | rdpInspector.menu.packetCache.label=Packet Cache 43 | rdpInspector.menu.packetCache.tip=Store packets in a cache before the console is opened. 44 | 45 | # LOCALIZATION NOTE (rdpInspector.menu.showInlineDetails.label,rdpInspector.menu.showInlineDetails.tip): 46 | # RDP Inspector menu label. The menu is available in RDP Inspector start 47 | # button located in Firefox toolbar, inside the Options sub-menu. 48 | rdpInspector.menu.showInlineDetails.label=Show Packet Details Inline 49 | rdpInspector.menu.showInlineDetails.tip=Show a detailed tree view of the Packet content. 50 | 51 | # LOCALIZATION NOTE (rdpInspector.menu.autoOpenOnWebIDEConnection.label,rdpInspector.menu.autoOpenOnWebIDEConnection.tip): 52 | # RDP Inspector menu label. The menu is available in RDP Inspector start 53 | # button located in Firefox toolbar, inside the Options sub-menu. 54 | rdpInspector.menu.autoOpenOnWebIDEConnection.label=Open automatically on new WebIDE connections 55 | rdpInspector.menu.autoOpenOnWebIDEConnection.tip=Open an RDP inspector window automatically on every new WebIDE connections. 56 | 57 | # LOCALIZATION NOTE (rdpInspector.menu.connectionList.label, rdpInspector.menu.connectionList.tip): 58 | # RDP Inspector menu label. The menu is available in RDP Inspector start 59 | # button located in Firefox toolbar. 60 | rdpInspector.menu.connectionList.label=Connect to... 61 | rdpInspector.menu.connectionList.tip=Open a dialog which lists all the RDP Connections available to the RDPInspector 62 | -------------------------------------------------------------------------------- /chrome/locale/nl/inspector.properties: -------------------------------------------------------------------------------- 1 | rdpInspector.option.showInlineDetails=Pakketdetails inline weergeven 2 | rdpInspector.option.hideInlineDetails=Pakketdetails inline verbergen 3 | rdpInspector.option.cachePackets=Pakketten bufferen voordat de inspecteur wordt geopend 4 | rdpInspector.cmd.clear=Wissen 5 | rdpInspector.cmd.find=Zoeken 6 | rdpInspector.cmd.summary=Samenvatting 7 | rdpInspector.tooltip.sizeSent=Totaal aantal naar de foutopsporingsserver verstuurde gegevens 8 | rdpInspector.tooltip.sizeReceived=Totaal aantal van de foutopsporingsserver ontvangen gegevens 9 | rdpInspector.tooltip.packetsSent=Aantal naar de foutopsporingsserver verstuurde pakketten 10 | rdpInspector.tooltip.packetsReceived=Aantal van de foutopsporingsserver ontvangen pakketten 11 | rdpInspector.label.packets=Pakketten 12 | rdpInspector.label.data=Gegevens 13 | rdpInspector.cmd.refresh=Vernieuwen 14 | -------------------------------------------------------------------------------- /chrome/locale/nl/toolbox.properties: -------------------------------------------------------------------------------- 1 | rdpInspector.title=RDP Inspector 2 | rdpInspector.startButton.title=RDP-inspecteur 3 | rdpInspector.startButton.tip=Protocolinspecteur voor foutopsporing op afstand. 4 | rdpInspector.menu.about.label=Over RDP Inspector… 5 | rdpInspector.menu.about.tip=Informatie over RDP Inspector 6 | rdpInspector.menu.visitHomePage.label=Startpagina bezoeken… 7 | rdpInspector.menu.visitHomePage.tip=Lees meer over RDP Inspector 8 | rdpInspector.menu.reportIssue.label=Probleem melden… 9 | rdpInspector.menu.reportIssue.tip=Hebt u een bug gevonden of zou u graag een nieuwe functie zien? Laat het ons weten! 10 | rdpInspector.menu.group.label=Discussiegroep… 11 | rdpInspector.menu.group.tip=De website van de discussiegroep (gedeeld met Firebug) openen 12 | -------------------------------------------------------------------------------- /chrome/locale/pt-BR/inspector.properties: -------------------------------------------------------------------------------- 1 | rdpInspector.option.showInlineDetails=Exibir detalhes do pacote 2 | rdpInspector.option.hideInlineDetails=Ocultar detalhes do pacote 3 | rdpInspector.option.cachePackets=Pacotes da cache antes do inspector ser aberto 4 | rdpInspector.cmd.clear=Limpar 5 | rdpInspector.cmd.find=Procurar 6 | rdpInspector.cmd.summary=Resumo 7 | rdpInspector.tooltip.sizeSent=A quantidade total de dados enviado para o servidor depurador 8 | rdpInspector.tooltip.sizeReceived=Quantidade total de dados recebidos do servidor depurador 9 | rdpInspector.tooltip.packetsSent=O número de pacotes enviada para o servidor depurador 10 | rdpInspector.tooltip.packetsReceived=Número de pacotes recebidos a partir do servidor depurador 11 | rdpInspector.label.packets=Pacotes 12 | rdpInspector.label.data=Dados 13 | rdpInspector.cmd.refresh=Recarregar 14 | -------------------------------------------------------------------------------- /chrome/locale/pt-BR/toolbox.properties: -------------------------------------------------------------------------------- 1 | rdpInspector.title=RDP Inspector 2 | rdpInspector.startButton.title=RDP Inspector 3 | rdpInspector.startButton.tip=Inspetor de protocolo de depuração remota. 4 | rdpInspector.menu.about.label=Sobre o RDP Inspector 5 | rdpInspector.menu.about.tip=Informações sobre o RDP Inspector 6 | rdpInspector.menu.visitHomePage.label=Visite a Página Principal… 7 | rdpInspector.menu.visitHomePage.tip=Saiba mais sobre o RDP Inspector 8 | rdpInspector.menu.reportIssue.label=Relatório do problema… 9 | rdpInspector.menu.reportIssue.tip=Encontrou um bug ou precisa de um novo recurso? Nos informe! 10 | rdpInspector.menu.group.label=Grupo de discussão… 11 | rdpInspector.menu.group.tip=Abrir o site do grupo de discussão (compartilhado com o Firebug) 12 | -------------------------------------------------------------------------------- /chrome/locale/zh-CN/inspector.properties: -------------------------------------------------------------------------------- 1 | rdpInspector.option.showInlineDetails=显示数据包的详细信息 2 | rdpInspector.option.hideInlineDetails=隐藏数据包的详细信息 3 | rdpInspector.option.cachePackets=在探查器打开前缓存数据包 4 | rdpInspector.cmd.clear=清空 5 | rdpInspector.cmd.find=查找 6 | rdpInspector.cmd.summary=摘要 7 | rdpInspector.tooltip.sizeSent=向调试器服务器发送数据的总量 8 | rdpInspector.tooltip.sizeReceived=从调试器服务器接收数据的总量 9 | rdpInspector.tooltip.packetsSent=向调试器服务器发送的数据包数量 10 | rdpInspector.tooltip.packetsReceived=从调试器服务器接收的数据包数量 11 | rdpInspector.label.packets=数据包 12 | rdpInspector.label.data=数据 13 | rdpInspector.cmd.refresh=刷新 14 | -------------------------------------------------------------------------------- /chrome/locale/zh-CN/toolbox.properties: -------------------------------------------------------------------------------- 1 | rdpInspector.title=RDP Inspector 2 | rdpInspector.startButton.title=RDP Inspector 3 | rdpInspector.startButton.tip=远程调试协议探查器。 4 | rdpInspector.menu.about.label=关于 RDP Inspector... 5 | rdpInspector.menu.about.tip=有关 RDP Inspector 的信息 6 | rdpInspector.menu.visitHomePage.label=访问主页... 7 | rdpInspector.menu.visitHomePage.tip=详细了解有关 RDP Inspector 8 | rdpInspector.menu.reportIssue.label=报告问题... 9 | rdpInspector.menu.reportIssue.tip=您遇到了 bug?或是有关于新功能的点子?告诉我们吧! 10 | rdpInspector.menu.group.label=讨论组... 11 | rdpInspector.menu.group.tip=打开讨论组网站 (与 Firebug 共享) 12 | -------------------------------------------------------------------------------- /chrome/skin/classic/shared/icon16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firebug/rdp-inspector/60b22d880d9ea334e638b14c69102e8ed5c5c1e6/chrome/skin/classic/shared/icon16.png -------------------------------------------------------------------------------- /chrome/skin/classic/shared/icon32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firebug/rdp-inspector/60b22d880d9ea334e638b14c69102e8ed5c5c1e6/chrome/skin/classic/shared/icon32.png -------------------------------------------------------------------------------- /chrome/skin/classic/shared/icon64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firebug/rdp-inspector/60b22d880d9ea334e638b14c69102e8ed5c5c1e6/chrome/skin/classic/shared/icon64.png -------------------------------------------------------------------------------- /chrome/skin/classic/shared/search.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 14 | 16 | 18 | 22 | 26 | 27 | 29 | 33 | 37 | 38 | 45 | 48 | 49 | 57 | 65 | 66 | 68 | 69 | 71 | image/svg+xml 72 | 74 | 75 | 76 | 77 | 78 | 82 | 86 | 87 | -------------------------------------------------------------------------------- /data/.eslintrc: -------------------------------------------------------------------------------- 1 | // extends common eslintrc config with "javascript running in a content context" specific configs 2 | { 3 | "extends": "../.eslintrc", 4 | "plugins": [ 5 | // prevents tab whitespace when 'indent' rule is disabled 6 | "no-tabs", 7 | "react" 8 | ], 9 | "env": { 10 | // enable browser & amd conventions 11 | "browser": true, 12 | "amd": true 13 | }, 14 | "rules": { 15 | // disabled due to conflicts with special indentation in requirejs modules 16 | "indent": 0, 17 | // prevents any usage of tab whitespaces 18 | "no-tabs/at-all": [2], 19 | 20 | // force definition of displayName on React components 21 | "react/display-name": 2, 22 | 23 | // TODO: force propTypes on React Components 24 | "react/prop-types": 0, 25 | 26 | // disabled due to conflicts with capitalized React components names 27 | "new-cap": [0], 28 | }, 29 | "globals": {} 30 | } 31 | -------------------------------------------------------------------------------- /data/connection-list/actions.js: -------------------------------------------------------------------------------- 1 | /* See license.txt for terms of usage */ 2 | 3 | define(function(require, exports, module) { 4 | 5 | "use strict"; 6 | 7 | const types = { 8 | SET_CONNECTIONS: "SET_CONNECTIONS" 9 | }; 10 | 11 | // export actions types and action creators 12 | module.exports = { 13 | types, 14 | 15 | setConnections(connections) { 16 | return { type: types.SET_CONNECTIONS, connections }; 17 | } 18 | }; 19 | 20 | }); 21 | -------------------------------------------------------------------------------- /data/connection-list/components/connection-list.js: -------------------------------------------------------------------------------- 1 | /* See license.txt for terms of usage */ 2 | 3 | define(function(require, exports/*, module*/) { 4 | 5 | "use strict"; 6 | 7 | // ReactJS 8 | const React = require("react"); 9 | 10 | // React Bootstrap factories 11 | const { 12 | ListGroup, ListGroupItem, 13 | Tabs, Tab 14 | } = require("shared/react-bootstrap-factories"); 15 | 16 | const ConnectionsGroup = React.createClass({ 17 | displayName: "ConnectionsGroup", 18 | 19 | render() { 20 | let connections = this.props.connections.map((conn) => { 21 | return ListGroupItem({ 22 | style: { width: "100%" }, 23 | onClick: (evt) => { 24 | this.props.onConnectionClick(conn, evt); 25 | } 26 | }, conn.name); 27 | }); 28 | 29 | return ListGroup({ style: { width: "100%" } }, connections); 30 | } 31 | }); 32 | 33 | exports.ConnectionList = React.createClass({ 34 | displayName: "ConnectionList", 35 | 36 | render() { 37 | const connections = this.props.connections || {}; 38 | 39 | // turn the first level (connections group) into a ConnectionsGroups components 40 | const connectionsGroups = Object.keys(connections).map((groupName, i) => { 41 | return Tab({ 42 | key: groupName, 43 | title: connections[groupName].label, 44 | eventKey: i + 1, 45 | style: { overflow: "auto" } 46 | }, React.createElement(ConnectionsGroup, { 47 | onConnectionClick: this.props.onConnectionClick, 48 | connections: connections[groupName].connections 49 | })); 50 | }); 51 | 52 | return Tabs({ 53 | className: "mainTabbedArea", 54 | defaultActiveKey: 1, animation: false 55 | }, connectionsGroups); 56 | } 57 | }); 58 | 59 | }); 60 | -------------------------------------------------------------------------------- /data/connection-list/config.js: -------------------------------------------------------------------------------- 1 | /* See license.txt for terms of usage */ 2 | 3 | /* globals requirejs */ 4 | 5 | // RequireJS configuration 6 | require.config({ 7 | baseUrl: ".", 8 | scriptType: "application/javascript;version=1.8", 9 | paths: { 10 | "shared": "../shared", 11 | "jquery": "../lib/jquery/jquery", 12 | "react": "../lib/react/react", 13 | "react-dom": "../lib/react/react-dom", 14 | "bootstrap": "../lib/bootstrap/js/bootstrap", 15 | "immutable": "../lib/immutable/immutable", 16 | "react-bootstrap": "../lib/react-bootstrap/react-bootstrap", 17 | "reps": "../../node_modules/firebug.sdk/lib/reps", 18 | "firebug.sdk": "../../node_modules/firebug.sdk", 19 | "redux": "../lib/redux/redux", 20 | "react-redux": "../lib/redux/react-redux", 21 | } 22 | }); 23 | 24 | // Load the main panel module 25 | requirejs(["index"]); 26 | -------------------------------------------------------------------------------- /data/connection-list/containers/main-panel.js: -------------------------------------------------------------------------------- 1 | /* See license.txt for terms of usage */ 2 | 3 | define(function(require, exports/*, module*/) { 4 | 5 | "use strict"; 6 | 7 | // React & Redux 8 | const React = require("react"); 9 | const { connect } = require("react-redux"); 10 | 11 | // Connections List components 12 | const { ConnectionList } = require("../components/connection-list"); 13 | 14 | const MainPanel = React.createClass({ 15 | displayName: "MainPanel", 16 | 17 | render() { 18 | return React.createElement(ConnectionList, { 19 | connections: this.props.connections, 20 | onConnectionClick: this.props.onConnectionClick 21 | }); 22 | } 23 | }); 24 | 25 | function mapStoreToProps(state) { 26 | let { connections } = state; 27 | return { connections }; 28 | } 29 | 30 | exports.MainPanel = connect(mapStoreToProps)(MainPanel); 31 | 32 | }); 33 | -------------------------------------------------------------------------------- /data/connection-list/css/connection-list.css: -------------------------------------------------------------------------------- 1 | /* See license.txt for terms of usage */ 2 | 3 | /******************************************************************************/ 4 | /* Connection List Window */ 5 | 6 | .tab-content .list-group-item { 7 | border-radius: 0; 8 | } 9 | 10 | .tab-content .list-group-item:first-child { 11 | border-top: 0; 12 | } 13 | -------------------------------------------------------------------------------- /data/connection-list/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | -------------------------------------------------------------------------------- /data/connection-list/index.js: -------------------------------------------------------------------------------- 1 | /* See license.txt for terms of usage */ 2 | 3 | define(function(require/*, exports, module*/) { 4 | 5 | "use strict"; 6 | 7 | // React 8 | var ReactDOM = require("react-dom"); 9 | 10 | // RDP Inspector 11 | const { Resizer } = require("shared/resizer"); 12 | const { ReactLazyFactories } = require("shared/react-helpers"); 13 | const { RDPConnectionList } = require("shared/rdp-inspector-window"); 14 | 15 | // generate React Factories 16 | const { Provider } = ReactLazyFactories(require("react-redux")); 17 | const { MainPanel } = ReactLazyFactories(require("./containers/main-panel")); 18 | 19 | // actions & store 20 | const actions = require("./actions"); 21 | const store = require("./store").configureStore(); 22 | 23 | function render() { 24 | let content = document.querySelector("#content"); 25 | let provider = Provider({ store }, MainPanel({ 26 | onConnectionClick: (conn) => { 27 | RDPConnectionList.openRDPInspectorWindow(conn); 28 | } 29 | })); 30 | let app = ReactDOM.render(provider, content); 31 | return new Resizer(window, app); 32 | } 33 | 34 | function updateConnections() { 35 | let connections = RDPConnectionList.getConnectionsInfo(); 36 | store.dispatch(actions.setConnections(connections)); 37 | } 38 | 39 | render(); 40 | updateConnections(); 41 | RDPConnectionList.onConnectionsUpdated.addListener(updateConnections); 42 | 43 | }); 44 | -------------------------------------------------------------------------------- /data/connection-list/reducers.js: -------------------------------------------------------------------------------- 1 | /* See license.txt for terms of usage */ 2 | 3 | define(function(require, exports/*, module*/) { 4 | 5 | "use strict"; 6 | 7 | // actions types 8 | const { types } = require("./actions"); 9 | 10 | /** 11 | * Initial state definition 12 | */ 13 | const initialState = {}; 14 | 15 | function connections(state = initialState, action) { 16 | switch(action.type) { 17 | case types.SET_CONNECTIONS: 18 | return action.connections; 19 | default: 20 | return state; 21 | } 22 | } 23 | 24 | // Export combined reducers 25 | 26 | // Redux 27 | const { combineReducers } = require("redux"); 28 | 29 | exports.rootReducer = combineReducers({ 30 | connections 31 | }); 32 | 33 | }); 34 | -------------------------------------------------------------------------------- /data/connection-list/store.js: -------------------------------------------------------------------------------- 1 | /* See license.txt for terms of usage */ 2 | 3 | define(function(require, exports/*, module*/) { 4 | 5 | "use strict"; 6 | 7 | // Redux 8 | const { createStore } = require("redux"); 9 | 10 | // RDP Inspector 11 | const { rootReducer } = require("./reducers"); 12 | 13 | function configureStore(initialState) { 14 | return createStore(rootReducer, initialState); 15 | } 16 | 17 | // Exports from this module 18 | exports.configureStore = configureStore; 19 | 20 | }); 21 | -------------------------------------------------------------------------------- /data/inspector/actions/actors.js: -------------------------------------------------------------------------------- 1 | /* See license.txt for terms of usage */ 2 | 3 | define(function(require, exports, module) { 4 | 5 | "use strict"; 6 | 7 | const types = { 8 | SET_ACTORS: "SET_ACTORS", 9 | CLEAR_ACTORS: "CLEAR_ACTORS" 10 | }; 11 | 12 | // export actions types and action creators 13 | module.exports = { 14 | types, 15 | 16 | setActors(actors) { 17 | return { type: types.SET_ACTORS, actors }; 18 | }, 19 | 20 | clearActors() { 21 | return { type: types.CLEAR_ACTORS }; 22 | }, 23 | }; 24 | 25 | }); 26 | -------------------------------------------------------------------------------- /data/inspector/actions/global.js: -------------------------------------------------------------------------------- 1 | /* See license.txt for terms of usage */ 2 | 3 | define(function(require, exports, module) { 4 | 5 | "use strict"; 6 | 7 | const types = { 8 | SET_SEARCH_FILTER: "SET_SEARCH_FILTER", 9 | }; 10 | 11 | // export actions types and action creators 12 | module.exports = { 13 | types, 14 | 15 | setSearchFilter(filter) { 16 | return { type: types.SET_SEARCH_FILTER, filter }; 17 | }, 18 | }; 19 | 20 | }); 21 | -------------------------------------------------------------------------------- /data/inspector/actions/index.js: -------------------------------------------------------------------------------- 1 | /* See license.txt for terms of usage */ 2 | 3 | define(function(require, exports, module) { 4 | 5 | "use strict"; 6 | 7 | const global = require("./global"); 8 | const actors = require("./actors"); 9 | const packets = require("./packets"); 10 | 11 | module.exports = Object.assign({}, global, actors, packets, { 12 | types: Object.assign({}, actors.types, packets.types) 13 | }); 14 | 15 | }); 16 | -------------------------------------------------------------------------------- /data/inspector/actions/packets.js: -------------------------------------------------------------------------------- 1 | /* See license.txt for terms of usage */ 2 | 3 | define(function(require, exports, module) { 4 | 5 | "use strict"; 6 | 7 | const types = { 8 | IMPORT_PACKETS_CACHE: "IMPORT_PACKETS_CACHE", 9 | IMPORT_PACKETS_FROMFILE: "IMPORTS_PACKETS_FROMFILE", 10 | INIT_PACKETLIST_OPTIONS: "INIT_PACKETLIST_OPTIONS", 11 | APPEND_PACKET: "APPEND_PACKET", 12 | APPEND_SUMMARY: "APPEND_SUMMARY", 13 | APPEND_MESSAGE: "APPEND_MESSAGE", 14 | EDIT_PACKET: "EDIT_PACKET", 15 | SELECT_PACKET: "SELECT_PACKET", 16 | CLEAR_PACKET_LIST: "CLEAR_PACKET_LIST", 17 | SET_PACKET_FILTER: "SET_PACKET_FILTER", 18 | TOGGLE_PACKETLIST_OPTION: "TOGGLE_PACKETLIST_OPTION", 19 | TOGGLE_PACKETLIST_PAUSE: "TOGGLE_PACKETLIST_PAUSE", 20 | SET_PACKETLIST_ERROR: "SET_PACKETLIST_ERROR", 21 | }; 22 | 23 | // export actions types and action creators 24 | module.exports = { 25 | types, 26 | 27 | importPacketsCache(cache) { 28 | return { type: types.IMPORT_PACKETS_CACHE, cache }; 29 | }, 30 | 31 | importPacketsFromFile(data) { 32 | return { type: types.IMPORT_PACKETS_FROMFILE, data }; 33 | }, 34 | 35 | initPacketListOptions(options) { 36 | return { type: types.INIT_PACKETLIST_OPTIONS, options }; 37 | }, 38 | 39 | appendPacket(packetType, packetData) { 40 | return { type: types.APPEND_PACKET, packetType, packetData }; 41 | }, 42 | 43 | appendSummary() { 44 | let time = new Date(); 45 | return { type: types.APPEND_SUMMARY, time }; 46 | }, 47 | 48 | appendMessage(message) { 49 | let time = new Date(); 50 | return { type: types.APPEND_MESSAGE, message, time }; 51 | }, 52 | 53 | editPacket(packet) { 54 | return { type: types.EDIT_PACKET, packet }; 55 | }, 56 | 57 | selectPacket(packet) { 58 | return { type: types.SELECT_PACKET, packet }; 59 | }, 60 | 61 | clearPacketList() { 62 | return { type: types.CLEAR_PACKET_LIST }; 63 | }, 64 | 65 | togglePacketListOption(name) { 66 | return { type: types.TOGGLE_PACKETLIST_OPTION, name }; 67 | }, 68 | 69 | togglePacketListPause() { 70 | return { type: types.TOGGLE_PACKETLIST_PAUSE }; 71 | }, 72 | 73 | setPacketListError(error) { 74 | return { type: types.SET_PACKETLIST_ERROR, error }; 75 | } 76 | 77 | }; 78 | 79 | }); 80 | -------------------------------------------------------------------------------- /data/inspector/components/actors-panel.js: -------------------------------------------------------------------------------- 1 | /* See license.txt for terms of usage */ 2 | 3 | define(function(require, exports/*, module*/) { 4 | 5 | "use strict"; 6 | 7 | // Dependencies 8 | const React = require("react"); 9 | 10 | // RDP Inspector 11 | const { ActorsToolbar } = require("./actors-toolbar"); 12 | 13 | const { Locale } = require("shared/rdp-inspector-window"); 14 | 15 | // Shortcuts 16 | const { tr, td, table, tbody, thead, th, div, h4 } = React.DOM; 17 | 18 | const GLOBAL_ACTORS_POOLS = "global-actors-pool"; 19 | const TAB_ACTORS_POOLS = "tab-actors-pool"; 20 | const ACTORS_FACTORIES = "actors-factories"; 21 | 22 | var PanelTypesLabels = {}; 23 | PanelTypesLabels[GLOBAL_ACTORS_POOLS] = Locale.$STR("rdpInspector.label.MainProcess"); 24 | PanelTypesLabels[TAB_ACTORS_POOLS] = Locale.$STR("rdpInspector.label.ChildProcess"); 25 | PanelTypesLabels[ACTORS_FACTORIES] = Locale.$STR("rdpInspector.label.ActorsFactories"); 26 | 27 | /** 28 | * @template This template renders 'Actors' tab body. 29 | */ 30 | var ActorsPanel = React.createClass({ 31 | /** @lends ActorsPanel */ 32 | 33 | displayName: "ActorsPanel", 34 | 35 | getInitialState: function() { 36 | return { 37 | panelType: GLOBAL_ACTORS_POOLS 38 | }; 39 | }, 40 | 41 | render: function() { 42 | var { actors } = this.props; 43 | var { panelType } = this.state; 44 | 45 | var el; 46 | 47 | switch(panelType) { 48 | case GLOBAL_ACTORS_POOLS: 49 | el = ActorsPools({ 50 | data: (actors && actors.global), 51 | key: "global", 52 | searchFilter: this.props.searchFilter 53 | }); 54 | break; 55 | case TAB_ACTORS_POOLS: 56 | el = ActorsPools({ 57 | data: (actors && actors.tab), 58 | key: "tab", 59 | searchFilter: this.props.searchFilter 60 | }); 61 | break; 62 | case ACTORS_FACTORIES: 63 | el = ActorsFactories({ 64 | key: "factories", 65 | data: { 66 | global: actors && actors.global, 67 | tab: actors && actors.tab 68 | }, 69 | searchFilter: this.props.searchFilter 70 | }); 71 | break; 72 | } 73 | 74 | return ( 75 | div({ className: "actorsPanelBox" }, 76 | ActorsToolbar({ actions: this.props.actions, 77 | currentPanelType: panelType, 78 | panelTypesLabels: PanelTypesLabels, 79 | onPanelTypeSelected: this.onPanelTypeSelected 80 | }), 81 | div({ className: "actorsScrollBox" }, el) 82 | ) 83 | ); 84 | }, 85 | 86 | onPanelTypeSelected: function(panelType) { 87 | this.setState({ 88 | panelType: panelType 89 | }); 90 | } 91 | }); 92 | 93 | /** 94 | * @template This template renders 'ActorsPools' list in the tab content. 95 | */ 96 | var ActorsPools = React.createFactory(React.createClass({ 97 | /** @lends ActorsPools */ 98 | 99 | displayName: "ActorsPools", 100 | 101 | render: function() { 102 | var pools = []; 103 | 104 | if (this.props.data) { 105 | var { actorPool, extraPools } = this.props.data; 106 | pools = pools.concat(actorPool, extraPools); 107 | } 108 | 109 | var poolTables = pools.map((poolData) => { 110 | var pool = poolData.pool; 111 | var poolId = poolData.id; 112 | var actorClass = false; 113 | 114 | if (!Array.isArray(pool)) { 115 | pool = [pool]; 116 | actorClass = true; 117 | } 118 | 119 | if (pool.length > 0) { 120 | return PoolTable({ 121 | pool: pool, 122 | actorClass: actorClass, 123 | id: poolId, 124 | key: poolId, 125 | searchFilter: this.props.searchFilter 126 | }); 127 | } 128 | }).filter((el) => el); 129 | 130 | return div({ className: "poolContainer" }, poolTables); 131 | } 132 | })); 133 | 134 | /** 135 | * @template This template renders 'PoolTable' which render a table related 136 | * to a single pool of actors. 137 | */ 138 | var PoolTable = React.createFactory(React.createClass({ 139 | /** @lends ActorsPanel */ 140 | 141 | displayName: "PoolTable", 142 | 143 | render: function() { 144 | var rows = []; 145 | 146 | // Iterate array of actors. 147 | var actors = this.props.pool; 148 | for (var i in actors) { 149 | if (this.props.searchFilter && 150 | JSON.stringify(actors[i]).toLowerCase() 151 | .indexOf(this.props.searchFilter.toLowerCase()) < 0) { 152 | // filter out packets which don't match the filter 153 | continue; 154 | } 155 | actors[i].key = actors[i].actorID; 156 | rows.push(PoolRow(actors[i])); 157 | } 158 | 159 | // Pools are mixed with Actor objects (created using CreateClass). 160 | var className = "poolTable"; 161 | if (this.props.actorClass) { 162 | className += " actorClass"; 163 | } 164 | 165 | var id = this.props.id ? "ID: " + this.props.id : ""; 166 | 167 | return ( 168 | div({}, 169 | h4({}, "Pool" + id), 170 | table({className: className}, 171 | thead({className: "poolRow"}, 172 | th({width: "20%"}, "Actor ID"), 173 | th({width: "20%"}, "Prefix"), 174 | th({width: "20%"}, "TypeName"), 175 | th({width: "20%"}, "Parent"), 176 | th({width: "20%"}, "Constructor") 177 | ), 178 | tbody(null, rows) 179 | ) 180 | ) 181 | ); 182 | } 183 | })); 184 | 185 | /** 186 | * @template This template renders a single row of the 'PoolTable' . 187 | */ 188 | var PoolRow = React.createFactory(React.createClass({ 189 | /** @lends PoolRow */ 190 | 191 | displayName: "PoolRow", 192 | 193 | render: function() { 194 | var actor = this.props; 195 | return ( 196 | tr({className: "poolRow"}, 197 | td({}, actor.actorID), 198 | td({}, actor.actorPrefix), 199 | td({}, actor.typeName), 200 | td({}, actor.parentID), 201 | td({}, actor.constructor) 202 | ) 203 | ); 204 | } 205 | })); 206 | 207 | /** 208 | * @template This template renders a single 'FactoryTable' component. 209 | */ 210 | var FactoryTable = React.createFactory(React.createClass({ 211 | /** @lends FactoryTable */ 212 | 213 | displayName: "FactoryTable", 214 | 215 | render: function() { 216 | var rows = []; 217 | 218 | var factories = this.props.factories; 219 | for (var i in factories) { 220 | if (this.props.searchFilter && 221 | JSON.stringify(factories[i]).toLowerCase() 222 | .indexOf(this.props.searchFilter.toLowerCase()) < 0) { 223 | // filter out packets which don't match the filter 224 | continue; 225 | } 226 | 227 | factories[i].key = factories[i].prefix + factories[i].name; 228 | rows.push(FactoryRow(factories[i])); 229 | } 230 | 231 | return ( 232 | table({className: "poolTable"}, 233 | thead({className: "poolRow"}, 234 | th({width: "33%"}, "Name"), 235 | th({width: "33%"}, "Prefix"), 236 | th({width: "33%"}, "Constructor") 237 | ), 238 | tbody(null, rows) 239 | ) 240 | ); 241 | } 242 | })); 243 | 244 | /** 245 | * @template This template renders the 'ActorsFactories' list of tables. 246 | */ 247 | var ActorsFactories = React.createFactory(React.createClass({ 248 | /** @lends ActorsFactories */ 249 | 250 | displayName: "ActorsFactories", 251 | 252 | render: function() { 253 | var main = this.props.data.global || { factories: {} }; 254 | var child = this.props.data.tab || { factories: {} }; 255 | var searchFilter = this.props.searchFilter; 256 | 257 | return ( 258 | div({className: "poolContainer"}, 259 | h4(null, "Main Process - Global Factories"), 260 | FactoryTable({ factories: main.factories.global, searchFilter: searchFilter }), 261 | h4(null, "Main Process - Tab Factories"), 262 | FactoryTable({ factories: main.factories.tab, searchFilter: searchFilter }), 263 | h4(null, "Child Process - Global Factories"), 264 | FactoryTable({ factories: child.factories.global, searchFilter: searchFilter }), 265 | h4(null, "Child Process - Tab Factories"), 266 | FactoryTable({ factories: child.factories.tab, searchFilter: searchFilter }) 267 | ) 268 | ); 269 | } 270 | })); 271 | 272 | /** 273 | * @template This template renders a single row of the 'FactoryTable'. 274 | */ 275 | var FactoryRow = React.createFactory(React.createClass({ 276 | /** @lends ActorsPanel */ 277 | 278 | displayName: "FactoryRow", 279 | 280 | render: function() { 281 | var factory = this.props; 282 | return ( 283 | tr({className: "poolRow"}, 284 | td({}, factory.name), 285 | td({}, factory.prefix), 286 | td({}, factory.ctor) 287 | ) 288 | ); 289 | } 290 | })); 291 | 292 | // Exports from this module 293 | exports.ActorsPanel = React.createFactory(ActorsPanel); 294 | exports.ActorsPanelComponent = ActorsPanel; 295 | 296 | }); 297 | -------------------------------------------------------------------------------- /data/inspector/components/actors-toolbar.js: -------------------------------------------------------------------------------- 1 | /* See license.txt for terms of usage */ 2 | 3 | define(function(require, exports/*, module*/) { 4 | 5 | "use strict"; 6 | 7 | // Dependencies 8 | var React = require("react"); 9 | 10 | // Shortcuts 11 | const { ButtonToolbar, Button } = require("shared/react-bootstrap-factories"); 12 | 13 | const { select, option } = React.DOM; 14 | 15 | // RDP Window injected APIs 16 | const { Locale } = require("shared/rdp-inspector-window"); 17 | 18 | /** 19 | * @template This object is responsible for rendering the toolbar 20 | * in Actors tab 21 | */ 22 | var ActorsToolbar = React.createClass({ 23 | /** @lends ActorsToolbar */ 24 | 25 | displayName: "ActorsToolbar", 26 | 27 | render: function() { 28 | var { panelTypesLabels, currentPanelType } = this.props; 29 | 30 | var options = Object.keys(panelTypesLabels).map((value) => { 31 | var label = panelTypesLabels[value]; 32 | return option({ value: value, key: value }, label); 33 | }); 34 | 35 | return ( 36 | ButtonToolbar({className: "toolbar"}, 37 | Button({bsSize: "xsmall", onClick: this.onRefresh}, 38 | Locale.$STR("rdpInspector.cmd.refresh") 39 | ), 40 | select({ selected: currentPanelType, onChange: this.onChange }, 41 | options 42 | ) 43 | ) 44 | ); 45 | }, 46 | 47 | // Commands 48 | 49 | onRefresh: function(/*event*/) { 50 | this.props.actions.getActors(); 51 | }, 52 | 53 | onChange: function(event) { 54 | var type = event.target.value; 55 | this.props.onPanelTypeSelected(type); 56 | } 57 | }); 58 | 59 | // Exports from this module 60 | exports.ActorsToolbar = React.createFactory(ActorsToolbar); 61 | }); 62 | -------------------------------------------------------------------------------- /data/inspector/components/factories.js: -------------------------------------------------------------------------------- 1 | /* See license.txt for terms of usage */ 2 | 3 | define(function(require, exports/*, module*/) { 4 | 5 | "use strict"; 6 | 7 | // Dependencies 8 | var React = require("react"); 9 | var ReactDOM = require("react-dom"); 10 | 11 | // Consts 12 | const { tr, td, table, tbody, thead, th, div, h4 } = React.DOM; 13 | 14 | // Templates 15 | 16 | /** 17 | * TODO docs 18 | */ 19 | var FactoryRow = React.createFactory(React.createClass({ 20 | /** @lends FactoryRow */ 21 | 22 | displayName: "FactoryRow", 23 | 24 | render: function() { 25 | var factory = this.props; 26 | return ( 27 | tr({className: "poolRow"}, 28 | td({}, factory.name), 29 | td({}, factory.prefix), 30 | td({}, factory.ctor) 31 | ) 32 | ); 33 | } 34 | })); 35 | 36 | /** 37 | * TODO docs 38 | * xxxHonza: localization 39 | */ 40 | var FactoryTable = React.createFactory(React.createClass({ 41 | /** @lends FactoryTable */ 42 | 43 | displayName: "FactoryTable", 44 | 45 | render: function() { 46 | var rows = []; 47 | 48 | var factories = this.props.factories; 49 | for (var i in factories) { 50 | if (this.props.searchFilter && 51 | JSON.stringify(factories[i]).toLowerCase() 52 | .indexOf(this.props.searchFilter.toLowerCase()) < 0) { 53 | // filter out packets which don't match the filter 54 | continue; 55 | } 56 | 57 | factories[i].key = factories[i].prefix + factories[i].name; 58 | rows.push(FactoryRow(factories[i])); 59 | } 60 | 61 | return ( 62 | table({className: "poolTable"}, 63 | thead({className: "poolRow"}, 64 | th({width: "33%"}, "Name"), 65 | th({width: "33%"}, "Prefix"), 66 | th({width: "33%"}, "Constructor") 67 | ), 68 | tbody(null, rows) 69 | ) 70 | ); 71 | } 72 | })); 73 | 74 | /** 75 | * TODO docs 76 | */ 77 | var FactoryList = React.createFactory(React.createClass({ 78 | /** @lends FactoryList */ 79 | 80 | displayName: "FactoryList", 81 | 82 | getInitialState: function() { 83 | return { 84 | main: {factories: {}}, 85 | child: {factories: {}}, 86 | searchFilter: null 87 | }; 88 | }, 89 | render: function() { 90 | var main = this.state.main; 91 | var child = this.state.child; 92 | var searchFilter = this.state.searchFilter; 93 | 94 | // xxxHonza: localization 95 | return ( 96 | div({className: "poolContainer"}, 97 | h4(null, "Main Process - Global Factories"), 98 | FactoryTable({ factories: main.factories.global, searchFilter: searchFilter }), 99 | h4(null, "Main Process - Tab Factories"), 100 | FactoryTable({ factories: main.factories.tab, searchFilter: searchFilter }), 101 | h4(null, "Child Process - Global Factories"), 102 | FactoryTable({ factories: child.factories.global, searchFilter: searchFilter }), 103 | h4(null, "Child Process - Tab Factories"), 104 | FactoryTable({ factories: child.factories.tab, searchFilter: searchFilter }) 105 | ) 106 | ); 107 | } 108 | })); 109 | 110 | // TODO: turn this into a more React approach 111 | var Factories = { 112 | render: function(parentNode) { 113 | return ReactDOM.render(FactoryList(), parentNode); 114 | } 115 | }; 116 | 117 | // Exports from this module 118 | exports.Factories = Factories; 119 | 120 | }); 121 | -------------------------------------------------------------------------------- /data/inspector/components/main-tabbed-area.js: -------------------------------------------------------------------------------- 1 | /* See license.txt for terms of usage */ 2 | 3 | define(function(require, exports, module) { 4 | 5 | "use strict"; 6 | 7 | // ReactJS 8 | var React = require("react"); 9 | var ReactDOM = require("react-dom"); 10 | 11 | // RDP Inspector 12 | const { ActorsPanel } = require("./actors-panel"); 13 | const { PacketsPanel } = require("./packets-panel"); 14 | const { SearchBox } = require("./search-box"); 15 | 16 | // Constants 17 | const { Tabs, Tab, Alert } = require("shared/react-bootstrap-factories"); 18 | 19 | // RDP Window injected APIs 20 | const { Locale } = require("shared/rdp-inspector-window"); 21 | 22 | /** 23 | * @template This template is responsible for rendering the main 24 | * application UI. The UI consist from set of tabs (Packets and Actors) 25 | * displaying list of sent/received packets and list of registered 26 | * actors. 27 | */ 28 | var MainTabbedArea = React.createClass({ 29 | /** @lends MainTabbedArea */ 30 | 31 | displayName: "MainTabbedArea", 32 | 33 | getInitialState: function() { 34 | return { packets: [] }; 35 | }, 36 | 37 | componentDidMount: function() { 38 | var tabbedArea = ReactDOM.findDOMNode(this.refs.tabbedArea); 39 | SearchBox.create(tabbedArea.querySelector(".nav-tabs")); 40 | }, 41 | 42 | componentWillUnmount: function() { 43 | var tabbedArea = ReactDOM.findDOMNode(this.refs.tabbedArea); 44 | SearchBox.destroy(tabbedArea.querySelector(".nav-tabs")); 45 | }, 46 | 47 | onErrorDismiss: function() { 48 | this.props.view.clearError(); 49 | }, 50 | 51 | render: function() { 52 | var packets = Locale.$STR("rdpInspector.tab.Packets"); 53 | var actors = Locale.$STR("rdpInspector.tab.Actors"); 54 | var { error } = this.props.packets; 55 | 56 | return ( 57 | Tabs({className: "mainTabbedArea", defaultActiveKey: 1, 58 | animation: false, ref: "tabbedArea"}, 59 | error ? Alert({ 60 | bsStyle: "warning", 61 | onDismiss: this.onErrorDismiss, 62 | dismissAfter: 2000, 63 | style: { 64 | position: "absolute", 65 | width: "100%", 66 | zIndex: 999999 67 | } 68 | }, error.message) : null, 69 | Tab({ eventKey: 1, title: packets }, 70 | PacketsPanel({ 71 | packets: this.props.packets.filteredPackets, 72 | actions: this.props.view, 73 | selectedPacket: this.props.packets.selectedPacket, 74 | editedPacket: this.props.packets.editedPacket, 75 | searchFilter: this.props.global.searchFilter, 76 | showInlineDetails: this.props.packets.options.showInlineDetails, 77 | packetCacheEnabled: this.props.packets.options.packetCacheEnabled, 78 | removedPackets: this.props.packets.removedPackets, 79 | paused: this.props.packets.paused, 80 | actorIDs: this.props.actors.actorIDs 81 | }) 82 | ), 83 | Tab({ eventKey: 2, title: actors }, 84 | ActorsPanel({ 85 | actions: this.props.view, 86 | actors: this.props.actors, 87 | searchFilter: this.props.global.searchFilter 88 | }) 89 | ) 90 | ) 91 | ); 92 | } 93 | }); 94 | 95 | // Exports from this module 96 | module.exports = MainTabbedArea; 97 | }); 98 | -------------------------------------------------------------------------------- /data/inspector/components/packet-details.js: -------------------------------------------------------------------------------- 1 | /* See license.txt for terms of usage */ 2 | 3 | define(function(require, exports/*, module*/) { 4 | 5 | "use strict"; 6 | 7 | // Dependencies 8 | const React = require("react"); 9 | 10 | // Firebug SDK 11 | const { TreeView } = require("reps/tree-view"); 12 | 13 | // Shortcuts 14 | const { div } = React.DOM; 15 | 16 | /** 17 | * @template This template represents a list of packets displayed 18 | * inside the panel content. 19 | */ 20 | var PacketDetails = React.createClass({ 21 | /** @lends PacketDetails */ 22 | 23 | displayName: "PacketDetails", 24 | 25 | getInitialState: function() { 26 | return { 27 | selectedPacket: null 28 | }; 29 | }, 30 | 31 | render: function() { 32 | var selectedPacket = this.props.selectedPacket || {}; 33 | 34 | return ( 35 | div({className: "details"}, 36 | TreeView({key: "packet-detail", data: selectedPacket.packet}) 37 | ) 38 | ); 39 | } 40 | }); 41 | 42 | // Exports from this module 43 | exports.PacketDetails = React.createFactory(PacketDetails); 44 | }); 45 | -------------------------------------------------------------------------------- /data/inspector/components/packet-editor.js: -------------------------------------------------------------------------------- 1 | /* See license.txt for terms of usage */ 2 | 3 | define(function(require, exports/*, module*/) { 4 | 5 | "use strict"; 6 | 7 | // Dependencies 8 | const React = require("react"); 9 | 10 | // Firebug SDK 11 | const { TreeEditorView } = require("./tree-editor-view"); 12 | 13 | // Constants 14 | const { div } = React.DOM; 15 | 16 | const { ButtonToolbar, Button } = require("shared/react-bootstrap-factories"); 17 | 18 | /** 19 | * @template This template represents the Packet Editor toolbar 20 | */ 21 | 22 | var PacketEditorToolbar = React.createFactory(React.createClass({ 23 | /** @lends PacketEditrView */ 24 | 25 | displayName: "PacketEditorToolbar", 26 | 27 | render: function() { 28 | return ButtonToolbar({className: "toolbar"}, [ 29 | Button({ onClick: this.props.onSend, key: "send", 30 | bsStyle: "primary", bsSize: "xsmall", 31 | style: { marginLeft: 12, color: "white" } }, "Send"), 32 | 33 | Button({ onClick: this.props.onRedo, key: "redo", 34 | className: "pull-right", 35 | disabled: !this.props.isRedoEnabled, 36 | bsStyle: "default", bsSize: "xsmall", 37 | style: { marginRight: 6 } }, "Redo"), 38 | Button({ onClick: this.props.onUndo, key: "undo", 39 | className: "pull-right", 40 | disabled: !this.props.isUndoEnabled, 41 | bsStyle: "default", bsSize: "xsmall", 42 | style: { marginRight: 6 } }, "Undo"), 43 | Button({ onClick: this.props.onClear, key: "clear", 44 | className: "pull-right", 45 | bsStyle: "danger", bsSize: "xsmall", 46 | style: { marginRight: 6, color: "white" } }, "Clear") 47 | ]); 48 | } 49 | })); 50 | 51 | /** 52 | * @template This template represents the PacketEditor sidebar 53 | */ 54 | var PacketEditor = React.createClass({ 55 | displayName: "PacketEditor", 56 | 57 | getInitialState: function() { 58 | return { 59 | editedPacket: null, 60 | defaultData: { 61 | to: "root", 62 | type: "requestTypes" 63 | } 64 | }; 65 | }, 66 | 67 | componentWillReceiveProps: function(nextProps) { 68 | this.setState({ 69 | editedPacket: nextProps.editedPacket 70 | }); 71 | }, 72 | 73 | render: function() { 74 | var editedPacket = this.state.editedPacket || this.props.editedPacket; 75 | var { actorIDs } = this.props; 76 | 77 | return ( 78 | div({className: "details editor"}, 79 | PacketEditorToolbar({ 80 | onClear: this.onClear, 81 | onSend: this.onSend, 82 | onUndo: this.onUndo, 83 | onRedo: this.onRedo, 84 | isUndoEnabled: true, 85 | isRedoEnabled: true 86 | }), 87 | TreeEditorView({ 88 | ref: "editor", 89 | key: "packet-editor", 90 | data: editedPacket, 91 | defaultData: this.state.defaultData, 92 | handleAutocompletion: (suggestionType, keyPath, value) => { 93 | if (!actorIDs && suggestionType != "value") { 94 | return []; 95 | } 96 | 97 | try { 98 | var parsedValue; 99 | 100 | // remove starting and ending '"' if any 101 | parsedValue = typeof value == "string" ? 102 | value.replace(/^"|"$/g, "") : ""; 103 | 104 | if(keyPath.length == 1 && keyPath[0] == "to") { 105 | // get a suggestion list by filtering actorIDs list 106 | return actorIDs.filter((suggestion) => { 107 | return suggestion.indexOf(parsedValue) >= 0; 108 | }); 109 | } 110 | } catch(e) { 111 | //console.debug("exception on parsing autocompletion", e); 112 | } 113 | 114 | return []; 115 | } 116 | }) 117 | ) 118 | ); 119 | }, 120 | 121 | onUndo: function() { 122 | this.refs.editor.undo(); 123 | }, 124 | 125 | onRedo: function() { 126 | this.refs.editor.redo(); 127 | }, 128 | 129 | onClear: function() { 130 | this.refs.editor.clearData(); 131 | }, 132 | 133 | onSend: function() { 134 | this.props.actions.send(this.refs.editor.getData()); 135 | } 136 | }); 137 | 138 | // Exports from this module 139 | exports.PacketEditor = React.createFactory(PacketEditor); 140 | 141 | }); 142 | -------------------------------------------------------------------------------- /data/inspector/components/packet-list.js: -------------------------------------------------------------------------------- 1 | /* See license.txt for terms of usage */ 2 | 3 | define(function(require, exports/*, module*/) { 4 | 5 | "use strict"; 6 | 7 | // Dependencies 8 | const React = require("react"); 9 | const ReactDOM = require("react-dom"); 10 | 11 | // RDP Inspector 12 | const { Packet } = require("./packet"); 13 | const { PacketsSummary } = require("./packets-summary"); 14 | const { PacketsLimit } = require("./packets-limit"); 15 | const { PacketsMessage } = require("./packets-message"); 16 | 17 | // Shortcuts 18 | const { div } = React.DOM; 19 | 20 | /** 21 | * @template This template represents a list of packets displayed 22 | * inside the panel content. 23 | */ 24 | var PacketList = React.createClass({ 25 | /** @lends PacketList */ 26 | 27 | displayName: "PacketList", 28 | 29 | getInitialState: function() { 30 | return { data: [] }; 31 | }, 32 | 33 | componentWillUpdate: function() { 34 | var node = ReactDOM.findDOMNode(this); 35 | this.shouldScrollBottom = node.scrollTop + 36 | node.offsetHeight === node.scrollHeight; 37 | }, 38 | 39 | componentDidUpdate: function() { 40 | if (this.shouldScrollBottom) { 41 | var node = ReactDOM.findDOMNode(this); 42 | node.scrollTop = node.scrollHeight; 43 | } 44 | }, 45 | 46 | render: function() { 47 | var output = []; 48 | var filter = this.props.searchFilter; 49 | var removedPackets = this.props.removedPackets; 50 | 51 | if (removedPackets > 0) { 52 | output.push(PacketsLimit({ 53 | removedPackets: removedPackets 54 | })); 55 | } 56 | 57 | var packets = this.props.data; 58 | for (var i in packets) { 59 | var packet = packets[i]; 60 | 61 | // Render 'summary' packets. 62 | if (packet.type == "summary") { 63 | output.push(PacketsSummary({ 64 | key: packet.id, 65 | data: packet 66 | })); 67 | continue; 68 | } 69 | 70 | // Render 'message' packets. 71 | if (packet.type == "message") { 72 | output.push(PacketsMessage({ 73 | key: packet.id, 74 | data: packet 75 | })); 76 | continue; 77 | } 78 | 79 | // Filter out packets which don't match the search token. 80 | if (filter && packet.rawPacket.toLowerCase().indexOf(filter.toLowerCase()) < 0) { 81 | continue; 82 | } 83 | 84 | var selected = this.props.selectedPacket == packet; 85 | 86 | output.push(Packet({ 87 | key: packet.id, 88 | data: packet, 89 | actions: this.props.actions, 90 | selected: selected, 91 | showInlineDetails: this.props.showInlineDetails 92 | })); 93 | } 94 | 95 | return ( 96 | div({className: "list"}, 97 | div({}, output) 98 | ) 99 | ); 100 | } 101 | }); 102 | 103 | // Exports from this module 104 | exports.PacketList = React.createFactory(PacketList); 105 | exports.PacketListComponent = PacketList; 106 | }); 107 | -------------------------------------------------------------------------------- /data/inspector/components/packet-stack-sidepanel.js: -------------------------------------------------------------------------------- 1 | /* See license.txt for terms of usage */ 2 | 3 | define(function(require, exports/*, module*/) { 4 | 5 | "use strict"; 6 | 7 | // Dependencies 8 | const React = require("react"); 9 | 10 | // Firebug SDK 11 | const { TreeView } = require("reps/tree-view"); 12 | 13 | // Shortcuts 14 | const { div } = React.DOM; 15 | 16 | /** 17 | * @template This template represents a side panel that displays 18 | * list of stack-frames for selected packet. 19 | */ 20 | var PacketStackSidePanel = React.createClass({ 21 | /** @lends PacketStackSidePanel */ 22 | 23 | displayName: "PacketStackSidePanel", 24 | 25 | getInitialState: function() { 26 | return { 27 | selectedPacket: null 28 | }; 29 | }, 30 | 31 | render: function() { 32 | var selectedPacket = this.props.selectedPacket || {}; 33 | var frames = selectedPacket.stack ? selectedPacket.stack.frames : []; 34 | 35 | // Customize TreeView logic that is responsible for 36 | // returning object properties. In case of StackFrames 37 | // only props (not functions) are returned. 38 | // Result of the function is used for computing children 39 | // nodes in the tree view. 40 | function getObjectProperties(obj, callback) { 41 | for (var p in obj) { 42 | try { 43 | if (typeof obj[p] != "function") { 44 | callback(p, obj[p]); 45 | } 46 | } 47 | catch (e) { 48 | /* eslint: no-empty-block: 0*/ 49 | } 50 | } 51 | } 52 | 53 | return ( 54 | div({className: "stackSidePanel"}, 55 | TreeView({key: "packet-detail", data: frames, 56 | getObjectProperties: getObjectProperties}) 57 | ) 58 | ); 59 | } 60 | }); 61 | 62 | // Exports from this module 63 | exports.PacketStackSidePanel = React.createFactory(PacketStackSidePanel); 64 | }); 65 | -------------------------------------------------------------------------------- /data/inspector/components/packet.js: -------------------------------------------------------------------------------- 1 | /* See license.txt for terms of usage */ 2 | 3 | define(function(require, exports /*, module */) { 4 | 5 | "use strict"; 6 | 7 | // ReactJS 8 | const React = require("react"); 9 | 10 | // Firebug SDK 11 | const { TreeView } = require("reps/tree-view"); 12 | 13 | // RDP Inspector 14 | //const { TextWithTooltip } = require("./text-with-tooltip"); 15 | 16 | // Constants 17 | const { div, span, ul, li, a } = React.DOM; 18 | 19 | // RDP Window injected APIs 20 | const { Locale, Str } = require("shared/rdp-inspector-window"); 21 | 22 | /** 23 | * @template This template is responsible for rendering a packet. 24 | * Packets are rendered within {@link PacketList} sorted by time. 25 | * 26 | * A packet displays basic information in the list and can also 27 | * display inline preview of all inner fields. 28 | */ 29 | var Packet = React.createClass({ 30 | /** @lends Packet */ 31 | 32 | displayName: "Packet", 33 | 34 | /** 35 | * Packet needs to be re-rendered only if the selection or 36 | * 'show inline details' option changes. This is an optimization 37 | * the makes the packet-list rendering a lot faster. 38 | */ 39 | shouldComponentUpdate: function(nextProps, nextState) { 40 | var { contextMenu: prevContextMenu } = this.state || {}; 41 | var { contextMenu: nextContextMenu } = nextState || {}; 42 | 43 | return (this.props.selected != nextProps.selected || 44 | this.props.showInlineDetails != nextProps.showInlineDetails || 45 | prevContextMenu != nextContextMenu); 46 | }, 47 | 48 | render: function() { 49 | var data = this.props.data; 50 | var packet = data.packet; 51 | var type = packet.type ? packet.type : ""; 52 | var mode = "tiny"; 53 | var classNames = ["packetPanel", data.type]; 54 | var size = Str.formatSize(data.size); 55 | var time = data.time; 56 | //var stack = data.stack; 57 | 58 | // Use String.formatTime, but how to access from the content? 59 | var timeText = time.toLocaleTimeString() + "." + time.getMilliseconds(); 60 | var previewData = { 61 | packet: packet 62 | }; 63 | 64 | // Error packets have its own styling 65 | if (packet.error) { 66 | classNames.push("error"); 67 | } 68 | 69 | // Selected packets are highlighted 70 | if (this.props.selected) { 71 | classNames.push("selected"); 72 | } 73 | 74 | /*var topFrame = stack.getTopFrame(); 75 | var stackFrameUrl = topFrame ? topFrame.getUrl() : null; 76 | var stackFrame = topFrame ? topFrame.getLabel() : null;*/ 77 | 78 | // Inline preview component 79 | var preview = this.props.showInlineDetails ? TreeView( 80 | {data: previewData, mode: mode}) : null; 81 | 82 | if (this.props.data.type == "send") { 83 | return ( 84 | div({className: classNames.join(" "), onClick: this.onClick, 85 | onContextMenu: this.onContextMenu}, 86 | div({className: "packetBox"}, 87 | div({className: "packetContent"}, 88 | div({className: "body"}, 89 | span({className: "text"}, 90 | Locale.$STR("rdpInspector.label.sent") + " " 91 | ), 92 | span({className: "type"}, type), 93 | span({className: "text"}, 94 | " " + Locale.$STR("rdpInspector.label.to") + " " 95 | ), 96 | span({className: "to"}, packet.to), 97 | div({}, 98 | /*TextWithTooltip({ 99 | tooltip: stackFrameUrl, className: "stackFrameLabel", 100 | onClick: this.onViewSource.bind(this, topFrame)}, 101 | stackFrame 102 | ),*/ 103 | span({className: "info"}, timeText + ", " + size) 104 | ), 105 | div({className: "preview"}, 106 | preview 107 | ) 108 | ), 109 | div({className: "boxArrow"}) 110 | ) 111 | ), 112 | this.state && this.state.contextMenu && 113 | ul({className: "dropdown-menu", role: "menu", ref: "contextMenu", 114 | onMouseLeave: this.onContextMenuMouseLeave, 115 | style: { 116 | display: "block", 117 | top: this.state.contextMenuTop, 118 | left: this.state.contextMenuLeft 119 | }}, 120 | li({role: "presentation"}, 121 | a({ref: "editAndResendAction", onClick: this.onEditAndResendClick}, 122 | "Edit and Resend")) 123 | ) 124 | ) 125 | ); 126 | } else { 127 | return ( 128 | div({className: classNames.join(" "), onClick: this.onClick}, 129 | div({className: "packetBox"}, 130 | div({className: "packetContent"}, 131 | div({className: "boxArrow"}), 132 | div({className: "body"}, 133 | div({className: "from"}, 134 | span({className: "text"}, 135 | Locale.$STR("rdpInspector.label.received") + " " 136 | ), 137 | span({}, type), 138 | span({className: "text"}, 139 | " " + Locale.$STR("rdpInspector.label.from") + " "), 140 | span({}, packet.from), 141 | div({}, 142 | /*TextWithTooltip({ 143 | tooltip: stackFrameUrl, className: "stackFrameLabel", 144 | onClick: this.onViewSource.bind(this, topFrame)}, 145 | stackFrame 146 | ),*/ 147 | span({className: "info"}, timeText + ", " + size) 148 | ) 149 | ), 150 | // NOTE: on issue #44, a long "consoleAPICall" received packet 151 | // was wrongly turned into a "div.errorMessage" 152 | packet.error ? div({className: "errorMessage"}, 153 | div({}, packet.error), 154 | div({}, packet.message) 155 | ) : null, 156 | div({className: "preview"}, 157 | preview 158 | ) 159 | ) 160 | ) 161 | ) 162 | ) 163 | ); 164 | } 165 | }, 166 | 167 | // Event Handlers 168 | onEditAndResendClick: function() { 169 | this.setState({ 170 | contextMenu: false 171 | }); 172 | this.props.actions.editPacket(this.props.data.packet); 173 | }, 174 | 175 | onContextMenuMouseLeave: function() { 176 | this.setState({ 177 | contextMenu: false 178 | }); 179 | }, 180 | 181 | onContextMenu: function(event) { 182 | event.stopPropagation(); 183 | event.preventDefault(); 184 | 185 | this.setState({ 186 | contextMenu: true, 187 | contextMenuTop: event.clientY - 16, 188 | contextMenuLeft: event.clientX - 16 189 | }); 190 | this.props.actions.selectPacket(this.props.data); 191 | }, 192 | 193 | onClick: function(event) { 194 | var target = event.target; 195 | 196 | event.stopPropagation(); 197 | event.preventDefault(); 198 | 199 | // If a 'memberLabel' is clicked inside the inline preview 200 | // tree, let's process it by the tree, so expansion and 201 | // collapsing works. Otherwise just select the packet. 202 | if (!target.classList.contains("memberLabel")) { 203 | this.props.actions.selectPacket(this.props.data); 204 | } 205 | }, 206 | 207 | onViewSource: function(topFrame, event) { 208 | event.stopPropagation(); 209 | event.preventDefault(); 210 | 211 | this.props.actions.onViewSource({ 212 | url: topFrame.url, 213 | lineNumber: topFrame.lineNumber 214 | }); 215 | } 216 | }); 217 | 218 | // Exports from this module 219 | exports.Packet = React.createFactory(Packet); 220 | exports.PacketComponent = Packet; 221 | }); 222 | -------------------------------------------------------------------------------- /data/inspector/components/packets-limit.js: -------------------------------------------------------------------------------- 1 | /* See license.txt for terms of usage */ 2 | 3 | define(function(require, exports/*, module*/) { 4 | 5 | "use strict"; 6 | 7 | // ReactJS 8 | const React = require("react"); 9 | 10 | // Constants 11 | const { div, span } = React.DOM; 12 | 13 | // RDP Window injected APIs 14 | const { Locale } = require("shared/rdp-inspector-window"); 15 | 16 | /** 17 | * @template This template is responsible for rendering a message 18 | * at the top of the packet list that informs the user about reaching 19 | * the maximum limit of displayed packets. The message also displays 20 | * number of packets removed from the list. 21 | */ 22 | var PacketsLimit = React.createClass({ 23 | /** @lends PacketsLimit */ 24 | 25 | displayName: "PacketsLimit", 26 | 27 | render: function() { 28 | var removedPackets = this.props.removedPackets; 29 | var label = Locale.$STR("rdpInspector.label.outOfLimit"); 30 | 31 | // Render summary info 32 | return ( 33 | div({className: "packetsLimit"}, 34 | span({className: "text"}, removedPackets + " " + label) 35 | ) 36 | ); 37 | } 38 | }); 39 | 40 | // Exports from this module 41 | exports.PacketsLimit = React.createFactory(PacketsLimit); 42 | }); 43 | -------------------------------------------------------------------------------- /data/inspector/components/packets-message.js: -------------------------------------------------------------------------------- 1 | /* See license.txt for terms of usage */ 2 | 3 | define(function(require, exports/*, module*/) { 4 | 5 | "use strict"; 6 | 7 | // ReactJS 8 | const React = require("react"); 9 | 10 | // Constants 11 | const { div } = React.DOM; 12 | 13 | /** 14 | * @template This template renders a generic message within the 15 | * packet list. 16 | */ 17 | var PacketsMessage = React.createClass({ 18 | /** @lends PacketsMessage */ 19 | 20 | displayName: "PacketsMessage", 21 | 22 | render: function() { 23 | var packet = this.props.data; 24 | var message = packet.message; 25 | var time = packet.time; 26 | 27 | var timeText = time.toLocaleTimeString() + "." + time.getMilliseconds(); 28 | 29 | // Render summary info 30 | return ( 31 | div({className: "packetsMessage"}, 32 | div({className: "text"}, message), 33 | div({className: "time"}, timeText) 34 | ) 35 | ); 36 | } 37 | }); 38 | 39 | // Exports from this module 40 | exports.PacketsMessage = React.createFactory(PacketsMessage); 41 | }); 42 | -------------------------------------------------------------------------------- /data/inspector/components/packets-panel.js: -------------------------------------------------------------------------------- 1 | /* See license.txt for terms of usage */ 2 | 3 | define(function(require, exports/*, module*/) { 4 | 5 | "use strict"; 6 | 7 | // Dependencies 8 | const React = require("react"); 9 | 10 | // Firebug SDK 11 | const { createFactories } = require("reps/rep-utils"); 12 | const { Splitter } = createFactories(require("reps/splitter")); 13 | 14 | // RDP Inspector 15 | const { PacketList } = require("./packet-list"); 16 | const { PacketsSidebar } = require("./packets-sidebar"); 17 | const { PacketsToolbar } = require("./packets-toolbar"); 18 | 19 | // Shortcuts 20 | const { div } = React.DOM; 21 | 22 | /** 23 | * @template This template renders 'Packets' tab body. 24 | */ 25 | var PacketsPanel = React.createClass({ 26 | /** @lends PacketPanel */ 27 | 28 | displayName: "PacketsPanel", 29 | 30 | getInitialState: function() { 31 | return { 32 | packets: this.props.packets, 33 | selectedPacket: null 34 | }; 35 | }, 36 | 37 | render: function() { 38 | var leftPanel = div({className: "mainPanel"}, 39 | PacketsToolbar({ 40 | actions: this.props.actions, 41 | showInlineDetails: this.props.showInlineDetails, 42 | packetCacheEnabled: this.props.packetCacheEnabled, 43 | paused: this.props.paused 44 | }), 45 | PacketList({ 46 | data: this.props.packets, 47 | actions: this.props.actions, 48 | selectedPacket: this.props.selectedPacket, 49 | searchFilter: this.props.searchFilter, 50 | showInlineDetails: this.props.showInlineDetails, 51 | removedPackets: this.props.removedPackets 52 | }) 53 | ); 54 | 55 | var rightPanel = div({className: "sidePanel"}, 56 | PacketsSidebar({ 57 | selectedPacket: this.props.selectedPacket, 58 | editedPacket: this.props.editedPacket, 59 | actions: this.props.actions, 60 | actorIDs: this.props.actorIDs 61 | }) 62 | ); 63 | 64 | return ( 65 | div({className: "packetsPanelBox"}, 66 | Splitter({ 67 | mode: "vertical", 68 | min: 200, 69 | leftPanel: leftPanel, 70 | rightPanel: rightPanel, 71 | innerBox: div({className: "innerBox"}) 72 | }) 73 | ) 74 | ); 75 | } 76 | }); 77 | 78 | // Exports from this module 79 | exports.PacketsPanel = React.createFactory(PacketsPanel); 80 | exports.PacketsPanelComponent = PacketsPanel; 81 | 82 | }); 83 | -------------------------------------------------------------------------------- /data/inspector/components/packets-sidebar.js: -------------------------------------------------------------------------------- 1 | /* See license.txt for terms of usage */ 2 | 3 | define(function(require, exports/*, module*/) { 4 | 5 | "use strict"; 6 | 7 | // ReactJS 8 | const React = require("react"); 9 | 10 | // RDP Inspector 11 | const { PacketDetails } = require("./packet-details"); 12 | const { PacketEditor } = require("./packet-editor"); 13 | const { PacketStackSidePanel } = require("./packet-stack-sidepanel"); 14 | 15 | // Constants 16 | const { Tabs, Tab } = require("shared/react-bootstrap-factories"); 17 | 18 | /** 19 | * @template This template represents a list of packets displayed 20 | * inside the panel content. 21 | */ 22 | var PacketsSidebar = React.createClass({ 23 | /** @lends PacketsSidebar */ 24 | 25 | displayName: "PacketsSidebar", 26 | 27 | getInitialState: function() { 28 | return { 29 | activeKey: 1 30 | }; 31 | }, 32 | 33 | onTabSelected: function(key) { 34 | this.setState({ 35 | activeKey: key 36 | }); 37 | }, 38 | 39 | componentDidMount: function() { 40 | window.addEventListener("rdpinspector:switchToPacketEditorTab", 41 | this.onSwitchToPacketEditorTab); 42 | }, 43 | 44 | componentWillUnmount: function() { 45 | window.removeEventListener("rdpinspector:switchToPacketEditorTab", this.onSwitchToPacketEditorTab); 46 | }, 47 | 48 | onSwitchToPacketEditorTab: function() { 49 | this.setState({ activeKey: 2 }); 50 | }, 51 | 52 | render: function() { 53 | // TODO xxxRpl: externalize and localize sidebar tab titles 54 | return ( 55 | Tabs({ 56 | className: "sideBarTabbedArea", animation: false, 57 | activeKey: this.state.activeKey, 58 | onSelect: this.onTabSelected 59 | }, 60 | Tab({ eventKey: 1, title: "Packet Details" }, 61 | PacketDetails({ 62 | selectedPacket: this.props.selectedPacket 63 | }) 64 | ), 65 | Tab({ eventKey: 2, title: "Send Packet" }, 66 | PacketEditor({ 67 | actions: this.props.actions, 68 | actorIDs: this.props.actorIDs, 69 | editedPacket: this.props.editedPacket 70 | }) 71 | ), 72 | Tab({ eventKey: 3, title: "Stack" }, 73 | PacketStackSidePanel({ 74 | actions: this.props.actions, 75 | selectedPacket: this.props.selectedPacket 76 | }) 77 | ) 78 | ) 79 | ); 80 | } 81 | }); 82 | 83 | // Exports from this module 84 | exports.PacketsSidebar = React.createFactory(PacketsSidebar); 85 | exports.PacketsSidebarComponent = PacketsSidebar; 86 | }); 87 | -------------------------------------------------------------------------------- /data/inspector/components/packets-summary.js: -------------------------------------------------------------------------------- 1 | /* See license.txt for terms of usage */ 2 | 3 | define(function(require, exports/*, module*/) { 4 | 5 | "use strict"; 6 | 7 | // ReactJS 8 | const React = require("react"); 9 | 10 | // RDP Inspector 11 | const { TextWithTooltip } = require("./text-with-tooltip"); 12 | 13 | // RDP Window injected APIs 14 | const { Locale, Str } = require("shared/rdp-inspector-window"); 15 | 16 | 17 | // Constants 18 | const { div } = React.DOM; 19 | 20 | /** 21 | * @template This template is responsible for rendering packet summary 22 | * information. The summary can be inserted into the list by clicking 23 | * on 'Summary' button. It displays number of sent and received packets 24 | * and total amount of sent and received data. 25 | */ 26 | var PacketsSummary = React.createClass({ 27 | /** @lends PacketsSummary */ 28 | 29 | displayName: "PacketsSummary", 30 | 31 | render: function() { 32 | var summary = this.props.data; 33 | var time = summary.time; 34 | 35 | var timeText = time.toLocaleTimeString() + "." + time.getMilliseconds(); 36 | var sizeReceived = Str.formatSize(summary.data.received); 37 | var sizeSent = Str.formatSize(summary.data.sent); 38 | 39 | // Tooltips 40 | var sizeSentTip = Locale.$STR("rdpInspector.tooltip.sizeSent"); 41 | var sizeReceivedTip = Locale.$STR("rdpInspector.tooltip.sizeReceived"); 42 | var packetsSentTip = Locale.$STR("rdpInspector.tooltip.packetsSent"); 43 | var packetsReceivedTip = Locale.$STR("rdpInspector.tooltip.packetsReceived"); 44 | 45 | // Labels 46 | var packetsText = Locale.$STR("rdpInspector.label.packets"); 47 | var dataText = Locale.$STR("rdpInspector.label.data"); 48 | 49 | // Render summary info 50 | return ( 51 | div({className: "packetsSummary"}, 52 | div({className: "text"}, packetsText + ": "), 53 | TextWithTooltip({tooltip: packetsSentTip}, summary.packets.sent), 54 | div({className: "slash"}, " / "), 55 | TextWithTooltip({tooltip: packetsReceivedTip}, summary.packets.received), 56 | div({className: "separator"}), 57 | div({className: "text"}, dataText + ": "), 58 | TextWithTooltip({tooltip: sizeSentTip}, sizeSent), 59 | div({className: "slash"}, " / "), 60 | TextWithTooltip({tooltip: sizeReceivedTip}, sizeReceived), 61 | div({className: "separator"}), 62 | div({className: "time"}, timeText) 63 | ) 64 | ); 65 | } 66 | }); 67 | 68 | // Exports from this module 69 | exports.PacketsSummary = React.createFactory(PacketsSummary); 70 | exports.PacketsSummaryComponent = PacketsSummary; 71 | }); 72 | -------------------------------------------------------------------------------- /data/inspector/components/packets-toolbar.js: -------------------------------------------------------------------------------- 1 | /* See license.txt for terms of usage */ 2 | 3 | define(function(require, exports/*, module*/) { 4 | 5 | "use strict"; 6 | 7 | // ReactJS 8 | var React = require("react"); 9 | 10 | // Constants 11 | const { 12 | ButtonToolbar, Button, 13 | DropdownButton, MenuItem, 14 | OverlayTrigger, Tooltip 15 | } = require("shared/react-bootstrap-factories"); 16 | 17 | const { span, input } = React.DOM; 18 | 19 | // RDP Window injected APIs 20 | const { Locale } = require("shared/rdp-inspector-window"); 21 | 22 | /** 23 | * @template This object represents a template for a toolbar displayed 24 | * within the Packets tab 25 | */ 26 | var PacketsToolbar = React.createClass({ 27 | /** @lends PacketsToolbar */ 28 | 29 | displayName: "PacketsToolbar", 30 | 31 | render: function() { 32 | var { showInlineDetails, packetCacheEnabled } = this.props; 33 | 34 | var labels = {}; 35 | labels.inlineDetails = Locale.$STR("rdpInspector.option.showInlineDetails"); 36 | labels.cachePackets = Locale.$STR("rdpInspector.option.packetCacheEnabled"); 37 | 38 | var tooltips = {}; 39 | tooltips.inlineDetails = Locale.$STR("rdpInspector.option.showInlineDetails.tip"); 40 | tooltips.cachePackets = Locale.$STR("rdpInspector.option.packetCacheEnabled.tip"); 41 | 42 | var paused = this.props.paused; 43 | var pauseClassName = paused ? "btn-warning" : ""; 44 | 45 | return ( 46 | ButtonToolbar({className: "toolbar"}, 47 | DropdownButton({ bsSize: "xsmall", ref: "fileMenu", title: Locale.$STR("rdpInspector.menu.File")}, 48 | MenuItem({key: "fileLoad", ref: "fileLoad", onClick: this.onLoadPacketsFromFile }, 49 | Locale.$STR("rdpInspector.cmd.load")), 50 | MenuItem({key: "fileSave", ref: "fileSave", onClick: this.onSavePacketsFromFile }, 51 | Locale.$STR("rdpInspector.cmd.save")) 52 | ), 53 | DropdownButton({ 54 | bsSize: "xsmall", title: Locale.$STR("rdpInspector.menu.Options"), 55 | className: "pull-right", ref: "options" 56 | }, 57 | OverlayTrigger({placement: "bottom", overlay: Tooltip({}, tooltips.inlineDetails)}, 58 | MenuItem({key: "inlineDetails", ref: "optionShowInlineDetails", onClick: this.onShowInlineDetails}, 59 | input({type: "checkbox", checked: showInlineDetails}), labels.inlineDetails 60 | ) 61 | ), 62 | OverlayTrigger({placement: "bottom", overlay: Tooltip({}, tooltips.cachePackets)}, 63 | MenuItem({key: "cachePackets", ref: "optionCachePackets", onClick: this.onCachePackets}, 64 | input({type: "checkbox", checked: packetCacheEnabled}), labels.cachePackets 65 | ) 66 | ) 67 | ), 68 | Button({bsSize: "xsmall", onClick: this.onClear}, 69 | Locale.$STR("rdpInspector.cmd.clear") 70 | ), 71 | Button({bsSize: "xsmall", onClick: this.onFind}, 72 | Locale.$STR("rdpInspector.cmd.find") 73 | ), 74 | Button({bsSize: "xsmall", onClick: this.onSummary}, 75 | Locale.$STR("rdpInspector.cmd.summary") 76 | ), 77 | Button({bsSize: "xsmall", className: pauseClassName, 78 | onClick: this.onPause}, 79 | span({className: "glyphicon glyphicon-pause", "aria-hidden": true}) 80 | ) 81 | ) 82 | ); 83 | }, 84 | 85 | // Commands 86 | 87 | onClear: function(/*event*/) { 88 | this.props.actions.clear(); 89 | }, 90 | 91 | onFind: function(/*event*/) { 92 | this.props.actions.find(); 93 | }, 94 | 95 | onSummary: function(/*event*/) { 96 | this.props.actions.appendSummary(); 97 | }, 98 | 99 | onShowInlineDetails: function() { 100 | this.props.actions.onShowInlineDetails(); 101 | }, 102 | 103 | onCachePackets: function() { 104 | this.props.actions.onPacketCacheEnabled(); 105 | }, 106 | 107 | onPause: function(/*event*/) { 108 | this.props.actions.onPause(); 109 | }, 110 | 111 | onLoadPacketsFromFile: function(/*event*/) { 112 | this.props.actions.loadPacketsFromFile(); 113 | this.refs.fileMenu.setState({ open: false }); 114 | 115 | }, 116 | 117 | onSavePacketsFromFile: function(/*event*/) { 118 | this.props.actions.savePacketsToFile(); 119 | this.refs.fileMenu.setState({ open: false }); 120 | } 121 | }); 122 | 123 | // Exports from this module 124 | exports.PacketsToolbar = React.createFactory(PacketsToolbar); 125 | exports.PacketsToolbarComponent = PacketsToolbar; 126 | }); 127 | -------------------------------------------------------------------------------- /data/inspector/components/pools.js: -------------------------------------------------------------------------------- 1 | /* See license.txt for terms of usage */ 2 | 3 | define(function(require, exports/*, module*/) { 4 | 5 | "use strict"; 6 | 7 | // Dependencies 8 | const React = require("react"); 9 | const { tr, td, table, tbody, thead, th, div, h4 } = React.DOM; 10 | 11 | // Templates 12 | 13 | /** 14 | * TODO docs 15 | */ 16 | var PoolRow = React.createFactory(React.createClass({ 17 | /** @lends PoolRow */ 18 | 19 | displayName: "PoolRow", 20 | 21 | render: function() { 22 | var actor = this.props; 23 | return ( 24 | tr({className: "poolRow"}, 25 | td({}, actor.actorID), 26 | td({}, actor.actorPrefix), 27 | td({}, actor.typeName), 28 | td({}, actor.parentID), 29 | td({}, actor.constructor) 30 | ) 31 | ); 32 | } 33 | })); 34 | 35 | /** 36 | * TODO docs 37 | * xxxHonza: localization 38 | */ 39 | var PoolTable = React.createFactory(React.createClass({ 40 | /** @lends PoolTable */ 41 | 42 | displayName: "PoolTable", 43 | 44 | render: function() { 45 | var rows = []; 46 | 47 | // Iterate array of actors. 48 | var actors = this.props.pool; 49 | for (var i in actors) { 50 | if (this.props.searchFilter && 51 | JSON.stringify(actors[i]).toLowerCase() 52 | .indexOf(this.props.searchFilter.toLowerCase()) < 0) { 53 | // filter out packets which don't match the filter 54 | continue; 55 | } 56 | actors[i].key = actors[i].actorID; 57 | rows.push(PoolRow(actors[i])); 58 | } 59 | 60 | // Pools are mixed with Actor objects (created using CreateClass). 61 | var className = "poolTable"; 62 | if (this.props.actorClass) { 63 | className += " actorClass"; 64 | } 65 | 66 | var id = this.props.id ? "ID: " + this.props.id : ""; 67 | 68 | return ( 69 | div({}, 70 | h4({}, "Pool" + id), 71 | table({className: className}, 72 | thead({className: "poolRow"}, 73 | th({width: "20%"}, "Actor ID"), 74 | th({width: "20%"}, "Prefix"), 75 | th({width: "20%"}, "TypeName"), 76 | th({width: "20%"}, "Parent"), 77 | th({width: "20%"}, "Constructor") 78 | ), 79 | tbody(null, rows) 80 | ) 81 | ) 82 | ); 83 | } 84 | })); 85 | 86 | /** 87 | * TODO docs 88 | */ 89 | var PoolList = React.createFactory(React.createClass({ 90 | /** @lends PoolList */ 91 | 92 | displayName: "PoolList", 93 | 94 | getInitialState: function() { 95 | return { 96 | pools: [] 97 | }; 98 | }, 99 | 100 | render: function() { 101 | var pools = []; 102 | 103 | for (var i in this.state.pools) { 104 | var poolData = this.state.pools[i]; 105 | var pool = poolData.pool; 106 | var poolId = poolData.id; 107 | 108 | var actorClass = false; 109 | 110 | // xxxHonza: there are actors stored as pools. 111 | // See also: https://bugzilla.mozilla.org/show_bug.cgi?id=1119790#c1 112 | if (!Array.isArray(pool)) { 113 | pool = [pool]; 114 | actorClass = true; 115 | } 116 | 117 | pools.push(PoolTable({ 118 | pool: pool, 119 | actorClass: actorClass, 120 | id: poolId, 121 | key: i, 122 | searchFilter: this.state.searchFilter 123 | })); 124 | } 125 | 126 | return ( 127 | div({className: "poolContainer"}, 128 | pools 129 | ) 130 | ); 131 | } 132 | })); 133 | 134 | var Pools = { 135 | render: function(parentNode) { 136 | return React.render(PoolList(), parentNode); 137 | } 138 | }; 139 | 140 | // Exports from this module 141 | exports.Pools = Pools; 142 | 143 | }); 144 | -------------------------------------------------------------------------------- /data/inspector/components/search-box.js: -------------------------------------------------------------------------------- 1 | /* See license.txt for terms of usage */ 2 | 3 | define(function(require, exports/*, module*/) { 4 | 5 | "use strict"; 6 | 7 | /** 8 | * TODO docs xxxHonza: can we use ReactJS? 9 | */ 10 | var SearchBox = 11 | /** @lends SearchBox */ 12 | { 13 | create: function(parentNode) { 14 | var doc = parentNode.ownerDocument; 15 | var tabArea = doc.querySelector(".mainTabbedArea [role=tablist] .nav-tabs"); 16 | var item = doc.createElement("li"); 17 | tabArea.appendChild(item); 18 | 19 | // Search box 20 | var searchBox = doc.createElement("input"); 21 | searchBox.setAttribute("class", "searchBox"); 22 | searchBox.setAttribute("type", "search"); 23 | searchBox.setAttribute("results", "true"); 24 | item.appendChild(searchBox); 25 | 26 | searchBox.addEventListener("command", this.onChange.bind(this, searchBox), false); 27 | searchBox.addEventListener("input", this.onChange.bind(this, searchBox), false); 28 | searchBox.addEventListener("keypress", this.onKeyPress.bind(this, searchBox), false); 29 | }, 30 | 31 | destroy: function(parentNode) { 32 | var doc = parentNode.ownerDocument; 33 | var searchBox = doc.querySelector(".searchBox"); 34 | searchBox.remove(); 35 | }, 36 | 37 | onKeyPress: function(searchBox/*, event*/) { 38 | this.onSearch(searchBox); 39 | }, 40 | 41 | onChange: function(searchBox/*, event*/) { 42 | this.onSearch(searchBox); 43 | }, 44 | 45 | onSearch: function(searchBox) { 46 | var win = searchBox.ownerDocument.defaultView; 47 | var event = new win.MessageEvent("search", { 48 | data: searchBox.value 49 | }); 50 | win.dispatchEvent(event); 51 | } 52 | }; 53 | 54 | // Exports from this module 55 | exports.SearchBox = SearchBox; 56 | }); 57 | -------------------------------------------------------------------------------- /data/inspector/components/stack-frame-rep.js: -------------------------------------------------------------------------------- 1 | /* See license.txt for terms of usage */ 2 | 3 | define(function(require, exports /*, module */) { 4 | 5 | "use strict"; 6 | 7 | // ReactJS 8 | const React = require("react"); 9 | 10 | // Firebug SDK 11 | const { Reps } = require("reps/reps"); 12 | const { ObjectBox } = require("reps/object-box"); 13 | 14 | // Constants 15 | const { span } = React.DOM; 16 | 17 | // RDP Window injected APIs 18 | const { postChromeMessage } = require("shared/rdp-inspector-window"); 19 | 20 | /** 21 | * This component is responsible for rendering a stack frame. 22 | */ 23 | var StackFrameRep = React.createClass({ 24 | /** @lends StackFrameRep */ 25 | 26 | displayName: "StackFrameRep", 27 | 28 | render: function() { 29 | var stackFrame = this.props.object; 30 | var name = stackFrame.name; 31 | var label = stackFrame.getLabel(); 32 | 33 | return ( 34 | ObjectBox({className: "stackFrame"}, 35 | span({className: "stackName"}, name + "()"), 36 | span({className: "stackLabel", onClick: this.onViewSource}, label) 37 | ) 38 | ); 39 | }, 40 | 41 | onViewSource: function(event) { 42 | event.stopPropagation(); 43 | event.preventDefault(); 44 | 45 | // xxxHonza: how to get reference to the action list? 46 | /*this.props.actions.onViewSource({ 47 | url: topFrame.fileName, 48 | lineNumber: topFrame.lineNumber 49 | });*/ 50 | 51 | var frame = this.props.object; 52 | postChromeMessage("view-source", { 53 | url: frame.url, 54 | lineNumber: frame.lineNumber 55 | }); 56 | } 57 | }); 58 | 59 | // Registration 60 | 61 | function supportsObject(object/*, type*/) { 62 | return object instanceof StackFrame; 63 | } 64 | 65 | Reps.registerRep({ 66 | rep: React.createFactory(StackFrameRep), 67 | supportsObject: supportsObject 68 | }); 69 | 70 | // helper classes using in the packets reducers 71 | 72 | // StackTrace 73 | 74 | // xxxHonza: revisit frame filtering should and find solid way. 75 | function StackTrace(frames, packetType) { 76 | // Remove all frames before 'EventEmitter_emit()' frame. 77 | // These are part of the infrastructure (always there). 78 | if (packetType == "send") { 79 | //frames = filterFrames(frames, "DebuggerClient.requester/<"); 80 | //frames = filterFrames(frames, "EventEmitter_emit"); 81 | //frames = filterFrames(frames, "makeInfallible/<", true); 82 | } 83 | 84 | // Filter out empty frames 85 | frames = frames.filter(frame => !!frame.name); 86 | 87 | // Create StackFrame instances, so the right rep is used for 88 | // rendering (see {@StackFrameRep}. 89 | this.frames = frames.map(frame => new StackFrame(frame)); 90 | } 91 | 92 | StackTrace.prototype = { 93 | hasFrames: function() { 94 | return this.frames.length > 0; 95 | }, 96 | 97 | getTopFrame: function() { 98 | return this.hasFrames() ? this.frames[0] : null; 99 | }, 100 | }; 101 | 102 | // StackFrame 103 | 104 | function StackFrame(frame) { 105 | this.url = frame.fileName; 106 | this.lineNumber = frame.lineNumber; 107 | this.columnNumber = frame.columnNumber; 108 | this.name = frame.name; 109 | } 110 | 111 | StackFrame.prototype = { 112 | getLabel: function() { 113 | var path = this.url; 114 | var index = path ? path.lastIndexOf("/") : -1; 115 | var label = (index == -1) ? path : path.substr(index + 1); 116 | 117 | if (this.lineNumber) { 118 | label += ":" + this.lineNumber; 119 | } 120 | 121 | if (this.columnNumber) { 122 | label += ":" + this.columnNumber; 123 | } 124 | 125 | return label; 126 | }, 127 | 128 | getUrl: function() { 129 | return this.url; 130 | } 131 | }; 132 | 133 | // Helpers 134 | 135 | /* NOTE: currently unused */ 136 | /* 137 | function filterFrames(frames, pivot, onlyFirst) { 138 | var frame; 139 | 140 | if (onlyFirst) { 141 | for (frame of frames) { 142 | if (frame.name == pivot) { 143 | frames.shift(); 144 | } else { 145 | break; 146 | } 147 | } 148 | return frames; 149 | } 150 | 151 | var newFrames = []; 152 | var remove = true; 153 | for (frame of frames) { 154 | if (!remove) { 155 | newFrames.push(frame); 156 | } 157 | 158 | if (frame.name == pivot) { 159 | remove = false; 160 | } 161 | } 162 | 163 | // The pivot frame wasn't found. 164 | if (remove) { 165 | newFrames = frames; 166 | } 167 | 168 | return newFrames; 169 | } 170 | */ 171 | 172 | 173 | // Exports from this module 174 | exports.StackFrameRep = StackFrameRep; 175 | exports.StackTrace = StackTrace; 176 | exports.StackFrame = StackFrame; 177 | 178 | }); 179 | -------------------------------------------------------------------------------- /data/inspector/components/text-with-tooltip.js: -------------------------------------------------------------------------------- 1 | /* See license.txt for terms of usage */ 2 | 3 | define(function(require, exports/*, module*/) { 4 | 5 | "use strict"; 6 | 7 | // ReactJS 8 | const React = require("react"); 9 | 10 | // Constants 11 | const { Tooltip, OverlayTrigger } = require("shared/react-bootstrap-factories"); 12 | 13 | const { div } = React.DOM; 14 | 15 | /** 16 | * @template Helper template responsible for rendering a tooltip. 17 | */ 18 | const TextWithTooltip = React.createFactory(React.createClass({ 19 | displayName: "TextWithTooltip", 20 | 21 | render: function() { 22 | var tooltip = Tooltip({}, this.props.tooltip); 23 | return ( 24 | OverlayTrigger({placement: "top", overlay: tooltip, delayShow: 200, 25 | delayHide: 150}, 26 | div({className: this.props.className, onClick: this.props.onClick}, 27 | this.props.children 28 | ) 29 | ) 30 | ); 31 | } 32 | })); 33 | 34 | // Exports from this module 35 | exports.TextWithTooltip = TextWithTooltip; 36 | }); 37 | -------------------------------------------------------------------------------- /data/inspector/config.js: -------------------------------------------------------------------------------- 1 | /* See license.txt for terms of usage */ 2 | 3 | /* globals requirejs */ 4 | 5 | // RequireJS configuration 6 | require.config({ 7 | baseUrl: ".", 8 | scriptType: "application/javascript;version=1.8", 9 | paths: { 10 | "shared": "../shared", 11 | "jquery": "../lib/jquery/jquery", 12 | "react": "../lib/react/react", 13 | "react-dom": "../lib/react/react-dom", 14 | "bootstrap": "../lib/bootstrap/js/bootstrap", 15 | "immutable": "../lib/immutable/immutable", 16 | "react-bootstrap": "../lib/react-bootstrap/react-bootstrap", 17 | "reps": "../../node_modules/firebug.sdk/lib/reps", 18 | "firebug.sdk": "../../node_modules/firebug.sdk", 19 | "redux": "../lib/redux/redux", 20 | "react-redux": "../lib/redux/react-redux", 21 | } 22 | }); 23 | 24 | // Load the main panel module 25 | requirejs(["main"]); 26 | -------------------------------------------------------------------------------- /data/inspector/containers/app.js: -------------------------------------------------------------------------------- 1 | /* See license.txt for terms of usage */ 2 | 3 | define(function(require, exports/*, module*/) { 4 | 5 | "use strict"; 6 | 7 | // React & Redux 8 | const React = require("react"); 9 | const { connect } = require("react-redux"); 10 | 11 | // Connections List components 12 | const MainTabbedArea = require("../components/main-tabbed-area"); 13 | 14 | const App = React.createClass({ 15 | displayName: "App", 16 | 17 | render() { 18 | return React.createElement(MainTabbedArea, { 19 | view: this.props.view, 20 | global: this.props.global, 21 | actors: this.props.actors, 22 | packets: this.props.packets, 23 | }); 24 | } 25 | }); 26 | 27 | function mapStoreToProps(state) { 28 | let { global, actors, packets } = state; 29 | return { global, actors, packets }; 30 | } 31 | 32 | exports.App = connect(mapStoreToProps)(App); 33 | 34 | }); 35 | -------------------------------------------------------------------------------- /data/inspector/css/actors-panel.css: -------------------------------------------------------------------------------- 1 | /* See license.txt for terms of usage */ 2 | 3 | /******************************************************************************/ 4 | /* Actors Panel */ 5 | 6 | .poolContainer { 7 | font-size: 12px; 8 | } 9 | 10 | .poolTable { 11 | border: 1px solid rgb(221, 221, 221); 12 | width: 100%; 13 | margin-bottom: 10px; 14 | } 15 | 16 | .poolRow TD, 17 | .poolRow TH { 18 | border-bottom: 1px solid rgb(221, 221, 221); 19 | padding-left: 10px; 20 | } 21 | 22 | .poolTable.actorClass { 23 | background-color: rgb(247, 247, 247); 24 | } 25 | -------------------------------------------------------------------------------- /data/inspector/css/base.css: -------------------------------------------------------------------------------- 1 | /* See license.txt for terms of usage */ 2 | 3 | /******************************************************************************/ 4 | /* General */ 5 | 6 | body { 7 | background-color: white; 8 | padding: 0; 9 | margin: 0; 10 | height: 100%; 11 | } 12 | 13 | *:focus { 14 | outline: none !important; 15 | } 16 | 17 | #content { 18 | height: 100%; 19 | } 20 | 21 | #content > DIV { 22 | height: 100%; 23 | } 24 | -------------------------------------------------------------------------------- /data/inspector/css/packets-panel.css: -------------------------------------------------------------------------------- 1 | /* See license.txt for terms of usage */ 2 | 3 | /******************************************************************************/ 4 | /* Packets Panel */ 5 | 6 | .packetPanel { 7 | margin-bottom: 6px; 8 | font-size: 11px; 9 | font-family: Lucida Grande, Tahoma, sans-serif; 10 | line-height: 15px; 11 | } 12 | 13 | .packetPanel .packetBox { 14 | display: inline-block; 15 | max-width: 90%; 16 | } 17 | 18 | .packetPanel .packetContent { 19 | display: flex; 20 | } 21 | 22 | .packetPanel.receive .boxArrow { 23 | background-image: url("../res/received-arrow.png"); 24 | background-repeat: no-repeat; 25 | background-position: 0 center; 26 | margin-right: -1px; 27 | order: 1; 28 | width: 8px; 29 | z-index: 2; 30 | min-width: 8px; 31 | } 32 | 33 | .packetPanel.receive.selected .boxArrow { 34 | background-image: url("../res/received-arrow-selected.png"); 35 | } 36 | 37 | .packetPanel.send .boxArrow { 38 | background-image: url("../res/sent-arrow.png"); 39 | background-repeat: no-repeat; 40 | background-position: 0 center; 41 | margin-left: -1px; 42 | order: 3; 43 | width: 9px; 44 | min-width: 9px; 45 | z-index: 2; 46 | } 47 | 48 | .packetPanel.send.selected .boxArrow { 49 | background-image: url("../res/sent-arrow-selected.png"); 50 | } 51 | 52 | .packetPanel .body { 53 | display: inline-block; 54 | padding: 2px 5px 2px 5px; 55 | border: 1px solid #bfccd1; 56 | border-radius: 3px; 57 | min-width: 270px; 58 | background-image: linear-gradient(rgba(255, 255, 255, 0.7), rgba(255, 255, 255, 0.0)); 59 | order: 2; 60 | z-index: 1; 61 | } 62 | 63 | .packetPanel.receive .body { 64 | background-color: rgb(252, 248, 227); 65 | } 66 | 67 | .packetPanel.send .body { 68 | background-color: rgb(223, 240, 216); 69 | text-align: left; 70 | } 71 | 72 | .packetPanel.send { 73 | text-align: left; 74 | } 75 | 76 | .packetPanel.send { 77 | text-align: right; 78 | } 79 | 80 | .packetPanel .body .text { 81 | color: gray; 82 | } 83 | 84 | .packetPanel.error .body { 85 | background-color: rgb(255, 221, 221); 86 | } 87 | 88 | .packetPanel.selected .body { 89 | border-color: rgb(0, 170, 214); 90 | background-color: rgb(173, 211, 232); 91 | } 92 | 93 | .packetPanel .type, 94 | .packetPanel .to, 95 | .packetPanel .from { 96 | color: red; 97 | font-family: monospace; 98 | } 99 | 100 | .packetPanel .info { 101 | color: gray; 102 | font-size: 10px; 103 | text-align: right; 104 | margin-left: 20px; 105 | display: inline-flex; 106 | font-family: monospace; 107 | float: right; 108 | padding-top: 4px; 109 | } 110 | 111 | .packetPanel .stack:hover { 112 | text-decoration: underline; 113 | } 114 | 115 | .packetPanel .arrow { 116 | margin: 0 5px 0 5px; 117 | } 118 | 119 | .packetPanel .arrow.hide { 120 | display: none; 121 | } 122 | .packetPanel .from { 123 | padding-bottom: 5px;} 124 | 125 | .packetPanel .errorMessage { 126 | color: red; 127 | margin-bottom: 5px; 128 | } 129 | 130 | /******************************************************************************/ 131 | /* Inline Packet Details Preview */ 132 | 133 | .packetPanel .preview { 134 | overflow: auto; 135 | width: 100%; 136 | } 137 | 138 | .packetPanel .memberRow:hover { 139 | background-color: transparent; 140 | } 141 | 142 | .packetPanel .domTable > tbody > tr > td { 143 | border-bottom: transparent; 144 | } 145 | 146 | /******************************************************************************/ 147 | 148 | .packetsPanelBox { 149 | height: 100%; 150 | } 151 | 152 | .packetsPanelBox TD { 153 | vertical-align: top; 154 | } 155 | 156 | .packetsPanelBox .list { 157 | /* xxxHonza: minus the toolbar height*/ 158 | height: calc(100% - 30px); 159 | overflow: auto; 160 | padding: 10px; 161 | } 162 | 163 | .packetsPanelBox .details { 164 | border-left: 1px solid #EFEFEF; 165 | height: 100%; 166 | overflow: auto; 167 | } 168 | 169 | .tabPacketsPane { 170 | height: 100%; 171 | padding: 0px; 172 | } 173 | 174 | /******************************************************************************/ 175 | /* Packets Summary */ 176 | 177 | .packetsSummary { 178 | color: gray; 179 | font-size: 10px; 180 | border-top: 1px dotted #EFEFEF; 181 | margin: 10px 0 20px 0; 182 | padding: 2px 0 2px 0; 183 | } 184 | 185 | .packetsSummary DIV { 186 | display: inline-block; 187 | } 188 | 189 | .packetsSummary .time { 190 | float: right; 191 | font-family: monospace; 192 | } 193 | 194 | .packetsSummary .separator { 195 | width: 20px; 196 | } 197 | 198 | .packetsSummary .text { 199 | padding-right: 3px; 200 | } 201 | 202 | .packetsSummary .slash { 203 | width: 10px; 204 | text-align: center; 205 | } 206 | 207 | .tooltip-inner { 208 | max-width: 110px; 209 | } 210 | 211 | /******************************************************************************/ 212 | /* Packets Limit */ 213 | 214 | .packetsLimit { 215 | text-align: center; 216 | margin: 10px 0 20px 0; 217 | } 218 | 219 | .packetsLimit .text { 220 | padding: 2px 3px 2px 3px; 221 | color: gray; 222 | font-size: 12px; 223 | border: 1px solid #bfccd1; 224 | border-radius: 3px; 225 | background-color: rgb(219, 234, 249) !important; 226 | background-image: linear-gradient(rgba(255, 255, 255, 0.8), rgba(255, 255, 255, 0.2)); 227 | } 228 | 229 | /******************************************************************************/ 230 | /* Packets Message */ 231 | 232 | .packetsMessage { 233 | color: gray; 234 | font-size: 10px; 235 | border-top: 1px dotted #EFEFEF; 236 | margin: 10px 0 20px 0; 237 | padding: 2px 0 2px 0; 238 | } 239 | 240 | .packetsMessage DIV { 241 | display: inline-block; 242 | } 243 | 244 | .packetsMessage .time { 245 | float: right; 246 | font-family: monospace; 247 | } 248 | 249 | .packetsMessage .text { 250 | padding-right: 3px; 251 | } 252 | 253 | /******************************************************************************/ 254 | /* StackFrame */ 255 | 256 | .stackSidePanel { 257 | height: 100%; 258 | overflow: auto; 259 | } 260 | 261 | .stackSidePanel .preview { 262 | overflow: auto; 263 | width: 100%; 264 | } 265 | 266 | .stackSidePanel .objectBox-stackFrame .stackName { 267 | display: inline-flex; 268 | font-family: monospace; 269 | float: left; 270 | text-align: left; 271 | } 272 | 273 | .packetPanel .stackFrameLabel, 274 | .stackSidePanel .objectBox-stackFrame .stackLabel { 275 | color: blue; 276 | text-align: right; 277 | display: inline-flex; 278 | font-family: monospace; 279 | float: right; 280 | cursor: pointer; 281 | margin-right: 4px; 282 | } 283 | 284 | .packetPanel .stackFrameLabel { 285 | font-size: 10px; 286 | margin-top: 4px; 287 | float: left; 288 | } 289 | -------------------------------------------------------------------------------- /data/inspector/css/search-box.css: -------------------------------------------------------------------------------- 1 | /* See license.txt for terms of usage */ 2 | 3 | /******************************************************************************/ 4 | /* Search Box */ 5 | 6 | .searchBox { 7 | height: 21px; 8 | font-size: 12px; 9 | margin-top: 2px; 10 | border: 1px solid rgb(170, 188, 207); 11 | width: 200px; 12 | position: fixed; /* xxxHonza: how to avoid fixed position? */ 13 | right: 5px; 14 | background-image: url("chrome://rdpinspector/skin/search.svg"); 15 | background-repeat: no-repeat; 16 | background-position: 2px center; 17 | padding-left: 20px; 18 | } 19 | -------------------------------------------------------------------------------- /data/inspector/css/toolbar.css: -------------------------------------------------------------------------------- 1 | /* See license.txt for terms of usage */ 2 | 3 | /******************************************************************************/ 4 | /* Toolbar */ 5 | 6 | .toolbar { 7 | height: 30px; 8 | padding: 4px; 9 | border-bottom: 1px solid rgb(170, 188, 207); 10 | background-color: rgb(219, 234, 249) !important; 11 | background-image: linear-gradient(rgba(255, 255, 255, 0.8), rgba(255, 255, 255, 0.2)); 12 | } 13 | 14 | .toolbar .btn { 15 | border-radius: 2px; 16 | color: #141414; 17 | } 18 | 19 | .toolbar select { 20 | margin-left: 3px; 21 | line-height: 1.0; 22 | font-size: 12px; 23 | } 24 | 25 | .toolbar input[type="checkbox"] { 26 | margin-right: 8px; 27 | } 28 | 29 | /******************************************************************************/ 30 | /* Tooltip */ 31 | 32 | .tooltip .tooltip-inner { 33 | background-color: #EEE1B3; 34 | color: black; 35 | max-width: 300px; 36 | } 37 | .tooltip.bottom .tooltip-arrow { 38 | border-bottom-color: #EEE1B3; 39 | color: black; 40 | } 41 | -------------------------------------------------------------------------------- /data/inspector/css/toolbox.css: -------------------------------------------------------------------------------- 1 | /* See license.txt for terms of usage */ 2 | 3 | /******************************************************************************/ 4 | /* Main Tabs */ 5 | 6 | .mainTabbedArea { 7 | background-color: rgb(219, 234, 249); 8 | background-image: linear-gradient(rgba(253, 253, 253, 0.2), rgba(253, 253, 253, 0)); 9 | } 10 | 11 | .mainTabbedArea li a { 12 | padding: 3px 8px; 13 | font-weight: bold; 14 | color: #565656; 15 | } 16 | 17 | .mainTabbedArea li.active a, 18 | .mainTabbedArea li.active a:focus { 19 | background-color: rgb(247, 251, 254); 20 | border: 1px solid rgb(170, 188, 207); 21 | border-bottom-color: transparent; 22 | } 23 | 24 | .mainTabbedArea li:hover a { 25 | border: 1px solid #C8C8C8; 26 | border-bottom: 1px solid transparent; 27 | background-color: transparent !important; 28 | } 29 | 30 | .mainTabbedArea li.active:hover a { 31 | border: 1px solid rgb(170, 188, 207) !important; 32 | background-color: rgb(247, 251, 254) !important; 33 | border-bottom-color: transparent !important; 34 | } 35 | 36 | .mainTabbedArea .nav-tabs { 37 | padding-top: 3px; 38 | padding-left: 3px; 39 | height: 30px; 40 | border-bottom-color: rgb(170, 188, 207); 41 | background-color: rgb(219, 234, 249) !important; 42 | background-image: linear-gradient(rgba(255, 255, 255, 0.8), rgba(255, 255, 255, 0.2)); 43 | } 44 | 45 | .tab-content { 46 | /* xxxHonza: minus the height of the tab bar */ 47 | height: calc(100% - 31px); 48 | } 49 | 50 | .tab-pane { 51 | height: 100%; 52 | padding: 0px; 53 | background-color: white; 54 | } 55 | 56 | /******************************************************************************/ 57 | /* SideBar */ 58 | 59 | .sideBarTabbedArea { 60 | height: 30px; 61 | border-bottom: 1px solid rgb(170, 188, 207); 62 | background-color: rgb(219, 234, 249) !important; 63 | background-image: linear-gradient(rgba(255, 255, 255, 0.8), rgba(255, 255, 255, 0.2)); 64 | } 65 | 66 | .sideBarTabbedArea li a { 67 | padding: 4px 9px; 68 | font-weight: normal; 69 | font-size: 12px; 70 | font-family: "Helvetica Neue",Helvetica,Arial,sans-serif; 71 | color: #141414; 72 | } 73 | 74 | .sideBarTabbedArea li.active a, 75 | .sideBarTabbedArea li.active a:focus { 76 | background-color: white; 77 | border: 1px solid rgb(170, 188, 207); 78 | border-bottom-color: transparent; 79 | color: #141414; 80 | } 81 | 82 | .sideBarTabbedArea li:hover a { 83 | border-color: #C8C8C8; 84 | background-color: transparent; 85 | } 86 | 87 | .sideBarTabbedArea li.active:hover a { 88 | border: 1px solid rgb(170, 188, 207) !important; 89 | border-bottom-color: transparent !important; 90 | color: #141414 !important; 91 | } 92 | 93 | .sideBarTabbedArea.nav-tabs { 94 | padding-top: 3px; 95 | padding-left: 3px; 96 | } 97 | 98 | /******************************************************************************/ 99 | /* Panels */ 100 | 101 | .mainPanel { 102 | height: 100%; 103 | } 104 | 105 | .sidePanel { 106 | height: 100%; 107 | } 108 | 109 | .sidePanel > DIV { 110 | height: 100%; 111 | } 112 | 113 | /******************************************************************************/ 114 | /* Actors Panels */ 115 | 116 | .actorsPanelBox { 117 | height: calc(100% - 30px); 118 | } 119 | 120 | .actorsScrollBox { 121 | height: 100%; 122 | padding: 10px; 123 | overflow: auto; 124 | } 125 | -------------------------------------------------------------------------------- /data/inspector/css/tree-editor-view.css: -------------------------------------------------------------------------------- 1 | /* See license.txt for terms of usage */ 2 | 3 | /******************************************************************************/ 4 | /* Tree Editor View */ 5 | 6 | /* remove button on editable field */ 7 | .domTable.editable .memberRow .closeButton { 8 | display: none; 9 | position: absolute; 10 | right: 2px; 11 | } 12 | 13 | .domTable.editable .memberRow:hover .closeButton { 14 | display: inline-block; 15 | } 16 | 17 | /* new field row */ 18 | .domTable.editable .memberRow.newRow { 19 | background: #FFFEE1; 20 | } 21 | 22 | .domTable.editable .memberRow.newRow input { 23 | border: none; 24 | background: transparent; 25 | width: 100%; 26 | } 27 | 28 | .domTable.editable .memberRow.editRow input { 29 | border: 1px groove; 30 | width: 100%; 31 | } 32 | 33 | .domTable.editable .memberRow.editRow input.valid { 34 | border-color: green; 35 | background-color: rgba(0,210,0,0.2); 36 | } 37 | 38 | .domTable.editable .memberRow.editRow input.invalid { 39 | border-color: red; 40 | background-color: rgba(210,0,0,0.2); 41 | } 42 | 43 | .domTable.editable ul.suggestions { 44 | position: absolute; 45 | z-index: 9999; 46 | padding: 0; 47 | margin: 0; 48 | background-color: white; 49 | color: black; 50 | border: 1px solid buttonshadow; 51 | cursor: default; 52 | text-align: left; 53 | list-style-type: none; 54 | overflow: hidden; 55 | } 56 | 57 | .domTable.editable ul.suggestions:hover { 58 | overflow: auto; 59 | } 60 | 61 | .domTable.editable ul.suggestions li { 62 | padding: 2px; 63 | } 64 | 65 | .domTable.editable ul.suggestions li:hover { 66 | background: yellow; 67 | color: black; 68 | } 69 | 70 | /* FIX: missing close button on hover */ 71 | .closeButton:hover { 72 | filter: url("resource://rdpinspector-at-getfirebug-dot-com/node_modules/firebug.sdk/skin/classic/shared/filters.svg#darken") !important; 73 | } 74 | -------------------------------------------------------------------------------- /data/inspector/frame-script.js: -------------------------------------------------------------------------------- 1 | /* See license.txt for terms of usage */ 2 | 3 | (function(global) { 4 | 5 | "use strict"; 6 | 7 | const { 8 | Components, 9 | content, 10 | addEventListener, 11 | sendAsyncMessage, 12 | addMessageListener, 13 | /*removeMessageListener,*/ 14 | } = global; 15 | 16 | const Cu = Components.utils; 17 | /*const Cc = Components.classes; 18 | const Ci = Components.interfaces;*/ 19 | 20 | /*const document = content.document;*/ 21 | const window = content; 22 | 23 | /** 24 | * Listener for message from the chrome scope. It's further distributed 25 | * as DOM event, so it can be handled by the page content script. 26 | */ 27 | function messageListener(message) { 28 | const { type, data, origin, bubbles, cancelable } = message.data; 29 | 30 | const event = new window.MessageEvent(type, { 31 | bubbles: bubbles, 32 | cancelable: cancelable, 33 | data: data, 34 | origin: origin, 35 | target: window, 36 | source: window 37 | }); 38 | 39 | window.dispatchEvent(event); 40 | } 41 | 42 | addMessageListener("rdpinspector/event/message", messageListener); 43 | 44 | /** 45 | * Send a message back to the parent panel (chrome scope). 46 | */ 47 | function postChromeMessage(type, args, objects) { 48 | let data = { 49 | type: type, 50 | args: args 51 | }; 52 | 53 | sendAsyncMessage("message", data, objects); 54 | } 55 | 56 | /** 57 | * Export 'postChromeMessage' function to the frame content as soon 58 | * as it's loaded. This function allows sending messages from the 59 | * frame's content directly to the chrome scope. 60 | */ 61 | addEventListener("DOMContentLoaded", function onContentLoaded(/*event*/) { 62 | removeEventListener("DOMContentLoaded", onContentLoaded, true); 63 | 64 | Cu.exportFunction(postChromeMessage, window, { 65 | defineAs: "postChromeMessage" 66 | }); 67 | }, true); 68 | 69 | // End of scope 70 | })(this); 71 | -------------------------------------------------------------------------------- /data/inspector/main.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | -------------------------------------------------------------------------------- /data/inspector/main.js: -------------------------------------------------------------------------------- 1 | /* See license.txt for terms of usage */ 2 | 3 | define(function(require/*, exports, module*/) { 4 | 5 | "use strict"; 6 | 7 | // ReactJS 8 | var ReactDOM = require("react-dom"); 9 | 10 | // RDP Inspector 11 | const { Resizer } = require("shared/resizer"); 12 | const { ReactLazyFactories } = require("shared/react-helpers"); 13 | 14 | // generate React Factories 15 | const { Provider } = ReactLazyFactories(require("react-redux")); 16 | const { App } = ReactLazyFactories(require("./containers/app")); 17 | 18 | // Reps 19 | require("./components/stack-frame-rep"); 20 | 21 | // Search 22 | var { Search } = require("./search"); 23 | 24 | // RDP Window injected APIs 25 | var { postChromeMessage, RDPInspectorView } = require("shared/rdp-inspector-window"); 26 | 27 | // actions & store 28 | const store = window.store = require("./store").configureStore(); 29 | const actions = require("./actions/index.js"); 30 | 31 | const view = new RDPInspectorView({ 32 | window, actions, store, 33 | }); 34 | 35 | /** 36 | * Render the main application component. It's the main tab bar displayed 37 | * at the top of the window. This component also represents ReactJS root. 38 | */ 39 | view.render = function() { 40 | let content = document.querySelector("#content"); 41 | let provider = Provider({ store }, App({ view })); 42 | let app = ReactDOM.render(provider, content); 43 | 44 | /* eslint-disable no-new */ 45 | new Resizer(window, app); 46 | new Search(window, store); 47 | /* eslint-enable */ 48 | }; 49 | 50 | view.render(); 51 | // Send notification about initialization being done. 52 | postChromeMessage("initialized"); 53 | 54 | // End of main.js 55 | }); 56 | -------------------------------------------------------------------------------- /data/inspector/reducers/actors.js: -------------------------------------------------------------------------------- 1 | /* See license.txt for terms of usage */ 2 | 3 | define(function(require, exports, module) { 4 | 5 | "use strict"; 6 | 7 | // actions types 8 | const { types } = require("../actions/actors"); 9 | 10 | /** 11 | * Initial state definition 12 | */ 13 | const initialState = {}; 14 | 15 | function actorsReducer(state = initialState, action) { 16 | switch(action.type) { 17 | case types.SET_ACTORS: 18 | return setActors(state, action.actors); 19 | case types.CLEAR_ACTORS: 20 | return clearActors(state); 21 | default: 22 | return state; 23 | } 24 | } 25 | 26 | module.exports = actorsReducer; 27 | 28 | // helpers 29 | function clearActors() { 30 | return {}; 31 | } 32 | 33 | function setActors(state, actors) { 34 | let { tab, global } = actors; 35 | let actorIDs = collectActorIDs([ 36 | tab.actorPool, 37 | tab.extraPools, 38 | global.actorPool, 39 | global.extraPools 40 | ], []); 41 | 42 | return Object.assign({}, state, { 43 | tab, global, actorIDs 44 | }); 45 | } 46 | 47 | function collectActorIDs(data, res) { 48 | if (data instanceof Array) { 49 | data.forEach((item) => { 50 | collectActorIDs(item, res); 51 | }); 52 | } else if (data instanceof Object) { 53 | if (data.pool) { 54 | collectActorIDs(data.pool, res); 55 | } else if (data.actorID) { 56 | var { actorID } = data; 57 | if (res.indexOf(actorID) < 0) { 58 | res.push(actorID); 59 | } 60 | } 61 | } 62 | 63 | return res; 64 | } 65 | }); 66 | -------------------------------------------------------------------------------- /data/inspector/reducers/global.js: -------------------------------------------------------------------------------- 1 | /* See license.txt for terms of usage */ 2 | 3 | define(function(require, exports, module) { 4 | 5 | "use strict"; 6 | 7 | // actions types 8 | const { types } = require("../actions/global"); 9 | 10 | /** 11 | * Initial state definition 12 | */ 13 | const initialState = {}; 14 | 15 | function globalReducer(state = initialState, action) { 16 | switch(action.type) { 17 | case types.SET_SEARCH_FILTER: 18 | return setSearchFilter(state, action.filter); 19 | default: 20 | return state; 21 | } 22 | } 23 | 24 | module.exports = globalReducer; 25 | 26 | 27 | function setSearchFilter(state, filter) { 28 | return Object.assign({}, state, { 29 | searchFilter: filter 30 | }); 31 | } 32 | 33 | }); 34 | -------------------------------------------------------------------------------- /data/inspector/reducers/index.js: -------------------------------------------------------------------------------- 1 | /* See license.txt for terms of usage */ 2 | 3 | define(function(require, exports/*, module*/) { 4 | 5 | "use strict"; 6 | 7 | // Redux 8 | const { combineReducers } = require("redux"); 9 | 10 | // RDP Inspector 11 | const global = require("./global"); 12 | const actors = require("./actors"); 13 | const packets = require("./packets"); 14 | 15 | var rootReducer = combineReducers({ global, actors, packets }); 16 | 17 | // Exports from this module 18 | exports.rootReducer = rootReducer; 19 | }); 20 | -------------------------------------------------------------------------------- /data/inspector/reducers/packets.js: -------------------------------------------------------------------------------- 1 | /* See license.txt for terms of usage */ 2 | 3 | define(function(require, exports, module) { 4 | 5 | "use strict"; 6 | 7 | // RDP Window injected APIs 8 | const { Options, Locale } = require("shared/rdp-inspector-window"); 9 | const { StackTrace } = require("../components/stack-frame-rep"); 10 | 11 | // actions types 12 | const { types } = require("../actions/packets"); 13 | 14 | /** 15 | * Initial state definition 16 | */ 17 | const initialState = { 18 | paused: false, 19 | uniqueId: 0, 20 | options: {}, 21 | filter: null, 22 | editedPacket: null, 23 | selectedPacket: null, 24 | removedPackets: 0, 25 | filteredPackets: [], 26 | packets: [], 27 | summary: { 28 | data: { sent: 0, received: 0}, 29 | packets: { sent: 0, received: 0} 30 | }, 31 | error: null, 32 | }; 33 | 34 | function packetsReducer(state = initialState, action) { 35 | switch(action.type) { 36 | case types.IMPORT_PACKETS_FROMFILE: 37 | return importPacketsFromFile(state, action.data); 38 | case types.IMPORT_PACKETS_CACHE: 39 | return importPacketsCache(state, action.cache); 40 | case types.INIT_PACKETLIST_OPTIONS: 41 | return initPacketListOptions(state, action.options); 42 | case types.TOGGLE_PACKETLIST_OPTION: 43 | return togglePacketListOption(state, action.name); 44 | case types.TOGGLE_PACKETLIST_PAUSE: 45 | return togglePacketListPause(state); 46 | case types.APPEND_PACKET: 47 | return appendPacket(state, action.packetType, action.packetData); 48 | case types.APPEND_SUMMARY: 49 | return appendSummary(state, action.time); 50 | case types.APPEND_MESSAGE: 51 | return appendMessage(state, action.message, action.time); 52 | case types.SELECT_PACKET: 53 | return selectPacket(state, action.packet); 54 | case types.EDIT_PACKET: 55 | return editPacket(state, action.packet); 56 | case types.CLEAR_PACKET_LIST: 57 | return clearPacketList(state); 58 | case types.SET_PACKETLIST_ERROR: 59 | return setPacketListError(state, action.error); 60 | default: 61 | return state; 62 | } 63 | } 64 | 65 | module.exports = packetsReducer; 66 | 67 | // helpers 68 | 69 | function importPacketsFromFile(state, data) { 70 | let removedPackets = data.removedPackets || 0; 71 | let newState = clearPacketList(state); 72 | 73 | if (data.packets && data.packets.length > 0) { 74 | for (let packet of data.packets) { 75 | newState = appendToCollectedPackets(newState, packet); 76 | } 77 | } 78 | 79 | return Object.assign({}, newState, { removedPackets }); 80 | } 81 | 82 | function importPacketsCache(state, cache) { 83 | let removedPackets = cache.removedPackets || 0; 84 | let newState = state; 85 | 86 | if (cache.packets && cache.packets.length > 0) { 87 | for (let packet of cache.packets) { 88 | // TODO: Trace errors 89 | newState = appendPacket(newState, packet.type, packet); 90 | } 91 | } 92 | 93 | return Object.assign({}, newState, { removedPackets }); 94 | } 95 | 96 | function initPacketListOptions(state, options) { 97 | return Object.assign({}, state, { 98 | options 99 | }); 100 | } 101 | 102 | function togglePacketListOption(state, name) { 103 | let options = JSON.parse(JSON.stringify(state.options)); 104 | options[name] = !options[name]; 105 | 106 | return Object.assign({}, state, { 107 | options 108 | }); 109 | } 110 | 111 | function togglePacketListPause(state) { 112 | let paused = !state.paused; 113 | let newState; 114 | 115 | if (paused) { 116 | newState = appendMessage(state, Locale.$STR("rdpInspector.label.Paused"), new Date()); 117 | } else { 118 | newState = appendMessage(state, Locale.$STR("rdpInspector.label.Unpaused"), new Date()); 119 | } 120 | 121 | return Object.assign({}, newState, { 122 | paused 123 | }); 124 | } 125 | 126 | function appendToCollectedPackets(state, packet) { 127 | let limit = Options.getPref("extensions.rdpinspector.packetLimit"); 128 | 129 | if (state.packets.length >= limit) { 130 | state.packets.shift(); 131 | } 132 | 133 | let summary = JSON.parse(JSON.stringify(state.summary)); 134 | 135 | switch (packet.type) { 136 | case "send": 137 | summary.data.sent += packet.size; 138 | summary.packets.sent += 1; 139 | break; 140 | case "receive": 141 | summary.data.received += packet.size; 142 | summary.packets.received += 1; 143 | break; 144 | } 145 | 146 | packet.id = ++state.uniqueId; 147 | 148 | let packets = [ ...state.packets, packet]; 149 | let filteredPackets = filterRDPInspectPackets(packets); 150 | 151 | return Object.assign({}, state, { 152 | summary, packets, filteredPackets 153 | }); 154 | } 155 | 156 | function appendPacket(state, packetType, packetData) { 157 | let rawPacket = JSON.stringify(packetData.packet); 158 | let packet = { 159 | type: packetType, 160 | packet: packetData.packet, 161 | rawPacket, 162 | size: rawPacket.length, 163 | time: new Date(packetData.time), 164 | stack: new StackTrace(packetData.stack, packetType) 165 | }; 166 | 167 | return appendToCollectedPackets(state, packet); 168 | } 169 | 170 | function appendSummary(state, time) { 171 | return appendToCollectedPackets(state, { 172 | type: "summary", 173 | time, 174 | data: { 175 | sent: state.summary.data.sent, 176 | received: state.summary.data.received 177 | }, 178 | packets: { 179 | sent: state.summary.packets.sent, 180 | received: state.summary.packets.received 181 | } 182 | }); 183 | } 184 | 185 | function appendMessage(state, message, time) { 186 | return appendToCollectedPackets(state, { 187 | type: "message", time, message 188 | }); 189 | } 190 | 191 | function selectPacket(state, packet) { 192 | return Object.assign({}, state, { 193 | selectedPacket: packet 194 | }); 195 | } 196 | 197 | function editPacket(state, packet) { 198 | return Object.assign({}, state, { 199 | editedPacket: packet 200 | }); 201 | } 202 | 203 | function clearPacketList(state) { 204 | return Object.assign({}, state, { 205 | selectedPacket: null, 206 | packets: [], 207 | filteredPackets: [], 208 | summary: JSON.parse(JSON.stringify(initialState.summary)) 209 | }); 210 | } 211 | 212 | function setPacketListError(state, error) { 213 | // TODO: Trace errors 214 | return Object.assign({}, state, { error }); 215 | } 216 | 217 | function filterRDPInspectPackets(packets) { 218 | var filterFrom = {}; 219 | 220 | return packets.filter((packet) => { 221 | var actorId = packet.packet ? (packet.packet.to || packet.packet.from) : null; 222 | 223 | // filter our all the RDPi actorInspector actor 224 | if (actorId && actorId.indexOf("actorInspector") > 0) { 225 | return false; 226 | } 227 | 228 | if (packet.type == "send") { 229 | // filter sent RDP packets needed to register the RDPi actorInspector actor 230 | if (packet.packet.rdpInspectorInternals) { 231 | filterFrom[packet.packet.to] = filterFrom[packet.packet.to] || 0; 232 | filterFrom[packet.packet.to] += 1; 233 | 234 | return false; 235 | } 236 | 237 | // filter sent RDP packets needed to register the RDPi actorInspector actor 238 | if (packet.packet.type == "registerActor" && 239 | packet.packet.filename.indexOf("rdpinspector-at-getfirebug-dot-com") > 0) { 240 | filterFrom[packet.packet.to] = filterFrom[packet.packet.to] || 0; 241 | filterFrom[packet.packet.to] += 1; 242 | return false; 243 | } 244 | } 245 | 246 | // filter received RDP packets needed to register the RDPi actorInspector actor 247 | if (packet.type == "receive" && filterFrom[packet.packet.from] > 0) { 248 | filterFrom[packet.packet.from] -= 1; 249 | return false; 250 | } 251 | 252 | return true; 253 | }); 254 | } 255 | 256 | }); 257 | -------------------------------------------------------------------------------- /data/inspector/res/arrow.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 14 | 16 | 18 | 22 | 26 | 27 | 29 | 33 | 37 | 38 | 47 | 56 | 57 | 59 | 60 | 62 | image/svg+xml 63 | 65 | 66 | 67 | 68 | 69 | 72 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /data/inspector/res/icon-16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firebug/rdp-inspector/60b22d880d9ea334e638b14c69102e8ed5c5c1e6/data/inspector/res/icon-16.png -------------------------------------------------------------------------------- /data/inspector/res/received-arrow-selected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firebug/rdp-inspector/60b22d880d9ea334e638b14c69102e8ed5c5c1e6/data/inspector/res/received-arrow-selected.png -------------------------------------------------------------------------------- /data/inspector/res/received-arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firebug/rdp-inspector/60b22d880d9ea334e638b14c69102e8ed5c5c1e6/data/inspector/res/received-arrow.png -------------------------------------------------------------------------------- /data/inspector/res/sent-arrow-selected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firebug/rdp-inspector/60b22d880d9ea334e638b14c69102e8ed5c5c1e6/data/inspector/res/sent-arrow-selected.png -------------------------------------------------------------------------------- /data/inspector/res/sent-arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firebug/rdp-inspector/60b22d880d9ea334e638b14c69102e8ed5c5c1e6/data/inspector/res/sent-arrow.png -------------------------------------------------------------------------------- /data/inspector/search.js: -------------------------------------------------------------------------------- 1 | /* See license.txt for terms of usage */ 2 | 3 | define(function(require, exports/*, module*/) { 4 | 5 | "use strict"; 6 | 7 | const actions = require("./actions/index"); 8 | 9 | /** 10 | * This object is responsible for listening search events 11 | * and updating application state (the root RJS component). 12 | */ 13 | function Search(win, store) { 14 | this.win = win; 15 | this.store = store; 16 | 17 | this.win.addEventListener("search", this.onSearch.bind(this)); 18 | } 19 | 20 | Search.prototype = 21 | /** @lends Search */ 22 | { 23 | onSearch: function(event) { 24 | var value = event.data; 25 | this.store.dispatch(actions.setSearchFilter(value)); 26 | } 27 | }; 28 | 29 | // Exports from this module 30 | exports.Search = Search; 31 | }); 32 | -------------------------------------------------------------------------------- /data/inspector/store.js: -------------------------------------------------------------------------------- 1 | /* See license.txt for terms of usage */ 2 | 3 | define(function(require, exports/*, module*/) { 4 | 5 | "use strict"; 6 | 7 | // Redux 8 | const { createStore } = require("redux"); 9 | 10 | // RDP Inspector 11 | const { rootReducer } = require("./reducers/index"); 12 | 13 | function configureStore(initialState) { 14 | return createStore(rootReducer, initialState); 15 | } 16 | 17 | // Exports from this module 18 | exports.configureStore = configureStore; 19 | 20 | }); 21 | -------------------------------------------------------------------------------- /data/lib/bootstrap/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firebug/rdp-inspector/60b22d880d9ea334e638b14c69102e8ed5c5c1e6/data/lib/bootstrap/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /data/lib/bootstrap/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firebug/rdp-inspector/60b22d880d9ea334e638b14c69102e8ed5c5c1e6/data/lib/bootstrap/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /data/lib/bootstrap/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firebug/rdp-inspector/60b22d880d9ea334e638b14c69102e8ed5c5c1e6/data/lib/bootstrap/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /data/lib/bootstrap/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firebug/rdp-inspector/60b22d880d9ea334e638b14c69102e8ed5c5c1e6/data/lib/bootstrap/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /data/lib/react/react-dom.js: -------------------------------------------------------------------------------- 1 | /** 2 | * ReactDOM v0.14.2 3 | * 4 | * Copyright 2013-2015, Facebook, Inc. 5 | * All rights reserved. 6 | * 7 | * This source code is licensed under the BSD-style license found in the 8 | * LICENSE file in the root directory of this source tree. An additional grant 9 | * of patent rights can be found in the PATENTS file in the same directory. 10 | * 11 | */ 12 | // Based off https://github.com/ForbesLindesay/umd/blob/master/template.js 13 | ;(function(f) { 14 | // CommonJS 15 | if (typeof exports === "object" && typeof module !== "undefined") { 16 | module.exports = f(require('react')); 17 | 18 | // RequireJS 19 | } else if (typeof define === "function" && define.amd) { 20 | define(['react'], f); 21 | 22 | //