Compare commits

...

19 Commits

Author SHA1 Message Date
Nick O'Leary
1c86908b90 Bump 0.10.2 2015-02-20 10:07:10 +00:00
Nick O'Leary
9b26973883 Ensure activeWorkspace is set when a flow contains no tabs 2015-02-20 10:05:42 +00:00
Nick O'Leary
2585e983a5 Add test-* grunt tasks 2015-02-15 23:35:24 +00:00
Nick O'Leary
a808cb44c2 Merge pull request #563 from emiloberg/master
Fixes bug that prevented unsubscribe from WebSockets, browser side. Fixes node-red/node-red/#562
2015-02-15 21:54:48 +00:00
Nick O'Leary
edd9d2cb9c Fix Inject node handling of day selection
Fixes #564
2015-02-15 21:53:14 +00:00
Emil Öberg
33d24f79ce Fixes bug that prevented unsubscribe from WebSockets, browser side. Fixes node-red/node-red/#562 2015-02-14 22:25:25 +01:00
dceejay
cc095e4edf edit HTML node info to remove ref to jQuery. Link to CSSselect instead. 2015-02-14 19:06:35 +00:00
dceejay
07641d57ab recorrect debug logging level colour class names so sidebar is as-was.
in light of new logging levels
2015-02-14 12:14:06 +00:00
dceejay
5643c51507 Let debug node show "topic" correctly for errors in functions. 2015-02-13 21:14:54 +00:00
Nick O'Leary
ad6254c0b8 Add oneditdelete handler for config nodes
Already had the undocumented ondelete handler. Adding
this to be consistent with the other oneditXYZ handlers.
2015-02-13 11:20:08 +00:00
Nick O'Leary
d6ca421d59 Remove unecessary argument to oneditcancel 2015-02-13 11:05:45 +00:00
Nick O'Leary
79bd01f810 Remove X button on dialogs
Fixes #561

Also, oneditcancel not being honoured for regular nodes, only config nodes
2015-02-13 10:06:28 +00:00
Nick O'Leary
e357352240 Tidy up info tab handling of subflows and comments 2015-02-10 21:29:27 +00:00
dceejay
0accfade02 catch internal subflow info error in tab-info... 2015-02-10 20:15:00 +00:00
dceejay
00b7afe3ae spelling pedant alert in debug node... its not it's 2015-02-10 20:14:33 +00:00
dceejay
2e76541fa5 Update Debug node test to "unbreak" build... oops 2015-02-10 17:31:26 +00:00
dceejay
e2911078e3 tidy up tab-info so subflows show more useful information
(was broken before but no-one noticed ;-)
(and reorder fields in HTTP and XML nodes so name comes out first - ocd)
2015-02-10 16:56:07 +00:00
dceejay
c6157687c9 Move payload type label in Debug window to meta data row
rather than (object) etc at start of actual payload.
2015-02-10 16:56:07 +00:00
Nick O'Leary
87a1818486 Add missing FA font file 2015-02-09 09:48:31 +00:00
15 changed files with 244 additions and 220 deletions

View File

@@ -86,6 +86,10 @@ module.exports = function(grunt) {
grunt.loadNpmTasks('grunt-simple-mocha');
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.registerTask('default', ['jshint:core','jshint:tests','jshint:editor','simplemocha:core','simplemocha:nodes']);
grunt.registerTask('default', ['test-core','test-editor','test-nodes']);
grunt.registerTask('test-core', ['jshint:core','simplemocha:core']);
grunt.registerTask('test-editor', ['jshint:editor']);
grunt.registerTask('test-nodes', ['simplemocha:nodes']);
};

View File

