summaryrefslogtreecommitdiffstats
path: root/browser/components/customizableui/test/browser_PanelMultiView_focus.js
blob: a7786734ba6c37870b91bf6d2d116ed2ec54c5af (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
/* Any copyright is dedicated to the Public Domain.
 * http://creativecommons.org/publicdomain/zero/1.0/ */

"use strict";

/**
 * Test the focus behavior when opening PanelViews.
 */

const { PanelMultiView } = ChromeUtils.import(
  "resource:///modules/PanelMultiView.jsm"
);

let gAnchor;
let gPanel;
let gPanelMultiView;
let gMainView;
let gMainButton;
let gMainSubButton;
let gSubView;
let gSubButton;

function createWith(doc, tag, props) {
  let el = doc.createXULElement(tag);
  for (let prop in props) {
    el.setAttribute(prop, props[prop]);
  }
  return el;
}

add_setup(async function() {
  let navBar = document.getElementById("nav-bar");
  gAnchor = document.createXULElement("toolbarbutton");
  // Must be focusable in order for key presses to work.
  gAnchor.style["-moz-user-focus"] = "normal";
  navBar.appendChild(gAnchor);
  let onPress = event =>
    PanelMultiView.openPopup(gPanel, gAnchor, {
      triggerEvent: event,
    });
  gAnchor.addEventListener("keypress", onPress);
  gAnchor.addEventListener("click", onPress);
  gPanel = document.createXULElement("panel");
  navBar.appendChild(gPanel);
  gPanelMultiView = document.createXULElement("panelmultiview");
  gPanelMultiView.setAttribute("mainViewId", "testMainView");
  gPanel.appendChild(gPanelMultiView);

  gMainView = document.createXULElement("panelview");
  gMainView.id = "testMainView";
  gPanelMultiView.appendChild(gMainView);
  gMainButton = createWith(document, "button", { label: "gMainButton" });
  gMainView.appendChild(gMainButton);
  gMainSubButton = createWith(document, "button", { label: "gMainSubButton" });
  gMainView.appendChild(gMainSubButton);
  gMainSubButton.addEventListener("command", () =>
    gPanelMultiView.showSubView("testSubView", gMainSubButton)
  );

  gSubView = document.createXULElement("panelview");
  gSubView.id = "testSubView";
  gPanelMultiView.appendChild(gSubView);
  gSubButton = createWith(document, "button", { label: "gSubButton" });
  gSubView.appendChild(gSubButton);

  registerCleanupFunction(() => {
    gAnchor.remove();
    gPanel.remove();
  });
});

// Activate the main view by pressing a key. Focus should be moved inside.
add_task(async function testMainViewByKeypress() {
  gAnchor.focus();
  await gCUITestUtils.openPanelMultiView(gPanel, gMainView, () =>
    EventUtils.synthesizeKey(" ")
  );
  Assert.equal(
    document.activeElement,
    gMainButton,
    "Focus on button in main view"
  );
  await gCUITestUtils.hidePanelMultiView(gPanel, () =>
    PanelMultiView.hidePopup(gPanel)
  );
});

// Activate the main view by clicking the mouse. Focus should not be moved
// inside.
add_task(async function testMainViewByClick() {
  await gCUITestUtils.openPanelMultiView(gPanel, gMainView, () =>
    gAnchor.click()
  );
  Assert.notEqual(
    document.activeElement,
    gMainButton,
    "Focus not on button in main view"
  );
  await gCUITestUtils.hidePanelMultiView(gPanel, () =>
    PanelMultiView.hidePopup(gPanel)
  );
});

// Activate the subview by pressing a key. Focus should be moved to the first
// button after the Back button.
add_task(async function testSubViewByKeypress() {
  await gCUITestUtils.openPanelMultiView(gPanel, gMainView, () =>
    gAnchor.click()
  );
  while (document.activeElement != gMainSubButton) {
    EventUtils.synthesizeKey("KEY_Tab", { shiftKey: true });
  }
  let shown = BrowserTestUtils.waitForEvent(gSubView, "ViewShown");
  EventUtils.synthesizeKey(" ");
  await shown;
  Assert.equal(
    document.activeElement,
    gSubButton,
    "Focus on first button after Back button in subview"
  );
  await gCUITestUtils.hidePanelMultiView(gPanel, () =>
    PanelMultiView.hidePopup(gPanel)
  );
});

// Activate the subview by clicking the mouse. Focus should not be moved
// inside.
add_task(async function testSubViewByClick() {
  await gCUITestUtils.openPanelMultiView(gPanel, gMainView, () =>
    gAnchor.click()
  );
  let shown = BrowserTestUtils.waitForEvent(gSubView, "ViewShown");
  gMainSubButton.click();
  await shown;
  let backButton = gSubView.querySelector(".subviewbutton-back");
  Assert.notEqual(
    document.activeElement,
    backButton,
    "Focus not on Back button in subview"
  );
  Assert.notEqual(
    document.activeElement,
    gSubButton,
    "Focus not on button after Back button in subview"
  );
  await gCUITestUtils.hidePanelMultiView(gPanel, () =>
    PanelMultiView.hidePopup(gPanel)
  );
});

// Test that focus is restored when going back to a previous view.
add_task(async function testBackRestoresFocus() {
  await gCUITestUtils.openPanelMultiView(gPanel, gMainView, () =>
    gAnchor.click()
  );
  while (document.activeElement != gMainSubButton) {
    EventUtils.synthesizeKey("KEY_Tab", { shiftKey: true });
  }
  let shown = BrowserTestUtils.waitForEvent(gSubView, "ViewShown");
  EventUtils.synthesizeKey(" ");
  await shown;
  shown = BrowserTestUtils.waitForEvent(gMainView, "ViewShown");
  EventUtils.synthesizeKey("KEY_ArrowLeft");
  await shown;
  Assert.equal(
    document.activeElement,
    gMainSubButton,
    "Focus on sub button in main view"
  );
  await gCUITestUtils.hidePanelMultiView(gPanel, () =>
    PanelMultiView.hidePopup(gPanel)
  );
});