UNPKG

routebar

Version:

A visual component for navigating between panel cells containing user content.

353 lines (304 loc) 23 kB
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>screenManager.js - Documentation</title> <script src="scripts/prettify/prettify.js"></script> <script src="scripts/prettify/lang-css.js"></script> <!--[if lt IE 9]> <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script> <![endif]--> <link type="text/css" rel="stylesheet" href="https://code.ionicframework.com/ionicons/2.0.1/css/ionicons.min.css"> <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css"> <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css"> </head> <body> <input type="checkbox" id="nav-trigger" class="nav-trigger" /> <label for="nav-trigger" class="navicon-button x"> <div class="navicon"></div> </label> <label for="nav-trigger" class="overlay"></label> <nav> <h2><a href="index.html">Home</a></h2><h3>Classes</h3><ul><li><a href="Animation.html">Animation</a><ul class='methods'><li data-type='method'><a href="Animation.html#configure">configure</a></li><li data-type='method'><a href="Animation.html#destroy">destroy</a></li><li data-type='method'><a href="Animation.html#goToCenter">goToCenter</a></li><li data-type='method'><a href="Animation.html#goToCorrectSide">goToCorrectSide</a></li><li data-type='method'><a href="Animation.html#goToWrongSide">goToWrongSide</a></li></ul></li><li><a href="ArrowsControl.html">ArrowsControl</a><ul class='methods'><li data-type='method'><a href="ArrowsControl.html#configure">configure</a></li><li data-type='method'><a href="ArrowsControl.html#destroy">destroy</a></li><li data-type='method'><a href="ArrowsControl.html#disable">disable</a></li><li data-type='method'><a href="ArrowsControl.html#enable">enable</a></li><li data-type='method'><a href="ArrowsControl.html#isEnable">isEnable</a></li></ul></li><li><a href="BaseDispatcher.html">BaseDispatcher</a><ul class='methods'><li data-type='method'><a href="BaseDispatcher.html#add">add</a></li><li data-type='method'><a href="BaseDispatcher.html#configure">configure</a></li><li data-type='method'><a href="BaseDispatcher.html#destroy">destroy</a></li><li data-type='method'><a href="BaseDispatcher.html#remove">remove</a></li><li data-type='method'><a href="BaseDispatcher.html#runActions">runActions</a></li></ul></li><li><a href="ControlManager.html">ControlManager</a><ul class='methods'><li data-type='method'><a href="ControlManager.html#add">add</a></li><li data-type='method'><a href="ControlManager.html#configure">configure</a></li><li data-type='method'><a href="ControlManager.html#destroy">destroy</a></li><li data-type='method'><a href="ControlManager.html#disable">disable</a></li><li data-type='method'><a href="ControlManager.html#disableAll">disableAll</a></li><li data-type='method'><a href="ControlManager.html#enable">enable</a></li><li data-type='method'><a href="ControlManager.html#enableAll">enableAll</a></li><li data-type='method'><a href="ControlManager.html#enableByValues">enableByValues</a></li><li data-type='method'><a href="ControlManager.html#isEnable">isEnable</a></li><li data-type='method'><a href="ControlManager.html#remove">remove</a></li></ul></li><li><a href="KeydownControl.html">KeydownControl</a><ul class='methods'><li data-type='method'><a href="KeydownControl.html#configure">configure</a></li><li data-type='method'><a href="KeydownControl.html#destroy">destroy</a></li><li data-type='method'><a href="KeydownControl.html#disable">disable</a></li><li data-type='method'><a href="KeydownControl.html#enable">enable</a></li><li data-type='method'><a href="KeydownControl.html#isEnable">isEnable</a></li></ul></li><li><a href="module-Errors-ArgumentError.html">ArgumentError</a></li><li><a href="module-Errors-FatalError.html">FatalError</a></li><li><a href="module-Errors-NotRealizedError.html">NotRealizedError</a></li><li><a href="module-Errors-PathNotFoundError.html">PathNotFoundError</a></li><li><a href="Moving.html">Moving</a><ul class='methods'><li data-type='method'><a href="Moving.html#activate">activate</a></li><li data-type='method'><a href="Moving.html#addPlugin">addPlugin</a></li><li data-type='method'><a href="Moving.html#animateWrongSide">animateWrongSide</a></li><li data-type='method'><a href="Moving.html#configure">configure</a></li><li data-type='method'><a href="Moving.html#destroy">destroy</a></li><li data-type='method'><a href="Moving.html#getControlManager">getControlManager</a></li><li data-type='method'><a href="Moving.html#getScreenManager">getScreenManager</a></li><li data-type='method'><a href="Moving.html#goToScreen">goToScreen</a></li><li data-type='method'><a href="Moving.html#move">move</a></li><li data-type='method'><a href="Moving.html#moveBack">moveBack</a></li><li data-type='method'><a href="Moving.html#reload">reload</a></li><li data-type='method'><a href="Moving.html#removePlugin">removePlugin</a></li><li data-type='method'><a href="Moving.html#resetConfig">resetConfig</a></li><li data-type='method'><a href="Moving.html#setScreen">setScreen</a></li></ul></li><li><a href="ScreenManager.html">ScreenManager</a><ul class='methods'><li data-type='method'><a href="ScreenManager.html#clearHistory">clearHistory</a></li><li data-type='method'><a href="ScreenManager.html#configure">configure</a></li><li data-type='method'><a href="ScreenManager.html#destroy">destroy</a></li><li data-type='method'><a href="ScreenManager.html#findShortestPath">findShortestPath</a></li><li data-type='method'><a href="ScreenManager.html#getCurScreen">getCurScreen</a></li><li data-type='method'><a href="ScreenManager.html#getRelativeScreen">getRelativeScreen</a></li><li data-type='method'><a href="ScreenManager.html#popHistory">popHistory</a></li></ul></li><li><a href="ScreenModel.html">ScreenModel</a><ul class='methods'><li data-type='method'><a href="ScreenModel.html#.clearUpdateFn">clearUpdateFn</a></li><li data-type='method'><a href="ScreenModel.html#.configure">configure</a></li><li data-type='method'><a href="ScreenModel.html#.getMainScreen">getMainScreen</a></li><li data-type='method'><a href="ScreenModel.html#.registerUpdateFn">registerUpdateFn</a></li><li data-type='method'><a href="ScreenModel.html#.setMainScreen">setMainScreen</a></li><li data-type='method'><a href="ScreenModel.html#.unregisterUpdateFn">unregisterUpdateFn</a></li><li data-type='method'><a href="ScreenModel.html#childrenLength">childrenLength</a></li><li data-type='method'><a href="ScreenModel.html#defaultChildIndex">defaultChildIndex</a></li><li data-type='method'><a href="ScreenModel.html#defaultParentIndex">defaultParentIndex</a></li><li data-type='method'><a href="ScreenModel.html#getChild">getChild</a></li><li data-type='method'><a href="ScreenModel.html#getChildIndex">getChildIndex</a></li><li data-type='method'><a href="ScreenModel.html#getParent">getParent</a></li><li data-type='method'><a href="ScreenModel.html#getParentIndex">getParentIndex</a></li><li data-type='method'><a href="ScreenModel.html#html">html</a></li><li data-type='method'><a href="ScreenModel.html#isDirectedGraph">isDirectedGraph</a></li><li data-type='method'><a href="ScreenModel.html#isTemporary">isTemporary</a></li><li data-type='method'><a href="ScreenModel.html#parentsLength">parentsLength</a></li><li data-type='method'><a href="ScreenModel.html#pushChildren">pushChildren</a></li><li data-type='method'><a href="ScreenModel.html#pushParents">pushParents</a></li><li data-type='method'><a href="ScreenModel.html#removeChild">removeChild</a></li><li data-type='method'><a href="ScreenModel.html#removeParent">removeParent</a></li><li data-type='method'><a href="ScreenModel.html#resetChildren">resetChildren</a></li><li data-type='method'><a href="ScreenModel.html#resetParents">resetParents</a></li><li data-type='method'><a href="ScreenModel.html#sortChildren">sortChildren</a></li><li data-type='method'><a href="ScreenModel.html#sortParents">sortParents</a></li><li data-type='method'><a href="ScreenModel.html#toString">toString</a></li></ul></li><li><a href="SwipesControl.html">SwipesControl</a><ul class='methods'><li data-type='method'><a href="SwipesControl.html#configure">configure</a></li><li data-type='method'><a href="SwipesControl.html#destroy">destroy</a></li><li data-type='method'><a href="SwipesControl.html#disable">disable</a></li><li data-type='method'><a href="SwipesControl.html#enable">enable</a></li><li data-type='method'><a href="SwipesControl.html#isEnable">isEnable</a></li></ul></li></ul><h3>Modules</h3><ul><li><a href="module-Batch.html">Batch</a><ul class='methods'><li data-type='method'><a href="module-Batch.html#.animateWrongSide">animateWrongSide</a></li><li data-type='method'><a href="module-Batch.html#.configure">configure</a></li><li data-type='method'><a href="module-Batch.html#.move">move</a></li><li data-type='method'><a href="module-Batch.html#.moveBack">moveBack</a></li><li data-type='method'><a href="module-Batch.html#.reload">reload</a></li><li data-type='method'><a href="module-Batch.html#.removeAll">removeAll</a></li><li data-type='method'><a href="module-Batch.html#.setScreen">setScreen</a></li></ul></li><li><a href="module-Errors.html">Errors</a></li><li><a href="module-MainModule.html">MainModule</a></li><li><a href="module-RbManager.html">RbManager</a><ul class='methods'><li data-type='method'><a href="module-RbManager.html#.init">init</a></li><li data-type='method'><a href="module-RbManager.html#.remove">remove</a></li></ul></li><li><a href="module-Utils.html">Utils</a><ul class='methods'><li data-type='method'><a href="module-Utils.html#.capitalizeFirstLetter">capitalizeFirstLetter</a></li><li data-type='method'><a href="module-Utils.html#.cycledNumber">cycledNumber</a></li><li data-type='method'><a href="module-Utils.html#.getStartSide">getStartSide</a></li><li data-type='method'><a href="module-Utils.html#.inherite">inherite</a></li><li data-type='method'><a href="module-Utils.html#.mixin">mixin</a></li><li data-type='method'><a href="module-Utils.html#.mobileCheck">mobileCheck</a></li><li data-type='method'><a href="module-Utils.html#.nop">nop</a></li><li data-type='method'><a href="module-Utils.html#.oppositeSide">oppositeSide</a></li></ul></li></ul><h3>Interfaces</h3><ul><li><a href="IControl.html">IControl</a><ul class='methods'><li data-type='method'><a href="IControl.html#configure">configure</a></li><li data-type='method'><a href="IControl.html#destroy">destroy</a></li><li data-type='method'><a href="IControl.html#disable">disable</a></li><li data-type='method'><a href="IControl.html#enable">enable</a></li><li data-type='method'><a href="IControl.html#isEnable">isEnable</a></li></ul></li><li><a href="IPlugin.html">IPlugin</a><ul class='methods'><li data-type='method'><a href="IPlugin.html#configure">configure</a></li><li data-type='method'><a href="IPlugin.html#destroy">destroy</a></li></ul></li></ul> </nav> <div id="main"> <h1 class="page-title">screenManager.js</h1> <section> <article> <pre class="prettyprint source linenums"><code>define(['utils', 'screenModel', 'IPlugin', 'errors'], function(Utils, Screen, IPlugin, Errors) { "use strict"; /** * @class * Класс-менеджер моделей контента * @constructor ScreenManager * @extends IPlugin */ function ScreenManager() { this._history = []; this._curScreen = null; this._relativeUpdateFn = this._updateRelativeScreen.bind(this); Screen.registerUpdateFn(this._relativeUpdateFn); } Utils.inherite(ScreenManager, IPlugin); /** * Применить конфигурацию к панели. Учитывает опции maxHistoryLength, isDirectPath, cyclicStep, getLeft, getTop, getRight, getBottom. * @param {Moving~config} config - конфигурация * @memberOf ScreenManager */ ScreenManager.prototype.configure = function(config) { if (typeof config === 'object') { if (config.maxHistoryLength !== undefined) { if (typeof config.maxHistoryLength === 'number' &amp;&amp; config.maxHistoryLength >= 0) { this._maxHistoryLength = config.maxHistoryLength; if (this._history.length > this._maxHistoryLength) { this._history = this._history.slice(this._history.length - this._maxHistoryLength); } } else { throw new Errors.ArgumentError('maxHistoryLength', config.maxHistoryLength); } } if (config.isDirectPath !== undefined) { this._isDirectPath = config.isDirectPath; } if (config.cyclicStep !== undefined) { this._cyclicStep = config.cyclicStep; } if (config.getLeft !== undefined) { this._getLeft = config.getLeft; } if (config.getRight !== undefined) { this._getRight = config.getRight; } if (config.getTop !== undefined) { this._getTop = config.getTop; } if (config.getBottom !== undefined) { this._getBottom = config.getBottom; } if (config.savePrevious !== undefined) { this._savePrevious = config.savePrevious; } } }; ScreenManager.prototype._updateScreens = function(side, screen, isSaveHistory) { var updated = false; if (screen) { if (this._curScreen !== screen) { updated = true; } this._curScreen = screen; } else if (this.getRelativeScreen(side)) { var prevScreen = this._curScreen; this._curScreen = this.getRelativeScreen(side); if (side !== 'center') { updated = true; } } if (updated &amp;&amp; isSaveHistory !== false) { this._history.push({ screen: prevScreen, side: Utils.oppositeSide(side), lastSide: this._lastSide, lastScreen: this._lastScreen }); if (this._history.length > this._maxHistoryLength) { this._history.shift(); } } return this._curScreen; }; ScreenManager.prototype._getRelativeScreenByScreen = function(screen, side) { if (!(screen instanceof Screen)) { throw new Errors.ArgumentError('screen', screen); } if (Utils.sidesWithCenter.indexOf(side) === -1) { throw new Errors.ArgumentError('side', side); } if (side === 'center') { return screen; } else if (side === 'left') { return this._getLeft(screen); } else if (side === 'top') { return this._getTop(screen, this._cyclicStep); } else if (side === 'right') { return this._getRight(screen); } else if (side === 'bottom') { return this._getBottom(screen, this._cyclicStep); } return null; }; ScreenManager.prototype._setRelativeScreen = function(side, baseScreen, targetScreen, isCheckSave, reverse) { if (!(targetScreen instanceof Screen)) { throw new Errors.ArgumentError('targetScreen', targetScreen); } if (!(baseScreen instanceof Screen)) { throw new Errors.ArgumentError('baseScreen', baseScreen); } var savePrevious = isCheckSave ? this._savePrevious : true; if (side === (reverse ? 'left' : 'right') &amp;&amp; savePrevious) { var childIndex = baseScreen.getChildIndex(targetScreen); if (childIndex !== -1) { baseScreen.defaultChildIndex(childIndex); } else { throw new Errors.FatalError('Base screen is ' + baseScreen.toString() + '. Child screen not found: ', targetScreen.toString()); } } if (side === (reverse ? 'right' : 'left') &amp;&amp; savePrevious) { var parentIndex = baseScreen.getParentIndex(targetScreen); if (parentIndex !== -1) { baseScreen.defaultParentIndex(parentIndex); } else { throw new Errors.FatalError('Base screen is ' + baseScreen.toString() + '. Parent screen not found: ', targetScreen.toString()); } } }; ScreenManager.prototype._updateRelativeScreen = function(screen) { if (!(screen instanceof Screen)) { throw new Errors.ArgumentError('screen', screen); } if (!this._getRight(screen)) { screen.defaultChildIndex(0); } if (!this._getLeft(screen)) { screen.defaultParentIndex(0); } }; /** * Возвращает модель текущей ячейки панели. * @returns {ScreenModel|null} модель текущей ячейки панели * @memberOf ScreenManager */ ScreenManager.prototype.getCurScreen = function() { return this._curScreen; }; /** * Возвращает модель, располагающуюся рядом с текущей ячейкой панели. * @param {string} side - сторона относительно текущей ячейки * @returns {ScreenModel|null} модель текущей ячейки панели * @memberOf ScreenManager */ ScreenManager.prototype.getRelativeScreen = function(side) { return this._getRelativeScreenByScreen(this._curScreen, side); }; /** * Очистить историю перемещений в панели. * @memberOf ScreenManager */ ScreenManager.prototype.clearHistory = function() { this._history = []; }; /** * Удаляет из истории перемещений последнее удачное перемещение в панели и возвращает модель, которая располагается в последней посещенной ячейке из истории. * @returns {ScreenModel} Модель из последнего удачного перемещения в истории * @memberOf ScreenManager */ ScreenManager.prototype.popHistory = function() { var res = this._history.pop(); if (res) { this._lastSide = res.lastSide; this._lastScreen = res.lastScreen; } else { this._lastSide = null; this._lastScreen = null; } return res; }; ScreenManager.prototype._containsHistory = function(screen) { return this._history.some(function(val) { return val.screen === screen; }); }; /** * Поиск кратчайшего пути от одной модели до другой. Если для разных ячеек панели используются одинаковые модели, результат непредсказуем. * @param {ScreenModel} start - Модель, от которой начинает поиск пути * @param {ScreenModel} end - Конечная модель, в которую ищется путь * @returns {null|ScreenModel[]} Путь от начальной модели до конечной модели в панели * @memberOf ScreenManager */ ScreenManager.prototype.findShortestPath = function (start, end) { function findPaths(start, end) { var costs = {}, open = {'0': [start]}, predecessors = {}, keys; var addToOpen = function (cost, vertex) { if (!open[cost]) open[cost] = []; open[cost].push(vertex); }; costs[start] = 0; while (open) { if(!(keys = Object.keys(open)).length) break; keys.sort(function (a, b) { return a - b; }); var key = keys[0], bucket = open[key], node = bucket.shift(), currentCost = +key, adjacentNodes; if (self._isDirectPath) { adjacentNodes = node &amp;&amp; node._children .concat(node._parents)// todo если оставить только children будет настоящий поиск в графе .concat(self._getRelativeScreenByScreen(node, 'top')) .concat(self._getRelativeScreenByScreen(node, 'bottom')) || []; } else { adjacentNodes = node &amp;&amp; [self._getRelativeScreenByScreen(node, 'left'), self._getRelativeScreenByScreen(node, 'top'), self._getRelativeScreenByScreen(node, 'right'), self._getRelativeScreenByScreen(node, 'bottom') ] || []; } if (!bucket.length) delete open[key]; for (var i = 0; i &lt; adjacentNodes.length; i++) { var vertex = adjacentNodes[i], totalCost = currentCost + 1, vertexCost = costs[vertex]; if ((vertexCost === undefined) || (vertexCost > totalCost)) { costs[vertex] = totalCost; addToOpen(totalCost, vertex); predecessors[vertex] = node; } } } if (costs[end] === undefined) { return null; } else { return predecessors; } } function extractShortest(predecessors, end) { var nodes = [], u = end; while (u) { nodes.push(u); u = predecessors[u]; } nodes.reverse(); return nodes; } var self = this; var predecessors = findPaths(start, end); return !predecessors ? null : extractShortest(predecessors, end); }; /** * Уничтожить ScreenManager * @memberOf ScreenManager */ ScreenManager.prototype.destroy = function() { Screen.unregisterUpdateFn(this._relativeUpdateFn); this._history = null; this._curScreen = null; }; return ScreenManager; });</code></pre> </article> </section> </div> <br class="clear"> <footer> Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.3</a> using the Minami theme. </footer> <script>prettyPrint();</script> <script src="scripts/linenumber.js"></script> </body> </html>