| Index: Source/core/html/track/TextTrackCueList.cpp
|
| diff --git a/Source/core/html/track/TextTrackCueList.cpp b/Source/core/html/track/TextTrackCueList.cpp
|
| index bb23faffddc60b7993baed665ab706571e53484d..40052b9b4aef97ea42f7f0571ba537dd3492b12b 100644
|
| --- a/Source/core/html/track/TextTrackCueList.cpp
|
| +++ b/Source/core/html/track/TextTrackCueList.cpp
|
| @@ -24,9 +24,10 @@
|
| */
|
|
|
| #include "config.h"
|
| -
|
| #include "core/html/track/TextTrackCueList.h"
|
|
|
| +#include "wtf/StdLibExtras.h"
|
| +
|
| namespace blink {
|
|
|
| TextTrackCueList::TextTrackCueList()
|
| @@ -80,31 +81,33 @@ bool TextTrackCueList::add(PassRefPtrWillBeRawPtr<TextTrackCue> cue)
|
| ASSERT(cue->startTime() >= 0);
|
| ASSERT(cue->endTime() >= 0);
|
|
|
| - return add(cue, 0, m_list.size());
|
| + // Maintain text track cue order:
|
| + // https://html.spec.whatwg.org/#text-track-cue-order
|
| + size_t index = findInsertionIndex(cue.get());
|
| +
|
| + // FIXME: The cue should not exist in the list in the first place.
|
| + if (!m_list.isEmpty() && (index > 0) && (m_list[index - 1].get() == cue.get()))
|
| + return false;
|
| +
|
| + m_list.insert(index, cue);
|
| + invalidateCueIndexes(index);
|
| + return true;
|
| }
|
|
|
| -bool TextTrackCueList::add(PassRefPtrWillBeRawPtr<TextTrackCue> prpCue, size_t start, size_t end)
|
| +static bool cueIsBefore(const TextTrackCue* cue, PassRefPtrWillBeRawPtr<TextTrackCue> otherCue)
|
| {
|
| - ASSERT_WITH_SECURITY_IMPLICATION(start <= m_list.size());
|
| - ASSERT_WITH_SECURITY_IMPLICATION(end <= m_list.size());
|
| -
|
| - // Maintain text track cue order:
|
| - // http://www.whatwg.org/specs/web-apps/current-work/#text-track-cue-order
|
| - RefPtrWillBeRawPtr<TextTrackCue> cue = prpCue;
|
| - if (start == end) {
|
| - if (!m_list.isEmpty() && (start > 0) && (m_list[start - 1].get() == cue.get()))
|
| - return false;
|
| -
|
| - m_list.insert(start, cue);
|
| - invalidateCueIndexes(start);
|
| + if (cue->startTime() < otherCue->startTime())
|
| return true;
|
| - }
|
|
|
| - size_t index = (start + end) / 2;
|
| - if (cue->startTime() < m_list[index]->startTime() || (cue->startTime() == m_list[index]->startTime() && cue->endTime() > m_list[index]->endTime()))
|
| - return add(cue.release(), start, index);
|
| + return cue->startTime() == otherCue->startTime() && cue->endTime() > otherCue->endTime();
|
| +}
|
|
|
| - return add(cue.release(), index + 1, end);
|
| +size_t TextTrackCueList::findInsertionIndex(const TextTrackCue* cueToInsert) const
|
| +{
|
| + auto it = std::upper_bound(m_list.begin(), m_list.end(), cueToInsert, cueIsBefore);
|
| + size_t index = safeCast<size_t>(it - m_list.begin());
|
| + ASSERT_WITH_SECURITY_IMPLICATION(index <= m_list.size());
|
| + return index;
|
| }
|
|
|
| bool TextTrackCueList::remove(TextTrackCue* cue)
|
| @@ -114,21 +117,25 @@ bool TextTrackCueList::remove(TextTrackCue* cue)
|
| return false;
|
|
|
| m_list.remove(index);
|
| + // FIXME: While removing a cue does not invalidate the cue order, it does
|
| + // make it more difficult to maintain the invariant, so should probably
|
| + // just invalidate here as well.
|
| return true;
|
| }
|
|
|
| -bool TextTrackCueList::updateCueIndex(TextTrackCue* cue)
|
| +void TextTrackCueList::updateCueIndex(TextTrackCue* cue)
|
| {
|
| - size_t index = m_list.find(cue);
|
| - if (index == kNotFound)
|
| - return false;
|
| + if (!remove(cue))
|
| + return;
|
|
|
| cue->setIsActive(false);
|
| cue->removeDisplayTree();
|
|
|
| - m_list.remove(index);
|
| -
|
| - return add(cue);
|
| + // FIXME: If moving the cue such that its index in list increases, then
|
| + // what happens with the cached index on cues in the range [oldIndex,
|
| + // newIndex)? (Some of the indices will be "safe", but there'll be a risk
|
| + // that the lazy update via cueIndex() yields duplicates/incorrect order.)
|
| + add(cue);
|
| }
|
|
|
| void TextTrackCueList::clear()
|
| @@ -138,6 +145,7 @@ void TextTrackCueList::clear()
|
|
|
| void TextTrackCueList::invalidateCueIndexes(size_t start)
|
| {
|
| + // FIXME: When iterating cues we could as well update their cached indices too.
|
| for (size_t i = start; i < m_list.size(); ++i)
|
| m_list[i]->invalidateCueIndex();
|
| }
|
|
|