blockly 7.20211209.2 → 8.0.0

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 (262) hide show
  1. package/blockly.d.ts +18963 -18432
  2. package/blockly.min.js +852 -844
  3. package/blockly_compressed.js +669 -664
  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 +41 -27
  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 +146 -141
  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 +19 -9
  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/dart_compressed.js +40 -43
  208. package/dart_compressed.js.map +1 -1
  209. package/generators/dart/colour.js +56 -64
  210. package/generators/dart/lists.js +61 -50
  211. package/generators/dart/math.js +160 -148
  212. package/generators/dart/text.js +83 -61
  213. package/generators/javascript/colour.js +37 -34
  214. package/generators/javascript/lists.js +50 -43
  215. package/generators/javascript/math.js +123 -139
  216. package/generators/javascript/text.js +67 -81
  217. package/generators/lua/colour.js +25 -23
  218. package/generators/lua/lists.js +97 -69
  219. package/generators/lua/logic.js +1 -2
  220. package/generators/lua/math.js +182 -144
  221. package/generators/lua/text.js +116 -99
  222. package/generators/php/colour.js +38 -32
  223. package/generators/php/lists.js +109 -89
  224. package/generators/php/math.js +90 -81
  225. package/generators/php/text.js +63 -61
  226. package/generators/python/colour.js +18 -18
  227. package/generators/python/lists.js +38 -30
  228. package/generators/python/loops.js +12 -8
  229. package/generators/python/math.js +104 -106
  230. package/generators/python/text.js +34 -30
  231. package/javascript_compressed.js +37 -39
  232. package/javascript_compressed.js.map +1 -1
  233. package/lua_compressed.js +39 -42
  234. package/lua_compressed.js.map +1 -1
  235. package/msg/az.js +2 -2
  236. package/msg/be.js +4 -4
  237. package/msg/cs.js +15 -15
  238. package/msg/de.js +1 -1
  239. package/msg/diq.js +1 -1
  240. package/msg/eo.js +1 -1
  241. package/msg/es.js +1 -1
  242. package/msg/fa.js +1 -1
  243. package/msg/fr.js +4 -4
  244. package/msg/he.js +1 -1
  245. package/msg/hr.js +2 -2
  246. package/msg/hy.js +2 -2
  247. package/msg/id.js +12 -12
  248. package/msg/inh.js +14 -14
  249. package/msg/ja.js +7 -7
  250. package/msg/lv.js +29 -29
  251. package/msg/pa.js +3 -3
  252. package/msg/smn.js +436 -0
  253. package/msg/te.js +1 -1
  254. package/msg/yue.js +1 -1
  255. package/msg/zh-hans.js +3 -3
  256. package/msg/zh-hant.js +3 -3
  257. package/package.json +7 -6
  258. package/php_compressed.js +38 -42
  259. package/php_compressed.js.map +1 -1
  260. package/python_compressed.js +26 -25
  261. package/python_compressed.js.map +1 -1
  262. package/blocks/all.js +0 -23
@@ -18,7 +18,6 @@
18
18
  goog.module('Blockly.zelos.ConstantProvider');
19
19
 
20
20
  const dom = goog.require('Blockly.utils.dom');
21
- const object = goog.require('Blockly.utils.object');
22
21
  const svgPaths = goog.require('Blockly.utils.svgPaths');
23
22
  const utilsColour = goog.require('Blockly.utils.colour');
24
23
  const {ConnectionType} = goog.require('Blockly.ConnectionType');
@@ -28,953 +27,979 @@ const {Svg} = goog.require('Blockly.utils.Svg');
28
27
 
29
28
  /**
30
29
  * An object that provides constants for rendering blocks in Zelos mode.
31
- * @constructor
32
- * @package
33
30
  * @extends {BaseConstantProvider}
34
31
  * @alias Blockly.zelos.ConstantProvider
35
32
  */
