const StringFormatDefinition = { name: 'String Format', docs: 'https://docs.noodl.net/nodes/string-manipulation/string-format', category: 'String Manipulation', initialize() { const internal = this._internal; internal.format = ''; internal.cachedResult = ''; internal.resultDirty = false; internal.inputValues = {}; }, getInspectInfo() { return this.formatValue(); }, inputs: { format: { type: { name: 'string', multiline: true }, displayName: 'Format', set(value) { if (this._internal.format === value) return; this._internal.format = value; this._internal.resultDirty = true; this.scheduleFormat(); } } }, outputs: { formatted: { type: 'string', displayName: 'Formatted', get() { return this.formatValue(); } } }, methods: { formatValue() { var internal = this._internal; if (internal.resultDirty) { var formatted = internal.format; var matches = internal.format.match(/\{[A-Za-z0-9_]*\}/g); var inputs = []; if (matches) { inputs = matches.map(function (name) { return name.replace('{', '').replace('}', ''); }); } inputs.forEach(function (name) { var v = internal.inputValues[name]; formatted = formatted.replace('{' + name + '}', v !== undefined ? v : ''); }); internal.cachedResult = formatted; internal.resultDirty = false; } return internal.cachedResult; }, registerInputIfNeeded(name) { if (this.hasInput(name)) { return; } this.registerInput(name, { set: userInputSetter.bind(this, name) }); }, scheduleFormat() { if (this.formatScheduled) return; this.formatScheduled = true; this.scheduleAfterInputsHaveUpdated(() => { this.formatValue(); this.flagOutputDirty('formatted'); this.formatScheduled = false; }); } } }; function userInputSetter(name, value) { /* jshint validthis:true */ if (this._internal.inputValues[name] === value) return; this._internal.inputValues[name] = value; this._internal.resultDirty = true; this.scheduleFormat(); } function updatePorts(id, format, editorConnection) { var inputs = format.match(/\{[A-Za-z0-9_]*\}/g) || []; var portsNames = inputs.map(function (def) { return def.replace('{', '').replace('}', ''); }); var ports = portsNames //get unique names .filter(function (value, index, self) { return self.indexOf(value) === index; }) //and map names to ports .map(function (name) { return { name: name, type: 'string', plug: 'input' }; }); editorConnection.sendDynamicPorts(id, ports); } module.exports = { node: StringFormatDefinition, setup: function (context, graphModel) { if (!context.editorConnection || !context.editorConnection.isRunningLocally()) { return; } graphModel.on('nodeAdded.String Format', function (node) { if (node.parameters.format) { updatePorts(node.id, node.parameters.format, context.editorConnection); } node.on('parameterUpdated', function (event) { if (event.name === 'format') { updatePorts(node.id, node.parameters.format, context.editorConnection); } }); }); } };