Bug 1374875 - Use simpler mutation observer than nsRange for media elements. r=cpearce

MozReview-Commit-ID: FVPdHC6tBXg
This commit is contained in:
Mats Palmgren 2017-06-23 02:03:08 +02:00
Родитель 7565237b48
Коммит c3f48d9dd2
2 изменённых файлов: 47 добавлений и 40 удалений

Просмотреть файл

@ -1403,7 +1403,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(HTMLMediaElement, nsGenericHTM
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSrcMediaSource)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSrcStream)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSrcAttrStream)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSourcePointer)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mLoadBlockedDoc)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSourceLoadCandidate)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mAudioChannelWrapper)
@ -1422,6 +1421,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(HTMLMediaElement, nsGenericHTM
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(HTMLMediaElement, nsGenericHTMLElement)
tmp->RemoveMutationObserver(tmp);
if (tmp->mSrcStream) {
// Need to EndMediaStreamPlayback to clear mSrcStream and make sure everything
// gets unhooked correctly.
@ -1430,7 +1430,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(HTMLMediaElement, nsGenericHTMLE
NS_IMPL_CYCLE_COLLECTION_UNLINK(mSrcAttrStream)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mMediaSource)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mSrcMediaSource)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mSourcePointer)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mLoadBlockedDoc)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mSourceLoadCandidate)
if (tmp->mAudioChannelWrapper) {
@ -1463,6 +1462,35 @@ NS_IMPL_BOOL_ATTR(HTMLMediaElement, Loop, loop)
NS_IMPL_BOOL_ATTR(HTMLMediaElement, DefaultMuted, muted)
NS_IMPL_ENUM_ATTR_DEFAULT_VALUE(HTMLMediaElement, Preload, preload, nullptr)
void
HTMLMediaElement::ContentInserted(nsIDocument* aDocument,
nsIContent* aContainer,
nsIContent* aChild,
int32_t aIndexInContainer)
{
if (aContainer != this ||
aIndexInContainer >= int32_t(mSourcePointer) ||
aIndexInContainer < 0) {
return;
}
++mSourcePointer;
}
void
HTMLMediaElement::ContentRemoved(nsIDocument* aDocument,
nsIContent* aContainer,
nsIContent* aChild,
int32_t aIndexInContainer,
nsIContent* aPreviousSibling)
{
if (aContainer != this ||
aIndexInContainer >= int32_t(mSourcePointer) ||
aIndexInContainer < 0) {
return;
}
--mSourcePointer;
}
NS_IMETHODIMP_(bool)
HTMLMediaElement::IsVideo()
{
@ -1741,7 +1769,7 @@ void HTMLMediaElement::AbortExistingLoads()
mIsEncrypted = false;
mPendingEncryptedInitData.Reset();
mWaitingForKey = NOT_WAITING_FOR_KEY;
mSourcePointer = nullptr;
mSourcePointer = 0;
mTags = nullptr;
@ -2249,6 +2277,8 @@ void HTMLMediaElement::LoadFromSourceChildren()
parentDoc->FlushPendingNotifications(FlushType::Layout);
}
AddMutationObserverUnlessExists(this);
while (true) {
nsIContent* child = GetNextSource();
if (!child) {
@ -3708,6 +3738,7 @@ HTMLMediaElement::HTMLMediaElement(already_AddRefed<mozilla::dom::NodeInfo>& aNo
mSrcStreamPausedCurrentTime(-1),
mShutdownObserver(new ShutdownObserver),
mCurrentLoadID(0),
mSourcePointer(0),
mNetworkState(nsIDOMHTMLMediaElement::NETWORK_EMPTY),
mReadyState(nsIDOMHTMLMediaElement::HAVE_NOTHING, "HTMLMediaElement::mReadyState"),
mLoadWaitStatus(NOT_WAITING),
@ -6356,46 +6387,16 @@ void HTMLMediaElement::NotifyAddedSource()
nsIContent* HTMLMediaElement::GetNextSource()
{
nsCOMPtr<nsIDOMNode> thisDomNode = do_QueryObject(this);
mSourceLoadCandidate = nullptr;
nsresult rv = NS_OK;
if (!mSourcePointer) {
// First time this has been run, create a selection to cover children.
mSourcePointer = new nsRange(this);
// If this media element is removed from the DOM, don't gravitate the
// range up to its ancestor, leave it attached to the media element.
mSourcePointer->SetEnableGravitationOnElementRemoval(false);
rv = mSourcePointer->SelectNodeContents(thisDomNode);
if (NS_FAILED(rv)) return nullptr;
rv = mSourcePointer->Collapse(true);
if (NS_FAILED(rv)) return nullptr;
}
while (true) {
#ifdef DEBUG
nsCOMPtr<nsIDOMNode> startContainer;
rv = mSourcePointer->GetStartContainer(getter_AddRefs(startContainer));
if (NS_FAILED(rv)) return nullptr;
NS_ASSERTION(startContainer == thisDomNode,
"Should only iterate over direct children");
#endif
int32_t startOffset = 0;
rv = mSourcePointer->GetStartOffset(&startOffset);
NS_ENSURE_SUCCESS(rv, nullptr);
if (uint32_t(startOffset) == GetChildCount())
if (mSourcePointer >= GetChildCount())
return nullptr; // No more children.
// Advance the range to the next child.
rv = mSourcePointer->SetStart(thisDomNode, startOffset + 1);
NS_ENSURE_SUCCESS(rv, nullptr);
nsIContent* child = GetChildAt(mSourcePointer);
nsIContent* child = GetChildAt(startOffset);
// Advance to the next child.
++mSourcePointer;
// If child is a <source> element, it is the next candidate.
if (child && child->IsHTMLElement(nsGkAtoms::source)) {

Просмотреть файл

@ -23,6 +23,7 @@
#include "mozilla/StateWatching.h"
#include "nsGkAtoms.h"
#include "PrincipalChangeObserver.h"
#include "nsStubMutationObserver.h"
// X.h on Linux #defines CurrentTime as 0L, so we have to #undef it here.
#ifdef CurrentTime
@ -84,7 +85,8 @@ class HTMLMediaElement : public nsGenericHTMLElement,
public nsIDOMHTMLMediaElement,
public MediaDecoderOwner,
public PrincipalChangeObserver<DOMMediaStream>,
public SupportsWeakPtr<HTMLMediaElement>
public SupportsWeakPtr<HTMLMediaElement>,
public nsStubMutationObserver
{
public:
typedef mozilla::TimeStamp TimeStamp;
@ -96,6 +98,8 @@ public:
typedef mozilla::MetadataTags MetadataTags;
MOZ_DECLARE_WEAKREFERENCE_TYPENAME(HTMLMediaElement)
NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED
NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED
CORSMode GetCORSMode() {
return mCORSMode;
@ -1378,8 +1382,10 @@ protected:
uint32_t mCurrentLoadID;
// Points to the child source elements, used to iterate through the children
// when selecting a resource to load.
RefPtr<nsRange> mSourcePointer;
// when selecting a resource to load. This is the index of the child element
// that is the current 'candidate' in:
// https://html.spec.whatwg.org/multipage/media.html#concept-media-load-algorithm
uint32_t mSourcePointer;
// Points to the document whose load we're blocking. This is the document
// we're bound to when loading starts.