Add methods links

This commit is contained in:
Roman Hotsiy 2015-11-27 00:43:01 +02:00
parent 32681bdfba
commit 313c62cb2e
7 changed files with 72 additions and 11 deletions

View File

@ -1,6 +1,8 @@
<div class="method">
<div class="method-content">
<h2 class="method-header">{{data.methodInfo.summary}}</h2>
<h2 class="method-header">
<a class="method-link" href="#{{tag}}{{pointer}}"></a>{{data.methodInfo.summary}}
</h2>
<h3 class="method-endpoint">
<span class="http-method" [ng-class]="data.method">{{data.method}}</span>
<span class="api-url">{{data.apiUrl}}</span> <span class="path">{{data.path}}</span>

View File

@ -11,7 +11,8 @@ import SchemaSample from '../SchemaSample/schema-sample';
selector: 'method',
templateUrl: './lib/components/Method/method.html',
styleUrls: ['./lib/components/Method/method.css'],
directives: [ParamsList, ResponsesList, ResponsesSamples, SchemaSample]
directives: [ParamsList, ResponsesList, ResponsesSamples, SchemaSample],
inputs: ['tag']
})
export default class Method extends BaseComponent {
constructor(schemaMgr) {

View File

@ -10,6 +10,30 @@ responses-list, params-list {
color: $method-headers-color;
}
.method-link {
cursor: pointer;
margin-left: -15px;
padding: 0;
line-height: 1;
width: 15px;
display: inline-block;
}
.method-link:before {
content: "";
width: 15px;
height: 15px;
background-size: contain;
background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZlcnNpb249IjEuMSIgeD0iMCIgeT0iMCIgd2lkdGg9IjUxMiIgaGVpZ2h0PSI1MTIiIHZpZXdCb3g9IjAgMCA1MTIgNTEyIiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCA1MTIgNTEyIiB4bWw6c3BhY2U9InByZXNlcnZlIj48cGF0aCBmaWxsPSIjMDEwMTAxIiBkPSJNNDU5LjcgMjMzLjRsLTkwLjUgOTAuNWMtNTAgNTAtMTMxIDUwLTE4MSAwIC03LjktNy44LTE0LTE2LjctMTkuNC0yNS44bDQyLjEtNDIuMWMyLTIgNC41LTMuMiA2LjgtNC41IDIuOSA5LjkgOCAxOS4zIDE1LjggMjcuMiAyNSAyNSA2NS42IDI0LjkgOTAuNSAwbDkwLjUtOTAuNWMyNS0yNSAyNS02NS42IDAtOTAuNSAtMjQuOS0yNS02NS41LTI1LTkwLjUgMGwtMzIuMiAzMi4yYy0yNi4xLTEwLjItNTQuMi0xMi45LTgxLjYtOC45bDY4LjYtNjguNmM1MC01MCAxMzEtNTAgMTgxIDBDNTA5LjYgMTAyLjMgNTA5LjYgMTgzLjQgNDU5LjcgMjMzLjR6TTIyMC4zIDM4Mi4ybC0zMi4yIDMyLjJjLTI1IDI0LjktNjUuNiAyNC45LTkwLjUgMCAtMjUtMjUtMjUtNjUuNiAwLTkwLjVsOTAuNS05MC41YzI1LTI1IDY1LjUtMjUgOTAuNSAwIDcuOCA3LjggMTIuOSAxNy4yIDE1LjggMjcuMSAyLjQtMS40IDQuOC0yLjUgNi44LTQuNWw0Mi4xLTQyYy01LjQtOS4yLTExLjYtMTgtMTkuNC0yNS44IC01MC01MC0xMzEtNTAtMTgxIDBsLTkwLjUgOTAuNWMtNTAgNTAtNTAgMTMxIDAgMTgxIDUwIDUwIDEzMSA1MCAxODEgMGw2OC42LTY4LjZDMjc0LjYgMzk1LjEgMjQ2LjQgMzkyLjMgMjIwLjMgMzgyLjJ6Ii8+PC9zdmc+Cg==');
opacity: 0.5;
visibility: hidden;
display: inline-block;
vertical-align: middle;
}
.method-link:hover:before {
visibility: visible;
}
.method-endpoint {
margin: 0;
font-weight: 200;

View File

@ -6,6 +6,6 @@
<p *ng-if="tag.description" inner-html="{{ tag.description | marked }}"> </p>
</div>
<method *ng-for="#method of tag.methods" [pointer]="method.pointer" [attr.pointer]="method.pointer"
[attr.tag]="method.tag"></method>
[attr.tag]="method.tag" [tag]="method.tag"></method>
</tag>
</div>

View File

@ -3,6 +3,7 @@
import {RedocComponent, BaseComponent} from '../base';
import SchemaManager from '../../utils/SchemaManager';
import {NgZone} from 'angular2/angular2';
import {redocEvents} from '../../events';
const CHANGE = {
NEXT : 1,
@ -35,6 +36,20 @@ export default class SideMenu extends BaseComponent {
this.activeCatIdx = 0;
this.activeMethodIdx = -1;
this.prevOffsetY = null;
redocEvents.bootstrapped.subscribe(() => this.hashScroll());
}
hashScroll() {
let hash = window.location.hash;
if (!hash) return;
hash = hash.substr(1);
let tag = hash.split('/')[0];
let ptr = hash.substr(tag.length);
console.log(tag, ptr);
let el = this.getMethodEl(ptr, tag);
if (el) this.scrollTo(el);
}
bindScroll() {
@ -49,12 +64,16 @@ export default class SideMenu extends BaseComponent {
this.scrollToActive();
}
scrollToActive() {
let subjRect = this.getMethodEl().getBoundingClientRect();
scrollTo(el) {
let subjRect = el.getBoundingClientRect();
let offset = window.scrollY + subjRect.top - this.viewBoxTop;
window.scrollTo(0, offset);
}
scrollToActive() {
this.scrollTo(this.getCurrentMethodEl());
}
activate(catIdx, methodIdx) {
let menu = this.data.menu;
menu[this.activeCatIdx].active = false;
@ -110,13 +129,15 @@ export default class SideMenu extends BaseComponent {
return (methodIdx === 0 && catIdx === 0);
}
getMethodEl() {
let ptr = this.activeMethodPtr;
let tag = this.data.menu[this.activeCatIdx].name;
getMethodEl(ptr, tag) {
let selector = ptr ? `[pointer="${ptr}"][tag="${tag}"]` : `[tag="${tag}"]`;
return document.querySelector(selector);
}
getCurrentMethodEl() {
return this.getMethodEl(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.viewBoxTop) {
@ -134,7 +155,7 @@ export default class SideMenu extends BaseComponent {
this.prevOffsetY = window.scrollY;
let stable = false;
while(!stable) {
let activeMethodHost = this.getMethodEl();
let activeMethodHost = this.getCurrentMethodEl();
if (!activeMethodHost) return;
var elementInViewPos = this.getElementInViewPos(activeMethodHost);
if(isScrolledDown && elementInViewPos === INVIEW_POSITION.BELLOW) {

8
lib/events.js Normal file
View File

@ -0,0 +1,8 @@
'use strict';
import {EventEmitter} from 'angular2/angular2';
var bootsrEmmiter = new EventEmitter();
export var redocEvents = {
bootstrapped: bootsrEmmiter
};

View File

@ -3,14 +3,19 @@
import {bootstrap} from 'angular2/angular2';
import {Redoc} from './components/index';
import SchemaManager from './utils/SchemaManager';
import {redocEvents} from './events';
export * from './components/index';
export function init(schemaUrl) {
SchemaManager.instance().load(schemaUrl)
.then(() => bootstrap(Redoc))
.then(
() => console.log('ReDoc bootstrapped!'),
() => {
redocEvents.bootstrapped.next();
console.log('ReDoc bootstrapped!');
},
error => console.log(error)
);
}