/* * Copyright (C) 2011, 2013 Google Inc. All rights reserved. * Copyright (C) 2011-2017 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: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 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. * * Neither the name of Google Inc. nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "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 THE COPYRIGHT * OWNER 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 "config.h" #include "TextTrackCue.h" #if ENABLE(VIDEO_TRACK) #include "CSSPropertyNames.h" #include "CSSValueKeywords.h" #include "Event.h" #include "Logging.h" #include "NodeTraversal.h" #include "Text.h" #include "TextTrack.h" #include "TextTrackCueList.h" #include "VTTCue.h" #include "VTTRegionList.h" #include namespace WebCore { const AtomicString& TextTrackCue::cueShadowPseudoId() { static NeverDestroyed cue("cue", AtomicString::ConstructFromLiteral); return cue; } TextTrackCue::TextTrackCue(ScriptExecutionContext& context, const MediaTime& start, const MediaTime& end) : m_startTime(start) , m_endTime(end) , m_scriptExecutionContext(context) , m_isActive(false) , m_pauseOnExit(false) { ASSERT(m_scriptExecutionContext.isDocument()); } void TextTrackCue::willChange() { if (++m_processingCueChanges > 1) return; if (m_track) m_track->cueWillChange(this); } void TextTrackCue::didChange() { ASSERT(m_processingCueChanges); if (--m_processingCueChanges) return; if (m_track) m_track->cueDidChange(this); } TextTrack* TextTrackCue::track() const { return m_track; } void TextTrackCue::setTrack(TextTrack* track) { m_track = track; } void TextTrackCue::setId(const String& id) { if (m_id == id) return; willChange(); m_id = id; didChange(); } void TextTrackCue::setStartTime(double value) { // TODO(93143): Add spec-compliant behavior for negative time values. if (m_startTime.toDouble() == value || value < 0) return; setStartTime(MediaTime::createWithDouble(value)); } void TextTrackCue::setStartTime(const MediaTime& value) { willChange(); m_startTime = value; didChange(); } void TextTrackCue::setEndTime(double value) { // TODO(93143): Add spec-compliant behavior for negative time values. if (m_endTime.toDouble() == value || value < 0) return; setEndTime(MediaTime::createWithDouble(value)); } void TextTrackCue::setEndTime(const MediaTime& value) { willChange(); m_endTime = value; didChange(); } void TextTrackCue::setPauseOnExit(bool value) { if (m_pauseOnExit == value) return; m_pauseOnExit = value; } bool TextTrackCue::dispatchEvent(Event& event) { // When a TextTrack's mode is disabled: no cues are active, no events fired. if (!track() || track()->mode() == TextTrack::Mode::Disabled) return false; return EventTarget::dispatchEvent(event); } bool TextTrackCue::isActive() { return m_isActive && track() && track()->mode() != TextTrack::Mode::Disabled; } void TextTrackCue::setIsActive(bool active) { m_isActive = active; } bool TextTrackCue::isOrderedBefore(const TextTrackCue* other) const { return startMediaTime() < other->startMediaTime() || (startMediaTime() == other->startMediaTime() && endMediaTime() > other->endMediaTime()); } bool TextTrackCue::cueContentsMatch(const TextTrackCue& cue) const { if (cueType() != cue.cueType()) return false; if (id() != cue.id()) return false; return true; } bool TextTrackCue::isEqual(const TextTrackCue& cue, TextTrackCue::CueMatchRules match) const { if (cueType() != cue.cueType()) return false; if (match != IgnoreDuration && endMediaTime() != cue.endMediaTime()) return false; if (!hasEquivalentStartTime(cue)) return false; if (!cueContentsMatch(cue)) return false; return true; } bool TextTrackCue::hasEquivalentStartTime(const TextTrackCue& cue) const { MediaTime startTimeVariance = MediaTime::zeroTime(); if (track()) startTimeVariance = track()->startTimeVariance(); else if (cue.track()) startTimeVariance = cue.track()->startTimeVariance(); return abs(abs(startMediaTime()) - abs(cue.startMediaTime())) <= startTimeVariance; } bool TextTrackCue::doesExtendCue(const TextTrackCue& cue) const { if (!cueContentsMatch(cue)) return false; if (endMediaTime() != cue.startMediaTime()) return false; return true; } } // namespace WebCore #endif