diff --git a/blockly_uncompressed.js b/blockly_uncompressed.js index 25c8984d0..bfc627411 100644 --- a/blockly_uncompressed.js +++ b/blockly_uncompressed.js @@ -39,13 +39,13 @@ goog.addDependency('../../core/components/tree/treenode.js', ['Blockly.tree.Tree goog.addDependency('../../core/connection.js', ['Blockly.Connection'], ['Blockly.Events', 'Blockly.Events.BlockMove', 'Blockly.Xml'], {}); goog.addDependency('../../core/connection_db.js', ['Blockly.ConnectionDB'], ['Blockly.RenderedConnection'], {}); goog.addDependency('../../core/constants.js', ['Blockly.constants'], [], {}); -goog.addDependency('../../core/contextmenu.js', ['Blockly.ContextMenu'], ['Blockly.Events', 'Blockly.Events.BlockCreate', 'Blockly.Menu', 'Blockly.MenuItem', 'Blockly.Msg', 'Blockly.Xml', 'Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.dom', 'Blockly.utils.userAgent'], {}); +goog.addDependency('../../core/contextmenu.js', ['Blockly.ContextMenu'], ['Blockly.Events', 'Blockly.Events.BlockCreate', 'Blockly.Menu', 'Blockly.MenuItem', 'Blockly.Msg', 'Blockly.Xml', 'Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.Rect', 'Blockly.utils.dom', 'Blockly.utils.userAgent'], {}); goog.addDependency('../../core/css.js', ['Blockly.Css'], [], {'lang': 'es5'}); goog.addDependency('../../core/dropdowndiv.js', ['Blockly.DropDownDiv'], ['Blockly.utils.dom', 'Blockly.utils.math', 'Blockly.utils.style'], {}); goog.addDependency('../../core/events.js', ['Blockly.Events'], ['Blockly.utils'], {}); goog.addDependency('../../core/events_abstract.js', ['Blockly.Events.Abstract'], ['Blockly.Events'], {}); goog.addDependency('../../core/extensions.js', ['Blockly.Extensions'], ['Blockly.utils'], {}); -goog.addDependency('../../core/field.js', ['Blockly.Field'], ['Blockly.Events', 'Blockly.Events.BlockChange', 'Blockly.Gesture', 'Blockly.utils', 'Blockly.utils.Size', 'Blockly.utils.dom', 'Blockly.utils.style', 'Blockly.utils.userAgent'], {'lang': 'es5'}); +goog.addDependency('../../core/field.js', ['Blockly.Field'], ['Blockly.Events', 'Blockly.Events.BlockChange', 'Blockly.Gesture', 'Blockly.utils', 'Blockly.utils.Rect', 'Blockly.utils.Size', 'Blockly.utils.dom', 'Blockly.utils.style', 'Blockly.utils.userAgent'], {'lang': 'es5'}); goog.addDependency('../../core/field_angle.js', ['Blockly.FieldAngle'], ['Blockly.Css', 'Blockly.DropDownDiv', 'Blockly.FieldTextInput', 'Blockly.fieldRegistry', 'Blockly.utils.dom', 'Blockly.utils.math', 'Blockly.utils.object', 'Blockly.utils.userAgent'], {}); goog.addDependency('../../core/field_checkbox.js', ['Blockly.FieldCheckbox'], ['Blockly.Events', 'Blockly.Events.BlockChange', 'Blockly.Field', 'Blockly.fieldRegistry', 'Blockly.utils.Size', 'Blockly.utils.dom', 'Blockly.utils.object'], {}); goog.addDependency('../../core/field_colour.js', ['Blockly.FieldColour'], ['Blockly.Css', 'Blockly.DropDownDiv', 'Blockly.Events', 'Blockly.Events.BlockChange', 'Blockly.Field', 'Blockly.fieldRegistry', 'Blockly.navigation', 'Blockly.utils.IdGenerator', 'Blockly.utils.KeyCodes', 'Blockly.utils.Size', 'Blockly.utils.aria', 'Blockly.utils.colour', 'Blockly.utils.dom', 'Blockly.utils.object'], {}); @@ -72,13 +72,13 @@ goog.addDependency('../../core/input.js', ['Blockly.Input'], ['Blockly.Connectio goog.addDependency('../../core/insertion_marker_manager.js', ['Blockly.InsertionMarkerManager'], ['Blockly.Events', 'Blockly.blockAnimations'], {'lang': 'es5'}); goog.addDependency('../../core/interfaces/i_accessibility.js', ['Blockly.IASTNodeLocation', 'Blockly.IASTNodeLocationSvg', 'Blockly.IASTNodeLocationWithBlock', 'Blockly.IBlocklyActionable'], [], {}); goog.addDependency('../../core/interfaces/i_bounded_element.js', ['Blockly.IBoundedElement'], [], {}); -goog.addDependency('../../core/interfaces/i_copyable.js', ['Blockly.ICopyable'], ['Blockly.ISelectable'], {}); +goog.addDependency('../../core/interfaces/i_copyable.js', ['Blockly.ICopyable'], [], {}); goog.addDependency('../../core/interfaces/i_deletable.js', ['Blockly.IDeletable'], [], {}); goog.addDependency('../../core/interfaces/i_deletearea.js', ['Blockly.IDeleteArea'], [], {}); -goog.addDependency('../../core/interfaces/i_disposable.js', ['Blockly.IDisposable'], ['Blockly.Inheritance'], {}); goog.addDependency('../../core/interfaces/i_movable.js', ['Blockly.IMovable'], [], {}); goog.addDependency('../../core/interfaces/i_registrable.js', ['Blockly.IRegistrable'], [], {}); -goog.addDependency('../../core/interfaces/i_selectable.js', ['Blockly.ISelectable'], ['Blockly.IDeletable', 'Blockly.IMovable'], {}); +goog.addDependency('../../core/interfaces/i_selectable.js', ['Blockly.ISelectable'], [], {}); +goog.addDependency('../../core/interfaces/i_toolbox.js', ['Blockly.IToolbox'], [], {}); goog.addDependency('../../core/keyboard_nav/action.js', ['Blockly.Action'], [], {}); goog.addDependency('../../core/keyboard_nav/ast_node.js', ['Blockly.ASTNode'], ['Blockly.utils.Coordinate'], {'lang': 'es5'}); goog.addDependency('../../core/keyboard_nav/basic_cursor.js', ['Blockly.BasicCursor'], ['Blockly.ASTNode', 'Blockly.Cursor'], {'lang': 'es5'}); @@ -94,7 +94,7 @@ goog.addDependency('../../core/menuitem.js', ['Blockly.MenuItem'], ['Blockly.uti goog.addDependency('../../core/msg.js', ['Blockly.Msg'], ['Blockly.utils.global'], {}); goog.addDependency('../../core/mutator.js', ['Blockly.Mutator'], ['Blockly.Bubble', 'Blockly.Events', 'Blockly.Events.BlockChange', 'Blockly.Events.Ui', 'Blockly.Icon', 'Blockly.WorkspaceSvg', 'Blockly.Xml', 'Blockly.navigation', 'Blockly.utils', 'Blockly.utils.dom', 'Blockly.utils.global', 'Blockly.utils.object', 'Blockly.utils.xml'], {}); goog.addDependency('../../core/names.js', ['Blockly.Names'], ['Blockly.Msg'], {}); -goog.addDependency('../../core/options.js', ['Blockly.Options'], ['Blockly.Theme', 'Blockly.Themes.Classic', 'Blockly.Xml', 'Blockly.user.keyMap', 'Blockly.utils.Metrics', 'Blockly.utils.toolbox', 'Blockly.utils.userAgent'], {}); +goog.addDependency('../../core/options.js', ['Blockly.Options'], ['Blockly.Theme', 'Blockly.Themes.Classic', 'Blockly.Xml', 'Blockly.registry', 'Blockly.user.keyMap', 'Blockly.utils.Metrics', 'Blockly.utils.toolbox', 'Blockly.utils.userAgent'], {}); goog.addDependency('../../core/procedures.js', ['Blockly.Procedures'], ['Blockly.Blocks', 'Blockly.Events', 'Blockly.Events.BlockChange', 'Blockly.Field', 'Blockly.Msg', 'Blockly.Names', 'Blockly.Workspace', 'Blockly.Xml', 'Blockly.constants', 'Blockly.utils.xml'], {}); goog.addDependency('../../core/registry.js', ['Blockly.registry'], [], {}); goog.addDependency('../../core/rendered_connection.js', ['Blockly.RenderedConnection'], ['Blockly.Connection', 'Blockly.Events', 'Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.dom', 'Blockly.utils.object'], {}); @@ -138,7 +138,7 @@ goog.addDependency('../../core/renderers/zelos/path_object.js', ['Blockly.zelos. goog.addDependency('../../core/renderers/zelos/renderer.js', ['Blockly.zelos.Renderer'], ['Blockly.InsertionMarkerManager', 'Blockly.blockRendering', 'Blockly.blockRendering.Renderer', 'Blockly.utils.object', 'Blockly.zelos.ConstantProvider', 'Blockly.zelos.Drawer', 'Blockly.zelos.MarkerSvg', 'Blockly.zelos.PathObject', 'Blockly.zelos.RenderInfo'], {}); goog.addDependency('../../core/requires.js', ['Blockly.requires'], ['Blockly', 'Blockly.Comment', 'Blockly.FieldAngle', 'Blockly.FieldCheckbox', 'Blockly.FieldColour', 'Blockly.FieldDropdown', 'Blockly.FieldImage', 'Blockly.FieldLabelSerializable', 'Blockly.FieldMultilineInput', 'Blockly.FieldNumber', 'Blockly.FieldTextInput', 'Blockly.FieldVariable', 'Blockly.FlyoutButton', 'Blockly.Generator', 'Blockly.HorizontalFlyout', 'Blockly.Mutator', 'Blockly.Themes.Classic', 'Blockly.Themes.Dark', 'Blockly.Themes.Deuteranopia', 'Blockly.Themes.HighContrast', 'Blockly.Themes.Tritanopia', 'Blockly.Toolbox', 'Blockly.Trashcan', 'Blockly.VariablesDynamic', 'Blockly.VerticalFlyout', 'Blockly.Warning', 'Blockly.ZoomControls', 'Blockly.geras.Renderer', 'Blockly.thrasos.Renderer', 'Blockly.zelos.Renderer'], {}); goog.addDependency('../../core/scrollbar.js', ['Blockly.Scrollbar', 'Blockly.ScrollbarPair'], ['Blockly.Touch', 'Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.Metrics', 'Blockly.utils.dom'], {}); -goog.addDependency('../../core/theme.js', ['Blockly.Theme'], ['Blockly.utils', 'Blockly.utils.colour', 'Blockly.utils.object'], {}); +goog.addDependency('../../core/theme.js', ['Blockly.Theme'], ['Blockly.registry', 'Blockly.utils', 'Blockly.utils.colour', 'Blockly.utils.object'], {}); goog.addDependency('../../core/theme/classic.js', ['Blockly.Themes.Classic'], ['Blockly.Theme'], {}); goog.addDependency('../../core/theme/dark.js', ['Blockly.Themes.Dark'], ['Blockly.Theme'], {}); goog.addDependency('../../core/theme/deuteranopia.js', ['Blockly.Themes.Deuteranopia'], ['Blockly.Theme'], {}); @@ -147,13 +147,13 @@ goog.addDependency('../../core/theme/modern.js', ['Blockly.Themes.Modern'], ['Bl goog.addDependency('../../core/theme/tritanopia.js', ['Blockly.Themes.Tritanopia'], ['Blockly.Theme'], {}); goog.addDependency('../../core/theme/zelos.js', ['Blockly.Themes.Zelos'], ['Blockly.Theme'], {}); goog.addDependency('../../core/theme_manager.js', ['Blockly.ThemeManager'], ['Blockly.Theme'], {}); -goog.addDependency('../../core/toolbox.js', ['Blockly.Toolbox'], ['Blockly.Css', 'Blockly.Events', 'Blockly.Events.Ui', 'Blockly.Touch', 'Blockly.navigation', 'Blockly.tree.TreeControl', 'Blockly.tree.TreeNode', 'Blockly.utils', 'Blockly.utils.Rect', 'Blockly.utils.aria', 'Blockly.utils.colour', 'Blockly.utils.dom', 'Blockly.utils.object', 'Blockly.utils.toolbox'], {}); +goog.addDependency('../../core/toolbox.js', ['Blockly.Toolbox'], ['Blockly.Css', 'Blockly.Events', 'Blockly.Events.Ui', 'Blockly.Touch', 'Blockly.navigation', 'Blockly.registry', 'Blockly.tree.TreeControl', 'Blockly.tree.TreeNode', 'Blockly.utils', 'Blockly.utils.Rect', 'Blockly.utils.aria', 'Blockly.utils.colour', 'Blockly.utils.dom', 'Blockly.utils.object', 'Blockly.utils.toolbox'], {}); goog.addDependency('../../core/tooltip.js', ['Blockly.Tooltip'], ['Blockly.utils.string'], {}); goog.addDependency('../../core/touch.js', ['Blockly.Touch'], ['Blockly.utils', 'Blockly.utils.global', 'Blockly.utils.string'], {}); goog.addDependency('../../core/touch_gesture.js', ['Blockly.TouchGesture'], ['Blockly.Gesture', 'Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.object'], {}); goog.addDependency('../../core/trashcan.js', ['Blockly.Trashcan'], ['Blockly.Scrollbar', 'Blockly.Xml', 'Blockly.utils.Rect', 'Blockly.utils.dom'], {}); goog.addDependency('../../core/ui_events.js', ['Blockly.Events.Ui'], ['Blockly.Events', 'Blockly.Events.Abstract', 'Blockly.utils.object'], {}); -goog.addDependency('../../core/utils.js', ['Blockly.utils'], ['Blockly.Msg', 'Blockly.constants', 'Blockly.utils.Coordinate', 'Blockly.utils.colour', 'Blockly.utils.global', 'Blockly.utils.string', 'Blockly.utils.style', 'Blockly.utils.userAgent'], {}); +goog.addDependency('../../core/utils.js', ['Blockly.utils'], ['Blockly.Msg', 'Blockly.constants', 'Blockly.utils.Coordinate', 'Blockly.utils.Rect', 'Blockly.utils.colour', 'Blockly.utils.global', 'Blockly.utils.string', 'Blockly.utils.style', 'Blockly.utils.userAgent'], {}); goog.addDependency('../../core/utils/aria.js', ['Blockly.utils.aria'], [], {}); goog.addDependency('../../core/utils/colour.js', ['Blockly.utils.colour'], [], {}); goog.addDependency('../../core/utils/coordinate.js', ['Blockly.utils.Coordinate'], [], {}); @@ -187,7 +187,7 @@ goog.addDependency('../../core/workspace_comment_svg.js', ['Blockly.WorkspaceCom goog.addDependency('../../core/workspace_drag_surface_svg.js', ['Blockly.WorkspaceDragSurfaceSvg'], ['Blockly.utils', 'Blockly.utils.dom'], {}); goog.addDependency('../../core/workspace_dragger.js', ['Blockly.WorkspaceDragger'], ['Blockly.utils.Coordinate'], {}); goog.addDependency('../../core/workspace_events.js', ['Blockly.Events.FinishedLoading'], ['Blockly.Events', 'Blockly.Events.Ui', 'Blockly.utils.object'], {'lang': 'es5'}); -goog.addDependency('../../core/workspace_svg.js', ['Blockly.WorkspaceSvg'], ['Blockly.BlockSvg', 'Blockly.ConnectionDB', 'Blockly.Events', 'Blockly.Events.BlockCreate', 'Blockly.Gesture', 'Blockly.Grid', 'Blockly.MarkerManager', 'Blockly.Msg', 'Blockly.Options', 'Blockly.ThemeManager', 'Blockly.Themes.Classic', 'Blockly.TouchGesture', 'Blockly.Workspace', 'Blockly.WorkspaceAudio', 'Blockly.WorkspaceDragSurfaceSvg', 'Blockly.Xml', 'Blockly.blockRendering', 'Blockly.constants', 'Blockly.navigation', 'Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.Metrics', 'Blockly.utils.Rect', 'Blockly.utils.dom', 'Blockly.utils.object', 'Blockly.utils.toolbox'], {}); +goog.addDependency('../../core/workspace_svg.js', ['Blockly.WorkspaceSvg'], ['Blockly.BlockSvg', 'Blockly.ConnectionDB', 'Blockly.Events', 'Blockly.Events.BlockCreate', 'Blockly.Gesture', 'Blockly.Grid', 'Blockly.MarkerManager', 'Blockly.Msg', 'Blockly.Options', 'Blockly.ThemeManager', 'Blockly.Themes.Classic', 'Blockly.TouchGesture', 'Blockly.Workspace', 'Blockly.WorkspaceAudio', 'Blockly.WorkspaceDragSurfaceSvg', 'Blockly.Xml', 'Blockly.blockRendering', 'Blockly.constants', 'Blockly.navigation', 'Blockly.registry', 'Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.Metrics', 'Blockly.utils.Rect', 'Blockly.utils.dom', 'Blockly.utils.object', 'Blockly.utils.toolbox'], {}); goog.addDependency('../../core/ws_comment_events.js', ['Blockly.Events.CommentBase', 'Blockly.Events.CommentChange', 'Blockly.Events.CommentCreate', 'Blockly.Events.CommentDelete', 'Blockly.Events.CommentMove'], ['Blockly.Events', 'Blockly.Events.Abstract', 'Blockly.utils.Coordinate', 'Blockly.utils.object', 'Blockly.utils.xml'], {}); goog.addDependency('../../core/xml.js', ['Blockly.Xml'], ['Blockly.Events', 'Blockly.Events.BlockCreate', 'Blockly.Events.FinishedLoading', 'Blockly.Events.VarCreate', 'Blockly.utils', 'Blockly.utils.dom', 'Blockly.utils.global', 'Blockly.utils.xml'], {}); goog.addDependency('../../core/zoom_controls.js', ['Blockly.ZoomControls'], ['Blockly.Css', 'Blockly.Scrollbar', 'Blockly.Touch', 'Blockly.utils.dom'], {'lang': 'es5'}); diff --git a/core/options.js b/core/options.js index a9e76ff8c..75151b104 100644 --- a/core/options.js +++ b/core/options.js @@ -14,7 +14,9 @@ goog.provide('Blockly.Options'); goog.require('Blockly.Theme'); goog.require('Blockly.Themes.Classic'); +goog.require('Blockly.registry'); goog.require('Blockly.user.keyMap'); +goog.require('Blockly.utils.IdGenerator'); goog.require('Blockly.utils.Metrics'); goog.require('Blockly.utils.toolbox'); goog.require('Blockly.utils.userAgent'); @@ -316,10 +318,14 @@ Blockly.Options.parseGridOptions_ = function(options) { */ Blockly.Options.parseThemeOptions_ = function(options) { var theme = options['theme'] || Blockly.Themes.Classic; - if (theme instanceof Blockly.Theme) { + if (typeof theme == 'string') { + return /** @type {!Blockly.Theme} */ ( + Blockly.registry.getObject(Blockly.registry.Type.THEME, theme)); + } else if (theme instanceof Blockly.Theme) { return /** @type {!Blockly.Theme} */ (theme); } - return Blockly.Theme.defineTheme('builtin', theme); + return Blockly.Theme.defineTheme( + 'builtin' + Blockly.utils.IdGenerator.getNextUniqueId(), theme); }; /** diff --git a/core/registry.js b/core/registry.js index a9d258ffc..ec7224c2c 100644 --- a/core/registry.js +++ b/core/registry.js @@ -16,6 +16,7 @@ goog.provide('Blockly.registry'); goog.requireType('Blockly.blockRendering.Renderer'); goog.requireType('Blockly.Field'); goog.requireType('Blockly.IToolbox'); +goog.requireType('Blockly.Theme'); goog.requireType('Blockly.utils.toolbox'); @@ -63,6 +64,9 @@ Blockly.registry.Type.FIELD = new Blockly.registry.Type('field'); /** @type {!Blockly.registry.Type} */ Blockly.registry.Type.TOOLBOX = new Blockly.registry.Type('toolbox'); +/** @type {!Blockly.registry.Type} */ +Blockly.registry.Type.THEME = new Blockly.registry.Type('theme'); + /** * Registers a class based on a type and name. * @param {string|Blockly.registry.Type} type The type of the plugin. diff --git a/core/renderers/common/block_rendering.js b/core/renderers/common/block_rendering.js index 83cbf9d72..8b4a2b572 100644 --- a/core/renderers/common/block_rendering.js +++ b/core/renderers/common/block_rendering.js @@ -20,13 +20,6 @@ goog.require('Blockly.registry'); goog.require('Blockly.utils.object'); -/** - * The set of all registered renderers, keyed by their name. - * @type {!Object} - * @private - */ -Blockly.blockRendering.rendererMap_ = {}; - /** * Whether or not the debugger is turned on. * @type {boolean} diff --git a/core/theme.js b/core/theme.js index e314b7642..f66021f4d 100644 --- a/core/theme.js +++ b/core/theme.js @@ -11,6 +11,7 @@ goog.provide('Blockly.Theme'); +goog.require('Blockly.registry'); goog.require('Blockly.utils'); goog.require('Blockly.utils.colour'); goog.require('Blockly.utils.object'); @@ -73,6 +74,9 @@ Blockly.Theme = function(name, opt_blockStyles, opt_categoryStyles, * @package */ this.startHats = null; + + // Register the theme by name. + Blockly.registry.register(Blockly.registry.Type.THEME, name, this); }; /** @@ -206,9 +210,14 @@ Blockly.Theme.prototype.setStartHats = function(startHats) { Blockly.Theme.defineTheme = function(name, themeObj) { var theme = new Blockly.Theme(name); var base = themeObj['base']; - if (base && base instanceof Blockly.Theme) { - Blockly.utils.object.deepMerge(theme, base); - theme.name = name; + if (base) { + if (typeof base == "string") { + base = Blockly.registry.getObject(Blockly.registry.Type.THEME, base); + } + if (base instanceof Blockly.Theme) { + Blockly.utils.object.deepMerge(theme, base); + theme.name = name; + } } Blockly.utils.object.deepMerge(theme.blockStyles, @@ -222,5 +231,6 @@ Blockly.Theme.defineTheme = function(name, themeObj) { if (themeObj['startHats'] != null) { theme.startHats = themeObj['startHats']; } + return theme; }; diff --git a/core/utils/idgenerator.js b/core/utils/idgenerator.js index 81bd405a6..e17c51f31 100644 --- a/core/utils/idgenerator.js +++ b/core/utils/idgenerator.js @@ -29,5 +29,5 @@ Blockly.utils.IdGenerator.nextId_ = 0; * @return {string} The next unique identifier. */ Blockly.utils.IdGenerator.getNextUniqueId = function() { - return 'blockly:' + (Blockly.utils.IdGenerator.nextId_++).toString(36); + return 'blockly-' + (Blockly.utils.IdGenerator.nextId_++).toString(36); }; diff --git a/tests/mocha/block_test.js b/tests/mocha/block_test.js index 08f11a84b..3375c57bb 100644 --- a/tests/mocha/block_test.js +++ b/tests/mocha/block_test.js @@ -1657,6 +1657,8 @@ suite('Blocks', function() { }); teardown(function() { this.workspace.dispose(); + // Clear all registered themes. + Blockly.registry.typeMap_['theme'] = {}; }); test('Set colour hue', function() { this.block.setColour('20'); diff --git a/tests/mocha/theme_test.js b/tests/mocha/theme_test.js index d9c15d709..3e7c18a8f 100644 --- a/tests/mocha/theme_test.js +++ b/tests/mocha/theme_test.js @@ -11,6 +11,10 @@ 'use strict'; suite('Theme', function() { + teardown(function() { + // Clear all registered themes. + Blockly.registry.typeMap_['theme'] = {}; + }); function defineThemeTestBlocks() { Blockly.defineBlocksWithJsonArray([{