merged from develop branch

This commit is contained in:
Tony Tam
2013-08-14 10:51:15 -07:00
34 changed files with 11051 additions and 5255 deletions

1
.gitignore vendored
View File

@@ -19,3 +19,4 @@ reports/*
swagger-ui.sublime-workspace swagger-ui.sublime-workspace
.idea .idea
.project .project
node_modules/*

View File

@@ -12,6 +12,8 @@ sourceFiles = [
'view/ParameterView' 'view/ParameterView'
'view/SignatureView' 'view/SignatureView'
'view/ContentTypeView' 'view/ContentTypeView'
'view/ResponseContentTypeView'
'view/ParameterContentTypeView'
] ]

23
dist/css/screen.css vendored
View File

@@ -1757,3 +1757,26 @@ pre code {
.message-fail { .message-fail {
color: #cc0000; color: #cc0000;
} }
.info_title {
padding-bottom: 10px;
font-weight: bold;
font-size: 25px;
}
.info_description {
padding-bottom: 10px;
font-size: 15px;
}
.info_tos {
padding-bottom: 5px;
}
.info_license {
padding-bottom: 5px;
}
.info_contact {
padding-bottom: 5px;
}

120
dist/index.html vendored
View File

@@ -1,74 +1,78 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<title>Swagger UI</title> <title>Swagger UI</title>
<link href='//fonts.googleapis.com/css?family=Droid+Sans:400,700' rel='stylesheet' type='text/css'/> <link href='//fonts.googleapis.com/css?family=Droid+Sans:400,700' rel='stylesheet' type='text/css'/>
<link href='css/hightlight.default.css' media='screen' rel='stylesheet' type='text/css'/> <link href='css/hightlight.default.css' media='screen' rel='stylesheet' type='text/css'/>
<link href='css/screen.css' media='screen' rel='stylesheet' type='text/css'/> <link href='css/screen.css' media='screen' rel='stylesheet' type='text/css'/>
<script src='lib/jquery-1.8.0.min.js' type='text/javascript'></script> <script type="text/javascript" src="lib/shred.bundle.js" /></script>
<script src='lib/jquery.slideto.min.js' type='text/javascript'></script> <script src='lib/jquery-1.8.0.min.js' type='text/javascript'></script>
<script src='lib/jquery.wiggle.min.js' type='text/javascript'></script> <script src='lib/jquery.slideto.min.js' type='text/javascript'></script>
<script src='lib/jquery.ba-bbq.min.js' type='text/javascript'></script> <script src='lib/jquery.wiggle.min.js' type='text/javascript'></script>
<script src='lib/handlebars-1.0.rc.1.js' type='text/javascript'></script> <script src='lib/jquery.ba-bbq.min.js' type='text/javascript'></script>
<script src='lib/underscore-min.js' type='text/javascript'></script> <script src='lib/handlebars-1.0.0.js' type='text/javascript'></script>
<script src='lib/backbone-min.js' type='text/javascript'></script> <script src='lib/underscore-min.js' type='text/javascript'></script>
<script src='lib/swagger.js' type='text/javascript'></script> <script src='lib/backbone-min.js' type='text/javascript'></script>
<script src='swagger-ui.js' type='text/javascript'></script> <script src='lib/swagger.js' type='text/javascript'></script>
<script src='lib/highlight.7.3.pack.js' type='text/javascript'></script> <script src='swagger-ui.js' type='text/javascript'></script>
<script src='lib/highlight.7.3.pack.js' type='text/javascript'></script>
<script src='lib/highlight.7.3.pack.js' type='text/javascript'></script>
<script type="text/javascript">
$(function () {
window.swaggerUi = new SwaggerUi({
url: "http://petstore.swagger.wordnik.com/api/api-docs",
dom_id: "swagger-ui-container",
supportedSubmitMethods: ['get', 'post', 'put', 'delete'],
onComplete: function(swaggerApi, swaggerUi){
if(console) {
console.log("Loaded SwaggerUI")
}
$('pre code').each(function(i, e) {hljs.highlightBlock(e)});
},
onFailure: function(data) {
if(console) {
console.log("Unable to Load SwaggerUI");
console.log(data);
}
},
docExpansion: "none"
});
<script type="text/javascript"> $('#input_apiKey').change(function() {
$(function () { var key = $('#input_apiKey')[0].value;
window.swaggerUi = new SwaggerUi({ console.log("key: " + key);
discoveryUrl:"http://petstore.swagger.wordnik.com/api/api-docs", if(key && key.trim() != "") {
apiKey:"special-key", console.log("added key " + key);
dom_id:"swagger-ui-container", window.authorizations.add("key", new ApiKeyAuthorization("api_key", key, "query"));
supportHeaderParams: false, }
supportedSubmitMethods: ['get', 'post', 'put'], })
onComplete: function(swaggerApi, swaggerUi){ window.swaggerUi.load();
if(console) { });
console.log("Loaded SwaggerUI")
console.log(swaggerApi);
console.log(swaggerUi);
}
$('pre code').each(function(i, e) {hljs.highlightBlock(e)});
},
onFailure: function(data) {
if(console) {
console.log("Unable to Load SwaggerUI");
console.log(data);
}
},
docExpansion: "none"
});
window.swaggerUi.load(); </script>
});
</script>
</head> </head>
<body> <body>
<div id='header'> <div id='header'>
<div class="swagger-ui-wrap"> <div class="swagger-ui-wrap">
<a id="logo" href="http://swagger.wordnik.com">swagger</a> <a id="logo" href="http://swagger.wordnik.com">swagger</a>
<form id='api_selector'> <form id='api_selector'>
<div class='input icon-btn'> <div class='input icon-btn'>
<img id="show-pet-store-icon" src="images/pet_store_api.png" title="Show Swagger Petstore Example Apis"> <img id="show-pet-store-icon" src="images/pet_store_api.png" title="Show Swagger Petstore Example Apis">
</div> </div>
<div class='input icon-btn'> <div class='input icon-btn'>
<img id="show-wordnik-dev-icon" src="images/wordnik_api.png" title="Show Wordnik Developer Apis"> <img id="show-wordnik-dev-icon" src="images/wordnik_api.png" title="Show Wordnik Developer Apis">
</div> </div>
<div class='input'><input placeholder="http://example.com/api" id="input_baseUrl" name="baseUrl" <div class='input'><input placeholder="http://example.com/api" id="input_baseUrl" name="baseUrl" type="text"/></div>
type="text"/></div> <div class='input'><input placeholder="api_key" id="input_apiKey" name="apiKey" type="text"/></div>
<div class='input'><input placeholder="api_key" id="input_apiKey" name="apiKey" type="text"/></div> <div class='input'><a id="explore" href="#">Explore</a></div>
<div class='input'><a id="explore" href="#">Explore</a></div> </form>
</form> </div>
</div>
</div> </div>
<div id="message-bar" class="swagger-ui-wrap"> <div id="message-bar" class="swagger-ui-wrap">
&nbsp; &nbsp;
</div> </div>
<div id="swagger-ui-container" class="swagger-ui-wrap"> <div id="swagger-ui-container" class="swagger-ui-wrap">

2278
dist/lib/handlebars-1.0.0.js vendored Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

2765
dist/lib/shred.bundle.js vendored Normal file

File diff suppressed because it is too large Load Diff

193
dist/lib/shred/content.js vendored Normal file
View File

@@ -0,0 +1,193 @@
// The purpose of the `Content` object is to abstract away the data conversions
// to and from raw content entities as strings. For example, you want to be able
// to pass in a Javascript object and have it be automatically converted into a
// JSON string if the `content-type` is set to a JSON-based media type.
// Conversely, you want to be able to transparently get back a Javascript object
// in the response if the `content-type` is a JSON-based media-type.
// One limitation of the current implementation is that it [assumes the `charset` is UTF-8](https://github.com/spire-io/shred/issues/5).
// The `Content` constructor takes an options object, which *must* have either a
// `body` or `data` property and *may* have a `type` property indicating the
// media type. If there is no `type` attribute, a default will be inferred.
var Content = function(options) {
this.body = options.body;
this.data = options.data;
this.type = options.type;
};
Content.prototype = {
// Treat `toString()` as asking for the `content.body`. That is, the raw content entity.
//
// toString: function() { return this.body; }
//
// Commented out, but I've forgotten why. :/
};
// `Content` objects have the following attributes:
Object.defineProperties(Content.prototype,{
// - **type**. Typically accessed as `content.type`, reflects the `content-type`
// header associated with the request or response. If not passed as an options
// to the constructor or set explicitly, it will infer the type the `data`
// attribute, if possible, and, failing that, will default to `text/plain`.
type: {
get: function() {
if (this._type) {
return this._type;
} else {
if (this._data) {
switch(typeof this._data) {
case "string": return "text/plain";
case "object": return "application/json";
}
}
}
return "text/plain";
},
set: function(value) {
this._type = value;
return this;
},
enumerable: true
},
// - **data**. Typically accessed as `content.data`, reflects the content entity
// converted into Javascript data. This can be a string, if the `type` is, say,
// `text/plain`, but can also be a Javascript object. The conversion applied is
// based on the `processor` attribute. The `data` attribute can also be set
// directly, in which case the conversion will be done the other way, to infer
// the `body` attribute.
data: {
get: function() {
if (this._body) {
return this.processor.parser(this._body);
} else {
return this._data;
}
},
set: function(data) {
if (this._body&&data) Errors.setDataWithBody(this);
this._data = data;
return this;
},
enumerable: true
},
// - **body**. Typically accessed as `content.body`, reflects the content entity
// as a UTF-8 string. It is the mirror of the `data` attribute. If you set the
// `data` attribute, the `body` attribute will be inferred and vice-versa. If
// you attempt to set both, an exception is raised.
body: {
get: function() {
if (this._data) {
return this.processor.stringify(this._data);
} else {
return this._body.toString();
}
},
set: function(body) {
if (this._data&&body) Errors.setBodyWithData(this);
this._body = body;
return this;
},
enumerable: true
},
// - **processor**. The functions that will be used to convert to/from `data` and
// `body` attributes. You can add processors. The two that are built-in are for
// `text/plain`, which is basically an identity transformation and
// `application/json` and other JSON-based media types (including custom media
// types with `+json`). You can add your own processors. See below.
processor: {
get: function() {
var processor = Content.processors[this.type];
if (processor) {
return processor;
} else {
// Return the first processor that matches any part of the
// content type. ex: application/vnd.foobar.baz+json will match json.
var main = this.type.split(";")[0];
var parts = main.split(/\+|\//);
for (var i=0, l=parts.length; i < l; i++) {
processor = Content.processors[parts[i]]
}
return processor || {parser:identity,stringify:toString};
}
},
enumerable: true
},
// - **length**. Typically accessed as `content.length`, returns the length in
// bytes of the raw content entity.
length: {
get: function() {
if (typeof Buffer !== 'undefined') {
return Buffer.byteLength(this.body);
}
return this.body.length;
}
}
});
Content.processors = {};
// The `registerProcessor` function allows you to add your own processors to
// convert content entities. Each processor consists of a Javascript object with
// two properties:
// - **parser**. The function used to parse a raw content entity and convert it
// into a Javascript data type.
// - **stringify**. The function used to convert a Javascript data type into a
// raw content entity.
Content.registerProcessor = function(types,processor) {
// You can pass an array of types that will trigger this processor, or just one.
// We determine the array via duck-typing here.
if (types.forEach) {
types.forEach(function(type) {
Content.processors[type] = processor;
});
} else {
// If you didn't pass an array, we just use what you pass in.
Content.processors[types] = processor;
}
};
// Register the identity processor, which is used for text-based media types.
var identity = function(x) { return x; }
, toString = function(x) { return x.toString(); }
Content.registerProcessor(
["text/html","text/plain","text"],
{ parser: identity, stringify: toString });
// Register the JSON processor, which is used for JSON-based media types.
Content.registerProcessor(
["application/json; charset=utf-8","application/json","json"],
{
parser: function(string) {
return JSON.parse(string);
},
stringify: function(data) {
return JSON.stringify(data); }});
var qs = require('querystring');
// Register the post processor, which is used for JSON-based media types.
Content.registerProcessor(
["application/x-www-form-urlencoded"],
{ parser : qs.parse, stringify : qs.stringify });
// Error functions are defined separately here in an attempt to make the code
// easier to read.
var Errors = {
setDataWithBody: function(object) {
throw new Error("Attempt to set data attribute of a content object " +
"when the body attributes was already set.");
},
setBodyWithData: function(object) {
throw new Error("Attempt to set body attribute of a content object " +
"when the data attributes was already set.");
}
}
module.exports = Content;

813
dist/lib/swagger.js vendored

File diff suppressed because it is too large Load Diff

1646
dist/swagger-ui.js vendored

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

2765
lib/shred.bundle.js Normal file

File diff suppressed because it is too large Load Diff

193
lib/shred/content.js Normal file
View File

@@ -0,0 +1,193 @@
// The purpose of the `Content` object is to abstract away the data conversions
// to and from raw content entities as strings. For example, you want to be able
// to pass in a Javascript object and have it be automatically converted into a
// JSON string if the `content-type` is set to a JSON-based media type.
// Conversely, you want to be able to transparently get back a Javascript object
// in the response if the `content-type` is a JSON-based media-type.
// One limitation of the current implementation is that it [assumes the `charset` is UTF-8](https://github.com/spire-io/shred/issues/5).
// The `Content` constructor takes an options object, which *must* have either a
// `body` or `data` property and *may* have a `type` property indicating the
// media type. If there is no `type` attribute, a default will be inferred.
var Content = function(options) {
this.body = options.body;
this.data = options.data;
this.type = options.type;
};
Content.prototype = {
// Treat `toString()` as asking for the `content.body`. That is, the raw content entity.
//
// toString: function() { return this.body; }
//
// Commented out, but I've forgotten why. :/
};
// `Content` objects have the following attributes:
Object.defineProperties(Content.prototype,{
// - **type**. Typically accessed as `content.type`, reflects the `content-type`
// header associated with the request or response. If not passed as an options
// to the constructor or set explicitly, it will infer the type the `data`
// attribute, if possible, and, failing that, will default to `text/plain`.
type: {
get: function() {
if (this._type) {
return this._type;
} else {
if (this._data) {
switch(typeof this._data) {
case "string": return "text/plain";
case "object": return "application/json";
}
}
}
return "text/plain";
},
set: function(value) {
this._type = value;
return this;
},
enumerable: true
},
// - **data**. Typically accessed as `content.data`, reflects the content entity
// converted into Javascript data. This can be a string, if the `type` is, say,
// `text/plain`, but can also be a Javascript object. The conversion applied is
// based on the `processor` attribute. The `data` attribute can also be set
// directly, in which case the conversion will be done the other way, to infer
// the `body` attribute.
data: {
get: function() {
if (this._body) {
return this.processor.parser(this._body);
} else {
return this._data;
}
},
set: function(data) {
if (this._body&&data) Errors.setDataWithBody(this);
this._data = data;
return this;
},
enumerable: true
},
// - **body**. Typically accessed as `content.body`, reflects the content entity
// as a UTF-8 string. It is the mirror of the `data` attribute. If you set the
// `data` attribute, the `body` attribute will be inferred and vice-versa. If
// you attempt to set both, an exception is raised.
body: {
get: function() {
if (this._data) {
return this.processor.stringify(this._data);
} else {
return this._body.toString();
}
},
set: function(body) {
if (this._data&&body) Errors.setBodyWithData(this);
this._body = body;
return this;
},
enumerable: true
},
// - **processor**. The functions that will be used to convert to/from `data` and
// `body` attributes. You can add processors. The two that are built-in are for
// `text/plain`, which is basically an identity transformation and
// `application/json` and other JSON-based media types (including custom media
// types with `+json`). You can add your own processors. See below.
processor: {
get: function() {
var processor = Content.processors[this.type];
if (processor) {
return processor;
} else {
// Return the first processor that matches any part of the
// content type. ex: application/vnd.foobar.baz+json will match json.
var main = this.type.split(";")[0];
var parts = main.split(/\+|\//);
for (var i=0, l=parts.length; i < l; i++) {
processor = Content.processors[parts[i]]
}
return processor || {parser:identity,stringify:toString};
}
},
enumerable: true
},
// - **length**. Typically accessed as `content.length`, returns the length in
// bytes of the raw content entity.
length: {
get: function() {
if (typeof Buffer !== 'undefined') {
return Buffer.byteLength(this.body);
}
return this.body.length;
}
}
});
Content.processors = {};
// The `registerProcessor` function allows you to add your own processors to
// convert content entities. Each processor consists of a Javascript object with
// two properties:
// - **parser**. The function used to parse a raw content entity and convert it
// into a Javascript data type.
// - **stringify**. The function used to convert a Javascript data type into a
// raw content entity.
Content.registerProcessor = function(types,processor) {
// You can pass an array of types that will trigger this processor, or just one.
// We determine the array via duck-typing here.
if (types.forEach) {
types.forEach(function(type) {
Content.processors[type] = processor;
});
} else {
// If you didn't pass an array, we just use what you pass in.
Content.processors[types] = processor;
}
};
// Register the identity processor, which is used for text-based media types.
var identity = function(x) { return x; }
, toString = function(x) { return x.toString(); }
Content.registerProcessor(
["text/html","text/plain","text"],
{ parser: identity, stringify: toString });
// Register the JSON processor, which is used for JSON-based media types.
Content.registerProcessor(
["application/json; charset=utf-8","application/json","json"],
{
parser: function(string) {
return JSON.parse(string);
},
stringify: function(data) {
return JSON.stringify(data); }});
var qs = require('querystring');
// Register the post processor, which is used for JSON-based media types.
Content.registerProcessor(
["application/x-www-form-urlencoded"],
{ parser : qs.parse, stringify : qs.stringify });
// Error functions are defined separately here in an attempt to make the code
// easier to read.
var Errors = {
setDataWithBody: function(object) {
throw new Error("Attempt to set data attribute of a content object " +
"when the body attributes was already set.");
},
setBodyWithData: function(object) {
throw new Error("Attempt to set body attribute of a content object " +
"when the data attributes was already set.");
}
}
module.exports = Content;

1111
lib/swagger.js Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
{ {
"name": "swagger-ui", "name": "swagger-ui",
"version": "1.1.15", "version": "2.0.0",
"description": "Swagger UI is a dependency-free collection of HTML, Javascript, and CSS assets that dynamically generate beautiful documentation from a Swagger-compliant API", "description": "Swagger UI is a dependency-free collection of HTML, Javascript, and CSS assets that dynamically generate beautiful documentation from a Swagger-compliant API",
"scripts": { "scripts": {
"build": "PATH=$PATH:./node_modules/.bin cake dist", "build": "PATH=$PATH:./node_modules/.bin cake dist",
@@ -19,7 +19,6 @@
"readmeFilename": "README.md", "readmeFilename": "README.md",
"dependencies": { "dependencies": {
"coffee-script": "~1.5.0", "coffee-script": "~1.5.0",
"swagger-client": "1.0.4",
"handlebars": "~1.0.10" "handlebars": "~1.0.10"
} }
} }

View File

@@ -34,16 +34,22 @@ class SwaggerUi extends Backbone.Router
# Event handler for when url/key is received from user # Event handler for when url/key is received from user
updateSwaggerUi: (data) -> updateSwaggerUi: (data) ->
@options.discoveryUrl = data.discoveryUrl @options.url = data.url
@options.apiKey = data.apiKey
@load() @load()
# Create an api and render # Create an api and render
load: -> load: ->
# Initialize the API object # Initialize the API object
@mainView?.clear() @mainView?.clear()
@headerView.update(@options.discoveryUrl, @options.apiKey) url = @options.url
if url.indexOf("http") isnt 0
url = @buildUrl(window.location.href.toString(), url)
@options.url = url
@headerView.update(url)
@api = new SwaggerApi(@options) @api = new SwaggerApi(@options)
@api.build()
@api
# This is bound to success handler for SwaggerApi # This is bound to success handler for SwaggerApi
# so it gets called when SwaggerApi completes loading # so it gets called when SwaggerApi completes loading
@@ -52,8 +58,8 @@ class SwaggerUi extends Backbone.Router
@mainView = new MainView({model: @api, el: $('#' + @dom_id)}).render() @mainView = new MainView({model: @api, el: $('#' + @dom_id)}).render()
@showMessage() @showMessage()
switch @options.docExpansion switch @options.docExpansion
when "full" then Docs.expandOperationsForResource('') when "full" then Docs.expandOperationsForResource('')
when "list" then Docs.collapseOperationsForResource('') when "list" then Docs.collapseOperationsForResource('')
@options.onComplete(@api, @) if @options.onComplete @options.onComplete(@api, @) if @options.onComplete
setTimeout( setTimeout(
=> =>
@@ -61,6 +67,16 @@ class SwaggerUi extends Backbone.Router
400 400
) )
buildUrl: (base, url) ->
console.log "base is " + base
parts = base.split("/")
base = parts[0] + "//" + parts[2]
if url.indexOf("/") is 0
base + url
else
base + "/" + url
# Shows message on topbar of the ui # Shows message on topbar of the ui
showMessage: (data = '') -> showMessage: (data = '') ->
$('#message-bar').removeClass 'message-fail' $('#message-bar').removeClass 'message-fail'

View File

@@ -5,12 +5,7 @@ class ContentTypeView extends Backbone.View
template = @template() template = @template()
$(@el).html(template(@model)) $(@el).html(template(@model))
@isParam = @model.isParam $('label[for=contentType]', $(@el)).text('Response Content Type')
if @isParam
$('label[for=contentType]', $(@el)).text('Parameter content type:')
else
$('label[for=contentType]', $(@el)).text('Response Content Type')
@ @

View File

@@ -9,17 +9,16 @@ class HeaderView extends Backbone.View
initialize: -> initialize: ->
showPetStore: (e) -> showPetStore: (e) ->
@trigger( @trigger(
'update-swagger-ui' 'update-swagger-ui'
{discoveryUrl:"http://petstore.swagger.wordnik.com/api/api-docs.json", apiKey:"special-key"} {url:"http://petstore.swagger.wordnik.com/api/api-docs.json"}
) )
showWordnikDev: (e) -> showWordnikDev: (e) ->
@trigger( @trigger(
'update-swagger-ui' 'update-swagger-ui'
{discoveryUrl:"http://api.wordnik.com/v4/resources.json", apiKey:""} {url:"http://api.wordnik.com/v4/resources.json"}
) )
showCustomOnKeyup: (e) -> showCustomOnKeyup: (e) ->
@@ -29,10 +28,10 @@ class HeaderView extends Backbone.View
e?.preventDefault() e?.preventDefault()
@trigger( @trigger(
'update-swagger-ui' 'update-swagger-ui'
{discoveryUrl: $('#input_baseUrl').val(), apiKey: $('#input_apiKey').val()} {url: $('#input_baseUrl').val(), apiKey: $('#input_apiKey').val()}
) )
update: (url, apiKey, trigger = false) -> update: (url, apiKey, trigger = false) ->
$('#input_baseUrl').val url $('#input_baseUrl').val url
$('#input_apiKey').val apiKey #$('#input_apiKey').val apiKey
@trigger 'update-swagger-ui', {discoveryUrl:url, apiKey:apiKey} if trigger @trigger 'update-swagger-ui', {url:url} if trigger

View File

@@ -9,7 +9,7 @@ class OperationView extends Backbone.View
initialize: -> initialize: ->
render: -> render: ->
isMethodSubmissionSupported = jQuery.inArray(@model.httpMethod, @model.supportedSubmitMethods()) >= 0 isMethodSubmissionSupported = true #jQuery.inArray(@model.method, @model.supportedSubmitMethods) >= 0
@model.isReadOnly = true unless isMethodSubmissionSupported @model.isReadOnly = true unless isMethodSubmissionSupported
$(@el).html(Handlebars.templates.operation(@model)) $(@el).html(Handlebars.templates.operation(@model))
@@ -23,31 +23,35 @@ class OperationView extends Backbone.View
responseSignatureView = new SignatureView({model: signatureModel, tagName: 'div'}) responseSignatureView = new SignatureView({model: signatureModel, tagName: 'div'})
$('.model-signature', $(@el)).append responseSignatureView.render().el $('.model-signature', $(@el)).append responseSignatureView.render().el
else else
$('.model-signature', $(@el)).html(@model.responseClass) $('.model-signature', $(@el)).html(@model.type)
contentTypeModel = contentTypeModel =
isParam: false isParam: false
# support old syntax contentTypeModel.consumes = @model.consumes
if @model.supportedContentTypes contentTypeModel.produces = @model.produces
contentTypeModel.produces = @model.supportedContentTypes
if @model.produces for param in @model.parameters
contentTypeModel.produces = @model.produces type = param.type || param.dataType
if type.toLowerCase() == 'file'
if !contentTypeModel.consumes
console.log "set content type "
contentTypeModel.consumes = 'multipart/form-data'
contentTypeView = new ContentTypeView({model: contentTypeModel}) responseContentTypeView = new ResponseContentTypeView({model: contentTypeModel})
$('.content-type', $(@el)).append contentTypeView.render().el $('.response-content-type', $(@el)).append responseContentTypeView.render().el
# Render each parameter # Render each parameter
@addParameter param for param in @model.parameters @addParameter param, contentTypeModel.consumes for param in @model.parameters
# Render each response code # Render each response code
@addStatusCode statusCode for statusCode in @model.errorResponses @addStatusCode statusCode for statusCode in @model.responseMessages
@ @
addParameter: (param) -> addParameter: (param, consumes) ->
# Render a parameter # Render a parameter
param.consumes = consumes
paramView = new ParameterView({model: param, tagName: 'tr', readOnly: @model.isReadOnly}) paramView = new ParameterView({model: param, tagName: 'tr', readOnly: @model.isReadOnly})
$('.operation-params', $(@el)).append paramView.render().el $('.operation-params', $(@el)).append paramView.render().el
@@ -72,103 +76,27 @@ class OperationView extends Backbone.View
# if error free submit it # if error free submit it
if error_free if error_free
map = {} map = {}
for o in form.serializeArray() opts = {parent: @}
#for o in form.serializeArray()
#if(o.value? && jQuery.trim(o.value).length > 0)
#map[o.name] = o.value
for o in form.find("input")
if(o.value? && jQuery.trim(o.value).length > 0) if(o.value? && jQuery.trim(o.value).length > 0)
map[o.name] = o.value map[o.name] = encodeURI(o.value)
isFileUpload = form.children().find('input[type~="file"]').size() != 0 for o in form.find("textarea")
if(o.value? && jQuery.trim(o.value).length > 0)
map["body"] = o.value
isFormPost = false opts.responseContentType = $("div select[name=responseContentType]", $(@el)).val()
consumes = "application/json" opts.requestContentType = $("div select[name=parameterContentType]", $(@el)).val()
if @model.consumes and @model.consumes.length > 0
# honor the consumes setting above everything else
consumes = @model.consumes[0]
else
for o in @model.parameters
if o.paramType == 'form'
isFormPost = true
consumes = false
if isFileUpload @model.do(map, opts, @showCompleteStatus, @showErrorStatus, @)
consumes = false
else if @model.httpMethod.toLowerCase() == "post" and isFormPost is false
consumes = "application/json"
if isFileUpload success: (response, parent) ->
# requires HTML5 compatible browser parent.showCompleteStatus response
bodyParam = new FormData()
# add params except file
for param in @model.parameters
if (param.paramType is 'body' or 'form') and param.name isnt 'file' and param.name isnt 'File' and map[param.name]?
bodyParam.append(param.name, map[param.name])
# add files
$.each form.children().find('input[type~="file"]'), (i, el) ->
bodyParam.append($(el).attr('name'), el.files[0])
console.log(bodyParam)
else if isFormPost
bodyParam = new FormData()
for param in @model.parameters
if map[param.name]?
bodyParam.append(param.name, map[param.name])
else
bodyParam = null
for param in @model.parameters
if param.paramType is 'body'
bodyParam = map[param.name]
log "bodyParam = " + bodyParam
headerParams = null
invocationUrl =
if @model.supportHeaderParams()
headerParams = @model.getHeaderParams(map)
@model.urlify(map, false)
else
@model.urlify(map, true)
log 'submitting ' + invocationUrl
$(".request_url", $(@el)).html "<pre>" + invocationUrl + "</pre>"
$(".response_throbber", $(@el)).show()
obj =
type: @model.httpMethod
url: invocationUrl
headers: headerParams
data: bodyParam
contentType: consumes
dataType: 'json'
processData: false
error: (xhr, textStatus, error) =>
@showErrorStatus(xhr, textStatus, error)
success: (data) =>
@showResponse(data)
complete: (data) =>
@showCompleteStatus(data)
paramContentTypeField = $("td select[name=contentType]", $(@el)).val()
if paramContentTypeField
obj.contentType = paramContentTypeField
log 'content type = ' + obj.contentType
if not (obj.data or (obj.type is 'GET' or obj.type is 'DELETE')) and obj.contentType is not "application/x-www-form-urlencoded"
obj.contentType = false
log 'content type is now = ' + obj.contentType
responseContentTypeField = $('.content > .content-type > div > select[name=contentType]', $(@el)).val()
if responseContentTypeField
obj.headers = if obj.headers? then obj.headers else {}
obj.headers.accept = responseContentTypeField
jQuery.ajax(obj)
false
# $.getJSON(invocationUrl, (r) => @showResponse(r)).complete((r) => @showCompleteStatus(r)).error (r) => @showErrorStatus(r)
# handler for hide response link # handler for hide response link
hideResponse: (e) -> hideResponse: (e) ->
@@ -182,14 +110,13 @@ class OperationView extends Backbone.View
prettyJson = JSON.stringify(response, null, "\t").replace(/\n/g, "<br>") prettyJson = JSON.stringify(response, null, "\t").replace(/\n/g, "<br>")
$(".response_body", $(@el)).html escape(prettyJson) $(".response_body", $(@el)).html escape(prettyJson)
# Show error from server # Show error from server
showErrorStatus: (data) -> showErrorStatus: (data, parent) ->
@showStatus data parent.showStatus data
# show the status codes # show the status codes
showCompleteStatus: (data) -> showCompleteStatus: (data, parent) ->
@showStatus data parent.showStatus data
# Adapted from http://stackoverflow.com/a/2893259/454004 # Adapted from http://stackoverflow.com/a/2893259/454004
formatXml: (xml) -> formatXml: (xml) ->
@@ -252,21 +179,39 @@ class OperationView extends Backbone.View
# puts the response data in UI # puts the response data in UI
showStatus: (data) -> showStatus: (data) ->
try content = data.content.data
code = $('<code />').text(JSON.stringify(JSON.parse(data.responseText), null, 2)) headers = data.getHeaders()
# if server is nice, and sends content-type back, we can use it
contentType = headers["Content-Type"]
if content == undefined
code = $('<code />').text("no content")
pre = $('<pre class="json" />').append(code) pre = $('<pre class="json" />').append(code)
catch error else if contentType.indexOf("application/json") == 0
code = $('<code />').text(@formatXml(data.responseText)) code = $('<code />').text(JSON.stringify(JSON.parse(content), null, 2))
pre = $('<pre class="json" />').append(code)
else if contentType.indexOf("application/xml") == 0
code = $('<code />').text(@formatXml(content))
pre = $('<pre class="xml" />').append(code) pre = $('<pre class="xml" />').append(code)
else if contentType.indexOf("text/html") == 0
code = $('<code />').html(content)
pre = $('<pre class="xml" />').append(code)
else
# don't know what to render!
code = $('<code />').text(content)
pre = $('<pre class="json" />').append(code)
response_body = pre response_body = pre
$(".request_url").html "<pre>" + data.request.url + "</pre>"
$(".response_code", $(@el)).html "<pre>" + data.status + "</pre>" $(".response_code", $(@el)).html "<pre>" + data.status + "</pre>"
$(".response_body", $(@el)).html response_body $(".response_body", $(@el)).html response_body
$(".response_headers", $(@el)).html "<pre>" + data.getAllResponseHeaders() + "</pre>" $(".response_headers", $(@el)).html "<pre>" + JSON.stringify(data.getHeaders()) + "</pre>"
$(".response", $(@el)).slideDown() $(".response", $(@el)).slideDown()
$(".response_hider", $(@el)).show() $(".response_hider", $(@el)).show()
$(".response_throbber", $(@el)).hide() $(".response_throbber", $(@el)).hide()
hljs.highlightBlock($('.response_body', $(@el))[0]) hljs.highlightBlock($('.response_body', $(@el))[0])
toggleOperationContent: -> toggleOperationContent: ->
elem = $('#' + Docs.escapeResourceName(@model.resourceName) + "_" + @model.nickname + "_" + @model.httpMethod + "_" + @model.number + "_content") elem = $('#' + Docs.escapeResourceName(@model.resourceName) + "_" + @model.nickname + "_" + @model.method + "_" + @model.number + "_content")
if elem.is(':visible') then Docs.collapseOperation(elem) else Docs.expandOperation(elem) if elem.is(':visible') then Docs.collapseOperation(elem) else Docs.expandOperation(elem)

View File

@@ -0,0 +1,14 @@
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

View File

@@ -2,8 +2,9 @@ class ParameterView extends Backbone.View
initialize: -> initialize: ->
render: -> render: ->
type = @model.type || @model.dataType
@model.isBody = true if @model.paramType == 'body' @model.isBody = true if @model.paramType == 'body'
@model.isFile = true if @model.dataType == 'file' @model.isFile = true if type.toLowerCase() == 'file'
template = @template() template = @template()
$(@el).html(template(@model)) $(@el).html(template(@model))
@@ -19,18 +20,23 @@ class ParameterView extends Backbone.View
else else
$('.model-signature', $(@el)).html(@model.signature) $('.model-signature', $(@el)).html(@model.signature)
isParam = false
if @model.isBody
isParam = true
contentTypeModel = contentTypeModel =
isParam: false isParam: isParam
# support old syntax contentTypeModel.consumes = @model.consumes
if @model.supportedContentTypes
contentTypeModel.produces = @model.supportedContentTypes
if @model.produces if isParam
contentTypeModel.produces = @model.produces parameterContentTypeView = new ParameterContentTypeView({model: contentTypeModel})
$('.parameter-content-type', $(@el)).append parameterContentTypeView.render().el
contentTypeView = new ContentTypeView({model: contentTypeModel}) else
$('.content-type', $(@el)).append contentTypeView.render().el responseContentTypeView = new ResponseContentTypeView({model: contentTypeModel})
$('.response-content-type', $(@el)).append responseContentTypeView.render().el
@ @

View File

@@ -0,0 +1,14 @@
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

View File

@@ -1757,3 +1757,26 @@ pre code {
.message-fail { .message-fail {
color: #cc0000; color: #cc0000;
} }
.info_title {
padding-bottom: 10px;
font-weight: bold;
font-size: 25px;
}
.info_description {
padding-bottom: 10px;
font-size: 15px;
}
.info_tos {
padding-bottom: 5px;
}
.info_license {
padding-bottom: 5px;
}
.info_contact {
padding-bottom: 5px;
}

View File

@@ -1,74 +1,78 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<title>Swagger UI</title> <title>Swagger UI</title>
<link href='//fonts.googleapis.com/css?family=Droid+Sans:400,700' rel='stylesheet' type='text/css'/> <link href='//fonts.googleapis.com/css?family=Droid+Sans:400,700' rel='stylesheet' type='text/css'/>
<link href='css/hightlight.default.css' media='screen' rel='stylesheet' type='text/css'/> <link href='css/hightlight.default.css' media='screen' rel='stylesheet' type='text/css'/>
<link href='css/screen.css' media='screen' rel='stylesheet' type='text/css'/> <link href='css/screen.css' media='screen' rel='stylesheet' type='text/css'/>
<script src='lib/jquery-1.8.0.min.js' type='text/javascript'></script> <script type="text/javascript" src="lib/shred.bundle.js" /></script>
<script src='lib/jquery.slideto.min.js' type='text/javascript'></script> <script src='lib/jquery-1.8.0.min.js' type='text/javascript'></script>
<script src='lib/jquery.wiggle.min.js' type='text/javascript'></script> <script src='lib/jquery.slideto.min.js' type='text/javascript'></script>
<script src='lib/jquery.ba-bbq.min.js' type='text/javascript'></script> <script src='lib/jquery.wiggle.min.js' type='text/javascript'></script>
<script src='lib/handlebars-1.0.0.js' type='text/javascript'></script> <script src='lib/jquery.ba-bbq.min.js' type='text/javascript'></script>
<script src='lib/underscore-min.js' type='text/javascript'></script> <script src='lib/handlebars-1.0.0.js' type='text/javascript'></script>
<script src='lib/backbone-min.js' type='text/javascript'></script> <script src='lib/underscore-min.js' type='text/javascript'></script>
<script src='lib/swagger.js' type='text/javascript'></script> <script src='lib/backbone-min.js' type='text/javascript'></script>
<script src='swagger-ui.js' type='text/javascript'></script> <script src='lib/swagger.js' type='text/javascript'></script>
<script src='lib/highlight.7.3.pack.js' type='text/javascript'></script> <script src='swagger-ui.js' type='text/javascript'></script>
<script src='lib/highlight.7.3.pack.js' type='text/javascript'></script>
<script src='lib/highlight.7.3.pack.js' type='text/javascript'></script>
<script type="text/javascript">
$(function () {
window.swaggerUi = new SwaggerUi({
url: "http://petstore.swagger.wordnik.com/api/api-docs",
dom_id: "swagger-ui-container",
supportedSubmitMethods: ['get', 'post', 'put', 'delete'],
onComplete: function(swaggerApi, swaggerUi){
if(console) {
console.log("Loaded SwaggerUI")
}
$('pre code').each(function(i, e) {hljs.highlightBlock(e)});
},
onFailure: function(data) {
if(console) {
console.log("Unable to Load SwaggerUI");
console.log(data);
}
},
docExpansion: "none"
});
<script type="text/javascript"> $('#input_apiKey').change(function() {
$(function () { var key = $('#input_apiKey')[0].value;
window.swaggerUi = new SwaggerUi({ console.log("key: " + key);
discoveryUrl:"http://petstore.swagger.wordnik.com/api/api-docs.json", if(key && key.trim() != "") {
apiKey:"special-key", console.log("added key " + key);
dom_id:"swagger-ui-container", window.authorizations.add("key", new ApiKeyAuthorization("api_key", key, "query"));
supportHeaderParams: false, }
supportedSubmitMethods: ['get', 'post', 'put'], })
onComplete: function(swaggerApi, swaggerUi){ window.swaggerUi.load();
if(console) { });
console.log("Loaded SwaggerUI")
console.log(swaggerApi);
console.log(swaggerUi);
}
$('pre code').each(function(i, e) {hljs.highlightBlock(e)});
},
onFailure: function(data) {
if(console) {
console.log("Unable to Load SwaggerUI");
console.log(data);
}
},
docExpansion: "none"
});
window.swaggerUi.load(); </script>
});
</script>
</head> </head>
<body> <body>
<div id='header'> <div id='header'>
<div class="swagger-ui-wrap"> <div class="swagger-ui-wrap">
<a id="logo" href="http://swagger.wordnik.com">swagger</a> <a id="logo" href="http://swagger.wordnik.com">swagger</a>
<form id='api_selector'> <form id='api_selector'>
<div class='input icon-btn'> <div class='input icon-btn'>
<img id="show-pet-store-icon" src="images/pet_store_api.png" title="Show Swagger Petstore Example Apis"> <img id="show-pet-store-icon" src="images/pet_store_api.png" title="Show Swagger Petstore Example Apis">
</div> </div>
<div class='input icon-btn'> <div class='input icon-btn'>
<img id="show-wordnik-dev-icon" src="images/wordnik_api.png" title="Show Wordnik Developer Apis"> <img id="show-wordnik-dev-icon" src="images/wordnik_api.png" title="Show Wordnik Developer Apis">
</div> </div>
<div class='input'><input placeholder="http://example.com/api" id="input_baseUrl" name="baseUrl" <div class='input'><input placeholder="http://example.com/api" id="input_baseUrl" name="baseUrl" type="text"/></div>
type="text"/></div> <div class='input'><input placeholder="api_key" id="input_apiKey" name="apiKey" type="text"/></div>
<div class='input'><input placeholder="api_key" id="input_apiKey" name="apiKey" type="text"/></div> <div class='input'><a id="explore" href="#">Explore</a></div>
<div class='input'><a id="explore" href="#">Explore</a></div> </form>
</form> </div>
</div>
</div> </div>
<div id="message-bar" class="swagger-ui-wrap"> <div id="message-bar" class="swagger-ui-wrap">
&nbsp; &nbsp;
</div> </div>
<div id="swagger-ui-container" class="swagger-ui-wrap"> <div id="swagger-ui-container" class="swagger-ui-wrap">

View File

@@ -1,10 +1,10 @@
<label for="contentType"></label> <label for="contentType"></label>
<select name="contentType"> <select name="contentType">
{{#if produces}} {{#if produces}}
{{#each produces}} {{#each produces}}
<option value="{{{this}}}">{{{this}}}</option> <option value="{{{this}}}">{{{this}}}</option>
{{/each}} {{/each}}
{{else}} {{else}}
<option value="application/json">application/json</option> <option value="application/json">application/json</option>
{{/if}} {{/if}}
</select> </select>

View File

@@ -1,4 +1,12 @@
<div class='info' id='api_info'>
{{#if info}}
<div class="info_title">{{info.title}}</div>
<div class="info_description">{{{info.description}}}</div>
{{#if info.termsOfServiceUrl}}<div class="info_tos"><a href="{{info.termsOfServiceUrl}}">Terms of service</a></div>{{/if}}
{{#if info.contact}}<div class='info_contact'><a href="mailto:{{info.contact}}">Contact the developer</a></div>{{/if}}
{{#if info.license}}<div class='info_license'><a href='{{info.licenseUrl}}'>{{info.license}}</a></div>{{/if}}
{{/if}}
</div>
<div class='container' id='resources_container'> <div class='container' id='resources_container'>
<ul id='resources'> <ul id='resources'>
</ul> </ul>

View File

@@ -1,49 +1,49 @@
<ul class='operations' > <ul class='operations' >
<li class='{{httpMethod}} operation' id='{{resourceName}}_{{nickname}}_{{httpMethod}}_{{number}}'> <li class='{{method}} operation' id='{{resourceName}}_{{nickname}}_{{method}}_{{number}}'>
<div class='heading'> <div class='heading'>
<h3> <h3>
<span class='http_method'> <span class='http_method'>
<a href='#!/{{resourceName}}/{{nickname}}_{{httpMethod}}_{{number}}' class="toggleOperation">{{httpMethod}}</a> <a href='#!/{{resourceName}}/{{nickname}}_{{method}}_{{number}}' class="toggleOperation">{{method}}</a>
</span> </span>
<span class='path'> <span class='path'>
<a href='#!/{{resourceName}}/{{nickname}}_{{httpMethod}}_{{number}}' class="toggleOperation">{{path}}</a> <a href='#!/{{resourceName}}/{{nickname}}_{{method}}_{{number}}' class="toggleOperation">{{path}}</a>
</span> </span>
</h3> </h3>
<ul class='options'> <ul class='options'>
<li> <li>
<a href='#!/{{resourceName}}/{{nickname}}_{{httpMethod}}_{{number}}' class="toggleOperation">{{{summary}}}</a> <a href='#!/{{resourceName}}/{{nickname}}_{{method}}_{{number}}' class="toggleOperation">{{{summary}}}</a>
</li> </li>
</ul> </ul>
</div> </div>
<div class='content' id='{{resourceName}}_{{nickname}}_{{httpMethod}}_{{number}}_content' style='display:none'> <div class='content' id='{{resourceName}}_{{nickname}}_{{method}}_{{number}}_content' style='display:none'>
{{#if notes}} {{#if notes}}
<h4>Implementation Notes</h4> <h4>Implementation Notes</h4>
<p>{{{notes}}}</p> <p>{{{notes}}}</p>
{{/if}} {{/if}}
{{#if responseClass}} {{#if type}}
<h4>Response Class</h4> <h4>Response Class</h4>
<p><span class="model-signature" /></p> <p><span class="model-signature" /></p>
<br/> <br/>
<div class="content-type" /> <div class="response-content-type" />
{{/if}} {{/if}}
<form accept-charset='UTF-8' class='sandbox'> <form accept-charset='UTF-8' class='sandbox'>
<div style='margin:0;padding:0;display:inline'></div> <div style='margin:0;padding:0;display:inline'></div>
{{#if parameters}} {{#if parameters}}
<h4>Parameters</h4> <h4>Parameters</h4>
<table class='fullwidth'> <table class='fullwidth'>
<thead> <thead>
<tr> <tr>
<th style="width: 100px; max-width: 100px">Parameter</th> <th style="width: 100px; max-width: 100px">Parameter</th>
<th style="width: 310px; max-width: 310px">Value</th> <th style="width: 310px; max-width: 310px">Value</th>
<th style="width: 200px; max-width: 200px">Description</th> <th style="width: 200px; max-width: 200px">Description</th>
<th style="width: 100px; max-width: 100px">Parameter Type</th> <th style="width: 100px; max-width: 100px">Parameter Type</th>
<th style="width: 220px; max-width: 230px">Data Type</th> <th style="width: 220px; max-width: 230px">Data Type</th>
</tr> </tr>
</thead> </thead>
<tbody class="operation-params"> <tbody class="operation-params">
</tbody> </tbody>
</table> </table>
{{/if}} {{/if}}
{{#if errorResponses}} {{#if errorResponses}}

View File

@@ -4,13 +4,14 @@
{{#if isBody}} {{#if isBody}}
{{#if isFile}} {{#if isFile}}
<input type="file" name='{{name}}'/> <input type="file" name='{{name}}'/>
<div class="parameter-content-type" />
{{else}} {{else}}
{{#if defaultValue}} {{#if defaultValue}}
<textarea class='body-textarea' name='{{name}}'>{{defaultValue}}</textarea> <textarea class='body-textarea' name='{{name}}'>{{defaultValue}}</textarea>
{{else}} {{else}}
<textarea class='body-textarea' name='{{name}}'></textarea> <textarea class='body-textarea' name='{{name}}'></textarea>
<br /> <br />
<div class="content-type" /> <div class="parameter-content-type" />
{{/if}} {{/if}}
{{/if}} {{/if}}
{{else}} {{else}}
@@ -27,4 +28,3 @@
<td> <td>
<span class="model-signature"></span> <span class="model-signature"></span>
</td> </td>

View File

@@ -9,7 +9,7 @@
{{else}} {{else}}
<textarea class='body-textarea' placeholder='(required)' name='{{name}}'></textarea> <textarea class='body-textarea' placeholder='(required)' name='{{name}}'></textarea>
<br /> <br />
<div class="content-type" /> <div class="parameter-content-type" />
{{/if}} {{/if}}
{{/if}} {{/if}}
{{else}} {{else}}

View File

@@ -0,0 +1,10 @@
<label for="parameterContentType"></label>
<select name="parameterContentType">
{{#if consumes}}
{{#each consumes}}
<option value="{{{this}}}">{{{this}}}</option>
{{/each}}
{{else}}
<option value="application/json">application/json</option>
{{/if}}
</select>

View File

@@ -1,26 +1,26 @@
<div class='heading'> <div class='heading'>
<h2> <h2>
<a href='#!/{{name}}' onclick="Docs.toggleEndpointListForResource('{{name}}');">/{{name}}</a> <a href='#!/{{name}}' onclick="Docs.toggleEndpointListForResource('{{name}}');">{{name}}</a>
</h2> </h2>
<ul class='options'> <ul class='options'>
<li> <li>
<a href='#!/{{name}}' id='endpointListTogger_{{name}}' <a href='#!/{{name}}' id='endpointListTogger_{{name}}'
onclick="Docs.toggleEndpointListForResource('{{name}}');">Show/Hide</a> onclick="Docs.toggleEndpointListForResource('{{name}}');">Show/Hide</a>
</li> </li>
<li> <li>
<a href='#' onclick="Docs.collapseOperationsForResource('{{name}}'); return false;"> <a href='#' onclick="Docs.collapseOperationsForResource('{{name}}'); return false;">
List Operations List Operations
</a> </a>
</li> </li>
<li> <li>
<a href='#' onclick="Docs.expandOperationsForResource('{{name}}'); return false;"> <a href='#' onclick="Docs.expandOperationsForResource('{{name}}'); return false;">
Expand Operations Expand Operations
</a> </a>
</li> </li>
<li> <li>
<a href='{{url}}'>Raw</a> <a href='{{url}}'>Raw</a>
</li> </li>
</ul> </ul>
</div> </div>
<ul class='endpoints' id='{{name}}_endpoint_list' style='display:none'> <ul class='endpoints' id='{{name}}_endpoint_list' style='display:none'>

View File

@@ -0,0 +1,10 @@
<label for="responseContentType"></label>
<select name="responseContentType">
{{#if produces}}
{{#each produces}}
<option value="{{{this}}}">{{{this}}}</option>
{{/each}}
{{else}}
<option value="application/json">application/json</option>
{{/if}}
</select>

View File

@@ -1,5 +1,4 @@
window.api_key = 'a2a73e7b926c924fad7001ca3111acd55af2ffabf50eb4ae5' window.url = "http://api.wordnik.com/v4/resources.json"
window.discoveryUrl = "http://api.wordnik.com/v4/resources.json"
describe 'SwaggerUi', -> describe 'SwaggerUi', ->
@@ -8,7 +7,7 @@ describe 'SwaggerUi', ->
beforeEach -> beforeEach ->
window.ui = new SwaggerUi window.ui = new SwaggerUi
api_key: window.api_key api_key: window.api_key
discoveryUrl: window.discoveryUrl url: window.url
waitsFor -> waitsFor ->
ui.ready ui.ready