mirror of
				https://github.com/Redocly/redoc.git
				synced 2025-11-04 01:37:32 +03:00 
			
		
		
		
	
		
			
				
	
	
		
			163 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			163 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
'use strict';
 | 
						|
 | 
						|
import { ElementRef,
 | 
						|
  ChangeDetectorRef,
 | 
						|
  Input,
 | 
						|
  Component,
 | 
						|
  OnInit,
 | 
						|
  OnDestroy,
 | 
						|
  HostBinding
 | 
						|
} from '@angular/core';
 | 
						|
 | 
						|
import { BrowserDomAdapter as DOM } from '../../utils/browser-adapter';
 | 
						|
import { BaseComponent } from '../base';
 | 
						|
 | 
						|
import * as detectScollParent from 'scrollparent';
 | 
						|
 | 
						|
import { SpecManager } from '../../utils/spec-manager';
 | 
						|
import {
 | 
						|
  SearchService,
 | 
						|
  OptionsService,
 | 
						|
  Options,
 | 
						|
  Hash,
 | 
						|
  AppStateService,
 | 
						|
  SchemaHelper,
 | 
						|
  MenuService,
 | 
						|
  Marker
 | 
						|
} from '../../services/';
 | 
						|
import { LazyTasksService } from '../../shared/components/LazyFor/lazy-for';
 | 
						|
 | 
						|
function getPreOptions() {
 | 
						|
  return Redoc._preOptions || {};
 | 
						|
}
 | 
						|
 | 
						|
@Component({
 | 
						|
  selector: 'redoc',
 | 
						|
  templateUrl: './redoc.html',
 | 
						|
  styleUrls: ['./redoc.css'],
 | 
						|
  providers: [
 | 
						|
    SpecManager,
 | 
						|
    MenuService,
 | 
						|
    SearchService,
 | 
						|
    LazyTasksService,
 | 
						|
    Marker
 | 
						|
  ]
 | 
						|
  //changeDetection: ChangeDetectionStrategy.OnPush
 | 
						|
})
 | 
						|
export class Redoc extends BaseComponent implements OnInit {
 | 
						|
  static _preOptions: any = {};
 | 
						|
 | 
						|
  error: any;
 | 
						|
  specLoaded: boolean;
 | 
						|
  options: Options;
 | 
						|
 | 
						|
  loadingProgress: number;
 | 
						|
 | 
						|
  @Input() specUrl: string;
 | 
						|
  @HostBinding('class.loading') specLoading: boolean = false;
 | 
						|
  @HostBinding('class.loading-remove') specLoadingRemove: boolean = false;
 | 
						|
 | 
						|
  private element: HTMLElement;
 | 
						|
  private $parent: Element;
 | 
						|
  private $refElem: Element;
 | 
						|
 | 
						|
  constructor(
 | 
						|
    specMgr: SpecManager,
 | 
						|
    optionsMgr: OptionsService,
 | 
						|
    elementRef: ElementRef,
 | 
						|
    private changeDetector: ChangeDetectorRef,
 | 
						|
    private appState: AppStateService,
 | 
						|
    private lazyTasksService: LazyTasksService,
 | 
						|
    private hash: Hash
 | 
						|
  ) {
 | 
						|
    super(specMgr);
 | 
						|
    SchemaHelper.setSpecManager(specMgr);
 | 
						|
    // merge options passed before init
 | 
						|
    optionsMgr.options = getPreOptions();
 | 
						|
 | 
						|
    this.element = elementRef.nativeElement;
 | 
						|
    this.$parent = this.element.parentNode as Element;
 | 
						|
    this.$refElem = this.element.nextElementSibling;
 | 
						|
 | 
						|
    //parse options (top level component doesn't support inputs)
 | 
						|
    optionsMgr.parseOptions( this.element );
 | 
						|
    let scrollParent = detectScollParent( this.element );
 | 
						|
    if (scrollParent === (document.scrollingElement || document.documentElement)) scrollParent = window;
 | 
						|
    optionsMgr.options.$scrollParent = scrollParent;
 | 
						|
    this.options = optionsMgr.options;
 | 
						|
    this.lazyTasksService.allSync = !this.options.lazyRendering;
 | 
						|
  }
 | 
						|
 | 
						|
  hideLoadingAnimation() {
 | 
						|
    if (this.options.hideLoading) {
 | 
						|
      return
 | 
						|
    }
 | 
						|
    requestAnimationFrame(() => {
 | 
						|
      this.specLoadingRemove = true;
 | 
						|
      setTimeout(() => {
 | 
						|
        this.specLoadingRemove = false;
 | 
						|
        this.specLoading = false;
 | 
						|
      }, 400);
 | 
						|
    });
 | 
						|
  }
 | 
						|
 | 
						|
  showLoadingAnimation() {
 | 
						|
    if (this.options.hideLoading) {
 | 
						|
      return
 | 
						|
    }
 | 
						|
    this.specLoading = true;
 | 
						|
    this.specLoadingRemove = false;
 | 
						|
  }
 | 
						|
 | 
						|
  load() {
 | 
						|
    // bunlde spec directly if passsed or load by URL
 | 
						|
    this.specMgr.load(this.options.spec || this.options.specUrl).catch(err => {
 | 
						|
      throw err;
 | 
						|
    });
 | 
						|
 | 
						|
    this.appState.loading.subscribe(loading => {
 | 
						|
      if (loading) {
 | 
						|
        this.showLoadingAnimation();
 | 
						|
      } else {
 | 
						|
        this.hideLoadingAnimation();
 | 
						|
      }
 | 
						|
    });
 | 
						|
 | 
						|
    this.specMgr.spec.subscribe((spec) => {
 | 
						|
      if (!spec) {
 | 
						|
        this.appState.startLoading();
 | 
						|
      } else {
 | 
						|
        this.specLoaded = true;
 | 
						|
        this.changeDetector.markForCheck();
 | 
						|
        this.changeDetector.detectChanges();
 | 
						|
        setTimeout(() => {
 | 
						|
          this.hash.start();
 | 
						|
        });
 | 
						|
      }
 | 
						|
    });
 | 
						|
  }
 | 
						|
 | 
						|
  ngOnInit() {
 | 
						|
    this.lazyTasksService.loadProgress.subscribe(progress => this.loadingProgress = progress)
 | 
						|
    this.appState.error.subscribe(_err => {
 | 
						|
      if (!_err) return;
 | 
						|
 | 
						|
      this.appState.stopLoading();
 | 
						|
 | 
						|
      if (this.loadingProgress === 100) return;
 | 
						|
      this.error = _err;
 | 
						|
      this.changeDetector.markForCheck();
 | 
						|
    });
 | 
						|
 | 
						|
    if (this.specUrl) {
 | 
						|
      this.options.specUrl = this.specUrl;
 | 
						|
    }
 | 
						|
    this.load();
 | 
						|
  }
 | 
						|
 | 
						|
  ngOnDestroy() {
 | 
						|
    let $clone = this.element.cloneNode();
 | 
						|
    this.$parent.insertBefore($clone, this.$refElem);
 | 
						|
  }
 | 
						|
}
 |