1/*
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#ifndef InspectorCSSAgent_h
26#define InspectorCSSAgent_h
27
28#include "CSSSelector.h"
29#include "ContentSecurityPolicy.h"
30#include "InspectorDOMAgent.h"
31#include "InspectorStyleSheet.h"
32#include "InspectorWebAgentBase.h"
33#include "InspectorWebBackendDispatchers.h"
34#include "SecurityContext.h"
35#include <inspector/InspectorValues.h>
36#include <wtf/HashMap.h>
37#include <wtf/HashSet.h>
38#include <wtf/PassRefPtr.h>
39#include <wtf/RefPtr.h>
40#include <wtf/text/WTFString.h>
41
42namespace Inspector {
43class InspectorCSSFrontendDispatcher;
44}
45
46namespace WebCore {
47
48class CSSRule;
49class CSSRuleList;
50class CSSStyleDeclaration;
51class CSSStyleRule;
52class CSSStyleSheet;
53class Document;
54class DocumentStyleSheetCollection;
55class Element;
56class InspectorCSSOMWrappers;
57class InstrumentingAgents;
58class NameNodeMap;
59class Node;
60class NodeList;
61class StyleResolver;
62class StyleRule;
63class ChangeRegionOversetTask;
64
65#if ENABLE(INSPECTOR)
66
67class InspectorCSSAgent
68    : public InspectorAgentBase
69    , public InspectorDOMAgent::DOMListener
70    , public Inspector::InspectorCSSBackendDispatcherHandler
71    , public InspectorStyleSheet::Listener {
72    WTF_MAKE_NONCOPYABLE(InspectorCSSAgent);
73    WTF_MAKE_FAST_ALLOCATED;
74public:
75    class InlineStyleOverrideScope {
76    public:
77        InlineStyleOverrideScope(SecurityContext* context)
78            : m_contentSecurityPolicy(context->contentSecurityPolicy())
79        {
80            m_contentSecurityPolicy->setOverrideAllowInlineStyle(true);
81        }
82
83        ~InlineStyleOverrideScope()
84        {
85            m_contentSecurityPolicy->setOverrideAllowInlineStyle(false);
86        }
87
88    private:
89        ContentSecurityPolicy* m_contentSecurityPolicy;
90    };
91
92    InspectorCSSAgent(InstrumentingAgents*, InspectorDOMAgent*);
93    ~InspectorCSSAgent();
94
95    static CSSStyleRule* asCSSStyleRule(CSSRule*);
96
97    bool forcePseudoState(Element*, CSSSelector::PseudoClassType);
98    virtual void didCreateFrontendAndBackend(Inspector::InspectorFrontendChannel*, Inspector::InspectorBackendDispatcher*) override;
99    virtual void willDestroyFrontendAndBackend(Inspector::InspectorDisconnectReason) override;
100    virtual void discardAgent() override;
101    virtual void enable(ErrorString*) override;
102    virtual void disable(ErrorString*) override;
103    void reset();
104    void mediaQueryResultChanged();
105    void didCreateNamedFlow(Document*, WebKitNamedFlow*);
106    void willRemoveNamedFlow(Document*, WebKitNamedFlow*);
107    void didChangeRegionOverset(Document*, WebKitNamedFlow*);
108    void regionOversetChanged(WebKitNamedFlow*, int documentNodeId);
109    void didRegisterNamedFlowContentElement(Document*, WebKitNamedFlow*, Node* contentElement, Node* nextContentElement = nullptr);
110    void didUnregisterNamedFlowContentElement(Document*, WebKitNamedFlow*, Node* contentElement);
111
112    virtual void getComputedStyleForNode(ErrorString*, int nodeId, RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::CSSComputedStyleProperty>>&) override;
113    virtual void getInlineStylesForNode(ErrorString*, int nodeId, RefPtr<Inspector::TypeBuilder::CSS::CSSStyle>& inlineStyle, RefPtr<Inspector::TypeBuilder::CSS::CSSStyle>& attributes) override;
114    virtual void getMatchedStylesForNode(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) override;
115    virtual void getAllStyleSheets(ErrorString*, RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::CSSStyleSheetHeader>>& styleSheetInfos) override;
116    virtual void getStyleSheet(ErrorString*, const String& styleSheetId, RefPtr<Inspector::TypeBuilder::CSS::CSSStyleSheetBody>& result) override;
117    virtual void getStyleSheetText(ErrorString*, const String& styleSheetId, String* result) override;
118    virtual void setStyleSheetText(ErrorString*, const String& styleSheetId, const String& text) override;
119    virtual void setStyleText(ErrorString*, const RefPtr<Inspector::InspectorObject>& styleId, const String& text, RefPtr<Inspector::TypeBuilder::CSS::CSSStyle>& result) override;
120    virtual void setPropertyText(ErrorString*, const RefPtr<Inspector::InspectorObject>& styleId, int propertyIndex, const String& text, bool overwrite, RefPtr<Inspector::TypeBuilder::CSS::CSSStyle>& result) override;
121    virtual void toggleProperty(ErrorString*, const RefPtr<Inspector::InspectorObject>& styleId, int propertyIndex, bool disable, RefPtr<Inspector::TypeBuilder::CSS::CSSStyle>& result) override;
122    virtual void setRuleSelector(ErrorString*, const RefPtr<Inspector::InspectorObject>& ruleId, const String& selector, RefPtr<Inspector::TypeBuilder::CSS::CSSRule>& result) override;
123    virtual void addRule(ErrorString*, int contextNodeId, const String& selector, RefPtr<Inspector::TypeBuilder::CSS::CSSRule>& result) override;
124    virtual void getSupportedCSSProperties(ErrorString*, RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::CSSPropertyInfo>>& result) override;
125    virtual void forcePseudoState(ErrorString*, int nodeId, const RefPtr<Inspector::InspectorArray>& forcedPseudoClasses) override;
126    virtual void getNamedFlowCollection(ErrorString*, int documentNodeId, RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::NamedFlow>>& result) override;
127
128private:
129    class StyleSheetAction;
130    class SetStyleSheetTextAction;
131    class SetStyleTextAction;
132    class SetPropertyTextAction;
133    class TogglePropertyAction;
134    class SetRuleSelectorAction;
135    class AddRuleAction;
136
137    typedef HashMap<String, RefPtr<InspectorStyleSheet>> IdToInspectorStyleSheet;
138    typedef HashMap<CSSStyleSheet*, RefPtr<InspectorStyleSheet>> CSSStyleSheetToInspectorStyleSheet;
139    typedef HashMap<Node*, RefPtr<InspectorStyleSheetForInlineStyle>> NodeToInspectorStyleSheet; // bogus "stylesheets" with elements' inline styles
140    typedef HashMap<RefPtr<Document>, RefPtr<InspectorStyleSheet>> DocumentToViaInspectorStyleSheet; // "via inspector" stylesheets
141    typedef HashMap<int, unsigned> NodeIdToForcedPseudoState;
142
143    void resetNonPersistentData();
144    InspectorStyleSheetForInlineStyle* asInspectorStyleSheet(Element* element);
145    Element* elementForId(ErrorString*, int nodeId);
146    int documentNodeWithRequestedFlowsId(Document*);
147    void collectStyleSheets(CSSStyleSheet*, Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::CSSStyleSheetHeader>*);
148
149    InspectorStyleSheet* bindStyleSheet(CSSStyleSheet*);
150    InspectorStyleSheet* viaInspectorStyleSheet(Document*, bool createIfAbsent);
151    InspectorStyleSheet* assertStyleSheetForId(ErrorString*, const String&);
152    Inspector::TypeBuilder::CSS::StyleSheetOrigin::Enum detectOrigin(CSSStyleSheet* pageStyleSheet, Document* ownerDocument);
153
154    PassRefPtr<Inspector::TypeBuilder::CSS::CSSRule> buildObjectForRule(StyleRule*, StyleResolver&);
155    PassRefPtr<Inspector::TypeBuilder::CSS::CSSRule> buildObjectForRule(CSSStyleRule*);
156    PassRefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::CSSRule>> buildArrayForRuleList(CSSRuleList*);
157    PassRefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::RuleMatch>> buildArrayForMatchedRuleList(const Vector<RefPtr<StyleRule>>&, StyleResolver&, Element*);
158    PassRefPtr<Inspector::TypeBuilder::CSS::CSSStyle> buildObjectForAttributesStyle(Element*);
159    PassRefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::Region>> buildArrayForRegions(ErrorString*, PassRefPtr<NodeList>, int documentNodeId);
160    PassRefPtr<Inspector::TypeBuilder::CSS::NamedFlow> buildObjectForNamedFlow(ErrorString*, WebKitNamedFlow*, int documentNodeId);
161
162    // InspectorDOMAgent::DOMListener implementation
163    virtual void didRemoveDocument(Document*) override;
164    virtual void didRemoveDOMNode(Node*) override;
165    virtual void didModifyDOMAttr(Element*) override;
166
167    // InspectorCSSAgent::Listener implementation
168    virtual void styleSheetChanged(InspectorStyleSheet*) override;
169
170    void resetPseudoStates();
171
172    std::unique_ptr<Inspector::InspectorCSSFrontendDispatcher> m_frontendDispatcher;
173    RefPtr<Inspector::InspectorCSSBackendDispatcher> m_backendDispatcher;
174    InspectorDOMAgent* m_domAgent;
175
176    IdToInspectorStyleSheet m_idToInspectorStyleSheet;
177    CSSStyleSheetToInspectorStyleSheet m_cssStyleSheetToInspectorStyleSheet;
178    NodeToInspectorStyleSheet m_nodeToInspectorStyleSheet;
179    DocumentToViaInspectorStyleSheet m_documentToInspectorStyleSheet;
180    NodeIdToForcedPseudoState m_nodeIdToForcedPseudoState;
181    HashSet<int> m_namedFlowCollectionsRequested;
182    std::unique_ptr<ChangeRegionOversetTask> m_changeRegionOversetTask;
183
184    int m_lastStyleSheetId;
185};
186
187#endif
188
189} // namespace WebCore
190
191#endif // !defined(InspectorCSSAgent_h)
192