diff --git a/docs/custom_ui.rst b/docs/custom_ui.rst index c81d5ad..6603506 100644 --- a/docs/custom_ui.rst +++ b/docs/custom_ui.rst @@ -4,15 +4,8 @@ Customizing the web UI The web UI can be customized using the settings available in :ref:`swagger-ui-settings` and :ref:`redoc-ui-settings`. -You can also extend one of the ``drf-yasg/swagger-ui.html`` or ``drf-yasg/redoc.html`` templates that are used for -rendering. The customizable blocks are currently limited to: +You can also extend one of the drf-yasg/swagger-ui.html_ or drf-yasg/redoc.html_ templates that are used for +rendering. See the template source code (linked above) for a complete list of customizable blocks. -{% block extra_styles %} - additional stylesheets - -{% block extra_scripts %} - additional scripts - -{% block user_context_message %} - *(swagger-ui session auth only)* - logged in user message +.. _drf-yasg/swagger-ui.html: https://github.com/axnsan12/drf-yasg/blob/master/src/drf_yasg/templates/drf-yasg/swagger-ui.html +.. _drf-yasg/redoc.html: https://github.com/axnsan12/drf-yasg/blob/master/src/drf_yasg/templates/drf-yasg/redoc.html diff --git a/src/drf_yasg/static/drf-yasg/redoc-init.js b/src/drf_yasg/static/drf-yasg/redoc-init.js index b45a2e3..a8b59e3 100644 --- a/src/drf_yasg/static/drf-yasg/redoc-init.js +++ b/src/drf_yasg/static/drf-yasg/redoc-init.js @@ -23,7 +23,7 @@ for (var p in redocSettings) { } } -document.body.appendChild(redoc); +document.body.replaceChild(redoc, document.getElementById('redoc-placeholder')); function hideEmptyVersion() { // 'span.api-info-version' is for redoc 1.x, 'div.api-info span' is for redoc 2-alpha diff --git a/src/drf_yasg/static/drf-yasg/redoc/redoc-logo.png b/src/drf_yasg/static/drf-yasg/redoc/redoc-logo.png new file mode 100644 index 0000000..73e5e03 Binary files /dev/null and b/src/drf_yasg/static/drf-yasg/redoc/redoc-logo.png differ diff --git a/src/drf_yasg/static/drf-yasg/swagger-ui-dist/favicon-16x16.png b/src/drf_yasg/static/drf-yasg/swagger-ui-dist/favicon-16x16.png deleted file mode 100644 index 0f7e13b..0000000 Binary files a/src/drf_yasg/static/drf-yasg/swagger-ui-dist/favicon-16x16.png and /dev/null differ diff --git a/src/drf_yasg/static/drf-yasg/swagger-ui-init.js b/src/drf_yasg/static/drf-yasg/swagger-ui-init.js index fc69d43..8db8642 100644 --- a/src/drf_yasg/static/drf-yasg/swagger-ui-init.js +++ b/src/drf_yasg/static/drf-yasg/swagger-ui-init.js @@ -1,12 +1,16 @@ "use strict"; var currentPath = window.location.protocol + "//" + window.location.host + window.location.pathname; var defaultSpecUrl = currentPath + '?format=openapi'; + +// load the saved authorization state from localStorage; ImmutableJS is used for consistency with swagger-ui state var savedAuth = Immutable.fromJS({}); try { savedAuth = Immutable.fromJS(JSON.parse(localStorage.getItem("drf-yasg-auth")) || {}); } catch (e) { localStorage.removeItem("drf-yasg-auth"); } + +// global SwaggerUI config object; can be changed directly or by hooking initSwaggerUiConfig var swaggerUiConfig = { url: defaultSpecUrl, dom_id: '#swagger-ui', @@ -35,7 +39,7 @@ var swaggerUiConfig = { onComplete: function () { preauthorizeAny(savedAuth, window.ui); hookAuthActions(window.ui); - }, + } }; function patchSwaggerUi() { @@ -62,29 +66,52 @@ function initSwaggerUi() { console.log("WARNING: skipping initSwaggerUi() because window.ui is already defined"); return; } + if (document.querySelector('.auth-wrapper .authorize')) { + patchSwaggerUi(); + } + else { + insertionQ('.auth-wrapper .authorize').every(patchSwaggerUi); + } var swaggerSettings = JSON.parse(document.getElementById('swagger-settings').innerHTML); - if (!('oauth2RedirectUrl' in swaggerSettings)) { - var oauth2RedirectUrl = document.getElementById('oauth2-redirect-url'); - if (oauth2RedirectUrl) { - swaggerSettings['oauth2RedirectUrl'] = oauth2RedirectUrl.href; - oauth2RedirectUrl.parentNode.removeChild(oauth2RedirectUrl); + + var oauth2RedirectUrl = document.getElementById('oauth2-redirect-url'); + if (oauth2RedirectUrl) { + if (!('oauth2RedirectUrl' in swaggerSettings)) { + if (oauth2RedirectUrl) { + swaggerSettings['oauth2RedirectUrl'] = oauth2RedirectUrl.href; + } } + oauth2RedirectUrl.parentNode.removeChild(oauth2RedirectUrl); } console.log('swaggerSettings', swaggerSettings); + var oauth2Config = JSON.parse(document.getElementById('oauth2-config').innerHTML); + console.log('oauth2Config', oauth2Config); + + initSwaggerUiConfig(swaggerSettings, oauth2Config); + window.ui = SwaggerUIBundle(swaggerUiConfig); + window.ui.initOAuth(oauth2Config); +} + +/** + * Initialize the global swaggerUiConfig with any given additional settings. + * @param swaggerSettings SWAGGER_SETTINGS from Django settings + * @param oauth2Settings OAUTH2_CONFIG from Django settings + */ +function initSwaggerUiConfig(swaggerSettings, oauth2Settings) { for (var p in swaggerSettings) { if (swaggerSettings.hasOwnProperty(p)) { swaggerUiConfig[p] = swaggerSettings[p]; } } - - var oauth2Config = JSON.parse(document.getElementById('oauth2-config').innerHTML); - console.log('oauth2Config', oauth2Config); - window.ui = SwaggerUIBundle(swaggerUiConfig); - window.ui.initOAuth(oauth2Config); } +/** + * Call sui.preauthorize### according to the type of savedAuth. + * @param savedAuth auth object saved from authActions.authorize + * @param sui SwaggerUI or SwaggerUIBundle instance + */ function preauthorizeAny(savedAuth, sui) { var schemeName = savedAuth.get("name"), schemeType = savedAuth.getIn(["schema", "type"]); if (schemeType === "basic" && schemeName) { @@ -101,6 +128,11 @@ function preauthorizeAny(savedAuth, sui) { } } +/** + * Manually apply auth headers from the given auth object. + * @param savedAuth auth object saved from authActions.authorize + * @param requestHeaders target headers + */ function applyAuth(savedAuth, requestHeaders) { var schemeName = savedAuth.get("name"), schemeType = savedAuth.getIn(["schema", "type"]); if (schemeType === "basic" && schemeName) { @@ -121,6 +153,11 @@ function applyAuth(savedAuth, requestHeaders) { } } +/** + * Hook the authorize and logout actions of SwaggerUI. + * The hooks are used to persist authorization data and trigger schema refetch. + * @param sui SwaggerUI or SwaggerUIBundle instance + */ function hookAuthActions(sui) { var originalAuthorize = sui.authActions.authorize; sui.authActions.authorize = function (authorization) { @@ -144,13 +181,4 @@ function hookAuthActions(sui) { }; } -window.addEventListener('load', function () { - initSwaggerUi(); - - if (document.querySelector('.auth-wrapper .authorize')) { - patchSwaggerUi(); - } - else { - insertionQ('.auth-wrapper .authorize').every(patchSwaggerUi); - } -}); +window.addEventListener('load', initSwaggerUi); diff --git a/src/drf_yasg/templates/drf-yasg/redoc.html b/src/drf_yasg/templates/drf-yasg/redoc.html index 34f4a2f..f51a5eb 100644 --- a/src/drf_yasg/templates/drf-yasg/redoc.html +++ b/src/drf_yasg/templates/drf-yasg/redoc.html @@ -2,21 +2,45 @@
-