Source: widgets/SpwIWantTo.js

Retour à la documentation
/**
 * @class spw.widgets.SpwIWantTo
 */
define(["dojo/_base/declare", "spw/api/SpwBaseWidget", "dojo/_base/lang",
        "spw/api/Utils", "dojo/_base/array", "dojo/dom-construct",
        "dijit/form/DropDownButton", "dijit/DropDownMenu", "dijit/CheckedMenuItem",
        "dojo/dom-style", "dojo/query", "dojo/on", "dojo/mouse",
        "spw/api/PopupMenuItem", "dijit/MenuSeparator", "dojo/dom-class",
        "dojo/keys", "dojo/_base/event", "spw/api/popup", "dojo/dom-attr", "dojo/dom-geometry",
        "dijit/Tooltip", "dijit/layout/BorderContainer", "dijit/layout/ContentPane", "spw/api/SpwPopupItem"],
    function (declare, SpwBaseWidget, lang, Utils, array, domConstruct,
              DropDownButton, DropDownMenu, CheckedMenuItem, domStyle, query, on,
              mouse, PopupMenuItem, MenuSeparator, domClass, keys, event, popup, domAttr, domGeometry,
              Tooltip, BorderContainer, ContentPane, SpwPopupItem) {

        var SpwIWantTo = null;

        SpwIWantTo = declare("spw.widgets.SpwIWantTo", [SpwBaseWidget], /** @lends spw.widgets.SpwIWantTo.prototype */{

            /*
             "content": [
             "spwIdentifyWidget",
             {
             "widgetId":"spwTocWidget",
             "label":"Afficher/Masquer la TOC"
             },
             {
             "label":"Analyses",
             "content": [
             "spwConcentricCirclesWidget"
             ]
             }
             ],
             */
            content: null,
            buttonColor: null,
            focusColor: null,
            listColor: null,
            label: "Je veux...",
            iconStyle: null,
            labelPosition: null,

            dropDownPosition: null,

            spwWidgetsManager: null,
            _menu: null,
            _button: null,

            /**
             * @constructs
             */
            constructor: function () {
                this.iconStyle = {};
            },

            postMixInProperties: function () {
                this.inherited(arguments);

                this.spwWidgetsManager = this.spwViewer.get('spwWidgetsManager');
            },

            addWidgetToMainMenu: function (widget) {
                var retVal = null;

                if (typeof widget === 'string') {
                    retVal = this.createMenuItemFromWidgetId(this._menu, {
                        widgetId: widget
                    });
                }
                else if (widget.widgetId) {
                    retVal = this.createMenuItemFromWidgetId(this._menu, widget);
                }
                else if (widget.content) {
                    retVal = this.createMenuItemFromContent(this._menu, widget);
                }
                else {
                    widget.content = [];
                    retVal = this.createMenuItemFromContent(this._menu, widget);
                }

                return retVal;
            },

            removeWidgetFromMainMenu: function (widget) {
                this._menu.removeChild(widget);
            },

            buildMenu: function (content, widgetInfo) {
                var isIntegrated = (content && content.length === 1 && content[0] && content[0].integrated);

                var menu = null;

                if (!isIntegrated) {
                    menu = new this.myDropDownMenu({
                        style: "display: none;",
                        doLayout: false,
                        onOpen: function () {
                            if (this.parentMenu == null) {
                                domClass.remove(this._popupWrapper, "dijitMenuPopup");
                                domClass.add(this._popupWrapper, widgetInfo && widgetInfo.popupClass ? widgetInfo.popupClass : "iWantToMenuPopup");
                            } else {
                                domClass.add(this._popupWrapper, "iWantToMenuChildPopup");
                                domClass.remove(this._popupWrapper, "dijitMenuPopup");
                            }
                            if(!domClass.contains(document.body, "claro")){
                                domClass.add(this._popupWrapper, "claro");
                                domStyle.set(this._popupWrapper, { "width":"auto", "height": "auto", "overflow": "initial" });
                            }
                        }
                    });
                }
                else {
                    return this.createMenuItemFromWidgetId(null, content[0], widgetInfo);
                }

                var doContent = lang.hitch(this, function (contentInfo) {
                    if (contentInfo && contentInfo.separator) {
                        menu.addChild(new MenuSeparator());
                    }
                    else if (typeof(contentInfo) === 'string') {
                        this.createMenuItemFromWidgetId(menu, {widgetId: contentInfo});
                    }
                    else if (typeof(contentInfo.widgetId) !== 'undefined') {
                        this.createMenuItemFromWidgetId(menu, contentInfo);
                    }
                    else if (typeof(contentInfo.content) !== 'undefined') {
                        this.createMenuItemFromContent(menu, contentInfo);
                    }
                    else {
                        contentInfo.content = [];
                        this.createMenuItemFromContent(menu, contentInfo);
                    }
                });

                if (content instanceof Array) {
                    array.forEach(content, doContent);
                }
                else if (content) {
                    doContent(content);
                }

                return menu;
            },

            refresh: function () {
                array.forEach(this._toRefresh, lang.hitch(this, function (r) {
                    if (r.refresh) {
                        r.refresh();
                    }
                }));
            },

            createMenuItemFromWidgetId: function (menu, widgetInfo, parentInfo) {
                var widget = this.spwWidgetsManager.getWidgets({widgetId: widgetInfo.widgetId});
                if (widget && widget.length) {

                    if (widget[0]) {
                        widget[0]._closeOnSolitary = true;
                    }

                    if (widgetInfo.integrated === true) {
                        var width = widgetInfo.popupDim && widgetInfo.popupDim.width ? widgetInfo.popupDim.width : widget[0].style && widget[0].style.width ? widget[0].style.width : widget[0].width ? widget[0].width : '300px';
                        var height = widgetInfo.popupDim && widgetInfo.popupDim.height ? widgetInfo.popupDim.height : 'auto';

                        var div = new SpwPopupItem({
                            style: 'background-color: #ffffff; height: ' + height + '; width: ' + width + ';',
                            dimensions: {
                                w: width,
                                h: height
                            },
                            closable: widgetInfo.closable,
                            lightTitle: this.lightTitle,
                            widget: widget[0],
                            widgetInfo: parentInfo ? parentInfo : widgetInfo,
                            spwParentMenu: menu
                        });

                        this._toRefresh = this._toReferesh || [];
                        this._toRefresh.push(div);

                        div.startup();

                        return div;
                    } else {
                        var listItem = this.createMenuItem(widget[0], widgetInfo);
                        if (listItem) {
                            menu.addChild(listItem);
                        }
                        return listItem;
                    }
                }
            },

            createMenuItem: function (widget, widgetInfo) {
                var listItem = null;
                if (widget && widget.isInstanceOf && widget.isInstanceOf(SpwBaseWidget)) {
                    listItem = new CheckedMenuItem({
                        label: widgetInfo.label ? widgetInfo.label : widget.get('widgetTitle'),
                        iconClass: widget.iconClass ? widget.iconClass : "",
                        onClick: function () {
                            if (widget.get('activated')) {
                                widget.onDeactivate();
                            } else {
                                widget.onActivate();
                                if (widget.get('isOneShot')) {
                                    listItem.set('checked', false);
                                    widget.set('activated', false);
                                }

                            }
                        },
                        checked: widget.get('activated')
                    });

                    if (widgetInfo.tooltip) {
                        new Tooltip({
                            connectId: listItem.domNode,
                            label: widgetInfo.tooltip,
                            position: ['after', 'below'],
                            showDelay: 1000
                        });
                    }

                    if (widgetInfo.iconStyle) {
                        query("span.dijitMenuItemIcon", listItem.domNode).forEach(lang.hitch(this, function (node) {
                            try {
                                domStyle.set(node, widgetInfo.iconStyle);
                            } catch (err) {
                                console.error(err);
                            }
                            query("span.dijitMenuItemIconChar", listItem.domNode).forEach(lang.hitch(this, function (iconChar) {
                                domConstruct.place(iconChar, node, "before");
                            }));
                        }));
                    }

                    if (this.listColor) {
                        this.attachListItemColor(listItem);
                    }

                    widget.watch("activated", function (prop, o, n) {
                        if (!widget.get('isOneShot')) {
                            listItem.set('checked', n);
                        }
                    });
                }
                return listItem;
            },

            createMenuItemFromContent: function (menu, widgetInfo) {
                if (widgetInfo.content && widgetInfo.content.length > 0) {
                    var widgetId = widgetInfo.content[0].widgetId;
                    if (widgetId && this.spwViewer.spwWidgetsManager.getWidget(widgetId) == null) {
                        return null;
                    }
                }
                var listItem = new PopupMenuItem({
                    label: widgetInfo.label,
                    iconClass: "",
                    popup: this.buildMenu(widgetInfo.content, widgetInfo)
                });

                if (listItem.popup) {
                    listItem.popup.spwParentMenu = listItem;
                }

                if (widgetInfo.tooltip) {
                    new Tooltip({
                        connectId: listItem.domNode,
                        label: widgetInfo.tooltip,
                        position: ['after', 'below'],
                        showDelay: 1000
                    });
                }

                if (widgetInfo.iconStyle) {
                    query("span.dijitMenuItemIcon", listItem.domNode).forEach(lang.hitch(this, function (node) {
                        try {
                            domStyle.set(node, widgetInfo.iconStyle);
                        } catch (err) {
                            console.error(err);
                        }
                    }));
                }
                if (this.listColor) {
                    this.attachListItemColor(listItem);
                }

                menu.addChild(listItem);
                return listItem;
            },

            buildRendering: function () {
                this.inherited(arguments);

                this._button = new this.myButton({
                    label: this.label,
                    dropDownPosition: this.dropDownPosition || ['below']
                }, domConstruct.create("div", {}, this.domNode, "last"));

                if (this.tooltip) {
                    new Tooltip({
                        connectId: this._button.domNode,
                        label: this.tooltip,
                        position: ['after', 'below'],
                        showDelay: 1000
                    });
                }

                if (this.buttonColor) {
                    query(".dijitButtonNode", this._button.domNode).forEach(lang.hitch(this, function (node) {
                        try {
                            domStyle.set(node, "backgroundColor", this.buttonColor);
                        } catch (err) {
                            console.error(err);
                        }
                    }));
                }
                query(".dijitButtonNode", this._button.domNode).forEach(lang.hitch(this, function (node) {
                    on(node, mouse.enter, lang.hitch(this, function () {
                        try {
                            domStyle.set(node, "backgroundColor", this.focusColor);
                        } catch (err) {
                            console.error(err);
                        }
                    }));
                    on(node, mouse.leave, lang.hitch(this, function () {
                        try {
                            domStyle.set(node, "backgroundColor", this.buttonColor);
                        } catch (err) {
                            console.error(err);
                        }
                    }));
                }));

                if (this.iconStyle) {
                    this._button.set('iconClass', '');
                    query("span.dijitIcon", this._button.domNode).forEach(lang.hitch(this, function (node) {
                        try {
                            domStyle.set(node, this.iconStyle);
                        } catch (err) {
                            console.error(err);
                        }
                    }));
                }

                query("span.dijitButtonContents.dijitDownArrowButton", this._button.domNode).forEach(lang.hitch(this, function (node) {
                    if (this.labelPosition == "top" || this.labelPosition == "bottom") {
                        var wrapperDiv = domConstruct.create("div", {});
                        query("*", node).forEach(function (elem) {
                            domConstruct.place(elem, wrapperDiv, "last");
                        });
                        domConstruct.place(wrapperDiv, node);
                        query("span.dijitIcon", wrapperDiv).forEach(function (iconElem) {
                            domConstruct.place(iconElem, wrapperDiv, this.labelPosition == "bottom" ? "after" : "before");
                        });
                    } else if (this.labelPosition == "right") {
                        query("span.dijitIcon", node).forEach(function (iconElem) {
                            domConstruct.place(iconElem, node, "last");
                        });
                    }
                }));

                query("span.dijitButtonNode", this._button.domNode).forEach(lang.hitch(this, function (node) {
                    try {
                        domStyle.set(node, this.buttonStyle);
                    } catch (err) {
                        console.error(err);
                    }
                }));

                if (this.spwWidgetsManager.widgetsCreated) {
                    this._menu = this.buildMenu(this.content, this);

                    if (this._menu) {
                        this._menu.spwParentMenu = this._button;
                    }

                    this._button.set('dropDown', this._menu);
                } else {
                    this.spwWidgetsManager.on(this.spwWidgetsManager.events.widgetsCreated, lang.hitch(this, function () {
                        this._menu = this.buildMenu(this.content, this);
                        this._menu.spwParentMenu = this._button;
                        this._button.set('dropDown', this._menu);
                    }));
                }
            },

            attachListItemColor: function (listItem) {
                on(listItem.domNode, mouse.enter, lang.hitch(this, function () {
                    query("td", listItem.domNode).forEach(lang.hitch(this, function (node) {
                        try {
                            domStyle.set(node, "backgroundColor", this.listColor);
                        } catch (err) {
                            console.error(err);
                        }
                    }));
                }));
                on(listItem.domNode, mouse.leave, lang.hitch(this, function () {
                    query("td", listItem.domNode).forEach(lang.hitch(this, function (node) {
                        try {
                            domStyle.set(node, "backgroundColor", "white");
                        } catch (err) {
                            console.error(err);
                        }
                    }));
                }));
            },

            myDropDownMenu: declare([DropDownMenu], {
                onItemHover: function() {}
            }),

            myButton: declare([DropDownButton], {
                openDropDown: function () {
                    // summary:
                    //      Opens the dropdown for this widget.   To be called only when this.dropDown
                    //      has been created and is ready to display (ie, it's data is loaded).
                    // returns:
                    //      return value of dijit/popup.open()
                    // tags:
                    //      protected

                    var dropDown = this.dropDown,
                        ddNode = dropDown.domNode,
                        aroundNode = this._aroundNode || this.domNode,
                        self = this;

                    var args = {
                        parent: this,
                        popup: dropDown,
                        around: aroundNode,
                        orient: this.dropDownPosition,
                        maxHeight: this.maxHeight,
                        onExecute: function () {
                            self.closeDropDown(true);
                        },
                        onCancel: function (evt) {
                            self.closeDropDown(true);
                        },
                        onClose: function () {
                            domAttr.set(self._popupStateNode, "popupActive", false);
                            domClass.remove(self._popupStateNode, "dijitHasDropDownOpen");
                            self._set("_opened", false);    // use set() because _CssStateMixin is watching
                        }
                    };

                    var retVal = popup.open(args);

                    // https://github.com/dojo/dijit/blob/1ab27cefdce2ddd2f386dcfd7bba1a8dc6163cc7/popup.js
                    var lastPushed = popup._stack[popup._stack.length - 1];

                    lastPushed.handlers[0].remove();
                    lastPushed.handlers[0] = on(lastPushed.wrapper, 'keydown', lang.hitch(popup, function (evt) {
                        if (evt.keyCode == keys.ESCAPE && args.onCancel) {
                            evt.stopPropagation();
                            evt.preventDefault();
                            args.onCancel();
                        }
                        /*else if(evt.keyCode == keys.TAB){
                         evt.stopPropagation();
                         evt.preventDefault();
                         var topPopup = this.getTopPopup();
                         if(topPopup && topPopup.onCancel){
                         topPopup.onCancel();
                         }
                         }*/
                    }));

                    if (dropDown.onCancel && args.onCancel) {
                        lastPushed.handlers[1].remove();
                    }

                    lastPushed.handlers[lastPushed.handlers.length - 1].remove();

                    // Set width of drop down if necessary, so that dropdown width + width of scrollbar (from popup wrapper)
                    // matches width of aroundNode
                    if (this.forceWidth || (this.autoWidth && aroundNode.offsetWidth > dropDown._popupWrapper.offsetWidth)) {
                        var widthAdjust = aroundNode.offsetWidth - dropDown._popupWrapper.offsetWidth;
                        var resizeArgs = {
                            w: dropDown.domNode.offsetWidth + widthAdjust
                        };
                        if (lang.isFunction(dropDown.resize)) {
                            dropDown.resize(resizeArgs);
                        } else {
                            domGeometry.setMarginBox(ddNode, resizeArgs);
                        }

                        // If dropdown is right-aligned then compensate for width change by changing horizontal position
                        if (retVal.corner[1] == "R") {
                            dropDown._popupWrapper.style.left =
                                (dropDown._popupWrapper.style.left.replace("px", "") - widthAdjust) + "px";
                        }
                    }

                    domAttr.set(this._popupStateNode, "popupActive", "true");
                    domClass.add(this._popupStateNode, "dijitHasDropDownOpen");
                    this._set("_opened", true); // use set() because _CssStateMixin is watching

                    this._popupStateNode.setAttribute("aria-expanded", "true");
                    this._popupStateNode.setAttribute("aria-owns", dropDown.id);

                    // Set aria-labelledby on dropdown if it's not already set to something more meaningful
                    if (ddNode.getAttribute("role") !== "presentation" && !ddNode.getAttribute("aria-labelledby")) {
                        ddNode.setAttribute("aria-labelledby", this.id);
                    }

                    return retVal;
                }
            })
        });

        return SpwIWantTo;
    });