<commit_before>/**
 * @license
 * Visual Blocks Editor
 *
 * Copyright 2017 Google Inc.
 * https://developers.google.com/blockly/
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @fileoverview Layout code for a vertical variant of the flyout.
 * @author <EMAIL> (<NAME>)
 */
'use strict';

goog.provide('Blockly.VerticalFlyout');

goog.require('Blockly.Block');
goog.require('Blockly.Comment');
goog.require('Blockly.Events');
goog.require('Blockly.Flyout');
goog.require('Blockly.FlyoutButton');
goog.require('Blockly.utils');
goog.require('Blockly.WorkspaceSvg');
goog.require('goog.dom');
goog.require('goog.dom.animationFrame.polyfill');
goog.require('goog.events');
goog.require('goog.math.Rect');
goog.require('goog.userAgent');


/**
 * Class for a flyout.
 * @param {!Object} workspaceOptions Dictionary of options for the workspace.
 * @extends {Blockly.Flyout}
 * @constructor
 */
Blockly.VerticalFlyout = function(workspaceOptions) {
  workspaceOptions.getMetrics = this.getMetrics_.bind(this);
  workspaceOptions.setMetrics = this.setMetrics_.bind(this);

  Blockly.VerticalFlyout.superClass_.constructor.call(this, workspaceOptions);
  /**
   * Flyout should be laid out vertically.
   * @type {boolean}
   * @private
   */
  this.horizontalLayout_ = false;

  /**
   * List of checkboxes next to variable blocks.
   * Each element is an object containing the SVG for the checkbox, a boolean
   * for its checked state, and the block the checkbox is associated with.
   * @type {!Array.<!Object>}
   * @private
   */
  this.checkboxes_ = [];
};
goog.inherits(Blockly.VerticalFlyout, Blockly.Flyout);

/**
 * Does the flyout automatically close when a block is created?
 * @type {boolean}
 */
Blockly.VerticalFlyout.prototype.autoClose = false;

/**
 * The width of the flyout, if not otherwise specified.
 * @type {number}
 */
Blockly.VerticalFlyout.prototype.DEFAULT_WIDTH = 250;

/**
 * Size of a checkbox next to a variable reporter.
 * @type {number}
 * @const
 */
Blockly.VerticalFlyout.prototype.CHECKBOX_SIZE = 20;

/**
 * SVG path data for checkmark in checkbox.
 * @type {string}
 * @const
 */
Blockly.VerticalFlyout.prototype.CHECKMARK_PATH =
    'M' + Blockly.VerticalFlyout.prototype.CHECKBOX_SIZE / 4 +
    ' ' + Blockly.VerticalFlyout.prototype.CHECKBOX_SIZE / 2 +
    'L' + 5 * Blockly.VerticalFlyout.prototype.CHECKBOX_SIZE / 12 +
    ' ' + 2 * Blockly.VerticalFlyout.prototype.CHECKBOX_SIZE / 3 +
    'L' + 3 * Blockly.VerticalFlyout.prototype.CHECKBOX_SIZE / 4 +
    ' ' + Blockly.VerticalFlyout.prototype.CHECKBOX_SIZE / 3;

/**
 * Size of the checkbox corner radius
 * @type {number}
 * @const
 */
Blockly.VerticalFlyout.prototype.CHECKBOX_CORNER_RADIUS = 5;

/**
 * Space above and around the checkbox.
 * @type {number}
 * @const
 */
Blockly.VerticalFlyout.prototype.CHECKBOX_MARGIN = Blockly.Flyout.prototype.MARGIN;

/**
 * Total additional width of a row that contains a checkbox.
 * @type {number}
 * @const
 */
Blockly.VerticalFlyout.prototype.CHECKBOX_SPACE_X =
    Blockly.VerticalFlyout.prototype.CHECKBOX_SIZE +
    2 * Blockly.VerticalFlyout.prototype.CHECKBOX_MARGIN;

/**
 * Initializes the flyout.
 * @param {!Blockly.Workspace} targetWorkspace The workspace in which to create
 *     new blocks.
 */
Blockly.VerticalFlyout.prototype.init = function(targetWorkspace) {
  Blockly.VerticalFlyout.superClass_.init.call(this, targetWorkspace);
  this.workspace_.scale = targetWorkspace.scale;
};

/**
 * Creates the flyout's DOM.  Only needs to be called once.
 * @param {string} tagName HTML element
 * @return {!Element} The flyout's SVG group.
 */
