debug
This commit is contained in:
parent
0e6c0c0395
commit
a62ca0125d
@ -104,4 +104,10 @@ public class SpiderContext extends HashMap<String, Object>{
|
||||
return cookieContext;
|
||||
}
|
||||
|
||||
public void pause(String nodeId,String event,String key,Object value){}
|
||||
|
||||
public void resume(){}
|
||||
|
||||
public void stop(){}
|
||||
|
||||
}
|
||||
|
@ -192,7 +192,7 @@ public class Spider {
|
||||
return;
|
||||
}
|
||||
//判断箭头上的条件,如果不成立则不执行
|
||||
if (!executeCondition(fromNode, node, variables)) {
|
||||
if (!executeCondition(fromNode, node, variables, context)) {
|
||||
return;
|
||||
}
|
||||
logger.debug("执行节点[{}:{}]", node.getNodeName(), node.getNodeId());
|
||||
@ -270,7 +270,7 @@ public class Spider {
|
||||
/**
|
||||
* 判断箭头上的表达式是否成立
|
||||
*/
|
||||
private boolean executeCondition(SpiderNode fromNode, SpiderNode node, Map<String, Object> variables) {
|
||||
private boolean executeCondition(SpiderNode fromNode, SpiderNode node, Map<String, Object> variables, SpiderContext context) {
|
||||
if (fromNode != null) {
|
||||
boolean hasException = variables.get("ex") != null;
|
||||
String exceptionFlow = node.getExceptionFlow(fromNode.getNodeId());
|
||||
|
@ -73,6 +73,7 @@ public class ExecuteSQLExecutor implements ShapeExecutor, Grammerable {
|
||||
return;
|
||||
}
|
||||
sql = sqlObject.toString();
|
||||
context.pause(node.getNodeId(),"common",SQL,sql);
|
||||
} catch (Exception e) {
|
||||
logger.error("获取sql出错,异常信息:{}", e.getMessage(), e);
|
||||
ExceptionUtils.wrapAndThrow(e);
|
||||
@ -93,7 +94,6 @@ public class ExecuteSQLExecutor implements ShapeExecutor, Grammerable {
|
||||
parameterSize = Math.max(parameterSize, Array.getLength(parameter));
|
||||
}
|
||||
}
|
||||
|
||||
params[i] = parameter;
|
||||
}
|
||||
String statementType = node.getStringJsonValue(STATEMENT_TYPE);
|
||||
|
@ -75,6 +75,7 @@ public class OutputExecutor implements ShapeExecutor{
|
||||
String outputName = item.get(OUTPUT_NAME);
|
||||
try {
|
||||
value = ExpressionUtils.execute(outputValue, variables);
|
||||
context.pause(node.getNodeId(),"common",outputName,value);
|
||||
logger.debug("输出{}={}", outputName,value);
|
||||
} catch (Exception e) {
|
||||
logger.error("输出{}出错,异常信息:{}", outputName,e);
|
||||
|
@ -107,6 +107,7 @@ public class RequestExecutor implements ShapeExecutor,Grammerable{
|
||||
sleepTime = lastExecuteTime + sleepTime - System.currentTimeMillis();
|
||||
}
|
||||
if (sleepTime > 0) {
|
||||
context.pause(node.getNodeId(),"common",SLEEP,sleepTime);
|
||||
logger.debug("设置延迟时间:{}ms", sleepTime);
|
||||
Thread.sleep(sleepTime);
|
||||
}
|
||||
@ -126,6 +127,7 @@ public class RequestExecutor implements ShapeExecutor,Grammerable{
|
||||
logger.error("设置请求url出错,异常信息:{}", e);
|
||||
ExceptionUtils.wrapAndThrow(e);
|
||||
}
|
||||
context.pause(node.getNodeId(),"common",URL,url);
|
||||
logger.info("设置请求url:{}", url);
|
||||
request.url(url);
|
||||
//设置请求超时时间
|
||||
@ -150,11 +152,11 @@ public class RequestExecutor implements ShapeExecutor,Grammerable{
|
||||
}
|
||||
SpiderNode root = context.getRootNode();
|
||||
//设置请求header
|
||||
setRequestHeader(request, root.getListJsonValue(HEADER_NAME,HEADER_VALUE), context, variables);
|
||||
setRequestHeader(request, node.getListJsonValue(HEADER_NAME,HEADER_VALUE), context, variables);
|
||||
setRequestHeader(root, request, root.getListJsonValue(HEADER_NAME,HEADER_VALUE), context, variables);
|
||||
setRequestHeader(node, request, node.getListJsonValue(HEADER_NAME,HEADER_VALUE), context, variables);
|
||||
|
||||
//设置全局Cookie
|
||||
Map<String, String> cookies = getRequestCookie(request, root.getListJsonValue(COOKIE_NAME, COOKIE_VALUE), context, variables);
|
||||
Map<String, String> cookies = getRequestCookie(root, root.getListJsonValue(COOKIE_NAME, COOKIE_VALUE), context, variables);
|
||||
if(!cookies.isEmpty()){
|
||||
logger.info("设置全局Cookie:{}", cookies);
|
||||
request.cookies(cookies);
|
||||
@ -162,23 +164,15 @@ public class RequestExecutor implements ShapeExecutor,Grammerable{
|
||||
//设置自动管理的Cookie
|
||||
boolean cookieAutoSet = !"0".equals(node.getStringJsonValue(COOKIE_AUTO_SET));
|
||||
if(cookieAutoSet && !cookieContext.isEmpty()){
|
||||
context.pause(node.getNodeId(),COOKIE_AUTO_SET,COOKIE_AUTO_SET,cookieContext);
|
||||
request.cookies(cookieContext);
|
||||
logger.info("自动设置Cookie:{}", cookieContext);
|
||||
}
|
||||
//设置本节点Cookie
|
||||
cookies = getRequestCookie(request, node.getListJsonValue(COOKIE_NAME, COOKIE_VALUE), context, variables);
|
||||
cookies = getRequestCookie(node, node.getListJsonValue(COOKIE_NAME, COOKIE_VALUE), context, variables);
|
||||
if(!cookies.isEmpty()){
|
||||
cookies.entrySet().forEach(entry->{
|
||||
try {
|
||||
Object value = ExpressionUtils.execute(entry.getValue(), variables);
|
||||
entry.setValue(Objects.toString(value));
|
||||
} catch (Exception e) {
|
||||
logger.error("设置Cookie出错:{}",e);
|
||||
}
|
||||
|
||||
});
|
||||
logger.debug("设置Cookie:{}", cookies);
|
||||
request.cookies(cookies);
|
||||
logger.debug("设置Cookie:{}", cookies);
|
||||
}
|
||||
if(cookieAutoSet){
|
||||
cookieContext.putAll(cookies);
|
||||
@ -191,6 +185,7 @@ public class RequestExecutor implements ShapeExecutor,Grammerable{
|
||||
request.contentType(contentType);
|
||||
try {
|
||||
Object requestBody = ExpressionUtils.execute(node.getStringJsonValue(REQUEST_BODY), variables);
|
||||
context.pause(node.getNodeId(),"request-body",REQUEST_BODY,requestBody);
|
||||
request.data(requestBody);
|
||||
logger.info("设置请求Body:{}", requestBody);
|
||||
} catch (Exception e) {
|
||||
@ -198,17 +193,18 @@ public class RequestExecutor implements ShapeExecutor,Grammerable{
|
||||
}
|
||||
}else if("form-data".equals(bodyType)){
|
||||
List<Map<String, String>> formParameters = node.getListJsonValue(PARAMETER_FORM_NAME,PARAMETER_FORM_VALUE,PARAMETER_FORM_TYPE,PARAMETER_FORM_FILENAME);
|
||||
streams = setRequestFormParameter(request,formParameters,context,variables);
|
||||
streams = setRequestFormParameter(node,request,formParameters,context,variables);
|
||||
}else{
|
||||
//设置请求参数
|
||||
setRequestParameter(request,root.getListJsonValue(PARAMETER_NAME,PARAMETER_VALUE), context, variables);
|
||||
setRequestParameter(request,node.getListJsonValue(PARAMETER_NAME,PARAMETER_VALUE),context,variables);
|
||||
setRequestParameter(root, request, root.getListJsonValue(PARAMETER_NAME,PARAMETER_VALUE), context, variables);
|
||||
setRequestParameter(node, request, node.getListJsonValue(PARAMETER_NAME,PARAMETER_VALUE), context, variables);
|
||||
}
|
||||
//设置代理
|
||||
String proxy = node.getStringJsonValue(PROXY);
|
||||
if(proxy != null){
|
||||
if(StringUtils.isNotBlank(proxy)){
|
||||
try {
|
||||
Object value = ExpressionUtils.execute(proxy, variables);
|
||||
context.pause(node.getNodeId(),"common",PROXY,value);
|
||||
if(value != null){
|
||||
String[] proxyArr = value.toString().split(":");
|
||||
if(proxyArr.length == 2){
|
||||
@ -246,11 +242,11 @@ public class RequestExecutor implements ShapeExecutor,Grammerable{
|
||||
}
|
||||
}
|
||||
|
||||
private List<InputStream> setRequestFormParameter(HttpRequest request,List<Map<String, String>> parameters,SpiderContext context,Map<String,Object> variables){
|
||||
private List<InputStream> setRequestFormParameter(SpiderNode node, HttpRequest request,List<Map<String, String>> parameters,SpiderContext context,Map<String,Object> variables){
|
||||
List<InputStream> streams = new ArrayList<>();
|
||||
if(parameters != null){
|
||||
for (Map<String,String> nameValue : parameters) {
|
||||
Object value = null;
|
||||
Object value;
|
||||
String parameterName = nameValue.get(PARAMETER_FORM_NAME);
|
||||
if(StringUtils.isNotBlank(parameterName)){
|
||||
String parameterValue = nameValue.get(PARAMETER_FORM_VALUE);
|
||||
@ -271,12 +267,14 @@ public class RequestExecutor implements ShapeExecutor,Grammerable{
|
||||
if(stream != null){
|
||||
streams.add(stream);
|
||||
request.data(parameterName, parameterFilename, stream);
|
||||
context.pause(node.getNodeId(),"request-body",parameterName,parameterFilename);
|
||||
logger.info("设置请求参数:{}={}",parameterName,parameterFilename);
|
||||
}else{
|
||||
logger.warn("设置请求参数:{}失败,无二进制内容",parameterName);
|
||||
}
|
||||
}else{
|
||||
request.data(parameterName, value);
|
||||
context.pause(node.getNodeId(),"request-body",parameterName,value);
|
||||
logger.info("设置请求参数:{}={}",parameterName,value);
|
||||
}
|
||||
|
||||
@ -289,18 +287,19 @@ public class RequestExecutor implements ShapeExecutor,Grammerable{
|
||||
return streams;
|
||||
}
|
||||
|
||||
private Map<String,String> getRequestCookie(HttpRequest request, List<Map<String, String>> cookies, SpiderContext context, Map<String, Object> variables) {
|
||||
private Map<String,String> getRequestCookie(SpiderNode node, List<Map<String, String>> cookies, SpiderContext context, Map<String, Object> variables) {
|
||||
Map<String,String> cookieMap = new HashMap<>();
|
||||
if (cookies != null) {
|
||||
for (Map<String, String> nameValue : cookies) {
|
||||
Object value = null;
|
||||
Object value;
|
||||
String cookieName = nameValue.get(COOKIE_NAME);
|
||||
if (StringUtils.isNotBlank(cookieName)) {
|
||||
String cookieValue = nameValue.get(COOKIE_VALUE);
|
||||
try {
|
||||
value = ExpressionUtils.execute(cookieValue, variables);
|
||||
if (value != null) {
|
||||
cookieMap.put(cookieName, cookieValue);
|
||||
cookieMap.put(cookieName, value.toString());
|
||||
context.pause(node.getNodeId(),"request-cookie",cookieName,value.toString());
|
||||
logger.info("设置请求Cookie:{}={}", cookieName, value);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
@ -312,7 +311,7 @@ public class RequestExecutor implements ShapeExecutor,Grammerable{
|
||||
return cookieMap;
|
||||
}
|
||||
|
||||
private void setRequestParameter(HttpRequest request, List<Map<String, String>> parameters, SpiderContext context, Map<String, Object> variables) {
|
||||
private void setRequestParameter(SpiderNode node, HttpRequest request, List<Map<String, String>> parameters, SpiderContext context, Map<String, Object> variables) {
|
||||
if (parameters != null) {
|
||||
for (Map<String, String> nameValue : parameters) {
|
||||
Object value = null;
|
||||
@ -321,6 +320,7 @@ public class RequestExecutor implements ShapeExecutor,Grammerable{
|
||||
String parameterValue = nameValue.get(PARAMETER_VALUE);
|
||||
try {
|
||||
value = ExpressionUtils.execute(parameterValue, variables);
|
||||
context.pause(node.getNodeId(),"request-parameter",parameterName,value);
|
||||
logger.info("设置请求参数:{}={}", parameterName, value);
|
||||
} catch (Exception e) {
|
||||
logger.error("设置请求参数:{}出错,异常信息:{}", parameterName, e);
|
||||
@ -331,7 +331,7 @@ public class RequestExecutor implements ShapeExecutor,Grammerable{
|
||||
}
|
||||
}
|
||||
|
||||
private void setRequestHeader(HttpRequest request, List<Map<String, String>> headers, SpiderContext context, Map<String, Object> variables) {
|
||||
private void setRequestHeader(SpiderNode node,HttpRequest request, List<Map<String, String>> headers, SpiderContext context, Map<String, Object> variables) {
|
||||
if (headers != null) {
|
||||
for (Map<String, String> nameValue : headers) {
|
||||
Object value = null;
|
||||
@ -340,6 +340,7 @@ public class RequestExecutor implements ShapeExecutor,Grammerable{
|
||||
String headerValue = nameValue.get(HEADER_VALUE);
|
||||
try {
|
||||
value = ExpressionUtils.execute(headerValue, variables);
|
||||
context.pause(node.getNodeId(),"request-header",headerName,value);
|
||||
logger.info("设置请求Header:{}={}", headerName, value);
|
||||
} catch (Exception e) {
|
||||
logger.error("设置请求Header:{}出错,异常信息:{}", headerName, e);
|
||||
|
@ -36,6 +36,7 @@ public class VariableExecutor implements ShapeExecutor{
|
||||
try {
|
||||
value = ExpressionUtils.execute(variableValue, variables);
|
||||
logger.debug("设置变量{}={}",variableName,value);
|
||||
context.pause(node.getNodeId(),"common",variableName,value);
|
||||
} catch (Exception e) {
|
||||
logger.error("设置变量{}出错,异常信息:{}",variableName,e);
|
||||
ExceptionUtils.wrapAndThrow(e);
|
||||
|
@ -19,10 +19,22 @@ public class SpiderWebSocketContext extends SpiderContext {
|
||||
|
||||
private Session session;
|
||||
|
||||
private boolean debug;
|
||||
|
||||
private Object lock = new Object();
|
||||
|
||||
public SpiderWebSocketContext(Session session) {
|
||||
this.session = session;
|
||||
}
|
||||
|
||||
public boolean isDebug() {
|
||||
return debug;
|
||||
}
|
||||
|
||||
public void setDebug(boolean debug) {
|
||||
this.debug = debug;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addOutput(SpiderOutput output) {
|
||||
super.addOutput(output);
|
||||
@ -44,4 +56,89 @@ public class SpiderWebSocketContext extends SpiderContext {
|
||||
} catch (Throwable ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pause(String nodeId, String event, String key, Object value) {
|
||||
if(this.debug && this.isRunning()) {
|
||||
synchronized (this) {
|
||||
if(this.debug && this.isRunning()) {
|
||||
synchronized (lock) {
|
||||
try {
|
||||
write(new WebSocketEvent<>("debug", new DebugInfo(nodeId, event, key, value)));
|
||||
lock.wait();
|
||||
} catch (InterruptedException ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resume() {
|
||||
if(this.debug){
|
||||
synchronized (lock){
|
||||
lock.notify();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
if(this.debug){
|
||||
synchronized (lock){
|
||||
lock.notifyAll();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class DebugInfo{
|
||||
|
||||
private String nodeId;
|
||||
|
||||
private String event;
|
||||
|
||||
private String key;
|
||||
|
||||
private Object value;
|
||||
|
||||
public DebugInfo(String nodeId, String event, String key, Object value) {
|
||||
this.nodeId = nodeId;
|
||||
this.event = event;
|
||||
this.key = key;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public String getNodeId() {
|
||||
return nodeId;
|
||||
}
|
||||
|
||||
public void setNodeId(String nodeId) {
|
||||
this.nodeId = nodeId;
|
||||
}
|
||||
|
||||
public String getEvent() {
|
||||
return event;
|
||||
}
|
||||
|
||||
public void setEvent(String event) {
|
||||
this.event = event;
|
||||
}
|
||||
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public void setKey(String key) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
public Object getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(Object value) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -30,8 +30,10 @@ public class WebSocketEditorServer {
|
||||
public void onMessage(String message, Session session) {
|
||||
JSONObject event = JSON.parseObject(message);
|
||||
String eventType = event.getString("eventType");
|
||||
if ("test".equals(eventType)) {
|
||||
boolean isDebug = "debug".equalsIgnoreCase(eventType);
|
||||
if ("test".equalsIgnoreCase(eventType) || isDebug) {
|
||||
context = new SpiderWebSocketContext(session);
|
||||
context.setDebug(isDebug);
|
||||
context.setRunning(true);
|
||||
new Thread(() -> {
|
||||
String xml = event.getString("message");
|
||||
@ -45,12 +47,15 @@ public class WebSocketEditorServer {
|
||||
}).start();
|
||||
} else if ("stop".equals(eventType) && context != null) {
|
||||
context.setRunning(false);
|
||||
context.stop();
|
||||
} else if("resume".equalsIgnoreCase(eventType) && context != null){
|
||||
context.resume();
|
||||
}
|
||||
}
|
||||
|
||||
@OnClose
|
||||
public void onClose(Session session) {
|
||||
context.setRunning(false);
|
||||
context.stop();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ html,body{
|
||||
width : 46px;
|
||||
left : 0px;
|
||||
top : 30px;
|
||||
bottom:300px;
|
||||
bottom:200px;
|
||||
max-height: 100%;
|
||||
overflow: auto;
|
||||
background: #F6F6F6;
|
||||
@ -59,7 +59,7 @@ html,body{
|
||||
.main-container .resize-container{
|
||||
cursor: n-resize;
|
||||
position: absolute;
|
||||
bottom : 290px;
|
||||
bottom : 190px;
|
||||
width : 100%;
|
||||
height : 20px;
|
||||
background: transparent;
|
||||
@ -69,7 +69,7 @@ html,body{
|
||||
left : 38px;
|
||||
width : 100%;
|
||||
top : 30px;
|
||||
bottom : 300px;
|
||||
bottom : 200px;
|
||||
background-image: linear-gradient(90deg, rgba(153, 153, 153, 0.3) 1px, rgba(0, 0, 0, 0) 1px),linear-gradient(rgba(153, 153, 153, 0.3) 1px, rgba(0, 0, 0, 0) 1px);
|
||||
background-size: 8px 8px;
|
||||
overflow: auto;
|
||||
@ -78,7 +78,7 @@ html,body{
|
||||
position: absolute;
|
||||
width : 100%;
|
||||
bottom : 0px;
|
||||
height : 300px;
|
||||
height : 200px;
|
||||
box-shadow: -2px 1px 3px #eee;
|
||||
overflow: auto;
|
||||
}
|
||||
@ -237,7 +237,7 @@ html,body{
|
||||
white-space: nowrap;
|
||||
}
|
||||
#test-window{
|
||||
padding:0px 10px;
|
||||
padding:0px 0px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.layui-layer.codemirror .layui-input-block{
|
||||
@ -267,13 +267,134 @@ html,body{
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
|
||||
.toolbar-container ul li {
|
||||
background-repeat: no-repeat;
|
||||
background-size: 18px 18px;
|
||||
background-position: center center;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
padding : 0 4px;
|
||||
}
|
||||
.toolbar-container ul li.btn-save{
|
||||
background-image : url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAABAUlEQVRYR+2XwRHCIBBF/3ZBCdqFHXjSOvDi1ViB1KE3G9Au9OjJoQscMyFDIggkgUxmkmOym33z9wMLYeSHRq6PGoAJdQOwSgj0ArCXnC5mDRNAJSxu/nprQvwASE6NtjChSrD2ex9sO48JdQawqfJqiGwA38I2iKwANojsAA0IwnsUgAqi9NYMMB0FfOve9d21f+h9wq/ASRUgHDoBKBzljgpbbjBAp8IBSTPAdBRgfUyovWAxY7ACOjDAV39DXMe8fxl2nAc0jWueiFYgdiBJBsCEegBYeFrylJyW5qk3WAsCAa6S0zoJQKwZZw8MrsDsgeQmjC3QNz7n5dTGev8AcqN8CWX2vpEAAAAASUVORK5CYII=");
|
||||
}
|
||||
.toolbar-container ul li.btn-return{
|
||||
background-image : url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAACF0lEQVRYR8WWvWtTURjGf09UcGtBNAEdMjmpdOjm4qj4QZcWN8Gl6OK9QdAt6eLg0HsXwep/0A4iFbWTbjrpUARxcNDivRHBj8FBwn3lxiRc0zTJTZPTs95zzvO7z/txXrHHS3usT1+AUmirwFrsaW1SoDsCtMTngQXnAK7EU1e3OeBSfBtAR9xYyhtziZ8GW4UGm19u6v2w5zsOlEJL450m3TjWa4yNBqx88xX1u/C/EGQg0sxfyEMyHdj0ASjvFycMThtclvhNwsPYV22nu3rlQNuJ3BBZkcOBzRREVTAHPI09ne8F0bMMd+NEt0g7r8x4UPe12P29Xx8YixOpYCmwGqKKsdQdjkGdcH5cTagU2mPEbCNhNpuYzt6CUmBnEC+6XXAG0AxFaKsyjke+Ztq54BrgOnDPEk7VK9rs2Yrz1H7evWlp7hNvsw+cUwfSZnVQfBdUIk+BcwdaeWDZRHTqwLFlO9oosKWEa1FF95070C5FJZyLKnruHKAY2m1B9dAPpt7V9Mc5QCm0Z8DX2NMV532gGJgnERhcrHt64hSgGNoFwTpiPb6hS9n+MfEqaNd+K95nI08bzgCOBDZXEI+agsat2NfdoeeBvG02u7+4bCcpcFXgYXwAFmNfLwdORM3BYcRlYgooC9KXrvzvp1kpwJ3I06ehZsLO5DIaxC/gM+IjCW8kXnXHe6ADo+nu7tTEq2AQ3l/lPMsh86zkIgAAAABJRU5ErkJggg==");
|
||||
}
|
||||
.toolbar-container ul li.btn-selectAll{
|
||||
background-image : url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAClklEQVRYR82XsYsTURDGv1krK8HCbBqx1r/AszCK3IGoYKEgnHAWHlhI3p5coSCXAwsb3V0rBQsb4cRGLEywMYWgB6IWdygiaqG3LwhaiFoc5pONSdjdZDcvyeLdtu/NfL83M2/mrWCDP9lgfWw+ANtliYIrAuwbJzpaSc/hbJcVCBaia7FN9g3uRhOrAJZB1EYGEKxqJfej9h1xEIvakUpnLQZQ9HibwLRFTKw58nJkgIRhmni4LR4Bn3UQTa3k4P8Q7wEoeHxqAb8CJZN5AGSdvG8KbI/PAXzTSg6PC2Ai3psCjy8gWNNlOTYOgKl4D0DR5eum4GNDyfFRAYYR7xeBFRBvtCMnwsWWM2BZO1I1AbJ9LoCoJK9alm38Fnh8C+CVVnKqBfDP4SUQU9qRepajNPH2Iepp9kmA9wSeNZSc7oi1e8Pklj849OWCvOsHkXVy2yOzIhIHcPkJgidayZmuUIVWYRuqItjOdZQa8/Iz1uEGhH0ogILLz5aFalCWs1GRosedBGogPmhHjnTWTHI+FIDtMwDxQCs5lwz1Dp8TFlETYClQMmsi3qqjSApslzMQ7I9GOFkDXwEsaSXn++b6Ok/Cwr0wp+FUM6n2BEA4DUOAA2nD6HsTuNNQ4qRVfNHlHAXXTMT7RCAbwPb4A4KbuizzmVfOZWnQtezWSTwFAwB8/hbCC5RcNGk8JnuGSoHtcZ3A1YaSyybOTfYMC5DZNEwEk3uGA/D5EMRRIaYDR+6OIhhrUu03oDQxFczJ4/agSr8F7apdAbBnXPGufeQNaATQnoIzAHblABGbpMYAOQj3dWF7fARga2oj6slfniSC8J25N/NZ3h3BPmdJ3MpTH2j9bywm/xc2369Zzqce6G7DI/AXxriYMP/Ruk8AAAAASUVORK5CYII=");
|
||||
}
|
||||
.toolbar-container ul li.btn-console-xml{
|
||||
background-image : url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAACmUlEQVRYR+2XTUgVURTHf2cQI6NPwjdai2iRkWCBUhRBukkkqEUQRItqGYaO0aaVti/fSBhEiwxaGbUoiKCFRiuxIiHDkMg+vRVoazFP3Ekfj+nNOPN85qa7Gobz8Ztzz9z/ucIKL1nh/MQCVHXrYXXoAvanBVX4KTCk0PnNk6Eo/1gA19fnwE5gOC0AsAbYBYwZTxpSA1T6WufACHDVeHKxCABcX28BZ0RomGyXF4ViRFbAzWojwgDKZdMhdhtSLzerXQidKE2mQwb/AySqQFWP1uscaxX2iJAF+lBup66/dRBO2x5QpUPglVPOu6+t8ik/Vq4HMr7uE+gF6otKltRJeFj2i3OfL8iXP4zzy/X1MXAAuIfyIXgtHBJlxP7TSeOHvm6DCrtRngbhhB0KJ4H7xpPjYQAFBo0nTcUkS+rj+joANBpPgo/Pr0AOwM3qEYSbwDjKNYRehJemXVqSJoqySwRgnatvaMXGSWZHu2TGPpdNserjJZn+ZwBLTbTkCpQKoLZfy0dPyExesy/eA9Z4a7eunnV4DWyPgHmb974mBviB8eRYaoBSVSAcJ3ETLjhW+dqsUIcG8pp42bNDhdHvnjzJd0oFkFOzxGkLGIbUNDFA9RXdPFfGD+AuyiNgIhWHQwXKeaAFh0rTJjaWnRGSNeFyzQORABlfpwXGjSd7A9JlGkhcX98Dm4wn68NHsRWjg/Mlt2K0LZDT0kxEVs4nYsUoRo77jCdnU+3/vHHBJo6S49xvFx5ISlCBRAPJXwfGMvVAOE/kVFzta80cjAHXjSetxWxBpkfviHIKh1rTJm8KxYi/mGR1HGFLMBfAVEqIhYvJcNyQs+jd0PW1H2gG1qUBCK5mwjPTLkfj/BYFSJO0GNsVB/gNWbh3MAOKB3oAAAAASUVORK5CYII=");
|
||||
}
|
||||
.toolbar-container ul li.btn-graphical-xml{
|
||||
background-image : url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAABXklEQVRYR+2Xr0/DUBSFv1sLAgFbg0KDQaOYRCDBMIMjEKDVCEayhASzjgRIUAhmkDjU9lcQCAZHsYQExyGvsGU/UKt4E72uL733fu/0tj3P8BzmuT+TBRAm2gCOgZLBvUQ9je01j0phQwsKqJtYM3iSOEpj63Rr9hQoNbUSiAdguq9hJ42skgsgURtYHagRsJQe2KNb6wGEia6AHWCTgA7fXABOkdwhcW1wimX1zmS03g+tOgzgGu4iKk6iclO3JrZyd/8tcJlGtlduat/EOXCTRrY9DODo7oAP4BlYBKYcUC4Iwz2CL+AFYxYxb6L6FltrAMBdhA3VsGwIXXwi1vsHZhyQuYaWA6NtMJPli5M0ttrIEHYXwkT678Zxmvdq9m0sjWzg1R/5DhQAhQKFAoUChQKFAl4V8Po7/jOk/gxJmMi7JfNrSr3b8swT+jyY5PF8eXIn62yYZyfj5v4A3Ho4MJVAO+EAAAAASUVORK5CYII=");
|
||||
}
|
||||
.toolbar-container ul li.btn-edit-xml{
|
||||
background-image : url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAC/0lEQVRYR82XTWgTURDHf7NNrRelgtJFWhHtqYLQYkXwYIsHrR4UrRf1IHgR1HaTHrzWm1U0acWzBT9Ai3oSBQWrCOIXiIgnkWqUblH8qAc9NDvyNh+mcbNJa2r6YCHsznvzy7w3/5knlBj2kLaQ4hDQhdBcyj7z/REQdx0ZKWUvYQZ2XPsRosDiUgsFfleOu1HpD5tbFKBhUDeLcjdv8gjK65IgQjewJmunEJ9wJFZsXlEAe1BPo6QnKp1uVEZLOgeWn9WNXoqHBbYPXEc2Bc0vDpDQa8AuYNR1pLMc58Zm6YAuitQxGWD/1HVkfeH7MIB7QAdl7GPhonZCNRBYuO/2Skf+t/8LkPZ823WkKwtRDQDj+7rryG7zo1oA5mBvc6Nya64AzgEtBefABlYCC/3EEi5N9Mr+OQEIFbeEJoHGbHZVAyCdXZn0nj8Avu5PT1CjXL4OlCtCObsarro9EijbdkL/joCd0PPADuAj8EEhKYrZq6RaJCNTJFM1flFqBdqAWpTvCBHwn1rAygdV2DDhyOMAkQoEyL409kbzzWk1z1tVxlEGxPLrQlbFjE0TsDpjP03dwupHsQjkA/xAOIoyrMpeEYZQ9lgw6QnPffHwaFeLYb/qWXTg+dDTR5ECVg6AkacLKE0oNxFOmWroeXyVmrQjEfahnDQAIqxT5VllAQDXEckVFaUTi+0ogrJAhTaBBUC7Z9FsebypKIAofWq6IOEncCIT5iuexRYrxRKEYwq/BHZaUyzzInyqHIDyWaFHhMsCWxUuYtFt9jmltEYsDqv6veEr4Ij7jVq7njsZgD+H8R/OgNnnFcAqkwXAO79kmW1IZ8ha4GXOYUYnRGhUOJiLxAwBjA4cmLHghEyYkQ6YdaqqhEF/JJevs2jJSlTDeVqMimp2FSMwq7Y8LPymZa+p471AfbYvrPjFJAygIa6OCHHfRjjj9kpf5a9mxQiEdH+RHl/w6HJj8mRuL6fBMGPiERuPyY10IEqMWV7PA0oDL4ySijLoRmUsa/Ab6oa/MD/ej0IAAAAASUVORK5CYII=");
|
||||
}
|
||||
.toolbar-container ul li.btn-copy{
|
||||
background-image : url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAACcElEQVRYR82XPYgTURSFz4kWdqZw1wluIbiVKyK4CoLgLhY21lY2guBWZkYLrWRtFzQTQQRRWFCrRWwstHIrQVBQMRZuky4vKiu4YOFPjkyS2fxN8t6sA2a6zDv33u/+vMx7xH9+6BK/ECoQcAzAhIveovkA4bEJuBrprACFshYk3MkgcK+LHGbMRX60AnglrYGYzhpAxKN6kWftAKHUDl6FMG8CVrcK45U0B+JF237V+JxPA9A02Grw2M7rJDQIUAh1vCHMdgchcQpqzYqAZy4AOeJrzefDJO1QAC/UGpBpr39AuGECXusGSQTwynoF4ahLdik1343PnVaA3aG+Eci3hRUJ91IG2pSTOAngdPzC+OyZs8QKdAP0G2wFZJS/8QTwQkV7cy7KNq5AvqT8DuJJ/N5SiYqAq3WfTyNdkr+R2zDJYDLUwRzwLkULVozPM5kBNB2VtAjihA1Cwqd6wAtdWQ5UNHUFbEFHrWfSgrEAcG0BgC9x/zObgUJZhyW8dq2EhLvxHGTSgqmb2vM7h+cAZhwg1iFcNgGXM6uAQ9ChkkwqMBYAE7c1ve0npmwwDWL9s8/3Sf8D0Smq86XCEQBL7d+dA0lSybxb2o8GKrbgm+vCdRNwsX8GhtoTS6bIK81PZRJAM/tfiA4pbk86gGXj81zkeChAEyyqwh9M2giYw0atyDfWFrQE1e6D7UgAW+Bh66N2Qb/NAACJ2e5s0kLsKqmwnXgJYG9kazvgxADRzWchbTAHfcX4PDBK1wLovTA4+HWTELhf83neChAPHBu4JGCfm/uWSsAhAm97bIgNNrBSC/jA5st6M7I5+Nf1v3QzjDCiAQFdAAAAAElFTkSuQmCC");
|
||||
}
|
||||
.toolbar-container ul li.btn-paste{
|
||||
background-image : url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAACkElEQVRYR+2Xv08TYRjHP0+BkBg1JAZ7YMKEizoYcdBJnAy7Pwpuarqo5Yp/ALBr7trEgX/AARYXQ+JCFwdM1EkHo3EpchVjTJCwwD3mmvZyLde7XltMSLz1nud5P8/3ed/nfV4h4TdS0Al1OeG5SYrtzVl5lzBEg7kkcR619JIrNCyYUia+5+V9kjhB27YA0pYuiZCNXERZdPKykBQkFsDPWlmMDC7cc0wZ6wrAsHQKKCKMHwikXHfyUgpbwLB0AWE+5N/q/gC5rYfypRWYr8BpW9MpcIAVlE9NO2WedgCaVRJuAmOOKSdjAepZOKY0lGV0SY+5u+y0Ie1Hx5QLQTvD0kmEtSh4f7FWAF5Aw9ZbKOdjINadvKweCsB4UQf/7HO1DRUOmtQUCP7oV9bLc7Jb7SX1H60USNt6B3gmcKYjgHCnHRWylVl5EQtg2PoUeOLVsWcAghcTx5TL7QCs1Yx7BhBU+z/A0VLAKOo5XJYhtieE7td6k+tqD1SdO/kEr1OuVBtb7e7wgI5WCTpJPOr2TKzAkKVDg8KawMUImJJjSmTP6KoEhq3eJhyOuF6/bpryIEqtrgB6UYZ/BjBi6V2Fs6HQwnziPZAke8NWjbGvDjCHcgxHCppVZal5uqoONrCM8KGvj8zGI/nsA0Q4Jb4Nw2aLwOJvNUWm8li+NQwktdGrlWyxR6tpFKtOyX7rrWWu8KY/RWYjJ+W6fcMAOvxcx1N7TInLKT+gcC3pPBBUwM8cSi5kfphSCcLGPkwMWzsuAXDbq7kKrwf2mS7Pya/mjXnYAN7U+WrvONM/78t22KmIBUjbmhMoAKGvooijNqnwcsBlpj4BdwTgPS5EuKFwJUkfALac38ywIHtRfn8Bx9qgMJt6UN8AAAAASUVORK5CYII=");
|
||||
}
|
||||
.toolbar-container ul li.btn-delete{
|
||||
background-image : url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAACBElEQVRYR+2XsWsUQRTGfy+msNMqmZgDIyJYiDYWYnX5C6wEsRADtuosiq2nrfFuEms1doKdtZBUgpUoiEVAUyjM+Q9oIfdk1t3l7ty9nbjYyE6zw843M9987z3ee0LEWNzQ63PKJYXzEXAEXo+E58Ob8qgOL3WABaen5+Bdhtupw2fr3fAdwZlvVt7P2lNLwDi9BawruKGVJIbAotOBgAVueysPmxEYaA/hLso9n0gvhoDZxx4xTp8CVyMOjpU/Pyo1Q83YCQQ+Ayt1yH+0viedvi7/FE4UFwjbQW5gvy+ezTGYEbooqzlwXtmdcEIz0C4ZgVh7xypjnG4HAt7KxJ0tgSgFzECDk4ZI2fKJ7OWyG6cXw9xbeVH8q8b+vQnGQnXLW1kLl6WkhBBBoBzLiZVhU3wTH8g3h8jwVlIvLhz2N4FVn0gaNWXYlkCrQKtAq0CrwH+gQEWRaZxqlg2LrFpVkDZKRnnyyRNOnnqXN7UT5l9vyJfxyigkqmlsYwKxpVcVLorAkXU9OZrnI/DBWznV9NKiSNnQNZQnwBtv5dz4uRMV0UpPD/44zC7QUbg2tPK4KYmlvp5V4RXCobLm5o/WbMlpotDPKp3obmia6MKmHj8w4r7C5WztgbdyZxpX2hsap8+AK01fP7b/pbdyoey8yuY0C6ejDbqm7yifVHg7y5S/AHMyMO8AdUhTAAAAAElFTkSuQmCC");
|
||||
}
|
||||
.toolbar-container ul li.btn-cut{
|
||||
background-image : url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAEFElEQVRYR+2WXYhUZRjHf8/sLn1BbNrunFkjAlGEwDYTytxALyo30FpNQYoipfWiZefMIlZIZV1YYuw5sxK1ZUkQIipKaUJdtNInIUkiRKGlRe6cUXMJoRLW848zzsjs7MzuzAh50wvn5jxfP56v9zWu8rGrHJ8JAZwBtQS9duZKIB1PG4KUbajkY0KARFrfZ5LWXi9AIq1uhbTVDeD4Og4cC1zrrBUi3q/FFuMjxMt1AyTS6pLYA2wLXFtVLUSiX3MV45Bgb9a1pRPZTdqEUQ0xXhJszLq2fjKIqf2a1hTjMHD+YsiiM30WZbHimRQgsoz72mPQhdETJO2Nit4kS6Q5LGg3Y2kmaXsnA64KoG2LZoUX2Q9MN7Esk7KoLOOO4+sA0DlZ3YsNqwKIDBxfy4GdgEIx/3TKvil2lPC1VbC6mrrXBZCD8PQKxguCUyY6gpSdLP4P/KyQrmyfHZ0s9QV51RnIGQypMX6EXQaPAIemttFxLsMqiTcjsYzHsknbXm3wSK82AKBtQHeGIbty/WB8KPFw3tFrGdeeryV4XQD5fngCeP9yMPFxo1j+e5/9/Z8AtKQ1owE+CJJ2t+PpoBmfZlzbWGvwujIwZUA3NoXsNri/OKDE09mUba0VouYeSPjaLliZD/Q50AzMzjVhyJJsn+2rBaImAMfXFqAnH2AkNspMGpkawo+Ff4LOrGvfVgtRESDh60GJecSYgxhBnIjuhILjmOgYTtlX+T2wDmNTXnYcy92C04BGxP6GJvad6rE/ykGVBYh7GjSjG9hhcBJxs4x5wO25VIvV2ZS9V+ww7utLg/n5f98BRxG/YixC3ASsCVJ2sBRiHIDj6wugA7Gw2KDZU/M1xpDBtMC11lJHhVvTjDWZpL1dLE94cmV4obi3dIWPAUj06wHF+CQGs4Zd+6lcyhxfQ8APgWvPFMsdT8eAwSBlr5e18zSA4QSurSiWjwFwPK3FuCdw7dFKTZQYkKuQpwLX7ijoOJ46MfaMXqD17LN2vgJApHMgNkrL8Fo7W9AZAxD3tdcuPcHWVQJw0noIsTtw7fqCTtyTa8bjgWtzK9lFJbzWGAljtJ/utSNlARxPm/JperJiBtLqDsWLWdduuZyBS1f1YODalIrgnm7DOKGQ2cW35dge8LVMsD52HR3Da+yvsqlM613EzMC1+wryNk9zQuNrM3pLG7CoTAswhi78Q/PIc/Zn2QzkZvpSkxG4trBSp8tYmU3ajjGd7utViegBWnbc8vtiQekojhvDuK8lBtuADPCWhUSLpUXGYmD5RM8tx9dOIr2Qd0L4rAFuEMwADpbbARFU2UXUOqDpFrLZLLd4bgXOIX4JxbrSOR6XJV/RGN6V/6Iy/gZsDlyL3hDjTk13QaUGu5L//wP8C7qXoDBLpnUnAAAAAElFTkSuQmCC");
|
||||
}
|
||||
.toolbar-container ul li.btn-undo{
|
||||
background-image : url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAACrklEQVRYR8WWTUhUURTHf2cccxEtMmPeiAmFi8iVQRREkBBFXxBBGZFEUBBIzRtBo2gT0cIPZt4IGRUECZG6KyIwNwURBEEthHBtOi+ClhUoc+I9dZrvN+9BM297/ud/f++ec++5QoAvktLzkmHJjsvbAOl5KeLXwLB0ABhG6a45QMTSpIDpQtcawEjpFMrZ7I7VCiAyohsJMyPC/rxy1QJga0I7GkK8AbYX9cr/BoiO6QHNMAs0lWzU/wkQsbRHYNLjhExJhtF0v3zye5Jy9UXHMJpUU4WkD9OvwHiokRdLfbLgI8+V5gEYSR1CGPRrkqOfFLifNuV9tR5ZACOlEyi91SaW1Ql/JMPNdFysarykfVw3Ly8zrcqhahKq1ajw7HtMLnjpxbB0Duj0EgaMz9um7KyUK62j2pIJMw10B1zEK+2nbcqWcqJ/PWCpc+x6vNyCxCuVo/AUjCFcC7KIZ44wYMdktFBXfA9YelvhrqdhMMFF25SJiheRE4yk9LIojz3W+Ay0A2XrW5ivsCghuuzr8mM9VvZBErX0iMJLYENJkPVZ8FAbo7/oUNiLcAY4VhFcuGHHZNgTwBEYY7qLDDNAW5FpmWFkWLoHXJA4EC4BMx/O0PWtX347Mc8nWcuQbgo34bz9dueZeUzDiKUnBJ4CzSUg+mxTxqsCWE82UvoK5XjWrIpx3JbQ5pUQzrQsfE98tE3Z5wvALYmlD4CrLkQVAFl4S18DR3N3okHpWozLF88SFG5fxNJbAvf8AKzBPwEu5fgN2qaM+AZwDKJJ7VVY8PssNyx9Dpxb2/rZtCmHAwG4f5TUg34BIkndIeI29DbHY0VpDQwQ7CKEqKVXFB6tthEnaw6w1g+rg0+5Ux+AhHYS4h3Ch7oAuPMmoTEJcapuAGulmKsrQDSpp/8CHSTrKGEN0hMAAAAASUVORK5CYII=");
|
||||
}
|
||||
.toolbar-container ul li.btn-redo{
|
||||
background-image : url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAACv0lEQVRYR7WWTWgTURSFzxksqEtROmntWgQXCoIggtnUboqCi1oQBBcqKiQzsT8LEV2IYoVmohQERZRKoRZEFBeKUkGFgmA3VlwUBRXnDf5sxEVNmisTkxjSzPTNpHnL5Jxzv7lz33tDrMAys5IUAx1emhNR4xjV0EjvA4CYBjCkLF6OkrnSABDA8SzauhArDlAqTNxVaR7QgWgNAAARvEIBPd4gf4eBtAygXPTjYhF7vmU4HwTRagC/7gINdLspvmgE0TRAYlS2i4EBAKHvXIB+z+JkPUQsgI4x6SrmsQ/ACQCbdYatNJsC27Xp1OojASQc2SXASQD9ukWX6AQjyuZw5XdtgERWLDFwEYLVsYv/rzqu0jz0b8dqrPac3KHgoIZUW0LiaVsb+pYFMB15D2CTdnI04VwogOnIDwDromVqq6eNQkgHWtH2GrRJZbE0yA07YOZkAIJIt5r2cwuuKpupwF1gOuJP523twAhCAmdci+cDzwHzimyQImYJdEbI9efkE4BtYR4hjnhp3gg9Cc2cDEFwKSzI3z4CTLCIGXct5nGM+ZoPkkbWPwT2uhYfh94FG0dlTcHAbOCWI276hb00n9UHhQB8gYEeleK7oIeqDqHpiH+ujzUQ/oTglLJ5KygkAOBNYQHJ78P8FdrRyp+mIzMAdtSJXwLIKIuvw0KWABCPVJq9OnNU6kBnVrYustT+2jUleRxe7ovGN9QBXFMWj+sUr54DpiODAEZqTFPKYp9uSAVAgNOexQu6vipAwpEnAnSXjZGKVzpAoMu1OR6leAlgfVYSq4ivZeNnESQ9mx+iBPkdUDafR/FUtGx3pJfAw3I7jroWr8cJiuuhmZVzIM4CqF4QccPi+Gjm5AEEO1HEbpXhXJyQZjw0HZmWIu57GeaaCYrr9QHeKotb4gY062MiK/tdm/eaDYrr/wsm9/oZYCxm5gAAAABJRU5ErkJggg==");
|
||||
}
|
||||
.toolbar-container ul li.btn-debug{
|
||||
background-image : url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAACDElEQVRYR+2XvW7TUBTHf/++AhJxXgJegCEMiIGlDEgMgICFIiFiV7AgJFoJiQWwqy7tUIH4WFhg6dKFDrwAfQnbPAPyQY6S4hTfe50QFITwmHs+fj7nf65PRODpZ5ZU4lQ51OOQbfO8t2VPVfG9SLTh85PvsJfabYm92sYgLWOtd4HoZfZSkIxsjU0fhBMgyuwK8KGZ0GC3jLXmhc5sR3BnysYD4a1AGwTG2yLRjTaIKLU3iOsnzh4UsV64oL0AtVMrBHwB+kBvHLgEcuBcM5FgLY+1O7cGJo4OCK8cZFzLE70PaSZYgXEVai3Umuj8mHhUDvUs5BAEiDKbOfkkqYmDcqiLc7cgSm0D8ST0Ft4EFXfzde04RRilNvAkGfxO8obvYWscY1NjgM8LSjRbGOP8XwPQ1mdX+dvL+fPdu/vVLWir2enUVlfER1ffXHe7T7SVcflbok8nY7YCeNXvudfn8Vs+gGcMu/dyuq6d/YpYy52CIpaWOoZNgKWM4agFjsXC/Q3456bAUYGbiFeLvIgwbhWJXv9yEf0fw2V+jkNjWLfrjy4kzjE83oYXsJIhnhdDPXSuZKEVpp/ZgcGFkJ3jvCxiRXMvpceVyOwesD0ThLFdJLof8gmu5ZMAvS27Khv95wvp4lCwl8d6F0pen3cGaOhiwAqXDM7IOFv/buKr4IiK/SJRaGWb4voBFz7zud8HAWwAAAAASUVORK5CYII=");
|
||||
}
|
||||
.toolbar-container ul li.btn-debug.disabled{
|
||||
background-image : url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAB+klEQVRYR+2XvWpUURDHZ/YVUqgvYV4gxfnfRSxskiKQQkVtTCAICaaRQLIQSONHkcYUQclHY2OaNIG9cwpfwLyE5B3CHTlhL1zXc87sXlauoKedr9/Omf/ZuUzG8d5vqOocgG3Lt2kXkb2qqm76/f5uLo5zxrIsXzDzUfBh5g/Ouc1JILz371V1I/hWVTXIQSQBvPfLqvplrOAhgNUchIh8JKKXTZ8cRLYDMQhVPSmK4mkMoizLY2Z+MmZ7DeBdCjoLEIISnfhGRPeI6M4o8TUR/SCihbFCqwAOW89AHZiAsMbhMYAzy8nsQEggImEWlq1kTTszv3HO7VsxJkCb4nVRZr50zj1sfQXD4XC31+vtWL/CsK8BCMqIHhYRR0SpIsE2i+MTSQY1gMyiSosc+GsAYleQan+qnXUDpokbRFUgIotE9DXW0tyzagztEoDz8ZxRgFyitgCpuO4BMjKc5i6bnZ04DkC3Kgj1O5VhE6ATGd5eQUxq/5YKYh0QkWdE9GnGD9FzAJ9/e4j+y3DUgU7+ji0Zhuv6owtJUob1oMxoJXsLYCu5kllbjPf+UlUfWH4J+zWAu62X0jpQRNaJ6GAaCFU9KIrilRVjruUNiJXRN581F2FjOgJwahUP9okBGiAB4BEz31fV+dskzN9V9YqILgBYK9svXD8BsfwbJJRBMOgAAAAASUVORK5CYII=");
|
||||
}
|
||||
.toolbar-container ul li.btn-stop{
|
||||
background-image : url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAA7UlEQVRYR+2XMQ4BQRSG/zcnUGklknUBbkGosCqTLWk4AU6g0gqVDRXhFhyASSRalRPME8ui06yd5m31spm8/59vm/0IX8/Jb5eJKGcZ2e/3Sc2KcGXmSyGc7+KdFA/G13sAxaTCfuw5eOGs9DgTFTAtvQSjnlL4M4aw8hazBhk/qAJ2nWr4O0zVyDR1D4SxkwKMPh19PVTAwEUBC4ykgBAQAkJACAgBISAEhIAQcE/AtHQHjImLv2IQuhT5IGjrogCDK081S9cL47tGfviR0zT98OWFbzn9GHJQBdu8JWT+8UkU4wZSZy+cbuL9d70ElVavuQ4NAAAAAElFTkSuQmCC");
|
||||
}
|
||||
.toolbar-container ul li.btn-stop.disabled{
|
||||
background-image : url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAA60lEQVRYR+2XIQ7CQBBFZ6YXQGFJuAL4ZmshoOAQYOAEwAlQXAIUBGQ7rYcrkGBRXKCzpA1L6jCla6Zq0mzm/301fQiVJ0mSARF18jxvV9/XNQdB8BSRRxRFF7cT3cDMVwDo1RX2Y8/NGNMvzpQFmHkPAJOGwl3MwRgzxSzLRiJybDi8jCOiMTLzAgC2PgoAwBLjOF4T0cpHARHZaAEloASUgBJQAkpACSgBJeCfQJqmM2vtzsdfMSLOsfBBRDz7KGCtHTo1a9IL3V1LP6zKaZN+WHrhV05dpY8ndkWk9Y9PQkQvIrqHYXhy+9/sjtdIJLkrLAAAAABJRU5ErkJggg==");
|
||||
}
|
||||
.toolbar-container ul li.btn-test{
|
||||
background-image : url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAABSUlEQVRYR+2XoU7DUBSGv1MUT8D2NmgUCkGCxbH0PgFDoNjNhkBiZ0hAAQ4cFgwgQbE2kDCJ4pDL1oSQbu26tndi1W3+7/z3/uecCp4f8azPEmDxHWh2dUfhIzJyXcV9mepAo6tthH0nLHCHYgdGzssEmQ7Q00tg46+gQn8loPPWkvsyQLIAboH1FKEvVewqdF6NDOcBKQqQaD4r2DiU06IQ8wIkulfOkdjIzawgZQGMdIUTDbDxnrzkBSkXYKQ6AGwUis0DUQXA2Ix8sa0MIKnexfZbOXo38pDmSOUATlRhKMp2WjetBeC3cuUgMtL+70JdAI8EbEUteaodwN0BCThMEx/PmMlhafR0UivOTFje4VXFEXjsAx47obdZ4G0a1rMPrPX0QmDT30bkeyd0lTePdVeVzyiUs8zwF3hh8f8LChQ10ydLB34An+qlIUX4b60AAAAASUVORK5CYII=");
|
||||
}
|
||||
.toolbar-container ul li.btn-test.disabled{
|
||||
background-image : url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAABRElEQVRYR+2XoU/EMBTG39fu71rb1KFQCBIs/waHQHGTSCyGBBScauewYACJxJBwErOV9MKSC1m63a5bT1z1lu/Xb+977w2U+CCxPu0Bdt8BY8wJ5/xLSrkYo16CDhhjZoyxMy8M4AlAIYS4iwkSBLDWPgA4WBd0zt1wzudCiOcYIEGAsixLIpItQj9EVBDRXCm13AZkKECj+e5BlFLXQyG2BVjpAnisqqrQWttNQaIArIleMcZ8oX70BYkN4N34dM75z+JrpPNEB2gU+8Z2NIAGxMcWwKVS6qXNjtEB/kSXAI7buulUAFTX9bnWevbfhakAXjnnR3mev00O4Gsgy7KLNvFVDwnlJNCKu+PVc3hFB0jdB9J0wpSzINk0nGwfuCeiw2QbUfKd0N/cWnvKGPuWUt52hn/AA7v/XzDgUhu9snfgFw99pCHdhM6eAAAAAElFTkSuQmCC");
|
||||
}
|
||||
.toolbar-container ul li.btn-resume{
|
||||
background-image : url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACYAAAAgCAYAAAB+ZAqzAAACIElEQVRYR83Yz2vTYBzH8fcnivgXaI/eBcHjQGSCRw/C8OBhZ0GkTdUJCo0TxSkIrSJ4ENGDFxl4UWSi4A/cScSLguJBFG1SGYrDH1DtvpKu3WZZ0zZr0+QU8jxJXvnky/M8PALYVLS9jjgGjBjMGpz64upB2NbuyJRsH7BTMO27ehrVN06bMkUbRTxquXnOgR1lV28jYO+BLUDNwKu4OhsH0O4eZS7aeaye1n+HQbHi6nAEzFra7kl4fk4v+gFUpmRhWqOrPOxx4GpXD7Cw67xBoeLq0lpx/YY1PdMOFKJKoRN8ULDwveVG7V3rhFitfZCw5vuur3PwPmf1qRdgEjAE7xYWa+9Wt7hEYCswlzf8xvt4XN86AZOGgXhpVh/37kbhkoc1NBLn/I14HNCfYRV/VDDPqOEFR9Q68zC0xJa0wmR4vqszK79g+LBlzX2gELh6Hl5KEyz0/BD19Ippg9XzsxojqYTVjO3pgxkHg7yupAcmPlTFtq9Zzaem+CWm/JxOpGm4CFjP7uCQXreOwkP7lQY3K67G200Lw4DNSYz7Oc2kaRK/Hbga67TkSbL4vwsmfFdXu0ElAxN3rMr+yoR+dosaNOwX4mSQ04VeQM2+gyr+Gecv+fJRvYmDGkRiVTMmK3lNxQUtJ9anLQKJh1pgspzX7FpRi4nF31R5BWwNVymNWjrdD9BSYuFJnG2ozSXbIxjD4UaQ1ZN+osJn/QMBvnXeD1WGKgAAAABJRU5ErkJggg==");
|
||||
}
|
||||
.toolbar-container ul li.btn-resume.disabled{
|
||||
background-image : url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACYAAAAgCAYAAAB+ZAqzAAAC5UlEQVRYR7WYy2oUQRSG/9N5AN/DhRsfYOpUWpGgSPCKBGMUFYJ4JagoiToQogQSEVGiGDFIUIxIIEiYpKqYLIKKILh34yqoIEIWCp0jPc6EcZjO1NRMatX0ufxfna4+XV1UKBS2RFF0IYqi/QC+AZhJkmQ6juMfyBjOuQMAxkXkg4jktdYfs3xD75MxpouI5moS9DHz06yk1loLQJXtqwDyzHw7FKJeHFlrJwEcqzHOMHNawbrDWmsAcI1xIYqifC6XK7YDMAWrnn0lp2PmWuF1PWttAUBcd6ZEeaXUYKtwQWDOuXkR2ZklTkTLIjLIzAuhgEFg1tq3AHY1EhWRMa31xUZ+WWus6UdpjJkjoi5Pwc9JkpyL4zjV8R5BFXPOzYrIHm8VAEQ0oZQ67RsTBGatfQNgr69IxY+IvqQdQCm11Cg2FOw1gO5GybPsIjKltT66UXwo2CsA+0LBynErRNStlFpu2+J3zr0QkYMtgpXCRWRSa328NldoxaYBHG4HWDnH6tramu7s7Hy/vh5DOr9z7rmIHGkjWCkVET1SSp0qXYeAWWunAPS0G6ySj5kpFCzdefRuFljavIPAnHNPRKRvs8A6Ojq2B4FZax8DOLEZYETUr5R6EARmjJkgopPtBCOiryKyjZl/trL4HwLw/u41mgAR3VFKXa72C6qYc+6+iPQ3EvSwfwewg5k/tavB3gNwxkM404WIXiqlDmU5BFXMGHOXiM6GgBHRLxHpZeZ0h5INHthgxwCcDwCbY+bdPnFBFbPWjgK45CNQ9vkN4Aozj/vGBIEZY+4Q0YCnyEKSJD1xHK94+v/7bgY+yhEA/73e9URFZEhrfasZoIpvEJgxZpiIrm4guCQiA1rrdyFQrVQsD+B6RpWGtdbXQoGqK9b0EYFz7mb6Q1stLiLpJm9Qaz3fKlSpYiGHKouLizeiKBqqAhhlZt+XwYubQo6hisXi1iRJnhHRHyIayeVys15qTTj9BSbJmzEMQ5JCAAAAAElFTkSuQmCC");
|
||||
}
|
||||
.spiderflow-debug-tooltip{
|
||||
position: absolute;
|
||||
z-index: 2147483647;
|
||||
background: #fefefe;
|
||||
border-radius: 2px;
|
||||
padding: 5px;
|
||||
border: 1px solid #eee;
|
||||
box-shadow : 2px 0px 5px 1px rgba(0, 0, 0, 0.6)
|
||||
}
|
||||
.spiderflow-debug-tooltip .content{
|
||||
max-height: 500px;
|
||||
overflow: auto;
|
||||
max-width: 500px;
|
||||
}
|
||||
.spiderflow-debug-tooltip .content::-webkit-scrollbar {
|
||||
width: 5px;
|
||||
height: 5px;
|
||||
}
|
||||
.spiderflow-debug-tooltip .content::-webkit-scrollbar-track {
|
||||
background-color:#ccc;
|
||||
-webkit-border-radius: 2em;
|
||||
-moz-border-radius: 2em;
|
||||
border-radius:2em;
|
||||
}
|
||||
.spiderflow-debug-tooltip .content::-webkit-scrollbar-thumb {
|
||||
background-color:#999;
|
||||
-webkit-border-radius: 2em;
|
||||
-moz-border-radius: 2em;
|
||||
border-radius:2em;
|
||||
}
|
||||
.spiderflow-debug-tooltip::before{
|
||||
content: ' ';
|
||||
width: 0px;
|
||||
height: 0px;
|
||||
position: absolute;
|
||||
bottom: -17px;
|
||||
left: 50%;
|
||||
border-width: 8px;
|
||||
border-style: solid;
|
||||
border-color: #eee transparent transparent transparent;
|
||||
margin-left: -4px;
|
||||
}
|
||||
.spiderflow-debug-tooltip::after{
|
||||
content: ' ';
|
||||
width: 0px;
|
||||
height: 0px;
|
||||
position: absolute;
|
||||
bottom: -16px;
|
||||
left: 50%;
|
||||
border-width: 8px;
|
||||
border-style: solid;
|
||||
border-color: #fefefe transparent transparent transparent;
|
||||
margin-left: -4px;
|
||||
}
|
||||
|
||||
/*样式调整*/
|
||||
.properties-container .editor-form-node input, .properties-container .editor-form-node textarea{
|
||||
font-size : 12px;
|
||||
}
|
||||
.layui-input, .layui-select, .layui-textarea{
|
||||
.properties-container .editor-form-node .layui-input,.properties-container .editor-form-node .layui-select,.properties-container .editor-form-node .layui-textarea{
|
||||
height : 24px;
|
||||
}
|
||||
.layui-form-label{
|
||||
@ -356,4 +477,45 @@ html,body{
|
||||
}
|
||||
.properties-container .layui-form-item .layui-input-inline{
|
||||
width : auto;
|
||||
}
|
||||
|
||||
.layer-test .layui-layer-title{
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
}
|
||||
.layer-test .layui-layer-setwin{
|
||||
top : 6px;
|
||||
}
|
||||
.layer-test .layui-tab{
|
||||
margin : 0px;
|
||||
}
|
||||
.layer-test .layui-tab-content{
|
||||
padding : 2px;
|
||||
}
|
||||
.layer-test .layui-layer-btn{
|
||||
padding-top:2px !important;
|
||||
margin-top:-5px;
|
||||
}
|
||||
.layer-test .layui-layer-btn .layui-inline{
|
||||
margin-top:5px;
|
||||
}
|
||||
.layer-test .layui-layer-btn .layui-inline input{
|
||||
font-size:12px;
|
||||
height : 26px;
|
||||
}
|
||||
.layer-test .layui-layer-btn a{
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
margin: 5px 5px 0;
|
||||
padding: 0px 10px;
|
||||
font-size:12px;
|
||||
}
|
||||
.layer-test .layui-layer-max{
|
||||
display: none;
|
||||
}
|
||||
.layer-test .layui-layer-max.layui-layer-maxmin{
|
||||
display: inline-block;
|
||||
}
|
||||
#test-window{
|
||||
height:340px !important;
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
.layui-body .layui-tab{margin:0px;height:100%;}
|
||||
.layui-body .layui-tab .layui-tab-content{position: absolute;top: 40px;bottom: 0px;width: 100%;padding:0px;overflow: hidden;}
|
||||
.layui-body .layui-tab .layui-tab-content .layui-tab-item{height:100%;width:calc(100% - 48px);}
|
||||
.layui-body .layui-tab .layui-tab-content .layui-tab-item{height:100%;}
|
||||
/***********************/
|
||||
|
||||
.layui-layout-admin .layui-search-menu{
|
||||
|
@ -102,10 +102,8 @@ iframe{
|
||||
color:rgba(0, 0, 0, 0.65);
|
||||
}
|
||||
.layui-body .layui-tab .layui-tab-content{
|
||||
top:64px !important;
|
||||
left:24px;
|
||||
right:24px;
|
||||
bottom:24px !important;
|
||||
top:41px !important;
|
||||
left:1px;
|
||||
}
|
||||
.layui-layout-admin .layui-body,.layui-layout-admin .layui-footer{
|
||||
background-color: #f0f2f5;
|
||||
|
@ -29,19 +29,21 @@
|
||||
<div class="main-container">
|
||||
<div class="toolbar-container">
|
||||
<ul>
|
||||
<li class="btn-return">返回</li>
|
||||
<li class="btn-selectAll" title="Ctrl+A">全选</li>
|
||||
<li class="btn-save" title="Ctrl+S">保存</li>
|
||||
<li class="btn-test" title="Ctrl+Q">测试</li>
|
||||
<li class="btn-console-xml">打印XML</li>
|
||||
<li class="btn-edit-xml">XML编辑</li>
|
||||
<li class="btn-graphical-xml">图形化编辑</li>
|
||||
<li class="btn-copy" title="Ctrl+C">复制</li>
|
||||
<li class="btn-paste" title="Ctrl+V">粘贴</li>
|
||||
<li class="btn-cut" title="Ctrl+X">剪切</li>
|
||||
<li class="btn-undo" title="Ctrl+Z">撤销</li>
|
||||
<li class="btn-redo" title="Ctrl+Y">恢复</li>
|
||||
<li class="btn-delete" title="Delete">删除</li>
|
||||
<li class="btn-return"></li>
|
||||
<li class="btn-selectAll" title="全选(Ctrl+A)"></li>
|
||||
<li class="btn-save" title="保存(Ctrl+S)"></li>
|
||||
<li class="btn-console-xml" title="打印XML"></li>
|
||||
<li class="btn-edit-xml" title="XML编辑"></li>
|
||||
<li class="btn-copy" title="复制(Ctrl+C)"></li>
|
||||
<li class="btn-paste" title="粘贴(Ctrl+V)"></li>
|
||||
<li class="btn-cut" title="剪切(Ctrl+X)"></li>
|
||||
<li class="btn-undo" title="撤销(Ctrl+Z)"></li>
|
||||
<li class="btn-redo" title="反撤销(Ctrl+Y)"></li>
|
||||
<li class="btn-delete" title="删除(Delete)"></li>
|
||||
<li class="btn-test" title="测试(Ctrl+Q)"></li>
|
||||
<li class="btn-debug" title="调试(Ctrl+Q)"></li>
|
||||
<li class="btn-resume disabled" title="下一步"></li>
|
||||
<li class="btn-stop disabled" title="停止"></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="sidebar-container"></div>
|
||||
|
@ -18,7 +18,8 @@
|
||||
<ul class="layui-nav layui-layout-right">
|
||||
<li class="layui-nav-item"><a target="_blank" href="https://www.spiderflow.org">帮助文档</a></li>
|
||||
<li class="layui-nav-item"><a target="_blank" href="https://shang.qq.com/wpa/qunwpa?idkey=10faa4cf9743e0aa379a72f2ad12a9e576c81462742143c8f3391b52e8c3ed8d">加入QQ群</li>
|
||||
<li class="layui-nav-item"><a target="_blank" href='https://gitee.com/jmxd/spider-flow'><img src='https://gitee.com/jmxd/spider-flow/badge/star.svg?theme=white' alt='star'></img></a></li>
|
||||
<li class="layui-nav-item"><a target="_blank" href='https://gitee.com/jmxd/spider-flow'><img src='https://gitee.com/jmxd/spider-flow/badge/star.svg?theme=white' alt='gitee star' /></a></li>
|
||||
<li class="layui-nav-item"><a target="_blank" href='https://github.com/javamxd/spider-flow'><img src='https://img.shields.io/github/stars/javamxd/spider-flow.svg?style=social' alt='github star' style="background: none"/></a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="layui-side">
|
||||
|
@ -2,6 +2,7 @@ var $ = layui.$;
|
||||
var editor;
|
||||
var flows;
|
||||
var codeMirrorInstances = {};
|
||||
var socket;
|
||||
function renderCodeMirror(){
|
||||
codeMirrorInstances = {};
|
||||
$('[codemirror]').each(function(){
|
||||
@ -221,9 +222,13 @@ $(function(){
|
||||
render();
|
||||
return;
|
||||
}
|
||||
$.get('resources/templates/' + template +".html",function(content){
|
||||
templateCache[template] = content;
|
||||
render();
|
||||
$.ajax({
|
||||
url : 'resources/templates/' + template +".html",
|
||||
async :false,
|
||||
success : function(content){
|
||||
templateCache[template] = content;
|
||||
render();
|
||||
}
|
||||
});
|
||||
}
|
||||
if (!mxClient.isBrowserSupported()){
|
||||
@ -649,267 +654,360 @@ function bindToolbarClickAction(editor){
|
||||
$(".editor-container").hide();
|
||||
$(".xml-container textarea").val(editor.getXML());
|
||||
$(".xml-container").show();
|
||||
$(this).removeClass('btn-edit-xml').addClass('btn-graphical-xml');
|
||||
}).on('click',".btn-graphical-xml",function(){
|
||||
$(".editor-container").show();
|
||||
$(".xml-container").hide();
|
||||
$(this).removeClass('btn-graphical-xml').addClass('btn-edit-xml');
|
||||
// editor.setXML($(".xml-container textarea").val());
|
||||
// editor.onSelectedCell();
|
||||
}).on('click','.btn-stop:not(.disabled)',function () {
|
||||
socket.send(JSON.stringify({
|
||||
eventType : 'stop'
|
||||
}));
|
||||
}).on('click','.btn-resume:not(.disabled)',function () {
|
||||
$(this).addClass('disabled')
|
||||
$(".spiderflow-debug-tooltip").remove();
|
||||
socket.send(JSON.stringify({
|
||||
eventType : 'resume'
|
||||
}));
|
||||
}).on('click','.btn-test',function(){
|
||||
validXML(function(){
|
||||
var LogViewer;
|
||||
var tableMap = {};
|
||||
var socket;
|
||||
var first = true;
|
||||
var filterText = '';
|
||||
var testWindowIndex = layui.layer.open({
|
||||
id : 'test-window',
|
||||
type : 1,
|
||||
content : '<div class="test-window-container"><div class="output-container"><div class="layui-tab layui-tab-fixed layui-tab-brief"><ul class="layui-tab-title"></ul><div class="layui-tab-content"></div></div></div><canvas class="log-container" width="960" height="100"></canvas></div>',
|
||||
area : ["980px","500px"],
|
||||
shade : 0,
|
||||
maxmin : true,
|
||||
maxWidth : 700,
|
||||
maxHeight : 400,
|
||||
title : '测试窗口',
|
||||
btn : ['关闭','显示/隐藏输出','显示/隐藏日志','停止'],
|
||||
btn2 : function(){
|
||||
var $output = $(".test-window-container .output-container");
|
||||
var $log = $(".test-window-container .log-container");
|
||||
if($output.is(":hidden")){
|
||||
$output.show();
|
||||
$output.find("canvas").each(function(){
|
||||
if($log.is(":hidden")){
|
||||
this.height = 320;
|
||||
}else{
|
||||
this.height = 200;
|
||||
}
|
||||
})
|
||||
$log.attr('height',100)
|
||||
LogViewer.resize();
|
||||
for(var tableId in tableMap){
|
||||
tableMap[tableId].instance.resize();
|
||||
}
|
||||
}else{
|
||||
$output.hide();
|
||||
$log.attr('height',400);
|
||||
LogViewer.resize();
|
||||
for(var tableId in tableMap){
|
||||
tableMap[tableId].instance.resize();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
},
|
||||
btn3 : function(){
|
||||
var $output = $(".test-window-container .output-container");
|
||||
var $log = $(".test-window-container .log-container");
|
||||
if($log.is(":hidden")){
|
||||
$log.show();
|
||||
$log.attr('height',$output.is(":hidden") ? 400 : 100)
|
||||
$output.find("canvas").each(function(){
|
||||
runSpider(false);
|
||||
}).on('click','.btn-debug',function(){
|
||||
runSpider(true);
|
||||
}).on('click',".btn-return",function(){
|
||||
location.href="spiderList.html"
|
||||
}).on('click','.btn-save',function(){
|
||||
Save();
|
||||
})
|
||||
}
|
||||
function runSpider(debug){
|
||||
validXML(function(){
|
||||
$(".btn-debug,.btn-test,.btn-resume").addClass('disabled');
|
||||
$(".btn-stop").removeClass('disabled');
|
||||
var LogViewer;
|
||||
var tableMap = {};
|
||||
var first = true;
|
||||
var filterText = '';
|
||||
var testWindowIndex = layui.layer.open({
|
||||
id : 'test-window',
|
||||
type : 1,
|
||||
skin : 'layer-test',
|
||||
content : '<div class="test-window-container"><div class="output-container"><div class="layui-tab layui-tab-fixed layui-tab-brief"><ul class="layui-tab-title"></ul><div class="layui-tab-content"></div></div></div><canvas class="log-container" width="677" height="100"></canvas></div>',
|
||||
area : ["680px","400px"],
|
||||
shade : 0,
|
||||
offset : 'rt',
|
||||
maxmin :true,
|
||||
maxWidth : 700,
|
||||
maxHeight : 400,
|
||||
title : '测试窗口',
|
||||
btn : ['关闭','显示/隐藏输出','显示/隐藏日志','停止'],
|
||||
btn2 : function(){
|
||||
var $output = $(".test-window-container .output-container");
|
||||
var $log = $(".test-window-container .log-container");
|
||||
if($output.is(":hidden")){
|
||||
$output.show();
|
||||
$output.find("canvas").each(function(){
|
||||
if($log.is(":hidden")){
|
||||
this.height = 290;
|
||||
}else{
|
||||
this.height = 200;
|
||||
});
|
||||
LogViewer.resize();
|
||||
for(var tableId in tableMap){
|
||||
tableMap[tableId].instance.resize();
|
||||
}
|
||||
}else{
|
||||
$log.hide();
|
||||
$output.find("canvas").each(function(){
|
||||
this.height = 320;
|
||||
});
|
||||
LogViewer.resize();
|
||||
for(var tableId in tableMap){
|
||||
tableMap[tableId].instance.resize();
|
||||
}
|
||||
})
|
||||
$log.attr('height',100)
|
||||
LogViewer.resize();
|
||||
for(var tableId in tableMap){
|
||||
tableMap[tableId].instance.resize();
|
||||
}
|
||||
return false;
|
||||
},
|
||||
btn4 : function(){
|
||||
var $btn = $("#layui-layer" + testWindowIndex).find('.layui-layer-btn3');
|
||||
if($btn.html() == '停止'){
|
||||
}else{
|
||||
$output.hide();
|
||||
$log.attr('height',320);
|
||||
LogViewer.resize();
|
||||
for(var tableId in tableMap){
|
||||
tableMap[tableId].instance.resize();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
},
|
||||
btn3 : function(){
|
||||
var $output = $(".test-window-container .output-container");
|
||||
var $log = $(".test-window-container .log-container");
|
||||
if($log.is(":hidden")){
|
||||
$log.show();
|
||||
$log.attr('height',$output.is(":hidden") ? 320 : 100)
|
||||
$output.find("canvas").each(function(){
|
||||
this.height = 200;
|
||||
});
|
||||
LogViewer.resize();
|
||||
for(var tableId in tableMap){
|
||||
tableMap[tableId].instance.resize();
|
||||
}
|
||||
}else{
|
||||
$log.hide();
|
||||
$output.find("canvas").each(function(){
|
||||
this.height = 320;
|
||||
});
|
||||
LogViewer.resize();
|
||||
for(var tableId in tableMap){
|
||||
tableMap[tableId].instance.resize();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
},
|
||||
btn4 : function(){
|
||||
var $btn = $("#layui-layer" + testWindowIndex).find('.layui-layer-btn3');
|
||||
if($btn.html() == '停止'){
|
||||
socket.send(JSON.stringify({
|
||||
eventType : 'stop'
|
||||
}));
|
||||
}else{
|
||||
$(".btn-debug,.btn-test,.btn-resume").addClass('disabled');
|
||||
$(".btn-stop").removeClass('disabled');
|
||||
socket.send(JSON.stringify({
|
||||
eventType : debug ? 'debug' : 'test',
|
||||
message : editor.getXML()
|
||||
}));
|
||||
$btn.html('停止');
|
||||
}
|
||||
return false;
|
||||
},
|
||||
end : function(){
|
||||
if(socket){
|
||||
socket.close();
|
||||
$(".spiderflow-debug-tooltip").remove();
|
||||
$(".btn-stop,.btn-resume").addClass('disabled');
|
||||
$(".btn-test,.btn-debug").removeClass('disabled')
|
||||
}
|
||||
if(LogViewer){
|
||||
LogViewer.destory();
|
||||
}
|
||||
for(var tableId in tableMap){
|
||||
tableMap[tableId].instance.destory();
|
||||
}
|
||||
},
|
||||
success : function(layero,index){
|
||||
var logElement = $(".test-window-container .log-container")[0];
|
||||
var colors = {
|
||||
'array' : '#2a00ff',
|
||||
'object' : '#2a00ff',
|
||||
'boolean' : '#600100',
|
||||
'number' : '#000E59'
|
||||
}
|
||||
LogViewer = new CanvasViewer({
|
||||
element : logElement,
|
||||
onClick : function(e){
|
||||
onCanvasViewerClick(e,'日志');
|
||||
}
|
||||
});
|
||||
$(layero).find(".layui-layer-btn")
|
||||
.append('<div class="layui-inline"><input type="text" class="layui-input" placeholder="输入关键字过滤日志"/></div>')
|
||||
.on("keyup","input",function(){
|
||||
LogViewer.filter(this.value);
|
||||
});
|
||||
socket = createWebSocket({
|
||||
onopen : function(){
|
||||
socket.send(JSON.stringify({
|
||||
eventType : 'stop'
|
||||
}));
|
||||
}else{
|
||||
socket.send(JSON.stringify({
|
||||
eventType : 'test',
|
||||
eventType : debug ? 'debug' : 'test',
|
||||
message : editor.getXML()
|
||||
}));
|
||||
$btn.html('停止');
|
||||
}
|
||||
return false;
|
||||
},
|
||||
end : function(){
|
||||
if(socket){
|
||||
socket.close();
|
||||
}
|
||||
if(LogViewer){
|
||||
LogViewer.destory();
|
||||
}
|
||||
for(var tableId in tableMap){
|
||||
tableMap[tableId].instance.destory();
|
||||
}
|
||||
},
|
||||
success : function(layero,index){
|
||||
var logElement = $(".test-window-container .log-container")[0];
|
||||
var colors = {
|
||||
'array' : '#2a00ff',
|
||||
'object' : '#2a00ff',
|
||||
'boolean' : '#600100',
|
||||
'number' : '#000E59'
|
||||
}
|
||||
LogViewer = new CanvasViewer({
|
||||
element : logElement,
|
||||
onClick : function(e){
|
||||
onCanvasViewerClick(e,'日志');
|
||||
}
|
||||
});
|
||||
$(layero).find(".layui-layer-btn")
|
||||
.append('<div class="layui-inline"><input type="text" class="layui-input" placeholder="输入关键字过滤日志"/></div>')
|
||||
.on("keyup","input",function(){
|
||||
LogViewer.filter(this.value);
|
||||
});
|
||||
socket = createWebSocket({
|
||||
onopen : function(){
|
||||
socket.send(JSON.stringify({
|
||||
eventType : 'test',
|
||||
message : editor.getXML()
|
||||
}));
|
||||
},
|
||||
onmessage : function(e){
|
||||
var event = JSON.parse(e.data);
|
||||
var eventType = event.eventType;
|
||||
var message = event.message;
|
||||
if(eventType == 'finish'){
|
||||
$("#layui-layer" + testWindowIndex).find('.layui-layer-btn3').html('重新开始');
|
||||
}else if(eventType == 'output'){
|
||||
var tableId = 'output-' + message.nodeId;
|
||||
var $table = $('#' + tableId);
|
||||
if($table.length == 0){
|
||||
tableMap[tableId] = {
|
||||
index : 0
|
||||
};
|
||||
var $tab = $(".test-window-container .output-container .layui-tab")
|
||||
var outputTitle = '输出-'+tableId;
|
||||
var cell = editor.getModel().cells[message.nodeId];
|
||||
if(cell){
|
||||
outputTitle = cell.value;
|
||||
}
|
||||
if(first){
|
||||
$tab.find(".layui-tab-title").append('<li class="layui-this">' + outputTitle + '</li>');
|
||||
$tab.find(".layui-tab-content").append('<div class="layui-tab-item layui-show" data-output="'+tableId+'"></div>');
|
||||
first = false;
|
||||
}else{
|
||||
$tab.find(".layui-tab-title").append('<li>' + outputTitle + '</li>');
|
||||
$tab.find(".layui-tab-content").append('<div class="layui-tab-item" data-output="'+tableId+'"></div>');
|
||||
}
|
||||
$table = $('<canvas width="960" height="200"/>').appendTo($(".test-window-container .output-container .layui-tab-item[data-output="+tableId+"]"));
|
||||
$table.attr('id',tableId);
|
||||
tableMap[tableId].instance = new CanvasViewer({
|
||||
element : document.getElementById(tableId),
|
||||
grid : true,
|
||||
header : true,
|
||||
style : {
|
||||
font : 'bold 13px Consolas'
|
||||
},
|
||||
onClick : function(e){
|
||||
onCanvasViewerClick(e,'表格');
|
||||
}
|
||||
})
|
||||
var cols = [];
|
||||
var texts = [new CanvasText({
|
||||
text : '序号',
|
||||
maxWidth : 100
|
||||
})];
|
||||
for(var i =0,len = message.outputNames.length;i<len;i++){
|
||||
texts.push(new CanvasText({
|
||||
text : message.outputNames[i],
|
||||
maxWidth : 200,
|
||||
click : true
|
||||
}));
|
||||
}
|
||||
tableMap[tableId].instance.append(texts);
|
||||
},
|
||||
onmessage : function(e){
|
||||
var event = JSON.parse(e.data);
|
||||
var eventType = event.eventType;
|
||||
var message = event.message;
|
||||
if(eventType == 'finish'){
|
||||
$(".spiderflow-debug-tooltip").remove();
|
||||
$("#layui-layer" + testWindowIndex).find('.layui-layer-btn3').html('重新开始');
|
||||
$(".btn-stop,.btn-resume").addClass('disabled');
|
||||
$(".btn-test,.btn-debug").removeClass('disabled')
|
||||
}else if(eventType == 'output'){
|
||||
var tableId = 'output-' + message.nodeId;
|
||||
var $table = $('#' + tableId);
|
||||
if($table.length == 0){
|
||||
tableMap[tableId] = {
|
||||
index : 0
|
||||
};
|
||||
var $tab = $(".test-window-container .output-container .layui-tab")
|
||||
var outputTitle = '输出-'+tableId;
|
||||
var cell = editor.getModel().cells[message.nodeId];
|
||||
if(cell){
|
||||
outputTitle = cell.value;
|
||||
}
|
||||
if(first){
|
||||
$tab.find(".layui-tab-title").append('<li class="layui-this">' + outputTitle + '</li>');
|
||||
$tab.find(".layui-tab-content").append('<div class="layui-tab-item layui-show" data-output="'+tableId+'"></div>');
|
||||
first = false;
|
||||
}else{
|
||||
$tab.find(".layui-tab-title").append('<li>' + outputTitle + '</li>');
|
||||
$tab.find(".layui-tab-content").append('<div class="layui-tab-item" data-output="'+tableId+'"></div>');
|
||||
}
|
||||
$table = $('<canvas width="677" height="200"/>').appendTo($(".test-window-container .output-container .layui-tab-item[data-output="+tableId+"]"));
|
||||
$table.attr('id',tableId);
|
||||
tableMap[tableId].instance = new CanvasViewer({
|
||||
element : document.getElementById(tableId),
|
||||
grid : true,
|
||||
header : true,
|
||||
style : {
|
||||
font : 'bold 13px Consolas'
|
||||
},
|
||||
onClick : function(e){
|
||||
onCanvasViewerClick(e,'表格');
|
||||
}
|
||||
})
|
||||
var cols = [];
|
||||
var texts = [new CanvasText({
|
||||
text : ++tableMap[tableId].index,
|
||||
maxWidth : 200,
|
||||
click : true
|
||||
text : '序号',
|
||||
maxWidth : 100
|
||||
})];
|
||||
for(var i =0,len = message.outputNames.length;i<len;i++){
|
||||
var displayText = message.values[i];
|
||||
var variableType = 'string';
|
||||
if(Array.isArray(displayText)){
|
||||
texts.push(new CanvasText({
|
||||
text : message.outputNames[i],
|
||||
maxWidth : 200,
|
||||
click : true
|
||||
}));
|
||||
}
|
||||
tableMap[tableId].instance.append(texts);
|
||||
}
|
||||
var texts = [new CanvasText({
|
||||
text : ++tableMap[tableId].index,
|
||||
maxWidth : 200,
|
||||
click : true
|
||||
})];
|
||||
for(var i =0,len = message.outputNames.length;i<len;i++){
|
||||
var displayText = message.values[i];
|
||||
var variableType = 'string';
|
||||
if(Array.isArray(displayText)){
|
||||
variableType = 'array';
|
||||
displayText = JSON.stringify(displayText);
|
||||
}else{
|
||||
variableType = typeof displayText;
|
||||
if(variableType == 'object'){
|
||||
displayText = JSON.stringify(displayText);
|
||||
}
|
||||
}
|
||||
texts.push(new CanvasText({
|
||||
text : displayText,
|
||||
maxWidth : 200,
|
||||
color : colors[variableType] || 'black',
|
||||
click : true
|
||||
}));
|
||||
}
|
||||
tableMap[tableId].instance.append(texts);
|
||||
tableMap[tableId].instance.scrollTo(-1);
|
||||
}else if(eventType == 'log'){
|
||||
var texts = [];
|
||||
var defaultColor = message.level == 'error' ? 'red' : '';
|
||||
texts.push(new CanvasText({
|
||||
text : message.level,
|
||||
color : defaultColor
|
||||
}));
|
||||
texts.push(new CanvasText({
|
||||
text : event.timestamp,
|
||||
color : defaultColor
|
||||
}));
|
||||
var temp = message.message.split("{}");
|
||||
message.variables = message.variables || [];
|
||||
for(var i=0,len=temp.length;i<len;i++){
|
||||
if(temp[i]!=''){
|
||||
texts.push(new CanvasText({
|
||||
text : temp[i],
|
||||
color : defaultColor
|
||||
}))
|
||||
}
|
||||
var object = message.variables[i];
|
||||
if(object != undefined){
|
||||
var variableType = '';
|
||||
var displayText = object;
|
||||
if(Array.isArray(object)){
|
||||
variableType = 'array';
|
||||
displayText = JSON.stringify(displayText);
|
||||
}else{
|
||||
variableType = typeof displayText;
|
||||
variableType = typeof object;
|
||||
if(variableType == 'object'){
|
||||
displayText = JSON.stringify(displayText);
|
||||
}
|
||||
}
|
||||
texts.push(new CanvasText({
|
||||
text : displayText,
|
||||
maxWidth : 200,
|
||||
color : colors[variableType] || 'black',
|
||||
maxWidth : 330,
|
||||
color : colors[variableType] || '#025900',
|
||||
click : true
|
||||
}));
|
||||
}))
|
||||
}
|
||||
tableMap[tableId].instance.append(texts);
|
||||
tableMap[tableId].instance.scrollTo(-1);
|
||||
}else if(eventType == 'log'){
|
||||
var texts = [];
|
||||
var defaultColor = message.level == 'error' ? 'red' : '';
|
||||
texts.push(new CanvasText({
|
||||
text : message.level,
|
||||
color : defaultColor
|
||||
}));
|
||||
texts.push(new CanvasText({
|
||||
text : event.timestamp,
|
||||
color : defaultColor
|
||||
}));
|
||||
var temp = message.message.split("{}");
|
||||
message.variables = message.variables || [];
|
||||
for(var i=0,len=temp.length;i<len;i++){
|
||||
if(temp[i]!=''){
|
||||
texts.push(new CanvasText({
|
||||
text : temp[i],
|
||||
color : defaultColor
|
||||
}))
|
||||
}
|
||||
var object = message.variables[i];
|
||||
if(object != undefined){
|
||||
var variableType = '';
|
||||
var displayText = object;
|
||||
if(Array.isArray(object)){
|
||||
variableType = 'array';
|
||||
displayText = JSON.stringify(displayText);
|
||||
}else{
|
||||
variableType = typeof object;
|
||||
if(variableType == 'object'){
|
||||
displayText = JSON.stringify(displayText);
|
||||
}
|
||||
}
|
||||
texts.push(new CanvasText({
|
||||
text : displayText,
|
||||
maxWidth : 330,
|
||||
color : colors[variableType] || '#025900',
|
||||
click : true
|
||||
}))
|
||||
}
|
||||
}
|
||||
LogViewer.append(texts);
|
||||
LogViewer.scrollTo(-1);
|
||||
}
|
||||
LogViewer.append(texts);
|
||||
LogViewer.scrollTo(-1);
|
||||
}else if(eventType == 'debug'){
|
||||
console.log(message);
|
||||
$(".btn-resume").removeClass('disabled');
|
||||
var type = message.event;
|
||||
editor.selectCell(editor.graph.model.cells[message.nodeId]);
|
||||
var selector;
|
||||
if(type == 'request-parameter'){
|
||||
$('.layui-tab-title li:eq(1)').click();
|
||||
}
|
||||
if(type == 'request-cookie'){
|
||||
$('.layui-tab-title li:eq(2)').click();
|
||||
}
|
||||
if(type == 'request-header'){
|
||||
$('.layui-tab-title li:eq(3)').click();
|
||||
}
|
||||
if(type == 'request-body'){
|
||||
$('.layui-tab-title li:eq(4)').click();
|
||||
}
|
||||
if(type == 'common' || type == 'request-parameter' || type == 'request-header' || type == 'request-cookie'){
|
||||
selector = '.layui-table-cell input[value='+message.key+']';
|
||||
}
|
||||
if($(selector).length == 0){
|
||||
selector = '.properties-container input[name='+message.key+']';
|
||||
}
|
||||
if($(selector).length == 0){
|
||||
selector = '.properties-container [codemirror='+message.key+']';
|
||||
}
|
||||
var o1 = $(selector).offset();
|
||||
var $parent = $(".properties-container");
|
||||
var o2 = $parent.offset();
|
||||
if(o1.top > o2.top + $parent.height()){
|
||||
$parent[0].scrollTop = o1.top - o2.top;
|
||||
}
|
||||
var msg = message.value;
|
||||
var isJson = Array.isArray(msg) || typeof msg == 'object';
|
||||
if(!isJson){
|
||||
var temp = document.createElement("div");
|
||||
(temp.textContent != null) ? (temp.textContent = msg) : (temp.innerText = msg);
|
||||
msg = temp.innerHTML;
|
||||
temp = null;
|
||||
}
|
||||
var content = '<div class="message-content" style="padding:10px;'+(isJson ? '':'font-weight: bold;font-family:Consolas;font-size:12px;')+'">'+(isJson ? '' : msg.replace(/\n/g,'<br>')).replace(/ /g,' ').replace(/\t/g,' ')+'</div>';
|
||||
var tooltip = bindTooltip(content,selector);
|
||||
if(isJson){
|
||||
var $dom = $(tooltip.dom).find(".message-content");
|
||||
jsonTree.create(msg,$dom[0]);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
})
|
||||
});
|
||||
}).on('click',".btn-return",function(){
|
||||
location.href="spiderList.html"
|
||||
}).on('click','.btn-save',function(){
|
||||
Save();
|
||||
})
|
||||
}
|
||||
});
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
function bindTooltip(content,selector){
|
||||
var dom = document.createElement('div');
|
||||
var $target = $(selector);
|
||||
var offset = $target.offset();
|
||||
dom.className = 'spiderflow-debug-tooltip';
|
||||
dom.style.bottom = ($("body").height() - offset.top) + 'px';
|
||||
dom.style.left = (offset.left + $target.width() / 2) + 'px';
|
||||
dom.innerHTML = '<div class="content">' + content + '</div>';
|
||||
document.body.appendChild(dom);
|
||||
$(selector).offset();
|
||||
return {
|
||||
dom : dom,
|
||||
close : function(){
|
||||
document.body.removeChild(dom);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
//最近点击打开的弹窗
|
||||
var index;
|
||||
|
Loading…
Reference in New Issue
Block a user