mirror of
https://github.com/Redocly/redoc.git
synced 2024-11-30 20:43:42 +03:00
Merge branch 'master' into releases
This commit is contained in:
commit
383169d6c5
10
.travis.yml
10
.travis.yml
|
@ -6,10 +6,10 @@ branches:
|
||||||
- releases
|
- releases
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
- env: JOB=e2e
|
- env: JOB=e2e-guru
|
||||||
fast_finish: true
|
fast_finish: true
|
||||||
allow_failures:
|
allow_failures:
|
||||||
- env: JOB=e2e
|
- env: JOB=e2e-guru
|
||||||
env:
|
env:
|
||||||
global:
|
global:
|
||||||
- GH_REF: github.com/Rebilly/ReDoc.git
|
- GH_REF: github.com/Rebilly/ReDoc.git
|
||||||
|
@ -41,16 +41,16 @@ deploy:
|
||||||
secure: PuhWLERrCEFmXmdFpw2OVFlqpOIVDmgwk5JUJOYaFdVCh/smp0+jZCQ4vrdFpuG96rnDVirD+A8xvW6NgsNNaRthLgOB/LRdFN69rU6Gvn3At6wlnC55t5dlhxPvCfnzJcHVBLXX4EmMkjnZqDg2uczXTzPodr3FnQJNuXmP8B33fzDVLyHccvXZ90abwXWVrgRIXPU28niqCR8DOC2OTzs7wqz+BLNkYDRRbyYXsg62HWuD33x5iof5IqBmhzBt3usCGmF3QGcgHrXHdZw3sZnit8+Bua++3KrXR0x6HGXXN1AoXVmCAkCa5OTQ5R3tCRxiJN3P2KLnvWeZR74sTFkovJB/6pGCvbJ/c7Wnuw6sD7SgOUBD359ULB6lAf5OnxBLoNebX4JxxVXF+zA4E3Bl44VxkzDpPWc15xqBPMB5vBREzMVmJ5mExn2s5cmLQjADbl9h0y6gZnhnNJ+iTmqtrVyM0ZkF2rPrzrTdGD+ULmRIlTMkdD1bh+/TJ3RdXT3P4/zNUJmiNnvgnnJVYYvsGaXWF+7uCVHT/8k2RsoSHqgkqh0gkDqGSwVix55y5mC7T2Vk9lMBhm6MvFJXaonOX0kxJS4EDQ3plPd6/ybG+TLhwggYnQ8o9msU5Nt6FpUShKiezjKurIhbQZdwlVivX3tahjW2QjNDO58xGgY=
|
secure: PuhWLERrCEFmXmdFpw2OVFlqpOIVDmgwk5JUJOYaFdVCh/smp0+jZCQ4vrdFpuG96rnDVirD+A8xvW6NgsNNaRthLgOB/LRdFN69rU6Gvn3At6wlnC55t5dlhxPvCfnzJcHVBLXX4EmMkjnZqDg2uczXTzPodr3FnQJNuXmP8B33fzDVLyHccvXZ90abwXWVrgRIXPU28niqCR8DOC2OTzs7wqz+BLNkYDRRbyYXsg62HWuD33x5iof5IqBmhzBt3usCGmF3QGcgHrXHdZw3sZnit8+Bua++3KrXR0x6HGXXN1AoXVmCAkCa5OTQ5R3tCRxiJN3P2KLnvWeZR74sTFkovJB/6pGCvbJ/c7Wnuw6sD7SgOUBD359ULB6lAf5OnxBLoNebX4JxxVXF+zA4E3Bl44VxkzDpPWc15xqBPMB5vBREzMVmJ5mExn2s5cmLQjADbl9h0y6gZnhnNJ+iTmqtrVyM0ZkF2rPrzrTdGD+ULmRIlTMkdD1bh+/TJ3RdXT3P4/zNUJmiNnvgnnJVYYvsGaXWF+7uCVHT/8k2RsoSHqgkqh0gkDqGSwVix55y5mC7T2Vk9lMBhm6MvFJXaonOX0kxJS4EDQ3plPd6/ybG+TLhwggYnQ8o9msU5Nt6FpUShKiezjKurIhbQZdwlVivX3tahjW2QjNDO58xGgY=
|
||||||
on:
|
on:
|
||||||
tags: true
|
tags: true
|
||||||
condition: $JOB != e2e
|
condition: $JOB != e2e-guru
|
||||||
- skip_cleanup: true
|
- skip_cleanup: true
|
||||||
provider: script
|
provider: script
|
||||||
script: npm run branch-release
|
script: npm run branch-release
|
||||||
on:
|
on:
|
||||||
branch: master
|
branch: master
|
||||||
condition: $JOB != e2e
|
condition: $JOB != e2e-guru
|
||||||
- skip_cleanup: true
|
- skip_cleanup: true
|
||||||
provider: script
|
provider: script
|
||||||
script: npm run deploy
|
script: npm run deploy
|
||||||
on:
|
on:
|
||||||
tags: true
|
tags: true
|
||||||
condition: $JOB != e2e
|
condition: $JOB != e2e-guru
|
||||||
|
|
|
@ -8,7 +8,7 @@ git reset --hard
|
||||||
git fetch origin gh-pages:gh-pages
|
git fetch origin gh-pages:gh-pages
|
||||||
git checkout gh-pages
|
git checkout gh-pages
|
||||||
cp -R ../releases/* .
|
cp -R ../releases/* .
|
||||||
git checkout master
|
git checkout @{-1}
|
||||||
cd -
|
cd -
|
||||||
|
|
||||||
# build
|
# build
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
if [ "$JOB" = "e2e" ]; then
|
if [ "$JOB" = "e2e-guru" ]; then
|
||||||
npm run e2e
|
npm run e2e
|
||||||
else
|
else
|
||||||
npm run unit
|
npm run unit
|
||||||
|
echo "Starting Basic E2E"
|
||||||
|
npm run e2e
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -41,6 +41,7 @@ gulp.task('inlineTemplates', ['sass'], function() {
|
||||||
var JS_DEV_DEPS = [
|
var JS_DEV_DEPS = [
|
||||||
'lib/utils/browser-update.js',
|
'lib/utils/browser-update.js',
|
||||||
'node_modules/zone.js/dist/zone.js',
|
'node_modules/zone.js/dist/zone.js',
|
||||||
|
'node_modules/zone.js/dist/long-stack-trace-zone.js',
|
||||||
'node_modules/reflect-metadata/Reflect.js',
|
'node_modules/reflect-metadata/Reflect.js',
|
||||||
'node_modules/babel-polyfill/dist/polyfill.js'
|
'node_modules/babel-polyfill/dist/polyfill.js'
|
||||||
];
|
];
|
||||||
|
|
|
@ -1,22 +1,22 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import {SchemaManager, RedocComponent, BaseComponent} from '../base';
|
import { SchemaManager, RedocComponent, BaseComponent } from '../base';
|
||||||
import OptionsManager from '../../options';
|
import { OptionsService } from '../../services/index';
|
||||||
|
|
||||||
@RedocComponent({
|
@RedocComponent({
|
||||||
selector: 'api-info',
|
selector: 'api-info',
|
||||||
styleUrls: ['./lib/components/ApiInfo/api-info.css'],
|
styleUrls: ['./lib/components/ApiInfo/api-info.css'],
|
||||||
templateUrl: './lib/components/ApiInfo/api-info.html'
|
templateUrl: './lib/components/ApiInfo/api-info.html'
|
||||||
})
|
})
|
||||||
@Reflect.metadata('parameters', [[SchemaManager], [OptionsManager]])
|
@Reflect.metadata('parameters', [[SchemaManager], [OptionsService]])
|
||||||
export default class ApiInfo extends BaseComponent {
|
export class ApiInfo extends BaseComponent {
|
||||||
constructor(schemaMgr, optionsMgr) {
|
constructor(schemaMgr, optionsService) {
|
||||||
super(schemaMgr);
|
super(schemaMgr);
|
||||||
this.optionsMgr = optionsMgr;
|
this.optionsService = optionsService;
|
||||||
}
|
}
|
||||||
|
|
||||||
prepareModel() {
|
prepareModel() {
|
||||||
this.data = this.componentSchema.info;
|
this.data = this.componentSchema.info;
|
||||||
this.specUrl = this.optionsMgr.options.specUrl;
|
this.specUrl = this.optionsService.options.specUrl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
@import '../../common/styles/variables';
|
@import '../../shared/styles/variables';
|
||||||
|
|
||||||
.api-info-header {
|
.api-info-header {
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
|
|
|
@ -1,22 +1,23 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import { getChildDebugElement } from 'tests/helpers';
|
import { getChildDebugElement } from 'tests/helpers';
|
||||||
import {Component, provide} from 'angular2/core';
|
import { Component, provide } from '@angular/core';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
TestComponentBuilder,
|
|
||||||
async,
|
|
||||||
inject,
|
inject,
|
||||||
|
async,
|
||||||
beforeEach,
|
beforeEach,
|
||||||
beforeEachProviders,
|
beforeEachProviders,
|
||||||
it
|
it
|
||||||
} from 'angular2/testing';
|
} from '@angular/core/testing';
|
||||||
|
|
||||||
import ApiInfo from 'lib/components/ApiInfo/api-info';
|
import { TestComponentBuilder } from '@angular/compiler/testing';
|
||||||
|
|
||||||
|
import { ApiInfo } from 'lib/components/ApiInfo/api-info';
|
||||||
import SchemaManager from 'lib/utils/SchemaManager';
|
import SchemaManager from 'lib/utils/SchemaManager';
|
||||||
import OptionsManager from 'lib/options';
|
import { OptionsService } from 'lib/services/index';
|
||||||
|
|
||||||
let optsMgr = new OptionsManager();
|
let optionsService = new OptionsService();
|
||||||
|
|
||||||
describe('Redoc components', () => {
|
describe('Redoc components', () => {
|
||||||
describe('ApiInfo Component', () => {
|
describe('ApiInfo Component', () => {
|
||||||
|
@ -25,7 +26,7 @@ describe('Redoc components', () => {
|
||||||
let fixture;
|
let fixture;
|
||||||
beforeEachProviders(() => [
|
beforeEachProviders(() => [
|
||||||
provide(SchemaManager, {useValue: new SchemaManager()}),
|
provide(SchemaManager, {useValue: new SchemaManager()}),
|
||||||
provide(OptionsManager, {useValue: optsMgr})
|
provide(OptionsService, {useValue: optionsService})
|
||||||
]);
|
]);
|
||||||
|
|
||||||
beforeEach(async(inject([TestComponentBuilder, SchemaManager], (tcb, schemaMgr) => {
|
beforeEach(async(inject([TestComponentBuilder, SchemaManager], (tcb, schemaMgr) => {
|
||||||
|
@ -39,7 +40,9 @@ describe('Redoc components', () => {
|
||||||
component = getChildDebugElement(fixture.debugElement, 'api-info').componentInstance;
|
component = getChildDebugElement(fixture.debugElement, 'api-info').componentInstance;
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
done();
|
done();
|
||||||
}, err => done.fail(err));
|
}, err => {
|
||||||
|
done.fail(err);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ import {RedocComponent, BaseComponent} from '../base';
|
||||||
styleUrls: ['./lib/components/ApiLogo/api-logo.css'],
|
styleUrls: ['./lib/components/ApiLogo/api-logo.css'],
|
||||||
templateUrl: './lib/components/ApiLogo/api-logo.html'
|
templateUrl: './lib/components/ApiLogo/api-logo.html'
|
||||||
})
|
})
|
||||||
export default class ApiLogo extends BaseComponent {
|
export class ApiLogo extends BaseComponent {
|
||||||
constructor(schemaMgr) {
|
constructor(schemaMgr) {
|
||||||
super(schemaMgr);
|
super(schemaMgr);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
@import '../../common/styles/variables';
|
@import '../../shared/styles/variables';
|
||||||
|
|
||||||
img {
|
img {
|
||||||
max-height: 150px;
|
max-height: 150px;
|
||||||
|
|
|
@ -1,18 +1,19 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import { getChildDebugElement } from 'tests/helpers';
|
import { getChildDebugElement } from 'tests/helpers';
|
||||||
import {Component, provide} from 'angular2/core';
|
import {Component, provide} from '@angular/core';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
TestComponentBuilder,
|
|
||||||
async,
|
|
||||||
inject,
|
inject,
|
||||||
|
async,
|
||||||
beforeEach,
|
beforeEach,
|
||||||
beforeEachProviders,
|
beforeEachProviders,
|
||||||
it
|
it
|
||||||
} from 'angular2/testing';
|
} from '@angular/core/testing';
|
||||||
|
|
||||||
import ApiLogo from 'lib/components/ApiLogo/api-logo';
|
import { TestComponentBuilder } from '@angular/compiler/testing';
|
||||||
|
|
||||||
|
import { ApiLogo } from 'lib/components/ApiLogo/api-logo';
|
||||||
import SchemaManager from 'lib/utils/SchemaManager';
|
import SchemaManager from 'lib/utils/SchemaManager';
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
@import '../../common/styles/variables';
|
@import '../../shared/styles/variables';
|
||||||
$lines-width: 1px;
|
$lines-width: 1px;
|
||||||
$bullet-size: 1px;
|
$bullet-size: 1px;
|
||||||
$cell-spacing: 25px;
|
$cell-spacing: 25px;
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import {Component, ElementRef, ViewContainerRef} from 'angular2/core';
|
import { Component, ElementRef, ViewContainerRef } from '@angular/core';
|
||||||
import {CORE_DIRECTIVES} from 'angular2/common';
|
import { CORE_DIRECTIVES } from '@angular/common';
|
||||||
import {DynamicComponentLoader} from 'angular2/src/core/linker/dynamic_component_loader';
|
import { DynamicComponentLoader } from '@angular/core';
|
||||||
|
|
||||||
import JsonSchema from './json-schema';
|
import { JsonSchema } from './json-schema';
|
||||||
import OptionsManager from '../../options';
|
import { OptionsService } from '../../services/index';
|
||||||
import SchemaManager from '../../utils/SchemaManager';
|
import SchemaManager from '../../utils/SchemaManager';
|
||||||
|
|
||||||
|
|
||||||
|
@ -18,14 +18,15 @@ var cache = {};
|
||||||
template: '',
|
template: '',
|
||||||
directives: [CORE_DIRECTIVES]
|
directives: [CORE_DIRECTIVES]
|
||||||
})
|
})
|
||||||
@Reflect.metadata('parameters', [[SchemaManager], [ViewContainerRef], [ElementRef], [DynamicComponentLoader], [OptionsManager]])
|
@Reflect.metadata('parameters', [[SchemaManager], [ViewContainerRef], [
|
||||||
export default class JsonSchemaLazy {
|
ElementRef], [DynamicComponentLoader], [OptionsService]])
|
||||||
|
export class JsonSchemaLazy {
|
||||||
|
|
||||||
constructor(schemaMgr, viewRef, elementRef, dcl, optionsMgr) {
|
constructor(schemaMgr, viewRef, elementRef, dcl, optionsService) {
|
||||||
this.viewRef = viewRef;
|
this.viewRef = viewRef;
|
||||||
this.elementRef = elementRef;
|
this.elementRef = elementRef;
|
||||||
this.dcl = dcl;
|
this.dcl = dcl;
|
||||||
this.optionsMgr = optionsMgr;
|
this.optionsService = optionsService;
|
||||||
this.schemaMgr = schemaMgr;
|
this.schemaMgr = schemaMgr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,13 +36,17 @@ export default class JsonSchemaLazy {
|
||||||
}
|
}
|
||||||
|
|
||||||
load() {
|
load() {
|
||||||
if (this.optionsMgr.options.disableLazySchemas) return;
|
if (this.optionsService.options.disableLazySchemas) return;
|
||||||
if (this.loaded) return;
|
if (this.loaded) return;
|
||||||
if (this.pointer) {
|
if (this.pointer) {
|
||||||
this.dcl.loadNextToLocation(JsonSchema, this.viewRef).then((compRef) => {
|
this.dcl.loadNextToLocation(JsonSchema, this.viewRef).then((compRef) => {
|
||||||
this.initComponent(compRef);
|
this.initComponent(compRef);
|
||||||
// trigger change detection
|
// trigger change detection
|
||||||
compRef.hostView.changeDetectorRef.detectChanges();
|
if (compRef.changeDetectorRef) {
|
||||||
|
compRef.changeDetectorRef.detectChanges();
|
||||||
|
} else {
|
||||||
|
compRef.hostView.changeDetectorRef.detectChanges();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
this.loaded = true;
|
this.loaded = true;
|
||||||
|
@ -60,7 +65,11 @@ export default class JsonSchemaLazy {
|
||||||
if ($element.querySelector('.discriminator-wrap')) {
|
if ($element.querySelector('.discriminator-wrap')) {
|
||||||
this.dcl.loadNextToLocation(JsonSchema, this.viewRef).then((compRef) => {
|
this.dcl.loadNextToLocation(JsonSchema, this.viewRef).then((compRef) => {
|
||||||
this.initComponent(compRef);
|
this.initComponent(compRef);
|
||||||
compRef.hostView.changeDetectorRef.detectChanges();
|
if (compRef.changeDetectorRef) {
|
||||||
|
compRef.changeDetectorRef.detectChanges();
|
||||||
|
} else {
|
||||||
|
compRef.hostView.changeDetectorRef.detectChanges();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -70,7 +79,11 @@ export default class JsonSchemaLazy {
|
||||||
} else {
|
} else {
|
||||||
cache[this.pointer] = this.dcl.loadNextToLocation(JsonSchema, this.viewRef).then((compRef) => {
|
cache[this.pointer] = this.dcl.loadNextToLocation(JsonSchema, this.viewRef).then((compRef) => {
|
||||||
this.initComponent(compRef);
|
this.initComponent(compRef);
|
||||||
compRef.hostView.changeDetectorRef.detectChanges();
|
if (compRef.changeDetectorRef) {
|
||||||
|
compRef.changeDetectorRef.detectChanges();
|
||||||
|
} else {
|
||||||
|
compRef.hostView.changeDetectorRef.detectChanges();
|
||||||
|
}
|
||||||
return compRef;
|
return compRef;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,21 +1,23 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import { getChildDebugElement } from 'tests/helpers';
|
import { getChildDebugElement } from 'tests/helpers';
|
||||||
import {Component, provide} from 'angular2/core';
|
import { Component, provide } from '@angular/core';
|
||||||
import {DynamicComponentLoader} from 'angular2/src/core/linker/dynamic_component_loader';
|
import { DynamicComponentLoader } from '@angular/core';
|
||||||
import {BrowserDomAdapter} from 'angular2/platform/browser';
|
import { BrowserDomAdapter } from '@angular/platform-browser/src/browser/browser_adapter';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
TestComponentBuilder,
|
|
||||||
inject,
|
inject,
|
||||||
beforeEach,
|
beforeEach,
|
||||||
beforeEachProviders,
|
beforeEachProviders,
|
||||||
it
|
it
|
||||||
} from 'angular2/testing';
|
} from '@angular/core/testing';
|
||||||
|
|
||||||
import JsonSchemaLazy from 'lib/components/JsonSchema/json-schema-lazy';
|
import { TestComponentBuilder } from '@angular/compiler/testing';
|
||||||
|
|
||||||
|
|
||||||
|
import { JsonSchemaLazy } from 'lib/components/JsonSchema/json-schema-lazy';
|
||||||
import SchemaManager from 'lib/utils/SchemaManager';
|
import SchemaManager from 'lib/utils/SchemaManager';
|
||||||
import OptionsManager from 'lib/options';
|
import { OptionsService } from 'lib/services/index';
|
||||||
|
|
||||||
describe('Redoc components', () => {
|
describe('Redoc components', () => {
|
||||||
describe('JsonSchemaLazy Component', () => {
|
describe('JsonSchemaLazy Component', () => {
|
||||||
|
@ -31,7 +33,7 @@ describe('Redoc components', () => {
|
||||||
beforeEachProviders(() => [
|
beforeEachProviders(() => [
|
||||||
provide(SchemaManager, {useValue: schemaMgr}),
|
provide(SchemaManager, {useValue: schemaMgr}),
|
||||||
provide(BrowserDomAdapter, {useClass: BrowserDomAdapter}),
|
provide(BrowserDomAdapter, {useClass: BrowserDomAdapter}),
|
||||||
provide(OptionsManager, {useClass: OptionsManager})
|
provide(OptionsService, {useClass: OptionsService})
|
||||||
]);
|
]);
|
||||||
beforeEach(inject([TestComponentBuilder, DynamicComponentLoader], (tcb, dcl) => {
|
beforeEach(inject([TestComponentBuilder, DynamicComponentLoader], (tcb, dcl) => {
|
||||||
builder = tcb;
|
builder = tcb;
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import {ElementRef} from 'angular2/core';
|
import { ElementRef } from '@angular/core';
|
||||||
|
|
||||||
import {RedocComponent, BaseComponent, SchemaManager} from '../base';
|
import { RedocComponent, BaseComponent, SchemaManager } from '../base';
|
||||||
import {DropDown} from '../../common/components/DropDown/dropdown';
|
import { DropDown } from '../../shared/components/index';
|
||||||
import JsonPointer from '../../utils/JsonPointer';
|
import JsonPointer from '../../utils/JsonPointer';
|
||||||
|
|
||||||
@RedocComponent({
|
@RedocComponent({
|
||||||
|
@ -14,7 +14,7 @@ import JsonPointer from '../../utils/JsonPointer';
|
||||||
inputs: ['isArray', 'final', 'nestOdd', 'childFor', 'skipReadOnly']
|
inputs: ['isArray', 'final', 'nestOdd', 'childFor', 'skipReadOnly']
|
||||||
})
|
})
|
||||||
@Reflect.metadata('parameters', [[SchemaManager], [ElementRef]])
|
@Reflect.metadata('parameters', [[SchemaManager], [ElementRef]])
|
||||||
export default class JsonSchema extends BaseComponent {
|
export class JsonSchema extends BaseComponent {
|
||||||
constructor(schemaMgr, elementRef) {
|
constructor(schemaMgr, elementRef) {
|
||||||
super(schemaMgr);
|
super(schemaMgr);
|
||||||
this.$element = elementRef.nativeElement;
|
this.$element = elementRef.nativeElement;
|
||||||
|
@ -109,7 +109,7 @@ export default class JsonSchema extends BaseComponent {
|
||||||
props = props || [];
|
props = props || [];
|
||||||
|
|
||||||
if (schema.additionalProperties && schema.additionalProperties !== false) {
|
if (schema.additionalProperties && schema.additionalProperties !== false) {
|
||||||
let propsSchema = this.prepareAdditionalProperties(schema.additionalProperties);
|
let propsSchema = this.prepareAdditionalProperties(schema);
|
||||||
propsSchema._additional = true;
|
propsSchema._additional = true;
|
||||||
props.push(propsSchema);
|
props.push(propsSchema);
|
||||||
}
|
}
|
||||||
|
@ -126,8 +126,9 @@ export default class JsonSchema extends BaseComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
prepareAdditionalProperties(schema) {
|
prepareAdditionalProperties(schema) {
|
||||||
return JsonSchema.injectPropertyData(schema, '<Additional Properties> *',
|
var addProps = schema.additionalProperties;
|
||||||
JsonPointer.join(schema._pointer || this.pointer, ['additionalProperties']));
|
return JsonSchema.injectPropertyData(addProps, '<Additional Properties> *',
|
||||||
|
JsonPointer.join(addProps._pointer || schema._pointer || this.pointer, ['additionalProperties']));
|
||||||
}
|
}
|
||||||
|
|
||||||
static injectPropertyData(propertySchema, propertyName, propPointer) {
|
static injectPropertyData(propertySchema, propertyName, propPointer) {
|
||||||
|
|
|
@ -1,18 +1,19 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import { getChildDebugElement } from 'tests/helpers';
|
import { Component, provide } from '@angular/core';
|
||||||
import {Component, provide} from 'angular2/core';
|
|
||||||
import OptionsManager from 'lib/options';
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
TestComponentBuilder,
|
|
||||||
inject,
|
inject,
|
||||||
beforeEach,
|
beforeEach,
|
||||||
beforeEachProviders,
|
beforeEachProviders,
|
||||||
it
|
it
|
||||||
} from 'angular2/testing';
|
} from '@angular/core/testing';
|
||||||
|
import { TestComponentBuilder } from '@angular/compiler/testing';
|
||||||
|
|
||||||
import JsonSchema from 'lib/components/JsonSchema/json-schema';
|
import { OptionsService } from 'lib/services/index';
|
||||||
|
import { getChildDebugElement } from 'tests/helpers';
|
||||||
|
|
||||||
|
|
||||||
|
import { JsonSchema } from 'lib/components/JsonSchema/json-schema';
|
||||||
import SchemaManager from 'lib/utils/SchemaManager';
|
import SchemaManager from 'lib/utils/SchemaManager';
|
||||||
|
|
||||||
describe('Redoc components', () => {
|
describe('Redoc components', () => {
|
||||||
|
@ -23,7 +24,7 @@ describe('Redoc components', () => {
|
||||||
let fixture;
|
let fixture;
|
||||||
beforeEachProviders(() => [
|
beforeEachProviders(() => [
|
||||||
provide(SchemaManager, {useValue: schemaMgr}),
|
provide(SchemaManager, {useValue: schemaMgr}),
|
||||||
provide(OptionsManager, {useClass: OptionsManager})
|
provide(OptionsService, {useClass: OptionsService})
|
||||||
]);
|
]);
|
||||||
beforeEach(inject([TestComponentBuilder], (tcb) => {
|
beforeEach(inject([TestComponentBuilder], (tcb) => {
|
||||||
builder = tcb;
|
builder = tcb;
|
||||||
|
|
|
@ -16,11 +16,11 @@
|
||||||
<h5>Definition</h5>
|
<h5>Definition</h5>
|
||||||
<span class="method-endpoint">
|
<span class="method-endpoint">
|
||||||
<h5 class="http-method" [ngClass]="data.httpMethod">{{data.httpMethod}}</h5>
|
<h5 class="http-method" [ngClass]="data.httpMethod">{{data.httpMethod}}</h5>
|
||||||
<span class="api-url">{{data.apiUrl}}</span> <span class="path">{{data.path}}</span>
|
<span class="api-url">{{data.apiUrl}}</span><span class="path">{{data.path}}</span>
|
||||||
</span>
|
</span>
|
||||||
<div *ngIf="data.bodyParam">
|
<div *ngIf="data.bodyParam">
|
||||||
<br>
|
<br>
|
||||||
<request-samples [pointer]="pointer" [bodySchemaPtr]="data.bodyParam._pointer">
|
<request-samples [pointer]="pointer" [schemaPointer]="data.bodyParam._pointer">
|
||||||
</request-samples>
|
</request-samples>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
|
|
|
@ -1,22 +1,22 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import {JsonPointer} from '../../utils/JsonPointer';
|
import { JsonPointer } from '../../utils/JsonPointer';
|
||||||
import {RedocComponent, BaseComponent} from '../base';
|
import { RedocComponent, BaseComponent } from '../base';
|
||||||
|
|
||||||
import ParamsList from '../ParamsList/params-list';
|
import { ParamsList } from '../ParamsList/params-list';
|
||||||
import ResponsesList from '../ResponsesList/responses-list';
|
import { ResponsesList } from '../ResponsesList/responses-list';
|
||||||
import ResponsesSamples from '../ResponsesSamples/responses-samples';
|
import { ResponsesSamples } from '../ResponsesSamples/responses-samples';
|
||||||
import SchemaSample from '../SchemaSample/schema-sample';
|
import { SchemaSample } from '../SchemaSample/schema-sample';
|
||||||
import RequestSamples from '../RequestSamples/request-samples';
|
import { RequestSamples } from '../RequestSamples/request-samples';
|
||||||
|
|
||||||
@RedocComponent({
|
@RedocComponent({
|
||||||
selector: 'method',
|
selector: 'method',
|
||||||
templateUrl: './lib/components/Method/method.html',
|
templateUrl: './lib/components/Method/method.html',
|
||||||
styleUrls: ['./lib/components/Method/method.css'],
|
styleUrls: ['./lib/components/Method/method.css'],
|
||||||
directives: [ParamsList, ResponsesList, ResponsesSamples, SchemaSample, RequestSamples],
|
directives: [ ParamsList, ResponsesList, ResponsesSamples, SchemaSample, RequestSamples ],
|
||||||
inputs: ['tag']
|
inputs: ['tag']
|
||||||
})
|
})
|
||||||
export default class Method extends BaseComponent {
|
export class Method extends BaseComponent {
|
||||||
constructor(schemaMgr) {
|
constructor(schemaMgr) {
|
||||||
super(schemaMgr);
|
super(schemaMgr);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
@import '../../common/styles/variables';
|
@import '../../shared/styles/variables';
|
||||||
@import '../../common/styles/share-link';
|
@import '../../shared/styles/share-link';
|
||||||
|
|
||||||
:host {
|
:host {
|
||||||
padding-bottom: 100px;
|
padding-bottom: 100px;
|
||||||
|
|
|
@ -1,21 +1,21 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import { getChildDebugElement } from 'tests/helpers';
|
import { Component, provide } from '@angular/core';
|
||||||
import {Component, provide} from 'angular2/core';
|
import { BrowserDomAdapter } from '@angular/platform-browser/src/browser/browser_adapter';
|
||||||
import {BrowserDomAdapter} from 'angular2/platform/browser';
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
TestComponentBuilder,
|
|
||||||
async,
|
|
||||||
inject,
|
inject,
|
||||||
|
async,
|
||||||
beforeEach,
|
beforeEach,
|
||||||
beforeEachProviders,
|
beforeEachProviders,
|
||||||
it
|
it
|
||||||
} from 'angular2/testing';
|
} from '@angular/core/testing';
|
||||||
|
import { TestComponentBuilder } from '@angular/compiler/testing';
|
||||||
|
|
||||||
import Method from 'lib/components/Method/method';
|
import { getChildDebugElement } from 'tests/helpers';
|
||||||
|
|
||||||
|
import { Method } from 'lib/components/Method/method';
|
||||||
import SchemaManager from 'lib/utils/SchemaManager';
|
import SchemaManager from 'lib/utils/SchemaManager';
|
||||||
import OptionsManager from 'lib/options';
|
import { OptionsService, RedocEventsService } from 'lib/services/index';
|
||||||
|
|
||||||
describe('Redoc components', () => {
|
describe('Redoc components', () => {
|
||||||
describe('Method Component', () => {
|
describe('Method Component', () => {
|
||||||
|
@ -24,7 +24,8 @@ describe('Redoc components', () => {
|
||||||
beforeEachProviders(() => [
|
beforeEachProviders(() => [
|
||||||
provide(SchemaManager, {useValue: new SchemaManager()}),
|
provide(SchemaManager, {useValue: new SchemaManager()}),
|
||||||
provide(BrowserDomAdapter, {useClass: BrowserDomAdapter}),
|
provide(BrowserDomAdapter, {useClass: BrowserDomAdapter}),
|
||||||
provide(OptionsManager, {useClass: OptionsManager})
|
provide(OptionsService, {useClass: OptionsService}),
|
||||||
|
provide(RedocEventsService, {useClass: RedocEventsService})
|
||||||
]);
|
]);
|
||||||
beforeEach(async(inject([TestComponentBuilder, SchemaManager], (tcb, schemaMgr) => {
|
beforeEach(async(inject([TestComponentBuilder, SchemaManager], (tcb, schemaMgr) => {
|
||||||
builder = tcb;
|
builder = tcb;
|
||||||
|
|
|
@ -1,17 +1,18 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import {RedocComponent, BaseComponent} from '../base';
|
import { forwardRef } from '@angular/core';
|
||||||
import Method from '../Method/method';
|
import { RedocComponent, BaseComponent } from '../base';
|
||||||
import {EncodeURIComponentPipe} from '../../utils/pipes';
|
import { Method } from '../Method/method';
|
||||||
|
import { EncodeURIComponentPipe } from '../../utils/pipes';
|
||||||
|
|
||||||
@RedocComponent({
|
@RedocComponent({
|
||||||
selector: 'methods-list',
|
selector: 'methods-list',
|
||||||
templateUrl: './lib/components/MethodsList/methods-list.html',
|
templateUrl: './lib/components/MethodsList/methods-list.html',
|
||||||
styleUrls: ['./lib/components/MethodsList/methods-list.css'],
|
styleUrls: ['./lib/components/MethodsList/methods-list.css'],
|
||||||
directives: [Method],
|
directives: [ forwardRef(() => Method) ],
|
||||||
pipes: [EncodeURIComponentPipe]
|
pipes: [ EncodeURIComponentPipe ]
|
||||||
})
|
})
|
||||||
export default class MethodsList extends BaseComponent {
|
export class MethodsList extends BaseComponent {
|
||||||
|
|
||||||
constructor(schemaMgr) {
|
constructor(schemaMgr) {
|
||||||
super(schemaMgr);
|
super(schemaMgr);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
@import '../../common/styles/variables';
|
@import '../../shared/styles/variables';
|
||||||
@import '../../common/styles/share-link';
|
@import '../../shared/styles/share-link';
|
||||||
|
|
||||||
.tag-info {
|
.tag-info {
|
||||||
padding: 40px;
|
padding: 40px;
|
||||||
|
|
|
@ -1,20 +1,20 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import { getChildDebugElement } from 'tests/helpers';
|
import { Component, provide } from '@angular/core';
|
||||||
import {Component, provide} from 'angular2/core';
|
import { BrowserDomAdapter } from '@angular/platform-browser/src/browser/browser_adapter';
|
||||||
import OptionsManager from 'lib/options';
|
|
||||||
import {BrowserDomAdapter} from 'angular2/platform/browser';
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
TestComponentBuilder,
|
|
||||||
inject,
|
inject,
|
||||||
async,
|
async,
|
||||||
beforeEach,
|
beforeEach,
|
||||||
beforeEachProviders,
|
beforeEachProviders,
|
||||||
it
|
it
|
||||||
} from 'angular2/testing';
|
} from '@angular/core/testing';
|
||||||
|
import { TestComponentBuilder } from '@angular/compiler/testing';
|
||||||
|
|
||||||
import MethodsList from 'lib/components/MethodsList/methods-list';
|
import { getChildDebugElement } from 'tests/helpers';
|
||||||
|
|
||||||
|
import { OptionsService, RedocEventsService } from 'lib/services/index';
|
||||||
|
import { MethodsList } from 'lib/components/MethodsList/methods-list';
|
||||||
import SchemaManager from 'lib/utils/SchemaManager';
|
import SchemaManager from 'lib/utils/SchemaManager';
|
||||||
|
|
||||||
describe('Redoc components', () => {
|
describe('Redoc components', () => {
|
||||||
|
@ -24,8 +24,9 @@ describe('Redoc components', () => {
|
||||||
let fixture;
|
let fixture;
|
||||||
beforeEachProviders(() => [
|
beforeEachProviders(() => [
|
||||||
provide(SchemaManager, {useValue: new SchemaManager()}),
|
provide(SchemaManager, {useValue: new SchemaManager()}),
|
||||||
provide(OptionsManager, {useClass: OptionsManager}),
|
provide(OptionsService, {useClass: OptionsService}),
|
||||||
provide(BrowserDomAdapter, {useClass: BrowserDomAdapter})
|
provide(BrowserDomAdapter, {useClass: BrowserDomAdapter}),
|
||||||
|
provide(RedocEventsService, {useClass: RedocEventsService})
|
||||||
]);
|
]);
|
||||||
beforeEach(async(inject([TestComponentBuilder, SchemaManager], (tcb, schemaMgr) => {
|
beforeEach(async(inject([TestComponentBuilder, SchemaManager], (tcb, schemaMgr) => {
|
||||||
builder = tcb;
|
builder = tcb;
|
||||||
|
@ -56,11 +57,9 @@ describe('Redoc components', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
/** Test component that contains an ApiInfo. */
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'test-app',
|
selector: 'test-app',
|
||||||
directives: [MethodsList],
|
directives: [ MethodsList ],
|
||||||
providers: [SchemaManager],
|
|
||||||
template:
|
template:
|
||||||
`<methods-list></methods-list>`
|
`<methods-list></methods-list>`
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import {RedocComponent, BaseComponent} from '../base';
|
import { RedocComponent, BaseComponent } from '../base';
|
||||||
import JsonSchema from '../JsonSchema/json-schema';
|
import { JsonSchema } from '../JsonSchema/json-schema';
|
||||||
import JsonSchemaLazy from '../JsonSchema/json-schema-lazy';
|
import {JsonSchemaLazy} from '../JsonSchema/json-schema-lazy';
|
||||||
|
|
||||||
function safePush(obj, prop, item) {
|
function safePush(obj, prop, item) {
|
||||||
if (!obj[prop]) obj[prop] = [];
|
if (!obj[prop]) obj[prop] = [];
|
||||||
|
@ -15,7 +15,7 @@ function safePush(obj, prop, item) {
|
||||||
styleUrls: ['./lib/components/ParamsList/params-list.css'],
|
styleUrls: ['./lib/components/ParamsList/params-list.css'],
|
||||||
directives: [JsonSchema, JsonSchemaLazy]
|
directives: [JsonSchema, JsonSchemaLazy]
|
||||||
})
|
})
|
||||||
export default class ParamsList extends BaseComponent {
|
export class ParamsList extends BaseComponent {
|
||||||
constructor(schemaMgr) {
|
constructor(schemaMgr) {
|
||||||
super(schemaMgr);
|
super(schemaMgr);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
@import '../../common/styles/variables';
|
@import '../../shared/styles/variables';
|
||||||
|
|
||||||
$hint-color: #999999;
|
$hint-color: #999999;
|
||||||
|
|
||||||
|
|
|
@ -1,20 +1,20 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import {ChangeDetectionStrategy, provide, enableProdMode} from 'angular2/core';
|
import { provide, enableProdMode, ElementRef } from '@angular/core';
|
||||||
import {ElementRef} from 'angular2/core';
|
import { bootstrap } from '@angular/platform-browser-dynamic';
|
||||||
import {BrowserDomAdapter, bootstrap} from 'angular2/platform/browser';
|
import { BrowserDomAdapter } from '@angular/platform-browser/src/browser/browser_adapter';
|
||||||
import detectScollParent from 'scrollparent';
|
import { RedocComponent, BaseComponent } from '../base';
|
||||||
import {RedocComponent, BaseComponent} from '../base';
|
|
||||||
|
import { ApiInfo } from '../ApiInfo/api-info';
|
||||||
|
import { ApiLogo } from '../ApiLogo/api-logo';
|
||||||
|
import { MethodsList } from '../MethodsList/methods-list';
|
||||||
|
import { SideMenu } from '../SideMenu/side-menu';
|
||||||
|
|
||||||
|
import { StickySidebar } from '../../shared/components/index';
|
||||||
import SchemaManager from '../../utils/SchemaManager';
|
import SchemaManager from '../../utils/SchemaManager';
|
||||||
|
import { OptionsService, RedocEventsService } from '../../services/index';
|
||||||
|
|
||||||
import ApiInfo from '../ApiInfo/api-info';
|
import detectScollParent from 'scrollparent';
|
||||||
import ApiLogo from '../ApiLogo/api-logo';
|
|
||||||
import MethodsList from '../MethodsList/methods-list';
|
|
||||||
import SideMenu from '../SideMenu/side-menu';
|
|
||||||
import StickySidebar from '../../common/components/StickySidebar/sticky-sidebar';
|
|
||||||
import OptionsManager from '../../options';
|
|
||||||
import {redocEvents} from '../../events';
|
|
||||||
|
|
||||||
import './redoc-loading-styles.css!css';
|
import './redoc-loading-styles.css!css';
|
||||||
|
|
||||||
var dom = new BrowserDomAdapter();
|
var dom = new BrowserDomAdapter();
|
||||||
|
@ -24,23 +24,30 @@ var _modeLocked = false;
|
||||||
selector: 'redoc',
|
selector: 'redoc',
|
||||||
providers: [
|
providers: [
|
||||||
SchemaManager,
|
SchemaManager,
|
||||||
BrowserDomAdapter
|
BrowserDomAdapter,
|
||||||
|
RedocEventsService
|
||||||
],
|
],
|
||||||
templateUrl: './lib/components/Redoc/redoc.html',
|
templateUrl: './lib/components/Redoc/redoc.html',
|
||||||
styleUrls: ['./lib/components/Redoc/redoc.css'],
|
styleUrls: ['./lib/components/Redoc/redoc.css'],
|
||||||
directives: [ApiInfo, ApiLogo, MethodsList, SideMenu, StickySidebar],
|
directives: [ ApiInfo, ApiLogo, MethodsList, SideMenu, StickySidebar ]
|
||||||
changeDetection: ChangeDetectionStrategy.Default
|
|
||||||
})
|
})
|
||||||
@Reflect.metadata('parameters', [
|
@Reflect.metadata('parameters', [
|
||||||
[SchemaManager], [OptionsManager], [ElementRef]])
|
[SchemaManager], [OptionsService], [ElementRef], [RedocEventsService]])
|
||||||
export default class Redoc extends BaseComponent {
|
export class Redoc extends BaseComponent {
|
||||||
constructor(schemaMgr, optionsMgr, elementRef) {
|
constructor(schemaMgr, optionsMgr, elementRef, events) {
|
||||||
super(schemaMgr);
|
super(schemaMgr);
|
||||||
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 );
|
||||||
optionsMgr.options.$scrollParent = detectScollParent( this.element );
|
optionsMgr.options.$scrollParent = detectScollParent( this.element );
|
||||||
this.options = optionsMgr.options;
|
this.options = optionsMgr.options;
|
||||||
|
this.events = events;
|
||||||
|
}
|
||||||
|
|
||||||
|
ngAfterViewInit() {
|
||||||
|
setTimeout( () => {
|
||||||
|
this.events.bootstrapped.next();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
static showLoadingAnimation() {
|
static showLoadingAnimation() {
|
||||||
|
@ -58,11 +65,11 @@ export default class Redoc extends BaseComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
static init(specUrl, options) {
|
static init(specUrl, options) {
|
||||||
var optionsMgr = new OptionsManager();
|
var optionsService = new OptionsService(dom);
|
||||||
optionsMgr.options = options;
|
optionsService.options = options;
|
||||||
optionsMgr.options.specUrl = optionsMgr.options.specUrl || specUrl;
|
optionsService.options.specUrl = optionsService.options.specUrl || specUrl;
|
||||||
var providers = [
|
var providers = [
|
||||||
provide(OptionsManager, {useValue: optionsMgr})
|
provide(OptionsService, {useValue: optionsService})
|
||||||
];
|
];
|
||||||
|
|
||||||
if (Redoc.appRef) {
|
if (Redoc.appRef) {
|
||||||
|
@ -71,7 +78,7 @@ export default class Redoc extends BaseComponent {
|
||||||
Redoc.showLoadingAnimation();
|
Redoc.showLoadingAnimation();
|
||||||
return SchemaManager.instance().load(specUrl)
|
return SchemaManager.instance().load(specUrl)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
if (!_modeLocked && !optionsMgr.options.debugMode) {
|
if (!_modeLocked && !optionsService.options.debugMode) {
|
||||||
enableProdMode();
|
enableProdMode();
|
||||||
_modeLocked = true;
|
_modeLocked = true;
|
||||||
}
|
}
|
||||||
|
@ -81,8 +88,6 @@ export default class Redoc extends BaseComponent {
|
||||||
(appRef) => {
|
(appRef) => {
|
||||||
Redoc.hideLoadingAnimation();
|
Redoc.hideLoadingAnimation();
|
||||||
Redoc.appRef = appRef;
|
Redoc.appRef = appRef;
|
||||||
// setTimeout to allow cached elements to init
|
|
||||||
setTimeout(() => redocEvents.bootstrapped.next());
|
|
||||||
console.log('ReDoc bootstrapped!');
|
console.log('ReDoc bootstrapped!');
|
||||||
},
|
},
|
||||||
error => {
|
error => {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
@import '../../common/styles/variables';
|
@import '../../shared/styles/variables';
|
||||||
|
|
||||||
:host {
|
:host {
|
||||||
display: block;
|
display: block;
|
||||||
|
|
|
@ -1,23 +1,24 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import { getChildDebugElement } from 'tests/helpers';
|
import { getChildDebugElement } from 'tests/helpers';
|
||||||
import {Component, ViewMetadata, provide} from 'angular2/core';
|
import { Component, provide } from '@angular/core';
|
||||||
import {BrowserDomAdapter} from 'angular2/platform/browser';
|
import { BrowserDomAdapter } from '@angular/platform-browser/src/browser/browser_adapter';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
TestComponentBuilder,
|
|
||||||
inject,
|
inject,
|
||||||
async,
|
async,
|
||||||
beforeEach,
|
beforeEach,
|
||||||
beforeEachProviders,
|
beforeEachProviders,
|
||||||
it
|
it
|
||||||
} from 'angular2/testing';
|
} from '@angular/core/testing';
|
||||||
|
|
||||||
import Redoc from 'lib/components/Redoc/redoc';
|
import { TestComponentBuilder } from '@angular/compiler/testing';
|
||||||
|
|
||||||
|
import { Redoc } from 'lib/components/Redoc/redoc';
|
||||||
import SchemaManager from 'lib/utils/SchemaManager';
|
import SchemaManager from 'lib/utils/SchemaManager';
|
||||||
import OptionsManager from 'lib/options';
|
import { OptionsService } from 'lib/services/index';
|
||||||
|
|
||||||
let optsMgr = new OptionsManager();
|
let optsMgr = new OptionsService(new BrowserDomAdapter());
|
||||||
|
|
||||||
describe('Redoc components', () => {
|
describe('Redoc components', () => {
|
||||||
describe('Redoc Component', () => {
|
describe('Redoc Component', () => {
|
||||||
|
@ -25,7 +26,10 @@ describe('Redoc components', () => {
|
||||||
beforeEachProviders(() => [
|
beforeEachProviders(() => [
|
||||||
provide(SchemaManager, {useValue: new SchemaManager()}),
|
provide(SchemaManager, {useValue: new SchemaManager()}),
|
||||||
provide(BrowserDomAdapter, {useValue: new BrowserDomAdapter()}),
|
provide(BrowserDomAdapter, {useValue: new BrowserDomAdapter()}),
|
||||||
provide(OptionsManager, {useValue: optsMgr})
|
provide(OptionsService, {useValue: optsMgr})
|
||||||
|
]);
|
||||||
|
beforeEachProviders(() => [
|
||||||
|
provide(OptionsService, {useValue: optsMgr})
|
||||||
]);
|
]);
|
||||||
beforeEach(async(inject([TestComponentBuilder, SchemaManager], (tcb, schemaMgr) => {
|
beforeEach(async(inject([TestComponentBuilder, SchemaManager], (tcb, schemaMgr) => {
|
||||||
builder = tcb;
|
builder = tcb;
|
||||||
|
@ -49,62 +53,6 @@ describe('Redoc components', () => {
|
||||||
done();
|
done();
|
||||||
}, err => done.fail(err));
|
}, err => done.fail(err));
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Options', () => {
|
|
||||||
let component;
|
|
||||||
let fixture;
|
|
||||||
|
|
||||||
function build(tmpl, cb) {
|
|
||||||
builder = builder.overrideView(TestApp,
|
|
||||||
new ViewMetadata({template: tmpl, directives: [Redoc]}));
|
|
||||||
builder.createAsync(TestApp).then(_fixture => {
|
|
||||||
fixture = _fixture;
|
|
||||||
component = getChildDebugElement(fixture.debugElement, 'redoc').componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
cb();
|
|
||||||
}, err => cb(err));
|
|
||||||
}
|
|
||||||
|
|
||||||
afterEach(() => {
|
|
||||||
fixture.destroy();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should parse numeric scrollYOffset', (done) => {
|
|
||||||
build(`<redoc scroll-y-offset="50"></redoc>`, err => {
|
|
||||||
if (err) return done.fail(err);
|
|
||||||
component.options.scrollYOffset().should.be.equal(50);
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should parse selector scrollYOffset', (done) => {
|
|
||||||
build(`<div id="test" style="position: fixed; height: 50px; top:0"> </div>
|
|
||||||
<redoc scroll-y-offset="#test"></redoc>`, err => {
|
|
||||||
if (err) return done.fail(err);
|
|
||||||
component.options.scrollYOffset().should.be.equal(50);
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return 0 for incorrect selector scrollYOffset', (done) => {
|
|
||||||
build(`<div id="test" style="position: fixed; height: 50px; top:0"> </div>
|
|
||||||
<redoc scroll-y-offset="#test2"></redoc>`, err => {
|
|
||||||
if (err) return done.fail(err);
|
|
||||||
component.options.scrollYOffset().should.be.equal(0);
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should handle function scrollYOffset', (done) => {
|
|
||||||
optsMgr.options.scrollYOffset = () => 123;
|
|
||||||
build(`<redoc></redoc>`, err => {
|
|
||||||
if (err) return done.fail(err);
|
|
||||||
component.options.scrollYOffset().should.be.equal(123);
|
|
||||||
optsMgr.options.scrollYOffset = 0;
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Redoc init', () => {
|
describe('Redoc init', () => {
|
||||||
|
@ -151,7 +99,7 @@ describe('Redoc components', () => {
|
||||||
beforeEachProviders(() => [
|
beforeEachProviders(() => [
|
||||||
provide(SchemaManager, {useValue: new SchemaManager()}),
|
provide(SchemaManager, {useValue: new SchemaManager()}),
|
||||||
provide(BrowserDomAdapter, {useValue: new BrowserDomAdapter()}),
|
provide(BrowserDomAdapter, {useValue: new BrowserDomAdapter()}),
|
||||||
provide(OptionsManager, {useValue: optsMgr})
|
provide(OptionsService, {useValue: optsMgr})
|
||||||
]);
|
]);
|
||||||
beforeEach(async(inject([TestComponentBuilder, SchemaManager], (tcb, schemaMgr) => {
|
beforeEach(async(inject([TestComponentBuilder, SchemaManager], (tcb, schemaMgr) => {
|
||||||
builder = tcb;
|
builder = tcb;
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
<header *ngIf="data.bodySchemaPtr || data.samples.length"> Request samples </header>
|
<header *ngIf="data.schemaPointer || data.samples.length"> Request samples </header>
|
||||||
<schema-sample *ngIf="!data.samples.length" [pointer]="data.bodySchemaPtr"> </schema-sample>
|
<schema-sample *ngIf="!data.samples.length" [pointer]="data.schemaPointer"> </schema-sample>
|
||||||
<tabs *ngIf="data.samples.length" (change)=changeLangNotify($event)>
|
<tabs *ngIf="data.samples.length" (change)=changeLangNotify($event)>
|
||||||
<tab tabTitle="JSON">
|
<tab tabTitle="JSON">
|
||||||
<schema-sample [pointer]="data.bodySchemaPtr"> </schema-sample>
|
<schema-sample [pointer]="data.schemaPointer"> </schema-sample>
|
||||||
</tab>
|
</tab>
|
||||||
<tab *ngFor="let sample of data.samples" [tabTitle]="sample.lang">
|
<tab *ngFor="let sample of data.samples" [tabTitle]="sample.lang">
|
||||||
<pre innerHtml="{{sample.source | prism:sample.lang}}"></pre>
|
<pre innerHtml="{{sample.source | prism:sample.lang}}"></pre>
|
||||||
|
|
|
@ -1,49 +1,50 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import {ViewChildren, QueryList, ChangeDetectorRef, ChangeDetectionStrategy} from 'angular2/core';
|
import { ViewChildren, QueryList } from '@angular/core';
|
||||||
|
|
||||||
import {RedocComponent, BaseComponent, SchemaManager} from '../base';
|
import { RedocComponent, BaseComponent, SchemaManager } from '../base';
|
||||||
import JsonPointer from '../../utils/JsonPointer';
|
import JsonPointer from '../../utils/JsonPointer';
|
||||||
import {Tabs, Tab} from '../../common/components/Tabs/tabs';
|
import { Tabs, Tab } from '../../shared/components/index';
|
||||||
import SchemaSample from '../SchemaSample/schema-sample';
|
import { SchemaSample } from '../SchemaSample/schema-sample';
|
||||||
import {PrismPipe} from '../../utils/pipes';
|
import { PrismPipe } from '../../utils/pipes';
|
||||||
import {redocEvents} from '../../events';
|
import { RedocEventsService } from '../../services/index';
|
||||||
|
|
||||||
@RedocComponent({
|
@RedocComponent({
|
||||||
selector: 'request-samples',
|
selector: 'request-samples',
|
||||||
templateUrl: './lib/components/RequestSamples/request-samples.html',
|
templateUrl: './lib/components/RequestSamples/request-samples.html',
|
||||||
styleUrls: ['./lib/components/RequestSamples/request-samples.css'],
|
styleUrls: ['./lib/components/RequestSamples/request-samples.css'],
|
||||||
directives: [SchemaSample, Tabs, Tab],
|
directives: [SchemaSample, Tabs, Tab],
|
||||||
inputs: ['bodySchemaPtr'],
|
inputs: ['schemaPointer'],
|
||||||
pipes: [PrismPipe],
|
pipes: [PrismPipe]
|
||||||
changeDetection: ChangeDetectionStrategy.OnPush
|
|
||||||
})
|
})
|
||||||
@Reflect.metadata('parameters', [[SchemaManager], [new ViewChildren(Tabs), QueryList], [ChangeDetectorRef]])
|
@Reflect.metadata('parameters', [[SchemaManager], [RedocEventsService], [new ViewChildren(Tabs), QueryList]])
|
||||||
export default class RequestSamples extends BaseComponent {
|
export class RequestSamples extends BaseComponent {
|
||||||
constructor(schemaMgr, tabs, changeDetector) {
|
constructor(schemaMgr, events, childQuery) {
|
||||||
super(schemaMgr);
|
super(schemaMgr);
|
||||||
tabs.changes.subscribe(_ => {
|
childQuery.changes.subscribe(() => {
|
||||||
this.tabs = tabs.first;
|
this.childTabs = childQuery.first;
|
||||||
this.subscribeForEvents(_);
|
|
||||||
});
|
});
|
||||||
this.changeDetector = changeDetector;
|
this.events = events;
|
||||||
|
}
|
||||||
|
|
||||||
|
init() {
|
||||||
|
this.subscribeForEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
changeLangNotify(lang) {
|
changeLangNotify(lang) {
|
||||||
redocEvents.samplesLanguageChanged.next(lang);
|
this.events.samplesLanguageChanged.next(lang);
|
||||||
}
|
}
|
||||||
|
|
||||||
subscribeForEvents() {
|
subscribeForEvents() {
|
||||||
if (!this.tabs) return;
|
this.events.samplesLanguageChanged.subscribe((sampleLang) => {
|
||||||
redocEvents.samplesLanguageChanged.subscribe((sampleLang) => {
|
if (!this.childTabs) return;
|
||||||
this.tabs.selectyByTitle(sampleLang);
|
this.childTabs.selectyByTitle(sampleLang);
|
||||||
this.changeDetector.markForCheck();
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
prepareModel() {
|
prepareModel() {
|
||||||
this.data = {};
|
this.data = {};
|
||||||
this.data.bodySchemaPtr = JsonPointer.join(this.bodySchemaPtr, 'schema');
|
this.data.schemaPointer = JsonPointer.join(this.schemaPointer, 'schema');
|
||||||
this.data.samples = this.componentSchema['x-code-samples'] || [];
|
this.data.samples = this.componentSchema['x-code-samples'] || [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
@import '../../common/styles/variables';
|
@import '../../shared/styles/variables';
|
||||||
|
|
||||||
header {
|
header {
|
||||||
font-family: $headers-font;
|
font-family: $headers-font;
|
||||||
|
|
|
@ -2,11 +2,11 @@
|
||||||
|
|
||||||
import {RedocComponent, BaseComponent, SchemaManager} from '../base';
|
import {RedocComponent, BaseComponent, SchemaManager} from '../base';
|
||||||
import JsonPointer from '../../utils/JsonPointer';
|
import JsonPointer from '../../utils/JsonPointer';
|
||||||
import JsonSchema from '../JsonSchema/json-schema';
|
import { JsonSchema } from '../JsonSchema/json-schema';
|
||||||
import JsonSchemaLazy from '../JsonSchema/json-schema-lazy';
|
import { JsonSchemaLazy } from '../JsonSchema/json-schema-lazy';
|
||||||
import Zippy from '../../common/components/Zippy/zippy';
|
import { Zippy } from '../../shared/components/index';
|
||||||
import {statusCodeType} from '../../utils/helpers';
|
import { statusCodeType } from '../../utils/helpers';
|
||||||
import OptionsManager from '../../options';
|
import { OptionsService } from '../../services/index';
|
||||||
|
|
||||||
function isNumeric(n) {
|
function isNumeric(n) {
|
||||||
return (!isNaN(parseFloat(n)) && isFinite(n));
|
return (!isNaN(parseFloat(n)) && isFinite(n));
|
||||||
|
@ -18,8 +18,8 @@ function isNumeric(n) {
|
||||||
styleUrls: ['./lib/components/ResponsesList/responses-list.css'],
|
styleUrls: ['./lib/components/ResponsesList/responses-list.css'],
|
||||||
directives: [JsonSchema, Zippy, JsonSchemaLazy]
|
directives: [JsonSchema, Zippy, JsonSchemaLazy]
|
||||||
})
|
})
|
||||||
@Reflect.metadata('parameters', [[SchemaManager], [OptionsManager]])
|
@Reflect.metadata('parameters', [[SchemaManager], [OptionsService]])
|
||||||
export default class ResponsesList extends BaseComponent {
|
export class ResponsesList extends BaseComponent {
|
||||||
constructor(schemaMgr, optionsMgr) {
|
constructor(schemaMgr, optionsMgr) {
|
||||||
super(schemaMgr);
|
super(schemaMgr);
|
||||||
this.options = optionsMgr.options;
|
this.options = optionsMgr.options;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
@import '../../common/styles/variables';
|
@import '../../shared/styles/variables';
|
||||||
|
|
||||||
.responses-list-header {
|
.responses-list-header {
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import {RedocComponent, BaseComponent} from '../base';
|
import { forwardRef } from '@angular/core';
|
||||||
|
import { RedocComponent, BaseComponent } from '../base';
|
||||||
import JsonPointer from '../../utils/JsonPointer';
|
import JsonPointer from '../../utils/JsonPointer';
|
||||||
import {Tabs, Tab} from '../../common/components/Tabs/tabs';
|
import { Tabs, Tab } from '../../shared/components/index';
|
||||||
import SchemaSample from '../SchemaSample/schema-sample';
|
import { SchemaSample } from '../index';
|
||||||
import {statusCodeType} from '../../utils/helpers';
|
import { statusCodeType } from '../../utils/helpers';
|
||||||
|
|
||||||
|
|
||||||
function isNumeric(n) {
|
function isNumeric(n) {
|
||||||
|
@ -20,9 +21,9 @@ function hasExample(response) {
|
||||||
selector: 'responses-samples',
|
selector: 'responses-samples',
|
||||||
templateUrl: './lib/components/ResponsesSamples/responses-samples.html',
|
templateUrl: './lib/components/ResponsesSamples/responses-samples.html',
|
||||||
styleUrls: ['./lib/components/ResponsesSamples/responses-samples.css'],
|
styleUrls: ['./lib/components/ResponsesSamples/responses-samples.css'],
|
||||||
directives: [SchemaSample, Tabs, Tab]
|
directives: [forwardRef( ()=> SchemaSample), Tabs, Tab]
|
||||||
})
|
})
|
||||||
export default class ResponsesSamples extends BaseComponent {
|
export class ResponsesSamples extends BaseComponent {
|
||||||
constructor(schemaMgr) {
|
constructor(schemaMgr) {
|
||||||
super(schemaMgr);
|
super(schemaMgr);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
@import '../../common/styles/variables';
|
@import '../../shared/styles/variables';
|
||||||
|
|
||||||
tab, tabs {
|
tab, tabs {
|
||||||
display: block;
|
display: block;
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import {ElementRef} from 'angular2/core';
|
import { ElementRef } from '@angular/core';
|
||||||
|
|
||||||
import SchemaSampler from 'json-schema-instantiator';
|
import SchemaSampler from 'json-schema-instantiator';
|
||||||
|
|
||||||
import {JsonFormatter} from '../../utils/JsonFormatterPipe';
|
import { RedocComponent, BaseComponent, SchemaManager } from '../base';
|
||||||
import {RedocComponent, BaseComponent, SchemaManager} from '../base';
|
import { JsonFormatter } from '../../utils/JsonFormatterPipe';
|
||||||
|
|
||||||
@RedocComponent({
|
@RedocComponent({
|
||||||
selector: 'schema-sample',
|
selector: 'schema-sample',
|
||||||
|
@ -14,7 +14,7 @@ import {RedocComponent, BaseComponent, SchemaManager} from '../base';
|
||||||
styleUrls: ['./lib/components/SchemaSample/schema-sample.css']
|
styleUrls: ['./lib/components/SchemaSample/schema-sample.css']
|
||||||
})
|
})
|
||||||
@Reflect.metadata('parameters', [[SchemaManager], [ElementRef]])
|
@Reflect.metadata('parameters', [[SchemaManager], [ElementRef]])
|
||||||
export default class SchemaSample extends BaseComponent {
|
export class SchemaSample extends BaseComponent {
|
||||||
constructor(schemaMgr, elementRef) {
|
constructor(schemaMgr, elementRef) {
|
||||||
super(schemaMgr);
|
super(schemaMgr);
|
||||||
this.element = elementRef.nativeElement;
|
this.element = elementRef.nativeElement;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
@import '../../common/styles/variables';
|
@import '../../shared/styles/variables';
|
||||||
|
|
||||||
pre {
|
pre {
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
<div class="mobile-nav" (click)="toggleMobileNav()">
|
<div #mobile class="mobile-nav" (click)="toggleMobileNav()">
|
||||||
<span class="menu-header"> API Reference: </span>
|
<span class="menu-header"> API Reference: </span>
|
||||||
<span class="selected-item-info">
|
<span class="selected-item-info">
|
||||||
<span class="selected-tag"> {{activeCatCaption}} </span>
|
<span class="selected-tag"> {{activeCatCaption}} </span>
|
||||||
<span class="selected-endpoint">{{activeItemCaption}}</span>
|
<span class="selected-endpoint">{{activeItemCaption}}</span>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div id="resources-nav">
|
<div #desktop id="resources-nav">
|
||||||
<h5 class="menu-header"> API reference </h5>
|
<h5 class="menu-header"> API reference </h5>
|
||||||
<div *ngFor="let cat of data.menu; let idx = index" class="menu-cat">
|
<div *ngFor="let cat of data.menu; let idx = index" class="menu-cat">
|
||||||
|
|
||||||
|
|
|
@ -1,231 +1,70 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import {ChangeDetectorRef, ChangeDetectionStrategy, ElementRef} from 'angular2/core';
|
import { ElementRef, ChangeDetectorRef } from '@angular/core';
|
||||||
import {document} from 'angular2/src/facade/browser';
|
import { BrowserDomAdapter } from '@angular/platform-browser/src/browser/browser_adapter';
|
||||||
import {BrowserDomAdapter} from 'angular2/platform/browser';
|
import { global } from '@angular/core/src/facade/lang';
|
||||||
import {global} from 'angular2/src/facade/lang';
|
|
||||||
|
|
||||||
import {RedocComponent, BaseComponent, SchemaManager} from '../base';
|
import { RedocComponent, BaseComponent, SchemaManager } from '../base';
|
||||||
import {redocEvents} from '../../events';
|
import { ScrollService, Hash, MenuService, OptionsService } from '../../services/index';
|
||||||
import OptionsManager from '../../options';
|
|
||||||
|
|
||||||
const CHANGE = {
|
|
||||||
NEXT : 1,
|
|
||||||
BACK : -1,
|
|
||||||
INITIAL : 0
|
|
||||||
};
|
|
||||||
|
|
||||||
const INVIEW_POSITION = {
|
|
||||||
ABOVE : 1,
|
|
||||||
BELLOW: -1,
|
|
||||||
INVIEW: 0
|
|
||||||
};
|
|
||||||
|
|
||||||
@RedocComponent({
|
@RedocComponent({
|
||||||
selector: 'side-menu',
|
selector: 'side-menu',
|
||||||
templateUrl: './lib/components/SideMenu/side-menu.html',
|
templateUrl: './lib/components/SideMenu/side-menu.html',
|
||||||
styleUrls: ['./lib/components/SideMenu/side-menu.css'],
|
providers: [ScrollService, MenuService, Hash],
|
||||||
changeDetection: ChangeDetectionStrategy.Default
|
styleUrls: ['./lib/components/SideMenu/side-menu.css']
|
||||||
})
|
})
|
||||||
@Reflect.metadata('parameters', [[SchemaManager], [ElementRef],
|
@Reflect.metadata('parameters', [[SchemaManager], [ElementRef], [BrowserDomAdapter],
|
||||||
[BrowserDomAdapter], [ChangeDetectorRef], [OptionsManager]])
|
[ScrollService], [MenuService], [Hash], [OptionsService], [ChangeDetectorRef]])
|
||||||
export default class SideMenu extends BaseComponent {
|
export class SideMenu extends BaseComponent {
|
||||||
constructor(schemaMgr, elementRef, dom, changeDetectorRef, optionsMgr) {
|
constructor(schemaMgr, elementRef, dom, scrollService,
|
||||||
|
menuService, hash, optionsService, detectorRef) {
|
||||||
super(schemaMgr);
|
super(schemaMgr);
|
||||||
this.$element = elementRef.nativeElement;
|
this.$element = elementRef.nativeElement;
|
||||||
this.changeDetector = changeDetectorRef;
|
|
||||||
this.dom = dom;
|
this.dom = dom;
|
||||||
this.options = optionsMgr.options;
|
this.scrollService = scrollService;
|
||||||
this.$scrollParent = this.options.$scrollParent;
|
this.menuService = menuService;
|
||||||
this.bindEvents();
|
this.hash = hash;
|
||||||
this.activeCatIdx = 0;
|
|
||||||
this.activeMethodIdx = -1;
|
|
||||||
this.prevOffsetY = null;
|
|
||||||
|
|
||||||
redocEvents.bootstrapped.subscribe(() => this.hashScroll());
|
|
||||||
|
|
||||||
this.activeCatCaption = '';
|
this.activeCatCaption = '';
|
||||||
this.activeItemCaption = '';
|
this.activeItemCaption = '';
|
||||||
|
|
||||||
|
this.options = optionsService.options;
|
||||||
|
this.detectorRef = detectorRef;
|
||||||
|
|
||||||
|
this.menuService.changed.subscribe((cat, item) => this.changed(cat, item));
|
||||||
}
|
}
|
||||||
|
|
||||||
scrollY() {
|
changed(cat, item) {
|
||||||
return (this.$scrollParent.pageYOffset != null) ? this.$scrollParent.pageYOffset : this.$scrollParent.scrollTop;
|
this.activeCatCaption = cat.name || '';
|
||||||
}
|
this.activeItemCaption = item && item.summary || '';
|
||||||
|
|
||||||
hashScroll(evt) {
|
//safari doesn't update bindings if not run changeDetector manually :(
|
||||||
let hash = this.dom.getLocation().hash;
|
this.detectorRef.detectChanges();
|
||||||
if (!hash) return;
|
|
||||||
|
|
||||||
let $el;
|
|
||||||
hash = hash.substr(1);
|
|
||||||
let namespace = hash.split('/')[0];
|
|
||||||
let ptr = decodeURIComponent(hash.substr(namespace.length + 1));
|
|
||||||
if (namespace === 'operation') {
|
|
||||||
$el = this.getMethodElByOperId(ptr);
|
|
||||||
} else if (namespace === 'tag') {
|
|
||||||
let tag = ptr.split('/')[0];
|
|
||||||
ptr = ptr.substr(tag.length);
|
|
||||||
$el = this.getMethodElByPtr(ptr, tag);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($el) this.scrollTo($el);
|
|
||||||
if (evt) evt.preventDefault();
|
|
||||||
}
|
|
||||||
|
|
||||||
bindEvents() {
|
|
||||||
this.prevOffsetY = this.scrollY();
|
|
||||||
|
|
||||||
//decorate option.scrollYOffset to account mobile nav
|
|
||||||
this.scrollYOffset = () => {
|
|
||||||
let mobileNavOffset = this.$mobileNav.clientHeight;
|
|
||||||
return this.options.scrollYOffset() + mobileNavOffset;
|
|
||||||
};
|
|
||||||
this._cancel = {};
|
|
||||||
this._cancel.scroll = this.dom.onAndCancel(this.$scrollParent, 'scroll', () => { this.scrollHandler(); });
|
|
||||||
this._cancel.hash = this.dom.onAndCancel(global, 'hashchange', evt => this.hashScroll(evt));
|
|
||||||
}
|
|
||||||
|
|
||||||
destroy() {
|
|
||||||
this._cancel.scroll();
|
|
||||||
this._cancel.hash();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
activateAndScroll(idx, methodIdx) {
|
activateAndScroll(idx, methodIdx) {
|
||||||
if (this.mobileMode()) {
|
if (this.mobileMode()) {
|
||||||
this.toggleMobileNav();
|
this.toggleMobileNav();
|
||||||
}
|
}
|
||||||
this.activate(idx, methodIdx);
|
this.menuService.activate(idx, methodIdx);
|
||||||
this.scrollToActive();
|
this.menuService.scrollToActive();
|
||||||
}
|
}
|
||||||
|
|
||||||
scrollTo($el) {
|
init() {
|
||||||
// TODO: rewrite this to use offsetTop as more reliable solution
|
this.$mobileNav = this.dom.querySelector(this.$element, '.mobile-nav');
|
||||||
let subjRect = $el.getBoundingClientRect();
|
this.$resourcesNav = this.dom.querySelector(this.$element, '#resources-nav');
|
||||||
let offset = this.scrollY() + subjRect.top - this.scrollYOffset() + 1;
|
|
||||||
if (this.$scrollParent.scrollTo) {
|
|
||||||
this.$scrollParent.scrollTo(0, offset);
|
|
||||||
} else {
|
|
||||||
this.$scrollParent.scrollTop = offset;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
scrollToActive() {
|
//decorate option.scrollYOffset to account mobile nav
|
||||||
this.scrollTo(this.getCurrentMethodEl());
|
var origOffset = this.options.scrollYOffset;
|
||||||
}
|
this.options.scrollYOffset = () => {
|
||||||
|
let mobileNavOffset = this.$mobileNav.clientHeight;
|
||||||
activate(catIdx, methodIdx) {
|
return origOffset() + mobileNavOffset;
|
||||||
let menu = this.data.menu;
|
};
|
||||||
|
|
||||||
this.activeCatCaption = '';
|
|
||||||
this.activeItemCaption = '';
|
|
||||||
|
|
||||||
menu[this.activeCatIdx].active = false;
|
|
||||||
if (menu[this.activeCatIdx].methods.length) {
|
|
||||||
if (this.activeMethodIdx >= 0) {
|
|
||||||
menu[this.activeCatIdx].methods[this.activeMethodIdx].active = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.activeCatIdx = catIdx;
|
|
||||||
this.activeMethodIdx = methodIdx;
|
|
||||||
menu[catIdx].active = true;
|
|
||||||
this.activeCatCaption = menu[catIdx].name;
|
|
||||||
this.activeMethodPtr = null;
|
|
||||||
if (menu[catIdx].methods.length && (methodIdx > -1)) {
|
|
||||||
let currentItem = menu[catIdx].methods[methodIdx];
|
|
||||||
currentItem.active = true;
|
|
||||||
this.activeMethodPtr = currentItem.pointer;
|
|
||||||
this.activeItemCaption = currentItem.summary;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_calcActiveIndexes(offset) {
|
|
||||||
let menu = this.data.menu;
|
|
||||||
let catCount = menu.length;
|
|
||||||
let catLength = menu[this.activeCatIdx].methods.length;
|
|
||||||
|
|
||||||
let resMethodIdx = this.activeMethodIdx + offset;
|
|
||||||
let resCatIdx = this.activeCatIdx;
|
|
||||||
|
|
||||||
if (resMethodIdx > catLength - 1) {
|
|
||||||
resCatIdx++;
|
|
||||||
resMethodIdx = -1;
|
|
||||||
}
|
|
||||||
if (resMethodIdx < -1) {
|
|
||||||
let prevCatIdx = --resCatIdx;
|
|
||||||
catLength = menu[Math.max(prevCatIdx, 0)].methods.length;
|
|
||||||
resMethodIdx = catLength - 1;
|
|
||||||
}
|
|
||||||
if (resCatIdx > catCount - 1) {
|
|
||||||
resCatIdx = catCount - 1;
|
|
||||||
resMethodIdx = catLength - 1;
|
|
||||||
}
|
|
||||||
if (resCatIdx < 0) {
|
|
||||||
resCatIdx = 0;
|
|
||||||
resMethodIdx = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return [resCatIdx, resMethodIdx];
|
|
||||||
}
|
|
||||||
|
|
||||||
changeActive(offset = 1) {
|
|
||||||
let [catIdx, methodIdx] = this._calcActiveIndexes(offset);
|
|
||||||
this.activate(catIdx, methodIdx);
|
|
||||||
return (methodIdx === 0 && catIdx === 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
getMethodElByPtr(ptr, tag) {
|
|
||||||
let selector = ptr ? `[pointer="${ptr}"][tag="${tag}"]` : `[tag="${tag}"]`;
|
|
||||||
return document.querySelector(selector);
|
|
||||||
}
|
|
||||||
|
|
||||||
getMethodElByOperId(operationId) {
|
|
||||||
let selector =`[operation-id="${operationId}"]`;
|
|
||||||
return document.querySelector(selector);
|
|
||||||
}
|
|
||||||
|
|
||||||
getCurrentMethodEl() {
|
|
||||||
return this.getMethodElByPtr(this.activeMethodPtr, this.data.menu[this.activeCatIdx].name);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* returns 1 if element if above the view, 0 if in view and -1 below the view */
|
|
||||||
getElementInViewPos($el) {
|
|
||||||
if (Math.floor($el.getBoundingClientRect().top) > this.scrollYOffset()) {
|
|
||||||
return INVIEW_POSITION.ABOVE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($el.getBoundingClientRect().bottom <= this.scrollYOffset()) {
|
|
||||||
return INVIEW_POSITION.BELLOW;
|
|
||||||
}
|
|
||||||
return INVIEW_POSITION.INVIEW;
|
|
||||||
}
|
|
||||||
|
|
||||||
scrollHandler() {
|
|
||||||
let isScrolledDown = (this.scrollY() - this.prevOffsetY > 0);
|
|
||||||
this.prevOffsetY = this.scrollY();
|
|
||||||
let stable = false;
|
|
||||||
while(!stable) {
|
|
||||||
let $activeMethodHost = this.getCurrentMethodEl();
|
|
||||||
if (!$activeMethodHost) return;
|
|
||||||
var elementInViewPos = this.getElementInViewPos($activeMethodHost);
|
|
||||||
if(isScrolledDown && elementInViewPos === INVIEW_POSITION.BELLOW) {
|
|
||||||
stable = this.changeActive(CHANGE.NEXT);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if(!isScrolledDown && elementInViewPos === INVIEW_POSITION.ABOVE ) {
|
|
||||||
stable = this.changeActive(CHANGE.BACK);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
stable = true;
|
|
||||||
}
|
|
||||||
this.changeDetector.detectChanges();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
prepareModel() {
|
prepareModel() {
|
||||||
this.data = {};
|
this.data = {};
|
||||||
this.data.menu = Array.from(this.schemaMgr.buildMenuTree().entries()).map(
|
this.data.menu = this.menuService.categories;
|
||||||
el => ({name: el[0], description: el[1].description, methods: el[1].methods})
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mobileMode() {
|
mobileMode() {
|
||||||
|
@ -246,9 +85,8 @@ export default class SideMenu extends BaseComponent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
init() {
|
destroy() {
|
||||||
this.$mobileNav = this.dom.querySelector(this.$element, '.mobile-nav');
|
this.scrollService.unbind();
|
||||||
this.$resourcesNav = this.dom.querySelector(this.$element, '#resources-nav');
|
this.hash.unbind();
|
||||||
this.changeActive(CHANGE.INITIAL);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
@import '../../common/styles/variables';
|
@import '../../shared/styles/variables';
|
||||||
$mobile-menu-compact-breakpoint: 550px;
|
$mobile-menu-compact-breakpoint: 550px;
|
||||||
|
|
||||||
.menu-header {
|
.menu-header {
|
||||||
|
|
|
@ -1,30 +1,32 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import { getChildDebugElement, mouseclick} from 'tests/helpers';
|
import { getChildDebugElement } from 'tests/helpers';
|
||||||
import {Component, provide, ViewMetadata} from 'angular2/core';
|
import { Component, provide } from '@angular/core';
|
||||||
import {BrowserDomAdapter} from 'angular2/platform/browser';
|
import { BrowserDomAdapter } from '@angular/platform-browser/src/browser/browser_adapter';
|
||||||
import OptionsManager from 'lib/options';
|
import { OptionsService, RedocEventsService } from 'lib/services/index';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
TestComponentBuilder,
|
|
||||||
inject,
|
inject,
|
||||||
async,
|
async,
|
||||||
beforeEach,
|
beforeEach,
|
||||||
beforeEachProviders,
|
beforeEachProviders,
|
||||||
it
|
it
|
||||||
} from 'angular2/testing';
|
} from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { TestComponentBuilder } from '@angular/compiler/testing';
|
||||||
|
|
||||||
|
import { MethodsList, SideMenu } from 'lib/components/index';
|
||||||
|
|
||||||
import {redocEvents} from 'lib/events';
|
|
||||||
import MethodsList from 'lib/components/MethodsList/methods-list';
|
|
||||||
import SideMenu from 'lib/components/SideMenu/side-menu';
|
|
||||||
import SchemaManager from 'lib/utils/SchemaManager';
|
import SchemaManager from 'lib/utils/SchemaManager';
|
||||||
|
|
||||||
let testOptions = new OptionsManager();
|
let testOptions = new OptionsService();
|
||||||
testOptions.options = {
|
testOptions.options = {
|
||||||
scrollYOffset: () => 0,
|
scrollYOffset: () => 0,
|
||||||
scrollParent: window
|
scrollParent: window
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let redocEvents = new RedocEventsService();
|
||||||
|
|
||||||
describe('Redoc components', () => {
|
describe('Redoc components', () => {
|
||||||
describe('SideMenu Component', () => {
|
describe('SideMenu Component', () => {
|
||||||
let builder;
|
let builder;
|
||||||
|
@ -33,165 +35,32 @@ describe('Redoc components', () => {
|
||||||
beforeEachProviders(() => [
|
beforeEachProviders(() => [
|
||||||
provide(SchemaManager, {useValue: new SchemaManager()}),
|
provide(SchemaManager, {useValue: new SchemaManager()}),
|
||||||
provide(BrowserDomAdapter, {useValue: new BrowserDomAdapter()}),
|
provide(BrowserDomAdapter, {useValue: new BrowserDomAdapter()}),
|
||||||
provide(OptionsManager, {useValue: testOptions})
|
provide(OptionsService, {useValue: testOptions}),
|
||||||
|
provide(RedocEventsService, {useValue: redocEvents})
|
||||||
]);
|
]);
|
||||||
beforeEach(async(inject([TestComponentBuilder, SchemaManager], (tcb, schemaMgr) => {
|
beforeEach(async(inject([TestComponentBuilder, SchemaManager], (tcb, schemaMgr) => {
|
||||||
builder = tcb;
|
builder = tcb;
|
||||||
return schemaMgr.load('/tests/schemas/extended-petstore.yml');
|
return schemaMgr.load('/tests/schemas/extended-petstore.yml');
|
||||||
})));
|
})));
|
||||||
|
|
||||||
|
beforeEach((done) => {
|
||||||
|
builder.createAsync(TestApp).then(_fixture => {
|
||||||
|
fixture = _fixture;
|
||||||
|
component = getChildDebugElement(fixture.debugElement, 'side-menu').componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
done();
|
||||||
|
}, err => {
|
||||||
|
throw err;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
if (fixture) fixture.destroy();
|
if (fixture) fixture.destroy();
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('window parent case', () => {
|
it('should init component and component data', () => {
|
||||||
beforeEach((done) => {
|
expect(component).not.toBeNull();
|
||||||
builder.createAsync(TestApp).then(_fixture => {
|
expect(component.data).not.toBeNull();
|
||||||
fixture = _fixture;
|
|
||||||
component = getChildDebugElement(fixture.debugElement, 'side-menu').componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
done();
|
|
||||||
}, err => {
|
|
||||||
throw err;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should init component and component data', () => {
|
|
||||||
expect(component).not.toBeNull();
|
|
||||||
expect(component.data).not.toBeNull();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should run hashScroll when redoc bootstrapped', (done) => {
|
|
||||||
spyOn(component.dom, 'getLocation').and.returnValue({hash: ''});
|
|
||||||
spyOn(component, 'hashScroll').and.stub();
|
|
||||||
spyOn(window, 'scrollTo').and.stub();
|
|
||||||
redocEvents.bootstrapped.next();
|
|
||||||
setTimeout(() => {
|
|
||||||
expect(component.hashScroll).toHaveBeenCalled();
|
|
||||||
expect(window.scrollTo).not.toHaveBeenCalled();
|
|
||||||
|
|
||||||
window.scrollTo.and.callThrough();
|
|
||||||
component.hashScroll.and.callThrough();
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should scroll to method when location hash is present [jp]', (done) => {
|
|
||||||
let hash = '#tag/pet/paths/~1pet~1findByStatus/get';
|
|
||||||
spyOn(component.dom, 'getLocation').and.returnValue({hash: hash});
|
|
||||||
spyOn(component, 'hashScroll').and.callThrough();
|
|
||||||
spyOn(window, 'scrollTo').and.stub();
|
|
||||||
redocEvents.bootstrapped.next();
|
|
||||||
setTimeout(() => {
|
|
||||||
expect(component.hashScroll).toHaveBeenCalled();
|
|
||||||
let scrollY = window.scrollTo.calls.argsFor(0)[1];
|
|
||||||
expect(scrollY).toBeGreaterThan(0);
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should scroll to method when location hash is present [operation]', (done) => {
|
|
||||||
let hash = '#operation/getPetById';
|
|
||||||
spyOn(component.dom, 'getLocation').and.returnValue({hash: hash});
|
|
||||||
spyOn(component, 'hashScroll').and.callThrough();
|
|
||||||
spyOn(window, 'scrollTo').and.stub();
|
|
||||||
redocEvents.bootstrapped.next();
|
|
||||||
setTimeout(() => {
|
|
||||||
expect(component.hashScroll).toHaveBeenCalled();
|
|
||||||
let scrollY = window.scrollTo.calls.argsFor(0)[1];
|
|
||||||
expect(scrollY).toBeGreaterThan(0);
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('scrollable div parent case', () => {
|
|
||||||
let menuNativeEl;
|
|
||||||
beforeEach((done) => {
|
|
||||||
let scollableDivTmpl =
|
|
||||||
`<div style="height: 500px; overflow-y: auto;">
|
|
||||||
<side-menu></side-menu>
|
|
||||||
<methods-list></methods-list>
|
|
||||||
</div>`;
|
|
||||||
builder = builder.overrideView(
|
|
||||||
TestApp, new ViewMetadata({template: scollableDivTmpl, directives: [MethodsList, SideMenu]}));
|
|
||||||
builder.createAsync(TestApp).then(_fixture => {
|
|
||||||
fixture = _fixture;
|
|
||||||
component = getChildDebugElement(fixture.debugElement, 'side-menu').componentInstance;
|
|
||||||
menuNativeEl = getChildDebugElement(fixture.debugElement, 'side-menu').nativeElement;
|
|
||||||
component.options.scrollParent = _fixture.nativeElement.children[0];
|
|
||||||
component.$scrollParent = _fixture.nativeElement.children[0];
|
|
||||||
fixture.detectChanges();
|
|
||||||
done();
|
|
||||||
}, err => {
|
|
||||||
throw err;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
it('should init component and component data', () => {
|
|
||||||
expect(component).not.toBeNull();
|
|
||||||
expect(component.data).not.toBeNull();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should scroll to method when location hash is present [jp]', (done) => {
|
|
||||||
let hash = '#tag/pet/paths/~1pet~1findByStatus/get';
|
|
||||||
spyOn(component.dom, 'getLocation').and.returnValue({hash: hash});
|
|
||||||
spyOn(component, 'hashScroll').and.callThrough();
|
|
||||||
redocEvents.bootstrapped.next();
|
|
||||||
setTimeout(() => {
|
|
||||||
expect(component.hashScroll).toHaveBeenCalled();
|
|
||||||
expect(component.$scrollParent.scrollTop).toBeGreaterThan(0);
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should scroll to method when location hash is present [operation]', (done) => {
|
|
||||||
let hash = '#operation/getPetById';
|
|
||||||
spyOn(component.dom, 'getLocation').and.returnValue({hash: hash});
|
|
||||||
spyOn(component, 'hashScroll').and.callThrough();
|
|
||||||
redocEvents.bootstrapped.next();
|
|
||||||
setTimeout(() => {
|
|
||||||
expect(component.hashScroll).toHaveBeenCalled();
|
|
||||||
expect(component.$scrollParent.scrollTop).toBeGreaterThan(0);
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should select next/prev menu item when scrolled down/up', () => {
|
|
||||||
component.activeCatIdx.should.be.equal(0);
|
|
||||||
component.activeMethodIdx.should.be.equal(-1);
|
|
||||||
let elTop = component.getCurrentMethodEl().getBoundingClientRect().bottom;
|
|
||||||
|
|
||||||
component.$scrollParent.scrollTop = elTop + 1;
|
|
||||||
//simulate scroll down
|
|
||||||
spyOn(component, 'scrollY').and.returnValue(elTop + 2);
|
|
||||||
component.scrollHandler();
|
|
||||||
component.activeCatIdx.should.be.equal(1);
|
|
||||||
|
|
||||||
|
|
||||||
component.$scrollParent.scrollTop = elTop - 1;
|
|
||||||
//simulate scroll up
|
|
||||||
component.scrollY.and.returnValue(elTop - 2);
|
|
||||||
component.scrollHandler();
|
|
||||||
component.activeCatIdx.should.be.equal(0);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should activate menu item on click', () => {
|
|
||||||
let menuItemEl = menuNativeEl.querySelector('li');
|
|
||||||
expect(menuItemEl).not.toHaveCssClass('active');
|
|
||||||
mouseclick(menuItemEl);
|
|
||||||
fixture.detectChanges();
|
|
||||||
expect(menuItemEl).toHaveCssClass('active');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should scroll to appropriate element when click on menu label', () => {
|
|
||||||
component.$scrollParent.scrollTop.should.be.equal(0);
|
|
||||||
let menuItemEl = menuNativeEl.querySelector('li');
|
|
||||||
mouseclick(menuItemEl);
|
|
||||||
component.$scrollParent.scrollTop.should.be.above(0);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -200,7 +69,6 @@ describe('Redoc components', () => {
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'test-app',
|
selector: 'test-app',
|
||||||
directives: [MethodsList, SideMenu],
|
directives: [MethodsList, SideMenu],
|
||||||
providers: [SchemaManager],
|
|
||||||
template:
|
template:
|
||||||
`<side-menu></side-menu>
|
`<side-menu></side-menu>
|
||||||
<methods-list></methods-list>`
|
<methods-list></methods-list>`
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
import {Component, ChangeDetectionStrategy} from 'angular2/core';
|
import { Component, ChangeDetectionStrategy } from '@angular/core';
|
||||||
import {CORE_DIRECTIVES, JsonPipe, AsyncPipe} from 'angular2/common';
|
import { CORE_DIRECTIVES, JsonPipe, AsyncPipe } from '@angular/common';
|
||||||
import SchemaManager from '../utils/SchemaManager';
|
import SchemaManager from '../utils/SchemaManager';
|
||||||
import JsonPointer from '../utils/JsonPointer';
|
import JsonPointer from '../utils/JsonPointer';
|
||||||
import {MarkedPipe, JsonPointerEscapePipe} from '../utils/pipes';
|
import { MarkedPipe, JsonPointerEscapePipe } from '../utils/pipes';
|
||||||
|
|
||||||
export { SchemaManager };
|
export { SchemaManager };
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import SchemaManager from 'lib/utils/SchemaManager';
|
import SchemaManager from 'lib/utils/SchemaManager';
|
||||||
import {BaseComponent} from 'lib/components/base';
|
import { BaseComponent } from 'lib/components/base';
|
||||||
|
|
||||||
describe('Redoc components', () => {
|
describe('Redoc components', () => {
|
||||||
describe('BaseComponent', () => {
|
describe('BaseComponent', () => {
|
||||||
|
|
|
@ -1,42 +1,16 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import ApiInfo from './ApiInfo/api-info';
|
export * from './ApiInfo/api-info';
|
||||||
import ApiLogo from './ApiLogo/api-logo';
|
export * from './ApiLogo/api-logo';
|
||||||
import Method from './Method/method.js';
|
export * from './JsonSchema/json-schema';
|
||||||
import MethodsList from './MethodsList/methods-list';
|
export * from './JsonSchema/json-schema-lazy';
|
||||||
import ParamsList from './ParamsList/params-list';
|
export * from './ParamsList/params-list';
|
||||||
import Redoc from './Redoc/redoc';
|
export * from './RequestSamples/request-samples';
|
||||||
import ResponsesList from './ResponsesList/responses-list';
|
export * from './ResponsesList/responses-list';
|
||||||
import ResponsesSamples from './ResponsesSamples/responses-samples';
|
export * from './ResponsesSamples/responses-samples';
|
||||||
import SchemaSample from './SchemaSample/schema-sample';
|
export * from './SchemaSample/schema-sample';
|
||||||
import SideMenu from './SideMenu/side-menu';
|
export * from './SideMenu/side-menu';
|
||||||
import JsonSchema from './JsonSchema/json-schema';
|
export * from './MethodsList/methods-list';
|
||||||
|
export * from './Method/method';
|
||||||
|
|
||||||
const REDOC_COMPONENTS = [
|
export * from './Redoc/redoc';
|
||||||
ApiInfo,
|
|
||||||
ApiLogo,
|
|
||||||
JsonSchema,
|
|
||||||
Method,
|
|
||||||
MethodsList,
|
|
||||||
ParamsList,
|
|
||||||
Redoc,
|
|
||||||
ResponsesList,
|
|
||||||
ResponsesSamples,
|
|
||||||
SchemaSample,
|
|
||||||
SideMenu
|
|
||||||
];
|
|
||||||
|
|
||||||
export {
|
|
||||||
ApiInfo,
|
|
||||||
ApiLogo,
|
|
||||||
JsonSchema,
|
|
||||||
Method,
|
|
||||||
MethodsList,
|
|
||||||
ParamsList,
|
|
||||||
Redoc,
|
|
||||||
ResponsesList,
|
|
||||||
ResponsesSamples,
|
|
||||||
SchemaSample,
|
|
||||||
SideMenu,
|
|
||||||
REDOC_COMPONENTS
|
|
||||||
};
|
|
||||||
|
|
|
@ -1,10 +0,0 @@
|
||||||
'use strict';
|
|
||||||
|
|
||||||
import {EventEmitter} from 'angular2/core';
|
|
||||||
|
|
||||||
var bootsrEmmiter = new EventEmitter();
|
|
||||||
var langChanged = new EventEmitter();
|
|
||||||
export var redocEvents = {
|
|
||||||
bootstrapped: bootsrEmmiter,
|
|
||||||
samplesLanguageChanged: langChanged
|
|
||||||
};
|
|
10
lib/services/events.service.js
Normal file
10
lib/services/events.service.js
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
import { EventEmitter } from '@angular/core';
|
||||||
|
|
||||||
|
export class RedocEventsService {
|
||||||
|
constructor() {
|
||||||
|
this.bootstrapped = new EventEmitter();
|
||||||
|
this.samplesLanguageChanged = new EventEmitter();
|
||||||
|
}
|
||||||
|
}
|
33
lib/services/hash.service.js
Normal file
33
lib/services/hash.service.js
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
'use strict';
|
||||||
|
import { Injectable, EventEmitter } from '@angular/core';
|
||||||
|
import { BrowserDomAdapter } from '@angular/platform-browser/src/browser/browser_adapter';
|
||||||
|
import { global } from '@angular/core/src/facade/lang';
|
||||||
|
|
||||||
|
import { RedocEventsService } from './events.service';
|
||||||
|
|
||||||
|
@Reflect.metadata('parameters', [[BrowserDomAdapter], [RedocEventsService]])
|
||||||
|
@Injectable()
|
||||||
|
export class Hash {
|
||||||
|
constructor(dom, events) {
|
||||||
|
this.changed = new EventEmitter();
|
||||||
|
this.dom = dom;
|
||||||
|
this.bind();
|
||||||
|
|
||||||
|
events.bootstrapped.subscribe(() => this.changed.next(this.hash));
|
||||||
|
}
|
||||||
|
|
||||||
|
get hash() {
|
||||||
|
return this.dom.getLocation().hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
bind() {
|
||||||
|
this._cancel = this.dom.onAndCancel(global, 'hashchange', (evt) => {
|
||||||
|
this.changed.next(this.hash);
|
||||||
|
evt.preventDefault();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
unbind() {
|
||||||
|
this._cancel();
|
||||||
|
}
|
||||||
|
}
|
28
lib/services/hash.service.spec.js
Normal file
28
lib/services/hash.service.spec.js
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
import { BrowserDomAdapter } from '@angular/platform-browser/src/browser/browser_adapter';
|
||||||
|
|
||||||
|
import { RedocEventsService } from './events.service';
|
||||||
|
import { Hash } from './hash.service';
|
||||||
|
|
||||||
|
describe('Hash Service', () => {
|
||||||
|
let events = new RedocEventsService();
|
||||||
|
let hashService;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
hashService = new Hash(new BrowserDomAdapter(), events);
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
hashService.unbind();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should trigger changed event after ReDoc bootstrapped', (done) => {
|
||||||
|
spyOn(hashService.changed, 'next').and.callThrough();
|
||||||
|
events.bootstrapped.next();
|
||||||
|
setTimeout(() => {
|
||||||
|
expect(hashService.changed.next).toHaveBeenCalled();
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
7
lib/services/index.js
Normal file
7
lib/services/index.js
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
export * from './events.service.js';
|
||||||
|
export * from './options.service.js';
|
||||||
|
export * from './menu.service.js';
|
||||||
|
export * from './scroll.service.js';
|
||||||
|
export * from './hash.service.js';
|
152
lib/services/menu.service.js
Normal file
152
lib/services/menu.service.js
Normal file
|
@ -0,0 +1,152 @@
|
||||||
|
'use strict';
|
||||||
|
import { Injectable, EventEmitter } from '@angular/core';
|
||||||
|
import { ScrollService, INVIEW_POSITION } from './scroll.service.js';
|
||||||
|
import { Hash } from './hash.service.js';
|
||||||
|
import SchemaManager from '../utils/SchemaManager';
|
||||||
|
|
||||||
|
const CHANGE = {
|
||||||
|
NEXT : 1,
|
||||||
|
BACK : -1,
|
||||||
|
INITIAL : 0
|
||||||
|
};
|
||||||
|
|
||||||
|
@Reflect.metadata('parameters', [[Hash], [ScrollService], [SchemaManager]])
|
||||||
|
@Injectable()
|
||||||
|
export class MenuService {
|
||||||
|
constructor(hash, scrollService, schemaMgr) {
|
||||||
|
this.hash = hash;
|
||||||
|
this.scrollService = scrollService;
|
||||||
|
|
||||||
|
this.activeCatIdx = 0;
|
||||||
|
this.activeMethodIdx = -1;
|
||||||
|
this.changed = new EventEmitter();
|
||||||
|
|
||||||
|
this.categories = Array.from(schemaMgr.buildMenuTree().entries()).map(
|
||||||
|
el => ({name: el[0], description: el[1].description, methods: el[1].methods})
|
||||||
|
);
|
||||||
|
|
||||||
|
scrollService.scroll.subscribe((evt) => {
|
||||||
|
this.scrollUpdate(evt.isScrolledDown);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.changeActive(CHANGE.INITIAL);
|
||||||
|
|
||||||
|
this.hash.changed.subscribe((hash) => {
|
||||||
|
this.hashScroll(hash);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
scrollUpdate(isScrolledDown) {
|
||||||
|
let stable = false;
|
||||||
|
while(!stable) {
|
||||||
|
let $activeMethodHost = this.getCurrentMethodEl();
|
||||||
|
if (!$activeMethodHost) return;
|
||||||
|
var elementInViewPos = this.scrollService.getElementPos($activeMethodHost);
|
||||||
|
if(isScrolledDown && elementInViewPos === INVIEW_POSITION.BELLOW) {
|
||||||
|
stable = this.changeActive(CHANGE.NEXT);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(!isScrolledDown && elementInViewPos === INVIEW_POSITION.ABOVE ) {
|
||||||
|
stable = this.changeActive(CHANGE.BACK);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
stable = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getCurrentMethodEl() {
|
||||||
|
return this.getMethodElByPtr(this.activeMethodPtr,
|
||||||
|
this.categories[this.activeCatIdx].name);
|
||||||
|
}
|
||||||
|
|
||||||
|
getMethodElByPtr(ptr, tag) {
|
||||||
|
let selector = ptr ? `[pointer="${ptr}"][tag="${tag}"]` : `[tag="${tag}"]`;
|
||||||
|
return document.querySelector(selector);
|
||||||
|
}
|
||||||
|
|
||||||
|
getMethodElByOperId(operationId) {
|
||||||
|
let selector =`[operation-id="${operationId}"]`;
|
||||||
|
return document.querySelector(selector);
|
||||||
|
}
|
||||||
|
|
||||||
|
activate(catIdx, methodIdx) {
|
||||||
|
let menu = this.categories;
|
||||||
|
|
||||||
|
menu[this.activeCatIdx].active = false;
|
||||||
|
if (menu[this.activeCatIdx].methods.length) {
|
||||||
|
if (this.activeMethodIdx >= 0) {
|
||||||
|
menu[this.activeCatIdx].methods[this.activeMethodIdx].active = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.activeCatIdx = catIdx;
|
||||||
|
this.activeMethodIdx = methodIdx;
|
||||||
|
menu[catIdx].active = true;
|
||||||
|
this.activeMethodPtr = null;
|
||||||
|
let currentItem;
|
||||||
|
if (menu[catIdx].methods.length && (methodIdx > -1)) {
|
||||||
|
currentItem = menu[catIdx].methods[methodIdx];
|
||||||
|
currentItem.active = true;
|
||||||
|
this.activeMethodPtr = currentItem.pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.changed.next(menu[catIdx], currentItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
_calcActiveIndexes(offset) {
|
||||||
|
let menu = this.categories;
|
||||||
|
let catCount = menu.length;
|
||||||
|
let catLength = menu[this.activeCatIdx].methods.length;
|
||||||
|
|
||||||
|
let resMethodIdx = this.activeMethodIdx + offset;
|
||||||
|
let resCatIdx = this.activeCatIdx;
|
||||||
|
|
||||||
|
if (resMethodIdx > catLength - 1) {
|
||||||
|
resCatIdx++;
|
||||||
|
resMethodIdx = -1;
|
||||||
|
}
|
||||||
|
if (resMethodIdx < -1) {
|
||||||
|
let prevCatIdx = --resCatIdx;
|
||||||
|
catLength = menu[Math.max(prevCatIdx, 0)].methods.length;
|
||||||
|
resMethodIdx = catLength - 1;
|
||||||
|
}
|
||||||
|
if (resCatIdx > catCount - 1) {
|
||||||
|
resCatIdx = catCount - 1;
|
||||||
|
resMethodIdx = catLength - 1;
|
||||||
|
}
|
||||||
|
if (resCatIdx < 0) {
|
||||||
|
resCatIdx = 0;
|
||||||
|
resMethodIdx = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return [resCatIdx, resMethodIdx];
|
||||||
|
}
|
||||||
|
|
||||||
|
changeActive(offset = 1) {
|
||||||
|
let [catIdx, methodIdx] = this._calcActiveIndexes(offset);
|
||||||
|
this.activate(catIdx, methodIdx);
|
||||||
|
return (methodIdx === 0 && catIdx === 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
scrollToActive() {
|
||||||
|
this.scrollService.scrollTo(this.getCurrentMethodEl());
|
||||||
|
}
|
||||||
|
|
||||||
|
hashScroll(hash) {
|
||||||
|
if (!hash) return;
|
||||||
|
|
||||||
|
let $el;
|
||||||
|
hash = hash.substr(1);
|
||||||
|
let namespace = hash.split('/')[0];
|
||||||
|
let ptr = decodeURIComponent(hash.substr(namespace.length + 1));
|
||||||
|
if (namespace === 'operation') {
|
||||||
|
$el = this.getMethodElByOperId(ptr);
|
||||||
|
} else if (namespace === 'tag') {
|
||||||
|
let tag = ptr.split('/')[0];
|
||||||
|
ptr = ptr.substr(tag.length);
|
||||||
|
$el = this.getMethodElByPtr(ptr, tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($el) this.scrollService.scrollTo($el);
|
||||||
|
}
|
||||||
|
}
|
126
lib/services/menu.service.spec.js
Normal file
126
lib/services/menu.service.spec.js
Normal file
|
@ -0,0 +1,126 @@
|
||||||
|
'use strict';
|
||||||
|
import { provide, Component } from '@angular/core';
|
||||||
|
import { BrowserDomAdapter } from '@angular/platform-browser/src/browser/browser_adapter';
|
||||||
|
import {
|
||||||
|
inject,
|
||||||
|
beforeEach,
|
||||||
|
describe,
|
||||||
|
beforeEachProviders,
|
||||||
|
it
|
||||||
|
} from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { TestComponentBuilder } from '@angular/compiler/testing';
|
||||||
|
|
||||||
|
import { OptionsService } from './options.service';
|
||||||
|
import { MenuService } from './menu.service';
|
||||||
|
import { Hash } from './hash.service';
|
||||||
|
import { ScrollService } from './scroll.service';
|
||||||
|
import { RedocEventsService } from './events.service';
|
||||||
|
import { MethodsList } from 'lib/components/index';
|
||||||
|
import SchemaManager from 'lib/utils/SchemaManager';
|
||||||
|
|
||||||
|
describe('Menu service', () => {
|
||||||
|
let menu, hashService, scroll;
|
||||||
|
let builder;
|
||||||
|
let schemaMgr;
|
||||||
|
|
||||||
|
beforeEachProviders(() => [
|
||||||
|
provide(BrowserDomAdapter, {useClass: BrowserDomAdapter}),
|
||||||
|
provide(OptionsService, {useClass: OptionsService}),
|
||||||
|
provide(Hash, {useClass: Hash}),
|
||||||
|
provide(ScrollService, {useClass: ScrollService}),
|
||||||
|
provide(RedocEventsService, {useClass: RedocEventsService}),
|
||||||
|
provide(SchemaManager, {useClass: SchemaManager})
|
||||||
|
]);
|
||||||
|
|
||||||
|
beforeEach(inject([Hash, ScrollService, SchemaManager, TestComponentBuilder],
|
||||||
|
(_hash, _scroll, _schemaMgr, tcb) => {
|
||||||
|
hashService = _hash;
|
||||||
|
scroll = _scroll;
|
||||||
|
schemaMgr = _schemaMgr;
|
||||||
|
builder = tcb;
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
beforeEach((done) => {
|
||||||
|
schemaMgr.load('/tests/schemas/extended-petstore.yml').then(() => {
|
||||||
|
menu = new MenuService(hashService, scroll, schemaMgr);
|
||||||
|
done();
|
||||||
|
}).catch((err) => done.fail(err));
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach((done) => {
|
||||||
|
builder.createAsync(TestApp).then((fixture) => {
|
||||||
|
fixture.detectChanges();
|
||||||
|
done();
|
||||||
|
}).catch((err) => done.fail(err));
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
it('should run hashScroll when hash changed', (done) => {
|
||||||
|
spyOn(menu, 'hashScroll').and.callThrough();
|
||||||
|
hashService.changed.subscribe(() => {
|
||||||
|
expect(menu.hashScroll).toHaveBeenCalled();
|
||||||
|
menu.hashScroll.and.callThrough();
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
hashService.changed.next();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should scroll to method when location hash is present [jp]', (done) => {
|
||||||
|
let hash = '#tag/pet/paths/~1pet~1findByStatus/get';
|
||||||
|
spyOn(menu, 'hashScroll').and.callThrough();
|
||||||
|
spyOn(window, 'scrollTo').and.stub();
|
||||||
|
hashService.changed.subscribe(() => {
|
||||||
|
expect(menu.hashScroll).toHaveBeenCalled();
|
||||||
|
let scrollY = window.scrollTo.calls.argsFor(0)[1];
|
||||||
|
expect(scrollY).toBeGreaterThan(0);
|
||||||
|
window.scrollTo.and.callThrough();
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
hashService.changed.next(hash);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should scroll to method when location hash is present [operation]', (done) => {
|
||||||
|
let hash = '#operation/getPetById';
|
||||||
|
spyOn(menu, 'hashScroll').and.callThrough();
|
||||||
|
spyOn(window, 'scrollTo').and.stub();
|
||||||
|
hashService.changed.subscribe(() => {
|
||||||
|
expect(menu.hashScroll).toHaveBeenCalled();
|
||||||
|
let scrollY = window.scrollTo.calls.argsFor(0)[1];
|
||||||
|
expect(scrollY).toBeGreaterThan(0);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
hashService.changed.next(hash);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should select next/prev menu item when scrolled down/up', () => {
|
||||||
|
scroll.$scrollParent = document.querySelector('#parent');
|
||||||
|
menu.activeCatIdx.should.be.equal(0);
|
||||||
|
menu.activeMethodIdx.should.be.equal(-1);
|
||||||
|
let elTop = menu.getCurrentMethodEl().getBoundingClientRect().bottom;
|
||||||
|
|
||||||
|
scroll.$scrollParent.scrollTop = elTop + 1;
|
||||||
|
|
||||||
|
//simulate scroll down
|
||||||
|
spyOn(scroll, 'scrollY').and.returnValue(elTop + 2);
|
||||||
|
menu.scrollUpdate(true);
|
||||||
|
menu.activeCatIdx.should.be.equal(1);
|
||||||
|
|
||||||
|
scroll.scrollY.and.returnValue(elTop - 2);
|
||||||
|
scroll.$scrollParent.scrollTop = elTop - 1;
|
||||||
|
menu.scrollUpdate(false);
|
||||||
|
menu.activeCatIdx.should.be.equal(0);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'test-app',
|
||||||
|
directives: [ MethodsList ],
|
||||||
|
template:
|
||||||
|
`<div id='parent' style='height: 500px; overflow:auto'>
|
||||||
|
<methods-list></methods-list>
|
||||||
|
</div>`
|
||||||
|
})
|
||||||
|
class TestApp {
|
||||||
|
}
|
|
@ -1,22 +1,23 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { isFunction, isString } from '@angular/core/src/facade/lang';
|
||||||
|
import { BrowserDomAdapter } from '@angular/platform-browser/src/browser/browser_adapter';
|
||||||
|
import { global } from '@angular/core/src/facade/lang';
|
||||||
|
|
||||||
import {isFunction, isString} from 'angular2/src/facade/lang';
|
const defaults = {
|
||||||
import {BrowserDomAdapter} from 'angular2/platform/browser';
|
|
||||||
import {global} from 'angular2/src/facade/lang';
|
|
||||||
|
|
||||||
var defaults = {
|
|
||||||
scrollYOffset: 0,
|
scrollYOffset: 0,
|
||||||
disableLazySchemas: false,
|
disableLazySchemas: false,
|
||||||
debugMode: global.redocDebugMode
|
debugMode: global && global.redocDebugMode
|
||||||
};
|
};
|
||||||
|
|
||||||
var OPTION_NAMES = new Set(['scrollYOffset', 'disableLazySchemas', 'specUrl']);
|
const OPTION_NAMES = new Set(['scrollYOffset', 'disableLazySchemas', 'specUrl']);
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
@Reflect.metadata('parameters', [[BrowserDomAdapter]])
|
@Reflect.metadata('parameters', [[BrowserDomAdapter]])
|
||||||
export default class OptionsManager {
|
export class OptionsService {
|
||||||
constructor() {
|
constructor(dom) {
|
||||||
this._options = defaults;
|
this._options = defaults;
|
||||||
this.dom = new BrowserDomAdapter();
|
this.dom = dom;
|
||||||
}
|
}
|
||||||
|
|
||||||
get options() {
|
get options() {
|
55
lib/services/options.service.spec.js
Normal file
55
lib/services/options.service.spec.js
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
import { BrowserDomAdapter } from '@angular/platform-browser/src/browser/browser_adapter';
|
||||||
|
import {
|
||||||
|
it
|
||||||
|
} from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { OptionsService } from './options.service';
|
||||||
|
|
||||||
|
describe('Options Service', () => {
|
||||||
|
let tmpDiv;
|
||||||
|
let optionsService;
|
||||||
|
|
||||||
|
function build(html) {
|
||||||
|
tmpDiv = document.createElement('div');
|
||||||
|
tmpDiv.innerHTML = html;
|
||||||
|
document.body.appendChild(tmpDiv);
|
||||||
|
return tmpDiv.lastChild;
|
||||||
|
}
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
document.body.removeChild(tmpDiv);
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
optionsService = new OptionsService(new BrowserDomAdapter());
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should parse numeric scrollYOffset', () => {
|
||||||
|
var elem = build(`<redoc scroll-y-offset="50"></redoc>`);
|
||||||
|
optionsService.parseOptions(elem);
|
||||||
|
optionsService.options.scrollYOffset().should.be.equal(50);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should parse selector scrollYOffset', () => {
|
||||||
|
var elem = build(`<div id="test" style="position: fixed; height: 50px; top:0"> </div>
|
||||||
|
<redoc scroll-y-offset="#test"></redoc>`);
|
||||||
|
optionsService.parseOptions(elem);
|
||||||
|
optionsService.options.scrollYOffset().should.be.equal(50);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return 0 for incorrect selector scrollYOffset', () => {
|
||||||
|
var elem = build(`<div id="test" style="position: fixed; height: 50px; top:0"> </div>
|
||||||
|
<redoc scroll-y-offset="#test2"></redoc>`);
|
||||||
|
optionsService.parseOptions(elem);
|
||||||
|
optionsService.options.scrollYOffset().should.be.equal(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle function scrollYOffset', () => {
|
||||||
|
optionsService.options = { scrollYOffset: () => 123 };
|
||||||
|
var elem = build(`<redoc></redoc>`);
|
||||||
|
optionsService.parseOptions(elem);
|
||||||
|
optionsService.options.scrollYOffset().should.be.equal(123);
|
||||||
|
});
|
||||||
|
});
|
66
lib/services/scroll.service.js
Normal file
66
lib/services/scroll.service.js
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
'use strict';
|
||||||
|
import { Injectable, EventEmitter } from '@angular/core';
|
||||||
|
import { BrowserDomAdapter } from '@angular/platform-browser/src/browser/browser_adapter';
|
||||||
|
import { OptionsService } from './options.service.js';
|
||||||
|
|
||||||
|
export const INVIEW_POSITION = {
|
||||||
|
ABOVE : 1,
|
||||||
|
BELLOW: -1,
|
||||||
|
INVIEW: 0
|
||||||
|
};
|
||||||
|
|
||||||
|
@Reflect.metadata('parameters', [
|
||||||
|
[BrowserDomAdapter], [OptionsService]])
|
||||||
|
@Injectable()
|
||||||
|
export class ScrollService {
|
||||||
|
constructor(dom, optionsService) {
|
||||||
|
//events.bootstrapped.subscribe(() => this.hashScroll());
|
||||||
|
this.scrollYOffset = () => optionsService.options.scrollYOffset();
|
||||||
|
this.$scrollParent = optionsService.options.$scrollParent;
|
||||||
|
this.scroll = new EventEmitter();
|
||||||
|
this.dom = dom;
|
||||||
|
this.bind();
|
||||||
|
}
|
||||||
|
|
||||||
|
scrollY() {
|
||||||
|
return (this.$scrollParent.pageYOffset != null) ? this.$scrollParent.pageYOffset : this.$scrollParent.scrollTop;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* returns 1 if element if above the view, 0 if in view and -1 below the view */
|
||||||
|
getElementPos($el) {
|
||||||
|
if (Math.floor($el.getBoundingClientRect().top) > this.scrollYOffset()) {
|
||||||
|
return INVIEW_POSITION.ABOVE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($el.getBoundingClientRect().bottom <= this.scrollYOffset()) {
|
||||||
|
return INVIEW_POSITION.BELLOW;
|
||||||
|
}
|
||||||
|
return INVIEW_POSITION.INVIEW;
|
||||||
|
}
|
||||||
|
|
||||||
|
scrollTo($el) {
|
||||||
|
// TODO: rewrite this to use offsetTop as more reliable solution
|
||||||
|
let subjRect = $el.getBoundingClientRect();
|
||||||
|
let offset = this.scrollY() + subjRect.top - this.scrollYOffset() + 1;
|
||||||
|
if (this.$scrollParent.scrollTo) {
|
||||||
|
this.$scrollParent.scrollTo(0, offset);
|
||||||
|
} else {
|
||||||
|
this.$scrollParent.scrollTop = offset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
scrollHandler(evt) {
|
||||||
|
let isScrolledDown = (this.scrollY() - this.prevOffsetY > 0);
|
||||||
|
this.prevOffsetY = this.scrollY();
|
||||||
|
this.scroll.next({isScrolledDown, evt});
|
||||||
|
}
|
||||||
|
|
||||||
|
bind() {
|
||||||
|
this.prevOffsetY = this.scrollY();
|
||||||
|
this._cancel = this.dom.onAndCancel(this.$scrollParent, 'scroll', (evt) => { this.scrollHandler(evt); });
|
||||||
|
}
|
||||||
|
|
||||||
|
unbind() {
|
||||||
|
this._cancel();
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import {Component, EventEmitter, ElementRef} from 'angular2/core';
|
import {Component, EventEmitter, ElementRef} from '@angular/core';
|
||||||
import {CORE_DIRECTIVES} from 'angular2/common';
|
import {CORE_DIRECTIVES} from '@angular/common';
|
||||||
import DropKick from 'Robdel12/DropKick';
|
import DropKick from 'Robdel12/DropKick';
|
||||||
import 'Robdel12/DropKick/build/css/dropkick.css!css';
|
import 'Robdel12/DropKick/build/css/dropkick.css!css';
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ import 'Robdel12/DropKick/build/css/dropkick.css!css';
|
||||||
</select>
|
</select>
|
||||||
`,
|
`,
|
||||||
directives: [CORE_DIRECTIVES],
|
directives: [CORE_DIRECTIVES],
|
||||||
styleUrls: ['./lib/common/components/DropDown/dropdown.css']
|
styleUrls: ['./lib/shared/components/DropDown/drop-down.css']
|
||||||
})
|
})
|
||||||
@Reflect.metadata('parameters', [[ElementRef]])
|
@Reflect.metadata('parameters', [[ElementRef]])
|
||||||
export class DropDown {
|
export class DropDown {
|
|
@ -1,14 +1,14 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import {Directive, ElementRef} from 'angular2/core';
|
import {Directive, ElementRef} from '@angular/core';
|
||||||
import {BrowserDomAdapter} from 'angular2/platform/browser';
|
import {BrowserDomAdapter} from '@angular/platform-browser/src/browser/browser_adapter';
|
||||||
|
|
||||||
@Directive({
|
@Directive({
|
||||||
selector: '[sticky-sidebar]',
|
selector: '[sticky-sidebar]',
|
||||||
inputs: ['scrollParent', 'scrollYOffset']
|
inputs: ['scrollParent', 'scrollYOffset']
|
||||||
})
|
})
|
||||||
@Reflect.metadata('parameters', [[ElementRef], [BrowserDomAdapter]])
|
@Reflect.metadata('parameters', [[ElementRef], [BrowserDomAdapter]])
|
||||||
export default class StickySidebar {
|
export class StickySidebar {
|
||||||
constructor(elementRef, dom) {
|
constructor(elementRef, dom) {
|
||||||
this.$element = elementRef.nativeElement;
|
this.$element = elementRef.nativeElement;
|
||||||
this.dom = dom;
|
this.dom = dom;
|
|
@ -1,18 +1,19 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import { getChildDebugElementByType } from 'tests/helpers';
|
import { getChildDebugElementByType } from 'tests/helpers';
|
||||||
import {Component, provide} from 'angular2/core';
|
import { Component, provide } from '@angular/core';
|
||||||
import {BrowserDomAdapter} from 'angular2/platform/browser';
|
import { BrowserDomAdapter } from '@angular/platform-browser/src/browser/browser_adapter';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
TestComponentBuilder,
|
|
||||||
inject,
|
inject,
|
||||||
beforeEach,
|
beforeEach,
|
||||||
beforeEachProviders,
|
beforeEachProviders,
|
||||||
it
|
it
|
||||||
} from 'angular2/testing';
|
} from '@angular/core/testing';
|
||||||
|
|
||||||
import StickySidebar from 'lib/common/components/StickySidebar/sticky-sidebar';
|
import { TestComponentBuilder } from '@angular/compiler/testing';
|
||||||
|
|
||||||
|
import { StickySidebar } from 'lib/shared/components/index';
|
||||||
|
|
||||||
describe('Common components', () => {
|
describe('Common components', () => {
|
||||||
describe('StickySidebar Component', () => {
|
describe('StickySidebar Component', () => {
|
|
@ -1,7 +1,7 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import {Component, EventEmitter} from 'angular2/core';
|
import {Component, EventEmitter} from '@angular/core';
|
||||||
import {CORE_DIRECTIVES} from 'angular2/common';
|
import {CORE_DIRECTIVES} from '@angular/common';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'tabs',
|
selector: 'tabs',
|
||||||
|
@ -14,7 +14,7 @@ import {CORE_DIRECTIVES} from 'angular2/common';
|
||||||
<ng-content></ng-content>
|
<ng-content></ng-content>
|
||||||
`,
|
`,
|
||||||
directives: [CORE_DIRECTIVES],
|
directives: [CORE_DIRECTIVES],
|
||||||
styleUrls: ['./lib/common/components/Tabs/tabs.css']
|
styleUrls: ['./lib/shared/components/Tabs/tabs.css']
|
||||||
})
|
})
|
||||||
export class Tabs {
|
export class Tabs {
|
||||||
constructor() {
|
constructor() {
|
|
@ -1,16 +1,17 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import { getChildDebugElement, getChildDebugElementAll } from 'tests/helpers';
|
import { getChildDebugElement, getChildDebugElementAll } from 'tests/helpers';
|
||||||
import {Component} from 'angular2/core';
|
import {Component} from '@angular/core';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
TestComponentBuilder,
|
|
||||||
inject,
|
inject,
|
||||||
beforeEach,
|
beforeEach,
|
||||||
it
|
it
|
||||||
} from 'angular2/testing';
|
} from '@angular/core/testing';
|
||||||
|
|
||||||
import {Tabs, Tab} from 'lib/common/components/Tabs/tabs';
|
import { TestComponentBuilder } from '@angular/compiler/testing';
|
||||||
|
|
||||||
|
import {Tabs, Tab} from 'lib/shared/components/index';
|
||||||
|
|
||||||
describe('Common components', () => {
|
describe('Common components', () => {
|
||||||
describe('Tabs Component', () => {
|
describe('Tabs Component', () => {
|
|
@ -1,17 +1,17 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import {Component, EventEmitter} from 'angular2/core';
|
import {Component, EventEmitter} from '@angular/core';
|
||||||
import {CORE_DIRECTIVES} from 'angular2/common';
|
import {CORE_DIRECTIVES} from '@angular/common';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'zippy',
|
selector: 'zippy',
|
||||||
events: ['open', 'close'],
|
events: ['open', 'close'],
|
||||||
inputs: ['title', 'visible', 'type', 'empty'],
|
inputs: ['title', 'visible', 'type', 'empty'],
|
||||||
templateUrl: './lib/common/components/Zippy/zippy.html',
|
templateUrl: './lib/shared/components/Zippy/zippy.html',
|
||||||
styleUrls: ['./lib/common/components/Zippy/zippy.css'],
|
styleUrls: ['./lib/shared/components/Zippy/zippy.css'],
|
||||||
directives: [CORE_DIRECTIVES]
|
directives: [CORE_DIRECTIVES]
|
||||||
})
|
})
|
||||||
export default class Zippy {
|
export class Zippy {
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.type = 'general';
|
this.type = 'general';
|
|
@ -1,16 +1,16 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import { getChildDebugElement, mouseclick } from 'tests/helpers';
|
import { getChildDebugElement, mouseclick } from 'tests/helpers';
|
||||||
import {Component} from 'angular2/core';
|
|
||||||
|
|
||||||
|
import { Component } from '@angular/core';
|
||||||
import {
|
import {
|
||||||
TestComponentBuilder,
|
|
||||||
inject,
|
inject,
|
||||||
beforeEach,
|
beforeEach,
|
||||||
it
|
it
|
||||||
} from 'angular2/testing';
|
} from '@angular/core/testing';
|
||||||
|
|
||||||
import Zippy from 'lib/common/components/Zippy/zippy';
|
import { TestComponentBuilder } from '@angular/compiler/testing';
|
||||||
|
import { Zippy } from 'lib/shared/components/index';
|
||||||
|
|
||||||
describe('Common components', () => {
|
describe('Common components', () => {
|
||||||
describe('Zippy Component', () => {
|
describe('Zippy Component', () => {
|
5
lib/shared/components/index.js
Normal file
5
lib/shared/components/index.js
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
'use strict';
|
||||||
|
export * from './DropDown/drop-down';
|
||||||
|
export * from './StickySidebar/sticky-sidebar';
|
||||||
|
export * from './Tabs/tabs';
|
||||||
|
export * from './Zippy/zippy';
|
|
@ -1,6 +1,6 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
import {Pipe} from 'angular2/core';
|
import {Pipe} from '@angular/core';
|
||||||
import {isBlank} from 'angular2/src/facade/lang';
|
import {isBlank} from '@angular/core/src/facade/lang';
|
||||||
|
|
||||||
var level = 1;
|
var level = 1;
|
||||||
const COLLAPSE_LEVEL = 2;
|
const COLLAPSE_LEVEL = 2;
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import {Pipe} from 'angular2/core';
|
import {Pipe} from '@angular/core';
|
||||||
import {isString, stringify, isBlank} from 'angular2/src/facade/lang';
|
import {isString, stringify, isBlank} from '@angular/core/src/facade/lang';
|
||||||
import {BaseException} from 'angular2/src/facade/exceptions';
|
import {BaseException} from '@angular/core/src/facade/exceptions';
|
||||||
import {JsonPointer} from './JsonPointer';
|
import {JsonPointer} from './JsonPointer';
|
||||||
|
|
||||||
import Prism from '../../prismjs-bundle';
|
import Prism from '../../prismjs-bundle';
|
||||||
|
|
16
package.json
16
package.json
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "redoc",
|
"name": "redoc",
|
||||||
"description": "Swagger-generated API Reference Documentation",
|
"description": "Swagger-generated API Reference Documentation",
|
||||||
"version": "0.8.0",
|
"version": "0.9.0",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "git://github.com/Rebilly/ReDoc"
|
"url": "git://github.com/Rebilly/ReDoc"
|
||||||
|
@ -32,8 +32,12 @@
|
||||||
"jspm": {
|
"jspm": {
|
||||||
"configFile": "system.config.js",
|
"configFile": "system.config.js",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@angular/common": "npm:@angular/common@^2.0.0-rc.1",
|
||||||
|
"@angular/compiler": "npm:@angular/compiler@^2.0.0-rc.1",
|
||||||
|
"@angular/core": "npm:@angular/core@^2.0.0-rc.1",
|
||||||
|
"@angular/platform-browser": "npm:@angular/platform-browser@^2.0.0-rc.1",
|
||||||
|
"@angular/platform-browser-dynamic": "npm:@angular/platform-browser-dynamic@^2.0.0-rc.1",
|
||||||
"Robdel12/DropKick": "github:Robdel12/DropKick@^2.1.7",
|
"Robdel12/DropKick": "github:Robdel12/DropKick@^2.1.7",
|
||||||
"angular2": "npm:angular2@2.0.0-beta.17",
|
|
||||||
"es6-shim": "github:es-shims/es6-shim@^0.33.6",
|
"es6-shim": "github:es-shims/es6-shim@^0.33.6",
|
||||||
"hint.css": "npm:hint.css@^2.2.1",
|
"hint.css": "npm:hint.css@^2.2.1",
|
||||||
"json": "github:systemjs/plugin-json@^0.1.0",
|
"json": "github:systemjs/plugin-json@^0.1.0",
|
||||||
|
@ -42,9 +46,11 @@
|
||||||
"json-schema-instantiator": "npm:json-schema-instantiator@^0.3.0",
|
"json-schema-instantiator": "npm:json-schema-instantiator@^0.3.0",
|
||||||
"marked": "npm:marked@^0.3.5",
|
"marked": "npm:marked@^0.3.5",
|
||||||
"prismjs": "npm:prismjs@^1.3.0",
|
"prismjs": "npm:prismjs@^1.3.0",
|
||||||
|
"rxjs": "npm:rxjs@5.0.0-beta.6",
|
||||||
"scrollparent": "npm:scrollparent@^0.1.0",
|
"scrollparent": "npm:scrollparent@^0.1.0",
|
||||||
"stream-http": "npm:stream-http@^2.3.0",
|
"stream-http": "npm:stream-http@^2.3.0",
|
||||||
"swagger-parser": "npm:swagger-parser@4.0.0-beta.2"
|
"swagger-parser": "npm:swagger-parser@4.0.0-beta.2",
|
||||||
|
"zone.js": "npm:zone.js@0.6.12"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"babel": "npm:babel-core@^5.8.34",
|
"babel": "npm:babel-core@^5.8.34",
|
||||||
|
@ -85,7 +91,7 @@
|
||||||
"istanbul": "github:gotwarlost/istanbul#source-map",
|
"istanbul": "github:gotwarlost/istanbul#source-map",
|
||||||
"jasmine-core": "^2.4.1",
|
"jasmine-core": "^2.4.1",
|
||||||
"jasmine-spec-reporter": "^2.4.0",
|
"jasmine-spec-reporter": "^2.4.0",
|
||||||
"jspm": "^0.16.19",
|
"jspm": "^0.16.34",
|
||||||
"karma": "^0.13.15",
|
"karma": "^0.13.15",
|
||||||
"karma-babel-preprocessor": "^5.2.2",
|
"karma-babel-preprocessor": "^5.2.2",
|
||||||
"karma-chrome-launcher": "^0.2.2",
|
"karma-chrome-launcher": "^0.2.2",
|
||||||
|
@ -106,7 +112,7 @@
|
||||||
"run-sequence": "^1.1.5",
|
"run-sequence": "^1.1.5",
|
||||||
"should": "^8.0.2",
|
"should": "^8.0.2",
|
||||||
"sinon": "^1.17.2",
|
"sinon": "^1.17.2",
|
||||||
"systemjs-builder": "^0.15.2",
|
"systemjs-builder": "^0.15.16",
|
||||||
"vinyl-paths": "^2.0.0",
|
"vinyl-paths": "^2.0.0",
|
||||||
"zone.js": "^0.6.12"
|
"zone.js": "^0.6.12"
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,8 @@ let config = {
|
||||||
return loadJson('https://apis-guru.github.io/api-models/api/v1/list.json').then((list) => {
|
return loadJson('https://apis-guru.github.io/api-models/api/v1/list.json').then((list) => {
|
||||||
global.apisGuruList = list;
|
global.apisGuruList = list;
|
||||||
return browser.getCapabilities().then(function (cap) {
|
return browser.getCapabilities().then(function (cap) {
|
||||||
browser.isIE = cap.caps_.browserName === 'internet explorer';
|
browser.isIE = cap.browserName === 'internet explorer'
|
||||||
|
|| (cap.caps_ && cap.caps_.browserName === 'internet explorer')
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
|
@ -29,16 +29,20 @@ System.config({
|
||||||
|
|
||||||
meta: {
|
meta: {
|
||||||
"jspm_packages/npm/json-formatter-js@0.2.0/src/*": {
|
"jspm_packages/npm/json-formatter-js@0.2.0/src/*": {
|
||||||
"format": "es6"
|
"format": "esm"
|
||||||
},
|
},
|
||||||
"jspm_packages/npm/json-schema-view-js@0.2.0/src/*": {
|
"jspm_packages/npm/json-schema-view-js@0.2.0/src/*": {
|
||||||
"format": "es6"
|
"format": "esm"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
map: {
|
map: {
|
||||||
|
"@angular/common": "npm:@angular/common@2.0.0-rc.1",
|
||||||
|
"@angular/compiler": "npm:@angular/compiler@2.0.0-rc.1",
|
||||||
|
"@angular/core": "npm:@angular/core@2.0.0-rc.1",
|
||||||
|
"@angular/platform-browser": "npm:@angular/platform-browser@2.0.0-rc.1",
|
||||||
|
"@angular/platform-browser-dynamic": "npm:@angular/platform-browser-dynamic@2.0.0-rc.1",
|
||||||
"Robdel12/DropKick": "github:Robdel12/DropKick@2.1.7",
|
"Robdel12/DropKick": "github:Robdel12/DropKick@2.1.7",
|
||||||
"angular2": "npm:angular2@2.0.0-beta.17",
|
|
||||||
"babel": "npm:babel-core@5.8.34",
|
"babel": "npm:babel-core@5.8.34",
|
||||||
"babel-runtime": "npm:babel-runtime@5.8.34",
|
"babel-runtime": "npm:babel-runtime@5.8.34",
|
||||||
"clean-css": "npm:clean-css@3.4.6",
|
"clean-css": "npm:clean-css@3.4.6",
|
||||||
|
@ -52,10 +56,12 @@ System.config({
|
||||||
"json-schema-instantiator": "npm:json-schema-instantiator@0.3.0",
|
"json-schema-instantiator": "npm:json-schema-instantiator@0.3.0",
|
||||||
"marked": "npm:marked@0.3.5",
|
"marked": "npm:marked@0.3.5",
|
||||||
"prismjs": "npm:prismjs@1.3.0",
|
"prismjs": "npm:prismjs@1.3.0",
|
||||||
|
"rxjs": "npm:rxjs@5.0.0-beta.6",
|
||||||
"scrollparent": "npm:scrollparent@0.1.0",
|
"scrollparent": "npm:scrollparent@0.1.0",
|
||||||
"stream-http": "npm:stream-http@2.3.0",
|
"stream-http": "npm:stream-http@2.3.0",
|
||||||
"swagger-parser": "npm:swagger-parser@4.0.0-beta.2",
|
"swagger-parser": "npm:swagger-parser@4.0.0-beta.2",
|
||||||
"systemjs/plugin-json": "github:systemjs/plugin-json@0.1.2",
|
"systemjs/plugin-json": "github:systemjs/plugin-json@0.1.2",
|
||||||
|
"zone.js": "npm:zone.js@0.6.12",
|
||||||
"github:jspm/nodelibs-assert@0.1.0": {
|
"github:jspm/nodelibs-assert@0.1.0": {
|
||||||
"assert": "npm:assert@1.3.0"
|
"assert": "npm:assert@1.3.0"
|
||||||
},
|
},
|
||||||
|
@ -131,17 +137,38 @@ System.config({
|
||||||
"github:jspm/nodelibs-zlib@0.1.0": {
|
"github:jspm/nodelibs-zlib@0.1.0": {
|
||||||
"browserify-zlib": "npm:browserify-zlib@0.1.4"
|
"browserify-zlib": "npm:browserify-zlib@0.1.4"
|
||||||
},
|
},
|
||||||
|
"npm:@angular/common@2.0.0-rc.1": {
|
||||||
|
"@angular/core": "npm:@angular/core@2.0.0-rc.1",
|
||||||
|
"process": "github:jspm/nodelibs-process@0.1.2"
|
||||||
|
},
|
||||||
|
"npm:@angular/compiler@2.0.0-rc.1": {
|
||||||
|
"@angular/core": "npm:@angular/core@2.0.0-rc.1",
|
||||||
|
"process": "github:jspm/nodelibs-process@0.1.2"
|
||||||
|
},
|
||||||
|
"npm:@angular/core@2.0.0-rc.1": {
|
||||||
|
"process": "github:jspm/nodelibs-process@0.1.2",
|
||||||
|
"rxjs": "npm:rxjs@5.0.0-beta.6",
|
||||||
|
"zone.js": "npm:zone.js@0.6.12"
|
||||||
|
},
|
||||||
|
"npm:@angular/platform-browser-dynamic@2.0.0-rc.1": {
|
||||||
|
"@angular/common": "npm:@angular/common@2.0.0-rc.1",
|
||||||
|
"@angular/compiler": "npm:@angular/compiler@2.0.0-rc.1",
|
||||||
|
"@angular/core": "npm:@angular/core@2.0.0-rc.1",
|
||||||
|
"@angular/platform-browser": "npm:@angular/platform-browser@2.0.0-rc.1",
|
||||||
|
"process": "github:jspm/nodelibs-process@0.1.2"
|
||||||
|
},
|
||||||
|
"npm:@angular/platform-browser@2.0.0-rc.1": {
|
||||||
|
"@angular/common": "npm:@angular/common@2.0.0-rc.1",
|
||||||
|
"@angular/compiler": "npm:@angular/compiler@2.0.0-rc.1",
|
||||||
|
"@angular/core": "npm:@angular/core@2.0.0-rc.1",
|
||||||
|
"process": "github:jspm/nodelibs-process@0.1.2"
|
||||||
|
},
|
||||||
"npm:amdefine@1.0.0": {
|
"npm:amdefine@1.0.0": {
|
||||||
"fs": "github:jspm/nodelibs-fs@0.1.2",
|
"fs": "github:jspm/nodelibs-fs@0.1.2",
|
||||||
"module": "github:jspm/nodelibs-module@0.1.0",
|
"module": "github:jspm/nodelibs-module@0.1.0",
|
||||||
"path": "github:jspm/nodelibs-path@0.1.0",
|
"path": "github:jspm/nodelibs-path@0.1.0",
|
||||||
"process": "github:jspm/nodelibs-process@0.1.2"
|
"process": "github:jspm/nodelibs-process@0.1.2"
|
||||||
},
|
},
|
||||||
"npm:angular2@2.0.0-beta.17": {
|
|
||||||
"reflect-metadata": "npm:reflect-metadata@0.1.2",
|
|
||||||
"rxjs": "npm:rxjs@5.0.0-beta.7",
|
|
||||||
"zone.js": "npm:zone.js@0.6.12"
|
|
||||||
},
|
|
||||||
"npm:argparse@1.0.7": {
|
"npm:argparse@1.0.7": {
|
||||||
"fs": "github:jspm/nodelibs-fs@0.1.2",
|
"fs": "github:jspm/nodelibs-fs@0.1.2",
|
||||||
"path": "github:jspm/nodelibs-path@0.1.0",
|
"path": "github:jspm/nodelibs-path@0.1.0",
|
||||||
|
@ -736,10 +763,6 @@ System.config({
|
||||||
"string_decoder": "npm:string_decoder@0.10.31",
|
"string_decoder": "npm:string_decoder@0.10.31",
|
||||||
"util-deprecate": "npm:util-deprecate@1.0.2"
|
"util-deprecate": "npm:util-deprecate@1.0.2"
|
||||||
},
|
},
|
||||||
"npm:reflect-metadata@0.1.2": {
|
|
||||||
"assert": "github:jspm/nodelibs-assert@0.1.0",
|
|
||||||
"process": "github:jspm/nodelibs-process@0.1.2"
|
|
||||||
},
|
|
||||||
"npm:request@2.72.0": {
|
"npm:request@2.72.0": {
|
||||||
"aws-sign2": "npm:aws-sign2@0.6.0",
|
"aws-sign2": "npm:aws-sign2@0.6.0",
|
||||||
"aws4": "npm:aws4@1.3.2",
|
"aws4": "npm:aws4@1.3.2",
|
||||||
|
@ -778,10 +801,9 @@ System.config({
|
||||||
"buffer": "github:jspm/nodelibs-buffer@0.1.0",
|
"buffer": "github:jspm/nodelibs-buffer@0.1.0",
|
||||||
"process": "github:jspm/nodelibs-process@0.1.2"
|
"process": "github:jspm/nodelibs-process@0.1.2"
|
||||||
},
|
},
|
||||||
"npm:rxjs@5.0.0-beta.7": {
|
"npm:rxjs@5.0.0-beta.6": {
|
||||||
"buffer": "github:jspm/nodelibs-buffer@0.1.0",
|
"buffer": "github:jspm/nodelibs-buffer@0.1.0",
|
||||||
"process": "github:jspm/nodelibs-process@0.1.2",
|
"process": "github:jspm/nodelibs-process@0.1.2"
|
||||||
"symbol-observable": "npm:symbol-observable@0.2.4"
|
|
||||||
},
|
},
|
||||||
"npm:sha.js@2.4.5": {
|
"npm:sha.js@2.4.5": {
|
||||||
"buffer": "github:jspm/nodelibs-buffer@0.1.0",
|
"buffer": "github:jspm/nodelibs-buffer@0.1.0",
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
console.log('here');
|
||||||
const verifyNoBrowserErrors = require('./helpers').verifyNoBrowserErrors;
|
const verifyNoBrowserErrors = require('./helpers').verifyNoBrowserErrors;
|
||||||
const scrollToEl = require('./helpers').scrollToEl;
|
const scrollToEl = require('./helpers').scrollToEl;
|
||||||
const fixFFTest = require('./helpers').fixFFTest;
|
const fixFFTest = require('./helpers').fixFFTest;
|
||||||
|
@ -50,34 +51,36 @@ describe('Scroll sync', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('APIs.guru specs test', ()=> {
|
if (process.env.JOB === 'e2e-guru') {
|
||||||
|
describe('APIs.guru specs test', ()=> {
|
||||||
|
|
||||||
// global.apisGuruList was loaded in onPrepare method of protractor config
|
// global.apisGuruList was loaded in onPrepare method of protractor config
|
||||||
let apisGuruList = global.apisGuruList;
|
let apisGuruList = global.apisGuruList;
|
||||||
|
|
||||||
// Remove certain APIs that are known to cause problems
|
// Remove certain APIs that are known to cause problems
|
||||||
delete apisGuruList['motaword.com']; // invalid (see https://github.com/BigstickCarpet/swagger-parser/issues/26)
|
delete apisGuruList['motaword.com']; // invalid (see https://github.com/BigstickCarpet/swagger-parser/issues/26)
|
||||||
delete apisGuruList['learnifier.com']; // allof object and no type
|
delete apisGuruList['learnifier.com']; // allof object and no type
|
||||||
delete apisGuruList['googleapis.com:mirror']; // bad urls in images
|
delete apisGuruList['googleapis.com:mirror']; // bad urls in images
|
||||||
delete apisGuruList['googleapis.com:discovery']; // non-string references
|
delete apisGuruList['googleapis.com:discovery']; // non-string references
|
||||||
delete apisGuruList['clarify.io']; // non-string references
|
delete apisGuruList['clarify.io']; // non-string references
|
||||||
delete apisGuruList['pushpay.com']; // https://github.com/Rebilly/ReDoc/issues/30
|
delete apisGuruList['pushpay.com']; // https://github.com/Rebilly/ReDoc/issues/30
|
||||||
|
|
||||||
// run quick version of e2e test on all builds except releases
|
// run quick version of e2e test on all builds except releases
|
||||||
if (process.env.TRAVIS && !process.env.TRAVIS_TAG) {
|
if (process.env.TRAVIS && !process.env.TRAVIS_TAG) {
|
||||||
console.log('Running on short APIs guru list');
|
console.log('Running on short APIs guru list');
|
||||||
apisGuruList = eachNth(apisGuruList, 10);
|
apisGuruList = eachNth(apisGuruList, 10);
|
||||||
} else {
|
} else {
|
||||||
console.log('Running on full APIs guru list')
|
console.log('Running on full APIs guru list')
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let apiName of Object.keys(apisGuruList)) {
|
for (let apiName of Object.keys(apisGuruList)) {
|
||||||
let apiInfo = apisGuruList[apiName].versions[apisGuruList[apiName].preferred];
|
let apiInfo = apisGuruList[apiName].versions[apisGuruList[apiName].preferred];
|
||||||
let url = apiInfo.swaggerUrl;
|
let url = apiInfo.swaggerUrl;
|
||||||
|
|
||||||
// temporary hack due to this issue: https://github.com/substack/https-browserify/issues/6
|
// temporary hack due to this issue: https://github.com/substack/https-browserify/issues/6
|
||||||
url = url.replace('https://', 'http://');
|
url = url.replace('https://', 'http://');
|
||||||
url = url.replace('apis-guru.github.io/', 'apis-guru.github.io:80/');
|
url = url.replace('apis-guru.github.io/', 'apis-guru.github.io:80/');
|
||||||
basicTests(url, `${apiName}:${apiInfo.info.version}\n${url}`);
|
basicTests(url, `${apiName}:${apiInfo.info.version}\n${url}`);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import {By} from 'angular2/platform/browser';
|
import {By} from '@angular/platform-browser';
|
||||||
|
|
||||||
/** Gets a child DebugElement by tag name. */
|
/** Gets a child DebugElement by tag name. */
|
||||||
export function getChildDebugElement(parent, tagName) {
|
export function getChildDebugElement(parent, tagName) {
|
||||||
|
|
|
@ -1,13 +1,11 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import {setBaseTestProviders} from 'angular2/testing';
|
import {setBaseTestProviders} from '@angular/core/testing';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
TEST_BROWSER_PLATFORM_PROVIDERS,
|
TEST_BROWSER_DYNAMIC_PLATFORM_PROVIDERS,
|
||||||
TEST_BROWSER_APPLICATION_PROVIDERS
|
TEST_BROWSER_DYNAMIC_APPLICATION_PROVIDERS
|
||||||
} from 'angular2/platform/testing/browser';
|
} from '@angular/platform-browser-dynamic/testing';
|
||||||
import {
|
|
||||||
|
|
||||||
ELEMENT_PROBE_PROVIDERS_PROD_MODE
|
|
||||||
} from 'angular2/platform/browser';
|
setBaseTestProviders(TEST_BROWSER_DYNAMIC_PLATFORM_PROVIDERS, [TEST_BROWSER_DYNAMIC_APPLICATION_PROVIDERS]);
|
||||||
setBaseTestProviders(TEST_BROWSER_PLATFORM_PROVIDERS, [TEST_BROWSER_APPLICATION_PROVIDERS, ELEMENT_PROBE_PROVIDERS_PROD_MODE]);
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user