mirror of
https://github.com/servo/servo.git
synced 2025-08-16 02:45:36 +01:00
Update web-platform-tests to revision bc60e6f82132cfc9a5b688c566c7772024b3c15c
This commit is contained in:
parent
449881f566
commit
29156ca9e2
223 changed files with 7517 additions and 2093 deletions
|
@ -222,6 +222,7 @@ tasks:
|
|||
script: >-
|
||||
export TOXENV=py27;
|
||||
export HYPOTHESIS_PROFILE=ci;
|
||||
export PY_COLORS=0;
|
||||
./tools/ci/run_tc.py \
|
||||
tools_unittest \
|
||||
tools/ci/ci_tools_unittest.sh
|
||||
|
@ -234,6 +235,7 @@ tasks:
|
|||
script: >-
|
||||
export TOXENV=py36;
|
||||
export HYPOTHESIS_PROFILE=ci;
|
||||
export PY_COLORS=0;
|
||||
sudo apt update -qqy;
|
||||
sudo apt install -qqy python3-pip;
|
||||
./tools/ci/run_tc.py \
|
||||
|
|
320
tests/wpt/web-platform-tests/IndexedDB/structured-clone.any.js
Normal file
320
tests/wpt/web-platform-tests/IndexedDB/structured-clone.any.js
Normal file
|
@ -0,0 +1,320 @@
|
|||
// META: script=support-promises.js
|
||||
// META: title=Indexed DB and Structured Serializing/Deserializing
|
||||
// META: timeout=long
|
||||
|
||||
// Tests Indexed DB coverage of HTML's Safe "passing of structured data"
|
||||
// https://html.spec.whatwg.org/multipage/structured-data.html
|
||||
|
||||
function describe(value) {
|
||||
let type, str;
|
||||
if (typeof value === 'object' && value) {
|
||||
type = value.__proto__.constructor.name;
|
||||
// Handle Number(-0), etc.
|
||||
str = Object.is(value.valueOf(), -0) ? '-0' : String(value);
|
||||
} else {
|
||||
type = typeof value;
|
||||
// Handle primitive -0.
|
||||
str = Object.is(value, -0) ? '-0' : String(value);
|
||||
}
|
||||
return `${type}: ${str}`;
|
||||
}
|
||||
|
||||
function cloneTest(value, verifyFunc) {
|
||||
promise_test(async t => {
|
||||
const db = await createDatabase(t, db => {
|
||||
const store = db.createObjectStore('store');
|
||||
// This index is not used, but evaluating key path on each put()
|
||||
// call will exercise (de)serialization.
|
||||
store.createIndex('index', 'dummyKeyPath');
|
||||
});
|
||||
t.add_cleanup(() => {
|
||||
if (db) {
|
||||
db.close();
|
||||
indexedDB.deleteDatabase(db.name);
|
||||
}
|
||||
});
|
||||
const tx = db.transaction('store', 'readwrite');
|
||||
const store = tx.objectStore('store');
|
||||
await promiseForRequest(t, store.put(value, 'key'));
|
||||
const result = await promiseForRequest(t, store.get('key'));
|
||||
await verifyFunc(value, result);
|
||||
await promiseForTransaction(t, tx);
|
||||
}, describe(value));
|
||||
}
|
||||
|
||||
// Specialization of cloneTest() for objects, with common asserts.
|
||||
function cloneObjectTest(value, verifyFunc) {
|
||||
cloneTest(value, async (orig, clone) => {
|
||||
assert_not_equals(orig, clone);
|
||||
assert_equals(typeof clone, 'object');
|
||||
assert_equals(orig.__proto__, clone.__proto__);
|
||||
await verifyFunc(orig, clone);
|
||||
});
|
||||
}
|
||||
|
||||
function cloneFailureTest(value) {
|
||||
promise_test(async t => {
|
||||
const db = await createDatabase(t, db => {
|
||||
db.createObjectStore('store');
|
||||
});
|
||||
t.add_cleanup(() => {
|
||||
if (db) {
|
||||
db.close();
|
||||
indexedDB.deleteDatabase(db.name);
|
||||
}
|
||||
});
|
||||
const tx = db.transaction('store', 'readwrite');
|
||||
const store = tx.objectStore('store');
|
||||
assert_throws('DataCloneError', () => store.put(value, 'key'));
|
||||
}, 'Not serializable: ' + describe(value));
|
||||
}
|
||||
|
||||
//
|
||||
// ECMAScript types
|
||||
//
|
||||
|
||||
// Primitive values: Undefined, Null, Boolean, Number, BigInt, String
|
||||
const booleans = [false, true];
|
||||
const numbers = [
|
||||
NaN,
|
||||
-Infinity,
|
||||
-Number.MAX_VALUE,
|
||||
-0xffffffff,
|
||||
-0x80000000,
|
||||
-0x7fffffff,
|
||||
-1,
|
||||
-Number.MIN_VALUE,
|
||||
-0,
|
||||
0,
|
||||
1,
|
||||
Number.MIN_VALUE,
|
||||
0x7fffffff,
|
||||
0x80000000,
|
||||
0xffffffff,
|
||||
Number.MAX_VALUE,
|
||||
Infinity,
|
||||
];
|
||||
const bigints = [
|
||||
-12345678901234567890n,
|
||||
-1n,
|
||||
0n,
|
||||
1n,
|
||||
12345678901234567890n,
|
||||
];
|
||||
const strings = [
|
||||
'',
|
||||
'this is a sample string',
|
||||
'null(\0)',
|
||||
];
|
||||
|
||||
[undefined, null].concat(booleans, numbers, bigints, strings)
|
||||
.forEach(value => cloneTest(value, (orig, clone) => {
|
||||
assert_equals(orig, clone);
|
||||
}));
|
||||
|
||||
// "Primitive" Objects (Boolean, Number, BigInt, String)
|
||||
[].concat(booleans, numbers, strings)
|
||||
.forEach(value => cloneObjectTest(Object(value), (orig, clone) => {
|
||||
assert_equals(orig.valueOf(), clone.valueOf());
|
||||
}));
|
||||
|
||||
// Dates
|
||||
[
|
||||
new Date(-1e13),
|
||||
new Date(-1e12),
|
||||
new Date(-1e9),
|
||||
new Date(-1e6),
|
||||
new Date(-1e3),
|
||||
new Date(0),
|
||||
new Date(1e3),
|
||||
new Date(1e6),
|
||||
new Date(1e9),
|
||||
new Date(1e12),
|
||||
new Date(1e13)
|
||||
].forEach(value => cloneTest(value, (orig, clone) => {
|
||||
assert_not_equals(orig, clone);
|
||||
assert_equals(typeof clone, 'object');
|
||||
assert_equals(orig.__proto__, clone.__proto__);
|
||||
assert_equals(orig.valueOf(), clone.valueOf());
|
||||
}));
|
||||
|
||||
// Regular Expressions
|
||||
[
|
||||
new RegExp(),
|
||||
/abc/,
|
||||
/abc/g,
|
||||
/abc/i,
|
||||
/abc/gi,
|
||||
/abc/m,
|
||||
/abc/mg,
|
||||
/abc/mi,
|
||||
/abc/mgi,
|
||||
/abc/gimsuy,
|
||||
].forEach(value => cloneObjectTest(value, (orig, clone) => {
|
||||
assert_equals(orig.toString(), clone.toString());
|
||||
}));
|
||||
|
||||
// ArrayBuffer
|
||||
cloneObjectTest(new Uint8Array([0, 1, 254, 255]).buffer, (orig, clone) => {
|
||||
assert_array_equals(new Uint8Array(orig), new Uint8Array(clone));
|
||||
});
|
||||
|
||||
// TODO SharedArrayBuffer
|
||||
|
||||
// Array Buffer Views
|
||||
[
|
||||
new Uint8Array([]),
|
||||
new Uint8Array([0, 1, 254, 255]),
|
||||
new Uint16Array([0x0000, 0x0001, 0xFFFE, 0xFFFF]),
|
||||
new Uint32Array([0x00000000, 0x00000001, 0xFFFFFFFE, 0xFFFFFFFF]),
|
||||
new Int8Array([0, 1, 254, 255]),
|
||||
new Int16Array([0x0000, 0x0001, 0xFFFE, 0xFFFF]),
|
||||
new Int32Array([0x00000000, 0x00000001, 0xFFFFFFFE, 0xFFFFFFFF]),
|
||||
new Uint8ClampedArray([0, 1, 254, 255]),
|
||||
new Float32Array([-Infinity, -1.5, -1, -0.5, 0, 0.5, 1, 1.5, Infinity, NaN]),
|
||||
new Float64Array([-Infinity, -Number.MAX_VALUE, -Number.MIN_VALUE, 0,
|
||||
Number.MIN_VALUE, Number.MAX_VALUE, Infinity, NaN])
|
||||
].forEach(value => cloneObjectTest(value, (orig, clone) => {
|
||||
assert_array_equals(orig, clone);
|
||||
}));
|
||||
|
||||
// Map
|
||||
cloneObjectTest(new Map([[1,2],[3,4]]), (orig, clone) => {
|
||||
assert_array_equals([...orig.keys()], [...clone.keys()]);
|
||||
assert_array_equals([...orig.values()], [...clone.values()]);
|
||||
});
|
||||
|
||||
// Set
|
||||
cloneObjectTest(new Set([1,2,3,4]), (orig, clone) => {
|
||||
assert_array_equals([...orig.values()], [...clone.values()]);
|
||||
});
|
||||
|
||||
// Error
|
||||
[
|
||||
new Error(),
|
||||
new Error('abc', 'def'),
|
||||
new EvalError(),
|
||||
new EvalError('ghi', 'jkl'),
|
||||
new RangeError(),
|
||||
new RangeError('ghi', 'jkl'),
|
||||
new ReferenceError(),
|
||||
new ReferenceError('ghi', 'jkl'),
|
||||
new SyntaxError(),
|
||||
new SyntaxError('ghi', 'jkl'),
|
||||
new TypeError(),
|
||||
new TypeError('ghi', 'jkl'),
|
||||
new URIError(),
|
||||
new URIError('ghi', 'jkl'),
|
||||
].forEach(value => cloneObjectTest(value, (orig, clone) => {
|
||||
assert_equals(orig.name, clone.name);
|
||||
assert_equals(orig.message, clone.message);
|
||||
}));
|
||||
|
||||
// Arrays
|
||||
[
|
||||
[],
|
||||
[1,2,3],
|
||||
Object.assign(
|
||||
['foo', 'bar'],
|
||||
{10: true, 11: false, 20: 123, 21: 456, 30: null}),
|
||||
Object.assign(
|
||||
['foo', 'bar'],
|
||||
{a: true, b: false, foo: 123, bar: 456, '': null}),
|
||||
].forEach(value => cloneObjectTest(value, (orig, clone) => {
|
||||
assert_array_equals(orig, clone);
|
||||
assert_array_equals(Object.keys(orig), Object.keys(clone));
|
||||
Object.keys(orig).forEach(key => {
|
||||
assert_equals(orig[key], clone[key], `Property ${key}`);
|
||||
});
|
||||
}));
|
||||
|
||||
// Objects
|
||||
cloneObjectTest({foo: true, bar: false}, (orig, clone) => {
|
||||
assert_array_equals(Object.keys(orig), Object.keys(clone));
|
||||
Object.keys(orig).forEach(key => {
|
||||
assert_equals(orig[key], clone[key], `Property ${key}`);
|
||||
});
|
||||
});
|
||||
|
||||
//
|
||||
// [Serializable] Platform objects
|
||||
//
|
||||
|
||||
// TODO: Test these additional interfaces:
|
||||
// * DOMQuad
|
||||
// * DOMException
|
||||
// * DetectedText, DetectedFace, DetectedBarcode
|
||||
// * RTCCertificate
|
||||
|
||||
// Geometry types
|
||||
[
|
||||
new DOMMatrix(),
|
||||
new DOMMatrixReadOnly(),
|
||||
new DOMPoint(),
|
||||
new DOMPointReadOnly(),
|
||||
new DOMRect,
|
||||
new DOMRectReadOnly(),
|
||||
].forEach(value => cloneObjectTest(value, (orig, clone) => {
|
||||
Object.keys(orig.__proto__).forEach(key => {
|
||||
assert_equals(orig[key], clone[key], `Property ${key}`);
|
||||
});
|
||||
}));
|
||||
|
||||
// ImageData
|
||||
const image_data = new ImageData(8, 8);
|
||||
for (let i = 0; i < 256; ++i) {
|
||||
image_data.data[i] = i;
|
||||
}
|
||||
cloneObjectTest(image_data, (orig, clone) => {
|
||||
assert_equals(orig.width, clone.width);
|
||||
assert_equals(orig.height, clone.height);
|
||||
assert_array_equals(orig.data, clone.data);
|
||||
});
|
||||
|
||||
// Blob
|
||||
cloneObjectTest(
|
||||
new Blob(['This is a test.'], {type: 'a/b'}),
|
||||
async (orig, clone) => {
|
||||
assert_equals(orig.size, clone.size);
|
||||
assert_equals(orig.type, clone.type);
|
||||
assert_equals(await orig.text(), await clone.text());
|
||||
});
|
||||
|
||||
// File
|
||||
cloneObjectTest(
|
||||
new File(['This is a test.'], 'foo.txt', {type: 'c/d'}),
|
||||
async (orig, clone) => {
|
||||
assert_equals(orig.size, clone.size);
|
||||
assert_equals(orig.type, clone.type);
|
||||
assert_equals(orig.name, clone.name);
|
||||
assert_equals(orig.lastModified, clone.lastModified);
|
||||
assert_equals(String(orig.lastModifiedDate),
|
||||
String(clone.lastModifiedDate));
|
||||
assert_equals(await orig.text(), await clone.text());
|
||||
});
|
||||
|
||||
|
||||
// FileList - exposed in Workers, but not constructable.
|
||||
if ('document' in self) {
|
||||
// TODO: Test with populated list.
|
||||
cloneObjectTest(
|
||||
Object.assign(document.createElement('input'),
|
||||
{type: 'file', multiple: true}).files,
|
||||
async (orig, clone) => {
|
||||
assert_equals(orig.length, clone.length);
|
||||
});
|
||||
}
|
||||
|
||||
//
|
||||
// Non-serializable types
|
||||
//
|
||||
[
|
||||
// ECMAScript types
|
||||
function() {},
|
||||
Symbol('desc'),
|
||||
|
||||
// Non-[Serializable] platform objects
|
||||
self,
|
||||
new Event(''),
|
||||
new MessageChannel()
|
||||
].forEach(cloneFailureTest);
|
|
@ -0,0 +1,20 @@
|
|||
import collections
|
||||
import json
|
||||
import os
|
||||
|
||||
|
||||
def main():
|
||||
'''Formats spec.src.json.'''
|
||||
script_directory = os.path.dirname(os.path.abspath(__file__))
|
||||
for dir in ['mixed-content', 'referrer-policy']:
|
||||
filename = os.path.join(script_directory, '..', '..', '..', dir,
|
||||
'spec.src.json')
|
||||
spec = json.load(
|
||||
open(filename, 'r'), object_pairs_hook=collections.OrderedDict)
|
||||
with open(filename, 'w') as f:
|
||||
f.write(json.dumps(spec, indent=2, separators=(',', ': ')))
|
||||
f.write('\n')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
|
@ -28,7 +28,10 @@ def expand_pattern(expansion_pattern, test_expansion_schema):
|
|||
return expansion
|
||||
|
||||
|
||||
def permute_expansion(expansion, artifact_order, selection = {}, artifact_index = 0):
|
||||
def permute_expansion(expansion,
|
||||
artifact_order,
|
||||
selection={},
|
||||
artifact_index=0):
|
||||
assert isinstance(artifact_order, list), "artifact_order should be a list"
|
||||
|
||||
if artifact_index >= len(artifact_order):
|
||||
|
@ -39,20 +42,23 @@ def permute_expansion(expansion, artifact_order, selection = {}, artifact_index
|
|||
|
||||
for artifact_value in expansion[artifact_key]:
|
||||
selection[artifact_key] = artifact_value
|
||||
for next_selection in permute_expansion(expansion,
|
||||
artifact_order,
|
||||
selection,
|
||||
artifact_index + 1):
|
||||
for next_selection in permute_expansion(expansion, artifact_order,
|
||||
selection, artifact_index + 1):
|
||||
yield next_selection
|
||||
|
||||
|
||||
def generate_selection(config, selection, spec, test_html_template_basename):
|
||||
# TODO: Refactor out this referrer-policy-specific part.
|
||||
if 'referrer_policy' in spec:
|
||||
# Oddball: it can be None, so in JS it's null.
|
||||
selection['referrer_policy'] = spec['referrer_policy']
|
||||
# Dumps the test config `selection` into a serialized JSON string.
|
||||
# We omit `name` parameter because it is not used by tests.
|
||||
def dump_test_parameters(selection):
|
||||
selection = dict(selection)
|
||||
del selection['name']
|
||||
|
||||
test_parameters = json.dumps(selection, indent=2, separators=(',', ':'))
|
||||
return json.dumps(
|
||||
selection, indent=2, separators=(',', ': '), sort_keys=True)
|
||||
|
||||
|
||||
def generate_selection(config, selection, spec, test_html_template_basename):
|
||||
test_parameters = dump_test_parameters(selection)
|
||||
# Adjust the template for the test invoking JS. Indent it to look nice.
|
||||
indent = "\n" + " " * 8
|
||||
test_parameters = test_parameters.replace("\n", indent)
|
||||
|
@ -66,14 +72,16 @@ def generate_selection(config, selection, spec, test_html_template_basename):
|
|||
''' % (config.test_case_name, test_parameters)
|
||||
|
||||
selection['spec_name'] = spec['name']
|
||||
selection['test_page_title'] = config.test_page_title_template % spec['title']
|
||||
selection[
|
||||
'test_page_title'] = config.test_page_title_template % spec['title']
|
||||
selection['spec_description'] = spec['description']
|
||||
selection['spec_specification_url'] = spec['specification_url']
|
||||
selection['helper_js'] = config.helper_js
|
||||
selection['sanity_checker_js'] = config.sanity_checker_js
|
||||
selection['spec_json_js'] = config.spec_json_js
|
||||
|
||||
test_filename = os.path.join(config.spec_directory, config.test_file_path_pattern % selection)
|
||||
test_filename = os.path.join(config.spec_directory,
|
||||
config.test_file_path_pattern % selection)
|
||||
test_headers_filename = test_filename + ".headers"
|
||||
test_directory = os.path.dirname(test_filename)
|
||||
|
||||
|
@ -83,14 +91,15 @@ def generate_selection(config, selection, spec, test_html_template_basename):
|
|||
html_template_filename = os.path.join(util.template_directory,
|
||||
test_html_template_basename)
|
||||
generated_disclaimer = disclaimer_template \
|
||||
% {'generating_script_filename': os.path.relpath(__file__,
|
||||
% {'generating_script_filename': os.path.relpath(sys.argv[0],
|
||||
util.test_root_directory),
|
||||
'html_template_filename': os.path.relpath(html_template_filename,
|
||||
util.test_root_directory)}
|
||||
|
||||
# Adjust the template for the test invoking JS. Indent it to look nice.
|
||||
selection['generated_disclaimer'] = generated_disclaimer.rstrip()
|
||||
selection['test_description'] = config.test_description_template % selection
|
||||
selection[
|
||||
'test_description'] = config.test_description_template % selection
|
||||
selection['test_description'] = \
|
||||
selection['test_description'].rstrip().replace("\n", "\n" + " " * 33)
|
||||
|
||||
|
@ -123,9 +132,11 @@ def generate_test_source_files(config, spec_json, target):
|
|||
specification = spec_json['specification']
|
||||
|
||||
spec_json_js_template = util.get_template('spec_json.js.template')
|
||||
generated_spec_json_filename = os.path.join(config.spec_directory, "spec_json.js")
|
||||
util.write_file(generated_spec_json_filename,
|
||||
spec_json_js_template % {'spec_json': json.dumps(spec_json)})
|
||||
generated_spec_json_filename = os.path.join(config.spec_directory,
|
||||
"spec_json.js")
|
||||
util.write_file(
|
||||
generated_spec_json_filename,
|
||||
spec_json_js_template % {'spec_json': json.dumps(spec_json)})
|
||||
|
||||
# Choose a debug/release template depending on the target.
|
||||
html_template = "test.%s.html.template" % target
|
||||
|
@ -149,13 +160,18 @@ def generate_test_source_files(config, spec_json, target):
|
|||
output_dict = {}
|
||||
|
||||
for expansion_pattern in spec['test_expansion']:
|
||||
expansion = expand_pattern(expansion_pattern, test_expansion_schema)
|
||||
expansion = expand_pattern(expansion_pattern,
|
||||
test_expansion_schema)
|
||||
for selection in permute_expansion(expansion, artifact_order):
|
||||
selection['delivery_key'] = spec_json['delivery_key']
|
||||
selection_path = config.selection_pattern % selection
|
||||
if not selection_path in exclusion_dict:
|
||||
if selection_path in output_dict:
|
||||
if expansion_pattern['expansion'] != 'override':
|
||||
print("Error: %s's expansion is default but overrides %s" % (selection['name'], output_dict[selection_path]['name']))
|
||||
print(
|
||||
"Error: %s's expansion is default but overrides %s"
|
||||
% (selection['name'],
|
||||
output_dict[selection_path]['name']))
|
||||
sys.exit(1)
|
||||
output_dict[selection_path] = copy.deepcopy(selection)
|
||||
else:
|
||||
|
@ -163,24 +179,30 @@ def generate_test_source_files(config, spec_json, target):
|
|||
|
||||
for selection_path in output_dict:
|
||||
selection = output_dict[selection_path]
|
||||
generate_selection(config,
|
||||
selection,
|
||||
spec,
|
||||
html_template)
|
||||
generate_selection(config, selection, spec, html_template)
|
||||
|
||||
|
||||
def main(config):
|
||||
parser = argparse.ArgumentParser(description='Test suite generator utility')
|
||||
parser.add_argument('-t', '--target', type = str,
|
||||
choices = ("release", "debug"), default = "release",
|
||||
help = 'Sets the appropriate template for generating tests')
|
||||
parser.add_argument('-s', '--spec', type = str, default = None,
|
||||
help = 'Specify a file used for describing and generating the tests')
|
||||
parser = argparse.ArgumentParser(
|
||||
description='Test suite generator utility')
|
||||
parser.add_argument(
|
||||
'-t',
|
||||
'--target',
|
||||
type=str,
|
||||
choices=("release", "debug"),
|
||||
default="release",
|
||||
help='Sets the appropriate template for generating tests')
|
||||
parser.add_argument(
|
||||
'-s',
|
||||
'--spec',
|
||||
type=str,
|
||||
default=None,
|
||||
help='Specify a file used for describing and generating the tests')
|
||||
# TODO(kristijanburnik): Add option for the spec_json file.
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.spec:
|
||||
config.spec_directory = args.spec
|
||||
config.spec_directory = args.spec
|
||||
|
||||
spec_filename = os.path.join(config.spec_directory, "spec.src.json")
|
||||
spec_json = util.load_spec_json(spec_filename)
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
from __future__ import print_function
|
||||
|
||||
import json, sys
|
||||
from common_paths import *
|
||||
|
||||
|
||||
def assert_non_empty_string(obj, field):
|
||||
assert field in obj, 'Missing field "%s"' % field
|
||||
|
@ -31,12 +31,13 @@ def assert_contains(obj, field):
|
|||
|
||||
|
||||
def assert_value_from(obj, field, items):
|
||||
assert obj[field] in items, \
|
||||
'Field "%s" must be from: %s' % (field, str(items))
|
||||
assert obj[field] in items, \
|
||||
'Field "%s" must be from: %s' % (field, str(items))
|
||||
|
||||
|
||||
def assert_atom_or_list_items_from(obj, field, items):
|
||||
if isinstance(obj[field], basestring) or isinstance(obj[field], int):
|
||||
if isinstance(obj[field], basestring) or isinstance(
|
||||
obj[field], int) or obj[field] is None:
|
||||
assert_value_from(obj, field, items)
|
||||
return
|
||||
|
||||
|
@ -71,13 +72,15 @@ def assert_valid_artifact(exp_pattern, artifact_key, schema):
|
|||
assert_valid_artifact(exp_pattern[artifact_key], sub_artifact_key,
|
||||
sub_schema)
|
||||
|
||||
|
||||
def validate(spec_json, details):
|
||||
""" Validates the json specification for generating tests. """
|
||||
|
||||
details['object'] = spec_json
|
||||
assert_contains_only_fields(spec_json, ["specification",
|
||||
"test_expansion_schema",
|
||||
"excluded_tests"])
|
||||
assert_contains_only_fields(spec_json, [
|
||||
"specification", "delivery_key", "test_expansion_schema",
|
||||
"excluded_tests"
|
||||
])
|
||||
assert_non_empty_list(spec_json, "specification")
|
||||
assert_non_empty_dict(spec_json, "test_expansion_schema")
|
||||
assert_non_empty_list(spec_json, "excluded_tests")
|
||||
|
@ -93,11 +96,10 @@ def validate(spec_json, details):
|
|||
details['object'] = spec
|
||||
|
||||
# Validate required fields for a single spec.
|
||||
assert_contains_only_fields(spec, ['name',
|
||||
'title',
|
||||
'description',
|
||||
'specification_url',
|
||||
'test_expansion'])
|
||||
assert_contains_only_fields(spec, [
|
||||
'name', 'title', 'description', 'specification_url',
|
||||
'test_expansion'
|
||||
])
|
||||
assert_non_empty_string(spec, 'name')
|
||||
assert_non_empty_string(spec, 'title')
|
||||
assert_non_empty_string(spec, 'description')
|
||||
|
@ -123,14 +125,10 @@ def validate(spec_json, details):
|
|||
|
||||
# Validate the test_expansion schema members.
|
||||
details['object'] = test_expansion_schema
|
||||
assert_contains_only_fields(test_expansion_schema, ['expansion',
|
||||
'source_scheme',
|
||||
'opt_in_method',
|
||||
'context_nesting',
|
||||
'redirection',
|
||||
'subresource',
|
||||
'origin',
|
||||
'expectation'])
|
||||
assert_contains_only_fields(test_expansion_schema, [
|
||||
'expansion', 'source_scheme', 'delivery_type', 'delivery_value',
|
||||
'redirection', 'subresource', 'origin', 'expectation'
|
||||
])
|
||||
# Validate excluded tests.
|
||||
details['object'] = excluded_tests
|
||||
for excluded_test_expansion in excluded_tests:
|
||||
|
@ -139,10 +137,8 @@ def validate(spec_json, details):
|
|||
details['object'] = excluded_test_expansion
|
||||
for artifact in test_expansion_schema:
|
||||
details['test_expansion_field'] = artifact
|
||||
assert_valid_artifact(
|
||||
excluded_test_expansion,
|
||||
artifact,
|
||||
test_expansion_schema[artifact])
|
||||
assert_valid_artifact(excluded_test_expansion, artifact,
|
||||
test_expansion_schema[artifact])
|
||||
del details['test_expansion_field']
|
||||
|
||||
del details['object']
|
||||
|
@ -159,7 +155,7 @@ def assert_valid_spec_json(spec_json):
|
|||
|
||||
|
||||
def main():
|
||||
spec_json = load_spec_json();
|
||||
spec_json = load_spec_json()
|
||||
assert_valid_spec_json(spec_json)
|
||||
print("Spec JSON is valid.")
|
||||
|
|
@ -3,10 +3,10 @@ from __future__ import print_function
|
|||
import os, sys, json, re
|
||||
|
||||
script_directory = os.path.dirname(os.path.abspath(__file__))
|
||||
template_directory = os.path.abspath(os.path.join(script_directory,
|
||||
'template'))
|
||||
test_root_directory = os.path.abspath(os.path.join(script_directory,
|
||||
'..', '..', '..'))
|
||||
template_directory = os.path.abspath(
|
||||
os.path.join(script_directory, 'template'))
|
||||
test_root_directory = os.path.abspath(
|
||||
os.path.join(script_directory, '..', '..', '..'))
|
||||
|
||||
|
||||
def get_template(basename):
|
||||
|
@ -20,22 +20,22 @@ def write_file(filename, contents):
|
|||
|
||||
|
||||
def read_nth_line(fp, line_number):
|
||||
fp.seek(0)
|
||||
for i, line in enumerate(fp):
|
||||
if (i + 1) == line_number:
|
||||
return line
|
||||
fp.seek(0)
|
||||
for i, line in enumerate(fp):
|
||||
if (i + 1) == line_number:
|
||||
return line
|
||||
|
||||
|
||||
def load_spec_json(path_to_spec):
|
||||
re_error_location = re.compile('line ([0-9]+) column ([0-9]+)')
|
||||
with open(path_to_spec, "r") as f:
|
||||
try:
|
||||
return json.load(f)
|
||||
return json.load(f)
|
||||
except ValueError as ex:
|
||||
print(ex.message)
|
||||
match = re_error_location.search(ex.message)
|
||||
if match:
|
||||
line_number, column = int(match.group(1)), int(match.group(2))
|
||||
print(read_nth_line(f, line_number).rstrip())
|
||||
print(" " * (column - 1) + "^")
|
||||
sys.exit(1)
|
||||
print(ex.message)
|
||||
match = re_error_location.search(ex.message)
|
||||
if match:
|
||||
line_number, column = int(match.group(1)), int(match.group(2))
|
||||
print(read_nth_line(f, line_number).rstrip())
|
||||
print(" " * (column - 1) + "^")
|
||||
sys.exit(1)
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
'use strict';
|
||||
|
||||
promise_test(async t => {
|
||||
await cookieStore.set('cookie-name', 'cookie-value', { secure: false });
|
||||
t.add_cleanup(async () => { await cookieStore.delete('cookie-name'); });
|
||||
|
||||
await cookieStore.delete('cookie-name');
|
||||
const cookie = await cookieStore.get('cookie-name');
|
||||
assert_equals(cookie, null);
|
||||
}, 'cookieStore.delete(name) can delete an insecure cookie');
|
||||
|
||||
promise_test(async t => {
|
||||
await cookieStore.set('cookie-name', 'cookie-value', { secure: false });
|
||||
t.add_cleanup(async () => { await cookieStore.delete('cookie-name'); });
|
||||
|
||||
await cookieStore.delete({ name: 'cookie-name' });
|
||||
const cookie = await cookieStore.get('cookie-name');
|
||||
assert_equals(cookie, null);
|
||||
}, 'cookieStore.delete(options) can delete an insecure cookie');
|
|
@ -5,31 +5,32 @@
|
|||
|
||||
'use strict';
|
||||
|
||||
promise_test(async () => {
|
||||
const idl = await fetch('/interfaces/credential-management.idl').then(r => r.text());
|
||||
const html = await fetch('/interfaces/html.idl').then(r => r.text());
|
||||
idl_test(
|
||||
['credential-management'],
|
||||
['html', 'dom'],
|
||||
idl_array => {
|
||||
idl_array.add_objects({
|
||||
CredentialsContainer: ['navigator.credentials'],
|
||||
PasswordCredential: ['passwordCredential'],
|
||||
FederatedCredential: ['federatedCredential'],
|
||||
});
|
||||
|
||||
var idl_array = new IdlArray();
|
||||
idl_array.add_idls(idl);
|
||||
idl_array.add_dependency_idls(html);
|
||||
idl_array.add_objects({
|
||||
CredentialsContainer: ['navigator.credentials'],
|
||||
PasswordCredential: [
|
||||
`new PasswordCredential({
|
||||
try {
|
||||
self.passwordCredential = new PasswordCredential({
|
||||
id: "id",
|
||||
password: "pencil",
|
||||
iconURL: "https://example.com/",
|
||||
name: "name"
|
||||
})`
|
||||
],
|
||||
FederatedCredential: [
|
||||
`new FederatedCredential({
|
||||
});
|
||||
} catch (e) {}
|
||||
|
||||
try {
|
||||
self.federatedCredential = new FederatedCredential({
|
||||
id: "id",
|
||||
provider: "https://example.com",
|
||||
iconURL: "https://example.com/",
|
||||
name: "name"
|
||||
})`
|
||||
]
|
||||
});
|
||||
idl_array.test();
|
||||
})
|
||||
});
|
||||
} catch (e) {}
|
||||
}
|
||||
)
|
||||
|
|
|
@ -8,3 +8,4 @@
|
|||
display: none
|
||||
}
|
||||
</style>
|
||||
<body></body>
|
||||
|
|
|
@ -6,3 +6,4 @@
|
|||
html { display: none; }
|
||||
body { background: red; }
|
||||
</style>
|
||||
<body></body>
|
||||
|
|
|
@ -14,3 +14,4 @@
|
|||
}));
|
||||
};
|
||||
</script>
|
||||
<body></body>
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
<!DOCTYPE html>
|
||||
<title>CSS Backgrounds and Borders Test: don't propagate body background when display:contents</title>
|
||||
<link rel="help" href="https://drafts.csswg.org/css-backgrounds/#special-backgrounds">
|
||||
<link rel="match" href="../reference/blank.html">
|
||||
<style>
|
||||
body {
|
||||
background: red;
|
||||
display: contents
|
||||
}
|
||||
</style>
|
||||
<body></body>
|
|
@ -13,7 +13,7 @@
|
|||
<div id="target"></div>
|
||||
<script>
|
||||
test_computed_value("border-image-source", "none");
|
||||
test_computed_value("border-image-source", 'url("http://www.example.com/")');
|
||||
test_computed_value("border-image-source", 'url("http://{{host}}/")');
|
||||
|
||||
test(() => {
|
||||
const target = document.getElementById('target');
|
|
@ -0,0 +1,51 @@
|
|||
<!DOCTYPE HTML>
|
||||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<html><head>
|
||||
<meta charset="utf-8">
|
||||
<title>Reference: Insert text node as first child in LI</title>
|
||||
<link rel="author" title="Mats Palmgren" href="mailto:mats@mozilla.org">
|
||||
<style>
|
||||
ul.inside { list-style-position: inside; }
|
||||
.before::before { content: "before"; }
|
||||
.after::after { content: "after"; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<ul class="inside">
|
||||
<li>AB</li>
|
||||
</ul>
|
||||
|
||||
<ul class="inside">
|
||||
<li class="before">AB</li>
|
||||
</ul>
|
||||
|
||||
<ul class="inside">
|
||||
<li class="after">AB</li>
|
||||
</ul>
|
||||
|
||||
<ul class="inside">
|
||||
<li class="before after">AB</li>
|
||||
</ul>
|
||||
|
||||
<ul>
|
||||
<li>AB</li>
|
||||
</ul>
|
||||
|
||||
<ul>
|
||||
<li class="before">AB</li>
|
||||
</ul>
|
||||
|
||||
<ul>
|
||||
<li class="after">AB</li>
|
||||
</ul>
|
||||
|
||||
<ul>
|
||||
<li class="before after">AB</li>
|
||||
</ul>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,60 @@
|
|||
<!DOCTYPE HTML>
|
||||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<html class="reftest-wait"><head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test: Insert text node as first child in LI</title>
|
||||
<link rel="author" title="Mats Palmgren" href="mailto:mats@mozilla.org">
|
||||
<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1567773">
|
||||
<link rel="match" href="li-insert-child-ref.html">
|
||||
<style>
|
||||
ul.inside { list-style-position: inside; }
|
||||
.before::before { content: "before"; }
|
||||
.after::after { content: "after"; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<ul class="inside">
|
||||
<li>B</li>
|
||||
</ul>
|
||||
|
||||
<ul class="inside">
|
||||
<li class="before">B</li>
|
||||
</ul>
|
||||
|
||||
<ul class="inside">
|
||||
<li class="after">B</li>
|
||||
</ul>
|
||||
|
||||
<ul class="inside">
|
||||
<li class="before after">B</li>
|
||||
</ul>
|
||||
|
||||
<ul>
|
||||
<li>B</li>
|
||||
</ul>
|
||||
|
||||
<ul>
|
||||
<li class="before">B</li>
|
||||
</ul>
|
||||
|
||||
<ul>
|
||||
<li class="after">B</li>
|
||||
</ul>
|
||||
|
||||
<ul>
|
||||
<li class="before after">B</li>
|
||||
</ul>
|
||||
|
||||
<script>
|
||||
document.body.offsetHeight;
|
||||
let items = Array.prototype.slice.call(document.querySelectorAll('li'));
|
||||
items.map(li => li.insertBefore(document.createTextNode('A'), li.firstChild));
|
||||
document.documentElement.className = '';
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -15,10 +15,10 @@
|
|||
test_computed_value('list-style', 'none', 'outside none none');
|
||||
|
||||
test_computed_value('list-style', 'inside', 'inside none disc');
|
||||
test_computed_value('list-style', 'url("https://example.com/")', 'outside url("https://example.com/") disc');
|
||||
test_computed_value('list-style', 'url("https://{{host}}/")', 'outside url("https://{{host}}/") disc');
|
||||
test_computed_value('list-style', 'square', 'outside none square');
|
||||
|
||||
test_computed_value('list-style', 'inside url("https://example.com/") square');
|
||||
test_computed_value('list-style', 'inside url("https://{{host}}/") square');
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,12 @@
|
|||
<!doctype html>
|
||||
<title>CSS Overflow Test: Propagation of body overflow to viewport</title>
|
||||
<link rel="help" href="https://drafts.csswg.org/css-overflow/#overflow-propagation">
|
||||
<link rel="help" href="https://github.com/w3c/csswg-drafts/pull/4148">
|
||||
<link rel="match" href="reference/overflow-body-propagation-ref.html">
|
||||
<style>
|
||||
body {
|
||||
overflow: scroll;
|
||||
margin-top: 100px;
|
||||
}
|
||||
</style>
|
||||
<body>The viewport should have scrollbars, not the body.</body>
|
|
@ -0,0 +1,6 @@
|
|||
<!doctype html>
|
||||
<title>CSS Overflow Test: Do not propagate overflow of display:none body to viewport</title>
|
||||
<link rel="help" href="https://drafts.csswg.org/css-overflow-3/#overflow-propagation">
|
||||
<link rel="help" href="https://github.com/w3c/csswg-drafts/pull/4148">
|
||||
<link rel="match" href="/css/reference/blank.html">
|
||||
<body style="display:none; overflow:scroll"></body>
|
|
@ -0,0 +1,6 @@
|
|||
<!doctype html>
|
||||
<title>CSS Overflow Test: Do not propagate overflow of display:contents body to viewport</title>
|
||||
<link rel="help" href="https://drafts.csswg.org/css-overflow-3/#overflow-propagation">
|
||||
<link rel="help" href="https://github.com/w3c/csswg-drafts/pull/4148">
|
||||
<link rel="match" href="/css/reference/blank.html">
|
||||
<body style="display:contents; overflow:scroll"></body>
|
|
@ -0,0 +1,14 @@
|
|||
<!doctype html>
|
||||
<link rel="help" href="https://drafts.csswg.org/css-overflow/#overflow-propagation">
|
||||
<link rel="help" href="https://github.com/w3c/csswg-drafts/pull/4148">
|
||||
<link rel="match" href="reference/overflow-body-no-propagation-ref.html">
|
||||
<style>
|
||||
html {
|
||||
overflow: hidden;
|
||||
}
|
||||
body {
|
||||
overflow: scroll;
|
||||
margin-top: 100px;
|
||||
}
|
||||
</style>
|
||||
<body>The body should have scrollbars, not the viewport.</body>
|
|
@ -0,0 +1,5 @@
|
|||
<!doctype html>
|
||||
<html style="overflow:auto">
|
||||
<title>CSS Overflow Test Reference</title>
|
||||
<body style="margin-top:100px;overflow:scroll">The body should have scrollbars, not the viewport.</body>
|
||||
</html>
|
|
@ -0,0 +1,5 @@
|
|||
<!doctype html>
|
||||
<html style="overflow:scroll">
|
||||
<title>CSS Overflow Test Reference</title>
|
||||
<body style="margin-top:100px">The viewport should have scrollbars, not the body.</body>
|
||||
</html>
|
|
@ -3,7 +3,7 @@
|
|||
<title>CSS Overflow: -webkit-line-clamp with an empty line</title>
|
||||
<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-overflow-3/#webkit-line-clamp">
|
||||
<link rel="match" href="about:blank">
|
||||
<link rel="match" href="/css/reference/blank.html">
|
||||
<style>
|
||||
.clamp {
|
||||
display: -webkit-box;
|
||||
|
|
|
@ -52,9 +52,9 @@ test(function() {
|
|||
test(function() {
|
||||
inlineStyle.setProperty('--length', 'hi');
|
||||
inlineStyle.setProperty('--color', '20');
|
||||
assert_equals(inlineStyle.getPropertyValue('--length'), '5');
|
||||
assert_equals(inlineStyle.getPropertyValue('--color'), 'hello');
|
||||
}, "Values not matching the registered type can't be set");
|
||||
assert_equals(inlineStyle.getPropertyValue('--length'), 'hi');
|
||||
assert_equals(inlineStyle.getPropertyValue('--color'), '20');
|
||||
}, "Values not matching the registered type can still be set");
|
||||
|
||||
test(function() {
|
||||
inlineStyle.removeProperty('--length');
|
||||
|
@ -66,8 +66,9 @@ test(function() {
|
|||
}, "Values can be removed from inline styles");
|
||||
|
||||
test(function() {
|
||||
sheetStyle.setProperty('--length', 'banana'); // Invalid, no change
|
||||
assert_equals(computedStyle.getPropertyValue('--length'), '10px');
|
||||
// 'banana' is not a valid <length>, but still accepted.
|
||||
sheetStyle.setProperty('--length', 'banana');
|
||||
assert_equals(computedStyle.getPropertyValue('--length'), '0px');
|
||||
sheetStyle.setProperty('--length', '20px');
|
||||
assert_equals(computedStyle.getPropertyValue('--length'), '20px');
|
||||
sheetStyle.setProperty('--length', 'initial');
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,21 @@
|
|||
<!DOCTYPE html>
|
||||
<link rel="help" href="https://crbug.com/926167">
|
||||
<style>
|
||||
|
||||
#container {
|
||||
width: 200px;
|
||||
height: 150px;
|
||||
border: 1px solid black;
|
||||
overflow: scroll;
|
||||
}
|
||||
#target {
|
||||
width: 100px;
|
||||
height: 50px;
|
||||
background: green;
|
||||
transform: scale(4);
|
||||
}
|
||||
</style>
|
||||
<!-- -->
|
||||
<div id="container">
|
||||
<div id="target"></div>
|
||||
</div>
|
|
@ -0,0 +1,34 @@
|
|||
<!DOCTYPE html>
|
||||
<title>CSS Overflow: css-overflow-3</title>
|
||||
<link rel="author" href="mailto:atotic@google.com">
|
||||
<link rel="help" href="https://crbug.com/926167">
|
||||
<link rel="match" href="scrollbars-chrome-bug-001-ref.html">
|
||||
<meta name="assert" content="scrollbars keep up to date with a changing transform">
|
||||
<style>
|
||||
|
||||
#container {
|
||||
width: 200px;
|
||||
height: 150px;
|
||||
border: 1px solid black;
|
||||
overflow: scroll;
|
||||
}
|
||||
#target {
|
||||
width: 100px;
|
||||
height: 50px;
|
||||
background: green;
|
||||
transform: scale(1);
|
||||
}
|
||||
</style>
|
||||
<!-- -->
|
||||
<div id="container">
|
||||
<div id="target"></div>
|
||||
</div>
|
||||
<script>
|
||||
// 1st transform triggers layer creation, and full layout.
|
||||
// 2nd transform just updates overflow, which does not update scrollbars.
|
||||
// This triggers the bug.
|
||||
document.body.offsetTop;
|
||||
document.querySelector("#target").style.transform = "scale(1.5)";
|
||||
document.body.offsetTop;
|
||||
document.querySelector("#target").style.transform = "scale(4.0)";
|
||||
</script>
|
|
@ -15,6 +15,11 @@
|
|||
test_computed_value("shape-image-threshold", "-7", "0");
|
||||
test_computed_value("shape-image-threshold", "0.5");
|
||||
test_computed_value("shape-image-threshold", "12.5", "1");
|
||||
|
||||
// https://github.com/w3c/csswg-drafts/issues/4102
|
||||
test_computed_value("shape-image-threshold", "-100%", "0");
|
||||
test_computed_value("shape-image-threshold", "50%", "0.5");
|
||||
test_computed_value("shape-image-threshold", "300%", "1");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
<script>
|
||||
test_invalid_value("shape-image-threshold", "auto");
|
||||
test_invalid_value("shape-image-threshold", "10px");
|
||||
test_invalid_value("shape-image-threshold", "100%");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -14,6 +14,11 @@
|
|||
<script>
|
||||
test_valid_value("shape-image-threshold", "12.5");
|
||||
test_valid_value("shape-image-threshold", "-7");
|
||||
|
||||
// https://github.com/w3c/csswg-drafts/issues/4102
|
||||
test_valid_value("shape-image-threshold", "-100%", "-1");
|
||||
test_valid_value("shape-image-threshold", "50%", "0.5");
|
||||
test_valid_value("shape-image-threshold", "300%", "3");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
<!doctype HTML>
|
||||
<meta charset="utf8">
|
||||
<title>Perspective with transforms equivalencies.</title>
|
||||
<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
|
||||
<style>
|
||||
|
||||
#container {
|
||||
transform: translate(-200px, -200px);
|
||||
width: 500px;
|
||||
height: 500px;
|
||||
perspective: 500px;
|
||||
}
|
||||
|
||||
#container > div {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
transform-style: preserve-3d;
|
||||
transform: translateZ(-250px) rotateZ(45deg);
|
||||
}
|
||||
|
||||
#container > div > div {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
background-color: rgba(3, 121, 255, 0.3);
|
||||
box-sizing: border-box;
|
||||
border: 3px solid black;
|
||||
}
|
||||
|
||||
#one { transform: rotateY(90deg) translateZ(250px); }
|
||||
</style>
|
||||
|
||||
<div id="container">
|
||||
<div>
|
||||
<div id="one"></div>
|
||||
<div id="one"></div>
|
||||
<div id="one"></div>
|
||||
<div id="one"></div>
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1,52 @@
|
|||
<!doctype HTML>
|
||||
<meta charset="utf8">
|
||||
<title>Perspective with transforms equivalencies.</title>
|
||||
<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
|
||||
<link rel="help" href="http://www.w3.org/TR/css-transforms-2/#perspective-property">
|
||||
<link rel="help" href="http://www.w3.org/TR/css-transforms-1/#transform-property">
|
||||
<link rel="match" href="perspective-transforms-equivalence-ref.html">
|
||||
<!--
|
||||
Perspective with different transforms can have small anti-aliasing
|
||||
pixel differences, so the test should fuzzy patch to the ref.
|
||||
-->
|
||||
<meta name="fuzzy" content="maxDifference=10;totalPixels=10">
|
||||
<style>
|
||||
|
||||
#container {
|
||||
transform: translate(-200px, -200px);
|
||||
width: 500px;
|
||||
height: 500px;
|
||||
perspective: 500px;
|
||||
}
|
||||
|
||||
#container > div {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
transform-style: preserve-3d;
|
||||
transform: translateZ(-250px) rotateZ(45deg);
|
||||
}
|
||||
|
||||
#container > div > div {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
background-color: rgba(3, 121, 255, 0.3);
|
||||
box-sizing: border-box;
|
||||
border: 3px solid black;
|
||||
}
|
||||
|
||||
/* The following four should be equivalent. */
|
||||
#one { transform: rotateY(90deg) translateZ(250px); }
|
||||
#two { transform: rotateZ(90deg) rotateX(90deg) translateZ(250px); }
|
||||
#three { transform: rotateY(-90deg) translateZ(-250px); }
|
||||
#four { transform: rotateZ(-90deg) rotateX(90deg) translateZ(-250px); }
|
||||
</style>
|
||||
|
||||
<div id="container">
|
||||
<div>
|
||||
<div id="one"></div>
|
||||
<div id="two"></div>
|
||||
<div id="three"></div>
|
||||
<div id="four"></div>
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1,18 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Don't crash when setting a CSSVariableReferenceValue</title>
|
||||
<link rel="help" href="https://drafts.css-houdini.org/css-typed-om-1/#cssvariablereferencevalue">
|
||||
<link rel="help" href="https://crbug.com/986710<">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<style>
|
||||
:root { --x: green; }
|
||||
</style>
|
||||
<div id="target"></div>
|
||||
<script>
|
||||
test(function(){
|
||||
let ref = new CSSVariableReferenceValue('--x')
|
||||
let unparsed = new CSSUnparsedValue([' ', ref]);
|
||||
target.attributeStyleMap.set('color', unparsed);
|
||||
assert_equals('rgb(0, 128, 0)', target.computedStyleMap().get('color').toString());
|
||||
}, 'Do not crash when referencing a variable with CSSVariableReferenceValue');
|
||||
</script>
|
|
@ -0,0 +1,23 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>Test reference</title>
|
||||
<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net">
|
||||
<style>
|
||||
.v-rl {
|
||||
writing-mode: vertical-rl;
|
||||
width: 200px;
|
||||
}
|
||||
span {
|
||||
-webkit-text-combine: horizontal; /*testing the layout text-combine, not it's support in general*/
|
||||
text-combine-upright: all;
|
||||
white-space: normal;
|
||||
}
|
||||
#test { color: blue; }
|
||||
#ref { color: orange; }
|
||||
</style>
|
||||
<p>Test passes if the blue and orange lines of text are identical.
|
||||
|
||||
<div class=v-rl>
|
||||
<div id=test>あ<span>12</span>い<span>34</span>う<span>5 6</span>えお</div>
|
||||
<div id=ref>あ<span>12</span>い<span>34</span>う<span>5 6</span>えお</div>
|
||||
</div>
|
|
@ -0,0 +1,23 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>Test Reference</title>
|
||||
<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net">
|
||||
<style>
|
||||
.v-rl {
|
||||
writing-mode: vertical-rl;
|
||||
width: 200px;
|
||||
}
|
||||
span {
|
||||
-webkit-text-combine: horizontal; /*testing the layout text-combine, not it's support in general*/
|
||||
text-combine-upright: all;
|
||||
white-space: pre;
|
||||
}
|
||||
#test { color: blue; }
|
||||
#ref { color: orange; }
|
||||
</style>
|
||||
<p>Test passes if the blue and orange lines of text are identical.
|
||||
|
||||
<div class=v-rl>
|
||||
<div id=test>あ<span> 12</span>い<span>34 </span>う<span>5 6</span>えお</div>
|
||||
<div id=ref>あ<span> 12</span>い<span>34 </span>う<span>5 6</span>えお</div>
|
||||
</div>
|
|
@ -0,0 +1,31 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>Test Reference</title>
|
||||
<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net">
|
||||
<style>
|
||||
.v-rl {
|
||||
writing-mode: vertical-rl;
|
||||
width: 200px;
|
||||
}
|
||||
span {
|
||||
display: inline-block;
|
||||
height: 1em;
|
||||
}
|
||||
#test { color: blue; }
|
||||
#test2 { color: brown; }
|
||||
#ref { color: orange; }
|
||||
.v-rl > div {
|
||||
display: inline-block;
|
||||
border: solid;
|
||||
margin: 0 5px;
|
||||
}
|
||||
</style>
|
||||
<p>Test passes if the blue, orange, brown boxes are identical.
|
||||
|
||||
<div class=v-rl>
|
||||
<div id=test>あいう<span></span>えお<span></span></div>
|
||||
<br>
|
||||
<div id=test2>あいう<span></span>えお<span></span></div>
|
||||
<br>
|
||||
<div id=ref>あいう<span></span>えお<span></span></div>
|
||||
</div>
|
|
@ -0,0 +1,27 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Writing Modes Test: white-space:normal space processing in text-combine-horizontal</title>
|
||||
<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net">
|
||||
<link rel="help" href="https://www.w3.org/TR/css-writing-modes-4/#text-combine-layout">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-text-3/#white-space-rules">
|
||||
<link rel="match" href="reference/tcy-white-space-processing-001-ref.html">
|
||||
<meta name="assert" content="Spaces with white-space:normal in a text-combine horizontal is trimmed at the start and end, and collapsed in the middle.">
|
||||
<style>
|
||||
.v-rl {
|
||||
writing-mode: vertical-rl;
|
||||
width: 200px;
|
||||
}
|
||||
span {
|
||||
-webkit-text-combine: horizontal; /*testing the layout text-combine, not it's support in general*/
|
||||
text-combine-upright: all;
|
||||
white-space: normal;
|
||||
}
|
||||
#test { color: blue; }
|
||||
#ref { color: orange; }
|
||||
</style>
|
||||
<p>Test passes if the blue and orange lines of text are identical.
|
||||
|
||||
<div class=v-rl>
|
||||
<div id=test>あ<span> 12</span>い<span>34 </span>う<span>5 6</span>えお</div>
|
||||
<div id=ref>あ<span>12</span>い<span>34</span>う<span>5 6</span>えお</div>
|
||||
</div>
|
|
@ -0,0 +1,27 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Writing Modes Test: white-space:pre space processing in text-combine-horizontal</title>
|
||||
<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net">
|
||||
<link rel="help" href="https://www.w3.org/TR/css-writing-modes-4/#text-combine-layout">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-text-3/#white-space-rules">
|
||||
<link rel="match" href="reference/tcy-white-space-processing-002-ref.html">
|
||||
<meta name="assert" content="Spaces with white-space:pre in a text-combine-upright are preserved">
|
||||
<style>
|
||||
.v-rl {
|
||||
writing-mode: vertical-rl;
|
||||
width: 200px;
|
||||
}
|
||||
span {
|
||||
-webkit-text-combine: horizontal; /*testing the layout text-combine, not it's support in general*/
|
||||
text-combine-upright: all;
|
||||
white-space: pre;
|
||||
}
|
||||
#test { color: blue; }
|
||||
#ref { color: orange; }
|
||||
</style>
|
||||
<p>Test passes if the blue and orange lines of text are identical.
|
||||
|
||||
<div class=v-rl>
|
||||
<div id=test>あ<span> 12</span>い<span>34 </span>う<span>5 6</span>えお</div>
|
||||
<div id=ref>あ<span> 12</span>い<span>34 </span>う<span>5 6</span>えお</div>
|
||||
</div>
|
|
@ -0,0 +1,44 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Writing Modes Test: white space only text-combine-horizontal</title>
|
||||
<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net">
|
||||
<link rel="help" href="https://www.w3.org/TR/css-writing-modes-4/#text-combine-layout">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-text-3/#white-space-rules">
|
||||
<link rel="match" href="reference/tcy-white-space-processing-003-ref.html">
|
||||
<meta name="assert" content="a text-combine-upright with only white-space is preserved as a 1em square, including at the end of the containing line, regardless of the value of the white-space property">
|
||||
<style>
|
||||
.v-rl {
|
||||
writing-mode: vertical-rl;
|
||||
width: 200px;
|
||||
}
|
||||
#test span {
|
||||
-webkit-text-combine: horizontal; /*testing the layout text-combine, not it's support in general*/
|
||||
text-combine-upright: all;
|
||||
}
|
||||
#test2 span {
|
||||
-webkit-text-combine: horizontal; /*testing the layout text-combine, not it's support in general*/
|
||||
text-combine-upright: all;
|
||||
white-space: pre;
|
||||
}
|
||||
#ref span {
|
||||
display: inline-block;
|
||||
height: 1em;
|
||||
}
|
||||
#test { color: blue; }
|
||||
#test2 { color: brown; }
|
||||
#ref { color: orange; }
|
||||
.v-rl > div {
|
||||
display: inline-block;
|
||||
border: solid;
|
||||
margin: 0 5px;
|
||||
}
|
||||
</style>
|
||||
<p>Test passes if the blue, orange, brown boxes are identical.
|
||||
|
||||
<div class=v-rl>
|
||||
<div id=test>あいう<span> </span>えお<span> </span></div>
|
||||
<br>
|
||||
<div id=test2>あいう<span> </span>えお<span> </span></div>
|
||||
<br>
|
||||
<div id=ref>あいう<span></span>えお<span></span></div>
|
||||
</div>
|
|
@ -37,11 +37,10 @@ on [file names][file-name-flags].
|
|||
|
||||
#### Support Files
|
||||
|
||||
Various support files are available in in the `/common/` and `/media/`
|
||||
directories (web-platform-tests) and `/support/` (in css/). Reusing
|
||||
existing resources is encouraged where possible, as is adding
|
||||
generally useful files to these common areas rather than to specific
|
||||
test suites.
|
||||
Various support files are available in in the directories named `/common/`,
|
||||
`/media/`, and `/css/support/`. Reusing existing resources is encouraged where
|
||||
possible, as is adding generally-useful files to these common areas rather than
|
||||
to specific test suites.
|
||||
|
||||
|
||||
#### Tools
|
||||
|
@ -61,9 +60,17 @@ subdirectory and put your script there.
|
|||
|
||||
### File Formats
|
||||
|
||||
Tests must be HTML or XML (inc. XHTML and SVG) files; some
|
||||
testharness.js tests
|
||||
are [auto-generated from JS files][server features].
|
||||
Tests are generally formatted as HTML (including XHTML) or XML (including SVG).
|
||||
Some test types support other formats:
|
||||
|
||||
- [testharness.js tests](testharness) may be expressed as JavaScript files
|
||||
([the WPT server automatically generates the HTML documents for these][server
|
||||
features])
|
||||
- [WebDriver specification tests](wdspec) are expressed as Python files
|
||||
|
||||
The best way to determine how to format a new test is to look at how similar
|
||||
tests have been formatted. You can also ask for advice in [the project's IRC
|
||||
room][IRC].
|
||||
|
||||
|
||||
### Character Encoding
|
||||
|
@ -179,6 +186,7 @@ for CSS have some additional requirements for:
|
|||
[server features]: server-features
|
||||
[assumptions]: assumptions
|
||||
[ahem]: ahem
|
||||
[IRC]: irc://irc.w3.org:6667/testing
|
||||
[lint-tool]: lint-tool
|
||||
[css-metadata]: css-metadata
|
||||
[css-user-styles]: css-user-styles
|
||||
|
|
|
@ -5,10 +5,6 @@ these are especially using for [visual](visual) tests which need to be manually
|
|||
judged and following common patterns makes it easier to correctly tell if a
|
||||
given test passed or not.
|
||||
|
||||
## Make tests self-describing
|
||||
|
||||
Tests should make it obvious when they pass and when they fail. It shouldn't be necessary to consult the specification to figure out whether a test has passed of failed.
|
||||
|
||||
## Indicating success
|
||||
|
||||
Success is largely indicated by the color green; typically in one of
|
||||
|
@ -80,7 +76,7 @@ ways:
|
|||
* Silver or light gray is often used for irrelevant content, such as
|
||||
filler text.
|
||||
|
||||
Obviously, none of this can be taken as absolute rules, as testing of
|
||||
None of these rules are absolute because testing
|
||||
color-related functionality will necessitate using some of these
|
||||
colors!
|
||||
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
<!DOCTYPE HTML>
|
||||
<meta charset=utf-8>
|
||||
<title>ElementTiming: element is only exposed for fully active documents.</title>
|
||||
<body>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<iframe src="resources/iframe-stores-entry.html" id="ifr"></iframe>
|
||||
<script>
|
||||
let t = async_test('Only expose element attribute for fully active documents');
|
||||
window.triggerTest = t.step_func_done(elementEntry => {
|
||||
assert_not_equals(elementEntry.element, null);
|
||||
const iframe = document.getElementById('ifr');
|
||||
iframe.remove();
|
||||
assert_equals(elementEntry.element, null);
|
||||
});
|
||||
</script>
|
||||
</body>
|
|
@ -0,0 +1,30 @@
|
|||
<!DOCTYPE HTML>
|
||||
<meta charset=utf-8>
|
||||
<title>Element Timing: entry does not change its id or identifier value</title>
|
||||
<body>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="resources/element-timing-helpers.js"></script>
|
||||
<p elementtiming='my_identifier' id='my_id'>Text</p>
|
||||
<script>
|
||||
async_test(function (t) {
|
||||
if (!window.PerformanceElementTiming) {
|
||||
assert_unreached("PerformanceElementTiming is not implemented");
|
||||
}
|
||||
const observer = new PerformanceObserver(
|
||||
t.step_func_done(function(entryList) {
|
||||
assert_equals(entryList.getEntries().length, 1);
|
||||
const entry = entryList.getEntries()[0];
|
||||
assert_equals(entry.id, 'my_id');
|
||||
assert_equals(entry.identifier, 'my_identifier');
|
||||
const element = document.getElementById('my_id');
|
||||
element.id = 'other_id';
|
||||
element.setAttribute('elementtiming', 'other_identifier');
|
||||
assert_equals(entry.id, 'my_id');
|
||||
assert_equals(entry.identifier, 'my_identifier');
|
||||
})
|
||||
);
|
||||
observer.observe({type: 'element', buffered: true});
|
||||
}, 'PerformanceElementTiming id and identifier do not change when Element changes.');
|
||||
</script>
|
||||
</body>
|
|
@ -0,0 +1,16 @@
|
|||
// META: script=/resources/WebIDLParser.js
|
||||
// META: script=/resources/idlharness.js
|
||||
|
||||
// https://wicg.github.io/element-timing/
|
||||
|
||||
'use strict';
|
||||
|
||||
idl_test(
|
||||
['element-timing'],
|
||||
['performance-timeline', 'dom'],
|
||||
idl_array => {
|
||||
idl_array.add_objects({
|
||||
// PerformanceElementTiming: [ TODO ]
|
||||
});
|
||||
}
|
||||
);
|
|
@ -4,13 +4,22 @@ function checkElementInternal(entry, expectedUrl, expectedIdentifier, expectedID
|
|||
assert_equals(entry.entryType, 'element');
|
||||
assert_equals(entry.url, expectedUrl);
|
||||
assert_equals(entry.identifier, expectedIdentifier);
|
||||
assert_equals(entry.startTime, 0);
|
||||
if (beforeRender != 0) {
|
||||
// In this case, renderTime is not 0.
|
||||
assert_equals(entry.startTime, entry.renderTime);
|
||||
} else {
|
||||
// In this case, renderTime is 0, so compare to loadTime.
|
||||
assert_equals(entry.startTime, entry.loadTime);
|
||||
}
|
||||
assert_equals(entry.duration, 0);
|
||||
assert_equals(entry.id, expectedID);
|
||||
assert_greater_than_equal(entry.renderTime, beforeRender);
|
||||
assert_greater_than_equal(performance.now(), entry.renderTime);
|
||||
if (expectedElement !== null)
|
||||
if (expectedElement !== null) {
|
||||
assert_equals(entry.element, expectedElement);
|
||||
assert_equals(entry.identifier, expectedElement.elementTiming);
|
||||
assert_equals(entry.id, expectedElement.id);
|
||||
}
|
||||
}
|
||||
|
||||
// Checks that this is an ElementTiming entry with url |expectedUrl|. It also
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<p elementtiming='text'>Text</p>
|
||||
<script>
|
||||
const observer = new PerformanceObserver(entryList => {
|
||||
window.parent.triggerTest(entryList.getEntries()[0]);
|
||||
});
|
||||
observer.observe({type: 'element', buffered: true});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -38,8 +38,16 @@ const waitForLoad = new Promise(resolve => { addEventListener('load', resolve);
|
|||
|
||||
idl_test(
|
||||
['html'],
|
||||
['SVG', 'cssom', 'touch-events', 'uievents', 'dom', 'xhr'],
|
||||
['SVG', 'cssom', 'touch-events', 'uievents', 'dom', 'xhr', 'FileAPI'],
|
||||
async idlArray => {
|
||||
self.documentWithHandlers = new Document();
|
||||
const handler = function(e) {};
|
||||
for (const callback of idlArray.members['GlobalEventHandlers'].members) {
|
||||
if (callback.idlType && callback.idlType.idlType === 'EventHandler') {
|
||||
documentWithHandlers[callback.name] = handler;
|
||||
}
|
||||
}
|
||||
|
||||
idlArray.add_objects({
|
||||
NodeList: ['document.getElementsByName("name")'],
|
||||
HTMLAllCollection: ['document.all'],
|
||||
|
@ -48,7 +56,7 @@ idl_test(
|
|||
HTMLOptionsCollection: ['document.createElement("select").options'],
|
||||
DOMStringMap: ['document.head.dataset'],
|
||||
Transferable: [],
|
||||
Document: ['iframe.contentDocument', 'new Document()'],
|
||||
Document: ['iframe.contentDocument', 'new Document()', 'documentWithHandlers'],
|
||||
XMLDocument: ['document.implementation.createDocument(null, "", null)'],
|
||||
HTMLElement: ['document.createElement("noscript")'], // more tests in html/semantics/interfaces.js
|
||||
HTMLUnknownElement: ['document.createElement("bgsound")'], // more tests in html/semantics/interfaces.js
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
<div id="null"></div>
|
||||
<div name="divwithname"></div>
|
||||
<div id="-0"></div>
|
||||
<div id="log"></div>
|
||||
<script>
|
||||
var anchors = document.querySelectorAll("a");
|
||||
var divs = document.querySelectorAll("div");
|
||||
|
@ -34,7 +35,7 @@ test(function() {
|
|||
}, "document.all is an HTMLAllCollection");
|
||||
|
||||
test(function() {
|
||||
assert_equals(document.all.length, 24);
|
||||
assert_equals(document.all.length, 25);
|
||||
}, "length attribute");
|
||||
|
||||
// indexed property getter
|
||||
|
@ -42,12 +43,12 @@ test(function() {
|
|||
test(function() {
|
||||
assert_equals(document.all[0], document.documentElement);
|
||||
assert_equals(document.all[-0], document.documentElement);
|
||||
assert_equals(document.all[23], scripts[2]);
|
||||
assert_equals(document.all[24], scripts[2]);
|
||||
}, "indexed property getter");
|
||||
|
||||
test(function() {
|
||||
assert_equals(document.all[-1], undefined);
|
||||
assert_equals(document.all[24], undefined);
|
||||
assert_equals(document.all[25], undefined);
|
||||
assert_equals(document.all[42], undefined);
|
||||
assert_equals(document.all[43], undefined);
|
||||
assert_equals(document.all[4294967294], undefined);
|
||||
|
@ -86,8 +87,8 @@ test(function() {
|
|||
|
||||
test(function() {
|
||||
assert_equals(document.all["0"], document.documentElement);
|
||||
assert_equals(document.all["23"], document.scripts[2]);
|
||||
assert_equals(document.all["24"], undefined);
|
||||
assert_equals(document.all["24"], document.scripts[2]);
|
||||
assert_equals(document.all["25"], undefined);
|
||||
assert_equals(document.all["42"], undefined);
|
||||
assert_equals(document.all["43"], undefined);
|
||||
}, "named property getter with \"array index property name\"");
|
||||
|
@ -187,16 +188,16 @@ test(function() {
|
|||
|
||||
test(function() {
|
||||
assert_equals(document.all("0"), document.documentElement);
|
||||
assert_equals(document.all("23"), document.scripts[2]);
|
||||
assert_equals(document.all("24"), null);
|
||||
assert_equals(document.all("24"), document.scripts[2]);
|
||||
assert_equals(document.all("25"), null);
|
||||
assert_equals(document.all("42"), null);
|
||||
assert_equals(document.all("43"), null);
|
||||
}, "legacy caller with \"array index property name\"");
|
||||
|
||||
test(function() {
|
||||
assert_equals(document.all(0), document.documentElement);
|
||||
assert_equals(document.all(23), document.scripts[2]);
|
||||
assert_equals(document.all(24), null);
|
||||
assert_equals(document.all(24), document.scripts[2]);
|
||||
assert_equals(document.all(25), null);
|
||||
assert_equals(document.all(42), null);
|
||||
assert_equals(document.all(43), null);
|
||||
}, "legacy caller with \"array index property name\" as number");
|
||||
|
@ -267,16 +268,16 @@ test(function() {
|
|||
|
||||
test(function() {
|
||||
assert_equals(document.all.item("0"), document.documentElement);
|
||||
assert_equals(document.all.item("23"), document.scripts[2]);
|
||||
assert_equals(document.all.item("24"), null);
|
||||
assert_equals(document.all.item("24"), document.scripts[2]);
|
||||
assert_equals(document.all.item("25"), null);
|
||||
assert_equals(document.all.item("42"), null);
|
||||
assert_equals(document.all.item("43"), null);
|
||||
}, "item method with \"array index property name\"");
|
||||
|
||||
test(function() {
|
||||
assert_equals(document.all.item(0), document.documentElement);
|
||||
assert_equals(document.all.item(23), document.scripts[2]);
|
||||
assert_equals(document.all.item(24), null);
|
||||
assert_equals(document.all.item(24), document.scripts[2]);
|
||||
assert_equals(document.all.item(25), null);
|
||||
assert_equals(document.all.item(42), null);
|
||||
assert_equals(document.all.item(43), null);
|
||||
}, "item method with \"array index property name\" as number");
|
||||
|
@ -329,6 +330,5 @@ test(function() {
|
|||
}
|
||||
}, "collections are new live HTMLCollection instances");
|
||||
</script>
|
||||
<div id="log"></div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -4,4 +4,4 @@
|
|||
|
||||
[TestDriver actions: actions with key pressed]
|
||||
expected:
|
||||
if os == "mac" and product == "chrome": FAIL
|
||||
if os == "mac" and (product == "chrome" or product=="firefox"): FAIL
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
// Source: File API (https://w3c.github.io/FileAPI/)
|
||||
|
||||
[Constructor(optional sequence<BlobPart> blobParts,
|
||||
optional BlobPropertyBag options),
|
||||
optional BlobPropertyBag options = {}),
|
||||
Exposed=(Window,Worker), Serializable]
|
||||
interface Blob {
|
||||
|
||||
|
@ -33,7 +33,7 @@ typedef (BufferSource or Blob or USVString) BlobPart;
|
|||
|
||||
[Constructor(sequence<BlobPart> fileBits,
|
||||
USVString fileName,
|
||||
optional FilePropertyBag options),
|
||||
optional FilePropertyBag options = {}),
|
||||
Exposed=(Window,Worker), Serializable]
|
||||
interface File : Blob {
|
||||
readonly attribute DOMString name;
|
||||
|
|
20
tests/wpt/web-platform-tests/interfaces/element-timing.idl
Normal file
20
tests/wpt/web-platform-tests/interfaces/element-timing.idl
Normal file
|
@ -0,0 +1,20 @@
|
|||
// GENERATED CONTENT - DO NOT EDIT
|
||||
// Content was automatically extracted by Reffy into reffy-reports
|
||||
// (https://github.com/tidoust/reffy-reports)
|
||||
// Source: Element Timing API (https://wicg.github.io/element-timing/)
|
||||
|
||||
interface PerformanceElementTiming : PerformanceEntry {
|
||||
readonly attribute DOMHighResTimeStamp renderTime;
|
||||
readonly attribute DOMHighResTimeStamp loadTime;
|
||||
readonly attribute DOMRectReadOnly intersectionRect;
|
||||
readonly attribute DOMString identifier;
|
||||
readonly attribute unsigned long naturalWidth;
|
||||
readonly attribute unsigned long naturalHeight;
|
||||
readonly attribute DOMString id;
|
||||
readonly attribute Element? element;
|
||||
readonly attribute DOMString url;
|
||||
};
|
||||
|
||||
partial interface Element {
|
||||
[CEReactions] attribute DOMString elementTiming;
|
||||
};
|
|
@ -4,11 +4,11 @@
|
|||
// Source: Input Events Level 1 (https://cdn.staticaly.com/gh/w3c/input-events/v1/index.html)
|
||||
|
||||
partial interface InputEvent {
|
||||
readonly attribute DataTransfer? dataTransfer;
|
||||
sequence<StaticRange> getTargetRanges();
|
||||
readonly attribute DataTransfer? dataTransfer;
|
||||
sequence<StaticRange> getTargetRanges();
|
||||
};
|
||||
|
||||
partial dictionary InputEventInit {
|
||||
DataTransfer? dataTransfer = null;
|
||||
sequence<StaticRange> targetRanges = [];
|
||||
DataTransfer? dataTransfer = null;
|
||||
sequence<StaticRange> targetRanges = [];
|
||||
};
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
// GENERATED CONTENT - DO NOT EDIT
|
||||
// Content was automatically extracted by Reffy into reffy-reports
|
||||
// (https://github.com/tidoust/reffy-reports)
|
||||
// Source: Largest Contentful Paint (https://wicg.github.io/largest-contentful-paint/)
|
||||
|
||||
interface LargestContentfulPaint : PerformanceEntry {
|
||||
readonly attribute DOMHighResTimeStamp renderTime;
|
||||
readonly attribute DOMHighResTimeStamp loadTime;
|
||||
readonly attribute unsigned long size;
|
||||
readonly attribute DOMString id;
|
||||
readonly attribute DOMString url;
|
||||
readonly attribute Element? element;
|
||||
};
|
|
@ -23,8 +23,8 @@ callback PerformanceObserverCallback = void (PerformanceObserverEntryList entrie
|
|||
PerformanceObserver observer);
|
||||
[Constructor(PerformanceObserverCallback callback), Exposed=(Window,Worker)]
|
||||
interface PerformanceObserver {
|
||||
void observe(optional PerformanceObserverInit options);
|
||||
void disconnect();
|
||||
void observe (optional PerformanceObserverInit options = {});
|
||||
void disconnect ();
|
||||
PerformanceEntryList takeRecords();
|
||||
[SameObject] static readonly attribute FrozenArray<DOMString> supportedEntryTypes;
|
||||
};
|
||||
|
|
|
@ -4,23 +4,23 @@
|
|||
// Source: User Timing Level 3 (https://w3c.github.io/user-timing/)
|
||||
|
||||
dictionary PerformanceMarkOptions {
|
||||
any detail;
|
||||
DOMHighResTimeStamp startTime;
|
||||
};
|
||||
any detail;
|
||||
DOMHighResTimeStamp startTime;
|
||||
};
|
||||
|
||||
dictionary PerformanceMeasureOptions {
|
||||
any detail;
|
||||
(DOMString or DOMHighResTimeStamp) start;
|
||||
DOMHighResTimeStamp duration;
|
||||
(DOMString or DOMHighResTimeStamp) end;
|
||||
};
|
||||
dictionary PerformanceMeasureOptions {
|
||||
any detail;
|
||||
(DOMString or DOMHighResTimeStamp) start;
|
||||
DOMHighResTimeStamp duration;
|
||||
(DOMString or DOMHighResTimeStamp) end;
|
||||
};
|
||||
|
||||
partial interface Performance {
|
||||
PerformanceMark mark(DOMString markName, optional PerformanceMarkOptions markOptions = {});
|
||||
void clearMarks(optional DOMString markName);
|
||||
PerformanceMeasure measure(DOMString measureName, optional (DOMString or PerformanceMeasureOptions) startOrMeasureOptions = {}, optional DOMString endMark);
|
||||
void clearMeasures(optional DOMString measureName);
|
||||
};
|
||||
partial interface Performance {
|
||||
PerformanceMark mark(DOMString markName, optional PerformanceMarkOptions markOptions = {});
|
||||
void clearMarks(optional DOMString markName);
|
||||
PerformanceMeasure measure(DOMString measureName, optional (DOMString or PerformanceMeasureOptions) startOrMeasureOptions = {}, optional DOMString endMark);
|
||||
void clearMeasures(optional DOMString measureName);
|
||||
};
|
||||
|
||||
[Exposed=(Window,Worker),
|
||||
Constructor(DOMString markName, optional PerformanceMarkOptions markOptions)]
|
||||
|
|
|
@ -3,6 +3,10 @@
|
|||
// (https://github.com/tidoust/reffy-reports)
|
||||
// Source: Web Share API - Level 1 (https://wicg.github.io/web-share/)
|
||||
|
||||
partial interface Navigator {
|
||||
[SecureContext] Promise<void> share(optional ShareData data = {});
|
||||
};
|
||||
|
||||
dictionary ShareData {
|
||||
USVString title;
|
||||
USVString text;
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
<!DOCTYPE html>
|
||||
<html dir="rtl">
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="./resources/intersection-observer-test-utils.js"></script>
|
||||
|
||||
<style>
|
||||
pre, #log {
|
||||
position: absolute;
|
||||
top: 120px;
|
||||
left: 0;
|
||||
}
|
||||
#root {
|
||||
width: 350px;
|
||||
height: 100px;
|
||||
border: 1px solid black;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
overflow-x: auto;
|
||||
}
|
||||
#target-start, #target-end {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
flex-shrink: 0;
|
||||
background-color: green;
|
||||
text-align: center;
|
||||
}
|
||||
#target-end {
|
||||
margin-inline-start: 500px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<div id="root">
|
||||
<div id="target-start">start</div>
|
||||
<div id="target-end">end</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
runTestCycle(function() {
|
||||
let io = new IntersectionObserver(entries => {
|
||||
entries.forEach(entry => {
|
||||
if (entry.isIntersecting) {
|
||||
entry.target.classList.add("intersecting");
|
||||
} else {
|
||||
entry.target.classList.remove("intersecting");
|
||||
}
|
||||
});
|
||||
}, { root: document.getElementById("root") });
|
||||
document.querySelectorAll("#root > div").forEach(element => {
|
||||
io.observe(element);
|
||||
});
|
||||
runTestCycle(step0, "First rAF");
|
||||
}, "Explicit rtl root with overflow clipping");
|
||||
|
||||
function step0() {
|
||||
assert_true(
|
||||
document.getElementById("target-start").classList.contains("intersecting"),
|
||||
"Target at scroll start is intersecting");
|
||||
assert_false(
|
||||
document.getElementById("target-end").classList.contains("intersecting"),
|
||||
"Target at scroll end is not intersecting");
|
||||
}
|
||||
</script>
|
|
@ -7,7 +7,7 @@
|
|||
<script src="/resources/testharnessreport.js"></script>
|
||||
|
||||
<script type="module">
|
||||
import { storage } from "std:kv-storage";
|
||||
import storage from "std:kv-storage";
|
||||
|
||||
test(() => {
|
||||
assert_equals(storage.backingStore, storage.backingStore);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { StorageArea, storage as defaultArea } from "std:kv-storage";
|
||||
import defaultArea, { StorageArea } from "std:kv-storage";
|
||||
import { assertAsyncIteratorEquals, assertAsyncIteratorCustomEquals } from "./equality-asserters.js";
|
||||
|
||||
// Used when we're manually creating the database, and so the IDB helpers also want to clean it up.
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
<script src="/resources/idlharness.js"></script>
|
||||
|
||||
<script type="module">
|
||||
import { storage, StorageArea } from "std:kv-storage";
|
||||
import storage, { StorageArea } from "std:kv-storage";
|
||||
|
||||
// Web IDL/idlharness.js do not yet have support for the spec's IDL, which uses module {},
|
||||
// async_iterator, and some new extended attributes. This IDL is a mutated version to work with the
|
||||
|
@ -172,4 +172,4 @@ function frameLoadPromise(frame) {
|
|||
frame.onerror = () => reject(new Error(`${frame.src} failed to load`));
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</script>
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
|
||||
<script type="module">
|
||||
import { testVariousMethodsWithDefaultArea } from "./helpers/kvs-tests.js";
|
||||
import { storage } from "std:kv-storage";
|
||||
|
||||
testVariousMethodsWithDefaultArea(
|
||||
"Storage methods smoke test with string key and value", "key", "value", assert_equals
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
<!DOCTYPE HTML>
|
||||
<meta charset=utf-8>
|
||||
<title>Largest Contentful Paint: element is only exposed for fully active documents.</title>
|
||||
<body>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<iframe src="resources/iframe-stores-entry.html" id="ifr"></iframe>
|
||||
<script>
|
||||
let t = async_test('Only expose element attribute for fully active documents');
|
||||
window.triggerTest = t.step_func_done(entry => {
|
||||
assert_not_equals(entry.element, null);
|
||||
const iframe = document.getElementById('ifr');
|
||||
iframe.remove();
|
||||
assert_equals(entry.element, null);
|
||||
});
|
||||
</script>
|
||||
</body>
|
|
@ -0,0 +1,30 @@
|
|||
<!doctype html>
|
||||
<title>Largest Contentful Paint IDL tests</title>
|
||||
<link rel="help" href="https://wicg.github.io/largest-contentful-paint/">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/resources/WebIDLParser.js"></script>
|
||||
<script src="/resources/idlharness.js"></script>
|
||||
<script>
|
||||
'use strict';
|
||||
|
||||
idl_test(
|
||||
['largest-contentful-paint'],
|
||||
['performance-timeline', 'dom'],
|
||||
async (idl_array, t) => {
|
||||
idl_array.add_objects({
|
||||
LargestContentfulPaint: ['lcp']
|
||||
});
|
||||
|
||||
window.lcp = await new Promise((resolve, reject) => {
|
||||
const observer = new PerformanceObserver(entryList => {
|
||||
resolve(entryList.getEntries()[0]);
|
||||
});
|
||||
observer.observe({type: 'largest-contentful-paint', buffered: true});
|
||||
t.step_timeout(() => reject('Timed out waiting for LargestContentfulPaint entry'), 3000);
|
||||
});
|
||||
}
|
||||
);
|
||||
</script>
|
||||
<!-- a contentful element to observe -->
|
||||
<img src=/images/green-100x50.png>
|
|
@ -0,0 +1,47 @@
|
|||
<!DOCTYPE HTML>
|
||||
<meta charset=utf-8>
|
||||
<title>Largest Contentful Paint: observe image.</title>
|
||||
<body>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script>
|
||||
async_test(function (t) {
|
||||
if (!window.LargestContentfulPaint) {
|
||||
assert_unreached("LargestContentfulPaint is not implemented");
|
||||
}
|
||||
const beforeRender = performance.now();
|
||||
const observer = new PerformanceObserver(
|
||||
t.step_func_done(function(entryList) {
|
||||
assert_equals(entryList.getEntries().length, 1);
|
||||
const entry = entryList.getEntries()[0];
|
||||
assert_equals(entry.entryType, 'largest-contentful-paint');
|
||||
assert_greater_than_equal(entry.renderTime, beforeRender,
|
||||
'The rendering timestamp should occur after script starts running.');
|
||||
assert_greater_than_equal(performance.now(), entry.renderTime,
|
||||
'The rendering timestamp should occur before the entry is dispatched to the observer.');
|
||||
assert_equals(entry.startTime, 0);
|
||||
assert_equals(entry.duration, 0);
|
||||
// blue.png is 133 x 106.
|
||||
assert_equals(entry.size, 14098);
|
||||
assert_equals(entry.id, 'image_id');
|
||||
// 25 is the length of "largest-contentful-paint/".
|
||||
const index = window.location.href.lastIndexOf('/') - 25;
|
||||
const pathname = window.location.href.substring(0, index) + '/images/blue.png';
|
||||
assert_equals(entry.url, pathname);
|
||||
assert_greater_than(entry.loadTime, beforeRender,
|
||||
'The load timestamp should occur after script starts running.');
|
||||
assert_less_than(entry.loadTime, entry.renderTime,
|
||||
'The load timestamp should occur before the render timestamp.')
|
||||
assert_equals(entry.element, document.getElementById('image_id'));
|
||||
})
|
||||
);
|
||||
observer.observe({type: 'largest-contentful-paint', buffered: true});
|
||||
}, 'Same-origin image after a JS initiated scroll event is observable.');
|
||||
document.body.dispatchEvent(new Event('scroll'));
|
||||
const image = new Image();
|
||||
image.id = 'image_id';
|
||||
image.src = '/images/blue.png';
|
||||
document.body.appendChild(image);
|
||||
</script>
|
||||
|
||||
</body>
|
|
@ -0,0 +1,12 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<p>Text</p>
|
||||
<script>
|
||||
const observer = new PerformanceObserver(entryList => {
|
||||
window.parent.triggerTest(entryList.getEntries()[0]);
|
||||
});
|
||||
observer.observe({type: 'largest-contentful-paint', buffered: true});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -62,5 +62,7 @@
|
|||
</math>
|
||||
</p>
|
||||
|
||||
<script src="/mathml/support/feature-detection.js"></script>
|
||||
<script>MathMLFeatureDetection.ensure_for_match_reftest("has_mspace");</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -6,15 +6,11 @@
|
|||
</head>
|
||||
<body>
|
||||
|
||||
<!-- Test dir="rtl" on MathML token elements. The text contains RTL and
|
||||
LTR characters, so the attribute is needed to specify the actual
|
||||
direction. -->
|
||||
|
||||
<p><math><mtext dir="rtl">חוק \left חסר או חוק \right מיותר</mtext></math></p>
|
||||
<p><math><ms dir="rtl">חוק \left חסר או חוק \right מיותר</ms></math></p>
|
||||
<p><math><mo dir="rtl">חוק \left חסר או חוק \right מיותר</mo></math></p>
|
||||
<p><math><mi dir="rtl">חוק \left חסר או חוק \right מיותר</mi></math></p>
|
||||
<p><math><mn dir="rtl">חוק \left חסר או חוק \right מיותר</mn></math></p>
|
||||
<p><math><mtext style="direction: rtl;">חוק \left חסר או חוק \right מיותר</mtext></math></p>
|
||||
<p><math><ms style="direction: rtl;">חוק \left חסר או חוק \right מיותר</ms></math></p>
|
||||
<p><math><mo style="direction: rtl;">חוק \left חסר או חוק \right מיותר</mo></math></p>
|
||||
<p><math><mi style="direction: rtl;">חוק \left חסר או חוק \right מיותר</mi></math></p>
|
||||
<p><math><mn style="direction: rtl;">חוק \left חסר או חוק \right מיותר</mn></math></p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -21,5 +21,8 @@
|
|||
<p><math><mi dir="rtl">חוק \left חסר או חוק \right מיותר</mi></math></p>
|
||||
<p><math><mn dir="rtl">חוק \left חסר או חוק \right מיותר</mn></math></p>
|
||||
|
||||
<script src="/mathml/support/feature-detection.js"></script>
|
||||
<script>MathMLFeatureDetection.ensure_for_match_reftest("has_dir");</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
<meta name="assert" content="Verify fraction metrics for different sizes of numerator and denominator.">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/mathml/support/feature-detection.js"></script>
|
||||
<style>
|
||||
math, mspace {
|
||||
font-size: 10px;
|
||||
|
@ -33,6 +34,8 @@
|
|||
|
||||
function runTests() {
|
||||
test(function() {
|
||||
assert_true(MathMLFeatureDetection.has_mspace());
|
||||
|
||||
var e = 3;
|
||||
var mathAxis = getBox("axis").middle;
|
||||
// For stacks, nothing in the OpenType MATH specification seems to ensure
|
||||
|
@ -51,6 +54,8 @@
|
|||
}, "Fraction axis is aligned on the math axis");
|
||||
|
||||
test(function() {
|
||||
assert_true(MathMLFeatureDetection.has_mspace());
|
||||
|
||||
for (var i = 0; i < 10; i++) {
|
||||
assert_less_than(getBox("frac" + i + "num").bottom, getBox("frac" + i + "den").top, "numerator is above denominator");
|
||||
assert_less_than(getBox("frac" + i + "den").top - getBox("frac" + i + "num").bottom, 5, "The gap between numerator and denominator is not too large");
|
||||
|
@ -58,12 +63,16 @@
|
|||
}, "Vertical positions of numerator and denominator");
|
||||
|
||||
test(function() {
|
||||
assert_true(MathMLFeatureDetection.has_mspace());
|
||||
|
||||
var e = 3;
|
||||
for (var i = 0; i < 10; i++)
|
||||
assert_approx_equals(getBox("frac" + i + "num").center, getBox("frac" + i + "den").center, e, "numerator and denominator are horizontally centered");
|
||||
}, "Horizontal alignments of numerator and denominator");
|
||||
|
||||
test(function() {
|
||||
assert_true(MathMLFeatureDetection.has_mspace());
|
||||
|
||||
var e = 5;
|
||||
for (var i = 0; i < 10; i++) {
|
||||
var frac = getBox("frac" + i);
|
||||
|
|
|
@ -51,5 +51,7 @@
|
|||
</mfrac>
|
||||
</math>
|
||||
</div>
|
||||
<script src="/mathml/support/feature-detection.js"></script>
|
||||
<script>MathMLFeatureDetection.ensure_for_match_reftest("has_mfrac");</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -28,5 +28,7 @@
|
|||
</mfrac>
|
||||
</math>
|
||||
</div>
|
||||
<script src="/mathml/support/feature-detection.js"></script>
|
||||
<script>MathMLFeatureDetection.ensure_for_match_reftest("has_mfrac");</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -37,6 +37,8 @@
|
|||
</head>
|
||||
<body>
|
||||
<p>This test passes if it renders the same as an invalid fraction with 3 children.</p>
|
||||
<math>
|
||||
<math></math>
|
||||
<script src="/mathml/support/feature-detection.js"></script>
|
||||
<script>MathMLFeatureDetection.ensure_for_match_reftest("has_mfrac");</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -30,5 +30,7 @@
|
|||
<mn id="mn2">2</mn>
|
||||
</mfrac>
|
||||
</math>
|
||||
<script src="/mathml/support/feature-detection.js"></script>
|
||||
<script>MathMLFeatureDetection.ensure_for_match_reftest("has_mfrac");</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -32,6 +32,8 @@
|
|||
</head>
|
||||
<body>
|
||||
<p>This test passes if you see a fraction.</p>
|
||||
<math>
|
||||
<math></math>
|
||||
<script src="/mathml/support/feature-detection.js"></script>
|
||||
<script>MathMLFeatureDetection.ensure_for_match_reftest("has_mfrac");</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -41,5 +41,7 @@
|
|||
<mspace width="20px" height="10px" style="background: cyan"></mspace>
|
||||
</mfrac>
|
||||
</math>
|
||||
<script src="/mathml/support/feature-detection.js"></script>
|
||||
<script>MathMLFeatureDetection.ensure_for_match_reftest("has_mfrac");</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
<meta name="assert" content="Verifies fraction with positive, negative, percent and named space linethickness values.">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/mathml/support/feature-detection.js"></script>
|
||||
<style type="text/css">
|
||||
@font-face {
|
||||
font-family: TestFont;
|
||||
|
@ -37,19 +38,23 @@
|
|||
var epsilon = 2;
|
||||
|
||||
test(function() {
|
||||
assert_true(MathMLFeatureDetection.has_mspace());
|
||||
assert_approx_equals(LineThickness("positive"), 5.67 * 10, epsilon);
|
||||
}, "Positive");
|
||||
|
||||
test(function() {
|
||||
assert_true(MathMLFeatureDetection.has_mspace());
|
||||
/* Negative values are treated as 0 */
|
||||
assert_approx_equals(LineThickness("negative"), 0, epsilon);
|
||||
}, "Negative");
|
||||
|
||||
test(function() {
|
||||
assert_true(MathMLFeatureDetection.has_mspace());
|
||||
assert_approx_equals(LineThickness("percent"), defaultRuleThickness * 234 / 100, epsilon);
|
||||
}, "Percentage");
|
||||
|
||||
test(function() {
|
||||
assert_true(MathMLFeatureDetection.has_mspace());
|
||||
/* Namedspace values are invalid in MathML Core. */
|
||||
assert_approx_equals(LineThickness("namedspace"), defaultRuleThickness, epsilon);
|
||||
}, "Named space");
|
||||
|
|
|
@ -26,5 +26,7 @@
|
|||
<mspace width="20px" height="10px" style="background: cyan"></mspace>
|
||||
</mfrac>
|
||||
</math>
|
||||
<script src="/mathml/support/feature-detection.js"></script>
|
||||
<script>MathMLFeatureDetection.ensure_for_match_reftest("has_mfrac");</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -22,5 +22,7 @@
|
|||
</mrow>
|
||||
</mfrac>
|
||||
</math>
|
||||
<script src="/mathml/support/feature-detection.js"></script>
|
||||
<script>MathMLFeatureDetection.ensure_for_match_reftest("has_mfrac");</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -52,5 +52,7 @@
|
|||
</mfrac>
|
||||
</math>
|
||||
</p>
|
||||
<script src="/mathml/support/feature-detection.js"></script>
|
||||
<script>MathMLFeatureDetection.ensure_for_match_reftest("has_mfrac");</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
<meta name="assert" content="Element mfrac correctly uses the fraction parameters from the MATH table.">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/mathml/support/feature-detection.js"></script>
|
||||
<style>
|
||||
math, mspace {
|
||||
font-size: 10px;
|
||||
|
@ -68,6 +69,8 @@
|
|||
|
||||
function runTests() {
|
||||
test(function() {
|
||||
assert_true(MathMLFeatureDetection.has_mspace());
|
||||
|
||||
var v1 = 7000 * emToPx;
|
||||
var v2 = 1000 * emToPx;
|
||||
assert_approx_equals(getBox("ref0001").top - getBox("num0001").bottom,
|
||||
|
@ -75,54 +78,72 @@
|
|||
}, "AxisHeight");
|
||||
|
||||
test(function() {
|
||||
assert_true(MathMLFeatureDetection.has_mspace());
|
||||
|
||||
var v1 = 5000 * emToPx;
|
||||
assert_approx_equals(getBox("den0002").top - getBox("ref0002").bottom,
|
||||
v1, epsilon, "mfrac: denominator gap");
|
||||
}, "DenominatorDisplayStyleGapMin");
|
||||
|
||||
test(function() {
|
||||
assert_true(MathMLFeatureDetection.has_mspace());
|
||||
|
||||
var v1 = 6000 * emToPx;
|
||||
assert_approx_equals(getBox("den0003").top - getBox("ref0003").bottom,
|
||||
v1, epsilon, "mfrac: denominator shift");
|
||||
}, "DenominatorDisplayStyleShiftDown");
|
||||
|
||||
test(function() {
|
||||
assert_true(MathMLFeatureDetection.has_mspace());
|
||||
|
||||
var v1 = 4000 * emToPx;
|
||||
assert_approx_equals(getBox("den0004").top - getBox("ref0004").bottom,
|
||||
v1, epsilon, "mfrac: denominator gap");
|
||||
}, "DenominatorGapMin");
|
||||
|
||||
test(function() {
|
||||
assert_true(MathMLFeatureDetection.has_mspace());
|
||||
|
||||
var v1 = 3000 * emToPx;
|
||||
assert_approx_equals(getBox("den0005").top - getBox("ref0005").bottom,
|
||||
v1, epsilon, "mfrac: denominator shift");
|
||||
}, "DenominatorShiftDown");
|
||||
|
||||
test(function() {
|
||||
assert_true(MathMLFeatureDetection.has_mspace());
|
||||
|
||||
var v1 = 8000 * emToPx;
|
||||
assert_approx_equals(getBox("ref0006").top - getBox("num0006").bottom,
|
||||
v1, epsilon, "mfrac: numerator gap");
|
||||
}, "NumeratorDisplayStyleGapMin");
|
||||
|
||||
test(function() {
|
||||
assert_true(MathMLFeatureDetection.has_mspace());
|
||||
|
||||
var v1 = 2000 * emToPx;
|
||||
assert_approx_equals(getBox("ref0007").top - getBox("num0007").bottom,
|
||||
v1, epsilon, "mfrac: numerator shift");
|
||||
}, "NumeratorDisplayStyleShiftDown");
|
||||
|
||||
test(function() {
|
||||
assert_true(MathMLFeatureDetection.has_mspace());
|
||||
|
||||
var v1 = 9000 * emToPx;
|
||||
assert_approx_equals(getBox("ref0008").top - getBox("num0008").bottom,
|
||||
v1, epsilon, "mfrac: numerator gap");
|
||||
}, "NumeratorGapMin");
|
||||
|
||||
test(function() {
|
||||
assert_true(MathMLFeatureDetection.has_mspace());
|
||||
|
||||
var v1 = 11000 * emToPx;
|
||||
assert_approx_equals(getBox("ref0009").top - getBox("num0009").bottom,
|
||||
v1, epsilon, "mfrac: numerator shift");
|
||||
}, "NumeratorShiftDown");
|
||||
|
||||
test(function() {
|
||||
assert_true(MathMLFeatureDetection.has_mspace());
|
||||
|
||||
var v1 = 10000 * emToPx;
|
||||
assert_approx_equals(getBox("den0010").top - getBox("num0010").bottom,
|
||||
v1, epsilon, "mfrac: rule thickness");
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
<meta name="assert" content="Element mfrac correctly uses the stack parameters from the MATH table.">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/mathml/support/feature-detection.js"></script>
|
||||
<style>
|
||||
math, mspace {
|
||||
font-size: 10px;
|
||||
|
@ -56,42 +57,56 @@
|
|||
|
||||
function runTests() {
|
||||
test(function() {
|
||||
assert_true(MathMLFeatureDetection.has_mspace());
|
||||
|
||||
var v = 7000 * emToPx;
|
||||
assert_approx_equals(getBox("ref0001").top - getBox("num0001").bottom,
|
||||
v, epsilon, "mfrac: axis height");
|
||||
}, "AxisHeight");
|
||||
|
||||
test(function() {
|
||||
assert_true(MathMLFeatureDetection.has_mspace());
|
||||
|
||||
var v = 5000 * emToPx;
|
||||
assert_approx_equals(getBox("den0002").top - getBox("ref0002").bottom,
|
||||
v, epsilon, "mfrac: denominator shift");
|
||||
}, "BottomDisplayStyleShiftDown");
|
||||
|
||||
test(function() {
|
||||
assert_true(MathMLFeatureDetection.has_mspace());
|
||||
|
||||
var v = 6000 * emToPx;
|
||||
assert_approx_equals(getBox("den0003").top - getBox("ref0003").bottom,
|
||||
v, epsilon, "mfrac: denominator shift");
|
||||
}, "BottomShiftDown");
|
||||
|
||||
test(function() {
|
||||
assert_true(MathMLFeatureDetection.has_mspace());
|
||||
|
||||
var v = 4000 * emToPx;
|
||||
assert_approx_equals(getBox("den0004").top - getBox("num0004").bottom,
|
||||
v, epsilon, "mfrac: gap");
|
||||
}, "DisplayStyleGapMin");
|
||||
|
||||
test(function() {
|
||||
assert_true(MathMLFeatureDetection.has_mspace());
|
||||
|
||||
var v = 8000 * emToPx;
|
||||
assert_approx_equals(getBox("den0005").top - getBox("num0005").bottom,
|
||||
v, epsilon, "mfrac: gap");
|
||||
}, "GapMin");
|
||||
|
||||
test(function() {
|
||||
assert_true(MathMLFeatureDetection.has_mspace());
|
||||
|
||||
var v = 3000 * emToPx;
|
||||
assert_approx_equals(getBox("ref0006").top - getBox("num0006").bottom,
|
||||
v, epsilon, "mfrac: numerator shift");
|
||||
}, "TopDisplayStyleShiftUp");
|
||||
|
||||
test(function() {
|
||||
assert_true(MathMLFeatureDetection.has_mspace());
|
||||
|
||||
var v = 9000 * emToPx;
|
||||
assert_approx_equals(getBox("ref0007").top - getBox("num0007").bottom,
|
||||
v, epsilon, "mfrac: numerator shift");
|
||||
|
|
|
@ -86,5 +86,7 @@
|
|||
</math>
|
||||
</p>
|
||||
<div id="frame"></div>
|
||||
<script src="/mathml/support/feature-detection.js"></script>
|
||||
<script>MathMLFeatureDetection.ensure_for_match_reftest("has_mfrac");</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -86,5 +86,7 @@
|
|||
</math>
|
||||
</p>
|
||||
<div id="frame"></div>
|
||||
<script src="/mathml/support/feature-detection.js"></script>
|
||||
<script>MathMLFeatureDetection.ensure_for_match_reftest("has_mfrac");</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -86,5 +86,7 @@
|
|||
</math>
|
||||
</p>
|
||||
<div id="frame"></div>
|
||||
<script src="/mathml/support/feature-detection.js"></script>
|
||||
<script>MathMLFeatureDetection.ensure_for_match_reftest("has_mfrac");</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -86,5 +86,7 @@
|
|||
</math>
|
||||
</p>
|
||||
<div id="frame"></div>
|
||||
<script src="/mathml/support/feature-detection.js"></script>
|
||||
<script>MathMLFeatureDetection.ensure_for_match_reftest("has_mfrac");</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -86,5 +86,7 @@
|
|||
</math>
|
||||
</p>
|
||||
<div id="frame"></div>
|
||||
<script src="/mathml/support/feature-detection.js"></script>
|
||||
<script>MathMLFeatureDetection.ensure_for_match_reftest("has_mfrac");</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -86,5 +86,7 @@
|
|||
</math>
|
||||
</p>
|
||||
<div id="frame"></div>
|
||||
<script src="/mathml/support/feature-detection.js"></script>
|
||||
<script>MathMLFeatureDetection.ensure_for_match_reftest("has_mfrac");</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -18,5 +18,7 @@
|
|||
</mfrac>
|
||||
</math>
|
||||
</div>
|
||||
<script src="/mathml/support/feature-detection.js"></script>
|
||||
<script>MathMLFeatureDetection.ensure_for_match_reftest("has_mfrac");</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#enclose-expression-inside-notation-menclose">
|
||||
<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#adjust-space-around-content-mpadded">
|
||||
<meta name="assert" content="Baseline for mrow-like elements is correct.">
|
||||
<script src="/mathml/support/feature-detection.js"></script>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script type="text/javascript">
|
||||
|
@ -23,6 +24,7 @@
|
|||
var x = document.getElementById("above" + tag).getBoundingClientRect();
|
||||
var y = document.getElementById("below" + tag).getBoundingClientRect();
|
||||
test(function() {
|
||||
assert_true(MathMLFeatureDetection.has_mspace());
|
||||
assert_equals(x.bottom, y.top);
|
||||
}, "baseline alignment inside " + tag);
|
||||
});
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#adjust-space-around-content-mpadded">
|
||||
<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#operator-fence-separator-or-accent-mo">
|
||||
<meta name="assert" content="Operators can stretch inside mrow-like elements.">
|
||||
<script src="/mathml/support/feature-detection.js"></script>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<style>
|
||||
|
@ -36,6 +37,7 @@
|
|||
["Mrow", "Sqrt", "Style", "Error", "Phantom", "Math", "Menclose", "Mpadded"].forEach((tag) => {
|
||||
var mo = document.getElementById("mo" + tag);
|
||||
test(function() {
|
||||
assert_true(MathMLFeatureDetection.has_mspace());
|
||||
assert_greater_than_equal(mo.getBoundingClientRect().height, 100);
|
||||
}, "operator stretching inside " + tag);
|
||||
});
|
||||
|
|
|
@ -0,0 +1,155 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Embellished operators</title>
|
||||
<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
|
||||
<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#embellished-operators">
|
||||
<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#definition-of-space-like-elements">
|
||||
<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#layout-of-mrow">
|
||||
<meta name="assert" content="Verify definition of embellished operators">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/mathml/support/feature-detection.js"></script>
|
||||
<style>
|
||||
/* Default spacing of operator 'X' is 0.2777777777777778em so quite different
|
||||
from the measured/specified 0em and 1em. */
|
||||
math, math * {
|
||||
font: 25px/1 Ahem;
|
||||
}
|
||||
mn {
|
||||
color: black;
|
||||
}
|
||||
.testedElement mo {
|
||||
color: yellow !important;
|
||||
}
|
||||
.testedElement, .testedElement * {
|
||||
color: blue !important;
|
||||
background: blue !important;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
function spaceBeforeElement(id) {
|
||||
var element = document.getElementById(id);
|
||||
var mnBefore = element.previousElementSibling;
|
||||
return element.getBoundingClientRect().left - mnBefore.getBoundingClientRect().right;
|
||||
}
|
||||
|
||||
function spaceBeforeCoreOperator(id) {
|
||||
var element = document.getElementById(id);
|
||||
var coreMo = element.getElementsByTagName("mo")[0];
|
||||
return coreMo.getBoundingClientRect().left - element.getBoundingClientRect().left;
|
||||
}
|
||||
|
||||
setup({ explicit_done: true });
|
||||
window.addEventListener("load", runTests);
|
||||
|
||||
function runTests() {
|
||||
var epsilon = 1;
|
||||
var emToPx = 25;
|
||||
|
||||
["mrow", "mstyle", "mphantom", "mpadded"].forEach(tag => {
|
||||
test(function() {
|
||||
assert_true(MathMLFeatureDetection.has_operator_spacing());
|
||||
assert_approx_equals(spaceBeforeElement(`${tag}-op`), 2 * emToPx, epsilon);
|
||||
assert_approx_equals(spaceBeforeCoreOperator(`${tag}-op`), 0, epsilon);
|
||||
}, `${tag} (embellished operator)`);
|
||||
|
||||
test(function() {
|
||||
assert_true(MathMLFeatureDetection.has_operator_spacing());
|
||||
assert_approx_equals(spaceBeforeElement(`${tag}-nonop`), 0, epsilon);
|
||||
assert_approx_equals(spaceBeforeCoreOperator(`${tag}-nonop`), 2 * emToPx, epsilon);
|
||||
}, `${tag} (not embellished operator)`);
|
||||
});
|
||||
|
||||
done();
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="log"></div>
|
||||
<p>
|
||||
<math>
|
||||
<mn>X</mn>
|
||||
<mrow id="mrow-op" class="testedElement">
|
||||
<mo lspace="2em" rspace="0em">X</mo>
|
||||
<mtext class="space-like">X</mtext>
|
||||
</mrow>
|
||||
<mn>X</mn>
|
||||
</math>
|
||||
</p>
|
||||
<p>
|
||||
<math>
|
||||
<mn>X</mn>
|
||||
<mrow id="mrow-nonop" class="testedElement">
|
||||
<mo lspace="2em" rspace="0em">X</mo>
|
||||
<mn>X</mn> <!-- "mn" is not space-like -->
|
||||
</mrow>
|
||||
<mn>X</mn>
|
||||
</math>
|
||||
</p>
|
||||
<!-- mstyle is an embellished operator if its children consist
|
||||
of one embellished operator and zero or more space-like elements. -->
|
||||
<p>
|
||||
<math>
|
||||
<mn>X</mn>
|
||||
<mstyle id="mstyle-op" class="testedElement">
|
||||
<mo lspace="2em" rspace="0em">X</mo>
|
||||
</mstyle>
|
||||
<mn>X</mn>
|
||||
</math>
|
||||
</p>
|
||||
<p>
|
||||
<math>
|
||||
<mn>X</mn>
|
||||
<mstyle id="mstyle-nonop" class="testedElement">
|
||||
<mo lspace="2em" rspace="0em">X</mo>
|
||||
<mn>X</mn> <!-- "mn" is not space-like -->
|
||||
</mstyle>
|
||||
<mn>X</mn>
|
||||
</math>
|
||||
</p>
|
||||
<!-- mphantom is an embellished operator if its children consist
|
||||
of one embellished operator and zero or more space-like elements. -->
|
||||
<p>
|
||||
<math>
|
||||
<mn>X</mn>
|
||||
<mphantom id="mphantom-op" class="testedElement">
|
||||
<mo lspace="2em" rspace="0em">X</mo>
|
||||
</mphantom>
|
||||
<mn>X</mn>
|
||||
</math>
|
||||
</p>
|
||||
<p>
|
||||
<math>
|
||||
<mn>X</mn>
|
||||
<mphantom id="mphantom-nonop" class="testedElement">
|
||||
<mo lspace="2em" rspace="0em">X</mo>
|
||||
<mn>X</mn> <!-- "mn" is not space-like -->
|
||||
</mphantom>
|
||||
<mn>X</mn>
|
||||
</math>
|
||||
</p>
|
||||
<!-- mpadded is an embellished operator if its children consist
|
||||
of one embellished operator and zero or more space-like elements. -->
|
||||
<p>
|
||||
<math>
|
||||
<mn>X</mn>
|
||||
<mpadded id="mpadded-op" class="testedElement">
|
||||
<mo lspace="2em" rspace="0em">X</mo>
|
||||
</mpadded>
|
||||
<mn>X</mn>
|
||||
</math>
|
||||
</p>
|
||||
<p>
|
||||
<math>
|
||||
<mn>X</mn>
|
||||
<mpadded id="mpadded-nonop" class="testedElement">
|
||||
<mo lspace="2em" rspace="0em">X</mo>
|
||||
<mn>X</mn> <!-- "mn" is not space-like -->
|
||||
</mpadded>
|
||||
<mn>X</mn>
|
||||
</math>
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,286 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Embellished operators</title>
|
||||
<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
|
||||
<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#embellished-operators">
|
||||
<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#definition-of-space-like-elements">
|
||||
<link rel="help" href="https://mathml-refresh.github.io/mathml-core/#layout-of-mrow">
|
||||
<meta name="assert" content="Verify definition of embellished operators">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/mathml/support/feature-detection.js"></script>
|
||||
<style>
|
||||
/* Default spacing of operator 'X' is 0.2777777777777778em so quite different
|
||||
from the measured/specified 0em and 1em. */
|
||||
math, math * {
|
||||
font: 25px/1 Ahem;
|
||||
}
|
||||
mn {
|
||||
color: black;
|
||||
}
|
||||
mtext.space-like {
|
||||
color: lightblue !important;
|
||||
}
|
||||
.testedElement mo {
|
||||
color: yellow !important;
|
||||
}
|
||||
.testedElement, .testedElement * {
|
||||
color: blue !important;
|
||||
background: blue !important;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
function spaceBeforeElement(element) {
|
||||
var mnBefore = element.previousElementSibling;
|
||||
return element.getBoundingClientRect().left - mnBefore.getBoundingClientRect().right;
|
||||
}
|
||||
|
||||
setup({ explicit_done: true });
|
||||
window.addEventListener("load", runTests);
|
||||
|
||||
function runTests() {
|
||||
var epsilon = 1;
|
||||
var emToPx = 25;
|
||||
|
||||
["msub", "msup", "msubsup", "munder", "mover", "munderover",
|
||||
"mmultiscripts", "mfrac", "maction", "semantics"].forEach(tag => {
|
||||
test(function() {
|
||||
assert_true(MathMLFeatureDetection.has_operator_spacing());
|
||||
var element = document.getElementsByTagName(tag)[0];
|
||||
assert_approx_equals(spaceBeforeElement(element), 2 * emToPx, epsilon);
|
||||
}, `${tag} (embellished operator)`);
|
||||
|
||||
test(function() {
|
||||
assert_true(MathMLFeatureDetection.has_operator_spacing());
|
||||
var element = document.getElementsByTagName(tag)[1];
|
||||
assert_approx_equals(spaceBeforeElement(element), 0, epsilon);
|
||||
}, `${tag} (not embellished operator)`);
|
||||
});
|
||||
done();
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="log"></div>
|
||||
<!-- <msub>, <msup>, <msubsup>, <munder>, <mover>, <munderover>,
|
||||
<mmultiscripts>, <mfrac>, <semantics> or <maction> are embellished
|
||||
operators if their first child exists and is an embellished operator -->
|
||||
<p>
|
||||
<math>
|
||||
<mn>X</mn>
|
||||
<msub class="testedElement">
|
||||
<mo lspace="2em" rspace="0em">X</mo>
|
||||
<mn>X</mn>
|
||||
</msub>
|
||||
<mn>X</mn>
|
||||
</math>
|
||||
</p>
|
||||
<p>
|
||||
<math>
|
||||
<mn>X</mn>
|
||||
<msup class="testedElement">
|
||||
<mo lspace="2em" rspace="0em">X</mo>
|
||||
<mn>X</mn>
|
||||
</msup>
|
||||
<mn>X</mn>
|
||||
</math>
|
||||
</p>
|
||||
<p>
|
||||
<math>
|
||||
<mn>X</mn>
|
||||
<msubsup class="testedElement">
|
||||
<mo lspace="2em" rspace="0em">X</mo>
|
||||
<mn>X</mn>
|
||||
<mn>X</mn>
|
||||
</msubsup>
|
||||
<mn>X</mn>
|
||||
</math>
|
||||
</p>
|
||||
<p>
|
||||
<math>
|
||||
<mn>X</mn>
|
||||
<munder class="testedElement">
|
||||
<mo lspace="2em" rspace="0em">X</mo>
|
||||
<mn>X</mn>
|
||||
</munder>
|
||||
<mn>X</mn>
|
||||
</math>
|
||||
</p>
|
||||
<p>
|
||||
<math>
|
||||
<mn>X</mn>
|
||||
<mover class="testedElement">
|
||||
<mo lspace="2em" rspace="0em">X</mo>
|
||||
<mn>X</mn>
|
||||
</mover>
|
||||
<mn>X</mn>
|
||||
</math>
|
||||
</p>
|
||||
<p>
|
||||
<math>
|
||||
<mn>X</mn>
|
||||
<munderover class="testedElement">
|
||||
<mo lspace="2em" rspace="0em">X</mo>
|
||||
<mn>X</mn>
|
||||
</munderover>
|
||||
<mn>X</mn>
|
||||
</math>
|
||||
</p>
|
||||
<p>
|
||||
<math>
|
||||
<mn>X</mn>
|
||||
<mmultiscripts class="testedElement">
|
||||
<mo lspace="2em" rspace="0em">X</mo>
|
||||
<mn>X</mn>
|
||||
<mn>X</mn>
|
||||
<mn>X</mn>
|
||||
<mn>X</mn>
|
||||
</mmultiscripts>
|
||||
<mn>X</mn>
|
||||
</math>
|
||||
</p>
|
||||
<p>
|
||||
<math>
|
||||
<mn>X</mn>
|
||||
<mfrac class="testedElement">
|
||||
<mo lspace="2em" rspace="0em">X</mo>
|
||||
<mn>X</mn>
|
||||
</mfrac>
|
||||
<mn>X</mn>
|
||||
</math>
|
||||
</p>
|
||||
<p>
|
||||
<math>
|
||||
<mn>X</mn>
|
||||
<maction class="testedElement" actiontype="statusline">
|
||||
<mo lspace="2em" rspace="0em">X</mo>
|
||||
<mn>STATUS MESSAGE</mn>
|
||||
</maction>
|
||||
<mn>X</mn>
|
||||
</math>
|
||||
</p>
|
||||
<p>
|
||||
<math>
|
||||
<mn>X</mn>
|
||||
<semantics class="testedElement">
|
||||
<mo lspace="2em" rspace="0em">X</mo>
|
||||
<annotation>TEXT ANNOTATION</annotation>
|
||||
<mn>X</mn>
|
||||
</semantics>
|
||||
<mn>X</mn>
|
||||
</math>
|
||||
</p>
|
||||
<!-- <msub>, <msup>, <msubsup>, <munder>, <mover>, <munderover>,
|
||||
<mmultiscripts>, <mfrac>, <semantics> or <maction> are not embellished
|
||||
operators if their first child is not an embellished operator -->
|
||||
<p>
|
||||
<math>
|
||||
<mn>X</mn>
|
||||
<msub class="testedElement">
|
||||
<mn>X</mn>
|
||||
<mo lspace="2em" rspace="0em">X</mo>
|
||||
</msub>
|
||||
<mn>X</mn>
|
||||
</math>
|
||||
</p>
|
||||
<p>
|
||||
<math>
|
||||
<mn>X</mn>
|
||||
<msup class="testedElement">
|
||||
<mn>X</mn>
|
||||
<mo lspace="2em" rspace="0em">X</mo>
|
||||
</msup>
|
||||
<mn>X</mn>
|
||||
</math>
|
||||
</p>
|
||||
<p>
|
||||
<math>
|
||||
<mn>X</mn>
|
||||
<msubsup class="testedElement">
|
||||
<mn>X</mn>
|
||||
<mo lspace="2em" rspace="0em">X</mo>
|
||||
<mn>X</mn>
|
||||
</msubsup>
|
||||
<mn>X</mn>
|
||||
</math>
|
||||
</p>
|
||||
<p>
|
||||
<math>
|
||||
<mn>X</mn>
|
||||
<munder class="testedElement">
|
||||
<mn>X</mn>
|
||||
<mo lspace="2em" rspace="0em">X</mo>
|
||||
</munder>
|
||||
<mn>X</mn>
|
||||
</math>
|
||||
</p>
|
||||
<p>
|
||||
<math>
|
||||
<mn>X</mn>
|
||||
<mover class="testedElement">
|
||||
<mn>X</mn>
|
||||
<mo lspace="2em" rspace="0em">X</mo>
|
||||
</mover>
|
||||
<mn>X</mn>
|
||||
</math>
|
||||
</p>
|
||||
<p>
|
||||
<math>
|
||||
<mn>X</mn>
|
||||
<munderover class="testedElement">
|
||||
<mn>X</mn>
|
||||
<mo lspace="2em" rspace="0em">X</mo>
|
||||
</munderover>
|
||||
<mn>X</mn>
|
||||
</math>
|
||||
</p>
|
||||
<p>
|
||||
<math>
|
||||
<mn>X</mn>
|
||||
<mmultiscripts class="testedElement">
|
||||
<mn>X</mn>
|
||||
<mo lspace="2em" rspace="0em">X</mo>
|
||||
<mn>X</mn>
|
||||
<mn>X</mn>
|
||||
<mn>X</mn>
|
||||
</mmultiscripts>
|
||||
<mn>X</mn>
|
||||
</math>
|
||||
</p>
|
||||
<p>
|
||||
<math>
|
||||
<mn>X</mn>
|
||||
<mfrac class="testedElement">
|
||||
<mn>X</mn>
|
||||
<mo lspace="2em" rspace="0em">X</mo>
|
||||
</mfrac>
|
||||
<mn>X</mn>
|
||||
</math>
|
||||
</p>
|
||||
<p>
|
||||
<math>
|
||||
<mn>X</mn>
|
||||
<maction class="testedElement" actiontype="statusline">
|
||||
<mn>X</mn>
|
||||
<mo lspace="2em" rspace="0em">STATUS MESSAGE</mo>
|
||||
</maction>
|
||||
<mn>X</mn>
|
||||
</math>
|
||||
</p>
|
||||
<p>
|
||||
<math>
|
||||
<mn>X</mn>
|
||||
<semantics class="testedElement">
|
||||
<mrow>
|
||||
<mn>X</mn>
|
||||
<mo lspace="2em" rspace="0em">X</mo>
|
||||
</mrow>
|
||||
<annotation>TEXT ANNOTATION</annotation>
|
||||
</semantics>
|
||||
<mn>X</mn>
|
||||
</math>
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
|
@ -7,6 +7,7 @@
|
|||
<meta name="assert" content="Elements msqrt and mroot correctly use the radical parameters from the MATH table.">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/mathml/support/feature-detection.js"></script>
|
||||
<style>
|
||||
math, mspace {
|
||||
font-size: 10px;
|
||||
|
@ -56,6 +57,8 @@
|
|||
|
||||
function runTests() {
|
||||
test(function() {
|
||||
assert_true(MathMLFeatureDetection.has_mspace());
|
||||
|
||||
var v1 = 25;
|
||||
var v2 = 1000 * emToPx;
|
||||
var radicalHeight = getBox("base001").height + v2;
|
||||
|
@ -65,6 +68,8 @@
|
|||
}, "RadicalDegreeBottomRaisePercent");
|
||||
|
||||
test(function() {
|
||||
assert_true(MathMLFeatureDetection.has_mspace());
|
||||
|
||||
var v1 = 7000 * emToPx;
|
||||
var v2 = 1000 * emToPx;
|
||||
assert_approx_equals(getBox("base0021").top - getBox("radical0021").top,
|
||||
|
@ -76,6 +81,8 @@
|
|||
}, "RadicalDisplayStyleVerticalGap");
|
||||
|
||||
test(function() {
|
||||
assert_true(MathMLFeatureDetection.has_mspace());
|
||||
|
||||
var v1 = 3000 * emToPx;
|
||||
var v2 = 1000 * emToPx;
|
||||
assert_approx_equals(getBox("base0031").top - getBox("radical0031").top,
|
||||
|
@ -86,7 +93,9 @@
|
|||
"mroot: vertical gap");
|
||||
}, "RadicalExtraAscender");
|
||||
|
||||
test(function() {
|
||||
test(function() {
|
||||
assert_true(MathMLFeatureDetection.has_mspace());
|
||||
|
||||
// Note: the size variants of U+221A in this font have width 1000.
|
||||
var v1 = 5000 * emToPx;
|
||||
var radicalSymbolWidth = 1000 * emToPx;
|
||||
|
@ -97,6 +106,8 @@
|
|||
}, "RadicalKernAfterDegree");
|
||||
|
||||
test(function() {
|
||||
assert_true(MathMLFeatureDetection.has_mspace());
|
||||
|
||||
var v1 = 4000 * emToPx;
|
||||
assert_approx_equals(getBox("index005").left - getBox("radical005").left,
|
||||
v1, epsilon,
|
||||
|
@ -104,6 +115,8 @@
|
|||
}, "RadicalKernBeforeDegree");
|
||||
|
||||
test(function() {
|
||||
assert_true(MathMLFeatureDetection.has_mspace());
|
||||
|
||||
var v = 8000 * emToPx;
|
||||
assert_approx_equals(getBox("base0061").top - getBox("radical0061").top,
|
||||
v, epsilon,
|
||||
|
@ -114,6 +127,8 @@
|
|||
}, "RadicalRuleThickness");
|
||||
|
||||
test(function() {
|
||||
assert_true(MathMLFeatureDetection.has_mspace());
|
||||
|
||||
var v1 = 6000 * emToPx;
|
||||
var v2 = 1000 * emToPx;
|
||||
assert_approx_equals(getBox("base0071").top - getBox("radical0071").top,
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
<meta name="assert" content="Basic metrics for elements msub, msup and msubsup.">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/mathml/support/feature-detection.js"></script>
|
||||
<style>
|
||||
math, mspace {
|
||||
font-size: 10px;
|
||||
|
@ -28,6 +29,8 @@
|
|||
|
||||
function runTests() {
|
||||
test(function() {
|
||||
assert_true(MathMLFeatureDetection.has_mspace());
|
||||
|
||||
var e = 1;
|
||||
assert_less_than_equal(getBox("msubBase").right, getBox("msubSub").left, e, "msub: subscript is after base");
|
||||
assert_less_than_equal(getBox("msupBase").right, getBox("msupSup").left, e, "msup: superscript is after base");
|
||||
|
@ -43,6 +46,8 @@
|
|||
}, "Respective horizontal positions");
|
||||
|
||||
test(function() {
|
||||
assert_true(MathMLFeatureDetection.has_mspace());
|
||||
|
||||
var e = 1;
|
||||
assert_approx_equals(getBox("msubBase").middle, getBox("baseline").bottom, e, "msub: base is placed on the baseline");
|
||||
assert_approx_equals(getBox("msupBase").middle, getBox("baseline").bottom, e, "msup: base is placed on the baseline");
|
||||
|
@ -50,6 +55,8 @@
|
|||
}, "Alignment of the base on the baseline");
|
||||
|
||||
test(function() {
|
||||
assert_true(MathMLFeatureDetection.has_mspace());
|
||||
|
||||
var e = 3;
|
||||
assert_approx_equals(getBox("msubSub").middle, getBox("msubBase").bottom, e, "msub: script is placed at the bottom of the base");
|
||||
assert_approx_equals(getBox("msupSup").middle, getBox("msupBase").top, e, "msup: script is placed at the top of the base");
|
||||
|
@ -58,6 +65,8 @@
|
|||
}, "Vertical position of scripts");
|
||||
|
||||
test(function() {
|
||||
assert_true(MathMLFeatureDetection.has_mspace());
|
||||
|
||||
var e = 3;
|
||||
assert_approx_equals(getBox("msub").width, getBox("msubSub").right - getBox("msubBase").left, e, "msub: width is determined by the left/right sides of base/script (+ some space after script)");
|
||||
assert_approx_equals(getBox("msup").width, getBox("msupSup").right - getBox("msupBase").left, e, "msup: width is determined by the left/right sides of base/script (+ some space after script)");
|
||||
|
@ -65,6 +74,8 @@
|
|||
}, "Width of scripted elements");
|
||||
|
||||
test(function() {
|
||||
assert_true(MathMLFeatureDetection.has_mspace());
|
||||
|
||||
var e = 1;
|
||||
assert_greater_than_equal(getBox("msub").height, getBox("msubBase").height, e, "msub: height is at least the one of the base");
|
||||
assert_greater_than_equal(getBox("msup").height, getBox("msupBase").height, e, "msup: height is at least the one of the base");
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
<meta name="assert" content="Basic metrics for the mmultiscript element.">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/mathml/support/feature-detection.js"></script>
|
||||
<style>
|
||||
math, mspace {
|
||||
font-size: 10px;
|
||||
|
@ -28,6 +29,8 @@
|
|||
|
||||
function runTests() {
|
||||
test(function() {
|
||||
assert_true(MathMLFeatureDetection.has_mspace());
|
||||
|
||||
var e = 1;
|
||||
assert_less_than_equal(getBox("msubBase").right, getBox("msubSub").left, e, "subscript is after base");
|
||||
assert_less_than_equal(getBox("msupBase").right, getBox("msupSup").left, e, "superscript is after base");
|
||||
|
@ -54,6 +57,8 @@
|
|||
}, "Respective horizontal positions");
|
||||
|
||||
test(function() {
|
||||
assert_true(MathMLFeatureDetection.has_mspace());
|
||||
|
||||
var e = 1;
|
||||
assert_approx_equals(getBox("msubBase").middle, getBox("baseline").bottom, e, "base is placed on the baseline");
|
||||
assert_approx_equals(getBox("msupBase").middle, getBox("baseline").bottom, e, "base is placed on the baseline");
|
||||
|
@ -64,6 +69,8 @@
|
|||
}, "Alignment of the base on the baseline");
|
||||
|
||||
test(function() {
|
||||
assert_true(MathMLFeatureDetection.has_mspace());
|
||||
|
||||
var e = 3;
|
||||
assert_approx_equals(getBox("msubSub").middle, getBox("msubBase").bottom, e, "script is placed at the bottom of the base");
|
||||
assert_approx_equals(getBox("msupSup").middle, getBox("msupBase").top, e, "script is placed at the top of the base");
|
||||
|
@ -77,6 +84,8 @@
|
|||
}, "Vertical position of scripts");
|
||||
|
||||
test(function() {
|
||||
assert_true(MathMLFeatureDetection.has_mspace());
|
||||
|
||||
var e = 3;
|
||||
assert_approx_equals(getBox("msub").width, getBox("msubSub").right - getBox("msubBase").left, e, "width is determined by the left/right sides of base/script (+ some space after script)");
|
||||
assert_approx_equals(getBox("msup").width, getBox("msupSup").right - getBox("msupBase").left, e, "width is determined by the left/right sides of base/script (+ some space after script)");
|
||||
|
@ -88,6 +97,8 @@
|
|||
}, "Width of scripted elements");
|
||||
|
||||
test(function() {
|
||||
assert_true(MathMLFeatureDetection.has_mspace());
|
||||
|
||||
var e = 1;
|
||||
assert_greater_than_equal(getBox("msub").height, getBox("msubBase").height, e, "height is at least the one of the base");
|
||||
assert_greater_than_equal(getBox("msup").height, getBox("msupBase").height, e, "height is at least the one of the base");
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
<meta name="assert" content="Basic metrics for the mmultiscript element with many scripts.">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/mathml/support/feature-detection.js"></script>
|
||||
<style>
|
||||
math, mspace {
|
||||
font-size: 10px;
|
||||
|
@ -28,12 +29,16 @@
|
|||
|
||||
function runTests() {
|
||||
test(function() {
|
||||
assert_true(MathMLFeatureDetection.has_mspace());
|
||||
|
||||
var e = 1;
|
||||
for (var i = 0; i < 5; i++)
|
||||
assert_approx_equals(getBox("multi" + i + "base").middle, getBox("baseline").bottom, e, "base " + i + "is placed on the baseline");
|
||||
}, "Alignment of the base on the baseline");
|
||||
|
||||
test(function() {
|
||||
assert_true(MathMLFeatureDetection.has_mspace());
|
||||
|
||||
var e = 5;
|
||||
assert_approx_equals(getBox("multi0").width, 30, e, "width of multi0");
|
||||
assert_approx_equals(getBox("multi0").height, 30, e, "height of multi0");
|
||||
|
@ -49,6 +54,8 @@
|
|||
}, "Dimensions of the scripted elements");
|
||||
|
||||
test(function() {
|
||||
assert_true(MathMLFeatureDetection.has_mspace());
|
||||
|
||||
var e = 3;
|
||||
for (var i = 2; i <= 4; i++) {
|
||||
var base = getBox("multi" + i + "base");
|
||||
|
@ -66,6 +73,8 @@
|
|||
}, "Vertical positions of scripts");
|
||||
|
||||
test(function() {
|
||||
assert_true(MathMLFeatureDetection.has_mspace());
|
||||
|
||||
var e = 1;
|
||||
for (var i = 2; i <= 4; i++) {
|
||||
var base = getBox("multi" + i + "base");
|
||||
|
@ -81,6 +90,8 @@
|
|||
}, "Horizontal alignment of scripts");
|
||||
|
||||
test(function() {
|
||||
assert_true(MathMLFeatureDetection.has_mspace());
|
||||
|
||||
for (var i = 2; i <= 4; i++) {
|
||||
var base = getBox("multi" + i + "base");
|
||||
var firstPostScript = getBox("multi" + i + "postsub1");
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
<meta name="assert" content="Verify metrics of scripted elements for bases of different heights.">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/mathml/support/feature-detection.js"></script>
|
||||
<style>
|
||||
math, mspace {
|
||||
font-size: 10px;
|
||||
|
@ -30,6 +31,8 @@
|
|||
|
||||
function runTests() {
|
||||
test(function() {
|
||||
assert_true(MathMLFeatureDetection.has_mspace());
|
||||
|
||||
var e = 1;
|
||||
sizeArray.forEach(function(size) {
|
||||
assert_approx_equals(getBox("msub" + size + "base").middle, getBox("baseline").bottom, e, "msub base " + size + "is placed on the baseline");
|
||||
|
@ -40,6 +43,8 @@
|
|||
}, "Alignment on the baseline for bases of different heights");
|
||||
|
||||
test(function() {
|
||||
assert_true(MathMLFeatureDetection.has_mspace());
|
||||
|
||||
var e = 5;
|
||||
sizeArray.forEach(function(size) {
|
||||
assert_approx_equals(getBox("msub" + size + "sub").middle, getBox("msub" + size + "base").bottom, e, "msub script " + size + "is placed at the top of of the base");
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
<meta name="assert" content="Verify metrics of scripted elements with tall scripts.">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/mathml/support/feature-detection.js"></script>
|
||||
<style>
|
||||
math, mspace {
|
||||
font-size: 10px;
|
||||
|
@ -30,6 +31,8 @@
|
|||
|
||||
function runTests() {
|
||||
test(function() {
|
||||
assert_true(MathMLFeatureDetection.has_mspace());
|
||||
|
||||
var e = 1;
|
||||
assert_approx_equals(getBox("msubbase").middle, getBox("baseline").bottom, e, "msub base is placed on the baseline");
|
||||
assert_approx_equals(getBox("msupbase").middle, getBox("baseline").bottom, e, "msup base is placed on the baseline");
|
||||
|
@ -38,6 +41,8 @@
|
|||
}, "Alignment on the baseline with different and large script heights");
|
||||
|
||||
test(function() {
|
||||
assert_true(MathMLFeatureDetection.has_mspace());
|
||||
|
||||
assert_greater_than(getBox("msubsub").top, getBox("msubbase").top, "msub: subscript is below the top of the base");
|
||||
assert_less_than(getBox("msupsup").bottom, getBox("msupbase").bottom, "msup: supscript is above the bottom of the base");
|
||||
assert_greater_than(getBox("msubsupsub").top, getBox("msubsupbase").top, "msubsup: subscript is below the top of the base");
|
||||
|
@ -49,6 +54,8 @@
|
|||
}, "Tall subscripts/superscripts are not placed too high/low");
|
||||
|
||||
test(function() {
|
||||
assert_true(MathMLFeatureDetection.has_mspace());
|
||||
|
||||
assert_greater_than(getBox("msubsupsub").top, getBox("msubsupsup").bottom, "msubsup: subscript is below the superscript");
|
||||
assert_greater_than(getBox("multipresub").top, getBox("multipresup").bottom, "mmultiscripts: presubscript is below the presuperscript");
|
||||
assert_greater_than(getBox("multipostsub").top, getBox("multipostsup").bottom, "mmultiscripts: postsubscript is below the postsuperscript");
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
<meta name="assert" content="Elements msub, msup, subsup and msubsup correctly use the subscript and superscript parameters from the MATH table.">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/mathml/support/feature-detection.js"></script>
|
||||
<style>
|
||||
math, mspace {
|
||||
font-size: 10px;
|
||||
|
@ -68,6 +69,8 @@
|
|||
|
||||
function runTests() {
|
||||
test(function() {
|
||||
assert_true(MathMLFeatureDetection.has_mspace());
|
||||
|
||||
var v = 3000 * emToPx;
|
||||
assert_approx_equals(getBox("ref001").left - getBox("sub001").right, v, epsilon, "msub: Space after subscript");
|
||||
assert_approx_equals(getBox("ref002").left - getBox("sup002").right, v, epsilon, "msup: Space after superscript");
|
||||
|
@ -78,6 +81,8 @@
|
|||
}, "SpaceAfterScript");
|
||||
|
||||
test(function() {
|
||||
assert_true(MathMLFeatureDetection.has_mspace());
|
||||
|
||||
var v = 7000 * emToPx;
|
||||
assert_approx_equals(getBox("ref101").bottom - getBox("sup102").bottom, v, epsilon, "msup: Superscript shift");
|
||||
assert_approx_equals(getBox("ref101").bottom - getBox("sup103").bottom, v, epsilon, "msubsup: Superscript shift");
|
||||
|
@ -87,6 +92,8 @@
|
|||
}, "SuperscriptShiftUp");
|
||||
|
||||
test(function() {
|
||||
assert_true(MathMLFeatureDetection.has_mspace());
|
||||
|
||||
var v = 5000 * emToPx;
|
||||
assert_approx_equals(getBox("ref201").bottom - getBox("sup202").bottom, v, epsilon, "msup: Superscript shift");
|
||||
assert_approx_equals(getBox("ref201").bottom - getBox("sup203").bottom, v, epsilon, "msubsup: Superscript shift");
|
||||
|
@ -96,6 +103,8 @@
|
|||
}, "SuperscriptShiftUpCramped");
|
||||
|
||||
test(function() {
|
||||
assert_true(MathMLFeatureDetection.has_mspace());
|
||||
|
||||
var v = 6000 * emToPx;
|
||||
assert_approx_equals(getBox("sub301").bottom - getBox("ref300").bottom, v, epsilon, "msup: Subscript shift");
|
||||
assert_approx_equals(getBox("sub302").bottom - getBox("ref300").bottom, v, epsilon, "msubsup: Subscript shift");
|
||||
|
@ -104,12 +113,16 @@
|
|||
}, "SubscriptShiftDown");
|
||||
|
||||
test(function() {
|
||||
assert_true(MathMLFeatureDetection.has_mspace());
|
||||
|
||||
var v = 11000 * emToPx;
|
||||
assert_approx_equals(getBox("sub4011").top - getBox("sup4012").bottom, v, epsilon, "msubsup: SubSuperscript gap");
|
||||
assert_approx_equals(getBox("sub4021").top - getBox("sup4022").bottom, v, epsilon, "mmultiscripts: SubSuperscript gap");
|
||||
}, "SubSuperscriptGapMin");
|
||||
|
||||
test(function() {
|
||||
assert_true(MathMLFeatureDetection.has_mspace());
|
||||
|
||||
var v1 = 11000 * emToPx;
|
||||
var v2 = 3000 * emToPx;
|
||||
assert_approx_equals(getBox("sub501").top - getBox("sup501").bottom, v1, epsilon, "msubsup: SubSuperscript gap");
|
||||
|
@ -119,21 +132,29 @@
|
|||
}, "SuperscriptBottomMaxWithSubscript");
|
||||
|
||||
test(function() {
|
||||
assert_true(MathMLFeatureDetection.has_mspace());
|
||||
|
||||
var v = 4000 * emToPx;
|
||||
assert_approx_equals(getBox("ref600").bottom - getBox("sub601").top, v, epsilon, "msub: Subscript top");
|
||||
}, "SubscriptTopMax");
|
||||
|
||||
test(function() {
|
||||
assert_true(MathMLFeatureDetection.has_mspace());
|
||||
|
||||
var v = 8000 * emToPx;
|
||||
assert_approx_equals(getBox("ref700").bottom - getBox("sub701").bottom, v, epsilon, "msub: Superscript bottom");
|
||||
}, "SuperscriptBottomMin");
|
||||
|
||||
test(function() {
|
||||
assert_true(MathMLFeatureDetection.has_mspace());
|
||||
|
||||
var v = 9000 * emToPx;
|
||||
assert_approx_equals(getBox("sub801").bottom - getBox("base801").bottom, v, epsilon, "msub: Superscript drop");
|
||||
}, "SubscriptBaselineDrop");
|
||||
|
||||
test(function() {
|
||||
assert_true(MathMLFeatureDetection.has_mspace());
|
||||
|
||||
var v = 10000 * emToPx;
|
||||
assert_approx_equals(getBox("sup901").bottom - getBox("base901").top, v, epsilon, "msup: Superscript drop");
|
||||
}, "SuperscriptBaselineDrop");
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
<meta name="assert" content="Elements msub, msup, subsup and msubsup correctly use the italic correction from the MATH table.">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/mathml/support/feature-detection.js"></script>
|
||||
<style>
|
||||
math, mspace {
|
||||
font-size: 10px;
|
||||
|
@ -42,6 +43,8 @@
|
|||
var epsilon = 1;
|
||||
function runTests() {
|
||||
test(function() {
|
||||
assert_true(MathMLFeatureDetection.has_mspace());
|
||||
|
||||
var v = 0;
|
||||
assert_approx_equals(getBox("base001").right - getBox("sub001").left, v, epsilon, "msub");
|
||||
assert_approx_equals(getBox("sup002").left, getBox("base002").right, epsilon, "msup");
|
||||
|
@ -50,6 +53,8 @@
|
|||
assert_approx_equals(getBox("sup005").left - getBox("sub005").left, 0, epsilon, "mmultiscripts prescripts");
|
||||
}, "Null Italic Correction");
|
||||
test(function() {
|
||||
assert_true(MathMLFeatureDetection.has_mspace());
|
||||
|
||||
var emToPx = 10 / 1000; // font-size: 10px, font.em = 1000
|
||||
var v = 3000 * emToPx;
|
||||
assert_approx_equals(getBox("base011").right - getBox("sub011").left, v, epsilon, "msub");
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue