diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2016-04-10 09:28:39 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2016-04-10 09:28:39 +0000 |
commit | 32761a6cee1d0dee366b885b7b9c777e67885688 (patch) | |
tree | d6bec92bebfb216f4126356e55518842c2f476a1 /Source/WebCore/html/HTMLViewSourceDocument.cpp | |
parent | a4e969f4965059196ca948db781e52f7cfebf19e (diff) | |
download | WebKitGtk-tarball-32761a6cee1d0dee366b885b7b9c777e67885688.tar.gz |
webkitgtk-2.4.11webkitgtk-2.4.11
Diffstat (limited to 'Source/WebCore/html/HTMLViewSourceDocument.cpp')
-rw-r--r-- | Source/WebCore/html/HTMLViewSourceDocument.cpp | 294 |
1 files changed, 294 insertions, 0 deletions
diff --git a/Source/WebCore/html/HTMLViewSourceDocument.cpp b/Source/WebCore/html/HTMLViewSourceDocument.cpp new file mode 100644 index 000000000..5b705d9ce --- /dev/null +++ b/Source/WebCore/html/HTMLViewSourceDocument.cpp @@ -0,0 +1,294 @@ +/* + * Copyright (C) 2006, 2008, 2009, 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "HTMLViewSourceDocument.h" + +#include "DOMImplementation.h" +#include "DocumentStyleSheetCollection.h" +#include "HTMLAnchorElement.h" +#include "HTMLBRElement.h" +#include "HTMLBaseElement.h" +#include "HTMLBodyElement.h" +#include "HTMLDivElement.h" +#include "HTMLHtmlElement.h" +#include "HTMLTableCellElement.h" +#include "HTMLTableElement.h" +#include "HTMLTableRowElement.h" +#include "HTMLTableSectionElement.h" +#include "Text.h" +#include "TextViewSourceParser.h" + +namespace WebCore { + +using namespace HTMLNames; + +HTMLViewSourceDocument::HTMLViewSourceDocument(Frame* frame, const URL& url, const String& mimeType) + : HTMLDocument(frame, url) + , m_type(mimeType) +{ + styleSheetCollection().setUsesBeforeAfterRulesOverride(true); + setIsViewSource(true); + + setCompatibilityMode(QuirksMode); + lockCompatibilityMode(); +} + +PassRefPtr<DocumentParser> HTMLViewSourceDocument::createParser() +{ + if (m_type == "text/html" || m_type == "application/xhtml+xml" || m_type == "image/svg+xml" || DOMImplementation::isXMLMIMEType(m_type)) + return HTMLViewSourceParser::create(*this); + + return TextViewSourceParser::create(*this); +} + +void HTMLViewSourceDocument::createContainingTable() +{ + RefPtr<HTMLHtmlElement> html = HTMLHtmlElement::create(*this); + parserAppendChild(html); + RefPtr<HTMLBodyElement> body = HTMLBodyElement::create(*this); + html->parserAppendChild(body); + // Create a line gutter div that can be used to make sure the gutter extends down the height of the whole + // document. + RefPtr<HTMLDivElement> div = HTMLDivElement::create(*this); + div->setAttribute(classAttr, "webkit-line-gutter-backdrop"); + body->parserAppendChild(div); + + RefPtr<HTMLTableElement> table = HTMLTableElement::create(*this); + body->parserAppendChild(table); + m_tbody = HTMLTableSectionElement::create(tbodyTag, *this); + table->parserAppendChild(m_tbody); + m_current = m_tbody; +} + +void HTMLViewSourceDocument::addSource(const String& source, HTMLToken& token) +{ + if (!m_current) + createContainingTable(); + + switch (token.type()) { + case HTMLToken::Uninitialized: + ASSERT_NOT_REACHED(); + break; + case HTMLToken::DOCTYPE: + processDoctypeToken(source, token); + break; + case HTMLToken::EndOfFile: + if (!m_tbody->hasChildNodes()) + addLine(String()); + break; + case HTMLToken::StartTag: + case HTMLToken::EndTag: + processTagToken(source, token); + break; + case HTMLToken::Comment: + processCommentToken(source, token); + break; + case HTMLToken::Character: + processCharacterToken(source, token); + break; + } +} + +void HTMLViewSourceDocument::processDoctypeToken(const String& source, HTMLToken&) +{ + if (!m_current) + createContainingTable(); + m_current = addSpanWithClassName("webkit-html-doctype"); + addText(source, "webkit-html-doctype"); + m_current = m_td; +} + +void HTMLViewSourceDocument::processTagToken(const String& source, HTMLToken& token) +{ + m_current = addSpanWithClassName("webkit-html-tag"); + + AtomicString tagName(token.name()); + + unsigned index = 0; + HTMLToken::AttributeList::const_iterator iter = token.attributes().begin(); + while (index < source.length()) { + if (iter == token.attributes().end()) { + // We want to show the remaining characters in the token. + index = addRange(source, index, source.length(), ""); + ASSERT(index == source.length()); + break; + } + + AtomicString name(iter->name); + String value = StringImpl::create8BitIfPossible(iter->value); + + index = addRange(source, index, iter->nameRange.start - token.startIndex(), ""); + index = addRange(source, index, iter->nameRange.end - token.startIndex(), "webkit-html-attribute-name"); + + if (tagName == baseTag && name == hrefAttr) + m_current = addBase(value); + + index = addRange(source, index, iter->valueRange.start - token.startIndex(), ""); + + bool isLink = name == srcAttr || name == hrefAttr; + index = addRange(source, index, iter->valueRange.end - token.startIndex(), "webkit-html-attribute-value", isLink, tagName == aTag, value); + + ++iter; + } + m_current = m_td; +} + +void HTMLViewSourceDocument::processCommentToken(const String& source, HTMLToken&) +{ + m_current = addSpanWithClassName("webkit-html-comment"); + addText(source, "webkit-html-comment"); + m_current = m_td; +} + +void HTMLViewSourceDocument::processCharacterToken(const String& source, HTMLToken&) +{ + addText(source, ""); +} + +PassRefPtr<Element> HTMLViewSourceDocument::addSpanWithClassName(const AtomicString& className) +{ + if (m_current == m_tbody) { + addLine(className); + return m_current; + } + + RefPtr<HTMLElement> span = HTMLElement::create(spanTag, *this); + span->setAttribute(classAttr, className); + m_current->parserAppendChild(span); + return span.release(); +} + +void HTMLViewSourceDocument::addLine(const AtomicString& className) +{ + // Create a table row. + RefPtr<HTMLTableRowElement> trow = HTMLTableRowElement::create(*this); + m_tbody->parserAppendChild(trow); + + // Create a cell that will hold the line number (it is generated in the stylesheet using counters). + RefPtr<HTMLTableCellElement> td = HTMLTableCellElement::create(tdTag, *this); + td->setAttribute(classAttr, "webkit-line-number"); + trow->parserAppendChild(td); + + // Create a second cell for the line contents + td = HTMLTableCellElement::create(tdTag, *this); + td->setAttribute(classAttr, "webkit-line-content"); + trow->parserAppendChild(td); + m_current = m_td = td; + +#ifdef DEBUG_LINE_NUMBERS + RefPtr<Text> lineNumberText = Text::create(*this, String::number(parser()->lineNumber() + 1) + " "); + td->addChild(lineNumberText); +#endif + + // Open up the needed spans. + if (!className.isEmpty()) { + if (className == "webkit-html-attribute-name" || className == "webkit-html-attribute-value") + m_current = addSpanWithClassName("webkit-html-tag"); + m_current = addSpanWithClassName(className); + } +} + +void HTMLViewSourceDocument::finishLine() +{ + if (!m_current->hasChildNodes()) { + RefPtr<HTMLBRElement> br = HTMLBRElement::create(*this); + m_current->parserAppendChild(br); + } + m_current = m_tbody; +} + +void HTMLViewSourceDocument::addText(const String& text, const AtomicString& className) +{ + if (text.isEmpty()) + return; + + // Add in the content, splitting on newlines. + Vector<String> lines; + text.split('\n', true, lines); + unsigned size = lines.size(); + for (unsigned i = 0; i < size; i++) { + String substring = lines[i]; + if (m_current == m_tbody) + addLine(className); + if (substring.isEmpty()) { + if (i == size - 1) + break; + finishLine(); + continue; + } + RefPtr<Text> text = Text::create(*this, substring); + m_current->parserAppendChild(text); + if (i < size - 1) + finishLine(); + } +} + +int HTMLViewSourceDocument::addRange(const String& source, int start, int end, const String& className, bool isLink, bool isAnchor, const String& link) +{ + ASSERT(start <= end); + if (start == end) + return start; + + String text = source.substring(start, end - start); + if (!className.isEmpty()) { + if (isLink) + m_current = addLink(link, isAnchor); + else + m_current = addSpanWithClassName(className); + } + addText(text, className); + if (!className.isEmpty() && m_current != m_tbody) + m_current = toElement(m_current->parentNode()); + return end; +} + +PassRefPtr<Element> HTMLViewSourceDocument::addBase(const AtomicString& href) +{ + RefPtr<HTMLBaseElement> base = HTMLBaseElement::create(baseTag, *this); + base->setAttribute(hrefAttr, href); + m_current->parserAppendChild(base); + return base.release(); +} + +PassRefPtr<Element> HTMLViewSourceDocument::addLink(const AtomicString& url, bool isAnchor) +{ + if (m_current == m_tbody) + addLine("webkit-html-tag"); + + // Now create a link for the attribute value instead of a span. + RefPtr<HTMLAnchorElement> anchor = HTMLAnchorElement::create(*this); + const char* classValue; + if (isAnchor) + classValue = "webkit-html-attribute-value webkit-html-external-link"; + else + classValue = "webkit-html-attribute-value webkit-html-resource-link"; + anchor->setAttribute(classAttr, classValue); + anchor->setAttribute(targetAttr, "_blank"); + anchor->setAttribute(hrefAttr, url); + m_current->parserAppendChild(anchor); + return anchor.release(); +} + +} |