diff --git a/dashboard-ui/bower_components/Sortable/Sortable.js b/dashboard-ui/bower_components/Sortable/Sortable.js deleted file mode 100644 index f4ac38dff5..0000000000 --- a/dashboard-ui/bower_components/Sortable/Sortable.js +++ /dev/null @@ -1,1249 +0,0 @@ -/**! - * Sortable - * @author RubaXa - * @license MIT - */ - - -(function (factory) { - "use strict"; - - if (typeof define === "function" && define.amd) { - define(factory); - } - else if (typeof module != "undefined" && typeof module.exports != "undefined") { - module.exports = factory(); - } - else if (typeof Package !== "undefined") { - Sortable = factory(); // export for Meteor.js - } - else { - /* jshint sub:true */ - window["Sortable"] = factory(); - } -})(function () { - "use strict"; - - var dragEl, - parentEl, - ghostEl, - cloneEl, - rootEl, - nextEl, - - scrollEl, - scrollParentEl, - - lastEl, - lastCSS, - lastParentCSS, - - oldIndex, - newIndex, - - activeGroup, - autoScroll = {}, - - tapEvt, - touchEvt, - - moved, - - /** @const */ - RSPACE = /\s+/g, - - expando = 'Sortable' + (new Date).getTime(), - - win = window, - document = win.document, - parseInt = win.parseInt, - - supportDraggable = !!('draggable' in document.createElement('div')), - supportCssPointerEvents = (function (el) { - el = document.createElement('x'); - el.style.cssText = 'pointer-events:auto'; - return el.style.pointerEvents === 'auto'; - })(), - - _silent = false, - - abs = Math.abs, - slice = [].slice, - - touchDragOverListeners = [], - - _autoScroll = _throttle(function (/**Event*/evt, /**Object*/options, /**HTMLElement*/rootEl) { - // Bug: https://bugzilla.mozilla.org/show_bug.cgi?id=505521 - if (rootEl && options.scroll) { - var el, - rect, - sens = options.scrollSensitivity, - speed = options.scrollSpeed, - - x = evt.clientX, - y = evt.clientY, - - winWidth = window.innerWidth, - winHeight = window.innerHeight, - - vx, - vy - ; - - // Delect scrollEl - if (scrollParentEl !== rootEl) { - scrollEl = options.scroll; - scrollParentEl = rootEl; - - if (scrollEl === true) { - scrollEl = rootEl; - - do { - if ((scrollEl.offsetWidth < scrollEl.scrollWidth) || - (scrollEl.offsetHeight < scrollEl.scrollHeight) - ) { - break; - } - /* jshint boss:true */ - } while (scrollEl = scrollEl.parentNode); - } - } - - if (scrollEl) { - el = scrollEl; - rect = scrollEl.getBoundingClientRect(); - vx = (abs(rect.right - x) <= sens) - (abs(rect.left - x) <= sens); - vy = (abs(rect.bottom - y) <= sens) - (abs(rect.top - y) <= sens); - } - - - if (!(vx || vy)) { - vx = (winWidth - x <= sens) - (x <= sens); - vy = (winHeight - y <= sens) - (y <= sens); - - /* jshint expr:true */ - (vx || vy) && (el = win); - } - - - if (autoScroll.vx !== vx || autoScroll.vy !== vy || autoScroll.el !== el) { - autoScroll.el = el; - autoScroll.vx = vx; - autoScroll.vy = vy; - - clearInterval(autoScroll.pid); - - if (el) { - autoScroll.pid = setInterval(function () { - if (el === win) { - win.scrollTo(win.pageXOffset + vx * speed, win.pageYOffset + vy * speed); - } else { - vy && (el.scrollTop += vy * speed); - vx && (el.scrollLeft += vx * speed); - } - }, 24); - } - } - } - }, 30), - - _prepareGroup = function (options) { - var group = options.group; - - if (!group || typeof group != 'object') { - group = options.group = {name: group}; - } - - ['pull', 'put'].forEach(function (key) { - if (!(key in group)) { - group[key] = true; - } - }); - - options.groups = ' ' + group.name + (group.put.join ? ' ' + group.put.join(' ') : '') + ' '; - } - ; - - - - /** - * @class Sortable - * @param {HTMLElement} el - * @param {Object} [options] - */ - function Sortable(el, options) { - if (!(el && el.nodeType && el.nodeType === 1)) { - throw 'Sortable: `el` must be HTMLElement, and not ' + {}.toString.call(el); - } - - this.el = el; // root element - this.options = options = _extend({}, options); - - - // Export instance - el[expando] = this; - - - // Default options - var defaults = { - group: Math.random(), - sort: true, - disabled: false, - store: null, - handle: null, - scroll: true, - scrollSensitivity: 30, - scrollSpeed: 10, - draggable: /[uo]l/i.test(el.nodeName) ? 'li' : '>*', - ghostClass: 'sortable-ghost', - chosenClass: 'sortable-chosen', - ignore: 'a, img', - filter: null, - animation: 0, - setData: function (dataTransfer, dragEl) { - dataTransfer.setData('Text', dragEl.textContent); - }, - dropBubble: false, - dragoverBubble: false, - dataIdAttr: 'data-id', - delay: 0, - forceFallback: false, - fallbackClass: 'sortable-fallback', - fallbackOnBody: false - }; - - - // Set default options - for (var name in defaults) { - !(name in options) && (options[name] = defaults[name]); - } - - _prepareGroup(options); - - // Bind all private methods - for (var fn in this) { - if (fn.charAt(0) === '_') { - this[fn] = this[fn].bind(this); - } - } - - // Setup drag mode - this.nativeDraggable = options.forceFallback ? false : supportDraggable; - - // Bind events - _on(el, 'mousedown', this._onTapStart); - _on(el, 'touchstart', this._onTapStart); - - if (this.nativeDraggable) { - _on(el, 'dragover', this); - _on(el, 'dragenter', this); - } - - touchDragOverListeners.push(this._onDragOver); - - // Restore sorting - options.store && this.sort(options.store.get(this)); - } - - - Sortable.prototype = /** @lends Sortable.prototype */ { - constructor: Sortable, - - _onTapStart: function (/** Event|TouchEvent */evt) { - var _this = this, - el = this.el, - options = this.options, - type = evt.type, - touch = evt.touches && evt.touches[0], - target = (touch || evt).target, - originalTarget = target, - filter = options.filter; - - - if (type === 'mousedown' && evt.button !== 0 || options.disabled) { - return; // only left button or enabled - } - - target = _closest(target, options.draggable, el); - - if (!target) { - return; - } - - // get the index of the dragged element within its parent - oldIndex = _index(target); - - // Check filter - if (typeof filter === 'function') { - if (filter.call(this, evt, target, this)) { - _dispatchEvent(_this, originalTarget, 'filter', target, el, oldIndex); - evt.preventDefault(); - return; // cancel dnd - } - } - else if (filter) { - filter = filter.split(',').some(function (criteria) { - criteria = _closest(originalTarget, criteria.trim(), el); - - if (criteria) { - _dispatchEvent(_this, criteria, 'filter', target, el, oldIndex); - return true; - } - }); - - if (filter) { - evt.preventDefault(); - return; // cancel dnd - } - } - - - if (options.handle && !_closest(originalTarget, options.handle, el)) { - return; - } - - - // Prepare `dragstart` - this._prepareDragStart(evt, touch, target); - }, - - _prepareDragStart: function (/** Event */evt, /** Touch */touch, /** HTMLElement */target) { - var _this = this, - el = _this.el, - options = _this.options, - ownerDocument = el.ownerDocument, - dragStartFn; - - if (target && !dragEl && (target.parentNode === el)) { - tapEvt = evt; - - rootEl = el; - dragEl = target; - parentEl = dragEl.parentNode; - nextEl = dragEl.nextSibling; - activeGroup = options.group; - - dragStartFn = function () { - // Delayed drag has been triggered - // we can re-enable the events: touchmove/mousemove - _this._disableDelayedDrag(); - - // Make the element draggable - dragEl.draggable = true; - - // Chosen item - _toggleClass(dragEl, _this.options.chosenClass, true); - - // Bind the events: dragstart/dragend - _this._triggerDragStart(touch); - }; - - // Disable "draggable" - options.ignore.split(',').forEach(function (criteria) { - _find(dragEl, criteria.trim(), _disableDraggable); - }); - - _on(ownerDocument, 'mouseup', _this._onDrop); - _on(ownerDocument, 'touchend', _this._onDrop); - _on(ownerDocument, 'touchcancel', _this._onDrop); - - if (options.delay) { - // If the user moves the pointer or let go the click or touch - // before the delay has been reached: - // disable the delayed drag - _on(ownerDocument, 'mouseup', _this._disableDelayedDrag); - _on(ownerDocument, 'touchend', _this._disableDelayedDrag); - _on(ownerDocument, 'touchcancel', _this._disableDelayedDrag); - _on(ownerDocument, 'mousemove', _this._disableDelayedDrag); - _on(ownerDocument, 'touchmove', _this._disableDelayedDrag); - - _this._dragStartTimer = setTimeout(dragStartFn, options.delay); - } else { - dragStartFn(); - } - } - }, - - _disableDelayedDrag: function () { - var ownerDocument = this.el.ownerDocument; - - clearTimeout(this._dragStartTimer); - _off(ownerDocument, 'mouseup', this._disableDelayedDrag); - _off(ownerDocument, 'touchend', this._disableDelayedDrag); - _off(ownerDocument, 'touchcancel', this._disableDelayedDrag); - _off(ownerDocument, 'mousemove', this._disableDelayedDrag); - _off(ownerDocument, 'touchmove', this._disableDelayedDrag); - }, - - _triggerDragStart: function (/** Touch */touch) { - if (touch) { - // Touch device support - tapEvt = { - target: dragEl, - clientX: touch.clientX, - clientY: touch.clientY - }; - - this._onDragStart(tapEvt, 'touch'); - } - else if (!this.nativeDraggable) { - this._onDragStart(tapEvt, true); - } - else { - _on(dragEl, 'dragend', this); - _on(rootEl, 'dragstart', this._onDragStart); - } - - try { - if (document.selection) { - document.selection.empty(); - } else { - window.getSelection().removeAllRanges(); - } - } catch (err) { - } - }, - - _dragStarted: function () { - if (rootEl && dragEl) { - // Apply effect - _toggleClass(dragEl, this.options.ghostClass, true); - - Sortable.active = this; - - // Drag start event - _dispatchEvent(this, rootEl, 'start', dragEl, rootEl, oldIndex); - } - }, - - _emulateDragOver: function () { - if (touchEvt) { - if (this._lastX === touchEvt.clientX && this._lastY === touchEvt.clientY) { - return; - } - - this._lastX = touchEvt.clientX; - this._lastY = touchEvt.clientY; - - if (!supportCssPointerEvents) { - _css(ghostEl, 'display', 'none'); - } - - var target = document.elementFromPoint(touchEvt.clientX, touchEvt.clientY), - parent = target, - groupName = ' ' + this.options.group.name + '', - i = touchDragOverListeners.length; - - if (parent) { - do { - if (parent[expando] && parent[expando].options.groups.indexOf(groupName) > -1) { - while (i--) { - touchDragOverListeners[i]({ - clientX: touchEvt.clientX, - clientY: touchEvt.clientY, - target: target, - rootEl: parent - }); - } - - break; - } - - target = parent; // store last element - } - /* jshint boss:true */ - while (parent = parent.parentNode); - } - - if (!supportCssPointerEvents) { - _css(ghostEl, 'display', ''); - } - } - }, - - - _onTouchMove: function (/**TouchEvent*/evt) { - if (tapEvt) { - // only set the status to dragging, when we are actually dragging - if (!Sortable.active) { - this._dragStarted(); - } - - // as well as creating the ghost element on the document body - this._appendGhost(); - - var touch = evt.touches ? evt.touches[0] : evt, - dx = touch.clientX - tapEvt.clientX, - dy = touch.clientY - tapEvt.clientY, - translate3d = evt.touches ? 'translate3d(' + dx + 'px,' + dy + 'px,0)' : 'translate(' + dx + 'px,' + dy + 'px)'; - - moved = true; - touchEvt = touch; - - _css(ghostEl, 'webkitTransform', translate3d); - _css(ghostEl, 'mozTransform', translate3d); - _css(ghostEl, 'msTransform', translate3d); - _css(ghostEl, 'transform', translate3d); - - evt.preventDefault(); - } - }, - - _appendGhost: function () { - if (!ghostEl) { - var rect = dragEl.getBoundingClientRect(), - css = _css(dragEl), - options = this.options, - ghostRect; - - ghostEl = dragEl.cloneNode(true); - - _toggleClass(ghostEl, options.ghostClass, false); - _toggleClass(ghostEl, options.fallbackClass, true); - - _css(ghostEl, 'top', rect.top - parseInt(css.marginTop, 10)); - _css(ghostEl, 'left', rect.left - parseInt(css.marginLeft, 10)); - _css(ghostEl, 'width', rect.width); - _css(ghostEl, 'height', rect.height); - _css(ghostEl, 'opacity', '0.8'); - _css(ghostEl, 'position', 'fixed'); - _css(ghostEl, 'zIndex', '100000'); - _css(ghostEl, 'pointerEvents', 'none'); - - options.fallbackOnBody && document.body.appendChild(ghostEl) || rootEl.appendChild(ghostEl); - - // Fixing dimensions. - ghostRect = ghostEl.getBoundingClientRect(); - _css(ghostEl, 'width', rect.width * 2 - ghostRect.width); - _css(ghostEl, 'height', rect.height * 2 - ghostRect.height); - } - }, - - _onDragStart: function (/**Event*/evt, /**boolean*/useFallback) { - var dataTransfer = evt.dataTransfer, - options = this.options; - - this._offUpEvents(); - - if (activeGroup.pull == 'clone') { - cloneEl = dragEl.cloneNode(true); - _css(cloneEl, 'display', 'none'); - rootEl.insertBefore(cloneEl, dragEl); - } - - if (useFallback) { - - if (useFallback === 'touch') { - // Bind touch events - _on(document, 'touchmove', this._onTouchMove); - _on(document, 'touchend', this._onDrop); - _on(document, 'touchcancel', this._onDrop); - } else { - // Old brwoser - _on(document, 'mousemove', this._onTouchMove); - _on(document, 'mouseup', this._onDrop); - } - - this._loopId = setInterval(this._emulateDragOver, 50); - } - else { - if (dataTransfer) { - dataTransfer.effectAllowed = 'move'; - options.setData && options.setData.call(this, dataTransfer, dragEl); - } - - _on(document, 'drop', this); - setTimeout(this._dragStarted, 0); - } - }, - - _onDragOver: function (/**Event*/evt) { - var el = this.el, - target, - dragRect, - revert, - options = this.options, - group = options.group, - groupPut = group.put, - isOwner = (activeGroup === group), - canSort = options.sort; - - if (evt.preventDefault !== void 0) { - evt.preventDefault(); - !options.dragoverBubble && evt.stopPropagation(); - } - - moved = true; - - if (activeGroup && !options.disabled && - (isOwner - ? canSort || (revert = !rootEl.contains(dragEl)) // Reverting item into the original list - : activeGroup.pull && groupPut && ( - (activeGroup.name === group.name) || // by Name - (groupPut.indexOf && ~groupPut.indexOf(activeGroup.name)) // by Array - ) - ) && - (evt.rootEl === void 0 || evt.rootEl === this.el) // touch fallback - ) { - // Smart auto-scrolling - _autoScroll(evt, options, this.el); - - if (_silent) { - return; - } - - target = _closest(evt.target, options.draggable, el); - dragRect = dragEl.getBoundingClientRect(); - - if (revert) { - _cloneHide(true); - - if (cloneEl || nextEl) { - rootEl.insertBefore(dragEl, cloneEl || nextEl); - } - else if (!canSort) { - rootEl.appendChild(dragEl); - } - - return; - } - - - if ((el.children.length === 0) || (el.children[0] === ghostEl) || - (el === evt.target) && (target = _ghostIsLast(el, evt)) - ) { - - if (target) { - if (target.animated) { - return; - } - - targetRect = target.getBoundingClientRect(); - } - - _cloneHide(isOwner); - - if (_onMove(rootEl, el, dragEl, dragRect, target, targetRect) !== false) { - if (!dragEl.contains(el)) { - el.appendChild(dragEl); - parentEl = el; // actualization - } - - this._animate(dragRect, dragEl); - target && this._animate(targetRect, target); - } - } - else if (target && !target.animated && target !== dragEl && (target.parentNode[expando] !== void 0)) { - if (lastEl !== target) { - lastEl = target; - lastCSS = _css(target); - lastParentCSS = _css(target.parentNode); - } - - - var targetRect = target.getBoundingClientRect(), - width = targetRect.right - targetRect.left, - height = targetRect.bottom - targetRect.top, - floating = /left|right|inline/.test(lastCSS.cssFloat + lastCSS.display) - || (lastParentCSS.display == 'flex' && lastParentCSS['flex-direction'].indexOf('row') === 0), - isWide = (target.offsetWidth > dragEl.offsetWidth), - isLong = (target.offsetHeight > dragEl.offsetHeight), - halfway = (floating ? (evt.clientX - targetRect.left) / width : (evt.clientY - targetRect.top) / height) > 0.5, - nextSibling = target.nextElementSibling, - moveVector = _onMove(rootEl, el, dragEl, dragRect, target, targetRect), - after - ; - - if (moveVector !== false) { - _silent = true; - setTimeout(_unsilent, 30); - - _cloneHide(isOwner); - - if (moveVector === 1 || moveVector === -1) { - after = (moveVector === 1); - } - else if (floating) { - var elTop = dragEl.offsetTop, - tgTop = target.offsetTop; - - if (elTop === tgTop) { - after = (target.previousElementSibling === dragEl) && !isWide || halfway && isWide; - } else { - after = tgTop > elTop; - } - } else { - after = (nextSibling !== dragEl) && !isLong || halfway && isLong; - } - - if (!dragEl.contains(el)) { - if (after && !nextSibling) { - el.appendChild(dragEl); - } else { - target.parentNode.insertBefore(dragEl, after ? nextSibling : target); - } - } - - parentEl = dragEl.parentNode; // actualization - - this._animate(dragRect, dragEl); - this._animate(targetRect, target); - } - } - } - }, - - _animate: function (prevRect, target) { - var ms = this.options.animation; - - if (ms) { - var currentRect = target.getBoundingClientRect(); - - _css(target, 'transition', 'none'); - _css(target, 'transform', 'translate3d(' - + (prevRect.left - currentRect.left) + 'px,' - + (prevRect.top - currentRect.top) + 'px,0)' - ); - - target.offsetWidth; // repaint - - _css(target, 'transition', 'all ' + ms + 'ms'); - _css(target, 'transform', 'translate3d(0,0,0)'); - - clearTimeout(target.animated); - target.animated = setTimeout(function () { - _css(target, 'transition', ''); - _css(target, 'transform', ''); - target.animated = false; - }, ms); - } - }, - - _offUpEvents: function () { - var ownerDocument = this.el.ownerDocument; - - _off(document, 'touchmove', this._onTouchMove); - _off(ownerDocument, 'mouseup', this._onDrop); - _off(ownerDocument, 'touchend', this._onDrop); - _off(ownerDocument, 'touchcancel', this._onDrop); - }, - - _onDrop: function (/**Event*/evt) { - var el = this.el, - options = this.options; - - clearInterval(this._loopId); - clearInterval(autoScroll.pid); - clearTimeout(this._dragStartTimer); - - // Unbind events - _off(document, 'mousemove', this._onTouchMove); - - if (this.nativeDraggable) { - _off(document, 'drop', this); - _off(el, 'dragstart', this._onDragStart); - } - - this._offUpEvents(); - - if (evt) { - if (moved) { - evt.preventDefault(); - !options.dropBubble && evt.stopPropagation(); - } - - ghostEl && ghostEl.parentNode.removeChild(ghostEl); - - if (dragEl) { - if (this.nativeDraggable) { - _off(dragEl, 'dragend', this); - } - - _disableDraggable(dragEl); - - // Remove class's - _toggleClass(dragEl, this.options.ghostClass, false); - _toggleClass(dragEl, this.options.chosenClass, false); - - if (rootEl !== parentEl) { - newIndex = _index(dragEl); - - if (newIndex >= 0) { - // drag from one list and drop into another - _dispatchEvent(null, parentEl, 'sort', dragEl, rootEl, oldIndex, newIndex); - _dispatchEvent(this, rootEl, 'sort', dragEl, rootEl, oldIndex, newIndex); - - // Add event - _dispatchEvent(null, parentEl, 'add', dragEl, rootEl, oldIndex, newIndex); - - // Remove event - _dispatchEvent(this, rootEl, 'remove', dragEl, rootEl, oldIndex, newIndex); - } - } - else { - // Remove clone - cloneEl && cloneEl.parentNode.removeChild(cloneEl); - - if (dragEl.nextSibling !== nextEl) { - // Get the index of the dragged element within its parent - newIndex = _index(dragEl); - - if (newIndex >= 0) { - // drag & drop within the same list - _dispatchEvent(this, rootEl, 'update', dragEl, rootEl, oldIndex, newIndex); - _dispatchEvent(this, rootEl, 'sort', dragEl, rootEl, oldIndex, newIndex); - } - } - } - - if (Sortable.active) { - if (newIndex === null || newIndex === -1) { - newIndex = oldIndex; - } - - _dispatchEvent(this, rootEl, 'end', dragEl, rootEl, oldIndex, newIndex); - - // Save sorting - this.save(); - } - } - - // Nulling - rootEl = - dragEl = - parentEl = - ghostEl = - nextEl = - cloneEl = - - scrollEl = - scrollParentEl = - - tapEvt = - touchEvt = - - moved = - newIndex = - - lastEl = - lastCSS = - - activeGroup = - Sortable.active = null; - } - }, - - - handleEvent: function (/**Event*/evt) { - var type = evt.type; - - if (type === 'dragover' || type === 'dragenter') { - if (dragEl) { - this._onDragOver(evt); - _globalDragOver(evt); - } - } - else if (type === 'drop' || type === 'dragend') { - this._onDrop(evt); - } - }, - - - /** - * Serializes the item into an array of string. - * @returns {String[]} - */ - toArray: function () { - var order = [], - el, - children = this.el.children, - i = 0, - n = children.length, - options = this.options; - - for (; i < n; i++) { - el = children[i]; - if (_closest(el, options.draggable, this.el)) { - order.push(el.getAttribute(options.dataIdAttr) || _generateId(el)); - } - } - - return order; - }, - - - /** - * Sorts the elements according to the array. - * @param {String[]} order order of the items - */ - sort: function (order) { - var items = {}, rootEl = this.el; - - this.toArray().forEach(function (id, i) { - var el = rootEl.children[i]; - - if (_closest(el, this.options.draggable, rootEl)) { - items[id] = el; - } - }, this); - - order.forEach(function (id) { - if (items[id]) { - rootEl.removeChild(items[id]); - rootEl.appendChild(items[id]); - } - }); - }, - - - /** - * Save the current sorting - */ - save: function () { - var store = this.options.store; - store && store.set(this); - }, - - - /** - * For each element in the set, get the first element that matches the selector by testing the element itself and traversing up through its ancestors in the DOM tree. - * @param {HTMLElement} el - * @param {String} [selector] default: `options.draggable` - * @returns {HTMLElement|null} - */ - closest: function (el, selector) { - return _closest(el, selector || this.options.draggable, this.el); - }, - - - /** - * Set/get option - * @param {string} name - * @param {*} [value] - * @returns {*} - */ - option: function (name, value) { - var options = this.options; - - if (value === void 0) { - return options[name]; - } else { - options[name] = value; - - if (name === 'group') { - _prepareGroup(options); - } - } - }, - - - /** - * Destroy - */ - destroy: function () { - var el = this.el; - - el[expando] = null; - - _off(el, 'mousedown', this._onTapStart); - _off(el, 'touchstart', this._onTapStart); - - if (this.nativeDraggable) { - _off(el, 'dragover', this); - _off(el, 'dragenter', this); - } - - // Remove draggable attributes - Array.prototype.forEach.call(el.querySelectorAll('[draggable]'), function (el) { - el.removeAttribute('draggable'); - }); - - touchDragOverListeners.splice(touchDragOverListeners.indexOf(this._onDragOver), 1); - - this._onDrop(); - - this.el = el = null; - } - }; - - - function _cloneHide(state) { - if (cloneEl && (cloneEl.state !== state)) { - _css(cloneEl, 'display', state ? 'none' : ''); - !state && cloneEl.state && rootEl.insertBefore(cloneEl, dragEl); - cloneEl.state = state; - } - } - - - function _closest(/**HTMLElement*/el, /**String*/selector, /**HTMLElement*/ctx) { - if (el) { - ctx = ctx || document; - selector = selector.split('.'); - - var tag = selector.shift().toUpperCase(), - re = new RegExp('\\s(' + selector.join('|') + ')(?=\\s)', 'g'); - - do { - if ( - (tag === '>*' && el.parentNode === ctx) || ( - (tag === '' || el.nodeName.toUpperCase() == tag) && - (!selector.length || ((' ' + el.className + ' ').match(re) || []).length == selector.length) - ) - ) { - return el; - } - } - while (el !== ctx && (el = el.parentNode)); - } - - return null; - } - - - function _globalDragOver(/**Event*/evt) { - if (evt.dataTransfer) { - evt.dataTransfer.dropEffect = 'move'; - } - evt.preventDefault(); - } - - - function _on(el, event, fn) { - el.addEventListener(event, fn, false); - } - - - function _off(el, event, fn) { - el.removeEventListener(event, fn, false); - } - - - function _toggleClass(el, name, state) { - if (el) { - if (el.classList) { - el.classList[state ? 'add' : 'remove'](name); - } - else { - var className = (' ' + el.className + ' ').replace(RSPACE, ' ').replace(' ' + name + ' ', ' '); - el.className = (className + (state ? ' ' + name : '')).replace(RSPACE, ' '); - } - } - } - - - function _css(el, prop, val) { - var style = el && el.style; - - if (style) { - if (val === void 0) { - if (document.defaultView && document.defaultView.getComputedStyle) { - val = document.defaultView.getComputedStyle(el, ''); - } - else if (el.currentStyle) { - val = el.currentStyle; - } - - return prop === void 0 ? val : val[prop]; - } - else { - if (!(prop in style)) { - prop = '-webkit-' + prop; - } - - style[prop] = val + (typeof val === 'string' ? '' : 'px'); - } - } - } - - - function _find(ctx, tagName, iterator) { - if (ctx) { - var list = ctx.getElementsByTagName(tagName), i = 0, n = list.length; - - if (iterator) { - for (; i < n; i++) { - iterator(list[i], i); - } - } - - return list; - } - - return []; - } - - - - function _dispatchEvent(sortable, rootEl, name, targetEl, fromEl, startIndex, newIndex) { - var evt = document.createEvent('Event'), - options = (sortable || rootEl[expando]).options, - onName = 'on' + name.charAt(0).toUpperCase() + name.substr(1); - - evt.initEvent(name, true, true); - - evt.to = rootEl; - evt.from = fromEl || rootEl; - evt.item = targetEl || rootEl; - evt.clone = cloneEl; - - evt.oldIndex = startIndex; - evt.newIndex = newIndex; - - rootEl.dispatchEvent(evt); - - if (options[onName]) { - options[onName].call(sortable, evt); - } - } - - - function _onMove(fromEl, toEl, dragEl, dragRect, targetEl, targetRect) { - var evt, - sortable = fromEl[expando], - onMoveFn = sortable.options.onMove, - retVal; - - evt = document.createEvent('Event'); - evt.initEvent('move', true, true); - - evt.to = toEl; - evt.from = fromEl; - evt.dragged = dragEl; - evt.draggedRect = dragRect; - evt.related = targetEl || toEl; - evt.relatedRect = targetRect || toEl.getBoundingClientRect(); - - fromEl.dispatchEvent(evt); - - if (onMoveFn) { - retVal = onMoveFn.call(sortable, evt); - } - - return retVal; - } - - - function _disableDraggable(el) { - el.draggable = false; - } - - - function _unsilent() { - _silent = false; - } - - - /** @returns {HTMLElement|false} */ - function _ghostIsLast(el, evt) { - var lastEl = el.lastElementChild, - rect = lastEl.getBoundingClientRect(); - - return ((evt.clientY - (rect.top + rect.height) > 5) || (evt.clientX - (rect.right + rect.width) > 5)) && lastEl; // min delta - } - - - /** - * Generate id - * @param {HTMLElement} el - * @returns {String} - * @private - */ - function _generateId(el) { - var str = el.tagName + el.className + el.src + el.href + el.textContent, - i = str.length, - sum = 0; - - while (i--) { - sum += str.charCodeAt(i); - } - - return sum.toString(36); - } - - /** - * Returns the index of an element within its parent - * @param {HTMLElement} el - * @return {number} - */ - function _index(el) { - var index = 0; - - if (!el || !el.parentNode) { - return -1; - } - - while (el && (el = el.previousElementSibling)) { - if (el.nodeName.toUpperCase() !== 'TEMPLATE') { - index++; - } - } - - return index; - } - - function _throttle(callback, ms) { - var args, _this; - - return function () { - if (args === void 0) { - args = arguments; - _this = this; - - setTimeout(function () { - if (args.length === 1) { - callback.call(_this, args[0]); - } else { - callback.apply(_this, args); - } - - args = void 0; - }, ms); - } - }; - } - - function _extend(dst, src) { - if (dst && src) { - for (var key in src) { - if (src.hasOwnProperty(key)) { - dst[key] = src[key]; - } - } - } - - return dst; - } - - - // Export utils - Sortable.utils = { - on: _on, - off: _off, - css: _css, - find: _find, - is: function (el, selector) { - return !!_closest(el, selector, el); - }, - extend: _extend, - throttle: _throttle, - closest: _closest, - toggleClass: _toggleClass, - index: _index - }; - - - /** - * Create sortable instance - * @param {HTMLElement} el - * @param {Object} [options] - */ - Sortable.create = function (el, options) { - return new Sortable(el, options); - }; - - - // Export - Sortable.version = '1.4.2'; - return Sortable; -}); diff --git a/dashboard-ui/bower_components/Sortable/meteor/.versions b/dashboard-ui/bower_components/Sortable/meteor/.versions deleted file mode 100644 index 777e70ed92..0000000000 --- a/dashboard-ui/bower_components/Sortable/meteor/.versions +++ /dev/null @@ -1,34 +0,0 @@ -base64@1.0.3 -binary-heap@1.0.3 -blaze@2.1.2 -blaze-tools@1.0.3 -callback-hook@1.0.3 -check@1.0.5 -dburles:mongo-collection-instances@0.3.4 -ddp@1.1.0 -deps@1.0.7 -ejson@1.0.6 -geojson-utils@1.0.3 -html-tools@1.0.4 -htmljs@1.0.4 -id-map@1.0.3 -jquery@1.11.3_2 -json@1.0.3 -lai:collection-extensions@0.1.4 -local-test:rubaxa:sortable@1.2.1 -logging@1.0.7 -meteor@1.1.6 -minifiers@1.1.5 -minimongo@1.0.8 -mongo@1.1.0 -observe-sequence@1.0.6 -ordered-dict@1.0.3 -random@1.0.3 -reactive-var@1.0.5 -retry@1.0.3 -rubaxa:sortable@1.2.1 -spacebars-compiler@1.0.6 -templating@1.1.1 -tinytest@1.0.5 -tracker@1.0.7 -underscore@1.0.3 diff --git a/dashboard-ui/bower_components/Sortable/meteor/example/.meteor/.finished-upgraders b/dashboard-ui/bower_components/Sortable/meteor/example/.meteor/.finished-upgraders deleted file mode 100644 index 8a761038c5..0000000000 --- a/dashboard-ui/bower_components/Sortable/meteor/example/.meteor/.finished-upgraders +++ /dev/null @@ -1,8 +0,0 @@ -# This file contains information which helps Meteor properly upgrade your -# app when you run 'meteor update'. You should check it into version control -# with your project. - -notices-for-0.9.0 -notices-for-0.9.1 -0.9.4-platform-file -notices-for-facebook-graph-api-2 diff --git a/dashboard-ui/bower_components/Sortable/meteor/example/.meteor/.gitignore b/dashboard-ui/bower_components/Sortable/meteor/example/.meteor/.gitignore deleted file mode 100644 index 4083037423..0000000000 --- a/dashboard-ui/bower_components/Sortable/meteor/example/.meteor/.gitignore +++ /dev/null @@ -1 +0,0 @@ -local diff --git a/dashboard-ui/bower_components/Sortable/meteor/example/.meteor/.id b/dashboard-ui/bower_components/Sortable/meteor/example/.meteor/.id deleted file mode 100644 index b39baa1d8d..0000000000 --- a/dashboard-ui/bower_components/Sortable/meteor/example/.meteor/.id +++ /dev/null @@ -1,7 +0,0 @@ -# This file contains a token that is unique to your project. -# Check it into your repository along with the rest of this directory. -# It can be used for purposes such as: -# - ensuring you don't accidentally deploy one app on top of another -# - providing package authors with aggregated statistics - -ir0jg2douy3yo5mehw diff --git a/dashboard-ui/bower_components/Sortable/meteor/example/.meteor/packages b/dashboard-ui/bower_components/Sortable/meteor/example/.meteor/packages deleted file mode 100644 index 6f65fb7c45..0000000000 --- a/dashboard-ui/bower_components/Sortable/meteor/example/.meteor/packages +++ /dev/null @@ -1,10 +0,0 @@ -# Meteor packages used by this project, one per line. -# -# 'meteor add' and 'meteor remove' will edit this file for you, -# but you can also edit it by hand. - -meteor-platform -autopublish -insecure -rubaxa:sortable -fezvrasta:bootstrap-material-design diff --git a/dashboard-ui/bower_components/Sortable/meteor/example/.meteor/platforms b/dashboard-ui/bower_components/Sortable/meteor/example/.meteor/platforms deleted file mode 100644 index 8a3a35f9f6..0000000000 --- a/dashboard-ui/bower_components/Sortable/meteor/example/.meteor/platforms +++ /dev/null @@ -1,2 +0,0 @@ -browser -server diff --git a/dashboard-ui/bower_components/Sortable/meteor/example/.meteor/release b/dashboard-ui/bower_components/Sortable/meteor/example/.meteor/release deleted file mode 100644 index 315c635bf3..0000000000 --- a/dashboard-ui/bower_components/Sortable/meteor/example/.meteor/release +++ /dev/null @@ -1 +0,0 @@ -METEOR@1.1.0.3 diff --git a/dashboard-ui/bower_components/Sortable/meteor/example/.meteor/versions b/dashboard-ui/bower_components/Sortable/meteor/example/.meteor/versions deleted file mode 100644 index a65be54d9a..0000000000 --- a/dashboard-ui/bower_components/Sortable/meteor/example/.meteor/versions +++ /dev/null @@ -1,53 +0,0 @@ -autopublish@1.0.3 -autoupdate@1.2.1 -base64@1.0.3 -binary-heap@1.0.3 -blaze@2.1.2 -blaze-tools@1.0.3 -boilerplate-generator@1.0.3 -callback-hook@1.0.3 -check@1.0.5 -dburles:mongo-collection-instances@0.3.4 -ddp@1.1.0 -deps@1.0.7 -ejson@1.0.6 -fastclick@1.0.3 -fezvrasta:bootstrap-material-design@0.3.0 -geojson-utils@1.0.3 -html-tools@1.0.4 -htmljs@1.0.4 -http@1.1.0 -id-map@1.0.3 -insecure@1.0.3 -jquery@1.11.3_2 -json@1.0.3 -lai:collection-extensions@0.1.4 -launch-screen@1.0.2 -livedata@1.0.13 -logging@1.0.7 -meteor@1.1.6 -meteor-platform@1.2.2 -minifiers@1.1.5 -minimongo@1.0.8 -mobile-status-bar@1.0.3 -mongo@1.1.0 -observe-sequence@1.0.6 -ordered-dict@1.0.3 -random@1.0.3 -reactive-dict@1.1.0 -reactive-var@1.0.5 -reload@1.1.3 -retry@1.0.3 -routepolicy@1.0.5 -rubaxa:sortable@1.2.1 -session@1.1.0 -spacebars@1.0.6 -spacebars-compiler@1.0.6 -templating@1.1.1 -tracker@1.0.7 -twbs:bootstrap@3.3.5 -ui@1.0.6 -underscore@1.0.3 -url@1.0.4 -webapp@1.2.0 -webapp-hashing@1.0.3 diff --git a/dashboard-ui/bower_components/Sortable/meteor/example/client/define-object-type.css b/dashboard-ui/bower_components/Sortable/meteor/example/client/define-object-type.css deleted file mode 100644 index d67b4b1d74..0000000000 --- a/dashboard-ui/bower_components/Sortable/meteor/example/client/define-object-type.css +++ /dev/null @@ -1,57 +0,0 @@ -.glyphicon { - vertical-align: baseline; - font-size: 80%; - margin-right: 0.5em; -} - -[class^="mdi-"], [class*=" mdi-"] { - vertical-align: baseline; - font-size: 90%; - margin-right: 0.4em; -} - -.list-pair { - display: flex; /* use the flexbox model */ - flex-direction: row; -} -.sortable { -/* font-size: 2em;*/ -} - -.sortable.source { - /*background: #9FA8DA;*/ - flex: 0 0 auto; - margin-right: 1em; - cursor: move; - cursor: -webkit-grabbing; -} - -.sortable.target { - /*background: #3F51B5;*/ - flex: 1 1 auto; - margin-left: 1em; -} - -.target .well { - -} - -.sortable-handle { - cursor: move; - cursor: -webkit-grabbing; -} -.sortable-handle.pull-right { - margin-top: 0.3em; -} - -.sortable-ghost { - opacity: 0.6; -} - -/* show the remove button on hover */ -.removable .close { - display: none; -} -.removable:hover .close { - display: block; -} diff --git a/dashboard-ui/bower_components/Sortable/meteor/example/client/define-object-type.html b/dashboard-ui/bower_components/Sortable/meteor/example/client/define-object-type.html deleted file mode 100644 index d852cbcb5a..0000000000 --- a/dashboard-ui/bower_components/Sortable/meteor/example/client/define-object-type.html +++ /dev/null @@ -1,94 +0,0 @@ - - Reactive RubaXa:Sortable for Meteor - - - - {{> navbar}} - -
- - - {{> typeDefinition}} -
- - - - - - - - \ No newline at end of file diff --git a/dashboard-ui/bower_components/Sortable/meteor/example/client/define-object-type.js b/dashboard-ui/bower_components/Sortable/meteor/example/client/define-object-type.js deleted file mode 100644 index ad2a19e2a0..0000000000 --- a/dashboard-ui/bower_components/Sortable/meteor/example/client/define-object-type.js +++ /dev/null @@ -1,101 +0,0 @@ -// Define an object type by dragging together attributes - -Template.typeDefinition.helpers({ - types: function () { - return Types.find({}, { sort: { order: 1 } }); - }, - typesOptions: { - sortField: 'order', // defaults to 'order' anyway - group: { - name: 'typeDefinition', - pull: 'clone', - put: false - }, - sort: false // don't allow reordering the types, just the attributes below - }, - - attributes: function () { - return Attributes.find({}, { - sort: { order: 1 }, - transform: function (doc) { - doc.icon = Types.findOne({name: doc.type}).icon; - return doc; - } - }); - }, - attributesOptions: { - group: { - name: 'typeDefinition', - put: true - }, - onAdd: function (event) { - delete event.data._id; // Generate a new id when inserting in the Attributes collection. Otherwise, if we add the same type twice, we'll get an error that the ids are not unique. - delete event.data.icon; - event.data.type = event.data.name; - event.data.name = 'Rename me (double click)' - }, - // event handler for reordering attributes - onSort: function (event) { - console.log('Item %s went from #%d to #%d', - event.data.name, event.oldIndex, event.newIndex - ); - } - } -}); - -Template.sortableItemTarget.events({ - 'dblclick .name': function (event, template) { - // Make the name editable. We should use an existing component, but it's - // in a sorry state - https://github.com/arillo/meteor-x-editable/issues/1 - var name = template.$('.name'); - var input = template.$('input'); - if (input.length) { // jQuery never returns null - http://stackoverflow.com/questions/920236/how-can-i-detect-if-a-selector-returns-null - input.show(); - } else { - input = $(''); - name.after(input); - } - name.hide(); - input.focus(); - }, - 'blur input[type=text]': function (event, template) { - // commit the change to the name, if any - var input = template.$('input'); - input.hide(); - template.$('.name').show(); - // TODO - what is the collection here? We'll hard-code for now. - // https://github.com/meteor/meteor/issues/3303 - if (this.name !== input.val() && this.name !== '') - Attributes.update(this._id, {$set: {name: input.val()}}); - }, - 'keydown input[type=text]': function (event, template) { - if (event.which === 27) { - // ESC - discard edits and keep existing value - template.$('input').val(this.name); - event.preventDefault(); - event.target.blur(); - } else if (event.which === 13) { - // ENTER - event.preventDefault(); - event.target.blur(); - } - } -}); - -// you can add events to all Sortable template instances -Template.sortable.events({ - 'click .close': function (event, template) { - // `this` is the data context set by the enclosing block helper (#each, here) - template.collection.remove(this._id); - // custom code, working on a specific collection - if (Attributes.find().count() === 0) { - Meteor.setTimeout(function () { - Attributes.insert({ - name: 'Not nice to delete the entire list! Add some attributes instead.', - type: 'String', - order: 0 - }) - }, 1000); - } - } -}); diff --git a/dashboard-ui/bower_components/Sortable/meteor/example/model.js b/dashboard-ui/bower_components/Sortable/meteor/example/model.js deleted file mode 100644 index 8ae88226ae..0000000000 --- a/dashboard-ui/bower_components/Sortable/meteor/example/model.js +++ /dev/null @@ -1,2 +0,0 @@ -Types = new Mongo.Collection('types'); -Attributes = new Mongo.Collection('attributes'); diff --git a/dashboard-ui/bower_components/Sortable/meteor/example/run.bat b/dashboard-ui/bower_components/Sortable/meteor/example/run.bat deleted file mode 100644 index b2a0d8b4e6..0000000000 --- a/dashboard-ui/bower_components/Sortable/meteor/example/run.bat +++ /dev/null @@ -1,7 +0,0 @@ -@echo off -REM Sanity check: make sure we're in the directory of the script -set DIR=%~dp0 -cd %DIR% - -set PACKAGE_DIRS=..\..\ -meteor run %* diff --git a/dashboard-ui/bower_components/Sortable/meteor/example/run.sh b/dashboard-ui/bower_components/Sortable/meteor/example/run.sh deleted file mode 100644 index 8a9123ae38..0000000000 --- a/dashboard-ui/bower_components/Sortable/meteor/example/run.sh +++ /dev/null @@ -1,5 +0,0 @@ -# sanity check: make sure we're in the root directory of the example -cd "$( dirname "$0" )" - -# let Meteor find the local package -PACKAGE_DIRS=../../ meteor run "$@" diff --git a/dashboard-ui/bower_components/Sortable/meteor/example/server/fixtures.js b/dashboard-ui/bower_components/Sortable/meteor/example/server/fixtures.js deleted file mode 100644 index 617acf948c..0000000000 --- a/dashboard-ui/bower_components/Sortable/meteor/example/server/fixtures.js +++ /dev/null @@ -1,75 +0,0 @@ -Meteor.startup(function () { - if (Types.find().count() === 0) { - [ - { - name: 'String', - icon: '' - }, - { - name: 'Text, multi-line', - icon: '' - }, - { - name: 'Category', - icon: '' - }, - { - name: 'Number', - icon: '' - }, - { - name: 'Date', - icon: '' - }, - { - name: 'Hyperlink', - icon: '' - }, - { - name: 'Image', - icon: '' - }, - { - name: 'Progress', - icon: '' - }, - { - name: 'Duration', - icon: '' - }, - { - name: 'Map address', - icon: '' - }, - { - name: 'Relationship', - icon: '' - } - ].forEach(function (type, i) { - Types.insert({ - name: type.name, - icon: type.icon, - order: i - }); - } - ); - console.log('Initialized attribute types.'); - } - - if (Attributes.find().count() === 0) { - [ - { name: 'Name', type: 'String' }, - { name: 'Created at', type: 'Date' }, - { name: 'Link', type: 'Hyperlink' }, - { name: 'Owner', type: 'Relationship' } - ].forEach(function (attribute, i) { - Attributes.insert({ - name: attribute.name, - type: attribute.type, - order: i - }); - } - ); - console.log('Created sample object type.'); - } -}); diff --git a/dashboard-ui/bower_components/Sortable/meteor/example/server/sortable-collections.js b/dashboard-ui/bower_components/Sortable/meteor/example/server/sortable-collections.js deleted file mode 100644 index 76069a5922..0000000000 --- a/dashboard-ui/bower_components/Sortable/meteor/example/server/sortable-collections.js +++ /dev/null @@ -1,3 +0,0 @@ -'use strict'; - -Sortable.collections = ['attributes']; diff --git a/dashboard-ui/bower_components/Sortable/meteor/methods-client.js b/dashboard-ui/bower_components/Sortable/meteor/methods-client.js deleted file mode 100644 index 52f4ebec2e..0000000000 --- a/dashboard-ui/bower_components/Sortable/meteor/methods-client.js +++ /dev/null @@ -1,16 +0,0 @@ -'use strict'; - -Meteor.methods({ - /** - * Update the sortField of documents with given ids in a collection, incrementing it by incDec - * @param {String} collectionName - name of the collection to update - * @param {String[]} ids - array of document ids - * @param {String} orderField - the name of the order field, usually "order" - * @param {Number} incDec - pass 1 or -1 - */ - 'rubaxa:sortable/collection-update': function (collectionName, ids, sortField, incDec) { - var selector = {_id: {$in: ids}}, modifier = {$inc: {}}; - modifier.$inc[sortField] = incDec; - Mongo.Collection.get(collectionName).update(selector, modifier, {multi: true}); - } -}); diff --git a/dashboard-ui/bower_components/Sortable/meteor/methods-server.js b/dashboard-ui/bower_components/Sortable/meteor/methods-server.js deleted file mode 100644 index 9598bfc992..0000000000 --- a/dashboard-ui/bower_components/Sortable/meteor/methods-server.js +++ /dev/null @@ -1,31 +0,0 @@ -'use strict'; - -Sortable = {}; -Sortable.collections = []; // array of collection names that the client is allowed to reorder - -Meteor.methods({ - /** - * Update the sortField of documents with given ids in a collection, incrementing it by incDec - * @param {String} collectionName - name of the collection to update - * @param {String[]} ids - array of document ids - * @param {String} orderField - the name of the order field, usually "order" - * @param {Number} incDec - pass 1 or -1 - */ - 'rubaxa:sortable/collection-update': function (collectionName, ids, sortField, incDec) { - check(collectionName, String); - // don't allow the client to modify just any collection - if (!Sortable || !Array.isArray(Sortable.collections)) { - throw new Meteor.Error(500, 'Please define Sortable.collections'); - } - if (Sortable.collections.indexOf(collectionName) === -1) { - throw new Meteor.Error(403, 'Collection <' + collectionName + '> is not Sortable. Please add it to Sortable.collections in server code.'); - } - - check(ids, [String]); - check(sortField, String); - check(incDec, Number); - var selector = {_id: {$in: ids}}, modifier = {$inc: {}}; - modifier.$inc[sortField] = incDec; - Mongo.Collection.get(collectionName).update(selector, modifier, {multi: true}); - } -}); diff --git a/dashboard-ui/bower_components/Sortable/meteor/package.js b/dashboard-ui/bower_components/Sortable/meteor/package.js deleted file mode 100644 index aaa048eea4..0000000000 --- a/dashboard-ui/bower_components/Sortable/meteor/package.js +++ /dev/null @@ -1,85 +0,0 @@ -// Package metadata file for Meteor.js -'use strict'; - -var packageName = 'rubaxa:sortable'; // https://atmospherejs.com/rubaxa/sortable -var gitHubPath = 'RubaXa/Sortable'; // https://github.com/RubaXa/Sortable -var npmPackageName = 'sortablejs'; // https://www.npmjs.com/package/sortablejs - optional but recommended; used as fallback if GitHub fails - -/* All of the below is just to get the version number of the 3rd party library. - * First we'll try to read it from package.json. This works when publishing or testing the package - * but not when running an example app that uses a local copy of the package because the current - * directory will be that of the app, and it won't have package.json. Finding the path of a file is hard: - * http://stackoverflow.com/questions/27435797/how-do-i-obtain-the-path-of-a-file-in-a-meteor-package - * Therefore, we'll fall back to GitHub (which is more frequently updated), and then to NPMJS. - * We also don't have the HTTP package at this stage, and if we use Package.* in the request() callback, - * it will error that it must be run in a Fiber. So we'll use Node futures. - */ -var request = Npm.require('request'); -var Future = Npm.require('fibers/future'); - -var fut = new Future; -var version; - -if (!version) try { - var packageJson = JSON.parse(Npm.require('fs').readFileSync('../package.json')); - version = packageJson.version; -} catch (e) { - // if the file was not found, fall back to GitHub - console.warn('Could not find ../package.json to read version number from; trying GitHub...'); - var url = 'https://api.github.com/repos/' + gitHubPath + '/tags'; - request.get({ - url: url, - headers: { - 'User-Agent': 'request' // GitHub requires it - } - }, function (error, response, body) { - if (!error && response.statusCode === 200) { - var versions = JSON.parse(body).map(function (version) { - return version['name'].replace(/^\D+/, '') // trim leading non-digits from e.g. "v4.3.0" - }).sort(); - fut.return(versions[versions.length -1]); - } else { - // GitHub API rate limit reached? Fall back to npmjs. - console.warn('GitHub request to', url, 'failed:\n ', response && response.statusCode, response && response.body, error || '', '\nTrying NPMJS...'); - url = 'http://registry.npmjs.org/' + npmPackageName + '/latest'; - request.get(url, function (error, response, body) { - if (!error && response.statusCode === 200) - fut.return(JSON.parse(body).version); - else - fut.throw('Could not get version information from ' + url + ' either (incorrect package name?):\n' + (response && response.statusCode || '') + (response && response.body || '') + (error || '')); - }); - } - }); - - version = fut.wait(); -} - -// Now that we finally have an accurate version number... -Package.describe({ - name: packageName, - summary: 'Sortable: reactive minimalist reorderable drag-and-drop lists on modern browsers and touch devices', - version: version, - git: 'https://github.com/RubaXa/Sortable.git', - documentation: 'README.md' -}); - -Package.onUse(function (api) { - api.versionsFrom(['METEOR@0.9.0', 'METEOR@1.0']); - api.use('templating', 'client'); - api.use('dburles:mongo-collection-instances@0.3.4'); // to watch collections getting created - api.export('Sortable'); // exported on the server too, as a global to hold the array of sortable collections (for security) - api.addFiles([ - '../Sortable.js', - 'template.html', // the HTML comes first, so reactivize.js can refer to the template in it - 'reactivize.js' - ], 'client'); - api.addFiles('methods-client.js', 'client'); - api.addFiles('methods-server.js', 'server'); -}); - -Package.onTest(function (api) { - api.use(packageName, 'client'); - api.use('tinytest', 'client'); - - api.addFiles('test.js', 'client'); -}); diff --git a/dashboard-ui/bower_components/Sortable/meteor/publish.sh b/dashboard-ui/bower_components/Sortable/meteor/publish.sh deleted file mode 100644 index af392cac1c..0000000000 --- a/dashboard-ui/bower_components/Sortable/meteor/publish.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/bin/bash -# Publish package to Meteor's repository, Atmospherejs.com - -# Make sure Meteor is installed, per https://www.meteor.com/install. -# The curl'ed script is totally safe; takes 2 minutes to read its source and check. -type meteor >/dev/null 2>&1 || { curl https://install.meteor.com/ | sh; } - -# sanity check: make sure we're in the directory of the script -cd "$( dirname "$0" )" - -# publish package, creating it if it's the first time we're publishing -PACKAGE_NAME=$(grep -i name package.js | head -1 | cut -d "'" -f 2) - -echo "Publishing $PACKAGE_NAME..." - -# Attempt to re-publish the package - the most common operation once the initial release has -# been made. If the package name was changed (rare), you'll have to pass the --create flag. -meteor publish "$@"; EXIT_CODE=$? -if (( $EXIT_CODE == 0 )); then - echo "Thanks for releasing a new version. You can see it at" - echo "https://atmospherejs.com/${PACKAGE_NAME/://}" -else - echo "We have an error. Please post it at https://github.com/RubaXa/Sortable/issues" -fi - -exit $EXIT_CODE diff --git a/dashboard-ui/bower_components/Sortable/meteor/reactivize.js b/dashboard-ui/bower_components/Sortable/meteor/reactivize.js deleted file mode 100644 index ae7ff4b8d9..0000000000 --- a/dashboard-ui/bower_components/Sortable/meteor/reactivize.js +++ /dev/null @@ -1,201 +0,0 @@ -/* -Make a Sortable reactive by binding it to a Mongo.Collection. -Calls `rubaxa:sortable/collection-update` on the server to update the sortField of affected records. - -TODO: - * supply consecutive values if the `order` field doesn't have any - * .get(DOMElement) - return the Sortable object of a DOMElement - * create a new _id automatically onAdd if the event.from list had pull: 'clone' - * support arrays - * sparse arrays - * tests - * drop onto existing empty lists - * insert back into lists emptied by dropping - * performance on dragging into long list at the beginning - * handle failures on Collection operations, e.g. add callback to .insert - * when adding elements, update ranks just for the half closer to the start/end of the list - * revisit http://programmers.stackexchange.com/questions/266451/maintain-ordered-collection-by-updating-as-few-order-fields-as-possible - * reproduce the insidious bug where the list isn't always sorted (fiddle with dragging #1 over #2, then back, then #N before #1) - - */ - -'use strict'; - -Template.sortable.created = function () { - var templateInstance = this; - // `this` is a template instance that can store properties of our choice - http://docs.meteor.com/#/full/template_inst - if (templateInstance.setupDone) return; // paranoid: only run setup once - // this.data is the data context - http://docs.meteor.com/#/full/template_data - // normalize all options into templateInstance.options, and remove them from .data - templateInstance.options = templateInstance.data.options || {}; - Object.keys(templateInstance.data).forEach(function (key) { - if (key === 'options' || key === 'items') return; - templateInstance.options[key] = templateInstance.data[key]; - delete templateInstance.data[key]; - }); - templateInstance.options.sortField = templateInstance.options.sortField || 'order'; - // We can get the collection via the .collection property of the cursor, but changes made that way - // will NOT be sent to the server - https://github.com/meteor/meteor/issues/3271#issuecomment-66656257 - // Thus we need to use dburles:mongo-collection-instances to get a *real* collection - if (templateInstance.data.items && templateInstance.data.items.collection) { - // cursor passed via items=; its .collection works client-only and has a .name property - templateInstance.collectionName = templateInstance.data.items.collection.name; - templateInstance.collection = Mongo.Collection.get(templateInstance.collectionName); - } else if (templateInstance.data.items) { - // collection passed via items=; does NOT have a .name property, but _name - templateInstance.collection = templateInstance.data.items; - templateInstance.collectionName = templateInstance.collection._name; - } else if (templateInstance.data.collection) { - // cursor passed directly - templateInstance.collectionName = templateInstance.data.collection.name; - templateInstance.collection = Mongo.Collection.get(templateInstance.collectionName); - } else { - templateInstance.collection = templateInstance.data; // collection passed directly - templateInstance.collectionName = templateInstance.collection._name; - } - - // TODO if (Array.isArray(templateInstance.collection)) - - // What if user filters some of the items in the cursor, instead of ordering the entire collection? - // Use case: reorder by preference movies of a given genre, a filter within all movies. - // A: Modify all intervening items **that are on the client**, to preserve the overall order - // TODO: update *all* orders via a server method that takes not ids, but start & end elements - mild security risk - delete templateInstance.data.options; - - /** - * When an element was moved, adjust its orders and possibly the order of - * other elements, so as to maintain a consistent and correct order. - * - * There are three approaches to this: - * 1) Using arbitrary precision arithmetic and setting only the order of the moved - * element to the average of the orders of the elements around it - - * http://programmers.stackexchange.com/questions/266451/maintain-ordered-collection-by-updating-as-few-order-fields-as-possible - * The downside is that the order field in the DB will increase by one byte every - * time an element is reordered. - * 2) Adjust the orders of the intervening items. This keeps the orders sane (integers) - * but is slower because we have to modify multiple documents. - * TODO: we may be able to update fewer records by only altering the - * order of the records between the newIndex/oldIndex and the start/end of the list. - * 3) Use regular precision arithmetic, but when the difference between the orders of the - * moved item and the one before/after it falls below a certain threshold, adjust - * the order of that other item, and cascade doing so up or down the list. - * This will keep the `order` field constant in size, and will only occasionally - * require updating the `order` of other records. - * - * For now, we use approach #2. - * - * @param {String} itemId - the _id of the item that was moved - * @param {Number} orderPrevItem - the order of the item before it, or null - * @param {Number} orderNextItem - the order of the item after it, or null - */ - templateInstance.adjustOrders = function adjustOrders(itemId, orderPrevItem, orderNextItem) { - var orderField = templateInstance.options.sortField; - var selector = templateInstance.options.selector || {}, modifier = {$set: {}}; - var ids = []; - var startOrder = templateInstance.collection.findOne(itemId)[orderField]; - if (orderPrevItem !== null) { - // Element has a previous sibling, therefore it was moved down in the list. - // Decrease the order of intervening elements. - selector[orderField] = {$lte: orderPrevItem, $gt: startOrder}; - ids = _.pluck(templateInstance.collection.find(selector, {fields: {_id: 1}}).fetch(), '_id'); - Meteor.call('rubaxa:sortable/collection-update', templateInstance.collectionName, ids, orderField, -1); - - // Set the order of the dropped element to the order of its predecessor, whose order was decreased - modifier.$set[orderField] = orderPrevItem; - } else { - // element moved up the list, increase order of intervening elements - selector[orderField] = {$gte: orderNextItem, $lt: startOrder}; - ids = _.pluck(templateInstance.collection.find(selector, {fields: {_id: 1}}).fetch(), '_id'); - Meteor.call('rubaxa:sortable/collection-update', templateInstance.collectionName, ids, orderField, 1); - - // Set the order of the dropped element to the order of its successor, whose order was increased - modifier.$set[orderField] = orderNextItem; - } - templateInstance.collection.update(itemId, modifier); - }; - - templateInstance.setupDone = true; -}; - - -Template.sortable.rendered = function () { - var templateInstance = this; - var orderField = templateInstance.options.sortField; - - // sorting was changed within the list - var optionsOnUpdate = templateInstance.options.onUpdate; - templateInstance.options.onUpdate = function sortableUpdate(/**Event*/event) { - var itemEl = event.item; // dragged HTMLElement - event.data = Blaze.getData(itemEl); - if (event.newIndex < event.oldIndex) { - // Element moved up in the list. The dropped element has a next sibling for sure. - var orderNextItem = Blaze.getData(itemEl.nextElementSibling)[orderField]; - templateInstance.adjustOrders(event.data._id, null, orderNextItem); - } else if (event.newIndex > event.oldIndex) { - // Element moved down in the list. The dropped element has a previous sibling for sure. - var orderPrevItem = Blaze.getData(itemEl.previousElementSibling)[orderField]; - templateInstance.adjustOrders(event.data._id, orderPrevItem, null); - } else { - // do nothing - drag and drop in the same location - } - if (optionsOnUpdate) optionsOnUpdate(event); - }; - - // element was added from another list - var optionsOnAdd = templateInstance.options.onAdd; - templateInstance.options.onAdd = function sortableAdd(/**Event*/event) { - var itemEl = event.item; // dragged HTMLElement - event.data = Blaze.getData(itemEl); - // let the user decorate the object with additional properties before insertion - if (optionsOnAdd) optionsOnAdd(event); - - // Insert the new element at the end of the list and move it where it was dropped. - // We could insert it at the beginning, but that would lead to negative orders. - var sortSpecifier = {}; sortSpecifier[orderField] = -1; - event.data.order = templateInstance.collection.findOne({}, { sort: sortSpecifier, limit: 1 }).order + 1; - // TODO: this can obviously be optimized by setting the order directly as the arithmetic average, with the caveats described above - var newElementId = templateInstance.collection.insert(event.data); - event.data._id = newElementId; - if (itemEl.nextElementSibling) { - var orderNextItem = Blaze.getData(itemEl.nextElementSibling)[orderField]; - templateInstance.adjustOrders(newElementId, null, orderNextItem); - } else { - // do nothing - inserted after the last element - } - // remove the dropped HTMLElement from the list because we have inserted it in the collection, which will update the template - itemEl.parentElement.removeChild(itemEl); - }; - - // element was removed by dragging into another list - var optionsOnRemove = templateInstance.options.onRemove; - templateInstance.options.onRemove = function sortableRemove(/**Event*/event) { - var itemEl = event.item; // dragged HTMLElement - event.data = Blaze.getData(itemEl); - // don't remove from the collection if group.pull is clone or false - if (typeof templateInstance.options.group === 'undefined' - || typeof templateInstance.options.group.pull === 'undefined' - || templateInstance.options.group.pull === true - ) templateInstance.collection.remove(event.data._id); - if (optionsOnRemove) optionsOnRemove(event); - }; - - // just compute the `data` context - ['onStart', 'onEnd', 'onSort', 'onFilter'].forEach(function (eventHandler) { - if (templateInstance.options[eventHandler]) { - var userEventHandler = templateInstance.options[eventHandler]; - templateInstance.options[eventHandler] = function (/**Event*/event) { - var itemEl = event.item; // dragged HTMLElement - event.data = Blaze.getData(itemEl); - userEventHandler(event); - }; - } - }); - - templateInstance.sortable = Sortable.create(templateInstance.firstNode.parentElement, templateInstance.options); - // TODO make the object accessible, e.g. via Sortable.getSortableById() or some such -}; - - -Template.sortable.destroyed = function () { - if(this.sortable) this.sortable.destroy(); -}; diff --git a/dashboard-ui/bower_components/Sortable/meteor/runtests.bat b/dashboard-ui/bower_components/Sortable/meteor/runtests.bat deleted file mode 100644 index 9bddf93487..0000000000 --- a/dashboard-ui/bower_components/Sortable/meteor/runtests.bat +++ /dev/null @@ -1,8 +0,0 @@ -@echo off -REM Test Meteor package before publishing to Atmospherejs.com - -REM Sanity check: make sure we're in the directory of the script -set DIR=%~dp0 -cd %DIR% - -meteor test-packages ./ %* diff --git a/dashboard-ui/bower_components/Sortable/meteor/runtests.sh b/dashboard-ui/bower_components/Sortable/meteor/runtests.sh deleted file mode 100644 index 0e738a7e89..0000000000 --- a/dashboard-ui/bower_components/Sortable/meteor/runtests.sh +++ /dev/null @@ -1,35 +0,0 @@ -#!/bin/sh -# Test Meteor package before publishing to Atmospherejs.com - -# Make sure Meteor is installed, per https://www.meteor.com/install. -# The curl'ed script is totally safe; takes 2 minutes to read its source and check. -type meteor >/dev/null 2>&1 || { curl https://install.meteor.com/ | sh; } - -# sanity check: make sure we're in the directory of the script -cd "$( dirname "$0" )" - - -# delete the temporary files even if Ctrl+C is pressed -int_trap() { - printf "\nTests interrupted. Cleaning up...\n\n" -} -trap int_trap INT - - -EXIT_CODE=0 - -PACKAGE_NAME=$(grep -i name package.js | head -1 | cut -d "'" -f 2) - -echo "### Testing $PACKAGE_NAME..." - -# provide an invalid MONGO_URL so Meteor doesn't bog us down with an empty Mongo database -if [ $# -gt 0 ]; then - # interpret any parameter to mean we want an interactive test - MONGO_URL=mongodb:// meteor test-packages ./ -else - # automated/CI test with phantomjs - ./node_modules/.bin/spacejam --mongo-url mongodb:// test-packages ./ - EXIT_CODE=$(( $EXIT_CODE + $? )) -fi - -exit $EXIT_CODE diff --git a/dashboard-ui/bower_components/Sortable/meteor/template.html b/dashboard-ui/bower_components/Sortable/meteor/template.html deleted file mode 100644 index 3923d3d9cc..0000000000 --- a/dashboard-ui/bower_components/Sortable/meteor/template.html +++ /dev/null @@ -1,5 +0,0 @@ - diff --git a/dashboard-ui/bower_components/Sortable/meteor/test.js b/dashboard-ui/bower_components/Sortable/meteor/test.js deleted file mode 100644 index f7c00a9fbf..0000000000 --- a/dashboard-ui/bower_components/Sortable/meteor/test.js +++ /dev/null @@ -1,9 +0,0 @@ -'use strict'; - -Tinytest.add('Sortable.is', function (test) { - var items = document.createElement('ul'); - items.innerHTML = '
  • item 1
  • item 2
  • item 3
  • '; - var sortable = new Sortable(items); - test.instanceOf(sortable, Sortable, 'Instantiation OK'); - test.length(sortable.toArray(), 3, 'Three elements'); -}); diff --git a/dashboard-ui/bower_components/Sortable/st/app.css b/dashboard-ui/bower_components/Sortable/st/app.css deleted file mode 100644 index 6a97f8e496..0000000000 --- a/dashboard-ui/bower_components/Sortable/st/app.css +++ /dev/null @@ -1,239 +0,0 @@ -html { - background-image: -webkit-linear-gradient(bottom, #F4E2C9 20%, #F4D7C9 100%); - background-image: -ms-linear-gradient(bottom, #F4E2C9 20%, #F4D7C9 100%); - background-image: linear-gradient(to bottom, #F4E2C9 20%, #F4D7C9 100%); -} - -html, body { - margin: 0; - padding: 0; - position: relative; - color: #464637; - min-height: 100%; - font-size: 20px; - font-family: 'Roboto', sans-serif; - font-weight: 300; -} - - -h1 { - color: #FF3F00; - font-size: 20px; - font-family: 'Roboto', sans-serif; - font-weight: 300; - text-align: center; -} - - -ul { - margin: 0; - padding: 0; - list-style: none; -} - -.container { - width: 80%; - margin: auto; - min-width: 1100px; - max-width: 1300px; - position: relative; -} - -@media (min-width: 750px) and (max-width: 970px){ - .container { - width: 100%; - min-width: 750px; - } -} - - -.sortable-ghost { - opacity: .2; -} - - -img { - border: 0; - vertical-align: middle; -} - - -.logo { - top: 55px; - left: 30px; - position: absolute; -} - - -.title { - color: #fff; - padding: 3px 10px; - display: inline-block; - position: relative; - background-color: #FF7373; - z-index: 1000; -} - .title_xl { - padding: 3px 15px; - font-size: 40px; - } - - - -.tile { - width: 22%; - min-width: 245px; - color: #FF7270; - padding: 10px 30px; - text-align: center; - margin-top: 15px; - margin-left: 5px; - margin-right: 30px; - background-color: #fff; - display: inline-block; - vertical-align: top; -} - .tile__name { - cursor: move; - padding-bottom: 10px; - border-bottom: 1px solid #FF7373; - } - - .tile__list { - margin-top: 10px; - } - .tile__list:last-child { - margin-right: 0; - min-height: 80px; - } - - .tile__list img { - cursor: move; - margin: 10px; - border-radius: 100%; - } - - - -.block { - opacity: 1; - position: absolute; -} - .block__list { - padding: 20px 0; - max-width: 360px; - margin-top: -8px; - margin-left: 5px; - background-color: #fff; - } - .block__list-title { - margin: -20px 0 0; - padding: 10px; - text-align: center; - background: #5F9EDF; - } - .block__list li { cursor: move; } - - .block__list_words li { - background-color: #fff; - padding: 10px 40px; - } - .block__list_words .sortable-ghost { - opacity: 0.4; - background-color: #F4E2C9; - } - - .block__list_words li:first-letter { - text-transform: uppercase; - } - - .block__list_tags { - padding-left: 30px; - } - - .block__list_tags:after { - clear: both; - content: ''; - display: block; - } - .block__list_tags li { - color: #fff; - float: left; - margin: 8px 20px 10px 0; - padding: 5px 10px; - min-width: 10px; - background-color: #5F9EDF; - text-align: center; - } - .block__list_tags li:first-child:first-letter { - text-transform: uppercase; - } - - - -#editable {} - #editable li { - position: relative; - } - - #editable i { - -webkit-transition: opacity .2s; - transition: opacity .2s; - opacity: 0; - display: block; - cursor: pointer; - color: #c00; - top: 10px; - right: 40px; - position: absolute; - font-style: normal; - } - - #editable li:hover i { - opacity: 1; - } - - -#filter {} - #filter button { - color: #fff; - width: 100%; - border: none; - outline: 0; - opacity: .5; - margin: 10px 0 0; - transition: opacity .1s ease; - cursor: pointer; - background: #5F9EDF; - padding: 10px 0; - font-size: 20px; - } - #filter button:hover { - opacity: 1; - } - - #filter .block__list { - padding-bottom: 0; - } - -.drag-handle { - margin-right: 10px; - font: bold 20px Sans-Serif; - color: #5F9EDF; - display: inline-block; - cursor: move; - cursor: -webkit-grabbing; /* overrides 'move' */ -} - -#todos input { - padding: 5px; - font-size: 14px; - font-family: 'Roboto', sans-serif; - font-weight: 300; -} - - - -#nested ul li { - background-color: rgba(0,0,0,.05); -} diff --git a/dashboard-ui/bower_components/Sortable/st/app.js b/dashboard-ui/bower_components/Sortable/st/app.js deleted file mode 100644 index 164270d9ad..0000000000 --- a/dashboard-ui/bower_components/Sortable/st/app.js +++ /dev/null @@ -1,226 +0,0 @@ -(function () { - 'use strict'; - - var byId = function (id) { return document.getElementById(id); }, - - loadScripts = function (desc, callback) { - var deps = [], key, idx = 0; - - for (key in desc) { - deps.push(key); - } - - (function _next() { - var pid, - name = deps[idx], - script = document.createElement('script'); - - script.type = 'text/javascript'; - script.src = desc[deps[idx]]; - - pid = setInterval(function () { - if (window[name]) { - clearTimeout(pid); - - deps[idx++] = window[name]; - - if (deps[idx]) { - _next(); - } else { - callback.apply(null, deps); - } - } - }, 30); - - document.getElementsByTagName('head')[0].appendChild(script); - })() - }, - - console = window.console; - - - if (!console.log) { - console.log = function () { - alert([].join.apply(arguments, ' ')); - }; - } - - - Sortable.create(byId('foo'), { - group: "words", - animation: 150, - store: { - get: function (sortable) { - var order = localStorage.getItem(sortable.options.group); - return order ? order.split('|') : []; - }, - set: function (sortable) { - var order = sortable.toArray(); - localStorage.setItem(sortable.options.group, order.join('|')); - } - }, - onAdd: function (evt){ console.log('onAdd.foo:', [evt.item, evt.from]); }, - onUpdate: function (evt){ console.log('onUpdate.foo:', [evt.item, evt.from]); }, - onRemove: function (evt){ console.log('onRemove.foo:', [evt.item, evt.from]); }, - onStart:function(evt){ console.log('onStart.foo:', [evt.item, evt.from]);}, - onSort:function(evt){ console.log('onStart.foo:', [evt.item, evt.from]);}, - onEnd: function(evt){ console.log('onEnd.foo:', [evt.item, evt.from]);} - }); - - - Sortable.create(byId('bar'), { - group: "words", - animation: 150, - onAdd: function (evt){ console.log('onAdd.bar:', evt.item); }, - onUpdate: function (evt){ console.log('onUpdate.bar:', evt.item); }, - onRemove: function (evt){ console.log('onRemove.bar:', evt.item); }, - onStart:function(evt){ console.log('onStart.foo:', evt.item);}, - onEnd: function(evt){ console.log('onEnd.foo:', evt.item);} - }); - - - // Multi groups - Sortable.create(byId('multi'), { - animation: 150, - draggable: '.tile', - handle: '.tile__name' - }); - - [].forEach.call(byId('multi').getElementsByClassName('tile__list'), function (el){ - Sortable.create(el, { - group: 'photo', - animation: 150 - }); - }); - - - // Editable list - var editableList = Sortable.create(byId('editable'), { - animation: 150, - filter: '.js-remove', - onFilter: function (evt) { - evt.item.parentNode.removeChild(evt.item); - } - }); - - - byId('addUser').onclick = function () { - Ply.dialog('prompt', { - title: 'Add', - form: { name: 'name' } - }).done(function (ui) { - var el = document.createElement('li'); - el.innerHTML = ui.data.name + ''; - editableList.el.appendChild(el); - }); - }; - - - // Advanced groups - [{ - name: 'advanced', - pull: true, - put: true - }, - { - name: 'advanced', - pull: 'clone', - put: false - }, { - name: 'advanced', - pull: false, - put: true - }].forEach(function (groupOpts, i) { - Sortable.create(byId('advanced-' + (i + 1)), { - sort: (i != 1), - group: groupOpts, - animation: 150 - }); - }); - - - // 'handle' option - Sortable.create(byId('handle-1'), { - handle: '.drag-handle', - animation: 150 - }); - - - // Angular example - angular.module('todoApp', ['ng-sortable']) - .constant('ngSortableConfig', {onEnd: function() { - console.log('default onEnd()'); - }}) - .controller('TodoController', ['$scope', function ($scope) { - $scope.todos = [ - {text: 'learn angular', done: true}, - {text: 'build an angular app', done: false} - ]; - - $scope.addTodo = function () { - $scope.todos.push({text: $scope.todoText, done: false}); - $scope.todoText = ''; - }; - - $scope.remaining = function () { - var count = 0; - angular.forEach($scope.todos, function (todo) { - count += todo.done ? 0 : 1; - }); - return count; - }; - - $scope.archive = function () { - var oldTodos = $scope.todos; - $scope.todos = []; - angular.forEach(oldTodos, function (todo) { - if (!todo.done) $scope.todos.push(todo); - }); - }; - }]) - .controller('TodoControllerNext', ['$scope', function ($scope) { - $scope.todos = [ - {text: 'learn Sortable', done: true}, - {text: 'use ng-sortable', done: false}, - {text: 'Enjoy', done: false} - ]; - - $scope.remaining = function () { - var count = 0; - angular.forEach($scope.todos, function (todo) { - count += todo.done ? 0 : 1; - }); - return count; - }; - - $scope.sortableConfig = { group: 'todo', animation: 150 }; - 'Start End Add Update Remove Sort'.split(' ').forEach(function (name) { - $scope.sortableConfig['on' + name] = console.log.bind(console, name); - }); - }]); -})(); - - - -// Background -document.addEventListener("DOMContentLoaded", function () { - function setNoiseBackground(el, width, height, opacity) { - var canvas = document.createElement("canvas"); - var context = canvas.getContext("2d"); - - canvas.width = width; - canvas.height = height; - - for (var i = 0; i < width; i++) { - for (var j = 0; j < height; j++) { - var val = Math.floor(Math.random() * 255); - context.fillStyle = "rgba(" + val + "," + val + "," + val + "," + opacity + ")"; - context.fillRect(i, j, 1, 1); - } - } - - el.style.background = "url(" + canvas.toDataURL("image/png") + ")"; - } - - setNoiseBackground(document.getElementsByTagName('body')[0], 50, 50, 0.02); -}, false); diff --git a/dashboard-ui/bower_components/Sortable/st/face-01.jpg b/dashboard-ui/bower_components/Sortable/st/face-01.jpg deleted file mode 100644 index 06f9640b28..0000000000 Binary files a/dashboard-ui/bower_components/Sortable/st/face-01.jpg and /dev/null differ diff --git a/dashboard-ui/bower_components/Sortable/st/face-02.jpg b/dashboard-ui/bower_components/Sortable/st/face-02.jpg deleted file mode 100644 index 9063724c89..0000000000 Binary files a/dashboard-ui/bower_components/Sortable/st/face-02.jpg and /dev/null differ diff --git a/dashboard-ui/bower_components/Sortable/st/face-03.jpg b/dashboard-ui/bower_components/Sortable/st/face-03.jpg deleted file mode 100644 index 3e64a48bdb..0000000000 Binary files a/dashboard-ui/bower_components/Sortable/st/face-03.jpg and /dev/null differ diff --git a/dashboard-ui/bower_components/Sortable/st/face-04.jpg b/dashboard-ui/bower_components/Sortable/st/face-04.jpg deleted file mode 100644 index 0e5c73bcc5..0000000000 Binary files a/dashboard-ui/bower_components/Sortable/st/face-04.jpg and /dev/null differ diff --git a/dashboard-ui/bower_components/Sortable/st/face-05.jpg b/dashboard-ui/bower_components/Sortable/st/face-05.jpg deleted file mode 100644 index a8111224db..0000000000 Binary files a/dashboard-ui/bower_components/Sortable/st/face-05.jpg and /dev/null differ diff --git a/dashboard-ui/bower_components/Sortable/st/face-06.jpg b/dashboard-ui/bower_components/Sortable/st/face-06.jpg deleted file mode 100644 index 063be72724..0000000000 Binary files a/dashboard-ui/bower_components/Sortable/st/face-06.jpg and /dev/null differ diff --git a/dashboard-ui/bower_components/Sortable/st/face-07.jpg b/dashboard-ui/bower_components/Sortable/st/face-07.jpg deleted file mode 100644 index aebd0112e5..0000000000 Binary files a/dashboard-ui/bower_components/Sortable/st/face-07.jpg and /dev/null differ diff --git a/dashboard-ui/bower_components/Sortable/st/face-08.jpg b/dashboard-ui/bower_components/Sortable/st/face-08.jpg deleted file mode 100644 index b4e27f1966..0000000000 Binary files a/dashboard-ui/bower_components/Sortable/st/face-08.jpg and /dev/null differ diff --git a/dashboard-ui/bower_components/Sortable/st/face-09.jpg b/dashboard-ui/bower_components/Sortable/st/face-09.jpg deleted file mode 100644 index 8ecdef6e32..0000000000 Binary files a/dashboard-ui/bower_components/Sortable/st/face-09.jpg and /dev/null differ diff --git a/dashboard-ui/bower_components/Sortable/st/iframe/frame.html b/dashboard-ui/bower_components/Sortable/st/iframe/frame.html deleted file mode 100644 index 677eeef642..0000000000 --- a/dashboard-ui/bower_components/Sortable/st/iframe/frame.html +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - - - - - -
    -
    - 14 - - Drag me by the handle -
    -
    - 2 - - You can also select text -
    -
    - 1 - - Best of both worlds! -
    -
    - - - diff --git a/dashboard-ui/bower_components/Sortable/st/iframe/index.html b/dashboard-ui/bower_components/Sortable/st/iframe/index.html deleted file mode 100644 index fcd089857c..0000000000 --- a/dashboard-ui/bower_components/Sortable/st/iframe/index.html +++ /dev/null @@ -1,49 +0,0 @@ - - - - - IFrame playground - - - - - - - - - - - - - -
    -
    This is Sortable
    -
    It works with Bootstrap...
    -
    ...out of the box.
    -
    It has support for touch devices.
    -
    Just drag some elements around.
    -
    - - - - - diff --git a/dashboard-ui/bower_components/Sortable/st/logo.png b/dashboard-ui/bower_components/Sortable/st/logo.png deleted file mode 100644 index 76cc77c347..0000000000 Binary files a/dashboard-ui/bower_components/Sortable/st/logo.png and /dev/null differ diff --git a/dashboard-ui/bower_components/Sortable/st/og-image.png b/dashboard-ui/bower_components/Sortable/st/og-image.png deleted file mode 100644 index 7d7a51da9a..0000000000 Binary files a/dashboard-ui/bower_components/Sortable/st/og-image.png and /dev/null differ diff --git a/dashboard-ui/bower_components/emby-webcomponents/emby-itemscontainer/emby-itemscontainer.js b/dashboard-ui/bower_components/emby-webcomponents/emby-itemscontainer/emby-itemscontainer.js index 8ac2a9bb6b..d72ff544db 100644 --- a/dashboard-ui/bower_components/emby-webcomponents/emby-itemscontainer/emby-itemscontainer.js +++ b/dashboard-ui/bower_components/emby-webcomponents/emby-itemscontainer/emby-itemscontainer.js @@ -1,4 +1,4 @@ -define(['itemShortcuts', 'connectionManager', 'layoutManager', 'browser', 'dom', 'registerElement'], function (itemShortcuts, connectionManager, layoutManager, browser, dom) { +define(['itemShortcuts', 'connectionManager', 'layoutManager', 'browser', 'dom', 'loading', 'registerElement'], function (itemShortcuts, connectionManager, layoutManager, browser, dom, loading) { var ItemsContainerProtoType = Object.create(HTMLDivElement.prototype); @@ -105,6 +105,76 @@ }); }; + function onDrop(evt, itemsContainer) { + + var playlistId = itemsContainer.getAttribute('data-playlistid'); + + loading.show(); + + var el = evt.item; + + var newIndex = evt.newIndex; + var itemId = el.getAttribute('data-playlistitemid'); + + var serverId = el.getAttribute('data-serverid'); + var apiClient = connectionManager.getApiClient(serverId); + + apiClient.ajax({ + + url: apiClient.getUrl('Playlists/' + playlistId + '/Items/' + itemId + '/Move/' + newIndex), + + type: 'POST' + + }).then(function () { + + el.setAttribute('data-index', newIndex); + loading.hide(); + + }, function () { + + loading.hide(); + + itemsContainer.dispatchEvent(new CustomEvent('needsrefresh', { + detail: {}, + cancelable: false, + bubbles: true + })); + }); + } + + ItemsContainerProtoType.enableDragReordering = function (enabled) { + + var current = this.sortable; + + if (!enabled) { + if (current) { + current.destroy(); + this.sortable = null; + } + return; + } + + if (current) { + return; + } + + var self = this; + require(['sortable'], function (Sortable) { + + self.sortable = new Sortable(self, { + + draggable: ".listItem", + handle: '.listViewDragHandle', + + // dragging ended + onEnd: function (/**Event*/evt) { + + onDrop(evt, self); + } + }); + }); + }; + ItemsContainerProtoType.attachedCallback = function () { this.addEventListener('click', onClick); @@ -130,6 +200,7 @@ this.enableHoverMenu(false); this.enableMultiSelect(false); + this.enableDragReordering(false); this.removeEventListener('click', onClick); this.removeEventListener('contextmenu', onContextMenu); this.removeEventListener('contextmenu', disableEvent); diff --git a/dashboard-ui/scripts/playlistedit.js b/dashboard-ui/scripts/playlistedit.js index 4cb057da67..687aa88c0d 100644 --- a/dashboard-ui/scripts/playlistedit.js +++ b/dashboard-ui/scripts/playlistedit.js @@ -76,22 +76,6 @@ elem.setAttribute('data-playlistid', item.Id); elem.innerHTML = html; - var listParent = elem; - - require(['sortable'], function (Sortable) { - - var sortable = new Sortable(listParent, { - - draggable: ".listItem", - handle: '.listViewDragHandle', - - // dragging ended - onEnd: function (/**Event*/evt) { - - onDrop(evt, page, item); - } - }); - }); ImageLoader.lazyChildren(elem); $('.btnNextPage', elem).on('click', function () { @@ -108,37 +92,12 @@ }); } - function onDrop(evt, page, item) { - - Dashboard.showLoadingMsg(); - - var el = evt.item; - - var newIndex = evt.newIndex; - var itemId = el.getAttribute('data-playlistitemid'); - - ApiClient.ajax({ - - url: ApiClient.getUrl('Playlists/' + item.Id + '/Items/' + itemId + '/Move/' + newIndex), - - type: 'POST' - - }).then(function () { - - el.setAttribute('data-index', newIndex); - Dashboard.hideLoadingMsg(); - - }, function () { - - Dashboard.hideLoadingMsg(); - reloadItems(page, item); - }); - } - function init(page, item) { var elem = page.querySelector('#childrenContent .itemsContainer'); + elem.enableDragReordering(true); + elem.addEventListener('needsrefresh', function () { reloadItems(page, item);