diff --git a/lib/components/ApiInfo/api-info.ts b/lib/components/ApiInfo/api-info.ts
index fcb8163c..2ea4f634 100644
--- a/lib/components/ApiInfo/api-info.ts
+++ b/lib/components/ApiInfo/api-info.ts
@@ -1,7 +1,7 @@
'use strict';
-import { Component, ChangeDetectionStrategy, OnInit } from '@angular/core';
+import { Component, ChangeDetectionStrategy, OnInit, ElementRef } from '@angular/core';
import { SpecManager, BaseComponent } from '../base';
-import { OptionsService } from '../../services/index';
+import { OptionsService, Marker } from '../../services/index';
@Component({
selector: 'api-info',
@@ -12,8 +12,13 @@ import { OptionsService } from '../../services/index';
export class ApiInfo extends BaseComponent implements OnInit {
info: any = {};
specUrl: String;
- constructor(specMgr: SpecManager, private optionsService: OptionsService) {
+ constructor(specMgr: SpecManager,
+ private optionsService: OptionsService,
+ elRef: ElementRef,
+ marker: Marker
+ ) {
super(specMgr);
+ marker.addElement(elRef.nativeElement);
}
init() {
diff --git a/lib/components/Redoc/redoc.html b/lib/components/Redoc/redoc.html
index a688d51a..15f48a01 100644
--- a/lib/components/Redoc/redoc.html
+++ b/lib/components/Redoc/redoc.html
@@ -9,6 +9,7 @@
diff --git a/lib/components/Search/redoc-search.html b/lib/components/Search/redoc-search.html
new file mode 100644
index 00000000..c74bdbf3
--- /dev/null
+++ b/lib/components/Search/redoc-search.html
@@ -0,0 +1 @@
+
diff --git a/lib/components/Search/redoc-search.scss b/lib/components/Search/redoc-search.scss
new file mode 100644
index 00000000..5d4e87f3
--- /dev/null
+++ b/lib/components/Search/redoc-search.scss
@@ -0,0 +1,3 @@
+:host {
+ display: block;
+}
diff --git a/lib/components/Search/redoc-search.ts b/lib/components/Search/redoc-search.ts
new file mode 100644
index 00000000..18f21b28
--- /dev/null
+++ b/lib/components/Search/redoc-search.ts
@@ -0,0 +1,28 @@
+'use strict';
+import { Component, ChangeDetectionStrategy, OnInit, HostBinding } from '@angular/core';
+import { Marker } from '../../services/';
+
+@Component({
+ selector: 'redoc-search',
+ styleUrls: ['./redoc-search.css'],
+ templateUrl: './redoc-search.html',
+ changeDetection: ChangeDetectionStrategy.OnPush
+})
+export class RedocSearch implements OnInit {
+ logo:any = {};
+
+ constructor(private marker: Marker) {
+ }
+
+ init() {
+
+ }
+
+ update(val) {
+ this.marker.mark(val);
+ }
+
+ ngOnInit() {
+
+ }
+}
diff --git a/lib/components/SideMenu/side-menu.ts b/lib/components/SideMenu/side-menu.ts
index 27d30c1c..fbe3d7e7 100644
--- a/lib/components/SideMenu/side-menu.ts
+++ b/lib/components/SideMenu/side-menu.ts
@@ -5,7 +5,7 @@ import { Component, EventEmitter, Input, Output, ElementRef, ChangeDetectorRef,
//import { global } from '@angular/core/src/facade/lang';
import { trigger, state, animate, transition, style } from '@angular/core';
import { BaseComponent, SpecManager } from '../base';
-import { ScrollService, MenuService, OptionsService, MenuItem } from '../../services/';
+import { ScrollService, MenuService, OptionsService, MenuItem, Marker} from '../../services/';
import { BrowserDomAdapter as DOM } from '../../utils/browser-adapter';
const global = window;
@@ -55,7 +55,7 @@ export class SideMenu extends BaseComponent implements OnInit, OnDestroy {
constructor(specMgr:SpecManager, elementRef:ElementRef,
private scrollService:ScrollService, private menuService:MenuService,
- optionsService:OptionsService, private detectorRef:ChangeDetectorRef) {
+ optionsService:OptionsService, private detectorRef:ChangeDetectorRef, private marker:Marker) {
super(specMgr);
this.$element = elementRef.nativeElement;
@@ -64,7 +64,8 @@ export class SideMenu extends BaseComponent implements OnInit, OnDestroy {
this.options = optionsService.options;
- this.menuService.changed.subscribe((evt) => this.changed(evt));
+ this.menuService.changedActiveItem.subscribe((evt) => this.changed(evt));
+ this.menuService.changed.subscribe((evt) => this.detectorRef.detectChanges());
}
changed(item) {
@@ -147,4 +148,7 @@ export class SideMenu extends BaseComponent implements OnInit, OnDestroy {
ngOnInit() {
this.preinit();
}
+
+ ngAfterViewInit() {
+ }
}
diff --git a/lib/components/index.ts b/lib/components/index.ts
index 4b4ffc32..ecf74a79 100644
--- a/lib/components/index.ts
+++ b/lib/components/index.ts
@@ -15,15 +15,16 @@ import { Method } from './Method/method';
import { Warnings } from './Warnings/warnings';
import { SecurityDefinitions } from './SecurityDefinitions/security-definitions';
import { LoadingBar } from './LoadingBar/loading-bar';
+import { RedocSearch } from './Search/redoc-search';
import { Redoc } from './Redoc/redoc';
export const REDOC_DIRECTIVES = [
ApiInfo, ApiLogo, JsonSchema, JsonSchemaLazy, ParamsList, RequestSamples, ResponsesList,
ResponsesSamples, SchemaSample, SideMenu, MethodsList, Method, Warnings, Redoc, SecurityDefinitions,
- LoadingBar, SideMenuItems
+ LoadingBar, SideMenuItems, RedocSearch
];
export { ApiInfo, ApiLogo, JsonSchema, JsonSchemaLazy, ParamsList, RequestSamples, ResponsesList,
ResponsesSamples, SchemaSample, SideMenu, MethodsList, Method, Warnings, Redoc, SecurityDefinitions,
-LoadingBar, SideMenuItems }
+LoadingBar, SideMenuItems, RedocSearch }
diff --git a/lib/redoc.module.ts b/lib/redoc.module.ts
index b13b2dc3..4ba10894 100644
--- a/lib/redoc.module.ts
+++ b/lib/redoc.module.ts
@@ -16,6 +16,7 @@ import {
AppStateService,
ComponentParser,
ContentProjector,
+ Marker,
COMPONENT_PARSER_ALLOWED } from './services/';
import { SpecManager } from './utils/spec-manager';
@@ -35,6 +36,7 @@ import { SpecManager } from './utils/spec-manager';
ComponentParser,
ContentProjector,
LazyTasksService,
+ Marker,
{ provide: APP_ID, useValue: 'redoc' },
{ provide: ErrorHandler, useClass: CustomErrorHandler },
{ provide: COMPONENT_PARSER_ALLOWED, useValue: { 'security-definitions': SecurityDefinitions} }
diff --git a/lib/services/index.ts b/lib/services/index.ts
index 8a33b956..7200d85a 100644
--- a/lib/services/index.ts
+++ b/lib/services/index.ts
@@ -11,3 +11,4 @@ export * from './warnings.service';
export * from './component-parser.service';
export * from './content-projector.service';
+export * from './marker.service';
diff --git a/lib/services/marker.service.ts b/lib/services/marker.service.ts
new file mode 100644
index 00000000..bc42a725
--- /dev/null
+++ b/lib/services/marker.service.ts
@@ -0,0 +1,90 @@
+import { Injectable } from '@angular/core';
+import * as Mark from 'mark.js';
+import { MenuService } from './menu.service';
+
+const ROLL_LEN = 5;
+@Injectable()
+export class Marker {
+ permInstances = [];
+ rolledInstances = new Array(ROLL_LEN);
+ term: string;
+
+ currIdx = -1;
+
+ constructor(private menu: MenuService) {
+ menu.changedActiveItem.subscribe(() => {
+ this.roll();
+ });
+ }
+
+ addElement(el: Element) {
+ this.permInstances.push(new Mark(el));
+ }
+
+ newMarkerAtMenuItem(idx:number) {
+ let context = this.menu.getEl(idx);
+
+ if (this.menu.isTagItem(idx)) {
+ context = this.menu.getTagInfoEl(idx);
+ }
+ let newInst = context && new Mark(context);
+ if (newInst && this.term) {
+ newInst.mark(this.term);
+ }
+ return newInst;
+ }
+
+ roll() {
+ let newIdx = this.menu.activeIdx;
+ let diff = newIdx - this.currIdx;
+ this.currIdx = newIdx;
+ if (diff < 0) {
+ diff = - diff;
+ for (let i=0; i < Math.min(diff, ROLL_LEN); i++) {
+ let prevInst = this.rolledInstances.pop();
+ if(prevInst) prevInst.unmark();
+
+ let idx = newIdx - Math.floor(ROLL_LEN/2) + i;
+ let newMark = this.newMarkerAtMenuItem(idx);
+ this.rolledInstances.unshift(newMark);
+ }
+ } else {
+ for (let i=0; i < Math.min(diff, ROLL_LEN); i++) {
+ let oldInst = this.rolledInstances.shift();
+ oldInst && oldInst.unmark();
+
+ let idx = newIdx + Math.floor(ROLL_LEN/2) - i;
+ let newMark = this.newMarkerAtMenuItem(idx);
+ this.rolledInstances.push(newMark);
+ }
+ }
+ }
+
+ mark(term: string) {
+ this.term = term || null;
+ this.remark();
+ }
+
+ remark() {
+ for (let marker of this.permInstances) {
+ if (marker) {
+ marker.unmark();
+ if (this.term) marker.mark(this.term);
+ }
+ }
+ for (let marker of this.rolledInstances) {
+ if (marker) {
+ marker.unmark();
+ if (this.term) marker.mark(this.term);
+ }
+ }
+ }
+
+ unmark() {
+ this.term = null;
+ this.remark();
+ }
+
+ updateMark() {
+ }
+}
diff --git a/lib/services/menu.service.ts b/lib/services/menu.service.ts
index ab0a2602..cdc8f64f 100644
--- a/lib/services/menu.service.ts
+++ b/lib/services/menu.service.ts
@@ -44,6 +44,7 @@ export interface MenuItem {
@Injectable()
export class MenuService {
changed: EventEmitter
= new EventEmitter();
+ changedActiveItem: EventEmitter = new EventEmitter();
items: MenuItem[];
activeIdx: number = -1;
@@ -135,6 +136,7 @@ export class MenuService {
getEl(flatIdx:number):Element {
if (flatIdx < 0) return null;
+ if (flatIdx > this.flatItems.length - 1) return null;
let currentItem = this.flatItems[flatIdx];
if (!currentItem) return;
if (currentItem.isGroup) currentItem = this.flatItems[flatIdx + 1];
@@ -156,6 +158,18 @@ export class MenuService {
return selector ? document.querySelector(selector) : null;
}
+ isTagItem(flatIdx: number):boolean {
+ let item = this.flatItems[flatIdx];
+ return item && item.metadata && item.metadata.type === 'tag';
+ }
+
+ getTagInfoEl(flatIdx: number):Element {
+ if (!this.isTagItem(flatIdx)) return null;
+
+ let el = this.getEl(flatIdx);
+ return el && el.querySelector('.tag-info');
+ }
+
getCurrentEl():Element {
return this.getEl(this.activeIdx);
}
@@ -186,7 +200,7 @@ export class MenuService {
cItem.parent.active = true;
cItem = cItem.parent;
}
- this.changed.next(item);
+ this.changedActiveItem.next(item);
}
changeActive(offset = 1):boolean {
diff --git a/manual-types/index.d.ts b/manual-types/index.d.ts
index 8d37c8e6..1a39435e 100644
--- a/manual-types/index.d.ts
+++ b/manual-types/index.d.ts
@@ -6,6 +6,7 @@ declare module "scrollparent"
declare module "slugify"
declare module "url"
declare module "json-pointer";
+declare module "mark.js";
declare module "*.css" {
const content: string;
diff --git a/package.json b/package.json
index 96f0c3c9..4ce9ea78 100644
--- a/package.json
+++ b/package.json
@@ -111,6 +111,7 @@
"hint.css": "^2.3.2",
"json-pointer": "^0.6.0",
"json-schema-ref-parser": "^3.1.2",
+ "mark.js": "github:julmot/mark.js",
"openapi-sampler": "^0.3.3",
"prismjs": "^1.5.1",
"remarkable": "^1.6.2",