Skip to content

Commit b1605a0

Browse files
committed
Merge branch 'master' into bug/3329-duplicate-css
# Conflicts: # make-webpack-config.js
2 parents 87bb442 + aab1403 commit b1605a0

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+631
-169
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ node_modules
55
npm-debug.log*
66
.eslintcache
77
package-lock.json
8+
*.iml

README.md

+15-13
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ The OpenAPI Specification has undergone 4 revisions since initial creation in 20
2222

2323
Swagger UI Version | Release Date | OpenAPI Spec compatibility | Notes | Status
2424
------------------ | ------------ | -------------------------- | ----- | ------
25-
3.0.18 | 2017-07-07 | 2.0 | [tag v3.0.18](https://github.com/swagger-api/swagger-ui/tree/v3.0.18) |
25+
3.0.19 | 2017-07-14 | 2.0 | [tag v3.0.19](https://github.com/swagger-api/swagger-ui/tree/v3.0.19) |
2626
2.2.10 | 2017-01-04 | 1.1, 1.2, 2.0 | [tag v2.2.10](https://github.com/swagger-api/swagger-ui/tree/v2.2.10) |
2727
2.1.5 | 2016-07-20 | 1.1, 1.2, 2.0 | [tag v2.1.5](https://github.com/swagger-api/swagger-ui/tree/v2.1.5) |
2828
2.0.24 | 2014-09-12 | 1.1, 1.2 | [tag v2.0.24](https://github.com/swagger-api/swagger-ui/tree/v2.0.24) |
@@ -67,7 +67,6 @@ To help with the migration, here are the currently known issues with 3.X. This l
6767

6868
- Only part of the [parameters](#parameters) previously supported are available.
6969
- The JSON Form Editor is not implemented.
70-
- Shebang URL support for operations is missing.
7170
- Support for `collectionFormat` is partial.
7271
- l10n (translations) is not implemented.
7372
- Relative path support for external files is not implemented.
@@ -82,17 +81,17 @@ To use swagger-ui's bundles, you should take a look at the [source of swagger-ui
8281

8382
```javascript
8483
const ui = SwaggerUIBundle({
85-
url: "http://petstore.swagger.io/v2/swagger.json",
86-
dom_id: '#swagger-ui',
87-
presets: [
88-
SwaggerUIBundle.presets.apis,
89-
SwaggerUIStandalonePreset
90-
],
91-
plugins: [
92-
SwaggerUIBundle.plugins.DownloadUrl
93-
],
94-
layout: "StandaloneLayout"
95-
})
84+
url: "http://petstore.swagger.io/v2/swagger.json",
85+
dom_id: '#swagger-ui',
86+
presets: [
87+
SwaggerUIBundle.presets.apis,
88+
SwaggerUIStandalonePreset
89+
],
90+
plugins: [
91+
SwaggerUIBundle.plugins.DownloadUrl
92+
],
93+
layout: "StandaloneLayout"
94+
})
9695
```
9796

9897
#### OAuth2 configuration
@@ -137,13 +136,16 @@ spec | A JSON object describing the OpenAPI Specification. When used, the `url`
137136
validatorUrl | By default, Swagger-UI attempts to validate specs against swagger.io's online validator. You can use this parameter to set a different validator URL, for example for locally deployed validators ([Validator Badge](https://github.com/swagger-api/validator-badge)). Setting it to `null` will disable validation.
138137
dom_id | The id of a dom element inside which SwaggerUi will put the user interface for swagger.
139138
oauth2RedirectUrl | OAuth redirect URL
139+
tagsSorter | Apply a sort to the tag list of each API. It can be 'alpha' (sort by paths alphanumerically) or a function (see [Array.prototype.sort()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort) to learn how to write a sort function). Two tag name strings are passed to the sorter for each pass. Default is the order determined by Swagger-UI.
140140
operationsSorter | Apply a sort to the operation list of each API. It can be 'alpha' (sort by paths alphanumerically), 'method' (sort by HTTP method) or a function (see Array.prototype.sort() to know how sort function works). Default is the order returned by the server unchanged.
141141
configUrl | Configs URL
142142
parameterMacro | MUST be a function. Function to set default value to parameters. Accepts two arguments parameterMacro(operation, parameter). Operation and parameter are objects passed for context, both remain immutable
143143
modelPropertyMacro | MUST be a function. Function to set default values to each property in model. Accepts one argument modelPropertyMacro(property), property is immutable
144144
docExpansion | Controls the default expansion setting for the operations and tags. It can be 'list' (expands only the tags), 'full' (expands the tags and operations) or 'none' (expands nothing). The default is 'list'.
145145
displayOperationId | Controls the display of operationId in operations list. The default is `false`.
146146
displayRequestDuration | Controls the display of the request duration (in milliseconds) for `Try it out` requests. The default is `false`.
147+
maxDisplayedTags | If set, limits the number of tagged operations displayed to at most this many. The default is to show all operations.
148+
filter | If set, enables filtering. The top bar will show an edit box that you can use to filter the tagged operations that are shown. Can be true/false to enable or disable, or an explicit filter string in which case filtering will be enabled using that string as the filter expression. Filtering is case sensitive matching the filter expression anywhere inside the tag.
147149

148150
### Plugins
149151

dev-helpers/index.html

+33-33
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,15 @@
1111
<style>
1212
html
1313
{
14-
box-sizing: border-box;
15-
overflow: -moz-scrollbars-vertical;
16-
overflow-y: scroll;
14+
box-sizing: border-box;
15+
overflow: -moz-scrollbars-vertical;
16+
overflow-y: scroll;
1717
}
1818
*,
1919
*:before,
2020
*:after
2121
{
22-
box-sizing: inherit;
22+
box-sizing: inherit;
2323
}
2424

2525
body {
@@ -34,7 +34,7 @@
3434
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="position:absolute;width:0;height:0">
3535
<defs>
3636
<symbol viewBox="0 0 20 20" id="unlocked">
37-
<path d="M15.8 8H14V5.6C14 2.703 12.665 1 10 1 7.334 1 6 2.703 6 5.6V6h2v-.801C8 3.754 8.797 3 10 3c1.203 0 2 .754 2 2.199V8H4c-.553 0-1 .646-1 1.199V17c0 .549.428 1.139.951 1.307l1.197.387C5.672 18.861 6.55 19 7.1 19h5.8c.549 0 1.428-.139 1.951-.307l1.196-.387c.524-.167.953-.757.953-1.306V9.199C17 8.646 16.352 8 15.8 8z"></path>
37+
<path d="M15.8 8H14V5.6C14 2.703 12.665 1 10 1 7.334 1 6 2.703 6 5.6V6h2v-.801C8 3.754 8.797 3 10 3c1.203 0 2 .754 2 2.199V8H4c-.553 0-1 .646-1 1.199V17c0 .549.428 1.139.951 1.307l1.197.387C5.672 18.861 6.55 19 7.1 19h5.8c.549 0 1.428-.139 1.951-.307l1.196-.387c.524-.167.953-.757.953-1.306V9.199C17 8.646 16.352 8 15.8 8z"></path>
3838
</symbol>
3939

4040
<symbol viewBox="0 0 20 20" id="locked">
@@ -70,34 +70,34 @@
7070
<script src="./swagger-ui-bundle.js"> </script>
7171
<script src="./swagger-ui-standalone-preset.js"> </script>
7272
<script>
73-
window.onload = function() {
74-
window["SwaggerUIBundle"] = window["swagger-ui-bundle"]
75-
window["SwaggerUIStandalonePreset"] = window["swagger-ui-standalone-preset"]
76-
// Build a system
77-
const ui = SwaggerUIBundle({
78-
url: "http://petstore.swagger.io/v2/swagger.json",
79-
dom_id: '#swagger-ui',
80-
presets: [
81-
SwaggerUIBundle.presets.apis,
82-
SwaggerUIStandalonePreset
83-
],
84-
plugins: [
85-
SwaggerUIBundle.plugins.DownloadUrl
86-
],
87-
layout: "StandaloneLayout"
88-
})
89-
90-
window.ui = ui
91-
92-
ui.initOAuth({
93-
clientId: "your-client-id",
94-
clientSecret: "your-client-secret-if-required",
95-
realm: "your-realms",
96-
appName: "your-app-name",
97-
scopeSeparator: " ",
98-
additionalQueryStringParams: {}
99-
})
100-
}
73+
window.onload = function() {
74+
window["SwaggerUIBundle"] = window["swagger-ui-bundle"]
75+
window["SwaggerUIStandalonePreset"] = window["swagger-ui-standalone-preset"]
76+
// Build a system
77+
const ui = SwaggerUIBundle({
78+
url: "http://petstore.swagger.io/v2/swagger.json",
79+
dom_id: '#swagger-ui',
80+
presets: [
81+
SwaggerUIBundle.presets.apis,
82+
SwaggerUIStandalonePreset
83+
],
84+
plugins: [
85+
SwaggerUIBundle.plugins.DownloadUrl
86+
],
87+
layout: "StandaloneLayout"
88+
})
89+
90+
window.ui = ui
91+
92+
ui.initOAuth({
93+
clientId: "your-client-id",
94+
clientSecret: "your-client-secret-if-required",
95+
realm: "your-realms",
96+
appName: "your-app-name",
97+
scopeSeparator: " ",
98+
additionalQueryStringParams: {}
99+
})
100+
}
101101
</script>
102102
</body>
103103

dist/swagger-ui-bundle.js

+8-8
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/swagger-ui-bundle.js.map

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/swagger-ui-standalone-preset.js

+3-3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/swagger-ui-standalone-preset.js.map

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/swagger-ui.css

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/swagger-ui.js

+2-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/swagger-ui.js.map

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/deep-linking.md

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# Deep linking
2+
3+
Swagger-UI allows you to deeply link into tags and operations within a spec. When Swagger-UI is provided a URL fragment at runtime, it will automatically expand and scroll to a specified tag or operation.
4+
5+
## Usage
6+
7+
👉🏼 Add `deepLinking: true` to your Swagger-UI configuration to enable this functionality.
8+
9+
When you expand a tag or operation, Swagger-UI will automatically update its URL fragment with a deep link to the item.
10+
Conversely, when you collapse a tag or operation, Swagger-UI will clear the URL fragment.
11+
12+
You can also right-click a tag name or operation path in order to copy a link to that tag or operation.
13+
14+
#### Fragment format
15+
16+
The fragment is formatted in one of two ways:
17+
18+
- `#/{tagName}`, to trigger the focus of a specific tag
19+
- `#/{tagName}/{operationId}`, to trigger the focus of a specific operation within a tag
20+
21+
`operationId` is the explicit operationId provided in the spec, if one exists.
22+
Otherwise, Swagger-UI generates an implicit operationId by combining the operation's path and method, and escaping non-alphanumeric characters.
23+
24+
## FAQ
25+
26+
> I'm using Swagger-UI in an application that needs control of the URL fragment. How do I disable deep-linking?
27+
28+
This functionality is disabled by default, but you can pass `deepLinking: false` into Swagger-UI as a configuration item to be sure.
29+
30+
> Can I link to multiple tags or operations?
31+
32+
No, this is not supported.
33+
34+
> Can I collapse everything except the operation or tag I'm linking to?
35+
36+
Sure - use `docExpansion: none` to collapse all tags and operations. Your deep link will take precedence over the setting, so only the tag or operation you've specified will be expanded.

make-webpack-config.js

+4-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ var webpack = require("webpack")
44
var ExtractTextPlugin = require("extract-text-webpack-plugin")
55
var deepExtend = require("deep-extend")
66
const {gitDescribeSync} = require("git-describe")
7+
const os = require("os")
78

89
var pkg = require("./package.json")
910

@@ -84,7 +85,9 @@ module.exports = function(rules, options) {
8485
"buildInfo": JSON.stringify({
8586
PACKAGE_VERSION: (pkg.version),
8687
GIT_COMMIT: gitInfo.hash,
87-
GIT_DIRTY: gitInfo.dirty
88+
GIT_DIRTY: gitInfo.dirty,
89+
HOSTNAME: os.hostname(),
90+
BUILD_TIME: new Date().toUTCString()
8891
})
8992
}))
9093

package.json

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "swagger-ui",
3-
"version": "3.0.18",
3+
"version": "3.0.19",
44
"main": "dist/swagger-ui.js",
55
"repository": "[email protected]:swagger-api/swagger-ui.git",
66
"contributors": [
@@ -68,9 +68,10 @@
6868
"redux-logger": "*",
6969
"reselect": "2.5.3",
7070
"sanitize-html": "^1.14.1",
71+
"scroll-to-element": "^2.0.0",
7172
"serialize-error": "2.0.0",
7273
"shallowequal": "0.2.2",
73-
"swagger-client": "3.0.17",
74+
"swagger-client": "3.0.18",
7475
"url-parse": "^1.1.8",
7576
"whatwg-fetch": "0.11.1",
7677
"worker-loader": "^0.7.1",

src/core/components/array-model.jsx

+6-3
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,19 @@ export default class ArrayModel extends Component {
1717
render(){
1818
let { getComponent, required, schema, depth, expandDepth } = this.props
1919
let items = schema.get("items")
20+
let title = schema.get("title") || name
2021
let properties = schema.filter( ( v, key) => ["type", "items", "$$ref"].indexOf(key) === -1 )
2122

2223
const ModelCollapse = getComponent("ModelCollapse")
2324
const Model = getComponent("Model")
2425

25-
return <span className="model">
26+
const titleEl = title &&
2627
<span className="model-title">
27-
<span className="model-title__text">{ schema.get("title") }</span>
28+
<span className="model-title__text">{ title }</span>
2829
</span>
29-
<ModelCollapse collapsed={ depth > expandDepth } collapsedContent="[...]">
30+
31+
return <span className="model">
32+
<ModelCollapse title={titleEl} collapsed={ depth > expandDepth } collapsedContent="[...]">
3033
[
3134
<span><Model { ...this.props } schema={ items } required={ false }/></span>
3235
]

src/core/components/layouts/base.jsx

+25-1
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,13 @@ export default class BaseLayout extends React.Component {
1313
getComponent: PropTypes.func.isRequired
1414
}
1515

16+
onFilterChange =(e) => {
17+
let {target: {value}} = e
18+
this.props.layoutActions.updateFilter(value)
19+
}
20+
1621
render() {
17-
let { specSelectors, specActions, getComponent } = this.props
22+
let { specSelectors, specActions, getComponent, layoutSelectors } = this.props
1823

1924
let info = specSelectors.info()
2025
let url = specSelectors.url()
@@ -31,6 +36,15 @@ export default class BaseLayout extends React.Component {
3136
let Row = getComponent("Row")
3237
let Col = getComponent("Col")
3338
let Errors = getComponent("errors", true)
39+
40+
let isLoading = specSelectors.loadingStatus() === "loading"
41+
let isFailed = specSelectors.loadingStatus() === "failed"
42+
let filter = layoutSelectors.currentFilter()
43+
44+
let inputStyle = {}
45+
if(isFailed) inputStyle.color = "red"
46+
if(isLoading) inputStyle.color = "#aaa"
47+
3448
const Schemes = getComponent("schemes")
3549

3650
const isSpecEmpty = !specSelectors.specStr()
@@ -57,13 +71,23 @@ export default class BaseLayout extends React.Component {
5771
{ schemes && schemes.size ? (
5872
<Schemes schemes={ schemes } specActions={ specActions } />
5973
) : null }
74+
6075
{ securityDefinitions ? (
6176
<AuthorizeBtn />
6277
) : null }
6378
</Col>
6479
</div>
6580
) : null }
6681

82+
{
83+
filter === null || filter === false ? null :
84+
<div className="filter-container">
85+
<Col className="filter wrapper" mobile={12}>
86+
<input className="operation-filter-input" placeholder="Filter by tag" type="text" onChange={this.onFilterChange} value={filter === true || filter === "true" ? "" : filter} disabled={isLoading} style={inputStyle} />
87+
</Col>
88+
</div>
89+
}
90+
6791
<Row>
6892
<Col mobile={12} desktop={12} >
6993
<Operations/>

src/core/components/model-collapse.jsx

+12-6
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,14 @@ export default class ModelCollapse extends Component {
55
static propTypes = {
66
collapsedContent: PropTypes.any,
77
collapsed: PropTypes.bool,
8-
children: PropTypes.any
8+
children: PropTypes.any,
9+
title: PropTypes.element
910
}
1011

1112
static defaultProps = {
1213
collapsedContent: "{...}",
1314
collapsed: true,
15+
title: null
1416
}
1517

1618
constructor(props, context) {
@@ -31,11 +33,15 @@ export default class ModelCollapse extends Component {
3133
}
3234

3335
render () {
34-
return (<span>
35-
<span onClick={ this.toggleCollapsed } style={{ "cursor": "pointer" }}>
36-
<span className={ "model-toggle" + ( this.state.collapsed ? " collapsed" : "" ) }></span>
36+
const {title} = this.props
37+
return (
38+
<span>
39+
{ title && <span onClick={this.toggleCollapsed} style={{ "cursor": "pointer" }}>{title}</span> }
40+
<span onClick={ this.toggleCollapsed } style={{ "cursor": "pointer" }}>
41+
<span className={ "model-toggle" + ( this.state.collapsed ? " collapsed" : "" ) }></span>
42+
</span>
43+
{ this.state.collapsed ? this.state.collapsedContent : this.props.children }
3744
</span>
38-
{ this.state.collapsed ? this.state.collapsedContent : this.props.children }
39-
</span>)
45+
)
4046
}
4147
}

src/core/components/models.jsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ export default class Models extends Component {
2828
<use xlinkHref="#large-arrow" />
2929
</svg>
3030
</h4>
31-
<Collapse isOpened={showModels} animated>
31+
<Collapse isOpened={showModels}>
3232
{
3333
definitions.entrySeq().map( ( [ name, model ])=>{
3434
return <div className="model-container" key={ `models-section-${name}` }>

src/core/components/object-model.jsx

+5-7
Original file line numberDiff line numberDiff line change
@@ -38,15 +38,13 @@ export default class ObjectModel extends Component {
3838
}
3939
</span>)
4040

41+
const titleEl = title && <span className="model-title">
42+
{ isRef && schema.get("$$ref") && <span className="model-hint">{ schema.get("$$ref") }</span> }
43+
<span className="model-title__text">{ title }</span>
44+
</span>
4145

4246
return <span className="model">
43-
{
44-
title && <span className="model-title">
45-
{ isRef && schema.get("$$ref") && <span className="model-hint">{ schema.get("$$ref") }</span> }
46-
<span className="model-title__text">{ title }</span>
47-
</span>
48-
}
49-
<ModelCollapse collapsed={ depth > expandDepth } collapsedContent={ collapsedContent }>
47+
<ModelCollapse title={titleEl} collapsed={ depth > expandDepth } collapsedContent={ collapsedContent }>
5048
<span className="brace-open object">{ braceOpen }</span>
5149
{
5250
!isRef ? null : <JumpToPathSection name={ name }/>

0 commit comments

Comments
 (0)