diff --git a/app/assets/javascripts/plugins/jquery.litebox.js b/app/assets/javascripts/plugins/jquery.litebox.js index bf09b11699..2134442475 100644 --- a/app/assets/javascripts/plugins/jquery.litebox.js +++ b/app/assets/javascripts/plugins/jquery.litebox.js @@ -1,266 +1,270 @@ -/*! - * jQuery plugin - * Litebox - modal dialog window - * Copyright (c) 2015 Nick Seryakov https://github.com/kolking - * - * Usage example: - * new LiteBox({ content: '#MyLiteBox' }).open(); - * new LiteBox({ url: '/contact.html', hash: '#contact' }); - */ - -;(function($, window, document, undefined) { - - var LiteBox = function(options) { - this.$win = $(window); - this.$doc = $(document); - this.$body = $(document.body); - this.options = $.extend({}, this.defaults, options); - - if(this.options.hash) { - if(this.options.hash.toString().charAt(0) !== '#') { - this.options.hash = '#' + this.options.hash; - } - this.$win.on('hashchange.LiteBox', $.proxy(this.checkHash, this)); - this.checkHash(); - } - }; - - LiteBox.prototype = { - defaults: { - url: null, // URL for loading content - hash: null, // Hash to show litebox - content: null, // Selector for local content element - cssclass: null, // Custom CSS class for the litebox - noscroll: true, // Disable page scroll when open - disposable: false // Remove from DOM after close - }, - - isopen: false, - $wrapper: null, - $container: null, - $content: null, - - checkHash: function() { - this[this.options.hash.toLowerCase() === window.location.hash.toLowerCase() ? 'open' : 'close'](); - }, - - pageScroll: function(enabled) { - var offset; - if(enabled) { - // Enable page scroll - offset = parseInt($('html').css('top'), 10); - $('html').css({ 'top':'','width':'','position':'','overflow':'','overflow-y':'' }); - $('html,body').scrollTop(-offset).css('overflow', ''); - } else { - // Disable page scroll - if($(document).height() > $(window).height()) { - offset = $(window).scrollTop(); - $('html').css({ - 'top': -offset, - 'width': '100%', - 'position': 'fixed', - 'overflow': 'hidden', - 'overflow-y': 'scroll' - }); - } else { - $('html,body').css('overflow', 'hidden'); - } - } - }, - - open: function() { - if(this.isopen) return; - - // Disable page scroll - if(this.options.noscroll) { - this.pageScroll(false); - } - - if(this.$wrapper) { - // Show litebox if already exists - this.$wrapper.add(this.$container).addClass('visible'); - } else { - // Create elements - this.$wrapper = $('
').addClass('litebox category_modal').addClass(this.options.cssclass); - this.$closebutton = $('').addClass('litebox_close') - .attr('aria-label', 'close').text('×'); - this.$container = $('
').addClass('litebox_container'); - this.$content = $('
').addClass('litebox_content'); - - // Bind close handlers - this.$wrapper.add(this.$closebutton).on('click', $.proxy(this.eventClose, this)); - this.$container.click(function(e) { e.stopPropagation(); }); - - // Insert into DOM and show - this.$container.append(this.$closebutton, this.$content); - this.$wrapper.append(this.$container).appendTo(this.$body); - this.$wrapper.css('opacity'); // Force reflow - this.$wrapper.addClass('visible'); - - if(this.options.url) { - // Load remote content - this.$wrapper.addClass('litebox-busy'); - $.ajax({ - url: this.options.url, - cache: false, - context: this - }).done(function(data) { - this.insert(data); - }).fail(function() { - this.$wrapper.addClass('litebox-error'); - }).always(function() { - this.$wrapper.removeClass('litebox-busy'); - }); - } else if(this.options.content) { - // Get local content - this.insert($(this.options.content).show()); - } else { - console.log('LiteBox: No content has been defined'); - } - } - - // Close with Escape key - this.$doc.on('keyup.LiteBox', $.proxy(this.eventClose, this)); - this.isopen = true; - - return this; - }, - - insert: function(content) { - this.$content.html(content); - this.$container.addClass('visible'); - this.$content.find(':text:not(:hidden,[readonly],[disabled]):first').focus(); - - // Close litebox if button[type=reset] pressed - this.$content.on('click', 'form :reset', $.proxy(this.eventClose, this)); - - // Include submit button value into serialization - this.$content.on('click', 'form :submit', function() { - var button = $(this); - button.after($('').attr({ - type: 'hidden', - name: button.attr('name'), - value: button.val() - })); - }); - - // Submit an inner form via ajax - this.$content.on('submit.LiteBox', 'form', $.proxy(function(e) { - e.preventDefault(); - - var $form = $(e.currentTarget); - var form_method = $form.attr('method'); - var form_action = $form.attr('action'); - var multipart = $form.attr('enctype') === 'multipart/form-data'; - var form_data = multipart ? new FormData($form[0]) : $form.serialize(); - var $submit = $form.find(':submit').prop('disabled', true); - - this.$content.addClass('ajax-busy'); - - $.ajax({ - url: form_action, - method: form_method, - data: form_data, - cache: false, - context: this, - contentType: (multipart ? false : 'application/x-www-form-urlencoded; charset=UTF-8'), - processData: (multipart ? false : true) - }).done(function(data, textStatus, jqXHR) { - var status = jqXHR.status; - var location = jqXHR.getResponseHeader('location'); - if(status === 201) { - if(location) { - var oldPath = window.location.href.split('#')[0]; - var newPath = location.split('#')[0]; - window.location.assign(location); - - // Force page reload if location path not changed - if(newPath === oldPath) { - window.location.reload(); - } - } else { - this.close(); - } - } else { - this.$content.html(data); - } - }).fail(function() { - this.$content.addClass('ajax-error'); - }).always(function() { - $submit.prop('disabled', false); - this.$content.removeClass('ajax-busy'); - }); - }, this)); - }, - - close: function() { - if(!this.isopen || !this.$wrapper) return; - - // Hide litebox and unbind key handler - this.$wrapper.removeClass('visible'); - this.$doc.off('keyup.LiteBox'); - this.isopen = false; - - // Enable page scroll - if(this.options.noscroll) { - this.pageScroll(true); - } - - // Remove litebox from DOM after all CSS transitions - if(this.options.disposable || this.options.url) { - var events = 'transitionend otransitionend oTransitionEnd webkitTransitionEnd msTransitionEnd'; - this.$wrapper.one(events, $.proxy(this.destroy, this)); - } - - // Make sure to reset location hash - if(this.options.hash) { - window.location.replace('#'); - } - }, - - eventClose: function(e) { - if(e.type === 'keyup' && e.keyCode !== 27) return; - - e.preventDefault(); - e.stopPropagation(); - - this.close(); - }, - - destroy: function(e) { - this.$wrapper.remove(); - this.$wrapper = null; - this.$container = null; - this.$content = null; - } - }; - - LiteBox.defaults = LiteBox.prototype.defaults; - - $.fn.litebox = function(eventName) { - eventName = eventName || 'click'; - - return this.each(function() { - if(!this.litebox) { - var $elm = $(this); - var options = $.extend({ url: $elm.attr('href') }, $elm.data('litebox')); - if(options.hash === true) { - options.hash = options.url; - } - this.litebox = new LiteBox(options); - } - - $(this).on(eventName, function(e) { - e.preventDefault(); - if(this.litebox.options.hash) { - document.location.hash = this.litebox.options.hash; - } else { - this.litebox.open(); - } - }); - }); - }; - - window.LiteBox = LiteBox; - -})(jQuery, window, document); +/*! + * jQuery plugin + * Litebox - modal dialog window + * Copyright (c) 2015 Nick Seryakov https://github.com/kolking + * + * Usage example: + * new LiteBox({ content: '#MyLiteBox' }).open(); + * new LiteBox({ url: '/contact.html', hash: '#contact' }); + */ + +;(function($, window, document, undefined) { + + var LiteBox = function(options) { + this.$win = $(window); + this.$doc = $(document); + this.$body = $(document.body); + this.options = $.extend({}, this.defaults, options); + + if(this.options.hash) { + if(this.options.hash.toString().charAt(0) !== '#') { + this.options.hash = '#' + this.options.hash; + } + this.$win.on('hashchange.LiteBox', $.proxy(this.checkHash, this)); + this.checkHash(); + } + }; + + LiteBox.prototype = { + defaults: { + url: null, // URL for loading content + hash: null, // Hash to show litebox + content: null, // Selector for local content element + cssclass: null, // Custom CSS class for the litebox + noscroll: true, // Disable page scroll when open + disposable: false, // Remove from DOM after close + noclose: false // Remove close button + }, + + isopen: false, + $wrapper: null, + $container: null, + $content: null, + + checkHash: function() { + this[this.options.hash.toLowerCase() === window.location.hash.toLowerCase() ? 'open' : 'close'](); + }, + + pageScroll: function(enabled) { + var offset; + if(enabled) { + // Enable page scroll + offset = parseInt($('html').css('top'), 10); + $('html').css({ 'top':'','width':'','position':'','overflow':'','overflow-y':'' }); + $('html,body').scrollTop(-offset).css('overflow', ''); + } else { + // Disable page scroll + if($(document).height() > $(window).height()) { + offset = $(window).scrollTop(); + $('html').css({ + 'top': -offset, + 'width': '100%', + 'position': 'fixed', + 'overflow': 'hidden', + 'overflow-y': 'scroll' + }); + } else { + $('html,body').css('overflow', 'hidden'); + } + } + }, + + open: function() { + if(this.isopen) return; + + // Disable page scroll + if(this.options.noscroll) { + this.pageScroll(false); + } + + if(this.$wrapper) { + // Show litebox if already exists + this.$wrapper.add(this.$container).addClass('visible'); + } else { + // Create elements + this.$wrapper = $('
').addClass('litebox category_modal').addClass(this.options.cssclass); + this.$closebutton = $('').addClass('litebox_close') + .attr('aria-label', 'close').text('×'); + this.$container = $('
').addClass('litebox_container'); + this.$content = $('
').addClass('litebox_content'); + + // Insert into DOM and show + if(this.options.noclose) { + this.$container.append(this.$content); + } else { + // Bind close handlers + this.$wrapper.add(this.$closebutton).on('click', $.proxy(this.eventClose, this)); + this.$container.click(function(e) { e.stopPropagation(); }); + this.$container.append(this.$closebutton, this.$content); + } + this.$wrapper.append(this.$container).appendTo(this.$body); + this.$wrapper.css('opacity'); // Force reflow + this.$wrapper.addClass('visible'); + + if(this.options.url) { + // Load remote content + this.$wrapper.addClass('litebox-busy'); + $.ajax({ + url: this.options.url, + cache: false, + context: this + }).done(function(data) { + this.insert(data); + }).fail(function() { + this.$wrapper.addClass('litebox-error'); + }).always(function() { + this.$wrapper.removeClass('litebox-busy'); + }); + } else if(this.options.content) { + // Get local content + this.insert($(this.options.content).show()); + } else { + console.log('LiteBox: No content has been defined'); + } + } + + // Close with Escape key + this.$doc.on('keyup.LiteBox', $.proxy(this.eventClose, this)); + this.isopen = true; + + return this; + }, + + insert: function(content) { + this.$content.html(content); + this.$container.addClass('visible'); + this.$content.find(':text:not(:hidden,[readonly],[disabled]):first').focus(); + + // Close litebox if button[type=reset] pressed + this.$content.on('click', 'form :reset', $.proxy(this.eventClose, this)); + + // Include submit button value into serialization + this.$content.on('click', 'form :submit', function() { + var button = $(this); + button.after($('').attr({ + type: 'hidden', + name: button.attr('name'), + value: button.val() + })); + }); + + // Submit an inner form via ajax + this.$content.on('submit.LiteBox', 'form', $.proxy(function(e) { + e.preventDefault(); + + var $form = $(e.currentTarget); + var form_method = $form.attr('method'); + var form_action = $form.attr('action'); + var multipart = $form.attr('enctype') === 'multipart/form-data'; + var form_data = multipart ? new FormData($form[0]) : $form.serialize(); + var $submit = $form.find(':submit').prop('disabled', true); + + this.$content.addClass('ajax-busy'); + + $.ajax({ + url: form_action, + method: form_method, + data: form_data, + cache: false, + context: this, + contentType: (multipart ? false : 'application/x-www-form-urlencoded; charset=UTF-8'), + processData: (multipart ? false : true) + }).done(function(data, textStatus, jqXHR) { + var status = jqXHR.status; + var location = jqXHR.getResponseHeader('location'); + if(status === 201) { + if(location) { + var oldPath = window.location.href.split('#')[0]; + var newPath = location.split('#')[0]; + window.location.assign(location); + + // Force page reload if location path not changed + if(newPath === oldPath) { + window.location.reload(); + } + } else { + this.close(); + } + } else { + this.$content.html(data); + } + }).fail(function() { + this.$content.addClass('ajax-error'); + }).always(function() { + $submit.prop('disabled', false); + this.$content.removeClass('ajax-busy'); + }); + }, this)); + }, + + close: function() { + if(!this.isopen || !this.$wrapper) return; + + // Hide litebox and unbind key handler + this.$wrapper.removeClass('visible'); + this.$doc.off('keyup.LiteBox'); + this.isopen = false; + + // Enable page scroll + if(this.options.noscroll) { + this.pageScroll(true); + } + + // Remove litebox from DOM after all CSS transitions + if(this.options.disposable || this.options.url) { + var events = 'transitionend otransitionend oTransitionEnd webkitTransitionEnd msTransitionEnd'; + this.$wrapper.one(events, $.proxy(this.destroy, this)); + } + + // Make sure to reset location hash + if(this.options.hash) { + window.location.replace('#'); + } + }, + + eventClose: function(e) { + if(e.type === 'keyup' && e.keyCode !== 27) return; + + e.preventDefault(); + e.stopPropagation(); + + this.close(); + }, + + destroy: function(e) { + this.$wrapper.remove(); + this.$wrapper = null; + this.$container = null; + this.$content = null; + } + }; + + LiteBox.defaults = LiteBox.prototype.defaults; + + $.fn.litebox = function(eventName) { + eventName = eventName || 'click'; + + return this.each(function() { + if(!this.litebox) { + var $elm = $(this); + var options = $.extend({ url: $elm.attr('href') }, $elm.data('litebox')); + if(options.hash === true) { + options.hash = options.url; + } + this.litebox = new LiteBox(options); + } + + $(this).on(eventName, function(e) { + e.preventDefault(); + if(this.litebox.options.hash) { + document.location.hash = this.litebox.options.hash; + } else { + this.litebox.open(); + } + }); + }); + }; + + window.LiteBox = LiteBox; + +})(jQuery, window, document); diff --git a/app/views/collection/edit_privacy.html.slim b/app/views/collection/edit_privacy.html.slim index 79a315c94b..46b25ab4fd 100644 --- a/app/views/collection/edit_privacy.html.slim +++ b/app/views/collection/edit_privacy.html.slim @@ -8,7 +8,7 @@ =validation_summary @collection.errors =f.submit t('.save_changes'), id: 'collection-settings-save', hidden: true table.form.collection-settings - tr + tr th(colspan="2") h3.settings-label =t('.collection_privacy') @@ -21,7 +21,7 @@ =link_to(collection_restrict_collection_path(:collection_id => @collection.id), class: 'button inline-btn') =svg_symbol '#icon-lock', class: 'icon' span =t('.make_collection_private') - tr + tr td(colspan="2") -if @collection.restricted p =t('.collection_restricted_description') @@ -29,24 +29,24 @@ p =t('.collection_public_description') tr: td tr - th + th h3.settings-label =t('.collection_collaborators') p.settings-label ="(#{@collaborators.count})" unless @collaborators.empty? - p =link_to(t('.edit_collaborators'), collection_edit_collaborators_path(@collection.slug), id: 'edit-collaboators-button', class: 'button', disabled: !@collection.restricted, :data => { litebox: { hash: 'edit-collaborators', noscroll: false }}) + p =link_to(t('.edit_collaborators'), collection_edit_collaborators_path(@collection.slug), id: 'edit-collaboators-button', class: 'button', disabled: !@collection.restricted, :data => { litebox: { hash: 'edit-collaborators', noscroll: false, noclose: true }}) td =render 'users_list', users: @collaborators, type: 'collaborators', disabled: !@collection.restricted - tr + tr th h3.settings-label =t('.collection_owners') p.settings-label ="(#{@owners.count})" unless @owners.empty? - p =link_to(t('.edit_owners'), collection_edit_owners_path(@collection.slug), id: 'edit-owners-button', class: 'button', :data => { litebox: { hash: 'edit-owners', noscroll: false }}) + p =link_to(t('.edit_owners'), collection_edit_owners_path(@collection.slug), id: 'edit-owners-button', class: 'button', :data => { litebox: { hash: 'edit-owners', noscroll: false, noclose: true }}) td =render 'users_list', users: @owners, type: 'owners' tr - th + th h3.settings-label =t('.blocked_users') p.settings-label ="(#{@blocked_users.count})" unless @blocked_users.empty? - p =link_to(t('.block'), collection_block_users_path(@collection.slug), id: 'block-users-button', class: 'button', disabled: @collection.restricted, :data => { litebox: { hash: 'block-users', noscroll: false, remote: true }}) + p =link_to(t('.block'), collection_block_users_path(@collection.slug), id: 'block-users-button', class: 'button', disabled: @collection.restricted, :data => { litebox: { hash: 'block-users', noscroll: false, noclose: true, remote: true }}) td =render 'users_list', users: @blocked_users, type: 'blocked', disabled: @collection.restricted tr: td @@ -63,7 +63,7 @@ =f.radio_button :api_access, false, disabled: !@collection.restricted, :checked => !(@collection.api_access || !@collection.restricted) =f.label :api_access_false .big =t('.closed_api') - tr + tr td(colspan="2") h3 =t('.restrict_editing') =link_to({ :action => 'restrict_transcribed', :collection_id => @collection.id }, class: 'button action-btn exits', disabled: @collection.works.empty? || !@collection.text_entry?) diff --git a/app/views/document_sets/settings.html.slim b/app/views/document_sets/settings.html.slim index 546861096a..48b51e76c5 100644 --- a/app/views/document_sets/settings.html.slim +++ b/app/views/document_sets/settings.html.slim @@ -84,7 +84,7 @@ -if @collection.restricted .allowed-collaborators h3 =t('.document_set_collaborators') - p =link_to(t('.edit_collaborators'), collection_edit_set_collaborators_path(document_set_id: @document_set.slug), id: 'edit-set-collaborators-button', class: 'button', data: { litebox: { hash: 'edit-set-collaborators', noscroll: false }}) + p =link_to(t('.edit_collaborators'), collection_edit_set_collaborators_path(document_set_id: @document_set.slug), id: 'edit-set-collaborators-button', class: 'button', data: { litebox: { hash: 'edit-set-collaborators', noscroll: false, noclose: true }}) =render 'collection/users_list', users: @collaborators, type: 'collaborators' -content_for :javascript diff --git a/app/views/work/edit.html.slim b/app/views/work/edit.html.slim index 0de0a76e4b..ad87a3c1e5 100644 --- a/app/views/work/edit.html.slim +++ b/app/views/work/edit.html.slim @@ -182,7 +182,7 @@ -if @work.restrict_scribes .allowed-collaborators h3 =t('.allowed_collaborators') - p =link_to(t('.edit_collaborators'), work_edit_scribes_path(@collection, @work), id: 'edit-scribes-button', class: 'button', data: { litebox: { hash: 'edit-scribes', noscroll: false }}) + p =link_to(t('.edit_collaborators'), work_edit_scribes_path(@collection, @work), id: 'edit-scribes-button', class: 'button', data: { litebox: { hash: 'edit-scribes', noscroll: false, noclose: true }}) =render 'collection/users_list', users: @scribes, type: 'collaborators'