Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: sky/engine/core/css/CSSStyleSheet.cpp

Issue 780483002: Remove the CSSOM. (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « sky/engine/core/css/CSSStyleSheet.h ('k') | sky/engine/core/css/CSSStyleSheet.idl » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * (C) 1999-2003 Lars Knoll (knoll@kde.org) 2 * (C) 1999-2003 Lars Knoll (knoll@kde.org)
3 * Copyright (C) 2004, 2006, 2007, 2012 Apple Inc. All rights reserved. 3 * Copyright (C) 2004, 2006, 2007, 2012 Apple Inc. All rights reserved.
4 * 4 *
5 * This library is free software; you can redistribute it and/or 5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public 6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either 7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version. 8 * version 2 of the License, or (at your option) any later version.
9 * 9 *
10 * This library is distributed in the hope that it will be useful, 10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details. 13 * Library General Public License for more details.
14 * 14 *
15 * You should have received a copy of the GNU Library General Public License 15 * You should have received a copy of the GNU Library General Public License
16 * along with this library; see the file COPYING.LIB. If not, write to 16 * along with this library; see the file COPYING.LIB. If not, write to
17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301, USA. 18 * Boston, MA 02110-1301, USA.
19 */ 19 */
20 20
21 #include "sky/engine/config.h" 21 #include "sky/engine/config.h"
22 #include "sky/engine/core/css/CSSStyleSheet.h" 22 #include "sky/engine/core/css/CSSStyleSheet.h"
23 23
24 #include "sky/engine/bindings/core/v8/ExceptionState.h" 24 #include "sky/engine/bindings/core/v8/ExceptionState.h"
25 #include "sky/engine/bindings/core/v8/V8Binding.h" 25 #include "sky/engine/bindings/core/v8/V8Binding.h"
26 #include "sky/engine/bindings/core/v8/V8PerIsolateData.h" 26 #include "sky/engine/bindings/core/v8/V8PerIsolateData.h"
27 #include "sky/engine/core/css/CSSRuleList.h"
28 #include "sky/engine/core/css/MediaList.h" 27 #include "sky/engine/core/css/MediaList.h"
29 #include "sky/engine/core/css/StyleRule.h" 28 #include "sky/engine/core/css/StyleRule.h"
30 #include "sky/engine/core/css/StyleSheetContents.h" 29 #include "sky/engine/core/css/StyleSheetContents.h"
31 #include "sky/engine/core/css/parser/BisonCSSParser.h" 30 #include "sky/engine/core/css/parser/BisonCSSParser.h"
32 #include "sky/engine/core/dom/Document.h" 31 #include "sky/engine/core/dom/Document.h"
33 #include "sky/engine/core/dom/ExceptionCode.h" 32 #include "sky/engine/core/dom/ExceptionCode.h"
34 #include "sky/engine/core/dom/Node.h" 33 #include "sky/engine/core/dom/Node.h"
35 #include "sky/engine/core/frame/UseCounter.h" 34 #include "sky/engine/core/frame/UseCounter.h"
36 #include "sky/engine/core/html/HTMLStyleElement.h" 35 #include "sky/engine/core/html/HTMLStyleElement.h"
37 #include "sky/engine/wtf/text/StringBuilder.h" 36 #include "sky/engine/wtf/text/StringBuilder.h"
38 37
39 namespace blink { 38 namespace blink {
40 39
41 class StyleSheetCSSRuleList final : public CSSRuleList {
42 public:
43 static PassOwnPtr<StyleSheetCSSRuleList> create(CSSStyleSheet* sheet)
44 {
45 return adoptPtr(new StyleSheetCSSRuleList(sheet));
46 }
47
48 private:
49 StyleSheetCSSRuleList(CSSStyleSheet* sheet) : m_styleSheet(sheet) { }
50
51 virtual void ref() override { m_styleSheet->ref(); }
52 virtual void deref() override { m_styleSheet->deref(); }
53
54 virtual unsigned length() const override { return m_styleSheet->length(); }
55 virtual CSSRule* item(unsigned index) const override { return m_styleSheet-> item(index); }
56
57 virtual CSSStyleSheet* styleSheet() const override { return m_styleSheet; }
58
59 RawPtr<CSSStyleSheet> m_styleSheet;
60 };
61
62 #if ENABLE(ASSERT) 40 #if ENABLE(ASSERT)
63 static bool isAcceptableCSSStyleSheetParent(Node* parentNode) 41 static bool isAcceptableCSSStyleSheetParent(Node* parentNode)
64 { 42 {
65 // Only these nodes can be parents of StyleSheets, and they need to call 43 // Only these nodes can be parents of StyleSheets, and they need to call
66 // clearOwnerNode() when moved out of document. 44 // clearOwnerNode() when moved out of document.
67 // Destruction of the style sheet counts as being "moved out of the 45 // Destruction of the style sheet counts as being "moved out of the
68 // document", but only in the non-oilpan version of blink. I.e. don't call 46 // document", but only in the non-oilpan version of blink. I.e. don't call
69 // clearOwnerNode() in the owner's destructor in oilpan. 47 // clearOwnerNode() in the owner's destructor in oilpan.
70 return !parentNode 48 return !parentNode
71 || parentNode->isDocumentNode() 49 || parentNode->isDocumentNode()
(...skipping 28 matching lines...) Expand all
100 , m_isInlineStylesheet(isInlineStylesheet) 78 , m_isInlineStylesheet(isInlineStylesheet)
101 , m_ownerNode(ownerNode) 79 , m_ownerNode(ownerNode)
102 , m_startPosition(startPosition) 80 , m_startPosition(startPosition)
103 { 81 {
104 ASSERT(isAcceptableCSSStyleSheetParent(ownerNode)); 82 ASSERT(isAcceptableCSSStyleSheetParent(ownerNode));
105 m_contents->registerClient(this); 83 m_contents->registerClient(this);
106 } 84 }
107 85
108 CSSStyleSheet::~CSSStyleSheet() 86 CSSStyleSheet::~CSSStyleSheet()
109 { 87 {
110 // With oilpan the parent style sheet pointer is strong and the sheet and
111 // its RuleCSSOMWrappers die together and we don't need to clear them here.
112 // Also with oilpan the StyleSheetContents client pointers are weak and
113 // therefore do not need to be cleared here.
114 // For style rules outside the document, .parentStyleSheet can become null e ven if the style rule
115 // is still observable from JavaScript. This matches the behavior of .parent Node for nodes, but
116 // it's not ideal because it makes the CSSOM's behavior depend on the timing of garbage collection.
117 for (unsigned i = 0; i < m_childRuleCSSOMWrappers.size(); ++i) {
118 if (m_childRuleCSSOMWrappers[i])
119 m_childRuleCSSOMWrappers[i]->setParentStyleSheet(0);
120 }
121
122 if (m_mediaCSSOMWrapper)
123 m_mediaCSSOMWrapper->clearParentStyleSheet();
124
125 m_contents->unregisterClient(this); 88 m_contents->unregisterClient(this);
126 } 89 }
127 90
128 void CSSStyleSheet::willMutateRules() 91 void CSSStyleSheet::willMutateRules()
129 { 92 {
130 // If we are the only client it is safe to mutate. 93 // If we are the only client it is safe to mutate.
131 if (m_contents->clientSize() <= 1 && !m_contents->isInMemoryCache()) { 94 if (m_contents->clientSize() <= 1 && !m_contents->isInMemoryCache()) {
132 m_contents->clearRuleSet(); 95 m_contents->clearRuleSet();
133 if (Document* document = ownerDocument()) 96 if (Document* document = ownerDocument())
134 m_contents->removeSheetFromCache(document); 97 m_contents->removeSheetFromCache(document);
135 m_contents->setMutable(); 98 m_contents->setMutable();
136 return; 99 return;
137 } 100 }
138 // Only cacheable stylesheets should have multiple clients. 101 // Only cacheable stylesheets should have multiple clients.
139 ASSERT(m_contents->isCacheable()); 102 ASSERT(m_contents->isCacheable());
140 103
141 // Copy-on-write. 104 // Copy-on-write.
142 m_contents->unregisterClient(this); 105 m_contents->unregisterClient(this);
143 m_contents = m_contents->copy(); 106 m_contents = m_contents->copy();
144 m_contents->registerClient(this); 107 m_contents->registerClient(this);
145 108
146 m_contents->setMutable(); 109 m_contents->setMutable();
147
148 // Any existing CSSOM wrappers need to be connected to the copied child rule s.
149 reattachChildRuleCSSOMWrappers();
150 } 110 }
151 111
152 void CSSStyleSheet::didMutateRules() 112 void CSSStyleSheet::didMutateRules()
153 { 113 {
154 ASSERT(m_contents->isMutable()); 114 ASSERT(m_contents->isMutable());
155 ASSERT(m_contents->clientSize() <= 1); 115 ASSERT(m_contents->clientSize() <= 1);
156 116
157 didMutate(PartialRuleUpdate); 117 didMutate(PartialRuleUpdate);
158 } 118 }
159 119
160 void CSSStyleSheet::didMutate(StyleSheetUpdateType updateType) 120 void CSSStyleSheet::didMutate(StyleSheetUpdateType updateType)
161 { 121 {
162 Document* owner = ownerDocument(); 122 Document* owner = ownerDocument();
163 if (!owner) 123 if (!owner)
164 return; 124 return;
165 125
166 owner->modifiedStyleSheet(this); 126 owner->modifiedStyleSheet(this);
167 } 127 }
168 128
169 void CSSStyleSheet::reattachChildRuleCSSOMWrappers()
170 {
171 for (unsigned i = 0; i < m_childRuleCSSOMWrappers.size(); ++i) {
172 if (!m_childRuleCSSOMWrappers[i])
173 continue;
174 m_childRuleCSSOMWrappers[i]->reattach(m_contents->ruleAt(i));
175 }
176 }
177 129
178 void CSSStyleSheet::setMediaQueries(PassRefPtr<MediaQuerySet> mediaQueries) 130 void CSSStyleSheet::setMediaQueries(PassRefPtr<MediaQuerySet> mediaQueries)
179 { 131 {
180 m_mediaQueries = mediaQueries; 132 m_mediaQueries = mediaQueries;
181 if (m_mediaCSSOMWrapper && m_mediaQueries)
182 m_mediaCSSOMWrapper->reattach(m_mediaQueries.get());
183 133
184 // Add warning message to inspector whenever dpi/dpcm values are used for "s creen" media. 134 // Add warning message to inspector whenever dpi/dpcm values are used for "s creen" media.
185 reportMediaQueryWarningIfNeeded(ownerDocument(), m_mediaQueries.get()); 135 reportMediaQueryWarningIfNeeded(ownerDocument(), m_mediaQueries.get());
186 } 136 }
187 137
188 unsigned CSSStyleSheet::length() const 138 unsigned CSSStyleSheet::length() const
189 { 139 {
190 return m_contents->ruleCount(); 140 return m_contents->ruleCount();
191 } 141 }
192 142
193 CSSRule* CSSStyleSheet::item(unsigned index)
194 {
195 unsigned ruleCount = length();
196 if (index >= ruleCount)
197 return 0;
198
199 if (m_childRuleCSSOMWrappers.isEmpty())
200 m_childRuleCSSOMWrappers.grow(ruleCount);
201 ASSERT(m_childRuleCSSOMWrappers.size() == ruleCount);
202
203 RefPtr<CSSRule>& cssRule = m_childRuleCSSOMWrappers[index];
204 if (!cssRule)
205 cssRule = m_contents->ruleAt(index)->createCSSOMWrapper(this);
206 return cssRule.get();
207 }
208
209 void CSSStyleSheet::clearOwnerNode() 143 void CSSStyleSheet::clearOwnerNode()
210 { 144 {
211 didMutate(EntireStyleSheetUpdate); 145 didMutate(EntireStyleSheetUpdate);
212 if (m_ownerNode) 146 if (m_ownerNode)
213 m_contents->unregisterClient(this); 147 m_contents->unregisterClient(this);
214 m_ownerNode = nullptr; 148 m_ownerNode = nullptr;
215 } 149 }
216 150
217 PassRefPtr<CSSRuleList> CSSStyleSheet::rules()
218 {
219 // IE behavior.
220 RefPtr<StaticCSSRuleList> nonCharsetRules(StaticCSSRuleList::create());
221 unsigned ruleCount = length();
222 for (unsigned i = 0; i < ruleCount; ++i) {
223 CSSRule* rule = item(i);
224 nonCharsetRules->rules().append(rule);
225 }
226 return nonCharsetRules.release();
227 }
228
229 unsigned CSSStyleSheet::insertRule(const String& ruleString, unsigned index, Exc eptionState& exceptionState)
230 {
231 ASSERT(m_childRuleCSSOMWrappers.isEmpty() || m_childRuleCSSOMWrappers.size() == m_contents->ruleCount());
232
233 if (index > length()) {
234 exceptionState.throwDOMException(IndexSizeError, "The index provided (" + String::number(index) + ") is larger than the maximum index (" + String::numbe r(length()) + ").");
235 return 0;
236 }
237 CSSParserContext context(m_contents->parserContext(), UseCounter::getFrom(th is));
238 BisonCSSParser p(context);
239 RefPtr<StyleRuleBase> rule = p.parseRule(m_contents.get(), ruleString);
240
241 if (!rule) {
242 exceptionState.throwDOMException(SyntaxError, "Failed to parse the rule '" + ruleString + "'.");
243 return 0;
244 }
245 RuleMutationScope mutationScope(this);
246
247 bool success = m_contents->wrapperInsertRule(rule, index);
248 if (!success) {
249 exceptionState.throwDOMException(HierarchyRequestError, "Failed to inser t the rule.");
250 return 0;
251 }
252 if (!m_childRuleCSSOMWrappers.isEmpty())
253 m_childRuleCSSOMWrappers.insert(index, RefPtr<CSSRule>(nullptr));
254
255 return index;
256 }
257
258 unsigned CSSStyleSheet::insertRule(const String& rule, ExceptionState& exception State)
259 {
260 UseCounter::countDeprecation(callingExecutionContext(V8PerIsolateData::mainT hreadIsolate()), UseCounter::CSSStyleSheetInsertRuleOptionalArg);
261 return insertRule(rule, 0, exceptionState);
262 }
263
264 void CSSStyleSheet::deleteRule(unsigned index, ExceptionState& exceptionState)
265 {
266 ASSERT(m_childRuleCSSOMWrappers.isEmpty() || m_childRuleCSSOMWrappers.size() == m_contents->ruleCount());
267
268 if (index >= length()) {
269 exceptionState.throwDOMException(IndexSizeError, "The index provided (" + String::number(index) + ") is larger than the maximum index (" + String::numbe r(length() - 1) + ").");
270 return;
271 }
272 RuleMutationScope mutationScope(this);
273
274 m_contents->wrapperDeleteRule(index);
275
276 if (!m_childRuleCSSOMWrappers.isEmpty()) {
277 if (m_childRuleCSSOMWrappers[index])
278 m_childRuleCSSOMWrappers[index]->setParentStyleSheet(0);
279 m_childRuleCSSOMWrappers.remove(index);
280 }
281 }
282
283 int CSSStyleSheet::addRule(const String& selector, const String& style, int inde x, ExceptionState& exceptionState)
284 {
285 StringBuilder text;
286 text.append(selector);
287 text.appendLiteral(" { ");
288 text.append(style);
289 if (!style.isEmpty())
290 text.append(' ');
291 text.append('}');
292 insertRule(text.toString(), index, exceptionState);
293
294 // As per Microsoft documentation, always return -1.
295 return -1;
296 }
297
298 int CSSStyleSheet::addRule(const String& selector, const String& style, Exceptio nState& exceptionState)
299 {
300 return addRule(selector, style, length(), exceptionState);
301 }
302
303
304 PassRefPtr<CSSRuleList> CSSStyleSheet::cssRules()
305 {
306 if (!m_ruleListCSSOMWrapper)
307 m_ruleListCSSOMWrapper = StyleSheetCSSRuleList::create(this);
308 return m_ruleListCSSOMWrapper.get();
309 }
310
311 KURL CSSStyleSheet::baseURL() const 151 KURL CSSStyleSheet::baseURL() const
312 { 152 {
313 return m_contents->baseURL(); 153 return m_contents->baseURL();
314 } 154 }
315 155
316 MediaList* CSSStyleSheet::media() const
317 {
318 if (!m_mediaQueries)
319 return 0;
320
321 if (!m_mediaCSSOMWrapper)
322 m_mediaCSSOMWrapper = MediaList::create(m_mediaQueries.get(), const_cast <CSSStyleSheet*>(this));
323 return m_mediaCSSOMWrapper.get();
324 }
325
326 Document* CSSStyleSheet::ownerDocument() const 156 Document* CSSStyleSheet::ownerDocument() const
327 { 157 {
328 return ownerNode() ? &ownerNode()->document() : 0; 158 return ownerNode() ? &ownerNode()->document() : 0;
329 } 159 }
330 160
331 void CSSStyleSheet::clearChildRuleCSSOMWrappers()
332 {
333 m_childRuleCSSOMWrappers.clear();
334 }
335
336 } // namespace blink 161 } // namespace blink
OLDNEW
« no previous file with comments | « sky/engine/core/css/CSSStyleSheet.h ('k') | sky/engine/core/css/CSSStyleSheet.idl » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698