From 833d33355c07897cd9b22e96a76e281b71be36f3 Mon Sep 17 00:00:00 2001 From: Christopher Willis-Ford Date: Fri, 19 Apr 2019 12:28:19 -0700 Subject: [PATCH] retrieve blockInfo from args when isDynamic is set --- src/engine/mutation-adapter.js | 4 ++ src/extension-support/extension-manager.js | 46 ++++++++++++++-------- 2 files changed, 34 insertions(+), 16 deletions(-) diff --git a/src/engine/mutation-adapter.js b/src/engine/mutation-adapter.js index d1984d30e..8cfac7634 100644 --- a/src/engine/mutation-adapter.js +++ b/src/engine/mutation-adapter.js @@ -13,6 +13,10 @@ const mutatorTagToObject = function (dom) { for (const prop in dom.attribs) { if (prop === 'xmlns') continue; obj[prop] = decodeHtml(dom.attribs[prop]); + if (prop === 'blockinfo') { + obj.blockInfo = JSON.parse(obj.blockinfo); + delete obj.blockinfo; + } } for (let i = 0; i < dom.children.length; i++) { obj.children.push( diff --git a/src/extension-support/extension-manager.js b/src/extension-support/extension-manager.js index e70929b63..a2f89aae0 100644 --- a/src/extension-support/extension-manager.js +++ b/src/extension-support/extension-manager.js @@ -390,26 +390,40 @@ class ExtensionManager { log.warn(`Ignoring opcode "${blockInfo.opcode}" for button with text: ${blockInfo.text}`); } break; - default: - if (blockInfo.opcode) { - const funcName = blockInfo.func ? this._sanitizeID(blockInfo.func) : blockInfo.opcode; - - // Avoid promise latency unless necessary - if (dispatch._isRemoteService(serviceName)) { - blockInfo.func = (args, util) => dispatch.call(serviceName, funcName, args, util, blockInfo); - } else { - const serviceObject = dispatch.services[serviceName]; - if (!serviceObject[funcName]) { - // The function might show up later as a dynamic property of the service object - log.warn(`Could not find extension block function called ${funcName}`); - } - blockInfo.func = (args, util) => serviceObject[funcName](args, util, blockInfo); - } - } else { + default: { + if (!blockInfo.opcode) { throw new Error('Missing opcode for block'); } + + const funcName = blockInfo.func ? this._sanitizeID(blockInfo.func) : blockInfo.opcode; + + const getBlockInfo = blockInfo.isDynamic ? + args => args && args.mutation && args.mutation.blockInfo : + () => blockInfo; + const callBlockFunc = (() => { + if (dispatch._isRemoteService(serviceName)) { + return (args, util, realBlockInfo) => + dispatch.call(serviceName, funcName, args, util, realBlockInfo); + } + + // avoid promise latency if we can call direct + const serviceObject = dispatch.services[serviceName]; + if (!serviceObject[funcName]) { + // The function might show up later as a dynamic property of the service object + log.warn(`Could not find extension block function called ${funcName}`); + } + return (args, util, realBlockInfo) => + serviceObject[funcName](args, util, realBlockInfo); + })(); + + blockInfo.func = (args, util) => { + const realBlockInfo = getBlockInfo(args); + // TODO: filter args using the keys of realBlockInfo.arguments? maybe only if sandboxed? + return callBlockFunc(args, util, realBlockInfo); + }; break; } + } return blockInfo; }