<!DOCTYPE HTML> <html> <!-- https://bugzilla.mozilla.org/show_bug.cgi?id=1201407 --> <head> <title>Test inputcontextfocus and inputcontextblur event</title> <script type="application/javascript;version=1.7" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> <script type="application/javascript;version=1.7" src="inputmethod_common.js"></script> <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/> </head> <body> <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1201407">Mozilla Bug 1201407</a> <p id="display"></p> <pre id="test"> <script class="testbody" type="application/javascript;version=1.7"> let contentFrameMM; function setupTestRunner() { info('setupTestRunner'); let im = navigator.mozInputMethod; let expectedEventDetails = [ { type: 'input', inputType: 'text' }, { type: 'input', inputType: 'search' }, { type: 'textarea', inputType: 'textarea' }, { type: 'contenteditable', inputType: 'textarea' }, { type: 'input', inputType: 'number' }, { type: 'input', inputType: 'tel' }, { type: 'input', inputType: 'url' }, { type: 'input', inputType: 'email' }, { type: 'input', inputType: 'password' }, { type: 'input', inputType: 'datetime' }, { type: 'input', inputType: 'date', value: '2015-08-03', min: '1990-01-01', max: '2020-01-01' }, { type: 'input', inputType: 'month' }, { type: 'input', inputType: 'week' }, { type: 'input', inputType: 'time' }, { type: 'input', inputType: 'datetime-local' }, { type: 'input', inputType: 'color' }, { type: 'select', inputType: 'select-one', choices: { multiple: false, choices: [ { group: false, inGroup: false, text: 'foo', disabled: false, selected: true, optionIndex: 0 }, { group: false, inGroup: false, text: 'bar', disabled: true, selected: false, optionIndex: 1 }, { group: true, text: 'group', disabled: false }, { group: false, inGroup: true, text: 'baz', disabled: false, selected: false, optionIndex: 2 } ] } }, { type: 'select', inputType: 'select-multiple', choices: { multiple: true, choices: [ { group: false, inGroup: false, text: 'foo', disabled: false, selected: true, optionIndex: 0 }, { group: false, inGroup: false, text: 'bar', disabled: true, selected: false, optionIndex: 1 }, { group: true, text: 'group', disabled: false }, { group: false, inGroup: true, text: 'baz', disabled: false, selected: false, optionIndex: 2 } ] } } ]; let expectBlur = false; function deepAssertObject(obj, expectedObj, desc) { for (let prop in expectedObj) { if (typeof expectedObj[prop] === 'object') { deepAssertObject(obj[prop], expectedObj[prop], desc + '.' + prop); } else { is(obj[prop], expectedObj[prop], desc + '.' + prop); } } } im.mgmt.oninputcontextfocus = im.mgmt.oninputcontextblur = function(evt) { if (expectBlur) { is(evt.type, 'inputcontextblur', 'evt.type'); evt.preventDefault(); expectBlur = false; return; } let expectedEventDetail = expectedEventDetails.shift(); if (!expectedEventDetail) { ok(false, 'Receving extra events'); inputmethod_cleanup(); return; } is(evt.type, 'inputcontextfocus', 'evt.type'); evt.preventDefault(); expectBlur = true; let detail = evt.detail; deepAssertObject(detail, expectedEventDetail, 'detail'); if (expectedEventDetails.length) { contentFrameMM.sendAsyncMessage('test:next'); } else { im.mgmt.oninputcontextfocus = im.mgmt.oninputcontextblur = null; inputmethod_cleanup(); } }; } function setupInputAppFrame() { info('setupInputAppFrame'); return new Promise((resolve, reject) => { let appFrameScript = function appFrameScript() { let im = content.navigator.mozInputMethod; im.mgmt.oninputcontextfocus = im.mgmt.oninputcontextblur = function(evt) { sendAsyncMessage('text:appEvent', { type: evt.type }); }; content.document.body.textContent = 'I am a input app'; }; let path = location.pathname; let basePath = location.protocol + '//' + location.host + path.substring(0, path.lastIndexOf('/')); let imeUrl = basePath + '/file_blank.html'; let inputAppFrame = document.createElement('iframe'); inputAppFrame.setAttribute('mozbrowser', true); inputAppFrame.src = imeUrl; document.body.appendChild(inputAppFrame); let mm = SpecialPowers.getBrowserFrameMessageManager(inputAppFrame); inputAppFrame.addEventListener('mozbrowserloadend', function() { mm.addMessageListener('text:appEvent', function(msg) { ok(false, 'Input app should not receive ' + msg.data.type + ' event.'); }); mm.loadFrameScript('data:,(' + encodeURIComponent(appFrameScript.toString()) + ')();', false); // Set the input app frame to be active let req = inputAppFrame.setInputMethodActive(true); resolve(req); }); }); } function setupContentFrame() { info('setupContentFrame'); return new Promise((resolve, reject) => { let contentFrameScript = function contentFrameScript() { let input = content.document.body.firstElementChild; let i = 0; input.focus(); addMessageListener('test:next', function() { content.document.body.children[++i].focus(); }); }; let iframe = document.createElement('iframe'); iframe.src = 'file_test_focus_blur_manage_events.html'; iframe.setAttribute('mozbrowser', true); document.body.appendChild(iframe); let mm = contentFrameMM = SpecialPowers.getBrowserFrameMessageManager(iframe); iframe.addEventListener('mozbrowserloadend', function() { mm.loadFrameScript('data:,(' + encodeURIComponent(contentFrameScript.toString()) + ')();', false); resolve(); }); }); } inputmethod_setup(function() { Promise.resolve() .then(() => setupTestRunner()) .then(() => setupContentFrame()) .then(() => setupInputAppFrame()) .catch((e) => { ok(false, 'Error' + e.toString()); console.error(e); }); }); </script> </pre> </body> </html>