summaryrefslogtreecommitdiffstats
path: root/devtools/client/inspector/shared/test/browser_styleinspector_context-menu-copy-color_01.js
blob: 5a27edf165d2a27b3b7225443cac2b742b84ee69 (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
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
 http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";

// Test "Copy color" item of the context menu #1: Test _isColorPopup.

const TEST_URI = `
  <div style="color:rgb(18, 58, 188);margin:0px;background:span[data-color];">
    Test "Copy color" context menu option
  </div>
`;

add_task(function* () {
  // Test is slow on Linux EC2 instances - Bug 1137765
  requestLongerTimeout(2);
  yield addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
  let {inspector} = yield openInspector();
  yield testView("ruleview", inspector);
  yield testView("computedview", inspector);
});

function* testView(viewId, inspector) {
  info("Testing " + viewId);

  yield inspector.sidebar.select(viewId);
  let view = inspector[viewId].view || inspector[viewId].computedView;
  yield selectNode("div", inspector);

  testIsColorValueNode(view);
  testIsColorPopupOnAllNodes(view);
  yield clearCurrentNodeSelection(inspector);
}

/**
 * A function testing that isColorValueNode correctly detects nodes part of
 * color values.
 */
function testIsColorValueNode(view) {
  info("Testing that child nodes of color nodes are detected.");
  let root = rootElement(view);
  let colorNode = root.querySelector("span[data-color]");

  ok(colorNode, "Color node found");
  for (let node of iterateNodes(colorNode)) {
    ok(isColorValueNode(node), "Node is part of color value.");
  }
}

/**
 * A function testing that _isColorPopup returns a correct value for all nodes
 * in the view.
 */
function testIsColorPopupOnAllNodes(view) {
  let root = rootElement(view);
  for (let node of iterateNodes(root)) {
    testIsColorPopupOnNode(view, node);
  }
}

/**
 * Test result of _isColorPopup with given node.
 * @param object view
 *               A CSSRuleView or CssComputedView instance.
 * @param Node node
 *             A node to check.
 */
function testIsColorPopupOnNode(view, node) {
  info("Testing node " + node);
  view.styleDocument.popupNode = node;
  view._contextmenu._colorToCopy = "";

  let result = view._contextmenu._isColorPopup();
  let correct = isColorValueNode(node);

  is(result, correct, "_isColorPopup returned the expected value " + correct);
  is(view._contextmenu._colorToCopy, (correct) ? "rgb(18, 58, 188)" : "",
     "_colorToCopy was set to the expected value");
}

/**
 * Check if a node is part of color value i.e. it has parent with a 'data-color'
 * attribute.
 */
function isColorValueNode(node) {
  let container = (node.nodeType == node.TEXT_NODE) ?
                   node.parentElement : node;

  let isColorNode = el => el.dataset && "color" in el.dataset;

  while (!isColorNode(container)) {
    container = container.parentNode;
    if (!container) {
      info("No color. Node is not part of color value.");
      return false;
    }
  }

  info("Found a color. Node is part of color value.");

  return true;
}

/**
 * A generator that iterates recursively trough all child nodes of baseNode.
 */
function* iterateNodes(baseNode) {
  yield baseNode;

  for (let child of baseNode.childNodes) {
    yield* iterateNodes(child);
  }
}

/**
 * Returns the root element for the given view, rule or computed.
 */
var rootElement = view => (view.element) ? view.element : view.styleDocument;