Thu, 22 Jan 2015 13:21:57 +0100
Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6
michael@0 | 1 | /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
michael@0 | 2 | /* This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
michael@0 | 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 5 | |
michael@0 | 6 | #include "nsPluginArray.h" |
michael@0 | 7 | |
michael@0 | 8 | #include "mozilla/Preferences.h" |
michael@0 | 9 | #include "mozilla/dom/PluginArrayBinding.h" |
michael@0 | 10 | #include "mozilla/dom/PluginBinding.h" |
michael@0 | 11 | |
michael@0 | 12 | #include "nsCharSeparatedTokenizer.h" |
michael@0 | 13 | #include "nsMimeTypeArray.h" |
michael@0 | 14 | #include "Navigator.h" |
michael@0 | 15 | #include "nsIDocShell.h" |
michael@0 | 16 | #include "nsIWebNavigation.h" |
michael@0 | 17 | #include "nsPluginHost.h" |
michael@0 | 18 | #include "nsPluginTags.h" |
michael@0 | 19 | #include "nsIObserverService.h" |
michael@0 | 20 | #include "nsIWeakReference.h" |
michael@0 | 21 | #include "mozilla/Services.h" |
michael@0 | 22 | #include "nsIInterfaceRequestorUtils.h" |
michael@0 | 23 | |
michael@0 | 24 | using namespace mozilla; |
michael@0 | 25 | using namespace mozilla::dom; |
michael@0 | 26 | |
michael@0 | 27 | nsPluginArray::nsPluginArray(nsPIDOMWindow* aWindow) |
michael@0 | 28 | : mWindow(aWindow) |
michael@0 | 29 | { |
michael@0 | 30 | SetIsDOMBinding(); |
michael@0 | 31 | } |
michael@0 | 32 | |
michael@0 | 33 | void |
michael@0 | 34 | nsPluginArray::Init() |
michael@0 | 35 | { |
michael@0 | 36 | nsCOMPtr<nsIObserverService> obsService = |
michael@0 | 37 | mozilla::services::GetObserverService(); |
michael@0 | 38 | if (obsService) { |
michael@0 | 39 | obsService->AddObserver(this, "plugin-info-updated", true); |
michael@0 | 40 | } |
michael@0 | 41 | } |
michael@0 | 42 | |
michael@0 | 43 | nsPluginArray::~nsPluginArray() |
michael@0 | 44 | { |
michael@0 | 45 | } |
michael@0 | 46 | |
michael@0 | 47 | nsPIDOMWindow* |
michael@0 | 48 | nsPluginArray::GetParentObject() const |
michael@0 | 49 | { |
michael@0 | 50 | MOZ_ASSERT(mWindow); |
michael@0 | 51 | return mWindow; |
michael@0 | 52 | } |
michael@0 | 53 | |
michael@0 | 54 | JSObject* |
michael@0 | 55 | nsPluginArray::WrapObject(JSContext* aCx) |
michael@0 | 56 | { |
michael@0 | 57 | return PluginArrayBinding::Wrap(aCx, this); |
michael@0 | 58 | } |
michael@0 | 59 | |
michael@0 | 60 | NS_IMPL_CYCLE_COLLECTING_ADDREF(nsPluginArray) |
michael@0 | 61 | NS_IMPL_CYCLE_COLLECTING_RELEASE(nsPluginArray) |
michael@0 | 62 | NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsPluginArray) |
michael@0 | 63 | NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY |
michael@0 | 64 | NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIObserver) |
michael@0 | 65 | NS_INTERFACE_MAP_ENTRY(nsIObserver) |
michael@0 | 66 | NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference) |
michael@0 | 67 | NS_INTERFACE_MAP_END |
michael@0 | 68 | |
michael@0 | 69 | NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_3(nsPluginArray, |
michael@0 | 70 | mWindow, |
michael@0 | 71 | mPlugins, |
michael@0 | 72 | mHiddenPlugins) |
michael@0 | 73 | |
michael@0 | 74 | static void |
michael@0 | 75 | GetPluginMimeTypes(const nsTArray<nsRefPtr<nsPluginElement> >& aPlugins, |
michael@0 | 76 | nsTArray<nsRefPtr<nsMimeType> >& aMimeTypes) |
michael@0 | 77 | { |
michael@0 | 78 | for (uint32_t i = 0; i < aPlugins.Length(); ++i) { |
michael@0 | 79 | nsPluginElement *plugin = aPlugins[i]; |
michael@0 | 80 | aMimeTypes.AppendElements(plugin->MimeTypes()); |
michael@0 | 81 | } |
michael@0 | 82 | } |
michael@0 | 83 | |
michael@0 | 84 | void |
michael@0 | 85 | nsPluginArray::GetMimeTypes(nsTArray<nsRefPtr<nsMimeType> >& aMimeTypes, |
michael@0 | 86 | nsTArray<nsRefPtr<nsMimeType> >& aHiddenMimeTypes) |
michael@0 | 87 | { |
michael@0 | 88 | aMimeTypes.Clear(); |
michael@0 | 89 | aHiddenMimeTypes.Clear(); |
michael@0 | 90 | |
michael@0 | 91 | if (!AllowPlugins()) { |
michael@0 | 92 | return; |
michael@0 | 93 | } |
michael@0 | 94 | |
michael@0 | 95 | EnsurePlugins(); |
michael@0 | 96 | |
michael@0 | 97 | GetPluginMimeTypes(mPlugins, aMimeTypes); |
michael@0 | 98 | GetPluginMimeTypes(mHiddenPlugins, aHiddenMimeTypes); |
michael@0 | 99 | } |
michael@0 | 100 | |
michael@0 | 101 | nsPluginElement* |
michael@0 | 102 | nsPluginArray::Item(uint32_t aIndex) |
michael@0 | 103 | { |
michael@0 | 104 | bool unused; |
michael@0 | 105 | return IndexedGetter(aIndex, unused); |
michael@0 | 106 | } |
michael@0 | 107 | |
michael@0 | 108 | nsPluginElement* |
michael@0 | 109 | nsPluginArray::NamedItem(const nsAString& aName) |
michael@0 | 110 | { |
michael@0 | 111 | bool unused; |
michael@0 | 112 | return NamedGetter(aName, unused); |
michael@0 | 113 | } |
michael@0 | 114 | |
michael@0 | 115 | void |
michael@0 | 116 | nsPluginArray::Refresh(bool aReloadDocuments) |
michael@0 | 117 | { |
michael@0 | 118 | nsRefPtr<nsPluginHost> pluginHost = nsPluginHost::GetInst(); |
michael@0 | 119 | |
michael@0 | 120 | if(!AllowPlugins() || !pluginHost) { |
michael@0 | 121 | return; |
michael@0 | 122 | } |
michael@0 | 123 | |
michael@0 | 124 | // NS_ERROR_PLUGINS_PLUGINSNOTCHANGED on reloading plugins indicates |
michael@0 | 125 | // that plugins did not change and was not reloaded |
michael@0 | 126 | if (pluginHost->ReloadPlugins() == |
michael@0 | 127 | NS_ERROR_PLUGINS_PLUGINSNOTCHANGED) { |
michael@0 | 128 | nsTArray<nsRefPtr<nsPluginTag> > newPluginTags; |
michael@0 | 129 | pluginHost->GetPlugins(newPluginTags); |
michael@0 | 130 | |
michael@0 | 131 | // Check if the number of plugins we know about are different from |
michael@0 | 132 | // the number of plugin tags the plugin host knows about. If the |
michael@0 | 133 | // lengths are different, we refresh. This is safe because we're |
michael@0 | 134 | // notified for every plugin enabling/disabling event that |
michael@0 | 135 | // happens, and therefore the lengths will be in sync only when |
michael@0 | 136 | // the both arrays contain the same plugin tags (though as |
michael@0 | 137 | // different types). |
michael@0 | 138 | uint32_t pluginCount = mPlugins.Length() + mHiddenPlugins.Length(); |
michael@0 | 139 | if (newPluginTags.Length() == pluginCount) { |
michael@0 | 140 | return; |
michael@0 | 141 | } |
michael@0 | 142 | } |
michael@0 | 143 | |
michael@0 | 144 | mPlugins.Clear(); |
michael@0 | 145 | mHiddenPlugins.Clear(); |
michael@0 | 146 | |
michael@0 | 147 | nsCOMPtr<nsIDOMNavigator> navigator; |
michael@0 | 148 | mWindow->GetNavigator(getter_AddRefs(navigator)); |
michael@0 | 149 | |
michael@0 | 150 | if (!navigator) { |
michael@0 | 151 | return; |
michael@0 | 152 | } |
michael@0 | 153 | |
michael@0 | 154 | static_cast<mozilla::dom::Navigator*>(navigator.get())->RefreshMIMEArray(); |
michael@0 | 155 | |
michael@0 | 156 | nsCOMPtr<nsIWebNavigation> webNav = do_GetInterface(mWindow); |
michael@0 | 157 | if (aReloadDocuments && webNav) { |
michael@0 | 158 | webNav->Reload(nsIWebNavigation::LOAD_FLAGS_NONE); |
michael@0 | 159 | } |
michael@0 | 160 | } |
michael@0 | 161 | |
michael@0 | 162 | nsPluginElement* |
michael@0 | 163 | nsPluginArray::IndexedGetter(uint32_t aIndex, bool &aFound) |
michael@0 | 164 | { |
michael@0 | 165 | aFound = false; |
michael@0 | 166 | |
michael@0 | 167 | if (!AllowPlugins()) { |
michael@0 | 168 | return nullptr; |
michael@0 | 169 | } |
michael@0 | 170 | |
michael@0 | 171 | EnsurePlugins(); |
michael@0 | 172 | |
michael@0 | 173 | aFound = aIndex < mPlugins.Length(); |
michael@0 | 174 | |
michael@0 | 175 | return aFound ? mPlugins[aIndex] : nullptr; |
michael@0 | 176 | } |
michael@0 | 177 | |
michael@0 | 178 | void |
michael@0 | 179 | nsPluginArray::Invalidate() |
michael@0 | 180 | { |
michael@0 | 181 | nsCOMPtr<nsIObserverService> obsService = |
michael@0 | 182 | mozilla::services::GetObserverService(); |
michael@0 | 183 | if (obsService) { |
michael@0 | 184 | obsService->RemoveObserver(this, "plugin-info-updated"); |
michael@0 | 185 | } |
michael@0 | 186 | } |
michael@0 | 187 | |
michael@0 | 188 | static nsPluginElement* |
michael@0 | 189 | FindPlugin(const nsTArray<nsRefPtr<nsPluginElement> >& aPlugins, |
michael@0 | 190 | const nsAString& aName) |
michael@0 | 191 | { |
michael@0 | 192 | for (uint32_t i = 0; i < aPlugins.Length(); ++i) { |
michael@0 | 193 | nsAutoString pluginName; |
michael@0 | 194 | nsPluginElement* plugin = aPlugins[i]; |
michael@0 | 195 | plugin->GetName(pluginName); |
michael@0 | 196 | |
michael@0 | 197 | if (pluginName.Equals(aName)) { |
michael@0 | 198 | return plugin; |
michael@0 | 199 | } |
michael@0 | 200 | } |
michael@0 | 201 | |
michael@0 | 202 | return nullptr; |
michael@0 | 203 | } |
michael@0 | 204 | |
michael@0 | 205 | nsPluginElement* |
michael@0 | 206 | nsPluginArray::NamedGetter(const nsAString& aName, bool &aFound) |
michael@0 | 207 | { |
michael@0 | 208 | aFound = false; |
michael@0 | 209 | |
michael@0 | 210 | if (!AllowPlugins()) { |
michael@0 | 211 | return nullptr; |
michael@0 | 212 | } |
michael@0 | 213 | |
michael@0 | 214 | EnsurePlugins(); |
michael@0 | 215 | |
michael@0 | 216 | nsPluginElement* plugin = FindPlugin(mPlugins, aName); |
michael@0 | 217 | if (!plugin) { |
michael@0 | 218 | plugin = FindPlugin(mHiddenPlugins, aName); |
michael@0 | 219 | } |
michael@0 | 220 | |
michael@0 | 221 | aFound = (plugin != nullptr); |
michael@0 | 222 | return plugin; |
michael@0 | 223 | } |
michael@0 | 224 | |
michael@0 | 225 | bool |
michael@0 | 226 | nsPluginArray::NameIsEnumerable(const nsAString& aName) |
michael@0 | 227 | { |
michael@0 | 228 | return true; |
michael@0 | 229 | } |
michael@0 | 230 | |
michael@0 | 231 | uint32_t |
michael@0 | 232 | nsPluginArray::Length() |
michael@0 | 233 | { |
michael@0 | 234 | if (!AllowPlugins()) { |
michael@0 | 235 | return 0; |
michael@0 | 236 | } |
michael@0 | 237 | |
michael@0 | 238 | EnsurePlugins(); |
michael@0 | 239 | |
michael@0 | 240 | return mPlugins.Length(); |
michael@0 | 241 | } |
michael@0 | 242 | |
michael@0 | 243 | void |
michael@0 | 244 | nsPluginArray::GetSupportedNames(unsigned, nsTArray<nsString>& aRetval) |
michael@0 | 245 | { |
michael@0 | 246 | aRetval.Clear(); |
michael@0 | 247 | |
michael@0 | 248 | if (!AllowPlugins()) { |
michael@0 | 249 | return; |
michael@0 | 250 | } |
michael@0 | 251 | |
michael@0 | 252 | for (uint32_t i = 0; i < mPlugins.Length(); ++i) { |
michael@0 | 253 | nsAutoString pluginName; |
michael@0 | 254 | mPlugins[i]->GetName(pluginName); |
michael@0 | 255 | |
michael@0 | 256 | aRetval.AppendElement(pluginName); |
michael@0 | 257 | } |
michael@0 | 258 | } |
michael@0 | 259 | |
michael@0 | 260 | NS_IMETHODIMP |
michael@0 | 261 | nsPluginArray::Observe(nsISupports *aSubject, const char *aTopic, |
michael@0 | 262 | const char16_t *aData) { |
michael@0 | 263 | if (!nsCRT::strcmp(aTopic, "plugin-info-updated")) { |
michael@0 | 264 | Refresh(false); |
michael@0 | 265 | } |
michael@0 | 266 | |
michael@0 | 267 | return NS_OK; |
michael@0 | 268 | } |
michael@0 | 269 | |
michael@0 | 270 | bool |
michael@0 | 271 | nsPluginArray::AllowPlugins() const |
michael@0 | 272 | { |
michael@0 | 273 | nsCOMPtr<nsIDocShell> docShell = do_GetInterface(mWindow); |
michael@0 | 274 | |
michael@0 | 275 | return docShell && docShell->PluginsAllowedInCurrentDoc(); |
michael@0 | 276 | } |
michael@0 | 277 | |
michael@0 | 278 | static bool |
michael@0 | 279 | HasStringPrefix(const nsCString& str, const nsACString& prefix) { |
michael@0 | 280 | return str.Compare(prefix.BeginReading(), false, prefix.Length()) == 0; |
michael@0 | 281 | } |
michael@0 | 282 | |
michael@0 | 283 | static bool |
michael@0 | 284 | IsPluginEnumerable(const nsTArray<nsCString>& enumerableNames, |
michael@0 | 285 | const nsPluginTag* pluginTag) |
michael@0 | 286 | { |
michael@0 | 287 | const nsCString& pluginName = pluginTag->mName; |
michael@0 | 288 | |
michael@0 | 289 | const uint32_t length = enumerableNames.Length(); |
michael@0 | 290 | for (uint32_t i = 0; i < length; i++) { |
michael@0 | 291 | const nsCString& name = enumerableNames[i]; |
michael@0 | 292 | if (HasStringPrefix(pluginName, name)) { |
michael@0 | 293 | return true; // don't hide plugin |
michael@0 | 294 | } |
michael@0 | 295 | } |
michael@0 | 296 | |
michael@0 | 297 | return false; // hide plugin! |
michael@0 | 298 | } |
michael@0 | 299 | |
michael@0 | 300 | void |
michael@0 | 301 | nsPluginArray::EnsurePlugins() |
michael@0 | 302 | { |
michael@0 | 303 | if (!mPlugins.IsEmpty() || !mHiddenPlugins.IsEmpty()) { |
michael@0 | 304 | // We already have an array of plugin elements. |
michael@0 | 305 | return; |
michael@0 | 306 | } |
michael@0 | 307 | |
michael@0 | 308 | nsRefPtr<nsPluginHost> pluginHost = nsPluginHost::GetInst(); |
michael@0 | 309 | if (!pluginHost) { |
michael@0 | 310 | // We have no plugin host. |
michael@0 | 311 | return; |
michael@0 | 312 | } |
michael@0 | 313 | |
michael@0 | 314 | nsTArray<nsRefPtr<nsPluginTag> > pluginTags; |
michael@0 | 315 | pluginHost->GetPlugins(pluginTags); |
michael@0 | 316 | |
michael@0 | 317 | nsTArray<nsCString> enumerableNames; |
michael@0 | 318 | |
michael@0 | 319 | const nsAdoptingCString& enumerableNamesPref = |
michael@0 | 320 | Preferences::GetCString("plugins.enumerable_names"); |
michael@0 | 321 | |
michael@0 | 322 | bool disablePluginHiding = !enumerableNamesPref || |
michael@0 | 323 | enumerableNamesPref.EqualsLiteral("*"); |
michael@0 | 324 | |
michael@0 | 325 | if (!disablePluginHiding) { |
michael@0 | 326 | nsCCharSeparatedTokenizer tokens(enumerableNamesPref, ','); |
michael@0 | 327 | while (tokens.hasMoreTokens()) { |
michael@0 | 328 | const nsCSubstring& token = tokens.nextToken(); |
michael@0 | 329 | if (!token.IsEmpty()) { |
michael@0 | 330 | enumerableNames.AppendElement(token); |
michael@0 | 331 | } |
michael@0 | 332 | } |
michael@0 | 333 | } |
michael@0 | 334 | |
michael@0 | 335 | // need to wrap each of these with a nsPluginElement, which is |
michael@0 | 336 | // scriptable. |
michael@0 | 337 | for (uint32_t i = 0; i < pluginTags.Length(); ++i) { |
michael@0 | 338 | nsPluginTag* pluginTag = pluginTags[i]; |
michael@0 | 339 | |
michael@0 | 340 | // Add the plugin to the list of hidden plugins or non-hidden plugins? |
michael@0 | 341 | nsTArray<nsRefPtr<nsPluginElement> >& pluginArray = |
michael@0 | 342 | (disablePluginHiding || IsPluginEnumerable(enumerableNames, pluginTag)) |
michael@0 | 343 | ? mPlugins |
michael@0 | 344 | : mHiddenPlugins; |
michael@0 | 345 | |
michael@0 | 346 | pluginArray.AppendElement(new nsPluginElement(mWindow, pluginTag)); |
michael@0 | 347 | } |
michael@0 | 348 | } |
michael@0 | 349 | |
michael@0 | 350 | // nsPluginElement implementation. |
michael@0 | 351 | |
michael@0 | 352 | NS_IMPL_CYCLE_COLLECTING_ADDREF(nsPluginElement) |
michael@0 | 353 | NS_IMPL_CYCLE_COLLECTING_RELEASE(nsPluginElement) |
michael@0 | 354 | NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsPluginElement) |
michael@0 | 355 | NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY |
michael@0 | 356 | NS_INTERFACE_MAP_ENTRY(nsISupports) |
michael@0 | 357 | NS_INTERFACE_MAP_END |
michael@0 | 358 | |
michael@0 | 359 | NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_2(nsPluginElement, mWindow, mMimeTypes) |
michael@0 | 360 | |
michael@0 | 361 | nsPluginElement::nsPluginElement(nsPIDOMWindow* aWindow, |
michael@0 | 362 | nsPluginTag* aPluginTag) |
michael@0 | 363 | : mWindow(aWindow), |
michael@0 | 364 | mPluginTag(aPluginTag) |
michael@0 | 365 | { |
michael@0 | 366 | SetIsDOMBinding(); |
michael@0 | 367 | } |
michael@0 | 368 | |
michael@0 | 369 | nsPIDOMWindow* |
michael@0 | 370 | nsPluginElement::GetParentObject() const |
michael@0 | 371 | { |
michael@0 | 372 | MOZ_ASSERT(mWindow); |
michael@0 | 373 | return mWindow; |
michael@0 | 374 | } |
michael@0 | 375 | |
michael@0 | 376 | JSObject* |
michael@0 | 377 | nsPluginElement::WrapObject(JSContext* aCx) |
michael@0 | 378 | { |
michael@0 | 379 | return PluginBinding::Wrap(aCx, this); |
michael@0 | 380 | } |
michael@0 | 381 | |
michael@0 | 382 | void |
michael@0 | 383 | nsPluginElement::GetDescription(nsString& retval) const |
michael@0 | 384 | { |
michael@0 | 385 | CopyUTF8toUTF16(mPluginTag->mDescription, retval); |
michael@0 | 386 | } |
michael@0 | 387 | |
michael@0 | 388 | void |
michael@0 | 389 | nsPluginElement::GetFilename(nsString& retval) const |
michael@0 | 390 | { |
michael@0 | 391 | CopyUTF8toUTF16(mPluginTag->mFileName, retval); |
michael@0 | 392 | } |
michael@0 | 393 | |
michael@0 | 394 | void |
michael@0 | 395 | nsPluginElement::GetVersion(nsString& retval) const |
michael@0 | 396 | { |
michael@0 | 397 | CopyUTF8toUTF16(mPluginTag->mVersion, retval); |
michael@0 | 398 | } |
michael@0 | 399 | |
michael@0 | 400 | void |
michael@0 | 401 | nsPluginElement::GetName(nsString& retval) const |
michael@0 | 402 | { |
michael@0 | 403 | CopyUTF8toUTF16(mPluginTag->mName, retval); |
michael@0 | 404 | } |
michael@0 | 405 | |
michael@0 | 406 | nsMimeType* |
michael@0 | 407 | nsPluginElement::Item(uint32_t aIndex) |
michael@0 | 408 | { |
michael@0 | 409 | EnsurePluginMimeTypes(); |
michael@0 | 410 | |
michael@0 | 411 | return mMimeTypes.SafeElementAt(aIndex); |
michael@0 | 412 | } |
michael@0 | 413 | |
michael@0 | 414 | nsMimeType* |
michael@0 | 415 | nsPluginElement::NamedItem(const nsAString& aName) |
michael@0 | 416 | { |
michael@0 | 417 | bool unused; |
michael@0 | 418 | return NamedGetter(aName, unused); |
michael@0 | 419 | } |
michael@0 | 420 | |
michael@0 | 421 | nsMimeType* |
michael@0 | 422 | nsPluginElement::IndexedGetter(uint32_t aIndex, bool &aFound) |
michael@0 | 423 | { |
michael@0 | 424 | EnsurePluginMimeTypes(); |
michael@0 | 425 | |
michael@0 | 426 | aFound = aIndex < mMimeTypes.Length(); |
michael@0 | 427 | |
michael@0 | 428 | return aFound ? mMimeTypes[aIndex] : nullptr; |
michael@0 | 429 | } |
michael@0 | 430 | |
michael@0 | 431 | nsMimeType* |
michael@0 | 432 | nsPluginElement::NamedGetter(const nsAString& aName, bool &aFound) |
michael@0 | 433 | { |
michael@0 | 434 | EnsurePluginMimeTypes(); |
michael@0 | 435 | |
michael@0 | 436 | aFound = false; |
michael@0 | 437 | |
michael@0 | 438 | for (uint32_t i = 0; i < mMimeTypes.Length(); ++i) { |
michael@0 | 439 | if (mMimeTypes[i]->Type().Equals(aName)) { |
michael@0 | 440 | aFound = true; |
michael@0 | 441 | |
michael@0 | 442 | return mMimeTypes[i]; |
michael@0 | 443 | } |
michael@0 | 444 | } |
michael@0 | 445 | |
michael@0 | 446 | return nullptr; |
michael@0 | 447 | } |
michael@0 | 448 | |
michael@0 | 449 | bool |
michael@0 | 450 | nsPluginElement::NameIsEnumerable(const nsAString& aName) |
michael@0 | 451 | { |
michael@0 | 452 | return true; |
michael@0 | 453 | } |
michael@0 | 454 | |
michael@0 | 455 | uint32_t |
michael@0 | 456 | nsPluginElement::Length() |
michael@0 | 457 | { |
michael@0 | 458 | EnsurePluginMimeTypes(); |
michael@0 | 459 | |
michael@0 | 460 | return mMimeTypes.Length(); |
michael@0 | 461 | } |
michael@0 | 462 | |
michael@0 | 463 | void |
michael@0 | 464 | nsPluginElement::GetSupportedNames(unsigned, nsTArray<nsString>& retval) |
michael@0 | 465 | { |
michael@0 | 466 | EnsurePluginMimeTypes(); |
michael@0 | 467 | |
michael@0 | 468 | for (uint32_t i = 0; i < mMimeTypes.Length(); ++i) { |
michael@0 | 469 | retval.AppendElement(mMimeTypes[i]->Type()); |
michael@0 | 470 | } |
michael@0 | 471 | } |
michael@0 | 472 | |
michael@0 | 473 | nsTArray<nsRefPtr<nsMimeType> >& |
michael@0 | 474 | nsPluginElement::MimeTypes() |
michael@0 | 475 | { |
michael@0 | 476 | EnsurePluginMimeTypes(); |
michael@0 | 477 | |
michael@0 | 478 | return mMimeTypes; |
michael@0 | 479 | } |
michael@0 | 480 | |
michael@0 | 481 | void |
michael@0 | 482 | nsPluginElement::EnsurePluginMimeTypes() |
michael@0 | 483 | { |
michael@0 | 484 | if (!mMimeTypes.IsEmpty()) { |
michael@0 | 485 | return; |
michael@0 | 486 | } |
michael@0 | 487 | |
michael@0 | 488 | for (uint32_t i = 0; i < mPluginTag->mMimeTypes.Length(); ++i) { |
michael@0 | 489 | NS_ConvertUTF8toUTF16 type(mPluginTag->mMimeTypes[i]); |
michael@0 | 490 | mMimeTypes.AppendElement(new nsMimeType(mWindow, this, i, type)); |
michael@0 | 491 | } |
michael@0 | 492 | } |