зеркало из https://github.com/mozilla/pjs.git
Bug 730318 - Implement a way for chrome js to enumerate the plugin objects on a page for activation. r=khuey
This commit is contained in:
Родитель
fa552074df
Коммит
5fc2025a5d
|
@ -111,6 +111,7 @@ class imgIRequest;
|
||||||
class nsISHEntry;
|
class nsISHEntry;
|
||||||
class nsDOMNavigationTiming;
|
class nsDOMNavigationTiming;
|
||||||
class nsWindowSizes;
|
class nsWindowSizes;
|
||||||
|
class nsIObjectLoadingContent;
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace css {
|
namespace css {
|
||||||
|
@ -1570,6 +1571,10 @@ public:
|
||||||
// state is unlocked/false.
|
// state is unlocked/false.
|
||||||
virtual nsresult SetImageLockingState(bool aLocked) = 0;
|
virtual nsresult SetImageLockingState(bool aLocked) = 0;
|
||||||
|
|
||||||
|
virtual nsresult AddPlugin(nsIObjectLoadingContent* aPlugin) = 0;
|
||||||
|
virtual void RemovePlugin(nsIObjectLoadingContent* aPlugin) = 0;
|
||||||
|
virtual void GetPlugins(nsTArray<nsIObjectLoadingContent*>& aPlugins) = 0;
|
||||||
|
|
||||||
virtual nsresult GetStateObject(nsIVariant** aResult) = 0;
|
virtual nsresult GetStateObject(nsIVariant** aResult) = 0;
|
||||||
|
|
||||||
virtual nsDOMNavigationTiming* GetNavigationTiming() const = 0;
|
virtual nsDOMNavigationTiming* GetNavigationTiming() const = 0;
|
||||||
|
|
|
@ -52,7 +52,7 @@ interface nsIURI;
|
||||||
/**
|
/**
|
||||||
* This interface represents a content node that loads objects.
|
* This interface represents a content node that loads objects.
|
||||||
*/
|
*/
|
||||||
[scriptable, uuid(3FF07AB3-5BAC-4D98-9549-5BD15CCEBCD3)]
|
[scriptable, uuid(fd56fda8-d3c3-4368-8cf3-67dbc992aec9)]
|
||||||
interface nsIObjectLoadingContent : nsISupports
|
interface nsIObjectLoadingContent : nsISupports
|
||||||
{
|
{
|
||||||
const unsigned long TYPE_LOADING = 0;
|
const unsigned long TYPE_LOADING = 0;
|
||||||
|
@ -125,6 +125,12 @@ interface nsIObjectLoadingContent : nsISupports
|
||||||
*/
|
*/
|
||||||
void playPlugin();
|
void playPlugin();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This attribute will return true if the plugin has been activated
|
||||||
|
* and false if the plugin is still in the click-to-play state.
|
||||||
|
*/
|
||||||
|
readonly attribute boolean activated;
|
||||||
|
|
||||||
[noscript] void stopPluginInstance();
|
[noscript] void stopPluginInstance();
|
||||||
|
|
||||||
[noscript] void syncStartPluginInstance();
|
[noscript] void syncStartPluginInstance();
|
||||||
|
|
|
@ -1674,6 +1674,8 @@ nsDocument::~nsDocument()
|
||||||
// unlocked state, and then clear the table.
|
// unlocked state, and then clear the table.
|
||||||
SetImageLockingState(false);
|
SetImageLockingState(false);
|
||||||
mImageTracker.Clear();
|
mImageTracker.Clear();
|
||||||
|
|
||||||
|
mPlugins.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMPL_CYCLE_COLLECTION_CLASS(nsDocument)
|
NS_IMPL_CYCLE_COLLECTION_CLASS(nsDocument)
|
||||||
|
@ -2024,7 +2026,8 @@ nsDocument::Init()
|
||||||
mScriptLoader = new nsScriptLoader(this);
|
mScriptLoader = new nsScriptLoader(this);
|
||||||
NS_ENSURE_TRUE(mScriptLoader, NS_ERROR_OUT_OF_MEMORY);
|
NS_ENSURE_TRUE(mScriptLoader, NS_ERROR_OUT_OF_MEMORY);
|
||||||
|
|
||||||
if (!mImageTracker.Init()) {
|
if (!mImageTracker.Init() ||
|
||||||
|
!mPlugins.Init()) {
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8362,6 +8365,51 @@ nsDocument::RemoveImage(imgIRequest* aImage)
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
nsDocument::AddPlugin(nsIObjectLoadingContent* aPlugin)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(aPlugin);
|
||||||
|
if (!mPlugins.PutEntry(aPlugin)) {
|
||||||
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsDocument::RemovePlugin(nsIObjectLoadingContent* aPlugin)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(aPlugin);
|
||||||
|
mPlugins.RemoveEntry(aPlugin);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
AllSubDocumentPluginEnum(nsIDocument* aDocument, void* userArg)
|
||||||
|
{
|
||||||
|
nsTArray<nsIObjectLoadingContent*>* plugins =
|
||||||
|
reinterpret_cast< nsTArray<nsIObjectLoadingContent*>* >(userArg);
|
||||||
|
MOZ_ASSERT(plugins);
|
||||||
|
aDocument->GetPlugins(*plugins);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static PLDHashOperator
|
||||||
|
AllPluginEnum(nsPtrHashKey<nsIObjectLoadingContent>* aPlugin, void* userArg)
|
||||||
|
{
|
||||||
|
nsTArray<nsIObjectLoadingContent*>* allPlugins =
|
||||||
|
reinterpret_cast< nsTArray<nsIObjectLoadingContent*>* >(userArg);
|
||||||
|
MOZ_ASSERT(allPlugins);
|
||||||
|
allPlugins->AppendElement(aPlugin->GetKey());
|
||||||
|
return PL_DHASH_NEXT;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsDocument::GetPlugins(nsTArray<nsIObjectLoadingContent*>& aPlugins)
|
||||||
|
{
|
||||||
|
aPlugins.SetCapacity(aPlugins.Length() + mPlugins.Count());
|
||||||
|
mPlugins.EnumerateEntries(AllPluginEnum, &aPlugins);
|
||||||
|
EnumerateSubDocuments(AllSubDocumentPluginEnum, &aPlugins);
|
||||||
|
}
|
||||||
|
|
||||||
PLDHashOperator LockEnumerator(imgIRequest* aKey,
|
PLDHashOperator LockEnumerator(imgIRequest* aKey,
|
||||||
PRUint32 aData,
|
PRUint32 aData,
|
||||||
void* userArg)
|
void* userArg)
|
||||||
|
|
|
@ -935,6 +935,16 @@ public:
|
||||||
virtual NS_HIDDEN_(nsresult) RemoveImage(imgIRequest* aImage);
|
virtual NS_HIDDEN_(nsresult) RemoveImage(imgIRequest* aImage);
|
||||||
virtual NS_HIDDEN_(nsresult) SetImageLockingState(bool aLocked);
|
virtual NS_HIDDEN_(nsresult) SetImageLockingState(bool aLocked);
|
||||||
|
|
||||||
|
// AddPlugin adds a plugin-related element to mPlugins when the element is
|
||||||
|
// added to the tree.
|
||||||
|
virtual nsresult AddPlugin(nsIObjectLoadingContent* aPlugin);
|
||||||
|
// RemovePlugin removes a plugin-related element to mPlugins when the
|
||||||
|
// element is removed from the tree.
|
||||||
|
virtual void RemovePlugin(nsIObjectLoadingContent* aPlugin);
|
||||||
|
// GetPlugins returns the plugin-related elements from
|
||||||
|
// the frame and any subframes.
|
||||||
|
virtual void GetPlugins(nsTArray<nsIObjectLoadingContent*>& aPlugins);
|
||||||
|
|
||||||
virtual nsresult GetStateObject(nsIVariant** aResult);
|
virtual nsresult GetStateObject(nsIVariant** aResult);
|
||||||
|
|
||||||
virtual nsDOMNavigationTiming* GetNavigationTiming() const;
|
virtual nsDOMNavigationTiming* GetNavigationTiming() const;
|
||||||
|
@ -1304,6 +1314,9 @@ private:
|
||||||
// Tracking for images in the document.
|
// Tracking for images in the document.
|
||||||
nsDataHashtable< nsPtrHashKey<imgIRequest>, PRUint32> mImageTracker;
|
nsDataHashtable< nsPtrHashKey<imgIRequest>, PRUint32> mImageTracker;
|
||||||
|
|
||||||
|
// Tracking for plugins in the document.
|
||||||
|
nsTHashtable< nsPtrHashKey<nsIObjectLoadingContent> > mPlugins;
|
||||||
|
|
||||||
VisibilityState mVisibilityState;
|
VisibilityState mVisibilityState;
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
|
|
@ -115,6 +115,18 @@ static PRLogModuleInfo* gObjectLog = PR_NewLogModule("objlc");
|
||||||
|
|
||||||
#include "mozilla/Preferences.h"
|
#include "mozilla/Preferences.h"
|
||||||
|
|
||||||
|
static bool gClickToPlayPlugins = false;
|
||||||
|
|
||||||
|
static void
|
||||||
|
InitPrefCache()
|
||||||
|
{
|
||||||
|
static bool initializedPrefCache = false;
|
||||||
|
if (!initializedPrefCache) {
|
||||||
|
mozilla::Preferences::AddBoolVarCache(&gClickToPlayPlugins, "plugins.click_to_play");
|
||||||
|
}
|
||||||
|
initializedPrefCache = true;
|
||||||
|
}
|
||||||
|
|
||||||
class nsAsyncInstantiateEvent : public nsRunnable {
|
class nsAsyncInstantiateEvent : public nsRunnable {
|
||||||
public:
|
public:
|
||||||
nsObjectLoadingContent *mContent;
|
nsObjectLoadingContent *mContent;
|
||||||
|
@ -556,6 +568,26 @@ bool nsObjectLoadingContent::IsPluginEnabledByExtension(nsIURI* uri, nsCString&
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
nsObjectLoadingContent::BindToTree(nsIDocument* aDocument, nsIContent* /*aParent*/,
|
||||||
|
nsIContent* /*aBindingParent*/,
|
||||||
|
bool /*aCompileEventHandlers*/)
|
||||||
|
{
|
||||||
|
if (aDocument) {
|
||||||
|
return aDocument->AddPlugin(this);
|
||||||
|
}
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsObjectLoadingContent::UnbindFromTree(bool /*aDeep*/, bool /*aNullParent*/)
|
||||||
|
{
|
||||||
|
nsCOMPtr<nsIContent> thisContent = do_QueryInterface(static_cast<nsIObjectLoadingContent*>(this));
|
||||||
|
MOZ_ASSERT(thisContent);
|
||||||
|
nsIDocument* ownerDoc = thisContent->OwnerDoc();
|
||||||
|
ownerDoc->RemovePlugin(this);
|
||||||
|
}
|
||||||
|
|
||||||
nsObjectLoadingContent::nsObjectLoadingContent()
|
nsObjectLoadingContent::nsObjectLoadingContent()
|
||||||
: mPendingInstantiateEvent(nsnull)
|
: mPendingInstantiateEvent(nsnull)
|
||||||
, mChannel(nsnull)
|
, mChannel(nsnull)
|
||||||
|
@ -564,11 +596,14 @@ nsObjectLoadingContent::nsObjectLoadingContent()
|
||||||
, mUserDisabled(false)
|
, mUserDisabled(false)
|
||||||
, mSuppressed(false)
|
, mSuppressed(false)
|
||||||
, mNetworkCreated(true)
|
, mNetworkCreated(true)
|
||||||
// If plugins.click_to_play is false, plugins should always play
|
|
||||||
, mShouldPlay(!mozilla::Preferences::GetBool("plugins.click_to_play", false))
|
|
||||||
, mSrcStreamLoading(false)
|
, mSrcStreamLoading(false)
|
||||||
, mFallbackReason(ePluginOtherState)
|
, mFallbackReason(ePluginOtherState)
|
||||||
{
|
{
|
||||||
|
InitPrefCache();
|
||||||
|
// If plugins.click_to_play is false, plugins should always play
|
||||||
|
mShouldPlay = !gClickToPlayPlugins;
|
||||||
|
// If plugins.click_to_play is true, track the activated state of plugins.
|
||||||
|
mActivated = !gClickToPlayPlugins;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsObjectLoadingContent::~nsObjectLoadingContent()
|
nsObjectLoadingContent::~nsObjectLoadingContent()
|
||||||
|
@ -2216,5 +2251,13 @@ nsObjectLoadingContent::PlayPlugin()
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
|
||||||
mShouldPlay = true;
|
mShouldPlay = true;
|
||||||
|
mActivated = true;
|
||||||
return LoadObject(mURI, true, mContentType, true);
|
return LoadObject(mURI, true, mContentType, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsObjectLoadingContent::GetActivated(bool* aActivated)
|
||||||
|
{
|
||||||
|
*aActivated = mActivated;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
|
@ -244,6 +244,12 @@ class nsObjectLoadingContent : public nsImageLoadingContent
|
||||||
|
|
||||||
static void DoStopPlugin(nsPluginInstanceOwner *aInstanceOwner, bool aDelayedStop);
|
static void DoStopPlugin(nsPluginInstanceOwner *aInstanceOwner, bool aDelayedStop);
|
||||||
|
|
||||||
|
nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||||
|
nsIContent* aBindingParent,
|
||||||
|
bool aCompileEventHandler);
|
||||||
|
void UnbindFromTree(bool aDeep = true,
|
||||||
|
bool aNullParent = true);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void NotifyContentObjectWrapper();
|
void NotifyContentObjectWrapper();
|
||||||
|
@ -399,6 +405,10 @@ class nsObjectLoadingContent : public nsImageLoadingContent
|
||||||
// This is used for click-to-play plugins.
|
// This is used for click-to-play plugins.
|
||||||
bool mShouldPlay : 1;
|
bool mShouldPlay : 1;
|
||||||
|
|
||||||
|
// Used to keep track of whether or not a plugin has been played.
|
||||||
|
// This is used for click-to-play plugins.
|
||||||
|
bool mActivated : 1;
|
||||||
|
|
||||||
// Used to track when we might try to instantiate a plugin instance based on
|
// Used to track when we might try to instantiate a plugin instance based on
|
||||||
// a src data stream being delivered to this object. When this is true we don't
|
// a src data stream being delivered to this object. When this is true we don't
|
||||||
// want plugin instance instantiation code to attempt to load src data again or
|
// want plugin instance instantiation code to attempt to load src data again or
|
||||||
|
|
|
@ -265,6 +265,11 @@ nsHTMLObjectElement::BindToTree(nsIDocument *aDocument,
|
||||||
aCompileEventHandlers);
|
aCompileEventHandlers);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
rv = nsObjectLoadingContent::BindToTree(aDocument, aParent,
|
||||||
|
aBindingParent,
|
||||||
|
aCompileEventHandlers);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
// If we already have all the children, start the load.
|
// If we already have all the children, start the load.
|
||||||
if (mIsDoneAddingChildren) {
|
if (mIsDoneAddingChildren) {
|
||||||
void (nsHTMLObjectElement::*start)() = &nsHTMLObjectElement::StartObjectLoad;
|
void (nsHTMLObjectElement::*start)() = &nsHTMLObjectElement::StartObjectLoad;
|
||||||
|
@ -279,6 +284,7 @@ nsHTMLObjectElement::UnbindFromTree(bool aDeep,
|
||||||
bool aNullParent)
|
bool aNullParent)
|
||||||
{
|
{
|
||||||
RemovedFromDocument();
|
RemovedFromDocument();
|
||||||
|
nsObjectLoadingContent::UnbindFromTree(aDeep, aNullParent);
|
||||||
nsGenericHTMLFormElement::UnbindFromTree(aDeep, aNullParent);
|
nsGenericHTMLFormElement::UnbindFromTree(aDeep, aNullParent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -283,6 +283,11 @@ nsHTMLSharedObjectElement::BindToTree(nsIDocument *aDocument,
|
||||||
aCompileEventHandlers);
|
aCompileEventHandlers);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
rv = nsObjectLoadingContent::BindToTree(aDocument, aParent,
|
||||||
|
aBindingParent,
|
||||||
|
aCompileEventHandlers);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
// If we already have all the children, start the load.
|
// If we already have all the children, start the load.
|
||||||
if (mIsDoneAddingChildren) {
|
if (mIsDoneAddingChildren) {
|
||||||
void (nsHTMLSharedObjectElement::*start)() =
|
void (nsHTMLSharedObjectElement::*start)() =
|
||||||
|
@ -298,6 +303,7 @@ nsHTMLSharedObjectElement::UnbindFromTree(bool aDeep,
|
||||||
bool aNullParent)
|
bool aNullParent)
|
||||||
{
|
{
|
||||||
RemovedFromDocument();
|
RemovedFromDocument();
|
||||||
|
nsObjectLoadingContent::UnbindFromTree(aDeep, aNullParent);
|
||||||
nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent);
|
nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -51,6 +51,7 @@
|
||||||
#include "nsRefreshDriver.h"
|
#include "nsRefreshDriver.h"
|
||||||
#include "nsDOMTouchEvent.h"
|
#include "nsDOMTouchEvent.h"
|
||||||
#include "nsIDOMTouchEvent.h"
|
#include "nsIDOMTouchEvent.h"
|
||||||
|
#include "nsObjectLoadingContent.h"
|
||||||
|
|
||||||
#include "nsIScrollableFrame.h"
|
#include "nsIScrollableFrame.h"
|
||||||
|
|
||||||
|
@ -76,6 +77,7 @@
|
||||||
#include "nsCSSProps.h"
|
#include "nsCSSProps.h"
|
||||||
#include "nsDOMFile.h"
|
#include "nsDOMFile.h"
|
||||||
#include "BasicLayers.h"
|
#include "BasicLayers.h"
|
||||||
|
#include "nsTArrayHelpers.h"
|
||||||
|
|
||||||
#if defined(MOZ_X11) && defined(MOZ_WIDGET_GTK2)
|
#if defined(MOZ_X11) && defined(MOZ_WIDGET_GTK2)
|
||||||
#include <gdk/gdk.h>
|
#include <gdk/gdk.h>
|
||||||
|
@ -2230,3 +2232,26 @@ nsDOMWindowUtils::GetPaintingSuppressed(bool *aPaintingSuppressed)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsDOMWindowUtils::GetPlugins(JSContext* cx, jsval* aPlugins)
|
||||||
|
{
|
||||||
|
if (!IsUniversalXPConnectCapable()) {
|
||||||
|
return NS_ERROR_DOM_SECURITY_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsIDOMDocument* ddoc = mWindow->GetExtantDocument();
|
||||||
|
|
||||||
|
nsresult rv;
|
||||||
|
nsCOMPtr<nsIDocument> doc = do_QueryInterface(ddoc, &rv);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
nsTArray<nsIObjectLoadingContent*> plugins;
|
||||||
|
doc->GetPlugins(plugins);
|
||||||
|
|
||||||
|
JSObject* jsPlugins = nsnull;
|
||||||
|
rv = nsTArrayToJSArray(cx, plugins, &jsPlugins);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
*aPlugins = OBJECT_TO_JSVAL(jsPlugins);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
|
@ -70,7 +70,7 @@ interface nsIDOMFile;
|
||||||
interface nsIFile;
|
interface nsIFile;
|
||||||
interface nsIDOMTouch;
|
interface nsIDOMTouch;
|
||||||
|
|
||||||
[scriptable, uuid(43feb172-30e1-4ff1-b021-004f973da516)]
|
[scriptable, uuid(c7f303a1-4f7b-4d38-a192-c3f0e25dadb1)]
|
||||||
interface nsIDOMWindowUtils : nsISupports {
|
interface nsIDOMWindowUtils : nsISupports {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1099,4 +1099,15 @@ interface nsIDOMWindowUtils : nsISupports {
|
||||||
* otherwise.
|
* otherwise.
|
||||||
*/
|
*/
|
||||||
readonly attribute boolean paintingSuppressed;
|
readonly attribute boolean paintingSuppressed;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an array of plugins on the page for opt-in activation.
|
||||||
|
*
|
||||||
|
* Cannot be accessed from unprivileged context (not content-accessible).
|
||||||
|
* Will throw a DOM security error if called without UniversalXPConnect
|
||||||
|
* privileges.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
[implicit_jscontext]
|
||||||
|
readonly attribute jsval plugins;
|
||||||
};
|
};
|
||||||
|
|
|
@ -4090,7 +4090,7 @@ JS_SetElement(JSContext *cx, JSObject *obj, uint32_t index, jsval *vp)
|
||||||
{
|
{
|
||||||
AssertNoGC(cx);
|
AssertNoGC(cx);
|
||||||
CHECK_REQUEST(cx);
|
CHECK_REQUEST(cx);
|
||||||
assertSameCompartment(cx, obj);
|
assertSameCompartment(cx, obj, *vp);
|
||||||
JSAutoResolveFlags rf(cx, JSRESOLVE_QUALIFIED | JSRESOLVE_ASSIGNING);
|
JSAutoResolveFlags rf(cx, JSRESOLVE_QUALIFIED | JSRESOLVE_ASSIGNING);
|
||||||
return obj->setElement(cx, index, vp, false);
|
return obj->setElement(cx, index, vp, false);
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,6 +49,7 @@ EXPORTS = \
|
||||||
nsAXPCNativeCallContext.h \
|
nsAXPCNativeCallContext.h \
|
||||||
xpc_map_end.h \
|
xpc_map_end.h \
|
||||||
nsAutoJSValHolder.h \
|
nsAutoJSValHolder.h \
|
||||||
|
nsTArrayHelpers.h \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
include $(topsrcdir)/config/rules.mk
|
include $(topsrcdir)/config/rules.mk
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||||
|
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#ifndef __NSTARRAYHELPERS_H__
|
||||||
|
#define __NSTARRAYHELPERS_H__
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline nsresult
|
||||||
|
nsTArrayToJSArray(JSContext* aCx, const nsTArray<T>& aSourceArray,
|
||||||
|
JSObject** aResultArray)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(aCx);
|
||||||
|
JSAutoRequest ar(aCx);
|
||||||
|
|
||||||
|
JSObject* arrayObj = JS_NewArrayObject(aCx, aSourceArray.Length(), nsnull);
|
||||||
|
if (!arrayObj) {
|
||||||
|
NS_WARNING("JS_NewArrayObject failed!");
|
||||||
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
JSObject* global = JS_GetGlobalForScopeChain(aCx);
|
||||||
|
MOZ_ASSERT(global);
|
||||||
|
|
||||||
|
for (PRUint32 index = 0; index < aSourceArray.Length(); index++) {
|
||||||
|
nsCOMPtr<nsISupports> obj;
|
||||||
|
nsresult rv = CallQueryInterface(aSourceArray[index], getter_AddRefs(obj));
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
jsval wrappedVal;
|
||||||
|
rv = nsContentUtils::WrapNative(aCx, global, obj, &wrappedVal, nsnull, true);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
if (!JS_SetElement(aCx, arrayObj, index, &wrappedVal)) {
|
||||||
|
NS_WARNING("JS_SetElement failed!");
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!JS_FreezeObject(aCx, arrayObj)) {
|
||||||
|
NS_WARNING("JS_FreezeObject failed!");
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
*aResultArray = arrayObj;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* __NSTARRAYHELPERS_H__ */
|
Загрузка…
Ссылка в новой задаче