Automatic update from web-platform-tests Mark valid-custom-element-names.html slow Fixed: 455479521 Change-Id: I17cc6ea065456c3b49f51bc208193c797f8c8060 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7088533 Commit-Queue: Joey Arhar <jarhar@chromium.org> Auto-Submit: Mason Freed <masonf@chromium.org> Reviewed-by: Joey Arhar <jarhar@chromium.org> Cr-Commit-Position: refs/heads/main@{#1536807} -- wpt-commits: f7b427c97aa91a9a62d511ae569f2c2ba6839da1 wpt-pr: 55728
139 lines
3.8 KiB
HTML
139 lines
3.8 KiB
HTML
<!DOCTYPE html>
|
|
<meta name="timeout" content="long">
|
|
<link rel=author href="mailto:jarhar@chromium.org">
|
|
<link rel=help href="https://github.com/whatwg/html/pull/7991">
|
|
<script src="/resources/testharness.js"></script>
|
|
<script src="/resources/testharnessreport.js"></script>
|
|
|
|
<script>
|
|
function isAsciiLowerAlpha(codePoint) {
|
|
return codePoint >= 0x61 && codePoint <= 0x7A;
|
|
}
|
|
function isAsciiUpperAlpha(codePoint) {
|
|
return codePoint >= 0x41 && codePoint <= 0x5A;
|
|
}
|
|
function isAsciiAlpha(codePoint) {
|
|
return isAsciiLowerAlpha(codePoint) || isAsciiUpperAlpha(codePoint);
|
|
}
|
|
function isAsciiDigit(codePoint) {
|
|
return codePoint >= 0x30 && codePoint <= 0x39;
|
|
}
|
|
function isAsciiWhitespace(codePoint) {
|
|
return codePoint == 0x9 || codePoint == 0xA || codePoint == 0xC || codePoint == 0xD || codePoint == 0x20;
|
|
}
|
|
|
|
function debugString(str) {
|
|
const codePoints = [];
|
|
for (const c of str) {
|
|
codePoints.push(c.codePointAt(0));
|
|
}
|
|
return `code points: ${JSON.stringify(codePoints)}, string: "${str}"`;
|
|
}
|
|
|
|
const validCustomElementNames = [
|
|
'annotation-xml-custom',
|
|
];
|
|
const invalidCustomElementNames = [
|
|
'',
|
|
'annotation-xml',
|
|
'color-profile',
|
|
'font-face',
|
|
'font-face-src',
|
|
'font-face-uri',
|
|
'font-face-format',
|
|
'font-face-name',
|
|
'missing-glyph',
|
|
];
|
|
|
|
const testCodePoints = [0x1F171, 0x1F196, 0x10000];
|
|
for (let i = 0; i < 0x80; i++) {
|
|
testCodePoints.push(i);
|
|
}
|
|
|
|
const elementLocalNameRegex = /^(?:[A-Za-z][^\0\t\n\f\r\u0020/>]*|[:_\u0080-\u{10FFFF}][A-Za-z0-9-.:_\u0080-\u{10FFFF}]*)$/u;
|
|
|
|
function isValidCustomElementName(str) {
|
|
if (!str.length) {
|
|
return false;
|
|
}
|
|
|
|
if (!str.includes('-')) {
|
|
return false;
|
|
}
|
|
|
|
let first = true;
|
|
for (const c of str) {
|
|
const codePoint = c.codePointAt(0);
|
|
if (first) {
|
|
if (!isAsciiLowerAlpha(codePoint)) {
|
|
return false;
|
|
}
|
|
first = false;
|
|
}
|
|
if (isAsciiUpperAlpha(codePoint)) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return elementLocalNameRegex.test(str);
|
|
}
|
|
|
|
// In order to test the branching logic of valid element local names and the
|
|
// requirement of having a '-' character, this method generates different
|
|
// variations of potential custom element names given two code points.
|
|
function createStringWithSeparatorMode(codePoint, prefix, separatorMode) {
|
|
const str = String.fromCodePoint(codePoint);
|
|
if (separatorMode == 0) {
|
|
return `${prefix}${str}`;
|
|
} else if (separatorMode == 1) {
|
|
return `${prefix}-${str}`;
|
|
} else if (separatorMode == 2) {
|
|
return `${prefix}${str}-element`;
|
|
}
|
|
}
|
|
|
|
for (const prefix of ['', 'a', 'A', ' ', '\0']) {
|
|
for (const codePoint of testCodePoints) {
|
|
for (const separatorMode of [0, 1, 2]) {
|
|
const str = createStringWithSeparatorMode(
|
|
codePoint, prefix, separatorMode);
|
|
if (isValidCustomElementName(str)) {
|
|
validCustomElementNames.push(str);
|
|
} else {
|
|
invalidCustomElementNames.push(str);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
let nextClassNumber = 1;
|
|
function createElementClass() {
|
|
const name = `CustomElement${nextClassNumber++}`;
|
|
const newClass = function() {};
|
|
newClass.prototype = HTMLElement;
|
|
return newClass;
|
|
}
|
|
|
|
for (const validName of validCustomElementNames) {
|
|
promise_test(async t => {
|
|
const newClass = createElementClass();
|
|
customElements.define(validName, newClass);
|
|
await customElements.whenDefined(validName);
|
|
}, `Valid custom element name: ${debugString(validName)}`);
|
|
}
|
|
|
|
for (const invalidName of invalidCustomElementNames) {
|
|
promise_test(async t => {
|
|
const newClass = createElementClass();
|
|
assert_throws_dom(
|
|
'SyntaxError',
|
|
() => customElements.define(invalidName, newClass),
|
|
`customElements.define should have thrown`);
|
|
await promise_rejects_dom(t, 'SyntaxError',
|
|
customElements.whenDefined(invalidName),
|
|
`customElements.whenDefined should have thrown`);
|
|
}, `Invalid custom element name: ${debugString(invalidName)}`);
|
|
}
|
|
|
|
</script>
|