| /* |
| * Copyright (c) 2010-2019 BSI Business Systems Integration AG. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * BSI Business Systems Integration AG - initial API and implementation |
| */ |
| import {FocusManagerSpecHelper, FormSpecHelper, TableSpecHelper, TreeSpecHelper} from '@eclipse-scout/testing'; |
| import {Device, FocusRule, focusUtils, scout} from '../../src/index'; |
| |
| /* global FocusManagerSpecHelper */ |
| jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000; |
| describe('scout.FocusManager', function() { |
| var session, formHelper, focusHelper, focusManager; |
| |
| beforeEach(function() { |
| setFixtures(sandbox()); |
| jasmine.Ajax.install(); |
| session = sandboxSession(); |
| focusManager = session.focusManager; |
| formHelper = new FormSpecHelper(session); |
| focusHelper = new FocusManagerSpecHelper(); |
| jasmine.clock().install(); |
| uninstallUnloadHandlers(session); |
| }); |
| |
| afterEach(function() { |
| session = null; |
| jasmine.Ajax.uninstall(); |
| jasmine.clock().uninstall(); |
| }); |
| |
| function createDivWithTwoInputs() { |
| var $container = session.$entryPoint.makeDiv(); |
| $container.appendElement('<input type="text" val="input1" class="input1">'); |
| $container.appendElement('<input type="text" val="input2" class="input2">'); |
| return $container; |
| } |
| |
| describe('isSelectableText', function() { |
| |
| it('must return true for disabled text-fields', function() { |
| var $textField = $('<input>') |
| .attr('type', 'text') |
| .attr('disabled', 'disabled'); |
| expect(focusUtils.isSelectableText($textField)).toBe(true); |
| }); |
| |
| }); |
| |
| describe('Focus fixes for Internet Explorer (IE)', function() { |
| |
| beforeEach(function() { |
| // simulate we are an IE |
| Device.get().browser = Device.Browser.INTERNET_EXPLORER; |
| }); |
| |
| it('Click on table-cell, must focus table', function() { |
| var tableHelper = new TableSpecHelper(session); |
| var tableModel = tableHelper.createModelFixture(2, 1); |
| var table = tableHelper.createTable(tableModel); |
| table.render(); |
| |
| // we don't really click - just simulate that the method has been called by the FocusManager |
| var event = { |
| target: $('.table-cell')[0], |
| preventDefault: function() { |
| } |
| }; |
| spyOn(event, 'preventDefault'); |
| focusManager._handleIEEvent(event); |
| expect(document.activeElement).toBe(table.$container[0]); |
| expect(event.preventDefault).toHaveBeenCalled(); |
| }); |
| |
| it('Click on tree-node, must focus tree', function() { |
| var treeHelper = new TreeSpecHelper(session); |
| var treeModel = treeHelper.createModelFixture(1); |
| var tree = treeHelper.createTree(treeModel); |
| tree.render(); |
| |
| // we don't really click - just simulate that the method has been called by the FocusManager |
| var event = { |
| target: $('.tree-node')[0], |
| preventDefault: function() { |
| } |
| }; |
| spyOn(event, 'preventDefault'); |
| focusManager._handleIEEvent(event); |
| expect(document.activeElement).toBe(tree.$container[0]); |
| expect(event.preventDefault).toHaveBeenCalled(); |
| }); |
| |
| }); |
| |
| describe('validateFocus', function() { |
| |
| it('When nothing else is focusable, focus must be on the Desktop (=sandbox)', function() { |
| focusManager.validateFocus(); |
| var sandbox = $('#sandbox')[0]; |
| expect(document.activeElement).toBe(sandbox); |
| }); |
| |
| describe('with forms:', function() { |
| |
| var form; |
| beforeEach(function() { |
| form = formHelper.createFormWithFields(session.desktop, false, 4); |
| form.render(); |
| }); |
| |
| afterEach(function() { |
| form.destroy(); |
| form = null; |
| }); |
| |
| /** |
| * Because form is not a dialog, it does not install its own focus-context |
| * but uses the focus-context of the Desktop (=sandbox) instead. |
| */ |
| it('Focus-context must install listeners on its $container', function() { |
| expect(focusHelper.handlersRegistered(session.$entryPoint)).toBe(true); |
| }); |
| |
| it('Focus must be on the 1st form-field when form is rendered', function() { |
| var $firstField = form.rootGroupBox.fields[0].$field; |
| expect($firstField).toBeFocused(); |
| }); |
| |
| it('FocusContext must remember the last focused element', function() { |
| var $secondField = form.rootGroupBox.fields[1].$field; |
| $secondField.focus(); |
| expect($secondField).toBeFocused(); |
| |
| expect(focusManager._findActiveContext().lastValidFocusedElement).toBe($secondField[0]); |
| }); |
| |
| it('A new FocusContext must be created when a form is opened as dialog', function() { |
| var $secondField = form.rootGroupBox.fields[1].$field; |
| $secondField.focus(); // must be remembered by focus-context |
| |
| var sandboxContext = focusManager._findActiveContext(); |
| expect(sandboxContext.$container).toBe(session.$entryPoint); |
| |
| var dialog = formHelper.createFormWithFields(session.desktop, true, 2); |
| dialog.render(); |
| |
| expect(focusManager._focusContexts.length).toBe(2); |
| |
| var dialogContext = focusManager._findActiveContext(); |
| expect(dialogContext.$container).toBe(dialog.$container); |
| |
| // focus-context must install handlers on form $container |
| expect(focusHelper.handlersRegistered(dialog.$container)).toBe(true); |
| |
| // must remember last focused field of first focus-context |
| expect(sandboxContext.lastValidFocusedElement).toBe($secondField[0]); |
| }); |
| |
| it('Must focus another valid field if the focused field is removed', function() { |
| var $firstField = form.rootGroupBox.fields[0].$field, |
| $secondField = form.rootGroupBox.fields[1].$field; |
| |
| expect($firstField).toBeFocused(); |
| $firstField.remove(); |
| expect($secondField).toBeFocused(); |
| }); |
| |
| it('Must focus another valid field if the focused field is hidden', function() { |
| var $firstField = form.rootGroupBox.fields[0].$field, |
| $secondField = form.rootGroupBox.fields[1].$field; |
| |
| expect($firstField).toBeFocused(); |
| $firstField.setVisible(false); |
| expect($secondField).toBeFocused(); |
| }); |
| |
| }); |
| |
| }); |
| |
| describe('activateFocusContext', function() { |
| |
| it('activates the context of the given $container and restores its focus', function() { |
| var $container1 = createDivWithTwoInputs().appendTo(session.$entryPoint); |
| var $container2 = createDivWithTwoInputs().appendTo(session.$entryPoint); |
| focusManager.installFocusContext($container1); |
| expect(document.activeElement).toBe($container1.children('.input1')[0]); |
| |
| focusManager.installFocusContext($container2); |
| focusManager.requestFocus($container2.children('.input2')); |
| expect(document.activeElement).toBe($container2.children('.input2')[0]); |
| |
| focusManager.activateFocusContext($container1); |
| expect(document.activeElement).toBe($container1.children('.input1')[0]); |
| |
| focusManager.activateFocusContext($container2); |
| expect(document.activeElement).toBe($container2.children('.input2')[0]); |
| |
| focusManager.uninstallFocusContext($container1); |
| focusManager.uninstallFocusContext($container2); |
| }); |
| |
| }); |
| |
| describe('requestFocus', function() { |
| it('focuses the given element', function() { |
| var $container1 = createDivWithTwoInputs().appendTo(session.$entryPoint); |
| focusManager.installFocusContext($container1); |
| |
| focusManager.requestFocus($container1.children('.input1')); |
| expect(document.activeElement).toBe($container1.children('.input1')[0]); |
| |
| focusManager.uninstallFocusContext($container1); |
| }); |
| |
| it('activates the context of the element if the element to focus is not in the active context', function() { |
| var $container1 = createDivWithTwoInputs().appendTo(session.$entryPoint); |
| var $container2 = createDivWithTwoInputs().appendTo(session.$entryPoint); |
| focusManager.installFocusContext($container1); |
| focusManager.installFocusContext($container2); |
| |
| focusManager.requestFocus($container1.children('.input1')); |
| expect(document.activeElement).toBe($container1.children('.input1')[0]); |
| expect(focusManager._findActiveContext().$container[0]).toBe($container1[0]); |
| |
| focusManager.requestFocus($container2.children('.input2')); |
| expect(document.activeElement).toBe($container2.children('.input2')[0]); |
| expect(focusManager._findActiveContext().$container[0]).toBe($container2[0]); |
| |
| focusManager.uninstallFocusContext($container1); |
| focusManager.uninstallFocusContext($container2); |
| }); |
| |
| it('does nothing if the element cannot be focused', function() { |
| var $container1 = createDivWithTwoInputs().appendTo(session.$entryPoint); |
| var $container2 = createDivWithTwoInputs().appendTo(session.$entryPoint); |
| focusManager.installFocusContext($container1); |
| focusManager.installFocusContext($container2); |
| |
| focusManager.requestFocus($container1.children('.input1')); |
| expect(document.activeElement).toBe($container1.children('.input1')[0]); |
| expect(focusManager._findActiveContext().$container[0]).toBe($container1[0]); |
| |
| // Container2 is covered by a glass pane -> requesting focus on a covered element should do nothing |
| var glassPane = scout.create('GlassPane', { |
| parent: session.desktop |
| }); |
| glassPane.render($container2); |
| focusManager.requestFocus($container2.children('.input2')); |
| expect(document.activeElement).toBe($container1.children('.input1')[0]); |
| expect(focusManager._findActiveContext().$container[0]).toBe($container1[0]); |
| |
| focusManager.uninstallFocusContext($container1); |
| focusManager.uninstallFocusContext($container2); |
| }); |
| |
| it('activates the correct context', function() { |
| var $input0 = session.$entryPoint.appendElement('<input type="text" class="input0">'); |
| var $container1 = createDivWithTwoInputs().appendTo(session.$entryPoint); |
| var $container2 = createDivWithTwoInputs().appendTo(session.$entryPoint); |
| focusManager.installFocusContext(session.$entryPoint); |
| focusManager.installFocusContext($container1); |
| focusManager.installFocusContext($container2); |
| |
| focusManager.requestFocus($input0); |
| expect(document.activeElement).toBe($input0[0]); |
| expect(focusManager._findActiveContext().$container[0]).toBe(session.$entryPoint[0]); |
| |
| focusManager.requestFocus($container1.children('.input1')); |
| expect(document.activeElement).toBe($container1.children('.input1')[0]); |
| expect(focusManager._findActiveContext().$container[0]).toBe($container1[0]); |
| |
| focusManager.requestFocus($container2.children('.input2')); |
| expect(document.activeElement).toBe($container2.children('.input2')[0]); |
| expect(focusManager._findActiveContext().$container[0]).toBe($container2[0]); |
| |
| focusManager.uninstallFocusContext(session.$entryPoint); |
| focusManager.uninstallFocusContext($container1); |
| focusManager.uninstallFocusContext($container2); |
| }); |
| }); |
| |
| describe('registerGlassPaneTarget', function() { |
| it('removes the focus if the active element will be covered by the glass pane', function() { |
| var $container1 = createDivWithTwoInputs().appendTo(session.$entryPoint); |
| focusManager.installFocusContext($container1); |
| |
| focusManager.requestFocus($container1.children('.input1')); |
| expect(document.activeElement).toBe($container1.children('.input1')[0]); |
| expect(focusManager._findActiveContext().$container[0]).toBe($container1[0]); |
| |
| // GlassPane will cover the active element -> blur it and focus desktop |
| var glassPane = scout.create('GlassPane', { |
| parent: session.desktop |
| }); |
| glassPane.render($container1); |
| expect(document.activeElement).toBe(session.$entryPoint[0]); |
| |
| // Destroy glass pane -> restore focus |
| glassPane.destroy(); |
| expect(document.activeElement).toBe($container1.children('.input1')[0]); |
| |
| focusManager.uninstallFocusContext($container1); |
| }); |
| }); |
| |
| describe('evaluateFocusRule', function() { |
| it('should find first focusable element', function() { |
| var $container = createDivWithTwoInputs().appendTo(session.$entryPoint); |
| focusManager.installFocusContext($container); |
| |
| expect(focusManager.evaluateFocusRule($container, FocusRule.NONE)).toBe(null); |
| expect(focusManager.evaluateFocusRule($container, FocusRule.AUTO)).toBe($container.children('.input1')[0]); |
| expect(focusManager.evaluateFocusRule($container, FocusRule.PREPARE)).toBe($container.children('.input1')[0]); |
| expect(focusManager.evaluateFocusRule($container, null)).toBe($container.children('.input1')[0]); |
| expect(focusManager.evaluateFocusRule($container, 'invalid-rule')).toBe('invalid-rule'); |
| expect(focusManager.evaluateFocusRule($container, $container.children('.input2')[0])).toBe($container.children('.input2')[0]); |
| }); |
| }); |
| }); |