pxt-microbit 8.1.12 → 8.1.14
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.
- package/built/block-tests.js +1 -1
- package/built/sim-strings.json +1 -1
- package/built/sim.d.ts +2 -1
- package/built/sim.js +200 -158
- package/built/target.js +1 -1
- package/built/target.json +1 -1
- package/built/targetlight.js +1 -1
- package/built/targetlight.json +1 -1
- package/built/web/react-common-authcode.css +2 -2
- package/built/web/react-common-multiplayer.css +2 -2
- package/built/web/react-common-skillmap.css +2 -2
- package/built/web/rtlreact-common-authcode.css +2 -2
- package/built/web/rtlreact-common-multiplayer.css +2 -2
- package/built/web/rtlreact-common-skillmap.css +2 -2
- package/built/web/rtlsemantic.css +2 -2
- package/built/web/semantic.css +2 -2
- package/package.json +2 -2
package/built/sim.js
CHANGED
|
@@ -4069,13 +4069,14 @@ var pxsim;
|
|
|
4069
4069
|
.sim-button-nut:hover {
|
|
4070
4070
|
stroke:1px solid #704A4A;
|
|
4071
4071
|
}
|
|
4072
|
-
.sim-pin:hover {
|
|
4072
|
+
.sim-pin[focusable=true]:hover {
|
|
4073
4073
|
stroke:#D4AF37;
|
|
4074
4074
|
stroke-width:2px;
|
|
4075
4075
|
}
|
|
4076
4076
|
|
|
4077
|
-
.sim-pin-touch.touched {
|
|
4077
|
+
.sim-pin-touch[focusable=true].touched {
|
|
4078
4078
|
stroke:darkorange !important;
|
|
4079
|
+
stroke-width:5px;
|
|
4079
4080
|
}
|
|
4080
4081
|
|
|
4081
4082
|
.sim-led-back:hover {
|
|
@@ -4170,6 +4171,7 @@ var pxsim;
|
|
|
4170
4171
|
}
|
|
4171
4172
|
.sim-label, .sim-button-label {
|
|
4172
4173
|
fill: #000;
|
|
4174
|
+
pointer-events: none;
|
|
4173
4175
|
}
|
|
4174
4176
|
.sim-wireframe .sim-board {
|
|
4175
4177
|
stroke-width: 2px;
|
|
@@ -4177,25 +4179,25 @@ var pxsim;
|
|
|
4177
4179
|
*:focus {
|
|
4178
4180
|
outline: none;
|
|
4179
4181
|
}
|
|
4180
|
-
*:focus .sim-button-outer,
|
|
4181
|
-
.sim-shake:focus,
|
|
4182
|
-
.sim-thermometer:focus {
|
|
4182
|
+
*:focus-visible .sim-button-outer,
|
|
4183
|
+
.sim-shake:focus-visible,
|
|
4184
|
+
.sim-thermometer:focus-visible {
|
|
4183
4185
|
outline: 5px solid white;
|
|
4184
4186
|
stroke: black;
|
|
4185
4187
|
stroke-width: 10px;
|
|
4186
4188
|
paint-order: stroke;
|
|
4187
4189
|
}
|
|
4188
|
-
.sim-button-outer.sim-button-group:focus > .sim-button {
|
|
4190
|
+
.sim-button-outer.sim-button-group:focus-visible > .sim-button {
|
|
4189
4191
|
outline: 5px solid white;
|
|
4190
4192
|
stroke: black;
|
|
4191
4193
|
stroke-width: 5px;
|
|
4192
4194
|
paint-order: stroke;
|
|
4193
4195
|
}
|
|
4194
|
-
.sim-light-level-button:focus,
|
|
4195
|
-
.sim-antenna-outer:focus > .sim-antenna {
|
|
4196
|
+
.sim-light-level-button:focus-visible,
|
|
4197
|
+
.sim-antenna-outer:focus-visible > .sim-antenna {
|
|
4196
4198
|
outline: 5px solid white;
|
|
4197
4199
|
}
|
|
4198
|
-
.sim-pin:focus {
|
|
4200
|
+
.sim-pin:focus-visible {
|
|
4199
4201
|
stroke: white;
|
|
4200
4202
|
stroke-width: 5px !important;
|
|
4201
4203
|
}
|
|
@@ -4208,6 +4210,9 @@ var pxsim;
|
|
|
4208
4210
|
-webkit-user-select: none;
|
|
4209
4211
|
-ms-user-select: none;
|
|
4210
4212
|
}
|
|
4213
|
+
[focusable=true] {
|
|
4214
|
+
cursor: pointer;
|
|
4215
|
+
}
|
|
4211
4216
|
`;
|
|
4212
4217
|
const MB_HIGHCONTRAST = `
|
|
4213
4218
|
path.sim-board {
|
|
@@ -4220,11 +4225,11 @@ path.sim-board {
|
|
|
4220
4225
|
.sim-led-back {
|
|
4221
4226
|
stroke: white;
|
|
4222
4227
|
}
|
|
4223
|
-
*:focus .sim-button-outer,
|
|
4224
|
-
.sim-pin:focus,
|
|
4225
|
-
.sim-thermometer:focus,
|
|
4226
|
-
.sim-shake:focus,
|
|
4227
|
-
.sim-light-level-button:focus {
|
|
4228
|
+
*:focus-visible .sim-button-outer,
|
|
4229
|
+
.sim-pin:focus-visible,
|
|
4230
|
+
.sim-thermometer:focus-visible,
|
|
4231
|
+
.sim-shake:focus-visible,
|
|
4232
|
+
.sim-light-level-button:focus-visible {
|
|
4228
4233
|
stroke: #10C8CD !important;
|
|
4229
4234
|
}
|
|
4230
4235
|
`;
|
|
@@ -4250,29 +4255,33 @@ path.sim-board {
|
|
|
4250
4255
|
"P12", "P2", "P13", "P14", "P15", "P16", "P17", "P18", "P19", "P20",
|
|
4251
4256
|
"GND0", "GND", "+3v3", "GND1"
|
|
4252
4257
|
];
|
|
4258
|
+
// title is currently unused.
|
|
4253
4259
|
const pinTitles = [
|
|
4254
|
-
"P0, ANALOG IN",
|
|
4255
|
-
"P1, ANALOG IN",
|
|
4256
|
-
"P2, ANALOG IN",
|
|
4257
|
-
"P3, ANALOG IN, LED Col 1",
|
|
4258
|
-
"P4, ANALOG IN, LED Col 2",
|
|
4259
|
-
"P5, BUTTON A",
|
|
4260
|
-
"P6, LED Col 9",
|
|
4261
|
-
"P7, LED Col 8",
|
|
4262
|
-
"P8",
|
|
4263
|
-
"P9, LED Col 7",
|
|
4264
|
-
"P10, ANALOG IN, LED Col 3",
|
|
4265
|
-
"P11, BUTTON B",
|
|
4266
|
-
"P12, RESERVED ACCESSIBILITY",
|
|
4267
|
-
"P13, SPI - SCK",
|
|
4268
|
-
"P14, SPI - MISO",
|
|
4269
|
-
"P15, SPI - MOSI",
|
|
4270
|
-
"P16, SPI - Chip Select",
|
|
4271
|
-
"P17, +3v3",
|
|
4272
|
-
"P18, +3v3",
|
|
4273
|
-
"P19, I2C - SCL",
|
|
4274
|
-
"P20, I2C - SDA",
|
|
4275
|
-
"GND", "GND"
|
|
4260
|
+
{ title: "P0, ANALOG IN", ariaLabel: pxsim.localization.lf("Pin 0") },
|
|
4261
|
+
{ title: "P1, ANALOG IN", ariaLabel: pxsim.localization.lf("Pin 1") },
|
|
4262
|
+
{ title: "P2, ANALOG IN", ariaLabel: pxsim.localization.lf("Pin 2") },
|
|
4263
|
+
{ title: "P3, ANALOG IN, LED Col 1", ariaLabel: pxsim.localization.lf("Pin 3") },
|
|
4264
|
+
{ title: "P4, ANALOG IN, LED Col 2", ariaLabel: pxsim.localization.lf("Pin 4") },
|
|
4265
|
+
{ title: "P5, BUTTON A", ariaLabel: pxsim.localization.lf("Pin 5") },
|
|
4266
|
+
{ title: "P6, LED Col 9", ariaLabel: pxsim.localization.lf("Pin 6") },
|
|
4267
|
+
{ title: "P7, LED Col 8", ariaLabel: pxsim.localization.lf("Pin 7") },
|
|
4268
|
+
{ title: "P8", ariaLabel: pxsim.localization.lf("Pin 8") },
|
|
4269
|
+
{ title: "P9, LED Col 7", ariaLabel: pxsim.localization.lf("Pin 9") },
|
|
4270
|
+
{ title: "P10, ANALOG IN, LED Col 3", ariaLabel: pxsim.localization.lf("Pin 10") },
|
|
4271
|
+
{ title: "P11, BUTTON B", ariaLabel: pxsim.localization.lf("Pin 11") },
|
|
4272
|
+
{ title: "P12, RESERVED ACCESSIBILITY", ariaLabel: pxsim.localization.lf("Pin 12") },
|
|
4273
|
+
{ title: "P13, SPI - SCK", ariaLabel: pxsim.localization.lf("Pin 13") },
|
|
4274
|
+
{ title: "P14, SPI - MISO", ariaLabel: pxsim.localization.lf("Pin 14") },
|
|
4275
|
+
{ title: "P15, SPI - MOSI", ariaLabel: pxsim.localization.lf("Pin 15") },
|
|
4276
|
+
{ title: "P16, SPI - Chip Select", ariaLabel: pxsim.localization.lf("Pin 16") },
|
|
4277
|
+
{ title: "P17, +3v3", ariaLabel: pxsim.localization.lf("Pin 3V") },
|
|
4278
|
+
{ title: "P18, +3v3", ariaLabel: pxsim.localization.lf("Pin 3V") },
|
|
4279
|
+
{ title: "P19, I2C - SCL", ariaLabel: pxsim.localization.lf("Pin 19") },
|
|
4280
|
+
{ title: "P20, I2C - SDA", ariaLabel: pxsim.localization.lf("Pin 20") },
|
|
4281
|
+
{ title: "GND", ariaLabel: pxsim.localization.lf("Pin GND") },
|
|
4282
|
+
{ title: "GND", ariaLabel: pxsim.localization.lf("Pin GND") },
|
|
4283
|
+
{ title: "+3v3", ariaLabel: pxsim.localization.lf("Pin 3V") },
|
|
4284
|
+
{ title: "GND", ariaLabel: pxsim.localization.lf("Pin GND") },
|
|
4276
4285
|
];
|
|
4277
4286
|
const MB_WIDTH = 500;
|
|
4278
4287
|
const MB_HEIGHT = 408;
|
|
@@ -4315,6 +4324,7 @@ path.sim-board {
|
|
|
4315
4324
|
class MicrobitBoardSvg {
|
|
4316
4325
|
constructor(props) {
|
|
4317
4326
|
this.props = props;
|
|
4327
|
+
this.liveRegionInitialized = false;
|
|
4318
4328
|
this.headInitialized = false;
|
|
4319
4329
|
this.antennaInitialized = false;
|
|
4320
4330
|
this.lightLevelInitialized = false;
|
|
@@ -4350,7 +4360,7 @@ path.sim-board {
|
|
|
4350
4360
|
if (props && props.runtime) {
|
|
4351
4361
|
this.board = this.props.runtime.board;
|
|
4352
4362
|
this.board.updateSubscribers.push(() => this.updateState());
|
|
4353
|
-
this.updateState();
|
|
4363
|
+
this.updateState(true);
|
|
4354
4364
|
this.attachEvents();
|
|
4355
4365
|
}
|
|
4356
4366
|
}
|
|
@@ -4409,7 +4419,7 @@ path.sim-board {
|
|
|
4409
4419
|
pxsim.svg.setGradientColors(this.soundLevelGradient, theme.ledOff, theme.ledOn);
|
|
4410
4420
|
this.positionV2Elements();
|
|
4411
4421
|
}
|
|
4412
|
-
updateState() {
|
|
4422
|
+
updateState(initialCall = false) {
|
|
4413
4423
|
const state = this.board;
|
|
4414
4424
|
if (!state)
|
|
4415
4425
|
return;
|
|
@@ -4430,6 +4440,12 @@ path.sim-board {
|
|
|
4430
4440
|
pxsim.U.addClass(this.element, "grayscale");
|
|
4431
4441
|
else
|
|
4432
4442
|
pxsim.U.removeClass(this.element, "grayscale");
|
|
4443
|
+
if (!initialCall && !this.liveRegionInitialized) {
|
|
4444
|
+
// The iframe document's innerHTML is cleared after mkBoardView is called.
|
|
4445
|
+
// Ensure that the live region is created after this.
|
|
4446
|
+
pxsim.accessibility.setLiveContent("");
|
|
4447
|
+
this.liveRegionInitialized = true;
|
|
4448
|
+
}
|
|
4433
4449
|
}
|
|
4434
4450
|
updateButtonPairs() {
|
|
4435
4451
|
const state = this.board;
|
|
@@ -4493,8 +4509,8 @@ path.sim-board {
|
|
|
4493
4509
|
pxsim.svg.fill(this.shakeButton, this.props.theme.virtualButtonUp);
|
|
4494
4510
|
this.board.accelerometerState.shake();
|
|
4495
4511
|
});
|
|
4496
|
-
pxsim.accessibility.setAria(this.shakeButton, "button", "Shake
|
|
4497
|
-
this.shakeText = pxsim.svg.child(this.g, "text", { x: 420, y: 122, class: "sim-text-small" });
|
|
4512
|
+
pxsim.accessibility.setAria(this.shakeButton, "button", pxsim.localization.lf("Shake"));
|
|
4513
|
+
this.shakeText = pxsim.svg.child(this.g, "text", { x: 420, y: 122, class: "sim-text-small", "aria-hidden": true });
|
|
4498
4514
|
this.shakeText.textContent = "SHAKE";
|
|
4499
4515
|
}
|
|
4500
4516
|
}
|
|
@@ -4533,19 +4549,23 @@ path.sim-board {
|
|
|
4533
4549
|
}
|
|
4534
4550
|
}
|
|
4535
4551
|
updatePin(pin, index) {
|
|
4552
|
+
var _a, _b;
|
|
4536
4553
|
if (!pin)
|
|
4537
4554
|
return;
|
|
4538
4555
|
let text = this.pinTexts[index];
|
|
4539
4556
|
let v = "";
|
|
4557
|
+
let ariaValueNow;
|
|
4540
4558
|
if (pin.mode & pxsim.PinFlags.Analog) {
|
|
4541
4559
|
v = Math.floor(100 - (pin.value || 0) / 1023 * 100) + "%";
|
|
4542
4560
|
if (text)
|
|
4543
4561
|
text.textContent = (pin.period ? "~" : "") + (pin.value || 0) + "";
|
|
4562
|
+
ariaValueNow = (_a = pin.value) !== null && _a !== void 0 ? _a : 0;
|
|
4544
4563
|
}
|
|
4545
4564
|
else if (pin.mode & pxsim.PinFlags.Digital) {
|
|
4546
4565
|
v = pin.value > 0 ? "0%" : "100%";
|
|
4547
4566
|
if (text)
|
|
4548
4567
|
text.textContent = pin.value > 0 ? "1" : "0";
|
|
4568
|
+
ariaValueNow = pin.value > 0 ? 1 : 0;
|
|
4549
4569
|
}
|
|
4550
4570
|
else if (pin.mode & pxsim.PinFlags.Touch) {
|
|
4551
4571
|
v = pin.touched ? "0%" : "100%";
|
|
@@ -4561,12 +4581,37 @@ path.sim-board {
|
|
|
4561
4581
|
pxsim.svg.setGradientValue(this.pinGradients[index], v);
|
|
4562
4582
|
if (pin.mode !== pxsim.PinFlags.Unused) {
|
|
4563
4583
|
pxsim.accessibility.makeFocusable(this.pins[index]);
|
|
4564
|
-
|
|
4565
|
-
|
|
4566
|
-
|
|
4567
|
-
|
|
4568
|
-
|
|
4569
|
-
|
|
4584
|
+
if (pin.mode & pxsim.PinFlags.Touch) {
|
|
4585
|
+
this.pins[index].setAttribute("role", "button");
|
|
4586
|
+
this.pins[index].ariaLabel = this.pins[index].firstChild.textContent;
|
|
4587
|
+
this.pins[index].removeAttribute("aria-valuemin");
|
|
4588
|
+
this.pins[index].removeAttribute("aria-valuemax");
|
|
4589
|
+
this.pins[index].removeAttribute("aria-orientation");
|
|
4590
|
+
this.pins[index].removeAttribute("aria-valuenow");
|
|
4591
|
+
this.pins[index].removeAttribute("aria-valuetext");
|
|
4592
|
+
this.pins[index].removeAttribute("aria-readonly");
|
|
4593
|
+
}
|
|
4594
|
+
else {
|
|
4595
|
+
this.pins[index].setAttribute("role", "slider");
|
|
4596
|
+
this.pins[index].ariaLabel = this.pins[index].firstChild.textContent;
|
|
4597
|
+
this.pins[index].setAttribute("aria-valuemin", "0");
|
|
4598
|
+
this.pins[index].setAttribute("aria-valuemax", pin.mode & pxsim.PinFlags.Analog ? "1023" : "1");
|
|
4599
|
+
this.pins[index].setAttribute("aria-orientation", "vertical");
|
|
4600
|
+
this.pins[index].setAttribute("aria-valuenow", (_b = ariaValueNow.toString()) !== null && _b !== void 0 ? _b : "");
|
|
4601
|
+
// Check that the text content isn't just a plain int and only set aria-valuetext if required.
|
|
4602
|
+
if ((text === null || text === void 0 ? void 0 : text.textContent) && (text === null || text === void 0 ? void 0 : text.textContent) !== parseInt(text === null || text === void 0 ? void 0 : text.textContent).toString()) {
|
|
4603
|
+
this.pins[index].setAttribute("aria-valuetext", text.textContent);
|
|
4604
|
+
}
|
|
4605
|
+
else {
|
|
4606
|
+
this.pins[index].removeAttribute("aria-valuetext");
|
|
4607
|
+
}
|
|
4608
|
+
if (pin.mode & pxsim.PinFlags.Input) {
|
|
4609
|
+
this.pins[index].removeAttribute("aria-readonly");
|
|
4610
|
+
}
|
|
4611
|
+
else {
|
|
4612
|
+
this.pins[index].setAttribute("aria-readonly", "true");
|
|
4613
|
+
}
|
|
4614
|
+
}
|
|
4570
4615
|
}
|
|
4571
4616
|
}
|
|
4572
4617
|
updateTemperature() {
|
|
@@ -4578,7 +4623,7 @@ path.sim-board {
|
|
|
4578
4623
|
if (!this.thermometerInitialized) {
|
|
4579
4624
|
this.thermometerInitialized = true;
|
|
4580
4625
|
this.thermometer.style.visibility = "visible";
|
|
4581
|
-
this.thermometerText = pxsim.svg.child(this.g, "text", { class: 'sim-text', x: 58, y: 130 });
|
|
4626
|
+
this.thermometerText = pxsim.svg.child(this.g, "text", { class: 'sim-text', x: 58, y: 130, "aria-hidden": true });
|
|
4582
4627
|
if (this.props.runtime)
|
|
4583
4628
|
this.props.runtime.environmentGlobals[pxsim.localization.lf("temperature")] = state.thermometerState.temperature;
|
|
4584
4629
|
this.updateTheme();
|
|
@@ -4597,26 +4642,14 @@ path.sim-board {
|
|
|
4597
4642
|
ev => { },
|
|
4598
4643
|
// keydown
|
|
4599
4644
|
(ev) => {
|
|
4600
|
-
|
|
4601
|
-
if (
|
|
4602
|
-
|
|
4603
|
-
state.thermometerState.temperature--;
|
|
4604
|
-
if (state.thermometerState.temperature < -5) {
|
|
4605
|
-
state.thermometerState.temperature = 50;
|
|
4606
|
-
}
|
|
4607
|
-
this.updateTemperature();
|
|
4608
|
-
}
|
|
4609
|
-
else if (charCode === 38 || charCode === 39) { // Up/Right arrow
|
|
4610
|
-
ev.preventDefault();
|
|
4611
|
-
state.thermometerState.temperature++;
|
|
4612
|
-
if (state.thermometerState.temperature > 50) {
|
|
4613
|
-
state.thermometerState.temperature = -5;
|
|
4614
|
-
}
|
|
4645
|
+
const value = commonKeyHandler(ev, state.thermometerState.temperature, tmin, tmax);
|
|
4646
|
+
if (value !== undefined) {
|
|
4647
|
+
state.thermometerState.temperature = value;
|
|
4615
4648
|
this.updateTemperature();
|
|
4616
4649
|
}
|
|
4617
4650
|
});
|
|
4618
4651
|
pxsim.accessibility.makeFocusable(this.thermometer);
|
|
4619
|
-
pxsim.accessibility.setAria(this.thermometer, "slider", pxsim.localization.lf("
|
|
4652
|
+
pxsim.accessibility.setAria(this.thermometer, "slider", pxsim.localization.lf("Temperature"));
|
|
4620
4653
|
this.thermometer.setAttribute("aria-valuemin", "-5");
|
|
4621
4654
|
this.thermometer.setAttribute("aria-valuemax", "50");
|
|
4622
4655
|
this.thermometer.setAttribute("aria-orientation", "vertical");
|
|
@@ -4629,7 +4662,6 @@ path.sim-board {
|
|
|
4629
4662
|
this.thermometerText.textContent = t + "°C";
|
|
4630
4663
|
this.thermometer.setAttribute("aria-valuenow", t.toString());
|
|
4631
4664
|
this.thermometer.setAttribute("aria-valuetext", t + "°C");
|
|
4632
|
-
pxsim.accessibility.setLiveContent(t + "°C");
|
|
4633
4665
|
}
|
|
4634
4666
|
updateSoundLevel() {
|
|
4635
4667
|
let state = this.board;
|
|
@@ -4641,7 +4673,7 @@ path.sim-board {
|
|
|
4641
4673
|
this.soundLevelInitialized = true;
|
|
4642
4674
|
this.soundLevel.style.visibility = "visible";
|
|
4643
4675
|
const level = state.microphoneState.getLevel();
|
|
4644
|
-
this.soundLevelText = pxsim.svg.child(this.g, "text", { class: 'sim-text', x: 370, y: 90 });
|
|
4676
|
+
this.soundLevelText = pxsim.svg.child(this.g, "text", { class: 'sim-text', x: 370, y: 90, "aria-hidden": true });
|
|
4645
4677
|
if (this.props.runtime)
|
|
4646
4678
|
this.props.runtime.environmentGlobals[pxsim.localization.lf("sound level")] = state.microphoneState.getLevel();
|
|
4647
4679
|
this.updateTheme();
|
|
@@ -4660,15 +4692,9 @@ path.sim-board {
|
|
|
4660
4692
|
ev => { },
|
|
4661
4693
|
// keydown
|
|
4662
4694
|
(ev) => {
|
|
4663
|
-
|
|
4664
|
-
if (
|
|
4665
|
-
|
|
4666
|
-
state.microphoneState.setLevel(state.microphoneState.getLevel() - 1);
|
|
4667
|
-
this.updateMicrophone();
|
|
4668
|
-
}
|
|
4669
|
-
else if (charCode === 38 || charCode === 39) { // Up/Right arrow
|
|
4670
|
-
ev.preventDefault();
|
|
4671
|
-
state.microphoneState.setLevel(state.microphoneState.getLevel() + 1);
|
|
4695
|
+
const value = commonKeyHandler(ev, state.microphoneState.getLevel(), tmin, tmax);
|
|
4696
|
+
if (value !== undefined) {
|
|
4697
|
+
state.microphoneState.setLevel(value);
|
|
4672
4698
|
this.updateMicrophone();
|
|
4673
4699
|
}
|
|
4674
4700
|
});
|
|
@@ -4686,7 +4712,6 @@ path.sim-board {
|
|
|
4686
4712
|
this.soundLevelText.textContent = t + "";
|
|
4687
4713
|
this.soundLevel.setAttribute("aria-valuenow", t.toString());
|
|
4688
4714
|
this.soundLevel.setAttribute("aria-valuetext", t + "");
|
|
4689
|
-
pxsim.accessibility.setLiveContent(t + "");
|
|
4690
4715
|
}
|
|
4691
4716
|
updateHeading() {
|
|
4692
4717
|
let xc = 258;
|
|
@@ -4714,23 +4739,9 @@ path.sim-board {
|
|
|
4714
4739
|
ev => { },
|
|
4715
4740
|
// keydown
|
|
4716
4741
|
(ev) => {
|
|
4717
|
-
|
|
4718
|
-
if (
|
|
4719
|
-
|
|
4720
|
-
state.compassState.heading--;
|
|
4721
|
-
if (state.compassState.heading < 0)
|
|
4722
|
-
state.compassState.heading += 360;
|
|
4723
|
-
if (state.compassState.heading >= 360)
|
|
4724
|
-
state.compassState.heading %= 360;
|
|
4725
|
-
this.updateHeading();
|
|
4726
|
-
}
|
|
4727
|
-
else if (charCode === 38 || charCode === 39) { // Up/Right arrow
|
|
4728
|
-
ev.preventDefault();
|
|
4729
|
-
state.compassState.heading++;
|
|
4730
|
-
if (state.compassState.heading < 0)
|
|
4731
|
-
state.compassState.heading += 360;
|
|
4732
|
-
if (state.compassState.heading >= 360)
|
|
4733
|
-
state.compassState.heading %= 360;
|
|
4742
|
+
const value = commonKeyHandler(ev, state.compassState.heading, 0, 359);
|
|
4743
|
+
if (value !== undefined) {
|
|
4744
|
+
state.compassState.heading = value;
|
|
4734
4745
|
this.updateHeading();
|
|
4735
4746
|
}
|
|
4736
4747
|
});
|
|
@@ -4757,6 +4768,7 @@ path.sim-board {
|
|
|
4757
4768
|
}
|
|
4758
4769
|
}
|
|
4759
4770
|
flashAntenna() {
|
|
4771
|
+
var _a;
|
|
4760
4772
|
if (!this.antennaInitialized) {
|
|
4761
4773
|
this.antenna.style.visibility = "visible";
|
|
4762
4774
|
this.antennaInitialized = true;
|
|
@@ -4778,27 +4790,21 @@ path.sim-board {
|
|
|
4778
4790
|
};
|
|
4779
4791
|
const keyboardEventHandler = (ev) => {
|
|
4780
4792
|
var _a;
|
|
4781
|
-
const
|
|
4782
|
-
|
|
4783
|
-
|
|
4784
|
-
ev.preventDefault();
|
|
4785
|
-
setValue(rs - 1);
|
|
4786
|
-
}
|
|
4787
|
-
else if (charCode === 38 || charCode === 39) { // Up/Right arrow
|
|
4788
|
-
ev.preventDefault();
|
|
4789
|
-
setValue(rs + 1);
|
|
4793
|
+
const value = commonKeyHandler(ev, (_a = this.board.radioState.datagram.rssi) !== null && _a !== void 0 ? _a : -75, valueMin, valueMax);
|
|
4794
|
+
if (value !== undefined) {
|
|
4795
|
+
setValue(value);
|
|
4790
4796
|
}
|
|
4791
4797
|
};
|
|
4792
4798
|
pxsim.svg.buttonEvents(this.antenna.children[0], mouseEventHandler, mouseEventHandler, mouseEventHandler, () => { });
|
|
4793
4799
|
pxsim.svg.buttonEvents(this.antenna.children[1], mouseEventHandler, mouseEventHandler, mouseEventHandler, () => { });
|
|
4794
4800
|
this.antenna.addEventListener('keydown', keyboardEventHandler);
|
|
4795
4801
|
pxsim.accessibility.makeFocusable(this.antenna);
|
|
4796
|
-
pxsim.accessibility.setAria(this.antenna, "slider", "
|
|
4802
|
+
pxsim.accessibility.setAria(this.antenna, "slider", pxsim.localization.lf("Received Signal Strength Indicator"));
|
|
4803
|
+
;
|
|
4797
4804
|
this.antenna.setAttribute("aria-valuemin", `${valueMin}`);
|
|
4798
4805
|
this.antenna.setAttribute("aria-valuemax", `${valueMax}`);
|
|
4799
4806
|
this.antenna.setAttribute("aria-orientation", "horizontal");
|
|
4800
|
-
this.antenna.setAttribute("aria-valuenow",
|
|
4801
|
-
pxsim.accessibility.setLiveContent("");
|
|
4807
|
+
this.antenna.setAttribute("aria-valuenow", ((_a = this.board.radioState.datagram.rssi) !== null && _a !== void 0 ? _a : -75).toString());
|
|
4802
4808
|
}
|
|
4803
4809
|
let now = Date.now();
|
|
4804
4810
|
if (now - this.lastAntennaFlash > 200) {
|
|
@@ -4819,14 +4825,13 @@ path.sim-board {
|
|
|
4819
4825
|
let ayb = 40;
|
|
4820
4826
|
for (let i = 0; i < 4; ++i)
|
|
4821
4827
|
pxsim.svg.child(this.g, "rect", { x: ANTENNA_X - 90 + i * 6, y: ayt + 28 - i * 4, width: 4, height: 2 + i * 4, fill: "#fff" });
|
|
4822
|
-
this.rssi = pxsim.svg.child(this.g, "text", { x: ANTENNA_X - 64, y: ayb, class: "sim-text" });
|
|
4828
|
+
this.rssi = pxsim.svg.child(this.g, "text", { x: ANTENNA_X - 64, y: ayb, class: "sim-text", "aria-hidden": true });
|
|
4823
4829
|
this.rssi.textContent = "";
|
|
4824
4830
|
}
|
|
4825
4831
|
const vt = v.toString();
|
|
4826
4832
|
if (vt !== this.rssi.textContent) {
|
|
4827
4833
|
this.rssi.textContent = v.toString();
|
|
4828
4834
|
this.antenna.setAttribute("aria-valuenow", this.rssi.textContent);
|
|
4829
|
-
pxsim.accessibility.setLiveContent(this.rssi.textContent);
|
|
4830
4835
|
}
|
|
4831
4836
|
}
|
|
4832
4837
|
updatePins() {
|
|
@@ -4860,30 +4865,18 @@ path.sim-board {
|
|
|
4860
4865
|
ev => { },
|
|
4861
4866
|
// keydown
|
|
4862
4867
|
(ev) => {
|
|
4863
|
-
|
|
4864
|
-
if (
|
|
4865
|
-
|
|
4866
|
-
this.
|
|
4867
|
-
if (this.board.lightSensorState.lightLevel < 0) {
|
|
4868
|
-
this.board.lightSensorState.lightLevel = 255;
|
|
4869
|
-
}
|
|
4870
|
-
this.applyLightLevel();
|
|
4871
|
-
}
|
|
4872
|
-
else if (charCode === 38 || charCode === 39) { // Up/Right arrow
|
|
4873
|
-
ev.preventDefault();
|
|
4874
|
-
this.board.lightSensorState.lightLevel++;
|
|
4875
|
-
if (this.board.lightSensorState.lightLevel > 255) {
|
|
4876
|
-
this.board.lightSensorState.lightLevel = 0;
|
|
4877
|
-
}
|
|
4878
|
-
this.applyLightLevel();
|
|
4868
|
+
const value = commonKeyHandler(ev, state.lightSensorState.lightLevel, 0, 255);
|
|
4869
|
+
if (value !== undefined) {
|
|
4870
|
+
state.lightSensorState.lightLevel = value;
|
|
4871
|
+
this.updateLightLevel();
|
|
4879
4872
|
}
|
|
4880
4873
|
});
|
|
4881
|
-
this.lightLevelText = pxsim.svg.child(this.g, "text", { x: 85, y: LIGHT_LEVEL_BUTTON_POSITION_Y + LIGHT_LEVEL_BUTTON_RADIUS - 5, text: '', class: 'sim-text' });
|
|
4874
|
+
this.lightLevelText = pxsim.svg.child(this.g, "text", { x: 85, y: LIGHT_LEVEL_BUTTON_POSITION_Y + LIGHT_LEVEL_BUTTON_RADIUS - 5, text: '', class: 'sim-text', 'aria-hidden': true });
|
|
4882
4875
|
if (this.props.runtime)
|
|
4883
4876
|
this.props.runtime.environmentGlobals[pxsim.localization.lf("lightLevel")] = state.lightSensorState.lightLevel;
|
|
4884
4877
|
this.updateTheme();
|
|
4885
4878
|
pxsim.accessibility.makeFocusable(this.lightLevelButton);
|
|
4886
|
-
pxsim.accessibility.setAria(this.lightLevelButton, "slider", "Light level");
|
|
4879
|
+
pxsim.accessibility.setAria(this.lightLevelButton, "slider", pxsim.localization.lf("Light level"));
|
|
4887
4880
|
this.lightLevelButton.setAttribute("aria-valuemin", "0");
|
|
4888
4881
|
this.lightLevelButton.setAttribute("aria-valuemax", "255");
|
|
4889
4882
|
this.lightLevelButton.setAttribute("aria-orientation", "vertical");
|
|
@@ -4897,7 +4890,6 @@ path.sim-board {
|
|
|
4897
4890
|
pxsim.svg.setGradientValue(this.lightLevelGradient, Math.min(100, Math.max(0, Math.floor(lv * 100 / 255))) + '%');
|
|
4898
4891
|
this.lightLevelText.textContent = lv.toString();
|
|
4899
4892
|
this.lightLevelButton.setAttribute("aria-valuenow", lv.toString());
|
|
4900
|
-
pxsim.accessibility.setLiveContent(lv.toString());
|
|
4901
4893
|
}
|
|
4902
4894
|
findParentElement() {
|
|
4903
4895
|
let el = this.element;
|
|
@@ -4936,21 +4928,21 @@ path.sim-board {
|
|
|
4936
4928
|
// update text
|
|
4937
4929
|
if (acc.flags & pxsim.AccelerometerFlag.X) {
|
|
4938
4930
|
if (!this.accTextX) {
|
|
4939
|
-
this.accTextX = pxsim.svg.child(this.g, "text", { x: 365, y: 260, class: "sim-text" });
|
|
4931
|
+
this.accTextX = pxsim.svg.child(this.g, "text", { x: 365, y: 260, class: "sim-text", "aria-hidden": true });
|
|
4940
4932
|
this.accTextX.textContent = "";
|
|
4941
4933
|
}
|
|
4942
4934
|
this.accTextX.textContent = `ax:${x}`;
|
|
4943
4935
|
}
|
|
4944
4936
|
if (acc.flags & pxsim.AccelerometerFlag.Y) {
|
|
4945
4937
|
if (!this.accTextY) {
|
|
4946
|
-
this.accTextY = pxsim.svg.child(this.g, "text", { x: 365, y: 285, class: "sim-text" });
|
|
4938
|
+
this.accTextY = pxsim.svg.child(this.g, "text", { x: 365, y: 285, class: "sim-text", "aria-hidden": true });
|
|
4947
4939
|
this.accTextY.textContent = "";
|
|
4948
4940
|
}
|
|
4949
4941
|
this.accTextY.textContent = `ay:${-y}`;
|
|
4950
4942
|
}
|
|
4951
4943
|
if (acc.flags & pxsim.AccelerometerFlag.Z) {
|
|
4952
4944
|
if (!this.accTextZ) {
|
|
4953
|
-
this.accTextZ = pxsim.svg.child(this.g, "text", { x: 365, y: 310, class: "sim-text" });
|
|
4945
|
+
this.accTextZ = pxsim.svg.child(this.g, "text", { x: 365, y: 310, class: "sim-text", "aria-hidden": true });
|
|
4954
4946
|
this.accTextZ.textContent = "";
|
|
4955
4947
|
}
|
|
4956
4948
|
this.accTextZ.textContent = `az:${z}`;
|
|
@@ -4968,7 +4960,9 @@ path.sim-board {
|
|
|
4968
4960
|
"y": "0px",
|
|
4969
4961
|
"width": MB_WIDTH + "px",
|
|
4970
4962
|
"height": MB_HEIGHT + "px",
|
|
4971
|
-
"fill": "rgba(0,0,0,0)"
|
|
4963
|
+
"fill": "rgba(0,0,0,0)",
|
|
4964
|
+
// Allows screen reader users to interact with board properly.
|
|
4965
|
+
"role": "application"
|
|
4972
4966
|
});
|
|
4973
4967
|
this.style = pxsim.svg.child(this.element, "style", {});
|
|
4974
4968
|
this.style.textContent = MB_STYLE + (this.props.theme.highContrast ? MB_HIGHCONTRAST : "");
|
|
@@ -5095,7 +5089,7 @@ path.sim-board {
|
|
|
5095
5089
|
this.heads.push(pxsim.svg.path(this.headParts, "sim-theme", "M269.9,50.2L269.9,50.2l-39.5,0v0c-14.1,0.1-24.6,10.7-24.6,24.8c0,13.9,10.4,24.4,24.3,24.7v0h39.6c14.2,0,24.8-10.6,24.8-24.7C294.5,61,284,50.3,269.9,50.2 M269.7,89.2L269.7,89.2l-39.3,0c-7.7-0.1-14-6.4-14-14.2c0-7.8,6.4-14.2,14.2-14.2h39.1c7.8,0,14.2,6.4,14.2,14.2C283.9,82.9,277.5,89.2,269.7,89.2"));
|
|
5096
5090
|
this.heads.push(pxsim.svg.path(this.headParts, "sim-theme", "M230.6,69.7c-2.9,0-5.3,2.4-5.3,5.3c0,2.9,2.4,5.3,5.3,5.3c2.9,0,5.3-2.4,5.3-5.3C235.9,72.1,233.5,69.7,230.6,69.7"));
|
|
5097
5091
|
this.heads.push(pxsim.svg.path(this.headParts, "sim-theme", "M269.7,80.3c2.9,0,5.3-2.4,5.3-5.3c0-2.9-2.4-5.3-5.3-5.3c-2.9,0-5.3,2.4-5.3,5.3C264.4,77.9,266.8,80.3,269.7,80.3"));
|
|
5098
|
-
this.headText = pxsim.svg.child(this.g, "text", { x: 160, y: 60, class: "sim-text" });
|
|
5092
|
+
this.headText = pxsim.svg.child(this.g, "text", { x: 160, y: 60, class: "sim-text", "aria-hidden": true });
|
|
5099
5093
|
}
|
|
5100
5094
|
buildPinElements() {
|
|
5101
5095
|
// https://www.microbit.co.uk/device/pins
|
|
@@ -5119,7 +5113,7 @@ path.sim-board {
|
|
|
5119
5113
|
this.pins = pinDrawOrder.reduce((pins, pinName) => {
|
|
5120
5114
|
const simPinIndex = pinNames.indexOf(pinName);
|
|
5121
5115
|
const newPin = drawList[simPinIndex]();
|
|
5122
|
-
pxsim.svg.hydrate(newPin, { title: pinTitles[simPinIndex] });
|
|
5116
|
+
pxsim.svg.hydrate(newPin, { title: pinTitles[simPinIndex].ariaLabel });
|
|
5123
5117
|
pins[simPinIndex] = newPin;
|
|
5124
5118
|
return pins;
|
|
5125
5119
|
}, new Array(pinDrawOrder.length));
|
|
@@ -5129,7 +5123,7 @@ path.sim-board {
|
|
|
5129
5123
|
pin.setAttribute("fill", `url(#${gid})`);
|
|
5130
5124
|
return lg;
|
|
5131
5125
|
});
|
|
5132
|
-
this.pinTexts = [67, 165, 275].map(x => pxsim.svg.child(this.g, "text", { class: "sim-text-pin", x: x, y: 345 }));
|
|
5126
|
+
this.pinTexts = [67, 165, 275].map(x => pxsim.svg.child(this.g, "text", { class: "sim-text-pin", x: x, y: 345, "aria-hidden": true }));
|
|
5133
5127
|
pxsim.svg.path(this.g, "sim-label", "M35.7,376.4c0-2.8,2.1-5.1,5.5-5.1c3.3,0,5.5,2.4,5.5,5.1v4.7c0,2.8-2.2,5.1-5.5,5.1c-3.3,0-5.5-2.4-5.5-5.1V376.4zM43.3,376.4c0-1.3-0.8-2.3-2.2-2.3c-1.3,0-2.1,1.1-2.1,2.3v4.7c0,1.2,0.8,2.3,2.1,2.3c1.3,0,2.2-1.1,2.2-2.3V376.4z");
|
|
5134
5128
|
pxsim.svg.path(this.g, "sim-label", "M136.2,374.1c2.8,0,3.4-0.8,3.4-2.5h2.9v14.3h-3.4v-9.5h-3V374.1z");
|
|
5135
5129
|
pxsim.svg.path(this.g, "sim-label", "M248.6,378.5c1.7-1,3-1.7,3-3.1c0-1.1-0.7-1.6-1.6-1.6c-1,0-1.8,0.6-1.8,2.1h-3.3c0-2.6,1.8-4.6,5.1-4.6c2.6,0,4.9,1.3,4.9,4.3c0,2.4-2.3,3.9-3.8,4.7c-2,1.3-2.5,1.8-2.5,2.9h6.1v2.7h-10C244.8,381.2,246.4,379.9,248.6,378.5z");
|
|
@@ -5199,7 +5193,7 @@ path.sim-board {
|
|
|
5199
5193
|
const title = pxsim.localization.lf("micro:bit v2 needed");
|
|
5200
5194
|
this.v2Circle = pxsim.svg.child(this.g, "circle", { r: 21, title: title });
|
|
5201
5195
|
pxsim.svg.fill(this.v2Circle, "white");
|
|
5202
|
-
this.v2Text = pxsim.svg.child(this.g, "text", { class: "sim-text", title: title });
|
|
5196
|
+
this.v2Text = pxsim.svg.child(this.g, "text", { class: "sim-text", title: title, "aria-hidden": true });
|
|
5203
5197
|
this.v2Text.textContent = "V2";
|
|
5204
5198
|
pxsim.svg.fill(this.v2Text, "black");
|
|
5205
5199
|
this.v2Text.style.fontWeight = "700";
|
|
@@ -5225,8 +5219,7 @@ path.sim-board {
|
|
|
5225
5219
|
this.microphoneLed = pxsim.svg.path(microg, "sim-led sim-mic", "M 352.852 71 C 351.315 71 350.07 72.248 350.07 73.784 V 79.056 C 350.07 80.594 351.316 81.838 352.852 81.838 C 354.387 81.838 355.634 80.593 355.634 79.056 V 73.784 C 355.634 72.248 354.387 71 352.852 71 Z M 346.743 79.981 C 346.743 82.84 348.853 85.062 351.501 85.658 V 87.095 H 348.448 V 89.329 H 357.366 V 87.095 H 354.306 V 85.658 C 356.954 85.064 359.071 82.842 359.071 79.981 H 357.057 C 357.057 82.174 355.168 83.81 352.905 83.81 C 350.64 83.81 348.757 82.173 348.757 79.981 Z");
|
|
5226
5220
|
pxsim.svg.fills([this.microphoneLed], this.props.theme.ledOff);
|
|
5227
5221
|
// ring
|
|
5228
|
-
|
|
5229
|
-
pxsim.svg.title(microhole, pxsim.localization.lf("microphone (micro:bit v2 needed)"));
|
|
5222
|
+
pxsim.svg.child(this.g, "circle", { cx: 336, cy: 86, r: 3, stroke: "gold", strokeWidth: "1px" });
|
|
5230
5223
|
this.updateMicrophone();
|
|
5231
5224
|
this.updateTheme();
|
|
5232
5225
|
}
|
|
@@ -5330,10 +5323,11 @@ path.sim-board {
|
|
|
5330
5323
|
let state = this.board;
|
|
5331
5324
|
let pin = state.edgeConnectorState.pins[index];
|
|
5332
5325
|
let svgpin = this.pins[index];
|
|
5333
|
-
if (pin.mode & pxsim.PinFlags.Input) {
|
|
5326
|
+
if (pin.mode & pxsim.PinFlags.Input && !(pin.mode & pxsim.PinFlags.Touch)) {
|
|
5334
5327
|
let cursor = pxsim.svg.cursorPoint(pt, this.element, ev);
|
|
5335
|
-
let
|
|
5336
|
-
|
|
5328
|
+
let maxValue = pin.mode & pxsim.PinFlags.Analog ? 1023 : 1;
|
|
5329
|
+
let v = (400 - cursor.y) / 40 * maxValue;
|
|
5330
|
+
pin.value = Math.max(0, Math.min(maxValue, Math.floor(v)));
|
|
5337
5331
|
}
|
|
5338
5332
|
this.updatePin(pin, index);
|
|
5339
5333
|
},
|
|
@@ -5343,10 +5337,11 @@ path.sim-board {
|
|
|
5343
5337
|
let pin = state.edgeConnectorState.pins[index];
|
|
5344
5338
|
let svgpin = this.pins[index];
|
|
5345
5339
|
pxsim.U.addClass(svgpin, "touched");
|
|
5346
|
-
if (pin.mode & pxsim.PinFlags.Input) {
|
|
5340
|
+
if (pin.mode & pxsim.PinFlags.Input && !(pin.mode & pxsim.PinFlags.Touch)) {
|
|
5347
5341
|
let cursor = pxsim.svg.cursorPoint(pt, this.element, ev);
|
|
5348
|
-
let
|
|
5349
|
-
|
|
5342
|
+
let maxValue = pin.mode & pxsim.PinFlags.Analog ? 1023 : 1;
|
|
5343
|
+
let v = (400 - cursor.y) / 40 * maxValue;
|
|
5344
|
+
pin.value = Math.max(0, Math.min(maxValue, Math.floor(v)));
|
|
5350
5345
|
}
|
|
5351
5346
|
this.updatePin(pin, index);
|
|
5352
5347
|
},
|
|
@@ -5361,23 +5356,11 @@ path.sim-board {
|
|
|
5361
5356
|
},
|
|
5362
5357
|
// keydown
|
|
5363
5358
|
(ev) => {
|
|
5364
|
-
|
|
5365
|
-
|
|
5366
|
-
|
|
5367
|
-
if (
|
|
5368
|
-
|
|
5369
|
-
pin.value -= 10;
|
|
5370
|
-
if (pin.value < 0) {
|
|
5371
|
-
pin.value = 1023;
|
|
5372
|
-
}
|
|
5373
|
-
this.updatePin(pin, index);
|
|
5374
|
-
}
|
|
5375
|
-
else if (charCode === 38 || charCode === 39) { // Up/Right arrow
|
|
5376
|
-
ev.preventDefault();
|
|
5377
|
-
pin.value += 10;
|
|
5378
|
-
if (pin.value > 1023) {
|
|
5379
|
-
pin.value = 0;
|
|
5380
|
-
}
|
|
5359
|
+
const state = this.board;
|
|
5360
|
+
const pin = state.edgeConnectorState.pins[index];
|
|
5361
|
+
const value = pinKeyHandler(ev, pin.value, 0, pin.mode & pxsim.PinFlags.Analog ? 1023 : 1, pin.mode);
|
|
5362
|
+
if (value !== undefined) {
|
|
5363
|
+
pin.value = value;
|
|
5381
5364
|
this.updatePin(pin, index);
|
|
5382
5365
|
}
|
|
5383
5366
|
});
|
|
@@ -5523,6 +5506,65 @@ path.sim-board {
|
|
|
5523
5506
|
}
|
|
5524
5507
|
}
|
|
5525
5508
|
visuals.MicrobitBoardSvg = MicrobitBoardSvg;
|
|
5509
|
+
const isHandledKey = (key) => {
|
|
5510
|
+
return ["ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight", "PageUp", "PageDown", "Home", "End"].includes(key);
|
|
5511
|
+
};
|
|
5512
|
+
const getSliderStepValue = (min, max) => {
|
|
5513
|
+
const range = max - min;
|
|
5514
|
+
// Assumes slider values are always integers.
|
|
5515
|
+
return Math.max(1, Math.floor(range / 10));
|
|
5516
|
+
};
|
|
5517
|
+
const commonKeyHandler = (e, currentValue, min, max) => {
|
|
5518
|
+
const key = e.key;
|
|
5519
|
+
if (isHandledKey(key)) {
|
|
5520
|
+
e.preventDefault();
|
|
5521
|
+
}
|
|
5522
|
+
switch (key) {
|
|
5523
|
+
case "ArrowDown":
|
|
5524
|
+
case "ArrowLeft": {
|
|
5525
|
+
return Math.max(min, currentValue - 1);
|
|
5526
|
+
}
|
|
5527
|
+
case "ArrowUp":
|
|
5528
|
+
case "ArrowRight": {
|
|
5529
|
+
return Math.min(max, currentValue + 1);
|
|
5530
|
+
}
|
|
5531
|
+
case "Home": {
|
|
5532
|
+
return min;
|
|
5533
|
+
}
|
|
5534
|
+
case "End": {
|
|
5535
|
+
return max;
|
|
5536
|
+
}
|
|
5537
|
+
case "PageDown": {
|
|
5538
|
+
const step = getSliderStepValue(min, max);
|
|
5539
|
+
const value = currentValue - step;
|
|
5540
|
+
return Math.max(min, value);
|
|
5541
|
+
}
|
|
5542
|
+
case "PageUp": {
|
|
5543
|
+
const step = getSliderStepValue(min, max);
|
|
5544
|
+
const value = currentValue + step;
|
|
5545
|
+
return Math.min(max, value);
|
|
5546
|
+
}
|
|
5547
|
+
}
|
|
5548
|
+
return undefined;
|
|
5549
|
+
};
|
|
5550
|
+
const pinKeyHandler = (e, currentValue, min, max, pinMode) => {
|
|
5551
|
+
const key = e.key;
|
|
5552
|
+
if (isHandledKey(key)) {
|
|
5553
|
+
if (!(pinMode & pxsim.PinFlags.Input)) {
|
|
5554
|
+
e.preventDefault();
|
|
5555
|
+
pxsim.accessibility.setLiveContent(pxsim.localization.lf("This pin is read-only"));
|
|
5556
|
+
return undefined;
|
|
5557
|
+
}
|
|
5558
|
+
if (pinMode & pxsim.PinFlags.Touch) {
|
|
5559
|
+
// The pin is in touch mode and has button markup, not a slider.
|
|
5560
|
+
e.preventDefault();
|
|
5561
|
+
return undefined;
|
|
5562
|
+
}
|
|
5563
|
+
}
|
|
5564
|
+
// The pin value for a digital pin may be higher than 1 depending on how its value was set.
|
|
5565
|
+
const currentValueClamped = Math.min(max, currentValue);
|
|
5566
|
+
return commonKeyHandler(e, currentValueClamped, min, max);
|
|
5567
|
+
};
|
|
5526
5568
|
})(visuals = pxsim.visuals || (pxsim.visuals = {}));
|
|
5527
5569
|
})(pxsim || (pxsim = {}));
|
|
5528
5570
|
var pxsim;
|