blob: 64d5936b9bd93cf130d61183e81da37209abcd95 [file] [log] [blame]
/*
* Copyright (C) 2011 Google 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 COMPUTER, 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 COMPUTER, 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/html/track/text_track_cue_list.h"
#include <algorithm>
#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h"
namespace blink {
TextTrackCueList::TextTrackCueList() : first_invalid_index_(0) {}
wtf_size_t TextTrackCueList::length() const {
return list_.size();
}
TextTrackCue* TextTrackCueList::AnonymousIndexedGetter(wtf_size_t index) const {
if (index < list_.size())
return list_[index].Get();
return nullptr;
}
TextTrackCue* TextTrackCueList::getCueById(const AtomicString& id) const {
for (const auto& cue : list_) {
if (cue->id() == id)
return cue.Get();
}
return nullptr;
}
void TextTrackCueList::CollectActiveCues(TextTrackCueList& active_cues) const {
active_cues.Clear();
for (auto& cue : list_) {
if (cue->IsActive())
active_cues.Add(cue);
}
}
bool TextTrackCueList::Add(TextTrackCue* cue) {
// Maintain text track cue order:
// https://html.spec.whatwg.org/#text-track-cue-order
wtf_size_t index = FindInsertionIndex(cue);
// FIXME: The cue should not exist in the list in the first place.
if (!list_.IsEmpty() && (index > 0) && (list_[index - 1].Get() == cue))
return false;
list_.insert(index, cue);
InvalidateCueIndex(index);
return true;
}
static bool CueIsBefore(const TextTrackCue* cue, TextTrackCue* other_cue) {
if (cue->startTime() < other_cue->startTime())
return true;
return cue->startTime() == other_cue->startTime() &&
cue->endTime() > other_cue->endTime();
}
wtf_size_t TextTrackCueList::FindInsertionIndex(
const TextTrackCue* cue_to_insert) const {
auto* it =
std::upper_bound(list_.begin(), list_.end(), cue_to_insert, CueIsBefore);
wtf_size_t index = SafeCast<wtf_size_t>(it - list_.begin());
SECURITY_DCHECK(index <= list_.size());
return index;
}
bool TextTrackCueList::Remove(TextTrackCue* cue) {
wtf_size_t index = list_.Find(cue);
if (index == kNotFound)
return false;
list_.EraseAt(index);
InvalidateCueIndex(index);
cue->InvalidateCueIndex();
return true;
}
void TextTrackCueList::RemoveAll() {
if (list_.IsEmpty())
return;
first_invalid_index_ = 0;
for (auto& cue : list_)
cue->InvalidateCueIndex();
Clear();
}
void TextTrackCueList::UpdateCueIndex(TextTrackCue* cue) {
if (!Remove(cue))
return;
Add(cue);
}
void TextTrackCueList::Clear() {
list_.clear();
}
void TextTrackCueList::InvalidateCueIndex(wtf_size_t index) {
// Store the smallest (first) index that we know has a cue that does not
// meet the criteria:
// cueIndex(list[index-1]) + 1 == cueIndex(list[index]) [index > 0]
// This is a stronger requirement than we need, but it's easier to maintain.
// We can then check if a cue's index is valid by comparing it with
// |first_invalid_index_| - if it's strictly less it is valid.
first_invalid_index_ = std::min(first_invalid_index_, index);
}
void TextTrackCueList::ValidateCueIndexes() {
// Compute new index values for the cues starting at
// |first_invalid_index_|. If said index is beyond the end of the list, no
// cues will need to be updated.
for (wtf_size_t i = first_invalid_index_; i < list_.size(); ++i)
list_[i]->UpdateCueIndex(i);
first_invalid_index_ = list_.size();
}
void TextTrackCueList::Trace(blink::Visitor* visitor) {
visitor->Trace(list_);
ScriptWrappable::Trace(visitor);
}
} // namespace blink