| Index: ui/keyboard/resources/elements/kb-keyboard.js
|
| diff --git a/ui/keyboard/resources/elements/kb-keyboard.js b/ui/keyboard/resources/elements/kb-keyboard.js
|
| deleted file mode 100644
|
| index ceb8f683d08d992c3b4c556adbf27c11cb9f3b13..0000000000000000000000000000000000000000
|
| --- a/ui/keyboard/resources/elements/kb-keyboard.js
|
| +++ /dev/null
|
| @@ -1,977 +0,0 @@
|
| -// Copyright 2014 The Chromium Authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style license that can be
|
| -// found in the LICENSE file.
|
| -
|
| -/**
|
| - * The repeat delay in milliseconds before a key starts repeating. Use the
|
| - * same rate as Chromebook.
|
| - * (See chrome/browser/chromeos/language_preferences.cc)
|
| - * @const
|
| - * @type {number}
|
| - */
|
| -var REPEAT_DELAY_MSEC = 500;
|
| -
|
| -/**
|
| - * The repeat interval or number of milliseconds between subsequent
|
| - * keypresses. Use the same rate as Chromebook.
|
| - * @const
|
| - * @type {number}
|
| - */
|
| -var REPEAT_INTERVAL_MSEC = 50;
|
| -
|
| -/**
|
| - * The double click/tap interval.
|
| - * @const
|
| - * @type {number}
|
| - */
|
| -var DBL_INTERVAL_MSEC = 300;
|
| -
|
| -/**
|
| - * The index of the name of the keyset when searching for all keysets.
|
| - * @const
|
| - * @type {number}
|
| - */
|
| -var REGEX_KEYSET_INDEX = 1;
|
| -
|
| -/**
|
| - * The integer number of matches when searching for keysets.
|
| - * @const
|
| - * @type {number}
|
| - */
|
| -var REGEX_MATCH_COUNT = 2;
|
| -
|
| -/**
|
| - * The boolean to decide if keyboard should transit to upper case keyset
|
| - * when spacebar is pressed. If a closing punctuation is followed by a
|
| - * spacebar, keyboard should automatically transit to upper case.
|
| - * @type {boolean}
|
| - */
|
| -var enterUpperOnSpace = false;
|
| -
|
| -/**
|
| - * A structure to track the currently repeating key on the keyboard.
|
| - */
|
| -var repeatKey = {
|
| -
|
| - /**
|
| - * The timer for the delay before repeating behaviour begins.
|
| - * @type {number|undefined}
|
| - */
|
| - timer: undefined,
|
| -
|
| - /**
|
| - * The interval timer for issuing keypresses of a repeating key.
|
| - * @type {number|undefined}
|
| - */
|
| - interval: undefined,
|
| -
|
| - /**
|
| - * The key which is currently repeating.
|
| - * @type {BaseKey|undefined}
|
| - */
|
| - key: undefined,
|
| -
|
| - /**
|
| - * Cancel the repeat timers of the currently active key.
|
| - */
|
| - cancel: function() {
|
| - clearTimeout(this.timer);
|
| - clearInterval(this.interval);
|
| - this.timer = undefined;
|
| - this.interval = undefined;
|
| - this.key = undefined;
|
| - }
|
| -};
|
| -
|
| -/**
|
| - * The minimum movement interval needed to trigger cursor move on
|
| - * horizontal and vertical way.
|
| - * @const
|
| - * @type {number}
|
| - */
|
| -var MIN_SWIPE_DIST_X = 50;
|
| -var MIN_SWIPE_DIST_Y = 20;
|
| -
|
| -/**
|
| - * The maximum swipe distance that will trigger hintText of a key
|
| - * to be typed.
|
| - * @const
|
| - * @type {number}
|
| - */
|
| -var MAX_SWIPE_FLICK_DIST = 60;
|
| -
|
| -/**
|
| - * The boolean to decide if it is swipe in process or finished.
|
| - * @type {boolean}
|
| - */
|
| -var swipeInProgress = false;
|
| -
|
| -// Flag values for ctrl, alt and shift as defined by EventFlags
|
| -// in "event_constants.h".
|
| -// @enum {number}
|
| -var Modifier = {
|
| - NONE: 0,
|
| - ALT: 8,
|
| - CONTROL: 4,
|
| - SHIFT: 2
|
| -};
|
| -
|
| -/**
|
| - * A structure to track the current swipe status.
|
| - */
|
| -var swipeTracker = {
|
| - /**
|
| - * The latest PointerMove event in the swipe.
|
| - * @type {Object}
|
| - */
|
| - currentEvent: undefined,
|
| -
|
| - /**
|
| - * Whether or not a swipe changes direction.
|
| - * @type {false}
|
| - */
|
| - isComplex: false,
|
| -
|
| - /**
|
| - * The count of horizontal and vertical movement.
|
| - * @type {number}
|
| - */
|
| - offset_x : 0,
|
| - offset_y : 0,
|
| -
|
| - /**
|
| - * Last touch coordinate.
|
| - * @type {number}
|
| - */
|
| - pre_x : 0,
|
| - pre_y : 0,
|
| -
|
| - /**
|
| - * The PointerMove event which triggered the swipe.
|
| - * @type {Object}
|
| - */
|
| - startEvent: undefined,
|
| -
|
| - /**
|
| - * The flag of current modifier key.
|
| - * @type {number}
|
| - */
|
| - swipeFlags : 0,
|
| -
|
| - /**
|
| - * Current swipe direction.
|
| - * @type {number}
|
| - */
|
| - swipeDirection : 0,
|
| -
|
| - /**
|
| - * The number of times we've swiped within a single swipe.
|
| - * @type {number}
|
| - */
|
| - swipeIndex: 0,
|
| -
|
| - /**
|
| - * Returns the combined direction of the x and y offsets.
|
| - * @return {number} The latest direction.
|
| - */
|
| - getOffsetDirection: function() {
|
| - // TODO (rsadam): Use angles to figure out the direction.
|
| - var direction = 0;
|
| - // Checks for horizontal swipe.
|
| - if (Math.abs(this.offset_x) > MIN_SWIPE_DIST_X) {
|
| - if (this.offset_x > 0) {
|
| - direction |= SwipeDirection.RIGHT;
|
| - } else {
|
| - direction |= SwipeDirection.LEFT;
|
| - }
|
| - }
|
| - // Checks for vertical swipe.
|
| - if (Math.abs(this.offset_y) > MIN_SWIPE_DIST_Y) {
|
| - if (this.offset_y < 0) {
|
| - direction |= SwipeDirection.UP;
|
| - } else {
|
| - direction |= SwipeDirection.DOWN;
|
| - }
|
| - }
|
| - return direction;
|
| - },
|
| -
|
| - /**
|
| - * Populates the swipe update details.
|
| - * @param {boolean} endSwipe Whether this is the final event for this
|
| - * swipe.
|
| - * @return {Object} The current state of the swipeTracker.
|
| - */
|
| - populateDetails: function(endSwipe) {
|
| - var detail = {};
|
| - detail.direction = this.swipeDirection;
|
| - detail.index = this.swipeIndex;
|
| - detail.status = this.swipeStatus;
|
| - detail.endSwipe = endSwipe;
|
| - detail.startEvent = this.startEvent;
|
| - detail.currentEvent = this.currentEvent;
|
| - detail.isComplex = this.isComplex;
|
| - return detail;
|
| - },
|
| -
|
| - /**
|
| - * Reset all the values when swipe finished.
|
| - */
|
| - resetAll: function() {
|
| - this.offset_x = 0;
|
| - this.offset_y = 0;
|
| - this.pre_x = 0;
|
| - this.pre_y = 0;
|
| - this.swipeFlags = 0;
|
| - this.swipeDirection = 0;
|
| - this.swipeIndex = 0;
|
| - this.startEvent = undefined;
|
| - this.currentEvent = undefined;
|
| - this.isComplex = false;
|
| - },
|
| -
|
| - /**
|
| - * Updates the swipe path with the current event.
|
| - * @param {Object} event The PointerEvent that triggered this update.
|
| - * @return {boolean} Whether or not to notify swipe observers.
|
| - */
|
| - update: function(event) {
|
| - if(!event.isPrimary)
|
| - return false;
|
| - // Update priors.
|
| - this.offset_x += event.screenX - this.pre_x;
|
| - this.offset_y += event.screenY - this.pre_y;
|
| - this.pre_x = event.screenX;
|
| - this.pre_y = event.screenY;
|
| -
|
| - // Check if movement crosses minimum thresholds in each direction.
|
| - var direction = this.getOffsetDirection();
|
| - if (direction == 0)
|
| - return false;
|
| - // If swipeIndex is zero the current event is triggering the swipe.
|
| - if (this.swipeIndex == 0) {
|
| - this.startEvent = event;
|
| - } else if (direction != this.swipeDirection) {
|
| - // Toggle the isComplex flag.
|
| - this.isComplex = true;
|
| - }
|
| - // Update the swipe tracker.
|
| - this.swipeDirection = direction;
|
| - this.offset_x = 0;
|
| - this.offset_y = 0;
|
| - this.currentEvent = event;
|
| - this.swipeIndex++;
|
| - return true;
|
| - },
|
| -
|
| -};
|
| -
|
| -Polymer('kb-keyboard', {
|
| - alt: null,
|
| - config: null,
|
| - control: null,
|
| - dblDetail_: null,
|
| - dblTimer_: null,
|
| - inputType: null,
|
| - lastPressedKey: null,
|
| - shift: null,
|
| - sounds: {},
|
| - stale: true,
|
| - swipeHandler: null,
|
| - voiceInput_: null,
|
| - //TODO(rsadam@): Add a control to let users change this.
|
| - volume: DEFAULT_VOLUME,
|
| -
|
| - /**
|
| - * The default input type to keyboard layout map. The key must be one of
|
| - * the input box type values.
|
| - * @type {object}
|
| - */
|
| - inputTypeToLayoutMap: {
|
| - number: "numeric",
|
| - text: "qwerty",
|
| - password: "qwerty"
|
| - },
|
| -
|
| - /**
|
| - * Caches the specified sound on the keyboard.
|
| - * @param {string} soundId The name of the .wav file in the "sounds"
|
| - directory.
|
| - */
|
| - addSound: function(soundId) {
|
| - // Check if already loaded.
|
| - if (soundId == Sound.NONE || this.sounds[soundId])
|
| - return;
|
| - var pool = [];
|
| - for (var i = 0; i < SOUND_POOL_SIZE; i++) {
|
| - var audio = document.createElement('audio');
|
| - audio.preload = "auto";
|
| - audio.id = soundId;
|
| - audio.src = "../sounds/" + soundId + ".wav";
|
| - audio.volume = this.volume;
|
| - pool.push(audio);
|
| - }
|
| - this.sounds[soundId] = pool;
|
| - },
|
| -
|
| - /**
|
| - * Changes the current keyset.
|
| - * @param {Object} detail The detail of the event that called this
|
| - * function.
|
| - */
|
| - changeKeyset: function(detail) {
|
| - if (detail.relegateToShift && this.shift) {
|
| - this.keyset = this.shift.textKeyset;
|
| - this.activeKeyset.nextKeyset = undefined;
|
| - return true;
|
| - }
|
| - var toKeyset = detail.toKeyset;
|
| - if (toKeyset) {
|
| - this.keyset = toKeyset;
|
| - this.activeKeyset.nextKeyset = detail.nextKeyset;
|
| - return true;
|
| - }
|
| - return false;
|
| - },
|
| -
|
| - keysetChanged: function() {
|
| - var keyset = this.activeKeyset;
|
| - // Show the keyset if it has been initialized.
|
| - if (keyset)
|
| - keyset.show();
|
| - },
|
| -
|
| - configChanged: function() {
|
| - this.layout = this.config.layout;
|
| - },
|
| -
|
| - ready: function() {
|
| - this.voiceInput_ = new VoiceInput(this);
|
| - this.swipeHandler = this.move.bind(this);
|
| - var self = this;
|
| - getKeyboardConfig(function(config) {
|
| - self.config = config;
|
| - });
|
| - },
|
| -
|
| - /**
|
| - * Registers a callback for state change events.
|
| - * @param{!Function} callback Callback function to register.
|
| - */
|
| - addKeysetChangedObserver: function(callback) {
|
| - this.addEventListener('stateChange', callback);
|
| - },
|
| -
|
| - /**
|
| - * Called when the type of focused input box changes. If a keyboard layout
|
| - * is defined for the current input type, that layout will be loaded.
|
| - * Otherwise, the keyboard layout for 'text' type will be loaded.
|
| - */
|
| - inputTypeChanged: function() {
|
| - // Disable layout switching at accessibility mode.
|
| - if (this.config && this.config.a11ymode)
|
| - return;
|
| -
|
| - // TODO(bshe): Toggle visibility of some keys in a keyboard layout
|
| - // according to the input type.
|
| - var layout = this.inputTypeToLayoutMap[this.inputType];
|
| - if (!layout)
|
| - layout = this.inputTypeToLayoutMap.text;
|
| - this.layout = layout;
|
| - },
|
| -
|
| - /**
|
| - * When double click/tap event is enabled, the second key-down and key-up
|
| - * events on the same key should be skipped. Return true when the event
|
| - * with |detail| should be skipped.
|
| - * @param {Object} detail The detail of key-up or key-down event.
|
| - */
|
| - skipEvent: function(detail) {
|
| - if (this.dblDetail_) {
|
| - if (this.dblDetail_.char != detail.char) {
|
| - // The second key down is not on the same key. Double click/tap
|
| - // should be ignored.
|
| - this.dblDetail_ = null;
|
| - clearTimeout(this.dblTimer_);
|
| - } else if (this.dblDetail_.clickCount == 1) {
|
| - return true;
|
| - }
|
| - }
|
| - return false;
|
| - },
|
| -
|
| - /**
|
| - * Handles a swipe update.
|
| - * param {Object} detail The swipe update details.
|
| - */
|
| - onSwipeUpdate: function(detail) {
|
| - var direction = detail.direction;
|
| - if (!direction)
|
| - console.error("Swipe direction cannot be: " + direction);
|
| - // Triggers swipe editting if it's a purely horizontal swipe.
|
| - if (!(direction & (SwipeDirection.UP | SwipeDirection.DOWN))) {
|
| - // Nothing to do if the swipe has ended.
|
| - if (detail.endSwipe)
|
| - return;
|
| - var modifiers = 0;
|
| - // TODO (rsadam): This doesn't take into account index shifts caused
|
| - // by vertical swipes.
|
| - if (detail.index % 2 != 0) {
|
| - modifiers |= Modifier.SHIFT;
|
| - modifiers |= Modifier.CONTROL;
|
| - }
|
| - MoveCursor(direction, modifiers);
|
| - return;
|
| - }
|
| - // Triggers swipe hintText if it's a purely vertical swipe.
|
| - if (this.activeKeyset.flick &&
|
| - !(direction & (SwipeDirection.LEFT | SwipeDirection.RIGHT))) {
|
| - // Check if event is relevant to us.
|
| - if ((!detail.endSwipe) || (detail.isComplex))
|
| - return;
|
| - // Too long a swipe.
|
| - var distance = Math.abs(detail.startEvent.screenY -
|
| - detail.currentEvent.screenY);
|
| - if (distance > MAX_SWIPE_FLICK_DIST)
|
| - return;
|
| - var triggerKey = detail.startEvent.target;
|
| - if (triggerKey && triggerKey.onFlick)
|
| - triggerKey.onFlick(detail);
|
| - }
|
| - },
|
| -
|
| - /**
|
| - * This function is bound to swipeHandler. Updates the current swipe
|
| - * status so that PointerEvents can be converted to Swipe events.
|
| - * @param {PointerEvent} event.
|
| - */
|
| - move: function(event) {
|
| - if (!swipeTracker.update(event))
|
| - return;
|
| - // Conversion was successful, swipe is now in progress.
|
| - swipeInProgress = true;
|
| - if (this.lastPressedKey) {
|
| - this.lastPressedKey.classList.remove('active');
|
| - this.lastPressedKey = null;
|
| - }
|
| - this.onSwipeUpdate(swipeTracker.populateDetails(false));
|
| - },
|
| -
|
| - /**
|
| - * Handles key-down event that is sent by kb-key-base.
|
| - * @param {CustomEvent} event The key-down event dispatched by
|
| - * kb-key-base.
|
| - * @param {Object} detail The detail of pressed kb-key.
|
| - */
|
| - keyDown: function(event, detail) {
|
| - if (this.skipEvent(detail))
|
| - return;
|
| -
|
| - if (this.lastPressedKey) {
|
| - this.lastPressedKey.classList.remove('active');
|
| - this.lastPressedKey.autoRelease();
|
| - }
|
| - this.lastPressedKey = event.target;
|
| - this.lastPressedKey.classList.add('active');
|
| - repeatKey.cancel();
|
| - this.playSound(detail.sound);
|
| -
|
| - var char = detail.char;
|
| - switch(char) {
|
| - case 'Shift':
|
| - this.classList.remove('caps-locked');
|
| - break;
|
| - case 'Alt':
|
| - case 'Ctrl':
|
| - var modifier = char.toLowerCase() + "-active";
|
| - // Removes modifier if already active.
|
| - if (this.classList.contains(modifier))
|
| - this.classList.remove(modifier);
|
| - break;
|
| - case 'Invalid':
|
| - // Not all Invalid keys are transition keys. Reset control keys if
|
| - // we pressed a transition key.
|
| - if (event.target.toKeyset || detail.relegateToShift)
|
| - this.onNonControlKeyTyped();
|
| - break;
|
| - default:
|
| - // Notify shift key.
|
| - if (this.shift)
|
| - this.shift.onNonControlKeyDown();
|
| - if (this.ctrl)
|
| - this.ctrl.onNonControlKeyDown();
|
| - if (this.alt)
|
| - this.alt.onNonControlKeyDown();
|
| - break;
|
| - }
|
| - if(this.changeKeyset(detail))
|
| - return;
|
| - if (detail.repeat) {
|
| - this.keyTyped(detail);
|
| - this.onNonControlKeyTyped();
|
| - repeatKey.key = this.lastPressedKey;
|
| - var self = this;
|
| - repeatKey.timer = setTimeout(function() {
|
| - repeatKey.timer = undefined;
|
| - repeatKey.interval = setInterval(function() {
|
| - self.playSound(detail.sound);
|
| - self.keyTyped(detail);
|
| - }, REPEAT_INTERVAL_MSEC);
|
| - }, Math.max(0, REPEAT_DELAY_MSEC - REPEAT_INTERVAL_MSEC));
|
| - }
|
| - },
|
| -
|
| - /**
|
| - * Handles key-out event that is sent by kb-shift-key.
|
| - * @param {CustomEvent} event The key-out event dispatched by
|
| - * kb-shift-key.
|
| - * @param {Object} detail The detail of pressed kb-shift-key.
|
| - */
|
| - keyOut: function(event, detail) {
|
| - this.changeKeyset(detail);
|
| - },
|
| -
|
| - /**
|
| - * Enable/start double click/tap event recognition.
|
| - * @param {CustomEvent} event The enable-dbl event dispatched by
|
| - * kb-shift-key.
|
| - * @param {Object} detail The detail of pressed kb-shift-key.
|
| - */
|
| - enableDbl: function(event, detail) {
|
| - if (!this.dblDetail_) {
|
| - this.dblDetail_ = detail;
|
| - this.dblDetail_.clickCount = 0;
|
| - var self = this;
|
| - this.dblTimer_ = setTimeout(function() {
|
| - self.dblDetail_.callback = null;
|
| - self.dblDetail_ = null;
|
| - }, DBL_INTERVAL_MSEC);
|
| - }
|
| - },
|
| -
|
| - /**
|
| - * Enable the selection while swipe.
|
| - * @param {CustomEvent} event The enable-dbl event dispatched by
|
| - * kb-shift-key.
|
| - */
|
| - enableSel: function(event) {
|
| - // TODO(rsadam): Disabled for now. May come back if we revert swipe
|
| - // selection to not do word selection.
|
| - },
|
| -
|
| - /**
|
| - * Handles pointerdown event. This is used for swipe selection process.
|
| - * to get the start pre_x and pre_y. And also add a pointermove handler
|
| - * to start handling the swipe selection event.
|
| - * @param {PointerEvent} event The pointerup event that received by
|
| - * kb-keyboard.
|
| - */
|
| - down: function(event) {
|
| - var layout = getKeysetLayout(this.activeKeysetId);
|
| - var key = layout.findClosestKey(event.clientX, event.clientY);
|
| - if (key)
|
| - key.down(event);
|
| - if (event.isPrimary) {
|
| - swipeTracker.pre_x = event.screenX;
|
| - swipeTracker.pre_y = event.screenY;
|
| - this.addEventListener("pointermove", this.swipeHandler, false);
|
| - }
|
| - },
|
| -
|
| - /**
|
| - * Handles pointerup event. This is used for double tap/click events.
|
| - * @param {PointerEvent} event The pointerup event that bubbled to
|
| - * kb-keyboard.
|
| - */
|
| - up: function(event) {
|
| - var layout = getKeysetLayout(this.activeKeysetId);
|
| - var key = layout.findClosestKey(event.clientX, event.clientY);
|
| - if (key)
|
| - key.up(event);
|
| - // When touch typing, it is very possible that finger moves slightly out
|
| - // of the key area before releases. The key should not be dropped in
|
| - // this case.
|
| - // TODO(rsadam@) Change behaviour such that the key drops and the second
|
| - // key gets pressed.
|
| - if (this.lastPressedKey &&
|
| - this.lastPressedKey.pointerId == event.pointerId) {
|
| - this.lastPressedKey.autoRelease();
|
| - }
|
| -
|
| - if (this.dblDetail_) {
|
| - this.dblDetail_.clickCount++;
|
| - if (this.dblDetail_.clickCount == 2) {
|
| - this.dblDetail_.callback();
|
| - this.changeKeyset(this.dblDetail_);
|
| - clearTimeout(this.dblTimer_);
|
| -
|
| - this.classList.add('caps-locked');
|
| -
|
| - this.dblDetail_ = null;
|
| - }
|
| - }
|
| -
|
| - // TODO(zyaozhujun): There are some edge cases to deal with later.
|
| - // (for instance, what if a second finger trigger a down and up
|
| - // event sequence while swiping).
|
| - // When pointer up from the screen, a swipe selection session finished,
|
| - // all the data should be reset to prepare for the next session.
|
| - if (event.isPrimary && swipeInProgress) {
|
| - swipeInProgress = false;
|
| - this.onSwipeUpdate(swipeTracker.populateDetails(true))
|
| - swipeTracker.resetAll();
|
| - }
|
| - this.removeEventListener('pointermove', this.swipeHandler, false);
|
| - },
|
| -
|
| - /**
|
| - * Handles PointerOut event. This is used for when a swipe gesture goes
|
| - * outside of the keyboard window.
|
| - * @param {Object} event The pointerout event that bubbled to the
|
| - * kb-keyboard.
|
| - */
|
| - out: function(event) {
|
| - repeatKey.cancel();
|
| - // Ignore if triggered from one of the keys.
|
| - if (this.compareDocumentPosition(event.relatedTarget) &
|
| - Node.DOCUMENT_POSITION_CONTAINED_BY)
|
| - return;
|
| - if (swipeInProgress)
|
| - this.onSwipeUpdate(swipeTracker.populateDetails(true))
|
| - // Touched outside of the keyboard area, so disables swipe.
|
| - swipeInProgress = false;
|
| - swipeTracker.resetAll();
|
| - this.removeEventListener('pointermove', this.swipeHandler, false);
|
| - },
|
| -
|
| - /**
|
| - * Handles a TypeKey event. This is used for when we programmatically
|
| - * want to type a specific key.
|
| - * @param {CustomEvent} event The TypeKey event that bubbled to the
|
| - * kb-keyboard.
|
| - */
|
| - type: function(event) {
|
| - this.keyTyped(event.detail);
|
| - },
|
| -
|
| - /**
|
| - * Handles key-up event that is sent by kb-key-base.
|
| - * @param {CustomEvent} event The key-up event dispatched by kb-key-base.
|
| - * @param {Object} detail The detail of pressed kb-key.
|
| - */
|
| - keyUp: function(event, detail) {
|
| - if (this.skipEvent(detail))
|
| - return;
|
| - if (swipeInProgress)
|
| - return;
|
| - if (detail.activeModifier) {
|
| - var modifier = detail.activeModifier.toLowerCase() + "-active";
|
| - this.classList.add(modifier);
|
| - }
|
| - // Adds the current keyboard modifiers to the detail.
|
| - if (this.ctrl)
|
| - detail.controlModifier = this.ctrl.isActive();
|
| - if (this.alt)
|
| - detail.altModifier = this.alt.isActive();
|
| - if (this.lastPressedKey)
|
| - this.lastPressedKey.classList.remove('active');
|
| - // Keyset transition key. This is needed to transition from upper
|
| - // to lower case when we are not in caps mode, as well as when
|
| - // we're ending chording.
|
| - this.changeKeyset(detail);
|
| -
|
| - if (this.lastPressedKey &&
|
| - this.lastPressedKey.charValue != event.target.charValue) {
|
| - return;
|
| - }
|
| - if (repeatKey.key == event.target) {
|
| - repeatKey.cancel();
|
| - this.lastPressedKey = null;
|
| - return;
|
| - }
|
| - var toLayoutId = detail.toLayout;
|
| - // Layout transition key.
|
| - if (toLayoutId)
|
| - this.layout = toLayoutId;
|
| - var char = detail.char;
|
| - this.lastPressedKey = null;
|
| - // Characters that should not be typed.
|
| - switch(char) {
|
| - case 'Invalid':
|
| - case 'Shift':
|
| - case 'Ctrl':
|
| - case 'Alt':
|
| - enterUpperOnSpace = false;
|
| - swipeTracker.swipeFlags = 0;
|
| - return;
|
| - case 'Microphone':
|
| - this.voiceInput_.onDown();
|
| - return;
|
| - default:
|
| - break;
|
| - }
|
| - // Tries to type the character. Resorts to insertText if that fails.
|
| - if(!this.keyTyped(detail))
|
| - insertText(char);
|
| - // Post-typing logic.
|
| - switch(char) {
|
| - case '\n':
|
| - case ' ':
|
| - if(enterUpperOnSpace) {
|
| - enterUpperOnSpace = false;
|
| - if (this.shift) {
|
| - var shiftDetail = this.shift.onSpaceAfterPunctuation();
|
| - // Check if transition defined.
|
| - this.changeKeyset(shiftDetail);
|
| - } else {
|
| - console.error('Capitalization on space after punctuation \
|
| - enabled, but cannot find target keyset.');
|
| - }
|
| - // Immediately return to maintain shift-state. Space is a
|
| - // non-control key and would otherwise trigger a reset of the
|
| - // shift key, causing a transition to lower case.
|
| - return;
|
| - }
|
| - break;
|
| - case '.':
|
| - case '?':
|
| - case '!':
|
| - enterUpperOnSpace = this.shouldUpperOnSpace();
|
| - break;
|
| - default:
|
| - enterUpperOnSpace = false;
|
| - break;
|
| - }
|
| - // Reset control keys.
|
| - this.onNonControlKeyTyped();
|
| - },
|
| -
|
| - /**
|
| - * Handles key-longpress event that is sent by kb-key-base.
|
| - * @param {CustomEvent} event The key-longpress event dispatched by
|
| - * kb-key-base.
|
| - * @param {Object} detail The detail of pressed key.
|
| - */
|
| - keyLongpress: function(event, detail) {
|
| - // If the gesture is long press, remove the pointermove listener.
|
| - this.removeEventListener('pointermove', this.swipeHandler, false);
|
| - // Keyset transtion key.
|
| - if (this.changeKeyset(detail)) {
|
| - // Locks the keyset before removing active to prevent flicker.
|
| - this.classList.add('caps-locked');
|
| - // Makes last pressed key inactive if transit to a new keyset on long
|
| - // press.
|
| - if (this.lastPressedKey)
|
| - this.lastPressedKey.classList.remove('active');
|
| - }
|
| - },
|
| -
|
| - /**
|
| - * Plays the specified sound.
|
| - * @param {Sound} sound The id of the audio tag.
|
| - */
|
| - playSound: function(sound) {
|
| - if (!SOUND_ENABLED || !sound || sound == Sound.NONE)
|
| - return;
|
| - var pool = this.sounds[sound];
|
| - if (!pool) {
|
| - console.error("Cannot find audio tag: " + sound);
|
| - return;
|
| - }
|
| - // Search the sound pool for a free resource.
|
| - for (var i = 0; i < pool.length; i++) {
|
| - if (pool[i].paused) {
|
| - pool[i].play();
|
| - return;
|
| - }
|
| - }
|
| - },
|
| -
|
| - /**
|
| - * Whether we should transit to upper case when seeing a space after
|
| - * punctuation.
|
| - * @return {boolean}
|
| - */
|
| - shouldUpperOnSpace: function() {
|
| - // TODO(rsadam): Add other input types in which we should not
|
| - // transition to upper after a space.
|
| - return this.inputTypeValue != 'password';
|
| - },
|
| -
|
| - /**
|
| - * Handler for the 'set-layout' event.
|
| - * @param {!Event} event The triggering event.
|
| - * @param {{layout: string}} details Details of the event, which contains
|
| - * the name of the layout to activate.
|
| - */
|
| - setLayout: function(event, details) {
|
| - this.layout = details.layout;
|
| - },
|
| -
|
| - /**
|
| - * Handles a change in the keyboard layout. Auto-selects the default
|
| - * keyset for the new layout.
|
| - */
|
| - layoutChanged: function() {
|
| - this.stale = true;
|
| - if (!this.selectDefaultKeyset()) {
|
| - console.error('No default keyset found for layout: ' + this.layout);
|
| - return;
|
| - }
|
| - this.activeKeyset.show();
|
| - },
|
| -
|
| - /**
|
| - * Notifies the modifier keys that a non-control key was typed. This
|
| - * lets them reset sticky behaviour. A non-control key is defined as
|
| - * any key that is not Control, Alt, or Shift.
|
| - */
|
| - onNonControlKeyTyped: function() {
|
| - if (this.shift)
|
| - this.shift.onNonControlKeyTyped();
|
| - if (this.ctrl)
|
| - this.ctrl.onNonControlKeyTyped();
|
| - if (this.alt)
|
| - this.alt.onNonControlKeyTyped();
|
| - this.classList.remove('ctrl-active');
|
| - this.classList.remove('alt-active');
|
| - },
|
| -
|
| - /**
|
| - * Callback function for when volume is changed.
|
| - */
|
| - volumeChanged: function() {
|
| - var toChange = Object.keys(this.sounds);
|
| - for (var i = 0; i < toChange.length; i++) {
|
| - var pool = this.sounds[toChange[i]];
|
| - for (var j = 0; j < pool.length; j++) {
|
| - pool[j].volume = this.volume;
|
| - }
|
| - }
|
| - },
|
| -
|
| - /**
|
| - * Id for the active keyset.
|
| - * @type {string}
|
| - */
|
| - get activeKeysetId() {
|
| - return this.layout + '-' + this.keyset;
|
| - },
|
| -
|
| - /**
|
| - * The active keyset DOM object.
|
| - * @type {kb-keyset}
|
| - */
|
| - get activeKeyset() {
|
| - return this.querySelector('#' + this.activeKeysetId);
|
| - },
|
| -
|
| - /**
|
| - * The current input type.
|
| - * @type {string}
|
| - */
|
| - get inputTypeValue() {
|
| - return this.inputType;
|
| - },
|
| -
|
| - /**
|
| - * Changes the input type if it's different from the current
|
| - * type, else resets the keyset to the default keyset.
|
| - * @type {string}
|
| - */
|
| - set inputTypeValue(value) {
|
| - if (value == this.inputType)
|
| - this.selectDefaultKeyset();
|
| - else
|
| - this.inputType = value;
|
| - },
|
| -
|
| - /**
|
| - * The keyboard is ready for input once the target keyset appears
|
| - * in the distributed nodes for the keyboard.
|
| - * @return {boolean} Indicates if the keyboard is ready for input.
|
| - */
|
| - isReady: function() {
|
| - var keyset = this.activeKeyset;
|
| - if (!keyset)
|
| - return false;
|
| - var nodes = this.$.content.getDistributedNodes();
|
| - for (var i = 0; i < nodes.length; i++) {
|
| - if (nodes[i].id && nodes[i].id == keyset.id)
|
| - return true;
|
| - }
|
| - return false;
|
| - },
|
| -
|
| - /**
|
| - * Generates fabricated key events to simulate typing on a
|
| - * physical keyboard.
|
| - * @param {Object} detail Attributes of the key being typed.
|
| - * @return {boolean} Whether the key type succeeded.
|
| - */
|
| - keyTyped: function(detail) {
|
| - var builder = this.$.keyCodeMetadata;
|
| - if (this.ctrl)
|
| - detail.controlModifier = this.ctrl.isActive();
|
| - if (this.alt)
|
| - detail.altModifier = this.alt.isActive();
|
| - var downEvent = builder.createVirtualKeyEvent(detail, "keydown");
|
| - if (downEvent) {
|
| - sendKeyEvent(downEvent);
|
| - sendKeyEvent(builder.createVirtualKeyEvent(detail, "keyup"));
|
| - return true;
|
| - }
|
| - return false;
|
| - },
|
| -
|
| - /**
|
| - * Selects the default keyset for a layout.
|
| - * @return {boolean} True if successful. This method can fail if the
|
| - * keysets corresponding to the layout have not been injected.
|
| - */
|
| - selectDefaultKeyset: function() {
|
| - var keysets = this.querySelectorAll('kb-keyset');
|
| - // Full name of the keyset is of the form 'layout-keyset'.
|
| - var regex = new RegExp('^' + this.layout + '-(.+)');
|
| - var keysetsLoaded = false;
|
| - for (var i = 0; i < keysets.length; i++) {
|
| - var matches = keysets[i].id.match(regex);
|
| - if (matches && matches.length == REGEX_MATCH_COUNT) {
|
| - keysetsLoaded = true;
|
| - // Without both tests for a default keyset, it is possible to get
|
| - // into a state where multiple layouts are displayed. A
|
| - // reproducable test case is do the following set of keyset
|
| - // transitions: qwerty -> system -> dvorak -> qwerty.
|
| - // TODO(kevers): Investigate why this is the case.
|
| - if (keysets[i].isDefault ||
|
| - keysets[i].getAttribute('isDefault') == 'true') {
|
| - this.keyset = matches[REGEX_KEYSET_INDEX];
|
| - this.classList.remove('caps-locked');
|
| - this.classList.remove('alt-active');
|
| - this.classList.remove('ctrl-active');
|
| - // Caches shift key.
|
| - this.shift = this.querySelector('kb-shift-key');
|
| - if (this.shift)
|
| - this.shift.reset();
|
| - // Caches control key.
|
| - this.ctrl = this.querySelector('kb-modifier-key[char=Ctrl]');
|
| - if (this.ctrl)
|
| - this.ctrl.reset();
|
| - // Caches alt key.
|
| - this.alt = this.querySelector('kb-modifier-key[char=Alt]');
|
| - if (this.alt)
|
| - this.alt.reset();
|
| - this.fire('stateChange', {
|
| - state: 'keysetLoaded',
|
| - value: this.keyset,
|
| - });
|
| - keyboardLoaded();
|
| - return true;
|
| - }
|
| - }
|
| - }
|
| - if (keysetsLoaded)
|
| - console.error('No default keyset found for ' + this.layout);
|
| - return false;
|
| - }
|
| -});
|
|
|