From ffd59eb0554b4c691f1cb6c7dd0bf6187280c374 Mon Sep 17 00:00:00 2001
From: OttoMao <ottomao@gmail.com>
Date: Wed, 8 Jul 2015 17:55:14 +0800
Subject: [PATCH] optimze map icon

---
 lib/recorder.js        | 36 ++++++++++++++++++++++----------
 lib/requestHandler.js  | 12 +++++++++--
 lib/rule_default.js    |  1 +
 web/build/index.js     |  6 ++++++
 web/build/popup.js     |  2 +-
 web/build/recordRow.js | 30 ++++++++++++++++++---------
 web/css/page.css       | 47 ++++++++++++++----------------------------
 web/index.html         | 12 +++++++----
 web/page.js            | 38 ++++++++++++++++++++++++----------
 web/src/index.js       |  6 ++++++
 web/src/popup.js       |  2 +-
 web/src/recordRow.js   | 30 ++++++++++++++++++---------
 12 files changed, 141 insertions(+), 81 deletions(-)

diff --git a/lib/recorder.js b/lib/recorder.js
index 5a18c5b..4babf28 100644
--- a/lib/recorder.js
+++ b/lib/recorder.js
@@ -15,7 +15,6 @@ function Recorder(option){
 
     option = option || {};
     if(option.filename && typeof option.filename == "string"){
-
         try{
             if(fs.existsSync(option.filename)){
                 fs.writeFileSync(option.filename,""); //empty original file
@@ -39,9 +38,20 @@ function Recorder(option){
         db = new Datastore();
     }
 
-
     self.recordBodyMap = []; // id - body 
 
+    self.emitUpdate = function(id,info){
+        if(info){
+            self.emit("update",info);
+        }else{
+            self.getSingleRecord(id,function(err,doc){
+                if(!err && !!doc && !!doc[0]){
+                    self.emit("update",doc[0]);
+                }
+            });
+        }
+    };
+
     self.updateRecord = function(id,info){
         if(id < 0 ) return;
 
@@ -50,10 +60,18 @@ function Recorder(option){
         db.update({_id:id},finalInfo);
         self.updateRecordBody(id,info);
 
-        self.emit("update",finalInfo);
+        self.emitUpdate(id,finalInfo);
     };
 
- 
+    self.updateExtInfo = function(id,extInfo){
+        db.update({_id:id},{ $set: { ext: extInfo } },{},function(err,nums){
+            if(!err){
+                self.emitUpdate(id);
+            }
+        });
+
+    }
+
     self.appendRecord = function(info){
         if(info.req.headers.anyproxy_web_req){ //request from web interface
             return -1;
@@ -64,10 +82,9 @@ function Recorder(option){
         db.insert(finalInfo);
         self.updateRecordBody(id,info);
 
-        self.emit("update",finalInfo);
+        self.emitUpdate(id,finalInfo);
         return thisId;
     };
-    
 
     //update recordBody if exits
     self.updateRecordBody =function(id,info){
@@ -91,9 +108,7 @@ function Recorder(option){
         return self.recordBodyMap[id] || "";
     };
 
-
     self.getBodyUTF8 = function(id,cb){
-
         var bodyContent = self.getBody(id),
             result      = "";
 
@@ -123,17 +138,16 @@ function Recorder(option){
             }
 
         });
-    }
+    };
 
     self.getSingleRecord = function(id,cb){
         db.find({_id:parseInt(id)},cb);
-    }
+    };
 
     self.getSummaryList = function(cb){
         db.find({},cb);
     };
 
-
     self.db = db;
 }
 
diff --git a/lib/requestHandler.js b/lib/requestHandler.js
index 723b422..e067dfa 100644
--- a/lib/requestHandler.js
+++ b/lib/requestHandler.js
@@ -44,7 +44,15 @@ function userRequestHandler(req,userRes){
     logUtil.printLog(color.green("\nreceived request to : " + host + path));
 
     //get request body and route to local or remote
-    async.series([fetchReqData,routeReq],function(){});
+    async.series([
+        fetchReqData,
+        routeReq
+    ],function(){
+        //mark some ext info
+        if(req.anyproxy_map_local){
+            GLOBAL.recorder.updateExtInfo(resourceInfoId, {map : req.anyproxy_map_local});
+        }
+    });
 
     //get request body
     function fetchReqData(callback){
@@ -408,5 +416,5 @@ module.exports.getRuleSummary     = getRuleSummary;
 note
     req.url is wired
     in http  server : http://www.example.com/a/b/c
-    in https server : /work/alibaba
+    in https server : /a/b/c
 */
diff --git a/lib/rule_default.js b/lib/rule_default.js
index eb3b47a..10e71da 100644
--- a/lib/rule_default.js
+++ b/lib/rule_default.js
@@ -31,6 +31,7 @@ module.exports = {
                 }
             });
 
+
             return !!req.anyproxy_map_local;
         }
     },
diff --git a/web/build/index.js b/web/build/index.js
index 17e2866..fe8ab2f 100644
--- a/web/build/index.js
+++ b/web/build/index.js
@@ -140,6 +140,12 @@ var recorder;
 
 //action bar
 (function(){
+
+	//detect whether to show the filter and map btn
+	$.get("/filetree?root=/",function(){
+		$(".J_filterSection").show();
+	});
+
 	//clear log
 	function clearLogs(){
 		recordSet = [];
diff --git a/web/build/popup.js b/web/build/popup.js
index 1c53070..c245670 100644
--- a/web/build/popup.js
+++ b/web/build/popup.js
@@ -78,7 +78,7 @@ function init(React){
 					React.createElement("div", {className: "overlay_mask", onClick: this.setHide}), 
 					React.createElement("div", {className: "recordDetailOverlay", ref: "mainOverlay", style: {left: this.state.left}}, 
 						React.createElement("div", {className: "dragbar", onMouseDown: this.dealDrag}), 
-						React.createElement("span", {className: "escBtn", onClick: this.setHide}, "Close (ESC)"), 
+						React.createElement("span", {className: "escBtn", onClick: this.setHide}, React.createElement("i", {className: "uk-icon-times"})), 
 						React.createElement("div", null, 
 							this.state.content
 						)
diff --git a/web/build/recordRow.js b/web/build/recordRow.js
index 7d2a24e..a484be5 100644
--- a/web/build/recordRow.js
+++ b/web/build/recordRow.js
@@ -20,24 +20,34 @@ function init(React){
 		},
 		render : function(){
 			var trClassesArr = [],
-				trClasses;
-			if(this.props.data.statusCode){
+				trClasses,
+				data = this.props.data || {};
+			if(data.statusCode){
 				trClassesArr.push("record_status_done");
 			}
 
-			trClassesArr.push( ((Math.floor(this.props.data._id /2) - this.props.data._id /2) == 0)? "row_even" : "row_odd" );
+			trClassesArr.push( ((Math.floor(data._id /2) - data._id /2) == 0)? "row_even" : "row_odd" );
 			trClasses = trClassesArr.join(" ");
 
-			var dateStr = dateFormat(new Date(this.props.data.startTime),"hh:mm:ss");
+			var dateStr = dateFormat(new Date(data.startTime),"hh:mm:ss");
+
+			var rowIcon = [];
+			if(data.protocol == "https"){
+				rowIcon.push(React.createElement("span", {className: "icon_record", title: "https"}, React.createElement("i", {className: "uk-icon-lock"})));
+			}
+
+			if(data.ext && data.ext.map){
+				rowIcon.push(React.createElement("span", {className: "icon_record", title: "mapped to local file"}, React.createElement("i", {className: "uk-icon-shield"})));
+			}
 
 			return(
 				React.createElement("tr", {className: trClasses, onClick: this.props.onSelect}, 
-					React.createElement("td", {className: "data_id"}, this.props.data._id), 
-					React.createElement("td", null, this.props.data.method, " ", React.createElement("span", {className: "protocol protocol_" + this.props.data.protocol, title: "https"}, React.createElement("i", {className: "uk-icon-lock"})), " "), 
-					React.createElement("td", {className: "http_status http_status_" + this.props.data.statusCode}, this.props.data.statusCode), 
-					React.createElement("td", {title: this.props.data.host}, this.props.data.host), 
-					React.createElement("td", {title: this.props.data.path}, this.props.data.path), 
-					React.createElement("td", null, this.props.data.mime), 
+					React.createElement("td", {className: "data_id"}, data._id), 
+					React.createElement("td", null, data.method, " ", rowIcon, " "), 
+					React.createElement("td", {className: "http_status http_status_" + data.statusCode}, data.statusCode), 
+					React.createElement("td", {title: data.host}, data.host), 
+					React.createElement("td", {title: data.path}, data.path), 
+					React.createElement("td", null, data.mime), 
 					React.createElement("td", null, dateStr)
 				)
 			);
diff --git a/web/css/page.css b/web/css/page.css
index 1509a60..9ca6908 100644
--- a/web/css/page.css
+++ b/web/css/page.css
@@ -9,10 +9,8 @@ body, html {
 .topHead{
 	height: 55px;
 	position: relative;
-/*	-webkit-box-shadow: 0px 3px 23px 0px rgba(50, 50, 50, 0.75);
-	-moz-box-shadow:    0px 3px 23px 0px rgba(50, 50, 50, 0.75);
-	box-shadow:         0px 3px 23px 0px rgba(50, 50, 50, 0.75);
-*/}
+	border-bottom: 1px solid #333;
+}
 
 .topHead .logoWrapper{
 	float: left;
@@ -64,20 +62,26 @@ body, html {
 }
 
 .topHead .ctrlWrapper{
-	height: 35px;
-	line-height: 35px;
+	height: 26px;
+	line-height: 26px;
+}
+
+.topHead .ctrlWrapper .sep{
+	display: inline-block;
+	margin: 0 8px;
+	color: #777;
 }
 
 .topHead .topBtn{
 	margin-right: 8px;
-	transition:0.1s;
+	transition:0.08s;
 	padding: 4px;
 	border-radius: 2px;
 }
 
 .topHead .topBtn:hover:not(.btn_disable){
 	background: #07D;
-	transition:0.1s;
+	transition:0.08s;
 	color: #FFF;
 }
 
@@ -93,20 +97,6 @@ body, html {
 	color: #777;
 }
 
-.topHead .ruleDesc{
-	height: 20px;
-	border-bottom: 1px solid #333;
-}
-
-.topHead .ruleDesc span{
-	padding-left: 3px;
-}
-
-.topHead .ctrlWrapper .sep{
-	display: inline-block;
-	margin: 0 8px;
-	color: #777;
-}
 
 .mainTableWrapper{
 	margin-top: 0;
@@ -214,7 +204,7 @@ body, html {
 	background: #FFF;
 	border-left: 1px solid #CCC;
 	top: 0;
-	padding: 10px 10px 20px 10px;
+	padding: 10px 20px 10px 10px;
 	overflow-y:scroll;
 	box-sizing: border-box;
 	-moz-box-sizing: border-box;
@@ -223,11 +213,11 @@ body, html {
 
 .recordDetailOverlay .escBtn{
 	position: absolute;
-	right: 10px;
+	right: 8px;
 	top: 8px;
 	color: #777;
 	cursor: pointer;
-	text-decoration: underline;
+	font-size: 16px;
 }
 
 .recordDetailOverlay li{
@@ -257,12 +247,7 @@ body, html {
 	color: #910A0A;
 }
 
-
-.protocol{
-	display: none;
-}
-
-.protocol.protocol_https{
+.icon_record{
 	display: inline;
 	font-size: 14px;
 	color: #777;
diff --git a/web/index.html b/web/index.html
index 3bf73ef..f8848bd 100644
--- a/web/index.html
+++ b/web/index.html
@@ -21,16 +21,20 @@
 			<a href="#"><span class="topBtn J_clearBtn"><i class="uk-icon-eraser"></i>Clear(Ctrl+X)</span></a>
 
 			<span class="sep">|</span>
-			<a href="/fetchCrtFile" target="_blank"><span class="topBtn"><i class="uk-icon-certificate"></i>Download rootCA.crt</span></a>
+			<a href="/fetchCrtFile" target="_blank"><span class="topBtn"><i class="uk-icon-download"></i>Download rootCA.crt</span></a>
 			<a href="/qr_root" class="J_fetchRootQR" target="_blank"><span class="topBtn"><i class="uk-icon-qrcode"></i>QRCode of rootCA.crt</span></a>
 
 			<span class="sep">|</span>
 			<a href="https://github.com/alibaba/anyproxy" target="_blank"><span class="topBtn"><i class="uk-icon-github"></i>Github</span></a>
 		</div>
 
-		<div class="ruleDesc">
-			<a href="#"><span class="topBtn J_showFilter"><i class="uk-icon-filter"></i>Filter</span></a>
-			<a href="#"><span class="topBtn J_showMapPanel"><i class="uk-icon-level-down"></i>Map Local</span></a>
+		<div class="ctrlWrapper">
+			<span class="J_filterSection" style="display:none">
+				<a href="#"><span class="topBtn J_showFilter"><i class="uk-icon-filter"></i>Filter</span></a>
+				<a href="#"><span class="topBtn J_showMapPanel"><i class="uk-icon-shield"></i>Map Local</span></a>
+
+				<span class="sep">|</span>
+			</span>
 			<span><i class="uk-icon-chain"></i>Rule : {{rule}}</span>
 		</div>
 
diff --git a/web/page.js b/web/page.js
index 2c2e7d5..3afadb2 100644
--- a/web/page.js
+++ b/web/page.js
@@ -186,6 +186,12 @@
 
 	//action bar
 	(function(){
+
+		//detect whether to show the filter and map btn
+		$.get("/filetree?root=/",function(){
+			$(".J_filterSection").show();
+		});
+
 		//clear log
 		function clearLogs(){
 			recordSet = [];
@@ -20355,7 +20361,7 @@
 						React.createElement("div", {className: "overlay_mask", onClick: this.setHide}), 
 						React.createElement("div", {className: "recordDetailOverlay", ref: "mainOverlay", style: {left: this.state.left}}, 
 							React.createElement("div", {className: "dragbar", onMouseDown: this.dealDrag}), 
-							React.createElement("span", {className: "escBtn", onClick: this.setHide}, "Close (ESC)"), 
+							React.createElement("span", {className: "escBtn", onClick: this.setHide}, React.createElement("i", {className: "uk-icon-times"})), 
 							React.createElement("div", null, 
 								this.state.content
 							)
@@ -20449,24 +20455,34 @@
 			},
 			render : function(){
 				var trClassesArr = [],
-					trClasses;
-				if(this.props.data.statusCode){
+					trClasses,
+					data = this.props.data || {};
+				if(data.statusCode){
 					trClassesArr.push("record_status_done");
 				}
 
-				trClassesArr.push( ((Math.floor(this.props.data._id /2) - this.props.data._id /2) == 0)? "row_even" : "row_odd" );
+				trClassesArr.push( ((Math.floor(data._id /2) - data._id /2) == 0)? "row_even" : "row_odd" );
 				trClasses = trClassesArr.join(" ");
 
-				var dateStr = dateFormat(new Date(this.props.data.startTime),"hh:mm:ss");
+				var dateStr = dateFormat(new Date(data.startTime),"hh:mm:ss");
+
+				var rowIcon = [];
+				if(data.protocol == "https"){
+					rowIcon.push(React.createElement("span", {className: "icon_record", title: "https"}, React.createElement("i", {className: "uk-icon-lock"})));
+				}
+
+				if(data.ext && data.ext.map){
+					rowIcon.push(React.createElement("span", {className: "icon_record", title: "mapped to local file"}, React.createElement("i", {className: "uk-icon-shield"})));
+				}
 
 				return(
 					React.createElement("tr", {className: trClasses, onClick: this.props.onSelect}, 
-						React.createElement("td", {className: "data_id"}, this.props.data._id), 
-						React.createElement("td", null, this.props.data.method, " ", React.createElement("span", {className: "protocol protocol_" + this.props.data.protocol, title: "https"}, React.createElement("i", {className: "uk-icon-lock"})), " "), 
-						React.createElement("td", {className: "http_status http_status_" + this.props.data.statusCode}, this.props.data.statusCode), 
-						React.createElement("td", {title: this.props.data.host}, this.props.data.host), 
-						React.createElement("td", {title: this.props.data.path}, this.props.data.path), 
-						React.createElement("td", null, this.props.data.mime), 
+						React.createElement("td", {className: "data_id"}, data._id), 
+						React.createElement("td", null, data.method, " ", rowIcon, " "), 
+						React.createElement("td", {className: "http_status http_status_" + data.statusCode}, data.statusCode), 
+						React.createElement("td", {title: data.host}, data.host), 
+						React.createElement("td", {title: data.path}, data.path), 
+						React.createElement("td", null, data.mime), 
 						React.createElement("td", null, dateStr)
 					)
 				);
diff --git a/web/src/index.js b/web/src/index.js
index 5b94387..7c88d12 100644
--- a/web/src/index.js
+++ b/web/src/index.js
@@ -140,6 +140,12 @@ var recorder;
 
 //action bar
 (function(){
+
+	//detect whether to show the filter and map btn
+	$.get("/filetree?root=/",function(){
+		$(".J_filterSection").show();
+	});
+
 	//clear log
 	function clearLogs(){
 		recordSet = [];
diff --git a/web/src/popup.js b/web/src/popup.js
index ce54123..a832d27 100644
--- a/web/src/popup.js
+++ b/web/src/popup.js
@@ -78,7 +78,7 @@ function init(React){
 					<div className="overlay_mask" onClick={this.setHide}></div>
 					<div className="recordDetailOverlay" ref="mainOverlay" style={{left: this.state.left}}>
 						<div className="dragbar" onMouseDown={this.dealDrag}></div>
-						<span className="escBtn" onClick={this.setHide}>Close (ESC)</span>
+						<span className="escBtn" onClick={this.setHide}><i className="uk-icon-times"></i></span>
 						<div>
 							{this.state.content}
 						</div>
diff --git a/web/src/recordRow.js b/web/src/recordRow.js
index feab941..9c3181b 100644
--- a/web/src/recordRow.js
+++ b/web/src/recordRow.js
@@ -20,24 +20,34 @@ function init(React){
 		},
 		render : function(){
 			var trClassesArr = [],
-				trClasses;
-			if(this.props.data.statusCode){
+				trClasses,
+				data = this.props.data || {};
+			if(data.statusCode){
 				trClassesArr.push("record_status_done");
 			}
 
-			trClassesArr.push( ((Math.floor(this.props.data._id /2) - this.props.data._id /2) == 0)? "row_even" : "row_odd" );
+			trClassesArr.push( ((Math.floor(data._id /2) - data._id /2) == 0)? "row_even" : "row_odd" );
 			trClasses = trClassesArr.join(" ");
 
-			var dateStr = dateFormat(new Date(this.props.data.startTime),"hh:mm:ss");
+			var dateStr = dateFormat(new Date(data.startTime),"hh:mm:ss");
+
+			var rowIcon = [];
+			if(data.protocol == "https"){
+				rowIcon.push(<span className="icon_record" title="https"><i className="uk-icon-lock"></i></span>);
+			}
+
+			if(data.ext && data.ext.map){
+				rowIcon.push(<span className="icon_record" title="mapped to local file"><i className="uk-icon-shield"></i></span>);
+			}
 
 			return(
 				<tr className={trClasses} onClick={this.props.onSelect}>
-					<td className="data_id">{this.props.data._id}</td>
-					<td>{this.props.data.method} <span className={"protocol protocol_" + this.props.data.protocol} title="https"><i className="uk-icon-lock"></i></span> </td>
-					<td className={"http_status http_status_" + this.props.data.statusCode}>{this.props.data.statusCode}</td>
-					<td title={this.props.data.host}>{this.props.data.host}</td>
-					<td title={this.props.data.path}>{this.props.data.path}</td>
-					<td>{this.props.data.mime}</td>
+					<td className="data_id">{data._id}</td>
+					<td>{data.method} {rowIcon} </td>
+					<td className={"http_status http_status_" + data.statusCode}>{data.statusCode}</td>
+					<td title={data.host}>{data.host}</td>
+					<td title={data.path}>{data.path}</td>
+					<td>{data.mime}</td>
 					<td>{dateStr}</td>
 				</tr>
 			);