root/trunk/WebCore/dom/DOMImplementation.cpp

Revision 45255, 13.3 KB (checked in by eric@webkit.org, 8 days ago)

2009-06-26 Takeshi Yoshino < tyoshino@google.com>

Reviewed by Timothy Hatcher.

Bug 26156: In view-source mode, always render the contents using HTMLViewSourceDocument
 https://bugs.webkit.org/show_bug.cgi?id=26156

When in view-source mode, render the contents using HTMLViewSourceDocument
regardless it's applicable for any plugin or not.

Chromium tells WebCore to render the contents of specified URL when
view-source: prefix is added to the URL. But currently, DOMImplementation
ignores inViewSourceMode() when the MIME type is indicating that the contents
are neither texts nor HTML family documents.

For example, we can check the contents of asf file without launching media
player. Rendering contents for view-source:-specified input is not what user
expects.

 http://code.google.com/p/chromium/issues/detail?id=10545

I want to fix this issue by this patch. IMHO, regardless of this Chromium
specific issue, I think we should force use of HTMLViewSourceDocument when
inViewSourceMode() is specified.

  • fast/frames/resources/viewsource-fake-image-file.png: Added.
  • fast/frames/viewsource-on-image-file.html: Added.
  • platform/mac/fast/frames/viewsource-on-image-file-expected.txt: Added.

2009-06-26 Takeshi Yoshino < tyoshino@google.com>

Reviewed by Timothy Hatcher.

Bug 26156: In view-source mode, always render the contents using HTMLViewSourceDocument
 https://bugs.webkit.org/show_bug.cgi?id=26156

When in view-source mode, render the contents using HTMLViewSourceDocument
regardless it's applicable for any plugin or not.

Chromium tells WebCore to render the contents of specified URL when
view-source: prefix is added to the URL. But currently, DOMImplementation
ignores inViewSourceMode() when the MIME type is indicating that the contents
are neither texts nor HTML family documents.

For example, we can check the contents of asf file without launching media
player. Rendering contents for view-source:-specified input is not what user
expects.

 http://code.google.com/p/chromium/issues/detail?id=10545

I want to fix this issue by this patch. IMHO, regardless of this Chromium
specific issue, I think we should force use of HTMLViewSourceDocument when
inViewSourceMode() is specified.

Test: fast/frames/viewsource-on-image-file.html

  • dom/DOMImplementation.cpp: (WebCore::DOMImplementation::createDocument):
  • html/HTMLViewSourceDocument.cpp: (WebCore::HTMLViewSourceDocument::createTokenizer):
  • html/HTMLViewSourceDocument.h:
  • Property svn:eol-style set to native
