blockly 7.20211209.4 → 8.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (231) hide show
  1. package/blockly.d.ts +18963 -18432
  2. package/blockly.min.js +5 -4
  3. package/blockly_compressed.js +4 -3
  4. package/blockly_compressed.js.map +1 -1
  5. package/blocks/blocks.js +47 -0
  6. package/blocks/colour.js +13 -3
  7. package/blocks/lists.js +22 -13
  8. package/blocks/logic.js +13 -3
  9. package/blocks/loops.js +24 -11
  10. package/blocks/math.js +12 -3
  11. package/blocks/procedures.js +45 -32
  12. package/blocks/text.js +22 -13
  13. package/blocks/variables.js +14 -3
  14. package/blocks/variables_dynamic.js +13 -3
  15. package/blocks_compressed.js +1 -1
  16. package/blocks_compressed.js.map +1 -1
  17. package/core/block.js +1869 -1814
  18. package/core/block_drag_surface.js +201 -200
  19. package/core/block_dragger.js +377 -373
  20. package/core/block_svg.js +1593 -1479
  21. package/core/blockly.js +8 -22
  22. package/core/blocks.js +9 -2
  23. package/core/browser_events.js +22 -5
  24. package/core/bubble.js +841 -797
  25. package/core/bubble_dragger.js +213 -206
  26. package/core/bump_objects.js +2 -2
  27. package/core/clipboard.js +9 -9
  28. package/core/comment.js +353 -332
  29. package/core/common.js +46 -17
  30. package/core/component_manager.js +181 -174
  31. package/core/config.js +87 -0
  32. package/core/connection.js +595 -584
  33. package/core/connection_checker.js +242 -244
  34. package/core/connection_db.js +235 -230
  35. package/core/contextmenu.js +9 -6
  36. package/core/contextmenu_items.js +1 -2
  37. package/core/contextmenu_registry.js +93 -89
  38. package/core/css.js +474 -474
  39. package/core/delete_area.js +45 -42
  40. package/core/drag_target.js +57 -56
  41. package/core/dropdowndiv.js +153 -163
  42. package/core/events/events.js +2 -2
  43. package/core/events/events_abstract.js +89 -77
  44. package/core/events/events_block_base.js +37 -36
  45. package/core/events/events_block_change.js +130 -124
  46. package/core/events/events_block_create.js +73 -71
  47. package/core/events/events_block_delete.js +84 -82
  48. package/core/events/events_block_drag.js +50 -49
  49. package/core/events/events_block_move.js +147 -140
  50. package/core/events/events_bubble_open.js +51 -50
  51. package/core/events/events_click.js +48 -44
  52. package/core/events/events_comment_base.js +72 -69
  53. package/core/events/events_comment_change.js +63 -61
  54. package/core/events/events_comment_create.js +44 -42
  55. package/core/events/events_comment_delete.js +42 -40
  56. package/core/events/events_comment_move.js +106 -104
  57. package/core/events/events_marker_move.js +65 -64
  58. package/core/events/events_selected.js +46 -45
  59. package/core/events/events_theme_change.js +36 -35
  60. package/core/events/events_toolbox_item_select.js +46 -45
  61. package/core/events/events_trashcan_open.js +37 -36
  62. package/core/events/events_ui.js +47 -46
  63. package/core/events/events_ui_base.js +30 -29
  64. package/core/events/events_var_base.js +37 -36
  65. package/core/events/events_var_create.js +50 -48
  66. package/core/events/events_var_delete.js +50 -48
  67. package/core/events/events_var_rename.js +51 -49
  68. package/core/events/events_viewport.js +66 -65
  69. package/core/events/utils.js +29 -14
  70. package/core/events/workspace_events.js +49 -55
  71. package/core/extensions.js +4 -3
  72. package/core/field.js +1061 -997
  73. package/core/field_angle.js +462 -442
  74. package/core/field_checkbox.js +194 -182
  75. package/core/field_colour.js +519 -505
  76. package/core/field_dropdown.js +617 -598
  77. package/core/field_image.js +229 -220
  78. package/core/field_label.js +102 -91
  79. package/core/field_label_serializable.js +42 -41
  80. package/core/field_multilineinput.js +372 -358
  81. package/core/field_number.js +272 -253
  82. package/core/field_textinput.js +499 -467
  83. package/core/field_variable.js +458 -420
  84. package/core/flyout_base.js +1005 -952
  85. package/core/flyout_button.js +277 -260
  86. package/core/flyout_horizontal.js +304 -302
  87. package/core/flyout_metrics_manager.js +64 -64
  88. package/core/flyout_vertical.js +306 -300
  89. package/core/generator.js +459 -446
  90. package/core/gesture.js +829 -813
  91. package/core/grid.js +166 -163
  92. package/core/icon.js +168 -159
  93. package/core/inject.js +7 -5
  94. package/core/input.js +257 -248
  95. package/core/insertion_marker_manager.js +655 -624
  96. package/core/internal_constants.js +0 -129
  97. package/core/keyboard_nav/ast_node.js +605 -596
  98. package/core/keyboard_nav/basic_cursor.js +166 -165
  99. package/core/keyboard_nav/cursor.js +99 -97
  100. package/core/keyboard_nav/marker.js +83 -79
  101. package/core/keyboard_nav/tab_navigate_cursor.js +18 -23
  102. package/core/marker_manager.js +153 -141
  103. package/core/menu.js +377 -372
  104. package/core/menuitem.js +223 -217
  105. package/core/metrics_manager.js +403 -390
  106. package/core/mutator.js +468 -437
  107. package/core/names.js +229 -188
  108. package/core/options.js +290 -284
  109. package/core/procedures.js +29 -17
  110. package/core/registry.js +19 -16
  111. package/core/rendered_connection.js +482 -463
  112. package/core/renderers/common/block_rendering.js +9 -3
  113. package/core/renderers/common/constants.js +1119 -1112
  114. package/core/renderers/common/debug.js +14 -0
  115. package/core/renderers/common/debugger.js +338 -316
  116. package/core/renderers/common/drawer.js +380 -370
  117. package/core/renderers/common/i_path_object.js +2 -2
  118. package/core/renderers/common/info.js +626 -618
  119. package/core/renderers/common/marker_svg.js +579 -541
  120. package/core/renderers/common/path_object.js +203 -200
  121. package/core/renderers/common/renderer.js +220 -218
  122. package/core/renderers/geras/constants.js +36 -36
  123. package/core/renderers/geras/drawer.js +155 -147
  124. package/core/renderers/geras/highlight_constants.js +244 -238
  125. package/core/renderers/geras/highlighter.js +231 -179
  126. package/core/renderers/geras/info.js +392 -369
  127. package/core/renderers/geras/measurables/inline_input.js +25 -19
  128. package/core/renderers/geras/measurables/statement_input.js +23 -17
  129. package/core/renderers/geras/path_object.js +106 -121
  130. package/core/renderers/geras/renderer.js +96 -98
  131. package/core/renderers/measurables/base.js +30 -18
  132. package/core/renderers/measurables/bottom_row.js +83 -80
  133. package/core/renderers/measurables/connection.js +22 -15
  134. package/core/renderers/measurables/external_value_input.js +35 -22
  135. package/core/renderers/measurables/field.js +35 -20
  136. package/core/renderers/measurables/hat.js +18 -13
  137. package/core/renderers/measurables/icon.js +24 -17
  138. package/core/renderers/measurables/in_row_spacer.js +15 -13
  139. package/core/renderers/measurables/inline_input.js +43 -33
  140. package/core/renderers/measurables/input_connection.js +41 -28
  141. package/core/renderers/measurables/input_row.js +50 -44
  142. package/core/renderers/measurables/jagged_edge.js +14 -12
  143. package/core/renderers/measurables/next_connection.js +16 -14
  144. package/core/renderers/measurables/output_connection.js +26 -20
  145. package/core/renderers/measurables/previous_connection.js +16 -15
  146. package/core/renderers/measurables/round_corner.js +20 -18
  147. package/core/renderers/measurables/row.js +184 -168
  148. package/core/renderers/measurables/spacer_row.js +38 -23
  149. package/core/renderers/measurables/square_corner.js +18 -16
  150. package/core/renderers/measurables/statement_input.js +23 -20
  151. package/core/renderers/measurables/top_row.js +88 -85
  152. package/core/renderers/minimalist/constants.js +8 -7
  153. package/core/renderers/minimalist/drawer.js +11 -10
  154. package/core/renderers/minimalist/info.js +18 -18
  155. package/core/renderers/minimalist/renderer.js +40 -39
  156. package/core/renderers/thrasos/info.js +258 -248
  157. package/core/renderers/thrasos/renderer.js +20 -20
  158. package/core/renderers/zelos/constants.js +898 -873
  159. package/core/renderers/zelos/drawer.js +186 -169
  160. package/core/renderers/zelos/info.js +502 -479
  161. package/core/renderers/zelos/marker_svg.js +129 -115
  162. package/core/renderers/zelos/measurables/bottom_row.js +31 -30
  163. package/core/renderers/zelos/measurables/inputs.js +22 -21
  164. package/core/renderers/zelos/measurables/row_elements.js +14 -13
  165. package/core/renderers/zelos/measurables/top_row.js +34 -33
  166. package/core/renderers/zelos/path_object.js +181 -180
  167. package/core/renderers/zelos/renderer.js +91 -92
  168. package/core/scrollbar.js +759 -713
  169. package/core/scrollbar_pair.js +250 -245
  170. package/core/serialization/blocks.js +26 -10
  171. package/core/serialization/workspaces.js +3 -2
  172. package/core/shortcut_registry.js +286 -277
  173. package/core/sprites.js +31 -0
  174. package/core/theme.js +135 -141
  175. package/core/theme_manager.js +147 -143
  176. package/core/toolbox/category.js +602 -576
  177. package/core/toolbox/collapsible_category.js +226 -227
  178. package/core/toolbox/separator.js +70 -61
  179. package/core/toolbox/toolbox.js +934 -927
  180. package/core/toolbox/toolbox_item.js +115 -99
  181. package/core/tooltip.js +108 -35
  182. package/core/touch.js +8 -3
  183. package/core/touch_gesture.js +254 -251
  184. package/core/trashcan.js +606 -595
  185. package/core/utils/coordinate.js +97 -95
  186. package/core/utils/dom.js +2 -2
  187. package/core/utils/global.js +2 -0
  188. package/core/utils/rect.js +41 -37
  189. package/core/utils/sentinel.js +25 -0
  190. package/core/utils/size.js +30 -27
  191. package/core/utils/svg.js +18 -16
  192. package/core/variable_map.js +325 -341
  193. package/core/variable_model.js +55 -54
  194. package/core/variables.js +9 -2
  195. package/core/variables_dynamic.js +3 -1
  196. package/core/warning.js +126 -120
  197. package/core/widgetdiv.js +4 -4
  198. package/core/workspace.js +685 -664
  199. package/core/workspace_audio.js +124 -118
  200. package/core/workspace_comment.js +308 -298
  201. package/core/workspace_comment_svg.js +1029 -951
  202. package/core/workspace_drag_surface_svg.js +147 -140
  203. package/core/workspace_dragger.js +70 -71
  204. package/core/workspace_svg.js +2322 -2297
  205. package/core/xml.js +30 -20
  206. package/core/zoom_controls.js +431 -439
  207. package/generators/dart/colour.js +56 -64
  208. package/generators/dart/lists.js +61 -50
  209. package/generators/dart/math.js +160 -148
  210. package/generators/dart/text.js +83 -61
  211. package/generators/javascript/colour.js +37 -34
  212. package/generators/javascript/lists.js +50 -43
  213. package/generators/javascript/math.js +123 -139
  214. package/generators/javascript/text.js +67 -81
  215. package/generators/lua/colour.js +25 -23
  216. package/generators/lua/lists.js +97 -69
  217. package/generators/lua/logic.js +1 -2
  218. package/generators/lua/math.js +182 -144
  219. package/generators/lua/text.js +116 -99
  220. package/generators/php/colour.js +38 -32
  221. package/generators/php/lists.js +109 -89
  222. package/generators/php/math.js +90 -81
  223. package/generators/php/text.js +63 -61
  224. package/generators/python/colour.js +18 -18
  225. package/generators/python/lists.js +38 -30
  226. package/generators/python/loops.js +12 -8
  227. package/generators/python/math.js +104 -106
  228. package/generators/python/text.js +34 -30
  229. package/msg/smn.js +436 -0
  230. package/package.json +7 -6
  231. package/blocks/all.js +0 -23
