fix bugs in relaxng; new html5 support provided by relaxng schema

This commit is contained in:
Eugene Kudelevsky
2011-08-16 18:51:36 +04:00
parent 5ebac4b4ff
commit ef6a57ea54
41 changed files with 6429 additions and 76 deletions
+3 -35
View File
@@ -1,38 +1,4 @@
<idea-plugin version="2" url="http://www.jetbrains.net/confluence/display/CONTEST/RELAX-NG+Support">
<id>RelaxNG-Support</id>
<name>RELAX-NG Support</name>
<depends>com.intellij.modules.xml</depends>
<description><![CDATA[
Support for RELAX-NG XML schemas. See <a href="http://relaxng.org/">relaxng.org</a> and the corresponding
IntelliJ IDEA feature request: <a href="http://www.jetbrains.net/jira/browse/IDEA-13734">IDEA-13734</a>.
<p>
The plugin provides the following features:
</p>
<ul>
<li> Completion and validation of XML documents associated with RELAX-NG schemas</li>
<li> Editing RELAX-NG files in XML and compact syntax, including on-the-fly error checking, completion,
documentation lookup and more.</li>
<li> Conversion between different schema formats (including W3C XML Schema/XML 1.0 DTDs) using
<a href="http://www.thaiopensource.com/relaxng/trang.html">Trang</a></li>
</ul>
]]></description>
<version>1.6</version>
<change-notes><![CDATA[
<ul>
<li>extreme index optimization</li>
<li>renameable xml prefixes</li>
<li>IDEA 9.x compatibility bugfixes</li>
</ul>
<p>
The complete list of changes in earlier versions is available
<a href="http://www.jetbrains.net/confluence/display/CONTEST/RELAX-NG+Support#RELAX-NGSupport-VersionHistory">here</a>
</p>
]]></change-notes>
<vendor email="sascha.weinreuter@cit.de">Sascha Weinreuter</vendor>
<idea-plugin>
<extensions defaultExtensionNs="com.intellij">
<errorHandler implementation="com.intellij.diagnostic.ITNReporter" />
<gotoSymbolContributor implementation="org.intellij.plugins.relaxNG.GotoSymbolContributor" />
@@ -76,6 +42,8 @@
<dom.implementation interfaceClass="org.intellij.plugins.relaxNG.xml.dom.RngGrammar" implementationClass="org.intellij.plugins.relaxNG.xml.dom.impl.RngGrammarImpl"/>
<dom.implementation interfaceClass="org.intellij.plugins.relaxNG.xml.dom.RngInclude" implementationClass="org.intellij.plugins.relaxNG.xml.dom.impl.RngIncludeImpl"/>
<dom.implementation interfaceClass="org.intellij.plugins.relaxNG.xml.dom.RngRef" implementationClass="org.intellij.plugins.relaxNG.xml.dom.impl.RngRefImpl"/>
<xml.html5SchemaProvider implementation="org.intellij.plugins.relaxNG.xml.RngHtml5SchemaProvider"/>
<metaDataContributor implementation="org.intellij.html.RngHtml5MetaDataContributor"/>
</extensions>
<project-components>
@@ -35,7 +35,7 @@ class ChildElementFinder extends RecursionSaveWalker {
}
public Void onRef(DRefPattern p) {
if (myDepth < myTargetDepth) {
if (myDepth < myTargetDepth || myTargetDepth == -1) {
return super.onRef(p);
}
return null;
@@ -44,9 +44,9 @@ class ChildElementFinder extends RecursionSaveWalker {
public Void onElement(DElementPattern p) {
myDepth++;
try {
if (myDepth == myTargetDepth) {
if (myDepth == myTargetDepth || myTargetDepth == -1) {
myRoots.add(p);
return null;
return myTargetDepth != -1 ? null : super.onElement(p);
} else {
return super.onElement(p);
}
@@ -61,8 +61,8 @@ public class CompositeDescriptor extends RngElementDescriptor {
public XmlElementDescriptor[] getElementsDescriptors(XmlTag context) {
final List<XmlElementDescriptor> descriptors = new ArrayList<XmlElementDescriptor>(Arrays.asList(super.getElementsDescriptors(context)));
for (DElementPattern pattern : myPatterns) {
final List<DElementPattern> list = ContainerUtil.findAll(ChildElementFinder.find(2, pattern), NamedPatternFilter.INSTANCE);
descriptors.addAll(Arrays.asList(RngNsDescriptor.convertElementDescriptors(list, myNsDescriptor)));
final List<DElementPattern> list = ChildElementFinder.find(2, pattern);
descriptors.addAll(Arrays.asList(myNsDescriptor.convertElementDescriptors(list)));
}
return descriptors.toArray(new XmlElementDescriptor[descriptors.size()]);
}
@@ -26,8 +26,7 @@ import com.intellij.psi.util.*;
import com.intellij.psi.xml.XmlAttribute;
import com.intellij.psi.xml.XmlTag;
import com.intellij.util.ArrayUtil;
import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.HashMap;
import com.intellij.xml.XmlAttributeDescriptor;
import com.intellij.xml.XmlElementDescriptor;
import com.intellij.xml.XmlElementsGroup;
@@ -42,10 +41,7 @@ import org.kohsuke.rngom.nc.NameClassVisitor;
import org.xml.sax.Locator;
import javax.xml.namespace.QName;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.*;
public class RngElementDescriptor implements XmlElementDescriptor {
private static final Key<ParameterizedCachedValue<XmlElementDescriptor, RngElementDescriptor>> DESCR_KEY = Key.create("DESCR");
@@ -89,8 +85,7 @@ public class RngElementDescriptor implements XmlElementDescriptor {
}
final List<DElementPattern> patterns = ChildElementFinder.find(2, pattern);
final List<DElementPattern> list = ContainerUtil.findAll(patterns, NamedPatternFilter.INSTANCE);
return RngNsDescriptor.convertElementDescriptors(list, myNsDescriptor);
return myNsDescriptor.convertElementDescriptors(patterns);
}
protected XmlElementDescriptor findElementDescriptor(XmlTag childTag) {
@@ -136,13 +131,25 @@ public class RngElementDescriptor implements XmlElementDescriptor {
}
protected XmlAttributeDescriptor[] computeAttributeDescriptors(final Map<DAttributePattern, Pair<? extends Map<String, String>, Boolean>> map) {
final List<DAttributePattern> list = ContainerUtil.findAll(map.keySet(), NamedPatternFilter.INSTANCE);
return ContainerUtil.map2Array(list, XmlAttributeDescriptor.class, new Function<DAttributePattern, XmlAttributeDescriptor>() {
public XmlAttributeDescriptor fun(DAttributePattern dAttributePattern) {
final Pair<? extends Map<String, String>, Boolean> pair = map.get(dAttributePattern);
return new RngXmlAttributeDescriptor(RngElementDescriptor.this, dAttributePattern, pair.first, pair.second);
final Map<QName, RngXmlAttributeDescriptor> name2descriptor = new HashMap<QName, RngXmlAttributeDescriptor>();
for (DAttributePattern pattern : map.keySet()) {
final Pair<? extends Map<String, String>, Boolean> value = map.get(pattern);
for (QName name : pattern.getName().listNames()) {
RngXmlAttributeDescriptor descriptor = name2descriptor.get(name);
final RngXmlAttributeDescriptor newDescriptor = new RngXmlAttributeDescriptor(this, pattern, value.first, value.second);
if (descriptor == null) {
descriptor = newDescriptor;
}
else {
descriptor = descriptor.mergeWith(newDescriptor);
}
name2descriptor.put(name, descriptor);
}
});
}
final Collection<RngXmlAttributeDescriptor> result = name2descriptor.values();
return result.toArray(new RngXmlAttributeDescriptor[result.size()]);
}
public final XmlAttributeDescriptor getAttributeDescriptor(String attributeName, @Nullable XmlTag context) {
@@ -35,8 +35,8 @@ import com.intellij.psi.xml.XmlDocument;
import com.intellij.psi.xml.XmlFile;
import com.intellij.psi.xml.XmlTag;
import com.intellij.util.ArrayUtil;
import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.HashMap;
import com.intellij.xml.XmlElementDescriptor;
import com.intellij.xml.XmlNSDescriptor;
import org.intellij.plugins.relaxNG.ApplicationLoader;
@@ -51,8 +51,10 @@ import org.kohsuke.rngom.digested.DPattern;
import org.kohsuke.rngom.nc.NameClass;
import javax.xml.namespace.QName;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
/**
* Created by IntelliJ IDEA.
@@ -117,12 +119,17 @@ public class RngNsDescriptor implements XmlNSDescriptor, Validator {
}
private XmlElementDescriptor findRootDescriptorInner(XmlTag tag) {
return findDescriptor(tag, ChildElementFinder.find(myPattern));
final List<DElementPattern> patterns = ContainerUtil.findAll(ChildElementFinder.find(-1, myPattern), NamedPatternFilter.INSTANCE);
return findDescriptor(tag, patterns);
}
public XmlElementDescriptor findDescriptor(XmlTag tag, List<DElementPattern> list) {
final QName qName = new QName(tag.getNamespace(), tag.getLocalName());
return findDescriptor(qName, list);
}
private XmlElementDescriptor findDescriptor(final QName qName, List<DElementPattern> list) {
int max = -1;
DElementPattern maxPattern = null;
for (DElementPattern pattern : list) {
@@ -144,9 +151,9 @@ public class RngNsDescriptor implements XmlNSDescriptor, Validator {
if (maxPattern != null) {
if (patterns.size() > 1) {
return new CompositeDescriptor(this, maxPattern, patterns);
return initDescriptor(new CompositeDescriptor(this, maxPattern, patterns));
} else {
return new RngElementDescriptor(this, maxPattern);
return initDescriptor(new RngElementDescriptor(this, maxPattern));
}
} else {
return null;
@@ -159,16 +166,40 @@ public class RngNsDescriptor implements XmlNSDescriptor, Validator {
return XmlElementDescriptor.EMPTY_ARRAY;
}
final List<DElementPattern> list = ContainerUtil.findAll(ChildElementFinder.find(myPattern), NamedPatternFilter.INSTANCE);
return convertElementDescriptors(list, this);
final List<DElementPattern> list = ChildElementFinder.find(-1, myPattern);
return convertElementDescriptors(list);
}
static XmlElementDescriptor[] convertElementDescriptors(List<DElementPattern> finder, final RngNsDescriptor nsDescriptor) {
return ContainerUtil.map2Array(finder, XmlElementDescriptor.class, new Function<DElementPattern, XmlElementDescriptor>() {
public XmlElementDescriptor fun(final DElementPattern elementPattern) {
return new RngElementDescriptor(nsDescriptor, elementPattern);
XmlElementDescriptor[] convertElementDescriptors(List<DElementPattern> patterns) {
patterns = ContainerUtil.findAll(patterns, NamedPatternFilter.INSTANCE);
final Map<QName, List<DElementPattern>> name2patterns = new HashMap<QName, List<DElementPattern>>();
for (DElementPattern pattern : patterns) {
for (QName qName : pattern.getName().listNames()) {
List<DElementPattern> dPatterns = name2patterns.get(qName);
if (dPatterns == null) {
dPatterns = new ArrayList<DElementPattern>();
name2patterns.put(qName, dPatterns);
}
dPatterns.add(pattern);
}
});
}
final List<XmlElementDescriptor> result = new ArrayList<XmlElementDescriptor>();
for (QName qName : name2patterns.keySet()) {
final List<DElementPattern> patternList = name2patterns.get(qName);
final XmlElementDescriptor descriptor = findDescriptor(qName, patternList);
if (descriptor != null) {
result.add(descriptor);
}
}
return result.toArray(new XmlElementDescriptor[result.size()]);
}
protected XmlElementDescriptor initDescriptor(@NotNull XmlElementDescriptor descriptor) {
return descriptor;
}
@NotNull
@@ -15,6 +15,7 @@
*/
package com.intellij.html.impl;
import com.intellij.html.RelaxedHtmlNSDescriptor;
import com.intellij.psi.xml.XmlDocument;
import com.intellij.psi.xml.XmlTag;
import com.intellij.util.ArrayUtil;
@@ -26,7 +27,7 @@ import com.intellij.xml.util.XmlUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class RelaxedHtmlFromSchemaNSDescriptor extends XmlNSDescriptorImpl {
public class RelaxedHtmlFromSchemaNSDescriptor extends XmlNSDescriptorImpl implements RelaxedHtmlNSDescriptor {
public XmlElementDescriptor getElementDescriptor(@NotNull XmlTag tag) {
XmlElementDescriptor elementDescriptor = super.getElementDescriptor(tag);
@@ -15,7 +15,7 @@
*/
package com.intellij.psi.impl.source.html.dtd;
import com.intellij.html.impl.RelaxedHtmlFromSchemaNSDescriptor;
import com.intellij.html.RelaxedHtmlNSDescriptor;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.util.SimpleFieldCache;
import com.intellij.psi.PsiElement;
@@ -57,7 +57,7 @@ public class HtmlNSDescriptorImpl implements XmlNSDescriptor, DumbAware, XmlNSTy
private volatile Map<String, XmlElementDescriptor> myCachedDecls;
public HtmlNSDescriptorImpl(XmlNSDescriptor _delegate) {
this(_delegate, _delegate instanceof RelaxedHtmlFromSchemaNSDescriptor, false);
this(_delegate, _delegate instanceof RelaxedHtmlNSDescriptor, false);
}
public HtmlNSDescriptorImpl(XmlNSDescriptor _delegate, boolean relaxed, boolean caseSensitive) {
@@ -853,7 +853,11 @@ public class XmlTagImpl extends XmlElementImpl implements XmlTag {
private String getNsLocation(String ns) {
if (XmlUtil.XHTML_URI.equals(ns)) {
return ExternalResourceManagerEx.getInstanceEx().getDefaultHtmlDoctype(getProject());
String defaultHtmlDoctype = ExternalResourceManagerEx.getInstanceEx().getDefaultHtmlDoctype(getProject());
if (XmlUtil.HTML5_SCHEMA_LOCATION.equals(defaultHtmlDoctype)) {
defaultHtmlDoctype = XmlUtil.XHTML5_SCHEMA_LOCATION;
}
return defaultHtmlDoctype;
}
return ns;
}
@@ -65,10 +65,7 @@ import com.intellij.util.*;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.xmlb.JDOMXIncluder;
import com.intellij.xml.*;
import com.intellij.xml.impl.schema.ComplexTypeDescriptor;
import com.intellij.xml.impl.schema.TypeDescriptor;
import com.intellij.xml.impl.schema.XmlElementDescriptorImpl;
import com.intellij.xml.impl.schema.XmlNSDescriptorImpl;
import com.intellij.xml.impl.schema.*;
import com.intellij.xml.index.IndexedRelevantResource;
import com.intellij.xml.index.XmlNamespaceIndex;
import org.jetbrains.annotations.NonNls;
@@ -1025,10 +1022,22 @@ public class XmlUtil {
}
public static final String HTML5_SCHEMA_LOCATION;
public static final String XHTML5_SCHEMA_LOCATION;
static {
URL schemaLocationURL = XmlUtil.class.getResource(ExternalResourceManagerImpl.STANDARD_SCHEMAS + "html5/xhtml5.xsd");
HTML5_SCHEMA_LOCATION = VfsUtil.urlToPath(VfsUtil.fixURLforIDEA(schemaLocationURL.toExternalForm()));
final Html5SchemaProvider[] providers = Html5SchemaProvider.EP_NAME.getExtensions();
final URL htmlSchemaLocationURL;
final URL xhtmlSchemaLocationURL;
if (providers.length > 0) {
htmlSchemaLocationURL = providers[0].getHtmlSchemaLocation();
xhtmlSchemaLocationURL = providers[0].getXhtmlSchemaLocation();
}
else {
htmlSchemaLocationURL = XmlUtil.class.getResource(ExternalResourceManagerImpl.STANDARD_SCHEMAS + "html5/xhtml5.xsd");
xhtmlSchemaLocationURL = htmlSchemaLocationURL;
}
HTML5_SCHEMA_LOCATION = VfsUtil.urlToPath(VfsUtil.fixURLforIDEA(htmlSchemaLocationURL.toExternalForm()));
XHTML5_SCHEMA_LOCATION = VfsUtil.urlToPath(VfsUtil.fixURLforIDEA(xhtmlSchemaLocationURL.toExternalForm()));
}
@Nullable
@@ -1052,7 +1061,9 @@ public class XmlUtil {
return HTML4_LOOSE_URI;
}
else if (HtmlUtil.isHtml5Doctype(doctype)) {
docType = HTML5_SCHEMA_LOCATION;
docType = doctype.getLanguage() instanceof HTMLLanguage
? HTML5_SCHEMA_LOCATION
: XHTML5_SCHEMA_LOCATION;
}
}
return docType;
@@ -0,0 +1,9 @@
package com.intellij.html;
import com.intellij.xml.XmlNSDescriptor;
/**
* @author Eugene.Kudelevsky
*/
public interface RelaxedHtmlNSDescriptor extends XmlNSDescriptor {
}
@@ -0,0 +1,19 @@
package com.intellij.xml;
import com.intellij.openapi.extensions.ExtensionPointName;
import org.jetbrains.annotations.NotNull;
import java.net.URL;
/**
* @author Eugene.Kudelevsky
*/
public interface Html5SchemaProvider {
ExtensionPointName<Html5SchemaProvider> EP_NAME = ExtensionPointName.create("com.intellij.xml.html5SchemaProvider");
@NotNull
URL getHtmlSchemaLocation();
@NotNull
URL getXhtmlSchemaLocation();
}
@@ -0,0 +1,109 @@
package org.intellij.html;
import com.intellij.html.impl.RelaxedHtmlFromSchemaElementDescriptor;
import com.intellij.psi.PsiElement;
import com.intellij.psi.xml.XmlAttribute;
import com.intellij.psi.xml.XmlTag;
import com.intellij.util.ArrayUtil;
import com.intellij.xml.*;
import com.intellij.xml.util.HtmlUtil;
/**
* @author Eugene.Kudelevsky
*/
public class RelaxedHtmlFromRngElementDescriptor implements XmlElementDescriptor, XmlElementDescriptorAwareAboutChildren {
private final XmlElementDescriptor myDelegate;
public RelaxedHtmlFromRngElementDescriptor(XmlElementDescriptor delegate) {
myDelegate = delegate;
}
public XmlElementDescriptor getElementDescriptor(XmlTag childTag, XmlTag contextTag) {
XmlElementDescriptor elementDescriptor = myDelegate.getElementDescriptor(childTag, contextTag);
if (elementDescriptor == null) {
return RelaxedHtmlFromSchemaElementDescriptor.getRelaxedDescriptor(this, childTag);
}
return elementDescriptor;
}
@Override
public String getQualifiedName() {
return myDelegate.getQualifiedName();
}
@Override
public String getDefaultName() {
return myDelegate.getDefaultName();
}
public XmlElementDescriptor[] getElementsDescriptors(final XmlTag context) {
return ArrayUtil.mergeArrays(
myDelegate.getElementsDescriptors(context),
HtmlUtil.getCustomTagDescriptors(context),
XmlElementDescriptor.class
);
}
public XmlAttributeDescriptor[] getAttributesDescriptors(final XmlTag context) {
return RelaxedHtmlFromSchemaElementDescriptor.addAttrDescriptorsForFacelets(context, myDelegate.getAttributesDescriptors(context));
}
@Override
public XmlAttributeDescriptor getAttributeDescriptor(XmlAttribute attribute) {
return getAttributeDescriptor(attribute.getName(), attribute.getParent());
}
@Override
public XmlNSDescriptor getNSDescriptor() {
return myDelegate.getNSDescriptor();
}
@Override
public XmlElementsGroup getTopGroup() {
return myDelegate.getTopGroup();
}
@Override
public int getContentType() {
return myDelegate.getContentType();
}
public XmlAttributeDescriptor getAttributeDescriptor(String attributeName, final XmlTag context) {
final XmlAttributeDescriptor descriptor = myDelegate.getAttributeDescriptor(attributeName.toLowerCase(), context);
if (descriptor != null) return descriptor;
return RelaxedHtmlFromSchemaElementDescriptor.getAttributeDescriptorFromFacelets(attributeName, context);
}
@Override
public PsiElement getDeclaration() {
return myDelegate.getDeclaration();
}
@Override
public String getName(PsiElement context) {
return myDelegate.getName(context);
}
@Override
public String getName() {
return myDelegate.getName();
}
@Override
public void init(PsiElement element) {
myDelegate.init(element);
}
@Override
public Object[] getDependences() {
return myDelegate.getDependences();
}
@Override
public boolean allowElementsFromNamespace(String namespace, XmlTag context) {
return true;
}
}
@@ -0,0 +1,43 @@
package org.intellij.html;
import com.intellij.html.RelaxedHtmlNSDescriptor;
import com.intellij.psi.xml.XmlDocument;
import com.intellij.psi.xml.XmlTag;
import com.intellij.util.ArrayUtil;
import com.intellij.xml.XmlElementDescriptor;
import com.intellij.xml.impl.schema.AnyXmlElementDescriptor;
import com.intellij.xml.util.HtmlUtil;
import com.intellij.xml.util.XmlUtil;
import org.intellij.plugins.relaxNG.model.descriptors.RngNsDescriptor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* @author Eugene.Kudelevsky
*/
public class RelaxedHtmlFromRngNSDescriptor extends RngNsDescriptor implements RelaxedHtmlNSDescriptor {
public XmlElementDescriptor getElementDescriptor(@NotNull XmlTag tag) {
XmlElementDescriptor elementDescriptor = super.getElementDescriptor(tag);
String namespace;
if (elementDescriptor == null &&
!((namespace = tag.getNamespace()).equals(XmlUtil.XHTML_URI))) {
return new AnyXmlElementDescriptor(
null,
XmlUtil.HTML_URI.equals(namespace) ? this : tag.getNSDescriptor(tag.getNamespace(), true)
);
}
return elementDescriptor;
}
@Override
protected XmlElementDescriptor initDescriptor(@NotNull XmlElementDescriptor descriptor) {
return new RelaxedHtmlFromRngElementDescriptor(descriptor);
}
@NotNull
public XmlElementDescriptor[] getRootElementsDescriptors(@Nullable final XmlDocument doc) {
return ArrayUtil.mergeArrays(super.getRootElementsDescriptors(doc), HtmlUtil.getCustomTagDescriptors(doc), XmlElementDescriptor.class);
}
}
@@ -0,0 +1,64 @@
package org.intellij.html;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.filters.AndFilter;
import com.intellij.psi.filters.ClassFilter;
import com.intellij.psi.filters.XmlTextFilter;
import com.intellij.psi.meta.MetaDataContributor;
import com.intellij.psi.meta.MetaDataRegistrar;
import com.intellij.util.ReflectionCache;
import com.intellij.xml.util.XmlUtil;
import org.intellij.plugins.relaxNG.compact.psi.RncDecl;
import org.intellij.plugins.relaxNG.compact.psi.RncFile;
import org.intellij.plugins.relaxNG.compact.psi.RncNsDecl;
import org.intellij.plugins.relaxNG.compact.psi.impl.RncDocument;
/**
* @author Eugene.Kudelevsky
*/
public class RngHtml5MetaDataContributor implements MetaDataContributor {
@Override
public void contributeMetaData(MetaDataRegistrar registrar) {
registrar.registerMetaData(
new AndFilter(
new ClassFilter(RncDocument.class),
new MyRncNamespaceFilter(XmlUtil.HTML_URI, XmlUtil.XHTML_URI)),
RelaxedHtmlFromRngNSDescriptor.class
);
}
private static class MyRncNamespaceFilter extends XmlTextFilter {
MyRncNamespaceFilter(String... namespaces) {
super(namespaces);
}
public boolean isClassAcceptable(Class hintClass) {
return ReflectionCache.isAssignable(RncDocument.class, hintClass);
}
public boolean isAcceptable(Object element, PsiElement context) {
if (!(element instanceof RncDocument)) {
return false;
}
final PsiFile file = ((RncDocument)element).getContainingFile();
String namespace = null;
if (file instanceof RncFile) {
for (RncDecl decl : ((RncFile)file).getDeclarations()) {
if (decl instanceof RncNsDecl) {
namespace = decl.getDeclaredNamespace();
break;
}
}
}
if (namespace != null) {
for (String aMyValue : myValue) {
if (aMyValue.equals(namespace)) return true;
}
}
return false;
}
}
}
@@ -0,0 +1,23 @@
package org.intellij.plugins.relaxNG.xml;
import com.intellij.xml.Html5SchemaProvider;
import org.jetbrains.annotations.NotNull;
import java.net.URL;
/**
* @author Eugene.Kudelevsky
*/
public class RngHtml5SchemaProvider implements Html5SchemaProvider {
@NotNull
@Override
public URL getHtmlSchemaLocation() {
return RngHtml5SchemaProvider.class.getResource("/resources/html5-schema/html5.rnc");
}
@NotNull
@Override
public URL getXhtmlSchemaLocation() {
return RngHtml5SchemaProvider.class.getResource("/resources/html5-schema/xhtml5.rnc");
}
}
@@ -0,0 +1,23 @@
The RELAX NG Schema for (X)HTML 5 is licensed under the MIT open source license.
The following legal notice applies to all files in this directory:
Copyright (c) 2005-2007 Elika J. Etemad (fantasai) and Henri Sivonen (hsivonen)
Copyright (c) 2007-2008 Mozilla Foundation
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
@@ -0,0 +1,281 @@
datatypes w = "http://whattf.org/datatype-draft"
# #####################################################################
## RELAX NG Schema for HTML 5: Web Application Features #
# #####################################################################
## Additions to Common Attributes
common.attrs.interact &=
( common.attrs.contextmenu?
& common.attrs.contenteditable?
& common.attrs.draggable?
& common.attrs.dropzone?
& common.attrs.hidden?
& common.attrs.spellcheck?
)
common.attrs.other &= common.attrs.interact
## Context Menu: contextmenu
common.attrs.contextmenu =
attribute contextmenu {
common.data.idref
}
## Editable Content: contenteditable
common.attrs.contenteditable =
attribute contenteditable {
w:string "true" | w:string "false" | w:string ""
}
## Draggable Element: draggable
common.attrs.draggable =
attribute draggable {
w:string "true" | w:string "false"
}
## Dropzone: dropzone
common.attrs.dropzone =
attribute dropzone {
list {
( xsd:string { pattern = "[sS]:.+" }
| xsd:string { pattern = "[fF]:.+" }
)*
,
( w:string "copy"
| w:string "move"
| w:string "link"
)?
,
( xsd:string { pattern = "[sS]:.+" }
| xsd:string { pattern = "[fF]:.+" }
)*
}
}
## Hidden Element: hidden
common.attrs.hidden =
attribute hidden {
w:string "hidden" | w:string ""
}
## Spellchecking and grammar checking: spellcheck
common.attrs.spellcheck =
attribute spellcheck{
w:string "true" | w:string "false" | w:string ""
}
## Application Cache: manifest
html.attrs.manifest =
attribute manifest {
common.data.uri.non-empty
}
html.attrs &= html.attrs.manifest?
## Progess Indicator: <progress>
progress.elem =
element progress { progress.inner & progress.attrs }
progress.attrs =
( common.attrs
& progress.attrs.value?
& progress.attrs.max?
)
progress.attrs.value =
attribute value {
common.data.float.non-negative
}
progress.attrs.max =
attribute max {
common.data.float.positive
}
progress.inner =
( common.inner.phrasing ) #Cannot enforce textContent format here
common.elem.phrasing |= progress.elem
## Command with an associated action: <command type='command'>
command.command.elem =
element command { command.inner & command.command.attrs }
command.command.attrs =
( common.attrs
& command.command.attrs.type?
& common-command.attrs
)
command.command.attrs.type =
attribute type {
w:string "command"
}
command.elem = command.command.elem
## Selection of one item from a list of items: <command type='radio'>
command.radio.elem =
element command { command.inner & command.radio.attrs }
command.radio.attrs =
( common.attrs
& ( command.radio.attrs.type
& command.radio.attrs.radiogroup #REVISIT taking liberties here
& command.radio.attrs.checked?
)
& common-command.attrs
)
command.radio.attrs.type =
attribute type {
w:string "radio"
}
command.radio.attrs.radiogroup =
attribute radiogroup {
string #REVISIT need special format here?
}
command.radio.attrs.checked =
attribute checked {
w:string "checked" | w:string ""
}
command.elem |= command.radio.elem
## State or option that can be toggled: <command type='checkbox'>
command.checkbox.elem =
element command { command.inner & command.checkbox.attrs }
command.checkbox.attrs =
( common.attrs
& ( command.checkbox.attrs.type
& command.checkbox.attrs.checked?
)
& common-command.attrs
)
command.checkbox.attrs.type =
attribute type {
w:string "checkbox"
}
command.checkbox.attrs.checked =
attribute checked {
w:string "checked" | w:string ""
}
command.elem |= command.checkbox.elem
common-command.attrs =
( command.attrs.label?
& command.attrs.icon?
& command.attrs.disabled?
)
command.attrs.label =
attribute label {
string
}
command.attrs.icon =
attribute icon {
common.data.uri.non-empty
}
command.attrs.disabled =
attribute disabled {
w:string "disabled" | w:string ""
}
command.inner =
( empty )
common.elem.metadata |=
( command.elem & nonHTMLizable )
common.elem.phrasing |= command.elem
## Menu: <menu>
menu.elem =
element menu { menu.inner & menu.attrs }
menu.attrs =
( common.attrs
& menu.attrs.type?
& menu.attrs.label?
)
menu.attrs.type =
attribute type {
w:string "toolbar" | w:string "context"
}
menu.attrs.label =
attribute label {
string
}
menu.inner =
( mli.elem*
| common.inner.flow
)
common.elem.flow |= menu.elem
# REVISIT allow nested menus
## Menu Item: <li>
mli.elem =
element li { mli.inner & mli.attrs }
mli.attrs =
( common.attrs )
mli.inner =
( common.inner.flow )
## Canvas for Dynamic Graphics: <canvas>
canvas.elem.flow =
element canvas { canvas.inner.flow & canvas.attrs }
canvas.elem.phrasing =
element canvas { canvas.inner.phrasing & canvas.attrs }
canvas.attrs =
( common.attrs
& canvas.attrs.height?
& canvas.attrs.width?
& common.attrs.aria?
)
canvas.attrs.height =
attribute height {
common.data.integer.non-negative
}
canvas.attrs.width =
attribute width {
common.data.integer.non-negative
}
canvas.inner.flow =
( common.inner.flow )
canvas.inner.phrasing =
( common.inner.phrasing )
common.elem.flow |= canvas.elem.flow
common.elem.phrasing |= canvas.elem.phrasing
## Additional On-Demand Information: <details>
details.elem =
element details { details.inner & details.attrs }
details.attrs =
( common.attrs
& details.attrs.open?
& common.attrs.aria.implicit.region?
)
details.attrs.open =
attribute open {
w:string "open" | w:string ""
}
details.inner =
( summary.elem?
, common.inner.flow
)
common.elem.flow |= details.elem
## Caption/summary for details element: <summary>
summary.elem =
element summary { summary.inner & summary.attrs }
summary.attrs =
( common.attrs )
summary.inner =
( common.inner.phrasing )
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,201 @@
datatypes w = "http://whattf.org/datatype-draft"
# #####################################################################
## RELAX NG Schema for HTML 5: Basic Prose Markup #
# #####################################################################
# #####################################################################
## Paragraph-Level
## Paragraph: <p>
p.elem =
element p { p.inner & p.attrs }
p.attrs =
( common.attrs
& common.attrs.aria?
)
p.inner =
( common.inner.phrasing ) # REVISIT lists in span?
common.elem.flow |= p.elem
## Hint Transition: <hr>
hr.elem =
element hr { hr.inner & hr.attrs }
hr.attrs =
( common.attrs )
hr.inner =
( empty )
common.elem.flow |= hr.elem
# #####################################################################
## Preformatting Blocks
## Preformatted Text: <pre>
pre.elem =
element pre { pre.inner & pre.attrs }
pre.attrs =
( common.attrs
& common.attrs.aria?
)
pre.inner =
( common.inner.phrasing )
common.elem.flow |= pre.elem
# #####################################################################
## Simple Lists
## Unordered List: <ul>
ul.elem =
element ul { ul.inner & ul.attrs }
ul.attrs =
( common.attrs
& ( common.attrs.aria
| common.attrs.aria.implicit.region
)?
)
ul.inner =
( li.elem* )
common.elem.flow |= ul.elem
## Unordered List Item: <li>
li.elem =
element li { li.inner & li.attrs }
li.attrs =
( common.attrs
& ( common.attrs.aria
| common.attrs.aria.implicit.listitem
)?
)
li.inner =
( common.inner.flow )
## Ordered List: <ol>
ol.elem =
element ol { ol.inner & ol.attrs }
ol.attrs =
( common.attrs
& ol.attrs.start?
& ol.attrs.reversed?
& ol.attrs.type?
& ( common.attrs.aria
| common.attrs.aria.implicit.region
)?
)
ol.attrs.start =
attribute start {
common.data.integer
}
ol.attrs.reversed =
attribute reversed {
w:string "reversed" | w:string ""
}
ol.attrs.type =
attribute type {
w:string "1" | w:string "a" | w:string "A" | w:string "i" | w:string "I"
}
ol.inner =
( oli.elem* )
common.elem.flow |= ol.elem
## Ordered List Item: <li>
oli.elem =
element li { oli.inner & oli.attrs }
oli.attrs =
( common.attrs
& oli.attrs.value?
& ( common.attrs.aria
| common.attrs.aria.implicit.listitem
)?
)
oli.attrs.value =
attribute value {
common.data.integer
}
oli.inner =
( common.inner.flow )
# #####################################################################
## Definition Lists
## Definition List: <dl>
dl.elem =
element dl { dl.inner & dl.attrs }
dl.attrs =
( common.attrs
& common.attrs.aria?
)
dl.inner =
( ( dt.elem+
, dd.elem+
)*
)
common.elem.flow |= dl.elem
## Definition Term: <dt>
dt.elem =
element dt { dt.inner & dt.attrs }
dt.attrs =
( common.attrs
& common.attrs.aria?
)
dt.inner =
( common.inner.phrasing )
## Definition Description: <dd>
dd.elem =
element dd { dd.inner & dd.attrs }
dd.elem.phrasing =
element dd { dd.inner.phrasing & dd.attrs }
dd.attrs =
( common.attrs
& common.attrs.aria?
)
dd.inner =
( common.inner.flow )
dd.inner.phrasing =
( common.inner.phrasing )
# #####################################################################
## Miscellaneous Elements
## Generic Container: <div>
div.elem =
element div { div.inner & div.attrs }
div.attrs =
( common.attrs
& common.attrs.aria?
)
div.inner =
( style.elem.scoped*
, common.inner.flow
)
common.elem.flow |= div.elem
## Title or Explanatory Caption: <legend>
legend.elem =
element legend { legend.inner & legend.attrs }
legend.attrs =
( common.attrs
& common.attrs.aria.implicit.region?
)
legend.inner =
( common.inner.phrasing )
@@ -0,0 +1,420 @@
datatypes w = "http://whattf.org/datatype-draft"
# #####################################################################
## RELAX NG Schema for HTML 5: Common Definitions #
# #####################################################################
# #####################################################################
## Language Parameters - redefine in inclusion block as necessary #
# #####################################################################
## HTML vs. XHTML restrictions
XMLonly = empty
HTMLonly = notAllowed
## HTML 4 Compatibility - set to notAllowed to disallow markup introduced in HTML 5
# (This only affects mixed-version modules; wholly HTML5
# modules should simply be left out of the inclusion list.)
v5only = empty
## HTML Compatibility Switches - set to notAllowed to disallow
## XML features that can't be roundtripped HTML <-> XHTML
# (xml:base on elements other than <html>)
nonRoundtrippable = empty
## XML features that can't be serialized as HTML
nonHTMLizable = empty
# #####################################################################
## Wildcards #
# #####################################################################
## Any attribute from any namespace
common.attr.anything =
attribute * { text }*
## Any element from any namespace
common.elem.anything =
element * { common.inner.anything & common.attr.anything }
## Any content from any namespace
common.inner.anything =
( text
& common.elem.anything*
)
# #####################################################################
## Common Element Classes #
# #####################################################################
## Metadata Elements
common.elem.metadata =
( notAllowed )
## Phrase Elements
common.elem.phrasing =
( notAllowed )
## Prose Elements
common.elem.flow =
( common.elem.phrasing )
# #####################################################################
## Common Content Models #
# #####################################################################
## Metadata Content
common.inner.metadata =
( common.elem.metadata* )
## Phrase Content
common.inner.phrasing =
( text & common.elem.phrasing* )
## Prose Content
common.inner.flow =
( text & common.elem.flow* ) # REVISIT <style scoped>
# #####################################################################
## Common Attributes #
# #####################################################################
# When updating, check <bdo> definition too
common.attrs =
( common.attrs.basic
& common.attrs.i18n
& common.attrs.present
& common.attrs.other
)
common.attrs.basic =
( ( common.attrs.id
| common.attrs.xml-id
)? # REVISIT assuming only either one is allowed
& common.attrs.class?
& common.attrs.title?
& common.attrs.base?
& common.attrs.space?
& common.attrs.role?
)
common.attrs.id =
attribute id {
common.data.id
}
common.attrs.xml-id =
attribute xml:id {
xsd:NCName
} & XMLonly
common.attrs.class =
attribute class {
common.data.tokens
}
common.attrs.title =
attribute title {
text
}
common.attrs.role =
attribute role {
text
}
common.attrs.base =
common.attrs.xmlbase
& nonRoundtrippable
common.attrs.xmlbase =
attribute xml:base {
common.data.uri
} & XMLonly
common.attrs.space =
common.attrs.xmlspace
common.attrs.xmlspace =
attribute xml:space {
string "preserve" | string "default"
} & XMLonly
common.attrs.i18n =
( common.attrs.dir?
& common.attrs.language?
)
common.attrs.dir =
attribute dir {
w:string "ltr" | w:string "rtl" | w:string "auto"
}
# This lang definition is a hack for enviroments where
# the HTML5 parser maps lang to xml:lang.
# Sameness check left to Schematron
common.attrs.language =
( common.attrs.xmllang?
& common.attrs.lang?
)
common.attrs.lang =
attribute lang {
common.data.langcode
} & XMLonly
common.attrs.xmllang =
attribute xml:lang {
common.data.langcode
}
# common.attrs.language =
# ( common.attrs.lang
# | common.attrs.xmllang
# )
# common.attrs.lang =
# attribute lang {
# common.data.langcode
# } & HTMLonly
# common.attrs.xmllang =
# attribute xml:lang {
# common.data.langcode
# } & XMLonly
common.attrs.present =
( common.attrs.style?
& common.attrs.tabindex?
& common.attrs.accesskey?
)
common.attrs.style =
attribute style {
string
}
common.attrs.tabindex =
attribute tabindex {
common.data.integer
}
# REVISIT move style to a module and bundle tabindex with ARIA
common.attrs.accesskey =
attribute accesskey {
common.data.keylabellist
}
common.attrs.other =
empty
# #####################################################################
## Common Datatypes #
# #####################################################################
## Names and Tokens
common.data.tokens =
list { token* }
common.data.browsing-context =
w:browsing-context
common.data.browsing-context-or-keyword =
w:browsing-context-or-keyword
# xsd:string {
# pattern = "()|([^_].*)|(_[bB][lL][aA][nN][kK])|(_[sS][eE][lL][fF])|(_[pP][aA][rR][eE][nN][tT])|(_[tT][oO][pP])"
# }
## IDs and IDREFs
common.data.id =
w:ID
# xsd:string {
# pattern = "\S+"
# }
common.data.idref =
w:IDREF
common.data.idrefs =
w:IDREFS
common.data.name =
w:ID #FIXME
common.data.hash-name =
w:hash-name
# xsd:string {
# pattern = "#.+"
# }
## Numerical
common.data.integer =
w:integer
# xsd:string {
# pattern = "-?[0-9]+"
# }
common.data.integer.positive =
w:integer-positive
# xsd:string {
# pattern = "0*[1-9][0-9]*"
# }
common.data.integer.non-negative =
w:integer-non-negative
# xsd:string {
# pattern = "[0-9]+"
# }
# common.data.percent =
# xsd:string {
# pattern = "(100)|([1-9]?[0-9](\.[0-9]+)?)%"
# }
common.data.float =
w:float
# xsd:string {
# pattern = "-?[0-9]+(\.[0-9]+)?([eE]-?[0-9]+)?"
# }
common.data.float.positive =
w:float-positive
# xsd:string {
# pattern = "(0*[1-9][0-9]*(\.[0-9]+)?)|([0-9]+(\.0*[1-9][0-9]*)?)([eE]-?[0-9]+)?"
# }
common.data.float.non-negative =
w:float-non-negative
# xsd:string {
# pattern = "[0-9]+(\.[0-9]+)?([eE]-?[0-9]+)?"
# }
## Temporal
common.data.datetime =
w:datetime-tz
common.data.date-or-time =
w:date-or-time
common.data.date =
w:date
## IRIs
common.data.uri =
# allow either a non-empty IRI ref or zero or more HTML
# space characters (which are: space, tab, LF, FF, CR)
( w:iri-ref
| xsd:string {
pattern = "[ \x{0A}-\x{0D}]*"
# NOTE The range above incorrectly allows U+000B
# in addition to the HTML space characters; but
# that's not a problem in practice because HTML
# and XML parsers will both catch any U+000B
# and report an error for it before that pattern
# ever gets evaluated.
}
)
common.data.uri.non-empty =
w:iri-ref
common.data.uris =
list { w:iri-ref* }
common.data.uri.absolute =
w:iri
## <link type='icon'> sizes
common.data.sizes =
# list { w:sizes }
list {
xsd:string {
pattern = "[1-9][0-9]*x[1-9][0-9]*"
}+
}
## MIME types
common.data.mimetype =
w:mime-type
## Encodings
common.data.charset =
w:charset
common.data.meta-charset =
w:meta-charset
## Refresh
common.data.refresh =
w:refresh
## Default style
common.data.default-style =
string
# w:default-style
## Media Queries
common.data.mediaquery =
w:media-query
## Language Codes
common.data.langcode =
w:string "" | w:language
## List of Key Labels
common.data.keylabellist =
w:keylabellist
## Microdata Properties
common.data.microdata-properties =
list { w:microdata-property+ }
## Zero
common.data.zero =
w:zero
## ECMAScript FunctionBody
common.data.functionbody =
w:functionbody
# #####################################################################
## WF2 Module Hook #
# #####################################################################
common-form.attrs.form = ( notAllowed )
# #####################################################################
## ARIA Module Hooks #
# #####################################################################
common.attrs.aria = ( notAllowed )
common.attrs.aria.implicit.button = ( notAllowed )
common.attrs.aria.implicit.input = ( notAllowed )
common.attrs.aria.implicit.region = ( notAllowed )
common.attrs.aria.implicit.group = ( notAllowed )
common.attrs.aria.implicit.th = ( notAllowed )
common.attrs.aria.implicit.structure = ( notAllowed )
common.attrs.aria.implicit.link = ( notAllowed )
common.attrs.aria.implicit.listitem = ( notAllowed )
common.attrs.aria.implicit.img = ( notAllowed )
common.attrs.aria.implicit.select = ( notAllowed )
common.attrs.aria.landmark.application = ( notAllowed )
common.attrs.aria.landmark.banner = ( notAllowed )
common.attrs.aria.landmark.complementary = ( notAllowed )
common.attrs.aria.landmark.contentinfo = ( notAllowed )
common.attrs.aria.landmark.main = ( notAllowed )
common.attrs.aria.landmark.navigation = ( notAllowed )
common.attrs.aria.landmark.search = ( notAllowed )
# per ARIA spec: article, document, and note are not actually landmarks
common.attrs.aria.landmark.article = ( notAllowed )
common.attrs.aria.landmark.document = ( notAllowed )
common.attrs.aria.landmark.note = ( notAllowed )
@@ -0,0 +1,332 @@
datatypes w = "http://whattf.org/datatype-draft"
# #####################################################################
## RELAX NG Schema for HTML 5: Core Scripting #
# #####################################################################
# #####################################################################
## Scripting Elements
## Inline Scripts: <script>
script.elem.embedded =
element script { script.inner.embedded & script.attrs.embedded }
script.attrs.embedded =
( common.attrs
& script.attrs.type?
& script.attrs.language? # restricted in Schematron
)
script.elem.imported =
element script { script.inner.imported & script.attrs.imported }
script.attrs.imported =
( common.attrs
& script.attrs.src?
& script.attrs.defer?
& script.attrs.async?
& script.attrs.type?
& script.attrs.charset?
& script.attrs.language? # restricted in Schematron
)
script.attrs.src =
attribute src {
common.data.uri.non-empty
}
script.attrs.defer =
attribute defer {
w:string "defer" | w:string ""
}
script.attrs.async =
attribute async {
w:string "async" | w:string ""
} & v5only
script.attrs.type =
attribute type {
common.data.mimetype # XXX without charset parameter!
}
script.attrs.charset =
attribute charset {
common.data.charset
}
script.attrs.language =
attribute language {
string
}
script.inner.embedded =
( common.inner.anything )
script.inner.imported =
( common.inner.anything )
script.elem =
( script.elem.embedded
| script.elem.imported
)
common.elem.metadata |= script.elem
common.elem.phrasing |= script.elem
## Fallback Unscripted Content: <noscript>
noscript.elem.head =
element noscript { noscript.inner.head & noscript.attrs }
& HTMLonly
noscript.inner.head =
( link.elem
| meta.http-equiv.default-style.elem
| meta.http-equiv.refresh.elem
| style.elem
)*
noscript.elem.phrasing =
element noscript { noscript.inner.phrasing & noscript.attrs }
& HTMLonly
noscript.inner.phrasing =
( common.inner.phrasing )
noscript.elem.flow =
element noscript { noscript.inner.flow & noscript.attrs }
& HTMLonly
noscript.inner.flow =
( common.inner.flow )
noscript.attrs =
( common.attrs )
common.elem.metadata |= noscript.elem.head
common.elem.phrasing |= noscript.elem.phrasing
common.elem.flow |= noscript.elem.flow
# #####################################################################
## Event Handler Attribute Definitions
common.attrs.scripting &=
( scripting.attr.onabort?
& scripting.attr.onblur?
& scripting.attr.oncanplay?
& scripting.attr.oncanplaythrough?
& scripting.attr.onchange?
& scripting.attr.onclick?
& scripting.attr.oncontextmenu?
& scripting.attr.ondblclick?
& scripting.attr.ondrag?
& scripting.attr.ondragend?
& scripting.attr.ondragenter?
& scripting.attr.ondragleave?
& scripting.attr.ondragover?
& scripting.attr.ondragstart?
& scripting.attr.ondrop?
& scripting.attr.ondurationchange?
& scripting.attr.onemptied?
& scripting.attr.onended?
& scripting.attr.onerror?
& scripting.attr.onfocus?
& scripting.attr.oninput?
& scripting.attr.oninvalid?
& scripting.attr.onkeydown?
& scripting.attr.onkeypress?
& scripting.attr.onkeyup?
& scripting.attr.onload?
& scripting.attr.onloadeddata?
& scripting.attr.onloadedmetadata?
& scripting.attr.onloadstart?
& scripting.attr.onmousedown?
& scripting.attr.onmousemove?
& scripting.attr.onmouseout?
& scripting.attr.onmouseover?
& scripting.attr.onmouseup?
& scripting.attr.onmousewheel?
& scripting.attr.onpause?
& scripting.attr.onplay?
& scripting.attr.onplaying?
& scripting.attr.onprogress?
& scripting.attr.onratechange?
& scripting.attr.onreadystatechange?
& scripting.attr.onreset?
& scripting.attr.onscroll?
& scripting.attr.onseeked?
& scripting.attr.onseeking?
& scripting.attr.onselect?
& scripting.attr.onshow?
& scripting.attr.onstalled?
& scripting.attr.onsubmit?
& scripting.attr.onsuspend?
& scripting.attr.ontimeupdate?
& scripting.attr.onvolumechange?
& scripting.attr.onwaiting?
)
common.attrs.other &= common.attrs.scripting
scripting.attr.onabort =
attribute onabort { common.data.functionbody }
scripting.attr.onblur =
attribute onblur { common.data.functionbody }
scripting.attr.oncanplay =
attribute oncanplay { common.data.functionbody }
scripting.attr.oncanplaythrough =
attribute oncanplaythrough { common.data.functionbody }
scripting.attr.onchange =
attribute onchange { common.data.functionbody }
scripting.attr.onclick =
attribute onclick { common.data.functionbody }
scripting.attr.oncontextmenu =
attribute oncontextmenu { common.data.functionbody }
scripting.attr.ondblclick =
attribute ondblclick { common.data.functionbody }
scripting.attr.ondrag =
attribute ondrag { common.data.functionbody }
scripting.attr.ondragend =
attribute ondragend { common.data.functionbody }
scripting.attr.ondragenter =
attribute ondragenter { common.data.functionbody }
scripting.attr.ondragleave =
attribute ondragleave { common.data.functionbody }
scripting.attr.ondragover =
attribute ondragover { common.data.functionbody }
scripting.attr.ondragstart =
attribute ondragstart { common.data.functionbody }
scripting.attr.ondrop =
attribute ondrop { common.data.functionbody }
scripting.attr.ondurationchange =
attribute ondurationchange { common.data.functionbody }
scripting.attr.onemptied =
attribute onemptied { common.data.functionbody }
scripting.attr.onended =
attribute onended { common.data.functionbody }
scripting.attr.onerror =
attribute onerror { common.data.functionbody }
scripting.attr.onfocus =
attribute onfocus { common.data.functionbody }
scripting.attr.onformchange =
attribute onformchange { common.data.functionbody }
scripting.attr.onforminput =
attribute onforminput { common.data.functionbody }
scripting.attr.oninput =
attribute oninput { common.data.functionbody }
scripting.attr.oninvalid =
attribute oninvalid { common.data.functionbody }
scripting.attr.onkeydown =
attribute onkeydown { common.data.functionbody }
scripting.attr.onkeypress =
attribute onkeypress { common.data.functionbody }
scripting.attr.onkeyup =
attribute onkeyup { common.data.functionbody }
scripting.attr.onload =
attribute onload { common.data.functionbody }
scripting.attr.onloadeddata =
attribute onloadeddata { common.data.functionbody }
scripting.attr.onloadedmetadata =
attribute onloadedmetadata { common.data.functionbody }
scripting.attr.onloadstart =
attribute onloadstart { common.data.functionbody }
scripting.attr.onmousedown =
attribute onmousedown { common.data.functionbody }
scripting.attr.onmousemove =
attribute onmousemove { common.data.functionbody }
scripting.attr.onmouseout =
attribute onmouseout { common.data.functionbody }
scripting.attr.onmouseover =
attribute onmouseover { common.data.functionbody }
scripting.attr.onmouseup =
attribute onmouseup { common.data.functionbody }
scripting.attr.onmousewheel =
attribute onmousewheel { common.data.functionbody }
scripting.attr.onpause =
attribute onpause { common.data.functionbody }
scripting.attr.onplay =
attribute onplay { common.data.functionbody }
scripting.attr.onplaying =
attribute onplaying { common.data.functionbody }
scripting.attr.onprogress =
attribute onprogress { common.data.functionbody }
scripting.attr.onratechange =
attribute onratechange { common.data.functionbody }
scripting.attr.onreadystatechange =
attribute onreadystatechange { common.data.functionbody }
scripting.attr.onreset =
attribute onreset { common.data.functionbody }
scripting.attr.onscroll =
attribute onscroll { common.data.functionbody }
scripting.attr.onseeked =
attribute onseeked { common.data.functionbody }
scripting.attr.onseeking =
attribute onseeking { common.data.functionbody }
scripting.attr.onselect =
attribute onselect { common.data.functionbody }
scripting.attr.onshow =
attribute onshow { common.data.functionbody }
scripting.attr.onstalled =
attribute onstalled { common.data.functionbody }
scripting.attr.onsubmit =
attribute onsubmit { common.data.functionbody }
scripting.attr.onsuspend =
attribute onsuspend { common.data.functionbody }
scripting.attr.ontimeupdate =
attribute ontimeupdate { common.data.functionbody }
scripting.attr.onvolumechange =
attribute onvolumechange { common.data.functionbody }
scripting.attr.onwaiting =
attribute onwaiting { common.data.functionbody }
# scripting.attr.common =
# ( scripting.attr.mouse
# & scripting.attr.keyboard
# & scripting.attr.focus
# )
#
# scripting.attr.mouse =
# ( scripting.attr.mouse.click?
# & scripting.attr.mouse.dblclick?
# & scripting.attr.mouse.down?
# & scripting.attr.mouse.up?
# & scripting.attr.mouse.over?
# & scripting.attr.mouse.move?
# & scripting.attr.mouse.out?
# )
# scripting.attr.mouse.click =
# attribute onclick { string }
# scripting.attr.mouse.dblclick =
# attribute ondblclick { string }
# scripting.attr.mouse.down =
# attribute onmousedown { string }
# scripting.attr.mouse.up =
# attribute onmouseup { string }
# scripting.attr.mouse.over =
# attribute onmouseover { string }
# scripting.attr.mouse.move =
# attribute onmousemove { string }
# scripting.attr.mouse.out =
# attribute onmouseout { string }
#
# scripting.attr.keyboard =
# ( scripting.attr.keyboard.press?
# & scripting.attr.keyboard.down?
# & scripting.attr.keyboard.up?
# )
# scripting.attr.keyboard.press =
# attribute onkeypress { string }
# scripting.attr.keyboard.down =
# attribute onkeydown { string }
# scripting.attr.keyboard.up =
# attribute onkeyup { string }
#
#
# scripting.attr.focus =
# ( scripting.attr.focus.gain?
# & scripting.attr.focus.lose?
# )
# scripting.attr.focus.gain =
# attribute onfocus { string }
# scripting.attr.focus.lose =
# attribute onblur { string }
#
# scripting.attr.loading =
# ( scripting.attr.loading.load?
# & scripting.attr.loading.unload?
# )
# scripting.attr.loading.load =
# attribute onload { string }
# scripting.attr.loading.unload =
# attribute onunload { string }
# #####################################################################
# Event Handler Attribute Assignments
# body.attrs &= scripting.attr.loading
@@ -0,0 +1,84 @@
datatypes w = "http://whattf.org/datatype-draft"
# #####################################################################
## RELAX NG Schema for HTML 5: Static Data Markup #
# #####################################################################
## Time: <time>
time.elem =
element time { time.inner & time.attrs }
time.attrs =
( common.attrs
& ( time.attrs.datetime?
|
(
( time.attrs.datetime.dateonly?
| time.attrs.datetime.tz?
)
& time.attrs.pubdate
)
)
)
time.attrs.datetime =
attribute datetime {
common.data.date-or-time #REVISIT check format
}
time.attrs.datetime.dateonly =
attribute datetime {
common.data.date
}
time.attrs.datetime.tz =
attribute datetime {
common.data.datetime
}
time.attrs.pubdate =
attribute pubdate {
w:string "pubdate" | w:string ""
}
time.inner =
( common.inner.phrasing ) #Cannot enforce textContent format here
common.elem.phrasing |= time.elem
## Scalar Gauge: <meter>
meter.elem =
element meter { meter.inner & meter.attrs }
meter.attrs =
( common.attrs
& meter.attrs.value
& meter.attrs.min?
& meter.attrs.low?
& meter.attrs.high?
& meter.attrs.max?
& meter.attrs.optimum?
)
meter.attrs.value =
attribute value {
common.data.float
}
meter.attrs.min =
attribute min {
common.data.float
}
meter.attrs.low =
attribute low {
common.data.float
}
meter.attrs.high =
attribute high {
common.data.float
}
meter.attrs.max =
attribute max {
common.data.float
}
meter.attrs.optimum =
attribute optimum {
common.data.float
}
meter.inner =
( common.inner.phrasing ) #Cannot enforce textContent format here
common.elem.phrasing |= meter.elem
@@ -0,0 +1,570 @@
datatypes w = "http://whattf.org/datatype-draft"
namespace local = ""
# #####################################################################
## RELAX NG Schema for HTML 5: Embedded Content #
# #####################################################################
#######################################################################
## Replaced Content
## Images: <img>
img.elem =
element img { img.inner & img.attrs }
img.attrs =
( common.attrs
& img.attrs.src
& img.attrs.alt?
& img.attrs.height?
& img.attrs.width?
& img.attrs.usemap?
& img.attrs.ismap?
& img.attrs.border? # obsolete
& common.attrs.aria?
)
img.attrs.src =
attribute src {
common.data.uri.non-empty
}
img.attrs.alt =
attribute alt {
text
}
img.attrs.height =
attribute height {
common.data.integer.non-negative
}
img.attrs.width =
attribute width {
common.data.integer.non-negative
}
img.attrs.usemap =
attribute usemap {
common.data.hash-name
}
img.attrs.ismap =
attribute ismap {
w:string "ismap" | w:string ""
}
img.attrs.border =
attribute border {
common.data.zero
}
img.inner =
empty
common.elem.phrasing |= img.elem
## Plug-ins: <embed>
embed.elem =
element embed { embed.inner & embed.attrs }
embed.attrs =
( common.attrs
& embed.attrs.src?
& embed.attrs.type?
& embed.attrs.height?
& embed.attrs.width?
& embed.attrs.other*
)
embed.attrs.src =
attribute src {
common.data.uri.non-empty
}
embed.attrs.type =
attribute type {
common.data.mimetype
}
embed.attrs.height =
attribute height {
common.data.integer.non-negative
}
embed.attrs.width =
attribute width {
common.data.integer.non-negative
}
embed.attrs.other = # REVISIT common.attrs
attribute local:* - ( src
| type
| height
| width
| id
| class
| title
| dir
| lang
| style
| tabindex
| contextmenu
| contenteditable
| draggable
| dropzone
| hidden
| onabort
| onblur
| oncanplay
| oncanplaythrough
| onchange
| onclick
| oncontextmenu
| ondblclick
| ondrag
| ondragend
| ondragenter
| ondragleave
| ondragover
| ondragstart
| ondrop
| ondurationchange
| onemptied
| onended
| onerror
| onfocus
| oninput
| oninvalid
| onkeydown
| onkeypress
| onkeyup
| onload
| onloadeddata
| onloadedmetadata
| onloadstart
| onmousedown
| onmousemove
| onmouseout
| onmouseover
| onmouseup
| onmousewheel
| onpause
| onplay
| onplaying
| onprogress
| onratechange
| onreadystatechange
| onreset
| onscroll
| onseeked
| onseeking
| onselect
| onshow
| onstalled
| onsubmit
| onsuspend
| ontimeupdate
| onvolumechange
| onwaiting
| onafterprint
| onbeforeprint
| onbeforeunload
| onhashchange
| onmessage
| onoffline
| ononline
| onpopstate
| onredo
| onresize
| onstorage
| onundo
| onunload
| role
| aria-atomic
| aria-busy
| aria-controls
| aria-describedby
| aria-disabled
| aria-dropeffect
| aria-flowto
| aria-grabbed
| aria-haspopup
| aria-hidden
| aria-invalid
| aria-label
| aria-labelledby
| aria-live
| aria-owns
| aria-relevant
| aria-required
| spellcheck
| accesskey
| itemref
| itemprop
| itemscope
| itemtype
| itemid
| name
| align
)
{
string
}
embed.inner =
empty
common.elem.phrasing |= embed.elem
## Generic Objects: <object>
object.elem.flow =
element object { object.inner.flow & object.attrs }
object.elem.phrasing =
element object { object.inner.phrasing & object.attrs }
object.attrs =
( common.attrs
& ( ( object.attrs.data
& object.attrs.type?
)
| object.attrs.type
)
# & object.attrs.classid?
# & object.attrs.codebase?
# & object.attrs.codetype?
& object.attrs.height?
& object.attrs.width?
& object.attrs.usemap?
& object.attrs.name?
& common-form.attrs.form?
& common.attrs.aria?
)
object.attrs.data =
attribute data {
common.data.uri.non-empty
}
object.attrs.type =
attribute type {
common.data.mimetype
}
object.attrs.height =
attribute height {
common.data.integer.non-negative
}
object.attrs.width =
attribute width {
common.data.integer.non-negative
}
object.attrs.usemap =
attribute usemap {
common.data.hash-name
}
object.attrs.name =
attribute name {
common.data.browsing-context
}
object.inner.flow =
( param.elem*
, common.inner.flow
)
object.inner.phrasing =
( param.elem*
, common.inner.phrasing
)
common.elem.flow |= object.elem.flow
common.elem.phrasing |= object.elem.phrasing
## Initialization Parameters: <param>
param.elem =
element param { param.inner & param.attrs }
param.attrs =
( common.attrs
& param.attrs.name
& param.attrs.value
)
param.attrs.name =
attribute name {
string
}
param.attrs.value =
attribute value {
string
}
param.inner =
( empty )
## Inline Frame: <iframe>
iframe.elem =
element iframe { iframe.inner & iframe.attrs }
iframe.attrs =
( common.attrs
& iframe.attrs.src?
& iframe.attrs.srcdoc?
& iframe.attrs.name?
& iframe.attrs.width?
& iframe.attrs.height?
& iframe.attrs.sandbox?
& iframe.attrs.seamless?
& ( common.attrs.aria
| common.attrs.aria.implicit.region
)?
)
iframe.attrs.src =
attribute src {
common.data.uri.non-empty
}
iframe.attrs.srcdoc =
attribute srcdoc {
string #FIXME
}
iframe.attrs.name =
attribute name {
common.data.browsing-context
}
iframe.attrs.height =
attribute height {
common.data.integer.non-negative
}
iframe.attrs.width =
attribute width {
common.data.integer.non-negative
}
iframe.attrs.seamless =
attribute seamless {
w:string "seamless" | w:string ""
} & v5only
iframe.attrs.sandbox =
attribute sandbox
{ list
{ ( w:string "allow-top-navigation" )?
, ( w:string "allow-same-origin" )?
, ( w:string "allow-forms" )?
, ( w:string "allow-scripts" )?
}
| list
{ ( w:string "allow-top-navigation" )?
, ( w:string "allow-same-origin" )?
, ( w:string "allow-scripts" )?
, ( w:string "allow-forms" )?
}
| list
{ ( w:string "allow-top-navigation" )?
, ( w:string "allow-forms" )?
, ( w:string "allow-same-origin" )?
, ( w:string "allow-scripts" )?
}
| list
{ ( w:string "allow-top-navigation" )?
, ( w:string "allow-forms" )?
, ( w:string "allow-scripts" )?
, ( w:string "allow-same-origin" )?
}
| list
{ ( w:string "allow-top-navigation" )?
, ( w:string "allow-scripts" )?
, ( w:string "allow-same-origin" )?
, ( w:string "allow-forms" )?
}
| list
{ ( w:string "allow-top-navigation" )?
, ( w:string "allow-scripts" )?
, ( w:string "allow-forms" )?
, ( w:string "allow-same-origin" )?
}
| list
{ ( w:string "allow-same-origin" )?
, ( w:string "allow-top-navigation" )?
, ( w:string "allow-forms" )?
, ( w:string "allow-scripts" )?
}
| list
{ ( w:string "allow-same-origin" )?
, ( w:string "allow-top-navigation" )?
, ( w:string "allow-scripts" )?
, ( w:string "allow-forms" )?
}
| list
{ ( w:string "allow-forms" )?
, ( w:string "allow-top-navigation" )?
, ( w:string "allow-same-origin" )?
, ( w:string "allow-scripts" )?
}
| list
{ ( w:string "allow-forms" )?
, ( w:string "allow-top-navigation" )?
, ( w:string "allow-scripts" )?
, ( w:string "allow-same-origin" )?
}
| list
{ ( w:string "allow-scripts" )?
, ( w:string "allow-top-navigation" )?
, ( w:string "allow-same-origin" )?
, ( w:string "allow-forms" )?
}
| list
{ ( w:string "allow-scripts" )?
, ( w:string "allow-top-navigation" )?
, ( w:string "allow-forms" )?
, ( w:string "allow-same-origin" )?
}
| list
{ ( w:string "allow-same-origin" )?
, ( w:string "allow-forms" )?
, ( w:string "allow-top-navigation" )?
, ( w:string "allow-scripts" )?
}
| list
{ ( w:string "allow-same-origin" )?
, ( w:string "allow-scripts" )?
, ( w:string "allow-top-navigation" )?
, ( w:string "allow-forms" )?
}
| list
{ ( w:string "allow-forms" )?
, ( w:string "allow-same-origin" )?
, ( w:string "allow-top-navigation" )?
, ( w:string "allow-scripts" )?
}
| list
{ ( w:string "allow-forms" )?
, ( w:string "allow-scripts" )?
, ( w:string "allow-top-navigation" )?
, ( w:string "allow-same-origin" )?
}
| list
{ ( w:string "allow-scripts" )?
, ( w:string "allow-same-origin" )?
, ( w:string "allow-top-navigation" )?
, ( w:string "allow-forms" )?
}
| list
{ ( w:string "allow-scripts" )?
, ( w:string "allow-forms" )?
, ( w:string "allow-top-navigation" )?
, ( w:string "allow-same-origin" )?
}
| list
{ ( w:string "allow-same-origin" )?
, ( w:string "allow-forms" )?
, ( w:string "allow-scripts" )?
, ( w:string "allow-top-navigation" )?
}
| list
{ ( w:string "allow-same-origin" )?
, ( w:string "allow-scripts" )?
, ( w:string "allow-forms" )?
, ( w:string "allow-top-navigation" )?
}
| list
{ ( w:string "allow-forms" )?
, ( w:string "allow-same-origin" )?
, ( w:string "allow-scripts" )?
, ( w:string "allow-top-navigation" )?
}
| list
{ ( w:string "allow-forms" )?
, ( w:string "allow-scripts" )?
, ( w:string "allow-same-origin" )?
, ( w:string "allow-top-navigation" )?
}
| list
{ ( w:string "allow-scripts" )?
, ( w:string "allow-same-origin" )?
, ( w:string "allow-forms" )?
, ( w:string "allow-top-navigation" )?
}
| list
{ ( w:string "allow-scripts" )?
, ( w:string "allow-forms" )?
, ( w:string "allow-same-origin" )?
, ( w:string "allow-top-navigation" )?
}
} & v5only
iframe.inner =
( text )
common.elem.phrasing |= iframe.elem
#######################################################################
## Image Maps
## Map Definition: <map>
map.elem.flow =
element map { map.inner.flow & map.attrs }
map.elem.phrasing =
element map { map.inner.phrasing & map.attrs }
map.attrs =
( common.attrs
& map.attrs.name
) # REVISIT make id required in Schematron
map.attrs.name =
attribute name {
common.data.name
}
map.inner.flow =
( common.inner.flow )
map.inner.phrasing =
( common.inner.phrasing )
common.elem.flow |= map.elem.flow
common.elem.phrasing |= map.elem.phrasing
## Map Area Definition: <area>
area.elem =
element area { area.inner & area.attrs }
area.attrs =
( common.attrs
& ( area.attrs.alt
& shared-hyperlink.attrs.href
)?
& shared-hyperlink.attrs.target?
& shared-hyperlink.attrs.ping?
& shared-hyperlink.attrs.rel?
& shared-hyperlink.attrs.media?
& shared-hyperlink.attrs.hreflang?
& shared-hyperlink.attrs.type?
& area.attrs.shape?
)
area.attrs.alt =
attribute alt {
text
}
area.attrs.shape =
( ( area.attrs.shape.rect? & area.attrs.coords.rect )
| ( area.attrs.shape.circle & area.attrs.coords.circle )
| ( area.attrs.shape.poly & area.attrs.coords.poly )
| ( area.attrs.shape.default )
)
area.attrs.shape.rect =
attribute shape {
w:string "rect"
}
area.attrs.coords.rect =
attribute coords {
w:rectangle
# xsd:token {
# pattern = "-?[0-9]+,-?[0-9]+,-?[0-9]+,-?[0-9]+"
# }
}
area.attrs.shape.circle =
attribute shape {
w:string "circle"
}
area.attrs.coords.circle =
attribute coords {
w:circle
# xsd:token {
# pattern = "-?[0-9]+,-?[0-9]+,[0-9]+"
# }
}
area.attrs.shape.poly =
attribute shape {
w:string "poly"
}
area.attrs.coords.poly =
attribute coords {
w:polyline
# xsd:token {
# pattern = "-?[0-9]+,-?[0-9]+,-?[0-9]+,-?[0-9]+,-?[0-9]+,-?[0-9]+(,-?[0-9]+,-?[0-9]+)*"
# }
}
area.attrs.shape.default =
attribute shape {
w:string "default"
}
area.inner =
( empty )
common.elem.phrasing |= area.elem
@@ -0,0 +1,63 @@
datatypes w = "http://whattf.org/datatype-draft"
# #####################################################################
## RELAX NG Schema for HTML 5: Datatypes related to forms #
# #####################################################################
## MIME types
form.data.mimetypelist =
w:mime-type-list
form.data.charsetlist =
string # FIXME should be a "a space- and/or comma-delimited
# list of charset values"
## ECMAScript Regular Expression
form.data.pattern =
w:pattern
## Temporal
form.data.datetime-local =
w:datetime-local
form.data.date =
w:date
form.data.month =
w:month
form.data.week =
w:week
form.data.time =
w:time
## Email
form.data.emailaddress =
w:email-address
form.data.emailaddresslist =
w:email-address-list
## Color
form.data.color =
w:simple-color
# xsd:string {
# pattern = "#[a-fA-F0-9]{6}"
# }
## Text without line breaks
form.data.stringwithoutlinebreaks =
w:string-without-line-breaks
## Non-empty string
form.data.nonemptystring =
w:non-empty-string
@@ -0,0 +1,56 @@
default namespace = "http://www.w3.org/1999/html"
# #####################################################################
## RELAX NG Schema for HTML 5 #
# #####################################################################
# To validate an HTML 5 document, you must first validate against #
# this schema and then ALSO validate against assertions.sch #
## HTML flavor RELAX NG schemas can only be used after the #
## document has been transformed to well-formed XML. #
## - Insert closing slashes in all empty element tags #
## - Insert all optional start and end tags #
## - Add xmlns "http://www.w3.org/1999/xhtml" #
## - Properly escape <script> and <style> CDATA #
## - Parse and transform all HTML-only entities to numeric #
## character references #
## Obviously, syntax-checking involving these features cannot be #
## done by the RELAX NG schema and must be checked, along with the #
## <!DOCTYPE> requirement, by some other application. #
# #####################################################################
## Schema Framework & Parameters
include "common.rnc" {
# XHTML flavor #
XMLonly = notAllowed
HTMLonly = empty
# HTML 4 compat #
v5only = empty
# HTML-serializability #
nonHTMLizable = notAllowed
# HTML-roundtrippability #
nonRoundtrippable = notAllowed
}
# #####################################################################
## Language Definitions
start = html.elem
include "meta.rnc"
include "phrase.rnc"
include "block.rnc"
include "sectional.rnc"
include "structural.rnc"
include "revision.rnc"
include "embed.rnc"
include "ruby.rnc"
include "media.rnc"
include "core-scripting.rnc"
include "tables.rnc"
include "form-datatypes.rnc"
include "web-forms.rnc"
include "web-forms2.rnc"
include "applications.rnc"
include "data.rnc"
@@ -0,0 +1,63 @@
default namespace = "http://www.w3.org/1999/xhtml"
# #####################################################################
## RELAX NG Schema for (X)HTML 5: Exclusions #
# #####################################################################
## This file is unmaintained. Please use assertions.sch instead.
# #####################################################################
## Schema Framework & Parameters
start = normal.elem.all-inclusive
# #####################################################################
## Normal Element Patterns
## Any attribute from any namespace
normal.attr.anything =
attribute * { text }*
## Any element from any namespace except exceptional elements,
## but allowing those elements as descendants
normal.elem.all =
element * - (dfn) {
normal.elem.all-inclusive
}
## Any element from any namespace including exceptional elements
normal.elem.all-inclusive =
wildcard.elem.exclude-all | dfn.elem.exclude-self
# #####################################################################
## Exclusion Element Patterns
# exclude all exceptional elements from the name classes;
# list them explicitly in content models instead
normal.elem.exclude-dfn =
element * - (dfn) {
normal.elem.exclude-dfn
}
dfn.elem.exclude-self =
element dfn {
( normal.attr.anything
& normal.elem.exclude-dfn
)
}
# FIXME this part was cut off -- hsivonen
wildcard.elem.exclude-all =
notAllowed
#FIXME no nested forms in HTML-serializable docs
#FIXME no nested labels
#FIXME no blockquote inside header or footer
#FIXME exactly one hn in header
@@ -0,0 +1,205 @@
datatypes w = "http://whattf.org/datatype-draft"
# #####################################################################
## RELAX NG Schema for HTML 5: Advanced Embedded Content #
# #####################################################################
## Attributes Common to Media Elements
# src not included
media.attrs =
( media.attrs.autoplay?
& media.attrs.preload?
& media.attrs.controls?
& media.attrs.loop?
& media.attrs.mediagroup?
& media.attrs.muted?
)
media.attrs.autoplay =
attribute autoplay {
w:string "autoplay" | w:string ""
}
media.attrs.preload =
attribute preload {
w:string "none" | w:string "metadata" | w:string "auto" | w:string ""
}
media.attrs.controls =
attribute controls {
w:string "controls" | w:string ""
}
media.attrs.loop =
attribute loop {
w:string "loop" | w:string ""
}
media.attrs.mediagroup =
attribute mediagroup {
string
}
media.attrs.muted =
attribute muted {
w:string "muted" | w:string ""
}
## Source: <source>
source.elem =
element source { source.inner & source.attrs }
source.attrs =
( common.attrs
& source.attrs.src
& source.attrs.type?
& source.attrs.media?
)
source.attrs.src =
attribute src {
common.data.uri.non-empty
}
source.attrs.type =
attribute type {
common.data.mimetype
}
source.attrs.media =
attribute media {
common.data.mediaquery
}
source.inner =
( empty )
## Media src attribute
media.attrs.src =
attribute src {
common.data.uri.non-empty
}
## Video: <video>
video.elem.flow =
element video { video.inner.flow & video.attrs }
video.elem.phrasing =
element video { video.inner.phrasing & video.attrs }
video.attrs =
( common.attrs
& media.attrs
& video.attrs.poster?
& video.attrs.height?
& video.attrs.width?
)
video.attrs.poster =
attribute poster {
common.data.uri.non-empty
}
video.attrs.height =
attribute height {
common.data.integer.non-negative
}
video.attrs.width =
attribute width {
common.data.integer.non-negative
}
video.inner.flow =
( video.source
, track.elem*
, common.inner.flow
)
video.inner.phrasing =
( video.source
, track.elem*
, common.inner.phrasing
)
video.source =
( media.attrs.src
| source.elem*
)
common.elem.flow |= video.elem.flow
common.elem.phrasing |= video.elem.phrasing
## Audio: <audio>
audio.elem.flow =
element audio { audio.inner.flow & audio.attrs }
audio.elem.phrasing =
element audio { audio.inner.phrasing & audio.attrs }
audio.attrs =
( common.attrs
& media.attrs
)
audio.inner.flow =
( audio.source
, track.elem*
, common.inner.flow
)
audio.inner.phrasing =
( audio.source
, track.elem*
, common.inner.phrasing
)
audio.source =
( media.attrs.src
| source.elem+
)
common.elem.flow |= audio.elem.flow
common.elem.phrasing |= audio.elem.phrasing
## supplementary media track: <track>
#
track.elem =
element track { track.inner & track.attrs }
track.attrs =
( common.attrs
& track.attrs.kind?
& track.attrs.src
& track.attrs.srclang?
& track.attrs.label?
& track.attrs.default?
)
track.attrs.kind =
attribute kind {
w:string "subtitles" | w:string "captions" | w:string "descriptions" | w:string "chapters" | w:string "metadata"
}
track.attrs.src =
attribute src {
common.data.uri.non-empty
}
track.attrs.srclang =
attribute srclang {
common.data.langcode
}
track.attrs.label =
attribute label {
string # must be non-empty value; check is in assertions code
}
track.attrs.default =
attribute default {
w:string "default" | w:string ""
}
track.inner =
( empty )
## Captioned Content: <figure>
figure.elem =
element figure { figure.inner & figure.attrs }
figure.attrs =
( common.attrs
& common.attrs.aria.implicit.img?
)
figure.inner =
( ( figcaption.elem, common.inner.flow )
| ( common.inner.flow, figcaption.elem? )
)
common.elem.flow |= figure.elem
## Figure caption: <figcaption>
figcaption.elem =
element figcaption { figcaption.inner & figcaption.attrs }
figcaption.attrs =
( common.attrs )
figcaption.inner =
( common.inner.flow )
@@ -0,0 +1,323 @@
datatypes w = "http://whattf.org/datatype-draft"
# #####################################################################
## RELAX NG Schema for HTML 5: Global Structure & Metadata #
# #####################################################################
## Root Element: <html>
html.elem =
element html { html.inner & html.attrs }
html.attrs =
( common.attrs )
html.inner =
( head.elem
, body.elem
)
## Metadata Container: <head>
head.elem =
element head { head.inner & head.attrs }
head.attrs =
( common.attrs
# & head.attrs.profile?
)
# head.attrs.profile =
# attribute profile {
# common.data.uris #REVISIT should these be absolute (zero or more)
# }
head.inner =
( title.elem
& base.elem? # REVISIT need a non-schema checker or Schematron
& common.inner.metadata # Limit encoding decl position in Schematron
)
# head.inner =
# ( meta.elem.encoding?
# , ( title.elem
# & base.elem? # REVISIT need a non-schema checker or Schematron
# & common.inner.metadata
# )
# )
## Content Container: <body>
body.elem =
element body { body.inner & body.attrs }
body.attrs =
( common.attrs
& ( common.attrs.aria.landmark.application
| common.attrs.aria.landmark.document
| common.attrs.aria.implicit.structure
)?
& body.attrs.onafterprint?
& body.attrs.onbeforeprint?
& body.attrs.onbeforeunload?
& body.attrs.onhashchange?
& body.attrs.onmessage?
& body.attrs.onoffline?
& body.attrs.ononline?
& body.attrs.onpopstate?
& body.attrs.onredo?
& body.attrs.onresize?
& body.attrs.onstorage?
& body.attrs.onundo?
& body.attrs.onunload?
)
body.inner =
( common.inner.flow )
body.attrs.onafterprint =
attribute onafterprint { common.data.functionbody }
body.attrs.onbeforeprint =
attribute onbeforeprint { common.data.functionbody }
body.attrs.onbeforeunload =
attribute onbeforeunload { common.data.functionbody }
body.attrs.onhashchange =
attribute onhashchange { common.data.functionbody }
body.attrs.onmessage =
attribute onmessage { common.data.functionbody }
body.attrs.onoffline =
attribute onoffline { common.data.functionbody }
body.attrs.ononline =
attribute ononline { common.data.functionbody }
body.attrs.onpopstate =
attribute onpopstate { common.data.functionbody }
body.attrs.onredo =
attribute onredo { common.data.functionbody }
body.attrs.onresize =
attribute onresize { common.data.functionbody }
body.attrs.onstorage =
attribute onstorage { common.data.functionbody }
body.attrs.onundo =
attribute onundo { common.data.functionbody }
body.attrs.onunload =
attribute onunload { common.data.functionbody }
## Document Title: <title>
title.elem =
element title { title.inner & title.attrs }
title.attrs =
( common.attrs )
title.inner =
( text )
## Base URI: <base>
base.elem =
element base { base.inner & base.attrs }
base.attrs =
( common.attrs
& ( ( base.attrs.href
& base.attrs.target?
)
| base.attrs.target
)
)
base.attrs.href =
attribute href {
common.data.uri
}
base.attrs.target =
attribute target {
common.data.browsing-context-or-keyword
}
base.inner =
( empty )
## Global Relationships: <link>
link.elem =
element link { link.inner & link.attrs }
link.attrs =
( common.attrs.basic
& common.attrs.i18n
& common.attrs.present
& common.attrs.other
& common.attrs.microdata.itemref?
& common.attrs.microdata.itemscope?
& common.attrs.microdata.itemtype?
& common.attrs.microdata.itemid?
& link.attrs.href
& ( link.attrs.rel
| common.attrs.microdata.itemprop
)
& shared-hyperlink.attrs.hreflang?
& shared-hyperlink.attrs.media?
& shared-hyperlink.attrs.type?
& link.attrs.sizes?
# link.attrs.title included in common.attrs
)
link.attrs.href =
attribute href {
common.data.uri.non-empty
}
link.attrs.rel =
attribute rel {
w:link-rel
}
link.attrs.sizes =
attribute sizes {
w:string "any" | common.data.sizes
}
link.inner =
( empty )
common.elem.metadata |= link.elem
## Global Style: <style>
style.elem =
element style { style.inner & style.attrs }
style.attrs =
( common.attrs
& style.attrs.type?
& style.attrs.media?
# style.attrs.title included in common.attrs
)
style.attrs.type =
attribute type {
common.data.mimetype
}
style.attrs.media =
attribute media {
common.data.mediaquery
}
style.inner =
( common.inner.anything )
common.elem.metadata |= style.elem
## Scoped Style: <style scoped>
style.elem.scoped =
element style { style.inner & style.scoped.attrs }
style.scoped.attrs =
( common.attrs
& style.attrs.type?
& style.attrs.media?
& style.attrs.scoped
# style.attrs.title included in common.attrs
)
style.attrs.scoped =
attribute scoped {
w:string "scoped" | w:string ""
}
## Name-Value Metadata: <meta name>
meta.name.elem =
element meta { meta.inner & meta.name.attrs }
meta.name.attrs =
( common.attrs.basic
& common.attrs.i18n
& common.attrs.present
& common.attrs.other
& meta.name.attrs.name
& meta.name.attrs.content
)
meta.name.attrs.name =
attribute name {
w:meta-name
}
meta.name.attrs.content =
attribute content {
string
}
meta.inner =
( empty )
common.elem.metadata |= meta.name.elem
## "refresh" pragma directive: <meta http-equiv='refresh'>
meta.http-equiv.refresh.elem =
element meta { meta.inner & meta.http-equiv.refresh.attrs }
meta.http-equiv.refresh.attrs =
( common.attrs.basic
& common.attrs.i18n
& common.attrs.present
& common.attrs.other
& meta.http-equiv.attrs.http-equiv.refresh
& meta.http-equiv.attrs.content.refresh
)
meta.http-equiv.attrs.http-equiv.refresh =
attribute http-equiv {
w:string "refresh"
}
meta.http-equiv.attrs.content.refresh =
attribute content {
common.data.refresh
}
common.elem.metadata |= meta.http-equiv.refresh.elem # not quite right per spec
# if the definition is
# reused in another language
## "default-style" pragma directive: <meta http-equiv='default-style'>
meta.http-equiv.default-style.elem =
element meta { meta.inner & meta.http-equiv.default-style.attrs }
meta.http-equiv.default-style.attrs =
( common.attrs.basic
& common.attrs.i18n
& common.attrs.present
& common.attrs.other
& meta.http-equiv.attrs.http-equiv.default-style
& meta.http-equiv.attrs.content.default-style
)
meta.http-equiv.attrs.http-equiv.default-style =
attribute http-equiv {
w:string "default-style"
}
meta.http-equiv.attrs.content.default-style =
attribute content {
common.data.default-style
}
common.elem.metadata |= meta.http-equiv.default-style.elem # not quite right per spec
# if the definition is
# reused in another language
## Inline Character Encoding Statement for HTML: <meta charset>
meta.charset.elem =
element meta { meta.inner & meta.charset.attrs }
meta.charset.attrs =
( common.attrs.basic
& common.attrs.i18n
& common.attrs.present
& common.attrs.other
& meta.charset.attrs.charset
)
meta.charset.attrs.charset =
attribute charset {
(common.data.charset & HTMLonly)
| (xsd:string {
pattern = "[uU][tT][fF]-8"
} & XMLonly )
}
## Inline Character Encoding Statement for HTML: <meta http-equiv='content-type'>
meta.http-equiv.content-type.elem =
element meta { meta.inner & meta.http-equiv.content-type.attrs }
& HTMLonly
meta.http-equiv.content-type.attrs =
( common.attrs.basic
& common.attrs.i18n
& common.attrs.present
& common.attrs.other
& meta.http-equiv.attrs.http-equiv.content-type
& meta.http-equiv.attrs.content.content-type
)
meta.http-equiv.attrs.http-equiv.content-type =
attribute http-equiv {
w:string "content-type"
}
meta.http-equiv.attrs.content.content-type =
attribute content {
common.data.meta-charset
}
common.elem.metadata |= ( meta.charset.elem | meta.http-equiv.content-type.elem )
@@ -0,0 +1,81 @@
datatypes w = "http://whattf.org/datatype-draft"
# #####################################################################
## RELAX NG Schema for HTML 5: Microdata #
# #####################################################################
common.attrs.microdata =
( common.attrs.microdata.itemref?
& common.attrs.microdata.itemprop?
& common.attrs.microdata.itemscope?
& common.attrs.microdata.itemtype?
& common.attrs.microdata.itemid?
)
common.attrs.microdata.itemref =
attribute itemref {
common.data.idrefs
}
common.attrs.microdata.itemprop =
attribute itemprop {
common.data.microdata-properties
}
common.attrs.microdata.itemscope =
attribute itemscope {
w:string "itemscope" | w:string ""
}
common.attrs.microdata.itemtype =
attribute itemtype {
common.data.uri.absolute
}
common.attrs.microdata.itemid =
attribute itemid {
common.data.uri
}
common.attrs &= common.attrs.microdata
## URL-valued Property Metadata: <link itemprop>
link.elem.phrasing =
element link { link.inner & link.phrasing.attrs }
link.phrasing.attrs =
( common.attrs.basic
& common.attrs.i18n
& common.attrs.present
& common.attrs.other
& common.attrs.microdata.itemprop
& common.attrs.microdata.itemref?
& common.attrs.microdata.itemscope?
& common.attrs.microdata.itemtype?
& common.attrs.microdata.itemid?
& shared-hyperlink.attrs.href
& shared-hyperlink.attrs.hreflang?
& shared-hyperlink.attrs.media?
& shared-hyperlink.attrs.type?
& link.attrs.sizes?
# link.attrs.title included in common.attrs
)
common.elem.phrasing |= link.elem.phrasing
## Property Metadata: <meta itemprop>
meta.itemprop.elem =
element meta { meta.inner & meta.itemprop.attrs }
meta.itemprop.attrs =
( common.attrs.basic
& common.attrs.i18n
& common.attrs.present
& common.attrs.other
& common.attrs.microdata.itemprop
& common.attrs.microdata.itemref?
& common.attrs.microdata.itemscope?
& common.attrs.microdata.itemtype?
& common.attrs.microdata.itemid?
& meta.itemprop.attrs.content
)
meta.itemprop.attrs.content =
attribute content {
string
}
common.elem.metadata |= meta.itemprop.elem
common.elem.phrasing |= meta.itemprop.elem
@@ -0,0 +1,361 @@
datatypes w = "http://whattf.org/datatype-draft"
# #####################################################################
## RELAX NG Schema for HTML 5: Phrase Markup #
# #####################################################################
## Contextual Hyperlink: <a>
a.elem.phrasing =
element a { a.inner.phrasing & a.attrs }
a.elem.flow =
element a { a.inner.flow & a.attrs }
a.attrs =
( common.attrs
& a.attrs.name?
& shared-hyperlink.attrs.href?
& shared-hyperlink.attrs.target?
& shared-hyperlink.attrs.rel?
& shared-hyperlink.attrs.hreflang?
& shared-hyperlink.attrs.media?
& shared-hyperlink.attrs.type?
& shared-hyperlink.attrs.ping?
& ( common.attrs.aria
| common.attrs.aria.implicit.link
)?
)
a.attrs.name =
attribute name {
common.data.id # XXX not what the spec says
}
a.inner.phrasing =
( common.inner.phrasing )
a.inner.flow =
( common.inner.flow )
common.elem.phrasing |= a.elem.phrasing
common.elem.flow |= a.elem.flow
## Shared hyperlink attributes
shared-hyperlink.attrs.href =
attribute href {
common.data.uri
}
shared-hyperlink.attrs.target =
attribute target {
common.data.browsing-context-or-keyword
}
shared-hyperlink.attrs.rel =
attribute rel {
w:a-rel
}
shared-hyperlink.attrs.hreflang =
attribute hreflang {
common.data.langcode
}
shared-hyperlink.attrs.media =
attribute media {
common.data.mediaquery
}
shared-hyperlink.attrs.type =
attribute type {
common.data.mimetype
}
shared-hyperlink.attrs.ping =
attribute ping {
common.data.uris
} & v5only
## Emphatic Stress: <em>
em.elem =
element em { em.inner & em.attrs }
em.attrs =
( common.attrs
& common.attrs.aria?
)
em.inner =
( common.inner.phrasing )
common.elem.phrasing |= em.elem
## Strong Importance: <strong>
strong.elem =
element strong { strong.inner & strong.attrs }
strong.attrs =
( common.attrs
& common.attrs.aria?
)
strong.inner =
( common.inner.phrasing )
common.elem.phrasing |= strong.elem
## Small Print and Side Comments: <small>
small.elem =
element small { small.inner & small.attrs }
small.attrs =
( common.attrs
& common.attrs.aria?
)
small.inner =
( common.inner.phrasing )
common.elem.phrasing |= small.elem
## Marked (Highlighted) Text: <mark>
mark.elem =
element mark { mark.inner & mark.attrs }
& v5only
mark.attrs =
( common.attrs )
mark.inner =
( common.inner.phrasing )
common.elem.phrasing |= mark.elem
## Abbreviation: <abbr>
abbr.elem =
element abbr { abbr.inner & abbr.attrs }
abbr.attrs =
( common.attrs
# abbr.attrs.title included in common.attrs
& common.attrs.aria?
)
abbr.inner =
( common.inner.phrasing )
common.elem.phrasing |= abbr.elem
## Defining Instance: <dfn>
dfn.elem =
element dfn { dfn.inner & dfn.attrs }
dfn.attrs =
( common.attrs
# dfn.attrs.title included in common.attrs
& common.attrs.aria?
)
dfn.inner =
( common.inner.phrasing )
common.elem.phrasing |= dfn.elem
## Italic: <i>
i.elem =
element i { i.inner & i.attrs }
i.attrs =
( common.attrs
& common.attrs.aria?
)
i.inner =
( common.inner.phrasing )
common.elem.phrasing |= i.elem
## Bold: <b>
b.elem =
element b { b.inner & b.attrs }
b.attrs =
( common.attrs
& common.attrs.aria?
)
b.inner =
( common.inner.phrasing )
common.elem.phrasing |= b.elem
## Struck Text: <s>
s.elem =
element s { s.inner & s.attrs }
s.attrs =
( common.attrs
& common.attrs.aria?
)
s.inner =
( common.inner.phrasing )
common.elem.phrasing |= s.elem
## Underline: <u>
u.elem =
element u { u.inner & u.attrs }
u.attrs =
( common.attrs
& common.attrs.aria?
)
u.inner =
( common.inner.phrasing )
common.elem.phrasing |= u.elem
## Code Fragment: <code>
code.elem =
element code { code.inner & code.attrs }
code.attrs =
( common.attrs
& common.attrs.aria?
)
code.inner =
( common.inner.phrasing )
common.elem.phrasing |= code.elem
## Variable or Placeholder: <var>
var.elem =
element var { var.inner & var.attrs }
var.attrs =
( common.attrs
& common.attrs.aria?
)
var.inner =
( common.inner.phrasing )
common.elem.phrasing |= var.elem
## (Sample) Output: <samp>
samp.elem =
element samp { samp.inner & samp.attrs }
samp.attrs =
( common.attrs
& common.attrs.aria?
)
samp.inner =
( common.inner.phrasing )
common.elem.phrasing |= samp.elem
## User Input: <kbd>
kbd.elem =
element kbd { kbd.inner & kbd.attrs }
kbd.attrs =
( common.attrs
& common.attrs.aria?
)
kbd.inner =
( common.inner.phrasing )
common.elem.phrasing |= kbd.elem
## Superscript: <sup>
sup.elem =
element sup { sup.inner & sup.attrs }
sup.attrs =
( common.attrs )
sup.inner =
( common.inner.phrasing )
common.elem.phrasing |= sup.elem
## Subscript: <sub>
sub.elem =
element sub { sub.inner & sub.attrs }
sub.attrs =
( common.attrs )
sub.inner =
( common.inner.phrasing )
common.elem.phrasing |= sub.elem
## Quotation: <q>
q.elem =
element q { q.inner & q.attrs }
q.attrs =
( common.attrs
& q.attrs.cite?
& common.attrs.aria?
)
q.attrs.cite =
attribute cite {
common.data.uri
}
q.inner =
( common.inner.phrasing )
common.elem.phrasing |= q.elem
## Title of Work: <cite>
cite.elem =
element cite { cite.inner & cite.attrs }
cite.attrs =
( common.attrs
& common.attrs.aria?
)
cite.inner =
( common.inner.phrasing )
common.elem.phrasing |= cite.elem
## Generic Span: <span>
span.elem =
element span { span.inner & span.attrs }
span.attrs =
( common.attrs
& common.attrs.aria?
)
span.inner =
( common.inner.phrasing ) # REVISIT allow ol and ul?
common.elem.phrasing |= span.elem
## Bidirectional Override: <bdo>
bdo.elem =
element bdo { bdo.inner & bdo.attrs }
bdo.attrs =
( common.attrs ) # dir required in Schematron
bdo.inner =
( common.inner.phrasing )
common.elem.phrasing |= bdo.elem
## Bidirectional Isolate: <bdi>
bdi.elem =
element bdi { bdi.inner & bdi.attrs }
bdi.attrs =
( common.attrs )
bdi.inner =
( common.inner.phrasing )
common.elem.phrasing |= bdi.elem
## Line Break: <br>
br.elem =
element br { br.inner & br.attrs }
br.attrs =
( common.attrs )
br.inner =
( empty )
common.elem.phrasing |= br.elem
## Line-break opportunity: <wbr>
wbr.elem =
element wbr { wbr.inner & wbr.attrs }
wbr.attrs =
( common.attrs )
wbr.inner =
( empty )
common.elem.phrasing |= wbr.elem
@@ -0,0 +1,52 @@
# #####################################################################
## RELAX NG Schema for HTML 5: Revision Annotations #
# #####################################################################
## Common Attributes
edit.attrs.cite =
attribute cite {
common.data.uri
}
edit.attrs.datetime =
attribute datetime {
common.data.datetime | common.data.date
}
## Inserts: <ins>
ins.elem.flow =
element ins { ins.inner.flow & ins.attrs }
ins.elem.phrasing =
element ins { ins.inner.phrasing & ins.attrs }
ins.attrs =
( common.attrs
& edit.attrs.cite?
& edit.attrs.datetime?
)
ins.inner.flow =
( common.inner.flow )
ins.inner.phrasing =
( common.inner.phrasing )
common.elem.flow |= ins.elem.flow
common.elem.phrasing |= ins.elem.phrasing
## Deletions: <del>
del.elem.flow =
element del { del.inner.flow & del.attrs }
del.elem.phrasing =
element del { del.inner.phrasing & del.attrs }
del.attrs =
( common.attrs
& edit.attrs.cite?
& edit.attrs.datetime?
)
del.inner.flow =
( common.inner.flow )
del.inner.phrasing =
( common.inner.phrasing )
common.elem.flow |= del.elem.flow
common.elem.phrasing |= del.elem.phrasing
@@ -0,0 +1,51 @@
datatypes w = "http://whattf.org/datatype-draft"
namespace local = ""
# #####################################################################
## RELAX NG Schema for HTML 5: Ruby #
# #####################################################################
#######################################################################
## Ruby Annotation: <ruby>
ruby.elem =
element ruby { ruby.inner & ruby.attrs }
ruby.attrs =
( common.attrs
& common.attrs.aria?
)
ruby.inner =
( ( common.inner.phrasing
, ( rt.elem
| ( rp.elem
, rt.elem
, rp.elem
)
)
)+
)
common.elem.phrasing |= ruby.elem
## Ruby Text: <rt>
rt.elem =
element rt { rt.inner & rt.attrs }
rt.attrs =
( common.attrs
& common.attrs.aria?
)
rt.inner =
( common.inner.phrasing )
## Ruby Parenthesis: <rp>
rp.elem =
element rp { rp.inner & rp.attrs }
rp.attrs =
( common.attrs
& common.attrs.aria?
)
rp.inner =
( common.inner.phrasing )
@@ -0,0 +1,140 @@
# #####################################################################
## RELAX NG Schema for HTML 5: Sectioning Markup #
# #####################################################################
# #####################################################################
## Headings
## Heading (Rank 1): <h1>
h1.elem =
element h1 { h1.inner & h1.attrs }
h1.attrs =
( common.attrs
& common.attrs.aria.implicit.structure?
)
h1.inner =
( common.inner.phrasing )
common.elem.flow |= h1.elem
## Heading (Rank 2): <h2>
h2.elem =
element h2 { h2.inner & h2.attrs }
h2.attrs =
( common.attrs
& common.attrs.aria.implicit.structure?
)
h2.inner =
( common.inner.phrasing )
common.elem.flow |= h2.elem
## Heading (Rank 3): <h3>
h3.elem =
element h3 { h3.inner & h3.attrs }
h3.attrs =
( common.attrs
& common.attrs.aria.implicit.structure?
)
h3.inner =
( common.inner.phrasing )
common.elem.flow |= h3.elem
## Heading (Rank 4): <h4>
h4.elem =
element h4 { h4.inner & h4.attrs }
h4.attrs =
( common.attrs
& common.attrs.aria.implicit.structure?
)
h4.inner =
( common.inner.phrasing )
common.elem.flow |= h4.elem
## Heading (Rank 5): <h5>
h5.elem =
element h5 { h5.inner & h5.attrs }
h5.attrs =
( common.attrs
& common.attrs.aria.implicit.structure?
)
h5.inner =
( common.inner.phrasing )
common.elem.flow |= h5.elem
## Heading (Rank 6): <h6>
h6.elem =
element h6 { h6.inner & h6.attrs }
h6.attrs =
( common.attrs
& common.attrs.aria.implicit.structure?
)
h6.inner =
( common.inner.phrasing )
common.elem.flow |= h6.elem
## Heading Group: <hgroup>
hgroup.elem =
element hgroup { hgroup.inner & hgroup.attrs }
hgroup.attrs =
( common.attrs
& common.attrs.aria.implicit.structure?
)
hgroup.inner =
( h1.elem
| h2.elem
| h3.elem
| h4.elem
| h5.elem
| h6.elem
)+
common.elem.flow |= hgroup.elem
# #####################################################################
## Section Meta
## Contact Info: <address>
address.elem =
element address { address.inner & address.attrs }
address.attrs =
( common.attrs
& common.attrs.aria.implicit.region?
)
address.inner =
( common.inner.flow )
common.elem.flow |= address.elem
# #####################################################################
## Quotations
## Block Quotes: <blockquote>
blockquote.elem =
element blockquote { blockquote.inner & blockquote.attrs }
blockquote.attrs =
( common.attrs
& blockquote.attrs.cite?
& common.attrs.aria?
)
blockquote.attrs.cite =
attribute cite {
common.data.uri
}
blockquote.inner =
( common.inner.flow )
common.elem.flow |= blockquote.elem
@@ -0,0 +1,105 @@
# #####################################################################
## RELAX NG Schema for HTML 5: Block Markup Added in HTML5 #
# #####################################################################
## Section: <section>
section.elem =
element section { section.inner & section.attrs }
section.attrs =
( common.attrs
& ( common.attrs.aria
| common.attrs.aria.implicit.region
)?
)
section.inner =
( style.elem.scoped*
, common.inner.flow
)
common.elem.flow |= section.elem
## Navigational Links: <nav>
nav.elem =
element nav { nav.inner & nav.attrs }
nav.attrs =
( common.attrs
& ( common.attrs.aria.implicit.region
| common.attrs.aria.landmark.navigation
)?
)
nav.inner =
( common.inner.flow )
common.elem.flow |= nav.elem
## Article: <article>
article.elem =
element article { article.inner & article.attrs }
article.attrs =
( common.attrs
& ( common.attrs.aria.implicit.region
| common.attrs.aria.landmark.article
| common.attrs.aria.landmark.main
| common.attrs.aria.landmark.document
| common.attrs.aria.landmark.application
)?
)
article.inner =
( style.elem*
, common.inner.flow
)
common.elem.flow |= article.elem
## Tangential Aside: <aside>
aside.elem =
element aside { aside.inner & aside.attrs }
aside.attrs =
( common.attrs
& ( common.attrs.aria.implicit.region
| common.attrs.aria.landmark.complementary
| common.attrs.aria.landmark.search
| common.attrs.aria.landmark.note
)?
)
aside.inner =
( style.elem*
, common.inner.flow
)
common.elem.flow |= aside.elem
## Header: <header>
header.elem =
element header { header.inner & header.attrs }
header.attrs =
( common.attrs
& ( common.attrs.aria.implicit.region
| common.attrs.aria.landmark.banner
)?
)
header.inner =
( common.inner.flow )
common.elem.flow |= header.elem
## Footer: <footer>
footer.elem =
element footer { footer.inner & footer.attrs }
footer.attrs =
( common.attrs
& ( common.attrs.aria.implicit.region
| common.attrs.aria.landmark.contentinfo
)?
)
footer.inner =
( common.inner.flow )
common.elem.flow |= footer.elem
@@ -0,0 +1,224 @@
datatypes w = "http://whattf.org/datatype-draft"
# #####################################################################
## RELAX NG Schema for HTML 5: Tables #
# #####################################################################
# #####################################################################
## Table Envelope
## Table Datatypes
# tables.data.multilen =
# ( common.data.integer.positive
# | common.data.percent
# | xsd:token { pattern = "[0-9]+\*" } #REVISIT should this one be string?
# )
## Table Alignment Attributes
tables.attrs.alignment =
( tables.attrs.align?
& tables.attrs.char?
& tables.attrs.valign?
)
tables.attrs.align =
attribute align {
( w:string "left"
| w:string "center"
| w:string "right"
| w:string "justify"
| w:string "char"
)
}
tables.attrs.char =
attribute char {
xsd:string { pattern = "." }
}
tables.attrs.valign =
attribute valign {
( w:string "top"
| w:string "middle"
| w:string "bottom"
| w:string "baseline"
)
}
## Data Table: <table>
table.elem =
element table { table.inner & table.attrs }
table.attrs =
( common.attrs
& table.attrs.border?
& common.attrs.aria?
)
table.attrs.border =
attribute border {
string
}
table.inner =
( caption.elem?
, colgroup.elem*
, thead.elem?
, ( ( tfoot.elem
, ( tbody.elem* | tr.elem+ )
)
| ( ( tbody.elem* | tr.elem+ )
, tfoot.elem?
)
)
)
common.elem.flow |= table.elem
## Table Caption: <caption>
caption.elem =
element caption { caption.inner & caption.attrs }
caption.attrs =
( common.attrs
& common.attrs.aria.implicit.region?
)
caption.inner =
( common.inner.flow )
# #####################################################################
## Table Super Structure
## Table Column Group: <colgroup>
colgroup.elem =
element colgroup { colgroup.inner & colgroup.attrs }
colgroup.attrs =
( common.attrs )
colgroup.attrs.span =
attribute span {
common.data.integer.positive
}
colgroup.inner =
( col.elem*
| colgroup.attrs.span?
)
## Table Column: <col>
col.elem =
element col { col.inner & col.attrs }
col.attrs =
( common.attrs
& col.attrs.span?
)
col.attrs.span =
attribute span {
common.data.integer.positive
}
col.inner =
( empty )
## Table Header Row Group
thead.elem =
element thead { thead.inner & thead.attrs }
thead.attrs =
( common.attrs )
thead.inner =
( tr.elem* )
## Table Footer Row Group
tfoot.elem =
element tfoot { tfoot.inner & tfoot.attrs }
tfoot.attrs =
( common.attrs )
tfoot.inner =
( tr.elem* )
## Table Row Group
tbody.elem =
element tbody { tbody.inner & tbody.attrs }
tbody.attrs =
( common.attrs )
tbody.inner =
( tr.elem* )
# #####################################################################
## Cell Structure
## Table Row
tr.elem =
element tr { tr.inner & tr.attrs }
tr.attrs =
( common.attrs
& common.attrs.aria?
)
tr.inner =
( ( td.elem | th.elem )* )
## Common Table Cell Attributes
tables.attrs.cell-structure =
( tables.attrs.colspan?
& tables.attrs.rowspan?
)
tables.attrs.colspan =
attribute colspan {
common.data.integer.positive
}
tables.attrs.rowspan =
attribute rowspan {
common.data.integer.non-negative
}
tables.attrs.access-headers =
( tables.attrs.headers? )
tables.attrs.headers =
attribute headers {
common.data.idrefs
}
tables.attrs.define-headers =
( tables.attrs.scope? )
tables.attrs.scope =
attribute scope {
( w:string "row"
| w:string "col"
| w:string "rowgroup"
| w:string "colgroup"
)
}
tables.attrs.abbr =
attribute abbr {
text
}
## Table Data Cell: <td>
td.elem =
element td { td.inner & td.attrs }
td.attrs =
( common.attrs
& tables.attrs.cell-structure
& tables.attrs.headers?
# & tables.attrs.alignment
& common.attrs.aria?
)
td.inner =
( common.inner.flow )
## Table Header Cells: <th>
th.elem =
element th { th.inner & th.attrs }
th.attrs =
( common.attrs
& tables.attrs.cell-structure
& tables.attrs.scope?
& tables.attrs.headers?
# & tables.attrs.alignment
& common.attrs.aria.implicit.th?
)
th.inner =
( common.inner.phrasing )
@@ -0,0 +1,27 @@
# #####################################################################
## RELAX NG Schema for HTML 5: Web Forms 1.0 Scripting #
# #####################################################################
scripting.attr.form.select =
attribute onselect { string }
scripting.attr.form.change =
attribute onchange { string }
# input.text.attrs &=
# ( scripting.attr.form.select?
# )
# shared-form.attrs &=
# ( scripting.attr.form.change?
# )
# form.attrs &=
# ( scripting.attr.form.reset?
# & scripting.attr.form.submit?
# )
scripting.attr.form.submit =
attribute onsubmit { string }
scripting.attr.form.reset =
attribute onreset { string }
@@ -0,0 +1,536 @@
datatypes w = "http://whattf.org/datatype-draft"
# #####################################################################
## RELAX NG Schema for HTML 5: Web Forms 1.0 markup #
# #####################################################################
## Shared attributes for form controls
common-form.attrs =
( common-form.attrs.name?
& common-form.attrs.disabled?
)
common-form.attrs.name =
attribute name {
string #REVISIT should this be restricted somehow? No & and = perhaps?
}
common-form.attrs.disabled =
attribute disabled {
w:string "disabled" | w:string ""
}
shared-form.attrs.readonly =
attribute readonly {
w:string "readonly" | w:string ""
}
shared-form.attrs.maxlength =
attribute maxlength {
common.data.integer.non-negative
}
shared-form.attrs.size =
attribute size {
common.data.integer.positive
}
# REVISIT tabindex goes in common.attrs
## Shared attributes for <input>
input.attrs.checked =
attribute checked {
w:string "checked" | w:string ""
}
## Text Field: <input type='text'>
input.text.elem =
element input { input.text.attrs }
input.text.attrs =
( common.attrs
& common-form.attrs
& input.text.attrs.type?
& shared-form.attrs.maxlength?
& shared-form.attrs.readonly?
& shared-form.attrs.size?
& input.text.attrs.value?
& ( common.attrs.aria
| common.attrs.aria.implicit.input
)?
)
input.text.attrs.type =
attribute type {
w:string "text"
}
input.text.attrs.value =
attribute value {
form.data.stringwithoutlinebreaks
}
input.elem = input.text.elem
## Password Field: <input type='password'>
input.password.elem =
element input { input.password.attrs }
input.password.attrs =
( common.attrs
& common-form.attrs
& input.password.attrs.type
& shared-form.attrs.maxlength?
& shared-form.attrs.readonly?
& shared-form.attrs.size?
& input.password.attrs.value?
& common.attrs.aria.implicit.input?
)
input.password.attrs.type =
attribute type {
w:string "password"
}
input.password.attrs.value =
attribute value {
form.data.stringwithoutlinebreaks
}
input.elem |= input.password.elem
## Checkbox: <input type='checkbox'>
input.checkbox.elem =
element input { input.checkbox.attrs }
input.checkbox.attrs =
( common.attrs
& common-form.attrs
& input.checkbox.attrs.type
& input.attrs.checked?
& input.checkbox.attrs.value?
& common.attrs.aria.implicit.input?
)
input.checkbox.attrs.type =
attribute type {
w:string "checkbox"
}
input.checkbox.attrs.value =
attribute value {
string #REVISIT require non-empty value?
}
input.elem |= input.checkbox.elem
## Radiobutton: <input type='radio'>
input.radio.elem =
element input { input.radio.attrs }
input.radio.attrs =
( common.attrs
& common-form.attrs
& input.radio.attrs.type
& input.attrs.checked?
& input.radio.attrs.value?
& common.attrs.aria.implicit.input?
)
input.radio.attrs.type =
attribute type {
w:string "radio"
}
input.radio.attrs.value =
attribute value {
string #REVISIT require non-empty value?
}
input.elem |= input.radio.elem
## Scripting Hook Button: <input type='button'>
input.button.elem =
element input { input.button.attrs }
input.button.attrs =
( common.attrs
& common-form.attrs
& input.button.attrs.type
& input.button.attrs.value?
& ( common.attrs.aria
| common.attrs.aria.implicit.button
)?
)
input.button.attrs.type =
attribute type {
w:string "button"
}
input.button.attrs.value =
attribute value {
string #REVISIT require non-empty value?
}
input.elem |= input.button.elem
#REVISIT should this be enabled by a scripting module only?
## Submit Button: <input type='submit'>
input.submit.elem =
element input { input.submit.attrs }
input.submit.attrs =
( common.attrs
& common-form.attrs
& input.submit.attrs.type
& input.submit.attrs.value?
& common.attrs.aria.implicit.button?
)
input.submit.attrs.type =
attribute type {
w:string "submit"
}
input.submit.attrs.value =
attribute value {
string #REVISIT require non-empty value?
}
input.elem |= input.submit.elem
## Reset Button: <input type='reset'>
input.reset.elem =
element input { input.reset.attrs }
input.reset.attrs =
( common.attrs
& common-form.attrs
& input.reset.attrs.type
& input.reset.attrs.value?
& common.attrs.aria.implicit.button?
)
input.reset.attrs.type =
attribute type {
w:string "reset"
}
input.reset.attrs.value =
attribute value {
string #REVISIT require non-empty value?
}
input.elem |= input.reset.elem
# REVISIT does reset make sense outside a form?
## File Upload: <input type='file'>
input.file.elem =
element input { input.file.attrs }
input.file.attrs =
( common.attrs
& common-form.attrs
& input.file.attrs.type
& input.file.attrs.accept?
& common.attrs.aria.implicit.input?
)
input.file.attrs.type =
attribute type {
w:string "file"
}
input.file.attrs.accept =
attribute accept {
form.data.mimetypelist
}
input.elem |= input.file.elem
## Hidden String: <input type='hidden'>
input.hidden.elem =
element input { input.hidden.attrs }
input.hidden.attrs =
( common.attrs
& common-form.attrs
& input.hidden.attrs.type
& input.hidden.attrs.value?
)
input.hidden.attrs.type =
attribute type {
w:string "hidden"
}
input.hidden.attrs.value =
attribute value {
string
}
input.elem |= input.hidden.elem
## Image Submit Button: <input type='image'>
input.image.elem =
element input { input.image.attrs }
input.image.attrs =
( common.attrs
& common-form.attrs
& input.image.attrs.type
& input.image.attrs.alt
& input.image.attrs.src?
& ( common.attrs.aria
| common.attrs.aria.implicit.button
)?
)
input.image.attrs.type =
attribute type {
w:string "image"
}
input.image.attrs.alt =
attribute alt {
form.data.nonemptystring
}
input.image.attrs.src =
attribute src {
common.data.uri.non-empty
}
input.elem |= input.image.elem
common.elem.phrasing |= input.elem
## Text Area: <textarea>
textarea.elem =
element textarea { textarea.inner & textarea.attrs }
textarea.attrs =
( common.attrs
& common-form.attrs
& shared-form.attrs.readonly?
& textarea.attrs.rows-and-cols-wf1
& common.attrs.aria.implicit.input?
#FIXME onfocus, onblur, onselect,onchange
)
# This is ugly.
textarea.attrs.rows-and-cols-wf1 =
textarea.attrs.rows-and-cols-wf1.inner
textarea.attrs.rows-and-cols-wf1.inner =
( textarea.attrs.cols
& textarea.attrs.rows
)
textarea.attrs.cols =
attribute cols {
common.data.integer.positive
}
textarea.attrs.rows =
attribute rows {
common.data.integer.positive
}
textarea.inner =
( text )
common.elem.phrasing |= textarea.elem
# Due to limitations with interleave, handling single/multiple selection
# enforcement in RELAX NG seems to be possible but really awkward.
# Tried it. Leaving it to Schematron.
## Select menu option: <option selected>
option.elem =
element option { option.inner & option.attrs }
option.attrs =
( common.attrs
& common-form.attrs.disabled?
& option.attrs.selected?
& option.attrs.label?
& option.attrs.value?
& common.attrs.aria.implicit.input?
)
option.attrs.selected =
attribute selected {
w:string "selected" | w:string ""
}
option.attrs.label =
attribute label {
string
}
option.attrs.value =
attribute value {
string
}
option.inner =
( text )
## Option Group: <optgroup>
optgroup.elem =
element optgroup { optgroup.inner & optgroup.attrs }
optgroup.attrs =
( common.attrs
& optgroup.attrs.label
& common-form.attrs.disabled?
)
optgroup.attrs.label =
attribute label {
string
}
optgroup.inner =
( option.elem* )
## Selection Menu: <select>
select.elem =
element select { select.inner & select.attrs }
select.attrs =
( common.attrs
& common-form.attrs
& select.attrs.size?
& select.attrs.multiple?
# FIXME onfocus, onblur, onchange
)
select.attrs.size =
attribute size {
common.data.integer.positive
}
select.attrs.multiple =
attribute multiple {
w:string "multiple" | w:string ""
}
select.inner =
( optgroup.elem*
& option.elem*
)
common.elem.phrasing |= select.elem
## Shared Definitions for Complex Button
button.attrs.value =
attribute value {
string
}
button.inner =
( common.inner.phrasing )
## Complex Submit Button: <button type='submit'>
button.submit.elem =
element button { button.inner & button.submit.attrs }
button.submit.attrs =
( common.attrs
& common-form.attrs
& button.submit.attrs.type?
& button.attrs.value?
& common.attrs.aria.implicit.button?
)
button.submit.attrs.type =
attribute type {
w:string "submit"
}
button.elem = button.submit.elem
## Complex Reset Button: <button type='reset'>
button.reset.elem =
element button { button.inner & button.reset.attrs }
button.reset.attrs =
( common.attrs
& common-form.attrs
& button.reset.attrs.type
& button.attrs.value? #REVISIT I guess this still affects the DOM
& common.attrs.aria.implicit.button?
)
button.reset.attrs.type =
attribute type {
w:string "reset"
}
button.elem |= button.reset.elem
## Complex Push Button: <button type='button'>
button.button.elem =
element button { button.inner & button.button.attrs }
button.button.attrs =
( common.attrs
& common-form.attrs
& button.button.attrs.type
& button.attrs.value? #REVISIT I guess this still affects the DOM
& ( common.attrs.aria
| common.attrs.aria.implicit.button
)?
)
button.button.attrs.type =
attribute type {
w:string "button"
}
button.elem |= button.button.elem
common.elem.phrasing |= button.elem
## Form: <form>
form.elem =
element form { form.inner & form.attrs }
form.attrs =
( common.attrs
& form.attrs.action? #REVISIT Should this be required anyway?
& form.attrs.method?
& form.attrs.enctype?
& common-form.attrs.name?
& form.attrs.accept-charset?
& ( common.attrs.aria
| common.attrs.aria.implicit.region
)?
)
form.attrs.action =
attribute action {
common.data.uri.non-empty
}
form.attrs.method =
attribute method {
form.attrs.method.data
}
form.attrs.method.data =
( w:string "get" | w:string "post" )
form.attrs.enctype =
attribute enctype {
form.attrs.enctype.data
}
form.attrs.enctype.data =
( w:string "application/x-www-form-urlencoded"
| w:string "multipart/form-data"
)
form.attrs.accept-charset =
attribute accept-charset {
form.data.charsetlist
}
form.inner =
( common.inner.flow )
common.elem.flow |= form.elem
## Fieldset: <fieldset>
fieldset.elem =
element fieldset { fieldset.inner & fieldset.attrs }
fieldset.attrs =
( common.attrs
& common.attrs.aria.implicit.group?
)
fieldset.inner =
( legend.elem? #REVISIT should this be required?
, common.inner.flow
)
common.elem.flow |= fieldset.elem
## Label: <label>
label.elem =
element label { label.inner & label.attrs }
label.attrs =
( common.attrs
& label.attrs.for?
& common.attrs.aria.implicit.region?
)
label.attrs.for =
attribute for {
common.data.idref
}
label.inner =
( common.inner.phrasing ) #REVISIT making obvious guess
common.elem.phrasing |= label.elem
@@ -0,0 +1,9 @@
# #####################################################################
## RELAX NG Schema for HTML 5: Web Forms 2.0 Scripting #
# #####################################################################
# output.attrs &=
# ( scripting.attr.form.formchange?
# & scripting.attr.form.forminput?
# & scripting.attr.form.change?
# )
@@ -0,0 +1,800 @@
datatypes w = "http://whattf.org/datatype-draft"
# #####################################################################
## RELAX NG Schema for HTML 5: Web Forms 2.0 markup #
# #####################################################################
## Shared attributes for form controls
common-form.attrs &=
( common-form.attrs.form? )
common-form.attrs.form |=
attribute form {
common.data.idref
}
shared-form.attrs.formaction =
attribute formaction {
common.data.uri.non-empty
}
shared-form.attrs.formenctype =
attribute formenctype {
shared-form.attrs.formenctype.data
}
shared-form.attrs.formenctype.data =
( w:string "application/x-www-form-urlencoded"
| w:string "multipart/form-data"
| w:string "text/plain"
)
shared-form.attrs.formmethod =
attribute formmethod {
shared-form.attrs.formmethod.data
}
shared-form.attrs.formmethod.data =
( w:string "get"
| w:string "post"
)
shared-form.attrs.formtarget =
attribute formtarget {
common.data.browsing-context-or-keyword
}
shared-form.attrs.formnovalidate =
attribute formnovalidate {
w:string "formnovalidate" | w:string ""
}
shared-form.attrs.autofocus =
attribute autofocus {
w:string "autofocus" | w:string ""
}
shared-form.attrs.pattern =
attribute pattern {
form.data.pattern
}
shared-form.attrs.template =
attribute template {
common.data.idref
}
shared-form.attrs.required =
attribute required {
w:string "required" | w:string ""
}
shared-form.attrs.placeholder =
attribute placeholder {
form.data.stringwithoutlinebreaks
}
shared-form.attrs.dirname =
attribute dirname {
form.data.nonemptystring
}
## Shared attributes for <input>
input.attrs.autocomplete =
attribute autocomplete {
w:string "on" | w:string "off"
}
input.attrs.list =
attribute list {
common.data.idref
}
input.attrs.step.float =
attribute step {
w:string "any" | common.data.float.positive
}
input.attrs.step.integer =
attribute step {
w:string "any" | common.data.integer.positive
}
input.attrs.multiple =
attribute multiple {
w:string "multiple" | w:string ""
}
## Text Field: <input type='text'>, Extensions
input.text.attrs &=
( input.attrs.autocomplete?
& shared-form.attrs.autofocus?
& input.attrs.list?
& shared-form.attrs.pattern?
& shared-form.attrs.required?
& shared-form.attrs.placeholder?
& shared-form.attrs.dirname?
)
## Password Field: <input type='password'>, Extensions
input.password.attrs &=
( input.attrs.autocomplete?
& shared-form.attrs.autofocus?
& shared-form.attrs.pattern?
& shared-form.attrs.required?
& shared-form.attrs.placeholder?
)
## Checkbox <input type='checkbox'>, Extensions
input.checkbox.attrs &=
( shared-form.attrs.autofocus?
& shared-form.attrs.required?
)
## Radiobutton: <input type='radio'>, Extensions
input.radio.attrs &=
( shared-form.attrs.autofocus?
& shared-form.attrs.required?
)
## Scripting Hook Button: <input type='button'>, Extensions
input.button.attrs &=
( shared-form.attrs.autofocus? )
## Submit Button: <input type='submit'>, Extensions
input.submit.attrs &=
( shared-form.attrs.formaction?
& shared-form.attrs.autofocus?
& shared-form.attrs.formenctype?
& shared-form.attrs.formmethod?
& shared-form.attrs.formtarget?
& shared-form.attrs.formnovalidate?
)
## Reset Button: <input type='reset'>, Extensions
input.reset.attrs &=
( shared-form.attrs.autofocus? )
## File Upload: <input type='file'>, Extensions
input.file.attrs &=
( shared-form.attrs.autofocus?
& shared-form.attrs.required?
& input.attrs.multiple?
)
## Image Submit Button: <input type='image'>, Extensions
input.image.attrs &=
( shared-form.attrs.formaction?
& shared-form.attrs.autofocus?
& shared-form.attrs.formenctype?
& shared-form.attrs.formmethod?
& shared-form.attrs.formtarget?
& shared-form.attrs.formnovalidate?
& input.image.attrs.height?
& input.image.attrs.width?
)
input.image.attrs.height =
attribute height {
common.data.integer.non-negative
}
input.image.attrs.width =
attribute width {
common.data.integer.non-negative
}
## Global Date and Time: <input type='datetime'>
input.datetime.elem =
element input { input.datetime.attrs }
input.datetime.attrs =
( common.attrs
& common-form.attrs
& input.datetime.attrs.type
& input.attrs.autocomplete?
& shared-form.attrs.autofocus?
& input.attrs.list?
& input.datetime.attrs.min?
& input.datetime.attrs.max?
& input.attrs.step.float?
& shared-form.attrs.readonly?
& shared-form.attrs.required?
& input.datetime.attrs.value?
& common.attrs.aria.implicit.input?
)
input.datetime.attrs.type =
attribute type {
w:string "datetime"
}
input.datetime.attrs.min =
attribute min {
common.data.datetime
}
input.datetime.attrs.max =
attribute max {
common.data.datetime
}
input.datetime.attrs.value =
attribute value {
common.data.datetime
}
input.elem |= input.datetime.elem
## Date and Time with No Time Zone Information: <input type='datetime-local'>
input.datetime-local.elem =
element input { input.datetime-local.attrs }
input.datetime-local.attrs =
( common.attrs
& common-form.attrs
& input.datetime-local.attrs.type
& input.attrs.autocomplete?
& shared-form.attrs.autofocus?
& input.attrs.list?
& input.datetime-local.attrs.min?
& input.datetime-local.attrs.max?
& input.attrs.step.float?
& shared-form.attrs.readonly?
& shared-form.attrs.required?
& input.datetime-local.attrs.value?
& common.attrs.aria.implicit.input?
)
input.datetime-local.attrs.type =
attribute type {
w:string "datetime-local"
}
input.datetime-local.attrs.min =
attribute min {
form.data.datetime-local
}
input.datetime-local.attrs.max =
attribute max {
form.data.datetime-local
}
input.datetime-local.attrs.value =
attribute value {
form.data.datetime-local
}
input.elem |= input.datetime-local.elem
## Date: <input type='date'>
input.date.elem =
element input { input.date.attrs }
input.date.attrs =
( common.attrs
& common-form.attrs
& input.date.attrs.type
& input.attrs.autocomplete?
& shared-form.attrs.autofocus?
& input.attrs.list?
& input.date.attrs.min?
& input.date.attrs.max?
& input.attrs.step.integer?
& shared-form.attrs.readonly?
& shared-form.attrs.required?
& input.date.attrs.value?
& common.attrs.aria.implicit.input?
)
input.date.attrs.type =
attribute type {
w:string "date"
}
input.date.attrs.min =
attribute min {
form.data.date
}
input.date.attrs.max =
attribute max {
form.data.date
}
input.date.attrs.value =
attribute value {
form.data.date
}
input.elem |= input.date.elem
## Year and Month: <input type='month'>
input.month.elem =
element input { input.month.attrs }
input.month.attrs =
( common.attrs
& common-form.attrs
& input.month.attrs.type
& input.attrs.autocomplete?
& shared-form.attrs.autofocus?
& input.attrs.list?
& input.month.attrs.min?
& input.month.attrs.max?
& input.attrs.step.integer?
& shared-form.attrs.readonly?
& shared-form.attrs.required?
& input.month.attrs.value?
& common.attrs.aria.implicit.input?
)
input.month.attrs.type =
attribute type {
w:string "month"
}
input.month.attrs.min =
attribute min {
form.data.month
}
input.month.attrs.max =
attribute max {
form.data.month
}
input.month.attrs.value =
attribute value {
form.data.month
}
input.elem |= input.month.elem
## Time without Time Zone Information: <input type='time'>
input.time.elem =
element input { input.time.attrs }
input.time.attrs =
( common.attrs
& common-form.attrs
& input.time.attrs.type
& input.attrs.autocomplete?
& shared-form.attrs.autofocus?
& input.attrs.list?
& input.time.attrs.min?
& input.time.attrs.max?
& input.attrs.step.float?
& shared-form.attrs.readonly?
& shared-form.attrs.required?
& input.time.attrs.value?
& common.attrs.aria.implicit.input?
)
input.time.attrs.type =
attribute type {
w:string "time"
}
input.time.attrs.min =
attribute min {
form.data.time
}
input.time.attrs.max =
attribute max {
form.data.time
}
input.time.attrs.value =
attribute value {
form.data.time
}
input.elem |= input.time.elem
## Year and Week: <input type='week'>
input.week.elem =
element input { input.week.attrs }
input.week.attrs =
( common.attrs
& common-form.attrs
& input.week.attrs.type
& input.attrs.autocomplete?
& shared-form.attrs.autofocus?
& input.attrs.list?
& input.week.attrs.min?
& input.week.attrs.max?
& input.attrs.step.integer?
& shared-form.attrs.readonly?
& shared-form.attrs.required?
& input.week.attrs.value?
& common.attrs.aria.implicit.input?
)
input.week.attrs.type =
attribute type {
w:string "week"
}
input.week.attrs.min =
attribute min {
form.data.week
}
input.week.attrs.max =
attribute max {
form.data.week
}
input.week.attrs.value =
attribute value {
form.data.week
}
input.elem |= input.week.elem
## Number: <input type='number'>
input.number.elem =
element input { input.number.attrs }
input.number.attrs =
( common.attrs
& common-form.attrs
& input.number.attrs.type
& input.attrs.autocomplete?
& shared-form.attrs.autofocus?
& input.attrs.list?
& input.number.attrs.min?
& input.number.attrs.max?
& input.attrs.step.float?
& shared-form.attrs.readonly?
& shared-form.attrs.required?
& input.number.attrs.value?
& common.attrs.aria.implicit.input?
)
input.number.attrs.type =
attribute type {
w:string "number"
}
input.number.attrs.min =
attribute min {
common.data.float
}
input.number.attrs.max =
attribute max {
common.data.float
}
input.number.attrs.value =
attribute value {
common.data.float
}
input.elem |= input.number.elem
## Imprecise Number: <input type='range'>
input.range.elem =
element input { input.range.attrs }
input.range.attrs =
( common.attrs
& common-form.attrs
& input.range.attrs.type
& input.attrs.autocomplete?
& shared-form.attrs.autofocus?
& input.attrs.list?
& input.range.attrs.min?
& input.range.attrs.max?
& input.attrs.step.float?
& input.range.attrs.value?
& common.attrs.aria.implicit.input?
)
input.range.attrs.type =
attribute type {
w:string "range"
}
input.range.attrs.min =
attribute min {
common.data.float
}
input.range.attrs.max =
attribute max {
common.data.float
}
input.range.attrs.value =
attribute value {
common.data.float
}
input.elem |= input.range.elem
## Email Address: <input type='email'>
input.email.elem =
element input { input.email.attrs }
input.email.attrs =
( common.attrs
& common-form.attrs
& input.email.attrs.type
& input.attrs.autocomplete?
& shared-form.attrs.autofocus?
& input.attrs.list?
& shared-form.attrs.maxlength?
& shared-form.attrs.pattern?
& shared-form.attrs.readonly?
& shared-form.attrs.required?
& shared-form.attrs.size?
& shared-form.attrs.placeholder?
& ( ( input.attrs.multiple
& input.email.attrs.value.multiple?
)
| input.email.attrs.value.single?
)?
& common.attrs.aria.implicit.input?
)
input.email.attrs.type =
attribute type {
w:string "email"
}
input.email.attrs.value.single =
attribute value {
form.data.emailaddress
}
input.email.attrs.value.multiple =
attribute value {
form.data.emailaddresslist
}
input.elem |= input.email.elem
## IRI: <input type='url'>
input.url.elem =
element input { input.url.attrs }
input.url.attrs =
( common.attrs
& common-form.attrs
& input.url.attrs.type
& input.attrs.autocomplete?
& shared-form.attrs.autofocus?
& input.attrs.list?
& shared-form.attrs.maxlength?
& shared-form.attrs.pattern?
& shared-form.attrs.readonly?
& shared-form.attrs.required?
& shared-form.attrs.size?
& shared-form.attrs.placeholder?
& input.url.attrs.value?
& common.attrs.aria.implicit.input?
)
input.url.attrs.type =
attribute type {
w:string "url"
}
input.url.attrs.value =
attribute value {
w:string "" | common.data.uri.absolute
}
input.elem |= input.url.elem
## Search: <input type='search'>
input.search.elem =
element input { input.search.attrs }
input.search.attrs =
( common.attrs
& common-form.attrs
& input.search.attrs.type
& input.attrs.autocomplete?
& shared-form.attrs.autofocus?
& input.attrs.list?
& shared-form.attrs.maxlength?
& shared-form.attrs.pattern?
& shared-form.attrs.readonly?
& shared-form.attrs.required?
& shared-form.attrs.size?
& shared-form.attrs.placeholder?
& shared-form.attrs.dirname?
& input.search.attrs.value?
& common.attrs.aria.implicit.input?
)
input.search.attrs.type =
attribute type {
w:string "search"
}
input.search.attrs.value =
attribute value {
form.data.stringwithoutlinebreaks
}
input.elem |= input.search.elem
## Telephone Number: <input type='tel'>
input.tel.elem =
element input { input.tel.attrs }
input.tel.attrs =
( common.attrs
& common-form.attrs
& input.tel.attrs.type
& input.attrs.autocomplete?
& shared-form.attrs.autofocus?
& input.attrs.list?
& shared-form.attrs.maxlength?
& shared-form.attrs.pattern?
& shared-form.attrs.readonly?
& shared-form.attrs.required?
& shared-form.attrs.size?
& shared-form.attrs.placeholder?
& input.tel.attrs.value?
& common.attrs.aria.implicit.input?
)
input.tel.attrs.type =
attribute type {
w:string "tel"
}
input.tel.attrs.value =
attribute value {
form.data.stringwithoutlinebreaks
}
input.elem |= input.tel.elem
## Color: <input type='color'>
input.color.elem =
element input { input.color.attrs }
input.color.attrs =
( common.attrs
& common-form.attrs
& input.color.attrs.type
& input.attrs.autocomplete?
& shared-form.attrs.autofocus?
& input.attrs.list?
& input.color.attrs.value?
& common.attrs.aria.implicit.input?
)
input.color.attrs.type =
attribute type {
w:string "color"
}
input.color.attrs.value =
attribute value {
form.data.color
}
input.elem |= input.color.elem
## Form Output: <output>
output.elem =
element output { output.inner & output.attrs }
output.attrs =
( common.attrs
& common-form.attrs.name?
& common-form.attrs.form?
& output.attrs.for?
& common.attrs.aria.implicit.region?
)
output.attrs.for =
attribute for {
common.data.idrefs #REVISIT spec says space--not whitespace
}
output.inner =
( common.inner.phrasing )
common.elem.phrasing |= output.elem
## Text Area: <textarea>, extensions
textarea.attrs.rows-and-cols-wf1.inner &=
notAllowed
textarea.attrs.rows-and-cols-wf1 |=
empty
textarea.attrs &=
( shared-form.attrs.maxlength?
& shared-form.attrs.autofocus?
& shared-form.attrs.required?
& shared-form.attrs.placeholder?
& shared-form.attrs.dirname?
& textarea.attrs.rows?
& ( ( textarea.attrs.wrap.hard
& textarea.attrs.cols
)
| ( textarea.attrs.wrap.soft?
& textarea.attrs.cols?
)
)
)
textarea.attrs.wrap.hard =
attribute wrap {
w:string "hard"
}
textarea.attrs.wrap.soft =
attribute wrap {
w:string "soft"
}
## List of Prefill Data: <datalist>
#REVISIT should the options in datalist be non-selectable?
datalist.elem =
element datalist { datalist.inner & datalist.attrs }
datalist.inner =
( option.elem* & common.inner.phrasing )
datalist.attrs =
( common.attrs )
common.elem.phrasing |= datalist.elem
## Complex Submit Button: <button type='submit'>, extensions
button.submit.attrs &=
( shared-form.attrs.formaction?
& shared-form.attrs.autofocus?
& shared-form.attrs.formenctype?
& shared-form.attrs.formmethod?
& shared-form.attrs.formtarget?
& shared-form.attrs.formnovalidate?
)
## Complex Reset Button: <button type='reset'>, extensions
button.reset.attrs &=
( shared-form.attrs.autofocus? )
## Complex Push Button: <button type='button'>, extensions
button.button.attrs &=
( shared-form.attrs.autofocus? )
## Form: <form>, extensions
form.attrs &=
( form.attrs.novalidate?
& form.attrs.target?
& form.attrs.autocomplete?
)
form.attrs.novalidate =
attribute novalidate {
w:string "novalidate" | w:string ""
}
form.attrs.target =
attribute target {
common.data.browsing-context-or-keyword
}
form.attrs.autocomplete =
attribute autocomplete {
w:string "on" | w:string "off"
}
# REVISIT should this be case-insensitive in conforming XHTML documents?
form.attrs.enctype.data |=
( w:string "text/plain" )
## Fieldset: <fieldset>, extensions
fieldset.attrs &=
( common-form.attrs )
## Label: <label>, extensions
label.attrs &=
( common-form.attrs.form? )
## Key-pair generator/input control: <keygen>
keygen.elem =
element keygen { keygen.inner & keygen.attrs }
keygen.attrs =
( common.attrs
& keygen.attrs.challenge?
& keygen.attrs.keytype?
& shared-form.attrs.autofocus?
& common-form.attrs?
#REVISIT which ARIA attributes needed here
)
keygen.attrs.challenge =
attribute challenge {
string
}
keygen.attrs.keytype =
attribute keytype {
w:string "rsa"
}
keygen.inner =
( empty )
common.elem.phrasing |= keygen.elem
## Selection Menu: <select>, Extensions
select.attrs &=
( shared-form.attrs.autofocus?
& shared-form.attrs.required?
)
@@ -0,0 +1,40 @@
default namespace = "http://www.w3.org/1999/xhtml"
# #####################################################################
## RELAX NG Schema for XHTML 5 #
# #####################################################################
# To validate an XHTML 5 document, you must first validate against #
# this schema and then ALSO validate against assertions.sch #
# #####################################################################
## Schema Framework & Parameters
include "common.rnc" {
# XHTML flavor #
XMLonly = empty
HTMLonly = notAllowed
# HTML 4 compat #
v5only = empty
}
# #####################################################################
## Language Definitions
start = html.elem
include "meta.rnc"
include "phrase.rnc"
include "block.rnc"
include "sectional.rnc"
include "structural.rnc"
include "revision.rnc"
include "embed.rnc"
include "ruby.rnc"
include "media.rnc"
include "core-scripting.rnc"
include "tables.rnc"
include "form-datatypes.rnc"
include "web-forms.rnc"
include "web-forms2.rnc"
include "applications.rnc"
include "data.rnc"