@robotical/martyblocksjr 4.2.0 → 4.2.2

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 (49) hide show
  1. package/editions/free/src/app.bundle.js +1 -1
  2. package/editions/free/src/assets/ui/viewOnCompact.png +0 -0
  3. package/editions/free/src/assets/ui/viewOnCompactWideLabel.png +0 -0
  4. package/editions/free/src/assets/ui/viewOnTargetCompact.png +0 -0
  5. package/editions/free/src/css/editor.css +96 -0
  6. package/editions/free/src/css/editorleftpanel.css +21 -22
  7. package/editions/free/src/css/editorstage.css +62 -0
  8. package/editions/free/src/css/paintlook.css +23 -0
  9. package/editions/free/src/localizations/bg.json +1 -0
  10. package/editions/free/src/localizations/ca.json +1 -0
  11. package/editions/free/src/localizations/cs.json +1 -0
  12. package/editions/free/src/localizations/cy.json +1 -0
  13. package/editions/free/src/localizations/da.json +1 -0
  14. package/editions/free/src/localizations/de.json +1 -0
  15. package/editions/free/src/localizations/el.json +1 -0
  16. package/editions/free/src/localizations/en.json +1 -0
  17. package/editions/free/src/localizations/es.json +1 -0
  18. package/editions/free/src/localizations/fi.json +1 -0
  19. package/editions/free/src/localizations/fr.json +1 -0
  20. package/editions/free/src/localizations/it.json +1 -0
  21. package/editions/free/src/localizations/ja.json +1 -0
  22. package/editions/free/src/localizations/ko.json +1 -0
  23. package/editions/free/src/localizations/nl.json +1 -0
  24. package/editions/free/src/localizations/no.json +1 -0
  25. package/editions/free/src/localizations/pl.json +1 -0
  26. package/editions/free/src/localizations/pt-br.json +1 -0
  27. package/editions/free/src/localizations/pt.json +1 -0
  28. package/editions/free/src/localizations/sv.json +1 -0
  29. package/editions/free/src/localizations/th.json +1 -0
  30. package/editions/free/src/localizations/tr.json +1 -0
  31. package/editions/free/src/localizations/uk.json +1 -0
  32. package/editions/free/src/localizations/zh-cn.json +1 -0
  33. package/editions/free/src/localizations/zh-tw.json +1 -0
  34. package/editions/free/src/media.json +3 -0
  35. package/package.json +1 -1
  36. package/tests/e2e/accessibility.e2e.test.js +19 -2
  37. package/tests/e2e/animated-sprite-paint-disabled.e2e.test.js +358 -0
  38. package/tests/e2e/background-paint-active-selection.e2e.test.js +162 -0
  39. package/tests/e2e/blocks-jr-hidden-blocks.e2e.test.js +262 -0
  40. package/tests/e2e/chromium-79-smoke.test.js +19 -10
  41. package/tests/e2e/delete-last-sprite-mode.e2e.test.js +162 -0
  42. package/tests/e2e/duplicate-page.e2e.test.js +414 -0
  43. package/tests/e2e/marty-script-activation-paths.e2e.test.js +593 -0
  44. package/tests/e2e/microbit-extension-project-reload.e2e.test.js +6 -1
  45. package/tests/e2e/paint-editor-cancel.e2e.test.js +274 -0
  46. package/tests/e2e/project-load-progress-loop.e2e.test.js +6 -1
  47. package/tests/e2e/project-save-stall.e2e.test.js +230 -0
  48. package/tests/e2e/sprite-watermark-grayscale.e2e.test.js +269 -0
  49. package/tests/e2e/top-toolbar-tooltips.e2e.test.js +152 -0
@@ -111,6 +111,97 @@ div.frame {
111
111
  height: ${css_vh(37.29)};
112
112
  }
113
113
 
