mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-10 20:05:49 +00:00
Merge m-c to s-c
This commit is contained in:
commit
6c715c1626
@ -66,6 +66,7 @@ pref("image.cache.size", 1048576); // bytes
|
||||
|
||||
/* offline cache prefs */
|
||||
pref("browser.offline-apps.notify", false);
|
||||
pref("browser.cache.offline.enable", false);
|
||||
|
||||
/* protocol warning prefs */
|
||||
pref("network.protocol-handler.warn-external.tel", false);
|
||||
|
@ -72,11 +72,19 @@ function startupHttpd(baseDir, port) {
|
||||
server.start(port);
|
||||
}
|
||||
|
||||
// XXX until we have a security model, just let the pre-installed
|
||||
// app used indexedDB.
|
||||
function allowIndexedDB(url) {
|
||||
let uri = Services.io.newURI(url, null, null);
|
||||
Services.perms.add(uri, 'indexedDB', Ci.nsIPermissionManager.ALLOW_ACTION);
|
||||
// FIXME Bug 707625
|
||||
// until we have a proper security model, add some rights to
|
||||
// the pre-installed web applications
|
||||
function addPermissions(urls) {
|
||||
let permissions = ['indexedDB', 'webapps-manage', 'offline-app'];
|
||||
urls.forEach(function(url) {
|
||||
let uri = Services.io.newURI(url, null, null);
|
||||
let allow = Ci.nsIPermissionManager.ALLOW_ACTION;
|
||||
|
||||
permissions.forEach(function(permission) {
|
||||
Services.perms.add(uri, permission, allow);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -135,7 +143,7 @@ var shell = {
|
||||
let baseHost = 'http://localhost';
|
||||
homeURL = homeURL.replace(baseDir, baseHost + ':' + SERVER_PORT);
|
||||
}
|
||||
allowIndexedDB(homeURL);
|
||||
addPermissions([homeURL]);
|
||||
} catch (e) {
|
||||
let msg = 'Fatal error during startup: [' + e + '[' + homeURL + ']';
|
||||
return alert(msg);
|
||||
@ -172,7 +180,7 @@ var shell = {
|
||||
doCommand: function shell_doCommand(cmd) {
|
||||
switch (cmd) {
|
||||
case 'cmd_close':
|
||||
this.sendEvent(this.home.contentWindow, 'appclose');
|
||||
this.home.contentWindow.postMessage('appclose', '*');
|
||||
break;
|
||||
}
|
||||
},
|
||||
@ -200,6 +208,9 @@ var shell = {
|
||||
break;
|
||||
case 'MozApplicationManifest':
|
||||
try {
|
||||
if (!Services.prefs.getBoolPref('browser.cache.offline.enable'))
|
||||
return;
|
||||
|
||||
let contentWindow = evt.originalTarget.defaultView;
|
||||
let documentElement = contentWindow.document.documentElement;
|
||||
if (!documentElement)
|
||||
@ -210,10 +221,18 @@ var shell = {
|
||||
return;
|
||||
|
||||
let documentURI = contentWindow.document.documentURIObject;
|
||||
let manifestURI = Services.io.newURI(manifest, null, documentURI);
|
||||
if (!Services.perms.testPermission(documentURI, 'offline-app')) {
|
||||
if (Services.prefs.getBoolPref('browser.offline-apps.notify')) {
|
||||
// FIXME Bug 710729 - Add a UI for offline cache notifications
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
Services.perms.add(documentURI, 'offline-app',
|
||||
Ci.nsIPermissionManager.ALLOW_ACTION);
|
||||
|
||||
let manifestURI = Services.io.newURI(manifest, null, documentURI);
|
||||
let updateService = Cc['@mozilla.org/offlinecacheupdate-service;1']
|
||||
.getService(Ci.nsIOfflineCacheUpdateService);
|
||||
updateService.scheduleUpdate(manifestURI, documentURI, window);
|
||||
|
@ -394,7 +394,7 @@
|
||||
ClearErrors
|
||||
ReadRegStr $1 HKLM "Software\Classes\FirefoxHTML\ShellEx\IconHandler" ""
|
||||
${Unless} ${Errors}
|
||||
ReadRegStr $1 HKLM "Software\Classes\FirefoxHTML\" ""
|
||||
ReadRegStr $1 HKLM "Software\Classes\FirefoxHTML\DefaultIcon" ""
|
||||
${GetLongPath} "$INSTDIR\${FileMainEXE}" $2
|
||||
${If} "$1" != "$2,1"
|
||||
WriteRegStr HKLM "Software\Classes\FirefoxHTML\DefaultIcon" "" "$2,1"
|
||||
|
@ -398,6 +398,11 @@ user_pref("extensions.update.url", "http://%(server)s/extensions-dummy/updateURL
|
||||
user_pref("extensions.blocklist.url", "http://%(server)s/extensions-dummy/blocklistURL");
|
||||
// Make sure opening about:addons won't hit the network
|
||||
user_pref("extensions.webservice.discoverURL", "http://%(server)s/extensions-dummy/discoveryURL");
|
||||
// Make sure AddonRepository won't hit the network
|
||||
user_pref("extensions.getAddons.maxResults", 0);
|
||||
user_pref("extensions.getAddons.get.url", "http://%(server)s/extensions-dummy/repositoryGetURL");
|
||||
user_pref("extensions.getAddons.search.browseURL", "http://%(server)s/extensions-dummy/repositoryBrowseURL");
|
||||
user_pref("extensions.getAddons.search.url", "http://%(server)s/extensions-dummy/repositorySearchURL");
|
||||
""" % { "server" : self.webServer + ":" + str(self.httpPort) }
|
||||
prefs.append(part)
|
||||
|
||||
|
@ -51,7 +51,7 @@ interface nsIDOMClientRect;
|
||||
/**
|
||||
* This interface represents a content node that loads objects.
|
||||
*/
|
||||
[scriptable, uuid(107e8048-d00f-4711-bd21-97184ccae0b1)]
|
||||
[scriptable, uuid(e5330f90-91a3-41d7-b29e-af38a23a6602)]
|
||||
interface nsIObjectLoadingContent : nsISupports
|
||||
{
|
||||
const unsigned long TYPE_LOADING = 0;
|
||||
@ -125,4 +125,10 @@ interface nsIObjectLoadingContent : nsISupports
|
||||
in AString pluginDumpID,
|
||||
in AString browserDumpID,
|
||||
in boolean submittedCrashReport);
|
||||
|
||||
/**
|
||||
* This method will play a plugin that has been stopped by the
|
||||
* click-to-play plugins feature.
|
||||
*/
|
||||
void playPlugin();
|
||||
};
|
||||
|
@ -105,10 +105,7 @@ static PRLogModuleInfo* gObjectLog = PR_NewLogModule("objlc");
|
||||
#define LOG(args) PR_LOG(gObjectLog, PR_LOG_DEBUG, args)
|
||||
#define LOG_ENABLED() PR_LOG_TEST(gObjectLog, PR_LOG_DEBUG)
|
||||
|
||||
#ifdef ANDROID
|
||||
#include "nsXULAppAPI.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#endif
|
||||
|
||||
class nsAsyncInstantiateEvent : public nsRunnable {
|
||||
public:
|
||||
@ -428,14 +425,14 @@ IsSupportedImage(const nsCString& aMimeType)
|
||||
}
|
||||
|
||||
static bool
|
||||
IsSupportedPlugin(const nsCString& aMIMEType)
|
||||
IsSupportedPlugin(const nsCString& aMIMEType, bool aShouldPlay)
|
||||
{
|
||||
nsCOMPtr<nsIPluginHost> pluginHostCOM(do_GetService(MOZ_PLUGIN_HOST_CONTRACTID));
|
||||
nsPluginHost *pluginHost = static_cast<nsPluginHost*>(pluginHostCOM.get());
|
||||
if (!pluginHost) {
|
||||
return false;
|
||||
}
|
||||
nsresult rv = pluginHost->IsPluginEnabledForType(aMIMEType.get());
|
||||
nsresult rv = pluginHost->IsPluginEnabledForType(aMIMEType.get(), aShouldPlay);
|
||||
return NS_SUCCEEDED(rv);
|
||||
}
|
||||
|
||||
@ -461,7 +458,7 @@ GetExtensionFromURI(nsIURI* uri, nsCString& ext)
|
||||
* in the given URI. The MIME type is returned in the mimeType out parameter.
|
||||
*/
|
||||
static bool
|
||||
IsPluginEnabledByExtension(nsIURI* uri, nsCString& mimeType)
|
||||
IsPluginEnabledByExtension(nsIURI* uri, nsCString& mimeType, bool aShouldPlay)
|
||||
{
|
||||
nsCAutoString ext;
|
||||
GetExtensionFromURI(uri, ext);
|
||||
@ -477,7 +474,8 @@ IsPluginEnabledByExtension(nsIURI* uri, nsCString& mimeType)
|
||||
}
|
||||
|
||||
const char* typeFromExt;
|
||||
if (NS_SUCCEEDED(pluginHost->IsPluginEnabledForExtension(ext.get(), typeFromExt))) {
|
||||
if (NS_SUCCEEDED(pluginHost->IsPluginEnabledForExtension(ext.get(), typeFromExt,
|
||||
aShouldPlay))) {
|
||||
mimeType = typeFromExt;
|
||||
return true;
|
||||
}
|
||||
@ -492,6 +490,8 @@ 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))
|
||||
, mFallbackReason(ePluginOtherState)
|
||||
{
|
||||
}
|
||||
@ -553,7 +553,7 @@ nsObjectLoadingContent::OnStartRequest(nsIRequest *aRequest,
|
||||
// Need to check IsSupportedPlugin() in addition to GetTypeOfContent()
|
||||
// because otherwise the default plug-in's catch-all behavior would
|
||||
// confuse things.
|
||||
(IsSupportedPlugin(mContentType) &&
|
||||
(IsSupportedPlugin(mContentType, mShouldPlay) &&
|
||||
GetTypeOfContent(mContentType) == eType_Plugin)) {
|
||||
// Set the type we'll use for dispatch on the channel. Otherwise we could
|
||||
// end up trying to dispatch to a nsFrameLoader, which will complain that
|
||||
@ -573,7 +573,7 @@ nsObjectLoadingContent::OnStartRequest(nsIRequest *aRequest,
|
||||
|
||||
if (mContentType.EqualsASCII(APPLICATION_OCTET_STREAM)) {
|
||||
nsCAutoString extType;
|
||||
if (IsPluginEnabledByExtension(uri, extType)) {
|
||||
if (IsPluginEnabledByExtension(uri, extType, mShouldPlay)) {
|
||||
mContentType = extType;
|
||||
chan->SetContentType(extType);
|
||||
}
|
||||
@ -1273,8 +1273,8 @@ nsObjectLoadingContent::LoadObject(nsIURI* aURI,
|
||||
|
||||
nsCAutoString overrideType;
|
||||
if ((caps & eOverrideServerType) &&
|
||||
((!aTypeHint.IsEmpty() && IsSupportedPlugin(aTypeHint)) ||
|
||||
(aURI && IsPluginEnabledByExtension(aURI, overrideType)))) {
|
||||
((!aTypeHint.IsEmpty() && IsSupportedPlugin(aTypeHint, mShouldPlay)) ||
|
||||
(aURI && IsPluginEnabledByExtension(aURI, overrideType, mShouldPlay)))) {
|
||||
ObjectType newType;
|
||||
if (overrideType.IsEmpty()) {
|
||||
newType = GetTypeOfContent(aTypeHint);
|
||||
@ -1412,7 +1412,7 @@ nsObjectLoadingContent::LoadObject(nsIURI* aURI,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (IsSupportedPlugin(aTypeHint)) {
|
||||
if (IsSupportedPlugin(aTypeHint, mShouldPlay)) {
|
||||
mType = eType_Plugin;
|
||||
|
||||
rv = TryInstantiate(aTypeHint, aURI);
|
||||
@ -1714,7 +1714,7 @@ nsObjectLoadingContent::GetTypeOfContent(const nsCString& aMIMEType)
|
||||
return eType_Document;
|
||||
}
|
||||
|
||||
if ((caps & eSupportPlugins) && IsSupportedPlugin(aMIMEType)) {
|
||||
if ((caps & eSupportPlugins) && IsSupportedPlugin(aMIMEType, mShouldPlay)) {
|
||||
return eType_Plugin;
|
||||
}
|
||||
|
||||
@ -1875,7 +1875,7 @@ nsObjectLoadingContent::Instantiate(nsIObjectFrame* aFrame,
|
||||
|
||||
nsCString typeToUse(aMIMEType);
|
||||
if (typeToUse.IsEmpty() && aURI) {
|
||||
IsPluginEnabledByExtension(aURI, typeToUse);
|
||||
IsPluginEnabledByExtension(aURI, typeToUse, mShouldPlay);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIContent> thisContent =
|
||||
@ -1962,12 +1962,6 @@ nsObjectLoadingContent::GetPluginSupportState(nsIContent* aContent,
|
||||
/* static */ PluginSupportState
|
||||
nsObjectLoadingContent::GetPluginDisabledState(const nsCString& aContentType)
|
||||
{
|
||||
#ifdef ANDROID
|
||||
// if plugins are disabled, don't show the click to play message
|
||||
if (!mozilla::Preferences::GetBool("plugin.disable", false) &&
|
||||
XRE_GetProcessType() == GeckoProcessType_Content)
|
||||
return ePluginClickToPlay;
|
||||
#endif
|
||||
nsCOMPtr<nsIPluginHost> pluginHostCOM(do_GetService(MOZ_PLUGIN_HOST_CONTRACTID));
|
||||
nsPluginHost *pluginHost = static_cast<nsPluginHost*>(pluginHostCOM.get());
|
||||
if (!pluginHost) {
|
||||
@ -1977,6 +1971,8 @@ nsObjectLoadingContent::GetPluginDisabledState(const nsCString& aContentType)
|
||||
nsresult rv = pluginHost->IsPluginEnabledForType(aContentType.get());
|
||||
if (rv == NS_ERROR_PLUGIN_DISABLED)
|
||||
return ePluginDisabled;
|
||||
if (rv == NS_ERROR_PLUGIN_CLICKTOPLAY)
|
||||
return ePluginClickToPlay;
|
||||
if (rv == NS_ERROR_PLUGIN_BLOCKLISTED)
|
||||
return ePluginBlocklisted;
|
||||
return ePluginUnsupported;
|
||||
@ -2046,3 +2042,13 @@ nsObjectLoadingContent::PluginCrashed(nsIPluginTag* aPluginTag,
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsObjectLoadingContent::PlayPlugin()
|
||||
{
|
||||
if (!nsContentUtils::IsCallerChrome())
|
||||
return NS_OK;
|
||||
|
||||
mShouldPlay = true;
|
||||
return LoadObject(mURI, true, mContentType, true);
|
||||
}
|
||||
|
@ -66,7 +66,7 @@ enum PluginSupportState {
|
||||
ePluginOutdated, // The plugin is considered outdated, but not disabled
|
||||
ePluginOtherState, // Something else (e.g. uninitialized or not a plugin)
|
||||
ePluginCrashed,
|
||||
ePluginClickToPlay
|
||||
ePluginClickToPlay // The plugin is disabled until the user clicks on it
|
||||
};
|
||||
|
||||
/**
|
||||
@ -410,6 +410,10 @@ class nsObjectLoadingContent : public nsImageLoadingContent
|
||||
// it may lose the flag.
|
||||
bool mNetworkCreated : 1;
|
||||
|
||||
// Used to keep track of whether or not a plugin should be played.
|
||||
// This is used for click-to-play plugins.
|
||||
bool mShouldPlay : 1;
|
||||
|
||||
// A specific state that caused us to fallback
|
||||
PluginSupportState mFallbackReason;
|
||||
|
||||
|
@ -1096,13 +1096,16 @@ WebGLContext::MaybeRestoreContext()
|
||||
if (mContextLost || mAllowRestore)
|
||||
return;
|
||||
|
||||
bool isEGL = gl->GetContextType() == GLContext::ContextTypeEGL,
|
||||
isANGLE = gl->IsANGLE();
|
||||
|
||||
GLContext::ContextResetARB resetStatus = GLContext::CONTEXT_NO_ERROR;
|
||||
if (mHasRobustness) {
|
||||
gl->MakeCurrent();
|
||||
resetStatus = (GLContext::ContextResetARB) gl->fGetGraphicsResetStatus();
|
||||
// This call is safe as it does not actually interact with GL, so the
|
||||
// context does not have to be current.
|
||||
} else if (gl->GetContextType() == GLContext::ContextTypeEGL) {
|
||||
} else if (isEGL) {
|
||||
// Simulate a ARB_robustness guilty context loss for when we
|
||||
// get an EGL_CONTEXT_LOST error. It may not actually be guilty,
|
||||
// but we can't make any distinction, so we must assume the worst
|
||||
@ -1133,6 +1136,13 @@ WebGLContext::MaybeRestoreContext()
|
||||
break;
|
||||
case GLContext::CONTEXT_UNKNOWN_CONTEXT_RESET_ARB:
|
||||
NS_WARNING("WebGL content on the page might have caused the graphics card to reset");
|
||||
if (isEGL && isANGLE) {
|
||||
// If we're using ANGLE, we ONLY get back UNKNOWN context resets, including for guilty contexts.
|
||||
// This means that we can't restore it or risk restoring a guilty context. Should this ever change,
|
||||
// we can get rid of the whole IsANGLE() junk from GLContext.h since, as of writing, this is the
|
||||
// only use for it. See ANGLE issue 261.
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -4355,9 +4355,18 @@ WebGLContext::CompileShader(nsIWebGLShader *sobj)
|
||||
if (mEnabledExtensions[WebGL_OES_standard_derivatives])
|
||||
resources.OES_standard_derivatives = 1;
|
||||
|
||||
// notice that on Android, we always use SH_GLSL_OUTPUT, we never use the ESSL backend.
|
||||
// see bug 709947, the reason is that 1) we dont really need a ESSL backend since the
|
||||
// source is already ESSL, and 2) we ran into massive Android crashes when we used the ESSL backend.
|
||||
// But if we wanted to use shader transformations on ES platforms, we would have to use the
|
||||
// ESSL backend
|
||||
compiler = ShConstructCompiler((ShShaderType) shader->ShaderType(),
|
||||
SH_WEBGL_SPEC,
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
SH_GLSL_OUTPUT,
|
||||
#else
|
||||
gl->IsGLES2() ? SH_ESSL_OUTPUT : SH_GLSL_OUTPUT,
|
||||
#endif
|
||||
&resources);
|
||||
|
||||
// We're storing an actual instance of StripComments because, if we don't, the
|
||||
|
@ -146,4 +146,8 @@ nsresult
|
||||
NS_NewDOMCustomEvent(nsIDOMEvent** aInstancePtrResult, nsPresContext* aPresContext, nsEvent* aEvent);
|
||||
nsresult
|
||||
NS_NewDOMSmsEvent(nsIDOMEvent** aInstancePtrResult, nsPresContext* aPresContext, nsEvent* aEvent);
|
||||
nsresult
|
||||
NS_NewDOMPopStateEvent(nsIDOMEvent** aInstancePtrResult, nsPresContext* aPresContext, nsEvent* aEvent);
|
||||
nsresult
|
||||
NS_NewDOMHashChangeEvent(nsIDOMEvent** aInstancePtrResult, nsPresContext* aPresContext, nsEvent* aEvent);
|
||||
#endif // nsIPrivateDOMEvent_h__
|
||||
|
@ -88,6 +88,34 @@ nsDOMCloseEvent::InitCloseEvent(const nsAString& aType,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDOMCloseEvent::InitFromCtor(const nsAString& aType, nsISupports* aDict,
|
||||
JSContext* aCx, JSObject* aObj)
|
||||
{
|
||||
nsCOMPtr<nsICloseEventInit> eventInit = do_QueryInterface(aDict);
|
||||
bool bubbles = false;
|
||||
bool cancelable = false;
|
||||
bool wasClean = false;
|
||||
PRUint16 code = 0;
|
||||
nsAutoString reason;
|
||||
if (eventInit) {
|
||||
nsresult rv = eventInit->GetBubbles(&bubbles);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = eventInit->GetCancelable(&cancelable);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = eventInit->GetWasClean(&wasClean);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = eventInit->GetCode(&code);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
JSBool found = JS_FALSE;
|
||||
if (JS_HasProperty(aCx, aObj, "reason", &found) && found) {
|
||||
rv = eventInit->GetReason(reason);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
}
|
||||
return InitCloseEvent(aType, bubbles, cancelable, wasClean, code, reason);
|
||||
}
|
||||
|
||||
nsresult
|
||||
NS_NewDOMCloseEvent(nsIDOMEvent** aInstancePtrResult,
|
||||
nsPresContext* aPresContext,
|
||||
|
@ -64,6 +64,9 @@ public:
|
||||
|
||||
NS_DECL_NSIDOMCLOSEEVENT
|
||||
|
||||
virtual const nsIID& EventInitIID() { return NS_GET_IID(nsICloseEventInit); }
|
||||
virtual nsresult InitFromCtor(const nsAString& aType, nsISupports* aDict,
|
||||
JSContext* aCx, JSObject* aObj);
|
||||
private:
|
||||
bool mWasClean;
|
||||
PRUint16 mReasonCode;
|
||||
|
@ -78,6 +78,25 @@ nsDOMCustomEvent::InitCustomEvent(const nsAString& aType,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDOMCustomEvent::InitFromCtor(const nsAString& aType, nsISupports* aDict,
|
||||
JSContext* aCx, JSObject* aObj)
|
||||
{
|
||||
nsCOMPtr<nsICustomEventInit> eventInit = do_QueryInterface(aDict);
|
||||
bool bubbles = false;
|
||||
bool cancelable = false;
|
||||
nsCOMPtr<nsIVariant> detail;
|
||||
if (eventInit) {
|
||||
nsresult rv = eventInit->GetBubbles(&bubbles);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = eventInit->GetCancelable(&cancelable);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = eventInit->GetDetail(getter_AddRefs(detail));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
return InitCustomEvent(aType, bubbles, cancelable, detail);
|
||||
}
|
||||
|
||||
nsresult
|
||||
NS_NewDOMCustomEvent(nsIDOMEvent** aInstancePtrResult,
|
||||
nsPresContext* aPresContext,
|
||||
|
@ -59,6 +59,9 @@ public:
|
||||
// Forward to base class
|
||||
NS_FORWARD_TO_NSDOMEVENT
|
||||
|
||||
virtual const nsIID& EventInitIID() { return NS_GET_IID(nsICustomEventInit); }
|
||||
virtual nsresult InitFromCtor(const nsAString& aType, nsISupports* aDict,
|
||||
JSContext* aCx, JSObject* aObj);
|
||||
private:
|
||||
nsCOMPtr<nsIVariant> mDetail;
|
||||
};
|
||||
|
@ -61,6 +61,7 @@
|
||||
#include "nsIScriptError.h"
|
||||
#include "nsDOMPopStateEvent.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "nsJSUtils.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
@ -122,7 +123,6 @@ static char *sPopupAllowedEvents;
|
||||
|
||||
nsDOMEvent::nsDOMEvent(nsPresContext* aPresContext, nsEvent* aEvent)
|
||||
{
|
||||
mPresContext = aPresContext;
|
||||
mPrivateDataDuplicated = false;
|
||||
|
||||
if (aEvent) {
|
||||
@ -159,6 +159,15 @@ nsDOMEvent::nsDOMEvent(nsPresContext* aPresContext, nsEvent* aEvent)
|
||||
mEvent->time = PR_Now();
|
||||
}
|
||||
|
||||
InitPresContextData(aPresContext);
|
||||
|
||||
NS_ASSERTION(mEvent->message != NS_PAINT, "Trying to create a DOM paint event!");
|
||||
}
|
||||
|
||||
void
|
||||
nsDOMEvent::InitPresContextData(nsPresContext* aPresContext)
|
||||
{
|
||||
mPresContext = aPresContext;
|
||||
// Get the explicit original target (if it's anonymous make it null)
|
||||
{
|
||||
nsCOMPtr<nsIContent> content = GetTargetFromFrame();
|
||||
@ -168,8 +177,6 @@ nsDOMEvent::nsDOMEvent(nsPresContext* aPresContext, nsEvent* aEvent)
|
||||
mExplicitOriginalTarget = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
NS_ASSERTION(mEvent->message != NS_PAINT, "Trying to create a DOM paint event!");
|
||||
}
|
||||
|
||||
nsDOMEvent::~nsDOMEvent()
|
||||
@ -190,6 +197,7 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsDOMEvent)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMEvent)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMNSEvent)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIPrivateDOMEvent)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIJSNativeInitializer)
|
||||
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(Event)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
@ -372,6 +380,67 @@ nsDOMEvent::SetTrusted(bool aTrusted)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMEvent::Initialize(nsISupports* aOwner, JSContext* aCx, JSObject* aObj,
|
||||
PRUint32 aArgc, jsval* aArgv)
|
||||
{
|
||||
NS_ENSURE_TRUE(aArgc >= 1, NS_ERROR_XPC_NOT_ENOUGH_ARGS);
|
||||
|
||||
bool trusted = false;
|
||||
nsCOMPtr<nsPIDOMWindow> w = do_QueryInterface(aOwner);
|
||||
if (w) {
|
||||
nsCOMPtr<nsIDocument> d = do_QueryInterface(w->GetExtantDocument());
|
||||
if (d) {
|
||||
trusted = nsContentUtils::IsChromeDoc(d);
|
||||
nsIPresShell* s = d->GetShell();
|
||||
if (s) {
|
||||
InitPresContextData(s->GetPresContext());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
JSAutoRequest ar(aCx);
|
||||
JSString* jsstr = JS_ValueToString(aCx, aArgv[0]);
|
||||
if (!jsstr) {
|
||||
return NS_ERROR_DOM_SYNTAX_ERR;
|
||||
}
|
||||
|
||||
JS::Anchor<JSString*> deleteProtector(jsstr);
|
||||
|
||||
nsDependentJSString type;
|
||||
NS_ENSURE_STATE(type.init(aCx, jsstr));
|
||||
|
||||
nsCOMPtr<nsISupports> dict;
|
||||
JSObject* obj = nsnull;
|
||||
if (aArgc >= 2 && !JSVAL_IS_PRIMITIVE(aArgv[1])) {
|
||||
obj = JSVAL_TO_OBJECT(aArgv[1]);
|
||||
nsContentUtils::XPConnect()->WrapJS(aCx, obj,
|
||||
EventInitIID(),
|
||||
getter_AddRefs(dict));
|
||||
}
|
||||
nsresult rv = InitFromCtor(type, dict, aCx, obj);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
SetTrusted(trusted);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDOMEvent::InitFromCtor(const nsAString& aType, nsISupports* aDict,
|
||||
JSContext* aCx, JSObject* aObj)
|
||||
{
|
||||
nsCOMPtr<nsIEventInit> eventInit = do_QueryInterface(aDict);
|
||||
bool bubbles = false;
|
||||
bool cancelable = false;
|
||||
if (eventInit) {
|
||||
nsresult rv = eventInit->GetBubbles(&bubbles);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = eventInit->GetCancelable(&cancelable);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
return InitEvent(aType, bubbles, cancelable);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMEvent::GetEventPhase(PRUint16* aEventPhase)
|
||||
{
|
||||
|
@ -49,13 +49,17 @@
|
||||
#include "nsGUIEvent.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsIJSNativeInitializer.h"
|
||||
|
||||
class nsIContent;
|
||||
class nsPresContext;
|
||||
class JSContext;
|
||||
class JSObject;
|
||||
|
||||
class nsDOMEvent : public nsIDOMEvent,
|
||||
public nsIDOMNSEvent,
|
||||
public nsIPrivateDOMEvent
|
||||
public nsIPrivateDOMEvent,
|
||||
public nsIJSNativeInitializer
|
||||
{
|
||||
public:
|
||||
|
||||
@ -219,6 +223,16 @@ public:
|
||||
NS_IMETHOD_(nsEvent*) GetInternalNSEvent();
|
||||
NS_IMETHOD SetTrusted(bool aTrusted);
|
||||
|
||||
// nsIJSNativeInitializer
|
||||
NS_IMETHOD Initialize(nsISupports* aOwner, JSContext* aCx, JSObject* aObj,
|
||||
PRUint32 aArgc, jsval* aArgv);
|
||||
|
||||
virtual const nsIID& EventInitIID() { return NS_GET_IID(nsIEventInit); }
|
||||
virtual nsresult InitFromCtor(const nsAString& aType, nsISupports* aDict,
|
||||
JSContext* aCx, JSObject* aObj);
|
||||
|
||||
void InitPresContextData(nsPresContext* aPresContext);
|
||||
|
||||
virtual void Serialize(IPC::Message* aMsg, bool aSerializeInterfaceType);
|
||||
virtual bool Deserialize(const IPC::Message* aMsg, void** aIter);
|
||||
|
||||
|
@ -78,6 +78,34 @@ nsDOMHashChangeEvent::InitHashChangeEvent(const nsAString &aTypeArg,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDOMHashChangeEvent::InitFromCtor(const nsAString& aType, nsISupports* aDict,
|
||||
JSContext* aCx, JSObject* aObj)
|
||||
{
|
||||
nsCOMPtr<nsIHashChangeEventInit> eventInit = do_QueryInterface(aDict);
|
||||
bool bubbles = false;
|
||||
bool cancelable = false;
|
||||
nsAutoString oldURL;
|
||||
nsAutoString newURL;
|
||||
if (eventInit) {
|
||||
nsresult rv = eventInit->GetBubbles(&bubbles);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = eventInit->GetCancelable(&cancelable);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
JSBool found = JS_FALSE;
|
||||
if (JS_HasProperty(aCx, aObj, "oldURL", &found) && found) {
|
||||
rv = eventInit->GetOldURL(oldURL);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
found = JS_FALSE;
|
||||
if (JS_HasProperty(aCx, aObj, "newURL", &found) && found) {
|
||||
rv = eventInit->GetNewURL(newURL);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
}
|
||||
return InitHashChangeEvent(aType, bubbles, cancelable, oldURL, newURL);
|
||||
}
|
||||
|
||||
nsresult NS_NewDOMHashChangeEvent(nsIDOMEvent** aInstancePtrResult,
|
||||
nsPresContext* aPresContext,
|
||||
nsEvent* aEvent)
|
||||
|
@ -58,13 +58,12 @@ public:
|
||||
|
||||
NS_FORWARD_TO_NSDOMEVENT
|
||||
|
||||
virtual const nsIID& EventInitIID() { return NS_GET_IID(nsIHashChangeEventInit); }
|
||||
virtual nsresult InitFromCtor(const nsAString& aType, nsISupports* aDict,
|
||||
JSContext* aCx, JSObject* aObj);
|
||||
protected:
|
||||
nsString mOldURL;
|
||||
nsString mNewURL;
|
||||
};
|
||||
|
||||
nsresult NS_NewDOMHashChangeEvent(nsIDOMEvent** aInstancePtrResult,
|
||||
nsPresContext* aPresContext,
|
||||
nsEvent* aEvent);
|
||||
|
||||
#endif // nsDOMHashChangeEvent_h__
|
||||
|
@ -144,6 +144,61 @@ nsDOMMouseEvent::InitMouseEvent(const nsAString & aType, bool aCanBubble, bool a
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDOMMouseEvent::InitFromCtor(const nsAString& aType, nsISupports* aDict,
|
||||
JSContext* aCx, JSObject* aObj)
|
||||
{
|
||||
nsCOMPtr<nsIMouseEventInit> eventInit = do_QueryInterface(aDict);
|
||||
bool bubbles = false;
|
||||
bool cancelable = false;
|
||||
nsCOMPtr<nsIDOMWindow> view;
|
||||
PRInt32 detail = 0;
|
||||
PRInt32 screenX = 0;
|
||||
PRInt32 screenY = 0;
|
||||
PRInt32 clientX = 0;
|
||||
PRInt32 clientY = 0;
|
||||
bool ctrl = false;
|
||||
bool alt = false;
|
||||
bool shift = false;
|
||||
bool meta = false;
|
||||
PRUint16 button = 0;
|
||||
nsCOMPtr<nsIDOMEventTarget> relatedTarget;
|
||||
if (eventInit) {
|
||||
nsresult rv = eventInit->GetBubbles(&bubbles);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = eventInit->GetCancelable(&cancelable);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = eventInit->GetView(getter_AddRefs(view));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = eventInit->GetDetail(&detail);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = eventInit->GetScreenX(&screenX);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = eventInit->GetScreenY(&screenY);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = eventInit->GetClientX(&clientX);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = eventInit->GetClientY(&clientY);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = eventInit->GetCtrlKey(&ctrl);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = eventInit->GetShiftKey(&shift);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = eventInit->GetAltKey(&alt);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = eventInit->GetMetaKey(&meta);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = eventInit->GetButton(&button);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = eventInit->GetRelatedTarget(getter_AddRefs(relatedTarget));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
return InitMouseEvent(aType, bubbles, cancelable,
|
||||
view, detail, screenX, screenY, clientX, clientY,
|
||||
ctrl, alt, shift, meta,
|
||||
button, relatedTarget);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMMouseEvent::InitNSMouseEvent(const nsAString & aType, bool aCanBubble, bool aCancelable,
|
||||
nsIDOMWindow *aView, PRInt32 aDetail, PRInt32 aScreenX,
|
||||
|
@ -60,6 +60,9 @@ public:
|
||||
// Forward to base class
|
||||
NS_FORWARD_TO_NSDOMUIEVENT
|
||||
|
||||
virtual const nsIID& EventInitIID() { return NS_GET_IID(nsIMouseEventInit); }
|
||||
virtual nsresult InitFromCtor(const nsAString& aType, nsISupports* aDict,
|
||||
JSContext* aCx, JSObject* aObj);
|
||||
protected:
|
||||
// Specific implementation for a mouse event.
|
||||
virtual nsresult Which(PRUint32* aWhich);
|
||||
|
@ -69,6 +69,25 @@ nsDOMPageTransitionEvent::InitPageTransitionEvent(const nsAString &aTypeArg,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDOMPageTransitionEvent::InitFromCtor(const nsAString& aType, nsISupports* aDict,
|
||||
JSContext* aCx, JSObject* aObj)
|
||||
{
|
||||
nsCOMPtr<nsIPageTransitionEventInit> eventInit = do_QueryInterface(aDict);
|
||||
bool bubbles = false;
|
||||
bool cancelable = false;
|
||||
bool persisted = false;
|
||||
if (eventInit) {
|
||||
nsresult rv = eventInit->GetBubbles(&bubbles);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = eventInit->GetCancelable(&cancelable);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = eventInit->GetPersisted(&persisted);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
return InitPageTransitionEvent(aType, bubbles, cancelable, persisted);
|
||||
}
|
||||
|
||||
nsresult NS_NewDOMPageTransitionEvent(nsIDOMEvent** aInstancePtrResult,
|
||||
nsPresContext* aPresContext,
|
||||
nsEvent *aEvent)
|
||||
|
@ -55,6 +55,10 @@ public:
|
||||
|
||||
// Forward to base class
|
||||
NS_FORWARD_TO_NSDOMEVENT
|
||||
|
||||
virtual const nsIID& EventInitIID() { return NS_GET_IID(nsIPageTransitionEventInit); }
|
||||
virtual nsresult InitFromCtor(const nsAString& aType, nsISupports* aDict,
|
||||
JSContext* aCx, JSObject* aObj);
|
||||
protected:
|
||||
bool mPersisted;
|
||||
};
|
||||
|
@ -83,6 +83,25 @@ nsDOMPopStateEvent::InitPopStateEvent(const nsAString &aTypeArg,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDOMPopStateEvent::InitFromCtor(const nsAString& aType, nsISupports* aDict,
|
||||
JSContext* aCx, JSObject* aObj)
|
||||
{
|
||||
nsCOMPtr<nsIPopStateEventInit> eventInit = do_QueryInterface(aDict);
|
||||
bool bubbles = false;
|
||||
bool cancelable = false;
|
||||
nsCOMPtr<nsIVariant> state;
|
||||
if (eventInit) {
|
||||
nsresult rv = eventInit->GetBubbles(&bubbles);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = eventInit->GetCancelable(&cancelable);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = eventInit->GetState(getter_AddRefs(state));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
return InitPopStateEvent(aType, bubbles, cancelable, state);
|
||||
}
|
||||
|
||||
nsresult NS_NewDOMPopStateEvent(nsIDOMEvent** aInstancePtrResult,
|
||||
nsPresContext* aPresContext,
|
||||
nsEvent* aEvent)
|
||||
|
@ -60,12 +60,11 @@ public:
|
||||
|
||||
NS_FORWARD_TO_NSDOMEVENT
|
||||
|
||||
virtual const nsIID& EventInitIID() { return NS_GET_IID(nsIPopStateEventInit); }
|
||||
virtual nsresult InitFromCtor(const nsAString& aType, nsISupports* aDict,
|
||||
JSContext* aCx, JSObject* aObj);
|
||||
protected:
|
||||
nsCOMPtr<nsIVariant> mState;
|
||||
};
|
||||
|
||||
nsresult NS_NewDOMPopStateEvent(nsIDOMEvent** aInstancePtrResult,
|
||||
nsPresContext* aPresContext,
|
||||
nsEvent* aEvent);
|
||||
|
||||
#endif // nsDOMPopStateEvent_h__
|
||||
|
@ -205,6 +205,28 @@ nsDOMUIEvent::InitUIEvent(const nsAString& typeArg,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDOMUIEvent::InitFromCtor(const nsAString& aType, nsISupports* aDict,
|
||||
JSContext* aCx, JSObject* aObj)
|
||||
{
|
||||
nsCOMPtr<nsIUIEventInit> eventInit = do_QueryInterface(aDict);
|
||||
bool bubbles = false;
|
||||
bool cancelable = false;
|
||||
nsCOMPtr<nsIDOMWindow> view;
|
||||
PRInt32 detail = 0;
|
||||
if (eventInit) {
|
||||
nsresult rv = eventInit->GetBubbles(&bubbles);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = eventInit->GetCancelable(&cancelable);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = eventInit->GetView(getter_AddRefs(view));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = eventInit->GetDetail(&detail);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
return InitUIEvent(aType, bubbles, cancelable, view, detail);
|
||||
}
|
||||
|
||||
// ---- nsDOMNSUIEvent implementation -------------------
|
||||
nsIntPoint
|
||||
nsDOMUIEvent::GetPagePoint()
|
||||
|
@ -64,6 +64,9 @@ public:
|
||||
|
||||
NS_FORWARD_NSIDOMNSEVENT(nsDOMEvent::)
|
||||
|
||||
virtual const nsIID& EventInitIID() { return NS_GET_IID(nsIUIEventInit); }
|
||||
virtual nsresult InitFromCtor(const nsAString& aType, nsISupports* aDict,
|
||||
JSContext* aCx, JSObject* aObj);
|
||||
protected:
|
||||
// Internal helper functions
|
||||
nsIntPoint GetClientPoint();
|
||||
|
@ -112,6 +112,7 @@ _TEST_FILES = \
|
||||
empty.js \
|
||||
test_bug689564.html \
|
||||
test_bug698929.html \
|
||||
test_eventctors.html \
|
||||
$(NULL)
|
||||
|
||||
#bug 585630
|
||||
@ -144,6 +145,7 @@ _CHROME_FILES = \
|
||||
window_bug617528.xul \
|
||||
test_bug679494.xul \
|
||||
file_bug679494.html \
|
||||
test_eventctors.xul \
|
||||
$(NULL)
|
||||
|
||||
libs:: $(_TEST_FILES)
|
||||
|
378
content/events/test/test_eventctors.html
Normal file
378
content/events/test/test_eventctors.html
Normal file
@ -0,0 +1,378 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=675884
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 675884</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=675884">Mozilla Bug 675884</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
/** Test for Bug 675884 **/
|
||||
|
||||
var receivedEvent;
|
||||
document.addEventListener("hello", function(e) { receivedEvent = e; }, true);
|
||||
|
||||
// Event
|
||||
var e;
|
||||
var ex = false;
|
||||
try {
|
||||
e = new Event();
|
||||
} catch(exp) {
|
||||
ex = true;
|
||||
}
|
||||
ok(ex, "First parameter is required!");
|
||||
ex = false;
|
||||
|
||||
e = new Event("hello");
|
||||
ok(e.type, "hello", "Wrong event type!");
|
||||
ok(!e.isTrusted, "Event shouldn't be trusted!");
|
||||
ok(!e.bubbles, "Event shouldn't bubble!");
|
||||
ok(!e.cancelable, "Event shouldn't be cancelable!");
|
||||
document.dispatchEvent(e);
|
||||
is(receivedEvent, e, "Wrong event!");
|
||||
|
||||
e = new Event("hello", { bubbles: true, cancelable: true });
|
||||
ok(e.type, "hello", "Wrong event type!");
|
||||
ok(!e.isTrusted, "Event shouldn't be trusted!");
|
||||
ok(e.bubbles, "Event should bubble!");
|
||||
ok(e.cancelable, "Event should be cancelable!");
|
||||
document.dispatchEvent(e);
|
||||
is(receivedEvent, e, "Wrong event!");
|
||||
|
||||
// CustomEvent
|
||||
|
||||
try {
|
||||
e = new CustomEvent();
|
||||
} catch(exp) {
|
||||
ex = true;
|
||||
}
|
||||
ok(ex, "First parameter is required!");
|
||||
ex = false;
|
||||
|
||||
e = new CustomEvent("hello");
|
||||
ok(e.type, "hello", "Wrong event type!");
|
||||
ok(!e.isTrusted, "Event shouldn't be trusted!");
|
||||
ok(!e.bubbles, "Event shouldn't bubble!");
|
||||
ok(!e.cancelable, "Event shouldn't be cancelable!");
|
||||
document.dispatchEvent(e);
|
||||
is(receivedEvent, e, "Wrong event!");
|
||||
|
||||
e = new CustomEvent("hello", { bubbles: true, cancelable: true, detail: window });
|
||||
ok(e.type, "hello", "Wrong event type!");
|
||||
ok(!e.isTrusted, "Event shouldn't be trusted!");
|
||||
ok(e.bubbles, "Event should bubble!");
|
||||
ok(e.cancelable, "Event should be cancelable!");
|
||||
is(e.detail, window , "Wrong event.detail!");
|
||||
document.dispatchEvent(e);
|
||||
is(receivedEvent, e, "Wrong event!");
|
||||
|
||||
e = new CustomEvent("hello", { cancelable: true, detail: window });
|
||||
ok(e.type, "hello", "Wrong event type!");
|
||||
ok(!e.isTrusted, "Event shouldn't be trusted!");
|
||||
ok(!e.bubbles, "Event shouldn't bubble!");
|
||||
ok(e.cancelable, "Event should be cancelable!");
|
||||
is(e.detail, window , "Wrong event.detail!");
|
||||
|
||||
e = new CustomEvent("hello", { detail: 123 });
|
||||
is(e.detail, 123, "Wrong event.detail!");
|
||||
ok(!e.bubbles, "Event shouldn't bubble!");
|
||||
ok(!e.cancelable, "Event shouldn't be cancelable!");
|
||||
|
||||
var dict = { get detail() { return document.body } };
|
||||
e = new CustomEvent("hello", dict);
|
||||
is(e.detail, dict.detail, "Wrong event.detail!");
|
||||
ok(!e.bubbles, "Event shouldn't bubble!");
|
||||
ok(!e.cancelable, "Event shouldn't be cancelable!");
|
||||
|
||||
e = new CustomEvent("hello", 1234);
|
||||
is(e.detail, null, "Wrong event.detail!");
|
||||
ok(!e.bubbles, "Event shouldn't bubble!");
|
||||
ok(!e.cancelable, "Event shouldn't be cancelable!");
|
||||
|
||||
var dict = { get detail() { throw "foo"; } };
|
||||
|
||||
try {
|
||||
e = new CustomEvent("hello", dict);
|
||||
} catch (exp) {
|
||||
ex = true;
|
||||
}
|
||||
ok(ex, "Should have thrown an exception!");
|
||||
ex = false;
|
||||
|
||||
// CloseEvent
|
||||
|
||||
try {
|
||||
e = new CloseEvent();
|
||||
} catch(exp) {
|
||||
ex = true;
|
||||
}
|
||||
ok(ex, "First parameter is required!");
|
||||
ex = false;
|
||||
|
||||
e = new CloseEvent("hello");
|
||||
ok(e.type, "hello", "Wrong event type!");
|
||||
ok(!e.isTrusted, "Event shouldn't be trusted!");
|
||||
ok(!e.bubbles, "Event shouldn't bubble!");
|
||||
ok(!e.cancelable, "Event shouldn't be cancelable!");
|
||||
is(e.wasClean, false, "wasClean should be false!");
|
||||
is(e.code, 0, "code should be 0!");
|
||||
is(e.reason, "", "reason should be ''!");
|
||||
document.dispatchEvent(e);
|
||||
is(receivedEvent, e, "Wrong event!");
|
||||
|
||||
e = new CloseEvent("hello",
|
||||
{ bubbles: true, cancelable: true, wasClean: true, code: 1, reason: "foo" });
|
||||
ok(e.type, "hello", "Wrong event type!");
|
||||
ok(!e.isTrusted, "Event shouldn't be trusted!");
|
||||
ok(e.bubbles, "Event should bubble!");
|
||||
ok(e.cancelable, "Event should be cancelable!");
|
||||
is(e.wasClean, true, "wasClean should be true!");
|
||||
is(e.code, 1, "code should be 1!");
|
||||
is(e.reason, "foo", "reason should be 'foo'!");
|
||||
document.dispatchEvent(e);
|
||||
is(receivedEvent, e, "Wrong event!");
|
||||
|
||||
e = new CloseEvent("hello",
|
||||
{ bubbles: true, cancelable: true, wasClean: true, code: 1 });
|
||||
ok(e.type, "hello", "Wrong event type!");
|
||||
ok(!e.isTrusted, "Event shouldn't be trusted!");
|
||||
ok(e.bubbles, "Event should bubble!");
|
||||
ok(e.cancelable, "Event should be cancelable!");
|
||||
is(e.wasClean, true, "wasClean should be true!");
|
||||
is(e.code, 1, "code should be 1!");
|
||||
is(e.reason, "", "reason should be ''!");
|
||||
document.dispatchEvent(e);
|
||||
is(receivedEvent, e, "Wrong event!");
|
||||
|
||||
|
||||
// HashChangeEvent
|
||||
|
||||
try {
|
||||
e = new HashChangeEvent();
|
||||
} catch(exp) {
|
||||
ex = true;
|
||||
}
|
||||
ok(ex, "First parameter is required!");
|
||||
ex = false;
|
||||
|
||||
e = new HashChangeEvent("hello");
|
||||
ok(e.type, "hello", "Wrong event type!");
|
||||
ok(!e.isTrusted, "Event shouldn't be trusted!");
|
||||
ok(!e.bubbles, "Event shouldn't bubble!");
|
||||
ok(!e.cancelable, "Event shouldn't be cancelable!");
|
||||
is(e.oldURL, "", "oldURL should be ''");
|
||||
is(e.newURL, "", "newURL should be ''");
|
||||
document.dispatchEvent(e);
|
||||
is(receivedEvent, e, "Wrong event!");
|
||||
|
||||
e = new HashChangeEvent("hello",
|
||||
{ bubbles: true, cancelable: true, oldURL: "old", newURL: "new" });
|
||||
ok(e.type, "hello", "Wrong event type!");
|
||||
ok(!e.isTrusted, "Event shouldn't be trusted!");
|
||||
ok(e.bubbles, "Event should bubble!");
|
||||
ok(e.cancelable, "Event should be cancelable!");
|
||||
is(e.oldURL, "old", "oldURL should be 'old'");
|
||||
is(e.newURL, "new", "newURL should be 'new'");
|
||||
document.dispatchEvent(e);
|
||||
is(receivedEvent, e, "Wrong event!");
|
||||
|
||||
e = new HashChangeEvent("hello",
|
||||
{ bubbles: true, cancelable: true, newURL: "new" });
|
||||
ok(e.type, "hello", "Wrong event type!");
|
||||
ok(!e.isTrusted, "Event shouldn't be trusted!");
|
||||
ok(e.bubbles, "Event should bubble!");
|
||||
ok(e.cancelable, "Event should be cancelable!");
|
||||
is(e.oldURL, "", "oldURL should be ''");
|
||||
is(e.newURL, "new", "newURL should be 'new'");
|
||||
document.dispatchEvent(e);
|
||||
is(receivedEvent, e, "Wrong event!");
|
||||
|
||||
// PageTransitionEvent
|
||||
|
||||
try {
|
||||
e = new PageTransitionEvent();
|
||||
} catch(exp) {
|
||||
ex = true;
|
||||
}
|
||||
ok(ex, "First parameter is required!");
|
||||
ex = false;
|
||||
|
||||
e = new PageTransitionEvent("hello");
|
||||
ok(e.type, "hello", "Wrong event type!");
|
||||
ok(!e.isTrusted, "Event shouldn't be trusted!");
|
||||
ok(!e.bubbles, "Event shouldn't bubble!");
|
||||
ok(!e.cancelable, "Event shouldn't be cancelable!");
|
||||
is(e.persisted, false, "persisted should be false");
|
||||
document.dispatchEvent(e);
|
||||
is(receivedEvent, e, "Wrong event!");
|
||||
|
||||
e = new PageTransitionEvent("hello",
|
||||
{ bubbles: true, cancelable: true, persisted: true});
|
||||
ok(e.type, "hello", "Wrong event type!");
|
||||
ok(!e.isTrusted, "Event shouldn't be trusted!");
|
||||
ok(e.bubbles, "Event should bubble!");
|
||||
ok(e.cancelable, "Event should be cancelable!");
|
||||
is(e.persisted, true, "persisted should be true");
|
||||
document.dispatchEvent(e);
|
||||
is(receivedEvent, e, "Wrong event!");
|
||||
|
||||
e = new PageTransitionEvent("hello", { persisted: true});
|
||||
ok(e.type, "hello", "Wrong event type!");
|
||||
ok(!e.isTrusted, "Event shouldn't be trusted!");
|
||||
ok(!e.bubbles, "Event shouldn't bubble!");
|
||||
ok(!e.cancelable, "Event shouldn't be cancelable!");
|
||||
is(e.persisted, true, "persisted should be true");
|
||||
document.dispatchEvent(e);
|
||||
is(receivedEvent, e, "Wrong event!");
|
||||
|
||||
// PopStateEvent
|
||||
|
||||
try {
|
||||
e = new PopStateEvent();
|
||||
} catch(exp) {
|
||||
ex = true;
|
||||
}
|
||||
ok(ex, "First parameter is required!");
|
||||
ex = false;
|
||||
|
||||
e = new PopStateEvent("hello");
|
||||
ok(e.type, "hello", "Wrong event type!");
|
||||
ok(!e.isTrusted, "Event shouldn't be trusted!");
|
||||
ok(!e.bubbles, "Event shouldn't bubble!");
|
||||
ok(!e.cancelable, "Event shouldn't be cancelable!");
|
||||
is(e.state, null, "persisted should be null");
|
||||
document.dispatchEvent(e);
|
||||
is(receivedEvent, e, "Wrong event!");
|
||||
|
||||
e = new PopStateEvent("hello",
|
||||
{ bubbles: true, cancelable: true, state: window});
|
||||
ok(e.type, "hello", "Wrong event type!");
|
||||
ok(!e.isTrusted, "Event shouldn't be trusted!");
|
||||
ok(e.bubbles, "Event should bubble!");
|
||||
ok(e.cancelable, "Event should be cancelable!");
|
||||
is(e.state, window, "persisted should be window");
|
||||
document.dispatchEvent(e);
|
||||
is(receivedEvent, e, "Wrong event!");
|
||||
|
||||
|
||||
e = new PopStateEvent("hello", { state: window});
|
||||
ok(e.type, "hello", "Wrong event type!");
|
||||
ok(!e.isTrusted, "Event shouldn't be trusted!");
|
||||
ok(!e.bubbles, "Event shouldn't bubble!");
|
||||
ok(!e.cancelable, "Event shouldn't be cancelable!");
|
||||
is(e.state, window, "persisted should be window");
|
||||
document.dispatchEvent(e);
|
||||
is(receivedEvent, e, "Wrong event!");
|
||||
|
||||
// UIEvent
|
||||
|
||||
try {
|
||||
e = new UIEvent();
|
||||
} catch(exp) {
|
||||
ex = true;
|
||||
}
|
||||
ok(ex, "First parameter is required!");
|
||||
ex = false;
|
||||
|
||||
e = new UIEvent("hello");
|
||||
ok(e.type, "hello", "Wrong event type!");
|
||||
ok(!e.isTrusted, "Event shouldn't be trusted!");
|
||||
ok(!e.bubbles, "Event shouldn't bubble!");
|
||||
ok(!e.cancelable, "Event shouldn't be cancelable!");
|
||||
is(e.detail, 0, "detail should be 0");
|
||||
is(e.view, null, "view should be null");
|
||||
document.dispatchEvent(e);
|
||||
is(receivedEvent, e, "Wrong event!");
|
||||
|
||||
e = new UIEvent("hello",
|
||||
{ bubbles: true, cancelable: true, view: window, detail: 1});
|
||||
ok(e.type, "hello", "Wrong event type!");
|
||||
ok(!e.isTrusted, "Event shouldn't be trusted!");
|
||||
ok(e.bubbles, "Event should bubble!");
|
||||
ok(e.cancelable, "Event should be cancelable!");
|
||||
is(e.detail, 1, "detail should be 1");
|
||||
is(e.view, window, "view should be window");
|
||||
document.dispatchEvent(e);
|
||||
is(receivedEvent, e, "Wrong event!");
|
||||
|
||||
// UIEvent
|
||||
|
||||
try {
|
||||
e = new UIEvent();
|
||||
} catch(exp) {
|
||||
ex = true;
|
||||
}
|
||||
ok(ex, "First parameter is required!");
|
||||
ex = false;
|
||||
|
||||
e = new MouseEvent("hello");
|
||||
ok(e.type, "hello", "Wrong event type!");
|
||||
ok(!e.isTrusted, "Event shouldn't be trusted!");
|
||||
ok(!e.bubbles, "Event shouldn't bubble!");
|
||||
ok(!e.cancelable, "Event shouldn't be cancelable!");
|
||||
document.dispatchEvent(e);
|
||||
is(receivedEvent, e, "Wrong event!");
|
||||
|
||||
var mouseEventProps =
|
||||
[ { screenX: 0 },
|
||||
{ screenY: 0 },
|
||||
{ clientX: 0 },
|
||||
{ clientY: 0 },
|
||||
{ ctrlKey: false },
|
||||
{ shiftKey: false },
|
||||
{ altKey: false },
|
||||
{ metaKey: false },
|
||||
{ button: 0 },
|
||||
{ relatedTarget: null }
|
||||
];
|
||||
|
||||
var testProps =
|
||||
[
|
||||
{ screenX: 1 },
|
||||
{ screenY: 2 },
|
||||
{ clientX: 3 },
|
||||
{ clientY: 4 },
|
||||
{ ctrlKey: true },
|
||||
{ shiftKey: true },
|
||||
{ altKey: true },
|
||||
{ metaKey: true },
|
||||
{ button: 5 },
|
||||
{ relatedTarget: window }
|
||||
];
|
||||
|
||||
var defaultMouseEventValues = {};
|
||||
for (var i = 0; i < mouseEventProps.length; ++i) {
|
||||
for (prop in mouseEventProps[i]) {
|
||||
ok(prop in e, "MouseEvent doesn't have property " + prop + "!");
|
||||
defaultMouseEventValues[prop] = mouseEventProps[i][prop];
|
||||
}
|
||||
}
|
||||
|
||||
while (testProps.length) {
|
||||
var p = testProps.shift();
|
||||
e = new MouseEvent("foo", p);
|
||||
for (var def in defaultMouseEventValues) {
|
||||
if (!(def in p)) {
|
||||
is(e[def], defaultMouseEventValues[def], "Wrong default value for " + def + "!");
|
||||
} else {
|
||||
is(e[def], p[def], "Wrong event init value for " + def + "!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SimpleTest.finish();
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
51
content/events/test/test_eventctors.xul
Normal file
51
content/events/test/test_eventctors.xul
Normal file
@ -0,0 +1,51 @@
|
||||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet type="text/css" href="chrome://global/skin"?>
|
||||
<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=675884
|
||||
-->
|
||||
<window title="Mozilla Bug 675884"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
|
||||
|
||||
<!-- test results are displayed in the html:body -->
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=675884"
|
||||
target="_blank">Mozilla Bug 675884</a>
|
||||
</body>
|
||||
|
||||
<!-- test code goes here -->
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
/** Test for Bug 675884 **/
|
||||
|
||||
// Most of the tests are in .html file, but test here that
|
||||
// isTrusted is handled correctly in chrome.
|
||||
|
||||
var receivedEvent;
|
||||
document.addEventListener("hello", function(e) { receivedEvent = e; }, true);
|
||||
|
||||
// Event
|
||||
var e;
|
||||
var ex = false;
|
||||
try {
|
||||
e = new Event();
|
||||
} catch(exp) {
|
||||
ex = true;
|
||||
}
|
||||
ok(ex, "First parameter is required!");
|
||||
ex = false;
|
||||
|
||||
e = new Event("hello");
|
||||
ok(e.type, "hello", "Wrong event type!");
|
||||
ok(e.isTrusted, "Event should be trusted!");
|
||||
ok(!e.bubbles, "Event shouldn't bubble!");
|
||||
ok(!e.cancelable, "Event shouldn't be cancelable!");
|
||||
document.dispatchEvent(e);
|
||||
is(receivedEvent, e, "Wrong event!");
|
||||
|
||||
SimpleTest.finish();
|
||||
|
||||
]]>
|
||||
</script>
|
||||
</window>
|
@ -514,6 +514,7 @@
|
||||
#include "nsIDOMSmsManager.h"
|
||||
#include "nsIDOMSmsMessage.h"
|
||||
#include "nsIDOMSmsEvent.h"
|
||||
#include "nsIPrivateDOMEvent.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
@ -1574,6 +1575,25 @@ static const nsContractIDMapData kConstructorMap[] =
|
||||
NS_DEFINE_CONSTRUCTOR_DATA(EventSource, NS_EVENTSOURCE_CONTRACTID)
|
||||
};
|
||||
|
||||
#define NS_DEFINE_EVENT_CTOR(_class) \
|
||||
nsresult \
|
||||
NS_DOM##_class##Ctor(nsISupports** aInstancePtrResult) \
|
||||
{ \
|
||||
nsIDOMEvent* e = nsnull; \
|
||||
nsresult rv = NS_NewDOM##_class(&e, nsnull, nsnull); \
|
||||
*aInstancePtrResult = e; \
|
||||
return rv; \
|
||||
}
|
||||
|
||||
NS_DEFINE_EVENT_CTOR(Event)
|
||||
NS_DEFINE_EVENT_CTOR(CustomEvent)
|
||||
NS_DEFINE_EVENT_CTOR(PopStateEvent)
|
||||
NS_DEFINE_EVENT_CTOR(HashChangeEvent)
|
||||
NS_DEFINE_EVENT_CTOR(PageTransitionEvent)
|
||||
NS_DEFINE_EVENT_CTOR(CloseEvent)
|
||||
NS_DEFINE_EVENT_CTOR(UIEvent)
|
||||
NS_DEFINE_EVENT_CTOR(MouseEvent)
|
||||
|
||||
struct nsConstructorFuncMapData
|
||||
{
|
||||
PRInt32 mDOMClassInfoID;
|
||||
@ -1583,10 +1603,21 @@ struct nsConstructorFuncMapData
|
||||
#define NS_DEFINE_CONSTRUCTOR_FUNC_DATA(_class, _func) \
|
||||
{ eDOMClassInfo_##_class##_id, _func },
|
||||
|
||||
#define NS_DEFINE_EVENT_CONSTRUCTOR_FUNC_DATA(_class) \
|
||||
{ eDOMClassInfo_##_class##_id, NS_DOM##_class##Ctor },
|
||||
|
||||
static const nsConstructorFuncMapData kConstructorFuncMap[] =
|
||||
{
|
||||
NS_DEFINE_CONSTRUCTOR_FUNC_DATA(File, nsDOMFileFile::NewFile)
|
||||
NS_DEFINE_CONSTRUCTOR_FUNC_DATA(MozBlobBuilder, NS_NewBlobBuilder)
|
||||
NS_DEFINE_EVENT_CONSTRUCTOR_FUNC_DATA(Event)
|
||||
NS_DEFINE_EVENT_CONSTRUCTOR_FUNC_DATA(CustomEvent)
|
||||
NS_DEFINE_EVENT_CONSTRUCTOR_FUNC_DATA(PopStateEvent)
|
||||
NS_DEFINE_EVENT_CONSTRUCTOR_FUNC_DATA(HashChangeEvent)
|
||||
NS_DEFINE_EVENT_CONSTRUCTOR_FUNC_DATA(PageTransitionEvent)
|
||||
NS_DEFINE_EVENT_CONSTRUCTOR_FUNC_DATA(CloseEvent)
|
||||
NS_DEFINE_EVENT_CONSTRUCTOR_FUNC_DATA(UIEvent)
|
||||
NS_DEFINE_EVENT_CONSTRUCTOR_FUNC_DATA(MouseEvent)
|
||||
};
|
||||
|
||||
nsIXPConnect *nsDOMClassInfo::sXPConnect = nsnull;
|
||||
|
@ -59,3 +59,11 @@ interface nsIDOMCloseEvent : nsIDOMEvent
|
||||
in unsigned short aReasonCode,
|
||||
in DOMString aReason);
|
||||
};
|
||||
|
||||
[scriptable, uuid(148ed08e-14f1-4be5-b2f8-23f765738379)]
|
||||
interface nsICloseEventInit : nsIEventInit
|
||||
{
|
||||
attribute boolean wasClean;
|
||||
attribute unsigned short code;
|
||||
attribute DOMString reason;
|
||||
};
|
||||
|
@ -49,3 +49,9 @@ interface nsIDOMCustomEvent : nsIDOMEvent
|
||||
in boolean cancelableArg,
|
||||
in nsIVariant detailArg);
|
||||
};
|
||||
|
||||
[scriptable, uuid(8c166794-06af-4eac-b76b-bc132e421b06)]
|
||||
interface nsICustomEventInit : nsIEventInit
|
||||
{
|
||||
attribute nsIVariant detail;
|
||||
};
|
||||
|
@ -181,3 +181,10 @@ interface nsIDOMEvent : nsISupports
|
||||
*/
|
||||
void stopImmediatePropagation();
|
||||
};
|
||||
|
||||
[scriptable, uuid(fe864f0f-45df-404a-bb27-83c5d08be8d1)]
|
||||
interface nsIEventInit : nsISupports
|
||||
{
|
||||
attribute boolean bubbles;
|
||||
attribute boolean cancelable;
|
||||
};
|
||||
|
@ -46,3 +46,10 @@ interface nsIDOMHashChangeEvent : nsIDOMEvent
|
||||
in DOMString oldURLArg,
|
||||
in DOMString newURLArg);
|
||||
};
|
||||
|
||||
[scriptable, uuid(e56881c1-3714-45bb-bca3-1453ea24ee90)]
|
||||
interface nsIHashChangeEventInit : nsIEventInit
|
||||
{
|
||||
attribute DOMString oldURL;
|
||||
attribute DOMString newURL;
|
||||
};
|
||||
|
@ -113,3 +113,19 @@ interface nsIDOMMouseEvent : nsIDOMUIEvent
|
||||
in float pressure,
|
||||
in unsigned short inputSourceArg);
|
||||
};
|
||||
|
||||
[scriptable, uuid(9495a977-5c9e-4b34-8d51-22bfd9b4fcf6)]
|
||||
interface nsIMouseEventInit : nsIUIEventInit
|
||||
{
|
||||
attribute long screenX;
|
||||
attribute long screenY;
|
||||
attribute long clientX;
|
||||
attribute long clientY;
|
||||
attribute boolean ctrlKey;
|
||||
attribute boolean shiftKey;
|
||||
attribute boolean altKey;
|
||||
attribute boolean metaKey;
|
||||
attribute unsigned short button;
|
||||
// attribute unsigned short buttons; is not supported yet.
|
||||
attribute nsIDOMEventTarget relatedTarget;
|
||||
};
|
||||
|
@ -60,3 +60,9 @@ interface nsIDOMPageTransitionEvent : nsIDOMEvent
|
||||
in boolean canCancelArg,
|
||||
in boolean persisted);
|
||||
};
|
||||
|
||||
[scriptable, uuid(bf3eaa61-5048-48c4-b8b9-9bf833ca63d6)]
|
||||
interface nsIPageTransitionEventInit : nsIEventInit
|
||||
{
|
||||
attribute boolean persisted;
|
||||
};
|
||||
|
@ -49,3 +49,9 @@ interface nsIDOMPopStateEvent : nsIDOMEvent
|
||||
in boolean cancelableArg,
|
||||
in nsIVariant stateArg);
|
||||
};
|
||||
|
||||
[scriptable, uuid(2300bd68-f6e0-4c58-a1aa-45f94cdabfbd)]
|
||||
interface nsIPopStateEventInit : nsIEventInit
|
||||
{
|
||||
attribute nsIVariant state;
|
||||
};
|
||||
|
@ -73,3 +73,10 @@ interface nsIDOMUIEvent : nsIDOMEvent
|
||||
|
||||
readonly attribute boolean isChar;
|
||||
};
|
||||
|
||||
[scriptable, uuid(610eb27e-9718-4acd-8ed1-7d1840bc6c7f)]
|
||||
interface nsIUIEventInit : nsIEventInit
|
||||
{
|
||||
attribute nsIDOMWindow view;
|
||||
attribute long detail;
|
||||
};
|
||||
|
@ -46,5 +46,6 @@
|
||||
#define NS_ERROR_PLUGIN_DISABLED NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_PLUGINS,1001)
|
||||
#define NS_ERROR_PLUGIN_BLOCKLISTED NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_PLUGINS,1002)
|
||||
#define NS_ERROR_PLUGIN_TIME_RANGE_NOT_SUPPORTED NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_PLUGINS,1003)
|
||||
#define NS_ERROR_PLUGIN_CLICKTOPLAY NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_PLUGINS,1004)
|
||||
|
||||
#endif // nsPluginError_h__
|
||||
|
@ -152,6 +152,7 @@
|
||||
#include "nsContentErrors.h"
|
||||
#include "mozilla/TimeStamp.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
|
||||
#if defined(XP_WIN)
|
||||
#include "nsIWindowMediator.h"
|
||||
@ -1331,10 +1332,18 @@ nsPluginHost::TrySetUpPluginInstance(const char *aMimeType,
|
||||
|
||||
nsresult
|
||||
nsPluginHost::IsPluginEnabledForType(const char* aMimeType)
|
||||
{
|
||||
// If plugins.click_to_play is false, plugins should always play
|
||||
return IsPluginEnabledForType(aMimeType,
|
||||
!Preferences::GetBool("plugins.click_to_play", false));
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsPluginHost::IsPluginEnabledForType(const char* aMimeType, bool aShouldPlay)
|
||||
{
|
||||
nsPluginTag *plugin = FindPluginForType(aMimeType, true);
|
||||
if (plugin)
|
||||
return NS_OK;
|
||||
return aShouldPlay ? NS_OK : NS_ERROR_PLUGIN_CLICKTOPLAY;
|
||||
|
||||
// Pass false as the second arg so we can return NS_ERROR_PLUGIN_DISABLED
|
||||
// for disabled plug-ins.
|
||||
@ -1349,7 +1358,7 @@ nsPluginHost::IsPluginEnabledForType(const char* aMimeType)
|
||||
return NS_ERROR_PLUGIN_DISABLED;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
return aShouldPlay ? NS_OK : NS_ERROR_PLUGIN_CLICKTOPLAY;
|
||||
}
|
||||
|
||||
// check comma delimitered extensions
|
||||
@ -1377,12 +1386,24 @@ static int CompareExtensions(const char *aExtensionList, const char *aExtension)
|
||||
return PL_strcasecmp(pExt, aExtension);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsPluginHost::IsPluginEnabledForExtension(const char* aExtension, const char* &aMimeType)
|
||||
{
|
||||
// If plugins.click_to_play is false, plugins should always play
|
||||
return IsPluginEnabledForExtension(aExtension, aMimeType,
|
||||
!Preferences::GetBool("plugins.click_to_play", false));
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsPluginHost::IsPluginEnabledForExtension(const char* aExtension,
|
||||
const char* &aMimeType)
|
||||
const char* &aMimeType,
|
||||
bool aShouldPlay)
|
||||
{
|
||||
nsPluginTag *plugin = FindPluginEnabledForExtension(aExtension, aMimeType);
|
||||
return plugin ? NS_OK : NS_ERROR_FAILURE;
|
||||
if (plugin)
|
||||
return aShouldPlay ? NS_OK : NS_ERROR_PLUGIN_CLICKTOPLAY;
|
||||
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
class DOMMimeTypeImpl : public nsIDOMMimeType {
|
||||
@ -2254,11 +2275,6 @@ nsresult nsPluginHost::ScanPluginsDirectoryList(nsISimpleEnumerator *dirEnum,
|
||||
|
||||
nsresult nsPluginHost::LoadPlugins()
|
||||
{
|
||||
#ifdef ANDROID
|
||||
if (XRE_GetProcessType() == GeckoProcessType_Content) {
|
||||
return NS_OK;
|
||||
}
|
||||
#endif
|
||||
// do not do anything if it is already done
|
||||
// use ReloadPlugins() to enforce loading
|
||||
if (mPluginsLoaded)
|
||||
|
@ -118,7 +118,11 @@ public:
|
||||
nsIURI *aURL,
|
||||
nsIPluginInstanceOwner *aOwner);
|
||||
nsresult IsPluginEnabledForType(const char* aMimeType);
|
||||
nsresult IsPluginEnabledForType(const char* aMimeType,
|
||||
bool aShouldPlay);
|
||||
nsresult IsPluginEnabledForExtension(const char* aExtension, const char* &aMimeType);
|
||||
nsresult IsPluginEnabledForExtension(const char* aExtension, const char* &aMimeType,
|
||||
bool aShouldPlay);
|
||||
nsresult GetPluginCount(PRUint32* aPluginCount);
|
||||
nsresult GetPlugins(PRUint32 aPluginCount, nsIDOMPlugin** aPluginArray);
|
||||
|
||||
|
@ -1695,4 +1695,17 @@ public class GeckoAppShell
|
||||
public static void sendMessage(String aNumber, String aMessage) {
|
||||
GeckoSmsManager.send(aNumber, aMessage);
|
||||
}
|
||||
|
||||
public static boolean isTablet() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
|
||||
Configuration config = GeckoApp.mAppContext.getResources().getConfiguration();
|
||||
// xlarge is defined by android as screens larger than 960dp x 720dp
|
||||
// and should include most devices ~7in and up.
|
||||
// http://developer.android.com/guide/practices/screens_support.html
|
||||
if ((config.screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) >= Configuration.SCREENLAYOUT_SIZE_XLARGE) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -100,6 +100,7 @@ static const char *sExtensionNames[] = {
|
||||
"GL_ANGLE_framebuffer_multisample",
|
||||
"GL_OES_rgb8_rgba8",
|
||||
"GL_ARB_robustness",
|
||||
"GL_EXT_robustness",
|
||||
NULL
|
||||
};
|
||||
|
||||
@ -409,18 +410,32 @@ GLContext::InitWithPrefix(const char *prefix, bool trygl)
|
||||
(mSymbols.fMapBuffer && mSymbols.fUnmapBuffer),
|
||||
"ARB_pixel_buffer_object supported without glMapBuffer/UnmapBuffer being available!");
|
||||
|
||||
if (SupportsRobustness() && IsExtensionSupported(ARB_robustness)) {
|
||||
SymLoadStruct robustnessSymbols[] = {
|
||||
{ (PRFuncPtr*) &mSymbols.fGetGraphicsResetStatus, { "GetGraphicsResetStatusARB", NULL } },
|
||||
{ NULL, { NULL } },
|
||||
};
|
||||
if (SupportsRobustness()) {
|
||||
if (IsExtensionSupported(ARB_robustness)) {
|
||||
SymLoadStruct robustnessSymbols[] = {
|
||||
{ (PRFuncPtr*) &mSymbols.fGetGraphicsResetStatus, { "GetGraphicsResetStatusARB", NULL } },
|
||||
{ NULL, { NULL } },
|
||||
};
|
||||
|
||||
if (!LoadSymbols(&robustnessSymbols[0], trygl, prefix)) {
|
||||
NS_RUNTIMEABORT("GL supports ARB_robustness without supplying GetGraphicsResetStatusARB.");
|
||||
mInitialized = false;
|
||||
if (!LoadSymbols(&robustnessSymbols[0], trygl, prefix)) {
|
||||
NS_RUNTIMEABORT("GL supports ARB_robustness without supplying GetGraphicsResetStatusARB.");
|
||||
mInitialized = false;
|
||||
} else {
|
||||
mHasRobustness = true;
|
||||
}
|
||||
} else if (IsExtensionSupported(EXT_robustness)) {
|
||||
SymLoadStruct robustnessSymbols[] = {
|
||||
{ (PRFuncPtr*) &mSymbols.fGetGraphicsResetStatus, { "GetGraphicsResetStatusEXT", NULL } },
|
||||
{ NULL, { NULL } },
|
||||
};
|
||||
|
||||
if (!LoadSymbols(&robustnessSymbols[0], trygl, prefix)) {
|
||||
NS_RUNTIMEABORT("GL supports EGL_robustness without supplying GetGraphicsResetStatusEXT.");
|
||||
mInitialized = false;
|
||||
} else {
|
||||
mHasRobustness = true;
|
||||
}
|
||||
}
|
||||
|
||||
mHasRobustness = true;
|
||||
}
|
||||
|
||||
// Check for aux symbols based on extensions
|
||||
|
@ -665,6 +665,14 @@ public:
|
||||
return mIsGLES2 || IsExtensionSupported(ARB_ES2_compatibility);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the context is using ANGLE. This should only be overridden for an ANGLE
|
||||
* implementation.
|
||||
*/
|
||||
virtual bool IsANGLE() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* The derived class is expected to provide information on whether or not it
|
||||
* supports robustness.
|
||||
@ -1270,6 +1278,7 @@ public:
|
||||
ANGLE_framebuffer_multisample,
|
||||
OES_rgb8_rgba8,
|
||||
ARB_robustness,
|
||||
EXT_robustness,
|
||||
Extensions_Max
|
||||
};
|
||||
|
||||
|
@ -215,6 +215,18 @@ static EGLConfig
|
||||
CreateEGLSurfaceForXSurface(gfxASurface* aSurface, EGLConfig* aConfig = nsnull, EGLenum aDepth = 0);
|
||||
#endif
|
||||
|
||||
static EGLint gContextAttribs[] = {
|
||||
LOCAL_EGL_CONTEXT_CLIENT_VERSION, 2,
|
||||
LOCAL_EGL_NONE
|
||||
};
|
||||
|
||||
static EGLint gContextAttribsRobustness[] = {
|
||||
LOCAL_EGL_CONTEXT_CLIENT_VERSION, 2,
|
||||
//LOCAL_EGL_CONTEXT_ROBUST_ACCESS_EXT, LOCAL_EGL_TRUE,
|
||||
LOCAL_EGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_EXT, LOCAL_EGL_LOSE_CONTEXT_ON_RESET_EXT,
|
||||
LOCAL_EGL_NONE
|
||||
};
|
||||
|
||||
static int
|
||||
next_power_of_two(int v)
|
||||
{
|
||||
@ -245,7 +257,8 @@ static class EGLLibrary
|
||||
public:
|
||||
EGLLibrary()
|
||||
: mInitialized(false),
|
||||
mEGLLibrary(nsnull)
|
||||
mEGLLibrary(nsnull),
|
||||
mHasRobustness(false)
|
||||
{
|
||||
mIsANGLE = false;
|
||||
mHave_EGL_KHR_image_base = false;
|
||||
@ -429,7 +442,7 @@ public:
|
||||
return false;
|
||||
|
||||
const char *vendor = (const char*) fQueryString(mEGLDisplay, LOCAL_EGL_VENDOR);
|
||||
if (vendor && strstr(vendor, "TransGaming") != 0) {
|
||||
if (vendor && (strstr(vendor, "TransGaming") != 0 || strstr(vendor, "Google Inc.") != 0)) {
|
||||
mIsANGLE = true;
|
||||
}
|
||||
|
||||
@ -518,6 +531,10 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
if (strstr(extensions, "EGL_EXT_create_context_robustness")) {
|
||||
mHasRobustness = true;
|
||||
}
|
||||
|
||||
mInitialized = true;
|
||||
reporter.SetSuccessful();
|
||||
return true;
|
||||
@ -551,6 +568,10 @@ public:
|
||||
return mHave_EGL_ANGLE_surface_d3d_texture_2d_share_handle;
|
||||
}
|
||||
|
||||
bool HasRobustness() {
|
||||
return mHasRobustness;
|
||||
}
|
||||
|
||||
void
|
||||
DumpEGLConfig(EGLConfig cfg)
|
||||
{
|
||||
@ -625,6 +646,7 @@ private:
|
||||
EGLDisplay mEGLDisplay;
|
||||
|
||||
bool mIsANGLE;
|
||||
bool mHasRobustness;
|
||||
|
||||
bool mHave_EGL_KHR_image_base;
|
||||
bool mHave_EGL_KHR_image_pixmap;
|
||||
@ -645,22 +667,20 @@ class GLContextEGL : public GLContext
|
||||
bool aIsOffscreen = false)
|
||||
{
|
||||
EGLContext context;
|
||||
static EGLint cxattribs[] = {
|
||||
LOCAL_EGL_CONTEXT_CLIENT_VERSION, 2,
|
||||
LOCAL_EGL_NONE
|
||||
};
|
||||
|
||||
context = sEGLLibrary.fCreateContext(EGL_DISPLAY(),
|
||||
config,
|
||||
shareContext ? shareContext->mContext : EGL_NO_CONTEXT,
|
||||
cxattribs);
|
||||
sEGLLibrary.HasRobustness() ? gContextAttribsRobustness
|
||||
: gContextAttribs);
|
||||
if (!context) {
|
||||
if (shareContext) {
|
||||
shareContext = nsnull;
|
||||
context = sEGLLibrary.fCreateContext(EGL_DISPLAY(),
|
||||
config,
|
||||
EGL_NO_CONTEXT,
|
||||
cxattribs);
|
||||
sEGLLibrary.HasRobustness() ? gContextAttribsRobustness
|
||||
: gContextAttribs);
|
||||
if (!context) {
|
||||
NS_WARNING("Failed to create EGLContext!");
|
||||
return nsnull;
|
||||
@ -753,6 +773,7 @@ public:
|
||||
mIsDoubleBuffered = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
@ -766,7 +787,12 @@ public:
|
||||
|
||||
bool SupportsRobustness()
|
||||
{
|
||||
return false;
|
||||
return sEGLLibrary.HasRobustness();
|
||||
}
|
||||
|
||||
virtual bool IsANGLE()
|
||||
{
|
||||
return sEGLLibrary.IsANGLE();
|
||||
}
|
||||
|
||||
#if defined(MOZ_X11) && defined(MOZ_EGL_XRENDER_COMPOSITE)
|
||||
@ -2104,16 +2130,12 @@ TRY_ATTRIBS_AGAIN:
|
||||
|
||||
sEGLLibrary.fBindAPI(LOCAL_EGL_OPENGL_ES_API);
|
||||
|
||||
EGLint cxattrs[] = {
|
||||
LOCAL_EGL_CONTEXT_CLIENT_VERSION, 2,
|
||||
LOCAL_EGL_NONE
|
||||
};
|
||||
|
||||
context = sEGLLibrary.fCreateContext(EGL_DISPLAY(),
|
||||
config,
|
||||
EGL_NO_CONTEXT,
|
||||
cxattrs);
|
||||
if (!context) {
|
||||
sEGLLibrary.HasRobustness() ? gContextAttribsRobustness
|
||||
: gContextAttribs);
|
||||
if (!context) {
|
||||
NS_WARNING("Failed to create context");
|
||||
sEGLLibrary.fDestroySurface(EGL_DISPLAY(), surface);
|
||||
return nsnull;
|
||||
@ -2496,15 +2518,11 @@ GLContextEGL::CreateBasicEGLPixmapOffscreenContext(const gfxIntSize& aSize,
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
EGLint cxattribs[] = {
|
||||
LOCAL_EGL_CONTEXT_CLIENT_VERSION, 2,
|
||||
LOCAL_EGL_NONE
|
||||
};
|
||||
|
||||
EGLContext context = sEGLLibrary.fCreateContext(EGL_DISPLAY(),
|
||||
config,
|
||||
EGL_NO_CONTEXT,
|
||||
cxattribs);
|
||||
sEGLLibrary.HasRobustness() ? gContextAttribsRobustness
|
||||
: gContextAttribs);
|
||||
if (!context) {
|
||||
sEGLLibrary.fDestroySurface(EGL_DISPLAY(), surface);
|
||||
return nsnull;
|
||||
|
@ -3059,6 +3059,10 @@ typedef ptrdiff_t GLintptr;
|
||||
#define LOCAL_WGL_NO_RESET_NOTIFICATION_ARB 0x8261
|
||||
#define LOCAL_WGL_LOSE_CONTEXT_ON_RESET_ARB 0x8252
|
||||
|
||||
#define LOCAL_EGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_EXT 0x3138
|
||||
#define LOCAL_EGL_NO_RESET_NOTIFICATION_EXT 0x31BE
|
||||
#define LOCAL_EGL_LOSE_CONTEXT_ON_RESET_EXT 0x31BF
|
||||
|
||||
#define LOCAL_GL_CONTEXT_MAJOR_VERSION_ARB 0x2091
|
||||
#define LOCAL_GL_CONTEXT_MINOR_VERSION_ARB 0x2092
|
||||
#define LOCAL_GL_CONTEXT_LAYER_PLANE_ARB 0x2093
|
||||
@ -3071,6 +3075,8 @@ typedef ptrdiff_t GLintptr;
|
||||
#define LOCAL_WGL_CONTEXT_FLAGS_ARB 0x2094
|
||||
#define LOCAL_WGL_CONTEXT_PROFILE_MASK_ARB 0x9126
|
||||
|
||||
#define LOCAL_EGL_CONTEXT_ROBUST_ACCESS_EXT 0x30BF
|
||||
|
||||
#define LOCAL_GL_CONTEXT_DEBUG_BIT_ARB 0x0001
|
||||
#define LOCAL_GL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002
|
||||
|
||||
|
@ -147,7 +147,7 @@ NS_IMETHODIMP nsPNGEncoder::StartImageEncode(PRUint32 aWidth,
|
||||
mPNG = png_create_write_struct(PNG_LIBPNG_VER_STRING,
|
||||
nsnull,
|
||||
ErrorCallback,
|
||||
ErrorCallback);
|
||||
WarningCallback);
|
||||
if (! mPNG)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
@ -665,10 +665,10 @@ nsPNGEncoder::StripAlpha(const PRUint8* aSrc, PRUint8* aDest,
|
||||
}
|
||||
|
||||
|
||||
// nsPNGEncoder::ErrorCallback
|
||||
// nsPNGEncoder::WarningCallback
|
||||
|
||||
void // static
|
||||
nsPNGEncoder::ErrorCallback(png_structp png_ptr,
|
||||
nsPNGEncoder::WarningCallback(png_structp png_ptr,
|
||||
png_const_charp warning_msg)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
@ -679,6 +679,25 @@ nsPNGEncoder::ErrorCallback(png_structp png_ptr,
|
||||
}
|
||||
|
||||
|
||||
// nsPNGEncoder::ErrorCallback
|
||||
|
||||
void // static
|
||||
nsPNGEncoder::ErrorCallback(png_structp png_ptr,
|
||||
png_const_charp error_msg)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
// XXX: these messages are probably useful callers...
|
||||
// use nsIConsoleService?
|
||||
PR_fprintf(PR_STDERR, "PNG Encoder: %s\n", error_msg);;
|
||||
#endif
|
||||
#if PNG_LIBPNG_VER < 10500
|
||||
longjmp(png_ptr->jmpbuf, 1);
|
||||
#else
|
||||
png_longjmp(png_ptr, 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
// nsPNGEncoder::WriteCallback
|
||||
|
||||
void // static
|
||||
|
@ -81,7 +81,8 @@ protected:
|
||||
PRUint32 aPixelWidth, bool aUseTransparency);
|
||||
void StripAlpha(const PRUint8* aSrc, PRUint8* aDest,
|
||||
PRUint32 aPixelWidth);
|
||||
static void ErrorCallback(png_structp png_ptr, png_const_charp warning_msg);
|
||||
static void WarningCallback(png_structp png_ptr, png_const_charp warning_msg);
|
||||
static void ErrorCallback(png_structp png_ptr, png_const_charp error_msg);
|
||||
static void WriteCallback(png_structp png, png_bytep data, png_size_t size);
|
||||
void NotifyListener();
|
||||
|
||||
|
@ -893,7 +893,7 @@ nsXPConnect::Traverse(void *p, nsCycleCollectionTraversalCallback &cb)
|
||||
JS_snprintf(name, sizeof(name), "JS Object (%s - %s)",
|
||||
clazz->name, si->GetJSClass()->name);
|
||||
} else if (clazz == &js::FunctionClass) {
|
||||
JSFunction* fun = (JSFunction*) xpc_GetJSPrivate(obj);
|
||||
JSFunction* fun = JS_GetObjectFunction(obj);
|
||||
JSString* str = JS_GetFunctionId(fun);
|
||||
if (str) {
|
||||
NS_ConvertUTF16toUTF8 fname(JS_GetInternedStringChars(str));
|
||||
@ -920,15 +920,8 @@ nsXPConnect::Traverse(void *p, nsCycleCollectionTraversalCallback &cb)
|
||||
JS_snprintf(name, sizeof(name), "JS %s", trace_types[traceKind]);
|
||||
}
|
||||
|
||||
if(traceKind == JSTRACE_OBJECT) {
|
||||
JSObject *global = JS_GetGlobalForObject(NULL, static_cast<JSObject*>(p));
|
||||
char fullname[100];
|
||||
JS_snprintf(fullname, sizeof(fullname),
|
||||
"%s (global=%p)", name, global);
|
||||
cb.DescribeGCedNode(isMarked, sizeof(JSObject), fullname);
|
||||
} else {
|
||||
cb.DescribeGCedNode(isMarked, sizeof(JSObject), name);
|
||||
}
|
||||
// Disable printing global for objects while we figure out ObjShrink fallout.
|
||||
cb.DescribeGCedNode(isMarked, sizeof(JSObject), name);
|
||||
} else {
|
||||
cb.DescribeGCedNode(isMarked, sizeof(JSObject), "JS Object");
|
||||
}
|
||||
|
@ -75,6 +75,8 @@ _CHROME_FILES = \
|
||||
test_getweakmapkeys.xul \
|
||||
test_weakmaps.xul \
|
||||
test_bug706301.xul \
|
||||
test_ccbeginfail.xul \
|
||||
test_ccdump.xul \
|
||||
$(NULL)
|
||||
|
||||
# Disabled until this test gets updated to test the new proxy based
|
||||
|
67
js/xpconnect/tests/chrome/test_ccbeginfail.xul
Normal file
67
js/xpconnect/tests/chrome/test_ccbeginfail.xul
Normal file
@ -0,0 +1,67 @@
|
||||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet type="text/css" href="chrome://global/skin"?>
|
||||
<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=710761
|
||||
-->
|
||||
<window title="Mozilla Bug 710761"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
|
||||
|
||||
<!-- test results are displayed in the html:body -->
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=710761"
|
||||
target="_blank">Mozilla Bug 710761</a>
|
||||
</body>
|
||||
|
||||
<!-- test code goes here -->
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
/** Test for Bug 710761 **/
|
||||
|
||||
let noCallbacks = true;
|
||||
|
||||
var beginFailListener = {
|
||||
QueryInterface: function QueryInterface(aIID) {
|
||||
if (aIID.equals(Components.interfaces.nsICycleCollectorListener) ||
|
||||
aIID.equals(Components.interfaces.nsISupports))
|
||||
return this;
|
||||
throw Components.results.NS_NOINTERFACE;
|
||||
},
|
||||
|
||||
/* nsICycleCollectorListener */
|
||||
begin: function () {
|
||||
throw Components.results.NS_ERROR_FAILURE;
|
||||
},
|
||||
noteRefCountedObject: function (addr, rc, descr) {
|
||||
noCallbacks = false;
|
||||
},
|
||||
noteGCedObject: function (addr, marked, descr) {
|
||||
noCallbacks = false;
|
||||
},
|
||||
noteEdge: function (addr, descr) {
|
||||
noCallbacks = false;
|
||||
},
|
||||
beginResults: function () {
|
||||
noCallbacks = false;
|
||||
},
|
||||
describeRoot: function (addr, known) {
|
||||
noCallbacks = false;
|
||||
},
|
||||
describeGarbage: function (addr) {
|
||||
noCallbacks = false;
|
||||
},
|
||||
end: function () {
|
||||
noCallbacks = false;
|
||||
},
|
||||
};
|
||||
|
||||
window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
|
||||
.getInterface(Components.interfaces.nsIDOMWindowUtils)
|
||||
.cycleCollect(beginFailListener);
|
||||
|
||||
ok(noCallbacks, "If cycle collector listener begin fails, no further callbacks should be called.");
|
||||
|
||||
]]>
|
||||
</script>
|
||||
</window>
|
49
js/xpconnect/tests/chrome/test_ccdump.xul
Normal file
49
js/xpconnect/tests/chrome/test_ccdump.xul
Normal file
@ -0,0 +1,49 @@
|
||||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet type="text/css" href="chrome://global/skin"?>
|
||||
<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=709162
|
||||
-->
|
||||
<window title="Mozilla Bug 709162"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
|
||||
|
||||
<!-- test results are displayed in the html:body -->
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=709162"
|
||||
target="_blank">Mozilla Bug 709162</a>
|
||||
</body>
|
||||
|
||||
<!-- test code goes here -->
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
/** Test for Bug 709162 **/
|
||||
|
||||
var emptyListener = {
|
||||
QueryInterface: function QueryInterface(aIID) {
|
||||
if (aIID.equals(Components.interfaces.nsICycleCollectorListener) ||
|
||||
aIID.equals(Components.interfaces.nsISupports))
|
||||
return this;
|
||||
throw Components.results.NS_NOINTERFACE;
|
||||
},
|
||||
|
||||
/* nsICycleCollectorListener */
|
||||
begin: function () {},
|
||||
noteRefCountedObject: function (addr, rc, descr) {},
|
||||
noteGCedObject: function (addr, marked, descr) {},
|
||||
noteEdge: function (addr, descr) {},
|
||||
beginResults: function () {},
|
||||
describeRoot: function (addr, known) {},
|
||||
describeGarbage: function (addr) {},
|
||||
end: function () {},
|
||||
};
|
||||
|
||||
window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
|
||||
.getInterface(Components.interfaces.nsIDOMWindowUtils)
|
||||
.cycleCollect(emptyListener);
|
||||
|
||||
ok(true, "Dump cycle collector graph without crashing.");
|
||||
|
||||
]]>
|
||||
</script>
|
||||
</window>
|
154
mobile/android/base/AutoCompletePopup.java
Normal file
154
mobile/android/base/AutoCompletePopup.java
Normal file
@ -0,0 +1,154 @@
|
||||
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla Android code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2011
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Margaret Leibovic <margaret.leibovic@gmail.com>
|
||||
* Sriram Ramasubramanian <sriram@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
package org.mozilla.gecko;
|
||||
|
||||
import org.mozilla.gecko.gfx.FloatSize;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.view.animation.Animation;
|
||||
import android.view.animation.AnimationUtils;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.AdapterView.OnItemClickListener;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.RelativeLayout.LayoutParams;
|
||||
import android.widget.ListView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
|
||||
public class AutoCompletePopup extends ListView {
|
||||
private Context mContext;
|
||||
private RelativeLayout.LayoutParams mLayout;
|
||||
|
||||
private int mWidth;
|
||||
private int mHeight;
|
||||
|
||||
private Animation mAnimation;
|
||||
|
||||
private static final String LOGTAG = "AutoCompletePopup";
|
||||
|
||||
public AutoCompletePopup(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
mContext = context;
|
||||
|
||||
mAnimation = AnimationUtils.loadAnimation(context, R.anim.grow_fade_in);
|
||||
mAnimation.setDuration(75);
|
||||
|
||||
setFocusable(false);
|
||||
|
||||
setOnItemClickListener(new OnItemClickListener() {
|
||||
public void onItemClick(AdapterView<?> parentView, View view, int position, long id) {
|
||||
String value = ((TextView) view).getText().toString();
|
||||
GeckoAppShell.sendEventToGecko(new GeckoEvent("FormAssist:AutoComplete", value));
|
||||
hide();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void show(JSONArray suggestions, JSONArray rect, double zoom) {
|
||||
ArrayAdapter<String> adapter = new ArrayAdapter<String>(mContext, R.layout.autocomplete_list_item);
|
||||
for (int i = 0; i < suggestions.length(); i++) {
|
||||
try {
|
||||
adapter.add(suggestions.get(i).toString());
|
||||
} catch (JSONException e) {
|
||||
Log.i(LOGTAG, "JSONException: " + e);
|
||||
}
|
||||
}
|
||||
|
||||
setAdapter(adapter);
|
||||
|
||||
if (isShown())
|
||||
return;
|
||||
|
||||
setVisibility(View.VISIBLE);
|
||||
startAnimation(mAnimation);
|
||||
|
||||
if (mLayout == null) {
|
||||
mLayout = (RelativeLayout.LayoutParams) getLayoutParams();
|
||||
mWidth = mLayout.width;
|
||||
mHeight = mLayout.height;
|
||||
}
|
||||
|
||||
int left = 0;
|
||||
int top = 0;
|
||||
int width = 0;
|
||||
int height = 0;
|
||||
|
||||
try {
|
||||
left = (int) (rect.getDouble(0) * zoom);
|
||||
top = (int) (rect.getDouble(1) * zoom);
|
||||
width = (int) (rect.getDouble(2) * zoom);
|
||||
height = (int) (rect.getDouble(3) * zoom);
|
||||
} catch (JSONException e) { }
|
||||
|
||||
int listWidth = mWidth;
|
||||
int listHeight = mHeight;
|
||||
int listLeft = left < 0 ? 0 : left;
|
||||
int listTop = top + height;
|
||||
|
||||
FloatSize viewport = GeckoApp.mAppContext.getLayerController().getViewportSize();
|
||||
|
||||
// If the textbox is smaller than the screen-width,
|
||||
// shrink the list's width
|
||||
if ((left + width) < viewport.width)
|
||||
listWidth = left + width;
|
||||
|
||||
// If the list is extending outside of the viewport
|
||||
// try moving above
|
||||
if (((listTop + listHeight) > viewport.height) && (listHeight <= top))
|
||||
listTop = (top - listHeight);
|
||||
|
||||
mLayout = new RelativeLayout.LayoutParams(listWidth, listHeight);
|
||||
mLayout.setMargins(listLeft, listTop, 0, 0);
|
||||
setLayoutParams(mLayout);
|
||||
requestLayout();
|
||||
}
|
||||
|
||||
public void hide() {
|
||||
if (isShown()) {
|
||||
setVisibility(View.GONE);
|
||||
GeckoAppShell.sendEventToGecko(new GeckoEvent("FormAssist:Closed", null));
|
||||
}
|
||||
}
|
||||
}
|
@ -121,6 +121,7 @@ abstract public class GeckoApp
|
||||
|
||||
public static BrowserToolbar mBrowserToolbar;
|
||||
public static DoorHangerPopup mDoorHangerPopup;
|
||||
public static AutoCompletePopup mAutoCompletePopup;
|
||||
public Favicons mFavicons;
|
||||
|
||||
private Geocoder mGeocoder;
|
||||
@ -925,6 +926,23 @@ abstract public class GeckoApp
|
||||
mBrowserToolbar.setVisibility(View.VISIBLE);
|
||||
}
|
||||
});
|
||||
} else if (event.equals("FormAssist:AutoComplete")) {
|
||||
final JSONArray suggestions = message.getJSONArray("suggestions");
|
||||
if (suggestions.length() == 0) {
|
||||
mMainHandler.post(new Runnable() {
|
||||
public void run() {
|
||||
mAutoCompletePopup.hide();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
final JSONArray rect = message.getJSONArray("rect");
|
||||
final double zoom = message.getDouble("zoom");
|
||||
mMainHandler.post(new Runnable() {
|
||||
public void run() {
|
||||
mAutoCompletePopup.show(suggestions, rect, zoom);
|
||||
}
|
||||
});
|
||||
}
|
||||
} else if (event.equals("AgentMode:Changed")) {
|
||||
Tab.AgentMode agentMode = message.getString("agentMode").equals("mobile") ? Tab.AgentMode.MOBILE : Tab.AgentMode.DESKTOP;
|
||||
int tabId = message.getInt("tabId");
|
||||
@ -958,6 +976,7 @@ abstract public class GeckoApp
|
||||
}
|
||||
|
||||
public void run() {
|
||||
mAutoCompletePopup.hide();
|
||||
if (mAboutHomeContent == null) {
|
||||
mAboutHomeContent = (AboutHomeContent) findViewById(R.id.abouthome_content);
|
||||
mAboutHomeContent.init(GeckoApp.mAppContext);
|
||||
@ -1059,6 +1078,7 @@ abstract public class GeckoApp
|
||||
|
||||
mMainHandler.post(new Runnable() {
|
||||
public void run() {
|
||||
mAutoCompletePopup.hide();
|
||||
if (Tabs.getInstance().isSelectedTab(tab)) {
|
||||
mBrowserToolbar.setTitle(tab.getDisplayTitle());
|
||||
mBrowserToolbar.setFavicon(tab.getFavicon());
|
||||
@ -1324,6 +1344,7 @@ abstract public class GeckoApp
|
||||
mMainLayout = (LinearLayout) findViewById(R.id.main_layout);
|
||||
|
||||
mDoorHangerPopup = new DoorHangerPopup(this);
|
||||
mAutoCompletePopup = (AutoCompletePopup) findViewById(R.id.autocomplete_popup);
|
||||
|
||||
Tabs tabs = Tabs.getInstance();
|
||||
Tab tab = tabs.getSelectedTab();
|
||||
@ -1415,6 +1436,7 @@ abstract public class GeckoApp
|
||||
GeckoAppShell.registerGeckoEventListener("ToggleChrome:Hide", GeckoApp.mAppContext);
|
||||
GeckoAppShell.registerGeckoEventListener("ToggleChrome:Show", GeckoApp.mAppContext);
|
||||
GeckoAppShell.registerGeckoEventListener("AgentMode:Changed", GeckoApp.mAppContext);
|
||||
GeckoAppShell.registerGeckoEventListener("FormAssist:AutoComplete", GeckoApp.mAppContext);
|
||||
|
||||
mConnectivityFilter = new IntentFilter();
|
||||
mConnectivityFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
|
||||
@ -1643,6 +1665,7 @@ abstract public class GeckoApp
|
||||
GeckoAppShell.unregisterGeckoEventListener("ToggleChrome:Hide", GeckoApp.mAppContext);
|
||||
GeckoAppShell.unregisterGeckoEventListener("ToggleChrome:Show", GeckoApp.mAppContext);
|
||||
GeckoAppShell.unregisterGeckoEventListener("AgentMode:Changed", GeckoApp.mAppContext);
|
||||
GeckoAppShell.unregisterGeckoEventListener("FormAssist:AutoComplete", GeckoApp.mAppContext);
|
||||
|
||||
mFavicons.close();
|
||||
|
||||
@ -1666,7 +1689,10 @@ abstract public class GeckoApp
|
||||
public void onConfigurationChanged(android.content.res.Configuration newConfig)
|
||||
{
|
||||
Log.i(LOGTAG, "configuration changed");
|
||||
// nothing, just ignore
|
||||
|
||||
// hide the autocomplete list on rotation
|
||||
mAutoCompletePopup.hide();
|
||||
|
||||
super.onConfigurationChanged(newConfig);
|
||||
}
|
||||
|
||||
|
@ -1550,6 +1550,19 @@ public class GeckoAppShell
|
||||
GeckoSmsManager.send(aNumber, aMessage);
|
||||
}
|
||||
|
||||
public static boolean isTablet() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
|
||||
Configuration config = GeckoApp.mAppContext.getResources().getConfiguration();
|
||||
// xlarge is defined by android as screens larger than 960dp x 720dp
|
||||
// and should include most devices ~7in and up.
|
||||
// http://developer.android.com/guide/practices/screens_support.html
|
||||
if ((config.screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) >= Configuration.SCREENLAYOUT_SIZE_XLARGE) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void emitGeckoAccessibilityEvent (int eventType, String role, String text, String description, boolean enabled, boolean checked, boolean password) {
|
||||
AccessibilityManager accessibilityManager =
|
||||
(AccessibilityManager) GeckoApp.mAppContext.getSystemService(Context.ACCESSIBILITY_SERVICE);
|
||||
|
@ -196,6 +196,9 @@ public class GeckoPreferences
|
||||
|
||||
// send the Preferences:Set message to Gecko
|
||||
public static void setPreference(String pref, Object value) {
|
||||
if (pref == null || pref.length() == 0)
|
||||
return;
|
||||
|
||||
try {
|
||||
JSONObject jsonPref = new JSONObject();
|
||||
jsonPref.put("name", pref);
|
||||
|
@ -50,6 +50,7 @@ DIST_FILES = package-name.txt
|
||||
JAVAFILES = \
|
||||
AboutHomeContent.java \
|
||||
AlertNotification.java \
|
||||
AutoCompletePopup.java \
|
||||
AwesomeBar.java \
|
||||
AwesomeBarTabs.java \
|
||||
BrowserToolbar.java \
|
||||
@ -174,6 +175,7 @@ DEFINES += -DMOZ_ANDROID_SHARED_ID="$(ANDROID_PACKAGE_NAME).sharedID"
|
||||
endif
|
||||
|
||||
RES_LAYOUT = \
|
||||
res/layout/autocomplete_list_item.xml \
|
||||
res/layout/awesomebar_header_row.xml \
|
||||
res/layout/awesomebar_row.xml \
|
||||
res/layout/awesomebar_search.xml \
|
||||
@ -369,6 +371,7 @@ MOZ_ANDROID_DRAWABLES += mobile/android/base/resources/drawable/abouthome_bg.png
|
||||
mobile/android/base/resources/drawable/address_bar_bg.xml \
|
||||
mobile/android/base/resources/drawable/address_bar_url_default.xml \
|
||||
mobile/android/base/resources/drawable/address_bar_url_pressed.xml \
|
||||
mobile/android/base/resources/drawable/autocomplete_list_bg.9.png \
|
||||
mobile/android/base/resources/drawable/awesomebar_tab_focus.xml \
|
||||
mobile/android/base/resources/drawable/awesomebar_tab_focus_selected.xml \
|
||||
mobile/android/base/resources/drawable/awesomebar_tab_indicator.xml \
|
||||
|
Binary file not shown.
After Width: | Height: | Size: 167 B |
@ -24,6 +24,15 @@
|
||||
|
||||
</org.mozilla.gecko.AboutHomeContent>
|
||||
|
||||
<org.mozilla.gecko.AutoCompletePopup android:id="@+id/autocomplete_popup"
|
||||
style="@android:style/Widget.ListView.White"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="100dip"
|
||||
android:background="@drawable/autocomplete_list_bg"
|
||||
android:cacheColorHint="#ffffff"
|
||||
android:listSelector="@android:drawable/list_selector_background"
|
||||
android:visibility="gone"/>
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="?android:attr/textAppearanceMediumInverse"
|
||||
android:textColor="?android:attr/textColorPrimaryInverse"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:paddingLeft="10dp"
|
||||
android:paddingRight="10dp"
|
||||
android:paddingTop="3dp"
|
||||
android:paddingBottom="3dp"/>
|
@ -31,6 +31,15 @@
|
||||
|
||||
</org.mozilla.gecko.AboutHomeContent>
|
||||
|
||||
<org.mozilla.gecko.AutoCompletePopup android:id="@+id/autocomplete_popup"
|
||||
style="@android:style/Widget.ListView.White"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="100dip"
|
||||
android:background="@drawable/autocomplete_list_bg"
|
||||
android:cacheColorHint="#ffffff"
|
||||
android:listSelector="@android:drawable/list_selector_background"
|
||||
android:visibility="gone"/>
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
@ -311,12 +311,14 @@ public class PanZoomController
|
||||
cancelTouch();
|
||||
// fall through
|
||||
case PANNING_HOLD_LOCKED:
|
||||
GeckoApp.mAppContext.mAutoCompletePopup.hide();
|
||||
mState = PanZoomState.PANNING_LOCKED;
|
||||
// fall through
|
||||
case PANNING_LOCKED:
|
||||
track(event);
|
||||
return true;
|
||||
case PANNING_HOLD:
|
||||
GeckoApp.mAppContext.mAutoCompletePopup.hide();
|
||||
mState = PanZoomState.PANNING;
|
||||
// fall through
|
||||
case PANNING:
|
||||
@ -779,10 +781,11 @@ public class PanZoomController
|
||||
// If we aren't overscrolled, just apply friction.
|
||||
float excess = getExcess();
|
||||
if (disableSnap || FloatUtils.fuzzyEquals(excess, 0.0f)) {
|
||||
float absvelocity = (float)
|
||||
Math.pow(Math.pow(velocity, FRICTION_FACTOR) * FRICTION,
|
||||
float absvelocity = Math.abs(velocity);
|
||||
absvelocity = (float)Math.pow(Math.pow(absvelocity, FRICTION_FACTOR) * FRICTION,
|
||||
1 / FRICTION_FACTOR);
|
||||
velocity = Math.copySign(absvelocity, velocity);
|
||||
// Math.copySign doesn't exist on Android 2.2
|
||||
velocity = (velocity < 0 ? -absvelocity : absvelocity);
|
||||
|
||||
if (Math.abs(velocity) < 0.1f) {
|
||||
velocity = 0.0f;
|
||||
@ -990,6 +993,8 @@ public class PanZoomController
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
|
||||
GeckoApp.mAppContext.mAutoCompletePopup.hide();
|
||||
|
||||
GeckoEvent e = new GeckoEvent("Gesture:SingleTap", ret.toString());
|
||||
GeckoAppShell.sendEventToGecko(e);
|
||||
return true;
|
||||
|
@ -201,6 +201,7 @@ var BrowserApp = {
|
||||
|
||||
NativeWindow.init();
|
||||
Downloads.init();
|
||||
FormAssistant.init();
|
||||
OfflineApps.init();
|
||||
IndexedDB.init();
|
||||
XPInstallObserver.init();
|
||||
@ -209,6 +210,8 @@ var BrowserApp = {
|
||||
|
||||
// Init LoginManager
|
||||
Cc["@mozilla.org/login-manager;1"].getService(Ci.nsILoginManager);
|
||||
// Init FormHistory
|
||||
Cc["@mozilla.org/satchel/form-history;1"].getService(Ci.nsIFormHistory2);
|
||||
|
||||
let uri = "about:home";
|
||||
if ("arguments" in window && window.arguments[0])
|
||||
@ -262,6 +265,7 @@ var BrowserApp = {
|
||||
|
||||
shutdown: function shutdown() {
|
||||
NativeWindow.uninit();
|
||||
FormAssistant.uninit();
|
||||
OfflineApps.uninit();
|
||||
IndexedDB.uninit();
|
||||
ViewportHandler.uninit();
|
||||
@ -1393,8 +1397,12 @@ Tab.prototype = {
|
||||
|
||||
let browser = BrowserApp.getBrowserForWindow(contentWin);
|
||||
let uri = browser.currentURI.spec;
|
||||
let documentURI = browser.contentDocument.documentURIObject.spec;
|
||||
let contentType = browser.contentDocument.contentType;
|
||||
let documentURI = "";
|
||||
let contentType = "";
|
||||
if (browser.contentDocument) {
|
||||
documentURI = browser.contentDocument.documentURIObject.spec;
|
||||
contentType = browser.contentDocument.contentType;
|
||||
}
|
||||
|
||||
let message = {
|
||||
gecko: {
|
||||
@ -2172,8 +2180,99 @@ var ErrorPageEventHandler = {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
var FormAssistant = {
|
||||
// Used to keep track of the element that corresponds to the current
|
||||
// autocomplete suggestions
|
||||
_currentInputElement: null,
|
||||
|
||||
init: function() {
|
||||
Services.obs.addObserver(this, "FormAssist:AutoComplete", false);
|
||||
Services.obs.addObserver(this, "FormAssist:Closed", false);
|
||||
|
||||
BrowserApp.deck.addEventListener("compositionstart", this, false);
|
||||
BrowserApp.deck.addEventListener("compositionupdate", this, false);
|
||||
},
|
||||
|
||||
uninit: function() {
|
||||
Services.obs.removeObserver(this, "FormAssist:AutoComplete");
|
||||
Services.obs.removeObserver(this, "FormAssist:Closed");
|
||||
},
|
||||
|
||||
observe: function(aSubject, aTopic, aData) {
|
||||
switch (aTopic) {
|
||||
case "FormAssist:AutoComplete":
|
||||
if (!this._currentInputElement)
|
||||
break;
|
||||
|
||||
// Remove focus from the textbox to avoid some bad IME interactions
|
||||
this._currentInputElement.blur();
|
||||
this._currentInputElement.value = aData;
|
||||
break;
|
||||
|
||||
case "FormAssist:Closed":
|
||||
this._currentInputElement = null;
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
handleEvent: function(aEvent) {
|
||||
switch (aEvent.type) {
|
||||
case "compositionstart":
|
||||
case "compositionupdate":
|
||||
let currentElement = aEvent.target;
|
||||
if (!this._isAutocomplete(currentElement))
|
||||
break;
|
||||
|
||||
// Keep track of input element so we can fill it in if the user
|
||||
// selects an autocomplete suggestion
|
||||
this._currentInputElement = currentElement;
|
||||
let suggestions = this._getAutocompleteSuggestions(aEvent.data, currentElement);
|
||||
|
||||
let rect = currentElement.getBoundingClientRect();
|
||||
let zoom = BrowserApp.selectedTab.viewport.zoom;
|
||||
|
||||
sendMessageToJava({
|
||||
gecko: {
|
||||
type: "FormAssist:AutoComplete",
|
||||
suggestions: suggestions,
|
||||
rect: [rect.left, rect.top, rect.width, rect.height],
|
||||
zoom: zoom
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
_isAutocomplete: function (aElement) {
|
||||
if (!(aElement instanceof HTMLInputElement) ||
|
||||
(aElement.getAttribute("type") == "password") ||
|
||||
(aElement.hasAttribute("autocomplete") &&
|
||||
aElement.getAttribute("autocomplete").toLowerCase() == "off"))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
/** Retrieve the autocomplete list from the autocomplete service for an element */
|
||||
_getAutocompleteSuggestions: function(aSearchString, aElement) {
|
||||
let results = Cc["@mozilla.org/satchel/form-autocomplete;1"].
|
||||
getService(Ci.nsIFormAutoComplete).
|
||||
autoCompleteSearch(aElement.name || aElement.id, aSearchString, aElement, null);
|
||||
|
||||
let suggestions = [];
|
||||
if (results.matchCount > 0) {
|
||||
for (let i = 0; i < results.matchCount; i++) {
|
||||
let value = results.getValueAt(i);
|
||||
// Do not show the value if it is the current one in the input field
|
||||
if (value == aSearchString)
|
||||
continue;
|
||||
|
||||
suggestions.push(value);
|
||||
}
|
||||
}
|
||||
|
||||
return suggestions;
|
||||
},
|
||||
|
||||
show: function(aList, aElement) {
|
||||
let data = JSON.parse(sendMessageToJava({ gecko: aList }));
|
||||
let selected = data.button;
|
||||
|
@ -55,7 +55,7 @@ let modules = {
|
||||
privileged: true,
|
||||
hide: true
|
||||
},
|
||||
get firefox() this[fennec],
|
||||
get firefox() this.fennec,
|
||||
|
||||
// about:blank has some bad loading behavior we can avoid, if we use an alias
|
||||
empty: {
|
||||
|
@ -177,15 +177,21 @@ let Util = {
|
||||
return this._isTablet = true;
|
||||
|
||||
#ifdef ANDROID
|
||||
// Disable tablet mode on non-honeycomb devices because of theme bugs (bug 705026)
|
||||
let sysInfo = Cc["@mozilla.org/system-info;1"].getService(Ci.nsIPropertyBag2);
|
||||
let shellVersion = sysInfo.get("shellVersion") || "";
|
||||
let matches = shellVersion.match(/\((\d+)\)$/);
|
||||
if (matches) {
|
||||
let sdkVersion = parseInt(matches[1]);
|
||||
if (sdkVersion < 11 || sdkVersion > 13)
|
||||
// Disable tablet mode on pre-honeycomb devices because of theme bugs (bug 705026)
|
||||
if (sdkVersion < 11)
|
||||
return this._isTablet = false;
|
||||
|
||||
// Always enable tablet mode on honeycomb devices.
|
||||
if (sdkVersion < 14)
|
||||
return this._isTablet = true;
|
||||
}
|
||||
// On Ice Cream Sandwich devices, switch modes based on screen size.
|
||||
return this._isTablet = sysInfo.get("isTablet");
|
||||
#endif
|
||||
|
||||
let dpi = this.displayDPI;
|
||||
|
@ -146,7 +146,7 @@ chrome.jar:
|
||||
skin/images/aurora-lightbox-close.png (images/aurora-lightbox-close.png)
|
||||
|
||||
chrome.jar:
|
||||
% skin browser classic/1.0 %skin/gingerbread/ os=Android osversion=2.3 osversion=2.3.3 osversion=2.3.4 osversion=2.3.5 osversion=2.3.6 osversion=2.3.7 osversion=2.3.8 osversion>=4.0
|
||||
% skin browser classic/1.0 %skin/gingerbread/ os=Android osversion>=2.3
|
||||
% skin browser gingerbread/1.0 %skin/gingerbread/
|
||||
skin/gingerbread/aboutPage.css (aboutPage.css)
|
||||
skin/gingerbread/about.css (about.css)
|
||||
@ -285,7 +285,10 @@ chrome.jar:
|
||||
skin/gingerbread/images/aurora-lightbox-close.png (images/aurora-lightbox-close.png)
|
||||
|
||||
chrome.jar:
|
||||
% skin browser classic/1.0 %skin/honeycomb/ os=Android osversion=3.0 osversion=3.1 osversion=3.2 osversion=3.2.1 osversion=3.2.2 osversion=3.2.3 osversion=3.2.4 osversion=3.2.5 osversion=3.2.6 osversion=3.2.7 osversion=3.2.8 osversion=3.2.9
|
||||
# Always use the honeycomb theme on honeycomb devices.
|
||||
% skin browser classic/1.0 %skin/honeycomb/ os=Android osversion>=3.0
|
||||
# On Ice Cream Sandwich devices, switch themes based on screen size.
|
||||
% skin browser classic/1.0 %skin/gingerbread/ os=Android osversion>=4.0 tablet=0
|
||||
% skin browser honeycomb/1.0 %skin/honeycomb/
|
||||
skin/honeycomb/aboutPage.css (aboutPage.css)
|
||||
skin/honeycomb/about.css (about.css)
|
||||
|
@ -1472,6 +1472,9 @@ pref("dom.max_script_run_time", 10);
|
||||
// resolved.
|
||||
pref("hangmonitor.timeout", 0);
|
||||
|
||||
// If true, plugins will be click to play
|
||||
pref("plugins.click_to_play", false);
|
||||
|
||||
#ifndef DEBUG
|
||||
// How long a plugin is allowed to process a synchronous IPC message
|
||||
// before we consider it "hung".
|
||||
|
@ -1 +1 @@
|
||||
http://hg.mozilla.org/projects/addon-sdk/archive/52fd4dc4e77d.tar.bz2
|
||||
http://hg.mozilla.org/projects/addon-sdk/archive/34b9f7aff342.tar.bz2
|
||||
|
@ -21,6 +21,7 @@
|
||||
*
|
||||
* Contributor(s):
|
||||
* Taras Glek <tglek@mozilla.com>
|
||||
* Vladan Djeric <vdjeric@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
@ -81,7 +82,7 @@ public:
|
||||
typedef nsBaseHashtableET<nsCStringHashKey, StmtStats> SlowSQLEntryType;
|
||||
|
||||
private:
|
||||
bool AddSlowSQLInfo(JSContext *cx, JSObject *rootObj, bool mainThread);
|
||||
bool AddSQLInfo(JSContext *cx, JSObject *rootObj, bool mainThread);
|
||||
|
||||
// This is used for speedy JS string->Telemetry::ID conversions
|
||||
typedef nsBaseHashtableET<nsCharPtrHashKey, Telemetry::ID> CharPtrEntryType;
|
||||
@ -325,41 +326,26 @@ TelemetryImpl::NewHistogram(const nsACString &name, PRUint32 min, PRUint32 max,
|
||||
struct EnumeratorArgs {
|
||||
JSContext *cx;
|
||||
JSObject *statsObj;
|
||||
JSObject *statementsObj;
|
||||
int32 statementIndex;
|
||||
};
|
||||
|
||||
PLDHashOperator
|
||||
StatementEnumerator(TelemetryImpl::SlowSQLEntryType *entry, void *arg)
|
||||
{
|
||||
EnumeratorArgs *args = static_cast<EnumeratorArgs *>(arg);
|
||||
const nsACString &statement = entry->GetKey();
|
||||
const nsACString &sql = entry->GetKey();
|
||||
jsval hitCount = UINT_TO_JSVAL(entry->mData.hitCount);
|
||||
jsval totalTime = UINT_TO_JSVAL(entry->mData.totalTime);
|
||||
args->statementIndex++;
|
||||
|
||||
JSObject *hitsAndTimeObj = JS_NewArrayObject(args->cx, 2, nsnull);
|
||||
if (!hitsAndTimeObj ||
|
||||
!JS_SetElement(args->cx, hitsAndTimeObj, 0, &hitCount) ||
|
||||
!JS_SetElement(args->cx, hitsAndTimeObj, 1, &totalTime))
|
||||
JSObject *arrayObj = JS_NewArrayObject(args->cx, 2, nsnull);
|
||||
if (!arrayObj ||
|
||||
!JS_SetElement(args->cx, arrayObj, 0, &hitCount) ||
|
||||
!JS_SetElement(args->cx, arrayObj, 1, &totalTime))
|
||||
return PL_DHASH_STOP;
|
||||
|
||||
jsid propertyId = INT_TO_JSID(args->statementIndex);
|
||||
JSBool success = JS_DefinePropertyById(args->cx, args->statsObj,
|
||||
INT_TO_JSID(args->statementIndex),
|
||||
OBJECT_TO_JSVAL(hitsAndTimeObj),
|
||||
NULL, NULL, JSPROP_ENUMERATE);
|
||||
if (!success)
|
||||
return PL_DHASH_STOP;
|
||||
|
||||
JSString *string = JS_NewStringCopyN(args->cx, statement.BeginReading(), statement.Length());
|
||||
if (!string)
|
||||
return PL_DHASH_STOP;
|
||||
|
||||
success = JS_DefinePropertyById(args->cx, args->statementsObj,
|
||||
INT_TO_JSID(args->statementIndex),
|
||||
STRING_TO_JSVAL(string), NULL, NULL,
|
||||
JSPROP_ENUMERATE);
|
||||
JSBool success = JS_DefineProperty(args->cx, args->statsObj,
|
||||
sql.BeginReading(),
|
||||
OBJECT_TO_JSVAL(arrayObj),
|
||||
NULL, NULL, JSPROP_ENUMERATE);
|
||||
if (!success)
|
||||
return PL_DHASH_STOP;
|
||||
|
||||
@ -367,28 +353,20 @@ StatementEnumerator(TelemetryImpl::SlowSQLEntryType *entry, void *arg)
|
||||
}
|
||||
|
||||
bool
|
||||
TelemetryImpl::AddSlowSQLInfo(JSContext *cx, JSObject *rootObj, bool mainThread)
|
||||
TelemetryImpl::AddSQLInfo(JSContext *cx, JSObject *rootObj, bool mainThread)
|
||||
{
|
||||
JSObject *statementsObj = JS_NewObject(cx, NULL, NULL, NULL);
|
||||
JSObject *statsObj = JS_NewObject(cx, NULL, NULL, NULL);
|
||||
if (!statementsObj || !statsObj)
|
||||
if (!statsObj)
|
||||
return false;
|
||||
|
||||
JSBool ok = JS_DefineProperty(cx, rootObj,
|
||||
mainThread ? "slowSQLOnMain" : "slowSQLOnOther",
|
||||
OBJECT_TO_JSVAL(statementsObj),
|
||||
mainThread ? "mainThread" : "otherThreads",
|
||||
OBJECT_TO_JSVAL(statsObj),
|
||||
NULL, NULL, JSPROP_ENUMERATE);
|
||||
if (!ok)
|
||||
return false;
|
||||
|
||||
ok = JS_DefineProperty(cx, rootObj,
|
||||
mainThread ? "slowSQLStatsMain" : "slowSQLStatsOther",
|
||||
OBJECT_TO_JSVAL(statsObj),
|
||||
NULL, NULL, JSPROP_ENUMERATE);
|
||||
if (!ok)
|
||||
return false;
|
||||
|
||||
EnumeratorArgs args = { cx, statsObj, statementsObj, 0 };
|
||||
EnumeratorArgs args = { cx, statsObj };
|
||||
nsTHashtable<SlowSQLEntryType> *sqlMap;
|
||||
sqlMap = (mainThread ? &mSlowSQLOnMainThread : &mSlowSQLOnOtherThread);
|
||||
PRUint32 num = sqlMap->EnumerateEntries(StatementEnumerator,
|
||||
@ -420,13 +398,23 @@ TelemetryImpl::GetHistogramSnapshots(JSContext *cx, jsval *ret)
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
TelemetryImpl::GetSlowSQL(JSContext *cx, jsval *ret)
|
||||
{
|
||||
JSObject *root_obj = JS_NewObject(cx, NULL, NULL, NULL);
|
||||
if (!root_obj)
|
||||
return NS_ERROR_FAILURE;
|
||||
*ret = OBJECT_TO_JSVAL(root_obj);
|
||||
|
||||
MutexAutoLock hashMutex(mHashMutex);
|
||||
// Add info about slow SQL queries on the main thread
|
||||
if (!AddSlowSQLInfo(cx, root_obj, true))
|
||||
if (!AddSQLInfo(cx, root_obj, true))
|
||||
return NS_ERROR_FAILURE;
|
||||
// Add info about slow SQL queries on other threads
|
||||
if (!AddSlowSQLInfo(cx, root_obj, false))
|
||||
if (!AddSQLInfo(cx, root_obj, false))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
return NS_OK;
|
||||
|
@ -18,6 +18,7 @@
|
||||
*
|
||||
* Contributor(s):
|
||||
* Taras Glek <tglek@mozilla.com>
|
||||
* Vladan Djeric <vdjeric@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
@ -323,7 +324,8 @@ TelemetryPing.prototype = {
|
||||
ver: PAYLOAD_VERSION,
|
||||
info: this.getMetadata(reason),
|
||||
simpleMeasurements: getSimpleMeasurements(),
|
||||
histograms: this.getHistograms()
|
||||
histograms: this.getHistograms(),
|
||||
slowSQL: Telemetry.slowSQL
|
||||
};
|
||||
|
||||
let isTestPing = (reason == "test-ping");
|
||||
|
@ -21,6 +21,7 @@
|
||||
*
|
||||
* Contributor(s):
|
||||
* Taras Glek <tglek@mozilla.com>
|
||||
* Vladan Djeric <vdjeric@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
@ -66,6 +67,24 @@ interface nsITelemetry : nsISupports
|
||||
[implicit_jscontext]
|
||||
readonly attribute jsval histogramSnapshots;
|
||||
|
||||
/*
|
||||
* An object containing information about slow SQL prepared statements.
|
||||
*
|
||||
* {
|
||||
* mainThread: { "sqlString1": [<hit count>, <total time>], "sqlString2": [...], ... },
|
||||
* otherThreads: { "sqlString3": [<hit count>, <total time>], "sqlString4": [...], ... }
|
||||
* }
|
||||
*
|
||||
* where:
|
||||
* mainThread: Slow statements that executed on the main thread
|
||||
* otherThreads: Slow statements that executed on a non-main thread
|
||||
* sqlString - String of the offending prepared statement
|
||||
* hit count - The number of times this statement required longer than the threshold time to execute
|
||||
* total time - The sum of all execution times above the threshold time for this statement
|
||||
*/
|
||||
[implicit_jscontext]
|
||||
readonly attribute jsval slowSQL;
|
||||
|
||||
/**
|
||||
* Create and return a histogram where bucket sizes increase exponentially. Parameters:
|
||||
*
|
||||
|
@ -90,6 +90,9 @@ function checkHistograms(request, response) {
|
||||
let tc = payload.histograms[TELEMETRY_SUCCESS]
|
||||
do_check_eq(uneval(tc),
|
||||
uneval(expected_tc));
|
||||
|
||||
do_check_true(("mainThread" in payload.slowSQL) &&
|
||||
("otherThreads" in payload.slowSQL));
|
||||
gFinished = true;
|
||||
}
|
||||
|
||||
|
@ -91,6 +91,11 @@ function test_getHistogramById() {
|
||||
do_check_true(s.static);
|
||||
}
|
||||
|
||||
function test_getSlowSQL() {
|
||||
var slow = Telemetry.slowSQL;
|
||||
do_check_true(("mainThread" in slow) && ("otherThreads" in slow));
|
||||
}
|
||||
|
||||
// Check that telemetry doesn't record in private mode
|
||||
function test_privateMode() {
|
||||
var h = Telemetry.newHistogram("test::private_mode_boolean", 1,2,3, Telemetry.HISTOGRAM_BOOLEAN);
|
||||
@ -117,5 +122,6 @@ function run_test()
|
||||
|
||||
test_boolean_histogram();
|
||||
test_getHistogramById();
|
||||
test_getSlowSQL();
|
||||
test_privateMode();
|
||||
}
|
||||
|
@ -51,6 +51,8 @@ MODULE = test_extensionmanager
|
||||
|
||||
ifneq (mobile,$(MOZ_BUILD_APP))
|
||||
DIRS += \
|
||||
xpinstall \
|
||||
browser \
|
||||
mochitest \
|
||||
$(NULL)
|
||||
endif
|
||||
|
@ -7,7 +7,6 @@
|
||||
|
||||
const URI_EXTENSION_UPDATE_DIALOG = "chrome://mozapps/content/extensions/update.xul";
|
||||
|
||||
const PREF_GETADDONS_CACHE_ENABLED = "extensions.getAddons.cache.enabled";
|
||||
const PREF_GETADDONS_BYIDS = "extensions.getAddons.get.url";
|
||||
const PREF_MIN_PLATFORM_COMPAT = "extensions.minCompatiblePlatformVersion";
|
||||
|
||||
@ -35,10 +34,6 @@ function test() {
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
Services.prefs.clearUserPref(PREF_GETADDONS_CACHE_ENABLED);
|
||||
});
|
||||
|
||||
function end_test() {
|
||||
// Test generates a lot of available installs so just cancel them all
|
||||
AddonManager.getAllInstalls(function(aInstalls) {
|
||||
|
@ -27,8 +27,6 @@ function test() {
|
||||
}
|
||||
|
||||
function end_test() {
|
||||
Services.prefs.clearUserPref(PREF_GETADDONS_GETSEARCHRESULTS);
|
||||
|
||||
// Test generates a lot of available installs so just cancel them all
|
||||
AddonManager.getAllInstalls(function(aInstalls) {
|
||||
aInstalls.forEach(function(aInstall) {
|
||||
|
@ -73,7 +73,6 @@ function test() {
|
||||
|
||||
|
||||
function end_test() {
|
||||
Services.prefs.clearUserPref(PREF_GETADDONS_GETSEARCHRESULTS);
|
||||
close_manager(gManagerWindow, finish);
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,6 @@
|
||||
|
||||
// Tests that the discovery view loads properly
|
||||
|
||||
const PREF_GETADDONS_CACHE_ENABLED = "extensions.getAddons.cache.enabled";
|
||||
const MAIN_URL = "https://example.com/" + RELATIVE_DIR + "discovery.html";
|
||||
|
||||
var gManagerWindow;
|
||||
@ -40,10 +39,6 @@ function test() {
|
||||
// Temporarily enable caching
|
||||
Services.prefs.setBoolPref(PREF_GETADDONS_CACHE_ENABLED, true);
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
Services.prefs.setBoolPref(PREF_GETADDONS_CACHE_ENABLED, false);
|
||||
});
|
||||
|
||||
waitForExplicitFinish();
|
||||
|
||||
gProvider = new MockProvider();
|
||||
|
@ -26,11 +26,7 @@ function test() {
|
||||
}
|
||||
|
||||
function end_test() {
|
||||
close_manager(gManagerWindow, function() {
|
||||
Services.prefs.clearUserPref("extensions.getAddons.search.url");
|
||||
|
||||
finish();
|
||||
});
|
||||
close_manager(gManagerWindow, finish);
|
||||
}
|
||||
|
||||
function get_node(parent, anonid) {
|
||||
|
@ -29,7 +29,6 @@ function test() {
|
||||
|
||||
function end_test() {
|
||||
close_manager(gManagerWindow, function() {
|
||||
Services.prefs.clearUserPref("extensions.getAddons.search.url");
|
||||
Services.prefs.clearUserPref("extensions.checkUpdateSecurity");
|
||||
|
||||
AddonManager.getAddonByID("addon1@tests.mozilla.org", function(aAddon) {
|
||||
|
@ -5,7 +5,6 @@
|
||||
// Tests that compatibility overrides are refreshed when showing the addon
|
||||
// selection UI.
|
||||
|
||||
const PREF_GETADDONS_CACHE_ENABLED = "extensions.getAddons.cache.enabled";
|
||||
const PREF_GETADDONS_BYIDS = "extensions.getAddons.get.url";
|
||||
const PREF_MIN_PLATFORM_COMPAT = "extensions.minCompatiblePlatformVersion";
|
||||
|
||||
@ -45,8 +44,6 @@ registerCleanupFunction(function() {
|
||||
if (gTestAddon)
|
||||
gTestAddon.uninstall();
|
||||
|
||||
Services.prefs.clearUserPref(PREF_GETADDONS_CACHE_ENABLED);
|
||||
Services.prefs.clearUserPref(PREF_GETADDONS_BYIDS);
|
||||
Services.prefs.clearUserPref(PREF_MIN_PLATFORM_COMPAT);
|
||||
});
|
||||
|
||||
|
@ -21,6 +21,7 @@ const TESTROOT2 = "http://example.org/" + RELATIVE_DIR;
|
||||
const CHROMEROOT = pathParts.join("/") + "/";
|
||||
const PREF_DISCOVERURL = "extensions.webservice.discoverURL";
|
||||
const PREF_UPDATEURL = "extensions.update.url";
|
||||
const PREF_GETADDONS_CACHE_ENABLED = "extensions.getAddons.cache.enabled";
|
||||
|
||||
const MANAGER_URI = "about:addons";
|
||||
const INSTALL_URI = "chrome://mozapps/content/xpinstall/xpinstallConfirm.xul";
|
||||
@ -34,24 +35,45 @@ var gTestStart = null;
|
||||
|
||||
var gUseInContentUI = !gTestInWindow && ("switchToTabHavingURI" in window);
|
||||
|
||||
var gDiscoveryURL = Services.prefs.getCharPref(PREF_DISCOVERURL);
|
||||
var gUpdateURL = Services.prefs.getCharPref(PREF_UPDATEURL);
|
||||
var gRestorePrefs = [{name: PREF_LOGGING_ENABLED},
|
||||
{name: "extensions.webservice.discoverURL"},
|
||||
{name: "extensions.update.url"},
|
||||
{name: "extensions.getAddons.get.url"},
|
||||
{name: "extensions.getAddons.search.browseURL"},
|
||||
{name: "extensions.getAddons.search.url"},
|
||||
{name: "extensions.getAddons.cache.enabled"},
|
||||
{name: PREF_SEARCH_MAXRESULTS},
|
||||
{name: PREF_STRICT_COMPAT}];
|
||||
|
||||
gRestorePrefs.forEach(function(aPref) {
|
||||
if (!Services.prefs.prefHasUserValue(aPref.name)) {
|
||||
aPref.type = "clear";
|
||||
return;
|
||||
}
|
||||
aPref.type = Services.prefs.getPrefType(aPref.name);
|
||||
if (aPref.type == Services.prefs.PREF_BOOL)
|
||||
aPref.value = Services.prefs.getBoolPref(aPref.name);
|
||||
else if (aPref.type == Services.prefs.PREF_INT)
|
||||
aPref.value = Services.prefs.getIntPref(aPref.name);
|
||||
else if (aPref.type == Services.prefs.PREF_STRING)
|
||||
aPref.value = Services.prefs.getCharPref(aPref.name);
|
||||
});
|
||||
|
||||
// Turn logging on for all tests
|
||||
Services.prefs.setBoolPref(PREF_LOGGING_ENABLED, true);
|
||||
// Turn off remote results in searches
|
||||
Services.prefs.setIntPref(PREF_SEARCH_MAXRESULTS, 0);
|
||||
registerCleanupFunction(function() {
|
||||
Services.prefs.clearUserPref(PREF_LOGGING_ENABLED);
|
||||
try {
|
||||
Services.prefs.clearUserPref(PREF_SEARCH_MAXRESULTS);
|
||||
} catch (e) {}
|
||||
try {
|
||||
Services.prefs.clearUserPref(PREF_STRICT_COMPAT);
|
||||
} catch (e) {}
|
||||
|
||||
Services.prefs.setCharPref(PREF_DISCOVERURL, gDiscoveryURL);
|
||||
Services.prefs.setCharPref(PREF_UPDATEURL, gUpdateURL);
|
||||
registerCleanupFunction(function() {
|
||||
// Restore prefs
|
||||
gRestorePrefs.forEach(function(aPref) {
|
||||
if (aPref.type == "clear")
|
||||
Services.prefs.clearUserPref(aPref.name);
|
||||
else if (aPref.type == Services.prefs.PREF_BOOL)
|
||||
Services.prefs.setBoolPref(aPref.name, aPref.value);
|
||||
else if (aPref.type == Services.prefs.PREF_INT)
|
||||
Services.prefs.setIntPref(aPref.name, aPref.value);
|
||||
else if (aPref.type == Services.prefs.PREF_STRING)
|
||||
Services.prefs.setCharPref(aPref.name, aPref.value);
|
||||
});
|
||||
|
||||
// Throw an error if the add-ons manager window is open anywhere
|
||||
var windows = Services.wm.getEnumerator("Addons:Manager");
|
||||
|
@ -156,6 +156,7 @@ AndroidBridge::Init(JNIEnv *jEnv,
|
||||
jPostToJavaThread = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "postToJavaThread", "(Z)V");
|
||||
jInitCamera = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "initCamera", "(Ljava/lang/String;III)[I");
|
||||
jCloseCamera = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "closeCamera", "()V");
|
||||
jIsTablet = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "isTablet", "()Z");
|
||||
jEnableBatteryNotifications = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "enableBatteryNotifications", "()V");
|
||||
jDisableBatteryNotifications = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "disableBatteryNotifications", "()V");
|
||||
jGetCurrentBatteryInformation = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "getCurrentBatteryInformation", "()[D");
|
||||
@ -1463,6 +1464,12 @@ AndroidBridge::UnlockWindow(void* window)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
AndroidBridge::IsTablet()
|
||||
{
|
||||
return mJNIEnv->CallStaticBooleanMethod(mGeckoAppShellClass, jIsTablet);
|
||||
}
|
||||
|
||||
/* Implementation file */
|
||||
NS_IMPL_ISUPPORTS1(nsAndroidBridge, nsIAndroidBridge)
|
||||
|
||||
|
@ -336,6 +336,8 @@ public:
|
||||
PRUint16 GetNumberOfMessagesForText(const nsAString& aText);
|
||||
void SendMessage(const nsAString& aNumber, const nsAString& aText);
|
||||
|
||||
bool IsTablet();
|
||||
|
||||
protected:
|
||||
static AndroidBridge *sBridge;
|
||||
|
||||
@ -411,6 +413,7 @@ protected:
|
||||
jmethodID jPostToJavaThread;
|
||||
jmethodID jInitCamera;
|
||||
jmethodID jCloseCamera;
|
||||
jmethodID jIsTablet;
|
||||
jmethodID jEnableBatteryNotifications;
|
||||
jmethodID jDisableBatteryNotifications;
|
||||
jmethodID jGetCurrentBatteryInformation;
|
||||
|
@ -345,6 +345,9 @@ nsMenuItemIconX::LoadIcon(nsIURI* aIconURI)
|
||||
nsnull, getter_AddRefs(mIconRequest));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// We need to request the icon be decoded (bug 573583, bug 705516).
|
||||
mIconRequest->RequestDecode();
|
||||
|
||||
return NS_OK;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
|
||||
@ -381,10 +384,6 @@ NS_IMETHODIMP
|
||||
nsMenuItemIconX::OnStartContainer(imgIRequest* aRequest,
|
||||
imgIContainer* aContainer)
|
||||
{
|
||||
// Request a decode
|
||||
NS_ABORT_IF_FALSE(aContainer, "who sent the notification then?");
|
||||
aContainer->RequestDecode();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -55,16 +55,12 @@
|
||||
#include "mozIAsyncFavicons.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "JumpListBuilder.h"
|
||||
#include "nsToolkit.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace widget {
|
||||
|
||||
// SHCreateItemFromParsingName is only available on vista and up. We only load this if we
|
||||
// need to call it on win7+.
|
||||
JumpListLink::SHCreateItemFromParsingNamePtr JumpListLink::createItemFromParsingName = nsnull;
|
||||
const PRUnichar JumpListLink::kSehllLibraryName[] = L"shell32.dll";
|
||||
const char JumpListItem::kJumpListCacheDir[] = "jumpListCache";
|
||||
HMODULE JumpListLink::sShellDll = nsnull;
|
||||
|
||||
// ISUPPORTS Impl's
|
||||
NS_IMPL_ISUPPORTS1(JumpListItem,
|
||||
@ -742,18 +738,11 @@ nsresult JumpListLink::GetShellItem(nsCOMPtr<nsIJumpListItem>& item, nsRefPtr<IS
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Load vista+ SHCreateItemFromParsingName
|
||||
if (createItemFromParsingName == nsnull) {
|
||||
if (sShellDll)
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
sShellDll = ::LoadLibraryW(kSehllLibraryName);
|
||||
if (sShellDll)
|
||||
createItemFromParsingName = (SHCreateItemFromParsingNamePtr)GetProcAddress(sShellDll, "SHCreateItemFromParsingName");
|
||||
if (createItemFromParsingName == nsnull)
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
if (!nsToolkit::VistaCreateItemFromParsingNameInit())
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
||||
// Create the IShellItem
|
||||
if (FAILED(createItemFromParsingName(NS_ConvertASCIItoUTF16(spec).get(),
|
||||
if (FAILED(nsToolkit::createItemFromParsingName(NS_ConvertASCIItoUTF16(spec).get(),
|
||||
NULL, IID_PPV_ARGS(&psi))))
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
|
@ -118,14 +118,9 @@ public:
|
||||
static nsresult GetJumpListLink(IShellItem *pItem, nsCOMPtr<nsIJumpListLink>& aLink);
|
||||
|
||||
protected:
|
||||
typedef HRESULT (WINAPI * SHCreateItemFromParsingNamePtr)(PCWSTR pszPath, IBindCtx *pbc, REFIID riid, void **ppv);
|
||||
|
||||
nsString mUriTitle;
|
||||
nsCOMPtr<nsIURI> mURI;
|
||||
nsCOMPtr<nsICryptoHash> mCryptoHash;
|
||||
static const PRUnichar kSehllLibraryName[];
|
||||
static HMODULE sShellDll;
|
||||
static SHCreateItemFromParsingNamePtr createItemFromParsingName;
|
||||
};
|
||||
|
||||
class JumpListShortcut : public JumpListItem, public nsIJumpListShortcut
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -23,6 +23,7 @@
|
||||
* Contributor(s):
|
||||
* Stuart Parmenter <pavlov@netscape.com>
|
||||
* Seth Spitzer <sspitzer@netscape.com>
|
||||
* Jim Mathies <jmathies@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
@ -41,30 +42,53 @@
|
||||
#ifndef nsFilePicker_h__
|
||||
#define nsFilePicker_h__
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#if MOZ_WINSDK_TARGETVER >= MOZ_NTDDI_LONGHORN
|
||||
// For Vista IFileDialog interfaces
|
||||
#if _WIN32_WINNT < _WIN32_WINNT_VISTA
|
||||
#define _WIN32_WINNT_bak _WIN32_WINNT
|
||||
#undef _WIN32_WINNT
|
||||
#define _WIN32_WINNT _WIN32_WINNT_VISTA
|
||||
#define _WIN32_IE_bak _WIN32_IE
|
||||
#undef _WIN32_IE
|
||||
#define _WIN32_IE _WIN32_IE_IE70
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "nsILocalFile.h"
|
||||
#include "nsITimer.h"
|
||||
#include "nsISimpleEnumerator.h"
|
||||
#include "nsCOMArray.h"
|
||||
#include "nsAutoPtr.h"
|
||||
|
||||
#include "nsICharsetConverterManager.h"
|
||||
#include "nsBaseFilePicker.h"
|
||||
#include "nsString.h"
|
||||
#include "nsdefs.h"
|
||||
#include <windows.h>
|
||||
#include <commdlg.h>
|
||||
#include <shobjidl.h>
|
||||
|
||||
/**
|
||||
* Native Windows FileSelector wrapper
|
||||
*/
|
||||
|
||||
class nsFilePicker : public nsBaseFilePicker
|
||||
#if MOZ_WINSDK_TARGETVER >= MOZ_NTDDI_LONGHORN
|
||||
, public IFileDialogEvents
|
||||
#endif
|
||||
{
|
||||
public:
|
||||
nsFilePicker();
|
||||
virtual ~nsFilePicker();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
#if MOZ_WINSDK_TARGETVER >= MOZ_NTDDI_LONGHORN
|
||||
// IUnknown's QueryInterface
|
||||
STDMETHODIMP QueryInterface(REFIID refiid, void** ppvResult);
|
||||
#endif
|
||||
|
||||
// nsIFilePicker (less what's in nsBaseFilePicker)
|
||||
// nsIFilePicker (less what's in nsBaseFilePicker)
|
||||
NS_IMETHOD GetDefaultString(nsAString& aDefaultString);
|
||||
NS_IMETHOD SetDefaultString(const nsAString& aDefaultString);
|
||||
NS_IMETHOD GetDefaultExtension(nsAString& aDefaultExtension);
|
||||
@ -78,6 +102,17 @@ public:
|
||||
NS_IMETHOD ShowW(PRInt16 *aReturnVal);
|
||||
NS_IMETHOD AppendFilter(const nsAString& aTitle, const nsAString& aFilter);
|
||||
|
||||
#if MOZ_WINSDK_TARGETVER >= MOZ_NTDDI_LONGHORN
|
||||
// IFileDialogEvents
|
||||
HRESULT STDMETHODCALLTYPE OnFileOk(IFileDialog *pfd);
|
||||
HRESULT STDMETHODCALLTYPE OnFolderChanging(IFileDialog *pfd, IShellItem *psiFolder);
|
||||
HRESULT STDMETHODCALLTYPE OnFolderChange(IFileDialog *pfd);
|
||||
HRESULT STDMETHODCALLTYPE OnSelectionChange(IFileDialog *pfd);
|
||||
HRESULT STDMETHODCALLTYPE OnShareViolation(IFileDialog *pfd, IShellItem *psi, FDE_SHAREVIOLATION_RESPONSE *pResponse);
|
||||
HRESULT STDMETHODCALLTYPE OnTypeChange(IFileDialog *pfd);
|
||||
HRESULT STDMETHODCALLTYPE OnOverwrite(IFileDialog *pfd, IShellItem *psi, FDE_OVERWRITE_RESPONSE *pResponse);
|
||||
#endif
|
||||
|
||||
protected:
|
||||
enum PickerType {
|
||||
PICKER_TYPE_OPEN,
|
||||
@ -90,13 +125,28 @@ protected:
|
||||
PRInt16 aMode);
|
||||
static void GetQualifiedPath(const PRUnichar *aInPath, nsString &aOutPath);
|
||||
void GetFilterListArray(nsString& aFilterList);
|
||||
bool GetFileName(OPENFILENAMEW* ofn, PickerType aType);
|
||||
bool FilePickerWrapper(OPENFILENAMEW* ofn, PickerType aType);
|
||||
bool ShowFolderPicker(const nsString& aInitialDir);
|
||||
bool ShowXPFolderPicker(const nsString& aInitialDir);
|
||||
bool ShowFilePicker(const nsString& aInitialDir);
|
||||
bool ShowXPFilePicker(const nsString& aInitialDir);
|
||||
void AppendXPFilter(const nsAString& aTitle, const nsAString& aFilter);
|
||||
void RememberLastUsedDirectory();
|
||||
bool IsPrivacyModeEnabled();
|
||||
bool IsDefaultPathLink();
|
||||
bool IsDefaultPathHtml();
|
||||
void SetDialogHandle(HWND aWnd);
|
||||
bool ClosePickerIfNeeded(bool aIsXPDialog);
|
||||
static void PickerCallbackTimerFunc(nsITimer *aTimer, void *aPicker);
|
||||
static UINT_PTR CALLBACK MultiFilePickerHook(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
static UINT_PTR CALLBACK FilePickerHook(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
nsCOMPtr<nsIWidget> mParentWidget;
|
||||
nsString mTitle;
|
||||
PRInt16 mMode;
|
||||
nsCString mFile;
|
||||
nsString mDefault;
|
||||
nsString mDefaultFilePath;
|
||||
nsString mDefaultFilename;
|
||||
nsString mDefaultExtension;
|
||||
nsString mFilterList;
|
||||
PRInt16 mSelectedType;
|
||||
@ -104,22 +154,50 @@ protected:
|
||||
static char mLastUsedDirectory[];
|
||||
nsString mUnicodeFile;
|
||||
static PRUnichar *mLastUsedUnicodeDirectory;
|
||||
};
|
||||
HWND mDlgWnd;
|
||||
|
||||
// The constructor will obtain the working path, the destructor
|
||||
// will set the working path back to what it used to be.
|
||||
class AutoRestoreWorkingPath
|
||||
{
|
||||
public:
|
||||
AutoRestoreWorkingPath();
|
||||
~AutoRestoreWorkingPath();
|
||||
inline bool HasWorkingPath() const
|
||||
#if MOZ_WINSDK_TARGETVER >= MOZ_NTDDI_LONGHORN
|
||||
class ComDlgFilterSpec
|
||||
{
|
||||
return mWorkingPath != NULL;
|
||||
}
|
||||
public:
|
||||
ComDlgFilterSpec() :
|
||||
mSpecList(nsnull),
|
||||
mLength(0) {}
|
||||
~ComDlgFilterSpec() {
|
||||
free(mSpecList);
|
||||
}
|
||||
|
||||
const PRUint32 Length() {
|
||||
return mLength;
|
||||
}
|
||||
|
||||
private:
|
||||
nsAutoArrayPtr<PRUnichar> mWorkingPath;
|
||||
const bool IsEmpty() {
|
||||
return (mLength == 0);
|
||||
}
|
||||
|
||||
const COMDLG_FILTERSPEC* get() {
|
||||
return mSpecList;
|
||||
}
|
||||
|
||||
void Append(const nsAString& aTitle, const nsAString& aFilter);
|
||||
private:
|
||||
COMDLG_FILTERSPEC* mSpecList;
|
||||
nsAutoTArray<nsString, 2> mStrings;
|
||||
PRUint32 mLength;
|
||||
};
|
||||
|
||||
ComDlgFilterSpec mComFilterList;
|
||||
DWORD mFDECookie;
|
||||
#endif
|
||||
};
|
||||
|
||||
#if MOZ_WINSDK_TARGETVER >= MOZ_NTDDI_LONGHORN
|
||||
#if defined(_WIN32_WINNT_bak)
|
||||
#undef _WIN32_WINNT
|
||||
#define _WIN32_WINNT _WIN32_WINNT_bak
|
||||
#undef _WIN32_IE
|
||||
#define _WIN32_IE _WIN32_IE_bak
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif // nsFilePicker_h__
|
||||
|
@ -54,11 +54,14 @@
|
||||
#include <unknwn.h>
|
||||
|
||||
nsToolkit* nsToolkit::gToolkit = nsnull;
|
||||
|
||||
HINSTANCE nsToolkit::mDllInstance = 0;
|
||||
|
||||
static const unsigned long kD3DUsageDelay = 5000;
|
||||
|
||||
// SHCreateItemFromParsingName is only available on vista and up.
|
||||
nsToolkit::SHCreateItemFromParsingNamePtr nsToolkit::createItemFromParsingName = nsnull;
|
||||
const PRUnichar nsToolkit::kSehllLibraryName[] = L"shell32.dll";
|
||||
HMODULE nsToolkit::sShellDll = nsnull;
|
||||
|
||||
static void
|
||||
StartAllowingD3D9(nsITimer *aTimer, void *aClosure)
|
||||
{
|
||||
@ -122,6 +125,24 @@ nsToolkit::StartAllowingD3D9()
|
||||
nsWindow::StartAllowingD3D9(false);
|
||||
}
|
||||
|
||||
// Load and store Vista+ SHCreateItemFromParsingName
|
||||
bool
|
||||
nsToolkit::VistaCreateItemFromParsingNameInit()
|
||||
{
|
||||
if (createItemFromParsingName)
|
||||
return true;
|
||||
if (sShellDll)
|
||||
return false;
|
||||
sShellDll = LoadLibraryW(kSehllLibraryName);
|
||||
if (!sShellDll)
|
||||
return false;
|
||||
createItemFromParsingName = (SHCreateItemFromParsingNamePtr)
|
||||
GetProcAddress(sShellDll, "SHCreateItemFromParsingName");
|
||||
if (createItemFromParsingName == nsnull)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
//
|
||||
// Return the nsToolkit for the current thread. If a toolkit does not
|
||||
|
@ -43,7 +43,8 @@
|
||||
|
||||
#include "nsITimer.h"
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
#include <windows.h>
|
||||
#include <shobjidl.h>
|
||||
#include <imm.h>
|
||||
|
||||
// Avoid including windowsx.h to prevent macro pollution
|
||||
@ -54,15 +55,6 @@
|
||||
#define GET_Y_LPARAM(pt) (short(HIWORD(pt)))
|
||||
#endif
|
||||
|
||||
// we used to use MAX_PATH
|
||||
// which works great for one file
|
||||
// but for multiple files, the format is
|
||||
// dirpath\0\file1\0file2\0...filen\0\0
|
||||
// and that can quickly be more than MAX_PATH (260)
|
||||
// see bug #172001 for more details
|
||||
#define FILE_BUFFER_SIZE 4096
|
||||
|
||||
|
||||
/**
|
||||
* Makes sure exit/enter mouse messages are always dispatched.
|
||||
* In the case where the mouse has exited the outer most window the
|
||||
@ -121,12 +113,18 @@ public:
|
||||
static void Startup(HMODULE hModule);
|
||||
static void Shutdown();
|
||||
static void StartAllowingD3D9();
|
||||
static bool VistaCreateItemFromParsingNameInit();
|
||||
|
||||
typedef HRESULT (WINAPI * SHCreateItemFromParsingNamePtr)(PCWSTR pszPath, IBindCtx *pbc, REFIID riid, void **ppv);
|
||||
static SHCreateItemFromParsingNamePtr createItemFromParsingName;
|
||||
|
||||
protected:
|
||||
static nsToolkit* gToolkit;
|
||||
|
||||
nsCOMPtr<nsITimer> mD3D9Timer;
|
||||
MouseTrailer mMouseTrailer;
|
||||
static const PRUnichar kSehllLibraryName[];
|
||||
static HMODULE sShellDll;
|
||||
};
|
||||
|
||||
#endif // TOOLKIT_H
|
||||
|
@ -310,6 +310,7 @@ public:
|
||||
void PickerOpen();
|
||||
void PickerClosed();
|
||||
|
||||
bool const DestroyCalled() { return mDestroyCalled; }
|
||||
protected:
|
||||
|
||||
// A magic number to identify the FAKETRACKPOINTSCROLLABLE window created
|
||||
|
@ -124,6 +124,8 @@ _CHROME_FILES += taskbar_previews.xul \
|
||||
$(NULL)
|
||||
|
||||
_TEST_FILES += test_bug565392.html \
|
||||
test_picker_no_crash.html \
|
||||
window_picker_no_crash_child.html \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
|
35
widget/tests/test_picker_no_crash.html
Normal file
35
widget/tests/test_picker_no_crash.html
Normal file
@ -0,0 +1,35 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test for crashes when the parent window of a file picker is closed via script</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
|
||||
<script type="application/javascript">
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
var childWindow;
|
||||
|
||||
function testStepOne() {
|
||||
childWindow = window.open('window_picker_no_crash_child.html', 'childWindow', 'width=300,height=150');
|
||||
SimpleTest.waitForFocus(testStepTwo, childWindow);
|
||||
}
|
||||
|
||||
function testStepTwo() {
|
||||
childWindow.document.form1.uploadbox.click();
|
||||
// This should not crash the browser
|
||||
childWindow.close();
|
||||
setTimeout("testStepThree();", 5000);
|
||||
}
|
||||
|
||||
function testStepThree() {
|
||||
ok(true, "browser didn't crash");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForFocus(testStepOne);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
10
widget/tests/window_picker_no_crash_child.html
Normal file
10
widget/tests/window_picker_no_crash_child.html
Normal file
@ -0,0 +1,10 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Picker window</title>
|
||||
</head>
|
||||
<body>
|
||||
<form name="form1">
|
||||
<input type="file" name="uploadbox">
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
@ -197,11 +197,11 @@ nsSystemInfo::Init()
|
||||
str.Append(NS_LITERAL_STRING(" ("));
|
||||
str.AppendInt(version);
|
||||
str.Append(NS_LITERAL_STRING(")"));
|
||||
}
|
||||
}
|
||||
SetPropertyAsAString(NS_LITERAL_STRING("shellVersion"), str);
|
||||
}
|
||||
|
||||
|
||||
bool isTablet = mozilla::AndroidBridge::Bridge()->IsTablet();
|
||||
SetPropertyAsBool(NS_LITERAL_STRING("isTablet"), isTablet);
|
||||
}
|
||||
#endif
|
||||
return NS_OK;
|
||||
|
@ -434,6 +434,9 @@ ParseManifest(NSLocationType type, FileLocation &file, char* buf, bool aChromeOn
|
||||
NS_NAMED_LITERAL_STRING(kOs, "os");
|
||||
NS_NAMED_LITERAL_STRING(kOsVersion, "osversion");
|
||||
NS_NAMED_LITERAL_STRING(kABI, "abi");
|
||||
#if defined(MOZ_WIDGET_ANDROID)
|
||||
NS_NAMED_LITERAL_STRING(kTablet, "tablet");
|
||||
#endif
|
||||
|
||||
// Obsolete
|
||||
NS_NAMED_LITERAL_STRING(kXPCNativeWrappers, "xpcnativewrappers");
|
||||
@ -498,8 +501,10 @@ ParseManifest(NSLocationType type, FileLocation &file, char* buf, bool aChromeOn
|
||||
gtk_major_version,
|
||||
gtk_minor_version);
|
||||
#elif defined(MOZ_WIDGET_ANDROID)
|
||||
bool isTablet = false;
|
||||
if (mozilla::AndroidBridge::Bridge()) {
|
||||
mozilla::AndroidBridge::Bridge()->GetStaticStringField("android/os/Build$VERSION", "RELEASE", osVersion);
|
||||
isTablet = mozilla::AndroidBridge::Bridge()->IsTablet();
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -587,6 +592,9 @@ ParseManifest(NSLocationType type, FileLocation &file, char* buf, bool aChromeOn
|
||||
TriState stOsVersion = eUnspecified;
|
||||
TriState stOs = eUnspecified;
|
||||
TriState stABI = eUnspecified;
|
||||
#if defined(MOZ_WIDGET_ANDROID)
|
||||
TriState stTablet = eUnspecified;
|
||||
#endif
|
||||
bool platform = false;
|
||||
bool contentAccessible = false;
|
||||
|
||||
@ -602,6 +610,14 @@ ParseManifest(NSLocationType type, FileLocation &file, char* buf, bool aChromeOn
|
||||
CheckVersionFlag(kGeckoVersion, wtoken, geckoVersion, stGeckoVersion))
|
||||
continue;
|
||||
|
||||
#if defined(MOZ_WIDGET_ANDROID)
|
||||
bool tablet = false;
|
||||
if (CheckFlag(kTablet, wtoken, tablet)) {
|
||||
stTablet = (tablet == isTablet) ? eOK : eBad;
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (directive->contentflags &&
|
||||
(CheckFlag(kPlatform, wtoken, platform) ||
|
||||
CheckFlag(kContentAccessible, wtoken, contentAccessible)))
|
||||
@ -627,6 +643,9 @@ ParseManifest(NSLocationType type, FileLocation &file, char* buf, bool aChromeOn
|
||||
stGeckoVersion == eBad ||
|
||||
stOs == eBad ||
|
||||
stOsVersion == eBad ||
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
stTablet == eBad ||
|
||||
#endif
|
||||
stABI == eBad)
|
||||
continue;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user