refactor: circular deps part 5

This commit is contained in:
Nathan Walker
2025-07-08 08:10:17 -07:00
parent 6ede07a551
commit b70aa2c45f
6 changed files with 138 additions and 137 deletions

View File

@ -1,125 +1,4 @@
import { Application } from '../application'; // Only keep helpers that do not import from application here.
import type { View } from '../ui/core/view'; // If any code remains that needs Application, move it to accessibility-css-init.ts.
import { AccessibilityServiceEnabledObservable } from './accessibility-service';
import { FontScaleCategory, getCurrentFontScale, getFontScaleCategory, VALID_FONT_SCALES } from './font-scale';
// CSS-classes export { initAccessibilityCssHelper } from './accessibility-css-init';
const fontScaleExtraSmallCategoryClass = `a11y-fontscale-xs`;
const fontScaleMediumCategoryClass = `a11y-fontscale-m`;
const fontScaleExtraLargeCategoryClass = `a11y-fontscale-xl`;
const fontScaleCategoryClasses = [fontScaleExtraSmallCategoryClass, fontScaleMediumCategoryClass, fontScaleExtraLargeCategoryClass];
const a11yServiceEnabledClass = `a11y-service-enabled`;
const a11yServiceDisabledClass = `a11y-service-disabled`;
const a11yServiceClasses = [a11yServiceEnabledClass, a11yServiceDisabledClass];
let accessibilityServiceObservable: AccessibilityServiceEnabledObservable;
let fontScaleCssClasses: Map<number, string>;
let currentFontScaleClass = '';
let currentFontScaleCategory = '';
let currentA11YServiceClass = '';
function ensureClasses() {
if (accessibilityServiceObservable) {
return;
}
fontScaleCssClasses = new Map(VALID_FONT_SCALES.map((fs) => [fs, `a11y-fontscale-${Number(fs * 100).toFixed(0)}`]));
accessibilityServiceObservable = new AccessibilityServiceEnabledObservable();
}
function applyRootCssClass(cssClasses: string[], newCssClass: string): void {
const rootView = Application.getRootView();
if (!rootView) {
return;
}
Application.applyCssClass(rootView, cssClasses, newCssClass);
const rootModalViews = <Array<View>>rootView._getRootModalViews();
rootModalViews.forEach((rootModalView) => Application.applyCssClass(rootModalView, cssClasses, newCssClass));
}
function applyFontScaleToRootViews(): void {
const rootView = Application.getRootView();
if (!rootView) {
return;
}
const fontScale = getCurrentFontScale();
rootView.style.fontScaleInternal = fontScale;
const rootModalViews = <Array<View>>rootView._getRootModalViews();
rootModalViews.forEach((rootModalView) => (rootModalView.style.fontScaleInternal = fontScale));
}
export function initAccessibilityCssHelper(): void {
ensureClasses();
Application.on(Application.fontScaleChangedEvent, () => {
updateCurrentHelperClasses();
applyFontScaleToRootViews();
});
accessibilityServiceObservable.on(AccessibilityServiceEnabledObservable.propertyChangeEvent, updateCurrentHelperClasses);
}
/**
* Update the helper CSS-classes.
* Return true is any changes.
*/
function updateCurrentHelperClasses(): void {
const fontScale = getCurrentFontScale();
const fontScaleCategory = getFontScaleCategory();
const oldFontScaleClass = currentFontScaleClass;
if (fontScaleCssClasses.has(fontScale)) {
currentFontScaleClass = fontScaleCssClasses.get(fontScale);
} else {
currentFontScaleClass = fontScaleCssClasses.get(1);
}
if (oldFontScaleClass !== currentFontScaleClass) {
applyRootCssClass([...fontScaleCssClasses.values()], currentFontScaleClass);
}
const oldActiveFontScaleCategory = currentFontScaleCategory;
switch (fontScaleCategory) {
case FontScaleCategory.ExtraSmall: {
currentFontScaleCategory = fontScaleExtraSmallCategoryClass;
break;
}
case FontScaleCategory.Medium: {
currentFontScaleCategory = fontScaleMediumCategoryClass;
break;
}
case FontScaleCategory.ExtraLarge: {
currentFontScaleCategory = fontScaleExtraLargeCategoryClass;
break;
}
default: {
currentFontScaleCategory = fontScaleMediumCategoryClass;
break;
}
}
if (oldActiveFontScaleCategory !== currentFontScaleCategory) {
applyRootCssClass(fontScaleCategoryClasses, currentFontScaleCategory);
}
const oldA11YStatusClass = currentA11YServiceClass;
if (accessibilityServiceObservable.accessibilityServiceEnabled) {
currentA11YServiceClass = a11yServiceEnabledClass;
} else {
currentA11YServiceClass = a11yServiceDisabledClass;
}
if (oldA11YStatusClass !== currentA11YServiceClass) {
applyRootCssClass(a11yServiceClasses, currentA11YServiceClass);
}
}

