#include "config.h"
#include "core/inspector/DOMPatchSupport.h"
-#include "bindings/v8/ExceptionState.h"
-#include "bindings/v8/ExceptionStatePlaceholder.h"
+#include "bindings/core/v8/ExceptionState.h"
+#include "bindings/core/v8/ExceptionStatePlaceholder.h"
#include "core/dom/Attribute.h"
#include "core/dom/ContextFeatures.h"
#include "core/dom/Document.h"
#include "core/dom/DocumentFragment.h"
#include "core/dom/Node.h"
+#include "core/dom/NodeTraversal.h"
#include "core/dom/XMLDocument.h"
#include "core/html/HTMLBodyElement.h"
#include "core/html/HTMLDocument.h"
#include "core/inspector/DOMEditor.h"
#include "core/inspector/InspectorHistory.h"
#include "core/xml/parser/XMLDocumentParser.h"
+#include "platform/Crypto.h"
+#include "public/platform/Platform.h"
#include "wtf/Deque.h"
#include "wtf/HashTraits.h"
#include "wtf/RefPtr.h"
-#include "wtf/SHA1.h"
#include "wtf/text/Base64.h"
#include "wtf/text/CString.h"
-using namespace std;
-
-namespace WebCore {
+namespace blink {
struct DOMPatchSupport::Digest {
explicit Digest(Node* node) : m_node(node) { }
void DOMPatchSupport::patchDocument(const String& markup)
{
- RefPtr<Document> newDocument;
- if (m_document.isHTMLDocument())
+ RefPtrWillBeRawPtr<Document> newDocument = nullptr;
+ if (document().isHTMLDocument())
newDocument = HTMLDocument::create();
- else if (m_document.isXHTMLDocument())
+ else if (document().isXHTMLDocument())
newDocument = XMLDocument::createXHTML();
- else if (m_document.isXMLDocument())
+ else if (document().isXMLDocument())
newDocument = XMLDocument::create();
ASSERT(newDocument);
- newDocument->setContextFeatures(m_document.contextFeatures());
- RefPtr<DocumentParser> parser;
- if (m_document.isHTMLDocument())
- parser = HTMLDocumentParser::create(toHTMLDocument(newDocument.get()), false);
+ newDocument->setContextFeatures(document().contextFeatures());
+ RefPtrWillBeRawPtr<DocumentParser> parser = nullptr;
+ if (document().isHTMLDocument())
+ parser = HTMLDocumentParser::create(toHTMLDocument(*newDocument), false);
else
- parser = XMLDocumentParser::create(newDocument.get(), 0);
+ parser = XMLDocumentParser::create(*newDocument, 0);
parser->insert(markup); // Use insert() so that the parser will not yield.
parser->finish();
parser->detach();
- OwnPtr<Digest> oldInfo = createDigest(m_document.documentElement(), 0);
+ OwnPtr<Digest> oldInfo = createDigest(document().documentElement(), 0);
OwnPtr<Digest> newInfo = createDigest(newDocument->documentElement(), &m_unusedNodesMap);
if (!innerPatchNode(oldInfo.get(), newInfo.get(), IGNORE_EXCEPTION)) {
// Fall back to rewrite.
- m_document.write(markup);
- m_document.close();
+ document().write(markup);
+ document().close();
}
}
}
Node* previousSibling = node->previousSibling();
- RefPtr<DocumentFragment> fragment = DocumentFragment::create(m_document);
- Node* targetNode = node->parentElementOrShadowRoot() ? node->parentElementOrShadowRoot() : m_document.documentElement();
+ RefPtrWillBeRawPtr<DocumentFragment> fragment = DocumentFragment::create(document());
+ Node* targetNode = node->parentElementOrShadowRoot() ? node->parentElementOrShadowRoot() : document().documentElement();
// Use the document BODY as the context element when editing immediate shadow root children,
// as it provides an equivalent parsing context.
if (targetNode->isShadowRoot())
- targetNode = m_document.body();
+ targetNode = document().body();
Element* targetElement = toElement(targetNode);
// FIXME: This code should use one of createFragment* in markup.h
- if (m_document.isHTMLDocument())
+ if (document().isHTMLDocument())
fragment->parseHTML(markup, targetElement);
else
fragment->parseXML(markup, targetElement);
for (Node* child = parentNode->firstChild(); child != node; child = child->nextSibling())
newList.append(createDigest(child, 0));
for (Node* child = fragment->firstChild(); child; child = child->nextSibling()) {
- if (isHTMLHeadElement(*child) && !child->firstChild() && markupCopy.find("</head>") == kNotFound)
+ if (isHTMLHeadElement(*child) && !child->hasChildren() && markupCopy.find("</head>") == kNotFound)
continue; // HTML5 parser inserts empty <head> tag whenever it parses <body>
- if (isHTMLBodyElement(*child) && !child->firstChild() && markupCopy.find("</body>") == kNotFound)
+ if (isHTMLBodyElement(*child) && !child->hasChildren() && markupCopy.find("</body>") == kNotFound)
continue; // HTML5 parser inserts empty <body> tag whenever it parses </head>
newList.append(createDigest(child, &m_unusedNodesMap));
}
return false;
}
- if (oldNode->nodeType() != Node::ELEMENT_NODE)
+ if (!oldNode->isElementNode())
return true;
// Patch attributes
Element* newElement = toElement(newNode);
if (oldDigest->m_attrsSHA1 != newDigest->m_attrsSHA1) {
// FIXME: Create a function in Element for removing all properties. Take in account whether did/willModifyAttribute are important.
- if (oldElement->hasAttributesWithoutUpdate()) {
- while (oldElement->attributeCount()) {
- const Attribute& attribute = oldElement->attributeItem(0);
- if (!m_domEditor->removeAttribute(oldElement, attribute.localName(), exceptionState))
- return false;
- }
+ while (oldElement->attributesWithoutUpdate().size()) {
+ const Attribute& attribute = oldElement->attributesWithoutUpdate().at(0);
+ if (!m_domEditor->removeAttribute(oldElement, attribute.localName(), exceptionState))
+ return false;
}
// FIXME: Create a function in Element for copying properties. cloneDataFromElement() is close but not enough for this case.
- if (newElement->hasAttributesWithoutUpdate()) {
- size_t numAttrs = newElement->attributeCount();
- for (size_t i = 0; i < numAttrs; ++i) {
- const Attribute& attribute = newElement->attributeItem(i);
- if (!m_domEditor->setAttribute(oldElement, attribute.name().localName(), attribute.value(), exceptionState))
- return false;
- }
+ AttributeCollection attributes = newElement->attributesWithoutUpdate();
+ AttributeCollection::iterator end = attributes.end();
+ for (AttributeCollection::iterator it = attributes.begin(); it != end; ++it) {
+ if (!m_domEditor->setAttribute(oldElement, it->name().localName(), it->value(), exceptionState))
+ return false;
}
}
if (oldIt == oldTable.end() || oldIt->value.size() != 1)
continue;
- newMap[newIt->value[0]] = make_pair(newList[newIt->value[0]].get(), oldIt->value[0]);
- oldMap[oldIt->value[0]] = make_pair(oldList[oldIt->value[0]].get(), newIt->value[0]);
+ newMap[newIt->value[0]] = std::make_pair(newList[newIt->value[0]].get(), oldIt->value[0]);
+ oldMap[oldIt->value[0]] = std::make_pair(oldList[oldIt->value[0]].get(), newIt->value[0]);
}
for (size_t i = 0; newList.size() > 0 && i < newList.size() - 1; ++i) {
size_t j = newMap[i].second + 1;
if (j < oldMap.size() && !oldMap[j].first && newList[i + 1]->m_sha1 == oldList[j]->m_sha1) {
- newMap[i + 1] = make_pair(newList[i + 1].get(), j);
- oldMap[j] = make_pair(oldList[j].get(), i + 1);
+ newMap[i + 1] = std::make_pair(newList[i + 1].get(), j);
+ oldMap[j] = std::make_pair(oldList[j].get(), i + 1);
}
}
size_t j = newMap[i].second - 1;
if (!oldMap[j].first && newList[i - 1]->m_sha1 == oldList[j]->m_sha1) {
- newMap[i - 1] = make_pair(newList[i - 1].get(), j);
- oldMap[j] = make_pair(oldList[j].get(), i - 1);
+ newMap[i - 1] = std::make_pair(newList[i - 1].get(), j);
+ oldMap[j] = std::make_pair(oldList[j].get(), i - 1);
}
}
dumpMap(newMap, "NEW");
#endif
- return make_pair(oldMap, newMap);
+ return std::make_pair(oldMap, newMap);
}
bool DOMPatchSupport::innerPatchChildren(ContainerNode* parentNode, const Vector<OwnPtr<Digest> >& oldList, const Vector<OwnPtr<Digest> >& newList, ExceptionState& exceptionState)
for (size_t i = 0; i < newMap.size(); ++i) {
if (newMap[i].first || merges.contains(newList[i].get()))
continue;
- if (!insertBeforeAndMarkAsUsed(parentNode, newList[i].get(), parentNode->traverseToChildAt(i), exceptionState))
+ if (!insertBeforeAndMarkAsUsed(parentNode, newList[i].get(), NodeTraversal::childAt(*parentNode, i), exceptionState))
return false;
}
for (size_t i = 0; i < oldMap.size(); ++i) {
if (!oldMap[i].first)
continue;
- RefPtr<Node> node = oldMap[i].first->m_node;
- Node* anchorNode = parentNode->traverseToChildAt(oldMap[i].second);
+ RefPtrWillBeRawPtr<Node> node = oldMap[i].first->m_node;
+ Node* anchorNode = NodeTraversal::childAt(*parentNode, oldMap[i].second);
if (node == anchorNode)
continue;
if (isHTMLBodyElement(*node) || isHTMLHeadElement(*node))
return true;
}
-static void addStringToSHA1(SHA1& sha1, const String& string)
+static void addStringToDigestor(blink::WebCryptoDigestor* digestor, const String& string)
{
- CString cString = string.utf8();
- sha1.addBytes(reinterpret_cast<const uint8_t*>(cString.data()), cString.length());
+ digestor->consume(reinterpret_cast<const unsigned char*>(string.utf8().data()), string.length());
}
PassOwnPtr<DOMPatchSupport::Digest> DOMPatchSupport::createDigest(Node* node, UnusedNodesMap* unusedNodesMap)
{
Digest* digest = new Digest(node);
- SHA1 sha1;
+ OwnPtr<blink::WebCryptoDigestor> digestor = createDigestor(HashAlgorithmSha1);
+ DigestValue digestResult;
Node::NodeType nodeType = node->nodeType();
- sha1.addBytes(reinterpret_cast<const uint8_t*>(&nodeType), sizeof(nodeType));
- addStringToSHA1(sha1, node->nodeName());
- addStringToSHA1(sha1, node->nodeValue());
+ digestor->consume(reinterpret_cast<const unsigned char*>(&nodeType), sizeof(nodeType));
+ addStringToDigestor(digestor.get(), node->nodeName());
+ addStringToDigestor(digestor.get(), node->nodeValue());
- if (node->nodeType() == Node::ELEMENT_NODE) {
- Node* child = node->firstChild();
+ if (node->isElementNode()) {
+ Element& element = toElement(*node);
+ Node* child = element.firstChild();
while (child) {
OwnPtr<Digest> childInfo = createDigest(child, unusedNodesMap);
- addStringToSHA1(sha1, childInfo->m_sha1);
+ addStringToDigestor(digestor.get(), childInfo->m_sha1);
child = child->nextSibling();
digest->m_children.append(childInfo.release());
}
- Element* element = toElement(node);
-
- if (element->hasAttributesWithoutUpdate()) {
- size_t numAttrs = element->attributeCount();
- SHA1 attrsSHA1;
- for (size_t i = 0; i < numAttrs; ++i) {
- const Attribute& attribute = element->attributeItem(i);
- addStringToSHA1(attrsSHA1, attribute.name().toString());
- addStringToSHA1(attrsSHA1, attribute.value());
+
+ AttributeCollection attributes = element.attributesWithoutUpdate();
+ if (!attributes.isEmpty()) {
+ OwnPtr<blink::WebCryptoDigestor> attrsDigestor = createDigestor(HashAlgorithmSha1);
+ AttributeCollection::iterator end = attributes.end();
+ for (AttributeCollection::iterator it = attributes.begin(); it != end; ++it) {
+ addStringToDigestor(attrsDigestor.get(), it->name().toString());
+ addStringToDigestor(attrsDigestor.get(), it->value().string());
}
- Vector<uint8_t, 20> attrsHash;
- attrsSHA1.computeHash(attrsHash);
- digest->m_attrsSHA1 = base64Encode(reinterpret_cast<const char*>(attrsHash.data()), 10);
- addStringToSHA1(sha1, digest->m_attrsSHA1);
+ finishDigestor(attrsDigestor.get(), digestResult);
+ digest->m_attrsSHA1 = base64Encode(reinterpret_cast<const char*>(digestResult.data()), 10);
+ addStringToDigestor(digestor.get(), digest->m_attrsSHA1);
+ digestResult.clear();
}
}
+ finishDigestor(digestor.get(), digestResult);
+ digest->m_sha1 = base64Encode(reinterpret_cast<const char*>(digestResult.data()), 10);
- Vector<uint8_t, 20> hash;
- sha1.computeHash(hash);
- digest->m_sha1 = base64Encode(reinterpret_cast<const char*>(hash.data()), 10);
if (unusedNodesMap)
unusedNodesMap->add(digest->m_sha1, digest);
return adoptPtr(digest);
bool DOMPatchSupport::removeChildAndMoveToNew(Digest* oldDigest, ExceptionState& exceptionState)
{
- RefPtr<Node> oldNode = oldDigest->m_node;
+ RefPtrWillBeRawPtr<Node> oldNode = oldDigest->m_node;
if (!m_domEditor->removeChild(oldNode->parentNode(), oldNode.get(), exceptionState))
return false;
}
#endif
-} // namespace WebCore
+} // namespace blink