From 8d8374b8e2630d1e0cb6bb53624aecc10c0a694b Mon Sep 17 00:00:00 2001 From: Michael Teeuw Date: Thu, 13 Oct 2016 15:00:59 +0200 Subject: [PATCH] First implementation of Visibility locking. --- js/main.js | 49 ++++++++++++++++++++++++++----- js/module.js | 32 ++++++++++++++++---- modules/README.md | 75 ++++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 140 insertions(+), 16 deletions(-) diff --git a/js/main.js b/js/main.js index c0c63006..a8572c6a 100644 --- a/js/main.js +++ b/js/main.js @@ -174,7 +174,17 @@ var MM = (function() { * argument speed Number - The speed of the hide animation. * argument callback function - Called when the animation is done. */ - var hideModule = function(module, speed, callback) { + var hideModule = function(module, speed, callback, options) { + options = options || {}; + + // set lockString if set in options. + if (options.lockString) { + Log.log("Has lockstring: " + options.lockString); + if (module.lockStrings.indexOf(options.lockString) === -1) { + module.lockStrings.push(options.lockString); + } + } + var moduleWrapper = document.getElementById(module.identifier); if (moduleWrapper !== null) { moduleWrapper.style.transition = "opacity " + speed / 1000 + "s"; @@ -183,7 +193,7 @@ var MM = (function() { clearTimeout(module.showHideTimer); module.showHideTimer = setTimeout(function() { // To not take up any space, we just make the position absolute. - // since it"s fade out anyway, we can see it lay above or + // since it's fade out anyway, we can see it lay above or // below other modules. This works way better than adjusting // the .display property. moduleWrapper.style.position = "absolute"; @@ -200,7 +210,30 @@ var MM = (function() { * argument speed Number - The speed of the show animation. * argument callback function - Called when the animation is done. */ - var showModule = function(module, speed, callback) { + var showModule = function(module, speed, callback, options) { + options = options || {}; + + // remove lockString if set in options. + if (options.lockString) { + var index = module.lockStrings.indexOf(options.lockString) + if ( index !== -1) { + module.lockStrings.splice(index, 1); + } + } + + // Check if there are no more lockstrings set, or the force option is set. + // Otherwise cancel show action. + if (module.lockStrings.length !== 0 && options.force !== true) { + Log.log("Will not show " + module.name + ". LockStrings active: " + module.lockStrings.join(",")); + return; + } + + // If forced show, clean current lockstrings. + if (module.lockStrings.length !== 0 && options.force === true) { + Log.log("Force show of module: " + module.name); + module.lockStrings = []; + } + var moduleWrapper = document.getElementById(module.identifier); if (moduleWrapper !== null) { moduleWrapper.style.transition = "opacity " + speed / 1000 + "s"; @@ -419,10 +452,11 @@ var MM = (function() { * argument module Module - The module hide. * argument speed Number - The speed of the hide animation. * argument callback function - Called when the animation is done. + * argument options object - Optional settings for the hide method. */ - hideModule: function(module, speed, callback) { + hideModule: function(module, speed, callback, options) { module.hidden = true; - hideModule(module, speed, callback); + hideModule(module, speed, callback, options); }, /* showModule(module, speed, callback) @@ -431,10 +465,11 @@ var MM = (function() { * argument module Module - The module show. * argument speed Number - The speed of the show animation. * argument callback function - Called when the animation is done. + * argument options object - Optional settings for the hide method. */ - showModule: function(module, speed, callback) { + showModule: function(module, speed, callback, options) { module.hidden = false; - showModule(module, speed, callback); + showModule(module, speed, callback, options); } }; diff --git a/js/module.js b/js/module.js index 9c26bc7b..fe669cee 100644 --- a/js/module.js +++ b/js/module.js @@ -20,6 +20,10 @@ var Module = Class.extend({ // Timer reference used for showHide animation callbacks. showHideTimer: null, + // Array to store lockStrings. These stings are used to lock + // visibility when hiding and showing module. + lockStrings: [], + /* init() * Is called when the module is instantiated. */ @@ -314,15 +318,24 @@ var Module = Class.extend({ * * argument speed Number - The speed of the hide animation. * argument callback function - Called when the animation is done. + * argument options object - Optional settings for the hide method. */ - hide: function(speed, callback) { + hide: function(speed, callback, options) { + if (typeof callback === "object") { + options = callback; + callback = function() {}; + } + callback = callback || function() {}; + options = options || {}; var self = this; MM.hideModule(self, speed, function() { self.suspend(); callback(); - }); + }, options); + + Log.log(options); }, /* showModule(module, speed, callback) @@ -330,10 +343,19 @@ var Module = Class.extend({ * * argument speed Number - The speed of the show animation. * argument callback function - Called when the animation is done. + * argument options object - Optional settings for the hide method. */ - show: function(speed, callback) { + show: function(speed, callback, options) { + if (typeof callback === "object") { + options = callback; + callback = function() {}; + } + + callback = callback || function() {}; + options = options || {}; + this.resume(); - MM.showModule(this, speed, callback); + MM.showModule(this, speed, callback, options); } }); @@ -347,7 +369,7 @@ Module.create = function(name) { return obj; } - var temp = obj.constructor(); // give temp the original obj"s constructor + var temp = obj.constructor(); // give temp the original obj's constructor for (var key in obj) { temp[key] = cloneObject(obj[key]); } diff --git a/modules/README.md b/modules/README.md index e7a23abd..d157c983 100644 --- a/modules/README.md +++ b/modules/README.md @@ -283,26 +283,93 @@ If you want to send a notification to the node_helper, use the `sendSocketNotifi this.sendSocketNotification('SET_CONFIG', this.config); ```` -####`this.hide(speed, callback)` -***speed* Number** - Optional, The speed of the hide animation in milliseconds. +####`this.hide(speed, callback, options)` +***speed* Number** - Optional (Required when setting callback or options), The speed of the hide animation in milliseconds. ***callback* Function** - Optional, The callback after the hide animation is finished. +***options* Function** - Optional, Object with additional options for the hide action (see below). To hide a module, you can call the `hide(speed, callback)` method. You can call the hide method on the module instance itself using `this.hide()`, but of course you can also hide another module using `anOtherModule.hide()`. +Possible configurable options: + +- `lockString` - String - When setting lock string, the module can not be shown without passing the correct lockstring. This way (multiple) modules can prevent a module from showing. It's considered best practice to use your modules identifier as the locksString: `this.identifier`. See *visibility locking* below. + + **Note 1:** If the hide animation is canceled, for instance because the show method is called before the hide animation was finished, the callback will not be called.
**Note 2:** If the hide animation is hijacked (an other method calls hide on the same module), the callback will not be called.
**Note 3:** If the dom is not yet created, the hide method won't work. Wait for the `DOM_OBJECTS_CREATED` [notification](#notificationreceivednotification-payload-sender). -####`this.show(speed, callback)` -***speed* Number** - Optional, The speed of the show animation in milliseconds. + +####`this.show(speed, callback, options)` +***speed* Number** - Optional (Required when setting callback or options), The speed of the show animation in milliseconds. ***callback* Function** - Optional, The callback after the show animation is finished. +***options* Function** - Optional, Object with additional options for the show action (see below). To show a module, you can call the `show(speed, callback)` method. You can call the show method on the module instance itself using `this.show()`, but of course you can also show another module using `anOtherModule.show()`. +Possible configurable options: + +- `lockString` - String - When setting lock string, the module can not be shown without passing the correct lockstring. This way (multiple) modules can prevent a module from showing. See *visibility locking- below. +- `force` - Boolean - When setting the force tag to `true`, the locking mechanism will be overwritten. Use this option with caution. It's considered best practice to let the usage of the force option be use- configurable. See *visibility locking* below. + **Note 1:** If the show animation is canceled, for instance because the hide method is called before the show animation was finished, the callback will not be called.
**Note 2:** If the show animation is hijacked (an other method calls show on the same module), the callback will not be called.
**Note 3:** If the dom is not yet created, the show method won't work. Wait for the `DOM_OBJECTS_CREATED` [notification](#notificationreceivednotification-payload-sender). +####Visibility locking +Visiblity locking helps the module system to prevent unwanted hide/show actions. The following scenario explains the concept: + +**Module B asks module A to hide:** +```` +moduleA.hide(0, {lockString: "module_b_identifier"}); +```` +Module A is now hidden, and has an lock array with the following strings: +```` +moduleA.lockStrings == ["module_b_identifier"] +moduleA.hidden == true +```` +**Module C asks module A to hide:** +```` +moduleA.hide(0, {lockString: "module_c_identifier"}); +```` +Module A is now hidden, and has an lock array with the following strings: +```` +moduleA.lockStrings == ["module_b_identifier", "module_c_identifier"] +moduleA.hidden == true +```` +**Module B asks module A to show:** +```` +moduleA.show(0, {lockString: "module_b_identifier"}); +```` +The lockString will be removed from moduleA’s locks array, but since there still is an other lock string available, the module remains hidden: +```` +moduleA.lockStrings == ["module_c_identifier"] +moduleA.hidden == true +```` +**Module C asks module A to show:** +```` +moduleA.show(0, {lockString: "module_c_identifier"}); +```` +The lockString will be removed from moduleA’s locks array, and since this will result in an empty lock array, the module will be visible: +```` +moduleA.lockStrings == [] +moduleA.hidden == false +```` + +**Note:** The locking mechanism can be overwritten by using the force tag: +```` +moduleA.show(0, {force: true}); +```` +This will reset the lockstring array, and will show the module. +```` +moduleA.lockStrings == [] +moduleA.hidden == false +```` + +Use this `force` method with caution. See `show()` method for more information. + + + ####`this.translate(identifier)` ***identifier* String** - Identifier of the string that should be translated.