From c7d52c0f922fb8ef4c30655aafaf84fd956c9eee Mon Sep 17 00:00:00 2001 From: dxue Date: Tue, 30 Sep 2014 10:24:54 +0800 Subject: [PATCH] Bug 985853 - [Keyboard UX update][User Story] Hold shift to enter upper case characters --- .../js/keyboard/active_targets_manager.js | 8 ++-- apps/keyboard/js/keyboard/target_handlers.js | 33 ++++++++++++- .../js/keyboard/target_handlers_manager.js | 5 ++ apps/keyboard/js/render.js | 15 ++++++ apps/keyboard/style/keyboard.css | 48 ++++++++++++++++--- 5 files changed, 98 insertions(+), 11 deletions(-) diff --git a/apps/keyboard/js/keyboard/active_targets_manager.js b/apps/keyboard/js/keyboard/active_targets_manager.js index d33f9ba2ff84..0c6360f35610 100644 --- a/apps/keyboard/js/keyboard/active_targets_manager.js +++ b/apps/keyboard/js/keyboard/active_targets_manager.js @@ -33,6 +33,7 @@ ActiveTargetsManager.prototype.ontargetmovedin = null; ActiveTargetsManager.prototype.ontargetcommitted = null; ActiveTargetsManager.prototype.ontargetcancelled = null; ActiveTargetsManager.prototype.ontargetdoubletapped = null; +ActiveTargetsManager.prototype.onnewtargetwillactivate = null; // Show accent char menu (if there is one) or do other stuff // after LONG_PRESS_TIMEOUT @@ -99,10 +100,11 @@ ActiveTargetsManager.prototype._handlePressStart = function(press, id) { return; } - // All targets before the new touch need to be committed, - // according to UX requirement. + // Notify current targets about the new touch. this.activeTargets.forEach(function(target, id) { - this._handlePressEnd(press, id); + if (typeof this.onnewtargetwillactivate === 'function') { + this.onnewtargetwillactivate(target); + } }, this); var target = press.target; diff --git a/apps/keyboard/js/keyboard/target_handlers.js b/apps/keyboard/js/keyboard/target_handlers.js index 51aa2e288dc5..5438285b2c0b 100644 --- a/apps/keyboard/js/keyboard/target_handlers.js +++ b/apps/keyboard/js/keyboard/target_handlers.js @@ -1,6 +1,6 @@ 'use strict'; -/* global KeyEvent */ +/* global KeyEvent, IMERender */ (function(exports) { @@ -79,6 +79,11 @@ DefaultTargetHandler.prototype.doubleTap = function() { this.app.console.log('DefaultTargetHandler.doubleTap()'); this.commit(); }; +DefaultTargetHandler.prototype.newTargetActivate = function() { + this.commit(); + // Ignore any action when commit. + this.ignoreCommitActions = true; +}; var NullTargetHandler = function(target, app) { DefaultTargetHandler.apply(this, arguments); @@ -231,11 +236,28 @@ var CapsLockTargetHandler = function(target, app) { DefaultTargetHandler.apply(this, arguments); }; CapsLockTargetHandler.prototype = Object.create(DefaultTargetHandler.prototype); +CapsLockTargetHandler.prototype.capsLockState = 'none'; +CapsLockTargetHandler.prototype.newTargetActivated = false; +CapsLockTargetHandler.prototype.activate = function() { + if (this.app.upperCaseStateManager.isUpperCaseLocked) { + this.capsLockState = 'upperCaseLocked'; + } else if (this.app.upperCaseStateManager.isUpperCase) { + this.capsLockState = 'upperCase'; + } else { + this.capsLockState = 'none'; + } + this.app.feedbackManager.triggerFeedback(this.target); + this.app.visualHighlightManager.show(this.target); +}; CapsLockTargetHandler.prototype.commit = function() { + // If hold shift to enter upper case, set isUpperCase false when finished this.app.upperCaseStateManager.switchUpperCaseState({ - isUpperCase: !this.app.upperCaseStateManager.isUpperCase, + isUpperCase: this.newTargetActivated ? false : + !this.app.upperCaseStateManager.isUpperCase, isUpperCaseLocked: false }); + this.newTargetActivated = false; + this.capsLockState = 'none'; this.app.visualHighlightManager.hide(this.target); }; CapsLockTargetHandler.prototype.doubleTap = function() { @@ -244,6 +266,13 @@ CapsLockTargetHandler.prototype.doubleTap = function() { }); this.app.visualHighlightManager.hide(this.target); }; +CapsLockTargetHandler.prototype.newTargetActivate = function() { + this.newTargetActivated = true; + this.app.upperCaseStateManager.switchUpperCaseState({ + isUpperCaseLocked: true + }); + IMERender.highlightKey(this.target, { capsLockState: this.capsLockState }); +}; var SwitchKeyboardTargetHandler = function(target, app) { DefaultTargetHandler.apply(this, arguments); diff --git a/apps/keyboard/js/keyboard/target_handlers_manager.js b/apps/keyboard/js/keyboard/target_handlers_manager.js index 9608ef6e51b3..ba96c9161a4a 100644 --- a/apps/keyboard/js/keyboard/target_handlers_manager.js +++ b/apps/keyboard/js/keyboard/target_handlers_manager.js @@ -39,6 +39,8 @@ TargetHandlersManager.prototype.start = function() { this._callTargetAction.bind(this, 'cancel', false, true); activeTargetsManager.ontargetdoubletapped = this._callTargetAction.bind(this, 'doubleTap', false, true); + activeTargetsManager.onnewtargetwillactivate = + this._callTargetAction.bind(this, 'newTargetActivate', false, false); activeTargetsManager.start(); }; @@ -61,6 +63,9 @@ TargetHandlersManager.prototype.stop = function() { // "longpress" is noticeably an optional step during the life cycle and does // not start or end the handler/active target, so it was not mentioned in the // above list. +// "newTargetActivate" is similar to "longpress", it is an optional step too, +// so it was not mentioned in the above list. When newTargetActivate is called, +// isUpperCase will be set to true, and hold the icon's background. // // Please note that since we are using target (an abstract key object associated // with one DOM element) as the identifier of handlers, we do not assign new diff --git a/apps/keyboard/js/render.js b/apps/keyboard/js/render.js index 5435e937bbd5..542c6d9f0940 100644 --- a/apps/keyboard/js/render.js +++ b/apps/keyboard/js/render.js @@ -318,11 +318,26 @@ var IMERender = (function() { if (!options.showUpperCase) { keyElem.classList.add('lowercase'); } + // Show highlight locked background. + switch (options.capsLockState) { + case 'upperCaseLocked': + keyElem.classList.add('highlight-locked-uppercaselocked'); + break; + case 'upperCase': + keyElem.classList.add('highlight-locked-uppercase'); + break; + case 'none': + keyElem.classList.add('highlight-locked-none'); + break; + } }; // Unhighlight a key var unHighlightKey = function kr_unHighlightKey(key) { var keyElem = targetObjDomMap.get(key); + keyElem.classList.remove('highlight-locked-uppercaselocked'); + keyElem.classList.remove('highlight-locked-uppercase'); + keyElem.classList.remove('highlight-locked-none'); keyElem.classList.remove('highlighted'); keyElem.classList.remove('lowercase'); }; diff --git a/apps/keyboard/style/keyboard.css b/apps/keyboard/style/keyboard.css index 2cd483234ed0..0f1549a7ac46 100644 --- a/apps/keyboard/style/keyboard.css +++ b/apps/keyboard/style/keyboard.css @@ -179,6 +179,39 @@ button::-moz-focus-inner { left: 0; } +/* Rules for hold shift to enter upper case */ +.keyboard-key.highlight-locked-uppercaselocked { + background-color: #4a5255; +} + +.keyboard-key.highlight-locked-uppercaselocked > .visual-wrapper { + box-shadow: 0 0.4rem 0 #00caf2; +} + +.keyboard-key.highlight-locked-none > .visual-wrapper > .key-element { + color: #00b8d6; +} + +.keyboard-key.highlight-locked-uppercase { + background-color: #00caf2; +} + +.keyboard-key.highlight-locked-uppercase > .visual-wrapper { + box-shadow: 0 0 0 #00caf2; +} + +.keyboard-key.highlight-locked-uppercase > .visual-wrapper > .key-element { + color: #00b8d6; + border-right-color: transparent; +} + +.keyboard-key.highlight-locked-none > .visual-wrapper { + box-shadow: 0 0 0 #00caf2; +} + +.keyboard-key.highlight-locked-none > .visual-wrapper > .key-element { + color: #00b8d6; +} /* Special keys */ .keyboard-key.special-key > .visual-wrapper > .key-element { @@ -186,12 +219,15 @@ button::-moz-focus-inner { right: 0; bottom: 0; left: 0; - color: #abb0b1; font: 500 1.5rem/4.3rem 'Keyboard Symbols', sans-serif; } +.keyboard-key.special-key:not([class*='highlight-locked']) > .visual-wrapper > .key-element { + color: #abb0b1; +} + /* Highlight for special keys */ -.keyboard-key.special-key.highlighted > .visual-wrapper > .key-element { +.keyboard-key.special-key.highlighted:not([class*='highlight-locked']) > .visual-wrapper > .key-element { color: #00b8d6; } @@ -243,22 +279,22 @@ button::-moz-focus-inner { /* Key states */ /* Active key, used for shift key - uppercase */ -.keyboard-key.kbr-key-active { +.keyboard-key.kbr-key-active:not([class*='highlight-locked']) { background-color: #00caf2; } -.keyboard-key.kbr-key-active > .visual-wrapper > .key-element { +.keyboard-key.kbr-key-active:not([class*='highlight-locked']) > .visual-wrapper > .key-element { color: #fff; border-right-color: transparent; } /* Caps lock case */ -.keyboard-key.special-key.kbr-key-hold > .visual-wrapper > .key-element { +.keyboard-key.special-key.kbr-key-hold:not([class*='highlight-locked']) > .visual-wrapper > .key-element { color: #00caf2; } /* The underline for caps lock */ -.keyboard-key.kbr-key-hold > .visual-wrapper { +.keyboard-key.kbr-key-hold:not([class*='highlight-locked']) > .visual-wrapper { box-shadow: 0 0.4rem 0 #00caf2; }