253 lines
6.8 KiB
JavaScript
253 lines
6.8 KiB
JavaScript
|
var Backbone = require('backbone');
|
||
|
var _ = require('underscore');
|
||
|
var checkAndBuildOpts = require('builder/helpers/required-opts');
|
||
|
var populateRoute = require('./populate-route');
|
||
|
|
||
|
var ROUTE_LAYERS = 'layers';
|
||
|
var ROUTE_WIDGETS = 'widgets';
|
||
|
var ROUTE_SETTINGS = 'settings';
|
||
|
var BASE_LAYER_ROUTE = 'layer/:layerId';
|
||
|
var ROUTE_WIDGET = 'widget/:widgetId';
|
||
|
var ROUTE_BASEMAP = 'basemap';
|
||
|
var ROUTE_LAYER_DATA_TAB = BASE_LAYER_ROUTE + '/data';
|
||
|
var ROUTE_LAYER_ANALYSES_TAB = BASE_LAYER_ROUTE + '/analyses(/:nodeId)';
|
||
|
var ROUTE_LAYER_STYLE_TAB = BASE_LAYER_ROUTE + '/style';
|
||
|
var ROUTE_LAYER_POPUPS_TAB = BASE_LAYER_ROUTE + '/popups';
|
||
|
var ROUTE_LAYER_LEGENDS_TAB = BASE_LAYER_ROUTE + '/legends';
|
||
|
var ROUTE_MODAL = 'modal';
|
||
|
var ROUTE_ADD_POINT = BASE_LAYER_ROUTE + '/add/point';
|
||
|
var ROUTE_ADD_LINE = BASE_LAYER_ROUTE + '/add/line';
|
||
|
var ROUTE_ADD_POLYGON = BASE_LAYER_ROUTE + '/add/polygon';
|
||
|
var EDIT_FEATURE = BASE_LAYER_ROUTE + '/edit/:featureId';
|
||
|
|
||
|
var REQUIRED_OPTS = [
|
||
|
'modals',
|
||
|
'editorModel',
|
||
|
'widgetDefinitionsCollection',
|
||
|
'handleModalsRoute',
|
||
|
'handleAnalysesRoute',
|
||
|
'handleWidgetRoute'
|
||
|
];
|
||
|
|
||
|
var ROUTES = [
|
||
|
['root', ''],
|
||
|
['root', ROUTE_LAYERS],
|
||
|
['settings', ROUTE_SETTINGS],
|
||
|
['layer', BASE_LAYER_ROUTE],
|
||
|
['widgets', ROUTE_WIDGETS],
|
||
|
['widget', ROUTE_WIDGET],
|
||
|
['layer_data', ROUTE_LAYER_DATA_TAB],
|
||
|
['layer_analyses', ROUTE_LAYER_ANALYSES_TAB],
|
||
|
['layer_style', ROUTE_LAYER_STYLE_TAB],
|
||
|
['layer_style', BASE_LAYER_ROUTE],
|
||
|
['layer_popups', ROUTE_LAYER_POPUPS_TAB],
|
||
|
['layer_legends', ROUTE_LAYER_LEGENDS_TAB],
|
||
|
['add_feature_point', ROUTE_ADD_POINT],
|
||
|
['add_feature_line', ROUTE_ADD_LINE],
|
||
|
['add_feature_polygon', ROUTE_ADD_POLYGON],
|
||
|
['edit_feature', EDIT_FEATURE],
|
||
|
['modal', ROUTE_MODAL],
|
||
|
['basemap', ROUTE_BASEMAP]
|
||
|
];
|
||
|
|
||
|
module.exports = (function () {
|
||
|
var initialized = false;
|
||
|
var routeModel = new Backbone.Model();
|
||
|
// keep last route before a modal, so we can replace /modal with it
|
||
|
var previousRoute;
|
||
|
// Routes that should not be kept as a "previous" route
|
||
|
var UNSTORABLE_ROUTES;
|
||
|
|
||
|
function generateRoute (routeName, model) {
|
||
|
return function () {
|
||
|
model.set('currentRoute', [routeName].concat(Array.prototype.slice.call(arguments)));
|
||
|
};
|
||
|
}
|
||
|
|
||
|
return {
|
||
|
init: function (options) {
|
||
|
if (initialized) {
|
||
|
throw new Error('Router can only be initialized once');
|
||
|
}
|
||
|
|
||
|
checkAndBuildOpts(options, REQUIRED_OPTS, this);
|
||
|
|
||
|
var self = this;
|
||
|
initialized = true;
|
||
|
this.appRouter = new Backbone.Router();
|
||
|
|
||
|
ROUTES.forEach(function (route) {
|
||
|
self.appRouter.route(route[1], generateRoute(route[0], routeModel));
|
||
|
});
|
||
|
UNSTORABLE_ROUTES = [
|
||
|
ROUTE_ADD_POINT,
|
||
|
ROUTE_ADD_LINE,
|
||
|
ROUTE_ADD_POLYGON,
|
||
|
EDIT_FEATURE
|
||
|
].map(function (route) {
|
||
|
return self.appRouter._routeToRegExp(route);
|
||
|
});
|
||
|
|
||
|
this._initBinds();
|
||
|
},
|
||
|
|
||
|
_initBinds: function () {
|
||
|
this.getRouteModel().on('change:currentRoute', this._onChangeRoute, this);
|
||
|
},
|
||
|
|
||
|
_onChangeRoute: function (routeModel) {
|
||
|
var currentRoute = routeModel.get('currentRoute');
|
||
|
|
||
|
if (!currentRoute) return;
|
||
|
|
||
|
this._handleModalsRoute(currentRoute, this._modals);
|
||
|
this._handleAnalysesRoute(currentRoute);
|
||
|
this._handleWidgetRoute(currentRoute, this._widgetDefinitionsCollection);
|
||
|
|
||
|
this._editorModel.set('edition', false);
|
||
|
},
|
||
|
|
||
|
getRouter: function () {
|
||
|
return this.appRouter;
|
||
|
},
|
||
|
|
||
|
getRouteModel: function () {
|
||
|
return routeModel;
|
||
|
},
|
||
|
|
||
|
goBack: function () {
|
||
|
Backbone.history.history.back();
|
||
|
},
|
||
|
|
||
|
goToDefaultRoute: function () {
|
||
|
this.navigate('');
|
||
|
},
|
||
|
|
||
|
replaceWithRoot: function () {
|
||
|
this.navigate('', { replace: true });
|
||
|
},
|
||
|
|
||
|
goToBaseMap: function (layerId) {
|
||
|
this.navigate(ROUTE_BASEMAP);
|
||
|
},
|
||
|
|
||
|
goToLayerList: function () {
|
||
|
this.navigate(ROUTE_LAYERS);
|
||
|
},
|
||
|
|
||
|
goToSettings: function () {
|
||
|
this.navigate(ROUTE_SETTINGS);
|
||
|
},
|
||
|
|
||
|
goToDataTab: function (layerId) {
|
||
|
this.navigate(populateRoute(ROUTE_LAYER_DATA_TAB, { layerId: layerId }));
|
||
|
},
|
||
|
|
||
|
goToAnalysisTab: function (layerId, options) {
|
||
|
this.navigate(populateRoute(ROUTE_LAYER_ANALYSES_TAB, { layerId: layerId }), options);
|
||
|
},
|
||
|
|
||
|
goToAnalysisNode: function (layerId, nodeId, options) {
|
||
|
var args = { layerId: layerId, nodeId: nodeId };
|
||
|
|
||
|
this.navigate(populateRoute(ROUTE_LAYER_ANALYSES_TAB, args), options);
|
||
|
},
|
||
|
|
||
|
goToStyleTab: function (layerId) {
|
||
|
this.navigate(populateRoute(ROUTE_LAYER_STYLE_TAB, { layerId: layerId }));
|
||
|
},
|
||
|
|
||
|
goToPopupsTab: function (layerId) {
|
||
|
this.navigate(populateRoute(ROUTE_LAYER_POPUPS_TAB, { layerId: layerId }));
|
||
|
},
|
||
|
|
||
|
goToLegendsTab: function (layerId) {
|
||
|
this.navigate(populateRoute(ROUTE_LAYER_LEGENDS_TAB, { layerId: layerId }));
|
||
|
},
|
||
|
|
||
|
goToWidgetList: function () {
|
||
|
this.navigate(ROUTE_WIDGETS);
|
||
|
},
|
||
|
|
||
|
goToWidget: function (widgetId) {
|
||
|
var route = routeModel.get('currentRoute');
|
||
|
var options = {};
|
||
|
|
||
|
if (_.isArray(route) && route[0] === 'widget') {
|
||
|
options.replace = true;
|
||
|
}
|
||
|
|
||
|
this.navigate(populateRoute(ROUTE_WIDGET, { widgetId: widgetId }), options);
|
||
|
},
|
||
|
|
||
|
getCurrentRoute: function () {
|
||
|
return Backbone.history.getPath();
|
||
|
},
|
||
|
|
||
|
saveCurrentRoute: function () {
|
||
|
var currentRoute = this.getCurrentRoute();
|
||
|
var canBeSaved = !UNSTORABLE_ROUTES.some(function (regex) {
|
||
|
return regex.test(currentRoute);
|
||
|
});
|
||
|
|
||
|
if (canBeSaved === true) {
|
||
|
previousRoute = currentRoute;
|
||
|
}
|
||
|
},
|
||
|
|
||
|
addPoint: function (layerId) {
|
||
|
this._addFeature(ROUTE_ADD_POINT, layerId);
|
||
|
},
|
||
|
|
||
|
addLine: function (layerId) {
|
||
|
this._addFeature(ROUTE_ADD_LINE, layerId);
|
||
|
},
|
||
|
|
||
|
addPolygon: function (layerId) {
|
||
|
this._addFeature(ROUTE_ADD_POLYGON, layerId);
|
||
|
},
|
||
|
|
||
|
goToPreviousRoute: function (options) {
|
||
|
previousRoute = previousRoute || options.fallback;
|
||
|
|
||
|
if (previousRoute !== null && previousRoute !== undefined) {
|
||
|
this.navigate(previousRoute, options.options);
|
||
|
previousRoute = null;
|
||
|
} else {
|
||
|
Backbone.history.history.back();
|
||
|
}
|
||
|
},
|
||
|
|
||
|
_addFeature: function (route, layerId) {
|
||
|
this.navigate(populateRoute(route, { layerId: layerId }));
|
||
|
},
|
||
|
|
||
|
editFeature: function (feature) {
|
||
|
var featureId = feature.get('cartodb_id');
|
||
|
var layerId = feature.getLayerId();
|
||
|
|
||
|
this.navigate(populateRoute(EDIT_FEATURE, {
|
||
|
layerId: layerId,
|
||
|
featureId: featureId
|
||
|
}));
|
||
|
},
|
||
|
|
||
|
navigate: function (route, options) {
|
||
|
this.saveCurrentRoute();
|
||
|
|
||
|
options = _.extend({
|
||
|
trigger: true
|
||
|
}, options);
|
||
|
|
||
|
this.appRouter.navigate(route, options);
|
||
|
},
|
||
|
|
||
|
replaceState: function (route) {
|
||
|
var root = Backbone.history.root;
|
||
|
var newRoute = root + route;
|
||
|
|
||
|
window.history.replaceState(null, null, newRoute);
|
||
|
}
|
||
|
};
|
||
|
})();
|