예제 #1
0
void DataTransferItemList::GenerateFiles(FileList* aFiles,
                                         nsIPrincipal* aFilesPrincipal) {
  MOZ_ASSERT(aFiles);
  MOZ_ASSERT(aFilesPrincipal);

  // For non-system principals, the Files list should be empty if the
  // DataTransfer is protected.
  if (!nsContentUtils::IsSystemPrincipal(aFilesPrincipal) &&
      mDataTransfer->IsProtected()) {
    return;
  }

  uint32_t count = Length();
  for (uint32_t i = 0; i < count; i++) {
    bool found;
    RefPtr<DataTransferItem> item = IndexedGetter(i, found);
    MOZ_ASSERT(found);

    if (item->Kind() == DataTransferItem::KIND_FILE) {
      RefPtr<File> file = item->GetAsFile(*aFilesPrincipal, IgnoreErrors());
      if (NS_WARN_IF(!file)) {
        continue;
      }
      aFiles->Append(file);
    }
  }
}
예제 #2
0
NS_IMETHODIMP 
nsDOMWindowList::Item(uint32_t aIndex, mozIDOMWindowProxy** aReturn)
{
  nsCOMPtr<nsPIDOMWindowOuter> window = IndexedGetter(aIndex);
  window.forget(aReturn);
  return NS_OK;
}
예제 #3
0
void
VideoTrackList::RemoveTrack(const RefPtr<MediaTrack>& aTrack)
{
  // we need to find the video track before |MediaTrackList::RemoveTrack|. Or
  // mSelectedIndex will not be valid. The check of mSelectedIndex == -1
  // need to be done after RemoveTrack. Also the call of
  // |MediaTrackList::RemoveTrack| is necessary even when mSelectedIndex = -1.
  bool found;
  VideoTrack* selectedVideoTrack = IndexedGetter(mSelectedIndex, found);
  MediaTrackList::RemoveTrack(aTrack);
  if (mSelectedIndex == -1) {
    // There was no selected track and we don't select another track on removal.
    return;
  }
  MOZ_ASSERT(found, "When mSelectedIndex is set it should point to a track");
  MOZ_ASSERT(selectedVideoTrack, "The mSelectedIndex should be set to video track only");

  // Let the caller of RemoveTrack deal with choosing the new selected track if
  // it removes the currently-selected track.
  if (aTrack == selectedVideoTrack) {
    mSelectedIndex = -1;
    return;
  }

  // The removed track was not the selected track and there is a
  // currently-selected video track. We need to find the new location of the
  // selected track.
  for (size_t ix = 0; ix < mTracks.Length(); ix++) {
    if (mTracks[ix] == selectedVideoTrack) {
      mSelectedIndex = ix;
      return;
    }
  }
}
예제 #4
0
void DOMSVGStringList::GetItem(uint32_t aIndex, nsAString& aRetval,
                               ErrorResult& aRv) {
  bool found;
  IndexedGetter(aIndex, found, aRetval);
  if (!found) {
    aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
  }
}
NS_IMETHODIMP 
nsDOMWindowList::Item(uint32_t aIndex, nsIDOMWindow** aReturn)
{
  bool found;
  nsCOMPtr<nsIDOMWindow> window = IndexedGetter(aIndex, found);
  window.forget(aReturn);
  return NS_OK;
}
예제 #6
0
void DataTransferItemList::ClearDataHelper(DataTransferItem* aItem,
                                           uint32_t aIndexHint,
                                           uint32_t aMozOffsetHint,
                                           nsIPrincipal& aSubjectPrincipal,
                                           ErrorResult& aRv) {
  MOZ_ASSERT(aItem);
  if (NS_WARN_IF(mDataTransfer->IsReadOnly())) {
    return;
  }

  if (aItem->Principal() && !aSubjectPrincipal.Subsumes(aItem->Principal())) {
    aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
    return;
  }

  // Check if the aIndexHint is actually the index, and then remove the item
  // from aItems
  bool found;
  if (IndexedGetter(aIndexHint, found) == aItem) {
    mItems.RemoveElementAt(aIndexHint);
  } else {
    mItems.RemoveElement(aItem);
  }

  // Check if the aMozIndexHint and aMozOffsetHint are actually the index and
  // offset, and then remove them from mIndexedItems
  MOZ_ASSERT(aItem->Index() < mIndexedItems.Length());
  nsTArray<RefPtr<DataTransferItem>>& items = mIndexedItems[aItem->Index()];
  if (aMozOffsetHint < items.Length() && aItem == items[aMozOffsetHint]) {
    items.RemoveElementAt(aMozOffsetHint);
  } else {
    items.RemoveElement(aItem);
  }

  mDataTransfer->TypesListMayHaveChanged();

  // Check if we should remove the index. We never remove index 0.
  if (items.Length() == 0 && aItem->Index() != 0) {
    mIndexedItems.RemoveElementAt(aItem->Index());

    // Update the index of every element which has now been shifted
    for (uint32_t i = aItem->Index(); i < mIndexedItems.Length(); i++) {
      nsTArray<RefPtr<DataTransferItem>>& items = mIndexedItems[i];
      for (uint32_t j = 0; j < items.Length(); j++) {
        items[j]->SetIndex(i);
      }
    }
  }

  // Give the removed item the invalid index
  aItem->SetIndex(-1);

  if (aItem->Kind() == DataTransferItem::KIND_FILE) {
    RegenerateFiles();
  }
}
예제 #7
0
already_AddRefed<nsISVGPoint>
DOMSVGPointList::GetItem(uint32_t index, ErrorResult& error)
{
  bool found;
  RefPtr<nsISVGPoint> item = IndexedGetter(index, found, error);
  if (!found) {
    error.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
  }
  return item.forget();
}
예제 #8
0
void
TextTrackManager::PopulatePendingList()
{
  uint32_t len = mTextTracks->Length();
  bool dummy;
  for (uint32_t index = 0; index < len; ++index) {
    TextTrack* ttrack = mTextTracks->IndexedGetter(index, dummy);
    if (ttrack && ttrack->Mode() != TextTrackMode::Disabled &&
        ttrack->ReadyState() == TextTrackReadyState::Loading) {
      mPendingTextTracks->AddTextTrack(ttrack,
                                       CompareTextTracks(mMediaElement));
    }
  }
}
예제 #9
0
// https://html.spec.whatwg.org/multipage/embedded-content.html#time-marches-on
void
TextTrackManager::TimeMarchesOn()
{
  NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
  WEBVTT_LOG("TimeMarchesOn");
  mTimeMarchesOnDispatched = false;

  // Early return if we don't have any TextTracks or shutting down.
  if (!mTextTracks || mTextTracks->Length() == 0 || mShutdown) {
    return;
  }

  nsISupports* parentObject =
    mMediaElement->OwnerDoc()->GetParentObject();
  if (NS_WARN_IF(!parentObject)) {
    return;
  }
  nsCOMPtr<nsPIDOMWindowInner> window = do_QueryInterface(parentObject);

  if (mMediaElement &&
      (!(mMediaElement->GetPlayedOrSeeked()) || mMediaElement->Seeking())) {
    WEBVTT_LOG("TimeMarchesOn seeking or post return");
    return;
  }

  // Step 3.
  double currentPlaybackTime = mMediaElement->CurrentTime();
  bool hasNormalPlayback = !mHasSeeked;
  mHasSeeked = false;
  WEBVTT_LOG("TimeMarchesOn mLastTimeMarchesOnCalled %lf currentPlaybackTime %lf hasNormalPlayback %d"
      , mLastTimeMarchesOnCalled, currentPlaybackTime, hasNormalPlayback);

  // Step 1, 2.
  RefPtr<TextTrackCueList> currentCues =
    new TextTrackCueList(window);
  RefPtr<TextTrackCueList> otherCues =
    new TextTrackCueList(window);
  bool dummy;
  for (uint32_t index = 0; index < mTextTracks->Length(); ++index) {
    TextTrack* ttrack = mTextTracks->IndexedGetter(index, dummy);
    if (ttrack && dummy) {
      // TODO: call GetCueListByTimeInterval on mNewCues?
      ttrack->UpdateActiveCueList();
      TextTrackCueList* activeCueList = ttrack->GetActiveCues();
      if (activeCueList) {
        for (uint32_t i = 0; i < activeCueList->Length(); ++i) {
          currentCues->AddCue(*((*activeCueList)[i]));
        }
      }
    }
  }
  WEBVTT_LOGV("TimeMarchesOn currentCues %d", currentCues->Length());
  // Populate otherCues with 'non-active" cues.
  if (hasNormalPlayback) {
    if (currentPlaybackTime < mLastTimeMarchesOnCalled) {
      // TODO: Add log and find the root cause why the
      // playback position goes backward.
      mLastTimeMarchesOnCalled = currentPlaybackTime;
    }
    media::Interval<double> interval(mLastTimeMarchesOnCalled,
                                     currentPlaybackTime);
    otherCues = mNewCues->GetCueListByTimeInterval(interval);;
  } else {
    // Seek case. Put the mLastActiveCues into otherCues.
    otherCues = mLastActiveCues;
  }
  for (uint32_t i = 0; i < currentCues->Length(); ++i) {
    TextTrackCue* cue = (*currentCues)[i];
    otherCues->RemoveCue(*cue);
  }
  WEBVTT_LOGV("TimeMarchesOn otherCues %d", otherCues->Length());
  // Step 4.
  RefPtr<TextTrackCueList> missedCues = new TextTrackCueList(window);
  if (hasNormalPlayback) {
    for (uint32_t i = 0; i < otherCues->Length(); ++i) {
      TextTrackCue* cue = (*otherCues)[i];
      if (cue->StartTime() >= mLastTimeMarchesOnCalled &&
          cue->EndTime() <= currentPlaybackTime) {
        missedCues->AddCue(*cue);
      }
    }
  }
  WEBVTT_LOGV("TimeMarchesOn missedCues %d", missedCues->Length());
  // Step 5. Empty now.
  // TODO: Step 6: fire timeupdate?

  // Step 7. Abort steps if condition 1, 2, 3 are satisfied.
  // 1. All of the cues in current cues have their active flag set.
  // 2. None of the cues in other cues have their active flag set.
  // 3. Missed cues is empty.
  bool c1 = true;
  for (uint32_t i = 0; i < currentCues->Length(); ++i) {
    if (!(*currentCues)[i]->GetActive()) {
      c1 = false;
      break;
    }
  }
  bool c2 = true;
  for (uint32_t i = 0; i < otherCues->Length(); ++i) {
    if ((*otherCues)[i]->GetActive()) {
      c2 = false;
      break;
    }
  }
  bool c3 = (missedCues->Length() == 0);
  if (c1 && c2 && c3) {
    mLastTimeMarchesOnCalled = currentPlaybackTime;
    WEBVTT_LOG("TimeMarchesOn step 7 return, mLastTimeMarchesOnCalled %lf", mLastTimeMarchesOnCalled);
    return;
  }

  // Step 8. Respect PauseOnExit flag if not seek.
  if (hasNormalPlayback) {
    for (uint32_t i = 0; i < otherCues->Length(); ++i) {
      TextTrackCue* cue = (*otherCues)[i];
      if (cue && cue->PauseOnExit() && cue->GetActive()) {
        WEBVTT_LOG("TimeMarchesOn pause the MediaElement");
        mMediaElement->Pause();
        break;
      }
    }
    for (uint32_t i = 0; i < missedCues->Length(); ++i) {
      TextTrackCue* cue = (*missedCues)[i];
      if (cue && cue->PauseOnExit()) {
        WEBVTT_LOG("TimeMarchesOn pause the MediaElement");
        mMediaElement->Pause();
        break;
      }
    }
  }

  // Step 15.
  // Sort text tracks in the same order as the text tracks appear
  // in the media element's list of text tracks, and remove
  // duplicates.
  TextTrackListInternal affectedTracks;
  // Step 13, 14.
  nsTArray<RefPtr<SimpleTextTrackEvent>> eventList;
  // Step 9, 10.
  // For each text track cue in missed cues, prepare an event named
  // enter for the TextTrackCue object with the cue start time.
  for (uint32_t i = 0; i < missedCues->Length(); ++i) {
    TextTrackCue* cue = (*missedCues)[i];
    if (cue) {
      SimpleTextTrackEvent* event =
        new SimpleTextTrackEvent(NS_LITERAL_STRING("enter"),
                                 cue->StartTime(), cue->GetTrack(),
                                 cue);
      eventList.InsertElementSorted(event,
        CompareSimpleTextTrackEvents(mMediaElement));
      affectedTracks.AddTextTrack(cue->GetTrack(), CompareTextTracks(mMediaElement));
    }
  }

  // Step 11, 17.
  for (uint32_t i = 0; i < otherCues->Length(); ++i) {
    TextTrackCue* cue = (*otherCues)[i];
    if (cue->GetActive() || missedCues->IsCueExist(cue)) {
      double time = cue->StartTime() > cue->EndTime() ? cue->StartTime()
                                                      : cue->EndTime();
      SimpleTextTrackEvent* event =
        new SimpleTextTrackEvent(NS_LITERAL_STRING("exit"), time,
                                 cue->GetTrack(), cue);
      eventList.InsertElementSorted(event,
        CompareSimpleTextTrackEvents(mMediaElement));
      affectedTracks.AddTextTrack(cue->GetTrack(), CompareTextTracks(mMediaElement));
    }
    cue->SetActive(false);
  }

  // Step 12, 17.
  for (uint32_t i = 0; i < currentCues->Length(); ++i) {
    TextTrackCue* cue = (*currentCues)[i];
    if (!cue->GetActive()) {
      SimpleTextTrackEvent* event =
        new SimpleTextTrackEvent(NS_LITERAL_STRING("enter"),
                                 cue->StartTime(), cue->GetTrack(),
                                 cue);
      eventList.InsertElementSorted(event,
        CompareSimpleTextTrackEvents(mMediaElement));
      affectedTracks.AddTextTrack(cue->GetTrack(), CompareTextTracks(mMediaElement));
    }
    cue->SetActive(true);
  }

  // Fire the eventList
  for (uint32_t i = 0; i < eventList.Length(); ++i) {
    NS_DispatchToMainThread(eventList[i].forget());
  }

  // Step 16.
  for (uint32_t i = 0; i < affectedTracks.Length(); ++i) {
    TextTrack* ttrack = affectedTracks[i];
    if (ttrack) {
      ttrack->DispatchAsyncTrustedEvent(NS_LITERAL_STRING("cuechange"));
      HTMLTrackElement* trackElement = ttrack->GetTrackElement();
      if (trackElement) {
        trackElement->DispatchTrackRunnable(NS_LITERAL_STRING("cuechange"));
      }
    }
  }

  mLastTimeMarchesOnCalled = currentPlaybackTime;
  mLastActiveCues = currentCues;

  // Step 18.
  UpdateCueDisplay();
}