mirror of
https://github.com/scratchfoundation/scratch-vm.git
synced 2025-08-28 22:30:40 -04:00
Adding support for dynamic menus in extensions.
This commit is contained in:
parent
229cd7a50c
commit
b6bb92d8f6
2 changed files with 42 additions and 15 deletions
|
@ -551,22 +551,23 @@ class Runtime extends EventEmitter {
|
||||||
*/
|
*/
|
||||||
_buildMenuForScratchBlocks (menuName, menuItems, categoryInfo) {
|
_buildMenuForScratchBlocks (menuName, menuItems, categoryInfo) {
|
||||||
const menuId = this._makeExtensionMenuId(menuName, categoryInfo.id);
|
const menuId = this._makeExtensionMenuId(menuName, categoryInfo.id);
|
||||||
|
var options = null;
|
||||||
/** @TODO: support dynamic menus when 'menuItems' is a method name string (see extension spec) */
|
if (typeof menuItems === 'function') {
|
||||||
if (typeof menuItems === 'string') {
|
options = function () {
|
||||||
throw new Error(`Dynamic extension menus are not yet supported. Menu name: ${menuName}`);
|
return menuItems();
|
||||||
}
|
|
||||||
const options = menuItems.map(item => {
|
|
||||||
switch (typeof item) {
|
|
||||||
case 'string':
|
|
||||||
return [item, item];
|
|
||||||
case 'object':
|
|
||||||
return [item.text, item.value];
|
|
||||||
default:
|
|
||||||
throw new Error(`Can't interpret menu item: ${item}`);
|
|
||||||
}
|
}
|
||||||
});
|
} else {
|
||||||
|
options = menuItems.map(item => {
|
||||||
|
switch (typeof item) {
|
||||||
|
case 'string':
|
||||||
|
return [item, item];
|
||||||
|
case 'object':
|
||||||
|
return [item.text, item.value];
|
||||||
|
default:
|
||||||
|
throw new Error(`Can't interpret menu item: ${item}`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
json: {
|
json: {
|
||||||
message0: '%1',
|
message0: '%1',
|
||||||
|
|
|
@ -242,8 +242,34 @@ class ExtensionManager {
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}, []);
|
}, []);
|
||||||
|
extensionInfo.menus = extensionInfo.menus || [];
|
||||||
|
extensionInfo.menus = this._prepareMenuInfo(serviceName, extensionInfo.menus);
|
||||||
return extensionInfo;
|
return extensionInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare extension menus. e.g. setup binding for dynamic menu functions.
|
||||||
|
* @param {string} serviceName - the name of the service hosting this extension block
|
||||||
|
* @param {Array.<MenuInfo>} menuInfo - the menu defined by the extension.
|
||||||
|
* @returns {Array.<MenuInfo>} - a menuInfo object with all preprocessing done.
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
_prepareMenuInfo (serviceName, menus) {
|
||||||
|
var menuNames = Object.getOwnPropertyNames(menus);
|
||||||
|
for (let i = 0; i < menuNames.length; i++) {
|
||||||
|
var item = menuNames[i];
|
||||||
|
// If the value is a string, it should be the name of a function in the
|
||||||
|
// extension object to call to populate the menu whenever it is opened.
|
||||||
|
// Set up the binding for the function object here so
|
||||||
|
// we can use it later when converting the menu for Scratch Blocks.
|
||||||
|
if (typeof menus[item] === 'string') {
|
||||||
|
const serviceObject = dispatch.services[serviceName];
|
||||||
|
const menuFunc = serviceObject[menus[item]].bind(serviceObject);
|
||||||
|
menus[item] = menuFunc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return menus;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Apply defaults for optional block fields.
|
* Apply defaults for optional block fields.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue