diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2019-08-30 10:22:43 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2019-08-30 12:36:28 +0000 |
commit | 271a6c3487a14599023a9106329505597638d793 (patch) | |
tree | e040d58ffc86c1480b79ca8528020ca9ec919bf8 /chromium/third_party/blink/renderer/core/svg | |
parent | 7b2ffa587235a47d4094787d72f38102089f402a (diff) | |
download | qtwebengine-chromium-271a6c3487a14599023a9106329505597638d793.tar.gz |
BASELINE: Update Chromium to 77.0.3865.59
Change-Id: I1e89a5f3b009a9519a6705102ad65c92fe736f21
Reviewed-by: Michael BrĂ¼ning <michael.bruning@qt.io>
Diffstat (limited to 'chromium/third_party/blink/renderer/core/svg')
134 files changed, 1030 insertions, 469 deletions
diff --git a/chromium/third_party/blink/renderer/core/svg/BUILD.gn b/chromium/third_party/blink/renderer/core/svg/BUILD.gn index 58c6861e677..0878e91c919 100644 --- a/chromium/third_party/blink/renderer/core/svg/BUILD.gn +++ b/chromium/third_party/blink/renderer/core/svg/BUILD.gn @@ -14,6 +14,8 @@ blink_core_sources("svg") { } sources = [ + "animation/smil_animation_sandwich.cc", + "animation/smil_animation_sandwich.h", "animation/smil_time.cc", "animation/smil_time.h", "animation/smil_time_container.cc", diff --git a/chromium/third_party/blink/renderer/core/svg/animation/smil_animation_sandwich.cc b/chromium/third_party/blink/renderer/core/svg/animation/smil_animation_sandwich.cc new file mode 100644 index 00000000000..503581cf8b8 --- /dev/null +++ b/chromium/third_party/blink/renderer/core/svg/animation/smil_animation_sandwich.cc @@ -0,0 +1,153 @@ +/* + * Copyright (C) 2008 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "third_party/blink/renderer/core/svg/animation/smil_animation_sandwich.h" + +#include <algorithm> + +#include "third_party/blink/renderer/core/svg/animation/svg_smil_element.h" + +namespace blink { + +SMILAnimationSandwich::SMILAnimationSandwich() {} + +void SMILAnimationSandwich::Schedule(SVGSMILElement* animation) { + DCHECK(!sandwich_.Contains(animation)); + sandwich_.push_back(animation); +} + +void SMILAnimationSandwich::Unschedule(SVGSMILElement* animation) { + auto* position = std::find(sandwich_.begin(), sandwich_.end(), animation); + DCHECK(sandwich_.end() != position); + sandwich_.erase(position); +} + +void SMILAnimationSandwich::Reset() { + for (SVGSMILElement* animation : sandwich_) { + animation->Reset(); + } +} + +void SMILAnimationSandwich::UpdateTiming(double elapsed, bool seek_to_time) { + if (!std::is_sorted(sandwich_.begin(), sandwich_.end(), + PriorityCompare(elapsed))) { + std::sort(sandwich_.begin(), sandwich_.end(), PriorityCompare(elapsed)); + } + + active_.ReserveCapacity(sandwich_.size()); + for (const auto& it_animation : sandwich_) { + SVGSMILElement* animation = it_animation.Get(); + DCHECK(animation->HasValidTarget()); + + if (animation->NeedsToProgress(elapsed)) { + animation->Progress(elapsed, seek_to_time); + active_.push_back(animation); + } else if (animation->IsContributing(elapsed)) { + active_.push_back(animation); + } else { + animation->ClearAnimatedType(); + } + } +} + +SMILTime SMILAnimationSandwich::GetNextFireTime() { + SMILTime earliest_fire_time = SMILTime::Unresolved(); + for (const auto& it_animation : sandwich_) { + SVGSMILElement* animation = it_animation.Get(); + + SMILTime next_fire_time = animation->NextProgressTime(); + if (next_fire_time.IsFinite()) + earliest_fire_time = std::min(next_fire_time, earliest_fire_time); + } + return earliest_fire_time; +} + +void SMILAnimationSandwich::SendEvents(double elapsed, bool seek_to_time) { + if (seek_to_time) { + for (auto& animation : active_) { + animation->TriggerPendingEvents(elapsed); + } + } + + for (auto& animation : active_) { + animation->UpdateSyncbases(); + } + + for (auto& animation : active_) { + animation->UpdateNextProgressTime(elapsed); + } + + auto* it = active_.begin(); + while (it != active_.end()) { + auto* scheduled = it->Get(); + if (scheduled->IsContributing(elapsed)) { + it++; + continue; + } + scheduled->ClearAnimatedType(); + it = active_.erase(it); + } +} + +SVGSMILElement* SMILAnimationSandwich::ApplyAnimationValues() { + if (active_.IsEmpty()) + return nullptr; + // Results are accumulated to the first animation that animates and + // contributes to a particular element/attribute pair. + // Only reset the animated type to the base value once for + // the lowest priority animation that animates and + // contributes to a particular element/attribute pair. + SVGSMILElement* result_element = active_.front(); + result_element->ResetAnimatedType(); + + // Animations have to be applied lowest to highest prio. + // + // Only calculate the relevant animations. If we actually set the + // animation value, we don't need to calculate what is beneath it + // in the sandwich. + auto* sandwich_start = active_.end(); + while (sandwich_start != active_.begin()) { + --sandwich_start; + if ((*sandwich_start)->OverwritesUnderlyingAnimationValue()) + break; + } + + for (auto* sandwich_it = sandwich_start; sandwich_it != active_.end(); + sandwich_it++) { + (*sandwich_it)->UpdateAnimatedValue(result_element); + } + active_.Shrink(0); + + result_element->ApplyResultsToTarget(); + + return result_element; +} + +void SMILAnimationSandwich::Trace(blink::Visitor* visitor) { + visitor->Trace(sandwich_); + visitor->Trace(active_); +} + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/core/svg/animation/smil_animation_sandwich.h b/chromium/third_party/blink/renderer/core/svg/animation/smil_animation_sandwich.h new file mode 100644 index 00000000000..f783f3d352d --- /dev/null +++ b/chromium/third_party/blink/renderer/core/svg/animation/smil_animation_sandwich.h @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2008 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_SVG_ANIMATION_SMIL_ANIMATION_SANDWICH_H_ +#define THIRD_PARTY_BLINK_RENDERER_CORE_SVG_ANIMATION_SMIL_ANIMATION_SANDWICH_H_ + +#include "third_party/blink/renderer/core/svg/animation/smil_time.h" +#include "third_party/blink/renderer/core/svg/animation/svg_smil_element.h" +#include "third_party/blink/renderer/platform/heap/handle.h" +#include "third_party/blink/renderer/platform/wtf/vector.h" + +namespace blink { + +struct PriorityCompare { + PriorityCompare(double elapsed) : elapsed_(elapsed) {} + bool operator()(const Member<SVGSMILElement>& a, + const Member<SVGSMILElement>& b) { + // FIXME: This should also consider possible timing relations between the + // elements. + SMILTime a_begin = a->IntervalBegin(); + SMILTime b_begin = b->IntervalBegin(); + // Frozen elements need to be prioritized based on their previous interval. + a_begin = a->IsFrozen() && elapsed_ < a_begin ? a->PreviousIntervalBegin() + : a_begin; + b_begin = b->IsFrozen() && elapsed_ < b_begin ? b->PreviousIntervalBegin() + : b_begin; + if (a_begin == b_begin) + return a->DocumentOrderIndex() < b->DocumentOrderIndex(); + return a_begin < b_begin; + } + double elapsed_; +}; + +class SMILAnimationSandwich : public GarbageCollected<SMILAnimationSandwich> { + public: + using ScheduledVector = HeapVector<Member<SVGSMILElement>>; + explicit SMILAnimationSandwich(); + + void Schedule(SVGSMILElement* animation); + void Unschedule(SVGSMILElement* animation); + void Reset(); + + void UpdateTiming(double elapsed, bool seek_to_time); + void SendEvents(double elapsed, bool seek_to_time); + SVGSMILElement* ApplyAnimationValues(); + + SMILTime GetNextFireTime(); + + bool IsEmpty() { return sandwich_.IsEmpty(); } + + void Trace(blink::Visitor*); + + private: + // The list stored here is always sorted. + ScheduledVector sandwich_; + ScheduledVector active_; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_SVG_ANIMATION_SMIL_ANIMATION_SANDWICH_H_ diff --git a/chromium/third_party/blink/renderer/core/svg/animation/smil_time.h b/chromium/third_party/blink/renderer/core/svg/animation/smil_time.h index 378ab8b5ad4..bea1545c331 100644 --- a/chromium/third_party/blink/renderer/core/svg/animation/smil_time.h +++ b/chromium/third_party/blink/renderer/core/svg/animation/smil_time.h @@ -26,7 +26,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_SVG_ANIMATION_SMIL_TIME_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_SVG_ANIMATION_SMIL_TIME_H_ -#include "third_party/blink/renderer/platform/wtf/allocator.h" +#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" #include "third_party/blink/renderer/platform/wtf/assertions.h" #include "third_party/blink/renderer/platform/wtf/hash_traits.h" #include "third_party/blink/renderer/platform/wtf/math_extras.h" diff --git a/chromium/third_party/blink/renderer/core/svg/animation/smil_time_container.cc b/chromium/third_party/blink/renderer/core/svg/animation/smil_time_container.cc index e9d898324ed..8b392035b7c 100644 --- a/chromium/third_party/blink/renderer/core/svg/animation/smil_time_container.cc +++ b/chromium/third_party/blink/renderer/core/svg/animation/smil_time_container.cc @@ -32,15 +32,15 @@ #include "third_party/blink/renderer/core/dom/element_traversal.h" #include "third_party/blink/renderer/core/frame/local_frame_view.h" #include "third_party/blink/renderer/core/frame/settings.h" -#include "third_party/blink/renderer/core/frame/use_counter.h" #include "third_party/blink/renderer/core/svg/animation/smil_time.h" #include "third_party/blink/renderer/core/svg/animation/svg_smil_element.h" #include "third_party/blink/renderer/core/svg/svg_svg_element.h" +#include "third_party/blink/renderer/platform/instrumentation/use_counter.h" namespace blink { -static constexpr TimeDelta kAnimationPolicyOnceDuration = - TimeDelta::FromSeconds(3); +static constexpr base::TimeDelta kAnimationPolicyOnceDuration = + base::TimeDelta::FromSeconds(3); SMILTimeContainer::SMILTimeContainer(SVGSVGElement& owner) : presentation_time_(0), @@ -79,15 +79,19 @@ void SMILTimeContainer::Schedule(SVGSMILElement* animation, DCHECK(!prevent_scheduled_animations_changes_); #endif - AttributeAnimationsMap& attribute_map = - scheduled_animations_.insert(target, AttributeAnimationsMap()) - .stored_value->value; - Member<AnimationsLinkedHashSet>& scheduled = - attribute_map.insert(attribute_name, nullptr).stored_value->value; - if (!scheduled) - scheduled = MakeGarbageCollected<AnimationsLinkedHashSet>(); - DCHECK(!scheduled->Contains(animation)); - scheduled->insert(animation); + // Separate out Discard and AnimateMotion + QualifiedName name = (animation->HasTagName(svg_names::kAnimateMotionTag) || + animation->HasTagName(svg_names::kDiscardTag)) + ? animation->TagQName() + : attribute_name; + + auto key = std::make_pair(target, name); + auto& sandwich = + scheduled_animations_.insert(key, nullptr).stored_value->value; + if (!sandwich) + sandwich = MakeGarbageCollected<SMILAnimationSandwich>(); + + sandwich->Schedule(animation); SMILTime next_fire_time = animation->NextProgressTime(); if (next_fire_time.IsFinite()) @@ -103,20 +107,20 @@ void SMILTimeContainer::Unschedule(SVGSMILElement* animation, DCHECK(!prevent_scheduled_animations_changes_); #endif - GroupedAnimationsMap::iterator it = scheduled_animations_.find(target); + // Separate out Discard and AnimateMotion + QualifiedName name = (animation->HasTagName(svg_names::kAnimateMotionTag) || + animation->HasTagName(svg_names::kDiscardTag)) + ? animation->TagQName() + : attribute_name; + + auto key = std::make_pair(target, name); + AnimationsMap::iterator it = scheduled_animations_.find(key); CHECK(it != scheduled_animations_.end()); - AttributeAnimationsMap& attribute_map = it->value; - AttributeAnimationsMap::iterator attribute_map_it = - attribute_map.find(attribute_name); - DCHECK(attribute_map_it != attribute_map.end()); - AnimationsLinkedHashSet* scheduled = attribute_map_it->value; - AnimationsLinkedHashSet::iterator it_animation = scheduled->find(animation); - DCHECK(it_animation != scheduled->end()); - scheduled->erase(it_animation); - - if (scheduled->IsEmpty()) - attribute_map.erase(attribute_map_it); - if (attribute_map.IsEmpty()) + + auto& sandwich = *(it->value); + sandwich.Unschedule(animation); + + if (sandwich.IsEmpty()) scheduled_animations_.erase(it); } @@ -235,13 +239,8 @@ void SMILTimeContainer::SetElapsed(double elapsed) { #if DCHECK_IS_ON() prevent_scheduled_animations_changes_ = true; #endif - for (const auto& attribute_entry : scheduled_animations_) { - for (const auto& entry : attribute_entry.value) { - const AnimationsLinkedHashSet* scheduled = entry.value; - for (SVGSMILElement* element : *scheduled) { - element->Reset(); - } - } + for (const auto& sandwich : scheduled_animations_) { + sandwich.value->Reset(); } #if DCHECK_IS_ON() prevent_scheduled_animations_changes_ = false; @@ -273,7 +272,8 @@ void SMILTimeContainer::ScheduleWakeUp( FrameSchedulingState frame_scheduling_state) { DCHECK(frame_scheduling_state == kSynchronizeAnimations || frame_scheduling_state == kFutureAnimationFrame); - wakeup_timer_.StartOneShot(TimeDelta::FromSecondsD(delay_time), FROM_HERE); + wakeup_timer_.StartOneShot(base::TimeDelta::FromSecondsD(delay_time), + FROM_HERE); frame_scheduling_state_ = frame_scheduling_state; } @@ -352,26 +352,6 @@ void SMILTimeContainer::UpdateDocumentOrderIndexes() { document_order_indexes_dirty_ = false; } -struct PriorityCompare { - PriorityCompare(double elapsed) : elapsed_(elapsed) {} - bool operator()(const Member<SVGSMILElement>& a, - const Member<SVGSMILElement>& b) { - // FIXME: This should also consider possible timing relations between the - // elements. - SMILTime a_begin = a->IntervalBegin(); - SMILTime b_begin = b->IntervalBegin(); - // Frozen elements need to be prioritized based on their previous interval. - a_begin = a->IsFrozen() && elapsed_ < a_begin ? a->PreviousIntervalBegin() - : a_begin; - b_begin = b->IsFrozen() && elapsed_ < b_begin ? b->PreviousIntervalBegin() - : b_begin; - if (a_begin == b_begin) - return a->DocumentOrderIndex() < b->DocumentOrderIndex(); - return a_begin < b_begin; - } - double elapsed_; -}; - SVGSVGElement& SMILTimeContainer::OwnerSVGElement() const { return *owner_svg_element_; } @@ -411,106 +391,87 @@ void SMILTimeContainer::UpdateAnimationsAndScheduleFrameIfNeeded( if (!GetDocument().IsActive()) return; - SMILTime earliest_fire_time = UpdateAnimations(elapsed, seek_to_time); + UpdateAnimationTimings(elapsed, seek_to_time); + ApplyAnimationValues(elapsed); + + SMILTime earliest_fire_time = SMILTime::Unresolved(); + for (auto& sandwich : scheduled_animations_) { + SMILTime next_fire_time = sandwich.value->GetNextFireTime(); + if (next_fire_time.IsFinite()) + earliest_fire_time = std::min(next_fire_time, earliest_fire_time); + } + if (!CanScheduleFrame(earliest_fire_time)) return; double delay_time = earliest_fire_time.Value() - elapsed; ScheduleAnimationFrame(delay_time); } -SMILTime SMILTimeContainer::UpdateAnimations(double elapsed, - bool seek_to_time) { +void SMILTimeContainer::UpdateAnimationTimings(double elapsed, + bool seek_to_time) { DCHECK(GetDocument().IsActive()); - SMILTime earliest_fire_time = SMILTime::Unresolved(); #if DCHECK_IS_ON() // This boolean will catch any attempts to schedule/unschedule - // scheduledAnimations during this critical section. Similarly, any elements + // scheduledAnimations during this critical section. Similarly, any elements // removed will unschedule themselves, so this will catch modification of // animationsToApply. - prevent_scheduled_animations_changes_ = true; + base::AutoReset<bool> no_scheduled_animations_change_scope( + &prevent_scheduled_animations_changes_, true); #endif if (document_order_indexes_dirty_) UpdateDocumentOrderIndexes(); - using AnimationsVector = HeapVector<Member<SVGSMILElement>>; - AnimationsVector animations_to_apply; - AnimationsVector scheduled_animations_in_same_group; - for (auto& attribute_entry : scheduled_animations_) { - AttributeAnimationsMap& attribute_map = attribute_entry.value; - Vector<QualifiedName> invalid_keys; - for (const auto& entry : attribute_map) { - DCHECK(entry.value); + { + Vector<AnimationId> invalid_keys; + for (auto& entry : scheduled_animations_) { if (entry.value->IsEmpty()) { invalid_keys.push_back(entry.key); - continue; } + } + scheduled_animations_.RemoveAll(invalid_keys); + } - // Sort according to priority. Elements with later begin time have higher - // priority. In case of a tie, document order decides. - // FIXME: This should also consider timing relationships between the - // elements. Dependents have higher priority. - CopyToVector(*entry.value, scheduled_animations_in_same_group); - std::sort(scheduled_animations_in_same_group.begin(), - scheduled_animations_in_same_group.end(), - PriorityCompare(elapsed)); - - AnimationsVector sandwich; - for (const auto& it_animation : scheduled_animations_in_same_group) { - SVGSMILElement* animation = it_animation.Get(); - DCHECK_EQ(animation->TimeContainer(), this); - DCHECK(animation->HasValidTarget()); - - // This will calculate the contribution from the animation and update - // timing. - if (animation->Progress(elapsed, seek_to_time)) { - sandwich.push_back(animation); - } else { - animation->ClearAnimatedType(); - } - - SMILTime next_fire_time = animation->NextProgressTime(); - if (next_fire_time.IsFinite()) - earliest_fire_time = std::min(next_fire_time, earliest_fire_time); - } + active_sandwiches_.ReserveCapacity(scheduled_animations_.size()); + for (auto& entry : scheduled_animations_) { + auto* sandwich = entry.value.Get(); + sandwich->UpdateTiming(elapsed, seek_to_time); - if (!sandwich.IsEmpty()) { - // Results are accumulated to the first animation that animates and - // contributes to a particular element/attribute pair. - // Only reset the animated type to the base value once for - // the lowest priority animation that animates and - // contributes to a particular element/attribute pair. - SVGSMILElement* result_element = sandwich.front(); - result_element->ResetAnimatedType(); - - // Go through the sandwich from lowest prio to highest and generate - // the animated value (if any.) - for (const auto& animation : sandwich) - animation->UpdateAnimatedValue(result_element); - - animations_to_apply.push_back(result_element); - } + if (!sandwich->IsEmpty()) { + active_sandwiches_.push_back(sandwich); } - attribute_map.RemoveAll(invalid_keys); } + for (auto& sandwich : active_sandwiches_) { + sandwich->SendEvents(elapsed, seek_to_time); + } +} + +void SMILTimeContainer::ApplyAnimationValues(double elapsed) { +#if DCHECK_IS_ON() + prevent_scheduled_animations_changes_ = true; +#endif + HeapVector<Member<SVGSMILElement>> animations_to_apply; + for (auto& sandwich : active_sandwiches_) { + if (SVGSMILElement* animation = sandwich->ApplyAnimationValues()) + animations_to_apply.push_back(animation); + } + active_sandwiches_.Shrink(0); + if (animations_to_apply.IsEmpty()) { #if DCHECK_IS_ON() prevent_scheduled_animations_changes_ = false; #endif - return earliest_fire_time; + return; } + // Everything bellow handles "discard" elements. UseCounter::Count(&GetDocument(), WebFeature::kSVGSMILAnimationAppliedEffect); std::sort(animations_to_apply.begin(), animations_to_apply.end(), PriorityCompare(elapsed)); - // Apply results to target elements. - for (const auto& timed_element : animations_to_apply) - timed_element->ApplyResultsToTarget(); - #if DCHECK_IS_ON() prevent_scheduled_animations_changes_ = false; #endif @@ -519,6 +480,8 @@ SMILTime SMILTimeContainer::UpdateAnimations(double elapsed, if (timed_element->isConnected() && timed_element->IsSVGDiscardElement()) { SVGElement* target_element = timed_element->targetElement(); if (target_element && target_element->isConnected()) { + UseCounter::Count(&GetDocument(), + WebFeature::kSVGSMILDiscardElementTriggered); target_element->remove(IGNORE_EXCEPTION_FOR_TESTING); DCHECK(!target_element->isConnected()); } @@ -529,7 +492,7 @@ SMILTime SMILTimeContainer::UpdateAnimations(double elapsed, } } } - return earliest_fire_time; + return; } void SMILTimeContainer::AdvanceFrameForTesting() { @@ -540,6 +503,7 @@ void SMILTimeContainer::AdvanceFrameForTesting() { void SMILTimeContainer::Trace(blink::Visitor* visitor) { visitor->Trace(scheduled_animations_); visitor->Trace(owner_svg_element_); + visitor->Trace(active_sandwiches_); } } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/svg/animation/smil_time_container.h b/chromium/third_party/blink/renderer/core/svg/animation/smil_time_container.h index ad3e1addaa1..ce762bfa188 100644 --- a/chromium/third_party/blink/renderer/core/svg/animation/smil_time_container.h +++ b/chromium/third_party/blink/renderer/core/svg/animation/smil_time_container.h @@ -27,6 +27,7 @@ #define THIRD_PARTY_BLINK_RENDERER_CORE_SVG_ANIMATION_SMIL_TIME_CONTAINER_H_ #include "third_party/blink/renderer/core/dom/qualified_name.h" +#include "third_party/blink/renderer/core/svg/animation/smil_animation_sandwich.h" #include "third_party/blink/renderer/platform/graphics/image_animation_policy.h" #include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/timer.h" @@ -40,11 +41,14 @@ namespace blink { class Document; class SMILTime; class SVGElement; -class SVGSMILElement; class SVGSVGElement; class SMILTimeContainer : public GarbageCollectedFinalized<SMILTimeContainer> { public: + // Sorted list + using AnimationId = std::pair<WeakMember<SVGElement>, QualifiedName>; + using AnimationsMap = HeapHashMap<AnimationId, Member<SMILAnimationSandwich>>; + explicit SMILTimeContainer(SVGSVGElement& owner); ~SMILTimeContainer(); @@ -106,7 +110,8 @@ class SMILTimeContainer : public GarbageCollectedFinalized<SMILTimeContainer> { bool CanScheduleFrame(SMILTime earliest_fire_time) const; void UpdateAnimationsAndScheduleFrameIfNeeded(double elapsed, bool seek_to_time = false); - SMILTime UpdateAnimations(double elapsed, bool seek_to_time); + void UpdateAnimationTimings(double elapsed, bool seek_to_time); + void ApplyAnimationValues(double elapsed); void ServiceOnNextFrame(); void ScheduleWakeUp(double delay_time, FrameSchedulingState); bool HasPendingSynchronization() const; @@ -131,12 +136,8 @@ class SMILTimeContainer : public GarbageCollectedFinalized<SMILTimeContainer> { TaskRunnerTimer<SMILTimeContainer> wakeup_timer_; TaskRunnerTimer<SMILTimeContainer> animation_policy_once_timer_; - using AnimationsLinkedHashSet = HeapLinkedHashSet<WeakMember<SVGSMILElement>>; - using AttributeAnimationsMap = - HeapHashMap<QualifiedName, Member<AnimationsLinkedHashSet>>; - using GroupedAnimationsMap = - HeapHashMap<WeakMember<SVGElement>, AttributeAnimationsMap>; - GroupedAnimationsMap scheduled_animations_; + AnimationsMap scheduled_animations_; + HeapVector<Member<SMILAnimationSandwich>> active_sandwiches_; Member<SVGSVGElement> owner_svg_element_; diff --git a/chromium/third_party/blink/renderer/core/svg/animation/svg_smil_element.cc b/chromium/third_party/blink/renderer/core/svg/animation/svg_smil_element.cc index fe85da6a37f..ffad3ed7358 100644 --- a/chromium/third_party/blink/renderer/core/svg/animation/svg_smil_element.cc +++ b/chromium/third_party/blink/renderer/core/svg/animation/svg_smil_element.cc @@ -33,13 +33,13 @@ #include "third_party/blink/renderer/core/dom/events/event.h" #include "third_party/blink/renderer/core/dom/events/native_event_listener.h" #include "third_party/blink/renderer/core/dom/id_target_observer.h" -#include "third_party/blink/renderer/core/frame/use_counter.h" #include "third_party/blink/renderer/core/svg/animation/smil_time_container.h" #include "third_party/blink/renderer/core/svg/svg_svg_element.h" #include "third_party/blink/renderer/core/svg/svg_uri_reference.h" #include "third_party/blink/renderer/core/xlink_names.h" #include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/heap/heap.h" +#include "third_party/blink/renderer/platform/instrumentation/use_counter.h" #include "third_party/blink/renderer/platform/wtf/functional.h" #include "third_party/blink/renderer/platform/wtf/math_extras.h" #include "third_party/blink/renderer/platform/wtf/std_lib_extras.h" @@ -153,12 +153,13 @@ void SVGSMILElement::Condition::ConnectSyncBase(SVGSMILElement& timed_element) { DCHECK(!base_id_.IsEmpty()); DCHECK_EQ(type_, kSyncbase); Element* element = timed_element.GetTreeScope().getElementById(base_id_); - if (!element || !IsSVGSMILElement(*element)) { + auto* svg_smil_element = DynamicTo<SVGSMILElement>(element); + if (!svg_smil_element) { base_element_ = nullptr; return; } - base_element_ = ToSVGSMILElement(element); - ToSVGSMILElement(*element).AddSyncBaseDependent(timed_element); + base_element_ = svg_smil_element; + svg_smil_element->AddSyncBaseDependent(timed_element); } void SVGSMILElement::Condition::DisconnectSyncBase( @@ -166,7 +167,7 @@ void SVGSMILElement::Condition::DisconnectSyncBase( DCHECK_EQ(type_, kSyncbase); if (!base_element_) return; - ToSVGSMILElement(*base_element_).RemoveSyncBaseDependent(timed_element); + To<SVGSMILElement>(*base_element_).RemoveSyncBaseDependent(timed_element); base_element_ = nullptr; } @@ -228,7 +229,8 @@ SVGSMILElement::SVGSMILElement(const QualifiedName& tag_name, Document& doc) cached_repeat_dur_(kInvalidCachedTime), cached_repeat_count_(kInvalidCachedTime), cached_min_(kInvalidCachedTime), - cached_max_(kInvalidCachedTime) { + cached_max_(kInvalidCachedTime), + interval_has_changed_(false) { ResolveFirstInterval(); } @@ -710,7 +712,7 @@ static void InsertSorted(Vector<SMILTimeWithOrigin>& list, void SVGSMILElement::AddInstanceTime(BeginOrEnd begin_or_end, SMILTime time, SMILTimeWithOrigin::Origin origin) { - SMILTime elapsed = this->Elapsed(); + SMILTime elapsed = Elapsed(); if (elapsed.IsUnresolved()) return; SMILTimeWithOrigin time_with_origin(time, origin); @@ -761,9 +763,9 @@ SMILTime SVGSMILElement::FindInstanceTime(BeginOrEnd begin_or_end, SMILTime SVGSMILElement::RepeatingDuration() const { // Computing the active duration // http://www.w3.org/TR/SMIL2/smil-timing.html#Timing-ComputingActiveDur - SMILTime repeat_count = this->RepeatCount(); - SMILTime repeat_dur = this->RepeatDur(); - SMILTime simple_duration = this->SimpleDuration(); + SMILTime repeat_count = RepeatCount(); + SMILTime repeat_dur = RepeatDur(); + SMILTime simple_duration = SimpleDuration(); if (!simple_duration || (repeat_dur.IsUnresolved() && repeat_count.IsUnresolved())) return simple_duration; @@ -788,8 +790,8 @@ SMILTime SVGSMILElement::ResolveActiveEnd(SMILTime resolved_begin, preliminary_active_duration = std::min(RepeatingDuration(), resolved_end - resolved_begin); - SMILTime min_value = this->MinValue(); - SMILTime max_value = this->MaxValue(); + SMILTime min_value = MinValue(); + SMILTime max_value = MaxValue(); if (min_value > max_value) { // Ignore both. // http://www.w3.org/TR/2001/REC-smil-animation-20010904/#MinMax @@ -804,9 +806,9 @@ SMILInterval SVGSMILElement::ResolveInterval( IntervalSelector interval_selector) const { bool first = interval_selector == kFirstInterval; // See the pseudocode in http://www.w3.org/TR/SMIL3/smil-timing.html#q90. - SMILTime begin_after = - first ? -std::numeric_limits<double>::infinity() : interval_.end; - SMILTime last_interval_temp_end = std::numeric_limits<double>::infinity(); + auto constexpr infinity = std::numeric_limits<double>::infinity(); + SMILTime begin_after = first ? -infinity : interval_.end; + SMILTime last_interval_temp_end = infinity; while (true) { bool equals_minimum_ok = !first || interval_.end > interval_.begin; SMILTime temp_begin = @@ -843,7 +845,7 @@ void SVGSMILElement::ResolveFirstInterval() { if (!first_interval.begin.IsUnresolved() && first_interval != interval_) { interval_ = first_interval; - NotifyDependentsIntervalChanged(); + NotifyDependentsIntervalChanged(interval_); next_progress_time_ = next_progress_time_.IsUnresolved() ? interval_.begin : std::min(next_progress_time_, interval_.begin); @@ -853,21 +855,16 @@ void SVGSMILElement::ResolveFirstInterval() { } } -bool SVGSMILElement::ResolveNextInterval() { +base::Optional<SMILInterval> SVGSMILElement::ResolveNextInterval() { SMILInterval next_interval = ResolveInterval(kNextInterval); DCHECK(!next_interval.begin.IsIndefinite()); if (!next_interval.begin.IsUnresolved() && next_interval.begin != interval_.begin) { - interval_ = next_interval; - NotifyDependentsIntervalChanged(); - next_progress_time_ = next_progress_time_.IsUnresolved() - ? interval_.begin - : std::min(next_progress_time_, interval_.begin); - return true; + return next_interval; } - return false; + return base::nullopt; } SMILTime SVGSMILElement::NextProgressTime() const { @@ -892,7 +889,7 @@ void SVGSMILElement::BeginListChanged(SMILTime event_time) { if (GetActiveState() != kActive) EndedActiveInterval(); } - NotifyDependentsIntervalChanged(); + NotifyDependentsIntervalChanged(interval_); } } } @@ -903,7 +900,7 @@ void SVGSMILElement::BeginListChanged(SMILTime event_time) { } void SVGSMILElement::EndListChanged(SMILTime) { - SMILTime elapsed = this->Elapsed(); + SMILTime elapsed = Elapsed(); if (is_waiting_for_first_interval_) { ResolveFirstInterval(); } else if (elapsed < interval_.end && interval_.begin.IsFinite()) { @@ -912,7 +909,7 @@ void SVGSMILElement::EndListChanged(SMILTime) { new_end = ResolveActiveEnd(interval_.begin, new_end); if (new_end != interval_.end) { interval_.end = new_end; - NotifyDependentsIntervalChanged(); + NotifyDependentsIntervalChanged(interval_); } } } @@ -922,35 +919,35 @@ void SVGSMILElement::EndListChanged(SMILTime) { time_container_->NotifyIntervalsChanged(); } -SVGSMILElement::RestartedInterval SVGSMILElement::MaybeRestartInterval( +base::Optional<SMILInterval> SVGSMILElement::CheckForNewRestartInterval( double elapsed) { DCHECK(!is_waiting_for_first_interval_); DCHECK(elapsed >= interval_.begin); Restart restart = GetRestart(); if (restart == kRestartNever) - return kDidNotRestartInterval; + return base::nullopt; - if (elapsed < interval_.end) { - if (restart != kRestartAlways) - return kDidNotRestartInterval; + base::Optional<SMILInterval> modified; + if (elapsed < interval_.end && restart == kRestartAlways) { SMILTime next_begin = FindInstanceTime(kBegin, interval_.begin, false); if (next_begin < interval_.end) { - interval_.end = next_begin; - NotifyDependentsIntervalChanged(); + modified = interval_; + modified->end = next_begin; } } - if (elapsed >= interval_.end) { - if (ResolveNextInterval() && elapsed >= interval_.begin) - return kDidRestartInterval; + if ((modified && elapsed >= modified->end) || + (!modified && elapsed >= interval_.end)) { + modified = ResolveNextInterval(); } - return kDidNotRestartInterval; + + return modified; } void SVGSMILElement::SeekToIntervalCorrespondingToTime(double elapsed) { DCHECK(!is_waiting_for_first_interval_); - DCHECK(elapsed >= interval_.begin); + DCHECK(interval_.begin.IsFinite()); // Manually seek from interval to interval, just as if the animation would run // regulary. @@ -971,16 +968,33 @@ void SVGSMILElement::SeekToIntervalCorrespondingToTime(double elapsed) { // End current interval, and start a new interval from the 'nextBegin' // time. interval_.end = next_begin; - if (!ResolveNextInterval()) + + base::Optional<SMILInterval> next_interval = ResolveNextInterval(); + if (!next_interval) break; + + interval_ = *next_interval; + NotifyDependentsIntervalChanged(interval_); + next_progress_time_ = + next_progress_time_.IsUnresolved() + ? interval_.begin + : std::min(next_progress_time_, interval_.begin); continue; } // If the desired 'elapsed' time is past the current interval, advance to // the next. if (elapsed >= interval_.end) { - if (!ResolveNextInterval()) + base::Optional<SMILInterval> next_interval = ResolveNextInterval(); + if (!next_interval) break; + + interval_ = *next_interval; + NotifyDependentsIntervalChanged(interval_); + next_progress_time_ = + next_progress_time_.IsUnresolved() + ? interval_.begin + : std::min(next_progress_time_, interval_.begin); continue; } @@ -988,45 +1002,57 @@ void SVGSMILElement::SeekToIntervalCorrespondingToTime(double elapsed) { } } -float SVGSMILElement::CalculateAnimationPercentAndRepeat( - double elapsed, - unsigned& repeat) const { - SMILTime simple_duration = this->SimpleDuration(); - repeat = 0; +unsigned SVGSMILElement::CalculateAnimationRepeat(double elapsed) const { + const SMILTime simple_duration = SimpleDuration(); + if (simple_duration.IsIndefinite() || !simple_duration) + return 0; + DCHECK(simple_duration.IsFinite()); + DCHECK(interval_.begin.IsFinite()); + + double active_time = std::max(elapsed - interval_.begin.Value(), 0.0); + SMILTime repeating_duration = RepeatingDuration(); + if (elapsed >= interval_.end || active_time > repeating_duration) { + unsigned repeat = static_cast<unsigned>(repeating_duration.Value() / + simple_duration.Value()); + if (!fmod(repeating_duration.Value(), simple_duration.Value())) + return repeat - 1; + return repeat; + } + unsigned repeat = + static_cast<unsigned>(active_time / simple_duration.Value()); + return repeat; +} + +float SVGSMILElement::CalculateAnimationPercent(double elapsed) const { + SMILTime simple_duration = SimpleDuration(); if (simple_duration.IsIndefinite()) { - repeat = 0; return 0.f; } if (!simple_duration) { - repeat = 0; return 1.f; } - DCHECK(interval_.begin.IsFinite()); DCHECK(simple_duration.IsFinite()); + DCHECK(interval_.begin.IsFinite()); + + SMILTime repeating_duration = RepeatingDuration(); double active_time = elapsed - interval_.begin.Value(); - SMILTime repeating_duration = this->RepeatingDuration(); if (elapsed >= interval_.end || active_time > repeating_duration) { - repeat = static_cast<unsigned>(repeating_duration.Value() / - simple_duration.Value()); - if (!fmod(repeating_duration.Value(), simple_duration.Value())) - repeat--; - // Use the interval to compute the interval position if we've passed the // interval end, otherwise use the "repeating duration". This prevents a // stale interval (with for instance an 'indefinite' end) from yielding an // invalid interval position. - double last_active_duration = - elapsed >= interval_.end - ? interval_.end.Value() - interval_.begin.Value() - : repeating_duration.Value(); + double last_active_duration; + if (elapsed >= interval_.end) + last_active_duration = interval_.end.Value() - interval_.begin.Value(); + else + last_active_duration = repeating_duration.Value(); double percent = last_active_duration / simple_duration.Value(); percent = percent - floor(percent); - if (percent < std::numeric_limits<float>::epsilon() || - 1 - percent < std::numeric_limits<float>::epsilon()) + float epsilon = std::numeric_limits<float>::epsilon(); + if (percent < epsilon || 1 - percent < epsilon) return 1.0f; return clampTo<float>(percent); } - repeat = static_cast<unsigned>(active_time / simple_duration.Value()); double simple_time = fmod(active_time, simple_duration.Value()); return clampTo<float>(simple_time / simple_duration.Value()); } @@ -1035,7 +1061,7 @@ SMILTime SVGSMILElement::CalculateNextProgressTime(double elapsed) const { if (GetActiveState() == kActive) { // If duration is indefinite the value does not actually change over time. // Same is true for <set>. - SMILTime simple_duration = this->SimpleDuration(); + SMILTime simple_duration = SimpleDuration(); if (simple_duration.IsIndefinite() || IsSVGSetElement(*this)) { SMILTime repeating_duration_end = interval_.begin + RepeatingDuration(); // We are supposed to do freeze semantics when repeating ends, even if the @@ -1069,13 +1095,19 @@ bool SVGSMILElement::IsContributing(double elapsed) const { GetActiveState() == kFrozen; } -bool SVGSMILElement::Progress(double elapsed, bool seek_to_time) { +// The first part of the processing of the animation, +// this checks if there are any further calculations needed +// to continue and makes sure the intervals are correct. +bool SVGSMILElement::NeedsToProgress(double elapsed) { + // Check we're connected to something. DCHECK(time_container_); + // Check that we have some form of start or are prepared to find it. DCHECK(is_waiting_for_first_interval_ || interval_.begin.IsFinite()); if (!sync_base_conditions_connected_) ConnectSyncBaseConditions(); + // Check if we need updating, otherwise just return. if (!interval_.begin.IsFinite()) { DCHECK_EQ(GetActiveState(), kInactive); next_progress_time_ = SMILTime::Unresolved(); @@ -1085,39 +1117,92 @@ bool SVGSMILElement::Progress(double elapsed, bool seek_to_time) { if (elapsed < interval_.begin) { DCHECK_NE(GetActiveState(), kActive); next_progress_time_ = interval_.begin; - // If the animation is frozen, it's still contributing. - return GetActiveState() == kFrozen; + return false; } - previous_interval_begin_ = interval_.begin; if (is_waiting_for_first_interval_) { is_waiting_for_first_interval_ = false; ResolveFirstInterval(); } + return true; +} +void SVGSMILElement::TriggerPendingEvents(double elapsed) { + if (GetActiveState() == kInactive) + ScheduleEvent(event_type_names::kBeginEvent); + + unsigned repeat = CalculateAnimationRepeat(elapsed); + if (repeat) { + for (unsigned repeat_event_count = 1; repeat_event_count < repeat; + repeat_event_count++) + ScheduleRepeatEvents(repeat_event_count); + if (GetActiveState() == kInactive) + ScheduleRepeatEvents(repeat); + } + + if (GetActiveState() == kInactive || GetActiveState() == kFrozen) + ScheduleEvent(event_type_names::kEndEvent); +} + +void SVGSMILElement::UpdateSyncbases() { + if (!interval_has_changed_) + return; + interval_has_changed_ = false; + NotifyDependentsIntervalChanged(interval_); + next_progress_time_ = next_progress_time_.IsUnresolved() + ? interval_.begin + : std::min(next_progress_time_, interval_.begin); +} + +void SVGSMILElement::UpdateNextProgressTime(double elapsed) { + next_progress_time_ = CalculateNextProgressTime(elapsed); +} + +void SVGSMILElement::Progress(double elapsed, bool seek_to_time) { // This call may obtain a new interval -- never call - // calculateAnimationPercentAndRepeat() before! + // CalculateAnimation{ Percent, Repeat }() before! if (seek_to_time) { SeekToIntervalCorrespondingToTime(elapsed); if (elapsed < interval_.begin) { // elapsed is not within an interval. next_progress_time_ = interval_.begin; - return false; + return; } } - unsigned repeat = 0; - float percent = CalculateAnimationPercentAndRepeat(elapsed, repeat); - RestartedInterval restarted_interval = MaybeRestartInterval(elapsed); + float percent = CalculateAnimationPercent(elapsed); + unsigned repeat = CalculateAnimationRepeat(elapsed); + + base::Optional<SMILInterval> new_interval = + CheckForNewRestartInterval(elapsed); + + // This boolean is quite intricate. (Bug 379751) + // + // If we get a new interval we send all events + bool interval_did_start_or_end = (new_interval && *new_interval != interval_); + + // This catches a tricky edge case where the interval began and ended + // on the same frame. So we check if the interval has passed, and + // that it's not the same interval as it was last time. + bool new_begin_time = + (interval_.begin != previous_interval_begin_ && interval_.end <= elapsed); + + if (new_begin_time) { + previous_interval_begin_ = interval_.begin; + interval_did_start_or_end = true; + } + + if (new_interval) { + interval_ = *new_interval; + interval_has_changed_ = true; + } ActiveState old_active_state = GetActiveState(); active_state_ = DetermineActiveState(elapsed); - bool animation_is_contributing = IsContributing(elapsed); - if (animation_is_contributing) { - if (old_active_state == kInactive || - restarted_interval == kDidRestartInterval) { + if (IsContributing(elapsed)) { + if (old_active_state == kInactive || interval_did_start_or_end) { ScheduleEvent(event_type_names::kBeginEvent); StartedActiveInterval(); } @@ -1130,34 +1215,15 @@ bool SVGSMILElement::Progress(double elapsed, bool seek_to_time) { } if ((old_active_state == kActive && GetActiveState() != kActive) || - restarted_interval == kDidRestartInterval) { + interval_did_start_or_end) { ScheduleEvent(event_type_names::kEndEvent); EndedActiveInterval(); } - - // Triggering all the pending events if the animation timeline is changed. - if (seek_to_time) { - if (GetActiveState() == kInactive) - ScheduleEvent(event_type_names::kBeginEvent); - - if (repeat) { - for (unsigned repeat_event_count = 1; repeat_event_count < repeat; - repeat_event_count++) - ScheduleRepeatEvents(repeat_event_count); - if (GetActiveState() == kInactive) - ScheduleRepeatEvents(repeat); - } - - if (GetActiveState() == kInactive || GetActiveState() == kFrozen) - ScheduleEvent(event_type_names::kEndEvent); - } - - next_progress_time_ = CalculateNextProgressTime(elapsed); - return animation_is_contributing; } -void SVGSMILElement::NotifyDependentsIntervalChanged() { - DCHECK(interval_.begin.IsFinite()); +void SVGSMILElement::NotifyDependentsIntervalChanged( + const SMILInterval& interval) { + DCHECK(interval.begin.IsFinite()); // |loopBreaker| is used to avoid infinite recursions which may be caused by: // |notifyDependentsIntervalChanged| -> |createInstanceTimesFromSyncbase| -> // |add{Begin,End}Time| -> |{begin,end}TimeChanged| -> @@ -1172,13 +1238,14 @@ void SVGSMILElement::NotifyDependentsIntervalChanged() { return; for (SVGSMILElement* element : sync_base_dependents_) - element->CreateInstanceTimesFromSyncbase(*this); + element->CreateInstanceTimesFromSyncbase(*this, interval); loop_breaker.erase(this); } void SVGSMILElement::CreateInstanceTimesFromSyncbase( - SVGSMILElement& sync_base) { + SVGSMILElement& sync_base, + const SMILInterval& interval) { // FIXME: To be really correct, this should handle updating exising interval // by changing the associated times instead of creating new ones. for (Condition* condition : conditions_) { @@ -1189,9 +1256,9 @@ void SVGSMILElement::CreateInstanceTimesFromSyncbase( // conversions. Phew! SMILTime time = 0; if (condition->GetName() == "begin") - time = sync_base.interval_.begin + condition->Offset(); + time = interval.begin + condition->Offset(); else - time = sync_base.interval_.end + condition->Offset(); + time = interval.end + condition->Offset(); if (!time.IsFinite()) continue; AddInstanceTime(condition->GetBeginOrEnd(), time); @@ -1202,7 +1269,7 @@ void SVGSMILElement::CreateInstanceTimesFromSyncbase( void SVGSMILElement::AddSyncBaseDependent(SVGSMILElement& animation) { sync_base_dependents_.insert(&animation); if (interval_.begin.IsFinite()) - animation.CreateInstanceTimesFromSyncbase(*this); + animation.CreateInstanceTimesFromSyncbase(*this, interval_); } void SVGSMILElement::RemoveSyncBaseDependent(SVGSMILElement& animation) { @@ -1267,6 +1334,10 @@ void SVGSMILElement::DidChangeAnimationTarget() { is_scheduled_ = true; } +const AttrNameToTrustedType& SVGSMILElement::GetCheckedAttributeTypes() const { + return SVGURIReference::GetCheckedAttributeTypes(); +} + void SVGSMILElement::Trace(blink::Visitor* visitor) { visitor->Trace(target_element_); visitor->Trace(target_id_observer_); diff --git a/chromium/third_party/blink/renderer/core/svg/animation/svg_smil_element.h b/chromium/third_party/blink/renderer/core/svg/animation/svg_smil_element.h index 5ff56d78fa8..5e801946596 100644 --- a/chromium/third_party/blink/renderer/core/svg/animation/svg_smil_element.h +++ b/chromium/third_party/blink/renderer/core/svg/animation/svg_smil_element.h @@ -85,7 +85,13 @@ class CORE_EXPORT SVGSMILElement : public SVGElement, public SVGTests { SMILTime SimpleDuration() const; void SeekToIntervalCorrespondingToTime(double elapsed); - bool Progress(double elapsed, bool seek_to_time); + + bool NeedsToProgress(double elapsed); + void Progress(double elapsed, bool seek_to_time); + void TriggerPendingEvents(double elapsed); + void UpdateSyncbases(); + void UpdateNextProgressTime(double elapsed); + SMILTime NextProgressTime() const; void UpdateAnimatedValue(SVGSMILElement* result_element) { UpdateAnimation(last_percent_, last_repeat_, result_element); @@ -106,6 +112,11 @@ class CORE_EXPORT SVGSMILElement : public SVGElement, public SVGTests { virtual void ClearAnimatedType() = 0; virtual void ApplyResultsToTarget() = 0; + // Returns true if this animation "sets" the + // value of the animation. Thus all previous + // animations are rendered useless. + virtual bool OverwritesUnderlyingAnimationValue() = 0; + bool AnimatedTypeIsLocked() const { return animated_property_locked_; } void LockAnimatedType() { DCHECK(!animated_property_locked_); @@ -125,6 +136,8 @@ class CORE_EXPORT SVGSMILElement : public SVGElement, public SVGTests { virtual bool IsSVGDiscardElement() const { return false; } + const AttrNameToTrustedType& GetCheckedAttributeTypes() const override; + void Trace(blink::Visitor*) override; protected: @@ -168,14 +181,12 @@ class CORE_EXPORT SVGSMILElement : public SVGElement, public SVGTests { SMILInterval ResolveInterval(IntervalSelector) const; void ResolveFirstInterval(); - bool ResolveNextInterval(); + base::Optional<SMILInterval> ResolveNextInterval(); SMILTime ResolveActiveEnd(SMILTime resolved_begin, SMILTime resolved_end) const; SMILTime RepeatingDuration() const; - enum RestartedInterval { kDidNotRestartInterval, kDidRestartInterval }; - - RestartedInterval MaybeRestartInterval(double elapsed); + base::Optional<SMILInterval> CheckForNewRestartInterval(double elapsed); void BeginListChanged(SMILTime event_time); void EndListChanged(SMILTime event_time); @@ -227,8 +238,9 @@ class CORE_EXPORT SVGSMILElement : public SVGElement, public SVGTests { void DisconnectSyncBaseConditions(); void DisconnectEventBaseConditions(); - void NotifyDependentsIntervalChanged(); - void CreateInstanceTimesFromSyncbase(SVGSMILElement& syncbase); + void NotifyDependentsIntervalChanged(const SMILInterval& interval); + void CreateInstanceTimesFromSyncbase(SVGSMILElement& syncbase, + const SMILInterval& interval); void AddSyncBaseDependent(SVGSMILElement&); void RemoveSyncBaseDependent(SVGSMILElement&); @@ -238,8 +250,8 @@ class CORE_EXPORT SVGSMILElement : public SVGElement, public SVGTests { return static_cast<ActiveState>(active_state_); } ActiveState DetermineActiveState(SMILTime elapsed) const; - float CalculateAnimationPercentAndRepeat(double elapsed, - unsigned& repeat) const; + float CalculateAnimationPercent(double elapsed) const; + unsigned CalculateAnimationRepeat(double elapsed) const; SMILTime CalculateNextProgressTime(double elapsed) const; Member<SVGElement> target_element_; @@ -284,6 +296,7 @@ class CORE_EXPORT SVGSMILElement : public SVGElement, public SVGTests { mutable SMILTime cached_max_; bool animated_property_locked_; + bool interval_has_changed_; friend class ConditionEventListener; }; @@ -296,8 +309,15 @@ inline bool IsSVGSMILElement(const SVGElement& element) { element.HasTagName((svg_names::kDiscardTag)); } -DEFINE_SVGELEMENT_TYPE_CASTS_WITH_FUNCTION(SVGSMILElement); +template <> +struct DowncastTraits<SVGSMILElement> { + static bool AllowFrom(const Node& node) { + auto* svg_element = DynamicTo<SVGElement>(node); + return svg_element && IsSVGSMILElement(*svg_element); + } +}; +DEFINE_SVGELEMENT_TYPE_CASTS_WITH_FUNCTION(SVGSMILElement); } // namespace blink #endif // THIRD_PARTY_BLINK_RENDERER_CORE_SVG_ANIMATION_SVG_SMIL_ELEMENT_H_ diff --git a/chromium/third_party/blink/renderer/core/svg/color_distance.h b/chromium/third_party/blink/renderer/core/svg/color_distance.h index f69c1c1748c..cef574f78e4 100644 --- a/chromium/third_party/blink/renderer/core/svg/color_distance.h +++ b/chromium/third_party/blink/renderer/core/svg/color_distance.h @@ -20,7 +20,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_SVG_COLOR_DISTANCE_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_SVG_COLOR_DISTANCE_H_ -#include "third_party/blink/renderer/platform/wtf/allocator.h" +#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" namespace blink { diff --git a/chromium/third_party/blink/renderer/core/svg/gradient_attributes.h b/chromium/third_party/blink/renderer/core/svg/gradient_attributes.h index a6eb3872330..18eadcfd26c 100644 --- a/chromium/third_party/blink/renderer/core/svg/gradient_attributes.h +++ b/chromium/third_party/blink/renderer/core/svg/gradient_attributes.h @@ -22,7 +22,7 @@ #include "third_party/blink/renderer/core/svg/svg_gradient_element.h" #include "third_party/blink/renderer/core/svg/svg_unit_types.h" -#include "third_party/blink/renderer/platform/wtf/allocator.h" +#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" namespace blink { diff --git a/chromium/third_party/blink/renderer/core/svg/graphics/dark_mode_svg_image_classifier.cc b/chromium/third_party/blink/renderer/core/svg/graphics/dark_mode_svg_image_classifier.cc index da38d471619..5947150aac5 100644 --- a/chromium/third_party/blink/renderer/core/svg/graphics/dark_mode_svg_image_classifier.cc +++ b/chromium/third_party/blink/renderer/core/svg/graphics/dark_mode_svg_image_classifier.cc @@ -11,7 +11,7 @@ DarkModeSVGImageClassifier::DarkModeSVGImageClassifier() {} DarkModeClassification DarkModeSVGImageClassifier::Classify( SVGImage* image, const FloatRect& src_rect) { - return DarkModeClassification::kApplyDarkModeFilter; + return DarkModeClassification::kApplyFilter; } } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/svg/graphics/dark_mode_svg_image_classifier.h b/chromium/third_party/blink/renderer/core/svg/graphics/dark_mode_svg_image_classifier.h index 62bdaf9feb0..98fa960a33d 100644 --- a/chromium/third_party/blink/renderer/core/svg/graphics/dark_mode_svg_image_classifier.h +++ b/chromium/third_party/blink/renderer/core/svg/graphics/dark_mode_svg_image_classifier.h @@ -8,7 +8,7 @@ #include "third_party/blink/renderer/core/svg/graphics/svg_image.h" #include "third_party/blink/renderer/platform/geometry/float_rect.h" #include "third_party/blink/renderer/platform/graphics/graphics_types.h" -#include "third_party/blink/renderer/platform/wtf/allocator.h" +#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" namespace blink { diff --git a/chromium/third_party/blink/renderer/core/svg/graphics/filters/svg_filter_builder.cc b/chromium/third_party/blink/renderer/core/svg/graphics/filters/svg_filter_builder.cc index f7049447a40..751dc6ba66e 100644 --- a/chromium/third_party/blink/renderer/core/svg/graphics/filters/svg_filter_builder.cc +++ b/chromium/third_party/blink/renderer/core/svg/graphics/filters/svg_filter_builder.cc @@ -96,7 +96,7 @@ void SVGFilterGraphNodeMap::InvalidateDependentEffects(FilterEffect* effect) { effect->DisposeImageFilters(); - FilterEffectSet& effect_references = this->EffectReferences(effect); + FilterEffectSet& effect_references = EffectReferences(effect); for (FilterEffect* effect_reference : effect_references) InvalidateDependentEffects(effect_reference); } @@ -179,8 +179,7 @@ void SVGFilterBuilder::BuildGraph(Filter* filter, if (!element->IsFilterEffect()) continue; - SVGFilterPrimitiveStandardAttributes& effect_element = - ToSVGFilterPrimitiveStandardAttributes(*element); + auto& effect_element = To<SVGFilterPrimitiveStandardAttributes>(*element); FilterEffect* effect = effect_element.Build(this, filter); if (!effect) continue; diff --git a/chromium/third_party/blink/renderer/core/svg/graphics/svg_image.cc b/chromium/third_party/blink/renderer/core/svg/graphics/svg_image.cc index 943099a29d8..1801d0f37cc 100644 --- a/chromium/third_party/blink/renderer/core/svg/graphics/svg_image.cc +++ b/chromium/third_party/blink/renderer/core/svg/graphics/svg_image.cc @@ -34,6 +34,7 @@ #include "third_party/blink/renderer/core/dom/events/event_dispatch_forbidden_scope.h" #include "third_party/blink/renderer/core/dom/flat_tree_traversal.h" #include "third_party/blink/renderer/core/dom/node_traversal.h" +#include "third_party/blink/renderer/core/frame/local_dom_window.h" #include "third_party/blink/renderer/core/frame/local_frame.h" #include "third_party/blink/renderer/core/frame/local_frame_client.h" #include "third_party/blink/renderer/core/frame/local_frame_view.h" @@ -673,13 +674,18 @@ void SVGImage::AdvanceAnimationForTesting() { root_element->TimeContainer()->AdvanceFrameForTesting(); // The following triggers animation updates which can issue a new draw - // but will not permanently change the animation timeline. - // TODO(pdr): Actually advance the document timeline so CSS animations - // can be properly tested. + // and temporarily change the animation timeline. It's necessary to call + // reset before changing to a time value as animation clock does not + // expect to go backwards. + base::TimeTicks current_animation_time = + page_->Animator().Clock().CurrentTime(); + page_->Animator().Clock().ResetTimeForTesting(); page_->Animator().ServiceScriptedAnimations( - base::TimeTicks() + + root_element->GetDocument().Timeline().ZeroTime() + base::TimeDelta::FromSecondsD(root_element->getCurrentTime())); GetImageObserver()->Changed(this); + page_->Animator().Clock().ResetTimeForTesting(); + page_->Animator().Clock().UpdateTime(current_animation_time); } } @@ -789,7 +795,8 @@ Image::SizeAvailability SVGImage::DataChanged(bool all_data_received) { TRACE_EVENT0("blink", "SVGImage::dataChanged::createFrame"); DCHECK(!frame_client_); frame_client_ = MakeGarbageCollected<SVGImageLocalFrameClient>(this); - frame = MakeGarbageCollected<LocalFrame>(frame_client_, *page, nullptr); + frame = MakeGarbageCollected<LocalFrame>(frame_client_, *page, nullptr, + nullptr, nullptr); frame->SetView(MakeGarbageCollected<LocalFrameView>(*frame)); frame->Init(); } @@ -838,6 +845,10 @@ Image::SizeAvailability SVGImage::DataChanged(bool all_data_received) { return kSizeAvailable; } +bool SVGImage::IsSizeAvailable() { + return SvgRootElement(page_.Get()); +} + String SVGImage::FilenameExtension() const { return "svg"; } diff --git a/chromium/third_party/blink/renderer/core/svg/graphics/svg_image.h b/chromium/third_party/blink/renderer/core/svg/graphics/svg_image.h index c501563971b..29fe1bf74c6 100644 --- a/chromium/third_party/blink/renderer/core/svg/graphics/svg_image.h +++ b/chromium/third_party/blink/renderer/core/svg/graphics/svg_image.h @@ -33,7 +33,7 @@ #include "third_party/blink/renderer/platform/graphics/paint/paint_record.h" #include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/weborigin/kurl.h" -#include "third_party/blink/renderer/platform/wtf/allocator.h" +#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" #include "third_party/skia/include/core/SkRefCnt.h" namespace blink { @@ -126,7 +126,7 @@ class CORE_EXPORT SVGImage final : public Image { protected: // Whether or not size is available yet. - bool IsSizeAvailable() override { return !!page_; } + bool IsSizeAvailable() override; private: // Accesses m_page. @@ -245,8 +245,9 @@ class CORE_EXPORT SVGImage final : public Image { FRIEND_TEST_ALL_PREFIXES(ElementFragmentAnchorTest, SVGDocumentDoesntCreateFragment); FRIEND_TEST_ALL_PREFIXES(SVGImageTest, SupportsSubsequenceCaching); - FRIEND_TEST_ALL_PREFIXES(SVGImageTest, JankTrackerDisabled); + FRIEND_TEST_ALL_PREFIXES(SVGImageTest, LayoutShiftTrackerDisabled); FRIEND_TEST_ALL_PREFIXES(SVGImageTest, SetSizeOnVisualViewport); + FRIEND_TEST_ALL_PREFIXES(SVGImageTest, IsSizeAvailable); }; DEFINE_IMAGE_TYPE_CASTS(SVGImage); diff --git a/chromium/third_party/blink/renderer/core/svg/graphics/svg_image_chrome_client.cc b/chromium/third_party/blink/renderer/core/svg/graphics/svg_image_chrome_client.cc index 058982369b9..141c30d0d25 100644 --- a/chromium/third_party/blink/renderer/core/svg/graphics/svg_image_chrome_client.cc +++ b/chromium/third_party/blink/renderer/core/svg/graphics/svg_image_chrome_client.cc @@ -38,8 +38,8 @@ namespace blink { -static constexpr TimeDelta kAnimationFrameDelay = - TimeDelta::FromSecondsD(1.0 / 60); +static constexpr base::TimeDelta kAnimationFrameDelay = + base::TimeDelta::FromSecondsD(1.0 / 60); SVGImageChromeClient::SVGImageChromeClient(SVGImage* image) : image_(image), @@ -104,7 +104,7 @@ void SVGImageChromeClient::ScheduleAnimation(const LocalFrameView*) { // animations, but prefer a fixed, jittery, frame-delay if there're any // animations. Checking for pending/active animations could be more // stringent. - TimeDelta fire_time; + base::TimeDelta fire_time; if (image_->MaybeAnimated()) { if (IsSuspended()) return; @@ -131,7 +131,7 @@ void SVGImageChromeClient::AnimationTimerFired(TimerBase*) { if (!image_->GetImageObserver()) return; - image_->ServiceAnimations(CurrentTimeTicks()); + image_->ServiceAnimations(base::TimeTicks::Now()); } } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/svg/graphics/svg_image_test.cc b/chromium/third_party/blink/renderer/core/svg/graphics/svg_image_test.cc index f6adc8da886..078ece67a1f 100644 --- a/chromium/third_party/blink/renderer/core/svg/graphics/svg_image_test.cc +++ b/chromium/third_party/blink/renderer/core/svg/graphics/svg_image_test.cc @@ -12,7 +12,7 @@ #include "third_party/blink/renderer/core/frame/local_frame_view.h" #include "third_party/blink/renderer/core/frame/visual_viewport.h" #include "third_party/blink/renderer/core/html/html_image_element.h" -#include "third_party/blink/renderer/core/layout/jank_tracker.h" +#include "third_party/blink/renderer/core/layout/layout_shift_tracker.h" #include "third_party/blink/renderer/core/layout/layout_view.h" #include "third_party/blink/renderer/core/paint/paint_layer.h" #include "third_party/blink/renderer/core/svg/graphics/svg_image_chrome_client.h" @@ -114,7 +114,7 @@ TEST_F(SVGImageTest, TimelineSuspendAndResume) { // Fire the timer/trigger a frame update. Since the observer always returns // true for shouldPauseAnimation, this will result in the timeline being // suspended. - test::RunDelayedTasks(TimeDelta::FromMilliseconds(1) + + test::RunDelayedTasks(base::TimeDelta::FromMilliseconds(1) + timer->NextFireInterval()); EXPECT_TRUE(chrome_client.IsSuspended()); EXPECT_FALSE(timer->IsActive()); @@ -148,7 +148,7 @@ TEST_F(SVGImageTest, ResetAnimation) { // Fire the timer/trigger a frame update. The timeline will remain // suspended and no frame will be scheduled. - test::RunDelayedTasks(TimeDelta::FromMillisecondsD(1) + + test::RunDelayedTasks(base::TimeDelta::FromMillisecondsD(1) + timer->NextFireInterval()); EXPECT_TRUE(chrome_client.IsSuspended()); EXPECT_FALSE(timer->IsActive()); @@ -172,14 +172,14 @@ TEST_F(SVGImageTest, SupportsSubsequenceCaching) { ToLayoutBoxModelObject(svg_root)->Layer()->SupportsSubsequenceCaching()); } -TEST_F(SVGImageTest, JankTrackerDisabled) { +TEST_F(SVGImageTest, LayoutShiftTrackerDisabled) { const bool kDontPause = false; Load("<svg xmlns='http://www.w3.org/2000/svg'></svg>", kDontPause); LocalFrame* local_frame = To<LocalFrame>(GetImage().GetPageForTesting()->MainFrame()); EXPECT_TRUE(local_frame->GetDocument()->IsSVGDocument()); - auto& jank_tracker = local_frame->View()->GetJankTracker(); - EXPECT_FALSE(jank_tracker.IsActive()); + auto& layout_shift_tracker = local_frame->View()->GetLayoutShiftTracker(); + EXPECT_FALSE(layout_shift_tracker.IsActive()); } TEST_F(SVGImageTest, SetSizeOnVisualViewport) { @@ -197,6 +197,18 @@ TEST_F(SVGImageTest, SetSizeOnVisualViewport) { GetImage().GetPageForTesting()->GetVisualViewport().Size()); } +TEST_F(SVGImageTest, IsSizeAvailable) { + const bool kShouldPause = false; + Load("<svg xmlns='http://www.w3.org/2000/svg'></svg>", kShouldPause); + EXPECT_TRUE(GetImage().IsSizeAvailable()); + + Load("<notsvg></notsvg>", kShouldPause); + EXPECT_FALSE(GetImage().IsSizeAvailable()); + + Load("<notsvg xmlns='http://www.w3.org/2000/svg'></notsvg>", kShouldPause); + EXPECT_FALSE(GetImage().IsSizeAvailable()); +} + class SVGImageSimTest : public SimTest {}; TEST_F(SVGImageSimTest, PageVisibilityHiddenToVisible) { @@ -226,7 +238,7 @@ TEST_F(SVGImageSimTest, PageVisibilityHiddenToVisible) { // Wait for the next animation frame to be triggered, and then trigger a new // frame. The image animation timeline should be running. - test::RunDelayedTasks(TimeDelta::FromMilliseconds(1) + + test::RunDelayedTasks(base::TimeDelta::FromMilliseconds(1) + timer->NextFireInterval()); Compositor().BeginFrame(); @@ -236,7 +248,7 @@ TEST_F(SVGImageSimTest, PageVisibilityHiddenToVisible) { // fire. This should suspend the image animation. (Suspend the image's // animation timeline.) WebView().SetIsHidden(/*is_hidden=*/true, /*initial_state=*/false); - test::RunDelayedTasks(TimeDelta::FromMilliseconds(1) + + test::RunDelayedTasks(base::TimeDelta::FromMilliseconds(1) + timer->NextFireInterval()); EXPECT_TRUE(svg_image_chrome_client.IsSuspended()); @@ -244,7 +256,7 @@ TEST_F(SVGImageSimTest, PageVisibilityHiddenToVisible) { // Set page visibility to 'visible' - this should schedule a new animation // frame and resume the image animation. WebView().SetIsHidden(/*is_hidden=*/false, /*initial_state=*/false); - test::RunDelayedTasks(TimeDelta::FromMilliseconds(1) + + test::RunDelayedTasks(base::TimeDelta::FromMilliseconds(1) + timer->NextFireInterval()); Compositor().BeginFrame(); diff --git a/chromium/third_party/blink/renderer/core/svg/properties/svg_animated_property.cc b/chromium/third_party/blink/renderer/core/svg/properties/svg_animated_property.cc index 00baabda75f..31b4b832dd5 100644 --- a/chromium/third_party/blink/renderer/core/svg/properties/svg_animated_property.cc +++ b/chromium/third_party/blink/renderer/core/svg/properties/svg_animated_property.cc @@ -51,8 +51,8 @@ SVGAnimatedPropertyBase::SVGAnimatedPropertyBase( attribute_name_(attribute_name) { DCHECK(context_element_); DCHECK(attribute_name_ != QualifiedName::Null()); - DCHECK_EQ(this->GetType(), type); - DCHECK_EQ(this->CssPropertyId(), css_property_id); + DCHECK_EQ(GetType(), type); + DCHECK_EQ(CssPropertyId(), css_property_id); DCHECK_EQ(initial_value_storage_, initial_value); } diff --git a/chromium/third_party/blink/renderer/core/svg/properties/svg_list_property_helper.h b/chromium/third_party/blink/renderer/core/svg/properties/svg_list_property_helper.h index 866817217a3..7596e65f652 100644 --- a/chromium/third_party/blink/renderer/core/svg/properties/svg_list_property_helper.h +++ b/chromium/third_party/blink/renderer/core/svg/properties/svg_list_property_helper.h @@ -36,7 +36,7 @@ #include "third_party/blink/renderer/platform/bindings/exception_messages.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" #include "third_party/blink/renderer/platform/heap/heap.h" -#include "third_party/blink/renderer/platform/wtf/allocator.h" +#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" #include "third_party/blink/renderer/platform/wtf/vector.h" namespace blink { diff --git a/chromium/third_party/blink/renderer/core/svg/svg_a_element.cc b/chromium/third_party/blink/renderer/core/svg/svg_a_element.cc index 0a7bb9f24ca..f44723cbf89 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_a_element.cc +++ b/chromium/third_party/blink/renderer/core/svg/svg_a_element.cc @@ -120,8 +120,9 @@ void SVGAElement::DefaultEventHandler(Event& event) { if (url[0] == '#') { Element* target_element = GetTreeScope().getElementById(AtomicString(url.Substring(1))); - if (target_element && IsSVGSMILElement(*target_element)) { - ToSVGSMILElement(target_element)->BeginByLinkActivation(); + if (auto* svg_smil_element = + DynamicTo<SVGSMILElement>(target_element)) { + svg_smil_element->BeginByLinkActivation(); event.SetDefaultHandled(); return; } @@ -132,14 +133,18 @@ void SVGAElement::DefaultEventHandler(Event& event) { target = AtomicString("_blank"); event.SetDefaultHandled(); + if (!GetDocument().GetFrame()) + return; + FrameLoadRequest frame_request( &GetDocument(), ResourceRequest(GetDocument().CompleteURL(url))); frame_request.SetNavigationPolicy(NavigationPolicyFromEvent(&event)); frame_request.SetTriggeringEventInfo( event.isTrusted() ? WebTriggeringEventInfo::kFromTrustedEvent : WebTriggeringEventInfo::kFromUntrustedEvent); - if (!GetDocument().GetFrame()) - return; + frame_request.GetResourceRequest().SetHasUserGesture( + LocalFrame::HasTransientUserActivation(GetDocument().GetFrame())); + Frame* frame = GetDocument() .GetFrame() ->Tree() diff --git a/chromium/third_party/blink/renderer/core/svg/svg_a_element.h b/chromium/third_party/blink/renderer/core/svg/svg_a_element.h index 0302bcae462..19cfd753e5a 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_a_element.h +++ b/chromium/third_party/blink/renderer/core/svg/svg_a_element.h @@ -38,6 +38,10 @@ class CORE_EXPORT SVGAElement final : public SVGGraphicsElement, explicit SVGAElement(Document&); + const AttrNameToTrustedType& GetCheckedAttributeTypes() const override { + return SVGURIReference::GetCheckedAttributeTypes(); + } + void Trace(blink::Visitor*) override; private: diff --git a/chromium/third_party/blink/renderer/core/svg/svg_a_element.idl b/chromium/third_party/blink/renderer/core/svg/svg_a_element.idl index 29e46a3f5ef..cdc459e6628 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_a_element.idl +++ b/chromium/third_party/blink/renderer/core/svg/svg_a_element.idl @@ -25,6 +25,7 @@ // https://svgwg.org/svg2-draft/linking.html#InterfaceSVGAElement +[Exposed=Window] interface SVGAElement : SVGGraphicsElement { [ImplementedAs=svgTarget, Measure] readonly attribute SVGAnimatedString target; }; diff --git a/chromium/third_party/blink/renderer/core/svg/svg_angle.idl b/chromium/third_party/blink/renderer/core/svg/svg_angle.idl index e684b5582cb..84a5f2907c0 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_angle.idl +++ b/chromium/third_party/blink/renderer/core/svg/svg_angle.idl @@ -23,6 +23,7 @@ // https://svgwg.org/svg2-draft/types.html#InterfaceSVGAngle [ + Exposed=Window, ImplementedAs=SVGAngleTearOff ] interface SVGAngle { // Angle Unit Types diff --git a/chromium/third_party/blink/renderer/core/svg/svg_animate_element.cc b/chromium/third_party/blink/renderer/core/svg/svg_animate_element.cc index 7cb6975172d..8096b369441 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_animate_element.cc +++ b/chromium/third_party/blink/renderer/core/svg/svg_animate_element.cc @@ -339,8 +339,7 @@ void SVGAnimateElement::CalculateAnimatedValue(float percentage, DCHECK_EQ(from_property_->GetType(), GetAnimatedPropertyType()); DCHECK(to_property_); - SVGAnimateElement* result_animation_element = - ToSVGAnimateElement(result_element); + auto* result_animation_element = To<SVGAnimateElement>(result_element); DCHECK(result_animation_element->animated_value_); DCHECK_EQ(result_animation_element->GetAnimatedPropertyType(), GetAnimatedPropertyType()); @@ -352,7 +351,7 @@ void SVGAnimateElement::CalculateAnimatedValue(float percentage, percentage = percentage < 0.5 ? 0 : 1; // Target element might have changed. - SVGElement* target_element = this->targetElement(); + SVGElement* target_element = targetElement(); // Values-animation accumulates using the last values entry corresponding to // the end of duration time. @@ -419,8 +418,8 @@ bool SVGAnimateElement::CalculateFromAndByValues(const String& from_string, void SVGAnimateElement::ResetAnimatedType() { ResolveTargetProperty(); - SVGElement* target_element = this->targetElement(); - const QualifiedName& attribute_name = this->AttributeName(); + SVGElement* target_element = targetElement(); + const QualifiedName& attribute_name = AttributeName(); if (!ShouldApplyAnimation(*target_element, attribute_name)) return; @@ -451,7 +450,7 @@ void SVGAnimateElement::ClearAnimatedType() { // the lock is held. See crbug.com/581546. DCHECK(!AnimatedTypeIsLocked()); - SVGElement* target_element = this->targetElement(); + SVGElement* target_element = targetElement(); if (!target_element) { animated_value_.Clear(); return; @@ -489,7 +488,8 @@ void SVGAnimateElement::ApplyResultsToTarget() { if (!animated_value_) return; - if (!ShouldApplyAnimation(*targetElement(), AttributeName())) + SVGElement* target_element = targetElement(); + if (!ShouldApplyAnimation(*target_element, AttributeName())) return; // We do update the style and the animation property independent of each @@ -497,15 +497,17 @@ void SVGAnimateElement::ApplyResultsToTarget() { if (IsAnimatingCSSProperty()) { // CSS properties animation code-path. // Convert the result of the animation to a String and apply it as CSS - // property on the target. - MutableCSSPropertyValueSet* property_set = - targetElement()->EnsureAnimatedSMILStyleProperties(); - if (property_set - ->SetProperty( - css_property_id_, animated_value_->ValueAsString(), false, - targetElement()->GetDocument().GetSecureContextMode(), nullptr) - .did_change) { - targetElement()->SetNeedsStyleRecalc( + // property on the target_element. + MutableCSSPropertyValueSet* properties = + target_element->EnsureAnimatedSMILStyleProperties(); + auto animated_value_string = animated_value_->ValueAsString(); + auto secure_context_mode = + target_element->GetDocument().GetSecureContextMode(); + auto set_result = + properties->SetProperty(css_property_id_, animated_value_string, false, + secure_context_mode, nullptr); + if (set_result.did_change) { + target_element->SetNeedsStyleRecalc( kLocalStyleChange, StyleChangeReasonForTracing::Create(style_change_reason::kAnimation)); } diff --git a/chromium/third_party/blink/renderer/core/svg/svg_animate_element.h b/chromium/third_party/blink/renderer/core/svg/svg_animate_element.h index 04d066604d1..094435aef5d 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_animate_element.h +++ b/chromium/third_party/blink/renderer/core/svg/svg_animate_element.h @@ -137,7 +137,13 @@ inline bool IsSVGAnimateElement(const SVGElement& element) { element.HasTagName(svg_names::kSetTag); } -DEFINE_SVGELEMENT_TYPE_CASTS_WITH_FUNCTION(SVGAnimateElement); +template <> +struct DowncastTraits<SVGAnimateElement> { + static bool AllowFrom(const Node& node) { + auto* element = DynamicTo<SVGElement>(node); + return element && IsSVGAnimateElement(*element); + } +}; } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/svg/svg_animate_motion_element.cc b/chromium/third_party/blink/renderer/core/svg/svg_animate_motion_element.cc index fa8c8d5fc7e..c0c87d99464 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_animate_motion_element.cc +++ b/chromium/third_party/blink/renderer/core/svg/svg_animate_motion_element.cc @@ -143,7 +143,7 @@ static bool ParsePoint(const String& string, FloatPoint& point) { } void SVGAnimateMotionElement::ResetAnimatedType() { - SVGElement* target_element = this->targetElement(); + SVGElement* target_element = targetElement(); if (!target_element || !TargetCanHaveMotionTransform(*target_element)) return; if (AffineTransform* transform = target_element->AnimateMotionTransform()) @@ -151,7 +151,7 @@ void SVGAnimateMotionElement::ResetAnimatedType() { } void SVGAnimateMotionElement::ClearAnimatedType() { - SVGElement* target_element = this->targetElement(); + SVGElement* target_element = targetElement(); if (!target_element) return; @@ -198,7 +198,7 @@ bool SVGAnimateMotionElement::CalculateFromAndByValues( void SVGAnimateMotionElement::CalculateAnimatedValue(float percentage, unsigned repeat_count, SVGSMILElement*) { - SVGElement* target_element = this->targetElement(); + SVGElement* target_element = targetElement(); DCHECK(target_element); AffineTransform* transform = target_element->AnimateMotionTransform(); if (!transform) @@ -245,7 +245,7 @@ void SVGAnimateMotionElement::CalculateAnimatedValue(float percentage, } transform->Translate(position.X(), position.Y()); - RotateMode rotate_mode = this->GetRotateMode(); + RotateMode rotate_mode = GetRotateMode(); if (rotate_mode != kRotateAuto && rotate_mode != kRotateAutoReverse) return; if (rotate_mode == kRotateAutoReverse) @@ -256,23 +256,23 @@ void SVGAnimateMotionElement::CalculateAnimatedValue(float percentage, void SVGAnimateMotionElement::ApplyResultsToTarget() { // We accumulate to the target element transform list so there is not much to // do here. - SVGElement* target_element = this->targetElement(); + SVGElement* target_element = targetElement(); if (!target_element) return; - AffineTransform* t = target_element->AnimateMotionTransform(); - if (!t) + AffineTransform* target_transform = target_element->AnimateMotionTransform(); + if (!target_transform) return; // ...except in case where we have additional instances in <use> trees. - const HeapHashSet<WeakMember<SVGElement>>& instances = - target_element->InstancesForElement(); + const auto& instances = target_element->InstancesForElement(); for (SVGElement* shadow_tree_element : instances) { DCHECK(shadow_tree_element); - AffineTransform* transform = shadow_tree_element->AnimateMotionTransform(); - if (!transform) + AffineTransform* shadow_transform = + shadow_tree_element->AnimateMotionTransform(); + if (!shadow_transform) continue; - transform->SetMatrix(t->A(), t->B(), t->C(), t->D(), t->E(), t->F()); + shadow_transform->SetTransform(*target_transform); if (LayoutObject* layout_object = shadow_tree_element->GetLayoutObject()) InvalidateForAnimateMotionTransformChange(*layout_object); } diff --git a/chromium/third_party/blink/renderer/core/svg/svg_animated_angle.idl b/chromium/third_party/blink/renderer/core/svg/svg_animated_angle.idl index 73997a2c16f..2c6575dee30 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_animated_angle.idl +++ b/chromium/third_party/blink/renderer/core/svg/svg_animated_angle.idl @@ -25,6 +25,7 @@ // https://svgwg.org/svg2-draft/types.html#InterfaceSVGAnimatedAngle +[Exposed=Window] interface SVGAnimatedAngle { readonly attribute SVGAngle baseVal; readonly attribute SVGAngle animVal; diff --git a/chromium/third_party/blink/renderer/core/svg/svg_animated_boolean.idl b/chromium/third_party/blink/renderer/core/svg/svg_animated_boolean.idl index c8492ea9e4d..d5c4168b7ea 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_animated_boolean.idl +++ b/chromium/third_party/blink/renderer/core/svg/svg_animated_boolean.idl @@ -25,6 +25,7 @@ // https://svgwg.org/svg2-draft/types.html#InterfaceSVGAnimatedBoolean +[Exposed=Window] interface SVGAnimatedBoolean { [RaisesException=Setter] attribute boolean baseVal; readonly attribute boolean animVal; diff --git a/chromium/third_party/blink/renderer/core/svg/svg_animated_enumeration.idl b/chromium/third_party/blink/renderer/core/svg/svg_animated_enumeration.idl index b6e66228bae..05beaa0410e 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_animated_enumeration.idl +++ b/chromium/third_party/blink/renderer/core/svg/svg_animated_enumeration.idl @@ -26,6 +26,7 @@ // https://svgwg.org/svg2-draft/types.html#InterfaceSVGAnimatedEnumeration [ + Exposed=Window, ImplementedAs=SVGAnimatedEnumerationBase ] interface SVGAnimatedEnumeration { [RaisesException=Setter] attribute unsigned short baseVal; diff --git a/chromium/third_party/blink/renderer/core/svg/svg_animated_href.cc b/chromium/third_party/blink/renderer/core/svg/svg_animated_href.cc index c9144106b28..bbf6c93202c 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_animated_href.cc +++ b/chromium/third_party/blink/renderer/core/svg/svg_animated_href.cc @@ -4,11 +4,11 @@ #include "third_party/blink/renderer/core/svg/svg_animated_href.h" -#include "third_party/blink/renderer/core/frame/use_counter.h" #include "third_party/blink/renderer/core/svg/svg_element.h" #include "third_party/blink/renderer/core/svg_names.h" #include "third_party/blink/renderer/core/xlink_names.h" #include "third_party/blink/renderer/platform/heap/heap.h" +#include "third_party/blink/renderer/platform/instrumentation/use_counter.h" namespace blink { diff --git a/chromium/third_party/blink/renderer/core/svg/svg_animated_integer.idl b/chromium/third_party/blink/renderer/core/svg/svg_animated_integer.idl index 794195b8449..21fde77c89d 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_animated_integer.idl +++ b/chromium/third_party/blink/renderer/core/svg/svg_animated_integer.idl @@ -25,6 +25,7 @@ // https://svgwg.org/svg2-draft/types.html#InterfaceSVGAnimatedInteger +[Exposed=Window] interface SVGAnimatedInteger { [RaisesException=Setter] attribute long baseVal; readonly attribute long animVal; diff --git a/chromium/third_party/blink/renderer/core/svg/svg_animated_length.cc b/chromium/third_party/blink/renderer/core/svg/svg_animated_length.cc index 6179957867c..72f7c264bda 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_animated_length.cc +++ b/chromium/third_party/blink/renderer/core/svg/svg_animated_length.cc @@ -39,9 +39,13 @@ SVGParsingError SVGAnimatedLength::AttributeChanged(const String& value) { SVGAnimatedProperty<SVGLength>::AttributeChanged(value); if (SVGLength::NegativeValuesForbiddenForAnimatedLengthAttribute( - AttributeName()) && - BaseValue()->ValueInSpecifiedUnits() < 0) - parse_status = SVGParseStatus::kNegativeValue; + AttributeName())) { + // TODO(crbug.com/982425): Pass |kValueRangeNonNegative| to property parser + // to handle range checking on math functions correctly, and also to avoid + // this ad hoc range checking. + if (BaseValue()->IsNegativeNumericLiteral()) + parse_status = SVGParseStatus::kNegativeValue; + } return parse_status; } diff --git a/chromium/third_party/blink/renderer/core/svg/svg_animated_length.idl b/chromium/third_party/blink/renderer/core/svg/svg_animated_length.idl index 4d32d50d4e5..bf4abe2037f 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_animated_length.idl +++ b/chromium/third_party/blink/renderer/core/svg/svg_animated_length.idl @@ -25,6 +25,7 @@ // https://svgwg.org/svg2-draft/types.html#InterfaceSVGAnimatedLength +[Exposed=Window] interface SVGAnimatedLength { readonly attribute SVGLength baseVal; readonly attribute SVGLength animVal; diff --git a/chromium/third_party/blink/renderer/core/svg/svg_animated_length_list.idl b/chromium/third_party/blink/renderer/core/svg/svg_animated_length_list.idl index 1abc3dffebf..55e73f81c7c 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_animated_length_list.idl +++ b/chromium/third_party/blink/renderer/core/svg/svg_animated_length_list.idl @@ -25,6 +25,7 @@ // https://svgwg.org/svg2-draft/types.html#InterfaceSVGAnimatedLengthList +[Exposed=Window] interface SVGAnimatedLengthList { readonly attribute SVGLengthList baseVal; readonly attribute SVGLengthList animVal; diff --git a/chromium/third_party/blink/renderer/core/svg/svg_animated_number.idl b/chromium/third_party/blink/renderer/core/svg/svg_animated_number.idl index 5bae7e0b196..61f0a1fd8fb 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_animated_number.idl +++ b/chromium/third_party/blink/renderer/core/svg/svg_animated_number.idl @@ -26,6 +26,7 @@ // https://svgwg.org/svg2-draft/types.html#InterfaceSVGAnimatedNumber +[Exposed=Window] interface SVGAnimatedNumber { [RaisesException=Setter] attribute float baseVal; readonly attribute float animVal; diff --git a/chromium/third_party/blink/renderer/core/svg/svg_animated_number_list.idl b/chromium/third_party/blink/renderer/core/svg/svg_animated_number_list.idl index 4f35f957f2d..b828e0a1b6e 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_animated_number_list.idl +++ b/chromium/third_party/blink/renderer/core/svg/svg_animated_number_list.idl @@ -25,6 +25,7 @@ // https://svgwg.org/svg2-draft/types.html#InterfaceSVGAnimatedNumberList +[Exposed=Window] interface SVGAnimatedNumberList { readonly attribute SVGNumberList baseVal; readonly attribute SVGNumberList animVal; diff --git a/chromium/third_party/blink/renderer/core/svg/svg_animated_preserve_aspect_ratio.idl b/chromium/third_party/blink/renderer/core/svg/svg_animated_preserve_aspect_ratio.idl index 505752ba57b..0b5fbfe1d3c 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_animated_preserve_aspect_ratio.idl +++ b/chromium/third_party/blink/renderer/core/svg/svg_animated_preserve_aspect_ratio.idl @@ -25,6 +25,7 @@ // https://svgwg.org/svg2-draft/coords.html#InterfaceSVGAnimatedPreserveAspectRatio +[Exposed=Window] interface SVGAnimatedPreserveAspectRatio { readonly attribute SVGPreserveAspectRatio baseVal; readonly attribute SVGPreserveAspectRatio animVal; diff --git a/chromium/third_party/blink/renderer/core/svg/svg_animated_rect.idl b/chromium/third_party/blink/renderer/core/svg/svg_animated_rect.idl index ebbdc18c520..d464cd00a74 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_animated_rect.idl +++ b/chromium/third_party/blink/renderer/core/svg/svg_animated_rect.idl @@ -25,6 +25,7 @@ // https://svgwg.org/svg2-draft/types.html#InterfaceSVGAnimatedRect +[Exposed=Window] interface SVGAnimatedRect { // TODO(foolip): SVGRect should be DOMRectReadOnly. readonly attribute SVGRect baseVal; diff --git a/chromium/third_party/blink/renderer/core/svg/svg_animated_string.idl b/chromium/third_party/blink/renderer/core/svg/svg_animated_string.idl index 5081ecba54a..2b1b8e971de 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_animated_string.idl +++ b/chromium/third_party/blink/renderer/core/svg/svg_animated_string.idl @@ -25,6 +25,7 @@ // https://svgwg.org/svg2-draft/types.html#InterfaceSVGAnimatedString +[Exposed=Window] interface SVGAnimatedString { [RaisesException=Setter] attribute DOMString baseVal; readonly attribute DOMString animVal; diff --git a/chromium/third_party/blink/renderer/core/svg/svg_animated_transform_list.idl b/chromium/third_party/blink/renderer/core/svg/svg_animated_transform_list.idl index bd0c2950f27..fa01fa45fb8 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_animated_transform_list.idl +++ b/chromium/third_party/blink/renderer/core/svg/svg_animated_transform_list.idl @@ -25,6 +25,7 @@ // https://svgwg.org/svg2-draft/coords.html#InterfaceSVGAnimatedTransformList +[Exposed=Window] interface SVGAnimatedTransformList { [MeasureAs=SVGAnimatedTransformListBaseVal] readonly attribute SVGTransformList baseVal; readonly attribute SVGTransformList animVal; diff --git a/chromium/third_party/blink/renderer/core/svg/svg_animation_element.cc b/chromium/third_party/blink/renderer/core/svg/svg_animation_element.cc index 6c4c0b34cd7..8b28853e571 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_animation_element.cc +++ b/chromium/third_party/blink/renderer/core/svg/svg_animation_element.cc @@ -25,11 +25,11 @@ #include "third_party/blink/renderer/core/svg/svg_animation_element.h" #include "third_party/blink/renderer/core/dom/document.h" -#include "third_party/blink/renderer/core/frame/use_counter.h" #include "third_party/blink/renderer/core/svg/svg_animate_element.h" #include "third_party/blink/renderer/core/svg/svg_parser_utilities.h" #include "third_party/blink/renderer/core/svg_names.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" +#include "third_party/blink/renderer/platform/instrumentation/use_counter.h" #include "third_party/blink/renderer/platform/wtf/math_extras.h" namespace blink { @@ -469,10 +469,9 @@ void SVGAnimationElement::CurrentValuesForValuesAnimation( return; } - CalcMode calc_mode = this->GetCalcMode(); - if (IsSVGAnimateElement(*this)) { - SVGAnimateElement& animate_element = ToSVGAnimateElement(*this); - if (!animate_element.AnimatedPropertyTypeSupportsAddition()) + CalcMode calc_mode = GetCalcMode(); + if (auto* animate_element = DynamicTo<SVGAnimateElement>(this)) { + if (!animate_element->AnimatedPropertyTypeSupportsAddition()) calc_mode = kCalcModeDiscrete; } if (!key_points_.IsEmpty() && calc_mode != kCalcModePaced) @@ -527,8 +526,8 @@ void SVGAnimationElement::StartedActiveInterval() { key_points_.size() != key_times_.size()) return; - AnimationMode animation_mode = this->GetAnimationMode(); - CalcMode calc_mode = this->GetCalcMode(); + AnimationMode animation_mode = GetAnimationMode(); + CalcMode calc_mode = GetCalcMode(); if (calc_mode == kCalcModeSpline) { unsigned splines_count = key_splines_.size(); if (!splines_count || @@ -601,8 +600,8 @@ void SVGAnimationElement::UpdateAnimation(float percent, return; float effective_percent; - CalcMode calc_mode = this->GetCalcMode(); - AnimationMode animation_mode = this->GetAnimationMode(); + CalcMode calc_mode = GetCalcMode(); + AnimationMode animation_mode = GetAnimationMode(); if (animation_mode == kValuesAnimation) { String from; String to; @@ -629,4 +628,11 @@ void SVGAnimationElement::UpdateAnimation(float percent, CalculateAnimatedValue(effective_percent, repeat_count, result_element); } +bool SVGAnimationElement::OverwritesUnderlyingAnimationValue() { + return !IsAdditive() && !IsAccumulated() && + GetAnimationMode() != kToAnimation && + GetAnimationMode() != kByAnimation && + GetAnimationMode() != kNoAnimation; +} + } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/svg/svg_animation_element.h b/chromium/third_party/blink/renderer/core/svg/svg_animation_element.h index 3b546c0d8d8..fcfb1791be8 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_animation_element.h +++ b/chromium/third_party/blink/renderer/core/svg/svg_animation_element.h @@ -74,6 +74,8 @@ class CORE_EXPORT SVGAnimationElement : public SVGSMILElement { AnimationMode GetAnimationMode() const { return animation_mode_; } CalcMode GetCalcMode() const { return calc_mode_; } + bool OverwritesUnderlyingAnimationValue() override; + template <typename AnimatedType> void AnimateDiscreteType(float percentage, const AnimatedType& from_type, diff --git a/chromium/third_party/blink/renderer/core/svg/svg_circle_element.idl b/chromium/third_party/blink/renderer/core/svg/svg_circle_element.idl index 76f2a42a6b6..64cfbad9f99 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_circle_element.idl +++ b/chromium/third_party/blink/renderer/core/svg/svg_circle_element.idl @@ -26,6 +26,7 @@ // https://svgwg.org/svg2-draft/shapes.html#InterfaceSVGCircleElement +[Exposed=Window] interface SVGCircleElement : SVGGeometryElement { [MeasureAs=SVG1DOMShape] readonly attribute SVGAnimatedLength cx; [MeasureAs=SVG1DOMShape] readonly attribute SVGAnimatedLength cy; diff --git a/chromium/third_party/blink/renderer/core/svg/svg_clip_path_element.cc b/chromium/third_party/blink/renderer/core/svg/svg_clip_path_element.cc index 9767ed1f9f1..676b342ead2 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_clip_path_element.cc +++ b/chromium/third_party/blink/renderer/core/svg/svg_clip_path_element.cc @@ -46,7 +46,7 @@ void SVGClipPathElement::SvgAttributeChanged(const QualifiedName& attr_name) { SVGElement::InvalidationGuard invalidation_guard(this); LayoutSVGResourceContainer* layout_object = - ToLayoutSVGResourceContainer(this->GetLayoutObject()); + ToLayoutSVGResourceContainer(GetLayoutObject()); if (layout_object) layout_object->InvalidateCacheAndMarkForLayout(); return; diff --git a/chromium/third_party/blink/renderer/core/svg/svg_defs_element.idl b/chromium/third_party/blink/renderer/core/svg/svg_defs_element.idl index ba525a6356c..a463b202a00 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_defs_element.idl +++ b/chromium/third_party/blink/renderer/core/svg/svg_defs_element.idl @@ -25,5 +25,6 @@ // https://svgwg.org/svg2-draft/struct.html#InterfaceSVGDefsElement +[Exposed=Window] interface SVGDefsElement : SVGGraphicsElement { }; diff --git a/chromium/third_party/blink/renderer/core/svg/svg_desc_element.idl b/chromium/third_party/blink/renderer/core/svg/svg_desc_element.idl index 68ed11d7fad..d11274b5777 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_desc_element.idl +++ b/chromium/third_party/blink/renderer/core/svg/svg_desc_element.idl @@ -25,5 +25,6 @@ // https://svgwg.org/svg2-draft/struct.html#InterfaceSVGDescElement +[Exposed=Window] interface SVGDescElement : SVGElement { }; diff --git a/chromium/third_party/blink/renderer/core/svg/svg_discard_element.cc b/chromium/third_party/blink/renderer/core/svg/svg_discard_element.cc index d5f6cc98b59..a9b70737e19 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_discard_element.cc +++ b/chromium/third_party/blink/renderer/core/svg/svg_discard_element.cc @@ -35,6 +35,8 @@ namespace blink { SVGDiscardElement::SVGDiscardElement(Document& document) - : SVGSMILElement(svg_names::kDiscardTag, document) {} + : SVGSMILElement(svg_names::kDiscardTag, document) { + UseCounter::Count(&GetDocument(), WebFeature::kSVGSMILDiscardElementParsed); +} } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/svg/svg_discard_element.h b/chromium/third_party/blink/renderer/core/svg/svg_discard_element.h index 7b9d4140bde..8b7b026349b 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_discard_element.h +++ b/chromium/third_party/blink/renderer/core/svg/svg_discard_element.h @@ -49,6 +49,8 @@ class SVGDiscardElement final : public SVGSMILElement { void ApplyResultsToTarget() override {} void AnimationAttributeChanged() override {} + bool OverwritesUnderlyingAnimationValue() override { return false; } + void StartedActiveInterval() override {} void UpdateAnimation(float percent, unsigned repeat, diff --git a/chromium/third_party/blink/renderer/core/svg/svg_element.cc b/chromium/third_party/blink/renderer/core/svg/svg_element.cc index 506e181d42c..20546983471 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_element.cc +++ b/chromium/third_party/blink/renderer/core/svg/svg_element.cc @@ -44,7 +44,6 @@ #include "third_party/blink/renderer/core/dom/shadow_root.h" #include "third_party/blink/renderer/core/frame/csp/content_security_policy.h" #include "third_party/blink/renderer/core/frame/settings.h" -#include "third_party/blink/renderer/core/frame/use_counter.h" #include "third_party/blink/renderer/core/html/html_element.h" #include "third_party/blink/renderer/core/html_names.h" #include "third_party/blink/renderer/core/inspector/console_message.h" @@ -60,6 +59,7 @@ #include "third_party/blink/renderer/core/svg_names.h" #include "third_party/blink/renderer/core/xml_names.h" #include "third_party/blink/renderer/platform/heap/heap.h" +#include "third_party/blink/renderer/platform/instrumentation/use_counter.h" #include "third_party/blink/renderer/platform/wtf/threading.h" namespace blink { @@ -83,8 +83,8 @@ SVGElement::~SVGElement() { DCHECK(isConnected() || !HasRelativeLengths()); } -void SVGElement::DetachLayoutTree(const AttachContext& context) { - Element::DetachLayoutTree(context); +void SVGElement::DetachLayoutTree(bool performing_reattach) { + Element::DetachLayoutTree(performing_reattach); if (SVGElement* element = CorrespondingElement()) element->RemoveInstanceMapping(this); // To avoid a noncollectable Blink GC reference cycle, we must clear the @@ -583,7 +583,7 @@ void SVGElement::InvalidateRelativeLengthClients( &in_relative_length_clients_invalidation_, true); #endif - if (LayoutObject* layout_object = this->GetLayoutObject()) { + if (LayoutObject* layout_object = GetLayoutObject()) { if (HasRelativeLengths() && layout_object->IsSVGResourceContainer()) { ToLayoutSVGResourceContainer(layout_object) ->InvalidateCacheAndMarkForLayout( @@ -1328,4 +1328,9 @@ void SVGElement::Trace(blink::Visitor* visitor) { Element::Trace(visitor); } +void SVGElement::AccessKeyAction(bool send_mouse_events) { + DispatchSimulatedClick( + nullptr, send_mouse_events ? kSendMouseUpDownEvents : kSendNoEvents); +} + } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/svg/svg_element.h b/chromium/third_party/blink/renderer/core/svg/svg_element.h index 3c5fb74591f..60ed0c4bc73 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_element.h +++ b/chromium/third_party/blink/renderer/core/svg/svg_element.h @@ -29,7 +29,7 @@ #include "third_party/blink/renderer/core/svg/svg_parsing_error.h" #include "third_party/blink/renderer/core/svg_names.h" #include "third_party/blink/renderer/platform/heap/handle.h" -#include "third_party/blink/renderer/platform/wtf/allocator.h" +#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" #include "third_party/blink/renderer/platform/wtf/casting.h" #include "third_party/blink/renderer/platform/wtf/hash_map.h" @@ -55,7 +55,7 @@ class CORE_EXPORT SVGElement : public Element { public: ~SVGElement() override; void AttachLayoutTree(AttachContext&) override; - void DetachLayoutTree(const AttachContext&) override; + void DetachLayoutTree(bool performing_reattach) override; int tabIndex() const override; bool SupportsFocus() const override { return false; } @@ -264,6 +264,8 @@ class CORE_EXPORT SVGElement : public Element { void RemovedEventListener(const AtomicString& event_type, const RegisteredEventListener&) final; + void AccessKeyAction(bool send_mouse_events) override; + private: bool IsSVGElement() const = delete; // This will catch anyone doing an unnecessary check. diff --git a/chromium/third_party/blink/renderer/core/svg/svg_element.idl b/chromium/third_party/blink/renderer/core/svg/svg_element.idl index 57a07d3e1a8..9fee3804823 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_element.idl +++ b/chromium/third_party/blink/renderer/core/svg/svg_element.idl @@ -22,6 +22,7 @@ // https://svgwg.org/svg2-draft/types.html#InterfaceSVGElement +[Exposed=Window] interface SVGElement : Element { [MeasureAs=SVGClassName] readonly attribute SVGAnimatedString className; [SameObject, PerWorldBindings] readonly attribute DOMStringMap dataset; diff --git a/chromium/third_party/blink/renderer/core/svg/svg_ellipse_element.idl b/chromium/third_party/blink/renderer/core/svg/svg_ellipse_element.idl index 546f53292f7..206bf047695 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_ellipse_element.idl +++ b/chromium/third_party/blink/renderer/core/svg/svg_ellipse_element.idl @@ -25,6 +25,7 @@ // https://svgwg.org/svg2-draft/shapes.html#InterfaceSVGEllipseElement +[Exposed=Window] interface SVGEllipseElement : SVGGeometryElement { [MeasureAs=SVG1DOMShape] readonly attribute SVGAnimatedLength cx; [MeasureAs=SVG1DOMShape] readonly attribute SVGAnimatedLength cy; diff --git a/chromium/third_party/blink/renderer/core/svg/svg_fe_image_element.cc b/chromium/third_party/blink/renderer/core/svg/svg_fe_image_element.cc index 1256a0e23fc..9069c8b1ede 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_fe_image_element.cc +++ b/chromium/third_party/blink/renderer/core/svg/svg_fe_image_element.cc @@ -45,7 +45,9 @@ SVGFEImageElement::SVGFEImageElement(Document& document) AddToPropertyMap(preserve_aspect_ratio_); } -SVGFEImageElement::~SVGFEImageElement() { +SVGFEImageElement::~SVGFEImageElement() = default; + +void SVGFEImageElement::Dispose() { ClearImageResource(); } diff --git a/chromium/third_party/blink/renderer/core/svg/svg_fe_image_element.h b/chromium/third_party/blink/renderer/core/svg/svg_fe_image_element.h index af5dcd70c64..a29911334a1 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_fe_image_element.h +++ b/chromium/third_party/blink/renderer/core/svg/svg_fe_image_element.h @@ -36,6 +36,8 @@ class SVGFEImageElement final : public SVGFilterPrimitiveStandardAttributes, public ImageResourceObserver { DEFINE_WRAPPERTYPEINFO(); USING_GARBAGE_COLLECTED_MIXIN(SVGFEImageElement); + // Pre-finalize to promptly remove as a ImageResource client. + USING_PRE_FINALIZER(SVGFEImageElement, Dispose); public: bool CurrentFrameHasSingleSecurityOrigin() const; @@ -46,8 +48,12 @@ class SVGFEImageElement final : public SVGFilterPrimitiveStandardAttributes, return preserve_aspect_ratio_.Get(); } - // Promptly remove as a ImageResource client. - EAGERLY_FINALIZE(); + const AttrNameToTrustedType& GetCheckedAttributeTypes() const override { + return SVGURIReference::GetCheckedAttributeTypes(); + } + + void Dispose(); + void Trace(blink::Visitor*) override; private: diff --git a/chromium/third_party/blink/renderer/core/svg/svg_filter_element.h b/chromium/third_party/blink/renderer/core/svg/svg_filter_element.h index 02c1c251f3d..46c123b0970 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_filter_element.h +++ b/chromium/third_party/blink/renderer/core/svg/svg_filter_element.h @@ -68,6 +68,10 @@ class CORE_EXPORT SVGFilterElement final : public SVGElement, // Get the associated SVGResource object, if any. LocalSVGResource* AssociatedResource() const; + const AttrNameToTrustedType& GetCheckedAttributeTypes() const override { + return SVGURIReference::GetCheckedAttributeTypes(); + } + private: void SvgAttributeChanged(const QualifiedName&) override; void ChildrenChanged(const ChildrenChange&) override; diff --git a/chromium/third_party/blink/renderer/core/svg/svg_filter_primitive_standard_attributes.cc b/chromium/third_party/blink/renderer/core/svg/svg_filter_primitive_standard_attributes.cc index a0c122aa35a..9edbeaa78f2 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_filter_primitive_standard_attributes.cc +++ b/chromium/third_party/blink/renderer/core/svg/svg_filter_primitive_standard_attributes.cc @@ -190,12 +190,11 @@ void SVGFilterPrimitiveStandardAttributes::PrimitiveAttributeChanged( } void InvalidateFilterPrimitiveParent(SVGElement& element) { - auto* svg_parent = DynamicTo<SVGElement>(element.parentElement()); + auto* svg_parent = + DynamicTo<SVGFilterPrimitiveStandardAttributes>(element.parentElement()); if (!svg_parent) return; - if (!IsSVGFilterPrimitiveStandardAttributes(*svg_parent)) - return; - ToSVGFilterPrimitiveStandardAttributes(*svg_parent).Invalidate(); + svg_parent->Invalidate(); } } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/svg/svg_filter_primitive_standard_attributes.h b/chromium/third_party/blink/renderer/core/svg/svg_filter_primitive_standard_attributes.h index 2aed48ffdc3..b0271c5fe3b 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_filter_primitive_standard_attributes.h +++ b/chromium/third_party/blink/renderer/core/svg/svg_filter_primitive_standard_attributes.h @@ -85,8 +85,13 @@ inline bool IsSVGFilterPrimitiveStandardAttributes(const SVGElement& element) { return element.IsFilterEffect(); } -DEFINE_SVGELEMENT_TYPE_CASTS_WITH_FUNCTION( - SVGFilterPrimitiveStandardAttributes); +template <> +struct DowncastTraits<SVGFilterPrimitiveStandardAttributes> { + static bool AllowFrom(const Node& node) { + auto* element = DynamicTo<SVGElement>(node); + return element && IsSVGFilterPrimitiveStandardAttributes(*element); + } +}; } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/svg/svg_foreign_object_element.cc b/chromium/third_party/blink/renderer/core/svg/svg_foreign_object_element.cc index a440a448328..a912b47f3d6 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_foreign_object_element.cc +++ b/chromium/third_party/blink/renderer/core/svg/svg_foreign_object_element.cc @@ -21,10 +21,10 @@ #include "third_party/blink/renderer/core/svg/svg_foreign_object_element.h" #include "third_party/blink/renderer/core/css/style_change_reason.h" -#include "third_party/blink/renderer/core/frame/use_counter.h" #include "third_party/blink/renderer/core/layout/svg/layout_svg_foreign_object.h" #include "third_party/blink/renderer/core/svg/svg_length.h" #include "third_party/blink/renderer/platform/heap/heap.h" +#include "third_party/blink/renderer/platform/instrumentation/use_counter.h" #include "third_party/blink/renderer/platform/wtf/assertions.h" namespace blink { diff --git a/chromium/third_party/blink/renderer/core/svg/svg_foreign_object_element.idl b/chromium/third_party/blink/renderer/core/svg/svg_foreign_object_element.idl index 03f3aff6801..1d2fa831adc 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_foreign_object_element.idl +++ b/chromium/third_party/blink/renderer/core/svg/svg_foreign_object_element.idl @@ -25,6 +25,7 @@ // https://svgwg.org/svg2-draft/embedded.html#InterfaceSVGForeignObjectElement +[Exposed=Window] interface SVGForeignObjectElement : SVGGraphicsElement { [MeasureAs=SVG1DOMForeignObjectElement] readonly attribute SVGAnimatedLength x; [MeasureAs=SVG1DOMForeignObjectElement] readonly attribute SVGAnimatedLength y; diff --git a/chromium/third_party/blink/renderer/core/svg/svg_g_element.idl b/chromium/third_party/blink/renderer/core/svg/svg_g_element.idl index cf7d964b5e1..6cec8b55b07 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_g_element.idl +++ b/chromium/third_party/blink/renderer/core/svg/svg_g_element.idl @@ -25,5 +25,6 @@ // https://svgwg.org/svg2-draft/struct.html#InterfaceSVGGElement +[Exposed=Window] interface SVGGElement : SVGGraphicsElement { }; diff --git a/chromium/third_party/blink/renderer/core/svg/svg_geometry_element.idl b/chromium/third_party/blink/renderer/core/svg/svg_geometry_element.idl index 8145d5c79fa..f447ef3b81f 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_geometry_element.idl +++ b/chromium/third_party/blink/renderer/core/svg/svg_geometry_element.idl @@ -30,6 +30,7 @@ // https://svgwg.org/svg2-draft/types.html#InterfaceSVGGeometryElement +[Exposed=Window] interface SVGGeometryElement : SVGGraphicsElement { [SameObject] readonly attribute SVGAnimatedNumber pathLength; diff --git a/chromium/third_party/blink/renderer/core/svg/svg_gradient_element.cc b/chromium/third_party/blink/renderer/core/svg/svg_gradient_element.cc index 3b684b46ec8..c05a4394725 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_gradient_element.cc +++ b/chromium/third_party/blink/renderer/core/svg/svg_gradient_element.cc @@ -81,7 +81,7 @@ void SVGGradientElement::BuildPendingResource() { if (!isConnected()) return; Element* target = ObserveTarget(target_id_observer_, *this); - if (auto* gradient = ToSVGGradientElementOrNull(target)) + if (auto* gradient = DynamicTo<SVGGradientElement>(target)) AddReferenceTo(gradient); InvalidateGradient(layout_invalidation_reason::kSvgResourceInvalidated); @@ -160,7 +160,7 @@ void SVGGradientElement::InvalidateGradient( void SVGGradientElement::InvalidateDependentGradients() { NotifyIncomingReferences([](SVGElement& element) { - if (auto* gradient = ToSVGGradientElementOrNull(element)) { + if (auto* gradient = DynamicTo<SVGGradientElement>(element)) { gradient->InvalidateGradient( layout_invalidation_reason::kSvgResourceInvalidated); } @@ -190,7 +190,7 @@ void SVGGradientElement::CollectCommonAttributes( const SVGGradientElement* SVGGradientElement::ReferencedElement() const { // Respect xlink:href, take attributes from referenced element. - return ToSVGGradientElementOrNull( + return DynamicTo<SVGGradientElement>( TargetElementFromIRIString(HrefString(), GetTreeScope())); } diff --git a/chromium/third_party/blink/renderer/core/svg/svg_gradient_element.h b/chromium/third_party/blink/renderer/core/svg/svg_gradient_element.h index 0376e5dfd46..ba5f6eea191 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_gradient_element.h +++ b/chromium/third_party/blink/renderer/core/svg/svg_gradient_element.h @@ -64,6 +64,10 @@ class SVGGradientElement : public SVGElement, public SVGURIReference { const SVGGradientElement* ReferencedElement() const; void CollectCommonAttributes(GradientAttributes&) const; + const AttrNameToTrustedType& GetCheckedAttributeTypes() const override { + return SVGURIReference::GetCheckedAttributeTypes(); + } + void Trace(blink::Visitor*) override; protected: @@ -99,7 +103,13 @@ inline bool IsSVGGradientElement(const SVGElement& element) { element.HasTagName(svg_names::kLinearGradientTag); } -DEFINE_SVGELEMENT_TYPE_CASTS_WITH_FUNCTION(SVGGradientElement); +template <> +struct DowncastTraits<SVGGradientElement> { + static bool AllowFrom(const Node& node) { + auto* svg_element = DynamicTo<SVGElement>(node); + return svg_element && IsSVGGradientElement(*svg_element); + } +}; } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/svg/svg_gradient_element.idl b/chromium/third_party/blink/renderer/core/svg/svg_gradient_element.idl index 5fb065d6a11..e8fe8dad1f2 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_gradient_element.idl +++ b/chromium/third_party/blink/renderer/core/svg/svg_gradient_element.idl @@ -26,6 +26,7 @@ // https://svgwg.org/svg2-draft/pservers.html#InterfaceSVGGradientElement [ + Exposed=Window, DoNotCheckConstants ] interface SVGGradientElement : SVGElement { // Spread Method Types diff --git a/chromium/third_party/blink/renderer/core/svg/svg_graphics_element.h b/chromium/third_party/blink/renderer/core/svg/svg_graphics_element.h index fd03167ee26..2b602085711 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_graphics_element.h +++ b/chromium/third_party/blink/renderer/core/svg/svg_graphics_element.h @@ -91,6 +91,14 @@ inline bool IsSVGGraphicsElement(const SVGElement& element) { return element.IsSVGGraphicsElement(); } +template <> +struct DowncastTraits<SVGGraphicsElement> { + static bool AllowFrom(const Node& node) { + auto* svg_element = DynamicTo<SVGElement>(node); + return svg_element && IsSVGGraphicsElement(*svg_element); + } +}; + DEFINE_SVGELEMENT_TYPE_CASTS_WITH_FUNCTION(SVGGraphicsElement); } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/svg/svg_graphics_element.idl b/chromium/third_party/blink/renderer/core/svg/svg_graphics_element.idl index 5f9b1d6e6e4..da35d78a36d 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_graphics_element.idl +++ b/chromium/third_party/blink/renderer/core/svg/svg_graphics_element.idl @@ -30,6 +30,7 @@ // https://svgwg.org/svg2-draft/types.html#InterfaceSVGGraphicsElement +[Exposed=Window] interface SVGGraphicsElement : SVGElement { [Measure] readonly attribute SVGAnimatedTransformList transform; diff --git a/chromium/third_party/blink/renderer/core/svg/svg_image_element.cc b/chromium/third_party/blink/renderer/core/svg/svg_image_element.cc index da3cb08045e..008ea04bb38 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_image_element.cc +++ b/chromium/third_party/blink/renderer/core/svg/svg_image_element.cc @@ -24,7 +24,6 @@ #include "third_party/blink/public/mojom/feature_policy/feature_policy.mojom-blink.h" #include "third_party/blink/renderer/core/css/css_property_names.h" #include "third_party/blink/renderer/core/css/style_change_reason.h" -#include "third_party/blink/renderer/core/frame/use_counter.h" #include "third_party/blink/renderer/core/html/media/media_element_parser_helpers.h" #include "third_party/blink/renderer/core/inspector/console_message.h" #include "third_party/blink/renderer/core/layout/layout_image_resource.h" @@ -32,6 +31,7 @@ #include "third_party/blink/renderer/core/layout/svg/layout_svg_image.h" #include "third_party/blink/renderer/core/svg_names.h" #include "third_party/blink/renderer/platform/heap/heap.h" +#include "third_party/blink/renderer/platform/instrumentation/use_counter.h" namespace blink { diff --git a/chromium/third_party/blink/renderer/core/svg/svg_image_element.h b/chromium/third_party/blink/renderer/core/svg/svg_image_element.h index 7c7c3ee084d..b5e3a360b4a 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_image_element.h +++ b/chromium/third_party/blink/renderer/core/svg/svg_image_element.h @@ -78,6 +78,10 @@ class CORE_EXPORT SVGImageElement final GetImageLoader().SetImageForTest(content); } + const AttrNameToTrustedType& GetCheckedAttributeTypes() const override { + return SVGURIReference::GetCheckedAttributeTypes(); + } + private: bool IsStructurallyExternal() const override { return !HrefString().IsNull(); diff --git a/chromium/third_party/blink/renderer/core/svg/svg_length.cc b/chromium/third_party/blink/renderer/core/svg/svg_length.cc index 6271a18c695..a7e66c3baf5 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_length.cc +++ b/chromium/third_party/blink/renderer/core/svg/svg_length.cc @@ -21,6 +21,8 @@ #include "third_party/blink/renderer/core/svg/svg_length.h" +#include "third_party/blink/renderer/core/css/css_math_function_value.h" +#include "third_party/blink/renderer/core/css/css_numeric_literal_value.h" #include "third_party/blink/renderer/core/css/css_primitive_value.h" #include "third_party/blink/renderer/core/css/css_value.h" #include "third_party/blink/renderer/core/css/parser/css_parser.h" @@ -63,17 +65,17 @@ const CSSPrimitiveValue& CreateInitialCSSValue( size_t initial_value_index = static_cast<size_t>(initial_value); DCHECK_LT(initial_value_index, base::size(g_initial_lengths_table)); const auto& entry = g_initial_lengths_table[initial_value_index]; - return *CSSPrimitiveValue::Create( + return *CSSNumericLiteralValue::Create( entry.value, static_cast<CSSPrimitiveValue::UnitType>(entry.unit)); } } // namespace SVGLength::SVGLength(SVGLengthMode mode) - : SVGLength( - *CSSPrimitiveValue::Create(0, - CSSPrimitiveValue::UnitType::kUserUnits), - mode) {} + : SVGLength(*CSSNumericLiteralValue::Create( + 0, + CSSPrimitiveValue::UnitType::kUserUnits), + mode) {} SVGLength::SVGLength(Initial initial, SVGLengthMode mode) : SVGLength(CreateInitialCSSValue(initial), mode) {} @@ -99,9 +101,10 @@ SVGPropertyBase* SVGLength::CloneForAnimation(const String& value) const { auto* length = MakeGarbageCollected<SVGLength>(); length->unit_mode_ = unit_mode_; - if (length->SetValueAsString(value) != SVGParseStatus::kNoError) - length->value_ = - CSSPrimitiveValue::Create(0, CSSPrimitiveValue::UnitType::kUserUnits); + if (length->SetValueAsString(value) != SVGParseStatus::kNoError) { + length->value_ = CSSNumericLiteralValue::Create( + 0, CSSPrimitiveValue::UnitType::kUserUnits); + } return length; } @@ -115,38 +118,66 @@ float SVGLength::Value(const SVGLengthContext& context) const { return context.ResolveValue(AsCSSPrimitiveValue(), UnitMode()); return context.ConvertValueToUserUnits(value_->GetFloatValue(), UnitMode(), - value_->TypeWithCalcResolved()); + NumericLiteralType()); } void SVGLength::SetValueAsNumber(float value) { - value_ = - CSSPrimitiveValue::Create(value, CSSPrimitiveValue::UnitType::kUserUnits); + value_ = CSSNumericLiteralValue::Create( + value, CSSPrimitiveValue::UnitType::kUserUnits); } void SVGLength::SetValue(float value, const SVGLengthContext& context) { - value_ = CSSPrimitiveValue::Create( + // |value| is in user units. + if (IsCalculated()) { + value_ = CSSNumericLiteralValue::Create( + value, CSSPrimitiveValue::UnitType::kUserUnits); + return; + } + value_ = CSSNumericLiteralValue::Create( context.ConvertValueFromUserUnits(value, UnitMode(), - value_->TypeWithCalcResolved()), - value_->TypeWithCalcResolved()); + NumericLiteralType()), + NumericLiteralType()); +} + +void SVGLength::SetValueInSpecifiedUnits(float value) { + DCHECK(!IsCalculated()); + value_ = CSSNumericLiteralValue::Create(value, NumericLiteralType()); } -static bool IsCalcCSSUnitType(CSSPrimitiveValue::UnitType type) { - return type >= CSSPrimitiveValue::UnitType::kCalc && - type <= - CSSPrimitiveValue::UnitType::kCalcPercentageWithLengthAndNumber; +bool SVGLength::IsRelative() const { + if (IsPercentage()) + return true; + // TODO(crbug.com/979895): This is the result of a refactoring, which might + // have revealed an existing bug with relative units in math functions. + return !IsCalculated() && + CSSPrimitiveValue::IsRelativeUnit(NumericLiteralType()); } static bool IsSupportedCSSUnitType(CSSPrimitiveValue::UnitType type) { return (CSSPrimitiveValue::IsLength(type) || type == CSSPrimitiveValue::UnitType::kNumber || - type == CSSPrimitiveValue::UnitType::kPercentage || - IsCalcCSSUnitType(type)) && + type == CSSPrimitiveValue::UnitType::kPercentage) && type != CSSPrimitiveValue::UnitType::kQuirkyEms; } +static bool IsSupportedCalculationCategory(CalculationCategory category) { + switch (category) { + case kCalcLength: + case kCalcNumber: + case kCalcPercent: + case kCalcPercentNumber: + case kCalcPercentLength: + case kCalcLengthNumber: + case kCalcPercentLengthNumber: + return true; + default: + return false; + } +} + void SVGLength::SetUnitType(CSSPrimitiveValue::UnitType type) { DCHECK(IsSupportedCSSUnitType(type)); - value_ = CSSPrimitiveValue::Create(value_->GetFloatValue(), type); + value_ = CSSNumericLiteralValue::Create(value_->GetFloatValue(), type); } float SVGLength::ValueAsPercentage() const { @@ -179,29 +210,45 @@ float SVGLength::ScaleByPercentage(float input) const { return result; } +namespace { + +const CSSParserContext* GetSVGAttributeParserContext() { + // NOTE(ikilpatrick): We will always parse SVG lengths in the insecure + // context mode. If a function/unit/etc will require a secure context check + // in the future, plumbing will need to be added. + DEFINE_STATIC_LOCAL( + const Persistent<CSSParserContext>, svg_parser_context, + (MakeGarbageCollected<CSSParserContext>( + kSVGAttributeMode, SecureContextMode::kInsecureContext))); + return svg_parser_context; +} + +} // namespace + SVGParsingError SVGLength::SetValueAsString(const String& string) { // TODO(fs): Preferably we wouldn't need to special-case the null // string (which we'll get for example for removeAttribute.) // Hopefully work on crbug.com/225807 can help here. if (string.IsNull()) { - value_ = - CSSPrimitiveValue::Create(0, CSSPrimitiveValue::UnitType::kUserUnits); + value_ = CSSNumericLiteralValue::Create( + 0, CSSPrimitiveValue::UnitType::kUserUnits); return SVGParseStatus::kNoError; } - // NOTE(ikilpatrick): We will always parse svg lengths in the insecure - // context mode. If a function/unit/etc will require a secure context check - // in the future, plumbing will need to be added. - auto* svg_parser_context = MakeGarbageCollected<CSSParserContext>( - kSVGAttributeMode, SecureContextMode::kInsecureContext); const CSSValue* parsed = CSSParser::ParseSingleValue( - CSSPropertyID::kX, string, svg_parser_context); + CSSPropertyID::kX, string, GetSVGAttributeParserContext()); const auto* new_value = DynamicTo<CSSPrimitiveValue>(parsed); if (!new_value) return SVGParseStatus::kExpectedLength; - if (!IsSupportedCSSUnitType(new_value->TypeWithCalcResolved())) - return SVGParseStatus::kExpectedLength; + if (const auto* math_value = DynamicTo<CSSMathFunctionValue>(new_value)) { + if (!IsSupportedCalculationCategory(math_value->Category())) + return SVGParseStatus::kExpectedLength; + } else { + const auto* numeric_literal_value = To<CSSNumericLiteralValue>(new_value); + if (!IsSupportedCSSUnitType(numeric_literal_value->GetType())) + return SVGParseStatus::kExpectedLength; + } value_ = new_value; return SVGParseStatus::kNoError; @@ -213,7 +260,7 @@ String SVGLength::ValueAsString() const { void SVGLength::NewValueSpecifiedUnits(CSSPrimitiveValue::UnitType type, float value) { - value_ = CSSPrimitiveValue::Create(value, type); + value_ = CSSNumericLiteralValue::Create(value, type); } void SVGLength::ConvertToSpecifiedUnits(CSSPrimitiveValue::UnitType type, @@ -221,7 +268,7 @@ void SVGLength::ConvertToSpecifiedUnits(CSSPrimitiveValue::UnitType type, DCHECK(IsSupportedCSSUnitType(type)); float value_in_user_units = Value(context); - value_ = CSSPrimitiveValue::Create( + value_ = CSSNumericLiteralValue::Create( context.ConvertValueFromUserUnits(value_in_user_units, UnitMode(), type), type); } @@ -311,15 +358,17 @@ void SVGLength::CalculateAnimatedValue( CSSPrimitiveValue::UnitType new_unit = CSSPrimitiveValue::UnitType::kUserUnits; if (percentage < 0.5) { - if (!from_length->IsCalculated()) - new_unit = from_length->TypeWithCalcResolved(); + if (!from_length->IsCalculated()) { + new_unit = from_length->NumericLiteralType(); + } } else { - if (!to_length->IsCalculated()) - new_unit = to_length->TypeWithCalcResolved(); + if (!to_length->IsCalculated()) { + new_unit = to_length->NumericLiteralType(); + } } animated_number = length_context.ConvertValueFromUserUnits( animated_number, UnitMode(), new_unit); - value_ = CSSPrimitiveValue::Create(animated_number, new_unit); + value_ = CSSNumericLiteralValue::Create(animated_number, new_unit); } float SVGLength::CalculateDistance(SVGPropertyBase* to_value, @@ -334,4 +383,10 @@ void SVGLength::SetInitial(unsigned initial_value) { value_ = CreateInitialCSSValue(static_cast<Initial>(initial_value)); } +bool SVGLength::IsNegativeNumericLiteral() const { + if (!value_->IsNumericLiteralValue()) + return false; + return value_->GetDoubleValue() < 0; +} + } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/svg/svg_length.h b/chromium/third_party/blink/renderer/core/svg/svg_length.h index 5e59803833d..b95a5fd0720 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_length.h +++ b/chromium/third_party/blink/renderer/core/svg/svg_length.h @@ -21,6 +21,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_SVG_SVG_LENGTH_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_SVG_SVG_LENGTH_H_ +#include "third_party/blink/renderer/core/css/css_numeric_literal_value.h" #include "third_party/blink/renderer/core/css/css_primitive_value.h" #include "third_party/blink/renderer/core/svg/properties/svg_property.h" #include "third_party/blink/renderer/core/svg/svg_length_context.h" @@ -64,9 +65,11 @@ class SVGLength final : public SVGPropertyBase { SVGLength* Clone() const; SVGPropertyBase* CloneForAnimation(const String&) const override; - CSSPrimitiveValue::UnitType TypeWithCalcResolved() const { - return value_->TypeWithCalcResolved(); + CSSPrimitiveValue::UnitType NumericLiteralType() const { + DCHECK(value_->IsNumericLiteralValue()); + return To<CSSNumericLiteralValue>(*value_).GetType(); } + void SetUnitType(CSSPrimitiveValue::UnitType); SVGLengthMode UnitMode() const { return static_cast<SVGLengthMode>(unit_mode_); @@ -80,9 +83,7 @@ class SVGLength final : public SVGPropertyBase { void SetValueAsNumber(float); float ValueInSpecifiedUnits() const { return value_->GetFloatValue(); } - void SetValueInSpecifiedUnits(float value) { - value_ = CSSPrimitiveValue::Create(value, value_->TypeWithCalcResolved()); - } + void SetValueInSpecifiedUnits(float value); const CSSPrimitiveValue& AsCSSPrimitiveValue() const { return *value_; } @@ -106,12 +107,12 @@ class SVGLength final : public SVGPropertyBase { const SVGLengthContext&); // Helper functions - bool IsRelative() const { - return CSSPrimitiveValue::IsRelativeUnit(value_->TypeWithCalcResolved()); - } + bool IsRelative() const; bool IsFontRelative() const { return value_->IsFontRelativeLength(); } bool IsCalculated() const { return value_->IsCalculated(); } + bool IsPercentage() const { return value_->IsPercentage(); } + bool IsNegativeNumericLiteral() const; bool IsZero() const { return value_->GetFloatValue() == 0; } static SVGLengthMode LengthModeForAnimatedLengthAttribute( diff --git a/chromium/third_party/blink/renderer/core/svg/svg_length.idl b/chromium/third_party/blink/renderer/core/svg/svg_length.idl index 4a90ae6e2d0..62f619eb66b 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_length.idl +++ b/chromium/third_party/blink/renderer/core/svg/svg_length.idl @@ -23,6 +23,7 @@ // https://svgwg.org/svg2-draft/types.html#InterfaceSVGLength [ + Exposed=Window, ImplementedAs=SVGLengthTearOff ] interface SVGLength { // Length Unit Types diff --git a/chromium/third_party/blink/renderer/core/svg/svg_length_list.cc b/chromium/third_party/blink/renderer/core/svg/svg_length_list.cc index 2579e0fde51..9ed70d9c3a5 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_length_list.cc +++ b/chromium/third_party/blink/renderer/core/svg/svg_length_list.cc @@ -135,12 +135,11 @@ void SVGLengthList::CalculateAnimatedValue( for (uint32_t i = 0; i < to_length_list_size; ++i) { // TODO(shanmuga.m): Support calc for SVGLengthList animation float animated_number = at(i)->Value(length_context); - CSSPrimitiveValue::UnitType unit_type = - to_list->at(i)->TypeWithCalcResolved(); + const SVGLength* length_for_unit_type = to_list->at(i); float effective_from = 0; if (from_length_list_size) { if (percentage < 0.5) - unit_type = from_list->at(i)->TypeWithCalcResolved(); + length_for_unit_type = from_list->at(i); effective_from = from_list->at(i)->Value(length_context); } float effective_to = to_list->at(i)->Value(length_context); @@ -152,6 +151,11 @@ void SVGLengthList::CalculateAnimatedValue( animation_element->AnimateAdditiveNumber( percentage, repeat_count, effective_from, effective_to, effective_to_at_end, animated_number); + // |animated_number| is in user units. + CSSPrimitiveValue::UnitType unit_type = + length_for_unit_type->IsCalculated() + ? CSSPrimitiveValue::UnitType::kUserUnits + : length_for_unit_type->NumericLiteralType(); at(i)->SetUnitType(unit_type); at(i)->SetValue(animated_number, length_context); } diff --git a/chromium/third_party/blink/renderer/core/svg/svg_length_list.idl b/chromium/third_party/blink/renderer/core/svg/svg_length_list.idl index b71c499c38b..a235675382b 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_length_list.idl +++ b/chromium/third_party/blink/renderer/core/svg/svg_length_list.idl @@ -27,6 +27,7 @@ // https://svgwg.org/svg2-draft/types.html#InterfaceSVGLengthList [ + Exposed=Window, ImplementedAs=SVGLengthListTearOff ] interface SVGLengthList { readonly attribute unsigned long length; diff --git a/chromium/third_party/blink/renderer/core/svg/svg_length_tear_off.cc b/chromium/third_party/blink/renderer/core/svg/svg_length_tear_off.cc index 749de14193f..be80a2d5b9d 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_length_tear_off.cc +++ b/chromium/third_party/blink/renderer/core/svg/svg_length_tear_off.cc @@ -101,7 +101,7 @@ bool SVGLengthTearOff::HasExposedLengthUnit() { if (Target()->IsCalculated()) return false; - CSSPrimitiveValue::UnitType unit = Target()->TypeWithCalcResolved(); + CSSPrimitiveValue::UnitType unit = Target()->NumericLiteralType(); return IsValidLengthUnit(unit) || unit == CSSPrimitiveValue::UnitType::kUnknown || unit == CSSPrimitiveValue::UnitType::kUserUnits; @@ -109,7 +109,7 @@ bool SVGLengthTearOff::HasExposedLengthUnit() { uint16_t SVGLengthTearOff::unitType() { return HasExposedLengthUnit() - ? ToInterfaceConstant(Target()->TypeWithCalcResolved()) + ? ToInterfaceConstant(Target()->NumericLiteralType()) : kSvgLengthtypeUnknown; } diff --git a/chromium/third_party/blink/renderer/core/svg/svg_line_element.idl b/chromium/third_party/blink/renderer/core/svg/svg_line_element.idl index 24856081f44..60927a53541 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_line_element.idl +++ b/chromium/third_party/blink/renderer/core/svg/svg_line_element.idl @@ -25,6 +25,7 @@ // https://svgwg.org/svg2-draft/shapes.html#InterfaceSVGLineElement +[Exposed=Window] interface SVGLineElement : SVGGeometryElement { [MeasureAs=SVG1DOMShape] readonly attribute SVGAnimatedLength x1; [MeasureAs=SVG1DOMShape] readonly attribute SVGAnimatedLength y1; diff --git a/chromium/third_party/blink/renderer/core/svg/svg_linear_gradient_element.idl b/chromium/third_party/blink/renderer/core/svg/svg_linear_gradient_element.idl index 64c8656b6da..02a6d078cda 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_linear_gradient_element.idl +++ b/chromium/third_party/blink/renderer/core/svg/svg_linear_gradient_element.idl @@ -25,6 +25,7 @@ // https://svgwg.org/svg2-draft/pservers.html#InterfaceSVGLinearGradientElement +[Exposed=Window] interface SVGLinearGradientElement : SVGGradientElement { [MeasureAs=SVG1DOMPaintServer] readonly attribute SVGAnimatedLength x1; [MeasureAs=SVG1DOMPaintServer] readonly attribute SVGAnimatedLength y1; diff --git a/chromium/third_party/blink/renderer/core/svg/svg_marker_element.idl b/chromium/third_party/blink/renderer/core/svg/svg_marker_element.idl index edd8c75ab28..c75fd2ffd3d 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_marker_element.idl +++ b/chromium/third_party/blink/renderer/core/svg/svg_marker_element.idl @@ -25,6 +25,7 @@ // https://svgwg.org/svg2-draft/painting.html#InterfaceSVGMarkerElement +[Exposed=Window] interface SVGMarkerElement : SVGElement { // Marker Unit Types diff --git a/chromium/third_party/blink/renderer/core/svg/svg_mask_element.cc b/chromium/third_party/blink/renderer/core/svg/svg_mask_element.cc index 827e47966d9..e194b0fe21f 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_mask_element.cc +++ b/chromium/third_party/blink/renderer/core/svg/svg_mask_element.cc @@ -130,7 +130,7 @@ void SVGMaskElement::SvgAttributeChanged(const QualifiedName& attr_name) { } LayoutSVGResourceContainer* layout_object = - ToLayoutSVGResourceContainer(this->GetLayoutObject()); + ToLayoutSVGResourceContainer(GetLayoutObject()); if (layout_object) layout_object->InvalidateCacheAndMarkForLayout(); diff --git a/chromium/third_party/blink/renderer/core/svg/svg_metadata_element.idl b/chromium/third_party/blink/renderer/core/svg/svg_metadata_element.idl index 9c557f1fa12..e55d8a167b2 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_metadata_element.idl +++ b/chromium/third_party/blink/renderer/core/svg/svg_metadata_element.idl @@ -21,5 +21,6 @@ // https://svgwg.org/svg2-draft/struct.html#InterfaceSVGMetadataElement +[Exposed=Window] interface SVGMetadataElement : SVGElement { }; diff --git a/chromium/third_party/blink/renderer/core/svg/svg_mpath_element.h b/chromium/third_party/blink/renderer/core/svg/svg_mpath_element.h index ee6fa88384b..59e28717381 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_mpath_element.h +++ b/chromium/third_party/blink/renderer/core/svg/svg_mpath_element.h @@ -39,6 +39,10 @@ class SVGMPathElement final : public SVGElement, public SVGURIReference { void TargetPathChanged(); + const AttrNameToTrustedType& GetCheckedAttributeTypes() const override { + return SVGURIReference::GetCheckedAttributeTypes(); + } + void Trace(blink::Visitor*) override; private: diff --git a/chromium/third_party/blink/renderer/core/svg/svg_number.idl b/chromium/third_party/blink/renderer/core/svg/svg_number.idl index b8be001920c..34fb0bde275 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_number.idl +++ b/chromium/third_party/blink/renderer/core/svg/svg_number.idl @@ -23,6 +23,7 @@ // https://svgwg.org/svg2-draft/types.html#InterfaceSVGNumber [ + Exposed=Window, ImplementedAs=SVGNumberTearOff ] interface SVGNumber { [RaisesException=Setter] attribute float value; diff --git a/chromium/third_party/blink/renderer/core/svg/svg_number_list.idl b/chromium/third_party/blink/renderer/core/svg/svg_number_list.idl index 1b26f22a8a3..10c86ae8eb6 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_number_list.idl +++ b/chromium/third_party/blink/renderer/core/svg/svg_number_list.idl @@ -27,6 +27,7 @@ // https://svgwg.org/svg2-draft/types.html#InterfaceSVGNumberList [ + Exposed=Window, ImplementedAs=SVGNumberListTearOff ] interface SVGNumberList { readonly attribute unsigned long length; diff --git a/chromium/third_party/blink/renderer/core/svg/svg_parsing_error.h b/chromium/third_party/blink/renderer/core/svg/svg_parsing_error.h index 03affa67a76..5ddcde59d00 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_parsing_error.h +++ b/chromium/third_party/blink/renderer/core/svg/svg_parsing_error.h @@ -68,7 +68,7 @@ class SVGParsingError { SVGParsingError(SVGParseStatus status = SVGParseStatus::kNoError, size_t locus = 0) : status_(static_cast<unsigned>(status)), locus_(CheckLocus(locus)) { - DCHECK_EQ(this->Status(), status); + DCHECK_EQ(Status(), status); } SVGParseStatus Status() const { return static_cast<SVGParseStatus>(status_); } diff --git a/chromium/third_party/blink/renderer/core/svg/svg_path_blender.cc b/chromium/third_party/blink/renderer/core/svg/svg_path_blender.cc index 3fd84ceb6f8..feeb3608ae4 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_path_blender.cc +++ b/chromium/third_party/blink/renderer/core/svg/svg_path_blender.cc @@ -23,7 +23,7 @@ #include "third_party/blink/renderer/core/svg/svg_path_consumer.h" #include "third_party/blink/renderer/core/svg/svg_path_data.h" #include "third_party/blink/renderer/platform/animation/animation_utilities.h" -#include "third_party/blink/renderer/platform/wtf/allocator.h" +#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" namespace blink { diff --git a/chromium/third_party/blink/renderer/core/svg/svg_path_data.h b/chromium/third_party/blink/renderer/core/svg/svg_path_data.h index 9e4f84abaaf..c58d9fd1610 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_path_data.h +++ b/chromium/third_party/blink/renderer/core/svg/svg_path_data.h @@ -22,7 +22,7 @@ #define THIRD_PARTY_BLINK_RENDERER_CORE_SVG_SVG_PATH_DATA_H_ #include "third_party/blink/renderer/platform/geometry/float_point.h" -#include "third_party/blink/renderer/platform/wtf/allocator.h" +#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" namespace blink { diff --git a/chromium/third_party/blink/renderer/core/svg/svg_path_element.cc b/chromium/third_party/blink/renderer/core/svg/svg_path_element.cc index cb1383fe0fe..c4f1cdf877e 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_path_element.cc +++ b/chromium/third_party/blink/renderer/core/svg/svg_path_element.cc @@ -47,7 +47,7 @@ Path SVGPathElement::AttributePath() const { } const StylePath* SVGPathElement::GetStylePath() const { - if (LayoutObject* layout_object = this->GetLayoutObject()) { + if (LayoutObject* layout_object = GetLayoutObject()) { const StylePath* style_path = layout_object->StyleRef().SvgStyle().D(); if (style_path) return style_path; @@ -99,7 +99,7 @@ void SVGPathElement::CollectStyleForPresentationAttribute( MutableCSSPropertyValueSet* style) { SVGAnimatedPropertyBase* property = PropertyFromAttribute(name); if (property == path_) { - SVGAnimatedPath* path = this->GetPath(); + SVGAnimatedPath* path = GetPath(); // If this is a <use> instance, return the referenced path to maximize // geometry sharing. if (const SVGElement* element = CorrespondingElement()) diff --git a/chromium/third_party/blink/renderer/core/svg/svg_path_element.idl b/chromium/third_party/blink/renderer/core/svg/svg_path_element.idl index 748f41834c8..2a4f0f75023 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_path_element.idl +++ b/chromium/third_party/blink/renderer/core/svg/svg_path_element.idl @@ -26,5 +26,6 @@ // https://svgwg.org/svg2-draft/paths.html#InterfaceSVGPathElement +[Exposed=Window] interface SVGPathElement : SVGGeometryElement { }; diff --git a/chromium/third_party/blink/renderer/core/svg/svg_path_query.h b/chromium/third_party/blink/renderer/core/svg/svg_path_query.h index c4b57386f23..5cb68be5d57 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_path_query.h +++ b/chromium/third_party/blink/renderer/core/svg/svg_path_query.h @@ -21,7 +21,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_SVG_SVG_PATH_QUERY_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_SVG_SVG_PATH_QUERY_H_ -#include "third_party/blink/renderer/platform/wtf/allocator.h" +#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" namespace blink { diff --git a/chromium/third_party/blink/renderer/core/svg/svg_pattern_element.h b/chromium/third_party/blink/renderer/core/svg/svg_pattern_element.h index 45b7af10525..1a4e2cbf138 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_pattern_element.h +++ b/chromium/third_party/blink/renderer/core/svg/svg_pattern_element.h @@ -80,6 +80,10 @@ class SVGPatternElement final : public SVGElement, const SVGPatternElement* ReferencedElement() const; + const AttrNameToTrustedType& GetCheckedAttributeTypes() const override { + return SVGURIReference::GetCheckedAttributeTypes(); + } + void Trace(blink::Visitor*) override; private: diff --git a/chromium/third_party/blink/renderer/core/svg/svg_pattern_element.idl b/chromium/third_party/blink/renderer/core/svg/svg_pattern_element.idl index 121f9b0a72a..49098b490a5 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_pattern_element.idl +++ b/chromium/third_party/blink/renderer/core/svg/svg_pattern_element.idl @@ -25,6 +25,7 @@ // https://svgwg.org/svg2-draft/pservers.html#InterfaceSVGPatternElement +[Exposed=Window] interface SVGPatternElement : SVGElement { [MeasureAs=SVG1DOMPaintServer] readonly attribute SVGAnimatedEnumeration patternUnits; [MeasureAs=SVG1DOMPaintServer] readonly attribute SVGAnimatedEnumeration patternContentUnits; diff --git a/chromium/third_party/blink/renderer/core/svg/svg_point_list.idl b/chromium/third_party/blink/renderer/core/svg/svg_point_list.idl index 060c6c08840..fd5aaa7161f 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_point_list.idl +++ b/chromium/third_party/blink/renderer/core/svg/svg_point_list.idl @@ -26,6 +26,7 @@ // https://svgwg.org/svg2-draft/shapes.html#InterfaceSVGPointList [ + Exposed=Window, ImplementedAs=SVGPointListTearOff ] interface SVGPointList { readonly attribute unsigned long length; diff --git a/chromium/third_party/blink/renderer/core/svg/svg_polygon_element.idl b/chromium/third_party/blink/renderer/core/svg/svg_polygon_element.idl index 02bf320cfc6..ab5e762f0cf 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_polygon_element.idl +++ b/chromium/third_party/blink/renderer/core/svg/svg_polygon_element.idl @@ -25,6 +25,7 @@ // https://svgwg.org/svg2-draft/shapes.html#InterfaceSVGPolygonElement +[Exposed=Window] interface SVGPolygonElement : SVGGeometryElement { // TODO(foolip): points and animatedPoints be on the SVGAnimatedPoints // interface which SVGPolygonElement should implement: diff --git a/chromium/third_party/blink/renderer/core/svg/svg_polyline_element.idl b/chromium/third_party/blink/renderer/core/svg/svg_polyline_element.idl index 2bb45187bd5..8539eaddde6 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_polyline_element.idl +++ b/chromium/third_party/blink/renderer/core/svg/svg_polyline_element.idl @@ -25,6 +25,7 @@ // https://svgwg.org/svg2-draft/shapes.html#InterfaceSVGPolylineElement +[Exposed=Window] interface SVGPolylineElement : SVGGeometryElement { // TODO(foolip): points and animatedPoints should be on the // SVGAnimatedPoints interface which SVGPolylineElement should implement: diff --git a/chromium/third_party/blink/renderer/core/svg/svg_preserve_aspect_ratio.idl b/chromium/third_party/blink/renderer/core/svg/svg_preserve_aspect_ratio.idl index 6ff75fb2dfc..1b730f7d0d5 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_preserve_aspect_ratio.idl +++ b/chromium/third_party/blink/renderer/core/svg/svg_preserve_aspect_ratio.idl @@ -26,6 +26,7 @@ // https://svgwg.org/svg2-draft/coords.html#InterfaceSVGPreserveAspectRatio [ + Exposed=Window, ImplementedAs=SVGPreserveAspectRatioTearOff ] interface SVGPreserveAspectRatio { // Alignment types diff --git a/chromium/third_party/blink/renderer/core/svg/svg_radial_gradient_element.idl b/chromium/third_party/blink/renderer/core/svg/svg_radial_gradient_element.idl index a128bf5851a..3330290c604 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_radial_gradient_element.idl +++ b/chromium/third_party/blink/renderer/core/svg/svg_radial_gradient_element.idl @@ -25,6 +25,7 @@ // https://svgwg.org/svg2-draft/pservers.html#InterfaceSVGRadialGradientElement +[Exposed=Window] interface SVGRadialGradientElement : SVGGradientElement { [MeasureAs=SVG1DOMPaintServer] readonly attribute SVGAnimatedLength cx; [MeasureAs=SVG1DOMPaintServer] readonly attribute SVGAnimatedLength cy; diff --git a/chromium/third_party/blink/renderer/core/svg/svg_rect.h b/chromium/third_party/blink/renderer/core/svg/svg_rect.h index 9f32545d709..e579b2745a9 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_rect.h +++ b/chromium/third_party/blink/renderer/core/svg/svg_rect.h @@ -23,7 +23,7 @@ #include "third_party/blink/renderer/core/svg/properties/svg_property_helper.h" #include "third_party/blink/renderer/core/svg/svg_parsing_error.h" #include "third_party/blink/renderer/platform/geometry/float_rect.h" -#include "third_party/blink/renderer/platform/wtf/allocator.h" +#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" namespace blink { diff --git a/chromium/third_party/blink/renderer/core/svg/svg_rect_element.idl b/chromium/third_party/blink/renderer/core/svg/svg_rect_element.idl index bde3c4bedf9..dabf27d429a 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_rect_element.idl +++ b/chromium/third_party/blink/renderer/core/svg/svg_rect_element.idl @@ -26,6 +26,7 @@ // https://svgwg.org/svg2-draft/shapes.html#InterfaceSVGRectElement +[Exposed=Window] interface SVGRectElement : SVGGeometryElement { [MeasureAs=SVG1DOMShape] readonly attribute SVGAnimatedLength x; [MeasureAs=SVG1DOMShape] readonly attribute SVGAnimatedLength y; diff --git a/chromium/third_party/blink/renderer/core/svg/svg_resource.cc b/chromium/third_party/blink/renderer/core/svg/svg_resource.cc index d767e45b99c..9421f732db6 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_resource.cc +++ b/chromium/third_party/blink/renderer/core/svg/svg_resource.cc @@ -128,8 +128,8 @@ void ExternalSVGResource::Load(const Document& document) { ResourceLoaderOptions options; options.initiator_info.name = fetch_initiator_type_names::kCSS; FetchParameters params(ResourceRequest(url_), options); - params.MutableResourceRequest().SetFetchRequestMode( - network::mojom::FetchRequestMode::kSameOrigin); + params.MutableResourceRequest().SetMode( + network::mojom::RequestMode::kSameOrigin); resource_document_ = DocumentResource::FetchSVGDocument(params, document.Fetcher(), this); target_ = ResolveTarget(); diff --git a/chromium/third_party/blink/renderer/core/svg/svg_script_element.cc b/chromium/third_party/blink/renderer/core/svg/svg_script_element.cc index 5d3ac5435b2..0147e9dfdef 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_script_element.cc +++ b/chromium/third_party/blink/renderer/core/svg/svg_script_element.cc @@ -173,6 +173,16 @@ bool SVGScriptElement::IsAnimatableAttribute(const QualifiedName& name) const { } #endif +const AttrNameToTrustedType& SVGScriptElement::GetCheckedAttributeTypes() + const { + DEFINE_STATIC_LOCAL(AttrNameToTrustedType, attribute_map, + ({ + {svg_names::kHrefAttr.LocalName(), + SpecificTrustedType::kTrustedScriptURL}, + })); + return attribute_map; +} + void SVGScriptElement::Trace(blink::Visitor* visitor) { visitor->Trace(loader_); SVGElement::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/core/svg/svg_script_element.h b/chromium/third_party/blink/renderer/core/svg/svg_script_element.h index c1222ee2449..cb4b1763331 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_script_element.h +++ b/chromium/third_party/blink/renderer/core/svg/svg_script_element.h @@ -49,6 +49,8 @@ class SVGScriptElement final : public SVGElement, bool IsScriptElement() const override { return true; } + const AttrNameToTrustedType& GetCheckedAttributeTypes() const override; + void Trace(blink::Visitor*) override; private: diff --git a/chromium/third_party/blink/renderer/core/svg/svg_script_element.idl b/chromium/third_party/blink/renderer/core/svg/svg_script_element.idl index 8ab0ade9b9a..59fc666d8bd 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_script_element.idl +++ b/chromium/third_party/blink/renderer/core/svg/svg_script_element.idl @@ -25,6 +25,7 @@ // https://svgwg.org/svg2-draft/interact.html#InterfaceSVGScriptElement +[Exposed=Window] interface SVGScriptElement : SVGElement { [Reflect] attribute DOMString type; }; diff --git a/chromium/third_party/blink/renderer/core/svg/svg_stop_element.cc b/chromium/third_party/blink/renderer/core/svg/svg_stop_element.cc index 7d73cf86127..557ce8d9706 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_stop_element.cc +++ b/chromium/third_party/blink/renderer/core/svg/svg_stop_element.cc @@ -51,7 +51,7 @@ void InvalidateInstancesAndAncestorResources(SVGStopElement* stop_element) { SVGElement::InvalidationGuard invalidation_guard(stop_element); Element* parent = stop_element->parentElement(); - if (auto* gradient = ToSVGGradientElementOrNull(parent)) + if (auto* gradient = DynamicTo<SVGGradientElement>(parent)) gradient->InvalidateGradient(layout_invalidation_reason::kChildChanged); } diff --git a/chromium/third_party/blink/renderer/core/svg/svg_stop_element.idl b/chromium/third_party/blink/renderer/core/svg/svg_stop_element.idl index 642e3aa8190..36fc16ec889 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_stop_element.idl +++ b/chromium/third_party/blink/renderer/core/svg/svg_stop_element.idl @@ -25,6 +25,7 @@ // https://svgwg.org/svg2-draft/pservers.html#InterfaceSVGStopElement +[Exposed=Window] interface SVGStopElement : SVGElement { [MeasureAs=SVG1DOMPaintServer] readonly attribute SVGAnimatedNumber offset; }; diff --git a/chromium/third_party/blink/renderer/core/svg/svg_string_list.idl b/chromium/third_party/blink/renderer/core/svg/svg_string_list.idl index 3609fcb8b2a..8f81d377b1d 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_string_list.idl +++ b/chromium/third_party/blink/renderer/core/svg/svg_string_list.idl @@ -26,6 +26,7 @@ // https://svgwg.org/svg2-draft/types.html#InterfaceSVGStringList [ + Exposed=Window, ImplementedAs=SVGStringListTearOff ] interface SVGStringList { readonly attribute unsigned long length; diff --git a/chromium/third_party/blink/renderer/core/svg/svg_style_element.idl b/chromium/third_party/blink/renderer/core/svg/svg_style_element.idl index 59fe6ac06e5..17044044289 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_style_element.idl +++ b/chromium/third_party/blink/renderer/core/svg/svg_style_element.idl @@ -26,6 +26,7 @@ // https://svgwg.org/svg2-draft/styling.html#InterfaceSVGStyleElement +[Exposed=Window] interface SVGStyleElement : SVGElement { attribute DOMString type; attribute DOMString media; diff --git a/chromium/third_party/blink/renderer/core/svg/svg_svg_element.cc b/chromium/third_party/blink/renderer/core/svg/svg_svg_element.cc index 3ca5f742ddf..fa5d203086e 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_svg_element.cc +++ b/chromium/third_party/blink/renderer/core/svg/svg_svg_element.cc @@ -146,7 +146,7 @@ void SVGSVGElement::UpdateUserTransform() { } bool SVGSVGElement::ZoomAndPanEnabled() const { - SVGZoomAndPanType zoom_and_pan = this->zoomAndPan(); + SVGZoomAndPanType zoom_and_pan = zoomAndPan(); if (view_spec_ && view_spec_->ZoomAndPan() != kSVGZoomAndPanUnknown) zoom_and_pan = view_spec_->ZoomAndPan(); return zoom_and_pan == kSVGZoomAndPanMagnify; @@ -249,7 +249,7 @@ void SVGSVGElement::SvgAttributeChanged(const QualifiedName& attr_name) { // height attributes can affect the replaced size so we need // to mark it for updating. if (width_or_height_changed) { - LayoutObject* layout_object = this->GetLayoutObject(); + LayoutObject* layout_object = GetLayoutObject(); // If the element is not attached, we cannot be sure if it is (going to // be) an outermost root, so always mark presentation attributes dirty in // that case. @@ -323,7 +323,7 @@ bool SVGSVGElement::CheckIntersectionOrEnclosure( return false; AffineTransform ctm = - ToSVGGraphicsElement(element).ComputeCTM(kAncestorScope, this); + To<SVGGraphicsElement>(element).ComputeCTM(kAncestorScope, this); FloatRect mapped_repaint_rect = ctm.MapRect(layout_object->VisualRectInLocalSVGCoordinates()); @@ -451,7 +451,7 @@ AffineTransform SVGSVGElement::LocalCoordinateSpaceTransform( transform.Translate(x_->CurrentValue()->Value(length_context), y_->CurrentValue()->Value(length_context)); } else if (mode == kScreenScope) { - if (LayoutObject* layout_object = this->GetLayoutObject()) { + if (LayoutObject* layout_object = GetLayoutObject()) { TransformationMatrix matrix; // Adjust for the zoom level factored into CSS coordinates (WK bug // #96361). @@ -629,18 +629,21 @@ FloatSize SVGSVGElement::CurrentViewportSize() const { } bool SVGSVGElement::HasIntrinsicWidth() const { - return width()->CurrentValue()->TypeWithCalcResolved() != - CSSPrimitiveValue::UnitType::kPercentage; + // TODO(crbug.com/979895): This is the result of a refactoring, which might + // have revealed an existing bug that we are not handling math functions + // involving percentages correctly. Fix it if necessary. + return !width()->CurrentValue()->IsPercentage(); } bool SVGSVGElement::HasIntrinsicHeight() const { - return height()->CurrentValue()->TypeWithCalcResolved() != - CSSPrimitiveValue::UnitType::kPercentage; + // TODO(crbug.com/979895): This is the result of a refactoring, which might + // have revealed an existing bug that we are not handling math functions + // involving percentages correctly. Fix it if necessary. + return !height()->CurrentValue()->IsPercentage(); } float SVGSVGElement::IntrinsicWidth() const { - if (width()->CurrentValue()->TypeWithCalcResolved() == - CSSPrimitiveValue::UnitType::kPercentage) + if (!HasIntrinsicWidth()) return 0; SVGLengthContext length_context(this); @@ -648,8 +651,7 @@ float SVGSVGElement::IntrinsicWidth() const { } float SVGSVGElement::IntrinsicHeight() const { - if (height()->CurrentValue()->TypeWithCalcResolved() == - CSSPrimitiveValue::UnitType::kPercentage) + if (!HasIntrinsicHeight()) return 0; SVGLengthContext length_context(this); diff --git a/chromium/third_party/blink/renderer/core/svg/svg_svg_element.idl b/chromium/third_party/blink/renderer/core/svg/svg_svg_element.idl index 898a11cf01e..e59537f9f2b 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_svg_element.idl +++ b/chromium/third_party/blink/renderer/core/svg/svg_svg_element.idl @@ -22,6 +22,7 @@ // https://svgwg.org/svg2-draft/struct.html#InterfaceSVGSVGElement +[Exposed=Window] interface SVGSVGElement : SVGGraphicsElement { [MeasureAs=SVG1DOMSVGElement] readonly attribute SVGAnimatedLength x; [MeasureAs=SVG1DOMSVGElement] readonly attribute SVGAnimatedLength y; diff --git a/chromium/third_party/blink/renderer/core/svg/svg_switch_element.cc b/chromium/third_party/blink/renderer/core/svg/svg_switch_element.cc index 73be72c72a3..f47af0dbb74 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_switch_element.cc +++ b/chromium/third_party/blink/renderer/core/svg/svg_switch_element.cc @@ -20,9 +20,9 @@ #include "third_party/blink/renderer/core/svg/svg_switch_element.h" -#include "third_party/blink/renderer/core/frame/use_counter.h" #include "third_party/blink/renderer/core/layout/svg/layout_svg_transformable_container.h" #include "third_party/blink/renderer/core/svg_names.h" +#include "third_party/blink/renderer/platform/instrumentation/use_counter.h" namespace blink { diff --git a/chromium/third_party/blink/renderer/core/svg/svg_switch_element.idl b/chromium/third_party/blink/renderer/core/svg/svg_switch_element.idl index 3611d236aae..f90943eb9f9 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_switch_element.idl +++ b/chromium/third_party/blink/renderer/core/svg/svg_switch_element.idl @@ -25,5 +25,6 @@ // https://svgwg.org/svg2-draft/struct.html#InterfaceSVGSwitchElement +[Exposed=Window] interface SVGSwitchElement : SVGGraphicsElement { }; diff --git a/chromium/third_party/blink/renderer/core/svg/svg_symbol_element.idl b/chromium/third_party/blink/renderer/core/svg/svg_symbol_element.idl index 7b5298a879a..939eb94ae66 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_symbol_element.idl +++ b/chromium/third_party/blink/renderer/core/svg/svg_symbol_element.idl @@ -25,6 +25,7 @@ // https://svgwg.org/svg2-draft/struct.html#InterfaceSVGSymbolElement +[Exposed=Window] interface SVGSymbolElement : SVGElement { }; diff --git a/chromium/third_party/blink/renderer/core/svg/svg_text_content_element.cc b/chromium/third_party/blink/renderer/core/svg/svg_text_content_element.cc index 07ecdaff02c..15a88aacac1 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_text_content_element.cc +++ b/chromium/third_party/blink/renderer/core/svg/svg_text_content_element.cc @@ -24,7 +24,6 @@ #include "third_party/blink/renderer/core/css_value_keywords.h" #include "third_party/blink/renderer/core/editing/frame_selection.h" #include "third_party/blink/renderer/core/frame/local_frame.h" -#include "third_party/blink/renderer/core/frame/use_counter.h" #include "third_party/blink/renderer/core/layout/api/line_layout_item.h" #include "third_party/blink/renderer/core/layout/svg/svg_text_query.h" #include "third_party/blink/renderer/core/svg/svg_enumeration_map.h" @@ -35,6 +34,7 @@ #include "third_party/blink/renderer/platform/bindings/exception_messages.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" #include "third_party/blink/renderer/platform/heap/heap.h" +#include "third_party/blink/renderer/platform/instrumentation/use_counter.h" namespace blink { @@ -60,8 +60,7 @@ class SVGAnimatedTextLength final : public SVGAnimatedLength { SVGLength::Initial::kUnitlessZero) {} SVGLengthTearOff* baseVal() override { - SVGTextContentElement* text_content_element = - ToSVGTextContentElement(ContextElement()); + auto* text_content_element = To<SVGTextContentElement>(ContextElement()); if (!text_content_element->TextLengthIsSpecifiedByUser()) BaseValue()->NewValueSpecifiedUnits( CSSPrimitiveValue::UnitType::kNumber, @@ -280,10 +279,8 @@ SVGTextContentElement* SVGTextContentElement::ElementFromLineLayoutItem( (!line_layout_item.IsSVGText() && !line_layout_item.IsSVGInline())) return nullptr; - auto* element = To<SVGElement>(line_layout_item.GetNode()); - DCHECK(element); - return IsSVGTextContentElement(*element) ? ToSVGTextContentElement(element) - : nullptr; + DCHECK(line_layout_item.GetNode()); + return DynamicTo<SVGTextContentElement>(line_layout_item.GetNode()); } } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/svg/svg_text_content_element.h b/chromium/third_party/blink/renderer/core/svg/svg_text_content_element.h index e6b76611395..2538750acae 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_text_content_element.h +++ b/chromium/third_party/blink/renderer/core/svg/svg_text_content_element.h @@ -96,7 +96,13 @@ inline bool IsSVGTextContentElement(const SVGElement& element) { return element.IsTextContent(); } -DEFINE_SVGELEMENT_TYPE_CASTS_WITH_FUNCTION(SVGTextContentElement); +template <> +struct DowncastTraits<SVGTextContentElement> { + static bool AllowFrom(const Node& node) { + auto* svg_element = DynamicTo<SVGElement>(node); + return svg_element && IsSVGTextContentElement(*svg_element); + } +}; } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/svg/svg_text_content_element.idl b/chromium/third_party/blink/renderer/core/svg/svg_text_content_element.idl index 6557fcf63d8..2117f0d68b5 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_text_content_element.idl +++ b/chromium/third_party/blink/renderer/core/svg/svg_text_content_element.idl @@ -25,6 +25,7 @@ // https://svgwg.org/svg2-draft/text.html#InterfaceSVGTextContentElement +[Exposed=Window] interface SVGTextContentElement : SVGGraphicsElement { // lengthAdjust Types [MeasureAs=SVG1DOMText] const unsigned short LENGTHADJUST_UNKNOWN = 0; diff --git a/chromium/third_party/blink/renderer/core/svg/svg_text_content_element_test.cc b/chromium/third_party/blink/renderer/core/svg/svg_text_content_element_test.cc index db820703b09..24625dde3b6 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_text_content_element_test.cc +++ b/chromium/third_party/blink/renderer/core/svg/svg_text_content_element_test.cc @@ -13,8 +13,7 @@ class SVGTextContentElementTest : public EditingTestBase {}; TEST_F(SVGTextContentElementTest, selectSubStringNotCrash) { SetBodyContent("<svg><text style='visibility:hidden;'>Text</text></svg>"); - SVGTextContentElement* elem = - ToSVGTextContentElement(GetDocument().QuerySelector("text")); + auto* elem = To<SVGTextContentElement>(GetDocument().QuerySelector("text")); VisiblePosition start = VisiblePosition::FirstPositionInNode( *const_cast<SVGTextContentElement*>(elem)); EXPECT_TRUE(start.IsNull()); diff --git a/chromium/third_party/blink/renderer/core/svg/svg_text_element.idl b/chromium/third_party/blink/renderer/core/svg/svg_text_element.idl index d3cbdf80a51..0ab1b3353b6 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_text_element.idl +++ b/chromium/third_party/blink/renderer/core/svg/svg_text_element.idl @@ -25,5 +25,6 @@ // https://svgwg.org/svg2-draft/text.html#InterfaceSVGTextElement +[Exposed=Window] interface SVGTextElement : SVGTextPositioningElement { }; diff --git a/chromium/third_party/blink/renderer/core/svg/svg_text_path_element.h b/chromium/third_party/blink/renderer/core/svg/svg_text_path_element.h index 05766023ca6..17c7f3c8a26 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_text_path_element.h +++ b/chromium/third_party/blink/renderer/core/svg/svg_text_path_element.h @@ -66,6 +66,10 @@ class SVGTextPathElement final : public SVGTextContentElement, return spacing_.Get(); } + const AttrNameToTrustedType& GetCheckedAttributeTypes() const override { + return SVGURIReference::GetCheckedAttributeTypes(); + } + void Trace(blink::Visitor*) override; private: diff --git a/chromium/third_party/blink/renderer/core/svg/svg_text_path_element.idl b/chromium/third_party/blink/renderer/core/svg/svg_text_path_element.idl index 2aea585ab3c..4fa851e0fc2 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_text_path_element.idl +++ b/chromium/third_party/blink/renderer/core/svg/svg_text_path_element.idl @@ -25,6 +25,7 @@ // https://svgwg.org/svg2-draft/text.html#InterfaceSVGTextPathElement +[Exposed=Window] interface SVGTextPathElement : SVGTextContentElement { // textPath Method Types [MeasureAs=SVG1DOMText] const unsigned short TEXTPATH_METHODTYPE_UNKNOWN = 0; diff --git a/chromium/third_party/blink/renderer/core/svg/svg_text_positioning_element.h b/chromium/third_party/blink/renderer/core/svg/svg_text_positioning_element.h index ac293307305..fd26dff2e08 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_text_positioning_element.h +++ b/chromium/third_party/blink/renderer/core/svg/svg_text_positioning_element.h @@ -57,7 +57,13 @@ inline bool IsSVGTextPositioningElement(const SVGElement& element) { return element.IsTextPositioning(); } -DEFINE_SVGELEMENT_TYPE_CASTS_WITH_FUNCTION(SVGTextPositioningElement); +template <> +struct DowncastTraits<SVGTextPositioningElement> { + static bool AllowFrom(const Node& node) { + auto* svg_element = DynamicTo<SVGElement>(node); + return svg_element && IsSVGTextPositioningElement(*svg_element); + } +}; } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/svg/svg_text_positioning_element.idl b/chromium/third_party/blink/renderer/core/svg/svg_text_positioning_element.idl index c55fe385578..3e3e90c3f17 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_text_positioning_element.idl +++ b/chromium/third_party/blink/renderer/core/svg/svg_text_positioning_element.idl @@ -25,6 +25,7 @@ // https://svgwg.org/svg2-draft/text.html#InterfaceSVGTextPositioningElement +[Exposed=Window] interface SVGTextPositioningElement : SVGTextContentElement { [MeasureAs=SVG1DOMText] readonly attribute SVGAnimatedLengthList x; [MeasureAs=SVG1DOMText] readonly attribute SVGAnimatedLengthList y; diff --git a/chromium/third_party/blink/renderer/core/svg/svg_title_element.idl b/chromium/third_party/blink/renderer/core/svg/svg_title_element.idl index cfb65fbba04..b40e215c0f1 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_title_element.idl +++ b/chromium/third_party/blink/renderer/core/svg/svg_title_element.idl @@ -25,5 +25,6 @@ // https://svgwg.org/svg2-draft/struct.html#InterfaceSVGTitleElement +[Exposed=Window] interface SVGTitleElement : SVGElement { }; diff --git a/chromium/third_party/blink/renderer/core/svg/svg_transform.idl b/chromium/third_party/blink/renderer/core/svg/svg_transform.idl index d0ec20edd83..1fe9ee2c5d0 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_transform.idl +++ b/chromium/third_party/blink/renderer/core/svg/svg_transform.idl @@ -22,6 +22,7 @@ // https://svgwg.org/svg2-draft/coords.html#InterfaceSVGTransform [ + Exposed=Window, ImplementedAs=SVGTransformTearOff ] interface SVGTransform { // Transform Types diff --git a/chromium/third_party/blink/renderer/core/svg/svg_transform_distance.h b/chromium/third_party/blink/renderer/core/svg/svg_transform_distance.h index 6fa9ab660d2..3f0bb934018 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_transform_distance.h +++ b/chromium/third_party/blink/renderer/core/svg/svg_transform_distance.h @@ -21,7 +21,7 @@ #define THIRD_PARTY_BLINK_RENDERER_CORE_SVG_SVG_TRANSFORM_DISTANCE_H_ #include "third_party/blink/renderer/core/svg/svg_transform.h" -#include "third_party/blink/renderer/platform/wtf/allocator.h" +#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" namespace blink { diff --git a/chromium/third_party/blink/renderer/core/svg/svg_transform_list.cc b/chromium/third_party/blink/renderer/core/svg/svg_transform_list.cc index c24b8c20c81..c85f8ececdf 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_transform_list.cc +++ b/chromium/third_party/blink/renderer/core/svg/svg_transform_list.cc @@ -26,6 +26,7 @@ #include "base/stl_util.h" #include "third_party/blink/renderer/core/css/css_function_value.h" #include "third_party/blink/renderer/core/css/css_identifier_value.h" +#include "third_party/blink/renderer/core/css/css_numeric_literal_value.h" #include "third_party/blink/renderer/core/css/css_primitive_value.h" #include "third_party/blink/renderer/core/css/css_value_list.h" #include "third_party/blink/renderer/core/svg/svg_parser_utilities.h" @@ -228,46 +229,46 @@ CSSValue* CreateTransformCSSValue(const SVGTransform& transform) { MakeGarbageCollected<CSSFunctionValue>(function_id); switch (function_id) { case CSSValueID::kRotate: { - transform_value->Append(*CSSPrimitiveValue::Create( + transform_value->Append(*CSSNumericLiteralValue::Create( transform.Angle(), CSSPrimitiveValue::UnitType::kDegrees)); FloatPoint rotation_origin = transform.RotationCenter(); if (!ToFloatSize(rotation_origin).IsZero()) { - transform_value->Append(*CSSPrimitiveValue::Create( + transform_value->Append(*CSSNumericLiteralValue::Create( rotation_origin.X(), CSSPrimitiveValue::UnitType::kUserUnits)); - transform_value->Append(*CSSPrimitiveValue::Create( + transform_value->Append(*CSSNumericLiteralValue::Create( rotation_origin.Y(), CSSPrimitiveValue::UnitType::kUserUnits)); } break; } case CSSValueID::kSkewX: case CSSValueID::kSkewY: - transform_value->Append(*CSSPrimitiveValue::Create( + transform_value->Append(*CSSNumericLiteralValue::Create( transform.Angle(), CSSPrimitiveValue::UnitType::kDegrees)); break; case CSSValueID::kMatrix: - transform_value->Append(*CSSPrimitiveValue::Create( + transform_value->Append(*CSSNumericLiteralValue::Create( transform.Matrix().A(), CSSPrimitiveValue::UnitType::kUserUnits)); - transform_value->Append(*CSSPrimitiveValue::Create( + transform_value->Append(*CSSNumericLiteralValue::Create( transform.Matrix().B(), CSSPrimitiveValue::UnitType::kUserUnits)); - transform_value->Append(*CSSPrimitiveValue::Create( + transform_value->Append(*CSSNumericLiteralValue::Create( transform.Matrix().C(), CSSPrimitiveValue::UnitType::kUserUnits)); - transform_value->Append(*CSSPrimitiveValue::Create( + transform_value->Append(*CSSNumericLiteralValue::Create( transform.Matrix().D(), CSSPrimitiveValue::UnitType::kUserUnits)); - transform_value->Append(*CSSPrimitiveValue::Create( + transform_value->Append(*CSSNumericLiteralValue::Create( transform.Matrix().E(), CSSPrimitiveValue::UnitType::kUserUnits)); - transform_value->Append(*CSSPrimitiveValue::Create( + transform_value->Append(*CSSNumericLiteralValue::Create( transform.Matrix().F(), CSSPrimitiveValue::UnitType::kUserUnits)); break; case CSSValueID::kScale: - transform_value->Append(*CSSPrimitiveValue::Create( + transform_value->Append(*CSSNumericLiteralValue::Create( transform.Matrix().A(), CSSPrimitiveValue::UnitType::kUserUnits)); - transform_value->Append(*CSSPrimitiveValue::Create( + transform_value->Append(*CSSNumericLiteralValue::Create( transform.Matrix().D(), CSSPrimitiveValue::UnitType::kUserUnits)); break; case CSSValueID::kTranslate: - transform_value->Append(*CSSPrimitiveValue::Create( + transform_value->Append(*CSSNumericLiteralValue::Create( transform.Matrix().E(), CSSPrimitiveValue::UnitType::kUserUnits)); - transform_value->Append(*CSSPrimitiveValue::Create( + transform_value->Append(*CSSNumericLiteralValue::Create( transform.Matrix().F(), CSSPrimitiveValue::UnitType::kUserUnits)); break; default: diff --git a/chromium/third_party/blink/renderer/core/svg/svg_transform_list.idl b/chromium/third_party/blink/renderer/core/svg/svg_transform_list.idl index e917f280ee1..3dda559cf64 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_transform_list.idl +++ b/chromium/third_party/blink/renderer/core/svg/svg_transform_list.idl @@ -27,6 +27,7 @@ // https://svgwg.org/svg2-draft/coords.html#InterfaceSVGTransformList [ + Exposed=Window, ImplementedAs=SVGTransformListTearOff ] interface SVGTransformList { readonly attribute unsigned long length; diff --git a/chromium/third_party/blink/renderer/core/svg/svg_tspan_element.idl b/chromium/third_party/blink/renderer/core/svg/svg_tspan_element.idl index d72fa86dba4..c28604e9265 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_tspan_element.idl +++ b/chromium/third_party/blink/renderer/core/svg/svg_tspan_element.idl @@ -25,5 +25,6 @@ // https://svgwg.org/svg2-draft/text.html#InterfaceSVGTSpanElement +[Exposed=Window] interface SVGTSpanElement : SVGTextPositioningElement { }; diff --git a/chromium/third_party/blink/renderer/core/svg/svg_unit_types.idl b/chromium/third_party/blink/renderer/core/svg/svg_unit_types.idl index 444f27d798f..77700b8b16e 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_unit_types.idl +++ b/chromium/third_party/blink/renderer/core/svg/svg_unit_types.idl @@ -25,6 +25,7 @@ // https://svgwg.org/svg2-draft/types.html#InterfaceSVGUnitTypes +[Exposed=Window] interface SVGUnitTypes { // Unit Types const unsigned short SVG_UNIT_TYPE_UNKNOWN = 0; diff --git a/chromium/third_party/blink/renderer/core/svg/svg_uri_reference.cc b/chromium/third_party/blink/renderer/core/svg/svg_uri_reference.cc index 99471e10c92..47221fbcadf 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_uri_reference.cc +++ b/chromium/third_party/blink/renderer/core/svg/svg_uri_reference.cc @@ -151,4 +151,13 @@ void SVGURIReference::UnobserveTarget(Member<IdTargetObserver>& observer) { observer = nullptr; } +const AttrNameToTrustedType& SVGURIReference::GetCheckedAttributeTypes() { + DEFINE_STATIC_LOCAL( + AttrNameToTrustedType, attribute_map, + ({ + {svg_names::kHrefAttr.LocalName(), SpecificTrustedType::kTrustedURL}, + })); + return attribute_map; +} + } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/svg/svg_uri_reference.h b/chromium/third_party/blink/renderer/core/svg/svg_uri_reference.h index 9b0d5050fc7..8d240521c55 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_uri_reference.h +++ b/chromium/third_party/blink/renderer/core/svg/svg_uri_reference.h @@ -24,6 +24,7 @@ #include <memory> #include "base/callback.h" #include "third_party/blink/renderer/core/core_export.h" +#include "third_party/blink/renderer/core/dom/element.h" #include "third_party/blink/renderer/core/svg/svg_animated_href.h" #include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/weborigin/kurl.h" @@ -31,7 +32,6 @@ namespace blink { class Document; -class Element; class IdTargetObserver; class SVGElement; class TreeScope; @@ -81,6 +81,8 @@ class CORE_EXPORT SVGURIReference : public GarbageCollectedMixin { // JS API SVGAnimatedHref* href() const { return href_.Get(); } + static const AttrNameToTrustedType& GetCheckedAttributeTypes(); + void Trace(blink::Visitor*) override; protected: diff --git a/chromium/third_party/blink/renderer/core/svg/svg_use_element.cc b/chromium/third_party/blink/renderer/core/svg/svg_use_element.cc index cdfdda9d4c8..2d5a2b3a1f2 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_use_element.cc +++ b/chromium/third_party/blink/renderer/core/svg/svg_use_element.cc @@ -204,8 +204,8 @@ void SVGUseElement::UpdateTargetReference() { ResourceLoaderOptions options; options.initiator_info.name = localName(); FetchParameters params(ResourceRequest(element_url_), options); - params.MutableResourceRequest().SetFetchRequestMode( - network::mojom::FetchRequestMode::kSameOrigin); + params.MutableResourceRequest().SetMode( + network::mojom::RequestMode::kSameOrigin); DocumentResource::FetchSVGDocument(params, GetDocument().Fetcher(), this); } @@ -499,23 +499,21 @@ Path SVGUseElement::ToClipPath() const { SVGGraphicsElement* SVGUseElement::VisibleTargetGraphicsElementForClipping() const { - auto* element = DynamicTo<SVGElement>(UseShadowRoot().firstChild()); - if (!element) - return nullptr; - - if (!element->IsSVGGraphicsElement()) + auto* svg_graphics_element = + DynamicTo<SVGGraphicsElement>(UseShadowRoot().firstChild()); + if (!svg_graphics_element) return nullptr; // Spec: "If a <use> element is a child of a clipPath element, it must // directly reference <path>, <text> or basic shapes elements. Indirect // references are an error and the clipPath element must be ignored." // https://drafts.fxtf.org/css-masking/#the-clip-path - if (!IsDirectReference(*element)) { + if (!IsDirectReference(*svg_graphics_element)) { // Spec: Indirect references are an error (14.3.5) return nullptr; } - return &ToSVGGraphicsElement(*element); + return svg_graphics_element; } void SVGUseElement::AddReferencesToFirstDegreeNestedUseElements( diff --git a/chromium/third_party/blink/renderer/core/svg/svg_use_element.h b/chromium/third_party/blink/renderer/core/svg/svg_use_element.h index 7c40606ee2c..b1ce459c8b0 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_use_element.h +++ b/chromium/third_party/blink/renderer/core/svg/svg_use_element.h @@ -59,6 +59,10 @@ class SVGUseElement final : public SVGGraphicsElement, void DispatchPendingEvent(); Path ToClipPath() const; + const AttrNameToTrustedType& GetCheckedAttributeTypes() const override { + return SVGURIReference::GetCheckedAttributeTypes(); + } + void Trace(blink::Visitor*) override; private: diff --git a/chromium/third_party/blink/renderer/core/svg/svg_use_element.idl b/chromium/third_party/blink/renderer/core/svg/svg_use_element.idl index 487f78ad324..2324986492b 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_use_element.idl +++ b/chromium/third_party/blink/renderer/core/svg/svg_use_element.idl @@ -25,6 +25,7 @@ // https://svgwg.org/svg2-draft/struct.html#InterfaceSVGUseElement +[Exposed=Window] interface SVGUseElement : SVGGraphicsElement { [MeasureAs=SVG1DOMUseElement] readonly attribute SVGAnimatedLength x; [MeasureAs=SVG1DOMUseElement] readonly attribute SVGAnimatedLength y; diff --git a/chromium/third_party/blink/renderer/core/svg/svg_view_element.cc b/chromium/third_party/blink/renderer/core/svg/svg_view_element.cc index 53e9262b0db..f91681d0d1a 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_view_element.cc +++ b/chromium/third_party/blink/renderer/core/svg/svg_view_element.cc @@ -20,8 +20,8 @@ #include "third_party/blink/renderer/core/svg/svg_view_element.h" -#include "third_party/blink/renderer/core/frame/use_counter.h" #include "third_party/blink/renderer/core/svg_names.h" +#include "third_party/blink/renderer/platform/instrumentation/use_counter.h" namespace blink { diff --git a/chromium/third_party/blink/renderer/core/svg/svg_view_element.idl b/chromium/third_party/blink/renderer/core/svg/svg_view_element.idl index 53626f22dc4..cb31f4a66ec 100644 --- a/chromium/third_party/blink/renderer/core/svg/svg_view_element.idl +++ b/chromium/third_party/blink/renderer/core/svg/svg_view_element.idl @@ -25,6 +25,7 @@ // https://svgwg.org/svg2-draft/linking.html#InterfaceSVGViewElement +[Exposed=Window] interface SVGViewElement : SVGElement { }; diff --git a/chromium/third_party/blink/renderer/core/svg/unsafe_svg_attribute_sanitization_test.cc b/chromium/third_party/blink/renderer/core/svg/unsafe_svg_attribute_sanitization_test.cc index b49eeeb7b7a..20a4843225a 100644 --- a/chromium/third_party/blink/renderer/core/svg/unsafe_svg_attribute_sanitization_test.cc +++ b/chromium/third_party/blink/renderer/core/svg/unsafe_svg_attribute_sanitization_test.cc @@ -95,11 +95,11 @@ TEST(UnsafeSVGAttributeSanitizationTest, pasteAnchor_javaScriptHrefIsStripped) { EXPECT_TRUE(sanitized_content.Contains("</a>")) << "We should have pasted *something*; the document is: " - << sanitized_content.Utf8().data(); + << sanitized_content.Utf8(); EXPECT_FALSE(sanitized_content.Contains(":alert()")) << "The JavaScript URL is unsafe and should have been stripped; " "instead: " - << sanitized_content.Utf8().data(); + << sanitized_content.Utf8(); } TEST(UnsafeSVGAttributeSanitizationTest, @@ -116,11 +116,11 @@ TEST(UnsafeSVGAttributeSanitizationTest, EXPECT_TRUE(sanitized_content.Contains("</a>")) << "We should have pasted *something*; the document is: " - << sanitized_content.Utf8().data(); + << sanitized_content.Utf8(); EXPECT_FALSE(sanitized_content.Contains(":alert()")) << "The JavaScript URL is unsafe and should have been stripped; " "instead: " - << sanitized_content.Utf8().data(); + << sanitized_content.Utf8(); } TEST(UnsafeSVGAttributeSanitizationTest, @@ -136,11 +136,11 @@ TEST(UnsafeSVGAttributeSanitizationTest, EXPECT_TRUE(sanitized_content.Contains("</a>")) << "We should have pasted *something*; the document is: " - << sanitized_content.Utf8().data(); + << sanitized_content.Utf8(); EXPECT_FALSE(sanitized_content.Contains(":alert()")) << "The JavaScript URL is unsafe and should have been stripped; " "instead: " - << sanitized_content.Utf8().data(); + << sanitized_content.Utf8(); } TEST(UnsafeSVGAttributeSanitizationTest, @@ -157,11 +157,11 @@ TEST(UnsafeSVGAttributeSanitizationTest, EXPECT_TRUE(sanitized_content.Contains("</a>")) << "We should have pasted *something*; the document is: " - << sanitized_content.Utf8().data(); + << sanitized_content.Utf8(); EXPECT_FALSE(sanitized_content.Contains(":alert()")) << "The JavaScript URL is unsafe and should have been stripped; " "instead: " - << sanitized_content.Utf8().data(); + << sanitized_content.Utf8(); } TEST(UnsafeSVGAttributeSanitizationTest, @@ -177,11 +177,11 @@ TEST(UnsafeSVGAttributeSanitizationTest, EXPECT_TRUE(sanitized_content.Contains("</a>")) << "We should have pasted *something*; the document is: " - << sanitized_content.Utf8().data(); + << sanitized_content.Utf8(); EXPECT_FALSE(sanitized_content.Contains(":alert()")) << "The JavaScript URL is unsafe and should have been stripped; " "instead: " - << sanitized_content.Utf8().data(); + << sanitized_content.Utf8(); } TEST( @@ -199,11 +199,11 @@ TEST( EXPECT_TRUE(sanitized_content.Contains("</a>")) << "We should have pasted *something*; the document is: " - << sanitized_content.Utf8().data(); + << sanitized_content.Utf8(); EXPECT_FALSE(sanitized_content.Contains(":alert()")) << "The JavaScript URL is unsafe and should have been stripped; " "instead: " - << sanitized_content.Utf8().data(); + << sanitized_content.Utf8(); } // Other sanitization integration tests are web tests that use @@ -226,11 +226,11 @@ TEST(UnsafeSVGAttributeSanitizationTest, EXPECT_TRUE(sanitized_content.Contains("<a href=\"https://www.goo")) << "We should have pasted *something*; the document is: " - << sanitized_content.Utf8().data(); + << sanitized_content.Utf8(); EXPECT_FALSE(sanitized_content.Contains(":alert()")) << "The JavaScript URL is unsafe and should have been stripped; " "instead: " - << sanitized_content.Utf8().data(); + << sanitized_content.Utf8(); } TEST( @@ -252,11 +252,11 @@ TEST( EXPECT_TRUE(sanitized_content.Contains("<a xlink:href=\"https://www.goo")) << "We should have pasted *something*; the document is: " - << sanitized_content.Utf8().data(); + << sanitized_content.Utf8(); EXPECT_FALSE(sanitized_content.Contains(":alert()")) << "The JavaScript URL is unsafe and should have been stripped; " "instead: " - << sanitized_content.Utf8().data(); + << sanitized_content.Utf8(); } // Unit tests |