1/*
2 * This file is part of the XSL implementation.
3 *
4 * Copyright (C) 2004, 2006, 2008, 2012 Apple Inc. All rights reserved.
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public License
17 * along with this library; see the file COPYING.LIB. If not, write to
18 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
20 *
21 */
22
23#pragma once
24
25#if ENABLE(XSLT)
26
27#include "ProcessingInstruction.h"
28#include "StyleSheet.h"
29#include <libxml/parser.h>
30#include <libxslt/transform.h>
31#include <wtf/Ref.h>
32#include <wtf/TypeCasts.h>
33
34namespace WebCore {
35
36class CachedResourceLoader;
37class XSLImportRule;
38
39class XSLStyleSheet final : public StyleSheet {
40public:
41 static Ref<XSLStyleSheet> create(XSLImportRule* parentImport, const String& originalURL, const URL& finalURL)
42 {
43 return adoptRef(*new XSLStyleSheet(parentImport, originalURL, finalURL));
44 }
45 static Ref<XSLStyleSheet> create(ProcessingInstruction* parentNode, const String& originalURL, const URL& finalURL)
46 {
47 return adoptRef(*new XSLStyleSheet(parentNode, originalURL, finalURL, false));
48 }
49 static Ref<XSLStyleSheet> createEmbedded(ProcessingInstruction* parentNode, const URL& finalURL)
50 {
51 return adoptRef(*new XSLStyleSheet(parentNode, finalURL.string(), finalURL, true));
52 }
53
54 // Taking an arbitrary node is unsafe, because owner node pointer can become stale.
55 // XSLTProcessor ensures that the stylesheet doesn't outlive its parent, in part by not exposing it to JavaScript.
56 static Ref<XSLStyleSheet> createForXSLTProcessor(Node* parentNode, const String& originalURL, const URL& finalURL)
57 {
58 return adoptRef(*new XSLStyleSheet(parentNode, originalURL, finalURL, false));
59 }
60
61 virtual ~XSLStyleSheet();
62
63 bool parseString(const String&);
64
65 void checkLoaded();
66
67 const URL& finalURL() const { return m_finalURL; }
68
69 void loadChildSheets();
70 void loadChildSheet(const String& href);
71
72 CachedResourceLoader* cachedResourceLoader();
73
74 Document* ownerDocument();
75 XSLStyleSheet* parentStyleSheet() const override { return m_parentStyleSheet; }
76 void setParentStyleSheet(XSLStyleSheet* parent);
77
78 xmlDocPtr document();
79 xsltStylesheetPtr compileStyleSheet();
80 xmlDocPtr locateStylesheetSubResource(xmlDocPtr parentDoc, const xmlChar* uri);
81
82 void clearDocuments();
83
84 void markAsProcessed();
85 bool processed() const { return m_processed; }
86
87 String type() const override { return "text/xml"; }
88 bool disabled() const override { return m_isDisabled; }
89 void setDisabled(bool b) override { m_isDisabled = b; }
90 Node* ownerNode() const override { return m_ownerNode; }
91 String href() const override { return m_originalURL; }
92 String title() const override { return emptyString(); }
93
94 void clearOwnerNode() override { m_ownerNode = nullptr; }
95 URL baseURL() const override { return m_finalURL; }
96 bool isLoading() const override;
97
98private:
99 XSLStyleSheet(Node* parentNode, const String& originalURL, const URL& finalURL, bool embedded);
100 XSLStyleSheet(XSLImportRule* parentImport, const String& originalURL, const URL& finalURL);
101
102 bool isXSLStyleSheet() const override { return true; }
103
104 void clearXSLStylesheetDocument();
105
106 Node* m_ownerNode;
107 String m_originalURL;
108 URL m_finalURL;
109 bool m_isDisabled { false };
110
111 Vector<std::unique_ptr<XSLImportRule>> m_children;
112
113 bool m_embedded;
114 bool m_processed;
115
116 xmlDocPtr m_stylesheetDoc { nullptr };
117 bool m_stylesheetDocTaken { false };
118 bool m_compilationFailed { false };
119
120 XSLStyleSheet* m_parentStyleSheet { nullptr };
121};
122
123} // namespace WebCore
124
125SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::XSLStyleSheet)
126 static bool isType(const WebCore::StyleSheet& styleSheet) { return styleSheet.isXSLStyleSheet(); }
127SPECIALIZE_TYPE_TRAITS_END()
128
129#endif // ENABLE(XSLT)
130