1 // ${project.version} 2 var exec = require('cordova/exec'), 3 channel = require('cordova/channel'), 4 promptActive = false, // Flag to prevent prompt from displaying more than once 5 bundle = null; // Internationalization. Loaded with device ready 6 7 // Event channels for CacheManager 8 var channels = { 9 'cacheinvalidated': channel.create('cacheinvalidated'), 10 'noviewerfound': channel.create('noviewerfound') 11 }; 12 13 // Holds the dom 0 handlers that are registered for the 14 // channels 15 var domZeroHandlers = {}; 16 17 // Private callback that plugin calls for events 18 var _eventHandler = function (event) { 19 if (event.type) { 20 if (event.type in channels) { 21 channels[event.type].fire(event); 22 } 23 } 24 }; 25 26 /** @namespace sap */ 27 28 /** 29 * The CacheManager plugin provides the ability to cache 30 * resources persistently and manage the lifecycle of SAP 31 * UI5 resources.<br/> <br/> Using this plugin, you can 32 * maximize the performance of online SAP UI5 applications. 33 * This is achieved by caching to disk the responses that 34 * are received by the webview according to their response 35 * headers. CacheManager then maintains and periodically 36 * checks for manifest files that tell whether resources for 37 * an app has been updated. When an update is found, the 38 * cache is purged. <br/> <br/> <b>Adding and Removing the 39 * CacheManager</b><br/> The CacheManager plugin is added 40 * and removed using the <a 41 * href="http://cordova.apache.org/docs/en/edge/guide_cli_index.md.html#The%20Command-line%20Interface">Cordova 42 * CLI</a>.<br/> <br/> To add the CacheManager plugin to 43 * your project, use the following command:<br/> cordova 44 * plugin add <path to directory containing Kapsel 45 * plugins>\cachemanager<br/> <br/> To remove the 46 * CacheManager plugin from your project, use the following 47 * command:<br/> cordova plugin rm 48 * com.sap.mp.cordova.plugins.cachemanager 49 * 50 * @namespace 51 * @alias CacheManager 52 * @memberof sap 53 */ 54 55 // Set default behaviors. These can be overridden by the 56 // parameters passed to 57 // the goToUrlAndStartCaching function. 58 var _shouldEnableSAPUI5LifecycleManagement = true; 59 var _shouldEnableCustomCache = true; 60 var _checkForUpdatesEvents = ['deviceready', 'resume']; 61 62 module.exports = { 63 /** 64 * Clear the browser cache. 65 * 66 * @example sap.CacheManager.clearCache(); 67 */ 68 clearCache: function () { 69 return exec(_eventHandler, _eventHandler, 'CacheManager', 'clearCache', []); 70 }, 71 72 /** 73 * Initialize the cache manager with the provided URL. 74 * 75 * @param {string} 76 * url The URL to navigate to. This is 77 * required. 78 * @param {Array. 79 * <string>} [checkForUpdatesEvents] Array of 80 * strings representing events that should 81 * trigger a check for application updates. 82 * @example sap.CacheManager.setUrl('https://<host>.<domain>:<port>/sap/bc/ui5_ui5/ui2/ushell/shells/abap/Fiorilaunchpad.html?sap-client=<client>&sap-language=EN'); 83 */ 84 setUrl: function (url, 85 checkForUpdatesEvents) { 86 87 if (typeof url !== 'string') { 88 throw 'url must be a string.'; 89 } 90 if (Object.prototype.toString 91 .call(checkForUpdatesEvents) === '[object Array]') { 92 _checkForUpdatesEvents = checkForUpdatesEvents; 93 } 94 if (_checkForUpdatesEvents.length === 0 && _shouldEnableSAPUI5LifecycleManagement) { 95 throw ('SAP UI5 lifecycle management is enabled, but there are no checkForUpdates events. ' + 96 'Without any checkForUpdates events, lifecycle management can\'t function properly.'); 97 } 98 99 exec(_eventHandler, _eventHandler, 'CacheManager', 'setUrl', [url]); 100 }, 101 102 /** 103 * Enable the cache manager. 104 * 105 * @param {boolean} enableCache 106 * Pass false if you do not want to override the default cache. 107 * @example sap.CacheManager.setCacheEnabled(true); 108 */ 109 setCacheEnabled: function (enableCache) { 110 if (typeof enableCache === 'boolean') { 111 _shouldEnableCustomCache = enableCache; 112 113 exec(_eventHandler, _eventHandler, 'CacheManager', 'enableCache', [_shouldEnableCustomCache]); 114 } 115 }, 116 117 /** 118 * Enable SAP UI5 life cycle management. 119 * 120 * @param {boolean} 121 * shouldEnableSAPUI5LifecycleManagement 122 * Pass false if you do not want to check for 123 * application updates. 124 * @example sap.CacheManager.setSAPUI5LifecycleManagementEnabled(true); 125 */ 126 setSAPUI5LifecycleManagementEnabled: function (shouldEnableSAPUI5LifecycleManagement) { 127 if (typeof shouldEnableSAPUI5LifecycleManagement === 'boolean') { 128 _shouldEnableSAPUI5LifecycleManagement = shouldEnableSAPUI5LifecycleManagement; 129 130 // Keep track of UI5 manifest files and 131 // invalidate UI5 lifecycle management apps when 132 // they're updated. 133 exec(_eventHandler, _eventHandler, 'CacheManager', 'enableSAPUI5LifecycleManagement', [_shouldEnableSAPUI5LifecycleManagement]); 134 } 135 }, 136 137 /** 138 * Reload the application. 139 * 140 * This function should only be called from a cacheinvalidated event handler. 141 */ 142 reloadApplication: function () { 143 exec(_eventHandler, _eventHandler, 'CacheManager', 'reloadApplication', []); 144 }, 145 146 /** 147 * Add a listener for an CacheManager event. See events for available event names. 148 * @param {string} eventname Name of the app update event. 149 * @param {function} f Function to call when event is fired. 150 * @example 151 * sap.CacheManager.addEventListener('cacheinvalidated', function(e) { 152 * console.log("Cache invalidated"); 153 * }); 154 */ 155 addEventListener: function (eventname, f) { 156 if (eventname in channels) { 157 channels[eventname].subscribe(f); 158 } 159 }, 160 161 /** 162 * Removes a listener for an CacheManager event. See events for available event names. 163 * @param {string} eventname Name of the app update event. 164 * @param {function} f Function that was registered. 165 * @example 166 * // Adding the listener 167 * var listener = function(e) { 168 * console.log("Checking for update"); 169 * }); 170 * sap.CacheManager.addEventListener('cacheinvalidated', listener); 171 * 172 * // Removing the listener 173 * sap.CacheManager.removeEventListener('cacheinvalidated', listener); 174 */ 175 removeEventListener: function (eventname, f) { 176 if (eventname in channels) { 177 channels[eventname].unsubscribe(f); 178 } 179 }, 180 181 setCheckForUpdatesEvents: function (events) { 182 if (!events || !Array.isArray(events)) { 183 // This function may be called without the 'events' argument 184 // just so that the event listeners are added. 185 events = _checkForUpdatesEvents; 186 } 187 _checkForUpdatesEvents.forEach(function(_event) { 188 document.removeEventListener(_event, sap.CacheManager.checkForUpdates); 189 }); 190 events.forEach(function(event){ 191 document.addEventListener(event, sap.CacheManager.checkForUpdates, false); 192 }); 193 _checkForUpdatesEvents = events; 194 195 }, 196 197 /** 198 * Request new versions of the known manifest files. If a difference 199 * is found, invalidate the out dated cached resources. 200 */ 201 checkForUpdates: function () { 202 if (!_shouldEnableSAPUI5LifecycleManagement) { 203 throw 'checkForUpdates called while SAP UI5 lifecycle management was not enabled.'; 204 } 205 return exec(_eventHandler, _eventHandler, 'CacheManager', 'checkForUpdates', []); 206 } 207 208 /** 209 * Event fired when CacheManager has it's cache invalidated. 210 * 211 * @event sap.CacheManager#cacheinvalidated 212 * @type {object} 213 * @property {string} type - The name of the event. Value 214 * will be cacheinvalidated. 215 * @example sap.CacheManager.addEventListener('cacheinvalidated', 216 * function(e) { console.log("Cache is 217 * invalidated"); }); 218 */ 219 220 /** 221 * Event fired when CacheManager is unable to display a 222 * particular mime type because there is no view for that 223 * type installed on the device. 224 * 225 * @event sap.CacheManager#noviewerfound 226 * @type {object} 227 * @property {string} type - The name of the event. Value 228 * will be noviewerfound. 229 * @example sap.CacheManager.addEventListener('noviewerfound', 230 * function(e) { console.log("No viewer 231 * installed"); }); 232 */ 233 }; 234 235 // Add getter/setter for DOM0 style events 236 for (var type in channels) { 237 function defineSetGet(eventType) { 238 module.exports.__defineGetter__("on" + eventType, 239 function () { 240 return domZeroHandlers[eventType]; 241 }); 242 243 module.exports.__defineSetter__( 244 "on" + eventType, 245 function (val) { 246 // Remove current handler 247 if (domZeroHandlers[eventType]) { 248 module.exports 249 .removeEventListener( 250 eventType, 251 domZeroHandlers[eventType]); 252 } 253 254 // Add new handler 255 if (val) { 256 domZeroHandlers[eventType] = val; 257 module.exports 258 .addEventListener( 259 eventType, 260 domZeroHandlers[eventType]); 261 } 262 }); 263 } 264 265 defineSetGet(type); 266 } 267 268 269 //Add default no viewer found implementation 270 module.exports.onnoviewerfound = function (parameters) { 271 var mimetype = parameters.mimetype; 272 273 function reportNoViewer() { 274 window.navigator.notification.alert(bundle.get("noviewer") + mimetype, null, bundle.get("noviewer_title"), bundle.get("ok")); 275 } 276 277 if (!bundle) { 278 // Load required translations 279 var i18n = require('com.sap.mp.cordova.plugins.i18n.i18n'); 280 i18n.load({ 281 path: "plugins/com.sap.mp.cordova.plugins.cachemanager/www" 282 }, function(i18nBundle) { 283 bundle = i18nBundle; 284 reportNoViewer(); 285 }); 286 } else { 287 reportNoViewer(); 288 } 289 }; 290 291 //Add default cache invalidated implementation 292 module.exports.oncacheinvalidated = function () { 293 var onConfirm = function (buttonIndex) { 294 promptActive = false; 295 if (buttonIndex === 1) { 296 module.exports.reloadApplication(); 297 } 298 }; 299 300 function reportCacheInvalidated() { 301 window.navigator.notification.confirm(bundle.get("msg_cache_invalid"), onConfirm, 302 bundle.get("title_cache_invalid"), bundle.get("ok")); 303 } 304 305 if (!bundle) { 306 // Load required translations 307 var i18n = require('com.sap.mp.cordova.plugins.i18n.i18n'); 308 i18n.load({ 309 path: "plugins/com.sap.mp.cordova.plugins.cachemanager/www" 310 }, function(i18nBundle) { 311 bundle = i18nBundle; 312 reportCacheInvalidated(); 313 }); 314 } else { 315 reportCacheInvalidated(); 316 } 317 }; 318 319 //Add event listeners so that checkForUpdates is called at the right time. 320 document.addEventListener('deviceready', module.exports.setCheckForUpdatesEvents, false); 321 document.addEventListener('deviceready', function () { 322 for (var j = 0; j < _checkForUpdatesEvents.length; j++) { 323 if (_checkForUpdatesEvents[j] === 'deviceready') { 324 module.exports.checkForUpdates(); 325 } 326 } 327 });