@@ -44,7 +44,6 @@
<div class="form-row inject-time-row hidden" id="inject-time-row-interval">
every <input id="inject-time-interval-count" class="inject-time-count" value="1"></input>
<select style="width: 100px" id="inject-time-interval-units"><option value="s">seconds</option><option value="m">minutes</option><option value="h">hours</option></select><br/>
<!-- on <select disabled id="inject-time-interval-days" class="inject-time-days"></select> -->
</div>
<div class="form-row inject-time-row hidden" id="inject-time-row-interval-time">
@@ -64,34 +63,45 @@
</select> minutes<br/>
between <select id="inject-time-interval-time-start" class="inject-time-times"></select>
and <select id="inject-time-interval-time-end" class="inject-time-times"></select><br/>
<!-- on <select id="inject-time-interval-time-days" class="inject-time-days"></select> -->
<div id="inject-time-interval-time-days" class="inject-time-days">
<table style="width:100% !important"><tr><td valign="top">on&nbsp;</td><td valign="top">
<label><input type='checkbox' class="cb1" value='1'/> Monday</label>
<label><input type='checkbox' class="cb1" value='2'/> Tuesday</label>
<label><input type='checkbox' class="cb1" value='3'/> Wednesday</label>
<label><input type='checkbox' class="cb1" value='4'/> Thursday</label>
<label><input type='checkbox' class="cb1" value='5'/> Friday</label>
<label><input type='checkbox' class="cb1" value='6'/> Saturday</label>
<label><input type='checkbox' class="cb1" value='0'/> Sunday</label>
<!-- <div><input type='checkbox' id="cb1selectall" value='*'/> Everyday</div> -->
</td></tr></table>
<div style="display: inline-block; vertical-align: top;margin-right: 5px;">on </div>
<div style="display:inline-block;">
<div>
<label><input type='checkbox' checked value='1'/> Monday</label>
<label><input type='checkbox' checked value='2'/> Tuesday</label>
<label><input type='checkbox' checked value='3'/> Wednesday</label>
</div>
<div>
<label><input type='checkbox' checked value='4'/> Thursday</label>
<label><input type='checkbox' checked value='5'/> Friday</label>
<label><input type='checkbox' checked value='6'/> Saturday</label>
</div>
<div>
<label><input type='checkbox' checked value='0'/> Sunday</label>
</div>
</div>
</div>
</div>
<div class="form-row inject-time-row hidden" id="inject-time-row-time">
at <input id="inject-time-time" value="12:00"></input><br/>
<!-- on <select id="inject-time-time-days" class="inject-time-days"></select> -->
<div id="inject-time-time-days" class="inject-time-days">
<table style="width:100% !important"><tr><td valign="top">on&nbsp;</td><td valign="top">
<label><input type='checkbox' class="cb2" value='1'/> Monday</label>
<label><input type='checkbox' class="cb2" value='2'/> Tuesday</label>
<label><input type='checkbox' class="cb2" value='3'/> Wednesday</label>
<label><input type='checkbox' class="cb2" value='4'/> Thursday</label>
<label><input type='checkbox' class="cb2" value='5'/> Friday</label>
<label><input type='checkbox' class="cb2" value='6'/> Saturday</label>
<label><input type='checkbox' class="cb2" value='0'/> Sunday</label>
</td></tr></table>
<div style="display: inline-block; vertical-align: top;margin-right: 5px;">on </div>
<div style="display:inline-block;">
<div>
<label><input type='checkbox' checked value='1'/> Monday</label>
<label><input type='checkbox' checked value='2'/> Tuesday</label>
<label><input type='checkbox' checked value='3'/> Wednesday</label>
</div>
<div>
<label><input type='checkbox' checked value='4'/> Thursday</label>
<label><input type='checkbox' checked value='5'/> Friday</label>
<label><input type='checkbox' checked value='6'/> Saturday</label>
</div>
<div>
<label><input type='checkbox' checked value='0'/> Sunday</label>
</div>
</div>
</div>
</div>
@@ -115,9 +125,18 @@
.inject-time-row select {
margin: 3px 0;
}
//.inject-time-days {
// width: 262px;
//}
.inject-time-days label {
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
vertical-align: top;
width: 100px;
}
.inject-time-days input {
width: auto;
}
.inject-time-times {
width: 90px;
}
@@ -135,12 +154,17 @@
}
</style>
<script type="text/x-red" data-help-name="inject">
<p>Pressing the button on the left side of the node allows a message on a topic to be injected into the flow. This is mainly for test purposes.</p>
<p>If no payload is specified the payload is set to the current time in millisecs since 1970. This allows subsequent functions to perform time based actions.</p>
<p>The repeat function does what it says on the tin and continuously sends the payload every x seconds.</p>
<p>The Fire once at start option actually waits 50mS before firing to give other nodes a chance to instantiate properly.</p>
<p><b>Note: </b>"Interval between times" and "at a specific time" will use cron. This means that 20 minutes will be at the next hour, 20 minutes past and 40 minutes past - not in 20 minutes time.
If you want every 20 minutes from now - use the basic "interval" option.</p>
<p>Pressing the button on the left side of the node allows a message on a topic
to be injected into the flow. This is mainly for test purposes.</p>
<p>The payload defaults to the current time in millisecs since 1970, but can
also be set to a String or left blank.</p>
<p>The repeat function allows the payload to be sent on the required schedule.</p>
<p>The Fire once at start option actually waits a short interval before firing
to give other nodes a chance to instantiate properly.</p>
<p><b>Note: </b>"Interval between times" and "at a specific time" uses cron.
This means that 20 minutes will be at the next hour, 20 minutes past and
40 minutes past - not in 20 minutes time. If you want every 20 minutes
from now - use the "interval" option.</p>
</script>
<script type="text/javascript">
@@ -191,42 +215,28 @@
}
});
//$("#cb1selectall").click(function () {
// $('.cb1').attr('checked', this.checked);
//});
//$(".cb1").click(function(){
// if($(".cb1:checked").length == 7) {
// $("#cb1selectall").attr("checked", "checked");
// } else {
// $("#cb1selectall").removeAttr("checked");
// }
//});
//var days = [
// {v:"*",t:"every day"},
// {v:"1-5",t:"Mondays to Fridays"},
// {v:"0,6",t:"Saturdays and Sundays"},
// {v:"1",t:"Mondays"},
// {v:"2",t:"Tuesdays"},
// {v:"3",t:"Wednesdays"},
// {v:"4",t:"Thursdays"},
// {v:"5",t:"Fridays"},
// {v:"6",t:"Saturdays"},
// {v:"0",t:"Sundays"}
//];
//$(".inject-time-days").each(function() {
// for (var d in days) {
// $(this).append($("<option></option>").val(days[d].v).text(days[d].t));
// }
//});
$(".inject-time-times").each(function() {
for (var i=0;i<24;i++) {
var l = (i<10?"0":"")+i+":00";
$(this).append($("<option></option>").val(i).text(l));
}
});
$("#inject-time-interval-time-start").change(function() {
var start = Number($("#inject-time-interval-time-start option:selected").val());
var end = Number($("#inject-time-interval-time-end option:selected").val());
$("#inject-time-interval-time-end option").remove();
for (var i=start+1;i<25;i++) {
var l = (i<10?"0":"")+i+":00";
if (i==24) {
l = "00:00";
}
var opt = $("<option></option>").val(i).text(l).appendTo("#inject-time-interval-time-end");
if (i === end) {
opt.attr("selected","selected");
}
}
});
$(".inject-time-count").spinner({
//max:60,
@@ -235,8 +245,6 @@
$("#inject-time-interval-units").change(function() {
var units = $("#inject-time-interval-units option:selected").val();
//$("#inject-time-interval-days").prop("disabled",(units == "s")?"disabled":false);
//$(".inject-time-count").spinner("option","max",(units == "h")?24:60);
});
$.widget( "ui.injecttimespinner", $.ui.spinner, {
@@ -277,7 +285,6 @@
if (this.repeat % 1440 === 0) { r = "h"; c = c/60; }
$("#inject-time-interval-count").val(c);
$("#inject-time-interval-units").val(r);
//$("#inject-time-interval-units option").filter(function() {return $(this).val() == "s";}).attr('selected',true);
$("#inject-time-interval-days").prop("disabled","disabled");
} else if (this.crontab) {
var cronparts = this.crontab.split(" ");
@@ -288,44 +295,28 @@
var time = cronparts[1]+":"+cronparts[0];
$("#inject-time-time").val(time);
$("#inject-time-type-select option").filter(function() {return $(this).val() == "s";}).attr('selected',true);
//$("#inject-time-time-days option").filter(function() {return $(this).val() == days;}).attr('selected',true);
if (days == "*") { days = "1,2,3,4,5,6,0"; }
var daya = days.split(",");
for(var i = 0; i < daya.length; i++) {
$("#inject-time-time-days [value=" + daya[i] + "]").attr("checked", "checked");
if (days == "*") {
$("#inject-time-time-days input[type=checkbox]").prop("checked",true);
} else {
$("#inject-time-time-days input[type=checkbox]").removeAttr("checked");
days.split(",").forEach(function(v) {
$("#inject-time-time-days [value=" + v + "]").prop("checked", true);
});
}
}
//else if (cronparts[0] == "0") {
// // interval - hours
// var hours = cronparts[1].slice(2);
// repeattype = "interval";
// $("#inject-time-interval-days").prop("disabled",false);
// $("#inject-time-interval-days option").filter(function() {return $(this).val() == days;}).attr('selected',true);
// $("#inject-time-interval-count").val(hours)
// $("#inject-time-interval-units option").filter(function() {return $(this).val() == "h";}).attr('selected',true);
//} else if (cronparts[1] == "*") {
// // interval - minutes
// var minutes = cronparts[0].slice(2);
// repeattype = "interval";
// $("#inject-time-interval-days").prop("disabled",false);
// $("#inject-time-interval-days option").filter(function() {return $(this).val() == days;}).attr('selected',true);
// $("#inject-time-interval-count").val(minutes)
// $("#inject-time-interval-units option").filter(function() {return $(this).val() == "m";}).attr('selected',true);
//}
else {
} else {
repeattype = "interval-time";
// interval - time period
var minutes = cronparts[0].slice(2);
if (minutes === "") { minutes = "0"; }
$("#inject-time-interval-time-units").val(minutes);
//$("#inject-time-interval-time-days option").filter(function() {return $(this).val() == days;}).attr('selected',true);
if (days == "*") { days = "1,2,3,4,5,6,0"; }
var daya = days.split(",");
for(var i = 0; i < daya.length; i++) {
$("#inject-time-interval-time-days [value=" + daya[i] + "]").attr("checked", "checked");
if (days == "*") {
$("#inject-time-interval-time-days input[type=checkbox]").prop("checked",true);
} else {
$("#inject-time-interval-time-days input[type=checkbox]").removeAttr("checked");
days.split(",").forEach(function(v) {
$("#inject-time-interval-time-days [value=" + v + "]").prop("checked", true);
});
}
var time = cronparts[1];
var timeparts = time.split(",");
var start;
@@ -389,6 +380,7 @@
$("#node-input-payloadType").val(this.payloadType);
$("#node-input-payloadType").change();
$("#inject-time-type-select").change();
$("#inject-time-interval-time-start").change();
},
oneditsave: function() {
@@ -400,7 +392,6 @@
} else if (type == "interval") {
var count = $("#inject-time-interval-count").val();
var units = $("#inject-time-interval-units option:selected").val();
//var days = $("#inject-time-interval-days option:selected").val();
if (units == "s") {
repeat = count;
} else {
@@ -413,64 +404,70 @@
}
}
} else if (type == "interval-time") {
repeat = "";
var count = $("#inject-time-interval-time-units").val();
var startTime = Number($("#inject-time-interval-time-start option:selected").val());
var endTime = Number($("#inject-time-interval-time-end option:selected").val());
//var days = $("#inject-time-interval-time-days option:selected").val();
var days = $('.cb1:checked').map(function(_, el) {
var days = $('#inject-time-interval-time-days input[type=checkbox]:checked').map(function(_, el) {
return $(el).val()
}).get();
if (days.length == 7) { days="*"; }
else { days = days.join(","); }
var timerange = "";
if (startTime == endTime) {
//TODO: invalid
repeat = "";
if (days.length == 0) {
crontab = "";
} else if (endTime == 0) {
timerange = startTime+"-23";
} else if (startTime+1 < endTime) {
timerange = startTime+"-"+(endTime-1);
} else if (startTime+1 == endTime) {
timerange = startTime;
} else {
var startpart = "";
var endpart = "";
if (startTime == 23) {
startpart = "23";
if (days.length == 7) {
days="*";
} else {
startpart = startTime+"-23";
days = days.join(",");
}
if (endTime == 1) {
endpart = "0";
var timerange = "";
if (endTime == 0) {
timerange = startTime+"-23";
} else if (startTime+1 < endTime) {
timerange = startTime+"-"+(endTime-1);
} else if (startTime+1 == endTime) {
timerange = startTime;
} else {
endpart = "0-"+(endTime-1);
var startpart = "";
var endpart = "";
if (startTime == 23) {
startpart = "23";
} else {
startpart = startTime+"-23";
}
if (endTime == 1) {
endpart = "0";
} else {
endpart = "0-"+(endTime-1);
}
timerange = startpart+","+endpart;
}
if (count === "0") {
crontab = count+" "+timerange+" * * "+days;
} else {
crontab = "*/"+count+" "+timerange+" * * "+days;
}
timerange = startpart+","+endpart;
}
repeat = "";
if (count === "0") {
crontab = count+" "+timerange+" * * "+days;
}
else {
crontab = "*/"+count+" "+timerange+" * * "+days;
}
} else if (type == "time") {
var time = $("#inject-time-time").val();
//var days = $("#inject-time-time-days option:selected").val();
var days = $('.cb2:checked').map(function(_, el) {
var days = $('#inject-time-time-days input[type=checkbox]:checked').map(function(_, el) {
return $(el).val()
}).get();
if (days.length == 7) { days="*"; }
else { days = days.join(","); }
var parts = time.split(":");
repeat = "";
crontab = parts[1]+" "+parts[0]+" * * "+days;
if (days.length == 0) {
crontab = "";
} else {
if (days.length == 7) {
days="*";
} else {
days = days.join(",");
}
var parts = time.split(":");
repeat = "";
crontab = parts[1]+" "+parts[0]+" * * "+days;
}
}
$("#node-input-repeat").val(repeat);
$("#node-input-crontab").val(crontab);
},
button: {
onclick: function() {

View File

@@ -1,5 +1,5 @@
<!--
Copyright 2013 IBM Corp.
Copyright 2013, 2015 IBM Corp.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -42,7 +42,7 @@
<p>The Debug node can be connected to the output of any node. It can be used to display the output of any message property in the debug tab of the sidebar. The default is to display <b>msg.payload</b>.</p>
<p>Each message will also display the timestamp, <b>msg.topic</b> and the property chosen to output.</p>
<p>The sidebar can be accessed under the options drop-down in the top right corner.</p>
<p>The button to the right of the node will toggle it's output on and off so you can de-clutter the debug window.</p>
<p>The button to the right of the node will toggle its output on and off so you can de-clutter the debug window.</p>
<p>If the payload is an object or buffer it will be stringified first for display and indicate that by saying "(Object)" or "(Buffer)".</p>
<p>Selecting any particular message will highlight (in red) the debug node that reported it. This is useful if you wire up multiple debug nodes.</p>
<p>Optionally can show the complete <b>msg</b> object.</p>
@@ -187,16 +187,22 @@
var name = (o.name?o.name:o.id).toString().replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;");
var topic = (o.topic||"").toString().replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;");
var property = (o.property?o.property:'').replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;");
var payload = (o.msg||"").toString().replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;");
var payload = (o.msg||"()").toString().replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;");
var typ = payload.substring(0,payload.indexOf(')')+1);
payload = payload.substring(payload.indexOf(')')+1);
msg.className = 'debug-message'+(o.level?(' debug-message-level-'+o.level):'');
msg.innerHTML = '<span class="debug-message-date">'+
getTimestamp()+'</span>'+
'<span class="debug-message-name">['+name+']</span>'+
'<span class="debug-message-topic">'+
(o.topic?topic+' : ':'')+
(o.property?'[msg.'+property+']':'[msg]')+
'</span>'+'<span class="debug-message-payload">'+
payload+'</span>';
getTimestamp()+'</span><span class="debug-message-name">['+name+']'+
'</span>';
// NOTE: relying on function error to have a "type" that all other msgs don't
if (o.hasOwnProperty("type") && (o.type === "function")) {
msg.className = 'debug-message debug-message-level-20';
msg.innerHTML += '<span class="debug-message-topic">[function] : (error)</span>';
} else {
msg.innerHTML += '<span class="debug-message-topic">'+(o.topic?topic+' : ':'')+
(o.property?'[msg.'+property+']':'[msg]')+" : "+typ+'</span>';
}
msg.innerHTML += '<span class="debug-message-payload">'+ payload+ '</span>';
var atBottom = (sbc.scrollHeight-messages.offsetHeight-sbc.scrollTop) < 5;
messageCount++;
$(messages).append(msg);
@@ -261,7 +267,7 @@
display: block;
background: #fff;
padding: 1px 5px;
font-size: 9px;
font-size: 10px;
color: #a66;
}
.debug-message-name {
@@ -279,11 +285,11 @@
border-left-color: #eee;
border-right-color: #eee;
}
.debug-message-level-warn {
.debug-message-level-30 {
border-left-color: #ffdf9d;
border-right-color: #ffdf9d;
}
.debug-message-level-error {
.debug-message-level-20 {
border-left-color: #f99;
border-right-color: #f99;
}

View File

@@ -99,11 +99,13 @@ module.exports = function(RED) {
seen = null;
} else if (typeof msg.msg === "boolean") {
msg.msg = "(boolean) "+msg.msg.toString();
} else if (typeof msg.msg === "number") {
msg.msg = "(number) "+msg.msg.toString();
} else if (msg.msg === 0) {
msg.msg = "0";
} else if (msg.msg === null || typeof msg.msg === "undefined") {
msg.msg = "(undefined)";
}
} else { msg.msg = "(string) "+msg.msg; }
if (msg.msg.length > debuglength) {
msg.msg = msg.msg.substr(0,debuglength) +" ....";

View File

@@ -30,7 +30,7 @@
</script>
<script type="text/x-red" data-help-name="comment">
<p>Comment</p>
<p>A node you can use to add comments to your flows.</p>
</script>
<script type="text/javascript">

View File

@@ -40,14 +40,14 @@
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
<input type="text" id="node-input-name" placeholder="Name">
</div>
<div class="form-tips">Tip: The <b>Select</b> value is a <a href="http://api.jquery.com/category/selectors/" target="_new"><i><u>jQuery</u></i></a> style selector.</div>
<div class="form-tips">Tip: The <b>Select</b> value is a <a href="https://github.com/fb55/CSSselect#user-content-supported-selectors" target="_new"><i><u>CSS Selector</u></i></a>, similar to a jQuery selector.</div>
</script>
<script type="text/x-red" data-help-name="html">
<p>Extracts elements from an html document held in <b>msg.payload</b> using a selector.</p>
<p>The selector uses <a href=="https://github.com/cheeriojs/cheerio/blob/master/Readme.md" target="_new">Cheerio</a>
which uses the <a href="https://github.com/fb55/CSSselect" target="_new">CSS selector</a> syntax.</p>
<p>The result is either a single message with a payload containing an array of the matched elements, or multiple
which uses the <a href="https://github.com/fb55/CSSselect#user-content-supported-selectors" target="_new">CSS selector</a> syntax.</p>
<p>The result can be either a single message with a payload containing an array of the matched elements, or multiple
messages that each contain a matched element.</p>
</script>
@@ -56,10 +56,10 @@
category: 'function',
color:"#DEBD5C",
defaults: {
name: {value:""},
tag: {value:""},
ret: {value:"html"},
as: {value:"single"},
name: {value:""}
as: {value:"single"}
},
inputs:1,
outputs:1,

View File

@@ -61,9 +61,9 @@
category: 'function',
color:"#DEBD5C",
defaults: {
name: {value:""},
attr: {value:'$',required:true},
chr: {value:'_',required:true},
name: {value:""}
chr: {value:'_',required:true}
},
inputs:1,
outputs:1,

View File

@@ -1,6 +1,6 @@
{
"name" : "node-red",
"version" : "0.10.1",
"version" : "0.10.2",
"description" : "A visual tool for wiring the Internet of Things",
"homepage" : "http://nodered.org",
"license" : "Apache",

Binary file not shown.

View File

@@ -95,15 +95,15 @@ RED.comms = (function() {
}
function unsubscribe(topic,callback) {
if (subscriptions.topic) {
for (var i=0;i<subscriptions.topic.length;i++) {
if (subscriptions.topic[i] === callback) {
subscriptions.topic.splice(i,1);
if (subscriptions[topic]) {
for (var i=0;i<subscriptions[topic].length;i++) {
if (subscriptions[topic][i] === callback) {
subscriptions[topic].splice(i,1);
break;
}
}
if (subscriptions.topic.length === 0) {
delete subscriptions.topic;
if (subscriptions[topic].length === 0) {
delete subscriptions[topic];
}
}
}

View File

@@ -615,6 +615,7 @@ RED.nodes = (function() {
addWorkspace(defaultWorkspace);
RED.view.addWorkspace(defaultWorkspace);
new_workspaces.push(defaultWorkspace);
activeWorkspace = RED.view.getWorkspace();
}
var node_map = {};

View File

@@ -257,6 +257,11 @@ RED.editor = (function() {
id: "node-dialog-cancel",
text: "Cancel",
click: function() {
if (editing_node._def) {
if (editing_node._def.oneditcancel) {
editing_node._def.oneditcancel.call(editing_node);
}
}
$( this ).dialog( "close" );
}
}
@@ -267,6 +272,7 @@ RED.editor = (function() {
}
},
open: function(e) {
$(this).parent().find(".ui-dialog-titlebar-close").hide();
RED.keyboard.disable();
if (editing_node) {
var size = $(this).dialog('option','sizeCache-'+editing_node.type);
@@ -547,6 +553,9 @@ RED.editor = (function() {
if (configTypeDef.ondelete) {
configTypeDef.ondelete.call(RED.nodes.node(configId));
}
if (configTypeDef.oneditdelete) {
configTypeDef.oneditdelete.call(RED.nodes.node(configId));
}
RED.nodes.remove(configId);
for (var i=0;i<configNode.users.length;i++) {
var user = configNode.users[i];
@@ -680,7 +689,8 @@ RED.editor = (function() {
],
resize: function(e,ui) {
},
open: function(e) {
open: function(e,ui) {
$(this).parent().find(".ui-dialog-titlebar-close").hide();
if (RED.view.state() != RED.state.EDITING) {
RED.keyboard.disable();
}
@@ -756,7 +766,8 @@ RED.editor = (function() {
}
}
],
open: function(e) {
open: function(e,ui) {
$(this).parent().find(".ui-dialog-titlebar-close").hide();
RED.keyboard.disable();
},
close: function(e) {

View File

@@ -14,7 +14,7 @@
* limitations under the License.
**/
RED.sidebar.info = (function() {
marked.setOptions({
renderer: new marked.Renderer(),
gfm: true,
@@ -25,7 +25,7 @@ RED.sidebar.info = (function() {
smartLists: true,
smartypants: false
});
var content = document.createElement("div");
content.id = "tab-info";
content.style.paddingTop = "4px";
@@ -38,7 +38,7 @@ RED.sidebar.info = (function() {
}
RED.sidebar.show("info");
}
function jsonFilter(key,value) {
if (key === "") {
return value;
@@ -58,58 +58,71 @@ RED.sidebar.info = (function() {
function refresh(node) {
var table = '<table class="node-info"><tbody>';
table += '<tr class="blank"><td colspan="2">Node</td></tr>';
table += "<tr><td>Type</td><td>&nbsp;"+node.type+"</td></tr>";
table += "<tr><td>ID</td><td>&nbsp;"+node.id+"</td></tr>";
table += '<tr class="blank"><td colspan="2">Properties</td></tr>';
if (node.type == "subflow") {
var m = /^subflow(:(.+))?$/.exec(node.type);
if (m) {
var subflowNode;
if (m[2]) {
subflowNode = RED.nodes.subflow(m[2]);
} else {
subflowNode = node;
}
table += '<tr class="blank"><td colspan="2">Subflow</td></tr>';
var userCount = 0;
var subflowType = "subflow:"+node.id;
var subflowType = "subflow:"+subflowNode.id;
RED.nodes.eachNode(function(n) {
if (n.type === subflowType) {
userCount++;
}
});
table += "<tr><td>name</td><td>"+node.name+"</td></tr>";
table += "<tr><td>inputs</td><td>"+node.in.length+"</td></tr>";
table += "<tr><td>outputs</td><td>"+node.out.length+"</td></tr>";
table += "<tr><td>name</td><td>"+subflowNode.name+"</td></tr>";
table += "<tr><td>instances</td><td>"+userCount+"</td></tr>";
}
if (node._def) {
for (var n in node._def.defaults) {
if (node._def.defaults.hasOwnProperty(n)) {
var val = node[n]||"";
var type = typeof val;
if (type === "string") {
if (val.length > 30) {
val = val.substring(0,30)+" ...";
if (node.type != "subflow" && node.type != "comment") {
table += '<tr class="blank"><td colspan="2">Properties</td></tr>';
if (node._def) {
for (var n in node._def.defaults) {
if (node._def.defaults.hasOwnProperty(n)) {
var val = node[n]||"";
var type = typeof val;
if (type === "string") {
if (val.length > 30) {
val = val.substring(0,30)+" ...";
}
val = val.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;");
} else if (type === "number") {
val = val.toString();
} else if ($.isArray(val)) {
val = "[<br/>";
for (var i=0;i<Math.min(node[n].length,10);i++) {
var vv = JSON.stringify(node[n][i],jsonFilter," ").replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;");
val += "&nbsp;"+i+": "+vv+"<br/>";
}
if (node[n].length > 10) {
val += "&nbsp;... "+node[n].length+" items<br/>";
}
val += "]";
} else {
val = JSON.stringify(val,jsonFilter," ");
val = val.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;");
}
val = val.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;");
} else if (type === "number") {
val = val.toString();
} else if ($.isArray(val)) {
val = "[<br/>";
for (var i=0;i<Math.min(node[n].length,10);i++) {
var vv = JSON.stringify(node[n][i],jsonFilter," ").replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;");
val += "&nbsp;"+i+": "+vv+"<br/>";
}
if (node[n].length > 10) {
val += "&nbsp;... "+node[n].length+" items<br/>";
}
val += "]";
} else {
val = JSON.stringify(val,jsonFilter," ");
val = val.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;");
table += "<tr><td>"+n+"</td><td>"+val+"</td></tr>";
}
table += "<tr><td>"+n+"</td><td>"+val+"</td></tr>";
}
}
}
table += "</tbody></table><br/>";
var helpText = $("script[data-help-name|='"+node.type+"']").html()||"";
table += '<div class="node-help">'+helpText+"</div>";
if (node.type != "comment") {
var helpText = $("script[data-help-name|='"+node.type+"']").html()||"";
table += '<div class="node-help">'+helpText+"</div>";
}
if (node._def && node._def.info) {
var info = node._def.info;

View File

@@ -765,16 +765,6 @@ g.link_unknown path.link_line {
.form-row input {
width:70%;
}
.form-row label .cb1 {
display: inline !important;
width: auto !important;
vertical-align: top !important;
}
.form-row label .cb2 {
display: inline !important;
width: auto !important;
vertical-align: top !important;
}
input.input-append-left {
border-top-right-radius: 0px;

View File

@@ -47,7 +47,7 @@ describe('debug node', function() {
n1.emit("input", {payload:"test"});
}, function(msg) {
JSON.parse(msg).should.eql({
topic:"debug",data:{id:"n1",name:"Debug",msg:"test",
topic:"debug",data:{id:"n1",name:"Debug",msg:"(string) test",
property:"payload"}
});
}, done);
@@ -63,7 +63,7 @@ describe('debug node', function() {
n1.emit("input", {payload:"test"});
}, function(msg) {
JSON.parse(msg).should.eql({
topic:"debug",data:{id:"n1",msg:"test",property:"payload"}
topic:"debug",data:{id:"n1",msg:"(string) test",property:"payload"}
});
count++;
}, function() {
@@ -107,7 +107,7 @@ describe('debug node', function() {
n1.emit("input", {payload:"test", foo:"bar"});
}, function(msg) {
JSON.parse(msg).should.eql({
topic:"debug",data:{id:"n1",msg:"bar",property:"foo"}
topic:"debug",data:{id:"n1",msg:"(string) bar",property:"foo"}
});
}, done);
});
@@ -121,7 +121,7 @@ describe('debug node', function() {
n1.emit("input", {payload:"test", foo: {bar: "bar"}});
}, function(msg) {
JSON.parse(msg).should.eql({
topic:"debug",data:{id:"n1",msg:"bar",property:"foo.bar"}
topic:"debug",data:{id:"n1",msg:"(string) bar",property:"foo.bar"}
});
}, done);
});
@@ -232,7 +232,7 @@ describe('debug node', function() {
topic:"debug",
data:{
id:"n1",
msg: Array(1001).join("X")+' ....',
msg: "(string) "+Array(992).join("X")+' ....',
property:"payload"
}
});
@@ -273,7 +273,7 @@ describe('debug node', function() {
});
}, function(msg) {
JSON.parse(msg).should.eql({
topic:"debug",data:{id:"n1",msg:"message 2",property:"payload"}
topic:"debug",data:{id:"n1",msg:"(string) message 2",property:"payload"}
});
}, done);
});