1 /* eslint max-statements: ["error", 41] */
4 var _ = require('lodash');
5 var Marionette = require('backbone.marionette');
6 var behaviourLookup = require('./lookup');
7 var unsafeParseHtml = require('../../utils/unsafe-parse-html');
9 var cachedWidgets = {};
11 function register(widgets) {
12 var keys = _.keys(widgets);
13 _.each(keys, function(key) {
14 var value = widgets[key];
15 cachedWidgets[key] = value;
19 function WidgetManager() {
23 WidgetManager.prototype.add = function(widget) {
24 this._widgets.push(widget);
27 WidgetManager.prototype.destroy = function() {
28 _.each(this._widgets, function(item) {
34 // eslint-disable-next-line complexity
35 function render(template, data, view) {
37 var pseudoSelectorString = '';
39 pseudoSelectorString += view.childViewContainer;
40 if (view.$el.length > 0) {
41 var viewEl = view.$el[0];
43 pseudoSelectorString += '#' + viewEl.id;
45 if (viewEl.classList.length > 0) {
46 pseudoSelectorString += '.' + Array.prototype.join(viewEl.classList, '.');
52 "Cannot render the template since it's false, null or undefined. For context, we tried to render into this element: " +
58 if (typeof template === 'function') {
59 templateFunc = template;
61 templateFunc = Marionette.TemplateCache.get(template);
64 var generatedText = templateFunc(data);
66 var prerenderedViews = data.prerenderedViews;
68 // No widgets? Just return the text
69 if (!prerenderedViews) return generatedText;
71 var dom = unsafeParseHtml(generatedText);
72 var widgetManager = view.widgetManager;
74 var widgetsRendered = dom.querySelectorAll('.widget');
75 var widgetsRenderedLen = widgetsRendered.length;
77 if (widgetsRenderedLen && !widgetManager) {
78 // Create a region manager if one doesn't already exist
79 widgetManager = new WidgetManager();
80 view.widgetManager = widgetManager;
83 for (var i = 0; i < widgetsRenderedLen; i++) {
84 var widgetEl = widgetsRendered[i];
85 var id = widgetEl.getAttribute('data-widget-id');
87 var attrs = prerenderedViews[id];
90 widgetEl.removeAttribute('data-widget-id');
92 var Widget = cachedWidgets[attrs.widgetName];
93 var model = attrs.model;
94 model.el = widgetEl; // Existing element
95 model.template = false; // No template (attach)
97 // Attach the widget to the prerendered content
98 var widget = new Widget(model);
101 // Add the widget to the widget manager
102 widgetManager.add(widget);
108 function getPrerendered(widgetName, model, id) {
109 var Widget = cachedWidgets[widgetName];
110 return Widget.getPrerendered(model, id);
113 var Behavior = Marionette.Behavior.extend({
114 initialize: function() {
115 if (this.view.templateHelpers) throw new Error('Cannot use templateHelpers with Widgets');
116 this.view.templateHelpers = function() {
117 // TODO: add global template helpers
120 getPrerendered: getPrerendered
124 onDestroy: function() {
125 if (this.view.widgetManager) {
126 this.view.widgetManager.destroy();
127 this.view.widgetManager = null;
132 // No simple way to do this...
133 Marionette.Renderer = {
137 behaviourLookup.register('Widgets', Behavior);