diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
commit | 1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch) | |
tree | 46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/WebCore/page/PageSerializer.cpp | |
parent | 32761a6cee1d0dee366b885b7b9c777e67885688 (diff) | |
download | WebKitGtk-tarball-master.tar.gz |
webkitgtk-2.16.5HEADwebkitgtk-2.16.5master
Diffstat (limited to 'Source/WebCore/page/PageSerializer.cpp')
-rw-r--r-- | Source/WebCore/page/PageSerializer.cpp | 152 |
1 files changed, 64 insertions, 88 deletions
diff --git a/Source/WebCore/page/PageSerializer.cpp b/Source/WebCore/page/PageSerializer.cpp index 55eeaa942..93d3777aa 100644 --- a/Source/WebCore/page/PageSerializer.cpp +++ b/Source/WebCore/page/PageSerializer.cpp @@ -31,6 +31,7 @@ #include "config.h" #include "PageSerializer.h" +#include "CSSFontFaceRule.h" #include "CSSImageValue.h" #include "CSSImportRule.h" #include "CSSStyleRule.h" @@ -43,10 +44,10 @@ #include "HTMLLinkElement.h" #include "HTMLMetaCharsetParser.h" #include "HTMLNames.h" +#include "HTMLObjectElement.h" #include "HTMLStyleElement.h" #include "HTTPParsers.h" #include "Image.h" -#include "MIMETypeRegistry.h" #include "MainFrame.h" #include "MarkupAccumulator.h" #include "Page.h" @@ -66,10 +67,10 @@ namespace WebCore { static bool isCharsetSpecifyingNode(const Node& node) { - if (!node.isHTMLElement()) + if (!is<HTMLElement>(node)) return false; - const HTMLElement& element = toHTMLElement(node); + const HTMLElement& element = downcast<HTMLElement>(node); if (!element.hasTagName(HTMLNames::metaTag)) return false; HTMLMetaCharsetParser::AttributeList attributes; @@ -79,8 +80,7 @@ static bool isCharsetSpecifyingNode(const Node& node) attributes.append(std::make_pair(attribute.name().toString(), attribute.value().string())); } } - TextEncoding textEncoding = HTMLMetaCharsetParser::encodingFromMetaAttributes(attributes); - return textEncoding.isValid(); + return HTMLMetaCharsetParser::encodingFromMetaAttributes(attributes).isValid(); } static bool shouldIgnoreElement(const Element& element) @@ -91,65 +91,60 @@ static bool shouldIgnoreElement(const Element& element) static const QualifiedName& frameOwnerURLAttributeName(const HTMLFrameOwnerElement& frameOwner) { // FIXME: We should support all frame owners including applets. - return isHTMLObjectElement(frameOwner) ? HTMLNames::dataAttr : HTMLNames::srcAttr; + return is<HTMLObjectElement>(frameOwner) ? HTMLNames::dataAttr : HTMLNames::srcAttr; } -class SerializerMarkupAccumulator final : public WebCore::MarkupAccumulator { +class PageSerializer::SerializerMarkupAccumulator final : public WebCore::MarkupAccumulator { public: SerializerMarkupAccumulator(PageSerializer&, Document&, Vector<Node*>*); - virtual ~SerializerMarkupAccumulator(); private: 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; + void appendText(StringBuilder&, const Text&) override; + void appendElement(StringBuilder&, const Element&, Namespaces*) override; + void appendCustomAttributes(StringBuilder&, const Element&, Namespaces*) override; + void appendEndTag(const Element&) override; }; -SerializerMarkupAccumulator::SerializerMarkupAccumulator(PageSerializer& serializer, Document& document, Vector<Node*>* nodes) +PageSerializer::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()) + if (m_document.isXMLDocument() || m_document.xmlStandalone()) appendString("<?xml version=\"" + m_document.xmlVersion() + "\" encoding=\"" + m_document.charset() + "\"?>"); } -SerializerMarkupAccumulator::~SerializerMarkupAccumulator() -{ -} - -void SerializerMarkupAccumulator::appendText(StringBuilder& out, const Text& text) +void PageSerializer::SerializerMarkupAccumulator::appendText(StringBuilder& out, const Text& text) { Element* parent = text.parentElement(); if (parent && !shouldIgnoreElement(*parent)) MarkupAccumulator::appendText(out, text); } -void SerializerMarkupAccumulator::appendElement(StringBuilder& out, const Element& element, Namespaces* namespaces) +void PageSerializer::SerializerMarkupAccumulator::appendElement(StringBuilder& out, const Element& element, Namespaces* namespaces) { if (!shouldIgnoreElement(element)) MarkupAccumulator::appendElement(out, element, namespaces); if (element.hasTagName(HTMLNames::headTag)) { - out.append("<meta charset=\""); + out.appendLiteral("<meta charset=\""); out.append(m_document.charset()); - out.append("\">"); + out.appendLiteral("\">"); } // FIXME: For object (plugins) tags and video tag we could replace them by an image of their current contents. } -void SerializerMarkupAccumulator::appendCustomAttributes(StringBuilder& out, const Element& element, Namespaces* namespaces) +void PageSerializer::SerializerMarkupAccumulator::appendCustomAttributes(StringBuilder& out, const Element& element, Namespaces* namespaces) { - if (!element.isFrameOwnerElement()) + if (!is<HTMLFrameOwnerElement>(element)) return; - const HTMLFrameOwnerElement& frameOwner = toHTMLFrameOwnerElement(element); + const HTMLFrameOwnerElement& frameOwner = downcast<HTMLFrameOwnerElement>(element); Frame* frame = frameOwner.contentFrame(); if (!frame) return; @@ -163,32 +158,20 @@ void SerializerMarkupAccumulator::appendCustomAttributes(StringBuilder& out, con appendAttribute(out, element, Attribute(frameOwnerURLAttributeName(frameOwner), url.string()), namespaces); } -void SerializerMarkupAccumulator::appendEndTag(const Node& node) -{ - if (node.isElementNode() && !shouldIgnoreElement(toElement(node))) - MarkupAccumulator::appendEndTag(node); -} - -PageSerializer::Resource::Resource() -{ -} - -PageSerializer::Resource::Resource(const URL& url, const String& mimeType, PassRefPtr<SharedBuffer> data) - : url(url) - , mimeType(mimeType) - , data(data) +void PageSerializer::SerializerMarkupAccumulator::appendEndTag(const Element& element) { + if (!shouldIgnoreElement(element)) + MarkupAccumulator::appendEndTag(element); } -PageSerializer::PageSerializer(Vector<PageSerializer::Resource>* resources) +PageSerializer::PageSerializer(Vector<PageSerializer::Resource>& resources) : m_resources(resources) - , m_blankFrameCounter(0) { } -void PageSerializer::serialize(Page* page) +void PageSerializer::serialize(Page& page) { - serializeFrame(&page->mainFrame()); + serializeFrame(&page.mainFrame()); } void PageSerializer::serializeFrame(Frame* frame) @@ -215,35 +198,34 @@ void PageSerializer::serializeFrame(Frame* frame) // FIXME: iframes used as images trigger this. We should deal with them correctly. return; } - String text = accumulator.serializeNodes(*document->documentElement(), 0, IncludeNode); - CString frameHTML = textEncoding.encode(text.deprecatedCharacters(), text.length(), EntitiesForUnencodables); - m_resources->append(Resource(url, document->suggestedMIMEType(), SharedBuffer::create(frameHTML.data(), frameHTML.length()))); + String text = accumulator.serializeNodes(*document->documentElement(), IncludeNode); + CString frameHTML = textEncoding.encode(text, EntitiesForUnencodables); + m_resources.append({ url, document->suggestedMIMEType(), SharedBuffer::create(frameHTML.data(), frameHTML.length()) }); m_resourceURLs.add(url); - for (Vector<Node*>::iterator iter = nodes.begin(); iter != nodes.end(); ++iter) { - Node* node = *iter; - if (!node->isElementNode()) + for (auto& node : nodes) { + if (!is<Element>(*node)) continue; - Element* element = toElement(node); + Element& element = downcast<Element>(*node); // We have to process in-line style as it might contain some resources (typically background images). - if (element->isStyledElement()) - retrieveResourcesForProperties(toStyledElement(element)->inlineStyle(), document); - - if (isHTMLImageElement(element)) { - HTMLImageElement* imageElement = toHTMLImageElement(element); - URL url = document->completeURL(imageElement->getAttribute(HTMLNames::srcAttr)); - CachedImage* cachedImage = imageElement->cachedImage(); - addImageToResources(cachedImage, imageElement->renderer(), url); - } else if (element->hasTagName(HTMLNames::linkTag)) { - HTMLLinkElement* linkElement = toHTMLLinkElement(element); - if (CSSStyleSheet* sheet = linkElement->sheet()) { - URL url = document->completeURL(linkElement->getAttribute(HTMLNames::hrefAttr)); + if (is<StyledElement>(element)) + retrieveResourcesForProperties(downcast<StyledElement>(element).inlineStyle(), document); + + if (is<HTMLImageElement>(element)) { + HTMLImageElement& imageElement = downcast<HTMLImageElement>(element); + URL url = document->completeURL(imageElement.attributeWithoutSynchronization(HTMLNames::srcAttr)); + CachedImage* cachedImage = imageElement.cachedImage(); + addImageToResources(cachedImage, imageElement.renderer(), url); + } else if (is<HTMLLinkElement>(element)) { + HTMLLinkElement& linkElement = downcast<HTMLLinkElement>(element); + if (CSSStyleSheet* sheet = linkElement.sheet()) { + URL url = document->completeURL(linkElement.attributeWithoutSynchronization(HTMLNames::hrefAttr)); serializeCSSStyleSheet(sheet, url); ASSERT(m_resourceURLs.contains(url)); } - } else if (isHTMLStyleElement(element)) { - if (CSSStyleSheet* sheet = toHTMLStyleElement(element)->sheet()) + } else if (is<HTMLStyleElement>(element)) { + if (CSSStyleSheet* sheet = downcast<HTMLStyleElement>(element).sheet()) serializeCSSStyleSheet(sheet, URL()); } } @@ -261,21 +243,21 @@ void PageSerializer::serializeCSSStyleSheet(CSSStyleSheet* styleSheet, const URL if (!itemText.isEmpty()) { cssText.append(itemText); if (i < styleSheet->length() - 1) - cssText.append("\n\n"); + cssText.appendLiteral("\n\n"); } Document* document = styleSheet->ownerDocument(); // Some rules have resources associated with them that we need to retrieve. - if (rule->type() == CSSRule::IMPORT_RULE) { - CSSImportRule* importRule = static_cast<CSSImportRule*>(rule); - URL importURL = document->completeURL(importRule->href()); + if (is<CSSImportRule>(*rule)) { + CSSImportRule& importRule = downcast<CSSImportRule>(*rule); + URL importURL = document->completeURL(importRule.href()); if (m_resourceURLs.contains(importURL)) continue; - serializeCSSStyleSheet(importRule->styleSheet(), importURL); - } else if (rule->type() == CSSRule::FONT_FACE_RULE) { + serializeCSSStyleSheet(importRule.styleSheet(), importURL); + } else if (is<CSSFontFaceRule>(*rule)) { // FIXME: Add support for font face rule. It is not clear to me at this point if the actual otf/eot file can // be retrieved from the CSSFontFaceRule object. - } else if (rule->type() == CSSRule::STYLE_RULE) - retrieveResourcesForRule(static_cast<CSSStyleRule*>(rule)->styleRule(), document); + } else if (is<CSSStyleRule>(*rule)) + retrieveResourcesForRule(downcast<CSSStyleRule>(*rule).styleRule(), document); } if (url.isValid() && !m_resourceURLs.contains(url)) { @@ -283,8 +265,8 @@ void PageSerializer::serializeCSSStyleSheet(CSSStyleSheet* styleSheet, const URL TextEncoding textEncoding(styleSheet->contents().charset()); ASSERT(textEncoding.isValid()); String textString = cssText.toString(); - CString text = textEncoding.encode(textString.deprecatedCharacters(), textString.length(), EntitiesForUnencodables); - m_resources->append(Resource(url, String("text/css"), SharedBuffer::create(text.data(), text.length()))); + CString text = textEncoding.encode(textString, EntitiesForUnencodables); + m_resources.append({ url, ASCIILiteral { "text/css" }, SharedBuffer::create(text.data(), text.length()) }); m_resourceURLs.add(url); } } @@ -306,14 +288,13 @@ void PageSerializer::addImageToResources(CachedImage* image, RenderElement* imag return; } - String mimeType = image->response().mimeType(); - m_resources->append(Resource(url, mimeType, data)); + m_resources.append({ url, image->response().mimeType(), WTFMove(data) }); m_resourceURLs.add(url); } -void PageSerializer::retrieveResourcesForRule(StyleRule* rule, Document* document) +void PageSerializer::retrieveResourcesForRule(StyleRule& rule, Document* document) { - retrieveResourcesForProperties(&rule->properties(), document); + retrieveResourcesForProperties(&rule.properties(), document); } void PageSerializer::retrieveResourcesForProperties(const StyleProperties* styleDeclaration, Document* document) @@ -327,30 +308,25 @@ void PageSerializer::retrieveResourcesForProperties(const StyleProperties* style unsigned propertyCount = styleDeclaration->propertyCount(); for (unsigned i = 0; i < propertyCount; ++i) { RefPtr<CSSValue> cssValue = styleDeclaration->propertyAt(i).value(); - if (!cssValue->isImageValue()) + if (!is<CSSImageValue>(*cssValue)) continue; - StyleImage* styleImage = toCSSImageValue(cssValue.get())->cachedOrPendingImage(); - // Non cached-images are just place-holders and do not contain data. - if (!styleImage || !styleImage->isCachedImage()) + auto* image = downcast<CSSImageValue>(*cssValue).cachedImage(); + if (!image) continue; - CachedImage* image = static_cast<StyleCachedImage*>(styleImage)->cachedImage(); - - URL url = document->completeURL(image->url()); - addImageToResources(image, 0, url); + addImageToResources(image, nullptr, document->completeURL(image->url())); } } URL PageSerializer::urlForBlankFrame(Frame* frame) { - HashMap<Frame*, URL>::iterator iter = m_blankFrameURLs.find(frame); + auto iter = m_blankFrameURLs.find(frame); if (iter != m_blankFrameURLs.end()) return iter->value; String url = "wyciwyg://frame/" + String::number(m_blankFrameCounter++); URL fakeURL(ParsedURLString, url); m_blankFrameURLs.add(frame, fakeURL); - return fakeURL; } |