diff --git a/core/block_svg.ts b/core/block_svg.ts index 6a42fc6fa..a0322fad7 100644 --- a/core/block_svg.ts +++ b/core/block_svg.ts @@ -785,10 +785,10 @@ export class BlockSvg extends Block implements IASTNodeLocationSvg, (group as AnyDuringMigration).translate_ = ''; (group as AnyDuringMigration).skew_ = ''; common.draggingConnections.push(...this.getConnections_(true)); - dom.addClass(this.svgGroup_ as Element, 'blocklyDragging'); + this.svgGroup_.classList.add('blocklyDragging'); } else { common.draggingConnections.length = 0; - dom.removeClass(this.svgGroup_ as Element, 'blocklyDragging'); + this.svgGroup_.classList.remove('blocklyDragging'); } // Recurse through all blocks attached under this one. for (let i = 0; i < this.childBlocks_.length; i++) { diff --git a/core/contextmenu.ts b/core/contextmenu.ts index 350a1e62c..436f3b1df 100644 --- a/core/contextmenu.ts +++ b/core/contextmenu.ts @@ -24,7 +24,6 @@ import {MenuItem} from './menuitem.js'; import {Msg} from './msg.js'; import * as aria from './utils/aria.js'; import {Coordinate} from './utils/coordinate.js'; -import * as dom from './utils/dom.js'; import {Rect} from './utils/rect.js'; import * as svgMath from './utils/svg_math.js'; import * as WidgetDiv from './widgetdiv.js'; @@ -181,7 +180,7 @@ function createWidget_(menu: Menu) { } menu.render(div); const menuDom = menu.getElement(); - dom.addClass((menuDom as Element), 'blocklyContextMenu'); + menuDom?.classList.add('blocklyContextMenu'); // Prevent system context menu when right-clicking a Blockly context menu. browserEvents.conditionalBind( (menuDom as EventTarget), 'contextmenu', null, haltPropagation); diff --git a/core/dropdowndiv.ts b/core/dropdowndiv.ts index d86a9af0c..b263a0be2 100644 --- a/core/dropdowndiv.ts +++ b/core/dropdowndiv.ts @@ -16,7 +16,6 @@ goog.declareModuleId('Blockly.dropDownDiv'); import type {BlockSvg} from './block_svg.js'; import * as common from './common.js'; import type {Field} from './field.js'; -import * as dom from './utils/dom.js'; import * as math from './utils/math.js'; import {Rect} from './utils/rect.js'; import type {Size} from './utils/size.js'; @@ -139,10 +138,10 @@ export function createDom() { // Handle focusin/out events to add a visual indicator when // a child is focused or blurred. div.addEventListener('focusin', function() { - dom.addClass(div, 'blocklyFocused'); + div.classList.add('blocklyFocused'); }); div.addEventListener('focusout', function() { - dom.removeClass(div, 'blocklyFocused'); + div.classList.remove('blocklyFocused'); }); } @@ -311,8 +310,12 @@ export function show( const mainWorkspace = common.getMainWorkspace() as WorkspaceSvg; renderedClassName = mainWorkspace.getRenderer().getClassName(); themeClassName = mainWorkspace.getTheme().getClassName(); - dom.addClass(div, renderedClassName); - dom.addClass(div, themeClassName); + if (renderedClassName) { + div.classList.add(renderedClassName); + } + if (themeClassName) { + div.classList.add(themeClassName); + } // When we change `translate` multiple times in close succession, // Chrome may choose to wait and apply them all at once. @@ -592,11 +595,11 @@ export function hideWithoutAnimation() { owner = null; if (renderedClassName) { - dom.removeClass(div, renderedClassName); + div.classList.remove(renderedClassName); renderedClassName = ''; } if (themeClassName) { - dom.removeClass(div, themeClassName); + div.classList.remove(themeClassName); themeClassName = ''; } (common.getMainWorkspace() as WorkspaceSvg).markFocused(); diff --git a/core/field.ts b/core/field.ts index 981330f76..57a821495 100644 --- a/core/field.ts +++ b/core/field.ts @@ -492,12 +492,12 @@ export abstract class Field implements IASTNodeLocationSvg, return; } if (this.enabled_ && this.sourceBlock_.isEditable()) { - dom.addClass(group, 'blocklyEditableText'); - dom.removeClass(group, 'blocklyNonEditableText'); + group.classList.add('blocklyEditableText'); + group.classList.remove('blocklyNonEditableText'); group.style.cursor = this.CURSOR; } else { - dom.addClass(group, 'blocklyNonEditableText'); - dom.removeClass(group, 'blocklyEditableText'); + group.classList.add('blocklyNonEditableText'); + group.classList.remove('blocklyEditableText'); group.style.cursor = ''; } } diff --git a/core/field_checkbox.ts b/core/field_checkbox.ts index 1a017be8e..6e3753b38 100644 --- a/core/field_checkbox.ts +++ b/core/field_checkbox.ts @@ -17,7 +17,6 @@ import './events/events_block_change.js'; import {FieldConfig, Field} from './field.js'; import * as fieldRegistry from './field_registry.js'; -import * as dom from './utils/dom.js'; import type {Sentinel} from './utils/sentinel.js'; @@ -112,7 +111,7 @@ export class FieldCheckbox extends Field { override initView() { super.initView(); - dom.addClass((this.textElement_), 'blocklyCheckbox'); + this.textElement_.classList.add('blocklyCheckbox'); this.textElement_.style.display = this.value_ ? 'block' : 'none'; } diff --git a/core/field_colour.ts b/core/field_colour.ts index b251917a6..4cf4e19d4 100644 --- a/core/field_colour.ts +++ b/core/field_colour.ts @@ -23,7 +23,6 @@ import {FieldConfig, Field} from './field.js'; import * as fieldRegistry from './field_registry.js'; import * as aria from './utils/aria.js'; import * as colour from './utils/colour.js'; -import * as dom from './utils/dom.js'; import * as idGenerator from './utils/idgenerator.js'; import {KeyCodes} from './utils/keycodes.js'; import type {Sentinel} from './utils/sentinel.js'; @@ -439,7 +438,7 @@ export class FieldColour extends Field { (this.picker_ as AnyDuringMigration)!.blur(); const highlighted = this.getHighlighted_(); if (highlighted) { - dom.removeClass(highlighted, 'blocklyColourHighlighted'); + highlighted.classList.remove('blocklyColourHighlighted'); } } @@ -474,10 +473,10 @@ export class FieldColour extends Field { // Unhighlight the current item. const highlighted = this.getHighlighted_(); if (highlighted) { - dom.removeClass(highlighted, 'blocklyColourHighlighted'); + highlighted.classList.remove('blocklyColourHighlighted'); } // Highlight new item. - dom.addClass(cell, 'blocklyColourHighlighted'); + cell.classList.add('blocklyColourHighlighted'); // Set new highlighted index. this.highlightedIndex_ = index; diff --git a/core/field_dropdown.ts b/core/field_dropdown.ts index 45d93e403..f67db210f 100644 --- a/core/field_dropdown.ts +++ b/core/field_dropdown.ts @@ -203,7 +203,7 @@ export class FieldDropdown extends Field { } if (this.borderRect_) { - dom.addClass(this.borderRect_, 'blocklyDropdownRect'); + this.borderRect_.classList.add('blocklyDropdownRect'); } } @@ -275,7 +275,7 @@ export class FieldDropdown extends Field { // Element gets created in render. this.menu_!.render(dropDownDiv.getContentDiv()); const menuElement = this.menu_!.getElement() as Element; - dom.addClass(menuElement, 'blocklyDropdownMenu'); + menuElement.classList.add('blocklyDropdownMenu'); if (this.getConstants()!.FIELD_DROPDOWN_COLOURED_DIV) { const primaryColour = this.sourceBlock_.isShadow() ? @@ -595,7 +595,7 @@ export class FieldDropdown extends Field { private renderSelectedText_() { // Retrieves the selected option to display through getText_. this.textContent_.nodeValue = this.getDisplayText_(); - dom.addClass(this.textElement_ as Element, 'blocklyDropdownText'); + this.textElement_.classList.add('blocklyDropdownText'); this.textElement_.setAttribute('text-anchor', 'start'); // Height and width include the border rect. diff --git a/core/field_label.ts b/core/field_label.ts index 48cf38f8e..ea7baec15 100644 --- a/core/field_label.ts +++ b/core/field_label.ts @@ -15,7 +15,6 @@ goog.declareModuleId('Blockly.FieldLabel'); import {FieldConfig, Field} from './field.js'; import * as fieldRegistry from './field_registry.js'; -import * as dom from './utils/dom.js'; import * as parsing from './utils/parsing.js'; import type {Sentinel} from './utils/sentinel.js'; @@ -76,7 +75,7 @@ export class FieldLabel extends Field { override initView() { this.createTextElement_(); if (this.class_) { - dom.addClass((this.textElement_), this.class_); + this.textElement_.classList.add(this.class_); } } @@ -101,13 +100,11 @@ export class FieldLabel extends Field { */ setClass(cssClass: string|null) { if (this.textElement_) { - // This check isn't necessary, but it's faster than letting removeClass - // figure it out. if (this.class_) { - dom.removeClass(this.textElement_, this.class_); + this.textElement_.classList.remove(this.class_); } if (cssClass) { - dom.addClass(this.textElement_, cssClass); + this.textElement_.classList.add(cssClass); } } this.class_ = cssClass; diff --git a/core/field_multilineinput.ts b/core/field_multilineinput.ts index f2f1ba0b6..8a5ba7dc6 100644 --- a/core/field_multilineinput.ts +++ b/core/field_multilineinput.ts @@ -239,9 +239,9 @@ export class FieldMultilineInput extends FieldTextInput { if (this.isBeingEdited_) { const htmlInput = this.htmlInput_ as HTMLElement; if (this.isOverflowedY_) { - dom.addClass(htmlInput, 'blocklyHtmlTextAreaInputOverflowedY'); + htmlInput.classList.add('blocklyHtmlTextAreaInputOverflowedY'); } else { - dom.removeClass(htmlInput, 'blocklyHtmlTextAreaInputOverflowedY'); + htmlInput.classList.remove('blocklyHtmlTextAreaInputOverflowedY'); } } @@ -258,10 +258,10 @@ export class FieldMultilineInput extends FieldTextInput { } const htmlInput = this.htmlInput_ as HTMLElement; if (!this.isTextValid_) { - dom.addClass(htmlInput, 'blocklyInvalidInput'); + htmlInput.classList.add('blocklyInvalidInput'); aria.setState(htmlInput, aria.State.INVALID, true); } else { - dom.removeClass(htmlInput, 'blocklyInvalidInput'); + htmlInput.classList.remove('blocklyInvalidInput'); aria.setState(htmlInput, aria.State.INVALID, false); } } diff --git a/core/field_textinput.ts b/core/field_textinput.ts index d1a66e268..8b02f8b9c 100644 --- a/core/field_textinput.ts +++ b/core/field_textinput.ts @@ -25,7 +25,6 @@ import * as fieldRegistry from './field_registry.js'; import {Msg} from './msg.js'; import * as aria from './utils/aria.js'; import {Coordinate} from './utils/coordinate.js'; -import * as dom from './utils/dom.js'; import {KeyCodes} from './utils/keycodes.js'; import * as parsing from './utils/parsing.js'; import type {Sentinel} from './utils/sentinel.js'; @@ -241,10 +240,10 @@ export class FieldTextInput extends Field { this.resizeEditor_(); const htmlInput = this.htmlInput_ as HTMLElement; if (!this.isTextValid_) { - dom.addClass(htmlInput, 'blocklyInvalidInput'); + htmlInput.classList.add('blocklyInvalidInput'); aria.setState(htmlInput, aria.State.INVALID, true); } else { - dom.removeClass(htmlInput, 'blocklyInvalidInput'); + htmlInput.classList.remove('blocklyInvalidInput'); aria.setState(htmlInput, aria.State.INVALID, false); } } @@ -328,7 +327,7 @@ export class FieldTextInput extends Field { eventUtils.setGroup(true); const div = WidgetDiv.getDiv(); - dom.addClass(this.getClickTarget_(), 'editing'); + this.getClickTarget_().classList.add('editing'); const htmlInput = (document.createElement('input')); htmlInput.className = 'blocklyHtmlInput'; @@ -397,7 +396,7 @@ export class FieldTextInput extends Field { style.boxShadow = ''; this.htmlInput_ = null; - dom.removeClass(this.getClickTarget_(), 'editing'); + this.getClickTarget_().classList.remove('editing'); } /** diff --git a/core/icon.ts b/core/icon.ts index 644cf1f82..ad726fc6f 100644 --- a/core/icon.ts +++ b/core/icon.ts @@ -63,7 +63,7 @@ export abstract class Icon { this.iconGroup_ = dom.createSvgElement(Svg.G, {'class': 'blocklyIconGroup'}); if (this.block_.isInFlyout) { - dom.addClass(this.iconGroup_, 'blocklyIconGroupReadonly'); + this.iconGroup_.classList.add('blocklyIconGroupReadonly'); } this.drawIcon_(this.iconGroup_); diff --git a/core/inject.ts b/core/inject.ts index 90cf20787..2ec3a4c26 100644 --- a/core/inject.ts +++ b/core/inject.ts @@ -169,11 +169,15 @@ function createMainWorkspace( svg.appendChild(mainWorkspace.createDom('blocklyMainBackground')); // Set the theme name and renderer name onto the injection div. - dom.addClass( - mainWorkspace.getInjectionDiv(), - mainWorkspace.getRenderer().getClassName()); - dom.addClass( - mainWorkspace.getInjectionDiv(), mainWorkspace.getTheme().getClassName()); + const injectionDiv = mainWorkspace.getInjectionDiv(); + const rendererClassName = mainWorkspace.getRenderer().getClassName(); + if (rendererClassName) { + injectionDiv.classList.add(rendererClassName); + } + const themeClassName = mainWorkspace.getTheme().getClassName(); + if (themeClassName) { + injectionDiv.classList.add(themeClassName); + } if (!wsOptions.hasCategories && wsOptions.languageTree) { // Add flyout as an that is a sibling of the workspace SVG. diff --git a/core/menu.ts b/core/menu.ts index e3612cede..722b5114f 100644 --- a/core/menu.ts +++ b/core/menu.ts @@ -16,7 +16,6 @@ import * as browserEvents from './browser_events.js'; import type {MenuItem} from './menuitem.js'; import * as aria from './utils/aria.js'; import {Coordinate} from './utils/coordinate.js'; -import * as dom from './utils/dom.js'; import {KeyCodes} from './utils/keycodes.js'; import type {Size} from './utils/size.js'; import * as style from './utils/style.js'; @@ -136,7 +135,7 @@ export class Menu { const el = this.getElement(); if (el) { el.focus({preventScroll: true}); - dom.addClass(el, 'blocklyFocused'); + el.classList.add('blocklyFocused'); } } @@ -145,7 +144,7 @@ export class Menu { const el = this.getElement(); if (el) { el.blur(); - dom.removeClass(el, 'blocklyFocused'); + el.classList.remove('blocklyFocused'); } } @@ -207,7 +206,7 @@ export class Menu { // a menu item's div. let currentElement: Element|null = elem; while (currentElement && currentElement !== menuElem) { - if (dom.hasClass(currentElement, 'blocklyMenuItem')) { + if (currentElement.classList.contains('blocklyMenuItem')) { // Having found a menu item's div, locate that menu item in this menu. for (let i = 0, menuItem; menuItem = this.menuItems_[i]; i++) { if (menuItem.getElement() === currentElement) { diff --git a/core/menuitem.ts b/core/menuitem.ts index 3eec5ac69..721c6cfce 100644 --- a/core/menuitem.ts +++ b/core/menuitem.ts @@ -13,7 +13,6 @@ import * as goog from '../closure/goog/goog.js'; goog.declareModuleId('Blockly.MenuItem'); import * as aria from './utils/aria.js'; -import * as dom from './utils/dom.js'; import * as idGenerator from './utils/idgenerator.js'; @@ -196,11 +195,11 @@ export class MenuItem { const name = 'blocklyMenuItemHighlight'; const nameDep = 'goog-menuitem-highlight'; if (highlight) { - dom.addClass(el, name); - dom.addClass(el, nameDep); + el.classList.add(name); + el.classList.add(nameDep); } else { - dom.removeClass(el, name); - dom.removeClass(el, nameDep); + el.classList.remove(name); + el.classList.remove(nameDep); } } } diff --git a/core/mutator.ts b/core/mutator.ts index a29520b92..c470e4898 100644 --- a/core/mutator.ts +++ b/core/mutator.ts @@ -230,14 +230,13 @@ export class Mutator extends Icon { if (!this.block_.isInFlyout) { if (this.block_.isEditable()) { if (this.iconGroup_) { - dom.removeClass( - this.iconGroup_ as Element, 'blocklyIconGroupReadonly'); + this.iconGroup_.classList.remove('blocklyIconGroupReadonly'); } } else { // Close any mutator bubble. Icon is not clickable. this.setVisible(false); if (this.iconGroup_) { - dom.addClass(this.iconGroup_ as Element, 'blocklyIconGroupReadonly'); + this.iconGroup_.classList.add('blocklyIconGroupReadonly'); } } } diff --git a/core/renderers/common/path_object.ts b/core/renderers/common/path_object.ts index f72895a3e..252b27e8e 100644 --- a/core/renderers/common/path_object.ts +++ b/core/renderers/common/path_object.ts @@ -162,10 +162,13 @@ export class PathObject implements IPathObject { * removed. */ protected setClass_(className: string, add: boolean) { + if (!className) { + return; + } if (add) { - dom.addClass(this.svgRoot as Element, className); + this.svgRoot.classList.add(className); } else { - dom.removeClass(this.svgRoot as Element, className); + this.svgRoot.classList.remove(className); } } diff --git a/core/theme_manager.ts b/core/theme_manager.ts index 8630f13fd..1a7bdd3f0 100644 --- a/core/theme_manager.ts +++ b/core/theme_manager.ts @@ -15,7 +15,6 @@ goog.declareModuleId('Blockly.ThemeManager'); import type {Theme} from './theme.js'; import * as arrayUtils from './utils/array.js'; -import * as dom from './utils/dom.js'; import type {Workspace} from './workspace.js'; import type {WorkspaceSvg} from './workspace_svg.js'; @@ -61,9 +60,15 @@ export class ThemeManager { const injectionDiv = this.workspace.getInjectionDiv(); if (injectionDiv) { if (prevTheme) { - dom.removeClass(injectionDiv, prevTheme.getClassName()); + const oldClassName = prevTheme.getClassName(); + if (oldClassName) { + injectionDiv.classList.remove(oldClassName); + } + } + const newClassName = this.theme.getClassName(); + if (newClassName) { + injectionDiv.classList.add(newClassName); } - dom.addClass(injectionDiv, this.theme.getClassName()); } // Refresh all subscribed workspaces. diff --git a/core/toolbox/category.ts b/core/toolbox/category.ts index 9fa3dafaa..70363e345 100644 --- a/core/toolbox/category.ts +++ b/core/toolbox/category.ts @@ -218,11 +218,11 @@ export class ToolboxCategory extends ToolboxItem implements * @returns The div that holds the icon and the label. */ protected createContainer_(): HTMLDivElement { - const container = (document.createElement('div')); - // AnyDuringMigration because: Argument of type 'string | undefined' is not - // assignable to parameter of type 'string'. - dom.addClass( - container, (this.cssConfig_ as AnyDuringMigration)['container']); + const container = document.createElement('div'); + const className = (this.cssConfig_ as AnyDuringMigration)['container']; + if (className) { + container.classList.add(className); + } return container; } @@ -234,9 +234,10 @@ export class ToolboxCategory extends ToolboxItem implements */ protected createRowContainer_(): HTMLDivElement { const rowDiv = (document.createElement('div')); - // AnyDuringMigration because: Argument of type 'string | undefined' is not - // assignable to parameter of type 'string'. - dom.addClass(rowDiv, (this.cssConfig_ as AnyDuringMigration)['row']); + const className = (this.cssConfig_ as AnyDuringMigration)['row']; + if (className) { + rowDiv.classList.add(className); + } let nestedPadding = ToolboxCategory.nestedPadding * this.getLevel(); // AnyDuringMigration because: Type 'string' is not assignable to type // 'number'. @@ -257,12 +258,12 @@ export class ToolboxCategory extends ToolboxItem implements * @returns The div that holds the icon and the label. */ protected createRowContentsContainer_(): HTMLDivElement { - const contentsContainer = (document.createElement('div')); - // AnyDuringMigration because: Argument of type 'string | undefined' is not - // assignable to parameter of type 'string'. - dom.addClass( - contentsContainer, - (this.cssConfig_ as AnyDuringMigration)['rowcontentcontainer']); + const contentsContainer = document.createElement('div'); + const className = + (this.cssConfig_ as AnyDuringMigration)['rowcontentcontainer']; + if (className) { + contentsContainer.classList.add(className); + } return contentsContainer; } @@ -274,10 +275,10 @@ export class ToolboxCategory extends ToolboxItem implements protected createIconDom_(): Element { const toolboxIcon = document.createElement('span'); if (!this.parentToolbox_.isHorizontal()) { - // AnyDuringMigration because: Argument of type 'string | undefined' is - // not assignable to parameter of type 'string'. - dom.addClass( - toolboxIcon, (this.cssConfig_ as AnyDuringMigration)['icon']); + const className = (this.cssConfig_ as AnyDuringMigration)['icon']; + if (className) { + toolboxIcon.classList.add(className); + } } toolboxIcon.style.display = 'inline-block'; @@ -295,10 +296,10 @@ export class ToolboxCategory extends ToolboxItem implements const toolboxLabel = document.createElement('span'); toolboxLabel.setAttribute('id', this.getId() + '.label'); toolboxLabel.textContent = name; - // AnyDuringMigration because: Argument of type 'string | undefined' is not - // assignable to parameter of type 'string'. - dom.addClass( - toolboxLabel, (this.cssConfig_ as AnyDuringMigration)['label']); + const className = (this.cssConfig_ as AnyDuringMigration)['label']; + if (className) { + toolboxLabel.classList.add(className); + } return toolboxLabel; } @@ -428,9 +429,10 @@ export class ToolboxCategory extends ToolboxItem implements // assignable to parameter of type 'string'. dom.removeClasses( iconDiv, (this.cssConfig_ as AnyDuringMigration)['closedicon']); - // AnyDuringMigration because: Argument of type 'string | undefined' is not - // assignable to parameter of type 'string'. - dom.addClass(iconDiv, (this.cssConfig_ as AnyDuringMigration)['openicon']); + const className = (this.cssConfig_ as AnyDuringMigration)['openicon']; + if (className) { + iconDiv.classList.add(className); + } } /** @@ -446,10 +448,10 @@ export class ToolboxCategory extends ToolboxItem implements // assignable to parameter of type 'string'. dom.removeClasses( iconDiv, (this.cssConfig_ as AnyDuringMigration)['openicon']); - // AnyDuringMigration because: Argument of type 'string | undefined' is not - // assignable to parameter of type 'string'. - dom.addClass( - iconDiv, (this.cssConfig_ as AnyDuringMigration)['closedicon']); + const className = (this.cssConfig_ as AnyDuringMigration)['closedicon']; + if (className) { + iconDiv.classList.add(className); + } } /** @@ -527,14 +529,22 @@ export class ToolboxCategory extends ToolboxItem implements * @param isSelected True if this category is selected, false otherwise. */ setSelected(isSelected: boolean) { + if (!this.rowDiv_) { + return; + } + const className = (this.cssConfig_ as AnyDuringMigration)['selected']; if (isSelected) { const defaultColour = this.parseColour_(ToolboxCategory.defaultBackgroundColour); - this.rowDiv_!.style.backgroundColor = this.colour_ || defaultColour; - dom.addClass(this.rowDiv_!, this.cssConfig_['selected']!); + this.rowDiv_.style.backgroundColor = this.colour_ || defaultColour; + if (className) { + this.rowDiv_.classList.add(className); + } } else { - this.rowDiv_!.style.backgroundColor = ''; - dom.removeClass(this.rowDiv_!, this.cssConfig_['selected']!); + this.rowDiv_.style.backgroundColor = ''; + if (className) { + this.rowDiv_.classList.remove(className); + } } aria.setState(this.htmlDiv_ as Element, aria.State.SELECTED, isSelected); } diff --git a/core/toolbox/collapsible_category.ts b/core/toolbox/collapsible_category.ts index 069f4335b..d20dc4269 100644 --- a/core/toolbox/collapsible_category.ts +++ b/core/toolbox/collapsible_category.ts @@ -17,7 +17,6 @@ import type {IToolbox} from '../interfaces/i_toolbox.js'; import type {IToolboxItem} from '../interfaces/i_toolbox_item.js'; import * as registry from '../registry.js'; import * as aria from '../utils/aria.js'; -import * as dom from '../utils/dom.js'; import * as toolbox from '../utils/toolbox.js'; import {ToolboxCategory} from './category.js'; @@ -141,10 +140,10 @@ export class CollapsibleToolboxCategory extends ToolboxCategory implements override createIconDom_() { const toolboxIcon = document.createElement('span'); if (!this.parentToolbox_.isHorizontal()) { - // AnyDuringMigration because: Argument of type 'string | undefined' is - // not assignable to parameter of type 'string'. - dom.addClass( - toolboxIcon, (this.cssConfig_ as AnyDuringMigration)['icon']); + const className = (this.cssConfig_ as AnyDuringMigration)['icon']; + if (className) { + toolboxIcon.classList.add(className); + } toolboxIcon.style.visibility = 'visible'; } @@ -160,9 +159,11 @@ export class CollapsibleToolboxCategory extends ToolboxCategory implements */ protected createSubCategoriesDom_(subcategories: IToolboxItem[]): HTMLDivElement { - const contentsContainer = (document.createElement('div')); - dom.addClass( - contentsContainer, (this.cssConfig_ as AnyDuringMigration)['contents']); + const contentsContainer = document.createElement('div'); + const className = (this.cssConfig_ as AnyDuringMigration)['contents']; + if (className) { + contentsContainer.classList.add(className); + } for (let i = 0; i < subcategories.length; i++) { const newCategory = subcategories[i]; diff --git a/core/toolbox/separator.ts b/core/toolbox/separator.ts index 09f1a46ea..1944552f8 100644 --- a/core/toolbox/separator.ts +++ b/core/toolbox/separator.ts @@ -58,8 +58,11 @@ export class ToolboxSeparator extends ToolboxItem { * @returns The parent element for the separator. */ protected createDom_(): HTMLDivElement { - const container = (document.createElement('div')); - dom.addClass(container, this.cssConfig_['container']!); + const container = document.createElement('div'); + const className = (this.cssConfig_ as AnyDuringMigration)['container']; + if (className) { + container.classList.add(className); + } this.htmlDiv_ = container; return container; } diff --git a/core/toolbox/toolbox.ts b/core/toolbox/toolbox.ts index 4c94b056f..14ab5c3b1 100644 --- a/core/toolbox/toolbox.ts +++ b/core/toolbox/toolbox.ts @@ -198,8 +198,8 @@ export class Toolbox extends DeleteArea implements IAutoHideable, protected createContainer_(): HTMLDivElement { const toolboxContainer = (document.createElement('div')); toolboxContainer.setAttribute('layout', this.isHorizontal() ? 'h' : 'v'); - dom.addClass(toolboxContainer, 'blocklyToolboxDiv'); - dom.addClass(toolboxContainer, 'blocklyNonSelectable'); + toolboxContainer.classList.add('blocklyToolboxDiv'); + toolboxContainer.classList.add('blocklyNonSelectable'); toolboxContainer.setAttribute('dir', this.RTL ? 'RTL' : 'LTR'); return toolboxContainer; } @@ -211,7 +211,7 @@ export class Toolbox extends DeleteArea implements IAutoHideable, */ protected createContentsContainer_(): HTMLDivElement { const contentsContainer = (document.createElement('div')); - dom.addClass(contentsContainer, 'blocklyToolboxContents'); + contentsContainer.classList.add('blocklyToolboxContents'); if (this.isHorizontal()) { contentsContainer.style.flexDirection = 'row'; } @@ -453,7 +453,9 @@ export class Toolbox extends DeleteArea implements IAutoHideable, * @internal */ addStyle(style: string) { - dom.addClass(this.HtmlDiv as Element, style); + if (style) { + this.HtmlDiv?.classList.add(style); + } } /** @@ -463,7 +465,9 @@ export class Toolbox extends DeleteArea implements IAutoHideable, * @internal */ removeStyle(style: string) { - dom.removeClass(this.HtmlDiv as Element, style); + if (style) { + this.HtmlDiv?.classList.remove(style); + } } /** diff --git a/core/utils/dom.ts b/core/utils/dom.ts index 2db279b43..605774bdb 100644 --- a/core/utils/dom.ts +++ b/core/utils/dom.ts @@ -115,7 +115,7 @@ export function addClass(element: Element, className: string): boolean { export function removeClasses(element: Element, classNames: string) { const classList = classNames.split(' '); for (let i = 0; i < classList.length; i++) { - removeClass(element, classList[i]); + element.classList.remove(classList[i]); } } diff --git a/core/widgetdiv.ts b/core/widgetdiv.ts index 85fbee2e6..2b21487ad 100644 --- a/core/widgetdiv.ts +++ b/core/widgetdiv.ts @@ -15,7 +15,6 @@ import * as goog from '../closure/goog/goog.js'; goog.declareModuleId('Blockly.WidgetDiv'); import * as common from './common.js'; -import * as dom from './utils/dom.js'; import type {Rect} from './utils/rect.js'; import type {Size} from './utils/size.js'; import type {WorkspaceSvg} from './workspace_svg.js'; @@ -93,8 +92,12 @@ export function show(newOwner: unknown, rtl: boolean, newDispose: () => void) { const mainWorkspace = common.getMainWorkspace() as WorkspaceSvg; rendererClassName = mainWorkspace.getRenderer().getClassName(); themeClassName = mainWorkspace.getTheme().getClassName(); - dom.addClass(div, rendererClassName); - dom.addClass(div, themeClassName); + if (rendererClassName) { + div.classList.add(rendererClassName); + } + if (themeClassName) { + div.classList.add(themeClassName); + } } /** @@ -118,11 +121,11 @@ export function hide() { div.textContent = ''; if (rendererClassName) { - dom.removeClass(div, rendererClassName); + div.classList.remove(rendererClassName); rendererClassName = ''; } if (themeClassName) { - dom.removeClass(div, themeClassName); + div.classList.remove(themeClassName); themeClassName = ''; } (common.getMainWorkspace() as WorkspaceSvg).markFocused(); diff --git a/core/workspace_comment_svg.ts b/core/workspace_comment_svg.ts index 96eccc7cc..2c1d4e025 100644 --- a/core/workspace_comment_svg.ts +++ b/core/workspace_comment_svg.ts @@ -263,7 +263,7 @@ export class WorkspaceCommentSvg extends WorkspaceComment implements * @internal */ addSelect() { - dom.addClass(this.svgGroup_ as Element, 'blocklySelected'); + this.svgGroup_.classList.add('blocklySelected'); this.setFocus(); } @@ -273,7 +273,7 @@ export class WorkspaceCommentSvg extends WorkspaceComment implements * @internal */ removeSelect() { - dom.removeClass(this.svgGroup_ as Element, 'blocklySelected'); + this.svgGroup_.classList.add('blocklySelected'); this.blurFocus(); } @@ -283,7 +283,7 @@ export class WorkspaceCommentSvg extends WorkspaceComment implements * @internal */ addFocus() { - dom.addClass(this.svgGroup_ as Element, 'blocklyFocused'); + this.svgGroup_.classList.add('blocklyFocused'); } /** @@ -292,7 +292,7 @@ export class WorkspaceCommentSvg extends WorkspaceComment implements * @internal */ removeFocus() { - dom.removeClass(this.svgGroup_ as Element, 'blocklyFocused'); + this.svgGroup_.classList.remove('blocklyFocused'); } /** @@ -473,9 +473,9 @@ export class WorkspaceCommentSvg extends WorkspaceComment implements */ updateMovable() { if (this.isMovable()) { - dom.addClass(this.svgGroup_ as Element, 'blocklyDraggable'); + this.svgGroup_.classList.add('blocklyDraggable'); } else { - dom.removeClass(this.svgGroup_ as Element, 'blocklyDraggable'); + this.svgGroup_.classList.remove('blocklyDraggable'); } } @@ -514,9 +514,9 @@ export class WorkspaceCommentSvg extends WorkspaceComment implements const group = this.getSvgRoot(); (group as AnyDuringMigration).translate_ = ''; (group as AnyDuringMigration).skew_ = ''; - dom.addClass(this.svgGroup_ as Element, 'blocklyDragging'); + this.svgGroup_.classList.add('blocklyDragging'); } else { - dom.removeClass(this.svgGroup_ as Element, 'blocklyDragging'); + this.svgGroup_.classList.remove('blocklyDragging'); } } @@ -561,9 +561,9 @@ export class WorkspaceCommentSvg extends WorkspaceComment implements */ setDeleteStyle(enable: boolean) { if (enable) { - dom.addClass(this.svgGroup_ as Element, 'blocklyDraggingDelete'); + this.svgGroup_.classList.add('blocklyDraggingDelete'); } else { - dom.removeClass(this.svgGroup_ as Element, 'blocklyDraggingDelete'); + this.svgGroup_.classList.remove('blocklyDraggingDelete'); } } @@ -853,8 +853,7 @@ export class WorkspaceCommentSvg extends WorkspaceComment implements */ private deleteMouseDown_(e: Event) { // Highlight the delete icon. - dom.addClass( - this.deleteIconBorder_ as Element, 'blocklyDeleteIconHighlighted'); + this.deleteIconBorder_?.classList.add('blocklyDeleteIconHighlighted'); // This event has been handled. No need to bubble up to the document. e.stopPropagation(); } @@ -866,8 +865,7 @@ export class WorkspaceCommentSvg extends WorkspaceComment implements */ private deleteMouseOut_(_e: Event) { // Restore highlight on the delete icon. - dom.removeClass( - this.deleteIconBorder_ as Element, 'blocklyDeleteIconHighlighted'); + this.deleteIconBorder_?.classList.remove('blocklyDeleteIconHighlighted'); } /** @@ -1018,11 +1016,8 @@ export class WorkspaceCommentSvg extends WorkspaceComment implements } this.textarea_!.focus(); this.addFocus(); - dom.addClass( - this.svgRectTarget_ as SVGRectElement, 'blocklyCommentTargetFocused'); - dom.addClass( - this.svgHandleTarget_ as SVGRectElement, - 'blocklyCommentHandleTargetFocused'); + this.svgRectTarget_?.classList.add('blocklyCommentTargetFocused'); + this.svgHandleTarget_?.classList.add('blocklyCommentHandleTargetFocused'); }, 0); } @@ -1041,10 +1036,8 @@ export class WorkspaceCommentSvg extends WorkspaceComment implements this.textarea_!.blur(); this.removeFocus(); - dom.removeClass( - this.svgRectTarget_ as SVGRectElement, 'blocklyCommentTargetFocused'); - dom.removeClass( - this.svgHandleTarget_ as SVGRectElement, + this.svgRectTarget_?.classList.remove('blocklyCommentTargetFocused'); + this.svgHandleTarget_?.classList.remove( 'blocklyCommentHandleTargetFocused'); }, 0); } diff --git a/core/workspace_drag_surface_svg.ts b/core/workspace_drag_surface_svg.ts index 6694fbb14..c20678609 100644 --- a/core/workspace_drag_surface_svg.ts +++ b/core/workspace_drag_surface_svg.ts @@ -114,8 +114,8 @@ export class WorkspaceDragSurfaceSvg { const blockCanvas = this.SVG.childNodes[0] as Element; const bubbleCanvas = this.SVG.childNodes[1] as Element; if (!blockCanvas || !bubbleCanvas || - !dom.hasClass(blockCanvas, 'blocklyBlockCanvas') || - !dom.hasClass(bubbleCanvas, 'blocklyBubbleCanvas')) { + !(blockCanvas.classList.contains('blocklyBlockCanvas') || + !bubbleCanvas.classList.contains('blocklyBubbleCanvas'))) { throw Error( 'Couldn\'t clear and hide the drag surface. A node was missing.'); } diff --git a/core/workspace_svg.ts b/core/workspace_svg.ts index e10ab85d4..b401412ed 100644 --- a/core/workspace_svg.ts +++ b/core/workspace_svg.ts @@ -2082,8 +2082,8 @@ export class WorkspaceSvg extends Workspace implements IASTNodeLocationSvg { * @internal */ beginCanvasTransition() { - dom.addClass((this.svgBlockCanvas_), 'blocklyCanvasTransitioning'); - dom.addClass((this.svgBubbleCanvas_), 'blocklyCanvasTransitioning'); + this.svgBlockCanvas_.classList.add('blocklyCanvasTransitioning'); + this.svgBubbleCanvas_.classList.add('blocklyCanvasTransitioning'); } /** @@ -2092,8 +2092,8 @@ export class WorkspaceSvg extends Workspace implements IASTNodeLocationSvg { * @internal */ endCanvasTransition() { - dom.removeClass((this.svgBlockCanvas_), 'blocklyCanvasTransitioning'); - dom.removeClass((this.svgBubbleCanvas_), 'blocklyCanvasTransitioning'); + this.svgBlockCanvas_.classList.remove('blocklyCanvasTransitioning'); + this.svgBubbleCanvas_.classList.remove('blocklyCanvasTransitioning'); } /** Center the workspace. */