blob: f822ab5a62f45f498b09a477ef6c0f9cbd28d9d6 [file] [log] [blame]
apavlov@chromium.org8d79d7f2010-10-07 09:53:40 +00001/*
2 * Copyright (C) 2010, Google Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16 * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
17 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 */
24
25#include "config.h"
apavlov@chromium.org8d79d7f2010-10-07 09:53:40 +000026
27#if ENABLE(INSPECTOR)
28
yurys@chromium.org83110c82012-03-15 16:44:09 +000029#include "InspectorCSSAgent.h"
30
apavlov@chromium.org8d79d7f2010-10-07 09:53:40 +000031#include "CSSComputedStyleDeclaration.h"
apavlov@chromium.orgbe789cf2011-05-18 13:32:07 +000032#include "CSSImportRule.h"
apavlov@chromium.org8d79d7f2010-10-07 09:53:40 +000033#include "CSSPropertyNames.h"
34#include "CSSPropertySourceData.h"
35#include "CSSRule.h"
36#include "CSSRuleList.h"
37#include "CSSStyleRule.h"
apavlov@chromium.org8d79d7f2010-10-07 09:53:40 +000038#include "CSSStyleSheet.h"
apavlov@chromium.org31442e82012-03-05 10:44:40 +000039#include "ContentSecurityPolicy.h"
apavlov@chromium.org8d79d7f2010-10-07 09:53:40 +000040#include "DOMWindow.h"
mkwst@chromium.org33cdf432013-02-08 14:21:48 +000041#include "ExceptionCodePlaceholder.h"
apavlov@chromium.org8d79d7f2010-10-07 09:53:40 +000042#include "HTMLHeadElement.h"
apavlov@chromium.org5f4304d2013-03-04 13:34:47 +000043#include "HTMLStyleElement.h"
apavlov@chromium.org8d79d7f2010-10-07 09:53:40 +000044#include "InspectorDOMAgent.h"
pfeldman@chromium.org94451152012-02-07 17:00:32 +000045#include "InspectorHistory.h"
joepeck@webkit.orga3198442013-12-11 22:40:23 +000046#include "InspectorWebTypeBuilders.h"
yurys@chromium.org29626f82011-03-04 15:15:45 +000047#include "InstrumentingAgents.h"
rniwa@webkit.org3fc452e2012-08-24 21:46:24 +000048#include "NamedFlowCollection.h"
apavlov@chromium.org8d79d7f2010-10-07 09:53:40 +000049#include "Node.h"
pfeldman@chromium.org840f3482011-02-11 15:23:26 +000050#include "NodeList.h"
commit-queue@webkit.orge2bb32c2012-08-10 09:58:35 +000051#include "RenderRegion.h"
apavlov@chromium.org53991942013-03-25 12:55:30 +000052#include "SVGStyleElement.h"
antti@apple.come5428c52013-11-28 20:53:22 +000053#include "StyleProperties.h"
pfeldman@chromium.orga7128942012-07-25 13:48:47 +000054#include "StylePropertyShorthand.h"
alexis.menard@openbossa.orge6db2f62012-04-25 15:49:08 +000055#include "StyleResolver.h"
antti@apple.com8be9b562012-02-28 17:44:18 +000056#include "StyleRule.h"
apavlov@chromium.org8d79d7f2010-10-07 09:53:40 +000057#include "StyleSheetList.h"
commit-queue@webkit.org285994b2012-07-24 12:00:33 +000058#include "WebKitNamedFlow.h"
joepeck@webkit.orga3198442013-12-11 22:40:23 +000059#include <inspector/InspectorValues.h>
apavlov@chromium.orgba905e82011-12-19 15:14:14 +000060#include <wtf/CurrentTime.h>
apavlov@chromium.org8d79d7f2010-10-07 09:53:40 +000061#include <wtf/HashSet.h>
akling@apple.comf8515982013-09-02 18:50:01 +000062#include <wtf/Ref.h>
apavlov@chromium.org8d79d7f2010-10-07 09:53:40 +000063#include <wtf/Vector.h>
64#include <wtf/text/CString.h>
apavlov@chromium.org5ee19fd2012-01-11 15:14:44 +000065#include <wtf/text/StringConcatenate.h>
apavlov@chromium.org8d79d7f2010-10-07 09:53:40 +000066
joepeck@webkit.orga3198442013-12-11 22:40:23 +000067using namespace Inspector;
68
apavlov@chromium.org8d79d7f2010-10-07 09:53:40 +000069namespace WebCore {
70
pfeldman@chromium.orgefb43862011-08-16 17:15:06 +000071enum ForcePseudoClassFlags {
72 PseudoNone = 0,
73 PseudoHover = 1 << 0,
74 PseudoFocus = 1 << 1,
75 PseudoActive = 1 << 2,
76 PseudoVisited = 1 << 3
77};
78
apavlov@chromium.org6678c9b2011-06-28 12:07:48 +000079static unsigned computePseudoClassMask(InspectorArray* pseudoClassArray)
80{
abarth@webkit.orgf6d1b8c2012-08-29 07:38:10 +000081 DEFINE_STATIC_LOCAL(String, active, (ASCIILiteral("active")));
82 DEFINE_STATIC_LOCAL(String, hover, (ASCIILiteral("hover")));
83 DEFINE_STATIC_LOCAL(String, focus, (ASCIILiteral("focus")));
84 DEFINE_STATIC_LOCAL(String, visited, (ASCIILiteral("visited")));
apavlov@chromium.org6678c9b2011-06-28 12:07:48 +000085 if (!pseudoClassArray || !pseudoClassArray->length())
pfeldman@chromium.orgefb43862011-08-16 17:15:06 +000086 return PseudoNone;
apavlov@chromium.org6678c9b2011-06-28 12:07:48 +000087
pfeldman@chromium.orgefb43862011-08-16 17:15:06 +000088 unsigned result = PseudoNone;
apavlov@chromium.org6678c9b2011-06-28 12:07:48 +000089 for (size_t i = 0; i < pseudoClassArray->length(); ++i) {
90 RefPtr<InspectorValue> pseudoClassValue = pseudoClassArray->get(i);
91 String pseudoClass;
92 bool success = pseudoClassValue->asString(&pseudoClass);
93 if (!success)
94 continue;
95 if (pseudoClass == active)
pfeldman@chromium.orgefb43862011-08-16 17:15:06 +000096 result |= PseudoActive;
apavlov@chromium.org6678c9b2011-06-28 12:07:48 +000097 else if (pseudoClass == hover)
pfeldman@chromium.orgefb43862011-08-16 17:15:06 +000098 result |= PseudoHover;
apavlov@chromium.org6678c9b2011-06-28 12:07:48 +000099 else if (pseudoClass == focus)
pfeldman@chromium.orgefb43862011-08-16 17:15:06 +0000100 result |= PseudoFocus;
apavlov@chromium.org6678c9b2011-06-28 12:07:48 +0000101 else if (pseudoClass == visited)
pfeldman@chromium.orgefb43862011-08-16 17:15:06 +0000102 result |= PseudoVisited;
apavlov@chromium.org6678c9b2011-06-28 12:07:48 +0000103 }
104
105 return result;
106}
107
commit-queue@webkit.org65563d42012-09-12 12:07:24 +0000108class UpdateRegionLayoutTask {
109public:
110 UpdateRegionLayoutTask(InspectorCSSAgent*);
111 void scheduleFor(WebKitNamedFlow*, int documentNodeId);
112 void unschedule(WebKitNamedFlow*);
113 void reset();
andersca@apple.comb6fe2302014-01-11 18:19:04 +0000114 void timerFired(Timer<UpdateRegionLayoutTask>&);
commit-queue@webkit.org65563d42012-09-12 12:07:24 +0000115
116private:
117 InspectorCSSAgent* m_cssAgent;
118 Timer<UpdateRegionLayoutTask> m_timer;
119 HashMap<WebKitNamedFlow*, int> m_namedFlows;
120};
121
122UpdateRegionLayoutTask::UpdateRegionLayoutTask(InspectorCSSAgent* cssAgent)
123 : m_cssAgent(cssAgent)
andersca@apple.comb6fe2302014-01-11 18:19:04 +0000124 , m_timer(this, &UpdateRegionLayoutTask::timerFired)
commit-queue@webkit.org65563d42012-09-12 12:07:24 +0000125{
126}
127
128void UpdateRegionLayoutTask::scheduleFor(WebKitNamedFlow* namedFlow, int documentNodeId)
129{
130 m_namedFlows.add(namedFlow, documentNodeId);
131
132 if (!m_timer.isActive())
133 m_timer.startOneShot(0);
134}
135
136void UpdateRegionLayoutTask::unschedule(WebKitNamedFlow* namedFlow)
137{
138 m_namedFlows.remove(namedFlow);
139}
140
141void UpdateRegionLayoutTask::reset()
142{
143 m_timer.stop();
144 m_namedFlows.clear();
145}
146
andersca@apple.comb6fe2302014-01-11 18:19:04 +0000147void UpdateRegionLayoutTask::timerFired(Timer<UpdateRegionLayoutTask>&)
commit-queue@webkit.org65563d42012-09-12 12:07:24 +0000148{
149 // The timer is stopped on m_cssAgent destruction, so this method will never be called after m_cssAgent has been destroyed.
andersca@apple.comc3523f82013-10-18 23:41:24 +0000150 Vector<std::pair<WebKitNamedFlow*, int>> namedFlows;
commit-queue@webkit.org65563d42012-09-12 12:07:24 +0000151
152 for (HashMap<WebKitNamedFlow*, int>::iterator it = m_namedFlows.begin(), end = m_namedFlows.end(); it != end; ++it)
benjamin@webkit.orgee554052012-10-07 23:12:07 +0000153 namedFlows.append(std::make_pair(it->key, it->value));
commit-queue@webkit.org65563d42012-09-12 12:07:24 +0000154
155 for (unsigned i = 0, size = namedFlows.size(); i < size; ++i) {
156 WebKitNamedFlow* namedFlow = namedFlows.at(i).first;
157 int documentNodeId = namedFlows.at(i).second;
158
159 if (m_namedFlows.contains(namedFlow)) {
160 m_cssAgent->regionLayoutUpdated(namedFlow, documentNodeId);
161 m_namedFlows.remove(namedFlow);
162 }
163 }
164
165 if (!m_namedFlows.isEmpty() && !m_timer.isActive())
166 m_timer.startOneShot(0);
167}
commit-queue@webkit.org2966a272013-06-21 14:31:26 +0000168
169class ChangeRegionOversetTask {
170public:
171 ChangeRegionOversetTask(InspectorCSSAgent*);
172 void scheduleFor(WebKitNamedFlow*, int documentNodeId);
173 void unschedule(WebKitNamedFlow*);
174 void reset();
andersca@apple.comb6fe2302014-01-11 18:19:04 +0000175 void timerFired(Timer<ChangeRegionOversetTask>&);
commit-queue@webkit.org2966a272013-06-21 14:31:26 +0000176
177private:
178 InspectorCSSAgent* m_cssAgent;
179 Timer<ChangeRegionOversetTask> m_timer;
180 HashMap<WebKitNamedFlow*, int> m_namedFlows;
181};
182
183ChangeRegionOversetTask::ChangeRegionOversetTask(InspectorCSSAgent* cssAgent)
184 : m_cssAgent(cssAgent)
andersca@apple.comb6fe2302014-01-11 18:19:04 +0000185 , m_timer(this, &ChangeRegionOversetTask::timerFired)
commit-queue@webkit.org2966a272013-06-21 14:31:26 +0000186{
187}
188
189void ChangeRegionOversetTask::scheduleFor(WebKitNamedFlow* namedFlow, int documentNodeId)
190{
191 m_namedFlows.add(namedFlow, documentNodeId);
192
193 if (!m_timer.isActive())
194 m_timer.startOneShot(0);
195}
196
197void ChangeRegionOversetTask::unschedule(WebKitNamedFlow* namedFlow)
198{
199 m_namedFlows.remove(namedFlow);
200}
201
202void ChangeRegionOversetTask::reset()
203{
204 m_timer.stop();
205 m_namedFlows.clear();
206}
207
andersca@apple.comb6fe2302014-01-11 18:19:04 +0000208void ChangeRegionOversetTask::timerFired(Timer<ChangeRegionOversetTask>&)
commit-queue@webkit.org2966a272013-06-21 14:31:26 +0000209{
210 // The timer is stopped on m_cssAgent destruction, so this method will never be called after m_cssAgent has been destroyed.
211 for (HashMap<WebKitNamedFlow*, int>::iterator it = m_namedFlows.begin(), end = m_namedFlows.end(); it != end; ++it)
212 m_cssAgent->regionOversetChanged(it->key, it->value);
213
214 m_namedFlows.clear();
215}
commit-queue@webkit.org65563d42012-09-12 12:07:24 +0000216
pfeldman@chromium.org94451152012-02-07 17:00:32 +0000217class InspectorCSSAgent::StyleSheetAction : public InspectorHistory::Action {
218 WTF_MAKE_NONCOPYABLE(StyleSheetAction);
219public:
pfeldman@chromium.org8ef57362012-02-13 13:12:15 +0000220 StyleSheetAction(const String& name, InspectorStyleSheet* styleSheet)
pfeldman@chromium.org94451152012-02-07 17:00:32 +0000221 : InspectorHistory::Action(name)
pfeldman@chromium.org8ef57362012-02-13 13:12:15 +0000222 , m_styleSheet(styleSheet)
pfeldman@chromium.org94451152012-02-07 17:00:32 +0000223 {
224 }
225
pfeldman@chromium.org94451152012-02-07 17:00:32 +0000226protected:
pfeldman@chromium.org8ef57362012-02-13 13:12:15 +0000227 RefPtr<InspectorStyleSheet> m_styleSheet;
pfeldman@chromium.org94451152012-02-07 17:00:32 +0000228};
229
230class InspectorCSSAgent::SetStyleSheetTextAction : public InspectorCSSAgent::StyleSheetAction {
231 WTF_MAKE_NONCOPYABLE(SetStyleSheetTextAction);
232public:
pfeldman@chromium.org8ef57362012-02-13 13:12:15 +0000233 SetStyleSheetTextAction(InspectorStyleSheet* styleSheet, const String& text)
234 : InspectorCSSAgent::StyleSheetAction("SetStyleSheetText", styleSheet)
pfeldman@chromium.org94451152012-02-07 17:00:32 +0000235 , m_text(text)
236 {
237 }
238
pfeldman@chromium.orga9730c42012-02-15 09:12:15 +0000239 virtual bool perform(ExceptionCode& ec)
pfeldman@chromium.org94451152012-02-07 17:00:32 +0000240 {
pfeldman@chromium.org8ef57362012-02-13 13:12:15 +0000241 if (!m_styleSheet->getText(&m_oldText))
pfeldman@chromium.org94451152012-02-07 17:00:32 +0000242 return false;
pfeldman@chromium.orga9730c42012-02-15 09:12:15 +0000243 return redo(ec);
pfeldman@chromium.org94451152012-02-07 17:00:32 +0000244 }
245
apavlov@chromium.orge4f065a2013-02-26 09:15:17 +0000246 virtual bool undo(ExceptionCode& ec)
pfeldman@chromium.org94451152012-02-07 17:00:32 +0000247 {
apavlov@chromium.orge4f065a2013-02-26 09:15:17 +0000248 if (m_styleSheet->setText(m_oldText, ec)) {
pfeldman@chromium.org8ef57362012-02-13 13:12:15 +0000249 m_styleSheet->reparseStyleSheet(m_oldText);
pfeldman@chromium.org94451152012-02-07 17:00:32 +0000250 return true;
251 }
252 return false;
253 }
254
apavlov@chromium.orge4f065a2013-02-26 09:15:17 +0000255 virtual bool redo(ExceptionCode& ec)
pfeldman@chromium.orga9730c42012-02-15 09:12:15 +0000256 {
apavlov@chromium.orge4f065a2013-02-26 09:15:17 +0000257 if (m_styleSheet->setText(m_text, ec)) {
pfeldman@chromium.orga9730c42012-02-15 09:12:15 +0000258 m_styleSheet->reparseStyleSheet(m_text);
259 return true;
260 }
261 return false;
262 }
263
pfeldman@chromium.orga1a70a42012-02-14 08:50:19 +0000264 virtual String mergeId()
265 {
266 return String::format("SetStyleSheetText %s", m_styleSheet->id().utf8().data());
267 }
268
269 virtual void merge(PassOwnPtr<Action> action)
270 {
271 ASSERT(action->mergeId() == mergeId());
272
273 SetStyleSheetTextAction* other = static_cast<SetStyleSheetTextAction*>(action.get());
274 m_text = other->m_text;
275 }
276
pfeldman@chromium.org94451152012-02-07 17:00:32 +0000277private:
278 String m_text;
279 String m_oldText;
280};
281
timothy@apple.com17aafb02013-04-19 05:59:02 +0000282class InspectorCSSAgent::SetStyleTextAction : public InspectorCSSAgent::StyleSheetAction {
283 WTF_MAKE_NONCOPYABLE(SetStyleTextAction);
284public:
285 SetStyleTextAction(InspectorStyleSheet* styleSheet, const InspectorCSSId& cssId, const String& text)
286 : InspectorCSSAgent::StyleSheetAction(ASCIILiteral("SetStyleText"), styleSheet)
287 , m_cssId(cssId)
288 , m_text(text)
289 {
290 }
291
292 virtual bool perform(ExceptionCode& ec)
293 {
294 return redo(ec);
295 }
296
297 virtual bool undo(ExceptionCode& ec)
298 {
299 return m_styleSheet->setStyleText(m_cssId, m_oldText, 0, ec);
300 }
301
302 virtual bool redo(ExceptionCode& ec)
303 {
304 return m_styleSheet->setStyleText(m_cssId, m_text, &m_oldText, ec);
305 }
306
307 virtual String mergeId()
308 {
309 ASSERT(m_styleSheet->id() == m_cssId.styleSheetId());
310 return String::format("SetStyleText %s:%u", m_styleSheet->id().utf8().data(), m_cssId.ordinal());
311 }
312
313 virtual void merge(PassOwnPtr<Action> action)
314 {
315 ASSERT(action->mergeId() == mergeId());
316
317 SetStyleTextAction* other = static_cast<SetStyleTextAction*>(action.get());
318 m_text = other->m_text;
319 }
320
321private:
322 InspectorCSSId m_cssId;
323 String m_text;
324 String m_oldText;
325};
326
pfeldman@chromium.org94451152012-02-07 17:00:32 +0000327class InspectorCSSAgent::SetPropertyTextAction : public InspectorCSSAgent::StyleSheetAction {
328 WTF_MAKE_NONCOPYABLE(SetPropertyTextAction);
329public:
pfeldman@chromium.org8ef57362012-02-13 13:12:15 +0000330 SetPropertyTextAction(InspectorStyleSheet* styleSheet, const InspectorCSSId& cssId, unsigned propertyIndex, const String& text, bool overwrite)
331 : InspectorCSSAgent::StyleSheetAction("SetPropertyText", styleSheet)
pfeldman@chromium.org94451152012-02-07 17:00:32 +0000332 , m_cssId(cssId)
333 , m_propertyIndex(propertyIndex)
334 , m_text(text)
335 , m_overwrite(overwrite)
336 {
337 }
338
339 virtual String toString()
340 {
341 return mergeId() + ": " + m_oldText + " -> " + m_text;
342 }
343
pfeldman@chromium.org8ef57362012-02-13 13:12:15 +0000344 virtual bool perform(ExceptionCode& ec)
pfeldman@chromium.org94451152012-02-07 17:00:32 +0000345 {
pfeldman@chromium.orga9730c42012-02-15 09:12:15 +0000346 return redo(ec);
347 }
348
349 virtual bool undo(ExceptionCode& ec)
350 {
351 String placeholder;
352 return m_styleSheet->setPropertyText(m_cssId, m_propertyIndex, m_overwrite ? m_oldText : "", true, &placeholder, ec);
353 }
354
355 virtual bool redo(ExceptionCode& ec)
356 {
pfeldman@chromium.org94451152012-02-07 17:00:32 +0000357 String oldText;
pfeldman@chromium.org8ef57362012-02-13 13:12:15 +0000358 bool result = m_styleSheet->setPropertyText(m_cssId, m_propertyIndex, m_text, m_overwrite, &oldText, ec);
pfeldman@chromium.org94451152012-02-07 17:00:32 +0000359 m_oldText = oldText.stripWhiteSpace();
360 // FIXME: remove this once the model handles this case.
benjamin@webkit.org127cec2c2012-04-30 21:32:44 +0000361 if (!m_oldText.endsWith(';'))
abarth@webkit.org96a2c952012-08-31 01:25:43 +0000362 m_oldText.append(';');
timothy@apple.com17aafb02013-04-19 05:59:02 +0000363
pfeldman@chromium.org94451152012-02-07 17:00:32 +0000364 return result;
365 }
366
pfeldman@chromium.org94451152012-02-07 17:00:32 +0000367 virtual String mergeId()
368 {
pfeldman@chromium.org8ef57362012-02-13 13:12:15 +0000369 return String::format("SetPropertyText %s:%u:%s", m_styleSheet->id().utf8().data(), m_propertyIndex, m_overwrite ? "true" : "false");
pfeldman@chromium.org94451152012-02-07 17:00:32 +0000370 }
371
372 virtual void merge(PassOwnPtr<Action> action)
373 {
374 ASSERT(action->mergeId() == mergeId());
375
376 SetPropertyTextAction* other = static_cast<SetPropertyTextAction*>(action.get());
377 m_text = other->m_text;
378 }
379
380private:
381 InspectorCSSId m_cssId;
382 unsigned m_propertyIndex;
383 String m_text;
384 String m_oldText;
385 bool m_overwrite;
386};
387
388class InspectorCSSAgent::TogglePropertyAction : public InspectorCSSAgent::StyleSheetAction {
389 WTF_MAKE_NONCOPYABLE(TogglePropertyAction);
390public:
pfeldman@chromium.org8ef57362012-02-13 13:12:15 +0000391 TogglePropertyAction(InspectorStyleSheet* styleSheet, const InspectorCSSId& cssId, unsigned propertyIndex, bool disable)
392 : InspectorCSSAgent::StyleSheetAction("ToggleProperty", styleSheet)
pfeldman@chromium.org94451152012-02-07 17:00:32 +0000393 , m_cssId(cssId)
394 , m_propertyIndex(propertyIndex)
395 , m_disable(disable)
396 {
397 }
398
pfeldman@chromium.org8ef57362012-02-13 13:12:15 +0000399 virtual bool perform(ExceptionCode& ec)
pfeldman@chromium.org94451152012-02-07 17:00:32 +0000400 {
pfeldman@chromium.orga9730c42012-02-15 09:12:15 +0000401 return redo(ec);
pfeldman@chromium.org94451152012-02-07 17:00:32 +0000402 }
403
pfeldman@chromium.org8ef57362012-02-13 13:12:15 +0000404 virtual bool undo(ExceptionCode& ec)
pfeldman@chromium.org94451152012-02-07 17:00:32 +0000405 {
pfeldman@chromium.org8ef57362012-02-13 13:12:15 +0000406 return m_styleSheet->toggleProperty(m_cssId, m_propertyIndex, !m_disable, ec);
pfeldman@chromium.org94451152012-02-07 17:00:32 +0000407 }
408
pfeldman@chromium.orga9730c42012-02-15 09:12:15 +0000409 virtual bool redo(ExceptionCode& ec)
410 {
411 return m_styleSheet->toggleProperty(m_cssId, m_propertyIndex, m_disable, ec);
412 }
413
pfeldman@chromium.org94451152012-02-07 17:00:32 +0000414private:
415 InspectorCSSId m_cssId;
416 unsigned m_propertyIndex;
417 bool m_disable;
418};
419
pfeldman@chromium.org8ef57362012-02-13 13:12:15 +0000420class InspectorCSSAgent::SetRuleSelectorAction : public InspectorCSSAgent::StyleSheetAction {
421 WTF_MAKE_NONCOPYABLE(SetRuleSelectorAction);
422public:
423 SetRuleSelectorAction(InspectorStyleSheet* styleSheet, const InspectorCSSId& cssId, const String& selector)
424 : InspectorCSSAgent::StyleSheetAction("SetRuleSelector", styleSheet)
425 , m_cssId(cssId)
426 , m_selector(selector)
427 {
428 }
429
430 virtual bool perform(ExceptionCode& ec)
431 {
432 m_oldSelector = m_styleSheet->ruleSelector(m_cssId, ec);
433 if (ec)
434 return false;
pfeldman@chromium.orga9730c42012-02-15 09:12:15 +0000435 return redo(ec);
pfeldman@chromium.org8ef57362012-02-13 13:12:15 +0000436 }
437
438 virtual bool undo(ExceptionCode& ec)
439 {
440 return m_styleSheet->setRuleSelector(m_cssId, m_oldSelector, ec);
441 }
442
pfeldman@chromium.orga9730c42012-02-15 09:12:15 +0000443 virtual bool redo(ExceptionCode& ec)
444 {
445 return m_styleSheet->setRuleSelector(m_cssId, m_selector, ec);
446 }
447
pfeldman@chromium.org8ef57362012-02-13 13:12:15 +0000448private:
449 InspectorCSSId m_cssId;
450 String m_selector;
451 String m_oldSelector;
452};
453
454class InspectorCSSAgent::AddRuleAction : public InspectorCSSAgent::StyleSheetAction {
455 WTF_MAKE_NONCOPYABLE(AddRuleAction);
456public:
457 AddRuleAction(InspectorStyleSheet* styleSheet, const String& selector)
458 : InspectorCSSAgent::StyleSheetAction("AddRule", styleSheet)
459 , m_selector(selector)
460 {
461 }
462
463 virtual bool perform(ExceptionCode& ec)
464 {
pfeldman@chromium.orga9730c42012-02-15 09:12:15 +0000465 return redo(ec);
pfeldman@chromium.org8ef57362012-02-13 13:12:15 +0000466 }
467
468 virtual bool undo(ExceptionCode& ec)
469 {
470 return m_styleSheet->deleteRule(m_newId, ec);
471 }
472
pfeldman@chromium.orga9730c42012-02-15 09:12:15 +0000473 virtual bool redo(ExceptionCode& ec)
474 {
475 CSSStyleRule* cssStyleRule = m_styleSheet->addRule(m_selector, ec);
476 if (ec)
477 return false;
478 m_newId = m_styleSheet->ruleId(cssStyleRule);
479 return true;
480 }
481
pfeldman@chromium.org8ef57362012-02-13 13:12:15 +0000482 InspectorCSSId newRuleId() { return m_newId; }
483
484private:
485 InspectorCSSId m_newId;
486 String m_selector;
487 String m_oldSelector;
488};
489
apavlov@chromium.org8d79d7f2010-10-07 09:53:40 +0000490// static
andreas.kling@nokia.comf04e49c2011-10-14 21:33:49 +0000491CSSStyleRule* InspectorCSSAgent::asCSSStyleRule(CSSRule* rule)
apavlov@chromium.org8d79d7f2010-10-07 09:53:40 +0000492{
akling@apple.comc713db32012-11-22 03:45:40 +0000493 if (rule->type() != CSSRule::STYLE_RULE)
apavlov@chromium.org8d79d7f2010-10-07 09:53:40 +0000494 return 0;
495 return static_cast<CSSStyleRule*>(rule);
496}
497
commit-queue@webkit.orgf188ae92013-11-01 01:07:29 +0000498InspectorCSSAgent::InspectorCSSAgent(InstrumentingAgents* instrumentingAgents, InspectorDOMAgent* domAgent)
joepeck@webkit.orga3198442013-12-11 22:40:23 +0000499 : InspectorAgentBase(ASCIILiteral("CSS"), instrumentingAgents)
yurys@chromium.org29626f82011-03-04 15:15:45 +0000500 , m_domAgent(domAgent)
apavlov@chromium.org8d79d7f2010-10-07 09:53:40 +0000501 , m_lastStyleSheetId(1)
apavlov@chromium.org8d79d7f2010-10-07 09:53:40 +0000502{
yurys@chromium.orgd8e367c2011-02-21 14:38:24 +0000503 m_domAgent->setDOMListener(this);
apavlov@chromium.org8d79d7f2010-10-07 09:53:40 +0000504}
505
506InspectorCSSAgent::~InspectorCSSAgent()
507{
pfeldman@chromium.orgeccfccf2011-12-02 08:21:57 +0000508 ASSERT(!m_domAgent);
apavlov@chromium.org8d79d7f2010-10-07 09:53:40 +0000509 reset();
510}
511
joepeck@webkit.orga3198442013-12-11 22:40:23 +0000512void InspectorCSSAgent::didCreateFrontendAndBackend(Inspector::InspectorFrontendChannel* frontendChannel, InspectorBackendDispatcher* backendDispatcher)
apavlov@chromium.orgad517d02011-12-15 09:23:19 +0000513{
joepeck@webkit.org20fd4482013-11-13 22:58:16 +0000514 m_frontendDispatcher = std::make_unique<InspectorCSSFrontendDispatcher>(frontendChannel);
joepeck@webkit.org143537c2013-11-14 02:24:46 +0000515 m_backendDispatcher = InspectorCSSBackendDispatcher::create(backendDispatcher, this);
apavlov@chromium.orgad517d02011-12-15 09:23:19 +0000516}
517
joepeck@webkit.orgd1e21aa2014-01-24 02:38:08 +0000518void InspectorCSSAgent::willDestroyFrontendAndBackend(InspectorDisconnectReason)
pfeldman@chromium.orgefb43862011-08-16 17:15:06 +0000519{
joepeck@webkit.org20fd4482013-11-13 22:58:16 +0000520 m_frontendDispatcher = nullptr;
joepeck@webkit.org143537c2013-11-14 02:24:46 +0000521 m_backendDispatcher.clear();
joepeck@webkit.org20fd4482013-11-13 22:58:16 +0000522
apavlov@chromium.orgd63acd82012-09-13 08:41:26 +0000523 resetNonPersistentData();
pfeldman@chromium.orgefb43862011-08-16 17:15:06 +0000524}
525
pfeldman@chromium.orgeccfccf2011-12-02 08:21:57 +0000526void InspectorCSSAgent::discardAgent()
527{
528 m_domAgent->setDOMListener(0);
529 m_domAgent = 0;
530}
531
apavlov@chromium.org6dbb39d2010-11-10 17:12:45 +0000532void InspectorCSSAgent::reset()
533{
534 m_idToInspectorStyleSheet.clear();
535 m_cssStyleSheetToInspectorStyleSheet.clear();
536 m_nodeToInspectorStyleSheet.clear();
537 m_documentToInspectorStyleSheet.clear();
apavlov@chromium.orgd63acd82012-09-13 08:41:26 +0000538 resetNonPersistentData();
539}
540
541void InspectorCSSAgent::resetNonPersistentData()
542{
commit-queue@webkit.org5c25fc42012-08-06 16:39:56 +0000543 m_namedFlowCollectionsRequested.clear();
commit-queue@webkit.org65563d42012-09-12 12:07:24 +0000544 if (m_updateRegionLayoutTask)
545 m_updateRegionLayoutTask->reset();
commit-queue@webkit.org2966a272013-06-21 14:31:26 +0000546 if (m_changeRegionOversetTask)
547 m_changeRegionOversetTask->reset();
apavlov@chromium.orgcc4fd4a2012-07-04 16:10:45 +0000548 resetPseudoStates();
apavlov@chromium.org6dbb39d2010-11-10 17:12:45 +0000549}
550
apavlov@chromium.orgad517d02011-12-15 09:23:19 +0000551void InspectorCSSAgent::enable(ErrorString*)
552{
apavlov@chromium.orgd63acd82012-09-13 08:41:26 +0000553 m_instrumentingAgents->setInspectorCSSAgent(this);
apavlov@chromium.orgad517d02011-12-15 09:23:19 +0000554}
555
556void InspectorCSSAgent::disable(ErrorString*)
557{
apavlov@chromium.orgd63acd82012-09-13 08:41:26 +0000558 m_instrumentingAgents->setInspectorCSSAgent(0);
apavlov@chromium.orgad517d02011-12-15 09:23:19 +0000559}
560
561void InspectorCSSAgent::mediaQueryResultChanged()
562{
joepeck@webkit.org20fd4482013-11-13 22:58:16 +0000563 if (m_frontendDispatcher)
564 m_frontendDispatcher->mediaQueryResultChanged();
apavlov@chromium.orgad517d02011-12-15 09:23:19 +0000565}
566
commit-queue@webkit.org65563d42012-09-12 12:07:24 +0000567void InspectorCSSAgent::didCreateNamedFlow(Document* document, WebKitNamedFlow* namedFlow)
commit-queue@webkit.org5c25fc42012-08-06 16:39:56 +0000568{
commit-queue@webkit.org65563d42012-09-12 12:07:24 +0000569 int documentNodeId = documentNodeWithRequestedFlowsId(document);
570 if (!documentNodeId)
commit-queue@webkit.org5c25fc42012-08-06 16:39:56 +0000571 return;
572
commit-queue@webkit.org65563d42012-09-12 12:07:24 +0000573 ErrorString errorString;
joepeck@webkit.org20fd4482013-11-13 22:58:16 +0000574 m_frontendDispatcher->namedFlowCreated(buildObjectForNamedFlow(&errorString, namedFlow, documentNodeId));
commit-queue@webkit.org5c25fc42012-08-06 16:39:56 +0000575}
576
commit-queue@webkit.org65563d42012-09-12 12:07:24 +0000577void InspectorCSSAgent::willRemoveNamedFlow(Document* document, WebKitNamedFlow* namedFlow)
commit-queue@webkit.org5c25fc42012-08-06 16:39:56 +0000578{
commit-queue@webkit.org65563d42012-09-12 12:07:24 +0000579 int documentNodeId = documentNodeWithRequestedFlowsId(document);
580 if (!documentNodeId)
commit-queue@webkit.org5c25fc42012-08-06 16:39:56 +0000581 return;
582
commit-queue@webkit.org65563d42012-09-12 12:07:24 +0000583 if (m_updateRegionLayoutTask)
584 m_updateRegionLayoutTask->unschedule(namedFlow);
commit-queue@webkit.org2966a272013-06-21 14:31:26 +0000585
586 if (m_changeRegionOversetTask)
587 m_changeRegionOversetTask->unschedule(namedFlow);
commit-queue@webkit.org65563d42012-09-12 12:07:24 +0000588
joepeck@webkit.org20fd4482013-11-13 22:58:16 +0000589 m_frontendDispatcher->namedFlowRemoved(documentNodeId, namedFlow->name().string());
commit-queue@webkit.org65563d42012-09-12 12:07:24 +0000590}
591
592void InspectorCSSAgent::didUpdateRegionLayout(Document* document, WebKitNamedFlow* namedFlow)
593{
594 int documentNodeId = documentNodeWithRequestedFlowsId(document);
595 if (!documentNodeId)
596 return;
597
598 if (!m_updateRegionLayoutTask)
599 m_updateRegionLayoutTask = adoptPtr(new UpdateRegionLayoutTask(this));
600 m_updateRegionLayoutTask->scheduleFor(namedFlow, documentNodeId);
601}
602
603void InspectorCSSAgent::regionLayoutUpdated(WebKitNamedFlow* namedFlow, int documentNodeId)
604{
605 if (namedFlow->flowState() == WebKitNamedFlow::FlowStateNull)
606 return;
607
608 ErrorString errorString;
akling@apple.comf8515982013-09-02 18:50:01 +0000609 Ref<WebKitNamedFlow> protect(*namedFlow);
commit-queue@webkit.org65563d42012-09-12 12:07:24 +0000610
joepeck@webkit.org20fd4482013-11-13 22:58:16 +0000611 m_frontendDispatcher->regionLayoutUpdated(buildObjectForNamedFlow(&errorString, namedFlow, documentNodeId));
commit-queue@webkit.org5c25fc42012-08-06 16:39:56 +0000612}
613
commit-queue@webkit.org2966a272013-06-21 14:31:26 +0000614void InspectorCSSAgent::didChangeRegionOverset(Document* document, WebKitNamedFlow* namedFlow)
615{
616 int documentNodeId = documentNodeWithRequestedFlowsId(document);
617 if (!documentNodeId)
618 return;
619
620 if (!m_changeRegionOversetTask)
621 m_changeRegionOversetTask = adoptPtr(new ChangeRegionOversetTask(this));
622 m_changeRegionOversetTask->scheduleFor(namedFlow, documentNodeId);
623}
624
625void InspectorCSSAgent::regionOversetChanged(WebKitNamedFlow* namedFlow, int documentNodeId)
626{
627 if (namedFlow->flowState() == WebKitNamedFlow::FlowStateNull)
628 return;
629
630 ErrorString errorString;
akling@apple.comf8515982013-09-02 18:50:01 +0000631 Ref<WebKitNamedFlow> protect(*namedFlow);
commit-queue@webkit.org2966a272013-06-21 14:31:26 +0000632
joepeck@webkit.org20fd4482013-11-13 22:58:16 +0000633 m_frontendDispatcher->regionOversetChanged(buildObjectForNamedFlow(&errorString, namedFlow, documentNodeId));
commit-queue@webkit.org2966a272013-06-21 14:31:26 +0000634}
635
achicu@adobe.comede34342013-10-29 02:38:09 +0000636void InspectorCSSAgent::didRegisterNamedFlowContentElement(Document* document, WebKitNamedFlow* namedFlow, Node* contentElement, Node* nextContentElement)
637{
638 int documentNodeId = documentNodeWithRequestedFlowsId(document);
639 if (!documentNodeId)
640 return;
641
642 ErrorString errorString;
643 int contentElementNodeId = m_domAgent->pushNodeToFrontend(&errorString, documentNodeId, contentElement);
644 int nextContentElementNodeId = nextContentElement ? m_domAgent->pushNodeToFrontend(&errorString, documentNodeId, nextContentElement) : 0;
joepeck@webkit.org20fd4482013-11-13 22:58:16 +0000645 m_frontendDispatcher->registeredNamedFlowContentElement(documentNodeId, namedFlow->name().string(), contentElementNodeId, nextContentElementNodeId);
achicu@adobe.comede34342013-10-29 02:38:09 +0000646}
647
648void InspectorCSSAgent::didUnregisterNamedFlowContentElement(Document* document, WebKitNamedFlow* namedFlow, Node* contentElement)
649{
650 int documentNodeId = documentNodeWithRequestedFlowsId(document);
651 if (!documentNodeId)
652 return;
653
654 ErrorString errorString;
655 int contentElementNodeId = m_domAgent->pushNodeToFrontend(&errorString, documentNodeId, contentElement);
achicu@adobe.coma205e7f2013-11-07 18:05:55 +0000656 if (!contentElementNodeId) {
657 // We've already notified that the DOM node was removed from the DOM, so there's no need to send another event.
658 return;
659 }
joepeck@webkit.org20fd4482013-11-13 22:58:16 +0000660 m_frontendDispatcher->unregisteredNamedFlowContentElement(documentNodeId, namedFlow->name().string(), contentElementNodeId);
achicu@adobe.comede34342013-10-29 02:38:09 +0000661}
662
pfeldman@chromium.orgefb43862011-08-16 17:15:06 +0000663bool InspectorCSSAgent::forcePseudoState(Element* element, CSSSelector::PseudoType pseudoType)
664{
apavlov@chromium.orgcc4fd4a2012-07-04 16:10:45 +0000665 if (m_nodeIdToForcedPseudoState.isEmpty())
pfeldman@chromium.orgefb43862011-08-16 17:15:06 +0000666 return false;
667
apavlov@chromium.orgcc4fd4a2012-07-04 16:10:45 +0000668 int nodeId = m_domAgent->boundNodeId(element);
669 if (!nodeId)
670 return false;
671
672 NodeIdToForcedPseudoState::iterator it = m_nodeIdToForcedPseudoState.find(nodeId);
673 if (it == m_nodeIdToForcedPseudoState.end())
674 return false;
675
benjamin@webkit.orgee554052012-10-07 23:12:07 +0000676 unsigned forcedPseudoState = it->value;
pfeldman@chromium.orgefb43862011-08-16 17:15:06 +0000677 switch (pseudoType) {
678 case CSSSelector::PseudoActive:
apavlov@chromium.orgcc4fd4a2012-07-04 16:10:45 +0000679 return forcedPseudoState & PseudoActive;
pfeldman@chromium.orgefb43862011-08-16 17:15:06 +0000680 case CSSSelector::PseudoFocus:
apavlov@chromium.orgcc4fd4a2012-07-04 16:10:45 +0000681 return forcedPseudoState & PseudoFocus;
pfeldman@chromium.orgefb43862011-08-16 17:15:06 +0000682 case CSSSelector::PseudoHover:
apavlov@chromium.orgcc4fd4a2012-07-04 16:10:45 +0000683 return forcedPseudoState & PseudoHover;
pfeldman@chromium.orgefb43862011-08-16 17:15:06 +0000684 case CSSSelector::PseudoVisited:
apavlov@chromium.orgcc4fd4a2012-07-04 16:10:45 +0000685 return forcedPseudoState & PseudoVisited;
pfeldman@chromium.orgefb43862011-08-16 17:15:06 +0000686 default:
687 return false;
688 }
689}
690
joepeck@webkit.orga3198442013-12-11 22:40:23 +0000691void InspectorCSSAgent::getMatchedStylesForNode(ErrorString* errorString, int nodeId, const bool* includePseudo, const bool* includeInherited, RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::RuleMatch>>& matchedCSSRules, RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::PseudoIdMatches>>& pseudoIdMatches, RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::InheritedStyleEntry>>& inheritedEntries)
apavlov@chromium.orgd35f1492011-11-21 12:19:52 +0000692{
693 Element* element = elementForId(errorString, nodeId);
694 if (!element)
695 return;
696
apavlov@chromium.orgd35f1492011-11-21 12:19:52 +0000697 // Matched rules.
akling@apple.com622b1a42013-08-30 14:30:12 +0000698 StyleResolver& styleResolver = element->document().ensureStyleResolver();
andersca@apple.comc3523f82013-10-18 23:41:24 +0000699 Vector<RefPtr<StyleRuleBase>> matchedRules = styleResolver.styleRulesForElement(element, StyleResolver::AllCSSRules);
akling@apple.com82a4c882013-05-03 20:43:27 +0000700 matchedCSSRules = buildArrayForMatchedRuleList(matchedRules, styleResolver, element);
apavlov@chromium.orgd35f1492011-11-21 12:19:52 +0000701
702 // Pseudo elements.
apavlov@chromium.org47bfc332012-03-26 14:04:50 +0000703 if (!includePseudo || *includePseudo) {
joepeck@webkit.orga3198442013-12-11 22:40:23 +0000704 RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::PseudoIdMatches>> pseudoElements = Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::PseudoIdMatches>::create();
apavlov@chromium.orgd35f1492011-11-21 12:19:52 +0000705 for (PseudoId pseudoId = FIRST_PUBLIC_PSEUDOID; pseudoId < AFTER_LAST_INTERNAL_PSEUDOID; pseudoId = static_cast<PseudoId>(pseudoId + 1)) {
andersca@apple.comc3523f82013-10-18 23:41:24 +0000706 Vector<RefPtr<StyleRuleBase>> matchedRules = styleResolver.pseudoStyleRulesForElement(element, pseudoId, StyleResolver::AllCSSRules);
akling@apple.com82a4c882013-05-03 20:43:27 +0000707 if (!matchedRules.isEmpty()) {
joepeck@webkit.orga3198442013-12-11 22:40:23 +0000708 RefPtr<Inspector::TypeBuilder::CSS::PseudoIdMatches> matches = Inspector::TypeBuilder::CSS::PseudoIdMatches::create()
apavlov@chromium.org47bfc332012-03-26 14:04:50 +0000709 .setPseudoId(static_cast<int>(pseudoId))
akling@apple.com82a4c882013-05-03 20:43:27 +0000710 .setMatches(buildArrayForMatchedRuleList(matchedRules, styleResolver, element));
apavlov@chromium.orgcecb43f2012-09-25 08:05:18 +0000711 pseudoElements->addItem(matches.release());
apavlov@chromium.orgd35f1492011-11-21 12:19:52 +0000712 }
713 }
714
apavlov@chromium.orgcecb43f2012-09-25 08:05:18 +0000715 pseudoIdMatches = pseudoElements.release();
apavlov@chromium.orgd35f1492011-11-21 12:19:52 +0000716 }
717
718 // Inherited styles.
apavlov@chromium.org47bfc332012-03-26 14:04:50 +0000719 if (!includeInherited || *includeInherited) {
joepeck@webkit.orga3198442013-12-11 22:40:23 +0000720 RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::InheritedStyleEntry>> entries = Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::InheritedStyleEntry>::create();
apavlov@chromium.orgd35f1492011-11-21 12:19:52 +0000721 Element* parentElement = element->parentElement();
722 while (parentElement) {
akling@apple.com622b1a42013-08-30 14:30:12 +0000723 StyleResolver& parentStyleResolver = parentElement->document().ensureStyleResolver();
andersca@apple.comc3523f82013-10-18 23:41:24 +0000724 Vector<RefPtr<StyleRuleBase>> parentMatchedRules = parentStyleResolver.styleRulesForElement(parentElement, StyleResolver::AllCSSRules);
joepeck@webkit.orga3198442013-12-11 22:40:23 +0000725 RefPtr<Inspector::TypeBuilder::CSS::InheritedStyleEntry> entry = Inspector::TypeBuilder::CSS::InheritedStyleEntry::create()
akling@apple.com82a4c882013-05-03 20:43:27 +0000726 .setMatchedCSSRules(buildArrayForMatchedRuleList(parentMatchedRules, styleResolver, parentElement));
apavlov@chromium.orgd35f1492011-11-21 12:19:52 +0000727 if (parentElement->style() && parentElement->style()->length()) {
728 InspectorStyleSheetForInlineStyle* styleSheet = asInspectorStyleSheet(parentElement);
729 if (styleSheet)
apavlov@chromium.orgcecb43f2012-09-25 08:05:18 +0000730 entry->setInlineStyle(styleSheet->buildObjectForStyle(styleSheet->styleForId(InspectorCSSId(styleSheet->id(), 0))));
apavlov@chromium.orgd35f1492011-11-21 12:19:52 +0000731 }
732
apavlov@chromium.orgcecb43f2012-09-25 08:05:18 +0000733 entries->addItem(entry.release());
apavlov@chromium.orgd35f1492011-11-21 12:19:52 +0000734 parentElement = parentElement->parentElement();
735 }
736
apavlov@chromium.orgcecb43f2012-09-25 08:05:18 +0000737 inheritedEntries = entries.release();
apavlov@chromium.orgd35f1492011-11-21 12:19:52 +0000738 }
739}
740
joepeck@webkit.orga3198442013-12-11 22:40:23 +0000741void InspectorCSSAgent::getInlineStylesForNode(ErrorString* errorString, int nodeId, RefPtr<Inspector::TypeBuilder::CSS::CSSStyle>& inlineStyle, RefPtr<Inspector::TypeBuilder::CSS::CSSStyle>& attributesStyle)
apavlov@chromium.org8d79d7f2010-10-07 09:53:40 +0000742{
pfeldman@chromium.orge573fa32011-03-17 18:10:15 +0000743 Element* element = elementForId(errorString, nodeId);
apavlov@chromium.org8d79d7f2010-10-07 09:53:40 +0000744 if (!element)
745 return;
746
747 InspectorStyleSheetForInlineStyle* styleSheet = asInspectorStyleSheet(element);
748 if (!styleSheet)
749 return;
750
loislo@chromium.orgf37187e2011-12-21 05:51:31 +0000751 inlineStyle = styleSheet->buildObjectForStyle(element->style());
joepeck@webkit.orga3198442013-12-11 22:40:23 +0000752 RefPtr<Inspector::TypeBuilder::CSS::CSSStyle> attributes = buildObjectForAttributesStyle(element);
apavlov@chromium.org0d4c01a2012-02-09 12:41:37 +0000753 attributesStyle = attributes ? attributes.release() : 0;
apavlov@chromium.org8d79d7f2010-10-07 09:53:40 +0000754}
755
joepeck@webkit.orga3198442013-12-11 22:40:23 +0000756void InspectorCSSAgent::getComputedStyleForNode(ErrorString* errorString, int nodeId, RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::CSSComputedStyleProperty>>& style)
apavlov@chromium.org8d79d7f2010-10-07 09:53:40 +0000757{
pfeldman@chromium.orge573fa32011-03-17 18:10:15 +0000758 Element* element = elementForId(errorString, nodeId);
apavlov@chromium.org8d79d7f2010-10-07 09:53:40 +0000759 if (!element)
760 return;
761
antti@apple.comac019f32012-02-10 18:22:24 +0000762 RefPtr<CSSComputedStyleDeclaration> computedStyleInfo = CSSComputedStyleDeclaration::create(element, true);
yurys@chromium.org418f91f2010-12-24 17:51:25 +0000763 RefPtr<InspectorStyle> inspectorStyle = InspectorStyle::create(InspectorCSSId(), computedStyleInfo, 0);
loislo@chromium.orgf37187e2011-12-21 05:51:31 +0000764 style = inspectorStyle->buildArrayForComputedStyle();
apavlov@chromium.org8d79d7f2010-10-07 09:53:40 +0000765}
766
joepeck@webkit.orga3198442013-12-11 22:40:23 +0000767void InspectorCSSAgent::getAllStyleSheets(ErrorString*, RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::CSSStyleSheetHeader>>& styleInfos)
apavlov@chromium.org8d79d7f2010-10-07 09:53:40 +0000768{
joepeck@webkit.orga3198442013-12-11 22:40:23 +0000769 styleInfos = Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::CSSStyleSheetHeader>::create();
commit-queue@webkit.org261bc862013-02-19 16:01:52 +0000770 Vector<Document*> documents = m_domAgent->documents();
771 for (Vector<Document*>::iterator it = documents.begin(); it != documents.end(); ++it) {
772 StyleSheetList* list = (*it)->styleSheets();
773 for (unsigned i = 0; i < list->length(); ++i) {
774 StyleSheet* styleSheet = list->item(i);
775 if (styleSheet->isCSSStyleSheet())
776 collectStyleSheets(static_cast<CSSStyleSheet*>(styleSheet), styleInfos.get());
777 }
778 }
apavlov@chromium.org8d79d7f2010-10-07 09:53:40 +0000779}
780
joepeck@webkit.orga3198442013-12-11 22:40:23 +0000781void InspectorCSSAgent::getStyleSheet(ErrorString* errorString, const String& styleSheetId, RefPtr<Inspector::TypeBuilder::CSS::CSSStyleSheetBody>& styleSheetObject)
apavlov@chromium.org8d79d7f2010-10-07 09:53:40 +0000782{
pfeldman@chromium.org8f286ef2011-04-15 12:39:32 +0000783 InspectorStyleSheet* inspectorStyleSheet = assertStyleSheetForId(errorString, styleSheetId);
apavlov@chromium.org8d79d7f2010-10-07 09:53:40 +0000784 if (!inspectorStyleSheet)
785 return;
786
loislo@chromium.orgf37187e2011-12-21 05:51:31 +0000787 styleSheetObject = inspectorStyleSheet->buildObjectForStyleSheet();
apavlov@chromium.org8d79d7f2010-10-07 09:53:40 +0000788}
789
pfeldman@chromium.org8f286ef2011-04-15 12:39:32 +0000790void InspectorCSSAgent::getStyleSheetText(ErrorString* errorString, const String& styleSheetId, String* result)
pfeldman@chromium.org4ee21ff2010-11-24 10:11:39 +0000791{
pfeldman@chromium.org8f286ef2011-04-15 12:39:32 +0000792 InspectorStyleSheet* inspectorStyleSheet = assertStyleSheetForId(errorString, styleSheetId);
pfeldman@chromium.org4ee21ff2010-11-24 10:11:39 +0000793 if (!inspectorStyleSheet)
794 return;
pfeldman@chromium.org8f286ef2011-04-15 12:39:32 +0000795
pfeldman@chromium.org94451152012-02-07 17:00:32 +0000796 inspectorStyleSheet->getText(result);
pfeldman@chromium.org4ee21ff2010-11-24 10:11:39 +0000797}
798
pfeldman@chromium.org8f286ef2011-04-15 12:39:32 +0000799void InspectorCSSAgent::setStyleSheetText(ErrorString* errorString, const String& styleSheetId, const String& text)
apavlov@chromium.org8d79d7f2010-10-07 09:53:40 +0000800{
pfeldman@chromium.org8ef57362012-02-13 13:12:15 +0000801 InspectorStyleSheet* inspectorStyleSheet = assertStyleSheetForId(errorString, styleSheetId);
802 if (!inspectorStyleSheet)
803 return;
804
pfeldman@chromium.orgb5db6a12012-02-10 13:15:12 +0000805 ExceptionCode ec = 0;
pfeldman@chromium.org8ef57362012-02-13 13:12:15 +0000806 m_domAgent->history()->perform(adoptPtr(new SetStyleSheetTextAction(inspectorStyleSheet, text)), ec);
pfeldman@chromium.orgb5db6a12012-02-10 13:15:12 +0000807 *errorString = InspectorDOMAgent::toErrorString(ec);
apavlov@chromium.org8d79d7f2010-10-07 09:53:40 +0000808}
809
joepeck@webkit.orga3198442013-12-11 22:40:23 +0000810void InspectorCSSAgent::setStyleText(ErrorString* errorString, const RefPtr<InspectorObject>& fullStyleId, const String& text, RefPtr<Inspector::TypeBuilder::CSS::CSSStyle>& result)
timothy@apple.com17aafb02013-04-19 05:59:02 +0000811{
812 InspectorCSSId compoundId(fullStyleId);
813 ASSERT(!compoundId.isEmpty());
814
815 InspectorStyleSheet* inspectorStyleSheet = assertStyleSheetForId(errorString, compoundId.styleSheetId());
816 if (!inspectorStyleSheet)
817 return;
818
819 ExceptionCode ec = 0;
820 bool success = m_domAgent->history()->perform(adoptPtr(new SetStyleTextAction(inspectorStyleSheet, compoundId, text)), ec);
821 if (success)
822 result = inspectorStyleSheet->buildObjectForStyle(inspectorStyleSheet->styleForId(compoundId));
823 *errorString = InspectorDOMAgent::toErrorString(ec);
824}
825
joepeck@webkit.orga3198442013-12-11 22:40:23 +0000826void InspectorCSSAgent::setPropertyText(ErrorString* errorString, const RefPtr<InspectorObject>& fullStyleId, int propertyIndex, const String& text, bool overwrite, RefPtr<Inspector::TypeBuilder::CSS::CSSStyle>& result)
apavlov@chromium.org8d79d7f2010-10-07 09:53:40 +0000827{
apavlov@chromium.orgfc8a58c2010-10-22 15:04:52 +0000828 InspectorCSSId compoundId(fullStyleId);
829 ASSERT(!compoundId.isEmpty());
apavlov@chromium.org8d79d7f2010-10-07 09:53:40 +0000830
pfeldman@chromium.org8f286ef2011-04-15 12:39:32 +0000831 InspectorStyleSheet* inspectorStyleSheet = assertStyleSheetForId(errorString, compoundId.styleSheetId());
apavlov@chromium.org8d79d7f2010-10-07 09:53:40 +0000832 if (!inspectorStyleSheet)
833 return;
834
pfeldman@chromium.orgb5db6a12012-02-10 13:15:12 +0000835 ExceptionCode ec = 0;
pfeldman@chromium.org8ef57362012-02-13 13:12:15 +0000836 bool success = m_domAgent->history()->perform(adoptPtr(new SetPropertyTextAction(inspectorStyleSheet, compoundId, propertyIndex, text, overwrite)), ec);
apavlov@chromium.orgfc8a58c2010-10-22 15:04:52 +0000837 if (success)
loislo@chromium.orgf37187e2011-12-21 05:51:31 +0000838 result = inspectorStyleSheet->buildObjectForStyle(inspectorStyleSheet->styleForId(compoundId));
pfeldman@chromium.orgb5db6a12012-02-10 13:15:12 +0000839 *errorString = InspectorDOMAgent::toErrorString(ec);
apavlov@chromium.org8d79d7f2010-10-07 09:53:40 +0000840}
841
joepeck@webkit.orga3198442013-12-11 22:40:23 +0000842void InspectorCSSAgent::toggleProperty(ErrorString* errorString, const RefPtr<InspectorObject>& fullStyleId, int propertyIndex, bool disable, RefPtr<Inspector::TypeBuilder::CSS::CSSStyle>& result)
apavlov@chromium.org8d79d7f2010-10-07 09:53:40 +0000843{
apavlov@chromium.orgfc8a58c2010-10-22 15:04:52 +0000844 InspectorCSSId compoundId(fullStyleId);
845 ASSERT(!compoundId.isEmpty());
846
pfeldman@chromium.org8f286ef2011-04-15 12:39:32 +0000847 InspectorStyleSheet* inspectorStyleSheet = assertStyleSheetForId(errorString, compoundId.styleSheetId());
apavlov@chromium.orgfc8a58c2010-10-22 15:04:52 +0000848 if (!inspectorStyleSheet)
849 return;
850
pfeldman@chromium.orgb5db6a12012-02-10 13:15:12 +0000851 ExceptionCode ec = 0;
pfeldman@chromium.org8ef57362012-02-13 13:12:15 +0000852 bool success = m_domAgent->history()->perform(adoptPtr(new TogglePropertyAction(inspectorStyleSheet, compoundId, propertyIndex, disable)), ec);
apavlov@chromium.orgfc8a58c2010-10-22 15:04:52 +0000853 if (success)
loislo@chromium.orgf37187e2011-12-21 05:51:31 +0000854 result = inspectorStyleSheet->buildObjectForStyle(inspectorStyleSheet->styleForId(compoundId));
pfeldman@chromium.orgb5db6a12012-02-10 13:15:12 +0000855 *errorString = InspectorDOMAgent::toErrorString(ec);
apavlov@chromium.org8d79d7f2010-10-07 09:53:40 +0000856}
857
joepeck@webkit.orga3198442013-12-11 22:40:23 +0000858void InspectorCSSAgent::setRuleSelector(ErrorString* errorString, const RefPtr<InspectorObject>& fullRuleId, const String& selector, RefPtr<Inspector::TypeBuilder::CSS::CSSRule>& result)
apavlov@chromium.org8d79d7f2010-10-07 09:53:40 +0000859{
apavlov@chromium.orgfc8a58c2010-10-22 15:04:52 +0000860 InspectorCSSId compoundId(fullRuleId);
861 ASSERT(!compoundId.isEmpty());
apavlov@chromium.org8d79d7f2010-10-07 09:53:40 +0000862
pfeldman@chromium.org8f286ef2011-04-15 12:39:32 +0000863 InspectorStyleSheet* inspectorStyleSheet = assertStyleSheetForId(errorString, compoundId.styleSheetId());
apavlov@chromium.org8d79d7f2010-10-07 09:53:40 +0000864 if (!inspectorStyleSheet)
865 return;
866
pfeldman@chromium.org8ef57362012-02-13 13:12:15 +0000867 ExceptionCode ec = 0;
868 bool success = m_domAgent->history()->perform(adoptPtr(new SetRuleSelectorAction(inspectorStyleSheet, compoundId, selector)), ec);
apavlov@chromium.org8d79d7f2010-10-07 09:53:40 +0000869
pfeldman@chromium.org8ef57362012-02-13 13:12:15 +0000870 if (success)
871 result = inspectorStyleSheet->buildObjectForRule(inspectorStyleSheet->ruleForId(compoundId));
apavlov@chromium.org47bfc332012-03-26 14:04:50 +0000872 *errorString = InspectorDOMAgent::toErrorString(ec);
apavlov@chromium.org8d79d7f2010-10-07 09:53:40 +0000873}
874
joepeck@webkit.orga3198442013-12-11 22:40:23 +0000875void InspectorCSSAgent::addRule(ErrorString* errorString, const int contextNodeId, const String& selector, RefPtr<Inspector::TypeBuilder::CSS::CSSRule>& result)
apavlov@chromium.org8d79d7f2010-10-07 09:53:40 +0000876{
pfeldman@chromium.org8ef57362012-02-13 13:12:15 +0000877 Node* node = m_domAgent->assertNode(errorString, contextNodeId);
apavlov@chromium.org8d79d7f2010-10-07 09:53:40 +0000878 if (!node)
879 return;
880
akling@apple.com622b1a42013-08-30 14:30:12 +0000881 InspectorStyleSheet* inspectorStyleSheet = viaInspectorStyleSheet(&node->document(), true);
pfeldman@chromium.org8ef57362012-02-13 13:12:15 +0000882 if (!inspectorStyleSheet) {
883 *errorString = "No target stylesheet found";
apavlov@chromium.orgd41cebd2011-01-20 15:46:28 +0000884 return;
pfeldman@chromium.org8ef57362012-02-13 13:12:15 +0000885 }
apavlov@chromium.org6dbb39d2010-11-10 17:12:45 +0000886
pfeldman@chromium.org8ef57362012-02-13 13:12:15 +0000887 ExceptionCode ec = 0;
888 OwnPtr<AddRuleAction> action = adoptPtr(new AddRuleAction(inspectorStyleSheet, selector));
889 AddRuleAction* rawAction = action.get();
890 bool success = m_domAgent->history()->perform(action.release(), ec);
891 if (!success) {
892 *errorString = InspectorDOMAgent::toErrorString(ec);
893 return;
894 }
895
896 InspectorCSSId ruleId = rawAction->newRuleId();
897 CSSStyleRule* rule = inspectorStyleSheet->ruleForId(ruleId);
898 result = inspectorStyleSheet->buildObjectForRule(rule);
apavlov@chromium.org8d79d7f2010-10-07 09:53:40 +0000899}
900
joepeck@webkit.orga3198442013-12-11 22:40:23 +0000901void InspectorCSSAgent::getSupportedCSSProperties(ErrorString*, RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::CSSPropertyInfo>>& cssProperties)
apavlov@chromium.org8d79d7f2010-10-07 09:53:40 +0000902{
joepeck@webkit.orga3198442013-12-11 22:40:23 +0000903 RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::CSSPropertyInfo>> properties = Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::CSSPropertyInfo>::create();
pfeldman@chromium.orga7128942012-07-25 13:48:47 +0000904 for (int i = firstCSSProperty; i <= lastCSSProperty; ++i) {
905 CSSPropertyID id = convertToCSSPropertyID(i);
joepeck@webkit.orga3198442013-12-11 22:40:23 +0000906 RefPtr<Inspector::TypeBuilder::CSS::CSSPropertyInfo> property = Inspector::TypeBuilder::CSS::CSSPropertyInfo::create()
benjamin@webkit.org5ab707f2012-08-17 21:24:15 +0000907 .setName(getPropertyNameString(id));
apavlov@chromium.org8d79d7f2010-10-07 09:53:40 +0000908
pfeldman@chromium.orga7128942012-07-25 13:48:47 +0000909 const StylePropertyShorthand& shorthand = shorthandForProperty(id);
910 if (!shorthand.length()) {
911 properties->addItem(property.release());
912 continue;
913 }
joepeck@webkit.orga3198442013-12-11 22:40:23 +0000914 RefPtr<Inspector::TypeBuilder::Array<String>> longhands = Inspector::TypeBuilder::Array<String>::create();
pfeldman@chromium.orga7128942012-07-25 13:48:47 +0000915 for (unsigned j = 0; j < shorthand.length(); ++j) {
916 CSSPropertyID longhandID = shorthand.properties()[j];
benjamin@webkit.org5ab707f2012-08-17 21:24:15 +0000917 longhands->addItem(getPropertyNameString(longhandID));
pfeldman@chromium.orga7128942012-07-25 13:48:47 +0000918 }
919 property->setLonghands(longhands);
920 properties->addItem(property.release());
921 }
loislo@chromium.orgf37187e2011-12-21 05:51:31 +0000922 cssProperties = properties.release();
apavlov@chromium.org8d79d7f2010-10-07 09:53:40 +0000923}
924
apavlov@chromium.orgd728ecd2012-08-13 09:06:15 +0000925void InspectorCSSAgent::forcePseudoState(ErrorString* errorString, int nodeId, const RefPtr<InspectorArray>& forcedPseudoClasses)
926{
927 Element* element = m_domAgent->assertElement(errorString, nodeId);
928 if (!element)
929 return;
930
931 unsigned forcedPseudoState = computePseudoClassMask(forcedPseudoClasses.get());
932 NodeIdToForcedPseudoState::iterator it = m_nodeIdToForcedPseudoState.find(nodeId);
benjamin@webkit.orgee554052012-10-07 23:12:07 +0000933 unsigned currentForcedPseudoState = it == m_nodeIdToForcedPseudoState.end() ? 0 : it->value;
apavlov@chromium.orgd728ecd2012-08-13 09:06:15 +0000934 bool needStyleRecalc = forcedPseudoState != currentForcedPseudoState;
935 if (!needStyleRecalc)
936 return;
937
938 if (forcedPseudoState)
939 m_nodeIdToForcedPseudoState.set(nodeId, forcedPseudoState);
940 else
941 m_nodeIdToForcedPseudoState.remove(nodeId);
akling@apple.com622b1a42013-08-30 14:30:12 +0000942 element->document().styleResolverChanged(RecalcStyleImmediately);
apavlov@chromium.orgd728ecd2012-08-13 09:06:15 +0000943}
944
joepeck@webkit.orga3198442013-12-11 22:40:23 +0000945void InspectorCSSAgent::getNamedFlowCollection(ErrorString* errorString, int documentNodeId, RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::NamedFlow>>& result)
commit-queue@webkit.org6f859512012-07-20 12:34:58 +0000946{
commit-queue@webkit.orge2bb32c2012-08-10 09:58:35 +0000947 Document* document = m_domAgent->assertDocument(errorString, documentNodeId);
commit-queue@webkit.org6f859512012-07-20 12:34:58 +0000948 if (!document)
949 return;
950
commit-queue@webkit.orge2bb32c2012-08-10 09:58:35 +0000951 m_namedFlowCollectionsRequested.add(documentNodeId);
commit-queue@webkit.org65563d42012-09-12 12:07:24 +0000952
andersca@apple.comc3523f82013-10-18 23:41:24 +0000953 Vector<RefPtr<WebKitNamedFlow>> namedFlowsVector = document->namedFlows()->namedFlows();
joepeck@webkit.orga3198442013-12-11 22:40:23 +0000954 RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::NamedFlow>> namedFlows = Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::NamedFlow>::create();
commit-queue@webkit.org5c25fc42012-08-06 16:39:56 +0000955
andersca@apple.comc3523f82013-10-18 23:41:24 +0000956 for (Vector<RefPtr<WebKitNamedFlow>>::iterator it = namedFlowsVector.begin(); it != namedFlowsVector.end(); ++it)
commit-queue@webkit.orge2bb32c2012-08-10 09:58:35 +0000957 namedFlows->addItem(buildObjectForNamedFlow(errorString, it->get(), documentNodeId));
commit-queue@webkit.org6f859512012-07-20 12:34:58 +0000958
959 result = namedFlows.release();
960}
961
apavlov@chromium.org8d79d7f2010-10-07 09:53:40 +0000962InspectorStyleSheetForInlineStyle* InspectorCSSAgent::asInspectorStyleSheet(Element* element)
963{
964 NodeToInspectorStyleSheet::iterator it = m_nodeToInspectorStyleSheet.find(element);
965 if (it == m_nodeToInspectorStyleSheet.end()) {
966 CSSStyleDeclaration* style = element->isStyledElement() ? element->style() : 0;
967 if (!style)
968 return 0;
969
970 String newStyleSheetId = String::number(m_lastStyleSheetId++);
joepeck@webkit.orga3198442013-12-11 22:40:23 +0000971 RefPtr<InspectorStyleSheetForInlineStyle> inspectorStyleSheet = InspectorStyleSheetForInlineStyle::create(m_domAgent->pageAgent(), newStyleSheetId, element, Inspector::TypeBuilder::CSS::StyleSheetOrigin::Regular, this);
apavlov@chromium.org8d79d7f2010-10-07 09:53:40 +0000972 m_idToInspectorStyleSheet.set(newStyleSheetId, inspectorStyleSheet);
973 m_nodeToInspectorStyleSheet.set(element, inspectorStyleSheet);
974 return inspectorStyleSheet.get();
975 }
976
benjamin@webkit.orgee554052012-10-07 23:12:07 +0000977 return it->value.get();
apavlov@chromium.org8d79d7f2010-10-07 09:53:40 +0000978}
979
pfeldman@chromium.org7e420b52011-03-21 07:54:32 +0000980Element* InspectorCSSAgent::elementForId(ErrorString* errorString, int nodeId)
apavlov@chromium.org8d79d7f2010-10-07 09:53:40 +0000981{
982 Node* node = m_domAgent->nodeForId(nodeId);
pfeldman@chromium.orge573fa32011-03-17 18:10:15 +0000983 if (!node) {
caseq@chromium.orgc2485692011-03-31 15:21:33 +0000984 *errorString = "No node with given id found";
pfeldman@chromium.orge573fa32011-03-17 18:10:15 +0000985 return 0;
986 }
commit-queue@webkit.orgecfaf0d2013-08-24 11:24:10 +0000987 if (!node->isElementNode()) {
caseq@chromium.orgc2485692011-03-31 15:21:33 +0000988 *errorString = "Not an element node";
pfeldman@chromium.orge573fa32011-03-17 18:10:15 +0000989 return 0;
990 }
apavlov@chromium.orgcc4fd4a2012-07-04 16:10:45 +0000991 return toElement(node);
apavlov@chromium.org8d79d7f2010-10-07 09:53:40 +0000992}
993
commit-queue@webkit.org65563d42012-09-12 12:07:24 +0000994int InspectorCSSAgent::documentNodeWithRequestedFlowsId(Document* document)
995{
996 int documentNodeId = m_domAgent->boundNodeId(document);
997 if (!documentNodeId || !m_namedFlowCollectionsRequested.contains(documentNodeId))
998 return 0;
999
1000 return documentNodeId;
1001}
1002
joepeck@webkit.orga3198442013-12-11 22:40:23 +00001003void InspectorCSSAgent::collectStyleSheets(CSSStyleSheet* styleSheet, Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::CSSStyleSheetHeader>* result)
apavlov@chromium.orgbe789cf2011-05-18 13:32:07 +00001004{
1005 InspectorStyleSheet* inspectorStyleSheet = bindStyleSheet(static_cast<CSSStyleSheet*>(styleSheet));
commit-queue@webkit.org261bc862013-02-19 16:01:52 +00001006 result->addItem(inspectorStyleSheet->buildObjectForStyleSheetInfo());
apavlov@chromium.orgbe789cf2011-05-18 13:32:07 +00001007 for (unsigned i = 0, size = styleSheet->length(); i < size; ++i) {
andreas.kling@nokia.com1678e2b2011-10-14 18:36:31 +00001008 CSSRule* rule = styleSheet->item(i);
akling@apple.comc713db32012-11-22 03:45:40 +00001009 if (rule->type() == CSSRule::IMPORT_RULE) {
andreas.kling@nokia.com1678e2b2011-10-14 18:36:31 +00001010 CSSStyleSheet* importedStyleSheet = static_cast<CSSImportRule*>(rule)->styleSheet();
1011 if (importedStyleSheet)
1012 collectStyleSheets(importedStyleSheet, result);
apavlov@chromium.orgbe789cf2011-05-18 13:32:07 +00001013 }
1014 }
1015}
1016
apavlov@chromium.org8d79d7f2010-10-07 09:53:40 +00001017InspectorStyleSheet* InspectorCSSAgent::bindStyleSheet(CSSStyleSheet* styleSheet)
1018{
1019 RefPtr<InspectorStyleSheet> inspectorStyleSheet = m_cssStyleSheetToInspectorStyleSheet.get(styleSheet);
1020 if (!inspectorStyleSheet) {
1021 String id = String::number(m_lastStyleSheetId++);
antti@apple.comfe126eb2012-04-25 22:42:47 +00001022 Document* document = styleSheet->ownerDocument();
pfeldman@chromium.orgf9adb6a2012-05-24 14:35:50 +00001023 inspectorStyleSheet = InspectorStyleSheet::create(m_domAgent->pageAgent(), id, styleSheet, detectOrigin(styleSheet, document), InspectorDOMAgent::documentURLString(document), this);
apavlov@chromium.org8d79d7f2010-10-07 09:53:40 +00001024 m_idToInspectorStyleSheet.set(id, inspectorStyleSheet);
1025 m_cssStyleSheetToInspectorStyleSheet.set(styleSheet, inspectorStyleSheet);
1026 }
1027 return inspectorStyleSheet.get();
1028}
1029
1030InspectorStyleSheet* InspectorCSSAgent::viaInspectorStyleSheet(Document* document, bool createIfAbsent)
1031{
1032 if (!document) {
1033 ASSERT(!createIfAbsent);
1034 return 0;
1035 }
1036
apavlov@chromium.org53991942013-03-25 12:55:30 +00001037 if (!document->isHTMLDocument() && !document->isSVGDocument())
1038 return 0;
1039
apavlov@chromium.org8d79d7f2010-10-07 09:53:40 +00001040 RefPtr<InspectorStyleSheet> inspectorStyleSheet = m_documentToInspectorStyleSheet.get(document);
1041 if (inspectorStyleSheet || !createIfAbsent)
1042 return inspectorStyleSheet.get();
1043
1044 ExceptionCode ec = 0;
1045 RefPtr<Element> styleElement = document->createElement("style", ec);
1046 if (!ec)
1047 styleElement->setAttribute("type", "text/css", ec);
apavlov@chromium.orgd41cebd2011-01-20 15:46:28 +00001048 if (!ec) {
1049 ContainerNode* targetNode;
1050 // HEAD is absent in ImageDocuments, for example.
1051 if (document->head())
1052 targetNode = document->head();
1053 else if (document->body())
1054 targetNode = document->body();
1055 else
1056 return 0;
apavlov@chromium.org31442e82012-03-05 10:44:40 +00001057
1058 InlineStyleOverrideScope overrideScope(document);
apavlov@chromium.orgd41cebd2011-01-20 15:46:28 +00001059 targetNode->appendChild(styleElement, ec);
1060 }
apavlov@chromium.org8d79d7f2010-10-07 09:53:40 +00001061 if (ec)
1062 return 0;
apavlov@chromium.org5f4304d2013-03-04 13:34:47 +00001063
apavlov@chromium.org53991942013-03-25 12:55:30 +00001064 CSSStyleSheet* cssStyleSheet = 0;
1065 if (styleElement->isHTMLElement())
kangil.han@samsung.comb9a949e2013-06-24 15:12:52 +00001066 cssStyleSheet = toHTMLStyleElement(styleElement.get())->sheet();
apavlov@chromium.org53991942013-03-25 12:55:30 +00001067 else if (styleElement->isSVGElement())
akling@apple.com3d1b2232013-09-10 03:10:11 +00001068 cssStyleSheet = toSVGStyleElement(styleElement.get())->sheet();
apavlov@chromium.org5f4304d2013-03-04 13:34:47 +00001069
apavlov@chromium.org5f4304d2013-03-04 13:34:47 +00001070 if (!cssStyleSheet)
1071 return 0;
1072
commit-queue@webkit.org261bc862013-02-19 16:01:52 +00001073 String id = String::number(m_lastStyleSheetId++);
joepeck@webkit.orga3198442013-12-11 22:40:23 +00001074 inspectorStyleSheet = InspectorStyleSheet::create(m_domAgent->pageAgent(), id, cssStyleSheet, Inspector::TypeBuilder::CSS::StyleSheetOrigin::Inspector, InspectorDOMAgent::documentURLString(document), this);
commit-queue@webkit.org261bc862013-02-19 16:01:52 +00001075 m_idToInspectorStyleSheet.set(id, inspectorStyleSheet);
1076 m_cssStyleSheetToInspectorStyleSheet.set(cssStyleSheet, inspectorStyleSheet);
1077 m_documentToInspectorStyleSheet.set(document, inspectorStyleSheet);
1078 return inspectorStyleSheet.get();
apavlov@chromium.org8d79d7f2010-10-07 09:53:40 +00001079}
1080
pfeldman@chromium.org8f286ef2011-04-15 12:39:32 +00001081InspectorStyleSheet* InspectorCSSAgent::assertStyleSheetForId(ErrorString* errorString, const String& styleSheetId)
apavlov@chromium.org8d79d7f2010-10-07 09:53:40 +00001082{
1083 IdToInspectorStyleSheet::iterator it = m_idToInspectorStyleSheet.find(styleSheetId);
pfeldman@chromium.orge573fa32011-03-17 18:10:15 +00001084 if (it == m_idToInspectorStyleSheet.end()) {
caseq@chromium.orgc2485692011-03-31 15:21:33 +00001085 *errorString = "No style sheet with given id found";
pfeldman@chromium.orge573fa32011-03-17 18:10:15 +00001086 return 0;
1087 }
benjamin@webkit.orgee554052012-10-07 23:12:07 +00001088 return it->value.get();
apavlov@chromium.org8d79d7f2010-10-07 09:53:40 +00001089}
1090
joepeck@webkit.orga3198442013-12-11 22:40:23 +00001091Inspector::TypeBuilder::CSS::StyleSheetOrigin::Enum InspectorCSSAgent::detectOrigin(CSSStyleSheet* pageStyleSheet, Document* ownerDocument)
apavlov@chromium.org8d79d7f2010-10-07 09:53:40 +00001092{
joepeck@webkit.orga3198442013-12-11 22:40:23 +00001093 Inspector::TypeBuilder::CSS::StyleSheetOrigin::Enum origin = Inspector::TypeBuilder::CSS::StyleSheetOrigin::Regular;
apavlov@chromium.org8d79d7f2010-10-07 09:53:40 +00001094 if (pageStyleSheet && !pageStyleSheet->ownerNode() && pageStyleSheet->href().isEmpty())
joepeck@webkit.orga3198442013-12-11 22:40:23 +00001095 origin = Inspector::TypeBuilder::CSS::StyleSheetOrigin::UserAgent;
apavlov@chromium.org8d79d7f2010-10-07 09:53:40 +00001096 else if (pageStyleSheet && pageStyleSheet->ownerNode() && pageStyleSheet->ownerNode()->nodeName() == "#document")
joepeck@webkit.orga3198442013-12-11 22:40:23 +00001097 origin = Inspector::TypeBuilder::CSS::StyleSheetOrigin::User;
apavlov@chromium.org8d79d7f2010-10-07 09:53:40 +00001098 else {
1099 InspectorStyleSheet* viaInspectorStyleSheetForOwner = viaInspectorStyleSheet(ownerDocument, false);
1100 if (viaInspectorStyleSheetForOwner && pageStyleSheet == viaInspectorStyleSheetForOwner->pageStyleSheet())
joepeck@webkit.orga3198442013-12-11 22:40:23 +00001101 origin = Inspector::TypeBuilder::CSS::StyleSheetOrigin::Inspector;
apavlov@chromium.org8d79d7f2010-10-07 09:53:40 +00001102 }
1103 return origin;
1104}
1105
joepeck@webkit.orga3198442013-12-11 22:40:23 +00001106PassRefPtr<Inspector::TypeBuilder::CSS::CSSRule> InspectorCSSAgent::buildObjectForRule(StyleRule* styleRule, StyleResolver& styleResolver)
akling@apple.com82a4c882013-05-03 20:43:27 +00001107{
1108 if (!styleRule)
1109 return 0;
1110
1111 // StyleRules returned by StyleResolver::styleRulesForElement lack parent pointers since that infomation is not cheaply available.
1112 // Since the inspector wants to walk the parent chain, we construct the full wrappers here.
akling@apple.comccd9e082013-08-30 16:18:11 +00001113 CSSStyleRule* cssomWrapper = styleResolver.inspectorCSSOMWrappers().getWrapperForRuleInSheets(styleRule, styleResolver.document().styleSheetCollection());
akling@apple.com82a4c882013-05-03 20:43:27 +00001114 if (!cssomWrapper)
1115 return 0;
1116 InspectorStyleSheet* inspectorStyleSheet = bindStyleSheet(cssomWrapper->parentStyleSheet());
1117 return inspectorStyleSheet ? inspectorStyleSheet->buildObjectForRule(cssomWrapper) : 0;
1118}
1119
joepeck@webkit.orga3198442013-12-11 22:40:23 +00001120PassRefPtr<Inspector::TypeBuilder::CSS::CSSRule> InspectorCSSAgent::buildObjectForRule(CSSStyleRule* rule)
apavlov@chromium.orgcecb43f2012-09-25 08:05:18 +00001121{
1122 if (!rule)
1123 return 0;
1124
akling@apple.com82a4c882013-05-03 20:43:27 +00001125 ASSERT(rule->parentStyleSheet());
commit-queue@webkit.org261bc862013-02-19 16:01:52 +00001126 InspectorStyleSheet* inspectorStyleSheet = bindStyleSheet(rule->parentStyleSheet());
1127 return inspectorStyleSheet ? inspectorStyleSheet->buildObjectForRule(rule) : 0;
apavlov@chromium.orgcecb43f2012-09-25 08:05:18 +00001128}
1129
joepeck@webkit.orga3198442013-12-11 22:40:23 +00001130PassRefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::CSSRule>> InspectorCSSAgent::buildArrayForRuleList(CSSRuleList* ruleList)
apavlov@chromium.org8d79d7f2010-10-07 09:53:40 +00001131{
joepeck@webkit.orga3198442013-12-11 22:40:23 +00001132 RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::CSSRule>> result = Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::CSSRule>::create();
apavlov@chromium.org8d79d7f2010-10-07 09:53:40 +00001133 if (!ruleList)
1134 return result.release();
1135
1136 for (unsigned i = 0, size = ruleList->length(); i < size; ++i) {
1137 CSSStyleRule* rule = asCSSStyleRule(ruleList->item(i));
joepeck@webkit.orga3198442013-12-11 22:40:23 +00001138 RefPtr<Inspector::TypeBuilder::CSS::CSSRule> ruleObject = buildObjectForRule(rule);
apavlov@chromium.orgcecb43f2012-09-25 08:05:18 +00001139 if (!ruleObject)
apavlov@chromium.org8d79d7f2010-10-07 09:53:40 +00001140 continue;
apavlov@chromium.orgcecb43f2012-09-25 08:05:18 +00001141 result->addItem(ruleObject);
apavlov@chromium.org8d79d7f2010-10-07 09:53:40 +00001142 }
1143 return result.release();
1144}
1145
joepeck@webkit.orga3198442013-12-11 22:40:23 +00001146PassRefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::RuleMatch>> InspectorCSSAgent::buildArrayForMatchedRuleList(const Vector<RefPtr<StyleRuleBase>>& matchedRules, StyleResolver& styleResolver, Element* element)
apavlov@chromium.orgcecb43f2012-09-25 08:05:18 +00001147{
joepeck@webkit.orga3198442013-12-11 22:40:23 +00001148 RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::RuleMatch>> result = Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::RuleMatch>::create();
apavlov@chromium.orgcecb43f2012-09-25 08:05:18 +00001149
akling@apple.com82a4c882013-05-03 20:43:27 +00001150 for (unsigned i = 0; i < matchedRules.size(); ++i) {
1151 if (!matchedRules[i]->isStyleRule())
1152 continue;
1153 StyleRule* matchedStyleRule = static_cast<StyleRule*>(matchedRules[i].get());
joepeck@webkit.orga3198442013-12-11 22:40:23 +00001154 RefPtr<Inspector::TypeBuilder::CSS::CSSRule> ruleObject = buildObjectForRule(matchedStyleRule, styleResolver);
apavlov@chromium.orgcecb43f2012-09-25 08:05:18 +00001155 if (!ruleObject)
1156 continue;
joepeck@webkit.orga3198442013-12-11 22:40:23 +00001157 RefPtr<Inspector::TypeBuilder::Array<int>> matchingSelectors = Inspector::TypeBuilder::Array<int>::create();
akling@apple.com82a4c882013-05-03 20:43:27 +00001158 const CSSSelectorList& selectorList = matchedStyleRule->selectorList();
apavlov@chromium.orgcecb43f2012-09-25 08:05:18 +00001159 long index = 0;
akling@apple.com140a7712013-01-23 10:26:04 +00001160 for (const CSSSelector* selector = selectorList.first(); selector; selector = CSSSelectorList::next(selector)) {
mkwst@chromium.org33cdf432013-02-08 14:21:48 +00001161 bool matched = element->webkitMatchesSelector(selector->selectorText(), IGNORE_EXCEPTION);
apavlov@chromium.orgcecb43f2012-09-25 08:05:18 +00001162 if (matched)
1163 matchingSelectors->addItem(index);
1164 ++index;
1165 }
joepeck@webkit.orga3198442013-12-11 22:40:23 +00001166 RefPtr<Inspector::TypeBuilder::CSS::RuleMatch> match = Inspector::TypeBuilder::CSS::RuleMatch::create()
apavlov@chromium.orgcecb43f2012-09-25 08:05:18 +00001167 .setRule(ruleObject)
1168 .setMatchingSelectors(matchingSelectors);
1169 result->addItem(match);
1170 }
1171
akling@apple.com82a4c882013-05-03 20:43:27 +00001172 return result.release();
apavlov@chromium.orgcecb43f2012-09-25 08:05:18 +00001173}
1174
joepeck@webkit.orga3198442013-12-11 22:40:23 +00001175PassRefPtr<Inspector::TypeBuilder::CSS::CSSStyle> InspectorCSSAgent::buildObjectForAttributesStyle(Element* element)
apavlov@chromium.org8d79d7f2010-10-07 09:53:40 +00001176{
kling@webkit.org119bc4e2012-02-04 12:24:19 +00001177 if (!element->isStyledElement())
apavlov@chromium.org0d4c01a2012-02-09 12:41:37 +00001178 return 0;
kling@webkit.org119bc4e2012-02-04 12:24:19 +00001179
akling@apple.comb977e612013-04-14 15:19:59 +00001180 // FIXME: Ugliness below.
antti@apple.come5428c52013-11-28 20:53:22 +00001181 StyleProperties* attributeStyle = const_cast<StyleProperties*>(toStyledElement(element)->presentationAttributeStyle());
commit-queue@webkit.org844de9e2012-11-05 10:47:35 +00001182 if (!attributeStyle)
apavlov@chromium.org0d4c01a2012-02-09 12:41:37 +00001183 return 0;
kling@webkit.org119bc4e2012-02-04 12:24:19 +00001184
akling@apple.com670fea12013-10-12 18:16:42 +00001185 ASSERT_WITH_SECURITY_IMPLICATION(attributeStyle->isMutable());
antti@apple.come5428c52013-11-28 20:53:22 +00001186 MutableStyleProperties* mutableAttributeStyle = static_cast<MutableStyleProperties*>(attributeStyle);
akling@apple.comb977e612013-04-14 15:19:59 +00001187
1188 RefPtr<InspectorStyle> inspectorStyle = InspectorStyle::create(InspectorCSSId(), mutableAttributeStyle->ensureCSSStyleDeclaration(), 0);
apavlov@chromium.org0d4c01a2012-02-09 12:41:37 +00001189 return inspectorStyle->buildObjectForStyle();
apavlov@chromium.org8d79d7f2010-10-07 09:53:40 +00001190}
1191
joepeck@webkit.orga3198442013-12-11 22:40:23 +00001192PassRefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::Region>> InspectorCSSAgent::buildArrayForRegions(ErrorString* errorString, PassRefPtr<NodeList> regionList, int documentNodeId)
commit-queue@webkit.orge2bb32c2012-08-10 09:58:35 +00001193{
joepeck@webkit.orga3198442013-12-11 22:40:23 +00001194 RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::Region>> regions = Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::Region>::create();
commit-queue@webkit.orge2bb32c2012-08-10 09:58:35 +00001195
1196 for (unsigned i = 0; i < regionList->length(); ++i) {
joepeck@webkit.orga3198442013-12-11 22:40:23 +00001197 Inspector::TypeBuilder::CSS::Region::RegionOverset::Enum regionOverset;
commit-queue@webkit.orge2bb32c2012-08-10 09:58:35 +00001198
commit-queue@webkit.org75d76c42013-06-20 16:13:11 +00001199 switch (toElement(regionList->item(i))->renderRegion()->regionOversetState()) {
1200 case RegionFit:
joepeck@webkit.orga3198442013-12-11 22:40:23 +00001201 regionOverset = Inspector::TypeBuilder::CSS::Region::RegionOverset::Fit;
commit-queue@webkit.orge2bb32c2012-08-10 09:58:35 +00001202 break;
commit-queue@webkit.org75d76c42013-06-20 16:13:11 +00001203 case RegionEmpty:
joepeck@webkit.orga3198442013-12-11 22:40:23 +00001204 regionOverset = Inspector::TypeBuilder::CSS::Region::RegionOverset::Empty;
commit-queue@webkit.orge2bb32c2012-08-10 09:58:35 +00001205 break;
commit-queue@webkit.org75d76c42013-06-20 16:13:11 +00001206 case RegionOverset:
joepeck@webkit.orga3198442013-12-11 22:40:23 +00001207 regionOverset = Inspector::TypeBuilder::CSS::Region::RegionOverset::Overset;
commit-queue@webkit.orge2bb32c2012-08-10 09:58:35 +00001208 break;
commit-queue@webkit.org75d76c42013-06-20 16:13:11 +00001209 case RegionUndefined:
commit-queue@webkit.orge2bb32c2012-08-10 09:58:35 +00001210 continue;
1211 default:
1212 ASSERT_NOT_REACHED();
1213 continue;
1214 }
1215
joepeck@webkit.orga3198442013-12-11 22:40:23 +00001216 RefPtr<Inspector::TypeBuilder::CSS::Region> region = Inspector::TypeBuilder::CSS::Region::create()
commit-queue@webkit.orge2bb32c2012-08-10 09:58:35 +00001217 .setRegionOverset(regionOverset)
1218 // documentNodeId was previously asserted
1219 .setNodeId(m_domAgent->pushNodeToFrontend(errorString, documentNodeId, regionList->item(i)));
1220
1221 regions->addItem(region);
1222 }
1223
1224 return regions.release();
1225}
1226
joepeck@webkit.orga3198442013-12-11 22:40:23 +00001227PassRefPtr<Inspector::TypeBuilder::CSS::NamedFlow> InspectorCSSAgent::buildObjectForNamedFlow(ErrorString* errorString, WebKitNamedFlow* webkitNamedFlow, int documentNodeId)
commit-queue@webkit.orge2bb32c2012-08-10 09:58:35 +00001228{
1229 RefPtr<NodeList> contentList = webkitNamedFlow->getContent();
joepeck@webkit.orga3198442013-12-11 22:40:23 +00001230 RefPtr<Inspector::TypeBuilder::Array<int>> content = Inspector::TypeBuilder::Array<int>::create();
commit-queue@webkit.orge2bb32c2012-08-10 09:58:35 +00001231
1232 for (unsigned i = 0; i < contentList->length(); ++i) {
1233 // documentNodeId was previously asserted
1234 content->addItem(m_domAgent->pushNodeToFrontend(errorString, documentNodeId, contentList->item(i)));
1235 }
1236
joepeck@webkit.orga3198442013-12-11 22:40:23 +00001237 RefPtr<Inspector::TypeBuilder::CSS::NamedFlow> namedFlow = Inspector::TypeBuilder::CSS::NamedFlow::create()
commit-queue@webkit.orge2bb32c2012-08-10 09:58:35 +00001238 .setDocumentNodeId(documentNodeId)
1239 .setName(webkitNamedFlow->name().string())
1240 .setOverset(webkitNamedFlow->overset())
1241 .setContent(content)
1242 .setRegions(buildArrayForRegions(errorString, webkitNamedFlow->getRegions(), documentNodeId));
1243
1244 return namedFlow.release();
1245}
1246
apavlov@chromium.org8d79d7f2010-10-07 09:53:40 +00001247void InspectorCSSAgent::didRemoveDocument(Document* document)
1248{
apavlov@chromium.org6dbb39d2010-11-10 17:12:45 +00001249 if (document)
1250 m_documentToInspectorStyleSheet.remove(document);
apavlov@chromium.org8d79d7f2010-10-07 09:53:40 +00001251}
1252
1253void InspectorCSSAgent::didRemoveDOMNode(Node* node)
1254{
apavlov@chromium.org6dbb39d2010-11-10 17:12:45 +00001255 if (!node)
1256 return;
1257
apavlov@chromium.orgcc4fd4a2012-07-04 16:10:45 +00001258 int nodeId = m_domAgent->boundNodeId(node);
1259 if (nodeId)
1260 m_nodeIdToForcedPseudoState.remove(nodeId);
pfeldman@chromium.orgefb43862011-08-16 17:15:06 +00001261
apavlov@chromium.org8d79d7f2010-10-07 09:53:40 +00001262 NodeToInspectorStyleSheet::iterator it = m_nodeToInspectorStyleSheet.find(node);
1263 if (it == m_nodeToInspectorStyleSheet.end())
1264 return;
1265
benjamin@webkit.orgee554052012-10-07 23:12:07 +00001266 m_idToInspectorStyleSheet.remove(it->value->id());
apavlov@chromium.org8d79d7f2010-10-07 09:53:40 +00001267 m_nodeToInspectorStyleSheet.remove(node);
1268}
1269
apavlov@chromium.org93e800a2010-12-24 16:39:32 +00001270void InspectorCSSAgent::didModifyDOMAttr(Element* element)
1271{
1272 if (!element)
1273 return;
1274
1275 NodeToInspectorStyleSheet::iterator it = m_nodeToInspectorStyleSheet.find(element);
1276 if (it == m_nodeToInspectorStyleSheet.end())
1277 return;
1278
benjamin@webkit.orgee554052012-10-07 23:12:07 +00001279 it->value->didModifyElementAttribute();
apavlov@chromium.org93e800a2010-12-24 16:39:32 +00001280}
1281
pfeldman@chromium.orga1a70a42012-02-14 08:50:19 +00001282void InspectorCSSAgent::styleSheetChanged(InspectorStyleSheet* styleSheet)
1283{
joepeck@webkit.org20fd4482013-11-13 22:58:16 +00001284 if (m_frontendDispatcher)
1285 m_frontendDispatcher->styleSheetChanged(styleSheet->id());
pfeldman@chromium.orga1a70a42012-02-14 08:50:19 +00001286}
1287
apavlov@chromium.orgcc4fd4a2012-07-04 16:10:45 +00001288void InspectorCSSAgent::resetPseudoStates()
pfeldman@chromium.orgefb43862011-08-16 17:15:06 +00001289{
apavlov@chromium.orgcc4fd4a2012-07-04 16:10:45 +00001290 HashSet<Document*> documentsToChange;
1291 for (NodeIdToForcedPseudoState::iterator it = m_nodeIdToForcedPseudoState.begin(), end = m_nodeIdToForcedPseudoState.end(); it != end; ++it) {
akling@apple.com622b1a42013-08-30 14:30:12 +00001292 if (Element* element = toElement(m_domAgent->nodeForId(it->key)))
1293 documentsToChange.add(&element->document());
pfeldman@chromium.orgefb43862011-08-16 17:15:06 +00001294 }
apavlov@chromium.orgcc4fd4a2012-07-04 16:10:45 +00001295
1296 m_nodeIdToForcedPseudoState.clear();
1297 for (HashSet<Document*>::iterator it = documentsToChange.begin(), end = documentsToChange.end(); it != end; ++it)
1298 (*it)->styleResolverChanged(RecalcStyleImmediately);
pfeldman@chromium.orgefb43862011-08-16 17:15:06 +00001299}
1300
apavlov@chromium.org8d79d7f2010-10-07 09:53:40 +00001301} // namespace WebCore
1302
1303#endif // ENABLE(INSPECTOR)