@wordpress/block-editor 11.0.0 → 11.1.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 (326) hide show
  1. package/CHANGELOG.md +9 -1
  2. package/README.md +2 -1
  3. package/build/components/alignment-control/ui.js +1 -7
  4. package/build/components/alignment-control/ui.js.map +1 -1
  5. package/build/components/block-alignment-control/use-available-alignments.js +4 -3
  6. package/build/components/block-alignment-control/use-available-alignments.js.map +1 -1
  7. package/build/components/block-icon/index.js +4 -2
  8. package/build/components/block-icon/index.js.map +1 -1
  9. package/build/components/block-inspector/index.js +55 -4
  10. package/build/components/block-inspector/index.js.map +1 -1
  11. package/build/components/block-list-appender/index.js +46 -34
  12. package/build/components/block-list-appender/index.js.map +1 -1
  13. package/build/components/block-list-appender/index.native.js +39 -34
  14. package/build/components/block-list-appender/index.native.js.map +1 -1
  15. package/build/components/block-mobile-toolbar/block-actions-menu.native.js +18 -18
  16. package/build/components/block-mobile-toolbar/block-actions-menu.native.js.map +1 -1
  17. package/build/components/block-mobile-toolbar/index.native.js +1 -1
  18. package/build/components/block-mobile-toolbar/index.native.js.map +1 -1
  19. package/build/components/block-pattern-setup/index.js +14 -7
  20. package/build/components/block-pattern-setup/index.js.map +1 -1
  21. package/build/components/block-styles/index.native.js +1 -3
  22. package/build/components/block-styles/index.native.js.map +1 -1
  23. package/build/components/block-styles/utils.js +7 -10
  24. package/build/components/block-styles/utils.js.map +1 -1
  25. package/build/components/block-toolbar/index.native.js +6 -8
  26. package/build/components/block-toolbar/index.native.js.map +1 -1
  27. package/build/components/block-tools/selected-block-popover.js +1 -3
  28. package/build/components/block-tools/selected-block-popover.js.map +1 -1
  29. package/build/components/block-variation-picker/index.js +1 -1
  30. package/build/components/block-variation-picker/index.js.map +1 -1
  31. package/build/components/colors/utils.js +2 -6
  32. package/build/components/colors/utils.js.map +1 -1
  33. package/build/components/colors-gradients/control.js +0 -3
  34. package/build/components/colors-gradients/control.js.map +1 -1
  35. package/build/components/colors-gradients/dropdown.js +0 -2
  36. package/build/components/colors-gradients/dropdown.js.map +1 -1
  37. package/build/components/colors-gradients/panel-color-gradient-settings.js +2 -19
  38. package/build/components/colors-gradients/panel-color-gradient-settings.js.map +1 -1
  39. package/build/components/colors-gradients/use-multiple-origin-colors-and-gradients.js +4 -3
  40. package/build/components/colors-gradients/use-multiple-origin-colors-and-gradients.js.map +1 -1
  41. package/build/components/copy-handler/index.js +37 -9
  42. package/build/components/copy-handler/index.js.map +1 -1
  43. package/build/components/font-sizes/fluid-utils.js +5 -2
  44. package/build/components/font-sizes/fluid-utils.js.map +1 -1
  45. package/build/components/font-sizes/utils.js +10 -4
  46. package/build/components/font-sizes/utils.js.map +1 -1
  47. package/build/components/font-sizes/with-font-sizes.js +11 -6
  48. package/build/components/font-sizes/with-font-sizes.js.map +1 -1
  49. package/build/components/gradients/use-gradient.js +2 -8
  50. package/build/components/gradients/use-gradient.js.map +1 -1
  51. package/build/components/iframe/index.js +13 -95
  52. package/build/components/iframe/index.js.map +1 -1
  53. package/build/components/iframe/use-compatibility-styles.js +93 -0
  54. package/build/components/iframe/use-compatibility-styles.js.map +1 -0
  55. package/build/components/inner-blocks/index.js +6 -2
  56. package/build/components/inner-blocks/index.js.map +1 -1
  57. package/build/components/inserter/hooks/use-insertion-point.js +4 -3
  58. package/build/components/inserter/hooks/use-insertion-point.js.map +1 -1
  59. package/build/components/inserter/index.js +13 -4
  60. package/build/components/inserter/index.js.map +1 -1
  61. package/build/components/inserter/media-tab/hooks.js +8 -5
  62. package/build/components/inserter/media-tab/hooks.js.map +1 -1
  63. package/build/components/inserter/quick-inserter.js +6 -3
  64. package/build/components/inserter/quick-inserter.js.map +1 -1
  65. package/build/components/inserter/search-items.js +15 -14
  66. package/build/components/inserter/search-items.js.map +1 -1
  67. package/build/components/inserter/search-results.js +4 -2
  68. package/build/components/inserter/search-results.js.map +1 -1
  69. package/build/components/list-view/block-select-button.js +1 -1
  70. package/build/components/list-view/block-select-button.js.map +1 -1
  71. package/build/components/off-canvas-editor/appender.js +21 -26
  72. package/build/components/off-canvas-editor/appender.js.map +1 -1
  73. package/build/components/off-canvas-editor/block-select-button.js +3 -2
  74. package/build/components/off-canvas-editor/block-select-button.js.map +1 -1
  75. package/build/components/off-canvas-editor/block.js +57 -45
  76. package/build/components/off-canvas-editor/block.js.map +1 -1
  77. package/build/components/off-canvas-editor/index.js +5 -1
  78. package/build/components/off-canvas-editor/index.js.map +1 -1
  79. package/build/components/off-canvas-editor/use-inserted-block.js +58 -0
  80. package/build/components/off-canvas-editor/use-inserted-block.js.map +1 -0
  81. package/build/components/responsive-block-control/label.js.map +1 -1
  82. package/build/components/rich-text/format-edit.js +12 -10
  83. package/build/components/rich-text/format-edit.js.map +1 -1
  84. package/build/components/rich-text/index.js.map +1 -1
  85. package/build/components/rich-text/use-paste-handler.js +21 -12
  86. package/build/components/rich-text/use-paste-handler.js.map +1 -1
  87. package/build/components/spacing-sizes-control/index.js +0 -1
  88. package/build/components/spacing-sizes-control/index.js.map +1 -1
  89. package/build/components/spacing-sizes-control/utils.js +1 -1
  90. package/build/components/spacing-sizes-control/utils.js.map +1 -1
  91. package/build/components/typewriter/index.js +1 -1
  92. package/build/components/typewriter/index.js.map +1 -1
  93. package/build/components/url-popover/image-url-input-ui.js +2 -2
  94. package/build/components/url-popover/image-url-input-ui.js.map +1 -1
  95. package/build/components/writing-flow/index.js +1 -1
  96. package/build/components/writing-flow/index.js.map +1 -1
  97. package/build/hooks/border.js +0 -1
  98. package/build/hooks/border.js.map +1 -1
  99. package/build/hooks/color-panel.js +0 -1
  100. package/build/hooks/color-panel.js.map +1 -1
  101. package/build/hooks/color.js +1 -2
  102. package/build/hooks/color.js.map +1 -1
  103. package/build/hooks/font-family.js +4 -4
  104. package/build/hooks/font-family.js.map +1 -1
  105. package/build/hooks/font-size.js +5 -3
  106. package/build/hooks/font-size.js.map +1 -1
  107. package/build/hooks/use-typography-props.js +11 -8
  108. package/build/hooks/use-typography-props.js.map +1 -1
  109. package/build/store/reducer.js +21 -7
  110. package/build/store/reducer.js.map +1 -1
  111. package/build/store/selectors.js +1 -1
  112. package/build/store/selectors.js.map +1 -1
  113. package/build/utils/pasting.js +6 -11
  114. package/build/utils/pasting.js.map +1 -1
  115. package/build-module/components/alignment-control/ui.js +1 -6
  116. package/build-module/components/alignment-control/ui.js.map +1 -1
  117. package/build-module/components/block-alignment-control/use-available-alignments.js +4 -3
  118. package/build-module/components/block-alignment-control/use-available-alignments.js.map +1 -1
  119. package/build-module/components/block-icon/index.js +4 -2
  120. package/build-module/components/block-icon/index.js.map +1 -1
  121. package/build-module/components/block-inspector/index.js +56 -5
  122. package/build-module/components/block-inspector/index.js.map +1 -1
  123. package/build-module/components/block-list-appender/index.js +46 -34
  124. package/build-module/components/block-list-appender/index.js.map +1 -1
  125. package/build-module/components/block-list-appender/index.native.js +39 -32
  126. package/build-module/components/block-list-appender/index.native.js.map +1 -1
  127. package/build-module/components/block-mobile-toolbar/block-actions-menu.native.js +18 -18
  128. package/build-module/components/block-mobile-toolbar/block-actions-menu.native.js.map +1 -1
  129. package/build-module/components/block-mobile-toolbar/index.native.js +1 -1
  130. package/build-module/components/block-mobile-toolbar/index.native.js.map +1 -1
  131. package/build-module/components/block-pattern-setup/index.js +14 -7
  132. package/build-module/components/block-pattern-setup/index.js.map +1 -1
  133. package/build-module/components/block-styles/index.native.js +1 -2
  134. package/build-module/components/block-styles/index.native.js.map +1 -1
  135. package/build-module/components/block-styles/utils.js +7 -9
  136. package/build-module/components/block-styles/utils.js.map +1 -1
  137. package/build-module/components/block-toolbar/index.native.js +6 -8
  138. package/build-module/components/block-toolbar/index.native.js.map +1 -1
  139. package/build-module/components/block-tools/selected-block-popover.js +1 -2
  140. package/build-module/components/block-tools/selected-block-popover.js.map +1 -1
  141. package/build-module/components/block-variation-picker/index.js +1 -1
  142. package/build-module/components/block-variation-picker/index.js.map +1 -1
  143. package/build-module/components/colors/utils.js +3 -7
  144. package/build-module/components/colors/utils.js.map +1 -1
  145. package/build-module/components/colors-gradients/control.js +0 -3
  146. package/build-module/components/colors-gradients/control.js.map +1 -1
  147. package/build-module/components/colors-gradients/dropdown.js +0 -2
  148. package/build-module/components/colors-gradients/dropdown.js.map +1 -1
  149. package/build-module/components/colors-gradients/panel-color-gradient-settings.js +4 -19
  150. package/build-module/components/colors-gradients/panel-color-gradient-settings.js.map +1 -1
  151. package/build-module/components/colors-gradients/use-multiple-origin-colors-and-gradients.js +4 -2
  152. package/build-module/components/colors-gradients/use-multiple-origin-colors-and-gradients.js.map +1 -1
  153. package/build-module/components/copy-handler/index.js +38 -10
  154. package/build-module/components/copy-handler/index.js.map +1 -1
  155. package/build-module/components/font-sizes/fluid-utils.js +5 -2
  156. package/build-module/components/font-sizes/fluid-utils.js.map +1 -1
  157. package/build-module/components/font-sizes/utils.js +11 -5
  158. package/build-module/components/font-sizes/utils.js.map +1 -1
  159. package/build-module/components/font-sizes/with-font-sizes.js +12 -7
  160. package/build-module/components/font-sizes/with-font-sizes.js.map +1 -1
  161. package/build-module/components/gradients/use-gradient.js +2 -7
  162. package/build-module/components/gradients/use-gradient.js.map +1 -1
  163. package/build-module/components/iframe/index.js +12 -95
  164. package/build-module/components/iframe/index.js.map +1 -1
  165. package/build-module/components/iframe/use-compatibility-styles.js +85 -0
  166. package/build-module/components/iframe/use-compatibility-styles.js.map +1 -0
  167. package/build-module/components/inner-blocks/index.js +6 -2
  168. package/build-module/components/inner-blocks/index.js.map +1 -1
  169. package/build-module/components/inserter/hooks/use-insertion-point.js +4 -3
  170. package/build-module/components/inserter/hooks/use-insertion-point.js.map +1 -1
  171. package/build-module/components/inserter/index.js +13 -4
  172. package/build-module/components/inserter/index.js.map +1 -1
  173. package/build-module/components/inserter/media-tab/hooks.js +8 -5
  174. package/build-module/components/inserter/media-tab/hooks.js.map +1 -1
  175. package/build-module/components/inserter/quick-inserter.js +6 -3
  176. package/build-module/components/inserter/quick-inserter.js.map +1 -1
  177. package/build-module/components/inserter/search-items.js +15 -13
  178. package/build-module/components/inserter/search-items.js.map +1 -1
  179. package/build-module/components/inserter/search-results.js +4 -2
  180. package/build-module/components/inserter/search-results.js.map +1 -1
  181. package/build-module/components/list-view/block-select-button.js +1 -1
  182. package/build-module/components/list-view/block-select-button.js.map +1 -1
  183. package/build-module/components/off-canvas-editor/appender.js +21 -27
  184. package/build-module/components/off-canvas-editor/appender.js.map +1 -1
  185. package/build-module/components/off-canvas-editor/block-select-button.js +3 -2
  186. package/build-module/components/off-canvas-editor/block-select-button.js.map +1 -1
  187. package/build-module/components/off-canvas-editor/block.js +58 -46
  188. package/build-module/components/off-canvas-editor/block.js.map +1 -1
  189. package/build-module/components/off-canvas-editor/index.js +5 -1
  190. package/build-module/components/off-canvas-editor/index.js.map +1 -1
  191. package/build-module/components/off-canvas-editor/use-inserted-block.js +47 -0
  192. package/build-module/components/off-canvas-editor/use-inserted-block.js.map +1 -0
  193. package/build-module/components/responsive-block-control/label.js +1 -2
  194. package/build-module/components/responsive-block-control/label.js.map +1 -1
  195. package/build-module/components/rich-text/format-edit.js +12 -9
  196. package/build-module/components/rich-text/format-edit.js.map +1 -1
  197. package/build-module/components/rich-text/index.js.map +1 -1
  198. package/build-module/components/rich-text/use-paste-handler.js +22 -12
  199. package/build-module/components/rich-text/use-paste-handler.js.map +1 -1
  200. package/build-module/components/spacing-sizes-control/index.js +0 -1
  201. package/build-module/components/spacing-sizes-control/index.js.map +1 -1
  202. package/build-module/components/spacing-sizes-control/utils.js +1 -1
  203. package/build-module/components/spacing-sizes-control/utils.js.map +1 -1
  204. package/build-module/components/typewriter/index.js +1 -1
  205. package/build-module/components/typewriter/index.js.map +1 -1
  206. package/build-module/components/url-popover/image-url-input-ui.js +3 -3
  207. package/build-module/components/url-popover/image-url-input-ui.js.map +1 -1
  208. package/build-module/components/writing-flow/index.js +1 -1
  209. package/build-module/components/writing-flow/index.js.map +1 -1
  210. package/build-module/hooks/border.js +0 -1
  211. package/build-module/hooks/border.js.map +1 -1
  212. package/build-module/hooks/color-panel.js +0 -1
  213. package/build-module/hooks/color-panel.js.map +1 -1
  214. package/build-module/hooks/color.js +1 -2
  215. package/build-module/hooks/color.js.map +1 -1
  216. package/build-module/hooks/font-family.js +5 -5
  217. package/build-module/hooks/font-family.js.map +1 -1
  218. package/build-module/hooks/font-size.js +5 -3
  219. package/build-module/hooks/font-size.js.map +1 -1
  220. package/build-module/hooks/use-typography-props.js +11 -8
  221. package/build-module/hooks/use-typography-props.js.map +1 -1
  222. package/build-module/store/reducer.js +21 -6
  223. package/build-module/store/reducer.js.map +1 -1
  224. package/build-module/store/selectors.js +2 -2
  225. package/build-module/store/selectors.js.map +1 -1
  226. package/build-module/utils/pasting.js +6 -10
  227. package/build-module/utils/pasting.js.map +1 -1
  228. package/build-style/content-rtl.css +3 -3
  229. package/build-style/content.css +3 -3
  230. package/build-style/default-editor-styles-rtl.css +3 -3
  231. package/build-style/default-editor-styles.css +3 -3
  232. package/build-style/style-rtl.css +35 -11
  233. package/build-style/style.css +35 -11
  234. package/package.json +29 -29
  235. package/src/components/alignment-control/test/index.js +2 -0
  236. package/src/components/alignment-control/ui.js +1 -7
  237. package/src/components/block-alignment-control/test/index.js +2 -0
  238. package/src/components/block-alignment-control/use-available-alignments.js +4 -3
  239. package/src/components/block-icon/index.js +4 -2
  240. package/src/components/block-icon/test/index.js +9 -5
  241. package/src/components/block-inspector/index.js +77 -4
  242. package/src/components/block-inspector/style.scss +7 -0
  243. package/src/components/block-list-appender/index.js +65 -54
  244. package/src/components/block-list-appender/index.native.js +45 -34
  245. package/src/components/block-mobile-toolbar/block-actions-menu.native.js +18 -22
  246. package/src/components/block-mobile-toolbar/index.native.js +1 -1
  247. package/src/components/block-mobile-toolbar/test/__snapshots__/block-actions-menu.native.js.snap +125 -0
  248. package/src/components/block-mobile-toolbar/test/block-actions-menu.native.js +439 -0
  249. package/src/components/block-mover/test/__snapshots__/index.native.js.snap +42 -0
  250. package/src/components/block-mover/test/index.native.js +157 -1
  251. package/src/components/block-pattern-setup/index.js +15 -6
  252. package/src/components/block-pattern-setup/style.scss +29 -1
  253. package/src/components/block-styles/index.native.js +1 -2
  254. package/src/components/block-styles/utils.js +5 -7
  255. package/src/components/block-switcher/test/index.js +3 -2
  256. package/src/components/block-toolbar/index.native.js +8 -11
  257. package/src/components/block-tools/selected-block-popover.js +1 -3
  258. package/src/components/block-variation-picker/index.js +5 -1
  259. package/src/components/block-vertical-alignment-control/test/index.js +2 -0
  260. package/src/components/colors/test/with-colors.js +2 -0
  261. package/src/components/colors/utils.js +5 -3
  262. package/src/components/colors-gradients/control.js +0 -7
  263. package/src/components/colors-gradients/dropdown.js +0 -2
  264. package/src/components/colors-gradients/panel-color-gradient-settings.js +4 -22
  265. package/src/components/colors-gradients/use-multiple-origin-colors-and-gradients.js +4 -2
  266. package/src/components/copy-handler/index.js +53 -7
  267. package/src/components/default-block-appender/test/index.js +2 -0
  268. package/src/components/font-sizes/fluid-utils.js +7 -1
  269. package/src/components/font-sizes/utils.js +5 -3
  270. package/src/components/font-sizes/with-font-sizes.js +4 -4
  271. package/src/components/gradients/use-gradient.js +2 -7
  272. package/src/components/iframe/index.js +8 -103
  273. package/src/components/iframe/use-compatibility-styles.js +95 -0
  274. package/src/components/image-size-control/test/index.js +147 -79
  275. package/src/components/inner-blocks/index.js +4 -2
  276. package/src/components/inserter/hooks/use-insertion-point.js +3 -2
  277. package/src/components/inserter/index.js +15 -2
  278. package/src/components/inserter/media-tab/hooks.js +5 -4
  279. package/src/components/inserter/quick-inserter.js +3 -0
  280. package/src/components/inserter/search-items.js +1 -2
  281. package/src/components/inserter/search-results.js +2 -0
  282. package/src/components/link-control/test/index.js +18 -4
  283. package/src/components/list-view/block-select-button.js +1 -1
  284. package/src/components/list-view/style.scss +1 -7
  285. package/src/components/media-replace-flow/test/index.js +2 -0
  286. package/src/components/off-canvas-editor/appender.js +30 -25
  287. package/src/components/off-canvas-editor/block-select-button.js +6 -2
  288. package/src/components/off-canvas-editor/block.js +93 -76
  289. package/src/components/off-canvas-editor/index.js +9 -0
  290. package/src/components/off-canvas-editor/style.scss +5 -1
  291. package/src/components/off-canvas-editor/test/use-inserted-block.js +108 -0
  292. package/src/components/off-canvas-editor/use-inserted-block.js +47 -0
  293. package/src/components/responsive-block-control/label.js +2 -3
  294. package/src/components/responsive-block-control/test/index.js +4 -2
  295. package/src/components/rich-text/format-edit.js +6 -10
  296. package/src/components/rich-text/index.js +1 -0
  297. package/src/components/rich-text/use-paste-handler.js +33 -14
  298. package/src/components/spacing-sizes-control/index.js +0 -1
  299. package/src/components/spacing-sizes-control/utils.js +1 -1
  300. package/src/components/typewriter/index.js +3 -1
  301. package/src/components/url-input/test/button.js +2 -0
  302. package/src/components/url-popover/image-url-input-ui.js +5 -4
  303. package/src/components/url-popover/test/index.js +21 -5
  304. package/src/components/warning/test/index.js +2 -0
  305. package/src/components/writing-flow/index.js +1 -1
  306. package/src/hooks/border.js +0 -1
  307. package/src/hooks/color-panel.js +0 -1
  308. package/src/hooks/color.js +0 -2
  309. package/src/hooks/font-family.js +3 -5
  310. package/src/hooks/font-size.js +13 -4
  311. package/src/hooks/test/use-typography-props.js +26 -0
  312. package/src/hooks/use-typography-props.js +15 -7
  313. package/src/store/reducer.js +13 -6
  314. package/src/store/selectors.js +2 -3
  315. package/src/utils/pasting.js +3 -9
  316. package/tsconfig.tsbuildinfo +1 -1
  317. package/build/components/colors-gradients/use-common-single-multiple-selects.js +0 -21
  318. package/build/components/colors-gradients/use-common-single-multiple-selects.js.map +0 -1
  319. package/build/components/rich-text/file-paste-handler.js +0 -21
  320. package/build/components/rich-text/file-paste-handler.js.map +0 -1
  321. package/build-module/components/colors-gradients/use-common-single-multiple-selects.js +0 -11
  322. package/build-module/components/colors-gradients/use-common-single-multiple-selects.js.map +0 -1
  323. package/build-module/components/rich-text/file-paste-handler.js +0 -13
  324. package/build-module/components/rich-text/file-paste-handler.js.map +0 -1
  325. package/src/components/colors-gradients/use-common-single-multiple-selects.js +0 -11
  326. package/src/components/rich-text/file-paste-handler.js +0 -13
