mirror of
https://github.com/google/blockly.git
synced 2026-01-08 17:40:09 +01:00
309 lines
8.1 KiB
JavaScript
309 lines
8.1 KiB
JavaScript
/**
|
|
* @license
|
|
* Visual Blocks Editor
|
|
*
|
|
* Copyright 2019 Google Inc.
|
|
* https://developers.google.com/blockly/
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
/**
|
|
* @fileoverview Blockly menu item similar to Closure's goog.ui.MenuItem
|
|
* @author samelh@google.com (Sam El-Husseini)
|
|
*/
|
|
'use strict';
|
|
|
|
goog.provide('Blockly.MenuItem');
|
|
|
|
goog.require('Blockly.Component');
|
|
goog.require('Blockly.utils.aria');
|
|
goog.require('Blockly.utils.dom');
|
|
goog.require('Blockly.utils.object');
|
|
|
|
|
|
/**
|
|
* Class representing an item in a menu.
|
|
*
|
|
* @param {string} content Text caption to display as the content of
|
|
* the item.
|
|
* @param {string=} opt_value Data/model associated with the menu item.
|
|
* @constructor
|
|
* @extends {Blockly.Component}
|
|
*/
|
|
Blockly.MenuItem = function(content, opt_value) {
|
|
Blockly.Component.call(this);
|
|
|
|
this.setContentInternal(content);
|
|
this.setValue(opt_value);
|
|
|
|
/**
|
|
* @type {boolean}
|
|
* @private
|
|
*/
|
|
this.enabled_ = true;
|
|
|
|
/**
|
|
* @type {Blockly.MenuItem}
|
|
* @private
|
|
*/
|
|
this.previousSibling_;
|
|
|
|
/**
|
|
* @type {Blockly.MenuItem}
|
|
* @private
|
|
*/
|
|
this.nextSibling_;
|
|
};
|
|
Blockly.utils.object.inherits(Blockly.MenuItem, Blockly.Component);
|
|
|
|
|
|
/**
|
|
* Creates the menuitem's DOM.
|
|
* @override
|
|
*/
|
|
Blockly.MenuItem.prototype.createDom = function() {
|
|
var element = document.createElement('div');
|
|
element.setAttribute('id', this.getId());
|
|
this.setElementInternal(element);
|
|
|
|
// Set class and style
|
|
element.setAttribute('class', 'goog-menuitem goog-option ' +
|
|
(!this.enabled_ ? 'goog-menuitem-disabled ' : '') +
|
|
(this.checked_ ? 'goog-option-selected ' : '') +
|
|
(this.isRightToLeft() ? 'goog-menuitem-rtl ' : ''));
|
|
element.setAttribute('style', 'user-select: none');
|
|
|
|
var content = this.getContentWrapperDom();
|
|
element.appendChild(content);
|
|
|
|
// Add a cheeckbox for checkable menu items.
|
|
var checkboxDom = this.getCheckboxDom();
|
|
if (checkboxDom) {
|
|
content.appendChild(checkboxDom);
|
|
}
|
|
|
|
content.appendChild(this.getContentDom());
|
|
|
|
// Initialize ARIA role and state.
|
|
Blockly.utils.aria.setRole(element, this.roleName_ || (this.checkable_ ?
|
|
Blockly.utils.aria.Role.MENUITEMCHECKBOX :
|
|
Blockly.utils.aria.Role.MENUITEM));
|
|
Blockly.utils.aria.setState(element,
|
|
Blockly.utils.aria.State.SELECTED, (this.checkable_ && this.checked_) || false);
|
|
};
|
|
|
|
/**
|
|
* @return {Element} The HTML element for the checkbox.
|
|
* @protected
|
|
*/
|
|
Blockly.MenuItem.prototype.getCheckboxDom = function() {
|
|
if (!this.checkable_) {
|
|
return null;
|
|
}
|
|
var menuItemCheckbox = document.createElement('div');
|
|
menuItemCheckbox.setAttribute('class', 'goog-menuitem-checkbox');
|
|
menuItemCheckbox.setAttribute('style', 'user-select: none;');
|
|
return menuItemCheckbox;
|
|
};
|
|
|
|
/**
|
|
* @return {!Element} The HTML for the content.
|
|
* @protected
|
|
*/
|
|
Blockly.MenuItem.prototype.getContentDom = function() {
|
|
var content = this.content_;
|
|
if (typeof content === 'string') {
|
|
content = document.createTextNode(content);
|
|
}
|
|
return content;
|
|
};
|
|
|
|
/**
|
|
* @return {!Element} The HTML for the content wrapper.
|
|
* @protected
|
|
*/
|
|
Blockly.MenuItem.prototype.getContentWrapperDom = function() {
|
|
var contentWrapper = document.createElement('div');
|
|
contentWrapper.setAttribute('class', 'goog-menuitem-content');
|
|
contentWrapper.setAttribute('style', 'user-select: none;');
|
|
return contentWrapper;
|
|
};
|
|
|
|
/**
|
|
* Sets the content associated with the menu item.
|
|
* @param {string} content Text caption to set as the
|
|
* menuitem's contents.
|
|
* @protected
|
|
*/
|
|
Blockly.MenuItem.prototype.setContentInternal = function(content) {
|
|
this.content_ = content;
|
|
};
|
|
|
|
/**
|
|
* Sets the value associated with the menu item.
|
|
* @param {*} value Value to be associated with the menu item.
|
|
* @package
|
|
*/
|
|
Blockly.MenuItem.prototype.setValue = function(value) {
|
|
this.value_ = value;
|
|
};
|
|
|
|
/**
|
|
* Gets the value associated with the menu item.
|
|
* @return {*} value Value associated with the menu item.
|
|
* @package
|
|
*/
|
|
Blockly.MenuItem.prototype.getValue = function() {
|
|
return this.value_;
|
|
};
|
|
|
|
/**
|
|
* Set the menu accessibility role.
|
|
* @param {!Blockly.utils.aria.Role|string} roleName role name.
|
|
* @package
|
|
*/
|
|
Blockly.MenuItem.prototype.setRole = function(roleName) {
|
|
this.roleName_ = roleName;
|
|
};
|
|
|
|
/**
|
|
* Sets the menu item to be checkable or not. Set to true for menu items
|
|
* that represent checkable options.
|
|
* @param {boolean} checkable Whether the menu item is checkable.
|
|
* @package
|
|
*/
|
|
Blockly.MenuItem.prototype.setCheckable = function(checkable) {
|
|
this.checkable_ = checkable;
|
|
};
|
|
|
|
/**
|
|
* Checks or unchecks the component.
|
|
* @param {boolean} checked Whether to check or uncheck the component.
|
|
* @package
|
|
*/
|
|
Blockly.MenuItem.prototype.setChecked = function(checked) {
|
|
if (!this.checkable_) {
|
|
return;
|
|
}
|
|
this.checked_ = checked;
|
|
|
|
var el = this.getElement();
|
|
if (el && this.isEnabled()) {
|
|
if (checked) {
|
|
Blockly.utils.dom.addClass(el, 'goog-option-selected');
|
|
Blockly.utils.aria.setState(el,
|
|
Blockly.utils.aria.State.SELECTED, true);
|
|
} else {
|
|
Blockly.utils.dom.removeClass(el, 'goog-option-selected');
|
|
Blockly.utils.aria.setState(el,
|
|
Blockly.utils.aria.State.SELECTED, false);
|
|
}
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Returns true if the component is currently highlighted, false otherwise.
|
|
* @return {boolean} Whether the component is highlighted.
|
|
* @package
|
|
*/
|
|
Blockly.MenuItem.prototype.isHighlighted = function() {
|
|
return this.highlight_;
|
|
};
|
|
|
|
/**
|
|
* Highlights or unhighlights the component.
|
|
* @param {boolean} highlight Whether to highlight or unhighlight the component.
|
|
* @package
|
|
*/
|
|
Blockly.MenuItem.prototype.setHighlighted = function(highlight) {
|
|
this.highlight_ = highlight;
|
|
|
|
var el = this.getElement();
|
|
if (el && this.isEnabled()) {
|
|
if (highlight) {
|
|
Blockly.utils.dom.addClass(el, 'goog-menuitem-highlight');
|
|
} else {
|
|
Blockly.utils.dom.removeClass(el, 'goog-menuitem-highlight');
|
|
}
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Returns true if the menu item is enabled, false otherwise.
|
|
* @return {boolean} Whether the menu item is enabled.
|
|
* @package
|
|
*/
|
|
Blockly.MenuItem.prototype.isEnabled = function() {
|
|
return this.enabled_;
|
|
};
|
|
|
|
/**
|
|
* Enables or disables the menu item.
|
|
* @param {boolean} enabled Whether to enable or disable the menu item.
|
|
* @package
|
|
*/
|
|
Blockly.MenuItem.prototype.setEnabled = function(enabled) {
|
|
this.enabled_ = enabled;
|
|
|
|
var el = this.getElement();
|
|
if (el) {
|
|
if (!this.enabled_) {
|
|
Blockly.utils.dom.addClass(el, 'goog-menuitem-disabled');
|
|
} else {
|
|
Blockly.utils.dom.removeClass(el, 'goog-menuitem-disabled');
|
|
}
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Handles click events. If the component is enabled, trigger
|
|
* the action associated with this menu item.
|
|
* @param {Event} _e Mouse event to handle.
|
|
* @package
|
|
*/
|
|
Blockly.MenuItem.prototype.handleClick = function(_e) {
|
|
if (this.isEnabled()) {
|
|
this.setHighlighted(true);
|
|
this.performActionInternal();
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Performs the appropriate action when the menu item is activated
|
|
* by the user.
|
|
* @protected
|
|
*/
|
|
Blockly.MenuItem.prototype.performActionInternal = function() {
|
|
if (this.checkable_) {
|
|
this.setChecked(!this.checked_);
|
|
}
|
|
if (this.actionHandler_) {
|
|
this.actionHandler_.call(/** @type {?} */ (this.actionHandlerObj_), this);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Set the handler that's triggered when the menu item is activated
|
|
* by the user. If `opt_obj` is provided, it will be used as the
|
|
* 'this' object in the function when called.
|
|
* @param {function(this:T,!Blockly.MenuItem):?} fn The handler.
|
|
* @param {T=} opt_obj Used as the 'this' object in f when called.
|
|
* @template T
|
|
* @package
|
|
*/
|
|
Blockly.MenuItem.prototype.onAction = function(fn, opt_obj) {
|
|
this.actionHandler_ = fn;
|
|
this.actionHandlerObj_ = opt_obj;
|
|
};
|