/* * Copyright (C) 2010 Google Inc. All rights reserved. * Copyright (C) 2015 Apple 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 "CSSSelector.h" #include "ContentSecurityPolicy.h" #include "InspectorDOMAgent.h" #include "InspectorStyleSheet.h" #include "InspectorWebAgentBase.h" #include "SecurityContext.h" #include #include #include #include #include #include namespace Inspector { class CSSFrontendDispatcher; } namespace WebCore { class CSSRule; class CSSStyleRule; class CSSStyleSheet; class ChangeRegionOversetTask; class Document; class Element; class Node; class NodeList; class StyleResolver; class StyleRule; class InspectorCSSAgent final : public InspectorAgentBase , public InspectorDOMAgent::DOMListener , public Inspector::CSSBackendDispatcherHandler , public InspectorStyleSheet::Listener { WTF_MAKE_NONCOPYABLE(InspectorCSSAgent); WTF_MAKE_FAST_ALLOCATED; public: class InlineStyleOverrideScope { public: InlineStyleOverrideScope(SecurityContext& context) : m_contentSecurityPolicy(context.contentSecurityPolicy()) { m_contentSecurityPolicy->setOverrideAllowInlineStyle(true); } ~InlineStyleOverrideScope() { m_contentSecurityPolicy->setOverrideAllowInlineStyle(false); } private: ContentSecurityPolicy* m_contentSecurityPolicy; }; InspectorCSSAgent(WebAgentContext&, InspectorDOMAgent*); virtual ~InspectorCSSAgent(); static CSSStyleRule* asCSSStyleRule(CSSRule&); virtual void didCreateFrontendAndBackend(Inspector::FrontendRouter*, Inspector::BackendDispatcher*) override; virtual void willDestroyFrontendAndBackend(Inspector::DisconnectReason) override; virtual void discardAgent() override; virtual void enable(ErrorString&) override; virtual void disable(ErrorString&) override; void regionOversetChanged(WebKitNamedFlow*, int documentNodeId); void reset(); // InspectorInstrumentation callbacks. void documentDetached(Document&); void mediaQueryResultChanged(); void activeStyleSheetsUpdated(Document&); void didCreateNamedFlow(Document&, WebKitNamedFlow&); void willRemoveNamedFlow(Document&, WebKitNamedFlow&); void didChangeRegionOverset(Document&, WebKitNamedFlow&); void didRegisterNamedFlowContentElement(Document&, WebKitNamedFlow&, Node& contentElement, Node* nextContentElement = nullptr); void didUnregisterNamedFlowContentElement(Document&, WebKitNamedFlow&, Node& contentElement); bool forcePseudoState(Element&, CSSSelector::PseudoClassType); virtual void getComputedStyleForNode(ErrorString&, int nodeId, RefPtr>&) override; virtual void getInlineStylesForNode(ErrorString&, int nodeId, RefPtr& inlineStyle, RefPtr& attributes) override; virtual void getMatchedStylesForNode(ErrorString&, int nodeId, const bool* includePseudo, const bool* includeInherited, RefPtr>& matchedCSSRules, RefPtr>& pseudoIdMatches, RefPtr>& inheritedEntries) override; virtual void getAllStyleSheets(ErrorString&, RefPtr>& styleSheetInfos) override; virtual void getStyleSheet(ErrorString&, const String& styleSheetId, RefPtr& result) override; virtual void getStyleSheetText(ErrorString&, const String& styleSheetId, String* result) override; virtual void setStyleSheetText(ErrorString&, const String& styleSheetId, const String& text) override; virtual void setStyleText(ErrorString&, const Inspector::InspectorObject& styleId, const String& text, RefPtr& result) override; virtual void setRuleSelector(ErrorString&, const Inspector::InspectorObject& ruleId, const String& selector, RefPtr& result) override; virtual void createStyleSheet(ErrorString&, const String& frameId, String* styleSheetId) override; virtual void addRule(ErrorString&, const String& styleSheetId, const String& selector, RefPtr& result) override; virtual void getSupportedCSSProperties(ErrorString&, RefPtr>& result) override; virtual void getSupportedSystemFontFamilyNames(ErrorString&, RefPtr>& result) override; virtual void forcePseudoState(ErrorString&, int nodeId, const Inspector::InspectorArray& forcedPseudoClasses) override; virtual void getNamedFlowCollection(ErrorString&, int documentNodeId, RefPtr>& result) override; private: class StyleSheetAction; class SetStyleSheetTextAction; class SetStyleTextAction; class SetRuleSelectorAction; class AddRuleAction; typedef HashMap> IdToInspectorStyleSheet; typedef HashMap> CSSStyleSheetToInspectorStyleSheet; typedef HashMap> NodeToInspectorStyleSheet; // bogus "stylesheets" with elements' inline styles typedef HashMap, Vector>> DocumentToViaInspectorStyleSheet; // "via inspector" stylesheets typedef HashMap NodeIdToForcedPseudoState; void resetNonPersistentData(); InspectorStyleSheetForInlineStyle* asInspectorStyleSheet(Element* element); Element* elementForId(ErrorString&, int nodeId); int documentNodeWithRequestedFlowsId(Document*); void collectAllStyleSheets(Vector&); void collectAllDocumentStyleSheets(Document&, Vector&); void collectStyleSheets(CSSStyleSheet*, Vector&); void setActiveStyleSheetsForDocument(Document&, Vector& activeStyleSheets); String unbindStyleSheet(InspectorStyleSheet*); InspectorStyleSheet* bindStyleSheet(CSSStyleSheet*); InspectorStyleSheet* assertStyleSheetForId(ErrorString&, const String&); InspectorStyleSheet* createInspectorStyleSheetForDocument(Document&); Inspector::Protocol::CSS::StyleSheetOrigin detectOrigin(CSSStyleSheet* pageStyleSheet, Document* ownerDocument); RefPtr buildObjectForRule(StyleRule*, StyleResolver&, Element*); RefPtr buildObjectForRule(CSSStyleRule*); RefPtr> buildArrayForMatchedRuleList(const Vector>&, StyleResolver&, Element*, PseudoId); RefPtr buildObjectForAttributesStyle(Element*); RefPtr> buildArrayForRegions(ErrorString&, RefPtr&&, int documentNodeId); RefPtr buildObjectForNamedFlow(ErrorString&, WebKitNamedFlow*, int documentNodeId); // InspectorDOMAgent::DOMListener implementation virtual void didRemoveDocument(Document*) override; virtual void didRemoveDOMNode(Node*) override; virtual void didModifyDOMAttr(Element*) override; // InspectorCSSAgent::Listener implementation virtual void styleSheetChanged(InspectorStyleSheet*) override; void resetPseudoStates(); std::unique_ptr m_frontendDispatcher; RefPtr m_backendDispatcher; InspectorDOMAgent* m_domAgent { nullptr }; IdToInspectorStyleSheet m_idToInspectorStyleSheet; CSSStyleSheetToInspectorStyleSheet m_cssStyleSheetToInspectorStyleSheet; NodeToInspectorStyleSheet m_nodeToInspectorStyleSheet; DocumentToViaInspectorStyleSheet m_documentToInspectorStyleSheet; HashMap> m_documentToKnownCSSStyleSheets; NodeIdToForcedPseudoState m_nodeIdToForcedPseudoState; HashSet m_namedFlowCollectionsRequested; std::unique_ptr m_changeRegionOversetTask; int m_lastStyleSheetId { 1 }; bool m_creatingViaInspectorStyleSheet { false }; }; } // namespace WebCore #endif // !defined(InspectorCSSAgent_h)