-
Notifications
You must be signed in to change notification settings - Fork 6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
PhET-iO instrumentation of Preferences and its dialog #744
Comments
What about an instrumented Property that stored whether or not preferences should be stored? Then you can turn it on and off. |
|
@zepumph based on our discussion in the last PhET-iO meeting, I think |
This blocks publication of Friction when published with Voicing (preferences) and also PhET-iO. |
In #743 (comment) we decided that this issue is blocked by that one. Marking accordingly. |
During PhET-iO meeting today, we decided that preferences Properties would not be stateful. If in the future clients desire this feature, then we can discuss making it possible. We also decided that it is acceptable and helpful to have data stream capabilities, so that a researcher could look at learners that use voicing or not (for example). This feels helpful to the goals of PhET-iO.
|
I got pretty far with initial instrumentation, but ran into a bug when trying to alert a description to aria live. I'll have to come back to this. Index: phet-io-wrappers/input-record-and-playback/inputRecordAndPlayback.js
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/phet-io-wrappers/input-record-and-playback/inputRecordAndPlayback.js b/phet-io-wrappers/input-record-and-playback/inputRecordAndPlayback.js
--- a/phet-io-wrappers/input-record-and-playback/inputRecordAndPlayback.js (revision 17e332da4b14b43f1a54f7f00e87ffa278e05ec1)
+++ b/phet-io-wrappers/input-record-and-playback/inputRecordAndPlayback.js (date 1647380181461)
@@ -75,6 +75,14 @@
} );
} );
}, 10 );
+
+
+ for ( let i = 0; i < sourceFrame.contentWindow.ALL_NODES.length; i++ ) {
+ if ( sourceFrame.contentWindow.ALL_NODES[ i ] !== destinationFrame.contentWindow.ALL_NODES[ i ] ) {
+ debugger;
+ }
+ }
+
} );
const setActivePropertyUpstreamSim = active => sourceClient.invoke( activePropertyPhetioID, 'setValue', [ active ] );
Index: joist/js/A11yButtonsHBox.js
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/joist/js/A11yButtonsHBox.js b/joist/js/A11yButtonsHBox.js
--- a/joist/js/A11yButtonsHBox.js (revision 6f617114eef353e72bea7319355af3d753269558)
+++ b/joist/js/A11yButtonsHBox.js (date 1647380543570)
@@ -40,7 +40,7 @@
const preferencesButton = new NavigationBarPreferencesButton(
sim.preferencesManager,
backgroundColorProperty, {
- tandem: options.tandem.createTandem( 'navigationBarPreferencesButton' )
+ tandem: options.tandem.createTandem( 'preferencesButton' )
} );
a11yButtons.push( preferencesButton );
Index: joist/js/preferences/PreferencesToggleSwitch.js
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/joist/js/preferences/PreferencesToggleSwitch.js b/joist/js/preferences/PreferencesToggleSwitch.js
--- a/joist/js/preferences/PreferencesToggleSwitch.js (revision 6f617114eef353e72bea7319355af3d753269558)
+++ b/joist/js/preferences/PreferencesToggleSwitch.js (date 1647381019873)
@@ -50,8 +50,8 @@
trackFillRight: '#64bd5a'
},
- // phet-io - opting out of Tandems for now
- tandem: Tandem.OPT_OUT
+ // phet-io
+ tandem: Tandem.REQUIRED
}, options );
assert && assert( options.labelNode === null || options.labelNode instanceof Node, 'labelNode is null or inserted as child' );
assert && assert( options.descriptionNode === null || options.descriptionNode instanceof Node, 'labelNode is null or inserted as child' );
@@ -75,8 +75,8 @@
voicingIgnoreVoicingManagerProperties: true,
voicingNameResponse: options.a11yLabel,
- // tandem - opting out of Tandems for now
- tandem: Tandem.OPT_OUT
+ // tandem
+ tandem: options.tandem.createTandem( 'toggleSwitch' )
} ) );
this.addChild( toggleSwitch );
Index: joist/js/preferences/GeneralPreferencesPanel.js
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/joist/js/preferences/GeneralPreferencesPanel.js b/joist/js/preferences/GeneralPreferencesPanel.js
--- a/joist/js/preferences/GeneralPreferencesPanel.js (revision 6f617114eef353e72bea7319355af3d753269558)
+++ b/joist/js/preferences/GeneralPreferencesPanel.js (date 1647382221566)
@@ -8,8 +8,8 @@
*/
import merge from '../../../phet-core/js/merge.js';
-import { VoicingRichText } from '../../../scenery/js/imports.js';
-import { VBox } from '../../../scenery/js/imports.js';
+import { VBox, VoicingRichText } from '../../../scenery/js/imports.js';
+import Tandem from '../../../tandem/js/Tandem.js';
import joist from '../joist.js';
import joistStrings from '../joistStrings.js';
import PreferencesDialog from './PreferencesDialog.js';
@@ -23,17 +23,24 @@
/**
* @param {Object} generalModel - configuration for the Tab, see PreferencesManager for entries
+ * @param {Object} [options]
*/
- constructor( generalModel ) {
- super( {
+ constructor( generalModel, options ) {
+
+ options = merge( {
align: 'left',
spacing: 40,
// pdom
tagName: 'section',
labelTagName: 'h2',
- labelContent: 'General'
- } );
+ labelContent: 'General',
+
+ // phet-io
+ tandem: Tandem.REQUIRED
+ }, options );
+
+ super( options );
const panelChildren = [];
generalModel.simControls && panelChildren.push( new SimControlsPanelSection( generalModel.simControls ) );
Index: joist/js/toolbar/Toolbar.js
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/joist/js/toolbar/Toolbar.js b/joist/js/toolbar/Toolbar.js
--- a/joist/js/toolbar/Toolbar.js (revision 6f617114eef353e72bea7319355af3d753269558)
+++ b/joist/js/toolbar/Toolbar.js (date 1647381873479)
@@ -18,11 +18,8 @@
import stepTimer from '../../../axon/js/stepTimer.js';
import Matrix3 from '../../../dot/js/Matrix3.js';
import { Shape } from '../../../kite/js/imports.js';
-import { voicingManager } from '../../../scenery/js/imports.js';
-import { voicingUtteranceQueue } from '../../../scenery/js/imports.js';
-import { Node } from '../../../scenery/js/imports.js';
-import { Path } from '../../../scenery/js/imports.js';
-import { Rectangle } from '../../../scenery/js/imports.js';
+import merge from '../../../phet-core/js/merge.js';
+import { Node, Path, Rectangle, voicingManager, voicingUtteranceQueue } from '../../../scenery/js/imports.js';
import ButtonNode from '../../../sun/js/buttons/ButtonNode.js';
import RoundPushButton from '../../../sun/js/buttons/RoundPushButton.js';
import Tandem from '../../../tandem/js/Tandem.js';
@@ -48,14 +45,20 @@
/**
* @param {Sim} sim
+ * @param {Object} [options]
*/
- constructor( sim ) {
+ constructor( sim, options ) {
- super( {
+ options = merge( {
// pdom
- tagName: 'div'
- } );
+ tagName: 'div',
+
+ // phet-io
+ tandem: Tandem.REQUIRED
+ }, options );
+
+ super( options );
// @private {BooleanProperty} - Whether or not the Toolbar is enabled (visible to the user)
this.isEnabledProperty = sim.preferencesManager.toolbarEnabledProperty;
@@ -89,7 +92,9 @@
// @private {VoicingToolbarItem} - Contents for the Toolbar, currently only controls related to the voicing
// feature.
const voicingAlertManager = new VoicingToolbarAlertManager( sim.screenProperty );
- this.menuContent = new VoicingToolbarItem( voicingAlertManager, sim.lookAndFeel );
+ this.menuContent = new VoicingToolbarItem( voicingAlertManager, sim.lookAndFeel, {
+ tandem: options.tandem.createTandem( 'menuContent' )
+ } );
// icon for the openButton
const chevronIcon = new DoubleChevron();
Index: joist/js/preferences/PreferencesTabs.js
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/joist/js/preferences/PreferencesTabs.js b/joist/js/preferences/PreferencesTabs.js
--- a/joist/js/preferences/PreferencesTabs.js (revision 6f617114eef353e72bea7319355af3d753269558)
+++ b/joist/js/preferences/PreferencesTabs.js (date 1647382546235)
@@ -8,15 +8,9 @@
*/
import Property from '../../../axon/js/Property.js';
+import merge from '../../../phet-core/js/merge.js';
import StringUtils from '../../../phetcommon/js/util/StringUtils.js';
-import { FocusHighlightPath } from '../../../scenery/js/imports.js';
-import { KeyboardUtils } from '../../../scenery/js/imports.js';
-import { Voicing } from '../../../scenery/js/imports.js';
-import { PressListener } from '../../../scenery/js/imports.js';
-import { Line } from '../../../scenery/js/imports.js';
-import { Node } from '../../../scenery/js/imports.js';
-import { Rectangle } from '../../../scenery/js/imports.js';
-import { Text } from '../../../scenery/js/imports.js';
+import { FocusHighlightPath, KeyboardUtils, Line, Node, PressListener, Rectangle, Text, Voicing } from '../../../scenery/js/imports.js';
import Tandem from '../../../tandem/js/Tandem.js';
import joist from '../joist.js';
import joistStrings from '../joistStrings.js';
@@ -34,14 +28,21 @@
/**
* @param {PreferencesTab[]} supportedTabs - list of tabs the Dialog should include
* @param {EnumerationDeprecatedProperty.<PreferencesDialog.PreferenceTab>} selectedPanelProperty
+ * @param {Object} [options]
*/
- constructor( supportedTabs, selectedPanelProperty ) {
- super( {
+ constructor( supportedTabs, selectedPanelProperty, options ) {
+ options = merge( {
+ // pdom
tagName: 'ul',
ariaRole: 'tablist',
- groupFocusHighlight: true
- } );
+ groupFocusHighlight: true,
+
+ // phet-io
+ tandem: Tandem.REQUIRED
+ }, options );
+
+ super( options );
// @private {null|Node} - A reference to the selected and focusable tab content so that we can determine which
// tab is next in order when cycling through with alternative input.
@@ -52,13 +53,14 @@
// @private {Tab[]}
this.content = [];
- const addTabIfSupported = ( preferenceTab, titleString ) => {
- _.includes( supportedTabs, preferenceTab ) && this.content.push( new Tab( titleString, selectedPanelProperty, preferenceTab ) );
+ const addTabIfSupported = ( preferenceTab, titleString, tandemName ) => {
+ const tandem = options.tandem.createTandem( tandemName );
+ _.includes( supportedTabs, preferenceTab ) && this.content.push( new Tab( titleString, selectedPanelProperty, preferenceTab, tandem ) );
};
- addTabIfSupported( PreferencesDialog.PreferencesTab.GENERAL, generalTitleString );
- addTabIfSupported( PreferencesDialog.PreferencesTab.VISUAL, visualTitleString );
- addTabIfSupported( PreferencesDialog.PreferencesTab.AUDIO, audioTitleString );
- addTabIfSupported( PreferencesDialog.PreferencesTab.INPUT, inputTitleString );
+ addTabIfSupported( PreferencesDialog.PreferencesTab.GENERAL, generalTitleString, 'generalTab' );
+ addTabIfSupported( PreferencesDialog.PreferencesTab.VISUAL, visualTitleString, 'visualTab' );
+ addTabIfSupported( PreferencesDialog.PreferencesTab.AUDIO, audioTitleString, 'audioTab' );
+ addTabIfSupported( PreferencesDialog.PreferencesTab.INPUT, inputTitleString, 'audioTab' );
for ( let i = 0; i < this.content.length; i++ ) {
this.addChild( this.content[ i ] );
@@ -154,7 +156,7 @@
* @param {EnumerationDeprecatedProperty.<PreferencesDialog.<PreferencesTab>} property
* @param {PreferencesDialog.PreferencesTab} value - PreferencesTab shown when this tab is selected
*/
- constructor( label, property, value ) {
+ constructor( label, property, value, tandem ) {
const textNode = new Text( label, PreferencesDialog.TAB_OPTIONS );
@@ -178,7 +180,9 @@
innerContent: label,
ariaRole: 'tab',
focusable: true,
- containerTagName: 'li'
+ containerTagName: 'li',
+
+ tandem: tandem
} );
// @public {PreferenceTab}
@@ -188,7 +192,7 @@
title: label
} );
- const buttonListener = new PressListener( {
+ const pressListener = new PressListener( {
press: () => {
property.set( value );
@@ -196,12 +200,12 @@
this.voicingSpeakNameResponse();
},
- // phet-io - opting out for now to get CT working
- tandem: Tandem.OPT_OUT
+ // phet-io
+ tandem: tandem.createTandem( 'pressListener' )
} );
- this.addInputListener( buttonListener );
+ this.addInputListener( pressListener );
- Property.multilink( [ property, buttonListener.isOverProperty ], ( selectedTab, isOver ) => {
+ Property.multilink( [ property, pressListener.isOverProperty ], ( selectedTab, isOver ) => {
textNode.opacity = selectedTab === value ? 1 :
isOver ? 0.8 :
0.6;
Index: joist/js/toolbar/VoicingToolbarItem.js
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/joist/js/toolbar/VoicingToolbarItem.js b/joist/js/toolbar/VoicingToolbarItem.js
--- a/joist/js/toolbar/VoicingToolbarItem.js (revision 6f617114eef353e72bea7319355af3d753269558)
+++ b/joist/js/toolbar/VoicingToolbarItem.js (date 1647381946682)
@@ -8,15 +8,10 @@
*/
import BooleanProperty from '../../../axon/js/BooleanProperty.js';
+import merge from '../../../phet-core/js/merge.js';
import PlayStopButton from '../../../scenery-phet/js/buttons/PlayStopButton.js';
import PhetFont from '../../../scenery-phet/js/PhetFont.js';
-import { VoicingText } from '../../../scenery/js/imports.js';
-import { ReadingBlockHighlight } from '../../../scenery/js/imports.js';
-import { voicingManager } from '../../../scenery/js/imports.js';
-import { AlignGroup } from '../../../scenery/js/imports.js';
-import { HBox } from '../../../scenery/js/imports.js';
-import { Node } from '../../../scenery/js/imports.js';
-import { Text } from '../../../scenery/js/imports.js';
+import { AlignGroup, HBox, Node, ReadingBlockHighlight, Text, voicingManager, VoicingText } from '../../../scenery/js/imports.js';
import Tandem from '../../../tandem/js/Tandem.js';
import Utterance from '../../../utterance-queue/js/Utterance.js';
import joist from '../joist.js';
@@ -46,16 +41,21 @@
/**
* @param {VoicingToolbarAlertManager} alertManager - generates the alert content when buttons are pressed
* @param {LookAndFeel} lookAndFeel
+ * @param {Object} [options]
*/
- constructor( alertManager, lookAndFeel ) {
-
- super( {
+ constructor( alertManager, lookAndFeel, options ) {
+ options = merge( {
// pdom
tagName: 'section',
labelTagName: 'h2',
- labelContent: toolbarString
- } );
+ labelContent: toolbarString,
+
+ // phet-io
+ tandem: Tandem.REQUIRED
+ }, options );
+
+ super( options );
const titleTextOptions = {
font: new PhetFont( 14 ),
@@ -76,7 +76,8 @@
a11yLabel: titleString,
toggleSwitchOptions: {
voicingUtteranceQueue: joistVoicingUtteranceQueue
- }
+ },
+ tandem: options.tandem.createTandem( 'muteSpeechSwitch' )
} );
// layout
Index: joist/js/preferences/SoundPanelSection.js
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/joist/js/preferences/SoundPanelSection.js b/joist/js/preferences/SoundPanelSection.js
--- a/joist/js/preferences/SoundPanelSection.js (revision 6f617114eef353e72bea7319355af3d753269558)
+++ b/joist/js/preferences/SoundPanelSection.js (date 1647381462367)
@@ -8,11 +8,7 @@
import merge from '../../../phet-core/js/merge.js';
import StringUtils from '../../../phetcommon/js/util/StringUtils.js';
-import { VoicingRichText } from '../../../scenery/js/imports.js';
-import { VoicingText } from '../../../scenery/js/imports.js';
-import { voicingUtteranceQueue } from '../../../scenery/js/imports.js';
-import { Text } from '../../../scenery/js/imports.js';
-import { VBox } from '../../../scenery/js/imports.js';
+import { Text, VBox, VoicingRichText, VoicingText, voicingUtteranceQueue } from '../../../scenery/js/imports.js';
import Checkbox from '../../../sun/js/Checkbox.js';
import soundManager from '../../../tambo/js/soundManager.js';
import Tandem from '../../../tandem/js/Tandem.js';
@@ -47,12 +43,15 @@
// PreferencesPanelSection. It is possible that the toggle for Sound can be redundant when Sound
// is the only Audio feature supported. In that case, control of Sound should go through the
// "All Audio" toggle.
- includeTitleToggleSwitch: true
+ includeTitleToggleSwitch: true,
+
+ // phet-io
+ tandem: Tandem.REQUIRED
}, options );
const soundLabel = new Text( soundsLabelString, PreferencesDialog.PANEL_SECTION_LABEL_OPTIONS );
- const titleNode = new PreferencesToggleSwitch( soundManager.enabledProperty, false, true, {
+ const soundEnabledSwitch = new PreferencesToggleSwitch( soundManager.enabledProperty, false, true, {
labelNode: soundLabel,
descriptionNode: new VoicingText( soundDescriptionString, merge( {}, PreferencesDialog.PANEL_SECTION_CONTENT_OPTIONS, {
readingBlockContent: StringUtils.fillIn( labelledDescriptionPatternString, {
@@ -63,7 +62,8 @@
toggleSwitchOptions: {
visible: options.includeTitleToggleSwitch
},
- a11yLabel: soundsLabelString
+ a11yLabel: soundsLabelString,
+ tandem: options.tandem.createTandem( 'soundEnabledSwitch' )
} );
let enhancedSoundContent = null;
@@ -79,7 +79,7 @@
voicingNameResponse: extraSoundsLabelString,
// phet-io
- tandem: Tandem.OPT_OUT
+ tandem: options.tandem.createTandem( 'enhancedSoundCheckbox' )
} );
const enhancedSoundDescription = new VoicingRichText( extraSoundsDescriptionString, merge( {}, PreferencesDialog.PANEL_SECTION_CONTENT_OPTIONS, {
@@ -102,7 +102,7 @@
}
super( {
- titleNode: titleNode,
+ titleNode: soundEnabledSwitch,
contentNode: enhancedSoundContent
} );
Index: joist/js/preferences/InputPreferencesPanel.js
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/joist/js/preferences/InputPreferencesPanel.js b/joist/js/preferences/InputPreferencesPanel.js
--- a/joist/js/preferences/InputPreferencesPanel.js (revision 6f617114eef353e72bea7319355af3d753269558)
+++ b/joist/js/preferences/InputPreferencesPanel.js (date 1647382257387)
@@ -8,10 +8,8 @@
import merge from '../../../phet-core/js/merge.js';
import StringUtils from '../../../phetcommon/js/util/StringUtils.js';
-import { VoicingRichText } from '../../../scenery/js/imports.js';
-import { voicingUtteranceQueue } from '../../../scenery/js/imports.js';
-import { Node } from '../../../scenery/js/imports.js';
-import { Text } from '../../../scenery/js/imports.js';
+import { Node, Text, VoicingRichText, voicingUtteranceQueue } from '../../../scenery/js/imports.js';
+import Tandem from '../../../tandem/js/Tandem.js';
import joist from '../joist.js';
import joistStrings from '../joistStrings.js';
import PreferencesDialog from './PreferencesDialog.js';
@@ -32,17 +30,22 @@
/**
* @param {Object} inputModel - see PreferencesManager
+ * @param {Object} [options]
*/
- constructor( inputModel ) {
- super( {
+ constructor( inputModel, options ) {
+ options = merge( {
// pdom
tagName: 'div',
labelTagName: 'h2',
- labelContent: inputTitleString
- } );
+ labelContent: inputTitleString,
+
+ tandem: Tandem.REQUIRED
+ }, options );
- const toggleSwitch = new PreferencesToggleSwitch( inputModel.gestureControlsEnabledProperty, false, true, {
+ super( options );
+
+ const gestureControlsEnabledSwitch = new PreferencesToggleSwitch( inputModel.gestureControlsEnabledProperty, false, true, {
labelNode: new Text( gestureControlsString, PreferencesDialog.PANEL_SECTION_LABEL_OPTIONS ),
descriptionNode: new VoicingRichText( gestureControlsDescriptionString, merge( {}, PreferencesDialog.PANEL_SECTION_CONTENT_OPTIONS, {
lineWrap: 350,
@@ -52,11 +55,12 @@
description: gestureControlsDescriptionString
} )
} ) ),
- a11yLabel: gestureControlsString
+ a11yLabel: gestureControlsString,
+ tandem: options.tandem.createTandem( 'gestureControlsEnabledSwitch' )
} );
const panelSection = new PreferencesPanelSection( {
- titleNode: toggleSwitch
+ titleNode: gestureControlsEnabledSwitch
} );
this.addChild( panelSection );
Index: joist/js/preferences/AudioPreferencesPanel.js
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/joist/js/preferences/AudioPreferencesPanel.js b/joist/js/preferences/AudioPreferencesPanel.js
--- a/joist/js/preferences/AudioPreferencesPanel.js (revision 6f617114eef353e72bea7319355af3d753269558)
+++ b/joist/js/preferences/AudioPreferencesPanel.js (date 1647381462364)
@@ -6,9 +6,9 @@
* @author Jesse Greenberg (PhET Interactive Simulations)
*/
-import { HBox } from '../../../scenery/js/imports.js';
-import { Text } from '../../../scenery/js/imports.js';
-import { VBox } from '../../../scenery/js/imports.js';
+import merge from '../../../phet-core/js/merge.js';
+import { HBox, Text, VBox } from '../../../scenery/js/imports.js';
+import Tandem from '../../../tandem/js/Tandem.js';
import joist from '../joist.js';
import joistStrings from '../joistStrings.js';
import PreferencesDialog from './PreferencesDialog.js';
@@ -24,13 +24,20 @@
/**
* @param {Object} audioModel - configuration for audio settings, see PreferencesManager
* @param {BooleanProperty} enableToolbarProperty - whether the Toolbar is enabled
+ * @param {Object} [options]
*/
- constructor( audioModel, enableToolbarProperty ) {
+ constructor( audioModel, enableToolbarProperty, options ) {
+
+ options = merge( {
+ tandem: Tandem.REQUIRED
+ }, options );
const panelChildren = [];
if ( audioModel.supportsVoicing ) {
- panelChildren.push( new VoicingPanelSection( audioModel, enableToolbarProperty ) );
+ panelChildren.push( new VoicingPanelSection( audioModel, enableToolbarProperty, {
+ tandem: options.tandem.createTandem( 'voicingPanelSection' )
+ } ) );
}
if ( audioModel.supportsSound ) {
@@ -41,7 +48,8 @@
const hideSoundToggle = audioModel.supportsVoicing !== audioModel.supportsSound;
panelChildren.push( new SoundPanelSection( audioModel, {
- includeTitleToggleSwitch: !hideSoundToggle
+ includeTitleToggleSwitch: !hideSoundToggle,
+ tandem: options.tandem.createTandem( 'soundPanelSection' )
} ) );
}
@@ -52,7 +60,8 @@
const allAudioSwitch = new PreferencesToggleSwitch( audioModel.simSoundEnabledProperty, false, true, {
labelNode: new Text( audioFeaturesString, PreferencesDialog.PANEL_SECTION_LABEL_OPTIONS ),
- a11yLabel: audioFeaturesString
+ a11yLabel: audioFeaturesString,
+ tandem: options.tandem.createTandem( 'allAudioSwitch' )
} );
const soundEnabledListener = enabled => {
Index: joist/js/preferences/VoicingPanelSection.js
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/joist/js/preferences/VoicingPanelSection.js b/joist/js/preferences/VoicingPanelSection.js
--- a/joist/js/preferences/VoicingPanelSection.js (revision 6f617114eef353e72bea7319355af3d753269558)
+++ b/joist/js/preferences/VoicingPanelSection.js (date 1647383310313)
@@ -89,12 +89,17 @@
/**
* @param {Object} audioModel - configuration for audio settings, see PreferencesManager
* @param {BooleanProperty} toolbarEnabledProperty - whether or not the Toolbar is enabled for use
+ * @param {Object} [options]
*/
- constructor( audioModel, toolbarEnabledProperty ) {
+ constructor( audioModel, toolbarEnabledProperty, options ) {
+
+ options = merge( {
+ tandem: Tandem.REQUIRED
+ }, options );
// the checkbox is the title for the section and totally enables/disables the feature
const voicingLabel = new Text( voicingLabelString, PreferencesDialog.PANEL_SECTION_LABEL_OPTIONS );
- const voicingSwitch = new PreferencesToggleSwitch( audioModel.voicingEnabledProperty, false, true, {
+ const voicingEnabledSwitch = new PreferencesToggleSwitch( audioModel.voicingEnabledProperty, false, true, {
labelNode: voicingLabel,
descriptionNode: new VoicingText( voicingDescriptionString, merge( {}, PreferencesDialog.PANEL_SECTION_CONTENT_OPTIONS, {
readingBlockContent: StringUtils.fillIn( labelledDescriptionPatternString, {
@@ -102,14 +107,16 @@
description: voicingDescriptionString
} )
} ) ),
- a11yLabel: voicingLabelString
+ a11yLabel: voicingLabelString,
+ tandem: options.tandem.createTandem( 'voicingEnabledSwitch' )
} );
// checkbox for the toolbar
const quickAccessLabel = new Text( toolbarLabelString, PreferencesDialog.PANEL_SECTION_LABEL_OPTIONS );
- const toolbarSwitch = new PreferencesToggleSwitch( toolbarEnabledProperty, false, true, {
+ const toolbarEnabledSwitch = new PreferencesToggleSwitch( toolbarEnabledProperty, false, true, {
labelNode: quickAccessLabel,
- a11yLabel: toolbarLabelString
+ a11yLabel: toolbarLabelString,
+ tandem: options.tandem.createTandem( 'toolbarEnabledSwitch' )
} );
// Speech output levels
@@ -129,9 +136,15 @@
align: 'left',
spacing: 5,
children: [
- createCheckbox( objectDetailsLabelString, audioModel.voicingObjectResponsesEnabledProperty ),
- createCheckbox( contextChangesLabelString, audioModel.voicingContextResponsesEnabledProperty ),
- createCheckbox( helpfulHintsLabelString, audioModel.voicingHintResponsesEnabledProperty )
+ createCheckbox( objectDetailsLabelString, audioModel.voicingObjectResponsesEnabledProperty,
+ options.tandem.createTandem( 'voicingObjectResponsesEnabledCheckbox' )
+ ),
+ createCheckbox( contextChangesLabelString, audioModel.voicingContextResponsesEnabledProperty,
+ options.tandem.createTandem( 'voicingContextResponsesEnabledCheckbox' )
+ ),
+ createCheckbox( helpfulHintsLabelString, audioModel.voicingHintResponsesEnabledProperty,
+ options.tandem.createTandem( 'voicingHintResponsesEnabledCheckbox' )
+ )
]
} );
@@ -167,7 +180,7 @@
voicingNameResponse: customizeVoiceString,
// phet-io
- tandem: Tandem.OPT_OUT
+ tandem: options.tandem.createTandem( 'expandCollapseButton' )
} );
const voiceOptionsContainer = new Node( {
@@ -186,13 +199,13 @@
voiceOptionsLabel.addInputListener( voiceOptionsPressListener );
const content = new Node( {
- children: [ speechOutputContent, toolbarSwitch, voiceOptionsContainer, voiceOptionsContent ]
+ children: [ speechOutputContent, toolbarEnabledSwitch, voiceOptionsContainer, voiceOptionsContent ]
} );
// layout for section content, custom rather than using a LayoutBox because the voice options label needs
// to be left aligned with other labels, while the ExpandCollapseButton extends to the left
- toolbarSwitch.leftTop = speechOutputContent.leftBottom.plusXY( 0, 20 );
- voiceOptionsLabel.leftTop = toolbarSwitch.leftBottom.plusXY( 0, 20 );
+ toolbarEnabledSwitch.leftTop = speechOutputContent.leftBottom.plusXY( 0, 20 );
+ voiceOptionsLabel.leftTop = toolbarEnabledSwitch.leftBottom.plusXY( 0, 20 );
expandCollapseButton.leftCenter = voiceOptionsLabel.rightCenter.plusXY( 10, 0 );
voiceOptionsContent.leftTop = voiceOptionsLabel.leftBottom.plusXY( 0, 10 );
voiceOptionsOpenProperty.link( open => { voiceOptionsContent.visible = open; } );
@@ -201,7 +214,7 @@
expandCollapseButton.focusHighlight = new FocusHighlightFromNode( voiceOptionsContainer );
super( {
- titleNode: voicingSwitch,
+ titleNode: voicingEnabledSwitch,
contentNode: content
} );
@@ -251,7 +264,10 @@
voiceList = englishVoices.slice( 0, 12 );
}
- voiceComboBox = new VoiceComboBox( voiceList, audioModel.voiceProperty, phet.joist.sim.topLayer );
+ // phet-io - for when creating the Archetype for the Capsule housing the preferencesDialog, we don't have a sim global.
+ const parent = phet.joist.sim.topLayer || new Node();
+
+ voiceComboBox = new VoiceComboBox( voiceList, audioModel.voiceProperty, parent );
voiceOptionsContent.addChild( voiceComboBox );
};
voicingManager.voicesChangedEmitter.addListener( voicesChangedListener );
@@ -297,7 +313,7 @@
* @param {BooleanProperty} property
* @returns {Checkbox}
*/
-const createCheckbox = ( labelString, property ) => {
+const createCheckbox = ( labelString, property, tandem ) => {
const labelNode = new Text( labelString, PreferencesDialog.PANEL_SECTION_CONTENT_OPTIONS );
return new Checkbox( labelNode, property, {
@@ -309,7 +325,7 @@
voicingNameResponse: labelString,
// phet-io
- tandem: Tandem.OPT_OUT
+ tandem: tandem
} );
};
@@ -399,8 +415,18 @@
* @param {SpeechSynthesisVoice[]} voices - list of voices to include from the voicingManager
* @param {Property.<SpeechSynthesisVoice|null>} voiceProperty
* @param {Node} parentNode - node that acts as a parent for the ComboBox list
+ * @param {Object} [options]
*/
- constructor( voices, voiceProperty, parentNode ) {
+ constructor( voices, voiceProperty, parentNode, options ) {
+
+ options = merge( {
+ listPosition: 'above',
+ accessibleName: voiceLabelString,
+
+ // phet-io, opt out because we would need to instrument voices, but those could change between runtimes.
+ tandem: Tandem.OPT_OUT
+ }, options );
+
const items = [];
if ( voices.length === 0 ) {
@@ -421,13 +447,7 @@
// voices
voiceProperty.set( items[ 0 ].value );
- super( items, voiceProperty, parentNode, {
- listPosition: 'above',
- accessibleName: voiceLabelString,
-
- // phet-io
- tandem: Tandem.OPT_OUT
- } );
+ super( items, voiceProperty, parentNode, options );
// voicing - responses for the button should always come through, regardless of user selection of
// responses. As of 10/29/21, ComboBox will only read the name response (which are always read regardless)
Index: joist/js/preferences/PreferencesDialog.js
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/joist/js/preferences/PreferencesDialog.js b/joist/js/preferences/PreferencesDialog.js
--- a/joist/js/preferences/PreferencesDialog.js (revision 6f617114eef353e72bea7319355af3d753269558)
+++ b/joist/js/preferences/PreferencesDialog.js (date 1647382028110)
@@ -10,15 +10,14 @@
*/
import EnumerationProperty from '../../../axon/js/EnumerationProperty.js';
-import EnumerationValue from '../../../phet-core/js/EnumerationValue.js';
import Enumeration from '../../../phet-core/js/Enumeration.js';
+import EnumerationValue from '../../../phet-core/js/EnumerationValue.js';
import merge from '../../../phet-core/js/merge.js';
import PhetFont from '../../../scenery-phet/js/PhetFont.js';
-import { KeyboardUtils } from '../../../scenery/js/imports.js';
-import { Node } from '../../../scenery/js/imports.js';
-import { Text } from '../../../scenery/js/imports.js';
+import { KeyboardUtils, Node, Text } from '../../../scenery/js/imports.js';
import Dialog from '../../../sun/js/Dialog.js';
import HSeparator from '../../../sun/js/HSeparator.js';
+import Tandem from '../../../tandem/js/Tandem.js';
import audioManager from '../audioManager.js';
import joist from '../joist.js';
import joistStrings from '../joistStrings.js';
@@ -83,6 +82,7 @@
// phet-io
phetioDynamicElement: true,
+ tandem: Tandem.REQUIRED,
// pdom
positionInPDOM: true
@@ -100,10 +100,14 @@
const selectedTabProperty = new EnumerationProperty( PreferencesTab.GENERAL );
// the set of tabs you can can click to activate a tab panel
- const preferencesTabs = new PreferencesTabs( supportedTabs, selectedTabProperty );
+ const preferencesTabs = new PreferencesTabs( supportedTabs, selectedTabProperty, {
+ tandem: options.tandem.createTandem( 'preferencesTabs' )
+ } );
// the panels of content with UI components to select preferences, only one is displayed at a time
- const preferencesPanels = new PreferencesPanels( preferencesModel, supportedTabs, selectedTabProperty );
+ const preferencesPanels = new PreferencesPanels( preferencesModel, supportedTabs, selectedTabProperty, {
+ tandem: options.tandem.createTandem( 'preferencesPanels' )
+ } );
// visual separator between tabs and panels - as long as the widest separated content, which may change with i18n
const tabPanelSeparator = new HSeparator( Math.max( preferencesPanels.width, preferencesTabs.width ), { lineWidth: 1 } );
Index: joist/js/preferences/VisualPreferencesPanel.js
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/joist/js/preferences/VisualPreferencesPanel.js b/joist/js/preferences/VisualPreferencesPanel.js
--- a/joist/js/preferences/VisualPreferencesPanel.js (revision 6f617114eef353e72bea7319355af3d753269558)
+++ b/joist/js/preferences/VisualPreferencesPanel.js (date 1647381649236)
@@ -9,10 +9,8 @@
import merge from '../../../phet-core/js/merge.js';
import StringUtils from '../../../phetcommon/js/util/StringUtils.js';
-import { VoicingText } from '../../../scenery/js/imports.js';
-import { voicingUtteranceQueue } from '../../../scenery/js/imports.js';
-import { Node } from '../../../scenery/js/imports.js';
-import { Text } from '../../../scenery/js/imports.js';
+import { Node, Text, VoicingText, voicingUtteranceQueue } from '../../../scenery/js/imports.js';
+import Tandem from '../../../tandem/js/Tandem.js';
import joist from '../joist.js';
import joistStrings from '../joistStrings.js';
import PreferencesDialog from './PreferencesDialog.js';
@@ -30,18 +28,25 @@
/**
* @param {Object} visualModel - see PreferencesManager
+ * @param {Object} [options]
*/
- constructor( visualModel ) {
- super( {
+ constructor( visualModel, options ) {
+
+ options = merge( {
// pdom
tagName: 'div',
labelTagName: 'h2',
- labelContent: 'Visual'
- } );
+ labelContent: 'Visual',
+
+ // phet-io
+ tandem: Tandem.REQUIRED
+ }, options );
+
+ super( options );
const label = new Text( interactiveHighlightsString, PreferencesDialog.PANEL_SECTION_LABEL_OPTIONS );
- const toggleSwitch = new PreferencesToggleSwitch( visualModel.interactiveHighlightsEnabledProperty, false, true, {
+ const interactiveHighlightsEnabledSwitch = new PreferencesToggleSwitch( visualModel.interactiveHighlightsEnabledProperty, false, true, {
labelNode: label,
descriptionNode: new VoicingText( interactiveHighlightsDescriptionString, merge( {}, PreferencesDialog.PANEL_SECTION_CONTENT_OPTIONS, {
readingBlockContent: StringUtils.fillIn( labelledDescriptionPatternString, {
@@ -49,11 +54,12 @@
description: interactiveHighlightsDescriptionString
} )
} ) ),
- a11yLabel: interactiveHighlightsString
+ a11yLabel: interactiveHighlightsString,
+ tandem: options.tandem.createTandem( 'interactiveHighlightsEnabledSwitch' )
} );
const panelSection = new PreferencesPanelSection( {
- titleNode: toggleSwitch
+ titleNode: interactiveHighlightsEnabledSwitch
} );
this.addChild( panelSection );
Index: joist/js/preferences/PreferencesPanels.js
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/joist/js/preferences/PreferencesPanels.js b/joist/js/preferences/PreferencesPanels.js
--- a/joist/js/preferences/PreferencesPanels.js (revision 6f617114eef353e72bea7319355af3d753269558)
+++ b/joist/js/preferences/PreferencesPanels.js (date 1647382221563)
@@ -9,8 +9,9 @@
* @author Jesse Greenberg (PhET Interactive Simulations)
*/
-import { AlignGroup } from '../../../scenery/js/imports.js';
-import { Node } from '../../../scenery/js/imports.js';
+import merge from '../../../phet-core/js/merge.js';
+import { AlignGroup, Node } from '../../../scenery/js/imports.js';
+import Tandem from '../../../tandem/js/Tandem.js';
import joist from '../joist.js';
import AudioPreferencesPanel from './AudioPreferencesPanel.js';
import GeneralPreferencesPanel from './GeneralPreferencesPanel.js';
@@ -24,46 +25,59 @@
* @param {PreferencesManager} preferencesModel
* @param {PreferencesTab[]} supportedTabs - list of Tabs supported by this Dialog
* @param {EnumerationDeprecatedProperty.<PreferencesTab>} selectedTabProperty
+ * @param {Object} [options]
*/
- constructor( preferencesModel, supportedTabs, selectedTabProperty ) {
- super();
+ constructor( preferencesModel, supportedTabs, selectedTabProperty, options ) {
+
+ options = merge( {
+ tandem: Tandem.REQUIRED
+ }, options );
+ super( options );
const panelAlignGroup = new AlignGroup( {
matchVertical: false
} );
- // @private {PreferencesPanel[]}
+ // @private {PreferencesPanelContainer[]}
this.content = [];
let generalPreferencesPanel = null;
if ( supportedTabs.includes( PreferencesDialog.PreferencesTab.GENERAL ) ) {
- generalPreferencesPanel = new GeneralPreferencesPanel( preferencesModel.generalModel );
+ generalPreferencesPanel = new GeneralPreferencesPanel( preferencesModel.generalModel, {
+ tandem: options.tandem.createTandem( 'generalPreferencesPanel' )
+ } );
const generalBox = panelAlignGroup.createBox( generalPreferencesPanel );
this.addChild( generalBox );
- this.content.push( new PreferencesPanel( generalPreferencesPanel, PreferencesDialog.PreferencesTab.GENERAL ) );
+ this.content.push( new PreferencesPanelContainer( generalPreferencesPanel, PreferencesDialog.PreferencesTab.GENERAL ) );
}
let visualPreferencesPanel = null;
if ( supportedTabs.includes( PreferencesDialog.PreferencesTab.VISUAL ) ) {
- visualPreferencesPanel = new VisualPreferencesPanel( preferencesModel.visualModel );
+ visualPreferencesPanel = new VisualPreferencesPanel( preferencesModel.visualModel, {
+ tandem: options.tandem.createTandem( 'visualPreferencesPanel' )
+ } );
const visualBox = panelAlignGroup.createBox( visualPreferencesPanel );
this.addChild( visualBox );
- this.content.push( new PreferencesPanel( visualPreferencesPanel, PreferencesDialog.PreferencesTab.VISUAL ) );
+ this.content.push( new PreferencesPanelContainer( visualPreferencesPanel, PreferencesDialog.PreferencesTab.VISUAL ) );
}
let audioPreferencesPanel = null;
if ( supportedTabs.includes( PreferencesDialog.PreferencesTab.AUDIO ) ) {
- audioPreferencesPanel = new AudioPreferencesPanel( preferencesModel.audioModel, preferencesModel.toolbarEnabledProperty );
+ audioPreferencesPanel = new AudioPreferencesPanel( preferencesModel.audioModel, preferencesModel.toolbarEnabledProperty, {
+ tandem: options.tandem.createTandem( 'audioPreferencesPanel' )
+ } );
const audioBox = panelAlignGroup.createBox( audioPreferencesPanel );
this.addChild( audioBox );
- this.content.push( new PreferencesPanel( audioPreferencesPanel, PreferencesDialog.PreferencesTab.AUDIO ) );
+ this.content.push( new PreferencesPanelContainer( audioPreferencesPanel, PreferencesDialog.PreferencesTab.AUDIO ) );
}
let inputPreferencesPanel = null;
if ( supportedTabs.includes( PreferencesDialog.PreferencesTab.INPUT ) ) {
- inputPreferencesPanel = new InputPreferencesPanel( preferencesModel.inputModel );
+ inputPreferencesPanel = new InputPreferencesPanel( preferencesModel.inputModel, {
+ tandem: options.tandem.createTandem( 'inputPreferencesPanel' )
+ } );
this.addChild( inputPreferencesPanel );
- this.content.push( new PreferencesPanel( inputPreferencesPanel, PreferencesDialog.PreferencesTab.INPUT ) );
+ this.content.push( new PreferencesPanelContainer( inputPreferencesPanel, PreferencesDialog.PreferencesTab.INPUT ) );
}
this.selectedTabProperty = selectedTabProperty;
@@ -79,7 +93,7 @@
/**
* @private
- * @returns {PreferencesPanel} - the currently selected preferences panel
+ * @returns {PreferencesPanelContainer} - the currently selected preferences panel
*/
getSelectedContent() {
for ( let i = 0; i < this.content.length; i++ ) {
@@ -95,7 +109,7 @@
/**
* Focus the selected panel. The panel should not be focusable until this is requested, so it is set to be
* focusable before the focus() call. When focus is removed from the panel, it should become non-focusable
- * again. That is handled in PreferencesPanel class.
+ * again. That is handled in PreferencesPanelContainer class.
* @public
*/
focusSelectedPanel() {
@@ -119,7 +133,7 @@
* An inner class that manages the panelContent and its value. A listener as added to the panel so that
* whenever focus is lost from the panel, it is removed from the traversal order.
*/
-class PreferencesPanel extends Node {
+class PreferencesPanelContainer extends Node {
/**
* @param {Node} panelContent
Index: joist/js/Sim.js
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/joist/js/Sim.js b/joist/js/Sim.js
--- a/joist/js/Sim.js (revision 6f617114eef353e72bea7319355af3d753269558)
+++ b/joist/js/Sim.js (date 1647383669108)
@@ -529,7 +529,9 @@
assert && assert( !options.simDisplayOptions.preferencesManager );
options.simDisplayOptions.preferencesManager = this.preferencesManager;
- this.toolbar = new Toolbar( this );
+ this.toolbar = new Toolbar( this, {
+ tandem: Tandem.GENERAL_VIEW.createTandem( 'toolbar' )
+ } );
// when the Toolbar positions update, resize the sim to fit in the available space
this.toolbar.rightPositionProperty.lazyLink( () => {
Index: joist/js/preferences/NavigationBarPreferencesButton.js
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/joist/js/preferences/NavigationBarPreferencesButton.js b/joist/js/preferences/NavigationBarPreferencesButton.js
--- a/joist/js/preferences/NavigationBarPreferencesButton.js (revision 6f617114eef353e72bea7319355af3d753269558)
+++ b/joist/js/preferences/NavigationBarPreferencesButton.js (date 1647383204788)
@@ -9,6 +9,8 @@
import merge from '../../../phet-core/js/merge.js';
import { Path } from '../../../scenery/js/imports.js';
import userCogSolidShape from '../../../sherpa/js/fontawesome-5/userCogSolidShape.js';
+import Dialog from '../../../sun/js/Dialog.js';
+import PhetioCapsule from '../../../tandem/js/PhetioCapsule.js';
import Tandem from '../../../tandem/js/Tandem.js';
import joist from '../joist.js';
import JoistButton from '../JoistButton.js';
@@ -32,15 +34,19 @@
maxWidth: 25
} );
- let preferencesDialog = null;
- super( icon, backgroundColorProperty, Tandem.OPT_OUT, {
+ assert && assert( !options.listener, 'PhetButton sets listener' );
+ const preferencesDialogCapsule = new PhetioCapsule( tandem => {
+ return new PreferencesDialog( preferencesModel, {
+ tandem: tandem
+ } );
+ }, [], {
+ tandem: options.tandem.createTandem( 'preferencesDialogCapsule' ),
+ phetioType: PhetioCapsule.PhetioCapsuleIO( Dialog.DialogIO )
+ } );
+
+ super( icon, backgroundColorProperty, options.tandem, {
listener: () => {
- if ( !preferencesDialog ) {
- preferencesDialog = new PreferencesDialog( preferencesModel, {
- tandem: Tandem.OPT_OUT
- } );
- }
-
+ const preferencesDialog = preferencesDialogCapsule.getElement();
preferencesDialog.show();
preferencesDialog.focusSelectedTab();
}, |
Alright. The view is committed above. It still isn't totally clear how we will have the model instrumented, since we largely don't want preferences to persist. Even so, this seems like a good commit point. I will work to see what more we would want to do with the model. |
In today's meeting, Regarding saving state with or without preferences@JacquiHayes identified that privacy laws may forbid detecting what a11y preferences are selected without specialized permissions. So we can have Regarding instrumenting the elements within the preferences dialog@kathy-phet: We are only instrumenting the controls within the "Simulation" tab, right? Conclusion: Leave it as it is (uninstrumented + mildly instrumented) for now, and wait for clients to ask for this feature before we start instrumenting these details. @zepumph can you please split this up into side issues as appropriate? @arouinfar will look into the tree as it is now and see if there are other changes to be made, after @zepumph gives the go-ahead. |
Still on me, pinged during today's PhET-iO meeting. |
Today during PhET-iO meeting. . . .
|
I'd like to co-assign @samreid because my time pre-vacation is running short, and I don't want to be a bottle neck. I think that @samreid could definitely work on marking things as phetioReadOnly: true again, and likely also the simSoundEnabledProperty rename. I'm still trying to get to this though! |
@marlitas and I will try a first draft of this today. |
@marlitas and I implemented the first step by making things no longer read only. We have no confidence that we have covered model elements that do not appear in gravity and orbits, and we are considering adding a post start up a session check that all nested elements under the preferences model are marked as read only false. We think this would take 30 minutes or so but would protect occurrences outside gravity and orbits, and all future occurrences. But if one day, we decide to make even one preferences model property as |
Looks like |
Just a couple more tweaks in voicing implementation from a sloppy first pass (sorry!) |
Today during PhET-iO meeting we were discussing how to instrument these preferences.
We feel strongly about two things:
For now we will achieve this by instrumenting preferences as phetioReadOnly: true, and phetioState:false. This way they show up in the data stream.
The text was updated successfully, but these errors were encountered: