Commit fe3b2ce3 authored by sergeyv@chromium.org's avatar sergeyv@chromium.org

Devtools [LayoutEditor]: Patch values in the selected rule

BUG=501896

Review URL: https://codereview.chromium.org/1310923003

git-svn-id: svn://svn.chromium.org/blink/trunk@201833 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent d432fc02
...@@ -164,31 +164,6 @@ Running test: testChangeMissingProperty ...@@ -164,31 +164,6 @@ Running test: testChangeMissingProperty
margin-top: 15px !important; margin-top: 15px !important;
} }
Running test: testChangeCSSOMEDProperty
{
padding-top: 55px;
margin-top: 33px !important;
margin-bottom: 101px;
}
*#inspected* { regular readonly
margin-left: 10px;
margin-bottom: 10px;
}
*#inspected* { regular
padding: 10px 20px 30px 40px;
padding-top: 50px;
padding-right: 20px;
padding-bottom: 30px;
padding-left: 40px;
}
@media (min-width: 1px)
*#inspected* { regular
padding-left: 5px;
margin-left: 20px;
padding-left: 10px;
margin-top: 15px !important;
}
Running test: testAppendWithSeparator Running test: testAppendWithSeparator
Dumping inline style: Dumping inline style:
{ {
......
...@@ -73,16 +73,6 @@ function test() ...@@ -73,16 +73,6 @@ function test()
updateProperty("margin-bottom", "101px", dumpUndoAndNext(next)); updateProperty("margin-bottom", "101px", dumpUndoAndNext(next));
}, },
function testChangeCSSOMEDProperty(next)
{
InspectorTest.evaluateInInspectedPage("document.styleSheets[0].cssRules[0].style.marginBottom = \"10px\"", onEvaluate);
function onEvaluate()
{
updateProperty("margin-bottom", "101px", dumpUndoAndNext(next));
}
},
function testAppendWithSeparator(next) function testAppendWithSeparator(next)
{ {
......
...@@ -94,6 +94,32 @@ String createShorthandValue(Document* document, const String& shorthand, const S ...@@ -94,6 +94,32 @@ String createShorthandValue(Document* document, const String& shorthand, const S
return style->getPropertyValue(shorthand); return style->getPropertyValue(shorthand);
} }
PassRefPtrWillBeRawPtr<CSSRuleList> filterDuplicateRules(RefPtrWillBeRawPtr<CSSRuleList> ruleList)
{
RefPtrWillBeRawPtr<StaticCSSRuleList> uniqRuleList = StaticCSSRuleList::create();
if (!ruleList)
return uniqRuleList.release();
HashSet<CSSStyleRule*> uniqRulesSet;
Vector<RefPtrWillBeRawPtr<CSSRule>> uniqRules;
for (unsigned i = ruleList->length(); i > 0; --i) {
CSSRule* rule = ruleList->item(i - 1);
if (!rule || rule->type() != CSSRule::STYLE_RULE)
continue;
CSSStyleRule* styleRule = toCSSStyleRule(rule);
if (uniqRulesSet.contains(styleRule))
continue;
uniqRulesSet.add(styleRule);
uniqRules.append(styleRule);
}
for (unsigned i = uniqRules.size(); i > 0; --i)
uniqRuleList->rules().append(uniqRules[i - 1]);
return uniqRuleList.release();
}
} // namespace } // namespace
namespace CSSAgentState { namespace CSSAgentState {
...@@ -1393,18 +1419,10 @@ PassRefPtr<TypeBuilder::Array<TypeBuilder::CSS::RuleMatch> > InspectorCSSAgent:: ...@@ -1393,18 +1419,10 @@ PassRefPtr<TypeBuilder::Array<TypeBuilder::CSS::RuleMatch> > InspectorCSSAgent::
if (!ruleList) if (!ruleList)
return result.release(); return result.release();
HashSet<CSSStyleRule*> uniqRulesSet; RefPtrWillBeRawPtr<CSSRuleList> uniqRules = filterDuplicateRules(ruleList);
Vector<CSSStyleRule*> uniqRules;
for (unsigned i = ruleList->length(); i > 0; --i) {
CSSStyleRule* rule = asCSSStyleRule(ruleList->item(i - 1));
if (uniqRulesSet.contains(rule))
continue;
uniqRulesSet.add(rule);
uniqRules.append(rule);
}
for (unsigned i = uniqRules.size(); i > 0; --i) { for (unsigned i = 0; i < uniqRules->length(); ++i) {
CSSStyleRule* rule = uniqRules.at(i - 1); CSSStyleRule* rule = asCSSStyleRule(uniqRules->item(i));
RefPtr<TypeBuilder::CSS::CSSRule> ruleObject = buildObjectForRule(rule); RefPtr<TypeBuilder::CSS::CSSRule> ruleObject = buildObjectForRule(rule);
if (!ruleObject) if (!ruleObject)
continue; continue;
...@@ -1515,11 +1533,9 @@ void InspectorCSSAgent::resetPseudoStates() ...@@ -1515,11 +1533,9 @@ void InspectorCSSAgent::resetPseudoStates()
document->setNeedsStyleRecalc(SubtreeStyleChange, StyleChangeReasonForTracing::create(StyleChangeReason::Inspector)); document->setNeedsStyleRecalc(SubtreeStyleChange, StyleChangeReasonForTracing::create(StyleChangeReason::Inspector));
} }
PassRefPtrWillBeRawPtr<CSSStyleDeclaration> InspectorCSSAgent::findEffectiveDeclaration(Element* element, CSSPropertyID propertyId) PassRefPtrWillBeRawPtr<CSSRuleList> InspectorCSSAgent::matchedRulesList(Element* element)
{ {
PseudoId elementPseudoId = element->pseudoId(); PseudoId elementPseudoId = element->pseudoId();
CSSStyleDeclaration* inlineStyle = element->style();
if (elementPseudoId) { if (elementPseudoId) {
element = element->parentOrShadowHostElement(); element = element->parentOrShadowHostElement();
if (!element) if (!element)
...@@ -1531,8 +1547,17 @@ PassRefPtrWillBeRawPtr<CSSStyleDeclaration> InspectorCSSAgent::findEffectiveDecl ...@@ -1531,8 +1547,17 @@ PassRefPtrWillBeRawPtr<CSSStyleDeclaration> InspectorCSSAgent::findEffectiveDecl
if (!ownerDocument->isActive()) if (!ownerDocument->isActive())
return nullptr; return nullptr;
String longhand = getPropertyNameString(propertyId); StyleResolver& styleResolver = ownerDocument->ensureStyleResolver();
element->updateDistribution();
return filterDuplicateRules(styleResolver.pseudoCSSRulesForElement(element, elementPseudoId, StyleResolver::AllCSSRules));
}
PassRefPtrWillBeRawPtr<CSSStyleDeclaration> InspectorCSSAgent::findEffectiveDeclaration(CSSPropertyID propertyId, CSSRuleList* ruleList, CSSStyleDeclaration* inlineStyle)
{
if (!ruleList && !inlineStyle)
return nullptr;
String longhand = getPropertyNameString(propertyId);
RefPtrWillBeRawPtr<CSSStyleDeclaration> foundStyle = nullptr; RefPtrWillBeRawPtr<CSSStyleDeclaration> foundStyle = nullptr;
bool isImportant = false; bool isImportant = false;
...@@ -1541,10 +1566,6 @@ PassRefPtrWillBeRawPtr<CSSStyleDeclaration> InspectorCSSAgent::findEffectiveDecl ...@@ -1541,10 +1566,6 @@ PassRefPtrWillBeRawPtr<CSSStyleDeclaration> InspectorCSSAgent::findEffectiveDecl
isImportant = inlineStyle->getPropertyPriority(longhand) == "important"; isImportant = inlineStyle->getPropertyPriority(longhand) == "important";
} }
StyleResolver& styleResolver = ownerDocument->ensureStyleResolver();
element->updateDistribution();
RefPtrWillBeRawPtr<CSSRuleList> ruleList = styleResolver.pseudoCSSRulesForElement(element, elementPseudoId, StyleResolver::AllCSSRules);
for (unsigned i = 0, size = ruleList ? ruleList->length() : 0; i < size; ++i) { for (unsigned i = 0, size = ruleList ? ruleList->length() : 0; i < size; ++i) {
if (isImportant) if (isImportant)
break; break;
...@@ -1571,39 +1592,16 @@ PassRefPtrWillBeRawPtr<CSSStyleDeclaration> InspectorCSSAgent::findEffectiveDecl ...@@ -1571,39 +1592,16 @@ PassRefPtrWillBeRawPtr<CSSStyleDeclaration> InspectorCSSAgent::findEffectiveDecl
return foundStyle.release(); return foundStyle.release();
} }
void InspectorCSSAgent::setCSSPropertyValue(ErrorString* errorString, Element* element, CSSPropertyID propertyId, const String& value) void InspectorCSSAgent::setCSSPropertyValue(ErrorString* errorString, Element* element, RefPtrWillBeRawPtr<CSSStyleDeclaration> style, CSSPropertyID propertyId, const String& value, bool forceImportant)
{ {
Document* ownerDocument = element->ownerDocument();
if (!ownerDocument->isActive()) {
*errorString = "Can't edit a node from a non-active document";
return;
}
Vector<StylePropertyShorthand, 4> shorthands;
getMatchingShorthandsForLonghand(propertyId, &shorthands);
String shorthand = shorthands.size() > 0 ? getPropertyNameString(shorthands[0].id()) : String();
String longhand = getPropertyNameString(propertyId);
RefPtrWillBeRawPtr<CSSStyleDeclaration> foundStyle = findEffectiveDeclaration(element, propertyId);
CSSStyleDeclaration* inlineStyle = element->style();
if (!foundStyle || !foundStyle->parentStyleSheet())
foundStyle = inlineStyle;
if (!foundStyle) {
*errorString = "Can't find a style to edit";
return;
}
InspectorStyleSheetBase* inspectorStyleSheet = nullptr; InspectorStyleSheetBase* inspectorStyleSheet = nullptr;
RefPtrWillBeRawPtr<CSSRuleSourceData> sourceData = nullptr; RefPtrWillBeRawPtr<CSSRuleSourceData> sourceData = nullptr;
if (foundStyle != inlineStyle) { // An absence of the parent rule means that given style is an inline style.
InspectorStyleSheet* styleSheet = bindStyleSheet(foundStyle->parentStyleSheet()); if (style->parentRule()) {
InspectorStyleSheet* styleSheet = bindStyleSheet(style->parentStyleSheet());
inspectorStyleSheet = styleSheet; inspectorStyleSheet = styleSheet;
sourceData = styleSheet->sourceDataForRule(foundStyle->parentRule()); sourceData = styleSheet->sourceDataForRule(style->parentRule());
} } else {
if (!sourceData) {
InspectorStyleSheetForInlineStyle* inlineStyleSheet = asInspectorStyleSheet(element); InspectorStyleSheetForInlineStyle* inlineStyleSheet = asInspectorStyleSheet(element);
inspectorStyleSheet = inlineStyleSheet; inspectorStyleSheet = inlineStyleSheet;
sourceData = inlineStyleSheet->ruleSourceData(); sourceData = inlineStyleSheet->ruleSourceData();
...@@ -1614,6 +1612,12 @@ void InspectorCSSAgent::setCSSPropertyValue(ErrorString* errorString, Element* e ...@@ -1614,6 +1612,12 @@ void InspectorCSSAgent::setCSSPropertyValue(ErrorString* errorString, Element* e
return; return;
} }
Vector<StylePropertyShorthand, 4> shorthands;
getMatchingShorthandsForLonghand(propertyId, &shorthands);
String shorthand = shorthands.size() > 0 ? getPropertyNameString(shorthands[0].id()) : String();
String longhand = getPropertyNameString(propertyId);
int foundIndex = -1; int foundIndex = -1;
WillBeHeapVector<CSSPropertySourceData> properties = sourceData->styleSourceData->propertyData; WillBeHeapVector<CSSPropertySourceData> properties = sourceData->styleSourceData->propertyData;
for (unsigned i = 0; i < properties.size(); ++i) { for (unsigned i = 0; i < properties.size(); ++i) {
...@@ -1638,8 +1642,7 @@ void InspectorCSSAgent::setCSSPropertyValue(ErrorString* errorString, Element* e ...@@ -1638,8 +1642,7 @@ void InspectorCSSAgent::setCSSPropertyValue(ErrorString* errorString, Element* e
String styleText = styleSheetText.substring(bodyRange.start, bodyRange.length()); String styleText = styleSheetText.substring(bodyRange.start, bodyRange.length());
SourceRange changeRange; SourceRange changeRange;
if (foundIndex == -1) { if (foundIndex == -1) {
bool isImportant = inlineStyle->getPropertyPriority(longhand) == "important"; String newPropertyText = "\n" + longhand + ": " + value + (forceImportant ? " !important" : "") + ";";
String newPropertyText = "\n" + longhand + ": " + value + (isImportant ? " !important" : "") + ";";
if (!styleText.isEmpty() && !styleText.stripWhiteSpace().endsWith(';')) if (!styleText.isEmpty() && !styleText.stripWhiteSpace().endsWith(';'))
newPropertyText = ";" + newPropertyText; newPropertyText = ";" + newPropertyText;
styleText.append(newPropertyText); styleText.append(newPropertyText);
...@@ -1649,11 +1652,11 @@ void InspectorCSSAgent::setCSSPropertyValue(ErrorString* errorString, Element* e ...@@ -1649,11 +1652,11 @@ void InspectorCSSAgent::setCSSPropertyValue(ErrorString* errorString, Element* e
CSSPropertySourceData declaration = properties[foundIndex]; CSSPropertySourceData declaration = properties[foundIndex];
String newValueText; String newValueText;
if (declaration.name == shorthand) if (declaration.name == shorthand)
newValueText = createShorthandValue(ownerDocument, shorthand, declaration.value, longhand, value); newValueText = createShorthandValue(element->ownerDocument(), shorthand, declaration.value, longhand, value);
else else
newValueText = value; newValueText = value;
String newPropertyText = declaration.name + ": " + newValueText + (declaration.important ? " !important" : "") + ";"; String newPropertyText = declaration.name + ": " + newValueText + (declaration.important || forceImportant ? " !important" : "") + ";";
styleText.replace(declaration.range.start - bodyRange.start, declaration.range.length(), newPropertyText); styleText.replace(declaration.range.start - bodyRange.start, declaration.range.length(), newPropertyText);
changeRange.start = declaration.range.start; changeRange.start = declaration.range.start;
changeRange.end = changeRange.start + newPropertyText.length(); changeRange.end = changeRange.start + newPropertyText.length();
...@@ -1667,6 +1670,7 @@ void InspectorCSSAgent::setCSSPropertyValue(ErrorString* errorString, Element* e ...@@ -1667,6 +1670,7 @@ void InspectorCSSAgent::setCSSPropertyValue(ErrorString* errorString, Element* e
void InspectorCSSAgent::setEffectivePropertyValueForNode(ErrorString* errorString, int nodeId, const String& propertyName, const String& value) void InspectorCSSAgent::setEffectivePropertyValueForNode(ErrorString* errorString, int nodeId, const String& propertyName, const String& value)
{ {
// TODO: move testing from CSSAgent to layout editor.
Element* element = elementForId(errorString, nodeId); Element* element = elementForId(errorString, nodeId);
if (!element) if (!element)
return; return;
...@@ -1676,7 +1680,26 @@ void InspectorCSSAgent::setEffectivePropertyValueForNode(ErrorString* errorStrin ...@@ -1676,7 +1680,26 @@ void InspectorCSSAgent::setEffectivePropertyValueForNode(ErrorString* errorStrin
*errorString = "Invalid property name"; *errorString = "Invalid property name";
return; return;
} }
setCSSPropertyValue(errorString, element, cssPropertyID(propertyName), value);
Document* ownerDocument = element->ownerDocument();
if (!ownerDocument->isActive()) {
*errorString = "Can't edit a node from a non-active document";
return;
}
CSSPropertyID propertyId = cssPropertyID(propertyName);
CSSStyleDeclaration* inlineStyle = element->style();
RefPtrWillBeRawPtr<CSSRuleList> ruleList = matchedRulesList(element);
RefPtrWillBeRawPtr<CSSStyleDeclaration> foundStyle = findEffectiveDeclaration(propertyId, ruleList.get(), inlineStyle);
if (!foundStyle || !foundStyle->parentStyleSheet())
foundStyle = inlineStyle;
if (!foundStyle) {
*errorString = "Can't find a style to edit";
return;
}
setCSSPropertyValue(errorString, element, foundStyle.get(), propertyId, value);
} }
DEFINE_TRACE(InspectorCSSAgent) DEFINE_TRACE(InspectorCSSAgent)
......
...@@ -115,7 +115,6 @@ public: ...@@ -115,7 +115,6 @@ public:
void disable(ErrorString*) override; void disable(ErrorString*) override;
void reset(); void reset();
void mediaQueryResultChanged(); void mediaQueryResultChanged();
void setCSSPropertyValue(ErrorString*, Element*, CSSPropertyID, const String&);
void activeStyleSheetsUpdated(Document*); void activeStyleSheetsUpdated(Document*);
void documentDetached(Document*); void documentDetached(Document*);
...@@ -145,8 +144,11 @@ public: ...@@ -145,8 +144,11 @@ public:
void collectMediaQueriesFromStyleSheet(CSSStyleSheet*, TypeBuilder::Array<TypeBuilder::CSS::CSSMedia>* mediaArray); void collectMediaQueriesFromStyleSheet(CSSStyleSheet*, TypeBuilder::Array<TypeBuilder::CSS::CSSMedia>* mediaArray);
PassRefPtr<TypeBuilder::CSS::CSSMedia> buildMediaObject(const MediaList*, MediaListSource, const String&, CSSStyleSheet*); PassRefPtr<TypeBuilder::CSS::CSSMedia> buildMediaObject(const MediaList*, MediaListSource, const String&, CSSStyleSheet*);
PassRefPtr<TypeBuilder::Array<TypeBuilder::CSS::CSSMedia> > buildMediaListChain(CSSRule*); PassRefPtr<TypeBuilder::Array<TypeBuilder::CSS::CSSMedia> > buildMediaListChain(CSSRule*);
PassRefPtrWillBeRawPtr<CSSStyleDeclaration> findEffectiveDeclaration(Element*, CSSPropertyID);
PassRefPtrWillBeRawPtr<CSSStyleDeclaration> findEffectiveDeclaration(CSSPropertyID, CSSRuleList* matchedRulesList, CSSStyleDeclaration* inlineStyle);
void setCSSPropertyValue(ErrorString*, Element*, RefPtrWillBeRawPtr<CSSStyleDeclaration>, CSSPropertyID, const String& value, bool forceImportant = false);
PassRefPtrWillBeRawPtr<CSSRuleList> matchedRulesList(Element*);
private: private:
class StyleSheetAction; class StyleSheetAction;
class SetStyleSheetTextAction; class SetStyleSheetTextAction;
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
#include "core/css/CSSComputedStyleDeclaration.h" #include "core/css/CSSComputedStyleDeclaration.h"
#include "core/css/CSSImportRule.h" #include "core/css/CSSImportRule.h"
#include "core/css/CSSMediaRule.h" #include "core/css/CSSMediaRule.h"
#include "core/css/CSSRuleList.h" #include "core/css/CSSStyleRule.h"
#include "core/css/MediaList.h" #include "core/css/MediaList.h"
#include "core/dom/NodeComputedStyle.h" #include "core/dom/NodeComputedStyle.h"
#include "core/dom/StaticNodeList.h" #include "core/dom/StaticNodeList.h"
...@@ -145,11 +145,6 @@ float toValidValue(CSSPropertyID propertyId, float newValue) ...@@ -145,11 +145,6 @@ float toValidValue(CSSPropertyID propertyId, float newValue)
return newValue; return newValue;
} }
bool comparePairs(const std::pair<unsigned, CSSStyleRule*>& lhs, const std::pair<unsigned, CSSStyleRule*>& rhs)
{
return lhs.first < rhs.first;
}
InspectorHighlightConfig affectedNodesHighlightConfig() InspectorHighlightConfig affectedNodesHighlightConfig()
{ {
// TODO: find a better color // TODO: find a better color
...@@ -209,7 +204,8 @@ LayoutEditor::LayoutEditor(InspectorCSSAgent* cssAgent, InspectorDOMAgent* domAg ...@@ -209,7 +204,8 @@ LayoutEditor::LayoutEditor(InspectorCSSAgent* cssAgent, InspectorDOMAgent* domAg
, m_changingProperty(CSSPropertyInvalid) , m_changingProperty(CSSPropertyInvalid)
, m_propertyInitialValue(0) , m_propertyInitialValue(0)
, m_isDirty(false) , m_isDirty(false)
, m_currentRuleIndex(-1) , m_matchedRules(StaticCSSRuleList::create())
, m_currentRuleIndex(0)
{ {
} }
...@@ -231,7 +227,8 @@ void LayoutEditor::selectNode(Node* node) ...@@ -231,7 +227,8 @@ void LayoutEditor::selectNode(Node* node)
m_element = element; m_element = element;
m_changingProperty = CSSPropertyInvalid; m_changingProperty = CSSPropertyInvalid;
m_propertyInitialValue = 0; m_propertyInitialValue = 0;
initializeCSSRules(); m_matchedRules = m_cssAgent->matchedRulesList(m_element.get());
m_currentRuleIndex = m_matchedRules->length();
} }
PassRefPtr<JSONObject> LayoutEditor::buildJSONInfo() const PassRefPtr<JSONObject> LayoutEditor::buildJSONInfo() const
...@@ -265,7 +262,7 @@ PassRefPtr<JSONObject> LayoutEditor::buildJSONInfo() const ...@@ -265,7 +262,7 @@ PassRefPtr<JSONObject> LayoutEditor::buildJSONInfo() const
RefPtrWillBeRawPtr<CSSPrimitiveValue> LayoutEditor::getPropertyCSSValue(CSSPropertyID property) const RefPtrWillBeRawPtr<CSSPrimitiveValue> LayoutEditor::getPropertyCSSValue(CSSPropertyID property) const
{ {
RefPtrWillBeRawPtr<CSSStyleDeclaration> style = m_cssAgent->findEffectiveDeclaration(m_element.get(), property); RefPtrWillBeRawPtr<CSSStyleDeclaration> style = m_cssAgent->findEffectiveDeclaration(property, m_matchedRules.get(), m_element->style());
if (!style) if (!style)
return nullptr; return nullptr;
...@@ -332,11 +329,8 @@ void LayoutEditor::overlayStartedPropertyChange(const String& anchorName) ...@@ -332,11 +329,8 @@ void LayoutEditor::overlayStartedPropertyChange(const String& anchorName)
void LayoutEditor::overlayPropertyChanged(float cssDelta) void LayoutEditor::overlayPropertyChanged(float cssDelta)
{ {
if (m_changingProperty && m_factor) { if (m_changingProperty && m_factor) {
String errorString;
float newValue = toValidValue(m_changingProperty, cssDelta / m_factor + m_propertyInitialValue); float newValue = toValidValue(m_changingProperty, cssDelta / m_factor + m_propertyInitialValue);
m_cssAgent->setCSSPropertyValue(&errorString, m_element.get(), m_changingProperty, truncateZeroes(String::format("%.2f", newValue)) + CSSPrimitiveValue::unitTypeToString(m_valueUnitType)); m_isDirty |= setCSSPropertyValueInCurrentRule(truncateZeroes(String::format("%.2f", newValue)) + CSSPrimitiveValue::unitTypeToString(m_valueUnitType));
if (!errorString)
m_isDirty = true;
} }
} }
...@@ -358,69 +352,29 @@ void LayoutEditor::clearSelection(bool commitChanges) ...@@ -358,69 +352,29 @@ void LayoutEditor::clearSelection(bool commitChanges)
m_element.clear(); m_element.clear();
m_isDirty = false; m_isDirty = false;
m_matchedRules.clear(); m_matchedRules = StaticCSSRuleList::create();
m_currentRuleIndex = -1; m_currentRuleIndex = 0;
} }
void LayoutEditor::initializeCSSRules() bool LayoutEditor::currentStyleIsInline()
{ {
if (!m_element) return m_currentRuleIndex == m_matchedRules->length();
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::make_pair(length, uniqRules[i]));
}
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() void LayoutEditor::nextSelector()
{ {
if (static_cast<size_t>(m_currentRuleIndex + 1) == m_matchedRules.size()) if (m_currentRuleIndex == 0)
return; return;
m_currentRuleIndex++; m_currentRuleIndex--;
} }
void LayoutEditor::previousSelector() void LayoutEditor::previousSelector()
{ {
if (m_currentRuleIndex == -1) if (currentStyleIsInline())
return; return;
m_currentRuleIndex--; m_currentRuleIndex++;
} }
String LayoutEditor::currentSelectorInfo() String LayoutEditor::currentSelectorInfo()
...@@ -429,35 +383,33 @@ String LayoutEditor::currentSelectorInfo() ...@@ -429,35 +383,33 @@ String LayoutEditor::currentSelectorInfo()
return String(); return String();
RefPtr<JSONObject> object = JSONObject::create(); RefPtr<JSONObject> object = JSONObject::create();
String currentSelectorText = m_currentRuleIndex == -1 ? "inline style" : m_matchedRules[m_currentRuleIndex]->selectorText(); String currentSelectorText = currentStyleIsInline() ? "inline style" : toCSSStyleRule(m_matchedRules->item(m_currentRuleIndex))->selectorText();
object->setString("selector", currentSelectorText); object->setString("selector", currentSelectorText);
Document* ownerDocument = m_element->ownerDocument(); Document* ownerDocument = m_element->ownerDocument();
if (!ownerDocument->isActive() || m_currentRuleIndex == -1) if (!ownerDocument->isActive() || currentStyleIsInline())
return object->toJSONString(); return object->toJSONString();
if (m_currentRuleIndex != -1) { bool hasSameSelectors = false;
bool hasSameSelectors = false; for (unsigned i = 0; i < m_matchedRules->length(); i++) {
for (size_t i = 0; i < m_matchedRules.size(); i++) { if (i != m_currentRuleIndex && toCSSStyleRule(m_matchedRules->item(i))->selectorText() == currentSelectorText) {
if (i != static_cast<unsigned>(m_currentRuleIndex) && m_matchedRules[i]->selectorText() == currentSelectorText) { hasSameSelectors = true;
hasSameSelectors = true; break;
break;
}
} }
}
if (hasSameSelectors) { if (hasSameSelectors) {
Vector<String> medias; Vector<String> medias;
buildMediaListChain(m_matchedRules[m_currentRuleIndex].get(), medias); buildMediaListChain(m_matchedRules->item(m_currentRuleIndex), medias);
RefPtr<JSONArray> mediasJSONArray = JSONArray::create(); RefPtr<JSONArray> mediasJSONArray = JSONArray::create();
for (size_t i = 0; i < medias.size(); ++i) for (size_t i = 0; i < medias.size(); ++i)
mediasJSONArray->pushString(medias[i]); mediasJSONArray->pushString(medias[i]);
object->setArray("medias", mediasJSONArray.release()); object->setArray("medias", mediasJSONArray.release());
}
} }
TrackExceptionState exceptionState; TrackExceptionState exceptionState;
RefPtrWillBeRawPtr<StaticElementList> elements = ownerDocument->querySelectorAll(AtomicString(m_matchedRules[m_currentRuleIndex]->selectorText()), exceptionState); RefPtrWillBeRawPtr<StaticElementList> elements = ownerDocument->querySelectorAll(AtomicString(currentSelectorText), exceptionState);
if (!elements || exceptionState.hadException()) if (!elements || exceptionState.hadException())
return object->toJSONString(); return object->toJSONString();
...@@ -477,4 +429,35 @@ String LayoutEditor::currentSelectorInfo() ...@@ -477,4 +429,35 @@ String LayoutEditor::currentSelectorInfo()
return object->toJSONString(); return object->toJSONString();
} }
bool LayoutEditor::setCSSPropertyValueInCurrentRule(const String& value)
{
if (!m_element)
return false;
RefPtrWillBeRawPtr<CSSStyleDeclaration> effectiveDeclaration = m_cssAgent->findEffectiveDeclaration(m_changingProperty, m_matchedRules.get(), m_element->style());
bool forceImportant = false;
if (effectiveDeclaration) {
CSSStyleRule* effectiveRule = nullptr;
if (effectiveDeclaration->parentRule() && effectiveDeclaration->parentRule()->type() == CSSRule::STYLE_RULE)
effectiveRule = toCSSStyleRule(effectiveDeclaration->parentRule());
unsigned effectiveRuleIndex = m_matchedRules->length();
for (unsigned i = 0; i < m_matchedRules->length(); ++i) {
if (m_matchedRules->item(i) == effectiveRule) {
effectiveRuleIndex = i;
break;
}
}
forceImportant = effectiveDeclaration->getPropertyPriority(getPropertyNameString(m_changingProperty)) == "important";
forceImportant |= effectiveRuleIndex > m_currentRuleIndex;
}
CSSStyleDeclaration* style = currentStyleIsInline() ? m_element->style() : toCSSStyleRule(m_matchedRules->item(m_currentRuleIndex))->style();
String errorString;
m_cssAgent->setCSSPropertyValue(&errorString, m_element.get(), style, m_changingProperty, value, forceImportant);
return errorString.isEmpty();
}
} // namespace blink } // namespace blink
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
#include "core/CSSPropertyNames.h" #include "core/CSSPropertyNames.h"
#include "core/CoreExport.h" #include "core/CoreExport.h"
#include "core/css/CSSPrimitiveValue.h" #include "core/css/CSSPrimitiveValue.h"
#include "core/css/CSSStyleRule.h" #include "core/css/CSSRuleList.h"
#include "core/dom/Element.h" #include "core/dom/Element.h"
#include "platform/heap/Handle.h" #include "platform/heap/Handle.h"
#include "wtf/PassOwnPtr.h" #include "wtf/PassOwnPtr.h"
...@@ -49,7 +49,8 @@ private: ...@@ -49,7 +49,8 @@ private:
RefPtrWillBeRawPtr<CSSPrimitiveValue> getPropertyCSSValue(CSSPropertyID) const; RefPtrWillBeRawPtr<CSSPrimitiveValue> getPropertyCSSValue(CSSPropertyID) const;
PassRefPtr<JSONObject> createValueDescription(const String&) const; PassRefPtr<JSONObject> createValueDescription(const String&) const;
void appendAnchorFor(JSONArray*, const String&, const String&, const FloatPoint&, const FloatPoint&) const; void appendAnchorFor(JSONArray*, const String&, const String&, const FloatPoint&, const FloatPoint&) const;
void initializeCSSRules(); bool setCSSPropertyValueInCurrentRule(const String&);
bool currentStyleIsInline();
RefPtrWillBeMember<Element> m_element; RefPtrWillBeMember<Element> m_element;
RawPtrWillBeMember<InspectorCSSAgent> m_cssAgent; RawPtrWillBeMember<InspectorCSSAgent> m_cssAgent;
...@@ -60,9 +61,9 @@ private: ...@@ -60,9 +61,9 @@ private:
CSSPrimitiveValue::UnitType m_valueUnitType; CSSPrimitiveValue::UnitType m_valueUnitType;
bool m_isDirty; bool m_isDirty;
WillBeHeapVector<RefPtrWillBeMember<CSSStyleRule>> m_matchedRules; RefPtrWillBeRawPtr<CSSRuleList> m_matchedRules;
// -1 means "inline style". // When m_currentRuleIndex == m_matchedRules.length(), current style is inline style.
int m_currentRuleIndex; unsigned m_currentRuleIndex;
}; };
} // namespace blink } // namespace blink
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment