From ef6a57ea544602f66604867800f36d41d4ddeae2 Mon Sep 17 00:00:00 2001 From: Eugene Kudelevsky Date: Mon, 15 Aug 2011 13:54:56 +0400 Subject: [PATCH] fix bugs in relaxng; new html5 support provided by relaxng schema --- plugins/relaxng/src/META-INF/plugin.xml | 38 +- .../model/descriptors/ChildElementFinder.java | 6 +- .../descriptors/CompositeDescriptor.java | 4 +- .../descriptors/RngElementDescriptor.java | 35 +- .../model/descriptors/RngNsDescriptor.java | 53 +- .../RelaxedHtmlFromSchemaNSDescriptor.java | 3 +- .../source/html/dtd/HtmlNSDescriptorImpl.java | 4 +- .../psi/impl/source/xml/XmlTagImpl.java | 6 +- .../src/com/intellij/xml/util/XmlUtil.java | 25 +- .../html/RelaxedHtmlNSDescriptor.java | 9 + .../com/intellij/xml/Html5SchemaProvider.java | 19 + .../RelaxedHtmlFromRngElementDescriptor.java | 109 ++ .../html/RelaxedHtmlFromRngNSDescriptor.java | 43 + .../html/RngHtml5MetaDataContributor.java | 64 ++ .../relaxNG/xml/RngHtml5SchemaProvider.java | 23 + .../src/resources/html5-schema/LICENSE | 23 + .../resources/html5-schema/applications.rnc | 281 +++++ .../src/resources/html5-schema/aria.rnc | 1017 +++++++++++++++++ .../src/resources/html5-schema/block.rnc | 201 ++++ .../src/resources/html5-schema/common.rnc | 420 +++++++ .../resources/html5-schema/core-scripting.rnc | 332 ++++++ .../src/resources/html5-schema/data.rnc | 84 ++ .../src/resources/html5-schema/embed.rnc | 570 +++++++++ .../resources/html5-schema/form-datatypes.rnc | 63 + .../src/resources/html5-schema/html5.rnc | 56 + .../html5-schema/html5exclusions.rnc | 63 + .../src/resources/html5-schema/media.rnc | 205 ++++ .../src/resources/html5-schema/meta.rnc | 323 ++++++ .../src/resources/html5-schema/microdata.rnc | 81 ++ .../src/resources/html5-schema/phrase.rnc | 361 ++++++ .../src/resources/html5-schema/revision.rnc | 52 + .../src/resources/html5-schema/ruby.rnc | 51 + .../src/resources/html5-schema/sectional.rnc | 140 +++ .../src/resources/html5-schema/structural.rnc | 105 ++ .../src/resources/html5-schema/tables.rnc | 224 ++++ .../src/resources/html5-schema/test.rnc | 0 .../html5-schema/web-forms-scripting.rnc | 27 + .../src/resources/html5-schema/web-forms.rnc | 536 +++++++++ .../html5-schema/web-forms2-scripting.rnc | 9 + .../src/resources/html5-schema/web-forms2.rnc | 800 +++++++++++++ .../src/resources/html5-schema/xhtml5.rnc | 40 + 41 files changed, 6429 insertions(+), 76 deletions(-) create mode 100644 xml/openapi/src/com/intellij/html/RelaxedHtmlNSDescriptor.java create mode 100644 xml/openapi/src/com/intellij/xml/Html5SchemaProvider.java create mode 100644 xml/relaxng/src/org/intellij/html/RelaxedHtmlFromRngElementDescriptor.java create mode 100644 xml/relaxng/src/org/intellij/html/RelaxedHtmlFromRngNSDescriptor.java create mode 100644 xml/relaxng/src/org/intellij/html/RngHtml5MetaDataContributor.java create mode 100644 xml/relaxng/src/org/intellij/plugins/relaxNG/xml/RngHtml5SchemaProvider.java create mode 100644 xml/relaxng/src/resources/html5-schema/LICENSE create mode 100644 xml/relaxng/src/resources/html5-schema/applications.rnc create mode 100644 xml/relaxng/src/resources/html5-schema/aria.rnc create mode 100644 xml/relaxng/src/resources/html5-schema/block.rnc create mode 100644 xml/relaxng/src/resources/html5-schema/common.rnc create mode 100644 xml/relaxng/src/resources/html5-schema/core-scripting.rnc create mode 100644 xml/relaxng/src/resources/html5-schema/data.rnc create mode 100644 xml/relaxng/src/resources/html5-schema/embed.rnc create mode 100644 xml/relaxng/src/resources/html5-schema/form-datatypes.rnc create mode 100644 xml/relaxng/src/resources/html5-schema/html5.rnc create mode 100644 xml/relaxng/src/resources/html5-schema/html5exclusions.rnc create mode 100644 xml/relaxng/src/resources/html5-schema/media.rnc create mode 100644 xml/relaxng/src/resources/html5-schema/meta.rnc create mode 100644 xml/relaxng/src/resources/html5-schema/microdata.rnc create mode 100644 xml/relaxng/src/resources/html5-schema/phrase.rnc create mode 100644 xml/relaxng/src/resources/html5-schema/revision.rnc create mode 100644 xml/relaxng/src/resources/html5-schema/ruby.rnc create mode 100644 xml/relaxng/src/resources/html5-schema/sectional.rnc create mode 100644 xml/relaxng/src/resources/html5-schema/structural.rnc create mode 100644 xml/relaxng/src/resources/html5-schema/tables.rnc create mode 100644 xml/relaxng/src/resources/html5-schema/test.rnc create mode 100644 xml/relaxng/src/resources/html5-schema/web-forms-scripting.rnc create mode 100644 xml/relaxng/src/resources/html5-schema/web-forms.rnc create mode 100644 xml/relaxng/src/resources/html5-schema/web-forms2-scripting.rnc create mode 100644 xml/relaxng/src/resources/html5-schema/web-forms2.rnc create mode 100644 xml/relaxng/src/resources/html5-schema/xhtml5.rnc diff --git a/plugins/relaxng/src/META-INF/plugin.xml b/plugins/relaxng/src/META-INF/plugin.xml index bfe39eaf65e4..73931f7b0a11 100644 --- a/plugins/relaxng/src/META-INF/plugin.xml +++ b/plugins/relaxng/src/META-INF/plugin.xml @@ -1,38 +1,4 @@ - - RelaxNG-Support - RELAX-NG Support - com.intellij.modules.xml - - relaxng.org and the corresponding - IntelliJ IDEA feature request: IDEA-13734. -

