Permalink
Browse files

migrating from angular to react/flux

  • Loading branch information...
Phoenixmatrix committed May 6, 2015
1 parent 6bebad9 commit 2d649e13a56b5c1b4f09d0d29724978be3caaa6d
Showing with 915 additions and 1,341 deletions.
  1. +17 −2 README.md
  2. +2 −2 gulpfile.js
  3. +3 −90 index.html
  4. +6 −4 index.js
  5. +10 −0 js/actions/config-actions.js
  6. +30 −0 js/actions/request-actions.js
  7. +11 −5 js/app.js
  8. +9 −0 js/components/Footer.jsx
  9. +29 −0 js/components/Header.jsx
  10. +49 −0 js/components/HttpHeaders.jsx
  11. +21 −0 js/components/LeftSection.jsx
  12. +27 −0 js/components/MainSection.jsx
  13. +69 −0 js/components/PhoenixMatrixApp.jsx
  14. +33 −0 js/components/RequestBody.jsx
  15. +28 −0 js/components/RequestDetail.jsx
  16. +30 −0 js/components/RequestDetailHeader.jsx
  17. +83 −0 js/components/RequestList.jsx
  18. +37 −0 js/components/RequestListItem.jsx
  19. +28 −0 js/components/ResponseDetail.jsx
  20. +103 −0 js/components/Splitter.jsx
  21. +48 −0 js/components/VerticalButtonBar.jsx
  22. +3 −0 js/constants/config-constants.js
  23. +6 −0 js/constants/request-constants.js
  24. +0 −6 js/controllers/index.js
  25. +0 −61 js/controllers/proxy.js
  26. +0 −6 js/directives/index.js
  27. +0 −144 js/directives/requestList.js
  28. +3 −0 js/dispatchers/AppDispatcher.js
  29. +0 −3 js/filters/index.js
  30. +1 −1 js/lib/config.js
  31. +0 −8 js/services/index.js
  32. +0 −15 js/services/requestFilter.js
  33. +0 −74 js/services/requests.js
  34. +38 −0 js/stores/config-store.js
  35. +158 −0 js/stores/request-store.js
  36. +32 −18 package.json
  37. +1 −1 phoenixmatrix.json
  38. 0 vendor/splitter/style.css → stylesheets/splitter.less
  39. +0 −242 vendor/angular/angular.min.js
  40. +0 −8 vendor/angular/angular.min.js.map
  41. +0 −551 vendor/bootstrap-ui/ui-bootstrap-custom-tpls-0.12.0.js
  42. +0 −90 vendor/splitter/splitter.js
  43. +0 −10 views/request-header.html
