All files / ext.wikilambda.edit/store/modules router.js

100% Statements 55/55
100% Branches 20/20
100% Functions 15/15
100% Lines 55/55

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181                25x           25x 4x             25x 3x                   25x 14x                     25x 8x 8x   8x                 25x 6x 6x 24x 5x       6x             25x 5x       5x 5x             25x 4x       4x 4x     25x                 1x     1x         1x     1x                           6x 1x     5x 5x 1x 1x   5x 5x                 10x 10x 2x   2x 2x 2x 8x 2x 6x 2x 4x 3x   1x                     4x 4x 4x 4x        
/*!
 * WikiLambda Vue editor: Application store router
 *
 * @copyright 2020– Abstract Wikipedia team; see AUTHORS.txt
 * @license MIT
 */
'use strict';
 
const Constants = require( '../../Constants.js' );
 
/**
 * @param {string} uriPath
 * @return {boolean}
 */
const isEvaluateFunctionCallPath = function ( uriPath ) {
	return uriPath === Constants.PATHS.EVALUTATE_FUNCTION_CALL;
};
 
/**
 * @param {string} uriPath
 * @return {boolean}
 */
const isNewOrExistingObjectPath = function ( uriPath ) {
	return [ Constants.PATHS.CREATE_Z_OBJECT, Constants.PATHS.EDIT_Z_OBJECT ].indexOf( uriPath ) !== -1;
};
 
/**
 * Analyses the zObject to determine if it is a function
 *
 * @param {Object} context The ZObject context in which we're operating
 * @param {Object} uriQuery The contextual mw.Uri's query sub-object
 * @return {boolean}
 */
const isFunction = function ( context, uriQuery ) {
	return uriQuery.zid === Constants.Z_FUNCTION || context.rootGetters.getCurrentZObjectType === Constants.Z_FUNCTION;
};
 
/**
 * Analyses the path and zObject to determine if the current view is the functionEditor
 *
 * @param {Object} context The ZObject context in which we're operating
 * @param {Object} uriQuery The contextual mw.Uri's query sub-object
 * @param {Object} uriPath The contextual mw.Uri's path sub-object
 * @return {boolean}
 */
const isFunctionEditor = function ( context, uriQuery, uriPath ) {
	var isEditpath = Constants.PATHS.EDIT_Z_OBJECT.indexOf( uriPath ) !== -1;
	var isFunctionObject = isFunction( context, uriQuery );
 
	return isEditpath && isFunctionObject;
};
 
/**
 * Whether the given URI path string is a known view in Constants.VIEWS
 *
 * @param {string} view
 * @return {boolean}
 */
const viewIsInvalid = function ( view ) {
	let viewExist = false;
	Object.keys( Constants.VIEWS ).forEach( function ( viewKey ) {
		if ( Constants.VIEWS[ viewKey ] === view ) {
			viewExist = true;
		}
	} );
 
	return !viewExist;
};
 
/**
 * @param {string} path
 * @param {string} query
 */
const pushToHistoryState = function ( path, query ) {
	const stateObj = {
		path: path,
		query: query
	};
	const queryString = path + '?' + $.param( query );
	window.history.pushState( stateObj, null, queryString );
};
 
/**
 * @param {string} path
 * @param {string} query
 */
const replaceToHistoryState = function ( path, query ) {
	const stateObj = {
		path: path,
		query: query
	};
	const queryString = path + '?' + $.param( query );
	window.history.replaceState( stateObj, null, queryString );
};
 
module.exports = {
	namespaced: true,
	state: {
		currentPath: mw.Uri().path,
		currentView: Constants.VIEWS.Z_OBJECT_VIEWER,
		queryParams: mw.Uri().query
	},
	getters: {
		getCurrentView: function ( state ) {
			return state.currentView;
		},
		getQueryParams: function ( state ) {
			return state.queryParams;
		}
	},
	mutations: {
		CHANGE_CURRENT_VIEW: function ( state, view ) {
			state.currentView = view;
		},
		CHANGE_QUERY_PARAMS: function ( state, queryParams ) {
			state.queryParams = queryParams;
		}
	},
	actions: {
		/**
		 * Changes the current View and Query params and updates the history states.
		 * This method is used to navigate between pages within the UI.
		 *
		 * @param {Object} context
		 * @param {Object} payload
		 * @param {string} payload.to
		 * @param {Object} payload.params
		 */
		navigate: function ( context, payload ) {
			if ( viewIsInvalid( payload.to ) ) {
				return;
			}
 
			context.commit( 'CHANGE_CURRENT_VIEW', payload.to );
			if ( payload.params ) {
				const queryParamsObject = $.extend( {}, context.state.queryParams, payload.params );
				context.commit( 'CHANGE_QUERY_PARAMS', queryParamsObject );
			}
			const query = $.extend( {}, context.state.queryParams, { view: context.state.currentView } );
			pushToHistoryState( context.state.currentPath, query );
 
		},
		/**
		 * Evaluate the Uri path to evaluate what View should be displayed.
		 *
		 * @param {Object} context
		 */
		evaluateUri: function ( context ) {
			var uri = mw.Uri();
			if ( uri.query.view ) {
				context.commit( 'CHANGE_CURRENT_VIEW', uri.query.view );
				// we remove the view from the query params
				const params = $.extend( {}, uri.query );
				delete params.view;
				context.commit( 'CHANGE_QUERY_PARAMS', params );
			} else if ( isFunctionEditor( context, uri.query, uri.path ) ) {
				context.dispatch( 'changeCurrentView', Constants.VIEWS.FUNCTION_EDITOR );
			} else if ( isFunction( context, uri.query ) ) {
				context.dispatch( 'changeCurrentView', Constants.VIEWS.FUNCTION_VIEWER );
			} else if ( isEvaluateFunctionCallPath( uri.path ) || isNewOrExistingObjectPath( uri.path ) ) {
				context.dispatch( 'changeCurrentView', Constants.VIEWS.Z_OBJECT_EDITOR );
			} else {
				context.dispatch( 'changeCurrentView', Constants.VIEWS.Z_OBJECT_VIEWER );
			}
		},
		/**
		 * Handle the changes of a view and replace the history state.
		 * This method is usually used when the change of view is made dynamically.
		 *
		 * @param {Object} context
		 * @param {string} view
		 */
		changeCurrentView: function ( context, view ) {
			context.commit( 'CHANGE_CURRENT_VIEW', view );
			const uri = mw.Uri();
			const query = $.extend( uri.query, { view: view } );
			replaceToHistoryState( uri.path, query );
		}
	}
};