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
package/core/options.js CHANGED
@@ -31,163 +31,318 @@ const {WorkspaceSvg} = goog.requireType('Blockly.WorkspaceSvg');
31
31
  /**
32
32
  * Parse the user-specified options, using reasonable defaults where behaviour
33
33
  * is unspecified.
34
- * @param {!BlocklyOptions} options Dictionary of options.
35
- * Specification:
36
- * https://developers.google.com/blockly/guides/get-started/web#configuration
37
- * @constructor
38
34
  * @alias Blockly.Options
39
35
  */
40
- const Options = function(options) {
41
- let toolboxJsonDef = null;
42
- let hasCategories = false;
43
- let hasTrashcan = false;
44
- let hasCollapse = false;
45
- let hasComments = false;
46
- let hasDisable = false;
47
- let hasSounds = false;
48
- const readOnly = !!options['readOnly'];
49
- if (!readOnly) {
50
- toolboxJsonDef = toolbox.convertToolboxDefToJson(options['toolbox']);
51
- hasCategories = toolbox.hasCategories(toolboxJsonDef);
52
- hasTrashcan = options['trashcan'];
53
- if (hasTrashcan === undefined) {
54
- hasTrashcan = hasCategories;
55
- }
56
- hasCollapse = options['collapse'];
57
- if (hasCollapse === undefined) {
58
- hasCollapse = hasCategories;
36
+ class Options {
37
+ /**
38
+ * @param {!BlocklyOptions} options Dictionary of options.
39
+ * Specification:
40
+ * https://developers.google.com/blockly/guides/get-started/web#configuration
41
+ */
42
+ constructor(options) {
43
+ let toolboxJsonDef = null;
44
+ let hasCategories = false;
45
+ let hasTrashcan = false;
46
+ let hasCollapse = false;
47
+ let hasComments = false;
48
+ let hasDisable = false;
49
+ let hasSounds = false;
50
+ const readOnly = !!options['readOnly'];
51
+ if (!readOnly) {
52
+ toolboxJsonDef = toolbox.convertToolboxDefToJson(options['toolbox']);
53
+ hasCategories = toolbox.hasCategories(toolboxJsonDef);
54
+ hasTrashcan = options['trashcan'];
55
+ if (hasTrashcan === undefined) {
56
+ hasTrashcan = hasCategories;
57
+ }
58
+ hasCollapse = options['collapse'];
59
+ if (hasCollapse === undefined) {
60
+ hasCollapse = hasCategories;
61
+ }
62
+ hasComments = options['comments'];
63
+ if (hasComments === undefined) {
64
+ hasComments = hasCategories;
65
+ }
66
+ hasDisable = options['disable'];
67
+ if (hasDisable === undefined) {
68
+ hasDisable = hasCategories;
69
+ }
70
+ hasSounds = options['sounds'];
71
+ if (hasSounds === undefined) {
72
+ hasSounds = true;
73
+ }
59
74
  }
60
- hasComments = options['comments'];
61
- if (hasComments === undefined) {
62
- hasComments = hasCategories;
75
+
76
+ let maxTrashcanContents = options['maxTrashcanContents'];
77
+ if (hasTrashcan) {
78
+ if (maxTrashcanContents === undefined) {
79
+ maxTrashcanContents = 32;
80
+ }
81
+ } else {
82
+ maxTrashcanContents = 0;
63
83
  }
64
- hasDisable = options['disable'];
65
- if (hasDisable === undefined) {
66
- hasDisable = hasCategories;
84
+ const rtl = !!options['rtl'];
85
+ let horizontalLayout = options['horizontalLayout'];
86
+ if (horizontalLayout === undefined) {
87
+ horizontalLayout = false;
67
88
  }
68
- hasSounds = options['sounds'];
69
- if (hasSounds === undefined) {
70
- hasSounds = true;
89
+ let toolboxAtStart = options['toolboxPosition'];
90
+ toolboxAtStart = toolboxAtStart !== 'end';
91
+
92
+ /** @type {!toolbox.Position} */
93
+ let toolboxPosition;
94
+ if (horizontalLayout) {
95
+ toolboxPosition =
96
+ toolboxAtStart ? toolbox.Position.TOP : toolbox.Position.BOTTOM;
97
+ } else {
98
+ toolboxPosition = (toolboxAtStart === rtl) ? toolbox.Position.RIGHT :
99
+ toolbox.Position.LEFT;
71
100
  }
72
- }
73
101
 
74
- let maxTrashcanContents = options['maxTrashcanContents'];
75
- if (hasTrashcan) {
76
- if (maxTrashcanContents === undefined) {
77
- maxTrashcanContents = 32;
102
+ let hasCss = options['css'];
103
+ if (hasCss === undefined) {
104
+ hasCss = true;
78
105
  }
79
- } else {
80
- maxTrashcanContents = 0;
81
- }
82
- const rtl = !!options['rtl'];
83
- let horizontalLayout = options['horizontalLayout'];
84
- if (horizontalLayout === undefined) {
85
- horizontalLayout = false;
86
- }
87
- let toolboxAtStart = options['toolboxPosition'];
88
- toolboxAtStart = toolboxAtStart !== 'end';
106
+ let pathToMedia = 'https://blockly-demo.appspot.com/static/media/';
107
+ if (options['media']) {
108
+ pathToMedia = options['media'];
109
+ } else if (options['path']) {
110
+ // 'path' is a deprecated option which has been replaced by 'media'.
111
+ pathToMedia = options['path'] + 'media/';
112
+ }
113
+ let oneBasedIndex;
114
+ if (options['oneBasedIndex'] === undefined) {
115
+ oneBasedIndex = true;
116
+ } else {
117
+ oneBasedIndex = !!options['oneBasedIndex'];
118
+ }
119
+ const renderer = options['renderer'] || 'geras';
89
120
 
90
- /** @type {!toolbox.Position} */
91
- let toolboxPosition;
92
- if (horizontalLayout) {
93
- toolboxPosition =
94
- toolboxAtStart ? toolbox.Position.TOP : toolbox.Position.BOTTOM;
95
- } else {
96
- toolboxPosition = (toolboxAtStart === rtl) ? toolbox.Position.RIGHT :
97
- toolbox.Position.LEFT;
98
- }
121
+ const plugins = options['plugins'] || {};
99
122
 
100
- let hasCss = options['css'];
101
- if (hasCss === undefined) {
102
- hasCss = true;
103
- }
104
- let pathToMedia = 'https://blockly-demo.appspot.com/static/media/';
105
- if (options['media']) {
106
- pathToMedia = options['media'];
107
- } else if (options['path']) {
108
- // 'path' is a deprecated option which has been replaced by 'media'.
109
- pathToMedia = options['path'] + 'media/';
110
- }
111
- let oneBasedIndex;
112
- if (options['oneBasedIndex'] === undefined) {
113
- oneBasedIndex = true;
114
- } else {
115
- oneBasedIndex = !!options['oneBasedIndex'];
123
+ /** @type {boolean} */
124
+ this.RTL = rtl;
125
+ /** @type {boolean} */
126
+ this.oneBasedIndex = oneBasedIndex;
127
+ /** @type {boolean} */
128
+ this.collapse = hasCollapse;
129
+ /** @type {boolean} */
130
+ this.comments = hasComments;
131
+ /** @type {boolean} */
132
+ this.disable = hasDisable;
133
+ /** @type {boolean} */
134
+ this.readOnly = readOnly;
135
+ /** @type {number} */
136
+ this.maxBlocks = options['maxBlocks'] || Infinity;
137
+ /** @type {?Object<string, number>} */
138
+ this.maxInstances = options['maxInstances'];
139
+ /** @type {string} */
140
+ this.pathToMedia = pathToMedia;
141
+ /** @type {boolean} */
142
+ this.hasCategories = hasCategories;
143
+ /** @type {!Options.MoveOptions} */
144
+ this.moveOptions = Options.parseMoveOptions_(options, hasCategories);
145
+ /** @deprecated January 2019 */
146
+ this.hasScrollbars = !!this.moveOptions.scrollbars;
147
+ /** @type {boolean} */
148
+ this.hasTrashcan = hasTrashcan;
149
+ /** @type {number} */
150
+ this.maxTrashcanContents = maxTrashcanContents;
151
+ /** @type {boolean} */
152
+ this.hasSounds = hasSounds;
153
+ /** @type {boolean} */
154
+ this.hasCss = hasCss;
155
+ /** @type {boolean} */
156
+ this.horizontalLayout = horizontalLayout;
157
+ /** @type {?toolbox.ToolboxInfo} */
158
+ this.languageTree = toolboxJsonDef;
159
+ /** @type {!Options.GridOptions} */
160
+ this.gridOptions = Options.parseGridOptions_(options);
161
+ /** @type {!Options.ZoomOptions} */
162
+ this.zoomOptions = Options.parseZoomOptions_(options);
163
+ /** @type {!toolbox.Position} */
164
+ this.toolboxPosition = toolboxPosition;
165
+ /** @type {!Theme} */
166
+ this.theme = Options.parseThemeOptions_(options);
167
+ /** @type {string} */
168
+ this.renderer = renderer;
169
+ /** @type {?Object} */
170
+ this.rendererOverrides = options['rendererOverrides'];
171
+
172
+ /**
173
+ * The SVG element for the grid pattern.
174
+ * Created during injection.
175
+ * @type {?SVGElement}
176
+ */
177
+ this.gridPattern = null;
178
+
179
+ /**
180
+ * The parent of the current workspace, or null if there is no parent
181
+ * workspace. We can assert that this is of type WorkspaceSvg as opposed to
182
+ * Workspace as this is only used in a rendered workspace.
183
+ * @type {?WorkspaceSvg}
184
+ */
185
+ this.parentWorkspace = options['parentWorkspace'];
186
+
187
+ /**
188
+ * Map of plugin type to name of registered plugin or plugin class.
189
+ * @type {!Object<string, (function(new:?, ...?)|string)>}
190
+ */
191
+ this.plugins = plugins;
192
+
193
+ /**
194
+ * If set, sets the translation of the workspace to match the scrollbars.
195
+ * @type {undefined|function(!{x:number,y:number}):void} A function that
196
+ * sets the translation of the workspace to match the scrollbars. The
197
+ * argument Contains an x and/or y property which is a float between 0
198
+ * and 1 specifying the degree of scrolling.
199
+ */
200
+ this.setMetrics = undefined;
201
+
202
+ /**
203
+ * @type {undefined|function():!Metrics} A function that returns a metrics
204
+ * object that describes the current workspace.
205
+ */
206
+ this.getMetrics = undefined;
116
207
  }
117
- const renderer = options['renderer'] || 'geras';
118
208
 
119
- const plugins = options['plugins'] || {};
209
+ /**
210
+ * Parse the user-specified move options, using reasonable defaults where
211
+ * behaviour is unspecified.
212
+ * @param {!Object} options Dictionary of options.
213
+ * @param {boolean} hasCategories Whether the workspace has categories or not.
214
+ * @return {!Options.MoveOptions} Normalized move options.
215
+ * @private
216
+ */
217
+ static parseMoveOptions_(options, hasCategories) {
218
+ const move = options['move'] || {};
219
+ const moveOptions = {};
220
+ if (move['scrollbars'] === undefined &&
221
+ options['scrollbars'] === undefined) {
222
+ moveOptions.scrollbars = hasCategories;
223
+ } else if (typeof move['scrollbars'] === 'object') {
224
+ moveOptions.scrollbars = {};
225
+ moveOptions.scrollbars.horizontal = !!move['scrollbars']['horizontal'];
226
+ moveOptions.scrollbars.vertical = !!move['scrollbars']['vertical'];
227
+ // Convert scrollbars object to boolean if they have the same value.
228
+ // This allows us to easily check for whether any scrollbars exist using
229
+ // !!moveOptions.scrollbars.
230
+ if (moveOptions.scrollbars.horizontal &&
231
+ moveOptions.scrollbars.vertical) {
232
+ moveOptions.scrollbars = true;
233
+ } else if (
234
+ !moveOptions.scrollbars.horizontal &&
235
+ !moveOptions.scrollbars.vertical) {
236
+ moveOptions.scrollbars = false;
237
+ }
238
+ } else {
239
+ moveOptions.scrollbars = !!move['scrollbars'] || !!options['scrollbars'];
240
+ }
120
241
 
121
- /** @type {boolean} */
122
- this.RTL = rtl;
123
- /** @type {boolean} */
124
- this.oneBasedIndex = oneBasedIndex;
125
- /** @type {boolean} */
126
- this.collapse = hasCollapse;
127
- /** @type {boolean} */
128
- this.comments = hasComments;
129
- /** @type {boolean} */
130
- this.disable = hasDisable;
131
- /** @type {boolean} */
132
- this.readOnly = readOnly;
133
- /** @type {number} */
134
- this.maxBlocks = options['maxBlocks'] || Infinity;
135
- /** @type {?Object<string, number>} */
136
- this.maxInstances = options['maxInstances'];
137
- /** @type {string} */
138
- this.pathToMedia = pathToMedia;
139
- /** @type {boolean} */
140
- this.hasCategories = hasCategories;
141
- /** @type {!Options.MoveOptions} */
142
- this.moveOptions = Options.parseMoveOptions_(options, hasCategories);
143
- /** @deprecated January 2019 */
144
- this.hasScrollbars = !!this.moveOptions.scrollbars;
145
- /** @type {boolean} */
146
- this.hasTrashcan = hasTrashcan;
147
- /** @type {number} */
148
- this.maxTrashcanContents = maxTrashcanContents;
149
- /** @type {boolean} */
150
- this.hasSounds = hasSounds;
151
- /** @type {boolean} */
152
- this.hasCss = hasCss;
153
- /** @type {boolean} */
154
- this.horizontalLayout = horizontalLayout;
155
- /** @type {?toolbox.ToolboxInfo} */
156
- this.languageTree = toolboxJsonDef;
157
- /** @type {!Options.GridOptions} */
158
- this.gridOptions = Options.parseGridOptions_(options);
159
- /** @type {!Options.ZoomOptions} */
160
- this.zoomOptions = Options.parseZoomOptions_(options);
161
- /** @type {!toolbox.Position} */
162
- this.toolboxPosition = toolboxPosition;
163
- /** @type {!Theme} */
164
- this.theme = Options.parseThemeOptions_(options);
165
- /** @type {string} */
166
- this.renderer = renderer;
167
- /** @type {?Object} */
168
- this.rendererOverrides = options['rendererOverrides'];
242
+ if (!moveOptions.scrollbars || move['wheel'] === undefined) {
243
+ // Defaults to true if single-direction scroll is enabled.
244
+ moveOptions.wheel = typeof moveOptions.scrollbars === 'object';
245
+ } else {
246
+ moveOptions.wheel = !!move['wheel'];
247
+ }
248
+ if (!moveOptions.scrollbars) {
249
+ moveOptions.drag = false;
250
+ } else if (move['drag'] === undefined) {
251
+ // Defaults to true if scrollbars is true.
252
+ moveOptions.drag = true;
253
+ } else {
254
+ moveOptions.drag = !!move['drag'];
255
+ }
256
+ return moveOptions;
257
+ }
169
258
 
170
259
  /**
171
- * The SVG element for the grid pattern.
172
- * Created during injection.
173
- * @type {?SVGElement}
260
+ * Parse the user-specified zoom options, using reasonable defaults where
261
+ * behaviour is unspecified. See zoom documentation:
262
+ * https://developers.google.com/blockly/guides/configure/web/zoom
263
+ * @param {!Object} options Dictionary of options.
264
+ * @return {!Options.ZoomOptions} Normalized zoom options.
265
+ * @private
174
266
  */
175
- this.gridPattern = null;
267
+ static parseZoomOptions_(options) {
268
+ const zoom = options['zoom'] || {};
269
+ const zoomOptions = {};
270
+ if (zoom['controls'] === undefined) {
271
+ zoomOptions.controls = false;
272
+ } else {
273
+ zoomOptions.controls = !!zoom['controls'];
274
+ }
275
+ if (zoom['wheel'] === undefined) {
276
+ zoomOptions.wheel = false;
277
+ } else {
278
+ zoomOptions.wheel = !!zoom['wheel'];
279
+ }
280
+ if (zoom['startScale'] === undefined) {
281
+ zoomOptions.startScale = 1;
282
+ } else {
283
+ zoomOptions.startScale = Number(zoom['startScale']);
284
+ }
285
+ if (zoom['maxScale'] === undefined) {
286
+ zoomOptions.maxScale = 3;
287
+ } else {
288
+ zoomOptions.maxScale = Number(zoom['maxScale']);
289
+ }
290
+ if (zoom['minScale'] === undefined) {
291
+ zoomOptions.minScale = 0.3;
292
+ } else {
293
+ zoomOptions.minScale = Number(zoom['minScale']);
294
+ }
295
+ if (zoom['scaleSpeed'] === undefined) {
296
+ zoomOptions.scaleSpeed = 1.2;
297
+ } else {
298
+ zoomOptions.scaleSpeed = Number(zoom['scaleSpeed']);
299
+ }
300
+ if (zoom['pinch'] === undefined) {
301
+ zoomOptions.pinch = zoomOptions.wheel || zoomOptions.controls;
302
+ } else {
303
+ zoomOptions.pinch = !!zoom['pinch'];
304
+ }
305
+ return zoomOptions;
306
+ }
176
307
 
177
308
  /**
178
- * The parent of the current workspace, or null if there is no parent
179
- * workspace. We can assert that this is of type WorkspaceSvg as opposed to
180
- * Workspace as this is only used in a rendered workspace.
181
- * @type {WorkspaceSvg}
309
+ * Parse the user-specified grid options, using reasonable defaults where
310
+ * behaviour is unspecified. See grid documentation:
311
+ * https://developers.google.com/blockly/guides/configure/web/grid
312
+ * @param {!Object} options Dictionary of options.
313
+ * @return {!Options.GridOptions} Normalized grid options.
314
+ * @private
182
315
  */
183
- this.parentWorkspace = options['parentWorkspace'];
316
+ static parseGridOptions_(options) {
317
+ const grid = options['grid'] || {};
318
+ const gridOptions = {};
319
+ gridOptions.spacing = Number(grid['spacing']) || 0;
320
+ gridOptions.colour = grid['colour'] || '#888';
321
+ gridOptions.length =
322
+ (grid['length'] === undefined) ? 1 : Number(grid['length']);
323
+ gridOptions.snap = gridOptions.spacing > 0 && !!grid['snap'];
324
+ return gridOptions;
325
+ }
184
326
 
185
327
  /**
186
- * Map of plugin type to name of registered plugin or plugin class.
187
- * @type {!Object<string, (function(new:?, ...?)|string)>}
328
+ * Parse the user-specified theme options, using the classic theme as a
329
+ * default. https://developers.google.com/blockly/guides/configure/web/themes
330
+ * @param {!Object} options Dictionary of options.
331
+ * @return {!Theme} A Blockly Theme.
332
+ * @private
188
333
  */
189
- this.plugins = plugins;
190
- };
334
+ static parseThemeOptions_(options) {
335
+ const theme = options['theme'] || Classic;
336
+ if (typeof theme === 'string') {
337
+ return /** @type {!Theme} */ (
338
+ registry.getObject(registry.Type.THEME, theme));
339
+ } else if (theme instanceof Theme) {
340
+ return /** @type {!Theme} */ (theme);
341
+ }
342
+ return Theme.defineTheme(
343
+ theme.name || ('builtin' + idGenerator.getNextUniqueId()), theme);
344
+ }
345
+ }
191
346
 
192
347
  /**
193
348
  * Grid Options.
@@ -233,153 +388,4 @@ Options.ScrollbarOptions;
233
388
  */
234
389
  Options.ZoomOptions;
235
390
 
236
- /**
237
- * If set, sets the translation of the workspace to match the scrollbars.
238
- * @param {!{x:number,y:number}} xyRatio Contains an x and/or y property which
239
- * is a float between 0 and 1 specifying the degree of scrolling.
240
- * @return {void}
241
- */
242
- Options.prototype.setMetrics;
243
-
244
- /**
245
- * Return an object with the metrics required to size the workspace.
246
- * @return {!Metrics} Contains size and position metrics.
247
- */
248
- Options.prototype.getMetrics;
249
-
250
- /**
251
- * Parse the user-specified move options, using reasonable defaults where
252
- * behaviour is unspecified.
253
- * @param {!Object} options Dictionary of options.
254
- * @param {boolean} hasCategories Whether the workspace has categories or not.
255
- * @return {!Options.MoveOptions} Normalized move options.
256
- * @private
257
- */
258
- Options.parseMoveOptions_ = function(options, hasCategories) {
259
- const move = options['move'] || {};
260
- const moveOptions = {};
261
- if (move['scrollbars'] === undefined && options['scrollbars'] === undefined) {
262
- moveOptions.scrollbars = hasCategories;
263
- } else if (typeof move['scrollbars'] === 'object') {
264
- moveOptions.scrollbars = {};
265
- moveOptions.scrollbars.horizontal = !!move['scrollbars']['horizontal'];
266
- moveOptions.scrollbars.vertical = !!move['scrollbars']['vertical'];
267
- // Convert scrollbars object to boolean if they have the same value.
268
- // This allows us to easily check for whether any scrollbars exist using
269
- // !!moveOptions.scrollbars.
270
- if (moveOptions.scrollbars.horizontal && moveOptions.scrollbars.vertical) {
271
- moveOptions.scrollbars = true;
272
- } else if (
273
- !moveOptions.scrollbars.horizontal &&
274
- !moveOptions.scrollbars.vertical) {
275
- moveOptions.scrollbars = false;
276
- }
277
- } else {
278
- moveOptions.scrollbars = !!move['scrollbars'] || !!options['scrollbars'];
279
- }
280
-
281
- if (!moveOptions.scrollbars || move['wheel'] === undefined) {
282
- // Defaults to true if single-direction scroll is enabled.
283
- moveOptions.wheel = typeof moveOptions.scrollbars === 'object';
284
- } else {
285
- moveOptions.wheel = !!move['wheel'];
286
- }
287
- if (!moveOptions.scrollbars) {
288
- moveOptions.drag = false;
289
- } else if (move['drag'] === undefined) {
290
- // Defaults to true if scrollbars is true.
291
- moveOptions.drag = true;
292
- } else {
293
- moveOptions.drag = !!move['drag'];
294
- }
295
- return moveOptions;
296
- };
297
-
298
- /**
299
- * Parse the user-specified zoom options, using reasonable defaults where
300
- * behaviour is unspecified. See zoom documentation:
301
- * https://developers.google.com/blockly/guides/configure/web/zoom
302
- * @param {!Object} options Dictionary of options.
303
- * @return {!Options.ZoomOptions} Normalized zoom options.
304
- * @private
305
- */
306
- Options.parseZoomOptions_ = function(options) {
307
- const zoom = options['zoom'] || {};
308
- const zoomOptions = {};
309
- if (zoom['controls'] === undefined) {
310
- zoomOptions.controls = false;
311
- } else {
312
- zoomOptions.controls = !!zoom['controls'];
313
- }
314
- if (zoom['wheel'] === undefined) {
315
- zoomOptions.wheel = false;
316
- } else {
317
- zoomOptions.wheel = !!zoom['wheel'];
318
- }
319
- if (zoom['startScale'] === undefined) {
320
- zoomOptions.startScale = 1;
321
- } else {
322
- zoomOptions.startScale = Number(zoom['startScale']);
323
- }
324
- if (zoom['maxScale'] === undefined) {
325
- zoomOptions.maxScale = 3;
326
- } else {
327
- zoomOptions.maxScale = Number(zoom['maxScale']);
328
- }
329
- if (zoom['minScale'] === undefined) {
330
- zoomOptions.minScale = 0.3;
331
- } else {
332
- zoomOptions.minScale = Number(zoom['minScale']);
333
- }
334
- if (zoom['scaleSpeed'] === undefined) {
335
- zoomOptions.scaleSpeed = 1.2;
336
- } else {
337
- zoomOptions.scaleSpeed = Number(zoom['scaleSpeed']);
338
- }
339
- if (zoom['pinch'] === undefined) {
340
- zoomOptions.pinch = zoomOptions.wheel || zoomOptions.controls;
341
- } else {
342
- zoomOptions.pinch = !!zoom['pinch'];
343
- }
344
- return zoomOptions;
345
- };
346
-
347
- /**
348
- * Parse the user-specified grid options, using reasonable defaults where
349
- * behaviour is unspecified. See grid documentation:
350
- * https://developers.google.com/blockly/guides/configure/web/grid
351
- * @param {!Object} options Dictionary of options.
352
- * @return {!Options.GridOptions} Normalized grid options.
353
- * @private
354
- */
355
- Options.parseGridOptions_ = function(options) {
356
- const grid = options['grid'] || {};
357
- const gridOptions = {};
358
- gridOptions.spacing = Number(grid['spacing']) || 0;
359
- gridOptions.colour = grid['colour'] || '#888';
360
- gridOptions.length =
361
- (grid['length'] === undefined) ? 1 : Number(grid['length']);
362
- gridOptions.snap = gridOptions.spacing > 0 && !!grid['snap'];
363
- return gridOptions;
364
- };
365
-
366
- /**
367
- * Parse the user-specified theme options, using the classic theme as a default.
368
- * https://developers.google.com/blockly/guides/configure/web/themes
369
- * @param {!Object} options Dictionary of options.
370
- * @return {!Theme} A Blockly Theme.
371
- * @private
372
- */
373
- Options.parseThemeOptions_ = function(options) {
374
- const theme = options['theme'] || Classic;
375
- if (typeof theme === 'string') {
376
- return /** @type {!Theme} */ (
377
- registry.getObject(registry.Type.THEME, theme));
378
- } else if (theme instanceof Theme) {
379
- return /** @type {!Theme} */ (theme);
380
- }
381
- return Theme.defineTheme(
382
- theme.name || ('builtin' + idGenerator.getNextUniqueId()), theme);
383
- };
384
-
385
391
  exports.Options = Options;