diff --git a/editor/js/ui/clipboard.js b/editor/js/ui/clipboard.js index 0d7519e10..e4350a464 100644 --- a/editor/js/ui/clipboard.js +++ b/editor/js/ui/clipboard.js @@ -276,9 +276,20 @@ RED.clipboard = (function() { if (typeof value !== "string" ) { value = JSON.stringify(value, function(key,value) { if (value !== null && typeof value === 'object') { - if (value.__encoded__ && value.hasOwnProperty('data') && value.hasOwnProperty('length')) { - truncated = value.data.length !== value.length; - return value.data; + if (value.__encoded__) { + if (value.hasOwnProperty('data') && value.hasOwnProperty('length')) { + truncated = value.data.length !== value.length; + return value.data; + } + if (value.type === 'function' || value.type === 'internal') { + return undefined + } + if (value.type === 'number') { + // Handle NaN and Infinity - they are not permitted + // in JSON. We can either substitute with a String + // representation or null + return null; + } } } return value; diff --git a/editor/js/ui/utils.js b/editor/js/ui/utils.js index 4f84da8ba..e64a33996 100644 --- a/editor/js/ui/utils.js +++ b/editor/js/ui/utils.js @@ -36,6 +36,8 @@ RED.utils = (function() { result = $('').text('array['+value.length+']'); } else if (value.hasOwnProperty('type') && value.type === 'function') { result = $('').text('function'); + } else if (value.hasOwnProperty('type') && value.type === 'number') { + result = $('').text(value.data); } else { result = $('object'); } @@ -47,6 +49,8 @@ RED.utils = (function() { subvalue = sanitize(value); } result = $('').html('"'+formatString(subvalue)+'"'); + } else if (typeof value === 'number') { + result = $('').text(""+value); } else { result = $('').text(""+value); } @@ -300,6 +304,8 @@ RED.utils = (function() { } if (obj === null || obj === undefined) { $(''+obj+'').appendTo(entryObj); + } else if (obj.__encoded__ && obj.type === 'number') { + e = $('').text(obj.data).appendTo(entryObj); } else if (typeHint === "function" || (obj.__encoded__ && obj.type === 'function')) { e = $('').text("function").appendTo(entryObj); } else if (typeHint === "internal" || (obj.__encoded__ && obj.type === 'internal')) { @@ -799,6 +805,10 @@ RED.utils = (function() { function decodeObject(payload,format) { if ((format === 'number') && (payload === "NaN")) { payload = Number.NaN; + } else if ((format === 'number') && (payload === "Infinity")) { + payload = Infinity; + } else if ((format === 'number') && (payload === "-Infinity")) { + payload = -Infinity; } else if (format === 'Object' || /^array/.test(format) || format === 'boolean' || format === 'number' ) { payload = JSON.parse(payload); } else if (/error/i.test(format)) { diff --git a/red/runtime/util.js b/red/runtime/util.js index 022faa65d..1d49641df 100644 --- a/red/runtime/util.js +++ b/red/runtime/util.js @@ -469,6 +469,14 @@ function encodeObject(msg,opts) { __encoded__: true, type: "function" } + } else if (typeof value === 'number') { + if (isNaN(value) || value === Infinity || value === -Infinity) { + value = { + __encoded__: true, + type: "number", + data: value.toString() + } + } } else if (value && value.constructor) { if (value.type === "Buffer") { value.__encoded__ = true;