Blockly.VerticalFlyout.prototype.createDom = function(tagName) {
  Blockly.VerticalFlyout.superClass_.createDom.call(this, tagName);

  /*
    <defs>
      <clipPath id="blocklyBlockMenuClipPath">
        <rect id="blocklyBlockMenuClipRect" height="1147px"
            width="248px" y="0" x="0">
        </rect>
      </clipPath>
    </defs>
  */
  this.defs_ = Blockly.utils.createSvgElement('defs', {}, this.svgGroup_);
  var clipPath = Blockly.utils.createSvgElement('clipPath',
      {'id':'blocklyBlockMenuClipPath'}, this.defs_);
  this.clipRect_ = Blockly.utils.createSvgElement('rect',
      {
        'id': 'blocklyBlockMenuClipRect',
        'height': '0',
        'width': '0',
        'y': '0',
        'x': '0'
      },
      clipPath);
  this.workspace_.svgGroup_.setAttribute(
      'clip-path', 'url(#blocklyBlockMenuClipPath)');

  return this.svgGroup_;
};

/**
 * 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;
  }

  try {
    var optionBox = this.workspace_.getCanvas().getBBox();
  } catch (e) {
    // Firefox has trouble with hidden elements (Bug 528969).
    var optionBox = {height: 0, y: 0, width: 0, x: 0};
  }

  // Padding for the end of the scrollbar.
  var absoluteTop = this.SCROLLBAR_PADDING;
  var absoluteLeft = 0;

  var viewHeight = this.height_ - 2 * this.SCROLLBAR_PADDING;
  var viewWidth = this.getWidth() - this.SCROLLBAR_PADDING;

  // Add padding to the bottom of the flyout, so we can scroll to the top of
  // the last category.
  var contentHeight = optionBox.height * this.workspace_.scale;
  this.recordCategoryScrollPositions_();
  var lastLabel = this.categoryScrollPositions[
      this.categoryScrollPositions.length - 1];
  var lastPos = lastLabel.position * this.workspace_.scale;
  var lastCategoryHeight = contentHeight - lastPos;
  var bottomPadding = viewHeight - lastCategoryHeight;

  var metrics = {
    viewHeight: viewHeight,
    viewWidth: viewWidth,
    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: absoluteTop,
    absoluteLeft: absoluteLeft<commit_msg>Handle very long extension categories<commit_after>/**
 * @license
 * Visual Blocks Editor
 *
 * Copyright 2017 Google Inc.
 * https://developers.google.com/blockly/
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @fileoverview Layout code for a vertical variant of the flyout.
 * @author <EMAIL> (<NAME>)
 */
'use strict';

goog.provide('Blockly.VerticalFlyout');

goog.require('Blockly.Block');
goog.require('Blockly.Comment');
goog.require('Blockly.Events');
goog.require('Blockly.Flyout');
goog.require('Blockly.FlyoutButton');
goog.require('Blockly.utils');
goog.require('Blockly.WorkspaceSvg');
goog.require('goog.dom');
goog.require('goog.dom.animationFrame.polyfill');
goog.require('goog.events');
goog.require('goog.math.Rect');
goog.require('goog.userAgent');


/**
 * Class for a flyout.
 * @param {!Object} workspaceOptions Dictionary of options for the workspace.
 * @extends {Blockly.Flyout}
 * @constructor
 */
Blockly.VerticalFlyout = function(workspaceOptions) {
  workspaceOptions.getMetrics = this.getMetrics_.bind(this);
  workspaceOptions.setMetrics = this.setMetrics_.bind(this);

  Blockly.VerticalFlyout.superClass_.constructor.call(this, workspaceOptions);
  /**
   * Flyout should be laid out vertically.
   * @type {boolean}
   * @private
   */
  this.horizontalLayout_ = false;

  /**
   * List of checkboxes next to variable blocks.
   * Each element is an object containing the SVG for the checkbox, a boolean
   * for its checked state, and the block the checkbox is associated with.
   * @type {!Array.<!Object>}
   * @private
   */
  this.checkboxes_ = [];
};
goog.inherits(Blockly.VerticalFlyout, Blockly.Flyout);

/**
 * Does the flyout automatically close when a block is created?
 * @type {boolean}
 */
Blockly.VerticalFlyout.prototype.autoClose = false;

/**
 * The width of the flyout, if not otherwise specified.
 * @type {number}
 */
Blockly.VerticalFlyout.prototype.DEFAULT_WIDTH = 250;

/**
 * Size of a checkbox next to a variable reporter.
 * @type {number}
 * @const
 */
Blockly.VerticalFlyout.prototype.CHECKBOX_SIZE = 20;

/**
 * SVG path data for checkmark in checkbox.
 * @type {string}
 * @const
 */
