summaryrefslogtreecommitdiffstats
path: root/devtools/client/inspector/markup/test/browser_markup_tag_edit_12.js
blob: 64f9e9d57a1ac9ff187c054f94fb7d926fe9c04a (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
/* Any copyright is dedicated to the Public Domain.
 http://creativecommons.org/publicdomain/zero/1.0/ */

"use strict";

// Tests that focus position is correct when tabbing through and editing
// attributes.

const TEST_URL =
  "data:text/html;charset=utf8," +
  "<div id='attr' a='1' b='2' c='3'></div>" +
  "<div id='delattr' tobeinvalid='1' last='2'></div>";

add_task(async function () {
  const { inspector } = await openInspectorForURL(TEST_URL);

  await testAttributeEditing(inspector);
  await testAttributeDeletion(inspector);
});

async function testAttributeEditing(inspector) {
  info("Testing focus position after attribute editing");

  info("Setting the first non-id attribute in edit mode");
  // focuses id
  await activateFirstAttribute("#attr", inspector);
  // focuses the first attr after id
  collapseSelectionAndTab(inspector);

  const attrs = await getAttributesFromEditor("#attr", inspector);

  info(
    "Editing this attribute, keeping the same name, " +
      "and tabbing to the next"
  );
  await editAttributeAndTab(attrs[1] + '="99"', inspector);
  checkFocusedAttribute(attrs[2], true);

  info(
    "Editing the new focused attribute, keeping the name, " +
      "and tabbing to the previous"
  );
  await editAttributeAndTab(attrs[2] + '="99"', inspector, true);
  checkFocusedAttribute(attrs[1], true);

  info("Editing attribute name, changes attribute order");
  await editAttributeAndTab("d='4'", inspector);
  checkFocusedAttribute("id", true);

  // Escape of the currently focused field for the next test
  EventUtils.sendKey("escape", inspector.panelWin);
}

async function testAttributeDeletion(inspector) {
  info("Testing focus position after attribute deletion");

  info("Setting the first non-id attribute in edit mode");
  // focuses id
  await activateFirstAttribute("#delattr", inspector);
  // focuses the first attr after id
  collapseSelectionAndTab(inspector);

  const attrs = await getAttributesFromEditor("#delattr", inspector);

  info("Entering an invalid attribute to delete the attribute");
  await editAttributeAndTab('"', inspector);
  checkFocusedAttribute(attrs[2], true);

  info("Deleting the last attribute");
  await editAttributeAndTab(" ", inspector);

  // Check we're on the newattr element
  const focusedAttr = Services.focus.focusedElement;
  ok(
    focusedAttr.classList.contains("styleinspector-propertyeditor"),
    "in newattr"
  );
  is(focusedAttr.tagName, "textarea", "newattr is active");
}

async function editAttributeAndTab(newValue, inspector, goPrevious) {
  const onEditMutation = inspector.markup.once("refocusedonedit");
  inspector.markup.doc.activeElement.value = newValue;
  if (goPrevious) {
    EventUtils.synthesizeKey("VK_TAB", { shiftKey: true }, inspector.panelWin);
  } else {
    EventUtils.sendKey("tab", inspector.panelWin);
  }
  await onEditMutation;
}

/**
 * Given a markup container, focus and turn in edit mode its first attribute
 * field.
 */
async function activateFirstAttribute(container, inspector) {
  const { editor } = await focusNode(container, inspector);
  editor.tag.focus();

  // Go to "id" attribute and trigger edit mode.
  EventUtils.sendKey("tab", inspector.panelWin);
  EventUtils.sendKey("return", inspector.panelWin);
}