@@ -26,97 +26,7 @@ import { __experimentalStyleProvider as StyleProvider } from '@wordpress/compone
26
26
  */
27
27
  import { useBlockSelectionClearer } from '../block-selection-clearer';
28
28
  import { useWritingFlow } from '../writing-flow';
29
-
30
- const BODY_CLASS_NAME = 'editor-styles-wrapper';
31
- const BLOCK_PREFIX = 'wp-block';
32
-
33
- /**
34
- * Clones stylesheets targetting the editor canvas to the given document. A
35
- * stylesheet is considered targetting the editor a canvas if it contains the
36
- * `editor-styles-wrapper`, `wp-block`, or `wp-block-*` class selectors.
37
- *
38
- * Ideally, this hook should be removed in the future and styles should be added
39
- * explicitly as editor styles.
40
- */
41
- function useStylesCompatibility() {
42
- return useRefEffect( ( node ) => {
43
- // Search the document for stylesheets targetting the editor canvas.
44
- Array.from( document.styleSheets ).forEach( ( styleSheet ) => {
45
- try {
46
- // May fail for external styles.
47
- // eslint-disable-next-line no-unused-expressions
48
- styleSheet.cssRules;
49
- } catch ( e ) {
50
- return;
51
- }
52
-
53
- const { ownerNode, cssRules } = styleSheet;
54
-
55
- if ( ! cssRules ) {
56
- return;
57
- }
58
-
59
- // Generally, ignore inline styles. We add inline styles belonging to a
60
- // stylesheet later, which may or may not match the selectors.
61
- if ( ownerNode.tagName !== 'LINK' ) {
62
- return;
63
- }
64
-
65
- // Don't try to add the reset styles, which were removed as a dependency
66
- // from `edit-blocks` for the iframe since we don't need to reset admin
67
- // styles.
68
- if ( ownerNode.id === 'wp-reset-editor-styles-css' ) {
69
- return;
70
- }
71
-
72
- function matchFromRules( _cssRules ) {
73
- return Array.from( _cssRules ).find(
74
- ( {
75
- selectorText,
76
- conditionText,
77
- cssRules: __cssRules,
78
- } ) => {
79
- // If the rule is conditional then it will not have selector text.
80
- // Recurse into child CSS ruleset to determine selector eligibility.
81
- if ( conditionText ) {
82
- return matchFromRules( __cssRules );
83
- }
84
-
85
- return (
86
- selectorText &&
87
- ( selectorText.includes(
88
- `.${ BODY_CLASS_NAME }`
89
- ) ||
90
- selectorText.includes( `.${ BLOCK_PREFIX }` ) )
91
- );
92
- }
93
- );
94
- }
95
-
96
- const isMatch = matchFromRules( cssRules );
97
-
98
- if (
99
- isMatch &&
100
- ! node.ownerDocument.getElementById( ownerNode.id )
101
- ) {
102
- // Display warning once we have a way to add style dependencies to the editor.
103
- // See: https://github.com/WordPress/gutenberg/pull/37466.
104
- node.appendChild( ownerNode.cloneNode( true ) );
105
-
106
- // Add inline styles belonging to the stylesheet.
107
- const inlineCssId = ownerNode.id.replace(
108
- '-css',
109
- '-inline-css'
110
- );
111
- const inlineCssElement = document.getElementById( inlineCssId );
112
-
113
- if ( inlineCssElement ) {
114
- node.appendChild( inlineCssElement.cloneNode( true ) );
115
- }
116
- }
117
- } );
118
- }, [] );
119
- }
29
+ import { useCompatibilityStyles } from './use-compatibility-styles';
120
30
 
121
31
  /**
122
32
  * Bubbles some event types (keydown, keypress, and dragover) to parent document
@@ -205,6 +115,11 @@ function Iframe(
205
115
  const [ iframeDocument, setIframeDocument ] = useState();
206
116
  const [ bodyClasses, setBodyClasses ] = useState( [] );
207
117
  const styles = useParsedAssets( assets?.styles );
118
+ const styleIds = styles.map( ( style ) => style.id );
119
+ const compatStyles = useCompatibilityStyles();
120
+ const neededCompatStyles = compatStyles.filter(
121
+ ( style ) => ! styleIds.includes( style.id )
122
+ );
208
123
  const scripts = useParsedAssets( assets?.scripts );
209
124
  const clearerRef = useBlockSelectionClearer();
210
125
  const [ before, writingFlowRef, after ] = useWritingFlow();
@@ -288,12 +203,11 @@ function Iframe(
288
203
  } );
289
204
  }, [] );
290
205
  const bodyRef = useMergeRefs( [ contentRef, clearerRef, writingFlowRef ] );
291
- const styleCompatibilityRef = useStylesCompatibility();
292
206
 
293
207
  head = (
294
208
  <>
295
209
  <style>{ 'html{height:auto!important;}body{margin:0}' }</style>
296
- { styles.map(
210
+ { [ ...styles, ...neededCompatStyles ].map(
297
211
  ( { tagName, href, id, rel, media, textContent } ) => {
298
212
  const TagName = tagName.toLowerCase();
299
213
 
@@ -342,7 +256,7 @@ function Iframe(
342
256
  ref={ bodyRef }
343
257
  className={ classnames(
344
258
  'block-editor-iframe__body',
345
- BODY_CLASS_NAME,
259
+ 'editor-styles-wrapper',
346
260
  ...bodyClasses
347
261
  ) }
348
262
  style={ {
@@ -359,15 +273,6 @@ function Iframe(
359
273
  inert={ readonly ? 'true' : undefined }
360
274
  >
361
275
  { contentResizeListener }
362
- { /*
363
- * This is a wrapper for the extra styles and scripts
364
- * rendered imperatively by cloning the parent,
365
- * it's important that this div's content remains uncontrolled.
366
- */ }
367
- <div
368
- style={ { display: 'none' } }
369
- ref={ styleCompatibilityRef }
370
- />
371
276
  <StyleProvider document={ iframeDocument }>
372
277
  { children }
373
278
  </StyleProvider>
@@ -0,0 +1,95 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { useMemo } from '@wordpress/element';
5
+
6
+ /**
7
+ * Returns a list of stylesheets that target the editor canvas. A stylesheet is
8
+ * considered targetting the editor a canvas if it contains the
9
+ * `editor-styles-wrapper`, `wp-block`, or `wp-block-*` class selectors.
10
+ *
11
+ * Ideally, this hook should be removed in the future and styles should be added
12
+ * explicitly as editor styles.
13
+ */
14
+ export function useCompatibilityStyles() {
15
+ // Only memoize the result once on load, since these stylesheets should not
16
+ // change.
17
+ return useMemo( () => {
18
+ // Search the document for stylesheets targetting the editor canvas.
19
+ return Array.from( document.styleSheets ).reduce(
20
+ ( accumulator, styleSheet ) => {
21
+ try {
22
+ // May fail for external styles.
23
+ // eslint-disable-next-line no-unused-expressions
24
+ styleSheet.cssRules;
25
+ } catch ( e ) {
26
+ return accumulator;
27
+ }
28
+
29
+ const { ownerNode, cssRules } = styleSheet;
30
+
31
+ if ( ! cssRules ) {
32
+ return accumulator;
33
+ }
34
+
35
+ // Generally, ignore inline styles. We add inline styles belonging to a
36
+ // stylesheet later, which may or may not match the selectors.
37
+ if ( ownerNode.tagName !== 'LINK' ) {
38
+ return accumulator;
39
+ }
40
+
41
+ // Don't try to add the reset styles, which were removed as a dependency
42
+ // from `edit-blocks` for the iframe since we don't need to reset admin
43
+ // styles.
44
+ if ( ownerNode.id === 'wp-reset-editor-styles-css' ) {
45
+ return accumulator;
46
+ }
47
+
48
+ function matchFromRules( _cssRules ) {
49
+ return Array.from( _cssRules ).find(
50
+ ( {
51
+ selectorText,
52
+ conditionText,
53
+ cssRules: __cssRules,
54
+ } ) => {
55
+ // If the rule is conditional then it will not have selector text.
56
+ // Recurse into child CSS ruleset to determine selector eligibility.
57
+ if ( conditionText ) {
58
+ return matchFromRules( __cssRules );
59
+ }
60
+
61
+ return (
62
+ selectorText &&
63
+ ( selectorText.includes(
64
+ '.editor-styles-wrapper'
65
+ ) ||
66
+ selectorText.includes( '.wp-block' ) )
67
+ );
68
+ }
69
+ );
70
+ }
71
+
72
+ if ( matchFromRules( cssRules ) ) {
73
+ // Display warning once we have a way to add style dependencies to the editor.
74
+ // See: https://github.com/WordPress/gutenberg/pull/37466.
75
+ accumulator.push( ownerNode.cloneNode( true ) );
76
+
77
+ // Add inline styles belonging to the stylesheet.
78
+ const inlineCssId = ownerNode.id.replace(
79
+ '-css',
80
+ '-inline-css'
81
+ );
82
+ const inlineCssElement =
83
+ document.getElementById( inlineCssId );
84
+
85
+ if ( inlineCssElement ) {
86
+ accumulator.push( inlineCssElement.cloneNode( true ) );
87
+ }
88
+ }
89
+
90
+ return accumulator;
91
+ },
92
+ []
93
+ );
94
+ }, [] );
95
+ }
@@ -1,7 +1,8 @@
1
1
  /**
2
2
  * External dependencies
3
3
  */
