mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
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:
parent
ac6701a55b
commit
5c1c03e064
@ -111,6 +111,7 @@ class imgIRequest;
|
||||
class nsISHEntry;
|
||||
class nsDOMNavigationTiming;
|
||||
class nsWindowSizes;
|
||||
class nsIObjectLoadingContent;
|
||||
|
||||
namespace mozilla {
|
||||
namespace css {
|
||||
@ -1570,6 +1571,10 @@ public:
|
||||
// state is unlocked/false.
|
||||
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 nsDOMNavigationTiming* GetNavigationTiming() const = 0;
|
||||
|
@ -52,7 +52,7 @@ interface nsIURI;
|
||||
/**
|
||||
* 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
|
||||
{
|
||||
const unsigned long TYPE_LOADING = 0;
|
||||
@ -125,6 +125,12 @@ interface nsIObjectLoadingContent : nsISupports
|
||||
*/
|
||||
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 syncStartPluginInstance();
|
||||
|
@ -1674,6 +1674,8 @@ nsDocument::~nsDocument()
|
||||
// unlocked state, and then clear the table.
|
||||
SetImageLockingState(false);
|
||||
mImageTracker.Clear();
|
||||
|
||||
mPlugins.Clear();
|
||||
}
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(nsDocument)
|
||||
@ -2024,7 +2026,8 @@ nsDocument::Init()
|
||||
mScriptLoader = new nsScriptLoader(this);
|
||||
NS_ENSURE_TRUE(mScriptLoader, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
if (!mImageTracker.Init()) {
|
||||
if (!mImageTracker.Init() ||
|
||||
!mPlugins.Init()) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
@ -8361,6 +8364,51 @@ nsDocument::RemoveImage(imgIRequest* aImage)
|
||||
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,
|
||||
PRUint32 aData,
|
||||
void* userArg)
|
||||
|
@ -935,6 +935,16 @@ public:
|
||||
virtual NS_HIDDEN_(nsresult) RemoveImage(imgIRequest* aImage);
|
||||
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 nsDOMNavigationTiming* GetNavigationTiming() const;
|
||||
@ -1300,6 +1310,9 @@ private:
|
||||
// Tracking for images in the document.
|
||||
nsDataHashtable< nsPtrHashKey<imgIRequest>, PRUint32> mImageTracker;
|
||||
|
||||
// Tracking for plugins in the document.
|
||||
nsTHashtable< nsPtrHashKey<nsIObjectLoadingContent> > mPlugins;
|
||||
|
||||
VisibilityState mVisibilityState;
|
||||
|
||||
#ifdef DEBUG
|
||||
|
@ -115,6 +115,18 @@ static PRLogModuleInfo* gObjectLog = PR_NewLogModule("objlc");
|
||||
|
||||
#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 {
|
||||
public:
|
||||
nsObjectLoadingContent *mContent;
|
||||
@ -546,6 +558,26 @@ bool nsObjectLoadingContent::IsPluginEnabledByExtension(nsIURI* uri, nsCString&
|
||||
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()
|
||||
: mPendingInstantiateEvent(nsnull)
|
||||
, mChannel(nsnull)
|
||||
@ -554,11 +586,14 @@ nsObjectLoadingContent::nsObjectLoadingContent()
|
||||
, mUserDisabled(false)
|
||||
, mSuppressed(false)
|
||||
, mNetworkCreated(true)
|
||||
// If plugins.click_to_play is false, plugins should always play
|
||||
, mShouldPlay(!mozilla::Preferences::GetBool("plugins.click_to_play", false))
|
||||
, mSrcStreamLoading(false)
|
||||
, 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()
|
||||
@ -2206,5 +2241,13 @@ nsObjectLoadingContent::PlayPlugin()
|
||||
return NS_OK;
|
||||
|
||||
mShouldPlay = true;
|
||||
mActivated = 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);
|
||||
|
||||
nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
nsIContent* aBindingParent,
|
||||
bool aCompileEventHandler);
|
||||
void UnbindFromTree(bool aDeep = true,
|
||||
bool aNullParent = true);
|
||||
|
||||
private:
|
||||
|
||||
void NotifyContentObjectWrapper();
|
||||
@ -399,6 +405,10 @@ class nsObjectLoadingContent : public nsImageLoadingContent
|
||||
// This is used for click-to-play plugins.
|
||||
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
|
||||
// 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
|
||||
|
@ -265,6 +265,11 @@ nsHTMLObjectElement::BindToTree(nsIDocument *aDocument,
|
||||
aCompileEventHandlers);
|
||||
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 (mIsDoneAddingChildren) {
|
||||
void (nsHTMLObjectElement::*start)() = &nsHTMLObjectElement::StartObjectLoad;
|
||||
@ -279,6 +284,7 @@ nsHTMLObjectElement::UnbindFromTree(bool aDeep,
|
||||
bool aNullParent)
|
||||
{
|
||||
RemovedFromDocument();
|
||||
nsObjectLoadingContent::UnbindFromTree(aDeep, aNullParent);
|
||||
nsGenericHTMLFormElement::UnbindFromTree(aDeep, aNullParent);
|
||||
}
|
||||
|
||||
|
@ -283,6 +283,11 @@ nsHTMLSharedObjectElement::BindToTree(nsIDocument *aDocument,
|
||||
aCompileEventHandlers);
|
||||
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 (mIsDoneAddingChildren) {
|
||||
void (nsHTMLSharedObjectElement::*start)() =
|
||||
@ -298,6 +303,7 @@ nsHTMLSharedObjectElement::UnbindFromTree(bool aDeep,
|
||||
bool aNullParent)
|
||||
{
|
||||
RemovedFromDocument();
|
||||
nsObjectLoadingContent::UnbindFromTree(aDeep, aNullParent);
|
||||
nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent);
|
||||
}
|
||||
|
||||
|
@ -51,6 +51,7 @@
|
||||
#include "nsRefreshDriver.h"
|
||||
#include "nsDOMTouchEvent.h"
|
||||
#include "nsIDOMTouchEvent.h"
|
||||
#include "nsObjectLoadingContent.h"
|
||||
|
||||
#include "nsIScrollableFrame.h"
|
||||
|
||||
@ -76,6 +77,7 @@
|
||||
#include "nsCSSProps.h"
|
||||
#include "nsDOMFile.h"
|
||||
#include "BasicLayers.h"
|
||||
#include "nsTArrayHelpers.h"
|
||||
|
||||
#if defined(MOZ_X11) && defined(MOZ_WIDGET_GTK2)
|
||||
#include <gdk/gdk.h>
|
||||
@ -2230,3 +2232,26 @@ nsDOMWindowUtils::GetPaintingSuppressed(bool *aPaintingSuppressed)
|
||||
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 nsIDOMTouch;
|
||||
|
||||
[scriptable, uuid(43feb172-30e1-4ff1-b021-004f973da516)]
|
||||
[scriptable, uuid(c7f303a1-4f7b-4d38-a192-c3f0e25dadb1)]
|
||||
interface nsIDOMWindowUtils : nsISupports {
|
||||
|
||||
/**
|
||||
@ -1099,4 +1099,15 @@ interface nsIDOMWindowUtils : nsISupports {
|
||||
* otherwise.
|
||||
*/
|
||||
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;
|
||||
};
|
||||
|
@ -4101,7 +4101,7 @@ JS_SetElement(JSContext *cx, JSObject *obj, uint32_t index, jsval *vp)
|
||||
{
|
||||
AssertNoGC(cx);
|
||||
CHECK_REQUEST(cx);
|
||||
assertSameCompartment(cx, obj);
|
||||
assertSameCompartment(cx, obj, *vp);
|
||||
JSAutoResolveFlags rf(cx, JSRESOLVE_QUALIFIED | JSRESOLVE_ASSIGNING);
|
||||
return obj->setElement(cx, index, vp, false);
|
||||
}
|
||||
|
@ -49,6 +49,7 @@ EXPORTS = \
|
||||
nsAXPCNativeCallContext.h \
|
||||
xpc_map_end.h \
|
||||
nsAutoJSValHolder.h \
|
||||
nsTArrayHelpers.h \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
49
js/xpconnect/public/nsTArrayHelpers.h
Normal file
49
js/xpconnect/public/nsTArrayHelpers.h
Normal file
@ -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__ */
|
Loading…
Reference in New Issue
Block a user