mirror of
				https://github.com/Redocly/redoc.git
				synced 2025-10-31 15:57:30 +03:00 
			
		
		
		
	Merge branch 'master' into releases
This commit is contained in:
		
						commit
						197c788a0c
					
				|  | @ -12,9 +12,11 @@ | |||
|         <input id="schema-url-input" value='http://rebilly.github.io/SwaggerTemplateRepo/swagger.yaml'> | ||||
|         <button type="submit"> Explore </button> | ||||
|       </form> | ||||
|       <iframe src="https://ghbtns.com/github-btn.html?user=Rebilly&repo=ReDoc&type=star&count=true&size=large" | ||||
|       frameborder="0" scrolling="0" width="130px" height="30px"></iframe> | ||||
|     </nav> | ||||
| 
 | ||||
|     <redoc scroll-y-offset="body > nav" spec-url='http://rebilly.github.io:80/SwaggerTemplateRepo/swagger.yaml'></redoc> | ||||
|     <redoc scroll-y-offset="body > nav" spec-url='http://rebilly.github.io/SwaggerTemplateRepo/swagger.yaml'></redoc> | ||||
| 
 | ||||
|     <!-- ReDoc built file with all dependencies included --> | ||||
|     <script src="main.js"> </script> | ||||
|  |  | |||
|  | @ -105,6 +105,13 @@ nav { | |||
|     box-sizing: border-box; | ||||
| } | ||||
| 
 | ||||
| nav iframe { | ||||
|   margin: 10px 0; | ||||
|   position: absolute; | ||||
|   right: 0; | ||||
|   top: 0; | ||||
| } | ||||
| 
 | ||||
