From 309c490bbb8daa9dc2cfe78d264ff7351e8d6ce7 Mon Sep 17 00:00:00 2001 From: Mark Herwege Date: Tue, 30 Jul 2024 08:29:17 +0200 Subject: [PATCH 01/14] http block enhancement Signed-off-by: Mark Herwege --- .../assets/definitions/blockly/blocks-http.js | 257 ++++++++++++++---- 1 file changed, 205 insertions(+), 52 deletions(-) diff --git a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-http.js b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-http.js index 791a570169..1480c5611e 100644 --- a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-http.js +++ b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-http.js @@ -8,6 +8,7 @@ import { javascriptGenerator } from 'blockly/javascript.js' export default function (f7, isGraalJs) { const timeoutImage = 'data:image/png;base64,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' const headerImage = 'data:image/png;base64,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' + const queryImage = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABBCAYAAABhNaJ7AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAAFiUAABYlAUlSJPAAAAg3SURBVHhe5ZtZjFRFFIbpngFETRREQTSKAUHUaBQXEsVdIhj3JRojUXgwGvXBhQej+GDcjbsYfIAY4oIKKu6iMaKAiiIKiCzuuCtgQJBlBr+/+r/tHewZpvtWz/Tol5w+dU/VrTqn7l5V3en/TGNjY4+c01WFhg5AHY3sjOyN9EdWI12RzchGZDtkMbIM+RqZnc/nl6CrSlU6YPPmzb2R00kOQC7I5XK7hIwyoY5vUFOQT5DJdMh62WMStQNw+BhkDAEPtymAbQ3qEeQ75FPyG7F1Q/+CrsPWA9EZ0RMZiPQl71J0Ecop/0nkPjpiYTDWCjh3Dqf5l+gibL+FugjdC+nmoq2Gfbdhv4HI1ci7oVLD9gxkiIu2HzjRB/nUfsmxDchYktu7SDTc1nhEZ0+A5FRU3kXaFhofU3AjOCKucFbVoa273bTa/gs52VnVh8Z2p90PC80HB+5CdXZ2m0GbPZGn5IPAjymo6GdeE2hE1+TPbvA35AhntRv4cL78EaRnoro4Ky5UPrrQTGjoRZtrAvzZBfnc7sm/w50VByo813Wrcj3OahJ8e81uys+jbM4GFQ1znar0DptrElzM4eMb9nU1spuzKoMK9qSuVaoQbrO55sHvl+zzhzZVBhXNUy3oqTZ1GPBZN0T5Ptmm8mDHca5gnk0dClzfA99XO4YrbW4d7HOCd2xA+tnc4cD3kxzHeqSPzVuHwsmp3+SDpCNCDPc6lidsahkKXusdqv4t3hYQRw9krWMaZnNpKNOTQutduO3er6sMsVznmBbYVBoKXOWCr9oUDercvaGh4X5kOjIfWZ4SbU+nzE0q512iQUj6tP5esYEGakpDoUUqgb7QpihQ3wQCXJoKuCVRufu9azTw4WbH9qxNgeKIEBlDcrncbMosyufz+9qcCerUl6Ma3LVgKbIO+amQDOxlnWZuXV3dqU5nBl92I77lSuNTL2L8JWQkUGCie+hWmzLDkZyTOrKS6Rs3biwZFO1eQ/6Wl4aGwKJBG286xn8/3TD+6Mz9bMoE9ei0LwbD9k3OahbK6D6he0R6v1HOzgx1neEY37SpAIYDnPGxTZmgHgWSvuZbfSS9b/pMmO6szBBid8f5Jypc/sl4WvJ8nGOdCSofg0oGQtdx7V3j9Fbh2lxO+ee8KQapU5zOBPWuxLcP0Nuij5MtT2JH9CEuMEs6AgdZC91Uw82nDMZbJ5xnHYOXrIsdoLH40MOkF0lHoHhXp1M1qVEW7rAfC1uBKE8lE95w8SuMFegS0PRUL21gzDzhUOJ0/cq6XP6y1oHRQYrFR/qhzu7S6oBLCLw/hoVozeBkZcv37dety+V7axGcjQExarpN+lQOVld1QDKU3GAdlQqu/wAOrnUyOhxsTciK0AEJjdZRqfQOjo/bOimKl0MEFGfxYKc7QFPUmeG5/ZuTCS1/gjZPcUCTs0GTqrFQ8JsKyaYdoJthZjp37jzNyQTN/FaCHs8BzoYY96YEzWIVY013QExWWsv58I5RDhs2bNDERvHGx2X0hpPRUQckz9uYU0rpR1/Z3xb19fWXOClWljirMsEllePArEetyfMziY1F6H3QUZ631JV+le3OfaHV3/c6+vgx1JuqK8rreQJ1D3LyZepu1Juglp38KgvpKCPAPPomoNJvcsOb+wxOoydGXV3dgySL3xHI2EIyGkkHhMtUZ4ASP2gDos32Ekz687cbnTIO2wRf301Q4CrPAXiLzeLgCb6Nr/Q9ogWSe1I4QOqAVegPtAEHWmdG1y11T/RmgACHcYSncEnoc/cdyxzs7yEXUyS9lEZHf0UhGZVTrMN9JXwT0/sDcVbTy0vpca3sioZOfeq8geSWw2LNoTMy/eo7l066uUuXLu97u2KIrzdKAz8r8Gkn2cJjkI3FGL+jE/amM6LOretM4KgfSt26lucipT6OZHuXQM+inFaYqVzCwT5rprXmPtISxJgc/X93JoHfRwGNltxjU7tCwBpCLzWSXPGIMbHNcIwjbfoHjAc6M3wt1QL4ouGxaekOwKYnTNmw3wDHtwa1jc1NIfN1F7rcpppATw53RMVzBsT0gGNrvgPJHOlCM236T0A8OyEaCBWDbS4NBZeoFDr9OtqhIZZ7HNPzNjUPhUa58O9I2Utcaw1i0OxUgPShNrcMBcNqK/RWJzNqHWJ43rHcadPWofD+2skcaXOHgzguVQDoL1Dlfe2y0/XeeSUSRo07Evg8VP4L0mfaXB7s+KIrWIiq1uBJdPBVCz3CegD0LTZXBhVMc0Uv2FTT4OoO+LrMPj9tc2VQx2AqeUyVCdLPOKsmwcXe+Jg8xj+zuXKopD+yANFyuWT6XP/eqLnLAb+0YFo3O/n4LUpffnGgwreRhxDdC9SA/h4Tr4GM4M8RyCb7thjRv9PiQYVnI2HdEFrLaBIuCgXaEfy5xb4o+Edtjgt1d6fy07ypRsNyGkH6BVRfZ7UZtDsEmVXwIvihNQnVgfo1jKxFBelFVSciK9S4IP04UvX3BdoYgOgfaQHS85H2W85L42FRdQLbryJ6CYl2o6S+rsgIJCzhTWD7MhdpX3BETwv9hS3NKmw3ovUo7Ydu9Z80KVvvOo9HNJqcPtM2IbeTjPIHqVY71RpwTHdffUaP1PhiMBoc1soMjcVpFarm5/Rurjk/+aD/Df+B6B+jIyi7K7rJ4Cy22aiH8/n8pIIlDlE7IAFnNeFyLElNi52FDCWgstpif03YvIJoldgCAp8he2yq0gFbQjC6ie5PUsPdhyFH0h/6K066fa0HUMB6g/uW/J+QqqxZSKD9+jbpgFqEy3VQp06dRv8NpmqfcgBaOQEAAAAASUVORK5CYII=' const unavailMsg = 'HTTP blocks aren\'t supported in "application/javascript;version=ECMAScript-5.1"' /* @@ -34,7 +35,6 @@ export default function (f7, isGraalJs) { ], this.handleRequestTypeSelection.bind(this)), 'requestType') .appendField('to') - this.updateShape(this.hasTimeout, true, this.hasHeader) this.handleRequestTypeSelection(this.getFieldValue('requestType')) this.setInputsInline(false) @@ -46,103 +46,214 @@ export default function (f7, isGraalJs) { handleRequestTypeSelection: function (requestType) { if (this.requestType !== requestType) { this.requestType = requestType - const getOrDelete = (requestType === 'HttpGetRequest' || requestType === 'HttpDeleteRequest') - if (!getOrDelete) { - if (!this.getInput('payload')) { - this.appendValueInput('payload') - .setCheck(null) - .appendField('with Payload') - .appendField(new Blockly.FieldDropdown([ - ['application/json', 'application/json'], - ['none', 'none'], - ['application/javascript', 'application/javascript'], - ['application/xhtml+xml ', 'application/xhtml+xml '], - ['application/xml ', 'application/xml '], - ['application/x-www-form-urlencoded ', 'application/x-www-form-urlencoded '], - ['text/html', 'text/html'], - ['text/javascript', 'text/javascript'], - ['text/plain', 'text/plain'], - ['text/xml', 'text/xml']]), 'contentType') + const isGet = requestType === 'HttpGetRequest' + const isPost = requestType === 'HttpPostRequest' + const isPut = requestType === 'HttpPutRequest' + const isDelete = requestType === 'HttpDeleteRequest' + if (isPost || isPut) { + this.hasPayload = true + } else { + this.hasPayload = false + this.hasPayloadDict = false + } + + const urlInput = this.getInput('url') + if (isGet || isDelete) { + if (urlInput.fieldRow[2].name !== 'imgQuery') { + const imageQueryField = new Blockly.FieldImage(queryImage, 15, 15, undefined, this.onClickQuery) + imageQueryField.setTooltip('Add query to the request.') + urlInput.insertFieldAt(2, imageQueryField, 'imgQuery') } } else { - if (this.getInput('payload')) { - this.removeInput('payload') + if (urlInput.fieldRow[2].name === 'imgQuery') { + urlInput.removeField('imgQuery') } + this.hasQuery = false } - this.updateShape(this.hasTimeout, true, this.hasHeader) + + if (isPost || isPut) { + this.handleContentTypeSelection(this.getFieldValue('contentType')) + } else { + this.updateShape(this.hasTimeout, this.hasHeader, this.hasQuery, true) + } + } + }, + handleContentTypeSelection: function (contentType) { + if (this.contentType !== contentType) { + this.contentType = contentType + this.hasPayloadDict = (contentType === 'application/x-www-form-urlencoded') + this.updateShape(this.hasTimeout, this.hasHeader, this.hasQuery, true) } }, - updateShape: function (hasTimeout, addNumBlock, hasHeader) { + updateShape: function (hasTimeout, hasHeader, hasQuery, addBlocks) { this.hasTimeout = hasTimeout this.hasHeader = hasHeader + this.hasQuery = hasQuery + if (hasTimeout) { if (!this.getInput('timeoutInput')) { const timeoutInput = this.appendValueInput('timeoutInput') .setCheck('Number') .appendField('with Timeout (ms)') - const blockAfter = (this.getInput('requestHeader')) ? 'requestHeader' : (this.getInput('payload')) ? 'payload' : undefined - + const blockAfter = this.getInput('requestHeader') ? 'requestHeader' : (this.getInput('payload') ? 'payload' : (this.getInput('query') ? 'query' : undefined)) if (blockAfter) { this.moveInputBefore('timeoutInput', blockAfter) } - if (addNumBlock) { + if (addBlocks) { const parentConnection = timeoutInput.connection const mathNumberBlock = this.workspace.newBlock('math_number') mathNumberBlock.setFieldValue('3000', 'NUM') - mathNumberBlock.initSvg() - mathNumberBlock.render() parentConnection.connect(mathNumberBlock.outputConnection) + mathNumberBlock.initSvg() + if (this.rendered) { + mathNumberBlock.render() + } } } - } else { - if (this.getInput('timeoutInput')) { - const parentConnection = this.getInput('timeoutInput').connection - const targetBlock = parentConnection.targetBlock() - if (targetBlock) { - targetBlock.unplug(true) - targetBlock.dispose(true) - } - this.removeInput('timeoutInput') + } else if (this.getInput('timeoutInput')) { + const parentConnection = this.getInput('timeoutInput').connection + const targetBlock = parentConnection.targetBlock() + if (targetBlock) { + targetBlock.unplug() + targetBlock.dispose() } + this.removeInput('timeoutInput') } + if (hasHeader) { if (!this.getInput('requestHeader')) { const headerInput = this.appendValueInput('requestHeader') .setCheck('Dictionary') .appendField('with Headers') - const blockAfter = (this.getInput('payload')) ? 'payload' : undefined - + const blockAfter = this.getInput('payload') ? 'payload' : (this.getInput('query') ? 'query' : undefined) if (blockAfter) { this.moveInputBefore('requestHeader', blockAfter) } + if (addBlocks) { + this.addDict(headerInput, 'header') + } } - } else { - if (this.getInput('requestHeader')) { - this.removeInput('requestHeader') + } else if (this.getInput('requestHeader')) { + const parentConnection = this.getInput('requestHeader').connection + const targetBlock = parentConnection.targetBlock() + this.disposeIfEmpty(targetBlock) + this.removeInput('requestHeader') + } + + if (hasQuery) { + if (!this.getInput('query')) { + const queryInput = this.appendValueInput('query') + .setCheck('Dictionary') + .appendField('with Query') + if (addBlocks) { + this.addDict(queryInput, 'param') + } + } + } else if (this.getInput('query')) { + const parentConnection = this.getInput('query').connection + const targetBlock = parentConnection.targetBlock() + this.disposeIfEmpty(targetBlock) + this.removeInput('query') + } + + let payloadInput = this.getInput('payload') + const parentConnection = payloadInput?.connection + const targetBlock = parentConnection?.targetBlock() + if (this.hasPayload) { + if (!payloadInput) { + payloadInput = this.appendValueInput('payload') + .appendField('with Payload') + .appendField(new Blockly.FieldDropdown([ + ['application/json', 'application/json'], + ['none', 'none'], + ['application/javascript', 'application/javascript'], + ['application/xhtml+xml', 'application/xhtml+xml'], + ['application/xml', 'application/xml'], + ['application/x-www-form-urlencoded', 'application/x-www-form-urlencoded'], + ['text/html', 'text/html'], + ['text/javascript', 'text/javascript'], + ['text/plain', 'text/plain'], + ['text/xml', 'text/xml']], this.handleContentTypeSelection.bind(this)), 'contentType') + .setShadowDom(Blockly.utils.xml.textToDom('')) + .setCheck(['String', 'Dictionary']) + if (addBlocks && this.hasPayloadDict) { + this.addDict(payloadInput, 'param') + } + } else if (this.hasPayloadDict) { + if (targetBlock && (targetBlock.type !== 'dicts_create_with') && !targetBlock.isShadow()) { + targetBlock.unplug() + targetBlock.moveBy(10, 10) + } + if (addBlocks && (!payloadInput.connection?.targetBlock() || payloadInput.connection.targetBlock().isShadow())) { + this.addDict(payloadInput, 'param') + } + } else if (targetBlock && (targetBlock.type === 'dicts_create_with')) { + this.disposeIfEmpty(targetBlock) + } + } else if (payloadInput) { + this.disposeIfEmpty(targetBlock) + this.removeInput('payload') + } + }, + addDict (input, param) { + const parentConnection = input.connection + const dictBlock = this.workspace.newBlock('dicts_create_with') + dictBlock.itemCount_ = 2 + dictBlock.updateShape_() + for (let i = 0; i < dictBlock.itemCount_; i++) { + dictBlock.setFieldValue(`${param}${i}`, 'KEY' + i) + dictBlock.getInput('ADD' + i).setShadowDom(Blockly.utils.xml.textToDom('')) + } + parentConnection.connect(dictBlock.outputConnection) + dictBlock.initSvg() + if (this.rendered) { + dictBlock.render() + } + }, + disposeIfEmpty (targetBlock) { + if (targetBlock) { + targetBlock.unplug() + targetBlock.moveBy(10, 10) + let isEmpty = true + if (!targetBlock.isShadow() && !targetBlock.getChildren().length) { + isEmpty = false } + let i = 0 + while (isEmpty && targetBlock.getInput('ADD' + i)) { + isEmpty = targetBlock.getInput('ADD' + i).connection.targetBlock().isShadow() + i++ + } + if (isEmpty) targetBlock.dispose() } }, onClickTimeout () { let block = this.getSourceBlock() block.hasTimeout = !block.hasTimeout - block.updateShape(block.hasTimeout, true, block.hasHeader) + block.updateShape(block.hasTimeout, block.hasHeader, block.hasQuery, true) }, onClickHeader () { let block = this.getSourceBlock() block.hasHeader = !block.hasHeader - block.updateShape(block.hasTimeout, true, block.hasHeader) + block.updateShape(block.hasTimeout, block.hasHeader, block.hasQuery, true) + }, + onClickQuery () { + let block = this.getSourceBlock() + block.hasQuery = !block.hasQuery + block.updateShape(block.hasTimeout, block.hasHeader, block.hasQuery, true) }, mutationToDom: function () { let container = Blockly.utils.xml.createElement('mutation') container.setAttribute('hasTimeout', this.hasTimeout) container.setAttribute('hasHeader', this.hasHeader) + container.setAttribute('hasQuery', this.hasQuery) return container }, domToMutation: function (xmlElement) { let hasTimeout = xmlElement.getAttribute('hasTimeout') === 'true' let hasHeader = xmlElement.getAttribute('hasHeader') === 'true' - this.updateShape(hasTimeout, false, hasHeader) + let hasQuery = xmlElement.getAttribute('hasQuery') === 'true' + this.updateShape(hasTimeout, hasHeader, hasQuery, false) } } @@ -154,31 +265,73 @@ export default function (f7, isGraalJs) { */ javascriptGenerator.forBlock['oh_httprequest'] = function (block) { const requestType = block.getFieldValue('requestType') + + let paramCode = '' + + const url = javascriptGenerator.valueToCode(block, 'url', javascriptGenerator.ORDER_ATOMIC) + const queryBlock = block.getInput('query')?.connection?.targetBlock() + let query + if (queryBlock) { + let elements = new Array(queryBlock.itemCount_) + for (let i = 0; i < queryBlock.itemCount_; i++) { + elements[i] = queryBlock.getFieldValue('KEY' + i) + '=\' + ' + paramCode += 'let param' + i + '= encodeURIComponent(' + (javascriptGenerator.valueToCode(queryBlock, 'ADD' + i, javascriptGenerator.ORDER_NONE) || 'null') + ');\n' + elements[i] += 'param' + i + } + query = elements.join(' + \'&') + } + paramCode += 'let url = ' + url + if (query) { + paramCode += ' + \'?' + query + } + paramCode += ';\n' + const contentType = block.getFieldValue('contentType') + if (contentType) { + paramCode += 'let contentType = ' + contentType + ';\n' + } + + const payloadBlock = block.getInput('payload')?.connection?.targetBlock() + let payload + if ((contentType === 'application/x-www-form-urlencoded') && (payloadBlock?.type === 'dicts_create_with')) { + let elements = new Array(payloadBlock.itemCount_) + for (let i = 0; i < payloadBlock.itemCount_; i++) { + elements[i] = '\\\'' + payloadBlock.getFieldValue('KEY' + i) + '\\\':\' + ' + paramCode += 'let param' + i + '= encodeURIComponent(' + (javascriptGenerator.valueToCode(payloadBlock, 'ADD' + i, javascriptGenerator.ORDER_NONE) || 'null') + ');\n' + elements[i] += 'param' + i + } + payload = '\'{' + elements.join(' + \',') + ' + \'}\'' + } else { + payload = javascriptGenerator.valueToCode(block, 'payload', javascriptGenerator.ORDER_ATOMIC) + } + if (payload) { + paramCode += 'let payload = ' + payload + ';\n' + } + const headers = javascriptGenerator.valueToCode(block, 'requestHeader', javascriptGenerator.ORDER_ATOMIC) + if (headers) { + paramCode += 'let headers = ' + headers + ';\n' + } const timeout = javascriptGenerator.valueToCode(block, 'timeoutInput', javascriptGenerator.ORDER_ATOMIC) || 3000 - const url = javascriptGenerator.valueToCode(block, 'url', javascriptGenerator.ORDER_ATOMIC) - const payload = javascriptGenerator.valueToCode(block, 'payload', javascriptGenerator.ORDER_ATOMIC) - const hasContent = (requestType !== 'HttpGetRequest' && requestType !== 'HttpDeleteRequest') let code = '' if (hasContent) { if (!headers) { - code = `actions.HTTP.send${requestType}(${url}, '${contentType}', ${payload}, ${timeout})` + code = `actions.HTTP.send${requestType}(url, contentType, payload, ${timeout})` } else { - code = `actions.HTTP.send${requestType}(${url},' ${contentType}', ${payload}, ${headers}, ${timeout})` + code = `actions.HTTP.send${requestType}(url, contentType, payload, headers, ${timeout})` } } else { if (!headers) { - code = `actions.HTTP.send${requestType}(${url}, ${timeout})` + code = `actions.HTTP.send${requestType}(url, ${timeout})` } else { - code = `actions.HTTP.send${requestType}(${url}, ${headers}, ${timeout})` + code = `actions.HTTP.send${requestType}(url, headers, ${timeout})` } } if (isGraalJs) { - return [code, javascriptGenerator.ORDER_NONE] + return [paramCode + code, javascriptGenerator.ORDER_NONE] } else { throw new Error(unavailMsg) } From a5c3e8d9b69e4d8c471925f49b9098405956e01d Mon Sep 17 00:00:00 2001 From: Mark Herwege Date: Tue, 30 Jul 2024 08:29:17 +0200 Subject: [PATCH 02/14] quote payload xml arguments Signed-off-by: Mark Herwege --- .../web/src/assets/definitions/blockly/blocks-http.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-http.js b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-http.js index 1480c5611e..95b7eca5b4 100644 --- a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-http.js +++ b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-http.js @@ -275,7 +275,7 @@ export default function (f7, isGraalJs) { let elements = new Array(queryBlock.itemCount_) for (let i = 0; i < queryBlock.itemCount_; i++) { elements[i] = queryBlock.getFieldValue('KEY' + i) + '=\' + ' - paramCode += 'let param' + i + '= encodeURIComponent(' + (javascriptGenerator.valueToCode(queryBlock, 'ADD' + i, javascriptGenerator.ORDER_NONE) || 'null') + ');\n' + paramCode += 'let param' + i + ' = encodeURIComponent(' + (javascriptGenerator.valueToCode(queryBlock, 'ADD' + i, javascriptGenerator.ORDER_NONE) || 'null') + ');\n' elements[i] += 'param' + i } query = elements.join(' + \'&') @@ -296,11 +296,11 @@ export default function (f7, isGraalJs) { if ((contentType === 'application/x-www-form-urlencoded') && (payloadBlock?.type === 'dicts_create_with')) { let elements = new Array(payloadBlock.itemCount_) for (let i = 0; i < payloadBlock.itemCount_; i++) { - elements[i] = '\\\'' + payloadBlock.getFieldValue('KEY' + i) + '\\\':\' + ' - paramCode += 'let param' + i + '= encodeURIComponent(' + (javascriptGenerator.valueToCode(payloadBlock, 'ADD' + i, javascriptGenerator.ORDER_NONE) || 'null') + ');\n' + elements[i] = '\\\'' + payloadBlock.getFieldValue('KEY' + i) + '\\\':\\\'\' + ' + paramCode += 'let param' + i + ' = encodeURIComponent(' + (javascriptGenerator.valueToCode(payloadBlock, 'ADD' + i, javascriptGenerator.ORDER_NONE) || 'null') + ');\n' elements[i] += 'param' + i } - payload = '\'{' + elements.join(' + \',') + ' + \'}\'' + payload = '\'{' + elements.join(' + \'\\\',') + ' + \'}\'' } else { payload = javascriptGenerator.valueToCode(block, 'payload', javascriptGenerator.ORDER_ATOMIC) } From 1403f066f647994f85c592cb86f6a8237395e279 Mon Sep 17 00:00:00 2001 From: Mark Herwege Date: Tue, 30 Jul 2024 08:29:18 +0200 Subject: [PATCH 03/14] fix variables Signed-off-by: Mark Herwege --- .../assets/definitions/blockly/blocks-http.js | 42 ++++++++++++------- 1 file changed, 28 insertions(+), 14 deletions(-) diff --git a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-http.js b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-http.js index 95b7eca5b4..20e12ce738 100644 --- a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-http.js +++ b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-http.js @@ -263,7 +263,7 @@ export default function (f7, isGraalJs) { * @param block * @returns {[string,number]} */ - javascriptGenerator.forBlock['oh_httprequest'] = function (block) { + javascriptGenerator.forBlock['oh_httprequest'] = function (block, generator) { const requestType = block.getFieldValue('requestType') let paramCode = '' @@ -275,42 +275,50 @@ export default function (f7, isGraalJs) { let elements = new Array(queryBlock.itemCount_) for (let i = 0; i < queryBlock.itemCount_; i++) { elements[i] = queryBlock.getFieldValue('KEY' + i) + '=\' + ' - paramCode += 'let param' + i + ' = encodeURIComponent(' + (javascriptGenerator.valueToCode(queryBlock, 'ADD' + i, javascriptGenerator.ORDER_NONE) || 'null') + ');\n' - elements[i] += 'param' + i + const paramVar = javascriptGenerator.nameDB_.getDistinctName('param' + i, Blockly.Names.NameType.VARIABLE) + const paramContent = javascriptGenerator.valueToCode(queryBlock, 'ADD' + i, javascriptGenerator.ORDER_NONE) || 'null' + paramCode += `var ${paramVar} = encodeURIComponent(${paramContent});\n` + elements[i] += paramVar } query = elements.join(' + \'&') } - paramCode += 'let url = ' + url + const urlVar = generator.nameDB_.getDistinctName('url', Blockly.Names.NameType.VARIABLE) + paramCode += `var ${urlVar} = ${url}` if (query) { paramCode += ' + \'?' + query } paramCode += ';\n' const contentType = block.getFieldValue('contentType') + const contentTypeVar = generator.nameDB_.getDistinctName('contentType', Blockly.Names.NameType.VARIABLE) if (contentType) { - paramCode += 'let contentType = ' + contentType + ';\n' + paramCode += `var ${contentTypeVar} = ${contentType};\n` } const payloadBlock = block.getInput('payload')?.connection?.targetBlock() let payload + const payloadVar = generator.nameDB_.getDistinctName('payload', Blockly.Names.NameType.VARIABLE) if ((contentType === 'application/x-www-form-urlencoded') && (payloadBlock?.type === 'dicts_create_with')) { let elements = new Array(payloadBlock.itemCount_) for (let i = 0; i < payloadBlock.itemCount_; i++) { elements[i] = '\\\'' + payloadBlock.getFieldValue('KEY' + i) + '\\\':\\\'\' + ' - paramCode += 'let param' + i + ' = encodeURIComponent(' + (javascriptGenerator.valueToCode(payloadBlock, 'ADD' + i, javascriptGenerator.ORDER_NONE) || 'null') + ');\n' - elements[i] += 'param' + i + const paramVar = javascriptGenerator.nameDB_.getDistinctName('param' + i, Blockly.Names.NameType.VARIABLE) + const paramContent = javascriptGenerator.valueToCode(queryBlock, 'ADD' + i, javascriptGenerator.ORDER_NONE) || 'null' + paramCode += `var ${paramVar} = encodeURIComponent(${paramContent});\n` + elements[i] += paramVar } payload = '\'{' + elements.join(' + \'\\\',') + ' + \'}\'' } else { payload = javascriptGenerator.valueToCode(block, 'payload', javascriptGenerator.ORDER_ATOMIC) } if (payload) { - paramCode += 'let payload = ' + payload + ';\n' + paramCode += `var ${payloadVar} = ${payload};\n` } const headers = javascriptGenerator.valueToCode(block, 'requestHeader', javascriptGenerator.ORDER_ATOMIC) + const headersVar = javascriptGenerator.nameDB_.getDistinctName('headers', Blockly.Names.NameType.VARIABLE) if (headers) { - paramCode += 'let headers = ' + headers + ';\n' + paramCode += `var ${headersVar} = ${headers};\n` } const timeout = javascriptGenerator.valueToCode(block, 'timeoutInput', javascriptGenerator.ORDER_ATOMIC) || 3000 @@ -319,21 +327,27 @@ export default function (f7, isGraalJs) { let code = '' if (hasContent) { if (!headers) { - code = `actions.HTTP.send${requestType}(url, contentType, payload, ${timeout})` + code = `actions.HTTP.send${requestType}(${urlVar}, ${contentTypeVar}, ${payloadVar}, ${timeout})` } else { - code = `actions.HTTP.send${requestType}(url, contentType, payload, headers, ${timeout})` + code = `actions.HTTP.send${requestType}(${urlVar}, ${contentTypeVar}, ${payloadVar}, ${headersVar}, ${timeout})` } } else { if (!headers) { - code = `actions.HTTP.send${requestType}(url, ${timeout})` + code = `actions.HTTP.send${requestType}(${urlVar}, ${timeout})` } else { - code = `actions.HTTP.send${requestType}(url, headers, ${timeout})` + code = `actions.HTTP.send${requestType}(${urlVar}, ${headersVar}, ${timeout})` } } if (isGraalJs) { - return [paramCode + code, javascriptGenerator.ORDER_NONE] + addParamCode(paramCode) + return [code, javascriptGenerator.ORDER_NONE] } else { throw new Error(unavailMsg) } } + + function addParamCode (paramCode) { + const paramCodeVar = javascriptGenerator.nameDB_.getDistinctName('paramCode', Blockly.Names.NameType.VARIABLE) + return javascriptGenerator.provideFunction_(paramCodeVar, [paramCode]) + } } From f2ca2657dd9d874ca21818ef0794e8cd513bcf13 Mon Sep 17 00:00:00 2001 From: Mark Herwege Date: Tue, 30 Jul 2024 08:29:18 +0200 Subject: [PATCH 04/14] use shadow blocks Signed-off-by: Mark Herwege --- .../assets/definitions/blockly/blocks-http.js | 154 ++++++------------ 1 file changed, 52 insertions(+), 102 deletions(-) diff --git a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-http.js b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-http.js index 20e12ce738..53769d9a29 100644 --- a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-http.js +++ b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-http.js @@ -74,7 +74,7 @@ export default function (f7, isGraalJs) { if (isPost || isPut) { this.handleContentTypeSelection(this.getFieldValue('contentType')) } else { - this.updateShape(this.hasTimeout, this.hasHeader, this.hasQuery, true) + this.updateShape(this.hasTimeout, this.hasHeader, this.hasQuery) } } }, @@ -82,84 +82,62 @@ export default function (f7, isGraalJs) { if (this.contentType !== contentType) { this.contentType = contentType this.hasPayloadDict = (contentType === 'application/x-www-form-urlencoded') - this.updateShape(this.hasTimeout, this.hasHeader, this.hasQuery, true) + this.updateShape(this.hasTimeout, this.hasHeader, this.hasQuery) } }, - updateShape: function (hasTimeout, hasHeader, hasQuery, addBlocks) { + updateShape: function (hasTimeout, hasHeader, hasQuery) { this.hasTimeout = hasTimeout this.hasHeader = hasHeader this.hasQuery = hasQuery + let timeoutInput = this.getInput('timeoutInput') if (hasTimeout) { - if (!this.getInput('timeoutInput')) { - const timeoutInput = this.appendValueInput('timeoutInput') + if (!timeoutInput) { + timeoutInput = this.appendValueInput('timeoutInput') .setCheck('Number') .appendField('with Timeout (ms)') - - const blockAfter = this.getInput('requestHeader') ? 'requestHeader' : (this.getInput('payload') ? 'payload' : (this.getInput('query') ? 'query' : undefined)) + const blockAfter = this.getInput('requestHeader') ? 'requestHeader' : (this.getInput('query') ? 'query' : (this.getInput('payload') ? 'payload' : undefined)) if (blockAfter) { this.moveInputBefore('timeoutInput', blockAfter) } - if (addBlocks) { - const parentConnection = timeoutInput.connection - const mathNumberBlock = this.workspace.newBlock('math_number') - mathNumberBlock.setFieldValue('3000', 'NUM') - parentConnection.connect(mathNumberBlock.outputConnection) - mathNumberBlock.initSvg() - if (this.rendered) { - mathNumberBlock.render() - } - } - } - } else if (this.getInput('timeoutInput')) { - const parentConnection = this.getInput('timeoutInput').connection - const targetBlock = parentConnection.targetBlock() - if (targetBlock) { - targetBlock.unplug() - targetBlock.dispose() + timeoutInput.setShadowDom(Blockly.utils.xml.textToDom('3000')) } + } else if (timeoutInput) { + timeoutInput.setShadowDom(null) this.removeInput('timeoutInput') } + let headerInput = this.getInput('requestHeader') if (hasHeader) { - if (!this.getInput('requestHeader')) { - const headerInput = this.appendValueInput('requestHeader') + if (!headerInput) { + headerInput = this.appendValueInput('requestHeader') .setCheck('Dictionary') .appendField('with Headers') - const blockAfter = this.getInput('payload') ? 'payload' : (this.getInput('query') ? 'query' : undefined) + const blockAfter = this.getInput('query') ? 'query' : (this.getInput('payload') ? 'payload' : undefined) if (blockAfter) { this.moveInputBefore('requestHeader', blockAfter) } - if (addBlocks) { - this.addDict(headerInput, 'header') - } + this.addDictShadowBlock(headerInput, 'header') } - } else if (this.getInput('requestHeader')) { - const parentConnection = this.getInput('requestHeader').connection - const targetBlock = parentConnection.targetBlock() - this.disposeIfEmpty(targetBlock) + } else if (headerInput) { + headerInput.setShadowDom(null) this.removeInput('requestHeader') } + let queryInput = this.getInput('query') if (hasQuery) { - if (!this.getInput('query')) { - const queryInput = this.appendValueInput('query') + if (!queryInput) { + queryInput = this.appendValueInput('query') .setCheck('Dictionary') .appendField('with Query') - if (addBlocks) { - this.addDict(queryInput, 'param') - } + this.addDictShadowBlock(queryInput, 'param') } - } else if (this.getInput('query')) { - const parentConnection = this.getInput('query').connection - const targetBlock = parentConnection.targetBlock() - this.disposeIfEmpty(targetBlock) + } else if (queryInput) { + queryInput.setShadowDom(null) this.removeInput('query') } let payloadInput = this.getInput('payload') - const parentConnection = payloadInput?.connection - const targetBlock = parentConnection?.targetBlock() if (this.hasPayload) { if (!payloadInput) { payloadInput = this.appendValueInput('payload') @@ -175,72 +153,44 @@ export default function (f7, isGraalJs) { ['text/javascript', 'text/javascript'], ['text/plain', 'text/plain'], ['text/xml', 'text/xml']], this.handleContentTypeSelection.bind(this)), 'contentType') - .setShadowDom(Blockly.utils.xml.textToDom('')) - .setCheck(['String', 'Dictionary']) - if (addBlocks && this.hasPayloadDict) { - this.addDict(payloadInput, 'param') - } - } else if (this.hasPayloadDict) { - if (targetBlock && (targetBlock.type !== 'dicts_create_with') && !targetBlock.isShadow()) { - targetBlock.unplug() - targetBlock.moveBy(10, 10) - } - if (addBlocks && (!payloadInput.connection?.targetBlock() || payloadInput.connection.targetBlock().isShadow())) { - this.addDict(payloadInput, 'param') - } - } else if (targetBlock && (targetBlock.type === 'dicts_create_with')) { - this.disposeIfEmpty(targetBlock) + } + if (payloadInput && this.hasPayloadDict && !payloadInput.connection.getCheck()?.includes('Dictionary')) { + payloadInput.setShadowDom(null) + payloadInput.setCheck('Dictionary') + this.addDictShadowBlock(payloadInput, 'param') + } else if (payloadInput && !this.hasPayloadDict && !payloadInput.connection.getCheck()?.includes('String')) { + payloadInput.setShadowDom(null) + payloadInput.setCheck('String') + payloadInput.setShadowDom(Blockly.utils.xml.textToDom('payload')) } } else if (payloadInput) { - this.disposeIfEmpty(targetBlock) + payloadInput.setShadowDom(null) this.removeInput('payload') } }, - addDict (input, param) { - const parentConnection = input.connection - const dictBlock = this.workspace.newBlock('dicts_create_with') - dictBlock.itemCount_ = 2 - dictBlock.updateShape_() - for (let i = 0; i < dictBlock.itemCount_; i++) { - dictBlock.setFieldValue(`${param}${i}`, 'KEY' + i) - dictBlock.getInput('ADD' + i).setShadowDom(Blockly.utils.xml.textToDom('')) - } - parentConnection.connect(dictBlock.outputConnection) - dictBlock.initSvg() - if (this.rendered) { - dictBlock.render() - } - }, - disposeIfEmpty (targetBlock) { - if (targetBlock) { - targetBlock.unplug() - targetBlock.moveBy(10, 10) - let isEmpty = true - if (!targetBlock.isShadow() && !targetBlock.getChildren().length) { - isEmpty = false - } - let i = 0 - while (isEmpty && targetBlock.getInput('ADD' + i)) { - isEmpty = targetBlock.getInput('ADD' + i).connection.targetBlock().isShadow() - i++ - } - if (isEmpty) targetBlock.dispose() - } + addDictShadowBlock (input, param) { + input.setShadowDom(Blockly.utils.xml.textToDom(` + + ${param}1 + ${param}1 + ${param}2 + ${param}2 + `)) }, onClickTimeout () { let block = this.getSourceBlock() block.hasTimeout = !block.hasTimeout - block.updateShape(block.hasTimeout, block.hasHeader, block.hasQuery, true) + block.updateShape(block.hasTimeout, block.hasHeader, block.hasQuery) }, onClickHeader () { let block = this.getSourceBlock() block.hasHeader = !block.hasHeader - block.updateShape(block.hasTimeout, block.hasHeader, block.hasQuery, true) + block.updateShape(block.hasTimeout, block.hasHeader, block.hasQuery) }, onClickQuery () { let block = this.getSourceBlock() block.hasQuery = !block.hasQuery - block.updateShape(block.hasTimeout, block.hasHeader, block.hasQuery, true) + block.updateShape(block.hasTimeout, block.hasHeader, block.hasQuery) }, mutationToDom: function () { let container = Blockly.utils.xml.createElement('mutation') @@ -253,7 +203,7 @@ export default function (f7, isGraalJs) { let hasTimeout = xmlElement.getAttribute('hasTimeout') === 'true' let hasHeader = xmlElement.getAttribute('hasHeader') === 'true' let hasQuery = xmlElement.getAttribute('hasQuery') === 'true' - this.updateShape(hasTimeout, hasHeader, hasQuery, false) + this.updateShape(hasTimeout, hasHeader, hasQuery) } } @@ -277,13 +227,13 @@ export default function (f7, isGraalJs) { elements[i] = queryBlock.getFieldValue('KEY' + i) + '=\' + ' const paramVar = javascriptGenerator.nameDB_.getDistinctName('param' + i, Blockly.Names.NameType.VARIABLE) const paramContent = javascriptGenerator.valueToCode(queryBlock, 'ADD' + i, javascriptGenerator.ORDER_NONE) || 'null' - paramCode += `var ${paramVar} = encodeURIComponent(${paramContent});\n` + paramCode += `const ${paramVar} = encodeURIComponent(${paramContent});\n` elements[i] += paramVar } query = elements.join(' + \'&') } const urlVar = generator.nameDB_.getDistinctName('url', Blockly.Names.NameType.VARIABLE) - paramCode += `var ${urlVar} = ${url}` + paramCode += `const ${urlVar} = ${url}` if (query) { paramCode += ' + \'?' + query } @@ -292,7 +242,7 @@ export default function (f7, isGraalJs) { const contentType = block.getFieldValue('contentType') const contentTypeVar = generator.nameDB_.getDistinctName('contentType', Blockly.Names.NameType.VARIABLE) if (contentType) { - paramCode += `var ${contentTypeVar} = ${contentType};\n` + paramCode += `const ${contentTypeVar} = '${contentType}';\n` } const payloadBlock = block.getInput('payload')?.connection?.targetBlock() @@ -303,8 +253,8 @@ export default function (f7, isGraalJs) { for (let i = 0; i < payloadBlock.itemCount_; i++) { elements[i] = '\\\'' + payloadBlock.getFieldValue('KEY' + i) + '\\\':\\\'\' + ' const paramVar = javascriptGenerator.nameDB_.getDistinctName('param' + i, Blockly.Names.NameType.VARIABLE) - const paramContent = javascriptGenerator.valueToCode(queryBlock, 'ADD' + i, javascriptGenerator.ORDER_NONE) || 'null' - paramCode += `var ${paramVar} = encodeURIComponent(${paramContent});\n` + const paramContent = javascriptGenerator.valueToCode(payloadBlock, 'ADD' + i, javascriptGenerator.ORDER_NONE) || 'null' + paramCode += `const ${paramVar} = encodeURIComponent(${paramContent});\n` elements[i] += paramVar } payload = '\'{' + elements.join(' + \'\\\',') + ' + \'}\'' @@ -312,13 +262,13 @@ export default function (f7, isGraalJs) { payload = javascriptGenerator.valueToCode(block, 'payload', javascriptGenerator.ORDER_ATOMIC) } if (payload) { - paramCode += `var ${payloadVar} = ${payload};\n` + paramCode += `const ${payloadVar} = ${payload};\n` } const headers = javascriptGenerator.valueToCode(block, 'requestHeader', javascriptGenerator.ORDER_ATOMIC) const headersVar = javascriptGenerator.nameDB_.getDistinctName('headers', Blockly.Names.NameType.VARIABLE) if (headers) { - paramCode += `var ${headersVar} = ${headers};\n` + paramCode += `const ${headersVar} = ${headers};\n` } const timeout = javascriptGenerator.valueToCode(block, 'timeoutInput', javascriptGenerator.ORDER_ATOMIC) || 3000 From 49fa92e1eee72df2d523faed286f0516c3fd15ee Mon Sep 17 00:00:00 2001 From: Mark Herwege Date: Tue, 30 Jul 2024 08:29:19 +0200 Subject: [PATCH 05/14] refactor Signed-off-by: Mark Herwege --- .../assets/definitions/blockly/blocks-http.js | 179 ++++++++---------- 1 file changed, 84 insertions(+), 95 deletions(-) diff --git a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-http.js b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-http.js index 53769d9a29..41ddb88a7e 100644 --- a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-http.js +++ b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-http.js @@ -4,6 +4,7 @@ import Blockly from 'blockly' import { javascriptGenerator } from 'blockly/javascript.js' +import { NormalModuleReplacementPlugin } from 'webpack' export default function (f7, isGraalJs) { const timeoutImage = 'data:image/png;base64,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' @@ -22,10 +23,14 @@ export default function (f7, isGraalJs) { const imageHeaderField = new Blockly.FieldImage(headerImage, 15, 15, undefined, this.onClickHeader) imageHeaderField.setTooltip('Add headers to the request.') + const imageQueryField = new Blockly.FieldImage(queryImage, 15, 15, undefined, this.onClickQuery) + imageQueryField.setTooltip('Add query to the request url.') + this.appendValueInput('url') .setCheck('String') .appendField(imageTimeoutField, 'imgTimeout') .appendField(imageHeaderField, 'imgHeader') + .appendField(imageQueryField, 'imgHeader') .appendField('send', 'methodField') .appendField(new Blockly.FieldDropdown([ ['HttpGetRequest', 'HttpGetRequest'], @@ -46,42 +51,27 @@ export default function (f7, isGraalJs) { handleRequestTypeSelection: function (requestType) { if (this.requestType !== requestType) { this.requestType = requestType - const isGet = requestType === 'HttpGetRequest' - const isPost = requestType === 'HttpPostRequest' - const isPut = requestType === 'HttpPutRequest' - const isDelete = requestType === 'HttpDeleteRequest' - if (isPost || isPut) { - this.hasPayload = true - } else { + this.contentType = null + if (requestType === 'HttpGetRequest') { this.hasPayload = false - this.hasPayloadDict = false - } - - const urlInput = this.getInput('url') - if (isGet || isDelete) { - if (urlInput.fieldRow[2].name !== 'imgQuery') { - const imageQueryField = new Blockly.FieldImage(queryImage, 15, 15, undefined, this.onClickQuery) - imageQueryField.setTooltip('Add query to the request.') - urlInput.insertFieldAt(2, imageQueryField, 'imgQuery') - } - } else { - if (urlInput.fieldRow[2].name === 'imgQuery') { - urlInput.removeField('imgQuery') - } - this.hasQuery = false - } - - if (isPost || isPut) { - this.handleContentTypeSelection(this.getFieldValue('contentType')) - } else { this.updateShape(this.hasTimeout, this.hasHeader, this.hasQuery) + } else { + this.hasPayload = true + const contentType = this.getFieldValue('contentType') + this.handleContentTypeSelection(contentType) } } }, handleContentTypeSelection: function (contentType) { if (this.contentType !== contentType) { - this.contentType = contentType - this.hasPayloadDict = (contentType === 'application/x-www-form-urlencoded') + if ((this.requestType === 'HttpDeleteRequest') && !contentType) { + // default content type for HttpDelete is none, normally no payload + this.contentType = 'none' + } else { + this.contentType = contentType + } + this.hasNoContent = (this.contentType === 'none') + this.isDictContent = ['application/json', 'application/x-www-form-urlencoded'].includeds(this.contentType) this.updateShape(this.hasTimeout, this.hasHeader, this.hasQuery) } }, @@ -137,11 +127,21 @@ export default function (f7, isGraalJs) { this.removeInput('query') } + let payloadInput = this.getInput('payload') if (this.hasPayload) { + if (this.hasNoContent && payloadInput && (payloadInput.type === Blockly.inputs.inputTypes.VALUE)) { + this.removePayloadInput() + } else if (!this.hasNoContent && payloadInput && (payloadInput.type === Blockly.inputs.inputTypes.DUMMY)) { + this.removePayloadInput() + } if (!payloadInput) { - payloadInput = this.appendValueInput('payload') - .appendField('with Payload') + if (this.hasNoContent) { + payloadInput = this.appendDummyInput('payload') + } else { + payloadInput = this.appendValueInput('payload') + } + payloadInput.appendField('with Payload') .appendField(new Blockly.FieldDropdown([ ['application/json', 'application/json'], ['none', 'none'], @@ -154,17 +154,27 @@ export default function (f7, isGraalJs) { ['text/plain', 'text/plain'], ['text/xml', 'text/xml']], this.handleContentTypeSelection.bind(this)), 'contentType') } - if (payloadInput && this.hasPayloadDict && !payloadInput.connection.getCheck()?.includes('Dictionary')) { - payloadInput.setShadowDom(null) - payloadInput.setCheck('Dictionary') - this.addDictShadowBlock(payloadInput, 'param') - } else if (payloadInput && !this.hasPayloadDict && !payloadInput.connection.getCheck()?.includes('String')) { + if (this.contentType !== 'none') { + if (this.isDictContent && !payloadInput.connection.getCheck()?.includes('Dictionary')) { + payloadInput.setShadowDom(null) + payloadInput.setCheck(['Dictionary', 'String']) + this.addDictShadowBlock(payloadInput, 'param') + } else if (!this.isDictContent && !payloadInput.connection.getCheck()?.includes('String')) { + payloadInput.setShadowDom(null) + payloadInput.setCheck('String') + payloadInput.setShadowDom(Blockly.utils.xml.textToDom('payload')) + } + } + } else { + this.removePayloadInput() + } + }, + removePayloadInput () { + let payloadInput = this.getInput('payload') + if (payloadInput) { + if (payloadInput.type === Blockly.inputs.inputTypes.VALUE) { payloadInput.setShadowDom(null) - payloadInput.setCheck('String') - payloadInput.setShadowDom(Blockly.utils.xml.textToDom('payload')) } - } else if (payloadInput) { - payloadInput.setShadowDom(null) this.removeInput('payload') } }, @@ -216,88 +226,67 @@ export default function (f7, isGraalJs) { javascriptGenerator.forBlock['oh_httprequest'] = function (block, generator) { const requestType = block.getFieldValue('requestType') - let paramCode = '' + let url = javascriptGenerator.valueToCode(block, 'url', javascriptGenerator.ORDER_ATOMIC) - const url = javascriptGenerator.valueToCode(block, 'url', javascriptGenerator.ORDER_ATOMIC) - const queryBlock = block.getInput('query')?.connection?.targetBlock() - let query - if (queryBlock) { - let elements = new Array(queryBlock.itemCount_) - for (let i = 0; i < queryBlock.itemCount_; i++) { - elements[i] = queryBlock.getFieldValue('KEY' + i) + '=\' + ' - const paramVar = javascriptGenerator.nameDB_.getDistinctName('param' + i, Blockly.Names.NameType.VARIABLE) - const paramContent = javascriptGenerator.valueToCode(queryBlock, 'ADD' + i, javascriptGenerator.ORDER_NONE) || 'null' - paramCode += `const ${paramVar} = encodeURIComponent(${paramContent});\n` - elements[i] += paramVar - } - query = elements.join(' + \'&') - } - const urlVar = generator.nameDB_.getDistinctName('url', Blockly.Names.NameType.VARIABLE) - paramCode += `const ${urlVar} = ${url}` + const query = javascriptGenerator.valueToCode(block, 'query', javascriptGenerator.ORDER_ATOMIC) if (query) { - paramCode += ' + \'?' + query + const queryEncodeFunction = encodeParams(query) + url = `${url} + '?' + ${queryEncodeFunction}(${query})` } - paramCode += ';\n' const contentType = block.getFieldValue('contentType') - const contentTypeVar = generator.nameDB_.getDistinctName('contentType', Blockly.Names.NameType.VARIABLE) - if (contentType) { - paramCode += `const ${contentTypeVar} = '${contentType}';\n` - } - const payloadBlock = block.getInput('payload')?.connection?.targetBlock() - let payload - const payloadVar = generator.nameDB_.getDistinctName('payload', Blockly.Names.NameType.VARIABLE) - if ((contentType === 'application/x-www-form-urlencoded') && (payloadBlock?.type === 'dicts_create_with')) { - let elements = new Array(payloadBlock.itemCount_) - for (let i = 0; i < payloadBlock.itemCount_; i++) { - elements[i] = '\\\'' + payloadBlock.getFieldValue('KEY' + i) + '\\\':\\\'\' + ' - const paramVar = javascriptGenerator.nameDB_.getDistinctName('param' + i, Blockly.Names.NameType.VARIABLE) - const paramContent = javascriptGenerator.valueToCode(payloadBlock, 'ADD' + i, javascriptGenerator.ORDER_NONE) || 'null' - paramCode += `const ${paramVar} = encodeURIComponent(${paramContent});\n` - elements[i] += paramVar - } - payload = '\'{' + elements.join(' + \'\\\',') + ' + \'}\'' - } else { - payload = javascriptGenerator.valueToCode(block, 'payload', javascriptGenerator.ORDER_ATOMIC) - } + let payload = javascriptGenerator.valueToCode(block, 'payload', javascriptGenerator.ORDER_ATOMIC) if (payload) { - paramCode += `const ${payloadVar} = ${payload};\n` + if (contentType === 'application/x-www-form-urlencoded') { + const payloadEncodeFunction = encodeParams(payload) + payload = `${payloadEncodeFunction}(${payload})` + } else if (contentType === 'application/json') { + const payloadToJSONStringFunction = toJSONString(payload) + payload = `${payloadToJSONStringFunction}(${payload})` + } } const headers = javascriptGenerator.valueToCode(block, 'requestHeader', javascriptGenerator.ORDER_ATOMIC) - const headersVar = javascriptGenerator.nameDB_.getDistinctName('headers', Blockly.Names.NameType.VARIABLE) - if (headers) { - paramCode += `const ${headersVar} = ${headers};\n` - } - const timeout = javascriptGenerator.valueToCode(block, 'timeoutInput', javascriptGenerator.ORDER_ATOMIC) || 3000 - const hasContent = (requestType !== 'HttpGetRequest' && requestType !== 'HttpDeleteRequest') let code = '' - if (hasContent) { + if (payload) { if (!headers) { - code = `actions.HTTP.send${requestType}(${urlVar}, ${contentTypeVar}, ${payloadVar}, ${timeout})` + code = `actions.HTTP.send${requestType}(${url}, '${contentType}', ${payload}, ${timeout})` } else { - code = `actions.HTTP.send${requestType}(${urlVar}, ${contentTypeVar}, ${payloadVar}, ${headersVar}, ${timeout})` + code = `actions.HTTP.send${requestType}(${url}, '${contentType}', ${payload}, ${headers}, ${timeout})` } } else { if (!headers) { - code = `actions.HTTP.send${requestType}(${urlVar}, ${timeout})` + code = `actions.HTTP.send${requestType}(${url}, ${timeout})` } else { - code = `actions.HTTP.send${requestType}(${urlVar}, ${headersVar}, ${timeout})` + code = `actions.HTTP.send${requestType}(${url}, ${headers}, ${timeout})` } } if (isGraalJs) { - addParamCode(paramCode) return [code, javascriptGenerator.ORDER_NONE] } else { throw new Error(unavailMsg) } } - function addParamCode (paramCode) { - const paramCodeVar = javascriptGenerator.nameDB_.getDistinctName('paramCode', Blockly.Names.NameType.VARIABLE) - return javascriptGenerator.provideFunction_(paramCodeVar, [paramCode]) + function encodeParams (params) { + return javascriptGenerator.provideFunction_('encodeParams', [ + 'function encodeParams(params) {', + ' if (params instanceof String) return params', + ' const encodedParams = Object.entries(params).map(([key, value]) => [key, encodeURIComponent(value)]);', + ' return encodedParams.map(p => p.join(\'=\')).join(\'&\');', + '}' + ]) + } + + function toJSONString (params) { + return javascriptGenerator.provideFunction_('toJSONString', [ + 'function toJSONString(params) {', + ' if (params instanceof String) return params', + ' return JSON.stringify(params)', + '}' + ]) } } From 04028c93031347bb3ee5d0e5782fc3e247694814 Mon Sep 17 00:00:00 2001 From: Mark Herwege Date: Tue, 30 Jul 2024 08:29:19 +0200 Subject: [PATCH 06/14] fix lint error Signed-off-by: Mark Herwege --- .../web/src/assets/definitions/blockly/blocks-http.js | 1 - 1 file changed, 1 deletion(-) diff --git a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-http.js b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-http.js index 41ddb88a7e..e341c9f4f2 100644 --- a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-http.js +++ b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-http.js @@ -127,7 +127,6 @@ export default function (f7, isGraalJs) { this.removeInput('query') } - let payloadInput = this.getInput('payload') if (this.hasPayload) { if (this.hasNoContent && payloadInput && (payloadInput.type === Blockly.inputs.inputTypes.VALUE)) { From c90f1848e1b69ebd40ee80fa9f1eaebfa9a09f1e Mon Sep 17 00:00:00 2001 From: Mark Herwege Date: Tue, 30 Jul 2024 08:29:19 +0200 Subject: [PATCH 07/14] fix Signed-off-by: Mark Herwege --- .../web/src/assets/definitions/blockly/blocks-http.js | 1 - 1 file changed, 1 deletion(-) diff --git a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-http.js b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-http.js index e341c9f4f2..506e0901f5 100644 --- a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-http.js +++ b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-http.js @@ -4,7 +4,6 @@ import Blockly from 'blockly' import { javascriptGenerator } from 'blockly/javascript.js' -import { NormalModuleReplacementPlugin } from 'webpack' export default function (f7, isGraalJs) { const timeoutImage = 'data:image/png;base64,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' From 53027c848c76b30554e2a8705ba26f64b8bbe6aa Mon Sep 17 00:00:00 2001 From: Mark Herwege Date: Tue, 30 Jul 2024 08:29:19 +0200 Subject: [PATCH 08/14] fixes Signed-off-by: Mark Herwege --- .../assets/definitions/blockly/blocks-http.js | 41 ++++++++++--------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-http.js b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-http.js index 506e0901f5..daf689ce3b 100644 --- a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-http.js +++ b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-http.js @@ -50,8 +50,7 @@ export default function (f7, isGraalJs) { handleRequestTypeSelection: function (requestType) { if (this.requestType !== requestType) { this.requestType = requestType - this.contentType = null - if (requestType === 'HttpGetRequest') { + if (['HttpGetRequest', 'HttpDeleteRequest'].includes(requestType)) { this.hasPayload = false this.updateShape(this.hasTimeout, this.hasHeader, this.hasQuery) } else { @@ -63,14 +62,10 @@ export default function (f7, isGraalJs) { }, handleContentTypeSelection: function (contentType) { if (this.contentType !== contentType) { - if ((this.requestType === 'HttpDeleteRequest') && !contentType) { - // default content type for HttpDelete is none, normally no payload - this.contentType = 'none' - } else { - this.contentType = contentType - } - this.hasNoContent = (this.contentType === 'none') - this.isDictContent = ['application/json', 'application/x-www-form-urlencoded'].includeds(this.contentType) + this.contentType = contentType + this.hasContent = (contentType !== 'none') + this.isJSONContent = (!contentType || (contentType === 'application/json')) + this.isEncodedContent = (contentType === 'application/x-www-form-urlencoded') this.updateShape(this.hasTimeout, this.hasHeader, this.hasQuery) } }, @@ -128,13 +123,15 @@ export default function (f7, isGraalJs) { let payloadInput = this.getInput('payload') if (this.hasPayload) { - if (this.hasNoContent && payloadInput && (payloadInput.type === Blockly.inputs.inputTypes.VALUE)) { + if (!this.hasContent && payloadInput && (payloadInput.type === Blockly.inputs.inputTypes.VALUE)) { this.removePayloadInput() - } else if (!this.hasNoContent && payloadInput && (payloadInput.type === Blockly.inputs.inputTypes.DUMMY)) { + payloadInput = null + } else if (this.hasContent && payloadInput && (payloadInput.type === Blockly.inputs.inputTypes.DUMMY)) { this.removePayloadInput() + payloadInput = null } if (!payloadInput) { - if (this.hasNoContent) { + if (!this.hasContent) { payloadInput = this.appendDummyInput('payload') } else { payloadInput = this.appendValueInput('payload') @@ -152,14 +149,18 @@ export default function (f7, isGraalJs) { ['text/plain', 'text/plain'], ['text/xml', 'text/xml']], this.handleContentTypeSelection.bind(this)), 'contentType') } - if (this.contentType !== 'none') { - if (this.isDictContent && !payloadInput.connection.getCheck()?.includes('Dictionary')) { + if (this.hasContent) { + if (this.isEncodedContent) { payloadInput.setShadowDom(null) payloadInput.setCheck(['Dictionary', 'String']) this.addDictShadowBlock(payloadInput, 'param') - } else if (!this.isDictContent && !payloadInput.connection.getCheck()?.includes('String')) { + } else { payloadInput.setShadowDom(null) - payloadInput.setCheck('String') + if (this.isJSONContent) { + payloadInput.setCheck(null) + } else { + payloadInput.setCheck('String') + } payloadInput.setShadowDom(Blockly.utils.xml.textToDom('payload')) } } @@ -272,7 +273,7 @@ export default function (f7, isGraalJs) { function encodeParams (params) { return javascriptGenerator.provideFunction_('encodeParams', [ 'function encodeParams(params) {', - ' if (params instanceof String) return params', + ' if ((typeof params === \'string\') || (params instanceof String)) return params;', ' const encodedParams = Object.entries(params).map(([key, value]) => [key, encodeURIComponent(value)]);', ' return encodedParams.map(p => p.join(\'=\')).join(\'&\');', '}' @@ -282,8 +283,8 @@ export default function (f7, isGraalJs) { function toJSONString (params) { return javascriptGenerator.provideFunction_('toJSONString', [ 'function toJSONString(params) {', - ' if (params instanceof String) return params', - ' return JSON.stringify(params)', + ' if ((typeof params === \'string\') || (params instanceof String)) return params;', + ' return JSON.stringify(params).replace(/^"+/, \'["\').replace(/"+$/, \'"]\');', '}' ]) } From 0653afc08bb3a1adc5d4ee590794ca6cef1a5b80 Mon Sep 17 00:00:00 2001 From: Mark Herwege Date: Tue, 30 Jul 2024 08:29:19 +0200 Subject: [PATCH 09/14] fixes Signed-off-by: Mark Herwege --- .../assets/definitions/blockly/blocks-http.js | 36 +++++++++++-------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-http.js b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-http.js index daf689ce3b..509a0f1f46 100644 --- a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-http.js +++ b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-http.js @@ -39,40 +39,36 @@ export default function (f7, isGraalJs) { ], this.handleRequestTypeSelection.bind(this)), 'requestType') .appendField('to') - this.handleRequestTypeSelection(this.getFieldValue('requestType')) - this.setInputsInline(false) this.setOutput(true, null) this.setColour(230) this.setTooltip('Send HTTP requests') this.setHelpUrl('https://www.openhab.org/docs/configuration/blockly/rules-blockly-http.html#requests') + + this.updateShape(this.hasTimeout, this.hasHeader, this.hasQuery, this.hasPayload) }, handleRequestTypeSelection: function (requestType) { if (this.requestType !== requestType) { this.requestType = requestType if (['HttpGetRequest', 'HttpDeleteRequest'].includes(requestType)) { this.hasPayload = false - this.updateShape(this.hasTimeout, this.hasHeader, this.hasQuery) } else { this.hasPayload = true - const contentType = this.getFieldValue('contentType') - this.handleContentTypeSelection(contentType) } + this.updateShape(this.hasTimeout, this.hasHeader, this.hasQuery, this.hasPayload) } }, handleContentTypeSelection: function (contentType) { if (this.contentType !== contentType) { this.contentType = contentType - this.hasContent = (contentType !== 'none') - this.isJSONContent = (!contentType || (contentType === 'application/json')) - this.isEncodedContent = (contentType === 'application/x-www-form-urlencoded') - this.updateShape(this.hasTimeout, this.hasHeader, this.hasQuery) + this.updateShape(this.hasTimeout, this.hasHeader, this.hasQuery, this.hasPayload) } }, - updateShape: function (hasTimeout, hasHeader, hasQuery) { + updateShape: function (hasTimeout, hasHeader, hasQuery, hasPayload) { this.hasTimeout = hasTimeout this.hasHeader = hasHeader this.hasQuery = hasQuery + this.hasPayload = hasPayload let timeoutInput = this.getInput('timeoutInput') if (hasTimeout) { @@ -114,6 +110,10 @@ export default function (f7, isGraalJs) { queryInput = this.appendValueInput('query') .setCheck('Dictionary') .appendField('with Query') + const blockAfter = this.getInput('payload') ? 'payload' : undefined + if (blockAfter) { + this.moveInputBefore('query', blockAfter) + } this.addDictShadowBlock(queryInput, 'param') } } else if (queryInput) { @@ -123,6 +123,9 @@ export default function (f7, isGraalJs) { let payloadInput = this.getInput('payload') if (this.hasPayload) { + this.hasContent = (this.contentType !== 'none') + this.isJSONContent = (!this.contentType || (this.contentType === 'application/json')) + this.isEncodedContent = (this.contentType === 'application/x-www-form-urlencoded') if (!this.hasContent && payloadInput && (payloadInput.type === Blockly.inputs.inputTypes.VALUE)) { this.removePayloadInput() payloadInput = null @@ -148,6 +151,9 @@ export default function (f7, isGraalJs) { ['text/javascript', 'text/javascript'], ['text/plain', 'text/plain'], ['text/xml', 'text/xml']], this.handleContentTypeSelection.bind(this)), 'contentType') + if (this.contentType) { + this.setFieldValue(this.contentType, 'contentType') + } } if (this.hasContent) { if (this.isEncodedContent) { @@ -189,30 +195,32 @@ export default function (f7, isGraalJs) { onClickTimeout () { let block = this.getSourceBlock() block.hasTimeout = !block.hasTimeout - block.updateShape(block.hasTimeout, block.hasHeader, block.hasQuery) + block.updateShape(block.hasTimeout, block.hasHeader, block.hasQuery, block.hasPayload) }, onClickHeader () { let block = this.getSourceBlock() block.hasHeader = !block.hasHeader - block.updateShape(block.hasTimeout, block.hasHeader, block.hasQuery) + block.updateShape(block.hasTimeout, block.hasHeader, block.hasQuery, block.hasPayload) }, onClickQuery () { let block = this.getSourceBlock() block.hasQuery = !block.hasQuery - block.updateShape(block.hasTimeout, block.hasHeader, block.hasQuery) + block.updateShape(block.hasTimeout, block.hasHeader, block.hasQuery, block.hasPayload) }, mutationToDom: function () { let container = Blockly.utils.xml.createElement('mutation') container.setAttribute('hasTimeout', this.hasTimeout) container.setAttribute('hasHeader', this.hasHeader) container.setAttribute('hasQuery', this.hasQuery) + container.setAttribute('hasPayload', this.hasPayload) return container }, domToMutation: function (xmlElement) { let hasTimeout = xmlElement.getAttribute('hasTimeout') === 'true' let hasHeader = xmlElement.getAttribute('hasHeader') === 'true' let hasQuery = xmlElement.getAttribute('hasQuery') === 'true' - this.updateShape(hasTimeout, hasHeader, hasQuery) + let hasPayload = xmlElement.getAttribute('hasPayload') === 'true' + this.updateShape(hasTimeout, hasHeader, hasQuery, hasPayload) } } From f9ae394e3b67359dadd027d0f70b92d4fefa9a21 Mon Sep 17 00:00:00 2001 From: Mark Herwege Date: Tue, 30 Jul 2024 08:54:53 +0200 Subject: [PATCH 10/14] replace fields by variables Signed-off-by: Mark Herwege --- .../assets/definitions/blockly/blocks-http.js | 46 ++++++++----------- 1 file changed, 19 insertions(+), 27 deletions(-) diff --git a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-http.js b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-http.js index 509a0f1f46..931ea956b4 100644 --- a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-http.js +++ b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-http.js @@ -45,30 +45,24 @@ export default function (f7, isGraalJs) { this.setTooltip('Send HTTP requests') this.setHelpUrl('https://www.openhab.org/docs/configuration/blockly/rules-blockly-http.html#requests') - this.updateShape(this.hasTimeout, this.hasHeader, this.hasQuery, this.hasPayload) + this.updateShape(this.hasTimeout, this.hasHeader, this.hasQuery) }, handleRequestTypeSelection: function (requestType) { if (this.requestType !== requestType) { this.requestType = requestType - if (['HttpGetRequest', 'HttpDeleteRequest'].includes(requestType)) { - this.hasPayload = false - } else { - this.hasPayload = true - } - this.updateShape(this.hasTimeout, this.hasHeader, this.hasQuery, this.hasPayload) + this.updateShape(this.hasTimeout, this.hasHeader, this.hasQuery) } }, handleContentTypeSelection: function (contentType) { if (this.contentType !== contentType) { this.contentType = contentType - this.updateShape(this.hasTimeout, this.hasHeader, this.hasQuery, this.hasPayload) + this.updateShape(this.hasTimeout, this.hasHeader, this.hasQuery) } }, - updateShape: function (hasTimeout, hasHeader, hasQuery, hasPayload) { + updateShape: function (hasTimeout, hasHeader, hasQuery) { this.hasTimeout = hasTimeout this.hasHeader = hasHeader this.hasQuery = hasQuery - this.hasPayload = hasPayload let timeoutInput = this.getInput('timeoutInput') if (hasTimeout) { @@ -121,20 +115,20 @@ export default function (f7, isGraalJs) { this.removeInput('query') } - let payloadInput = this.getInput('payload') - if (this.hasPayload) { - this.hasContent = (this.contentType !== 'none') - this.isJSONContent = (!this.contentType || (this.contentType === 'application/json')) - this.isEncodedContent = (this.contentType === 'application/x-www-form-urlencoded') - if (!this.hasContent && payloadInput && (payloadInput.type === Blockly.inputs.inputTypes.VALUE)) { + if (['HttpPostRequest', 'HttpPutRequest'].includes(this.requestType)) { + let payloadInput = this.getInput('payload') + let hasContent = (this.contentType !== 'none') + let isJSONContent = (!this.contentType || (this.contentType === 'application/json')) + let isEncodedContent = (this.contentType === 'application/x-www-form-urlencoded') + if (!hasContent && payloadInput && (payloadInput.type === Blockly.inputs.inputTypes.VALUE)) { this.removePayloadInput() payloadInput = null - } else if (this.hasContent && payloadInput && (payloadInput.type === Blockly.inputs.inputTypes.DUMMY)) { + } else if (hasContent && payloadInput && (payloadInput.type === Blockly.inputs.inputTypes.DUMMY)) { this.removePayloadInput() payloadInput = null } if (!payloadInput) { - if (!this.hasContent) { + if (!hasContent) { payloadInput = this.appendDummyInput('payload') } else { payloadInput = this.appendValueInput('payload') @@ -155,14 +149,14 @@ export default function (f7, isGraalJs) { this.setFieldValue(this.contentType, 'contentType') } } - if (this.hasContent) { - if (this.isEncodedContent) { + if (hasContent) { + if (isEncodedContent) { payloadInput.setShadowDom(null) payloadInput.setCheck(['Dictionary', 'String']) this.addDictShadowBlock(payloadInput, 'param') } else { payloadInput.setShadowDom(null) - if (this.isJSONContent) { + if (isJSONContent) { payloadInput.setCheck(null) } else { payloadInput.setCheck('String') @@ -195,32 +189,30 @@ export default function (f7, isGraalJs) { onClickTimeout () { let block = this.getSourceBlock() block.hasTimeout = !block.hasTimeout - block.updateShape(block.hasTimeout, block.hasHeader, block.hasQuery, block.hasPayload) + block.updateShape(block.hasTimeout, block.hasHeader, block.hasQuery) }, onClickHeader () { let block = this.getSourceBlock() block.hasHeader = !block.hasHeader - block.updateShape(block.hasTimeout, block.hasHeader, block.hasQuery, block.hasPayload) + block.updateShape(block.hasTimeout, block.hasHeader, block.hasQuery) }, onClickQuery () { let block = this.getSourceBlock() block.hasQuery = !block.hasQuery - block.updateShape(block.hasTimeout, block.hasHeader, block.hasQuery, block.hasPayload) + block.updateShape(block.hasTimeout, block.hasHeader, block.hasQuery) }, mutationToDom: function () { let container = Blockly.utils.xml.createElement('mutation') container.setAttribute('hasTimeout', this.hasTimeout) container.setAttribute('hasHeader', this.hasHeader) container.setAttribute('hasQuery', this.hasQuery) - container.setAttribute('hasPayload', this.hasPayload) return container }, domToMutation: function (xmlElement) { let hasTimeout = xmlElement.getAttribute('hasTimeout') === 'true' let hasHeader = xmlElement.getAttribute('hasHeader') === 'true' let hasQuery = xmlElement.getAttribute('hasQuery') === 'true' - let hasPayload = xmlElement.getAttribute('hasPayload') === 'true' - this.updateShape(hasTimeout, hasHeader, hasQuery, hasPayload) + this.updateShape(hasTimeout, hasHeader, hasQuery) } } From 26b98acbba72c6d353e9ec29a9d01cbac4813f6a Mon Sep 17 00:00:00 2001 From: Mark Herwege Date: Tue, 30 Jul 2024 09:06:59 +0200 Subject: [PATCH 11/14] rename variables Signed-off-by: Mark Herwege --- .../assets/definitions/blockly/blocks-http.js | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-http.js b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-http.js index 931ea956b4..da6dce0228 100644 --- a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-http.js +++ b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-http.js @@ -117,18 +117,18 @@ export default function (f7, isGraalJs) { if (['HttpPostRequest', 'HttpPutRequest'].includes(this.requestType)) { let payloadInput = this.getInput('payload') - let hasContent = (this.contentType !== 'none') - let isJSONContent = (!this.contentType || (this.contentType === 'application/json')) - let isEncodedContent = (this.contentType === 'application/x-www-form-urlencoded') - if (!hasContent && payloadInput && (payloadInput.type === Blockly.inputs.inputTypes.VALUE)) { + let hasPayload = (this.contentType !== 'none') + let isJSONPayload = (!this.contentType || (this.contentType === 'application/json')) + let isEncodedPayload = (this.contentType === 'application/x-www-form-urlencoded') + if (!hasPayload && payloadInput && (payloadInput.type === Blockly.inputs.inputTypes.VALUE)) { this.removePayloadInput() payloadInput = null - } else if (hasContent && payloadInput && (payloadInput.type === Blockly.inputs.inputTypes.DUMMY)) { + } else if (hasPayload && payloadInput && (payloadInput.type === Blockly.inputs.inputTypes.DUMMY)) { this.removePayloadInput() payloadInput = null } if (!payloadInput) { - if (!hasContent) { + if (!hasPayload) { payloadInput = this.appendDummyInput('payload') } else { payloadInput = this.appendValueInput('payload') @@ -149,14 +149,14 @@ export default function (f7, isGraalJs) { this.setFieldValue(this.contentType, 'contentType') } } - if (hasContent) { - if (isEncodedContent) { + if (hasPayload) { + if (isEncodedPayload) { payloadInput.setShadowDom(null) payloadInput.setCheck(['Dictionary', 'String']) this.addDictShadowBlock(payloadInput, 'param') } else { payloadInput.setShadowDom(null) - if (isJSONContent) { + if (isJSONPayload) { payloadInput.setCheck(null) } else { payloadInput.setCheck('String') From ef932ed89e3d7ae9e68b40e2827fde2616c1c68e Mon Sep 17 00:00:00 2001 From: Mark Herwege Date: Tue, 30 Jul 2024 09:11:33 +0200 Subject: [PATCH 12/14] variable simplification Signed-off-by: Mark Herwege --- .../web/src/assets/definitions/blockly/blocks-http.js | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-http.js b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-http.js index da6dce0228..ef2cfbf76a 100644 --- a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-http.js +++ b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-http.js @@ -118,8 +118,6 @@ export default function (f7, isGraalJs) { if (['HttpPostRequest', 'HttpPutRequest'].includes(this.requestType)) { let payloadInput = this.getInput('payload') let hasPayload = (this.contentType !== 'none') - let isJSONPayload = (!this.contentType || (this.contentType === 'application/json')) - let isEncodedPayload = (this.contentType === 'application/x-www-form-urlencoded') if (!hasPayload && payloadInput && (payloadInput.type === Blockly.inputs.inputTypes.VALUE)) { this.removePayloadInput() payloadInput = null @@ -150,16 +148,16 @@ export default function (f7, isGraalJs) { } } if (hasPayload) { - if (isEncodedPayload) { + if (this.contentType === 'application/x-www-form-urlencoded') { payloadInput.setShadowDom(null) payloadInput.setCheck(['Dictionary', 'String']) this.addDictShadowBlock(payloadInput, 'param') } else { payloadInput.setShadowDom(null) - if (isJSONPayload) { - payloadInput.setCheck(null) - } else { + if (this.contentType && (this.contentType !== 'application/json')) { payloadInput.setCheck('String') + } else { + payloadInput.setCheck(null) } payloadInput.setShadowDom(Blockly.utils.xml.textToDom('payload')) } From 958262eb73ae1bdc7daf141616d7740cb77fcc3a Mon Sep 17 00:00:00 2001 From: Mark Herwege Date: Tue, 30 Jul 2024 09:14:22 +0200 Subject: [PATCH 13/14] simplify code Signed-off-by: Mark Herwege --- .../web/src/assets/definitions/blockly/blocks-http.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-http.js b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-http.js index ef2cfbf76a..ae0e56e183 100644 --- a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-http.js +++ b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-http.js @@ -148,12 +148,11 @@ export default function (f7, isGraalJs) { } } if (hasPayload) { + payloadInput.setShadowDom(null) if (this.contentType === 'application/x-www-form-urlencoded') { - payloadInput.setShadowDom(null) payloadInput.setCheck(['Dictionary', 'String']) this.addDictShadowBlock(payloadInput, 'param') } else { - payloadInput.setShadowDom(null) if (this.contentType && (this.contentType !== 'application/json')) { payloadInput.setCheck('String') } else { From 9330a108f8eb21ea625d148b76fb39f2a56954d2 Mon Sep 17 00:00:00 2001 From: Mark Herwege Date: Mon, 19 Aug 2024 08:09:46 +0200 Subject: [PATCH 14/14] fix imgQuery field identifier Signed-off-by: Mark Herwege --- .../web/src/assets/definitions/blockly/blocks-http.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-http.js b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-http.js index ae0e56e183..7b84c4b824 100644 --- a/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-http.js +++ b/bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-http.js @@ -29,7 +29,7 @@ export default function (f7, isGraalJs) { .setCheck('String') .appendField(imageTimeoutField, 'imgTimeout') .appendField(imageHeaderField, 'imgHeader') - .appendField(imageQueryField, 'imgHeader') + .appendField(imageQueryField, 'imgQuery') .appendField('send', 'methodField') .appendField(new Blockly.FieldDropdown([ ['HttpGetRequest', 'HttpGetRequest'],