@@ -19,13 +19,22 @@ goog.module('Blockly.geras.Highlighter');
19
19
 
20
20
  const svgPaths = goog.require('Blockly.utils.svgPaths');
21
21
  /* eslint-disable-next-line no-unused-vars */
22
+ const {BottomRow} = goog.require('Blockly.blockRendering.BottomRow');
23
+ /* eslint-disable-next-line no-unused-vars */
22
24
  const {ConstantProvider} = goog.requireType('Blockly.blockRendering.ConstantProvider');
23
25
  /* eslint-disable-next-line no-unused-vars */
24
26
  const {HighlightConstantProvider} = goog.requireType('Blockly.geras.HighlightConstantProvider');
25
27
  /* eslint-disable-next-line no-unused-vars */
28
+ const {InlineInput} = goog.require('Blockly.geras.InlineInput');
29
+ /* eslint-disable-next-line no-unused-vars */
26
30
  const {RenderInfo} = goog.requireType('Blockly.geras.RenderInfo');
27
31
  /* eslint-disable-next-line no-unused-vars */
28
32
  const {Renderer} = goog.requireType('Blockly.geras.Renderer');
33
+ /* eslint-disable-next-line no-unused-vars */
34
+ const {Row} = goog.requireType('Blockly.blockRendering.Row');
35
+ const {SpacerRow} = goog.require('Blockly.blockRendering.SpacerRow');
36
+ /* eslint-disable-next-line no-unused-vars */
37
+ const {TopRow} = goog.require('Blockly.blockRendering.TopRow');
29
38
  const {Types} = goog.require('Blockly.blockRendering.Types');
