1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/dom/browser-element/mochitest/browserElement_SetInputMethodActive.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,178 @@ 1.4 +/* Any copyright is dedicated to the public domain. 1.5 + http://creativecommons.org/publicdomain/zero/1.0/ */ 1.6 + 1.7 +// Bug 905573 - Add setInputMethodActive to browser elements to allow gaia 1.8 +// system set the active IME app. 1.9 +'use strict'; 1.10 + 1.11 +SimpleTest.waitForExplicitFinish(); 1.12 +browserElementTestHelpers.setEnabledPref(true); 1.13 +browserElementTestHelpers.addPermission(); 1.14 + 1.15 +function setup() { 1.16 + let appInfo = SpecialPowers.Cc['@mozilla.org/xre/app-info;1'] 1.17 + .getService(SpecialPowers.Ci.nsIXULAppInfo); 1.18 + if (appInfo.name != 'B2G') { 1.19 + SpecialPowers.Cu.import("resource://gre/modules/Keyboard.jsm", window); 1.20 + } 1.21 + 1.22 + SpecialPowers.setBoolPref("dom.mozInputMethod.enabled", true); 1.23 + SpecialPowers.setBoolPref("dom.mozInputMethod.testing", true); 1.24 + SpecialPowers.addPermission('input-manage', true, document); 1.25 +} 1.26 + 1.27 +function tearDown() { 1.28 + SpecialPowers.setBoolPref("dom.mozInputMethod.enabled", false); 1.29 + SpecialPowers.setBoolPref("dom.mozInputMethod.testing", false); 1.30 + SpecialPowers.removePermission('input-manage', document); 1.31 + SimpleTest.finish(); 1.32 +} 1.33 + 1.34 +function runTest() { 1.35 + let path = location.pathname; 1.36 + let imeUrl = location.protocol + '//' + location.host + 1.37 + path.substring(0, path.lastIndexOf('/')) + 1.38 + '/file_inputmethod.html'; 1.39 + SpecialPowers.pushPermissions([{ 1.40 + type: 'input', 1.41 + allow: true, 1.42 + context: { 1.43 + url: imeUrl, 1.44 + appId: SpecialPowers.Ci.nsIScriptSecurityManager.NO_APP_ID, 1.45 + isInBrowserElement: true 1.46 + } 1.47 + }], createFrames); 1.48 +} 1.49 + 1.50 +var gFrames = []; 1.51 +var gInputFrame; 1.52 + 1.53 +function createFrames() { 1.54 + // Create two input method iframes. 1.55 + let loadendCount = 0; 1.56 + let countLoadend = function() { 1.57 + ok(this.setInputMethodActive, 'Can access setInputMethodActive.'); 1.58 + 1.59 + if (this === gInputFrame) { 1.60 + // The frame script running in the frame where the input is hosted. 1.61 + let appFrameScript = function appFrameScript() { 1.62 + let input = content.document.body.firstElementChild; 1.63 + input.oninput = function() { 1.64 + sendAsyncMessage('test:InputMethod:oninput', this.value); 1.65 + }; 1.66 + 1.67 + /* 1.68 + * Bug 957213. Sometimes we need to refocus the input field to avoid 1.69 + * intermittent test failure. 1.70 + */ 1.71 + content.setInterval(function() { 1.72 + input.focus(); 1.73 + }, 500); 1.74 + } 1.75 + 1.76 + // Inject frame script to receive input. 1.77 + let mm = SpecialPowers.getBrowserFrameMessageManager(gInputFrame); 1.78 + mm.loadFrameScript('data:,(' + appFrameScript.toString() + ')();', false); 1.79 + mm.addMessageListener("test:InputMethod:oninput", next); 1.80 + } 1.81 + 1.82 + loadendCount++; 1.83 + if (loadendCount === 3) { 1.84 + startTest(); 1.85 + } 1.86 + }; 1.87 + 1.88 + // Create an input field to receive string from input method iframes. 1.89 + gInputFrame = document.createElement('iframe'); 1.90 + SpecialPowers.wrap(gInputFrame).mozbrowser = true; 1.91 + gInputFrame.src = 1.92 + 'data:text/html,<input autofocus value="hello" />' + 1.93 + '<p>This is targetted mozbrowser frame.</p>'; 1.94 + document.body.appendChild(gInputFrame); 1.95 + gInputFrame.addEventListener('mozbrowserloadend', countLoadend); 1.96 + 1.97 + for (let i = 0; i < 2; i++) { 1.98 + let frame = gFrames[i] = document.createElement('iframe'); 1.99 + SpecialPowers.wrap(gFrames[i]).mozbrowser = true; 1.100 + // When the input method iframe is activated, it will send the URL 1.101 + // hash to current focused element. We set different hash to each 1.102 + // iframe so that iframes can be differentiated by their hash. 1.103 + frame.src = 'file_inputmethod.html#' + i; 1.104 + document.body.appendChild(frame); 1.105 + frame.addEventListener('mozbrowserloadend', countLoadend); 1.106 + } 1.107 +} 1.108 + 1.109 +function startTest() { 1.110 + // Set focus to the input field and wait for input methods' inputting. 1.111 + SpecialPowers.DOMWindowUtils.focus(gInputFrame); 1.112 + 1.113 + let req0 = gFrames[0].setInputMethodActive(true); 1.114 + req0.onsuccess = function() { 1.115 + ok(true, 'setInputMethodActive succeeded (0).'); 1.116 + }; 1.117 + 1.118 + req0.onerror = function() { 1.119 + ok(false, 'setInputMethodActive failed (0): ' + this.error.name); 1.120 + }; 1.121 +} 1.122 + 1.123 +var gTimerId = null; 1.124 +var gCount = 0; 1.125 + 1.126 +function next(msg) { 1.127 + gCount++; 1.128 + let wrappedMsg = SpecialPowers.wrap(msg); 1.129 + let value = wrappedMsg.data; 1.130 + // The texts sent from the first and the second input method are '#0' and 1.131 + // '#1' respectively. 1.132 + switch (gCount) { 1.133 + case 1: 1.134 + is(value, '#0hello', 1.135 + 'Failed to get correct input from the first iframe.'); 1.136 + let req1 = gFrames[1].setInputMethodActive(true); 1.137 + req1.onsuccess = function() { 1.138 + ok(true, 'setInputMethodActive succeeded (1).'); 1.139 + }; 1.140 + req1.onerror = function() { 1.141 + ok(false, 'setInputMethodActive failed (1): ' + this.error.name); 1.142 + }; 1.143 + break; 1.144 + 1.145 + case 2: 1.146 + is(value, '#0#1hello', 1.147 + 'Failed to get correct input from the second iframe.'); 1.148 + // Do nothing and wait for the next input from the second iframe. 1.149 + break; 1.150 + 1.151 + case 3: 1.152 + is(value, '#0#1#1hello', 1.153 + 'Failed to get correct input from the second iframe.'); 1.154 + // Receive the second input from the second iframe. 1.155 + // Deactive the second iframe. 1.156 + let req3 = gFrames[1].setInputMethodActive(false); 1.157 + req3.onsuccess = function() { 1.158 + ok(true, 'setInputMethodActive(false) succeeded (3).'); 1.159 + }; 1.160 + req3.onerror = function() { 1.161 + ok(false, 'setInputMethodActive(false) failed (3): ' + this.error.name); 1.162 + }; 1.163 + 1.164 + // Wait for a short while to ensure the second iframe is not active any 1.165 + // more. 1.166 + gTimerId = setTimeout(function() { 1.167 + ok(true, 'Successfully deactivate the second iframe.'); 1.168 + tearDown(); 1.169 + }, 1000); 1.170 + break; 1.171 + 1.172 + case 4: 1.173 + ok(false, 'Failed to deactivate the second iframe in time.'); 1.174 + clearTimeout(gTimerId); 1.175 + tearDown(); 1.176 + break; 1.177 + } 1.178 +} 1.179 + 1.180 +setup(); 1.181 +addEventListener('testready', runTest);