View
@@ -3,7 +3,7 @@ PhoenixMatrix web development proxy
[![Join the chat at https://gitter.im/Phoenixmatrix/phoenixmatrix-proxy](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/Phoenixmatrix/phoenixmatrix-proxy?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
_v0.2.0 technical preview_
_v0.2.1 technical preview_
Web debugging proxy in the spirit of Fiddler and Charles Proxy, written in JavaScript with [Electron Shell](http://electron.atom.io/)
and node.
@@ -12,6 +12,9 @@ Tested on MacOSX Yosemite, Windows 8.1 and Ubuntu 14.
## Release notes
**v0.2.0**
* Migrated from Angular to React
**v0.2.0**
* Moved from nw.js to Electron Shell
* Updated to the latest version of Babel
@@ -46,7 +49,7 @@ Again, the code is a mess. Please don't look at it and email me that its bad. Fo
* Open a command prompt and navigate to the location where you cloned it.
* Run `npm install`. Electron Shell will be downloaded here, so expect a big download.
* Run `gulp`
* You should now see the inspector. Setup the proxy in your browser of choice (or in your application), and you're good to go!
* You should now see the GUI application. Setup the proxy in your browser of choice (or in your application), and you're good to go!
* From now on you can use `npm start` to run PhoenixMatrix without rebuilding everything.
### Configuring your browser to use the proxy
@@ -75,6 +78,13 @@ The available options can be found in phoenixmatrix.json, in JSON format (duh!).
if you point your browser to it directly.
* `certificateExpiration`: how many days should the generated certificates be valid for
### Hacking and debugging PhoenixMatrix
PhoenixMatrix is built on top of Electron Shell, which in turn is built on top of Chromium and iojs.
This means you can easily add features or hack it up the same way you would a web page built with React and node/iojs.
Like the Chrome browser, Electron Shell supports the devtools you know: with the window focused, just hit ctrl+shift+i (command+shift+i on mac)!
### Caveats
* On MacOSX, when using the trackpad, scrolling isn't as smooth as it should be.
* On windows, make sure you have OpenSSL installed, and it is in the path. [Git Bash](http://git-scm.com/downloads)
@@ -87,10 +97,15 @@ even though you imported it, just delete the content of the certificate folder,
upstream for very long.
* Doesn't support old HTTP versions, web sockets, HTTP/2, old servers or uncommon network setups.
### Thanks, inspiration and resources
Inspiration taken from the following projects. Thanks! :
* [node-http-proxy](https://github.com/nodejitsu/node-http-proxy)
* [pem](https://github.com/andris9/pem)
Splitter was ported to React from [bg-splitter](https://github.com/blackgate/bg-splitter). Thanks!
My port isn't polished enough to warrent its own repo, but if anyone is interested, I can do so.
### License
The MIT License (MIT)
View
@@ -28,7 +28,7 @@ gulp.task('clean', function() {
});
gulp.task('build:styles', function() {
return gulp.src('./stylesheets/style.less')
return gulp.src('./stylesheets/**/*.less')
.pipe(less())
.pipe(gulp.dest('./dist/css'));
});
@@ -38,7 +38,7 @@ gulp.task('rebuild', function(cb) {
});
gulp.task('build:js', function() {
return gulp.src(['./js/**/*.js'])
return gulp.src(['./js/**/*.js', './js/**/*.jsx'])
.pipe(sourcemaps.init())
.pipe(babel(babelOptions))
.pipe(sourcemaps.write())
View
@@ -4,106 +4,19 @@
<title>PhoenixMatrix Proxy</title>
<link rel="stylesheet" type="text/css" href="./vendor/bootstrap/css/bootstrap.min.css"/>
<link rel="stylesheet" type="text/css" href="./vendor/font-awesome/css/font-awesome.css"/>
<link rel="stylesheet" type="text/css" href="./vendor/splitter/style.css"/>
<link rel="stylesheet" type="text/css" href="./dist/css/splitter.css"/>
<link rel="stylesheet" type="text/css" href="./dist/css/style.css"/>
<script type="text/javascript">
window.$ = window.jQuery = require('./vendor/jquery/jquery.min.js');
</script>
<script type="text/javascript" src='vendor/bootstrap/js/bootstrap.min.js'></script>
<script type="text/javascript" src='vendor/angular/angular.min.js'></script>
<script type="text/javascript" src='vendor/bootstrap-ui/ui-bootstrap-custom-tpls-0.12.0.js'></script>
<script type="text/javascript" src='vendor/splitter/splitter.js'></script>
<script type="text/javascript">
require('./dist/app');
</script>
</head>
<body ng-app="phoenixmatrix">
<body>
<div class="view-wrapper">
<div class="main-section" ng-controller="ProxyCtrl as index">
<div class="header-section navbar navbar-inverse navbar-fixed-top">
<span class="navbar-brand">PhoenixMatrix web debugging proxy v0.1 Preview</span>
<form class="navbar-form navbar-right">
<input type="text" class="form-control" placeholder="Search..." ng-model="requestFilter"
ng-model-options="{ debounce: 500 }">
</form>
</div>
<bg-splitter orientation="horizontal">
<bg-pane min-size="370">
<div class="left-section">
<ul class="button-toolbar">
<li class="fa fa-ban" ng-click="index.clear()" tooltip-placement="right" tooltip="Clear requests"></li>
<li class="fa fa-pause" ng-click="index.togglePause()" ng-class="{ selected: index.paused }" tooltip-placement="right" tooltip="Pause capture"></li>
<li class="fa fa-server" ng-click="index.toggleConnect()" ng-class="{ selected: index.config.includeConnect }" tooltip-placement="right" tooltip="Display CONNECT requests"></li>
</ul>
<div class="requests" request-list requests="proxy.requests" filter="requestFilter"
request-selected="index.selectRequest"></div>
</div>
</bg-pane>
<bg-pane min-size="200">
<div class="content-section">
<div class="request-detail" ng-if="selectedRequest">
<div ng-include="'views/request-header.html'"></div>
<div class="panel panel-default">
<div class="panel-heading">
<h4>Request</h4>
</div>
<div class="panel-body">
<div class="panel panel-primary headers-list" ng-if="selectedRequest.headers">
<div class="panel-heading" ng-click="collapseRequestHeaders = !collapseRequestHeaders">
Headers
</div>
<table class="table table-hover" ng-if="!collapseRequestHeaders">
<tbody>
<tr ng-repeat="(key, value) in selectedRequest.headers">
<td ng-bind="key"></td>
<td ng-bind="value"></td>
</tr>
</tbody>
</table>
</div>
<div class="panel panel-primary request-body" ng-if="selectedRequest.body.length">
<div class="panel-heading" ng-click="showRequestBody = !showRequestBody">Body</div>
<div class="panel-body" ng-if="showRequestBody" ng-bind="selectedRequest.body"></div>
</div>
</div>
</div>
</div>
<div class="response-detail" ng-if="selectedRequest && selectedRequest.responseHeaders">
<div class="panel panel-default">
<div class="panel-heading">
<h4>Response</h4>
</div>
<div class="panel-body">
<div class="panel panel-primary headers-list">
<div class="panel-heading"
ng-click="collapseResponseHeaders = !collapseResponseHeaders">Headers
</div>
<table class="table table-hover" ng-if="!collapseResponseHeaders">
<tbody>
<tr ng-repeat="(key, value) in selectedRequest.responseHeaders">
<td ng-bind="key"></td>
<td ng-bind="value"></td>
</tr>
</tbody>
</table>
</div>
<div class="panel panel-primary response-body" ng-if="selectedRequest.responseBody">
<div class="panel-heading" ng-click="collapseResponseBody = !collapseResponseBody">
Body
</div>
<div class="panel-body" ng-if="collapseResponseBody">
<textarea ng-bind="selectedRequest.responseBody"></textarea>
</div>
</div>
</div>
</div>
</div>
</div>
</bg-pane>
</div>
<div class="footer-section"></div>
</div>
<div class="main-section"></div>
</div>
</body>
</html>
View
@@ -18,9 +18,11 @@ app.on('window-all-closed', function() {
});
app.on('ready', function() {
globalShortcut.register('ctrl+shift+i', function() {
console.log('opening debugger')
BrowserWindow.getFocusedWindow().toggleDevTools();
globalShortcut.register('CommandOrControl+Shift+i', function() {
var w = BrowserWindow.getFocusedWindow();
if(w) {
w.toggleDevTools();
}
});
mainWindow = new BrowserWindow({width: 1000, height: 800, icon: "./icon.png"});
@@ -29,4 +31,4 @@ app.on('ready', function() {
mainWindow.on('closed', function() {
mainWindow = null;
});
});
});
@@ -0,0 +1,10 @@
import AppDispatcher from '../dispatchers/AppDispatcher';
import configConstants from '../constants/config-constants';
export default {
toggleConnect: function() {
AppDispatcher.dispatch({
action: configConstants.TOGGLE_CONNECT
});
}
};
@@ -0,0 +1,30 @@
import AppDispatcher from '../dispatchers/AppDispatcher';
import requestConstants from '../constants/request-constants';
export default {
selectRequest: function(request) {
AppDispatcher.dispatch({
action: requestConstants.SELECT_REQUEST,
request: request
});
},
setFilter: function(expression) {
AppDispatcher.dispatch({
action: requestConstants.SET_FILTER,
expression
});
},
clear: function() {
AppDispatcher.dispatch({
action: requestConstants.CLEAR
});
},
togglePause: function() {
AppDispatcher.dispatch({
action: requestConstants.TOGGLE_PAUSE
});
}
};
View
@@ -1,8 +1,14 @@
import 'babel/polyfill';
import './lib/angular';
import './services';
import './filters';
import './directives';
import './controllers';
import React from 'react';
import domready from "domready";
import PhoenixMatrixApp from './components/PhoenixMatrixApp';
import requestStore from './stores/request-store';
requestStore.init();
domready(function () {
React.render(
<PhoenixMatrixApp />,
document.body
);
});
View
@@ -0,0 +1,9 @@
import React from 'react';
export default React.createClass({
render: function() {
return (
<div className="footer-section"></div>
);
}
});
View
@@ -0,0 +1,29 @@
import _ from 'lodash';
import React from 'react';
import requestActions from '../actions/request-actions';
export default React.createClass({
setFilter: function(expression) {
requestActions.setFilter(expression.trim());
},
onChange: function(e) {
this.setFilter(e.target.value);
},
componentWillMount: function() {
this.setFilter = _.debounce(this.setFilter, 500);
},
render: function() {
return (
<div className="header-section navbar navbar-inverse navbar-fixed-top">
<span className="navbar-brand">PhoenixMatrix web debugging proxy v0.1 Preview</span>
<form className="navbar-form navbar-right">
<input ref="searchInput" type="text" className="form-control" placeholder="Search..." onChange={this.onChange} />
</form>
</div>
);
}
});
@@ -0,0 +1,49 @@
import React from 'react';
import _ from 'lodash';
const PureRenderMixin = React.addons.PureRenderMixin;
export default React.createClass({
mixins: [PureRenderMixin],
getInitialState: function() {
return { showTable: true };
},
toggle: function() {
this.setState({showTable: !this.state.showTable});
},
render: function() {
const headers = this.props.headers;
let content = null;
let headerTable;
if(headers && Object.keys(headers).length) {
if(this.state.showTable) {
headerTable =
<table className="table table-hover" ng-if="!collapseRequestHeaders">
<tbody>
{
_.map(headers, function(value, key) {
return <tr key={key}>
<td>{key}</td>
<td>{value}</td>
</tr>;
})
}
</tbody>
</table>
}
content = <div className="panel panel-primary headers-list">
<div className="panel-heading" onClick={this.toggle}>
Headers
</div>
{headerTable}
</div>;
}
return content;
}
});
@@ -0,0 +1,21 @@
import React from 'react';
import VerticalButtonBar from './VerticalButtonBar';
import RequestList from './RequestList';
const PureRenderMixin = React.addons.PureRenderMixin;
export default React.createClass({
mixins: [PureRenderMixin],
render: function() {
return (
<div className="left-section">
<VerticalButtonBar paused={this.props.paused} config={this.props.config} />
<RequestList
requests={this.props.requests}
selectedRequest={this.props.selectedRequest}
/>
</div>
);
}
});
Oops, something went wrong.

0 comments on commit 2d649e1

Please sign in to comment.