1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim:set ts=2 sw=2 sts=2 et cindent: */
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 "nsCOMPtr.h"
8 #include "nsCycleCollectionParticipant.h"
9 #include "nsGkAtoms.h"
10 
11 #include "mozilla/dom/SpeechSynthesisEvent.h"
12 #include "mozilla/dom/SpeechSynthesisUtteranceBinding.h"
13 #include "SpeechSynthesisUtterance.h"
14 #include "SpeechSynthesisVoice.h"
15 
16 #include <stdlib.h>
17 
18 namespace mozilla::dom {
19 
20 NS_IMPL_CYCLE_COLLECTION_INHERITED(SpeechSynthesisUtterance,
21                                    DOMEventTargetHelper, mVoice);
22 
23 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(SpeechSynthesisUtterance)
NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)24 NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
25 
26 NS_IMPL_ADDREF_INHERITED(SpeechSynthesisUtterance, DOMEventTargetHelper)
27 NS_IMPL_RELEASE_INHERITED(SpeechSynthesisUtterance, DOMEventTargetHelper)
28 
29 SpeechSynthesisUtterance::SpeechSynthesisUtterance(
30     nsPIDOMWindowInner* aOwnerWindow, const nsAString& text)
31     : DOMEventTargetHelper(aOwnerWindow),
32       mText(text),
33       mVolume(1),
34       mRate(1),
35       mPitch(1),
36       mPaused(false) {}
37 
38 SpeechSynthesisUtterance::~SpeechSynthesisUtterance() = default;
39 
WrapObject(JSContext * aCx,JS::Handle<JSObject * > aGivenProto)40 JSObject* SpeechSynthesisUtterance::WrapObject(
41     JSContext* aCx, JS::Handle<JSObject*> aGivenProto) {
42   return SpeechSynthesisUtterance_Binding::Wrap(aCx, this, aGivenProto);
43 }
44 
GetParentObject() const45 nsISupports* SpeechSynthesisUtterance::GetParentObject() const {
46   return GetOwner();
47 }
48 
49 already_AddRefed<SpeechSynthesisUtterance>
Constructor(GlobalObject & aGlobal,ErrorResult & aRv)50 SpeechSynthesisUtterance::Constructor(GlobalObject& aGlobal, ErrorResult& aRv) {
51   return Constructor(aGlobal, u""_ns, aRv);
52 }
53 
54 already_AddRefed<SpeechSynthesisUtterance>
Constructor(GlobalObject & aGlobal,const nsAString & aText,ErrorResult & aRv)55 SpeechSynthesisUtterance::Constructor(GlobalObject& aGlobal,
56                                       const nsAString& aText,
57                                       ErrorResult& aRv) {
58   nsCOMPtr<nsPIDOMWindowInner> win = do_QueryInterface(aGlobal.GetAsSupports());
59 
60   if (!win) {
61     aRv.Throw(NS_ERROR_FAILURE);
62     return nullptr;
63   }
64 
65   RefPtr<SpeechSynthesisUtterance> object =
66       new SpeechSynthesisUtterance(win, aText);
67   return object.forget();
68 }
69 
GetText(nsString & aResult) const70 void SpeechSynthesisUtterance::GetText(nsString& aResult) const {
71   aResult = mText;
72 }
73 
SetText(const nsAString & aText)74 void SpeechSynthesisUtterance::SetText(const nsAString& aText) {
75   mText = aText;
76 }
77 
GetLang(nsString & aResult) const78 void SpeechSynthesisUtterance::GetLang(nsString& aResult) const {
79   aResult = mLang;
80 }
81 
SetLang(const nsAString & aLang)82 void SpeechSynthesisUtterance::SetLang(const nsAString& aLang) {
83   mLang = aLang;
84 }
85 
GetVoice() const86 SpeechSynthesisVoice* SpeechSynthesisUtterance::GetVoice() const {
87   return mVoice;
88 }
89 
SetVoice(SpeechSynthesisVoice * aVoice)90 void SpeechSynthesisUtterance::SetVoice(SpeechSynthesisVoice* aVoice) {
91   mVoice = aVoice;
92 }
93 
Volume() const94 float SpeechSynthesisUtterance::Volume() const { return mVolume; }
95 
SetVolume(float aVolume)96 void SpeechSynthesisUtterance::SetVolume(float aVolume) {
97   mVolume = std::max<float>(std::min<float>(aVolume, 1), 0);
98 }
99 
Rate() const100 float SpeechSynthesisUtterance::Rate() const { return mRate; }
101 
SetRate(float aRate)102 void SpeechSynthesisUtterance::SetRate(float aRate) {
103   mRate = std::max<float>(std::min<float>(aRate, 10), 0.1f);
104 }
105 
Pitch() const106 float SpeechSynthesisUtterance::Pitch() const { return mPitch; }
107 
SetPitch(float aPitch)108 void SpeechSynthesisUtterance::SetPitch(float aPitch) {
109   mPitch = std::max<float>(std::min<float>(aPitch, 2), 0);
110 }
111 
GetChosenVoiceURI(nsString & aResult) const112 void SpeechSynthesisUtterance::GetChosenVoiceURI(nsString& aResult) const {
113   aResult = mChosenVoiceURI;
114 }
115 
DispatchSpeechSynthesisEvent(const nsAString & aEventType,uint32_t aCharIndex,const Nullable<uint32_t> & aCharLength,float aElapsedTime,const nsAString & aName)116 void SpeechSynthesisUtterance::DispatchSpeechSynthesisEvent(
117     const nsAString& aEventType, uint32_t aCharIndex,
118     const Nullable<uint32_t>& aCharLength, float aElapsedTime,
119     const nsAString& aName) {
120   SpeechSynthesisEventInit init;
121   init.mBubbles = false;
122   init.mCancelable = false;
123   init.mUtterance = this;
124   init.mCharIndex = aCharIndex;
125   init.mCharLength = aCharLength;
126   init.mElapsedTime = aElapsedTime;
127   init.mName = aName;
128 
129   RefPtr<SpeechSynthesisEvent> event =
130       SpeechSynthesisEvent::Constructor(this, aEventType, init);
131   DispatchTrustedEvent(event);
132 }
133 
134 }  // namespace mozilla::dom
135