| /* |
| * (C) 1999-2003 Lars Knoll (knoll@kde.org) |
| * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012 Apple Inc. All |
| * rights reserved. |
| * Copyright (C) 2011 Research In Motion Limited. All rights reserved. |
| * |
| * This library is free software; you can redistribute it and/or |
| * modify it under the terms of the GNU Library General Public |
| * License as published by the Free Software Foundation; either |
| * version 2 of the License, or (at your option) any later version. |
| * |
| * This library is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| * Library General Public License for more details. |
| * |
| * You should have received a copy of the GNU Library General Public License |
| * along with this library; see the file COPYING.LIB. If not, write to |
| * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
| * Boston, MA 02110-1301, USA. |
| */ |
| |
| #include "third_party/blink/renderer/core/css/style_attribute_mutation_scope.h" |
| |
| #include "third_party/blink/renderer/core/css/abstract_property_set_css_style_declaration.h" |
| #include "third_party/blink/renderer/core/dom/mutation_observer_interest_group.h" |
| #include "third_party/blink/renderer/core/dom/mutation_record.h" |
| #include "third_party/blink/renderer/core/html/custom/custom_element.h" |
| #include "third_party/blink/renderer/core/html/custom/custom_element_definition.h" |
| #include "third_party/blink/renderer/core/probe/core_probes.h" |
| |
| namespace blink { |
| |
| namespace { |
| |
| static CustomElementDefinition* DefinitionIfStyleChangedCallback( |
| Element* element) { |
| CustomElementDefinition* definition = |
| CustomElement::DefinitionForElement(element); |
| return definition && definition->HasStyleAttributeChangedCallback() |
| ? definition |
| : nullptr; |
| } |
| |
| } // namespace |
| |
| unsigned StyleAttributeMutationScope::scope_count_ = 0; |
| AbstractPropertySetCSSStyleDeclaration* |
| StyleAttributeMutationScope::current_decl_ = nullptr; |
| bool StyleAttributeMutationScope::should_notify_inspector_ = false; |
| bool StyleAttributeMutationScope::should_deliver_ = false; |
| |
| DISABLE_CFI_PERF |
| StyleAttributeMutationScope::StyleAttributeMutationScope( |
| AbstractPropertySetCSSStyleDeclaration* decl) { |
| ++scope_count_; |
| |
| if (scope_count_ != 1) { |
| DCHECK_EQ(current_decl_, decl); |
| return; |
| } |
| |
| DCHECK(!current_decl_); |
| current_decl_ = decl; |
| |
| if (!current_decl_->ParentElement()) |
| return; |
| |
| mutation_recipients_ = |
| MutationObserverInterestGroup::CreateForAttributesMutation( |
| *current_decl_->ParentElement(), html_names::kStyleAttr); |
| bool should_read_old_value = |
| (mutation_recipients_ && mutation_recipients_->IsOldValueRequested()) || |
| DefinitionIfStyleChangedCallback(current_decl_->ParentElement()); |
| |
| if (should_read_old_value) { |
| old_value_ = |
| current_decl_->ParentElement()->getAttribute(html_names::kStyleAttr); |
| } |
| |
| if (mutation_recipients_) { |
| AtomicString requested_old_value = |
| mutation_recipients_->IsOldValueRequested() ? old_value_ : g_null_atom; |
| mutation_ = MutationRecord::CreateAttributes(current_decl_->ParentElement(), |
| html_names::kStyleAttr, |
| requested_old_value); |
| } |
| } |
| |
| DISABLE_CFI_PERF |
| StyleAttributeMutationScope::~StyleAttributeMutationScope() { |
| --scope_count_; |
| if (scope_count_) |
| return; |
| |
| if (should_deliver_) { |
| if (mutation_) |
| mutation_recipients_->EnqueueMutationRecord(mutation_); |
| |
| Element* element = current_decl_->ParentElement(); |
| if (CustomElementDefinition* definition = |
| DefinitionIfStyleChangedCallback(element)) { |
| definition->EnqueueAttributeChangedCallback( |
| *element, html_names::kStyleAttr, old_value_, |
| element->getAttribute(html_names::kStyleAttr)); |
| } |
| |
| should_deliver_ = false; |
| } |
| |
| // We have to clear internal state before calling Inspector's code. |
| AbstractPropertySetCSSStyleDeclaration* local_copy_style_decl = current_decl_; |
| current_decl_ = nullptr; |
| |
| if (!should_notify_inspector_) |
| return; |
| |
| should_notify_inspector_ = false; |
| if (local_copy_style_decl->ParentElement()) |
| probe::DidInvalidateStyleAttr(local_copy_style_decl->ParentElement()); |
| } |
| |
| } // namespace blink |