diff --git a/dist/css/print.css b/dist/css/print.css index 9470571f..32bf0c86 100644 --- a/dist/css/print.css +++ b/dist/css/print.css @@ -184,6 +184,7 @@ .swagger-section .swagger-ui-wrap { line-height: 1; font-family: "Droid Sans", sans-serif; + min-width: 760px; max-width: 960px; margin-left: auto; margin-right: auto; @@ -1180,18 +1181,122 @@ } .swagger-section .oauth_submit { text-align: center; + display: inline-block; +} +.swagger-section .authorize-wrapper { + margin: 15px 0 10px; +} +.swagger-section .authorize-wrapper_operation { + float: right; +} +.swagger-section .authorize__btn:hover { + text-decoration: underline; + cursor: pointer; +} +.swagger-section .authorize__btn_operation:hover .authorize-scopes { + display: block; +} +.swagger-section .authorize-scopes { + position: absolute; + margin-top: 20px; + background: #FFF; + border: 1px solid #ccc; + border-radius: 5px; + display: none; + font-size: 13px; + max-width: 300px; + line-height: 30px; + color: black; + padding: 5px; +} +.swagger-section .authorize-scopes .authorize__scope { + text-decoration: none; +} +.swagger-section .authorize__btn_operation { + height: 18px; + vertical-align: middle; + display: inline-block; + background: url(../images/explorer_icons.png) no-repeat; +} +.swagger-section .authorize__btn_operation_login { + background-position: 0 0; + width: 18px; + margin-top: -6px; + margin-left: 4px; +} +.swagger-section .authorize__btn_operation_logout { + background-position: -30px 0; + width: 18px; + margin-top: -6px; + margin-left: 4px; +} +.swagger-section #auth_container { + color: #fff; + display: inline-block; + border: none; + padding: 5px; + width: 87px; + height: 13px; +} +.swagger-section #auth_container .authorize__btn { + color: #fff; +} +.swagger-section .auth_container { + padding: 0 0 10px; + margin-bottom: 5px; + border-bottom: solid 1px #CCC; + font-size: 0.9em; +} +.swagger-section .auth_container .auth__title { + color: #547f00; + font-size: 1.2em; +} +.swagger-section .auth_container .basic_auth__label { + display: inline-block; + width: 60px; +} +.swagger-section .auth_container .auth__description { + color: #999999; + margin-bottom: 5px; +} +.swagger-section .auth_container .auth__button { + margin-top: 10px; + height: 30px; +} +.swagger-section .auth_container .key_auth__field { + margin: 5px 0; +} +.swagger-section .auth_container .key_auth__label { + display: inline-block; + width: 60px; } .swagger-section .api-popup-dialog { - z-index: 10000; position: absolute; + display: none; +} +.swagger-section .api-popup-dialog-wrapper { + z-index: 1000; width: 500px; background: #FFF; padding: 20px; border: 1px solid #ccc; border-radius: 5px; - display: none; font-size: 13px; color: #777; + position: fixed; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); +} +.swagger-section .api-popup-dialog-shadow { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + opacity: 0.2; + background-color: gray; + z-index: 900; } .swagger-section .api-popup-dialog .api-popup-title { font-size: 24px; @@ -1205,6 +1310,10 @@ padding-left: 5px; padding-bottom: 5px; } +.swagger-section .api-popup-dialog .api-popup-content { + max-height: 500px; + overflow-y: auto; +} .swagger-section .api-popup-dialog .api-popup-authbtn { height: 30px; } diff --git a/dist/css/screen.css b/dist/css/screen.css index 9fbd283b..90a93a2d 100644 --- a/dist/css/screen.css +++ b/dist/css/screen.css @@ -184,6 +184,7 @@ .swagger-section .swagger-ui-wrap { line-height: 1; font-family: "Droid Sans", sans-serif; + min-width: 760px; max-width: 960px; margin-left: auto; margin-right: auto; @@ -1180,18 +1181,122 @@ } .swagger-section .oauth_submit { text-align: center; + display: inline-block; +} +.swagger-section .authorize-wrapper { + margin: 15px 0 10px; +} +.swagger-section .authorize-wrapper_operation { + float: right; +} +.swagger-section .authorize__btn:hover { + text-decoration: underline; + cursor: pointer; +} +.swagger-section .authorize__btn_operation:hover .authorize-scopes { + display: block; +} +.swagger-section .authorize-scopes { + position: absolute; + margin-top: 20px; + background: #FFF; + border: 1px solid #ccc; + border-radius: 5px; + display: none; + font-size: 13px; + max-width: 300px; + line-height: 30px; + color: black; + padding: 5px; +} +.swagger-section .authorize-scopes .authorize__scope { + text-decoration: none; +} +.swagger-section .authorize__btn_operation { + height: 18px; + vertical-align: middle; + display: inline-block; + background: url(../images/explorer_icons.png) no-repeat; +} +.swagger-section .authorize__btn_operation_login { + background-position: 0 0; + width: 18px; + margin-top: -6px; + margin-left: 4px; +} +.swagger-section .authorize__btn_operation_logout { + background-position: -30px 0; + width: 18px; + margin-top: -6px; + margin-left: 4px; +} +.swagger-section #auth_container { + color: #fff; + display: inline-block; + border: none; + padding: 5px; + width: 87px; + height: 13px; +} +.swagger-section #auth_container .authorize__btn { + color: #fff; +} +.swagger-section .auth_container { + padding: 0 0 10px; + margin-bottom: 5px; + border-bottom: solid 1px #CCC; + font-size: 0.9em; +} +.swagger-section .auth_container .auth__title { + color: #547f00; + font-size: 1.2em; +} +.swagger-section .auth_container .basic_auth__label { + display: inline-block; + width: 60px; +} +.swagger-section .auth_container .auth__description { + color: #999999; + margin-bottom: 5px; +} +.swagger-section .auth_container .auth__button { + margin-top: 10px; + height: 30px; +} +.swagger-section .auth_container .key_auth__field { + margin: 5px 0; +} +.swagger-section .auth_container .key_auth__label { + display: inline-block; + width: 60px; } .swagger-section .api-popup-dialog { - z-index: 10000; position: absolute; + display: none; +} +.swagger-section .api-popup-dialog-wrapper { + z-index: 1000; width: 500px; background: #FFF; padding: 20px; border: 1px solid #ccc; border-radius: 5px; - display: none; font-size: 13px; color: #777; + position: fixed; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); +} +.swagger-section .api-popup-dialog-shadow { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + opacity: 0.2; + background-color: gray; + z-index: 900; } .swagger-section .api-popup-dialog .api-popup-title { font-size: 24px; @@ -1205,6 +1310,10 @@ padding-left: 5px; padding-bottom: 5px; } +.swagger-section .api-popup-dialog .api-popup-content { + max-height: 500px; + overflow-y: auto; +} .swagger-section .api-popup-dialog .api-popup-authbtn { height: 30px; } @@ -1297,7 +1406,9 @@ } .swagger-section #header { background-color: #89bf04; - padding: 14px; + padding: 9px 14px 19px 14px; + height: 23px; + min-width: 775px; } .swagger-section #input_baseUrl { width: 400px; @@ -1308,9 +1419,8 @@ float: right; } .swagger-section #api_selector .input { - display: block; + display: inline-block; clear: none; - float: left; margin: 0 10px 0 0; } .swagger-section #api_selector input { @@ -1321,7 +1431,8 @@ .swagger-section #input_apiKey { width: 200px; } -.swagger-section #explore { +.swagger-section #explore, +.swagger-section #auth_container .authorize__btn { display: block; text-decoration: none; font-weight: bold; @@ -1336,17 +1447,25 @@ -khtml-border-radius: 4px; border-radius: 4px; } -.swagger-section #explore:hover { +.swagger-section #explore:hover, +.swagger-section #auth_container .authorize__btn:hover { background-color: #547f00; } .swagger-section #header #logo { font-size: 1.5em; font-weight: bold; text-decoration: none; - background: transparent url(../images/logo_small.png) no-repeat left center; - padding: 20px 0 20px 40px; color: white; } +.swagger-section #header #logo .logo__img { + display: block; + float: left; + margin-top: 2px; +} +.swagger-section #header #logo .logo__title { + display: inline-block; + padding: 5px 0 0 10px; +} .swagger-section #content_message { margin: 10px 15px; font-style: italic; @@ -1363,3 +1482,7 @@ .swagger-section .swagger-expand:before { content: "+"; } +.swagger-section .error { + outline-color: #cc0000; + background-color: #f2dede; +} diff --git a/dist/index.html b/dist/index.html index d95471a1..4bd82d5c 100644 --- a/dist/index.html +++ b/dist/index.html @@ -67,7 +67,7 @@ window.SwaggerTranslator.translate(); } - addApiKeyAuthorization(); +// addApiKeyAuthorization(); }, onFailure: function(data) { log("Unable to Load SwaggerUI"); @@ -79,16 +79,16 @@ showRequestHeaders: false }); - function addApiKeyAuthorization(){ - var key = encodeURIComponent($('#input_apiKey')[0].value); - if(key && key.trim() != "") { - var apiKeyAuth = new SwaggerClient.ApiKeyAuthorization("api_key", key, "query"); - window.swaggerUi.api.clientAuthorizations.add("api_key", apiKeyAuth); - log("added key " + key); - } - } - - $('#input_apiKey').change(addApiKeyAuthorization); +// function addApiKeyAuthorization(){ +// var key = encodeURIComponent($('#input_apiKey')[0].value); +// if(key && key.trim() != "") { +// var apiKeyAuth = new SwaggerClient.ApiKeyAuthorization("api_key", key, "query"); +// window.swaggerUi.api.clientAuthorizations.add("api_key", apiKeyAuth); +// log("added key " + key); +// } +// } +// +// $('#input_apiKey').change(addApiKeyAuthorization); // if you have an apiKey you would like to pre-populate on the page for demonstration purposes... /* @@ -110,11 +110,11 @@ diff --git a/dist/lib/swagger-oauth.js b/dist/lib/swagger-oauth.js index 576fcd33..2bb6be11 100644 --- a/dist/lib/swagger-oauth.js +++ b/dist/lib/swagger-oauth.js @@ -331,7 +331,8 @@ window.onOAuthComplete = function onOAuthComplete(token,OAuthSchemeKey) { } } }); - window.swaggerUi.api.clientAuthorizations.add(OAuthSchemeKey, new SwaggerClient.ApiKeyAuthorization('Authorization', 'Bearer ' + b, 'header')); + window.swaggerUi.api.clientAuthorizations.add(window.OAuthSchemeKey, new SwaggerClient.ApiKeyAuthorization('Authorization', 'Bearer ' + b, 'header')); + window.swaggerUi.load(); } } } diff --git a/dist/swagger-ui.js b/dist/swagger-ui.js index 92d06e19..726d5a15 100644 --- a/dist/swagger-ui.js +++ b/dist/swagger-ui.js @@ -6,15 +6,90 @@ */ (function(){this["Handlebars"] = this["Handlebars"] || {}; this["Handlebars"]["templates"] = this["Handlebars"]["templates"] || {}; -this["Handlebars"]["templates"]["apikey_button_view"] = Handlebars.template({"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) { +this["Handlebars"]["templates"]["apikey_auth"] = Handlebars.template({"1":function(depth0,helpers,partials,data) { var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression; - return "\n
\n
\n
\n \n \n
\n
\n"; + return " " + + escapeExpression(((helper = (helper = helpers.value || (depth0 != null ? depth0.value : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"value","hash":{},"data":data}) : helper))) + + "\n"; +},"3":function(depth0,helpers,partials,data) { + return " \n"; + },"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) { + var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = "
\n

Api key authorization

\n
" + + escapeExpression(((helper = (helper = helpers.description || (depth0 != null ? depth0.description : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"description","hash":{},"data":data}) : helper))) + + "
\n
\n
\n name:\n " + + escapeExpression(((helper = (helper = helpers.name || (depth0 != null ? depth0.name : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"name","hash":{},"data":data}) : helper))) + + "\n
\n
\n in:\n " + + escapeExpression(((helper = (helper = helpers['in'] || (depth0 != null ? depth0['in'] : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"in","hash":{},"data":data}) : helper))) + + "\n
\n
\n value:\n"; + stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.isLogout : depth0), {"name":"if","hash":{},"fn":this.program(1, data),"inverse":this.program(3, data),"data":data}); + if (stack1 != null) { buffer += stack1; } + return buffer + "
\n
\n
\n"; +},"useData":true}); +this["Handlebars"]["templates"]["auth_button_operation"] = Handlebars.template({"1":function(depth0,helpers,partials,data) { + return " authorize__btn_operation_login\n"; + },"3":function(depth0,helpers,partials,data) { + return " authorize__btn_operation_logout\n"; + },"5":function(depth0,helpers,partials,data) { + var stack1, buffer = " \n"; +},"6":function(depth0,helpers,partials,data) { + var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression; + return "
  • " + + escapeExpression(((helper = (helper = helpers.scope || (depth0 != null ? depth0.scope : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"scope","hash":{},"data":data}) : helper))) + + "
  • \n"; +},"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) { + var stack1, buffer = "
    \n"; + stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.scopes : depth0), {"name":"if","hash":{},"fn":this.program(5, data),"inverse":this.noop,"data":data}); + if (stack1 != null) { buffer += stack1; } + return buffer + "
    \n"; },"useData":true}); -this["Handlebars"]["templates"]["basic_auth_button_view"] = Handlebars.template({"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) { - return "
    \n
    \n
    \n
    \n \n
    \n \n \n
    \n
    \n\n"; +this["Handlebars"]["templates"]["auth_button"] = Handlebars.template({"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) { + return "Authorize\n"; },"useData":true}); +this["Handlebars"]["templates"]["auth_view"] = Handlebars.template({"1":function(depth0,helpers,partials,data) { + return " \n"; + },"3":function(depth0,helpers,partials,data) { + return " \n"; + },"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) { + var stack1, buffer = "
    \n\n
    \n
    \n"; + stack1 = helpers.unless.call(depth0, (depth0 != null ? depth0.isLogout : depth0), {"name":"unless","hash":{},"fn":this.program(1, data),"inverse":this.noop,"data":data}); + if (stack1 != null) { buffer += stack1; } + stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.isAuthorized : depth0), {"name":"if","hash":{},"fn":this.program(3, data),"inverse":this.noop,"data":data}); + if (stack1 != null) { buffer += stack1; } + return buffer + "
    \n\n
    \n"; +},"useData":true}); +this["Handlebars"]["templates"]["basic_auth"] = Handlebars.template({"1":function(depth0,helpers,partials,data) { + return " - authorized"; + },"3":function(depth0,helpers,partials,data) { + var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression; + return " " + + escapeExpression(((helper = (helper = helpers.username || (depth0 != null ? depth0.username : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"username","hash":{},"data":data}) : helper))) + + "\n"; +},"5":function(depth0,helpers,partials,data) { + return " \n"; + },"7":function(depth0,helpers,partials,data) { + return "
    \n password:\n \n
    \n"; + },"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) { + var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = "
    \n

    Basic authentication"; + stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.isLogout : depth0), {"name":"if","hash":{},"fn":this.program(1, data),"inverse":this.noop,"data":data}); + if (stack1 != null) { buffer += stack1; } + buffer += "

    \n
    \n
    " + + escapeExpression(((helper = (helper = helpers.description || (depth0 != null ? depth0.description : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"description","hash":{},"data":data}) : helper))) + + "
    \n
    \n username:\n"; + stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.isLogout : depth0), {"name":"if","hash":{},"fn":this.program(3, data),"inverse":this.program(5, data),"data":data}); + if (stack1 != null) { buffer += stack1; } + buffer += "
    \n"; + stack1 = helpers.unless.call(depth0, (depth0 != null ? depth0.isLogout : depth0), {"name":"unless","hash":{},"fn":this.program(7, data),"inverse":this.noop,"data":data}); + if (stack1 != null) { buffer += stack1; } + return buffer + "
    \n
    \n"; +},"useData":true}); this["Handlebars"]["templates"]["content_type"] = Handlebars.template({"1":function(depth0,helpers,partials,data) { var stack1, buffer = ""; stack1 = helpers.each.call(depth0, (depth0 != null ? depth0.produces : depth0), {"name":"each","hash":{},"fn":this.program(2, data),"inverse":this.noop,"data":data}); @@ -403,7 +478,7 @@ this["Handlebars"]["templates"]["main"] = Handlebars.template({"1":function(dept var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = "
    \n"; stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.info : depth0), {"name":"if","hash":{},"fn":this.program(1, data),"inverse":this.noop,"data":data}); if (stack1 != null) { buffer += stack1; } - buffer += "
    \n
    \n \n\n
    \n

    [ base url: " + buffer += "

    \n
    \n
    \n\n \n\n
    \n

    [ base url: " + escapeExpression(((helper = (helper = helpers.basePath || (depth0 != null ? depth0.basePath : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"basePath","hash":{},"data":data}) : helper))) + "\n"; stack1 = helpers['if'].call(depth0, ((stack1 = (depth0 != null ? depth0.info : depth0)) != null ? stack1.version : stack1), {"name":"if","hash":{},"fn":this.program(14, data),"inverse":this.noop,"data":data}); @@ -413,6 +488,38 @@ this["Handlebars"]["templates"]["main"] = Handlebars.template({"1":function(dept if (stack1 != null) { buffer += stack1; } return buffer + "

    \n
    \n
    \n"; },"useData":true}); +this["Handlebars"]["templates"]["oauth2"] = Handlebars.template({"1":function(depth0,helpers,partials,data) { + var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = "
  • \n \n
    \n " + + escapeExpression(((helper = (helper = helpers.description || (depth0 != null ? depth0.description : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"description","hash":{},"data":data}) : helper))) + + "\n"; + stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.OAuthSchemeKey : depth0), {"name":"if","hash":{},"fn":this.program(2, data),"inverse":this.noop,"data":data}); + if (stack1 != null) { buffer += stack1; } + return buffer + " \n
  • \n"; +},"2":function(depth0,helpers,partials,data) { + var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression; + return " (" + + escapeExpression(((helper = (helper = helpers.OAuthSchemeKey || (depth0 != null ? depth0.OAuthSchemeKey : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"OAuthSchemeKey","hash":{},"data":data}) : helper))) + + ")\n"; +},"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) { + var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = "
    \n

    Select OAuth2.0 Scopes

    \n

    " + + escapeExpression(((helper = (helper = helpers.description || (depth0 != null ? depth0.description : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"description","hash":{},"data":data}) : helper))) + + "

    \n

    Scopes are used to grant an application different levels of access to data on behalf of the end user. Each API may declare one or more scopes.\n Learn how to use\n

    \n

    " + + escapeExpression(((helper = (helper = helpers.appName || (depth0 != null ? depth0.appName : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"appName","hash":{},"data":data}) : helper))) + + " API requires the following scopes. Select which ones you want to grant to Swagger UI.

    \n

    Authorization URL: " + + escapeExpression(((helper = (helper = helpers.authorizationUrl || (depth0 != null ? depth0.authorizationUrl : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"authorizationUrl","hash":{},"data":data}) : helper))) + + "

    \n

    flow: " + + escapeExpression(((helper = (helper = helpers.flow || (depth0 != null ? depth0.flow : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"flow","hash":{},"data":data}) : helper))) + + "

    \n \n
    "; +},"useData":true}); this["Handlebars"]["templates"]["operation"] = Handlebars.template({"1":function(depth0,helpers,partials,data) { return "deprecated"; },"3":function(depth0,helpers,partials,data) { @@ -423,41 +530,25 @@ this["Handlebars"]["templates"]["operation"] = Handlebars.template({"1":function if (stack1 != null) { buffer += stack1; } return buffer + "
    \n"; },"7":function(depth0,helpers,partials,data) { - return "
    \n "; + return "
    \n"; },"9":function(depth0,helpers,partials,data) { - var stack1, buffer = "
    \n"; - stack1 = helpers.each.call(depth0, depth0, {"name":"each","hash":{},"fn":this.program(10, data),"inverse":this.noop,"data":data}); - if (stack1 != null) { buffer += stack1; } - return buffer + "
    \n"; -},"10":function(depth0,helpers,partials,data) { - var stack1, lambda=this.lambda, escapeExpression=this.escapeExpression, buffer = "
    " - + escapeExpression(lambda((depth0 != null ? depth0.scope : depth0), depth0)) - + "
    \n"; -},"12":function(depth0,helpers,partials,data) { - return "
    "; - },"14":function(depth0,helpers,partials,data) { - return "
    \n \n
    \n"; - },"16":function(depth0,helpers,partials,data) { var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, buffer = "
    \n

    Response Class (Status " + escapeExpression(((helper = (helper = helpers.successCode || (depth0 != null ? depth0.successCode : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"successCode","hash":{},"data":data}) : helper))) + ")

    \n "; - stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.successDescription : depth0), {"name":"if","hash":{},"fn":this.program(17, data),"inverse":this.noop,"data":data}); + stack1 = helpers['if'].call(depth0, (depth0 != null ? depth0.successDescription : depth0), {"name":"if","hash":{},"fn":this.program(10, data),"inverse":this.noop,"data":data}); if (stack1 != null) { buffer += stack1; } return buffer + "\n

    \n
    \n
    \n
    \n"; -},"17":function(depth0,helpers,partials,data) { +},"10":function(depth0,helpers,partials,data) { var stack1, helper, functionType="function", helperMissing=helpers.helperMissing, buffer = "
    "; stack1 = ((helper = (helper = helpers.successDescription || (depth0 != null ? depth0.successDescription : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"successDescription","hash":{},"data":data}) : helper)); if (stack1 != null) { buffer += stack1; } return buffer + "
    "; -},"19":function(depth0,helpers,partials,data) { +},"12":function(depth0,helpers,partials,data) { var stack1, buffer = "

    Headers

    \n \n \n \n \n \n \n \n \n \n \n"; - stack1 = helpers.each.call(depth0, (depth0 != null ? depth0.headers : depth0), {"name":"each","hash":{},"fn":this.program(20, data),"inverse":this.noop,"data":data}); + stack1 = helpers.each.call(depth0, (depth0 != null ? depth0.headers : depth0), {"name":"each","hash":{},"fn":this.program(13, data),"inverse":this.noop,"data":data}); if (stack1 != null) { buffer += stack1; } return buffer + " \n
    HeaderDescriptionTypeOther
    \n"; -},"20":function(depth0,helpers,partials,data) { +},"13":function(depth0,helpers,partials,data) { var lambda=this.lambda, escapeExpression=this.escapeExpression; return " \n " + escapeExpression(lambda((data && data.key), depth0)) @@ -468,18 +559,18 @@ this["Handlebars"]["templates"]["operation"] = Handlebars.template({"1":function + "\n " + escapeExpression(lambda((depth0 != null ? depth0.other : depth0), depth0)) + "\n \n"; -},"22":function(depth0,helpers,partials,data) { +},"15":function(depth0,helpers,partials,data) { return "

    Parameters

    \n \n \n \n \n \n \n \n \n \n \n \n\n \n
    ParameterValueDescriptionParameter TypeData Type
    \n"; - },"24":function(depth0,helpers,partials,data) { + },"17":function(depth0,helpers,partials,data) { return "
    \n

    Response Messages

    \n \n \n \n \n \n \n \n \n \n \n \n
    HTTP Status CodeReasonResponse ModelHeaders
    \n"; - },"26":function(depth0,helpers,partials,data) { + },"19":function(depth0,helpers,partials,data) { return ""; -},"28":function(depth0,helpers,partials,data) { +},"21":function(depth0,helpers,partials,data) { return "
    \n \n \n \n
    \n"; - },"30":function(depth0,helpers,partials,data) { + },"23":function(depth0,helpers,partials,data) { return "

    Request Headers

    \n
    \n"; },"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) { - var stack1, helper, options, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression, blockHelperMissing=helpers.blockHelperMissing, buffer = "
    \n \n \n \n"; },"useData":true}); @@ -843,6 +922,12 @@ this["Handlebars"]["templates"]["parameter_content_type"] = Handlebars.template( if (stack1 != null) { buffer += stack1; } return buffer + "\n"; },"useData":true}); +this["Handlebars"]["templates"]["popup"] = Handlebars.template({"compiler":[6,">= 2.0.0-beta.1"],"main":function(depth0,helpers,partials,data) { + var helper, functionType="function", helperMissing=helpers.helperMissing, escapeExpression=this.escapeExpression; + return "
    \n
    " + + escapeExpression(((helper = (helper = helpers.title || (depth0 != null ? depth0.title : depth0)) != null ? helper : helperMissing),(typeof helper === functionType ? helper.call(depth0, {"name":"title","hash":{},"data":data}) : helper))) + + "
    \n
    \n

    \n
    \n \n
    \n
    \n
    "; +},"useData":true}); this["Handlebars"]["templates"]["resource"] = Handlebars.template({"1":function(depth0,helpers,partials,data) { return " : "; },"3":function(depth0,helpers,partials,data) { @@ -18796,6 +18881,10 @@ window.SwaggerUi = Backbone.Router.extend({ if (this.mainView) { this.mainView.clear(); } + + if (this.authView) { + this.authView.remove(); + } var url = this.options.url; if (url && url.indexOf('http') !== 0) { url = this.buildUrl(window.location.href.toString(), url); @@ -18827,6 +18916,7 @@ window.SwaggerUi = Backbone.Router.extend({ // This is bound to success handler for SwaggerApi // so it gets called when SwaggerApi completes loading render: function(){ + var authsModel; this.showMessage('Finished Loading Resource Information. Rendering Swagger UI...'); this.mainView = new SwaggerUi.Views.MainView({ model: this.api, @@ -18834,6 +18924,18 @@ window.SwaggerUi = Backbone.Router.extend({ swaggerOptions: this.options, router: this }).render(); + if (!_.isEmpty(this.api.securityDefinitions)){ + authsModel = _.map(this.api.securityDefinitions, function (auth, name) { + var result = {}; + result[name] = auth; + return result; + }); + this.authView = new SwaggerUi.Views.AuthButtonView({ + data: SwaggerUi.utils.parseSecurityDefinitions(authsModel), + router: this + }); + $('#auth_container').append(this.authView.render().el); + } this.showMessage(); switch (this.options.docExpansion) { case 'full': @@ -18923,7 +19025,10 @@ window.SwaggerUi = Backbone.Router.extend({ }); window.SwaggerUi.Views = {}; +window.SwaggerUi.Models = {}; +window.SwaggerUi.Collections = {}; window.SwaggerUi.partials = {}; +window.SwaggerUi.utils = {}; // don't break backward compatibility with previous versions and warn users to upgrade their code (function(){ @@ -18981,107 +19086,609 @@ window.SwaggerUi.partials = {}; 'use strict'; -SwaggerUi.Views.ApiKeyButton = Backbone.View.extend({ // TODO: append this to global SwaggerUi +window.SwaggerUi.utils = { + parseSecurityDefinitions: function (security) { + var auths = Object.assign({}, window.swaggerUi.api.authSchemes || window.swaggerUi.api.securityDefinitions); + var oauth2Arr = []; + var authsArr = []; + var scopes = []; + var utils = window.SwaggerUi.utils; + + if (!Array.isArray(security)) { return null; } + + security.forEach(function (item) { + var singleSecurity = {}; + var singleOauth2Security = {}; + + for (var key in item) { + if (Array.isArray(item[key])) { + if (!auths[key]) { continue; } + auths[key] = auths[key] || {}; + if (auths[key].type === 'oauth2') { + singleOauth2Security[key] = Object.assign({}, auths[key]); + for (var i in singleOauth2Security[key].scopes) { + if (item[key].indexOf(i) < 0) { + delete singleOauth2Security[key].scopes[i]; + } + } + singleOauth2Security[key].scopes = utils.parseOauth2Scopes(singleOauth2Security[key].scopes); + scopes = _.merge(scopes, singleOauth2Security[key].scopes); + } else { + singleSecurity[key] = Object.assign({}, auths[key]); + } + } else { + if (item[key].type === 'oauth2') { + singleOauth2Security[key] = Object.assign({}, item[key]); + singleOauth2Security[key].scopes = utils.parseOauth2Scopes(singleOauth2Security[key].scopes); + scopes = _.merge(scopes, singleOauth2Security[key].scopes); + } else { + singleSecurity[key] = item[key]; + } + } + } - events:{ - 'click #apikey_button' : 'toggleApiKeyContainer', - 'click #apply_api_key' : 'applyApiKey' - }, + if (!_.isEmpty(singleSecurity)) { + authsArr.push(singleSecurity); + } - initialize: function(opts){ - this.options = opts || {}; - this.router = this.options.router; - }, + if (!_.isEmpty(singleOauth2Security)){ + oauth2Arr.push(singleOauth2Security); + } + }); - render: function(){ - var template = this.template(); - $(this.el).html(template(this.model)); + return { + auths : authsArr, + oauth2: oauth2Arr, + scopes: scopes + }; + }, - return this; - }, + parseOauth2Scopes: function (data) { + var scopes = Object.assign({}, data); + var result = []; + var key; + for (key in scopes) { + result.push({scope: key, description: scopes[key]}); + } - applyApiKey: function(){ - var keyAuth = new SwaggerClient.ApiKeyAuthorization( - this.model.name, - $('#input_apiKey_entry').val(), - this.model.in - ); - this.router.api.clientAuthorizations.add(this.model.name, keyAuth); - this.router.load(); - $('#apikey_container').show(); - }, + return result; + } +}; +'use strict'; - toggleApiKeyContainer: function(){ - if ($('#apikey_container').length) { +SwaggerUi.Models.ApiKeyAuthModel = Backbone.Model.extend({ + defaults: { + 'in': '', + name: '', + title: '', + value: '' + }, - var elem = $('#apikey_container').first(); + initialize: function () { + this.on('change', this.validate); + }, - if (elem.is(':visible')){ - elem.hide(); - } else { + validate: function () { + var valid = !!this.get('value'); - // hide others - $('.auth_container').hide(); - elem.show(); - } + this.set('valid', valid); + + return valid; } - }, +}); +'use strict'; - template: function(){ - return Handlebars.templates.apikey_button_view; - } +SwaggerUi.Views.ApiKeyAuthView = Backbone.View.extend({ // TODO: append this to global SwaggerUi + + events: { + 'change .input_apiKey_entry': 'apiKeyChange' + }, + + selectors: { + apikeyInput: '.input_apiKey_entry' + }, + + template: Handlebars.templates.apikey_auth, + + initialize: function(opts) { + this.options = opts || {}; + this.router = this.options.router; + }, + + render: function (){ + this.$el.html(this.template(this.model.toJSON())); + + return this; + }, + + apiKeyChange: function (e) { + var val = $(e.target).val(); + if (val) { + this.$(this.selectors.apikeyInput).removeClass('error'); + } + + this.model.set('value', val); + }, + + isValid: function () { + return this.model.validate(); + }, + + highlightInvalid: function () { + if (!this.isValid()) { + this.$(this.selectors.apikeyInput).addClass('error'); + } + } }); 'use strict'; -SwaggerUi.Views.BasicAuthButton = Backbone.View.extend({ +SwaggerUi.Views.AuthButtonView = Backbone.View.extend({ + events: { + 'click .authorize__btn': 'authorizeBtnClick' + }, + tpls: { + popup: Handlebars.templates.popup, + authBtn: Handlebars.templates.auth_button, + authBtnOperation: Handlebars.templates.auth_button_operation + }, - initialize: function (opts) { - this.options = opts || {}; - this.router = this.options.router; - }, + initialize: function(opts) { + this.options = opts || {}; + this.options.data = this.options.data || {}; + this.isOperation = this.options.isOperation; + this.model = this.model || {}; + this.router = this.options.router; + this.auths = this.options.data.oauth2.concat(this.options.data.auths); + }, - render: function(){ - var template = this.template(); - $(this.el).html(template(this.model)); + render: function () { + var tplName = this.isOperation ? 'authBtnOperation' : 'authBtn'; - return this; - }, + this.$authEl = this.renderAuths(this.auths); + this.$el.html(this.tpls[tplName](this.model)); - events: { - 'click #basic_auth_button' : 'togglePasswordContainer', - 'click #apply_basic_auth' : 'applyPassword' - }, + return this; + }, - applyPassword: function(event){ - event.preventDefault(); - var username = $('#input_username').val(); - var password = $('#input_password').val(); - var basicAuth = new SwaggerClient.PasswordAuthorization('basic', username, password); - this.router.api.clientAuthorizations.add(this.model.type, basicAuth); - this.router.load(); - $('#basic_auth_container').hide(); - }, + authorizeBtnClick: function (e) { + var authsModel; - togglePasswordContainer: function(){ - if ($('#basic_auth_container').length) { - var elem = $('#basic_auth_container').show(); - if (elem.is(':visible')){ - elem.slideUp(); - } else { - // hide others - $('.auth_container').hide(); - elem.show(); - } + e.preventDefault(); + + authsModel = { + title: 'Available authorizations', + content: this.$authEl + }; + + this.popup = new SwaggerUi.Views.PopupView({model: authsModel}); + this.popup.render(); + }, + + renderAuths: function (auths) { + var $el = $('
    '); + var isLogout = false; + + auths.forEach(function (auth) { + var authView = new SwaggerUi.Views.AuthView({data: auth, router: this.router}); + var authEl = authView.render().el; + $el.append(authEl); + if (authView.isLogout) { + isLogout = true; + } + }, this); + + this.model.isLogout = isLogout; + + return $el; } - }, - template: function(){ - return Handlebars.templates.basic_auth_button_view; - } +}); + +'use strict'; + +SwaggerUi.Collections.AuthsCollection = Backbone.Collection.extend({ + constructor: function() { + var args = Array.prototype.slice.call(arguments); + + args[0] = this.parse(args[0]); + + Backbone.Collection.apply(this, args); + }, + + add: function (model) { + var args = Array.prototype.slice.call(arguments); + + if (Array.isArray(model)) { + args[0] = _.map(model, function(val) { + return this.handleOne(val); + }, this); + } else { + args[0] = this.handleOne(model); + } + + Backbone.Collection.prototype.add.apply(this, args); + }, + + handleOne: function (model) { + var result = model; + + if (! (model instanceof Backbone.Model) ) { + switch (model.type) { + case 'oauth2': + result = new SwaggerUi.Models.Oauth2Model(model); + break; + case 'basic': + result = new SwaggerUi.Models.BasicAuthModel(model); + break; + case 'apiKey': + result = new SwaggerUi.Models.ApiKeyAuthModel(model); + break; + default: + result = new Backbone.Model(model); + } + } + + return result; + }, + + isValid: function () { + var valid = true; + + this.models.forEach(function(model) { + if (!model.validate()) { + valid = false; + } + }); + + return valid; + }, + + isAuthorized: function () { + return this.length === this.where({ isLogout: true }).length; + }, + + isPartiallyAuthorized: function () { + return this.where({ isLogout: true }).length > 0; + }, + + parse: function (data) { + var authz = Object.assign({}, window.swaggerUi.api.clientAuthorizations.authz); + + return _.map(data, function (auth, name) { + var isBasic = authz.basic && auth.type === 'basic'; + _.extend(auth, { + title: name + }); + + if (authz[name] || isBasic) { + _.extend(auth, { + isLogout: true, + value: isBasic ? undefined : authz[name].value, + username: isBasic ? authz.basic.username : undefined, + password: isBasic ? authz.basic.password : undefined, + valid: true + }); + } + + return auth; + }); + } +}); +'use strict'; + +SwaggerUi.Views.AuthsCollectionView = Backbone.View.extend({ + + initialize: function(opts) { + this.options = opts || {}; + this.options.data = this.options.data || {}; + this.router = this.options.router; + + this.collection = new SwaggerUi.Collections.AuthsCollection(opts.data); + + this.$innerEl = $('
    '); + this.authViews = []; + }, + + render: function () { + this.collection.each(function (auth) { + this.renderOneAuth(auth); + }, this); + + this.$el.html(this.$innerEl.html() ? this.$innerEl : ''); + + return this; + }, + + renderOneAuth: function (authModel) { + var authViewEl, authView, authViewName; + var type = authModel.get('type'); + + if (type === 'apiKey') { + authViewName = 'ApiKeyAuthView'; + } else if (type === 'basic' && this.$innerEl.find('.basic_auth_container').length === 0) { + authViewName = 'BasicAuthView'; + } else if (type === 'oauth2') { + authViewName = 'Oauth2View'; + } + + if (authViewName) { + authView = new SwaggerUi.Views[authViewName]({model: authModel, router: this.router}); + authViewEl = authView.render().el; + this.authViews.push(authView); + } + + this.$innerEl.append(authViewEl); + }, + + highlightInvalid: function () { + this.authViews.forEach(function (view) { + view.highlightInvalid(); + }, this); + } + +}); + +'use strict'; + +/* global redirect_uri */ +/* global clientId */ +/* global scopeSeparator */ +/* global additionalQueryStringParams */ +/* global clientSecret */ +/* global onOAuthComplete */ +/* global realm */ +/*jshint unused:false*/ + +SwaggerUi.Views.AuthView = Backbone.View.extend({ + events: { + 'click .auth_submit__button': 'authorizeClick', + 'click .auth_logout__button': 'logoutClick' + }, + + tpls: { + main: Handlebars.templates.auth_view + }, + + selectors: { + innerEl: '.auth_inner', + authBtn: '.auth_submit__button' + }, + + initialize: function(opts) { + this.options = opts || {}; + opts.data = opts.data || {}; + this.router = this.options.router; + + this.authsCollectionView = new SwaggerUi.Views.AuthsCollectionView({data: opts.data}); + + this.$el.html(this.tpls.main({ + isLogout: this.authsCollectionView.collection.isAuthorized(), + isAuthorized: this.authsCollectionView.collection.isPartiallyAuthorized() + })); + this.$innerEl = this.$(this.selectors.innerEl); + this.isLogout = this.authsCollectionView.collection.isPartiallyAuthorized(); + }, + + render: function () { + this.$innerEl.html(this.authsCollectionView.render().el); + + return this; + }, + + authorizeClick: function (e) { + e.preventDefault(); + e.stopPropagation(); + + if (this.authsCollectionView.collection.isValid()) { + this.authorize(); + } else { + this.authsCollectionView.highlightInvalid(); + } + }, + + authorize: function () { + this.authsCollectionView.collection.forEach(function (auth) { + var keyAuth, basicAuth; + var type = auth.get('type'); + + if (type === 'apiKey') { + keyAuth = new SwaggerClient.ApiKeyAuthorization( + auth.get('name'), + auth.get('value'), + auth.get('in') + ); + + this.router.api.clientAuthorizations.add(auth.get('title'), keyAuth); + } else if (type === 'basic') { + basicAuth = new SwaggerClient.PasswordAuthorization(auth.get('username'), auth.get('password')); + this.router.api.clientAuthorizations.add(auth.get('type'), basicAuth); + } else if (type === 'oauth2') { + this.handleOauth2Login(auth); + } + }, this); + + this.router.load(); + }, + + logoutClick: function (e) { + e.preventDefault(); + + this.authsCollectionView.collection.forEach(function (auth) { + var name = auth.get('type') === 'basic' ? 'basic' : auth.get('title'); + + window.swaggerUi.api.clientAuthorizations.remove(name); + }); + + this.router.load(); + }, + + // taken from lib/swagger-oauth.js + handleOauth2Login: function (auth) { + var host = window.location; + var pathname = location.pathname.substring(0, location.pathname.lastIndexOf('/')); + var defaultRedirectUrl = host.protocol + '//' + host.host + pathname + '/o2c.html'; + var redirectUrl = window.oAuthRedirectUrl || defaultRedirectUrl; + var url = null; + var scopes = _.map(auth.get('scopes'), function (scope) { + return scope.scope; + }); + var state, dets, ep; + window.OAuthSchemeKey = auth.get('title'); + + window.enabledScopes = scopes; + var flow = auth.get('flow'); + + if(auth.get('type') === 'oauth2' && flow && (flow === 'implicit' || flow === 'accessCode')) { + dets = auth.attributes; + url = dets.authorizationUrl + '?response_type=' + (flow === 'implicit' ? 'token' : 'code'); + window.swaggerUi.tokenName = dets.tokenName || 'access_token'; + window.swaggerUi.tokenUrl = (flow === 'accessCode' ? dets.tokenUrl : null); + state = window.OAuthSchemeKey; + } + else if(auth.get('type') === 'oauth2' && flow && (flow === 'application')) { + dets = auth.attributes; + window.swaggerUi.tokenName = dets.tokenName || 'access_token'; + this.clientCredentialsFlow(scopes, dets.tokenUrl, window.OAuthSchemeKey); + return; + } + else if(auth.get('grantTypes')) { + // 1.2 support + var o = auth.get('grantTypes'); + for(var t in o) { + if(o.hasOwnProperty(t) && t === 'implicit') { + dets = o[t]; + ep = dets.loginEndpoint.url; + url = dets.loginEndpoint.url + '?response_type=token'; + window.swaggerUi.tokenName = dets.tokenName; + } + else if (o.hasOwnProperty(t) && t === 'accessCode') { + dets = o[t]; + ep = dets.tokenRequestEndpoint.url; + url = dets.tokenRequestEndpoint.url + '?response_type=code'; + window.swaggerUi.tokenName = dets.tokenName; + } + } + } + + var redirect_uri = redirectUrl; + + url += '&redirect_uri=' + encodeURIComponent(redirectUrl); + url += '&realm=' + encodeURIComponent(realm); + url += '&client_id=' + encodeURIComponent(clientId); + url += '&scope=' + encodeURIComponent(scopes.join(scopeSeparator)); + url += '&state=' + encodeURIComponent(state); + for (var key in additionalQueryStringParams) { + url += '&' + key + '=' + encodeURIComponent(additionalQueryStringParams[key]); + } + + window.open(url); + }, + + // taken from lib/swagger-oauth.js + clientCredentialsFlow: function (scopes, tokenUrl, OAuthSchemeKey) { + var params = { + 'client_id': clientId, + 'client_secret': clientSecret, + 'scope': scopes.join(' '), + 'grant_type': 'client_credentials' + }; + $.ajax({ + url : tokenUrl, + type: 'POST', + data: params, + success: function (data) + { + onOAuthComplete(data, OAuthSchemeKey); + }, + error: function () + { + onOAuthComplete(''); + } + }); + } + +}); + +'use strict'; + +SwaggerUi.Models.BasicAuthModel = Backbone.Model.extend({ + defaults: { + username: '', + password: '', + title: 'basic' + }, + + initialize: function () { + this.on('change', this.validate); + }, + + validate: function () { + var valid = !!this.get('password') && !!this.get('username'); + + this.set('valid', valid); + + return valid; + } +}); +'use strict'; + +SwaggerUi.Views.BasicAuthView = Backbone.View.extend({ + + initialize: function (opts) { + this.options = opts || {}; + this.router = this.options.router; + }, + + events: { + 'change .auth_input': 'inputChange' + }, + + selectors: { + usernameInput: '.basic_auth__username', + passwordInput: '.basic_auth__password' + }, + + cls: { + error: 'error' + }, + + template: Handlebars.templates.basic_auth, + + render: function(){ + $(this.el).html(this.template(this.model.toJSON())); + + return this; + }, + + inputChange: function (e) { + var $el = $(e.target); + var val = $el.val(); + var attr = $el.prop('name'); + + if (val) { + $el.removeClass(this.cls.error); + } + + this.model.set(attr, val); + }, + + isValid: function () { + return this.model.validate(); + }, + + highlightInvalid: function () { + if (!this.model.get('username')) { + this.$(this.selectors.usernameInput).addClass(this.cls.error); + } + + if (!this.model.get('password')) { + this.$(this.selectors.passwordInput).addClass(this.cls.error); + } + } }); 'use strict'; @@ -19124,8 +19731,7 @@ SwaggerUi.Views.HeaderView = Backbone.View.extend({ } this.trigger('update-swagger-ui', { - url: $('#input_baseUrl').val(), - apiKey: $('#input_apiKey').val() + url: $('#input_baseUrl').val() }); }, @@ -19136,7 +19742,6 @@ SwaggerUi.Views.HeaderView = Backbone.View.extend({ $('#input_baseUrl').val(url); - //$('#input_apiKey').val(apiKey); if (trigger) { this.trigger('update-swagger-ui', {url:url}); } @@ -19227,26 +19832,9 @@ SwaggerUi.Views.MainView = Backbone.View.extend({ }, - 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, router: this.router}).render().el; - $('.auth_main_container').append(button); - } - - if (auth.type === 'basicAuth' && $('#basic_auth_button').length === 0) { - button = new SwaggerUi.Views.BasicAuthButton({model: auth, router: this.router}).render().el; - $('.auth_main_container').append(button); - } - } - } - - // Render the outer container for resources + render: function () { $(this.el).html(Handlebars.templates.main(this.model)); + this.model.securityDefinitions = this.model.securityDefinitions || {}; // Render each resource @@ -19298,7 +19886,7 @@ SwaggerUi.Views.MainView = Backbone.View.extend({ onLinkClick: function (e) { var el = e.target; - if (el.tagName === 'A') { + if (el.tagName === 'A' && el.href) { if (location.hostname !== el.hostname || location.port !== el.port) { e.preventDefault(); window.open(el.href, '_blank'); @@ -19309,6 +19897,60 @@ SwaggerUi.Views.MainView = Backbone.View.extend({ 'use strict'; +SwaggerUi.Models.Oauth2Model = Backbone.Model.extend({ + defaults: { + scopes: {} + }, + + initialize: function () { + this.on('change', this.validate); + }, + + setScopes: function (name, val) { + var auth = _.extend({}, this.attributes); + var index = _.findIndex(auth.scopes, function(o) { + return o.scope === name; + }); + auth.scopes[index].checked = val; + + this.set(auth); + this.validate(); + }, + + validate: function () { + var valid = _.findIndex(this.get('scopes'), function (o) { + return o.checked === true; + }) > -1; + + this.set('valid', valid); + + return valid; + } +}); +'use strict'; + +SwaggerUi.Views.Oauth2View = Backbone.View.extend({ + events: { + 'change .oauth-scope': 'scopeChange' + }, + + template: Handlebars.templates.oauth2, + + render: function () { + this.$el.html(this.template(this.model.toJSON())); + + return this; + }, + + scopeChange: function (e) { + var val = $(e.target).prop('checked'); + var scope = $(e.target).data('scope'); + + this.model.setScopes(scope, val); + } +}); +'use strict'; + SwaggerUi.Views.OperationView = Backbone.View.extend({ invocationUrl: null, @@ -19341,21 +19983,21 @@ SwaggerUi.Views.OperationView = Backbone.View.extend({ }, selectText: function(event) { - var doc = document, - text = event.target.firstChild, - range, - selection; - if (doc.body.createTextRange) { - range = document.body.createTextRange(); - range.moveToElementText(text); - range.select(); - } else if (window.getSelection) { - selection = window.getSelection(); - range = document.createRange(); - range.selectNodeContents(text); - selection.removeAllRanges(); - selection.addRange(range); - } + var doc = document, + text = event.target.firstChild, + range, + selection; + if (doc.body.createTextRange) { + range = document.body.createTextRange(); + range.moveToElementText(text); + range.select(); + } else if (window.getSelection) { + selection = window.getSelection(); + range = document.createRange(); + range.selectNodeContents(text); + selection.removeAllRanges(); + selection.addRange(range); + } }, mouseEnter: function(e) { @@ -19566,6 +20208,21 @@ SwaggerUi.Views.OperationView = Backbone.View.extend({ this.addStatusCode(statusCode); } + if (Array.isArray(this.model.security)) { + var authsModel = SwaggerUi.utils.parseSecurityDefinitions(this.model.security); + + authsModel.isLogout = !_.isEmpty(window.swaggerUi.api.clientAuthorizations.authz); + this.authView = new SwaggerUi.Views.AuthButtonView({ + data: authsModel, + router: this.router, + isOperation: true, + model: { + scopes: authsModel.scopes + } + }); + this.$('.authorize-wrapper').append(this.authView.render().el); + } + this.showSnippet(); return this; }, @@ -19801,7 +20458,7 @@ SwaggerUi.Views.OperationView = Backbone.View.extend({ // wraps a jquery response as a shred response wrap: function(data) { - var h, headerArray, headers, i, l, len, o; + var h, headerArray, headers, i, l, len, o; headers = {}; headerArray = data.getAllResponseHeaders().split('\r'); for (l = 0, len = headerArray.length; l < len; l++) { @@ -19978,7 +20635,7 @@ SwaggerUi.Views.OperationView = Backbone.View.extend({ code = $('').text('no content'); pre = $('
    ').append(code);
     
    -    // JSON
    +      // JSON
         } else if (contentType === 'application/json' || /\+json$/.test(contentType)) {
           var json = null;
           try {
    @@ -19989,35 +20646,35 @@ SwaggerUi.Views.OperationView = Backbone.View.extend({
           code = $('').text(json);
           pre = $('
    ').append(code);
     
    -    // XML
    +      // XML
         } else if (contentType === 'application/xml' || /\+xml$/.test(contentType)) {
           code = $('').text(this.formatXml(content));
           pre = $('
    ').append(code);
     
    -    // HTML
    +      // HTML
         } else if (contentType === 'text/html') {
           code = $('').html(_.escape(content));
           pre = $('
    ').append(code);
     
    -    // Plain Text
    +      // Plain Text
         } else if (/text\/plain/.test(contentType)) {
           code = $('').text(content);
           pre = $('
    ').append(code);
     
     
    -    // Image
    +      // Image
         } else if (/^image\//.test(contentType)) {
           pre = $('').attr('src', url);
     
    -    // Audio
    +      // Audio
         } else if (/^audio\//.test(contentType) && supportsAudioPlayback(contentType)) {
           pre = $('