blob: caf1477186dd15ce7883a29d289ffa05fbdef359 [file] [log] [blame]
/*
* Copyright (C) 2010, Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*/
#ifndef InspectorCSSAgent_h
#define InspectorCSSAgent_h
#include "core/CoreExport.h"
#include "core/css/CSSSelector.h"
#include "core/dom/SecurityContext.h"
#include "core/frame/csp/ContentSecurityPolicy.h"
#include "core/inspector/InspectorBaseAgent.h"
#include "core/inspector/InspectorDOMAgent.h"
#include "core/inspector/InspectorStyleSheet.h"
#include "core/inspector/protocol/CSS.h"
#include "wtf/HashCountedSet.h"
#include "wtf/HashMap.h"
#include "wtf/HashSet.h"
#include "wtf/PassRefPtr.h"
#include "wtf/RefPtr.h"
#include "wtf/Vector.h"
#include "wtf/text/WTFString.h"
namespace blink {
class CSSKeyframeRule;
class CSSRule;
class CSSRuleList;
class CSSStyleRule;
class CSSStyleSheet;
class Document;
class Element;
class InspectedFrames;
class InspectorNetworkAgent;
class InspectorResourceContainer;
class InspectorResourceContentLoader;
class MediaList;
class Node;
class LayoutObject;
class CORE_EXPORT InspectorCSSAgent final
: public InspectorBaseAgent<protocol::CSS::Metainfo>,
public InspectorDOMAgent::DOMListener,
public InspectorStyleSheetBase::Listener {
WTF_MAKE_NONCOPYABLE(InspectorCSSAgent);
USING_GARBAGE_COLLECTED_MIXIN(InspectorCSSAgent);
public:
enum MediaListSource {
MediaListSourceLinkedSheet,
MediaListSourceInlineSheet,
MediaListSourceMediaRule,
MediaListSourceImportRule
};
enum StyleSheetsUpdateType {
InitialFrontendLoad = 0,
ExistingFrontendRefresh,
};
class InlineStyleOverrideScope {
STACK_ALLOCATED();
public:
InlineStyleOverrideScope(SecurityContext* context)
: m_contentSecurityPolicy(context->contentSecurityPolicy()) {
m_contentSecurityPolicy->setOverrideAllowInlineStyle(true);
}
~InlineStyleOverrideScope() {
m_contentSecurityPolicy->setOverrideAllowInlineStyle(false);
}
private:
Member<ContentSecurityPolicy> m_contentSecurityPolicy;
};
static CSSStyleRule* asCSSStyleRule(CSSRule*);
static CSSMediaRule* asCSSMediaRule(CSSRule*);
static InspectorCSSAgent* create(
InspectorDOMAgent* domAgent,
InspectedFrames* inspectedFrames,
InspectorNetworkAgent* networkAgent,
InspectorResourceContentLoader* resourceContentLoader,
InspectorResourceContainer* resourceContainer) {
return new InspectorCSSAgent(domAgent, inspectedFrames, networkAgent,
resourceContentLoader, resourceContainer);
}
static void collectAllDocumentStyleSheets(Document*,
HeapVector<Member<CSSStyleSheet>>&);
~InspectorCSSAgent() override;
DECLARE_VIRTUAL_TRACE();
bool forcePseudoState(Element*, CSSSelector::PseudoType);
void didCommitLoadForLocalFrame(LocalFrame*) override;
void restore() override;
void flushPendingProtocolNotifications() override;
void reset();
void mediaQueryResultChanged();
void activeStyleSheetsUpdated(Document*);
void documentDetached(Document*);
void fontsUpdated();
void enable(std::unique_ptr<EnableCallback>) override;
void disable(ErrorString*) override;
void getMatchedStylesForNode(
ErrorString*,
int nodeId,
Maybe<protocol::CSS::CSSStyle>* inlineStyle,
Maybe<protocol::CSS::CSSStyle>* attributesStyle,
Maybe<protocol::Array<protocol::CSS::RuleMatch>>* matchedCSSRules,
Maybe<protocol::Array<protocol::CSS::PseudoElementMatches>>*,
Maybe<protocol::Array<protocol::CSS::InheritedStyleEntry>>*,
Maybe<protocol::Array<protocol::CSS::CSSKeyframesRule>>*) override;
void getInlineStylesForNode(
ErrorString*,
int nodeId,
Maybe<protocol::CSS::CSSStyle>* inlineStyle,
Maybe<protocol::CSS::CSSStyle>* attributesStyle) override;
void getComputedStyleForNode(
ErrorString*,
int nodeId,
std::unique_ptr<
protocol::Array<protocol::CSS::CSSComputedStyleProperty>>*) override;
void getPlatformFontsForNode(
ErrorString*,
int nodeId,
std::unique_ptr<protocol::Array<protocol::CSS::PlatformFontUsage>>* fonts)
override;
void collectClassNames(
ErrorString*,
const String& styleSheetId,
std::unique_ptr<protocol::Array<String>>* classNames) override;
void getStyleSheetText(ErrorString*,
const String& styleSheetId,
String* text) override;
void setStyleSheetText(ErrorString*,
const String& styleSheetId,
const String& text,
Maybe<String>* sourceMapURL) override;
void setRuleSelector(ErrorString*,
const String& styleSheetId,
std::unique_ptr<protocol::CSS::SourceRange>,
const String& selector,
std::unique_ptr<protocol::CSS::SelectorList>*) override;
void setKeyframeKey(
ErrorString*,
const String& styleSheetId,
std::unique_ptr<protocol::CSS::SourceRange>,
const String& keyText,
std::unique_ptr<protocol::CSS::Value>* outKeyText) override;
void setStyleTexts(
ErrorString*,
std::unique_ptr<protocol::Array<protocol::CSS::StyleDeclarationEdit>>
edits,
std::unique_ptr<protocol::Array<protocol::CSS::CSSStyle>>* styles)
override;
void setMediaText(ErrorString*,
const String& styleSheetId,
std::unique_ptr<protocol::CSS::SourceRange>,
const String& text,
std::unique_ptr<protocol::CSS::CSSMedia>*) override;
void createStyleSheet(ErrorString*,
const String& frameId,
String* styleSheetId) override;
void addRule(ErrorString*,
const String& styleSheetId,
const String& ruleText,
std::unique_ptr<protocol::CSS::SourceRange>,
std::unique_ptr<protocol::CSS::CSSRule>*) override;
void forcePseudoState(
ErrorString*,
int nodeId,
std::unique_ptr<protocol::Array<String>> forcedPseudoClasses) override;
void getMediaQueries(
ErrorString*,
std::unique_ptr<protocol::Array<protocol::CSS::CSSMedia>>*) override;
void setEffectivePropertyValueForNode(ErrorString*,
int nodeId,
const String& propertyName,
const String& value) override;
void getBackgroundColors(
ErrorString*,
int nodeId,
Maybe<protocol::Array<String>>* backgroundColors) override;
void collectMediaQueriesFromRule(CSSRule*,
protocol::Array<protocol::CSS::CSSMedia>*);
void collectMediaQueriesFromStyleSheet(
CSSStyleSheet*,
protocol::Array<protocol::CSS::CSSMedia>*);
std::unique_ptr<protocol::CSS::CSSMedia> buildMediaObject(const MediaList*,
MediaListSource,
const String&,
CSSStyleSheet*);
std::unique_ptr<protocol::Array<protocol::CSS::CSSMedia>> buildMediaListChain(
CSSRule*);
CSSStyleDeclaration* findEffectiveDeclaration(
CSSPropertyID,
const HeapVector<Member<CSSStyleDeclaration>>& styles);
void setLayoutEditorValue(ErrorString*,
Element*,
CSSStyleDeclaration*,
CSSPropertyID,
const String& value,
bool forceImportant = false);
void layoutEditorItemSelected(Element*, CSSStyleDeclaration*);
void getLayoutTreeAndStyles(
ErrorString*,
std::unique_ptr<protocol::Array<String>> styleWhitelist,
std::unique_ptr<protocol::Array<protocol::CSS::LayoutTreeNode>>*
layoutTreeNodes,
std::unique_ptr<protocol::Array<protocol::CSS::ComputedStyle>>*
computedStyles) override;
HeapVector<Member<CSSStyleDeclaration>> matchingStyles(Element*);
String styleSheetId(CSSStyleSheet*);
private:
class StyleSheetAction;
class SetStyleSheetTextAction;
class ModifyRuleAction;
class SetElementStyleAction;
class AddRuleAction;
static void collectStyleSheets(CSSStyleSheet*,
HeapVector<Member<CSSStyleSheet>>&);
InspectorCSSAgent(InspectorDOMAgent*,
InspectedFrames*,
InspectorNetworkAgent*,
InspectorResourceContentLoader*,
InspectorResourceContainer*);
typedef HeapHashMap<String, Member<InspectorStyleSheet>>
IdToInspectorStyleSheet;
typedef HeapHashMap<String, Member<InspectorStyleSheetForInlineStyle>>
IdToInspectorStyleSheetForInlineStyle;
typedef HeapHashMap<Member<Node>, Member<InspectorStyleSheetForInlineStyle>>
NodeToInspectorStyleSheet; // bogus "stylesheets" with elements' inline
// styles
typedef HashMap<int, unsigned> NodeIdToForcedPseudoState;
void resourceContentLoaded(std::unique_ptr<EnableCallback>);
void wasEnabled();
void resetNonPersistentData();
InspectorStyleSheetForInlineStyle* asInspectorStyleSheet(Element* element);
Element* elementForId(ErrorString*, int nodeId);
void updateActiveStyleSheets(Document*, StyleSheetsUpdateType);
void setActiveStyleSheets(Document*,
const HeapVector<Member<CSSStyleSheet>>&,
StyleSheetsUpdateType);
CSSStyleDeclaration* setStyleText(ErrorString*,
InspectorStyleSheetBase*,
const SourceRange&,
const String&);
bool multipleStyleTextsActions(
ErrorString*,
std::unique_ptr<protocol::Array<protocol::CSS::StyleDeclarationEdit>>,
HeapVector<Member<StyleSheetAction>>* actions);
std::unique_ptr<protocol::Array<protocol::CSS::CSSKeyframesRule>>
animationsForNode(Element*);
void collectPlatformFontsForLayoutObject(
LayoutObject*,
HashCountedSet<std::pair<int, String>>*);
InspectorStyleSheet* bindStyleSheet(CSSStyleSheet*);
String unbindStyleSheet(InspectorStyleSheet*);
InspectorStyleSheet* inspectorStyleSheetForRule(CSSStyleRule*);
InspectorStyleSheet* viaInspectorStyleSheet(Document*);
InspectorStyleSheet* assertInspectorStyleSheetForId(ErrorString*,
const String&);
InspectorStyleSheetBase* assertStyleSheetForId(ErrorString*, const String&);
String detectOrigin(CSSStyleSheet* pageStyleSheet, Document* ownerDocument);
std::unique_ptr<protocol::CSS::CSSRule> buildObjectForRule(CSSStyleRule*);
std::unique_ptr<protocol::Array<protocol::CSS::RuleMatch>>
buildArrayForMatchedRuleList(CSSRuleList*, Element*, PseudoId);
std::unique_ptr<protocol::CSS::CSSStyle> buildObjectForAttributesStyle(
Element*);
// InspectorDOMAgent::DOMListener implementation
void didRemoveDocument(Document*) override;
void didRemoveDOMNode(Node*) override;
void didModifyDOMAttr(Element*) override;
// InspectorStyleSheet::Listener implementation
void styleSheetChanged(InspectorStyleSheetBase*) override;
void resetPseudoStates();
struct VectorStringHashTraits;
using ComputedStylesMap = WTF::HashMap<Vector<String>,
int,
VectorStringHashTraits,
VectorStringHashTraits>;
void visitLayoutTreeNodes(
Node*,
protocol::Array<protocol::CSS::LayoutTreeNode>& layoutTreeNodes,
const Vector<std::pair<String, CSSPropertyID>>& cssPropertyWhitelist,
ComputedStylesMap& styleToIndexMap,
protocol::Array<protocol::CSS::ComputedStyle>& computedStyles);
int getStyleIndexForNode(
Node*,
const Vector<std::pair<String, CSSPropertyID>>& cssPropertyWhitelist,
ComputedStylesMap& styleToIndexMap,
protocol::Array<protocol::CSS::ComputedStyle>& computedStyles);
Member<InspectorDOMAgent> m_domAgent;
Member<InspectedFrames> m_inspectedFrames;
Member<InspectorNetworkAgent> m_networkAgent;
Member<InspectorResourceContentLoader> m_resourceContentLoader;
Member<InspectorResourceContainer> m_resourceContainer;
IdToInspectorStyleSheet m_idToInspectorStyleSheet;
IdToInspectorStyleSheetForInlineStyle m_idToInspectorStyleSheetForInlineStyle;
HeapHashMap<Member<CSSStyleSheet>, Member<InspectorStyleSheet>>
m_cssStyleSheetToInspectorStyleSheet;
typedef HeapHashMap<Member<Document>,
Member<HeapHashSet<Member<CSSStyleSheet>>>>
DocumentStyleSheets;
DocumentStyleSheets m_documentToCSSStyleSheets;
HeapHashSet<Member<Document>> m_invalidatedDocuments;
NodeToInspectorStyleSheet m_nodeToInspectorStyleSheet;
NodeIdToForcedPseudoState m_nodeIdToForcedPseudoState;
Member<CSSStyleSheet> m_inspectorUserAgentStyleSheet;
int m_resourceContentLoaderClientId;
friend class InspectorResourceContentLoaderCallback;
friend class StyleSheetBinder;
};
} // namespace blink
#endif // !defined(InspectorCSSAgent_h)