diff options
Diffstat (limited to 'Source/WebCore/inspector/InspectorCSSAgent.cpp')
-rw-r--r-- | Source/WebCore/inspector/InspectorCSSAgent.cpp | 1187 |
1 files changed, 539 insertions, 648 deletions
diff --git a/Source/WebCore/inspector/InspectorCSSAgent.cpp b/Source/WebCore/inspector/InspectorCSSAgent.cpp index 01a52da32..1a6c76803 100644 --- a/Source/WebCore/inspector/InspectorCSSAgent.cpp +++ b/Source/WebCore/inspector/InspectorCSSAgent.cpp @@ -1,5 +1,6 @@ /* - * Copyright (C) 2010, Google Inc. All rights reserved. + * 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 @@ -23,9 +24,6 @@ */ #include "config.h" - -#if ENABLE(INSPECTOR) - #include "InspectorCSSAgent.h" #include "CSSComputedStyleDeclaration.h" @@ -38,27 +36,28 @@ #include "CSSStyleSheet.h" #include "ContentSecurityPolicy.h" #include "DOMWindow.h" -#include "ExceptionCodePlaceholder.h" +#include "FontCache.h" #include "HTMLHeadElement.h" #include "HTMLStyleElement.h" -#include "InspectorDOMAgent.h" #include "InspectorHistory.h" -#include "InspectorWebTypeBuilders.h" +#include "InspectorPageAgent.h" #include "InstrumentingAgents.h" #include "NamedFlowCollection.h" #include "Node.h" #include "NodeList.h" -#include "RenderRegion.h" +#include "PseudoElement.h" +#include "RenderNamedFlowFragment.h" #include "SVGStyleElement.h" +#include "SelectorChecker.h" +#include "ShadowRoot.h" #include "StyleProperties.h" #include "StylePropertyShorthand.h" #include "StyleResolver.h" #include "StyleRule.h" +#include "StyleScope.h" #include "StyleSheetList.h" #include "WebKitNamedFlow.h" -#include <inspector/InspectorValues.h> -#include <wtf/CurrentTime.h> -#include <wtf/HashSet.h> +#include <inspector/InspectorProtocolObjects.h> #include <wtf/Ref.h> #include <wtf/Vector.h> #include <wtf/text/CString.h> @@ -69,127 +68,65 @@ using namespace Inspector; namespace WebCore { enum ForcePseudoClassFlags { - PseudoNone = 0, - PseudoHover = 1 << 0, - PseudoFocus = 1 << 1, - PseudoActive = 1 << 2, - PseudoVisited = 1 << 3 + PseudoClassNone = 0, + PseudoClassHover = 1 << 0, + PseudoClassFocus = 1 << 1, + PseudoClassActive = 1 << 2, + PseudoClassVisited = 1 << 3 }; -static unsigned computePseudoClassMask(InspectorArray* pseudoClassArray) +static unsigned computePseudoClassMask(const InspectorArray& pseudoClassArray) { - DEFINE_STATIC_LOCAL(String, active, (ASCIILiteral("active"))); - DEFINE_STATIC_LOCAL(String, hover, (ASCIILiteral("hover"))); - DEFINE_STATIC_LOCAL(String, focus, (ASCIILiteral("focus"))); - DEFINE_STATIC_LOCAL(String, visited, (ASCIILiteral("visited"))); - if (!pseudoClassArray || !pseudoClassArray->length()) - return PseudoNone; - - unsigned result = PseudoNone; - for (size_t i = 0; i < pseudoClassArray->length(); ++i) { - RefPtr<InspectorValue> pseudoClassValue = pseudoClassArray->get(i); + static NeverDestroyed<String> active(ASCIILiteral("active")); + static NeverDestroyed<String> hover(ASCIILiteral("hover")); + static NeverDestroyed<String> focus(ASCIILiteral("focus")); + static NeverDestroyed<String> visited(ASCIILiteral("visited")); + if (!pseudoClassArray.length()) + return PseudoClassNone; + + unsigned result = PseudoClassNone; + for (auto& pseudoClassValue : pseudoClassArray) { String pseudoClass; - bool success = pseudoClassValue->asString(&pseudoClass); + bool success = pseudoClassValue->asString(pseudoClass); if (!success) continue; if (pseudoClass == active) - result |= PseudoActive; + result |= PseudoClassActive; else if (pseudoClass == hover) - result |= PseudoHover; + result |= PseudoClassHover; else if (pseudoClass == focus) - result |= PseudoFocus; + result |= PseudoClassFocus; else if (pseudoClass == visited) - result |= PseudoVisited; + result |= PseudoClassVisited; } return result; } -class UpdateRegionLayoutTask { -public: - UpdateRegionLayoutTask(InspectorCSSAgent*); - void scheduleFor(WebKitNamedFlow*, int documentNodeId); - void unschedule(WebKitNamedFlow*); - void reset(); - void timerFired(Timer<UpdateRegionLayoutTask>&); - -private: - InspectorCSSAgent* m_cssAgent; - Timer<UpdateRegionLayoutTask> m_timer; - HashMap<WebKitNamedFlow*, int> m_namedFlows; -}; - -UpdateRegionLayoutTask::UpdateRegionLayoutTask(InspectorCSSAgent* cssAgent) - : m_cssAgent(cssAgent) - , m_timer(this, &UpdateRegionLayoutTask::timerFired) -{ -} - -void UpdateRegionLayoutTask::scheduleFor(WebKitNamedFlow* namedFlow, int documentNodeId) -{ - m_namedFlows.add(namedFlow, documentNodeId); - - if (!m_timer.isActive()) - m_timer.startOneShot(0); -} - -void UpdateRegionLayoutTask::unschedule(WebKitNamedFlow* namedFlow) -{ - m_namedFlows.remove(namedFlow); -} - -void UpdateRegionLayoutTask::reset() -{ - m_timer.stop(); - m_namedFlows.clear(); -} - -void UpdateRegionLayoutTask::timerFired(Timer<UpdateRegionLayoutTask>&) -{ - // The timer is stopped on m_cssAgent destruction, so this method will never be called after m_cssAgent has been destroyed. - Vector<std::pair<WebKitNamedFlow*, int>> namedFlows; - - for (HashMap<WebKitNamedFlow*, int>::iterator it = m_namedFlows.begin(), end = m_namedFlows.end(); it != end; ++it) - namedFlows.append(std::make_pair(it->key, it->value)); - - for (unsigned i = 0, size = namedFlows.size(); i < size; ++i) { - WebKitNamedFlow* namedFlow = namedFlows.at(i).first; - int documentNodeId = namedFlows.at(i).second; - - if (m_namedFlows.contains(namedFlow)) { - m_cssAgent->regionLayoutUpdated(namedFlow, documentNodeId); - m_namedFlows.remove(namedFlow); - } - } - - if (!m_namedFlows.isEmpty() && !m_timer.isActive()) - m_timer.startOneShot(0); -} - class ChangeRegionOversetTask { public: ChangeRegionOversetTask(InspectorCSSAgent*); void scheduleFor(WebKitNamedFlow*, int documentNodeId); void unschedule(WebKitNamedFlow*); void reset(); - void timerFired(Timer<ChangeRegionOversetTask>&); - + void timerFired(); + private: InspectorCSSAgent* m_cssAgent; - Timer<ChangeRegionOversetTask> m_timer; + Timer m_timer; HashMap<WebKitNamedFlow*, int> m_namedFlows; }; ChangeRegionOversetTask::ChangeRegionOversetTask(InspectorCSSAgent* cssAgent) : m_cssAgent(cssAgent) - , m_timer(this, &ChangeRegionOversetTask::timerFired) + , m_timer(*this, &ChangeRegionOversetTask::timerFired) { } void ChangeRegionOversetTask::scheduleFor(WebKitNamedFlow* namedFlow, int documentNodeId) { m_namedFlows.add(namedFlow, documentNodeId); - + if (!m_timer.isActive()) m_timer.startOneShot(0); } @@ -205,11 +142,11 @@ void ChangeRegionOversetTask::reset() m_namedFlows.clear(); } -void ChangeRegionOversetTask::timerFired(Timer<ChangeRegionOversetTask>&) +void ChangeRegionOversetTask::timerFired() { // The timer is stopped on m_cssAgent destruction, so this method will never be called after m_cssAgent has been destroyed. - for (HashMap<WebKitNamedFlow*, int>::iterator it = m_namedFlows.begin(), end = m_namedFlows.end(); it != end; ++it) - m_cssAgent->regionOversetChanged(it->key, it->value); + for (auto& namedFlow : m_namedFlows) + m_cssAgent->regionOversetChanged(namedFlow.key, namedFlow.value); m_namedFlows.clear(); } @@ -227,59 +164,59 @@ protected: RefPtr<InspectorStyleSheet> m_styleSheet; }; -class InspectorCSSAgent::SetStyleSheetTextAction : public InspectorCSSAgent::StyleSheetAction { +class InspectorCSSAgent::SetStyleSheetTextAction final : public InspectorCSSAgent::StyleSheetAction { WTF_MAKE_NONCOPYABLE(SetStyleSheetTextAction); public: SetStyleSheetTextAction(InspectorStyleSheet* styleSheet, const String& text) - : InspectorCSSAgent::StyleSheetAction("SetStyleSheetText", styleSheet) + : InspectorCSSAgent::StyleSheetAction(ASCIILiteral("SetStyleSheetText"), styleSheet) , m_text(text) { } - virtual bool perform(ExceptionCode& ec) +private: + ExceptionOr<void> perform() final { - if (!m_styleSheet->getText(&m_oldText)) - return false; - return redo(ec); + auto result = m_styleSheet->text(); + if (result.hasException()) + return result.releaseException(); + m_oldText = result.releaseReturnValue(); + return redo(); } - virtual bool undo(ExceptionCode& ec) + ExceptionOr<void> undo() final { - if (m_styleSheet->setText(m_oldText, ec)) { - m_styleSheet->reparseStyleSheet(m_oldText); - return true; - } - return false; + auto result = m_styleSheet->setText(m_oldText); + if (result.hasException()) + return result.releaseException(); + m_styleSheet->reparseStyleSheet(m_oldText); + return { }; } - virtual bool redo(ExceptionCode& ec) + ExceptionOr<void> redo() final { - if (m_styleSheet->setText(m_text, ec)) { - m_styleSheet->reparseStyleSheet(m_text); - return true; - } - return false; + auto result = m_styleSheet->setText(m_text); + if (result.hasException()) + return result.releaseException(); + m_styleSheet->reparseStyleSheet(m_text); + return { }; } - virtual String mergeId() + String mergeId() final { return String::format("SetStyleSheetText %s", m_styleSheet->id().utf8().data()); } - virtual void merge(PassOwnPtr<Action> action) + void merge(std::unique_ptr<Action> action) override { ASSERT(action->mergeId() == mergeId()); - - SetStyleSheetTextAction* other = static_cast<SetStyleSheetTextAction*>(action.get()); - m_text = other->m_text; + m_text = static_cast<SetStyleSheetTextAction&>(*action).m_text; } -private: String m_text; String m_oldText; }; -class InspectorCSSAgent::SetStyleTextAction : public InspectorCSSAgent::StyleSheetAction { +class InspectorCSSAgent::SetStyleTextAction final : public InspectorCSSAgent::StyleSheetAction { WTF_MAKE_NONCOPYABLE(SetStyleTextAction); public: SetStyleTextAction(InspectorStyleSheet* styleSheet, const InspectorCSSId& cssId, const String& text) @@ -289,28 +226,28 @@ public: { } - virtual bool perform(ExceptionCode& ec) + ExceptionOr<void> perform() override { - return redo(ec); + return redo(); } - virtual bool undo(ExceptionCode& ec) + ExceptionOr<void> undo() override { - return m_styleSheet->setStyleText(m_cssId, m_oldText, 0, ec); + return m_styleSheet->setStyleText(m_cssId, m_oldText, nullptr); } - virtual bool redo(ExceptionCode& ec) + ExceptionOr<void> redo() override { - return m_styleSheet->setStyleText(m_cssId, m_text, &m_oldText, ec); + return m_styleSheet->setStyleText(m_cssId, m_text, &m_oldText); } - virtual String mergeId() + String mergeId() override { ASSERT(m_styleSheet->id() == m_cssId.styleSheetId()); return String::format("SetStyleText %s:%u", m_styleSheet->id().utf8().data(), m_cssId.ordinal()); } - virtual void merge(PassOwnPtr<Action> action) + void merge(std::unique_ptr<Action> action) override { ASSERT(action->mergeId() == mergeId()); @@ -324,181 +261,89 @@ private: String m_oldText; }; -class InspectorCSSAgent::SetPropertyTextAction : public InspectorCSSAgent::StyleSheetAction { - WTF_MAKE_NONCOPYABLE(SetPropertyTextAction); -public: - SetPropertyTextAction(InspectorStyleSheet* styleSheet, const InspectorCSSId& cssId, unsigned propertyIndex, const String& text, bool overwrite) - : InspectorCSSAgent::StyleSheetAction("SetPropertyText", styleSheet) - , m_cssId(cssId) - , m_propertyIndex(propertyIndex) - , m_text(text) - , m_overwrite(overwrite) - { - } - - virtual String toString() - { - return mergeId() + ": " + m_oldText + " -> " + m_text; - } - - virtual bool perform(ExceptionCode& ec) - { - return redo(ec); - } - - virtual bool undo(ExceptionCode& ec) - { - String placeholder; - return m_styleSheet->setPropertyText(m_cssId, m_propertyIndex, m_overwrite ? m_oldText : "", true, &placeholder, ec); - } - - virtual bool redo(ExceptionCode& ec) - { - String oldText; - bool result = m_styleSheet->setPropertyText(m_cssId, m_propertyIndex, m_text, m_overwrite, &oldText, ec); - m_oldText = oldText.stripWhiteSpace(); - // FIXME: remove this once the model handles this case. - if (!m_oldText.endsWith(';')) - m_oldText.append(';'); - - return result; - } - - virtual String mergeId() - { - return String::format("SetPropertyText %s:%u:%s", m_styleSheet->id().utf8().data(), m_propertyIndex, m_overwrite ? "true" : "false"); - } - - virtual void merge(PassOwnPtr<Action> action) - { - ASSERT(action->mergeId() == mergeId()); - - SetPropertyTextAction* other = static_cast<SetPropertyTextAction*>(action.get()); - m_text = other->m_text; - } - -private: - InspectorCSSId m_cssId; - unsigned m_propertyIndex; - String m_text; - String m_oldText; - bool m_overwrite; -}; - -class InspectorCSSAgent::TogglePropertyAction : public InspectorCSSAgent::StyleSheetAction { - WTF_MAKE_NONCOPYABLE(TogglePropertyAction); -public: - TogglePropertyAction(InspectorStyleSheet* styleSheet, const InspectorCSSId& cssId, unsigned propertyIndex, bool disable) - : InspectorCSSAgent::StyleSheetAction("ToggleProperty", styleSheet) - , m_cssId(cssId) - , m_propertyIndex(propertyIndex) - , m_disable(disable) - { - } - - virtual bool perform(ExceptionCode& ec) - { - return redo(ec); - } - - virtual bool undo(ExceptionCode& ec) - { - return m_styleSheet->toggleProperty(m_cssId, m_propertyIndex, !m_disable, ec); - } - - virtual bool redo(ExceptionCode& ec) - { - return m_styleSheet->toggleProperty(m_cssId, m_propertyIndex, m_disable, ec); - } - -private: - InspectorCSSId m_cssId; - unsigned m_propertyIndex; - bool m_disable; -}; - -class InspectorCSSAgent::SetRuleSelectorAction : public InspectorCSSAgent::StyleSheetAction { +class InspectorCSSAgent::SetRuleSelectorAction final : public InspectorCSSAgent::StyleSheetAction { WTF_MAKE_NONCOPYABLE(SetRuleSelectorAction); public: SetRuleSelectorAction(InspectorStyleSheet* styleSheet, const InspectorCSSId& cssId, const String& selector) - : InspectorCSSAgent::StyleSheetAction("SetRuleSelector", styleSheet) + : InspectorCSSAgent::StyleSheetAction(ASCIILiteral("SetRuleSelector"), styleSheet) , m_cssId(cssId) , m_selector(selector) { } - virtual bool perform(ExceptionCode& ec) +private: + ExceptionOr<void> perform() final { - m_oldSelector = m_styleSheet->ruleSelector(m_cssId, ec); - if (ec) - return false; - return redo(ec); + auto result = m_styleSheet->ruleSelector(m_cssId); + if (result.hasException()) + return result.releaseException(); + m_oldSelector = result.releaseReturnValue(); + return redo(); } - virtual bool undo(ExceptionCode& ec) + ExceptionOr<void> undo() final { - return m_styleSheet->setRuleSelector(m_cssId, m_oldSelector, ec); + return m_styleSheet->setRuleSelector(m_cssId, m_oldSelector); } - virtual bool redo(ExceptionCode& ec) + ExceptionOr<void> redo() final { - return m_styleSheet->setRuleSelector(m_cssId, m_selector, ec); + return m_styleSheet->setRuleSelector(m_cssId, m_selector); } -private: InspectorCSSId m_cssId; String m_selector; String m_oldSelector; }; -class InspectorCSSAgent::AddRuleAction : public InspectorCSSAgent::StyleSheetAction { +class InspectorCSSAgent::AddRuleAction final : public InspectorCSSAgent::StyleSheetAction { WTF_MAKE_NONCOPYABLE(AddRuleAction); public: AddRuleAction(InspectorStyleSheet* styleSheet, const String& selector) - : InspectorCSSAgent::StyleSheetAction("AddRule", styleSheet) + : InspectorCSSAgent::StyleSheetAction(ASCIILiteral("AddRule"), styleSheet) , m_selector(selector) { } - virtual bool perform(ExceptionCode& ec) + InspectorCSSId newRuleId() const { return m_newId; } + +private: + ExceptionOr<void> perform() final { - return redo(ec); + return redo(); } - virtual bool undo(ExceptionCode& ec) + ExceptionOr<void> undo() final { - return m_styleSheet->deleteRule(m_newId, ec); + return m_styleSheet->deleteRule(m_newId); } - virtual bool redo(ExceptionCode& ec) + ExceptionOr<void> redo() final { - CSSStyleRule* cssStyleRule = m_styleSheet->addRule(m_selector, ec); - if (ec) - return false; - m_newId = m_styleSheet->ruleId(cssStyleRule); - return true; + auto result = m_styleSheet->addRule(m_selector); + if (result.hasException()) + return result.releaseException(); + m_newId = m_styleSheet->ruleId(result.releaseReturnValue()); + return { }; } - InspectorCSSId newRuleId() { return m_newId; } - -private: InspectorCSSId m_newId; String m_selector; String m_oldSelector; }; -// static -CSSStyleRule* InspectorCSSAgent::asCSSStyleRule(CSSRule* rule) +CSSStyleRule* InspectorCSSAgent::asCSSStyleRule(CSSRule& rule) { - if (rule->type() != CSSRule::STYLE_RULE) - return 0; - return static_cast<CSSStyleRule*>(rule); + if (!is<CSSStyleRule>(rule)) + return nullptr; + return downcast<CSSStyleRule>(&rule); } -InspectorCSSAgent::InspectorCSSAgent(InstrumentingAgents* instrumentingAgents, InspectorDOMAgent* domAgent) - : InspectorAgentBase(ASCIILiteral("CSS"), instrumentingAgents) +InspectorCSSAgent::InspectorCSSAgent(WebAgentContext& context, InspectorDOMAgent* domAgent) + : InspectorAgentBase(ASCIILiteral("CSS"), context) + , m_frontendDispatcher(std::make_unique<CSSFrontendDispatcher>(context.frontendRouter)) + , m_backendDispatcher(CSSBackendDispatcher::create(context.backendDispatcher, this)) , m_domAgent(domAgent) - , m_lastStyleSheetId(1) { m_domAgent->setDOMListener(this); } @@ -509,236 +354,273 @@ InspectorCSSAgent::~InspectorCSSAgent() reset(); } -void InspectorCSSAgent::didCreateFrontendAndBackend(Inspector::InspectorFrontendChannel* frontendChannel, InspectorBackendDispatcher* backendDispatcher) +void InspectorCSSAgent::didCreateFrontendAndBackend(Inspector::FrontendRouter*, Inspector::BackendDispatcher*) { - m_frontendDispatcher = std::make_unique<InspectorCSSFrontendDispatcher>(frontendChannel); - m_backendDispatcher = InspectorCSSBackendDispatcher::create(backendDispatcher, this); } -void InspectorCSSAgent::willDestroyFrontendAndBackend(InspectorDisconnectReason) +void InspectorCSSAgent::willDestroyFrontendAndBackend(Inspector::DisconnectReason) { - m_frontendDispatcher = nullptr; - m_backendDispatcher.clear(); - resetNonPersistentData(); + + String unused; + disable(unused); } void InspectorCSSAgent::discardAgent() { - m_domAgent->setDOMListener(0); - m_domAgent = 0; + m_domAgent->setDOMListener(nullptr); + m_domAgent = nullptr; } void InspectorCSSAgent::reset() { + // FIXME: Should we be resetting on main frame navigations? m_idToInspectorStyleSheet.clear(); m_cssStyleSheetToInspectorStyleSheet.clear(); m_nodeToInspectorStyleSheet.clear(); m_documentToInspectorStyleSheet.clear(); + m_documentToKnownCSSStyleSheets.clear(); resetNonPersistentData(); } void InspectorCSSAgent::resetNonPersistentData() { m_namedFlowCollectionsRequested.clear(); - if (m_updateRegionLayoutTask) - m_updateRegionLayoutTask->reset(); if (m_changeRegionOversetTask) m_changeRegionOversetTask->reset(); resetPseudoStates(); } -void InspectorCSSAgent::enable(ErrorString*) +void InspectorCSSAgent::enable(ErrorString&) { - m_instrumentingAgents->setInspectorCSSAgent(this); + m_instrumentingAgents.setInspectorCSSAgent(this); + + for (auto* document : m_domAgent->documents()) + activeStyleSheetsUpdated(*document); } -void InspectorCSSAgent::disable(ErrorString*) +void InspectorCSSAgent::disable(ErrorString&) { - m_instrumentingAgents->setInspectorCSSAgent(0); + m_instrumentingAgents.setInspectorCSSAgent(nullptr); +} + +void InspectorCSSAgent::documentDetached(Document& document) +{ + Vector<CSSStyleSheet*> emptyList; + setActiveStyleSheetsForDocument(document, emptyList); + + m_documentToKnownCSSStyleSheets.remove(&document); + m_documentToInspectorStyleSheet.remove(&document); + m_documentsWithForcedPseudoStates.remove(&document); } void InspectorCSSAgent::mediaQueryResultChanged() { - if (m_frontendDispatcher) - m_frontendDispatcher->mediaQueryResultChanged(); + m_frontendDispatcher->mediaQueryResultChanged(); } -void InspectorCSSAgent::didCreateNamedFlow(Document* document, WebKitNamedFlow* namedFlow) +void InspectorCSSAgent::activeStyleSheetsUpdated(Document& document) { - int documentNodeId = documentNodeWithRequestedFlowsId(document); - if (!documentNodeId) - return; + Vector<CSSStyleSheet*> cssStyleSheets; + collectAllDocumentStyleSheets(document, cssStyleSheets); - ErrorString errorString; - m_frontendDispatcher->namedFlowCreated(buildObjectForNamedFlow(&errorString, namedFlow, documentNodeId)); + setActiveStyleSheetsForDocument(document, cssStyleSheets); } -void InspectorCSSAgent::willRemoveNamedFlow(Document* document, WebKitNamedFlow* namedFlow) +void InspectorCSSAgent::setActiveStyleSheetsForDocument(Document& document, Vector<CSSStyleSheet*>& activeStyleSheets) { - int documentNodeId = documentNodeWithRequestedFlowsId(document); - if (!documentNodeId) - return; + HashSet<CSSStyleSheet*>& previouslyKnownActiveStyleSheets = m_documentToKnownCSSStyleSheets.add(&document, HashSet<CSSStyleSheet*>()).iterator->value; - if (m_updateRegionLayoutTask) - m_updateRegionLayoutTask->unschedule(namedFlow); - - if (m_changeRegionOversetTask) - m_changeRegionOversetTask->unschedule(namedFlow); + HashSet<CSSStyleSheet*> removedStyleSheets(previouslyKnownActiveStyleSheets); + Vector<CSSStyleSheet*> addedStyleSheets; + for (auto& activeStyleSheet : activeStyleSheets) { + if (removedStyleSheets.contains(activeStyleSheet)) + removedStyleSheets.remove(activeStyleSheet); + else + addedStyleSheets.append(activeStyleSheet); + } - m_frontendDispatcher->namedFlowRemoved(documentNodeId, namedFlow->name().string()); + for (auto* cssStyleSheet : removedStyleSheets) { + previouslyKnownActiveStyleSheets.remove(cssStyleSheet); + RefPtr<InspectorStyleSheet> inspectorStyleSheet = m_cssStyleSheetToInspectorStyleSheet.get(cssStyleSheet); + if (m_idToInspectorStyleSheet.contains(inspectorStyleSheet->id())) { + String id = unbindStyleSheet(inspectorStyleSheet.get()); + m_frontendDispatcher->styleSheetRemoved(id); + } + } + + for (auto* cssStyleSheet : addedStyleSheets) { + previouslyKnownActiveStyleSheets.add(cssStyleSheet); + if (!m_cssStyleSheetToInspectorStyleSheet.contains(cssStyleSheet)) { + InspectorStyleSheet* inspectorStyleSheet = bindStyleSheet(cssStyleSheet); + m_frontendDispatcher->styleSheetAdded(inspectorStyleSheet->buildObjectForStyleSheetInfo()); + } + } } -void InspectorCSSAgent::didUpdateRegionLayout(Document* document, WebKitNamedFlow* namedFlow) +void InspectorCSSAgent::didCreateNamedFlow(Document& document, WebKitNamedFlow& namedFlow) { - int documentNodeId = documentNodeWithRequestedFlowsId(document); + int documentNodeId = documentNodeWithRequestedFlowsId(&document); if (!documentNodeId) return; - if (!m_updateRegionLayoutTask) - m_updateRegionLayoutTask = adoptPtr(new UpdateRegionLayoutTask(this)); - m_updateRegionLayoutTask->scheduleFor(namedFlow, documentNodeId); + ErrorString unused; + m_frontendDispatcher->namedFlowCreated(buildObjectForNamedFlow(unused, &namedFlow, documentNodeId)); } -void InspectorCSSAgent::regionLayoutUpdated(WebKitNamedFlow* namedFlow, int documentNodeId) +void InspectorCSSAgent::willRemoveNamedFlow(Document& document, WebKitNamedFlow& namedFlow) { - if (namedFlow->flowState() == WebKitNamedFlow::FlowStateNull) + int documentNodeId = documentNodeWithRequestedFlowsId(&document); + if (!documentNodeId) return; - ErrorString errorString; - Ref<WebKitNamedFlow> protect(*namedFlow); + if (m_changeRegionOversetTask) + m_changeRegionOversetTask->unschedule(&namedFlow); - m_frontendDispatcher->regionLayoutUpdated(buildObjectForNamedFlow(&errorString, namedFlow, documentNodeId)); + m_frontendDispatcher->namedFlowRemoved(documentNodeId, namedFlow.name().string()); } -void InspectorCSSAgent::didChangeRegionOverset(Document* document, WebKitNamedFlow* namedFlow) +void InspectorCSSAgent::didChangeRegionOverset(Document& document, WebKitNamedFlow& namedFlow) { - int documentNodeId = documentNodeWithRequestedFlowsId(document); + int documentNodeId = documentNodeWithRequestedFlowsId(&document); if (!documentNodeId) return; - + if (!m_changeRegionOversetTask) - m_changeRegionOversetTask = adoptPtr(new ChangeRegionOversetTask(this)); - m_changeRegionOversetTask->scheduleFor(namedFlow, documentNodeId); + m_changeRegionOversetTask = std::make_unique<ChangeRegionOversetTask>(this); + m_changeRegionOversetTask->scheduleFor(&namedFlow, documentNodeId); } void InspectorCSSAgent::regionOversetChanged(WebKitNamedFlow* namedFlow, int documentNodeId) { if (namedFlow->flowState() == WebKitNamedFlow::FlowStateNull) return; - - ErrorString errorString; + + ErrorString unused; Ref<WebKitNamedFlow> protect(*namedFlow); - - m_frontendDispatcher->regionOversetChanged(buildObjectForNamedFlow(&errorString, namedFlow, documentNodeId)); + + m_frontendDispatcher->regionOversetChanged(buildObjectForNamedFlow(unused, namedFlow, documentNodeId)); } -void InspectorCSSAgent::didRegisterNamedFlowContentElement(Document* document, WebKitNamedFlow* namedFlow, Node* contentElement, Node* nextContentElement) +void InspectorCSSAgent::didRegisterNamedFlowContentElement(Document& document, WebKitNamedFlow& namedFlow, Node& contentElement, Node* nextContentElement) { - int documentNodeId = documentNodeWithRequestedFlowsId(document); + int documentNodeId = documentNodeWithRequestedFlowsId(&document); if (!documentNodeId) return; - ErrorString errorString; - int contentElementNodeId = m_domAgent->pushNodeToFrontend(&errorString, documentNodeId, contentElement); - int nextContentElementNodeId = nextContentElement ? m_domAgent->pushNodeToFrontend(&errorString, documentNodeId, nextContentElement) : 0; - m_frontendDispatcher->registeredNamedFlowContentElement(documentNodeId, namedFlow->name().string(), contentElementNodeId, nextContentElementNodeId); + ErrorString unused; + int contentElementNodeId = m_domAgent->pushNodeToFrontend(unused, documentNodeId, &contentElement); + int nextContentElementNodeId = nextContentElement ? m_domAgent->pushNodeToFrontend(unused, documentNodeId, nextContentElement) : 0; + m_frontendDispatcher->registeredNamedFlowContentElement(documentNodeId, namedFlow.name().string(), contentElementNodeId, nextContentElementNodeId); } -void InspectorCSSAgent::didUnregisterNamedFlowContentElement(Document* document, WebKitNamedFlow* namedFlow, Node* contentElement) +void InspectorCSSAgent::didUnregisterNamedFlowContentElement(Document& document, WebKitNamedFlow& namedFlow, Node& contentElement) { - int documentNodeId = documentNodeWithRequestedFlowsId(document); + int documentNodeId = documentNodeWithRequestedFlowsId(&document); if (!documentNodeId) return; - ErrorString errorString; - int contentElementNodeId = m_domAgent->pushNodeToFrontend(&errorString, documentNodeId, contentElement); + ErrorString unused; + int contentElementNodeId = m_domAgent->pushNodeToFrontend(unused, documentNodeId, &contentElement); if (!contentElementNodeId) { // We've already notified that the DOM node was removed from the DOM, so there's no need to send another event. return; } - m_frontendDispatcher->unregisteredNamedFlowContentElement(documentNodeId, namedFlow->name().string(), contentElementNodeId); + m_frontendDispatcher->unregisteredNamedFlowContentElement(documentNodeId, namedFlow.name().string(), contentElementNodeId); } -bool InspectorCSSAgent::forcePseudoState(Element* element, CSSSelector::PseudoType pseudoType) +bool InspectorCSSAgent::forcePseudoState(const Element& element, CSSSelector::PseudoClassType pseudoClassType) { if (m_nodeIdToForcedPseudoState.isEmpty()) return false; - int nodeId = m_domAgent->boundNodeId(element); + int nodeId = m_domAgent->boundNodeId(&element); if (!nodeId) return false; - NodeIdToForcedPseudoState::iterator it = m_nodeIdToForcedPseudoState.find(nodeId); + auto it = m_nodeIdToForcedPseudoState.find(nodeId); if (it == m_nodeIdToForcedPseudoState.end()) return false; unsigned forcedPseudoState = it->value; - switch (pseudoType) { - case CSSSelector::PseudoActive: - return forcedPseudoState & PseudoActive; - case CSSSelector::PseudoFocus: - return forcedPseudoState & PseudoFocus; - case CSSSelector::PseudoHover: - return forcedPseudoState & PseudoHover; - case CSSSelector::PseudoVisited: - return forcedPseudoState & PseudoVisited; + switch (pseudoClassType) { + case CSSSelector::PseudoClassActive: + return forcedPseudoState & PseudoClassActive; + case CSSSelector::PseudoClassFocus: + return forcedPseudoState & PseudoClassFocus; + case CSSSelector::PseudoClassHover: + return forcedPseudoState & PseudoClassHover; + case CSSSelector::PseudoClassVisited: + return forcedPseudoState & PseudoClassVisited; default: return false; } } -void 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) +void InspectorCSSAgent::getMatchedStylesForNode(ErrorString& errorString, int nodeId, const bool* includePseudo, const bool* includeInherited, RefPtr<Inspector::Protocol::Array<Inspector::Protocol::CSS::RuleMatch>>& matchedCSSRules, RefPtr<Inspector::Protocol::Array<Inspector::Protocol::CSS::PseudoIdMatches>>& pseudoIdMatches, RefPtr<Inspector::Protocol::Array<Inspector::Protocol::CSS::InheritedStyleEntry>>& inheritedEntries) { Element* element = elementForId(errorString, nodeId); if (!element) return; - // Matched rules. - StyleResolver& styleResolver = element->document().ensureStyleResolver(); - Vector<RefPtr<StyleRuleBase>> matchedRules = styleResolver.styleRulesForElement(element, StyleResolver::AllCSSRules); - matchedCSSRules = buildArrayForMatchedRuleList(matchedRules, styleResolver, element); - - // Pseudo elements. - if (!includePseudo || *includePseudo) { - RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::PseudoIdMatches>> pseudoElements = Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::PseudoIdMatches>::create(); - for (PseudoId pseudoId = FIRST_PUBLIC_PSEUDOID; pseudoId < AFTER_LAST_INTERNAL_PSEUDOID; pseudoId = static_cast<PseudoId>(pseudoId + 1)) { - Vector<RefPtr<StyleRuleBase>> matchedRules = styleResolver.pseudoStyleRulesForElement(element, pseudoId, StyleResolver::AllCSSRules); - if (!matchedRules.isEmpty()) { - RefPtr<Inspector::TypeBuilder::CSS::PseudoIdMatches> matches = Inspector::TypeBuilder::CSS::PseudoIdMatches::create() - .setPseudoId(static_cast<int>(pseudoId)) - .setMatches(buildArrayForMatchedRuleList(matchedRules, styleResolver, element)); - pseudoElements->addItem(matches.release()); - } + Element* originalElement = element; + PseudoId elementPseudoId = element->pseudoId(); + if (elementPseudoId) { + element = downcast<PseudoElement>(*element).hostElement(); + if (!element) { + errorString = ASCIILiteral("Pseudo element has no parent"); + return; } - - pseudoIdMatches = pseudoElements.release(); } - // Inherited styles. - if (!includeInherited || *includeInherited) { - RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::InheritedStyleEntry>> entries = Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::InheritedStyleEntry>::create(); - Element* parentElement = element->parentElement(); - while (parentElement) { - StyleResolver& parentStyleResolver = parentElement->document().ensureStyleResolver(); - Vector<RefPtr<StyleRuleBase>> parentMatchedRules = parentStyleResolver.styleRulesForElement(parentElement, StyleResolver::AllCSSRules); - RefPtr<Inspector::TypeBuilder::CSS::InheritedStyleEntry> entry = Inspector::TypeBuilder::CSS::InheritedStyleEntry::create() - .setMatchedCSSRules(buildArrayForMatchedRuleList(parentMatchedRules, styleResolver, parentElement)); - if (parentElement->style() && parentElement->style()->length()) { - InspectorStyleSheetForInlineStyle* styleSheet = asInspectorStyleSheet(parentElement); - if (styleSheet) - entry->setInlineStyle(styleSheet->buildObjectForStyle(styleSheet->styleForId(InspectorCSSId(styleSheet->id(), 0)))); + // Matched rules. + StyleResolver& styleResolver = element->styleResolver(); + auto matchedRules = styleResolver.pseudoStyleRulesForElement(element, elementPseudoId, StyleResolver::AllCSSRules); + matchedCSSRules = buildArrayForMatchedRuleList(matchedRules, styleResolver, *element, elementPseudoId); + + if (!originalElement->isPseudoElement()) { + // Pseudo elements. + if (!includePseudo || *includePseudo) { + auto pseudoElements = Inspector::Protocol::Array<Inspector::Protocol::CSS::PseudoIdMatches>::create(); + for (PseudoId pseudoId = FIRST_PUBLIC_PSEUDOID; pseudoId < AFTER_LAST_INTERNAL_PSEUDOID; pseudoId = static_cast<PseudoId>(pseudoId + 1)) { + auto matchedRules = styleResolver.pseudoStyleRulesForElement(element, pseudoId, StyleResolver::AllCSSRules); + if (!matchedRules.isEmpty()) { + auto matches = Inspector::Protocol::CSS::PseudoIdMatches::create() + .setPseudoId(static_cast<int>(pseudoId)) + .setMatches(buildArrayForMatchedRuleList(matchedRules, styleResolver, *element, pseudoId)) + .release(); + pseudoElements->addItem(WTFMove(matches)); + } } - entries->addItem(entry.release()); - parentElement = parentElement->parentElement(); + pseudoIdMatches = WTFMove(pseudoElements); } - inheritedEntries = entries.release(); + // Inherited styles. + if (!includeInherited || *includeInherited) { + auto entries = Inspector::Protocol::Array<Inspector::Protocol::CSS::InheritedStyleEntry>::create(); + Element* parentElement = element->parentElement(); + while (parentElement) { + StyleResolver& parentStyleResolver = parentElement->styleResolver(); + auto parentMatchedRules = parentStyleResolver.styleRulesForElement(parentElement, StyleResolver::AllCSSRules); + auto entry = Inspector::Protocol::CSS::InheritedStyleEntry::create() + .setMatchedCSSRules(buildArrayForMatchedRuleList(parentMatchedRules, styleResolver, *parentElement, NOPSEUDO)) + .release(); + if (parentElement->cssomStyle() && parentElement->cssomStyle()->length()) { + if (InspectorStyleSheetForInlineStyle* styleSheet = asInspectorStyleSheet(parentElement)) + entry->setInlineStyle(styleSheet->buildObjectForStyle(styleSheet->styleForId(InspectorCSSId(styleSheet->id(), 0)))); + } + + entries->addItem(WTFMove(entry)); + parentElement = parentElement->parentElement(); + } + + inheritedEntries = WTFMove(entries); + } } } -void InspectorCSSAgent::getInlineStylesForNode(ErrorString* errorString, int nodeId, RefPtr<Inspector::TypeBuilder::CSS::CSSStyle>& inlineStyle, RefPtr<Inspector::TypeBuilder::CSS::CSSStyle>& attributesStyle) +void InspectorCSSAgent::getInlineStylesForNode(ErrorString& errorString, int nodeId, RefPtr<Inspector::Protocol::CSS::CSSStyle>& inlineStyle, RefPtr<Inspector::Protocol::CSS::CSSStyle>& attributesStyle) { Element* element = elementForId(errorString, nodeId); if (!element) @@ -748,37 +630,65 @@ void InspectorCSSAgent::getInlineStylesForNode(ErrorString* errorString, int nod if (!styleSheet) return; - inlineStyle = styleSheet->buildObjectForStyle(element->style()); - RefPtr<Inspector::TypeBuilder::CSS::CSSStyle> attributes = buildObjectForAttributesStyle(element); - attributesStyle = attributes ? attributes.release() : 0; + inlineStyle = styleSheet->buildObjectForStyle(element->cssomStyle()); + if (auto attributes = buildObjectForAttributesStyle(element)) + attributesStyle = WTFMove(attributes); + else + attributesStyle = nullptr; } -void InspectorCSSAgent::getComputedStyleForNode(ErrorString* errorString, int nodeId, RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::CSSComputedStyleProperty>>& style) +void InspectorCSSAgent::getComputedStyleForNode(ErrorString& errorString, int nodeId, RefPtr<Inspector::Protocol::Array<Inspector::Protocol::CSS::CSSComputedStyleProperty>>& style) { Element* element = elementForId(errorString, nodeId); if (!element) return; - RefPtr<CSSComputedStyleDeclaration> computedStyleInfo = CSSComputedStyleDeclaration::create(element, true); - RefPtr<InspectorStyle> inspectorStyle = InspectorStyle::create(InspectorCSSId(), computedStyleInfo, 0); + RefPtr<CSSComputedStyleDeclaration> computedStyleInfo = CSSComputedStyleDeclaration::create(*element, true); + Ref<InspectorStyle> inspectorStyle = InspectorStyle::create(InspectorCSSId(), computedStyleInfo, nullptr); style = inspectorStyle->buildArrayForComputedStyle(); } -void InspectorCSSAgent::getAllStyleSheets(ErrorString*, RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::CSSStyleSheetHeader>>& styleInfos) +void InspectorCSSAgent::getAllStyleSheets(ErrorString&, RefPtr<Inspector::Protocol::Array<Inspector::Protocol::CSS::CSSStyleSheetHeader>>& styleInfos) +{ + styleInfos = Inspector::Protocol::Array<Inspector::Protocol::CSS::CSSStyleSheetHeader>::create(); + + Vector<InspectorStyleSheet*> inspectorStyleSheets; + collectAllStyleSheets(inspectorStyleSheets); + for (auto* inspectorStyleSheet : inspectorStyleSheets) + styleInfos->addItem(inspectorStyleSheet->buildObjectForStyleSheetInfo()); +} + +void InspectorCSSAgent::collectAllStyleSheets(Vector<InspectorStyleSheet*>& result) +{ + Vector<CSSStyleSheet*> cssStyleSheets; + for (auto* document : m_domAgent->documents()) + collectAllDocumentStyleSheets(*document, cssStyleSheets); + + for (auto* cssStyleSheet : cssStyleSheets) + result.append(bindStyleSheet(cssStyleSheet)); +} + +void InspectorCSSAgent::collectAllDocumentStyleSheets(Document& document, Vector<CSSStyleSheet*>& result) { - styleInfos = Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::CSSStyleSheetHeader>::create(); - Vector<Document*> documents = m_domAgent->documents(); - for (Vector<Document*>::iterator it = documents.begin(); it != documents.end(); ++it) { - StyleSheetList* list = (*it)->styleSheets(); - for (unsigned i = 0; i < list->length(); ++i) { - StyleSheet* styleSheet = list->item(i); - if (styleSheet->isCSSStyleSheet()) - collectStyleSheets(static_cast<CSSStyleSheet*>(styleSheet), styleInfos.get()); + auto cssStyleSheets = document.styleScope().activeStyleSheetsForInspector(); + for (auto& cssStyleSheet : cssStyleSheets) + collectStyleSheets(cssStyleSheet.get(), result); +} + +void InspectorCSSAgent::collectStyleSheets(CSSStyleSheet* styleSheet, Vector<CSSStyleSheet*>& result) +{ + result.append(styleSheet); + + for (unsigned i = 0, size = styleSheet->length(); i < size; ++i) { + CSSRule* rule = styleSheet->item(i); + if (is<CSSImportRule>(*rule)) { + if (CSSStyleSheet* importedStyleSheet = downcast<CSSImportRule>(*rule).styleSheet()) + collectStyleSheets(importedStyleSheet, result); } } } -void InspectorCSSAgent::getStyleSheet(ErrorString* errorString, const String& styleSheetId, RefPtr<Inspector::TypeBuilder::CSS::CSSStyleSheetBody>& styleSheetObject) +void InspectorCSSAgent::getStyleSheet(ErrorString& errorString, const String& styleSheetId, RefPtr<Inspector::Protocol::CSS::CSSStyleSheetBody>& styleSheetObject) { InspectorStyleSheet* inspectorStyleSheet = assertStyleSheetForId(errorString, styleSheetId); if (!inspectorStyleSheet) @@ -787,27 +697,29 @@ void InspectorCSSAgent::getStyleSheet(ErrorString* errorString, const String& st styleSheetObject = inspectorStyleSheet->buildObjectForStyleSheet(); } -void InspectorCSSAgent::getStyleSheetText(ErrorString* errorString, const String& styleSheetId, String* result) +void InspectorCSSAgent::getStyleSheetText(ErrorString& errorString, const String& styleSheetId, String* result) { InspectorStyleSheet* inspectorStyleSheet = assertStyleSheetForId(errorString, styleSheetId); if (!inspectorStyleSheet) return; - inspectorStyleSheet->getText(result); + auto text = inspectorStyleSheet->text(); + if (!text.hasException()) + *result = text.releaseReturnValue(); } -void InspectorCSSAgent::setStyleSheetText(ErrorString* errorString, const String& styleSheetId, const String& text) +void InspectorCSSAgent::setStyleSheetText(ErrorString& errorString, const String& styleSheetId, const String& text) { InspectorStyleSheet* inspectorStyleSheet = assertStyleSheetForId(errorString, styleSheetId); if (!inspectorStyleSheet) return; - ExceptionCode ec = 0; - m_domAgent->history()->perform(adoptPtr(new SetStyleSheetTextAction(inspectorStyleSheet, text)), ec); - *errorString = InspectorDOMAgent::toErrorString(ec); + auto result = m_domAgent->history()->perform(std::make_unique<SetStyleSheetTextAction>(inspectorStyleSheet, text)); + if (result.hasException()) + errorString = InspectorDOMAgent::toErrorString(result.releaseException()); } -void InspectorCSSAgent::setStyleText(ErrorString* errorString, const RefPtr<InspectorObject>& fullStyleId, const String& text, RefPtr<Inspector::TypeBuilder::CSS::CSSStyle>& result) +void InspectorCSSAgent::setStyleText(ErrorString& errorString, const InspectorObject& fullStyleId, const String& text, RefPtr<Inspector::Protocol::CSS::CSSStyle>& result) { InspectorCSSId compoundId(fullStyleId); ASSERT(!compoundId.isEmpty()); @@ -816,133 +728,182 @@ void InspectorCSSAgent::setStyleText(ErrorString* errorString, const RefPtr<Insp if (!inspectorStyleSheet) return; - ExceptionCode ec = 0; - bool success = m_domAgent->history()->perform(adoptPtr(new SetStyleTextAction(inspectorStyleSheet, compoundId, text)), ec); - if (success) - result = inspectorStyleSheet->buildObjectForStyle(inspectorStyleSheet->styleForId(compoundId)); - *errorString = InspectorDOMAgent::toErrorString(ec); + auto performResult = m_domAgent->history()->perform(std::make_unique<SetStyleTextAction>(inspectorStyleSheet, compoundId, text)); + if (performResult.hasException()) { + errorString = InspectorDOMAgent::toErrorString(performResult.releaseException()); + return; + } + + result = inspectorStyleSheet->buildObjectForStyle(inspectorStyleSheet->styleForId(compoundId)); } -void InspectorCSSAgent::setPropertyText(ErrorString* errorString, const RefPtr<InspectorObject>& fullStyleId, int propertyIndex, const String& text, bool overwrite, RefPtr<Inspector::TypeBuilder::CSS::CSSStyle>& result) +void InspectorCSSAgent::setRuleSelector(ErrorString& errorString, const InspectorObject& fullRuleId, const String& selector, RefPtr<Inspector::Protocol::CSS::CSSRule>& result) { - InspectorCSSId compoundId(fullStyleId); + InspectorCSSId compoundId(fullRuleId); ASSERT(!compoundId.isEmpty()); InspectorStyleSheet* inspectorStyleSheet = assertStyleSheetForId(errorString, compoundId.styleSheetId()); if (!inspectorStyleSheet) return; - ExceptionCode ec = 0; - bool success = m_domAgent->history()->perform(adoptPtr(new SetPropertyTextAction(inspectorStyleSheet, compoundId, propertyIndex, text, overwrite)), ec); - if (success) - result = inspectorStyleSheet->buildObjectForStyle(inspectorStyleSheet->styleForId(compoundId)); - *errorString = InspectorDOMAgent::toErrorString(ec); + auto performResult = m_domAgent->history()->perform(std::make_unique<SetRuleSelectorAction>(inspectorStyleSheet, compoundId, selector)); + if (performResult.hasException()) { + errorString = InspectorDOMAgent::toErrorString(performResult.releaseException()); + return; + } + + result = inspectorStyleSheet->buildObjectForRule(inspectorStyleSheet->ruleForId(compoundId), nullptr); } -void InspectorCSSAgent::toggleProperty(ErrorString* errorString, const RefPtr<InspectorObject>& fullStyleId, int propertyIndex, bool disable, RefPtr<Inspector::TypeBuilder::CSS::CSSStyle>& result) +void InspectorCSSAgent::createStyleSheet(ErrorString& errorString, const String& frameId, String* styleSheetId) { - InspectorCSSId compoundId(fullStyleId); - ASSERT(!compoundId.isEmpty()); + Frame* frame = m_domAgent->pageAgent()->frameForId(frameId); + if (!frame) { + errorString = ASCIILiteral("No frame for given id found"); + return; + } - InspectorStyleSheet* inspectorStyleSheet = assertStyleSheetForId(errorString, compoundId.styleSheetId()); - if (!inspectorStyleSheet) + Document* document = frame->document(); + if (!document) { + errorString = ASCIILiteral("No document for frame"); return; + } - ExceptionCode ec = 0; - bool success = m_domAgent->history()->perform(adoptPtr(new TogglePropertyAction(inspectorStyleSheet, compoundId, propertyIndex, disable)), ec); - if (success) - result = inspectorStyleSheet->buildObjectForStyle(inspectorStyleSheet->styleForId(compoundId)); - *errorString = InspectorDOMAgent::toErrorString(ec); + InspectorStyleSheet* inspectorStyleSheet = createInspectorStyleSheetForDocument(*document); + if (!inspectorStyleSheet) { + errorString = ASCIILiteral("Could not create stylesheet for the frame."); + return; + } + + *styleSheetId = inspectorStyleSheet->id(); } -void InspectorCSSAgent::setRuleSelector(ErrorString* errorString, const RefPtr<InspectorObject>& fullRuleId, const String& selector, RefPtr<Inspector::TypeBuilder::CSS::CSSRule>& result) +InspectorStyleSheet* InspectorCSSAgent::createInspectorStyleSheetForDocument(Document& document) { - InspectorCSSId compoundId(fullRuleId); - ASSERT(!compoundId.isEmpty()); + if (!document.isHTMLDocument() && !document.isSVGDocument()) + return nullptr; - InspectorStyleSheet* inspectorStyleSheet = assertStyleSheetForId(errorString, compoundId.styleSheetId()); - if (!inspectorStyleSheet) - return; + auto styleElement = HTMLStyleElement::create(document); + styleElement->setAttributeWithoutSynchronization(HTMLNames::typeAttr, AtomicString("text/css", AtomicString::ConstructFromLiteral)); + + ContainerNode* targetNode; + // HEAD is absent in ImageDocuments, for example. + if (auto* head = document.head()) + targetNode = head; + else if (auto* body = document.bodyOrFrameset()) + targetNode = body; + else + return nullptr; + + // Inserting this <style> into the document will trigger activeStyleSheetsUpdated + // and we will create an InspectorStyleSheet for this <style>'s CSSStyleSheet. + // Set this flag, so when we create it, we put it into the via inspector map. + m_creatingViaInspectorStyleSheet = true; + InlineStyleOverrideScope overrideScope(document); + auto appendResult = targetNode->appendChild(styleElement); + document.styleScope().flushPendingUpdate(); + m_creatingViaInspectorStyleSheet = false; + if (appendResult.hasException()) + return nullptr; - ExceptionCode ec = 0; - bool success = m_domAgent->history()->perform(adoptPtr(new SetRuleSelectorAction(inspectorStyleSheet, compoundId, selector)), ec); + auto iterator = m_documentToInspectorStyleSheet.find(&document); + ASSERT(iterator != m_documentToInspectorStyleSheet.end()); + if (iterator == m_documentToInspectorStyleSheet.end()) + return nullptr; - if (success) - result = inspectorStyleSheet->buildObjectForRule(inspectorStyleSheet->ruleForId(compoundId)); - *errorString = InspectorDOMAgent::toErrorString(ec); + auto& inspectorStyleSheetsForDocument = iterator->value; + ASSERT(!inspectorStyleSheetsForDocument.isEmpty()); + if (inspectorStyleSheetsForDocument.isEmpty()) + return nullptr; + + return inspectorStyleSheetsForDocument.last().get(); } -void InspectorCSSAgent::addRule(ErrorString* errorString, const int contextNodeId, const String& selector, RefPtr<Inspector::TypeBuilder::CSS::CSSRule>& result) +void InspectorCSSAgent::addRule(ErrorString& errorString, const String& styleSheetId, const String& selector, RefPtr<Inspector::Protocol::CSS::CSSRule>& result) { - Node* node = m_domAgent->assertNode(errorString, contextNodeId); - if (!node) - return; - - InspectorStyleSheet* inspectorStyleSheet = viaInspectorStyleSheet(&node->document(), true); + InspectorStyleSheet* inspectorStyleSheet = assertStyleSheetForId(errorString, styleSheetId); if (!inspectorStyleSheet) { - *errorString = "No target stylesheet found"; + errorString = ASCIILiteral("No target stylesheet found"); return; } - ExceptionCode ec = 0; - OwnPtr<AddRuleAction> action = adoptPtr(new AddRuleAction(inspectorStyleSheet, selector)); - AddRuleAction* rawAction = action.get(); - bool success = m_domAgent->history()->perform(action.release(), ec); - if (!success) { - *errorString = InspectorDOMAgent::toErrorString(ec); + auto action = std::make_unique<AddRuleAction>(inspectorStyleSheet, selector); + auto& rawAction = *action; + auto performResult = m_domAgent->history()->perform(WTFMove(action)); + if (performResult.hasException()) { + errorString = InspectorDOMAgent::toErrorString(performResult.releaseException()); return; } - InspectorCSSId ruleId = rawAction->newRuleId(); + InspectorCSSId ruleId = rawAction.newRuleId(); CSSStyleRule* rule = inspectorStyleSheet->ruleForId(ruleId); - result = inspectorStyleSheet->buildObjectForRule(rule); + result = inspectorStyleSheet->buildObjectForRule(rule, nullptr); } -void InspectorCSSAgent::getSupportedCSSProperties(ErrorString*, RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::CSSPropertyInfo>>& cssProperties) +void InspectorCSSAgent::getSupportedCSSProperties(ErrorString&, RefPtr<Inspector::Protocol::Array<Inspector::Protocol::CSS::CSSPropertyInfo>>& cssProperties) { - RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::CSSPropertyInfo>> properties = Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::CSSPropertyInfo>::create(); + auto properties = Inspector::Protocol::Array<Inspector::Protocol::CSS::CSSPropertyInfo>::create(); for (int i = firstCSSProperty; i <= lastCSSProperty; ++i) { CSSPropertyID id = convertToCSSPropertyID(i); - RefPtr<Inspector::TypeBuilder::CSS::CSSPropertyInfo> property = Inspector::TypeBuilder::CSS::CSSPropertyInfo::create() - .setName(getPropertyNameString(id)); + if (isInternalCSSProperty(id)) + continue; + + auto property = Inspector::Protocol::CSS::CSSPropertyInfo::create() + .setName(getPropertyNameString(id)) + .release(); const StylePropertyShorthand& shorthand = shorthandForProperty(id); if (!shorthand.length()) { - properties->addItem(property.release()); + properties->addItem(WTFMove(property)); continue; } - RefPtr<Inspector::TypeBuilder::Array<String>> longhands = Inspector::TypeBuilder::Array<String>::create(); + auto longhands = Inspector::Protocol::Array<String>::create(); for (unsigned j = 0; j < shorthand.length(); ++j) { CSSPropertyID longhandID = shorthand.properties()[j]; longhands->addItem(getPropertyNameString(longhandID)); } - property->setLonghands(longhands); - properties->addItem(property.release()); + property->setLonghands(WTFMove(longhands)); + properties->addItem(WTFMove(property)); } - cssProperties = properties.release(); + cssProperties = WTFMove(properties); +} + +void InspectorCSSAgent::getSupportedSystemFontFamilyNames(ErrorString&, RefPtr<Inspector::Protocol::Array<String>>& fontFamilyNames) +{ + auto families = Inspector::Protocol::Array<String>::create(); + + Vector<String> systemFontFamilies = FontCache::singleton().systemFontFamilies(); + for (const auto& familyName : systemFontFamilies) + families->addItem(familyName); + + fontFamilyNames = WTFMove(families); } -void InspectorCSSAgent::forcePseudoState(ErrorString* errorString, int nodeId, const RefPtr<InspectorArray>& forcedPseudoClasses) +void InspectorCSSAgent::forcePseudoState(ErrorString& errorString, int nodeId, const InspectorArray& forcedPseudoClasses) { Element* element = m_domAgent->assertElement(errorString, nodeId); if (!element) return; - unsigned forcedPseudoState = computePseudoClassMask(forcedPseudoClasses.get()); - NodeIdToForcedPseudoState::iterator it = m_nodeIdToForcedPseudoState.find(nodeId); + auto it = m_nodeIdToForcedPseudoState.find(nodeId); + unsigned forcedPseudoState = computePseudoClassMask(forcedPseudoClasses); unsigned currentForcedPseudoState = it == m_nodeIdToForcedPseudoState.end() ? 0 : it->value; - bool needStyleRecalc = forcedPseudoState != currentForcedPseudoState; - if (!needStyleRecalc) + if (forcedPseudoState == currentForcedPseudoState) return; - if (forcedPseudoState) + if (forcedPseudoState) { m_nodeIdToForcedPseudoState.set(nodeId, forcedPseudoState); - else + m_documentsWithForcedPseudoStates.add(&element->document()); + } else { m_nodeIdToForcedPseudoState.remove(nodeId); - element->document().styleResolverChanged(RecalcStyleImmediately); + if (m_nodeIdToForcedPseudoState.isEmpty()) + m_documentsWithForcedPseudoStates.clear(); + } + + element->document().styleScope().didChangeStyleSheetEnvironment(); } -void InspectorCSSAgent::getNamedFlowCollection(ErrorString* errorString, int documentNodeId, RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::NamedFlow>>& result) +void InspectorCSSAgent::getNamedFlowCollection(ErrorString& errorString, int documentNodeId, RefPtr<Inspector::Protocol::Array<Inspector::Protocol::CSS::NamedFlow>>& result) { Document* document = m_domAgent->assertDocument(errorString, documentNodeId); if (!document) @@ -950,25 +911,25 @@ void InspectorCSSAgent::getNamedFlowCollection(ErrorString* errorString, int doc m_namedFlowCollectionsRequested.add(documentNodeId); - Vector<RefPtr<WebKitNamedFlow>> namedFlowsVector = document->namedFlows()->namedFlows(); - RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::NamedFlow>> namedFlows = Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::NamedFlow>::create(); + Vector<RefPtr<WebKitNamedFlow>> namedFlowsVector = document->namedFlows().namedFlows(); + auto namedFlows = Inspector::Protocol::Array<Inspector::Protocol::CSS::NamedFlow>::create(); - for (Vector<RefPtr<WebKitNamedFlow>>::iterator it = namedFlowsVector.begin(); it != namedFlowsVector.end(); ++it) - namedFlows->addItem(buildObjectForNamedFlow(errorString, it->get(), documentNodeId)); + for (auto& namedFlow : namedFlowsVector) + namedFlows->addItem(buildObjectForNamedFlow(errorString, namedFlow.get(), documentNodeId)); - result = namedFlows.release(); + result = WTFMove(namedFlows); } InspectorStyleSheetForInlineStyle* InspectorCSSAgent::asInspectorStyleSheet(Element* element) { NodeToInspectorStyleSheet::iterator it = m_nodeToInspectorStyleSheet.find(element); if (it == m_nodeToInspectorStyleSheet.end()) { - CSSStyleDeclaration* style = element->isStyledElement() ? element->style() : 0; + CSSStyleDeclaration* style = element->cssomStyle(); if (!style) - return 0; + return nullptr; String newStyleSheetId = String::number(m_lastStyleSheetId++); - RefPtr<InspectorStyleSheetForInlineStyle> inspectorStyleSheet = InspectorStyleSheetForInlineStyle::create(m_domAgent->pageAgent(), newStyleSheetId, element, Inspector::TypeBuilder::CSS::StyleSheetOrigin::Regular, this); + RefPtr<InspectorStyleSheetForInlineStyle> inspectorStyleSheet = InspectorStyleSheetForInlineStyle::create(m_domAgent->pageAgent(), newStyleSheetId, element, Inspector::Protocol::CSS::StyleSheetOrigin::Regular, this); m_idToInspectorStyleSheet.set(newStyleSheetId, inspectorStyleSheet); m_nodeToInspectorStyleSheet.set(element, inspectorStyleSheet); return inspectorStyleSheet.get(); @@ -977,18 +938,18 @@ InspectorStyleSheetForInlineStyle* InspectorCSSAgent::asInspectorStyleSheet(Elem return it->value.get(); } -Element* InspectorCSSAgent::elementForId(ErrorString* errorString, int nodeId) +Element* InspectorCSSAgent::elementForId(ErrorString& errorString, int nodeId) { Node* node = m_domAgent->nodeForId(nodeId); if (!node) { - *errorString = "No node with given id found"; - return 0; + errorString = ASCIILiteral("No node with given id found"); + return nullptr; } - if (!node->isElementNode()) { - *errorString = "Not an element node"; - return 0; + if (!is<Element>(*node)) { + errorString = ASCIILiteral("Not an element node"); + return nullptr; } - return toElement(node); + return downcast<Element>(node); } int InspectorCSSAgent::documentNodeWithRequestedFlowsId(Document* document) @@ -1000,18 +961,13 @@ int InspectorCSSAgent::documentNodeWithRequestedFlowsId(Document* document) return documentNodeId; } -void InspectorCSSAgent::collectStyleSheets(CSSStyleSheet* styleSheet, Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::CSSStyleSheetHeader>* result) +String InspectorCSSAgent::unbindStyleSheet(InspectorStyleSheet* inspectorStyleSheet) { - InspectorStyleSheet* inspectorStyleSheet = bindStyleSheet(static_cast<CSSStyleSheet*>(styleSheet)); - result->addItem(inspectorStyleSheet->buildObjectForStyleSheetInfo()); - for (unsigned i = 0, size = styleSheet->length(); i < size; ++i) { - CSSRule* rule = styleSheet->item(i); - if (rule->type() == CSSRule::IMPORT_RULE) { - CSSStyleSheet* importedStyleSheet = static_cast<CSSImportRule*>(rule)->styleSheet(); - if (importedStyleSheet) - collectStyleSheets(importedStyleSheet, result); - } - } + String id = inspectorStyleSheet->id(); + m_idToInspectorStyleSheet.remove(id); + if (inspectorStyleSheet->pageStyleSheet()) + m_cssStyleSheetToInspectorStyleSheet.remove(inspectorStyleSheet->pageStyleSheet()); + return id; } InspectorStyleSheet* InspectorCSSAgent::bindStyleSheet(CSSStyleSheet* styleSheet) @@ -1023,190 +979,146 @@ InspectorStyleSheet* InspectorCSSAgent::bindStyleSheet(CSSStyleSheet* styleSheet inspectorStyleSheet = InspectorStyleSheet::create(m_domAgent->pageAgent(), id, styleSheet, detectOrigin(styleSheet, document), InspectorDOMAgent::documentURLString(document), this); m_idToInspectorStyleSheet.set(id, inspectorStyleSheet); m_cssStyleSheetToInspectorStyleSheet.set(styleSheet, inspectorStyleSheet); + if (m_creatingViaInspectorStyleSheet) { + auto& inspectorStyleSheetsForDocument = m_documentToInspectorStyleSheet.add(document, Vector<RefPtr<InspectorStyleSheet>>()).iterator->value; + inspectorStyleSheetsForDocument.append(inspectorStyleSheet); + } } return inspectorStyleSheet.get(); } -InspectorStyleSheet* InspectorCSSAgent::viaInspectorStyleSheet(Document* document, bool createIfAbsent) -{ - if (!document) { - ASSERT(!createIfAbsent); - return 0; - } - - if (!document->isHTMLDocument() && !document->isSVGDocument()) - return 0; - - RefPtr<InspectorStyleSheet> inspectorStyleSheet = m_documentToInspectorStyleSheet.get(document); - if (inspectorStyleSheet || !createIfAbsent) - return inspectorStyleSheet.get(); - - ExceptionCode ec = 0; - RefPtr<Element> styleElement = document->createElement("style", ec); - if (!ec) - styleElement->setAttribute("type", "text/css", ec); - if (!ec) { - ContainerNode* targetNode; - // HEAD is absent in ImageDocuments, for example. - if (document->head()) - targetNode = document->head(); - else if (document->body()) - targetNode = document->body(); - else - return 0; - - InlineStyleOverrideScope overrideScope(document); - targetNode->appendChild(styleElement, ec); - } - if (ec) - return 0; - - CSSStyleSheet* cssStyleSheet = 0; - if (styleElement->isHTMLElement()) - cssStyleSheet = toHTMLStyleElement(styleElement.get())->sheet(); -#if ENABLE(SVG) - else if (styleElement->isSVGElement()) - cssStyleSheet = toSVGStyleElement(styleElement.get())->sheet(); -#endif - - if (!cssStyleSheet) - return 0; - - String id = String::number(m_lastStyleSheetId++); - inspectorStyleSheet = InspectorStyleSheet::create(m_domAgent->pageAgent(), id, cssStyleSheet, Inspector::TypeBuilder::CSS::StyleSheetOrigin::Inspector, InspectorDOMAgent::documentURLString(document), this); - m_idToInspectorStyleSheet.set(id, inspectorStyleSheet); - m_cssStyleSheetToInspectorStyleSheet.set(cssStyleSheet, inspectorStyleSheet); - m_documentToInspectorStyleSheet.set(document, inspectorStyleSheet); - return inspectorStyleSheet.get(); -} - -InspectorStyleSheet* InspectorCSSAgent::assertStyleSheetForId(ErrorString* errorString, const String& styleSheetId) +InspectorStyleSheet* InspectorCSSAgent::assertStyleSheetForId(ErrorString& errorString, const String& styleSheetId) { IdToInspectorStyleSheet::iterator it = m_idToInspectorStyleSheet.find(styleSheetId); if (it == m_idToInspectorStyleSheet.end()) { - *errorString = "No style sheet with given id found"; - return 0; + errorString = ASCIILiteral("No stylesheet with given id found"); + return nullptr; } return it->value.get(); } -Inspector::TypeBuilder::CSS::StyleSheetOrigin::Enum InspectorCSSAgent::detectOrigin(CSSStyleSheet* pageStyleSheet, Document* ownerDocument) +Inspector::Protocol::CSS::StyleSheetOrigin InspectorCSSAgent::detectOrigin(CSSStyleSheet* pageStyleSheet, Document* ownerDocument) { - Inspector::TypeBuilder::CSS::StyleSheetOrigin::Enum origin = Inspector::TypeBuilder::CSS::StyleSheetOrigin::Regular; + if (m_creatingViaInspectorStyleSheet) + return Inspector::Protocol::CSS::StyleSheetOrigin::Inspector; + if (pageStyleSheet && !pageStyleSheet->ownerNode() && pageStyleSheet->href().isEmpty()) - origin = Inspector::TypeBuilder::CSS::StyleSheetOrigin::UserAgent; - else if (pageStyleSheet && pageStyleSheet->ownerNode() && pageStyleSheet->ownerNode()->nodeName() == "#document") - origin = Inspector::TypeBuilder::CSS::StyleSheetOrigin::User; - else { - InspectorStyleSheet* viaInspectorStyleSheetForOwner = viaInspectorStyleSheet(ownerDocument, false); - if (viaInspectorStyleSheetForOwner && pageStyleSheet == viaInspectorStyleSheetForOwner->pageStyleSheet()) - origin = Inspector::TypeBuilder::CSS::StyleSheetOrigin::Inspector; + return Inspector::Protocol::CSS::StyleSheetOrigin::UserAgent; + + if (pageStyleSheet && pageStyleSheet->ownerNode() && pageStyleSheet->ownerNode()->nodeName() == "#document") + return Inspector::Protocol::CSS::StyleSheetOrigin::User; + + auto iterator = m_documentToInspectorStyleSheet.find(ownerDocument); + if (iterator != m_documentToInspectorStyleSheet.end()) { + for (auto& inspectorStyleSheet : iterator->value) { + if (pageStyleSheet == inspectorStyleSheet->pageStyleSheet()) + return Inspector::Protocol::CSS::StyleSheetOrigin::Inspector; + } } - return origin; + + return Inspector::Protocol::CSS::StyleSheetOrigin::Regular; } -PassRefPtr<Inspector::TypeBuilder::CSS::CSSRule> InspectorCSSAgent::buildObjectForRule(StyleRule* styleRule, StyleResolver& styleResolver) +RefPtr<Inspector::Protocol::CSS::CSSRule> InspectorCSSAgent::buildObjectForRule(StyleRule* styleRule, StyleResolver& styleResolver, Element& element) { if (!styleRule) - return 0; + return nullptr; // StyleRules returned by StyleResolver::styleRulesForElement lack parent pointers since that infomation is not cheaply available. // Since the inspector wants to walk the parent chain, we construct the full wrappers here. - CSSStyleRule* cssomWrapper = styleResolver.inspectorCSSOMWrappers().getWrapperForRuleInSheets(styleRule, styleResolver.document().styleSheetCollection()); + styleResolver.inspectorCSSOMWrappers().collectDocumentWrappers(styleResolver.document().extensionStyleSheets()); + styleResolver.inspectorCSSOMWrappers().collectScopeWrappers(Style::Scope::forNode(element)); + + // Possiblity of :host styles if this element has a shadow root. + if (ShadowRoot* shadowRoot = element.shadowRoot()) + styleResolver.inspectorCSSOMWrappers().collectScopeWrappers(shadowRoot->styleScope()); + + CSSStyleRule* cssomWrapper = styleResolver.inspectorCSSOMWrappers().getWrapperForRuleInSheets(styleRule); if (!cssomWrapper) - return 0; + return nullptr; + InspectorStyleSheet* inspectorStyleSheet = bindStyleSheet(cssomWrapper->parentStyleSheet()); - return inspectorStyleSheet ? inspectorStyleSheet->buildObjectForRule(cssomWrapper) : 0; + return inspectorStyleSheet ? inspectorStyleSheet->buildObjectForRule(cssomWrapper, &element) : nullptr; } -PassRefPtr<Inspector::TypeBuilder::CSS::CSSRule> InspectorCSSAgent::buildObjectForRule(CSSStyleRule* rule) +RefPtr<Inspector::Protocol::CSS::CSSRule> InspectorCSSAgent::buildObjectForRule(CSSStyleRule* rule) { if (!rule) - return 0; + return nullptr; ASSERT(rule->parentStyleSheet()); InspectorStyleSheet* inspectorStyleSheet = bindStyleSheet(rule->parentStyleSheet()); - return inspectorStyleSheet ? inspectorStyleSheet->buildObjectForRule(rule) : 0; + return inspectorStyleSheet ? inspectorStyleSheet->buildObjectForRule(rule, nullptr) : nullptr; } -PassRefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::CSSRule>> InspectorCSSAgent::buildArrayForRuleList(CSSRuleList* ruleList) +RefPtr<Inspector::Protocol::Array<Inspector::Protocol::CSS::RuleMatch>> InspectorCSSAgent::buildArrayForMatchedRuleList(const Vector<RefPtr<StyleRule>>& matchedRules, StyleResolver& styleResolver, Element& element, PseudoId pseudoId) { - RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::CSSRule>> result = Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::CSSRule>::create(); - if (!ruleList) - return result.release(); + auto result = Inspector::Protocol::Array<Inspector::Protocol::CSS::RuleMatch>::create(); - for (unsigned i = 0, size = ruleList->length(); i < size; ++i) { - CSSStyleRule* rule = asCSSStyleRule(ruleList->item(i)); - RefPtr<Inspector::TypeBuilder::CSS::CSSRule> ruleObject = buildObjectForRule(rule); - if (!ruleObject) - continue; - result->addItem(ruleObject); - } - return result.release(); -} + SelectorChecker::CheckingContext context(SelectorChecker::Mode::CollectingRules); + context.pseudoId = pseudoId ? pseudoId : element.pseudoId(); + SelectorChecker selectorChecker(element.document()); -PassRefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::RuleMatch>> InspectorCSSAgent::buildArrayForMatchedRuleList(const Vector<RefPtr<StyleRuleBase>>& matchedRules, StyleResolver& styleResolver, Element* element) -{ - RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::RuleMatch>> result = Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::RuleMatch>::create(); - - for (unsigned i = 0; i < matchedRules.size(); ++i) { - if (!matchedRules[i]->isStyleRule()) - continue; - StyleRule* matchedStyleRule = static_cast<StyleRule*>(matchedRules[i].get()); - RefPtr<Inspector::TypeBuilder::CSS::CSSRule> ruleObject = buildObjectForRule(matchedStyleRule, styleResolver); + for (auto& matchedRule : matchedRules) { + RefPtr<Inspector::Protocol::CSS::CSSRule> ruleObject = buildObjectForRule(matchedRule.get(), styleResolver, element); if (!ruleObject) continue; - RefPtr<Inspector::TypeBuilder::Array<int>> matchingSelectors = Inspector::TypeBuilder::Array<int>::create(); - const CSSSelectorList& selectorList = matchedStyleRule->selectorList(); - long index = 0; + + auto matchingSelectors = Inspector::Protocol::Array<int>::create(); + const CSSSelectorList& selectorList = matchedRule->selectorList(); + int index = 0; for (const CSSSelector* selector = selectorList.first(); selector; selector = CSSSelectorList::next(selector)) { - bool matched = element->webkitMatchesSelector(selector->selectorText(), IGNORE_EXCEPTION); + unsigned ignoredSpecificity; + bool matched = selectorChecker.match(*selector, element, context, ignoredSpecificity); if (matched) matchingSelectors->addItem(index); ++index; } - RefPtr<Inspector::TypeBuilder::CSS::RuleMatch> match = Inspector::TypeBuilder::CSS::RuleMatch::create() - .setRule(ruleObject) - .setMatchingSelectors(matchingSelectors); - result->addItem(match); + + auto match = Inspector::Protocol::CSS::RuleMatch::create() + .setRule(WTFMove(ruleObject)) + .setMatchingSelectors(WTFMove(matchingSelectors)) + .release(); + result->addItem(WTFMove(match)); } - return result.release(); + return WTFMove(result); } -PassRefPtr<Inspector::TypeBuilder::CSS::CSSStyle> InspectorCSSAgent::buildObjectForAttributesStyle(Element* element) +RefPtr<Inspector::Protocol::CSS::CSSStyle> InspectorCSSAgent::buildObjectForAttributesStyle(Element* element) { - if (!element->isStyledElement()) - return 0; + ASSERT(element); + if (!is<StyledElement>(*element)) + return nullptr; // FIXME: Ugliness below. - StyleProperties* attributeStyle = const_cast<StyleProperties*>(toStyledElement(element)->presentationAttributeStyle()); + StyleProperties* attributeStyle = const_cast<StyleProperties*>(downcast<StyledElement>(element)->presentationAttributeStyle()); if (!attributeStyle) - return 0; + return nullptr; ASSERT_WITH_SECURITY_IMPLICATION(attributeStyle->isMutable()); MutableStyleProperties* mutableAttributeStyle = static_cast<MutableStyleProperties*>(attributeStyle); - RefPtr<InspectorStyle> inspectorStyle = InspectorStyle::create(InspectorCSSId(), mutableAttributeStyle->ensureCSSStyleDeclaration(), 0); + Ref<InspectorStyle> inspectorStyle = InspectorStyle::create(InspectorCSSId(), mutableAttributeStyle->ensureCSSStyleDeclaration(), nullptr); return inspectorStyle->buildObjectForStyle(); } -PassRefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::Region>> InspectorCSSAgent::buildArrayForRegions(ErrorString* errorString, PassRefPtr<NodeList> regionList, int documentNodeId) +RefPtr<Inspector::Protocol::Array<Inspector::Protocol::CSS::Region>> InspectorCSSAgent::buildArrayForRegions(ErrorString& errorString, RefPtr<NodeList>&& regionList, int documentNodeId) { - RefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::Region>> regions = Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::Region>::create(); + auto regions = Inspector::Protocol::Array<Inspector::Protocol::CSS::Region>::create(); for (unsigned i = 0; i < regionList->length(); ++i) { - Inspector::TypeBuilder::CSS::Region::RegionOverset::Enum regionOverset; + Inspector::Protocol::CSS::Region::RegionOverset regionOverset; - switch (toElement(regionList->item(i))->renderRegion()->regionOversetState()) { + switch (downcast<Element>(regionList->item(i))->regionOversetState()) { case RegionFit: - regionOverset = Inspector::TypeBuilder::CSS::Region::RegionOverset::Fit; + regionOverset = Inspector::Protocol::CSS::Region::RegionOverset::Fit; break; case RegionEmpty: - regionOverset = Inspector::TypeBuilder::CSS::Region::RegionOverset::Empty; + regionOverset = Inspector::Protocol::CSS::Region::RegionOverset::Empty; break; case RegionOverset: - regionOverset = Inspector::TypeBuilder::CSS::Region::RegionOverset::Overset; + regionOverset = Inspector::Protocol::CSS::Region::RegionOverset::Overset; break; case RegionUndefined: continue; @@ -1215,66 +1127,52 @@ PassRefPtr<Inspector::TypeBuilder::Array<Inspector::TypeBuilder::CSS::Region>> I continue; } - RefPtr<Inspector::TypeBuilder::CSS::Region> region = Inspector::TypeBuilder::CSS::Region::create() + auto region = Inspector::Protocol::CSS::Region::create() .setRegionOverset(regionOverset) // documentNodeId was previously asserted - .setNodeId(m_domAgent->pushNodeToFrontend(errorString, documentNodeId, regionList->item(i))); + .setNodeId(m_domAgent->pushNodeToFrontend(errorString, documentNodeId, regionList->item(i))) + .release(); - regions->addItem(region); + regions->addItem(WTFMove(region)); } - return regions.release(); + return WTFMove(regions); } -PassRefPtr<Inspector::TypeBuilder::CSS::NamedFlow> InspectorCSSAgent::buildObjectForNamedFlow(ErrorString* errorString, WebKitNamedFlow* webkitNamedFlow, int documentNodeId) +RefPtr<Inspector::Protocol::CSS::NamedFlow> InspectorCSSAgent::buildObjectForNamedFlow(ErrorString& errorString, WebKitNamedFlow* webkitNamedFlow, int documentNodeId) { RefPtr<NodeList> contentList = webkitNamedFlow->getContent(); - RefPtr<Inspector::TypeBuilder::Array<int>> content = Inspector::TypeBuilder::Array<int>::create(); + auto content = Inspector::Protocol::Array<int>::create(); for (unsigned i = 0; i < contentList->length(); ++i) { // documentNodeId was previously asserted content->addItem(m_domAgent->pushNodeToFrontend(errorString, documentNodeId, contentList->item(i))); } - RefPtr<Inspector::TypeBuilder::CSS::NamedFlow> namedFlow = Inspector::TypeBuilder::CSS::NamedFlow::create() + return Inspector::Protocol::CSS::NamedFlow::create() .setDocumentNodeId(documentNodeId) .setName(webkitNamedFlow->name().string()) .setOverset(webkitNamedFlow->overset()) - .setContent(content) - .setRegions(buildArrayForRegions(errorString, webkitNamedFlow->getRegions(), documentNodeId)); - - return namedFlow.release(); + .setContent(WTFMove(content)) + .setRegions(buildArrayForRegions(errorString, webkitNamedFlow->getRegions(), documentNodeId)) + .release(); } -void InspectorCSSAgent::didRemoveDocument(Document* document) +void InspectorCSSAgent::didRemoveDOMNode(Node& node, int nodeId) { - if (document) - m_documentToInspectorStyleSheet.remove(document); -} - -void InspectorCSSAgent::didRemoveDOMNode(Node* node) -{ - if (!node) - return; + m_nodeIdToForcedPseudoState.remove(nodeId); - int nodeId = m_domAgent->boundNodeId(node); - if (nodeId) - m_nodeIdToForcedPseudoState.remove(nodeId); - - NodeToInspectorStyleSheet::iterator it = m_nodeToInspectorStyleSheet.find(node); + auto it = m_nodeToInspectorStyleSheet.find(&node); if (it == m_nodeToInspectorStyleSheet.end()) return; m_idToInspectorStyleSheet.remove(it->value->id()); - m_nodeToInspectorStyleSheet.remove(node); + m_nodeToInspectorStyleSheet.remove(&node); } -void InspectorCSSAgent::didModifyDOMAttr(Element* element) +void InspectorCSSAgent::didModifyDOMAttr(Element& element) { - if (!element) - return; - - NodeToInspectorStyleSheet::iterator it = m_nodeToInspectorStyleSheet.find(element); + auto it = m_nodeToInspectorStyleSheet.find(&element); if (it == m_nodeToInspectorStyleSheet.end()) return; @@ -1283,23 +1181,16 @@ void InspectorCSSAgent::didModifyDOMAttr(Element* element) void InspectorCSSAgent::styleSheetChanged(InspectorStyleSheet* styleSheet) { - if (m_frontendDispatcher) - m_frontendDispatcher->styleSheetChanged(styleSheet->id()); + m_frontendDispatcher->styleSheetChanged(styleSheet->id()); } void InspectorCSSAgent::resetPseudoStates() { - HashSet<Document*> documentsToChange; - for (NodeIdToForcedPseudoState::iterator it = m_nodeIdToForcedPseudoState.begin(), end = m_nodeIdToForcedPseudoState.end(); it != end; ++it) { - if (Element* element = toElement(m_domAgent->nodeForId(it->key))) - documentsToChange.add(&element->document()); - } + for (auto& document : m_documentsWithForcedPseudoStates) + document->styleScope().didChangeStyleSheetEnvironment(); m_nodeIdToForcedPseudoState.clear(); - for (HashSet<Document*>::iterator it = documentsToChange.begin(), end = documentsToChange.end(); it != end; ++it) - (*it)->styleResolverChanged(RecalcStyleImmediately); + m_documentsWithForcedPseudoStates.clear(); } } // namespace WebCore - -#endif // ENABLE(INSPECTOR) |