| @media (min-width: 1000px) { | ||||
|     nav header { | ||||
|         position: absolute; | ||||
|  | @ -118,4 +125,8 @@ nav { | |||
|     nav header { | ||||
|         display: none; | ||||
|     } | ||||
| 
 | ||||
|     nav iframe { | ||||
|       display: none; | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -18,7 +18,7 @@ The information about API logo | |||
| | Field Name      |	Type	   | Description | | ||||
| | :-------------- | :------: | :---------- | | ||||
| | url             | string   | The URL pointing to the spec logo. MUST be in the format of a URL | ||||
| | backgroundColor | string   | background color to be used. MUST be in [CSS color syntax](https://developer.mozilla.org/en/docs/Web/CSS/color) | | ||||
| | backgroundColor | string   | background color to be used. MUST be RGB color in [hexadecimal format] (https://en.wikipedia.org/wiki/Web_colors#Hex_triplet) | ||||
| 
 | ||||
| 
 | ||||
| ###### x-logo example | ||||
|  | @ -30,7 +30,7 @@ json | |||
|     "title": "Swagger Petstore", | ||||
|     "x-logo": { | ||||
|       "url": "https://rebilly.github.io/ReDoc/petstore-logo.png", | ||||
|       "backgroundColor": "white" | ||||
|       "backgroundColor": "#FFFFFF" | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | @ -42,7 +42,7 @@ info: | |||
|   title: "Swagger Petstore" | ||||
|   x-logo: | ||||
|     url: "https://rebilly.github.io/ReDoc/petstore-logo.png" | ||||
|     backgroundColor: "white" | ||||
|     backgroundColor: "#FFFFFF" | ||||
| ``` | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										37
									
								
								lib/common/components/DropDown/dropdown.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								lib/common/components/DropDown/dropdown.js
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,37 @@ | |||
| 'use strict'; | ||||
| 
 | ||||
| import {Component, EventEmitter, ElementRef} from 'angular2/core'; | ||||
| import {CORE_DIRECTIVES} from 'angular2/common'; | ||||
| import DropKick from 'Robdel12/DropKick'; | ||||
| import 'Robdel12/DropKick/build/css/dropkick.css!css'; | ||||
| 
 | ||||
| @Component({ | ||||
|   selector: 'dropdown', | ||||
|   events: ['change'], | ||||
|   template: ` | ||||
|     <select (change)=onChange($event.target.value)> | ||||
|       <ng-content></ng-content> | ||||
|     </select> | ||||
|   `,
 | ||||
|   directives: [CORE_DIRECTIVES], | ||||
|   styleUrls: ['./lib/common/components/DropDown/dropdown.css'] | ||||
| }) | ||||
| @Reflect.metadata('parameters', [[ElementRef]]) | ||||
| export class DropDown { | ||||
|   constructor(elem) { | ||||
|     this.change = new EventEmitter(); | ||||
|     this.elem = elem.nativeElement; | ||||
|   } | ||||
| 
 | ||||
|   ngAfterContentInit() { | ||||
|     this.inst = new DropKick(this.elem.firstElementChild, {autoWidth: true}); | ||||
|   } | ||||
| 
 | ||||
|   onChange(value) { | ||||
|     this.change.next(value); | ||||
|   } | ||||
| 
 | ||||
|   destroy() { | ||||
|     this.inst.dispose(); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										70
									
								
								lib/common/components/DropDown/dropdown.scss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								lib/common/components/DropDown/dropdown.scss
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,70 @@ | |||
| @import '../../styles/variables'; | ||||
| 
 | ||||
| $silver: #666D71; | ||||
| $background-silver: #EEEFEF; | ||||
| $border: darken($background-silver, 2%); | ||||
| 
 | ||||
| :host { | ||||
|   .dk-select { | ||||
|     max-width: 100%; | ||||
|     font-family: $headers-font; | ||||
|   } | ||||
| 
 | ||||
|   .dk-selected:after { | ||||
|     display: none; | ||||
|   } | ||||
| 
 | ||||
|   // button | ||||
| 
 | ||||
|   .dk-selected { | ||||
|     color: $silver; | ||||
|     border-color: $silver; | ||||
|     padding: 0.4em 0.9em 0.4em 0.4em; | ||||
|     border-radius: 0.4rem; | ||||
|   } | ||||
| 
 | ||||
|   .dk-select-open-down .dk-selected { | ||||
|     border-radius: 0.4rem; | ||||
|   } | ||||
| 
 | ||||
|   .dk-select-open-down .dk-selected, .dk-selected:focus, .dk-selected:hover { | ||||
|     border-color: $primary-color; | ||||
|     color: $primary-color; | ||||
|   } | ||||
| 
 | ||||
|   // tick | ||||
|   .dk-selected:before { | ||||
|     border-top-color: $silver; | ||||
|     border-width: .35em .35em 0; | ||||
|   } | ||||
| 
 | ||||
|   .dk-select-open-down .dk-selected:before, | ||||
|   .dk-select-open-up .dk-selected:before { | ||||
|     border-bottom-color: $primary-color; | ||||
|     border-width: 0 .35em .35em; | ||||
|   } | ||||
| 
 | ||||
|   // items | ||||
|   .dk-select-multi:focus .dk-select-options, | ||||
|   .dk-select-open-down .dk-select-options, | ||||
|   .dk-select-open-up .dk-select-options { | ||||
|     border-color: $silver; | ||||
|   } | ||||
| 
 | ||||
|   .dk-select-options { | ||||
|     margin-top: 0.2em; | ||||
|     border-radius: 0.4em; | ||||
|   } | ||||
| 
 | ||||
|   .dk-option { | ||||
|     color: $black; | ||||
|     padding: 0.4em 0.4em; | ||||
|     &:hover { | ||||
|       background-color: $background-silver; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   .dk-option-selected { | ||||
|     background-color: $background-silver; | ||||
|   } | ||||
| } | ||||
|  | @ -14,7 +14,7 @@ var cache = {}; | |||
| 
 | ||||
| @Component({ | ||||
|   selector: 'json-schema-lazy', | ||||
|   inputs: ['pointer', 'auto'], | ||||
|   inputs: ['pointer', 'auto', 'skipReadOnly'], | ||||
|   template: '', | ||||
|   directives: [CORE_DIRECTIVES] | ||||
| }) | ||||
|  | @ -38,7 +38,7 @@ export default class JsonSchemaLazy { | |||
|     if (this.loaded) return; | ||||
|     if (this.pointer) { | ||||
|       this.dcl.loadNextToLocation(JsonSchema, this.elementRef).then((compRef) => { | ||||
|         compRef.instance.pointer = this.pointer; | ||||
|         this.initComponent(compRef); | ||||
|         // trigger change detection
 | ||||
|         compRef.hostView.changeDetectorRef.detectChanges(); | ||||
|       }); | ||||
|  | @ -58,7 +58,7 @@ export default class JsonSchemaLazy { | |||
|           // FIXME: get rid of dependency on selector
 | ||||
|           if ($element.querySelector('.discriminator-wrap')) { | ||||
|             this.dcl.loadNextToLocation(JsonSchema, this.elementRef).then((compRef) => { | ||||
|               compRef.instance.pointer = this.pointer; | ||||
|               this.initComponent(compRef); | ||||
|               compRef.hostView.changeDetectorRef.markForCheck(); | ||||
|             }); | ||||
|             return; | ||||
|  | @ -68,13 +68,18 @@ export default class JsonSchemaLazy { | |||
|       }); | ||||
|     } else { | ||||
|       cache[this.pointer] = this.dcl.loadNextToLocation(JsonSchema, this.elementRef).then((compRef) => { | ||||
|         compRef.instance.pointer = this.pointer; | ||||
|         this.initComponent(compRef); | ||||
|         compRef.hostView.changeDetectorRef.markForCheck(); | ||||
|         return compRef; | ||||
|       }); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   initComponent(compRef) { | ||||
|     compRef.instance.pointer = this.pointer; | ||||
|     compRef.instance.skipReadOnly = this.skipReadOnly; | ||||
|   } | ||||
| 
 | ||||
|   ngAfterViewInit() { | ||||
|     if (!this.auto) return; | ||||
|     this.loadCached(); | ||||
|  |  | |||
|  | @ -22,24 +22,24 @@ | |||
|           <span class="param-range" *ngIf="prop._range"> {{prop._range}} </span> | ||||
|           </span> | ||||
|           <span *ngIf="prop.required" class="param-required">Required</span> | ||||
|           <div *ngIf="prop.enum" class="param-enum"> | ||||
|           <div *ngIf="prop.enum && !prop.isDiscriminator" class="param-enum"> | ||||
|             <span *ngFor="#enumItem of prop.enum" class="enum-value {{enumItem.type}}"> {{enumItem.val | json}} </span> | ||||
|           </div> | ||||
|         </div> | ||||
|         <div class="param-description" innerHtml="{{prop.description | marked}}"></div> | ||||
|         <div class="discriminator-info" *ngIf="prop.isDiscriminator"> | ||||
|           <span>This field value determines the exact schema:</span> | ||||
|           <ul> | ||||
|             <li *ngFor="#derived of schema.derived" | ||||
|             (click)="selectDerived(derived)" [ngClass]="{active: derived.active}"> {{derived.name}} </li> | ||||
|           </ul> | ||||
|           <dropdown (change)="selectDerived($event)"> | ||||
|             <option *ngFor="#derived of schema.derived; #i=index" | ||||
|             [value]="i">{{derived.name}}</option> | ||||
|           </dropdown> | ||||
|         </div> | ||||
|       </td> | ||||
|     </tr> | ||||
|     <tr class="param-schema" [ngClass]="{'param-array': prop._isArray, 'last': last}" *ngIf="prop._pointer"> | ||||
|       <td colspan="2"> | ||||
|         <json-schema pointer="{{prop._pointer}}" [isArray]='prop._isArray' | ||||
|         class="nested-schema" [nestOdd]="!nestOdd" [attr.nesteven]="!nestOdd"> | ||||
|         <json-schema class="nested-schema" pointer="{{prop._pointer}}" [isArray]='prop._isArray' | ||||
|         [nestOdd]="!nestOdd" [skipReadOnly]="skipReadOnly" [attr.nesteven]="!nestOdd"> | ||||
|         </json-schema> | ||||
|       </td> | ||||
|     </tr> | ||||
|  | @ -47,7 +47,8 @@ | |||
|   <tr *ngIf="schema.derived.length" class="param-wrap discriminator-wrap" [ngClass]="{'empty': derivedEmtpy}"> | ||||
|     <td colspan="2"> | ||||
|       <div class="derived-schema" *ngFor="#derived of schema.derived" [ngClass]="{active: derived.active}"> | ||||
|         <json-schema *ngIf="!derived.empty" [childFor]="pointer" pointer="{{derived.$ref}}" [final]="derived.final" class="discriminator-part"> | ||||
|         <json-schema class="discriminator-part" *ngIf="!derived.empty" [childFor]="pointer" | ||||
|         pointer="{{derived.$ref}}" [final]="derived.final" [skipReadOnly]="skipReadOnly"> | ||||
|         </json-schema> | ||||
|       </div> | ||||
|     </td> | ||||
|  |  | |||
|  | @ -3,15 +3,15 @@ | |||
| import {ElementRef} from 'angular2/core'; | ||||
| 
 | ||||
| import {RedocComponent, BaseComponent, SchemaManager} from '../base'; | ||||
| import {Tabs, Tab} from '../../common/components/Tabs/tabs'; | ||||
| import {DropDown} from '../../common/components/DropDown/dropdown'; | ||||
| import JsonPointer from '../../utils/JsonPointer'; | ||||
| 
 | ||||
| @RedocComponent({ | ||||
|   selector: 'json-schema', | ||||
|   templateUrl: './lib/components/JsonSchema/json-schema.html', | ||||
|   styleUrls: ['./lib/components/JsonSchema/json-schema.css'], | ||||
|   directives: [JsonSchema, Tabs, Tab], | ||||
|   inputs: ['isArray', 'final', 'nestOdd', 'childFor'] | ||||
|   directives: [JsonSchema, DropDown], | ||||
|   inputs: ['isArray', 'final', 'nestOdd', 'childFor', 'skipReadOnly'] | ||||
| }) | ||||
| @Reflect.metadata('parameters', [[SchemaManager], [ElementRef]]) | ||||
| export default class JsonSchema extends BaseComponent { | ||||
|  | @ -21,8 +21,9 @@ export default class JsonSchema extends BaseComponent { | |||
|     this.final = false; | ||||
|   } | ||||
| 
 | ||||
|   selectDerived(subClass) { | ||||
|     if (subClass.active) return; | ||||
|   selectDerived(subClassIdx) { | ||||
|     let subClass = this.schema.derived[subClassIdx]; | ||||
|     if (!subClass || subClass.active) return; | ||||
|     this.schema.derived.forEach((subSchema) => { | ||||
|       subSchema.active = false; | ||||
|     }); | ||||
|  | @ -62,7 +63,23 @@ export default class JsonSchema extends BaseComponent { | |||
|     } | ||||
| 
 | ||||
|     this.schema = schema; | ||||
|     if (schema.derived.length) this.selectDerived(schema.derived[0]); | ||||
|     this.initDerived(); | ||||
|   } | ||||
| 
 | ||||
|   initDerived() { | ||||
|     if (!this.schema.derived.length) return; | ||||
|     let enumArr = this.schema.properties[this.schema.properties.length - 1].enum; | ||||
|     if (enumArr) { | ||||
|       let enumOrder = {}; | ||||
|       enumArr.forEach((enumItem, idx) => { | ||||
|         enumOrder[enumItem.val] = idx; | ||||
|       }); | ||||
| 
 | ||||
|       this.schema.derived.sort((a, b) => { | ||||
|         return enumOrder[a.name] > enumOrder[b.name]; | ||||
|       }); | ||||
|     } | ||||
|     this.selectDerived(0); | ||||
|   } | ||||
| 
 | ||||
|   prepareObjectPropertiesData(schema) { | ||||
|  | @ -74,7 +91,8 @@ export default class JsonSchema extends BaseComponent { | |||
|     let discriminatorFieldIdx = -1; | ||||
|     let props = Object.keys(schema.properties).map((prop, idx) => { | ||||
|       let propertySchema = schema.properties[prop]; | ||||
|       let propPointer = JsonPointer.join(schema._pointer || this.pointer, ['properties', prop]); | ||||
|       let propPointer = propertySchema._pointer || | ||||
|         JsonPointer.join(schema._pointer || this.pointer, ['properties', prop]); | ||||
|       propertySchema = JsonSchema.injectPropertyData(propertySchema, prop, propPointer); | ||||
|       // stop endless discriminator recursion
 | ||||
|       if (propertySchema._pointer === this.childFor) { | ||||
|  | @ -84,10 +102,12 @@ export default class JsonSchema extends BaseComponent { | |||
|       propertySchema.isDiscriminator = (schema.discriminator === prop); | ||||
|       if (propertySchema.isDiscriminator) { | ||||
|         discriminatorFieldIdx = idx; | ||||
|         propertySchema.enum = null; | ||||
|       } | ||||
|       return propertySchema; | ||||
|     }); | ||||
|     if (this.skipReadOnly) { | ||||
|       props = props.filter(prop => !prop.readOnly); | ||||
|     } | ||||
|     // Move discriminator field to the end of properties list
 | ||||
|     if (discriminatorFieldIdx > -1) { | ||||
|       let discrProp = props.splice(discriminatorFieldIdx, 1); | ||||
|  | @ -205,5 +225,22 @@ const injectors = { | |||
|         injectTo._range = range; | ||||
|       } | ||||
|     } | ||||
|   }, | ||||
|   string: { | ||||
|     check: propertySchema => (propertySchema.type === 'string'), | ||||
|     inject: (injectTo, propertySchema = injectTo) => { | ||||
|       var range; | ||||
|       if (propertySchema.minLength && propertySchema.maxLength) { | ||||
|         range = `[ ${propertySchema.minLength} .. ${propertySchema.maxLength} ]`; | ||||
|       } else if (propertySchema.maxLength) { | ||||
|         range = '<= ' + propertySchema.maxLength; | ||||
|       } else if (propertySchema.minimum) { | ||||
|         range = '>= ' + propertySchema.minLength; | ||||
|       } | ||||
| 
 | ||||
|       if (range) { | ||||
|         injectTo._range = range + ' characters'; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| }; | ||||
|  |  | |||
|  | @ -31,7 +31,7 @@ | |||
|   <div class="body-param-description" innerHtml="{{data.bodyParam.description | marked}}"></div> | ||||
|   <div> | ||||
|     <br> | ||||
|     <json-schema-lazy [auto]="true" pointer="{{data.bodyParam.pointer}}/schema"> | ||||
|     <json-schema-lazy [skipReadOnly]="true" [auto]="true" pointer="{{data.bodyParam.pointer}}/schema"> | ||||
|     </json-schema-lazy> | ||||
|   </div> | ||||
| </div> | ||||
|  |  | |||
|  | @ -192,12 +192,19 @@ export class BaseComponent { | |||
|         if (into.type === 'object' && subSchema.properties) { | ||||
|           into.properties || (into.properties = {}); | ||||
|           Object.assign(into.properties, subSchema.properties); | ||||
|           Object.keys(subSchema.properties).forEach(propName => { | ||||
|             if (!subSchema.properties[propName]._pointer) { | ||||
|               subSchema.properties[propName]._pointer = subSchema._pointer ? | ||||
|                 JsonPointer.join(subSchema._pointer, ['properties', propName]) : null; | ||||
|             } | ||||
|           }); | ||||
|         } | ||||
|         if (into.type === 'object' && subSchema.required) { | ||||
|           into.required || (into.required = []); | ||||
|           into.required.push(...subSchema.required); | ||||
|         } | ||||
| 
 | ||||
|         // don't merge _pointer
 | ||||
|         subSchema._pointer = null; | ||||
|         defaults(into, subSchema); | ||||
|       } | ||||
|       into.allOf = null; | ||||
|  |  | |||
|  | @ -1,7 +1,7 @@ | |||
| { | ||||
|   "name": "redoc", | ||||
|   "description": "Swagger-generated API Reference Documentation", | ||||
|   "version": "0.7.12", | ||||
|   "version": "0.7.13", | ||||
|   "repository": { | ||||
|     "type": "git", | ||||
|     "url": "git://github.com/Rebilly/ReDoc" | ||||
|  | @ -33,6 +33,7 @@ | |||
|   "jspm": { | ||||
|     "configFile": "system.config.js", | ||||
|     "dependencies": { | ||||
|       "Robdel12/DropKick": "github:Robdel12/DropKick@^2.1.7", | ||||
|       "angular2": "npm:angular2@^2.0.0-beta.12", | ||||
|       "es6-shim": "github:es-shims/es6-shim@^0.33.6", | ||||
|       "hint.css": "npm:hint.css@^2.2.1", | ||||
|  | @ -53,6 +54,11 @@ | |||
|       "core-js": "npm:core-js@^1.2.6", | ||||
|       "css": "github:systemjs/plugin-css@^0.1.18", | ||||
|       "systemjs/plugin-json": "github:systemjs/plugin-json@^0.1.0" | ||||
|     }, | ||||
|     "overrides": { | ||||
|       "github:Robdel12/DropKick@2.1.7": { | ||||
|         "format": "global" | ||||
|       } | ||||
|     } | ||||
|   }, | ||||
|   "devDependencies": { | ||||
|  |  | |||
|  | @ -37,6 +37,7 @@ System.config({ | |||
|   }, | ||||
| 
 | ||||
|   map: { | ||||
|     "Robdel12/DropKick": "github:Robdel12/DropKick@2.1.7", | ||||
|     "angular2": "npm:angular2@2.0.0-beta.12", | ||||
|     "babel": "npm:babel-core@5.8.34", | ||||
|     "babel-runtime": "npm:babel-runtime@5.8.34", | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	Block a user