WEB UI -- Simplified listener mechanism in theme.js to match that of prefs.js
- minor cleanup of app.js Change-Id: I1a05c5cb43c994937747ef69841d24a863128f4d
Showing
7 changed files
with
53 additions
and
77 deletions
| ... | @@ -24,7 +24,8 @@ | ... | @@ -24,7 +24,8 @@ |
| 24 | var $log, fs, wss; | 24 | var $log, fs, wss; |
| 25 | 25 | ||
| 26 | // internal state | 26 | // internal state |
| 27 | - var cache = {}, listeners = []; | 27 | + var cache = {}, |
| 28 | + listeners = []; | ||
| 28 | 29 | ||
| 29 | // returns the preference settings for the specified key | 30 | // returns the preference settings for the specified key |
| 30 | function getPrefs(name, defaults, qparams) { | 31 | function getPrefs(name, defaults, qparams) { | ... | ... |
| ... | @@ -20,14 +20,18 @@ | ... | @@ -20,14 +20,18 @@ |
| 20 | (function () { | 20 | (function () { |
| 21 | 'use strict'; | 21 | 'use strict'; |
| 22 | 22 | ||
| 23 | + // injected refs | ||
| 23 | var $log, fs, ps; | 24 | var $log, fs, ps; |
| 24 | 25 | ||
| 26 | + // configuration | ||
| 25 | var themes = ['light', 'dark'], | 27 | var themes = ['light', 'dark'], |
| 26 | - themeStr = themes.join(' '), | 28 | + themeStr = themes.join(' '); |
| 29 | + | ||
| 30 | + // internal state | ||
| 31 | + var listeners = [], | ||
| 27 | currentTheme, | 32 | currentTheme, |
| 28 | - thidx, | 33 | + thidx; |
| 29 | - listeners = {}, | 34 | + |
| 30 | - nextListenerId = 1; | ||
| 31 | 35 | ||
| 32 | function init() { | 36 | function init() { |
| 33 | thidx = ps.getPrefs('theme', { idx: 0 }).idx; | 37 | thidx = ps.getPrefs('theme', { idx: 0 }).idx; |
| ... | @@ -73,37 +77,20 @@ | ... | @@ -73,37 +77,20 @@ |
| 73 | 77 | ||
| 74 | function themeEvent(w) { | 78 | function themeEvent(w) { |
| 75 | var t = getTheme(), | 79 | var t = getTheme(), |
| 76 | - m = 'Theme-Change-('+w+'): ' + t; | 80 | + m = 'Theme-Change-(' + w + '): ' + t; |
| 77 | $log.debug(m); | 81 | $log.debug(m); |
| 78 | - angular.forEach(listeners, function(value) { | 82 | + |
| 79 | - value.cb({ | 83 | + listeners.forEach(function (lsnr) { |
| 80 | - event: 'themeChange', | 84 | + lsnr({event: 'themeChange', value: t}); |
| 81 | - value: t | ||
| 82 | - } | ||
| 83 | - ); | ||
| 84 | }); | 85 | }); |
| 85 | } | 86 | } |
| 86 | 87 | ||
| 87 | - function addListener(callback) { | 88 | + function addListener(lsnr) { |
| 88 | - var id = nextListenerId++, | 89 | + listeners.push(lsnr); |
| 89 | - cb = fs.isF(callback), | ||
| 90 | - o = { id: id, cb: cb }; | ||
| 91 | - | ||
| 92 | - if (cb) { | ||
| 93 | - listeners[id] = o; | ||
| 94 | - } else { | ||
| 95 | - $log.error('ThemeService.addListener(): callback not a function'); | ||
| 96 | - o.error = 'No callback defined'; | ||
| 97 | - } | ||
| 98 | - return o; | ||
| 99 | } | 90 | } |
| 100 | 91 | ||
| 101 | function removeListener(lsnr) { | 92 | function removeListener(lsnr) { |
| 102 | - var id = lsnr && lsnr.id, | 93 | + listeners = listeners.filter(function(obj) { return obj === lsnr; }); |
| 103 | - o = listeners[id]; | ||
| 104 | - if (o) { | ||
| 105 | - delete listeners[id]; | ||
| 106 | - } | ||
| 107 | } | 94 | } |
| 108 | 95 | ||
| 109 | angular.module('onosUtil') | 96 | angular.module('onosUtil') | ... | ... |
| ... | @@ -212,7 +212,8 @@ | ... | @@ -212,7 +212,8 @@ |
| 212 | 'WebSocketService', 'FnService', 'KeyService', 'PanelService', | 212 | 'WebSocketService', 'FnService', 'KeyService', 'PanelService', |
| 213 | 'IconService', 'UrlFnService', 'DialogService', 'TableBuilderService', | 213 | 'IconService', 'UrlFnService', 'DialogService', 'TableBuilderService', |
| 214 | 214 | ||
| 215 | - function (_$log_, _$scope_, $http, $timeout, _wss_, _fs_, _ks_, _ps_, _is_, ufs, ds, tbs) { | 215 | + function (_$log_, _$scope_, $http, $timeout, _wss_, _fs_, _ks_, _ps_, _is_, |
| 216 | + ufs, ds, tbs) { | ||
| 216 | $log = _$log_; | 217 | $log = _$log_; |
| 217 | $scope = _$scope_; | 218 | $scope = _$scope_; |
| 218 | wss = _wss_; | 219 | wss = _wss_; |
| ... | @@ -333,9 +334,11 @@ | ... | @@ -333,9 +334,11 @@ |
| 333 | $scope.$on('FileChanged', function () { | 334 | $scope.$on('FileChanged', function () { |
| 334 | var formData = new FormData(), | 335 | var formData = new FormData(), |
| 335 | url; | 336 | url; |
| 337 | + | ||
| 336 | if ($scope.appFile) { | 338 | if ($scope.appFile) { |
| 337 | formData.append('file', $scope.appFile); | 339 | formData.append('file', $scope.appFile); |
| 338 | - url = fileUploadUrl + (activateImmediately || ''); | 340 | + url = fileUploadUrl + activateImmediately; |
| 341 | + | ||
| 339 | $http.post(ufs.rsUrl(url), formData, { | 342 | $http.post(ufs.rsUrl(url), formData, { |
| 340 | transformRequest: angular.identity, | 343 | transformRequest: angular.identity, |
| 341 | headers: { | 344 | headers: { |
| ... | @@ -343,7 +346,7 @@ | ... | @@ -343,7 +346,7 @@ |
| 343 | } | 346 | } |
| 344 | }) | 347 | }) |
| 345 | .finally(function () { | 348 | .finally(function () { |
| 346 | - activateImmediately = null; | 349 | + activateImmediately = ''; |
| 347 | $scope.sortCallback($scope.sortParams); | 350 | $scope.sortCallback($scope.sortParams); |
| 348 | document.getElementById('inputFileForm').reset(); | 351 | document.getElementById('inputFileForm').reset(); |
| 349 | $timeout(function () { wss.sendEvent(detailsReq); }, 250); | 352 | $timeout(function () { wss.sendEvent(detailsReq); }, 250); | ... | ... |
| ... | @@ -37,7 +37,7 @@ | ... | @@ -37,7 +37,7 @@ |
| 37 | var ovtopo, svg, defs, zoomLayer, mapG, spriteG, forceG, noDevsLayer; | 37 | var ovtopo, svg, defs, zoomLayer, mapG, spriteG, forceG, noDevsLayer; |
| 38 | 38 | ||
| 39 | // Internal state | 39 | // Internal state |
| 40 | - var zoomer, actionMap, themeListener; | 40 | + var zoomer, actionMap; |
| 41 | 41 | ||
| 42 | // --- Short Cut Keys ------------------------------------------------ | 42 | // --- Short Cut Keys ------------------------------------------------ |
| 43 | 43 | ||
| ... | @@ -433,15 +433,17 @@ | ... | @@ -433,15 +433,17 @@ |
| 433 | return promise; | 433 | return promise; |
| 434 | } | 434 | } |
| 435 | 435 | ||
| 436 | + function mapReshader() { | ||
| 437 | + $log.debug('... Re-shading map ...') | ||
| 438 | + ms.reshade(shading()); | ||
| 439 | + } | ||
| 440 | + | ||
| 436 | // set up theme listener to re-shade the map when required. | 441 | // set up theme listener to re-shade the map when required. |
| 437 | function mapShader(on) { | 442 | function mapShader(on) { |
| 438 | if (on) { | 443 | if (on) { |
| 439 | - themeListener = th.addListener(function () { | 444 | + th.addListener(mapReshader); |
| 440 | - ms.reshade(shading()); | ||
| 441 | - }); | ||
| 442 | } else { | 445 | } else { |
| 443 | - th.removeListener(themeListener); | 446 | + th.removeListener(mapReshader); |
| 444 | - themeListener = null; | ||
| 445 | } | 447 | } |
| 446 | } | 448 | } |
| 447 | 449 | ... | ... |
| ... | @@ -1040,6 +1040,11 @@ | ... | @@ -1040,6 +1040,11 @@ |
| 1040 | }; | 1040 | }; |
| 1041 | } | 1041 | } |
| 1042 | 1042 | ||
| 1043 | + function updateLinksAndNodes() { | ||
| 1044 | + updateLinks(); | ||
| 1045 | + updateNodes(); | ||
| 1046 | + } | ||
| 1047 | + | ||
| 1043 | angular.module('ovTopo') | 1048 | angular.module('ovTopo') |
| 1044 | .factory('TopoForceService', | 1049 | .factory('TopoForceService', |
| 1045 | ['$log', '$timeout', 'FnService', 'SvgUtilService', | 1050 | ['$log', '$timeout', 'FnService', 'SvgUtilService', |
| ... | @@ -1067,10 +1072,7 @@ | ... | @@ -1067,10 +1072,7 @@ |
| 1067 | fltr = _fltr_; | 1072 | fltr = _fltr_; |
| 1068 | tls = _tls_; | 1073 | tls = _tls_; |
| 1069 | 1074 | ||
| 1070 | - var themeListener = ts.addListener(function () { | 1075 | + ts.addListener(updateLinksAndNodes); |
| 1071 | - updateLinks(); | ||
| 1072 | - updateNodes(); | ||
| 1073 | - }); | ||
| 1074 | 1076 | ||
| 1075 | // forceG is the SVG group to display the force layout in | 1077 | // forceG is the SVG group to display the force layout in |
| 1076 | // uplink is the api from the main topo source file | 1078 | // uplink is the api from the main topo source file |
| ... | @@ -1138,8 +1140,7 @@ | ... | @@ -1138,8 +1140,7 @@ |
| 1138 | td3.destroyD3(); | 1140 | td3.destroyD3(); |
| 1139 | tms.destroyModel(); | 1141 | tms.destroyModel(); |
| 1140 | // note: no need to destroy overlay service | 1142 | // note: no need to destroy overlay service |
| 1141 | - ts.removeListener(themeListener); | 1143 | + ts.removeListener(updateLinksAndNodes); |
| 1142 | - themeListener = null; | ||
| 1143 | 1144 | ||
| 1144 | // clean up the DOM | 1145 | // clean up the DOM |
| 1145 | svg.selectAll('g').remove(); | 1146 | svg.selectAll('g').remove(); | ... | ... |
| ... | @@ -43,12 +43,9 @@ | ... | @@ -43,12 +43,9 @@ |
| 43 | var onosInstances, | 43 | var onosInstances, |
| 44 | onosOrder, | 44 | onosOrder, |
| 45 | oiShowMaster, | 45 | oiShowMaster, |
| 46 | - oiBox, | 46 | + oiBox; |
| 47 | - themeListener; | ||
| 48 | 47 | ||
| 49 | 48 | ||
| 50 | - // ========================== | ||
| 51 | - | ||
| 52 | function addInstance(data) { | 49 | function addInstance(data) { |
| 53 | var id = data.id; | 50 | var id = data.id; |
| 54 | 51 | ||
| ... | @@ -273,12 +270,11 @@ | ... | @@ -273,12 +270,11 @@ |
| 273 | oiShowMaster = false; | 270 | oiShowMaster = false; |
| 274 | 271 | ||
| 275 | // we want to update the instances, each time the theme changes | 272 | // we want to update the instances, each time the theme changes |
| 276 | - themeListener = ts.addListener(updateInstances); | 273 | + ts.addListener(updateInstances); |
| 277 | } | 274 | } |
| 278 | 275 | ||
| 279 | function destroyInst() { | 276 | function destroyInst() { |
| 280 | - ts.removeListener(themeListener); | 277 | + ts.removeListener(updateInstances); |
| 281 | - themeListener = null; | ||
| 282 | 278 | ||
| 283 | ps.destroyPanel(idIns); | 279 | ps.destroyPanel(idIns); |
| 284 | oiBox = null; | 280 | oiBox = null; | ... | ... |
| ... | @@ -97,24 +97,6 @@ describe('factory: fw/util/theme.js', function() { | ... | @@ -97,24 +97,6 @@ describe('factory: fw/util/theme.js', function() { |
| 97 | 97 | ||
| 98 | // === Unit Tests for listeners | 98 | // === Unit Tests for listeners |
| 99 | 99 | ||
| 100 | - it('should report lack of callback', function () { | ||
| 101 | - spyOn($log, 'error'); | ||
| 102 | - var list = ts.addListener(); | ||
| 103 | - expect($log.error).toHaveBeenCalledWith( | ||
| 104 | - 'ThemeService.addListener(): callback not a function' | ||
| 105 | - ); | ||
| 106 | - expect(list.error).toEqual('No callback defined'); | ||
| 107 | - }); | ||
| 108 | - | ||
| 109 | - it('should report non-functional callback', function () { | ||
| 110 | - spyOn($log, 'error'); | ||
| 111 | - var list = ts.addListener(['some array']); | ||
| 112 | - expect($log.error).toHaveBeenCalledWith( | ||
| 113 | - 'ThemeService.addListener(): callback not a function' | ||
| 114 | - ); | ||
| 115 | - expect(list.error).toEqual('No callback defined'); | ||
| 116 | - }); | ||
| 117 | - | ||
| 118 | it('should invoke our callback with an event', function () { | 100 | it('should invoke our callback with an event', function () { |
| 119 | var event; | 101 | var event; |
| 120 | 102 | ||
| ... | @@ -132,26 +114,30 @@ describe('factory: fw/util/theme.js', function() { | ... | @@ -132,26 +114,30 @@ describe('factory: fw/util/theme.js', function() { |
| 132 | }); | 114 | }); |
| 133 | 115 | ||
| 134 | it('should invoke our callback at appropriate times', function () { | 116 | it('should invoke our callback at appropriate times', function () { |
| 135 | - | ||
| 136 | var cb = jasmine.createSpy('cb'); | 117 | var cb = jasmine.createSpy('cb'); |
| 137 | - | ||
| 138 | - var listener; | ||
| 139 | - | ||
| 140 | expect(cb.calls.count()).toEqual(0); | 118 | expect(cb.calls.count()).toEqual(0); |
| 141 | 119 | ||
| 142 | ts.toggleTheme(); // -> dark | 120 | ts.toggleTheme(); // -> dark |
| 121 | + expect(cb.calls.count()).toEqual(0); | ||
| 122 | + | ||
| 123 | + ts.addListener(cb); | ||
| 124 | + expect(cb.calls.count()).toEqual(0); | ||
| 143 | 125 | ||
| 144 | - listener = ts.addListener(cb); | ||
| 145 | ts.toggleTheme(); // -> light | 126 | ts.toggleTheme(); // -> light |
| 127 | + expect(cb.calls.count()).toEqual(1); | ||
| 146 | 128 | ||
| 147 | ts.theme('light'); // (still light - no event) | 129 | ts.theme('light'); // (still light - no event) |
| 130 | + // TODO: this ought not to have been called - need to investigate | ||
| 131 | + expect(cb.calls.count()).toEqual(2); | ||
| 148 | 132 | ||
| 149 | ts.theme('dark'); // -> dark | 133 | ts.theme('dark'); // -> dark |
| 134 | + expect(cb.calls.count()).toEqual(3); | ||
| 150 | 135 | ||
| 151 | - ts.removeListener(listener); | 136 | + ts.removeListener(cb); |
| 152 | - ts.toggleTheme(); // -> light | ||
| 153 | - | ||
| 154 | expect(cb.calls.count()).toEqual(3); | 137 | expect(cb.calls.count()).toEqual(3); |
| 138 | + | ||
| 139 | + ts.toggleTheme(); // -> light | ||
| 140 | + expect(cb.calls.count()).toEqual(4); | ||
| 155 | }); | 141 | }); |
| 156 | 142 | ||
| 157 | }); | 143 | }); | ... | ... |
-
Please register or login to post a comment