- The plugin provides the following features: -

-
    -
  • Completion and validation of XML documents associated with RELAX-NG schemas
  • -
  • Editing RELAX-NG files in XML and compact syntax, including on-the-fly error checking, completion, - documentation lookup and more.
  • -
  • Conversion between different schema formats (including W3C XML Schema/XML 1.0 DTDs) using - Trang
  • -
- ]]>
- 1.6 - - -
  • extreme index optimization
  • -
  • renameable xml prefixes
  • -
  • IDEA 9.x compatibility bugfixes
  • - -

    - The complete list of changes in earlier versions is available - here -

    -]]>
    - - Sascha Weinreuter - + @@ -76,6 +42,8 @@ + + diff --git a/plugins/relaxng/src/org/intellij/plugins/relaxNG/model/descriptors/ChildElementFinder.java b/plugins/relaxng/src/org/intellij/plugins/relaxNG/model/descriptors/ChildElementFinder.java index 4e00ae32533b..c472e3586310 100644 --- a/plugins/relaxng/src/org/intellij/plugins/relaxNG/model/descriptors/ChildElementFinder.java +++ b/plugins/relaxng/src/org/intellij/plugins/relaxNG/model/descriptors/ChildElementFinder.java @@ -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); } diff --git a/plugins/relaxng/src/org/intellij/plugins/relaxNG/model/descriptors/CompositeDescriptor.java b/plugins/relaxng/src/org/intellij/plugins/relaxNG/model/descriptors/CompositeDescriptor.java index 225bd2f751b2..8e5c75894595 100644 --- a/plugins/relaxng/src/org/intellij/plugins/relaxNG/model/descriptors/CompositeDescriptor.java +++ b/plugins/relaxng/src/org/intellij/plugins/relaxNG/model/descriptors/CompositeDescriptor.java @@ -61,8 +61,8 @@ public class CompositeDescriptor extends RngElementDescriptor { public XmlElementDescriptor[] getElementsDescriptors(XmlTag context) { final List descriptors = new ArrayList(Arrays.asList(super.getElementsDescriptors(context))); for (DElementPattern pattern : myPatterns) { - final List list = ContainerUtil.findAll(ChildElementFinder.find(2, pattern), NamedPatternFilter.INSTANCE); - descriptors.addAll(Arrays.asList(RngNsDescriptor.convertElementDescriptors(list, myNsDescriptor))); + final List list = ChildElementFinder.find(2, pattern); + descriptors.addAll(Arrays.asList(myNsDescriptor.convertElementDescriptors(list))); } return descriptors.toArray(new XmlElementDescriptor[descriptors.size()]); } diff --git a/plugins/relaxng/src/org/intellij/plugins/relaxNG/model/descriptors/RngElementDescriptor.java b/plugins/relaxng/src/org/intellij/plugins/relaxNG/model/descriptors/RngElementDescriptor.java index 16b4857c933c..4c3717d7f417 100644 --- a/plugins/relaxng/src/org/intellij/plugins/relaxNG/model/descriptors/RngElementDescriptor.java +++ b/plugins/relaxng/src/org/intellij/plugins/relaxNG/model/descriptors/RngElementDescriptor.java @@ -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> DESCR_KEY = Key.create("DESCR"); @@ -89,8 +85,7 @@ public class RngElementDescriptor implements XmlElementDescriptor { } final List patterns = ChildElementFinder.find(2, pattern); - final List 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, Boolean>> map) { - final List list = ContainerUtil.findAll(map.keySet(), NamedPatternFilter.INSTANCE); - return ContainerUtil.map2Array(list, XmlAttributeDescriptor.class, new Function() { - public XmlAttributeDescriptor fun(DAttributePattern dAttributePattern) { - final Pair, Boolean> pair = map.get(dAttributePattern); - return new RngXmlAttributeDescriptor(RngElementDescriptor.this, dAttributePattern, pair.first, pair.second); + final Map name2descriptor = new HashMap(); + + for (DAttributePattern pattern : map.keySet()) { + final Pair, 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 result = name2descriptor.values(); + return result.toArray(new RngXmlAttributeDescriptor[result.size()]); } public final XmlAttributeDescriptor getAttributeDescriptor(String attributeName, @Nullable XmlTag context) { diff --git a/plugins/relaxng/src/org/intellij/plugins/relaxNG/model/descriptors/RngNsDescriptor.java b/plugins/relaxng/src/org/intellij/plugins/relaxNG/model/descriptors/RngNsDescriptor.java index 7e9aaac14dcd..33aa3cf7bccc 100644 --- a/plugins/relaxng/src/org/intellij/plugins/relaxNG/model/descriptors/RngNsDescriptor.java +++ b/plugins/relaxng/src/org/intellij/plugins/relaxNG/model/descriptors/RngNsDescriptor.java @@ -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 patterns = ContainerUtil.findAll(ChildElementFinder.find(-1, myPattern), NamedPatternFilter.INSTANCE); + return findDescriptor(tag, patterns); } public XmlElementDescriptor findDescriptor(XmlTag tag, List list) { final QName qName = new QName(tag.getNamespace(), tag.getLocalName()); + return findDescriptor(qName, list); + } + + private XmlElementDescriptor findDescriptor(final QName qName, List 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 list = ContainerUtil.findAll(ChildElementFinder.find(myPattern), NamedPatternFilter.INSTANCE); - return convertElementDescriptors(list, this); + final List list = ChildElementFinder.find(-1, myPattern); + return convertElementDescriptors(list); } - static XmlElementDescriptor[] convertElementDescriptors(List finder, final RngNsDescriptor nsDescriptor) { - return ContainerUtil.map2Array(finder, XmlElementDescriptor.class, new Function() { - public XmlElementDescriptor fun(final DElementPattern elementPattern) { - return new RngElementDescriptor(nsDescriptor, elementPattern); + XmlElementDescriptor[] convertElementDescriptors(List patterns) { + patterns = ContainerUtil.findAll(patterns, NamedPatternFilter.INSTANCE); + + final Map> name2patterns = new HashMap>(); + for (DElementPattern pattern : patterns) { + for (QName qName : pattern.getName().listNames()) { + List dPatterns = name2patterns.get(qName); + if (dPatterns == null) { + dPatterns = new ArrayList(); + name2patterns.put(qName, dPatterns); + } + dPatterns.add(pattern); } - }); + } + + final List result = new ArrayList(); + + for (QName qName : name2patterns.keySet()) { + final List 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 diff --git a/xml/impl/src/com/intellij/html/impl/RelaxedHtmlFromSchemaNSDescriptor.java b/xml/impl/src/com/intellij/html/impl/RelaxedHtmlFromSchemaNSDescriptor.java index dc6a7f24c1c1..676247847a9a 100644 --- a/xml/impl/src/com/intellij/html/impl/RelaxedHtmlFromSchemaNSDescriptor.java +++ b/xml/impl/src/com/intellij/html/impl/RelaxedHtmlFromSchemaNSDescriptor.java @@ -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); diff --git a/xml/impl/src/com/intellij/psi/impl/source/html/dtd/HtmlNSDescriptorImpl.java b/xml/impl/src/com/intellij/psi/impl/source/html/dtd/HtmlNSDescriptorImpl.java index 85717dc84ffe..840e33530910 100644 --- a/xml/impl/src/com/intellij/psi/impl/source/html/dtd/HtmlNSDescriptorImpl.java +++ b/xml/impl/src/com/intellij/psi/impl/source/html/dtd/HtmlNSDescriptorImpl.java @@ -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 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) { diff --git a/xml/impl/src/com/intellij/psi/impl/source/xml/XmlTagImpl.java b/xml/impl/src/com/intellij/psi/impl/source/xml/XmlTagImpl.java index 5d7e38662845..dda67fb49cb4 100644 --- a/xml/impl/src/com/intellij/psi/impl/source/xml/XmlTagImpl.java +++ b/xml/impl/src/com/intellij/psi/impl/source/xml/XmlTagImpl.java @@ -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; } diff --git a/xml/impl/src/com/intellij/xml/util/XmlUtil.java b/xml/impl/src/com/intellij/xml/util/XmlUtil.java index e1aaa783b9b2..790d6e5c37a4 100644 --- a/xml/impl/src/com/intellij/xml/util/XmlUtil.java +++ b/xml/impl/src/com/intellij/xml/util/XmlUtil.java @@ -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; diff --git a/xml/openapi/src/com/intellij/html/RelaxedHtmlNSDescriptor.java b/xml/openapi/src/com/intellij/html/RelaxedHtmlNSDescriptor.java new file mode 100644 index 000000000000..275cbe9c93a3 --- /dev/null +++ b/xml/openapi/src/com/intellij/html/RelaxedHtmlNSDescriptor.java @@ -0,0 +1,9 @@ +package com.intellij.html; + +import com.intellij.xml.XmlNSDescriptor; + +/** + * @author Eugene.Kudelevsky + */ +public interface RelaxedHtmlNSDescriptor extends XmlNSDescriptor { +} diff --git a/xml/openapi/src/com/intellij/xml/Html5SchemaProvider.java b/xml/openapi/src/com/intellij/xml/Html5SchemaProvider.java new file mode 100644 index 000000000000..920c0c6c46a9 --- /dev/null +++ b/xml/openapi/src/com/intellij/xml/Html5SchemaProvider.java @@ -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 EP_NAME = ExtensionPointName.create("com.intellij.xml.html5SchemaProvider"); + + @NotNull + URL getHtmlSchemaLocation(); + + @NotNull + URL getXhtmlSchemaLocation(); +} diff --git a/xml/relaxng/src/org/intellij/html/RelaxedHtmlFromRngElementDescriptor.java b/xml/relaxng/src/org/intellij/html/RelaxedHtmlFromRngElementDescriptor.java new file mode 100644 index 000000000000..9237ba01a2b0 --- /dev/null +++ b/xml/relaxng/src/org/intellij/html/RelaxedHtmlFromRngElementDescriptor.java @@ -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; + } +} diff --git a/xml/relaxng/src/org/intellij/html/RelaxedHtmlFromRngNSDescriptor.java b/xml/relaxng/src/org/intellij/html/RelaxedHtmlFromRngNSDescriptor.java new file mode 100644 index 000000000000..ad58613c0dc8 --- /dev/null +++ b/xml/relaxng/src/org/intellij/html/RelaxedHtmlFromRngNSDescriptor.java @@ -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); + } +} diff --git a/xml/relaxng/src/org/intellij/html/RngHtml5MetaDataContributor.java b/xml/relaxng/src/org/intellij/html/RngHtml5MetaDataContributor.java new file mode 100644 index 000000000000..9d7c0a361f79 --- /dev/null +++ b/xml/relaxng/src/org/intellij/html/RngHtml5MetaDataContributor.java @@ -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; + } + } +} diff --git a/xml/relaxng/src/org/intellij/plugins/relaxNG/xml/RngHtml5SchemaProvider.java b/xml/relaxng/src/org/intellij/plugins/relaxNG/xml/RngHtml5SchemaProvider.java new file mode 100644 index 000000000000..c7f4a687f95c --- /dev/null +++ b/xml/relaxng/src/org/intellij/plugins/relaxNG/xml/RngHtml5SchemaProvider.java @@ -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"); + } +} diff --git a/xml/relaxng/src/resources/html5-schema/LICENSE b/xml/relaxng/src/resources/html5-schema/LICENSE new file mode 100644 index 000000000000..fd1093cc1c60 --- /dev/null +++ b/xml/relaxng/src/resources/html5-schema/LICENSE @@ -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. diff --git a/xml/relaxng/src/resources/html5-schema/applications.rnc b/xml/relaxng/src/resources/html5-schema/applications.rnc new file mode 100644 index 000000000000..bf27090d5950 --- /dev/null +++ b/xml/relaxng/src/resources/html5-schema/applications.rnc @@ -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.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.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.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.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.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:
  • + + mli.elem = + element li { mli.inner & mli.attrs } + mli.attrs = + ( common.attrs ) + mli.inner = + ( common.inner.flow ) + +## Canvas for Dynamic Graphics: + + 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.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.elem = + element summary { summary.inner & summary.attrs } + summary.attrs = + ( common.attrs ) + summary.inner = + ( common.inner.phrasing ) diff --git a/xml/relaxng/src/resources/html5-schema/aria.rnc b/xml/relaxng/src/resources/html5-schema/aria.rnc new file mode 100644 index 000000000000..9721d36e0fdb --- /dev/null +++ b/xml/relaxng/src/resources/html5-schema/aria.rnc @@ -0,0 +1,1017 @@ +# ##################################################################### +## RELAX NG Schema for HTML 5: Accessible Rich Internet Applications # +# ##################################################################### + +# ##################################################################### +## ARIA + +## Global states and properties + +aria.global = + ( aria.prop.atomic? + & aria.state.busy? + & aria.prop.controls? + & aria.prop.describedby? + & aria.state.disabled? + & aria.state.dropeffect? + & aria.prop.flowto? + & aria.state.grabbed? + & aria.prop.haspopup? + & aria.state.hidden? + & aria.state.invalid? + & aria.prop.label? + & aria.prop.labelledby? + & aria.prop.live? + & aria.prop.owns? + & aria.prop.relevant? + & aria.prop.required? + ) + +common.attrs.other &= aria.global? + +## States and Properties for Native Roles + +# common.attrs.aria.implicit.button |= +# ( aria.prop.controls? +# ) + +# common.attrs.aria.implicit.input |= +# ( aria.prop.controls? +# & aria.state.invalid? +# & aria.prop.required? +# ) + +common.attrs.aria.implicit.region |= + ( aria.state.expanded? +# & aria.prop.level? + ) + +common.attrs.aria.implicit.group |= + ( aria.state.expanded? + & aria.prop.activedescendant? + ) + +common.attrs.aria.implicit.th |= + ( aria.prop.sort? + & aria.prop.level? + & aria.state.expanded? + & aria.prop.readonly? + & aria.state.selected? + ) + +# common.attrs.aria.implicit.structure |= +# ( aria.prop.atomic? +# & aria.state.busy? +# & aria.prop.channel? +# & aria.prop.live? +# & aria.prop.relevant? +# ) + +# common.attrs.aria.implicit.link |= +# ( aria.prop.controls? +# & aria.state.disabled? +# ) + +common.attrs.aria.implicit.listitem |= + ( aria.prop.posinset? + & aria.prop.setsize? +# & aria.prop.atomic? + ) + +# common.attrs.aria.implicit.img |= +# ( aria.prop.atomic? +# & aria.state.busy? +# & aria.prop.channel? +# & aria.prop.controls? +# & aria.prop.live? +# & aria.prop.relevant? +# ) + +#common.attrs.aria.implicit.select |= +# ( aria.state.invalid? +# & aria.prop.required? +# & aria.prop.atomic? +# & aria.state.busy? +# & aria.prop.channel? +# & aria.prop.controls? +# & aria.prop.live? +# & aria.prop.relevant? +# ) + +# ##################################################################### +## States + +## busy + aria.state.busy = + attribute aria-busy + { string "true" + | string "false" #default + } + +## checked + aria.state.checked = + attribute aria-checked + { string "true" + | string "false" + | string "mixed" + | string "undefined" #default + } + +## disabled + aria.state.disabled = + attribute aria-disabled + { string "true" + | string "false" #default + } + +## dropeffect + aria.state.dropeffect = + attribute aria-dropeffect + { token "none" #default + | token "popup" + | token "execute" + | list + { ( string "copy" ) + , ( string "execute" )? + } + | list + { ( string "move" ) + , ( string "execute" )? + } + | list + { ( string "reference" ) + , ( string "execute" )? + } + | list + { ( string "execute" ) + , ( string "copy" ) + } + | list + { ( string "execute" ) + , ( string "move" ) + } + | list + { ( string "execute" ) + , ( string "reference" ) + } + } + +## expanded + aria.state.expanded = + attribute aria-expanded + { string "true" + | string "false" + | string "undefined" #default + } + +## grabbed + aria.state.grabbed = + attribute aria-grabbed + { string "true" + | string "false" + | string "undefined" #default + } + +## hidden + aria.state.hidden = + attribute aria-hidden + { string "true" + | string "false" #default + } + +## invalid + aria.state.invalid = + attribute aria-invalid + { string "true" + | string "false" #default + | string "grammar" + | string "spelling" + } + +## pressed + aria.state.pressed = + attribute aria-pressed + { string "true" + | string "false" + | string "mixed" + | string "undefined" #default + } + +## selected + aria.state.selected = + attribute aria-selected + { string "true" + | string "false" + | string "undefined" #default + } + + + +# ##################################################################### +## Properties + +## activedescendant + aria.prop.activedescendant = + attribute aria-activedescendant { + common.data.idref #REVISIT add Schematron check + } + +## atomic + aria.prop.atomic = + attribute aria-atomic + { string "true" + | string "false" #default + } + +## autocomplete + aria.prop.autocomplete = + attribute aria-autocomplete + { string "inline" + | string "list" + | string "both" + | string "none" #default + } + +## controls + aria.prop.controls = + attribute aria-controls { + common.data.idrefs #REVISIT add Schematron check + } + +## describedby + aria.prop.describedby = + attribute aria-describedby { + common.data.idrefs #REVISIT add Schematron check + } + +## flowto + aria.prop.flowto = + attribute aria-flowto { + common.data.idrefs #REVISIT add Schematron check + } + +## haspopup + aria.prop.haspopup = + attribute aria-haspopup + { string "true" #REVISIT check owns or descendant + | string "false" #default + } + +## label + aria.prop.label = + attribute aria-label { + string + } + +## labelledby + aria.prop.labelledby = + attribute aria-labelledby { + common.data.idrefs #REVISIT add Schematron check + } + +## level + aria.prop.level = + attribute aria-level { + common.data.integer.positive + } + +## live + aria.prop.live = + attribute aria-live + { string "off" #default + | string "polite" + | string "assertive" + } + +## multiline + aria.prop.multiline = + attribute aria-multiline + { string "true" + | string "false" #default + } + +## multiselectable + aria.prop.multiselectable = + attribute aria-multiselectable + { string "true" + | string "false" #default + } + +## owns + aria.prop.owns = + attribute aria-owns { + common.data.idrefs #REVISIT add Schematron check + } + +## posinset + aria.prop.posinset = + attribute aria-posinset { + common.data.integer.positive + } + +## readonly + aria.prop.readonly = + attribute aria-readonly + { string "true" + | string "false" #default + } + +## relevant + aria.prop.relevant = + attribute aria-relevant + { token "all" + | list + { ( string "additions" ) + , ( string "removals" )? + , ( string "text" )? + } + | list + { ( string "additions" ) + , ( string "text" )? + , ( string "removals" )? + } + | list + { ( string "removals" ) + , ( string "additions" )? + , ( string "text" )? + } + | list + { ( string "removals" ) + , ( string "text" )? + , ( string "additions" )? + } + | list + { ( string "text" ) + , ( string "additions" )? + , ( string "removals" )? + } + | list + { ( string "text" ) + , ( string "removals" )? + , ( string "additions" )? + } + } + +## required + aria.prop.required = + attribute aria-required + { string "true" + | string "false" #default + } + +## setsize + aria.prop.setsize = + attribute aria-setsize { + common.data.integer.non-negative + } + +## sort + aria.prop.sort = + attribute aria-sort + { string "ascending" + | string "descending" + | string "none" #default + | string "other" + } + +## valuemax + aria.prop.valuemax = + attribute aria-valuemax { + common.data.float #REVISIT + } + +## valuemin + aria.prop.valuemin = + attribute aria-valuemin { + common.data.float #REVISIT + } + +## valuenow + aria.prop.valuenow = + attribute aria-valuenow { + common.data.float #REVISIT + } + +## valuetext + aria.prop.valuetext = + attribute aria-valuetext { + string + } + +# ##################################################################### +## Roles + +## alert + aria.alert = + ( aria.role.alert + & aria.state.expanded? + ) + aria.role.alert = + attribute role { string "alert" } + + common.attrs.aria |= aria.alert + +## alertdialog + aria.alertdialog = + ( aria.role.alertdialog + & aria.state.expanded? + ) + aria.role.alertdialog = + attribute role { string "alertdialog" } + + common.attrs.aria |= aria.alertdialog + +## application + aria.application = + ( aria.role.application + & aria.state.expanded? + ) + aria.role.application = + attribute role { string "application" } + + common.attrs.aria |= aria.application + common.attrs.aria.landmark.application |= aria.application + +## article + aria.article = + ( aria.role.article + & aria.state.expanded? + ) + aria.role.article = + attribute role { string "article" } + + common.attrs.aria |= aria.article + common.attrs.aria.landmark.article |= aria.article + +## banner + aria.banner = + ( aria.role.banner + & aria.state.expanded? + ) + aria.role.banner = + attribute role { string "banner" } + + common.attrs.aria |= aria.banner + common.attrs.aria.landmark.banner |= aria.banner + +## button + aria.button = + ( aria.role.button + & aria.state.pressed? # not inherited + ) + aria.role.button = + attribute role { string "button" } + + common.attrs.aria |= aria.button + +## checkbox + aria.checkbox = + ( aria.role.checkbox + & aria.state.checked #required! + ) + aria.role.checkbox = + attribute role { string "checkbox" } + + common.attrs.aria |= aria.checkbox + +# XXX columnheader + +## combobox + aria.combobox = + ( aria.role.combobox + & aria.prop.activedescendant? + & aria.state.expanded #required! + ) + aria.role.combobox = + attribute role { string "combobox" } + + common.attrs.aria |= aria.combobox + +## complementary + aria.complementary = + ( aria.role.complementary + & aria.state.expanded? + ) + aria.role.complementary = + attribute role { string "complementary" } + + common.attrs.aria |= aria.complementary + common.attrs.aria.landmark.complementary |= aria.complementary + +## contentinfo + aria.contentinfo = + ( aria.role.contentinfo + & aria.state.expanded? + ) + aria.role.contentinfo = + attribute role { string "contentinfo" } + + common.attrs.aria |= aria.contentinfo + common.attrs.aria.landmark.contentinfo |= aria.contentinfo + +## definition + aria.definition = + ( aria.role.definition + & aria.state.expanded? + ) + aria.role.definition = + attribute role { string "definition" } + + common.attrs.aria |= aria.definition + +## dialog + aria.dialog = + ( aria.role.dialog + & aria.state.expanded? + ) + aria.role.dialog = + attribute role { string "dialog" } + + common.attrs.aria |= aria.dialog + +## directory + aria.directory = + ( aria.role.directory + & aria.state.expanded? + ) + aria.role.directory = + attribute role { string "directory" } + + common.attrs.aria |= aria.directory + +## document + aria.document = + ( aria.role.document + & aria.state.expanded? + ) + aria.role.document = + attribute role { string "document" } + + common.attrs.aria |= aria.document + common.attrs.aria.landmark.document |= aria.document + +## grid + aria.grid = + ( aria.role.grid + & aria.prop.level? # not inherited + & aria.prop.multiselectable? # not inherited + & aria.prop.readonly? # not inherited + & aria.prop.activedescendant? + & aria.state.expanded? + ) + aria.role.grid = + attribute role { string "grid" } + + common.attrs.aria |= aria.grid + +## gridcell + aria.gridcell = + ( aria.role.gridcell + & aria.prop.level? # net inherited + & aria.prop.readonly? # not inherited + & aria.state.selected? # not inherited + & aria.state.expanded? + ) + aria.role.gridcell = + attribute role { string "gridcell" } + + common.attrs.aria |= aria.gridcell + +## group + aria.group = + ( aria.role.group + & aria.prop.activedescendant? # not inherited + & aria.state.expanded? # not inherited + ) + aria.role.group = + attribute role { string "group" } + + common.attrs.aria |= aria.group + +## XXX heading + +## img + aria.img = + ( aria.role.img + & aria.state.expanded? + ) + aria.role.img = + attribute role { string "img" } + + common.attrs.aria |= aria.img + +## link + aria.link = + ( aria.role.link + ) + aria.role.link = + attribute role { string "link" } + + common.attrs.aria |= aria.link + +## list + aria.list = + ( aria.role.list + & aria.state.expanded? + ) + aria.role.list = + attribute role { string "list" } + + common.attrs.aria |= aria.list + +## listbox + aria.listbox = + ( aria.role.listbox + & aria.prop.multiselectable? # not inherited + & aria.prop.activedescendant? + & aria.state.expanded? + ) + aria.role.listbox = + attribute role { string "listbox" } + + common.attrs.aria |= aria.listbox + +## listitem + aria.listitem = + ( aria.role.listitem + & aria.prop.posinset? # not inherited + & aria.prop.setsize? # not inherited + & aria.prop.level? # not inherited + & aria.state.expanded? + ) + aria.role.listitem = + attribute role { string "listitem" } + + common.attrs.aria |= aria.listitem + +## log + aria.log = + ( aria.role.log + & aria.state.expanded? + ) + aria.role.log = + attribute role { string "log" } + + common.attrs.aria |= aria.log + +## main + aria.main = + ( aria.role.main + & aria.state.expanded? + ) + aria.role.main = + attribute role { string "main" } + + common.attrs.aria |= aria.main + common.attrs.aria.landmark.main |= aria.main + +## marquee + aria.marquee = + ( aria.role.marquee + & aria.state.expanded? + ) + aria.role.marquee = + attribute role { string "marquee" } + + common.attrs.aria |= aria.marquee + +## math + aria.math = + ( aria.role.math + & aria.state.expanded? + ) + aria.role.math = + attribute role { string "math" } + + common.attrs.aria |= aria.math + +## menu + aria.menu = + ( aria.role.menu + & aria.prop.activedescendant? + & aria.state.expanded? + ) + aria.role.menu = + attribute role { string "menu" } + + common.attrs.aria |= aria.menu + +## menubar + aria.menubar = + ( aria.role.menubar + & aria.prop.activedescendant? + & aria.state.expanded? + ) + aria.role.menubar = + attribute role { string "menubar" } + + common.attrs.aria |= aria.menubar + +## menuitem + aria.menuitem = + ( aria.role.menuitem ) + aria.role.menuitem = + attribute role { string "menuitem" } + + common.attrs.aria |= aria.menuitem + +## menuitemcheckbox + aria.menuitemcheckbox = + ( aria.role.menuitemcheckbox + & aria.state.checked #required + ) + aria.role.menuitemcheckbox = + attribute role { string "menuitemcheckbox" } + + common.attrs.aria |= aria.menuitemcheckbox + +## menuitemradio + aria.menuitemradio = + ( aria.role.menuitemradio + & aria.state.checked #required + & aria.state.selected? + ) + aria.role.menuitemradio = + attribute role { string "menuitemradio" } + + common.attrs.aria |= aria.menuitemradio + +## navigation + aria.navigation = + ( aria.role.navigation + & aria.state.expanded? + ) + aria.role.navigation = + attribute role { string "navigation" } + + common.attrs.aria |= aria.navigation + common.attrs.aria.landmark.navigation |= aria.navigation + +## note + aria.note = + ( aria.role.note + & aria.state.expanded? + ) + aria.role.note = + attribute role { string "note" } + + common.attrs.aria |= aria.note + common.attrs.aria.landmark.note |= aria.note + +## option + aria.option = + ( aria.role.option + & aria.state.checked? # not inherited + & aria.state.selected? # not inherited + ) + aria.role.option = + attribute role { string "option" } + + common.attrs.aria |= aria.option + + +## presentation + aria.presentation = + ( aria.role.presentation + & aria.state.expanded? + ) + aria.role.presentation = + attribute role { string "presentation" } + + common.attrs.aria |= aria.presentation + +## progressbar + aria.progressbar = + ( aria.role.progressbar + & aria.prop.valuemax? # not inherited + & aria.prop.valuemin? # not inherited + & aria.prop.valuenow? # not inherited + & aria.prop.valuetext? # not inherited + ) + aria.role.progressbar = + attribute role { string "progressbar" } + + common.attrs.aria |= aria.progressbar + +## radio + aria.radio = + ( aria.role.radio + & aria.state.checked #required! + & aria.state.selected? + ) + aria.role.radio = + attribute role { string "radio" } + + common.attrs.aria |= aria.radio + +## radiogroup + aria.radiogroup = + ( aria.role.radiogroup + & aria.prop.activedescendant? + & aria.state.expanded? + ) + aria.role.radiogroup = + attribute role { string "radiogroup" } + + common.attrs.aria |= aria.radiogroup + +## region + aria.region = + ( aria.role.region + & aria.state.expanded? + ) + aria.role.region = + attribute role { string "region" } + + common.attrs.aria |= aria.region + +## row + aria.row = + ( aria.role.row + & aria.prop.level? # not inherited + & aria.state.selected? # not inherited + & aria.prop.activedescendant? + & aria.state.expanded? + ) + aria.role.row = + attribute role { string "row" } + + common.attrs.aria |= aria.row + +# XXX rowheader + +## search + aria.search = + ( aria.role.search + & aria.state.expanded? + ) + aria.role.search = + attribute role { string "search" } + + common.attrs.aria |= aria.search + common.attrs.aria.landmark.search |= aria.search + +## separator + aria.separator = + ( aria.role.separator + & aria.state.expanded? + ) + aria.role.separator = + attribute role { string "separator" } + + common.attrs.aria |= aria.separator + +## slider + aria.slider = + ( aria.role.slider + & aria.prop.valuemax + & aria.prop.valuemin + & aria.prop.valuenow + & aria.prop.valuetext + ) + aria.role.slider = + attribute role { string "slider" } + + common.attrs.aria |= aria.slider + +## spinbutton + aria.spinbutton = + ( aria.role.spinbutton + & aria.prop.activedescendant? + & aria.prop.valuemax + & aria.prop.valuemin + & aria.prop.valuenow + & aria.prop.valuetext + ) + aria.role.spinbutton = + attribute role { string "spinbutton" } + + common.attrs.aria |= aria.spinbutton + +## status + aria.status = + ( aria.role.status + & aria.prop.activedescendant? + & aria.state.expanded? + ) + aria.role.status = + attribute role { string "status" } + + common.attrs.aria |= aria.status + +## tab + aria.tab = + ( aria.role.tab + & aria.state.selected? + & aria.state.expanded? + ) + aria.role.tab = + attribute role { string "tab" } + + common.attrs.aria |= aria.tab + +## tablist + aria.tablist = + ( aria.role.tablist + & aria.prop.activedescendant? + & aria.state.expanded? + ) + aria.role.tablist = + attribute role { string "tablist" } + +## tabpanel + aria.tabpanel = + ( aria.role.tabpanel + & aria.state.expanded? + ) + aria.role.tabpanel = + attribute role { string "tabpanel" } + + common.attrs.aria |= aria.tabpanel + +## textbox + aria.textbox = + ( aria.role.textbox + & aria.prop.autocomplete? # not inherited + & aria.prop.multiline? # not inherited + & aria.prop.readonly? # not inherited + ) + aria.role.textbox = + attribute role { string "textbox" } + + common.attrs.aria |= aria.textbox + +## timer + aria.timer = + ( aria.role.timer + & aria.prop.activedescendant? + & aria.state.expanded? + ) + aria.role.timer = + attribute role { string "timer" } + + common.attrs.aria |= aria.timer + +## toolbar + aria.toolbar = + ( aria.role.toolbar + & aria.prop.activedescendant? + & aria.state.expanded? + ) + aria.role.toolbar = + attribute role { string "toolbar" } + + common.attrs.aria |= aria.toolbar + +## tooltip + aria.tooltip = + ( aria.role.tooltip + & aria.state.expanded? + ) + aria.role.tooltip = + attribute role { string "tooltip" } + + common.attrs.aria |= aria.tooltip + +## tree + aria.tree = + ( aria.role.tree + & aria.prop.multiselectable? # not inherited + & aria.prop.activedescendant? + & aria.state.expanded? + ) + aria.role.tree = + attribute role { string "tree" } + + common.attrs.aria |= aria.tree + +## treegrid + aria.treegrid = + ( aria.role.treegrid + & aria.prop.activedescendant? + & aria.state.expanded? + & aria.prop.level? + & aria.prop.multiselectable? + & aria.prop.readonly? + ) + aria.role.treegrid = + attribute role { string "treegrid" } + + common.attrs.aria |= aria.treegrid + +## treeitem + aria.treeitem = + ( aria.role.treeitem + & aria.state.checked? + & aria.state.expanded? + & aria.prop.level? + & aria.prop.posinset? + & aria.state.selected? + & aria.prop.setsize? + ) + aria.role.treeitem = + attribute role { string "treeitem" } + + common.attrs.aria |= aria.treeitem + + diff --git a/xml/relaxng/src/resources/html5-schema/block.rnc b/xml/relaxng/src/resources/html5-schema/block.rnc new file mode 100644 index 000000000000..3f4332b23dc9 --- /dev/null +++ b/xml/relaxng/src/resources/html5-schema/block.rnc @@ -0,0 +1,201 @@ +datatypes w = "http://whattf.org/datatype-draft" + +# ##################################################################### +## RELAX NG Schema for HTML 5: Basic Prose Markup # +# ##################################################################### + +# ##################################################################### +## Paragraph-Level + +## Paragraph:

    + + 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.elem = + element hr { hr.inner & hr.attrs } + hr.attrs = + ( common.attrs ) + hr.inner = + ( empty ) + + common.elem.flow |= hr.elem + +# ##################################################################### +## Preformatting Blocks + +## Preformatted Text:
    +
    +	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.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.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.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:
      1. + + 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.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.elem = + element dt { dt.inner & dt.attrs } + dt.attrs = + ( common.attrs + & common.attrs.aria? + ) + dt.inner = + ( common.inner.phrasing ) + +## Definition Description:
        + + 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.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.elem = + element legend { legend.inner & legend.attrs } + legend.attrs = + ( common.attrs + & common.attrs.aria.implicit.region? + ) + legend.inner = + ( common.inner.phrasing ) diff --git a/xml/relaxng/src/resources/html5-schema/common.rnc b/xml/relaxng/src/resources/html5-schema/common.rnc new file mode 100644 index 000000000000..c4f1eb9b0e0b --- /dev/null +++ b/xml/relaxng/src/resources/html5-schema/common.rnc @@ -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 ) + 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