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
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
Dumping inline style:
{
......
......@@ -73,16 +73,6 @@ function test()
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)
{
......
......@@ -94,6 +94,32 @@ String createShorthandValue(Document* document, const String& shorthand, const S
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 CSSAgentState {
......@@ -1393,18 +1419,10 @@ PassRefPtr<TypeBuilder::Array<TypeBuilder::CSS::RuleMatch> > InspectorCSSAgent::
if (!ruleList)
return result.release();
HashSet<CSSStyleRule*> uniqRulesSet;
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);
}
RefPtrWillBeRawPtr<CSSRuleList> uniqRules = filterDuplicateRules(ruleList);
for (unsigned i = uniqRules.size(); i > 0; --i) {
CSSStyleRule* rule = uniqRules.at(i - 1);
for (unsigned i = 0; i < uniqRules->length(); ++i) {
CSSStyleRule* rule = asCSSStyleRule(uniqRules->item(i));
RefPtr<TypeBuilder::CSS::CSSRule> ruleObject = buildObjectForRule(rule);
if (!ruleObject)
continue;
......@@ -1515,11 +1533,9 @@ void InspectorCSSAgent::resetPseudoStates()
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();
CSSStyleDeclaration* inlineStyle = element->style();
if (elementPseudoId) {
element = element->parentOrShadowHostElement();
if (!element)
......@@ -1531,8 +1547,17 @@ PassRefPtrWillBeRawPtr<CSSStyleDeclaration> InspectorCSSAgent::findEffectiveDecl
if (!ownerDocument->isActive())
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;
bool isImportant = false;
......@@ -1541,10 +1566,6 @@ PassRefPtrWillBeRawPtr<CSSStyleDeclaration> InspectorCSSAgent::findEffectiveDecl
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) {
if (isImportant)
break;
......@@ -1571,39 +1592,16 @@ PassRefPtrWillBeRawPtr<CSSStyleDeclaration> InspectorCSSAgent::findEffectiveDecl
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;
RefPtrWillBeRawPtr<CSSRuleSourceData> sourceData = nullptr;
if (foundStyle != inlineStyle) {
InspectorStyleSheet* styleSheet = bindStyleSheet(foundStyle->parentStyleSheet());
// An absence of the parent rule means that given style is an inline style.
if (style->parentRule()) {
InspectorStyleSheet* styleSheet = bindStyleSheet(style->parentStyleSheet());
inspectorStyleSheet = styleSheet;
sourceData = styleSheet->sourceDataForRule(foundStyle->parentRule());
}
if (!sourceData) {
sourceData = styleSheet->sourceDataForRule(style->parentRule());
} else {
InspectorStyleSheetForInlineStyle* inlineStyleSheet = asInspectorStyleSheet(element);
inspectorStyleSheet = inlineStyleSheet;
sourceData = inlineStyleSheet->ruleSourceData();
......@@ -1614,6 +1612,12 @@ void InspectorCSSAgent::setCSSPropertyValue(ErrorString* errorString, Element* e
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;
WillBeHeapVector<CSSPropertySourceData> properties = sourceData->styleSourceData->propertyData;
for (unsigned i = 0; i < properties.size(); ++i) {
......@@ -1638,8 +1642,7 @@ void InspectorCSSAgent::setCSSPropertyValue(ErrorString* errorString, Element* e
String styleText = styleSheetText.substring(bodyRange.start, bodyRange.length());
SourceRange changeRange;
if (foundIndex == -1) {
bool isImportant = inlineStyle->getPropertyPriority(longhand) == "important";
String newPropertyText = "\n" + longhand + ": " + value + (isImportant ? " !important" : "") + ";";
String newPropertyText = "\n" + longhand + ": " + value + (forceImportant ? " !important" : "") + ";";
if (!styleText.isEmpty() && !styleText.stripWhiteSpace().endsWith(';'))
newPropertyText = ";" + newPropertyText;
styleText.append(newPropertyText);
......@@ -1649,11 +1652,11 @@ void InspectorCSSAgent::setCSSPropertyValue(ErrorString* errorString, Element* e
CSSPropertySourceData declaration = properties[foundIndex];
String newValueText;
if (declaration.name == shorthand)
newValueText = createShorthandValue(ownerDocument, shorthand, declaration.value, longhand, value);
newValueText = createShorthandValue(element->ownerDocument(), shorthand, declaration.value, longhand, value);
else
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);
changeRange.start = declaration.range.start;
changeRange.end = changeRange.start + newPropertyText.length();
......@@ -1667,6 +1670,7 @@ void InspectorCSSAgent::setCSSPropertyValue(ErrorString* errorString, Element* e
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);
if (!element)
return;
......@@ -1676,7 +1680,26 @@ void InspectorCSSAgent::setEffectivePropertyValueForNode(ErrorString* errorStrin
*errorString = "Invalid property name";
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)
......
......@@ -115,7 +115,6 @@ public:
void disable(ErrorString*) override;
void reset();
void mediaQueryResultChanged();
void setCSSPropertyValue(ErrorString*, Element*, CSSPropertyID, const String&);
void activeStyleSheetsUpdated(Document*);
void documentDetached(Document*);
......@@ -145,8 +144,11 @@ public:
void collectMediaQueriesFromStyleSheet(CSSStyleSheet*, TypeBuilder::Array<TypeBuilder::CSS::CSSMedia>* mediaArray);
PassRefPtr<TypeBuilder::CSS::CSSMedia> buildMediaObject(const MediaList*, MediaListSource, const String&, CSSStyleSheet*);
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:
class StyleSheetAction;
class SetStyleSheetTextAction;
......
......@@ -8,7 +8,7 @@
#include "core/css/CSSComputedStyleDeclaration.h"
#include "core/css/CSSImportRule.h"
#include "core/css/CSSMediaRule.h"
#include "core/css/CSSRuleList.h"
#include "core/css/CSSStyleRule.h"
#include "core/css/MediaList.h"
#include "core/dom/NodeComputedStyle.h"
#include "core/dom/StaticNodeList.h"
......@@ -145,11 +145,6 @@ 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
......@@ -209,7 +204,8 @@ LayoutEditor::LayoutEditor(InspectorCSSAgent* cssAgent, InspectorDOMAgent* domAg
, m_changingProperty(CSSPropertyInvalid)
, m_propertyInitialValue(0)
, m_isDirty(false)
, m_currentRuleIndex(-1)
, m_matchedRules(StaticCSSRuleList::create())
, m_currentRuleIndex(0)
{
}
......@@ -231,7 +227,8 @@ void LayoutEditor::selectNode(Node* node)
m_element = element;
m_changingProperty = CSSPropertyInvalid;
m_propertyInitialValue = 0;
initializeCSSRules();
m_matchedRules = m_cssAgent->matchedRulesList(m_element.get());
m_currentRuleIndex = m_matchedRules->length();
}
PassRefPtr<JSONObject> LayoutEditor::buildJSONInfo() const
......@@ -265,7 +262,7 @@ PassRefPtr<JSONObject> LayoutEditor::buildJSONInfo() 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)
return nullptr;
......@@ -332,11 +329,8 @@ void LayoutEditor::overlayStartedPropertyChange(const String& anchorName)
void LayoutEditor::overlayPropertyChanged(float cssDelta)
{
if (m_changingProperty && m_factor) {
String errorString;
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));
if (!errorString)
m_isDirty = true;
m_isDirty |= setCSSPropertyValueInCurrentRule(truncateZeroes(String::format("%.2f", newValue)) + CSSPrimitiveValue::unitTypeToString(m_valueUnitType));
}
}
......@@ -358,69 +352,29 @@ void LayoutEditor::clearSelection(bool commitChanges)
m_element.clear();
m_isDirty = false;
m_matchedRules.clear();
m_currentRuleIndex = -1;
m_matchedRules = StaticCSSRuleList::create();
m_currentRuleIndex = 0;
}
void LayoutEditor::initializeCSSRules()
bool LayoutEditor::currentStyleIsInline()
{
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::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);
};
return m_currentRuleIndex == m_matchedRules->length();
}
void LayoutEditor::nextSelector()
{
if (static_cast<size_t>(m_currentRuleIndex + 1) == m_matchedRules.size())
if (m_currentRuleIndex == 0)
return;
m_currentRuleIndex++;
m_currentRuleIndex--;
}
void LayoutEditor::previousSelector()
{
if (m_currentRuleIndex == -1)
if (currentStyleIsInline())
return;
m_currentRuleIndex--;
m_currentRuleIndex++;
}
String LayoutEditor::currentSelectorInfo()
......@@ -429,35 +383,33 @@ String LayoutEditor::currentSelectorInfo()
return String();
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);
Document* ownerDocument = m_element->ownerDocument();
if (!ownerDocument->isActive() || m_currentRuleIndex == -1)
if (!ownerDocument->isActive() || currentStyleIsInline())
return object->toJSONString();
if (m_currentRuleIndex != -1) {
bool hasSameSelectors = false;
for (size_t i = 0; i < m_matchedRules.size(); i++) {
if (i != static_cast<unsigned>(m_currentRuleIndex) && m_matchedRules[i]->selectorText() == currentSelectorText) {
hasSameSelectors = true;
break;
}
bool hasSameSelectors = false;
for (unsigned i = 0; i < m_matchedRules->length(); i++) {
if (i != m_currentRuleIndex && toCSSStyleRule(m_matchedRules->item(i))->selectorText() == currentSelectorText) {
hasSameSelectors = true;
break;
}
}
if (hasSameSelectors) {
Vector<String> medias;
buildMediaListChain(m_matchedRules[m_currentRuleIndex].get(), medias);
RefPtr<JSONArray> mediasJSONArray = JSONArray::create();
for (size_t i = 0; i < medias.size(); ++i)
mediasJSONArray->pushString(medias[i]);
if (hasSameSelectors) {
Vector<String> medias;
buildMediaListChain(m_matchedRules->item(m_currentRuleIndex), medias);
RefPtr<JSONArray> mediasJSONArray = JSONArray::create();
for (size_t i = 0; i < medias.size(); ++i)
mediasJSONArray->pushString(medias[i]);
object->setArray("medias", mediasJSONArray.release());
}
object->setArray("medias", mediasJSONArray.release());
}
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())
return object->toJSONString();
......@@ -477,4 +429,35 @@ String LayoutEditor::currentSelectorInfo()
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
......@@ -8,7 +8,7 @@
#include "core/CSSPropertyNames.h"
#include "core/CoreExport.h"
#include "core/css/CSSPrimitiveValue.h"
#include "core/css/CSSStyleRule.h"
#include "core/css/CSSRuleList.h"
#include "core/dom/Element.h"
#include "platform/heap/Handle.h"
#include "wtf/PassOwnPtr.h"
......@@ -49,7 +49,8 @@ private:
RefPtrWillBeRawPtr<CSSPrimitiveValue> getPropertyCSSValue(CSSPropertyID) const;
PassRefPtr<JSONObject> createValueDescription(const String&) 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;
RawPtrWillBeMember<InspectorCSSAgent> m_cssAgent;
......@@ -60,9 +61,9 @@ private:
CSSPrimitiveValue::UnitType m_valueUnitType;
bool m_isDirty;
WillBeHeapVector<RefPtrWillBeMember<CSSStyleRule>> m_matchedRules;
// -1 means "inline style".
int m_currentRuleIndex;
RefPtrWillBeRawPtr<CSSRuleList> m_matchedRules;
// When m_currentRuleIndex == m_matchedRules.length(), current style is inline style.
unsigned m_currentRuleIndex;
};
} // 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