void Element::cloneAttributesFromElement(const Element& other) { other.synchronizeAllAttributes(); if (!other.m_elementData) { m_elementData.clear(); return; } const AtomicString& oldID = getIdAttribute(); const AtomicString& newID = other.getIdAttribute(); if (!oldID.isNull() || !newID.isNull()) updateId(oldID, newID); // If 'other' has a mutable ElementData, convert it to an immutable one so we can share it between both elements. // We can only do this if there are no presentation attributes and sharing the data won't result in different case sensitivity of class or id. if (other.m_elementData->isUnique()) const_cast<Element&>(other).m_elementData = toUniqueElementData(other.m_elementData)->makeShareableCopy(); if (!other.m_elementData->isUnique()) m_elementData = other.m_elementData; else m_elementData = other.m_elementData->makeUniqueCopy(); AttributeCollection attributes = m_elementData->attributes(); AttributeCollection::iterator end = attributes.end(); for (AttributeCollection::iterator it = attributes.begin(); it != end; ++it) attributeChangedFromParserOrByCloning(it->name(), it->value(), ModifiedByCloning); }
bool ElementData::isEquivalent(const ElementData* other) const { AttributeCollection attributes = this->attributes(); if (!other) return attributes.isEmpty(); AttributeCollection otherAttributes = other->attributes(); if (attributes.size() != otherAttributes.size()) return false; AttributeCollection::iterator end = attributes.end(); for (AttributeCollection::iterator it = attributes.begin(); it != end; ++it) { const Attribute* otherAttr = otherAttributes.find(it->name()); if (!otherAttr || it->value() != otherAttr->value()) return false; } return true; }
// TODO(yosin): We should utilize |MarkupFormatter| here to share code, // especially escaping attribute values, done by |WebEntities| |m_htmlEntities| // and |m_xmlEntities|. void WebPageSerializerImpl::openTagToString(Element* element, SerializeDomParam* param) { bool needSkip; StringBuilder result; // Do pre action for open tag. result.append(preActionBeforeSerializeOpenTag(element, param, &needSkip)); if (needSkip) return; // Add open tag result.append('<'); result.append(element->nodeName().lower()); // Go through all attributes and serialize them. AttributeCollection attributes = element->attributes(); AttributeCollection::iterator end = attributes.end(); for (AttributeCollection::iterator it = attributes.begin(); it != end; ++it) { result.append(' '); // Add attribute pair result.append(it->name().toString()); result.appendLiteral("=\""); if (!it->value().isEmpty()) { const String& attrValue = it->value(); // Check whether we need to replace some resource links // with local resource paths. const QualifiedName& attrName = it->name(); if (element->hasLegalLinkAttribute(attrName)) { // For links start with "javascript:", we do not change it. if (attrValue.startsWith("javascript:", TextCaseInsensitive)) { result.append(m_htmlEntities.convertEntitiesInString(attrValue)); } else { // Get the absolute link WebLocalFrameImpl* subFrame = WebLocalFrameImpl::fromFrameOwnerElement(element); String completeURL = subFrame ? subFrame->frame()->document()->url() : param->document->completeURL(attrValue); // Check whether we have local files for those link. if (m_localLinks.contains(completeURL)) { if (!param->directoryName.isEmpty()) { result.appendLiteral("./"); result.append(param->directoryName); result.append('/'); } result.append(m_htmlEntities.convertEntitiesInString(m_localLinks.get(completeURL))); } else { result.append(m_htmlEntities.convertEntitiesInString(completeURL)); } } } else { if (param->isHTMLDocument) result.append(m_htmlEntities.convertEntitiesInString(attrValue)); else result.append(m_xmlEntities.convertEntitiesInString(attrValue)); } } result.append('\"'); } // Do post action for open tag. String addedContents = postActionAfterSerializeOpenTag(element, param); // Complete the open tag for element when it has child/children. if (element->hasChildren() || param->haveAddedContentsBeforeEnd) result.append('>'); // Append the added contents generate in post action of open tag. result.append(addedContents); // Save the result to data buffer. saveHTMLContentToBuffer(result.toString(), param); }