Wed, 31 Dec 2014 06:55:50 +0100
Added tag UPSTREAM_283F7C6 for changeset ca08bd8f51b2
michael@0 | 1 | /* Any copyright is dedicated to the public domain. |
michael@0 | 2 | http://creativecommons.org/publicdomain/zero/1.0/ */ |
michael@0 | 3 | |
michael@0 | 4 | // Bug 905573 - Add setInputMethodActive to browser elements to allow gaia |
michael@0 | 5 | // system set the active IME app. |
michael@0 | 6 | 'use strict'; |
michael@0 | 7 | |
michael@0 | 8 | SimpleTest.waitForExplicitFinish(); |
michael@0 | 9 | browserElementTestHelpers.setEnabledPref(true); |
michael@0 | 10 | browserElementTestHelpers.addPermission(); |
michael@0 | 11 | |
michael@0 | 12 | function setup() { |
michael@0 | 13 | let appInfo = SpecialPowers.Cc['@mozilla.org/xre/app-info;1'] |
michael@0 | 14 | .getService(SpecialPowers.Ci.nsIXULAppInfo); |
michael@0 | 15 | if (appInfo.name != 'B2G') { |
michael@0 | 16 | SpecialPowers.Cu.import("resource://gre/modules/Keyboard.jsm", window); |
michael@0 | 17 | } |
michael@0 | 18 | |
michael@0 | 19 | SpecialPowers.setBoolPref("dom.mozInputMethod.enabled", true); |
michael@0 | 20 | SpecialPowers.setBoolPref("dom.mozInputMethod.testing", true); |
michael@0 | 21 | SpecialPowers.addPermission('input-manage', true, document); |
michael@0 | 22 | } |
michael@0 | 23 | |
michael@0 | 24 | function tearDown() { |
michael@0 | 25 | SpecialPowers.setBoolPref("dom.mozInputMethod.enabled", false); |
michael@0 | 26 | SpecialPowers.setBoolPref("dom.mozInputMethod.testing", false); |
michael@0 | 27 | SpecialPowers.removePermission('input-manage', document); |
michael@0 | 28 | SimpleTest.finish(); |
michael@0 | 29 | } |
michael@0 | 30 | |
michael@0 | 31 | function runTest() { |
michael@0 | 32 | let path = location.pathname; |
michael@0 | 33 | let imeUrl = location.protocol + '//' + location.host + |
michael@0 | 34 | path.substring(0, path.lastIndexOf('/')) + |
michael@0 | 35 | '/file_inputmethod.html'; |
michael@0 | 36 | SpecialPowers.pushPermissions([{ |
michael@0 | 37 | type: 'input', |
michael@0 | 38 | allow: true, |
michael@0 | 39 | context: { |
michael@0 | 40 | url: imeUrl, |
michael@0 | 41 | appId: SpecialPowers.Ci.nsIScriptSecurityManager.NO_APP_ID, |
michael@0 | 42 | isInBrowserElement: true |
michael@0 | 43 | } |
michael@0 | 44 | }], createFrames); |
michael@0 | 45 | } |
michael@0 | 46 | |
michael@0 | 47 | var gFrames = []; |
michael@0 | 48 | var gInputFrame; |
michael@0 | 49 | |
michael@0 | 50 | function createFrames() { |
michael@0 | 51 | // Create two input method iframes. |
michael@0 | 52 | let loadendCount = 0; |
michael@0 | 53 | let countLoadend = function() { |
michael@0 | 54 | ok(this.setInputMethodActive, 'Can access setInputMethodActive.'); |
michael@0 | 55 | |
michael@0 | 56 | if (this === gInputFrame) { |
michael@0 | 57 | // The frame script running in the frame where the input is hosted. |
michael@0 | 58 | let appFrameScript = function appFrameScript() { |
michael@0 | 59 | let input = content.document.body.firstElementChild; |
michael@0 | 60 | input.oninput = function() { |
michael@0 | 61 | sendAsyncMessage('test:InputMethod:oninput', this.value); |
michael@0 | 62 | }; |
michael@0 | 63 | |
michael@0 | 64 | /* |
michael@0 | 65 | * Bug 957213. Sometimes we need to refocus the input field to avoid |
michael@0 | 66 | * intermittent test failure. |
michael@0 | 67 | */ |
michael@0 | 68 | content.setInterval(function() { |
michael@0 | 69 | input.focus(); |
michael@0 | 70 | }, 500); |
michael@0 | 71 | } |
michael@0 | 72 | |
michael@0 | 73 | // Inject frame script to receive input. |
michael@0 | 74 | let mm = SpecialPowers.getBrowserFrameMessageManager(gInputFrame); |
michael@0 | 75 | mm.loadFrameScript('data:,(' + appFrameScript.toString() + ')();', false); |
michael@0 | 76 | mm.addMessageListener("test:InputMethod:oninput", next); |
michael@0 | 77 | } |
michael@0 | 78 | |
michael@0 | 79 | loadendCount++; |
michael@0 | 80 | if (loadendCount === 3) { |
michael@0 | 81 | startTest(); |
michael@0 | 82 | } |
michael@0 | 83 | }; |
michael@0 | 84 | |
michael@0 | 85 | // Create an input field to receive string from input method iframes. |
michael@0 | 86 | gInputFrame = document.createElement('iframe'); |
michael@0 | 87 | SpecialPowers.wrap(gInputFrame).mozbrowser = true; |
michael@0 | 88 | gInputFrame.src = |
michael@0 | 89 | 'data:text/html,<input autofocus value="hello" />' + |
michael@0 | 90 | '<p>This is targetted mozbrowser frame.</p>'; |
michael@0 | 91 | document.body.appendChild(gInputFrame); |
michael@0 | 92 | gInputFrame.addEventListener('mozbrowserloadend', countLoadend); |
michael@0 | 93 | |
michael@0 | 94 | for (let i = 0; i < 2; i++) { |
michael@0 | 95 | let frame = gFrames[i] = document.createElement('iframe'); |
michael@0 | 96 | SpecialPowers.wrap(gFrames[i]).mozbrowser = true; |
michael@0 | 97 | // When the input method iframe is activated, it will send the URL |
michael@0 | 98 | // hash to current focused element. We set different hash to each |
michael@0 | 99 | // iframe so that iframes can be differentiated by their hash. |
michael@0 | 100 | frame.src = 'file_inputmethod.html#' + i; |
michael@0 | 101 | document.body.appendChild(frame); |
michael@0 | 102 | frame.addEventListener('mozbrowserloadend', countLoadend); |
michael@0 | 103 | } |
michael@0 | 104 | } |
michael@0 | 105 | |
michael@0 | 106 | function startTest() { |
michael@0 | 107 | // Set focus to the input field and wait for input methods' inputting. |
michael@0 | 108 | SpecialPowers.DOMWindowUtils.focus(gInputFrame); |
michael@0 | 109 | |
michael@0 | 110 | let req0 = gFrames[0].setInputMethodActive(true); |
michael@0 | 111 | req0.onsuccess = function() { |
michael@0 | 112 | ok(true, 'setInputMethodActive succeeded (0).'); |
michael@0 | 113 | }; |
michael@0 | 114 | |
michael@0 | 115 | req0.onerror = function() { |
michael@0 | 116 | ok(false, 'setInputMethodActive failed (0): ' + this.error.name); |
michael@0 | 117 | }; |
michael@0 | 118 | } |
michael@0 | 119 | |
michael@0 | 120 | var gTimerId = null; |
michael@0 | 121 | var gCount = 0; |
michael@0 | 122 | |
michael@0 | 123 | function next(msg) { |
michael@0 | 124 | gCount++; |
michael@0 | 125 | let wrappedMsg = SpecialPowers.wrap(msg); |
michael@0 | 126 | let value = wrappedMsg.data; |
michael@0 | 127 | // The texts sent from the first and the second input method are '#0' and |
michael@0 | 128 | // '#1' respectively. |
michael@0 | 129 | switch (gCount) { |
michael@0 | 130 | case 1: |
michael@0 | 131 | is(value, '#0hello', |
michael@0 | 132 | 'Failed to get correct input from the first iframe.'); |
michael@0 | 133 | let req1 = gFrames[1].setInputMethodActive(true); |
michael@0 | 134 | req1.onsuccess = function() { |
michael@0 | 135 | ok(true, 'setInputMethodActive succeeded (1).'); |
michael@0 | 136 | }; |
michael@0 | 137 | req1.onerror = function() { |
michael@0 | 138 | ok(false, 'setInputMethodActive failed (1): ' + this.error.name); |
michael@0 | 139 | }; |
michael@0 | 140 | break; |
michael@0 | 141 | |
michael@0 | 142 | case 2: |
michael@0 | 143 | is(value, '#0#1hello', |
michael@0 | 144 | 'Failed to get correct input from the second iframe.'); |
michael@0 | 145 | // Do nothing and wait for the next input from the second iframe. |
michael@0 | 146 | break; |
michael@0 | 147 | |
michael@0 | 148 | case 3: |
michael@0 | 149 | is(value, '#0#1#1hello', |
michael@0 | 150 | 'Failed to get correct input from the second iframe.'); |
michael@0 | 151 | // Receive the second input from the second iframe. |
michael@0 | 152 | // Deactive the second iframe. |
michael@0 | 153 | let req3 = gFrames[1].setInputMethodActive(false); |
michael@0 | 154 | req3.onsuccess = function() { |
michael@0 | 155 | ok(true, 'setInputMethodActive(false) succeeded (3).'); |
michael@0 | 156 | }; |
michael@0 | 157 | req3.onerror = function() { |
michael@0 | 158 | ok(false, 'setInputMethodActive(false) failed (3): ' + this.error.name); |
michael@0 | 159 | }; |
michael@0 | 160 | |
michael@0 | 161 | // Wait for a short while to ensure the second iframe is not active any |
michael@0 | 162 | // more. |
michael@0 | 163 | gTimerId = setTimeout(function() { |
michael@0 | 164 | ok(true, 'Successfully deactivate the second iframe.'); |
michael@0 | 165 | tearDown(); |
michael@0 | 166 | }, 1000); |
michael@0 | 167 | break; |
michael@0 | 168 | |
michael@0 | 169 | case 4: |
michael@0 | 170 | ok(false, 'Failed to deactivate the second iframe in time.'); |
michael@0 | 171 | clearTimeout(gTimerId); |
michael@0 | 172 | tearDown(); |
michael@0 | 173 | break; |
michael@0 | 174 | } |
michael@0 | 175 | } |
michael@0 | 176 | |
michael@0 | 177 | setup(); |
michael@0 | 178 | addEventListener('testready', runTest); |