// Copyright 2010 The Closure Library Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS-IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. goog.provide('goog.events.ImeHandlerTest'); goog.setTestOnly('goog.events.ImeHandlerTest'); goog.require('goog.array'); goog.require('goog.dom'); goog.require('goog.events'); goog.require('goog.events.ImeHandler'); goog.require('goog.events.KeyCodes'); goog.require('goog.object'); goog.require('goog.string'); goog.require('goog.testing.PropertyReplacer'); goog.require('goog.testing.events'); goog.require('goog.testing.events.Event'); goog.require('goog.testing.jsunit'); goog.require('goog.userAgent'); var sandbox; var imeHandler; var eventsFired; var stubs = new goog.testing.PropertyReplacer(); var eventTypes = goog.events.ImeHandler.EventType; function setUp() { sandbox = goog.dom.getElement('sandbox'); } function initImeHandler() { goog.events.ImeHandler.USES_COMPOSITION_EVENTS = goog.userAgent.GECKO || (goog.userAgent.WEBKIT && goog.userAgent.isVersionOrHigher(532)); imeHandler = new goog.events.ImeHandler(sandbox); eventsFired = []; goog.events.listen( imeHandler, goog.object.getValues(goog.events.ImeHandler.EventType), function(e) { eventsFired.push(e.type); }); } function tearDown() { imeHandler.dispose(); imeHandler = null; stubs.reset(); } function tearDownPage() { // Set up a test bed. sandbox.innerHTML = '
hello world
'; initImeHandler(); function unshiftEvent(e) { last10Events.unshift( e.type + ':' + e.keyCode + ':' + goog.string.htmlEscape(goog.dom.getTextContent(sandbox))); last10Events.length = Math.min(last10Events.length, 10); goog.dom.getElement('logger').innerHTML = last10Events.join('
'); } var last10Events = []; goog.events.listen( imeHandler, goog.object.getValues(goog.events.ImeHandler.EventType), unshiftEvent); goog.events.listen(sandbox, ['keydown', 'textInput'], unshiftEvent); } function assertEventsFired(var_args) { assertArrayEquals(goog.array.clone(arguments), eventsFired); } function fireInputEvent(type) { return goog.testing.events.fireBrowserEvent( new goog.testing.events.Event(type, sandbox)); } function fireImeKeySequence() { return fireKeySequence(goog.events.KeyCodes.WIN_IME); } function fireKeySequence(keyCode) { return ( goog.testing.events.fireBrowserEvent( new goog.testing.events.Event('textInput', sandbox)) & goog.testing.events.fireKeySequence(sandbox, keyCode)); } function testHandleKeyDown_GeckoCompositionEvents() { // This test verifies that our IME functions can dispatch IME events to // InputHandler in the expected order on Gecko. // Set the userAgent used for this test to Firefox. setUserAgent('GECKO'); stubs.set(goog.userAgent, 'MAC', false); initImeHandler(); fireInputEvent('compositionstart'); assertImeMode(); fireInputEvent('compositionupdate'); fireInputEvent('compositionupdate'); fireInputEvent('compositionend'); assertEventsFired( eventTypes.START, eventTypes.UPDATE, eventTypes.UPDATE, eventTypes.END); assertNotImeMode(); } /** * Verifies that our IME functions can dispatch IME events to the input handler * in the expected order on Chrome. jsUnitFarm does not have Linux Chrome or * Mac Chrome. So, we manually change the platform and run this test three * times. */ function testChromeCompositionEventsLinux() { runChromeCompositionEvents('LINUX'); } function testChromeCompositionEventsMac() { runChromeCompositionEvents('MAC'); } function testChromeCompositionEventsWindows() { runChromeCompositionEvents('WINDOWS'); } function runChromeCompositionEvents(platform) { setUserAgent('WEBKIT'); setVersion(532); stubs.set(goog.userAgent, platform, true); initImeHandler(); fireImeKeySequence(); fireInputEvent('compositionstart'); assertImeMode(); fireInputEvent('compositionupdate'); fireInputEvent('compositionupdate'); fireInputEvent('compositionend'); assertEventsFired( eventTypes.START, eventTypes.UPDATE, eventTypes.UPDATE, eventTypes.END); assertNotImeMode(); } /** * Ensures that the IME mode turn on/off correctly. */ function testHandlerKeyDownForIme_imeOnOff() { setUserAgent('IE'); initImeHandler(); // Send a WIN_IME keyDown event and see whether IME mode turns on. fireImeKeySequence(); assertImeMode(); // Send keyDown events which should not turn off IME mode and see whether // IME mode holds on. fireKeySequence(goog.events.KeyCodes.SHIFT); assertImeMode(); fireKeySequence(goog.events.KeyCodes.CTRL); assertImeMode(); // Send a keyDown event with keyCode = ENTER and see whether IME mode // turns off. fireKeySequence(goog.events.KeyCodes.ENTER); assertNotImeMode(); assertEventsFired(eventTypes.START, eventTypes.END); } /** * Ensures that IME mode turns off when keyup events which are involved * in committing IME text occurred in Safari. */ function testHandleKeyUpForSafari() { setUserAgent('WEBKIT'); setVersion(531); initImeHandler(); fireImeKeySequence(); assertImeMode(); fireKeySequence(goog.events.KeyCodes.ENTER); assertNotImeMode(); } /** * SCIM on Linux will fire WIN_IME keycodes for random characters. * Fortunately, all Linux-based browsers use composition events. * This test just verifies that we ignore the WIN_IME keycodes. */ function testScimFiresWinImeKeycodesGeckoLinux() { setUserAgent('GECKO'); assertScimInputIgnored(); } function testScimFiresWinImeKeycodesChromeLinux() { setUserAgent('WEBKIT'); setVersion(532); assertScimInputIgnored(); } function assertScimInputIgnored() { initImeHandler(); fireImeKeySequence(); assertNotImeMode(); fireInputEvent('compositionstart'); assertImeMode(); fireImeKeySequence(); assertImeMode(); fireInputEvent('compositionend'); assertNotImeMode(); } var userAgents = ['IE', 'GECKO', 'WEBKIT']; function setUserAgent(userAgent) { for (var i = 0; i < userAgents.length; i++) { stubs.set(goog.userAgent, userAgents[i], userAgents[i] == userAgent); } } function setVersion(version) { goog.userAgent.VERSION = version; goog.userAgent.isVersionOrHigherCache_ = {}; } function assertImeMode() { assertTrue('Should be in IME mode.', imeHandler.isImeMode()); } function assertNotImeMode() { assertFalse('Should not be in IME mode.', imeHandler.isImeMode()); }