Chromium Code Reviews| Index: third_party/WebKit/Source/core/inspector/InspectorCSSAgent.cpp |
| diff --git a/third_party/WebKit/Source/core/inspector/InspectorCSSAgent.cpp b/third_party/WebKit/Source/core/inspector/InspectorCSSAgent.cpp |
| index 5aec74b02a33daba88c42957303e5647a7751414..b292baad2c48d8f26c3307bdba62f65181ce13a4 100644 |
| --- a/third_party/WebKit/Source/core/inspector/InspectorCSSAgent.cpp |
| +++ b/third_party/WebKit/Source/core/inspector/InspectorCSSAgent.cpp |
| @@ -311,6 +311,11 @@ public: |
| : InspectorHistory::Action(name) |
| { |
| } |
| + |
| + virtual PassRefPtr<protocol::TypeBuilder::CSS::CSSStyle> takeSerializedStyle() |
| + { |
| + return nullptr; |
| + } |
| }; |
| class InspectorCSSAgent::SetStyleSheetTextAction final : public InspectorCSSAgent::StyleSheetAction { |
| @@ -435,6 +440,18 @@ public: |
| return result; |
| } |
| + PassRefPtr<protocol::TypeBuilder::CSS::CSSStyle> takeSerializedStyle() override |
| + { |
| + if (m_type != SetStyleText) |
| + return nullptr; |
| + RefPtrWillBeRawPtr<CSSRule> rule = takeRule(); |
| + if (rule->type() == CSSRule::STYLE_RULE) |
| + return m_styleSheet->buildObjectForStyle(toCSSStyleRule(rule.get())->style()); |
| + if (rule->type() == CSSRule::KEYFRAME_RULE) |
| + return m_styleSheet->buildObjectForStyle(toCSSKeyframeRule(rule.get())->style()); |
| + return nullptr; |
| + } |
| + |
| DEFINE_INLINE_VIRTUAL_TRACE() |
| { |
| visitor->trace(m_styleSheet); |
| @@ -509,6 +526,11 @@ public: |
| return String::format("SetElementStyleAction:%s", m_styleSheet->id().utf8().data()); |
| } |
| + PassRefPtr<protocol::TypeBuilder::CSS::CSSStyle> takeSerializedStyle() override |
| + { |
| + return m_styleSheet->buildObjectForStyle(m_styleSheet->inlineStyle()); |
| + } |
| + |
| void merge(PassRefPtrWillBeRawPtr<Action> action) override |
| { |
| ASSERT(action->mergeId() == mergeId()); |
| @@ -1203,21 +1225,89 @@ void InspectorCSSAgent::setKeyframeKey(ErrorString* errorString, const String& s |
| *errorString = InspectorDOMAgent::toErrorString(exceptionState); |
| } |
| -void InspectorCSSAgent::setStyleText(ErrorString* errorString, const String& styleSheetId, const RefPtr<JSONObject>& range, const String& text, RefPtr<protocol::TypeBuilder::CSS::CSSStyle>& result) |
| +bool InspectorCSSAgent::multipleStyleTextsActions(ErrorString* errorString, const RefPtr<JSONArray>& edits, HeapVector<RefPtrWillBeMember<StyleSheetAction>>* actions) |
| +{ |
| + size_t n = edits->length(); |
| + if (n == 0) { |
| + *errorString = "Edits should not be empty"; |
| + return false; |
| + } |
| + |
| + for (size_t i = 0; i < n; ++i) { |
| + RefPtr<JSONObject> edit = edits->get(i)->asObject(); |
| + String styleSheetId; |
| + bool success = edit->getString("styleSheetId", &styleSheetId); |
| + if (!success) { |
| + *errorString = String::format("Could not parse styleSheetId for edit #%zu of %zu", i + 1, n); |
| + return false; |
| + } |
| + InspectorStyleSheetBase* inspectorStyleSheet = assertStyleSheetForId(errorString, styleSheetId); |
| + if (!inspectorStyleSheet) { |
| + *errorString = String::format("StyleSheet not found for edit #%zu of %zu", i + 1 , n); |
| + return false; |
| + } |
| + |
| + RefPtr<JSONObject> rangeObject = edit->getObject("range"); |
| + if (!rangeObject) { |
| + *errorString = String::format("Could not parse range object for edit #%zu of %zu", i + 1, n); |
| + return false; |
| + } |
| + |
| + SourceRange range; |
| + if (!jsonRangeToSourceRange(errorString, inspectorStyleSheet, rangeObject, &range)) |
| + return false; |
| + |
| + String text; |
| + success = edit->getString("text", &text); |
| + if (!success) { |
| + *errorString = String::format("Could not parse text for edit #%zu of %zu", i + 1, n); |
| + return false; |
| + } |
| + |
| + if (inspectorStyleSheet->isInlineStyle()) { |
| + InspectorStyleSheetForInlineStyle* inlineStyleSheet = static_cast<InspectorStyleSheetForInlineStyle*>(inspectorStyleSheet); |
| + RefPtrWillBeRawPtr<SetElementStyleAction> action = adoptRefWillBeNoop(new SetElementStyleAction(inlineStyleSheet, text)); |
| + actions->append(action); |
| + } else { |
| + RefPtrWillBeRawPtr<ModifyRuleAction> action = adoptRefWillBeNoop(new ModifyRuleAction(ModifyRuleAction::SetStyleText, static_cast<InspectorStyleSheet*>(inspectorStyleSheet), range, text)); |
| + actions->append(action); |
| + } |
| + } |
| + return true; |
| +} |
| + |
| +void InspectorCSSAgent::setStyleTexts(ErrorString* errorString, const RefPtr<JSONArray>& edits, RefPtr<protocol::TypeBuilder::Array<protocol::TypeBuilder::CSS::CSSStyle>>& result) |
| { |
| FrontendOperationScope scope; |
| - InspectorStyleSheetBase* inspectorStyleSheet = assertStyleSheetForId(errorString, styleSheetId); |
| - if (!inspectorStyleSheet) { |
| - *errorString = "Stylesheet not found"; |
| + HeapVector<RefPtrWillBeMember<StyleSheetAction>> actions; |
| + if (!multipleStyleTextsActions(errorString, edits, &actions)) |
| return; |
| + |
| + TrackExceptionState exceptionState; |
| + for (size_t i = 0; i < actions.size(); ++i) { |
| + RefPtrWillBeMember<StyleSheetAction> action = actions.at(i); |
| + bool success = action->perform(exceptionState); |
| + if (!success) { |
| + for (size_t j = 0; j < i; ++j) { |
| + RefPtrWillBeMember<StyleSheetAction> revert = actions.at(i - j - 1); |
| + TrackExceptionState undoExceptionState; |
| + revert->undo(undoExceptionState); |
| + ASSERT(!undoExceptionState.hadException()); |
| + |
|
dgozman
2016/02/18 02:11:00
extra empty line
lushnikov
2016/02/18 02:49:37
Done.
|
| + } |
| + *errorString = String::format("Failed applying edit #%zu: %s", i, InspectorDOMAgent::toErrorString(exceptionState).utf8().data()); |
| + return; |
| + } |
| } |
| - SourceRange selectorRange; |
| - if (!jsonRangeToSourceRange(errorString, inspectorStyleSheet, range, &selectorRange)) |
| - return; |
| - CSSStyleDeclaration* style = setStyleText(errorString, inspectorStyleSheet, selectorRange, text); |
| - if (style) |
| - result = inspectorStyleSheet->buildObjectForStyle(style); |
| + result = protocol::TypeBuilder::Array<protocol::TypeBuilder::CSS::CSSStyle>::create(); |
| + for (size_t i = 0; i < actions.size(); ++i) { |
| + RefPtrWillBeMember<StyleSheetAction> action = actions.at(i); |
| + RefPtr<protocol::TypeBuilder::CSS::CSSStyle> stylePayload = action->takeSerializedStyle(); |
| + ASSERT(stylePayload); |
| + result->addItem(stylePayload); |
| + m_domAgent->history()->appendPerformedAction(action); |
| + } |
| } |
| CSSStyleDeclaration* InspectorCSSAgent::setStyleText(ErrorString* errorString, InspectorStyleSheetBase* inspectorStyleSheet, const SourceRange& range, const String& text) |