36
- const ConstantProvider = function() {
37
- ConstantProvider.superClass_.constructor.call(this);
38
-
39
- this.GRID_UNIT = 4;
40
-
41
- /**
42
- * @override
43
- */
44
- this.SMALL_PADDING = this.GRID_UNIT;
45
-
46
- /**
47
- * @override
48
- */
49
- this.MEDIUM_PADDING = 2 * this.GRID_UNIT;
50
-
51
- /**
52
- * @override
53
- */
54
- this.MEDIUM_LARGE_PADDING = 3 * this.GRID_UNIT;
55
-
56
- /**
57
- * @override
58
- */
59
- this.LARGE_PADDING = 4 * this.GRID_UNIT;
60
-
61
- /**
62
- * @override
63
- */
64
- this.CORNER_RADIUS = 1 * this.GRID_UNIT;
65
-
66
- /**
67
- * @override
68
- */
69
- this.NOTCH_WIDTH = 9 * this.GRID_UNIT;
70
-
71
- /**
72
- * @override
73
- */
74
- this.NOTCH_HEIGHT = 2 * this.GRID_UNIT;
75
-
76
- /**
77
- * @override
78
- */
79
- this.NOTCH_OFFSET_LEFT = 3 * this.GRID_UNIT;
80
-
81
- /**
82
- * @override
83
- */
84
- this.STATEMENT_INPUT_NOTCH_OFFSET = this.NOTCH_OFFSET_LEFT;
85
-
33
+ class ConstantProvider extends BaseConstantProvider {
86
34
  /**
87
- * @override
88
- */
89
- this.MIN_BLOCK_WIDTH = 2 * this.GRID_UNIT;
90
-
91
- /**
92
- * @override
93
- */
94
- this.MIN_BLOCK_HEIGHT = 12 * this.GRID_UNIT;
95
-
96
- /**
97
- * @override
98
- */
99
- this.EMPTY_STATEMENT_INPUT_HEIGHT = 6 * this.GRID_UNIT;
100
-
101
- /**
102
- * @override
103
- */
104
- this.TAB_OFFSET_FROM_TOP = 0;
105
-
106
- /**
107
- * @override
108
- */
109
- this.TOP_ROW_MIN_HEIGHT = this.CORNER_RADIUS;
110
-
111
- /**
112
- * @override
113
- */
114
- this.TOP_ROW_PRECEDES_STATEMENT_MIN_HEIGHT = this.LARGE_PADDING;
115
-
116
- /**
117
- * @override
118
- */
119
- this.BOTTOM_ROW_MIN_HEIGHT = this.CORNER_RADIUS;
120
-
121
- /**
122
- * @override
35
+ * @package
123
36
  */
124
- this.BOTTOM_ROW_AFTER_STATEMENT_MIN_HEIGHT = 6 * this.GRID_UNIT;
37
+ constructor() {
38
+ super();
39
+
40
+ this.GRID_UNIT = 4;
41
+
42
+ /**
43
+ * @override
44
+ */
45
+ this.SMALL_PADDING = this.GRID_UNIT;
46
+
47
+ /**
48
+ * @override
49
+ */
50
+ this.MEDIUM_PADDING = 2 * this.GRID_UNIT;
51
+
52
+ /**
53
+ * @override
54
+ */
55
+ this.MEDIUM_LARGE_PADDING = 3 * this.GRID_UNIT;
56
+
57
+ /**
58
+ * @override
59
+ */
60
+ this.LARGE_PADDING = 4 * this.GRID_UNIT;
61
+
62
+ /**
63
+ * @override
64
+ */
65
+ this.CORNER_RADIUS = 1 * this.GRID_UNIT;
66
+
67
+ /**
68
+ * @override
69
+ */
70
+ this.NOTCH_WIDTH = 9 * this.GRID_UNIT;
71
+
72
+ /**
73
+ * @override
74
+ */
75
+ this.NOTCH_HEIGHT = 2 * this.GRID_UNIT;
76
+
77
+ /**
78
+ * @override
79
+ */
80
+ this.NOTCH_OFFSET_LEFT = 3 * this.GRID_UNIT;
81
+
82
+ /**
83
+ * @override
84
+ */
85
+ this.STATEMENT_INPUT_NOTCH_OFFSET = this.NOTCH_OFFSET_LEFT;
86
+
87
+ /**
88
+ * @override
89
+ */
90
+ this.MIN_BLOCK_WIDTH = 2 * this.GRID_UNIT;
91
+
92
+ /**
93
+ * @override
94
+ */
95
+ this.MIN_BLOCK_HEIGHT = 12 * this.GRID_UNIT;
96
+
97
+ /**
98
+ * @override
99
+ */
100
+ this.EMPTY_STATEMENT_INPUT_HEIGHT = 6 * this.GRID_UNIT;
101
+
102
+ /**
103
+ * @override
104
+ */
105
+ this.TAB_OFFSET_FROM_TOP = 0;
106
+
107
+ /**
108
+ * @override
109
+ */
110
+ this.TOP_ROW_MIN_HEIGHT = this.CORNER_RADIUS;
111
+
112
+ /**
113
+ * @override
114
+ */
115
+ this.TOP_ROW_PRECEDES_STATEMENT_MIN_HEIGHT = this.LARGE_PADDING;
116
+
117
+ /**
118
+ * @override
119
+ */
120
+ this.BOTTOM_ROW_MIN_HEIGHT = this.CORNER_RADIUS;
121
+
122
+ /**
123
+ * @override
124
+ */
125
+ this.BOTTOM_ROW_AFTER_STATEMENT_MIN_HEIGHT = 6 * this.GRID_UNIT;
126
+
127
+ /**
128
+ * @override
129
+ */
130
+ this.STATEMENT_BOTTOM_SPACER = -this.NOTCH_HEIGHT;
131
+
132
+ /**
133
+ * Minimum statement input spacer width.
134
+ * @type {number}
135
+ */
136
+ this.STATEMENT_INPUT_SPACER_MIN_WIDTH = 40 * this.GRID_UNIT;
137
+
138
+ /**
139
+ * @override
140
+ */
141
+ this.STATEMENT_INPUT_PADDING_LEFT = 4 * this.GRID_UNIT;
142
+
143
+ /**
144
+ * @override
145
+ */
146
+ this.EMPTY_INLINE_INPUT_PADDING = 4 * this.GRID_UNIT;
147
+
148
+ /**
149
+ * @override
150
+ */
151
+ this.EMPTY_INLINE_INPUT_HEIGHT = 8 * this.GRID_UNIT;
152
+
153
+ /**
154
+ * @override
155
+ */
156
+ this.DUMMY_INPUT_MIN_HEIGHT = 8 * this.GRID_UNIT;
157
+
158
+ /**
159
+ * @override
160
+ */
161
+ this.DUMMY_INPUT_SHADOW_MIN_HEIGHT = 6 * this.GRID_UNIT;
162
+
163
+ /**
164
+ * @override
165
+ */
166
+ this.CURSOR_WS_WIDTH = 20 * this.GRID_UNIT;
167
+
168
+ /**
169
+ * @override
170
+ */
171
+ this.CURSOR_COLOUR = '#ffa200';
172
+
173
+ /**
174
+ * Radius of the cursor for input and output connections.
175
+ * @type {number}
176
+ * @package
177
+ */
178
+ this.CURSOR_RADIUS = 5;
179
+
180
+ /**
181
+ * @override
182
+ */
183
+ this.JAGGED_TEETH_HEIGHT = 0;
184
+
185
+ /**
186
+ * @override
187
+ */
188
+ this.JAGGED_TEETH_WIDTH = 0;
189
+
190
+ /**
191
+ * @override
192
+ */
193
+ this.START_HAT_HEIGHT = 22;
194
+
195
+ /**
196
+ * @override
197
+ */
198
+ this.START_HAT_WIDTH = 96;
199
+
200
+ /**
201
+ * @enum {number}
202
+ * @override
203
+ */
204
+ this.SHAPES = {HEXAGONAL: 1, ROUND: 2, SQUARE: 3, PUZZLE: 4, NOTCH: 5};
205
+
206
+ /**
207
+ * Map of output/input shapes and the amount they should cause a block to be
208
+ * padded. Outer key is the outer shape, inner key is the inner shape.
209
+ * When a block with the outer shape contains an input block with the inner
210
+ * shape on its left or right edge, the block elements are aligned such that
211
+ * the padding specified is reached.
212
+ * @package
213
+ */
214
+ this.SHAPE_IN_SHAPE_PADDING = {
215
+ 1: {
216
+ // Outer shape: hexagon.
217
+ 0: 5 * this.GRID_UNIT, // Field in hexagon.
218
+ 1: 2 * this.GRID_UNIT, // Hexagon in hexagon.
219
+ 2: 5 * this.GRID_UNIT, // Round in hexagon.
220
+ 3: 5 * this.GRID_UNIT, // Square in hexagon.
221
+ },
222
+ 2: {
223
+ // Outer shape: round.
224
+ 0: 3 * this.GRID_UNIT, // Field in round.
225
+ 1: 3 * this.GRID_UNIT, // Hexagon in round.
226
+ 2: 1 * this.GRID_UNIT, // Round in round.
227
+ 3: 2 * this.GRID_UNIT, // Square in round.
228
+ },
229
+ 3: {
230
+ // Outer shape: square.
231
+ 0: 2 * this.GRID_UNIT, // Field in square.
232
+ 1: 2 * this.GRID_UNIT, // Hexagon in square.
233
+ 2: 2 * this.GRID_UNIT, // Round in square.
234
+ 3: 2 * this.GRID_UNIT, // Square in square.
235
+ },
236
+ };
237
+
238
+ /**
239
+ * @override
240
+ */
241
+ this.FULL_BLOCK_FIELDS = true;
242
+
243
+ /**
244
+ * @override
245
+ */
246
+ this.FIELD_TEXT_FONTSIZE = 3 * this.GRID_UNIT;
247
+
248
+ /**
249
+ * @override
250
+ */
251
+ this.FIELD_TEXT_FONTWEIGHT = 'bold';
252
+
253
+ /**
254
+ * @override
255
+ */
256
+ this.FIELD_TEXT_FONTFAMILY =
257
+ '"Helvetica Neue", "Segoe UI", Helvetica, sans-serif';
258
+
259
+ /**
260
+ * @override
261
+ */
262
+ this.FIELD_BORDER_RECT_RADIUS = this.CORNER_RADIUS;
263
+
264
+ /**
265
+ * @override
266
+ */
267
+ this.FIELD_BORDER_RECT_X_PADDING = 2 * this.GRID_UNIT;
268
+
269
+ /**
270
+ * @override
271
+ */
272
+ this.FIELD_BORDER_RECT_Y_PADDING = 1.625 * this.GRID_UNIT;
273
+
274
+ /**
275
+ * @override
276
+ */
277
+ this.FIELD_BORDER_RECT_HEIGHT = 8 * this.GRID_UNIT;
278
+
279
+ /**
280
+ * @override
281
+ */
282
+ this.FIELD_DROPDOWN_BORDER_RECT_HEIGHT = 8 * this.GRID_UNIT;
283
+
284
+ /**
285
+ * @override
286
+ */
287
+ this.FIELD_DROPDOWN_NO_BORDER_RECT_SHADOW = true;
288
+
289
+ /**
290
+ * @override
291
+ */
292
+ this.FIELD_DROPDOWN_COLOURED_DIV = true;
293
+
294
+ /**
295
+ * @override
296
+ */
297
+ this.FIELD_DROPDOWN_SVG_ARROW = true;
298
+
299
+ /**
300
+ * @override
301
+ */
302
+ this.FIELD_DROPDOWN_SVG_ARROW_PADDING = this.FIELD_BORDER_RECT_X_PADDING;
303
+
304
+ /**
305
+ * @override
306
+ */
307
+ this.FIELD_TEXTINPUT_BOX_SHADOW = true;
308
+
309
+ /**
310
+ * @override
311
+ */
312
+ this.FIELD_COLOUR_FULL_BLOCK = true;
313
+
314
+ /**
315
+ * @override
316
+ */
317
+ this.FIELD_COLOUR_DEFAULT_WIDTH = 2 * this.GRID_UNIT;
318
+
319
+ /**
320
+ * @override
321
+ */
322
+ this.FIELD_COLOUR_DEFAULT_HEIGHT = 4 * this.GRID_UNIT;
323
+
324
+ /**
325
+ * @override
326
+ */
327
+ this.FIELD_CHECKBOX_X_OFFSET = 1 * this.GRID_UNIT;
328
+
329
+ /**
330
+ * The maximum width of a dynamic connection shape.
331
+ * @type {number}
332
+ */
333
+ this.MAX_DYNAMIC_CONNECTION_SHAPE_WIDTH = 12 * this.GRID_UNIT;
334
+
335
+ /**
336
+ * The selected glow colour.
337
+ * @type {string}
338
+ */
339
+ this.SELECTED_GLOW_COLOUR = '#fff200';
340
+
341
+ /**
342
+ * The size of the selected glow.
343
+ * @type {number}
344
+ */
345
+ this.SELECTED_GLOW_SIZE = 0.5;
346
+
347
+ /**
348
+ * The replacement glow colour.
349
+ * @type {string}
350
+ */
351
+ this.REPLACEMENT_GLOW_COLOUR = '#fff200';
352
+
353
+ /**
354
+ * The size of the selected glow.
355
+ * @type {number}
356
+ */
357
+ this.REPLACEMENT_GLOW_SIZE = 2;
358
+
359
+ /**
360
+ * The ID of the selected glow filter, or the empty string if no filter is
361
+ * set.
362
+ * @type {string}
363
+ * @package
364
+ */
365
+ this.selectedGlowFilterId = '';
366
+
367
+ /**
368
+ * The <filter> element to use for a selected glow, or null if not set.
369
+ * @type {SVGElement}
370
+ * @private
371
+ */
372
+ this.selectedGlowFilter_ = null;
373
+
374
+ /**
375
+ * The ID of the replacement glow filter, or the empty string if no filter
376
+ * is set.
377
+ * @type {string}
378
+ * @package
379
+ */
380
+ this.replacementGlowFilterId = '';
381
+
382
+ /**
383
+ * The <filter> element to use for a replacement glow, or null if not set.
384
+ * @type {SVGElement}
385
+ * @private
386
+ */
387
+ this.replacementGlowFilter_ = null;
388
+
389
+ /**
390
+ * The object containing information about the hexagon used for a boolean
391
+ * reporter block. Null before init is called.
392
+ * @type {Object}
393
+ */
394
+ this.HEXAGONAL = null;
395
+
396
+ /**
397
+ * The object containing information about the hexagon used for a number or
398
+ * string reporter block. Null before init is called.
399
+ * @type {Object}
400
+ */
401
+ this.ROUNDED = null;
402
+
403
+ /**
404
+ * The object containing information about the hexagon used for a
405
+ * rectangular reporter block. Null before init is called.
406
+ * @type {Object}
407
+ */
408
+ this.SQUARED = null;
409
+ }
125
410
 
126
411
  /**
127
412
  * @override
128
413
  */
129
- this.STATEMENT_BOTTOM_SPACER = -this.NOTCH_HEIGHT;
414
+ setFontConstants_(theme) {
415
+ super.setFontConstants_(theme);
130
416
 
131
- /**
132
- * Minimum statement input spacer width.
133
- * @type {number}
134
- */
135
- this.STATEMENT_INPUT_SPACER_MIN_WIDTH = 40 * this.GRID_UNIT;
417
+ this.FIELD_BORDER_RECT_HEIGHT =
418
+ this.FIELD_TEXT_HEIGHT + this.FIELD_BORDER_RECT_Y_PADDING * 2;
419
+ this.FIELD_DROPDOWN_BORDER_RECT_HEIGHT = this.FIELD_BORDER_RECT_HEIGHT;
420
+ }
136
421
 
137
422
  /**
138
423
  * @override
139
424
  */
140
- this.STATEMENT_INPUT_PADDING_LEFT = 4 * this.GRID_UNIT;
425
+ init() {
426
+ super.init();
427
+ this.HEXAGONAL = this.makeHexagonal();
428
+ this.ROUNDED = this.makeRounded();
429
+ this.SQUARED = this.makeSquared();
141
430
 
142
- /**
143
- * @override
144
- */
145
- this.EMPTY_INLINE_INPUT_PADDING = 4 * this.GRID_UNIT;
431
+ this.STATEMENT_INPUT_NOTCH_OFFSET =
432
+ this.NOTCH_OFFSET_LEFT + this.INSIDE_CORNERS.rightWidth;
433
+ }
146
434
 
147
435
  /**
148
436
  * @override
149
437
  */
150
- this.EMPTY_INLINE_INPUT_HEIGHT = 8 * this.GRID_UNIT;
438
+ setDynamicProperties_(theme) {
439
+ super.setDynamicProperties_(theme);
151
440
 
152
- /**
153
- * @override
154
- */
155
- this.DUMMY_INPUT_MIN_HEIGHT = 8 * this.GRID_UNIT;
441
+ this.SELECTED_GLOW_COLOUR = theme.getComponentStyle('selectedGlowColour') ||
442
+ this.SELECTED_GLOW_COLOUR;
443
+ const selectedGlowSize =
444
+ Number(theme.getComponentStyle('selectedGlowSize'));
445
+ this.SELECTED_GLOW_SIZE = selectedGlowSize && !isNaN(selectedGlowSize) ?
446
+ selectedGlowSize :
447
+ this.SELECTED_GLOW_SIZE;
448
+ this.REPLACEMENT_GLOW_COLOUR =
449
+ theme.getComponentStyle('replacementGlowColour') ||
450
+ this.REPLACEMENT_GLOW_COLOUR;
451
+ const replacementGlowSize =
452
+ Number(theme.getComponentStyle('replacementGlowSize'));
453
+ this.REPLACEMENT_GLOW_SIZE =
454
+ replacementGlowSize && !isNaN(replacementGlowSize) ?
455
+ replacementGlowSize :
456
+ this.REPLACEMENT_GLOW_SIZE;
457
+ }
156
458
 
157
459
  /**
158
460
  * @override
159
461
  */
160
- this.DUMMY_INPUT_SHADOW_MIN_HEIGHT = 6 * this.GRID_UNIT;
462
+ dispose() {
463
+ super.dispose();
464
+ if (this.selectedGlowFilter_) {
465
+ dom.removeNode(this.selectedGlowFilter_);
466
+ }
467
+ if (this.replacementGlowFilter_) {
468
+ dom.removeNode(this.replacementGlowFilter_);
469
+ }
470
+ }
161
471
 
162
472
  /**
163
473
  * @override
164
474
  */
165
- this.CURSOR_WS_WIDTH = 20 * this.GRID_UNIT;
475
+ makeStartHat() {
476
+ const height = this.START_HAT_HEIGHT;
477
+ const width = this.START_HAT_WIDTH;
166
478
 
167
- /**
168
- * @override
169
- */
170
- this.CURSOR_COLOUR = '#ffa200';
479
+ const mainPath = svgPaths.curve('c', [
480
+ svgPaths.point(25, -height),
481
+ svgPaths.point(71, -height),
482
+ svgPaths.point(width, 0),
483
+ ]);
484
+ return {height: height, width: width, path: mainPath};
485
+ }
171
486
 
172
487
  /**
173
- * Radius of the cursor for input and output connections.
174
- * @type {number}
488
+ * Create sizing and path information about a hexagonal shape.
489
+ * @return {!Object} An object containing sizing and path information about
490
+ * a hexagonal shape for connections.
175
491
  * @package
176
492
  */
177
- this.CURSOR_RADIUS = 5;
178
-
179
- /**
180
- * @override
181
- */
182
- this.JAGGED_TEETH_HEIGHT = 0;
183
-
184
- /**
185
- * @override
186
- */
187
- this.JAGGED_TEETH_WIDTH = 0;
188
-
189
- /**
190
- * @override
191
- */
192
- this.START_HAT_HEIGHT = 22;
193
-
194
- /**
195
- * @override
196
- */
197
- this.START_HAT_WIDTH = 96;
198
-
199
- /**
200
- * @enum {number}
201
- * @override
202
- */
203
- this.SHAPES = {HEXAGONAL: 1, ROUND: 2, SQUARE: 3, PUZZLE: 4, NOTCH: 5};
493
+ makeHexagonal() {
494
+ const maxWidth = this.MAX_DYNAMIC_CONNECTION_SHAPE_WIDTH;
495
+
496
+ /**
497
+ * Make the main path for the hexagonal connection shape out of two lines.
498
+ * The lines are defined with relative positions and require the block
499
+ * height. The 'up' and 'down' versions of the paths are the same, but the Y
500
+ * sign flips. The 'left' and 'right' versions of the path are also the
501
+ * same, but the X sign flips.
502
+ * @param {number} height The height of the block the connection is on.
503
+ * @param {boolean} up True if the path should be drawn from bottom to top,
504
+ * false otherwise.
505
+ * @param {boolean} right True if the path is for the right side of the
506
+ * block.
507
+ * @return {string} A path fragment describing a rounded connection.
508
+ */
509
+ function makeMainPath(height, up, right) {
510
+ const halfHeight = height / 2;
511
+ const width = halfHeight > maxWidth ? maxWidth : halfHeight;
512
+ const forward = up ? -1 : 1;
513
+ const direction = right ? -1 : 1;
514
+ const dy = forward * height / 2;
515
+ return svgPaths.lineTo(-direction * width, dy) +
516
+ svgPaths.lineTo(direction * width, dy);
517
+ }
518
+
519
+ return {
520
+ type: this.SHAPES.HEXAGONAL,
521
+ isDynamic: true,
522
+ width: function(height) {
523
+ const halfHeight = height / 2;
524
+ return halfHeight > maxWidth ? maxWidth : halfHeight;
525
+ },
526
+ height: function(height) {
527
+ return height;
528
+ },
529
+ connectionOffsetY: function(connectionHeight) {
530
+ return connectionHeight / 2;
531
+ },
532
+ connectionOffsetX: function(connectionWidth) {
533
+ return -connectionWidth;
534
+ },
535
+ pathDown: function(height) {
536
+ return makeMainPath(height, false, false);
537
+ },
538
+ pathUp: function(height) {
539
+ return makeMainPath(height, true, false);
540
+ },
541
+ pathRightDown: function(height) {
542
+ return makeMainPath(height, false, true);
543
+ },
544
+ pathRightUp: function(height) {
545
+ return makeMainPath(height, false, true);
546
+ },
547
+ };
548
+ }
204
549
 
205
550
  /**
206
- * Map of output/input shapes and the amount they should cause a block to be
207
- * padded. Outer key is the outer shape, inner key is the inner shape.
208
- * When a block with the outer shape contains an input block with the inner
209
- * shape on its left or right edge, the block elements are aligned such that
210
- * the padding specified is reached.
551
+ * Create sizing and path information about a rounded shape.
552
+ * @return {!Object} An object containing sizing and path information about
553
+ * a rounded shape for connections.
211
554
  * @package
212
555
  */
213
- this.SHAPE_IN_SHAPE_PADDING = {
214
- 1: {
215
- // Outer shape: hexagon.
216
- 0: 5 * this.GRID_UNIT, // Field in hexagon.
217
- 1: 2 * this.GRID_UNIT, // Hexagon in hexagon.
218
- 2: 5 * this.GRID_UNIT, // Round in hexagon.
219
- 3: 5 * this.GRID_UNIT, // Square in hexagon.
220
- },
221
- 2: {
222
- // Outer shape: round.
223
- 0: 3 * this.GRID_UNIT, // Field in round.
224
- 1: 3 * this.GRID_UNIT, // Hexagon in round.
225
- 2: 1 * this.GRID_UNIT, // Round in round.
226
- 3: 2 * this.GRID_UNIT, // Square in round.
227
- },
228
- 3: {
229
- // Outer shape: square.
230
- 0: 2 * this.GRID_UNIT, // Field in square.
231
- 1: 2 * this.GRID_UNIT, // Hexagon in square.
232
- 2: 2 * this.GRID_UNIT, // Round in square.
233
- 3: 2 * this.GRID_UNIT, // Square in square.
234
- },
235
- };
236
-
237
- /**
238
- * @override
239
- */
240
- this.FULL_BLOCK_FIELDS = true;
241
-
242
- /**
243
- * @override
244
- */
245
- this.FIELD_TEXT_FONTSIZE = 3 * this.GRID_UNIT;
246
-
247
- /**
248
- * @override
249
- */
250
- this.FIELD_TEXT_FONTWEIGHT = 'bold';
251
-
252
- /**
253
- * @override
254
- */
255
- this.FIELD_TEXT_FONTFAMILY =
256
- '"Helvetica Neue", "Segoe UI", Helvetica, sans-serif';
257
-
258
- /**
259
- * @override
260
- */
261
- this.FIELD_BORDER_RECT_RADIUS = this.CORNER_RADIUS;
262
-
263
- /**
264
- * @override
265
- */
266
- this.FIELD_BORDER_RECT_X_PADDING = 2 * this.GRID_UNIT;
267
-
268
- /**
269
- * @override
270
- */
271
- this.FIELD_BORDER_RECT_Y_PADDING = 1.625 * this.GRID_UNIT;
272
-
273
- /**
274
- * @override
275
- */
276
- this.FIELD_BORDER_RECT_HEIGHT = 8 * this.GRID_UNIT;
277
-
278
- /**
279
- * @override
280
- */
281
- this.FIELD_DROPDOWN_BORDER_RECT_HEIGHT = 8 * this.GRID_UNIT;
282
-
283
- /**
284
- * @override
285
- */
286
- this.FIELD_DROPDOWN_NO_BORDER_RECT_SHADOW = true;
287
-
288
- /**
289
- * @override
290
- */
291
- this.FIELD_DROPDOWN_COLOURED_DIV = true;
292
-
293
- /**
294
- * @override
295
- */
296
- this.FIELD_DROPDOWN_SVG_ARROW = true;
556
+ makeRounded() {
557
+ const maxWidth = this.MAX_DYNAMIC_CONNECTION_SHAPE_WIDTH;
558
+ const maxHeight = maxWidth * 2;
559
+
560
+ /**
561
+ * Make the main path for the rounded connection shape out of two arcs and
562
+ * a line that joins them. The arcs are defined with relative positions.
563
+ * Usually, the height of the block is split between the two arcs. In the
564
+ * case where the height of the block exceeds the maximum height, a line is
565
+ * drawn in between the two arcs. The 'up' and 'down' versions of the paths
566
+ * are the same, but the Y sign flips. The 'up' and 'right' versions of the
567
+ * path flip the sweep-flag which moves the arc at negative angles.
568
+ * @param {number} blockHeight The height of the block the connection is on.
569
+ * @param {boolean} up True if the path should be drawn from bottom to top,
570
+ * false otherwise.
571
+ * @param {boolean} right True if the path is for the right side of the
572
+ * block.
573
+ * @return {string} A path fragment describing a rounded connection.
574
+ */
575
+ function makeMainPath(blockHeight, up, right) {
576
+ const remainingHeight =
577
+ blockHeight > maxHeight ? blockHeight - maxHeight : 0;
578
+ const height = blockHeight > maxHeight ? maxHeight : blockHeight;
579
+ const radius = height / 2;
580
+ return svgPaths.arc(
581
+ 'a', '0 0,1', radius,
582
+ svgPaths.point(
583
+ (up ? -1 : 1) * radius, (up ? -1 : 1) * radius)) +
584
+ svgPaths.lineOnAxis('v', (right ? 1 : -1) * remainingHeight) +
585
+ svgPaths.arc(
586
+ 'a', '0 0,1', radius,
587
+ svgPaths.point((up ? 1 : -1) * radius, (up ? -1 : 1) * radius));
588
+ }
589
+
590
+ return {
591
+ type: this.SHAPES.ROUND,
592
+ isDynamic: true,
593
+ width: function(height) {
594
+ const halfHeight = height / 2;
595
+ return halfHeight > maxWidth ? maxWidth : halfHeight;
596
+ },
597
+ height: function(height) {
598
+ return height;
599
+ },
600
+ connectionOffsetY: function(connectionHeight) {
601
+ return connectionHeight / 2;
602
+ },
603
+ connectionOffsetX: function(connectionWidth) {
604
+ return -connectionWidth;
605
+ },
606
+ pathDown: function(height) {
607
+ return makeMainPath(height, false, false);
608
+ },
609
+ pathUp: function(height) {
610
+ return makeMainPath(height, true, false);
611
+ },
612
+ pathRightDown: function(height) {
613
+ return makeMainPath(height, false, true);
614
+ },
615
+ pathRightUp: function(height) {
616
+ return makeMainPath(height, false, true);
617
+ },
618
+ };
619
+ }
297
620
 
298
621
  /**
299
- * @override
622
+ * Create sizing and path information about a squared shape.
623
+ * @return {!Object} An object containing sizing and path information about
624
+ * a squared shape for connections.
625
+ * @package
300
626
  */
301
- this.FIELD_DROPDOWN_SVG_ARROW_PADDING = this.FIELD_BORDER_RECT_X_PADDING;
627
+ makeSquared() {
628
+ const radius = this.CORNER_RADIUS;
629
+
630
+ /**
631
+ * Make the main path for the squared connection shape out of two corners
632
+ * and a single line in-between (a and v). These are defined in relative
633
+ * positions and require the height of the block.
634
+ * The 'left' and 'right' versions of the paths are the same, but the Y sign
635
+ * flips. The 'up' and 'down' versions of the path determine where the
636
+ * corner point is placed and in turn the direction of the corners.
637
+ * @param {number} height The height of the block the connection is on.
638
+ * @param {boolean} up True if the path should be drawn from bottom to top,
639
+ * false otherwise.
640
+ * @param {boolean} right True if the path is for the right side of the
641
+ * block.
642
+ * @return {string} A path fragment describing a squared connection.
643
+ */
644
+ function makeMainPath(height, up, right) {
645
+ const innerHeight = height - radius * 2;
646
+ return svgPaths.arc(
647
+ 'a', '0 0,1', radius,
648
+ svgPaths.point(
649
+ (up ? -1 : 1) * radius, (up ? -1 : 1) * radius)) +
650
+ svgPaths.lineOnAxis('v', (right ? 1 : -1) * innerHeight) +
651
+ svgPaths.arc(
652
+ 'a', '0 0,1', radius,
653
+ svgPaths.point((up ? 1 : -1) * radius, (up ? -1 : 1) * radius));
654
+ }
655
+
656
+ return {
657
+ type: this.SHAPES.SQUARE,
658
+ isDynamic: true,
659
+ width: function(_height) {
660
+ return radius;
661
+ },
662
+ height: function(height) {
663
+ return height;
664
+ },
665
+ connectionOffsetY: function(connectionHeight) {
666
+ return connectionHeight / 2;
667
+ },
668
+ connectionOffsetX: function(connectionWidth) {
669
+ return -connectionWidth;
670
+ },
671
+ pathDown: function(height) {
672
+ return makeMainPath(height, false, false);
673
+ },
674
+ pathUp: function(height) {
675
+ return makeMainPath(height, true, false);
676
+ },
677
+ pathRightDown: function(height) {
678
+ return makeMainPath(height, false, true);
679
+ },
680
+ pathRightUp: function(height) {
681
+ return makeMainPath(height, false, true);
682
+ },
683
+ };
684
+ }
302
685
 
303
686
  /**
304
687
  * @override
305
688
  */
306
- this.FIELD_TEXTINPUT_BOX_SHADOW = true;
689
+ shapeFor(connection) {
690
+ let checks = connection.getCheck();
691
+ if (!checks && connection.targetConnection) {
692
+ checks = connection.targetConnection.getCheck();
693
+ }
694
+ let outputShape;
695
+ switch (connection.type) {
696
+ case ConnectionType.INPUT_VALUE:
697
+ case ConnectionType.OUTPUT_VALUE:
698
+ outputShape = connection.getSourceBlock().getOutputShape();
699
+ // If the block has an output shape set, use that instead.
700
+ if (outputShape !== null) {
701
+ switch (outputShape) {
702
+ case this.SHAPES.HEXAGONAL:
703
+ return /** @type {!Object} */ (this.HEXAGONAL);
704
+ case this.SHAPES.ROUND:
705
+ return /** @type {!Object} */ (this.ROUNDED);
706
+ case this.SHAPES.SQUARE:
707
+ return /** @type {!Object} */ (this.SQUARED);
708
+ }
709
+ }
710
+ // Includes doesn't work in IE.
711
+ if (checks && checks.indexOf('Boolean') !== -1) {
712
+ return /** @type {!Object} */ (this.HEXAGONAL);
713
+ }
714
+ if (checks && checks.indexOf('Number') !== -1) {
715
+ return /** @type {!Object} */ (this.ROUNDED);
716
+ }
717
+ if (checks && checks.indexOf('String') !== -1) {
718
+ return /** @type {!Object} */ (this.ROUNDED);
719
+ }
720
+ return /** @type {!Object} */ (this.ROUNDED);
721
+ case ConnectionType.PREVIOUS_STATEMENT:
722
+ case ConnectionType.NEXT_STATEMENT:
723
+ return this.NOTCH;
724
+ default:
725
+ throw Error('Unknown type');
726
+ }
727
+ }
307
728
 
308
729
  /**
309
730
  * @override
310
731
  */
311
- this.FIELD_COLOUR_FULL_BLOCK = true;
732
+ makeNotch() {
733
+ const width = this.NOTCH_WIDTH;
734
+ const height = this.NOTCH_HEIGHT;
312
735
 
313
- /**
314
- * @override
315
- */
316
- this.FIELD_COLOUR_DEFAULT_WIDTH = 2 * this.GRID_UNIT;
736
+ const innerWidth = width / 3;
737
+ const curveWidth = innerWidth / 3;
317
738
 
318
- /**
319
- * @override
320
- */
321
- this.FIELD_COLOUR_DEFAULT_HEIGHT = 4 * this.GRID_UNIT;
739
+ const halfHeight = height / 2;
740
+ const quarterHeight = halfHeight / 2;
741
+
742
+ /**
743
+ * Make the main path for the notch.
744
+ * @param {number} dir Direction multiplier to apply to horizontal offsets
745
+ * along the path. Either 1 or -1.
746
+ * @return {string} A path fragment describing a notch.
747
+ */
748
+ function makeMainPath(dir) {
749
+ return (
750
+ svgPaths.curve(
751
+ 'c',
752
+ [
753
+ svgPaths.point(dir * curveWidth / 2, 0),
754
+ svgPaths.point(dir * curveWidth * 3 / 4, quarterHeight / 2),
755
+ svgPaths.point(dir * curveWidth, quarterHeight),
756
+ ]) +
757
+ svgPaths.line([svgPaths.point(dir * curveWidth, halfHeight)]) +
758
+ svgPaths.curve(
759
+ 'c',
760
+ [
761
+ svgPaths.point(dir * curveWidth / 4, quarterHeight / 2),
762
+ svgPaths.point(dir * curveWidth / 2, quarterHeight),
763
+ svgPaths.point(dir * curveWidth, quarterHeight),
764
+ ]) +
765
+ svgPaths.lineOnAxis('h', dir * innerWidth) +
766
+ svgPaths.curve(
767
+ 'c',
768
+ [
769
+ svgPaths.point(dir * curveWidth / 2, 0),
770
+ svgPaths.point(dir * curveWidth * 3 / 4, -(quarterHeight / 2)),
771
+ svgPaths.point(dir * curveWidth, -quarterHeight),
772
+ ]) +
773
+ svgPaths.line([svgPaths.point(dir * curveWidth, -halfHeight)]) +
774
+ svgPaths.curve('c', [
775
+ svgPaths.point(dir * curveWidth / 4, -(quarterHeight / 2)),
776
+ svgPaths.point(dir * curveWidth / 2, -quarterHeight),
777
+ svgPaths.point(dir * curveWidth, -quarterHeight),
778
+ ]));
779
+ }
780
+
781
+ const pathLeft = makeMainPath(1);
782
+ const pathRight = makeMainPath(-1);
783
+
784
+ return {
785
+ type: this.SHAPES.NOTCH,
786
+ width: width,
787
+ height: height,
788
+ pathLeft: pathLeft,
789
+ pathRight: pathRight,
790
+ };
791
+ }
322
792
 
323
793
  /**
324
794
  * @override
325
795
  */
326
- this.FIELD_CHECKBOX_X_OFFSET = 1 * this.GRID_UNIT;
327
-
328
- /**
329
- * The maximum width of a dynamic connection shape.
330
- * @type {number}
331
- */
332
- this.MAX_DYNAMIC_CONNECTION_SHAPE_WIDTH = 12 * this.GRID_UNIT;
333
-
334
- /**
335
- * The selected glow colour.
336
- * @type {string}
337
- */
338
- this.SELECTED_GLOW_COLOUR = '#fff200';
339
-
340
- /**
341
- * The size of the selected glow.
342
- * @type {number}
343
- */
344
- this.SELECTED_GLOW_SIZE = 0.5;
345
-
346
- /**
347
- * The replacement glow colour.
348
- * @type {string}
349
- */
350
- this.REPLACEMENT_GLOW_COLOUR = '#fff200';
351
-
352
- /**
353
- * The size of the selected glow.
354
- * @type {number}
355
- */
356
- this.REPLACEMENT_GLOW_SIZE = 2;
357
-
358
- /**
359
- * The ID of the selected glow filter, or the empty string if no filter is
360
- * set.
361
- * @type {string}
362
- * @package
363
- */
364
- this.selectedGlowFilterId = '';
365
-
366
- /**
367
- * The <filter> element to use for a selected glow, or null if not set.
368
- * @type {SVGElement}
369
- * @private
370
- */
371
- this.selectedGlowFilter_ = null;
372
-
373
- /**
374
- * The ID of the replacement glow filter, or the empty string if no filter is
375
- * set.
376
- * @type {string}
377
- * @package
378
- */
379
- this.replacementGlowFilterId = '';
796
+ makeInsideCorners() {
797
+ const radius = this.CORNER_RADIUS;
380
798
 
381
- /**
382
- * The <filter> element to use for a replacement glow, or null if not set.
383
- * @type {SVGElement}
384
- * @private
385
- */
386
- this.replacementGlowFilter_ = null;
387
- };
388
- object.inherits(ConstantProvider, BaseConstantProvider);
389
-
390
- /**
391
- * @override
392
- */
393
- ConstantProvider.prototype.setFontConstants_ = function(theme) {
394
- ConstantProvider.superClass_.setFontConstants_.call(this, theme);
799
+ const innerTopLeftCorner =
800
+ svgPaths.arc('a', '0 0,0', radius, svgPaths.point(-radius, radius));
395
801
 
396
- this.FIELD_BORDER_RECT_HEIGHT =
397
- this.FIELD_TEXT_HEIGHT + this.FIELD_BORDER_RECT_Y_PADDING * 2;
398
- this.FIELD_DROPDOWN_BORDER_RECT_HEIGHT = this.FIELD_BORDER_RECT_HEIGHT;
399
- };
802
+ const innerTopRightCorner =
803
+ svgPaths.arc('a', '0 0,1', radius, svgPaths.point(-radius, radius));
400
804
 
401
- /**
402
- * @override
403
- */
404
- ConstantProvider.prototype.init = function() {
405
- ConstantProvider.superClass_.init.call(this);
406
- this.HEXAGONAL = this.makeHexagonal();
407
- this.ROUNDED = this.makeRounded();
408
- this.SQUARED = this.makeSquared();
409
-
410
- this.STATEMENT_INPUT_NOTCH_OFFSET =
411
- this.NOTCH_OFFSET_LEFT + this.INSIDE_CORNERS.rightWidth;
412
- };
805
+ const innerBottomLeftCorner =
806
+ svgPaths.arc('a', '0 0,0', radius, svgPaths.point(radius, radius));
413
807
 
414
- /**
415
- * @override
416
- */
417
- ConstantProvider.prototype.setDynamicProperties_ = function(theme) {
418
- ConstantProvider.superClass_.setDynamicProperties_.call(this, theme);
419
-
420
- this.SELECTED_GLOW_COLOUR = theme.getComponentStyle('selectedGlowColour') ||
421
- this.SELECTED_GLOW_COLOUR;
422
- const selectedGlowSize = Number(theme.getComponentStyle('selectedGlowSize'));
423
- this.SELECTED_GLOW_SIZE = selectedGlowSize && !isNaN(selectedGlowSize) ?
424
- selectedGlowSize :
425
- this.SELECTED_GLOW_SIZE;
426
- this.REPLACEMENT_GLOW_COLOUR =
427
- theme.getComponentStyle('replacementGlowColour') ||
428
- this.REPLACEMENT_GLOW_COLOUR;
429
- const replacementGlowSize =
430
- Number(theme.getComponentStyle('replacementGlowSize'));
431
- this.REPLACEMENT_GLOW_SIZE =
432
- replacementGlowSize && !isNaN(replacementGlowSize) ?
433
- replacementGlowSize :
434
- this.REPLACEMENT_GLOW_SIZE;
435
- };
808
+ const innerBottomRightCorner =
809
+ svgPaths.arc('a', '0 0,1', radius, svgPaths.point(radius, radius));
436
810
 
437
- /**
438
- * @override
439
- */
440
- ConstantProvider.prototype.dispose = function() {
441
- ConstantProvider.superClass_.dispose.call(this);
442
- if (this.selectedGlowFilter_) {
443
- dom.removeNode(this.selectedGlowFilter_);
444
- }
445
- if (this.replacementGlowFilter_) {
446
- dom.removeNode(this.replacementGlowFilter_);
811
+ return {
812
+ width: radius,
813
+ height: radius,
814
+ pathTop: innerTopLeftCorner,
815
+ pathBottom: innerBottomLeftCorner,
816
+ rightWidth: radius,
817
+ rightHeight: radius,
818
+ pathTopRight: innerTopRightCorner,
819
+ pathBottomRight: innerBottomRightCorner,
820
+ };
447
821
  }
448
- };
449
-
450
- /**
451
- * @override
452
- */
453
- ConstantProvider.prototype.makeStartHat = function() {
454
- const height = this.START_HAT_HEIGHT;
455
- const width = this.START_HAT_WIDTH;
456
-
457
- const mainPath = svgPaths.curve('c', [
458
- svgPaths.point(25, -height),
459
- svgPaths.point(71, -height),
460
- svgPaths.point(width, 0),
461
- ]);
462
- return {height: height, width: width, path: mainPath};
463
- };
464
-
465
- /**
466
- * Create sizing and path information about a hexagonal shape.
467
- * @return {!Object} An object containing sizing and path information about
468
- * a hexagonal shape for connections.
469
- * @package
470
- */
471
- ConstantProvider.prototype.makeHexagonal = function() {
472
- const maxWidth = this.MAX_DYNAMIC_CONNECTION_SHAPE_WIDTH;
473
822
 
474
823
  /**
475
- * Make the main path for the hexagonal connection shape out of two lines.
476
- * The lines are defined with relative positions and require the block height.
477
- * The 'up' and 'down' versions of the paths are the same, but the Y sign
478
- * flips. The 'left' and 'right' versions of the path are also the same, but
479
- * the X sign flips.
480
- * @param {number} height The height of the block the connection is on.
481
- * @param {boolean} up True if the path should be drawn from bottom to top,
482
- * false otherwise.
483
- * @param {boolean} right True if the path is for the right side of the
484
- * block.
485
- * @return {string} A path fragment describing a rounded connection.
824
+ * @override
486
825
  */
487
- function makeMainPath(height, up, right) {
488
- const halfHeight = height / 2;
489
- const width = halfHeight > maxWidth ? maxWidth : halfHeight;
490
- const forward = up ? -1 : 1;
491
- const direction = right ? -1 : 1;
492
- const dy = forward * height / 2;
493
- return svgPaths.lineTo(-direction * width, dy) +
494
- svgPaths.lineTo(direction * width, dy);
826
+ generateSecondaryColour_(colour) {
827
+ return utilsColour.blend('#000', colour, 0.15) || colour;
495
828
  }
496
829
 
497
- return {
498
- type: this.SHAPES.HEXAGONAL,
499
- isDynamic: true,
500
- width: function(height) {
501
- const halfHeight = height / 2;
502
- return halfHeight > maxWidth ? maxWidth : halfHeight;
503
- },
504
- height: function(height) {
505
- return height;
506
- },
507
- connectionOffsetY: function(connectionHeight) {
508
- return connectionHeight / 2;
509
- },
510
- connectionOffsetX: function(connectionWidth) {
511
- return -connectionWidth;
512
- },
513
- pathDown: function(height) {
514
- return makeMainPath(height, false, false);
515
- },
516
- pathUp: function(height) {
517
- return makeMainPath(height, true, false);
518
- },
519
- pathRightDown: function(height) {
520
- return makeMainPath(height, false, true);
521
- },
522
- pathRightUp: function(height) {
523
- return makeMainPath(height, false, true);
524
- },
525
- };
526
- };
527
-
528
- /**
529
- * Create sizing and path information about a rounded shape.
530
- * @return {!Object} An object containing sizing and path information about
531
- * a rounded shape for connections.
532
- * @package
533
- */
534
- ConstantProvider.prototype.makeRounded = function() {
535
- const maxWidth = this.MAX_DYNAMIC_CONNECTION_SHAPE_WIDTH;
536
- const maxHeight = maxWidth * 2;
537
-
538
830
  /**
539
- * Make the main path for the rounded connection shape out of two arcs and
540
- * a line that joins them. The arcs are defined with relative positions.
541
- * Usually, the height of the block is split between the two arcs. In the case
542
- * where the height of the block exceeds the maximum height, a line is drawn
543
- * in between the two arcs.
544
- * The 'up' and 'down' versions of the paths are the same, but the Y sign
545
- * flips. The 'up' and 'right' versions of the path flip the sweep-flag
546
- * which moves the arc at negative angles.
547
- * @param {number} blockHeight The height of the block the connection is on.
548
- * @param {boolean} up True if the path should be drawn from bottom to top,
549
- * false otherwise.
550
- * @param {boolean} right True if the path is for the right side of the
551
- * block.
552
- * @return {string} A path fragment describing a rounded connection.
831
+ * @override
553
832
  */
554
- function makeMainPath(blockHeight, up, right) {
555
- const remainingHeight =
556
- blockHeight > maxHeight ? blockHeight - maxHeight : 0;
557
- const height = blockHeight > maxHeight ? maxHeight : blockHeight;
558
- const radius = height / 2;
559
- return svgPaths.arc(
560
- 'a', '0 0,1', radius,
561
- svgPaths.point((up ? -1 : 1) * radius, (up ? -1 : 1) * radius)) +
562
- svgPaths.lineOnAxis('v', (right ? 1 : -1) * remainingHeight) +
563
- svgPaths.arc(
564
- 'a', '0 0,1', radius,
565
- svgPaths.point((up ? 1 : -1) * radius, (up ? -1 : 1) * radius));
833
+ generateTertiaryColour_(colour) {
834
+ return utilsColour.blend('#000', colour, 0.25) || colour;
566
835
  }
567
836
 
568
- return {
569
- type: this.SHAPES.ROUND,
570
- isDynamic: true,
571
- width: function(height) {
572
- const halfHeight = height / 2;
573
- return halfHeight > maxWidth ? maxWidth : halfHeight;
574
- },
575
- height: function(height) {
576
- return height;
577
- },
578
- connectionOffsetY: function(connectionHeight) {
579
- return connectionHeight / 2;
580
- },
581
- connectionOffsetX: function(connectionWidth) {
582
- return -connectionWidth;
583
- },
584
- pathDown: function(height) {
585
- return makeMainPath(height, false, false);
586
- },
587
- pathUp: function(height) {
588
- return makeMainPath(height, true, false);
589
- },
590
- pathRightDown: function(height) {
591
- return makeMainPath(height, false, true);
592
- },
593
- pathRightUp: function(height) {
594
- return makeMainPath(height, false, true);
595
- },
596
- };
597
- };
598
-
599
- /**
600
- * Create sizing and path information about a squared shape.
601
- * @return {!Object} An object containing sizing and path information about
602
- * a squared shape for connections.
603
- * @package
604
- */
605
- ConstantProvider.prototype.makeSquared = function() {
606
- const radius = this.CORNER_RADIUS;
607
-
608
837
  /**
609
- * Make the main path for the squared connection shape out of two corners
610
- * and a single line in-between (a and v). These are defined in relative
611
- * positions and require the height of the block.
612
- * The 'left' and 'right' versions of the paths are the same, but the Y sign
613
- * flips. The 'up' and 'down' versions of the path determine where the corner
614
- * point is placed and in turn the direction of the corners.
615
- * @param {number} height The height of the block the connection is on.
616
- * @param {boolean} up True if the path should be drawn from bottom to top,
617
- * false otherwise.
618
- * @param {boolean} right True if the path is for the right side of the
619
- * block.
620
- * @return {string} A path fragment describing a squared connection.
838
+ * @override
621
839
  */
622
- function makeMainPath(height, up, right) {
623
- const innerHeight = height - radius * 2;
624
- return svgPaths.arc(
625
- 'a', '0 0,1', radius,
626
- svgPaths.point((up ? -1 : 1) * radius, (up ? -1 : 1) * radius)) +
627
- svgPaths.lineOnAxis('v', (right ? 1 : -1) * innerHeight) +
628
- svgPaths.arc(
629
- 'a', '0 0,1', radius,
630
- svgPaths.point((up ? 1 : -1) * radius, (up ? -1 : 1) * radius));
840
+ createDom(svg, tagName, selector) {
841
+ super.createDom(svg, tagName, selector);
842
+ /*
843
+ <defs>
844
+ ... filters go here ...
845
+ </defs>
846
+ */
847
+ const defs = dom.createSvgElement(Svg.DEFS, {}, svg);
848
+ // Using a dilate distorts the block shape.
849
+ // Instead use a gaussian blur, and then set all alpha to 1 with a transfer.
850
+ const selectedGlowFilter = dom.createSvgElement(
851
+ Svg.FILTER, {
852
+ 'id': 'blocklySelectedGlowFilter' + this.randomIdentifier,
853
+ 'height': '160%',
854
+ 'width': '180%',
855
+ 'y': '-30%',
856
+ 'x': '-40%',
857
+ },
858
+ defs);
859
+ dom.createSvgElement(
860
+ Svg.FEGAUSSIANBLUR,
861
+ {'in': 'SourceGraphic', 'stdDeviation': this.SELECTED_GLOW_SIZE},
862
+ selectedGlowFilter);
863
+ // Set all gaussian blur pixels to 1 opacity before applying flood
864
+ const selectedComponentTransfer = dom.createSvgElement(
865
+ Svg.FECOMPONENTTRANSFER, {'result': 'outBlur'}, selectedGlowFilter);
866
+ dom.createSvgElement(
867
+ Svg.FEFUNCA,
868
+ {'type': 'table', 'tableValues': '0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1'},
869
+ selectedComponentTransfer);
870
+ // Color the highlight
871
+ dom.createSvgElement(
872
+ Svg.FEFLOOD, {
873
+ 'flood-color': this.SELECTED_GLOW_COLOUR,
874
+ 'flood-opacity': 1,
875
+ 'result': 'outColor',
876
+ },
877
+ selectedGlowFilter);
878
+ dom.createSvgElement(
879
+ Svg.FECOMPOSITE, {
880
+ 'in': 'outColor',
881
+ 'in2': 'outBlur',
882
+ 'operator': 'in',
883
+ 'result': 'outGlow',
884
+ },
885
+ selectedGlowFilter);
886
+ this.selectedGlowFilterId = selectedGlowFilter.id;
887
+ this.selectedGlowFilter_ = selectedGlowFilter;
888
+
889
+ // Using a dilate distorts the block shape.
890
+ // Instead use a gaussian blur, and then set all alpha to 1 with a transfer.
891
+ const replacementGlowFilter = dom.createSvgElement(
892
+ Svg.FILTER, {
893
+ 'id': 'blocklyReplacementGlowFilter' + this.randomIdentifier,
894
+ 'height': '160%',
895
+ 'width': '180%',
896
+ 'y': '-30%',
897
+ 'x': '-40%',
898
+ },
899
+ defs);
900
+ dom.createSvgElement(
901
+ Svg.FEGAUSSIANBLUR,
902
+ {'in': 'SourceGraphic', 'stdDeviation': this.REPLACEMENT_GLOW_SIZE},
903
+ replacementGlowFilter);
904
+ // Set all gaussian blur pixels to 1 opacity before applying flood
905
+ const replacementComponentTransfer = dom.createSvgElement(
906
+ Svg.FECOMPONENTTRANSFER, {'result': 'outBlur'}, replacementGlowFilter);
907
+ dom.createSvgElement(
908
+ Svg.FEFUNCA,
909
+ {'type': 'table', 'tableValues': '0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1'},
910
+ replacementComponentTransfer);
911
+ // Color the highlight
912
+ dom.createSvgElement(
913
+ Svg.FEFLOOD, {
914
+ 'flood-color': this.REPLACEMENT_GLOW_COLOUR,
915
+ 'flood-opacity': 1,
916
+ 'result': 'outColor',
917
+ },
918
+ replacementGlowFilter);
919
+ dom.createSvgElement(
920
+ Svg.FECOMPOSITE, {
921
+ 'in': 'outColor',
922
+ 'in2': 'outBlur',
923
+ 'operator': 'in',
924
+ 'result': 'outGlow',
925
+ },
926
+ replacementGlowFilter);
927
+ dom.createSvgElement(
928
+ Svg.FECOMPOSITE, {
929
+ 'in': 'SourceGraphic',
930
+ 'in2': 'outGlow',
931
+ 'operator': 'over',
932
+ },
933
+ replacementGlowFilter);
934
+ this.replacementGlowFilterId = replacementGlowFilter.id;
935
+ this.replacementGlowFilter_ = replacementGlowFilter;
631
936
  }
632
937
 
633
- return {
634
- type: this.SHAPES.SQUARE,
635
- isDynamic: true,
636
- width: function(_height) {
637
- return radius;
638
- },
639
- height: function(height) {
640
- return height;
641
- },
642
- connectionOffsetY: function(connectionHeight) {
643
- return connectionHeight / 2;
644
- },
645
- connectionOffsetX: function(connectionWidth) {
646
- return -connectionWidth;
647
- },
648
- pathDown: function(height) {
649
- return makeMainPath(height, false, false);
650
- },
651
- pathUp: function(height) {
652
- return makeMainPath(height, true, false);
653
- },
654
- pathRightDown: function(height) {
655
- return makeMainPath(height, false, true);
656
- },
657
- pathRightUp: function(height) {
658
- return makeMainPath(height, false, true);
659
- },
660
- };
661
- };
662
-
663
- /**
664
- * @override
665
- */
666
- ConstantProvider.prototype.shapeFor = function(connection) {
667
- let checks = connection.getCheck();
668
- if (!checks && connection.targetConnection) {
669
- checks = connection.targetConnection.getCheck();
670
- }
671
- let outputShape;
672
- switch (connection.type) {
673
- case ConnectionType.INPUT_VALUE:
674
- case ConnectionType.OUTPUT_VALUE:
675
- outputShape = connection.getSourceBlock().getOutputShape();
676
- // If the block has an output shape set, use that instead.
677
- if (outputShape !== null) {
678
- switch (outputShape) {
679
- case this.SHAPES.HEXAGONAL:
680
- return this.HEXAGONAL;
681
- case this.SHAPES.ROUND:
682
- return this.ROUNDED;
683
- case this.SHAPES.SQUARE:
684
- return this.SQUARED;
685
- }
686
- }
687
- // Includes doesn't work in IE.
688
- if (checks && checks.indexOf('Boolean') !== -1) {
689
- return this.HEXAGONAL;
690
- }
691
- if (checks && checks.indexOf('Number') !== -1) {
692
- return this.ROUNDED;
693
- }
694
- if (checks && checks.indexOf('String') !== -1) {
695
- return this.ROUNDED;
696
- }
697
- return this.ROUNDED;
698
- case ConnectionType.PREVIOUS_STATEMENT:
699
- case ConnectionType.NEXT_STATEMENT:
700
- return this.NOTCH;
701
- default:
702
- throw Error('Unknown type');
703
- }
704
- };
705
-
706
- /**
707
- * @override
708
- */
709
- ConstantProvider.prototype.makeNotch = function() {
710
- const width = this.NOTCH_WIDTH;
711
- const height = this.NOTCH_HEIGHT;
712
-
713
- const innerWidth = width / 3;
714
- const curveWidth = innerWidth / 3;
715
-
716
- const halfHeight = height / 2;
717
- const quarterHeight = halfHeight / 2;
718
-
719
938
  /**
720
- * Make the main path for the notch.
721
- * @param {number} dir Direction multiplier to apply to horizontal offsets
722
- * along the path. Either 1 or -1.
723
- * @return {string} A path fragment describing a notch.
939
+ * @override
724
940
  */
725
- function makeMainPath(dir) {
726
- return (
727
- svgPaths.curve(
728
- 'c',
729
- [
730
- svgPaths.point(dir * curveWidth / 2, 0),
731
- svgPaths.point(dir * curveWidth * 3 / 4, quarterHeight / 2),
732
- svgPaths.point(dir * curveWidth, quarterHeight),
733
- ]) +
734
- svgPaths.line([svgPaths.point(dir * curveWidth, halfHeight)]) +
735
- svgPaths.curve(
736
- 'c',
737
- [
738
- svgPaths.point(dir * curveWidth / 4, quarterHeight / 2),
739
- svgPaths.point(dir * curveWidth / 2, quarterHeight),
740
- svgPaths.point(dir * curveWidth, quarterHeight),
741
- ]) +
742
- svgPaths.lineOnAxis('h', dir * innerWidth) +
743
- svgPaths.curve(
744
- 'c',
745
- [
746
- svgPaths.point(dir * curveWidth / 2, 0),
747
- svgPaths.point(dir * curveWidth * 3 / 4, -(quarterHeight / 2)),
748
- svgPaths.point(dir * curveWidth, -quarterHeight),
749
- ]) +
750
- svgPaths.line([svgPaths.point(dir * curveWidth, -halfHeight)]) +
751
- svgPaths.curve('c', [
752
- svgPaths.point(dir * curveWidth / 4, -(quarterHeight / 2)),
753
- svgPaths.point(dir * curveWidth / 2, -quarterHeight),
754
- svgPaths.point(dir * curveWidth, -quarterHeight),
755
- ]));
941
+ getCSS_(selector) {
942
+ return [
943
+ /* eslint-disable indent */
944
+ // Text.
945
+ selector + ' .blocklyText,', selector + ' .blocklyFlyoutLabelText {',
946
+ 'font: ' + this.FIELD_TEXT_FONTWEIGHT + ' ' + this.FIELD_TEXT_FONTSIZE +
947
+ 'pt ' + this.FIELD_TEXT_FONTFAMILY + ';',
948
+ '}',
949
+
950
+ // Fields.
951
+ selector + ' .blocklyText {', 'fill: #fff;', '}',
952
+ selector + ' .blocklyNonEditableText>rect:not(.blocklyDropdownRect),',
953
+ selector + ' .blocklyEditableText>rect:not(.blocklyDropdownRect) {',
954
+ 'fill: ' + this.FIELD_BORDER_RECT_COLOUR + ';', '}',
955
+ selector + ' .blocklyNonEditableText>text,',
956
+ selector + ' .blocklyEditableText>text,',
957
+ selector + ' .blocklyNonEditableText>g>text,',
958
+ selector + ' .blocklyEditableText>g>text {', 'fill: #575E75;', '}',
959
+
960
+ // Flyout labels.
961
+ selector + ' .blocklyFlyoutLabelText {', 'fill: #575E75;', '}',
962
+
963
+ // Bubbles.
964
+ selector + ' .blocklyText.blocklyBubbleText {', 'fill: #575E75;', '}',
965
+
966
+ // Editable field hover.
967
+ selector + ' .blocklyDraggable:not(.blocklyDisabled)',
968
+ ' .blocklyEditableText:not(.editing):hover>rect,',
969
+ selector + ' .blocklyDraggable:not(.blocklyDisabled)',
970
+ ' .blocklyEditableText:not(.editing):hover>.blocklyPath {',
971
+ 'stroke: #fff;', 'stroke-width: 2;', '}',
972
+
973
+ // Text field input.
974
+ selector + ' .blocklyHtmlInput {',
975
+ 'font-family: ' + this.FIELD_TEXT_FONTFAMILY + ';',
976
+ 'font-weight: ' + this.FIELD_TEXT_FONTWEIGHT + ';', 'color: #575E75;',
977
+ '}',
978
+
979
+ // Dropdown field.
980
+ selector + ' .blocklyDropdownText {', 'fill: #fff !important;', '}',
981
+ // Widget and Dropdown Div
982
+ selector + '.blocklyWidgetDiv .goog-menuitem,',
983
+ selector + '.blocklyDropDownDiv .goog-menuitem {',
984
+ 'font-family: ' + this.FIELD_TEXT_FONTFAMILY + ';', '}',
985
+ selector + '.blocklyDropDownDiv .goog-menuitem-content {', 'color: #fff;',
986
+ '}',
987
+
988
+ // Connection highlight.
989
+ selector + ' .blocklyHighlightedConnectionPath {',
990
+ 'stroke: ' + this.SELECTED_GLOW_COLOUR + ';', '}',
991
+
992
+ // Disabled outline paths.
993
+ selector + ' .blocklyDisabled > .blocklyOutlinePath {',
994
+ 'fill: url(#blocklyDisabledPattern' + this.randomIdentifier + ')', '}',
995
+
996
+ // Insertion marker.
997
+ selector + ' .blocklyInsertionMarker>.blocklyPath {',
998
+ 'fill-opacity: ' + this.INSERTION_MARKER_OPACITY + ';', 'stroke: none;',
999
+ '}',
1000
+ /* eslint-enable indent */
1001
+ ];
756
1002
  }
757
-
758
- const pathLeft = makeMainPath(1);
759
- const pathRight = makeMainPath(-1);
760
-
761
- return {
762
- type: this.SHAPES.NOTCH,
763
- width: width,
764
- height: height,
765
- pathLeft: pathLeft,
766
- pathRight: pathRight,
767
- };
768
- };
769
-
770
- /**
771
- * @override
772
- */
773
- ConstantProvider.prototype.makeInsideCorners = function() {
774
- const radius = this.CORNER_RADIUS;
775
-
776
- const innerTopLeftCorner =
777
- svgPaths.arc('a', '0 0,0', radius, svgPaths.point(-radius, radius));
778
-
779
- const innerTopRightCorner =
780
- svgPaths.arc('a', '0 0,1', radius, svgPaths.point(-radius, radius));
781
-
782
- const innerBottomLeftCorner =
783
- svgPaths.arc('a', '0 0,0', radius, svgPaths.point(radius, radius));
784
-
785
- const innerBottomRightCorner =
786
- svgPaths.arc('a', '0 0,1', radius, svgPaths.point(radius, radius));
787
-
788
- return {
789
- width: radius,
790
- height: radius,
791
- pathTop: innerTopLeftCorner,
792
- pathBottom: innerBottomLeftCorner,
793
- rightWidth: radius,
794
- rightHeight: radius,
795
- pathTopRight: innerTopRightCorner,
796
- pathBottomRight: innerBottomRightCorner,
797
- };
798
- };
799
-
800
- /**
801
- * @override
802
- */
803
- ConstantProvider.prototype.generateSecondaryColour_ = function(colour) {
804
- return utilsColour.blend('#000', colour, 0.15) || colour;
805
- };
806
-
807
- /**
808
- * @override
809
- */
810
- ConstantProvider.prototype.generateTertiaryColour_ = function(colour) {
811
- return utilsColour.blend('#000', colour, 0.25) || colour;
812
- };
813
-
814
- /**
815
- * @override
816
- */
817
- ConstantProvider.prototype.createDom = function(svg, tagName, selector) {
818
- ConstantProvider.superClass_.createDom.call(this, svg, tagName, selector);
819
- /*
820
- <defs>
821
- ... filters go here ...
822
- </defs>
823
- */
824
- const defs = dom.createSvgElement(Svg.DEFS, {}, svg);
825
- // Using a dilate distorts the block shape.
826
- // Instead use a gaussian blur, and then set all alpha to 1 with a transfer.
827
- const selectedGlowFilter = dom.createSvgElement(
828
- Svg.FILTER, {
829
- 'id': 'blocklySelectedGlowFilter' + this.randomIdentifier,
830
- 'height': '160%',
831
- 'width': '180%',
832
- 'y': '-30%',
833
- 'x': '-40%',
834
- },
835
- defs);
836
- dom.createSvgElement(
837
- Svg.FEGAUSSIANBLUR,
838
- {'in': 'SourceGraphic', 'stdDeviation': this.SELECTED_GLOW_SIZE},
839
- selectedGlowFilter);
840
- // Set all gaussian blur pixels to 1 opacity before applying flood
841
- const selectedComponentTransfer = dom.createSvgElement(
842
- Svg.FECOMPONENTTRANSFER, {'result': 'outBlur'}, selectedGlowFilter);
843
- dom.createSvgElement(
844
- Svg.FEFUNCA,
845
- {'type': 'table', 'tableValues': '0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1'},
846
- selectedComponentTransfer);
847
- // Color the highlight
848
- dom.createSvgElement(
849
- Svg.FEFLOOD, {
850
- 'flood-color': this.SELECTED_GLOW_COLOUR,
851
- 'flood-opacity': 1,
852
- 'result': 'outColor',
853
- },
854
- selectedGlowFilter);
855
- dom.createSvgElement(
856
- Svg.FECOMPOSITE, {
857
- 'in': 'outColor',
858
- 'in2': 'outBlur',
859
- 'operator': 'in',
860
- 'result': 'outGlow',
861
- },
862
- selectedGlowFilter);
863
- this.selectedGlowFilterId = selectedGlowFilter.id;
864
- this.selectedGlowFilter_ = selectedGlowFilter;
865
-
866
- // Using a dilate distorts the block shape.
867
- // Instead use a gaussian blur, and then set all alpha to 1 with a transfer.
868
- const replacementGlowFilter = dom.createSvgElement(
869
- Svg.FILTER, {
870
- 'id': 'blocklyReplacementGlowFilter' + this.randomIdentifier,
871
- 'height': '160%',
872
- 'width': '180%',
873
- 'y': '-30%',
874
- 'x': '-40%',
875
- },
876
- defs);
877
- dom.createSvgElement(
878
- Svg.FEGAUSSIANBLUR,
879
- {'in': 'SourceGraphic', 'stdDeviation': this.REPLACEMENT_GLOW_SIZE},
880
- replacementGlowFilter);
881
- // Set all gaussian blur pixels to 1 opacity before applying flood
882
- const replacementComponentTransfer = dom.createSvgElement(
883
- Svg.FECOMPONENTTRANSFER, {'result': 'outBlur'}, replacementGlowFilter);
884
- dom.createSvgElement(
885
- Svg.FEFUNCA,
886
- {'type': 'table', 'tableValues': '0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1'},
887
- replacementComponentTransfer);
888
- // Color the highlight
889
- dom.createSvgElement(
890
- Svg.FEFLOOD, {
891
- 'flood-color': this.REPLACEMENT_GLOW_COLOUR,
892
- 'flood-opacity': 1,
893
- 'result': 'outColor',
894
- },
895
- replacementGlowFilter);
896
- dom.createSvgElement(
897
- Svg.FECOMPOSITE, {
898
- 'in': 'outColor',
899
- 'in2': 'outBlur',
900
- 'operator': 'in',
901
- 'result': 'outGlow',
902
- },
903
- replacementGlowFilter);
904
- dom.createSvgElement(
905
- Svg.FECOMPOSITE, {
906
- 'in': 'SourceGraphic',
907
- 'in2': 'outGlow',
908
- 'operator': 'over',
909
- },
910
- replacementGlowFilter);
911
- this.replacementGlowFilterId = replacementGlowFilter.id;
912
- this.replacementGlowFilter_ = replacementGlowFilter;
913
- };
914
-
915
- /**
916
- * @override
917
- */
918
- ConstantProvider.prototype.getCSS_ = function(selector) {
919
- return [
920
- /* eslint-disable indent */
921
- // Text.
922
- selector + ' .blocklyText,', selector + ' .blocklyFlyoutLabelText {',
923
- 'font: ' + this.FIELD_TEXT_FONTWEIGHT + ' ' + this.FIELD_TEXT_FONTSIZE +
924
- 'pt ' + this.FIELD_TEXT_FONTFAMILY + ';',
925
- '}',
926
-
927
- // Fields.
928
- selector + ' .blocklyText {', 'fill: #fff;', '}',
929
- selector + ' .blocklyNonEditableText>rect:not(.blocklyDropdownRect),',
930
- selector + ' .blocklyEditableText>rect:not(.blocklyDropdownRect) {',
931
- 'fill: ' + this.FIELD_BORDER_RECT_COLOUR + ';', '}',
932
- selector + ' .blocklyNonEditableText>text,',
933
- selector + ' .blocklyEditableText>text,',
934
- selector + ' .blocklyNonEditableText>g>text,',
935
- selector + ' .blocklyEditableText>g>text {', 'fill: #575E75;', '}',
936
-
937
- // Flyout labels.
938
- selector + ' .blocklyFlyoutLabelText {', 'fill: #575E75;', '}',
939
-
940
- // Bubbles.
941
- selector + ' .blocklyText.blocklyBubbleText {', 'fill: #575E75;', '}',
942
-
943
- // Editable field hover.
944
- selector + ' .blocklyDraggable:not(.blocklyDisabled)',
945
- ' .blocklyEditableText:not(.editing):hover>rect,',
946
- selector + ' .blocklyDraggable:not(.blocklyDisabled)',
947
- ' .blocklyEditableText:not(.editing):hover>.blocklyPath {', 'stroke: #fff;',
948
- 'stroke-width: 2;', '}',
949
-
950
- // Text field input.
951
- selector + ' .blocklyHtmlInput {',
952
- 'font-family: ' + this.FIELD_TEXT_FONTFAMILY + ';',
953
- 'font-weight: ' + this.FIELD_TEXT_FONTWEIGHT + ';', 'color: #575E75;', '}',
954
-
955
- // Dropdown field.
956
- selector + ' .blocklyDropdownText {', 'fill: #fff !important;', '}',
957
- // Widget and Dropdown Div
958
- selector + '.blocklyWidgetDiv .goog-menuitem,',
959
- selector + '.blocklyDropDownDiv .goog-menuitem {',
960
- 'font-family: ' + this.FIELD_TEXT_FONTFAMILY + ';', '}',
961
- selector + '.blocklyDropDownDiv .goog-menuitem-content {', 'color: #fff;',
962
- '}',
963
-
964
- // Connection highlight.
965
- selector + ' .blocklyHighlightedConnectionPath {',
966
- 'stroke: ' + this.SELECTED_GLOW_COLOUR + ';', '}',
967
-
968
- // Disabled outline paths.
969
- selector + ' .blocklyDisabled > .blocklyOutlinePath {',
970
- 'fill: url(#blocklyDisabledPattern' + this.randomIdentifier + ')', '}',
971
-
972
- // Insertion marker.
973
- selector + ' .blocklyInsertionMarker>.blocklyPath {',
974
- 'fill-opacity: ' + this.INSERTION_MARKER_OPACITY + ';', 'stroke: none;',
975
- '}',
976
- /* eslint-enable indent */
977
- ];
978
- };
1003
+ }
979
1004
 
980
1005
  exports.ConstantProvider = ConstantProvider;