<commit_before>/*globals define*/
/*
 * Copyright (C) 2013 Vanderbilt University, All rights reserved.
 *
 * @author brollb / https://github/brollb
 */

define(['logManager',
        'clientUtil'], function (logManager,
                                 clientUtil) {

    "use strict";

    var SelectionManager,
        SELECTION_OVERLAP_RATIO = 0.5,
        SELECTION_OUTLINE_MARGIN = 15,
        SELECTION_OUTLINE_MIN_WIDTH = 100,
        MOUSE_EVENT_POSTFIX = "SelectionManager";

    SelectionManager = function (options) {
        this.logger = (options && options.logger) || logManager.create(((options && options.loggerName) || "SelectionManager"));

        this._blockEditor = options ? options.blockEditor : null;

        if (this._blockEditor === undefined || this._blockEditor === null) {
            this.logger.error("Trying to initialize a SelectionManager without a blockEditor...");
            throw ("SelectionManager can not be created");
        }

        this._selectedElement = null;
        this._rotationEnabled = true;

        this.logger.debug("SelectionManager ctor finished");
    };

    SelectionManager.prototype.activate = function () {
        this._activateMouseListeners();
    };

    SelectionManager.prototype.deactivate = function () {
        this._deactivateMouseListeners();
        this._clearSelection();
    };

    SelectionManager.prototype._activateMouseListeners = function () {
        //enable SelectionManager specific DOM event listeners
        var self = this;

        this._blockEditor.onItemMouseDown = function (itemId, eventDetails) {
            if (self._blockEditor.mode === self._blockEditor.OPERATING_MODES.READ_ONLY ||
                self._blockEditor.mode === self._blockEditor.OPERATING_MODES.DESIGN) {
                self._setSelection(itemId, false);
                //self._setSelection([itemId], self._isMultiSelectionModifierKeyPressed(eventDetails));
            }
        };

        this._blockEditor.onBackgroundMouseDown = function (eventDetails) {
            if (self._blockEditor.mode === self._blockEditor.OPERATING_MODES.READ_ONLY ||
                self._blockEditor.mode === self._blockEditor.OPERATING_MODES.DESIGN) {
                self._onBackgroundMouseDown(eventDetails);
            }
        };
    };

    SelectionManager.prototype._deactivateMouseListeners = function () {
        this._blockEditor.onItemMouseDown = undefined;
        this._blockEditor.onConnectionMouseDown = undefined;
        this._blockEditor.onBackgroundMouseDown = undefined;
    };

    SelectionManager.prototype.initialize = function (el) {
        var self = this;

        this.$el = el;

        this._blockEditor.addEventListener(this._blockEditor.events.ON_COMPONENT_DELETE, function (blockEditor, componentId) {
            self._onComponentDelete(componentId);
        });
    };

    SelectionManager.prototype.getSelectedElements = function () {
        //DragInfo calls this and requires an array
        return [this._selectedElement];
    };

    SelectionManager.prototype.clear = function () {
        this._clearSelection();
    };

    SelectionManager.prototype.setSelection = function (idList, addToExistingSelection) {
        this._setSelection(idList, addToExistingSelection);
    };

    SelectionManager.prototype.onSelectionCommandClicked = function (command, selectedIds) {
        this.logger.warning("SelectionManager.prototype.onSelectionCommandClicked IS NOT OVERRIDDEN IN HOST COMPONENT. command: '" + command + "', selectedIds: " + selectedIds);
    };

    SelectionManager.prototype.onSelectionChanged = function (selectedIDs) {
        this.logger.warning("SelectionManager.prototype.onSelectionChanged IS NOT OVERRIDDEN IN HOST COMPONENT. selectedIDs: " + selectedIDs);
    };

    /********************** MULTIPLE SELECTION MODIFIER KEY CHECK ********************/
    SelectionManager.prototype._isMultiSelectionModifierKeyPressed = function (event) {
        return event.ctrlKey || event.metaKey;
    };
    /***************END OF --- MULTIPLE SELECTION MODIFIER KEY CHECK *****************/

    /*********************** RUBBERBAND SELECTION *************************************/

    SelectionManager.prototype._onBackgroundMouseDown = function (/*event*/) {
        //Clear the current selection
        this._clearSelection();
    };

    SelectionManager.prototype._onBackgroundMouseMove = function (event) {
        var mousePos = {'mX': event.mouseX, 'mY': event.mouseY};

        if (this._rubberbandSelection) {
            this._rubberbandSelection.x2 = mousePos.mX;
            this._rubberbandSelection.y2 = mousePos.mY;
            this._drawSelectionRubberBand();
        }
    };

    SelectionManager.prototype._onBackgroundMouseUp = function (event) {
        var mousePos = {'mX': event.mouseX, 'mY': event.mouseY},
            params;

        if (this._rubberbandSelection) {
            this._rubberbandSelection.x2 = mousePos.mX;
            this._rubberbandSelection.y2 = mousePos.mY;

            this._drawSelectionRubberBand();

            params = {"addToExistingSelection": this._rubberbandSelection.addToExistingSelection,
                "x": Math.min(this._rubberbandSelection.x, this._rubberbandSelection.x2),
                "x2": Math.max(this._rubberbandSelection.x, this._rubberbandSelection.x2),
                "y": Math.min(this._rubberbandSelection.y, this._rubberbandSelection.y2),
                "y2": Math.max(this._rubberbandSelection.y, this._rubberbandSelection.y2)};

            this._selectItemsByRubberBand(params);

            //remove rubber-band DOM
            this.$rubberBand.remove();
            this.$rubberBand = null;

            delete this._rubberbandSelection;
        }
    };

    /*********************** CLEAR SELECTION *********************************/
    SelectionManager.prototype._clearSelection = function () {
        var items = this._blockEditor.items,
            item,
            changed = false;

        if (this._selectedElement) {
            item = items[this._selectedElement];

            if (item) {
                if ($.isFunction(item.onDeselect)) {
                    item.onDeselect();
                }
            }

            changed = true;
        }

        this._selectedElement = null;

        this.hideSelectionOutline();

        if (changed) {
            this.onSelectionChanged(this._selectedElement);
        }
    };
    /*********************** END OF --- CLEAR SELECTION ****************************/

    /*********************** SET SELECTION *********************************/
    SelectionManager.prototype._setSelection = function (id) {
        var item,
            items = this._blockEditor.items,
            changed = false;

        this.logger.debug("setSelection: " + id);

        if(this._selectedElement !== id){
            changed = true;
        }

        if(this._selectedElement){
            item = items[this._selectedElement];
            if (item && $.isFunction(item.onDeselect)) {
                item.onDeselect();
            }
        }

        if(id){
            this._selectedElement = id;
            item = items[this._selectedElement];

            if (item && $.isFunction(item.onSelect)) {
                item.onSelect(true);
            }
        }
        this.showSelectionOutline();

        if (changed) {
            this.onSelectionChanged(this._selectedElement);
        }
    };
    /*********************** END OF --- SET SELECTION *********************************/

    /*********************** COMPONENT DELETE HANDLER *******************/
    SelectionManager.prototype._onComponentDelete = function (componentId) {
        //items are already deleted, we just need to remove them from the selectedIdList (if there)
        if (componentId === this._selectedElement){
            this._selectedElement = null;
            this.onSelectionChanged(this._selectedElement);
        }

    };
    /*********************** COMPONENT DELETE HANDLER *******************/

    /*********************** SHOW SELECTION OUTLINE *********************************/
    var SELECTION_OUTLINE_BASE = $('<div/>', {
        "class" : "selection-outline"
    });
    SelectionManager.prototype.showSelectionOutline = function () {
        var bBox = this._getSelectionBoundingBox(),
            cW = this._blockEditor._actualSize.w,
            cH = this._blockEditor._actualSize.h;

        if (bBox && bBox.hasOwnProperty("x")) {

            bBox.x -= SELECTION_OUTLINE_MARGIN;
            bBox.y -= SELECTION_OUTLINE_MARGIN;
            bBox.x2 += SELECTION_OUTLINE_MARGIN;
            bBox.y2 += SELECTION_OUTLINE_MARGIN;

            if (bBox.x < 0) {
                bBox.x = 0;
            }

            if (bBox.y < 0) {
                bBox.y = 0;
            }

            if (bBox.x2 > cW) {
                bBox.x2 = cW;
            }

            if (bBox.y2 > cH) {
                bBox.y2 = cH;
            }

            bBox.w = bBox.x2 - bBox.x;
            bBox.h = bBox.y2 - bBox.y;
            if (bBox.w < SELECTION_OUTLINE_MIN_WIDTH) {
                bBox.x -= (SELECTION_OUTLINE_MIN_WIDTH - bBox.w) / 2;
                bBox.x2 += (SELECTION_OUTLINE_MIN_WIDTH - bBox.w) / 2;
                bBox.w = bBox.x2 - bBox.x;
            }

            if (this._blockEditor.skinParts.$selectionOutline) {
                this._blockEditor.skinParts.$selectionOutline.empty();
            } else {
                this._blockEditor.skinParts.$selectionOutline = SELECTION_OUTLINE_BASE.clone();

                this._blockEditor.skinParts.$itemsContainer.append(this._blockEditor.skinParts.$selectionOutline);
            }

            this._blockEditor.skinParts.$selectionOutline.css({ "left": bBox.x,
                "top": bBox.y,
                "width": bBox.w,
                "height": bBox.h });

            this._renderSelectionActions();
        } else {
            this.hideSelectionOutline();
        }
    };
    /*********************** END OF --- SHOW SELECTION OUTLINE *********************************/

    /*********************** HIDE SELECTION OUTLINE *********************************/
    SelectionManager.prototype.hideSelectionOutline = function () {
        if (this._blockEditor.skinParts.$selectionOutline) {
            this._blockEditor.skinParts.$selectionOutline.empty();
            this._blockEditor.skinParts.$selectionOutline.remove();
            this._blockEditor.skinParts.$selectionOutline = null;
        }
    };
    /*********************** END OF --- HIDE SELECTION OUTLINE *********************************/

    /************* GET SELECTION OUTLINE COORDINATES AND DIMENSIONS ************************/
    SelectionManager.prototype._getSelectionBoundingBox = function () {
        var bBox,
            id,
            child,
            childBBox,
            items = this._blockEditor.items;

        if (this._selectedElement) {
            id = this._selectedElement;

            if (items[id]) {

                if (!bBox) {
                    bBox = { "x": this._blockEditor._actualSize.w,
                        "y": this._blockEditor._actualSize.h,
                        "x2": 0,
                        "y2": 0};
                }

                child = items[id];
                while (child) {  // Create the box from box and all sibling pointers
                    childBBox = child.getBoundingBox();

                    if (childBBox.x < bBox.x) {
                        bBox.x = childBBox.x;
                    }
                    if (childBBox.y < bBox.y) {
                        bBox.y = childBBox.y;
                    }
                    if (childBBox.x2 > bBox.x2) {
                        bBox.x2 = childBBox.x2;
                    }
                    if (childBBox.y2 > bBox.y2) {
                        bBox.y2 = childBBox.y2;
                    }

                    child = child.ptrs['next'];
                }
            }
        }

        return bBox;
    };
    /************* END OF --- GET SELECTION OUTLINE COORDINATES AND DIMENSIONS ************************/

    /************* RENDER COMMAND BUTTONS ON SELECTION OUTLINE ************************/

    var DELETE_BUTTON_BASE = $('<div/>', {
        "class" : "s-btn delete",
        "command" : "delete"
    });

    DELETE_BUTTON_BASE.html('<i class="glyphicon glyphicon-remove"></i>');

    SelectionManager.prototype._renderSelectionActions = function () {
        var deleteBtn,
            self = this;

        if (this._blockEditor.getIsReadOnlyMode() !== true) {
            deleteBtn = DELETE_BUTTON_BASE.clone();
            this._blockEditor.skinParts.$selectionOutline.append(deleteBtn);
        }

        //detach mousedown handler on selection outline
        this._blockEditor.skinParts.$selectionOutline.off("mousedown").off("click", ".s-btn");
        this._blockEditor.skinParts.$selectionOutline.on("mousedown", function (event) {
            event.stopPropagation();
        }).on("click", ".s-btn", function (event) {
            var command = $(this).attr("command");
            self.logger.debug("Selection button clicked with command: '" + command + "'");

            self.onSelectionCommandClicked(command, self._selectedElement, event);

            event.stopPropagation();
            event.preventDefault();
        });

    };
    /************* END OF --- RENDER COMMAND BUTTONS ON SELECTION OUTLINE ************************/

    return SelectionManager;
});
<commit_msg>Fixed highlighting box<commit_after>/*globals define*/
/*
 * Copyright (C) 2013 Vanderbilt University, All rights reserved.
 *
 * @author brollb / https://github/brollb
 */

