diff --git a/core/marker_manager.js b/core/marker_manager.js index 22090e81e..d8081714f 100644 --- a/core/marker_manager.js +++ b/core/marker_manager.js @@ -176,6 +176,8 @@ Blockly.MarkerManager.prototype.dispose = function() { this.unregisterMarker(markerId); } this.markers_ = null; - this.cursor_.dispose(); - this.cursor_ = null; + if (this.cursor_) { + this.cursor_.dispose(); + this.cursor_ = null; + } }; diff --git a/core/workspace_svg.js b/core/workspace_svg.js index e6d21cb3e..99399691b 100644 --- a/core/workspace_svg.js +++ b/core/workspace_svg.js @@ -849,9 +849,9 @@ Blockly.WorkspaceSvg.prototype.dispose = function() { if (!this.options.parentWorkspace) { // Top-most workspace. Dispose of the div that the // SVG is injected into (i.e. injectionDiv). - var div = this.getParentSvg().parentNode; - if (div) { - Blockly.utils.dom.removeNode(div); + var parentSvg = this.getParentSvg(); + if (parentSvg && parentSvg.parentNode) { + Blockly.utils.dom.removeNode(parentSvg.parentNode); } } if (this.resizeHandlerWrapper_) { diff --git a/tests/mocha/workspace_svg_test.js b/tests/mocha/workspace_svg_test.js index 5e7487552..ce6d9e900 100644 --- a/tests/mocha/workspace_svg_test.js +++ b/tests/mocha/workspace_svg_test.js @@ -32,6 +32,11 @@ suite('WorkspaceSvg', function() { delete Blockly.Blocks['test_val_in']; }); + test('dispose of WorkspaceSvg without dom throws no error', function() { + var ws = new Blockly.WorkspaceSvg(new Blockly.Options({})); + ws.dispose(); + }); + test('appendDomToWorkspace alignment', function() { var dom = Blockly.Xml.textToDom( '' + @@ -116,6 +121,49 @@ suite('WorkspaceSvg', function() { }); }); + suite('addTopBlock', function() { + setup(function() { + this.targetWorkspace = new Blockly.Workspace(); + this.workspace.isFlyout = true; + this.workspace.targetWorkspace = this.targetWorkspace; + Blockly.defineBlocksWithJsonArray([{ + "type": "get_var_block", + "message0": "%1", + "args0": [ + { + "type": "field_variable", + "name": "VAR", + "variableTypes": ["", "type1", "type2"] + } + ] + }]); + }); + + teardown(function() { + // Have to dispose of the main workspace after the flyout workspace + // because it holds the variable map. + // Normally the main workspace disposes of the flyout workspace. + workspaceTeardown.call(this, this.targetWorkspace); + delete Blockly.Blocks['get_var_block']; + }); + + test('Trivial Flyout is True', function() { + this.targetWorkspace.createVariable('name1', '', '1'); + + // Flyout.init usually does this binding. + this.workspace.variableMap_ = this.targetWorkspace.getVariableMap(); + + Blockly.Events.disable(); + var block = new Blockly.Block(this.workspace, 'get_var_block'); + block.inputList[0].fieldRow[0].setValue('1'); + Blockly.Events.enable(); + + this.workspace.removeTopBlock(block); + this.workspace.addTopBlock(block); + assertVariableValues(this.workspace, 'name1', '', '1'); + }); + }); + suite('Workspace Base class', function() { testAWorkspace(); }); diff --git a/tests/mocha/workspace_test.js b/tests/mocha/workspace_test.js index a92f45072..0c3d47907 100644 --- a/tests/mocha/workspace_test.js +++ b/tests/mocha/workspace_test.js @@ -245,34 +245,6 @@ function testAWorkspace() { }); }); - suite('addTopBlock', function() { - setup(function() { - this.targetWorkspace = new Blockly.Workspace(); - this.workspace.isFlyout = true; - this.workspace.targetWorkspace = this.targetWorkspace; - }); - - teardown(function() { - // Have to dispose of the main workspace after the flyout workspace - // because it holds the variable map. - // Normally the main workspace disposes of the flyout workspace. - workspaceTeardown.call(this, this.targetWorkspace); - }); - - test('Trivial Flyout is True', function() { - this.targetWorkspace.createVariable('name1', '', '1'); - - // Flyout.init usually does this binding. - this.workspace.variableMap_ = this.targetWorkspace.getVariableMap(); - - var block = createVarBlocksNoEvents(this.workspace, ['1'])[0]; - - this.workspace.removeTopBlock(block); - this.workspace.addTopBlock(block); - assertVariableValues(this.workspace, 'name1', '', '1'); - }); - }); - suite('getTopBlocks(ordered=true)', function() { test('Empty workspace', function() { chai.assert.equal(this.workspace.getTopBlocks(true).length, 0); @@ -595,11 +567,13 @@ function testAWorkspace() { suite('getById', function() { setup(function() { - this.workspaceB = new Blockly.Workspace(); + this.workspaceB = this.workspace.rendered ? + new Blockly.WorkspaceSvg(new Blockly.Options({})) : + new Blockly.Workspace(); }); teardown(function() { - this.workspaceB.dispose(); + workspaceTeardown.call(this, this.workspaceB); }); test('Trivial', function() { @@ -627,11 +601,13 @@ function testAWorkspace() { setup(function() { this.blockA = this.workspace.newBlock(''); this.blockB = this.workspace.newBlock(''); - this.workspaceB = new Blockly.Workspace(); + this.workspaceB = this.workspace.rendered ? + new Blockly.WorkspaceSvg(new Blockly.Options({})) : + new Blockly.Workspace(); }); teardown(function() { - this.workspaceB.dispose(); + workspaceTeardown.call(this, this.workspaceB); }); test('Trivial', function() {