From db8f9e8a9634b1f7cfb5702a2bb849b6126a74d4 Mon Sep 17 00:00:00 2001 From: Roman Hotsiy Date: Sat, 26 Dec 2015 23:12:10 +0200 Subject: [PATCH] options and options parsing mechanism --- demo/index.html | 2 +- .../StickySidebar/sticky-sidebar.js | 8 ++--- .../StickySidebar/sticky-sidebar.spec.js | 8 ++--- lib/components/Redoc/redoc.html | 2 +- lib/components/Redoc/redoc.js | 33 +++++++++++++++---- lib/components/Redoc/redoc.spec.js | 3 +- lib/components/SideMenu/side-menu.js | 10 +++--- lib/components/SideMenu/side-menu.spec.js | 6 ++-- lib/index.js | 4 ++- 9 files changed, 49 insertions(+), 27 deletions(-) diff --git a/demo/index.html b/demo/index.html index b025201c..ba33766e 100644 --- a/demo/index.html +++ b/demo/index.html @@ -12,7 +12,7 @@ - + Loading... diff --git a/lib/common/components/StickySidebar/sticky-sidebar.js b/lib/common/components/StickySidebar/sticky-sidebar.js index 997d197d..17eac49b 100644 --- a/lib/common/components/StickySidebar/sticky-sidebar.js +++ b/lib/common/components/StickySidebar/sticky-sidebar.js @@ -5,7 +5,7 @@ import {BrowserDomAdapter} from 'angular2/platform/browser'; @Component({ selector: 'sticky-sidebar', - inputs: ['scrollParent', 'scrollOffsetY'] + inputs: ['scrollParent', 'scrollYOffset'] }) @View({ template: ` @@ -37,7 +37,7 @@ export default class StickySidebar { } updatePosition() { - if ( this.scrollY + this.scrollOffsetY >= this.redocEl.offsetTop) { + if ( this.scrollY + this.scrollYOffset >= this.redocEl.offsetTop) { this.stick(); } else { this.unstick(); @@ -46,7 +46,7 @@ export default class StickySidebar { stick() { this.adapter.setStyle(this.element, 'position', 'fixed'); - this.adapter.setStyle(this.element, 'top', this.scrollOffsetY); + this.adapter.setStyle(this.element, 'top', this.scrollYOffset); } unstick() { @@ -60,7 +60,7 @@ export default class StickySidebar { ngOnInit() { this.redocEl = this.element.offsetParent; - this.scrollOffsetY = parseInt(this.scrollOffsetY); + this.scrollYOffset = parseInt(this.scrollYOffset); this.bind(); } diff --git a/lib/common/components/StickySidebar/sticky-sidebar.spec.js b/lib/common/components/StickySidebar/sticky-sidebar.spec.js index 379c9de1..9eb4e1a2 100644 --- a/lib/common/components/StickySidebar/sticky-sidebar.spec.js +++ b/lib/common/components/StickySidebar/sticky-sidebar.spec.js @@ -46,7 +46,7 @@ describe('Common components', () => { expect(component.stick).not.toHaveBeenCalled(); }); - it('should stick if scrolled more than scrollOffsetY', () => { + it('should stick if scrolled more than scrollYOffset', () => { spyOn(component, 'stick').and.callThrough(); fixture.detectChanges(); window.scrollY = 40; @@ -65,7 +65,7 @@ describe('Common components', () => { `
- +
` @@ -74,7 +74,7 @@ describe('Common components', () => { class TestApp { constructor() { this.options = {}; - this.options.scrollParent = window; - this.options.scrollOffsetY = 20; + this.scrollParent = window; + this.options.scrollYOffset = 20; } } diff --git a/lib/components/Redoc/redoc.html b/lib/components/Redoc/redoc.html index 762ff9e4..504d783e 100644 --- a/lib/components/Redoc/redoc.html +++ b/lib/components/Redoc/redoc.html @@ -1,5 +1,5 @@
- + diff --git a/lib/components/Redoc/redoc.js b/lib/components/Redoc/redoc.js index 3b59ad3b..eb6e31f2 100644 --- a/lib/components/Redoc/redoc.js +++ b/lib/components/Redoc/redoc.js @@ -8,12 +8,14 @@ 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 {options as defaultOptions} from '../../index'; import {ChangeDetectionStrategy} from 'angular2/core'; import {ElementRef} from 'angular2/core'; import {BrowserDomAdapter} from 'angular2/platform/browser'; import detectScollParent from 'scrollparent'; +let optionNames = new Set(['scrollYOffset']); @RedocComponent({ selector: 'redoc', @@ -24,20 +26,39 @@ import detectScollParent from 'scrollparent'; changeDetection: ChangeDetectionStrategy.Default }) export default class Redoc extends BaseComponent { - constructor(schemaMgr, elementRef) { + constructor(schemaMgr, elementRef, dom) { super(schemaMgr); this.element = elementRef.nativeElement; - let DOM = new BrowserDomAdapter(); + this.dom = dom; let el = this.element; - this.options = {}; //parse options (top level component doesn't support inputs) - this.options.scrollParent = detectScollParent(el); - this.options.scrollOffsetTop = parseInt(DOM.getAttribute(el, 'scroll-y-offset')) || 0; + this.scrollParent = detectScollParent(el); + this.parseOptions(); + this.options = Object.assign({}, defaultOptions, this.options); + } + + parseOptions() { + let attributesMap = this.dom.attributeMap(this.element); + this.options = {}; + Array.from(attributesMap.keys()) + //camelCasify + .map(k => ({ + attrName: k, + name: k.replace(/-(.)/g, (m, $1) => $1.toUpperCase()) + }) + ) + .filter(option => optionNames.has(option.name)) + .forEach(option => { + this.options[option.name] = attributesMap.get(option.attrName); + }); + + // post-process options + this.options.scrollYOffset = parseInt(this.options.scrollYOffset); } } -Redoc.parameters = Redoc.parameters.concat([[ElementRef]]); +Redoc.parameters = Redoc.parameters.concat([[ElementRef], [BrowserDomAdapter]]); // this doesn't work in side-menu.js because of some circular references issue SideMenu.parameters = SideMenu.parameters.concat([[Redoc]]); diff --git a/lib/components/Redoc/redoc.spec.js b/lib/components/Redoc/redoc.spec.js index dc03c488..5023a8e4 100644 --- a/lib/components/Redoc/redoc.spec.js +++ b/lib/components/Redoc/redoc.spec.js @@ -49,8 +49,7 @@ describe('Redoc components', () => { builder.createAsync(TestApp).then(fixture => { let component = getChildDebugElement(fixture.debugElement, 'redoc').componentInstance; fixture.detectChanges(); - console.log(component.options.scrollOffsetTop); - component.options.scrollOffsetTop.should.be.equal(50); + component.options.scrollYOffset.should.be.equal(50); fixture.destroy(); done(); }, err => done.fail(err)); diff --git a/lib/components/SideMenu/side-menu.js b/lib/components/SideMenu/side-menu.js index 59180fad..5e9c5c69 100644 --- a/lib/components/SideMenu/side-menu.js +++ b/lib/components/SideMenu/side-menu.js @@ -33,7 +33,7 @@ export default class SideMenu extends BaseComponent { this.adapter = adapter; this.redoc = redoc; - this.scrollParent = this.redoc.options.scrollParent; + this.scrollParent = this.redoc.scrollParent; // for some reason constructor is not run inside zone // as workaround running it manually @@ -65,7 +65,7 @@ export default class SideMenu extends BaseComponent { bindEvents() { this.prevOffsetY = this.scrollY(); - this.scrollOffsetY = this.redoc.options.scrollOffsetTop || 0; + this.scrollYOffset = this.redoc.options.scrollYOffset; this._cancel = {}; this._cancel.scroll = this.adapter.onAndCancel(this.scrollParent, 'scroll', () => { this.scrollHandler(); }); this._cancel.hash = this.adapter.onAndCancel(global, 'hashchange', evt => this.hashScroll(evt)); @@ -84,7 +84,7 @@ export default class SideMenu extends BaseComponent { scrollTo(el) { // TODO: rewrite this to use offsetTop as more reliable solution let subjRect = el.getBoundingClientRect(); - let offset = this.scrollY() + subjRect.top - this.scrollOffsetY + 1; + let offset = this.scrollY() + subjRect.top - this.scrollYOffset + 1; if (this.scrollParent.scrollTo) { this.scrollParent.scrollTo(0, offset); } else { @@ -162,11 +162,11 @@ export default class SideMenu extends BaseComponent { /* 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.scrollOffsetY) { + if (Math.floor(el.getBoundingClientRect().top) > this.scrollYOffset) { return INVIEW_POSITION.ABOVE; } - if (el.getBoundingClientRect().bottom <= this.scrollOffsetY) { + if (el.getBoundingClientRect().bottom <= this.scrollYOffset) { return INVIEW_POSITION.BELLOW; } return INVIEW_POSITION.INVIEW; diff --git a/lib/components/SideMenu/side-menu.spec.js b/lib/components/SideMenu/side-menu.spec.js index 0d29f025..8309145f 100644 --- a/lib/components/SideMenu/side-menu.spec.js +++ b/lib/components/SideMenu/side-menu.spec.js @@ -20,9 +20,9 @@ import SchemaManager from 'lib/utils/SchemaManager'; let _mockRedoc = { options: { - scrollOffsetTop: 0, - scrollParent: window - } + scrollYOffset: 0 + }, + scrollParent: window }; describe('Redoc components', () => { describe('SideMenu Component', () => { diff --git a/lib/index.js b/lib/index.js index c5152bb7..30b87de5 100644 --- a/lib/index.js +++ b/lib/index.js @@ -6,7 +6,9 @@ import SchemaManager from './utils/SchemaManager'; import {redocEvents} from './events'; export * from './components/index'; - +export var options = { + scrollYOffset: 0 +}; export function init(schemaUrl) { var promise = new Promise(function(resolve, reject) {