Move the dropdown field into the dropdown div. (#3122)

* Move the dropdown field into the dropdown div.
This commit is contained in:
Sam El-Husseini
2019-10-03 14:35:28 -07:00
committed by GitHub
parent e92bae1dda
commit fba98fca5b
5 changed files with 53 additions and 100 deletions

View File

@@ -911,7 +911,7 @@ Blockly.Block.prototype.getColourShadow = function() {
if (colourSecondary) {
return colourSecondary;
}
return Blockly.utils.colour.blend('white', this.getColour(), 0.6);
return Blockly.utils.colour.blend('#fff', this.getColour(), 0.6);
};
/**
@@ -935,8 +935,8 @@ Blockly.Block.prototype.getColourBorder = function() {
var colour = this.getColour();
return {
colourBorder: null,
colourLight: Blockly.utils.colour.blend('white', colour, 0.3),
colourDark: Blockly.utils.colour.blend('black', colour, 0.2)
colourLight: Blockly.utils.colour.blend('#fff', colour, 0.3),
colourDark: Blockly.utils.colour.blend('#000', colour, 0.2)
};
};

View File

@@ -706,7 +706,7 @@ Blockly.Css.CONTENT = [
'}',
'.blocklyDropDownDiv .goog-menuitem-content {',
'color: #fff;',
'color: #000;',
'}',
/* State: disabled. */
@@ -727,14 +727,9 @@ Blockly.Css.CONTENT = [
'}',
/* State: hover. */
'.blocklyWidgetDiv .goog-menuitem-highlight,',
'.blocklyWidgetDiv .goog-menuitem-hover {',
'background-color: #f1f3f4;',
'}',
'.blocklyDropDownDiv .goog-menuitem-highlight,',
'.blocklyDropDownDiv .goog-menuitem-hover {',
'background-color: rgba(0,0,0,.2);',
'.blocklyWidgetDiv .goog-menuitem-highlight ,',
'.blocklyDropDownDiv .goog-menuitem-highlight {',
'background-color: rgba(0,0,0,.1);',
'}',
/* State: selected/checked. */

View File

@@ -26,8 +26,8 @@
goog.provide('Blockly.DropDownDiv');
goog.require('Blockly.utils.dom');
goog.require('Blockly.utils.math');
goog.require('Blockly.utils.style');
@@ -102,6 +102,20 @@ Blockly.DropDownDiv.PADDING_Y = 16;
*/
Blockly.DropDownDiv.ANIMATION_TIME = 0.25;
/**
* The default dropdown div border color.
* @type {string}
* @const
*/
Blockly.DropDownDiv.DEFAULT_DROPDOWN_BORDER_COLOR = '#dadce0';
/**
* The default dropdown div color.
* @type {string}
* @const
*/
Blockly.DropDownDiv.DEFAULT_DROPDOWN_COLOR = '#fff';
/**
* Timer for animation out, to be cleared if we need to immediately hide
* without disrupting new shows.
@@ -124,6 +138,8 @@ Blockly.DropDownDiv.createDom = function() {
}
var div = document.createElement('div');
div.className = 'blocklyDropDownDiv';
div.style.backgroundColor = Blockly.DropDownDiv.DEFAULT_DROPDOWN_COLOR;
div.style.borderColor = Blockly.DropDownDiv.DEFAULT_DROPDOWN_BORDER_COLOR;
document.body.appendChild(div);
Blockly.DropDownDiv.DIV_ = div;
@@ -227,8 +243,10 @@ Blockly.DropDownDiv.showPositionedByBlock = function(field, block,
secondaryY += opt_secondaryYOffset;
}
// Set bounds to workspace; show the drop-down.
Blockly.DropDownDiv.setBoundsElement(block.workspace.getParentSvg().parentNode);
return Blockly.DropDownDiv.show(field, primaryX, primaryY, secondaryX, secondaryY, opt_onHide);
Blockly.DropDownDiv.setBoundsElement(
block.workspace.getParentSvg().parentNode);
return Blockly.DropDownDiv.show(
field, primaryX, primaryY, secondaryX, secondaryY, opt_onHide);
};
/**
@@ -519,11 +537,17 @@ Blockly.DropDownDiv.isVisible = function() {
/**
* Hide the menu only if it is owned by the provided object.
* @param {Object} owner Object which must be owning the drop-down to hide.
* @param {boolean=} opt_withoutAnimation True if we should hide the dropdown
* without animating.
* @return {boolean} True if hidden.
*/
Blockly.DropDownDiv.hideIfOwner = function(owner) {
Blockly.DropDownDiv.hideIfOwner = function(owner, opt_withoutAnimation) {
if (Blockly.DropDownDiv.owner_ === owner) {
Blockly.DropDownDiv.hide();
if (opt_withoutAnimation) {
Blockly.DropDownDiv.hideWithoutAnimation();
} else {
Blockly.DropDownDiv.hide();
}
return true;
}
return false;
@@ -540,12 +564,13 @@ Blockly.DropDownDiv.hide = function() {
div.style.opacity = 0;
// Finish animation - reset all values to default.
Blockly.DropDownDiv.animateOutTimer_ =
setTimeout(Blockly.DropDownDiv.hideWithoutAnimation,
Blockly.DropDownDiv.ANIMATION_TIME * 1000);
if (Blockly.DropDownDiv.onHide_) {
Blockly.DropDownDiv.onHide_();
Blockly.DropDownDiv.onHide_ = null;
}
setTimeout(function() {
Blockly.DropDownDiv.hideWithoutAnimation();
if (Blockly.DropDownDiv.onHide_) {
Blockly.DropDownDiv.onHide_();
Blockly.DropDownDiv.onHide_ = null;
}
}, Blockly.DropDownDiv.ANIMATION_TIME * 1000);
};
/**
@@ -567,6 +592,8 @@ Blockly.DropDownDiv.hideWithoutAnimation = function() {
div.style.top = '';
div.style.opacity = 0;
div.style.display = 'none';
div.style.backgroundColor = Blockly.DropDownDiv.DEFAULT_DROPDOWN_COLOR;
div.style.borderColor = Blockly.DropDownDiv.DEFAULT_DROPDOWN_BORDER_COLOR;
if (Blockly.DropDownDiv.onHide_) {
Blockly.DropDownDiv.onHide_();

View File

@@ -139,22 +139,6 @@ Blockly.FieldColour.prototype.titles_ = null;
*/
Blockly.FieldColour.prototype.columns_ = 0;
/**
* Border colour for the dropdown div showing the colour picker. Must be a CSS
* string.
* @type {string}
* @private
*/
Blockly.FieldColour.prototype.DROPDOWN_BORDER_COLOUR = '#dadce0';
/**
* Background colour for the dropdown div showing the colour picker. Must be a
* CSS string.
* @type {string}
* @private
*/
Blockly.FieldColour.prototype.DROPDOWN_BACKGROUND_COLOUR = 'white';
/**
* Configure the field based on the given map of options.
* @param {!Object} config A map of options to configure the field based on.
@@ -297,9 +281,6 @@ Blockly.FieldColour.prototype.showEditor_ = function() {
this.picker_ = this.dropdownCreate_();
Blockly.DropDownDiv.getContentDiv().appendChild(this.picker_);
Blockly.DropDownDiv.setColour(
this.DROPDOWN_BACKGROUND_COLOUR, this.DROPDOWN_BORDER_COLOUR);
Blockly.DropDownDiv.showPositionedByField(
this, this.dropdownDispose_.bind(this));

View File

@@ -37,7 +37,6 @@ goog.require('Blockly.utils.dom');
goog.require('Blockly.utils.object');
goog.require('Blockly.utils.Size');
goog.require('Blockly.utils.string');
goog.require('Blockly.utils.uiMenu');
goog.require('Blockly.utils.userAgent');
@@ -206,16 +205,14 @@ Blockly.FieldDropdown.prototype.initView = function() {
* @private
*/
Blockly.FieldDropdown.prototype.showEditor_ = function() {
Blockly.WidgetDiv.show(this, this.sourceBlock_.RTL,
this.widgetDispose_.bind(this));
this.menu_ = this.widgetCreate_();
this.menu_.render(Blockly.WidgetDiv.DIV);
this.menu_ = this.dropdownCreate_();
// Element gets created in render.
this.menu_.render(Blockly.DropDownDiv.getContentDiv());
Blockly.utils.dom.addClass(
/** @type {!Element} */ (this.menu_.getElement()), 'blocklyDropdownMenu');
this.positionMenu_(this.menu_);
Blockly.DropDownDiv.showPositionedByField(
this, this.dropdownDispose_.bind(this));
// Focusing needs to be handled after the menu is rendered and positioned.
// Otherwise it will cause a page scroll to get the misplaced menu in
@@ -231,11 +228,11 @@ Blockly.FieldDropdown.prototype.showEditor_ = function() {
};
/**
* Create the dropdown editor widget.
* Create the dropdown editor.
* @return {Blockly.Menu} The newly created dropdown menu.
* @private
*/
Blockly.FieldDropdown.prototype.widgetCreate_ = function() {
Blockly.FieldDropdown.prototype.dropdownCreate_ = function() {
var menu = new Blockly.Menu();
menu.setRightToLeft(this.sourceBlock_.RTL);
menu.setRole('listbox');
@@ -276,7 +273,7 @@ Blockly.FieldDropdown.prototype.widgetCreate_ = function() {
* Dispose of events belonging to the dropdown editor.
* @private
*/
Blockly.FieldDropdown.prototype.widgetDispose_ = function() {
Blockly.FieldDropdown.prototype.dropdownDispose_ = function() {
this.menu_.dispose();
this.menu_ = null;
};
@@ -287,57 +284,10 @@ Blockly.FieldDropdown.prototype.widgetDispose_ = function() {
* @private
*/
Blockly.FieldDropdown.prototype.handleMenuActionEvent_ = function(menuItem) {
Blockly.WidgetDiv.hideIfOwner(this);
Blockly.DropDownDiv.hideIfOwner(this, true);
this.onItemSelected(this.menu_, menuItem);
};
/**
* Place the menu correctly on the screen, taking into account the dimensions
* of the menu and the dimensions of the screen so that it doesn't run off any
* edges.
* @param {!Blockly.Menu} menu The menu to position.
* @private
*/
Blockly.FieldDropdown.prototype.positionMenu_ = function(menu) {
var viewportBBox = Blockly.utils.getViewportBBox();
var anchorBBox = this.getAnchorDimensions_();
var menuSize = Blockly.utils.uiMenu.getSize(menu);
var menuMaxHeightPx = Blockly.FieldDropdown.MAX_MENU_HEIGHT_VH *
document.documentElement.clientHeight;
if (menuSize.height > menuMaxHeightPx) {
menuSize.height = menuMaxHeightPx;
}
if (this.sourceBlock_.RTL) {
Blockly.utils.uiMenu.adjustBBoxesForRTL(viewportBBox, anchorBBox, menuSize);
}
Blockly.WidgetDiv.positionWithAnchor(viewportBBox, anchorBBox, menuSize,
this.sourceBlock_.RTL);
};
/**
* Returns the coordinates of the anchor rectangle for the widget div.
* On a FieldDropdown we take the top-left corner of the field, then adjust for
* the size of the checkmark that is displayed next to the currently selected
* item. This means that the item text will be positioned directly under the
* field text, rather than offset slightly.
* @return {!Object} The bounding rectangle of the anchor, in window
* coordinates.
* @private
*/
Blockly.FieldDropdown.prototype.getAnchorDimensions_ = function() {
var boundingBox = this.getScaledBBox_();
if (this.sourceBlock_.RTL) {
boundingBox.right += Blockly.FieldDropdown.CHECKMARK_OVERHANG;
} else {
boundingBox.left -= Blockly.FieldDropdown.CHECKMARK_OVERHANG;
}
return boundingBox;
};
/**
* Handle the selection of an item in the dropdown menu.
* @param {!Blockly.Menu} menu The Menu component clicked.