Replace extension delimeter with '_'

This commit is contained in:
Andrew Sliwinski 2018-04-20 07:54:02 -04:00
parent 47a2d76a14
commit f86cad3305
5 changed files with 74 additions and 39 deletions
src

View file

@ -471,7 +471,7 @@ class Runtime extends EventEmitter {
* @private * @private
*/ */
_makeExtensionMenuId (menuName, extensionId) { _makeExtensionMenuId (menuName, extensionId) {
return `${extensionId}.menu.${escapeHtml(menuName)}`; return `${extensionId}_menu_${escapeHtml(menuName)}`;
} }
/** /**
@ -625,7 +625,7 @@ class Runtime extends EventEmitter {
* @private * @private
*/ */
_convertForScratchBlocks (blockInfo, categoryInfo) { _convertForScratchBlocks (blockInfo, categoryInfo) {
const extendedOpcode = `${categoryInfo.id}.${blockInfo.opcode}`; const extendedOpcode = `${categoryInfo.id}_${blockInfo.opcode}`;
const blockJSON = { const blockJSON = {
type: extendedOpcode, type: extendedOpcode,

View file

@ -188,7 +188,7 @@ class ExtensionManager {
_registerInternalExtension (extensionObject) { _registerInternalExtension (extensionObject) {
const extensionInfo = extensionObject.getInfo(); const extensionInfo = extensionObject.getInfo();
const fakeWorkerId = this.nextExtensionWorker++; const fakeWorkerId = this.nextExtensionWorker++;
const serviceName = `extension.${fakeWorkerId}.${extensionInfo.id}`; const serviceName = `extension_${fakeWorkerId}_${extensionInfo.id}`;
return dispatch.setService(serviceName, extensionObject) return dispatch.setService(serviceName, extensionObject)
.then(() => { .then(() => {
dispatch.call('extensions', 'registerExtensionService', serviceName); dispatch.call('extensions', 'registerExtensionService', serviceName);
@ -229,7 +229,9 @@ class ExtensionManager {
*/ */
_prepareExtensionInfo (serviceName, extensionInfo) { _prepareExtensionInfo (serviceName, extensionInfo) {
extensionInfo = Object.assign({}, extensionInfo); extensionInfo = Object.assign({}, extensionInfo);
extensionInfo.id = this._sanitizeID(extensionInfo.id); if (!/^[a-z0-9]+$/i.test(extensionInfo.id)) {
throw new Error('Invalid extension id');
}
extensionInfo.name = extensionInfo.name || extensionInfo.id; extensionInfo.name = extensionInfo.name || extensionInfo.id;
extensionInfo.blocks = extensionInfo.blocks || []; extensionInfo.blocks = extensionInfo.blocks || [];
extensionInfo.targetTypes = extensionInfo.targetTypes || []; extensionInfo.targetTypes = extensionInfo.targetTypes || [];

View file

@ -19,6 +19,21 @@ const {loadCostume} = require('../import/load-costume.js');
const {loadSound} = require('../import/load-sound.js'); const {loadSound} = require('../import/load-sound.js');
const {deserializeCostume, deserializeSound} = require('./deserialize-assets.js'); const {deserializeCostume, deserializeSound} = require('./deserialize-assets.js');
// Constants used during deserialization of an SB3 file
const CORE_EXTENSIONS = [
'argument',
'control',
'data',
'event',
'looks',
'math',
'motion',
'operator',
'procedures',
'sensing',
'sound'
];
/** /**
* Convert a Scratch 2.0 procedure string (e.g., "my_procedure %s %b %n") * Convert a Scratch 2.0 procedure string (e.g., "my_procedure %s %b %n")
* into an argument map. This allows us to provide the expected inputs * into an argument map. This allows us to provide the expected inputs
@ -501,12 +516,14 @@ const parseBlock = function (sb2block, addBroadcastMsg, getVariableId, extension
return; return;
} }
const oldOpcode = sb2block[0]; const oldOpcode = sb2block[0];
// If the block is from an extension, record it. // If the block is from an extension, record it.
const dotIndex = blockMetadata.opcode.indexOf('.'); const index = blockMetadata.opcode.indexOf('_');
if (dotIndex >= 0) { const prefix = blockMetadata.opcode.substring(0, index);
const extension = blockMetadata.opcode.substring(0, dotIndex); if (CORE_EXTENSIONS.indexOf(prefix) === -1) {
extensions.extensionIDs.add(extension); extensions.extensionIDs.add(prefix);
} }
// Block skeleton. // Block skeleton.
const activeBlock = { const activeBlock = {
id: uid(), // Generate a new block unique ID. id: uid(), // Generate a new block unique ID.

View file

@ -420,11 +420,11 @@ const specMap = {
] ]
}, },
'playDrum': { 'playDrum': {
opcode: 'music.playDrumForBeats', opcode: 'music_playDrumForBeats',
argMap: [ argMap: [
{ {
type: 'input', type: 'input',
inputOp: 'music.menu.DRUM', inputOp: 'music_menu_DRUM',
inputName: 'DRUM' inputName: 'DRUM'
}, },
{ {
@ -435,7 +435,7 @@ const specMap = {
] ]
}, },
'rest:elapsed:from:': { 'rest:elapsed:from:': {
opcode: 'music.restForBeats', opcode: 'music_restForBeats',
argMap: [ argMap: [
{ {
type: 'input', type: 'input',
@ -445,7 +445,7 @@ const specMap = {
] ]
}, },
'noteOn:duration:elapsed:from:': { 'noteOn:duration:elapsed:from:': {
opcode: 'music.playNoteForBeats', opcode: 'music_playNoteForBeats',
argMap: [ argMap: [
{ {
type: 'input', type: 'input',
@ -460,11 +460,11 @@ const specMap = {
] ]
}, },
'instrument:': { 'instrument:': {
opcode: 'music.setInstrument', opcode: 'music_setInstrument',
argMap: [ argMap: [
{ {
type: 'input', type: 'input',
inputOp: 'music.menu.INSTRUMENT', inputOp: 'music_menu_INSTRUMENT',
inputName: 'INSTRUMENT' inputName: 'INSTRUMENT'
} }
] ]
@ -495,7 +495,7 @@ const specMap = {
] ]
}, },
'changeTempoBy:': { 'changeTempoBy:': {
opcode: 'music.changeTempo', opcode: 'music_changeTempo',
argMap: [ argMap: [
{ {
type: 'input', type: 'input',
@ -505,7 +505,7 @@ const specMap = {
] ]
}, },
'setTempoTo:': { 'setTempoTo:': {
opcode: 'music.setTempo', opcode: 'music_setTempo',
argMap: [ argMap: [
{ {
type: 'input', type: 'input',
@ -515,32 +515,32 @@ const specMap = {
] ]
}, },
'tempo': { 'tempo': {
opcode: 'music.getTempo', opcode: 'music_getTempo',
argMap: [ argMap: [
] ]
}, },
'clearPenTrails': { 'clearPenTrails': {
opcode: 'pen.clear', opcode: 'pen_clear',
argMap: [ argMap: [
] ]
}, },
'stampCostume': { 'stampCostume': {
opcode: 'pen.stamp', opcode: 'pen_stamp',
argMap: [ argMap: [
] ]
}, },
'putPenDown': { 'putPenDown': {
opcode: 'pen.penDown', opcode: 'pen_penDown',
argMap: [ argMap: [
] ]
}, },
'putPenUp': { 'putPenUp': {
opcode: 'pen.penUp', opcode: 'pen_penUp',
argMap: [ argMap: [
] ]
}, },
'penColor:': { 'penColor:': {
opcode: 'pen.setPenColorToColor', opcode: 'pen_setPenColorToColor',
argMap: [ argMap: [
{ {
type: 'input', type: 'input',
@ -550,7 +550,7 @@ const specMap = {
] ]
}, },
'changePenHueBy:': { 'changePenHueBy:': {
opcode: 'pen.changePenHueBy', opcode: 'pen_changePenHueBy',
argMap: [ argMap: [
{ {
type: 'input', type: 'input',
@ -560,7 +560,7 @@ const specMap = {
] ]
}, },
'setPenHueTo:': { 'setPenHueTo:': {
opcode: 'pen.setPenHueToNumber', opcode: 'pen_setPenHueToNumber',
argMap: [ argMap: [
{ {
type: 'input', type: 'input',
@ -570,7 +570,7 @@ const specMap = {
] ]
}, },
'changePenShadeBy:': { 'changePenShadeBy:': {
opcode: 'pen.changePenShadeBy', opcode: 'pen_changePenShadeBy',
argMap: [ argMap: [
{ {
type: 'input', type: 'input',
@ -580,7 +580,7 @@ const specMap = {
] ]
}, },
'setPenShadeTo:': { 'setPenShadeTo:': {
opcode: 'pen.setPenShadeToNumber', opcode: 'pen_setPenShadeToNumber',
argMap: [ argMap: [
{ {
type: 'input', type: 'input',
@ -590,7 +590,7 @@ const specMap = {
] ]
}, },
'changePenSizeBy:': { 'changePenSizeBy:': {
opcode: 'pen.changePenSizeBy', opcode: 'pen_changePenSizeBy',
argMap: [ argMap: [
{ {
type: 'input', type: 'input',
@ -600,7 +600,7 @@ const specMap = {
] ]
}, },
'penSize:': { 'penSize:': {
opcode: 'pen.setPenSizeTo', opcode: 'pen_setPenSizeTo',
argMap: [ argMap: [
{ {
type: 'input', type: 'input',
@ -610,16 +610,16 @@ const specMap = {
] ]
}, },
'senseVideoMotion': { 'senseVideoMotion': {
opcode: 'videoSensing.videoOn', opcode: 'videoSensing_videoOn',
argMap: [ argMap: [
{ {
type: 'input', type: 'input',
inputOp: 'videoSensing.menu.ATTRIBUTE', inputOp: 'videoSensing_menu_ATTRIBUTE',
inputName: 'ATTRIBUTE' inputName: 'ATTRIBUTE'
}, },
{ {
type: 'input', type: 'input',
inputOp: 'videoSensing.menu.SUBJECT', inputOp: 'videoSensing_menu_SUBJECT',
inputName: 'SUBJECT' inputName: 'SUBJECT'
} }
] ]
@ -655,7 +655,7 @@ const specMap = {
'whenSensorGreaterThan': ([, sensor]) => { 'whenSensorGreaterThan': ([, sensor]) => {
if (sensor === 'video motion') { if (sensor === 'video motion') {
return { return {
opcode: 'videoSensing.whenMotionGreaterThan', opcode: 'videoSensing_whenMotionGreaterThan',
argMap: [ argMap: [
// skip the first arg, since we converted to a video specific sensing block // skip the first arg, since we converted to a video specific sensing block
{}, {},
@ -980,17 +980,17 @@ const specMap = {
// ] // ]
// }, // },
'setVideoState': { 'setVideoState': {
opcode: 'videoSensing.videoToggle', opcode: 'videoSensing_videoToggle',
argMap: [ argMap: [
{ {
type: 'input', type: 'input',
inputOp: 'videoSensing.menu.VIDEO_STATE', inputOp: 'videoSensing_menu.VIDEO_STATE',
inputName: 'VIDEO_STATE' inputName: 'VIDEO_STATE'
} }
] ]
}, },
'setVideoTransparency': { 'setVideoTransparency': {
opcode: 'videoSensing.setVideoTransparency', opcode: 'videoSensing_setVideoTransparency',
argMap: [ argMap: [
{ {
type: 'input', type: 'input',

View file

@ -33,6 +33,21 @@ const INPUT_BLOCK_NO_SHADOW = 2; // no shadow
const INPUT_DIFF_BLOCK_SHADOW = 3; // obscured shadow const INPUT_DIFF_BLOCK_SHADOW = 3; // obscured shadow
// There shouldn't be a case where block is null, but shadow is present... // There shouldn't be a case where block is null, but shadow is present...
// Constants used during deserialization of an SB3 file
const CORE_EXTENSIONS = [
'argument',
'control',
'data',
'event',
'looks',
'math',
'motion',
'operator',
'procedures',
'sensing',
'sound'
];
// Constants referring to 'primitive' blocks that are usually shadows, // Constants referring to 'primitive' blocks that are usually shadows,
// or in the case of variables and lists, appear quite often in projects // or in the case of variables and lists, appear quite often in projects
// math_number // math_number
@ -700,10 +715,11 @@ const parseScratchObject = function (object, runtime, extensions, zip) {
const blockJSON = object.blocks[blockId]; const blockJSON = object.blocks[blockId];
blocks.createBlock(blockJSON); blocks.createBlock(blockJSON);
const dotIndex = blockJSON.opcode.indexOf('.'); // If the block is from an extension, record it.
if (dotIndex >= 0) { const index = blockJSON.opcode.indexOf('_');
const extensionId = blockJSON.opcode.substring(0, dotIndex); const prefix = blockJSON.opcode.substring(0, index);
extensions.extensionIDs.add(extensionId); if (CORE_EXTENSIONS.indexOf(prefix) === -1) {
extensions.extensionIDs.add(prefix);
} }
} }
} }