Show:
                            (function() {
                                'use strict';
                            
                                /* istanbul ignore if */
                                if(CKEDITOR.plugins.get('ae_panelmenubuttonbridge')) {
                                    return;
                                }
                            
                                /* istanbul ignore next */
                                function noop() {}
                            
                                // API not yet implemented inside the panel menu button bridge. By mocking the unsupported methods, we
                                // prevent plugins from crashing if they make use of them.
                                var UNSUPPORTED_PANEL_MENU_BUTTON_API = {
                                    createPanel: noop
                                };
                            
                                var PANEL_MENU_DEFS = {};
                            
                                /**
                                 * Generates a PanelMenuButtonBridge React class for a given panelmenubutton definition if it has not been
                                 * already created based on the panelmenubutton name and definition.
                                 *
                                 * @private
                                 * @method generatePanelMenuButtonBridge
                                 * @param {String} panelMenuButtonName The panel button name
                                 * @param {Object} panelMenuButtonDefinition The panel button definition
                                 * @return {Object} The generated or already existing React PanelMenuButton Class
                                 */
                                var generatePanelMenuButtonBridge = function(panelMenuButtonName, panelMenuButtonDefinition, editor) {
                                    var PanelMenuButtonBridge = AlloyEditor.Buttons[panelMenuButtonName];
                            
                                    PANEL_MENU_DEFS[editor.name] = PANEL_MENU_DEFS[editor.name] || {};
                                    PANEL_MENU_DEFS[editor.name][panelMenuButtonName] = PANEL_MENU_DEFS[editor.name][panelMenuButtonName] || panelMenuButtonDefinition;
                            
                                    if (!PanelMenuButtonBridge) {
                                        PanelMenuButtonBridge = React.createClass(
                                            CKEDITOR.tools.merge(UNSUPPORTED_PANEL_MENU_BUTTON_API, {
                                                displayName: panelMenuButtonName,
                            
                                                propTypes: {
                                                    editor: React.PropTypes.object.isRequired
                                                },
                            
                                                statics: {
                                                    key: panelMenuButtonName
                                                },
                            
                                                render: function() {
                                                    var editor = this.props.editor.get('nativeEditor');
                            
                                                    var panelMenuButtonDisplayName = PANEL_MENU_DEFS[editor.name][panelMenuButtonName].name || PANEL_MENU_DEFS[editor.name][panelMenuButtonName].command || panelMenuButtonName;
                            
                                                    var buttonClassName = 'ae-button ae-button-bridge';
                            
                                                    var iconClassName = 'ae-icon-' + panelMenuButtonDisplayName;
                            
                                                    var iconStyle = {};
                            
                                                    var cssStyle = CKEDITOR.skin.getIconStyle(panelMenuButtonDisplayName);
                            
                                                    if (cssStyle) {
                                                        var cssStyleParts = cssStyle.split(';');
                            
                                                        iconStyle.backgroundImage = cssStyleParts[0].substring(cssStyleParts[0].indexOf(':') + 1);
                                                        iconStyle.backgroundPosition = cssStyleParts[1].substring(cssStyleParts[1].indexOf(':') + 1);
                                                        iconStyle.backgroundSize = cssStyleParts[2].substring(cssStyleParts[2].indexOf(':') + 1);
                                                    }
                            
                                                    var panel;
                            
                                                    if (this.props.expanded) {
                                                        panel = this._getPanel();
                                                    }
                            
                                                    return (
                                                        <div className="ae-container ae-has-dropdown">
                                                            <button aria-expanded={this.props.expanded} aria-label={PANEL_MENU_DEFS[editor.name][panelMenuButtonName].label} className={buttonClassName} onClick={this.props.toggleDropdown} role="combobox" tabIndex={this.props.tabIndex} title={PANEL_MENU_DEFS[editor.name][panelMenuButtonName].label}>
                                                                <span className={iconClassName} style={iconStyle}></span>
                                                            </button>
                                                            {panel}
                                                        </div>
                                                    );
                                                },
                            
                                                _getPanel: function() {
                                                    var editor = this.props.editor.get('nativeEditor');
                            
                                                    var panelMenuButtonOnBlock = PANEL_MENU_DEFS[editor.name][panelMenuButtonName].onBlock;
                            
                                                    var panel = {
                                                        hide: this.props.toggleDropdown,
                                                        show: this.props.toggleDropdown
                                                    };
                            
                                                    var blockElement = new CKEDITOR.dom.element('div');
                            
                                                    var block = {
                                                        element: blockElement,
                                                        keys: {}
                                                    };
                            
                                                    /* istanbul ignore else */
                                                    if (panelMenuButtonOnBlock) {
                                                        panelMenuButtonOnBlock.call(this, panel, block);
                                                    }
                            
                                                    // TODO
                                                    // Use block.keys to configure the panel keyboard navigation
                            
                                                    return (
                                                        <AlloyEditor.ButtonDropdown onDismiss={this.props.toggleDropdown}>
                                                            <div className={blockElement.getAttribute('class')} dangerouslySetInnerHTML={{__html: blockElement.getHtml()}} />
                                                        </AlloyEditor.ButtonDropdown>
                                                    );
                                                }
                                            })
                                        );
                            
                                        AlloyEditor.Buttons[panelMenuButtonName] = PanelMenuButtonBridge;
                                    }
                            
                                    return PanelMenuButtonBridge;
                                };
                            
                                /* istanbul ignore else */
                                if (!CKEDITOR.plugins.get('panelmenubutton')) {
                                    CKEDITOR.UI_PANELBUTTON = 'panelmenubutton';
                            
                                    CKEDITOR.plugins.add('panelmenubutton', {});
                                }
                            
                                /**
                                 * CKEditor plugin that bridges the support offered by CKEditor PanelButton plugin. It takes over the
                                 * responsibility of registering and creating buttons via:
                                 * - editor.ui.addPanelMenuButton(name, definition)
                                 * - editor.ui.add(name, CKEDITOR.UI_PANELBUTTON, definition)
                                 *
                                 * @class CKEDITOR.plugins.ae_panelmenubuttonbridge
                                 * @requires CKEDITOR.plugins.ae_uibridge
                                 * @constructor
                                 */
                                CKEDITOR.plugins.add('ae_panelmenubuttonbridge', {
                                    requires: ['ae_uibridge'],
                            
                                    /**
                                     * Set the add handler for UI_PANELBUTTON to our own. We do this in the init phase to override
                                     * the one in the native plugin in case it's present
                                     *
                                     * @method init
                                     * @param {Object} editor The CKEditor instance being initialized
                                     */
                                    init: function(editor) {
                                        editor.ui.addPanelMenuButton = function(panelMenuButtonName, panelMenuButtonDefinition) {
                                            this.add(panelMenuButtonName, CKEDITOR.UI_PANELBUTTON, panelMenuButtonDefinition);
                                        };
                            
                                        editor.ui.addHandler(CKEDITOR.UI_PANELBUTTON, {
                                            add: generatePanelMenuButtonBridge,
                                            create: function(panelMenuButtonDefinition) {
                                                var panelMenuButtonName = 'panelMenuButtonBridge' + ((Math.random() * 1e9) >>> 0);
                                                var PanelMenuButtonBridge = generatePanelMenuButtonBridge(panelMenuButtonName, panelMenuButtonDefinition);
                            
                                                return new PanelMenuButtonBridge();
                                            }
                                        });
                                    }
                                });
                            }());