diff options
Diffstat (limited to 'testing/web-platform/tests/css/tools/w3ctestlib')
27 files changed, 7556 insertions, 0 deletions
diff --git a/testing/web-platform/tests/css/tools/w3ctestlib/Groups.py b/testing/web-platform/tests/css/tools/w3ctestlib/Groups.py new file mode 100644 index 0000000000..192ae9b6fd --- /dev/null +++ b/testing/web-platform/tests/css/tools/w3ctestlib/Groups.py @@ -0,0 +1,201 @@ +#!/usr/bin/python +# CSS Test Suite Manipulation Library +# Initial code by fantasai, joint copyright 2010 W3C and Microsoft +# Licensed under BSD 3-Clause: <http://www.w3.org/Consortium/Legal/2008/03-bsd-license> + +import shutil +import filecmp +import os.path +import Utils +from os.path import exists, join +from Sources import SourceCache, SourceSet, ConfigSource, ReftestManifest +from Utils import listfiles + +excludeDirs = ['CVS', '.svn', '.hg'] + +class TestGroup: + """Base class for test groups. Should never be used directly. + """ + + @staticmethod + def combine(groupA, groupB): + """Merge TestGroup `groupB` into `groupA`. Return the result of the merge. + Can accept none as arguments. + """ + if groupA and groupB: + groupA.merge(groupB) + return groupA or groupB + + def __init__(self, sourceCache, importDir, name=None, title=None, ui = None, **kwargs): + """Initialize with: + SourceCache `sourceCache` + Group name `name`, which must be a possible directory name or None + Directory path `importDir`, whose context is imported into the group + Option: Tuple of support directory names `supportDirNames` defaults + to ('support',). + Kwarg: File path manifestPath relative to `importDir` that + identifies the reftest manifest file (usually called 'reftest.list'). + Kwarg: File path manifestDest as destination (relative) path for + the reftest manifest file. Defaults to value of manifestPath. + If manifest provided, assumes that only the files listed in the manifest, + the .htaccess files in its parent directory, and the `importDir`'s + .htaccess file and support directory are relevant to the test suite. + """ + assert exists(importDir), "Directory to import %s does not exist" % importDir + + # Save name + self.name = name + self.title = title + + self.ui = ui + + sourceTree = sourceCache.sourceTree + + # Load htaccess + htapath = join(importDir, '.htaccess') + self.htaccess = ConfigSource(sourceTree, htapath, '.htaccess') \ + if exists(htapath) else None + + # Load support files + self.support = SourceSet(sourceCache) + supportDirNames = kwargs.get('supportDirNames', ('support',)) + for supportName in supportDirNames: + supportDir = join(importDir, supportName) + if exists(supportDir): + for (root, dirs, files) in os.walk(supportDir): + for dir in excludeDirs: + if dir in dirs: + dirs.remove(dir) + for name in files: + sourcepath = join(root, name) + relpath = Utils.relpath(sourcepath, importDir) + self.support.add(sourcepath, relpath, self.ui) + + # Load tests + self.tests = SourceSet(sourceCache) + self.refs = SourceSet(sourceCache) + + # Read manifest + manifestPath = kwargs.get('manifestPath', None) + manifestDest = kwargs.get('manifestDest', manifestPath) + if (manifestPath): + self.manifest = ReftestManifest(join(importDir, manifestPath), manifestDest) + + # Import tests + for (testSrc, refSrc), (testRel, refRel), refType in self.manifest: + test = sourceCache.generateSource(testSrc, testRel) + ref = sourceCache.generateSource(refSrc, refRel) + test.addReference(ref, refType) + self.tests.addSource(test, self.ui) + else: + self.manifest = None + # Import tests + fileNameList = [] + if kwargs.get('selfTestExt'): + fileNameList += listfiles(importDir, kwargs['selfTestExt']) + if kwargs.get('selfTestList'): + fileNameList += kwargs['selfTestList'] + for fileName in fileNameList: + filePath = join(importDir, fileName) + if sourceTree.isTestCase(filePath): + test = sourceCache.generateSource(filePath, fileName) + if (test.isTest()): + self.tests.addSource(test, self.ui) + + for test in self.tests.iter(): + if (test.isReftest()): + usedRefs = {} + usedRefs[test.sourcepath] = '==' + def loadReferences(source): # XXX need to verify refType for mutual exclusion (ie: a == b != a) + for refSrcPath, refRelPath, refType in source.getReferencePaths(): + if (exists(refSrcPath)): + ref = sourceCache.generateSource(refSrcPath, refRelPath) + source.addReference(ref) + if (refSrcPath not in usedRefs): + usedRefs[refSrcPath] = refType + if (ref not in self.tests): + self.refs.addSource(ref, self.ui) + loadReferences(ref) + else: + ui.warn("Missing Reference file: ", refSrcPath, "\n referenced from: ", source.sourcepath, "\n") + loadReferences(test) + + + def sourceCache(self): + return self.support.sourceCache + + def count(self): + """Returns number of tests. + """ + return len(self.tests) + + def iterTests(self): + return self.tests.iter() + + def _initFrom(self, group=None): + """Initialize with data from TestGroup `group`.""" + # copy + self.name = group.name if group else None + self.title = group.title if group else None + self.htaccess = group.htaccess if group else None + self.support = group.support if group else None + self.tests = group.tests if group else None + + def merge(self, other): + """Merge Group `other`'s contents into this Group and clear its contents. + """ + assert isinstance(other, TestGroup), \ + "Expected Group instance, got %s" % type(other) + if self.htaccess and other.htaccess: + self.htaccess.append(other.htaccess) + else: + self.htaccess = self.htaccess or other.htaccess + other.htaccess = None + + self.support = SourceSet.combine(self.support, other.support, self.ui) + other.support = None + + self.tests = SourceSet.combine(self.tests, other.tests, self.ui) + other.tests = None + + self.refs = SourceSet.combine(self.refs, other.refs, self.ui) + other.refs = None + if self.manifest and other.manifest: + self.manifest.append(other.manifest) + else: + self.manifest = self.manifest or other.manifest + other.manifest = None + + + def build(self, format): + """Build Group's contents through OutputFormat `format`. + """ + format.setSubDir(self.name) + + # Write .htaccess + if self.htaccess: + format.write(self.htaccess) + + # Write support files + format.convert = False # XXX hack turn off format conversion + self.support.write(format) + format.convert = True # XXX undo hack + + # Write tests + self.tests.adjustContentPaths(format) + self.tests.write(format) + + # Write refs + self.refs.write(format) + if self.manifest: + format.write(self.manifest) + + # copy support files to reference directory (XXX temp until proper support path fixup) + formatDir = format.destDir() + supportDir = join(formatDir, 'support') + referenceDir = join(formatDir, 'reference') + if exists(supportDir) and exists(referenceDir): + shutil.copytree(supportDir, join(referenceDir, 'support')) + + format.setSubDir() + diff --git a/testing/web-platform/tests/css/tools/w3ctestlib/HTMLSerializer.py b/testing/web-platform/tests/css/tools/w3ctestlib/HTMLSerializer.py new file mode 100644 index 0000000000..7f73bc17ec --- /dev/null +++ b/testing/web-platform/tests/css/tools/w3ctestlib/HTMLSerializer.py @@ -0,0 +1,277 @@ +#!/usr/bin/python
+# CSS Test Source Manipulation Library
+# Initial code by fantasai, joint copyright 2010 W3C and Microsoft
+# additions by peter.linss@hp.com copyright 2013 Hewlett-Packard
+# Licensed under BSD 3-Clause: <http://www.w3.org/Consortium/Legal/2008/03-bsd-license>
+
+import lxml
+from lxml import etree
+import htmlentitydefs
+import copy
+
+
+class HTMLSerializer(object):
+
+ gXMLns = 'http://www.w3.org/XML/1998/namespace'
+ gHTMLns = 'http://www.w3.org/1999/xhtml'
+
+ gDefaultNamespaces = {'http://www.w3.org/XML/1998/namespace': 'xmlns',
+ 'http://www.w3.org/2000/xmlns/': 'xmlns',
+ 'http://www.w3.org/1999/xlink': 'xlink'}
+
+ gVoidElements = frozenset((
+ 'base',
+ 'command',
+ 'event-source',
+ 'link',
+ 'meta',
+ 'hr',
+ 'br',
+ 'img',
+ 'embed',
+ 'param',
+ 'area',
+ 'col',
+ 'input',
+ 'source'
+ ))
+
+ gCDataElements = frozenset((
+ 'style',
+ 'script'
+ ))
+
+ gInvisibleChars = frozenset(
+ # ASCII control chars
+ range(0x0, 0x9) + range(0xB, 0xD) + range(0xE, 0x20) +
+ # Other control chars
+ # fixed-width spaces, zero-width marks, bidi marks
+ range(0x2000, 0x2010) +
+ # LS, PS, bidi control codes
+ range(0x2028, 0x2030) +
+ # nbsp, mathsp, ideosp, WJ, interlinear
+ [0x00A0, 0x205F, 0x3000, 0x2060, 0xFFF9, 0xFFFA, 0xFFFB]
+ )
+
+ gXMLEscapes = frozenset(gInvisibleChars |
+ frozenset((ord('&'), ord('<'), ord('>'))))
+
+ gXMLEntityNames = {'"': 'quot', '&': 'amp', "'": 'apos', '<': 'lt', '>': 'gt'}
+
+ gDocTypes = {
+ 'html': '<!DOCTYPE html>',
+ 'html4':
+ '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">',
+ 'html4-transitional':
+ '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">',
+ 'html4-frameset':
+ '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">',
+ 'svg11':
+ '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Basic//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-basic.dtd">',
+ 'svg11-tiny':
+ '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Tiny//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-tiny.dtd">',
+ 'xhtml10':
+ '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">',
+ 'xhtml10-transitional':
+ '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">',
+ 'xhtml10-frameset':
+ '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">',
+ 'xhtml11':
+ '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">',
+ 'xhtml-basic11':
+ '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN" "http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd">'
+ }
+
+
+ def __init__(self):
+ self._reset()
+
+ def _reset(self, xhtml = False):
+ self.mOutput = u''
+ self.mXHTML = xhtml
+
+ def _output(self, *args):
+ for arg in args:
+ self.mOutput += unicode(arg)
+
+ def _escape(self, text, escapeChars):
+ # This algorithm is O(MN) for M len(text) and N num escapable
+ # But it doesn't modify the text when N is zero (common case) and
+ # N is expected to be small (usually 1 or 2) in most other cases.
+ escapable = set()
+ for char in text:
+ if ord(char) in escapeChars:
+ escapable.add(char)
+ for char in escapable:
+ if (self.mXHTML):
+ name = self.gXMLEntityNames.get(char)
+ else:
+ name = htmlentitydefs.codepoint2name.get(ord(char))
+ escape = u'&%s;' % name if name else u'&#x%X;' % ord(char)
+ text = text.replace(char, escape)
+ return text
+
+ def _escapeXML(self, text):
+ return self._escape(text, self.gXMLEscapes)
+
+ def _escapeInvisible(self, text):
+ return self._escape(text, self.gInvisibleChars)
+
+ def _serializeElement(self, element, namespacePrefixes):
+ qName = etree.QName(element)
+ attrs = element.attrib.items() # in tree order
+
+ if (not namespacePrefixes):
+ namespacePrefixes = self.gDefaultNamespaces
+
+ if (self.mXHTML):
+ namespacePrefixes = copy.copy(namespacePrefixes)
+ for attr, value in attrs:
+ attrQName = etree.QName(attr)
+ if (self.gXMLns == attrQName.namespace):
+ namespacePrefixes[value] = attrQName.localname
+ elif ('xmlns' == attrQName.localname):
+ namespacePrefixes[value] = ''
+
+ if (self.mXHTML and qName.namespace and namespacePrefixes[qName.namespace]):
+ self._output('<', namespacePrefixes[qName.namespace], ':', qName.localname)
+ else:
+ self._output('<', qName.localname)
+
+ for attr, value in attrs:
+ attrQName = etree.QName(attr)
+ if ((attrQName.namespace == self.gXMLns) and ('lang' == attrQName.localname)):
+ if (self.mXHTML):
+ attr = 'xml:lang'
+ else:
+ attr = 'lang'
+ elif (attrQName.namespace and namespacePrefixes[attrQName.namespace]):
+ attr = namespacePrefixes[attrQName.namespace] + ':' + attrQName.localname
+ else:
+ attr = attrQName.localname
+
+ self._output(' ', attr, '=')
+ value = value.replace('&', '&')
+ if (self.mXHTML):
+ value = value.replace('<', '<')
+
+ if (('"' in value) and ("'" not in value)):
+ self._output("'", self._escapeInvisible(value), "'")
+ else:
+ self._output('"', self._escapeInvisible(value.replace('"', '"')), '"')
+
+ if ((qName.namespace == self.gHTMLns) and (qName.localname in self.gVoidElements)):
+ if (self.mXHTML):
+ self._output(' />')
+ else:
+ self._output('>')
+ else:
+ self._output('>')
+
+ if (None != element.text):
+ if ((qName.namespace == self.gHTMLns) and (qName.localname in self.gCDataElements)):
+ if (self.mXHTML):
+ self._output(self._escapeXML(element.text)) # or self._output('<![CDATA[', element.text, ']]>')
+ else:
+ self._output(element.text)
+ else:
+ self._output(self._escapeXML(element.text))
+
+ for child in list(element):
+ self._serializeNode(child, namespacePrefixes)
+
+ self._output('</', qName.localname, '>')
+
+ if (None != element.tail):
+ self._output(self._escapeXML(element.tail))
+
+ def _serializeEntity(self, entity):
+ self._output(entity.text)
+ if (None != entity.tail):
+ self._output(self._escapeXML(entity.tail))
+
+ def _serializePI(self, pi):
+ if (self.mXHTML):
+ self._output('<?', pi.target, ' ', pi.text, '?>')
+ else:
+ raise Exception("Processing Instructions can't be converted to HTML")
+ if (None != pi.tail):
+ self._output(self._escapeXML(pi.tail))
+
+ def _serializeComment(self, comment):
+ self._output('<!--', comment.text, '-->') # XXX escape comment?
+ if (None != comment.tail):
+ self._output(self._escapeXML(comment.tail))
+
+ def _serializeNode(self, node, namespacePrefixes = None):
+ if (isinstance(node, etree._Entity)):
+ self._serializeEntity(node)
+ elif (isinstance(node, etree._ProcessingInstruction)):
+ self._serializePI(node)
+ elif (isinstance(node, etree._Comment)):
+ self._serializeComment(node)
+ else:
+ self._serializeElement(node, namespacePrefixes)
+
+
+ def _serializeTree(self, tree):
+ root = tree.getroot()
+ preceding = [node for node in root.itersiblings(preceding = True)]
+ preceding.reverse()
+ for node in preceding:
+ self._serializeNode(node)
+ self._serializeNode(root)
+ for node in root.itersiblings():
+ self._serializeNode(node)
+
+ def _serializeDoctype(self, tree, doctype, default):
+ if (doctype):
+ self._output(self.gDocTypes[doctype], '\n')
+ else:
+ if (hasattr(tree, 'docinfo') and tree.docinfo and tree.docinfo.doctype):
+ doctypeSearch = tree.docinfo.doctype.lower()
+ for doctype in self.gDocTypes:
+ if (self.gDocTypes[doctype].lower() == doctypeSearch):
+ break
+ else:
+ doctype = None
+ if (self.mXHTML):
+ if ('html' == doctype):
+ doctype = 'xhtml10'
+ elif ('html4' == doctype):
+ doctype = 'xhtml10'
+ elif ('html4-transitional' == doctype):
+ doctype = 'xhtml10-transitional'
+ elif ('html4-frameset' == doctype):
+ doctype = 'xhtml10-frameset'
+ else:
+ if ('xhtml10' == doctype):
+ doctype = 'html4'
+ elif ('xhtml10-transitional' == doctype):
+ doctype = 'html4-transitional'
+ elif ('xhtml10-frameset' == doctype):
+ doctype = 'html4-frameset'
+ elif ('xhtml11' == doctype):
+ doctype = 'html4'
+ if (doctype):
+ self._output(self.gDocTypes[doctype], '\n')
+ else:
+ self._output(tree.docinfo.doctype, '\n')
+ else:
+ self._output(self.gDocTypes[default], '\n')
+
+
+ def serializeHTML(self, tree, doctype = None):
+ self._reset()
+ self._serializeDoctype(tree, doctype, 'html')
+ self._serializeTree(tree)
+ return self.mOutput
+
+ def serializeXHTML(self, tree, doctype = None):
+ self._reset(True)
+ # XXX '<!xml ...' ??
+ self._serializeDoctype(tree, doctype, 'xhtml11')
+ self._serializeTree(tree)
+ return self.mOutput
+
+
diff --git a/testing/web-platform/tests/css/tools/w3ctestlib/Indexer.py b/testing/web-platform/tests/css/tools/w3ctestlib/Indexer.py new file mode 100644 index 0000000000..f7e2eb2a17 --- /dev/null +++ b/testing/web-platform/tests/css/tools/w3ctestlib/Indexer.py @@ -0,0 +1,250 @@ +#!/usr/bin/python +# CSS Test Suite Manipulation Library +# Initial code by fantasai, joint copyright 2010 W3C and Microsoft +# Licensed under BSD 3-Clause: <http://www.w3.org/Consortium/Legal/2008/03-bsd-license> + +# Define contains vmethod for Template Toolkit +from template.stash import list_op +@list_op("contains") +def list_contains(l, x): + return x in l + +import sys +import re +import os +import codecs +from os.path import join, exists, abspath +from template import Template +import w3ctestlib +from Utils import listfiles, escapeToNamedASCII +from OutputFormats import ExtensionMap +import shutil + +class Section: + def __init__(self, uri, title, numstr): + self.uri = uri + self.title = title + self.numstr = numstr + self.tests = [] + def __cmp__(self, other): + return cmp(self.natsortkey(), other.natsortkey()) + def chapterNum(self): + return self.numstr.partition('.')[0] + def natsortkey(self): + chunks = self.numstr.partition('.#')[0].split('.') + for index in range(len(chunks)): + if chunks[index].isdigit(): + # wrap in tuple with '0' to explicitly specify numbers come first + chunks[index] = (0, int(chunks[index])) + else: + chunks[index] = (1, chunks[index]) + return (chunks, self.numstr) + +class Indexer: + + def __init__(self, suite, sections, suites, flags, splitChapter=False, templatePathList=None, + extraData=None, overviewTmplNames=None, overviewCopyExts=('.css', 'htaccess')): + """Initialize indexer with TestSuite `suite` toc data file + `tocDataPath` and additional template paths in list `templatePathList`. + + The toc data file should be list of tab-separated records, one + per line, of each spec section's uri, number/letter, and title. + `splitChapter` selects a single page index if False, chapter + indicies if True. + `extraData` can be a dictionary whose data gets passed to the templates. + `overviewCopyExts` lists file extensions that should be found + and copied from the template path into the main build directory. + The default value is ['.css', 'htaccess']. + `overviewTemplateNames` lists template names that should be + processed from the template path into the main build directory. + The '.tmpl' extension, if any, is stripped from the output filename. + The default value is ['index.htm.tmpl', 'index.xht.tmpl', 'testinfo.data.tmpl'] + """ + self.suite = suite + self.splitChapter = splitChapter + self.extraData = extraData + self.overviewCopyExtPat = re.compile('.*(%s)$' % '|'.join(overviewCopyExts)) + self.overviewTmplNames = overviewTmplNames if overviewTmplNames is not None \ + else ['index.htm.tmpl', 'index.xht.tmpl', 'testinfo.data.tmpl', + 'implementation-report-TEMPLATE.data.tmpl'] + + # Initialize template engine + self.templatePath = [join(w3ctestlib.__path__[0], 'templates')] + if templatePathList: + self.templatePath.extend(templatePathList) + self.templatePath = [abspath(path) for path in self.templatePath] + self.tt = Template({ + 'INCLUDE_PATH': self.templatePath, + 'ENCODING' : 'utf-8', + 'PRE_CHOMP' : 1, + 'POST_CHOMP' : 0, + }) + + # Load toc data + self.sections = {} + for uri, numstr, title in sections: + uri = intern(uri.encode('utf-8')) + uriKey = intern(self._normalizeScheme(uri)) + numstr = escapeToNamedASCII(numstr) + title = escapeToNamedASCII(title) if title else None + self.sections[uriKey] = Section(uri, title, numstr) + + self.suites = suites + self.flags = flags + + # Initialize storage + self.errors = {} + self.contributors = {} + self.alltests = [] + + def _normalizeScheme(self, uri): + if (uri and uri.startswith('http:')): + return 'https:' + uri[5:] + return uri + + def indexGroup(self, group): + for test in group.iterTests(): + data = test.getMetadata() + if data: # Shallow copy for template output + data = dict(data) + data['file'] = '/'.join((group.name, test.relpath)) \ + if group.name else test.relpath + if (data['scripttest']): + data['flags'].append(intern('script')) + self.alltests.append(data) + for uri in data['links']: + uri = self._normalizeScheme(uri) + uri = uri.replace(self._normalizeScheme(self.suite.draftroot), self._normalizeScheme(self.suite.specroot)) + if self.sections.has_key(uri): + testlist = self.sections[uri].tests.append(data) + for credit in data['credits']: + self.contributors[credit[0]] = credit[1] + else: + self.errors[test.sourcepath] = test.errors + + def __writeTemplate(self, template, data, outfile): + o = self.tt.process(template, data) + with open(outfile, 'w') as f: + f.write(o.encode('utf-8')) + + def writeOverview(self, destDir, errorOut=sys.stderr, addTests=[]): + """Write format-agnostic pages such as test suite overview pages, + test data files, and error reports. + + Indexed errors are reported to errorOut, which must be either + an output handle such as sys.stderr, a tuple of + (template filename string, output filename string) + or None to suppress error output. + + `addTests` is a list of additional test paths, relative to the + overview root; it is intended for indexing raw tests + """ + + # Set common values + data = self.extraData.copy() + data['suitetitle'] = self.suite.title + data['suite'] = self.suite.name + data['specroot'] = self.suite.specroot + data['draftroot'] = self.suite.draftroot + data['contributors'] = self.contributors + data['tests'] = self.alltests + data['extmap'] = ExtensionMap({'.xht':'', '.html':'', '.htm':'', '.svg':''}) + data['formats'] = self.suite.formats + data['addtests'] = addTests + data['suites'] = self.suites + data['flagInfo'] = self.flags + data['formatInfo'] = { 'html4': { 'report': True, 'path': 'html4', 'ext': 'htm', 'filter': 'nonHTML'}, + 'html5': { 'report': True, 'path': 'html', 'ext': 'htm', 'filter': 'nonHTML' }, + 'xhtml1': { 'report': True, 'path': 'xhtml1', 'ext': 'xht', 'filter': 'HTMLonly' }, + 'xhtml1print': { 'report': False, 'path': 'xhtml1print', 'ext': 'xht', 'filter': 'HTMLonly' }, + 'svg': { 'report': True, 'path': 'svg', 'ext': 'svg', 'filter': 'HTMLonly' } + } + + # Copy simple copy files + for tmplDir in reversed(self.templatePath): + files = listfiles(tmplDir) + for file in files: + if self.overviewCopyExtPat.match(file): + shutil.copy(join(tmplDir, file), join(destDir, file)) + + # Generate indexes + for tmpl in self.overviewTmplNames: + out = tmpl[0:-5] if tmpl.endswith('.tmpl') else tmpl + self.__writeTemplate(tmpl, data, join(destDir, out)) + + # Report errors + if (self.errors): + if type(errorOut) is type(('tmpl','out')): + data['errors'] = errors + self.__writeTemplate(errorOut[0], data, join(destDir, errorOut[1])) + else: + sys.stdout.flush() + for errorLocation in self.errors: + print >> errorOut, "Error in %s: %s" % \ + (errorLocation, ' '.join([str(error) for error in self.errors[errorLocation]])) + + def writeIndex(self, format): + """Write indices into test suite build output through format `format`. + """ + + # Set common values + data = self.extraData.copy() + data['suitetitle'] = self.suite.title + data['suite'] = self.suite.name + data['specroot'] = self.suite.specroot + data['draftroot'] = self.suite.draftroot + + data['indexext'] = format.indexExt + data['isXML'] = format.indexExt.startswith('.x') + data['formatdir'] = format.formatDirName + data['extmap'] = format.extMap + data['tests'] = self.alltests + data['suites'] = self.suites + data['flagInfo'] = self.flags + + # Generate indices: + + # Reftest indices + self.__writeTemplate('reftest-toc.tmpl', data, + format.dest('reftest-toc%s' % format.indexExt)) + self.__writeTemplate('reftest.tmpl', data, + format.dest('reftest.list')) + + # Table of Contents + sectionlist = sorted(self.sections.values()) + if self.splitChapter: + # Split sectionlist into chapters + chapters = [] + lastChapNum = '$' # some nonmatching initial char + chap = None + for section in sectionlist: + if (section.title and (section.chapterNum() != lastChapNum)): + lastChapNum = section.chapterNum() + chap = section + chap.sections = [] + chap.testcount = 0 + chap.testnames = set() + chapters.append(chap) + chap.testnames.update([test['name'] for test in section.tests]) + chap.testcount = len(chap.testnames) + chap.sections.append(section) + + # Generate main toc + data['chapters'] = chapters + self.__writeTemplate('chapter-toc.tmpl', data, + format.dest('toc%s' % format.indexExt)) + del data['chapters'] + + # Generate chapter tocs + for chap in chapters: + data['chaptertitle'] = chap.title + data['testcount'] = chap.testcount + data['sections'] = chap.sections + self.__writeTemplate('test-toc.tmpl', data, format.dest('chapter-%s%s' \ + % (chap.numstr, format.indexExt))) + + else: # not splitChapter + data['chapters'] = sectionlist + self.__writeTemplate('test-toc.tmpl', data, + format.dest('toc%s' % format.indexExt)) + del data['chapters'] diff --git a/testing/web-platform/tests/css/tools/w3ctestlib/OutputFormats.py b/testing/web-platform/tests/css/tools/w3ctestlib/OutputFormats.py new file mode 100644 index 0000000000..084e66d02f --- /dev/null +++ b/testing/web-platform/tests/css/tools/w3ctestlib/OutputFormats.py @@ -0,0 +1,207 @@ +#!/usr/bin/python +# CSS Test Source Manipulation Library +# Initial code by fantasai, joint copyright 2010 W3C and Microsoft +# Licensed under BSD 3-Clause: <http://www.w3.org/Consortium/Legal/2008/03-bsd-license> + +import re +import os +from os.path import join, exists, splitext, dirname, basename +from Sources import XHTMLSource, HTMLSource, SVGSource, SourceTree + +class ExtensionMap: + """ Given a file extension mapping (e.g. {'.xht' : '.htm'}), provides + a translate function for paths. + """ + def __init__(self, extMap): + self.extMap = extMap + + def translate(self, path): + for ext in self.extMap: + if path.endswith(ext): + return splitext(path)[0] + self.extMap[ext] + return path + +class BasicFormat: + """Base class. A Format manages all the conversions and location + transformations (e.g. subdirectory for all tests in that format) + associated with a test suite format. + + The base class implementation performs no conversions or + format-specific location transformations.""" + formatDirName = None + indexExt = '.htm' + convert = True # XXX hack to supress format conversion in support dirs, need to clean up output code to make this cleaner + + def __init__(self, destroot, sourceTree, extMap=None, outputDirName=None): + """Creates format root of the output tree. `destroot` is the root path + of the output tree. + + extMap provides a file extension mapping, e.g. {'.xht' : '.htm'} + """ + self.root = join(destroot, outputDirName) if outputDirName else destroot + self.sourceTree = sourceTree + self.formatDirName = outputDirName + if not exists(self.root): + os.makedirs(self.root) + self.extMap = ExtensionMap(extMap or {}) + self.subdir = None + + def setSubDir(self, name=None): + """Sets format to write into group subdirectory `name`. + """ + self.subdir = name + + def destDir(self): + return join(self.root, self.subdir) if self.subdir else self.root + + def dest(self, relpath): + """Returns final destination of relpath in this format and ensures that the + parent directory exists.""" + # Translate path + if (self.convert): + relpath = self.extMap.translate(relpath) + if (self.sourceTree.isReferenceAnywhere(relpath)): + relpath = join('reference', basename(relpath)) + # XXX when forcing support files into support path, need to account for support/support + dest = join(self.root, self.subdir, relpath) if self.subdir \ + else join(self.root, relpath) + # Ensure parent + parent = dirname(dest) + if not exists(parent): + os.makedirs(parent) + + return dest + + def write(self, source): + """Write FileSource to destination, following all necessary + conversion methods.""" + source.write(self, source) + + testTransform = False + # def testTransform(self, outputString, source) if needed + +class XHTMLFormat(BasicFormat): + """Base class for XHTML test suite format. Builds into 'xhtml1' subfolder + of root. + """ + indexExt = '.xht' + + def __init__(self, destroot, sourceTree, extMap=None, outputDirName='xhtml1'): + if not extMap: + extMap = {'.htm' : '.xht', '.html' : '.xht', '.xhtml' : '.xht' } + BasicFormat.__init__(self, destroot, sourceTree, extMap, outputDirName) + + def write(self, source): + # skip HTMLonly tests + if hasattr(source, 'hasFlag') and source.hasFlag('HTMLonly'): + return + if isinstance(source, HTMLSource) and self.convert: + source.write(self, source.serializeXHTML()) + else: + source.write(self) + +class HTMLFormat(BasicFormat): + """Base class for HTML test suite format. Builds into 'html4' subfolder + of root. + """ + + def __init__(self, destroot, sourceTree, extMap=None, outputDirName='html4'): + if not extMap: + extMap = {'.xht' : '.htm', '.xhtml' : '.htm', '.html' : '.htm' } + BasicFormat.__init__(self, destroot, sourceTree, extMap, outputDirName) + + def write(self, source): + # skip nonHTML tests + if hasattr(source, 'hasFlag') and source.hasFlag('nonHTML'): + return + if isinstance(source, XHTMLSource) and self.convert: + source.write(self, source.serializeHTML()) + else: + source.write(self) + + +class HTML5Format(HTMLFormat): + def __init__(self, destroot, sourceTree, extMap=None, outputDirName='html'): + HTMLFormat.__init__(self, destroot, sourceTree, extMap, outputDirName) + + def write(self, source): + # skip nonHTML tests + if hasattr(source, 'hasFlag') and source.hasFlag('nonHTML'): + return + if isinstance(source, XHTMLSource) and self.convert: + source.write(self, source.serializeHTML()) + else: + source.write(self) + + +class SVGFormat(BasicFormat): + def __init__(self, destroot, sourceTree, extMap=None, outputDirName='svg'): + if not extMap: + extMap = {'.svg' : '.svg' } + BasicFormat.__init__(self, destroot, sourceTree, extMap, outputDirName) + + def write(self, source): + # skip non SVG tests + if isinstance(source, SVGSource): + source.write(self) + + +class XHTMLPrintFormat(XHTMLFormat): + """Base class for XHTML Print test suite format. Builds into 'xhtml1print' + subfolder of root. + """ + + def __init__(self, destroot, sourceTree, testSuiteName, extMap=None, outputDirName='xhtml1print'): + if not extMap: + extMap = {'.htm' : '.xht', '.html' : '.xht', '.xhtml' : '.xht' } + BasicFormat.__init__(self, destroot, sourceTree, extMap, outputDirName) + self.testSuiteName = testSuiteName + + def write(self, source): + if (isinstance(source, XHTMLSource)): + if not source.hasFlag('HTMLonly'): + source.write(self, self.testTransform(source)) + else: + XHTMLFormat.write(self, source) + + def testTransform(self, source): + assert isinstance(source, XHTMLSource) + output = source.serializeXHTML('xhtml10') + + headermeta = {'suitename' : self.testSuiteName, + 'testid' : source.name(), + 'margin' : '', + } + if re.search('@page\s*{[^}]*@', output): + # Don't use headers and footers when page tests margin boxes + output = re.sub('(<body[^>]*>)', + '\1\n' + self.__htmlstart % headermeta, + output); + output = re.sub('(</body[^>]*>)', + '\1\n' + self.__htmlend % headermeta, + output); + else: + # add margin rule only when @page statement does not exist + if not re.search('@page', output): + headermeta['margin'] = self.__margin + output = re.sub('</title>', + '</title>\n <style type="text/css">%s</style>' % \ + (self.__css % headermeta), + output); + return output; + + # template bits + __margin = 'margin: 7%;'; + __font = 'font: italic 8pt sans-serif; color: gray;' + __css = """ + @page { %s + %%(margin)s + counter-increment: page; + @top-left { content: "%%(suitename)s"; } + @top-right { content: "Test %%(testid)s"; } + @bottom-right { content: counter(page); } + } +""" % __font + __htmlstart = '<p style="%s">Start of %%(suitename)s %%(testid)s.</p>' % __font + __htmlend = '<p style="%s">End of %%(suitename)s %%(testid)s.</p>' % __font + diff --git a/testing/web-platform/tests/css/tools/w3ctestlib/Sources.py b/testing/web-platform/tests/css/tools/w3ctestlib/Sources.py new file mode 100644 index 0000000000..f3848030ba --- /dev/null +++ b/testing/web-platform/tests/css/tools/w3ctestlib/Sources.py @@ -0,0 +1,1473 @@ +#!/usr/bin/python +# CSS Test Source Manipulation Library +# Initial code by fantasai, joint copyright 2010 W3C and Microsoft +# Licensed under BSD 3-Clause: <http://www.w3.org/Consortium/Legal/2008/03-bsd-license> + +from __future__ import print_function +from os.path import basename, exists, join +import os +import filecmp +import shutil +import re +import codecs +import collections +from xml import dom +import html5lib +from html5lib import treebuilders +from lxml import etree +from lxml.etree import ParseError +from Utils import getMimeFromExt, escapeToNamedASCII, basepath, isPathInsideBase, relativeURL, assetName +import HTMLSerializer +import warnings +import hashlib + +class SourceTree(object): + """Class that manages structure of test repository source. + Temporarily hard-coded path and filename rules, this should be configurable. + """ + + def __init__(self, repository = None): + self.mTestExtensions = ['.xht', '.html', '.xhtml', '.htm', '.xml', '.svg'] + self.mReferenceExtensions = ['.xht', '.html', '.xhtml', '.htm', '.xml', '.png', '.svg'] + self.mRepository = repository + + def _splitDirs(self, dir): + if ('' == dir): + pathList = [] + elif ('/' in dir): + pathList = dir.split('/') + else: + pathList = dir.split(os.path.sep) + return pathList + + def _splitPath(self, filePath): + """split a path into a list of directory names and the file name + paths may come form the os or mercurial, which always uses '/' as the + directory separator + """ + dir, fileName = os.path.split(filePath.lower()) + return (self._splitDirs(dir), fileName) + + def isTracked(self, filePath): + pathList, fileName = self._splitPath(filePath) + return (not self._isIgnored(pathList, fileName)) + + def _isApprovedPath(self, pathList): + return ((1 < len(pathList)) and ('approved' == pathList[0]) and (('support' == pathList[1]) or ('src' in pathList))) + + def isApprovedPath(self, filePath): + pathList, fileName = self._splitPath(filePath) + return (not self._isIgnored(pathList, fileName)) and self._isApprovedPath(pathList) + + def _isIgnoredPath(self, pathList): + return (('.hg' in pathList) or ('.git' in pathList) or + ('.svn' in pathList) or ('cvs' in pathList) or + ('incoming' in pathList) or ('work-in-progress' in pathList) or + ('data' in pathList) or ('archive' in pathList) or + ('reports' in pathList) or ('tools' == pathList[0]) or + ('test-plan' in pathList) or ('test-plans' in pathList)) + + def _isIgnored(self, pathList, fileName): + if (pathList): # ignore files in root + return (self._isIgnoredPath(pathList) or + fileName.startswith('.directory') or ('lock' == fileName) or + ('.ds_store' == fileName) or + fileName.startswith('.hg') or fileName.startswith('.git') or + ('sections.dat' == fileName) or ('get-spec-sections.pl' == fileName)) + return True + + def isIgnored(self, filePath): + pathList, fileName = self._splitPath(filePath) + return self._isIgnored(pathList, fileName) + + def isIgnoredDir(self, dir): + pathList = self._splitDirs(dir) + return self._isIgnoredPath(pathList) + + def _isToolPath(self, pathList): + return ('tools' in pathList) + + def _isTool(self, pathList, fileName): + return self._isToolPath(pathList) + + def isTool(self, filePath): + pathList, fileName = self._splitPath(filePath) + return (not self._isIgnored(pathList, fileName)) and self._isTool(pathList, fileName) + + def _isSupportPath(self, pathList): + return ('support' in pathList) + + def _isSupport(self, pathList, fileName): + return (self._isSupportPath(pathList) or + ((not self._isTool(pathList, fileName)) and + (not self._isReference(pathList, fileName)) and + (not self._isTestCase(pathList, fileName)))) + + def isSupport(self, filePath): + pathList, fileName = self._splitPath(filePath) + return (not self._isIgnored(pathList, fileName)) and self._isSupport(pathList, fileName) + + def _isReferencePath(self, pathList): + return (('reftest' in pathList) or ('reference' in pathList)) + + def _isReference(self, pathList, fileName): + if ((not self._isSupportPath(pathList)) and (not self._isToolPath(pathList))): + baseName, fileExt = os.path.splitext(fileName)[:2] + if (bool(re.search('(^ref-|^notref-).+', baseName)) or + bool(re.search('.+(-ref[0-9]*$|-notref[0-9]*$)', baseName)) or + ('-ref-' in baseName) or ('-notref-' in baseName)): + return (fileExt in self.mReferenceExtensions) + if (self._isReferencePath(pathList)): + return (fileExt in self.mReferenceExtensions) + return False + + def isReference(self, filePath): + pathList, fileName = self._splitPath(filePath) + return (not self._isIgnored(pathList, fileName)) and self._isReference(pathList, fileName) + + def isReferenceAnywhere(self, filePath): + pathList, fileName = self._splitPath(filePath) + return self._isReference(pathList, fileName) + + def _isTestCase(self, pathList, fileName): + if ((not self._isToolPath(pathList)) and (not self._isSupportPath(pathList)) and (not self._isReference(pathList, fileName))): + fileExt = os.path.splitext(fileName)[1] + return (fileExt in self.mTestExtensions) + return False + + def isTestCase(self, filePath): + pathList, fileName = self._splitPath(filePath) + return (not self._isIgnored(pathList, fileName)) and self._isTestCase(pathList, fileName) + + def getAssetName(self, filePath): + pathList, fileName = self._splitPath(filePath) + if (self._isReference(pathList, fileName) or self._isTestCase(pathList, fileName)): + return assetName(fileName) + return fileName.lower() # support files keep full name + + def getAssetType(self, filePath): + pathList, fileName = self._splitPath(filePath) + if (self._isReference(pathList, fileName)): + return intern('reference') + if (self._isTestCase(pathList, fileName)): + return intern('testcase') + if (self._isTool(pathList, fileName)): + return intern('tool') + return intern('support') + + +class SourceCache: + """Cache for FileSource objects. Supports one FileSource object + per sourcepath. + """ + def __init__(self, sourceTree): + self.__cache = {} + self.sourceTree = sourceTree + + def generateSource(self, sourcepath, relpath, data = None): + """Return a FileSource or derivative based on the extensionMap. + + Uses a cache to avoid creating more than one of the same object: + does not support creating two FileSources with the same sourcepath; + asserts if this is tried. (.htaccess files are not cached.) + + Cache is bypassed if loading form a change context + """ + if ((None == data) and self.__cache.has_key(sourcepath)): + source = self.__cache[sourcepath] + assert relpath == source.relpath + return source + + if basename(sourcepath) == '.htaccess': + return ConfigSource(self.sourceTree, sourcepath, relpath, data) + mime = getMimeFromExt(sourcepath) + if (mime == 'application/xhtml+xml'): + source = XHTMLSource(self.sourceTree, sourcepath, relpath, data) + elif (mime == 'text/html'): + source = HTMLSource(self.sourceTree, sourcepath, relpath, data) + elif (mime == 'image/svg+xml'): + source = SVGSource(self.sourceTree, sourcepath, relpath, data) + elif (mime == 'application/xml'): + source = XMLSource(self.sourceTree, sourcepath, relpath, data) + else: + source = FileSource(self.sourceTree, sourcepath, relpath, mime, data) + if (None == data): + self.__cache[sourcepath] = source + return source + +class SourceSet: + """Set of FileSource objects. No two FileSources of the same type in the set may + have the same name (except .htaccess files, which are merged). + """ + def __init__(self, sourceCache): + self.sourceCache = sourceCache + self.pathMap = {} # type/name -> source + + def __len__(self): + return len(self.pathMap) + + def _keyOf(self, source): + return source.type() + '/' + source.keyName() + + def __contains__(self, source): + return self._keyOf(source) in self.pathMap + + + def iter(self): + """Iterate over FileSource objects in SourceSet. + """ + return self.pathMap.itervalues() + + def addSource(self, source, ui): + """Add FileSource `source`. Throws exception if we already have + a FileSource with the same path relpath but different contents. + (ConfigSources are exempt from this requirement.) + """ + cachedSource = self.pathMap.get(self._keyOf(source)) + if not cachedSource: + self.pathMap[self._keyOf(source)] = source + else: + if source != cachedSource: + if isinstance(source, ConfigSource): + cachedSource.append(source) + else: + ui.warn("File merge mismatch %s vs %s for %s\n" % \ + (cachedSource.sourcepath, source.sourcepath, source.name())) + + def add(self, sourcepath, relpath, ui): + """Generate and add FileSource from sourceCache. Return the resulting + FileSource. + + Throws exception if we already have a FileSource with the same path + relpath but different contents. + """ + source = self.sourceCache.generateSource(sourcepath, relpath) + self.addSource(source, ui) + return source + + @staticmethod + def combine(a, b, ui): + """Merges a and b, and returns whichever one contains the merger (which + one is chosen based on merge efficiency). Can accept None as an argument. + """ + if not (a and b): + return a or b + if len(a) < len(b): + return b.merge(a, ui) + return a.merge(b, ui) + + def merge(self, other, ui): + """Merge sourceSet's contents into this SourceSet. + + Throws a RuntimeError if there's a sourceCache mismatch. + Throws an Exception if two files with the same relpath mismatch. + Returns merge result (i.e. self) + """ + if self.sourceCache is not other.sourceCache: + raise RuntimeError + + for source in other.pathMap.itervalues(): + self.addSource(source, ui) + return self + + def adjustContentPaths(self, format): + for source in self.pathMap.itervalues(): + source.adjustContentPaths(format) + + def write(self, format): + """Write files out through OutputFormat `format`. + """ + for source in self.pathMap.itervalues(): + format.write(source) + + +class StringReader(object): + """Wrapper around a string to give it a file-like api + """ + def __init__(self, string): + self.mString = string + self.mIndex = 0 + + def read(self, maxSize = None): + if (self.mIndex < len(self.mString)): + if (maxSize and (0 < maxSize)): + slice = self.mString[self.mIndex:self.mIndex + maxSize] + self.mIndex += len(slice) + return slice + else: + self.mIndex = len(self.mString) + return self.mString + return '' + + +class NamedDict(object): + def get(self, key): + if (key in self): + return self[key] + return None + + def __eq__(self, other): + for key in self.__slots__: + if (self[key] != other[key]): + return False + return True + + def __ne__(self, other): + for key in self.__slots__: + if (self[key] != other[key]): + return True + return False + + def __len__(self): + return len(self.__slots__) + + def __iter__(self): + return iter(self.__slots__) + + def __contains__(self, key): + return (key in self.__slots__) + + def copy(self): + clone = self.__class__() + for key in self.__slots__: + clone[key] = self[key] + return clone + + def keys(self): + return self.__slots__ + + def has_key(self, key): + return (key in self) + + def items(self): + return [(key, self[key]) for key in self.__slots__] + + def iteritems(self): + return iter(self.items()) + + def iterkeys(self): + return self.__iter__() + + def itervalues(self): + return iter(self.items()) + + def __str__(self): + return '{ ' + ', '.join([key + ': ' + str(self[key]) for key in self.__slots__]) + ' }' + + +class Metadata(NamedDict): + __slots__ = ('name', 'title', 'asserts', 'credits', 'reviewers', 'flags', 'links', 'references', 'revision', 'selftest', 'scripttest') + + def __init__(self, name = None, title = None, asserts = [], credits = [], reviewers = [], flags = [], links = [], + references = [], revision = None, selftest = True, scripttest = False): + self.name = name + self.title = title + self.asserts = asserts + self.credits = credits + self.reviewers = reviewers + self.flags = flags + self.links = links + self.references = references + self.revision = revision + self.selftest = selftest + self.scripttest = scripttest + + def __getitem__(self, key): + if ('name' == key): + return self.name + if ('title' == key): + return self.title + if ('asserts' == key): + return self.asserts + if ('credits' == key): + return self.credits + if ('reviewers' == key): + return self.reviewers + if ('flags' == key): + return self.flags + if ('links' == key): + return self.links + if ('references' == key): + return self.references + if ('revision' == key): + return self.revision + if ('selftest' == key): + return self.selftest + if ('scripttest' == key): + return self.scripttest + return None + + def __setitem__(self, key, value): + if ('name' == key): + self.name = value + elif ('title' == key): + self.title = value + elif ('asserts' == key): + self.asserts = value + elif ('credits' == key): + self.credits = value + elif ('reviewers' == key): + self.reviewers = value + elif ('flags' == key): + self.flags = value + elif ('links' == key): + self.links = value + elif ('references' == key): + self.references = value + elif ('revision' == key): + self.revision = value + elif ('selftest' == key): + self.selftest = value + elif ('scripttest' == key): + self.scripttest = value + else: + raise KeyError() + + +class ReferenceData(NamedDict): + __slots__ = ('name', 'type', 'relpath', 'repopath') + + def __init__(self, name = None, type = None, relpath = None, repopath = None): + self.name = name + self.type = type + self.relpath = relpath + self.repopath = repopath + + def __getitem__(self, key): + if ('name' == key): + return self.name + if ('type' == key): + return self.type + if ('relpath' == key): + return self.relpath + if ('repopath' == key): + return self.repopath + return None + + def __setitem__(self, key, value): + if ('name' == key): + self.name = value + elif ('type' == key): + self.type = value + elif ('relpath' == key): + self.relpath = value + elif ('repopath' == key): + self.repopath = value + else: + raise KeyError() + +UserData = collections.namedtuple('UserData', ('name', 'link')) + +class LineString(str): + def __new__(cls, value, line): + self = str.__new__(cls, value) + self.line = line + return self + + def lineValue(self): + return 'Line ' + str(self.line) + ': ' + str.__str__(self) if (self.line) else str.__str__(self) + + +class FileSource: + """Object representing a file. Two FileSources are equal if they represent + the same file contents. It is recommended to use a SourceCache to generate + FileSources. + """ + + def __init__(self, sourceTree, sourcepath, relpath, mimetype = None, data = None): + """Init FileSource from source path. Give it relative path relpath. + + `mimetype` should be the canonical MIME type for the file, if known. + If `mimetype` is None, guess type from file extension, defaulting to + the None key's value in extensionMap. + + `data` if provided, is a the contents of the file. Otherwise the file is read + from disk. + """ + self.sourceTree = sourceTree + self.sourcepath = sourcepath + self.relpath = relpath + self.mimetype = mimetype or getMimeFromExt(sourcepath) + self._data = data + self.errors = None + self.encoding = 'utf-8' + self.refs = {} + self.scripts = {} + self.metadata = None + self.metaSource = None + + def __eq__(self, other): + if not isinstance(other, FileSource): + return False + return self.sourcepath == other.sourcepath or \ + filecmp.cmp(self.sourcepath, other.sourcepath) + + def __ne__(self, other): + return not self == other + + def __cmp__(self, other): + return cmp(self.name(), other.name()) + + def name(self): + return self.sourceTree.getAssetName(self.sourcepath) + + def keyName(self): + if ('support' == self.type()): + return os.path.relpath(self.relpath, 'support') + return self.name() + + def type(self): + return self.sourceTree.getAssetType(self.sourcepath) + + def relativeURL(self, other): + return relativeURL(self.relpath, other.relpath) + + def data(self): + """Return file contents as a byte string.""" + if (self._data is None): + with open(self.sourcepath, 'r') as f: + self._data = f.read() + if (self._data.startswith(codecs.BOM_UTF8)): + self.encoding = 'utf-8-sig' # XXX look for other unicode BOMs + return self._data + + def unicode(self): + try: + return self.data().decode(self.encoding) + except UnicodeDecodeError: + return None + + def parse(self): + """Parses and validates FileSource data from sourcepath.""" + self.loadMetadata() + + def validate(self): + """Ensure data is loaded from sourcepath.""" + self.parse() + + def adjustContentPaths(self, format): + """Adjust any paths in file content for output format + XXX need to account for group paths""" + if (self.refs): + seenRefs = {} + seenRefs[self.sourcepath] = '==' + def adjustReferences(source): + newRefs = {} + for refName in source.refs: + refType, refPath, refNode, refSource = source.refs[refName] + if refSource: + refPath = relativeURL(format.dest(self.relpath), format.dest(refSource.relpath)) + if (refSource.sourcepath not in seenRefs): + seenRefs[refSource.sourcepath] = refType + adjustReferences(refSource) + else: + refPath = relativeURL(format.dest(self.relpath), format.dest(refPath)) + if (refPath != refNode.get('href')): + refNode.set('href', refPath) + newRefs[refName] = (refType, refPath, refNode, refSource) # update path in metadata + source.refs = newRefs + adjustReferences(self) + + if (self.scripts): # force testharness.js scripts to absolute path + for src in self.scripts: + if (src.endswith('/resources/testharness.js')): # accept relative paths to testharness.js + scriptNode = self.scripts[src] + scriptNode.set('src', '/resources/testharness.js') + elif (src.endswith('/resources/testharnessreport.js')): + scriptNode = self.scripts[src] + scriptNode.set('src', '/resources/testharnessreport.js') + + + def write(self, format): + """Writes FileSource.data() out to `self.relpath` through Format `format`.""" + data = self.data() + with open(format.dest(self.relpath), 'w') as f: + f.write(data) + if (self.metaSource): + self.metaSource.write(format) # XXX need to get output path from format, but not let it choose actual format + + def compact(self): + """Clears all cached data, preserves computed data.""" + pass + + def revision(self): + """Returns hash of the contents of this file and any related file, references, support files, etc. + XXX also needs to account for .meta file + """ + sha = hashlib.sha1() + sha.update(self.data()) + seenRefs = set(self.sourcepath) + def hashReference(source): + for refName in source.refs: + refSource = source.refs[refName][3] + if (refSource and (refSource.sourcepath not in seenRefs)): + sha.update(refSource.data()) + seenRefs.add(refSource.sourcepath) + hashReference(refSource) + hashReference(self) + return sha.hexdigest() + + def loadMetadata(self): + """Look for .meta file and load any metadata from it if present + """ + pass + + def augmentMetadata(self, next=None, prev=None, reference=None, notReference=None): + if (self.metaSource): + return self.metaSource.augmentMetadata(next, prev, reference, notReference) + return None + + # See http://wiki.csswg.org/test/css2.1/format for more info on metadata + def getMetadata(self, asUnicode = False): + """Return dictionary of test metadata. Stores list of errors + in self.errors if there are parse or metadata errors. + Data fields include: + - asserts [list of strings] + - credits [list of (name string, url string) tuples] + - reviewers [ list of (name string, url string) tuples] + - flags [list of token strings] + - links [list of url strings] + - name [string] + - title [string] + - references [list of ReferenceData per reference; None if not reftest] + - revision [revision id of last commit] + - selftest [bool] + - scripttest [bool] + Strings are given in ascii unless asUnicode==True. + """ + + self.validate() + + def encode(str): + return str if (hasattr(str, 'line')) else intern(str.encode('utf-8')) + + def escape(str, andIntern = True): + return str.encode('utf-8') if asUnicode else intern(escapeToNamedASCII(str)) if andIntern else escapeToNamedASCII(str) + + def listReferences(source, seen): + refGroups = [] + for refType, refRelPath, refNode, refSource in source.refs.values(): + if ('==' == refType): + if (refSource): + refSourcePath = refSource.sourcepath + else: + refSourcePath = os.path.normpath(join(basepath(source.sourcepath), refRelPath)) + if (refSourcePath in seen): + continue + seen.add(refSourcePath) + if (refSource): + sourceData = ReferenceData(name = self.sourceTree.getAssetName(refSourcePath), type = refType, + relpath = refRelPath, repopath = refSourcePath) + if (refSource.refs): + subRefLists = listReferences(refSource, seen.copy()) + if (subRefLists): + for subRefList in subRefLists: + refGroups.append([sourceData] + subRefList) + else: + refGroups.append([sourceData]) + else: + refGroups.append([sourceData]) + else: + sourceData = ReferenceData(name = self.sourceTree.getAssetName(refSourcePath), type = refType, + relpath = relativeURL(self.sourcepath, refSourcePath), + repopath = refSourcePath) + refGroups.append([sourceData]) + notRefs = {} + for refType, refRelPath, refNode, refSource in source.refs.values(): + if ('!=' == refType): + if (refSource): + refSourcePath = refSource.sourcepath + else: + refSourcePath = os.path.normpath(join(basepath(source.sourcepath), refRelPath)) + if (refSourcePath in seen): + continue + seen.add(refSourcePath) + if (refSource): + sourceData = ReferenceData(name = self.sourceTree.getAssetName(refSourcePath), type = refType, + relpath = refRelPath, repopath = refSourcePath) + notRefs[sourceData.name] = sourceData + if (refSource.refs): + for subRefList in listReferences(refSource, seen): + for subRefData in subRefList: + notRefs[subRefData.name] = subRefData + else: + sourceData = ReferenceData(name = self.sourceTree.getAssetName(refSourcePath), type = refType, + relpath = relativeURL(self.sourcepath, refSourcePath), + repopath = refSourcePath) + notRefs[sourceData.name] = sourceData + if (notRefs): + for refData in notRefs.values(): + refData.type = '!=' + if (refGroups): + for refGroup in refGroups: + for notRef in notRefs.values(): + for ref in refGroup: + if (ref.name == notRef.name): + break + else: + refGroup.append(notRef) + else: + refGroups.append(notRefs.values()) + return refGroups + + references = listReferences(self, set([self.sourcepath])) if (self.refs) else None + + if (self.metadata): + data = Metadata( + name = encode(self.name()), + title = escape(self.metadata['title'], False), + asserts = [escape(assertion, False) for assertion in self.metadata['asserts']], + credits = [UserData(escape(name), encode(link)) for name, link in self.metadata['credits']], + reviewers = [UserData(escape(name), encode(link)) for name, link in self.metadata['reviewers']], + flags = [encode(flag) for flag in self.metadata['flags']], + links = [encode(link) for link in self.metadata['links']], + references = references, + revision = self.revision(), + selftest = self.isSelftest(), + scripttest = self.isScripttest() + ) + return data + return None + + def addReference(self, referenceSource, match = None): + """Add reference source.""" + self.validate() + refName = referenceSource.name() + refPath = self.relativeURL(referenceSource) + if refName not in self.refs: + node = None + if match == '==': + node = self.augmentMetadata(reference=referenceSource).reference + elif match == '!=': + node = self.augmentMetadata(notReference=referenceSource).notReference + self.refs[refName] = (match, refPath, node, referenceSource) + else: + node = self.refs[refName][2] + node.set('href', refPath) + if (match): + node.set('rel', 'mismatch' if ('!=' == match) else 'match') + else: + match = self.refs[refName][0] + self.refs[refName] = (match, refPath, node, referenceSource) + + def getReferencePaths(self): + """Get list of paths to references as tuple(path, relPath, refType).""" + self.validate() + return [(os.path.join(os.path.dirname(self.sourcepath), ref[1]), + os.path.join(os.path.dirname(self.relpath), ref[1]), + ref[0]) + for ref in self.refs.values()] + + def isTest(self): + self.validate() + return bool(self.metadata) and bool(self.metadata.get('links')) + + def isReftest(self): + return self.isTest() and bool(self.refs) + + def isSelftest(self): + return self.isTest() and (not bool(self.refs)) + + def isScripttest(self): + if (self.isTest() and self.scripts): + for src in self.scripts: + if (src.endswith('/resources/testharness.js')): # accept relative paths to testharness.js + return True + return False + + def hasFlag(self, flag): + data = self.getMetadata() + if data: + return flag in data['flags'] + return False + + + +class ConfigSource(FileSource): + """Object representing a text-based configuration file. + Capable of merging multiple config-file contents. + """ + + def __init__(self, sourceTree, sourcepath, relpath, mimetype = None, data = None): + """Init ConfigSource from source path. Give it relative path relpath. + """ + FileSource.__init__(self, sourceTree, sourcepath, relpath, mimetype, data) + self.sourcepath = [sourcepath] + + def __eq__(self, other): + if not isinstance(other, ConfigSource): + return False + if self is other or self.sourcepath == other.sourcepath: + return True + if len(self.sourcepath) != len(other.sourcepath): + return False + for this, that in zip(self.sourcepath, other.sourcepath): + if not filecmp.cmp(this, that): + return False + return True + + def __ne__(self, other): + return not self == other + + def name(self): + return '.htaccess' + + def type(self): + return intern('support') + + def data(self): + """Merge contents of all config files represented by this source.""" + data = '' + for src in self.sourcepath: + with open(src) as f: + data += f.read() + data += '\n' + return data + + def getMetadata(self, asUnicode = False): + return None + + def append(self, other): + """Appends contents of ConfigSource `other` to this source. + Asserts if self.relpath != other.relpath. + """ + assert isinstance(other, ConfigSource) + assert self != other and self.relpath == other.relpath + self.sourcepath.extend(other.sourcepath) + +class ReftestFilepathError(Exception): + pass + +class ReftestManifest(ConfigSource): + """Object representing a reftest manifest file. + Iterating the ReftestManifest returns (testpath, refpath) tuples + with paths relative to the manifest. + """ + def __init__(self, sourceTree, sourcepath, relpath, data = None): + """Init ReftestManifest from source path. Give it relative path `relpath` + and load its .htaccess file. + """ + ConfigSource.__init__(self, sourceTree, sourcepath, relpath, mimetype = 'config/reftest', data = data) + + def basepath(self): + """Returns the base relpath of this reftest manifest path, i.e. + the parent of the manifest file. + """ + return basepath(self.relpath) + + baseRE = re.compile(r'^#\s*relstrip\s+(\S+)\s*') + stripRE = re.compile(r'#.*') + parseRE = re.compile(r'^\s*([=!]=)\s*(\S+)\s+(\S+)') + + def __iter__(self): + """Parse the reftest manifest files represented by this ReftestManifest + and return path information about each reftest pair as + ((test-sourcepath, ref-sourcepath), (test-relpath, ref-relpath), reftype) + Raises a ReftestFilepathError if any sources file do not exist or + if any relpaths point higher than the relpath root. + """ + striplist = [] + for src in self.sourcepath: + relbase = basepath(self.relpath) + srcbase = basepath(src) + with open(src) as f: + for line in f: + strip = self.baseRE.search(line) + if strip: + striplist.append(strip.group(1)) + line = self.stripRE.sub('', line) + m = self.parseRE.search(line) + if m: + record = ((join(srcbase, m.group(2)), join(srcbase, m.group(3))), \ + (join(relbase, m.group(2)), join(relbase, m.group(3))), \ + m.group(1)) + # for strip in striplist: + # strip relrecord + if not exists(record[0][0]): + raise ReftestFilepathError("Manifest Error in %s: " + "Reftest test file %s does not exist." \ + % (src, record[0][0])) + elif not exists(record[0][1]): + raise ReftestFilepathError("Manifest Error in %s: " + "Reftest reference file %s does not exist." \ + % (src, record[0][1])) + elif not isPathInsideBase(record[1][0]): + raise ReftestFilepathError("Manifest Error in %s: " + "Reftest test replath %s not within relpath root." \ + % (src, record[1][0])) + elif not isPathInsideBase(record[1][1]): + raise ReftestFilepathError("Manifest Error in %s: " + "Reftest test replath %s not within relpath root." \ + % (src, record[1][1])) + yield record + +import Utils # set up XML catalog +xhtmlns = '{http://www.w3.org/1999/xhtml}' +svgns = '{http://www.w3.org/2000/svg}' +xmlns = '{http://www.w3.org/XML/1998/namespace}' +xlinkns = '{http://www.w3.org/1999/xlink}' + +class XMLSource(FileSource): + """FileSource object with support reading XML trees.""" + + NodeTuple = collections.namedtuple('NodeTuple', ['next', 'prev', 'reference', 'notReference']) + + # Public Data + syntaxErrorDoc = \ + u""" + <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> + <html xmlns="http://www.w3.org/1999/xhtml"> + <head><title>Syntax Error</title></head> + <body> + <p>The XML file <![CDATA[%s]]> contains a syntax error and could not be parsed. + Please correct it and try again.</p> + <p>The parser's error report was:</p> + <pre><![CDATA[%s]]></pre> + </body> + </html> + """ + + # Private Data and Methods + __parser = etree.XMLParser(no_network=True, + # perf nightmare dtd_validation=True, + remove_comments=False, + strip_cdata=False, + resolve_entities=False) + + # Public Methods + + def __init__(self, sourceTree, sourcepath, relpath, data = None): + """Initialize XMLSource by loading from XML file `sourcepath`. + Parse errors are reported in `self.errors`, + and the source is replaced with an XHTML error message. + """ + FileSource.__init__(self, sourceTree, sourcepath, relpath, data = data) + self.tree = None + self.injectedTags = {} + + def cacheAsParseError(self, filename, e): + """Replace document with an error message.""" + errorDoc = self.syntaxErrorDoc % (filename, e) + from StringIO import StringIO + self.tree = etree.parse(StringIO(errorDoc), parser=self.__parser) + + def parse(self): + """Parse file and store any parse errors in self.errors""" + self.errors = None + try: + data = self.data() + if (data): + self.tree = etree.parse(StringReader(data), parser=self.__parser) + self.encoding = self.tree.docinfo.encoding or 'utf-8' + self.injectedTags = {} + else: + self.tree = None + self.errors = ['Empty source file'] + self.encoding = 'utf-8' + + FileSource.loadMetadata(self) + if ((not self.metadata) and self.tree and (not self.errors)): + self.extractMetadata(self.tree) + except etree.ParseError as e: + print("PARSE ERROR: " + self.sourcepath) + self.cacheAsParseError(self.sourcepath, e) + e.W3CTestLibErrorLocation = self.sourcepath + self.errors = [str(e)] + self.encoding = 'utf-8' + + def validate(self): + """Parse file if not parsed, and store any parse errors in self.errors""" + if self.tree is None: + self.parse() + + def getMeatdataContainer(self): + return self.tree.getroot().find(xhtmlns+'head') + + def injectMetadataLink(self, rel, href, tagCode = None): + """Inject (prepend) <link> with data given inside metadata container. + Injected element is tagged with `tagCode`, which can be + used to clear it with clearInjectedTags later. + """ + self.validate() + container = self.getMeatdataContainer() + if (container): + node = etree.Element(xhtmlns+'link', {'rel': rel, 'href': href}) + node.tail = container.text + container.insert(0, node) + self.injectedTags[node] = tagCode or True + return node + return None + + def clearInjectedTags(self, tagCode = None): + """Clears all injected elements from the tree, or clears injected + elements tagged with `tagCode` if `tagCode` is given. + """ + if not self.injectedTags or not self.tree: return + for node in self.injectedTags: + node.getparent().remove(node) + del self.injectedTags[node] + + def serializeXML(self): + self.validate() + return etree.tounicode(self.tree) + + def data(self): + if ((not self.tree) or (self.metaSource)): + return FileSource.data(self) + return self.serializeXML().encode(self.encoding, 'xmlcharrefreplace') + + def unicode(self): + if ((not self.tree) or (self.metaSource)): + return FileSource.unicode(self) + return self.serializeXML() + + def write(self, format, output=None): + """Write Source through OutputFormat `format`. + Write contents as string `output` instead if specified. + """ + if not output: + output = self.unicode() + + # write + with open(format.dest(self.relpath), 'w') as f: + f.write(output.encode(self.encoding, 'xmlcharrefreplace')) + + def compact(self): + self.tree = None + + def getMetadataElements(self, tree): + container = self.getMeatdataContainer() + if (None != container): + return [node for node in container] + return None + + def extractMetadata(self, tree): + """Extract metadata from tree.""" + links = []; credits = []; reviewers = []; flags = []; asserts = []; title = '' + + def tokenMatch(token, string): + return bool(re.search('(^|\s+)%s($|\s+)' % token, string)) if (string) else False + + errors = [] + readFlags = False + metaElements = self.getMetadataElements(tree) + if (not metaElements): + errors.append("Missing <head> element") + else: + # Scan and cache metadata + for node in metaElements: + if (node.tag == xhtmlns+'link'): + # help links + if tokenMatch('help', node.get('rel')): + link = node.get('href').strip() if node.get('href') else None + if (not link): + errors.append(LineString("Help link missing href value.", node.sourceline)) + elif (not (link.startswith('http://') or link.startswith('https://'))): + errors.append(LineString("Help link " + link.encode('utf-8') + " must be absolute URL.", node.sourceline)) + elif (link in links): + errors.append(LineString("Duplicate help link " + link.encode('utf-8') + ".", node.sourceline)) + else: + links.append(LineString(link, node.sourceline)) + # == references + elif tokenMatch('match', node.get('rel')) or tokenMatch('reference', node.get('rel')): + refPath = node.get('href').strip() if node.get('href') else None + if (not refPath): + errors.append(LineString("Reference link missing href value.", node.sourceline)) + else: + refName = self.sourceTree.getAssetName(join(self.sourcepath, refPath)) + if (refName in self.refs): + errors.append(LineString("Reference " + refName.encode('utf-8') + " already specified.", node.sourceline)) + else: + self.refs[refName] = ('==', refPath, node, None) + # != references + elif tokenMatch('mismatch', node.get('rel')) or tokenMatch('not-reference', node.get('rel')): + refPath = node.get('href').strip() if node.get('href') else None + if (not refPath): + errors.append(LineString("Reference link missing href value.", node.sourceline)) + else: + refName = self.sourceTree.getAssetName(join(self.sourcepath, refPath)) + if (refName in self.refs): + errors.append(LineString("Reference " + refName.encode('utf-8') + " already specified.", node.sourceline)) + else: + self.refs[refName] = ('!=', refPath, node, None) + else: # may have both author and reviewer in the same link + # credits + if tokenMatch('author', node.get('rel')): + name = node.get('title') + name = name.strip() if name else name + if (not name): + errors.append(LineString("Author link missing name (title attribute).", node.sourceline)) + else: + link = node.get('href').strip() if node.get('href') else None + if (not link): + errors.append(LineString("Author link for \"" + name.encode('utf-8') + "\" missing contact URL (http or mailto).", node.sourceline)) + else: + credits.append((name, link)) + # reviewers + if tokenMatch('reviewer', node.get('rel')): + name = node.get('title') + name = name.strip() if name else name + if (not name): + errors.append(LineString("Reviewer link missing name (title attribute).", node.sourceline)) + else: + link = node.get('href').strip() if node.get('href') else None + if (not link): + errors.append(LineString("Reviewer link for \"" + name.encode('utf-8') + "\" missing contact URL (http or mailto).", node.sourceline)) + else: + reviewers.append((name, link)) + elif (node.tag == xhtmlns+'meta'): + metatype = node.get('name') + metatype = metatype.strip() if metatype else metatype + # requirement flags + if ('flags' == metatype): + if (readFlags): + errors.append(LineString("Flags must only be specified once.", node.sourceline)) + else: + readFlags = True + if (None == node.get('content')): + errors.append(LineString("Flags meta missing content attribute.", node.sourceline)) + else: + for flag in sorted(node.get('content').split()): + flags.append(flag) + # test assertions + elif ('assert' == metatype): + if (None == node.get('content')): + errors.append(LineString("Assert meta missing content attribute.", node.sourceline)) + else: + asserts.append(node.get('content').strip().replace('\t', ' ')) + # title + elif (node.tag == xhtmlns+'title'): + title = node.text.strip() if node.text else '' + match = re.match('(?:[^:]*)[tT]est(?:[^:]*):(.*)', title, re.DOTALL) + if (match): + title = match.group(1) + title = title.strip() + # script + elif (node.tag == xhtmlns+'script'): + src = node.get('src').strip() if node.get('src') else None + if (src): + self.scripts[src] = node + + if (asserts or credits or reviewers or flags or links or title): + self.metadata = {'asserts' : asserts, + 'credits' : credits, + 'reviewers' : reviewers, + 'flags' : flags, + 'links' : links, + 'title' : title + } + + if (errors): + if (self.errors): + self.errors += errors + else: + self.errors = errors + + + def augmentMetadata(self, next=None, prev=None, reference=None, notReference=None): + """Add extra useful metadata to the head. All arguments are optional. + * Adds next/prev links to next/prev Sources given + * Adds reference link to reference Source given + """ + self.validate() + if next: + next = self.injectMetadataLink('next', self.relativeURL(next), 'next') + if prev: + prev = self.injectMetadataLink('prev', self.relativeURL(prev), 'prev') + if reference: + reference = self.injectMetadataLink('match', self.relativeURL(reference), 'ref') + if notReference: + notReference = self.injectMetadataLink('mismatch', self.relativeURL(notReference), 'not-ref') + return self.NodeTuple(next, prev, reference, notReference) + + +class XHTMLSource(XMLSource): + """FileSource object with support for XHTML->HTML conversions.""" + + # Public Methods + + def __init__(self, sourceTree, sourcepath, relpath, data = None): + """Initialize XHTMLSource by loading from XHTML file `sourcepath`. + Parse errors are stored in `self.errors`, + and the source is replaced with an XHTML error message. + """ + XMLSource.__init__(self, sourceTree, sourcepath, relpath, data = data) + + def serializeXHTML(self, doctype = None): + return self.serializeXML() + + def serializeHTML(self, doctype = None): + self.validate() + # Serialize +# print self.relpath + serializer = HTMLSerializer.HTMLSerializer() + output = serializer.serializeHTML(self.tree, doctype) + return output + + +class SVGSource(XMLSource): + """FileSource object with support for extracting metadata from SVG.""" + + def __init__(self, sourceTree, sourcepath, relpath, data = None): + """Initialize SVGSource by loading from SVG file `sourcepath`. + Parse errors are stored in `self.errors`, + and the source is replaced with an XHTML error message. + """ + XMLSource.__init__(self, sourceTree, sourcepath, relpath, data = data) + + def getMeatdataContainer(self): + groups = self.tree.getroot().findall(svgns+'g') + for group in groups: + if ('testmeta' == group.get('id')): + return group + return None + + def extractMetadata(self, tree): + """Extract metadata from tree.""" + links = []; credits = []; reviewers = []; flags = []; asserts = []; title = '' + + def tokenMatch(token, string): + return bool(re.search('(^|\s+)%s($|\s+)' % token, string)) if (string) else False + + errors = [] + readFlags = False + metaElements = self.getMetadataElements(tree) + if (not metaElements): + errors.append("Missing <g id='testmeta'> element") + else: + # Scan and cache metadata + for node in metaElements: + if (node.tag == xhtmlns+'link'): + # help links + if tokenMatch('help', node.get('rel')): + link = node.get('href').strip() if node.get('href') else None + if (not link): + errors.append(LineString("Help link missing href value.", node.sourceline)) + elif (not (link.startswith('http://') or link.startswith('https://'))): + errors.append(LineString("Help link " + link.encode('utf-8') + " must be absolute URL.", node.sourceline)) + elif (link in links): + errors.append(LineString("Duplicate help link " + link.encode('utf-8') + ".", node.sourceline)) + else: + links.append(LineString(link, node.sourceline)) + # == references + elif tokenMatch('match', node.get('rel')) or tokenMatch('reference', node.get('rel')): + refPath = node.get('href').strip() if node.get('href') else None + if (not refPath): + errors.append(LineString("Reference link missing href value.", node.sourceline)) + else: + refName = self.sourceTree.getAssetName(join(self.sourcepath, refPath)) + if (refName in self.refs): + errors.append(LineString("Reference " + refName.encode('utf-8') + " already specified.", node.sourceline)) + else: + self.refs[refName] = ('==', refPath, node, None) + # != references + elif tokenMatch('mismatch', node.get('rel')) or tokenMatch('not-reference', node.get('rel')): + refPath = node.get('href').strip() if node.get('href') else None + if (not refPath): + errors.append(LineString("Reference link missing href value.", node.sourceline)) + else: + refName = self.sourceTree.getAssetName(join(self.sourcepath, refPath)) + if (refName in self.refs): + errors.append(LineString("Reference " + refName.encode('utf-8') + " already specified.", node.sourceline)) + else: + self.refs[refName] = ('!=', refPath, node, None) + else: # may have both author and reviewer in the same link + # credits + if tokenMatch('author', node.get('rel')): + name = node.get('title') + name = name.strip() if name else name + if (not name): + errors.append(LineString("Author link missing name (title attribute).", node.sourceline)) + else: + link = node.get('href').strip() if node.get('href') else None + if (not link): + errors.append(LineString("Author link for \"" + name.encode('utf-8') + "\" missing contact URL (http or mailto).", node.sourceline)) + else: + credits.append((name, link)) + # reviewers + if tokenMatch('reviewer', node.get('rel')): + name = node.get('title') + name = name.strip() if name else name + if (not name): + errors.append(LineString("Reviewer link missing name (title attribute).", node.sourceline)) + else: + link = node.get('href').strip() if node.get('href') else None + if (not link): + errors.append(LineString("Reviewer link for \"" + name.encode('utf-8') + "\" missing contact URL (http or mailto).", node.sourceline)) + else: + reviewers.append((name, link)) + elif (node.tag == svgns+'metadata'): + metatype = node.get('class') + metatype = metatype.strip() if metatype else metatype + # requirement flags + if ('flags' == metatype): + if (readFlags): + errors.append(LineString("Flags must only be specified once.", node.sourceline)) + else: + readFlags = True + text = node.find(svgns+'text') + flagString = text.text if (text) else node.text + if (flagString): + for flag in sorted(flagString.split()): + flags.append(flag) + elif (node.tag == svgns+'desc'): + metatype = node.get('class') + metatype = metatype.strip() if metatype else metatype + # test assertions + if ('assert' == metatype): + asserts.append(node.text.strip().replace('\t', ' ')) + # test title + elif node.tag == svgns+'title': + title = node.text.strip() if node.text else '' + match = re.match('(?:[^:]*)[tT]est(?:[^:]*):(.*)', title, re.DOTALL) + if (match): + title = match.group(1) + title = title.strip() + # script tag (XXX restricted to metadata container?) + elif (node.tag == svgns+'script'): + src = node.get('src').strip() if node.get('src') else None + if (src): + self.scripts[src] = node + + if (asserts or credits or reviewers or flags or links or title): + self.metadata = {'asserts' : asserts, + 'credits' : credits, + 'reviewers' : reviewers, + 'flags' : flags, + 'links' : links, + 'title' : title + } + if (errors): + if (self.errors): + self.errors += errors + else: + self.errors = errors + + + +class HTMLSource(XMLSource): + """FileSource object with support for HTML metadata and HTML->XHTML conversions (untested).""" + + # Private Data and Methods + __parser = html5lib.HTMLParser(tree = treebuilders.getTreeBuilder('lxml')) + + # Public Methods + + def __init__(self, sourceTree, sourcepath, relpath, data = None): + """Initialize HTMLSource by loading from HTML file `sourcepath`. + """ + XMLSource.__init__(self, sourceTree, sourcepath, relpath, data = data) + + def parse(self): + """Parse file and store any parse errors in self.errors""" + self.errors = None + try: + data = self.data() + if data: + with warnings.catch_warnings(): + warnings.simplefilter("ignore") + self.tree = self.__parser.parse(data) + self.encoding = self.__parser.documentEncoding + self.injectedTags = {} + else: + self.tree = None + self.errors = ['Empty source file'] + self.encoding = 'utf-8' + + FileSource.loadMetadata(self) + if ((not self.metadata) and self.tree and (not self.errors)): + self.extractMetadata(self.tree) + except Exception as e: + print("PARSE ERROR: " + self.sourcepath) + e.W3CTestLibErrorLocation = self.sourcepath + self.errors = [str(e)] + self.encoding = 'utf-8' + + def _injectXLinks(self, element, nodeList): + injected = False + + xlinkAttrs = ['href', 'type', 'role', 'arcrole', 'title', 'show', 'actuate'] + if (element.get('href') or element.get(xlinkns + 'href')): + for attr in xlinkAttrs: + if (element.get(xlinkns + attr)): + injected = True + if (element.get(attr)): + injected = True + value = element.get(attr) + del element.attrib[attr] + element.set(xlinkns + attr, value) + nodeList.append((element, xlinkns + attr, attr)) + + for child in element: + if (type(child.tag) == type('')): # element node + qName = etree.QName(child.tag) + if ('foreignobject' != qName.localname.lower()): + injected |= self._injectXLinks(child, nodeList) + return injected + + + def _findElements(self, namespace, elementName): + elements = self.tree.findall('.//{' + namespace + '}' + elementName) + if (self.tree.getroot().tag == '{' + namespace + '}' + elementName): + elements.insert(0, self.tree.getroot()) + return elements + + def _injectNamespace(self, elementName, prefix, namespace, doXLinks, nodeList): + attr = xmlns + prefix if (prefix) else 'xmlns' + elements = self._findElements(namespace, elementName) + for element in elements: + if not element.get(attr): + element.set(attr, namespace) + nodeList.append((element, attr, None)) + if (doXLinks): + if (self._injectXLinks(element, nodeList)): + element.set(xmlns + 'xlink', 'http://www.w3.org/1999/xlink') + nodeList.append((element, xmlns + 'xlink', None)) + + def injectNamespaces(self): + nodeList = [] + self._injectNamespace('html', None, 'http://www.w3.org/1999/xhtml', False, nodeList) + self._injectNamespace('svg', None, 'http://www.w3.org/2000/svg', True, nodeList) + self._injectNamespace('math', None, 'http://www.w3.org/1998/Math/MathML', True, nodeList) + return nodeList + + def removeNamespaces(self, nodeList): + if nodeList: + for element, attr, oldAttr in nodeList: + if (oldAttr): + value = element.get(attr) + del element.attrib[attr] + element.set(oldAttr, value) + else: + del element.attrib[attr] + + def serializeXHTML(self, doctype = None): + self.validate() + # Serialize + nodeList = self.injectNamespaces() +# print self.relpath + serializer = HTMLSerializer.HTMLSerializer() + o = serializer.serializeXHTML(self.tree, doctype) + + self.removeNamespaces(nodeList) + return o + + def serializeHTML(self, doctype = None): + self.validate() + # Serialize +# print self.relpath + serializer = HTMLSerializer.HTMLSerializer() + o = serializer.serializeHTML(self.tree, doctype) + + return o + + def data(self): + if ((not self.tree) or (self.metaSource)): + return FileSource.data(self) + return self.serializeHTML().encode(self.encoding, 'xmlcharrefreplace') + + def unicode(self): + if ((not self.tree) or (self.metaSource)): + return FileSource.unicode(self) + return self.serializeHTML() + diff --git a/testing/web-platform/tests/css/tools/w3ctestlib/Suite.py b/testing/web-platform/tests/css/tools/w3ctestlib/Suite.py new file mode 100644 index 0000000000..c5fa03a155 --- /dev/null +++ b/testing/web-platform/tests/css/tools/w3ctestlib/Suite.py @@ -0,0 +1,121 @@ +#!/usr/bin/python +# CSS Test Suite Manipulation Library +# Initial code by fantasai, joint copyright 2010 W3C and Microsoft +# Licensed under BSD 3-Clause: <http://www.w3.org/Consortium/Legal/2008/03-bsd-license> + +import OutputFormats +import Utils +from Groups import TestGroup, excludeDirs +from Sources import SourceTree, SourceCache +from shutil import copytree, rmtree +from os.path import join +import os +from mercurial import ui as UserInterface, hg + +class TestSuite: + """Representation of a standard CSS test suite.""" + + def __init__(self, name, title, specUri, draftUri, sourceCache = None, ui = None): + self.name = name + self.title = title + self.specroot = specUri + self.draftroot = draftUri + + self.ui = ui if ui else UserInterface.ui() + self.defaultReftestRelpath='reftest.list' + self.groups = {} + self.sourcecache = sourceCache if sourceCache else SourceCache(SourceTree(hg.repository(self.ui, '.'))) + self.formats = ('html4', 'xhtml1', 'xhtml1print') # XXX FIXME, hardcoded list is lame + self.rawgroups = {} + + def addTestsByExt(self, dir, ext, groupName='', groupTitle=''): + """Add tests from directory `dir` by file extension (via `ext`, e.g. ext='.xht'). + """ + group = TestGroup(self.sourcecache, dir, selfTestExt=ext, + name=groupName, title=groupTitle, ui = self.ui) + self.addGroup(group) + + + def addTestsByList(self, dir, filenames, groupName='', groupTitle=''): + """Add tests from directory `dir`, via file name list `filenames`. + """ + group = TestGroup(self.sourcecache, dir, selfTestList=filenames, + name=groupName, title=groupTitle, ui = self.ui) + self.addGroup(group) + + def addReftests(self, dir, manifestPath, groupName='', groupTitle=''): + """Add tests by importing context of directory `dir` and importing all + tests listed in the `reftestManifestName` manifest inside `dir`. + """ + group = TestGroup(self.sourcecache, + dir, manifestPath=manifestPath, + manifestDest=self.defaultReftestRelpath, + name=groupName, title=groupTitle, ui = self.ui) + self.addGroup(group) + + def addGroup(self, group): + """ Add CSSTestGroup `group` to store. """ + master = self.groups.get(group.name) + if master: + master.merge(group) + else: + self.groups[group.name] = group + + def addRaw(self, dir, relpath): + """Add the contents of directory `dir` to the test suite by copying + (not processing). Note this means such tests will not be indexed. + `relpath` gives the directory's path within the build destination. + """ + self.rawgroups[dir] = relpath + + def setFormats(self, formats): + self.formats = formats + + def buildInto(self, dest, indexer): + """Builds test suite through all OutputFormats into directory at path `dest` + or through OutputFormat destination `dest`, using Indexer `indexer`. + """ + if isinstance(dest, OutputFormats.BasicFormat): + formats = (dest,) + dest = dest.root + else: + formats = [] + for format in self.formats: + if (format == 'html4'): + formats.append(OutputFormats.HTMLFormat(dest, self.sourcecache.sourceTree)) + elif (format == 'html5'): + formats.append(OutputFormats.HTML5Format(dest, self.sourcecache.sourceTree)) + elif (format == 'xhtml1'): + formats.append(OutputFormats.XHTMLFormat(dest, self.sourcecache.sourceTree)) + elif (format == 'xhtml1print'): + formats.append(OutputFormats.XHTMLPrintFormat(dest, self.sourcecache.sourceTree, self.title)) + elif (format == 'svg'): + formats.append(OutputFormats.SVGFormat(dest, self.sourcecache.sourceTree)) + + for format in formats: + for group in self.groups.itervalues(): + group.build(format) + + for group in self.groups.itervalues(): + indexer.indexGroup(group) + + for format in formats: + indexer.writeIndex(format) + + + rawtests = [] + for src, relpath in self.rawgroups.items(): + copytree(src, join(dest,relpath)) + for (root, dirs, files) in os.walk(join(dest,relpath)): + for xdir in excludeDirs: + if xdir in dirs: + dirs.remove(xdir) + rmtree(join(root,xdir)) + rawtests.extend( + [join(Utils.relpath(root,dest),file) + for file in files] + ) + + rawtests.sort() + indexer.writeOverview(dest, addTests=rawtests) + diff --git a/testing/web-platform/tests/css/tools/w3ctestlib/Utils.py b/testing/web-platform/tests/css/tools/w3ctestlib/Utils.py new file mode 100644 index 0000000000..065c30491c --- /dev/null +++ b/testing/web-platform/tests/css/tools/w3ctestlib/Utils.py @@ -0,0 +1,161 @@ +#!/usr/bin/python +# CSS Test Suite Manipulation Library Utilities +# Initial code by fantasai, joint copyright 2010 W3C and Microsoft +# Licensed under BSD 3-Clause: <http://www.w3.org/Consortium/Legal/2008/03-bsd-license> + +###### XML Parsing ###### + +import os +import w3ctestlib +os.environ['XML_CATALOG_FILES'] = os.path.join(w3ctestlib.__path__[0], 'catalog/catalog.xml') + +###### File path manipulation ###### + +import os.path +from os.path import sep, pardir + +def assetName(path): + return intern(os.path.splitext(os.path.basename(path))[0].lower().encode('ascii')) + +def basepath(path): + """ Returns the path part of os.path.split. + """ + return os.path.dirname(path) + +def isPathInsideBase(path, base=''): + path = os.path.normpath(path) + if base: + base = os.path.normpath(base) + pathlist = path.split(os.path.sep) + baselist = base.split(os.path.sep) + while baselist: + p = pathlist.pop(0) + b = baselist.pop(0) + if p != b: + return False + return not pathlist[0].startswith(os.path.pardir) + return not path.startswith(os.path.pardir) + +def relpath(path, start): + """Return relative path from start to end. WARNING: this is not the + same as a relative URL; see relativeURL().""" + try: + return os.path.relpath(path, start) + except AttributeError: + # This function is copied directly from the Python 2.6 source + # code, and is therefore under a different license. + + if not path: + raise ValueError("no path specified") + start_list = os.path.abspath(start).split(sep) + path_list = os.path.abspath(path).split(sep) + if start_list[0].lower() != path_list[0].lower(): + unc_path, rest = os.path.splitunc(path) + unc_start, rest = os.path.splitunc(start) + if bool(unc_path) ^ bool(unc_start): + raise ValueError("Cannot mix UNC and non-UNC paths (%s and %s)" + % (path, start)) + else: + raise ValueError("path is on drive %s, start on drive %s" + % (path_list[0], start_list[0])) + # Work out how much of the filepath is shared by start and path. + for i in range(min(len(start_list), len(path_list))): + if start_list[i].lower() != path_list[i].lower(): + break + else: + i += 1 + + rel_list = [pardir] * (len(start_list)-i) + path_list[i:] + if not rel_list: + return os.path.curdir + return os.path.join(*rel_list) + +def relativeURL(start, end): + """ Returns relative URL from `start` to `end`. + """ +# if isPathInsideBase(end, start): +# return relpath(end, start) +# else: + return relpath(end, basepath(start)) + +def listfiles(path, ext = None): + """ Returns a list of all files in a directory. + Optionally lists only files with a given extension. + """ + try: + _,_,files = os.walk(path).next() + if (ext): + files = [fileName for fileName in files if fileName.endswith(ext)] + except StopIteration: + files = [] + return files + +def listdirs(path): + """ Returns a list of all subdirectories in a directory. + """ + try: + _,dirs,_ = os.walk(path).next() + except StopIteration: + dirs = [] + return dirs + +###### MIME types and file extensions ###### + +extensionMap = { None : 'application/octet-stream', # default + '.xht' : 'application/xhtml+xml', + '.xhtml' : 'application/xhtml+xml', + '.xml' : 'application/xml', + '.htm' : 'text/html', + '.html' : 'text/html', + '.txt' : 'text/plain', + '.jpg' : 'image/jpeg', + '.png' : 'image/png', + '.svg' : 'image/svg+xml', + } + +def getMimeFromExt(filepath): + """Convenience function: equal to extenionMap.get(ext, extensionMap[None]). + """ + if filepath.endswith('.htaccess'): + return 'config/htaccess' + ext = os.path.splitext(filepath)[1] + return extensionMap.get(ext, extensionMap[None]) + +###### Escaping ###### + +import types +from htmlentitydefs import entitydefs + +entityify = dict([c,e] for e,c in entitydefs.iteritems()) + +def escapeMarkup(data): + """Escape markup characters (&, >, <). Copied from xml.sax.saxutils. + """ + # must do ampersand first + data = data.replace("&", "&") + data = data.replace(">", ">") + data = data.replace("<", "<") + return data + +def escapeToNamedASCII(text): + """Escapes to named entities where possible and numeric-escapes non-ASCII + """ + return escapeToNamed(text).encode('ascii', 'xmlcharrefreplace') + +def escapeToNamed(text): + """Escape characters with named entities. + """ + escapable = set() + + for c in text: + if ord(c) > 127: + escapable.add(c) + if type(text) == types.UnicodeType: + for c in escapable: + cLatin = c.encode('Latin-1', 'ignore') + if (cLatin in entityify): + text = text.replace(c, "&%s;" % entityify[cLatin]) + else: + for c in escapable: + text = text.replace(c, "&%s;" % entityify[c]) + return text diff --git a/testing/web-platform/tests/css/tools/w3ctestlib/__init__.py b/testing/web-platform/tests/css/tools/w3ctestlib/__init__.py new file mode 100644 index 0000000000..8ce9f985c3 --- /dev/null +++ b/testing/web-platform/tests/css/tools/w3ctestlib/__init__.py @@ -0,0 +1,3 @@ +
+
+__all__ = ['Sources', 'Groups', 'Indexer', 'Suite', 'OutputFormats', 'HTMLSerializer']
\ No newline at end of file diff --git a/testing/web-platform/tests/css/tools/w3ctestlib/catalog/catalog.xml b/testing/web-platform/tests/css/tools/w3ctestlib/catalog/catalog.xml new file mode 100644 index 0000000000..d9c5926235 --- /dev/null +++ b/testing/web-platform/tests/css/tools/w3ctestlib/catalog/catalog.xml @@ -0,0 +1,27 @@ +<?xml version="1.0"?> +<!-- <!DOCTYPE catalog PUBLIC "-//OASIS//DTD XML Catalogs V1.0//EN" "file:///usr/share/xml/schema/xml-core/catalog.dtd"> --> +<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog"> + <group prefer="public"> + <public + publicId="-//W3C//DTD XHTML 1.1//EN" + uri="xhtml11.dtd"/> + <public + publicId="-//W3C//DTD XHTML 1.0 Strict//EN" + uri="xhtml1-strict.dtd"/> + <public + publicId="-//W3C//DTD XHTML 1.0 Transitional//EN" + uri="xhtml1-transitional.dtd"/> + <public + publicId="-//W3C//DTD XHTML 1.0 Frameset//EN" + uri="xhtml1-frameset.dtd"/> + <public + publicId="-//W3C//ENTITIES Latin 1 for XHTML//EN" + uri="xhtml-lat1.ent"/> + <public + publicId="-//W3C//ENTITIES Special for XHTML//EN" + uri="xhtml-special.ent"/> + <public + publicId="-//W3C//ENTITIES Symbols for XHTML//EN" + uri="xhtml-special.ent"/> + </group> +</catalog> diff --git a/testing/web-platform/tests/css/tools/w3ctestlib/catalog/xhtml-lat1.ent b/testing/web-platform/tests/css/tools/w3ctestlib/catalog/xhtml-lat1.ent new file mode 100644 index 0000000000..ffee223eb1 --- /dev/null +++ b/testing/web-platform/tests/css/tools/w3ctestlib/catalog/xhtml-lat1.ent @@ -0,0 +1,196 @@ +<!-- Portions (C) International Organization for Standardization 1986 + Permission to copy in any form is granted for use with + conforming SGML systems and applications as defined in + ISO 8879, provided this notice is included in all copies. +--> +<!-- Character entity set. Typical invocation: + <!ENTITY % HTMLlat1 PUBLIC + "-//W3C//ENTITIES Latin 1 for XHTML//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml-lat1.ent"> + %HTMLlat1; +--> + +<!ENTITY nbsp " "> <!-- no-break space = non-breaking space, + U+00A0 ISOnum --> +<!ENTITY iexcl "¡"> <!-- inverted exclamation mark, U+00A1 ISOnum --> +<!ENTITY cent "¢"> <!-- cent sign, U+00A2 ISOnum --> +<!ENTITY pound "£"> <!-- pound sign, U+00A3 ISOnum --> +<!ENTITY curren "¤"> <!-- currency sign, U+00A4 ISOnum --> +<!ENTITY yen "¥"> <!-- yen sign = yuan sign, U+00A5 ISOnum --> +<!ENTITY brvbar "¦"> <!-- broken bar = broken vertical bar, + U+00A6 ISOnum --> +<!ENTITY sect "§"> <!-- section sign, U+00A7 ISOnum --> +<!ENTITY uml "¨"> <!-- diaeresis = spacing diaeresis, + U+00A8 ISOdia --> +<!ENTITY copy "©"> <!-- copyright sign, U+00A9 ISOnum --> +<!ENTITY ordf "ª"> <!-- feminine ordinal indicator, U+00AA ISOnum --> +<!ENTITY laquo "«"> <!-- left-pointing double angle quotation mark + = left pointing guillemet, U+00AB ISOnum --> +<!ENTITY not "¬"> <!-- not sign = angled dash, + U+00AC ISOnum --> +<!ENTITY shy "­"> <!-- soft hyphen = discretionary hyphen, + U+00AD ISOnum --> +<!ENTITY reg "®"> <!-- registered sign = registered trade mark sign, + U+00AE ISOnum --> +<!ENTITY macr "¯"> <!-- macron = spacing macron = overline + = APL overbar, U+00AF ISOdia --> +<!ENTITY deg "°"> <!-- degree sign, U+00B0 ISOnum --> +<!ENTITY plusmn "±"> <!-- plus-minus sign = plus-or-minus sign, + U+00B1 ISOnum --> +<!ENTITY sup2 "²"> <!-- superscript two = superscript digit two + = squared, U+00B2 ISOnum --> +<!ENTITY sup3 "³"> <!-- superscript three = superscript digit three + = cubed, U+00B3 ISOnum --> +<!ENTITY acute "´"> <!-- acute accent = spacing acute, + U+00B4 ISOdia --> +<!ENTITY micro "µ"> <!-- micro sign, U+00B5 ISOnum --> +<!ENTITY para "¶"> <!-- pilcrow sign = paragraph sign, + U+00B6 ISOnum --> +<!ENTITY middot "·"> <!-- middle dot = Georgian comma + = Greek middle dot, U+00B7 ISOnum --> +<!ENTITY cedil "¸"> <!-- cedilla = spacing cedilla, U+00B8 ISOdia --> +<!ENTITY sup1 "¹"> <!-- superscript one = superscript digit one, + U+00B9 ISOnum --> +<!ENTITY ordm "º"> <!-- masculine ordinal indicator, + U+00BA ISOnum --> +<!ENTITY raquo "»"> <!-- right-pointing double angle quotation mark + = right pointing guillemet, U+00BB ISOnum --> +<!ENTITY frac14 "¼"> <!-- vulgar fraction one quarter + = fraction one quarter, U+00BC ISOnum --> +<!ENTITY frac12 "½"> <!-- vulgar fraction one half + = fraction one half, U+00BD ISOnum --> +<!ENTITY frac34 "¾"> <!-- vulgar fraction three quarters + = fraction three quarters, U+00BE ISOnum --> +<!ENTITY iquest "¿"> <!-- inverted question mark + = turned question mark, U+00BF ISOnum --> +<!ENTITY Agrave "À"> <!-- latin capital letter A with grave + = latin capital letter A grave, + U+00C0 ISOlat1 --> +<!ENTITY Aacute "Á"> <!-- latin capital letter A with acute, + U+00C1 ISOlat1 --> +<!ENTITY Acirc "Â"> <!-- latin capital letter A with circumflex, + U+00C2 ISOlat1 --> +<!ENTITY Atilde "Ã"> <!-- latin capital letter A with tilde, + U+00C3 ISOlat1 --> +<!ENTITY Auml "Ä"> <!-- latin capital letter A with diaeresis, + U+00C4 ISOlat1 --> +<!ENTITY Aring "Å"> <!-- latin capital letter A with ring above + = latin capital letter A ring, + U+00C5 ISOlat1 --> +<!ENTITY AElig "Æ"> <!-- latin capital letter AE + = latin capital ligature AE, + U+00C6 ISOlat1 --> +<!ENTITY Ccedil "Ç"> <!-- latin capital letter C with cedilla, + U+00C7 ISOlat1 --> +<!ENTITY Egrave "È"> <!-- latin capital letter E with grave, + U+00C8 ISOlat1 --> +<!ENTITY Eacute "É"> <!-- latin capital letter E with acute, + U+00C9 ISOlat1 --> +<!ENTITY Ecirc "Ê"> <!-- latin capital letter E with circumflex, + U+00CA ISOlat1 --> +<!ENTITY Euml "Ë"> <!-- latin capital letter E with diaeresis, + U+00CB ISOlat1 --> +<!ENTITY Igrave "Ì"> <!-- latin capital letter I with grave, + U+00CC ISOlat1 --> +<!ENTITY Iacute "Í"> <!-- latin capital letter I with acute, + U+00CD ISOlat1 --> +<!ENTITY Icirc "Î"> <!-- latin capital letter I with circumflex, + U+00CE ISOlat1 --> +<!ENTITY Iuml "Ï"> <!-- latin capital letter I with diaeresis, + U+00CF ISOlat1 --> +<!ENTITY ETH "Ð"> <!-- latin capital letter ETH, U+00D0 ISOlat1 --> +<!ENTITY Ntilde "Ñ"> <!-- latin capital letter N with tilde, + U+00D1 ISOlat1 --> +<!ENTITY Ograve "Ò"> <!-- latin capital letter O with grave, + U+00D2 ISOlat1 --> +<!ENTITY Oacute "Ó"> <!-- latin capital letter O with acute, + U+00D3 ISOlat1 --> +<!ENTITY Ocirc "Ô"> <!-- latin capital letter O with circumflex, + U+00D4 ISOlat1 --> +<!ENTITY Otilde "Õ"> <!-- latin capital letter O with tilde, + U+00D5 ISOlat1 --> +<!ENTITY Ouml "Ö"> <!-- latin capital letter O with diaeresis, + U+00D6 ISOlat1 --> +<!ENTITY times "×"> <!-- multiplication sign, U+00D7 ISOnum --> +<!ENTITY Oslash "Ø"> <!-- latin capital letter O with stroke + = latin capital letter O slash, + U+00D8 ISOlat1 --> +<!ENTITY Ugrave "Ù"> <!-- latin capital letter U with grave, + U+00D9 ISOlat1 --> +<!ENTITY Uacute "Ú"> <!-- latin capital letter U with acute, + U+00DA ISOlat1 --> +<!ENTITY Ucirc "Û"> <!-- latin capital letter U with circumflex, + U+00DB ISOlat1 --> +<!ENTITY Uuml "Ü"> <!-- latin capital letter U with diaeresis, + U+00DC ISOlat1 --> +<!ENTITY Yacute "Ý"> <!-- latin capital letter Y with acute, + U+00DD ISOlat1 --> +<!ENTITY THORN "Þ"> <!-- latin capital letter THORN, + U+00DE ISOlat1 --> +<!ENTITY szlig "ß"> <!-- latin small letter sharp s = ess-zed, + U+00DF ISOlat1 --> +<!ENTITY agrave "à"> <!-- latin small letter a with grave + = latin small letter a grave, + U+00E0 ISOlat1 --> +<!ENTITY aacute "á"> <!-- latin small letter a with acute, + U+00E1 ISOlat1 --> +<!ENTITY acirc "â"> <!-- latin small letter a with circumflex, + U+00E2 ISOlat1 --> +<!ENTITY atilde "ã"> <!-- latin small letter a with tilde, + U+00E3 ISOlat1 --> +<!ENTITY auml "ä"> <!-- latin small letter a with diaeresis, + U+00E4 ISOlat1 --> +<!ENTITY aring "å"> <!-- latin small letter a with ring above + = latin small letter a ring, + U+00E5 ISOlat1 --> +<!ENTITY aelig "æ"> <!-- latin small letter ae + = latin small ligature ae, U+00E6 ISOlat1 --> +<!ENTITY ccedil "ç"> <!-- latin small letter c with cedilla, + U+00E7 ISOlat1 --> +<!ENTITY egrave "è"> <!-- latin small letter e with grave, + U+00E8 ISOlat1 --> +<!ENTITY eacute "é"> <!-- latin small letter e with acute, + U+00E9 ISOlat1 --> +<!ENTITY ecirc "ê"> <!-- latin small letter e with circumflex, + U+00EA ISOlat1 --> +<!ENTITY euml "ë"> <!-- latin small letter e with diaeresis, + U+00EB ISOlat1 --> +<!ENTITY igrave "ì"> <!-- latin small letter i with grave, + U+00EC ISOlat1 --> +<!ENTITY iacute "í"> <!-- latin small letter i with acute, + U+00ED ISOlat1 --> +<!ENTITY icirc "î"> <!-- latin small letter i with circumflex, + U+00EE ISOlat1 --> +<!ENTITY iuml "ï"> <!-- latin small letter i with diaeresis, + U+00EF ISOlat1 --> +<!ENTITY eth "ð"> <!-- latin small letter eth, U+00F0 ISOlat1 --> +<!ENTITY ntilde "ñ"> <!-- latin small letter n with tilde, + U+00F1 ISOlat1 --> +<!ENTITY ograve "ò"> <!-- latin small letter o with grave, + U+00F2 ISOlat1 --> +<!ENTITY oacute "ó"> <!-- latin small letter o with acute, + U+00F3 ISOlat1 --> +<!ENTITY ocirc "ô"> <!-- latin small letter o with circumflex, + U+00F4 ISOlat1 --> +<!ENTITY otilde "õ"> <!-- latin small letter o with tilde, + U+00F5 ISOlat1 --> +<!ENTITY ouml "ö"> <!-- latin small letter o with diaeresis, + U+00F6 ISOlat1 --> +<!ENTITY divide "÷"> <!-- division sign, U+00F7 ISOnum --> +<!ENTITY oslash "ø"> <!-- latin small letter o with stroke, + = latin small letter o slash, + U+00F8 ISOlat1 --> +<!ENTITY ugrave "ù"> <!-- latin small letter u with grave, + U+00F9 ISOlat1 --> +<!ENTITY uacute "ú"> <!-- latin small letter u with acute, + U+00FA ISOlat1 --> +<!ENTITY ucirc "û"> <!-- latin small letter u with circumflex, + U+00FB ISOlat1 --> +<!ENTITY uuml "ü"> <!-- latin small letter u with diaeresis, + U+00FC ISOlat1 --> +<!ENTITY yacute "ý"> <!-- latin small letter y with acute, + U+00FD ISOlat1 --> +<!ENTITY thorn "þ"> <!-- latin small letter thorn, + U+00FE ISOlat1 --> +<!ENTITY yuml "ÿ"> <!-- latin small letter y with diaeresis, + U+00FF ISOlat1 --> diff --git a/testing/web-platform/tests/css/tools/w3ctestlib/catalog/xhtml-special.ent b/testing/web-platform/tests/css/tools/w3ctestlib/catalog/xhtml-special.ent new file mode 100644 index 0000000000..ca358b2fec --- /dev/null +++ b/testing/web-platform/tests/css/tools/w3ctestlib/catalog/xhtml-special.ent @@ -0,0 +1,80 @@ +<!-- Special characters for XHTML --> + +<!-- Character entity set. Typical invocation: + <!ENTITY % HTMLspecial PUBLIC + "-//W3C//ENTITIES Special for XHTML//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml-special.ent"> + %HTMLspecial; +--> + +<!-- Portions (C) International Organization for Standardization 1986: + Permission to copy in any form is granted for use with + conforming SGML systems and applications as defined in + ISO 8879, provided this notice is included in all copies. +--> + +<!-- Relevant ISO entity set is given unless names are newly introduced. + New names (i.e., not in ISO 8879 list) do not clash with any + existing ISO 8879 entity names. ISO 10646 character numbers + are given for each character, in hex. values are decimal + conversions of the ISO 10646 values and refer to the document + character set. Names are Unicode names. +--> + +<!-- C0 Controls and Basic Latin --> +<!ENTITY quot """> <!-- quotation mark, U+0022 ISOnum --> +<!ENTITY amp "&#38;"> <!-- ampersand, U+0026 ISOnum --> +<!ENTITY lt "&#60;"> <!-- less-than sign, U+003C ISOnum --> +<!ENTITY gt ">"> <!-- greater-than sign, U+003E ISOnum --> +<!ENTITY apos "'"> <!-- apostrophe = APL quote, U+0027 ISOnum --> + +<!-- Latin Extended-A --> +<!ENTITY OElig "Œ"> <!-- latin capital ligature OE, + U+0152 ISOlat2 --> +<!ENTITY oelig "œ"> <!-- latin small ligature oe, U+0153 ISOlat2 --> +<!-- ligature is a misnomer, this is a separate character in some languages --> +<!ENTITY Scaron "Š"> <!-- latin capital letter S with caron, + U+0160 ISOlat2 --> +<!ENTITY scaron "š"> <!-- latin small letter s with caron, + U+0161 ISOlat2 --> +<!ENTITY Yuml "Ÿ"> <!-- latin capital letter Y with diaeresis, + U+0178 ISOlat2 --> + +<!-- Spacing Modifier Letters --> +<!ENTITY circ "ˆ"> <!-- modifier letter circumflex accent, + U+02C6 ISOpub --> +<!ENTITY tilde "˜"> <!-- small tilde, U+02DC ISOdia --> + +<!-- General Punctuation --> +<!ENTITY ensp " "> <!-- en space, U+2002 ISOpub --> +<!ENTITY emsp " "> <!-- em space, U+2003 ISOpub --> +<!ENTITY thinsp " "> <!-- thin space, U+2009 ISOpub --> +<!ENTITY zwnj "‌"> <!-- zero width non-joiner, + U+200C NEW RFC 2070 --> +<!ENTITY zwj "‍"> <!-- zero width joiner, U+200D NEW RFC 2070 --> +<!ENTITY lrm "‎"> <!-- left-to-right mark, U+200E NEW RFC 2070 --> +<!ENTITY rlm "‏"> <!-- right-to-left mark, U+200F NEW RFC 2070 --> +<!ENTITY ndash "–"> <!-- en dash, U+2013 ISOpub --> +<!ENTITY mdash "—"> <!-- em dash, U+2014 ISOpub --> +<!ENTITY lsquo "‘"> <!-- left single quotation mark, + U+2018 ISOnum --> +<!ENTITY rsquo "’"> <!-- right single quotation mark, + U+2019 ISOnum --> +<!ENTITY sbquo "‚"> <!-- single low-9 quotation mark, U+201A NEW --> +<!ENTITY ldquo "“"> <!-- left double quotation mark, + U+201C ISOnum --> +<!ENTITY rdquo "”"> <!-- right double quotation mark, + U+201D ISOnum --> +<!ENTITY bdquo "„"> <!-- double low-9 quotation mark, U+201E NEW --> +<!ENTITY dagger "†"> <!-- dagger, U+2020 ISOpub --> +<!ENTITY Dagger "‡"> <!-- double dagger, U+2021 ISOpub --> +<!ENTITY permil "‰"> <!-- per mille sign, U+2030 ISOtech --> +<!ENTITY lsaquo "‹"> <!-- single left-pointing angle quotation mark, + U+2039 ISO proposed --> +<!-- lsaquo is proposed but not yet ISO standardized --> +<!ENTITY rsaquo "›"> <!-- single right-pointing angle quotation mark, + U+203A ISO proposed --> +<!-- rsaquo is proposed but not yet ISO standardized --> + +<!-- Currency Symbols --> +<!ENTITY euro "€"> <!-- euro sign, U+20AC NEW --> diff --git a/testing/web-platform/tests/css/tools/w3ctestlib/catalog/xhtml-symbol.ent b/testing/web-platform/tests/css/tools/w3ctestlib/catalog/xhtml-symbol.ent new file mode 100644 index 0000000000..63c2abfa6f --- /dev/null +++ b/testing/web-platform/tests/css/tools/w3ctestlib/catalog/xhtml-symbol.ent @@ -0,0 +1,237 @@ +<!-- Mathematical, Greek and Symbolic characters for XHTML --> + +<!-- Character entity set. Typical invocation: + <!ENTITY % HTMLsymbol PUBLIC + "-//W3C//ENTITIES Symbols for XHTML//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml-symbol.ent"> + %HTMLsymbol; +--> + +<!-- Portions (C) International Organization for Standardization 1986: + Permission to copy in any form is granted for use with + conforming SGML systems and applications as defined in + ISO 8879, provided this notice is included in all copies. +--> + +<!-- Relevant ISO entity set is given unless names are newly introduced. + New names (i.e., not in ISO 8879 list) do not clash with any + existing ISO 8879 entity names. ISO 10646 character numbers + are given for each character, in hex. values are decimal + conversions of the ISO 10646 values and refer to the document + character set. Names are Unicode names. +--> + +<!-- Latin Extended-B --> +<!ENTITY fnof "ƒ"> <!-- latin small letter f with hook = function + = florin, U+0192 ISOtech --> + +<!-- Greek --> +<!ENTITY Alpha "Α"> <!-- greek capital letter alpha, U+0391 --> +<!ENTITY Beta "Β"> <!-- greek capital letter beta, U+0392 --> +<!ENTITY Gamma "Γ"> <!-- greek capital letter gamma, + U+0393 ISOgrk3 --> +<!ENTITY Delta "Δ"> <!-- greek capital letter delta, + U+0394 ISOgrk3 --> +<!ENTITY Epsilon "Ε"> <!-- greek capital letter epsilon, U+0395 --> +<!ENTITY Zeta "Ζ"> <!-- greek capital letter zeta, U+0396 --> +<!ENTITY Eta "Η"> <!-- greek capital letter eta, U+0397 --> +<!ENTITY Theta "Θ"> <!-- greek capital letter theta, + U+0398 ISOgrk3 --> +<!ENTITY Iota "Ι"> <!-- greek capital letter iota, U+0399 --> +<!ENTITY Kappa "Κ"> <!-- greek capital letter kappa, U+039A --> +<!ENTITY Lambda "Λ"> <!-- greek capital letter lamda, + U+039B ISOgrk3 --> +<!ENTITY Mu "Μ"> <!-- greek capital letter mu, U+039C --> +<!ENTITY Nu "Ν"> <!-- greek capital letter nu, U+039D --> +<!ENTITY Xi "Ξ"> <!-- greek capital letter xi, U+039E ISOgrk3 --> +<!ENTITY Omicron "Ο"> <!-- greek capital letter omicron, U+039F --> +<!ENTITY Pi "Π"> <!-- greek capital letter pi, U+03A0 ISOgrk3 --> +<!ENTITY Rho "Ρ"> <!-- greek capital letter rho, U+03A1 --> +<!-- there is no Sigmaf, and no U+03A2 character either --> +<!ENTITY Sigma "Σ"> <!-- greek capital letter sigma, + U+03A3 ISOgrk3 --> +<!ENTITY Tau "Τ"> <!-- greek capital letter tau, U+03A4 --> +<!ENTITY Upsilon "Υ"> <!-- greek capital letter upsilon, + U+03A5 ISOgrk3 --> +<!ENTITY Phi "Φ"> <!-- greek capital letter phi, + U+03A6 ISOgrk3 --> +<!ENTITY Chi "Χ"> <!-- greek capital letter chi, U+03A7 --> +<!ENTITY Psi "Ψ"> <!-- greek capital letter psi, + U+03A8 ISOgrk3 --> +<!ENTITY Omega "Ω"> <!-- greek capital letter omega, + U+03A9 ISOgrk3 --> + +<!ENTITY alpha "α"> <!-- greek small letter alpha, + U+03B1 ISOgrk3 --> +<!ENTITY beta "β"> <!-- greek small letter beta, U+03B2 ISOgrk3 --> +<!ENTITY gamma "γ"> <!-- greek small letter gamma, + U+03B3 ISOgrk3 --> +<!ENTITY delta "δ"> <!-- greek small letter delta, + U+03B4 ISOgrk3 --> +<!ENTITY epsilon "ε"> <!-- greek small letter epsilon, + U+03B5 ISOgrk3 --> +<!ENTITY zeta "ζ"> <!-- greek small letter zeta, U+03B6 ISOgrk3 --> +<!ENTITY eta "η"> <!-- greek small letter eta, U+03B7 ISOgrk3 --> +<!ENTITY theta "θ"> <!-- greek small letter theta, + U+03B8 ISOgrk3 --> +<!ENTITY iota "ι"> <!-- greek small letter iota, U+03B9 ISOgrk3 --> +<!ENTITY kappa "κ"> <!-- greek small letter kappa, + U+03BA ISOgrk3 --> +<!ENTITY lambda "λ"> <!-- greek small letter lamda, + U+03BB ISOgrk3 --> +<!ENTITY mu "μ"> <!-- greek small letter mu, U+03BC ISOgrk3 --> +<!ENTITY nu "ν"> <!-- greek small letter nu, U+03BD ISOgrk3 --> +<!ENTITY xi "ξ"> <!-- greek small letter xi, U+03BE ISOgrk3 --> +<!ENTITY omicron "ο"> <!-- greek small letter omicron, U+03BF NEW --> +<!ENTITY pi "π"> <!-- greek small letter pi, U+03C0 ISOgrk3 --> +<!ENTITY rho "ρ"> <!-- greek small letter rho, U+03C1 ISOgrk3 --> +<!ENTITY sigmaf "ς"> <!-- greek small letter final sigma, + U+03C2 ISOgrk3 --> +<!ENTITY sigma "σ"> <!-- greek small letter sigma, + U+03C3 ISOgrk3 --> +<!ENTITY tau "τ"> <!-- greek small letter tau, U+03C4 ISOgrk3 --> +<!ENTITY upsilon "υ"> <!-- greek small letter upsilon, + U+03C5 ISOgrk3 --> +<!ENTITY phi "φ"> <!-- greek small letter phi, U+03C6 ISOgrk3 --> +<!ENTITY chi "χ"> <!-- greek small letter chi, U+03C7 ISOgrk3 --> +<!ENTITY psi "ψ"> <!-- greek small letter psi, U+03C8 ISOgrk3 --> +<!ENTITY omega "ω"> <!-- greek small letter omega, + U+03C9 ISOgrk3 --> +<!ENTITY thetasym "ϑ"> <!-- greek theta symbol, + U+03D1 NEW --> +<!ENTITY upsih "ϒ"> <!-- greek upsilon with hook symbol, + U+03D2 NEW --> +<!ENTITY piv "ϖ"> <!-- greek pi symbol, U+03D6 ISOgrk3 --> + +<!-- General Punctuation --> +<!ENTITY bull "•"> <!-- bullet = black small circle, + U+2022 ISOpub --> +<!-- bullet is NOT the same as bullet operator, U+2219 --> +<!ENTITY hellip "…"> <!-- horizontal ellipsis = three dot leader, + U+2026 ISOpub --> +<!ENTITY prime "′"> <!-- prime = minutes = feet, U+2032 ISOtech --> +<!ENTITY Prime "″"> <!-- double prime = seconds = inches, + U+2033 ISOtech --> +<!ENTITY oline "‾"> <!-- overline = spacing overscore, + U+203E NEW --> +<!ENTITY frasl "⁄"> <!-- fraction slash, U+2044 NEW --> + +<!-- Letterlike Symbols --> +<!ENTITY weierp "℘"> <!-- script capital P = power set + = Weierstrass p, U+2118 ISOamso --> +<!ENTITY image "ℑ"> <!-- black-letter capital I = imaginary part, + U+2111 ISOamso --> +<!ENTITY real "ℜ"> <!-- black-letter capital R = real part symbol, + U+211C ISOamso --> +<!ENTITY trade "™"> <!-- trade mark sign, U+2122 ISOnum --> +<!ENTITY alefsym "ℵ"> <!-- alef symbol = first transfinite cardinal, + U+2135 NEW --> +<!-- alef symbol is NOT the same as hebrew letter alef, + U+05D0 although the same glyph could be used to depict both characters --> + +<!-- Arrows --> +<!ENTITY larr "←"> <!-- leftwards arrow, U+2190 ISOnum --> +<!ENTITY uarr "↑"> <!-- upwards arrow, U+2191 ISOnum--> +<!ENTITY rarr "→"> <!-- rightwards arrow, U+2192 ISOnum --> +<!ENTITY darr "↓"> <!-- downwards arrow, U+2193 ISOnum --> +<!ENTITY harr "↔"> <!-- left right arrow, U+2194 ISOamsa --> +<!ENTITY crarr "↵"> <!-- downwards arrow with corner leftwards + = carriage return, U+21B5 NEW --> +<!ENTITY lArr "⇐"> <!-- leftwards double arrow, U+21D0 ISOtech --> +<!-- Unicode does not say that lArr is the same as the 'is implied by' arrow + but also does not have any other character for that function. So lArr can + be used for 'is implied by' as ISOtech suggests --> +<!ENTITY uArr "⇑"> <!-- upwards double arrow, U+21D1 ISOamsa --> +<!ENTITY rArr "⇒"> <!-- rightwards double arrow, + U+21D2 ISOtech --> +<!-- Unicode does not say this is the 'implies' character but does not have + another character with this function so rArr can be used for 'implies' + as ISOtech suggests --> +<!ENTITY dArr "⇓"> <!-- downwards double arrow, U+21D3 ISOamsa --> +<!ENTITY hArr "⇔"> <!-- left right double arrow, + U+21D4 ISOamsa --> + +<!-- Mathematical Operators --> +<!ENTITY forall "∀"> <!-- for all, U+2200 ISOtech --> +<!ENTITY part "∂"> <!-- partial differential, U+2202 ISOtech --> +<!ENTITY exist "∃"> <!-- there exists, U+2203 ISOtech --> +<!ENTITY empty "∅"> <!-- empty set = null set, U+2205 ISOamso --> +<!ENTITY nabla "∇"> <!-- nabla = backward difference, + U+2207 ISOtech --> +<!ENTITY isin "∈"> <!-- element of, U+2208 ISOtech --> +<!ENTITY notin "∉"> <!-- not an element of, U+2209 ISOtech --> +<!ENTITY ni "∋"> <!-- contains as member, U+220B ISOtech --> +<!ENTITY prod "∏"> <!-- n-ary product = product sign, + U+220F ISOamsb --> +<!-- prod is NOT the same character as U+03A0 'greek capital letter pi' though + the same glyph might be used for both --> +<!ENTITY sum "∑"> <!-- n-ary summation, U+2211 ISOamsb --> +<!-- sum is NOT the same character as U+03A3 'greek capital letter sigma' + though the same glyph might be used for both --> +<!ENTITY minus "−"> <!-- minus sign, U+2212 ISOtech --> +<!ENTITY lowast "∗"> <!-- asterisk operator, U+2217 ISOtech --> +<!ENTITY radic "√"> <!-- square root = radical sign, + U+221A ISOtech --> +<!ENTITY prop "∝"> <!-- proportional to, U+221D ISOtech --> +<!ENTITY infin "∞"> <!-- infinity, U+221E ISOtech --> +<!ENTITY ang "∠"> <!-- angle, U+2220 ISOamso --> +<!ENTITY and "∧"> <!-- logical and = wedge, U+2227 ISOtech --> +<!ENTITY or "∨"> <!-- logical or = vee, U+2228 ISOtech --> +<!ENTITY cap "∩"> <!-- intersection = cap, U+2229 ISOtech --> +<!ENTITY cup "∪"> <!-- union = cup, U+222A ISOtech --> +<!ENTITY int "∫"> <!-- integral, U+222B ISOtech --> +<!ENTITY there4 "∴"> <!-- therefore, U+2234 ISOtech --> +<!ENTITY sim "∼"> <!-- tilde operator = varies with = similar to, + U+223C ISOtech --> +<!-- tilde operator is NOT the same character as the tilde, U+007E, + although the same glyph might be used to represent both --> +<!ENTITY cong "≅"> <!-- approximately equal to, U+2245 ISOtech --> +<!ENTITY asymp "≈"> <!-- almost equal to = asymptotic to, + U+2248 ISOamsr --> +<!ENTITY ne "≠"> <!-- not equal to, U+2260 ISOtech --> +<!ENTITY equiv "≡"> <!-- identical to, U+2261 ISOtech --> +<!ENTITY le "≤"> <!-- less-than or equal to, U+2264 ISOtech --> +<!ENTITY ge "≥"> <!-- greater-than or equal to, + U+2265 ISOtech --> +<!ENTITY sub "⊂"> <!-- subset of, U+2282 ISOtech --> +<!ENTITY sup "⊃"> <!-- superset of, U+2283 ISOtech --> +<!ENTITY nsub "⊄"> <!-- not a subset of, U+2284 ISOamsn --> +<!ENTITY sube "⊆"> <!-- subset of or equal to, U+2286 ISOtech --> +<!ENTITY supe "⊇"> <!-- superset of or equal to, + U+2287 ISOtech --> +<!ENTITY oplus "⊕"> <!-- circled plus = direct sum, + U+2295 ISOamsb --> +<!ENTITY otimes "⊗"> <!-- circled times = vector product, + U+2297 ISOamsb --> +<!ENTITY perp "⊥"> <!-- up tack = orthogonal to = perpendicular, + U+22A5 ISOtech --> +<!ENTITY sdot "⋅"> <!-- dot operator, U+22C5 ISOamsb --> +<!-- dot operator is NOT the same character as U+00B7 middle dot --> + +<!-- Miscellaneous Technical --> +<!ENTITY lceil "⌈"> <!-- left ceiling = APL upstile, + U+2308 ISOamsc --> +<!ENTITY rceil "⌉"> <!-- right ceiling, U+2309 ISOamsc --> +<!ENTITY lfloor "⌊"> <!-- left floor = APL downstile, + U+230A ISOamsc --> +<!ENTITY rfloor "⌋"> <!-- right floor, U+230B ISOamsc --> +<!ENTITY lang "〈"> <!-- left-pointing angle bracket = bra, + U+2329 ISOtech --> +<!-- lang is NOT the same character as U+003C 'less than sign' + or U+2039 'single left-pointing angle quotation mark' --> +<!ENTITY rang "〉"> <!-- right-pointing angle bracket = ket, + U+232A ISOtech --> +<!-- rang is NOT the same character as U+003E 'greater than sign' + or U+203A 'single right-pointing angle quotation mark' --> + +<!-- Geometric Shapes --> +<!ENTITY loz "◊"> <!-- lozenge, U+25CA ISOpub --> + +<!-- Miscellaneous Symbols --> +<!ENTITY spades "♠"> <!-- black spade suit, U+2660 ISOpub --> +<!-- black here seems to mean filled as opposed to hollow --> +<!ENTITY clubs "♣"> <!-- black club suit = shamrock, + U+2663 ISOpub --> +<!ENTITY hearts "♥"> <!-- black heart suit = valentine, + U+2665 ISOpub --> +<!ENTITY diams "♦"> <!-- black diamond suit, U+2666 ISOpub --> diff --git a/testing/web-platform/tests/css/tools/w3ctestlib/catalog/xhtml1-frameset.dtd b/testing/web-platform/tests/css/tools/w3ctestlib/catalog/xhtml1-frameset.dtd new file mode 100644 index 0000000000..d128f2eb7c --- /dev/null +++ b/testing/web-platform/tests/css/tools/w3ctestlib/catalog/xhtml1-frameset.dtd @@ -0,0 +1,1235 @@ +<!-- + Extensible HTML version 1.0 Frameset DTD + + This is the same as HTML 4 Frameset except for + changes due to the differences between XML and SGML. + + Namespace = http://www.w3.org/1999/xhtml + + For further information, see: http://www.w3.org/TR/xhtml1 + + Copyright (c) 1998-2002 W3C (MIT, INRIA, Keio), + All Rights Reserved. + + This DTD module is identified by the PUBLIC and SYSTEM identifiers: + + PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" + SYSTEM "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd" + + $Revision: 1.2 $ + $Date: 2002/08/01 18:37:55 $ + +--> + +<!--================ Character mnemonic entities =========================--> + +<!ENTITY % HTMLlat1 PUBLIC + "-//W3C//ENTITIES Latin 1 for XHTML//EN" + "xhtml-lat1.ent"> +%HTMLlat1; + +<!ENTITY % HTMLsymbol PUBLIC + "-//W3C//ENTITIES Symbols for XHTML//EN" + "xhtml-symbol.ent"> +%HTMLsymbol; + +<!ENTITY % HTMLspecial PUBLIC + "-//W3C//ENTITIES Special for XHTML//EN" + "xhtml-special.ent"> +%HTMLspecial; + +<!--================== Imported Names ====================================--> + +<!ENTITY % ContentType "CDATA"> + <!-- media type, as per [RFC2045] --> + +<!ENTITY % ContentTypes "CDATA"> + <!-- comma-separated list of media types, as per [RFC2045] --> + +<!ENTITY % Charset "CDATA"> + <!-- a character encoding, as per [RFC2045] --> + +<!ENTITY % Charsets "CDATA"> + <!-- a space separated list of character encodings, as per [RFC2045] --> + +<!ENTITY % LanguageCode "NMTOKEN"> + <!-- a language code, as per [RFC3066] --> + +<!ENTITY % Character "CDATA"> + <!-- a single character, as per section 2.2 of [XML] --> + +<!ENTITY % Number "CDATA"> + <!-- one or more digits --> + +<!ENTITY % LinkTypes "CDATA"> + <!-- space-separated list of link types --> + +<!ENTITY % MediaDesc "CDATA"> + <!-- single or comma-separated list of media descriptors --> + +<!ENTITY % URI "CDATA"> + <!-- a Uniform Resource Identifier, see [RFC2396] --> + +<!ENTITY % UriList "CDATA"> + <!-- a space separated list of Uniform Resource Identifiers --> + +<!ENTITY % Datetime "CDATA"> + <!-- date and time information. ISO date format --> + +<!ENTITY % Script "CDATA"> + <!-- script expression --> + +<!ENTITY % StyleSheet "CDATA"> + <!-- style sheet data --> + +<!ENTITY % Text "CDATA"> + <!-- used for titles etc. --> + +<!ENTITY % FrameTarget "NMTOKEN"> + <!-- render in this frame --> + +<!ENTITY % Length "CDATA"> + <!-- nn for pixels or nn% for percentage length --> + +<!ENTITY % MultiLength "CDATA"> + <!-- pixel, percentage, or relative --> + +<!ENTITY % MultiLengths "CDATA"> + <!-- comma-separated list of MultiLength --> + +<!ENTITY % Pixels "CDATA"> + <!-- integer representing length in pixels --> + +<!-- these are used for image maps --> + +<!ENTITY % Shape "(rect|circle|poly|default)"> + +<!ENTITY % Coords "CDATA"> + <!-- comma separated list of lengths --> + +<!-- used for object, applet, img, input and iframe --> +<!ENTITY % ImgAlign "(top|middle|bottom|left|right)"> + +<!-- a color using sRGB: #RRGGBB as Hex values --> +<!ENTITY % Color "CDATA"> + +<!-- There are also 16 widely known color names with their sRGB values: + + Black = #000000 Green = #008000 + Silver = #C0C0C0 Lime = #00FF00 + Gray = #808080 Olive = #808000 + White = #FFFFFF Yellow = #FFFF00 + Maroon = #800000 Navy = #000080 + Red = #FF0000 Blue = #0000FF + Purple = #800080 Teal = #008080 + Fuchsia= #FF00FF Aqua = #00FFFF +--> + +<!--=================== Generic Attributes ===============================--> + +<!-- core attributes common to most elements + id document-wide unique id + class space separated list of classes + style associated style info + title advisory title/amplification +--> +<!ENTITY % coreattrs + "id ID #IMPLIED + class CDATA #IMPLIED + style %StyleSheet; #IMPLIED + title %Text; #IMPLIED" + > + +<!-- internationalization attributes + lang language code (backwards compatible) + xml:lang language code (as per XML 1.0 spec) + dir direction for weak/neutral text +--> +<!ENTITY % i18n + "lang %LanguageCode; #IMPLIED + xml:lang %LanguageCode; #IMPLIED + dir (ltr|rtl) #IMPLIED" + > + +<!-- attributes for common UI events + onclick a pointer button was clicked + ondblclick a pointer button was double clicked + onmousedown a pointer button was pressed down + onmouseup a pointer button was released + onmousemove a pointer was moved onto the element + onmouseout a pointer was moved away from the element + onkeypress a key was pressed and released + onkeydown a key was pressed down + onkeyup a key was released +--> +<!ENTITY % events + "onclick %Script; #IMPLIED + ondblclick %Script; #IMPLIED + onmousedown %Script; #IMPLIED + onmouseup %Script; #IMPLIED + onmouseover %Script; #IMPLIED + onmousemove %Script; #IMPLIED + onmouseout %Script; #IMPLIED + onkeypress %Script; #IMPLIED + onkeydown %Script; #IMPLIED + onkeyup %Script; #IMPLIED" + > + +<!-- attributes for elements that can get the focus + accesskey accessibility key character + tabindex position in tabbing order + onfocus the element got the focus + onblur the element lost the focus +--> +<!ENTITY % focus + "accesskey %Character; #IMPLIED + tabindex %Number; #IMPLIED + onfocus %Script; #IMPLIED + onblur %Script; #IMPLIED" + > + +<!ENTITY % attrs "%coreattrs; %i18n; %events;"> + +<!-- text alignment for p, div, h1-h6. The default is + align="left" for ltr headings, "right" for rtl --> + +<!ENTITY % TextAlign "align (left|center|right|justify) #IMPLIED"> + +<!--=================== Text Elements ====================================--> + +<!ENTITY % special.extra + "object | applet | img | map | iframe"> + +<!ENTITY % special.basic + "br | span | bdo"> + +<!ENTITY % special + "%special.basic; | %special.extra;"> + +<!ENTITY % fontstyle.extra "big | small | font | basefont"> + +<!ENTITY % fontstyle.basic "tt | i | b | u + | s | strike "> + +<!ENTITY % fontstyle "%fontstyle.basic; | %fontstyle.extra;"> + +<!ENTITY % phrase.extra "sub | sup"> +<!ENTITY % phrase.basic "em | strong | dfn | code | q | + samp | kbd | var | cite | abbr | acronym"> + +<!ENTITY % phrase "%phrase.basic; | %phrase.extra;"> + +<!ENTITY % inline.forms "input | select | textarea | label | button"> + +<!-- these can occur at block or inline level --> +<!ENTITY % misc.inline "ins | del | script"> + +<!-- these can only occur at block level --> +<!ENTITY % misc "noscript | %misc.inline;"> + + +<!ENTITY % inline "a | %special; | %fontstyle; | %phrase; | %inline.forms;"> + +<!-- %Inline; covers inline or "text-level" elements --> +<!ENTITY % Inline "(#PCDATA | %inline; | %misc.inline;)*"> + +<!--================== Block level elements ==============================--> + +<!ENTITY % heading "h1|h2|h3|h4|h5|h6"> +<!ENTITY % lists "ul | ol | dl | menu | dir"> +<!ENTITY % blocktext "pre | hr | blockquote | address | center"> + +<!ENTITY % block + "p | %heading; | div | %lists; | %blocktext; | isindex | fieldset | table"> + +<!-- %Flow; mixes block and inline and is used for list items etc. --> +<!ENTITY % Flow "(#PCDATA | %block; | form | %inline; | %misc;)*"> + +<!--================== Content models for exclusions =====================--> + +<!-- a elements use %Inline; excluding a --> + +<!ENTITY % a.content + "(#PCDATA | %special; | %fontstyle; | %phrase; | %inline.forms; | %misc.inline;)*"> + +<!-- pre uses %Inline excluding img, object, applet, big, small, + sub, sup, font, or basefont --> + +<!ENTITY % pre.content + "(#PCDATA | a | %special.basic; | %fontstyle.basic; | %phrase.basic; | + %inline.forms; | %misc.inline;)*"> + + +<!-- form uses %Flow; excluding form --> + +<!ENTITY % form.content "(#PCDATA | %block; | %inline; | %misc;)*"> + +<!-- button uses %Flow; but excludes a, form, form controls, iframe --> + +<!ENTITY % button.content + "(#PCDATA | p | %heading; | div | %lists; | %blocktext; | + table | br | span | bdo | object | applet | img | map | + %fontstyle; | %phrase; | %misc;)*"> + +<!--================ Document Structure ==================================--> + +<!-- the namespace URI designates the document profile --> + +<!ELEMENT html (head, frameset)> +<!ATTLIST html + %i18n; + id ID #IMPLIED + xmlns %URI; #FIXED 'http://www.w3.org/1999/xhtml' + > + +<!--================ Document Head =======================================--> + +<!ENTITY % head.misc "(script|style|meta|link|object|isindex)*"> + +<!-- content model is %head.misc; combined with a single + title and an optional base element in any order --> + +<!ELEMENT head (%head.misc;, + ((title, %head.misc;, (base, %head.misc;)?) | + (base, %head.misc;, (title, %head.misc;))))> + +<!ATTLIST head + %i18n; + id ID #IMPLIED + profile %URI; #IMPLIED + > + +<!-- The title element is not considered part of the flow of text. + It should be displayed, for example as the page header or + window title. Exactly one title is required per document. + --> +<!ELEMENT title (#PCDATA)> +<!ATTLIST title + %i18n; + id ID #IMPLIED + > + +<!-- document base URI --> + +<!ELEMENT base EMPTY> +<!ATTLIST base + id ID #IMPLIED + href %URI; #IMPLIED + target %FrameTarget; #IMPLIED + > + +<!-- generic metainformation --> +<!ELEMENT meta EMPTY> +<!ATTLIST meta + %i18n; + id ID #IMPLIED + http-equiv CDATA #IMPLIED + name CDATA #IMPLIED + content CDATA #REQUIRED + scheme CDATA #IMPLIED + > + +<!-- + Relationship values can be used in principle: + + a) for document specific toolbars/menus when used + with the link element in document head e.g. + start, contents, previous, next, index, end, help + b) to link to a separate style sheet (rel="stylesheet") + c) to make a link to a script (rel="script") + d) by stylesheets to control how collections of + html nodes are rendered into printed documents + e) to make a link to a printable version of this document + e.g. a PostScript or PDF version (rel="alternate" media="print") +--> + +<!ELEMENT link EMPTY> +<!ATTLIST link + %attrs; + charset %Charset; #IMPLIED + href %URI; #IMPLIED + hreflang %LanguageCode; #IMPLIED + type %ContentType; #IMPLIED + rel %LinkTypes; #IMPLIED + rev %LinkTypes; #IMPLIED + media %MediaDesc; #IMPLIED + target %FrameTarget; #IMPLIED + > + +<!-- style info, which may include CDATA sections --> +<!ELEMENT style (#PCDATA)> +<!ATTLIST style + %i18n; + id ID #IMPLIED + type %ContentType; #REQUIRED + media %MediaDesc; #IMPLIED + title %Text; #IMPLIED + xml:space (preserve) #FIXED 'preserve' + > + +<!-- script statements, which may include CDATA sections --> +<!ELEMENT script (#PCDATA)> +<!ATTLIST script + id ID #IMPLIED + charset %Charset; #IMPLIED + type %ContentType; #REQUIRED + language CDATA #IMPLIED + src %URI; #IMPLIED + defer (defer) #IMPLIED + xml:space (preserve) #FIXED 'preserve' + > + +<!-- alternate content container for non script-based rendering --> + +<!ELEMENT noscript %Flow;> +<!ATTLIST noscript + %attrs; + > + +<!--======================= Frames =======================================--> + +<!-- only one noframes element permitted per document --> + +<!ELEMENT frameset (frameset|frame|noframes)*> +<!ATTLIST frameset + %coreattrs; + rows %MultiLengths; #IMPLIED + cols %MultiLengths; #IMPLIED + onload %Script; #IMPLIED + onunload %Script; #IMPLIED + > + +<!-- reserved frame names start with "_" otherwise starts with letter --> + +<!-- tiled window within frameset --> + +<!ELEMENT frame EMPTY> +<!ATTLIST frame + %coreattrs; + longdesc %URI; #IMPLIED + name NMTOKEN #IMPLIED + src %URI; #IMPLIED + frameborder (1|0) "1" + marginwidth %Pixels; #IMPLIED + marginheight %Pixels; #IMPLIED + noresize (noresize) #IMPLIED + scrolling (yes|no|auto) "auto" + > + +<!-- inline subwindow --> + +<!ELEMENT iframe %Flow;> +<!ATTLIST iframe + %coreattrs; + longdesc %URI; #IMPLIED + name NMTOKEN #IMPLIED + src %URI; #IMPLIED + frameborder (1|0) "1" + marginwidth %Pixels; #IMPLIED + marginheight %Pixels; #IMPLIED + scrolling (yes|no|auto) "auto" + align %ImgAlign; #IMPLIED + height %Length; #IMPLIED + width %Length; #IMPLIED + > + +<!-- alternate content container for non frame-based rendering --> + +<!ELEMENT noframes (body)> +<!ATTLIST noframes + %attrs; + > + +<!--=================== Document Body ====================================--> + +<!ELEMENT body %Flow;> +<!ATTLIST body + %attrs; + onload %Script; #IMPLIED + onunload %Script; #IMPLIED + background %URI; #IMPLIED + bgcolor %Color; #IMPLIED + text %Color; #IMPLIED + link %Color; #IMPLIED + vlink %Color; #IMPLIED + alink %Color; #IMPLIED + > + +<!ELEMENT div %Flow;> <!-- generic language/style container --> +<!ATTLIST div + %attrs; + %TextAlign; + > + +<!--=================== Paragraphs =======================================--> + +<!ELEMENT p %Inline;> +<!ATTLIST p + %attrs; + %TextAlign; + > + +<!--=================== Headings =========================================--> + +<!-- + There are six levels of headings from h1 (the most important) + to h6 (the least important). +--> + +<!ELEMENT h1 %Inline;> +<!ATTLIST h1 + %attrs; + %TextAlign; + > + +<!ELEMENT h2 %Inline;> +<!ATTLIST h2 + %attrs; + %TextAlign; + > + +<!ELEMENT h3 %Inline;> +<!ATTLIST h3 + %attrs; + %TextAlign; + > + +<!ELEMENT h4 %Inline;> +<!ATTLIST h4 + %attrs; + %TextAlign; + > + +<!ELEMENT h5 %Inline;> +<!ATTLIST h5 + %attrs; + %TextAlign; + > + +<!ELEMENT h6 %Inline;> +<!ATTLIST h6 + %attrs; + %TextAlign; + > + +<!--=================== Lists ============================================--> + +<!-- Unordered list bullet styles --> + +<!ENTITY % ULStyle "(disc|square|circle)"> + +<!-- Unordered list --> + +<!ELEMENT ul (li)+> +<!ATTLIST ul + %attrs; + type %ULStyle; #IMPLIED + compact (compact) #IMPLIED + > + +<!-- Ordered list numbering style + + 1 arabic numbers 1, 2, 3, ... + a lower alpha a, b, c, ... + A upper alpha A, B, C, ... + i lower roman i, ii, iii, ... + I upper roman I, II, III, ... + + The style is applied to the sequence number which by default + is reset to 1 for the first list item in an ordered list. +--> +<!ENTITY % OLStyle "CDATA"> + +<!-- Ordered (numbered) list --> + +<!ELEMENT ol (li)+> +<!ATTLIST ol + %attrs; + type %OLStyle; #IMPLIED + compact (compact) #IMPLIED + start %Number; #IMPLIED + > + +<!-- single column list (DEPRECATED) --> +<!ELEMENT menu (li)+> +<!ATTLIST menu + %attrs; + compact (compact) #IMPLIED + > + +<!-- multiple column list (DEPRECATED) --> +<!ELEMENT dir (li)+> +<!ATTLIST dir + %attrs; + compact (compact) #IMPLIED + > + +<!-- LIStyle is constrained to: "(%ULStyle;|%OLStyle;)" --> +<!ENTITY % LIStyle "CDATA"> + +<!-- list item --> + +<!ELEMENT li %Flow;> +<!ATTLIST li + %attrs; + type %LIStyle; #IMPLIED + value %Number; #IMPLIED + > + +<!-- definition lists - dt for term, dd for its definition --> + +<!ELEMENT dl (dt|dd)+> +<!ATTLIST dl + %attrs; + compact (compact) #IMPLIED + > + +<!ELEMENT dt %Inline;> +<!ATTLIST dt + %attrs; + > + +<!ELEMENT dd %Flow;> +<!ATTLIST dd + %attrs; + > + +<!--=================== Address ==========================================--> + +<!-- information on author --> + +<!ELEMENT address (#PCDATA | %inline; | %misc.inline; | p)*> +<!ATTLIST address + %attrs; + > + +<!--=================== Horizontal Rule ==================================--> + +<!ELEMENT hr EMPTY> +<!ATTLIST hr + %attrs; + align (left|center|right) #IMPLIED + noshade (noshade) #IMPLIED + size %Pixels; #IMPLIED + width %Length; #IMPLIED + > + +<!--=================== Preformatted Text ================================--> + +<!-- content is %Inline; excluding + "img|object|applet|big|small|sub|sup|font|basefont" --> + +<!ELEMENT pre %pre.content;> +<!ATTLIST pre + %attrs; + width %Number; #IMPLIED + xml:space (preserve) #FIXED 'preserve' + > + +<!--=================== Block-like Quotes ================================--> + +<!ELEMENT blockquote %Flow;> +<!ATTLIST blockquote + %attrs; + cite %URI; #IMPLIED + > + +<!--=================== Text alignment ===================================--> + +<!-- center content --> +<!ELEMENT center %Flow;> +<!ATTLIST center + %attrs; + > + +<!--=================== Inserted/Deleted Text ============================--> + + +<!-- + ins/del are allowed in block and inline content, but its + inappropriate to include block content within an ins element + occurring in inline content. +--> +<!ELEMENT ins %Flow;> +<!ATTLIST ins + %attrs; + cite %URI; #IMPLIED + datetime %Datetime; #IMPLIED + > + +<!ELEMENT del %Flow;> +<!ATTLIST del + %attrs; + cite %URI; #IMPLIED + datetime %Datetime; #IMPLIED + > + +<!--================== The Anchor Element ================================--> + +<!-- content is %Inline; except that anchors shouldn't be nested --> + +<!ELEMENT a %a.content;> +<!ATTLIST a + %attrs; + %focus; + charset %Charset; #IMPLIED + type %ContentType; #IMPLIED + name NMTOKEN #IMPLIED + href %URI; #IMPLIED + hreflang %LanguageCode; #IMPLIED + rel %LinkTypes; #IMPLIED + rev %LinkTypes; #IMPLIED + shape %Shape; "rect" + coords %Coords; #IMPLIED + target %FrameTarget; #IMPLIED + > + +<!--===================== Inline Elements ================================--> + +<!ELEMENT span %Inline;> <!-- generic language/style container --> +<!ATTLIST span + %attrs; + > + +<!ELEMENT bdo %Inline;> <!-- I18N BiDi over-ride --> +<!ATTLIST bdo + %coreattrs; + %events; + lang %LanguageCode; #IMPLIED + xml:lang %LanguageCode; #IMPLIED + dir (ltr|rtl) #REQUIRED + > + +<!ELEMENT br EMPTY> <!-- forced line break --> +<!ATTLIST br + %coreattrs; + clear (left|all|right|none) "none" + > + +<!ELEMENT em %Inline;> <!-- emphasis --> +<!ATTLIST em %attrs;> + +<!ELEMENT strong %Inline;> <!-- strong emphasis --> +<!ATTLIST strong %attrs;> + +<!ELEMENT dfn %Inline;> <!-- definitional --> +<!ATTLIST dfn %attrs;> + +<!ELEMENT code %Inline;> <!-- program code --> +<!ATTLIST code %attrs;> + +<!ELEMENT samp %Inline;> <!-- sample --> +<!ATTLIST samp %attrs;> + +<!ELEMENT kbd %Inline;> <!-- something user would type --> +<!ATTLIST kbd %attrs;> + +<!ELEMENT var %Inline;> <!-- variable --> +<!ATTLIST var %attrs;> + +<!ELEMENT cite %Inline;> <!-- citation --> +<!ATTLIST cite %attrs;> + +<!ELEMENT abbr %Inline;> <!-- abbreviation --> +<!ATTLIST abbr %attrs;> + +<!ELEMENT acronym %Inline;> <!-- acronym --> +<!ATTLIST acronym %attrs;> + +<!ELEMENT q %Inline;> <!-- inlined quote --> +<!ATTLIST q + %attrs; + cite %URI; #IMPLIED + > + +<!ELEMENT sub %Inline;> <!-- subscript --> +<!ATTLIST sub %attrs;> + +<!ELEMENT sup %Inline;> <!-- superscript --> +<!ATTLIST sup %attrs;> + +<!ELEMENT tt %Inline;> <!-- fixed pitch font --> +<!ATTLIST tt %attrs;> + +<!ELEMENT i %Inline;> <!-- italic font --> +<!ATTLIST i %attrs;> + +<!ELEMENT b %Inline;> <!-- bold font --> +<!ATTLIST b %attrs;> + +<!ELEMENT big %Inline;> <!-- bigger font --> +<!ATTLIST big %attrs;> + +<!ELEMENT small %Inline;> <!-- smaller font --> +<!ATTLIST small %attrs;> + +<!ELEMENT u %Inline;> <!-- underline --> +<!ATTLIST u %attrs;> + +<!ELEMENT s %Inline;> <!-- strike-through --> +<!ATTLIST s %attrs;> + +<!ELEMENT strike %Inline;> <!-- strike-through --> +<!ATTLIST strike %attrs;> + +<!ELEMENT basefont EMPTY> <!-- base font size --> +<!ATTLIST basefont + id ID #IMPLIED + size CDATA #REQUIRED + color %Color; #IMPLIED + face CDATA #IMPLIED + > + +<!ELEMENT font %Inline;> <!-- local change to font --> +<!ATTLIST font + %coreattrs; + %i18n; + size CDATA #IMPLIED + color %Color; #IMPLIED + face CDATA #IMPLIED + > + +<!--==================== Object ======================================--> +<!-- + object is used to embed objects as part of HTML pages. + param elements should precede other content. Parameters + can also be expressed as attribute/value pairs on the + object element itself when brevity is desired. +--> + +<!ELEMENT object (#PCDATA | param | %block; | form |%inline; | %misc;)*> +<!ATTLIST object + %attrs; + declare (declare) #IMPLIED + classid %URI; #IMPLIED + codebase %URI; #IMPLIED + data %URI; #IMPLIED + type %ContentType; #IMPLIED + codetype %ContentType; #IMPLIED + archive %UriList; #IMPLIED + standby %Text; #IMPLIED + height %Length; #IMPLIED + width %Length; #IMPLIED + usemap %URI; #IMPLIED + name NMTOKEN #IMPLIED + tabindex %Number; #IMPLIED + align %ImgAlign; #IMPLIED + border %Pixels; #IMPLIED + hspace %Pixels; #IMPLIED + vspace %Pixels; #IMPLIED + > + +<!-- + param is used to supply a named property value. + In XML it would seem natural to follow RDF and support an + abbreviated syntax where the param elements are replaced + by attribute value pairs on the object start tag. +--> +<!ELEMENT param EMPTY> +<!ATTLIST param + id ID #IMPLIED + name CDATA #REQUIRED + value CDATA #IMPLIED + valuetype (data|ref|object) "data" + type %ContentType; #IMPLIED + > + +<!--=================== Java applet ==================================--> +<!-- + One of code or object attributes must be present. + Place param elements before other content. +--> +<!ELEMENT applet (#PCDATA | param | %block; | form | %inline; | %misc;)*> +<!ATTLIST applet + %coreattrs; + codebase %URI; #IMPLIED + archive CDATA #IMPLIED + code CDATA #IMPLIED + object CDATA #IMPLIED + alt %Text; #IMPLIED + name NMTOKEN #IMPLIED + width %Length; #REQUIRED + height %Length; #REQUIRED + align %ImgAlign; #IMPLIED + hspace %Pixels; #IMPLIED + vspace %Pixels; #IMPLIED + > + +<!--=================== Images ===========================================--> + +<!-- + To avoid accessibility problems for people who aren't + able to see the image, you should provide a text + description using the alt and longdesc attributes. + In addition, avoid the use of server-side image maps. +--> + +<!ELEMENT img EMPTY> +<!ATTLIST img + %attrs; + src %URI; #REQUIRED + alt %Text; #REQUIRED + name NMTOKEN #IMPLIED + longdesc %URI; #IMPLIED + height %Length; #IMPLIED + width %Length; #IMPLIED + usemap %URI; #IMPLIED + ismap (ismap) #IMPLIED + align %ImgAlign; #IMPLIED + border %Pixels; #IMPLIED + hspace %Pixels; #IMPLIED + vspace %Pixels; #IMPLIED + > + +<!-- usemap points to a map element which may be in this document + or an external document, although the latter is not widely supported --> + +<!--================== Client-side image maps ============================--> + +<!-- These can be placed in the same document or grouped in a + separate document although this isn't yet widely supported --> + +<!ELEMENT map ((%block; | form | %misc;)+ | area+)> +<!ATTLIST map + %i18n; + %events; + id ID #REQUIRED + class CDATA #IMPLIED + style %StyleSheet; #IMPLIED + title %Text; #IMPLIED + name NMTOKEN #IMPLIED + > + +<!ELEMENT area EMPTY> +<!ATTLIST area + %attrs; + %focus; + shape %Shape; "rect" + coords %Coords; #IMPLIED + href %URI; #IMPLIED + nohref (nohref) #IMPLIED + alt %Text; #REQUIRED + target %FrameTarget; #IMPLIED + > + +<!--================ Forms ===============================================--> + +<!ELEMENT form %form.content;> <!-- forms shouldn't be nested --> + +<!ATTLIST form + %attrs; + action %URI; #REQUIRED + method (get|post) "get" + name NMTOKEN #IMPLIED + enctype %ContentType; "application/x-www-form-urlencoded" + onsubmit %Script; #IMPLIED + onreset %Script; #IMPLIED + accept %ContentTypes; #IMPLIED + accept-charset %Charsets; #IMPLIED + target %FrameTarget; #IMPLIED + > + +<!-- + Each label must not contain more than ONE field + Label elements shouldn't be nested. +--> +<!ELEMENT label %Inline;> +<!ATTLIST label + %attrs; + for IDREF #IMPLIED + accesskey %Character; #IMPLIED + onfocus %Script; #IMPLIED + onblur %Script; #IMPLIED + > + +<!ENTITY % InputType + "(text | password | checkbox | + radio | submit | reset | + file | hidden | image | button)" + > + +<!-- the name attribute is required for all but submit & reset --> + +<!ELEMENT input EMPTY> <!-- form control --> +<!ATTLIST input + %attrs; + %focus; + type %InputType; "text" + name CDATA #IMPLIED + value CDATA #IMPLIED + checked (checked) #IMPLIED + disabled (disabled) #IMPLIED + readonly (readonly) #IMPLIED + size CDATA #IMPLIED + maxlength %Number; #IMPLIED + src %URI; #IMPLIED + alt CDATA #IMPLIED + usemap %URI; #IMPLIED + onselect %Script; #IMPLIED + onchange %Script; #IMPLIED + accept %ContentTypes; #IMPLIED + align %ImgAlign; #IMPLIED + > + +<!ELEMENT select (optgroup|option)+> <!-- option selector --> +<!ATTLIST select + %attrs; + name CDATA #IMPLIED + size %Number; #IMPLIED + multiple (multiple) #IMPLIED + disabled (disabled) #IMPLIED + tabindex %Number; #IMPLIED + onfocus %Script; #IMPLIED + onblur %Script; #IMPLIED + onchange %Script; #IMPLIED + > + +<!ELEMENT optgroup (option)+> <!-- option group --> +<!ATTLIST optgroup + %attrs; + disabled (disabled) #IMPLIED + label %Text; #REQUIRED + > + +<!ELEMENT option (#PCDATA)> <!-- selectable choice --> +<!ATTLIST option + %attrs; + selected (selected) #IMPLIED + disabled (disabled) #IMPLIED + label %Text; #IMPLIED + value CDATA #IMPLIED + > + +<!ELEMENT textarea (#PCDATA)> <!-- multi-line text field --> +<!ATTLIST textarea + %attrs; + %focus; + name CDATA #IMPLIED + rows %Number; #REQUIRED + cols %Number; #REQUIRED + disabled (disabled) #IMPLIED + readonly (readonly) #IMPLIED + onselect %Script; #IMPLIED + onchange %Script; #IMPLIED + > + +<!-- + The fieldset element is used to group form fields. + Only one legend element should occur in the content + and if present should only be preceded by whitespace. +--> +<!ELEMENT fieldset (#PCDATA | legend | %block; | form | %inline; | %misc;)*> +<!ATTLIST fieldset + %attrs; + > + +<!ENTITY % LAlign "(top|bottom|left|right)"> + +<!ELEMENT legend %Inline;> <!-- fieldset label --> +<!ATTLIST legend + %attrs; + accesskey %Character; #IMPLIED + align %LAlign; #IMPLIED + > + +<!-- + Content is %Flow; excluding a, form, form controls, iframe +--> +<!ELEMENT button %button.content;> <!-- push button --> +<!ATTLIST button + %attrs; + %focus; + name CDATA #IMPLIED + value CDATA #IMPLIED + type (button|submit|reset) "submit" + disabled (disabled) #IMPLIED + > + +<!-- single-line text input control (DEPRECATED) --> +<!ELEMENT isindex EMPTY> +<!ATTLIST isindex + %coreattrs; + %i18n; + prompt %Text; #IMPLIED + > + +<!--======================= Tables =======================================--> + +<!-- Derived from IETF HTML table standard, see [RFC1942] --> + +<!-- + The border attribute sets the thickness of the frame around the + table. The default units are screen pixels. + + The frame attribute specifies which parts of the frame around + the table should be rendered. The values are not the same as + CALS to avoid a name clash with the valign attribute. +--> +<!ENTITY % TFrame "(void|above|below|hsides|lhs|rhs|vsides|box|border)"> + +<!-- + The rules attribute defines which rules to draw between cells: + + If rules is absent then assume: + "none" if border is absent or border="0" otherwise "all" +--> + +<!ENTITY % TRules "(none | groups | rows | cols | all)"> + +<!-- horizontal placement of table relative to document --> +<!ENTITY % TAlign "(left|center|right)"> + +<!-- horizontal alignment attributes for cell contents + + char alignment char, e.g. char=":" + charoff offset for alignment char +--> +<!ENTITY % cellhalign + "align (left|center|right|justify|char) #IMPLIED + char %Character; #IMPLIED + charoff %Length; #IMPLIED" + > + +<!-- vertical alignment attributes for cell contents --> +<!ENTITY % cellvalign + "valign (top|middle|bottom|baseline) #IMPLIED" + > + +<!ELEMENT table + (caption?, (col*|colgroup*), thead?, tfoot?, (tbody+|tr+))> +<!ELEMENT caption %Inline;> +<!ELEMENT thead (tr)+> +<!ELEMENT tfoot (tr)+> +<!ELEMENT tbody (tr)+> +<!ELEMENT colgroup (col)*> +<!ELEMENT col EMPTY> +<!ELEMENT tr (th|td)+> +<!ELEMENT th %Flow;> +<!ELEMENT td %Flow;> + +<!ATTLIST table + %attrs; + summary %Text; #IMPLIED + width %Length; #IMPLIED + border %Pixels; #IMPLIED + frame %TFrame; #IMPLIED + rules %TRules; #IMPLIED + cellspacing %Length; #IMPLIED + cellpadding %Length; #IMPLIED + align %TAlign; #IMPLIED + bgcolor %Color; #IMPLIED + > + +<!ENTITY % CAlign "(top|bottom|left|right)"> + +<!ATTLIST caption + %attrs; + align %CAlign; #IMPLIED + > + +<!-- +colgroup groups a set of col elements. It allows you to group +several semantically related columns together. +--> +<!ATTLIST colgroup + %attrs; + span %Number; "1" + width %MultiLength; #IMPLIED + %cellhalign; + %cellvalign; + > + +<!-- + col elements define the alignment properties for cells in + one or more columns. + + The width attribute specifies the width of the columns, e.g. + + width=64 width in screen pixels + width=0.5* relative width of 0.5 + + The span attribute causes the attributes of one + col element to apply to more than one column. +--> +<!ATTLIST col + %attrs; + span %Number; "1" + width %MultiLength; #IMPLIED + %cellhalign; + %cellvalign; + > + +<!-- + Use thead to duplicate headers when breaking table + across page boundaries, or for static headers when + tbody sections are rendered in scrolling panel. + + Use tfoot to duplicate footers when breaking table + across page boundaries, or for static footers when + tbody sections are rendered in scrolling panel. + + Use multiple tbody sections when rules are needed + between groups of table rows. +--> +<!ATTLIST thead + %attrs; + %cellhalign; + %cellvalign; + > + +<!ATTLIST tfoot + %attrs; + %cellhalign; + %cellvalign; + > + +<!ATTLIST tbody + %attrs; + %cellhalign; + %cellvalign; + > + +<!ATTLIST tr + %attrs; + %cellhalign; + %cellvalign; + bgcolor %Color; #IMPLIED + > + +<!-- Scope is simpler than headers attribute for common tables --> +<!ENTITY % Scope "(row|col|rowgroup|colgroup)"> + +<!-- th is for headers, td for data and for cells acting as both --> + +<!ATTLIST th + %attrs; + abbr %Text; #IMPLIED + axis CDATA #IMPLIED + headers IDREFS #IMPLIED + scope %Scope; #IMPLIED + rowspan %Number; "1" + colspan %Number; "1" + %cellhalign; + %cellvalign; + nowrap (nowrap) #IMPLIED + bgcolor %Color; #IMPLIED + width %Pixels; #IMPLIED + height %Pixels; #IMPLIED + > + +<!ATTLIST td + %attrs; + abbr %Text; #IMPLIED + axis CDATA #IMPLIED + headers IDREFS #IMPLIED + scope %Scope; #IMPLIED + rowspan %Number; "1" + colspan %Number; "1" + %cellhalign; + %cellvalign; + nowrap (nowrap) #IMPLIED + bgcolor %Color; #IMPLIED + width %Pixels; #IMPLIED + height %Pixels; #IMPLIED + > + diff --git a/testing/web-platform/tests/css/tools/w3ctestlib/catalog/xhtml1-strict.dtd b/testing/web-platform/tests/css/tools/w3ctestlib/catalog/xhtml1-strict.dtd new file mode 100644 index 0000000000..2927b9ece7 --- /dev/null +++ b/testing/web-platform/tests/css/tools/w3ctestlib/catalog/xhtml1-strict.dtd @@ -0,0 +1,978 @@ +<!-- + Extensible HTML version 1.0 Strict DTD + + This is the same as HTML 4 Strict except for + changes due to the differences between XML and SGML. + + Namespace = http://www.w3.org/1999/xhtml + + For further information, see: http://www.w3.org/TR/xhtml1 + + Copyright (c) 1998-2002 W3C (MIT, INRIA, Keio), + All Rights Reserved. + + This DTD module is identified by the PUBLIC and SYSTEM identifiers: + + PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + SYSTEM "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd" + + $Revision: 1.1 $ + $Date: 2002/08/01 13:56:03 $ + +--> + +<!--================ Character mnemonic entities =========================--> + +<!ENTITY % HTMLlat1 PUBLIC + "-//W3C//ENTITIES Latin 1 for XHTML//EN" + "xhtml-lat1.ent"> +%HTMLlat1; + +<!ENTITY % HTMLsymbol PUBLIC + "-//W3C//ENTITIES Symbols for XHTML//EN" + "xhtml-symbol.ent"> +%HTMLsymbol; + +<!ENTITY % HTMLspecial PUBLIC + "-//W3C//ENTITIES Special for XHTML//EN" + "xhtml-special.ent"> +%HTMLspecial; + +<!--================== Imported Names ====================================--> + +<!ENTITY % ContentType "CDATA"> + <!-- media type, as per [RFC2045] --> + +<!ENTITY % ContentTypes "CDATA"> + <!-- comma-separated list of media types, as per [RFC2045] --> + +<!ENTITY % Charset "CDATA"> + <!-- a character encoding, as per [RFC2045] --> + +<!ENTITY % Charsets "CDATA"> + <!-- a space separated list of character encodings, as per [RFC2045] --> + +<!ENTITY % LanguageCode "NMTOKEN"> + <!-- a language code, as per [RFC3066] --> + +<!ENTITY % Character "CDATA"> + <!-- a single character, as per section 2.2 of [XML] --> + +<!ENTITY % Number "CDATA"> + <!-- one or more digits --> + +<!ENTITY % LinkTypes "CDATA"> + <!-- space-separated list of link types --> + +<!ENTITY % MediaDesc "CDATA"> + <!-- single or comma-separated list of media descriptors --> + +<!ENTITY % URI "CDATA"> + <!-- a Uniform Resource Identifier, see [RFC2396] --> + +<!ENTITY % UriList "CDATA"> + <!-- a space separated list of Uniform Resource Identifiers --> + +<!ENTITY % Datetime "CDATA"> + <!-- date and time information. ISO date format --> + +<!ENTITY % Script "CDATA"> + <!-- script expression --> + +<!ENTITY % StyleSheet "CDATA"> + <!-- style sheet data --> + +<!ENTITY % Text "CDATA"> + <!-- used for titles etc. --> + +<!ENTITY % Length "CDATA"> + <!-- nn for pixels or nn% for percentage length --> + +<!ENTITY % MultiLength "CDATA"> + <!-- pixel, percentage, or relative --> + +<!ENTITY % Pixels "CDATA"> + <!-- integer representing length in pixels --> + +<!-- these are used for image maps --> + +<!ENTITY % Shape "(rect|circle|poly|default)"> + +<!ENTITY % Coords "CDATA"> + <!-- comma separated list of lengths --> + +<!--=================== Generic Attributes ===============================--> + +<!-- core attributes common to most elements + id document-wide unique id + class space separated list of classes + style associated style info + title advisory title/amplification +--> +<!ENTITY % coreattrs + "id ID #IMPLIED + class CDATA #IMPLIED + style %StyleSheet; #IMPLIED + title %Text; #IMPLIED" + > + +<!-- internationalization attributes + lang language code (backwards compatible) + xml:lang language code (as per XML 1.0 spec) + dir direction for weak/neutral text +--> +<!ENTITY % i18n + "lang %LanguageCode; #IMPLIED + xml:lang %LanguageCode; #IMPLIED + dir (ltr|rtl) #IMPLIED" + > + +<!-- attributes for common UI events + onclick a pointer button was clicked + ondblclick a pointer button was double clicked + onmousedown a pointer button was pressed down + onmouseup a pointer button was released + onmousemove a pointer was moved onto the element + onmouseout a pointer was moved away from the element + onkeypress a key was pressed and released + onkeydown a key was pressed down + onkeyup a key was released +--> +<!ENTITY % events + "onclick %Script; #IMPLIED + ondblclick %Script; #IMPLIED + onmousedown %Script; #IMPLIED + onmouseup %Script; #IMPLIED + onmouseover %Script; #IMPLIED + onmousemove %Script; #IMPLIED + onmouseout %Script; #IMPLIED + onkeypress %Script; #IMPLIED + onkeydown %Script; #IMPLIED + onkeyup %Script; #IMPLIED" + > + +<!-- attributes for elements that can get the focus + accesskey accessibility key character + tabindex position in tabbing order + onfocus the element got the focus + onblur the element lost the focus +--> +<!ENTITY % focus + "accesskey %Character; #IMPLIED + tabindex %Number; #IMPLIED + onfocus %Script; #IMPLIED + onblur %Script; #IMPLIED" + > + +<!ENTITY % attrs "%coreattrs; %i18n; %events;"> + +<!--=================== Text Elements ====================================--> + +<!ENTITY % special.pre + "br | span | bdo | map"> + + +<!ENTITY % special + "%special.pre; | object | img "> + +<!ENTITY % fontstyle "tt | i | b | big | small "> + +<!ENTITY % phrase "em | strong | dfn | code | q | + samp | kbd | var | cite | abbr | acronym | sub | sup "> + +<!ENTITY % inline.forms "input | select | textarea | label | button"> + +<!-- these can occur at block or inline level --> +<!ENTITY % misc.inline "ins | del | script"> + +<!-- these can only occur at block level --> +<!ENTITY % misc "noscript | %misc.inline;"> + +<!ENTITY % inline "a | %special; | %fontstyle; | %phrase; | %inline.forms;"> + +<!-- %Inline; covers inline or "text-level" elements --> +<!ENTITY % Inline "(#PCDATA | %inline; | %misc.inline;)*"> + +<!--================== Block level elements ==============================--> + +<!ENTITY % heading "h1|h2|h3|h4|h5|h6"> +<!ENTITY % lists "ul | ol | dl"> +<!ENTITY % blocktext "pre | hr | blockquote | address"> + +<!ENTITY % block + "p | %heading; | div | %lists; | %blocktext; | fieldset | table"> + +<!ENTITY % Block "(%block; | form | %misc;)*"> + +<!-- %Flow; mixes block and inline and is used for list items etc. --> +<!ENTITY % Flow "(#PCDATA | %block; | form | %inline; | %misc;)*"> + +<!--================== Content models for exclusions =====================--> + +<!-- a elements use %Inline; excluding a --> + +<!ENTITY % a.content + "(#PCDATA | %special; | %fontstyle; | %phrase; | %inline.forms; | %misc.inline;)*"> + +<!-- pre uses %Inline excluding big, small, sup or sup --> + +<!ENTITY % pre.content + "(#PCDATA | a | %fontstyle; | %phrase; | %special.pre; | %misc.inline; + | %inline.forms;)*"> + +<!-- form uses %Block; excluding form --> + +<!ENTITY % form.content "(%block; | %misc;)*"> + +<!-- button uses %Flow; but excludes a, form and form controls --> + +<!ENTITY % button.content + "(#PCDATA | p | %heading; | div | %lists; | %blocktext; | + table | %special; | %fontstyle; | %phrase; | %misc;)*"> + +<!--================ Document Structure ==================================--> + +<!-- the namespace URI designates the document profile --> + +<!ELEMENT html (head, body)> +<!ATTLIST html + %i18n; + id ID #IMPLIED + xmlns %URI; #FIXED 'http://www.w3.org/1999/xhtml' + > + +<!--================ Document Head =======================================--> + +<!ENTITY % head.misc "(script|style|meta|link|object)*"> + +<!-- content model is %head.misc; combined with a single + title and an optional base element in any order --> + +<!ELEMENT head (%head.misc;, + ((title, %head.misc;, (base, %head.misc;)?) | + (base, %head.misc;, (title, %head.misc;))))> + +<!ATTLIST head + %i18n; + id ID #IMPLIED + profile %URI; #IMPLIED + > + +<!-- The title element is not considered part of the flow of text. + It should be displayed, for example as the page header or + window title. Exactly one title is required per document. + --> +<!ELEMENT title (#PCDATA)> +<!ATTLIST title + %i18n; + id ID #IMPLIED + > + +<!-- document base URI --> + +<!ELEMENT base EMPTY> +<!ATTLIST base + href %URI; #REQUIRED + id ID #IMPLIED + > + +<!-- generic metainformation --> +<!ELEMENT meta EMPTY> +<!ATTLIST meta + %i18n; + id ID #IMPLIED + http-equiv CDATA #IMPLIED + name CDATA #IMPLIED + content CDATA #REQUIRED + scheme CDATA #IMPLIED + > + +<!-- + Relationship values can be used in principle: + + a) for document specific toolbars/menus when used + with the link element in document head e.g. + start, contents, previous, next, index, end, help + b) to link to a separate style sheet (rel="stylesheet") + c) to make a link to a script (rel="script") + d) by stylesheets to control how collections of + html nodes are rendered into printed documents + e) to make a link to a printable version of this document + e.g. a PostScript or PDF version (rel="alternate" media="print") +--> + +<!ELEMENT link EMPTY> +<!ATTLIST link + %attrs; + charset %Charset; #IMPLIED + href %URI; #IMPLIED + hreflang %LanguageCode; #IMPLIED + type %ContentType; #IMPLIED + rel %LinkTypes; #IMPLIED + rev %LinkTypes; #IMPLIED + media %MediaDesc; #IMPLIED + > + +<!-- style info, which may include CDATA sections --> +<!ELEMENT style (#PCDATA)> +<!ATTLIST style + %i18n; + id ID #IMPLIED + type %ContentType; #REQUIRED + media %MediaDesc; #IMPLIED + title %Text; #IMPLIED + xml:space (preserve) #FIXED 'preserve' + > + +<!-- script statements, which may include CDATA sections --> +<!ELEMENT script (#PCDATA)> +<!ATTLIST script + id ID #IMPLIED + charset %Charset; #IMPLIED + type %ContentType; #REQUIRED + src %URI; #IMPLIED + defer (defer) #IMPLIED + xml:space (preserve) #FIXED 'preserve' + > + +<!-- alternate content container for non script-based rendering --> + +<!ELEMENT noscript %Block;> +<!ATTLIST noscript + %attrs; + > + +<!--=================== Document Body ====================================--> + +<!ELEMENT body %Block;> +<!ATTLIST body + %attrs; + onload %Script; #IMPLIED + onunload %Script; #IMPLIED + > + +<!ELEMENT div %Flow;> <!-- generic language/style container --> +<!ATTLIST div + %attrs; + > + +<!--=================== Paragraphs =======================================--> + +<!ELEMENT p %Inline;> +<!ATTLIST p + %attrs; + > + +<!--=================== Headings =========================================--> + +<!-- + There are six levels of headings from h1 (the most important) + to h6 (the least important). +--> + +<!ELEMENT h1 %Inline;> +<!ATTLIST h1 + %attrs; + > + +<!ELEMENT h2 %Inline;> +<!ATTLIST h2 + %attrs; + > + +<!ELEMENT h3 %Inline;> +<!ATTLIST h3 + %attrs; + > + +<!ELEMENT h4 %Inline;> +<!ATTLIST h4 + %attrs; + > + +<!ELEMENT h5 %Inline;> +<!ATTLIST h5 + %attrs; + > + +<!ELEMENT h6 %Inline;> +<!ATTLIST h6 + %attrs; + > + +<!--=================== Lists ============================================--> + +<!-- Unordered list --> + +<!ELEMENT ul (li)+> +<!ATTLIST ul + %attrs; + > + +<!-- Ordered (numbered) list --> + +<!ELEMENT ol (li)+> +<!ATTLIST ol + %attrs; + > + +<!-- list item --> + +<!ELEMENT li %Flow;> +<!ATTLIST li + %attrs; + > + +<!-- definition lists - dt for term, dd for its definition --> + +<!ELEMENT dl (dt|dd)+> +<!ATTLIST dl + %attrs; + > + +<!ELEMENT dt %Inline;> +<!ATTLIST dt + %attrs; + > + +<!ELEMENT dd %Flow;> +<!ATTLIST dd + %attrs; + > + +<!--=================== Address ==========================================--> + +<!-- information on author --> + +<!ELEMENT address %Inline;> +<!ATTLIST address + %attrs; + > + +<!--=================== Horizontal Rule ==================================--> + +<!ELEMENT hr EMPTY> +<!ATTLIST hr + %attrs; + > + +<!--=================== Preformatted Text ================================--> + +<!-- content is %Inline; excluding "img|object|big|small|sub|sup" --> + +<!ELEMENT pre %pre.content;> +<!ATTLIST pre + %attrs; + xml:space (preserve) #FIXED 'preserve' + > + +<!--=================== Block-like Quotes ================================--> + +<!ELEMENT blockquote %Block;> +<!ATTLIST blockquote + %attrs; + cite %URI; #IMPLIED + > + +<!--=================== Inserted/Deleted Text ============================--> + +<!-- + ins/del are allowed in block and inline content, but its + inappropriate to include block content within an ins element + occurring in inline content. +--> +<!ELEMENT ins %Flow;> +<!ATTLIST ins + %attrs; + cite %URI; #IMPLIED + datetime %Datetime; #IMPLIED + > + +<!ELEMENT del %Flow;> +<!ATTLIST del + %attrs; + cite %URI; #IMPLIED + datetime %Datetime; #IMPLIED + > + +<!--================== The Anchor Element ================================--> + +<!-- content is %Inline; except that anchors shouldn't be nested --> + +<!ELEMENT a %a.content;> +<!ATTLIST a + %attrs; + %focus; + charset %Charset; #IMPLIED + type %ContentType; #IMPLIED + name NMTOKEN #IMPLIED + href %URI; #IMPLIED + hreflang %LanguageCode; #IMPLIED + rel %LinkTypes; #IMPLIED + rev %LinkTypes; #IMPLIED + shape %Shape; "rect" + coords %Coords; #IMPLIED + > + +<!--===================== Inline Elements ================================--> + +<!ELEMENT span %Inline;> <!-- generic language/style container --> +<!ATTLIST span + %attrs; + > + +<!ELEMENT bdo %Inline;> <!-- I18N BiDi over-ride --> +<!ATTLIST bdo + %coreattrs; + %events; + lang %LanguageCode; #IMPLIED + xml:lang %LanguageCode; #IMPLIED + dir (ltr|rtl) #REQUIRED + > + +<!ELEMENT br EMPTY> <!-- forced line break --> +<!ATTLIST br + %coreattrs; + > + +<!ELEMENT em %Inline;> <!-- emphasis --> +<!ATTLIST em %attrs;> + +<!ELEMENT strong %Inline;> <!-- strong emphasis --> +<!ATTLIST strong %attrs;> + +<!ELEMENT dfn %Inline;> <!-- definitional --> +<!ATTLIST dfn %attrs;> + +<!ELEMENT code %Inline;> <!-- program code --> +<!ATTLIST code %attrs;> + +<!ELEMENT samp %Inline;> <!-- sample --> +<!ATTLIST samp %attrs;> + +<!ELEMENT kbd %Inline;> <!-- something user would type --> +<!ATTLIST kbd %attrs;> + +<!ELEMENT var %Inline;> <!-- variable --> +<!ATTLIST var %attrs;> + +<!ELEMENT cite %Inline;> <!-- citation --> +<!ATTLIST cite %attrs;> + +<!ELEMENT abbr %Inline;> <!-- abbreviation --> +<!ATTLIST abbr %attrs;> + +<!ELEMENT acronym %Inline;> <!-- acronym --> +<!ATTLIST acronym %attrs;> + +<!ELEMENT q %Inline;> <!-- inlined quote --> +<!ATTLIST q + %attrs; + cite %URI; #IMPLIED + > + +<!ELEMENT sub %Inline;> <!-- subscript --> +<!ATTLIST sub %attrs;> + +<!ELEMENT sup %Inline;> <!-- superscript --> +<!ATTLIST sup %attrs;> + +<!ELEMENT tt %Inline;> <!-- fixed pitch font --> +<!ATTLIST tt %attrs;> + +<!ELEMENT i %Inline;> <!-- italic font --> +<!ATTLIST i %attrs;> + +<!ELEMENT b %Inline;> <!-- bold font --> +<!ATTLIST b %attrs;> + +<!ELEMENT big %Inline;> <!-- bigger font --> +<!ATTLIST big %attrs;> + +<!ELEMENT small %Inline;> <!-- smaller font --> +<!ATTLIST small %attrs;> + +<!--==================== Object ======================================--> +<!-- + object is used to embed objects as part of HTML pages. + param elements should precede other content. Parameters + can also be expressed as attribute/value pairs on the + object element itself when brevity is desired. +--> + +<!ELEMENT object (#PCDATA | param | %block; | form | %inline; | %misc;)*> +<!ATTLIST object + %attrs; + declare (declare) #IMPLIED + classid %URI; #IMPLIED + codebase %URI; #IMPLIED + data %URI; #IMPLIED + type %ContentType; #IMPLIED + codetype %ContentType; #IMPLIED + archive %UriList; #IMPLIED + standby %Text; #IMPLIED + height %Length; #IMPLIED + width %Length; #IMPLIED + usemap %URI; #IMPLIED + name NMTOKEN #IMPLIED + tabindex %Number; #IMPLIED + > + +<!-- + param is used to supply a named property value. + In XML it would seem natural to follow RDF and support an + abbreviated syntax where the param elements are replaced + by attribute value pairs on the object start tag. +--> +<!ELEMENT param EMPTY> +<!ATTLIST param + id ID #IMPLIED + name CDATA #IMPLIED + value CDATA #IMPLIED + valuetype (data|ref|object) "data" + type %ContentType; #IMPLIED + > + +<!--=================== Images ===========================================--> + +<!-- + To avoid accessibility problems for people who aren't + able to see the image, you should provide a text + description using the alt and longdesc attributes. + In addition, avoid the use of server-side image maps. + Note that in this DTD there is no name attribute. That + is only available in the transitional and frameset DTD. +--> + +<!ELEMENT img EMPTY> +<!ATTLIST img + %attrs; + src %URI; #REQUIRED + alt %Text; #REQUIRED + longdesc %URI; #IMPLIED + height %Length; #IMPLIED + width %Length; #IMPLIED + usemap %URI; #IMPLIED + ismap (ismap) #IMPLIED + > + +<!-- usemap points to a map element which may be in this document + or an external document, although the latter is not widely supported --> + +<!--================== Client-side image maps ============================--> + +<!-- These can be placed in the same document or grouped in a + separate document although this isn't yet widely supported --> + +<!ELEMENT map ((%block; | form | %misc;)+ | area+)> +<!ATTLIST map + %i18n; + %events; + id ID #REQUIRED + class CDATA #IMPLIED + style %StyleSheet; #IMPLIED + title %Text; #IMPLIED + name NMTOKEN #IMPLIED + > + +<!ELEMENT area EMPTY> +<!ATTLIST area + %attrs; + %focus; + shape %Shape; "rect" + coords %Coords; #IMPLIED + href %URI; #IMPLIED + nohref (nohref) #IMPLIED + alt %Text; #REQUIRED + > + +<!--================ Forms ===============================================--> +<!ELEMENT form %form.content;> <!-- forms shouldn't be nested --> + +<!ATTLIST form + %attrs; + action %URI; #REQUIRED + method (get|post) "get" + enctype %ContentType; "application/x-www-form-urlencoded" + onsubmit %Script; #IMPLIED + onreset %Script; #IMPLIED + accept %ContentTypes; #IMPLIED + accept-charset %Charsets; #IMPLIED + > + +<!-- + Each label must not contain more than ONE field + Label elements shouldn't be nested. +--> +<!ELEMENT label %Inline;> +<!ATTLIST label + %attrs; + for IDREF #IMPLIED + accesskey %Character; #IMPLIED + onfocus %Script; #IMPLIED + onblur %Script; #IMPLIED + > + +<!ENTITY % InputType + "(text | password | checkbox | + radio | submit | reset | + file | hidden | image | button)" + > + +<!-- the name attribute is required for all but submit & reset --> + +<!ELEMENT input EMPTY> <!-- form control --> +<!ATTLIST input + %attrs; + %focus; + type %InputType; "text" + name CDATA #IMPLIED + value CDATA #IMPLIED + checked (checked) #IMPLIED + disabled (disabled) #IMPLIED + readonly (readonly) #IMPLIED + size CDATA #IMPLIED + maxlength %Number; #IMPLIED + src %URI; #IMPLIED + alt CDATA #IMPLIED + usemap %URI; #IMPLIED + onselect %Script; #IMPLIED + onchange %Script; #IMPLIED + accept %ContentTypes; #IMPLIED + > + +<!ELEMENT select (optgroup|option)+> <!-- option selector --> +<!ATTLIST select + %attrs; + name CDATA #IMPLIED + size %Number; #IMPLIED + multiple (multiple) #IMPLIED + disabled (disabled) #IMPLIED + tabindex %Number; #IMPLIED + onfocus %Script; #IMPLIED + onblur %Script; #IMPLIED + onchange %Script; #IMPLIED + > + +<!ELEMENT optgroup (option)+> <!-- option group --> +<!ATTLIST optgroup + %attrs; + disabled (disabled) #IMPLIED + label %Text; #REQUIRED + > + +<!ELEMENT option (#PCDATA)> <!-- selectable choice --> +<!ATTLIST option + %attrs; + selected (selected) #IMPLIED + disabled (disabled) #IMPLIED + label %Text; #IMPLIED + value CDATA #IMPLIED + > + +<!ELEMENT textarea (#PCDATA)> <!-- multi-line text field --> +<!ATTLIST textarea + %attrs; + %focus; + name CDATA #IMPLIED + rows %Number; #REQUIRED + cols %Number; #REQUIRED + disabled (disabled) #IMPLIED + readonly (readonly) #IMPLIED + onselect %Script; #IMPLIED + onchange %Script; #IMPLIED + > + +<!-- + The fieldset element is used to group form fields. + Only one legend element should occur in the content + and if present should only be preceded by whitespace. +--> +<!ELEMENT fieldset (#PCDATA | legend | %block; | form | %inline; | %misc;)*> +<!ATTLIST fieldset + %attrs; + > + +<!ELEMENT legend %Inline;> <!-- fieldset label --> +<!ATTLIST legend + %attrs; + accesskey %Character; #IMPLIED + > + +<!-- + Content is %Flow; excluding a, form and form controls +--> +<!ELEMENT button %button.content;> <!-- push button --> +<!ATTLIST button + %attrs; + %focus; + name CDATA #IMPLIED + value CDATA #IMPLIED + type (button|submit|reset) "submit" + disabled (disabled) #IMPLIED + > + +<!--======================= Tables =======================================--> + +<!-- Derived from IETF HTML table standard, see [RFC1942] --> + +<!-- + The border attribute sets the thickness of the frame around the + table. The default units are screen pixels. + + The frame attribute specifies which parts of the frame around + the table should be rendered. The values are not the same as + CALS to avoid a name clash with the valign attribute. +--> +<!ENTITY % TFrame "(void|above|below|hsides|lhs|rhs|vsides|box|border)"> + +<!-- + The rules attribute defines which rules to draw between cells: + + If rules is absent then assume: + "none" if border is absent or border="0" otherwise "all" +--> + +<!ENTITY % TRules "(none | groups | rows | cols | all)"> + +<!-- horizontal alignment attributes for cell contents + + char alignment char, e.g. char=':' + charoff offset for alignment char +--> +<!ENTITY % cellhalign + "align (left|center|right|justify|char) #IMPLIED + char %Character; #IMPLIED + charoff %Length; #IMPLIED" + > + +<!-- vertical alignment attributes for cell contents --> +<!ENTITY % cellvalign + "valign (top|middle|bottom|baseline) #IMPLIED" + > + +<!ELEMENT table + (caption?, (col*|colgroup*), thead?, tfoot?, (tbody+|tr+))> +<!ELEMENT caption %Inline;> +<!ELEMENT thead (tr)+> +<!ELEMENT tfoot (tr)+> +<!ELEMENT tbody (tr)+> +<!ELEMENT colgroup (col)*> +<!ELEMENT col EMPTY> +<!ELEMENT tr (th|td)+> +<!ELEMENT th %Flow;> +<!ELEMENT td %Flow;> + +<!ATTLIST table + %attrs; + summary %Text; #IMPLIED + width %Length; #IMPLIED + border %Pixels; #IMPLIED + frame %TFrame; #IMPLIED + rules %TRules; #IMPLIED + cellspacing %Length; #IMPLIED + cellpadding %Length; #IMPLIED + > + +<!ATTLIST caption + %attrs; + > + +<!-- +colgroup groups a set of col elements. It allows you to group +several semantically related columns together. +--> +<!ATTLIST colgroup + %attrs; + span %Number; "1" + width %MultiLength; #IMPLIED + %cellhalign; + %cellvalign; + > + +<!-- + col elements define the alignment properties for cells in + one or more columns. + + The width attribute specifies the width of the columns, e.g. + + width=64 width in screen pixels + width=0.5* relative width of 0.5 + + The span attribute causes the attributes of one + col element to apply to more than one column. +--> +<!ATTLIST col + %attrs; + span %Number; "1" + width %MultiLength; #IMPLIED + %cellhalign; + %cellvalign; + > + +<!-- + Use thead to duplicate headers when breaking table + across page boundaries, or for static headers when + tbody sections are rendered in scrolling panel. + + Use tfoot to duplicate footers when breaking table + across page boundaries, or for static footers when + tbody sections are rendered in scrolling panel. + + Use multiple tbody sections when rules are needed + between groups of table rows. +--> +<!ATTLIST thead + %attrs; + %cellhalign; + %cellvalign; + > + +<!ATTLIST tfoot + %attrs; + %cellhalign; + %cellvalign; + > + +<!ATTLIST tbody + %attrs; + %cellhalign; + %cellvalign; + > + +<!ATTLIST tr + %attrs; + %cellhalign; + %cellvalign; + > + + +<!-- Scope is simpler than headers attribute for common tables --> +<!ENTITY % Scope "(row|col|rowgroup|colgroup)"> + +<!-- th is for headers, td for data and for cells acting as both --> + +<!ATTLIST th + %attrs; + abbr %Text; #IMPLIED + axis CDATA #IMPLIED + headers IDREFS #IMPLIED + scope %Scope; #IMPLIED + rowspan %Number; "1" + colspan %Number; "1" + %cellhalign; + %cellvalign; + > + +<!ATTLIST td + %attrs; + abbr %Text; #IMPLIED + axis CDATA #IMPLIED + headers IDREFS #IMPLIED + scope %Scope; #IMPLIED + rowspan %Number; "1" + colspan %Number; "1" + %cellhalign; + %cellvalign; + > + diff --git a/testing/web-platform/tests/css/tools/w3ctestlib/catalog/xhtml1-transitional.dtd b/testing/web-platform/tests/css/tools/w3ctestlib/catalog/xhtml1-transitional.dtd new file mode 100644 index 0000000000..628f27ac50 --- /dev/null +++ b/testing/web-platform/tests/css/tools/w3ctestlib/catalog/xhtml1-transitional.dtd @@ -0,0 +1,1201 @@ +<!-- + Extensible HTML version 1.0 Transitional DTD + + This is the same as HTML 4 Transitional except for + changes due to the differences between XML and SGML. + + Namespace = http://www.w3.org/1999/xhtml + + For further information, see: http://www.w3.org/TR/xhtml1 + + Copyright (c) 1998-2002 W3C (MIT, INRIA, Keio), + All Rights Reserved. + + This DTD module is identified by the PUBLIC and SYSTEM identifiers: + + PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + SYSTEM "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" + + $Revision: 1.2 $ + $Date: 2002/08/01 18:37:55 $ + +--> + +<!--================ Character mnemonic entities =========================--> + +<!ENTITY % HTMLlat1 PUBLIC + "-//W3C//ENTITIES Latin 1 for XHTML//EN" + "xhtml-lat1.ent"> +%HTMLlat1; + +<!ENTITY % HTMLsymbol PUBLIC + "-//W3C//ENTITIES Symbols for XHTML//EN" + "xhtml-symbol.ent"> +%HTMLsymbol; + +<!ENTITY % HTMLspecial PUBLIC + "-//W3C//ENTITIES Special for XHTML//EN" + "xhtml-special.ent"> +%HTMLspecial; + +<!--================== Imported Names ====================================--> + +<!ENTITY % ContentType "CDATA"> + <!-- media type, as per [RFC2045] --> + +<!ENTITY % ContentTypes "CDATA"> + <!-- comma-separated list of media types, as per [RFC2045] --> + +<!ENTITY % Charset "CDATA"> + <!-- a character encoding, as per [RFC2045] --> + +<!ENTITY % Charsets "CDATA"> + <!-- a space separated list of character encodings, as per [RFC2045] --> + +<!ENTITY % LanguageCode "NMTOKEN"> + <!-- a language code, as per [RFC3066] --> + +<!ENTITY % Character "CDATA"> + <!-- a single character, as per section 2.2 of [XML] --> + +<!ENTITY % Number "CDATA"> + <!-- one or more digits --> + +<!ENTITY % LinkTypes "CDATA"> + <!-- space-separated list of link types --> + +<!ENTITY % MediaDesc "CDATA"> + <!-- single or comma-separated list of media descriptors --> + +<!ENTITY % URI "CDATA"> + <!-- a Uniform Resource Identifier, see [RFC2396] --> + +<!ENTITY % UriList "CDATA"> + <!-- a space separated list of Uniform Resource Identifiers --> + +<!ENTITY % Datetime "CDATA"> + <!-- date and time information. ISO date format --> + +<!ENTITY % Script "CDATA"> + <!-- script expression --> + +<!ENTITY % StyleSheet "CDATA"> + <!-- style sheet data --> + +<!ENTITY % Text "CDATA"> + <!-- used for titles etc. --> + +<!ENTITY % FrameTarget "NMTOKEN"> + <!-- render in this frame --> + +<!ENTITY % Length "CDATA"> + <!-- nn for pixels or nn% for percentage length --> + +<!ENTITY % MultiLength "CDATA"> + <!-- pixel, percentage, or relative --> + +<!ENTITY % Pixels "CDATA"> + <!-- integer representing length in pixels --> + +<!-- these are used for image maps --> + +<!ENTITY % Shape "(rect|circle|poly|default)"> + +<!ENTITY % Coords "CDATA"> + <!-- comma separated list of lengths --> + +<!-- used for object, applet, img, input and iframe --> +<!ENTITY % ImgAlign "(top|middle|bottom|left|right)"> + +<!-- a color using sRGB: #RRGGBB as Hex values --> +<!ENTITY % Color "CDATA"> + +<!-- There are also 16 widely known color names with their sRGB values: + + Black = #000000 Green = #008000 + Silver = #C0C0C0 Lime = #00FF00 + Gray = #808080 Olive = #808000 + White = #FFFFFF Yellow = #FFFF00 + Maroon = #800000 Navy = #000080 + Red = #FF0000 Blue = #0000FF + Purple = #800080 Teal = #008080 + Fuchsia= #FF00FF Aqua = #00FFFF +--> + +<!--=================== Generic Attributes ===============================--> + +<!-- core attributes common to most elements + id document-wide unique id + class space separated list of classes + style associated style info + title advisory title/amplification +--> +<!ENTITY % coreattrs + "id ID #IMPLIED + class CDATA #IMPLIED + style %StyleSheet; #IMPLIED + title %Text; #IMPLIED" + > + +<!-- internationalization attributes + lang language code (backwards compatible) + xml:lang language code (as per XML 1.0 spec) + dir direction for weak/neutral text +--> +<!ENTITY % i18n + "lang %LanguageCode; #IMPLIED + xml:lang %LanguageCode; #IMPLIED + dir (ltr|rtl) #IMPLIED" + > + +<!-- attributes for common UI events + onclick a pointer button was clicked + ondblclick a pointer button was double clicked + onmousedown a pointer button was pressed down + onmouseup a pointer button was released + onmousemove a pointer was moved onto the element + onmouseout a pointer was moved away from the element + onkeypress a key was pressed and released + onkeydown a key was pressed down + onkeyup a key was released +--> +<!ENTITY % events + "onclick %Script; #IMPLIED + ondblclick %Script; #IMPLIED + onmousedown %Script; #IMPLIED + onmouseup %Script; #IMPLIED + onmouseover %Script; #IMPLIED + onmousemove %Script; #IMPLIED + onmouseout %Script; #IMPLIED + onkeypress %Script; #IMPLIED + onkeydown %Script; #IMPLIED + onkeyup %Script; #IMPLIED" + > + +<!-- attributes for elements that can get the focus + accesskey accessibility key character + tabindex position in tabbing order + onfocus the element got the focus + onblur the element lost the focus +--> +<!ENTITY % focus + "accesskey %Character; #IMPLIED + tabindex %Number; #IMPLIED + onfocus %Script; #IMPLIED + onblur %Script; #IMPLIED" + > + +<!ENTITY % attrs "%coreattrs; %i18n; %events;"> + +<!-- text alignment for p, div, h1-h6. The default is + align="left" for ltr headings, "right" for rtl --> + +<!ENTITY % TextAlign "align (left|center|right|justify) #IMPLIED"> + +<!--=================== Text Elements ====================================--> + +<!ENTITY % special.extra + "object | applet | img | map | iframe"> + +<!ENTITY % special.basic + "br | span | bdo"> + +<!ENTITY % special + "%special.basic; | %special.extra;"> + +<!ENTITY % fontstyle.extra "big | small | font | basefont"> + +<!ENTITY % fontstyle.basic "tt | i | b | u + | s | strike "> + +<!ENTITY % fontstyle "%fontstyle.basic; | %fontstyle.extra;"> + +<!ENTITY % phrase.extra "sub | sup"> +<!ENTITY % phrase.basic "em | strong | dfn | code | q | + samp | kbd | var | cite | abbr | acronym"> + +<!ENTITY % phrase "%phrase.basic; | %phrase.extra;"> + +<!ENTITY % inline.forms "input | select | textarea | label | button"> + +<!-- these can occur at block or inline level --> +<!ENTITY % misc.inline "ins | del | script"> + +<!-- these can only occur at block level --> +<!ENTITY % misc "noscript | %misc.inline;"> + +<!ENTITY % inline "a | %special; | %fontstyle; | %phrase; | %inline.forms;"> + +<!-- %Inline; covers inline or "text-level" elements --> +<!ENTITY % Inline "(#PCDATA | %inline; | %misc.inline;)*"> + +<!--================== Block level elements ==============================--> + +<!ENTITY % heading "h1|h2|h3|h4|h5|h6"> +<!ENTITY % lists "ul | ol | dl | menu | dir"> +<!ENTITY % blocktext "pre | hr | blockquote | address | center | noframes"> + +<!ENTITY % block + "p | %heading; | div | %lists; | %blocktext; | isindex |fieldset | table"> + +<!-- %Flow; mixes block and inline and is used for list items etc. --> +<!ENTITY % Flow "(#PCDATA | %block; | form | %inline; | %misc;)*"> + +<!--================== Content models for exclusions =====================--> + +<!-- a elements use %Inline; excluding a --> + +<!ENTITY % a.content + "(#PCDATA | %special; | %fontstyle; | %phrase; | %inline.forms; | %misc.inline;)*"> + +<!-- pre uses %Inline excluding img, object, applet, big, small, + font, or basefont --> + +<!ENTITY % pre.content + "(#PCDATA | a | %special.basic; | %fontstyle.basic; | %phrase.basic; | + %inline.forms; | %misc.inline;)*"> + +<!-- form uses %Flow; excluding form --> + +<!ENTITY % form.content "(#PCDATA | %block; | %inline; | %misc;)*"> + +<!-- button uses %Flow; but excludes a, form, form controls, iframe --> + +<!ENTITY % button.content + "(#PCDATA | p | %heading; | div | %lists; | %blocktext; | + table | br | span | bdo | object | applet | img | map | + %fontstyle; | %phrase; | %misc;)*"> + +<!--================ Document Structure ==================================--> + +<!-- the namespace URI designates the document profile --> + +<!ELEMENT html (head, body)> +<!ATTLIST html + %i18n; + id ID #IMPLIED + xmlns %URI; #FIXED 'http://www.w3.org/1999/xhtml' + > + +<!--================ Document Head =======================================--> + +<!ENTITY % head.misc "(script|style|meta|link|object|isindex)*"> + +<!-- content model is %head.misc; combined with a single + title and an optional base element in any order --> + +<!ELEMENT head (%head.misc;, + ((title, %head.misc;, (base, %head.misc;)?) | + (base, %head.misc;, (title, %head.misc;))))> + +<!ATTLIST head + %i18n; + id ID #IMPLIED + profile %URI; #IMPLIED + > + +<!-- The title element is not considered part of the flow of text. + It should be displayed, for example as the page header or + window title. Exactly one title is required per document. + --> +<!ELEMENT title (#PCDATA)> +<!ATTLIST title + %i18n; + id ID #IMPLIED + > + +<!-- document base URI --> + +<!ELEMENT base EMPTY> +<!ATTLIST base + id ID #IMPLIED + href %URI; #IMPLIED + target %FrameTarget; #IMPLIED + > + +<!-- generic metainformation --> +<!ELEMENT meta EMPTY> +<!ATTLIST meta + %i18n; + id ID #IMPLIED + http-equiv CDATA #IMPLIED + name CDATA #IMPLIED + content CDATA #REQUIRED + scheme CDATA #IMPLIED + > + +<!-- + Relationship values can be used in principle: + + a) for document specific toolbars/menus when used + with the link element in document head e.g. + start, contents, previous, next, index, end, help + b) to link to a separate style sheet (rel="stylesheet") + c) to make a link to a script (rel="script") + d) by stylesheets to control how collections of + html nodes are rendered into printed documents + e) to make a link to a printable version of this document + e.g. a PostScript or PDF version (rel="alternate" media="print") +--> + +<!ELEMENT link EMPTY> +<!ATTLIST link + %attrs; + charset %Charset; #IMPLIED + href %URI; #IMPLIED + hreflang %LanguageCode; #IMPLIED + type %ContentType; #IMPLIED + rel %LinkTypes; #IMPLIED + rev %LinkTypes; #IMPLIED + media %MediaDesc; #IMPLIED + target %FrameTarget; #IMPLIED + > + +<!-- style info, which may include CDATA sections --> +<!ELEMENT style (#PCDATA)> +<!ATTLIST style + %i18n; + id ID #IMPLIED + type %ContentType; #REQUIRED + media %MediaDesc; #IMPLIED + title %Text; #IMPLIED + xml:space (preserve) #FIXED 'preserve' + > + +<!-- script statements, which may include CDATA sections --> +<!ELEMENT script (#PCDATA)> +<!ATTLIST script + id ID #IMPLIED + charset %Charset; #IMPLIED + type %ContentType; #REQUIRED + language CDATA #IMPLIED + src %URI; #IMPLIED + defer (defer) #IMPLIED + xml:space (preserve) #FIXED 'preserve' + > + +<!-- alternate content container for non script-based rendering --> + +<!ELEMENT noscript %Flow;> +<!ATTLIST noscript + %attrs; + > + +<!--======================= Frames =======================================--> + +<!-- inline subwindow --> + +<!ELEMENT iframe %Flow;> +<!ATTLIST iframe + %coreattrs; + longdesc %URI; #IMPLIED + name NMTOKEN #IMPLIED + src %URI; #IMPLIED + frameborder (1|0) "1" + marginwidth %Pixels; #IMPLIED + marginheight %Pixels; #IMPLIED + scrolling (yes|no|auto) "auto" + align %ImgAlign; #IMPLIED + height %Length; #IMPLIED + width %Length; #IMPLIED + > + +<!-- alternate content container for non frame-based rendering --> + +<!ELEMENT noframes %Flow;> +<!ATTLIST noframes + %attrs; + > + +<!--=================== Document Body ====================================--> + +<!ELEMENT body %Flow;> +<!ATTLIST body + %attrs; + onload %Script; #IMPLIED + onunload %Script; #IMPLIED + background %URI; #IMPLIED + bgcolor %Color; #IMPLIED + text %Color; #IMPLIED + link %Color; #IMPLIED + vlink %Color; #IMPLIED + alink %Color; #IMPLIED + > + +<!ELEMENT div %Flow;> <!-- generic language/style container --> +<!ATTLIST div + %attrs; + %TextAlign; + > + +<!--=================== Paragraphs =======================================--> + +<!ELEMENT p %Inline;> +<!ATTLIST p + %attrs; + %TextAlign; + > + +<!--=================== Headings =========================================--> + +<!-- + There are six levels of headings from h1 (the most important) + to h6 (the least important). +--> + +<!ELEMENT h1 %Inline;> +<!ATTLIST h1 + %attrs; + %TextAlign; + > + +<!ELEMENT h2 %Inline;> +<!ATTLIST h2 + %attrs; + %TextAlign; + > + +<!ELEMENT h3 %Inline;> +<!ATTLIST h3 + %attrs; + %TextAlign; + > + +<!ELEMENT h4 %Inline;> +<!ATTLIST h4 + %attrs; + %TextAlign; + > + +<!ELEMENT h5 %Inline;> +<!ATTLIST h5 + %attrs; + %TextAlign; + > + +<!ELEMENT h6 %Inline;> +<!ATTLIST h6 + %attrs; + %TextAlign; + > + +<!--=================== Lists ============================================--> + +<!-- Unordered list bullet styles --> + +<!ENTITY % ULStyle "(disc|square|circle)"> + +<!-- Unordered list --> + +<!ELEMENT ul (li)+> +<!ATTLIST ul + %attrs; + type %ULStyle; #IMPLIED + compact (compact) #IMPLIED + > + +<!-- Ordered list numbering style + + 1 arabic numbers 1, 2, 3, ... + a lower alpha a, b, c, ... + A upper alpha A, B, C, ... + i lower roman i, ii, iii, ... + I upper roman I, II, III, ... + + The style is applied to the sequence number which by default + is reset to 1 for the first list item in an ordered list. +--> +<!ENTITY % OLStyle "CDATA"> + +<!-- Ordered (numbered) list --> + +<!ELEMENT ol (li)+> +<!ATTLIST ol + %attrs; + type %OLStyle; #IMPLIED + compact (compact) #IMPLIED + start %Number; #IMPLIED + > + +<!-- single column list (DEPRECATED) --> +<!ELEMENT menu (li)+> +<!ATTLIST menu + %attrs; + compact (compact) #IMPLIED + > + +<!-- multiple column list (DEPRECATED) --> +<!ELEMENT dir (li)+> +<!ATTLIST dir + %attrs; + compact (compact) #IMPLIED + > + +<!-- LIStyle is constrained to: "(%ULStyle;|%OLStyle;)" --> +<!ENTITY % LIStyle "CDATA"> + +<!-- list item --> + +<!ELEMENT li %Flow;> +<!ATTLIST li + %attrs; + type %LIStyle; #IMPLIED + value %Number; #IMPLIED + > + +<!-- definition lists - dt for term, dd for its definition --> + +<!ELEMENT dl (dt|dd)+> +<!ATTLIST dl + %attrs; + compact (compact) #IMPLIED + > + +<!ELEMENT dt %Inline;> +<!ATTLIST dt + %attrs; + > + +<!ELEMENT dd %Flow;> +<!ATTLIST dd + %attrs; + > + +<!--=================== Address ==========================================--> + +<!-- information on author --> + +<!ELEMENT address (#PCDATA | %inline; | %misc.inline; | p)*> +<!ATTLIST address + %attrs; + > + +<!--=================== Horizontal Rule ==================================--> + +<!ELEMENT hr EMPTY> +<!ATTLIST hr + %attrs; + align (left|center|right) #IMPLIED + noshade (noshade) #IMPLIED + size %Pixels; #IMPLIED + width %Length; #IMPLIED + > + +<!--=================== Preformatted Text ================================--> + +<!-- content is %Inline; excluding + "img|object|applet|big|small|sub|sup|font|basefont" --> + +<!ELEMENT pre %pre.content;> +<!ATTLIST pre + %attrs; + width %Number; #IMPLIED + xml:space (preserve) #FIXED 'preserve' + > + +<!--=================== Block-like Quotes ================================--> + +<!ELEMENT blockquote %Flow;> +<!ATTLIST blockquote + %attrs; + cite %URI; #IMPLIED + > + +<!--=================== Text alignment ===================================--> + +<!-- center content --> +<!ELEMENT center %Flow;> +<!ATTLIST center + %attrs; + > + +<!--=================== Inserted/Deleted Text ============================--> + +<!-- + ins/del are allowed in block and inline content, but its + inappropriate to include block content within an ins element + occurring in inline content. +--> +<!ELEMENT ins %Flow;> +<!ATTLIST ins + %attrs; + cite %URI; #IMPLIED + datetime %Datetime; #IMPLIED + > + +<!ELEMENT del %Flow;> +<!ATTLIST del + %attrs; + cite %URI; #IMPLIED + datetime %Datetime; #IMPLIED + > + +<!--================== The Anchor Element ================================--> + +<!-- content is %Inline; except that anchors shouldn't be nested --> + +<!ELEMENT a %a.content;> +<!ATTLIST a + %attrs; + %focus; + charset %Charset; #IMPLIED + type %ContentType; #IMPLIED + name NMTOKEN #IMPLIED + href %URI; #IMPLIED + hreflang %LanguageCode; #IMPLIED + rel %LinkTypes; #IMPLIED + rev %LinkTypes; #IMPLIED + shape %Shape; "rect" + coords %Coords; #IMPLIED + target %FrameTarget; #IMPLIED + > + +<!--===================== Inline Elements ================================--> + +<!ELEMENT span %Inline;> <!-- generic language/style container --> +<!ATTLIST span + %attrs; + > + +<!ELEMENT bdo %Inline;> <!-- I18N BiDi over-ride --> +<!ATTLIST bdo + %coreattrs; + %events; + lang %LanguageCode; #IMPLIED + xml:lang %LanguageCode; #IMPLIED + dir (ltr|rtl) #REQUIRED + > + +<!ELEMENT br EMPTY> <!-- forced line break --> +<!ATTLIST br + %coreattrs; + clear (left|all|right|none) "none" + > + +<!ELEMENT em %Inline;> <!-- emphasis --> +<!ATTLIST em %attrs;> + +<!ELEMENT strong %Inline;> <!-- strong emphasis --> +<!ATTLIST strong %attrs;> + +<!ELEMENT dfn %Inline;> <!-- definitional --> +<!ATTLIST dfn %attrs;> + +<!ELEMENT code %Inline;> <!-- program code --> +<!ATTLIST code %attrs;> + +<!ELEMENT samp %Inline;> <!-- sample --> +<!ATTLIST samp %attrs;> + +<!ELEMENT kbd %Inline;> <!-- something user would type --> +<!ATTLIST kbd %attrs;> + +<!ELEMENT var %Inline;> <!-- variable --> +<!ATTLIST var %attrs;> + +<!ELEMENT cite %Inline;> <!-- citation --> +<!ATTLIST cite %attrs;> + +<!ELEMENT abbr %Inline;> <!-- abbreviation --> +<!ATTLIST abbr %attrs;> + +<!ELEMENT acronym %Inline;> <!-- acronym --> +<!ATTLIST acronym %attrs;> + +<!ELEMENT q %Inline;> <!-- inlined quote --> +<!ATTLIST q + %attrs; + cite %URI; #IMPLIED + > + +<!ELEMENT sub %Inline;> <!-- subscript --> +<!ATTLIST sub %attrs;> + +<!ELEMENT sup %Inline;> <!-- superscript --> +<!ATTLIST sup %attrs;> + +<!ELEMENT tt %Inline;> <!-- fixed pitch font --> +<!ATTLIST tt %attrs;> + +<!ELEMENT i %Inline;> <!-- italic font --> +<!ATTLIST i %attrs;> + +<!ELEMENT b %Inline;> <!-- bold font --> +<!ATTLIST b %attrs;> + +<!ELEMENT big %Inline;> <!-- bigger font --> +<!ATTLIST big %attrs;> + +<!ELEMENT small %Inline;> <!-- smaller font --> +<!ATTLIST small %attrs;> + +<!ELEMENT u %Inline;> <!-- underline --> +<!ATTLIST u %attrs;> + +<!ELEMENT s %Inline;> <!-- strike-through --> +<!ATTLIST s %attrs;> + +<!ELEMENT strike %Inline;> <!-- strike-through --> +<!ATTLIST strike %attrs;> + +<!ELEMENT basefont EMPTY> <!-- base font size --> +<!ATTLIST basefont + id ID #IMPLIED + size CDATA #REQUIRED + color %Color; #IMPLIED + face CDATA #IMPLIED + > + +<!ELEMENT font %Inline;> <!-- local change to font --> +<!ATTLIST font + %coreattrs; + %i18n; + size CDATA #IMPLIED + color %Color; #IMPLIED + face CDATA #IMPLIED + > + +<!--==================== Object ======================================--> +<!-- + object is used to embed objects as part of HTML pages. + param elements should precede other content. Parameters + can also be expressed as attribute/value pairs on the + object element itself when brevity is desired. +--> + +<!ELEMENT object (#PCDATA | param | %block; | form | %inline; | %misc;)*> +<!ATTLIST object + %attrs; + declare (declare) #IMPLIED + classid %URI; #IMPLIED + codebase %URI; #IMPLIED + data %URI; #IMPLIED + type %ContentType; #IMPLIED + codetype %ContentType; #IMPLIED + archive %UriList; #IMPLIED + standby %Text; #IMPLIED + height %Length; #IMPLIED + width %Length; #IMPLIED + usemap %URI; #IMPLIED + name NMTOKEN #IMPLIED + tabindex %Number; #IMPLIED + align %ImgAlign; #IMPLIED + border %Pixels; #IMPLIED + hspace %Pixels; #IMPLIED + vspace %Pixels; #IMPLIED + > + +<!-- + param is used to supply a named property value. + In XML it would seem natural to follow RDF and support an + abbreviated syntax where the param elements are replaced + by attribute value pairs on the object start tag. +--> +<!ELEMENT param EMPTY> +<!ATTLIST param + id ID #IMPLIED + name CDATA #REQUIRED + value CDATA #IMPLIED + valuetype (data|ref|object) "data" + type %ContentType; #IMPLIED + > + +<!--=================== Java applet ==================================--> +<!-- + One of code or object attributes must be present. + Place param elements before other content. +--> +<!ELEMENT applet (#PCDATA | param | %block; | form | %inline; | %misc;)*> +<!ATTLIST applet + %coreattrs; + codebase %URI; #IMPLIED + archive CDATA #IMPLIED + code CDATA #IMPLIED + object CDATA #IMPLIED + alt %Text; #IMPLIED + name NMTOKEN #IMPLIED + width %Length; #REQUIRED + height %Length; #REQUIRED + align %ImgAlign; #IMPLIED + hspace %Pixels; #IMPLIED + vspace %Pixels; #IMPLIED + > + +<!--=================== Images ===========================================--> + +<!-- + To avoid accessibility problems for people who aren't + able to see the image, you should provide a text + description using the alt and longdesc attributes. + In addition, avoid the use of server-side image maps. +--> + +<!ELEMENT img EMPTY> +<!ATTLIST img + %attrs; + src %URI; #REQUIRED + alt %Text; #REQUIRED + name NMTOKEN #IMPLIED + longdesc %URI; #IMPLIED + height %Length; #IMPLIED + width %Length; #IMPLIED + usemap %URI; #IMPLIED + ismap (ismap) #IMPLIED + align %ImgAlign; #IMPLIED + border %Length; #IMPLIED + hspace %Pixels; #IMPLIED + vspace %Pixels; #IMPLIED + > + +<!-- usemap points to a map element which may be in this document + or an external document, although the latter is not widely supported --> + +<!--================== Client-side image maps ============================--> + +<!-- These can be placed in the same document or grouped in a + separate document although this isn't yet widely supported --> + +<!ELEMENT map ((%block; | form | %misc;)+ | area+)> +<!ATTLIST map + %i18n; + %events; + id ID #REQUIRED + class CDATA #IMPLIED + style %StyleSheet; #IMPLIED + title %Text; #IMPLIED + name CDATA #IMPLIED + > + +<!ELEMENT area EMPTY> +<!ATTLIST area + %attrs; + %focus; + shape %Shape; "rect" + coords %Coords; #IMPLIED + href %URI; #IMPLIED + nohref (nohref) #IMPLIED + alt %Text; #REQUIRED + target %FrameTarget; #IMPLIED + > + +<!--================ Forms ===============================================--> + +<!ELEMENT form %form.content;> <!-- forms shouldn't be nested --> + +<!ATTLIST form + %attrs; + action %URI; #REQUIRED + method (get|post) "get" + name NMTOKEN #IMPLIED + enctype %ContentType; "application/x-www-form-urlencoded" + onsubmit %Script; #IMPLIED + onreset %Script; #IMPLIED + accept %ContentTypes; #IMPLIED + accept-charset %Charsets; #IMPLIED + target %FrameTarget; #IMPLIED + > + +<!-- + Each label must not contain more than ONE field + Label elements shouldn't be nested. +--> +<!ELEMENT label %Inline;> +<!ATTLIST label + %attrs; + for IDREF #IMPLIED + accesskey %Character; #IMPLIED + onfocus %Script; #IMPLIED + onblur %Script; #IMPLIED + > + +<!ENTITY % InputType + "(text | password | checkbox | + radio | submit | reset | + file | hidden | image | button)" + > + +<!-- the name attribute is required for all but submit & reset --> + +<!ELEMENT input EMPTY> <!-- form control --> +<!ATTLIST input + %attrs; + %focus; + type %InputType; "text" + name CDATA #IMPLIED + value CDATA #IMPLIED + checked (checked) #IMPLIED + disabled (disabled) #IMPLIED + readonly (readonly) #IMPLIED + size CDATA #IMPLIED + maxlength %Number; #IMPLIED + src %URI; #IMPLIED + alt CDATA #IMPLIED + usemap %URI; #IMPLIED + onselect %Script; #IMPLIED + onchange %Script; #IMPLIED + accept %ContentTypes; #IMPLIED + align %ImgAlign; #IMPLIED + > + +<!ELEMENT select (optgroup|option)+> <!-- option selector --> +<!ATTLIST select + %attrs; + name CDATA #IMPLIED + size %Number; #IMPLIED + multiple (multiple) #IMPLIED + disabled (disabled) #IMPLIED + tabindex %Number; #IMPLIED + onfocus %Script; #IMPLIED + onblur %Script; #IMPLIED + onchange %Script; #IMPLIED + > + +<!ELEMENT optgroup (option)+> <!-- option group --> +<!ATTLIST optgroup + %attrs; + disabled (disabled) #IMPLIED + label %Text; #REQUIRED + > + +<!ELEMENT option (#PCDATA)> <!-- selectable choice --> +<!ATTLIST option + %attrs; + selected (selected) #IMPLIED + disabled (disabled) #IMPLIED + label %Text; #IMPLIED + value CDATA #IMPLIED + > + +<!ELEMENT textarea (#PCDATA)> <!-- multi-line text field --> +<!ATTLIST textarea + %attrs; + %focus; + name CDATA #IMPLIED + rows %Number; #REQUIRED + cols %Number; #REQUIRED + disabled (disabled) #IMPLIED + readonly (readonly) #IMPLIED + onselect %Script; #IMPLIED + onchange %Script; #IMPLIED + > + +<!-- + The fieldset element is used to group form fields. + Only one legend element should occur in the content + and if present should only be preceded by whitespace. +--> +<!ELEMENT fieldset (#PCDATA | legend | %block; | form | %inline; | %misc;)*> +<!ATTLIST fieldset + %attrs; + > + +<!ENTITY % LAlign "(top|bottom|left|right)"> + +<!ELEMENT legend %Inline;> <!-- fieldset label --> +<!ATTLIST legend + %attrs; + accesskey %Character; #IMPLIED + align %LAlign; #IMPLIED + > + +<!-- + Content is %Flow; excluding a, form, form controls, iframe +--> +<!ELEMENT button %button.content;> <!-- push button --> +<!ATTLIST button + %attrs; + %focus; + name CDATA #IMPLIED + value CDATA #IMPLIED + type (button|submit|reset) "submit" + disabled (disabled) #IMPLIED + > + +<!-- single-line text input control (DEPRECATED) --> +<!ELEMENT isindex EMPTY> +<!ATTLIST isindex + %coreattrs; + %i18n; + prompt %Text; #IMPLIED + > + +<!--======================= Tables =======================================--> + +<!-- Derived from IETF HTML table standard, see [RFC1942] --> + +<!-- + The border attribute sets the thickness of the frame around the + table. The default units are screen pixels. + + The frame attribute specifies which parts of the frame around + the table should be rendered. The values are not the same as + CALS to avoid a name clash with the valign attribute. +--> +<!ENTITY % TFrame "(void|above|below|hsides|lhs|rhs|vsides|box|border)"> + +<!-- + The rules attribute defines which rules to draw between cells: + + If rules is absent then assume: + "none" if border is absent or border="0" otherwise "all" +--> + +<!ENTITY % TRules "(none | groups | rows | cols | all)"> + +<!-- horizontal placement of table relative to document --> +<!ENTITY % TAlign "(left|center|right)"> + +<!-- horizontal alignment attributes for cell contents + + char alignment char, e.g. char=':' + charoff offset for alignment char +--> +<!ENTITY % cellhalign + "align (left|center|right|justify|char) #IMPLIED + char %Character; #IMPLIED + charoff %Length; #IMPLIED" + > + +<!-- vertical alignment attributes for cell contents --> +<!ENTITY % cellvalign + "valign (top|middle|bottom|baseline) #IMPLIED" + > + +<!ELEMENT table + (caption?, (col*|colgroup*), thead?, tfoot?, (tbody+|tr+))> +<!ELEMENT caption %Inline;> +<!ELEMENT thead (tr)+> +<!ELEMENT tfoot (tr)+> +<!ELEMENT tbody (tr)+> +<!ELEMENT colgroup (col)*> +<!ELEMENT col EMPTY> +<!ELEMENT tr (th|td)+> +<!ELEMENT th %Flow;> +<!ELEMENT td %Flow;> + +<!ATTLIST table + %attrs; + summary %Text; #IMPLIED + width %Length; #IMPLIED + border %Pixels; #IMPLIED + frame %TFrame; #IMPLIED + rules %TRules; #IMPLIED + cellspacing %Length; #IMPLIED + cellpadding %Length; #IMPLIED + align %TAlign; #IMPLIED + bgcolor %Color; #IMPLIED + > + +<!ENTITY % CAlign "(top|bottom|left|right)"> + +<!ATTLIST caption + %attrs; + align %CAlign; #IMPLIED + > + +<!-- +colgroup groups a set of col elements. It allows you to group +several semantically related columns together. +--> +<!ATTLIST colgroup + %attrs; + span %Number; "1" + width %MultiLength; #IMPLIED + %cellhalign; + %cellvalign; + > + +<!-- + col elements define the alignment properties for cells in + one or more columns. + + The width attribute specifies the width of the columns, e.g. + + width=64 width in screen pixels + width=0.5* relative width of 0.5 + + The span attribute causes the attributes of one + col element to apply to more than one column. +--> +<!ATTLIST col + %attrs; + span %Number; "1" + width %MultiLength; #IMPLIED + %cellhalign; + %cellvalign; + > + +<!-- + Use thead to duplicate headers when breaking table + across page boundaries, or for static headers when + tbody sections are rendered in scrolling panel. + + Use tfoot to duplicate footers when breaking table + across page boundaries, or for static footers when + tbody sections are rendered in scrolling panel. + + Use multiple tbody sections when rules are needed + between groups of table rows. +--> +<!ATTLIST thead + %attrs; + %cellhalign; + %cellvalign; + > + +<!ATTLIST tfoot + %attrs; + %cellhalign; + %cellvalign; + > + +<!ATTLIST tbody + %attrs; + %cellhalign; + %cellvalign; + > + +<!ATTLIST tr + %attrs; + %cellhalign; + %cellvalign; + bgcolor %Color; #IMPLIED + > + +<!-- Scope is simpler than headers attribute for common tables --> +<!ENTITY % Scope "(row|col|rowgroup|colgroup)"> + +<!-- th is for headers, td for data and for cells acting as both --> + +<!ATTLIST th + %attrs; + abbr %Text; #IMPLIED + axis CDATA #IMPLIED + headers IDREFS #IMPLIED + scope %Scope; #IMPLIED + rowspan %Number; "1" + colspan %Number; "1" + %cellhalign; + %cellvalign; + nowrap (nowrap) #IMPLIED + bgcolor %Color; #IMPLIED + width %Length; #IMPLIED + height %Length; #IMPLIED + > + +<!ATTLIST td + %attrs; + abbr %Text; #IMPLIED + axis CDATA #IMPLIED + headers IDREFS #IMPLIED + scope %Scope; #IMPLIED + rowspan %Number; "1" + colspan %Number; "1" + %cellhalign; + %cellvalign; + nowrap (nowrap) #IMPLIED + bgcolor %Color; #IMPLIED + width %Length; #IMPLIED + height %Length; #IMPLIED + > + diff --git a/testing/web-platform/tests/css/tools/w3ctestlib/catalog/xhtml11.dtd b/testing/web-platform/tests/css/tools/w3ctestlib/catalog/xhtml11.dtd new file mode 100644 index 0000000000..2a999b5b37 --- /dev/null +++ b/testing/web-platform/tests/css/tools/w3ctestlib/catalog/xhtml11.dtd @@ -0,0 +1,294 @@ +<!-- ....................................................................... --> +<!-- XHTML 1.1 DTD ........................................................ --> +<!-- file: xhtml11.dtd +--> + +<!-- XHTML 1.1 DTD + + This is XHTML, a reformulation of HTML as a modular XML application. + + The Extensible HyperText Markup Language (XHTML) + Copyright 1998-2001 World Wide Web Consortium + (Massachusetts Institute of Technology, Institut National de + Recherche en Informatique et en Automatique, Keio University). + All Rights Reserved. + + Permission to use, copy, modify and distribute the XHTML DTD and its + accompanying documentation for any purpose and without fee is hereby + granted in perpetuity, provided that the above copyright notice and + this paragraph appear in all copies. The copyright holders make no + representation about the suitability of the DTD for any purpose. + + It is provided "as is" without expressed or implied warranty. + + Author: Murray M. Altheim <altheim@eng.sun.com> + Revision: $Id: xhtml11.dtd,v 1.21 2001/05/29 16:37:01 ahby Exp $ + +--> +<!-- This is the driver file for version 1.1 of the XHTML DTD. + + Please use this formal public identifier to identify it: + + "-//W3C//DTD XHTML 1.1//EN" +--> +<!ENTITY % XHTML.version "-//W3C//DTD XHTML 1.1//EN" > + +<!-- Use this URI to identify the default namespace: + + "http://www.w3.org/1999/xhtml" + + See the Qualified Names module for information + on the use of namespace prefixes in the DTD. +--> +<!ENTITY % NS.prefixed "IGNORE" > +<!ENTITY % XHTML.prefix "" > + +<!-- Reserved for use with the XLink namespace: +--> +<!ENTITY % XLINK.xmlns "" > +<!ENTITY % XLINK.xmlns.attrib "" > + +<!-- For example, if you are using XHTML 1.1 directly, use the FPI + in the DOCTYPE declaration, with the xmlns attribute on the + document element to identify the default namespace: + + <?xml version="1.0"?> + <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "xhtml11.dtd"> + <html xmlns="http://www.w3.org/1999/xhtml" + xml:lang="en"> + ... + </html> + + Revisions: + (none) +--> + +<!-- reserved for future use with document profiles --> +<!ENTITY % XHTML.profile "" > + +<!-- Bidirectional Text features + This feature-test entity is used to declare elements + and attributes used for bidirectional text support. +--> +<!ENTITY % XHTML.bidi "INCLUDE" > + +<?doc type="doctype" role="title" { XHTML 1.1 } ?> + +<!-- ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: --> + +<!-- Pre-Framework Redeclaration placeholder .................... --> +<!-- this serves as a location to insert markup declarations + into the DTD prior to the framework declarations. +--> +<!ENTITY % xhtml-prefw-redecl.module "IGNORE" > +<![%xhtml-prefw-redecl.module;[ +%xhtml-prefw-redecl.mod; +<!-- end of xhtml-prefw-redecl.module -->]]> + +<!ENTITY % xhtml-events.module "INCLUDE" > + +<!-- Inline Style Module ........................................ --> +<!ENTITY % xhtml-inlstyle.module "INCLUDE" > +<![%xhtml-inlstyle.module;[ +<!ENTITY % xhtml-inlstyle.mod + PUBLIC "-//W3C//ELEMENTS XHTML Inline Style 1.0//EN" + "http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-inlstyle-1.mod" > +%xhtml-inlstyle.mod;]]> + +<!-- declare Document Model module instantiated in framework +--> +<!ENTITY % xhtml-model.mod + PUBLIC "-//W3C//ENTITIES XHTML 1.1 Document Model 1.0//EN" + "xhtml11-model-1.mod" > + +<!-- Modular Framework Module (required) ......................... --> +<!ENTITY % xhtml-framework.module "INCLUDE" > +<![%xhtml-framework.module;[ +<!ENTITY % xhtml-framework.mod + PUBLIC "-//W3C//ENTITIES XHTML Modular Framework 1.0//EN" + "http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-framework-1.mod" > +%xhtml-framework.mod;]]> + +<!-- Post-Framework Redeclaration placeholder ................... --> +<!-- this serves as a location to insert markup declarations + into the DTD following the framework declarations. +--> +<!ENTITY % xhtml-postfw-redecl.module "IGNORE" > +<![%xhtml-postfw-redecl.module;[ +%xhtml-postfw-redecl.mod; +<!-- end of xhtml-postfw-redecl.module -->]]> + +<!-- Text Module (Required) ..................................... --> +<!ENTITY % xhtml-text.module "INCLUDE" > +<![%xhtml-text.module;[ +<!ENTITY % xhtml-text.mod + PUBLIC "-//W3C//ELEMENTS XHTML Text 1.0//EN" + "http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-text-1.mod" > +%xhtml-text.mod;]]> + +<!-- Hypertext Module (required) ................................. --> +<!ENTITY % xhtml-hypertext.module "INCLUDE" > +<![%xhtml-hypertext.module;[ +<!ENTITY % xhtml-hypertext.mod + PUBLIC "-//W3C//ELEMENTS XHTML Hypertext 1.0//EN" + "http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-hypertext-1.mod" > +%xhtml-hypertext.mod;]]> + +<!-- Lists Module (required) .................................... --> +<!ENTITY % xhtml-list.module "INCLUDE" > +<![%xhtml-list.module;[ +<!ENTITY % xhtml-list.mod + PUBLIC "-//W3C//ELEMENTS XHTML Lists 1.0//EN" + "http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-list-1.mod" > +%xhtml-list.mod;]]> + +<!-- ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: --> + +<!-- Edit Module ................................................ --> +<!ENTITY % xhtml-edit.module "INCLUDE" > +<![%xhtml-edit.module;[ +<!ENTITY % xhtml-edit.mod + PUBLIC "-//W3C//ELEMENTS XHTML Editing Elements 1.0//EN" + "http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-edit-1.mod" > +%xhtml-edit.mod;]]> + +<!-- BIDI Override Module ....................................... --> +<!ENTITY % xhtml-bdo.module "%XHTML.bidi;" > +<![%xhtml-bdo.module;[ +<!ENTITY % xhtml-bdo.mod + PUBLIC "-//W3C//ELEMENTS XHTML BIDI Override Element 1.0//EN" + "http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-bdo-1.mod" > +%xhtml-bdo.mod;]]> + +<!-- Ruby Module ................................................ --> +<!ENTITY % Ruby.common.attlists "INCLUDE" > +<!ENTITY % Ruby.common.attrib "%Common.attrib;" > +<!ENTITY % xhtml-ruby.module "INCLUDE" > +<![%xhtml-ruby.module;[ +<!ENTITY % xhtml-ruby.mod + PUBLIC "-//W3C//ELEMENTS XHTML Ruby 1.0//EN" + "http://www.w3.org/TR/ruby/xhtml-ruby-1.mod" > +%xhtml-ruby.mod;]]> + +<!-- Presentation Module ........................................ --> +<!ENTITY % xhtml-pres.module "INCLUDE" > +<![%xhtml-pres.module;[ +<!ENTITY % xhtml-pres.mod + PUBLIC "-//W3C//ELEMENTS XHTML Presentation 1.0//EN" + "http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-pres-1.mod" > +%xhtml-pres.mod;]]> + +<!-- Link Element Module ........................................ --> +<!ENTITY % xhtml-link.module "INCLUDE" > +<![%xhtml-link.module;[ +<!ENTITY % xhtml-link.mod + PUBLIC "-//W3C//ELEMENTS XHTML Link Element 1.0//EN" + "http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-link-1.mod" > +%xhtml-link.mod;]]> + +<!-- Document Metainformation Module ............................ --> +<!ENTITY % xhtml-meta.module "INCLUDE" > +<![%xhtml-meta.module;[ +<!ENTITY % xhtml-meta.mod + PUBLIC "-//W3C//ELEMENTS XHTML Metainformation 1.0//EN" + "http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-meta-1.mod" > +%xhtml-meta.mod;]]> + +<!-- Base Element Module ........................................ --> +<!ENTITY % xhtml-base.module "INCLUDE" > +<![%xhtml-base.module;[ +<!ENTITY % xhtml-base.mod + PUBLIC "-//W3C//ELEMENTS XHTML Base Element 1.0//EN" + "http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-base-1.mod" > +%xhtml-base.mod;]]> + +<!-- Scripting Module ........................................... --> +<!ENTITY % xhtml-script.module "INCLUDE" > +<![%xhtml-script.module;[ +<!ENTITY % xhtml-script.mod + PUBLIC "-//W3C//ELEMENTS XHTML Scripting 1.0//EN" + "http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-script-1.mod" > +%xhtml-script.mod;]]> + +<!-- Style Sheets Module ......................................... --> +<!ENTITY % xhtml-style.module "INCLUDE" > +<![%xhtml-style.module;[ +<!ENTITY % xhtml-style.mod + PUBLIC "-//W3C//ELEMENTS XHTML Style Sheets 1.0//EN" + "http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-style-1.mod" > +%xhtml-style.mod;]]> + +<!-- Image Module ............................................... --> +<!ENTITY % xhtml-image.module "INCLUDE" > +<![%xhtml-image.module;[ +<!ENTITY % xhtml-image.mod + PUBLIC "-//W3C//ELEMENTS XHTML Images 1.0//EN" + "http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-image-1.mod" > +%xhtml-image.mod;]]> + +<!-- Client-side Image Map Module ............................... --> +<!ENTITY % xhtml-csismap.module "INCLUDE" > +<![%xhtml-csismap.module;[ +<!ENTITY % xhtml-csismap.mod + PUBLIC "-//W3C//ELEMENTS XHTML Client-side Image Maps 1.0//EN" + "http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-csismap-1.mod" > +%xhtml-csismap.mod;]]> + +<!-- Server-side Image Map Module ............................... --> +<!ENTITY % xhtml-ssismap.module "INCLUDE" > +<![%xhtml-ssismap.module;[ +<!ENTITY % xhtml-ssismap.mod + PUBLIC "-//W3C//ELEMENTS XHTML Server-side Image Maps 1.0//EN" + "http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-ssismap-1.mod" > +%xhtml-ssismap.mod;]]> + +<!-- Param Element Module ....................................... --> +<!ENTITY % xhtml-param.module "INCLUDE" > +<![%xhtml-param.module;[ +<!ENTITY % xhtml-param.mod + PUBLIC "-//W3C//ELEMENTS XHTML Param Element 1.0//EN" + "http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-param-1.mod" > +%xhtml-param.mod;]]> + +<!-- Embedded Object Module ..................................... --> +<!ENTITY % xhtml-object.module "INCLUDE" > +<![%xhtml-object.module;[ +<!ENTITY % xhtml-object.mod + PUBLIC "-//W3C//ELEMENTS XHTML Embedded Object 1.0//EN" + "http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-object-1.mod" > +%xhtml-object.mod;]]> + +<!-- Tables Module ............................................... --> +<!ENTITY % xhtml-table.module "INCLUDE" > +<![%xhtml-table.module;[ +<!ENTITY % xhtml-table.mod + PUBLIC "-//W3C//ELEMENTS XHTML Tables 1.0//EN" + "http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-table-1.mod" > +%xhtml-table.mod;]]> + +<!-- Forms Module ............................................... --> +<!ENTITY % xhtml-form.module "INCLUDE" > +<![%xhtml-form.module;[ +<!ENTITY % xhtml-form.mod + PUBLIC "-//W3C//ELEMENTS XHTML Forms 1.0//EN" + "http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-form-1.mod" > +%xhtml-form.mod;]]> + +<!-- Legacy Markup ............................................... --> +<!ENTITY % xhtml-legacy.module "IGNORE" > +<![%xhtml-legacy.module;[ +<!ENTITY % xhtml-legacy.mod + PUBLIC "-//W3C//ELEMENTS XHTML Legacy Markup 1.0//EN" + "http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-legacy-1.mod" > +%xhtml-legacy.mod;]]> + +<!-- Document Structure Module (required) ....................... --> +<!ENTITY % xhtml-struct.module "INCLUDE" > +<![%xhtml-struct.module;[ +<!ENTITY % xhtml-struct.mod + PUBLIC "-//W3C//ELEMENTS XHTML Document Structure 1.0//EN" + "http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-struct-1.mod" > +%xhtml-struct.mod;]]> + +<!-- end of XHTML 1.1 DTD ................................................. --> +<!-- ....................................................................... --> diff --git a/testing/web-platform/tests/css/tools/w3ctestlib/templates/chapter-toc.tmpl b/testing/web-platform/tests/css/tools/w3ctestlib/templates/chapter-toc.tmpl new file mode 100644 index 0000000000..e1e8bc275d --- /dev/null +++ b/testing/web-platform/tests/css/tools/w3ctestlib/templates/chapter-toc.tmpl @@ -0,0 +1,46 @@ +[%# variables in this template + indexext [string, e.g. '.html'] + suitetitle [string] + specroot [uri string] + formatdir [dir name string] + chapters [list of struct] + .numstr [string, e.g. '6.1.13'] + .title [string] + .testcount [number] +%] +[% IF isXML %] +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +[% ELSE %] +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"> +<html> +[% END %] + <head> + <title>[% suitetitle %]</title> + <style type="text/css"> + @import "http://www.w3.org/StyleSheets/TR/base.css"; + @import "[% IF formatdir %]../[% END %]indices.css"; + </style> + </head> +<body> + <h1>[% suitetitle %] By Chapter</h1> + + <p>This index contains both + <a href="http://wiki.csswg.org/test/selftest">self-describing tests</a> + and reftests. + A separate <a href="reftest-toc[% indexext%]">alphabetical reftest index</a> + is provided for tests in <a href="http://wiki.csswg.org/test/reftest">reftest + format</a> along with the <a href="reftest.list">reftest manifest</a>.</p> + + <table> +[% FOREACH chapter IN chapters %] + <tbody id="s[% chapter.numstr %]"> + <tr><th><a href="chapter-[% chapter.numstr %][% indexext %]"> + [% (chapter.numstr.match('^\d')) ? 'Chapter' : 'Appendix' +%] [%+ chapter.numstr +%] - + [%+ chapter.title +%]</a></th> + <td>([% chapter.testcount +%] Tests)</td></tr> + </tbody> +[% END %] + </table> +</body> +</html>
\ No newline at end of file diff --git a/testing/web-platform/tests/css/tools/w3ctestlib/templates/implementation-report-TEMPLATE.data.tmpl b/testing/web-platform/tests/css/tools/w3ctestlib/templates/implementation-report-TEMPLATE.data.tmpl new file mode 100644 index 0000000000..0231f23ba4 --- /dev/null +++ b/testing/web-platform/tests/css/tools/w3ctestlib/templates/implementation-report-TEMPLATE.data.tmpl @@ -0,0 +1,21 @@ +# UA version OS version +# UA string (if applicable) +# http://test.csswg.org/suites/[% suite %]/DATESTAMP/ +# See http://wiki.csswg.org/test/implementation-report for instructions +testname revision result comment +[% FOREACH test IN tests.sort(name) %] +[% FOREACH format IN formats %] +[% IF formatInfo.$format.report %] +[% SET skipFormat = 0 %] +[% FOREACH flag IN test.flags %] + [% SET skipFormat = 1 IF flag == formatInfo.$format.filter %] +[% END %] +[% UNLESS skipFormat +%] +[%+ formatInfo.$format.path +%]/[% test.name +%].[% formatInfo.$format.ext +%] [%+ test.revision +%] ? +[% END %] +[% END %] +[% END %] +[% END %] +[% FOREACH test IN addtests.sort() +%] +[%+ test +%] [%+ test.revision +%] ? +[% END %] diff --git a/testing/web-platform/tests/css/tools/w3ctestlib/templates/index.content.tmpl b/testing/web-platform/tests/css/tools/w3ctestlib/templates/index.content.tmpl new file mode 100644 index 0000000000..e32d8fe567 --- /dev/null +++ b/testing/web-platform/tests/css/tools/w3ctestlib/templates/index.content.tmpl @@ -0,0 +1,195 @@ +[% PROCESS "suitedata.tmpl" %] +[% IF official %] + <h1>[% suites.$suite.title %]</h1> +[% ELSE %] + <h1>Unofficial [% suites.$suite.title %]</h1> +[% END %] + <dt>Test Coordinator:</dt> + <dd>[% suites.$suite.owner %]</dd> + + <p>This is a <strong>[% statusNames.${suites.$suite.status}.title or "ERROR: $suite" %]</strong> + version of the [% suites.$suite.title %].</p> + +[% IF suites.$suite.harness != '' %] + <p>You can provide test data or review the testing results for this test suite:</p> + <dt><a href="http://test.csswg.org/harness/suite/[% suites.$suite.harness %]">Enter Data</a></dt> + <dt><a href="http://test.csswg.org/harness/review/[% suites.$suite.harness %]">Review Results</a></dt> +[% END %] + + +[% IF devel %] + <p>This build exists to aid in test suite development and contains unreviewed + tests. <strong>The pass/fail results of these tests are not reliable + indications of conformance.</strong> +[% ELSE %] + <p>Some tests in the test suite may contain errors. +[% END %] + Please check the latest version of the + <a href="[% suites.$suite.specroot %]">[% suites.$suite.spec %] specification</a> + <strong>and its errata</strong> + before assuming a failure is due to an implementation bug and + not a test suite bug.</p> + +[% UNLESS official %] + <p>You can find the <a href="[% suites.$suite.officialUrl %]">official + build</a> of the [% suites.$suite.title %] on W3C's web site.</p> +[% END %] + + <p>[% IF suites.$suite.status != 'fin' && suites.$suite.status != 'rc' %] + In time we hope to correct all errors and extend this test suite to + cover all of [% suites.$suite.spec %]. Your help is welcome in this effort. + [% END %] + The appropriate mailing list for submitting tests and bug reports is + <a href="http://lists.w3.org/Archives/Public/public-css-testsuite/">public-css-testsuite@w3.org</a>.</p> + <p> + To report bugs or feedback about a specific test file, + search for the filename (without extension) in + <a href="https://github.com/web-platform-tests/wpt/issues">web-platform-tests issues</a>, + and file a new issue if necessary with suggested label "wg-css". + More information on the contribution process and test guidelines is + available on the <a href="http://wiki.csswg.org/test">wiki + page</a>.</p> + + <p>Tests are currently available in these formats:</p> + + <dl> +[% FOREACH format IN formats %] + [% IF format == 'html4' %] + <dt><a href="html4/toc.htm">HTML 4.01</a></dt> + <dd>HTML 4.01 tests sent as <code>text/html</code></dd> + [% END %] + [% IF format == 'html5' %] + <dt><a href="html/toc.htm">HTML 5</a></dt> + <dd>HTML 5 tests sent as <code>text/html</code></dd> + [% END %] + [% IF format == 'xhtml1' %] + <dt><a href="xhtml1/toc.xht">XHTML 1.1</a></dt> + <dd>XHTML 1.1 tests sent as <code>application/xhtml+xml</code></dd> + [% END %] + [% IF format == 'xhtml1print' %] + <dt><a href="xhtml1print/toc.xht">XHTML 1.1 for Printers</a></dt> + <dd>XHTML 1.1 tests with all images converted from PNG to JPEG + and formatted with headers and footers to ease testing of + embedded printer software. This is not a canonical format, + and some tests may fail due to the format conversion that + would otherwise pass in the above XHTML 1.1 format.</dd> + </dl> + [% END %] +[% END %] + +[% IF suite == 'css2.1' %] + <p>Additional tests, that do not fit in any of those formats, + are located separately:</p> + + <dl> + <dt><a href="other/">Other Formats</a></dt> + <dd>Tests that do not fit in the above formats because they + test a combination of CSS and a particular document language's + features and/or error recovery.</dd> + </dl> +[% END %] + + <p>Unless the test instructions explicitly indicate otherwise, + any occurrence of red in a test indicates test failure.</p> + +[% IF suite == 'css2.1' %] + <p>Note that <em>many</em> of the tests require the + <a href="http://www.w3.org/Style/CSS/Test/Fonts/Ahem/">Ahem font to be installed</a>. + These tests are marked with the 'ahem' flag in their metadata. + Without the Ahem font installed, these tests are of no value.</p> + <p>Some of the font-related tests also require + <a href="http://www.w3.org/Style/CSS/Test/Fonts/">special fonts</a>. + These tests are marked with the 'font' flag in their metadata.</p> + +[% END %] +<h2 id="implement">Implementation Reports</h2> + <p>An <a href="implementation-report-TEMPLATE.data">implementation report template</a> + is available to help with creating implementation reports. See also the + <a href="http://lists.w3.org/Archives/Public/public-css-testsuite/2010Aug/0020.html">explanation</a> + of its format.</p> + +<h2 id="common">Common Assumptions</h2> + + <p>Most of the test suite makes the following assumptions:</p> + <ul> + <li>The X/HTML <code>div</code> element is assigned <code>display: block;</code> + and no other property declaration.</li> + <li>The X/HTML <code>span</code> element is assigned <code>display: inline;</code> + and no other property declaration.</li> + <li>The X/HTML <code>p</code> element is assigned <code>display: block;</code></li> + <li>The X/HTML <code>li</code> element is assigned <code>display: list-item;</code></li> + <li>The X/HTML table elements <code>table</code>, <code>tbody</code>, + <code>tr</code>, and <code>td</code> are assigned the <code>display</code> + values <code>table</code>, <code>table-row-group</code>, + <code>table-row</code>, and <code>table-cell</code>, respectively.</li> + <li>The device can display the sixteen color values associated with the color + keywords <code>black</code>, <code>white</code>, <code>gray</code>, + <code>silver</code>, <code>red</code>, <code>green</code>, <code>blue</code>, + <code>purple</code>, <code>yellow</code>, <code>orange</code>, <code>teal</code>, + <code>fuchsia</code>, <code>maroon</code>, <code>navy</code>, <code>aqua</code>, + and <code>lime</code> as distinct colors.</li> + <li>The UA is set to print background colors and, if it supports graphics, + background images.</li> + <li>The UA implements reasonable page-breaking behavior; e.g., it is assumed + that UAs will not break at every opportunity, but only near the end of + a page unless a page break is forced.</li> + <li>The UA implements reasonable line-breaking behavior; e.g., it is assumed + that spaces between alphanumeric characters provide line breaking + opportunities and that UAs will not break at every opportunity, but only + near the end of a line unless a line break is forced.</li> + </ul> + +<h2 id="uncommon">Uncommon Assumptions</h2> + + <p>In addition, some of the tests make one or more of the following + assumptions:</p> + + <ul> + <li>The device is a full-color device.</li> + <li>The device has a viewport width of at least 640px (approx).</li> + <li>The resolution of the device is 96 CSS pixels per inch.</li> + <li>The UA imposes no minimum font size.</li> + <li>The 'medium' font-size computes to 16px.</li> + <li>The initial value of 'color' is black.</li> + <li>The canvas background is white.</li> + <li>The user stylesheet is empty (except where indicated by the tests).</li> + <li>The device is interactive and uses scroll bars.</li> + </ul> + + <p>The tests that need these assumptions to be true have not yet been + marked, but it is likely that we will add a way to identify these + tests in due course. Tests should avoid relying on these assumptions + unless necessary.</p> + +<h2>License</h2> + +[% IF official %] + <p>This test suite is licensed under both the + <a href="http://www.w3.org/Consortium/Legal/2008/04-testsuite-license">W3C + Test Suite License</a> and the <a href="http://www.w3.org/Consortium/Legal/2008/03-bsd-license">W3C + 3-clause BSD License</a>. See W3C Legal's <a href="http://www.w3.org/Consortium/Legal/2008/04-testsuite-copyright">explanation + of the licenses</a>.</p> +[% ELSE %] + <p>These tests are licensed under the <a href="LICENSE-BSD">BSD 3-clause + License</a>. You may modify and distribute them under those terms. Aside + from their titles, documentation, and location they are identical to the + official tests of the same date. However, only the + <a href="http://www.w3.org/Style/Test/[% suite %]/current/">official % suites.$suite.title %] + </a> may be used as the basis for CSS conformance + claims.</p> +[% END %] + +<h2>Acknowledgements</h2> + + <p>Many thanks to the following for their contributions:</p> + <ul> +[%- FOREACH person = contributors.keys.sort %] + [% IF not person.match('^CSS1') %] + <li>[% person %]</li> + [% END %] +[%- END %] + </ul> +[% IF suite == 'css2.1' %] + <p>...and all the <a href="http://www.w3.org/Style/CSS/Test/CSS1/current/tsack.html">contributors + to the CSS1 test suite</a>.</p> +[% END %] diff --git a/testing/web-platform/tests/css/tools/w3ctestlib/templates/index.htm.tmpl b/testing/web-platform/tests/css/tools/w3ctestlib/templates/index.htm.tmpl new file mode 100644 index 0000000000..c29ed4a3c7 --- /dev/null +++ b/testing/web-platform/tests/css/tools/w3ctestlib/templates/index.htm.tmpl @@ -0,0 +1,20 @@ +[% PROCESS "suitedata.tmpl" %] +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"> +<html lang="en"> + <head> +[% IF official %] + <title>[% suites.$suite.title %]</title> +[% ELSE %] + <title>Unofficial [% suites.$suite.title %]</title> +[% END %] + <style type="text/css"> + @import "http://www.w3.org/StyleSheets/TR/base.css"; + @import "indices.css"; + </style> + </head> + <body> + +[% INCLUDE "index.content.tmpl" %] + +</body> +</html> diff --git a/testing/web-platform/tests/css/tools/w3ctestlib/templates/index.xht.tmpl b/testing/web-platform/tests/css/tools/w3ctestlib/templates/index.xht.tmpl new file mode 100644 index 0000000000..b355544cfa --- /dev/null +++ b/testing/web-platform/tests/css/tools/w3ctestlib/templates/index.xht.tmpl @@ -0,0 +1,20 @@ +[% PROCESS "suitedata.tmpl" %] +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> + <head> +[% IF official %] + <title>[% suites.$suite.title %]</title> +[% ELSE %] + <title>Unofficial [% suites.$suite.title %]</title> +[% END %] + <style type="text/css"> + @import "http://www.w3.org/StyleSheets/TR/base.css"; + @import "indices.css"; + </style> + </head> + <body> + +[% INCLUDE index.content.tmpl %] + +</body> +</html> diff --git a/testing/web-platform/tests/css/tools/w3ctestlib/templates/indices.css b/testing/web-platform/tests/css/tools/w3ctestlib/templates/indices.css new file mode 100644 index 0000000000..7bc70eeef9 --- /dev/null +++ b/testing/web-platform/tests/css/tools/w3ctestlib/templates/indices.css @@ -0,0 +1,96 @@ +/* CSS for CSS Conformance Test Indices */ +/* Written by fantasai */ + +/* Test Tables */ + + table { + border-collapse: collapse; + } + + thead { + border-bottom: 0.2em solid; + } + + tbody { + border: thin solid; + border-style: solid none; + } + + tbody.ch { + border-top: 0.2em solid; + } + tbody.ch th { + font-weight: bold; + } + + tbody th { + border-bottom: silver dotted thin; + background: #EEE; + color: black; + font-weight: normal; + font-style: italic; + } + tbody th :link { + color: gray; + background: transparent; + } + tbody th :visited { + color: #333; + background: transparent; + } + + th, td { + padding: 0.2em; + text-align: left; + vertical-align: baseline; + } + + td { + font-size: 0.9em; + } + + /* flags */ + td abbr { + border: solid thin gray; + padding: 0 0.1em; + cursor: help; + } + td abbr:hover { + background: #ffa; + color: black; + } + + + tr:hover { + background: #F9F9F9; + color: navy; + } + + th a, + td a { + text-decoration: none; + } + th a:hover, + td a:hover, + th a:focus, + td a:focus { + text-decoration: underline; + } + + td a { + display: block; + padding-left: 2em; + text-indent: -1em; + } + .refs { + font-weight: bold; + font-size: larger; + } + .assert, .assert > li { + list-style-type: none; + font-style: italic; + color: gray; + margin: 0; + padding: 0; + text-indent: 0; + } diff --git a/testing/web-platform/tests/css/tools/w3ctestlib/templates/reftest-toc.tmpl b/testing/web-platform/tests/css/tools/w3ctestlib/templates/reftest-toc.tmpl new file mode 100644 index 0000000000..91894235a4 --- /dev/null +++ b/testing/web-platform/tests/css/tools/w3ctestlib/templates/reftest-toc.tmpl @@ -0,0 +1,74 @@ +[%# variables in this template + isXML [bool] + extmap [ExtensionMap object] + suitetitle [string] + specroot [URI of spec] + formatdir [string] + chaptitle [string] + chapdir [string] + testcount [number] + sections [list of struct] + .id [string - section number or id] + .uri [URI of section] + .tests [list of struct] + .asserts [list of strings] + .flags [list of token strings] + .links [list of uri strings] + .name [string] +%] +[% PROCESS suitedata.tmpl %] +[% IF isXML %] +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +[% formatMismatchFlag = 'HTMLonly' %] +[% ELSE %] +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"> +<html> +[% formatMismatchFlag = 'nonHTML' %] +[% END %] + <head> + <title>[% suitetitle %] Reftest Index</title> + <style type="text/css"> + @import "http://www.w3.org/StyleSheets/TR/base.css"; + @import "[% IF formatdir %]../[% END %]indices.css"; + </style> + </head> + + <body> + + <h1>[% suitetitle %] Reftest Index</h1> + <table width="100%"> + <col id="test-column">[% IF isXML %]</col>[% END %] + <col id="ref-column">[% IF isXML %]</col>[% END %] + <col id="flags-column">[% IF isXML %]</col>[% END %] + <thead> + <tr> + <th>Test</th> + <th>Reference</th> + <th>Flags</th> + </tr> + </thead> +[% FOREACH entry IN tests.sort('name') %] + [% IF entry.references and not entry.flags.contains(formatMismatchFlag) %] + <tbody id="[% entry.name %]" class="[% entry.flags.join(' ') %]"> + [% FOREACH refList IN entry.references %] + [% IF loop.first %] + <tr> + <td rowspan="[% loop.size %]" title="[% entry.title | collapse | html %]"> + <a href="[% extmap.translate(entry.file) %]">[% entry.name %]</a></td> + <td>[% FOREACH ref IN refList %]<a href="[% extmap.translate(ref.relpath) %]">[% refCompMap.${ref.type} %]</a> [% END %]</td> + <td rowspan="[% entry.references.size %]">[% FOREACH flag IN entry.flags %][% IF flag != 'nonHTML' and flag != 'HTMLonly' %]<abbr class="[% flag %]" title="[% flagInfo.$flag.title %]">[% flagInfo.$flag.abbr %]</abbr>[% END %][% END %]</td> + </tr> + [% ELSE %] + <tr> + <td><a href="[% extmap.translate(ref.relpath) %]">[% refCompMap.${ref.type} %]</a></td> + </tr> + [% END %] + [% END %] + </tbody> + [% END %] +[% END %] + </table> + + </body> +</html> diff --git a/testing/web-platform/tests/css/tools/w3ctestlib/templates/reftest.tmpl b/testing/web-platform/tests/css/tools/w3ctestlib/templates/reftest.tmpl new file mode 100644 index 0000000000..14b9bb6595 --- /dev/null +++ b/testing/web-platform/tests/css/tools/w3ctestlib/templates/reftest.tmpl @@ -0,0 +1,7 @@ +[% FOR entry IN tests.sort('name') %] +[% IF not entry.flags.contains(formatMismatchFlag) %] +[% FOREACH refList IN entry.references %] +[%+ extmap.translate(entry.file) %] [% FOREACH ref IN refList %] [%+ ref.type %] [%+ extmap.translate(ref.relpath) %][% END %] +[% END %] +[% END %] +[% END %] diff --git a/testing/web-platform/tests/css/tools/w3ctestlib/templates/suitedata.tmpl b/testing/web-platform/tests/css/tools/w3ctestlib/templates/suitedata.tmpl new file mode 100644 index 0000000000..6aae9f2ea8 --- /dev/null +++ b/testing/web-platform/tests/css/tools/w3ctestlib/templates/suitedata.tmpl @@ -0,0 +1,23 @@ +[% refCompMap = + { '==' => '=', + '!=' => '≠' + } +%] +[% statusNames = { + 'dev' => { + 'title' => 'Development', + 'link' => 'http://www.w3.org/Style/CSS/Test/#phase-pa' }, + 'alpha' => { + 'title' => 'Alpha', + 'link' => 'http://www.w3.org/Style/CSS/Test/#phase-alpha' }, + 'beta' => { + 'title' => 'Beta', + 'link' => 'http://www.w3.org/Style/CSS/Test/#phase-beta' }, + 'rc' => { + 'title' => 'Release Candidate', + 'link' => 'http://www.w3.org/Style/CSS/Test/#phase-rc' }, + 'final' => { + 'title' => 'Final', + 'link' => 'http://www.w3.org/Style/CSS/Test/#phase-fin' }, + } +%] diff --git a/testing/web-platform/tests/css/tools/w3ctestlib/templates/test-toc.tmpl b/testing/web-platform/tests/css/tools/w3ctestlib/templates/test-toc.tmpl new file mode 100644 index 0000000000..ff9ffbc1b8 --- /dev/null +++ b/testing/web-platform/tests/css/tools/w3ctestlib/templates/test-toc.tmpl @@ -0,0 +1,97 @@ +[%# variables in this template + isXML [bool] + extmap [ExtensionMap object] + suitetitle [string] + specroot [URI of spec] + formatdir [string] + chaptitle [string] + chapdir [string] + testcount [number] + sections [list of struct] + .id [string - section number or id] + .uri [URI of section] + .tests [list of struct] + .asserts [list of strings] + .flags [list of token strings] + .links [list of uri strings] + .name [string] +%] +[% PROCESS suitedata.tmpl %] +[% IF isXML %] +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +[% formatMismatchFlag = 'HTMLonly' %] +[% ELSE %] +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"> +<html> +[% formatMismatchFlag = 'nonHTML' %] +[% END %] + <head> + <title>[% chaptertitle %] - [% suitetitle %]</title> + <style type="text/css"> + @import "http://www.w3.org/StyleSheets/TR/base.css"; + @import "[% IF formatdir %]../[% END %]indices.css"; + </style> + </head> + + <body> + + <h1>[% suitetitle %]</h1> +[% IF chaptertitle %] + <h2>[% chaptertitle %] ([% testcount %] tests)</h2> +[% END %] + <table width="100%"> + <col id="test-column">[% IF isXML %]</col>[% END %] + <col id="refs-column">[% IF isXML %]</col>[% END %] + <col id="flags-column">[% IF isXML %]</col>[% END %] + <col id="info-column">[% IF isXML %]</col>[% END %] + <thead> + <tr> + <th>Test</th> + <th><abbr title="Rendering References">Refs</abbr></th> + <th>Flags</th> + <th>Info</th> + </tr> + </thead> +[% FOREACH section IN sections %] + <tbody id="s[% section.numstr %]"> + [% IF section.title %] + <tr><th colspan="4" scope="rowgroup"> + <a href="#s[% section.numstr %]">+</a> + <a href="[% section.uri %]">[% section.numstr +%] [%+ section.title %]</a></th></tr> + [% END %] + <!-- [% section.tests.size %] tests --> + [% FOREACH entry IN section.tests.sort('name') %] + [% FOREACH flag IN entry.flags %] + [% SET skip = 1 IF flag == formatMismatchFlag %] + [% END %] + [% UNLESS skip %] + [% primary = (entry.links.0 == section.uri) or (entry.links.0 == section.uri.replace(specroot, draftroot)) %] + <tr id="[% entry.name %]-[% section.numstr %]" class=" + [% 'primary' IF primary %] + [% ' ' IF primary and entry.flags.size > 0 %] + [% entry.flags.join(' ') %]"> + <td>[% '<strong>' IF primary %] + <a href="[% extmap.translate(entry.file) %]">[% entry.name%]</a> + [% '</strong>' IF primary %]</td> + <td>[% FOREACH refList IN entry.references %][% FOREACH ref IN refList %]<a href="[% extmap.translate(ref.relpath) %]">[% refCompMap.${ref.type} %]</a> [%+ END %][%+ END %]</td> + <td>[% FOREACH flag IN entry.flags %][% IF flag != 'nonHTML' and flag != 'HTMLonly' %]<abbr class="[% flag %]" title="[% flagInfo.$flag.title %]">[% flagInfo.$flag.abbr %]</abbr>[% END %][% END %]</td> + <td>[% entry.title | collapse | html %] + [% IF entry.asserts.size > 0 %] + <ul class="assert"> + [% FOREACH assertion IN entry.asserts %] + <li>[% assertion | collapse | html %]</li> + [% END %] + </ul> + [% END %] + </td> + </tr> + [% END %] + [% skip = 0 %] + [% END %] + </tbody> +[% END %] + </table> + + </body> +</html>
\ No newline at end of file diff --git a/testing/web-platform/tests/css/tools/w3ctestlib/templates/testinfo.data.tmpl b/testing/web-platform/tests/css/tools/w3ctestlib/templates/testinfo.data.tmpl new file mode 100644 index 0000000000..d06a2a906c --- /dev/null +++ b/testing/web-platform/tests/css/tools/w3ctestlib/templates/testinfo.data.tmpl @@ -0,0 +1,16 @@ +id references title flags links revision credits assertion +[% FOREACH test IN tests.sort('name') %] +[%+ test.file.replace('\.[a-z]+$', '') +%] +[%- FOREACH refList IN test.references -%][%- FOREACH ref IN refList -%] +[%- '!' IF ref.type == '!=' %][% extmap.translate(ref.relpath) %][% ',' IF not loop.last() -%] +[%- END +%][% ';' IF not loop.last() -%] +[%- END +%] +[%- test.title FILTER collapse +%] +[%- test.flags.join(',') +%] +[%- test.links.join(',') +%] +[%- test.revision +%] +[%- FOREACH credit IN test.credits -%] +`[% credit.0 %]`<[% credit.1 %]>[% ',' IF not loop.last() -%] +[%- END +%] +[%- test.asserts.join(' ') FILTER collapse +%] +[% END %] |