View File

@ -0,0 +1,121 @@
import { Application } from '../application';
import type { View } from '../ui/core/view';
import { AccessibilityServiceEnabledObservable } from './accessibility-service';
import { FontScaleCategory, getCurrentFontScale, getFontScaleCategory, VALID_FONT_SCALES } from './font-scale';
// CSS-classes
const fontScaleExtraSmallCategoryClass = `a11y-fontscale-xs`;
const fontScaleMediumCategoryClass = `a11y-fontscale-m`;
const fontScaleExtraLargeCategoryClass = `a11y-fontscale-xl`;
const fontScaleCategoryClasses = [fontScaleExtraSmallCategoryClass, fontScaleMediumCategoryClass, fontScaleExtraLargeCategoryClass];
const a11yServiceEnabledClass = `a11y-service-enabled`;
const a11yServiceDisabledClass = `a11y-service-disabled`;
const a11yServiceClasses = [a11yServiceEnabledClass, a11yServiceDisabledClass];
let accessibilityServiceObservable: AccessibilityServiceEnabledObservable;
let fontScaleCssClasses: Map<number, string>;
let currentFontScaleClass = '';
let currentFontScaleCategory = '';
let currentA11YServiceClass = '';
function ensureClasses() {
if (accessibilityServiceObservable) {
return;
}
fontScaleCssClasses = new Map(VALID_FONT_SCALES.map((fs) => [fs, `a11y-fontscale-${Number(fs * 100).toFixed(0)}`]));
accessibilityServiceObservable = new AccessibilityServiceEnabledObservable();
}
function applyRootCssClass(cssClasses: string[], newCssClass: string): void {
const rootView = Application.getRootView();
if (!rootView) {
return;
}
Application.applyCssClass(rootView, cssClasses, newCssClass);
const rootModalViews = <Array<View>>rootView._getRootModalViews();
rootModalViews.forEach((rootModalView) => Application.applyCssClass(rootModalView, cssClasses, newCssClass));
}
function applyFontScaleToRootViews(): void {
const rootView = Application.getRootView();
if (!rootView) {
return;
}
const fontScale = getCurrentFontScale();
rootView.style.fontScaleInternal = fontScale;
const rootModalViews = <Array<View>>rootView._getRootModalViews();
rootModalViews.forEach((rootModalView) => (rootModalView.style.fontScaleInternal = fontScale));
}
function updateCurrentHelperClasses(): void {
const fontScale = getCurrentFontScale();
const fontScaleCategory = getFontScaleCategory();
const oldFontScaleClass = currentFontScaleClass;
if (fontScaleCssClasses.has(fontScale)) {
currentFontScaleClass = fontScaleCssClasses.get(fontScale);
} else {
currentFontScaleClass = fontScaleCssClasses.get(1);
}
if (oldFontScaleClass !== currentFontScaleClass) {
applyRootCssClass([...fontScaleCssClasses.values()], currentFontScaleClass);
}
const oldActiveFontScaleCategory = currentFontScaleCategory;
switch (fontScaleCategory) {
case FontScaleCategory.ExtraSmall: {
currentFontScaleCategory = fontScaleExtraSmallCategoryClass;
break;
}
case FontScaleCategory.Medium: {
currentFontScaleCategory = fontScaleMediumCategoryClass;
break;
}
case FontScaleCategory.ExtraLarge: {
currentFontScaleCategory = fontScaleExtraLargeCategoryClass;
break;
}
default: {
currentFontScaleCategory = fontScaleMediumCategoryClass;
break;
}
}
if (oldActiveFontScaleCategory !== currentFontScaleCategory) {
applyRootCssClass(fontScaleCategoryClasses, currentFontScaleCategory);
}
const oldA11YStatusClass = currentA11YServiceClass;
if (accessibilityServiceObservable.accessibilityServiceEnabled) {
currentA11YServiceClass = a11yServiceEnabledClass;
} else {
currentA11YServiceClass = a11yServiceDisabledClass;
}
if (oldA11YStatusClass !== currentA11YServiceClass) {
applyRootCssClass(a11yServiceClasses, currentA11YServiceClass);
}
}
export function initAccessibilityCssHelper(): void {
ensureClasses();
Application.on(Application.fontScaleChangedEvent, () => {
updateCurrentHelperClasses();
applyFontScaleToRootViews();
});
accessibilityServiceObservable.on(AccessibilityServiceEnabledObservable.propertyChangeEvent, updateCurrentHelperClasses);
}

