diff --git a/src/engine/runtime.js b/src/engine/runtime.js index 85babe5d9..4fb2c25b2 100644 --- a/src/engine/runtime.js +++ b/src/engine/runtime.js @@ -48,9 +48,8 @@ const ArgumentTypeMap = (() => { shadowType: 'text', fieldType: 'TEXT' }; - // @TODO: talk to Rachel & co. to figure out what goes here. Make it OK to not have a field. Add `check` support. map[ArgumentType.BOOLEAN] = { - shadowType: '' + check: 'Boolean' }; return map; })(); @@ -400,8 +399,7 @@ class Runtime extends EventEmitter { * @private */ _makeExtensionMenuId (menuName, extensionId) { - /** @TODO: protect against XML characters in menu name */ - return `${extensionId}.menu.${menuName}`; + return `${extensionId}.menu.${escapeHtml(menuName)}`; } /** @@ -515,36 +513,47 @@ class Runtime extends EventEmitter { // Sanitize the placeholder to ensure valid XML placeholder = placeholder.replace(/[<"&]/, '_'); - blockJSON.args0.push({ + const argJSON = { type: 'input_value', name: placeholder - }); - - // scratch-blocks uses 1-based argument indexing - const argNum = blockJSON.args0.length; - argsMap[placeholder] = argNum; + }; const argInfo = blockInfo.arguments[placeholder] || {}; const argTypeInfo = ArgumentTypeMap[argInfo.type] || {}; const defaultValue = (typeof argInfo.defaultValue === 'undefined' ? '' : argInfo.defaultValue.toString()); + if (argTypeInfo.check) { + argJSON.check = argTypeInfo.check; + } + const shadowType = (argInfo.menu ? this._makeExtensionMenuId(argInfo.menu, categoryInfo.id) : argTypeInfo.shadowType); const fieldType = argInfo.menu || argTypeInfo.fieldType; // is the ScratchBlocks name for a block input. - // The is a placeholder for a reporter and is visible when there's no reporter in this input. - inputList.push(``); + inputList.push(``); - // is a text field that the user can type into. Some shadows, like the color picker, don't allow - // text input and therefore don't need a field element. - if (fieldType) { - inputList.push(`${defaultValue}`); + // The is a placeholder for a reporter and is visible when there's no reporter in this input. + // Boolean inputs don't need to specify a shadow in the XML. + if (shadowType) { + inputList.push(``); + + // is a text field that the user can type into. Some shadows, like the color picker, don't allow + // text input and therefore don't need a field element. + if (fieldType) { + inputList.push(`${defaultValue}`); + } + + inputList.push(''); } - inputList.push(''); + inputList.push(''); + // scratch-blocks uses 1-based argument indexing + blockJSON.args0.push(argJSON); + const argNum = blockJSON.args0.length; + argsMap[placeholder] = argNum; return `%${argNum}`; });