+2013-10-05 Sam Weinig <sam@webkit.org>
+
+ CTTE: Thread references through markup.h
+ https://bugs.webkit.org/show_bug.cgi?id=122403
+
+ Reviewed by Darin Adler and Andreas Kling.
+
+ Highlights:
+ - Removed createFragmentFromMarkupWithContext(), it was unused.
+ - Moved createFragmentFromNodes() into its one caller (in WebKit/mac)
+ - Add a bunch more toFoo() overloads.
+
2013-10-06 Zan Dobersek <zdobersek@igalia.com>
[WebIDL] Annotate IDL interfaces under Source/WebCore/Modules/ with the OperationsNotDeletable attribute
__ZN7WebCore12TextIteratorD1Ev
__ZN7WebCore12UTF8EncodingEv
__ZN7WebCore12cacheStorageEv
-__ZN7WebCore12createMarkupEPKNS_5RangeEPN3WTF6VectorIPNS_4NodeELm0ENS3_15CrashOnOverflowEEENS_23EAnnotateForInterchangeEbNS_13EAbsoluteURLsE
__ZN7WebCore12deleteCookieERKNS_21NetworkStorageSessionERKNS_3URLERKN3WTF6StringE
__ZN7WebCore12gcControllerEv
__ZN7WebCore12iconDatabaseEv
__ZN7WebCore16VisibleSelectionC1EPKNS_5RangeENS_9EAffinityEb
__ZN7WebCore16VisibleSelectionC1ERKNS_15VisiblePositionES3_b
__ZN7WebCore16VisibleSelectionC1ERKNS_15VisiblePositionEb
-__ZN7WebCore16createFullMarkupEPKNS_4NodeE
-__ZN7WebCore16createFullMarkupEPKNS_5RangeE
+__ZN7WebCore16createFullMarkupERKNS_4NodeE
+__ZN7WebCore16createFullMarkupERKNS_5RangeE
__ZN7WebCore16deleteAllCookiesERKNS_21NetworkStorageSessionE
__ZN7WebCore16enclosingIntRectERK6CGRect
__ZN7WebCore16enclosingIntRectERKNS_9FloatRectE
__ZN7WebCore23MutableStylePropertySet25ensureCSSStyleDeclarationEv
__ZN7WebCore23MutableStylePropertySetD1Ev
__ZN7WebCore23SynchronousLoaderClient24platformBadResponseErrorEv
-__ZN7WebCore23createFragmentFromNodesEPNS_8DocumentERKN3WTF6VectorIPNS_4NodeELm0ENS2_15CrashOnOverflowEEE
__ZN7WebCore23dataForURLComponentTypeEP5NSURLl
__ZN7WebCore23decodeHostNameWithRangeEP8NSString8_NSRange
__ZN7WebCore23encodeHostNameWithRangeEP8NSString8_NSRange
__ZN7WebCore24FrameDestructionObserver14willDetachPageEv
__ZN7WebCore24FrameDestructionObserverC2EPNS_5FrameE
__ZN7WebCore24FrameDestructionObserverD2Ev
-__ZN7WebCore24createFragmentFromMarkupEPNS_8DocumentERKN3WTF6StringES5_NS_19ParserContentPolicyE
+__ZN7WebCore24createFragmentFromMarkupERNS_8DocumentERKN3WTF6StringES5_NS_19ParserContentPolicyE
__ZN7WebCore24decodeURLEscapeSequencesERKN3WTF6StringE
__ZN7WebCore24deleteCookiesForHostnameERKNS_21NetworkStorageSessionERKN3WTF6StringE
__ZN7WebCore24fileSystemRepresentationERKN3WTF6StringE
__ZN7WebCore28encodeWithURLEscapeSequencesERKN3WTF6StringE
__ZN7WebCore28removeLanguageChangeObserverEPv
__ZN7WebCore29cookieRequestHeaderFieldValueERKNS_21NetworkStorageSessionERKNS_3URLES5_
+__ZN7WebCore29createDefaultParagraphElementERNS_8DocumentE
__ZN7WebCore29isCharacterSmartReplaceExemptEib
__ZN7WebCore30hostNameNeedsDecodingWithRangeEP8NSString8_NSRange
__ZN7WebCore30hostNameNeedsEncodingWithRangeEP8NSString8_NSRange
1C11CCC80AA6093700DADB20 /* DOMHTMLElement.h in Copy Generated Headers */ = {isa = PBXBuildFile; fileRef = 85DF2EEB0AA387CB00AD64C5 /* DOMHTMLElement.h */; };
1C26497A0D7E248A00BD10F2 /* DocumentLoaderMac.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1C2649790D7E248A00BD10F2 /* DocumentLoaderMac.cpp */; };
1C26497C0D7E24EC00BD10F2 /* PageMac.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1C26497B0D7E24EC00BD10F2 /* PageMac.cpp */; };
- 1C4C8F020AD85D87009475CE /* DeleteButtonController.h in Headers */ = {isa = PBXBuildFile; fileRef = 1C4C8F000AD85D87009475CE /* DeleteButtonController.h */; };
+ 1C4C8F020AD85D87009475CE /* DeleteButtonController.h in Headers */ = {isa = PBXBuildFile; fileRef = 1C4C8F000AD85D87009475CE /* DeleteButtonController.h */; settings = {ATTRIBUTES = (Private, ); }; };
1C4C8F660AD8655D009475CE /* DeleteButton.h in Headers */ = {isa = PBXBuildFile; fileRef = 1C4C8F640AD8655D009475CE /* DeleteButton.h */; };
1C5FAED10DCFD90100D58F78 /* JSJavaScriptCallFrame.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1C5FAECF0DCFD90100D58F78 /* JSJavaScriptCallFrame.cpp */; };
1C5FAED20DCFD90100D58F78 /* JSJavaScriptCallFrame.h in Headers */ = {isa = PBXBuildFile; fileRef = 1C5FAED00DCFD90100D58F78 /* JSJavaScriptCallFrame.h */; };
- (DOMDocumentFragment *)createDocumentFragmentWithMarkupString:(NSString *)markupString baseURL:(NSURL *)baseURL
{
- return kit(createFragmentFromMarkup(core(self), markupString, [baseURL absoluteString]).get());
+ return kit(createFragmentFromMarkup(*core(self), markupString, [baseURL absoluteString]).get());
}
- (DOMDocumentFragment *)createDocumentFragmentWithText:(NSString *)text
virtual PassRefPtr<Text> virtualCreate(const String&);
};
+inline bool isCDATASection(const Node& node)
+{
+ return node.nodeType() == Node::CDATA_SECTION_NODE;
+}
+
+NODE_TYPE_CASTS(CDATASection)
+
} // namespace WebCore
#endif // CDATASection_h
namespace WebCore {
-class Comment FINAL : public CharacterData {
+class Comment final : public CharacterData {
public:
static PassRefPtr<Comment> create(Document&, const String&);
virtual bool childTypeAllowed(NodeType) const;
};
+inline bool isComment(const Node& node)
+{
+ return node.nodeType() == Node::COMMENT_NODE;
+}
+
+NODE_TYPE_CASTS(Comment)
+
} // namespace WebCore
#endif // Comment_h
String resultMIMEType;
String newSource;
String resultEncoding;
- if (!processor->transformToString(this, resultMIMEType, newSource, resultEncoding))
+ if (!processor->transformToString(*this, resultMIMEType, newSource, resultEncoding))
return;
// FIXME: If the transform failed we should probably report an error (like Mozilla does).
Frame* ownerFrame = frame();
}
#endif
-inline Document* toDocument(ScriptExecutionContext* scriptExecutionContext)
-{
- ASSERT_WITH_SECURITY_IMPLICATION(!scriptExecutionContext || scriptExecutionContext->isDocument());
- return static_cast<Document*>(scriptExecutionContext);
-}
-
-inline const Document* toDocument(const ScriptExecutionContext* scriptExecutionContext)
-{
- ASSERT_WITH_SECURITY_IMPLICATION(!scriptExecutionContext || scriptExecutionContext->isDocument());
- return static_cast<const Document*>(scriptExecutionContext);
-}
-
-inline Document* toDocument(Node* node)
-{
- ASSERT_WITH_SECURITY_IMPLICATION(!node || node->isDocumentNode());
- return static_cast<Document*>(node);
-}
-
-inline const Document* toDocument(const Node* node)
-{
- ASSERT_WITH_SECURITY_IMPLICATION(!node || node->isDocumentNode());
- return static_cast<const Document*>(node);
-}
-
-// This will catch anyone doing an unnecessary cast.
-void toDocument(const Document*);
-
// Put these methods here, because they require the Document definition, but we really want to inline them.
inline bool Node::isDocumentNode() const
Element* eventTargetElementForDocument(Document*);
+inline Document* toDocument(ScriptExecutionContext* scriptExecutionContext)
+{
+ ASSERT_WITH_SECURITY_IMPLICATION(!scriptExecutionContext || scriptExecutionContext->isDocument());
+ return static_cast<Document*>(scriptExecutionContext);
+}
+
+inline const Document* toDocument(const ScriptExecutionContext* scriptExecutionContext)
+{
+ ASSERT_WITH_SECURITY_IMPLICATION(!scriptExecutionContext || scriptExecutionContext->isDocument());
+ return static_cast<const Document*>(scriptExecutionContext);
+}
+
+inline bool isDocument(const Node& node)
+{
+ return node.isDocumentNode();
+}
+
+NODE_TYPE_CASTS(Document)
+
} // namespace WebCore
namespace WTF {
String m_subset;
};
+inline bool isDocumentType(const Node& node)
+{
+ return node.nodeType() == Node::DOCUMENT_TYPE_NODE;
+}
+
+NODE_TYPE_CASTS(DocumentType)
+
} // namespace WebCore
#endif
return parentNode();
}
-} //namespace
+#define NODE_TYPE_CASTS(NodeClassName) \
+inline const NodeClassName* to##NodeClassName(const Node* node) \
+{ \
+ ASSERT_WITH_SECURITY_IMPLICATION(!node || is##NodeClassName(*node)); \
+ return static_cast<const NodeClassName*>(node); \
+} \
+inline NodeClassName* to##NodeClassName(Node* node) \
+{ \
+ ASSERT_WITH_SECURITY_IMPLICATION(!node || is##NodeClassName(*node)); \
+ return static_cast<NodeClassName*>(node); \
+} \
+inline const NodeClassName& to##NodeClassName(const Node& node) \
+{ \
+ ASSERT_WITH_SECURITY_IMPLICATION(is##NodeClassName(node)); \
+ return static_cast<const NodeClassName&>(node); \
+} \
+inline NodeClassName& to##NodeClassName(Node& node) \
+{ \
+ ASSERT_WITH_SECURITY_IMPLICATION(is##NodeClassName(node)); \
+ return static_cast<NodeClassName&>(node); \
+} \
+void to##NodeClassName(const NodeClassName*); \
+void to##NodeClassName(const NodeClassName&);
+
+} // namespace WebCore
#ifndef NDEBUG
// Outside the WebCore namespace for ease of invocation from gdb.
class StyleSheet;
class CSSStyleSheet;
-class ProcessingInstruction FINAL : public CharacterData, private CachedStyleSheetClient {
+class ProcessingInstruction final : public CharacterData, private CachedStyleSheetClient {
public:
static PassRefPtr<ProcessingInstruction> create(Document&, const String& target, const String& data);
virtual ~ProcessingInstruction();
#endif
};
-inline ProcessingInstruction* toProcessingInstruction(Node* node)
+inline bool isProcessingInstruction(const Node& node)
{
- ASSERT_WITH_SECURITY_IMPLICATION(!node || node->nodeType() == Node::PROCESSING_INSTRUCTION_NODE);
- return static_cast<ProcessingInstruction*>(node);
+ return node.nodeType() == Node::PROCESSING_INSTRUCTION_NODE;
}
+NODE_TYPE_CASTS(ProcessingInstruction)
+
} //namespace
#endif
String Range::toHTML() const
{
- return createMarkup(this);
+ return createMarkup(*this);
}
String Range::text() const
String ShadowRoot::innerHTML() const
{
- return createMarkup(this, ChildrenOnly);
+ return createMarkup(*this, ChildrenOnly);
}
void ShadowRoot::setInnerHTML(const String& markup, ExceptionCode& ec)
return elementData()->presentationAttributeStyle();
}
+inline bool isStyledElement(const Node& node) { return node.isStyledElement(); }
+
+ELEMENT_TYPE_CASTS(StyledElement)
+
} //namespace
#endif
#endif
};
-inline Text& toText(Node& node)
+inline bool isText(const Node& node)
{
- ASSERT_WITH_SECURITY_IMPLICATION(node.isTextNode());
- return static_cast<Text&>(node);
+ return node.isTextNode();
}
-inline Text* toText(Node* node)
-{
- ASSERT_WITH_SECURITY_IMPLICATION(!node || node->isTextNode());
- return static_cast<Text*>(node);
-}
-
-inline const Text* toText(const Node* node)
-{
- ASSERT_WITH_SECURITY_IMPLICATION(!node || node->isTextNode());
- return static_cast<const Text*>(node);
-}
-
-void toText(const Text&);
-void toText(const Text*);
+NODE_TYPE_CASTS(Text)
} // namespace WebCore
RefPtr<DocumentFragment> fragment;
// This used to use a ternary for initialization, but that confused some versions of GCC, see bug 37912
if (startOfParagraphToMove != endOfParagraphToMove)
- fragment = createFragmentFromMarkup(&document(), createMarkup(range.get(), 0, DoNotAnnotateForInterchange, true), "");
+ fragment = createFragmentFromMarkup(document(), createMarkup(*range, 0, DoNotAnnotateForInterchange, true), "");
// A non-empty paragraph's style is moved when we copy and move it. We don't move
// anything if we're given an empty paragraph, but an empty paragraph can have style
static bool executeInsertHTML(Frame& frame, Event*, EditorCommandSource, const String& value)
{
- return executeInsertFragment(frame, createFragmentFromMarkup(frame.document(), value, ""));
+ return executeInsertFragment(frame, createFragmentFromMarkup(*frame.document(), value, ""));
}
static bool executeInsertImage(Frame& frame, Event*, EditorCommandSource, const String& value)
{
}
-String MarkupAccumulator::serializeNodes(Node* targetNode, Node* nodeToSkip, EChildrenOnly childrenOnly)
-{
- return serializeNodes(targetNode, nodeToSkip, childrenOnly, 0);
-}
-
-String MarkupAccumulator::serializeNodes(Node* targetNode, Node* nodeToSkip, EChildrenOnly childrenOnly, Vector<QualifiedName>* tagNamesToSkip)
+String MarkupAccumulator::serializeNodes(Node& targetNode, Node* nodeToSkip, EChildrenOnly childrenOnly, Vector<QualifiedName>* tagNamesToSkip)
{
serializeNodesWithNamespaces(targetNode, nodeToSkip, childrenOnly, 0, tagNamesToSkip);
return m_markup.toString();
}
-void MarkupAccumulator::serializeNodesWithNamespaces(Node* targetNode, Node* nodeToSkip, EChildrenOnly childrenOnly, const Namespaces* namespaces, Vector<QualifiedName>* tagNamesToSkip)
+void MarkupAccumulator::serializeNodesWithNamespaces(Node& targetNode, Node* nodeToSkip, EChildrenOnly childrenOnly, const Namespaces* namespaces, Vector<QualifiedName>* tagNamesToSkip)
{
- if (targetNode == nodeToSkip)
+ if (&targetNode == nodeToSkip)
return;
- if (tagNamesToSkip) {
+ if (tagNamesToSkip && targetNode.isElementNode()) {
for (size_t i = 0; i < tagNamesToSkip->size(); ++i) {
- if (targetNode->hasTagName(tagNamesToSkip->at(i)))
+ if (targetNode.hasTagName(tagNamesToSkip->at(i)))
return;
}
}
if (!childrenOnly)
appendStartTag(targetNode, &namespaceHash);
- if (!(targetNode->document().isHTMLDocument() && elementCannotHaveEndTag(targetNode))) {
+ if (!(targetNode.document().isHTMLDocument() && elementCannotHaveEndTag(targetNode))) {
#if ENABLE(TEMPLATE_ELEMENT)
- Node* current = targetNode->hasTagName(templateTag) ? toHTMLTemplateElement(targetNode)->content()->firstChild() : targetNode->firstChild();
+ Node* current = targetNode.hasTagName(templateTag) ? toHTMLTemplateElement(targetNode).content()->firstChild() : targetNode.firstChild();
#else
- Node* current = targetNode->firstChild();
+ Node* current = targetNode.firstChild();
#endif
for ( ; current; current = current->nextSibling())
- serializeNodesWithNamespaces(current, nodeToSkip, IncludeNode, &namespaceHash, tagNamesToSkip);
+ serializeNodesWithNamespaces(*current, nodeToSkip, IncludeNode, &namespaceHash, tagNamesToSkip);
}
if (!childrenOnly)
appendEndTag(targetNode);
}
-String MarkupAccumulator::resolveURLIfNeeded(const Element* element, const String& urlString) const
+String MarkupAccumulator::resolveURLIfNeeded(const Element& element, const String& urlString) const
{
switch (m_resolveURLsMethod) {
case ResolveAllURLs:
- return element->document().completeURL(urlString).string();
+ return element.document().completeURL(urlString).string();
case ResolveNonLocalURLs:
- if (!element->document().url().isLocalFile())
- return element->document().completeURL(urlString).string();
+ if (!element.document().url().isLocalFile())
+ return element.document().completeURL(urlString).string();
break;
case DoNotResolveURLs:
m_markup.append(string);
}
-void MarkupAccumulator::appendStartTag(Node* node, Namespaces* namespaces)
+void MarkupAccumulator::appendStartTag(const Node& node, Namespaces* namespaces)
{
appendStartMarkup(m_markup, node, namespaces);
if (m_nodes)
- m_nodes->append(node);
+ m_nodes->append(const_cast<Node*>(&node));
}
-void MarkupAccumulator::appendEndTag(Node* node)
+void MarkupAccumulator::appendEndTag(const Node& node)
{
appendEndMarkup(m_markup, node);
}
documentIsHTML ? EntityMaskInHTMLAttributeValue : EntityMaskInAttributeValue);
}
-void MarkupAccumulator::appendCustomAttributes(StringBuilder&, Element*, Namespaces*)
+void MarkupAccumulator::appendCustomAttributes(StringBuilder&, const Element&, Namespaces*)
{
}
-void MarkupAccumulator::appendQuotedURLAttributeValue(StringBuilder& result, const Element* element, const Attribute& attribute)
+void MarkupAccumulator::appendQuotedURLAttributeValue(StringBuilder& result, const Element& element, const Attribute& attribute)
{
- ASSERT(element->isURLAttribute(attribute));
+ ASSERT(element.isURLAttribute(attribute));
const String resolvedURLString = resolveURLIfNeeded(element, attribute.value());
UChar quoteChar = '"';
String strippedURLString = resolvedURLString.stripWhiteSpace();
result.append(quoteChar);
}
-void MarkupAccumulator::appendNodeValue(StringBuilder& result, const Node* node, const Range* range, EntityMask entityMask)
+void MarkupAccumulator::appendNodeValue(StringBuilder& result, const Node& node, const Range* range, EntityMask entityMask)
{
- const String str = node->nodeValue();
+ const String str = node.nodeValue();
unsigned length = str.length();
unsigned start = 0;
if (range) {
- if (node == range->endContainer())
+ if (&node == range->endContainer())
length = range->endOffset();
- if (node == range->startContainer()) {
+ if (&node == range->startContainer()) {
start = range->startOffset();
length -= start;
}
appendCharactersReplacingEntities(result, str, start, length, entityMask);
}
-bool MarkupAccumulator::shouldAddNamespaceElement(const Element* element)
+bool MarkupAccumulator::shouldAddNamespaceElement(const Element& element)
{
// Don't add namespace attribute if it is already defined for this elem.
- const AtomicString& prefix = element->prefix();
+ const AtomicString& prefix = element.prefix();
if (prefix.isEmpty())
- return !element->hasAttribute(xmlnsAtom);
+ return !element.hasAttribute(xmlnsAtom);
DEFINE_STATIC_LOCAL(String, xmlnsWithColon, (ASCIILiteral("xmlns:")));
- return !element->hasAttribute(xmlnsWithColon + prefix);
+ return !element.hasAttribute(xmlnsWithColon + prefix);
}
bool MarkupAccumulator::shouldAddNamespaceAttribute(const Attribute& attribute, Namespaces& namespaces)
}
}
-EntityMask MarkupAccumulator::entityMaskForText(Text* text) const
+EntityMask MarkupAccumulator::entityMaskForText(const Text& text) const
{
const QualifiedName* parentName = 0;
- if (text->parentElement())
- parentName = &(text->parentElement())->tagQName();
+ if (text.parentElement())
+ parentName = &text.parentElement()->tagQName();
if (parentName && (*parentName == scriptTag || *parentName == styleTag || *parentName == xmpTag))
return EntityMaskInCDATA;
- return text->document().isHTMLDocument() ? EntityMaskInHTMLPCDATA : EntityMaskInPCDATA;
+ return text.document().isHTMLDocument() ? EntityMaskInHTMLPCDATA : EntityMaskInPCDATA;
}
-void MarkupAccumulator::appendText(StringBuilder& result, Text* text)
+void MarkupAccumulator::appendText(StringBuilder& result, const Text& text)
{
appendNodeValue(result, text, m_range, entityMaskForText(text));
}
-void MarkupAccumulator::appendComment(StringBuilder& result, const String& comment)
+static void appendComment(StringBuilder& result, const String& comment)
{
// FIXME: Comment content is not escaped, but XMLSerializer (and possibly other callers) should raise an exception if it includes "-->".
result.appendLiteral("<!--");
result.appendLiteral("-->");
}
-void MarkupAccumulator::appendXMLDeclaration(StringBuilder& result, const Document* document)
+void MarkupAccumulator::appendXMLDeclaration(StringBuilder& result, const Document& document)
{
- if (!document->hasXMLDeclaration())
+ if (!document.hasXMLDeclaration())
return;
result.appendLiteral("<?xml version=\"");
- result.append(document->xmlVersion());
- const String& encoding = document->xmlEncoding();
+ result.append(document.xmlVersion());
+ const String& encoding = document.xmlEncoding();
if (!encoding.isEmpty()) {
result.appendLiteral("\" encoding=\"");
result.append(encoding);
}
- if (document->xmlStandaloneStatus() != Document::StandaloneUnspecified) {
+ if (document.xmlStandaloneStatus() != Document::StandaloneUnspecified) {
result.appendLiteral("\" standalone=\"");
- if (document->xmlStandalone())
+ if (document.xmlStandalone())
result.appendLiteral("yes");
else
result.appendLiteral("no");
result.appendLiteral("\"?>");
}
-void MarkupAccumulator::appendDocumentType(StringBuilder& result, const DocumentType* n)
+void MarkupAccumulator::appendDocumentType(StringBuilder& result, const DocumentType& documentType)
{
- if (n->name().isEmpty())
+ if (documentType.name().isEmpty())
return;
result.appendLiteral("<!DOCTYPE ");
- result.append(n->name());
- if (!n->publicId().isEmpty()) {
+ result.append(documentType.name());
+ if (!documentType.publicId().isEmpty()) {
result.appendLiteral(" PUBLIC \"");
- result.append(n->publicId());
+ result.append(documentType.publicId());
result.append('"');
- if (!n->systemId().isEmpty()) {
+ if (!documentType.systemId().isEmpty()) {
result.append(' ');
result.append('"');
- result.append(n->systemId());
+ result.append(documentType.systemId());
result.append('"');
}
- } else if (!n->systemId().isEmpty()) {
+ } else if (!documentType.systemId().isEmpty()) {
result.appendLiteral(" SYSTEM \"");
- result.append(n->systemId());
+ result.append(documentType.systemId());
result.append('"');
}
- if (!n->internalSubset().isEmpty()) {
+ if (!documentType.internalSubset().isEmpty()) {
result.append(' ');
result.append('[');
- result.append(n->internalSubset());
+ result.append(documentType.internalSubset());
result.append(']');
}
result.append('>');
result.append('>');
}
-void MarkupAccumulator::appendElement(StringBuilder& result, Element* element, Namespaces* namespaces)
+void MarkupAccumulator::appendElement(StringBuilder& result, const Element& element, Namespaces* namespaces)
{
appendOpenTag(result, element, namespaces);
- if (element->hasAttributes()) {
- unsigned length = element->attributeCount();
+ if (element.hasAttributes()) {
+ unsigned length = element.attributeCount();
for (unsigned int i = 0; i < length; i++)
- appendAttribute(result, element, element->attributeAt(i), namespaces);
+ appendAttribute(result, element, element.attributeAt(i), namespaces);
}
// Give an opportunity to subclasses to add their own attributes.
appendCloseTag(result, element);
}
-void MarkupAccumulator::appendOpenTag(StringBuilder& result, Element* element, Namespaces* namespaces)
+void MarkupAccumulator::appendOpenTag(StringBuilder& result, const Element& element, Namespaces* namespaces)
{
result.append('<');
- if (inXMLFragmentSerialization() && namespaces && element->prefix().isEmpty()) {
+ if (inXMLFragmentSerialization() && namespaces && element.prefix().isEmpty()) {
// According to http://www.w3.org/TR/DOM-Level-3-Core/namespaces-algorithms.html#normalizeDocumentAlgo we now should create
// a default namespace declaration to make this namespace well-formed. However, http://www.w3.org/TR/xml-names11/#xmlReserved states
// "The prefix xml MUST NOT be declared as the default namespace.", so use the xml prefix explicitly.
- if (element->namespaceURI() == XMLNames::xmlNamespaceURI) {
+ if (element.namespaceURI() == XMLNames::xmlNamespaceURI) {
result.append(xmlAtom);
result.append(':');
}
}
- result.append(element->nodeNamePreservingCase());
- if ((inXMLFragmentSerialization() || !element->document().isHTMLDocument()) && namespaces && shouldAddNamespaceElement(element))
- appendNamespace(result, element->prefix(), element->namespaceURI(), *namespaces, inXMLFragmentSerialization());
+ result.append(element.nodeNamePreservingCase());
+ if ((inXMLFragmentSerialization() || !element.document().isHTMLDocument()) && namespaces && shouldAddNamespaceElement(element))
+ appendNamespace(result, element.prefix(), element.namespaceURI(), *namespaces, inXMLFragmentSerialization());
}
-void MarkupAccumulator::appendCloseTag(StringBuilder& result, Element* element)
+void MarkupAccumulator::appendCloseTag(StringBuilder& result, const Element& element)
{
if (shouldSelfClose(element)) {
- if (element->isHTMLElement())
+ if (element.isHTMLElement())
result.append(' '); // XHTML 1.0 <-> HTML compatibility.
result.append('/');
}
} while (true);
}
-void MarkupAccumulator::appendAttribute(StringBuilder& result, Element* element, const Attribute& attribute, Namespaces* namespaces)
+void MarkupAccumulator::appendAttribute(StringBuilder& result, const Element& element, const Attribute& attribute, Namespaces* namespaces)
{
- bool documentIsHTML = element->document().isHTMLDocument();
+ bool documentIsHTML = element.document().isHTMLDocument();
result.append(' ');
result.append('=');
- if (element->isURLAttribute(attribute))
+ if (element.isURLAttribute(attribute))
appendQuotedURLAttributeValue(result, element, attribute);
else {
result.append('"');
result.appendLiteral("]]>");
}
-void MarkupAccumulator::appendStartMarkup(StringBuilder& result, const Node* node, Namespaces* namespaces)
+void MarkupAccumulator::appendStartMarkup(StringBuilder& result, const Node& node, Namespaces* namespaces)
{
if (namespaces)
namespaces->checkConsistency();
- switch (node->nodeType()) {
+ switch (node.nodeType()) {
case Node::TEXT_NODE:
- appendText(result, toText(const_cast<Node*>(node)));
+ appendText(result, toText(node));
break;
case Node::COMMENT_NODE:
- appendComment(result, static_cast<const Comment*>(node)->data());
+ appendComment(result, toComment(node).data());
break;
case Node::DOCUMENT_NODE:
appendXMLDeclaration(result, toDocument(node));
case Node::DOCUMENT_FRAGMENT_NODE:
break;
case Node::DOCUMENT_TYPE_NODE:
- appendDocumentType(result, static_cast<const DocumentType*>(node));
+ appendDocumentType(result, toDocumentType(node));
break;
case Node::PROCESSING_INSTRUCTION_NODE:
- appendProcessingInstruction(result, static_cast<const ProcessingInstruction*>(node)->target(), static_cast<const ProcessingInstruction*>(node)->data());
+ appendProcessingInstruction(result, toProcessingInstruction(node).target(), toProcessingInstruction(node).data());
break;
case Node::ELEMENT_NODE:
- appendElement(result, toElement(const_cast<Node*>(node)), namespaces);
+ appendElement(result, toElement(node), namespaces);
break;
case Node::CDATA_SECTION_NODE:
- appendCDATASection(result, static_cast<const CDATASection*>(node)->data());
+ appendCDATASection(result, toCDATASection(node).data());
break;
case Node::ATTRIBUTE_NODE:
case Node::ENTITY_NODE:
// 2. Elements w/ children never self-close because they use a separate end tag.
// 3. HTML elements which do not have a "forbidden" end tag will close with a separate end tag.
// 4. Other elements self-close.
-bool MarkupAccumulator::shouldSelfClose(const Node* node)
+bool MarkupAccumulator::shouldSelfClose(const Node& node)
{
- if (!inXMLFragmentSerialization() && node->document().isHTMLDocument())
+ if (!inXMLFragmentSerialization() && node.document().isHTMLDocument())
return false;
- if (node->hasChildNodes())
+ if (node.hasChildNodes())
return false;
- if (node->isHTMLElement() && !elementCannotHaveEndTag(node))
+ if (node.isHTMLElement() && !elementCannotHaveEndTag(node))
return false;
return true;
}
-bool MarkupAccumulator::elementCannotHaveEndTag(const Node* node)
+bool MarkupAccumulator::elementCannotHaveEndTag(const Node& node)
{
- if (!node->isHTMLElement())
+ if (!node.isHTMLElement())
return false;
// FIXME: ieForbidsInsertHTML may not be the right function to call here
// ieForbidsInsertHTML is used to disallow setting innerHTML/outerHTML
// or createContextualFragment. It does not necessarily align with
// which elements should be serialized w/o end tags.
- return static_cast<const HTMLElement*>(node)->ieForbidsInsertHTML();
+ return toHTMLElement(node).ieForbidsInsertHTML();
}
-void MarkupAccumulator::appendEndMarkup(StringBuilder& result, const Node* node)
+void MarkupAccumulator::appendEndMarkup(StringBuilder& result, const Node& node)
{
- if (!node->isElementNode() || shouldSelfClose(node) || (!node->hasChildNodes() && elementCannotHaveEndTag(node)))
+ if (!node.isElementNode() || shouldSelfClose(node) || (!node.hasChildNodes() && elementCannotHaveEndTag(node)))
return;
result.append('<');
result.append('/');
- result.append(toElement(node)->nodeNamePreservingCase());
+ result.append(toElement(node).nodeNamePreservingCase());
result.append('>');
}
MarkupAccumulator(Vector<Node*>*, EAbsoluteURLs, const Range* = 0, EFragmentSerialization = HTMLFragmentSerialization);
virtual ~MarkupAccumulator();
- String serializeNodes(Node* targetNode, Node* nodeToSkip, EChildrenOnly);
- String serializeNodes(Node* targetNode, Node* nodeToSkip, EChildrenOnly, Vector<QualifiedName>* tagNamesToSkip);
-
- static void appendComment(StringBuilder&, const String&);
+ String serializeNodes(Node& targetNode, Node* nodeToSkip, EChildrenOnly, Vector<QualifiedName>* tagNamesToSkip = nullptr);
static void appendCharactersReplacingEntities(StringBuilder&, const String&, unsigned, unsigned, EntityMask);
protected:
- virtual void appendString(const String&);
- void appendStartTag(Node*, Namespaces* = 0);
- virtual void appendEndTag(Node*);
static size_t totalLength(const Vector<String>&);
size_t length() const { return m_markup.length(); }
+
void concatenateMarkup(StringBuilder&);
+
+ virtual void appendString(const String&);
+ virtual void appendEndTag(const Node&);
+ virtual void appendCustomAttributes(StringBuilder&, const Element&, Namespaces*);
+ virtual void appendText(StringBuilder&, const Text&);
+ virtual void appendElement(StringBuilder&, const Element&, Namespaces*);
+
+ void appendStartTag(const Node&, Namespaces* = 0);
+
+ void appendOpenTag(StringBuilder&, const Element&, Namespaces*);
+ void appendCloseTag(StringBuilder&, const Element&);
+
+ void appendStartMarkup(StringBuilder&, const Node&, Namespaces*);
+ void appendEndMarkup(StringBuilder&, const Node&);
+
void appendAttributeValue(StringBuilder&, const String&, bool);
- virtual void appendCustomAttributes(StringBuilder&, Element*, Namespaces*);
- void appendNodeValue(StringBuilder&, const Node*, const Range*, EntityMask);
- bool shouldAddNamespaceElement(const Element*);
- bool shouldAddNamespaceAttribute(const Attribute&, Namespaces&);
+ void appendNodeValue(StringBuilder&, const Node&, const Range*, EntityMask);
void appendNamespace(StringBuilder&, const AtomicString& prefix, const AtomicString& namespaceURI, Namespaces&, bool allowEmptyDefaultNS = false);
- EntityMask entityMaskForText(Text*) const;
- virtual void appendText(StringBuilder&, Text*);
- void appendXMLDeclaration(StringBuilder&, const Document*);
- void appendDocumentType(StringBuilder&, const DocumentType*);
+ void appendXMLDeclaration(StringBuilder&, const Document&);
+ void appendDocumentType(StringBuilder&, const DocumentType&);
void appendProcessingInstruction(StringBuilder&, const String& target, const String& data);
- virtual void appendElement(StringBuilder&, Element*, Namespaces*);
- void appendOpenTag(StringBuilder&, Element*, Namespaces*);
- void appendCloseTag(StringBuilder&, Element*);
- void appendAttribute(StringBuilder&, Element*, const Attribute&, Namespaces*);
+ void appendAttribute(StringBuilder&, const Element&, const Attribute&, Namespaces*);
void appendCDATASection(StringBuilder&, const String&);
- void appendStartMarkup(StringBuilder&, const Node*, Namespaces*);
- bool shouldSelfClose(const Node*);
- bool elementCannotHaveEndTag(const Node*);
- void appendEndMarkup(StringBuilder&, const Node*);
+
+ bool shouldAddNamespaceElement(const Element&);
+ bool shouldAddNamespaceAttribute(const Attribute&, Namespaces&);
+ bool shouldSelfClose(const Node&);
+ bool elementCannotHaveEndTag(const Node&);
+ EntityMask entityMaskForText(const Text&) const;
Vector<Node*>* const m_nodes;
const Range* const m_range;
private:
- String resolveURLIfNeeded(const Element*, const String&) const;
- void appendQuotedURLAttributeValue(StringBuilder&, const Element*, const Attribute&);
- void serializeNodesWithNamespaces(Node* targetNode, Node* nodeToSkip, EChildrenOnly, const Namespaces*, Vector<QualifiedName>* tagNamesToSkip);
+ String resolveURLIfNeeded(const Element&, const String&) const;
+ void appendQuotedURLAttributeValue(StringBuilder&, const Element&, const Attribute&);
+ void serializeNodesWithNamespaces(Node& targetNode, Node* nodeToSkip, EChildrenOnly, const Namespaces*, Vector<QualifiedName>* tagNamesToSkip);
bool inXMLFragmentSerialization() const { return m_fragmentSerialization == XMLFragmentSerialization; }
void generateUniquePrefix(QualifiedName&, const Namespaces&);
loader->addAllArchiveResources(archive.get());
String markupString = String::fromUTF8(mainResource->data()->data(), mainResource->data()->size());
- addFragment(createFragmentFromMarkup(frame.document(), markupString, mainResource->url(), DisallowScriptingAndPluginContent));
+ addFragment(createFragmentFromMarkup(*frame.document(), markupString, mainResource->url(), DisallowScriptingAndPluginContent));
return true;
}
loader->addAllArchiveResources(archive.get());
String markupString = String::fromUTF8(mainResource->data()->data(), mainResource->data()->size());
- fragment = createFragmentFromMarkup(frame.document(), markupString, mainResource->url(), DisallowScriptingAndPluginContent);
+ fragment = createFragmentFromMarkup(*frame.document(), markupString, mainResource->url(), DisallowScriptingAndPluginContent);
return true;
}
if (stringOmittingMicrosoftPrefix.isEmpty())
return false;
- fragment = createFragmentFromMarkup(frame.document(), stringOmittingMicrosoftPrefix, emptyString(), DisallowScriptingAndPluginContent);
+ if (!frame.document())
+ return false;
+ Document& document = *frame.document();
+
+ fragment = createFragmentFromMarkup(document, stringOmittingMicrosoftPrefix, emptyString(), DisallowScriptingAndPluginContent);
return fragment;
}
changes[i].apply();
}
-class StyledMarkupAccumulator : public MarkupAccumulator {
+class StyledMarkupAccumulator final : public MarkupAccumulator {
public:
enum RangeFullySelectsNode { DoesFullySelectNode, DoesNotFullySelectNode };
StyledMarkupAccumulator(Vector<Node*>* nodes, EAbsoluteURLs, EAnnotateForInterchange, const Range*, Node* highestNodeToBeSerialized = 0);
+
Node* serializeNodes(Node* startNode, Node* pastEnd);
- virtual void appendString(const String& s) { return MarkupAccumulator::appendString(s); }
- void wrapWithNode(Node*, bool convertBlocksToInlines = false, RangeFullySelectsNode = DoesFullySelectNode);
- void wrapWithStyleNode(StylePropertySet*, Document*, bool isBlock = false);
+ void wrapWithNode(Node&, bool convertBlocksToInlines = false, RangeFullySelectsNode = DoesFullySelectNode);
+ void wrapWithStyleNode(StylePropertySet*, Document&, bool isBlock = false);
String takeResults();
+ using MarkupAccumulator::appendString;
+
private:
- void appendStyleNodeOpenTag(StringBuilder&, StylePropertySet*, Document*, bool isBlock = false);
+ void appendStyleNodeOpenTag(StringBuilder&, StylePropertySet*, Document&, bool isBlock = false);
const String& styleNodeCloseTag(bool isBlock = false);
- virtual void appendText(StringBuilder& out, Text*);
- String renderedText(const Node*, const Range*);
- String stringValueForRange(const Node*, const Range*);
- void appendElement(StringBuilder& out, Element*, bool addDisplayInline, RangeFullySelectsNode);
- void appendElement(StringBuilder& out, Element* element, Namespaces*) { appendElement(out, element, false, DoesFullySelectNode); }
+
+ String renderedText(const Node&, const Range*);
+ String stringValueForRange(const Node&, const Range*);
+
+ void appendElement(StringBuilder& out, const Element&, bool addDisplayInline, RangeFullySelectsNode);
+
+ virtual void appendText(StringBuilder& out, const Text&) override;
+ virtual void appendElement(StringBuilder& out, const Element& element, Namespaces*) override
+ {
+ appendElement(out, element, false, DoesFullySelectNode);
+ }
enum NodeTraversalMode { EmitString, DoNotEmitString };
Node* traverseNodesForSerialization(Node* startNode, Node* pastEnd, NodeTraversalMode);
- bool shouldAnnotate() { return m_shouldAnnotate == AnnotateForInterchange; }
- bool shouldApplyWrappingStyle(Node* node) const
+ bool shouldAnnotate()
{
- return m_highestNodeToBeSerialized && m_highestNodeToBeSerialized->parentNode() == node->parentNode()
- && m_wrappingStyle && m_wrappingStyle->style();
+ return m_shouldAnnotate == AnnotateForInterchange;
+ }
+
+ bool shouldApplyWrappingStyle(const Node& node) const
+ {
+ return m_highestNodeToBeSerialized && m_highestNodeToBeSerialized->parentNode() == node.parentNode() && m_wrappingStyle && m_wrappingStyle->style();
}
Vector<String> m_reversedPrecedingMarkup;
{
}
-void StyledMarkupAccumulator::wrapWithNode(Node* node, bool convertBlocksToInlines, RangeFullySelectsNode rangeFullySelectsNode)
+void StyledMarkupAccumulator::wrapWithNode(Node& node, bool convertBlocksToInlines, RangeFullySelectsNode rangeFullySelectsNode)
{
StringBuilder markup;
- if (node->isElementNode())
- appendElement(markup, toElement(node), convertBlocksToInlines && isBlock(const_cast<Node*>(node)), rangeFullySelectsNode);
+ if (node.isElementNode())
+ appendElement(markup, toElement(node), convertBlocksToInlines && isBlock(&node), rangeFullySelectsNode);
else
appendStartMarkup(markup, node, 0);
m_reversedPrecedingMarkup.append(markup.toString());
appendEndTag(node);
if (m_nodes)
- m_nodes->append(node);
+ m_nodes->append(&node);
}
-void StyledMarkupAccumulator::wrapWithStyleNode(StylePropertySet* style, Document* document, bool isBlock)
+void StyledMarkupAccumulator::wrapWithStyleNode(StylePropertySet* style, Document& document, bool isBlock)
{
StringBuilder openTag;
appendStyleNodeOpenTag(openTag, style, document, isBlock);
appendString(styleNodeCloseTag(isBlock));
}
-void StyledMarkupAccumulator::appendStyleNodeOpenTag(StringBuilder& out, StylePropertySet* style, Document* document, bool isBlock)
+void StyledMarkupAccumulator::appendStyleNodeOpenTag(StringBuilder& out, StylePropertySet* style, Document& document, bool isBlock)
{
// wrappingStyleForSerialization should have removed -webkit-text-decorations-in-effect
ASSERT(propertyMissingOrEqualToNone(style, CSSPropertyWebkitTextDecorationsInEffect));
out.appendLiteral("<div style=\"");
else
out.appendLiteral("<span style=\"");
- appendAttributeValue(out, style->asText(), document->isHTMLDocument());
+ appendAttributeValue(out, style->asText(), document.isHTMLDocument());
out.appendLiteral("\">");
}
return result.toString().replaceWithLiteral('\0', "");
}
-void StyledMarkupAccumulator::appendText(StringBuilder& out, Text* text)
+void StyledMarkupAccumulator::appendText(StringBuilder& out, const Text& text)
{
- const bool parentIsTextarea = text->parentElement() && isHTMLTextAreaElement(text->parentElement());
+ const bool parentIsTextarea = text.parentElement() && isHTMLTextAreaElement(text.parentElement());
const bool wrappingSpan = shouldApplyWrappingStyle(text) && !parentIsTextarea;
if (wrappingSpan) {
RefPtr<EditingStyle> wrappingStyle = m_wrappingStyle->copy();
// FIXME: Should this be included in forceInline?
wrappingStyle->style()->setProperty(CSSPropertyFloat, CSSValueNone);
- appendStyleNodeOpenTag(out, wrappingStyle->style(), &text->document());
+ appendStyleNodeOpenTag(out, wrappingStyle->style(), text.document());
}
if (!shouldAnnotate() || parentIsTextarea)
MarkupAccumulator::appendText(out, text);
else {
- const bool useRenderedText = !enclosingNodeWithTag(firstPositionInNode(text), selectTag);
+ const bool useRenderedText = !enclosingNodeWithTag(firstPositionInNode(const_cast<Text*>(&text)), selectTag);
String content = useRenderedText ? renderedText(text, m_range) : stringValueForRange(text, m_range);
StringBuilder buffer;
appendCharactersReplacingEntities(buffer, content, 0, content.length(), EntityMaskInPCDATA);
- out.append(convertHTMLTextToInterchangeFormat(buffer.toString(), text));
+ out.append(convertHTMLTextToInterchangeFormat(buffer.toString(), &text));
}
if (wrappingSpan)
out.append(styleNodeCloseTag());
}
-String StyledMarkupAccumulator::renderedText(const Node* node, const Range* range)
+String StyledMarkupAccumulator::renderedText(const Node& node, const Range* range)
{
- if (!node->isTextNode())
+ if (!node.isTextNode())
return String();
- const Text* textNode = static_cast<const Text*>(node);
+ const Text& textNode = toText(node);
unsigned startOffset = 0;
- unsigned endOffset = textNode->length();
+ unsigned endOffset = textNode.length();
- if (range && node == range->startContainer())
+ if (range && &node == range->startContainer())
startOffset = range->startOffset();
- if (range && node == range->endContainer())
+ if (range && &node == range->endContainer())
endOffset = range->endOffset();
- Position start = createLegacyEditingPosition(const_cast<Node*>(node), startOffset);
- Position end = createLegacyEditingPosition(const_cast<Node*>(node), endOffset);
- return plainText(Range::create(&node->document(), start, end).get());
+ Position start = createLegacyEditingPosition(const_cast<Node*>(&node), startOffset);
+ Position end = createLegacyEditingPosition(const_cast<Node*>(&node), endOffset);
+ return plainText(Range::create(&node.document(), start, end).get());
}
-String StyledMarkupAccumulator::stringValueForRange(const Node* node, const Range* range)
+String StyledMarkupAccumulator::stringValueForRange(const Node& node, const Range* range)
{
if (!range)
- return node->nodeValue();
-
- String str = node->nodeValue();
- if (node == range->endContainer())
- str.truncate(range->endOffset());
- if (node == range->startContainer())
- str.remove(0, range->startOffset());
- return str;
+ return node.nodeValue();
+
+ String nodeValue = node.nodeValue();
+ if (&node == range->endContainer())
+ nodeValue.truncate(range->endOffset());
+ if (&node == range->startContainer())
+ nodeValue.remove(0, range->startOffset());
+ return nodeValue;
}
-void StyledMarkupAccumulator::appendElement(StringBuilder& out, Element* element, bool addDisplayInline, RangeFullySelectsNode rangeFullySelectsNode)
+void StyledMarkupAccumulator::appendElement(StringBuilder& out, const Element& element, bool addDisplayInline, RangeFullySelectsNode rangeFullySelectsNode)
{
- const bool documentIsHTML = element->document().isHTMLDocument();
+ const bool documentIsHTML = element.document().isHTMLDocument();
appendOpenTag(out, element, 0);
- const unsigned length = element->hasAttributes() ? element->attributeCount() : 0;
- const bool shouldAnnotateOrForceInline = element->isHTMLElement() && (shouldAnnotate() || addDisplayInline);
+ const unsigned length = element.hasAttributes() ? element.attributeCount() : 0;
+ const bool shouldAnnotateOrForceInline = element.isHTMLElement() && (shouldAnnotate() || addDisplayInline);
const bool shouldOverrideStyleAttr = shouldAnnotateOrForceInline || shouldApplyWrappingStyle(element);
for (unsigned i = 0; i < length; ++i) {
- const Attribute& attribute = element->attributeAt(i);
+ const Attribute& attribute = element.attributeAt(i);
// We'll handle the style attribute separately, below.
if (attribute.name() == styleAttr && shouldOverrideStyleAttr)
continue;
if (shouldApplyWrappingStyle(element)) {
newInlineStyle = m_wrappingStyle->copy();
- newInlineStyle->removePropertiesInElementDefaultStyle(element);
- newInlineStyle->removeStyleConflictingWithStyleOfNode(element);
+ newInlineStyle->removePropertiesInElementDefaultStyle(const_cast<Element*>(&element));
+ newInlineStyle->removeStyleConflictingWithStyleOfNode(const_cast<Element*>(&element));
} else
newInlineStyle = EditingStyle::create();
- if (element->isStyledElement() && static_cast<StyledElement*>(element)->inlineStyle())
- newInlineStyle->overrideWithStyle(static_cast<StyledElement*>(element)->inlineStyle());
+ if (element.isStyledElement() && toStyledElement(element).inlineStyle())
+ newInlineStyle->overrideWithStyle(toStyledElement(element).inlineStyle());
if (shouldAnnotateOrForceInline) {
if (shouldAnnotate())
- newInlineStyle->mergeStyleFromRulesForSerialization(toHTMLElement(element));
+ newInlineStyle->mergeStyleFromRulesForSerialization(toHTMLElement(const_cast<Element*>(&element)));
if (addDisplayInline)
newInlineStyle->forceInline();
} else {
// Add the node to the markup if we're not skipping the descendants
if (shouldEmit)
- appendStartTag(n);
+ appendStartTag(*n);
// If node has no children, close the tag now.
if (!n->childNodeCount()) {
if (shouldEmit)
- appendEndTag(n);
+ appendEndTag(*n);
lastClosed = n;
} else {
openedTag = true;
break;
// Not at the end of the range, close ancestors up to sibling of next node.
if (shouldEmit)
- appendEndTag(ancestor);
+ appendEndTag(*ancestor);
lastClosed = ancestor;
ancestorsToClose.removeLast();
}
// or b) ancestors that we never encountered during a pre-order traversal starting at startNode:
ASSERT(startNode->isDescendantOf(parent));
if (shouldEmit)
- wrapWithNode(parent);
+ wrapWithNode(*parent);
lastClosed = parent;
}
}
// FIXME: Shouldn't we omit style info when annotate == DoNotAnnotateForInterchange?
// FIXME: At least, annotation and style info should probably not be included in range.markupString()
-static String createMarkupInternal(Document* document, const Range* range, const Range* updatedRange, Vector<Node*>* nodes,
+static String createMarkupInternal(Document& document, const Range& range, const Range& updatedRange, Vector<Node*>* nodes,
EAnnotateForInterchange shouldAnnotate, bool convertBlocksToInlines, EAbsoluteURLs shouldResolveURLs)
{
- ASSERT(document);
- ASSERT(range);
- ASSERT(updatedRange);
DEFINE_STATIC_LOCAL(const String, interchangeNewlineString, (ASCIILiteral("<br class=\"" AppleInterchangeNewline "\">")));
- bool collapsed = updatedRange->collapsed(ASSERT_NO_EXCEPTION);
+ bool collapsed = updatedRange.collapsed(ASSERT_NO_EXCEPTION);
if (collapsed)
return emptyString();
- Node* commonAncestor = updatedRange->commonAncestorContainer(ASSERT_NO_EXCEPTION);
+ Node* commonAncestor = updatedRange.commonAncestorContainer(ASSERT_NO_EXCEPTION);
if (!commonAncestor)
return emptyString();
- document->updateLayoutIgnorePendingStylesheets();
+ document.updateLayoutIgnorePendingStylesheets();
Node* body = enclosingNodeWithTag(firstPositionInNode(commonAncestor), bodyTag);
Node* fullySelectedRoot = 0;
// FIXME: Do this for all fully selected blocks, not just the body.
- if (body && areRangesEqual(VisibleSelection::selectionFromContentsOfNode(body).toNormalizedRange().get(), range))
+ if (body && areRangesEqual(VisibleSelection::selectionFromContentsOfNode(body).toNormalizedRange().get(), &range))
fullySelectedRoot = body;
- Node* specialCommonAncestor = highestAncestorToWrapMarkup(updatedRange, shouldAnnotate);
- StyledMarkupAccumulator accumulator(nodes, shouldResolveURLs, shouldAnnotate, updatedRange, specialCommonAncestor);
- Node* pastEnd = updatedRange->pastLastNode();
+ Node* specialCommonAncestor = highestAncestorToWrapMarkup(&updatedRange, shouldAnnotate);
- Node* startNode = updatedRange->firstNode();
- VisiblePosition visibleStart(updatedRange->startPosition(), VP_DEFAULT_AFFINITY);
- VisiblePosition visibleEnd(updatedRange->endPosition(), VP_DEFAULT_AFFINITY);
+ StyledMarkupAccumulator accumulator(nodes, shouldResolveURLs, shouldAnnotate, &updatedRange, specialCommonAncestor);
+ Node* pastEnd = updatedRange.pastLastNode();
+
+ Node* startNode = updatedRange.firstNode();
+ VisiblePosition visibleStart(updatedRange.startPosition(), VP_DEFAULT_AFFINITY);
+ VisiblePosition visibleEnd(updatedRange.endPosition(), VP_DEFAULT_AFFINITY);
if (shouldAnnotate == AnnotateForInterchange && needInterchangeNewlineAfter(visibleStart)) {
if (visibleStart == visibleEnd.previous())
return interchangeNewlineString;
} else {
// Since this node and all the other ancestors are not in the selection we want to set RangeFullySelectsNode to DoesNotFullySelectNode
// so that styles that affect the exterior of the node are not included.
- accumulator.wrapWithNode(ancestor, convertBlocksToInlines, StyledMarkupAccumulator::DoesNotFullySelectNode);
+ accumulator.wrapWithNode(*ancestor, convertBlocksToInlines, StyledMarkupAccumulator::DoesNotFullySelectNode);
}
if (nodes)
nodes->append(ancestor);
return accumulator.takeResults();
}
-String createMarkup(const Range* range, Vector<Node*>* nodes, EAnnotateForInterchange shouldAnnotate, bool convertBlocksToInlines, EAbsoluteURLs shouldResolveURLs)
+String createMarkup(const Range& range, Vector<Node*>* nodes, EAnnotateForInterchange shouldAnnotate, bool convertBlocksToInlines, EAbsoluteURLs shouldResolveURLs)
{
- if (!range)
- return emptyString();
-
- Document& document = range->ownerDocument();
- const Range* updatedRange = range;
+ Document& document = range.ownerDocument();
+ const Range* updatedRange = ⦥
#if ENABLE(DELETION_UI)
// Disable the delete button so it's elements are not serialized into the markup,
RefPtr<Range> updatedRangeRef;
if (frame) {
- updatedRangeRef = frame->editor().avoidIntersectionWithDeleteButtonController(range);
+ updatedRangeRef = frame->editor().avoidIntersectionWithDeleteButtonController(&range);
updatedRange = updatedRangeRef.get();
if (!updatedRange)
return emptyString();
}
#endif
- return createMarkupInternal(&document, range, updatedRange, nodes, shouldAnnotate, convertBlocksToInlines, shouldResolveURLs);
+ return createMarkupInternal(document, range, *updatedRange, nodes, shouldAnnotate, convertBlocksToInlines, shouldResolveURLs);
}
-PassRefPtr<DocumentFragment> createFragmentFromMarkup(Document* document, const String& markup, const String& baseURL, ParserContentPolicy parserContentPolicy)
+PassRefPtr<DocumentFragment> createFragmentFromMarkup(Document& document, const String& markup, const String& baseURL, ParserContentPolicy parserContentPolicy)
{
// We use a fake body element here to trick the HTML parser to using the InBody insertion mode.
- RefPtr<HTMLBodyElement> fakeBody = HTMLBodyElement::create(*document);
- RefPtr<DocumentFragment> fragment = DocumentFragment::create(*document);
+ RefPtr<HTMLBodyElement> fakeBody = HTMLBodyElement::create(document);
+ RefPtr<DocumentFragment> fragment = DocumentFragment::create(document);
fragment->parseHTML(markup, fakeBody.get(), parserContentPolicy);
- if (!baseURL.isEmpty() && baseURL != blankURL() && baseURL != document->baseURL())
+ if (!baseURL.isEmpty() && baseURL != blankURL() && baseURL != document.baseURL())
completeURLs(fragment.get(), baseURL);
return fragment.release();
}
-static const char fragmentMarkerTag[] = "webkit-fragment-marker";
-
-static bool findNodesSurroundingContext(Document* document, RefPtr<Node>& nodeBeforeContext, RefPtr<Node>& nodeAfterContext)
-{
- for (Node* node = document->firstChild(); node; node = NodeTraversal::next(node)) {
- if (node->nodeType() == Node::COMMENT_NODE && static_cast<CharacterData*>(node)->data() == fragmentMarkerTag) {
- if (!nodeBeforeContext)
- nodeBeforeContext = node;
- else {
- nodeAfterContext = node;
- return true;
- }
- }
- }
- return false;
-}
-
-static void trimFragment(DocumentFragment* fragment, Node* nodeBeforeContext, Node* nodeAfterContext)
+String createMarkup(const Node& node, EChildrenOnly childrenOnly, Vector<Node*>* nodes, EAbsoluteURLs shouldResolveURLs, Vector<QualifiedName>* tagNamesToSkip, EFragmentSerialization fragmentSerialization)
{
- RefPtr<Node> next;
- for (RefPtr<Node> node = fragment->firstChild(); node; node = next) {
- if (nodeBeforeContext->isDescendantOf(node.get())) {
- next = NodeTraversal::next(node.get());
- continue;
- }
- next = NodeTraversal::nextSkippingChildren(node.get());
- ASSERT(!node->contains(nodeAfterContext));
- node->parentNode()->removeChild(node.get(), ASSERT_NO_EXCEPTION);
- if (nodeBeforeContext == node)
- break;
- }
-
- ASSERT(nodeAfterContext->parentNode());
- for (RefPtr<Node> node = nodeAfterContext; node; node = next) {
- next = NodeTraversal::nextSkippingChildren(node.get());
- node->parentNode()->removeChild(node.get(), ASSERT_NO_EXCEPTION);
- }
-}
-
-PassRefPtr<DocumentFragment> createFragmentFromMarkupWithContext(Document* document, const String& markup, unsigned fragmentStart, unsigned fragmentEnd,
- const String& baseURL, ParserContentPolicy parserContentPolicy)
-{
- // FIXME: Need to handle the case where the markup already contains these markers.
-
- StringBuilder taggedMarkup;
- taggedMarkup.append(markup.left(fragmentStart));
- MarkupAccumulator::appendComment(taggedMarkup, fragmentMarkerTag);
- taggedMarkup.append(markup.substring(fragmentStart, fragmentEnd - fragmentStart));
- MarkupAccumulator::appendComment(taggedMarkup, fragmentMarkerTag);
- taggedMarkup.append(markup.substring(fragmentEnd));
-
- RefPtr<DocumentFragment> taggedFragment = createFragmentFromMarkup(document, taggedMarkup.toString(), baseURL, parserContentPolicy);
- RefPtr<Document> taggedDocument = Document::create(0, URL());
- taggedDocument->takeAllChildrenFrom(taggedFragment.get());
-
- RefPtr<Node> nodeBeforeContext;
- RefPtr<Node> nodeAfterContext;
- if (!findNodesSurroundingContext(taggedDocument.get(), nodeBeforeContext, nodeAfterContext))
- return 0;
-
- RefPtr<Range> range = Range::create(taggedDocument.get(),
- positionAfterNode(nodeBeforeContext.get()).parentAnchoredEquivalent(),
- positionBeforeNode(nodeAfterContext.get()).parentAnchoredEquivalent());
-
- Node* commonAncestor = range->commonAncestorContainer(ASSERT_NO_EXCEPTION);
- Node* specialCommonAncestor = ancestorToRetainStructureAndAppearanceWithNoRenderer(commonAncestor);
-
- // When there's a special common ancestor outside of the fragment, we must include it as well to
- // preserve the structure and appearance of the fragment. For example, if the fragment contains
- // TD, we need to include the enclosing TABLE tag as well.
- RefPtr<DocumentFragment> fragment = DocumentFragment::create(*document);
- if (specialCommonAncestor)
- fragment->appendChild(specialCommonAncestor, ASSERT_NO_EXCEPTION);
- else
- fragment->takeAllChildrenFrom(toContainerNode(commonAncestor));
-
- trimFragment(fragment.get(), nodeBeforeContext.get(), nodeAfterContext.get());
-
- return fragment;
-}
-
-String createMarkup(const Node* node, EChildrenOnly childrenOnly, Vector<Node*>* nodes, EAbsoluteURLs shouldResolveURLs, Vector<QualifiedName>* tagNamesToSkip, EFragmentSerialization fragmentSerialization)
-{
- if (!node)
- return emptyString();
-
HTMLElement* deleteButtonContainerElement = 0;
#if ENABLE(DELETION_UI)
- if (Frame* frame = node->document().frame()) {
+ if (Frame* frame = node.document().frame()) {
deleteButtonContainerElement = frame->editor().deleteButtonController().containerElement();
- if (node->isDescendantOf(deleteButtonContainerElement))
+ if (node.isDescendantOf(deleteButtonContainerElement))
return emptyString();
}
#endif
+
MarkupAccumulator accumulator(nodes, shouldResolveURLs, 0, fragmentSerialization);
- return accumulator.serializeNodes(const_cast<Node*>(node), deleteButtonContainerElement, childrenOnly, tagNamesToSkip);
+ return accumulator.serializeNodes(const_cast<Node&>(node), deleteButtonContainerElement, childrenOnly, tagNamesToSkip);
}
static void fillContainerFromString(ContainerNode* paragraph, const String& string)
return fragment.release();
}
-PassRefPtr<DocumentFragment> createFragmentFromNodes(Document* document, const Vector<Node*>& nodes)
-{
- if (!document)
- return 0;
-
-#if ENABLE(DELETION_UI)
- // disable the delete button so it's elements are not serialized into the markup
- DeleteButtonControllerDisableScope(document->frame());
-#endif
-
- RefPtr<DocumentFragment> fragment = document->createDocumentFragment();
-
- size_t size = nodes.size();
- for (size_t i = 0; i < size; ++i) {
- RefPtr<Element> element = createDefaultParagraphElement(*document);
- element->appendChild(nodes[i], ASSERT_NO_EXCEPTION);
- fragment->appendChild(element.release(), ASSERT_NO_EXCEPTION);
- }
-
- return fragment.release();
-}
-
String documentTypeString(const Document& document)
{
- return createMarkup(document.doctype());
+ DocumentType* documentType = document.doctype();
+ if (!documentType)
+ return emptyString();
+ return createMarkup(*documentType);
}
-String createFullMarkup(const Node* node)
+String createFullMarkup(const Node& node)
{
- if (!node)
- return String();
-
// FIXME: This is never "for interchange". Is that right?
String markupString = createMarkup(node, IncludeNode, 0);
- Node::NodeType nodeType = node->nodeType();
+ Node::NodeType nodeType = node.nodeType();
if (nodeType != Node::DOCUMENT_NODE && nodeType != Node::DOCUMENT_TYPE_NODE)
- markupString = documentTypeString(node->document()) + markupString;
+ markupString = documentTypeString(node.document()) + markupString;
return markupString;
}
-String createFullMarkup(const Range* range)
+String createFullMarkup(const Range& range)
{
- if (!range)
- return String();
-
- Node* node = range->startContainer();
+ Node* node = range.startContainer();
if (!node)
return String();
enum EFragmentSerialization { HTMLFragmentSerialization, XMLFragmentSerialization };
PassRefPtr<DocumentFragment> createFragmentFromText(Range* context, const String& text);
-PassRefPtr<DocumentFragment> createFragmentFromMarkup(Document*, const String& markup, const String& baseURL, ParserContentPolicy = AllowScriptingContent);
-PassRefPtr<DocumentFragment> createFragmentFromMarkupWithContext(Document*, const String& markup, unsigned fragmentStart, unsigned fragmentEnd, const String& baseURL, ParserContentPolicy);
-PassRefPtr<DocumentFragment> createFragmentFromNodes(Document*, const Vector<Node*>&);
+PassRefPtr<DocumentFragment> createFragmentFromMarkup(Document&, const String& markup, const String& baseURL, ParserContentPolicy = AllowScriptingContent);
PassRefPtr<DocumentFragment> createFragmentForInnerOuterHTML(const String&, Element*, ParserContentPolicy, ExceptionCode&);
PassRefPtr<DocumentFragment> createFragmentForTransformToFragment(const String&, const String& sourceMIMEType, Document* outputDoc);
PassRefPtr<DocumentFragment> createContextualFragment(const String&, HTMLElement*, ParserContentPolicy, ExceptionCode&);
void replaceChildrenWithFragment(ContainerNode&, PassRefPtr<DocumentFragment>, ExceptionCode&);
void replaceChildrenWithText(ContainerNode&, const String&, ExceptionCode&);
-String createMarkup(const Range*, Vector<Node*>* = 0, EAnnotateForInterchange = DoNotAnnotateForInterchange, bool convertBlocksToInlines = false, EAbsoluteURLs = DoNotResolveURLs);
-String createMarkup(const Node*, EChildrenOnly = IncludeNode, Vector<Node*>* = 0, EAbsoluteURLs = DoNotResolveURLs, Vector<QualifiedName>* tagNamesToSkip = 0, EFragmentSerialization = HTMLFragmentSerialization);
+String createMarkup(const Range&, Vector<Node*>* = 0, EAnnotateForInterchange = DoNotAnnotateForInterchange, bool convertBlocksToInlines = false, EAbsoluteURLs = DoNotResolveURLs);
+String createMarkup(const Node&, EChildrenOnly = IncludeNode, Vector<Node*>* = 0, EAbsoluteURLs = DoNotResolveURLs, Vector<QualifiedName>* tagNamesToSkip = 0, EFragmentSerialization = HTMLFragmentSerialization);
-String createFullMarkup(const Node*);
-String createFullMarkup(const Range*);
+String createFullMarkup(const Node&);
+String createFullMarkup(const Range&);
String urlToMarkup(const URL&, const String& title);
String HTMLElement::innerHTML() const
{
- return createMarkup(this, ChildrenOnly);
+ return createMarkup(*this, ChildrenOnly);
}
String HTMLElement::outerHTML() const
{
- return createMarkup(this);
+ return createMarkup(*this);
}
void HTMLElement::setInnerHTML(const String& html, ExceptionCode& ec)
return static_cast<HTMLFrameOwnerElement&>(node);
}
+inline const HTMLFrameOwnerElement& toFrameOwnerElement(const Node& node)
+{
+ ASSERT_WITH_SECURITY_IMPLICATION(node.isFrameOwnerElement());
+ return static_cast<const HTMLFrameOwnerElement&>(node);
+}
+
inline HTMLFrameOwnerElement* toFrameOwnerElement(Node* node)
{
ASSERT_WITH_SECURITY_IMPLICATION(!node || node->isFrameOwnerElement());
return static_cast<HTMLFrameOwnerElement*>(node);
}
+inline const HTMLFrameOwnerElement* toFrameOwnerElement(const Node* node)
+{
+ ASSERT_WITH_SECURITY_IMPLICATION(!node || node->isFrameOwnerElement());
+ return static_cast<const HTMLFrameOwnerElement*>(node);
+}
+
+void toFrameOwnerElement(const HTMLFrameOwnerElement&);
+void toFrameOwnerElement(const HTMLFrameOwnerElement*);
+
class SubframeLoadingDisabler {
public:
explicit SubframeLoadingDisabler(ContainerNode& root)
document().ensureTemplateDocument()->adoptIfNeeded(m_content.get());
}
-#ifndef NDEBUG
-const HTMLTemplateElement* toHTMLTemplateElement(const Node* node)
-{
- ASSERT_WITH_SECURITY_IMPLICATION(!node || (node->isHTMLElement() && node->hasTagName(templateTag)));
- return static_cast<const HTMLTemplateElement*>(node);
-}
-#endif
-
} // namespace WebCore
#endif // ENABLE(TEMPLATE_ELEMENT)
mutable RefPtr<DocumentFragment> m_content;
};
-const HTMLTemplateElement* toHTMLTemplateElement(const Node*);
-
-inline HTMLTemplateElement* toHTMLTemplateElement(Node* node)
-{
- return const_cast<HTMLTemplateElement*>(toHTMLTemplateElement(static_cast<const Node*>(node)));
-}
-
-#ifdef NDEBUG
-
-// The debug version of this, with assertions, is not inlined.
-inline const HTMLTemplateElement* toHTMLTemplateElement(const Node* node)
-{
- return static_cast<const HTMLTemplateElement*>(node);
-}
-#endif // NDEBUG
+ELEMENT_TYPE_CASTS(HTMLTemplateElement)
} // namespace WebCore
class DOMEditor::SetOuterHTMLAction : public InspectorHistory::Action {
WTF_MAKE_NONCOPYABLE(SetOuterHTMLAction);
public:
- SetOuterHTMLAction(Node* node, const String& html)
+ SetOuterHTMLAction(Node& node, const String& html)
: InspectorHistory::Action("SetOuterHTML")
, m_node(node)
- , m_nextSibling(node->nextSibling())
+ , m_nextSibling(node.nextSibling())
, m_html(html)
, m_newNode(0)
, m_history(adoptPtr(new InspectorHistory()))
}
private:
- RefPtr<Node> m_node;
+ Ref<Node> m_node;
RefPtr<Node> m_nextSibling;
String m_html;
String m_oldHTML;
return m_history->perform(adoptPtr(new RemoveAttributeAction(element, name)), ec);
}
-bool DOMEditor::setOuterHTML(Node* node, const String& html, Node** newNode, ExceptionCode& ec)
+bool DOMEditor::setOuterHTML(Node& node, const String& html, Node** newNode, ExceptionCode& ec)
{
OwnPtr<SetOuterHTMLAction> action = adoptPtr(new SetOuterHTMLAction(node, html));
SetOuterHTMLAction* rawAction = action.get();
return result;
}
-bool DOMEditor::setOuterHTML(Node* node, const String& html, Node** newNode, ErrorString* errorString)
+bool DOMEditor::setOuterHTML(Node& node, const String& html, Node** newNode, ErrorString* errorString)
{
ExceptionCode ec = 0;
bool result = setOuterHTML(node, html, newNode, ec);
bool removeChild(Node* parentNode, Node*, ExceptionCode&);
bool setAttribute(Element*, const String& name, const String& value, ExceptionCode&);
bool removeAttribute(Element*, const String& name, ExceptionCode&);
- bool setOuterHTML(Node*, const String& html, Node** newNode, ExceptionCode&);
+ bool setOuterHTML(Node&, const String& html, Node** newNode, ExceptionCode&);
bool replaceWholeText(Text*, const String& text, ExceptionCode&);
bool replaceChild(Node* parentNode, PassRefPtr<Node> newNode, Node* oldNode, ExceptionCode&);
bool setNodeValue(Node* parentNode, const String& value, ExceptionCode&);
bool removeChild(Node* parentNode, Node*, ErrorString*);
bool setAttribute(Element*, const String& name, const String& value, ErrorString*);
bool removeAttribute(Element*, const String& name, ErrorString*);
- bool setOuterHTML(Node*, const String& html, Node** newNode, ErrorString*);
+ bool setOuterHTML(Node&, const String& html, Node** newNode, ErrorString*);
bool replaceWholeText(Text*, const String& text, ErrorString*);
private:
}
}
-Node* DOMPatchSupport::patchNode(Node* node, const String& markup, ExceptionCode& ec)
+Node* DOMPatchSupport::patchNode(Node& node, const String& markup, ExceptionCode& ec)
{
// Don't parse <html> as a fragment.
- if (node->isDocumentNode() || (node->parentNode() && node->parentNode()->isDocumentNode())) {
+ if (node.isDocumentNode() || (node.parentNode() && node.parentNode()->isDocumentNode())) {
patchDocument(markup);
return 0;
}
- Node* previousSibling = node->previousSibling();
+ Node* previousSibling = node.previousSibling();
// FIXME: This code should use one of createFragment* in markup.h
RefPtr<DocumentFragment> fragment = DocumentFragment::create(*m_document);
if (m_document->isHTMLDocument())
- fragment->parseHTML(markup, node->parentElement() ? node->parentElement() : m_document->documentElement());
+ fragment->parseHTML(markup, node.parentElement() ? node.parentElement() : m_document->documentElement());
else
- fragment->parseXML(markup, node->parentElement() ? node->parentElement() : m_document->documentElement());
+ fragment->parseXML(markup, node.parentElement() ? node.parentElement() : m_document->documentElement());
// Compose the old list.
- ContainerNode* parentNode = node->parentNode();
- Vector<OwnPtr<Digest> > oldList;
+ ContainerNode* parentNode = node.parentNode();
+ Vector<OwnPtr<Digest>> oldList;
for (Node* child = parentNode->firstChild(); child; child = child->nextSibling())
oldList.append(createDigest(child, 0));
// Compose the new list.
String markupCopy = markup.lower();
Vector<OwnPtr<Digest> > newList;
- for (Node* child = parentNode->firstChild(); child != node; child = child->nextSibling())
+ 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 (child->hasTagName(headTag) && !child->firstChild() && markupCopy.find("</head>") == notFound)
continue; // HTML5 parser inserts empty <body> tag whenever it parses </head>
newList.append(createDigest(child, &m_unusedNodesMap));
}
- for (Node* child = node->nextSibling(); child; child = child->nextSibling())
+ for (Node* child = node.nextSibling(); child; child = child->nextSibling())
newList.append(createDigest(child, 0));
if (!innerPatchChildren(parentNode, oldList, newList, ec)) {
// Fall back to total replace.
ec = 0;
- if (!m_domEditor->replaceChild(parentNode, fragment.release(), node, ec))
+ if (!m_domEditor->replaceChild(parentNode, fragment.release(), &node, ec))
return 0;
}
return previousSibling ? previousSibling->nextSibling() : parentNode->firstChild();
virtual ~DOMPatchSupport();
void patchDocument(const String& markup);
- Node* patchNode(Node*, const String& markup, ExceptionCode&);
+ Node* patchNode(Node&, const String& markup, ExceptionCode&);
private:
struct Digest;
if (!node)
return;
- *outerHTML = createMarkup(node);
+ *outerHTML = createMarkup(*node);
}
void InspectorDOMAgent::setOuterHTML(ErrorString* errorString, int nodeId, const String& outerHTML)
}
Node* newNode = 0;
- if (!m_domEditor->setOuterHTML(node, outerHTML, &newNode, errorString))
+ if (!m_domEditor->setOuterHTML(*node, outerHTML, &newNode, errorString))
return;
if (!newNode) {
#include "markup.h"
#include <wtf/ListHashSet.h>
#include <wtf/RetainPtr.h>
+#include <wtf/text/StringBuilder.h>
namespace WebCore {
}
Vector<Node*> nodeList;
- String markupString = createMarkup(node, IncludeNode, &nodeList, DoNotResolveURLs, tagNamesToFilter.get());
+ String markupString = createMarkup(*node, IncludeNode, &nodeList, DoNotResolveURLs, tagNamesToFilter.get());
Node::NodeType nodeType = node->nodeType();
if (nodeType != Node::DOCUMENT_NODE && nodeType != Node::DOCUMENT_TYPE_NODE)
markupString = documentTypeString(node->document()) + markupString;
PassRefPtr<LegacyWebArchive> LegacyWebArchive::create(Range* range)
{
if (!range)
- return 0;
+ return nullptr;
Node* startContainer = range->startContainer();
if (!startContainer)
- return 0;
+ return nullptr;
Document& document = startContainer->document();
Frame* frame = document.frame();
if (!frame)
- return 0;
-
- Vector<Node*> nodeList;
+ return nullptr;
// FIXME: This is always "for interchange". Is that right? See the previous method.
- String markupString = documentTypeString(document) + createMarkup(range, &nodeList, AnnotateForInterchange);
+ Vector<Node*> nodeList;
+ String markupString = documentTypeString(document) + createMarkup(*range, &nodeList, AnnotateForInterchange);
return create(markupString, frame, nodeList, 0);
}
PassRefPtr<LegacyWebArchive> LegacyWebArchive::createFromSelection(Frame* frame)
{
if (!frame)
- return 0;
+ return nullptr;
Document* document = frame->document();
if (!document)
- return 0;
+ return nullptr;
+
+ StringBuilder builder;
+ builder.append(documentTypeString(*document));
- RefPtr<Range> selectionRange = frame->selection().toNormalizedRange();
Vector<Node*> nodeList;
- String markupString = documentTypeString(*document) + createMarkup(selectionRange.get(), &nodeList, AnnotateForInterchange);
+ RefPtr<Range> selectionRange = frame->selection().toNormalizedRange();
+ if (selectionRange)
+ builder.append(createMarkup(*selectionRange, &nodeList, AnnotateForInterchange));
+ String markupString = builder.toString();
RefPtr<LegacyWebArchive> archive = create(markupString, frame, nodeList, 0);
if (!document->isFrameSet())
Document* document = frame->document();
ASSERT(document);
- RefPtr<ReplaceSelectionCommand> command = ReplaceSelectionCommand::create(*document, createFragmentFromMarkup(document, item->title(), ""), replaceOptions);
+ RefPtr<ReplaceSelectionCommand> command = ReplaceSelectionCommand::create(*document, createFragmentFromMarkup(*document, item->title(), ""), replaceOptions);
applyCommand(command);
frameSelection.revealSelection(ScrollAlignment::alignToEdgeIfNeeded);
}
namespace WebCore {
-static bool isCharsetSpecifyingNode(Node* node)
+static bool isCharsetSpecifyingNode(const Node& node)
{
- if (!node->isHTMLElement())
+ if (!node.isHTMLElement())
return false;
- HTMLElement* element = toHTMLElement(node);
- if (!element->hasTagName(HTMLNames::metaTag))
+ const HTMLElement& element = toHTMLElement(node);
+ if (!element.hasTagName(HTMLNames::metaTag))
return false;
HTMLMetaCharsetParser::AttributeList attributes;
- if (element->hasAttributes()) {
- for (unsigned i = 0; i < element->attributeCount(); ++i) {
- const Attribute& attribute = element->attributeAt(i);
+ if (element.hasAttributes()) {
+ for (unsigned i = 0; i < element.attributeCount(); ++i) {
+ const Attribute& attribute = element.attributeAt(i);
// FIXME: We should deal appropriately with the attribute if they have a namespace.
attributes.append(std::make_pair(attribute.name().toString(), attribute.value().string()));
}
return textEncoding.isValid();
}
-static bool shouldIgnoreElement(Element* element)
+static bool shouldIgnoreElement(const Element& element)
{
- return element->hasTagName(HTMLNames::scriptTag) || element->hasTagName(HTMLNames::noscriptTag) || isCharsetSpecifyingNode(element);
+ return element.hasTagName(HTMLNames::scriptTag) || element.hasTagName(HTMLNames::noscriptTag) || isCharsetSpecifyingNode(element);
}
static const QualifiedName& frameOwnerURLAttributeName(const HTMLFrameOwnerElement& frameOwner)
return isHTMLObjectElement(frameOwner) ? HTMLNames::dataAttr : HTMLNames::srcAttr;
}
-class SerializerMarkupAccumulator : public WebCore::MarkupAccumulator {
+class SerializerMarkupAccumulator final : public WebCore::MarkupAccumulator {
public:
- SerializerMarkupAccumulator(PageSerializer*, Document*, Vector<Node*>*);
+ SerializerMarkupAccumulator(PageSerializer&, Document&, Vector<Node*>*);
virtual ~SerializerMarkupAccumulator();
-protected:
- virtual void appendText(StringBuilder& out, Text*);
- virtual void appendElement(StringBuilder& out, Element*, Namespaces*);
- virtual void appendCustomAttributes(StringBuilder& out, Element*, Namespaces*);
- virtual void appendEndTag(Node*);
-
private:
- PageSerializer* m_serializer;
- Document* m_document;
+ PageSerializer& m_serializer;
+ Document& m_document;
+
+ virtual void appendText(StringBuilder&, const Text&) override;
+ virtual void appendElement(StringBuilder&, const Element&, Namespaces*) override;
+ virtual void appendCustomAttributes(StringBuilder&, const Element&, Namespaces*) override;
+ virtual void appendEndTag(const Node&) override;
};
-SerializerMarkupAccumulator::SerializerMarkupAccumulator(PageSerializer* serializer, Document* document, Vector<Node*>* nodes)
+SerializerMarkupAccumulator::SerializerMarkupAccumulator(PageSerializer& serializer, Document& document, Vector<Node*>* nodes)
: MarkupAccumulator(nodes, ResolveAllURLs)
, m_serializer(serializer)
, m_document(document)
{
// MarkupAccumulator does not serialize the <?xml ... line, so we add it explicitely to ensure the right encoding is specified.
- if (m_document->isXHTMLDocument() || m_document->xmlStandalone() || m_document->isSVGDocument())
- appendString("<?xml version=\"" + m_document->xmlVersion() + "\" encoding=\"" + m_document->charset() + "\"?>");
+ if (m_document.isXHTMLDocument() || m_document.xmlStandalone() || m_document.isSVGDocument())
+ appendString("<?xml version=\"" + m_document.xmlVersion() + "\" encoding=\"" + m_document.charset() + "\"?>");
}
SerializerMarkupAccumulator::~SerializerMarkupAccumulator()
{
}
-void SerializerMarkupAccumulator::appendText(StringBuilder& out, Text* text)
+void SerializerMarkupAccumulator::appendText(StringBuilder& out, const Text& text)
{
- Element* parent = text->parentElement();
- if (parent && !shouldIgnoreElement(parent))
+ Element* parent = text.parentElement();
+ if (parent && !shouldIgnoreElement(*parent))
MarkupAccumulator::appendText(out, text);
}
-void SerializerMarkupAccumulator::appendElement(StringBuilder& out, Element* element, Namespaces* namespaces)
+void SerializerMarkupAccumulator::appendElement(StringBuilder& out, const Element& element, Namespaces* namespaces)
{
if (!shouldIgnoreElement(element))
MarkupAccumulator::appendElement(out, element, namespaces);
- if (element->hasTagName(HTMLNames::headTag)) {
+ if (element.hasTagName(HTMLNames::headTag)) {
out.append("<meta charset=\"");
- out.append(m_document->charset());
+ out.append(m_document.charset());
out.append("\">");
}
// FIXME: For object (plugins) tags and video tag we could replace them by an image of their current contents.
}
-void SerializerMarkupAccumulator::appendCustomAttributes(StringBuilder& out, Element* element, Namespaces* namespaces)
+void SerializerMarkupAccumulator::appendCustomAttributes(StringBuilder& out, const Element& element, Namespaces* namespaces)
{
- if (!element->isFrameOwnerElement())
+ if (!element.isFrameOwnerElement())
return;
- HTMLFrameOwnerElement* frameOwner = toFrameOwnerElement(element);
- Frame* frame = frameOwner->contentFrame();
+ const HTMLFrameOwnerElement& frameOwner = toFrameOwnerElement(element);
+ Frame* frame = frameOwner.contentFrame();
if (!frame)
return;
return;
// We need to give a fake location to blank frames so they can be referenced by the serialized frame.
- url = m_serializer->urlForBlankFrame(frame);
- appendAttribute(out, element, Attribute(frameOwnerURLAttributeName(*frameOwner), url.string()), namespaces);
+ url = m_serializer.urlForBlankFrame(frame);
+ appendAttribute(out, element, Attribute(frameOwnerURLAttributeName(frameOwner), url.string()), namespaces);
}
-void SerializerMarkupAccumulator::appendEndTag(Node* node)
+void SerializerMarkupAccumulator::appendEndTag(const Node& node)
{
- if (node->isElementNode() && !shouldIgnoreElement(toElement(node)))
+ if (node.isElementNode() && !shouldIgnoreElement(toElement(node)))
MarkupAccumulator::appendEndTag(node);
}
}
Vector<Node*> nodes;
- SerializerMarkupAccumulator accumulator(this, document, &nodes);
+ SerializerMarkupAccumulator accumulator(*this, *document, &nodes);
TextEncoding textEncoding(document->charset());
CString data;
if (!textEncoding.isValid()) {
// FIXME: iframes used as images trigger this. We should deal with them correctly.
return;
}
- String text = accumulator.serializeNodes(document->documentElement(), 0, IncludeNode);
+ String text = accumulator.serializeNodes(*document->documentElement(), 0, IncludeNode);
CString frameHTML = textEncoding.encode(text.characters(), text.length(), EntitiesForUnencodables);
m_resources->append(Resource(url, document->suggestedMIMEType(), SharedBuffer::create(frameHTML.data(), frameHTML.length())));
m_resourceURLs.add(url);
String DataObjectGtk::markup() const
{
if (m_range)
- return createMarkup(m_range.get(), 0, AnnotateForInterchange, false, ResolveNonLocalURLs);
+ return createMarkup(*m_range, 0, AnnotateForInterchange, false, ResolveNonLocalURLs);
return m_markup;
}
PassRefPtr<DocumentFragment> DragData::asFragment(Frame* frame, PassRefPtr<Range>, bool, bool&) const
{
if (!m_platformDragData->hasMarkup())
- return 0;
+ return nullptr;
- return createFragmentFromMarkup(frame->document(), m_platformDragData->markup(), "");
+ if (!frame->document())
+ return nullptr;
+
+ return createFragmentFromMarkup(*frame->document(), m_platformDragData->markup(), "");
}
}
{
m_dataObject->clearAll();
m_dataObject->setText(shouldSerializeSelectedTextForClipboard == IncludeImageAltTextForClipboard ? frame->editor().selectedTextForClipboard() : frame->editor().selectedText());
- m_dataObject->setMarkup(createMarkup(selectedRange, 0, AnnotateForInterchange, false, ResolveNonLocalURLs));
+ m_dataObject->setMarkup(createMarkup(*selectedRange, 0, AnnotateForInterchange, false, ResolveNonLocalURLs));
if (m_gtkClipboard)
PasteboardHelper::defaultPasteboardHelper()->writeClipboardContents(m_gtkClipboard, canSmartCopyOrDelete ? PasteboardHelper::IncludeSmartPaste : PasteboardHelper::DoNotIncludeSmartPaste);
if (!url.isEmpty()) {
m_dataObject->setURL(url, title);
- m_dataObject->setMarkup(createMarkup(toElement(node), IncludeNode, 0, ResolveAllURLs));
+ m_dataObject->setMarkup(createMarkup(*toElement(node), IncludeNode, 0, ResolveAllURLs));
}
GRefPtr<GdkPixbuf> pixbuf = adoptGRef(image->getGdkPixbuf());
chosePlainText = false;
if (m_dataObject->hasMarkup()) {
- RefPtr<DocumentFragment> fragment = createFragmentFromMarkup(frame->document(), m_dataObject->markup(), emptyString(), DisallowScriptingAndPluginContent);
- if (fragment)
- return fragment.release();
+ if (frame->document()) {
+ RefPtr<DocumentFragment> fragment = createFragmentFromMarkup(*frame->document(), m_dataObject->markup(), emptyString(), DisallowScriptingAndPluginContent);
+ if (fragment)
+ return fragment.release();
+ }
}
if (!allowPlainText)
if (DocumentLoader* loader = frame->loader().documentLoader())
loader->addAllArchiveResources(coreArchive.get());
- fragment = createFragmentFromMarkup(frame->document(), markupString.get(), mainResource->url(), DisallowScriptingContent);
+ fragment = createFragmentFromMarkup(*frame->document(), markupString.get(), mainResource->url(), DisallowScriptingContent);
}
}
if (fragment)
// FIXME: According to XMLHttpRequest Level 2, this should use the Document.innerHTML algorithm
// from the HTML5 specification to serialize the document.
- String body = createMarkup(document);
+ String body = createMarkup(*document);
// FIXME: this should use value of document.inputEncoding to determine the encoding to use.
TextEncoding encoding = UTF8Encoding();
ec = TypeError;
return String();
}
- return createMarkup(node, IncludeNode, 0, DoNotResolveURLs, 0, XMLFragmentSerialization);
+ return createMarkup(*node, IncludeNode, 0, DoNotResolveURLs, 0, XMLFragmentSerialization);
}
} // namespace WebCore
String resultMIMEType;
String resultString;
String resultEncoding;
- if (!transformToString(sourceNode, resultMIMEType, resultString, resultEncoding))
+ if (!transformToString(*sourceNode, resultMIMEType, resultString, resultEncoding))
return 0;
return createDocumentFromSource(resultString, resultEncoding, resultMIMEType, sourceNode, 0);
}
if (outputDoc->isHTMLDocument())
resultMIMEType = "text/html";
- if (!transformToString(sourceNode, resultMIMEType, resultString, resultEncoding))
+ if (!transformToString(*sourceNode, resultMIMEType, resultString, resultEncoding))
return 0;
return createFragmentForTransformToFragment(resultString, resultMIMEType, outputDoc);
}
~XSLTProcessor();
void setXSLStyleSheet(PassRefPtr<XSLStyleSheet> styleSheet) { m_stylesheet = styleSheet; }
- bool transformToString(Node* source, String& resultMIMEType, String& resultString, String& resultEncoding);
+ bool transformToString(Node& source, String& resultMIMEType, String& resultString, String& resultEncoding);
PassRefPtr<Document> createDocumentFromSource(const String& source, const String& sourceEncoding, const String& sourceMIMEType, Node* sourceNode, Frame* frame);
// DOM methods
// According to Mozilla documentation, the node must be a Document node, an xsl:stylesheet or xsl:transform element.
// But we just use text content regardless of node type.
- cachedStylesheet->parseString(createMarkup(stylesheetRootNode));
+ cachedStylesheet->parseString(createMarkup(*stylesheetRootNode));
}
if (!cachedStylesheet || !cachedStylesheet->document())
return cachedStylesheet->compileStyleSheet();
}
-static inline xmlDocPtr xmlDocPtrFromNode(Node* sourceNode, bool& shouldDelete)
+static inline xmlDocPtr xmlDocPtrFromNode(Node& sourceNode, bool& shouldDelete)
{
- Ref<Document> ownerDocument(sourceNode->document());
- bool sourceIsDocument = (sourceNode == &ownerDocument.get());
+ Ref<Document> ownerDocument(sourceNode.document());
+ bool sourceIsDocument = (&sourceNode == &ownerDocument.get());
xmlDocPtr sourceDoc = 0;
if (sourceIsDocument && ownerDocument->transformSource())
return "application/xml";
}
-bool XSLTProcessor::transformToString(Node* sourceNode, String& mimeType, String& resultString, String& resultEncoding)
+bool XSLTProcessor::transformToString(Node& sourceNode, String& mimeType, String& resultString, String& resultEncoding)
{
- Ref<Document> ownerDocument(sourceNode->document());
+ Ref<Document> ownerDocument(sourceNode.document());
setXSLTLoadCallBack(docLoaderFunc, this, ownerDocument->cachedResourceLoader());
xsltStylesheetPtr sheet = xsltStylesheetPointer(m_stylesheet, m_stylesheetRootNode.get());
+2013-10-05 Sam Weinig <sam@webkit.org>
+
+ CTTE: Thread references through markup.h
+ https://bugs.webkit.org/show_bug.cgi?id=122403
+
+ Reviewed by Darin Adler and Andreas Kling.
+
+ * DOM/WebDOMOperations.mm:
+ (-[DOMNode markupString]):
+ (-[DOMRange markupString]):
+ * WebView/WebFrame.mm:
+ (-[WebFrame _documentFragmentWithMarkupString:baseURLString:]):
+ (-[WebFrame _documentFragmentWithNodesAsParagraphs:]):
+
2013-10-05 Sam Weinig <sam@webkit.org>
CTTE: Pass DocumentWriter around as a reference
- (NSString *)markupString
{
- return createFullMarkup(core(self));
+ return createFullMarkup(*core(self));
}
- (NSRect)_renderRect:(bool *)isReplaced
- (NSString *)markupString
{
- return createFullMarkup(core(self));
+ return createFullMarkup(*core(self));
}
@end
- (DOMDocumentFragment *)_documentFragmentWithMarkupString:(NSString *)markupString baseURLString:(NSString *)baseURLString
{
- if (!_private->coreFrame || !_private->coreFrame->document())
+ Frame* frame = _private->coreFrame;
+ if (!frame)
+ return nil;
+
+ Document* document = frame->document();
+ if (!document)
return nil;
- return kit(createFragmentFromMarkup(_private->coreFrame->document(), markupString, baseURLString, DisallowScriptingContent).get());
+ return kit(createFragmentFromMarkup(*document, markupString, baseURLString, DisallowScriptingContent).get());
}
- (DOMDocumentFragment *)_documentFragmentWithNodesAsParagraphs:(NSArray *)nodes
{
- if (!_private->coreFrame || !_private->coreFrame->document())
+ Frame* frame = _private->coreFrame;
+ if (!frame)
return nil;
-
+
+ Document* document = frame->document();
+ if (!document)
+ return nil;
+
NSEnumerator *nodeEnum = [nodes objectEnumerator];
Vector<Node*> nodesVector;
DOMNode *node;
while ((node = [nodeEnum nextObject]))
nodesVector.append(core(node));
-
- return kit(createFragmentFromNodes(_private->coreFrame->document(), nodesVector).get());
+
+ RefPtr<DocumentFragment> fragment = document->createDocumentFragment();
+
+ for (auto node : nodesVector) {
+ RefPtr<Element> element = createDefaultParagraphElement(*document);
+ element->appendChild(node, ASSERT_NO_EXCEPTION);
+ fragment->appendChild(element.release(), ASSERT_NO_EXCEPTION);
+ }
+
+ return kit(fragment.release().get());
}
- (void)_replaceSelectionWithNode:(DOMNode *)node selectReplacement:(BOOL)selectReplacement smartReplace:(BOOL)smartReplace matchStyle:(BOOL)matchStyle