Line data Source code
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 "nsMimeTypeArray.h"
8 :
9 : #include "mozilla/dom/MimeTypeArrayBinding.h"
10 : #include "mozilla/dom/MimeTypeBinding.h"
11 : #include "nsIDOMNavigator.h"
12 : #include "nsPIDOMWindow.h"
13 : #include "nsPluginArray.h"
14 : #include "nsIMIMEService.h"
15 : #include "nsIMIMEInfo.h"
16 : #include "Navigator.h"
17 : #include "nsServiceManagerUtils.h"
18 : #include "nsContentUtils.h"
19 : #include "nsPluginTags.h"
20 :
21 : using namespace mozilla;
22 : using namespace mozilla::dom;
23 :
24 0 : NS_IMPL_CYCLE_COLLECTING_ADDREF(nsMimeTypeArray)
25 0 : NS_IMPL_CYCLE_COLLECTING_RELEASE(nsMimeTypeArray)
26 0 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsMimeTypeArray)
27 0 : NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
28 0 : NS_INTERFACE_MAP_ENTRY(nsISupports)
29 0 : NS_INTERFACE_MAP_END
30 :
31 0 : NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(nsMimeTypeArray,
32 : mWindow,
33 : mMimeTypes,
34 : mCTPMimeTypes)
35 :
36 0 : nsMimeTypeArray::nsMimeTypeArray(nsPIDOMWindowInner* aWindow)
37 0 : : mWindow(aWindow)
38 : {
39 0 : }
40 :
41 0 : nsMimeTypeArray::~nsMimeTypeArray()
42 : {
43 0 : }
44 :
45 : JSObject*
46 0 : nsMimeTypeArray::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
47 : {
48 0 : return MimeTypeArrayBinding::Wrap(aCx, this, aGivenProto);
49 : }
50 :
51 : void
52 0 : nsMimeTypeArray::Refresh()
53 : {
54 0 : mMimeTypes.Clear();
55 0 : mCTPMimeTypes.Clear();
56 0 : }
57 :
58 : nsPIDOMWindowInner*
59 0 : nsMimeTypeArray::GetParentObject() const
60 : {
61 0 : MOZ_ASSERT(mWindow);
62 0 : return mWindow;
63 : }
64 :
65 : nsMimeType*
66 0 : nsMimeTypeArray::Item(uint32_t aIndex, CallerType aCallerType)
67 : {
68 : bool unused;
69 0 : return IndexedGetter(aIndex, unused, aCallerType);
70 : }
71 :
72 : nsMimeType*
73 0 : nsMimeTypeArray::NamedItem(const nsAString& aName, CallerType aCallerType)
74 : {
75 : bool unused;
76 0 : return NamedGetter(aName, unused, aCallerType);
77 : }
78 :
79 : nsMimeType*
80 0 : nsMimeTypeArray::IndexedGetter(uint32_t aIndex, bool &aFound,
81 : CallerType aCallerType)
82 : {
83 0 : aFound = false;
84 :
85 0 : if (nsContentUtils::ResistFingerprinting(aCallerType)) {
86 0 : return nullptr;
87 : }
88 :
89 0 : EnsurePluginMimeTypes();
90 :
91 0 : if (aIndex >= mMimeTypes.Length()) {
92 0 : return nullptr;
93 : }
94 :
95 0 : aFound = true;
96 :
97 0 : return mMimeTypes[aIndex];
98 : }
99 :
100 : static nsMimeType*
101 0 : FindMimeType(const nsTArray<RefPtr<nsMimeType>>& aMimeTypes,
102 : const nsAString& aType)
103 : {
104 0 : for (uint32_t i = 0; i < aMimeTypes.Length(); ++i) {
105 0 : nsMimeType* mimeType = aMimeTypes[i];
106 0 : if (aType.Equals(mimeType->Type())) {
107 0 : return mimeType;
108 : }
109 : }
110 :
111 0 : return nullptr;
112 : }
113 :
114 : nsMimeType*
115 0 : nsMimeTypeArray::NamedGetter(const nsAString& aName, bool &aFound,
116 : CallerType aCallerType)
117 : {
118 0 : aFound = false;
119 :
120 0 : if (nsContentUtils::ResistFingerprinting(aCallerType)) {
121 0 : return nullptr;
122 : }
123 :
124 0 : EnsurePluginMimeTypes();
125 :
126 0 : nsString lowerName(aName);
127 0 : ToLowerCase(lowerName);
128 :
129 0 : nsMimeType* mimeType = FindMimeType(mMimeTypes, lowerName);
130 0 : if (mimeType) {
131 0 : aFound = true;
132 0 : return mimeType;
133 : }
134 0 : nsMimeType* hiddenType = FindMimeType(mCTPMimeTypes, lowerName);
135 0 : if (hiddenType) {
136 0 : nsPluginArray::NotifyHiddenPluginTouched(hiddenType->GetEnabledPlugin());
137 : }
138 :
139 0 : return nullptr;
140 : }
141 :
142 : uint32_t
143 0 : nsMimeTypeArray::Length(CallerType aCallerType)
144 : {
145 0 : if (nsContentUtils::ResistFingerprinting(aCallerType)) {
146 0 : return 0;
147 : }
148 :
149 0 : EnsurePluginMimeTypes();
150 :
151 0 : return mMimeTypes.Length();
152 : }
153 :
154 : void
155 0 : nsMimeTypeArray::GetSupportedNames(nsTArray<nsString>& aRetval,
156 : CallerType aCallerType)
157 : {
158 0 : if (nsContentUtils::ResistFingerprinting(aCallerType)) {
159 0 : return;
160 : }
161 :
162 0 : EnsurePluginMimeTypes();
163 :
164 0 : for (uint32_t i = 0; i < mMimeTypes.Length(); ++i) {
165 0 : aRetval.AppendElement(mMimeTypes[i]->Type());
166 : }
167 : }
168 :
169 : void
170 0 : nsMimeTypeArray::EnsurePluginMimeTypes()
171 : {
172 0 : if (!mMimeTypes.IsEmpty() || !mWindow) {
173 0 : return;
174 : }
175 :
176 0 : nsCOMPtr<nsIDOMNavigator> navigator = mWindow->GetNavigator();
177 :
178 0 : if (!navigator) {
179 0 : return;
180 : }
181 :
182 0 : ErrorResult rv;
183 : nsPluginArray *pluginArray =
184 0 : static_cast<Navigator*>(navigator.get())->GetPlugins(rv);
185 0 : if (!pluginArray) {
186 0 : return;
187 : }
188 :
189 0 : pluginArray->GetMimeTypes(mMimeTypes);
190 0 : pluginArray->GetCTPMimeTypes(mCTPMimeTypes);
191 : }
192 :
193 0 : NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(nsMimeType, AddRef)
194 0 : NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(nsMimeType, Release)
195 :
196 0 : NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(nsMimeType, mWindow, mPluginElement)
197 :
198 0 : nsMimeType::nsMimeType(nsPIDOMWindowInner* aWindow,
199 : nsPluginElement* aPluginElement,
200 : const nsAString& aType,
201 : const nsAString& aDescription,
202 0 : const nsAString& aExtension)
203 : : mWindow(aWindow),
204 : mPluginElement(aPluginElement),
205 : mType(aType),
206 : mDescription(aDescription),
207 0 : mExtension(aExtension)
208 : {
209 0 : MOZ_ASSERT(aPluginElement);
210 0 : }
211 :
212 0 : nsMimeType::~nsMimeType()
213 : {
214 0 : }
215 :
216 : nsPIDOMWindowInner*
217 0 : nsMimeType::GetParentObject() const
218 : {
219 0 : MOZ_ASSERT(mWindow);
220 0 : return mWindow;
221 : }
222 :
223 : JSObject*
224 0 : nsMimeType::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
225 : {
226 0 : return MimeTypeBinding::Wrap(aCx, this, aGivenProto);
227 : }
228 :
229 : void
230 0 : nsMimeType::GetDescription(nsString& aRetval) const
231 : {
232 0 : aRetval = mDescription;
233 0 : }
234 :
235 : nsPluginElement*
236 0 : nsMimeType::GetEnabledPlugin() const
237 : {
238 : // mPluginElement might be null if we got unlinked but are still somehow being
239 : // called into.
240 0 : if (!mPluginElement || !mPluginElement->PluginTag()->IsEnabled()) {
241 0 : return nullptr;
242 : }
243 0 : return mPluginElement;
244 : }
245 :
246 : void
247 0 : nsMimeType::GetSuffixes(nsString& aRetval) const
248 : {
249 0 : aRetval = mExtension;
250 0 : }
251 :
252 : void
253 0 : nsMimeType::GetType(nsString& aRetval) const
254 : {
255 0 : aRetval = mType;
256 0 : }
|