HTMLAudioElement.cpp (3487B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #include "mozilla/dom/HTMLAudioElement.h" 8 9 #include <algorithm> 10 11 #include "AudioSampleFormat.h" 12 #include "AudioStream.h" 13 #include "jsfriendapi.h" 14 #include "mozilla/dom/Document.h" 15 #include "mozilla/dom/HTMLAudioElementBinding.h" 16 #include "mozilla/dom/TimeRanges.h" 17 #include "nsComponentManagerUtils.h" 18 #include "nsContentUtils.h" 19 #include "nsError.h" 20 #include "nsGenericHTMLElement.h" 21 #include "nsGkAtoms.h" 22 #include "nsIHttpChannel.h" 23 #include "nsJSUtils.h" 24 25 nsGenericHTMLElement* NS_NewHTMLAudioElement( 26 already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo, 27 mozilla::dom::FromParser aFromParser) { 28 RefPtr<mozilla::dom::NodeInfo> nodeInfo(aNodeInfo); 29 auto* nim = nodeInfo->NodeInfoManager(); 30 mozilla::dom::HTMLAudioElement* element = 31 new (nim) mozilla::dom::HTMLAudioElement(nodeInfo.forget()); 32 element->Init(); 33 return element; 34 } 35 36 namespace mozilla::dom { 37 38 nsresult HTMLAudioElement::Clone(mozilla::dom::NodeInfo* aNodeInfo, 39 nsINode** aResult) const { 40 *aResult = nullptr; 41 RefPtr<mozilla::dom::NodeInfo> ni(aNodeInfo); 42 auto* nim = ni->NodeInfoManager(); 43 HTMLAudioElement* it = new (nim) HTMLAudioElement(ni.forget()); 44 it->Init(); 45 nsCOMPtr<nsINode> kungFuDeathGrip = it; 46 nsresult rv = const_cast<HTMLAudioElement*>(this)->CopyInnerTo(it); 47 if (NS_SUCCEEDED(rv)) { 48 kungFuDeathGrip.swap(*aResult); 49 } 50 return rv; 51 } 52 53 HTMLAudioElement::HTMLAudioElement(already_AddRefed<NodeInfo>&& aNodeInfo) 54 : HTMLMediaElement(std::move(aNodeInfo)) { 55 DecoderDoctorLogger::LogConstruction(this); 56 } 57 58 HTMLAudioElement::~HTMLAudioElement() { 59 DecoderDoctorLogger::LogDestruction(this); 60 } 61 62 bool HTMLAudioElement::IsInteractiveHTMLContent() const { 63 return HasAttr(nsGkAtoms::controls) || 64 HTMLMediaElement::IsInteractiveHTMLContent(); 65 } 66 67 already_AddRefed<HTMLAudioElement> HTMLAudioElement::Audio( 68 const GlobalObject& aGlobal, const Optional<nsAString>& aSrc, 69 ErrorResult& aRv) { 70 nsCOMPtr<nsPIDOMWindowInner> win = do_QueryInterface(aGlobal.GetAsSupports()); 71 Document* doc; 72 if (!win || !(doc = win->GetExtantDoc())) { 73 aRv.Throw(NS_ERROR_FAILURE); 74 return nullptr; 75 } 76 77 RefPtr<mozilla::dom::NodeInfo> nodeInfo = doc->NodeInfoManager()->GetNodeInfo( 78 nsGkAtoms::audio, nullptr, kNameSpaceID_XHTML, ELEMENT_NODE); 79 80 RefPtr<HTMLAudioElement> audio = 81 static_cast<HTMLAudioElement*>(NS_NewHTMLAudioElement(nodeInfo.forget())); 82 audio->SetHTMLAttr(nsGkAtoms::preload, u"auto"_ns, aRv); 83 if (aRv.Failed()) { 84 return nullptr; 85 } 86 87 if (aSrc.WasPassed()) { 88 audio->SetSrc(aSrc.Value(), aRv); 89 } 90 91 return audio.forget(); 92 } 93 94 nsresult HTMLAudioElement::SetAcceptHeader(nsIHttpChannel* aChannel) { 95 nsAutoCString value( 96 "audio/webm," 97 "audio/ogg," 98 "audio/wav," 99 "audio/*;q=0.9," 100 "application/ogg;q=0.7," 101 "video/*;q=0.6,*/*;q=0.5"); 102 103 return aChannel->SetRequestHeader("Accept"_ns, value, false); 104 } 105 106 JSObject* HTMLAudioElement::WrapNode(JSContext* aCx, 107 JS::Handle<JSObject*> aGivenProto) { 108 return HTMLAudioElement_Binding::Wrap(aCx, this, aGivenProto); 109 } 110 111 } // namespace mozilla::dom