diff options
Diffstat (limited to 'bundles/org.eclipse.wst.html.core/src/org/eclipse/wst/html/core/validate/HTMLElementContentValidator.java')
-rw-r--r-- | bundles/org.eclipse.wst.html.core/src/org/eclipse/wst/html/core/validate/HTMLElementContentValidator.java | 178 |
1 files changed, 178 insertions, 0 deletions
diff --git a/bundles/org.eclipse.wst.html.core/src/org/eclipse/wst/html/core/validate/HTMLElementContentValidator.java b/bundles/org.eclipse.wst.html.core/src/org/eclipse/wst/html/core/validate/HTMLElementContentValidator.java new file mode 100644 index 0000000000..007c225719 --- /dev/null +++ b/bundles/org.eclipse.wst.html.core/src/org/eclipse/wst/html/core/validate/HTMLElementContentValidator.java @@ -0,0 +1,178 @@ +/******************************************************************************* + * Copyright (c) 2004 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.wst.html.core.validate; + +import org.eclipse.wst.common.contentmodel.CMElementDeclaration; +import org.eclipse.wst.sse.core.IndexedRegion; +import org.eclipse.wst.xml.core.document.XMLNode; +import org.eclipse.wst.xml.core.document.XMLText; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +public class HTMLElementContentValidator extends PrimeValidator { + + /** + * HTMLElementContentValidator constructor comment. + */ + public HTMLElementContentValidator() { + super(); + } + + /** + * Allowing the INodeAdapter to compare itself against the type + * allows it to return true in more than one case. + */ + public boolean isAdapterForType(Object type) { + return ((type == HTMLElementContentValidator.class) || super.isAdapterForType(type)); + } + + /** + */ + public void validate(IndexedRegion node) { + Element target = (Element) node; + if (CMUtil.isForeign(target)) + return; + + validateContent(target, target.getChildNodes()); + } + + private void validateContent(Element parent, NodeList children) { + for (int i = 0; i < children.getLength(); i++) { + Node child = children.item(i); + if (child == null) + continue; + + // perform actual validation + validateNode(parent, child); + } + } + +// private int countExplicitSiblings(Element parent, String tagName) { +// NodeList children = parent.getChildNodes(); +// int count = 0; +// for (int i = 0; i < children.getLength(); i++) { +// Node child = children.item(i); +// if (child.getNodeType() != Node.ELEMENT_NODE) +// continue; +// if (tagName.equalsIgnoreCase(((Element) child).getTagName())) { +// count++; +// } +// } +// return count; +// } + + /* The implementation of the following method is practical but accurate. + * The accurate maximum occurence should be retreive from the content model. + * However, it is useful enough, since almost implicit elements are HTML, + * HEAD, or BODY. + */ +// private int getMaxOccur(Element parent, String childTag) { +// return 1; +// } + + private void validateNode(Element target, Node child) { + // NOTE: If the target element is 'UNKNOWN', that is, it has no + // element declaration, the content type of the element should be + // regarded as 'ANY'. -- 9/10/2001 + int contentType = CMElementDeclaration.ANY; + CMElementDeclaration edec = CMUtil.getDeclaration(target); + if (edec != null) + contentType = edec.getContentType(); + + int error = ErrorState.NONE_ERROR; + int segType = FMUtil.SEG_WHOLE_TAG; + + switch (child.getNodeType()) { + case Node.ELEMENT_NODE : + Element childElem = (Element) child; + // Defect 200321: + // This validator cares only HTML/XHTML elements. If a child is + // an element of foreign markup languages, just ignore it. + if (CMUtil.isForeign(childElem)) + return; + + CMElementDeclaration ced = CMUtil.getDeclaration((Element) child); + // Defect 186774: If a child is not one of HTML elements, + // it should be regarded as a valid child regardless the + // type of the parent content model. -- 10/12/2001 + if (ced == null || CMUtil.isSSI(ced) || (!CMUtil.isHTML(ced))) + return; + + switch (contentType) { + case CMElementDeclaration.ANY : + // Keep going. + return; + case CMElementDeclaration.ELEMENT : + case CMElementDeclaration.MIXED : + if (ced == null) + return; + if (CMUtil.isValidChild(edec, ced)) + return; + // Now, it is the time to check inclusion, unless the target + // document is not a XHTML. + if (!CMUtil.isXHTML(edec)) { + // pure HTML + if (CMUtil.isValidInclusion(ced, target)) + return; + } + error = ErrorState.INVALID_CONTENT_ERROR; + break; + default : + error = ErrorState.INVALID_CONTENT_ERROR; + break; + } + // Mark the whole START tag as an error segment. + segType = FMUtil.SEG_START_TAG; + break; + case Node.TEXT_NODE : + switch (contentType) { + case CMElementDeclaration.ANY : + case CMElementDeclaration.MIXED : + case CMElementDeclaration.PCDATA : + case CMElementDeclaration.CDATA : + // D184339 + // Keep going. + return; + case CMElementDeclaration.ELEMENT : + case CMElementDeclaration.EMPTY : + if (((XMLText) child).isWhitespace()) + return; + error = ErrorState.INVALID_CONTENT_ERROR; + break; + default : + error = ErrorState.INVALID_CONTENT_ERROR; + break; + } + // Mark the whole node as an error segment. + segType = FMUtil.SEG_WHOLE_TAG; + break; + case Node.COMMENT_NODE : + case Node.PROCESSING_INSTRUCTION_NODE : + if (contentType != CMElementDeclaration.EMPTY) + return; + error = ErrorState.INVALID_CONTENT_ERROR; + // Mark the whole node as an error segment. + segType = FMUtil.SEG_WHOLE_TAG; + break; + default : + error = ErrorState.INVALID_CONTENT_ERROR; + // Mark the whole node as an error segment. + segType = FMUtil.SEG_WHOLE_TAG; + break; + } + if (error != ErrorState.NONE_ERROR) { + Segment errorSeg = FMUtil.getSegment((XMLNode) child, segType); + if (errorSeg != null) + reporter.report(MessageFactory.createMessage(new ErrorInfoImpl(error, errorSeg, child))); + } + } +}
\ No newline at end of file |