define(['logManager',
        'clientUtil'], function (logManager,
                                 clientUtil) {

    "use strict";

    var SelectionManager,
        SELECTION_OVERLAP_RATIO = 0.5,
        SELECTION_OUTLINE_MARGIN = 15,
        SELECTION_OUTLINE_MIN_WIDTH = 100,
        MOUSE_EVENT_POSTFIX = "SelectionManager";

    SelectionManager = function (options) {
        this.logger = (options && options.logger) || logManager.create(((options && options.loggerName) || "SelectionManager"));

        this._blockEditor = options ? options.blockEditor : null;

        if (this._blockEditor === undefined || this._blockEditor === null) {
            this.logger.error("Trying to initialize a SelectionManager without a blockEditor...");
            throw ("SelectionManager can not be created");
        }

        this._selectedElement = null;
        this._rotationEnabled = true;

        this.logger.debug("SelectionManager ctor finished");
    };

    SelectionManager.prototype.activate = function () {
        this._activateMouseListeners();
    };

    SelectionManager.prototype.deactivate = function () {
        this._deactivateMouseListeners();
        this._clearSelection();
    };

    SelectionManager.prototype._activateMouseListeners = function () {
        //enable SelectionManager specific DOM event listeners
        var self = this;

        this._blockEditor.onItemMouseDown = function (itemId, eventDetails) {
            if (self._blockEditor.mode === self._blockEditor.OPERATING_MODES.READ_ONLY ||
                self._blockEditor.mode === self._blockEditor.OPERATING_MODES.DESIGN) {
                self._setSelection(itemId, false);
                //self._setSelection([itemId], self._isMultiSelectionModifierKeyPressed(eventDetails));
            }
        };

        this._blockEditor.onBackgroundMouseDown = function (eventDetails) {
            if (self._blockEditor.mode === self._blockEditor.OPERATING_MODES.READ_ONLY ||
                self._blockEditor.mode === self._blockEditor.OPERATING_MODES.DESIGN) {
                self._onBackgroundMouseDown(eventDetails);
            }
        };
    };

    SelectionManager.prototype._deactivateMouseListeners = function () {
        this._blockEditor.onItemMouseDown = undefined;
        this._blockEditor.onConnectionMouseDown = undefined;
        this._blockEditor.onBackgroundMouseDown = undefined;
    };

    SelectionManager.prototype.initialize = function (el) {
        var self = this;

        this.$el = el;

        this._blockEditor.addEventListener(this._blockEditor.events.ON_COMPONENT_DELETE, function (blockEditor, componentId) {
            self._onComponentDelete(componentId);
        });
    };

    SelectionManager.prototype.getSelectedElements = function () {
        //DragInfo calls this and requires an array
        return [this._selectedElement];
    };

    SelectionManager.prototype.clear = function () {
        this._clearSelection();
    };

    SelectionManager.prototype.setSelection = function (idList, addToExistingSelection) {
        this._setSelection(idList, addToExistingSelection);
    };

    SelectionManager.prototype.onSelectionCommandClicked = function (command, selectedIds) {
        this.logger.warning("SelectionManager.prototype.onSelectionCommandClicked IS NOT OVERRIDDEN IN HOST COMPONENT. command: '" + command + "', selectedIds: " + selectedIds);
    };

    SelectionManager.prototype.onSelectionChanged = function (selectedIDs) {
        this.logger.warning("SelectionManager.prototype.onSelectionChanged IS NOT OVERRIDDEN IN HOST COMPONENT. selectedIDs: " + selectedIDs);
    };

    /********************** MULTIPLE SELECTION MODIFIER KEY CHECK ********************/
    SelectionManager.prototype._isMultiSelectionModifierKeyPressed = function (event) {
        return event.ctrlKey || event.metaKey;
    };
    /***************END OF --- MULTIPLE SELECTION MODIFIER KEY CHECK *****************/

    /*********************** RUBBERBAND SELECTION *************************************/

    SelectionManager.prototype._onBackgroundMouseDown = function (/*event*/) {
        //Clear the current selection
        this._clearSelection();
    };

    SelectionManager.prototype._onBackgroundMouseMove = function (event) {
        var mousePos = {'mX': event.mouseX, 'mY': event.mouseY};

        if (this._rubberbandSelection) {
            this._rubberbandSelection.x2 = mousePos.mX;
            this._rubberbandSelection.y2 = mousePos.mY;
            this._drawSelectionRubberBand();
        }
    };

    SelectionManager.prototype._onBackgroundMouseUp = function (event) {
        var mousePos = {'mX': event.mouseX, 'mY': event.mouseY},
            params;

        if (this._rubberbandSelection) {
            this._rubberbandSelection.x2 = mousePos.mX;
            this._rubberbandSelection.y2 = mousePos.mY;

            this._drawSelectionRubberBand();

            params = {"addToExistingSelection": this._rubberbandSelection.addToExistingSelection,
                "x": Math.min(this._rubberbandSelection.x, this._rubberbandSelection.x2),
                "x2": Math.max(this._rubberbandSelection.x, this._rubberbandSelection.x2),
                "y": Math.min(this._rubberbandSelection.y, this._rubberbandSelection.y2),
                "y2": Math.max(this._rubberbandSelection.y, this._rubberbandSelection.y2)};

            this._selectItemsByRubberBand(params);

            //remove rubber-band DOM
            this.$rubberBand.remove();
            this.$rubberBand = null;

            delete this._rubberbandSelection;
        }
    };

    /*********************** CLEAR SELECTION *********************************/
    SelectionManager.prototype._clearSelection = function () {
        var items = this._blockEditor.items,
            item,
            changed = false;

        if (this._selectedElement) {
            item = items[this._selectedElement];

            if (item) {
                if ($.isFunction(item.onDeselect)) {
                    item.onDeselect();
                }
            }

            changed = true;
        }

        this._selectedElement = null;

        this.hideSelectionOutline();

        if (changed) {
            this.onSelectionChanged(this._selectedElement);
        }
    };
    /*********************** END OF --- CLEAR SELECTION ****************************/

    /*********************** SET SELECTION *********************************/
    SelectionManager.prototype._setSelection = function (id) {
        var item,
            items = this._blockEditor.items,
            changed = false;

        this.logger.debug("setSelection: " + id);

        if(this._selectedElement !== id){
            changed = true;
        }

        if(this._selectedElement){
            item = items[this._selectedElement];
            if (item && $.isFunction(item.onDeselect)) {
                item.onDeselect();
            }
        }

        if(id){
            this._selectedElement = id;
            item = items[this._selectedElement];

            if (item && $.isFunction(item.onSelect)) {
                item.onSelect(true);
            }
        }
        this.showSelectionOutline();

        if (changed) {
            this.onSelectionChanged(this._selectedElement);
        }
    };
    /*********************** END OF --- SET SELECTION *********************************/

    /*********************** COMPONENT DELETE HANDLER *******************/
    SelectionManager.prototype._onComponentDelete = function (componentId) {
        //items are already deleted, we just need to remove them from the selectedIdList (if there)
        if (componentId === this._selectedElement){
            this._selectedElement = null;
            this.onSelectionChanged(this._selectedElement);
        }

    };
    /*********************** COMPONENT DELETE HANDLER *******************/

    /*********************** SHOW SELECTION OUTLINE *********************************/
    var SELECTION_OUTLINE_BASE = $('<div/>', {
        "class" : "selection-outline"
    });
    SelectionManager.prototype.showSelectionOutline = function () {
        var bBox = this._getSelectionBoundingBox(),
            cW = this._blockEditor._actualSize.w,
            cH = this._blockEditor._actualSize.h;

        if (bBox && bBox.hasOwnProperty("x")) {

            bBox.x -= SELECTION_OUTLINE_MARGIN;
            bBox.y -= SELECTION_OUTLINE_MARGIN;
            bBox.x2 += SELECTION_OUTLINE_MARGIN;
            bBox.y2 += SELECTION_OUTLINE_MARGIN;

            if (bBox.x < 0) {
                bBox.x = 0;
            }

            if (bBox.y < 0) {
                bBox.y = 0;
            }

            if (bBox.x2 > cW) {
                bBox.x2 = cW;
            }

            if (bBox.y2 > cH) {
                bBox.y2 = cH;
            }

            bBox.w = bBox.x2 - bBox.x;
            bBox.h = bBox.y2 - bBox.y;
            if (bBox.w < SELECTION_OUTLINE_MIN_WIDTH) {
                bBox.x -= (SELECTION_OUTLINE_MIN_WIDTH - bBox.w) / 2;
                bBox.x2 += (SELECTION_OUTLINE_MIN_WIDTH - bBox.w) / 2;
                bBox.w = bBox.x2 - bBox.x;
            }

            if (this._blockEditor.skinParts.$selectionOutline) {
                this._blockEditor.skinParts.$selectionOutline.empty();
            } else {
                this._blockEditor.skinParts.$selectionOutline = SELECTION_OUTLINE_BASE.clone();

                this._blockEditor.skinParts.$itemsContainer.append(this._blockEditor.skinParts.$selectionOutline);
            }

            this._blockEditor.skinParts.$selectionOutline.css({ "left": bBox.x,
                "top": bBox.y,
                "width": bBox.w,
                "height": bBox.h });

            this._renderSelectionActions();
        } else {
            this.hideSelectionOutline();
        }
    };
    /*********************** END OF --- SHOW SELECTION OUTLINE *********************************/

    /*********************** HIDE SELECTION OUTLINE *********************************/
    SelectionManager.prototype.hideSelectionOutline = function () {
        if (this._blockEditor.skinParts.$selectionOutline) {
            this._blockEditor.skinParts.$selectionOutline.empty();
            this._blockEditor.skinParts.$selectionOutline.remove();
            this._blockEditor.skinParts.$selectionOutline = null;
        }
    };
    /*********************** END OF --- HIDE SELECTION OUTLINE *********************************/

    /************* GET SELECTION OUTLINE COORDINATES AND DIMENSIONS ************************/
    SelectionManager.prototype._getSelectionBoundingBox = function () {
        var bBox,
            id,
            child,
            current,
            next = [],
            ptrs,
            childBBox,
            items = this._blockEditor.items;

        if (this._selectedElement) {
            id = this._selectedElement;

            if (items[id]) {

                if (!bBox) {
                    bBox = { "x": this._blockEditor._actualSize.w,
                        "y": this._blockEditor._actualSize.h,
                        "x2": 0,
                        "y2": 0};
                }

                current = [items[id]];
                while (current.length) {  // Create the box from box and all sibling pointers
                    for (var c = current.length-1; c >= 0; c--) {  // Create the box from box and all sibling pointers
                        childBBox = current[c].getBoundingBox();

                        if (childBBox.x < bBox.x) {
                            bBox.x = childBBox.x;
                        }
                        if (childBBox.y < bBox.y) {
                            bBox.y = childBBox.y;
                        }
                        if (childBBox.x2 > bBox.x2) {
                            bBox.x2 = childBBox.x2;
                        }
                        if (childBBox.y2 > bBox.y2) {
                            bBox.y2 = childBBox.y2;
                        }

                        ptrs = Object.keys(current[c].ptrs);
                        for (var i = ptrs.length-1; i >= 0; i--) {
                            child = current[c].ptrs[ptrs[i]];
                            if (child) {
                                next.push(child);
                            }
                        }
                    }
                    current = next;
                    next = [];
                }
            }
        }

        return bBox;
    };
    /************* END OF --- GET SELECTION OUTLINE COORDINATES AND DIMENSIONS ************************/

    /************* RENDER COMMAND BUTTONS ON SELECTION OUTLINE ************************/

    var DELETE_BUTTON_BASE = $('<div/>', {
        "class" : "s-btn delete",
        "command" : "delete"
    });

    DELETE_BUTTON_BASE.html('<i class="glyphicon glyphicon-remove"></i>');

    SelectionManager.prototype._renderSelectionActions = function () {
        var deleteBtn,
            self = this;

        if (this._blockEditor.getIsReadOnlyMode() !== true) {
            deleteBtn = DELETE_BUTTON_BASE.clone();
            this._blockEditor.skinParts.$selectionOutline.append(deleteBtn);
        }

        //detach mousedown handler on selection outline
        this._blockEditor.skinParts.$selectionOutline.off("mousedown").off("click", ".s-btn");
        this._blockEditor.skinParts.$selectionOutline.on("mousedown", function (event) {
            event.stopPropagation();
        }).on("click", ".s-btn", function (event) {
            var command = $(this).attr("command");
            self.logger.debug("Selection button clicked with command: '" + command + "'");

            self.onSelectionCommandClicked(command, self._selectedElement, event);

            event.stopPropagation();
            event.preventDefault();
        });

    };
    /************* END OF --- RENDER COMMAND BUTTONS ON SELECTION OUTLINE ************************/

    return SelectionManager;
});
<|endoftext|>


