From 30343c8cf6e74cf2f8632433fce64a5ed891f3d2 Mon Sep 17 00:00:00 2001 From: Sam El-Husseini Date: Tue, 5 Nov 2019 10:44:51 -0800 Subject: [PATCH] Move the theme manager into WorkspaceSvg (#3400) --- core/workspace.js | 86 ----------------------- core/workspace_svg.js | 106 ++++++++++++++++++++++++----- tests/jsunit/block_test.js | 18 ----- tests/mocha/procedures_test.js | 13 +--- tests/mocha/xml_procedures_test.js | 5 -- 5 files changed, 92 insertions(+), 136 deletions(-) diff --git a/core/workspace.js b/core/workspace.js index 350229224..aec9a54bc 100644 --- a/core/workspace.js +++ b/core/workspace.js @@ -26,8 +26,6 @@ goog.provide('Blockly.Workspace'); goog.require('Blockly.Cursor'); goog.require('Blockly.MarkerCursor'); goog.require('Blockly.Events'); -goog.require('Blockly.ThemeManager'); -goog.require('Blockly.Themes.Classic'); goog.require('Blockly.utils'); goog.require('Blockly.utils.math'); goog.require('Blockly.VariableMap'); @@ -128,17 +126,6 @@ Blockly.Workspace = function(opt_options) { */ this.marker_ = new Blockly.MarkerCursor(); - /** - * Object in charge of storing and updating the workspace theme. - * @type {!Blockly.ThemeManager} - * @protected - */ - this.themeManager_ = this.options.parentWorkspace ? - this.options.parentWorkspace.getThemeManager() : - new Blockly.ThemeManager(this.options.theme || Blockly.Themes.Classic); - - this.themeManager_.subscribeWorkspace(this); - /** * True if keyboard accessibility mode is on, false otherwise. * @type {boolean} @@ -207,61 +194,6 @@ Blockly.Workspace.prototype.getMarker = function() { return this.marker_; }; -/** - * Get the workspace theme object. - * @return {!Blockly.Theme} The workspace theme object. - */ -Blockly.Workspace.prototype.getTheme = function() { - return this.themeManager_.getTheme(); -}; - -/** - * Set the workspace theme object. - * If no theme is passed, default to the `Blockly.Themes.Classic` theme. - * @param {Blockly.Theme} theme The workspace theme object. - */ -Blockly.Workspace.prototype.setTheme = function(theme) { - if (!theme) { - theme = /** @type {!Blockly.Theme} */ (Blockly.Themes.Classic); - } - this.themeManager_.setTheme(theme); -}; - -/** - * Refresh all blocks on the workspace after a theme update. - * @package - */ -Blockly.Workspace.prototype.refreshTheme = function() { - // Update all blocks in workspace that have a style name. - this.updateBlockStyles_(this.getAllBlocks(false).filter( - function(block) { - return block.getStyleName() !== undefined; - } - )); - - var event = new Blockly.Events.Ui(null, 'theme', null, null); - event.workspaceId = this.id; - Blockly.Events.fire(event); -}; - -/** - * Updates all the blocks with new style. - * @param {!Array.} blocks List of blocks to update the style - * on. - * @private - */ -Blockly.Workspace.prototype.updateBlockStyles_ = function(blocks) { - for (var i = 0, block; (block = blocks[i]); i++) { - var blockStyleName = block.getStyleName(); - if (blockStyleName) { - block.setStyle(blockStyleName); - if (block.mutator) { - block.mutator.updateBlockStyle(); - } - } - } -}; - /** * Dispose of this workspace. * Unlink from all DOM elements to prevent memory leaks. @@ -272,15 +204,6 @@ Blockly.Workspace.prototype.dispose = function() { this.clear(); // Remove from workspace database. delete Blockly.Workspace.WorkspaceDB_[this.id]; - - if (this.themeManager_) { - this.themeManager_.unsubscribeWorkspace(this); - this.themeManager_.unsubscribe(this.svgBackground_); - if (!this.options.parentWorkspace) { - this.themeManager_.dispose(); - this.themeManager_ = null; - } - } }; /** @@ -911,12 +834,3 @@ Blockly.Workspace.getAll = function() { } return workspaces; }; - -/** - * Get the theme manager for this workspace. - * @return {!Blockly.ThemeManager} The theme manager for this workspace. - * @package - */ -Blockly.Workspace.prototype.getThemeManager = function() { - return this.themeManager_; -}; diff --git a/core/workspace_svg.js b/core/workspace_svg.js index bf3f344d6..7a8034026 100644 --- a/core/workspace_svg.js +++ b/core/workspace_svg.js @@ -33,6 +33,8 @@ goog.require('Blockly.Gesture'); goog.require('Blockly.Grid'); goog.require('Blockly.Msg'); goog.require('Blockly.Options'); +goog.require('Blockly.ThemeManager'); +goog.require('Blockly.Themes.Classic'); goog.require('Blockly.TouchGesture'); goog.require('Blockly.utils'); goog.require('Blockly.utils.Coordinate'); @@ -134,6 +136,15 @@ Blockly.WorkspaceSvg = function(options, Blockly.Procedures.flyoutCategory); } + /** + * Object in charge of storing and updating the workspace theme. + * @type {!Blockly.ThemeManager} + * @protected + */ + this.themeManager_ = this.options.parentWorkspace ? + this.options.parentWorkspace.getThemeManager() : + new Blockly.ThemeManager(this.options.theme || Blockly.Themes.Classic); + /** * The block renderer used for rendering blocks on this workspace. * @type {!Blockly.blockRendering.Renderer} @@ -147,6 +158,8 @@ Blockly.WorkspaceSvg = function(options, * @private */ this.cachedParentSvg_ = null; + + this.themeManager_.subscribeWorkspace(this); }; Blockly.utils.object.inherits(Blockly.WorkspaceSvg, Blockly.Workspace); @@ -424,6 +437,76 @@ Blockly.WorkspaceSvg.prototype.getRenderer = function() { return this.renderer_; }; +/** + * Get the theme manager for this workspace. + * @return {!Blockly.ThemeManager} The theme manager for this workspace. + * @package + */ +Blockly.WorkspaceSvg.prototype.getThemeManager = function() { + return this.themeManager_; +}; + +/** + * Get the workspace theme object. + * @return {!Blockly.Theme} The workspace theme object. + */ +Blockly.WorkspaceSvg.prototype.getTheme = function() { + return this.themeManager_.getTheme(); +}; + +/** + * Set the workspace theme object. + * If no theme is passed, default to the `Blockly.Themes.Classic` theme. + * @param {Blockly.Theme} theme The workspace theme object. + */ +Blockly.WorkspaceSvg.prototype.setTheme = function(theme) { + if (!theme) { + theme = /** @type {!Blockly.Theme} */ (Blockly.Themes.Classic); + } + this.themeManager_.setTheme(theme); +}; + +/** + * Refresh all blocks on the workspace after a theme update. + * @package + */ +Blockly.WorkspaceSvg.prototype.refreshTheme = function() { + // Update all blocks in workspace that have a style name. + this.updateBlockStyles_(this.getAllBlocks(false).filter( + function(block) { + return block.getStyleName() !== undefined; + } + )); + + // Update current toolbox selection. + this.refreshToolboxSelection(); + if (this.toolbox_) { + this.toolbox_.updateColourFromTheme(); + } + + var event = new Blockly.Events.Ui(null, 'theme', null, null); + event.workspaceId = this.id; + Blockly.Events.fire(event); +}; + +/** + * Updates all the blocks with new style. + * @param {!Array.} blocks List of blocks to update the style + * on. + * @private + */ +Blockly.WorkspaceSvg.prototype.updateBlockStyles_ = function(blocks) { + for (var i = 0, block; (block = blocks[i]); i++) { + var blockStyleName = block.getStyleName(); + if (blockStyleName) { + block.setStyle(blockStyleName); + if (block.mutator) { + block.mutator.updateBlockStyle(); + } + } + } +}; + /** * Sets the cursor for use with keyboard navigation. * @@ -718,11 +801,11 @@ Blockly.WorkspaceSvg.prototype.dispose = function() { this.zoomControls_ = null; } - if (this.marker_) { + if (this.marker_ && this.marker_.getDrawer()) { this.marker_.getDrawer().dispose(); } - if (this.getCursor()) { + if (this.getCursor() && this.getCursor().getDrawer()) { this.getCursor().getDrawer().dispose(); } @@ -739,7 +822,12 @@ Blockly.WorkspaceSvg.prototype.dispose = function() { this.renderer_.getConstants().dispose(); if (this.themeManager_) { + this.themeManager_.unsubscribeWorkspace(this); this.themeManager_.unsubscribe(this.svgBackground_); + if (!this.options.parentWorkspace) { + this.themeManager_.dispose(); + this.themeManager_ = null; + } } Blockly.WorkspaceSvg.superClass_.dispose.call(this); @@ -2555,17 +2643,3 @@ Blockly.WorkspaceSvg.prototype.getGrid = function() { return this.grid_; }; -/** - * Refresh all blocks on the workspace, toolbox and flyout after a theme update. - * @package - * @override - */ -Blockly.WorkspaceSvg.prototype.refreshTheme = function() { - Blockly.WorkspaceSvg.superClass_.refreshTheme.call(this); - - // Update current toolbox selection. - this.refreshToolboxSelection(); - if (this.toolbox_) { - this.toolbox_.updateColourFromTheme(); - } -}; diff --git a/tests/jsunit/block_test.js b/tests/jsunit/block_test.js index a6588c353..603b4fd14 100644 --- a/tests/jsunit/block_test.js +++ b/tests/jsunit/block_test.js @@ -252,21 +252,3 @@ function test_block_row_unplug_multi_inputs_child() { blockTest_tearDown(); } } - -function test_set_style_throw_exception() { - blockTest_setUp(); - var styleStub = { - getBlockStyle: function() { - return null; - } - }; - mockControl_ = setUpMockMethod(workspace, 'getTheme', null, [styleStub]); - var blockA = workspace.newBlock('row_block'); - try { - blockA.setStyle('styleOne'); - } catch (error) { - assertEquals(error.message, 'Invalid style name: styleOne'); - } finally { - blockTest_tearDown(); - } -} diff --git a/tests/mocha/procedures_test.js b/tests/mocha/procedures_test.js index c973600b2..99b20e6ba 100644 --- a/tests/mocha/procedures_test.js +++ b/tests/mocha/procedures_test.js @@ -21,11 +21,6 @@ goog.require('Blockly.Msg'); suite('Procedures', function() { setup(function() { this.workspace = new Blockly.Workspace(); - this.workspace.setTheme(new Blockly.Theme({ - "procedure_blocks": { - "colourPrimary": "290" - } - })); this.callForAllTypes = function(func, startName) { var typesArray = [ @@ -249,9 +244,7 @@ suite('Procedures', function() { }); test('Multiple Workspaces', function() { this.callForAllTypes(function() { - var workspace = new Blockly.Workspace({ - theme: this.workspace.getTheme() - }); + var workspace = new Blockly.Workspace(); var def2 = new Blockly.Block(workspace, this.defType); def2.setFieldValue('name', 'NAME'); var caller2 = new Blockly.Block(workspace, this.callType); @@ -293,9 +286,7 @@ suite('Procedures', function() { }); test('Multiple Workspaces', function() { this.callForAllTypes(function() { - var workspace = new Blockly.Workspace({ - theme: this.workspace.getTheme() - }); + var workspace = new Blockly.Workspace(); var def2 = new Blockly.Block(workspace, this.defType); def2.setFieldValue('name', 'NAME'); var caller2 = new Blockly.Block(workspace, this.callType); diff --git a/tests/mocha/xml_procedures_test.js b/tests/mocha/xml_procedures_test.js index b8d871c80..fefa72aef 100644 --- a/tests/mocha/xml_procedures_test.js +++ b/tests/mocha/xml_procedures_test.js @@ -22,11 +22,6 @@ suite('Procedures XML', function() { suite('Deserialization', function() { setup(function() { this.workspace = new Blockly.Workspace(); - this.workspace.setTheme(new Blockly.Theme({ - "procedure_blocks": { - "colourPrimary": "290" - } - })); this.callForAllTypes = function(func) { var typesArray = [