114
+ .pagelist {
115
+ position: relative;
116
+ width: ${css_vh(21.09)};
117
+ }
118
+
119
+ .pageactions {
120
+ position: absolute;
121
+ top: 0;
122
+ left: 0;
123
+ width: ${css_vh(21.09)};
124
+ z-index: 7;
125
+ pointer-events: none;
126
+ }
127
+
128
+ .pageactionrow {
129
+ position: relative;
130
+ width: ${145 * scaleMultiplier}px;
131
+ height: ${109 * scaleMultiplier}px;
132
+ margin: ${css_vh(0)} ${css_vh(0)} ${css_vh(0.13)};
133
+ pointer-events: none;
134
+ }
135
+
136
+ .duplicatepage {
137
+ appearance: none;
138
+ position: absolute;
139
+ top: 0;
140
+ left: 0;
141
+ width: ${28 * scaleMultiplier}px;
142
+ height: ${28 * scaleMultiplier}px;
143
+ padding: 0;
144
+ border: 0;
145
+ border-radius: 50%;
146
+ background: url('../assets/ui/numOn.svg') no-repeat center;
147
+ background-size: 100% 100%;
148
+ color: #ffffff;
149
+ cursor: pointer;
150
+ pointer-events: auto;
151
+ }
152
+
153
+ .duplicatepage:hover:not(:disabled) {
154
+ filter: brightness(1.08);
155
+ }
156
+
157
+ .duplicatepage:active:not(:disabled) {
158
+ transform: scale(0.94);
159
+ }
160
+
161
+ .duplicatepage:disabled {
162
+ opacity: 0.32;
163
+ cursor: default;
164
+ }
165
+
166
+ .pageactionrow.delete-mode .duplicatepage {
167
+ visibility: hidden;
168
+ }
169
+
170
+ .duplicatepageicon,
171
+ .duplicatepageicon::before,
172
+ .duplicatepageicon::after {
173
+ box-sizing: border-box;
174
+ position: absolute;
175
+ }
176
+
177
+ .duplicatepageicon {
178
+ top: ${7 * scaleMultiplier}px;
179
+ left: ${7 * scaleMultiplier}px;
180
+ width: ${14 * scaleMultiplier}px;
181
+ height: ${13 * scaleMultiplier}px;
182
+ z-index: 1;
183
+ }
184
+
185
+ .duplicatepageicon::before,
186
+ .duplicatepageicon::after {
187
+ content: '';
188
+ width: ${11 * scaleMultiplier}px;
189
+ height: ${10 * scaleMultiplier}px;
190
+ border: ${1.5 * scaleMultiplier}px solid currentColor;
191
+ border-radius: ${1.5 * scaleMultiplier}px;
192
+ }
193
+
194
+ .duplicatepageicon::before {
195
+ top: 0;
196
+ left: 0;
197
+ }
198
+
199
+ .duplicatepageicon::after {
200
+ top: ${3 * scaleMultiplier}px;
201
+ left: ${3 * scaleMultiplier}px;
202
+ background: #F9A737;
203
+ }
204
+
114
205
  .pagethumb {
115
206
  background: none;
116
207
  position: relative;
@@ -299,6 +390,11 @@ div.frame {
299
390
  outline-offset: 4px;
300
391
  }
301
392
 
393
+ #blockspalette .categoryselector button[aria-pressed="true"]:focus,
394
+ #blockspalette .categoryselectorright button[aria-pressed="true"]:focus{
395
+ outline: none;
396
+ }
397
+
302
398
  #blockspalette .categoryselectorright{
303
399
  display: inline-block;
304
400
  word-spacing: -1;
@@ -313,11 +313,11 @@
313
313
  }
314
314
 
315
315
  .marty-mode-card {
316
- background: url('../assets/ui/viewOn.png') no-repeat left top;
317
- background-size: 100%;
316
+ background: url('../assets/ui/viewOnCompactWideLabel.png') no-repeat left top;
317
+ background-size: 100% 100%;
318
318
  position: relative;
319
319
  display: inline-block;
320
- width: ${css_vh(29.95)};
320
+ width: ${css_vh(23.18)};
321
321
  height: ${css_vh(10.16)};
322
322
  margin: 0px;
323
323
  margin-bottom: ${css_vh(-0.39)};
@@ -346,7 +346,7 @@
346
346
  position: absolute;
347
347
  text-align: center;
348
348
  top: ${css_vh(3.91)};
349
- left: ${css_vh(8.46)};
349
+ left: ${css_vh(9.24)};
350
350
  margin: 0px;
351
351
  padding: 0px;
352
352
  line-height: ${css_vh(2.60)};
@@ -356,7 +356,7 @@
356
356
  font-family: 'Lato Regular';
357
357
  font-weight: bold;
358
358
  font-size: ${css_vh(1.69)};
359
- width: ${css_vh(13.54)};
359
+ width: ${css_vh(11.97)};
360
360
  cursor: default;
361
361
  color: #F9A737;
362
362
  }
@@ -368,7 +368,7 @@
368
368
  position: relative;
369
369
  display: inline-block;
370
370
  word-spacing: -1;
371
- width: ${css_vh(29.95)};
371
+ width: ${css_vh(23.18)};
372
372
  height: ${css_vh(10.16)};
373
373
  margin: 0px;
374
374
  margin-bottom: ${css_vh(-0.39)};
@@ -391,24 +391,22 @@
391
391
 
392
392
  .spritethumb.off {
393
393
  background: url('../assets/ui/viewOff.png') no-repeat left top;
394
- background-size: ${css_vh(23.18)};
394
+ background-size: 100% 100%;
395
395
  }
396
396
 
397
397
  .spritethumb.off.target {
398
398
  background: url('../assets/ui/viewOffTarget.png') no-repeat left top;
399
- background-size: ${css_vh(23.18)};
399
+ background-size: 100% 100%;
400
400
  }
401
401
 
