UNPKG

apeman-react-mixins

Version:
188 lines (165 loc) 4.56 kB
/** * Mixin for page components * @module ApPageMixin * */ 'use strict' import React from 'react' import assert from 'assert' /** @lends ApPageMixin */ let ApPageMixin = { // -------------------- // Custom // -------------------- $apPageMixed: true, /** * Register page view resolver. * @param {object} resolver - A resolver instance */ registerPageViewResolver(resolver) { const s = this s._pageViewResolver = resolver; }, /** * Register page stack. * @param {string} name - Name of stack * @param {object} stacker - A stacker instance */ registerPageViewStacker(name, stacker) { const s = this s._pageStacks = s._pageStacks || {} let resolver = s._pageViewResolver; if (!resolver) { throw new Error('Resolver not found call `.registerPageViewResolver()` before this.') } stacker.stackName = name; stacker.addListener('push', s.pageStackViewDidPush) stacker.addListener('pop', s.pageStackViewDidPop) s._pageStacks[name] = stacker; }, /** * De register page stack * @param name */ deregisterPageStack(name) { const s = this let stacker = s._pageStacks[name]; stacker.removeListener('push', s.pageStackViewDidPush) stacker.removeListener('pop', s.pageStackViewDidPop) delete s._pageStacks[name]; }, /** * Get page main stack. * @param {string} name - Name of stack * @returns {ApViewStack.Stacker} */ getPageStack(name) { const s = this let stack = s._pageStacks[name]; if (!stack) { throw new Error('Stack not found. Call `.registerPageStack()` on componentWillMount.') } return stack; }, /** * Create page url from stacker * @param {object} stacker - View stacker. * @returns {string} - Page url */ pageURLWithStacker(stacker) { const s = this return `/${s.pageName}/${stacker.stackName}/${stacker.toURL()}`; }, /** * Reset page stacks. */ resetPageStacks() { const s = this let stacks = s._pageStacks || {} for (let name of Object.keys(stacks)) { let stack = stacks[name]; stack.reset() } }, /** * Restore page url * @param {string} url */ restorePageURL(url) { const s = this if (!url) { return; } let names = url.replace(/^\//, '').split(/\//g) if (names[0] === s.pageName) { names.shift() } if (names.length === 0) { s.resetPageStacks() return; } let stackName = names.shift(), stackerURL = names.join('/') if (!stackName) { return; } try { let stacker = s.getPageStack(stackName) stacker.fromURL(stackerURL) stacker.reload() } catch (e) { console.warn(`[${s.pageName}] Failed to restore url: ${url}`) } }, /** * Get layout for page. * @returns {object} */ getPageLayouts() { const s = this return s._pageLayouts || {} }, /** * Update page layout. * @param {string} name - Name of layout. * @param {object} layout - Layout data. */ updatePageLayout(name, layout) { const s = this let _pageLayouts = Object.assign({}, s.getPageLayouts()) _pageLayouts[name] = Object.assign( {}, _pageLayouts[name] || {}, layout ) s._pageLayouts = _pageLayouts; s.layout(true) }, // -------------------- // Specs // -------------------- getInitialState() { return {} }, // -------------------- // Lifecycle // -------------------- componentWillMount () { const s = this s.pageName = s.pageName || (s.getPageName && s.getPageName()) assert.ok(s.$apLocaleMixed, "ApLocaleMixin is required.") assert.ok(s.pageName, 'pageName is required.') }, componentWillUnmount () { const s = this // Cleanup stacks. for (let name of Object.keys(s._pageStacks || {})) { s.deregisterPageStack(name) } }, // ------------------ // Private // ------------------ _pageLayouts: null, _pageStacks: null, _pageViewResolver: null } export default Object.freeze(ApPageMixin)