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
|
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>MozButton Tests</title>
<script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
<script type="module" src="chrome://global/content/elements/moz-button.mjs"></script>
<link rel="stylesheet" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
<link rel="stylesheet" href="chrome://global/skin/design-system/tokens-brand.css">
<link rel="stylesheet" href="chrome://global/skin/design-system/text-and-typography.css">
<style>
.four::part(button),
.five::part(button),
.six::part(button) {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' width='16' height='16' fill='context-fill' fill-opacity='context-fill-opacity'%3E%3Cpath d='M3 7 1.5 7l-.5.5L1 9l.5.5 1.5 0 .5-.5 0-1.5z'/%3E%3Cpath d='m8.75 7-1.5 0-.5.5 0 1.5.5.5 1.5 0 .5-.5 0-1.5z'/%3E%3Cpath d='M14.5 7 13 7l-.5.5 0 1.5.5.5 1.5 0L15 9l0-1.5z'/%3E%3C/svg%3E");
}
</style>
<script>
function normalizeColor(val, computedStyles) {
if (val.includes("currentColor")) {
val = val.replaceAll("currentColor", computedStyles.color);
}
if (val.startsWith("light-dark")) {
let [, light, dark] = val.match(/light-dark\(([^,]+),\s*([^)]+)\)/);
if (light && dark) {
val = window.matchMedia("(prefers-color-scheme: dark)").matches ? dark : light;
}
}
try {
let { r, g, b, a } = InspectorUtils.colorToRGBA(val);
return `rgba(${r}, ${g}, ${b}, ${a})`;
} catch (e) {
info(val);
throw e;
}
}
function assertButtonPropertiesMatch(el, propertyToCssVar) {
let elStyles = getComputedStyle(el.buttonEl);
for (let [property, cssVar] of Object.entries(propertyToCssVar)) {
let propertyVal = elStyles[property];
let cssVarVal = cssVar.startsWith("--") ? elStyles.getPropertyValue(cssVar) : cssVar;
if (propertyVal.startsWith("rgb") || propertyVal.startsWith("#") || propertyVal.startsWith("color")) {
propertyVal = normalizeColor(propertyVal, elStyles);
cssVarVal = normalizeColor(cssVarVal, elStyles);
}
info(`${propertyVal} == ${cssVarVal}`);
is(propertyVal, cssVarVal, `${property} should be ${cssVar}`);
}
}
add_task(async function testButtonTypes() {
let [...buttons] = document.querySelectorAll("moz-button");
let [one, two, three, four, five, six] = buttons;
await Promise.all(buttons.map(btn => btn.updateComplete));
is(one.textContent, "Test button", "Text is set");
is(two.buttonEl.textContent.trim(), "Test button", "Text is set");
is(three.textContent, "Test button", "Text is set");
assertButtonPropertiesMatch(one, {
backgroundColor: "--button-background-color",
color: "--button-text-color",
height: "--button-min-height",
});
assertButtonPropertiesMatch(two, {
backgroundColor: "--button-background-color",
color: "--button-text-color",
height: "--button-min-height",
});
assertButtonPropertiesMatch(three, {
backgroundColor: "--button-background-color-primary",
color: "--button-text-color-primary",
height: "--button-min-height",
});
assertButtonPropertiesMatch(four, {
width: "--button-size-icon",
height: "--button-size-icon",
backgroundColor: "--button-background-color",
fill: "--icon-color",
});
assertButtonPropertiesMatch(five, {
width: "--button-size-icon",
height: "--button-size-icon",
backgroundColor: "transparent",
fill: "--icon-color",
});
assertButtonPropertiesMatch(six, {
width: "--button-size-icon",
height: "--button-size-icon",
backgroundColor: "transparent",
fill: "--icon-color",
});
buttons.forEach(btn => (btn.size = "small"));
await Promise.all(buttons.map(btn => btn.updateComplete));
assertButtonPropertiesMatch(one, {
height: "--button-min-height-small",
});
assertButtonPropertiesMatch(two, {
height: "--button-min-height-small",
});
assertButtonPropertiesMatch(three, {
height: "--button-min-height-small",
});
assertButtonPropertiesMatch(four, {
width: "--button-size-icon-small",
height: "--button-size-icon-small",
});
assertButtonPropertiesMatch(five, {
width: "--button-size-icon-small",
height: "--button-size-icon-small",
});
assertButtonPropertiesMatch(six, {
width: "--button-size-icon-small",
height: "--button-size-icon-small",
});
});
add_task(async function testA11yAttributes() {
let button = document.querySelector("moz-button");
async function testProperty(propName, jsPropName = propName) {
let propValue = `${propName} value`;
ok(!button.buttonEl.hasAttribute(propName), `No ${propName} on inner button`);
button.setAttribute(propName, propValue);
await button.updateComplete;
ok(!button.hasAttribute(propName), `moz-button ${propName} cleared`);
is(button.buttonEl.getAttribute(propName), propValue, `${propName} added to inner button`);
button[jsPropName] = null;
await button.updateComplete;
ok(!button.buttonEl.hasAttribute(propName), `${propName} cleared by setting property`);
}
await testProperty("title");
await testProperty("aria-label", "ariaLabel");
});
</script>
</head>
<body>
<moz-button class="one">Test button</moz-button>
<moz-button class="two" label="Test button"></moz-button>
<moz-button class="three" type="primary">Test button</moz-button>
<moz-button class="four" type="icon"></moz-button>
<moz-button class="five" type="icon ghost"></moz-button>
<moz-button class="six" type="ghost icon"></moz-button>
</body>
</html>
|