1 /* 2 * ***** BEGIN LICENSE BLOCK ***** 3 * Zimbra Collaboration Suite Web Client 4 * Copyright (C) 2007, 2009, 2010, 2013, 2014, 2016 Synacor, Inc. 5 * 6 * The contents of this file are subject to the Common Public Attribution License Version 1.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at: https://www.zimbra.com/license 9 * The License is based on the Mozilla Public License Version 1.1 but Sections 14 and 15 10 * have been added to cover use of software over a computer network and provide for limited attribution 11 * for the Original Developer. In addition, Exhibit A has been modified to be consistent with Exhibit B. 12 * 13 * Software distributed under the License is distributed on an "AS IS" basis, 14 * WITHOUT WARRANTY OF ANY KIND, either express or implied. 15 * See the License for the specific language governing rights and limitations under the License. 16 * The Original Code is Zimbra Open Source Web Client. 17 * The Initial Developer of the Original Code is Zimbra, Inc. All rights to the Original Code were 18 * transferred by Zimbra, Inc. to Synacor, Inc. on September 14, 2015. 19 * 20 * All portions of the code are Copyright (C) 2007, 2009, 2010, 2013, 2014, 2016 Synacor, Inc. All Rights Reserved. 21 * ***** END LICENSE BLOCK ***** 22 */ 23 24 /** 25 * Creates the portlet manager. 26 * @class 27 * This class represents the portlet manager. 28 * 29 * @see ZmPortalApp 30 * @see ZmPortlet 31 */ 32 ZmPortletMgr = function() { 33 this._portlets = {}; 34 this._loadedZimlets = {}; 35 this._delayedPortlets = {}; 36 }; 37 38 // 39 // Public methods 40 // 41 42 /** 43 * Creates the portlets. 44 * 45 * @param {Boolean} global if <code>true</code>, create global portlets 46 * @param {Object} manifest the portal manifest 47 */ 48 ZmPortletMgr.prototype.createPortlets = function(global, manifest) { 49 global = global != null ? global : false; 50 var portletsCreated = []; 51 manifest = manifest || appCtxt.getApp(ZmApp.PORTAL).getManifest(); 52 if (manifest) { 53 var portalDef = manifest.portal; 54 var portletDefs = portalDef && portalDef.portlets; 55 if (portletDefs) { 56 for (var i = 0; i < portletDefs.length; i++) { 57 var portletDef = portletDefs[i]; 58 var portletGlobal = portletDef.global == "true"; 59 if (portletGlobal != global) continue; 60 61 var id = portletDef.panel && portletDef.panel.id; 62 if (id && !this._portlets[id] && document.getElementById(id)) { 63 this.createPortlet(id, portletDef); 64 portletsCreated.push(id); 65 } 66 } 67 } 68 } 69 return portletsCreated; 70 }; 71 72 /** 73 * Creates the portlet. 74 * 75 * @param {String} id the portlet id 76 * @param {Object} portletDef the portlet definition 77 * 78 * @return {ZmPortlet} the newly created portlet 79 */ 80 ZmPortletMgr.prototype.createPortlet = function(id, portletDef) { 81 // create portlet 82 var portlet = new ZmPortlet(null, id, portletDef); 83 this._portlets[id] = portlet; 84 85 // notify portlet creation or add to list to notify later 86 var name = portlet.zimletName; 87 if (this._loadedZimlets[name]) { 88 this._portletCreated(portlet); 89 } 90 else if (name) { 91 if (!this._delayedPortlets[name]) { 92 this._delayedPortlets[name] = []; 93 } 94 this._delayedPortlets[name].push(portlet); 95 } 96 97 return portlet; 98 }; 99 100 /** 101 * Gets the portlets. 102 * 103 * @return {Array} an array of {@link ZmPortlet} objects 104 */ 105 ZmPortletMgr.prototype.getPortlets = function() { 106 return this._portlets; 107 }; 108 109 /** 110 * Gets the portlet by id. 111 * 112 * @param {String} id the portlet id 113 * @return {ZmPortlet} the portlet 114 */ 115 ZmPortletMgr.prototype.getPortletById = function(id) { 116 return this._portlets[id]; 117 }; 118 119 /** 120 * This method is called by ZmZimletContext after the source code for 121 * the zimlet is loaded. 122 * 123 * @private 124 */ 125 ZmPortletMgr.prototype.zimletLoaded = function(zimletCtxt) { 126 this._loadedZimlets[zimletCtxt.name] = true; 127 128 var delayedPortlets = this._delayedPortlets[zimletCtxt.name]; 129 if (delayedPortlets) { 130 for (var i = 0; i < delayedPortlets.length; i++) { 131 var portlet = delayedPortlets[i]; 132 this._portletCreated(portlet, zimletCtxt); 133 } 134 } 135 delete this._delayedPortlets[zimletCtxt.name]; 136 }; 137 138 /** 139 * This method is called after all of the zimlets have been loaded. It is 140 * a way for the portlet manager to know that there are no more zimlets 141 * expected. 142 * 143 * @private 144 */ 145 ZmPortletMgr.prototype.allZimletsLoaded = function() { 146 for (var name in this._portlets) { 147 var portlet = this._portlets[name]; 148 if (!this._loadedZimlets[portlet.zimletName]) { 149 // NOTE: We don't call setContent because there is no view object 150 // if no zimlet code was loaded. 151 var el = document.getElementById(portlet.id); 152 if (el) { 153 el.innerHTML = ""; 154 } 155 } 156 } 157 }; 158 159 // 160 // Protected methods 161 // 162 163 ZmPortletMgr.prototype._portletCreated = function(portlet, zimletCtxt) { 164 // get zimlet context, if needed 165 if (!zimletCtxt) { 166 zimletCtxt = appCtxt.getZimletMgr().getZimletsHash()[portlet.zimletName]; 167 } 168 169 // create view 170 var parentEl = document.getElementById(portlet.id); 171 var view = new ZmPortletView(parentEl, portlet); 172 173 // call portlet handler 174 var handler = zimletCtxt.handlerObject; 175 portlet.zimlet = handler; 176 if (handler) { 177 handler.portletCreated(portlet); 178 } 179 };