diff --git a/blockly_uncompressed.js b/blockly_uncompressed.js index 47f400da5..5c109ce3c 100644 --- a/blockly_uncompressed.js +++ b/blockly_uncompressed.js @@ -25,7 +25,7 @@ goog.addDependency('../../core/block.js', ['Blockly.Block'], ['Blockly.ASTNode', goog.addDependency('../../core/block_animations.js', ['Blockly.blockAnimations'], ['Blockly.utils.dom'], {}); goog.addDependency('../../core/block_drag_surface.js', ['Blockly.BlockDragSurfaceSvg'], ['Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.dom'], {}); goog.addDependency('../../core/block_dragger.js', ['Blockly.BlockDragger'], ['Blockly.Events', 'Blockly.Events.BlockMove', 'Blockly.Events.Ui', 'Blockly.InsertionMarkerManager', 'Blockly.blockAnimations', 'Blockly.utils.Coordinate', 'Blockly.utils.dom'], {}); -goog.addDependency('../../core/block_events.js', ['Blockly.Events.BlockBase', 'Blockly.Events.BlockChange', 'Blockly.Events.BlockCreate', 'Blockly.Events.BlockDelete', 'Blockly.Events.BlockMove', 'Blockly.Events.Change', 'Blockly.Events.Create', 'Blockly.Events.Delete', 'Blockly.Events.Move'], ['Blockly.Events', 'Blockly.Events.Abstract', 'Blockly.utils.Coordinate', 'Blockly.utils.object', 'Blockly.utils.xml'], {}); +goog.addDependency('../../core/block_events.js', ['Blockly.Events.BlockBase', 'Blockly.Events.BlockChange', 'Blockly.Events.BlockCreate', 'Blockly.Events.BlockDelete', 'Blockly.Events.BlockMove', 'Blockly.Events.Change', 'Blockly.Events.Create', 'Blockly.Events.Delete', 'Blockly.Events.Move'], ['Blockly.Events', 'Blockly.Events.Abstract', 'Blockly.registry', 'Blockly.utils.Coordinate', 'Blockly.utils.object', 'Blockly.utils.xml'], {}); goog.addDependency('../../core/block_svg.js', ['Blockly.BlockSvg'], ['Blockly.ASTNode', 'Blockly.Block', 'Blockly.ContextMenu', 'Blockly.ContextMenuRegistry', 'Blockly.Events', 'Blockly.Events.BlockMove', 'Blockly.Events.Ui', 'Blockly.Msg', 'Blockly.RenderedConnection', 'Blockly.TabNavigateCursor', 'Blockly.Tooltip', 'Blockly.Touch', 'Blockly.blockAnimations', 'Blockly.blockRendering.IPathObject', 'Blockly.navigation', 'Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.Rect', 'Blockly.utils.deprecation', 'Blockly.utils.dom', 'Blockly.utils.object'], {}); goog.addDependency('../../core/blockly.js', ['Blockly'], ['Blockly.Events', 'Blockly.Events.Ui', 'Blockly.Procedures', 'Blockly.Tooltip', 'Blockly.Touch', 'Blockly.Variables', 'Blockly.WidgetDiv', 'Blockly.WorkspaceSvg', 'Blockly.Xml', 'Blockly.constants', 'Blockly.inject', 'Blockly.navigation', 'Blockly.utils', 'Blockly.utils.Size', 'Blockly.utils.colour'], {}); goog.addDependency('../../core/blocks.js', ['Blockly.Blocks'], [], {}); @@ -45,7 +45,7 @@ goog.addDependency('../../core/contextmenu_items.js', ['Blockly.ContextMenuItems goog.addDependency('../../core/contextmenu_registry.js', ['Blockly.ContextMenuRegistry'], ['Blockly.ContextMenuItems'], {'lang': 'es5'}); 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.js', ['Blockly.Events'], ['Blockly.registry', '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.Rect', 'Blockly.utils.Size', 'Blockly.utils.dom', 'Blockly.utils.style', 'Blockly.utils.userAgent'], {'lang': 'es5'}); @@ -158,7 +158,7 @@ goog.addDependency('../../core/tooltip.js', ['Blockly.Tooltip'], ['Blockly.utils 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/ui_events.js', ['Blockly.Events.Ui'], ['Blockly.Events', 'Blockly.Events.Abstract', 'Blockly.registry', 'Blockly.utils.object'], {}); 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'], [], {}); @@ -179,7 +179,7 @@ goog.addDependency('../../core/utils/svg_paths.js', ['Blockly.utils.svgPaths'], goog.addDependency('../../core/utils/toolbox.js', ['Blockly.utils.toolbox'], [], {}); goog.addDependency('../../core/utils/useragent.js', ['Blockly.utils.userAgent'], ['Blockly.utils.global'], {}); goog.addDependency('../../core/utils/xml.js', ['Blockly.utils.xml'], [], {}); -goog.addDependency('../../core/variable_events.js', ['Blockly.Events.VarBase', 'Blockly.Events.VarCreate', 'Blockly.Events.VarDelete', 'Blockly.Events.VarRename'], ['Blockly.Events', 'Blockly.Events.Abstract', 'Blockly.utils.object'], {}); +goog.addDependency('../../core/variable_events.js', ['Blockly.Events.VarBase', 'Blockly.Events.VarCreate', 'Blockly.Events.VarDelete', 'Blockly.Events.VarRename'], ['Blockly.Events', 'Blockly.Events.Abstract', 'Blockly.registry', 'Blockly.utils.object'], {}); goog.addDependency('../../core/variable_map.js', ['Blockly.VariableMap'], ['Blockly.Events', 'Blockly.Events.VarDelete', 'Blockly.Events.VarRename', 'Blockly.Msg', 'Blockly.utils', 'Blockly.utils.object'], {}); goog.addDependency('../../core/variable_model.js', ['Blockly.VariableModel'], ['Blockly.Events', 'Blockly.Events.VarCreate', 'Blockly.utils'], {}); goog.addDependency('../../core/variables.js', ['Blockly.Variables'], ['Blockly.Blocks', 'Blockly.Msg', 'Blockly.VariableModel', 'Blockly.Xml', 'Blockly.utils', 'Blockly.utils.xml'], {}); @@ -193,9 +193,9 @@ goog.addDependency('../../core/workspace_comment_render_svg.js', ['Blockly.Works goog.addDependency('../../core/workspace_comment_svg.js', ['Blockly.WorkspaceCommentSvg'], ['Blockly.Css', 'Blockly.Events', 'Blockly.Events.CommentCreate', 'Blockly.Events.CommentDelete', 'Blockly.Events.CommentMove', 'Blockly.Events.Ui', 'Blockly.WorkspaceComment', 'Blockly.utils', 'Blockly.utils.Coordinate', 'Blockly.utils.Rect', 'Blockly.utils.dom', 'Blockly.utils.object'], {}); 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_events.js', ['Blockly.Events.FinishedLoading'], ['Blockly.Events', 'Blockly.Events.Ui', 'Blockly.registry', 'Blockly.utils.object'], {'lang': 'es5'}); goog.addDependency('../../core/workspace_svg.js', ['Blockly.WorkspaceSvg'], ['Blockly.BlockSvg', 'Blockly.ConnectionDB', 'Blockly.ContextMenuRegistry', '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/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.registry', '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'}); goog.addDependency("base.js", [], []); diff --git a/core/block_events.js b/core/block_events.js index aa6d2754a..06bd0fc5f 100644 --- a/core/block_events.js +++ b/core/block_events.js @@ -22,6 +22,7 @@ goog.provide('Blockly.Events.Move'); // Deprecated. goog.require('Blockly.Events'); goog.require('Blockly.Events.Abstract'); +goog.require('Blockly.registry'); goog.require('Blockly.utils.Coordinate'); goog.require('Blockly.utils.object'); goog.require('Blockly.utils.xml'); @@ -31,19 +32,26 @@ goog.require('Blockly.utils.xml'); /** * Abstract class for a block event. - * @param {Blockly.Block} block The block this event corresponds to. + * @param {!Blockly.Block=} opt_block The block this event corresponds to. + * Undefined for a blank event. * @extends {Blockly.Events.Abstract} * @constructor */ -Blockly.Events.BlockBase = function(block) { +Blockly.Events.BlockBase = function(opt_block) { Blockly.Events.BlockBase.superClass_.constructor.call(this); + this.isBlank = typeof opt_block == 'undefined'; /** * The block id for the block this event pertains to * @type {string} */ - this.blockId = block.id; - this.workspaceId = block.workspace.id; + this.blockId = this.isBlank ? '' : opt_block.id; + + /** + * The workspace identifier for this event. + * @type {string} + */ + this.workspaceId = this.isBlank ? '' : opt_block.workspace.id; }; Blockly.utils.object.inherits(Blockly.Events.BlockBase, Blockly.Events.Abstract); @@ -69,33 +77,36 @@ Blockly.Events.BlockBase.prototype.fromJson = function(json) { /** * Class for a block change event. - * @param {Blockly.Block} block The changed block. Null for a blank event. - * @param {string} element One of 'field', 'comment', 'disabled', etc. - * @param {?string} name Name of input or field affected, or null. - * @param {*} oldValue Previous value of element. - * @param {*} newValue New value of element. + * @param {!Blockly.Block=} opt_block The changed block. Undefined for a blank + * event. + * @param {string=} opt_element One of 'field', 'comment', 'disabled', etc. + * @param {?string=} opt_name Name of input or field affected, or null. + * @param {*=} opt_oldValue Previous value of element. + * @param {*=} opt_newValue New value of element. * @extends {Blockly.Events.BlockBase} * @constructor */ -Blockly.Events.Change = function(block, element, name, oldValue, newValue) { - if (!block) { +Blockly.Events.Change = function(opt_block, opt_element, opt_name, opt_oldValue, + opt_newValue) { + Blockly.Events.Change.superClass_.constructor.call(this, opt_block); + if (!opt_block) { return; // Blank event to be populated by fromJson. } - Blockly.Events.Change.superClass_.constructor.call(this, block); - this.element = element; - this.name = name; - this.oldValue = oldValue; - this.newValue = newValue; + this.element = typeof opt_element == 'undefined' ? '' : opt_element; + this.name = typeof opt_name == 'undefined' ? '' : opt_name; + this.oldValue = typeof opt_oldValue == 'undefined' ? '' : opt_oldValue; + this.newValue = typeof opt_newValue == 'undefined' ? '' : opt_newValue; }; Blockly.utils.object.inherits(Blockly.Events.Change, Blockly.Events.BlockBase); /** * Class for a block change event. - * @param {Blockly.Block} block The changed block. Null for a blank event. - * @param {string} element One of 'field', 'comment', 'disabled', etc. - * @param {?string} name Name of input or field affected, or null. - * @param {*} oldValue Previous value of element. - * @param {*} newValue New value of element. + * @param {!Blockly.Block=} opt_block The changed block. Undefined for a blank + * event. + * @param {string=} opt_element One of 'field', 'comment', 'disabled', etc. + * @param {?string=} opt_name Name of input or field affected, or null. + * @param {*=} opt_oldValue Previous value of element. + * @param {*=} opt_newValue New value of element. * @extends {Blockly.Events.BlockBase} * @constructor */ @@ -197,28 +208,30 @@ Blockly.Events.Change.prototype.run = function(forward) { /** * Class for a block creation event. - * @param {Blockly.Block} block The created block. Null for a blank event. + * @param {!Blockly.Block=} opt_block The created block. Undefined for a blank + * event. * @extends {Blockly.Events.BlockBase} * @constructor */ -Blockly.Events.Create = function(block) { - if (!block) { +Blockly.Events.Create = function(opt_block) { + Blockly.Events.Create.superClass_.constructor.call(this, opt_block); + if (!opt_block) { return; // Blank event to be populated by fromJson. } - Blockly.Events.Create.superClass_.constructor.call(this, block); - if (block.workspace.rendered) { - this.xml = Blockly.Xml.blockToDomWithXY(block); + if (opt_block.workspace.rendered) { + this.xml = Blockly.Xml.blockToDomWithXY(opt_block); } else { - this.xml = Blockly.Xml.blockToDom(block); + this.xml = Blockly.Xml.blockToDom(opt_block); } - this.ids = Blockly.Events.getDescendantIds(block); + this.ids = Blockly.Events.getDescendantIds(opt_block); }; Blockly.utils.object.inherits(Blockly.Events.Create, Blockly.Events.BlockBase); /** * Class for a block creation event. - * @param {Blockly.Block} block The created block. Null for a blank event. + * @param {!Blockly.Block=} block The created block. Undefined for a blank + * event. * @extends {Blockly.Events.BlockBase} * @constructor */ @@ -276,25 +289,26 @@ Blockly.Events.Create.prototype.run = function(forward) { /** * Class for a block deletion event. - * @param {Blockly.Block} block The deleted block. Null for a blank event. + * @param {!Blockly.Block=} opt_block The deleted block. Undefined for a blank + * event. * @extends {Blockly.Events.BlockBase} * @constructor */ -Blockly.Events.Delete = function(block) { - if (!block) { +Blockly.Events.Delete = function(opt_block) { + Blockly.Events.Delete.superClass_.constructor.call(this, opt_block); + if (!opt_block) { return; // Blank event to be populated by fromJson. } - if (block.getParent()) { + if (opt_block.getParent()) { throw Error('Connected blocks cannot be deleted.'); } - Blockly.Events.Delete.superClass_.constructor.call(this, block); - if (block.workspace.rendered) { - this.oldXml = Blockly.Xml.blockToDomWithXY(block); + if (opt_block.workspace.rendered) { + this.oldXml = Blockly.Xml.blockToDomWithXY(opt_block); } else { - this.oldXml = Blockly.Xml.blockToDom(block); + this.oldXml = Blockly.Xml.blockToDom(opt_block); } - this.ids = Blockly.Events.getDescendantIds(block); + this.ids = Blockly.Events.getDescendantIds(opt_block); }; Blockly.utils.object.inherits(Blockly.Events.Delete, Blockly.Events.BlockBase); @@ -356,15 +370,17 @@ Blockly.Events.Delete.prototype.run = function(forward) { /** * Class for a block move event. Created before the move. - * @param {Blockly.Block} block The moved block. Null for a blank event. + * @param {!Blockly.Block=} opt_block The moved block. Undefined for a blank + * event. * @extends {Blockly.Events.BlockBase} * @constructor */ -Blockly.Events.Move = function(block) { - if (!block) { +Blockly.Events.Move = function(opt_block) { + Blockly.Events.Move.superClass_.constructor.call(this, opt_block); + if (!opt_block) { return; // Blank event to be populated by fromJson. } - Blockly.Events.Move.superClass_.constructor.call(this, block); + var location = this.currentLocation_(); this.oldParentId = location.parentId; this.oldInputName = location.inputName; @@ -509,3 +525,12 @@ Blockly.Events.Move.prototype.run = function(forward) { } } }; + +Blockly.registry.register(Blockly.registry.Type.EVENT, Blockly.Events.CREATE, + Blockly.Events.Create); +Blockly.registry.register(Blockly.registry.Type.EVENT, Blockly.Events.DELETE, + Blockly.Events.Delete); +Blockly.registry.register(Blockly.registry.Type.EVENT, Blockly.Events.CHANGE, + Blockly.Events.Change); +Blockly.registry.register(Blockly.registry.Type.EVENT, Blockly.Events.MOVE, + Blockly.Events.Move); diff --git a/core/events.js b/core/events.js index 3f567b132..e803af0ab 100644 --- a/core/events.js +++ b/core/events.js @@ -16,6 +16,7 @@ */ goog.provide('Blockly.Events'); +goog.require('Blockly.registry'); goog.require('Blockly.utils'); @@ -338,53 +339,15 @@ Blockly.Events.getDescendantIds = function(block) { * @param {!Object} json JSON representation. * @param {!Blockly.Workspace} workspace Target workspace for event. * @return {!Blockly.Events.Abstract} The event represented by the JSON. + * @throws {Error} if an event type is not found in the registry. */ Blockly.Events.fromJson = function(json, workspace) { - // TODO: Should I have a way to register a new event into here? - var event; - switch (json.type) { - case Blockly.Events.CREATE: - event = new Blockly.Events.Create(null); - break; - case Blockly.Events.DELETE: - event = new Blockly.Events.Delete(null); - break; - case Blockly.Events.CHANGE: - event = new Blockly.Events.Change(null, '', '', '', ''); - break; - case Blockly.Events.MOVE: - event = new Blockly.Events.Move(null); - break; - case Blockly.Events.VAR_CREATE: - event = new Blockly.Events.VarCreate(null); - break; - case Blockly.Events.VAR_DELETE: - event = new Blockly.Events.VarDelete(null); - break; - case Blockly.Events.VAR_RENAME: - event = new Blockly.Events.VarRename(null, ''); - break; - case Blockly.Events.UI: - event = new Blockly.Events.Ui(null, '', '', ''); - break; - case Blockly.Events.COMMENT_CREATE: - event = new Blockly.Events.CommentCreate(null); - break; - case Blockly.Events.COMMENT_CHANGE: - event = new Blockly.Events.CommentChange(null, '', ''); - break; - case Blockly.Events.COMMENT_MOVE: - event = new Blockly.Events.CommentMove(null); - break; - case Blockly.Events.COMMENT_DELETE: - event = new Blockly.Events.CommentDelete(null); - break; - case Blockly.Events.FINISHED_LOADING: - event = new Blockly.Events.FinishedLoading(workspace); - break; - default: - throw Error('Unknown event type.'); + var eventClass = Blockly.registry.getClass(Blockly.registry.Type.EVENT, + json.type); + if (!eventClass) { + throw Error('Unknown event type.'); } + var event = new eventClass(); event.fromJson(json); event.workspaceId = workspace.id; return event; diff --git a/core/events_abstract.js b/core/events_abstract.js index cbe048b9d..948649f9a 100644 --- a/core/events_abstract.js +++ b/core/events_abstract.js @@ -21,6 +21,13 @@ goog.require('Blockly.Events'); * @constructor */ Blockly.Events.Abstract = function() { + + /** + * Whether or not the event is blank (to be populated by fromJson). + * @type {?boolean} + */ + this.isBlank = null; + /** * The workspace identifier for this event. * @type {string|undefined} @@ -61,6 +68,7 @@ Blockly.Events.Abstract.prototype.toJson = function() { * @param {!Object} json JSON representation. */ Blockly.Events.Abstract.prototype.fromJson = function(json) { + this.isBlank = false; this.group = json['group']; }; diff --git a/core/registry.js b/core/registry.js index b0e808ac4..05cb95160 100644 --- a/core/registry.js +++ b/core/registry.js @@ -14,6 +14,7 @@ goog.provide('Blockly.registry'); goog.requireType('Blockly.blockRendering.Renderer'); +goog.requireType('Blockly.Events.Abstract'); goog.requireType('Blockly.Field'); goog.requireType('Blockly.IConnectionChecker'); goog.requireType('Blockly.IFlyout'); @@ -60,21 +61,25 @@ Blockly.registry.Type.prototype.toString = function() { return this.name_; }; -/** @type {!Blockly.registry.Type} */ -Blockly.registry.Type.RENDERER = new Blockly.registry.Type('renderer'); +/** @type {!Blockly.registry.Type} */ +Blockly.registry.Type.CONNECTION_CHECKER = + new Blockly.registry.Type('connectionChecker'); + +/** @type {!Blockly.registry.Type} */ +Blockly.registry.Type.EVENT = new Blockly.registry.Type('event'); /** @type {!Blockly.registry.Type} */ Blockly.registry.Type.FIELD = new Blockly.registry.Type('field'); +/** @type {!Blockly.registry.Type} */ +Blockly.registry.Type.RENDERER = new Blockly.registry.Type('renderer'); + /** @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'); -/** @type {!Blockly.registry.Type} */ -Blockly.registry.Type.CONNECTION_CHECKER = - new Blockly.registry.Type('connectionChecker'); /** @type {!Blockly.registry.Type} */ Blockly.registry.Type.FLYOUTS_VERTICAL_TOOLBOX = diff --git a/core/ui_events.js b/core/ui_events.js index 693b7443d..7991f6b86 100644 --- a/core/ui_events.js +++ b/core/ui_events.js @@ -14,6 +14,7 @@ goog.provide('Blockly.Events.Ui'); goog.require('Blockly.Events'); goog.require('Blockly.Events.Abstract'); +goog.require('Blockly.registry'); goog.require('Blockly.utils.object'); @@ -23,20 +24,25 @@ goog.require('Blockly.utils.object'); * editing to work (e.g. scrolling the workspace, zooming, opening toolbox * categories). * UI events do not undo or redo. - * @param {Blockly.Block} block The affected block. - * @param {string} element One of 'selected', 'comment', 'mutatorOpen', etc. - * @param {*} oldValue Previous value of element. - * @param {*} newValue New value of element. + * @param {?Blockly.Block=} opt_block The affected block. Null for UI events + * that do not have an associated block. Undefined for a blank event. + * @param {string=} opt_element One of 'selected', 'comment', 'mutatorOpen', + * etc. + * @param {*=} opt_oldValue Previous value of element. + * @param {*=} opt_newValue New value of element. * @extends {Blockly.Events.Abstract} * @constructor */ -Blockly.Events.Ui = function(block, element, oldValue, newValue) { +Blockly.Events.Ui = function(opt_block, opt_element, opt_oldValue, + opt_newValue) { Blockly.Events.Ui.superClass_.constructor.call(this); - this.blockId = block ? block.id : null; - this.workspaceId = block ? block.workspace.id : undefined; - this.element = element; - this.oldValue = oldValue; - this.newValue = newValue; + this.isBlank = typeof opt_block == 'undefined'; + + this.blockId = opt_block ? opt_block.id : null; + this.workspaceId = opt_block ? opt_block.workspace.id : undefined; + this.element = typeof opt_element == 'undefined' ? '' : opt_element; + this.oldValue = typeof opt_oldValue == 'undefined' ? '' : opt_oldValue; + this.newValue = typeof opt_newValue == 'undefined' ? '' : opt_newValue; // UI events do not undo or redo. this.recordUndo = false; }; @@ -74,3 +80,6 @@ Blockly.Events.Ui.prototype.fromJson = function(json) { this.newValue = json['newValue']; this.blockId = json['blockId']; }; + +Blockly.registry.register(Blockly.registry.Type.EVENT, Blockly.Events.UI, + Blockly.Events.Ui); diff --git a/core/variable_events.js b/core/variable_events.js index 78c6d65c4..c908ff26a 100644 --- a/core/variable_events.js +++ b/core/variable_events.js @@ -17,25 +17,32 @@ goog.provide('Blockly.Events.VarRename'); goog.require('Blockly.Events'); goog.require('Blockly.Events.Abstract'); +goog.require('Blockly.registry'); goog.require('Blockly.utils.object'); /** * Abstract class for a variable event. - * @param {Blockly.VariableModel} variable The variable this event corresponds - * to. + * @param {!Blockly.VariableModel=} opt_variable The variable this event + * corresponds to. Undefined for a blank event. * @extends {Blockly.Events.Abstract} * @constructor */ -Blockly.Events.VarBase = function(variable) { +Blockly.Events.VarBase = function(opt_variable) { Blockly.Events.VarBase.superClass_.constructor.call(this); + this.isBlank = typeof opt_variable == 'undefined'; /** * The variable id for the variable this event pertains to. * @type {string} */ - this.varId = variable.getId(); - this.workspaceId = variable.workspace.id; + this.varId = this.isBlank ? '' : opt_variable.getId(); + + /** + * The workspace identifier for this event. + * @type {string} + */ + this.workspaceId = this.isBlank ? '' : opt_variable.workspace.id; }; Blockly.utils.object.inherits(Blockly.Events.VarBase, Blockly.Events.Abstract); @@ -60,18 +67,19 @@ Blockly.Events.VarBase.prototype.fromJson = function(json) { /** * Class for a variable creation event. - * @param {Blockly.VariableModel} variable The created variable. - * Null for a blank event. + * @param {!Blockly.VariableModel=} opt_variable The created variable. Undefined + * for a blank event. * @extends {Blockly.Events.VarBase} * @constructor */ -Blockly.Events.VarCreate = function(variable) { - if (!variable) { +Blockly.Events.VarCreate = function(opt_variable) { + Blockly.Events.VarCreate.superClass_.constructor.call(this, opt_variable); + if (!opt_variable) { return; // Blank event to be populated by fromJson. } - Blockly.Events.VarCreate.superClass_.constructor.call(this, variable); - this.varType = variable.type; - this.varName = variable.name; + + this.varType = opt_variable.type; + this.varName = opt_variable.name; }; Blockly.utils.object.inherits(Blockly.Events.VarCreate, Blockly.Events.VarBase); @@ -117,18 +125,19 @@ Blockly.Events.VarCreate.prototype.run = function(forward) { /** * Class for a variable deletion event. - * @param {Blockly.VariableModel} variable The deleted variable. - * Null for a blank event. + * @param {!Blockly.VariableModel=} opt_variable The deleted variable. Undefined + * for a blank event. * @extends {Blockly.Events.VarBase} * @constructor */ -Blockly.Events.VarDelete = function(variable) { - if (!variable) { +Blockly.Events.VarDelete = function(opt_variable) { + Blockly.Events.VarDelete.superClass_.constructor.call(this, opt_variable); + if (!opt_variable) { return; // Blank event to be populated by fromJson. } - Blockly.Events.VarDelete.superClass_.constructor.call(this, variable); - this.varType = variable.type; - this.varName = variable.name; + + this.varType = opt_variable.type; + this.varName = opt_variable.name; }; Blockly.utils.object.inherits(Blockly.Events.VarDelete, Blockly.Events.VarBase); @@ -174,19 +183,20 @@ Blockly.Events.VarDelete.prototype.run = function(forward) { /** * Class for a variable rename event. - * @param {Blockly.VariableModel} variable The renamed variable. - * Null for a blank event. - * @param {string} newName The new name the variable will be changed to. + * @param {!Blockly.VariableModel=} opt_variable The renamed variable. Undefined + * for a blank event. + * @param {string=} newName The new name the variable will be changed to. * @extends {Blockly.Events.VarBase} * @constructor */ -Blockly.Events.VarRename = function(variable, newName) { - if (!variable) { +Blockly.Events.VarRename = function(opt_variable, newName) { + Blockly.Events.VarRename.superClass_.constructor.call(this, opt_variable); + if (!opt_variable) { return; // Blank event to be populated by fromJson. } - Blockly.Events.VarRename.superClass_.constructor.call(this, variable); - this.oldName = variable.name; - this.newName = newName; + + this.oldName = opt_variable.name; + this.newName = typeof newName == 'undefined' ? '' : newName; }; Blockly.utils.object.inherits(Blockly.Events.VarRename, Blockly.Events.VarBase); @@ -229,3 +239,10 @@ Blockly.Events.VarRename.prototype.run = function(forward) { workspace.renameVariableById(this.varId, this.oldName); } }; + +Blockly.registry.register(Blockly.registry.Type.EVENT, + Blockly.Events.VAR_CREATE, Blockly.Events.VarCreate); +Blockly.registry.register(Blockly.registry.Type.EVENT, + Blockly.Events.VAR_DELETE, Blockly.Events.VarDelete); +Blockly.registry.register(Blockly.registry.Type.EVENT, + Blockly.Events.VAR_RENAME, Blockly.Events.VarRename); diff --git a/core/workspace_events.js b/core/workspace_events.js index de98c5896..f150eb454 100644 --- a/core/workspace_events.js +++ b/core/workspace_events.js @@ -14,6 +14,7 @@ goog.provide('Blockly.Events.FinishedLoading'); goog.require('Blockly.Events'); goog.require('Blockly.Events.Ui'); +goog.require('Blockly.registry'); goog.require('Blockly.utils.object'); @@ -22,17 +23,24 @@ goog.require('Blockly.utils.object'); * Used to notify the developer when the workspace has finished loading (i.e * domToWorkspace). * Finished loading events do not record undo or redo. - * @param {!Blockly.Workspace} workspace The workspace that has finished - * loading. - * @extends {Blockly.Events.Abstract} + * @param {!Blockly.Workspace=} opt_workspace The workspace that has finished + * loading. Undefined for a blank event. + * @extends {Blockly.Events.Ui} * @constructor */ -Blockly.Events.FinishedLoading = function(workspace) { +Blockly.Events.FinishedLoading = function(opt_workspace) { + + /** + * Whether or not the event is blank (to be populated by fromJson). + * @type {boolean} + */ + this.isBlank = typeof opt_workspace == 'undefined'; + /** * The workspace identifier for this event. * @type {string} */ - this.workspaceId = workspace.id; + this.workspaceId = opt_workspace ? opt_workspace.id : ''; /** * The event group ID for the group this event belongs to. Groups define @@ -76,6 +84,10 @@ Blockly.Events.FinishedLoading.prototype.toJson = function() { * @param {!Object} json JSON representation. */ Blockly.Events.FinishedLoading.prototype.fromJson = function(json) { + this.isBlank = false; this.workspaceId = json['workspaceId']; this.group = json['group']; }; + +Blockly.registry.register(Blockly.registry.Type.EVENT, + Blockly.Events.FINISHED_LOADING, Blockly.Events.FinishedLoading); diff --git a/core/ws_comment_events.js b/core/ws_comment_events.js index 6a88af290..82369fd37 100644 --- a/core/ws_comment_events.js +++ b/core/ws_comment_events.js @@ -18,6 +18,7 @@ goog.provide('Blockly.Events.CommentMove'); goog.require('Blockly.Events'); goog.require('Blockly.Events.Abstract'); +goog.require('Blockly.registry'); goog.require('Blockly.utils.Coordinate'); goog.require('Blockly.utils.object'); goog.require('Blockly.utils.xml'); @@ -27,23 +28,30 @@ goog.require('Blockly.utils.xml'); /** * Abstract class for a comment event. - * @param {Blockly.WorkspaceComment} comment The comment this event corresponds - * to. + * @param {!Blockly.WorkspaceComment=} opt_comment The comment this event + * corresponds to. Undefined for a blank event. * @extends {Blockly.Events.Abstract} * @constructor */ -Blockly.Events.CommentBase = function(comment) { +Blockly.Events.CommentBase = function(opt_comment) { + + /** + * Whether or not an event is blank. + * @type {boolean} + */ + this.isBlank = typeof opt_comment == 'undefined'; + /** * The ID of the comment this event pertains to. * @type {string} */ - this.commentId = comment.id; + this.commentId = this.isBlank ? '' : opt_comment.id; /** * The workspace identifier for this event. * @type {string} */ - this.workspaceId = comment.workspace.id; + this.workspaceId = this.isBlank ? '' : opt_comment.workspace.id; /** * The event group id for the group this event belongs to. Groups define @@ -85,20 +93,24 @@ Blockly.Events.CommentBase.prototype.fromJson = function(json) { /** * Class for a comment change event. - * @param {Blockly.WorkspaceComment} comment The comment that is being changed. - * Null for a blank event. - * @param {string} oldContents Previous contents of the comment. - * @param {string} newContents New contents of the comment. + * @param {!Blockly.WorkspaceComment=} opt_comment The comment that is being + * changed. Undefined for a blank event. + * @param {string=} opt_oldContents Previous contents of the comment. + * @param {string=} opt_newContents New contents of the comment. * @extends {Blockly.Events.CommentBase} * @constructor */ -Blockly.Events.CommentChange = function(comment, oldContents, newContents) { - if (!comment) { +Blockly.Events.CommentChange = function(opt_comment, opt_oldContents, + opt_newContents) { + Blockly.Events.CommentChange.superClass_.constructor.call(this, opt_comment); + if (!opt_comment) { return; // Blank event to be populated by fromJson. } - Blockly.Events.CommentChange.superClass_.constructor.call(this, comment); - this.oldContents_ = oldContents; - this.newContents_ = newContents; + + this.oldContents_ = typeof opt_oldContents == 'undefined' ? '' : + opt_oldContents; + this.newContents_ = typeof opt_newContents == 'undefined' ? '' : + opt_newContents; }; Blockly.utils.object.inherits(Blockly.Events.CommentChange, Blockly.Events.CommentBase); @@ -154,18 +166,18 @@ Blockly.Events.CommentChange.prototype.run = function(forward) { /** * Class for a comment creation event. - * @param {Blockly.WorkspaceComment} comment The created comment. - * Null for a blank event. + * @param {!Blockly.WorkspaceComment=} opt_comment The created comment. + * Undefined for a blank event. * @extends {Blockly.Events.CommentBase} * @constructor */ -Blockly.Events.CommentCreate = function(comment) { - if (!comment) { +Blockly.Events.CommentCreate = function(opt_comment) { + Blockly.Events.CommentCreate.superClass_.constructor.call(this, opt_comment); + if (!opt_comment) { return; // Blank event to be populated by fromJson. } - Blockly.Events.CommentCreate.superClass_.constructor.call(this, comment); - this.xml = comment.toXmlWithXY(); + this.xml = opt_comment.toXmlWithXY(); }; Blockly.utils.object.inherits(Blockly.Events.CommentCreate, Blockly.Events.CommentBase); @@ -228,18 +240,18 @@ Blockly.Events.CommentCreateDeleteHelper = function(event, create) { }; /** * Class for a comment deletion event. - * @param {Blockly.WorkspaceComment} comment The deleted comment. - * Null for a blank event. + * @param {!Blockly.WorkspaceComment=} opt_comment The deleted comment. + * Undefined for a blank event. * @extends {Blockly.Events.CommentBase} * @constructor */ -Blockly.Events.CommentDelete = function(comment) { - if (!comment) { +Blockly.Events.CommentDelete = function(opt_comment) { + Blockly.Events.CommentDelete.superClass_.constructor.call(this, opt_comment); + if (!opt_comment) { return; // Blank event to be populated by fromJson. } - Blockly.Events.CommentDelete.superClass_.constructor.call(this, comment); - this.xml = comment.toXmlWithXY(); + this.xml = opt_comment.toXmlWithXY(); }; Blockly.utils.object.inherits(Blockly.Events.CommentDelete, Blockly.Events.CommentBase); @@ -278,29 +290,29 @@ Blockly.Events.CommentDelete.prototype.run = function(forward) { /** * Class for a comment move event. Created before the move. - * @param {Blockly.WorkspaceComment} comment The comment that is being moved. - * Null for a blank event. + * @param {!Blockly.WorkspaceComment=} opt_comment The comment that is being + * moved. Undefined for a blank event. * @extends {Blockly.Events.CommentBase} * @constructor */ -Blockly.Events.CommentMove = function(comment) { - if (!comment) { +Blockly.Events.CommentMove = function(opt_comment) { + Blockly.Events.CommentMove.superClass_.constructor.call(this, opt_comment); + if (!opt_comment) { return; // Blank event to be populated by fromJson. } - Blockly.Events.CommentMove.superClass_.constructor.call(this, comment); /** * The comment that is being moved. Will be cleared after recording the new * location. * @type {Blockly.WorkspaceComment} */ - this.comment_ = comment; + this.comment_ = opt_comment; /** * The location before the move, in workspace coordinates. * @type {!Blockly.utils.Coordinate} */ - this.oldCoordinate_ = comment.getXY(); + this.oldCoordinate_ = opt_comment.getXY(); /** * The location after the move, in workspace coordinates. @@ -394,3 +406,12 @@ Blockly.Events.CommentMove.prototype.run = function(forward) { var current = comment.getXY(); comment.moveBy(target.x - current.x, target.y - current.y); }; + +Blockly.registry.register(Blockly.registry.Type.EVENT, + Blockly.Events.COMMENT_CREATE, Blockly.Events.CommentCreate); +Blockly.registry.register(Blockly.registry.Type.EVENT, + Blockly.Events.COMMENT_CHANGE, Blockly.Events.CommentChange); +Blockly.registry.register(Blockly.registry.Type.EVENT, + Blockly.Events.COMMENT_MOVE, Blockly.Events.CommentMove); +Blockly.registry.register(Blockly.registry.Type.EVENT, + Blockly.Events.COMMENT_DELETE, Blockly.Events.CommentDelete); diff --git a/tests/mocha/event_test.js b/tests/mocha/event_test.js index c7d0bbcd5..d5fa8576d 100644 --- a/tests/mocha/event_test.js +++ b/tests/mocha/event_test.js @@ -344,7 +344,7 @@ suite('Events', function() { suite('fromJson', function() { test('Var create', function() { var event = new Blockly.Events.VarCreate(this.variable); - var event2 = new Blockly.Events.VarCreate(null); + var event2 = new Blockly.Events.VarCreate(); var json = event.toJson(); event2.fromJson(json); @@ -352,7 +352,7 @@ suite('Events', function() { }); test('Var delete', function() { var event = new Blockly.Events.VarDelete(this.variable); - var event2 = new Blockly.Events.VarDelete(null); + var event2 = new Blockly.Events.VarDelete(); var json = event.toJson(); event2.fromJson(json); @@ -360,7 +360,7 @@ suite('Events', function() { }); test('Var rename', function() { var event = new Blockly.Events.VarRename(this.variable, ''); - var event2 = new Blockly.Events.VarRename(null); + var event2 = new Blockly.Events.VarRename(); var json = event.toJson(); event2.fromJson(json); diff --git a/tests/mocha/trashcan_test.js b/tests/mocha/trashcan_test.js index 315ebc66e..2256afc7a 100644 --- a/tests/mocha/trashcan_test.js +++ b/tests/mocha/trashcan_test.js @@ -10,7 +10,7 @@ suite("Trashcan", function() { '' + xmlString + ''); xml = xml.children[0]; - var event = new Blockly.Events.Delete(null); + var event = new Blockly.Events.Delete(); event.oldXml = xml; event.workspaceId = workspace.id; Blockly.Events.fire(event);