All Downloads are FREE. Search and download functionalities are using the official Maven repository.

goog.ui.menuitemrenderer.js Maven / Gradle / Ivy

Go to download

The Google Closure Library is a collection of JavaScript code designed for use with the Google Closure JavaScript Compiler. This non-official distribution was prepared by the ClojureScript team at http://clojure.org/

There is a newer version: 0.0-20230227-c7c0a541
Show newest version
// Copyright 2008 The Closure Library Authors. All Rights Reserved.
//
// 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 Renderer for {@link goog.ui.MenuItem}s.
 *
 * @author [email protected] (Attila Bodis)
 */

goog.provide('goog.ui.MenuItemRenderer');

goog.require('goog.a11y.aria.Role');
goog.require('goog.asserts');
goog.require('goog.dom');
goog.require('goog.dom.TagName');
goog.require('goog.dom.classlist');
goog.require('goog.ui.Component');
goog.require('goog.ui.ControlRenderer');



/**
 * Default renderer for {@link goog.ui.MenuItem}s.  Each item has the following
 * structure:
 *
 *    
*
* ...(menu item contents)... *
*
* * @constructor * @extends {goog.ui.ControlRenderer} */ goog.ui.MenuItemRenderer = function() { goog.ui.ControlRenderer.call(this); /** * Commonly used CSS class names, cached here for convenience (and to avoid * unnecessary string concatenation). * @type {!Array} * @private */ this.classNameCache_ = []; }; goog.inherits(goog.ui.MenuItemRenderer, goog.ui.ControlRenderer); goog.addSingletonGetter(goog.ui.MenuItemRenderer); /** * CSS class name the renderer applies to menu item elements. * @type {string} */ goog.ui.MenuItemRenderer.CSS_CLASS = goog.getCssName('goog-menuitem'); /** * Constants for referencing composite CSS classes. * @enum {number} * @private */ goog.ui.MenuItemRenderer.CompositeCssClassIndex_ = { HOVER: 0, CHECKBOX: 1, CONTENT: 2 }; /** * Returns the composite CSS class by using the cached value or by constructing * the value from the base CSS class and the passed index. * @param {goog.ui.MenuItemRenderer.CompositeCssClassIndex_} index Index for the * CSS class - could be highlight, checkbox or content in usual cases. * @return {string} The composite CSS class. * @private */ goog.ui.MenuItemRenderer.prototype.getCompositeCssClass_ = function(index) { var result = this.classNameCache_[index]; if (!result) { switch (index) { case goog.ui.MenuItemRenderer.CompositeCssClassIndex_.HOVER: result = goog.getCssName(this.getStructuralCssClass(), 'highlight'); break; case goog.ui.MenuItemRenderer.CompositeCssClassIndex_.CHECKBOX: result = goog.getCssName(this.getStructuralCssClass(), 'checkbox'); break; case goog.ui.MenuItemRenderer.CompositeCssClassIndex_.CONTENT: result = goog.getCssName(this.getStructuralCssClass(), 'content'); break; } this.classNameCache_[index] = result; } return result; }; /** @override */ goog.ui.MenuItemRenderer.prototype.getAriaRole = function() { return goog.a11y.aria.Role.MENU_ITEM; }; /** * Overrides {@link goog.ui.ControlRenderer#createDom} by adding extra markup * and stying to the menu item's element if it is selectable or checkable. * @param {goog.ui.Control} item Menu item to render. * @return {Element} Root element for the item. * @override */ goog.ui.MenuItemRenderer.prototype.createDom = function(item) { var element = item.getDomHelper().createDom( goog.dom.TagName.DIV, this.getClassNames(item).join(' '), this.createContent(item.getContent(), item.getDomHelper())); this.setEnableCheckBoxStructure( item, element, item.isSupportedState(goog.ui.Component.State.SELECTED) || item.isSupportedState(goog.ui.Component.State.CHECKED)); return element; }; /** @override */ goog.ui.MenuItemRenderer.prototype.getContentElement = function(element) { return /** @type {Element} */ (element && element.firstChild); }; /** * Overrides {@link goog.ui.ControlRenderer#decorate} by initializing the * menu item to checkable based on whether the element to be decorated has * extra stying indicating that it should be. * @param {goog.ui.Control} item Menu item instance to decorate the element. * @param {Element} element Element to decorate. * @return {Element} Decorated element. * @override */ goog.ui.MenuItemRenderer.prototype.decorate = function(item, element) { goog.asserts.assert(element); if (!this.hasContentStructure(element)) { element.appendChild( this.createContent(element.childNodes, item.getDomHelper())); } if (goog.dom.classlist.contains(element, goog.getCssName('goog-option'))) { (/** @type {goog.ui.MenuItem} */ (item)).setCheckable(true); this.setCheckable(item, element, true); } return goog.ui.MenuItemRenderer.superClass_.decorate.call( this, item, element); }; /** * Takes a menu item's root element, and sets its content to the given text * caption or DOM structure. Overrides the superclass immplementation by * making sure that the checkbox structure (for selectable/checkable menu * items) is preserved. * @param {Element} element The item's root element. * @param {goog.ui.ControlContent} content Text caption or DOM structure to be * set as the item's content. * @override */ goog.ui.MenuItemRenderer.prototype.setContent = function(element, content) { // Save the checkbox element, if present. var contentElement = this.getContentElement(element); var checkBoxElement = this.hasCheckBoxStructure(element) ? contentElement.firstChild : null; goog.ui.MenuItemRenderer.superClass_.setContent.call(this, element, content); if (checkBoxElement && !this.hasCheckBoxStructure(element)) { // The call to setContent() blew away the checkbox element; reattach it. contentElement.insertBefore( checkBoxElement, contentElement.firstChild || null); } }; /** * Returns true if the element appears to have a proper menu item structure by * checking whether its first child has the appropriate structural class name. * @param {Element} element Element to check. * @return {boolean} Whether the element appears to have a proper menu item DOM. * @protected */ goog.ui.MenuItemRenderer.prototype.hasContentStructure = function(element) { var child = goog.dom.getFirstElementChild(element); var contentClassName = this.getCompositeCssClass_( goog.ui.MenuItemRenderer.CompositeCssClassIndex_.CONTENT); return !!child && goog.dom.classlist.contains(child, contentClassName); }; /** * Wraps the given text caption or existing DOM node(s) in a structural element * containing the menu item's contents. * @param {goog.ui.ControlContent} content Menu item contents. * @param {goog.dom.DomHelper} dom DOM helper for document interaction. * @return {Element} Menu item content element. * @protected */ goog.ui.MenuItemRenderer.prototype.createContent = function(content, dom) { var contentClassName = this.getCompositeCssClass_( goog.ui.MenuItemRenderer.CompositeCssClassIndex_.CONTENT); return dom.createDom(goog.dom.TagName.DIV, contentClassName, content); }; /** * Enables/disables radio button semantics on the menu item. * @param {goog.ui.Control} item Menu item to update. * @param {Element} element Menu item element to update (may be null if the * item hasn't been rendered yet). * @param {boolean} selectable Whether the item should be selectable. */ goog.ui.MenuItemRenderer.prototype.setSelectable = function( item, element, selectable) { if (item && element) { this.setEnableCheckBoxStructure(item, element, selectable); } }; /** * Enables/disables checkbox semantics on the menu item. * @param {goog.ui.Control} item Menu item to update. * @param {Element} element Menu item element to update (may be null if the * item hasn't been rendered yet). * @param {boolean} checkable Whether the item should be checkable. */ goog.ui.MenuItemRenderer.prototype.setCheckable = function( item, element, checkable) { if (item && element) { this.setEnableCheckBoxStructure(item, element, checkable); } }; /** * Determines whether the item contains a checkbox element. * @param {Element} element Menu item root element. * @return {boolean} Whether the element contains a checkbox element. * @protected */ goog.ui.MenuItemRenderer.prototype.hasCheckBoxStructure = function(element) { var contentElement = this.getContentElement(element); if (contentElement) { var child = contentElement.firstChild; var checkboxClassName = this.getCompositeCssClass_( goog.ui.MenuItemRenderer.CompositeCssClassIndex_.CHECKBOX); return !!child && goog.dom.isElement(child) && goog.dom.classlist.contains( /** @type {!Element} */ (child), checkboxClassName); } return false; }; /** * Adds or removes extra markup and CSS styling to the menu item to make it * selectable or non-selectable, depending on the value of the * {@code selectable} argument. * @param {!goog.ui.Control} item Menu item to update. * @param {!Element} element Menu item element to update. * @param {boolean} enable Whether to add or remove the checkbox structure. * @protected */ goog.ui.MenuItemRenderer.prototype.setEnableCheckBoxStructure = function( item, element, enable) { this.setAriaRole(element, item.getPreferredAriaRole()); this.setAriaStates(item, element); if (enable != this.hasCheckBoxStructure(element)) { goog.dom.classlist.enable(element, goog.getCssName('goog-option'), enable); var contentElement = this.getContentElement(element); if (enable) { // Insert checkbox structure. var checkboxClassName = this.getCompositeCssClass_( goog.ui.MenuItemRenderer.CompositeCssClassIndex_.CHECKBOX); contentElement.insertBefore( item.getDomHelper().createDom( goog.dom.TagName.DIV, checkboxClassName), contentElement.firstChild || null); } else { // Remove checkbox structure. contentElement.removeChild(contentElement.firstChild); } } }; /** * Takes a single {@link goog.ui.Component.State}, and returns the * corresponding CSS class name (null if none). Overrides the superclass * implementation by using 'highlight' as opposed to 'hover' as the CSS * class name suffix for the HOVER state, for backwards compatibility. * @param {goog.ui.Component.State} state Component state. * @return {string|undefined} CSS class representing the given state * (undefined if none). * @override */ goog.ui.MenuItemRenderer.prototype.getClassForState = function(state) { switch (state) { case goog.ui.Component.State.HOVER: // We use 'highlight' as the suffix, for backwards compatibility. return this.getCompositeCssClass_( goog.ui.MenuItemRenderer.CompositeCssClassIndex_.HOVER); case goog.ui.Component.State.CHECKED: case goog.ui.Component.State.SELECTED: // We use 'goog-option-selected' as the class, for backwards // compatibility. return goog.getCssName('goog-option-selected'); default: return goog.ui.MenuItemRenderer.superClass_.getClassForState.call( this, state); } }; /** * Takes a single CSS class name which may represent a component state, and * returns the corresponding component state (0x00 if none). Overrides the * superclass implementation by treating 'goog-option-selected' as special, * for backwards compatibility. * @param {string} className CSS class name, possibly representing a component * state. * @return {goog.ui.Component.State} state Component state corresponding * to the given CSS class (0x00 if none). * @override */ goog.ui.MenuItemRenderer.prototype.getStateFromClass = function(className) { var hoverClassName = this.getCompositeCssClass_( goog.ui.MenuItemRenderer.CompositeCssClassIndex_.HOVER); switch (className) { case goog.getCssName('goog-option-selected'): return goog.ui.Component.State.CHECKED; case hoverClassName: return goog.ui.Component.State.HOVER; default: return goog.ui.MenuItemRenderer.superClass_.getStateFromClass.call( this, className); } }; /** @override */ goog.ui.MenuItemRenderer.prototype.getCssClass = function() { return goog.ui.MenuItemRenderer.CSS_CLASS; };




© 2015 - 2025 Weber Informatics LLC | Privacy Policy