30
39
 
31
40
 
@@ -39,221 +48,264 @@ const {Types} = goog.require('Blockly.blockRendering.Types');
39
48
  * position of each part of the block. The resulting paths are not continuous
40
49
  * or closed paths. The highlights for tabs and notches are loosely based on
41
50
  * tab and notch shapes, but are not exactly the same.
42
- *
43
- * @param {!RenderInfo} info An object containing all
44
- * information needed to render this block.
45
- * @package
46
- * @constructor
47
51
  * @alias Blockly.geras.Highlighter
48
52
  */
49
- const Highlighter = function(info) {
50
- this.info_ = info;
51
- this.steps_ = '';
52
- this.inlineSteps_ = '';
53
-
54
- this.RTL_ = this.info_.RTL;
55
-
56
- const renderer = /** @type {!Renderer} */ (info.getRenderer());
57
-
53
+ class Highlighter {
58
54
  /**
59
- * The renderer's constant provider.
60
- * @type {!ConstantProvider}
55
+ * @param {!RenderInfo} info An object containing all
56
+ * information needed to render this block.
57
+ * @package
61
58
  */
62
- this.constants_ = renderer.getConstants();
59
+ constructor(info) {
60
+ this.info_ = info;
61
+ this.steps_ = '';
62
+ this.inlineSteps_ = '';
63
63
 
64
- /**
65
- * @type {!HighlightConstantProvider}
66
- */
67
- this.highlightConstants_ = renderer.getHighlightConstants();
68
- /**
69
- * The offset between the block's main path and highlight path.
70
- * @type {number}
71
- * @private
72
- */
73
- this.highlightOffset_ = this.highlightConstants_.OFFSET;
64
+ this.RTL_ = this.info_.RTL;
74
65
 
75
- this.outsideCornerPaths_ = this.highlightConstants_.OUTSIDE_CORNER;
76
- this.insideCornerPaths_ = this.highlightConstants_.INSIDE_CORNER;
77
- this.puzzleTabPaths_ = this.highlightConstants_.PUZZLE_TAB;
78
- this.notchPaths_ = this.highlightConstants_.NOTCH;
79
- this.startPaths_ = this.highlightConstants_.START_HAT;
80
- this.jaggedTeethPaths_ = this.highlightConstants_.JAGGED_TEETH;
81
- };
66
+ const renderer = /** @type {!Renderer} */ (info.getRenderer());
82
67
 
83
- /**
84
- * Get the steps for the highlight path.
85
- * @return {string} The steps for the highlight path.
86
- * @package
87
- */
88
- Highlighter.prototype.getPath = function() {
89
- return this.steps_ + '\n' + this.inlineSteps_;
90
- };
68
+ /**
69
+ * The renderer's constant provider.
70
+ * @type {!ConstantProvider}
71
+ */
72
+ this.constants_ = renderer.getConstants();
91
73
 
92
- Highlighter.prototype.drawTopCorner = function(row) {
93
- this.steps_ += svgPaths.moveBy(row.xPos, this.info_.startY);
94
- for (let i = 0, elem; (elem = row.elements[i]); i++) {
95
- if (Types.isLeftSquareCorner(elem)) {
96
- this.steps_ += this.highlightConstants_.START_POINT;
97
- } else if (Types.isLeftRoundedCorner(elem)) {
98
- this.steps_ += this.outsideCornerPaths_.topLeft(this.RTL_);
99
- } else if (Types.isPreviousConnection(elem)) {
100
- this.steps_ += this.notchPaths_.pathLeft;
101
- } else if (Types.isHat(elem)) {
102
- this.steps_ += this.startPaths_.path(this.RTL_);
103
- } else if (Types.isSpacer(elem) && elem.width !== 0) {
104
- // The end point of the spacer needs to be offset by the highlight amount.
105
- // So instead of using the spacer's width for a relative horizontal, use
106
- // its width and position for an absolute horizontal move.
107
- this.steps_ += svgPaths.lineOnAxis(
108
- 'H', elem.xPos + elem.width - this.highlightOffset_);
109
- }
110
- }
74
+ /**
75
+ * @type {!HighlightConstantProvider}
76
+ */
77
+ this.highlightConstants_ = renderer.getHighlightConstants();
78
+ /**
79
+ * The offset between the block's main path and highlight path.
80
+ * @type {number}
81
+ * @private
82
+ */
83
+ this.highlightOffset_ = this.highlightConstants_.OFFSET;
111
84
 
112
- const right = row.xPos + row.width - this.highlightOffset_;
113
- this.steps_ += svgPaths.lineOnAxis('H', right);
114
- };
85
+ this.outsideCornerPaths_ = this.highlightConstants_.OUTSIDE_CORNER;
86
+ this.insideCornerPaths_ = this.highlightConstants_.INSIDE_CORNER;
87
+ this.puzzleTabPaths_ = this.highlightConstants_.PUZZLE_TAB;
88
+ this.notchPaths_ = this.highlightConstants_.NOTCH;
89
+ this.startPaths_ = this.highlightConstants_.START_HAT;
90
+ this.jaggedTeethPaths_ = this.highlightConstants_.JAGGED_TEETH;
91
+ }
115
92
 
116
- Highlighter.prototype.drawJaggedEdge_ = function(row) {
117
- if (this.info_.RTL) {
118
- const remainder =
119
- row.height - this.jaggedTeethPaths_.height - this.highlightOffset_;
120
- this.steps_ +=
121
- this.jaggedTeethPaths_.pathLeft + svgPaths.lineOnAxis('v', remainder);
93
+ /**
94
+ * Get the steps for the highlight path.
95
+ * @return {string} The steps for the highlight path.
96
+ * @package
97
+ */
98
+ getPath() {
99
+ return this.steps_ + '\n' + this.inlineSteps_;
122
100
  }
123
- };
124
101
 
125
- Highlighter.prototype.drawValueInput = function(row) {
126
- const input = row.getLastInput();
127
- if (this.RTL_) {
128
- const belowTabHeight = row.height - input.connectionHeight;
102
+ /**
103
+ * Add a highlight to the top corner of a block.
104
+ * @param {!TopRow} row The top row of the block.
105
+ * @package
106
+ */
107
+ drawTopCorner(row) {
108
+ this.steps_ += svgPaths.moveBy(row.xPos, this.info_.startY);
109
+ for (let i = 0, elem; (elem = row.elements[i]); i++) {
110
+ if (Types.isLeftSquareCorner(elem)) {
111
+ this.steps_ += this.highlightConstants_.START_POINT;
112
+ } else if (Types.isLeftRoundedCorner(elem)) {
113
+ this.steps_ += this.outsideCornerPaths_.topLeft(this.RTL_);
114
+ } else if (Types.isPreviousConnection(elem)) {
115
+ this.steps_ += this.notchPaths_.pathLeft;
116
+ } else if (Types.isHat(elem)) {
117
+ this.steps_ += this.startPaths_.path(this.RTL_);
118
+ } else if (Types.isSpacer(elem) && elem.width !== 0) {
119
+ // The end point of the spacer needs to be offset by the highlight
120
+ // amount. So instead of using the spacer's width for a relative
121
+ // horizontal, use its width and position for an absolute horizontal
122
+ // move.
123
+ this.steps_ += svgPaths.lineOnAxis(
124
+ 'H', elem.xPos + elem.width - this.highlightOffset_);
125
+ }
126
+ }
129
127
 
130
- this.steps_ +=
131
- svgPaths.moveTo(
132
- input.xPos + input.width - this.highlightOffset_, row.yPos) +
133
- this.puzzleTabPaths_.pathDown(this.RTL_) +
134
- svgPaths.lineOnAxis('v', belowTabHeight);
135
- } else {
136
- this.steps_ += svgPaths.moveTo(input.xPos + input.width, row.yPos) +
137
- this.puzzleTabPaths_.pathDown(this.RTL_);
128
+ const right = row.xPos + row.width - this.highlightOffset_;
129
+ this.steps_ += svgPaths.lineOnAxis('H', right);
138
130
  }
139
- };
140
131
 
141
- Highlighter.prototype.drawStatementInput = function(row) {
142
- const input = row.getLastInput();
143
- if (this.RTL_) {
144
- const innerHeight = row.height - (2 * this.insideCornerPaths_.height);
145
- this.steps_ += svgPaths.moveTo(input.xPos, row.yPos) +
146
- this.insideCornerPaths_.pathTop(this.RTL_) +
147
- svgPaths.lineOnAxis('v', innerHeight) +
148
- this.insideCornerPaths_.pathBottom(this.RTL_) +
149
- svgPaths.lineTo(
150
- row.width - input.xPos - this.insideCornerPaths_.width, 0);
151
- } else {
152
- this.steps_ += svgPaths.moveTo(input.xPos, row.yPos + row.height) +
153
- this.insideCornerPaths_.pathBottom(this.RTL_) +
154
- svgPaths.lineTo(
155
- row.width - input.xPos - this.insideCornerPaths_.width, 0);
132
+ /**
133
+ * Add a highlight on a jagged edge for a collapsed block.
134
+ * @param {!Row} row The row to highlight.
135
+ * @package
136
+ */
137
+ drawJaggedEdge_(row) {
138
+ if (this.info_.RTL) {
139
+ const remainder =
140
+ row.height - this.jaggedTeethPaths_.height - this.highlightOffset_;
141
+ this.steps_ +=
142
+ this.jaggedTeethPaths_.pathLeft + svgPaths.lineOnAxis('v', remainder);
143
+ }
156
144
  }
157
- };
158
145
 
159
- Highlighter.prototype.drawRightSideRow = function(row) {
160
- const rightEdge = row.xPos + row.width - this.highlightOffset_;
161
- if (row.followsStatement) {
162
- this.steps_ += svgPaths.lineOnAxis('H', rightEdge);
146
+ /**
147
+ * Add a highlight on a value input.
148
+ * @param {!Row} row The row the input belongs to.
149
+ * @package
150
+ */
151
+ drawValueInput(row) {
152
+ const input = /** @type {!InlineInput}} */ (row.getLastInput());
153
+ if (this.RTL_) {
154
+ const belowTabHeight = row.height - input.connectionHeight;
155
+
156
+ this.steps_ +=
157
+ svgPaths.moveTo(
158
+ input.xPos + input.width - this.highlightOffset_, row.yPos) +
159
+ this.puzzleTabPaths_.pathDown(this.RTL_) +
160
+ svgPaths.lineOnAxis('v', belowTabHeight);
161
+ } else {
162
+ this.steps_ += svgPaths.moveTo(input.xPos + input.width, row.yPos) +
163
+ this.puzzleTabPaths_.pathDown(this.RTL_);
164
+ }
163
165
  }
164
- if (this.RTL_) {
165
- this.steps_ += svgPaths.lineOnAxis('H', rightEdge);
166
- if (row.height > this.highlightOffset_) {
167
- this.steps_ += svgPaths.lineOnAxis(
168
- 'V', row.yPos + row.height - this.highlightOffset_);
166
+
167
+ /**
168
+ * Add a highlight on a statement input.
169
+ * @param {!Row} row The row to highlight.
170
+ * @package
171
+ */
172
+ drawStatementInput(row) {
173
+ const input = row.getLastInput();
174
+ if (this.RTL_) {
175
+ const innerHeight = row.height - (2 * this.insideCornerPaths_.height);
176
+ this.steps_ += svgPaths.moveTo(input.xPos, row.yPos) +
177
+ this.insideCornerPaths_.pathTop(this.RTL_) +
178
+ svgPaths.lineOnAxis('v', innerHeight) +
179
+ this.insideCornerPaths_.pathBottom(this.RTL_) +
180
+ svgPaths.lineTo(
181
+ row.width - input.xPos - this.insideCornerPaths_.width, 0);
182
+ } else {
183
+ this.steps_ += svgPaths.moveTo(input.xPos, row.yPos + row.height) +
184
+ this.insideCornerPaths_.pathBottom(this.RTL_) +
185
+ svgPaths.lineTo(
186
+ row.width - input.xPos - this.insideCornerPaths_.width, 0);
169
187
  }
170
188
  }
171
- };
172
189
 
173
- Highlighter.prototype.drawBottomRow = function(row) {
174
- // Highlight the vertical edge of the bottom row on the input side.
175
- // Highlighting is always from the top left, both in LTR and RTL.
176
- if (this.RTL_) {
177
- this.steps_ +=
178
- svgPaths.lineOnAxis('V', row.baseline - this.highlightOffset_);
179
- } else {
180
- const cornerElem = this.info_.bottomRow.elements[0];
181
- if (Types.isLeftSquareCorner(cornerElem)) {
182
- this.steps_ += svgPaths.moveTo(
183
- row.xPos + this.highlightOffset_,
184
- row.baseline - this.highlightOffset_);
185
- } else if (Types.isLeftRoundedCorner(cornerElem)) {
186
- this.steps_ += svgPaths.moveTo(row.xPos, row.baseline);
187
- this.steps_ += this.outsideCornerPaths_.bottomLeft();
190
+ /**
191
+ * Add a highlight on the right side of a row.
192
+ * @param {!Row} row The row to highlight.
193
+ * @package
194
+ */
195
+ drawRightSideRow(row) {
196
+ const rightEdge = row.xPos + row.width - this.highlightOffset_;
197
+ if (row instanceof SpacerRow && row.followsStatement) {
198
+ this.steps_ += svgPaths.lineOnAxis('H', rightEdge);
199
+ }
200
+ if (this.RTL_) {
201
+ this.steps_ += svgPaths.lineOnAxis('H', rightEdge);
202
+ if (row.height > this.highlightOffset_) {
203
+ this.steps_ += svgPaths.lineOnAxis(
204
+ 'V', row.yPos + row.height - this.highlightOffset_);
205
+ }
188
206
  }
189
207
  }
190
- };
191
208
 
192
- Highlighter.prototype.drawLeft = function() {
193
- const outputConnection = this.info_.outputConnection;
194
- if (outputConnection) {
195
- const tabBottom =
196
- outputConnection.connectionOffsetY + outputConnection.height;
197
- // Draw a line up to the bottom of the tab.
209
+ /**
210
+ * Add a highlight to the bottom row.
211
+ * @param {!BottomRow} row The row to highlight.
212
+ * @package
213
+ */
214
+ drawBottomRow(row) {
215
+ // Highlight the vertical edge of the bottom row on the input side.
216
+ // Highlighting is always from the top left, both in LTR and RTL.
198
217
  if (this.RTL_) {
199
- this.steps_ += svgPaths.moveTo(this.info_.startX, tabBottom);
218
+ this.steps_ +=
219
+ svgPaths.lineOnAxis('V', row.baseline - this.highlightOffset_);
200
220
  } else {
201
- const left = this.info_.startX + this.highlightOffset_;
202
- const bottom = this.info_.bottomRow.baseline - this.highlightOffset_;
203
- this.steps_ += svgPaths.moveTo(left, bottom);
204
- this.steps_ += svgPaths.lineOnAxis('V', tabBottom);
221
+ const cornerElem = this.info_.bottomRow.elements[0];
222
+ if (Types.isLeftSquareCorner(cornerElem)) {
223
+ this.steps_ += svgPaths.moveTo(
224
+ row.xPos + this.highlightOffset_,
225
+ row.baseline - this.highlightOffset_);
226
+ } else if (Types.isLeftRoundedCorner(cornerElem)) {
227
+ this.steps_ += svgPaths.moveTo(row.xPos, row.baseline);
228
+ this.steps_ += this.outsideCornerPaths_.bottomLeft();
229
+ }
205
230
  }
206
- this.steps_ += this.puzzleTabPaths_.pathUp(this.RTL_);
207
231
  }
208
232
 
209
- if (!this.RTL_) {
210
- const topRow = this.info_.topRow;
211
- if (Types.isLeftRoundedCorner(topRow.elements[0])) {
212
- this.steps_ += svgPaths.lineOnAxis('V', this.outsideCornerPaths_.height);
213
- } else {
214
- this.steps_ +=
215
- svgPaths.lineOnAxis('V', topRow.capline + this.highlightOffset_);
233
+ /**
234
+ * Draw the highlight on the left side of the block.
235
+ * @package
236
+ */
237
+ drawLeft() {
238
+ const outputConnection = this.info_.outputConnection;
239
+ if (outputConnection) {
240
+ const tabBottom =
241
+ outputConnection.connectionOffsetY + outputConnection.height;
242
+ // Draw a line up to the bottom of the tab.
243
+ if (this.RTL_) {
244
+ this.steps_ += svgPaths.moveTo(this.info_.startX, tabBottom);
245
+ } else {
246
+ const left = this.info_.startX + this.highlightOffset_;
247
+ const bottom = this.info_.bottomRow.baseline - this.highlightOffset_;
248
+ this.steps_ += svgPaths.moveTo(left, bottom);
249
+ this.steps_ += svgPaths.lineOnAxis('V', tabBottom);
250
+ }
251
+ this.steps_ += this.puzzleTabPaths_.pathUp(this.RTL_);
252
+ }
253
+
254
+ if (!this.RTL_) {
255
+ const topRow = this.info_.topRow;
256
+ if (Types.isLeftRoundedCorner(topRow.elements[0])) {
257
+ this.steps_ +=
258
+ svgPaths.lineOnAxis('V', this.outsideCornerPaths_.height);
259
+ } else {
260
+ this.steps_ +=
261
+ svgPaths.lineOnAxis('V', topRow.capline + this.highlightOffset_);
262
+ }
216
263
  }
217
264
  }
218
- };
219
265
 
220
- Highlighter.prototype.drawInlineInput = function(input) {
221
- const offset = this.highlightOffset_;
266
+ /**
267
+ * Add a highlight to an inline input.
268
+ * @param {!InlineInput} input The input to highlight.
269
+ * @package
270
+ */
271
+ drawInlineInput(input) {
272
+ const offset = this.highlightOffset_;
222
273
 
223
- // Relative to the block's left.
224
- const connectionRight = input.xPos + input.connectionWidth;
225
- const yPos = input.centerline - input.height / 2;
226
- const bottomHighlightWidth = input.width - input.connectionWidth;
227
- const startY = yPos + offset;
274
+ // Relative to the block's left.
275
+ const connectionRight = input.xPos + input.connectionWidth;
276
+ const yPos = input.centerline - input.height / 2;
277
+ const bottomHighlightWidth = input.width - input.connectionWidth;
278
+ const startY = yPos + offset;
228
279
 
229
- if (this.RTL_) {
230
- const aboveTabHeight = input.connectionOffsetY - offset;
231
- const belowTabHeight = input.height -
232
- (input.connectionOffsetY + input.connectionHeight) + offset;
280
+ if (this.RTL_) {
281
+ const aboveTabHeight = input.connectionOffsetY - offset;
282
+ const belowTabHeight = input.height -
283
+ (input.connectionOffsetY + input.connectionHeight) + offset;
233
284
 
234
- const startX = connectionRight - offset;
285
+ const startX = connectionRight - offset;
235
286
 
236
- this.inlineSteps_ += svgPaths.moveTo(startX, startY) +
237
- // Right edge above tab.
238
- svgPaths.lineOnAxis('v', aboveTabHeight) +
239
- // Back of tab.
240
- this.puzzleTabPaths_.pathDown(this.RTL_) +
241
- // Right edge below tab.
242
- svgPaths.lineOnAxis('v', belowTabHeight) +
243
- // Bottom.
244
- svgPaths.lineOnAxis('h', bottomHighlightWidth);
245
- } else {
246
- this.inlineSteps_ +=
247
- // Go to top right corner.
248
- svgPaths.moveTo(input.xPos + input.width + offset, startY) +
249
- // Highlight right edge, bottom.
250
- svgPaths.lineOnAxis('v', input.height) +
251
- svgPaths.lineOnAxis('h', -bottomHighlightWidth) +
252
- // Go to top of tab.
253
- svgPaths.moveTo(connectionRight, yPos + input.connectionOffsetY) +
254
- // Short highlight glint at bottom of tab.
255
- this.puzzleTabPaths_.pathDown(this.RTL_);
287
+ this.inlineSteps_ += svgPaths.moveTo(startX, startY) +
288
+ // Right edge above tab.
289
+ svgPaths.lineOnAxis('v', aboveTabHeight) +
290
+ // Back of tab.
291
+ this.puzzleTabPaths_.pathDown(this.RTL_) +
292
+ // Right edge below tab.
293
+ svgPaths.lineOnAxis('v', belowTabHeight) +
294
+ // Bottom.
295
+ svgPaths.lineOnAxis('h', bottomHighlightWidth);
296
+ } else {
297
+ this.inlineSteps_ +=
298
+ // Go to top right corner.
299
+ svgPaths.moveTo(input.xPos + input.width + offset, startY) +
300
+ // Highlight right edge, bottom.
301
+ svgPaths.lineOnAxis('v', input.height) +
302
+ svgPaths.lineOnAxis('h', -bottomHighlightWidth) +
303
+ // Go to top of tab.
304
+ svgPaths.moveTo(connectionRight, yPos + input.connectionOffsetY) +
305
+ // Short highlight glint at bottom of tab.
306
+ this.puzzleTabPaths_.pathDown(this.RTL_);
307
+ }
256
308
  }
257
- };
309
+ }
258
310
 
259
311
  exports.Highlighter = Highlighter;