Chromium Code Reviews| Index: Source/core/inspector/LayoutEditor.cpp |
| diff --git a/Source/core/inspector/LayoutEditor.cpp b/Source/core/inspector/LayoutEditor.cpp |
| index 8723663dd735be2471e54a60f561f10e6235daa0..a73d6705d131b402d0f89d9eb72f68b8a7035046 100644 |
| --- a/Source/core/inspector/LayoutEditor.cpp |
| +++ b/Source/core/inspector/LayoutEditor.cpp |
| @@ -6,7 +6,9 @@ |
| #include "core/inspector/LayoutEditor.h" |
| #include "core/css/CSSComputedStyleDeclaration.h" |
| +#include "core/css/CSSRuleList.h" |
| #include "core/dom/NodeComputedStyle.h" |
| +#include "core/dom/StaticNodeList.h" |
| #include "core/frame/FrameView.h" |
| #include "core/inspector/InspectorCSSAgent.h" |
| #include "core/inspector/InspectorDOMAgent.h" |
| @@ -139,6 +141,22 @@ float toValidValue(CSSPropertyID propertyId, float newValue) |
| return newValue; |
| } |
| + |
| +bool comparePairs(const std::pair<unsigned, CSSStyleRule*>& lhs, const std::pair<unsigned, CSSStyleRule*>& rhs) |
| +{ |
| + return lhs.first < rhs.first; |
| +} |
| + |
| +InspectorHighlightConfig affectedNodesHighlightConfig() |
| +{ |
| + // TODO: find a better color |
| + InspectorHighlightConfig config; |
| + config.content = Color(95, 127, 162, 100); |
| + config.padding = Color(95, 127, 162, 100); |
| + config.margin = Color(95, 127, 162, 100); |
| + return config; |
| +} |
| + |
| } // namespace |
| LayoutEditor::LayoutEditor(InspectorCSSAgent* cssAgent, InspectorDOMAgent* domAgent) |
| @@ -156,6 +174,7 @@ DEFINE_TRACE(LayoutEditor) |
| visitor->trace(m_element); |
| visitor->trace(m_cssAgent); |
| visitor->trace(m_domAgent); |
| + visitor->trace(m_matchedRules); |
| } |
| void LayoutEditor::selectNode(Node* node) |
| @@ -168,7 +187,7 @@ void LayoutEditor::selectNode(Node* node) |
| m_element = element; |
| m_changingProperty = CSSPropertyInvalid; |
| m_propertyInitialValue = 0; |
| - |
| + initializeCSSRules(); |
| } |
| PassRefPtr<JSONObject> LayoutEditor::buildJSONInfo() const |
| @@ -223,7 +242,6 @@ PassRefPtr<JSONObject> LayoutEditor::createValueDescription(const String& proper |
| object->setNumber("value", cssValue ? cssValue->getFloatValue() : 0); |
| CSSPrimitiveValue::UnitType unitType = cssValue ? cssValue->typeWithCalcResolved() : CSSPrimitiveValue::UnitType::Pixels; |
| object->setString("unit", CSSPrimitiveValue::unitTypeToString(unitType)); |
| - // TODO: Support an editing of other popular units like: em, rem |
| object->setBoolean("mutable", isMutableUnitType(unitType)); |
| return object.release(); |
| } |
| @@ -298,6 +316,100 @@ void LayoutEditor::clearSelection(bool commitChanges) |
| m_isDirty = false; |
| } |
| +void LayoutEditor::initializeCSSRules() |
| +{ |
| + m_matchedRules.clear(); |
|
dgozman
2015/09/02 18:58:57
Please also clear rules on commit/discard.
sergeyv
2015/09/02 20:22:18
Done.
|
| + m_currentRuleIndex = -1; |
| + if (!m_element) |
| + return; |
| + |
| + Document* ownerDocument = m_element->ownerDocument(); |
| + // A non-active document has no styles. |
| + if (!ownerDocument->isActive()) |
| + return; |
| + |
| + // Matched rules. |
| + StyleResolver& styleResolver = ownerDocument->ensureStyleResolver(); |
| + PseudoId elementPseudoId = m_element->pseudoId(); |
| + m_element->updateDistribution(); |
| + RefPtrWillBeRawPtr<CSSRuleList> matchedRules = styleResolver.pseudoCSSRulesForElement(m_element.get(), elementPseudoId, StyleResolver::AllCSSRules); |
| + if (!matchedRules) |
| + return; |
| + |
| + HashSet<CSSStyleRule*> uniqRulesSet; |
| + Vector<CSSStyleRule*> uniqRules; |
| + for (unsigned i = matchedRules->length(); i > 0; --i) { |
| + CSSRule* rule = matchedRules->item(i); |
| + if (!rule || rule->type() != CSSRule::STYLE_RULE || !rule->parentStyleSheet()) |
| + continue; |
| + |
| + CSSStyleRule* styleRule = toCSSStyleRule(rule); |
| + if (uniqRulesSet.contains(styleRule)) |
| + continue; |
| + uniqRulesSet.add(styleRule); |
| + uniqRules.append(styleRule); |
| + } |
| + Vector<std::pair<unsigned, CSSStyleRule*>> selectors; |
| + for (unsigned i = 0; i < uniqRules.size(); ++i) { |
| + TrackExceptionState exceptionState; |
| + RefPtrWillBeRawPtr<StaticElementList> elements = ownerDocument->querySelectorAll(AtomicString(uniqRules[i]->selectorText()), exceptionState); |
| + unsigned length = exceptionState.hadException() ? 0: elements->length(); |
| + selectors.append(std::pair<unsigned, CSSStyleRule*>(length, uniqRules[i])); |
|
dgozman
2015/09/02 18:58:57
make_pair?
sergeyv
2015/09/02 20:22:18
Done.
|
| + } |
| + |
| + std::sort(selectors.begin(), selectors.end(), &comparePairs); |
| + for (size_t i = 0; i < selectors.size(); ++i) |
| + m_matchedRules.append(selectors[i].second); |
| +}; |
| + |
| +void LayoutEditor::nextSelector() |
| +{ |
| + if (static_cast<size_t>(m_currentRuleIndex + 1) == m_matchedRules.size()) |
| + return; |
| + |
| + m_currentRuleIndex++; |
| +} |
| + |
| +void LayoutEditor::previousSelector() |
| +{ |
| + if (m_currentRuleIndex == -1) |
| + return; |
| + |
| + m_currentRuleIndex--; |
| +} |
| + |
| +String LayoutEditor::currentSelectorInfo() |
|
dgozman
2015/09/02 18:58:57
Let's cache the result.
sergeyv
2015/09/02 20:22:18
Done.
|
| +{ |
| + if (!m_element) |
| + return emptyString(); |
|
dgozman
2015/09/02 18:58:57
String()
sergeyv
2015/09/02 20:22:18
Done.
|
| + |
| + RefPtr<JSONObject> object = JSONObject::create(); |
| + String currentSelectorText = m_currentRuleIndex == -1 ? "inline style" : m_matchedRules[m_currentRuleIndex]->selectorText(); |
| + object->setString("selector", currentSelectorText); |
| + |
| + Document* ownerDocument = m_element->ownerDocument(); |
| + if (!ownerDocument->isActive() || m_currentRuleIndex == -1) |
| + return object->toJSONString(); |
| + |
| + TrackExceptionState exceptionState; |
| + RefPtrWillBeRawPtr<StaticElementList> elements = ownerDocument->querySelectorAll(AtomicString(m_matchedRules[m_currentRuleIndex]->selectorText()), exceptionState); |
| + |
| + if (!elements || exceptionState.hadException()) |
| + return object->toJSONString(); |
| + |
| + RefPtr<JSONArray> highlights = JSONArray::create(); |
| + for (unsigned i = 0; i < elements->length(); ++i) { |
| + Element* element = elements->item(i); |
| + if (element == m_element) |
| + continue; |
| + |
| + InspectorHighlight highlight(element, affectedNodesHighlightConfig(), false); |
|
dgozman
2015/09/02 18:58:57
nit: extract config into var.
sergeyv
2015/09/02 20:22:18
Done.
|
| + highlights->pushObject(highlight.asJSONObject()); |
| + } |
| + |
| + object->setArray("nodes", highlights.release()); |
| + return object->toJSONString(); |
| +} |
| } // namespace blink |