From dec2472e7143953bb4fde4bc64b53ce60cfe107c Mon Sep 17 00:00:00 2001 From: Aaron Imming Date: Thu, 4 Jul 2019 21:00:56 +0800 Subject: [PATCH 01/15] Add shadow to flyout SVG --- src/assets/sass/scratch/_flyout.scss | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/assets/sass/scratch/_flyout.scss b/src/assets/sass/scratch/_flyout.scss index 9219903d..49a90e49 100644 --- a/src/assets/sass/scratch/_flyout.scss +++ b/src/assets/sass/scratch/_flyout.scss @@ -1,7 +1,10 @@ +.blocklyFlyout { + filter: drop-shadow(0 10px 5px #999); +} + .blocklyFlyoutBackground { height: calc(100% - 60px) !important; fill: #fff !important; fill-opacity: 0.95 !important; - stroke: #ebebeb; - stroke-width: 5px; -} \ No newline at end of file +} + From af57b1290900c9657e61cf177f620aace87150e7 Mon Sep 17 00:00:00 2001 From: Aaron Imming Date: Thu, 4 Jul 2019 21:02:28 +0800 Subject: [PATCH 02/15] Change spacing to ensure arrow renders correctly --- src/assets/sass/scratch/_toolbox.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/assets/sass/scratch/_toolbox.scss b/src/assets/sass/scratch/_toolbox.scss index 7d0b11e2..6f1b32ad 100644 --- a/src/assets/sass/scratch/_toolbox.scss +++ b/src/assets/sass/scratch/_toolbox.scss @@ -30,7 +30,7 @@ $category-colours: ( display: flex; flex-direction: column; margin-top: 20px; - max-height: calc(100% - 40px) !important; + max-height: calc(100vh - 100px); overflow: hidden; position: absolute; user-select: none; From 3242e1f44356aa6d591ebeddbc5d45cb0a4d3f0c Mon Sep 17 00:00:00 2001 From: Aaron Imming Date: Thu, 4 Jul 2019 21:02:47 +0800 Subject: [PATCH 03/15] Hide Blockly's scrollbars --- src/assets/sass/scratch/_workspace.scss | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/assets/sass/scratch/_workspace.scss b/src/assets/sass/scratch/_workspace.scss index 31bc0dec..aa99b0a6 100644 --- a/src/assets/sass/scratch/_workspace.scss +++ b/src/assets/sass/scratch/_workspace.scss @@ -12,4 +12,8 @@ .blocklyText { fill: #000 !important; +} + +.blocklyMainWorkspaceScrollbar { + display: none; } \ No newline at end of file From 174d4d2dc008bf55492f65ea9917eb64f9c64638 Mon Sep 17 00:00:00 2001 From: Aaron Imming Date: Thu, 4 Jul 2019 21:03:43 +0800 Subject: [PATCH 04/15] Set correct x-coordinate so scrollbar renders correctly --- src/scratch/hooks/flyout_base.js | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/src/scratch/hooks/flyout_base.js b/src/scratch/hooks/flyout_base.js index 2ab51744..3b612d00 100644 --- a/src/scratch/hooks/flyout_base.js +++ b/src/scratch/hooks/flyout_base.js @@ -1,10 +1,26 @@ /* eslint-disable func-names, no-underscore-dangle */ + +/** + * Corner radius of the flyout background. + * @type {number} + * @const + */ +Blockly.Flyout.prototype.CORNER_RADIUS = 10; + /** * Margin around the edges of the blocks in the flyout. * @type {number} * @const */ -Blockly.Flyout.prototype.MARGIN = 24; +Blockly.Flyout.prototype.MARGIN = 30; + +/** + * Top/bottom padding between scrollbar and edge of flyout background. + * deriv-bot: Should be equal to CORNER_RADIUS + * @type {number} + * @const + */ +Blockly.Flyout.prototype.SCROLLBAR_PADDING = 20; /** * Update the view based on coordinates calculated in position(). @@ -13,26 +29,31 @@ Blockly.Flyout.prototype.MARGIN = 24; * @param {number} x The computed x origin of the flyout's SVG group. * @param {number} y The computed y origin of the flyout's SVG group. * @protected - * deriv-bot: Imported from Blockly, used in flyout_vertical.js */ Blockly.Flyout.prototype.positionAt_ = function(width, height, x, y) { this.svgGroup_.setAttribute('width', width); this.svgGroup_.setAttribute('height', height); + if (this.svgGroup_.tagName === 'svg') { const transform = `translate(${x}px,${y}px)`; + Blockly.utils.setCssTransform(this.svgGroup_, transform); } else { // IE and Edge don't support CSS transforms on SVG elements so // it's important to set the transform on the SVG element itself const transform = `translate(${x},${y})`; + this.svgGroup_.setAttribute('transform', transform); } // Update the scrollbar (if one exists). if (this.scrollbar_) { + const newX = x - Blockly.VerticalFlyout.ARROW_SIZE; + // Set the scrollbars origin to be the top left of the flyout. - this.scrollbar_.setOrigin(x, y); + this.scrollbar_.setOrigin(newX, y); this.scrollbar_.resize(); + // Set the position again so that if the metrics were the same (and the // resize failed) our position is still updated. this.scrollbar_.setPosition_(this.scrollbar_.position_.x, this.scrollbar_.position_.y); From 08f506acf55179ea50d1fdb6101394358f56a229 Mon Sep 17 00:00:00 2001 From: Aaron Imming Date: Fri, 5 Jul 2019 14:35:38 +0800 Subject: [PATCH 05/15] Move Blockly.BlockSvg.TAB_WIDTH override to block_svg.js --- src/scratch/hooks/block_svg.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/scratch/hooks/block_svg.js b/src/scratch/hooks/block_svg.js index 771aa8a6..9ff8f019 100644 --- a/src/scratch/hooks/block_svg.js +++ b/src/scratch/hooks/block_svg.js @@ -1,6 +1,10 @@ -/* eslint-disable func-names, no-underscore-dangle */ import { translate } from '../../utils/lang/i18n'; +/* eslint-disable func-names, no-underscore-dangle */ + +// deriv-bot: Blockly value, Scratch resets this to 0, req for correct spacing in flyout. +Blockly.BlockSvg.TAB_WIDTH = 8; + /** * Set whether the block is disabled or not. * @param {boolean} disabled True if disabled. From ee8a0f23b5039500c01aef7ae370569fe978e705 Mon Sep 17 00:00:00 2001 From: Aaron Imming Date: Fri, 5 Jul 2019 14:36:05 +0800 Subject: [PATCH 06/15] Update reference to ARROW_SIZE --- src/scratch/hooks/flyout_base.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/scratch/hooks/flyout_base.js b/src/scratch/hooks/flyout_base.js index 3b612d00..cdb83795 100644 --- a/src/scratch/hooks/flyout_base.js +++ b/src/scratch/hooks/flyout_base.js @@ -22,6 +22,14 @@ Blockly.Flyout.prototype.MARGIN = 30; */ Blockly.Flyout.prototype.SCROLLBAR_PADDING = 20; +/** + * The fraction of the distance to the scroll target to move the flyout on + * each animation frame, when auto-scrolling. Values closer to 1.0 will make + * the scroll animation complete faster. Use 1.0 for no animation. + * @type {number} + */ +Blockly.Flyout.prototype.scrollAnimationFraction = 1.0; + /** * Update the view based on coordinates calculated in position(). * @param {number} width The computed width of the flyout's SVG group @@ -48,7 +56,7 @@ Blockly.Flyout.prototype.positionAt_ = function(width, height, x, y) { // Update the scrollbar (if one exists). if (this.scrollbar_) { - const newX = x - Blockly.VerticalFlyout.ARROW_SIZE; + const newX = x - this.ARROW_SIZE; // Set the scrollbars origin to be the top left of the flyout. this.scrollbar_.setOrigin(newX, y); From b97cf5b6f23ea5bd72667792d03dda19c90c8c1c Mon Sep 17 00:00:00 2001 From: Aaron Imming Date: Fri, 5 Jul 2019 14:40:45 +0800 Subject: [PATCH 07/15] Hide flyout on scrolling the category menu --- src/scratch/hooks/toolbox.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/scratch/hooks/toolbox.js b/src/scratch/hooks/toolbox.js index 8e9b7cca..00464994 100644 --- a/src/scratch/hooks/toolbox.js +++ b/src/scratch/hooks/toolbox.js @@ -103,6 +103,16 @@ Blockly.Toolbox.CategoryMenu.prototype.createDom = function() { this.table = goog.dom.createDom('div', className); this.parentHtml_.appendChild(this.table); + + // Hide flyout on scrolling the toolbox category menu in + // order to ensure correct positioning of flyout. + this.table.addEventListener('scroll', () => { + const toolbox = this.parent_; + const flyout = toolbox.flyout_; + + toolbox.setSelectedItem(null); + flyout.hide(); + }); }; /** From 198ea83876431a10847d0bb856ee66dcd5f716a7 Mon Sep 17 00:00:00 2001 From: Aaron Imming Date: Fri, 5 Jul 2019 14:41:09 +0800 Subject: [PATCH 08/15] Logic for DerivBot flyout design --- src/scratch/hooks/flyout_vertical.js | 239 +++++++++++++++++++++------ 1 file changed, 190 insertions(+), 49 deletions(-) diff --git a/src/scratch/hooks/flyout_vertical.js b/src/scratch/hooks/flyout_vertical.js index 9952bf3e..6f37db91 100644 --- a/src/scratch/hooks/flyout_vertical.js +++ b/src/scratch/hooks/flyout_vertical.js @@ -1,10 +1,111 @@ /* eslint-disable func-names, no-underscore-dangle */ -// deriv-bot: Blockly value, Scratch resets this to, req for correct spacing in flyout. -Blockly.BlockSvg.TAB_WIDTH = 8; + +// deriv-bot: We render an arrow pointing to the current category. This value +// determines the size of that arrow. +Blockly.VerticalFlyout.prototype.ARROW_SIZE = 15; + +/** + * Return an object with all the metrics required to size scrollbars for the + * flyout. The following properties are computed: + * .viewHeight: Height of the visible rectangle, + * .viewWidth: Width of the visible rectangle, + * .contentHeight: Height of the contents, + * .contentWidth: Width of the contents, + * .viewTop: Offset of top edge of visible rectangle from parent, + * .contentTop: Offset of the top-most content from the y=0 coordinate, + * .absoluteTop: Top-edge of view. + * .viewLeft: Offset of the left edge of visible rectangle from parent, + * .contentLeft: Offset of the left-most content from the x=0 coordinate, + * .absoluteLeft: Left-edge of view. + * @return {Object} Contains size and position metrics of the flyout. + * @private + */ +Blockly.VerticalFlyout.prototype.getMetrics_ = function() { + if (!this.isVisible()) { + // Flyout is hidden. + return null; + } + + const optionBox = this.getContentBoundingBox_(); + + // Padding for the end of the scrollbar. + const absoluteTop = this.SCROLLBAR_PADDING; + const absoluteLeft = 0; + + // Add padding to the bottom of the flyout, so we can scroll to the top of + // the last category. deriv-bot: Add some extra padding. + const contentHeight = (optionBox.height + (this.SCROLLBAR_PADDING * 2)) * this.workspace_.scale; + const bottomPadding = this.MARGIN; + const metrics = { + viewHeight : this.height_ - this.MARGIN * 2, + viewWidth : this.getWidth() - this.SCROLLBAR_PADDING, + contentHeight: contentHeight + bottomPadding, + contentWidth : optionBox.width * this.workspace_.scale + 2 * this.MARGIN, + viewTop : -this.workspace_.scrollY + optionBox.y, + viewLeft : -this.workspace_.scrollX, + contentTop : optionBox.y, + contentLeft : optionBox.x, + absoluteTop, + absoluteLeft, + }; + return metrics; +}; + +/** + * Used to put the blocks on top of the flyout. + * Lay out the blocks in the flyout. + * @param {!Array.} contents The blocks and buttons to lay out. + * @param {!Array.} gaps The visible gaps between blocks. + * @private + */ +Blockly.VerticalFlyout.prototype.layout_ = function(contents, gaps) { + // Take workspace scale into consideration for correct positioning + const cursorX = (this.MARGIN / this.targetWorkspace_.scale) + this.CORNER_RADIUS; + let cursorY = this.CORNER_RADIUS + this.SCROLLBAR_PADDING; + + contents.forEach((item, index) => { + if (item.type === 'block') { + const { block } = item; + const root = block.getSvgRoot(); + const blockHW = block.getHeightWidth(); + + // Mark blocks as being inside a flyout. This is used to detect and + // prevent the closure of the flyout if the user right-clicks on such a + // block. + const allBlocks = block.getDescendants(false); + allBlocks.forEach(child => child.isInFlyout = true); + + // The block moves a bit extra for the hat, but the block's rectangle + // doesn't. That's because the hat actually extends up from 0. + const extra_hat_height = (block.startHat_ ? Blockly.BlockSvg.START_HAT_HEIGHT : 0); + const rect = this.createRect_(block, cursorX, cursorY, blockHW, index); + + block.moveBy(cursorX, cursorY + extra_hat_height); + this.addBlockListeners_(root, block, rect); + cursorY += blockHW.height + gaps[index] + extra_hat_height; + + } else if (item.type === 'button') { + // For both buttons and labels + const { button } = item; + const buttonSvg = button.createDom(); + + button.moveTo(cursorX, cursorY); + button.show(); + + // Clicking on a flyout button or label is a lot like clicking on the + // flyout background. + this.listeners_.push( + Blockly.bindEventWithChecks_(buttonSvg, 'mousedown', this, this.onMouseDown_) + ); + + this.buttons_.push(button); + cursorY += button.height + gaps[index]; + } + }); +}; /** * Move the flyout to the edge of the workspace. - * deriv-bot: Custom dimensions for flyout & support dynamic widths. */ Blockly.VerticalFlyout.prototype.position = function() { if (!this.isVisible()) { @@ -16,38 +117,53 @@ Blockly.VerticalFlyout.prototype.position = function() { // Hidden components will return null. return; } + // Consider the stroke thickness for spacing. + if (this.stroke_thickness_ === undefined) { + const css_style = window.getComputedStyle(this.svgBackground_); + this.stroke_thickness_ = (css_style.stroke !== 'none' && parseInt(css_style.strokeWidth) || 0); + } + // Toolbox bounds shouldn't change, keep in memory instead of continuously accessing DOM. + if (!this.toolbox_bounds_) { + this.toolbox_bounds_ = this.parentToolbox_.HtmlDiv.getBoundingClientRect(); + } + + const fullscreenFlyoutHeight = targetWorkspaceMetrics.viewHeight - (this.toolbox_bounds_.top * 2); + const toolboxFlyoutHeight = this.toolbox_bounds_.height + (this.MARGIN * 2) + (this.SCROLLBAR_PADDING * 2); + const flyoutContentHeight = this.getMetrics_().contentHeight + (this.toolbox_bounds_.top * 2); - // Record the height for Blockly.Flyout.getMetrics_ - // deriv-bot: Set to workspace height - this.height_ = targetWorkspaceMetrics.viewHeight - 40; + this.height_ = Math.min( + Math.max(toolboxFlyoutHeight, flyoutContentHeight), + fullscreenFlyoutHeight + ); - const edgeWidth = this.width_ - this.CORNER_RADIUS; - // deriv-bot: use this.height_ instead of targetWorkspaceMetrics.viewHeight - const edgeHeight = this.height_ - 2 * this.CORNER_RADIUS; + // edgeWidth and edgeHeight control the background SVG + const edgeHeight = + this.height_ + - (this.stroke_thickness_ * 2) + - (this.CORNER_RADIUS * 2) + - (this.toolbox_bounds_.top / 2); + + const edgeWidth = + this.width_ + - (this.stroke_thickness_ * 2) + - (this.CORNER_RADIUS * 2) + - this.ARROW_SIZE + - Blockly.Scrollbar.scrollbarThickness; this.setBackgroundPath_(edgeWidth, edgeHeight); // deriv-bot: Ensure flyout is rendered at same y-point as parent toolbox. - const y = this.parentToolbox_.HtmlDiv.offsetTop; - let x; + const y = this.toolbox_bounds_.top; + let x = 0; // If this flyout is the toolbox flyout. if (this.targetWorkspace_.toolboxPosition === this.toolboxPosition_) { // If there is a category toolbox. if (targetWorkspaceMetrics.toolboxWidth) { - if (this.toolboxPosition_ === Blockly.TOOLBOX_AT_LEFT) { - // deriv-bot: Allow for dynamic toolbox width. - x = this.parentToolbox_.HtmlDiv.clientWidth + Blockly.BlockSvg.TAB_WIDTH; - } else { - x = targetWorkspaceMetrics.viewWidth - this.width_; - } - } else if (this.toolboxPosition_ === Blockly.TOOLBOX_AT_LEFT) { - x = 0; - } else { - x = targetWorkspaceMetrics.viewWidth; + // deriv-bot: Allow for dynamic toolbox width, specifies where to position + // the flyout. + x = this.parentToolbox_.HtmlDiv.clientWidth + Blockly.BlockSvg.TAB_WIDTH; } - } else if (this.toolboxPosition_ === Blockly.TOOLBOX_AT_LEFT) { - x = 0; } else { // Because the anchor point of the flyout is on the left, but we want // to align the right edge of the flyout with the right edge of the @@ -56,21 +172,21 @@ Blockly.VerticalFlyout.prototype.position = function() { x = targetWorkspaceMetrics.viewWidth + targetWorkspaceMetrics.absoluteLeft - this.width_; } - this.positionAt_(this.width_, this.height_, x, y); + const svg_width = this.width_ - this.MARGIN + this.CORNER_RADIUS; + const svg_height = this.height_ - this.MARGIN + this.CORNER_RADIUS; + + this.positionAt_(svg_width, svg_height, x, y); }; /** * Compute width of flyout. Position mat under each block. - * For RTL: Lay out the blocks and buttons to be right-aligned. - * deriv-bot: Allow for dynamic width flyout. * @private */ Blockly.VerticalFlyout.prototype.reflowInternal_ = function() { this.workspace_.scale = this.targetWorkspace_.scale; let flyoutWidth = 0; - const blocks = this.workspace_.getTopBlocks(false); - blocks.forEach(block => { + this.workspace_.getTopBlocks(false).forEach(block => { let { width } = block.getHeightWidth(); if (block.outputConnection) { width -= Blockly.BlockSvg.TAB_WIDTH; @@ -82,33 +198,58 @@ Blockly.VerticalFlyout.prototype.reflowInternal_ = function() { flyoutWidth = Math.max(flyoutWidth, button.width); }); - flyoutWidth += this.MARGIN * 1.5 + Blockly.BlockSvg.TAB_WIDTH; + // Consider workspace scale when calculating margin, also consider the category arrow. + flyoutWidth += ((this.MARGIN * 1.5 / this.workspace_.scale) + Blockly.BlockSvg.TAB_WIDTH); + flyoutWidth += (this.CORNER_RADIUS * 2); flyoutWidth *= this.workspace_.scale; + flyoutWidth += this.ARROW_SIZE; flyoutWidth += Blockly.Scrollbar.scrollbarThickness; if (this.width_ !== flyoutWidth) { - blocks.forEach(block => { - if (this.RTL) { - // With the flyoutWidth known, right-align the blocks. - const oldX = block.getRelativeToSurfaceXY().x; - const newX = flyoutWidth / this.workspace_.scale - this.MARGIN - Blockly.BlockSvg.TAB_WIDTH; - - block.moveBy(newX - oldX, 0); - } - }); - - if (this.RTL) { - // With the flyoutWidth known, right-align the buttons. - this.buttons_.forEach(button => { - const { y } = button.getPosition(); - const x = flyoutWidth / this.workspace_.scale - button.width - this.MARGIN - Blockly.BlockSvg.TAB_WIDTH; - - button.moveTo(x, y); - }); - } - // Record the width for .getMetrics_ and .position. this.width_ = flyoutWidth; this.position(); } }; + +/** + * Create and set the path for the visible boundaries of the flyout. + * @param {number} width The width of the flyout, not including the rounded corners. + * @param {number} height The height of the flyout, not including rounded corners. + * @private + */ +Blockly.VerticalFlyout.prototype.setBackgroundPath_ = function(width, height) { + const el_selected_category = this.parentToolbox_.selectedItem_.parentHtml_; + const category_bounds = el_selected_category.getBoundingClientRect(); + + // Starting position of the SVG + const start_x = this.ARROW_SIZE + this.CORNER_RADIUS + this.stroke_thickness_; + const start_y = this.stroke_thickness_; + + // Calculate the line between the each of the top & bottom rounded corners. + const flyout_rectangle_width = Math.abs(width + this.ARROW_SIZE - this.MARGIN); + const has_arrow = category_bounds.top < (height - this.ARROW_SIZE * 2); + const path = []; + + path.push('M', start_x, start_y); + path.push('h', flyout_rectangle_width); + path.push('a', this.CORNER_RADIUS, this.CORNER_RADIUS, 0, 0, 1, this.CORNER_RADIUS, this.CORNER_RADIUS); + path.push('v', height - this.CORNER_RADIUS); + path.push('a', this.CORNER_RADIUS, this.CORNER_RADIUS, 0, 0, 1, -this.CORNER_RADIUS, this.CORNER_RADIUS); + path.push('h', -flyout_rectangle_width); + path.push('a', this.CORNER_RADIUS, this.CORNER_RADIUS, 0, 0, 1, -this.CORNER_RADIUS, -this.CORNER_RADIUS); + + if (has_arrow) { + const bottom_to_arrow = category_bounds.top + (category_bounds.height / 2) - 3; + + path.push('V', bottom_to_arrow); + path.push('l', -this.ARROW_SIZE, -this.ARROW_SIZE); + path.push('l', this.ARROW_SIZE, -this.ARROW_SIZE); + } + + path.push('V', this.stroke_thickness_ + this.CORNER_RADIUS); + path.push('a', this.CORNER_RADIUS, this.CORNER_RADIUS, 0, 0, 1, this.CORNER_RADIUS, -this.CORNER_RADIUS); + path.push('z'); + + this.svgBackground_.setAttribute('d', path.join(' ')); +}; From 51f5b79940a1f74f8f62e1e5d6255492458d08b4 Mon Sep 17 00:00:00 2001 From: Aaron Imming Date: Fri, 5 Jul 2019 14:41:36 +0800 Subject: [PATCH 09/15] Position flyout on workspace/window resize --- src/scratch/index.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/scratch/index.js b/src/scratch/index.js index 44d772e8..3904710d 100644 --- a/src/scratch/index.js +++ b/src/scratch/index.js @@ -61,8 +61,9 @@ export const scratchWorkspaceInit = async (scratch_area_name, scratch_div_name) el_scratch_div.style.top = `${y}px`; el_scratch_div.style.width = `${scratch_area.offsetWidth}px`; el_scratch_div.style.height = `${scratch_area.offsetHeight}px`; - + Blockly.svgResize(workspace); + workspace.toolbox_.flyout_.position(); }; // Resize workspace on workspace event, workaround for jumping workspace. From 6bec5e2ae0972e9ca40048f96ca22aec1afd1ba6 Mon Sep 17 00:00:00 2001 From: Aaron Imming Date: Fri, 5 Jul 2019 14:51:33 +0800 Subject: [PATCH 10/15] Eslint fixes --- src/assets/sass/scratch/_flyout.scss | 1 - src/scratch/index.js | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/src/assets/sass/scratch/_flyout.scss b/src/assets/sass/scratch/_flyout.scss index 49a90e49..ca293f87 100644 --- a/src/assets/sass/scratch/_flyout.scss +++ b/src/assets/sass/scratch/_flyout.scss @@ -7,4 +7,3 @@ fill: #fff !important; fill-opacity: 0.95 !important; } - diff --git a/src/scratch/index.js b/src/scratch/index.js index 3904710d..d7521feb 100644 --- a/src/scratch/index.js +++ b/src/scratch/index.js @@ -63,6 +63,7 @@ export const scratchWorkspaceInit = async (scratch_area_name, scratch_div_name) el_scratch_div.style.height = `${scratch_area.offsetHeight}px`; Blockly.svgResize(workspace); + // eslint-disable-next-line no-underscore-dangle workspace.toolbox_.flyout_.position(); }; From d3045d5f26cd3d4d0c626ab185669fc577e51f08 Mon Sep 17 00:00:00 2001 From: Aaron Imming Date: Fri, 5 Jul 2019 14:52:39 +0800 Subject: [PATCH 11/15] Add css-filters as an exception to .stylelintrc --- .stylelintrc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.stylelintrc b/.stylelintrc index 65b06ed4..8adea27a 100644 --- a/.stylelintrc +++ b/.stylelintrc @@ -51,7 +51,7 @@ "property-case" : "lower", "plugin/no-unsupported-browser-features" : [true, { "severity": "warning", - "ignore": ["calc", "user-select-none", "multicolumn", "css-appearance", "border-radius", "pointer"] + "ignore": ["calc", "user-select-none", "multicolumn", "css-appearance", "border-radius", "pointer", "css-filters"] }], "rule-empty-line-before" : ["always", { "ignore": ["after-comment"], "except": ["inside-block-and-after-rule", "first-nested"] }], "selector-attribute-brackets-space-inside" : "never", From 7501d4f20fd47f36f5b6c44b8e3edd900c8b87b3 Mon Sep 17 00:00:00 2001 From: Aaron Imming Date: Fri, 5 Jul 2019 14:58:51 +0800 Subject: [PATCH 12/15] Use bounds in memory, rather than accessing DOM --- src/scratch/hooks/flyout_vertical.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/scratch/hooks/flyout_vertical.js b/src/scratch/hooks/flyout_vertical.js index 6f37db91..873ea5f2 100644 --- a/src/scratch/hooks/flyout_vertical.js +++ b/src/scratch/hooks/flyout_vertical.js @@ -162,7 +162,7 @@ Blockly.VerticalFlyout.prototype.position = function() { if (targetWorkspaceMetrics.toolboxWidth) { // deriv-bot: Allow for dynamic toolbox width, specifies where to position // the flyout. - x = this.parentToolbox_.HtmlDiv.clientWidth + Blockly.BlockSvg.TAB_WIDTH; + x = this.toolbox_bounds_.width + Blockly.BlockSvg.TAB_WIDTH; } } else { // Because the anchor point of the flyout is on the left, but we want From c186430858ebc089a6234651defd510372aa772e Mon Sep 17 00:00:00 2001 From: Aaron Imming Date: Mon, 8 Jul 2019 11:11:47 +0800 Subject: [PATCH 13/15] Delete _blockly-toolbox.scss --- src/assets/sass/scratch/_blockly-toolbox.scss | 115 ------------------ 1 file changed, 115 deletions(-) delete mode 100644 src/assets/sass/scratch/_blockly-toolbox.scss diff --git a/src/assets/sass/scratch/_blockly-toolbox.scss b/src/assets/sass/scratch/_blockly-toolbox.scss deleted file mode 100644 index b4c024a3..00000000 --- a/src/assets/sass/scratch/_blockly-toolbox.scss +++ /dev/null @@ -1,115 +0,0 @@ -@import 'color'; - -.blocklyText { - fill: $black !important; -} - -.blocklyTreeSelected .blocklyTreeLabel { - color: $white !important; -} - -.blocklyTreeRow.blocklyTreeSelected .blocklyTreeIcon.blocklyTreeIconOpen, -.blocklyTreeRow.blocklyTreeSelected .blocklyTreeIcon.blocklyTreeIconClosedLtr { - filter: invert(100%); /* stylelint-disable-line */ -} - -.blocklyTreeIcon.blocklyTreeIconOpen { - // background-image: url('dist/media/image/down-arrow.svg') !important; - background-position: -0.19em -0.38em !important; -} - -.blocklyTreeIcon.blocklyTreeIconClosedLtr { - // background-image: url('dist/media/image/down-arrow.svg') !important; - background-position: -0.19em -0.38em !important; -} - -.blocklyTreeRow.blocklyTreeSelected { - background-color: #2a3052 !important; -} - -.blocklyTreeRow:not(.blocklyTreeSelected):hover { - background-color: $brand-dark-gray !important; -} - -.blocklyToolboxDiv .blocklyTreeRow { - color: $black; -} - -.blocklyEditableText tspan { - fill: $black !important; -} - -.blocklyEditableText rect { - fill-opacity: 1 !important; -} - -.blocklyFlyoutBackground { - fill: #fcfcfc !important; - fill-opacity: 1 !important; - stroke: $brand-dark-gray; - stroke-width: 0.15em; - stroke-linecap: round; -} - -.blocklyToolboxDiv { - border-width: thin; - color: $brand-dark-gray; - border-right: 0.06em solid; - width: 11em; - z-index: 99 !important; - left: -100%; - overflow-x: hidden !important; -} - -.blocklyIconShape { - fill: #2a3052 !important; -} - -.blocklyIconGroup:not(:hover), -.blocklyIconGroupReadonly { - opacity: 1 !important; -} - -.blocklySelected > .blocklyPath { - stroke: #fc3; - stroke-width: 2px; -} - -.blocklyTreeRow { - // box-shadow: inset 0 -0.06em 0 0 #dedede; - margin-bottom: 0px !important; - height: 1.9em !important; - padding-top: 0.25em; -} - -.blocklySvg { - background-color: $white !important; - position: absolute; -} - -.scratchCategoryMenu { - width: 100%; - color: #575e75; - font-size: 1em; - user-select: none; -} - -.scratchCategoryMenuItem { - padding: 0.5em 1em; - cursor: pointer; - text-align: left; -} - -.scratchCategoryItemBubble { - display: none; -} - -#scratch_area { - position: absolute; - height: 100%; - width: 100%; -} - -#scratch_div { - position: absolute; -} \ No newline at end of file From f00695ec93d49aa5e9639899fb6d0a372d686e9b Mon Sep 17 00:00:00 2001 From: Aaron Imming Date: Mon, 8 Jul 2019 11:12:34 +0800 Subject: [PATCH 14/15] Create vendor sass function --- src/assets/sass/base/mixins.scss | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 src/assets/sass/base/mixins.scss diff --git a/src/assets/sass/base/mixins.scss b/src/assets/sass/base/mixins.scss new file mode 100644 index 00000000..58357551 --- /dev/null +++ b/src/assets/sass/base/mixins.scss @@ -0,0 +1,7 @@ +@mixin vendor($property, $value) { + $prefixes: ('moz', 'webkit', 'ms', 'o'); + @each $prefix in $prefixes { + -#{$prefix}-#{$property}: #{$value}; + } + #{$property}: #{$value}; +} \ No newline at end of file From 793c00562341c2a644069c8355367acc48bafb22 Mon Sep 17 00:00:00 2001 From: Aaron Imming Date: Mon, 8 Jul 2019 11:13:14 +0800 Subject: [PATCH 15/15] Use vendor function for 'experimental' CSS --- src/assets/sass/scratch/_flyout.scss | 4 +++- src/assets/sass/scratch/_toolbox.scss | 8 +++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/assets/sass/scratch/_flyout.scss b/src/assets/sass/scratch/_flyout.scss index ca293f87..d43f3ea1 100644 --- a/src/assets/sass/scratch/_flyout.scss +++ b/src/assets/sass/scratch/_flyout.scss @@ -1,5 +1,7 @@ +@import '../base/mixins'; + .blocklyFlyout { - filter: drop-shadow(0 10px 5px #999); + @include vendor(filter, drop-shadow(0 10px 5px #999)); } .blocklyFlyoutBackground { diff --git a/src/assets/sass/scratch/_toolbox.scss b/src/assets/sass/scratch/_toolbox.scss index 6f1b32ad..6b741eb7 100644 --- a/src/assets/sass/scratch/_toolbox.scss +++ b/src/assets/sass/scratch/_toolbox.scss @@ -1,3 +1,5 @@ +@import '../base/mixins'; + $category-colours: ( trade-definition: #303f9f, before-purchase : #00897b, @@ -63,8 +65,8 @@ $category-colours: ( position: absolute; top: 0.6em; right: 0.6em; - transform: rotate(90deg); - transition: transform 0.25s ease; + @include vendor(transform, rotate(90deg)); + @include vendor(transition, transform 0.25s ease); } &__item { position: relative; @@ -90,7 +92,7 @@ $category-colours: ( } #{$toolbox}__arrow { position: relative; - transform: rotate(270deg); + @include vendor(transform, rotate(270deg)); margin-top: -2px; top: 0; right: -2px;