void MarkupFormatter::appendAttribute(StringBuilder& result, const Element& element, const Attribute& attribute, Namespaces* namespaces) { bool documentIsHTML = serializeAsHTMLDocument(element); QualifiedName prefixedName = attribute.name(); if (documentIsHTML && !attributeIsInSerializedNamespace(attribute)) { result.append(' '); result.append(attribute.name().localName()); } else { if (attribute.namespaceURI() == XMLNSNames::xmlnsNamespaceURI) { if (!attribute.prefix() && attribute.localName() != xmlnsAtom) prefixedName.setPrefix(xmlnsAtom); if (namespaces) { // Account for the namespace attribute we're about to append. const AtomicString& lookupKey = (!attribute.prefix()) ? emptyAtom : attribute.localName(); namespaces->set(lookupKey, attribute.value()); } } else if (attribute.namespaceURI() == XMLNames::xmlNamespaceURI) { if (!attribute.prefix()) prefixedName.setPrefix(xmlAtom); } else { if (attribute.namespaceURI() == XLinkNames::xlinkNamespaceURI) { if (!attribute.prefix()) prefixedName.setPrefix(xlinkAtom); } if (namespaces && shouldAddNamespaceAttribute(attribute, element)) { if (!prefixedName.prefix()) { // This behavior is in process of being standardized. See crbug.com/248044 and https://www.w3.org/Bugs/Public/show_bug.cgi?id=24208 String prefixPrefix("ns", 2); for (unsigned i = attribute.namespaceURI().impl()->existingHash(); ; ++i) { AtomicString newPrefix(String(prefixPrefix + String::number(i))); AtomicString foundURI = namespaces->get(newPrefix); if (foundURI == attribute.namespaceURI() || foundURI == nullAtom) { // We already generated a prefix for this namespace. prefixedName.setPrefix(newPrefix); break; } } } ASSERT(prefixedName.prefix()); appendNamespace(result, prefixedName.prefix(), attribute.namespaceURI(), *namespaces); } } result.append(' '); result.append(prefixedName.toString()); } result.append('='); if (element.isURLAttribute(attribute)) { appendQuotedURLAttributeValue(result, element, attribute); } else { result.append('"'); appendAttributeValue(result, attribute.value(), documentIsHTML); result.append('"'); } }
void SVGLangSpace::addSupportedAttributes(HashSet<QualifiedName>& supportedAttributes) { DEFINE_STATIC_LOCAL(AtomicString, xmlPrefix, ("xml", AtomicString::ConstructFromLiteral)); QualifiedName langWithPrefix = XMLNames::langAttr; langWithPrefix.setPrefix(xmlPrefix); supportedAttributes.add(langWithPrefix); supportedAttributes.add(XMLNames::langAttr); QualifiedName spaceWithPrefix = XMLNames::spaceAttr; spaceWithPrefix.setPrefix(xmlPrefix); supportedAttributes.add(spaceWithPrefix); supportedAttributes.add(XMLNames::spaceAttr); }
void SVGLangSpace::addSupportedAttributes(HashSet<QualifiedName>& supportedAttributes) { static NeverDestroyed<AtomicString> xmlPrefix("xml", AtomicString::ConstructFromLiteral); QualifiedName langWithPrefix = XMLNames::langAttr; langWithPrefix.setPrefix(xmlPrefix); supportedAttributes.add(langWithPrefix); supportedAttributes.add(XMLNames::langAttr); QualifiedName spaceWithPrefix = XMLNames::spaceAttr; spaceWithPrefix.setPrefix(xmlPrefix); supportedAttributes.add(spaceWithPrefix); supportedAttributes.add(XMLNames::spaceAttr); }
void SVGURIReference::addSupportedAttributes(HashSet<QualifiedName>& supportedAttributes) { DEFINE_STATIC_LOCAL(AtomicString, xlinkPrefix, ("xlink")); QualifiedName hrefWithPrefix = XLinkNames::hrefAttr; hrefWithPrefix.setPrefix(xlinkPrefix); supportedAttributes.add(hrefWithPrefix); supportedAttributes.add(XLinkNames::hrefAttr); }
void MarkupAccumulator::appendAttribute(StringBuilder& result, const Element& element, const Attribute& attribute, Namespaces* namespaces) { bool documentIsHTML = serializeAsHTMLDocument(element); result.append(' '); QualifiedName prefixedName = attribute.name(); if (documentIsHTML && !attributeIsInSerializedNamespace(attribute)) { result.append(attribute.name().localName()); } else { if (attribute.namespaceURI() == XLinkNames::xlinkNamespaceURI) { if (!attribute.prefix()) prefixedName.setPrefix(xlinkAtom); } else if (attribute.namespaceURI() == XMLNames::xmlNamespaceURI) { if (!attribute.prefix()) prefixedName.setPrefix(xmlAtom); } else if (attribute.namespaceURI() == XMLNSNames::xmlnsNamespaceURI) { if (attribute.name() != XMLNSNames::xmlnsAttr && !attribute.prefix()) prefixedName.setPrefix(xmlnsAtom); } result.append(prefixedName.toString()); } result.append('='); if (element.isURLAttribute(attribute)) { appendQuotedURLAttributeValue(result, element, attribute); } else { result.append('"'); appendAttributeValue(result, attribute.value(), documentIsHTML); result.append('"'); } if (!documentIsHTML && namespaces && shouldAddNamespaceAttribute(attribute, *namespaces)) appendNamespace(result, prefixedName.prefix(), prefixedName.namespaceURI(), *namespaces); }
void MarkupAccumulator::generateUniquePrefix(QualifiedName& prefixedName, const Namespaces& namespaces) { // http://www.w3.org/TR/DOM-Level-3-Core/namespaces-algorithms.html#normalizeDocumentAlgo // Find a prefix following the pattern "NS" + index (starting at 1) and make sure this // prefix is not declared in the current scope. StringBuilder builder; do { builder.clear(); builder.append("NS"); builder.appendNumber(++m_prefixLevel); const AtomicString& name = builder.toAtomicString(); if (!namespaces.get(name.impl())) { prefixedName.setPrefix(name); return; } } while (true); }
void MarkupAccumulator::appendAttribute(StringBuilder& result, const Element& element, const Attribute& attribute, Namespaces* namespaces) { bool documentIsHTML = element.document().isHTMLDocument(); result.append(' '); QualifiedName prefixedName = attribute.name(); if (documentIsHTML && !attributeIsInSerializedNamespace(attribute)) result.append(attribute.name().localName()); else { if (!attribute.namespaceURI().isEmpty()) { AtomicStringImpl* foundNS = namespaces && attribute.prefix().impl() ? namespaces->get(attribute.prefix().impl()) : 0; bool prefixIsAlreadyMappedToOtherNS = foundNS && foundNS != attribute.namespaceURI().impl(); if (attribute.prefix().isEmpty() || !foundNS || prefixIsAlreadyMappedToOtherNS) { if (AtomicStringImpl* prefix = namespaces ? namespaces->get(attribute.namespaceURI().impl()) : 0) prefixedName.setPrefix(AtomicString(prefix)); else { bool shouldBeDeclaredUsingAppendNamespace = !attribute.prefix().isEmpty() && !foundNS; if (!shouldBeDeclaredUsingAppendNamespace && attribute.localName() != xmlnsAtom && namespaces) generateUniquePrefix(prefixedName, *namespaces); } } } result.append(prefixedName.toString()); } result.append('='); if (element.isURLAttribute(attribute)) appendQuotedURLAttributeValue(result, element, attribute); else { result.append('"'); appendAttributeValue(result, attribute.value(), documentIsHTML); result.append('"'); } if ((inXMLFragmentSerialization() || !documentIsHTML) && namespaces && shouldAddNamespaceAttribute(attribute, *namespaces)) appendNamespace(result, prefixedName.prefix(), prefixedName.namespaceURI(), *namespaces); }