mirror of
https://github.com/Redocly/redoc.git
synced 2024-11-26 18:43:43 +03:00
Refactor + minor fixes/optimizations
This commit is contained in:
parent
76035c84d7
commit
17e7bf9fd8
|
@ -11,7 +11,7 @@ import {
|
||||||
} from '@angular/core/testing';
|
} from '@angular/core/testing';
|
||||||
|
|
||||||
import { ApiInfo } from './api-info';
|
import { ApiInfo } from './api-info';
|
||||||
import { SpecManager } from '../../utils/SpecManager';
|
import { SpecManager } from '../../utils/spec-manager';
|
||||||
|
|
||||||
describe('Redoc components', () => {
|
describe('Redoc components', () => {
|
||||||
describe('ApiInfo Component', () => {
|
describe('ApiInfo Component', () => {
|
||||||
|
|
|
@ -12,7 +12,7 @@ import { OptionsService, MenuService } from '../../services/index';
|
||||||
export class ApiInfo extends BaseComponent implements OnInit {
|
export class ApiInfo extends BaseComponent implements OnInit {
|
||||||
info: any = {};
|
info: any = {};
|
||||||
specUrl: String;
|
specUrl: String;
|
||||||
constructor(specMgr:SpecManager, private optionsService:OptionsService, private menuServ: MenuService) {
|
constructor(specMgr:SpecManager, private optionsService: OptionsService) {
|
||||||
super(specMgr);
|
super(specMgr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ import {
|
||||||
} from '@angular/core/testing';
|
} from '@angular/core/testing';
|
||||||
|
|
||||||
import { ApiLogo } from './api-logo';
|
import { ApiLogo } from './api-logo';
|
||||||
import { SpecManager } from '../../utils/SpecManager';
|
import { SpecManager } from '../../utils/spec-manager';
|
||||||
|
|
||||||
|
|
||||||
describe('Redoc components', () => {
|
describe('Redoc components', () => {
|
||||||
|
|
|
@ -5,7 +5,7 @@ import { Component, ElementRef, ViewContainerRef, OnDestroy, Input,
|
||||||
|
|
||||||
import { JsonSchema } from './json-schema';
|
import { JsonSchema } from './json-schema';
|
||||||
import { OptionsService } from '../../services/options.service';
|
import { OptionsService } from '../../services/options.service';
|
||||||
import { SpecManager } from '../../utils/SpecManager';
|
import { SpecManager } from '../../utils/spec-manager';
|
||||||
|
|
||||||
var cache = {};
|
var cache = {};
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ export class JsonSchemaLazy implements OnDestroy, AfterViewInit {
|
||||||
var componentFactory = this.resolver.resolveComponentFactory(JsonSchema);
|
var componentFactory = this.resolver.resolveComponentFactory(JsonSchema);
|
||||||
let contextInjector = this.location.parentInjector;
|
let contextInjector = this.location.parentInjector;
|
||||||
let compRef = this.location.createComponent(componentFactory, null, contextInjector, null);
|
let compRef = this.location.createComponent(componentFactory, null, contextInjector, null);
|
||||||
this.initComponent(compRef.instance);
|
this.projectComponentInputs(compRef.instance);
|
||||||
this._renderer.setElementAttribute(compRef.location.nativeElement, 'class', this.location.element.nativeElement.className);
|
this._renderer.setElementAttribute(compRef.location.nativeElement, 'class', this.location.element.nativeElement.className);
|
||||||
compRef.changeDetectorRef.detectChanges();
|
compRef.changeDetectorRef.detectChanges();
|
||||||
this.loaded = true;
|
this.loaded = true;
|
||||||
|
@ -58,7 +58,6 @@ export class JsonSchemaLazy implements OnDestroy, AfterViewInit {
|
||||||
this.pointer = this.normalizePointer();
|
this.pointer = this.normalizePointer();
|
||||||
if (cache[this.pointer]) {
|
if (cache[this.pointer]) {
|
||||||
let compRef = cache[this.pointer];
|
let compRef = cache[this.pointer];
|
||||||
setTimeout( ()=> {
|
|
||||||
let $element = compRef.location.nativeElement;
|
let $element = compRef.location.nativeElement;
|
||||||
|
|
||||||
// skip caching view with descendant schemas
|
// skip caching view with descendant schemas
|
||||||
|
@ -69,13 +68,12 @@ export class JsonSchemaLazy implements OnDestroy, AfterViewInit {
|
||||||
}
|
}
|
||||||
insertAfter($element.cloneNode(true), this.elementRef.nativeElement);
|
insertAfter($element.cloneNode(true), this.elementRef.nativeElement);
|
||||||
this.loaded = true;
|
this.loaded = true;
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
cache[this.pointer] = this._loadAfterSelf();
|
cache[this.pointer] = this._loadAfterSelf();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
initComponent(instance:JsonSchema) {
|
projectComponentInputs(instance:JsonSchema) {
|
||||||
Object.assign(instance, this);
|
Object.assign(instance, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ import { getChildDebugElement } from '../../../tests/helpers';
|
||||||
|
|
||||||
|
|
||||||
import { JsonSchema } from './json-schema';
|
import { JsonSchema } from './json-schema';
|
||||||
import { SpecManager } from '../../utils/SpecManager';;
|
import { SpecManager } from '../../utils/spec-manager';;
|
||||||
|
|
||||||
describe('Redoc components', () => {
|
describe('Redoc components', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
|
|
@ -10,7 +10,7 @@ import {
|
||||||
import { getChildDebugElement } from '../../../tests/helpers';
|
import { getChildDebugElement } from '../../../tests/helpers';
|
||||||
|
|
||||||
import { Method } from './method';
|
import { Method } from './method';
|
||||||
import { SpecManager } from '../../utils/SpecManager';;
|
import { SpecManager } from '../../utils/spec-manager';;
|
||||||
|
|
||||||
describe('Redoc components', () => {
|
describe('Redoc components', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
|
|
@ -11,7 +11,7 @@ import { getChildDebugElement } from '../../../tests/helpers';
|
||||||
|
|
||||||
|
|
||||||
import { MethodsList } from './methods-list';
|
import { MethodsList } from './methods-list';
|
||||||
import { SpecManager } from '../../utils/SpecManager';
|
import { SpecManager } from '../../utils/spec-manager';
|
||||||
|
|
||||||
describe('Redoc components', () => {
|
describe('Redoc components', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
|
|
@ -1,4 +1,8 @@
|
||||||
<div class="redoc-wrap" *ngIf="specLoaded">
|
<div class="redoc-error" *ngIf="error">
|
||||||
|
<h1>Oops... ReDoc failed to render this spec</h1>
|
||||||
|
<div class='redoc-error-details'>{{_error.message}}</div>
|
||||||
|
</div>
|
||||||
|
<div class="redoc-wrap" *ngIf="specLoaded && !error">
|
||||||
<div class="menu-content" sticky-sidebar [scrollParent]="options.$scrollParent" [scrollYOffset]="options.scrollYOffset">
|
<div class="menu-content" sticky-sidebar [scrollParent]="options.$scrollParent" [scrollYOffset]="options.scrollYOffset">
|
||||||
<api-logo> </api-logo>
|
<api-logo> </api-logo>
|
||||||
<side-menu> </side-menu>
|
<side-menu> </side-menu>
|
||||||
|
|
|
@ -11,7 +11,7 @@ import {
|
||||||
import { TestBed } from '@angular/core/testing';
|
import { TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
import { Redoc } from './redoc';
|
import { Redoc } from './redoc';
|
||||||
import { SpecManager } from '../../utils/SpecManager';
|
import { SpecManager } from '../../utils/spec-manager';
|
||||||
import { OptionsService } from '../../services/index';
|
import { OptionsService } from '../../services/index';
|
||||||
|
|
||||||
let optsMgr:OptionsService;
|
let optsMgr:OptionsService;
|
||||||
|
@ -46,123 +46,6 @@ describe('Redoc components', () => {
|
||||||
fixture.destroy();
|
fixture.destroy();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// describe('Redoc init', () => {
|
|
||||||
// let dom = new BrowserDomAdapter();
|
|
||||||
// let elem;
|
|
||||||
// beforeEach(() => {
|
|
||||||
// elem = dom.createElement('redoc');
|
|
||||||
// dom.defaultDoc().body.appendChild(elem);
|
|
||||||
// });
|
|
||||||
//
|
|
||||||
// afterEach(() => {
|
|
||||||
// dom.defaultDoc().body.removeChild(elem);
|
|
||||||
// });
|
|
||||||
//
|
|
||||||
// it('should return promise', () => {
|
|
||||||
// let res = Redoc.init().catch(() => {/**/});
|
|
||||||
// res.should.be.instanceof(Promise);
|
|
||||||
// });
|
|
||||||
//
|
|
||||||
// it('should hide loading animation and display message in case of error', async(() => {
|
|
||||||
// spyOn(Redoc, 'hideLoadingAnimation').and.callThrough();
|
|
||||||
// spyOn(Redoc, 'displayError').and.callThrough();
|
|
||||||
// let res = Redoc.init();
|
|
||||||
// return res.catch(() => {
|
|
||||||
// expect(Redoc.hideLoadingAnimation).toHaveBeenCalled();
|
|
||||||
// expect(Redoc.displayError).toHaveBeenCalled();
|
|
||||||
// });
|
|
||||||
// }));
|
|
||||||
//
|
|
||||||
// //skip because of PhantomJS crashes on this testcase
|
|
||||||
// xit('should init redoc', (done) => {
|
|
||||||
// var node = document.createElement('redoc');
|
|
||||||
// document.body.appendChild(node);
|
|
||||||
// let res = Redoc.init('/tests/schemas/extended-petstore.yml');
|
|
||||||
// res.then(() => { done(); }, () => {
|
|
||||||
// done.fail('Error handler should not been called');
|
|
||||||
// });
|
|
||||||
// });
|
|
||||||
// });
|
|
||||||
//
|
|
||||||
// describe('Redoc destroy', () => {
|
|
||||||
// let builder;
|
|
||||||
// let fixture;
|
|
||||||
// let element;
|
|
||||||
// let dom;
|
|
||||||
// let destroySpy;
|
|
||||||
//
|
|
||||||
// beforeEach(async(inject([SpecManager, OptionsService, BrowserDomAdapter],
|
|
||||||
// ( specMgr, opts, _dom) => {
|
|
||||||
//
|
|
||||||
// optsMgr = opts;
|
|
||||||
// dom = _dom;
|
|
||||||
// return specMgr.load('/tests/schemas/extended-petstore.yml');
|
|
||||||
// })));
|
|
||||||
//
|
|
||||||
// beforeEach(() => {
|
|
||||||
// fixture = TestBed.createComponent(TestAppComponent);
|
|
||||||
// element = getChildDebugElement(fixture.debugElement, 'methods-list').nativeElement;
|
|
||||||
// destroySpy = jasmine.createSpy('spy');
|
|
||||||
// Redoc.appRef = <ComponentRef<any>>{
|
|
||||||
// destroy: destroySpy
|
|
||||||
// };
|
|
||||||
// fixture.detectChanges();
|
|
||||||
// });
|
|
||||||
//
|
|
||||||
// afterEach(()=> {
|
|
||||||
// fixture.destroy();
|
|
||||||
// Redoc.appRef = null;
|
|
||||||
// });
|
|
||||||
//
|
|
||||||
// it('should call componentRef.destroy', () => {
|
|
||||||
// Redoc.destroy();
|
|
||||||
// expect(destroySpy).toHaveBeenCalled();
|
|
||||||
// });
|
|
||||||
//
|
|
||||||
// it('should create new host element', () => {
|
|
||||||
// element.parentElement.removeChild(element);
|
|
||||||
// Redoc.destroy();
|
|
||||||
// expect(dom.query('redoc')).not.toBeNull();
|
|
||||||
// dom.query('redoc').should.not.be.equal(element);
|
|
||||||
// });
|
|
||||||
//
|
|
||||||
// it('should set to null appRef', () => {
|
|
||||||
// Redoc.destroy();
|
|
||||||
// expect(Redoc.appRef).toBeNull();
|
|
||||||
// });
|
|
||||||
// });
|
|
||||||
//
|
|
||||||
// describe('Redoc autoInit', () => {
|
|
||||||
// const testURL = 'testurl';
|
|
||||||
// let dom = new BrowserDomAdapter();
|
|
||||||
// //let redocInitSpy;
|
|
||||||
// let elem: HTMLElement;
|
|
||||||
//
|
|
||||||
// beforeEach(() => {
|
|
||||||
// spyOn(Redoc, 'init').and.stub();
|
|
||||||
// elem = dom.createElement('redoc');
|
|
||||||
// dom.defaultDoc().body.appendChild(elem);
|
|
||||||
// dom.setAttribute(elem, 'spec-url', testURL);
|
|
||||||
// });
|
|
||||||
//
|
|
||||||
// it('should call Redoc.init with url from param spec-url', () => {
|
|
||||||
// Redoc.autoInit();
|
|
||||||
// expect(Redoc.init).toHaveBeenCalled();
|
|
||||||
// expect((<jasmine.Spy>Redoc.init).calls.argsFor(0)).toEqual([testURL]);
|
|
||||||
// });
|
|
||||||
//
|
|
||||||
// it('should not call Redoc.init when spec-url param is not provided', () => {
|
|
||||||
// dom.removeAttribute(elem, 'spec-url');
|
|
||||||
// Redoc.autoInit();
|
|
||||||
// expect(Redoc.init).not.toHaveBeenCalled();
|
|
||||||
// });
|
|
||||||
//
|
|
||||||
// afterEach(() => {
|
|
||||||
// (<jasmine.Spy>Redoc.init).and.callThrough();
|
|
||||||
// dom.defaultDoc().body.removeChild(elem);
|
|
||||||
// });
|
|
||||||
// });
|
|
||||||
});
|
});
|
||||||
|
|
||||||
/** Test component that contains a Redoc. */
|
/** Test component that contains a Redoc. */
|
||||||
|
|
|
@ -1,15 +1,23 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import { ElementRef, ComponentRef, ChangeDetectorRef, Input,
|
import { ElementRef,
|
||||||
Component, OnInit, ChangeDetectionStrategy} from '@angular/core';
|
ComponentRef,
|
||||||
|
ChangeDetectorRef,
|
||||||
|
Input,
|
||||||
|
Component,
|
||||||
|
OnInit,
|
||||||
|
ChangeDetectionStrategy,
|
||||||
|
HostBinding
|
||||||
|
} from '@angular/core';
|
||||||
|
|
||||||
import { BrowserDomAdapter as DOM } from '../../utils/browser-adapter';
|
import { BrowserDomAdapter as DOM } from '../../utils/browser-adapter';
|
||||||
import { BaseComponent } from '../base';
|
import { BaseComponent } from '../base';
|
||||||
|
|
||||||
import * as detectScollParent from 'scrollparent';
|
import * as detectScollParent from 'scrollparent';
|
||||||
|
|
||||||
import { SpecManager } from '../../utils/SpecManager';
|
import { SpecManager } from '../../utils/spec-manager';
|
||||||
import { OptionsService, RedocEventsService } from '../../services/index';
|
import { OptionsService, Hash, MenuService, AppStateService } from '../../services/index';
|
||||||
|
import { CustomErrorHandler } from '../../utils/';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'redoc',
|
selector: 'redoc',
|
||||||
|
@ -18,45 +26,29 @@ import { OptionsService, RedocEventsService } from '../../services/index';
|
||||||
changeDetection: ChangeDetectionStrategy.OnPush
|
changeDetection: ChangeDetectionStrategy.OnPush
|
||||||
})
|
})
|
||||||
export class Redoc extends BaseComponent implements OnInit {
|
export class Redoc extends BaseComponent implements OnInit {
|
||||||
static appRef: ComponentRef<any>;
|
|
||||||
static _preOptions: any;
|
static _preOptions: any;
|
||||||
specLoaded: boolean;
|
|
||||||
|
|
||||||
public options: any;
|
|
||||||
|
|
||||||
private element: any;
|
private element: any;
|
||||||
|
|
||||||
|
error: any;
|
||||||
|
specLoaded: boolean;
|
||||||
|
options: any;
|
||||||
|
|
||||||
@Input() specUrl: string;
|
@Input() specUrl: string;
|
||||||
|
@HostBinding('class.loading') specLoading: boolean = false;
|
||||||
|
@HostBinding('class.loading-remove') specLoadingRemove: boolean = false;
|
||||||
|
|
||||||
// TODO: refactor in separate component/service
|
constructor(
|
||||||
showLoadingAnimation() {
|
specMgr: SpecManager,
|
||||||
DOM.addClass(this.element, 'loading');
|
optionsMgr: OptionsService,
|
||||||
}
|
elementRef: ElementRef,
|
||||||
|
private changeDetector: ChangeDetectorRef,
|
||||||
hideLoadingAnimation() {
|
private appState: AppStateService
|
||||||
DOM.addClass(this.element, 'loading-remove');
|
) {
|
||||||
setTimeout(() => {
|
|
||||||
DOM.removeClass(this.element, 'loading-remove');
|
|
||||||
DOM.removeClass(this.element, 'loading');
|
|
||||||
}, 400);
|
|
||||||
}
|
|
||||||
|
|
||||||
static displayError(err, elem?) {
|
|
||||||
let redocEl = elem || DOM.query('redoc');
|
|
||||||
if (!redocEl) return;
|
|
||||||
let heading = 'Oops... ReDoc failed to render this spec';
|
|
||||||
let details = err.message;
|
|
||||||
let erroHtml = `<div class="redoc-error">
|
|
||||||
<h1>${heading}</h1>
|
|
||||||
<div class='redoc-error-details'>${details}</div>`;
|
|
||||||
redocEl.innerHTML = erroHtml;
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor(specMgr: SpecManager, optionsMgr:OptionsService, elementRef:ElementRef,
|
|
||||||
public events:RedocEventsService, private changeDetector: ChangeDetectorRef) {
|
|
||||||
super(specMgr);
|
super(specMgr);
|
||||||
// merge options passed before init
|
// merge options passed before init
|
||||||
optionsMgr.options = Redoc._preOptions || {};
|
optionsMgr.options = Redoc._preOptions || {};
|
||||||
|
|
||||||
this.element = elementRef.nativeElement;
|
this.element = elementRef.nativeElement;
|
||||||
//parse options (top level component doesn't support inputs)
|
//parse options (top level component doesn't support inputs)
|
||||||
optionsMgr.parseOptions( this.element );
|
optionsMgr.parseOptions( this.element );
|
||||||
|
@ -66,22 +58,34 @@ export class Redoc extends BaseComponent implements OnInit {
|
||||||
this.options = optionsMgr.options;
|
this.options = optionsMgr.options;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hideLoadingAnimation() {
|
||||||
|
this.specLoadingRemove = true;
|
||||||
|
setTimeout(() => {
|
||||||
|
this.specLoadingRemove = true;
|
||||||
|
this.specLoading = false;
|
||||||
|
}, 400);
|
||||||
|
}
|
||||||
|
|
||||||
load() {
|
load() {
|
||||||
this.showLoadingAnimation();
|
this.specMgr.load(this.options.specUrl);
|
||||||
SpecManager.instance().load(this.options.specUrl).then(() => {
|
this.specMgr.spec.subscribe((spec) => {
|
||||||
|
if (!spec) {
|
||||||
|
this.specLoading = true;
|
||||||
|
this.specLoaded = false;
|
||||||
|
} else {
|
||||||
this.specLoaded = true;
|
this.specLoaded = true;
|
||||||
|
this.hideLoadingAnimation();
|
||||||
this.changeDetector.markForCheck();
|
this.changeDetector.markForCheck();
|
||||||
//this.changeDetector.detectChanges();
|
}
|
||||||
this.events.bootstrapped.next({});
|
});
|
||||||
this.hideLoadingAnimation();
|
|
||||||
}).catch((err) => {
|
|
||||||
this.hideLoadingAnimation();
|
|
||||||
Redoc.displayError(err, this.element);
|
|
||||||
throw err;
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
|
this.appState.error.subscribe(_err => {
|
||||||
|
this.error = _err;
|
||||||
|
this.changeDetector.detectChanges();
|
||||||
|
})
|
||||||
|
|
||||||
if (this.specUrl) {
|
if (this.specUrl) {
|
||||||
this.options.specUrl = this.specUrl;
|
this.options.specUrl = this.specUrl;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,14 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import { Component, ViewChildren, QueryList, EventEmitter, Input,
|
import { Component, ViewChildren, QueryList, Input,
|
||||||
ChangeDetectionStrategy, OnInit, HostBinding } from '@angular/core';
|
ChangeDetectionStrategy, OnInit, HostBinding } from '@angular/core';
|
||||||
|
|
||||||
|
import { Subject } from 'rxjs/Subject';
|
||||||
|
|
||||||
import { BaseComponent, SpecManager } from '../base';
|
import { BaseComponent, SpecManager } from '../base';
|
||||||
import JsonPointer from '../../utils/JsonPointer';
|
import JsonPointer from '../../utils/JsonPointer';
|
||||||
import { Tabs } from '../../shared/components/index';
|
import { Tabs } from '../../shared/components/index';
|
||||||
import { RedocEventsService } from '../../services/index';
|
import { AppStateService } from '../../services/index';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'request-samples',
|
selector: 'request-samples',
|
||||||
|
@ -21,18 +23,17 @@ export class RequestSamples extends BaseComponent implements OnInit {
|
||||||
@HostBinding('attr.hidden') hidden;
|
@HostBinding('attr.hidden') hidden;
|
||||||
|
|
||||||
childTabs: Tabs;
|
childTabs: Tabs;
|
||||||
selectedLang: EventEmitter<any>;
|
selectedLang: Subject<any>;
|
||||||
samples: Array<any>;
|
samples: Array<any>;
|
||||||
|
|
||||||
constructor(specMgr:SpecManager, public events:RedocEventsService) {
|
constructor(specMgr:SpecManager, public appState:AppStateService) {
|
||||||
super(specMgr);
|
super(specMgr);
|
||||||
|
|
||||||
this.selectedLang = this.events.samplesLanguageChanged;
|
this.selectedLang = this.appState.samplesLanguage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
changeLangNotify(lang) {
|
changeLangNotify(lang) {
|
||||||
this.events.samplesLanguageChanged.next(lang);
|
this.selectedLang.next(lang);
|
||||||
}
|
}
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
<h1> Hello world </h1>
|
||||||
|
<h2> {{message}} {{pointer}} </h2>
|
28
lib/components/SecurityDefinitions/security-definitions.scss
Normal file
28
lib/components/SecurityDefinitions/security-definitions.scss
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
@import '../../shared/styles/variables';
|
||||||
|
|
||||||
|
.api-info-header {
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
:host > div {
|
||||||
|
width: 60%;
|
||||||
|
padding: 40px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
|
||||||
|
@media (max-width: $right-panel-squash-breakpoint) {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
a.openapi-button {
|
||||||
|
padding: 3px 8px 4px 8px;
|
||||||
|
color: $primary-color;
|
||||||
|
border: 1px solid $primary-color;
|
||||||
|
margin-left: 0.5em;
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
:host /deep/ [section] {
|
||||||
|
padding-top: 60px;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
25
lib/components/SecurityDefinitions/security-definitions.ts
Normal file
25
lib/components/SecurityDefinitions/security-definitions.ts
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
'use strict';
|
||||||
|
import { Component, ChangeDetectionStrategy, OnInit } from '@angular/core';
|
||||||
|
import { SpecManager, BaseComponent } from '../base';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'security-definitions',
|
||||||
|
styleUrls: ['./security-definitions.css'],
|
||||||
|
templateUrl: './security-definitions.html',
|
||||||
|
changeDetection: ChangeDetectionStrategy.OnPush
|
||||||
|
})
|
||||||
|
export class SecurityDefinitions extends BaseComponent implements OnInit {
|
||||||
|
info: any = {};
|
||||||
|
specUrl: String;
|
||||||
|
message: string = 'Roman';
|
||||||
|
constructor(specMgr:SpecManager) {
|
||||||
|
super(specMgr);
|
||||||
|
}
|
||||||
|
|
||||||
|
init() {
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.preinit();
|
||||||
|
}
|
||||||
|
}
|
|
@ -13,7 +13,7 @@ import { TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
import { MethodsList, SideMenu } from '../index';
|
import { MethodsList, SideMenu } from '../index';
|
||||||
|
|
||||||
import { SpecManager } from '../../utils/SpecManager';
|
import { SpecManager } from '../../utils/spec-manager';
|
||||||
|
|
||||||
let testOptions;
|
let testOptions;
|
||||||
|
|
||||||
|
|
|
@ -103,7 +103,6 @@ export class SideMenu extends BaseComponent implements OnInit {
|
||||||
|
|
||||||
destroy() {
|
destroy() {
|
||||||
this.scrollService.unbind();
|
this.scrollService.unbind();
|
||||||
this.hash.unbind();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import { SpecManager } from '../utils/SpecManager';
|
import { SpecManager } from '../utils/spec-manager';
|
||||||
import { BaseComponent } from '../components/base';
|
import { BaseComponent } from '../components/base';
|
||||||
|
|
||||||
describe('Redoc components', () => {
|
describe('Redoc components', () => {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
import { OnInit, OnDestroy } from '@angular/core';
|
import { OnInit, OnDestroy } from '@angular/core';
|
||||||
import { SpecManager } from '../utils/SpecManager';
|
import { SpecManager } from '../utils/spec-manager';
|
||||||
|
|
||||||
|
|
||||||
export { SpecManager };
|
export { SpecManager };
|
||||||
|
|
|
@ -13,13 +13,14 @@ import { SideMenu } from './SideMenu/side-menu';
|
||||||
import { MethodsList } from './MethodsList/methods-list';
|
import { MethodsList } from './MethodsList/methods-list';
|
||||||
import { Method } from './Method/method';
|
import { Method } from './Method/method';
|
||||||
import { Warnings } from './Warnings/warnings';
|
import { Warnings } from './Warnings/warnings';
|
||||||
|
import { SecurityDefinitions } from './SecurityDefinitions/security-definitions';
|
||||||
|
|
||||||
import { Redoc } from './Redoc/redoc';
|
import { Redoc } from './Redoc/redoc';
|
||||||
|
|
||||||
export const REDOC_DIRECTIVES = [
|
export const REDOC_DIRECTIVES = [
|
||||||
ApiInfo, ApiLogo, JsonSchema, JsonSchemaLazy, ParamsList, RequestSamples, ResponsesList,
|
ApiInfo, ApiLogo, JsonSchema, JsonSchemaLazy, ParamsList, RequestSamples, ResponsesList,
|
||||||
ResponsesSamples, SchemaSample, SideMenu, MethodsList, Method, Warnings, Redoc
|
ResponsesSamples, SchemaSample, SideMenu, MethodsList, Method, Warnings, Redoc, SecurityDefinitions
|
||||||
];
|
];
|
||||||
|
|
||||||
export { ApiInfo, ApiLogo, JsonSchema, JsonSchemaLazy, ParamsList, RequestSamples, ResponsesList,
|
export { ApiInfo, ApiLogo, JsonSchema, JsonSchemaLazy, ParamsList, RequestSamples, ResponsesList,
|
||||||
ResponsesSamples, SchemaSample, SideMenu, MethodsList, Method, Warnings, Redoc }
|
ResponsesSamples, SchemaSample, SideMenu, MethodsList, Method, Warnings, Redoc, SecurityDefinitions }
|
||||||
|
|
|
@ -3,7 +3,7 @@ import './components/Redoc/redoc-initial-styles.css';
|
||||||
|
|
||||||
import { enableProdMode } from '@angular/core';
|
import { enableProdMode } from '@angular/core';
|
||||||
import { Redoc } from './components/index';
|
import { Redoc } from './components/index';
|
||||||
import { SpecManager } from './utils/SpecManager';
|
import { SpecManager } from './utils/spec-manager';
|
||||||
import { BrowserDomAdapter as DOM } from './utils/browser-adapter';
|
import { BrowserDomAdapter as DOM } from './utils/browser-adapter';
|
||||||
import { disableDebugTools } from '@angular/platform-browser';
|
import { disableDebugTools } from '@angular/platform-browser';
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ export function init(specUrl:string, options:any = {}) {
|
||||||
moduleRef = appRef;
|
moduleRef = appRef;
|
||||||
console.log('ReDoc initialized!');
|
console.log('ReDoc initialized!');
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
Redoc.displayError(err);
|
//Redoc.displayError(err);
|
||||||
throw err;
|
throw err;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,26 +1,29 @@
|
||||||
import { NgModule } from '@angular/core';
|
import { NgModule, ErrorHandler } from '@angular/core';
|
||||||
import { CommonModule } from '@angular/common';
|
import { CommonModule } from '@angular/common';
|
||||||
|
|
||||||
import { Redoc, REDOC_DIRECTIVES } from './components/index';
|
import { Redoc, SecurityDefinitions, REDOC_DIRECTIVES } from './components/index';
|
||||||
import { REDOC_COMMON_DIRECTIVES } from './shared/components/index';
|
import { REDOC_COMMON_DIRECTIVES } from './shared/components/index';
|
||||||
import { REDOC_PIPES } from './utils/pipes';
|
import { REDOC_PIPES } from './utils/pipes';
|
||||||
|
import { CustomErrorHandler } from './utils/'
|
||||||
|
|
||||||
import { OptionsService, RedocEventsService, MenuService,
|
import { OptionsService, MenuService,
|
||||||
ScrollService, Hash, WarningsService } from './services/index';
|
ScrollService, Hash, WarningsService, AppStateService } from './services/';
|
||||||
import { SpecManager } from './utils/SpecManager';
|
import { SpecManager } from './utils/spec-manager';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [ CommonModule ],
|
imports: [ CommonModule ],
|
||||||
declarations: [ REDOC_DIRECTIVES, REDOC_COMMON_DIRECTIVES, REDOC_PIPES],
|
declarations: [ REDOC_DIRECTIVES, REDOC_COMMON_DIRECTIVES, REDOC_PIPES],
|
||||||
bootstrap: [ Redoc ],
|
bootstrap: [ Redoc ],
|
||||||
|
entryComponents: [SecurityDefinitions],
|
||||||
providers: [
|
providers: [
|
||||||
SpecManager,
|
SpecManager,
|
||||||
RedocEventsService,
|
|
||||||
ScrollService,
|
ScrollService,
|
||||||
Hash,
|
Hash,
|
||||||
MenuService,
|
MenuService,
|
||||||
WarningsService,
|
WarningsService,
|
||||||
OptionsService
|
OptionsService,
|
||||||
|
AppStateService,
|
||||||
|
{ provide: ErrorHandler, useClass: CustomErrorHandler }
|
||||||
],
|
],
|
||||||
exports: [Redoc]
|
exports: [Redoc]
|
||||||
})
|
})
|
||||||
|
|
11
lib/services/app-state.service.ts
Normal file
11
lib/services/app-state.service.ts
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { Subject } from 'rxjs/Subject';
|
||||||
|
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class AppStateService {
|
||||||
|
samplesLanguage = new Subject<string>();
|
||||||
|
error = new BehaviorSubject<any>(null);
|
||||||
|
}
|
|
@ -1,8 +1,9 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
var isSupported = document.queryCommandSupported && document.queryCommandSupported('copy');
|
||||||
export class Clipboard {
|
export class Clipboard {
|
||||||
static isSupported():boolean {
|
static isSupported():boolean {
|
||||||
return document.queryCommandSupported && document.queryCommandSupported('copy');
|
return isSupported;
|
||||||
}
|
}
|
||||||
|
|
||||||
static selectElement(element:any):void {
|
static selectElement(element:any):void {
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
'use strict';
|
|
||||||
|
|
||||||
import { EventEmitter, Output } from '@angular/core';
|
|
||||||
|
|
||||||
export class RedocEventsService {
|
|
||||||
@Output() bootstrapped = new EventEmitter();
|
|
||||||
@Output() samplesLanguageChanged = new EventEmitter();
|
|
||||||
}
|
|
|
@ -1,25 +1,22 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
import {
|
||||||
|
inject
|
||||||
|
} from '@angular/core/testing';
|
||||||
|
|
||||||
import { RedocEventsService } from './events.service';
|
|
||||||
import { Hash } from './hash.service';
|
import { Hash } from './hash.service';
|
||||||
|
import { SpecManager } from '../utils/spec-manager';
|
||||||
|
|
||||||
describe('Hash Service', () => {
|
describe('Hash Service', () => {
|
||||||
let events = new RedocEventsService();
|
let specMgr = new SpecManager();
|
||||||
let hashService;
|
let hashService;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(inject([Hash], (_hash) => hashService = _hash));
|
||||||
hashService = new Hash(events);
|
|
||||||
});
|
|
||||||
|
|
||||||
afterEach(() => {
|
|
||||||
hashService.unbind();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should trigger changed event after ReDoc bootstrapped', (done) => {
|
it('should trigger changed event after ReDoc bootstrapped', (done) => {
|
||||||
spyOn(hashService.changed, 'next').and.callThrough();
|
spyOn(hashService.value, 'next').and.callThrough();
|
||||||
events.bootstrapped.next({});
|
specMgr.spec.next({});
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
expect(hashService.changed.next).toHaveBeenCalled();
|
expect(hashService.value.next).toHaveBeenCalled();
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,32 +1,31 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
import { Injectable, EventEmitter, Output } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { BrowserDomAdapter as DOM } from '../utils/browser-adapter';
|
import { PlatformLocation } from '@angular/common';
|
||||||
import { global } from '@angular/core/src/facade/lang';
|
|
||||||
|
|
||||||
import { RedocEventsService } from './events.service';
|
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
|
||||||
|
import { SpecManager } from '../utils/spec-manager';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class Hash {
|
export class Hash {
|
||||||
@Output() changed = new EventEmitter();
|
public value = new BehaviorSubject<string>('');
|
||||||
private _cancel: any;
|
constructor(private specMgr: SpecManager, private location: PlatformLocation) {
|
||||||
constructor(private events:RedocEventsService) {
|
|
||||||
this.bind();
|
this.bind();
|
||||||
|
|
||||||
events.bootstrapped.subscribe(() => this.changed.next(this.hash));
|
this.specMgr.spec.subscribe((spec) => {
|
||||||
}
|
if (!spec) return;
|
||||||
|
setTimeout(() => {
|
||||||
get hash() {
|
this.value.next(this.hash);
|
||||||
return DOM.getLocation().hash;
|
});
|
||||||
}
|
|
||||||
|
|
||||||
bind() {
|
|
||||||
this._cancel = DOM.onAndCancel(global, 'hashchange', (evt) => {
|
|
||||||
this.changed.next(this.hash);
|
|
||||||
evt.preventDefault();
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
unbind() {
|
get hash() {
|
||||||
this._cancel();
|
return this.location.hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
bind() {
|
||||||
|
this.location.onHashChange(() => {
|
||||||
|
this.value.next(this.hash);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
export * from './events.service';
|
export * from './app-state.service';
|
||||||
export * from './options.service';
|
export * from './options.service';
|
||||||
export * from './menu.service';
|
export * from './menu.service';
|
||||||
export * from './scroll.service';
|
export * from './scroll.service';
|
||||||
|
|
|
@ -9,7 +9,7 @@ import {
|
||||||
import { MenuService } from './menu.service';
|
import { MenuService } from './menu.service';
|
||||||
import { Hash } from './hash.service';
|
import { Hash } from './hash.service';
|
||||||
import { ScrollService } from './scroll.service';
|
import { ScrollService } from './scroll.service';
|
||||||
import { SpecManager } from '../utils/SpecManager';;
|
import { SpecManager } from '../utils/spec-manager';;
|
||||||
|
|
||||||
describe('Menu service', () => {
|
describe('Menu service', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
@ -36,39 +36,42 @@ describe('Menu service', () => {
|
||||||
|
|
||||||
it('should run hashScroll when hash changed', (done) => {
|
it('should run hashScroll when hash changed', (done) => {
|
||||||
spyOn(menu, 'hashScroll').and.callThrough();
|
spyOn(menu, 'hashScroll').and.callThrough();
|
||||||
hashService.changed.subscribe(() => {
|
hashService.value.subscribe((hash) => {
|
||||||
|
if (!hash) return;
|
||||||
expect(menu.hashScroll).toHaveBeenCalled();
|
expect(menu.hashScroll).toHaveBeenCalled();
|
||||||
menu.hashScroll.and.callThrough();
|
menu.hashScroll.and.callThrough();
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
hashService.changed.next();
|
hashService.value.next('nonFalsy');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should scroll to method when location hash is present [jp]', (done) => {
|
it('should scroll to method when location hash is present [jp]', (done) => {
|
||||||
let hash = '#tag/pet/paths/~1pet~1findByStatus/get';
|
let hash = '#tag/pet/paths/~1pet~1findByStatus/get';
|
||||||
spyOn(menu, 'hashScroll').and.callThrough();
|
spyOn(menu, 'hashScroll').and.callThrough();
|
||||||
spyOn(window, 'scrollTo').and.stub();
|
spyOn(window, 'scrollTo').and.stub();
|
||||||
hashService.changed.subscribe(() => {
|
hashService.value.subscribe((hash) => {
|
||||||
|
if (!hash) return;
|
||||||
expect(menu.hashScroll).toHaveBeenCalled();
|
expect(menu.hashScroll).toHaveBeenCalled();
|
||||||
let scrollY = (<jasmine.Spy>window.scrollTo).calls.argsFor(0)[1];
|
let scrollY = (<jasmine.Spy>window.scrollTo).calls.argsFor(0)[1];
|
||||||
expect(scrollY).toBeGreaterThan(0);
|
expect(scrollY).toBeGreaterThan(0);
|
||||||
(<jasmine.Spy>window.scrollTo).and.callThrough();
|
(<jasmine.Spy>window.scrollTo).and.callThrough();
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
hashService.changed.next(hash);
|
hashService.value.next(hash);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should scroll to method when location hash is present [operation]', (done) => {
|
it('should scroll to method when location hash is present [operation]', (done) => {
|
||||||
let hash = '#operation/getPetById';
|
let hash = '#operation/getPetById';
|
||||||
spyOn(menu, 'hashScroll').and.callThrough();
|
spyOn(menu, 'hashScroll').and.callThrough();
|
||||||
spyOn(window, 'scrollTo').and.stub();
|
spyOn(window, 'scrollTo').and.stub();
|
||||||
hashService.changed.subscribe(() => {
|
hashService.value.subscribe((hash) => {
|
||||||
|
if (!hash) return;
|
||||||
expect(menu.hashScroll).toHaveBeenCalled();
|
expect(menu.hashScroll).toHaveBeenCalled();
|
||||||
let scrollY = (<jasmine.Spy>window.scrollTo).calls.argsFor(0)[1];
|
let scrollY = (<jasmine.Spy>window.scrollTo).calls.argsFor(0)[1];
|
||||||
expect(scrollY).toBeGreaterThan(0);
|
expect(scrollY).toBeGreaterThan(0);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
hashService.changed.next(hash);
|
hashService.value.next(hash);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should select next/prev menu item when scrolled down/up', () => {
|
it('should select next/prev menu item when scrolled down/up', () => {
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
import { Injectable, EventEmitter } from '@angular/core';
|
import { Injectable, EventEmitter } from '@angular/core';
|
||||||
import { ScrollService, INVIEW_POSITION } from './scroll.service';
|
import { ScrollService, INVIEW_POSITION } from './scroll.service';
|
||||||
import { Hash } from './hash.service';
|
import { Hash } from './hash.service';
|
||||||
import { SpecManager } from '../utils/SpecManager';
|
import { SpecManager } from '../utils/spec-manager';
|
||||||
import { SchemaHelper, MenuCategory } from './schema-helper.service';
|
import { SchemaHelper, MenuCategory } from './schema-helper.service';
|
||||||
|
|
||||||
const CHANGE = {
|
const CHANGE = {
|
||||||
|
@ -30,7 +30,7 @@ export class MenuService {
|
||||||
|
|
||||||
this.changeActive(CHANGE.INITIAL);
|
this.changeActive(CHANGE.INITIAL);
|
||||||
|
|
||||||
this.hash.changed.subscribe((hash) => {
|
this.hash.value.subscribe((hash) => {
|
||||||
this.hashScroll(hash);
|
this.hashScroll(hash);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
import { SchemaHelper } from './schema-helper.service';
|
import { SchemaHelper } from './schema-helper.service';
|
||||||
import { SpecManager } from '../utils/SpecManager';
|
import { SpecManager } from '../utils/spec-manager';
|
||||||
|
|
||||||
describe('Spec Helper', () => {
|
describe('Spec Helper', () => {
|
||||||
describe('buildMenuTree method', () => {
|
describe('buildMenuTree method', () => {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
import { JsonPointer } from '../utils/JsonPointer';
|
import { JsonPointer } from '../utils/JsonPointer';
|
||||||
import { SpecManager } from '../utils/SpecManager';
|
import { SpecManager } from '../utils/spec-manager';
|
||||||
import {methods as swaggerMethods, keywordTypes} from '../utils/swagger-defs';
|
import {methods as swaggerMethods, keywordTypes} from '../utils/swagger-defs';
|
||||||
import { WarningsService } from './warnings.service';
|
import { WarningsService } from './warnings.service';
|
||||||
import * as slugify from 'slugify';
|
import * as slugify from 'slugify';
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
import { SchemaNormalizer } from './schema-normalizer.service';
|
import { SchemaNormalizer } from './schema-normalizer.service';
|
||||||
import { SpecManager } from '../utils/SpecManager';;
|
import { SpecManager } from '../utils/spec-manager';;
|
||||||
|
|
||||||
describe('Spec Helper', () => {
|
describe('Spec Helper', () => {
|
||||||
let specMgr:SpecManager = new SpecManager();
|
let specMgr:SpecManager = new SpecManager();
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { SpecManager } from '../utils/SpecManager';
|
import { SpecManager } from '../utils/spec-manager';
|
||||||
import { JsonPointer } from '../utils/JsonPointer';
|
import { JsonPointer } from '../utils/JsonPointer';
|
||||||
import { defaults } from '../utils/helpers';
|
import { defaults } from '../utils/helpers';
|
||||||
import { WarningsService } from './warnings.service';
|
import { WarningsService } from './warnings.service';
|
||||||
|
|
|
@ -18,7 +18,6 @@ export class ScrollService {
|
||||||
private prevOffsetY: number;
|
private prevOffsetY: number;
|
||||||
private _cancel:any;
|
private _cancel:any;
|
||||||
constructor(optionsService:OptionsService) {
|
constructor(optionsService:OptionsService) {
|
||||||
//events.bootstrapped.subscribe(() => this.hashScroll());
|
|
||||||
this.scrollYOffset = () => optionsService.options.scrollYOffset();
|
this.scrollYOffset = () => optionsService.options.scrollYOffset();
|
||||||
this.$scrollParent = optionsService.options.$scrollParent;
|
this.$scrollParent = optionsService.options.$scrollParent;
|
||||||
this.scroll = new EventEmitter();
|
this.scroll = new EventEmitter();
|
||||||
|
@ -31,11 +30,12 @@ export class ScrollService {
|
||||||
|
|
||||||
/* returns 1 if element if above the view, 0 if in view and -1 below the view */
|
/* returns 1 if element if above the view, 0 if in view and -1 below the view */
|
||||||
getElementPos($el) {
|
getElementPos($el) {
|
||||||
if (Math.floor($el.getBoundingClientRect().top) > this.scrollYOffset()) {
|
let scrollYOffset = this.scrollYOffset();
|
||||||
|
if (Math.floor($el.getBoundingClientRect().top) > scrollYOffset) {
|
||||||
return INVIEW_POSITION.ABOVE;
|
return INVIEW_POSITION.ABOVE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($el.getBoundingClientRect().bottom <= this.scrollYOffset()) {
|
if ($el.getBoundingClientRect().bottom <= scrollYOffset) {
|
||||||
return INVIEW_POSITION.BELLOW;
|
return INVIEW_POSITION.BELLOW;
|
||||||
}
|
}
|
||||||
return INVIEW_POSITION.INVIEW;
|
return INVIEW_POSITION.INVIEW;
|
||||||
|
|
|
@ -1,10 +0,0 @@
|
||||||
/*eslint no-unused-vars: 0*/
|
|
||||||
/*eslint strict: 0*/
|
|
||||||
var $buoop = { vs: {i:9, f:25, o:12.1, s:7}, c:2 };
|
|
||||||
function $buo_f(){
|
|
||||||
var e = document.createElement('script');
|
|
||||||
e.src = '//browser-update.org/update.min.js';
|
|
||||||
document.body.appendChild(e);
|
|
||||||
}
|
|
||||||
try {document.addEventListener('DOMContentLoaded', $buo_f, false);}
|
|
||||||
catch(e){window['attachEvent']('onload', $buo_f);}
|
|
12
lib/utils/custom-error-handler.ts
Normal file
12
lib/utils/custom-error-handler.ts
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
import { ErrorHandler, Injectable } from '@angular/core';
|
||||||
|
import { AppStateService } from '../services/app-state.service';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class CustomErrorHandler implements ErrorHandler {
|
||||||
|
constructor(private appState: AppStateService) {
|
||||||
|
}
|
||||||
|
handleError(error) {
|
||||||
|
console.log(error);
|
||||||
|
this.appState.error.next(error);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,103 +0,0 @@
|
||||||
'use strict';
|
|
||||||
var Remarkable = require('remarkable');
|
|
||||||
var md = new Remarkable({
|
|
||||||
html: true,
|
|
||||||
linkify: true,
|
|
||||||
breaks: false,
|
|
||||||
typographer: false,
|
|
||||||
highlight: function (str, lang) {
|
|
||||||
if (lang === 'json')
|
|
||||||
lang = 'js';
|
|
||||||
var grammar = Prism.languages[lang];
|
|
||||||
if (!grammar)
|
|
||||||
return str;
|
|
||||||
return Prism.highlight(str, grammar);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
function renderMd(rawText, headersHandler) {
|
|
||||||
var _origRule;
|
|
||||||
if (headersHandler) {
|
|
||||||
_origRule = {
|
|
||||||
open: md.renderer.rules.heading_open,
|
|
||||||
close: md.renderer.rules.heading_close
|
|
||||||
};
|
|
||||||
md.renderer.rules.heading_open = function (tokens, idx) {
|
|
||||||
if (tokens[idx].hLevel !== 1) {
|
|
||||||
return _origRule.open(tokens, idx);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return headersHandler.open(tokens, idx);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
md.renderer.rules.heading_close = function (tokens, idx) {
|
|
||||||
if (tokens[idx].hLevel !== 1) {
|
|
||||||
return _origRule.close(tokens, idx);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return headersHandler.close(tokens, idx);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
var res = md.render(rawText);
|
|
||||||
if (headersHandler) {
|
|
||||||
md.renderer.rules.heading_open = _origRule.open;
|
|
||||||
md.renderer.rules.heading_close = _origRule.close;
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
exports.renderMd = renderMd;
|
|
||||||
function statusCodeType(statusCode) {
|
|
||||||
if (statusCode < 100 || statusCode > 599) {
|
|
||||||
throw new Error('invalid HTTP code');
|
|
||||||
}
|
|
||||||
var res = 'success';
|
|
||||||
if (statusCode >= 300 && statusCode < 400) {
|
|
||||||
res = 'redirect';
|
|
||||||
}
|
|
||||||
else if (statusCode >= 400) {
|
|
||||||
res = 'error';
|
|
||||||
}
|
|
||||||
else if (statusCode < 200) {
|
|
||||||
res = 'info';
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
exports.statusCodeType = statusCodeType;
|
|
||||||
function defaults(target, src) {
|
|
||||||
var props = Object.keys(src);
|
|
||||||
var index = -1, length = props.length;
|
|
||||||
while (++index < length) {
|
|
||||||
var key = props[index];
|
|
||||||
if (target[key] === undefined) {
|
|
||||||
target[key] = src[key];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return target;
|
|
||||||
}
|
|
||||||
exports.defaults = defaults;
|
|
||||||
function safePush(obj, prop, val) {
|
|
||||||
if (!obj[prop])
|
|
||||||
obj[prop] = [];
|
|
||||||
obj[prop].push(val);
|
|
||||||
}
|
|
||||||
exports.safePush = safePush;
|
|
||||||
function throttle(fn, threshhold, scope) {
|
|
||||||
threshhold = threshhold || 250;
|
|
||||||
var last, deferTimer;
|
|
||||||
return function () {
|
|
||||||
var context = scope || this;
|
|
||||||
var now = +new Date, args = arguments;
|
|
||||||
if (last && now < last + threshhold) {
|
|
||||||
clearTimeout(deferTimer);
|
|
||||||
deferTimer = setTimeout(function () {
|
|
||||||
last = now;
|
|
||||||
fn.apply(context, args);
|
|
||||||
}, threshhold);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
last = now;
|
|
||||||
fn.apply(context, args);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
exports.throttle = throttle;
|
|
1
lib/utils/index.ts
Normal file
1
lib/utils/index.ts
Normal file
|
@ -0,0 +1 @@
|
||||||
|
export * from './custom-error-handler';
|
|
@ -5,10 +5,13 @@ import { JsonPointer } from './JsonPointer';
|
||||||
import { renderMd, safePush } from './helpers';
|
import { renderMd, safePush } from './helpers';
|
||||||
import * as slugify from 'slugify';
|
import * as slugify from 'slugify';
|
||||||
import { parse as urlParse, resolve as urlResolve } from 'url';
|
import { parse as urlParse, resolve as urlResolve } from 'url';
|
||||||
|
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
|
||||||
|
|
||||||
export class SpecManager {
|
export class SpecManager {
|
||||||
public _schema: any = {};
|
public _schema: any = {};
|
||||||
public apiUrl: string;
|
public apiUrl: string;
|
||||||
|
|
||||||
|
public spec = new BehaviorSubject<any|null>(null);
|
||||||
private _instance: any;
|
private _instance: any;
|
||||||
private _url: string;
|
private _url: string;
|
||||||
|
|
||||||
|
@ -24,17 +27,19 @@ export class SpecManager {
|
||||||
SpecManager.prototype._instance = this;
|
SpecManager.prototype._instance = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
load(url) {
|
load(urlOrObject: string|Object) {
|
||||||
|
this.schema = null;
|
||||||
let promise = new Promise((resolve, reject) => {
|
let promise = new Promise((resolve, reject) => {
|
||||||
this._schema = {};
|
JsonSchemaRefParser.bundle(urlOrObject, {http: {withCredentials: false}})
|
||||||
|
|
||||||
JsonSchemaRefParser.bundle(url, {http: {withCredentials: false}})
|
|
||||||
.then(schema => {
|
.then(schema => {
|
||||||
try {
|
if (typeof urlOrObject === 'string') {
|
||||||
this._url = url;
|
this._url = urlOrObject;
|
||||||
|
}
|
||||||
this._schema = schema;
|
this._schema = schema;
|
||||||
|
try {
|
||||||
this.init();
|
this.init();
|
||||||
resolve(this._schema);
|
resolve(this._schema);
|
||||||
|
this.spec.next(this._schema);
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
reject(err);
|
reject(err);
|
||||||
}
|
}
|
||||||
|
@ -88,6 +93,11 @@ export class SpecManager {
|
||||||
return this._schema;
|
return this._schema;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
set schema(val:any) {
|
||||||
|
this._schema = val;
|
||||||
|
this.spec.next(this._schema);
|
||||||
|
}
|
||||||
|
|
||||||
byPointer(pointer) {
|
byPointer(pointer) {
|
||||||
let res = null;
|
let res = null;
|
||||||
try {
|
try {
|
|
@ -19,11 +19,11 @@ require('zone.js/dist/jasmine-patch');
|
||||||
require('../lib/vendor');
|
require('../lib/vendor');
|
||||||
|
|
||||||
var TestBed = require('@angular/core/testing').TestBed;
|
var TestBed = require('@angular/core/testing').TestBed;
|
||||||
|
var ErrorHandler = require('@angular/core').ErrorHandler;
|
||||||
var BrowserDynamicTestingModule = require('@angular/platform-browser-dynamic/testing').BrowserDynamicTestingModule;
|
var BrowserDynamicTestingModule = require('@angular/platform-browser-dynamic/testing').BrowserDynamicTestingModule;
|
||||||
var platformBrowserDynamicTesting = require('@angular/platform-browser-dynamic/testing').platformBrowserDynamicTesting;
|
var platformBrowserDynamicTesting = require('@angular/platform-browser-dynamic/testing').platformBrowserDynamicTesting;
|
||||||
var services = require('../lib/services/index');
|
var services = require('../lib/services/index');
|
||||||
var SpecManager = require('../lib/utils/SpecManager').SpecManager;
|
var SpecManager = require('../lib/utils/spec-manager').SpecManager;
|
||||||
var BrowserDomAdapter = require('@angular/platform-browser/src/browser/browser_adapter').BrowserDomAdapter;
|
|
||||||
var REDOC_PIPES = require('../lib/utils/pipes').REDOC_PIPES;
|
var REDOC_PIPES = require('../lib/utils/pipes').REDOC_PIPES;
|
||||||
var REDOC_COMMON_DIRECTIVES = require('../lib/shared/components/index').REDOC_COMMON_DIRECTIVES;
|
var REDOC_COMMON_DIRECTIVES = require('../lib/shared/components/index').REDOC_COMMON_DIRECTIVES;
|
||||||
var REDOC_DIRECTIVES = require('../lib/components/index').REDOC_DIRECTIVES;
|
var REDOC_DIRECTIVES = require('../lib/components/index').REDOC_DIRECTIVES;
|
||||||
|
@ -36,15 +36,14 @@ TestBed.initTestEnvironment(
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
providers: [
|
providers: [
|
||||||
BrowserDomAdapter,
|
|
||||||
SpecManager,
|
SpecManager,
|
||||||
BrowserDomAdapter,
|
services.AppStateService,
|
||||||
services.RedocEventsService,
|
|
||||||
services.ScrollService,
|
services.ScrollService,
|
||||||
services.Hash,
|
services.Hash,
|
||||||
services.MenuService,
|
services.MenuService,
|
||||||
services.WarningsService,
|
services.WarningsService,
|
||||||
services.OptionsService
|
services.OptionsService,
|
||||||
|
{ provide: ErrorHandler, useClass: services.CustomErrorHandler }
|
||||||
],
|
],
|
||||||
declarations: [REDOC_PIPES, REDOC_DIRECTIVES, REDOC_COMMON_DIRECTIVES]
|
declarations: [REDOC_PIPES, REDOC_DIRECTIVES, REDOC_COMMON_DIRECTIVES]
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import { SpecManager } from '../../lib/utils/SpecManager';
|
import { SpecManager } from '../../lib/utils/spec-manager';
|
||||||
describe('Utils', () => {
|
describe('Utils', () => {
|
||||||
describe('Schema manager', () => {
|
describe('Schema manager', () => {
|
||||||
let specMgr;
|
let specMgr;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user