Permalink
Browse files

update user interface, improve highlighting, add dojo

  • Loading branch information...
1 parent 5fc9286 commit b5c93beced0cb28961f14bcb5d67db17df38c3c5 @mhils committed Aug 16, 2012
View
12 .gitmodules
@@ -7,3 +7,15 @@
[submodule "netlib"]
path = netlib
url = git@github.com:mhils/netlib.git
+[submodule "gui/js/lib/dijit"]
+ path = gui/js/lib/dijit
+ url = https://github.com/dojo/dijit.git
+[submodule "gui/js/lib/dojo"]
+ path = gui/js/lib/dojo
+ url = https://github.com/dojo/dojo.git
+[submodule "gui/js/lib/dojox"]
+ path = gui/js/lib/dojox
+ url = https://github.com/dojo/dojox.git
+[submodule "gui/js/lib/util"]
+ path = gui/js/lib/util
+ url = https://github.com/dojo/util.git
View
328 gui/css/prefixer.less
@@ -0,0 +1,328 @@
+/*---------------------------------------------------
+ LESS Prefixer
+ ---------------------------------------------------
+
+ All of the CSS3 fun, none of the prefixes!
+
+ As a rule, you can use the CSS properties you
+ would expect just by adding a '.':
+
+ box-shadow => .box-shadow(@args)
+
+ Also, when shorthand is available, arguments are
+ not parameterized. Learn CSS, not LESS Prefixer.
+
+ -------------------------------------------------
+ TABLE OF CONTENTS
+ (*) denotes a syntax-sugar helper
+ -------------------------------------------------
+
+ .animation(@args)
+ .animation-delay(@delay)
+ .animation-direction(@direction)
+ .animation-duration(@duration)
+ .animation-iteration-count(@count)
+ .animation-name(@name)
+ .animation-play-state(@state)
+ .animation-timing-function(@function)
+ .background-size(@args)
+ .border-radius(@args)
+ .box-shadow(@args)
+ .inner-shadow(@args) *
+ .box-sizing(@args)
+ .border-box() *
+ .content-box() *
+ .columns(@args)
+ .column-count(@count)
+ .column-gap(@gap)
+ .column-rule(@args)
+ .column-width(@width)
+ .gradient(@default,@start,@stop) *
+ .linear-gradient-top(@default,@color1,@stop1,@color2,@stop2,[@color3,@stop3,@color4,@stop4])*
+ .linear-gradient-left(@default,@color1,@stop1,@color2,@stop2,[@color3,@stop3,@color4,@stop4])*
+ .opacity(@factor)
+ .transform(@args)
+ .rotate(@deg)
+ .scale(@factor)
+ .translate(@x,@y)
+ .translate3d(@x,@y,@z)
+ .translateHardware(@x,@y) *
+ .text-shadow(@args)
+ .transition(@args)
+ .transition-delay(@delay)
+ .transition-duration(@duration)
+ .transition-property(@property)
+ .transition-timing-function(@function)
+
+
+
+ Credit to LESS Elements for the motivation and
+ to CSS3Please.com for implementation.
+
+ Copyright (c) 2012 Joel Sutherland
+ MIT Licensed:
+ http://www.opensource.org/licenses/mit-license.php
+
+-----------------------------------------------------*/
+
+
+/* Animation */
+.animation(@args) {
+ -webkit-animation: @args;
+ -moz-animation: @args;
+ -ms-animation: @args;
+ -o-animation: @args;
+}
+.animation-delay(@delay) {
+ -webkit-animation-delay: @delay;
+ -moz-animation-delay: @delay;
+ -ms-animation-delay: @delay;
+ -o-animation-delay: @delay;
+}
+.animation-direction(@direction) {
+ -webkit-animation-direction: @direction;
+ -moz-animation-direction: @direction;
+ -ms-animation-direction: @direction;
+ -o-animation-direction: @direction;
+}
+.animation-duration(@duration) {
+ -webkit-animation-duration: @duration;
+ -moz-animation-duration: @duration;
+ -ms-animation-duration: @duration;
+ -o-animation-duration: @duration;
+}
+.animation-iteration-count(@count) {
+ -webkit-animation-iteration-count: @count;
+ -moz-animation-iteration-count: @count;
+ -ms-animation-iteration-count: @count;
+ -o-animation-iteration-count: @count;
+}
+.animation-name(@name) {
+ -webkit-animation-name: @name;
+ -moz-animation-name: @name;
+ -ms-animation-name: @name;
+ -o-animation-name: @name;
+}
+.animation-play-state(@state) {
+ -webkit-animation-play-state: @state;
+ -moz-animation-play-state: @state;
+ -ms-animation-play-state: @state;
+ -o-animation-play-state: @state;
+}
+.animation-timing-function(@function) {
+ -webkit-animation-timing-function: @function;
+ -moz-animation-timing-function: @function;
+ -ms-animation-timing-function: @function;
+ -o-animation-timing-function: @function;
+}
+
+
+/* Background Size */
+
+.background-size(@args) {
+ -webkit-background-size: @args;
+ -moz-background-size: @args;
+ background-size: @args;
+}
+
+
+/* Border Radius */
+
+.border-radius(@args) {
+ -webkit-border-radius: @args;
+ -moz-border-radius: @args;
+ border-radius: @args;
+
+ -webkit-background-clip: padding-box;
+ -moz-background-clip: padding;
+ background-clip: padding-box;
+}
+
+
+/* Box Shadows */
+.box-shadow(@args) {
+ -webkit-box-shadow: @args;
+ -moz-box-shadow: @args;
+ box-shadow: @args;
+}
+.inner-shadow(@args) {
+ .box-shadow(inset @args);
+}
+
+
+/* Box Sizing */
+.box-sizing(@args){
+ -webkit-box-sizing: @args;
+ -moz-box-sizing: @args;
+ box-sizing: @args;
+}
+.border-box(){
+ .box-sizing(border-box);
+}
+.content-box(){
+ .box-sizing(content-box);
+}
+
+
+
+/* Columns */
+.columns(@args){
+ -webkit-columns: @args;
+ -moz-columns: @args;
+ columns: @args;
+}
+.column-count(@count) {
+ -webkit-column-count: @count;
+ -moz-column-count: @count;
+ column-count: @count;
+}
+.column-gap(@gap) {
+ -webkit-column-gap: @gap;
+ -moz-column-gap: @gap;
+ column-gap: @gap;
+}
+.column-width(@width){
+ -webkit-column-width: @width;
+ -moz-column-width: @width;
+ column-width: @width;
+}
+.column-rule(@args){
+ -webkit-column-rule: @rule;
+ -moz-column-rule: @rule;
+ column-rule: @rule;
+}
+
+
+/* Gradients */
+.gradient(@default: #F5F5F5, @start: #EEE, @stop: #FFF) {
+ .linear-gradient-top(@default,@start,0%,@stop,100%);
+}
+.linear-gradient-top(@default,@color1,@stop1,@color2,@stop2) {
+ background-color: @default;
+ background-image: -webkit-gradient(linear, left top, left bottom, color-stop(@stop1, @color1), color-stop(@stop2 @color2));
+ background-image: -webkit-linear-gradient(top, @color1 @stop1, @color2 @stop2);
+ background-image: -moz-linear-gradient(top, @color1 @stop1, @color2 @stop2);
+ background-image: -ms-linear-gradient(top, @color1 @stop1, @color2 @stop2);
+ background-image: -o-linear-gradient(top, @color1 @stop1, @color2 @stop2);
+ background-image: linear-gradient(top, @color1 @stop1, @color2 @stop2);
+}
+.linear-gradient-top(@default,@color1,@stop1,@color2,@stop2,@color3,@stop3) {
+ background-color: @default;
+ background-image: -webkit-gradient(linear, left top, left bottom, color-stop(@stop1, @color1), color-stop(@stop2 @color2), color-stop(@stop3 @color3));
+ background-image: -webkit-linear-gradient(top, @color1 @stop1, @color2 @stop2, @color3 @stop3);
+ background-image: -moz-linear-gradient(top, @color1 @stop1, @color2 @stop2, @color3 @stop3);
+ background-image: -ms-linear-gradient(top, @color1 @stop1, @color2 @stop2, @color3 @stop3);
+ background-image: -o-linear-gradient(top, @color1 @stop1, @color2 @stop2, @color3 @stop3);
+ background-image: linear-gradient(top, @color1 @stop1, @color2 @stop2, @color3 @stop3);
+}
+.linear-gradient-top(@default,@color1,@stop1,@color2,@stop2,@color3,@stop3,@color4,@stop4) {
+ background-color: @default;
+ background-image: -webkit-gradient(linear, left top, left bottom, color-stop(@stop1, @color1), color-stop(@stop2 @color2), color-stop(@stop3 @color3), color-stop(@stop4 @color4));
+ background-image: -webkit-linear-gradient(top, @color1 @stop1, @color2 @stop2, @color3 @stop3, @color4 @stop4);
+ background-image: -moz-linear-gradient(top, @color1 @stop1, @color2 @stop2, @color3 @stop3, @color4 @stop4);
+ background-image: -ms-linear-gradient(top, @color1 @stop1, @color2 @stop2, @color3 @stop3, @color4 @stop4);
+ background-image: -o-linear-gradient(top, @color1 @stop1, @color2 @stop2, @color3 @stop3, @color4 @stop4);
+ background-image: linear-gradient(top, @color1 @stop1, @color2 @stop2, @color3 @stop3, @color4 @stop4);
+}
+.linear-gradient-left(@default,@color1,@stop1,@color2,@stop2) {
+ background-color: @default;
+ background-image: -webkit-gradient(linear, left top, left top, color-stop(@stop1, @color1), color-stop(@stop2 @color2));
+ background-image: -webkit-linear-gradient(left, @color1 @stop1, @color2 @stop2);
+ background-image: -moz-linear-gradient(left, @color1 @stop1, @color2 @stop2);
+ background-image: -ms-linear-gradient(left, @color1 @stop1, @color2 @stop2);
+ background-image: -o-linear-gradient(left, @color1 @stop1, @color2 @stop2);
+ background-image: linear-gradient(left, @color1 @stop1, @color2 @stop2);
+}
+.linear-gradient-left(@default,@color1,@stop1,@color2,@stop2,@color3,@stop3) {
+ background-color: @default;
+ background-image: -webkit-gradient(linear, left top, left top, color-stop(@stop1, @color1), color-stop(@stop2 @color2), color-stop(@stop3 @color3));
+ background-image: -webkit-linear-gradient(left, @color1 @stop1, @color2 @stop2, @color3 @stop3);
+ background-image: -moz-linear-gradient(left, @color1 @stop1, @color2 @stop2, @color3 @stop3);
+ background-image: -ms-linear-gradient(left, @color1 @stop1, @color2 @stop2, @color3 @stop3);
+ background-image: -o-linear-gradient(left, @color1 @stop1, @color2 @stop2, @color3 @stop3);
+ background-image: linear-gradient(left, @color1 @stop1, @color2 @stop2, @color3 @stop3);
+}
+.linear-gradient-left(@default,@color1,@stop1,@color2,@stop2,@color3,@stop3,@color4,@stop4) {
+ background-color: @default;
+ background-image: -webkit-gradient(linear, left top, left top, color-stop(@stop1, @color1), color-stop(@stop2 @color2), color-stop(@stop3 @color3), color-stop(@stop4 @color4));
+ background-image: -webkit-linear-gradient(left, @color1 @stop1, @color2 @stop2, @color3 @stop3, @color4 @stop4);
+ background-image: -moz-linear-gradient(left, @color1 @stop1, @color2 @stop2, @color3 @stop3, @color4 @stop4);
+ background-image: -ms-linear-gradient(left, @color1 @stop1, @color2 @stop2, @color3 @stop3, @color4 @stop4);
+ background-image: -o-linear-gradient(left, @color1 @stop1, @color2 @stop2, @color3 @stop3, @color4 @stop4);
+ background-image: linear-gradient(left, @color1 @stop1, @color2 @stop2, @color3 @stop3, @color4 @stop4);
+}
+
+
+/* Opacity */
+.opacity(@factor){
+ opacity: @factor;
+ @iefactor: @factor*100;
+ filter: alpha(opacity=@iefactor);
+}
+
+
+/* Text Shadow */
+.text-shadow(@args){
+ text-shadow: @args;
+}
+
+/* Transforms */
+
+.transform(@args) {
+ -webkit-transform: @args;
+ -moz-transform: @args;
+ -ms-transform: @args;
+ -o-transform: @args;
+ transform: @args;
+}
+.rotate(@deg:45deg){
+ .transform(rotate(@deg));
+}
+.scale(@factor:.5){
+ .transform(scale(@factor));
+}
+.translate(@x,@y){
+ .transform(translate(@x,@y));
+}
+.translate3d(@x,@y,@z) {
+ .transform(translate3d(@x,@y,@z));
+}
+.translateHardware(@x,@y){
+ .translate(@x,@y);
+ -webkit-transform: translate3d(@x,@y,0);
+ -moz-transform: translate3d(@x,@y,0);
+}
+
+
+/* Transitions */
+
+.transition(@args:200ms) {
+ -webkit-transition: @args;
+ -moz-transition: @args;
+ -o-transition: @args;
+ transition: @args;
+}
+.transition-delay(@delay:0) {
+ -webkit-transition-delay: @delay;
+ -moz-transition-delay: @delay;
+ -o-transition-delay: @delay;
+ transition-delay: @delay;
+}
+.transition-duration(@duration:200ms) {
+ -webkit-transition-duration: @duration;
+ -moz-transition-duration: @duration;
+ -o-transition-duration: @duration;
+ transition-duration: @duration;
+}
+.transition-property(@property:all) {
+ -webkit-transition-property: @property;
+ -moz-transition-property: @property;
+ -o-transition-property: @property;
+ transition-property: @property;
+}
+.transition-timing-function(@function:ease) {
+ -webkit-transition-timing-function: @function;
+ -moz-transition-timing-function: @function;
+ -o-transition-timing-function: @function;
+ transition-timing-function: @function;
+}
View
31 gui/css/search.less
@@ -0,0 +1,31 @@
+.filters {
+ float: right;
+ padding-left: 5px;
+}
+.filter-hide {
+ display: none;
+}
+.filters .filter-highlight {
+ display: inline-block;
+ font-size: @innerLineHeight;
+ line-height: 100%;
+ height: 100%;
+}
+.filters .filter-highlight:before {
+ content: "\2022";
+}
+
+.highlight(@name, @color) {
+ (~".filters .filter-highlight-@{name}:before") {
+ color: @color;
+ }
+ (~".search.highlight-@{name}") {
+ padding: 2px;
+ box-shadow: -6px 0 0 0 @color;
+ border: solid #cfcfcf 1px;
+ border-left: none;
+ }
+}
+.highlight(1,red);
+.highlight(2,gold);
+.highlight(3,green);
View
212 gui/css/style.css
@@ -1,4 +1,81 @@
-/* Column Width */
+/* Animation */
+/*---------------------------------------------------
+ LESS Prefixer
+ ---------------------------------------------------
+
+ All of the CSS3 fun, none of the prefixes!
+
+ As a rule, you can use the CSS properties you
+ would expect just by adding a '.':
+
+ box-shadow => .box-shadow(@args)
+
+ Also, when shorthand is available, arguments are
+ not parameterized. Learn CSS, not LESS Prefixer.
+
+ -------------------------------------------------
+ TABLE OF CONTENTS
+ (*) denotes a syntax-sugar helper
+ -------------------------------------------------
+
+ .animation(@args)
+ .animation-delay(@delay)
+ .animation-direction(@direction)
+ .animation-duration(@duration)
+ .animation-iteration-count(@count)
+ .animation-name(@name)
+ .animation-play-state(@state)
+ .animation-timing-function(@function)
+ .background-size(@args)
+ .border-radius(@args)
+ .box-shadow(@args)
+ .inner-shadow(@args) *
+ .box-sizing(@args)
+ .border-box() *
+ .content-box() *
+ .columns(@args)
+ .column-count(@count)
+ .column-gap(@gap)
+ .column-rule(@args)
+ .column-width(@width)
+ .gradient(@default,@start,@stop) *
+ .linear-gradient-top(@default,@color1,@stop1,@color2,@stop2,[@color3,@stop3,@color4,@stop4])*
+ .linear-gradient-left(@default,@color1,@stop1,@color2,@stop2,[@color3,@stop3,@color4,@stop4])*
+ .opacity(@factor)
+ .transform(@args)
+ .rotate(@deg)
+ .scale(@factor)
+ .translate(@x,@y)
+ .translate3d(@x,@y,@z)
+ .translateHardware(@x,@y) *
+ .text-shadow(@args)
+ .transition(@args)
+ .transition-delay(@delay)
+ .transition-duration(@duration)
+ .transition-property(@property)
+ .transition-timing-function(@function)
+
+
+
+ Credit to LESS Elements for the motivation and
+ to CSS3Please.com for implementation.
+
+ Copyright (c) 2012 Joel Sutherland
+ MIT Licensed:
+ http://www.opensource.org/licenses/mit-license.php
+
+-----------------------------------------------------*/
+/* Animation */
+/* Background Size */
+/* Border Radius */
+/* Box Shadows */
+/* Box Sizing */
+/* Columns */
+/* Gradients */
+/* Opacity */
+/* Text Shadow */
+/* Transforms */
+/* Transitions */
*:not(.dijitContentPane ) {
-webkit-box-sizing: border-box;
box-sizing: border-box;
@@ -41,19 +118,14 @@ header {
display: block;
height: 64px;
padding: 0.5em 100px 0.5em;
- background-color: #e6e6e6;
- background-image: -webkit-linear-gradient(top, #ffffff, #e6e6e6);
- /* Chrome 10+, Safari 5.1+, iOS 5+ */
-
- background-image: -moz-linear-gradient(top, #ffffff, #e6e6e6);
- /* Firefox 3.6-15 */
-
- background-image: -o-linear-gradient(top, #ffffff, #e6e6e6);
- /* Opera 11.10+ */
-
- background-image: linear-gradient(to bottom, #ffffff, #e6e6e6);
- /* Firefox 16+ */
-
+ background-color: #f2f2f2;
+ background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #ffffff), color-stop(100% #f2f2f2));
+ background-image: -webkit-linear-gradient(top, #ffffff 0%, #f2f2f2 100%);
+ background-image: -moz-linear-gradient(top, #ffffff 0%, #f2f2f2 100%);
+ background-image: -ms-linear-gradient(top, #ffffff 0%, #f2f2f2 100%);
+ background-image: -o-linear-gradient(top, #ffffff 0%, #f2f2f2 100%);
+ background-image: linear-gradient(top, #ffffff 0%, #f2f2f2 100%);
+ border-bottom: solid #454545 1px;
}
header a {
float: right;
@@ -75,8 +147,68 @@ header img {
height: 200px;
}
#searchbox {
+ width: 100%;
+}
+#searchbox input[type=text] {
+ width: 100%;
+}
+#main {
+ border-right: solid #454545 1px;
+ border-bottom: solid #cccccc 1px;
+}
+#rightCol {
+ padding: 20px;
+ border-left: solid #cccccc 1px;
+ background-color: #f7f7f7;
+ width: 200px;
+}
+#tutorial {
+ position: absolute;
+ top: 30px;
+ left: 30px;
+}
+.filters {
float: right;
- margin-top: 25px;
+ padding-left: 5px;
+}
+.filter-hide {
+ display: none;
+}
+.filters .filter-highlight {
+ display: inline-block;
+ font-size: 34px;
+ line-height: 100%;
+ height: 100%;
+}
+.filters .filter-highlight:before {
+ content: "\2022";
+}
+.filters .filter-highlight-1:before {
+ color: #ff0000;
+}
+.search.highlight-1 {
+ padding: 2px;
+ box-shadow: -6px 0 0 0 #ff0000;
+ border: solid #cfcfcf 1px;
+ border-left: none;
+}
+.filters .filter-highlight-2:before {
+ color: #ffd700;
+}
+.search.highlight-2 {
+ padding: 2px;
+ box-shadow: -6px 0 0 0 #ffd700;
+ border: solid #cfcfcf 1px;
+ border-left: none;
+}
+.filters .filter-highlight-3:before {
+ color: #008000;
+}
+.search.highlight-3 {
+ padding: 2px;
+ box-shadow: -6px 0 0 0 #008000;
+ border: solid #cfcfcf 1px;
+ border-left: none;
}
.table-fixed-header {
/* Basic Layout */
@@ -100,28 +232,45 @@ header img {
}
.table-fixed-header .scroll {
position: absolute;
- top: 18px;
+ top: 24px;
left: 0;
right: 0;
bottom: 0;
overflow-y: overlay;
overflow-x: hidden;
}
.table-fixed-header .header tr {
- height: 18px;
+ height: 24px;
}
.table-fixed-header .data tr {
height: 36px;
padding: 1px 0;
}
.table-fixed-header .data {
background-color: rgba(0, 0, 0, 0.07);
- background-image: -webkit-gradient(linear, left top, left bottom, from(transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(0, 0, 0, 0.05)), to(rgba(0, 0, 0, 0.05)));
- -webkit-background-size: 1px 72px;
+ background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, transparent), color-stop(50% transparent), color-stop(50% rgba(0, 0, 0, 0.05)), color-stop(100% rgba(0, 0, 0, 0.05)));
+ background-image: -webkit-linear-gradient(top, transparent 0%, transparent 50%, rgba(0, 0, 0, 0.05) 50%, rgba(0, 0, 0, 0.05) 100%);
+ background-image: -moz-linear-gradient(top, transparent 0%, transparent 50%, rgba(0, 0, 0, 0.05) 50%, rgba(0, 0, 0, 0.05) 100%);
+ background-image: -ms-linear-gradient(top, transparent 0%, transparent 50%, rgba(0, 0, 0, 0.05) 50%, rgba(0, 0, 0, 0.05) 100%);
+ background-image: -o-linear-gradient(top, transparent 0%, transparent 50%, rgba(0, 0, 0, 0.05) 50%, rgba(0, 0, 0, 0.05) 100%);
+ background-image: linear-gradient(top, transparent 0%, transparent 50%, rgba(0, 0, 0, 0.05) 50%, rgba(0, 0, 0, 0.05) 100%);
+ background-size: 1px 72px;
}
.table-fixed-header .data tr.selected {
background-color: rgba(255, 244, 122, 0.1);
}
+.table-fixed-header .header {
+ background-color: #ededed;
+ background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #ededed), color-stop(100% #d9d9d9));
+ background-image: -webkit-linear-gradient(top, #ededed 0%, #d9d9d9 100%);
+ background-image: -moz-linear-gradient(top, #ededed 0%, #d9d9d9 100%);
+ background-image: -ms-linear-gradient(top, #ededed 0%, #d9d9d9 100%);
+ background-image: -o-linear-gradient(top, #ededed 0%, #d9d9d9 100%);
+ background-image: linear-gradient(top, #ededed 0%, #d9d9d9 100%);
+}
+.table-fixed-header .header th {
+ border-bottom: 1px solid #a3a3a3;
+}
.table-fixed-header .header th {
text-align: left;
}
@@ -278,31 +427,6 @@ th.time {
width: 20%;
}
/* Row Styling */
-.filters {
- float: right;
- padding-left: 5px;
-}
-.filter-hide {
- display: none;
-}
-.filters .filter-highlight {
- display: inline-block;
- font-size: 34px;
- line-height: 100%;
- height: 100%;
-}
-.filters .filter-highlight:before {
- content: "\2022";
-}
-.filters .filter-highlight-1:before {
- color: red;
-}
-.filters .filter-highlight-2:before {
- color: orange;
-}
-.filters .filter-highlight-3:before {
- color: green;
-}
#trafficTable .icon {
float: left;
width: 32px;
View
43 gui/css/style.less
@@ -1,3 +1,8 @@
+@import "prefixer.less";
+
+@lightSeperator: solid hsl(0, 0%, 80%) 1px;
+@darkSeperator: solid hsl(0, 0%, 27%) 1px;
+
*:not(.dijitContentPane ) {
-webkit-box-sizing: border-box;
box-sizing: border-box;
@@ -37,16 +42,20 @@ h3 {
margin-top: 0.7em;
}
+.lightBg() {
+ .linear-gradient-top(hsl(0,0%,95%),
+ white,0%,
+ hsl(0,0%,95%),100%
+ );
+}
+
header {
overflow: auto;
display: block;
height: 64px;
padding: 0.5em 100px 0.5em;
- background-color: hsl(0,0%,90%);
- background-image: -webkit-linear-gradient(top, #ffffff, hsl(0,0%,90%)); /* Chrome 10+, Safari 5.1+, iOS 5+ */
- background-image: -moz-linear-gradient(top, #ffffff, hsl(0,0%,90%)); /* Firefox 3.6-15 */
- background-image: -o-linear-gradient(top, #ffffff, hsl(0,0%,90%)); /* Opera 11.10+ */
- background-image: linear-gradient(to bottom, #ffffff, hsl(0,0%,90%)); /* Firefox 16+ */
+ .lightBg;
+ border-bottom: @darkSeperator;
}
header a {
@@ -73,11 +82,31 @@ header img {
}
#searchbox {
- float: right;
- margin-top: 25px;
+ width: 100%;
+ input[type=text] {
+ width: 100%;
+ }
+}
+
+#main {
+ border-right: @darkSeperator;
+ border-bottom: @lightSeperator;
}
+#rightCol {
+ padding: 20px;
+ border-left: @lightSeperator;
+ background-color: hsl(0,0%,97%);
+ width: 200px;
+}
+
+#tutorial {
+ position: absolute;
+ top: 30px;
+ left: 30px;
+}
+@import "search.less";
@import "traffictable.less";
@import "preview.less";
@import "raw.less";
View
45 gui/css/traffictable.less
@@ -1,6 +1,6 @@
@lineHeight: 36px;
@innerLineHeight: 34px;
-@headerHeight: @lineHeight / 2;
+@headerHeight: @lineHeight / 1.5;
.table-fixed-header {
/* Basic Layout */
width: 100%;
@@ -32,13 +32,21 @@
}
/* Background & Row Highlight */
.data {
- background-color: hsla(0,0%,0%,0.07);
- background-image: -webkit-gradient(linear, left top, left bottom, from(transparent), color-stop(0.5, transparent), color-stop(0.5, hsla(0, 0%, 0%, 0.05)), to(hsla(0, 0%, 0%, 0.05)));
- -webkit-background-size: 1px @lineHeight*2;
+ .linear-gradient-top(
+ hsla(0,0%,0%,0.07),
+ transparent,0%,transparent,50%,
+ hsla(0, 0%, 0%, 0.05),50%,hsla(0, 0%, 0%, 0.05),100%);
+ background-size: 1px @lineHeight*2;
tr.selected {
background-color: hsla(55, 100%, 74%, 0.1);
}
}
+ .header {
+ .linear-gradient-top(hsl(0, 0%, 93%),hsl(0, 0%, 93%),0%,hsl(0, 0%, 85%),100%);
+ th {
+ border-bottom: 1px solid hsl(0, 0%, 64%);
+ }
+ }
/* Cell Layout */
.header th {
text-align: left;
@@ -60,9 +68,10 @@
min-width: 600px;
//FIXME: Remove when we are away from Closures TableSorter
+
.data thead { .hidden; }
th.goog-tablesorter-sorted {
- background-color: hsla(121, 45%, 50%,.5);
+ background-color: hsla(121, 45%, 50%,.5);
}
th.goog-tablesorter-sorted-reverse {
background-color: hsla(14, 87%, 50%,.5);
@@ -195,32 +204,6 @@ col.time, th.time {
/* Row Styling */
-.filters {
- float: right;
- padding-left: 5px;
-}
-.filter-hide {
- display: none;
-}
-.filters .filter-highlight {
- display: inline-block;
- font-size: @innerLineHeight;
- line-height: 100%;
- height: 100%;
-}
-.filters .filter-highlight:before {
- content: "\2022";
-}
-.filters .filter-highlight-1:before {
- color: red;
-}
-.filters .filter-highlight-2:before {
- color: orange;
-}
-.filters .filter-highlight-3:before {
- color: green;
-}
-
#trafficTable {
.icon {
float: left;
View
17 gui/index.html
@@ -86,12 +86,17 @@
</div>
<div id="rightCol">
<div id="searchbox">
-<input id=filter class=search data-negate=true data-filterclass="hide" placeholder="search: !not, ~regex"><br>
-<input data-filterclass="highlight highlight-1" class=search placeholder="highlight-red: !not, ~regex"><br>
-<input data-filterclass="highlight highlight-2" class=search placeholder="highlight-yellow: !not, ~regex"><br>
-<input data-filterclass="highlight highlight-3" class=search placeholder="highlight-green: !not, ~regex"><br>
-<input type=checkbox id=includeContent checked><label for="includeContent">search in content</label>
+<h2>Filter</h2>
+ <input id=filter class=search data-negate=true data-filterclass="hide" placeholder="search: !not, ~regex"><br>
+
+<h2>Highlight</h2>
+
+ <input data-filterclass="highlight highlight-1" class="search highlight-1" placeholder="highlight-red: !not, ~regex"><br>
+ <input data-filterclass="highlight highlight-2" class="search highlight-2" placeholder="highlight-yellow: !not, ~regex"><br>
+ <input data-filterclass="highlight highlight-3" class="search highlight-3" placeholder="highlight-green: !not, ~regex"><br><br>
+ <input type=checkbox id=includeContent checked><label for="includeContent">include content</label>
</div>
+
</div>
<div id=detail>
<div class=tabs>
@@ -120,7 +125,7 @@
<script src="./js/lib/prettify/prettify.js"></script>
<script src="./js/lib/prettify/lang-css.js"></script>
-
+<!-- ugly. remove closure dependency and move to amd modules ASAP! -->
<script>HoneyProxy = {flowModels:[]};</script>
<script src="./js/HoneyProxy/models/Flow.js"></script>
<script src="./js/HoneyProxy/template.js"></script>
View
2 gui/js/HoneyProxy/Config.js
@@ -17,10 +17,8 @@
console.log("start request");
$.getJSON("/api/config", function(data){
- console.log("request done");
HoneyProxy.config = new Config(data);
HoneyProxy.config.set("content","/files");
HoneyProxy.trigger("configLoaded");
- console.log("triggered");
});
})();
View
1 gui/js/HoneyProxy/HoneyProxy.js
@@ -36,7 +36,6 @@ window.HoneyProxy = HoneyProxy;
//establish websocket communication after config has been loaded.
HoneyProxy.on("configLoaded",function(){
- console.log("Config loaded.");
HoneyProxy.websocket.initialize();
})
View
6 gui/js/HoneyProxy/MainLayout.js
@@ -1,7 +1,8 @@
define([ "dojo/query",
"dijit/layout/BorderContainer",
+ "dijit/layout/TabContainer",
"dijit/layout/ContentPane",
- "dojo/domReady!"], function(query, BorderContainer, ContentPane) {
+ "dojo/domReady!"], function(query, BorderContainer, TabContainer, ContentPane) {
var appLayout = new BorderContainer({
design : "headline",
liveSplitters: false,
@@ -25,8 +26,9 @@ define([ "dojo/query",
splitter: true,
layoutPriority:2
},"detail");
-
//appLayout.addChild(detail);
+
+
appLayout.addChild(
new ContentPane({
region: "right",
View
38 gui/js/HoneyProxy/honeyproxy.profile.js
@@ -0,0 +1,38 @@
+var profile = {
+ releaseDir: "./release",
+
+ basePath: ".",
+
+ action: "release",
+
+ cssOptimize: "comments",
+
+ mini: true,
+
+ optimize: "closure",
+
+ layerOptimize: "closure",
+
+ stripConsole: "all",
+
+ selectorEngine: "acme",
+ packages:[{
+ name:"HoneyProxy",
+ location:"../HoneyProxy"
+ }],
+
+
+ layers: {
+ "dojo/dojo": {
+ include: [ "dojo/dojo", "HoneyProxy/MainLayout" ],
+ customBase: true,
+ boot: true
+ }
+ },
+
+ resourceTags: {
+ amd: function (filename, mid) {
+ return /\.js$/.test(filename);
+ }
+ }
+};
View
6 gui/js/HoneyProxy/package.json
@@ -0,0 +1,6 @@
+{
+ "name": "HoneyProxy",
+ "description": "HTTPS traffic analyzer",
+ "version": 1.0,
+ "dojoBuild": "honeyproxy.profile.js"
+}
View
1 gui/js/HoneyProxy/search.js
@@ -142,4 +142,5 @@ $(function(){
}
});
});
+
});
View
519 gui/js/lib/backbone.marionette.js
@@ -1,43 +1,39 @@
-// Backbone.Marionette v0.9.0
-//
-// Copyright (C)2012 Derick Bailey, Muted Solutions, LLC
-// Distributed Under MIT License
-//
-// Documentation and Full License Available at:
+// Backbone.Marionette, v0.9.11
+// Copyright (c)2012 Derick Bailey, Muted Solutions, LLC.
+// Distributed under MIT license
// http://github.com/derickbailey/backbone.marionette
-
Backbone.Marionette = (function(Backbone, _, $){
var Marionette = {};
-// BindTo: Event Binding
-// ---------------------
+// EventBinder
+// -----------
-// BindTo facilitates the binding and unbinding of events
+// The event binder facilitates the binding and unbinding of events
// from objects that extend `Backbone.Events`. It makes
// unbinding events, even with anonymous callback functions,
// easy.
//
-// Thanks to Johnny Oshika for this code.
-// http://stackoverflow.com/questions/7567404/backbone-js-repopulate-or-recreate-the-view/7607853#7607853
+// Inspired by [Johnny Oshika](http://stackoverflow.com/questions/7567404/backbone-js-repopulate-or-recreate-the-view/7607853#7607853)
-Marionette.BindTo = {
+Marionette.EventBinder = function(){
+ this._eventBindings = [];
+};
+_.extend(Marionette.EventBinder.prototype, {
// Store the event binding in array so it can be unbound
// easily, at a later point in time.
bindTo: function (obj, eventName, callback, context) {
context = context || this;
obj.on(eventName, callback, context);
- if (!this.bindings) { this.bindings = []; }
-
var binding = {
obj: obj,
eventName: eventName,
callback: callback,
context: context
- }
+ };
- this.bindings.push(binding);
+ this._eventBindings.push(binding);
return binding;
},
@@ -46,7 +42,7 @@ Marionette.BindTo = {
// returned from the `bindTo` method call.
unbindFrom: function(binding){
binding.obj.off(binding.eventName, binding.callback, binding.context);
- this.bindings = _.reject(this.bindings, function(bind){return bind === binding});
+ this._eventBindings = _.reject(this._eventBindings, function(bind){return bind === binding;});
},
// Unbind all of the events that we have stored.
@@ -55,21 +51,27 @@ Marionette.BindTo = {
// The `unbindFrom` call removes elements from the array
// while it is being iterated, so clone it first.
- var bindings = _.map(this.bindings, _.identity);
+ var bindings = _.map(this._eventBindings, _.identity);
_.each(bindings, function (binding, index) {
that.unbindFrom(binding);
});
}
-};
+});
+// Copy the `extend` function used by Backbone's classes
+Marionette.EventBinder.extend = Backbone.View.extend;
// Marionette.View
// ---------------
// The core view type that other Marionette views extend from.
Marionette.View = Backbone.View.extend({
constructor: function(){
+ var eventBinder = new Marionette.EventBinder();
+ _.extend(this, eventBinder);
+
Backbone.View.prototype.constructor.apply(this, arguments);
+
this.bindTo(this, "show", this.onShowCalled, this);
},
@@ -146,7 +148,7 @@ Marionette.View = Backbone.View.extend({
if (e && e.preventDefault){ e.preventDefault(); }
if (e && e.stopPropagation){ e.stopPropagation(); }
that.trigger(value);
- }
+ };
});
@@ -157,7 +159,7 @@ Marionette.View = Backbone.View.extend({
// to handle the `triggers` configuration
delegateEvents: function(events){
events = events || this.events;
- if (_.isFunction(events)){ events = events.call(this)}
+ if (_.isFunction(events)){ events = events.call(this); }
var combinedEvents = {};
var triggers = this.configureTriggers();
@@ -182,11 +184,31 @@ Marionette.View = Backbone.View.extend({
this.trigger('close');
this.unbindAll();
this.unbind();
+ },
+
+ // This method binds the elements specified in the "ui" hash inside the view's code with
+ // the associated jQuery selectors.
+ bindUIElements: function(){
+ if (!this.ui) { return; }
+
+ var that = this;
+
+ if (!this.uiBindings) {
+ // We want to store the ui hash in uiBindings, since afterwards the values in the ui hash
+ // will be overridden with jQuery selectors.
+ this.uiBindings = this.ui;
+ }
+
+ // refreshing the associated selectors since they should point to the newly rendered elements.
+ this.ui = {};
+ _.each(_.keys(this.uiBindings), function(key) {
+ var selector = that.uiBindings[key];
+ that.ui[key] = that.$(selector);
+ });
}
+
});
-// Copy the features of `BindTo`
-_.extend(Marionette.View.prototype, Marionette.BindTo);
// Item View
// ---------
@@ -197,15 +219,9 @@ _.extend(Marionette.View.prototype, Marionette.BindTo);
Marionette.ItemView = Marionette.View.extend({
constructor: function(){
Marionette.View.prototype.constructor.apply(this, arguments);
- this.initialEvents();
- },
- // Configured the initial events that the item view
- // binds to. Override this method to prevent the initial
- // events, or to add your own initial events.
- initialEvents: function(){
- if (this.collection){
- this.bindTo(this.collection, "reset", this.render, this);
+ if (this.initialEvents){
+ this.initialEvents();
}
},
@@ -223,10 +239,12 @@ Marionette.ItemView = Marionette.View.extend({
var template = this.getTemplate();
var html = Marionette.Renderer.render(template, data);
this.$el.html(html);
+ this.bindUIElements();
if (this.onRender){ this.onRender(); }
this.trigger("render", this);
this.trigger("item:rendered", this);
+ return this;
},
// Override the default close event to add a few
@@ -264,6 +282,7 @@ Marionette.CollectionView = Marionette.View.extend({
// Handle a child item added to the collection
addChildView: function(item, collection, options){
+ this.closeEmptyView();
var ItemView = this.getItemView();
return this.addItemView(item, ItemView, options.index);
},
@@ -274,30 +293,70 @@ Marionette.CollectionView = Marionette.View.extend({
this.onShowCallbacks.run();
},
- // Loop through all of the items and render
- // each of them with the specified `itemView`.
- render: function(){
- var that = this;
- var ItemView = this.getItemView();
- var EmptyView = this.options.emptyView || this.emptyView;
-
+ // Internal method to trigger the before render callbacks
+ // and events
+ triggerBeforeRender: function(){
if (this.beforeRender) { this.beforeRender(); }
+ this.trigger("before:render", this);
this.trigger("collection:before:render", this);
+ },
+
+ // Internal method to trigger the rendered callbacks and
+ // events
+ triggerRendered: function(){
+ if (this.onRender) { this.onRender(); }
+ this.trigger("render", this);
+ this.trigger("collection:rendered", this);
+ },
+ // Render the collection of items. Override this method to
+ // provide your own implementation of a render function for
+ // the collection view.
+ render: function(){
+ this.triggerBeforeRender();
+ this.closeEmptyView();
this.closeChildren();
- if (this.collection) {
- if (this.collection.length === 0 && EmptyView) {
- this.addItemView(new Backbone.Model(), EmptyView, 0);
- } else {
- this.collection.each(function(item, index){
- that.addItemView(item, ItemView, index);
- });
- }
+ if (this.collection && this.collection.length > 0) {
+ this.showCollection();
+ } else {
+ this.showEmptyView();
}
- if (this.onRender) { this.onRender(); }
- this.trigger("collection:rendered", this);
+ this.triggerRendered();
+ return this;
+ },
+
+ // Internal method to loop through each item in the
+ // collection view and show it
+ showCollection: function(){
+ var that = this;
+ var ItemView = this.getItemView();
+ this.collection.each(function(item, index){
+ that.addItemView(item, ItemView, index);
+ });
+ },
+
+ // Internal method to show an empty view in place of
+ // a collection of item views, when the collection is
+ // empty
+ showEmptyView: function(){
+ var EmptyView = this.options.emptyView || this.emptyView;
+ if (EmptyView && !this._showingEmptyView){
+ this._showingEmptyView = true;
+ var model = new Backbone.Model();
+ this.addItemView(model, EmptyView, 0);
+ }
+ },
+
+ // Internal method to close an existing emptyView instance
+ // if one exists. Called when a collection view has been
+ // rendered empty, and then an item is added to the collection.
+ closeEmptyView: function(){
+ if (this._showingEmptyView){
+ this.closeChildren();
+ delete this._showingEmptyView;
+ }
},
// Retrieve the itemView type, either from `this.options.itemView`
@@ -380,6 +439,11 @@ Marionette.CollectionView = Marionette.View.extend({
view.close();
delete this.children[item.cid];
}
+
+ if (!this.collection || this.collection.length === 0){
+ this.showEmptyView();
+ }
+
this.trigger("item:removed", view);
},
@@ -461,13 +525,19 @@ Marionette.CompositeView = Marionette.CollectionView.extend({
render: function(){
var that = this;
+ this.resetItemViewContainer();
+
var html = this.renderModel();
this.$el.html(html);
+ // the ui bindings is done here and not at the end of render since they should be
+ // available before the collection is rendered.
+ this.bindUIElements();
this.trigger("composite:model:rendered");
this.trigger("render");
this.renderCollection();
this.trigger("composite:rendered");
+ return this;
},
// Render the collection for the composite view
@@ -485,6 +555,45 @@ Marionette.CompositeView = Marionette.CollectionView.extend({
var template = this.getTemplate();
return Marionette.Renderer.render(template, data);
+ },
+
+ // Appends the `el` of itemView instances to the specified
+ // `itemViewContainer` (a jQuery selector). Override this method to
+ // provide custom logic of how the child item view instances have their
+ // HTML appended to the composite view instance.
+ appendHtml: function(cv, iv){
+ var $container = this.getItemViewContainer(cv);
+ $container.append(iv.el);
+ },
+
+ // Internal method to ensure an `$itemViewContainer` exists, for the
+ // `appendHtml` method to use.
+ getItemViewContainer: function(containerView){
+ var container;
+ if ("$itemViewContainer" in containerView){
+ container = containerView.$itemViewContainer;
+ } else {
+ if (containerView.itemViewContainer){
+ container = containerView.$(_.result(containerView, "itemViewContainer"));
+
+ if (container.length <= 0) {
+ var err = new Error("Missing `itemViewContainer`");
+ err.name = "ItemViewContainerMissingError";
+ throw err;
+ }
+ } else {
+ container = containerView.$el;
+ }
+ containerView.$itemViewContainer = container;
+ }
+ return container;
+ },
+
+ // Internal method to reset the `$itemViewContainer` on render
+ resetItemViewContainer: function(){
+ if (this.$itemViewContainer){
+ delete this.$itemViewContainer;
+ }
}
});
@@ -497,7 +606,8 @@ Marionette.CompositeView = Marionette.CollectionView.extend({
Marionette.Region = function(options){
this.options = options || {};
- _.extend(this, options);
+ var eventBinder = new Marionette.EventBinder();
+ _.extend(this, eventBinder, options);
if (!this.el){
var err = new Error("An 'el' must be specified");
@@ -518,7 +628,6 @@ _.extend(Marionette.Region.prototype, Backbone.Events, {
// `onShow` and `close` method on your view, just after showing
// or just before closing the view, respectively.
show: function(view){
- var that = this;
this.ensureEl();
this.close();
@@ -571,15 +680,21 @@ _.extend(Marionette.Region.prototype, Backbone.Events, {
// of the region.
attachView: function(view){
this.currentView = view;
+ },
+
+ // Reset the region by closing any existing view and
+ // clearing out the cached `$el`. The next time a view
+ // is shown via this region, the region will re-query the
+ // DOM for the region's `el`.
+ reset: function(){
+ this.close();
+ delete this.$el;
}
});
// Copy the `extend` function used by Backbone's classes
Marionette.Region.extend = Backbone.View.extend;
-// Copy the features of `BindTo`
-_.extend(Marionette.Region.prototype, Marionette.BindTo);
-
// Layout
// ------
@@ -590,6 +705,8 @@ _.extend(Marionette.Region.prototype, Marionette.BindTo);
// attaches `Region` instances to the specified `regions`.
// Used for composite view management and sub-application areas.
Marionette.Layout = Marionette.ItemView.extend({
+ regionType: Marionette.Region,
+
constructor: function () {
Backbone.Marionette.ItemView.apply(this, arguments);
this.initializeRegions();
@@ -610,7 +727,7 @@ Marionette.Layout = Marionette.ItemView.extend({
var result = Marionette.ItemView.prototype.render.apply(this, arguments);
return result;
- }
+ };
return result;
},
@@ -634,9 +751,18 @@ Marionette.Layout = Marionette.ItemView.extend({
}
var that = this;
- _.each(this.regions, function (selector, name) {
+ _.each(this.regions, function (region, name) {
+ if ( typeof region != 'string'
+ && typeof region.selector != 'string' ) {
+ throw new Exception('Region must be specified as a selector ' +
+ 'string or an object with selector property');
+ }
- var regionManager = new Backbone.Marionette.Region({
+ var selector = typeof region === 'string' ? region : region.selector;
+ var regionType = typeof region.regionType === 'undefined'
+ ? that.regionType : region.regionType;
+
+ var regionManager = new regionType({
el: selector,
getEl: function(selector){
return that.$(selector);
@@ -652,9 +778,13 @@ Marionette.Layout = Marionette.ItemView.extend({
// Re-initialize all of the regions by updating the `el` that
// they point to
reInitializeRegions: function(){
- _.each(this.regionManagers, function(region){
- delete region.$el;
- });
+ if (this.regionManagers && _.size(this.regionManagers)===0){
+ this.initializeRegions();
+ } else {
+ _.each(this.regionManagers, function(region){
+ region.reset();
+ });
+ }
},
// Close all of the regions that have been opened by
@@ -688,7 +818,10 @@ Marionette.Layout = Marionette.ItemView.extend({
Marionette.Application = function(options){
this.initCallbacks = new Marionette.Callbacks();
this.vent = new Marionette.EventAggregator();
- _.extend(this, options);
+ this.submodules = {};
+
+ var eventBinder = new Marionette.EventBinder();
+ _.extend(this, eventBinder, options);
};
_.extend(Marionette.Application.prototype, Backbone.Events, {
@@ -734,19 +867,29 @@ _.extend(Marionette.Application.prototype, Backbone.Events, {
}
},
+ // Removes a region from your app.
+ // Accepts the regions name
+ // removeRegion('myRegion')
+ removeRegion: function(region) {
+ this[region].close();
+ delete this[region];
+ },
+
// Create a module, attached to the application
- module: function(){
+ module: function(moduleNames, moduleDefinition){
+ // slice the args, and add this application object as the
+ // first argument of the array
+ var args = slice.call(arguments);
+ args.unshift(this);
+
// see the Marionette.Module object for more information
- return Marionette.Module.create.apply(this, arguments);
+ return Marionette.Module.create.apply(Marionette.Module, args);
}
});
// Copy the `extend` function used by Backbone's classes
Marionette.Application.extend = Backbone.View.extend;
-// Copy the features of `BindTo`
-_.extend(Marionette.Application.prototype, Marionette.BindTo);
-
// AppRouter
// ---------
@@ -819,72 +962,200 @@ Marionette.AppRouter = Backbone.Router.extend({
// A simple module system, used to create privacy and encapsulation in
// Marionette applications
-Marionette.Module = function(){};
+Marionette.Module = function(moduleName, app, customArgs){
+ this.moduleName = moduleName;
+
+ // store sub-modules
+ this.submodules = {};
+
+ this._setupInitializersAndFinalizers();
+
+ // store the configuration for this module
+ this._config = {};
+ this._config.app = app;
+ this._config.customArgs = customArgs;
+ this._config.definitions = [];
+
+ // extend this module with an event binder
+ var eventBinder = new Marionette.EventBinder();
+ _.extend(this, eventBinder);
+};
// Extend the Module prototype with events / bindTo, so that the module
// can be used as an event aggregator or pub/sub.
-_.extend(Marionette.Module.prototype, Backbone.Events, Marionette.BindTo);
+_.extend(Marionette.Module.prototype, Backbone.Events, {
+
+ // Initializer for a specific module. Initializers are run when the
+ // module's `start` method is called.
+ addInitializer: function(callback){
+ this._initializerCallbacks.add(callback);
+ },
+
+ // Finalizers are run when a module is stopped. They are used to teardown
+ // and finalize any variables, references, events and other code that the
+ // module had set up.
+ addFinalizer: function(callback){
+ this._finalizerCallbacks.add(callback);
+ },
+
+ // Start the module, and run all of it's initializers
+ start: function(options){
+ // Prevent re-start the module
+ if (this._isInitialized){ return; }
+
+ this._runModuleDefinition();
+ this._initializerCallbacks.run(options, this);
+ this._isInitialized = true;
+
+ // start the sub-modules
+ if (this.submodules){
+ _.each(this.submodules, function(mod){
+ mod.start(options);
+ });
+ }
+ },
+
+ // Stop this module by running its finalizers and then stop all of
+ // the sub-modules for this module
+ stop: function(){
+ // if we are not initialized, don't bother finalizing
+ if (!this._isInitialized){ return; }
+ this._isInitialized = false;
+
+ // run the finalizers
+ this._finalizerCallbacks.run();
+ // then reset the initializers and finalizers
+ this._setupInitializersAndFinalizers();
+
+ // stop the sub-modules
+ _.each(this.submodules, function(mod){ mod.stop(); });
+ },
+
+ // Configure the module with a definition function and any custom args
+ // that are to be passed in to the definition function
+ addDefinition: function(moduleDefinition){
+ this._config.definitions.push(moduleDefinition);
+ },
+
+ // Internal method: run the module definition function with the correct
+ // arguments
+ _runModuleDefinition: function(){
+ if (this._config.definitions.length === 0) { return; }
+
+ // build the correct list of arguments for the module definition
+ var args = _.flatten([
+ this,
+ this._config.app,
+ Backbone,
+ Marionette,
+ $, _,
+ this._config.customArgs
+ ]);
+
+ // run the module definition function with the correct args
+ var definitionCount = this._config.definitions.length-1;
+ for(var i=0; i <= definitionCount; i++){
+
+ var definition = this._config.definitions[i];
+ definition.apply(this, args);
+
+ }
+ },
+
+ // Internal method: set up new copies of initializers and finalizers.
+ // Calling this method will wipe out all existing initializers and
+ // finalizers.
+ _setupInitializersAndFinalizers: function(){
+ this._initializerCallbacks = new Marionette.Callbacks();
+ this._finalizerCallbacks = new Marionette.Callbacks();
+ }
+});
// Function level methods to create modules
_.extend(Marionette.Module, {
- // Create a module, hanging off 'this' as the parent object. This
- // method must be called with .apply or .create
- create: function(moduleNames, moduleDefinition){
- var moduleName, module, moduleOverride;
- var parentObject = this;
- var parentModule = this;
- var moduleNames = moduleNames.split(".");
+ // Create a module, hanging off the app parameter as the parent object.
+ create: function(app, moduleNames, moduleDefinition){
+ var that = this;
+ var parentModule = app;
+ moduleNames = moduleNames.split(".");
+
+ // get the custom args passed in after the module definition and
+ // get rid of the module name and definition function
+ var customArgs = slice.apply(arguments);
+ customArgs.splice(0, 3);
// Loop through all the parts of the module definition
var length = moduleNames.length;
- for(var i = 0; i < length; i++){
+ _.each(moduleNames, function(moduleName, i){
var isLastModuleInChain = (i === length-1);
- // Get the module name, and check if it exists on
- // the current parent already
- moduleName = moduleNames[i];
- module = parentModule[moduleName];
-
- // Create a new module if we don't have one already
+ // Get an existing module of this name if we have one
+ var module = parentModule[moduleName];
if (!module){
- module = new Marionette.Module();
- }
-
- // Check to see if we need to run the definition
- // for the module. Only run the definition if one
- // is supplied, and if we're at the last segment
- // of the "Module.Name" chain.
- if (isLastModuleInChain && moduleDefinition){
- // get the custom args passed in after the module definition and
- // get rid of the module name and definition function
- var customArgs = slice.apply(arguments);
- customArgs.shift();
- customArgs.shift();
-
- // final arguments list for the module definition
- var argsArray = [module, parentObject, Backbone, Marionette, jQuery, _, customArgs];
-
- // flatten the nested array
- var args = _.flatten(argsArray);
-
- // ensure the module definition's `this` is the module itself
- moduleDefinition.apply(module, args);
+ // Create a new module if we don't have one
+ module = new Marionette.Module(moduleName, app, customArgs);
+ parentModule[moduleName] = module;
+ // store the module on the parent
+ parentModule.submodules[moduleName] = module;
}
- // If the defined module is not what we are
- // currently storing as the module, replace it
- if (parentModule[moduleName] !== module){
- parentModule[moduleName] = module;
+ // Only add a module definition and initializer when this is
+ // the last module in a "parent.child.grandchild" hierarchy of
+ // module names
+ if (isLastModuleInChain ){
+ that._createModuleDefinition(module, moduleDefinition, app);
}
// Reset the parent module so that the next child
// in the list will be added to the correct parent
parentModule = module;
- }
+ });
// Return the last module in the definition chain
- return module;
+ return parentModule;
+ },
+
+ _createModuleDefinition: function(module, moduleDefinition, app){
+ var moduleOptions = this._getModuleDefinitionOptions(moduleDefinition);
+
+ // add the module definition
+ if (moduleOptions.definition){
+ module.addDefinition(moduleOptions.definition);
+ }
+
+ if (moduleOptions.startWithApp){
+ // start the module when the app starts
+ app.addInitializer(function(options){
+ module.start(options);
+ });
+ }
+ },
+
+ _getModuleDefinitionOptions: function(moduleDefinition){
+ // default to starting the module with the app
+ var options = { startWithApp: true };
+
+ // short circuit if we don't have a module definition
+ if (!moduleDefinition){ return options; }
+
+ if (_.isFunction(moduleDefinition)){
+ // if the definition is a function, assign it directly
+ // and use the defaults
+ options.definition = moduleDefinition;
+
+ } else {
+
+ // the definition is an object. grab the "define" attribute
+ // and the "startWithApp" attribute, as set the options
+ // appropriately
+ options.definition = moduleDefinition.define;
+ if (moduleDefinition.hasOwnProperty("startWithApp")){
+ options.startWithApp = moduleDefinition.startWithApp;
+ }
+ }
+
+ return options;
}
});
@@ -998,7 +1269,7 @@ Marionette.Renderer = {
// template function. Override this method to provide your own
// custom rendering and template handling for all of Marionette.
render: function(template, data){
- var templateFunc = Marionette.TemplateCache.get(template);
+ var templateFunc = typeof template === 'function' ? template : Marionette.TemplateCache.get(template);
var html = templateFunc(data);
return html;
}
@@ -1042,24 +1313,34 @@ _.extend(Marionette.Callbacks.prototype, {
// A pub-sub object that can be used to decouple various parts
// of an application through event-driven architecture.
-Marionette.EventAggregator = function(options){
- _.extend(this, options);
-};
+Marionette.EventAggregator = Marionette.EventBinder.extend({
+
+ // Extend any provided options directly on to the event binder
+ constructor: function(options){
+ Marionette.EventBinder.apply(this, arguments);
+ _.extend(this, options);
+ },
-_.extend(Marionette.EventAggregator.prototype, Backbone.Events, Marionette.BindTo, {
- // Assumes the event aggregator itself is the
- // object being bound to.
+ // Override the `bindTo` method to ensure that the event aggregator
+ // is used as the event binding storage
bindTo: function(eventName, callback, context){
- return Marionette.BindTo.bindTo.call(this, this, eventName, callback, context);
+ return Marionette.EventBinder.prototype.bindTo.call(this, this, eventName, callback, context);
}
});
+// Copy the basic Backbone.Events on to the event aggregator
+_.extend(Marionette.EventAggregator.prototype, Backbone.Events);
+
+// Copy the `extend` function used by Backbone's classes
+Marionette.EventAggregator.extend = Backbone.View.extend;
+
// Helpers
// -------
// For slicing `arguments` in functions
var slice = Array.prototype.slice;
+
return Marionette;
-})(Backbone, _, window.jQuery || window.Zepto || window.ender);
+})(Backbone, _, window.jQuery || window.Zepto || window.ender);
1 gui/js/lib/dijit
@@ -0,0 +1 @@
+Subproject commit 53230fcd9ee1968a36abb5bcb1d176c01a0c2647
1 gui/js/lib/dojo
@@ -0,0 +1 @@
+Subproject commit c4421a47373bfbf5ea085bc86083291832e8f7a7
1 gui/js/lib/dojox
@@ -0,0 +1 @@
+Subproject commit 151b20773280fc9563953058b2d2a0d259fb0851
View
11 gui/js/lib/underscore.es5.js
@@ -1,6 +1,7 @@
(function() {
var nativeGetOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
var nativeDefineProperty = Object.defineProperty;
+ var nativeGetPrototypeOf = Object.getPrototypeOf;
var slice = Array.prototype.slice;
var nativePropertyAccessWorksForObjects;
@@ -15,7 +16,15 @@
var nativeExtend = function(source) {
for ( var prop in source) {
- nativeDefineProperty(obj, prop, nativeGetOwnPropertyDescriptor(source, prop))
+ var descriptor = nativeGetOwnPropertyDescriptor(source, prop);
+ if(descriptor === undefined){
+ var proto = nativeGetPrototypeOf(source);
+ while(descriptor === undefined) {
+ descriptor = nativeGetOwnPropertyDescriptor(proto, prop);
+ proto = nativeGetPrototypeOf(proto);
+ }
+ }
+ nativeDefineProperty(obj, prop, descriptor);
}
};
var simpleExtend = function(source) {
1 gui/js/lib/util
@@ -0,0 +1 @@
+Subproject commit 46d61804c75d787ba70ff7cd251e341cce8c15dd
View
2 honeyproxy.py
@@ -122,7 +122,7 @@ def main():
print "HoneyProxy has been started! Usually you don't need the configuration details below:"
print "HTTP Root: "+httpGui
print "WebSocket API: "+wsURL
- print "Auth user: " + "HoneyProxy"
+ print "Auth user: " + "honey"
print "Auth key: "+ HoneyProxy.getAuthKey()
#run!

0 comments on commit b5c93be

Please sign in to comment.