View File

@ -1,6 +1,6 @@
import { CssProperty, InheritedCssProperty, Property } from '../ui/core/properties'; import { CssProperty, InheritedCssProperty, Property } from '../ui/core/properties';
import type { View } from '../ui/core/view'; import type { View } from '../ui/core/view';
import { booleanConverter } from '../ui/core/view-base'; import { booleanConverter } from '../ui/core/view-base/utils';
import { Style } from '../ui/styling/style'; import { Style } from '../ui/styling/style';
import { AccessibilityLiveRegion, AccessibilityRole, AccessibilityState, AccessibilityTrait } from './accessibility-types'; import { AccessibilityLiveRegion, AccessibilityRole, AccessibilityState, AccessibilityTrait } from './accessibility-types';

View File

@ -1,4 +1,4 @@
import { initAccessibilityCssHelper } from '../accessibility/accessibility-css-helper'; import { initAccessibilityCssHelper } from '../accessibility/accessibility-css-init';
import { initAccessibilityFontScale } from '../accessibility/font-scale'; import { initAccessibilityFontScale } from '../accessibility/font-scale';
import { CoreTypes } from '../core-types'; import { CoreTypes } from '../core-types';
import { CSSUtils } from '../css/system-classes'; import { CSSUtils } from '../css/system-classes';

View File

@ -20,6 +20,9 @@ import { profile } from '../../../profiling';
import { DOMNode } from '../../../debugger/dom-types'; import { DOMNode } from '../../../debugger/dom-types';
import { applyInlineStyle, CssState, StyleScope } from '../../styling/style-scope'; import { applyInlineStyle, CssState, StyleScope } from '../../styling/style-scope';
import { ViewBase as ViewBaseDefinition } from '.'; import { ViewBase as ViewBaseDefinition } from '.';
import { booleanConverter } from './utils';
export { booleanConverter } from './utils';
const defaultBindingSource = {}; const defaultBindingSource = {};
@ -1613,14 +1616,3 @@ export const defaultVisualStateProperty = new Property<ViewBase, string>({
}, },
}); });
defaultVisualStateProperty.register(ViewBase); defaultVisualStateProperty.register(ViewBase);
export function booleanConverter(v: string | boolean): boolean {
const lowercase = (v + '').toLowerCase();
if (lowercase === 'true') {
return true;
} else if (lowercase === 'false') {
return false;
}
throw new Error(`Invalid boolean: ${v}`);
}

View File

@ -0,0 +1,9 @@
// Utility functions for view-base and related modules
export function booleanConverter(v: string | boolean): boolean {
if (typeof v === 'string') {
v = v.trim().toLowerCase();
return v === 'true' || v === '1';
}
return !!v;
}