From 329a21c57285f7add5e6d2de812fa14983bbf7f5 Mon Sep 17 00:00:00 2001 From: Sam El-Husseini Date: Wed, 20 Nov 2019 11:07:39 -0800 Subject: [PATCH] Add theme and renderer classnames onto the widget and dropdown div. (#3456) * Add theme and renderer classnames onto the widget and dropdown div. --- core/css.js | 1 - core/dropdowndiv.js | 54 +++++++++++++++++++++++----- core/renderers/common/renderer.js | 13 ++++--- core/renderers/zelos/renderer.js | 7 +++- core/widgetdiv.js | 56 +++++++++++++++++++++-------- tests/mocha/field_textinput_test.js | 11 ++++-- 6 files changed, 110 insertions(+), 32 deletions(-) diff --git a/core/css.js b/core/css.js index 20778f3d5..eefaed158 100644 --- a/core/css.js +++ b/core/css.js @@ -393,7 +393,6 @@ Blockly.Css.CONTENT = [ '.blocklyHtmlInput {', 'border: none;', 'border-radius: 4px;', - 'font-family: sans-serif;', 'height: 100%;', 'margin: 0;', 'outline: none;', diff --git a/core/dropdowndiv.js b/core/dropdowndiv.js index 7730a829c..e291effc4 100644 --- a/core/dropdowndiv.js +++ b/core/dropdowndiv.js @@ -39,13 +39,6 @@ goog.require('Blockly.utils.style'); Blockly.DropDownDiv = function() { }; -/** - * The div element. Set once by Blockly.DropDownDiv.createDom. - * @type {Element} - * @private - */ -Blockly.DropDownDiv.DIV_ = null; - /** * Drop-downs will appear within the bounds of this element if possible. * Set in Blockly.DropDownDiv.setBoundsElement. @@ -135,6 +128,20 @@ Blockly.DropDownDiv.animateOutTimer_ = null; */ Blockly.DropDownDiv.onHide_ = null; +/** + * A class name representing the current owner's workspace renderer. + * @type {?string} + * @private + */ +Blockly.DropDownDiv.rendererClassName_ = null; + +/** + * A class name representing the current owner's workspace theme. + * @type {?string} + * @private + */ +Blockly.DropDownDiv.themeClassName_ = null; + /** * Create and insert the DOM element for this div. * @package @@ -148,16 +155,31 @@ Blockly.DropDownDiv.createDom = function() { div.style.backgroundColor = Blockly.DropDownDiv.DEFAULT_DROPDOWN_COLOUR; div.style.borderColor = Blockly.DropDownDiv.DEFAULT_DROPDOWN_BORDER_COLOUR; document.body.appendChild(div); + /** + * The div element. + * @type {!Element} + * @private + */ Blockly.DropDownDiv.DIV_ = div; var content = document.createElement('div'); content.className = 'blocklyDropDownContent'; div.appendChild(content); + /** + * The content element. + * @type {!Element} + * @private + */ Blockly.DropDownDiv.content_ = content; var arrow = document.createElement('div'); arrow.className = 'blocklyDropDownArrow'; div.appendChild(arrow); + /** + * The arrow element. + * @type {!Element} + * @private + */ Blockly.DropDownDiv.arrow_ = arrow; Blockly.DropDownDiv.DIV_.style.opacity = 0; @@ -341,7 +363,15 @@ Blockly.DropDownDiv.show = function(owner, rtl, primaryX, primaryY, Blockly.DropDownDiv.owner_ = owner; Blockly.DropDownDiv.onHide_ = opt_onHide || null; // Set direction. - Blockly.DropDownDiv.DIV_.style.direction = rtl ? 'rtl' : 'ltr'; + var div = Blockly.DropDownDiv.DIV_; + div.style.direction = rtl ? 'rtl' : 'ltr'; + + Blockly.DropDownDiv.rendererClassName_ = + Blockly.getMainWorkspace().getRenderer().name + '-renderer'; + Blockly.DropDownDiv.themeClassName_ = + Blockly.getMainWorkspace().getTheme().name + '-theme'; + Blockly.utils.dom.addClass(div, Blockly.DropDownDiv.rendererClassName_); + Blockly.utils.dom.addClass(div, Blockly.DropDownDiv.themeClassName_); // When we change `translate` multiple times in close succession, // Chrome may choose to wait and apply them all at once. @@ -637,6 +667,14 @@ Blockly.DropDownDiv.hideWithoutAnimation = function() { Blockly.DropDownDiv.clearContent(); Blockly.DropDownDiv.owner_ = null; + if (Blockly.DropDownDiv.rendererClassName_) { + Blockly.utils.dom.removeClass(div, Blockly.DropDownDiv.rendererClassName_); + Blockly.DropDownDiv.rendererClassName_ = null; + } + if (Blockly.DropDownDiv.themeClassName_) { + Blockly.utils.dom.removeClass(div, Blockly.DropDownDiv.themeClassName_); + Blockly.DropDownDiv.themeClassName_ = null; + } Blockly.getMainWorkspace().markFocused(); }; diff --git a/core/renderers/common/renderer.js b/core/renderers/common/renderer.js index 22e36f4a9..3d55db71a 100644 --- a/core/renderers/common/renderer.js +++ b/core/renderers/common/renderer.js @@ -44,9 +44,9 @@ Blockly.blockRendering.Renderer = function(name) { /** * The renderer name. * @type {string} - * @protected + * @package */ - this.name_ = name; + this.name = name; /** * The renderer's constant provider. @@ -154,7 +154,7 @@ Blockly.blockRendering.Renderer.prototype.getConstants = function() { * @protected */ Blockly.blockRendering.Renderer.prototype.getCSS_ = function() { - var selector = '.' + this.name_ + '-renderer'; + var selector = '.' + this.name + '-renderer'; var constants = this.getConstants(); return [ /* eslint-disable indent */ @@ -184,6 +184,11 @@ Blockly.blockRendering.Renderer.prototype.getCSS_ = function() { 'stroke: #fc3;', 'stroke-width: 3px;', '}', + + selector + ' .blocklyHtmlInput {', + 'font-family: ' + constants.FIELD_TEXT_FONTFAMILY + ';', + 'font-weight: ' + constants.FIELD_TEXT_FONTWEIGHT + ';', + '}', /* eslint-enable indent */ ]; }; @@ -194,7 +199,7 @@ Blockly.blockRendering.Renderer.prototype.getCSS_ = function() { * @private */ Blockly.blockRendering.Renderer.prototype.injectCSS_ = function(cssArray) { - var cssNodeId = 'blockly-renderer-style-' + this.name_; + var cssNodeId = 'blockly-renderer-style-' + this.name; if (document.getElementById(cssNodeId)) { // Already injected. return; diff --git a/core/renderers/zelos/renderer.js b/core/renderers/zelos/renderer.js index 751ce8a07..ac6559de3 100644 --- a/core/renderers/zelos/renderer.js +++ b/core/renderers/zelos/renderer.js @@ -127,7 +127,7 @@ Blockly.zelos.Renderer.prototype.shouldInsertDraggedBlock = function(_block, * @override */ Blockly.zelos.Renderer.prototype.getCSS_ = function() { - var selector = '.' + this.name_ + '-renderer'; + var selector = '.' + this.name + '-renderer'; var constants = this.getConstants(); return [ /* eslint-disable indent */ @@ -142,6 +142,11 @@ Blockly.zelos.Renderer.prototype.getCSS_ = function() { selector + ' .blocklyDropdownText {', 'fill: #fff !important;', '}', + + selector + ' .blocklyHtmlInput {', + 'font-family: ' + constants.FIELD_TEXT_FONTFAMILY + ';', + 'font-weight: ' + constants.FIELD_TEXT_FONTWEIGHT + ';', + '}', /* eslint-enable indent */ ]; }; diff --git a/core/widgetdiv.js b/core/widgetdiv.js index 90b37c4f0..1b7d5bcc4 100644 --- a/core/widgetdiv.js +++ b/core/widgetdiv.js @@ -32,12 +32,6 @@ goog.provide('Blockly.WidgetDiv'); goog.require('Blockly.utils.style'); -/** - * The HTML container. Set once by Blockly.WidgetDiv.createDom. - * @type {Element} - */ -Blockly.WidgetDiv.DIV = null; - /** * The object currently using this container. * @type {Object} @@ -52,6 +46,20 @@ Blockly.WidgetDiv.owner_ = null; */ Blockly.WidgetDiv.dispose_ = null; +/** + * A class name representing the current owner's workspace renderer. + * @type {?string} + * @private + */ +Blockly.WidgetDiv.rendererClassName_ = null; + +/** + * A class name representing the current owner's workspace theme. + * @type {?string} + * @private + */ +Blockly.WidgetDiv.themeClassName_ = null; + /** * Create the widget div and inject it onto the page. */ @@ -59,7 +67,10 @@ Blockly.WidgetDiv.createDom = function() { if (Blockly.WidgetDiv.DIV) { return; // Already created. } - // Create an HTML container for popup overlays (e.g. editor widgets). + /** + * The HTML container for popup overlays (e.g. editor widgets). + * @type {!Element} + */ Blockly.WidgetDiv.DIV = document.createElement('div'); Blockly.WidgetDiv.DIV.className = 'blocklyWidgetDiv'; document.body.appendChild(Blockly.WidgetDiv.DIV); @@ -79,25 +90,40 @@ Blockly.WidgetDiv.show = function(newOwner, rtl, dispose) { // Temporarily move the widget to the top of the screen so that it does not // cause a scrollbar jump in Firefox when displayed. var xy = Blockly.utils.style.getViewportPageOffset(); - Blockly.WidgetDiv.DIV.style.top = xy.y + 'px'; - Blockly.WidgetDiv.DIV.style.direction = rtl ? 'rtl' : 'ltr'; - Blockly.WidgetDiv.DIV.style.display = 'block'; + var div = Blockly.WidgetDiv.DIV; + div.style.top = xy.y + 'px'; + div.style.direction = rtl ? 'rtl' : 'ltr'; + div.style.display = 'block'; + Blockly.WidgetDiv.rendererClassName_ = + Blockly.getMainWorkspace().getRenderer().name + '-renderer'; + Blockly.WidgetDiv.themeClassName_ = + Blockly.getMainWorkspace().getTheme().name + '-theme'; + Blockly.utils.dom.addClass(div, Blockly.WidgetDiv.rendererClassName_); + Blockly.utils.dom.addClass(div, Blockly.WidgetDiv.themeClassName_); }; /** * Destroy the widget and hide the div. */ Blockly.WidgetDiv.hide = function() { + var div = Blockly.WidgetDiv.DIV; if (Blockly.WidgetDiv.owner_) { Blockly.WidgetDiv.owner_ = null; - Blockly.WidgetDiv.DIV.style.display = 'none'; - Blockly.WidgetDiv.DIV.style.left = ''; - Blockly.WidgetDiv.DIV.style.top = ''; + div.style.display = 'none'; + div.style.left = ''; + div.style.top = ''; Blockly.WidgetDiv.dispose_ && Blockly.WidgetDiv.dispose_(); Blockly.WidgetDiv.dispose_ = null; - Blockly.WidgetDiv.DIV.innerHTML = ''; + div.innerHTML = ''; + } + if (Blockly.WidgetDiv.rendererClassName_) { + Blockly.utils.dom.removeClass(div, Blockly.WidgetDiv.rendererClassName_); + Blockly.WidgetDiv.rendererClassName_ = null; + } + if (Blockly.WidgetDiv.themeClassName_) { + Blockly.utils.dom.removeClass(div, Blockly.WidgetDiv.themeClassName_); + Blockly.WidgetDiv.themeClassName_ = null; } - Blockly.getMainWorkspace().markFocused(); }; diff --git a/tests/mocha/field_textinput_test.js b/tests/mocha/field_textinput_test.js index 76df1748b..6598b0854 100644 --- a/tests/mocha/field_textinput_test.js +++ b/tests/mocha/field_textinput_test.js @@ -227,10 +227,14 @@ suite('Text Input Fields', function() { suite('Spellcheck', function() { setup(function() { this.prepField = function(field) { + var workspace = { + scale: 1, + getRenderer: function() { return {}; }, + getTheme: function() { return {}; }, + markFocused: function() {} + }; field.sourceBlock_ = { - workspace: { - scale: 1 - } + workspace: workspace }; field.constants_ = { FIELD_TEXT_FONTSIZE: 11, @@ -238,6 +242,7 @@ suite('Text Input Fields', function() { FIELD_TEXT_FONTFAMILY: 'sans-serif' }; field.clickTarget_ = document.createElement('div'); + Blockly.mainWorkspace = workspace; Blockly.WidgetDiv.DIV = document.createElement('div'); this.stub = sinon.stub(field, 'resizeEditor_'); };