mirror of
https://github.com/google/blockly.git
synced 2026-03-12 16:20:12 +01:00
fix: adding and removing css classes that contained spaces (#6455)
* fix: adding CSS classes * fix: removing css classes * fix: add a test for multiple icon classes * chore: format
This commit is contained in:
@@ -778,10 +778,10 @@ export class BlockSvg extends Block implements IASTNodeLocationSvg,
|
||||
(group as AnyDuringMigration).translate_ = '';
|
||||
(group as AnyDuringMigration).skew_ = '';
|
||||
common.draggingConnections.push(...this.getConnections_(true));
|
||||
this.svgGroup_.classList.add('blocklyDragging');
|
||||
dom.addClass(this.svgGroup_, 'blocklyDragging');
|
||||
} else {
|
||||
common.draggingConnections.length = 0;
|
||||
this.svgGroup_.classList.remove('blocklyDragging');
|
||||
dom.removeClass(this.svgGroup_, 'blocklyDragging');
|
||||
}
|
||||
// Recurse through all blocks attached under this one.
|
||||
for (let i = 0; i < this.childBlocks_.length; i++) {
|
||||
|
||||
@@ -17,6 +17,7 @@ import type {BlockSvg} from './block_svg.js';
|
||||
import * as browserEvents from './browser_events.js';
|
||||
import * as clipboard from './clipboard.js';
|
||||
import {config} from './config.js';
|
||||
import * as dom from './utils/dom.js';
|
||||
import type {ContextMenuOption, LegacyContextMenuOption} from './contextmenu_registry.js';
|
||||
import * as eventUtils from './events/utils.js';
|
||||
import {Menu} from './menu.js';
|
||||
@@ -179,7 +180,7 @@ function createWidget_(menu: Menu) {
|
||||
throw Error('Attempting to create a context menu when widget div is null');
|
||||
}
|
||||
const menuDom = menu.render(div);
|
||||
menuDom.classList.add('blocklyContextMenu');
|
||||
dom.addClass(menuDom, 'blocklyContextMenu');
|
||||
// Prevent system context menu when right-clicking a Blockly context menu.
|
||||
browserEvents.conditionalBind(
|
||||
(menuDom as EventTarget), 'contextmenu', null, haltPropagation);
|
||||
|
||||
@@ -15,6 +15,7 @@ goog.declareModuleId('Blockly.dropDownDiv');
|
||||
|
||||
import type {BlockSvg} from './block_svg.js';
|
||||
import * as common from './common.js';
|
||||
import * as dom from './utils/dom.js';
|
||||
import type {Field} from './field.js';
|
||||
import * as math from './utils/math.js';
|
||||
import {Rect} from './utils/rect.js';
|
||||
@@ -138,10 +139,10 @@ export function createDom() {
|
||||
// Handle focusin/out events to add a visual indicator when
|
||||
// a child is focused or blurred.
|
||||
div.addEventListener('focusin', function() {
|
||||
div.classList.add('blocklyFocused');
|
||||
dom.addClass(div, 'blocklyFocused');
|
||||
});
|
||||
div.addEventListener('focusout', function() {
|
||||
div.classList.remove('blocklyFocused');
|
||||
dom.removeClass(div, 'blocklyFocused');
|
||||
});
|
||||
}
|
||||
|
||||
@@ -311,10 +312,10 @@ export function show(
|
||||
renderedClassName = mainWorkspace.getRenderer().getClassName();
|
||||
themeClassName = mainWorkspace.getTheme().getClassName();
|
||||
if (renderedClassName) {
|
||||
div.classList.add(renderedClassName);
|
||||
dom.addClass(div, renderedClassName);
|
||||
}
|
||||
if (themeClassName) {
|
||||
div.classList.add(themeClassName);
|
||||
dom.addClass(div, themeClassName);
|
||||
}
|
||||
|
||||
// When we change `translate` multiple times in close succession,
|
||||
@@ -595,11 +596,11 @@ export function hideWithoutAnimation() {
|
||||
owner = null;
|
||||
|
||||
if (renderedClassName) {
|
||||
div.classList.remove(renderedClassName);
|
||||
dom.removeClass(div, renderedClassName);
|
||||
renderedClassName = '';
|
||||
}
|
||||
if (themeClassName) {
|
||||
div.classList.remove(themeClassName);
|
||||
dom.removeClass(div, themeClassName);
|
||||
themeClassName = '';
|
||||
}
|
||||
(common.getMainWorkspace() as WorkspaceSvg).markFocused();
|
||||
|
||||
@@ -492,12 +492,12 @@ export abstract class Field implements IASTNodeLocationSvg,
|
||||
return;
|
||||
}
|
||||
if (this.enabled_ && this.sourceBlock_.isEditable()) {
|
||||
group.classList.add('blocklyEditableText');
|
||||
group.classList.remove('blocklyNonEditableText');
|
||||
dom.addClass(group, 'blocklyEditableText');
|
||||
dom.removeClass(group, 'blocklyNonEditableText');
|
||||
group.style.cursor = this.CURSOR;
|
||||
} else {
|
||||
group.classList.add('blocklyNonEditableText');
|
||||
group.classList.remove('blocklyEditableText');
|
||||
dom.addClass(group, 'blocklyNonEditableText');
|
||||
dom.removeClass(group, 'blocklyEditableText');
|
||||
group.style.cursor = '';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ goog.declareModuleId('Blockly.FieldCheckbox');
|
||||
// Unused import preserved for side-effects. Remove if unneeded.
|
||||
import './events/events_block_change.js';
|
||||
|
||||
import * as dom from './utils/dom.js';
|
||||
import {FieldConfig, Field} from './field.js';
|
||||
import * as fieldRegistry from './field_registry.js';
|
||||
import type {Sentinel} from './utils/sentinel.js';
|
||||
@@ -111,7 +112,7 @@ export class FieldCheckbox extends Field {
|
||||
override initView() {
|
||||
super.initView();
|
||||
|
||||
this.textElement_.classList.add('blocklyCheckbox');
|
||||
dom.addClass(this.textElement_, 'blocklyCheckbox');
|
||||
this.textElement_.style.display = this.value_ ? 'block' : 'none';
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ import './events/events_block_change.js';
|
||||
import {BlockSvg} from './block_svg.js';
|
||||
import * as browserEvents from './browser_events.js';
|
||||
import * as Css from './css.js';
|
||||
import * as dom from './utils/dom.js';
|
||||
import * as dropDownDiv from './dropdowndiv.js';
|
||||
import {FieldConfig, Field} from './field.js';
|
||||
import * as fieldRegistry from './field_registry.js';
|
||||
@@ -438,7 +439,7 @@ export class FieldColour extends Field {
|
||||
(this.picker_ as AnyDuringMigration)!.blur();
|
||||
const highlighted = this.getHighlighted_();
|
||||
if (highlighted) {
|
||||
highlighted.classList.remove('blocklyColourHighlighted');
|
||||
dom.removeClass(highlighted, 'blocklyColourHighlighted');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -473,10 +474,10 @@ export class FieldColour extends Field {
|
||||
// Unhighlight the current item.
|
||||
const highlighted = this.getHighlighted_();
|
||||
if (highlighted) {
|
||||
highlighted.classList.remove('blocklyColourHighlighted');
|
||||
dom.removeClass(highlighted, 'blocklyColourHighlighted');
|
||||
}
|
||||
// Highlight new item.
|
||||
cell.classList.add('blocklyColourHighlighted');
|
||||
dom.addClass(cell, 'blocklyColourHighlighted');
|
||||
// Set new highlighted index.
|
||||
this.highlightedIndex_ = index;
|
||||
|
||||
|
||||
@@ -205,7 +205,7 @@ export class FieldDropdown extends Field {
|
||||
}
|
||||
|
||||
if (this.borderRect_) {
|
||||
this.borderRect_.classList.add('blocklyDropdownRect');
|
||||
dom.addClass(this.borderRect_, 'blocklyDropdownRect');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -276,7 +276,7 @@ export class FieldDropdown extends Field {
|
||||
dropDownDiv.clearContent();
|
||||
// Element gets created in render.
|
||||
const menuElement = this.menu_!.render(dropDownDiv.getContentDiv());
|
||||
menuElement.classList.add('blocklyDropdownMenu');
|
||||
dom.addClass(menuElement, 'blocklyDropdownMenu');
|
||||
|
||||
if (this.getConstants()!.FIELD_DROPDOWN_COLOURED_DIV) {
|
||||
const primaryColour = this.sourceBlock_.isShadow() ?
|
||||
@@ -608,7 +608,7 @@ export class FieldDropdown extends Field {
|
||||
private renderSelectedText_() {
|
||||
// Retrieves the selected option to display through getText_.
|
||||
this.textContent_.nodeValue = this.getDisplayText_();
|
||||
this.textElement_.classList.add('blocklyDropdownText');
|
||||
dom.addClass(this.textElement_, 'blocklyDropdownText');
|
||||
this.textElement_.setAttribute('text-anchor', 'start');
|
||||
|
||||
// Height and width include the border rect.
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
import * as goog from '../closure/goog/goog.js';
|
||||
goog.declareModuleId('Blockly.FieldLabel');
|
||||
|
||||
import * as dom from './utils/dom.js';
|
||||
import {FieldConfig, Field} from './field.js';
|
||||
import * as fieldRegistry from './field_registry.js';
|
||||
import * as parsing from './utils/parsing.js';
|
||||
@@ -75,7 +76,7 @@ export class FieldLabel extends Field {
|
||||
override initView() {
|
||||
this.createTextElement_();
|
||||
if (this.class_) {
|
||||
this.textElement_.classList.add(this.class_);
|
||||
dom.addClass(this.textElement_, this.class_);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -101,10 +102,10 @@ export class FieldLabel extends Field {
|
||||
setClass(cssClass: string|null) {
|
||||
if (this.textElement_) {
|
||||
if (this.class_) {
|
||||
this.textElement_.classList.remove(this.class_);
|
||||
dom.removeClass(this.textElement_, this.class_);
|
||||
}
|
||||
if (cssClass) {
|
||||
this.textElement_.classList.add(cssClass);
|
||||
dom.addClass(this.textElement_, cssClass);
|
||||
}
|
||||
}
|
||||
this.class_ = cssClass;
|
||||
|
||||
@@ -239,9 +239,9 @@ export class FieldMultilineInput extends FieldTextInput {
|
||||
if (this.isBeingEdited_) {
|
||||
const htmlInput = this.htmlInput_ as HTMLElement;
|
||||
if (this.isOverflowedY_) {
|
||||
htmlInput.classList.add('blocklyHtmlTextAreaInputOverflowedY');
|
||||
dom.addClass(htmlInput, 'blocklyHtmlTextAreaInputOverflowedY');
|
||||
} else {
|
||||
htmlInput.classList.remove('blocklyHtmlTextAreaInputOverflowedY');
|
||||
dom.removeClass(htmlInput, 'blocklyHtmlTextAreaInputOverflowedY');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -258,10 +258,10 @@ export class FieldMultilineInput extends FieldTextInput {
|
||||
}
|
||||
const htmlInput = this.htmlInput_ as HTMLElement;
|
||||
if (!this.isTextValid_) {
|
||||
htmlInput.classList.add('blocklyInvalidInput');
|
||||
dom.addClass(htmlInput, 'blocklyInvalidInput');
|
||||
aria.setState(htmlInput, aria.State.INVALID, true);
|
||||
} else {
|
||||
htmlInput.classList.remove('blocklyInvalidInput');
|
||||
dom.removeClass(htmlInput, 'blocklyInvalidInput');
|
||||
aria.setState(htmlInput, aria.State.INVALID, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ import './events/events_block_change.js';
|
||||
import type {BlockSvg} from './block_svg.js';
|
||||
import * as browserEvents from './browser_events.js';
|
||||
import * as dialog from './dialog.js';
|
||||
import * as dom from './utils/dom.js';
|
||||
import * as dropDownDiv from './dropdowndiv.js';
|
||||
import * as eventUtils from './events/utils.js';
|
||||
import {FieldConfig, Field} from './field.js';
|
||||
@@ -244,10 +245,10 @@ export class FieldTextInput extends Field {
|
||||
this.resizeEditor_();
|
||||
const htmlInput = this.htmlInput_ as HTMLElement;
|
||||
if (!this.isTextValid_) {
|
||||
htmlInput.classList.add('blocklyInvalidInput');
|
||||
dom.addClass(htmlInput, 'blocklyInvalidInput');
|
||||
aria.setState(htmlInput, aria.State.INVALID, true);
|
||||
} else {
|
||||
htmlInput.classList.remove('blocklyInvalidInput');
|
||||
dom.removeClass(htmlInput, 'blocklyInvalidInput');
|
||||
aria.setState(htmlInput, aria.State.INVALID, false);
|
||||
}
|
||||
}
|
||||
@@ -331,7 +332,7 @@ export class FieldTextInput extends Field {
|
||||
eventUtils.setGroup(true);
|
||||
const div = WidgetDiv.getDiv();
|
||||
|
||||
this.getClickTarget_().classList.add('editing');
|
||||
dom.addClass(this.getClickTarget_(), 'editing');
|
||||
|
||||
const htmlInput = (document.createElement('input'));
|
||||
htmlInput.className = 'blocklyHtmlInput';
|
||||
@@ -400,7 +401,7 @@ export class FieldTextInput extends Field {
|
||||
style.boxShadow = '';
|
||||
this.htmlInput_ = null;
|
||||
|
||||
this.getClickTarget_().classList.remove('editing');
|
||||
dom.removeClass(this.getClickTarget_(), 'editing');
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -69,7 +69,7 @@ export abstract class Icon {
|
||||
this.iconGroup_ =
|
||||
dom.createSvgElement(Svg.G, {'class': 'blocklyIconGroup'});
|
||||
if (this.getBlock().isInFlyout) {
|
||||
this.iconGroup_.classList.add('blocklyIconGroupReadonly');
|
||||
dom.addClass(this.iconGroup_, 'blocklyIconGroupReadonly');
|
||||
}
|
||||
this.drawIcon_(this.iconGroup_);
|
||||
|
||||
|
||||
@@ -172,11 +172,11 @@ function createMainWorkspace(
|
||||
const injectionDiv = mainWorkspace.getInjectionDiv();
|
||||
const rendererClassName = mainWorkspace.getRenderer().getClassName();
|
||||
if (rendererClassName) {
|
||||
injectionDiv.classList.add(rendererClassName);
|
||||
dom.addClass(injectionDiv, rendererClassName);
|
||||
}
|
||||
const themeClassName = mainWorkspace.getTheme().getClassName();
|
||||
if (themeClassName) {
|
||||
injectionDiv.classList.add(themeClassName);
|
||||
dom.addClass(injectionDiv, themeClassName);
|
||||
}
|
||||
|
||||
if (!wsOptions.hasCategories && wsOptions.languageTree) {
|
||||
|
||||
@@ -16,6 +16,7 @@ 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';
|
||||
@@ -137,7 +138,7 @@ export class Menu {
|
||||
const el = this.getElement();
|
||||
if (el) {
|
||||
el.focus({preventScroll: true});
|
||||
el.classList.add('blocklyFocused');
|
||||
dom.addClass(el, 'blocklyFocused');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -146,7 +147,7 @@ export class Menu {
|
||||
const el = this.getElement();
|
||||
if (el) {
|
||||
el.blur();
|
||||
el.classList.remove('blocklyFocused');
|
||||
dom.removeClass(el, 'blocklyFocused');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ 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';
|
||||
|
||||
|
||||
@@ -195,11 +196,11 @@ export class MenuItem {
|
||||
const name = 'blocklyMenuItemHighlight';
|
||||
const nameDep = 'goog-menuitem-highlight';
|
||||
if (highlight) {
|
||||
el.classList.add(name);
|
||||
el.classList.add(nameDep);
|
||||
dom.addClass(el, name);
|
||||
dom.addClass(el, nameDep);
|
||||
} else {
|
||||
el.classList.remove(name);
|
||||
el.classList.remove(nameDep);
|
||||
dom.removeClass(el, name);
|
||||
dom.removeClass(el, nameDep);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -238,13 +238,13 @@ export class Mutator extends Icon {
|
||||
if (!this.getBlock().isInFlyout) {
|
||||
if (this.getBlock().isEditable()) {
|
||||
if (this.iconGroup_) {
|
||||
this.iconGroup_.classList.remove('blocklyIconGroupReadonly');
|
||||
dom.removeClass(this.iconGroup_, 'blocklyIconGroupReadonly');
|
||||
}
|
||||
} else {
|
||||
// Close any mutator bubble. Icon is not clickable.
|
||||
this.setVisible(false);
|
||||
if (this.iconGroup_) {
|
||||
this.iconGroup_.classList.add('blocklyIconGroupReadonly');
|
||||
dom.addClass(this.iconGroup_, 'blocklyIconGroupReadonly');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -170,9 +170,9 @@ export class PathObject implements IPathObject {
|
||||
return;
|
||||
}
|
||||
if (add) {
|
||||
this.svgRoot.classList.add(className);
|
||||
dom.addClass(this.svgRoot, className);
|
||||
} else {
|
||||
this.svgRoot.classList.remove(className);
|
||||
dom.removeClass(this.svgRoot, className);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ 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';
|
||||
|
||||
@@ -62,12 +63,12 @@ export class ThemeManager {
|
||||
if (prevTheme) {
|
||||
const oldClassName = prevTheme.getClassName();
|
||||
if (oldClassName) {
|
||||
injectionDiv.classList.remove(oldClassName);
|
||||
dom.removeClass(injectionDiv, oldClassName);
|
||||
}
|
||||
}
|
||||
const newClassName = this.theme.getClassName();
|
||||
if (newClassName) {
|
||||
injectionDiv.classList.add(newClassName);
|
||||
dom.addClass(injectionDiv, newClassName);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -219,7 +219,7 @@ export class ToolboxCategory extends ToolboxItem implements
|
||||
const container = document.createElement('div');
|
||||
const className = this.cssConfig_['container'];
|
||||
if (className) {
|
||||
container.classList.add(className);
|
||||
dom.addClass(container, className);
|
||||
}
|
||||
return container;
|
||||
}
|
||||
@@ -234,7 +234,7 @@ export class ToolboxCategory extends ToolboxItem implements
|
||||
const rowDiv = document.createElement('div');
|
||||
const className = this.cssConfig_['row'];
|
||||
if (className) {
|
||||
rowDiv.classList.add(className);
|
||||
dom.addClass(rowDiv, className);
|
||||
}
|
||||
const nestedPadding =
|
||||
`${ToolboxCategory.nestedPadding * this.getLevel()}px`;
|
||||
@@ -253,7 +253,7 @@ export class ToolboxCategory extends ToolboxItem implements
|
||||
const contentsContainer = document.createElement('div');
|
||||
const className = this.cssConfig_['rowcontentcontainer'];
|
||||
if (className) {
|
||||
contentsContainer.classList.add(className);
|
||||
dom.addClass(contentsContainer, className);
|
||||
}
|
||||
return contentsContainer;
|
||||
}
|
||||
@@ -268,7 +268,7 @@ export class ToolboxCategory extends ToolboxItem implements
|
||||
if (!this.parentToolbox_.isHorizontal()) {
|
||||
const className = this.cssConfig_['icon'];
|
||||
if (className) {
|
||||
toolboxIcon.classList.add(className);
|
||||
dom.addClass(toolboxIcon, className);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -289,7 +289,7 @@ export class ToolboxCategory extends ToolboxItem implements
|
||||
toolboxLabel.textContent = name;
|
||||
const className = this.cssConfig_['label'];
|
||||
if (className) {
|
||||
toolboxLabel.classList.add(className);
|
||||
dom.addClass(toolboxLabel, className);
|
||||
}
|
||||
return toolboxLabel;
|
||||
}
|
||||
@@ -420,7 +420,7 @@ export class ToolboxCategory extends ToolboxItem implements
|
||||
}
|
||||
const className = this.cssConfig_['openicon'];
|
||||
if (className) {
|
||||
iconDiv.classList.add(className);
|
||||
dom.addClass(iconDiv, className);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -439,7 +439,7 @@ export class ToolboxCategory extends ToolboxItem implements
|
||||
}
|
||||
const className = this.cssConfig_['closedicon'];
|
||||
if (className) {
|
||||
iconDiv.classList.add(className);
|
||||
dom.addClass(iconDiv, className);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -527,12 +527,12 @@ export class ToolboxCategory extends ToolboxItem implements
|
||||
this.parseColour_(ToolboxCategory.defaultBackgroundColour);
|
||||
this.rowDiv_.style.backgroundColor = this.colour_ || defaultColour;
|
||||
if (className) {
|
||||
this.rowDiv_.classList.add(className);
|
||||
dom.addClass(this.rowDiv_, className);
|
||||
}
|
||||
} else {
|
||||
this.rowDiv_.style.backgroundColor = '';
|
||||
if (className) {
|
||||
this.rowDiv_.classList.remove(className);
|
||||
dom.removeClass(this.rowDiv_, className);
|
||||
}
|
||||
}
|
||||
aria.setState(this.htmlDiv_ as Element, aria.State.SELECTED, isSelected);
|
||||
|
||||
@@ -17,6 +17,7 @@ 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';
|
||||
@@ -142,7 +143,7 @@ export class CollapsibleToolboxCategory extends ToolboxCategory implements
|
||||
if (!this.parentToolbox_.isHorizontal()) {
|
||||
const className = (this.cssConfig_ as AnyDuringMigration)['icon'];
|
||||
if (className) {
|
||||
toolboxIcon.classList.add(className);
|
||||
dom.addClass(toolboxIcon, className);
|
||||
}
|
||||
toolboxIcon.style.visibility = 'visible';
|
||||
}
|
||||
@@ -162,7 +163,7 @@ export class CollapsibleToolboxCategory extends ToolboxCategory implements
|
||||
const contentsContainer = document.createElement('div');
|
||||
const className = (this.cssConfig_ as AnyDuringMigration)['contents'];
|
||||
if (className) {
|
||||
contentsContainer.classList.add(className);
|
||||
dom.addClass(contentsContainer, className);
|
||||
}
|
||||
|
||||
for (let i = 0; i < subcategories.length; i++) {
|
||||
|
||||
@@ -61,7 +61,7 @@ export class ToolboxSeparator extends ToolboxItem {
|
||||
const container = document.createElement('div');
|
||||
const className = this.cssConfig_['container'];
|
||||
if (className) {
|
||||
container.classList.add(className);
|
||||
dom.addClass(container, className);
|
||||
}
|
||||
this.htmlDiv_ = container;
|
||||
return container;
|
||||
|
||||
@@ -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');
|
||||
toolboxContainer.classList.add('blocklyToolboxDiv');
|
||||
toolboxContainer.classList.add('blocklyNonSelectable');
|
||||
dom.addClass(toolboxContainer, 'blocklyToolboxDiv');
|
||||
dom.addClass(toolboxContainer, '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'));
|
||||
contentsContainer.classList.add('blocklyToolboxContents');
|
||||
dom.addClass(contentsContainer, 'blocklyToolboxContents');
|
||||
if (this.isHorizontal()) {
|
||||
contentsContainer.style.flexDirection = 'row';
|
||||
}
|
||||
@@ -453,8 +453,8 @@ export class Toolbox extends DeleteArea implements IAutoHideable,
|
||||
* @internal
|
||||
*/
|
||||
addStyle(style: string) {
|
||||
if (style) {
|
||||
this.HtmlDiv?.classList.add(style);
|
||||
if (style && this.HtmlDiv) {
|
||||
dom.addClass(this.HtmlDiv, style);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -465,8 +465,8 @@ export class Toolbox extends DeleteArea implements IAutoHideable,
|
||||
* @internal
|
||||
*/
|
||||
removeStyle(style: string) {
|
||||
if (style) {
|
||||
this.HtmlDiv?.classList.remove(style);
|
||||
if (style && this.HtmlDiv) {
|
||||
dom.removeClass(this.HtmlDiv, style);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -85,46 +85,49 @@ export function createSvgElement<T extends SVGElement>(
|
||||
/**
|
||||
* Add a CSS class to a element.
|
||||
*
|
||||
* Handles multiple space-separated classes for legacy reasons.
|
||||
*
|
||||
* @param element DOM element to add class to.
|
||||
* @param className Name of class to add.
|
||||
* @returns True if class was added, false if already present.
|
||||
* @alias Blockly.utils.dom.addClass
|
||||
*/
|
||||
export function addClass(element: Element, className: string): boolean {
|
||||
if (element.classList.contains(className)) {
|
||||
const classNames = className.split(' ');
|
||||
if (classNames.every((name) => element.classList.contains(name))) {
|
||||
return false;
|
||||
}
|
||||
element.classList.add(className);
|
||||
element.classList.add(...classNames);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes multiple calsses from an element.
|
||||
* Removes multiple classes from an element.
|
||||
*
|
||||
* @param element DOM element to remove classes from.
|
||||
* @param classNames A string of one or multiple class names for an element.
|
||||
* @alias Blockly.utils.dom.removeClasses
|
||||
*/
|
||||
export function removeClasses(element: Element, classNames: string) {
|
||||
const classList = classNames.split(' ');
|
||||
for (let i = 0; i < classList.length; i++) {
|
||||
element.classList.remove(classList[i]);
|
||||
}
|
||||
element.classList.remove(...classNames.split(' '));
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a CSS class from a element.
|
||||
*
|
||||
* Handles multiple space-separated classes for legacy reasons.
|
||||
*
|
||||
* @param element DOM element to remove class from.
|
||||
* @param className Name of class to remove.
|
||||
* @returns True if class was removed, false if never present.
|
||||
* @alias Blockly.utils.dom.removeClass
|
||||
*/
|
||||
export function removeClass(element: Element, className: string): boolean {
|
||||
if (!element.classList.contains(className)) {
|
||||
const classNames = className.split(' ');
|
||||
if (classNames.every((name) => !element.classList.contains(name))) {
|
||||
return false;
|
||||
}
|
||||
element.classList.remove(className);
|
||||
element.classList.remove(...classNames);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ 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,10 +94,10 @@ export function show(newOwner: unknown, rtl: boolean, newDispose: () => void) {
|
||||
rendererClassName = mainWorkspace.getRenderer().getClassName();
|
||||
themeClassName = mainWorkspace.getTheme().getClassName();
|
||||
if (rendererClassName) {
|
||||
div.classList.add(rendererClassName);
|
||||
dom.addClass(div, rendererClassName);
|
||||
}
|
||||
if (themeClassName) {
|
||||
div.classList.add(themeClassName);
|
||||
dom.addClass(div, themeClassName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,11 +122,11 @@ export function hide() {
|
||||
div.textContent = '';
|
||||
|
||||
if (rendererClassName) {
|
||||
div.classList.remove(rendererClassName);
|
||||
dom.removeClass(div, rendererClassName);
|
||||
rendererClassName = '';
|
||||
}
|
||||
if (themeClassName) {
|
||||
div.classList.remove(themeClassName);
|
||||
dom.removeClass(div, themeClassName);
|
||||
themeClassName = '';
|
||||
}
|
||||
(common.getMainWorkspace() as WorkspaceSvg).markFocused();
|
||||
|
||||
@@ -263,7 +263,7 @@ export class WorkspaceCommentSvg extends WorkspaceComment implements
|
||||
* @internal
|
||||
*/
|
||||
addSelect() {
|
||||
this.svgGroup_.classList.add('blocklySelected');
|
||||
dom.addClass(this.svgGroup_, 'blocklySelected');
|
||||
this.setFocus();
|
||||
}
|
||||
|
||||
@@ -273,7 +273,7 @@ export class WorkspaceCommentSvg extends WorkspaceComment implements
|
||||
* @internal
|
||||
*/
|
||||
removeSelect() {
|
||||
this.svgGroup_.classList.add('blocklySelected');
|
||||
dom.addClass(this.svgGroup_, 'blocklySelected');
|
||||
this.blurFocus();
|
||||
}
|
||||
|
||||
@@ -283,7 +283,7 @@ export class WorkspaceCommentSvg extends WorkspaceComment implements
|
||||
* @internal
|
||||
*/
|
||||
addFocus() {
|
||||
this.svgGroup_.classList.add('blocklyFocused');
|
||||
dom.addClass(this.svgGroup_, 'blocklyFocused');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -292,7 +292,7 @@ export class WorkspaceCommentSvg extends WorkspaceComment implements
|
||||
* @internal
|
||||
*/
|
||||
removeFocus() {
|
||||
this.svgGroup_.classList.remove('blocklyFocused');
|
||||
dom.removeClass(this.svgGroup_, 'blocklyFocused');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -473,9 +473,9 @@ export class WorkspaceCommentSvg extends WorkspaceComment implements
|
||||
*/
|
||||
updateMovable() {
|
||||
if (this.isMovable()) {
|
||||
this.svgGroup_.classList.add('blocklyDraggable');
|
||||
dom.addClass(this.svgGroup_, 'blocklyDraggable');
|
||||
} else {
|
||||
this.svgGroup_.classList.remove('blocklyDraggable');
|
||||
dom.removeClass(this.svgGroup_, 'blocklyDraggable');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -514,9 +514,9 @@ export class WorkspaceCommentSvg extends WorkspaceComment implements
|
||||
const group = this.getSvgRoot();
|
||||
(group as AnyDuringMigration).translate_ = '';
|
||||
(group as AnyDuringMigration).skew_ = '';
|
||||
this.svgGroup_.classList.add('blocklyDragging');
|
||||
dom.addClass(this.svgGroup_, 'blocklyDragging');
|
||||
} else {
|
||||
this.svgGroup_.classList.remove('blocklyDragging');
|
||||
dom.removeClass(this.svgGroup_, 'blocklyDragging');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -561,9 +561,9 @@ export class WorkspaceCommentSvg extends WorkspaceComment implements
|
||||
*/
|
||||
setDeleteStyle(enable: boolean) {
|
||||
if (enable) {
|
||||
this.svgGroup_.classList.add('blocklyDraggingDelete');
|
||||
dom.addClass(this.svgGroup_, 'blocklyDraggingDelete');
|
||||
} else {
|
||||
this.svgGroup_.classList.remove('blocklyDraggingDelete');
|
||||
dom.removeClass(this.svgGroup_, 'blocklyDraggingDelete');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -853,7 +853,9 @@ export class WorkspaceCommentSvg extends WorkspaceComment implements
|
||||
*/
|
||||
private deleteMouseDown_(e: Event) {
|
||||
// Highlight the delete icon.
|
||||
this.deleteIconBorder_?.classList.add('blocklyDeleteIconHighlighted');
|
||||
if (this.deleteIconBorder_) {
|
||||
dom.addClass(this.deleteIconBorder_, 'blocklyDeleteIconHighlighted');
|
||||
}
|
||||
// This event has been handled. No need to bubble up to the document.
|
||||
e.stopPropagation();
|
||||
}
|
||||
@@ -865,7 +867,9 @@ export class WorkspaceCommentSvg extends WorkspaceComment implements
|
||||
*/
|
||||
private deleteMouseOut_(_e: Event) {
|
||||
// Restore highlight on the delete icon.
|
||||
this.deleteIconBorder_?.classList.remove('blocklyDeleteIconHighlighted');
|
||||
if (this.deleteIconBorder_) {
|
||||
dom.removeClass(this.deleteIconBorder_, 'blocklyDeleteIconHighlighted');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1016,8 +1020,13 @@ export class WorkspaceCommentSvg extends WorkspaceComment implements
|
||||
}
|
||||
this.textarea_!.focus();
|
||||
this.addFocus();
|
||||
this.svgRectTarget_?.classList.add('blocklyCommentTargetFocused');
|
||||
this.svgHandleTarget_?.classList.add('blocklyCommentHandleTargetFocused');
|
||||
if (this.svgRectTarget_) {
|
||||
dom.addClass(this.svgRectTarget_, 'blocklyCommentTargetFocused');
|
||||
}
|
||||
if (this.svgHandleTarget_) {
|
||||
dom.addClass(
|
||||
this.svgHandleTarget_, 'blocklyCommentHandleTargetFocused');
|
||||
}
|
||||
}, 0);
|
||||
}
|
||||
|
||||
@@ -1036,9 +1045,13 @@ export class WorkspaceCommentSvg extends WorkspaceComment implements
|
||||
|
||||
this.textarea_!.blur();
|
||||
this.removeFocus();
|
||||
this.svgRectTarget_?.classList.remove('blocklyCommentTargetFocused');
|
||||
this.svgHandleTarget_?.classList.remove(
|
||||
'blocklyCommentHandleTargetFocused');
|
||||
if (this.svgRectTarget_) {
|
||||
dom.removeClass(this.svgRectTarget_, 'blocklyCommentTargetFocused');
|
||||
}
|
||||
if (this.svgHandleTarget_) {
|
||||
dom.removeClass(
|
||||
this.svgHandleTarget_, 'blocklyCommentHandleTargetFocused');
|
||||
}
|
||||
}, 0);
|
||||
}
|
||||
|
||||
|
||||
@@ -2080,8 +2080,8 @@ export class WorkspaceSvg extends Workspace implements IASTNodeLocationSvg {
|
||||
* @internal
|
||||
*/
|
||||
beginCanvasTransition() {
|
||||
this.svgBlockCanvas_.classList.add('blocklyCanvasTransitioning');
|
||||
this.svgBubbleCanvas_.classList.add('blocklyCanvasTransitioning');
|
||||
dom.addClass(this.svgBlockCanvas_, 'blocklyCanvasTransitioning');
|
||||
dom.addClass(this.svgBubbleCanvas_, 'blocklyCanvasTransitioning');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2090,8 +2090,8 @@ export class WorkspaceSvg extends Workspace implements IASTNodeLocationSvg {
|
||||
* @internal
|
||||
*/
|
||||
endCanvasTransition() {
|
||||
this.svgBlockCanvas_.classList.remove('blocklyCanvasTransitioning');
|
||||
this.svgBubbleCanvas_.classList.remove('blocklyCanvasTransitioning');
|
||||
dom.removeClass(this.svgBlockCanvas_, 'blocklyCanvasTransitioning');
|
||||
dom.removeClass(this.svgBubbleCanvas_, 'blocklyCanvasTransitioning');
|
||||
}
|
||||
|
||||
/** Center the workspace. */
|
||||
|
||||
@@ -130,6 +130,26 @@ suite('Toolbox', function() {
|
||||
this.toolbox.render(jsonDef);
|
||||
chai.assert.lengthOf(this.toolbox.contents_, 1);
|
||||
});
|
||||
test('multiple icon classes can be applied', function() {
|
||||
const jsonDef = {'contents': [
|
||||
{
|
||||
"kind": "category",
|
||||
"cssConfig": {
|
||||
"icon": "customIcon customIconEvents",
|
||||
},
|
||||
"contents": [
|
||||
{
|
||||
"kind": "block",
|
||||
"blockxml": '<block xmlns="http://www.w3.org/1999/xhtml" type="basic_block"><field name="TEXT">FirstCategory-FirstBlock</field></block>',
|
||||
},
|
||||
],
|
||||
},
|
||||
]};
|
||||
chai.assert.doesNotThrow(() => {
|
||||
this.toolbox.render(jsonDef);
|
||||
});
|
||||
chai.assert.lengthOf(this.toolbox.contents_, 1);
|
||||
});
|
||||
});
|
||||
|
||||
suite('onClick_', function() {
|
||||
|
||||
Reference in New Issue
Block a user