@node-red/nodes 3.1.6 → 4.0.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/core/common/21-debug.js +2 -1
- package/core/common/lib/debug/debug-utils.js +2 -1
- package/core/function/15-change.js +4 -2
- package/core/network/22-websocket.html +206 -2
- package/core/network/22-websocket.js +37 -0
- package/core/network/31-tcpin.js +52 -16
- package/core/parsers/70-CSV.html +39 -4
- package/core/parsers/70-CSV.js +612 -260
- package/core/parsers/70-HTML.html +14 -1
- package/core/parsers/70-HTML.js +11 -0
- package/core/parsers/lib/csv/index.js +324 -0
- package/core/sequence/17-split.html +13 -5
- package/core/sequence/17-split.js +54 -34
- package/locales/de/messages.json +2 -1
- package/locales/en-US/messages.json +15 -5
- package/locales/en-US/network/31-tcpin.html +4 -0
- package/locales/en-US/parsers/70-CSV.html +4 -1
- package/locales/fr/messages.json +2 -1
- package/locales/ja/messages.json +2 -1
- package/locales/ko/messages.json +2 -1
- package/locales/pt-BR/messages.json +2 -1
- package/locales/ru/messages.json +2 -1
- package/locales/zh-CN/messages.json +2 -1
- package/locales/zh-TW/messages.json +2 -1
- package/package.json +1 -1
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
<option value="html" data-i18n="html.output.html"></option>
|
|
15
15
|
<option value="text" data-i18n="html.output.text"></option>
|
|
16
16
|
<option value="attr" data-i18n="html.output.attr"></option>
|
|
17
|
+
<option value="compl" data-i18n="html.output.compl"></option>
|
|
17
18
|
<!-- <option value="val">return the value from a form element</option> -->
|
|
18
19
|
</select>
|
|
19
20
|
</div>
|
|
@@ -28,6 +29,10 @@
|
|
|
28
29
|
<label for="node-input-outproperty"> </label>
|
|
29
30
|
<span data-i18n="html.label.in" style="padding-left:8px; padding-right:2px; vertical-align:-1px;"></span> <input type="text" id="node-input-outproperty" style="width:64%">
|
|
30
31
|
</div>
|
|
32
|
+
<div id='html-prefix-row' class="form-row" style="display: none;">
|
|
33
|
+
<label for="node-input-chr" style="width: 230px;"><i class="fa fa-tag"></i> <span data-i18n="html.label.prefix"></span></label>
|
|
34
|
+
<input type="text" id="node-input-chr" style="text-align:center; width: 40px;" placeholder="_">
|
|
35
|
+
</div>
|
|
31
36
|
<br/>
|
|
32
37
|
<div class="form-row">
|
|
33
38
|
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label>
|
|
@@ -45,7 +50,8 @@
|
|
|
45
50
|
outproperty: {value:"payload", validate: RED.validators.typedInput({ type: 'msg', allowUndefined: true }) },
|
|
46
51
|
tag: {value:""},
|
|
47
52
|
ret: {value:"html"},
|
|
48
|
-
as: {value:"single"}
|
|
53
|
+
as: {value:"single"},
|
|
54
|
+
chr: { value: "_" }
|
|
49
55
|
},
|
|
50
56
|
inputs:1,
|
|
51
57
|
outputs:1,
|
|
@@ -59,6 +65,13 @@
|
|
|
59
65
|
oneditprepare: function() {
|
|
60
66
|
$("#node-input-property").typedInput({default:'msg',types:['msg']});
|
|
61
67
|
$("#node-input-outproperty").typedInput({default:'msg',types:['msg']});
|
|
68
|
+
$('#node-input-ret').on( 'change', () => {
|
|
69
|
+
if ( $('#node-input-ret').val() == "compl" ) {
|
|
70
|
+
$('#html-prefix-row').show()
|
|
71
|
+
} else {
|
|
72
|
+
$('#html-prefix-row').hide()
|
|
73
|
+
}
|
|
74
|
+
});
|
|
62
75
|
}
|
|
63
76
|
});
|
|
64
77
|
</script>
|
package/core/parsers/70-HTML.js
CHANGED
|
@@ -25,6 +25,7 @@ module.exports = function(RED) {
|
|
|
25
25
|
this.tag = n.tag;
|
|
26
26
|
this.ret = n.ret || "html";
|
|
27
27
|
this.as = n.as || "single";
|
|
28
|
+
this.chr = n.chr || "_";
|
|
28
29
|
var node = this;
|
|
29
30
|
this.on("input", function(msg,send,done) {
|
|
30
31
|
var value = RED.util.getMessageProperty(msg,node.property);
|
|
@@ -47,6 +48,11 @@ module.exports = function(RED) {
|
|
|
47
48
|
if (node.ret === "attr") {
|
|
48
49
|
pay2 = Object.assign({},this.attribs);
|
|
49
50
|
}
|
|
51
|
+
if (node.ret === "compl") {
|
|
52
|
+
var bse = {}
|
|
53
|
+
bse[node.chr] = $(this).html().trim()
|
|
54
|
+
pay2 = Object.assign(bse, this.attribs);
|
|
55
|
+
}
|
|
50
56
|
//if (node.ret === "val") { pay2 = $(this).val(); }
|
|
51
57
|
/* istanbul ignore else */
|
|
52
58
|
if (pay2) {
|
|
@@ -69,6 +75,11 @@ module.exports = function(RED) {
|
|
|
69
75
|
var attribs = Object.assign({},this.attribs);
|
|
70
76
|
pay.push( attribs );
|
|
71
77
|
}
|
|
78
|
+
if (node.ret === "compl") {
|
|
79
|
+
var bse = {}
|
|
80
|
+
bse[node.chr] = $(this).html().trim()
|
|
81
|
+
pay.push( Object.assign(bse, this.attribs) )
|
|
82
|
+
}
|
|
72
83
|
//if (node.ret === "val") { pay.push( $(this).val() ); }
|
|
73
84
|
}
|
|
74
85
|
index++;
|
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
|
|
2
|
+
/**
|
|
3
|
+
* @typedef {Object} CSVParseOptions
|
|
4
|
+
* @property {number} [cursor=0] - an index into the CSV to start parsing from
|
|
5
|
+
* @property {string} [separator=','] - the separator character
|
|
6
|
+
* @property {string} [quote='"'] - the quote character
|
|
7
|
+
* @property {boolean} [headersOnly=false] - only parse the headers and return them
|
|
8
|
+
* @property {string[]} [headers=[]] - an array of headers to use instead of the first row of the CSV data
|
|
9
|
+
* @property {boolean} [dataHasHeaderRow=true] - whether the CSV data to parse has a header row
|
|
10
|
+
* @property {boolean} [outputHeader=true] - whether the output data should include a header row (only applies to array output)
|
|
11
|
+
* @property {boolean} [parseNumeric=false] - parse numeric values into numbers
|
|
12
|
+
* @property {boolean} [includeNullValues=false] - include null values in the output
|
|
13
|
+
* @property {boolean} [includeEmptyStrings=true] - include empty strings in the output
|
|
14
|
+
* @property {string} [outputStyle='object'] - output an array of arrays or an array of objects
|
|
15
|
+
* @property {boolean} [strict=false] - throw an error if the CSV is malformed
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Parses a CSV string into an array of arrays or an array of objects.
|
|
20
|
+
*
|
|
21
|
+
* NOTES:
|
|
22
|
+
* * Deviations from the RFC4180 spec (for the sake of user fiendliness, system implementations and flexibility), this parser will:
|
|
23
|
+
* * accept any separator character, not just `,`
|
|
24
|
+
* * accept any quote character, not just `"`
|
|
25
|
+
* * parse `\r`, `\n` or `\r\n` as line endings (RRFC4180 2.1 states lines are separated by CRLF)
|
|
26
|
+
* * Only single character `quote` is supported
|
|
27
|
+
* * `quote` is `"` by default
|
|
28
|
+
* * Any cell that contains a `quote` or `separator` will be quoted
|
|
29
|
+
* * Any `quote` characters inside a cell will be escaped as per RFC 4180 2.6
|
|
30
|
+
* * Only single character `separator` is supported
|
|
31
|
+
* * Only `array` and `object` output styles are supported
|
|
32
|
+
* * `array` output style is an array of arrays [[],[],[]]
|
|
33
|
+
* * `object` output style is an array of objects [{},{},{}]
|
|
34
|
+
* * Only `headers` or `dataHasHeaderRow` are supported, not both
|
|
35
|
+
* @param {string} csvIn - the CSV string to parse
|
|
36
|
+
* @param {CSVParseOptions} parseOptions - options
|
|
37
|
+
* @throws {Error}
|
|
38
|
+
*/
|
|
39
|
+
function parse(csvIn, parseOptions) {
|
|
40
|
+
/* Normalise options */
|
|
41
|
+
parseOptions = parseOptions || {};
|
|
42
|
+
const separator = parseOptions.separator ?? ',';
|
|
43
|
+
const quote = parseOptions.quote ?? '"';
|
|
44
|
+
const headersOnly = parseOptions.headersOnly ?? false;
|
|
45
|
+
const headers = Array.isArray(parseOptions.headers) ? parseOptions.headers : []
|
|
46
|
+
const dataHasHeaderRow = parseOptions.dataHasHeaderRow ?? true;
|
|
47
|
+
const outputHeader = parseOptions.outputHeader ?? true;
|
|
48
|
+
const parseNumeric = parseOptions.parseNumeric ?? false;
|
|
49
|
+
const includeNullValues = parseOptions.includeNullValues ?? false;
|
|
50
|
+
const includeEmptyStrings = parseOptions.includeEmptyStrings ?? true;
|
|
51
|
+
const outputStyle = ['array', 'object'].includes(parseOptions.outputStyle) ? parseOptions.outputStyle : 'object'; // 'array [[],[],[]]' or 'object [{},{},{}]
|
|
52
|
+
const strict = parseOptions.strict ?? false
|
|
53
|
+
|
|
54
|
+
/* Local variables */
|
|
55
|
+
const cursorMax = csvIn.length;
|
|
56
|
+
const ouputArrays = outputStyle === 'array';
|
|
57
|
+
const headersSupplied = headers.length > 0
|
|
58
|
+
// The original regex was an "is-a-number" positive logic test. /^ *[-]?(?!E)(?!0\d)\d*\.?\d*(E-?\+?)?\d+ *$/i;
|
|
59
|
+
// Below, is less strict and inverted logic but coupled with +cast it is 13%+ faster than original regex+parsefloat
|
|
60
|
+
// and has the benefit of understanding hexadecimals, binary and octal numbers.
|
|
61
|
+
const skipNumberConversion = /^ *(\+|-0\d|0\d)/
|
|
62
|
+
const cellBuilder = []
|
|
63
|
+
let rowBuilder = []
|
|
64
|
+
let cursor = typeof parseOptions.cursor === 'number' ? parseOptions.cursor : 0;
|
|
65
|
+
let newCell = true, inQuote = false, closed = false, output = [];
|
|
66
|
+
|
|
67
|
+
/* inline helper functions */
|
|
68
|
+
const finaliseCell = () => {
|
|
69
|
+
let cell = cellBuilder.join('')
|
|
70
|
+
cellBuilder.length = 0
|
|
71
|
+
// push the cell:
|
|
72
|
+
// NOTE: if cell is empty but newCell==true, then this cell had zero chars - push `null`
|
|
73
|
+
// otherwise push empty string
|
|
74
|
+
return rowBuilder.push(cell || (newCell ? null : ''))
|
|
75
|
+
}
|
|
76
|
+
const finaliseRow = () => {
|
|
77
|
+
if (cellBuilder.length) {
|
|
78
|
+
finaliseCell()
|
|
79
|
+
}
|
|
80
|
+
if (rowBuilder.length) {
|
|
81
|
+
output.push(rowBuilder)
|
|
82
|
+
rowBuilder = []
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/* Main parsing loop */
|
|
87
|
+
while (cursor < cursorMax) {
|
|
88
|
+
const char = csvIn[cursor]
|
|
89
|
+
if (inQuote) {
|
|
90
|
+
if (char === quote && csvIn[cursor + 1] === quote) {
|
|
91
|
+
cellBuilder.push(quote)
|
|
92
|
+
cursor += 2;
|
|
93
|
+
newCell = false;
|
|
94
|
+
closed = false;
|
|
95
|
+
} else if (char === quote) {
|
|
96
|
+
inQuote = false;
|
|
97
|
+
cursor += 1;
|
|
98
|
+
newCell = false;
|
|
99
|
+
closed = true;
|
|
100
|
+
} else {
|
|
101
|
+
cellBuilder.push(char)
|
|
102
|
+
newCell = false;
|
|
103
|
+
closed = false;
|
|
104
|
+
cursor++;
|
|
105
|
+
}
|
|
106
|
+
} else {
|
|
107
|
+
if (char === separator) {
|
|
108
|
+
finaliseCell()
|
|
109
|
+
cursor += 1;
|
|
110
|
+
newCell = true;
|
|
111
|
+
closed = false;
|
|
112
|
+
} else if (char === quote) {
|
|
113
|
+
if (newCell) {
|
|
114
|
+
inQuote = true;
|
|
115
|
+
cursor += 1;
|
|
116
|
+
newCell = false;
|
|
117
|
+
closed = false;
|
|
118
|
+
}
|
|
119
|
+
else if (strict) {
|
|
120
|
+
throw new UnquotedQuoteError(cursor)
|
|
121
|
+
} else {
|
|
122
|
+
// not strict, keep 1 quote if the next char is not a cell/record separator
|
|
123
|
+
cursor++
|
|
124
|
+
if (csvIn[cursor] && csvIn[cursor] !== '\n' && csvIn[cursor] !== '\r' && csvIn[cursor] !== separator) {
|
|
125
|
+
cellBuilder.push(char)
|
|
126
|
+
if (csvIn[cursor] === quote) {
|
|
127
|
+
cursor++ // skip the next quote
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
} else {
|
|
132
|
+
if (char === '\n' || char === '\r') {
|
|
133
|
+
finaliseRow()
|
|
134
|
+
if (csvIn[cursor + 1] === '\n') {
|
|
135
|
+
cursor += 2;
|
|
136
|
+
} else {
|
|
137
|
+
cursor++
|
|
138
|
+
}
|
|
139
|
+
newCell = true;
|
|
140
|
+
closed = false;
|
|
141
|
+
if (headersOnly) {
|
|
142
|
+
break
|
|
143
|
+
}
|
|
144
|
+
} else {
|
|
145
|
+
if (closed) {
|
|
146
|
+
if (strict) {
|
|
147
|
+
throw new DataAfterCloseError(cursor)
|
|
148
|
+
} else {
|
|
149
|
+
cursor--; // move back to grab the previously discarded char
|
|
150
|
+
closed = false
|
|
151
|
+
}
|
|
152
|
+
} else {
|
|
153
|
+
cellBuilder.push(char)
|
|
154
|
+
newCell = false;
|
|
155
|
+
cursor++;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
if (strict && inQuote) {
|
|
162
|
+
throw new ParseError(`Missing quote, unclosed cell`, cursor)
|
|
163
|
+
}
|
|
164
|
+
// finalise the last cell/row
|
|
165
|
+
finaliseRow()
|
|
166
|
+
let firstRowIsHeader = false
|
|
167
|
+
// if no headers supplied, generate them
|
|
168
|
+
if (output.length >= 1) {
|
|
169
|
+
if (headersSupplied) {
|
|
170
|
+
// headers already supplied
|
|
171
|
+
} else if (dataHasHeaderRow) {
|
|
172
|
+
// take the first row as the headers
|
|
173
|
+
headers.push(...output[0])
|
|
174
|
+
firstRowIsHeader = true
|
|
175
|
+
} else {
|
|
176
|
+
// generate headers col1, col2, col3, etc
|
|
177
|
+
for (let i = 0; i < output[0].length; i++) {
|
|
178
|
+
headers.push("col" + (i + 1))
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
const finalResult = {
|
|
184
|
+
/** @type {String[]} headers as an array of string */
|
|
185
|
+
headers: headers,
|
|
186
|
+
/** @type {String} headers as a comma-separated string */
|
|
187
|
+
header: null,
|
|
188
|
+
/** @type {Any[]} Result Data (may include header row: check `firstRowIsHeader` flag) */
|
|
189
|
+
data: [],
|
|
190
|
+
/** @type {Boolean|undefined} flag to indicate if the first row is a header row (only applies when `outputStyle` is 'array') */
|
|
191
|
+
firstRowIsHeader: undefined,
|
|
192
|
+
/** @type {'array'|'object'} flag to indicate the output style */
|
|
193
|
+
outputStyle: outputStyle,
|
|
194
|
+
/** @type {Number} The current cursor position */
|
|
195
|
+
cursor: cursor,
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
const quotedHeaders = []
|
|
199
|
+
for (let i = 0; i < headers.length; i++) {
|
|
200
|
+
if (!headers[i]) {
|
|
201
|
+
continue
|
|
202
|
+
}
|
|
203
|
+
quotedHeaders.push(quoteCell(headers[i], { quote, separator: ',' }))
|
|
204
|
+
}
|
|
205
|
+
finalResult.header = quotedHeaders.join(',') // always quote headers and join with comma
|
|
206
|
+
|
|
207
|
+
// output is an array of arrays [[],[],[]]
|
|
208
|
+
if (ouputArrays || headersOnly) {
|
|
209
|
+
if (!firstRowIsHeader && !headersOnly && outputHeader && headers.length > 0) {
|
|
210
|
+
if (output.length > 0) {
|
|
211
|
+
output.unshift(headers)
|
|
212
|
+
} else {
|
|
213
|
+
output = [headers]
|
|
214
|
+
}
|
|
215
|
+
firstRowIsHeader = true
|
|
216
|
+
}
|
|
217
|
+
if (headersOnly) {
|
|
218
|
+
delete finalResult.firstRowIsHeader
|
|
219
|
+
return finalResult
|
|
220
|
+
}
|
|
221
|
+
finalResult.firstRowIsHeader = firstRowIsHeader
|
|
222
|
+
finalResult.data = (firstRowIsHeader && !outputHeader) ? output.slice(1) : output
|
|
223
|
+
return finalResult
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// output is an array of objects [{},{},{}]
|
|
227
|
+
const outputObjects = []
|
|
228
|
+
let i = firstRowIsHeader ? 1 : 0
|
|
229
|
+
for (; i < output.length; i++) {
|
|
230
|
+
const rowObject = {}
|
|
231
|
+
let isEmpty = true
|
|
232
|
+
for (let j = 0; j < headers.length; j++) {
|
|
233
|
+
if (!headers[j]) {
|
|
234
|
+
continue
|
|
235
|
+
}
|
|
236
|
+
let v = output[i][j] === undefined ? null : output[i][j]
|
|
237
|
+
if (v === null && !includeNullValues) {
|
|
238
|
+
continue
|
|
239
|
+
} else if (v === "" && !includeEmptyStrings) {
|
|
240
|
+
continue
|
|
241
|
+
} else if (parseNumeric === true && v && !skipNumberConversion.test(v)) {
|
|
242
|
+
const vTemp = +v
|
|
243
|
+
const isNumber = !isNaN(vTemp)
|
|
244
|
+
if(isNumber) {
|
|
245
|
+
v = vTemp
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
rowObject[headers[j]] = v
|
|
249
|
+
isEmpty = false
|
|
250
|
+
}
|
|
251
|
+
// determine if this row is empty
|
|
252
|
+
if (!isEmpty) {
|
|
253
|
+
outputObjects.push(rowObject)
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
finalResult.data = outputObjects
|
|
257
|
+
delete finalResult.firstRowIsHeader
|
|
258
|
+
return finalResult
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* Quotes a cell in a CSV string if necessary. Addiionally, any double quotes inside the cell will be escaped as per RFC 4180 2.6 (https://datatracker.ietf.org/doc/html/rfc4180#section-2).
|
|
263
|
+
* @param {string} cell - the string to quote
|
|
264
|
+
* @param {*} options - options
|
|
265
|
+
* @param {string} [options.quote='"'] - the quote character
|
|
266
|
+
* @param {string} [options.separator=','] - the separator character
|
|
267
|
+
* @param {string[]} [options.quoteables] - an array of characters that, when encountered, will trigger the application of outer quotes
|
|
268
|
+
* @returns
|
|
269
|
+
*/
|
|
270
|
+
function quoteCell(cell, { quote = '"', separator = ",", quoteables } = {
|
|
271
|
+
quote: '"',
|
|
272
|
+
separator: ",",
|
|
273
|
+
quoteables: [quote, separator, '\r', '\n']
|
|
274
|
+
}) {
|
|
275
|
+
quoteables = quoteables || [quote, separator, '\r', '\n'];
|
|
276
|
+
|
|
277
|
+
let doubleUp = false;
|
|
278
|
+
if (cell.indexOf(quote) !== -1) { // add double quotes if any quotes
|
|
279
|
+
doubleUp = true;
|
|
280
|
+
}
|
|
281
|
+
const quoteChar = quoteables.some(q => cell.includes(q)) ? quote : '';
|
|
282
|
+
return quoteChar + (doubleUp ? cell.replace(/"/g, '""') : cell) + quoteChar;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
// #region Custom Error Classes
|
|
286
|
+
class ParseError extends Error {
|
|
287
|
+
/**
|
|
288
|
+
* @param {string} message - the error message
|
|
289
|
+
* @param {number} cursor - the cursor index where the error occurred
|
|
290
|
+
*/
|
|
291
|
+
constructor(message, cursor) {
|
|
292
|
+
super(message)
|
|
293
|
+
this.name = 'ParseError'
|
|
294
|
+
this.cursor = cursor
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
class UnquotedQuoteError extends ParseError {
|
|
299
|
+
/**
|
|
300
|
+
* @param {number} cursor - the cursor index where the error occurred
|
|
301
|
+
*/
|
|
302
|
+
constructor(cursor) {
|
|
303
|
+
super('Quote found in the middle of an unquoted field', cursor)
|
|
304
|
+
this.name = 'UnquotedQuoteError'
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
class DataAfterCloseError extends ParseError {
|
|
309
|
+
/**
|
|
310
|
+
* @param {number} cursor - the cursor index where the error occurred
|
|
311
|
+
*/
|
|
312
|
+
constructor(cursor) {
|
|
313
|
+
super('Data found after closing quote', cursor)
|
|
314
|
+
this.name = 'DataAfterCloseError'
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
// #endregion
|
|
319
|
+
|
|
320
|
+
exports.parse = parse
|
|
321
|
+
exports.quoteCell = quoteCell
|
|
322
|
+
exports.ParseError = ParseError
|
|
323
|
+
exports.UnquotedQuoteError = UnquotedQuoteError
|
|
324
|
+
exports.DataAfterCloseError = DataAfterCloseError
|
|
@@ -15,7 +15,11 @@
|
|
|
15
15
|
-->
|
|
16
16
|
|
|
17
17
|
<script type="text/html" data-template-name="split">
|
|
18
|
-
<div class="form-row"><span data-i18n="[html]split.intro"></span></div>
|
|
18
|
+
<!-- <div class="form-row"><span data-i18n="[html]split.intro"></span></div> -->
|
|
19
|
+
<div class="form-row">
|
|
20
|
+
<label for="node-input-property"><i class="fa fa-forward"></i> <span data-i18n="split.split"></span></label>
|
|
21
|
+
<input type="text" id="node-input-property" style="width:70%;"/>
|
|
22
|
+
</div>
|
|
19
23
|
<div class="form-row"><span data-i18n="[html]split.strBuff"></span></div>
|
|
20
24
|
<div class="form-row">
|
|
21
25
|
<label for="node-input-splt" style="padding-left:10px; margin-right:-10px;" data-i18n="split.splitUsing"></label>
|
|
@@ -39,10 +43,9 @@
|
|
|
39
43
|
<label for="node-input-addname-cb" style="width:auto;" data-i18n="split.addname"></label>
|
|
40
44
|
<input type="text" id="node-input-addname" style="width:70%">
|
|
41
45
|
</div>
|
|
42
|
-
<hr/>
|
|
43
46
|
<div class="form-row">
|
|
44
|
-
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label>
|
|
45
|
-
<input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name">
|
|
47
|
+
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="node-red:common.label.name"></span></label>
|
|
48
|
+
<input type="text" id="node-input-name" data-i18n="[placeholder]node-red:common.label.name">
|
|
46
49
|
</div>
|
|
47
50
|
</script>
|
|
48
51
|
|
|
@@ -57,7 +60,8 @@
|
|
|
57
60
|
arraySplt: {value:1},
|
|
58
61
|
arraySpltType: {value:"len"},
|
|
59
62
|
stream: {value:false},
|
|
60
|
-
addname: {value:"", validate: RED.validators.typedInput({ type: 'msg', allowBlank: true })}
|
|
63
|
+
addname: {value:"", validate: RED.validators.typedInput({ type: 'msg', allowBlank: true })},
|
|
64
|
+
property: {value:"payload",required:true}
|
|
61
65
|
},
|
|
62
66
|
inputs:1,
|
|
63
67
|
outputs:1,
|
|
@@ -69,6 +73,10 @@
|
|
|
69
73
|
return this.name?"node_label_italic":"";
|
|
70
74
|
},
|
|
71
75
|
oneditprepare: function() {
|
|
76
|
+
if (this.property === undefined) {
|
|
77
|
+
$("#node-input-property").val("payload");
|
|
78
|
+
}
|
|
79
|
+
$("#node-input-property").typedInput({default:'msg',types:['msg']});
|
|
72
80
|
$("#node-input-splt").typedInput({
|
|
73
81
|
default: 'str',
|
|
74
82
|
typeField: $("#node-input-spltType"),
|