402
402
  .spritethumb.on.target {
403
- background: url('../assets/ui/viewOnTarget.png') no-repeat left top;
404
- background-size: 100%;
405
- width: ${css_vh(29.95)};
403
+ background: url('../assets/ui/viewOnTargetCompact.png') no-repeat left top;
404
+ background-size: 100% 100%;
406
405
  }
407
406
 
408
407
  .spritethumb.on {
409
- background: url('../assets/ui/viewOn.png') no-repeat left top;
410
- background-size: 100%;
411
- width: ${css_vh(29.95)};
408
+ background: url('../assets/ui/viewOnCompact.png') no-repeat left top;
409
+ background-size: 100% 100%;
412
410
  }
413
411
 
414
412
  .spritethumb.noneditable {
@@ -480,8 +478,8 @@
480
478
  .spritethumb.on .sname{
481
479
  color: #F9A737;
482
480
  top: ${css_vh(3.91)};
483
- left: ${css_vh(9.24)};
484
- width: ${css_vh(11.97)};
481
+ left: ${css_vh(9.11)};
482
+ width: ${css_vh(8.33)};
485
483
  }
486
484
  .spritethumb.noneditable .sname{
487
485
  color: #999;
@@ -491,14 +489,14 @@
491
489
  }
492
490
 
493
491
  .spritethumb .brush {
494
- display: absolute;
492
+ display: block;
495
493
  position: absolute;
496
494
  background: url('../assets/paint/paintbrush.svg');
497
- background-size: ${css_vh(7.03)} ${css_vh(7.03)};
498
- width: ${css_vh(7.03)};
499
- height: ${css_vh(7.03)};
500
- top: ${css_vh(1.30)};
501
- left: ${css_vh(21.75)};
495
+ background-size: 100% 100%;
496
+ width: ${css_vh(5.08)};
497
+ height: ${css_vh(5.08)};
498
+ top: ${css_vh(2.54)};
499
+ left: ${css_vh(17.45)};
502
500
  margin: 0px;
503
501
  padding: 0px;
504
502
  }
@@ -507,3 +505,4 @@
507
505
  .spritethumb.off .brush{ display: none;}
508
506
  .spritethumb.noneditable .brush{ display: none;}
509
507
  .spritethumb.martynoneditable .brush{ display: none;}
508
+ .spritethumb.paintnoneditable .brush{ display: none;}
@@ -1,5 +1,67 @@
1
1
  /* toolbar */
2
2
 
3
+ button[data-tooltip]::before,
4
+ button[data-tooltip]::after {
5
+ position: absolute;
6
+ left: 50%;
7
+ z-index: 13000;
8
+ opacity: 0;
9
+ visibility: hidden;
10
+ pointer-events: none;
11
+ transition: opacity 120ms ease;
12
+ }
13
+
14
+ button[data-tooltip]::before {
15
+ content: '';
16
+ top: calc(100% + 6px);
17
+ width: 10px;
18
+ height: 10px;
19
+ border-top: 1px solid #8E8E8E;
20
+ border-left: 1px solid #8E8E8E;
21
+ background: #FFF0B7;
22
+ transform: translateX(-50%) rotate(45deg);
23
+ }
24
+
25
+ button[data-tooltip]::after {
26
+ content: attr(data-tooltip);
27
+ box-sizing: border-box;
28
+ top: calc(100% + 11px);
29
+ width: max-content;
30
+ max-width: 240px;
31
+ padding: 7px 10px;
32
+ border: 1px solid #8E8E8E;
33
+ border-radius: 4px;
34
+ background: linear-gradient(#FFF0B7, #FFC842);
35
+ box-shadow: 0 2px 5px rgba(0, 0, 0, 0.25);
36
+ color: #3D2800;
37
+ font-family: 'Lato Regular', sans-serif;
38
+ font-size: 14px;
39
+ font-weight: normal;
40
+ line-height: 18px;
41
+ text-align: center;
42
+ white-space: normal;
43
+ transform: translateX(-50%);
44
+ }
45
+
46
+ button[data-tooltip]:hover::before,
47
+ button[data-tooltip]:hover::after,
48
+ button[data-tooltip]:focus::before,
49
+ button[data-tooltip]:focus::after {
50
+ opacity: 1;
51
+ visibility: visible;
52
+ }
53
+
54
+ #full.presentationmode[data-tooltip]::after {
55
+ left: 0;
56
+ transform: none;
57
+ }
58
+
59
+ #go.presentationmode[data-tooltip]::after {
60
+ right: 0;
61
+ left: auto;
62
+ transform: none;
63
+ }
64
+
3
65
  .fullscreen#full {
4
66
  position: absolute;
5
67
  margin: 0px;
@@ -89,6 +89,29 @@ spriteform.off {visibility: hidden; };
89
89
  background-size: 100%;
90
90
  }
91
91
 
