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 "CSSStyleSheet.h" |
29 | #include "ContentType.h" |
30 | #include "DocumentType.h" |
31 | #include "Element.h" |
32 | #include "FTPDirectoryDocument.h" |
33 | #include "Frame.h" |
34 | #include "FrameLoader.h" |
35 | #include "FrameLoaderClient.h" |
36 | #include "HTMLDocument.h" |
37 | #include "HTMLHeadElement.h" |
38 | #include "HTMLTitleElement.h" |
39 | #include "Image.h" |
40 | #include "ImageDocument.h" |
41 | #include "MIMETypeRegistry.h" |
42 | #include "MediaDocument.h" |
43 | #include "MediaList.h" |
44 | #include "MediaPlayer.h" |
45 | #include "Page.h" |
46 | #include "PluginData.h" |
47 | #include "PluginDocument.h" |
48 | #include "SVGDocument.h" |
49 | #include "SVGNames.h" |
50 | #include "SecurityOrigin.h" |
51 | #include "SecurityOriginPolicy.h" |
52 | #include "Settings.h" |
53 | #include "StyleSheetContents.h" |
54 | #include "SubframeLoader.h" |
55 | #include "Text.h" |
56 | #include "TextDocument.h" |
57 | #include "XMLDocument.h" |
58 | #include <wtf/IsoMallocInlines.h> |
59 | #include <wtf/StdLibExtras.h> |
60 | |
61 | namespace WebCore { |
62 | |
63 | using namespace HTMLNames; |
64 | |
65 | WTF_MAKE_ISO_ALLOCATED_IMPL(DOMImplementation); |
66 | |
67 | DOMImplementation::DOMImplementation(Document& document) |
68 | : m_document(document) |
69 | { |
70 | } |
71 | |
72 | ExceptionOr<Ref<DocumentType>> DOMImplementation::createDocumentType(const String& qualifiedName, const String& publicId, const String& systemId) |
73 | { |
74 | auto parseResult = Document::parseQualifiedName(qualifiedName); |
75 | if (parseResult.hasException()) |
76 | return parseResult.releaseException(); |
77 | return DocumentType::create(m_document, qualifiedName, publicId, systemId); |
78 | } |
79 | |
80 | static inline Ref<XMLDocument> createXMLDocument(const String& namespaceURI) |
81 | { |
82 | if (namespaceURI == SVGNames::svgNamespaceURI) |
83 | return SVGDocument::create(nullptr, URL()); |
84 | if (namespaceURI == HTMLNames::xhtmlNamespaceURI) |
85 | return XMLDocument::createXHTML(nullptr, URL()); |
86 | return XMLDocument::create(nullptr, URL()); |
87 | } |
88 | |
89 | ExceptionOr<Ref<XMLDocument>> DOMImplementation::createDocument(const String& namespaceURI, const String& qualifiedName, DocumentType* documentType) |
90 | { |
91 | auto document = createXMLDocument(namespaceURI); |
92 | document->setContextDocument(m_document.contextDocument()); |
93 | document->setSecurityOriginPolicy(m_document.securityOriginPolicy()); |
94 | |
95 | RefPtr<Element> documentElement; |
96 | if (!qualifiedName.isEmpty()) { |
97 | ASSERT(!document->domWindow()); // If domWindow is not null, createElementNS could find CustomElementRegistry and arbitrary scripts. |
98 | auto result = document->createElementNS(namespaceURI, qualifiedName); |
99 | if (result.hasException()) |
100 | return result.releaseException(); |
101 | documentElement = result.releaseReturnValue(); |
102 | } |
103 | |
104 | if (documentType) |
105 | document->appendChild(*documentType); |
106 | if (documentElement) |
107 | document->appendChild(*documentElement); |
108 | |
109 | return document; |
110 | } |
111 | |
112 | Ref<CSSStyleSheet> DOMImplementation::createCSSStyleSheet(const String&, const String& media) |
113 | { |
114 | // FIXME: Title should be set. |
115 | // FIXME: Media could have wrong syntax, in which case we should generate an exception. |
116 | auto sheet = CSSStyleSheet::create(StyleSheetContents::create()); |
117 | sheet->setMediaQueries(MediaQuerySet::create(media)); |
118 | return sheet; |
119 | } |
120 | |
121 | Ref<HTMLDocument> DOMImplementation::createHTMLDocument(const String& title) |
122 | { |
123 | auto document = HTMLDocument::create(nullptr, URL()); |
124 | document->open(); |
125 | document->write(nullptr, { "<!doctype html><html><head></head><body></body></html>"_s }); |
126 | if (!title.isNull()) { |
127 | auto titleElement = HTMLTitleElement::create(titleTag, document); |
128 | titleElement->appendChild(document->createTextNode(title)); |
129 | ASSERT(document->head()); |
130 | document->head()->appendChild(titleElement); |
131 | } |
132 | document->setContextDocument(m_document.contextDocument()); |
133 | document->setSecurityOriginPolicy(m_document.securityOriginPolicy()); |
134 | return document; |
135 | } |
136 | |
137 | Ref<Document> DOMImplementation::createDocument(const String& type, Frame* frame, const URL& url) |
138 | { |
139 | // FIXME: Inelegant to have this here just because this is the home of DOM APIs for creating documents. |
140 | // This is internal, not a DOM API. Maybe we should put it in a new class called DocumentFactory, |
141 | // because of the analogy with HTMLElementFactory. |
142 | |
143 | // Plug-ins cannot take over for HTML, XHTML, plain text, or non-PDF images. |
144 | if (equalLettersIgnoringASCIICase(type, "text/html" )) |
145 | return HTMLDocument::create(frame, url); |
146 | if (equalLettersIgnoringASCIICase(type, "application/xhtml+xml" )) |
147 | return XMLDocument::createXHTML(frame, url); |
148 | if (equalLettersIgnoringASCIICase(type, "text/plain" )) |
149 | return TextDocument::create(frame, url); |
150 | bool isImage = MIMETypeRegistry::isSupportedImageMIMEType(type); |
151 | if (frame && isImage && !MIMETypeRegistry::isPDFOrPostScriptMIMEType(type)) |
152 | return ImageDocument::create(*frame, url); |
153 | |
154 | // The "image documents for subframe PDFs" mode will override a PDF plug-in. |
155 | if (frame && !frame->isMainFrame() && MIMETypeRegistry::isPDFMIMEType(type) && frame->settings().useImageDocumentForSubframePDF()) |
156 | return ImageDocument::create(*frame, url); |
157 | |
158 | #if ENABLE(VIDEO) |
159 | MediaEngineSupportParameters parameters; |
160 | parameters.type = ContentType { type }; |
161 | parameters.url = url; |
162 | if (MediaPlayer::supportsType(parameters)) |
163 | return MediaDocument::create(frame, url); |
164 | #endif |
165 | |
166 | #if ENABLE(FTPDIR) |
167 | if (equalLettersIgnoringASCIICase(type, "application/x-ftp-directory" )) |
168 | return FTPDirectoryDocument::create(frame, url); |
169 | #endif |
170 | |
171 | if (frame && frame->loader().client().shouldAlwaysUsePluginDocument(type)) |
172 | return PluginDocument::create(frame, url); |
173 | |
174 | // The following is the relatively costly lookup that requires initializing the plug-in database. |
175 | if (frame && frame->page()) { |
176 | auto allowedPluginTypes = frame->loader().subframeLoader().allowPlugins() |
177 | ? PluginData::AllPlugins : PluginData::OnlyApplicationPlugins; |
178 | if (frame->page()->pluginData().supportsWebVisibleMimeType(type, allowedPluginTypes)) |
179 | return PluginDocument::create(frame, url); |
180 | } |
181 | |
182 | // Items listed here, after the plug-in checks, can be overridden by plug-ins. |
183 | // For example, plug-ins can take over support for PDF or SVG. |
184 | if (frame && isImage) |
185 | return ImageDocument::create(*frame, url); |
186 | if (MIMETypeRegistry::isTextMIMEType(type)) |
187 | return TextDocument::create(frame, url); |
188 | if (equalLettersIgnoringASCIICase(type, "image/svg+xml" )) |
189 | return SVGDocument::create(frame, url); |
190 | if (MIMETypeRegistry::isXMLMIMEType(type)) |
191 | return XMLDocument::create(frame, url); |
192 | return HTMLDocument::create(frame, url); |
193 | } |
194 | |
195 | } |
196 | |