diff --git a/openid-connect-server-webapp/src/main/webapp/WEB-INF/tags/footer.tag b/openid-connect-server-webapp/src/main/webapp/WEB-INF/tags/footer.tag index 57c55dadf..30daa33de 100644 --- a/openid-connect-server-webapp/src/main/webapp/WEB-INF/tags/footer.tag +++ b/openid-connect-server-webapp/src/main/webapp/WEB-INF/tags/footer.tag @@ -22,6 +22,7 @@ <script type="text/javascript" src="resources/js/lib/bootstrapx-clickover.js"></script> <script type="text/javascript" src="resources/js/lib/moment.js"></script> <script type="text/javascript" src="resources/js/lib/retina.js"></script> +<script type="text/javascript" src="resources/js/lib/bootstrap-sheet.js"></script> <c:if test="${js != null && js != ''}"> <script type="text/javascript" src="resources/js/client.js"></script> <script type="text/javascript" src="resources/js/grant.js"></script> diff --git a/openid-connect-server-webapp/src/main/webapp/WEB-INF/tags/header.tag b/openid-connect-server-webapp/src/main/webapp/WEB-INF/tags/header.tag index ddf70903b..24f3a793e 100644 --- a/openid-connect-server-webapp/src/main/webapp/WEB-INF/tags/header.tag +++ b/openid-connect-server-webapp/src/main/webapp/WEB-INF/tags/header.tag @@ -16,6 +16,8 @@ <!-- Le styles --> <link href="resources/bootstrap2/css/bootstrap.min.css" rel="stylesheet"> + <link href="resources/css/bootstrap-sheet.css" rel="stylesheet"> + <style type="text/css"> html, diff --git a/openid-connect-server-webapp/src/main/webapp/WEB-INF/views/manage.jsp b/openid-connect-server-webapp/src/main/webapp/WEB-INF/views/manage.jsp index 45240d326..4a4583cea 100644 --- a/openid-connect-server-webapp/src/main/webapp/WEB-INF/views/manage.jsp +++ b/openid-connect-server-webapp/src/main/webapp/WEB-INF/views/manage.jsp @@ -22,11 +22,13 @@ <div class="span10"> <div class="content span12"> <div id="breadcrumbs"></div> - <div id="loadingbox" class="alert alert-warning"> + <div id="loadingbox" class="sheet hide fade" data-sheet-parent="#breadcrumbs"> + <div class="sheet-body"> Loading <span id="loading"></span>... <div class="progress progress-striped active"> <div class="bar" style="width: 0%"></div> </div> + </div> </div> <span id="content"> </span> @@ -34,4 +36,5 @@ </div> </div> </div> -<o:footer js="resources/js/admin.js" /> + +<o:footer js="resources/js/admin.js" /> \ No newline at end of file diff --git a/openid-connect-server-webapp/src/main/webapp/resources/css/bootstrap-sheet.css b/openid-connect-server-webapp/src/main/webapp/resources/css/bootstrap-sheet.css new file mode 100644 index 000000000..ad9e44d60 --- /dev/null +++ b/openid-connect-server-webapp/src/main/webapp/resources/css/bootstrap-sheet.css @@ -0,0 +1,57 @@ +/*! + * Bootstrap modal sheet + * + * Author: Michaël Perrin + * https://github.com/michaelperrin/bootstrap-modal-sheet + */ + +.sheet form { + margin: 0; +} + +.sheet .form-actions { + margin-top: 10px; + margin-bottom: 0; + padding: 10px 20px 10px; + text-align: right; +} + +.sheet { + position: absolute; + z-index: 1050; + + width: 600px; + background: rgba(240, 240, 240, 0.9); + border-color: #909090; + border-style: solid; + border-width: 0 1px 1px 1px; + box-shadow: inset 0 15px 12px -10px rgba(0, 0, 0, 0.4), 0 5px 12px rgba(0, 0, 0, 0.4); + padding-top: 15px; +} + +.sheet.hide { + display: none; +} + +.sheet .sheet-body { + padding-left: 15px; + padding-right: 15px; +} + +.sheet .sheet-footer { + margin-top: 10px; + margin-bottom: 0; + padding: 10px 20px 10px; + text-align: right; + background-color: #f5f5f5; + border-top: 1px solid #e5e5e5; +} + +.sheet-backdrop { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1040; +} diff --git a/openid-connect-server-webapp/src/main/webapp/resources/js/admin.js b/openid-connect-server-webapp/src/main/webapp/resources/js/admin.js index 47eae91d9..f197e3c1e 100644 --- a/openid-connect-server-webapp/src/main/webapp/resources/js/admin.js +++ b/openid-connect-server-webapp/src/main/webapp/resources/js/admin.js @@ -272,11 +272,11 @@ var BlackListListView = Backbone.View.extend({ return; } - $('#loadingbox').show(); + $('#loadingbox').sheet('show'); $('#loading').html('blacklist'); $.when(this.model.fetchIfNeeded()).done(function() { - $('#loadingbox').hide('slow'); + $('#loadingbox').sheet('hide'); callback(); }); }, @@ -287,11 +287,11 @@ var BlackListListView = Backbone.View.extend({ refreshTable:function() { var _self = this; - $('#loadingbox').show(); + $('#loadingbox').sheet('show'); $('#loading').html('blacklist'); $.when(this.model.fetchIfNeeded()).done(function() { - $('#loadingbox').hide('slow'); + $('#loadingbox').sheet('hide'); _self.render(); }); }, @@ -501,7 +501,7 @@ var AppRouter = Backbone.Router.extend({ $("#loading").html("console"); var baseUrl = $.url(app.serverConfiguration.issuer); Backbone.history.start({pushState: true, root: baseUrl.attr('relative') + 'manage/'}); - $('#loadingbox').hide('slow'); + $('#loadingbox').sheet('hide'); /** / } }); diff --git a/openid-connect-server-webapp/src/main/webapp/resources/js/client.js b/openid-connect-server-webapp/src/main/webapp/resources/js/client.js index 0d282d1f6..ad1b33641 100644 --- a/openid-connect-server-webapp/src/main/webapp/resources/js/client.js +++ b/openid-connect-server-webapp/src/main/webapp/resources/js/client.js @@ -244,14 +244,14 @@ var ClientListView = Backbone.View.extend({ return; } - $('#loadingbox').show(); + $('#loadingbox').sheet('show'); $('#loading').html('clients'); $.when(this.model.fetchIfNeeded(), this.options.whiteListList.fetchIfNeeded(), this.options.stats.fetchIfNeeded(), this.options.systemScopeList.fetchIfNeeded()).done(function() { - $('#loadingbox').hide('slow'); + $('#loadingbox').sheet('hide'); callback(); }); diff --git a/openid-connect-server-webapp/src/main/webapp/resources/js/grant.js b/openid-connect-server-webapp/src/main/webapp/resources/js/grant.js index 77035c790..c49cb8f59 100644 --- a/openid-connect-server-webapp/src/main/webapp/resources/js/grant.js +++ b/openid-connect-server-webapp/src/main/webapp/resources/js/grant.js @@ -44,13 +44,13 @@ var ApprovedSiteListView = Backbone.View.extend({ return; } - $('#loadingbox').show(); + $('#loadingbox').sheet('show'); $('#loading').html('approved sites'); $.when(this.model.fetchIfNeeded(), this.options.clientList.fetchIfNeeded(), this.options.systemScopeList.fetchIfNeeded()).done(function() { - $('#loadingbox').hide('slow'); + $('#loadingbox').sheet('hide'); callback(); }); }, @@ -113,13 +113,13 @@ var ApprovedSiteListView = Backbone.View.extend({ refreshTable:function() { var _self = this; - $('#loadingbox').show(); + $('#loadingbox').sheet('show'); $('#loading').html('approved sites'); $.when(this.model.fetch(), this.options.clientList.fetch(), this.options.systemScopeList.fetch()).done(function() { - $('#loadingbox').hide('slow'); + $('#loadingbox').sheet('hide'); _self.render(); }); } diff --git a/openid-connect-server-webapp/src/main/webapp/resources/js/lib/bootstrap-sheet.js b/openid-connect-server-webapp/src/main/webapp/resources/js/lib/bootstrap-sheet.js new file mode 100644 index 000000000..349a46fee --- /dev/null +++ b/openid-connect-server-webapp/src/main/webapp/resources/js/lib/bootstrap-sheet.js @@ -0,0 +1,205 @@ +/** + * Bootstrap modal sheet + * + * Author: Michaël Perrin + * https://github.com/michaelperrin/bootstrap-modal-sheet + */ + +(function () { + "use strict"; + + /* + * Sheet class definition + */ + + var Sheet = function (element, options) { + this.options = options; + this.$element = $(element) + .delegate('[data-dismiss="sheet"]', 'click.dismiss.sheet', $.proxy(this.hide, this)); + this.options.remote && this.$element.find('.sheet-body').load(this.options.remote); + }; + + Sheet.prototype = { + constructor: Sheet, + + toggle: function () { + return this[!this.isShown ? 'show' : 'hide'](); + }, + + show: function () { + var e = $.Event('show'); + var that = this; + + this.$element.trigger(e); + + if (this.isShown || e.isDefaultPrevented()) { + return; + } + + this.isShown = true; + + this.escape(); + + var transition = this.$element.hasClass('fade'); + + if (!this.$element.parent().length) { + this.$element.appendTo(document.body); //don't move modals dom position + } + + this.placeBelowParent(); + + if (this.options.backdrop) { + this.$backdrop = $('<div class="sheet-backdrop" />') + .appendTo(document.body) + ; + + this.$backdrop.click( + this.options.backdrop == 'static' ? + $.proxy(this.$element[0].focus, this.$element[0]) + : $.proxy(this.hide, this) + ); + + this.$backdrop.addClass('in'); + } + + transition ? + this.$element.slideDown('fast', function() { that.$element.focus().trigger('shown'); }) : + this.$element.show().focus().trigger('shown') + ; + + this.$element + .addClass('in') + .attr('aria-hidden', false) + .focus() + ; + }, + + placeBelowParent: function() { + if ( ! this.options.sheetParent) { + return; + } + + var $parent = $(this.options.sheetParent); + + if ( ! $parent) { + return; + } + + // Compute vertical position + var sheetPosition = $parent.offset().top + $parent.height(); + this.$element.css('top', sheetPosition + 'px'); + + // Compute horizontal position (make the sheet centered) + var margin = ($parent.width() - this.$element.width()) / 2; + var leftPosition = $parent.offset().left + margin; + + this.$element.css('left', leftPosition + 'px'); + }, + + hide: function (e) { + e && e.preventDefault(); + + var that = this; + + e = $.Event('hide'); + + this.$element.trigger(e); + + if (!this.isShown || e.isDefaultPrevented()) { + return; + } + + this.isShown = false; + + this.escape(); + + $(document).off('focusin.sheet'); + + this.$element + .removeClass('in') + .attr('aria-hidden', true) + ; + + this.hideSheet(); + }, + + hideSheet: function () { + var transition = this.$element.hasClass('fade'); + + transition ? this.$element.slideUp('fast') : this.$element.hide(); + this.removeBackdrop(); + this.$element.trigger('hidden'); + }, + + removeBackdrop: function () { + if ( ! this.options.backdrop) { + return; + } + + this.$backdrop.remove(); + this.$backdrop = null; + }, + + escape: function () { + var that = this; + + if (this.isShown && this.options.keyboard) { + this.$element.on('keyup.dismiss.sheet', function (e) { + e.which == 27 && that.hide(); + }); + } else if (!this.isShown) { + this.$element.off('keyup.dismiss.sheet'); + } + } + }; + + /* + * jQuery Sheet plugin definition + */ + + $.fn.sheet = function (option) { + return this.each(function () { + var $this = $(this); + + var data = $this.data('sheet'); + + var options = $.extend({}, $.fn.sheet.defaults, $this.data(), typeof option == 'object' && option); + + if (!data) { + $this.data('sheet', (data = new Sheet(this, options))); + } + + if (typeof option == 'string') { + data[option](); + } else if (options.show) { + data.show(); + } + }); + }; + + $.fn.sheet.defaults = { + keyboard: true, + show: true, + backdrop: true + }; + + $.fn.sheet.Constructor = Sheet; + + /* SHEET DATA-API + * ============== */ + + $(document).on('click.sheet.data-api', '[data-toggle="sheet"]', function (e) { + var $this = $(this); + var href = $this.attr('href'); + var $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))); //strip for ie7 + var option = $target.data('sheet') ? 'toggle' : $.extend({ remote:!/#/.test(href) && href }, $target.data(), $this.data()); + + e.preventDefault(); + + $target + .sheet(option) + .one('hide', function () { + $this.focus(); + }); + }); +}).call(this); diff --git a/openid-connect-server-webapp/src/main/webapp/resources/js/scope.js b/openid-connect-server-webapp/src/main/webapp/resources/js/scope.js index cd7e310a0..5d2c16ba6 100644 --- a/openid-connect-server-webapp/src/main/webapp/resources/js/scope.js +++ b/openid-connect-server-webapp/src/main/webapp/resources/js/scope.js @@ -140,11 +140,11 @@ var SystemScopeListView = Backbone.View.extend({ return; } - $('#loadingbox').show(); + $('#loadingbox').sheet('show'); $('#loading').html('approved sites'); $.when(this.model.fetchIfNeeded()).done(function() { - $('#loadingbox').hide('slow'); + $('#loadingbox').sheet('hide'); callback(); }); }, @@ -161,11 +161,11 @@ var SystemScopeListView = Backbone.View.extend({ refreshTable:function() { var _self = this; - $('#loadingbox').show(); + $('#loadingbox').sheet('show'); $('#loading').html('approved sites'); $.when(this.model.fetch()).done(function() { - $('#loadingbox').hide('slow'); + $('#loadingbox').sheet('hide'); _self.render(); }); }, diff --git a/openid-connect-server-webapp/src/main/webapp/resources/js/token.js b/openid-connect-server-webapp/src/main/webapp/resources/js/token.js index ade8e2e70..c044ffd83 100644 --- a/openid-connect-server-webapp/src/main/webapp/resources/js/token.js +++ b/openid-connect-server-webapp/src/main/webapp/resources/js/token.js @@ -320,21 +320,21 @@ var TokenListView = Backbone.View.extend({ return; } - $('#loadingbox').show(); + $('#loadingbox').sheet('show'); $('#loading').html('tokens'); $.when(this.model.access.fetchIfNeeded(), this.model.refresh.fetchIfNeeded(), this.options.clientList.fetchIfNeeded(), this.options.systemScopeList.fetchIfNeeded()).done(function() { - $('#loadingbox').hide('slow'); + $('#loadingbox').sheet('hide'); callback(); }); }, refreshTable:function() { - $('#loadingbox').show(); + $('#loadingbox').sheet('show'); $('#loading').html('tokens'); var _self = this; $.when(this.model.access.fetch(), @@ -342,7 +342,7 @@ var TokenListView = Backbone.View.extend({ this.options.clientList.fetch(), this.options.systemScopeList.fetch()).done(function(){ _self.render(); - $('#loadingbox').hide('slow'); + $('#loadingbox').sheet('hide'); }); }, diff --git a/openid-connect-server-webapp/src/main/webapp/resources/js/whitelist.js b/openid-connect-server-webapp/src/main/webapp/resources/js/whitelist.js index e9b829139..a27b79919 100644 --- a/openid-connect-server-webapp/src/main/webapp/resources/js/whitelist.js +++ b/openid-connect-server-webapp/src/main/webapp/resources/js/whitelist.js @@ -58,13 +58,13 @@ var WhiteListListView = Backbone.View.extend({ return; } - $('#loadingbox').show(); + $('#loadingbox').sheet('show'); $('#loading').html('whitelist'); $.when(this.model.fetchIfNeeded(), this.options.clientList.fetchIfNeeded(), this.options.systemScopeList.fetchIfNeeded()).done(function() { - $('#loadingbox').hide('slow'); + $('#loadingbox').sheet('hide'); callback(); }); }, @@ -105,13 +105,13 @@ var WhiteListListView = Backbone.View.extend({ refreshTable:function() { var _self = this; - $('#loadingbox').show(); + $('#loadingbox').sheet('show'); $('#loading').html('whitelist'); $.when(this.model.fetchIfNeeded(), this.options.clientList.fetchIfNeeded(), this.options.systemScopeList.fetchIfNeeded()).done(function() { - $('#loadingbox').hide('slow'); + $('#loadingbox').sheet('hide'); _self.render(); }); }