Fix : Settings drawer close usability bug

+ Settings drawer could not be closed when clicking above or below its
container. This has been fixed by changin the logic used for determining
if the click was inside/outside of the Settings drawer.

+ Added DOM utility to compensate for the limitations of JQuery
contains...
This commit is contained in:
jdescottes 2014-02-09 21:49:08 +01:00
parent c105619605
commit 676bf1c7fd
3 changed files with 59 additions and 23 deletions

View File

@ -1,5 +1,5 @@
(function () { (function () {
var ns = $.namespace("pskl.controller.settings"); var ns = $.namespace('pskl.controller.settings');
var settings = { var settings = {
'user' : { 'user' : {
@ -29,9 +29,9 @@
ns.SettingsController = function (piskelController) { ns.SettingsController = function (piskelController) {
this.piskelController = piskelController; this.piskelController = piskelController;
this.drawerContainer = document.getElementById("drawer-container"); this.drawerContainer = document.getElementById('drawer-container');
this.settingsContainer = $('[data-pskl-controller=settings]'); this.settingsContainer = $('[data-pskl-controller=settings]');
this.expanded = false; this.isExpanded = false;
this.currentSetting = null; this.currentSetting = null;
}; };
@ -39,25 +39,31 @@
* @public * @public
*/ */
ns.SettingsController.prototype.init = function() { ns.SettingsController.prototype.init = function() {
// Expand drawer when clicking 'Settings' tab. $('[data-setting]').click(this.onSettingIconClick.bind(this));
$('[data-setting]').click(function(evt) { $('body').click(this.onBodyClick.bind(this));
$.subscribe(Events.CLOSE_SETTINGS_DRAWER, this.closeDrawer.bind(this));
};
ns.SettingsController.prototype.onSettingIconClick = function (evt) {
var el = evt.originalEvent.currentTarget; var el = evt.originalEvent.currentTarget;
var setting = el.getAttribute("data-setting"); var setting = el.getAttribute('data-setting');
if (this.currentSetting != setting) { if (this.currentSetting != setting) {
this.loadSetting(setting); this.loadSetting(setting);
} else { } else {
this.closeDrawer(); this.closeDrawer();
} }
}.bind(this)); };
$('body').click(function (evt) { ns.SettingsController.prototype.onBodyClick = function (evt) {
var isInSettingsContainer = $.contains(this.settingsContainer.get(0), evt.target); var target = evt.target;
if (this.expanded && !isInSettingsContainer) {
var isInDrawerContainer = pskl.utils.Dom.isParent(target, this.drawerContainer);
var isInSettingsIcon = target.getAttribute('data-setting');
var isInSettingsContainer = isInDrawerContainer || isInSettingsIcon;
if (this.isExpanded && !isInSettingsContainer) {
this.closeDrawer(); this.closeDrawer();
} }
}.bind(this));
$.subscribe(Events.CLOSE_SETTINGS_DRAWER, this.closeDrawer.bind(this));
}; };
ns.SettingsController.prototype.loadSetting = function (setting) { ns.SettingsController.prototype.loadSetting = function (setting) {
@ -69,7 +75,7 @@
$('.' + SEL_SETTING_CLS).removeClass(SEL_SETTING_CLS); $('.' + SEL_SETTING_CLS).removeClass(SEL_SETTING_CLS);
$('[data-setting='+setting+']').addClass(SEL_SETTING_CLS); $('[data-setting='+setting+']').addClass(SEL_SETTING_CLS);
this.expanded = true; this.isExpanded = true;
this.currentSetting = setting; this.currentSetting = setting;
}; };
@ -77,7 +83,7 @@
this.settingsContainer.removeClass(EXP_DRAWER_CLS); this.settingsContainer.removeClass(EXP_DRAWER_CLS);
$('.' + SEL_SETTING_CLS).removeClass(SEL_SETTING_CLS); $('.' + SEL_SETTING_CLS).removeClass(SEL_SETTING_CLS);
this.expanded = false; this.isExpanded = false;
this.currentSetting = null; this.currentSetting = null;
}; };

29
js/utils/Dom.js Normal file
View File

@ -0,0 +1,29 @@
(function () {
var ns = $.namespace('pskl.utils');
ns.Dom = {
/**
* Check if a given HTML element is nested inside another
* @param {HTMLElement} node Element to test
* @param {HTMLElement} parent Potential Ancestor for node
* @param {Boolean} excludeParent set to true if the parent should be excluded from potential matches
* @return {Boolean} true if parent was found amongst the parentNode chain of node
*/
isParent : function (node, parent, excludeParent) {
if (node && parent) {
if (excludeParent) {
node = node.parentNode;
}
while (node) {
if (node === parent) {
return true;
}
node = node.parentNode;
}
}
return false;
}
};
})();

View File

@ -18,6 +18,7 @@ exports.scripts = [
"js/utils/core.js", "js/utils/core.js",
"js/utils/UserAgent.js", "js/utils/UserAgent.js",
"js/utils/CanvasUtils.js", "js/utils/CanvasUtils.js",
"js/utils/Dom.js",
"js/utils/Math.js", "js/utils/Math.js",
"js/utils/FileUtils.js", "js/utils/FileUtils.js",
"js/utils/FrameUtils.js", "js/utils/FrameUtils.js",