Replace WTF::move with WTFMove
[WebKit-https.git] / Source / WebCore / dom / ExtensionStyleSheets.cpp
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  *           (C) 2006 Alexey Proskuryakov (ap@webkit.org)
6  * Copyright (C) 2004-2009, 2011-2012, 2015 Apple Inc. All rights reserved.
7  * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
8  * Copyright (C) 2008, 2009, 2011, 2012 Google Inc. All rights reserved.
9  * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
10  * Copyright (C) Research In Motion Limited 2010-2011. All rights reserved.
11  *
12  * This library is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU Library General Public
14  * License as published by the Free Software Foundation; either
15  * version 2 of the License, or (at your option) any later version.
16  *
17  * This library is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20  * Library General Public License for more details.
21  *
22  * You should have received a copy of the GNU Library General Public License
23  * along with this library; see the file COPYING.LIB.  If not, write to
24  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
25  * Boston, MA 02110-1301, USA.
26  */
27
28 #include "config.h"
29 #include "ExtensionStyleSheets.h"
30
31 #include "CSSStyleSheet.h"
32 #include "Element.h"
33 #include "HTMLIFrameElement.h"
34 #include "HTMLLinkElement.h"
35 #include "HTMLStyleElement.h"
36 #include "Page.h"
37 #include "PageGroup.h"
38 #include "ProcessingInstruction.h"
39 #include "SVGNames.h"
40 #include "SVGStyleElement.h"
41 #include "Settings.h"
42 #include "StyleInvalidationAnalysis.h"
43 #include "StyleResolver.h"
44 #include "StyleSheetContents.h"
45 #include "StyleSheetList.h"
46 #include "UserContentController.h"
47 #include "UserContentURLPattern.h"
48 #include "UserStyleSheet.h"
49
50 namespace WebCore {
51
52 using namespace ContentExtensions;
53 using namespace HTMLNames;
54
55 ExtensionStyleSheets::ExtensionStyleSheets(Document& document)
56     : m_document(document)
57     , m_styleResolverChangedTimer(*this, &ExtensionStyleSheets::styleResolverChangedTimerFired)
58 {
59 }
60
61 CSSStyleSheet* ExtensionStyleSheets::pageUserSheet()
62 {
63     if (m_pageUserSheet)
64         return m_pageUserSheet.get();
65     
66     Page* owningPage = m_document.page();
67     if (!owningPage)
68         return 0;
69     
70     String userSheetText = owningPage->userStyleSheet();
71     if (userSheetText.isEmpty())
72         return 0;
73     
74     // Parse the sheet and cache it.
75     m_pageUserSheet = CSSStyleSheet::createInline(m_document, m_document.settings()->userStyleSheetLocation());
76     m_pageUserSheet->contents().setIsUserStyleSheet(true);
77     m_pageUserSheet->contents().parseString(userSheetText);
78     return m_pageUserSheet.get();
79 }
80
81 void ExtensionStyleSheets::clearPageUserSheet()
82 {
83     if (m_pageUserSheet) {
84         m_pageUserSheet = nullptr;
85         m_document.styleResolverChanged(DeferRecalcStyle);
86     }
87 }
88
89 void ExtensionStyleSheets::updatePageUserSheet()
90 {
91     clearPageUserSheet();
92     if (pageUserSheet())
93         m_document.styleResolverChanged(RecalcStyleImmediately);
94 }
95
96 const Vector<RefPtr<CSSStyleSheet>>& ExtensionStyleSheets::injectedUserStyleSheets() const
97 {
98     updateInjectedStyleSheetCache();
99     return m_injectedUserStyleSheets;
100 }
101
102 const Vector<RefPtr<CSSStyleSheet>>& ExtensionStyleSheets::injectedAuthorStyleSheets() const
103 {
104     updateInjectedStyleSheetCache();
105     return m_injectedAuthorStyleSheets;
106 }
107
108 void ExtensionStyleSheets::updateInjectedStyleSheetCache() const
109 {
110     if (m_injectedStyleSheetCacheValid)
111         return;
112     m_injectedStyleSheetCacheValid = true;
113     m_injectedUserStyleSheets.clear();
114     m_injectedAuthorStyleSheets.clear();
115
116     Page* owningPage = m_document.page();
117     if (!owningPage)
118         return;
119
120     const auto* userContentController = owningPage->userContentController();
121     if (!userContentController)
122         return;
123
124     const UserStyleSheetMap* userStyleSheets = userContentController->userStyleSheets();
125     if (!userStyleSheets)
126         return;
127
128     for (auto& styleSheets : userStyleSheets->values()) {
129         for (const auto& sheet : *styleSheets) {
130             if (sheet->injectedFrames() == InjectInTopFrameOnly && m_document.ownerElement())
131                 continue;
132
133             if (!UserContentURLPattern::matchesPatterns(m_document.url(), sheet->whitelist(), sheet->blacklist()))
134                 continue;
135
136             RefPtr<CSSStyleSheet> groupSheet = CSSStyleSheet::createInline(const_cast<Document&>(m_document), sheet->url());
137             bool isUserStyleSheet = sheet->level() == UserStyleUserLevel;
138             if (isUserStyleSheet)
139                 m_injectedUserStyleSheets.append(groupSheet);
140             else
141                 m_injectedAuthorStyleSheets.append(groupSheet);
142
143             groupSheet->contents().setIsUserStyleSheet(isUserStyleSheet);
144             groupSheet->contents().parseString(sheet->source());
145         }
146     }
147 }
148
149 void ExtensionStyleSheets::invalidateInjectedStyleSheetCache()
150 {
151     if (!m_injectedStyleSheetCacheValid)
152         return;
153     m_injectedStyleSheetCacheValid = false;
154     if (m_injectedUserStyleSheets.isEmpty() && m_injectedAuthorStyleSheets.isEmpty())
155         return;
156     m_document.styleResolverChanged(DeferRecalcStyle);
157 }
158
159 void ExtensionStyleSheets::addUserStyleSheet(Ref<StyleSheetContents>&& userSheet)
160 {
161     ASSERT(userSheet.get().isUserStyleSheet());
162     m_userStyleSheets.append(CSSStyleSheet::create(WTFMove(userSheet), &m_document));
163     m_document.styleResolverChanged(RecalcStyleImmediately);
164 }
165
166 void ExtensionStyleSheets::addAuthorStyleSheetForTesting(Ref<StyleSheetContents>&& authorSheet)
167 {
168     ASSERT(!authorSheet.get().isUserStyleSheet());
169     m_authorStyleSheetsForTesting.append(CSSStyleSheet::create(WTFMove(authorSheet), &m_document));
170     m_document.styleResolverChanged(RecalcStyleImmediately);
171 }
172
173 #if ENABLE(CONTENT_EXTENSIONS)
174 void ExtensionStyleSheets::addDisplayNoneSelector(const String& identifier, const String& selector, uint32_t selectorID)
175 {
176     auto result = m_contentExtensionSelectorSheets.add(identifier, nullptr);
177     if (result.isNewEntry) {
178         result.iterator->value = ContentExtensionStyleSheet::create(m_document);
179         m_userStyleSheets.append(&result.iterator->value->styleSheet());
180     }
181
182     result.iterator->value->addDisplayNoneSelector(selector, selectorID);
183     m_styleResolverChangedTimer.startOneShot(0);
184 }
185
186 void ExtensionStyleSheets::maybeAddContentExtensionSheet(const String& identifier, StyleSheetContents& sheet)
187 {
188     ASSERT(sheet.isUserStyleSheet());
189
190     if (m_contentExtensionSheets.contains(identifier))
191         return;
192
193     Ref<CSSStyleSheet> cssSheet = CSSStyleSheet::create(sheet, &m_document);
194     m_contentExtensionSheets.set(identifier, &cssSheet.get());
195     m_userStyleSheets.append(adoptRef(cssSheet.leakRef()));
196     m_styleResolverChangedTimer.startOneShot(0);
197 }
198 #endif // ENABLE(CONTENT_EXTENSIONS)
199
200 void ExtensionStyleSheets::styleResolverChangedTimerFired()
201 {
202     m_document.styleResolverChanged(RecalcStyleImmediately);
203 }
204
205 void ExtensionStyleSheets::detachFromDocument()
206 {
207     if (m_pageUserSheet)
208         m_pageUserSheet->detachFromDocument();
209     for (auto& sheet : m_injectedUserStyleSheets)
210         sheet->detachFromDocument();
211     for (auto& sheet :  m_injectedAuthorStyleSheets)
212         sheet->detachFromDocument();
213     for (auto& sheet : m_userStyleSheets)
214         sheet->detachFromDocument();
215     for (auto& sheet : m_authorStyleSheetsForTesting)
216         sheet->detachFromDocument();
217 }
218
219 }