Line 
1/*
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 *           (C) 1999 Antti Koivisto (koivisto@kde.org)
4 *           (C) 2001 Dirk Mueller (mueller@kde.org)
5 * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
6 * Copyright (C) 2006 Samuel Weinig (sam@webkit.org)
7 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Library General Public
11 * License as published by the Free Software Foundation; either
12 * version 2 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17 * Library General Public License for more details.
18 *
19 * You should have received a copy of the GNU Library General Public License
20 * along with this library; see the file COPYING.LIB.  If not, write to
21 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22 * Boston, MA 02110-1301, USA.
23 */
24
25#include "config.h"
26#include "DOMImplementation.h"
27
28#include "ContentType.h"
29#include "CSSStyleSheet.h"
30#include "DocumentType.h"
31#include "Element.h"
32#include "ExceptionCode.h"
33#include "Frame.h"
34#include "FTPDirectoryDocument.h"
35#include "HTMLDocument.h"
36#include "HTMLNames.h"
37#include "HTMLViewSourceDocument.h"
38#include "Image.h"
39#include "ImageDocument.h"
40#include "MediaDocument.h"
41#include "MediaList.h"
42#include "MediaPlayer.h"
43#include "MIMETypeRegistry.h"
44#include "Page.h"
45#include "PluginData.h"
46#include "PluginDocument.h"
47#include "RegularExpression.h"
48#include "Settings.h"
49#include "TextDocument.h"
50#include "XMLNames.h"
51#include <wtf/StdLibExtras.h>
52
53#if ENABLE(SVG)
54#include "SVGNames.h"
55#include "SVGDocument.h"
56#endif
57
58#if ENABLE(WML)
59#include "WMLNames.h"
60#include "WMLDocument.h"
61#endif
62
63namespace WebCore {
64
65#if ENABLE(SVG)
66
67typedef HashSet<String, CaseFoldingHash> FeatureSet;
68
69static void addString(FeatureSet& set, const char* string)
70{
71    set.add(string);
72}
73
74static bool isSVG10Feature(const String &feature)
75{
76    static bool initialized = false;
77    DEFINE_STATIC_LOCAL(FeatureSet, svgFeatures, ());
78    if (!initialized) {
79#if ENABLE(SVG_USE) && ENABLE(SVG_FOREIGN_OBJECT) && ENABLE(FILTERS) && ENABLE(SVG_FONTS)
80        addString(svgFeatures, "svg");
81        addString(svgFeatures, "svg.static");
82#endif
83//      addString(svgFeatures, "svg.animation");
84//      addString(svgFeatures, "svg.dynamic");
85//      addString(svgFeatures, "svg.dom.animation");
86//      addString(svgFeatures, "svg.dom.dynamic");
87#if ENABLE(SVG_USE) && ENABLE(SVG_FOREIGN_OBJECT) && ENABLE(FILTERS) && ENABLE(SVG_FONTS)
88        addString(svgFeatures, "dom");
89        addString(svgFeatures, "dom.svg");
90        addString(svgFeatures, "dom.svg.static");
91#endif
92//      addString(svgFeatures, "svg.all");
93//      addString(svgFeatures, "dom.svg.all");
94        initialized = true;
95    }
96    return svgFeatures.contains(feature);
97}
98
99static bool isSVG11Feature(const String &feature)
100{
101    static bool initialized = false;
102    DEFINE_STATIC_LOCAL(FeatureSet, svgFeatures, ());
103    if (!initialized) {
104        // Sadly, we cannot claim to implement any of the SVG 1.1 generic feature sets
105        // lack of Font and Filter support.
106        // http://bugs.webkit.org/show_bug.cgi?id=15480
107#if ENABLE(SVG_USE) && ENABLE(SVG_FOREIGN_OBJECT) && ENABLE(FILTERS) && ENABLE(SVG_FONTS)
108        addString(svgFeatures, "SVG");
109        addString(svgFeatures, "SVGDOM");
110        addString(svgFeatures, "SVG-static");
111        addString(svgFeatures, "SVGDOM-static");
112#endif
113#if ENABLE(SVG_ANIMATION)
114        addString(svgFeatures, "SVG-animation");
115        addString(svgFeatures, "SVGDOM-animation");
116#endif
117//      addString(svgFeatures, "SVG-dynamic);
118//      addString(svgFeatures, "SVGDOM-dynamic);
119        addString(svgFeatures, "CoreAttribute");
120#if ENABLE(SVG_USE)
121        addString(svgFeatures, "Structure");
122        addString(svgFeatures, "BasicStructure");
123#endif
124        addString(svgFeatures, "ContainerAttribute");
125        addString(svgFeatures, "ConditionalProcessing");
126        addString(svgFeatures, "Image");
127        addString(svgFeatures, "Style");
128        addString(svgFeatures, "ViewportAttribute");
129        addString(svgFeatures, "Shape");
130//      addString(svgFeatures, "Text"); // requires altGlyph, bug 6426
131        addString(svgFeatures, "BasicText");
132        addString(svgFeatures, "PaintAttribute");
133        addString(svgFeatures, "BasicPaintAttribute");
134        addString(svgFeatures, "OpacityAttribute");
135        addString(svgFeatures, "GraphicsAttribute");
136        addString(svgFeatures, "BaseGraphicsAttribute");
137        addString(svgFeatures, "Marker");
138//      addString(svgFeatures, "ColorProfile"); // requires color-profile, bug 6037
139        addString(svgFeatures, "Gradient");
140        addString(svgFeatures, "Pattern");
141        addString(svgFeatures, "Clip");
142        addString(svgFeatures, "BasicClip");
143        addString(svgFeatures, "Mask");
144#if ENABLE(FILTERS)
145//      addString(svgFeatures, "Filter");
146        addString(svgFeatures, "BasicFilter");
147#endif
148        addString(svgFeatures, "DocumentEventsAttribute");
149        addString(svgFeatures, "GraphicalEventsAttribute");
150//      addString(svgFeatures, "AnimationEventsAttribute");
151        addString(svgFeatures, "Cursor");
152        addString(svgFeatures, "Hyperlinking");
153        addString(svgFeatures, "XlinkAttribute");
154        addString(svgFeatures, "ExternalResourcesRequired");
155//      addString(svgFeatures, "View"); // buggy <view> support, bug 16962
156        addString(svgFeatures, "Script");
157#if ENABLE(SVG_ANIMATION)
158        addString(svgFeatures, "Animation"); 
159#endif
160#if ENABLE(SVG_FONTS)
161        addString(svgFeatures, "Font");
162        addString(svgFeatures, "BasicFont");
163#endif
164#if ENABLE(SVG_FOREIGN_OBJECT)
165        addString(svgFeatures, "Extensibility");
166#endif
167        initialized = true;
168    }
169    return svgFeatures.contains(feature);
170}
171#endif
172
173bool DOMImplementation::hasFeature(const String& feature, const String& version)
174{
175    String lower = feature.lower();
176    if (lower == "core" || lower == "html" || lower == "xml" || lower == "xhtml")
177        return version.isEmpty() || version == "1.0" || version == "2.0";
178    if (lower == "css"
179            || lower == "css2"
180            || lower == "events"
181            || lower == "htmlevents"
182            || lower == "mouseevents"
183            || lower == "mutationevents"
184            || lower == "range"
185            || lower == "stylesheets"
186            || lower == "traversal"
187            || lower == "uievents"
188            || lower == "views")
189        return version.isEmpty() || version == "2.0";
190    if (lower == "xpath" || lower == "textevents")
191        return version.isEmpty() || version == "3.0";
192
193#if ENABLE(SVG)
194    if ((version.isEmpty() || version == "1.1") && feature.startsWith("http://www.w3.org/tr/svg11/feature#", false)) {
195        if (isSVG11Feature(feature.right(feature.length() - 35)))
196            return true;
197    }
198
199    if ((version.isEmpty() || version == "1.0") && feature.startsWith("org.w3c.", false)) {
200        if (isSVG10Feature(feature.right(feature.length() - 8)))
201            return true;
202    }
203#endif
204   
205    return false;
206}
207
208PassRefPtr<DocumentType> DOMImplementation::createDocumentType(const String& qualifiedName,
209    const String& publicId, const String& systemId, ExceptionCode& ec)
210{
211    String prefix, localName;
212    if (!Document::parseQualifiedName(qualifiedName, prefix, localName, ec))
213        return 0;
214
215    return DocumentType::create(0, qualifiedName, publicId, systemId);
216}
217
218DOMImplementation* DOMImplementation::getInterface(const String& /*feature*/)
219{
220    return 0;
221}
222
223PassRefPtr<Document> DOMImplementation::createDocument(const String& namespaceURI,
224    const String& qualifiedName, DocumentType* doctype, ExceptionCode& ec)
225{
226    // WRONG_DOCUMENT_ERR: Raised if doctype has already been used with a different document or was
227    // created from a different implementation.
228    bool shouldThrowWrongDocErr = false;
229    if (doctype && doctype->document())
230        shouldThrowWrongDocErr = true;
231
232    RefPtr<Document> doc;
233#if ENABLE(SVG)
234    if (namespaceURI == SVGNames::svgNamespaceURI)
235        doc = SVGDocument::create(0);
236    else
237#endif
238#if ENABLE(WML)
239    if (namespaceURI == WMLNames::wmlNamespaceURI)
240        doc = WMLDocument::create(0);
241    else
242#endif
243    if (namespaceURI == HTMLNames::xhtmlNamespaceURI)
244        doc = Document::createXHTML(0);
245    else
246        doc = Document::create(0);
247
248    // now get the interesting parts of the doctype
249    if (doctype)
250        doc->addChild(doctype);
251
252    if (!qualifiedName.isEmpty()) {
253        RefPtr<Node> documentElement = doc->createElementNS(namespaceURI, qualifiedName, ec);
254        if (ec)
255            return 0;
256        doc->addChild(documentElement.release());
257    }
258
259    // Hixie's interpretation of the DOM Core spec suggests we should prefer
260    // other exceptions to WRONG_DOCUMENT_ERR (based on order mentioned in spec)
261    if (shouldThrowWrongDocErr) {
262        ec = WRONG_DOCUMENT_ERR;
263        return 0;
264    }
265
266    return doc.release();
267}
268
269PassRefPtr<CSSStyleSheet> DOMImplementation::createCSSStyleSheet(const String&, const String& media, ExceptionCode&)
270{
271    // FIXME: Title should be set.
272    // FIXME: Media could have wrong syntax, in which case we should generate an exception.
273    RefPtr<CSSStyleSheet> sheet = CSSStyleSheet::create();
274    sheet->setMedia(MediaList::createAllowingDescriptionSyntax(sheet.get(), media));
275    return sheet.release();
276}
277
278PassRefPtr<Document> DOMImplementation::createDocument(Frame* frame)
279{
280    return Document::create(frame);
281}
282
283PassRefPtr<HTMLDocument> DOMImplementation::createHTMLDocument(Frame* frame)
284{
285    return HTMLDocument::create(frame);
286}
287
288bool DOMImplementation::isXMLMIMEType(const String& mimeType)
289{
290    if (mimeType == "text/xml" || mimeType == "application/xml" || mimeType == "text/xsl")
291        return true;
292    static const char* const validChars = "[0-9a-zA-Z_\\-+~!$\\^{}|.%'`#&*]"; // per RFCs: 3023, 2045
293    DEFINE_STATIC_LOCAL(RegularExpression, xmlTypeRegExp, (String("^") + validChars + "+/" + validChars + "+\\+xml$", TextCaseSensitive));
294    return xmlTypeRegExp.match(mimeType) > -1;
295}
296
297bool DOMImplementation::isTextMIMEType(const String& mimeType)
298{
299    if (MIMETypeRegistry::isSupportedJavaScriptMIMEType(mimeType) ||
300        (mimeType.startsWith("text/") && mimeType != "text/html" &&
301         mimeType != "text/xml" && mimeType != "text/xsl"))
302        return true;
303
304    return false;
305}
306
307PassRefPtr<HTMLDocument> DOMImplementation::createHTMLDocument(const String& title)
308{
309    RefPtr<HTMLDocument> d = HTMLDocument::create(0);
310    d->open();
311    d->write("<!doctype html><html><head><title>" + title + "</title></head><body></body></html>");
312    return d.release();
313}
314
315PassRefPtr<Document> DOMImplementation::createDocument(const String& type, Frame* frame, bool inViewSourceMode)
316{
317    if (inViewSourceMode)
318        return HTMLViewSourceDocument::create(frame, type);
319
320    // Plugins cannot take HTML and XHTML from us, and we don't even need to initialize the plugin database for those.
321    if (type == "text/html")
322        return HTMLDocument::create(frame);
323    if (type == "application/xhtml+xml"
324#if ENABLE(XHTMLMP)
325        || type == "application/vnd.wap.xhtml+xml"
326#endif
327        )
328        return Document::createXHTML(frame);
329
330#if ENABLE(WML)
331    if (type == "text/vnd.wap.wml" || type == "application/vnd.wap.wmlc")
332        return WMLDocument::create(frame);
333#endif
334
335#if ENABLE(FTPDIR)
336    // Plugins cannot take FTP from us either
337    if (type == "application/x-ftp-directory")
338        return FTPDirectoryDocument::create(frame);
339#endif
340
341    PluginData* pluginData = 0;
342    if (frame && frame->page() && frame->page()->settings()->arePluginsEnabled())
343        pluginData = frame->page()->pluginData();
344
345    // PDF is one image type for which a plugin can override built-in support.
346    // We do not want QuickTime to take over all image types, obviously.
347    if ((type == "application/pdf" || type == "text/pdf") && pluginData && pluginData->supportsMimeType(type))
348        return PluginDocument::create(frame);
349    if (Image::supportsType(type))
350        return ImageDocument::create(frame);
351
352#if ENABLE(VIDEO)
353     // Check to see if the type can be played by our MediaPlayer, if so create a MediaDocument
354     if (MediaPlayer::supportsType(ContentType(type)))
355         return MediaDocument::create(frame);
356#endif
357
358    // Everything else except text/plain can be overridden by plugins. In particular, Adobe SVG Viewer should be used for SVG, if installed.
359    // Disallowing plug-ins to use text/plain prevents plug-ins from hijacking a fundamental type that the browser is expected to handle,
360    // and also serves as an optimization to prevent loading the plug-in database in the common case.
361    if (type != "text/plain" && pluginData && pluginData->supportsMimeType(type)) 
362        return PluginDocument::create(frame);
363    if (isTextMIMEType(type))
364        return TextDocument::create(frame);
365
366#if ENABLE(SVG)
367    if (type == "image/svg+xml") {
368#if ENABLE(DASHBOARD_SUPPORT)   
369        Settings* settings = frame ? frame->settings() : 0;
370        if (!settings || !settings->usesDashboardBackwardCompatibilityMode())
371#endif
372            return SVGDocument::create(frame);
373    }
374#endif
375    if (isXMLMIMEType(type))
376        return Document::create(frame);
377
378    return HTMLDocument::create(frame);
379}
380
381}
Note: See TracBrowser for help on using the browser.