/** * @param containingHtmlElement the name of the HTML element containing el. If the HTML element is * contained inside a template construct then this name may differ from el's immediate parent. */ private void inspectElement(JobEnvelope source, Element el, ElKey containingHtmlElement) { ElKey elKey = ElKey.forElement(el); // Recurse early so that ihtml:dynamic elements have been parsed before we // process the attributes element list. for (Node child : Nodes.childrenOf(el)) { inspect(source, child, elKey); } // For each attribute allowed on this element type, ensure that // (1) If it is not specified, and its default value is not allowed, then // it is added with a known safe value. // (2) Its value is rewritten as appropriate. // We don't have to worry about disallowed attributes since those will // not be present in scriptsPerNode. The TemplateSanitizer should have // stripped those out. The TemplateSanitizer should also have stripped out // disallowed elements. if (!htmlSchema.isElementAllowed(elKey)) { return; } HTML.Element elInfo = htmlSchema.lookupElement(elKey); List<HTML.Attribute> attrs = elInfo.getAttributes(); if (attrs != null) { for (HTML.Attribute a : attrs) { AttribKey attrKey = a.getKey(); if (!htmlSchema.isAttributeAllowed(attrKey)) { continue; } Attr attr = null; String aUri = attrKey.ns.uri; String aName = attrKey.localName; Attr unsafe = el.getAttributeNodeNS(aUri, aName); if (unsafe != null && a.getValueCriterion().accept(unsafe.getValue())) { attr = unsafe; } else if ((a.getDefaultValue() != null && !a.getValueCriterion().accept(a.getDefaultValue())) || !a.isOptional()) { attr = el.getOwnerDocument().createAttributeNS(aUri, aName); String safeValue; if (a.getType() == HTML.Attribute.Type.URI) { safeValue = "" + Nodes.getFilePositionFor(el).source().getUri(); } else { safeValue = a.getSafeValue(); } if (safeValue == null) { mq.addMessage( IhtmlMessageType.MISSING_ATTRIB, Nodes.getFilePositionFor(el), elKey, attrKey); continue; } attr.setNodeValue(safeValue); el.setAttributeNodeNS(attr); } if (attr != null) { inspectHtmlAttribute(source, attr, a); } } } scriptsPerNode.put(el, null); }
/** * Examines the HTML document and writes messages about problematic portions to the message queue * passed to the constructor. */ private void inspect() { if (!mq.hasMessageAtLevel(MessageLevel.FATAL_ERROR)) { for (IhtmlRoot ihtmlRoot : ihtmlRoots) { HtmlEmbeddedContentFinder finder = new HtmlEmbeddedContentFinder(htmlSchema, ihtmlRoot.baseUri, mq, mc); for (EmbeddedContent c : finder.findEmbeddedContent(ihtmlRoot.root)) { Node src = c.getSource(); if (src instanceof Attr) { embeddedContent.put((Attr) src, c); } } inspect(ihtmlRoot.source, ihtmlRoot.root, ElKey.forHtmlElement("div")); } } }
static AttribKey attrKey(String elQName, String aQName) { return AttribKey.forAttribute( Namespaces.HTML_DEFAULT, ElKey.forElement(Namespaces.HTML_DEFAULT, elQName), aQName); }
static ElKey elKey(String qname) { return ElKey.forElement(Namespaces.HTML_DEFAULT, qname); }