app/assets/javascripts/hooch.js in hooch-0.15.6 vs app/assets/javascripts/hooch.js in hooch-0.15.7

- old
+ new

@@ -1,5 +1,39 @@ +Set.prototype.isSuperset = function(subset) { + for (var elem of subset) { + if (!this.has(elem)) { + return false; + } + } + return true; +} + +Set.prototype.union = function(setB) { + var union = new Set(this); + for (var elem of setB) { + union.add(elem); + } + return union; +} + +Set.prototype.intersection = function(setB) { + var intersection = new Set(); + for (var elem of setB) { + if (this.has(elem)) { + intersection.add(elem); + } + } + return intersection; +} + +Set.prototype.difference = function(setB) { + var difference = new Set(this); + for (var elem of setB) { + difference.delete(elem); + } + return difference; +} var initHooch = function(){ hooch = { Emptier: Class.extend({ init: function($emptier){ var $target = $($emptier.data('target')); @@ -849,10 +883,17 @@ ReloadPage: Class.extend({ init: function(reload_page){ window.location.href = reload_page; } }), + PageReloader: Class.extend({ + init: function($reloader){ + $reloader.on('click', function(){ + window.location.reload(true) + }) + } + }), FakeCheckbox: Class.extend({ init: function($fake_checkbox){ this.$fake_checkbox = $fake_checkbox this.$form = this.getForm() this.prepDeselectors() @@ -1003,92 +1044,92 @@ } }), Sorter: Class.extend({ init: function($sorter){ this.$sorter = $sorter + this.$jq_obj = $sorter $sorter.data('sorter',this) + var new_uuid = new UUID + this.uniq_id = new_uuid.value + this.created_at = new Date() this.is_visible = $sorter.is(':visible') if(this.is_visible){ - this.setWidth(); + this.setWidth() + this.setBoundaries() this.getSortElements() } + this.startInactivityRefresh() var sorter = this - $(window).on('mouseup', function(e){ - sorter.onMouseup(); + $(window).on('mouseup touchend touchcancel', function(e){ + sorter.onMouseup(e) }); - $(window).on('mousemove', function(e){ - sorter.onMousemove(e) + $sorter.on('scroll', function(){ + sorter.handleScroll() }) + $sorter.parents().on('scroll', function(){ + sorter.handleScroll() + }) var observer = new MutationObserver(function(mutations) { - sorter.handleMutations(mutations) + sorter.onMutation(mutations) }); - var config = { childList: true, subtree: true, attributes: true }; + var config = { childList: true, subtree: true, attributes: true } observer.observe($sorter[0], config); }, - onMousemove: function(e){ - if(this.dragging_element){ - this.handleMouseMove(e) + usePolymorphicId: function(){ + if(this.$sorter.data('polymorphic-id')){ + return true } else { - var pressed_element = this.getPressedElement() - if(pressed_element){ - pressed_element.setDragging() - this.handleMouseMove(e) - } + return false } - return true }, - handleMouseMove: function(e){ - hooch.pauseEvent(e) - this.dragging_element.dragging = true - this.redrawDraggingElement(e); - this.refreshSequence(e) - return false - }, - onMouseup: function(){ - if(this.dragging_element){ - var tmp_dragging_element = this.dragging_element - this.removeDraggingElement() - if(tmp_dragging_element.dragging){ - this.sendSort() - } - tmp_dragging_element.dragging = false - } - var pressed_element = this.getPressedElement() - if(pressed_element){ - pressed_element.unSetPressed() - } - var sorter = this - setTimeout(function(){ - if(!sorter.is_visible){ - if(sorter.$sorter.is(':visible')){ - sorter.setWidth(); - sorter.getSortElements(); - } - } - },1000) - }, setWidth: function(){ - this.width = this.$sorter.width() + this.width = this.$sorter[0].getBoundingClientRect().width this.$sorter.css({width: this.width}) }, - handleMutations: function(mutations){ + onMutation: function(mutations){ + if(this.disabled) return var sorter = this; mutations.forEach(function(mutation) { if(mutation.addedNodes.length > 0){ var added_node = $(mutation.addedNodes[0]) if((!added_node.attr('id') || !added_node.attr('id').startsWith('thin_man_ajax_progress')) && !added_node.data('hooch-sorter-managed')){ sorter.getSortElements() + sorter.setBoundaries() } } if(mutation.removedNodes.length > 0){ var removed_node = $(mutation.removedNodes[0]) if((!removed_node.attr('id') || !removed_node.attr('id').startsWith('thin_man_ajax_progress')) && !removed_node.data('hooch-sorter-managed')){ sorter.getSortElements() + sorter.setBoundaries() } } }); }, + onMouseup: function(e){ // If some user action caused a sorter to become visible, set things up + if(this.disabled) return + var sorter = this + setTimeout(function(){ + if(!sorter.is_visible){ + if(sorter.$sorter.is(':visible')){ + sorter.is_visible = true + sorter.setWidth(); + sorter.getSortElements(); + } + } + },1000) + }, + handleScroll: function(){ + var sorter = this + if(this.scroll_finished){ + clearTimeout(this.scroll_finished); + } + this.scroll_finished = setTimeout(function(){ + sorter.setBoundaries() + sorter.refreshGrid() + }, 100); + }, getPressedElement: function(){ if(this.sort_elements){ var possible_pressed_element = $.grep(this.sort_elements, function(sort_element,i){return sort_element.pressed}) if(possible_pressed_element.length > 0){ return possible_pressed_element[0] @@ -1099,11 +1140,20 @@ getSortElements: function(){ this.$sort_elements = this.$sorter.children() this.sort_elements = [] var sorter = this; this.$sort_elements.each(function(){ - var sort_element = new hooch.SortElement($(this),sorter) + if($(this).data('hooch.SortElement')){ + tmp_sort_element = $(this).data('hooch.SortElement') + // if(tmp_sort_element.is_placeholder){ + // var sort_element = tmp_sort_element.sort_element + // } else { + var sort_element = tmp_sort_element + // } + } else { + var sort_element = new hooch.SortElement($(this),sorter) + } sorter.sort_elements.push(sort_element) }) if(this.sort_elements.length > 0){ this.row_height = this.sort_elements[0].height; var elem_widths = this.sort_elements.map(function(sort_element,i,arr){return sort_element.width}) @@ -1112,82 +1162,111 @@ if((this.min_elem_width * 2) <= this.width){ this.mode = 'Grid' } else { this.mode = 'Vertical' } + } else if(this.height > 0){ + this.min_elem_width = this.width; + this.refreshGrid(); + this.mode = 'Vertical' } }, + setBoundaries: function(){ + this.offset = this.$sorter[0].getBoundingClientRect() + this.top_boundary = this.offset.top + window.pageYOffset + this.left_boundary = this.offset.left + window.pageXOffset + this.right_boundary = this.left_boundary + this.width + this.height = this.$sorter[0].getBoundingClientRect().height + this.bottom_boundary = this.top_boundary + this.height + }, + handleDrag: function(){ + this.refreshSequence() + this.refreshGrid() + }, refreshGrid: function(){ this.rows = {} var sorter = this $.each(this.sort_elements,function(i,sort_element){ + let this_element if(sort_element != sorter.dragging_element){ this_element = sort_element } else { this_element = sort_element.placeholder } - var elem_top = this_element.getOffset().top; - if(!sorter.rows[elem_top]){ - sorter.rows[elem_top] = [] + if(this_element){ + var elem_top = this_element.getOffset().top; + if(!sorter.rows[elem_top]){ + sorter.rows[elem_top] = [] + } + sorter.rows[elem_top].push(this_element) } - sorter.rows[elem_top].push(this_element) }) this.row_keys = Object.keys(this.rows).map(function(val,i){return parseFloat(val)}).sort(sorter.numberSort) - $.each(this.rows, function(row_key,row){row.sort(sorter.elementHorizontalSort)}) + if('Horizontal' == this.mode){ + $.each(this.rows, function(row_key,row){row.sort(sorter.elementHorizontalSort)}) + } }, - redrawDraggingElement: function(e){ - this.dragging_element.setPosition(e); + draggingElementForGrid: function(){ + if(this.dragging_element){ + if(this.dragging_element.dragging){ + return this.dragging_element.placeholder + } else { + return this.dragging_element + } + } + return nil }, refreshSequence: function(){ var target_location = this.dragging_element.getCenter() var refresh_method = this['refreshSequence' + this.mode] refresh_method.call(this, target_location) }, + insertDraggingElement: function(element,e){ + this.dragging_element = element + this.refreshSequence() + this.getSortElements() + this.refreshGrid() + }, refreshSequenceGrid: function(target_location){ var dragging_element = this.dragging_element if(!this.withinCurrentRow(target_location.y)){ this.seekCurrentRow(target_location) } if('end' == this.current_row_key){ var last_element = this.getLastElement(); if(!last_element.is_placeholder){ last_element.$sort_element.after(dragging_element.placeholder.$sort_element) - this.refreshGrid() } } else if('begin' == this.current_row_key){ var first_element = this.getFirstElement(); if(!first_element.is_placeholder){ first_element.$sort_element.before(dragging_element.placeholder.$sort_element) - this.refreshGrid() } } else { var hovered_element = this.getHoveredElementHorizontal(target_location); if(hovered_element){ if('leftmost' == hovered_element){ var leftmost_element = this.current_row[0] leftmost_element.$sort_element.before(dragging_element.placeholder.$sort_element) - this.refreshGrid() } else { hovered_element.$sort_element.after(dragging_element.placeholder.$sort_element); - this.refreshGrid() } } } }, refreshSequenceVertical: function(target_location){ var dragging_element = this.dragging_element var hovered_element = this.getHoveredElementVertical(target_location) - if(hovered_element){ if('first' == hovered_element){ var first_key = this.row_keys[0] var first_element = this.rows[first_key][0] first_element.$sort_element.before(dragging_element.placeholder.$sort_element) - this.refreshGrid() + } else if('empty' == hovered_element){ + this.$sorter.html(dragging_element.placeholder.$sort_element) } else { hovered_element.$sort_element.after(dragging_element.placeholder.$sort_element) - this.refreshGrid() } } }, rowAfter: function(row){ return this.row_keys[this.row_keys.indexOf[row] + 1] @@ -1249,42 +1328,46 @@ return 'leftmost' } } }, getHoveredElementVertical: function(target_location){ - var sorter = this - current_element_key = $.grep(sorter.row_keys, function(row_key,i){ - var this_elem = sorter.rows[row_key][0] - if(!this_elem.is_placeholder){ - var elem_center = this_elem.getCenter() - var slot_top = elem_center.y - var below_top_edge = target_location.y >= slot_top - var next_row = sorter.rows[sorter.row_keys[i+1]] - var above_bottom_edge - var next_elem - if(next_row){ - next_elem = next_row[0] - if(next_elem && !next_elem.is_placeholder){ - var next_elem_center = next_elem.getCenter() - above_bottom_edge = target_location.y < next_elem_center.y + if(this.$sort_elements.length == 0){ + return 'empty' + } else { + var sorter = this + current_element_key = $.grep(sorter.row_keys, function(row_key,i){ + var this_elem = sorter.rows[row_key][0] + if(!this_elem.is_placeholder){ + var elem_center = this_elem.getCenter() + var slot_top = elem_center.y + var below_top_edge = target_location.y >= slot_top + var next_row = sorter.rows[sorter.row_keys[i+1]] + var above_bottom_edge + var next_elem + if(next_row){ + next_elem = next_row[0] + if(next_elem && !next_elem.is_placeholder){ + var next_elem_center = next_elem.getCenter() + above_bottom_edge = target_location.y < next_elem_center.y + } } + if(!next_elem){ + above_bottom_edge = below_top_edge + } + return(below_top_edge && above_bottom_edge) } - if(!next_elem){ - above_bottom_edge = below_top_edge + return false + })[0] + if(current_element_key){ + return this.rows[current_element_key][0] + } else { + var first_key = this.row_keys[0] + var first_elem = this.rows[first_key][0] + if(first_elem && !first_elem.is_placeholder && first_elem.getCenter().y > target_location.y){ + return 'first' } - return(below_top_edge && above_bottom_edge) } - return false - })[0] - if(current_element_key){ - return this.rows[current_element_key][0] - } else { - var first_key = this.row_keys[0] - var first_elem = this.rows[first_key][0] - if(first_elem && !first_elem.is_placeholder && first_elem.getCenter().y > target_location.y){ - return 'first' - } } }, getLastElement: function(){ var last_row_key = this.row_keys[this.row_keys.length-1] var last_row = this.rows[last_row_key]; @@ -1321,29 +1404,38 @@ } return false }, setDraggingElement: function(sort_element){ this.dragging_element = sort_element; - var current_row = this.rows[this.dragging_element.starting_offset.top] + var current_row = this.rows[sort_element.starting_offset.top] drag_index = current_row.indexOf(sort_element) if(drag_index > -1){ current_row.splice(drag_index, 1) } - current_row.push(this.dragging_element.placeholder) + current_row.push(sort_element.placeholder) this.refreshGrid(); }, - clearDraggingElement: function(){ - if(this.dragging_element){ - this.removeDraggingElement() - } + giveUpDraggingElement: function(){ + let sorter = this + $.each(this.rows, function(row_key, row){ + let placeholder_index = sorter.rows[row_key].indexOf(sorter.dragging_element.placeholder) + if(placeholder_index > -1){ + sorter.rows[row_key].splice(placeholder_index,1) + } + }) + delete this.dragging_element + this.getSortElements() }, - removeDraggingElement: function(){ + dropDraggingElement: function(){ + this.reinsertDraggingElement() + this.sendSort() + }, + reinsertDraggingElement: function(){ if(this.dragging_element){ - var placeholder_row = this.removePlaceholder() - this.rows[placeholder_row].push(this.dragging_element) + this.rows[this.placeholderRowKey()].push(this.dragging_element) this.dragging_element.drop() - this.dragging_element = undefined; + delete this.dragging_element this.refreshGrid(); } }, sendSort: function(){ $.ajax({ @@ -1352,103 +1444,317 @@ data: this.getFormData() }) }, getFormData: function(){ var id_array = $.map(this.$sorter.children(),function(e,i){return $(e).attr('id')}) - var first_id = id_array[0] - var last_underscore_location = first_id.lastIndexOf('_') - var array_name = first_id.slice(0,last_underscore_location) var form_data = {} - form_data[array_name] = id_array.map(function(id){ - return id.slice((last_underscore_location + 1)) - }) + if(this.usePolymorphicId()){ + form_data['polymorphic_items'] = id_array + } else { + var first_id = id_array[0] + var last_underscore_location = first_id.lastIndexOf('_') + var array_name = first_id.slice(0,last_underscore_location) + form_data[array_name] = id_array.map(function(id){ + return id.slice((last_underscore_location + 1)) + }) + } if(this.$sorter.data('sort-field')){ form_data['sort_field'] = this.$sorter.data('sort-field') } var csrf_token = $('[name="csrf-token"]').attr('content') if(csrf_token){ form_data['authenticity_token'] = csrf_token } return form_data }, - removePlaceholder: function(){ + placeholderRowKey: function(){ var sorter = this return $.grep(this.row_keys, function(row_key,i){ var placeholder_index = sorter.rows[row_key].indexOf(sorter.dragging_element.placeholder) if(placeholder_index > -1){ - sorter.rows[row_key].slice(placeholder_index,1) + sorter.rows[row_key].splice(placeholder_index,1) return true } return false })[0] + }, + containsPoint: function(point){ + let contains_horizontal = this.left_boundary <= point.x && point.x <= this.right_boundary + let contains_vertical = this.top_boundary <= point.y && point.y <= this.bottom_boundary + return contains_horizontal && contains_vertical + }, + matchesFilters: function(element_filters){ + let recipient_filters = this.$sorter.data('recipient-filters') + if(typeof element_filters.any == 'object'){ + // At least one of these is required to match + let any = true + for(var key in element_filters.any){ + if(!recipient_filters.hasOwnProperty(key)){ + any = false + break + } + let include_source = new Set(recipient_filters[key]) + let include_test = new Set(element_filters.any[key]) + if(include_source.intersection(include_test).size == 0){ + any = false + break + } + } + if(!any) return false + } + // All of these are required to match + let all = true + for(var key in element_filters.all){ + if(!recipient_filters.hasOwnProperty(key)){ + all = false + break + } + let include_source = new Set(recipient_filters[key]) + let include_test = new Set(element_filters.all[key]) + if(!include_source.isSuperset(include_test)){ + all = false + break + } + } + if(!all) return false + // None of these can be present to match + var none = true + for(var key in element_filters.none){ + if(!recipient_filters.hasOwnProperty(key)){continue} + let exclude_source = new Set(recipient_filters[key]) + let exclude_test = new Set(element_filters.none[key]) + if(exclude_source.intersection(exclude_test).size != 0){ + none = false + break + } + } + if(!none) return false + return true + }, + maskMe: function(){ + this.mask = $('<div>') + .css({position: 'absolute', 'z-index': 1000, + 'background-color': 'rgba(64,64,64,0.5)', + top: this.top_boundary, left: this.left_boundary, + width: this.width, height: this.height}) + $('body').append(this.mask) + }, + unmaskMe: function(){ + if(this.mask) this.mask.remove() + }, + startInactivityRefresh: function(){ + this.last_activity_time = new Date().getTime(); + var sorter = this + $('body').on("mousemove keypress", function(e) { + sorter.last_activity_time = new Date().getTime(); + }); + setTimeout(function(){sorter.inactivityRefresh()}, 6000); + }, + inactivityRefresh: function() { + var sorter = this + if(new Date().getTime() - this.last_activity_time >= 1800000){ + var $reload_link = $('<a>').text('Reload Page') + new hooch.PageReloader($reload_link) + var $modal_content = $('<div>').html("You must reload the page after 30 minutes of inactivity. ") + $modal_content.append($reload_link) + var modal = new hooch.Modal($modal_content) + modal.$dismisser.remove() + delete modal.dismisser + delete modal.$dismisser + } else { + setTimeout(function(){sorter.inactivityRefresh()}, 60000); + } + }, + disable: function(){ + this.disabled = true } }), SortElement: Class.extend({ init: function($sort_element,sorter){ - this.sorter = sorter; - this.$sort_element = $sort_element; - this.old_position = $sort_element.css('position') - this.starting_width = this.$sort_element[0].style.width - this.starting_height = this.$sort_element[0].style.height - this.starting_top = this.$sort_element[0].style.top - this.starting_left = this.$sort_element[0].style.left - $sort_element.css({width: this.starting_width}) + this.$jq_obj = $sort_element + var new_uuid = new UUID + this.uniq_id = new_uuid.value + this.created_at = new Date() + if(sorter) this.sorter = sorter; + $sort_element.data('hooch.SortElement', this) + this.$sort_element = $sort_element; + this.reusable = $sort_element.data('sort-reusable') if(typeof(window.getComputedStyle) == 'function'){ var computed_style = window.getComputedStyle(this.$sort_element[0]) - this.width = parseInt(computed_style.width) - this.height = parseInt(computed_style.height) + var current_offset = this.getOffset() + this.width = current_offset.width + this.height = current_offset.height + this.background_color = computed_style.getPropertyValue('background-color') + this.padding = computed_style.getPropertyValue('padding') + this.float = computed_style.getPropertyValue('float') }else{ this.width = this.$sort_element.width() this.height = this.$sort_element.height() } + this.original_positioning = + { position: this.$sort_element.css('position'), + top: this.$sort_element.css('top'), + left: this.$sort_element.css('left'), + width: this.width, + height: this.height + } + $sort_element.css({width: this.width}) this.dragging = false this.getDragHandle() this.$sort_element.css({cursor: ''}); this.$drag_handle.css({cursor: 'move'}); var sort_element = this - this.$drag_handle.on('mousedown', $.proxy(sort_element.onMousedown, sort_element)) + this.$drag_handle.on('mousedown touchstart', $.proxy(sort_element.onMousedown, sort_element)) this.$sort_element.on('dragstart', function(e){hooch.pauseEvent(e); return false}) + this.element_filters = this.getElementFilters() || {} + $(window).on('mousemove touchmove', function(e){ + sort_element.onMousemove(e) + }) + $(window).on('mouseup touchend touchcancel', function(e){ + sort_element.onMouseup(e) + }) }, onMousedown: function(e){ + if(this.disabled) return + hooch.pauseEvent(e) if(1 == e.which){ - this.sorter.clearDraggingElement(); - this.pressed = true - this.starting_offset = this.getOffset(); - this.mouse_start = {top: e.originalEvent.pageY, left: e.originalEvent.pageX} + if(!this.pressed && !this.dragging && (!this.sorter || !this.sorter.dragging_element)){ + this.pressed = true + this.starting_offset = this.getOffset(); + this.mouse_start = {top: e.originalEvent.pageY, left: e.originalEvent.pageX} + this.maskNonTargets() + } } + return false }, + onMousemove: function(e){ + if(this.disabled) return + hooch.pauseEvent(e) + if(this.pressed){this.setDragging()} + if(this.dragging){ + var target_sorter = this.targetSorter(e) + if(target_sorter){ + this.attachToSorter(target_sorter,e) + } else if(this.sorter){ + this.sorter.handleDrag() + } + this.setPosition(e) + } + return false + }, + onMouseup: function(e){ + if(this.disabled) return + if(this.pressed) this.unSetPressed() + if(this.dragging) this.handleMouseUp() + }, + handleMouseUp: function(){ + if(this.sorter){ + this.sorter.dropDraggingElement() + } else { + this.drop() + } + }, + currentSorters: function(){ + var sort_element = this + return window.any_time_manager.recordedObjects['hooch.Sorter']. + filter(function(sorter){return sorter != sort_element.sorter}) //Don't need the current parent + }, + targetSorter: function(e){ + var current_sorters = this.currentSorters() + if(current_sorters){ + var current_center = this.getCenter() + var element_filters = this.element_filters + return $.grep(current_sorters, function(sorter,i){ + return sorter.containsPoint(current_center) && sorter.matchesFilters(element_filters) + })[0] + } + }, + maskNonTargets: function(){ + $.each(this.getNonTargets(), function(i,non_target_sorter){ + non_target_sorter.maskMe() + }) + }, + unmaskNonTargets: function(){ + $.each(this.getNonTargets(), function(i,non_target_sorter){ + non_target_sorter.unmaskMe() + }) + }, + getNonTargets: function(){ + var current_sorters = this.currentSorters() + if(current_sorters){ + var element_filters = this.element_filters + return $.grep(current_sorters, function(sorter,i){ + return !sorter.matchesFilters(element_filters) + }) + } + return [] + }, + attachToSorter: function(target_sorter,e){ + if(this.reusable){ + delete this.reusable + } else { + this.destroyPlaceHolder() + } + if(this.sorter){ + this.sorter.giveUpDraggingElement() + } + this.createPlaceHolder() + this.sorter = target_sorter + this.sorter.insertDraggingElement(this) + }, unSetPressed: function(){ this.pressed = false }, getDragHandle: function(){ this.$drag_handle = this.$sort_element.findExclude('[data-drag-handle]','[data-sorter]') if(this.$drag_handle.length < 1){ this.$drag_handle = this.$sort_element } }, + createPlaceHolder: function(){ + var $placeholder = this.$sort_element. + clone(). + removeAttr('id'). + removeAttr('data-sort-element'). + css(this.original_positioning) + if(!this.reusable){ $placeholder.css({visibility: 'hidden'}) } + if(this.sorter){ $placeholder.data('hooch-sorter-managed',true) } + this.placeholder = new hooch.SortPlaceholder($placeholder,this) + }, + destroyPlaceHolder: function(){ + this.placeholder.destroy() + delete this.placeholder + }, setDragging: function(){ - this.sorter.clearDraggingElement(); + this.dragging = true this.unSetPressed() - this.placeholder = new hooch.SortPlaceholder(this.$sort_element.clone().removeAttr('id').css({width: this.width, height: this.height}).data('hooch-sorter-managed',true),this.sorter) - this.placeholder.css({'visibility': 'hidden'}); - // this.placeholder.css({'background-color': 'pink'}); + this.createPlaceHolder() $tmp = $('<div style="display: none;" data-hooch-sorter-managed="true"></div>') this.$sort_element.before($tmp) this.$sort_element - .css({position: 'absolute', top: this.starting_offset.top, left: this.starting_offset.left, width: this.width, height: this.height}) + .css({position: 'absolute', top: this.starting_offset.top, left: this.starting_offset.left, width: this.width, height: this.height, backgroundColor: this.background_color, padding: this.padding, float: this.float}) .data('hooch-sorter-managed',true) .appendTo('body') $tmp.replaceWith(this.placeholder.$sort_element) - this.sorter.setDraggingElement(this); + if(this.sorter){this.sorter.setDraggingElement(this)} }, drop: function(){ - this.css({position: this.old_position, top: this.starting_top, left: this.starting_left, width: this.starting_width, height: this.starting_height}).data('hooch-sorter-managed',true) + this.dragging = false + this.css(this.original_positioning).data('hooch-sorter-managed',true) this.placeholder.replaceWith(this.$sort_element); - this.placeholder = undefined + delete this.placeholder + this.unmaskNonTargets() }, + getElementFilters: function(){ + return this.$sort_element.data('target-filters') + }, getOffset: function(){ - return this.$sort_element.offset(); + let viewport_offset = this.$sort_element[0].getBoundingClientRect() + return {top: viewport_offset.top + window.pageYOffset, + left: viewport_offset.left + window.pageXOffset, + height: viewport_offset.height, + width: viewport_offset.width} }, setPosition: function(e){ var delta = this.getDelta(e) var new_position = this.getNewPosition(delta); this.$sort_element.css(new_position); @@ -1479,10 +1785,17 @@ css: function(css_obj){ return this.$sort_element.css(css_obj); }, replaceWith: function($jq_obj){ this.$sort_element.replaceWith($jq_obj) + }, + disable: function(){ + this.disabled = true + }, + destroy: function(){ + this.disable() + this.$sort_element.remove() } }), scroll_keys: {37: 1, 38: 1, 39: 1, 40: 1}, key_code_map: { // borrowed from jresig: https://github.com/jeresig/jquery.hotkeys 8: "backspace", @@ -1625,12 +1938,16 @@ } } }) }; hooch.SortPlaceholder = hooch.SortElement.extend({ - init: function($sort_element,sorter){ - this.sorter = sorter; + init: function($sort_element,sort_element){ + var new_uuid = new UUID + this.uniq_id = new_uuid.value + $sort_element.data('hooch.SortElement', this) + this.sort_element = sort_element + this.sorter = sort_element.sorter; this.is_placeholder = true; this.$sort_element = $sort_element; this.width = this.$sort_element.width() this.height = this.$sort_element.height() } @@ -1841,11 +2158,12 @@ },'hooch'); window.any_time_manager.registerList( ['hover_overflow','hidey_button','hide-show','submit-proxy','click-proxy','field-filler','revealer', 'checkbox-hidden-proxy','prevent-double-submit','prevent-double-link-click', 'tab-group', 'hover-reveal', 'emptier', 'remover', 'checkbox-proxy', 'fake-checkbox', 'fake-select', 'select-action-changer', - 'sorter','bind-key','modal-trigger','history-pusher', 'history-replacer', 'link', 'atarget'],'hooch'); + 'sorter', 'sort-element', 'bind-key','modal-trigger','history-pusher', 'history-replacer', 'link', 'atarget', + 'page-reloader'],'hooch'); window.any_time_manager.load(); }; hooch.pauseEvent = function(e){ if(e.stopPropagation) e.stopPropagation(); if(e.preventDefault) e.preventDefault(); @@ -1918,9 +2236,14 @@ tab_trigger.toggleTarget('no history'); } } }) }); + $(document).ajaxStop(function(){ + $.each(window.any_time_manager.recordedObjects['hooch.Sorter'], function(index, sorter){ + sorter.setBoundaries() + }) + }) } if(typeof Class === "undefined"){ $.getScript('https://rawgit.com/edraut/js_inheritance/a6c1e40986ecb276335b0a0b1792abd01f05ff6c/inheritance.js', function(){ initHooch(); });