removed mods directory from the ATutor codebase
[atutor.git] / mods / photo_album / fluid / component-templates / js / fluid / Reorderer.js
diff --git a/mods/photo_album/fluid/component-templates/js/fluid/Reorderer.js b/mods/photo_album/fluid/component-templates/js/fluid/Reorderer.js
deleted file mode 100644 (file)
index f5c89a3..0000000
+++ /dev/null
@@ -1,945 +0,0 @@
-/*\r
-Copyright 2007 - 2008 University of Toronto\r
-Copyright 2007 University of Cambridge\r
-\r
-Licensed under the Educational Community License (ECL), Version 2.0 or the New\r
-BSD license. You may not use this file except in compliance with one these\r
-Licenses.\r
-\r
-You may obtain a copy of the ECL 2.0 License and BSD License at\r
-https://source.fluidproject.org/svn/LICENSE.txt\r
-*/\r
-\r
-// Declare dependencies.\r
-var fluid = fluid || {};\r
-\r
-fluid.Reorderer = function (container, params) {\r
-    // Reliable 'this'.\r
-    //\r
-    var thisReorderer = this;\r
-    var theAvatar = null;\r
-    \r
-    this.domNode = jQuery (container);\r
-    \r
-    // the reorderable DOM element that is currently active\r
-    this.activeItem = null;\r
-        \r
-    this.layoutHandler = null;\r
-        \r
-    this.messageNamebase = "message-bundle:";\r
-    \r
-    this.orderableFinder = null;\r
-            \r
-    this.cssClasses = {\r
-        defaultStyle: "orderable-default",\r
-        selected: "orderable-selected",\r
-        dragging: "orderable-dragging",\r
-        hover: "orderable-hover",\r
-        focusTarget: "orderable-focus-target",\r
-        dropMarker: "orderable-drop-marker",\r
-        avatar: "orderable-avatar"\r
-    };\r
-\r
-    if (params) {\r
-        fluid.mixin (this, params);\r
-    }\r
-    \r
-   /**\r
-    * Return the element within the item that should receive focus. This is determined by \r
-    * cssClasses.focusTarget. If it is not specified, the item itself is returned.\r
-    * \r
-    * @param {Object} item\r
-    * @return {Object} The element that should receive focus in the specified item.\r
-    */\r
-    this.findElementToFocus = function (item) {\r
-        var elementToFocus = jQuery ("." + this.cssClasses.focusTarget, item).get (0);\r
-        if (elementToFocus) {\r
-            return elementToFocus;\r
-        }\r
-        return item;\r
-    };\r
-    \r
-    function setupDomNode (domNode) {\r
-        domNode.focus(thisReorderer.handleFocus);\r
-        domNode.blur (thisReorderer.handleBlur);\r
-        domNode.keydown (thisReorderer.handleKeyDown);\r
-        domNode.keyup (thisReorderer.handleKeyUp);\r
-        domNode.removeAttr ("aaa:activedescendent");\r
-    }   \r
-    \r
-    /**\r
-     * Changes the current focus to the specified item.\r
-     * @param {Object} anItem\r
-     */\r
-    this.focusItem = function(anItem) {\r
-        if (this.activeItem !== anItem) {\r
-            this.changeActiveItemToDefaultState();\r
-            this._setActiveItem (anItem);   \r
-        }\r
-        \r
-        var jActiveItem = jQuery (this.activeItem);\r
-        jActiveItem.removeClass (this.cssClasses.defaultStyle);\r
-        jActiveItem.addClass (this.cssClasses.selected);\r
-        \r
-        this.addFocusToElement (this.findElementToFocus (this.activeItem));\r
-    };\r
-    \r
-    this.addFocusToElement = function (anElement) {\r
-        var jElement = jQuery (anElement);\r
-        if (!jElement.hasTabIndex ()) {\r
-            jElement.tabIndex (-1);\r
-        }\r
-        jElement.focus ();\r
-    };\r
-    \r
-    this.removeFocusFromElement = function (anElement) {\r
-        jQuery (anElement).blur ();\r
-    };\r
-\r
-    /**\r
-     * Changes focus to the active item.\r
-     */\r
-    this.selectActiveItem = function() {\r
-        if (!this.activeItem) {\r
-            var orderables = this.orderableFinder (this.domNode.get(0));\r
-            if (orderables.length > 0) {\r
-                this._setActiveItem (orderables[0]);\r
-            }\r
-            else {\r
-                return;\r
-            }\r
-        }\r
-        this.focusItem (this.activeItem);\r
-    };\r
-    \r
-    this.handleFocus = function (evt) {\r
-        thisReorderer.selectActiveItem();\r
-        return false;\r
-    };\r
-    \r
-    this.handleBlur = function (evt) {\r
-        // Temporarily disabled blur handling in IE. See FLUID-7 for details.\r
-        if (!jQuery.browser.msie) {\r
-            thisReorderer.changeActiveItemToDefaultState();\r
-        }\r
-    };\r
-            \r
-    this.changeActiveItemToDefaultState = function() {\r
-        if (this.activeItem) {\r
-            var jActiveItem = jQuery (this.activeItem);\r
-            jActiveItem.removeClass (this.cssClasses.selected);\r
-            jActiveItem.addClass (this.cssClasses.defaultStyle);\r
-            this.removeFocusFromElement (jActiveItem);\r
-        }\r
-    };\r
-    \r
-    this.handleKeyDown = function (evt) {\r
-       if (thisReorderer.activeItem && evt.keyCode === fluid.keys.CTRL) {\r
-           jQuery (thisReorderer.activeItem).removeClass (thisReorderer.cssClasses.selected);\r
-           jQuery (thisReorderer.activeItem).addClass (thisReorderer.cssClasses.dragging);\r
-           thisReorderer.activeItem.setAttribute ("aaa:grab", "true");\r
-           return false;\r
-       }\r
-\r
-       return thisReorderer.handleArrowKeyPress(evt);\r
-    };\r
-\r
-    this.handleKeyUp = function (evt) {\r
-       if (thisReorderer.activeItem && evt.keyCode === fluid.keys.CTRL) {\r
-           jQuery (thisReorderer.activeItem).removeClass (thisReorderer.cssClasses.dragging);\r
-           jQuery (thisReorderer.activeItem).addClass (thisReorderer.cssClasses.selected);\r
-           thisReorderer.activeItem.setAttribute ("aaa:grab", "supported");\r
-           return false;\r
-       } \r
-    };\r
-        \r
-    this.handleArrowKeyPress = function (evt) {\r
-        if (thisReorderer.activeItem) {\r
-            switch (evt.keyCode) {\r
-                case fluid.keys.DOWN:\r
-                    evt.preventDefault();\r
-                    thisReorderer.handleDownArrow (evt.ctrlKey);                                \r
-                    return false;\r
-                case fluid.keys.UP: \r
-                    evt.preventDefault();\r
-                    thisReorderer.handleUpArrow (evt.ctrlKey);                              \r
-                    return false;\r
-                case fluid.keys.LEFT: \r
-                    evt.preventDefault();\r
-                    thisReorderer.handleLeftArrow (evt.ctrlKey);                                \r
-                    return false;\r
-                case fluid.keys.RIGHT: \r
-                    evt.preventDefault();\r
-                    thisReorderer.handleRightArrow (evt.ctrlKey);                               \r
-                    return false;\r
-                default:\r
-                    return true;\r
-            }\r
-        }\r
-    };\r
-    \r
-    this.handleUpArrow = function (isCtrl) {\r
-        if (isCtrl) {\r
-            this.layoutHandler.moveItemUp (this.activeItem);\r
-            this.findElementToFocus (this.activeItem).focus();\r
-        } else {\r
-            this.focusItem (this.layoutHandler.getItemAbove(this.activeItem));\r
-        }           \r
-    };\r
-    \r
-    this.handleDownArrow = function (isCtrl) {\r
-        if (isCtrl) {\r
-            this.layoutHandler.moveItemDown (this.activeItem);\r
-            this.findElementToFocus (this.activeItem).focus();\r
-        } else {\r
-            this.focusItem (this.layoutHandler.getItemBelow (this.activeItem));\r
-        }\r
-    };\r
-    \r
-    this.handleRightArrow = function (isCtrl) {\r
-        if (isCtrl) {\r
-            this.layoutHandler.moveItemRight (this.activeItem);\r
-            jQuery(this.findElementToFocus (this.activeItem)).focus();\r
-        } else {\r
-            this.focusItem (this.layoutHandler.getRightSibling (this.activeItem));              \r
-        }           \r
-    };\r
-    \r
-    this.handleLeftArrow = function (isCtrl) {\r
-        if (isCtrl) {\r
-            this.layoutHandler.moveItemLeft (this.activeItem);\r
-            this.findElementToFocus (this.activeItem).focus();\r
-        } else {\r
-            this.focusItem (this.layoutHandler.getLeftSibling (this.activeItem));               \r
-        }\r
-    };\r
-            \r
-    this._fetchMessage = function (messagekey) {\r
-        var messageID = this.messageNamebase + messagekey;\r
-        var node = document.getElementById (messageID);\r
-        \r
-        return node? node.innerHTML: "[Message not found at id " + messageID + "]";\r
-    };\r
-    \r
-    this._setActiveItem = function (anItem) {\r
-        this.activeItem = anItem;\r
-        this._updateActiveDescendent();\r
-    };\r
-    \r
-    this._updateActiveDescendent = function() {\r
-        if (this.activeItem) {\r
-            this.domNode.attr ("aaa:activedescendent", this.activeItem.id);\r
-        } else {\r
-            this.domNode.removeAttr ("aaa:activedescendent");\r
-        }\r
-    };\r
-\r
-    var dropMarker; // private scratch variable\r
-    \r
-    /**\r
-     * evt.data - the droppable DOM element.\r
-     */\r
-    function trackMouseMovement (evt) {\r
-        if (thisReorderer.layoutHandler.isMouseBefore (evt, evt.data)) {\r
-           jQuery (evt.data).before (dropMarker);\r
-       }        \r
-       else {\r
-           jQuery (evt.data).after (dropMarker);\r
-       }\r
-    }\r
-\r
-    /**\r
-     * Given an item, make it draggable.\r
-     */\r
-    function setUpDraggable (anItem) {\r
-        anItem.draggable ({\r
-            helper: function() {\r
-                theAvatar = jQuery (this).clone();\r
-                jQuery (theAvatar).removeAttr ("id");\r
-                jQuery ("[id]", theAvatar).removeAttr ("id");\r
-                jQuery (":hidden", theAvatar).remove(); \r
-                jQuery ("input", theAvatar).attr ("disabled", "true"); \r
-                theAvatar.addClass (thisReorderer.cssClasses.avatar);           \r
-                return theAvatar;\r
-            },\r
-            start: function (e, ui) {\r
-                thisReorderer.focusItem (ui.draggable.element);                \r
-                jQuery (ui.draggable.element).addClass (thisReorderer.cssClasses.dragging);\r
-                ui.draggable.element.setAttribute ("aaa:grab", "true");\r
-                \r
-                // In order to create valid html, the drop marker is the same type as the node being dragged.\r
-                // This creates a confusing UI in cases such as an ordered list. \r
-                // drop marker functionality should be made pluggable. \r
-                dropMarker = document.createElement (ui.draggable.element.tagName);\r
-                jQuery (dropMarker).addClass (thisReorderer.cssClasses.dropMarker);\r
-                dropMarker.style.visibility = "hidden";\r
-            },\r
-            stop: function(e, ui) {\r
-                jQuery (ui.draggable.element).removeClass (thisReorderer.cssClasses.dragging);\r
-                thisReorderer.activeItem.setAttribute ("aaa:grab", "supported");\r
-                thisReorderer.domNode.focus();\r
-                if (dropMarker.parentNode) {\r
-                    dropMarker.parentNode.removeChild (dropMarker);\r
-                }\r
-                theAvatar = null;\r
-            }\r
-        });\r
-    \r
-    }   // end setUpDraggable()\r
-\r
-    /**\r
-     * Make item a drop target.\r
-     */\r
-    function setUpDroppable (anItem, selector) {\r
-        anItem.droppable ({\r
-            accept: selector,\r
-            tolerance: "pointer",\r
-            over: function (e, ui) {\r
-                // the second parameter to bind() can be accessed through the event as event.data\r
-                jQuery (ui.droppable.element).bind ("mousemove", ui.droppable.element, trackMouseMovement);    \r
-                jQuery (theAvatar).bind ("mousemove", ui.droppable.element, trackMouseMovement);            \r
-                dropMarker.style.visibility = "visible";\r
-            },\r
-            out: function (e, ui) {\r
-                dropMarker.style.visibility = "hidden";\r
-                jQuery (ui.droppable.element).unbind ("mousemove", trackMouseMovement);\r
-                jQuery (theAvatar).unbind ("mousemove", trackMouseMovement);            \r
-            },\r
-            drop: function (e, ui) {\r
-                thisReorderer.layoutHandler.mouseMoveItem(e, ui.draggable.element, ui.droppable.element);\r
-                jQuery (ui.droppable.element).unbind ("mousemove", trackMouseMovement);\r
-                jQuery (theAvatar).unbind ("mousemove", trackMouseMovement);            \r
-            }\r
-        });\r
-    \r
-    }   // end setUpDroppable().\r
\r
-    /**\r
-     * Given an item, make it a draggable and a droppable with the relevant properties and functions.\r
-     * @param  anItem      The element to make draggable and droppable.\r
-     * @param  selector    The jQuery selector(s) that select all the orderables.\r
-     */ \r
-    function setUpDnDItem (anItem, selector) {\r
-        anItem.mouseover ( \r
-            function () {\r
-                jQuery (this).addClass (thisReorderer.cssClasses.hover);\r
-            }\r
-        );\r
-        \r
-        anItem.mouseout (  \r
-            function () {\r
-                jQuery (this).removeClass (thisReorderer.cssClasses.hover);\r
-            }\r
-        );\r
-  \r
-        // Make anItem draggable and a drop target (in the jQuery UI sense).\r
-        setUpDraggable (anItem);\r
-        setUpDroppable (anItem, selector);\r
-            \r
-    }   // end setUpDnDItem()\r
-        \r
-    function initOrderables() {\r
-        var items = thisReorderer.orderableFinder (thisReorderer.domNode.get(0));\r
-        if (items.length === 0) {\r
-            return;\r
-        }\r
-        \r
-        // Create a selector based on the ids of the nodes for use with drag and drop.\r
-        // This should be replaced with using the actual nodes rather then a selector \r
-        // but will require a patch to jquery's DnD. \r
-        // See: FLUID-71, FLUID-112\r
-        var selector = "";\r
-        for (var i = 0; i < items.length; i++) {\r
-            var item = items[i];\r
-            selector += "[id=" + item.id + "]";\r
-            if (i !== items.length - 1) {\r
-                selector += ", ";\r
-            }                   \r
-        }\r
-\r
-         // Setup orderable item including drag and drop.\r
-         for (i = 0; i < items.length; i++) {\r
-            jQuery (items[i]).addClass (thisReorderer.cssClasses.defaultStyle);\r
-            setUpDnDItem (jQuery (items[i]), selector);\r
-        }\r
-        \r
-        // Add any other drop targets (e.g., any unmoveable ones).\r
-        if ((thisReorderer.droppableFinder) && (thisReorderer.droppableFinder.constructor === Function)) {\r
-            var extraDropTargets = thisReorderer.droppableFinder (thisReorderer.domNode);\r
-            for (i = 0; i < extraDropTargets.length; i++) {\r
-                var jExtraDropTarget = jQuery (extraDropTargets[i]);\r
-                if (!jExtraDropTarget.droppableInstance()) {\r
-                    setUpDroppable (jExtraDropTarget, selector);\r
-                }\r
-            }\r
-        }\r
-    }   // end initOrderables().\r
-\r
-    /**\r
-     * Finds the "orderable" parent element given a child element.\r
-     */\r
-    this._findReorderableParent = function (childElement, items) {\r
-        if (!childElement) {\r
-            return null;\r
-        }\r
-        else {\r
-            for (var i=0; i<items.length; i++) {\r
-                if (childElement === items[i]) {\r
-                    return childElement;\r
-                }  \r
-            }\r
-            return this._findReorderableParent (childElement.parentNode, items);\r
-        }\r
-    };\r
-\r
-    // Final initialization of the Reorderer at the end of the construction process \r
-    if (this.domNode) {\r
-        setupDomNode(this.domNode);\r
-        initOrderables();\r
-    }\r
-}; // End Reorderer\r
-\r
-/*******************\r
- * Layout Handlers *\r
- *******************/\r
-(function () {\r
-    // Shared private functions.\r
-    var moveItem = function (item, relatedItemInfo, defaultPlacement, wrappedPlacement) {\r
-        var itemPlacement = defaultPlacement;\r
-        if (relatedItemInfo.hasWrapped) {\r
-            itemPlacement = wrappedPlacement;\r
-        }\r
-        \r
-        // The "after" and "before" strings are an artifact of using dojo.place. \r
-        // This should be refactored. \r
-        if (itemPlacement === "after") {\r
-            jQuery (relatedItemInfo.item).after (item);\r
-        } else {\r
-            jQuery (relatedItemInfo.item).before (item);\r
-        } \r
-    };\r
-    \r
-    /**\r
-     * For drag-and-drop during the drag:  is the mouse over the "before" half\r
-     * of the droppable?  In the case of a vertically oriented set of orderables,\r
-     * "before" means "above".  For a horizontally oriented set, "before" means\r
-     * "left of".\r
-     */\r
-    var isMouseBefore = function (evt, droppableEl, orientation) {\r
-        var mid;\r
-        if (orientation === fluid.orientation.VERTICAL) {\r
-            mid = jQuery (droppableEl).offset().top + (droppableEl.offsetHeight / 2);\r
-            return (evt.pageY < mid);\r
-        } else {\r
-            mid = jQuery (droppableEl).offset().left + (droppableEl.offsetWidth / 2);\r
-            return (evt.clientX < mid);\r
-        }\r
-    };    \r
-\r
-    var itemInfoFinders = {\r
-        /*\r
-         * A general get{Left|Right}SiblingInfo() given an item, a list of orderables and a direction.\r
-         * The direction is encoded by either a +1 to move right, or a -1 to\r
-         * move left, and that value is used internally as an increment or\r
-         * decrement, respectively, of the index of the given item.\r
-         */\r
-        getSiblingInfo: function (item, orderables, /* +1, -1 */ incDecrement) {\r
-            var index = jQuery (orderables).index (item) + incDecrement;\r
-            var hasWrapped = false;\r
-                \r
-            // Handle wrapping to 'before' the beginning. \r
-            if (index === -1) {\r
-                index = orderables.length - 1;\r
-                hasWrapped = true;\r
-            }\r
-            // Handle wrapping to 'after' the end.\r
-            else if (index === orderables.length) {\r
-                index = 0;\r
-                hasWrapped = true;\r
-            } \r
-            // Handle case where the passed-in item is *not* an "orderable"\r
-            // (or other undefined error).\r
-            //\r
-            else if (index < -1 || index > orderables.length) {\r
-                index = 0;\r
-            }\r
-            \r
-            return {item: orderables[index], hasWrapped: hasWrapped};\r
-        },\r
-\r
-        /*\r
-         * Returns an object containing the item that is to the right of the given item\r
-         * and a flag indicating whether or not the process has 'wrapped' around the end of\r
-         * the row that the given item is in\r
-         */\r
-        getRightSiblingInfo: function (item, orderables) {\r
-            return this.getSiblingInfo (item, orderables, 1);\r
-        },\r
-        \r
-        /*\r
-         * Returns an object containing the item that is to the left of the given item\r
-         * and a flag indicating whether or not the process has 'wrapped' around the end of\r
-         * the row that the given item is in\r
-         */\r
-        getLeftSiblingInfo: function (item, orderables) {\r
-            return this.getSiblingInfo (item, orderables, -1);\r
-        },\r
-        \r
-        /*\r
-         * Returns an object containing the item that is below the given item in the current grid\r
-         * and a flag indicating whether or not the process has 'wrapped' around the end of\r
-         * the column that the given item is in. The flag is necessary because when an image is being\r
-         * moved to the resulting item location, the decision of whether or not to insert before or\r
-         * after the item changes if the process wrapped around the column.\r
-         */\r
-        getItemInfoBelow: function (inItem, orderables) {\r
-            var curCoords = jQuery (inItem).offset();\r
-            var i, iCoords;\r
-            var firstItemInColumn, currentItem;\r
-            \r
-            for (i = 0; i < orderables.length; i++) {\r
-                currentItem = orderables [i];\r
-                iCoords = jQuery (orderables[i]).offset();\r
-                if (iCoords.left === curCoords.left) {\r
-                    firstItemInColumn = firstItemInColumn || currentItem;\r
-                    if (iCoords.top > curCoords.top) {\r
-                        return {item: currentItem, hasWrapped: false};\r
-                    }\r
-                }\r
-            }\r
-    \r
-            firstItemInColumn = firstItemInColumn || orderables [0];\r
-            return {item: firstItemInColumn, hasWrapped: true};\r
-        },\r
-        \r
-        /*\r
-         * Returns an object containing the item that is above the given item in the current grid\r
-         * and a flag indicating whether or not the process has 'wrapped' around the end of\r
-         * the column that the given item is in. The flag is necessary because when an image is being\r
-         * moved to the resulting item location, the decision of whether or not to insert before or\r
-         * after the item changes if the process wrapped around the column.\r
-         */\r
-         getItemInfoAbove: function (inItem, orderables) {\r
-            var curCoords = jQuery (inItem).offset();\r
-            var i, iCoords;\r
-            var lastItemInColumn, currentItem;\r
-            \r
-            for (i = orderables.length - 1; i > -1; i--) {\r
-                currentItem = orderables [i];\r
-                iCoords = jQuery (orderables[i]).offset();\r
-                if (iCoords.left === curCoords.left) {\r
-                    lastItemInColumn = lastItemInColumn || currentItem;\r
-                    if (curCoords.top > iCoords.top) {\r
-                        return {item: currentItem, hasWrapped: false};\r
-                    }\r
-                }\r
-            }\r
-    \r
-            lastItemInColumn = lastItemInColumn || orderables [0];\r
-            return {item: lastItemInColumn, hasWrapped: true};\r
-        }\r
-    \r
-    };\r
-    \r
-    // Public layout handlers.\r
-    fluid.ListLayoutHandler = function (params) {\r
-        var orderableFinder = params.orderableFinder;\r
-        var container = params.container;\r
-        var orderChangedCallback = params.orderChangedCallback;\r
-        var orientation = params.orientation;\r
-        \r
-        // Unwrap the container if it's a jQuery.\r
-        container = (container.jquery) ? container.get(0) : container;\r
-        \r
-        orderChangedCallback = orderChangedCallback || function () {};\r
-        \r
-        orientation = orientation || fluid.orientation.VERTICAL;    // default\r
-                \r
-        this.getRightSibling = function (item) {\r
-            return itemInfoFinders.getRightSiblingInfo(item, orderableFinder(container)).item;\r
-        };\r
-        \r
-        this.moveItemRight = function (item) {\r
-            moveItem (item, itemInfoFinders.getRightSiblingInfo(item, orderableFinder(container)), "after", "before");\r
-            orderChangedCallback();\r
-        };\r
-    \r
-        this.getLeftSibling = function (item) {\r
-            return itemInfoFinders.getLeftSiblingInfo(item, orderableFinder(container)).item;\r
-        };\r
-    \r
-        this.moveItemLeft = function (item) {\r
-            moveItem (item, itemInfoFinders.getLeftSiblingInfo(item, orderableFinder(container)), "before", "after");\r
-            orderChangedCallback();\r
-        };\r
-    \r
-        this.getItemBelow = this.getRightSibling;\r
-    \r
-        this.getItemAbove = this.getLeftSibling;\r
-        \r
-        this.moveItemUp = this.moveItemLeft;\r
-        \r
-        this.moveItemDown = this.moveItemRight;\r
-    \r
-        this.isMouseBefore = function(evt, droppableEl) {\r
-            return isMouseBefore(evt, droppableEl, orientation);\r
-        };\r
-        \r
-        this.mouseMoveItem = function (e, item, relatedItem) {\r
-            if (this.isMouseBefore (e, relatedItem)) {\r
-                jQuery (relatedItem).before (item);\r
-            } else {\r
-                jQuery (relatedItem).after (item);\r
-            }\r
-            orderChangedCallback(); \r
-        };\r
-    }; // End ListLayoutHandler\r
-    \r
-       /*\r
-        * Items in the Lightbox are stored in a list, but they are visually presented as a grid that\r
-        * changes dimensions when the window changes size. As a result, when the user presses the up or\r
-        * down arrow key, what lies above or below depends on the current window size.\r
-        * \r
-        * The GridLayoutHandler is responsible for handling changes to this virtual 'grid' of items\r
-        * in the window, and of informing the Lightbox of which items surround a given item.\r
-        */\r
-       fluid.GridLayoutHandler = function (params) {\r
-        fluid.ListLayoutHandler.call (this, params);\r
-\r
-        var orderableFinder = params.orderableFinder;\r
-        var container = params.container;\r
-        var orderChangedCallback = params.orderChangedCallback;\r
-        var orientation = fluid.orientation.HORIZONTAL;\r
-        \r
-               // Unwrap the container if it's a jQuery.\r
-        container = (container.jquery) ? container.get(0) : container;\r
-        \r
-        orderChangedCallback = orderChangedCallback || function () {};\r
-        \r
-           this.getItemBelow = function(item) {\r
-               return itemInfoFinders.getItemInfoBelow (item, orderableFinder(container)).item;\r
-           };\r
-       \r
-           this.moveItemDown = function (item) {\r
-               moveItem (item, itemInfoFinders.getItemInfoBelow (item, orderableFinder(container)), "after", "before");\r
-            orderChangedCallback(); \r
-           };\r
-                   \r
-           this.getItemAbove = function (item) {\r
-               return itemInfoFinders.getItemInfoAbove (item, orderableFinder(container)).item;   \r
-           }; \r
-           \r
-           this.moveItemUp = function (item) {\r
-               moveItem (item, itemInfoFinders.getItemInfoAbove (item, orderableFinder(container)), "before", "after");\r
-            orderChangedCallback(); \r
-           };\r
-                       \r
-           // We need to override ListLayoutHandler.isMouseBefore to ensure that the local private\r
-           // orientation is used.\r
-        this.isMouseBefore = function(evt, droppableEl) {\r
-            return isMouseBefore(evt, droppableEl, orientation);\r
-        };\r
-        \r
-       }; // End of GridLayoutHandler\r
-\r
-    fluid.portletPerms = fluid.portletPerms || {};\r
-    fluid.portletPerms.canDrop = function (perms, indexOfItem, indexOfTarget, position) {\r
-        return (!!perms[indexOfItem][indexOfTarget][position]); \r
-    };\r
-    \r
-    /*\r
-     * PortletLayout helper object.\r
-     */\r
-    fluid.PortletLayout = function() {\r
-               \r
-        /**\r
-         * Calculate the location of the item and the column in which it resides.\r
-         * @return  An object with column index and item index (within that column) properties.\r
-         *          These indices are -1 if the item does not exist in the grid.\r
-         */\r
-        this.calcColumnAndItemIndex = function (item, portletLayoutJSON) {\r
-               var indices = { columnIndex: -1, itemIndex: -1 };\r
-            for (var col = 0; col < portletLayoutJSON.columns.length; col++) {\r
-               var itemIndex = jQuery (portletLayoutJSON.columns[col].children).index (item.id);\r
-                if (itemIndex !== -1) {\r
-                    indices.columnIndex = col;\r
-                    indices.itemIndex = itemIndex;\r
-                    break;\r
-                }                \r
-            }\r
-            return indices;\r
-        };\r
-                        \r
-        /**\r
-         * Return the first orderable item in the given column.\r
-         */\r
-        this.findFirstOrderableSiblingInColumn = function (columnIndex, orderableItems, portletLayoutJSON) {\r
-            // Pull out the portlet id of the top-most sibling in the column.\r
-            var topMostOrderableSibling = null;\r
-            var itemIndex = 0;\r
-            var column = portletLayoutJSON.columns[columnIndex];\r
-            if (column) {\r
-                var id = column.children[itemIndex];\r
-                topMostOrderableSibling = jQuery ("#" + id)[0];\r
-                // loop down the column looking for first orderable portlet (i.e. skip over non-movable portlets)\r
-                while (orderableItems.index (topMostOrderableSibling) === -1) {\r
-                    itemIndex += 1;\r
-                    id = column.children[itemIndex];\r
-                    topMostOrderableSibling = jQuery ("#" + id).get (0);\r
-                }\r
-            }\r
-            return topMostOrderableSibling;\r
-        };\r
-        \r
-        /**\r
-         * Return the number of items in the given column.  If the column index\r
-         * is out of bounds, this returns -1.\r
-         */\r
-        this.numItemsInColumn = function (columnIndex, portletLayoutJSON) {\r
-               if ((columnIndex < 0) || (columnIndex > portletLayoutJSON.columns.length)) {\r
-                       return -1;\r
-               }\r
-               else {\r
-                  return portletLayoutJSON.columns[columnIndex].children.length;\r
-               }\r
-        };\r
-        \r
-        this.numColumns = function (layout) {\r
-            return layout.columns.length;\r
-        };\r
-        \r
-        this.findLinearIndex = function (itemId, layout) {\r
-            var columns = layout.columns;\r
-            var linearIndex = 0;\r
-            \r
-            for (var i = 0; i < columns.length; i++) {\r
-               var idsInCol = columns[i].children;\r
-               for (var j = 0; j < idsInCol.length; j++) {\r
-                       if (idsInCol[j] === itemId) {\r
-                               return linearIndex;\r
-                       }\r
-                       linearIndex++;\r
-               }\r
-            }\r
-            \r
-            return -1;\r
-        };\r
-        \r
-        /**\r
-         * Move an item within the portletLayoutJSON object. \r
-         */\r
-        this.updateLayout = function (item, relativeItem, placement, portletLayoutJSON) {\r
-            if (!item || !relativeItem) { return; }\r
-            var itemIndices = this.calcColumnAndItemIndex (item, portletLayoutJSON);\r
-\r
-            var itemId = portletLayoutJSON.columns[itemIndices.columnIndex].children[itemIndices.itemIndex];\r
-            portletLayoutJSON.columns[itemIndices.columnIndex].children.splice (itemIndices.itemIndex, 1);\r
-\r
-            var relativeItemIndices = this.calcColumnAndItemIndex (relativeItem, portletLayoutJSON);\r
-            var targetCol = portletLayoutJSON.columns[relativeItemIndices.columnIndex].children;\r
-            targetCol.splice (relativeItemIndices.itemIndex + (placement === "before"? 0 : 1), 0, itemId);\r
-        };\r
-    };   // End of PortletLayout.\r
-    \r
-    /*\r
-     * Portlet Layout Handler for reordering portlet-type markup.\r
-     * \r
-     * General movement guidelines:\r
-     * \r
-     * - Arrowing sideways will always go to the top (moveable) portlet in the column\r
-     * - Moving sideways will always move to the top available drop target in the column\r
-     * - Wrapping is not necessary at this first pass, but is ok\r
-     */\r
-    fluid.PortletLayoutHandler = function (params) {\r
-        var orderableFinder = params.orderableFinder;\r
-        var container = params.container;\r
-        var orderChangedCallback = params.orderChangedCallback;\r
-        var portletLayoutJSON = params.portletLayout;\r
-        var targetPerms = params.dropTargetPermissions;\r
-        var orientation = fluid.orientation.VERTICAL;\r
-        \r
-        var portletLayout = new fluid.PortletLayout();\r
-        \r
-        // Unwrap the container if it's a jQuery.\r
-        container = (container.jquery) ? container.get(0) : container;\r
-        \r
-        orderChangedCallback = orderChangedCallback || function () {};\r
-\r
-        // Private Methods.\r
-        /*\r
-            * A general get{Above|Below}Sibling() given an item and a direction.\r
-            * The direction is encoded by either a +1 to move down, or a -1 to\r
-            * move up, and that value is used internally as an increment or\r
-            * decrement, respectively, of the index of the given item.\r
-            * This implementation does not wrap around. \r
-            */\r
-           var getVerticalSibling = function (item, /* +1, -1 */ incDecrement) {\r
-               var orderables = orderableFinder (container);\r
-               var index = jQuery(orderables).index(item) + incDecrement;\r
-                   \r
-               // If we wrap, backup \r
-               if ((index === -1) || (index === orderables.length)) {\r
-                   return null;\r
-               }\r
-               // Handle case where the passed-in item is *not* an "orderable"\r
-               // (or other undefined error).\r
-               //\r
-               else if (index < -1 || index > orderables.length) {\r
-                   index = 0;\r
-               }\r
-               \r
-               return orderables[index];\r
-           };\r
-       \r
-           /*\r
-            * A general get{Beside}SiblingInfo() given an item and a direction.\r
-            * The direction is encoded by either a +1 to move right, or a -1 to\r
-            * move left.\r
-            * Currently, the horizontal sibling defaults to the top orderable item in the\r
-            * neighboring column.\r
-            */\r
-           var getHorizontalSibling = function (item, /* +1, -1 */ incDecrement) {\r
-               var orderables = orderableFinder (container);\r
-                   \r
-            // go through all the children and find which column the passed in item is located in.\r
-            // Save that column if found.\r
-            var colIndex = portletLayout.calcColumnAndItemIndex (item, portletLayoutJSON).columnIndex;\r
-               if (colIndex === -1) {\r
-                   return null;\r
-               }\r
-            var sibling = portletLayout.findFirstOrderableSiblingInColumn (colIndex + incDecrement, orderables, portletLayoutJSON);\r
-               return sibling;\r
-       \r
-           };\r
-                   \r
-           // These methods are public only for our unit tests. They need to be refactored into a portletlayout object.\r
-         var isFirstInColumn = function (item) {\r
-            var position = portletLayout.calcColumnAndItemIndex (item, portletLayoutJSON);\r
-            return (position.itemIndex === 0) ? true : false;\r
-        };\r
-    \r
-        var isLastInColumn = function (item) {\r
-            var position = portletLayout.calcColumnAndItemIndex (item, portletLayoutJSON);\r
-            return (position.itemIndex === portletLayout.numItemsInColumn (position.columnIndex, portletLayoutJSON)-1) ? true : false;\r
-        };\r
-        \r
-        var isInLeftmostColumn = function (item) {\r
-            if (portletLayout.calcColumnAndItemIndex (item, portletLayoutJSON).columnIndex === 0) {\r
-                return true;\r
-            } else {\r
-                return false;\r
-            }\r
-        };\r
-        \r
-        var isInRightmostColumn = function (item) {\r
-            if (portletLayout.calcColumnAndItemIndex (item, portletLayoutJSON).columnIndex === portletLayout.numColumns (portletLayoutJSON) - 1) {\r
-                return true;\r
-            } else {\r
-                return false;\r
-            }\r
-        };\r
-            \r
-        var canDrop = function (itemId, relatedItemId, position) {\r
-            return fluid.portletPerms.canDrop(\r
-                targetPerms, \r
-                portletLayout.findLinearIndex(itemId, portletLayoutJSON), \r
-                portletLayout.findLinearIndex(relatedItemId, portletLayoutJSON), \r
-                position);\r
-        };\r
-        \r
-        var moveBefore = function (item, relatedItem) {\r
-            if (!canDrop (item.id, relatedItem.id, fluid.position.BEFORE)) {\r
-                return;\r
-            } \r
-                \r
-            jQuery (relatedItem).before (item);\r
-            portletLayout.updateLayout (item, relatedItem, "before", portletLayoutJSON);\r
-            portletLayoutJSON = orderChangedCallback() || portletLayoutJSON; \r
-        };\r
-        \r
-        var moveAfter = function (item, relatedItem) {\r
-            if (!canDrop (item.id, relatedItem.id, fluid.position.AFTER)) {\r
-                return;\r
-            } \r
-                \r
-            jQuery (relatedItem).after (item);\r
-            portletLayout.updateLayout (item, relatedItem, "after", portletLayoutJSON);\r
-            portletLayoutJSON = orderChangedCallback() || portletLayoutJSON; \r
-        };        \r
-\r
-        // Public Methods\r
-        \r
-           this.getRightSibling = function (item) {\r
-            if (isInRightmostColumn(item)) {\r
-                return item;\r
-            } else {\r
-                return getHorizontalSibling(item, 1);\r
-            }\r
-           };\r
-           \r
-           this.moveItemRight = function (item) {\r
-            var rightSibling = this.getRightSibling (item);\r
-            jQuery (rightSibling).before (item);\r
-            portletLayout.updateLayout (item, rightSibling, "before", portletLayoutJSON);\r
-            // first, stringify the json before sending it\r
-            portletLayoutJSON = orderChangedCallback() || portletLayoutJSON; \r
-            // the return value will actually be a big json object with two parts\r
-            // we'll have to parse it, and separate the two parts\r
-           };\r
-       \r
-           this.getLeftSibling = function (item) {\r
-            if (isInLeftmostColumn(item)) {\r
-                return item;\r
-            } else {\r
-                return getHorizontalSibling(item, -1);\r
-            }\r
-           };\r
-       \r
-           this.moveItemLeft = function (item) {\r
-               var leftSibling = this.getLeftSibling(item);\r
-            jQuery (leftSibling).before (item);\r
-            portletLayout.updateLayout (item, leftSibling, "before", portletLayoutJSON);\r
-            portletLayoutJSON = orderChangedCallback() || portletLayoutJSON; \r
-           };\r
-       \r
-           this.getItemAbove = function (item) {\r
-               if (isFirstInColumn(item)) {\r
-                return item;\r
-            } else {\r
-                return getVerticalSibling (item, -1);\r
-            }\r
-           };\r
-           \r
-           this.moveItemUp = function (item) {\r
-               var siblingAbove = this.getItemAbove(item);\r
-               moveBefore (item, siblingAbove);\r
-           };\r
-               \r
-           this.getItemBelow = function (item) {\r
-               if (isLastInColumn(item)) {\r
-                return item;\r
-            } else {\r
-                return getVerticalSibling (item, 1);\r
-            }\r
-           };\r
-       \r
-           this.moveItemDown = function (item) {\r
-               var siblingBelow = this.getItemBelow(item);\r
-               moveAfter (item, siblingBelow);\r
-           };\r
-           \r
-           this.isMouseBefore = function(evt, droppableEl) {\r
-            return isMouseBefore(evt, droppableEl, orientation);\r
-        };\r
-\r
-        this.mouseMoveItem = function (e, item, relatedItem) {\r
-            if (this.isMouseBefore (e, relatedItem)) {\r
-                moveBefore (item, relatedItem);\r
-            } else {\r
-                moveAfter (item, relatedItem);\r
-            }\r
-        };\r
-        \r
-    }; // End PortalLayoutHandler\r
-}) ();\r
-\r