dom/browser-element/mochitest/browserElement_SetInputMethodActive.js

Wed, 31 Dec 2014 06:55:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:55:50 +0100
changeset 2
7e26c7da4463
permissions
-rw-r--r--

Added tag UPSTREAM_283F7C6 for changeset ca08bd8f51b2

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

mercurial