summaryrefslogtreecommitdiffstats
path: root/devtools/client/shared/test/browser_html_tooltip-03.js
blob: 6c189c1272f662313b3873495659f582227164f3 (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
/* Any copyright is dedicated to the Public Domain.
   http://creativecommons.org/publicdomain/zero/1.0/ */
/* import-globals-from helper_html_tooltip.js */

"use strict";

/**
 * Test the HTMLTooltip autofocus configuration option.
 */

const HTML_NS = "http://www.w3.org/1999/xhtml";
const TEST_URI = `data:text/xml;charset=UTF-8,<?xml version="1.0"?>
  <?xml-stylesheet href="chrome://global/skin/global.css"?>
  <?xml-stylesheet href="chrome://devtools/skin/tooltips.css"?>
  <window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
   title="Tooltip test">
    <vbox flex="1">
      <hbox id="box1" flex="1">
        <textbox></textbox>
      </hbox>
      <hbox id="box2" flex="1">test2</hbox>
      <hbox id="box3" flex="1">
        <textbox id="box3-input"></textbox>
      </hbox>
      <hbox id="box4" flex="1">
        <textbox id="box4-input"></textbox>
      </hbox>
    </vbox>
  </window>`;

const {HTMLTooltip} = require("devtools/client/shared/widgets/tooltip/HTMLTooltip");
loadHelperScript("helper_html_tooltip.js");

let useXulWrapper;

add_task(function* () {
  yield addTab("about:blank");
  let [, , doc] = yield createHost("bottom", TEST_URI);

  info("Run tests for a Tooltip without using a XUL panel");
  useXulWrapper = false;
  yield runTests(doc);

  info("Run tests for a Tooltip with a XUL panel");
  useXulWrapper = true;
  yield runTests(doc);
});

function* runTests(doc) {
  yield testNoAutoFocus(doc);
  yield testAutoFocus(doc);
  yield testAutoFocusPreservesFocusChange(doc);
}

function* testNoAutoFocus(doc) {
  yield focusNode(doc, "#box4-input");
  ok(doc.activeElement.closest("#box4-input"), "Focus is in the #box4-input");

  info("Test a tooltip without autofocus will not take focus");
  let tooltip = yield createTooltip(doc, false);

  yield showTooltip(tooltip, doc.getElementById("box1"));
  ok(doc.activeElement.closest("#box4-input"), "Focus is still in the #box4-input");

  yield hideTooltip(tooltip);
  yield blurNode(doc, "#box4-input");

  tooltip.destroy();
}

function* testAutoFocus(doc) {
  yield focusNode(doc, "#box4-input");
  ok(doc.activeElement.closest("#box4-input"), "Focus is in the #box4-input");

  info("Test autofocus tooltip takes focus when displayed, " +
    "and restores the focus when hidden");
  let tooltip = yield createTooltip(doc, true);

  yield showTooltip(tooltip, doc.getElementById("box1"));
  ok(doc.activeElement.closest(".tooltip-content"), "Focus is in the tooltip");

  yield hideTooltip(tooltip);
  ok(doc.activeElement.closest("#box4-input"), "Focus is in the #box4-input");

  info("Blur the textbox before moving to the next test to reset the state.");
  yield blurNode(doc, "#box4-input");

  tooltip.destroy();
}

function* testAutoFocusPreservesFocusChange(doc) {
  yield focusNode(doc, "#box4-input");
  ok(doc.activeElement.closest("#box4-input"), "Focus is still in the #box3-input");

  info("Test autofocus tooltip takes focus when displayed, " +
    "but does not try to restore the active element if it is not focused when hidden");
  let tooltip = yield createTooltip(doc, true);

  yield showTooltip(tooltip, doc.getElementById("box1"));
  ok(doc.activeElement.closest(".tooltip-content"), "Focus is in the tooltip");

  info("Move the focus to #box3-input while the tooltip is displayed");
  yield focusNode(doc, "#box3-input");
  ok(doc.activeElement.closest("#box3-input"), "Focus moved to the #box3-input");

  yield hideTooltip(tooltip);
  ok(doc.activeElement.closest("#box3-input"), "Focus is still in the #box3-input");

  info("Blur the textbox before moving to the next test to reset the state.");
  yield blurNode(doc, "#box3-input");

  tooltip.destroy();
}

/**
 * Fpcus the node corresponding to the provided selector in the provided document. Returns
 * a promise that will resolve when receiving the focus event on the node.
 */
function focusNode(doc, selector) {
  let node = doc.querySelector(selector);
  let onFocus = once(node, "focus");
  node.focus();
  return onFocus;
}

/**
 * Blur the node corresponding to the provided selector in the provided document. Returns
 * a promise that will resolve when receiving the blur event on the node.
 */
function blurNode(doc, selector) {
  let node = doc.querySelector(selector);
  let onBlur = once(node, "blur");
  node.blur();
  return onBlur;
}

/**
 * Create an HTMLTooltip instance with the provided autofocus setting.
 *
 * @param {Document} doc
 *        Document in which the tooltip should be created
 * @param {Boolean} autofocus
 * @return {Promise} promise that will resolve the HTMLTooltip instance created when the
 *         tooltip content will be ready.
 */
function* createTooltip(doc, autofocus) {
  let tooltip = new HTMLTooltip(doc, {autofocus, useXulWrapper});
  let div = doc.createElementNS(HTML_NS, "div");
  div.classList.add("tooltip-content");
  div.style.height = "50px";
  div.innerHTML = '<input type="text"></input>';

  tooltip.setContent(div, {width: 150, height: 50});
  return tooltip;
}