/static/js/controllers/placescontroller.js
JavaScript | 187 lines | 128 code | 33 blank | 26 comment | 7 complexity | 134d31a58fc3c8a08b1ab4f420e8f3e8 MD5 | raw file
Possible License(s): Apache-2.0
- define([
- 'config',
- 'underscore',
- 'backbone',
- 'lib/promise',
- 'lib/routecontroller',
- 'views/stackplacesview',
- 'models/sitemodel',
- 'lib/bridge',
- 'lib/assert',
- 'logger',
- 'lib/errors'
- ], function(
- config,
- util,
- Backbone,
- Promise,
- RouteController,
- PlacesView,
- SiteModel,
- Bridge,
- assert,
- logger,
- errors
- ) {
- var bridge = new Bridge();
- var onPlaceVisit = function (view, model, e) {
- e.preventDefault();
- bridge.showViewer();
- };
- var PlacesController = RouteController.extend({
- enter: function(options) {
- util.extend(this, options || {});
- if(!this.bridge) {
- this.bridge = bridge;
- }
- if(this.pageState){
- this.bridge.stateModel = this.pageState;
- }
- this.watch('view:stacklist', this.bridge, 'onReturnToStackList');
- return this;
- },
- exit: function(){
- // stop noticing when stacks are added/removed
- // stop noticing when an individual stack is changed
- var unwatches = this._watches,
- handle = null;
- while((handle = unwatches.shift())){
- handle();
- }
- },
- // I am not keen on having the `stack_id` be implicit, but I'll make
- // the method name abundantly clear and call it good for now. -GB.
- createPlaceInActiveStack: function (placeData) {
- var stack_id = this.pageState.get('stack_id');
- return this.createPlace(stack_id, placeData);
- },
- // Call this controller action to add a new place to a currently existing
- // stack.
- createPlace: function (stack_id, placeData) {
- var stackCollection = this.pageState.stacksCollection;
- assert.contains(
- placeData,
- ['place_url', 'place_title']
- ).orThrow(
- errors.KeysMissingError,
- "placescontroller: Data given to createPlace is missing required properties"
- );
-
- stackCollection.fetchStack(stack_id).then(function (stackModel) {
- // we don't have the place_id we need until lattice responds to the link request...
- stackModel.link(placeData);
- });
- return this;
- },
- changeStack: function (stack_id) {
- var pageState = this.pageState;
- var stackCollection = pageState.stacksCollection;
- pageState.set({ stack_id: stack_id });
- return stackCollection.fetchStack(stack_id).then(function (stack) {
- stackCollection.put(stack, { at: 0 });
- // Set this stackModel as active in the collection
- // (selects this stack, de-selects all other stacks).
- // TODO: this should happen outside of the setTimeout, however,
- // if we do this now, the stack view does not get rendered as
- // selected properly even when the model is selected. Check when
- // `render` method is called.
- stackCollection.selectStack(stack.id);
- var msg = util.extend(stack.toJSON(), { origin: config.appName });
- bridge.changeStack(msg);
- });
- },
- viewPlaces: function (stack_id, place_id) {
- var appView = this.appView;
- var self = this;
- var placesPromise = new Promise();
- this.changeStack(stack_id).then(function (stack) {
- var places = stack.places();
- // Default to stack's active `place_id` if not found.
- place_id = place_id || stack.get('place_id');
- // Replace previously-displayed view.
- appView.widget('#pane--places', self.placesView(stack));
- // If places have not yet been loaded for this stack, load them.
- // Semi-magical place fetching behavior to work around
- // <https://bugzilla.mozilla.org/show_bug.cgi?id=755146#c5>
- var placesReady = places.loaded ? places : places.fetch({ diff: true });
- Promise.when(placesReady, function (places) {
- placesPromise.resolve(places);
- var msg = util.extend(stack.toJSON(), { origin: config.appName });
- bridge
- .viewPlaces(msg)
- .showViewer();
- appView.activateChild('#pane--places');
- // Place should exist in collection at this point, since we fetched
- // all places.
- places
- .changePlace(place_id)
- .selectPlace(place_id);
- }, util.bind(placesPromise.reject, placesPromise));
- });
- return placesPromise;
- },
- // Create or return a memoized placesView for a given stack.
- placesView: function (stack) {
- var placesView = this.placesView = this.placesView || {};
- return placesView[stack.id] = placesView[stack.id] || this.createPlacesView(
- stack
- );
- },
- // Create a placesView for a given stackModel.
- // Configures event handlers, etc.
- createPlacesView: function (stack) {
- var appView = this.appView;
- var placesView = new PlacesView({
- model: stack,
- collection: stack.places(),
- bridge: this.bridge
- });
- // Recalculate mask height after adding places.
- var refitMask = function (collection) {
- var active = appView.activePane;
- if (active === '#pane--places') appView.fitMaskTo('#pane--places');
- };
- placesView.collection.bind('add', refitMask).bind('remove', refitMask);
- // Bind additional logic to visit events for this view.
- placesView.bind('visit', onPlaceVisit);
- return placesView;
- },
- onReturnToStackList: function(){
- this.pageState.navigate('stacks/active', true);
- }
- });
- // module return is an instance
- return new PlacesController();
- });