92
+ .paintcancel {
93
+ float: right;
94
+ display: block;
95
+ margin: ${css_vh(0.65)} ${css_vh(0.65)} ${css_vh(0.00)};
96
+ padding: ${css_vh(0.00)};
97
+ width: ${css_vh(8.46)};
98
+ height: ${css_vh(8.46)};
99
+ background: url('../assets/paint/cancel.svg');
100
+ background-size: 100%;
101
+ -webkit-user-select: none;
102
+ z-index: 1000;
103
+ }
104
+
105
+ .paintcancel:active {
106
+ background: url('../assets/paint/cancelPressed.svg');
107
+ background-size: 100%;
108
+ }
109
+
110
+ .paintcancel:focus-visible {
111
+ outline: 3px solid #133C46;
112
+ outline-offset: 2px;
113
+ }
114
+
92
115
  /* camera */
93
116
 
94
117
  .phototopbar {
@@ -1165,6 +1165,7 @@
1165
1165
  "A11Y_ADD_PAGE": "Add page",
1166
1166
  "A11Y_COPY_TO_PAGE": "Copy to page {PAGE}",
1167
1167
  "A11Y_DELETE_PAGE": "Delete page {PAGE}",
1168
+ "A11Y_DUPLICATE_PAGE": "Duplicate page {PAGE}",
1168
1169
  "A11Y_MOVE_PAGE_EARLIER": "Move page {PAGE} earlier",
1169
1170
  "A11Y_MOVE_PAGE_LATER": "Move page {PAGE} later",
1170
1171
  "BLOCK_DESC_MICROBIT_ON_BUTTON": "Starts when a micro:bit button is pressed.",
@@ -1165,6 +1165,7 @@
1165
1165
  "A11Y_ADD_PAGE": "Add page",
1166
1166
  "A11Y_COPY_TO_PAGE": "Copy to page {PAGE}",
1167
1167
  "A11Y_DELETE_PAGE": "Delete page {PAGE}",
1168
+ "A11Y_DUPLICATE_PAGE": "Duplicate page {PAGE}",
1168
1169
  "A11Y_MOVE_PAGE_EARLIER": "Move page {PAGE} earlier",
1169
1170
  "A11Y_MOVE_PAGE_LATER": "Move page {PAGE} later",
1170
1171
  "BLOCK_DESC_MICROBIT_ON_BUTTON": "Starts when a micro:bit button is pressed.",
@@ -1165,6 +1165,7 @@
1165
1165
  "A11Y_ADD_PAGE": "Add page",
1166
1166
  "A11Y_COPY_TO_PAGE": "Copy to page {PAGE}",
1167
1167
  "A11Y_DELETE_PAGE": "Delete page {PAGE}",
1168
+ "A11Y_DUPLICATE_PAGE": "Duplicate page {PAGE}",
1168
1169
  "A11Y_MOVE_PAGE_EARLIER": "Move page {PAGE} earlier",
1169
1170
  "A11Y_MOVE_PAGE_LATER": "Move page {PAGE} later",
1170
1171
  "BLOCK_DESC_MICROBIT_ON_BUTTON": "Starts when a micro:bit button is pressed.",
@@ -1165,6 +1165,7 @@
1165
1165
  "A11Y_ADD_PAGE": "Add page",
1166
1166
  "A11Y_COPY_TO_PAGE": "Copy to page {PAGE}",
1167
1167
  "A11Y_DELETE_PAGE": "Delete page {PAGE}",
1168
+ "A11Y_DUPLICATE_PAGE": "Duplicate page {PAGE}",
1168
1169
  "A11Y_MOVE_PAGE_EARLIER": "Move page {PAGE} earlier",
1169
1170
  "A11Y_MOVE_PAGE_LATER": "Move page {PAGE} later",
1170
1171
  "BLOCK_DESC_MICROBIT_ON_BUTTON": "Starts when a micro:bit button is pressed.",
@@ -1165,6 +1165,7 @@
1165
1165
  "A11Y_ADD_PAGE": "Add page",
1166
1166
  "A11Y_COPY_TO_PAGE": "Copy to page {PAGE}",
1167
1167
  "A11Y_DELETE_PAGE": "Delete page {PAGE}",
1168
+ "A11Y_DUPLICATE_PAGE": "Duplicate page {PAGE}",
1168
1169
  "A11Y_MOVE_PAGE_EARLIER": "Move page {PAGE} earlier",
1169
1170
  "A11Y_MOVE_PAGE_LATER": "Move page {PAGE} later",
1170
1171
  "BLOCK_DESC_MICROBIT_ON_BUTTON": "Starts when a micro:bit button is pressed.",
@@ -1165,6 +1165,7 @@
1165
1165
  "A11Y_ADD_PAGE": "Add page",
1166
1166
  "A11Y_COPY_TO_PAGE": "Copy to page {PAGE}",
1167
1167
  "A11Y_DELETE_PAGE": "Delete page {PAGE}",
1168
+ "A11Y_DUPLICATE_PAGE": "Duplicate page {PAGE}",
1168
1169
  "A11Y_MOVE_PAGE_EARLIER": "Move page {PAGE} earlier",
1169
1170
  "A11Y_MOVE_PAGE_LATER": "Move page {PAGE} later",
1170
1171
  "BLOCK_DESC_MICROBIT_ON_BUTTON": "Starts when a micro:bit button is pressed.",
@@ -1165,6 +1165,7 @@
1165
1165
  "A11Y_ADD_PAGE": "Add page",
1166
1166
  "A11Y_COPY_TO_PAGE": "Copy to page {PAGE}",
1167
1167
  "A11Y_DELETE_PAGE": "Delete page {PAGE}",
1168
+ "A11Y_DUPLICATE_PAGE": "Duplicate page {PAGE}",
1168
1169
  "A11Y_MOVE_PAGE_EARLIER": "Move page {PAGE} earlier",
1169
1170
  "A11Y_MOVE_PAGE_LATER": "Move page {PAGE} later",
1170
1171
  "BLOCK_DESC_MICROBIT_ON_BUTTON": "Starts when a micro:bit button is pressed.",
@@ -1165,6 +1165,7 @@
1165
1165
  "A11Y_ADD_PAGE": "Add page",
1166
1166
  "A11Y_COPY_TO_PAGE": "Copy to page {PAGE}",
1167
1167
  "A11Y_DELETE_PAGE": "Delete page {PAGE}",
1168
+ "A11Y_DUPLICATE_PAGE": "Duplicate page {PAGE}",
1168
1169
  "A11Y_MOVE_PAGE_EARLIER": "Move page {PAGE} earlier",
1169
1170
  "A11Y_MOVE_PAGE_LATER": "Move page {PAGE} later",
1170
1171
  "BLOCK_DESC_MICROBIT_ON_BUTTON": "Starts when a micro:bit button is pressed.",
@@ -1165,6 +1165,7 @@
1165
1165
  "A11Y_ADD_PAGE": "Add page",
1166
1166
  "A11Y_COPY_TO_PAGE": "Copy to page {PAGE}",
1167
1167
  "A11Y_DELETE_PAGE": "Delete page {PAGE}",
1168
+ "A11Y_DUPLICATE_PAGE": "Duplicate page {PAGE}",
1168
1169
  "A11Y_MOVE_PAGE_EARLIER": "Move page {PAGE} earlier",
1169
1170
  "A11Y_MOVE_PAGE_LATER": "Move page {PAGE} later",
1170
1171
  "BLOCK_DESC_MICROBIT_ON_BUTTON": "Starts when a micro:bit button is pressed.",
@@ -1165,6 +1165,7 @@
1165
1165
  "A11Y_ADD_PAGE": "Add page",
1166
1166
  "A11Y_COPY_TO_PAGE": "Copy to page {PAGE}",
1167
1167
  "A11Y_DELETE_PAGE": "Delete page {PAGE}",
1168
+ "A11Y_DUPLICATE_PAGE": "Duplicate page {PAGE}",
1168
1169
  "A11Y_MOVE_PAGE_EARLIER": "Move page {PAGE} earlier",
1169
1170
  "A11Y_MOVE_PAGE_LATER": "Move page {PAGE} later",
1170
1171
  "BLOCK_DESC_MICROBIT_ON_BUTTON": "Starts when a micro:bit button is pressed.",
@@ -1165,6 +1165,7 @@
1165
1165
  "A11Y_ADD_PAGE": "Add page",
1166
1166
  "A11Y_COPY_TO_PAGE": "Copy to page {PAGE}",
1167
1167
  "A11Y_DELETE_PAGE": "Delete page {PAGE}",
1168
+ "A11Y_DUPLICATE_PAGE": "Duplicate page {PAGE}",
1168
1169
  "A11Y_MOVE_PAGE_EARLIER": "Move page {PAGE} earlier",
1169
1170
  "A11Y_MOVE_PAGE_LATER": "Move page {PAGE} later",
1170
1171
  "BLOCK_DESC_MICROBIT_ON_BUTTON": "Starts when a micro:bit button is pressed.",
@@ -1165,6 +1165,7 @@
1165
1165
  "A11Y_ADD_PAGE": "Add page",
1166
1166
  "A11Y_COPY_TO_PAGE": "Copy to page {PAGE}",
1167
1167
  "A11Y_DELETE_PAGE": "Delete page {PAGE}",
1168
+ "A11Y_DUPLICATE_PAGE": "Duplicate page {PAGE}",
1168
1169
  "A11Y_MOVE_PAGE_EARLIER": "Move page {PAGE} earlier",
1169
1170
  "A11Y_MOVE_PAGE_LATER": "Move page {PAGE} later",
1170
1171
  "BLOCK_DESC_MICROBIT_ON_BUTTON": "Starts when a micro:bit button is pressed.",
@@ -1165,6 +1165,7 @@
1165
1165
  "A11Y_ADD_PAGE": "Add page",
1166
1166
  "A11Y_COPY_TO_PAGE": "Copy to page {PAGE}",
1167
1167
  "A11Y_DELETE_PAGE": "Delete page {PAGE}",
1168
+ "A11Y_DUPLICATE_PAGE": "Duplicate page {PAGE}",
1168
1169
  "A11Y_MOVE_PAGE_EARLIER": "Move page {PAGE} earlier",
1169
1170
  "A11Y_MOVE_PAGE_LATER": "Move page {PAGE} later",
1170
1171
  "BLOCK_DESC_MICROBIT_ON_BUTTON": "Starts when a micro:bit button is pressed.",
@@ -1165,6 +1165,7 @@
1165
1165
  "A11Y_ADD_PAGE": "Add page",
1166
1166
  "A11Y_COPY_TO_PAGE": "Copy to page {PAGE}",
1167
1167
  "A11Y_DELETE_PAGE": "Delete page {PAGE}",
1168
+ "A11Y_DUPLICATE_PAGE": "Duplicate page {PAGE}",
1168
1169
  "A11Y_MOVE_PAGE_EARLIER": "Move page {PAGE} earlier",
1169
1170
  "A11Y_MOVE_PAGE_LATER": "Move page {PAGE} later",
1170
1171
  "BLOCK_DESC_MICROBIT_ON_BUTTON": "Starts when a micro:bit button is pressed.",
@@ -1165,6 +1165,7 @@
1165
1165
  "A11Y_ADD_PAGE": "Add page",
1166
1166
  "A11Y_COPY_TO_PAGE": "Copy to page {PAGE}",
1167
1167
  "A11Y_DELETE_PAGE": "Delete page {PAGE}",
1168
+ "A11Y_DUPLICATE_PAGE": "Duplicate page {PAGE}",
1168
1169
  "A11Y_MOVE_PAGE_EARLIER": "Move page {PAGE} earlier",
1169
1170
  "A11Y_MOVE_PAGE_LATER": "Move page {PAGE} later",
1170
1171
  "BLOCK_DESC_MICROBIT_ON_BUTTON": "Starts when a micro:bit button is pressed.",
@@ -1165,6 +1165,7 @@
1165
1165
  "A11Y_ADD_PAGE": "Add page",
1166
1166
  "A11Y_COPY_TO_PAGE": "Copy to page {PAGE}",
1167
1167
  "A11Y_DELETE_PAGE": "Delete page {PAGE}",
1168
+ "A11Y_DUPLICATE_PAGE": "Duplicate page {PAGE}",
1168
1169
  "A11Y_MOVE_PAGE_EARLIER": "Move page {PAGE} earlier",
1169
1170
  "A11Y_MOVE_PAGE_LATER": "Move page {PAGE} later",
1170
1171
  "BLOCK_DESC_MICROBIT_ON_BUTTON": "Starts when a micro:bit button is pressed.",
@@ -1165,6 +1165,7 @@
1165
1165
  "A11Y_ADD_PAGE": "Add page",
1166
1166
  "A11Y_COPY_TO_PAGE": "Copy to page {PAGE}",
1167
1167
  "A11Y_DELETE_PAGE": "Delete page {PAGE}",
1168
+ "A11Y_DUPLICATE_PAGE": "Duplicate page {PAGE}",
1168
1169
  "A11Y_MOVE_PAGE_EARLIER": "Move page {PAGE} earlier",
1169
1170
  "A11Y_MOVE_PAGE_LATER": "Move page {PAGE} later",
1170
1171
  "BLOCK_DESC_MICROBIT_ON_BUTTON": "Starts when a micro:bit button is pressed.",
@@ -1165,6 +1165,7 @@
1165
1165
  "A11Y_ADD_PAGE": "Add page",
1166
1166
  "A11Y_COPY_TO_PAGE": "Copy to page {PAGE}",
1167
1167
  "A11Y_DELETE_PAGE": "Delete page {PAGE}",
1168
+ "A11Y_DUPLICATE_PAGE": "Duplicate page {PAGE}",
1168
1169
  "A11Y_MOVE_PAGE_EARLIER": "Move page {PAGE} earlier",
1169
1170
  "A11Y_MOVE_PAGE_LATER": "Move page {PAGE} later",
1170
1171
  "BLOCK_DESC_MICROBIT_ON_BUTTON": "Starts when a micro:bit button is pressed.",
@@ -1165,6 +1165,7 @@
1165
1165
  "A11Y_ADD_PAGE": "Add page",
1166
1166
  "A11Y_COPY_TO_PAGE": "Copy to page {PAGE}",
1167
1167
  "A11Y_DELETE_PAGE": "Delete page {PAGE}",
1168
+ "A11Y_DUPLICATE_PAGE": "Duplicate page {PAGE}",
1168
1169
  "A11Y_MOVE_PAGE_EARLIER": "Move page {PAGE} earlier",
1169
1170
  "A11Y_MOVE_PAGE_LATER": "Move page {PAGE} later",
1170
1171
  "BLOCK_DESC_MICROBIT_ON_BUTTON": "Starts when a micro:bit button is pressed.",
@@ -1165,6 +1165,7 @@
1165
1165
  "A11Y_ADD_PAGE": "Add page",
1166
1166
  "A11Y_COPY_TO_PAGE": "Copy to page {PAGE}",
1167
1167
  "A11Y_DELETE_PAGE": "Delete page {PAGE}",
1168
+ "A11Y_DUPLICATE_PAGE": "Duplicate page {PAGE}",
1168
1169
  "A11Y_MOVE_PAGE_EARLIER": "Move page {PAGE} earlier",
1169
1170
  "A11Y_MOVE_PAGE_LATER": "Move page {PAGE} later",
1170
1171
  "BLOCK_DESC_MICROBIT_ON_BUTTON": "Starts when a micro:bit button is pressed.",
@@ -1165,6 +1165,7 @@
1165
1165
  "A11Y_ADD_PAGE": "Add page",
1166
1166
  "A11Y_COPY_TO_PAGE": "Copy to page {PAGE}",
1167
1167
  "A11Y_DELETE_PAGE": "Delete page {PAGE}",
1168
+ "A11Y_DUPLICATE_PAGE": "Duplicate page {PAGE}",
1168
1169
  "A11Y_MOVE_PAGE_EARLIER": "Move page {PAGE} earlier",
1169
1170
  "A11Y_MOVE_PAGE_LATER": "Move page {PAGE} later",
1170
1171
  "BLOCK_DESC_MICROBIT_ON_BUTTON": "Starts when a micro:bit button is pressed.",
@@ -1165,6 +1165,7 @@
1165
1165
  "A11Y_ADD_PAGE": "Add page",
1166
1166
  "A11Y_COPY_TO_PAGE": "Copy to page {PAGE}",
1167
1167
  "A11Y_DELETE_PAGE": "Delete page {PAGE}",
1168
+ "A11Y_DUPLICATE_PAGE": "Duplicate page {PAGE}",
1168
1169
  "A11Y_MOVE_PAGE_EARLIER": "Move page {PAGE} earlier",
1169
1170
  "A11Y_MOVE_PAGE_LATER": "Move page {PAGE} later",
1170
1171
  "BLOCK_DESC_MICROBIT_ON_BUTTON": "Starts when a micro:bit button is pressed.",
@@ -1165,6 +1165,7 @@
1165
1165
  "A11Y_ADD_PAGE": "Add page",
1166
1166
  "A11Y_COPY_TO_PAGE": "Copy to page {PAGE}",
1167
1167
  "A11Y_DELETE_PAGE": "Delete page {PAGE}",
1168
+ "A11Y_DUPLICATE_PAGE": "Duplicate page {PAGE}",
1168
1169
  "A11Y_MOVE_PAGE_EARLIER": "Move page {PAGE} earlier",
1169
1170
  "A11Y_MOVE_PAGE_LATER": "Move page {PAGE} later",
1170
1171
  "BLOCK_DESC_MICROBIT_ON_BUTTON": "Starts when a micro:bit button is pressed.",
@@ -1165,6 +1165,7 @@
1165
1165
  "A11Y_ADD_PAGE": "Add page",
1166
1166
  "A11Y_COPY_TO_PAGE": "Copy to page {PAGE}",
1167
1167
  "A11Y_DELETE_PAGE": "Delete page {PAGE}",
1168
+ "A11Y_DUPLICATE_PAGE": "Duplicate page {PAGE}",
1168
1169
  "A11Y_MOVE_PAGE_EARLIER": "Move page {PAGE} earlier",
1169
1170
  "A11Y_MOVE_PAGE_LATER": "Move page {PAGE} later",
1170
1171
  "BLOCK_DESC_MICROBIT_ON_BUTTON": "Starts when a micro:bit button is pressed.",
@@ -1165,6 +1165,7 @@
1165
1165
  "A11Y_ADD_PAGE": "Add page",
1166
1166
  "A11Y_COPY_TO_PAGE": "Copy to page {PAGE}",
1167
1167
  "A11Y_DELETE_PAGE": "Delete page {PAGE}",
1168
+ "A11Y_DUPLICATE_PAGE": "Duplicate page {PAGE}",
1168
1169
  "A11Y_MOVE_PAGE_EARLIER": "Move page {PAGE} earlier",
1169
1170
  "A11Y_MOVE_PAGE_LATER": "Move page {PAGE} later",
1170
1171
  "BLOCK_DESC_MICROBIT_ON_BUTTON": "Starts when a micro:bit button is pressed.",
@@ -117,6 +117,7 @@
117
117
  "height": 321.28673,
118
118
  "ext": "svg",
119
119
  "name": "Octopus-Pink",
120
+ "watermarkMode": "source-grayscale",
120
121
  "order": "characters,07 weather",
121
122
  "tags":["characters", "07 weather"]
122
123
  },
