From 6beaa62b71be3b5271a61457af74407e8ec4f5c0 Mon Sep 17 00:00:00 2001 From: Arjun Balla Date: Tue, 23 Oct 2012 11:42:26 -0700 Subject: [PATCH] code to display resources in default/list/expended style. style can be passed as a option while creating swagerUi object. In future I would like to achieve this by passing options to templates and have a template helper method manipulate dom and apply correct classes.This approach will improve the performance as we need not go over the entire dom and call Doc.collapseOperationsForResource or Doc.expandOperationsForResource on each matched element --- src/main/coffeescript/SwaggerUi.coffee | 153 ++++++------ src/main/html/index.html | 186 +++++++------- src/main/javascript/doc.js | 322 ++++++++++++------------- 3 files changed, 334 insertions(+), 327 deletions(-) diff --git a/src/main/coffeescript/SwaggerUi.coffee b/src/main/coffeescript/SwaggerUi.coffee index 62e02c8a..772bb747 100644 --- a/src/main/coffeescript/SwaggerUi.coffee +++ b/src/main/coffeescript/SwaggerUi.coffee @@ -1,75 +1,78 @@ -class SwaggerUi extends Backbone.Router - - # Defaults - dom_id: "swagger_ui" - - # Attributes - options: null - api: null - headerView: null - mainView: null - - # SwaggerUi accepts all the same options as SwaggerApi - initialize: (options={}) -> - # Allow dom_id to be overridden - if options.dom_id? - @dom_id = options.dom_id - delete options.dom_id - - # Create an empty div which contains the dom_id - $('body').append('
') if not $('#' + @dom_id)? - - @options = options - - # Set the callbacks - @options.success = => @render(options) - @options.progress = (d) => @showMessage(d) - @options.failure = (d) => @onLoadFailure(d, options.doneFailure) - - # Create view to handle the header inputs - @headerView = new HeaderView({el: $('#header')}) - - # Event handler for when the baseUrl/apiKey is entered by user - @headerView.on 'update-swagger-ui', (data) => @updateSwaggerUi(data) - - # Event handler for when url/key is received from user - updateSwaggerUi: (data) -> - @options.discoveryUrl = data.discoveryUrl - @options.apiKey = data.apiKey - @load() - - # Create an api and render - load: -> - # Initialize the API object - @mainView?.clear() - @headerView.update(@options.discoveryUrl, @options.apiKey) - @api = new SwaggerApi(@options) - - # This is bound to success handler for SwaggerApi - # so it gets called when SwaggerApi completes loading - render:(options) -> - @showMessage('Finished Loading Resource Information. Rendering Swagger UI...') - @mainView = new MainView({model: @api, el: $('#' + @dom_id)}).render() - @showMessage() - options.doneSuccess() if options.doneSuccess - setTimeout( - => - Docs.shebang() - 400 - ) - - # Shows message on topbar of the ui - showMessage: (data = '') -> - $('#message-bar').removeClass 'message-fail' - $('#message-bar').addClass 'message-success' - $('#message-bar').html data - - # shows message in red - onLoadFailure: (data = '', doneFailure) -> - $('#message-bar').removeClass 'message-success' - $('#message-bar').addClass 'message-fail' - val = $('#message-bar').html data - doneFailure() if doneFailure - val - -window.SwaggerUi = SwaggerUi +class SwaggerUi extends Backbone.Router + + # Defaults + dom_id: "swagger_ui" + + # Attributes + options: null + api: null + headerView: null + mainView: null + + # SwaggerUi accepts all the same options as SwaggerApi + initialize: (options={}) -> + # Allow dom_id to be overridden + if options.dom_id? + @dom_id = options.dom_id + delete options.dom_id + + # Create an empty div which contains the dom_id + $('body').append('
') if not $('#' + @dom_id)? + + @options = options + + # Set the callbacks + @options.success = => @render(options) + @options.progress = (d) => @showMessage(d) + @options.failure = (d) => @onLoadFailure(d, options.doneFailure) + + # Create view to handle the header inputs + @headerView = new HeaderView({el: $('#header')}) + + # Event handler for when the baseUrl/apiKey is entered by user + @headerView.on 'update-swagger-ui', (data) => @updateSwaggerUi(data) + + # Event handler for when url/key is received from user + updateSwaggerUi: (data) -> + @options.discoveryUrl = data.discoveryUrl + @options.apiKey = data.apiKey + @load() + + # Create an api and render + load: -> + # Initialize the API object + @mainView?.clear() + @headerView.update(@options.discoveryUrl, @options.apiKey) + @api = new SwaggerApi(@options) + + # This is bound to success handler for SwaggerApi + # so it gets called when SwaggerApi completes loading + render:(options) -> + @showMessage('Finished Loading Resource Information. Rendering Swagger UI...') + @mainView = new MainView({model: @api, el: $('#' + @dom_id)}).render() + @showMessage() + switch options.docStyle + when "expand" then Docs.expandOperationsForResource('') + when "list" then Docs.collapseOperationsForResource('') + options.doneSuccess() if options.doneSuccess + setTimeout( + => + Docs.shebang() + 400 + ) + + # Shows message on topbar of the ui + showMessage: (data = '') -> + $('#message-bar').removeClass 'message-fail' + $('#message-bar').addClass 'message-success' + $('#message-bar').html data + + # shows message in red + onLoadFailure: (data = '', doneFailure) -> + $('#message-bar').removeClass 'message-success' + $('#message-bar').addClass 'message-fail' + val = $('#message-bar').html data + doneFailure() if doneFailure + val + +window.SwaggerUi = SwaggerUi diff --git a/src/main/html/index.html b/src/main/html/index.html index 28310c53..b1b3a8ec 100644 --- a/src/main/html/index.html +++ b/src/main/html/index.html @@ -1,91 +1,95 @@ - - - Swagger UI - - - - - - - - - - - - - - - - - - - - -
-   -
- -
- -
- - - - + + + Swagger UI + + + + + + + + + + + + + + + + + + + + +
+   +
+ +
+ +
+ + + + diff --git a/src/main/javascript/doc.js b/src/main/javascript/doc.js index 595d89f1..fad24eb9 100644 --- a/src/main/javascript/doc.js +++ b/src/main/javascript/doc.js @@ -1,162 +1,162 @@ -$(function() { - - // Helper function for vertically aligning DOM elements - // http://www.seodenver.com/simple-vertical-align-plugin-for-jquery/ - $.fn.vAlign = function() { - return this.each(function(i){ - var ah = $(this).height(); - var ph = $(this).parent().height(); - var mh = (ph - ah) / 2; - $(this).css('margin-top', mh); - }); - }; - - $.fn.stretchFormtasticInputWidthToParent = function() { - return this.each(function(i){ - var p_width = $(this).closest("form").innerWidth(); - var p_padding = parseInt($(this).closest("form").css('padding-left') ,10) + parseInt($(this).closest("form").css('padding-right'), 10); - var this_padding = parseInt($(this).css('padding-left'), 10) + parseInt($(this).css('padding-right'), 10); - $(this).css('width', p_width - p_padding - this_padding); - }); - }; - - $('form.formtastic li.string input, form.formtastic textarea').stretchFormtasticInputWidthToParent(); - - // Vertically center these paragraphs - // Parent may need a min-height for this to work.. - $('ul.downplayed li div.content p').vAlign(); - - // When a sandbox form is submitted.. - $("form.sandbox").submit(function(){ - - var error_free = true; - - // Cycle through the forms required inputs - $(this).find("input.required").each(function() { - - // Remove any existing error styles from the input - $(this).removeClass('error'); - - // Tack the error style on if the input is empty.. - if ($(this).val() == '') { - $(this).addClass('error'); - $(this).wiggle(); - error_free = false; - } - - }); - - return error_free; - }); - -}); - -function clippyCopiedCallback(a) { - $('#api_key_copied').fadeIn().delay(1000).fadeOut(); - - // var b = $("#clippy_tooltip_" + a); - // b.length != 0 && (b.attr("title", "copied!").trigger("tipsy.reload"), setTimeout(function() { - // b.attr("title", "copy to clipboard") - // }, - // 500)) -} - -// Logging function that accounts for browsers that don't have window.console -function log() { - if (window.console) console.log.apply(console,arguments); -} - -var Docs = { - - shebang: function() { - - // If shebang has an operation nickname in it.. - // e.g. /docs/#!/words/get_search - var fragments = $.param.fragment().split('/'); - fragments.shift(); // get rid of the bang - - switch (fragments.length) { - case 1: - // Expand all operations for the resource and scroll to it -// log('shebang resource:' + fragments[0]); - var dom_id = 'resource_' + fragments[0]; - - Docs.expandEndpointListForResource(fragments[0]); - $("#"+dom_id).slideto({highlight: false}); - break; - case 2: - // Refer to the endpoint DOM element, e.g. #words_get_search -// log('shebang endpoint: ' + fragments.join('_')); - - // Expand Resource - Docs.expandEndpointListForResource(fragments[0]); - $("#"+dom_id).slideto({highlight: false}); - - // Expand operation - var li_dom_id = fragments.join('_'); - var li_content_dom_id = li_dom_id + "_content"; - -// log("li_dom_id " + li_dom_id); -// log("li_content_dom_id " + li_content_dom_id); - - Docs.expandOperation($('#'+li_content_dom_id)); - $('#'+li_dom_id).slideto({highlight: false}); - break; - } - - }, - - toggleEndpointListForResource: function(resource) { - var elem = $('li#resource_' + Docs.escapeResourceName(resource) + ' ul.endpoints'); - if (elem.is(':visible')) { - Docs.collapseEndpointListForResource(resource); - } else { - Docs.expandEndpointListForResource(resource); - } - }, - - // Expand resource - expandEndpointListForResource: function(resource) { - $('#resource_' + resource).addClass('active'); - - var elem = $('li#resource_' + Docs.escapeResourceName(resource) + ' ul.endpoints'); - elem.slideDown(); - }, - - // Collapse resource and mark as explicitly closed - collapseEndpointListForResource: function(resource) { - $('#resource_' + resource).removeClass('active'); - - var elem = $('li#resource_' + Docs.escapeResourceName(resource) + ' ul.endpoints'); - elem.slideUp(); - }, - - expandOperationsForResource: function(resource) { - // Make sure the resource container is open.. - Docs.expandEndpointListForResource(resource); - $('li#resource_' + Docs.escapeResourceName(resource) + ' li.operation div.content').each(function() { - Docs.expandOperation($(this)); - }); - }, - - collapseOperationsForResource: function(resource) { - // Make sure the resource container is open.. - Docs.expandEndpointListForResource(resource); - $('li#resource_' + Docs.escapeResourceName(resource) + ' li.operation div.content').each(function() { - Docs.collapseOperation($(this)); - }); - }, - - escapeResourceName: function(resource) { - return resource.replace(/[!"#$%&'()*+,.\/:;<=>?@\[\\\]\^`{|}~]/g, "\\$&") - }, - - expandOperation: function(elem) { - elem.slideDown(); - }, - - collapseOperation: function(elem) { - elem.slideUp(); - } - +$(function() { + + // Helper function for vertically aligning DOM elements + // http://www.seodenver.com/simple-vertical-align-plugin-for-jquery/ + $.fn.vAlign = function() { + return this.each(function(i){ + var ah = $(this).height(); + var ph = $(this).parent().height(); + var mh = (ph - ah) / 2; + $(this).css('margin-top', mh); + }); + }; + + $.fn.stretchFormtasticInputWidthToParent = function() { + return this.each(function(i){ + var p_width = $(this).closest("form").innerWidth(); + var p_padding = parseInt($(this).closest("form").css('padding-left') ,10) + parseInt($(this).closest("form").css('padding-right'), 10); + var this_padding = parseInt($(this).css('padding-left'), 10) + parseInt($(this).css('padding-right'), 10); + $(this).css('width', p_width - p_padding - this_padding); + }); + }; + + $('form.formtastic li.string input, form.formtastic textarea').stretchFormtasticInputWidthToParent(); + + // Vertically center these paragraphs + // Parent may need a min-height for this to work.. + $('ul.downplayed li div.content p').vAlign(); + + // When a sandbox form is submitted.. + $("form.sandbox").submit(function(){ + + var error_free = true; + + // Cycle through the forms required inputs + $(this).find("input.required").each(function() { + + // Remove any existing error styles from the input + $(this).removeClass('error'); + + // Tack the error style on if the input is empty.. + if ($(this).val() == '') { + $(this).addClass('error'); + $(this).wiggle(); + error_free = false; + } + + }); + + return error_free; + }); + +}); + +function clippyCopiedCallback(a) { + $('#api_key_copied').fadeIn().delay(1000).fadeOut(); + + // var b = $("#clippy_tooltip_" + a); + // b.length != 0 && (b.attr("title", "copied!").trigger("tipsy.reload"), setTimeout(function() { + // b.attr("title", "copy to clipboard") + // }, + // 500)) +} + +// Logging function that accounts for browsers that don't have window.console +function log() { + if (window.console) console.log.apply(console,arguments); +} + +var Docs = { + + shebang: function() { + + // If shebang has an operation nickname in it.. + // e.g. /docs/#!/words/get_search + var fragments = $.param.fragment().split('/'); + fragments.shift(); // get rid of the bang + + switch (fragments.length) { + case 1: + // Expand all operations for the resource and scroll to it +// log('shebang resource:' + fragments[0]); + var dom_id = 'resource_' + fragments[0]; + + Docs.expandEndpointListForResource(fragments[0]); + $("#"+dom_id).slideto({highlight: false}); + break; + case 2: + // Refer to the endpoint DOM element, e.g. #words_get_search +// log('shebang endpoint: ' + fragments.join('_')); + + // Expand Resource + Docs.expandEndpointListForResource(fragments[0]); + $("#"+dom_id).slideto({highlight: false}); + + // Expand operation + var li_dom_id = fragments.join('_'); + var li_content_dom_id = li_dom_id + "_content"; + +// log("li_dom_id " + li_dom_id); +// log("li_content_dom_id " + li_content_dom_id); + + Docs.expandOperation($('#'+li_content_dom_id)); + $('#'+li_dom_id).slideto({highlight: false}); + break; + } + + }, + + toggleEndpointListForResource: function(resource) { + var elem = $('li[id^=resource_' + Docs.escapeResourceName(resource) + '] ul.endpoints'); + if (elem.is(':visible')) { + Docs.collapseEndpointListForResource(resource); + } else { + Docs.expandEndpointListForResource(resource); + } + }, + + // Expand resource + expandEndpointListForResource: function(resource) { + $('[id^=resource_' + resource + ']').addClass('active'); + + var elem = $('li[id^=resource_' + Docs.escapeResourceName(resource) + '] ul.endpoints'); + elem.slideDown(); + }, + + // Collapse resource and mark as explicitly closed + collapseEndpointListForResource: function(resource) { + $('[id^=resource_' + resource + ']').removeClass('active'); + + var elem = $('li[id^=resource_' + Docs.escapeResourceName(resource) + '] ul.endpoints'); + elem.slideUp(); + }, + + expandOperationsForResource: function(resource) { + // Make sure the resource container is open.. + Docs.expandEndpointListForResource(resource); + $('li[id^=resource_' + Docs.escapeResourceName(resource) + '] li.operation div.content').each(function() { + Docs.expandOperation($(this)); + }); + }, + + collapseOperationsForResource: function(resource) { + // Make sure the resource container is open.. + Docs.expandEndpointListForResource(resource); + $('li[id^=resource_' + Docs.escapeResourceName(resource) + '] li.operation div.content').each(function() { + Docs.collapseOperation($(this)); + }); + }, + + escapeResourceName: function(resource) { + return resource.replace(/[!"#$%&'()*+,.\/:;<=>?@\[\\\]\^`{|}~]/g, "\\$&") + }, + + expandOperation: function(elem) { + elem.slideDown(); + }, + + collapseOperation: function(elem) { + elem.slideUp(); + } + }; \ No newline at end of file