<commit_before>/**
 * Copyright (c) 2008 OpenGeo
 *
 */

/**
 * api: (define)
 * module = GeoExplorer
 * class = CapabilitiesGrid(config)
 * extends = Ext.grid.GridPanel
 */

/** api: constructor
 * ..class:: CapabilitiesGrid(config)
 * :param: config: A configuration :class:`Object`
 *
 * Create a new grid displaying the WMS cabilities of a URL, or the contents of
 * a :class:`GeoExt.data.WMSCapabilitiesStore`\ .  The user can add layers to a
 * passed-in :class:`GeoExt.MapPanel` from the grid.
 */

Ext.namespace("GeoExplorer");
GeoExplorer.CapabilitiesGrid = Ext.extend(Ext.grid.GridPanel, {

    store: null,

    cm: null,

    /**
     * api: property[mapPanel]
     * A :class:`GeoExt.MapPanel` to which layers can be added via this grid.
     */
    mapPanel : null,

    /** api: property[url]
     * A :class:`String` containing an OWS URL to which the GetCapabilities
     * request is sent.  Necessary if a store is not passed in as a
     * configuration option.
     */
    url: null,

    autoExpandColumn: "title",

    /** api: method[initComponent]
     *
     * Initializes the CapabilitiesGrid. Creates and loads a WMS Capabilities
     * store from the url property if one is not passed as a configuration
     * option.
     */
    initComponent: function(){

        if(!this.store){
            this.store = new GeoExt.data.WMSCapabilitiesStore({
                url: this.url + "?service=wms&request=GetCapabilities"
            });

            this.store.load();
        }

        var expander = new Ext.grid.RowExpander({
            tpl : new Ext.Template(
                '
Abstract: {abstract}
')});

        this.plugins = expander;

        this.cm = new Ext.grid.ColumnModel([
            expander,
            {header: "Name", dataIndex: "name", width: 180, sortable: true},
            {id: "title", header: "Title", dataIndex: "title", sortable: true},
            {header: "Queryable", dataIndex: "queryable"}
        ]);

        GeoExplorer.CapabilitiesGrid.superclass.initComponent.call(this);
    },

    /** api: method[addLayers]
     * :param: base: a boolean indicating whether or not to make the new layer
     *     a base layer.
     *
     * Adds a layer to the :class:`GeoExt.MapPanel` of this instance.
     */
    addLayers : function(base){

        var sm = this.getSelectionModel();

        //for now just use the first selected record
        //TODO: force single selection (until we allow
        //adding group layers)
        var records = sm.getSelections();

        var record, layer;
        for(var i = 0; i < records.length; i++){
            Ext.data.Record.AUTO_ID++;
            record = records[i].copy(Ext.data.Record.AUTO_ID);

            layer = record.get("layer").clone();
            record.data.layer = layer;

            /*
             * TODO: deal with srs and maxExtent - this should be done in the
             * CapabilitiesReader or by the serviceType provider.
             * At this point, we need to think about SRS if we want the layer to
             * have a maxExtent.  For our app, we are dealing with EPSG:4326
             * only.  This will have to be made more generic for apps that use
             * other srs.
             */

            layer.restrictedExtent = OpenLayers.Bounds.fromArray(record.get("llbbox")).transform(
                new OpenLayers.Projection("EPSG:4326"),
                new OpenLayers.Projection(this.mapPanel.map.getProjectionObject())
            );

            if (this.alignToGrid) {
                layer.maxExtent = new OpenLayers.Bounds(-180, -90, 180, 90).transform(
                            new OpenLayers.Projection("EPSG:4326"),
                            new OpenLayers.Projection(this.mapPanel.map.getProjectionObject())
                        );
            } else {
                layer.maxExtent = layer.restrictedExtent;
            }

            record.set("background", base && "background");
            this.mapPanel.layers.insert(
                base ? 0 : this.mapPanel.layers.getCount(),
                record
            );
        }

    }
});
<commit_msg>Request fewer, bigger tiles (see #193).<commit_after>/**
 * Copyright (c) 2008 OpenGeo
 *
 */

/**
 * api: (define)
 * module = GeoExplorer
 * class = CapabilitiesGrid(config)
 * extends = Ext.grid.GridPanel
 */

/** api: constructor
 * ..class:: CapabilitiesGrid(config)
 * :param: config: A configuration :class:`Object`
 *
 * Create a new grid displaying the WMS cabilities of a URL, or the contents of
 * a :class:`GeoExt.data.WMSCapabilitiesStore`\ .  The user can add layers to a
 * passed-in :class:`GeoExt.MapPanel` from the grid.
 */

Ext.namespace("GeoExplorer");
GeoExplorer.CapabilitiesGrid = Ext.extend(Ext.grid.GridPanel, {

    store: null,

    cm: null,

    /**
     * api: property[mapPanel]
     * A :class:`GeoExt.MapPanel` to which layers can be added via this grid.
     */
    mapPanel : null,

    /** api: property[url]
     * A :class:`String` containing an OWS URL to which the GetCapabilities
     * request is sent.  Necessary if a store is not passed in as a
     * configuration option.
     */
    url: null,

    autoExpandColumn: "title",

    /** api: method[initComponent]
     *
     * Initializes the CapabilitiesGrid. Creates and loads a WMS Capabilities
     * store from the url property if one is not passed as a configuration
     * option.
     */
    initComponent: function(){

        if(!this.store){
            this.store = new GeoExt.data.WMSCapabilitiesStore({
                url: this.url + "?service=wms&request=GetCapabilities"
            });

            this.store.load();
        }

        var expander = new Ext.grid.RowExpander({
            tpl : new Ext.Template(
                '
Abstract: {abstract}
')});

        this.plugins = expander;

        this.cm = new Ext.grid.ColumnModel([
            expander,
            {header: "Name", dataIndex: "name", width: 180, sortable: true},
            {id: "title", header: "Title", dataIndex: "title", sortable: true},
            {header: "Queryable", dataIndex: "queryable"}
        ]);

        GeoExplorer.CapabilitiesGrid.superclass.initComponent.call(this);
    },

    /** api: method[addLayers]
     * :param: base: a boolean indicating whether or not to make the new layer
     *     a base layer.
     *
     * Adds a layer to the :class:`GeoExt.MapPanel` of this instance.
     */
    addLayers : function(base){

        var sm = this.getSelectionModel();

        //for now just use the first selected record
        //TODO: force single selection (until we allow
        //adding group layers)
        var records = sm.getSelections();

        var record, layer;
        for(var i = 0; i < records.length; i++){
            Ext.data.Record.AUTO_ID++;
            record = records[i].copy(Ext.data.Record.AUTO_ID);

            layer = record.get("layer").clone();
            record.data.layer = layer;

            // TODO: allow config for layer options
            layer.buffer = 0;
            layer.tileSize = new OpenLayers.Size(512, 512),

            /*
             * TODO: deal with srs and maxExtent - this should be done in the
             * CapabilitiesReader or by the serviceType provider.
             * At this point, we need to think about SRS if we want the layer to
             * have a maxExtent.  For our app, we are dealing with EPSG:4326
             * only.  This will have to be made more generic for apps that use
             * other srs.
             */

            layer.restrictedExtent = OpenLayers.Bounds.fromArray(record.get("llbbox")).transform(
                new OpenLayers.Projection("EPSG:4326"),
                new OpenLayers.Projection(this.mapPanel.map.getProjectionObject())
            );

            if (this.alignToGrid) {
                layer.maxExtent = new OpenLayers.Bounds(-180, -90, 180, 90).transform(
                            new OpenLayers.Projection("EPSG:4326"),
                            new OpenLayers.Projection(this.mapPanel.map.getProjectionObject())
                        );
            } else {
                layer.maxExtent = layer.restrictedExtent;
            }

            record.set("background", base && "background");
            this.mapPanel.layers.insert(
                base ? 0 : this.mapPanel.layers.getCount(),
                record
            );
        }

    }
});
<|endoftext|>


<commit_before>/*
 *     (C) Copyright 2012-2013 Universidad Politécnica de Madrid
 *
 *     This file is part of Wirecloud Platform.
 *
 *     Wirecloud Platform is free software: you can redistribute it and/or
 *     modify it under the terms of the GNU Affero General Public License as
 *     published by the Free Software Foundation, either version 3 of the
 *     License, or (at your option) any later version.
 *
 *     Wirecloud is distributed in the hope that it will be useful, but WITHOUT
 *     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 *     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public
 *     License for more details.
 *
 *     You should have received a copy of the GNU Affero General Public License
 *     along with Wirecloud Platform.  If not, see
 *     <http://www.gnu.org/licenses/>.
 *
 */

/*globals gettext, Wirecloud*/

(function () {

    "use strict";

    var OperatorMeta = function OperatorMeta(desc) {
        var vendor, name, version, uri, display_name, description, inputs,
            outputs, prefList, prefs, pref, i;

        // Vendor
        if (!('vendor' in desc) || desc.vendor.trim() === '') {
            throw new TypeError(gettext('missing operator vendor'));
        }
        vendor = desc.vendor.trim();
        Object.defineProperty(this, 'vendor', {value: vendor});

        // Name
        if (!('name' in desc) || desc.name.trim() === '') {
            throw new TypeError(gettext('missing operator name'));
        }
        name = desc.name.trim();
        Object.defineProperty(this, 'name', {value: name});

        // Version
        if (!('version' in desc) || desc.version.trim() === '') {
            throw new TypeError(gettext('missing operator version'));
        }
        version = desc.version.trim();
        Object.defineProperty(this, 'version', {value: version});

        // URI
        uri = desc.name.trim();
        Object.defineProperty(this, 'uri', {value: vendor + '/' + name + '/' + version});

        if (!('display_name' in desc) || desc.display_name.trim() === '') {
            display_name = name;
        } else {
            display_name = desc.display_name;
        }
        Object.defineProperty(this, 'display_name', {value: display_name});

        description = desc.description;
        if (description == null || description.trim() === '') {
            description = '';
        }
        Object.defineProperty(this, 'description', {value: description});

        prefList = desc.preferences;
        if (!Array.isArray(prefList)) {
            prefList = [];
        }
        prefs = {};
        for (i = 0; i < prefList.length; i += 1) {
            pref = prefList[i] = new Wirecloud.wiring.OperatorUserPref(prefList[i]);
            prefs[pref.name] = pref;
        }
        Object.defineProperty(this, 'preferences', {value: prefs});
        Object.defineProperty(this, 'preferenceList', {value: prefList});

        inputs = desc.wiring.inputs;
        if (inputs == null) {
            inputs = {};
        }
        Object.defineProperty(this, 'inputs', {value: inputs});

        outputs = desc.wiring.outputs;
        if (outputs == null) {
            outputs = {};
        }
        Object.defineProperty(this, 'outputs', {value: outputs});

        if (inputs.length === 0 && outputs.length === 0) {
            throw new TypeError();
        }
    };

    OperatorMeta.prototype.instantiate = function instantiate(id, operator_status /*TODO*/, wiringEditor) {
        return new Wirecloud.Operator(this, id, operator_status /* TODO */, wiringEditor);
    };

    Wirecloud.wiring.OperatorMeta = OperatorMeta;
})();
<commit_msg>Remove baseless verification<commit_after>/*
 *     (C) Copyright 2012-2013 Universidad Politécnica de Madrid
 *
 *     This file is part of Wirecloud Platform.
 *
 *     Wirecloud Platform is free software: you can redistribute it and/or
 *     modify it under the terms of the GNU Affero General Public License as
 *     published by the Free Software Foundation, either version 3 of the
 *     License, or (at your option) any later version.
 *
 *     Wirecloud is distributed in the hope that it will be useful, but WITHOUT
 *     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 *     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public
 *     License for more details.
 *
 *     You should have received a copy of the GNU Affero General Public License
 *     along with Wirecloud Platform.  If not, see
 *     <http://www.gnu.org/licenses/>.
 *
 */

/*globals gettext, Wirecloud*/

(function () {

    "use strict";

    var OperatorMeta = function OperatorMeta(desc) {
        var vendor, name, version, uri, display_name, description, inputs,
            outputs, prefList, prefs, pref, i;

        // Vendor
        if (!('vendor' in desc) || desc.vendor.trim() === '') {
            throw new TypeError(gettext('missing operator vendor'));
        }
        vendor = desc.vendor.trim();
        Object.defineProperty(this, 'vendor', {value: vendor});

        // Name
        if (!('name' in desc) || desc.name.trim() === '') {
            throw new TypeError(gettext('missing operator name'));
        }
        name = desc.name.trim();
        Object.defineProperty(this, 'name', {value: name});

        // Version
        if (!('version' in desc) || desc.version.trim() === '') {
            throw new TypeError(gettext('missing operator version'));
        }
        version = desc.version.trim();
        Object.defineProperty(this, 'version', {value: version});

        // URI
        uri = desc.name.trim();
        Object.defineProperty(this, 'uri', {value: vendor + '/' + name + '/' + version});

        if (!('display_name' in desc) || desc.display_name.trim() === '') {
            display_name = name;
        } else {
            display_name = desc.display_name;
        }
        Object.defineProperty(this, 'display_name', {value: display_name});

        description = desc.description;
        if (description == null || description.trim() === '') {
            description = '';
        }
        Object.defineProperty(this, 'description', {value: description});

        prefList = desc.preferences;
        if (!Array.isArray(prefList)) {
            prefList = [];
        }
        prefs = {};
        for (i = 0; i < prefList.length; i += 1) {
            pref = prefList[i] = new Wirecloud.wiring.OperatorUserPref(prefList[i]);
            prefs[pref.name] = pref;
        }
        Object.defineProperty(this, 'preferences', {value: prefs});
        Object.defineProperty(this, 'preferenceList', {value: prefList});

        inputs = desc.wiring.inputs;
        if (inputs == null) {
            inputs = {};
        }
        Object.defineProperty(this, 'inputs', {value: inputs});

        outputs = desc.wiring.outputs;
        if (outputs == null) {
            outputs = {};
        }
        Object.defineProperty(this, 'outputs', {value: outputs});
    };

    OperatorMeta.prototype.instantiate = function instantiate(id, operator_status /*TODO*/, wiringEditor) {
        return new Wirecloud.Operator(this, id, operator_status /* TODO */, wiringEditor);
    };

    Wirecloud.wiring.OperatorMeta = OperatorMeta;
})();
<|endoftext|>


<commit_before>import React, {useEffect, useLayoutEffect, useRef, useState} from 'react';
import { StateNavigator } from 'navigation';
import { NavigationHandler } from 'navigation-react';
import { NavigationStack } from 'navigation-react-native';

const Stack = ({ children, ...props }) => {
  const stateNavigatorRef = useRef(new StateNavigator([]))
  const stateNavigator = stateNavigatorRef.current;
  const [states, setStates] = useState([]);
  useEffect(() => {
    setStates(oldStates => {
      const { newStates, newStatesLookup } = React.Children.toArray(children)
        .reduce(({ newStates, newStatesLookup }, { props: { name, ...rest }}) => {
          newStates.push({ key: name, ...rest })
          newStatesLookup[name] = true;
          return { newStates, newStatesLookup };
        }, { newStates: [], newStatesLookup: {} })
      for(const oldState of oldStates) {
        if (!newStatesLookup[oldState.key])
          newStates.push({ ...oldState, __deleted: true });
      }
      return newStates;
    });
  }, [ children ]);
  useLayoutEffect(() => {
    const { state, url } = stateNavigator.stateContext;
    stateNavigator.configure(states);
    let changed = !state;
    if (!changed) {
      const { state, crumbs } = stateNavigator.parseLink(url);
      changed = state.__deleted || crumbs.filter(({ state }) => state.__deleted).length;
    }
    if (changed && states.length)
      stateNavigator.navigate(states[0].key);
    const validateNavigation = ({ __deleted }) => !__deleted;
    stateNavigator.onBeforeNavigate(validateNavigation);
    return () => stateNavigator.offBeforeNavigate(validateNavigation);
  }, [ states ]);
  return !!states.length && (
    <NavigationHandler stateNavigator={stateNavigator}>
      <NavigationStack {...props} />
    </NavigationHandler>
  )
}

Stack.Scene = () => null;

export default Stack;
<commit_msg>Commented the component api effects<commit_after>import React, {useEffect, useLayoutEffect, useRef, useState} from 'react';
import { StateNavigator } from 'navigation';
import { NavigationHandler } from 'navigation-react';
import { NavigationStack } from 'navigation-react-native';

const Stack = ({ children, ...props }) => {
  const stateNavigatorRef = useRef(new StateNavigator([]))
  const stateNavigator = stateNavigatorRef.current;
  const [states, setStates] = useState([]);
  useEffect(() => {
    /**
     * Builds the new states from the children. Keeps the old states
     * but marks them as deleted (they're needed to parse old urls)
     */
    setStates(oldStates => {
      const { newStates, newStatesLookup } = React.Children.toArray(children)
        .reduce(({ newStates, newStatesLookup }, { props: { name, ...rest }}) => {
          newStates.push({ key: name, ...rest })
          newStatesLookup[name] = true;
          return { newStates, newStatesLookup };
        }, { newStates: [], newStatesLookup: {} })
      for(const oldState of oldStates) {
        if (!newStatesLookup[oldState.key])
          newStates.push({ ...oldState, __deleted: true });
      }
      return newStates;
    });
  }, [ children ]);
  useLayoutEffect(() => {
    /**
     * If the current stack contains any deleted scenes then navigates
     * to the first scene in the new stack. Prevents future navigation
     * to deleted scenes
     */
    const { state, url } = stateNavigator.stateContext;
    stateNavigator.configure(states);
    let changed = !state;
    if (!changed) {
      const { state, crumbs } = stateNavigator.parseLink(url);
      changed = state.__deleted || crumbs.filter(({ state }) => state.__deleted).length;
    }
    if (changed && states.length)
      stateNavigator.navigate(states[0].key);
    const validateNavigation = ({ __deleted }) => !__deleted;
    stateNavigator.onBeforeNavigate(validateNavigation);
    return () => stateNavigator.offBeforeNavigate(validateNavigation);
  }, [ states ]);
  return !!states.length && (
    <NavigationHandler stateNavigator={stateNavigator}>
      <NavigationStack {...props} />
    </NavigationHandler>
  )
}

Stack.Scene = () => null;

export default Stack;
<|endoftext|>


<commit_before>import React from 'react';
import { render } from 'react-native';

render(
Hello World
, document.getElementById('content'))<commit_msg>Added NavigationMotion to index<commit_after>import React from 'react';
import {render} from 'react-native';
import {NavigationHandler} from 'navigation-react';
import {NavigationMotion} from 'navigation-react-mobile';
import createStateNavigator from './createStateNavigator';

const stateNavigator = createStateNavigator();

stateNavigator.start();

render(
  <NavigationHandler stateNavigator={stateNavigator}>
    <NavigationMotion
        unmountedStyle={{opacity: 0}}
        mountedStyle={{opacity: 1}}
        crumbStyle={{opacity: 0}}>
        {({opacity}, scene, key) => (

            {scene}

        )}
    </NavigationMotion>
  </NavigationHandler>,
  document.getElementById('content')
)
<|endoftext|>


<commit_before>var sendMessage = require('./fbMessage/sendMessage');
var fbMessage = require('./fbMessage/fbMessage');

var debugMode = require('./config/debugMode');

var _ = require('underscore');

module.exports = function (config) {

	var senderId = config.senderId;
    var commands = config.command.split(' ');

    switch (commands[0]) {
        case 'weather':

            var location = _.rest(commands).join(' ');

            var textReply = new fbMessage
                .PlainText("Laicins " + commands + " ir jauks https://www.youtube.com/watch?v=PFjQd-sl_sU")
                .compose();

            sendMessage(senderId, textReply);

        break;

    }

};<commit_msg>command not found<commit_after>var sendMessage = require('./fbMessage/sendMessage');
var fbMessage = require('./fbMessage/fbMessage');

var debugMode = require('./config/debugMode');

var _ = require('underscore');

module.exports = function (config) {

	var senderId = config.senderId;
    var commands = config.command.split(' ');

    switch (commands[0]) {
        case 'weather':

            var location = _.rest(commands, 1).join(' ');

            var textReply = new fbMessage
                .PlainText("Laicins " + commands + " ir jauks")
                .compose();

            sendMessage(senderId, textReply);

        break;
        default:

            var textReply = new fbMessage
                .PlainText("Command '" + commands[0] + "' not found!")
                .compose();

            sendMessage(senderId, textReply);

    }

};<|endoftext|>


<commit_before>
require("requirish")._(module);

var should = require("should");
var assert = require("better-assert");
var async = require("async");
var _ = require("underscore");
var util = require("util");

var opcua = require("../../index");
var OPCUAClient = opcua.OPCUAClient;
var StatusCodes = opcua.StatusCodes;
var Variant = opcua.Variant;
var DataType = opcua.DataType;
var browse_service = opcua.browse_service;
var NodeCrawler = opcua.NodeCrawler;

var debugLog  = require("lib/misc/utils").make_debugLog(__filename);

var build_server_with_temperature_device = require("test/helpers/build_server_with_temperature_device").build_server_with_temperature_device;
var perform_operation_on_client_session = require("test/helpers/perform_operation_on_client_session").perform_operation_on_client_session;

var makeNodeId = opcua.makeNodeId;

var AttributeIds = opcua.AttributeIds;
var OPCUAClient = opcua.OPCUAClient;

var address_space_for_conformance_testing  = require("lib/simulation/address_space_for_conformance_testing");
var build_address_space_for_conformance_testing = address_space_for_conformance_testing.build_address_space_for_conformance_testing;

describe("NodeCrawler after write",function(){

    var namespaceIndex = 411;
    var port = 2555;

    // this test could be particularly slow on RapsberryPi or BeagleBoneBlack
    // so we set a big enough timeout
    this.timeout((process.arch === 'arm') ? 400000 : 100000);

    var server , client,temperatureVariableId,endpointUrl ;

    before(function(done){
        // we use a different port for each tests to make sure that there is
        // no left over in the tcp pipe that could generate an error
        //port+=1;
        server = build_server_with_temperature_device({ port:port},function(err) {

            build_address_space_for_conformance_testing(server.engine, {mass_variables: false});

            endpointUrl = server.endpoints[0].endpointDescriptions()[0].endpointUrl;
            temperatureVariableId = server.temperatureVariableId;
            done(err);
        });
    });

    beforeEach(function(done){
        client = new OPCUAClient();
        done();
    });

    afterEach(function(done){
        client = null;
        done();
    });

    after(function(done){
        server.shutdown(done);
    });

    it("should crawl, write to node, and crawl again", function(done) {

        perform_operation_on_client_session(client, endpointUrl, function (session, session_done) {

            async.series([
                function(inner_done) {
                    console.log('Starting first');
                    var crawler = new NodeCrawler(session);

                    var nodeId = "RootFolder";

                    crawler.read(nodeId, function (err, obj) {
                        console.log('first', err);

                        if (!err) {
                            console.log('read success');
                            obj.browseName.toString().should.equal("Root");
                            obj.organizes.length.should.equal(3);
                            obj.organizes[0].browseName.toString().should.eql("Objects");
                            obj.organizes[1].browseName.toString().should.eql("Types");
                            obj.organizes[2].browseName.toString().should.eql("Views");
                            obj.typeDefinition.should.eql("FolderType");
                        }
                        inner_done(err);
                    });
                },

                function(inner_done) {
                    console.log('starting second');

                    var nodeId = opcua.coerceNodeId(2294);
                    console.log(nodeId);

                    var nodeToWrite =
                        {
                            dataType: DataType.Boolean,
                            value: true
                        };

                    session.writeSingleNode(nodeId, nodeToWrite,function(err, results){

                        console.log('res', results);

                        if (err) {
                            return inner_done(err);
                        }

                        results.should.eql(opcua.StatusCodes.Good);

                        inner_done();
                    });
                },

                function(inner_done) {
                    console.log('Starting third');
                    var crawler = new NodeCrawler(session);

                    var nodeId = "RootFolder";

                    crawler.read(nodeId, function (err, obj) {
                        console.log('second', err);
                        if (!err) {
                            console.log('read success');
                            obj.browseName.toString().should.equal("Root");
                            obj.organizes.length.should.equal(3);
                            obj.organizes[0].browseName.toString().should.eql("Objects");
                            obj.organizes[1].browseName.toString().should.eql("Types");
                            obj.organizes[2].browseName.toString().should.eql("Views");
                            obj.typeDefinition.should.eql("FolderType");
                        }
                        inner_done(err);
                    });
                }
            ], session_done);

        }, done);
    });

});
<commit_msg>adjust timeout for test on slow vm<commit_after>
require("requirish")._(module);

var should = require("should");
var assert = require("better-assert");
var async = require("async");
var _ = require("underscore");
var util = require("util");

var opcua = require("../../index");
var OPCUAClient = opcua.OPCUAClient;
var StatusCodes = opcua.StatusCodes;
var Variant = opcua.Variant;
var DataType = opcua.DataType;
var browse_service = opcua.browse_service;
var NodeCrawler = opcua.NodeCrawler;

var debugLog  = require("lib/misc/utils").make_debugLog(__filename);

var build_server_with_temperature_device = require("test/helpers/build_server_with_temperature_device").build_server_with_temperature_device;
var perform_operation_on_client_session = require("test/helpers/perform_operation_on_client_session").perform_operation_on_client_session;

var makeNodeId = opcua.makeNodeId;

var AttributeIds = opcua.AttributeIds;
var OPCUAClient = opcua.OPCUAClient;

var address_space_for_conformance_testing  = require("lib/simulation/address_space_for_conformance_testing");
var build_address_space_for_conformance_testing = address_space_for_conformance_testing.build_address_space_for_conformance_testing;

describe("NodeCrawler after write",function(){

    var namespaceIndex = 411;
    var port = 2555;

    // this test could be particularly slow on RapsberryPi or BeagleBoneBlack
    // so we set a big enough timeout
    this.timeout((process.arch === 'arm') ? 800000 : 200000);

    var server , client,temperatureVariableId,endpointUrl ;

    before(function(done){
        // we use a different port for each tests to make sure that there is
        // no left over in the tcp pipe that could generate an error
        //port+=1;
        server = build_server_with_temperature_device({ port:port},function(err) {

            build_address_space_for_conformance_testing(server.engine, {mass_variables: false});

            endpointUrl = server.endpoints[0].endpointDescriptions()[0].endpointUrl;
            temperatureVariableId = server.temperatureVariableId;
            done(err);
        });
    });

    beforeEach(function(done){
        client = new OPCUAClient({
            requestedSessionTimeout: 60*1000*4 // 4 minutes
        });
        done();
    });

    afterEach(function(done){
        client = null;
        done();
    });

    after(function(done){
        server.shutdown(done);
    });

    it("should crawl, write to node, and crawl again", function(done) {

        perform_operation_on_client_session(client, endpointUrl, function (session, session_done) {

            async.series([
                function(inner_done) {
                    console.log('Starting first');
                    var crawler = new NodeCrawler(session);

                    var nodeId = "RootFolder";

                    crawler.read(nodeId, function (err, obj) {
                        console.log('first', err);

                        if (!err) {
                            console.log('read success');
                            obj.browseName.toString().should.equal("Root");
                            obj.organizes.length.should.equal(3);
                            obj.organizes[0].browseName.toString().should.eql("Objects");
                            obj.organizes[1].browseName.toString().should.eql("Types");
                            obj.organizes[2].browseName.toString().should.eql("Views");
                            obj.typeDefinition.should.eql("FolderType");
                        }
                        inner_done(err);
                    });
                },

                function(inner_done) {
                    console.log('starting second');

                    var nodeId = opcua.coerceNodeId(2294);
                    console.log(nodeId);

                    var nodeToWrite =
                        {
                            dataType: DataType.Boolean,
                            value: true
                        };

                    session.writeSingleNode(nodeId, nodeToWrite,function(err, results){

                        console.log('res', results);

                        if (err) {
                            return inner_done(err);
                        }

                        results.should.eql(opcua.StatusCodes.Good);

                        inner_done();
                    });
                },

                function(inner_done) {
                    console.log('Starting third');
                    var crawler = new NodeCrawler(session);

                    var nodeId = "RootFolder";

                    crawler.read(nodeId, function (err, obj) {
                        console.log('second', err);
                        if (!err) {
                            console.log('read success');
                            obj.browseName.toString().should.equal("Root");
                            obj.organizes.length.should.equal(3);
                            obj.organizes[0].browseName.toString().should.eql("Objects");
                            obj.organizes[1].browseName.toString().should.eql("Types");
                            obj.organizes[2].browseName.toString().should.eql("Views");
                            obj.typeDefinition.should.eql("FolderType");
                        }
                        inner_done(err);
                    });
                }
            ], session_done);

        }, done);
    });

});
<|endoftext|>


<commit_before>//var map = L.map('map');

//ピンを追加 childrencafeteria:cc
var cc1 = L.marker([34.392487, 132.475126]).bindPopup('青い鳥'),
    cc2 = L.marker([34.361050, 132.463745]).bindPopup('くるり食堂');

var childrencafeteria = L.layerGroup([
    cc1, cc2
]);

var pale = L.tileLayer('http://cyberjapandata.gsi.go.jp/xyz/pale/{z}/{x}/{y}.png',
{id: 'palemap', attribution: "国土地理院"}),
    blank = L.tileLayer('http://cyberjapandata.gsi.go.jp/xyz/blank/{z}/{x}/{y}.png',
{id: 'blankmap', attribution: "国土地理院"}),
    osm = L.tileLayer('http://tile.openstreetmap.jp/{z}/{x}/{y}.png',
{ id: 'osmmap', attribution: '© OpenStreetMap contributors' });

var map = L.map('map', {
    layers: [pale, childrencafeteria]
});

var baseMaps = {
    "淡色地図" : pale,
    "白地図"   : blank,
    "OSM japan"  : osm
};

var overlayMaps = {
    "こども食堂" : childrencafeteria
};

L.control.layers(baseMaps, overlayMaps).addTo(map);

map.setView([34.393073, 132.452091], 16);<commit_msg>地図のデフォルト点とzoom値を変更<commit_after>//var map = L.map('map');

//ピンを追加 childrencafeteria:cc
var cc1 = L.marker([34.392487, 132.475126]).bindPopup('青い鳥'),
    cc2 = L.marker([34.361050, 132.463745]).bindPopup('くるり食堂');

var childrencafeteria = L.layerGroup([
    cc1, cc2
]);

var pale = L.tileLayer('http://cyberjapandata.gsi.go.jp/xyz/pale/{z}/{x}/{y}.png',
{id: 'palemap', attribution: "国土地理院"}),
    blank = L.tileLayer('http://cyberjapandata.gsi.go.jp/xyz/blank/{z}/{x}/{y}.png',
{id: 'blankmap', attribution: "国土地理院"}),
    osm = L.tileLayer('http://tile.openstreetmap.jp/{z}/{x}/{y}.png',
{ id: 'osmmap', attribution: '© OpenStreetMap contributors' });

var map = L.map('map', {
    layers: [pale, childrencafeteria]
});

var baseMaps = {
    "淡色地図" : pale,
    "白地図"   : blank,
    "OSM japan"  : osm
};

var overlayMaps = {
    "こども食堂" : childrencafeteria
};

L.control.layers(baseMaps, overlayMaps).addTo(map);

map.setView([34.395247, 132.457659], 18);<|endoftext|>


<commit_before>var FieldType = require('../Type');
var TextType = require('../text/TextType');
var util = require('util');
var utils = require('keystone-utils');

/**
 * Text FieldType Constructor
 * @extends Field
 * @api public
 */
function textarea (list, path, options) {
	this._nativeType = String;
	this._underscoreMethods = ['format', 'crop'];
	this.height = options.height || 90;
	this._properties = ['height'];
	textarea.super_.call(this, list, path, options);
}
util.inherits(textarea, FieldType);

textarea.prototype.validateInput = TextType.prototype.validateInput;
textarea.prototype.validateRequiredInput = TextType.prototype.validateRequiredInput;

/* Inherit from TextType prototype */
textarea.prototype.addFilterToQuery = TextType.prototype.addFilterToQuery;
textarea.prototype.crop = TextType.prototype.crop;

/**
 * Formats the field value
 * @api public
 */
textarea.prototype.format = function (item) {
	return utils.textToHTML(item.get(this.path));
};

/* Export Field Type */
module.exports = textarea;
<commit_msg>Fix in readonly<commit_after>var FieldType = require('../Type');
var TextType = require('../text/TextType');
var util = require('util');
var utils = require('keystone-utils');

/**
 * Text FieldType Constructor
 * @extends Field
 * @api public
 */
function textarea (list, path, options) {
	this._nativeType = String;
	this._underscoreMethods = ['format', 'crop'];
	this.height = options.height || 90;
	this.multiline = true;
	this._properties = ['height','multiline'];
	textarea.super_.call(this, list, path, options);
}
util.inherits(textarea, FieldType);

textarea.prototype.validateInput = TextType.prototype.validateInput;
textarea.prototype.validateRequiredInput = TextType.prototype.validateRequiredInput;

/* Inherit from TextType prototype */
textarea.prototype.addFilterToQuery = TextType.prototype.addFilterToQuery;
textarea.prototype.crop = TextType.prototype.crop;

/**
 * Formats the field value
 * @api public
 */
textarea.prototype.format = function (item) {
	return utils.textToHTML(item.get(this.path));
};

/* Export Field Type */
module.exports = textarea;
<|endoftext|>


<commit_before>// ==========================================================================
// Project:   SproutCore - JavaScript Application Framework
// Copyright: ©2006-2009 Sprout Systems, Inc. and contributors.
//            Portions ©2008-2009 Apple Inc. All rights reserved.
// License:   Licened under MIT license (see license.js)
// ==========================================================================
sc_require('views/button') ;
sc_require('views/separator') ;

/**
  @class

  An SC.MenuItemView is created for every item in a menu.

  @extends SC.ButtonView
  @since SproutCore 1.0
*/
SC.MenuItemView = SC.View.extend( SC.ContentDisplay,
/** @scope SC.MenuItemView.prototype */{

  classNames: ['sc-menu-item'],

  /**
    @private
    @property
    @type {Boolean}
  */
  acceptsFirstResponder: YES,

  // ..........................................................
  // KEY PROPERTIES
  //
  /**
    The content object the menu view will display.

    @type Object
  */
  content: null,

  /**
    This returns true if the child view is a menu list view.
    This property can be over written to have other child views as well.

    @type Boolean
  */
  isSubMenuViewVisible: null,

  /**
    This property specifies whether this menu item is currently in focus

    @type Boolean
  */
  hasMouseExited: NO,

  /**
    Because we don't know what keys to observe for display changes
    until we're instantiated, we explicitly set contentDisplayProperties
    on init.

    @private
  */
  init: function() {
    var menu = this.getPath('parentMenu.rootMenu'),
    keyArray = menu.menuItemKeys.map(SC._menu_fetchKeys, menu);

    this.set('contentDisplayProperties', keyArray);
    return sc_super();
  },

  /**
    This menu item's submenu, if it exists.

    @type SC.MenuView
  */
  subMenu: function() {
    var content = this.get('content'), menuItems, parentMenu;

    if (!content) return null;

    parentMenu = this.get('parentMenu');
    menuItems = content.get(parentMenu.itemSubMenuKey );
    if (menuItems) {
      if (SC.kindOf(menuItems, SC.MenuPane)) {
        menuItems.set('isModal', NO);
        menuItems.set('isSubMenu', YES);
        menuItems.set('parentMenu', parentMenu);
        return menuItems;
      } else {
        return SC.MenuPane.create({
          layout: { width: 200 },
          items: menuItems,
          isModal: NO,
          isSubMenu: YES,
          parentMenu: parentMenu
        });
      }
    }

    return null;
  }.property('content').cacheable(),

  /**
    Whether or not this menu item has a submenu.

    @type Boolean
  */
  hasSubMenu: function() {
    return !!this.get('subMenu');
  }.property('subMenu').cacheable(),

  /**
    Fills the passed html-array with strings that can be joined to form the
    innerHTML of the receiver element.  Also populates an array of classNames
    to set on the outer element.

    @param {SC.RenderContext} context
    @param {Boolean} firstTime
    @returns {void}
  */
  render: function(context, firstTime) {
    var content = this.get('content') ;
    var key, val ;
    var menu = this.get('parentMenu');
    var itemWidth = this.get('itemWidth') || menu.layout.width ;
    var itemHeight = this.get('itemHeight') || 20 ;
    this.set('itemWidth',itemWidth);
    this.set('itemHeight',itemHeight);

    context = context.begin('a');

    if (content.get(menu.itemSeparatorKey)) {
      context.push('');
      context.addClass('disabled');
    } else {
      val = content.get(menu.itemIconKey);
      if (val) {
        this.renderImage(context, val);
        context.addClass('has-icon');
      }

      val = this.getContentProperty('itemTitleKey') || '';
      if (SC.typeOf(val) !== SC.T_STRING) val = val.toString();
      // TODO check localization setting
      this.renderLabel(context, val.loc());

      if (this.getContentProperty('itemCheckboxKey')) {
        context.push('

');
      }

      if (this.get('hasSubMenu')) {
        this.renderBranch(context);
      }

      val = this.getContentProperty('itemShortCutKey');
      if (val) {
        this.renderShortcut(context, val);
      }
    }

    context = context.end();
  },

  /**
   Generates the image used to represent the image icon. override this to
   return your own custom HTML

   @param {SC.RenderContext} context the render context
   @param {String} the source path of the image
   @returns {void}
  */
  renderImage: function(context, image) {
    // get a class name and url to include if relevant

    var url, className ;
    if (image && SC.ImageView.valueIsUrl(image)) {
      url = image ;
      className = '' ;
    } else {
      className = image ;
      url = SC.BLANK_IMAGE_URL;
    }
    // generate the img element...
    context.begin('img').addClass('image').addClass(className).attr('src', url).end() ;
  },

  /**
   Generates the label used to represent the menu item. override this to
   return your own custom HTML

   @param {SC.RenderContext} context the render context
   @param {String} menu item name
   @returns {void}
  */

  renderLabel: function(context, label) {
    if (this.get('escapeHTML')) {
      label = SC.RenderContext.escapeHTML(label) ;
    }
    context.push(""+label+"") ;
  },

  /**
   Generates the string used to represent the branch arrow. override this to
   return your own custom HTML

   @param {SC.RenderContext} context the render context
   @returns {void}
  */

  renderBranch: function(context) {
    context.push('') ;
  },

  /**
   Generates the string used to represent the short cut keys. override this to
   return your own custom HTML

   @param {SC.RenderContext} context the render context
   @param {String} the shortcut key string to be displayed with menu item name
   @returns {void}
  */
  renderShortcut: function(context, shortcut) {
    context.push('' + shortcut + '') ;
  },

  /**
    This method checks if the menu item is a separator.

    @param {}
    @returns Boolean
  */
  isSeparator: function() {
    return this.getContentProperty('itemSeparatorKey') === YES;
  }.property('content').cacheable(),

  /**
    This method will check whether the current Menu Item is still
    selected and then create a submenu accordignly.

    @param {}
    @returns void
  */
  showSubMenu: function() {
    var subMenu = this.get('subMenu') ;
    if(subMenu) {
      subMenu.popup(this,[0,0,0]) ;
    }
  },

  isEnabled: function() {
    return this.getContentProperty('itemIsEnabledKey') !== NO &&
           this.getContentProperty('itemSeparatorKey') !== YES;
  }.property('content.isEnabled').cacheable(),

  title: function() {
    var ret = this.getContentProperty('itemTitleKey');

    if (ret) {
      ret = ret.loc();
    }
    return ret;
  }.property('content.title').cacheable(),

  getContentProperty: function(property) {
    var content = this.get('content'),
        menu = this.get('parentMenu');

    if (content) {
      return content.get(menu.get(property));
    }
  },

  //..........................................
  //Mouse Events Handling
  //..........................................

  mouseUp: function(evt) {
    // SproutCore's event system will deliver the mouseUp event to the view
    // that got the mouseDown event, but for menus we want to track the mouse,
    // so we'll do our own dispatching.
    var targetMenuItem;

    targetMenuItem = this.getPath('parentMenu.rootMenu.targetMenuItem');

    if (targetMenuItem) targetMenuItem.performAction();
    return YES ;
  },

  performAction: function() {
    if(!this.get('isEnabled')) return ;
    var action = this.getContentProperty('itemActionKey'),
        target = this.getContentProperty('itemTargetKey'),
        disableFlash  = this.getContentProperty('itemDisableMenuFlashKey'),
        rootMenu = this.getPath('parentMenu.rootMenu'), responder;

    if (this.get('hasSubMenu')) {
      return;
    }

    action = (action === undefined) ? rootMenu.get('action') : action;
    target = (target === undefined) ? rootMenu.get('target') : target;

    this._flashCounter = 0;
    rootMenu.set('selectedItem', this.get('content'));

    // Legacy support for actions that are functions
    if (SC.typeOf(action) === SC.T_FUNCTION) {
      action.apply(target, [rootMenu]);
      SC.Logger.warn('Support for menu item action functions has been deprecated. Please use target and action.');
    } else {
      responder = this.getPath('pane.rootResponder') || SC.RootResponder.responder;
      if (!responder) return;

      if (!disableFlash) {
        // Start the menu flash, then invoke the action in 200ms
        responder.invokeLater(responder.sendAction, 200, action, target, this, this.get('pane'));
        this.invokeLater(this.flashHighlight, 25);
      } else {
        // Menu flash is disabled for this menu item, so fire the action immediately
        responder.sendAction(action, target, this, this.get('pane'));
        this.getPath('parentMenu.rootMenu').remove();
      }
    }
  },

  flashHighlight: function() {
    var flashCounter = this._flashCounter, layer = this.$();
    if (flashCounter % 2 === 0) {
      layer.addClass('focus');
    } else {
      layer.removeClass('focus');
    }

    if (flashCounter > 2) {
      this.getPath('parentMenu.rootMenu').remove();
    } else {
      this.invokeLater(this.flashHighlight, 50);
      this._flashCounter++;
    }
  },

  /** @private*/
  mouseDown: function(evt) {
    return YES ;
  },

  /** @private
    This has been over ridden from button view to prevent calling of render
    method (When isActive property is changed).
    Also based on whether the menu item has a sub Branch we create a sub Menu

    @returns Boolean
  */
  mouseEntered: function(evt) {
    var menu = this.get('parentMenu');
    menu.set('mouseHasEntered', YES);
    menu.set('currentMenuItem', this);

    if(this.get('hasSubMenu')) {
      this.invokeLater(this.showSubMenu(),100) ;
    }
	  return YES ;
  },

  /** @private
    Set the focus based on whether the current Menu item is selected or not.

    @returns Boolean
  */
  mouseExited: function(evt) {
    var subMenu, parentMenu;

    if (this.get('hasSubMenu')) {
      subMenu = this.get('subMenu');
      this.invokeLater(this.checkMouseLocation, 200);
    } else {
      parentMenu = this.get('parentMenu');

      if (parentMenu.get('currentMenuItem') === this) {
        parentMenu.set('currentMenuItem', null);
      }
    }

    return YES ;
  },

  checkMouseLocation: function() {
    var subMenu = this.get('subMenu'), parentMenu = this.get('parentMenu'),
        currentMenuItem, previousMenuItem;
    if (!subMenu.get('mouseHasEntered')) {
      currentMenuItem = parentMenu.get('currentMenuItem');
      if (currentMenuItem === this || currentMenuItem === null) {
        previousMenuItem = parentMenu.get('previousMenuItem');

        if (previousMenuItem) {
          previousMenuItem.resignFirstResponder();
        }
        subMenu.remove();
      }
    }
  },

  /** @private
    Call the moveUp function on the parent Menu

    @returns Boolean
  */
  moveUp: function(sender,evt) {
    var menu = this.get('parentMenu') ;
    if(menu) {
      menu.moveUp(this) ;
    }
    return YES ;
  },

  /** @private
    Call the moveDown function on the parent Menu

    @returns Boolean
  */
  moveDown: function(sender,evt) {
    var menu = this.get('parentMenu') ;
    if(menu) {
      menu.moveDown(this) ;
    }
    return YES ;
  },

  /** @private
    Call the function to create a branch

    @returns Boolean
  */
  moveRight: function(sender,evt) {
    this.showSubMenu() ;
    return YES;
  },

  /** @private*/
  keyDown: function(evt) {
    return this.interpretKeyEvents(evt) ;
  },

  /** @private*/
  keyUp: function(evt) {
    return YES ;
  },

  /** @private*/
  cancel: function(evt) {
    this.loseFocus() ;
    var menu = this.get('parentMenu') ;
    if (menu) menu.remove() ;
    var pane = menu.getPath('anchor.pane') ;
    if (pane) pane.becomeKeyPane() ;
    return YES ;
  },

  /** @private*/
  didBecomeFirstResponder: function(responder) {
    if (responder !== this) return;
    var parentMenu = this.get('parentMenu') ;
    if(parentMenu) {
      parentMenu.set('currentSelectedMenuItem', this) ;
    }
  },

  /** @private*/
  willLoseFirstResponder: function(responder) {
    if (responder !== this) return;
    var parentMenu = this.get('parentMenu') ;
    if(parentMenu) {
      parentMenu.set('currentSelectedMenuItem', null) ;
      parentMenu.set('previousSelectedMenuItem', this) ;
    }
  },

  /** @private*/
  insertNewline: function(sender, evt) {
    this.mouseUp(evt) ;
  },

  /**
    Close the parent Menu and remove the focus of the current Selected
    Menu Item

    @returns void
  */
  closeParent: function() {
    this.$().removeClass('focus') ;
    var menu = this.get('parentMenu') ;
    if(menu) {
      menu.remove() ;
    }
  },

  /** @private*/
  clickInside: function(frame, evt) {
    return SC.pointInRect({ x: evt.pageX, y: evt.pageY }, frame) ;
  }

}) ;
<commit_msg>Properly close the menu pane when uesrs press escape.<commit_after>// ==========================================================================
// Project:   SproutCore - JavaScript Application Framework
// Copyright: ©2006-2009 Sprout Systems, Inc. and contributors.
//            Portions ©2008-2009 Apple Inc. All rights reserved.
// License:   Licened under MIT license (see license.js)
// ==========================================================================
sc_require('views/button') ;
sc_require('views/separator') ;

/**
  @class

  An SC.MenuItemView is created for every item in a menu.

  @extends SC.ButtonView
  @since SproutCore 1.0
*/
SC.MenuItemView = SC.View.extend( SC.ContentDisplay,
/** @scope SC.MenuItemView.prototype */{

  classNames: ['sc-menu-item'],

  /**
    @private
    @property
    @type {Boolean}
  */
  acceptsFirstResponder: YES,

  // ..........................................................
  // KEY PROPERTIES
  //
  /**
    The content object the menu view will display.

    @type Object
  */
  content: null,

  /**
    This returns true if the child view is a menu list view.
    This property can be over written to have other child views as well.

    @type Boolean
  */
  isSubMenuViewVisible: null,

  /**
    This property specifies whether this menu item is currently in focus

    @type Boolean
  */
  hasMouseExited: NO,

  /**
    Because we don't know what keys to observe for display changes
    until we're instantiated, we explicitly set contentDisplayProperties
    on init.

    @private
  */
  init: function() {
    var menu = this.getPath('parentMenu.rootMenu'),
    keyArray = menu.menuItemKeys.map(SC._menu_fetchKeys, menu);

    this.set('contentDisplayProperties', keyArray);
    return sc_super();
  },

  /**
    This menu item's submenu, if it exists.

    @type SC.MenuView
  */
  subMenu: function() {
    var content = this.get('content'), menuItems, parentMenu;

    if (!content) return null;

    parentMenu = this.get('parentMenu');
    menuItems = content.get(parentMenu.itemSubMenuKey );
    if (menuItems) {
      if (SC.kindOf(menuItems, SC.MenuPane)) {
        menuItems.set('isModal', NO);
        menuItems.set('isSubMenu', YES);
        menuItems.set('parentMenu', parentMenu);
        return menuItems;
      } else {
        return SC.MenuPane.create({
          layout: { width: 200 },
          items: menuItems,
          isModal: NO,
          isSubMenu: YES,
          parentMenu: parentMenu
        });
      }
    }

    return null;
  }.property('content').cacheable(),

  /**
    Whether or not this menu item has a submenu.

    @type Boolean
  */
  hasSubMenu: function() {
    return !!this.get('subMenu');
  }.property('subMenu').cacheable(),

  /**
    Fills the passed html-array with strings that can be joined to form the
    innerHTML of the receiver element.  Also populates an array of classNames
    to set on the outer element.

    @param {SC.RenderContext} context
    @param {Boolean} firstTime
    @returns {void}
  */
  render: function(context, firstTime) {
    var content = this.get('content') ;
    var key, val ;
    var menu = this.get('parentMenu');
    var itemWidth = this.get('itemWidth') || menu.layout.width ;
    var itemHeight = this.get('itemHeight') || 20 ;
    this.set('itemWidth',itemWidth);
    this.set('itemHeight',itemHeight);

    context = context.begin('a');

    if (content.get(menu.itemSeparatorKey)) {
      context.push('');
      context.addClass('disabled');
    } else {
      val = content.get(menu.itemIconKey);
      if (val) {
        this.renderImage(context, val);
        context.addClass('has-icon');
      }

      val = this.getContentProperty('itemTitleKey') || '';
      if (SC.typeOf(val) !== SC.T_STRING) val = val.toString();
      // TODO check localization setting
      this.renderLabel(context, val.loc());

      if (this.getContentProperty('itemCheckboxKey')) {
        context.push('

');
      }

      if (this.get('hasSubMenu')) {
        this.renderBranch(context);
      }

      val = this.getContentProperty('itemShortCutKey');
      if (val) {
        this.renderShortcut(context, val);
      }
    }

    context = context.end();
  },

  /**
   Generates the image used to represent the image icon. override this to
   return your own custom HTML

   @param {SC.RenderContext} context the render context
   @param {String} the source path of the image
   @returns {void}
  */
  renderImage: function(context, image) {
    // get a class name and url to include if relevant

    var url, className ;
    if (image && SC.ImageView.valueIsUrl(image)) {
      url = image ;
      className = '' ;
    } else {
      className = image ;
      url = SC.BLANK_IMAGE_URL;
    }
    // generate the img element...
    context.begin('img').addClass('image').addClass(className).attr('src', url).end() ;
  },

  /**
   Generates the label used to represent the menu item. override this to
   return your own custom HTML

   @param {SC.RenderContext} context the render context
   @param {String} menu item name
   @returns {void}
  */

  renderLabel: function(context, label) {
    if (this.get('escapeHTML')) {
      label = SC.RenderContext.escapeHTML(label) ;
    }
    context.push(""+label+"") ;
  },

  /**
   Generates the string used to represent the branch arrow. override this to
   return your own custom HTML

   @param {SC.RenderContext} context the render context
   @returns {void}
  */

  renderBranch: function(context) {
    context.push('') ;
  },

  /**
   Generates the string used to represent the short cut keys. override this to
   return your own custom HTML

   @param {SC.RenderContext} context the render context
   @param {String} the shortcut key string to be displayed with menu item name
   @returns {void}
  */
  renderShortcut: function(context, shortcut) {
    context.push('' + shortcut + '') ;
  },

  /**
    This method checks if the menu item is a separator.

    @param {}
    @returns Boolean
  */
  isSeparator: function() {
    return this.getContentProperty('itemSeparatorKey') === YES;
  }.property('content').cacheable(),

  /**
    This method will check whether the current Menu Item is still
    selected and then create a submenu accordignly.

    @param {}
    @returns void
  */
  showSubMenu: function() {
    var subMenu = this.get('subMenu') ;
    if(subMenu) {
      subMenu.popup(this,[0,0,0]) ;
    }
  },

  isEnabled: function() {
    return this.getContentProperty('itemIsEnabledKey') !== NO &&
           this.getContentProperty('itemSeparatorKey') !== YES;
  }.property('content.isEnabled').cacheable(),

  title: function() {
    var ret = this.getContentProperty('itemTitleKey');

    if (ret) {
      ret = ret.loc();
    }
    return ret;
  }.property('content.title').cacheable(),

  getContentProperty: function(property) {
    var content = this.get('content'),
        menu = this.get('parentMenu');

    if (content) {
      return content.get(menu.get(property));
    }
  },

  //..........................................
  //Mouse Events Handling
  //..........................................

  mouseUp: function(evt) {
    // SproutCore's event system will deliver the mouseUp event to the view
    // that got the mouseDown event, but for menus we want to track the mouse,
    // so we'll do our own dispatching.
    var targetMenuItem;

    targetMenuItem = this.getPath('parentMenu.rootMenu.targetMenuItem');

    if (targetMenuItem) targetMenuItem.performAction();
    return YES ;
  },

  performAction: function() {
    if(!this.get('isEnabled')) return ;
    var action = this.getContentProperty('itemActionKey'),
        target = this.getContentProperty('itemTargetKey'),
        disableFlash  = this.getContentProperty('itemDisableMenuFlashKey'),
        rootMenu = this.getPath('parentMenu.rootMenu'), responder;

    if (this.get('hasSubMenu')) {
      return;
    }

    action = (action === undefined) ? rootMenu.get('action') : action;
    target = (target === undefined) ? rootMenu.get('target') : target;

    this._flashCounter = 0;
    rootMenu.set('selectedItem', this.get('content'));

    // Legacy support for actions that are functions
    if (SC.typeOf(action) === SC.T_FUNCTION) {
      action.apply(target, [rootMenu]);
      SC.Logger.warn('Support for menu item action functions has been deprecated. Please use target and action.');
    } else {
      responder = this.getPath('pane.rootResponder') || SC.RootResponder.responder;
      if (!responder) return;

      if (!disableFlash) {
        // Start the menu flash, then invoke the action in 200ms
        responder.invokeLater(responder.sendAction, 200, action, target, this, this.get('pane'));
        this.invokeLater(this.flashHighlight, 25);
      } else {
        // Menu flash is disabled for this menu item, so fire the action immediately
        responder.sendAction(action, target, this, this.get('pane'));
        this.getPath('parentMenu.rootMenu').remove();
      }
    }
  },

  flashHighlight: function() {
    var flashCounter = this._flashCounter, layer = this.$();
    if (flashCounter % 2 === 0) {
      layer.addClass('focus');
    } else {
      layer.removeClass('focus');
    }

    if (flashCounter > 2) {
      this.getPath('parentMenu.rootMenu').remove();
    } else {
      this.invokeLater(this.flashHighlight, 50);
      this._flashCounter++;
    }
  },

  /** @private*/
  mouseDown: function(evt) {
    return YES ;
  },

  /** @private
    This has been over ridden from button view to prevent calling of render
    method (When isActive property is changed).
    Also based on whether the menu item has a sub Branch we create a sub Menu

    @returns Boolean
  */
  mouseEntered: function(evt) {
    var menu = this.get('parentMenu');
    menu.set('mouseHasEntered', YES);
    menu.set('currentMenuItem', this);

    if(this.get('hasSubMenu')) {
      this.invokeLater(this.showSubMenu(),100) ;
    }
	  return YES ;
  },

  /** @private
    Set the focus based on whether the current Menu item is selected or not.

    @returns Boolean
  */
  mouseExited: function(evt) {
    var subMenu, parentMenu;

    if (this.get('hasSubMenu')) {
      subMenu = this.get('subMenu');
      this.invokeLater(this.checkMouseLocation, 200);
    } else {
      parentMenu = this.get('parentMenu');

      if (parentMenu.get('currentMenuItem') === this) {
        parentMenu.set('currentMenuItem', null);
      }
    }

    return YES ;
  },

  checkMouseLocation: function() {
    var subMenu = this.get('subMenu'), parentMenu = this.get('parentMenu'),
        currentMenuItem, previousMenuItem;
    if (!subMenu.get('mouseHasEntered')) {
      currentMenuItem = parentMenu.get('currentMenuItem');
      if (currentMenuItem === this || currentMenuItem === null) {
        previousMenuItem = parentMenu.get('previousMenuItem');

        if (previousMenuItem) {
          previousMenuItem.resignFirstResponder();
        }
        subMenu.remove();
      }
    }
  },

  /** @private
    Call the moveUp function on the parent Menu

    @returns Boolean
  */
  moveUp: function(sender,evt) {
    var menu = this.get('parentMenu') ;
    if(menu) {
      menu.moveUp(this) ;
    }
    return YES ;
  },

  /** @private
    Call the moveDown function on the parent Menu

    @returns Boolean
  */
  moveDown: function(sender,evt) {
    var menu = this.get('parentMenu') ;
    if(menu) {
      menu.moveDown(this) ;
    }
    return YES ;
  },

  /** @private
    Call the function to create a branch

    @returns Boolean
  */
  moveRight: function(sender,evt) {
    this.showSubMenu() ;
    return YES;
  },

  /** @private*/
  keyDown: function(evt) {
    return this.interpretKeyEvents(evt) ;
  },

  /** @private*/
  keyUp: function(evt) {
    return YES ;
  },

  /** @private*/
  cancel: function(evt) {
    this.getPath('parentMenu.rootMenu').remove();
    return YES ;
  },

  /** @private*/
  didBecomeFirstResponder: function(responder) {
    if (responder !== this) return;
    var parentMenu = this.get('parentMenu') ;
    if(parentMenu) {
      parentMenu.set('currentSelectedMenuItem', this) ;
    }
  },

  /** @private*/
  willLoseFirstResponder: function(responder) {
    if (responder !== this) return;
    var parentMenu = this.get('parentMenu') ;
    if(parentMenu) {
      parentMenu.set('currentSelectedMenuItem', null) ;
      parentMenu.set('previousSelectedMenuItem', this) ;
    }
  },

  /** @private*/
  insertNewline: function(sender, evt) {
    this.mouseUp(evt) ;
  },

  /**
    Close the parent Menu and remove the focus of the current Selected
    Menu Item

    @returns void
  */
  closeParent: function() {
    this.$().removeClass('focus') ;
    var menu = this.get('parentMenu') ;
    if(menu) {
      menu.remove() ;
    }
  },

  /** @private*/
  clickInside: function(frame, evt) {
    return SC.pointInRect({ x: evt.pageX, y: evt.pageY }, frame) ;
  }

}) ;
<|endoftext|>