2 * Copyright (C) 2011 Google Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above
12 * copyright notice, this list of conditions and the following disclaimer
13 * in the documentation and/or other materials provided with the
16 * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. AND ITS CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC.
20 * OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 #include "XMLErrors.h"
35 #include "HTMLNames.h"
37 #include <wtf/text/WTFString.h>
45 using namespace HTMLNames;
47 const int maxErrors = 25;
49 XMLErrors::XMLErrors(Document* document)
50 : m_document(document)
52 , m_lastErrorPosition(TextPosition1::belowRangePosition())
56 void XMLErrors::handleError(ErrorType type, const char* message, int lineNumber, int columnNumber)
58 handleError(type, message, TextPosition1(WTF::OneBasedNumber::fromOneBasedInt(lineNumber), WTF::OneBasedNumber::fromOneBasedInt(columnNumber)));
61 void XMLErrors::handleError(ErrorType type, const char* message, TextPosition1 position)
63 if (type == fatal || (m_errorCount < maxErrors && m_lastErrorPosition.m_line != position.m_line && m_lastErrorPosition.m_column != position.m_column)) {
66 appendErrorMessage("warning", position, message);
70 appendErrorMessage("error", position, message);
73 m_lastErrorPosition = position;
78 void XMLErrors::appendErrorMessage(const String& typeString, TextPosition1 position, const char* message)
80 // <typeString> on line <lineNumber> at column <columnNumber>: <message>
81 m_errorMessages.append(typeString);
82 m_errorMessages.append(" on line ");
83 m_errorMessages.append(String::number(position.m_line.oneBasedInt()));
84 m_errorMessages.append(" at column ");
85 m_errorMessages.append(String::number(position.m_column.oneBasedInt()));
86 m_errorMessages.append(": ");
87 m_errorMessages.append(message);
90 static inline RefPtr<Element> createXHTMLParserErrorHeader(Document* doc, const String& errorMessages)
92 RefPtr<Element> reportElement = doc->createElement(QualifiedName(nullAtom, "parsererror", xhtmlNamespaceURI), false);
93 reportElement->setAttribute(styleAttr, "display: block; white-space: pre; border: 2px solid #c77; padding: 0 1em 0 1em; margin: 1em; background-color: #fdd; color: black");
96 RefPtr<Element> h3 = doc->createElement(h3Tag, false);
97 reportElement->appendChild(h3.get(), ec);
98 h3->appendChild(doc->createTextNode("This page contains the following errors:"), ec);
100 RefPtr<Element> fixed = doc->createElement(divTag, false);
101 reportElement->appendChild(fixed.get(), ec);
102 fixed->setAttribute(styleAttr, "font-family:monospace;font-size:12px");
103 fixed->appendChild(doc->createTextNode(errorMessages), ec);
105 h3 = doc->createElement(h3Tag, false);
106 reportElement->appendChild(h3.get(), ec);
107 h3->appendChild(doc->createTextNode("Below is a rendering of the page up to the first error."), ec);
109 return reportElement;
112 void XMLErrors::insertErrorMessageBlock()
114 // One or more errors occurred during parsing of the code. Display an error block to the user above
115 // the normal content (the DOM tree is created manually and includes line/col info regarding
116 // where the errors are located)
118 // Create elements for display
119 ExceptionCode ec = 0;
120 RefPtr<Element> documentElement = m_document->documentElement();
121 if (!documentElement) {
122 RefPtr<Element> rootElement = m_document->createElement(htmlTag, false);
123 m_document->appendChild(rootElement, ec);
124 RefPtr<Element> body = m_document->createElement(bodyTag, false);
125 rootElement->appendChild(body, ec);
126 documentElement = body.get();
129 else if (documentElement->namespaceURI() == SVGNames::svgNamespaceURI) {
130 RefPtr<Element> rootElement = m_document->createElement(htmlTag, false);
131 RefPtr<Element> body = m_document->createElement(bodyTag, false);
132 rootElement->appendChild(body, ec);
133 body->appendChild(documentElement, ec);
134 m_document->appendChild(rootElement.get(), ec);
135 documentElement = body.get();
138 String errorMessages = m_errorMessages.toString();
139 RefPtr<Element> reportElement = createXHTMLParserErrorHeader(m_document, errorMessages);
140 documentElement->insertBefore(reportElement, documentElement->firstChild(), ec);
142 if (m_document->transformSourceDocument()) {
143 RefPtr<Element> paragraph = m_document->createElement(pTag, false);
144 paragraph->setAttribute(styleAttr, "white-space: normal");
145 paragraph->appendChild(m_document->createTextNode("This document was created as the result of an XSL transformation. The line and column numbers given are from the transformed result."), ec);
146 reportElement->appendChild(paragraph.release(), ec);
149 m_document->updateStyleIfNeeded();
152 } // namespace WebCore