4
- import { render, screen, fireEvent } from '@testing-library/react';
4
+ import { render, screen } from '@testing-library/react';
5
+ import userEvent from '@testing-library/user-event';
5
6
 
6
7
  /**
7
8
  * Internal dependencies
@@ -11,8 +12,6 @@ import ImageSizeControl from '../index';
11
12
  describe( 'ImageSizeControl', () => {
12
13
  const mockOnChange = jest.fn();
13
14
  const mockOnChangeImage = jest.fn();
14
- const getHeightInput = () => screen.getByLabelText( 'Height' );
15
- const getWidthInput = () => screen.getByLabelText( 'Width' );
16
15
 
17
16
  afterEach( () => {
18
17
  // Cleanup on exiting.
@@ -31,8 +30,12 @@ describe( 'ImageSizeControl', () => {
31
30
  />
32
31
  );
33
32
 
34
- expect( getHeightInput().value ).toBe( '300' );
35
- expect( getWidthInput().value ).toBe( '400' );
33
+ expect(
34
+ screen.getByRole( 'spinbutton', { name: 'Height' } )
35
+ ).toHaveValue( 300 );
36
+ expect(
37
+ screen.getByRole( 'spinbutton', { name: 'Width' } )
38
+ ).toHaveValue( 400 );
36
39
  } );
37
40
 
38
41
  it( 'returns default dimensions when custom dimensions are undefined', () => {
@@ -44,15 +47,23 @@ describe( 'ImageSizeControl', () => {
44
47
  />
45
48
  );
46
49
 
47
- expect( getHeightInput().value ).toBe( '100' );
48
- expect( getWidthInput().value ).toBe( '200' );
50
+ expect(
51
+ screen.getByRole( 'spinbutton', { name: 'Height' } )
52
+ ).toHaveValue( 100 );
53
+ expect(
54
+ screen.getByRole( 'spinbutton', { name: 'Width' } )
55
+ ).toHaveValue( 200 );
49
56
  } );
50
57
 
51
- it( 'returns empty string when custom and default dimensions are undefined', () => {
58
+ it( 'returns no value when custom and default dimensions are undefined', () => {
52
59
  render( <ImageSizeControl onChange={ mockOnChange } /> );
53
60
 
54
- expect( getHeightInput().value ).toBe( '' );
55
- expect( getWidthInput().value ).toBe( '' );
61
+ expect(
62
+ screen.getByRole( 'spinbutton', { name: 'Height' } )
63
+ ).toHaveValue( null );
64
+ expect(
65
+ screen.getByRole( 'spinbutton', { name: 'Width' } )
66
+ ).toHaveValue( null );
56
67
  } );
57
68
 
58
69
  it( 'returns default dimensions when initially undefined defaults are defined on rerender', () => {
@@ -62,12 +73,14 @@ describe( 'ImageSizeControl', () => {
62
73
  <ImageSizeControl onChange={ mockOnChange } />
63
74
  );
64
75
 
65
- const heightInput = getHeightInput();
66
- const widthInput = getWidthInput();
76
+ const heightInput = screen.getByRole( 'spinbutton', {
77
+ name: 'Height',
78
+ } );
79
+ const widthInput = screen.getByRole( 'spinbutton', { name: 'Width' } );
67
80
 
68
81
  // The dimensions are initially set to an empty string.
69
- expect( heightInput.value ).toBe( '' );
70
- expect( widthInput.value ).toBe( '' );
82
+ expect( heightInput ).toHaveValue( null );
83
+ expect( widthInput ).toHaveValue( null );
71
84
 
72
85
  // When new default dimensions are passed on a rerender (for example after they
73
86
  // are calculated following an image upload), update values to the new defaults.
@@ -80,48 +93,66 @@ describe( 'ImageSizeControl', () => {
80
93
  );
81
94
 
82
95
  // The dimensions should update to the defaults.
83
- expect( heightInput.value ).toBe( '300' );
84
- expect( widthInput.value ).toBe( '400' );
96
+ expect( heightInput ).toHaveValue( 300 );
97
+ expect( widthInput ).toHaveValue( 400 );
85
98
  } );
86
99
 
87
100
  describe( 'updating dimension inputs', () => {
88
- it( 'updates height and calls onChange', () => {
101
+ it( 'updates height and calls onChange', async () => {
102
+ const user = userEvent.setup();
89
103
  render( <ImageSizeControl onChange={ mockOnChange } /> );
90
104
 
91
- const heightInput = getHeightInput();
92
- const widthInput = getWidthInput();
105
+ const heightInput = screen.getByRole( 'spinbutton', {
106
+ name: 'Height',
107
+ } );
108
+ const widthInput = screen.getByRole( 'spinbutton', {
109
+ name: 'Width',
110
+ } );
93
111
 
94
- expect( heightInput.value ).toBe( '' );
95
- expect( widthInput.value ).toBe( '' );
112
+ expect( heightInput ).toHaveValue( null );
113
+ expect( widthInput ).toHaveValue( null );
96
114
 
97
- fireEvent.change( heightInput, { target: { value: '500' } } );
115
+ const newHeight = '500';
98
116
 
99
- expect( mockOnChange ).toHaveBeenCalledTimes( 1 );
100
- expect( mockOnChange ).toHaveBeenCalledWith( { height: 500 } );
117
+ await user.clear( heightInput );
118
+ await user.type( heightInput, newHeight );
101
119
 
102
- expect( heightInput.value ).toBe( '500' );
103
- expect( widthInput.value ).toBe( '' );
120
+ expect( mockOnChange ).toHaveBeenCalledTimes( newHeight.length );
121
+ expect( mockOnChange ).toHaveBeenLastCalledWith( { height: 500 } );
122
+
123
+ expect( heightInput ).toHaveValue( 500 );
124
+ expect( widthInput ).toHaveValue( null );
104
125
  } );
105
126
 
106
- it( 'updates width and calls onChange', () => {
127
+ it( 'updates width and calls onChange', async () => {
128
+ const user = userEvent.setup();
129
+
107
130
  render( <ImageSizeControl onChange={ mockOnChange } /> );
108
131
 
109
- const heightInput = getHeightInput();
110
- const widthInput = getWidthInput();
132
+ const heightInput = screen.getByRole( 'spinbutton', {
133
+ name: 'Height',
134
+ } );
135
+ const widthInput = screen.getByRole( 'spinbutton', {
136
+ name: 'Width',
137
+ } );
111
138
 
112
- expect( heightInput.value ).toBe( '' );
113
- expect( widthInput.value ).toBe( '' );
139
+ expect( heightInput ).toHaveValue( null );
140
+ expect( widthInput ).toHaveValue( null );
114
141
 
115
- fireEvent.change( widthInput, { target: { value: '500' } } );
142
+ const newWidth = '500';
143
+ await user.clear( widthInput );
144
+ await user.type( widthInput, newWidth );
116
145
 
117
- expect( mockOnChange ).toHaveBeenCalledTimes( 1 );
118
- expect( mockOnChange ).toHaveBeenCalledWith( { width: 500 } );
146
+ expect( mockOnChange ).toHaveBeenCalledTimes( newWidth.length );
147
+ expect( mockOnChange ).toHaveBeenLastCalledWith( { width: 500 } );
119
148
 
120
- expect( heightInput.value ).toBe( '' );
121
- expect( widthInput.value ).toBe( '500' );
149
+ expect( heightInput ).toHaveValue( null );
150
+ expect( widthInput ).toHaveValue( 500 );
122
151
  } );
123
152
 
124
- it( 'updates height and calls onChange for empty value', () => {
153
+ it( 'updates height and calls onChange for empty value', async () => {
154
+ const user = userEvent.setup();
155
+
125
156
  render(
126
157
  <ImageSizeControl
127
158
  imageHeight="100"
@@ -130,27 +161,33 @@ describe( 'ImageSizeControl', () => {
130
161
  />
131
162
  );
132
163
 
133
- const heightInput = getHeightInput();
134
- const widthInput = getWidthInput();
164
+ const heightInput = screen.getByRole( 'spinbutton', {
165
+ name: 'Height',
166
+ } );
167
+ const widthInput = screen.getByRole( 'spinbutton', {
168
+ name: 'Width',
169
+ } );
135
170
 
136
- expect( heightInput.value ).toBe( '100' );
137
- expect( widthInput.value ).toBe( '100' );
171
+ expect( heightInput ).toHaveValue( 100 );
172
+ expect( widthInput ).toHaveValue( 100 );
138
173
 
139
- fireEvent.change( heightInput, { target: { value: '' } } );
174
+ await user.clear( heightInput );
140
175
 
141
176
  // onChange is called and sets the dimension to undefined rather than
142
177
  // the empty string.
143
178
  expect( mockOnChange ).toHaveBeenCalledTimes( 1 );
144
- expect( mockOnChange ).toHaveBeenCalledWith( {
179
+ expect( mockOnChange ).toHaveBeenLastCalledWith( {
145
180
  height: undefined,
146
181
  } );
147
182
 
148
183
  // Height is updated to empty value and does not reset to default.
149
- expect( heightInput.value ).toBe( '' );
150
- expect( widthInput.value ).toBe( '100' );
184
+ expect( heightInput ).toHaveValue( null );
185
+ expect( widthInput ).toHaveValue( 100 );
151
186
  } );
152
187
 
153
- it( 'updates width and calls onChange for empty value', () => {
188
+ it( 'updates width and calls onChange for empty value', async () => {
189
+ const user = userEvent.setup();
190
+
154
191
  render(
155
192
  <ImageSizeControl
156
193
  imageHeight="100"
@@ -159,29 +196,35 @@ describe( 'ImageSizeControl', () => {
159
196
  />
160
197
  );
161
198
 
162
- const heightInput = getHeightInput();
163
- const widthInput = getWidthInput();
199
+ const heightInput = screen.getByRole( 'spinbutton', {
200
+ name: 'Height',
201
+ } );
202
+ const widthInput = screen.getByRole( 'spinbutton', {
203
+ name: 'Width',
204
+ } );
164
205
 
165
- expect( heightInput.value ).toBe( '100' );
166
- expect( widthInput.value ).toBe( '100' );
206
+ expect( heightInput ).toHaveValue( 100 );
207
+ expect( widthInput ).toHaveValue( 100 );
167
208
 
168
- fireEvent.change( widthInput, { target: { value: '' } } );
209
+ await user.clear( widthInput );
169
210
 
170
211
  // onChange is called and sets the dimension to undefined rather than
171
212
  // the empty string.
172
213
  expect( mockOnChange ).toHaveBeenCalledTimes( 1 );
173
- expect( mockOnChange ).toHaveBeenCalledWith( {
214
+ expect( mockOnChange ).toHaveBeenLastCalledWith( {
174
215
  width: undefined,
175
216
  } );
176
217
 
177
218
  // Width is updated to empty value and does not reset to default.
178
- expect( heightInput.value ).toBe( '100' );
179
- expect( widthInput.value ).toBe( '' );
219
+ expect( heightInput ).toHaveValue( 100 );
220
+ expect( widthInput ).toHaveValue( null );
180
221
  } );
181
222
  } );
182
223
 
183
224
  describe( 'reset button', () => {
184
- it( 'resets both height and width to default values', () => {
225
+ it( 'resets both height and width to default values', async () => {
226
+ const user = userEvent.setup();
227
+
185
228
  render(
186
229
  <ImageSizeControl
187
230
  imageHeight="100"
@@ -192,29 +235,35 @@ describe( 'ImageSizeControl', () => {
192
235
  />
193
236
  );
194
237
 
195
- const heightInput = getHeightInput();
196
- const widthInput = getWidthInput();
238
+ const heightInput = screen.getByRole( 'spinbutton', {
239
+ name: 'Height',
240
+ } );
241
+ const widthInput = screen.getByRole( 'spinbutton', {
242
+ name: 'Width',
243
+ } );
197
244
 
198
245
  // The initial dimension values display first.
199
- expect( heightInput.value ).toBe( '300' );
200
- expect( widthInput.value ).toBe( '400' );
246
+ expect( heightInput ).toHaveValue( 300 );
247
+ expect( widthInput ).toHaveValue( 400 );
201
248
 
202
- fireEvent.click( screen.getByText( 'Reset' ) );
249
+ await user.click( screen.getByRole( 'button', { name: 'Reset' } ) );
203
250
 
204
251
  // Both attributes are set to undefined to clear custom values.
205
- expect( mockOnChange ).toHaveBeenCalledWith( {
252
+ expect( mockOnChange ).toHaveBeenLastCalledWith( {
206
253
  height: undefined,
207
254
  width: undefined,
208
255
  } );
209
256
 
210
257
  // The inputs display the default values once more.
211
- expect( heightInput.value ).toBe( '100' );
212
- expect( widthInput.value ).toBe( '200' );
258
+ expect( heightInput ).toHaveValue( 100 );
259
+ expect( widthInput ).toHaveValue( 200 );
213
260
  } );
214
261
  } );
215
262
 
216
263
  describe( 'image size percentage presets', () => {
217
- it( 'updates height and width attributes on selection', () => {
264
+ it( 'updates height and width attributes on selection', async () => {
265
+ const user = userEvent.setup();
266
+
218
267
  render(
219
268
  <ImageSizeControl
220
269
  imageHeight="100"
@@ -223,18 +272,25 @@ describe( 'ImageSizeControl', () => {
223
272
  />
224
273
  );
225
274
 
226
- fireEvent.click( screen.getByText( '50%' ) );
275
+ const button = screen.getByRole( 'button', {
276
+ name: '50%',
277
+ pressed: false,
278
+ } );
279
+
280
+ await user.click( button );
227
281
 
228
- expect( screen.getByText( '50%' ) ).toHaveClass( 'is-pressed' );
282
+ expect( button ).toHaveClass( 'is-pressed' );
229
283
 
230
284
  // Both attributes are set to the rounded scaled value.
231
- expect( mockOnChange ).toHaveBeenCalledWith( {
285
+ expect( mockOnChange ).toHaveBeenLastCalledWith( {
232
286
  height: 50,
233
287
  width: 101,
234
288
  } );
235
289
  } );
236
290
 
237
- it( 'updates height and width inputs on selection', () => {
291
+ it( 'updates height and width inputs on selection', async () => {
292
+ const user = userEvent.setup();
293
+
238
294
  render(
239
295
  <ImageSizeControl
240
296
  imageHeight="100"
@@ -243,11 +299,20 @@ describe( 'ImageSizeControl', () => {
243
299
  />
244
300
  );
245
301
 
246
- fireEvent.click( screen.getByText( '50%' ) );
302
+ const button = screen.getByRole( 'button', {
303
+ name: '50%',
304
+ pressed: false,
305
+ } );
306
+
307
+ await user.click( button );
247
308
 
248
309
  // Both attributes are set to the rounded scaled value.
249
- expect( getHeightInput().value ).toBe( '50' );
250
- expect( getWidthInput().value ).toBe( '101' );
310
+ expect(
311
+ screen.getByRole( 'spinbutton', { name: 'Height' } )
312
+ ).toHaveValue( 50 );
313
+ expect(
314
+ screen.getByRole( 'spinbutton', { name: 'Width' } )
315
+ ).toHaveValue( 101 );
251
316
  } );
252
317
  } );
253
318
 
@@ -268,12 +333,14 @@ describe( 'ImageSizeControl', () => {
268
333
  />
269
334
  );
270
335
 
271
- expect( screen.getByLabelText( 'Image size' ).value ).toBe(
272
- 'medium'
273
- );
336
+ expect(
337
+ screen.getByRole( 'combobox', { name: 'Image size' } )
338
+ ).toHaveValue( 'medium' );
274
339
  } );
275
340
 
276
- it( 'calls onChangeImage with selected slug on selection', () => {
341
+ it( 'calls onChangeImage with selected slug on selection', async () => {
342
+ const user = userEvent.setup();
343
+
277
344
  render(
278
345
  <ImageSizeControl
279
346
  imageSizeOptions={ IMAGE_SIZE_OPTIONS }
@@ -283,12 +350,13 @@ describe( 'ImageSizeControl', () => {
283
350
  />
284
351
  );
285
352
 
286
- fireEvent.change( screen.getByLabelText( 'Image size' ), {
287
- target: { value: 'thumbnail' },
288
- } );
353
+ await user.selectOptions(
354
+ screen.getByRole( 'combobox', { name: 'Image size' } ),
355
+ 'thumbnail'
356
+ );
289
357
 
290
358
  // onChangeImage is called with the slug and the event.
291
- expect( mockOnChangeImage ).toHaveBeenCalledWith(
359
+ expect( mockOnChangeImage ).toHaveBeenLastCalledWith(
292
360
  'thumbnail',
293
361
  expect.any( Object )
294
362
  );
@@ -87,8 +87,10 @@ function UncontrolledInnerBlocks( props ) {
87
87
 
88
88
  const blockType = getBlockType( block.name );
89
89
 
90
- if ( ! blockType || ! blockType.providesContext ) {
91
- return {};
90
+ if (
91
+ Object.keys( blockType?.providesContext ?? {} ).length === 0
92
+ ) {
93
+ return { name: block.name };
92
94
  }
93
95
 
94
96
  return {
@@ -39,6 +39,7 @@ function useInsertionPoint( {
39
39
  isAppender,
40
40
  onSelect,
41
41
  shouldFocusBlock = true,
42
+ selectBlockOnInsert = true,
42
43
  } ) {
43
44
  const { getSelectedBlock } = useSelect( blockEditorStore );
44
45
  const { destinationRootClientId, destinationIndex } = useSelect(
@@ -108,7 +109,7 @@ function useInsertionPoint( {
108
109
  blocks,
109
110
  destinationIndex,
110
111
  destinationRootClientId,
111
- true,
112
+ selectBlockOnInsert,
112
113
  shouldFocusBlock || shouldForceFocusBlock ? 0 : null,
113
114
  meta
114
115
  );
@@ -122,7 +123,7 @@ function useInsertionPoint( {
122
123
  speak( message );
123
124
 
124
125
  if ( onSelect ) {
125
- onSelect();
126
+ onSelect( blocks );
126
127
  }
127
128
  },
128
129
  [