Plato on Github
Report Home
region.js
Maintainability
67.40
Lines of code
181
Difficulty
32.21
Estimated Errors
0.88
Function weight
By Complexity
By SLOC
// Region // ------ // // Manage the visual regions of your composite application. See // http://lostechies.com/derickbailey/2011/12/12/composite-js-apps-regions-and-region-managers/ Marionette.Region = function(options){ this.options = options || {}; this.el = Marionette.getOption(this, "el"); if (!this.el){ var err = new Error("An 'el' must be specified for a region."); err.name = "NoElError"; throw err; } if (this.initialize){ var args = Array.prototype.slice.apply(arguments); this.initialize.apply(this, args); } }; // Region Type methods // ------------------- _.extend(Marionette.Region, { // Build an instance of a region by passing in a configuration object // and a default region type to use if none is specified in the config. // // The config object should either be a string as a jQuery DOM selector, // a Region type directly, or an object literal that specifies both // a selector and regionType: // // ```js // { // selector: "#foo", // regionType: MyCustomRegion // } // ``` // buildRegion: function(regionConfig, defaultRegionType){ var regionIsString = (typeof regionConfig === "string"); var regionSelectorIsString = (typeof regionConfig.selector === "string"); var regionTypeIsUndefined = (typeof regionConfig.regionType === "undefined"); var regionIsType = (typeof regionConfig === "function"); if (!regionIsType && !regionIsString && !regionSelectorIsString) { throw new Error("Region must be specified as a Region type, a selector string or an object with selector property"); } var selector, RegionType; // get the selector for the region if (regionIsString) { selector = regionConfig; } if (regionConfig.selector) { selector = regionConfig.selector; } // get the type for the region if (regionIsType){ RegionType = regionConfig; } if (!regionIsType && regionTypeIsUndefined) { RegionType = defaultRegionType; } if (regionConfig.regionType) { RegionType = regionConfig.regionType; } // build the region instance var region = new RegionType({ el: selector }); // override the `getEl` function if we have a parentEl // this must be overridden to ensure the selector is found // on the first use of the region. if we try to assign the // region's `el` to `parentEl.find(selector)` in the object // literal to build the region, the element will not be // guaranteed to be in the DOM already, and will cause problems if (regionConfig.parentEl){ region.getEl = function(selector) { var parentEl = regionConfig.parentEl; if (_.isFunction(parentEl)){ parentEl = parentEl(); } return parentEl.find(selector); }; } return region; } }); // Region Instance Methods // ----------------------- _.extend(Marionette.Region.prototype, Backbone.Events, { // Displays a backbone view instance inside of the region. // Handles calling the `render` method for you. Reads content // directly from the `el` attribute. Also calls an optional // `onShow` and `close` method on your view, just after showing // or just before closing the view, respectively. show: function(view){ this.ensureEl(); if (view !== this.currentView) { this.close(); view.render(); this.open(view); } else { view.render(); } Marionette.triggerMethod.call(view, "show"); Marionette.triggerMethod.call(this, "show", view); this.currentView = view; }, ensureEl: function(){ if (!this.$el || this.$el.length === 0){ this.$el = this.getEl(this.el); } }, // Override this method to change how the region finds the // DOM element that it manages. Return a jQuery selector object. getEl: function(selector){ return Marionette.$(selector); }, // Override this method to change how the new view is // appended to the `$el` that the region is managing open: function(view){ this.$el.empty().append(view.el); }, // Close the current view, if there is one. If there is no // current view, it does nothing and returns immediately. close: function(){ var view = this.currentView; if (!view || view.isClosed){ return; } // call 'close' or 'remove', depending on which is found if (view.close) { view.close(); } else if (view.remove) { view.remove(); } Marionette.triggerMethod.call(this, "close"); delete this.currentView; }, // Attach an existing view to the region. This // will not call `render` or `onShow` for the new view, // and will not replace the current HTML for the `el` // of the region. attachView: function(view){ this.currentView = view; }, // Reset the region by closing any existing view and // clearing out the cached `$el`. The next time a view // is shown via this region, the region will re-query the // DOM for the region's `el`. reset: function(){ this.close(); delete this.$el; } }); // Copy the `extend` function used by Backbone's classes Marionette.Region.extend = Marionette.extend;