@@ -126,6 +127,7 @@
126
127
  "height": 321.28673,
127
128
  "ext": "svg",
128
129
  "name": "Raccoon",
130
+ "watermarkMode": "source-grayscale",
129
131
  "order": "characters,07 weather",
130
132
  "tags":["characters", "07 weather"]
131
133
  },
@@ -144,6 +146,7 @@
144
146
  "height": 321.28673,
145
147
  "ext": "svg",
146
148
  "name": "Unicorn",
149
+ "watermarkMode": "source-grayscale",
147
150
  "order": "characters,07 weather",
148
151
  "tags": ["characters", "07 weather"]
149
152
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@robotical/martyblocksjr",
3
- "version": "4.2.0",
3
+ "version": "4.2.2",
4
4
  "description": "ScratchJr",
5
5
  "repository": {
6
6
  "type": "git",
@@ -153,6 +153,14 @@ async function expectNamedControls(page, selectors) {
153
153
  expect(missing).toEqual([]);
154
154
  }
155
155
 
156
+ async function activateSkipLink(page, targetId) {
157
+ await page.focus('#skip-link');
158
+ await page.keyboard.press('Enter');
159
+ await page.waitForFunction((expectedTargetId) => {
160
+ return document.activeElement && document.activeElement.id === expectedTargetId;
161
+ }, { timeout: 5_000 }, targetId);
162
+ }
163
+
156
164
  beforeEach(async () => {
157
165
  server = spawn('python3', ['-m', 'http.server', `${PORT}`, '--directory', 'editions/free/src'], {
158
166
  stdio: 'ignore'
@@ -218,6 +226,8 @@ describe('Accessibility shell audit', () => {
218
226
  await tabToSelector(page, '#hometab');
219
227
  expectVisibleFocusIndicator(await getFocusStyles(page, '#hometab'));
220
228
 
229
+ await activateSkipLink(page, 'wrapc');
230
+
221
231
  await new Promise((resolve) => setTimeout(resolve, 1200));
222
232
  await page.click('#booktab');
223
233
  await page.waitForSelector('iframe#htmlcontents', { timeout: 30_000 });
@@ -288,6 +298,8 @@ describe('Accessibility shell audit', () => {
288
298
  await tabToSelector(page, guideCase.focusSelector);
289
299
  expectVisibleFocusIndicator(await getFocusStyles(page, guideCase.focusSelector));
290
300
 
301
+ await activateSkipLink(page, 'content');
302
+
291
303
  expectNoAxeViolations(await runAxe(page));
292
304
  expect(errors).toEqual([]);
293
305
  await page.close();
@@ -344,6 +356,8 @@ describe('Accessibility shell audit', () => {
344
356
  expect(await page.$eval('#scriptscontainer', (element) => element.getAttribute('role'))).toBe('list');
345
357
  expect(await page.$eval('#scriptscontainer', (element) => element.getAttribute('aria-label'))).toBe('Programming Script');
346
358
 
359
+ await activateSkipLink(page, 'frame');
360
+
347
361
  await expectNamedControls(page, [
348
362
  '#projectinfo',
349
363
  '#grid',
@@ -364,6 +378,7 @@ describe('Accessibility shell audit', () => {
364
378
  const motionButton = document.getElementById('sprite-motion');
365
379
  return motionButton && motionButton.getAttribute('aria-pressed') === 'true';
366
380
  }, { timeout: 5_000 });
381
+ expect((await getFocusStyles(page, '#sprite-motion')).outlineStyle).toBe('none');
367
382
  await page.waitForSelector('#forward_block[role="button"]', { timeout: 30_000 });
368
383
 
369
384
  await expectNamedControls(page, ['#forward_block', '#back_block']);
@@ -551,8 +566,10 @@ describe('Accessibility shell audit', () => {
551
566
  });
552
567
  expect(await page.evaluate(() => document.activeElement.id)).toBe('projectinfo');
553
568
 
554
- const editorUrl = page.url();
555
- await page.goto(`${editorUrl}&tutorial=cog-jrblocks-1`, { waitUntil: 'domcontentloaded', timeout: 30_000 });
569
+ const editorUrl = new URL(page.url());
570
+ editorUrl.searchParams.set('tutorial', 'cog-jrblocks-1');
571
+ editorUrl.hash = '';
572
+ await page.goto(editorUrl.toString(), { waitUntil: 'domcontentloaded', timeout: 30_000 });
556
573
  await page.waitForSelector('#tutorialMenuBar', { timeout: 40_000 });
557
574
  await page.waitForSelector('#nextStep', { timeout: 30_000 });
558
575