4
.jshintignore
Normal file
4
.jshintignore
Normal file
@@ -0,0 +1,4 @@
|
||||
node_modules
|
||||
src/main/javascript/doc.js
|
||||
dist
|
||||
lib
|
||||
35
.jshintrc
Normal file
35
.jshintrc
Normal file
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"node": true,
|
||||
"browser": true,
|
||||
"esnext": true,
|
||||
"bitwise": true,
|
||||
"curly": true,
|
||||
"eqeqeq": true,
|
||||
"immed": true,
|
||||
"indent": 2,
|
||||
"latedef": false,
|
||||
"newcap": true,
|
||||
"noarg": true,
|
||||
"quotmark": "single",
|
||||
"regexp": true,
|
||||
"undef": true,
|
||||
"unused": true,
|
||||
"strict": true,
|
||||
"trailing": true,
|
||||
"smarttabs": true,
|
||||
"globals": {
|
||||
"Backbone": false,
|
||||
"_": false,
|
||||
"$": false,
|
||||
"jQuery": false,
|
||||
"marked": false,
|
||||
"Docs": false,
|
||||
"SwaggerClient": false,
|
||||
"Handlebars": false,
|
||||
"ApiKeyAuthorization": false,
|
||||
"PasswordAuthorization": false,
|
||||
"hljs": false,
|
||||
"SwaggerUi": false,
|
||||
"swaggerUi": false // TODO: remove me
|
||||
}
|
||||
}
|
||||
@@ -5,4 +5,9 @@ node_js:
|
||||
install:
|
||||
- export DISPLAY=:99.0
|
||||
- sh -e /etc/init.d/xvfb start
|
||||
- npm install
|
||||
- npm i -g jshint
|
||||
- npm install
|
||||
|
||||
script:
|
||||
- jshint .
|
||||
- npm test
|
||||
3106
dist/swagger-ui.js
vendored
3106
dist/swagger-ui.js
vendored
File diff suppressed because it is too large
Load Diff
5
dist/swagger-ui.min.js
vendored
5
dist/swagger-ui.min.js
vendored
File diff suppressed because one or more lines are too long
32
gulpfile.js
32
gulpfile.js
@@ -2,9 +2,7 @@
|
||||
|
||||
var gulp = require('gulp');
|
||||
var es = require('event-stream');
|
||||
var gutil = require('gulp-util');
|
||||
var clean = require('gulp-clean');
|
||||
var coffee = require('gulp-coffee');
|
||||
var concat = require('gulp-concat');
|
||||
var uglify = require('gulp-uglify');
|
||||
var rename = require('gulp-rename');
|
||||
@@ -32,7 +30,7 @@ gulp.task('clean', function() {
|
||||
return gulp
|
||||
.src('./dist', {read: false})
|
||||
.pipe(clean({force: true}))
|
||||
.on('error', gutil.log);
|
||||
.on('error', log);
|
||||
});
|
||||
|
||||
/**
|
||||
@@ -47,16 +45,6 @@ function templates() {
|
||||
namespace: 'Handlebars.templates',
|
||||
noRedeclare: true, // Avoid duplicate declarations
|
||||
}))
|
||||
.on('error', gutil.log);
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes CoffeeScript files
|
||||
*/
|
||||
function coffeescript () {
|
||||
return gulp
|
||||
.src(['./src/main/coffeescript/**/*.coffee'])
|
||||
.pipe(coffee({bare: true}))
|
||||
.on('error', log);
|
||||
}
|
||||
|
||||
@@ -66,17 +54,17 @@ function coffeescript () {
|
||||
gulp.task('dist', ['clean'], function() {
|
||||
|
||||
return es.merge(
|
||||
gulp.src('./src/main/javascript/doc.js'),
|
||||
coffeescript(),
|
||||
gulp.src('./src/main/javascript/**/*.js'),
|
||||
templates()
|
||||
)
|
||||
.pipe(order(['docs.js', 'scripts.js', 'templates.js']))
|
||||
.pipe(order(['scripts.js', 'templates.js']))
|
||||
.pipe(concat('swagger-ui.js'))
|
||||
.pipe(header(banner, { pkg: pkg } ))
|
||||
.pipe(gulp.dest('./dist'))
|
||||
.pipe(uglify())
|
||||
.on('error', log)
|
||||
.pipe(rename({extname: '.min.js'}))
|
||||
.on('error', gutil.log)
|
||||
.on('error', log)
|
||||
.pipe(gulp.dest('./dist'))
|
||||
.pipe(connect.reload());
|
||||
});
|
||||
@@ -108,20 +96,20 @@ gulp.task('copy', ['less'], function() {
|
||||
gulp
|
||||
.src(['./lib/**/*.{js,map}'])
|
||||
.pipe(gulp.dest('./dist/lib'))
|
||||
.on('error', log)
|
||||
.on('error', log);
|
||||
|
||||
// copy all files inside html folder
|
||||
gulp
|
||||
.src(['./src/main/html/**/*'])
|
||||
.pipe(gulp.dest('./dist'))
|
||||
.on('error', log)
|
||||
.on('error', log);
|
||||
});
|
||||
|
||||
/**
|
||||
* Watch for changes and recompile
|
||||
*/
|
||||
gulp.task('watch', function() {
|
||||
return watch(['./src/**/*.{coffee,js,less,handlebars,html}'], function() {
|
||||
return watch(['./src/**/*.{coffee,js,less,handlebars}'], function() {
|
||||
gulp.start('default');
|
||||
});
|
||||
});
|
||||
@@ -137,9 +125,9 @@ gulp.task('connect', function() {
|
||||
});
|
||||
|
||||
function log(error) {
|
||||
console.log(error.toString());
|
||||
console.error(error.toString && error.toString());
|
||||
}
|
||||
|
||||
|
||||
gulp.task('default', ['dist', 'copy']);
|
||||
gulp.task('serve', ['connect', 'watch', 'default'])
|
||||
gulp.task('serve', ['connect', 'watch']);
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
"express": "^4.12.0",
|
||||
"gulp": "^3.8.11",
|
||||
"gulp-clean": "^0.3.1",
|
||||
"gulp-coffee": "^2.3.1",
|
||||
"gulp-concat": "^2.5.2",
|
||||
"gulp-connect": "^2.2.0",
|
||||
"gulp-declare": "^0.3.0",
|
||||
@@ -38,7 +37,6 @@
|
||||
"gulp-order": "^1.1.1",
|
||||
"gulp-rename": "^1.2.0",
|
||||
"gulp-uglify": "^1.1.0",
|
||||
"gulp-util": "^3.0.4",
|
||||
"gulp-watch": "^4.1.1",
|
||||
"gulp-wrap": "^0.11.0",
|
||||
"http-server": "git+https://github.com/nodeapps/http-server.git",
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
Handlebars.registerHelper('sanitize', (html) ->
|
||||
# Strip the script tags from the html, and return it as a Handlebars.SafeString
|
||||
html = html.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '')
|
||||
return new Handlebars.SafeString(html)
|
||||
)
|
||||
@@ -1,31 +0,0 @@
|
||||
class ApiKeyButton extends Backbone.View
|
||||
initialize: ->
|
||||
|
||||
render: ->
|
||||
template = @template()
|
||||
$(@el).html(template(@model))
|
||||
|
||||
@
|
||||
|
||||
events:
|
||||
"click #apikey_button" : "toggleApiKeyContainer"
|
||||
"click #apply_api_key" : "applyApiKey"
|
||||
|
||||
applyApiKey: ->
|
||||
window.authorizations.add(@model.name, new ApiKeyAuthorization(@model.name, $("#input_apiKey_entry").val(), @model.in))
|
||||
window.swaggerUi.load()
|
||||
elem = $('#apikey_container').show()
|
||||
|
||||
toggleApiKeyContainer: ->
|
||||
if $('#apikey_container').length > 0
|
||||
elem = $('#apikey_container').first()
|
||||
if elem.is ':visible'
|
||||
elem.hide()
|
||||
else
|
||||
# hide others
|
||||
$('.auth_container').hide()
|
||||
elem.show()
|
||||
|
||||
template: ->
|
||||
Handlebars.templates.apikey_button_view
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
class BasicAuthButton extends Backbone.View
|
||||
initialize: ->
|
||||
|
||||
render: ->
|
||||
template = @template()
|
||||
$(@el).html(template(@model))
|
||||
|
||||
@
|
||||
|
||||
events:
|
||||
"click #basic_auth_button" : "togglePasswordContainer"
|
||||
"click #apply_basic_auth" : "applyPassword"
|
||||
|
||||
applyPassword: ->
|
||||
username = $(".input_username").val()
|
||||
password = $(".input_password").val()
|
||||
window.authorizations.add(@model.type, new PasswordAuthorization("basic", username, password))
|
||||
window.swaggerUi.load()
|
||||
elem = $('#basic_auth_container').hide()
|
||||
|
||||
|
||||
togglePasswordContainer: ->
|
||||
if $('#basic_auth_container').length > 0
|
||||
elem = $('#basic_auth_container').show()
|
||||
if elem.is ':visible'
|
||||
elem.slideUp()
|
||||
else
|
||||
# hide others
|
||||
$('.auth_container').hide()
|
||||
elem.show()
|
||||
|
||||
template: ->
|
||||
Handlebars.templates.basic_auth_button_view
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
class ContentTypeView extends Backbone.View
|
||||
initialize: ->
|
||||
|
||||
render: ->
|
||||
template = @template()
|
||||
$(@el).html(template(@model))
|
||||
|
||||
$('label[for=contentType]', $(@el)).text('Response Content Type')
|
||||
|
||||
@
|
||||
|
||||
template: ->
|
||||
Handlebars.templates.content_type
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
class HeaderView extends Backbone.View
|
||||
events: {
|
||||
'click #show-pet-store-icon' : 'showPetStore'
|
||||
'click #show-wordnik-dev-icon' : 'showWordnikDev'
|
||||
'click #explore' : 'showCustom'
|
||||
'keyup #input_baseUrl' : 'showCustomOnKeyup'
|
||||
'keyup #input_apiKey' : 'showCustomOnKeyup'
|
||||
}
|
||||
|
||||
initialize: ->
|
||||
|
||||
showPetStore: (e) ->
|
||||
@trigger(
|
||||
'update-swagger-ui'
|
||||
{url:"http://petstore.swagger.wordnik.com/api/api-docs"}
|
||||
)
|
||||
|
||||
showWordnikDev: (e) ->
|
||||
@trigger(
|
||||
'update-swagger-ui'
|
||||
{url:"http://api.wordnik.com/v4/resources.json"}
|
||||
)
|
||||
|
||||
showCustomOnKeyup: (e) ->
|
||||
@showCustom() if e.keyCode is 13
|
||||
|
||||
showCustom: (e) ->
|
||||
e?.preventDefault()
|
||||
@trigger(
|
||||
'update-swagger-ui'
|
||||
{url: $('#input_baseUrl').val(), apiKey: $('#input_apiKey').val()}
|
||||
)
|
||||
|
||||
update: (url, apiKey, trigger = false) ->
|
||||
$('#input_baseUrl').val url
|
||||
#$('#input_apiKey').val apiKey
|
||||
@trigger 'update-swagger-ui', {url:url} if trigger
|
||||
@@ -1,14 +0,0 @@
|
||||
class ParameterContentTypeView extends Backbone.View
|
||||
initialize: ->
|
||||
|
||||
render: ->
|
||||
template = @template()
|
||||
$(@el).html(template(@model))
|
||||
|
||||
$('label[for=parameterContentType]', $(@el)).text('Parameter content type:')
|
||||
|
||||
@
|
||||
|
||||
template: ->
|
||||
Handlebars.templates.parameter_content_type
|
||||
|
||||
@@ -1,79 +0,0 @@
|
||||
class ParameterView extends Backbone.View
|
||||
initialize: ->
|
||||
Handlebars.registerHelper 'isArray',
|
||||
(param, opts) ->
|
||||
if param.type.toLowerCase() == 'array' || param.allowMultiple
|
||||
opts.fn(@)
|
||||
else
|
||||
opts.inverse(@)
|
||||
|
||||
render: ->
|
||||
type = @model.type || @model.dataType
|
||||
|
||||
if typeof type is 'undefined'
|
||||
schema = @model.schema
|
||||
if schema and schema['$ref']
|
||||
ref = schema['$ref']
|
||||
if ref.indexOf('#/definitions/') is 0
|
||||
type = ref.substring('#/definitions/'.length)
|
||||
else
|
||||
type = ref
|
||||
|
||||
@model.type = type
|
||||
@model.paramType = @model.in || @model.paramType
|
||||
@model.isBody = true if @model.paramType == 'body' or @model.in == 'body'
|
||||
@model.isFile = true if type and type.toLowerCase() == 'file'
|
||||
@model.default = (@model.default || @model.defaultValue)
|
||||
|
||||
if@model.allowableValues
|
||||
@model.isList = true
|
||||
|
||||
template = @template()
|
||||
$(@el).html(template(@model))
|
||||
|
||||
signatureModel =
|
||||
sampleJSON: @model.sampleJSON
|
||||
isParam: true
|
||||
signature: @model.signature
|
||||
|
||||
if @model.sampleJSON
|
||||
signatureView = new SignatureView({model: signatureModel, tagName: 'div'})
|
||||
$('.model-signature', $(@el)).append signatureView.render().el
|
||||
else
|
||||
$('.model-signature', $(@el)).html(@model.signature)
|
||||
|
||||
isParam = false
|
||||
|
||||
if @model.isBody
|
||||
isParam = true
|
||||
|
||||
contentTypeModel =
|
||||
isParam: isParam
|
||||
|
||||
contentTypeModel.consumes = @model.consumes
|
||||
|
||||
if isParam
|
||||
parameterContentTypeView = new ParameterContentTypeView({model: contentTypeModel})
|
||||
$('.parameter-content-type', $(@el)).append parameterContentTypeView.render().el
|
||||
|
||||
else
|
||||
responseContentTypeView = new ResponseContentTypeView({model: contentTypeModel})
|
||||
$('.response-content-type', $(@el)).append responseContentTypeView.render().el
|
||||
|
||||
@
|
||||
|
||||
# Return an appropriate template based on if the parameter is a list, readonly, required
|
||||
template: ->
|
||||
if @model.isList
|
||||
Handlebars.templates.param_list
|
||||
else
|
||||
if @options.readOnly
|
||||
if @model.required
|
||||
Handlebars.templates.param_readonly_required
|
||||
else
|
||||
Handlebars.templates.param_readonly
|
||||
else
|
||||
if @model.required
|
||||
Handlebars.templates.param_required
|
||||
else
|
||||
Handlebars.templates.param
|
||||
@@ -1,14 +0,0 @@
|
||||
class ResponseContentTypeView extends Backbone.View
|
||||
initialize: ->
|
||||
|
||||
render: ->
|
||||
template = @template()
|
||||
|
||||
$(@el).html(template(@model))
|
||||
|
||||
$('label[for=responseContentType]', $(@el)).text('Response Content Type')
|
||||
|
||||
@
|
||||
|
||||
template: ->
|
||||
Handlebars.templates.response_content_type
|
||||
@@ -1,51 +0,0 @@
|
||||
class SignatureView extends Backbone.View
|
||||
events: {
|
||||
'click a.description-link' : 'switchToDescription'
|
||||
'click a.snippet-link' : 'switchToSnippet'
|
||||
'mousedown .snippet' : 'snippetToTextArea'
|
||||
}
|
||||
|
||||
initialize: ->
|
||||
|
||||
render: ->
|
||||
template = @template()
|
||||
$(@el).html(template(@model))
|
||||
|
||||
@switchToSnippet()
|
||||
|
||||
@isParam = @model.isParam
|
||||
|
||||
if @isParam
|
||||
$('.notice', $(@el)).text('Click to set as parameter value')
|
||||
|
||||
@
|
||||
|
||||
template: ->
|
||||
Handlebars.templates.signature
|
||||
|
||||
# handler for show signature
|
||||
switchToDescription: (e) ->
|
||||
e?.preventDefault()
|
||||
$(".snippet", $(@el)).hide()
|
||||
$(".description", $(@el)).show()
|
||||
$('.description-link', $(@el)).addClass('selected')
|
||||
$('.snippet-link', $(@el)).removeClass('selected')
|
||||
|
||||
# handler for show sample
|
||||
switchToSnippet: (e) ->
|
||||
e?.preventDefault()
|
||||
$(".description", $(@el)).hide()
|
||||
$(".snippet", $(@el)).show()
|
||||
$('.snippet-link', $(@el)).addClass('selected')
|
||||
$('.description-link', $(@el)).removeClass('selected')
|
||||
|
||||
# handler for snippet to text area
|
||||
snippetToTextArea: (e) ->
|
||||
if @isParam
|
||||
e?.preventDefault()
|
||||
textArea = $('textarea', $(@el.parentNode.parentNode.parentNode))
|
||||
if $.trim(textArea.val()) == ''
|
||||
textArea.val(@model.sampleJSON)
|
||||
|
||||
|
||||
|
||||
197
src/main/javascript/SwaggerUi.js
Normal file
197
src/main/javascript/SwaggerUi.js
Normal file
@@ -0,0 +1,197 @@
|
||||
'use strict';
|
||||
|
||||
window.SwaggerUi = Backbone.Router.extend({
|
||||
|
||||
dom_id: 'swagger_ui',
|
||||
|
||||
// Attributes
|
||||
options: null,
|
||||
api: null,
|
||||
headerView: null,
|
||||
mainView: null,
|
||||
|
||||
// SwaggerUi accepts all the same options as SwaggerApi
|
||||
initialize: function(options) {
|
||||
options = options || {};
|
||||
|
||||
// Allow dom_id to be overridden
|
||||
if (options.dom_id) {
|
||||
this.dom_id = options.dom_id;
|
||||
delete options.dom_id;
|
||||
}
|
||||
|
||||
if (!options.supportedSubmitMethods){
|
||||
options.supportedSubmitMethods = [
|
||||
'get',
|
||||
'put',
|
||||
'post',
|
||||
'delete',
|
||||
'head',
|
||||
'options',
|
||||
'patch'
|
||||
];
|
||||
}
|
||||
|
||||
// Create an empty div which contains the dom_id
|
||||
if (! $('#' + this.dom_id)){
|
||||
$('body').append('<div id="' + this.dom_id + '"></div>') ;
|
||||
}
|
||||
|
||||
this.options = options;
|
||||
|
||||
// set marked options
|
||||
marked.setOptions({gfm: true});
|
||||
|
||||
// Set the callbacks
|
||||
var that = this;
|
||||
this.options.success = function() { return that.render(); };
|
||||
this.options.progress = function(d) { return that.showMessage(d); };
|
||||
this.options.failure = function(d) { return that.onLoadFailure(d); };
|
||||
|
||||
// Create view to handle the header inputs
|
||||
this.headerView = new SwaggerUi.Views.HeaderView({el: $('#header')});
|
||||
|
||||
// Event handler for when the baseUrl/apiKey is entered by user
|
||||
this.headerView.on('update-swagger-ui', function(data) {
|
||||
return this.updateSwaggerUi(data);
|
||||
});
|
||||
},
|
||||
|
||||
// Set an option after initializing
|
||||
setOption: function(option, value) {
|
||||
this.options[option] = value;
|
||||
},
|
||||
|
||||
// Get the value of a previously set option
|
||||
getOption: function(option) {
|
||||
return this.options[option];
|
||||
},
|
||||
|
||||
// Event handler for when url/key is received from user
|
||||
updateSwaggerUi: function(data){
|
||||
this.options.url = data.url;
|
||||
this.load();
|
||||
},
|
||||
|
||||
// Create an api and render
|
||||
load: function(){
|
||||
// Initialize the API object
|
||||
if (this.mainView) {
|
||||
this.mainView.clear();
|
||||
}
|
||||
var url = this.options.url;
|
||||
if (url && url.indexOf('http') !== 0) {
|
||||
url = this.buildUrl(window.location.href.toString(), url);
|
||||
}
|
||||
|
||||
this.options.url = url;
|
||||
this.headerView.update(url);
|
||||
|
||||
this.api = new SwaggerClient(this.options);
|
||||
},
|
||||
|
||||
// collapse all sections
|
||||
collapseAll: function(){
|
||||
Docs.collapseEndpointListForResource('');
|
||||
},
|
||||
|
||||
// list operations for all sections
|
||||
listAll: function(){
|
||||
Docs.collapseOperationsForResource('');
|
||||
},
|
||||
|
||||
// expand operations for all sections
|
||||
expandAll: function(){
|
||||
Docs.expandOperationsForResource('');
|
||||
},
|
||||
|
||||
// This is bound to success handler for SwaggerApi
|
||||
// so it gets called when SwaggerApi completes loading
|
||||
render: function(){
|
||||
this.showMessage('Finished Loading Resource Information. Rendering Swagger UI...');
|
||||
this.mainView = new SwaggerUi.Views.MainView({
|
||||
model: this.api,
|
||||
el: $('#' + this.dom_id),
|
||||
swaggerOptions: this.options
|
||||
}).render();
|
||||
this.showMessage();
|
||||
switch (this.options.docExpansion) {
|
||||
case 'full':
|
||||
this.expandAll(); break;
|
||||
case 'list':
|
||||
this.listAll(); break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
this.renderGFM();
|
||||
|
||||
if (this.options.onComplete){
|
||||
this.options.onComplete(this.api, this);
|
||||
}
|
||||
|
||||
setTimeout(Docs.shebang.bind(this), 100);
|
||||
},
|
||||
|
||||
buildUrl: function(base, url){
|
||||
if (url.indexOf('/') === 0) {
|
||||
var parts = base.split('/');
|
||||
base = parts[0] + '//' + parts[2];
|
||||
return base + url;
|
||||
} else {
|
||||
var endOfPath = base.length;
|
||||
|
||||
if (base.indexOf('?') > -1){
|
||||
endOfPath = Math.min(endOfPath, base.indexOf('?'));
|
||||
}
|
||||
|
||||
if (base.indexOf('#') > -1){
|
||||
endOfPath = Math.min(endOfPath, base.indexOf('#'));
|
||||
}
|
||||
|
||||
base = base.substring(0, endOfPath);
|
||||
|
||||
if (base.indexOf('/', base.length - 1 ) !== -1){
|
||||
return base + url;
|
||||
}
|
||||
|
||||
return base + '/' + url;
|
||||
}
|
||||
},
|
||||
|
||||
// Shows message on topbar of the ui
|
||||
showMessage: function(data){
|
||||
if (data === undefined) {
|
||||
data = '';
|
||||
}
|
||||
$('#message-bar').removeClass('message-fail');
|
||||
$('#message-bar').addClass('message-success');
|
||||
$('#message-bar').html(data);
|
||||
},
|
||||
|
||||
// shows message in red
|
||||
onLoadFailure: function(data){
|
||||
if (data === undefined) {
|
||||
data = '';
|
||||
}
|
||||
$('#message-bar').removeClass('message-success');
|
||||
$('#message-bar').addClass('message-fail');
|
||||
|
||||
var val = $('#message-bar').html(data);
|
||||
|
||||
if (this.options.onFailure) {
|
||||
this.options.onFailure(data);
|
||||
}
|
||||
|
||||
return val;
|
||||
},
|
||||
|
||||
// Renders GFM for elements with 'markdown' class
|
||||
renderGFM: function(){
|
||||
$('.markdown').each(function(){
|
||||
$(this).html(marked($(this).html()));
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
window.SwaggerUi.Views = {};
|
||||
@@ -1,22 +1,25 @@
|
||||
'use strict';
|
||||
|
||||
|
||||
$(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);
|
||||
return this.each(function(){
|
||||
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);
|
||||
return this.each(function(){
|
||||
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);
|
||||
});
|
||||
};
|
||||
|
||||
@@ -38,7 +41,7 @@ $(function() {
|
||||
$(this).removeClass('error');
|
||||
|
||||
// Tack the error style on if the input is empty..
|
||||
if ($(this).val() == '') {
|
||||
if ($(this).val() === '') {
|
||||
$(this).addClass('error');
|
||||
$(this).wiggle();
|
||||
error_free = false;
|
||||
@@ -51,7 +54,7 @@ $(function() {
|
||||
|
||||
});
|
||||
|
||||
function clippyCopiedCallback(a) {
|
||||
function clippyCopiedCallback() {
|
||||
$('#api_key_copied').fadeIn().delay(1000).fadeOut();
|
||||
|
||||
// var b = $("#clippy_tooltip_" + a);
|
||||
@@ -62,16 +65,16 @@ function clippyCopiedCallback(a) {
|
||||
}
|
||||
|
||||
// Logging function that accounts for browsers that don't have window.console
|
||||
log = function(){
|
||||
function log(){
|
||||
log.history = log.history || [];
|
||||
log.history.push(arguments);
|
||||
if(this.console){
|
||||
console.log( Array.prototype.slice.call(arguments)[0] );
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Handle browsers that do console incorrectly (IE9 and below, see http://stackoverflow.com/a/5539378/7913)
|
||||
if (Function.prototype.bind && console && typeof console.log == "object") {
|
||||
if (Function.prototype.bind && console && typeof console.log === "object") {
|
||||
[
|
||||
"log","info","warn","error","assert","dir","clear","profile","profileEnd"
|
||||
].forEach(function (method) {
|
||||
|
||||
7
src/main/javascript/helpers/handlebars.js
Normal file
7
src/main/javascript/helpers/handlebars.js
Normal file
@@ -0,0 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
Handlebars.registerHelper('sanitize', function(html) {
|
||||
// Strip the script tags from the html, and return it as a Handlebars.SafeString
|
||||
html = html.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '');
|
||||
return new Handlebars.SafeString(html);
|
||||
});
|
||||
51
src/main/javascript/view/ApiKeyButton.js
Normal file
51
src/main/javascript/view/ApiKeyButton.js
Normal file
@@ -0,0 +1,51 @@
|
||||
'use strict';
|
||||
|
||||
SwaggerUi.Views.ApiKeyButton = Backbone.View.extend({ // TODO: append this to global SwaggerUi
|
||||
|
||||
events:{
|
||||
'click #apikey_button' : 'toggleApiKeyContainer',
|
||||
'click #apply_api_key' : 'applyApiKey'
|
||||
},
|
||||
|
||||
initialize: function(){},
|
||||
|
||||
render: function(){
|
||||
var template = this.template();
|
||||
$(this.el).html(template(this.model));
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
|
||||
applyApiKey: function(){
|
||||
var keyAuth = new ApiKeyAuthorization(
|
||||
this.model.name,
|
||||
$('#input_apiKey_entry').val(),
|
||||
this.model.in
|
||||
);
|
||||
window.authorizations.add(this.model.name, keyAuth);
|
||||
window.swaggerUi.load();
|
||||
$('#apikey_container').show();
|
||||
},
|
||||
|
||||
toggleApiKeyContainer: function(){
|
||||
if ($('#apikey_container').length > 0) {
|
||||
|
||||
var elem = $('#apikey_container').first();
|
||||
|
||||
if (elem.is(':visible')){
|
||||
elem.hide();
|
||||
} else {
|
||||
|
||||
// hide others
|
||||
$('.auth_container').hide();
|
||||
elem.show();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
template: function(){
|
||||
return Handlebars.templates.apikey_button_view;
|
||||
}
|
||||
|
||||
});
|
||||
46
src/main/javascript/view/BasicAuthButton.js
Normal file
46
src/main/javascript/view/BasicAuthButton.js
Normal file
@@ -0,0 +1,46 @@
|
||||
'use strict';
|
||||
|
||||
SwaggerUi.Views.BasicAuthButton = Backbone.View.extend({
|
||||
|
||||
|
||||
initialize: function () {},
|
||||
|
||||
render: function(){
|
||||
var template = this.template();
|
||||
$(this.el).html(template(this.model));
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
events: {
|
||||
'click #basic_auth_button' : 'togglePasswordContainer',
|
||||
'click #apply_basic_auth' : 'applyPassword'
|
||||
},
|
||||
|
||||
applyPassword: function(){
|
||||
var username = $('.input_username').val();
|
||||
var password = $('.input_password').val();
|
||||
var basicAuth = new PasswordAuthorization('basic', username, password);
|
||||
window.authorizations.add(this.model.type, basicAuth);
|
||||
window.swaggerUi.load();
|
||||
$('#basic_auth_container').hide();
|
||||
},
|
||||
|
||||
togglePasswordContainer: function(){
|
||||
if ($('#basic_auth_container').length > 0) {
|
||||
var elem = $('#basic_auth_container').show();
|
||||
if (elem.is(':visible')){
|
||||
elem.slideUp();
|
||||
} else {
|
||||
// hide others
|
||||
$('.auth_container').hide();
|
||||
elem.show();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
template: function(){
|
||||
return Handlebars.templates.basic_auth_button_view;
|
||||
}
|
||||
|
||||
});
|
||||
13
src/main/javascript/view/ContentTypeView.js
Normal file
13
src/main/javascript/view/ContentTypeView.js
Normal file
@@ -0,0 +1,13 @@
|
||||
'use strict';
|
||||
|
||||
SwaggerUi.Views.ContentTypeView = Backbone.View.extend({
|
||||
initialize: function() {},
|
||||
|
||||
render: function(){
|
||||
$(this.el).html(Handlebars.templates.content_type(this.model));
|
||||
|
||||
$('label[for=contentType]', $(this.el)).text('Response Content Type');
|
||||
|
||||
return this;
|
||||
}
|
||||
});
|
||||
55
src/main/javascript/view/HeaderView.js
Normal file
55
src/main/javascript/view/HeaderView.js
Normal file
@@ -0,0 +1,55 @@
|
||||
'use strict';
|
||||
|
||||
SwaggerUi.Views.HeaderView = Backbone.View.extend({
|
||||
events: {
|
||||
'click #show-pet-store-icon' : 'showPetStore',
|
||||
'click #show-wordnik-dev-icon' : 'showWordnikDev',
|
||||
'click #explore' : 'showCustom',
|
||||
'keyup #input_baseUrl' : 'showCustomOnKeyup',
|
||||
'keyup #input_apiKey' : 'showCustomOnKeyup'
|
||||
},
|
||||
|
||||
initialize: function(){},
|
||||
|
||||
showPetStore: function(){
|
||||
this.trigger('update-swagger-ui', {
|
||||
url:'http://petstore.swagger.wordnik.com/api/api-docs'
|
||||
});
|
||||
},
|
||||
|
||||
showWordnikDev: function(){
|
||||
this.trigger('update-swagger-ui', {
|
||||
url: 'http://api.wordnik.com/v4/resources.json'
|
||||
});
|
||||
},
|
||||
|
||||
showCustomOnKeyup: function(e){
|
||||
if (e.keyCode === 13) {
|
||||
this.showCustom();
|
||||
}
|
||||
},
|
||||
|
||||
showCustom: function(e){
|
||||
if (e) {
|
||||
e.preventDefault();
|
||||
}
|
||||
|
||||
this.trigger('update-swagger-ui', {
|
||||
url: $('#input_baseUrl').val(),
|
||||
apiKey: $('#input_apiKey').val()
|
||||
});
|
||||
},
|
||||
|
||||
update: function(url, apiKey, trigger){
|
||||
if (trigger === undefined) {
|
||||
trigger = false;
|
||||
}
|
||||
|
||||
$('#input_baseUrl').val(url);
|
||||
|
||||
//$('#input_apiKey').val(apiKey);
|
||||
if (trigger) {
|
||||
this.trigger('update-swagger-ui', {url:url});
|
||||
}
|
||||
}
|
||||
});
|
||||
108
src/main/javascript/view/MainView.js
Normal file
108
src/main/javascript/view/MainView.js
Normal file
@@ -0,0 +1,108 @@
|
||||
'use strict';
|
||||
|
||||
SwaggerUi.Views.MainView = Backbone.View.extend({
|
||||
|
||||
// TODO: sorters were not used in any place, do we need them?
|
||||
// sorters = {
|
||||
// alpha : function(a,b){ return a.path.localeCompare(b.path); },
|
||||
// method : function(a,b){ return a.method.localeCompare(b.method); },
|
||||
// },
|
||||
|
||||
initialize: function(opts){
|
||||
opts = opts || {};
|
||||
// set up the UI for input
|
||||
this.model.auths = [];
|
||||
var key, value;
|
||||
|
||||
for (key in this.model.securityDefinitions) {
|
||||
value = this.model.securityDefinitions[key];
|
||||
|
||||
this.model.auths.push({
|
||||
name: key,
|
||||
type: value.type,
|
||||
value: value
|
||||
});
|
||||
}
|
||||
|
||||
if (this.model.swaggerVersion === '2.0') {
|
||||
if ('validatorUrl' in opts.swaggerOptions) {
|
||||
|
||||
// Validator URL specified explicitly
|
||||
this.model.validatorUrl = opts.swaggerOptions.validatorUrl;
|
||||
|
||||
} else if (this.model.url.indexOf('localhost') > 0) {
|
||||
|
||||
// Localhost override
|
||||
this.model.validatorUrl = null;
|
||||
|
||||
} else {
|
||||
|
||||
// Default validator
|
||||
this.model.validatorUrl = 'http://online.swagger.io/validator';
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
render: function(){
|
||||
if (this.model.securityDefinitions) {
|
||||
for (var name in this.model.securityDefinitions) {
|
||||
var auth = this.model.securityDefinitions[name];
|
||||
var button;
|
||||
|
||||
if (auth.type === 'apiKey' && $('#apikey_button').length === 0) {
|
||||
button = new SwaggerUi.Views.ApiKeyButton({model: auth}).render().el;
|
||||
$('.auth_main_container').append(button);
|
||||
}
|
||||
|
||||
if (auth.type === 'basicAuth' && $('#basic_auth_button').length === 0) {
|
||||
button = new SwaggerUi.Views.BasicAuthButton({model: auth}).render().el;
|
||||
$('.auth_main_container').append(button);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Render the outer container for resources
|
||||
$(this.el).html(Handlebars.templates.main(this.model));
|
||||
|
||||
// Render each resource
|
||||
|
||||
var resources = {};
|
||||
var counter = 0;
|
||||
for (var i = 0; i < this.model.apisArray.length; i++) {
|
||||
var resource = this.model.apisArray[i];
|
||||
var id = resource.name;
|
||||
while (typeof resources[id] !== 'undefined') {
|
||||
id = id + '_' + counter;
|
||||
counter += 1;
|
||||
}
|
||||
resource.id = id;
|
||||
resources[id] = resource;
|
||||
this.addResource(resource, this.model.auths);
|
||||
}
|
||||
|
||||
$('.propWrap').hover(function onHover(){
|
||||
$('.optionsWrapper', $(this)).show();
|
||||
}, function offhover(){
|
||||
$('.optionsWrapper', $(this)).hide();
|
||||
});
|
||||
return this;
|
||||
},
|
||||
|
||||
addResource: function(resource, auths){
|
||||
// Render a resource and add it to resources li
|
||||
resource.id = resource.id.replace(/\s/g, '_');
|
||||
var resourceView = new SwaggerUi.Views.ResourceView({
|
||||
model: resource,
|
||||
tagName: 'li',
|
||||
id: 'resource_' + resource.id,
|
||||
className: 'resource',
|
||||
auths: auths,
|
||||
swaggerOptions: this.options.swaggerOptions
|
||||
});
|
||||
$('#resources').append(resourceView.render().el);
|
||||
},
|
||||
|
||||
clear: function(){
|
||||
$(this.el).html('');
|
||||
}
|
||||
});
|
||||
624
src/main/javascript/view/OperationView.js
Normal file
624
src/main/javascript/view/OperationView.js
Normal file
@@ -0,0 +1,624 @@
|
||||
'use strict';
|
||||
|
||||
SwaggerUi.Views.OperationView = Backbone.View.extend({
|
||||
invocationUrl: null,
|
||||
|
||||
events: {
|
||||
'submit .sandbox' : 'submitOperation',
|
||||
'click .submit' : 'submitOperation',
|
||||
'click .response_hider' : 'hideResponse',
|
||||
'click .toggleOperation' : 'toggleOperationContent',
|
||||
'mouseenter .api-ic' : 'mouseEnter',
|
||||
'mouseout .api-ic' : 'mouseExit',
|
||||
},
|
||||
|
||||
initialize: function(opts) {
|
||||
opts = opts || {};
|
||||
this.auths = opts.auths;
|
||||
this.parentId = this.model.parentId;
|
||||
this.nickname = this.model.nickname;
|
||||
return this;
|
||||
},
|
||||
|
||||
mouseEnter: function(e) {
|
||||
var elem = $(this.el).find('.content');
|
||||
var x = e.pageX;
|
||||
var y = e.pageY;
|
||||
var scX = $(window).scrollLeft();
|
||||
var scY = $(window).scrollTop();
|
||||
var scMaxX = scX + $(window).width();
|
||||
var scMaxY = scY + $(window).height();
|
||||
var wd = elem.width();
|
||||
var hgh = elem.height();
|
||||
|
||||
if (x + wd > scMaxX) {
|
||||
x = scMaxX - wd;
|
||||
}
|
||||
|
||||
if (x < scX) {
|
||||
x = scX;
|
||||
}
|
||||
|
||||
if (y + hgh > scMaxY) {
|
||||
y = scMaxY - hgh;
|
||||
}
|
||||
|
||||
if (y < scY) {
|
||||
y = scY;
|
||||
}
|
||||
|
||||
var pos = {};
|
||||
pos.top = y;
|
||||
pos.left = x;
|
||||
elem.css(pos);
|
||||
$(e.currentTarget.parentNode).find('#api_information_panel').show();
|
||||
},
|
||||
|
||||
mouseExit: function(e) {
|
||||
$(e.currentTarget.parentNode).find('#api_information_panel').hide();
|
||||
},
|
||||
|
||||
// Note: copied from CoffeeScript compiled file
|
||||
// TODO: redactor
|
||||
render: function() {
|
||||
var a, auth, auths, code, contentTypeModel, isMethodSubmissionSupported, k, key, l, len, len1, len2, len3, len4, m, modelAuths, n, o, p, param, q, ref, ref1, ref2, ref3, ref4, ref5, responseContentTypeView, responseSignatureView, schema, schemaObj, scopeIndex, signatureModel, statusCode, successResponse, type, v, value;
|
||||
isMethodSubmissionSupported = jQuery.inArray(this.model.method, this.model.supportedSubmitMethods()) >= 0;
|
||||
if (!isMethodSubmissionSupported) {
|
||||
this.model.isReadOnly = true;
|
||||
}
|
||||
this.model.description = this.model.description || this.model.notes;
|
||||
if (this.model.description) {
|
||||
this.model.description = this.model.description.replace(/(?:\r\n|\r|\n)/g, '<br />');
|
||||
}
|
||||
this.model.oauth = null;
|
||||
modelAuths = this.model.authorizations || this.model.security;
|
||||
if (modelAuths) {
|
||||
if (Array.isArray(modelAuths)) {
|
||||
for (l = 0, len = modelAuths.length; l < len; l++) {
|
||||
auths = modelAuths[l];
|
||||
for (key in auths) {
|
||||
auth = auths[key];
|
||||
for (a in this.auths) {
|
||||
auth = this.auths[a];
|
||||
if (auth.type === 'oauth2') {
|
||||
this.model.oauth = {};
|
||||
this.model.oauth.scopes = [];
|
||||
ref1 = auth.value.scopes;
|
||||
for (k in ref1) {
|
||||
v = ref1[k];
|
||||
scopeIndex = auths[key].indexOf(k);
|
||||
if (scopeIndex >= 0) {
|
||||
o = {
|
||||
scope: k,
|
||||
description: v
|
||||
};
|
||||
this.model.oauth.scopes.push(o);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (k in modelAuths) {
|
||||
v = modelAuths[k];
|
||||
if (k === 'oauth2') {
|
||||
if (this.model.oauth === null) {
|
||||
this.model.oauth = {};
|
||||
}
|
||||
if (this.model.oauth.scopes === void 0) {
|
||||
this.model.oauth.scopes = [];
|
||||
}
|
||||
for (m = 0, len1 = v.length; m < len1; m++) {
|
||||
o = v[m];
|
||||
this.model.oauth.scopes.push(o);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (typeof this.model.responses !== 'undefined') {
|
||||
this.model.responseMessages = [];
|
||||
ref2 = this.model.responses;
|
||||
for (code in ref2) {
|
||||
value = ref2[code];
|
||||
schema = null;
|
||||
schemaObj = this.model.responses[code].schema;
|
||||
if (schemaObj && schemaObj.$ref) {
|
||||
schema = schemaObj.$ref;
|
||||
if (schema.indexOf('#/definitions/') === 0) {
|
||||
schema = schema.substring('#/definitions/'.length);
|
||||
}
|
||||
}
|
||||
this.model.responseMessages.push({
|
||||
code: code,
|
||||
message: value.description,
|
||||
responseModel: schema
|
||||
});
|
||||
}
|
||||
}
|
||||
if (typeof this.model.responseMessages === 'undefined') {
|
||||
this.model.responseMessages = [];
|
||||
}
|
||||
signatureModel = null;
|
||||
if (this.model.successResponse) {
|
||||
successResponse = this.model.successResponse;
|
||||
for (key in successResponse) {
|
||||
value = successResponse[key];
|
||||
this.model.successCode = key;
|
||||
if (typeof value === 'object' && typeof value.createJSONSample === 'function') {
|
||||
signatureModel = {
|
||||
sampleJSON: JSON.stringify(value.createJSONSample(), void 0, 2),
|
||||
isParam: false,
|
||||
signature: value.getMockSignature()
|
||||
};
|
||||
}
|
||||
}
|
||||
} else if (this.model.responseClassSignature && this.model.responseClassSignature !== 'string') {
|
||||
signatureModel = {
|
||||
sampleJSON: this.model.responseSampleJSON,
|
||||
isParam: false,
|
||||
signature: this.model.responseClassSignature
|
||||
};
|
||||
}
|
||||
$(this.el).html(Handlebars.templates.operation(this.model));
|
||||
if (signatureModel) {
|
||||
responseSignatureView = new SwaggerUi.Views.SignatureView({
|
||||
model: signatureModel,
|
||||
tagName: 'div'
|
||||
});
|
||||
$('.model-signature', $(this.el)).append(responseSignatureView.render().el);
|
||||
} else {
|
||||
this.model.responseClassSignature = 'string';
|
||||
$('.model-signature', $(this.el)).html(this.model.type);
|
||||
}
|
||||
contentTypeModel = {
|
||||
isParam: false
|
||||
};
|
||||
contentTypeModel.consumes = this.model.consumes;
|
||||
contentTypeModel.produces = this.model.produces;
|
||||
ref3 = this.model.parameters;
|
||||
for (n = 0, len2 = ref3.length; n < len2; n++) {
|
||||
param = ref3[n];
|
||||
type = param.type || param.dataType || '';
|
||||
if (typeof type === 'undefined') {
|
||||
schema = param.schema;
|
||||
if (schema && schema.$ref) {
|
||||
ref = schema.$ref;
|
||||
if (ref.indexOf('#/definitions/') === 0) {
|
||||
type = ref.substring('#/definitions/'.length);
|
||||
} else {
|
||||
type = ref;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (type && type.toLowerCase() === 'file') {
|
||||
if (!contentTypeModel.consumes) {
|
||||
contentTypeModel.consumes = 'multipart/form-data';
|
||||
}
|
||||
}
|
||||
param.type = type;
|
||||
}
|
||||
responseContentTypeView = new SwaggerUi.Views.ResponseContentTypeView({
|
||||
model: contentTypeModel
|
||||
});
|
||||
$('.response-content-type', $(this.el)).append(responseContentTypeView.render().el);
|
||||
ref4 = this.model.parameters;
|
||||
for (p = 0, len3 = ref4.length; p < len3; p++) {
|
||||
param = ref4[p];
|
||||
this.addParameter(param, contentTypeModel.consumes);
|
||||
}
|
||||
ref5 = this.model.responseMessages;
|
||||
for (q = 0, len4 = ref5.length; q < len4; q++) {
|
||||
statusCode = ref5[q];
|
||||
this.addStatusCode(statusCode);
|
||||
}
|
||||
return this;
|
||||
},
|
||||
|
||||
addParameter: function(param, consumes) {
|
||||
// Render a parameter
|
||||
param.consumes = consumes;
|
||||
var paramView = new SwaggerUi.Views.ParameterView({
|
||||
model: param,
|
||||
tagName: 'tr',
|
||||
readOnly: this.model.isReadOnly
|
||||
});
|
||||
$('.operation-params', $(this.el)).append(paramView.render().el);
|
||||
},
|
||||
|
||||
addStatusCode: function(statusCode) {
|
||||
// Render status codes
|
||||
var statusCodeView = new SwaggerUi.Views.StatusCodeView({model: statusCode, tagName: 'tr'});
|
||||
$('.operation-status', $(this.el)).append(statusCodeView.render().el);
|
||||
},
|
||||
|
||||
// Note: copied from CoffeeScript compiled file
|
||||
// TODO: redactor
|
||||
submitOperation: function(e) {
|
||||
var error_free, form, isFileUpload, l, len, len1, len2, m, map, n, o, opts, ref1, ref2, ref3, val;
|
||||
if (e !== null) {
|
||||
e.preventDefault();
|
||||
}
|
||||
form = $('.sandbox', $(this.el));
|
||||
error_free = true;
|
||||
form.find('input.required').each(function() {
|
||||
$(this).removeClass('error');
|
||||
if (jQuery.trim($(this).val()) === '') {
|
||||
$(this).addClass('error');
|
||||
$(this).wiggle({
|
||||
callback: (function(_this) {
|
||||
return function() {
|
||||
$(_this).focus();
|
||||
};
|
||||
})(this)
|
||||
});
|
||||
error_free = false;
|
||||
}
|
||||
});
|
||||
form.find('textarea.required').each(function() {
|
||||
$(this).removeClass('error');
|
||||
if (jQuery.trim($(this).val()) === '') {
|
||||
$(this).addClass('error');
|
||||
$(this).wiggle({
|
||||
callback: (function(_this) {
|
||||
return function() {
|
||||
return $(_this).focus();
|
||||
};
|
||||
})(this)
|
||||
});
|
||||
error_free = false;
|
||||
}
|
||||
});
|
||||
if (error_free) {
|
||||
map = {};
|
||||
opts = {
|
||||
parent: this
|
||||
};
|
||||
isFileUpload = false;
|
||||
ref1 = form.find('input');
|
||||
for (l = 0, len = ref1.length; l < len; l++) {
|
||||
o = ref1[l];
|
||||
if ((o.value !== null) && jQuery.trim(o.value).length > 0) {
|
||||
map[o.name] = o.value;
|
||||
}
|
||||
if (o.type === 'file') {
|
||||
map[o.name] = o.files[0];
|
||||
isFileUpload = true;
|
||||
}
|
||||
}
|
||||
ref2 = form.find('textarea');
|
||||
for (m = 0, len1 = ref2.length; m < len1; m++) {
|
||||
o = ref2[m];
|
||||
if ((o.value !== null) && jQuery.trim(o.value).length > 0) {
|
||||
map[o.name] = o.value;
|
||||
}
|
||||
}
|
||||
ref3 = form.find('select');
|
||||
for (n = 0, len2 = ref3.length; n < len2; n++) {
|
||||
o = ref3[n];
|
||||
val = this.getSelectedValue(o);
|
||||
if ((val !== null) && jQuery.trim(val).length > 0) {
|
||||
map[o.name] = val;
|
||||
}
|
||||
}
|
||||
opts.responseContentType = $('div select[name=responseContentType]', $(this.el)).val();
|
||||
opts.requestContentType = $('div select[name=parameterContentType]', $(this.el)).val();
|
||||
$('.response_throbber', $(this.el)).show();
|
||||
if (isFileUpload) {
|
||||
return this.handleFileUpload(map, form);
|
||||
} else {
|
||||
return this.model['do'](map, opts, this.showCompleteStatus, this.showErrorStatus, this);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
success: function(response, parent) {
|
||||
parent.showCompleteStatus(response);
|
||||
},
|
||||
|
||||
// Note: This is compiled code
|
||||
// TODO: Refactor
|
||||
handleFileUpload: function(map, form) {
|
||||
var bodyParam, el, headerParams, l, len, len1, len2, len3, m, n, o, obj, p, param, params, ref1, ref2, ref3, ref4;
|
||||
ref1 = form.serializeArray();
|
||||
for (l = 0, len = ref1.length; l < len; l++) {
|
||||
o = ref1[l];
|
||||
if ((o.value !== null) && jQuery.trim(o.value).length > 0) {
|
||||
map[o.name] = o.value;
|
||||
}
|
||||
}
|
||||
bodyParam = new FormData();
|
||||
params = 0;
|
||||
ref2 = this.model.parameters;
|
||||
for (m = 0, len1 = ref2.length; m < len1; m++) {
|
||||
param = ref2[m];
|
||||
if (param.paramType === 'form' || param['in'] === 'formData') {
|
||||
if (param.type.toLowerCase() !== 'file' && map[param.name] !== void 0) {
|
||||
bodyParam.append(param.name, map[param.name]);
|
||||
}
|
||||
}
|
||||
}
|
||||
headerParams = {};
|
||||
ref3 = this.model.parameters;
|
||||
for (n = 0, len2 = ref3.length; n < len2; n++) {
|
||||
param = ref3[n];
|
||||
if (param.paramType === 'header') {
|
||||
headerParams[param.name] = map[param.name];
|
||||
}
|
||||
}
|
||||
ref4 = form.find('input[type~="file"]');
|
||||
for (p = 0, len3 = ref4.length; p < len3; p++) {
|
||||
el = ref4[p];
|
||||
if (typeof el.files[0] !== 'undefined') {
|
||||
bodyParam.append($(el).attr('name'), el.files[0]);
|
||||
params += 1;
|
||||
}
|
||||
}
|
||||
this.invocationUrl = this.model.supportHeaderParams() ? (headerParams = this.model.getHeaderParams(map), delete headerParams['Content-Type'], this.model.urlify(map, false)) : this.model.urlify(map, true);
|
||||
$('.request_url', $(this.el)).html('<pre></pre>');
|
||||
$('.request_url pre', $(this.el)).text(this.invocationUrl);
|
||||
obj = {
|
||||
type: this.model.method,
|
||||
url: this.invocationUrl,
|
||||
headers: headerParams,
|
||||
data: bodyParam,
|
||||
dataType: 'json',
|
||||
contentType: false,
|
||||
processData: false,
|
||||
error: (function(_this) {
|
||||
return function(data) {
|
||||
return _this.showErrorStatus(_this.wrap(data), _this);
|
||||
};
|
||||
})(this),
|
||||
success: (function(_this) {
|
||||
return function(data) {
|
||||
return _this.showResponse(data, _this);
|
||||
};
|
||||
})(this),
|
||||
complete: (function(_this) {
|
||||
return function(data) {
|
||||
return _this.showCompleteStatus(_this.wrap(data), _this);
|
||||
};
|
||||
})(this)
|
||||
};
|
||||
if (window.authorizations) {
|
||||
window.authorizations.apply(obj);
|
||||
}
|
||||
if (params === 0) {
|
||||
obj.data.append('fake', 'true');
|
||||
}
|
||||
jQuery.ajax(obj);
|
||||
return false;
|
||||
// end of file-upload nastiness
|
||||
},
|
||||
// wraps a jquery response as a shred response
|
||||
|
||||
wrap: function(data) {
|
||||
var h, headerArray, headers, i, l, len, o;
|
||||
headers = {};
|
||||
headerArray = data.getAllResponseHeaders().split('\r');
|
||||
for (l = 0, len = headerArray.length; l < len; l++) {
|
||||
i = headerArray[l];
|
||||
h = i.match(/^([^:]*?):(.*)$/);
|
||||
if (!h) {
|
||||
h = [];
|
||||
}
|
||||
h.shift();
|
||||
if (h[0] !== void 0 && h[1] !== void 0) {
|
||||
headers[h[0].trim()] = h[1].trim();
|
||||
}
|
||||
}
|
||||
o = {};
|
||||
o.content = {};
|
||||
o.content.data = data.responseText;
|
||||
o.headers = headers;
|
||||
o.request = {};
|
||||
o.request.url = this.invocationUrl;
|
||||
o.status = data.status;
|
||||
return o;
|
||||
},
|
||||
|
||||
getSelectedValue: function(select) {
|
||||
if (!select.multiple) {
|
||||
return select.value;
|
||||
} else {
|
||||
var options = [];
|
||||
for (var l = 0, len = select.options.length; l < len; l++) {
|
||||
var opt = select.options[l];
|
||||
if (opt.selected) {
|
||||
options.push(opt.value);
|
||||
}
|
||||
}
|
||||
if (options.length > 0) {
|
||||
return options;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// handler for hide response link
|
||||
hideResponse: function(e) {
|
||||
if (e) { e.preventDefault(); }
|
||||
$('.response', $(this.el)).slideUp();
|
||||
$('.response_hider', $(this.el)).fadeOut();
|
||||
},
|
||||
|
||||
// Show response from server
|
||||
showResponse: function(response) {
|
||||
var prettyJson = JSON.stringify(response, null, '\t').replace(/\n/g, '<br>');
|
||||
$('.response_body', $(this.el)).html(_.escape(prettyJson));
|
||||
},
|
||||
|
||||
// Show error from server
|
||||
showErrorStatus: function(data, parent) {
|
||||
parent.showStatus(data);
|
||||
},
|
||||
|
||||
// show the status codes
|
||||
showCompleteStatus: function(data, parent){
|
||||
parent.showStatus(data);
|
||||
},
|
||||
|
||||
// Adapted from http://stackoverflow.com/a/2893259/454004
|
||||
// Note: directly ported from CoffeeScript
|
||||
// TODO: Cleanup CoffeeScript artifacts
|
||||
formatXml: function(xml) {
|
||||
var contexp, fn, formatted, indent, l, lastType, len, lines, ln, pad, reg, transitions, wsexp;
|
||||
reg = /(>)(<)(\/*)/g;
|
||||
wsexp = /[ ]*(.*)[ ]+\n/g;
|
||||
contexp = /(<.+>)(.+\n)/g;
|
||||
xml = xml.replace(reg, '$1\n$2$3').replace(wsexp, '$1\n').replace(contexp, '$1\n$2');
|
||||
pad = 0;
|
||||
formatted = '';
|
||||
lines = xml.split('\n');
|
||||
indent = 0;
|
||||
lastType = 'other';
|
||||
transitions = {
|
||||
'single->single': 0,
|
||||
'single->closing': -1,
|
||||
'single->opening': 0,
|
||||
'single->other': 0,
|
||||
'closing->single': 0,
|
||||
'closing->closing': -1,
|
||||
'closing->opening': 0,
|
||||
'closing->other': 0,
|
||||
'opening->single': 1,
|
||||
'opening->closing': 0,
|
||||
'opening->opening': 1,
|
||||
'opening->other': 1,
|
||||
'other->single': 0,
|
||||
'other->closing': -1,
|
||||
'other->opening': 0,
|
||||
'other->other': 0
|
||||
};
|
||||
fn = function(ln) {
|
||||
var fromTo, j, key, padding, type, types, value;
|
||||
types = {
|
||||
single: Boolean(ln.match(/<.+\/>/)),
|
||||
closing: Boolean(ln.match(/<\/.+>/)),
|
||||
opening: Boolean(ln.match(/<[^!?].*>/))
|
||||
};
|
||||
type = ((function() {
|
||||
var results;
|
||||
results = [];
|
||||
for (key in types) {
|
||||
value = types[key];
|
||||
if (value) {
|
||||
results.push(key);
|
||||
}
|
||||
}
|
||||
return results;
|
||||
})())[0];
|
||||
type = type === void 0 ? 'other' : type;
|
||||
fromTo = lastType + '->' + type;
|
||||
lastType = type;
|
||||
padding = '';
|
||||
indent += transitions[fromTo];
|
||||
padding = ((function() {
|
||||
var m, ref1, results;
|
||||
results = [];
|
||||
for (j = m = 0, ref1 = indent; 0 <= ref1 ? m < ref1 : m > ref1; j = 0 <= ref1 ? ++m : --m) {
|
||||
results.push(' ');
|
||||
}
|
||||
return results;
|
||||
})()).join('');
|
||||
if (fromTo === 'opening->closing') {
|
||||
formatted = formatted.substr(0, formatted.length - 1) + ln + '\n';
|
||||
} else {
|
||||
formatted += padding + ln + '\n';
|
||||
}
|
||||
};
|
||||
for (l = 0, len = lines.length; l < len; l++) {
|
||||
ln = lines[l];
|
||||
fn(ln);
|
||||
}
|
||||
return formatted;
|
||||
},
|
||||
|
||||
// puts the response data in UI
|
||||
showStatus: function(response) {
|
||||
var url, content;
|
||||
if (response.content === undefined) {
|
||||
content = response.data;
|
||||
url = response.url;
|
||||
} else {
|
||||
content = response.content.data;
|
||||
url = response.request.url;
|
||||
}
|
||||
var headers = response.headers;
|
||||
|
||||
// if server is nice, and sends content-type back, we can use it
|
||||
var contentType = null;
|
||||
if (headers) {
|
||||
contentType = headers['Content-Type'] || headers['content-type'];
|
||||
if (contentType) {
|
||||
contentType = contentType.split(';')[0].trim();
|
||||
}
|
||||
}
|
||||
$('.response_body', $(this.el)).removeClass('json');
|
||||
$('.response_body', $(this.el)).removeClass('xml');
|
||||
|
||||
var supportsAudioPlayback = function(contentType){
|
||||
var audioElement = document.createElement('audio');
|
||||
return !!(audioElement.canPlayType && audioElement.canPlayType(contentType).replace(/no/, ''));
|
||||
};
|
||||
|
||||
var pre;
|
||||
var code;
|
||||
if (!content) {
|
||||
code = $('<code />').text('no content');
|
||||
pre = $('<pre class="json" />').append(code);
|
||||
} else if (contentType === 'application/json' || /\+json$/.test(contentType)) {
|
||||
var json = null;
|
||||
try {
|
||||
json = JSON.stringify(JSON.parse(content), null, ' ');
|
||||
} catch (_error) {
|
||||
json = 'can\'t parse JSON. Raw result:\n\n' + content;
|
||||
}
|
||||
code = $('<code />').text(json);
|
||||
pre = $('<pre class="json" />').append(code);
|
||||
} else if (contentType === 'application/xml' || /\+xml$/.test(contentType)) {
|
||||
code = $('<code />').text(this.formatXml(content));
|
||||
pre = $('<pre class="xml" />').append(code);
|
||||
} else if (contentType === 'text/html') {
|
||||
code = $('<code />').html(_.escape(content));
|
||||
pre = $('<pre class="xml" />').append(code);
|
||||
} else if (/^image\//.test(contentType)) {
|
||||
pre = $('<img>').attr('src', url);
|
||||
} else if (/^audio\//.test(contentType) && supportsAudioPlayback(contentType)) {
|
||||
pre = $('<audio controls>').append($('<source>').attr('src', url).attr('type', contentType));
|
||||
} else {
|
||||
code = $('<code />').text(content);
|
||||
pre = $('<pre class="json" />').append(code);
|
||||
}
|
||||
var response_body = pre;
|
||||
$('.request_url', $(this.el)).html('<pre></pre>');
|
||||
$('.request_url pre', $(this.el)).text(url);
|
||||
$('.response_code', $(this.el)).html('<pre>' + response.status + '</pre>');
|
||||
$('.response_body', $(this.el)).html(response_body);
|
||||
$('.response_headers', $(this.el)).html('<pre>' + _.escape(JSON.stringify(response.headers, null, ' ')).replace(/\n/g, '<br>') + '</pre>');
|
||||
$('.response', $(this.el)).slideDown();
|
||||
$('.response_hider', $(this.el)).show();
|
||||
$('.response_throbber', $(this.el)).hide();
|
||||
var response_body_el = $('.response_body', $(this.el))[0];
|
||||
|
||||
// only highlight the response if response is less than threshold, default state is highlight response
|
||||
var opts = this.options.swaggerOptions;
|
||||
if (opts.highlightSizeThreshold && response.data.length > opts.highlightSizeThreshold) {
|
||||
return response_body_el;
|
||||
} else {
|
||||
return hljs.highlightBlock(response_body_el);
|
||||
}
|
||||
},
|
||||
|
||||
toggleOperationContent: function() {
|
||||
var elem = $('#' + Docs.escapeResourceName(this.parentId + '_' + this.nickname + '_content'));
|
||||
if (elem.is(':visible')){
|
||||
Docs.collapseOperation(elem);
|
||||
} else {
|
||||
Docs.expandOperation(elem);
|
||||
}
|
||||
}
|
||||
});
|
||||
14
src/main/javascript/view/ParameterContentTypeView.js
Normal file
14
src/main/javascript/view/ParameterContentTypeView.js
Normal file
@@ -0,0 +1,14 @@
|
||||
'use strict';
|
||||
|
||||
SwaggerUi.Views.ParameterContentTypeView = Backbone.View.extend({
|
||||
initialize: function () {},
|
||||
|
||||
render: function(){
|
||||
$(this.el).html(Handlebars.templates.parameter_content_type(this.model));
|
||||
|
||||
$('label[for=parameterContentType]', $(this.el)).text('Parameter content type:');
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
});
|
||||
101
src/main/javascript/view/ParameterView.js
Normal file
101
src/main/javascript/view/ParameterView.js
Normal file
@@ -0,0 +1,101 @@
|
||||
'use strict';
|
||||
|
||||
SwaggerUi.Views.ParameterView = Backbone.View.extend({
|
||||
initialize: function(){
|
||||
Handlebars.registerHelper('isArray', function(param, opts) {
|
||||
if (param.type.toLowerCase() === 'array' || param.allowMultiple) {
|
||||
opts.fn(this);
|
||||
} else {
|
||||
opts.inverse(this);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
render: function() {
|
||||
var type = this.model.type || this.model.dataType;
|
||||
|
||||
if (typeof type === 'undefined') {
|
||||
var schema = this.model.schema;
|
||||
if (schema && schema.$ref) {
|
||||
var ref = schema.$ref;
|
||||
if (ref.indexOf('#/definitions/') === 0) {
|
||||
type = ref.substring('#/definitions/'.length);
|
||||
} else {
|
||||
type = ref;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.model.type = type;
|
||||
this.model.paramType = this.model.in || this.model.paramType;
|
||||
this.model.isBody = this.model.paramType === 'body' || this.model.in === 'body';
|
||||
this.model.isFile = type && type.toLowerCase() === 'file';
|
||||
this.model.default = (this.model.default || this.model.defaultValue);
|
||||
|
||||
if (this.model.allowableValues) {
|
||||
this.model.isList = true;
|
||||
}
|
||||
|
||||
var template = this.template();
|
||||
$(this.el).html(template(this.model));
|
||||
|
||||
var signatureModel = {
|
||||
sampleJSON: this.model.sampleJSON,
|
||||
isParam: true,
|
||||
signature: this.model.signature
|
||||
};
|
||||
|
||||
if (this.model.sampleJSON) {
|
||||
var signatureView = new SwaggerUi.Views.SignatureView({model: signatureModel, tagName: 'div'});
|
||||
$('.model-signature', $(this.el)).append(signatureView.render().el);
|
||||
}
|
||||
else {
|
||||
$('.model-signature', $(this.el)).html(this.model.signature);
|
||||
}
|
||||
|
||||
var isParam = false;
|
||||
|
||||
if (this.model.isBody) {
|
||||
isParam = true;
|
||||
}
|
||||
|
||||
var contentTypeModel = {
|
||||
isParam: isParam
|
||||
};
|
||||
|
||||
contentTypeModel.consumes = this.model.consumes;
|
||||
|
||||
if (isParam) {
|
||||
var parameterContentTypeView = new SwaggerUi.Views.ParameterContentTypeView({model: contentTypeModel});
|
||||
$('.parameter-content-type', $(this.el)).append(parameterContentTypeView.render().el);
|
||||
}
|
||||
|
||||
else {
|
||||
var responseContentTypeView = new SwaggerUi.Views.ResponseContentTypeView({model: contentTypeModel});
|
||||
$('.response-content-type', $(this.el)).append(responseContentTypeView.render().el);
|
||||
}
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
// Return an appropriate template based on if the parameter is a list, readonly, required
|
||||
template: function(){
|
||||
if (this.model.isList) {
|
||||
return Handlebars.templates.param_list;
|
||||
} else {
|
||||
if (this.options.readOnly) {
|
||||
if (this.model.required) {
|
||||
return Handlebars.templates.param_readonly_required;
|
||||
} else {
|
||||
return Handlebars.templates.param_readonly;
|
||||
}
|
||||
} else {
|
||||
if (this.model.required) {
|
||||
return Handlebars.templates.param_required;
|
||||
} else {
|
||||
return Handlebars.templates.param;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
71
src/main/javascript/view/ResourceView.js
Normal file
71
src/main/javascript/view/ResourceView.js
Normal file
@@ -0,0 +1,71 @@
|
||||
'use strict';
|
||||
|
||||
SwaggerUi.Views.ResourceView = Backbone.View.extend({
|
||||
initialize: function(opts) {
|
||||
opts = opts || {};
|
||||
this.auths = opts.auths;
|
||||
if ('' === this.model.description) {
|
||||
this.model.description = null;
|
||||
}
|
||||
if (this.model.description) {
|
||||
this.model.summary = this.model.description;
|
||||
}
|
||||
},
|
||||
|
||||
render: function(){
|
||||
var methods = {};
|
||||
|
||||
|
||||
$(this.el).html(Handlebars.templates.resource(this.model));
|
||||
|
||||
// Render each operation
|
||||
for (var i = 0; i < this.model.operationsArray.length; i++) {
|
||||
var operation = this.model.operationsArray[i];
|
||||
var counter = 0;
|
||||
var id = operation.nickname;
|
||||
|
||||
while (typeof methods[id] !== 'undefined') {
|
||||
id = id + '_' + counter;
|
||||
counter += 1;
|
||||
}
|
||||
|
||||
methods[id] = operation;
|
||||
|
||||
operation.nickname = id;
|
||||
operation.parentId = this.model.id;
|
||||
this.addOperation(operation);
|
||||
}
|
||||
|
||||
$('.toggleEndpointList', this.el).click(this.callDocs.bind(this, 'toggleEndpointListForResource'));
|
||||
$('.collapseResource', this.el).click(this.callDocs.bind(this, 'collapseOperationsForResource'));
|
||||
$('.expandResource', this.el).click(this.callDocs.bind(this, 'expandOperationsForResource'));
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
addOperation: function(operation) {
|
||||
|
||||
operation.number = this.number;
|
||||
|
||||
// Render an operation and add it to operations li
|
||||
var operationView = new SwaggerUi.Views.OperationView({
|
||||
model: operation,
|
||||
tagName: 'li',
|
||||
className: 'endpoint',
|
||||
swaggerOptions: this.options.swaggerOptions,
|
||||
auths: this.auths
|
||||
});
|
||||
|
||||
$('.endpoints', $(this.el)).append(operationView.render().el);
|
||||
|
||||
this.number++;
|
||||
|
||||
},
|
||||
// Generic Event handler (`Docs` is global)
|
||||
|
||||
|
||||
callDocs: function(fnName, e) {
|
||||
e.preventDefault();
|
||||
Docs[fnName](e.currentTarget.getAttribute('data-id'));
|
||||
}
|
||||
});
|
||||
13
src/main/javascript/view/ResponseContentTypeView.js
Normal file
13
src/main/javascript/view/ResponseContentTypeView.js
Normal file
@@ -0,0 +1,13 @@
|
||||
'use strict';
|
||||
|
||||
SwaggerUi.Views.ResponseContentTypeView = Backbone.View.extend({
|
||||
initialize: function(){},
|
||||
|
||||
render: function(){
|
||||
$(this.el).html(Handlebars.templates.response_content_type(this.model));
|
||||
|
||||
$('label[for=responseContentType]', $(this.el)).text('Response Content Type');
|
||||
|
||||
return this;
|
||||
}
|
||||
});
|
||||
60
src/main/javascript/view/SignatureView.js
Normal file
60
src/main/javascript/view/SignatureView.js
Normal file
@@ -0,0 +1,60 @@
|
||||
'use strict';
|
||||
|
||||
SwaggerUi.Views.SignatureView = Backbone.View.extend({
|
||||
events: {
|
||||
'click a.description-link' : 'switchToDescription',
|
||||
'click a.snippet-link' : 'switchToSnippet',
|
||||
'mousedown .snippet' : 'snippetToTextArea'
|
||||
},
|
||||
|
||||
initialize: function () {
|
||||
|
||||
},
|
||||
|
||||
render: function(){
|
||||
|
||||
$(this.el).html(Handlebars.templates.signature(this.model));
|
||||
|
||||
this.switchToSnippet();
|
||||
|
||||
this.isParam = this.model.isParam;
|
||||
|
||||
if (this.isParam) {
|
||||
$('.notice', $(this.el)).text('Click to set as parameter value');
|
||||
}
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
// handler for show signature
|
||||
switchToDescription: function(e){
|
||||
if (e) { e.preventDefault(); }
|
||||
|
||||
$('.snippet', $(this.el)).hide();
|
||||
$('.description', $(this.el)).show();
|
||||
$('.description-link', $(this.el)).addClass('selected');
|
||||
$('.snippet-link', $(this.el)).removeClass('selected');
|
||||
},
|
||||
|
||||
// handler for show sample
|
||||
switchToSnippet: function(e){
|
||||
if (e) { e.preventDefault(); }
|
||||
|
||||
$('.description', $(this.el)).hide();
|
||||
$('.snippet', $(this.el)).show();
|
||||
$('.snippet-link', $(this.el)).addClass('selected');
|
||||
$('.description-link', $(this.el)).removeClass('selected');
|
||||
},
|
||||
|
||||
// handler for snippet to text area
|
||||
snippetToTextArea: function(e) {
|
||||
if (this.isParam) {
|
||||
if (e) { e.preventDefault(); }
|
||||
|
||||
var textArea = $('textarea', $(this.el.parentNode.parentNode.parentNode));
|
||||
if ($.trim(textArea.val()) === '') {
|
||||
textArea.val(this.model.sampleJSON);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
26
src/main/javascript/view/StatusCodeView.js
Normal file
26
src/main/javascript/view/StatusCodeView.js
Normal file
@@ -0,0 +1,26 @@
|
||||
'use strict';
|
||||
|
||||
SwaggerUi.Views.StatusCodeView = Backbone.View.extend({
|
||||
initialize: function () {
|
||||
|
||||
},
|
||||
|
||||
render: function(){
|
||||
$(this.el).html(Handlebars.templates.status_code(this.model));
|
||||
|
||||
// TODO get rid of "swaggerUi" global dependency
|
||||
if (swaggerUi.api.models.hasOwnProperty(this.model.responseModel)) {
|
||||
var responseModel = {
|
||||
sampleJSON: JSON.stringify(swaggerUi.api.models[this.model.responseModel].createJSONSample(), null, 2),
|
||||
isParam: false,
|
||||
signature: swaggerUi.api.models[this.model.responseModel].getMockSignature(),
|
||||
};
|
||||
|
||||
var responseModelView = new SwaggerUi.Views.SignatureView({model: responseModel, tagName: 'div'});
|
||||
$('.model-signature', this.$el).append(responseModelView.render().el);
|
||||
} else {
|
||||
$('.model-signature', this.$el).html('');
|
||||
}
|
||||
return this;
|
||||
}
|
||||
});
|
||||
10
test/.jshintrc
Normal file
10
test/.jshintrc
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"extends": "../.jshintrc",
|
||||
"expr": true,
|
||||
"jasmine": true,
|
||||
"globals": {
|
||||
"before": false,
|
||||
"after": false,
|
||||
"expect": true
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
/*
|
||||
* Web driver manager
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var webdriver = require('selenium-webdriver');
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
/*
|
||||
* Swagger UI and Specs Servers
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var path = require('path');
|
||||
var createServer = require('http-server').createServer;
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
'use strict';
|
||||
|
||||
var expect = require('chai').expect;
|
||||
var driver = require('./driver');
|
||||
var servers = require('./servers');
|
||||
@@ -13,7 +15,7 @@ var elements = [
|
||||
'header'
|
||||
];
|
||||
|
||||
describe('swagger 1.x spec tests', function (done) {
|
||||
describe('swagger 1.x spec tests', function () {
|
||||
this.timeout(10 * 1000);
|
||||
|
||||
before(function (done) {
|
||||
@@ -27,8 +29,9 @@ describe('swagger 1.x spec tests', function (done) {
|
||||
var errors = [];
|
||||
browserLogs.forEach(function(log){
|
||||
// 900 and above is "error" level. Console should not have any errors
|
||||
if (log.level.value > 900)
|
||||
if (log.level.value > 900) {
|
||||
console.log('browser error message:', log.message); errors.push(log);
|
||||
}
|
||||
});
|
||||
expect(errors).to.be.empty;
|
||||
done();
|
||||
@@ -46,7 +49,7 @@ describe('swagger 1.x spec tests', function (done) {
|
||||
|
||||
elements.forEach(function (id) {
|
||||
it('should render element: ' + id, function (done) {
|
||||
var locator = webdriver.By.id(id)
|
||||
var locator = webdriver.By.id(id);
|
||||
driver.isElementPresent(locator).then(function (isPresent) {
|
||||
expect(isPresent).to.be.true;
|
||||
done();
|
||||
@@ -63,7 +66,7 @@ describe('swagger 1.x spec tests', function (done) {
|
||||
});
|
||||
|
||||
it('should find the pet link', function(done){
|
||||
var locator = webdriver.By.xpath("//*[@data-id='pet']");
|
||||
var locator = webdriver.By.xpath('//*[@data-id="pet"]');
|
||||
driver.isElementPresent(locator).then(function (isPresent) {
|
||||
expect(isPresent).to.be.true;
|
||||
done();
|
||||
@@ -71,7 +74,7 @@ describe('swagger 1.x spec tests', function (done) {
|
||||
});
|
||||
|
||||
it('should find the pet resource description', function(done){
|
||||
var locator = webdriver.By.xpath("//div[contains(., 'Operations about pets')]");
|
||||
var locator = webdriver.By.xpath('//div[contains(., "Operations about pets")]');
|
||||
driver.findElements(locator).then(function (elements) {
|
||||
expect(elements.length).to.not.equal(0);
|
||||
done();
|
||||
@@ -79,7 +82,7 @@ describe('swagger 1.x spec tests', function (done) {
|
||||
});
|
||||
|
||||
it('should find the user link', function(done){
|
||||
var locator = webdriver.By.xpath("//*[@data-id='user']");
|
||||
var locator = webdriver.By.xpath('//*[@data-id="user"]');
|
||||
driver.isElementPresent(locator).then(function (isPresent) {
|
||||
expect(isPresent).to.be.true;
|
||||
done();
|
||||
@@ -87,7 +90,7 @@ describe('swagger 1.x spec tests', function (done) {
|
||||
});
|
||||
|
||||
it('should find the store link', function(done){
|
||||
var locator = webdriver.By.xpath("//*[@data-id='store']");
|
||||
var locator = webdriver.By.xpath('//*[@data-id="store"]');
|
||||
driver.isElementPresent(locator).then(function (isPresent) {
|
||||
expect(isPresent).to.be.true;
|
||||
done();
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
'use strict';
|
||||
|
||||
var expect = require('chai').expect;
|
||||
var webdriver = require('selenium-webdriver');
|
||||
var driver = require('./driver');
|
||||
@@ -14,7 +16,7 @@ var elements = [
|
||||
'header'
|
||||
];
|
||||
|
||||
describe('swagger 2.0 spec tests', function (done) {
|
||||
describe('swagger 2.0 spec tests', function () {
|
||||
this.timeout(10 * 1000);
|
||||
|
||||
before(function (done) {
|
||||
@@ -28,8 +30,9 @@ describe('swagger 2.0 spec tests', function (done) {
|
||||
var errors = [];
|
||||
browserLogs.forEach(function(log){
|
||||
// 900 and above is "error" level. Console should not have any errors
|
||||
if (log.level.value > 900)
|
||||
if (log.level.value > 900) {
|
||||
console.log('browser error message:', log.message); errors.push(log);
|
||||
}
|
||||
});
|
||||
expect(errors).to.be.empty;
|
||||
done();
|
||||
@@ -80,7 +83,7 @@ describe('swagger 2.0 spec tests', function (done) {
|
||||
});
|
||||
|
||||
it('should find the pet link', function(done){
|
||||
var locator = webdriver.By.xpath("//*[@data-id='pet']");
|
||||
var locator = webdriver.By.xpath('//*[@data-id="pet"]');
|
||||
driver.isElementPresent(locator).then(function (isPresent) {
|
||||
expect(isPresent).to.be.true;
|
||||
done();
|
||||
@@ -88,7 +91,7 @@ describe('swagger 2.0 spec tests', function (done) {
|
||||
});
|
||||
|
||||
it('should find the pet resource description', function(done){
|
||||
var locator = webdriver.By.xpath("//div[contains(., 'Everything about your Pets')]");
|
||||
var locator = webdriver.By.xpath('//div[contains(., "Everything about your Pets")]');
|
||||
driver.findElements(locator).then(function (elements) {
|
||||
expect(elements.length).to.not.equal(0);
|
||||
done();
|
||||
@@ -96,7 +99,7 @@ describe('swagger 2.0 spec tests', function (done) {
|
||||
});
|
||||
|
||||
it('should find the user link', function(done){
|
||||
var locator = webdriver.By.xpath("//*[@data-id='user']");
|
||||
var locator = webdriver.By.xpath('//*[@data-id="user"]');
|
||||
driver.isElementPresent(locator).then(function (isPresent) {
|
||||
expect(isPresent).to.be.true;
|
||||
done();
|
||||
@@ -104,7 +107,7 @@ describe('swagger 2.0 spec tests', function (done) {
|
||||
});
|
||||
|
||||
it('should find the store link', function(done){
|
||||
var locator = webdriver.By.xpath("//*[@data-id='store']");
|
||||
var locator = webdriver.By.xpath('//*[@data-id="store"]');
|
||||
driver.isElementPresent(locator).then(function (isPresent) {
|
||||
expect(isPresent).to.be.true;
|
||||
done();
|
||||
|
||||
Reference in New Issue
Block a user