Blockly.VerticalFlyout.prototype.CHECKMARK_PATH =
    'M' + Blockly.VerticalFlyout.prototype.CHECKBOX_SIZE / 4 +
    ' ' + Blockly.VerticalFlyout.prototype.CHECKBOX_SIZE / 2 +
    'L' + 5 * Blockly.VerticalFlyout.prototype.CHECKBOX_SIZE / 12 +
    ' ' + 2 * Blockly.VerticalFlyout.prototype.CHECKBOX_SIZE / 3 +
    'L' + 3 * Blockly.VerticalFlyout.prototype.CHECKBOX_SIZE / 4 +
    ' ' + Blockly.VerticalFlyout.prototype.CHECKBOX_SIZE / 3;

/**
 * Size of the checkbox corner radius
 * @type {number}
 * @const
 */
Blockly.VerticalFlyout.prototype.CHECKBOX_CORNER_RADIUS = 5;

/**
 * Space above and around the checkbox.
 * @type {number}
 * @const
 */
Blockly.VerticalFlyout.prototype.CHECKBOX_MARGIN = Blockly.Flyout.prototype.MARGIN;

/**
 * Total additional width of a row that contains a checkbox.
 * @type {number}
 * @const
 */
Blockly.VerticalFlyout.prototype.CHECKBOX_SPACE_X =
    Blockly.VerticalFlyout.prototype.CHECKBOX_SIZE +
    2 * Blockly.VerticalFlyout.prototype.CHECKBOX_MARGIN;

/**
 * Initializes the flyout.
 * @param {!Blockly.Workspace} targetWorkspace The workspace in which to create
 *     new blocks.
 */
Blockly.VerticalFlyout.prototype.init = function(targetWorkspace) {
  Blockly.VerticalFlyout.superClass_.init.call(this, targetWorkspace);
  this.workspace_.scale = targetWorkspace.scale;
};

/**
 * Creates the flyout's DOM.  Only needs to be called once.
 * @param {string} tagName HTML element
 * @return {!Element} The flyout's SVG group.
 */
Blockly.VerticalFlyout.prototype.createDom = function(tagName) {
  Blockly.VerticalFlyout.superClass_.createDom.call(this, tagName);

  /*
    <defs>
      <clipPath id="blocklyBlockMenuClipPath">
        <rect id="blocklyBlockMenuClipRect" height="1147px"
            width="248px" y="0" x="0">
        </rect>
      </clipPath>
    </defs>
  */
  this.defs_ = Blockly.utils.createSvgElement('defs', {}, this.svgGroup_);
  var clipPath = Blockly.utils.createSvgElement('clipPath',
      {'id':'blocklyBlockMenuClipPath'}, this.defs_);
  this.clipRect_ = Blockly.utils.createSvgElement('rect',
      {
        'id': 'blocklyBlockMenuClipRect',
        'height': '0',
        'width': '0',
        'y': '0',
        'x': '0'
      },
      clipPath);
  this.workspace_.svgGroup_.setAttribute(
      'clip-path', 'url(#blocklyBlockMenuClipPath)');

  return this.svgGroup_;
};

/**
 * 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;
  }

  try {
    var optionBox = this.workspace_.getCanvas().getBBox();
  } catch (e) {
    // Firefox has trouble with hidden elements (Bug 528969).
    var optionBox = {height: 0, y: 0, width: 0, x: 0};
  }

  // Padding for the end of the scrollbar.
  var absoluteTop = this.SCROLLBAR_PADDING;
  var absoluteLeft = 0;

  var viewHeight = this.height_ - 2 * this.SCROLLBAR_PADDING;
  var viewWidth = this.getWidth() - this.SCROLLBAR_PADDING;

  // Add padding to the bottom of the flyout, so we can scroll to the top of
  // the last category.
  var contentHeight = optionBox.height * this.workspace_.scale;
  this.recordCategoryScrollPositions_();
  var lastLabel = this.categoryScrollPositions[
      this.categoryScrollPositions.length - 1];
  var lastPos = lastLabel.position * this.workspace_.scale;
  var lastCategoryHeight = contentHeight - lastPos;
  var bottomPadding = this.MARGIN;
  if (lastCategoryHeight < viewHeight) {
    bottomPadding = viewHeight - lastCategoryHeight;
  }

  var metrics = {
    viewHeight: viewHeight,
    viewWidth: viewWidth,
    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: absoluteTop,
    absoluteLeft: absoluteLeft
{'fraction_non_alphanumeric': 0.11952630129440925, 'fraction_numerical': 0.007435968052877995, 'mean_word_length': 3.8016528925619837, 'pattern_counts': {'":': 0, '<': 22, '<?xml version=': 0, '>': 21, 'https://': 2, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3064264', 'n_tokens_mistral': 4627, 'n_tokens_neox': 4419, 'n_words': 1218}