Merge IonMonkey to mozilla-central. a=arewefastyet

--HG--
rename : content/base/src/nsWebSocket.cpp => content/base/src/WebSocket.cpp
rename : content/base/src/nsWebSocket.h => content/base/src/WebSocket.h
This commit is contained in:
David Anderson 2012-09-11 10:25:14 -07:00
commit 76ab271ead
193 changed files with 4551 additions and 2468 deletions

View File

@ -164,7 +164,7 @@ int main(int argc, char* argv[])
}
char *lastSlash = strrchr(exePath, XPCOM_FILE_PATH_SEPARATOR[0]);
if (!lastSlash || (lastSlash - exePath > MAXPATHLEN - sizeof(XPCOM_DLL) - 1))
if (!lastSlash || ((lastSlash - exePath) + sizeof(XPCOM_DLL) + 1 > MAXPATHLEN))
return 255;
strcpy(++lastSlash, XPCOM_DLL);

View File

@ -3647,18 +3647,18 @@
}
}
var scrollRect = tabStrip.scrollClientRect;
var rect = tabStrip.getBoundingClientRect();
var minMargin = scrollRect.left - rect.left;
var maxMargin = Math.min(minMargin + scrollRect.width,
scrollRect.right);
if (!ltr)
[minMargin, maxMargin] = [this.clientWidth - maxMargin,
this.clientWidth - minMargin];
var newMargin;
if (pixelsToScroll) {
// if we are scrolling, put the drop indicator at the edge
// so that it doesn't jump while scrolling
let scrollRect = tabStrip.scrollClientRect;
let minMargin = scrollRect.left - rect.left;
let maxMargin = Math.min(minMargin + scrollRect.width,
scrollRect.right);
if (!ltr)
[minMargin, maxMargin] = [this.clientWidth - maxMargin,
this.clientWidth - minMargin];
newMargin = (pixelsToScroll > 0) ? maxMargin : minMargin;
}
else {

View File

@ -1638,11 +1638,15 @@ ContentPermissionPrompt.prototype = {
}
var browserBundle = Services.strings.createBundle("chrome://browser/locale/browser.properties");
let secHistogram = Components.classes["@mozilla.org/base/telemetry;1"].
getService(Ci.nsITelemetry).
getHistogramById("SECURITY_UI");
var mainAction = {
label: browserBundle.GetStringFromName("geolocation.shareLocation"),
accessKey: browserBundle.GetStringFromName("geolocation.shareLocation.accesskey"),
callback: function() {
secHistogram.add(Ci.nsISecurityUITelemetry.WARNING_GEOLOCATION_REQUEST_SHARE_LOCATION);
request.allow();
},
};
@ -1667,6 +1671,7 @@ ContentPermissionPrompt.prototype = {
accessKey: browserBundle.GetStringFromName("geolocation.alwaysShareLocation.accesskey"),
callback: function () {
Services.perms.addFromPrincipal(requestingPrincipal, "geo", Ci.nsIPermissionManager.ALLOW_ACTION);
secHistogram.add(Ci.nsISecurityUITelemetry.WARNING_GEOLOCATION_REQUEST_ALWAYS_SHARE);
request.allow();
}
});
@ -1675,6 +1680,7 @@ ContentPermissionPrompt.prototype = {
accessKey: browserBundle.GetStringFromName("geolocation.neverShareLocation.accesskey"),
callback: function () {
Services.perms.addFromPrincipal(requestingPrincipal, "geo", Ci.nsIPermissionManager.DENY_ACTION);
secHistogram.add(Ci.nsISecurityUITelemetry.WARNING_GEOLOCATION_REQUEST_NEVER_SHARE);
request.cancel();
}
});
@ -1683,6 +1689,7 @@ ContentPermissionPrompt.prototype = {
var browser = chromeWin.gBrowser.getBrowserForDocument(requestingWindow.document);
secHistogram.add(Ci.nsISecurityUITelemetry.WARNING_GEOLOCATION_REQUEST);
chromeWin.PopupNotifications.show(browser, "geolocation", message, "geo-notification-icon",
mainAction, secondaryActions);
}

View File

@ -1587,7 +1587,7 @@ richlistitem[type~="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-
-moz-radial-gradient(center 3px, circle cover, rgba(233,242,252,1) 3%, rgba(172,206,255,.75) 40%, rgba(87,151,201,.5) 80%, rgba(87,151,201,0));
}
#tabbrowser-tabs[positionpinnedtabs] > .tabbrowser-tab[pinned] {
#tabbrowser-tabs[positionpinnedtabs] > .tabbrowser-tab > .tab-stack > .tab-content[pinned] {
min-height: 18px; /* corresponds to the max. height of non-textual tab contents, i.e. the tab close button */
}

View File

@ -1923,10 +1923,6 @@ richlistitem[type~="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-
list-style-image: url("chrome://browser/skin/tabbrowser/loading.png");
}
#tabbrowser-tabs[positionpinnedtabs] > .tabbrowser-tab[pinned] {
min-height: 16px; /* corresponds to the max. height of non-textual tab contents, i.e. the favicon */
}
.tab-throbber[pinned],
.tab-icon-image[pinned] {
-moz-margin-start: 5px;

View File

@ -45,8 +45,7 @@ NS_IMPL_ISUPPORTS1(nsSecurityNameSet, nsIScriptExternalNameSet)
static JSBool
netscape_security_enablePrivilege(JSContext *cx, unsigned argc, jsval *vp)
{
xpc::EnableUniversalXPConnect(cx);
return JS_TRUE;
return xpc::EnableUniversalXPConnect(cx);
}
static JSFunctionSpec PrivilegeManager_static_methods[] = {

View File

@ -27,8 +27,6 @@ endif
ifndef CROSS_COMPILE
ifdef USE_ELF_DYNSTR_GC
export:: elf-dynstr-gc
# Compiling the above will create dependency files.
NEED_MDDEPDIR = 1
endif
endif
@ -141,8 +139,8 @@ GARBAGE += \
ifndef CROSS_COMPILE
ifdef USE_ELF_DYNSTR_GC
elf-dynstr-gc: elf-dynstr-gc.c $(GLOBAL_DEPS)
$(CC) $(COMPILE_CFLAGS) $(GLIB_CFLAGS) -o $@ $< $(LDFLAGS) $(GLIB_LIBS)
elf-dynstr-gc: elf-dynstr-gc.c $(GLOBAL_DEPS) $(call mkdir_deps,$(MDDEPDIR))
$(CC) $(COMPILE_CFLAGS) $(GLIB_CFLAGS) -o $@ $< $(LDFLAGS) $(GLIB_LIBS)
endif
endif

View File

@ -380,13 +380,7 @@ ifndef HOST_PROGOBJS
HOST_PROGOBJS = $(HOST_OBJS)
endif
# MAKE_DIRS: List of directories to build while looping over directories.
# A Makefile that needs $(MDDEPDIR) created but doesn't set any of these
# variables we know to check can just set NEED_MDDEPDIR explicitly.
ifneq (,$(OBJS)$(XPIDLSRCS)$(SIMPLE_PROGRAMS)$(NEED_MDDEPDIR))
MAKE_DIRS += $(CURDIR)/$(MDDEPDIR)
GARBAGE_DIRS += $(CURDIR)/$(MDDEPDIR)
endif
GARBAGE_DIRS += $(wildcard $(CURDIR)/$(MDDEPDIR))
#
# Tags: emacs (etags), vi (ctags)
@ -952,7 +946,7 @@ $(HOST_CMMOBJS): host_%.$(OBJ_SUFFIX): %.mm
$(REPORT_BUILD)
$(ELOG) $(HOST_CXX) $(HOST_OUTOPTION)$@ -c $(HOST_CXXFLAGS) $(HOST_CMMFLAGS) $(INCLUDES) $(NSPR_CFLAGS) $(_VPATH_SRCS)
$(COBJS): %.$(OBJ_SUFFIX): %.c
$(COBJS): %.$(OBJ_SUFFIX): %.c $(call mkdir_deps,$(MDDEPDIR))
$(REPORT_BUILD)
@$(MAKE_DEPS_AUTO_CC)
$(ELOG) $(CC) $(OUTOPTION)$@ -c $(COMPILE_CFLAGS) $(_VPATH_SRCS)
@ -982,45 +976,45 @@ $(SOBJS): %.$(OBJ_SUFFIX): %.S
#
# Please keep the next two rules in sync.
#
$(CCOBJS): %.$(OBJ_SUFFIX): %.cc
$(CCOBJS): %.$(OBJ_SUFFIX): %.cc $(call mkdir_deps,$(MDDEPDIR))
$(REPORT_BUILD)
@$(MAKE_DEPS_AUTO_CXX)
$(ELOG) $(CCC) $(OUTOPTION)$@ -c $(COMPILE_CXXFLAGS) $(_VPATH_SRCS)
$(CPPOBJS): %.$(OBJ_SUFFIX): %.cpp
$(CPPOBJS): %.$(OBJ_SUFFIX): %.cpp $(call mkdir_deps,$(MDDEPDIR))
$(REPORT_BUILD)
@$(MAKE_DEPS_AUTO_CXX)
$(ELOG) $(CCC) $(OUTOPTION)$@ -c $(COMPILE_CXXFLAGS) $(_VPATH_SRCS)
$(CMMOBJS): $(OBJ_PREFIX)%.$(OBJ_SUFFIX): %.mm
$(CMMOBJS): $(OBJ_PREFIX)%.$(OBJ_SUFFIX): %.mm $(call mkdir_deps,$(MDDEPDIR))
$(REPORT_BUILD)
@$(MAKE_DEPS_AUTO_CXX)
$(ELOG) $(CCC) -o $@ -c $(COMPILE_CXXFLAGS) $(COMPILE_CMMFLAGS) $(_VPATH_SRCS)
$(CMOBJS): $(OBJ_PREFIX)%.$(OBJ_SUFFIX): %.m
$(CMOBJS): $(OBJ_PREFIX)%.$(OBJ_SUFFIX): %.m $(call mkdir_deps,$(MDDEPDIR))
$(REPORT_BUILD)
@$(MAKE_DEPS_AUTO_CC)
$(ELOG) $(CC) -o $@ -c $(COMPILE_CFLAGS) $(COMPILE_CMFLAGS) $(_VPATH_SRCS)
%.s: %.cpp
%.s: %.cpp $(call mkdir_deps,$(MDDEPDIR))
$(CCC) -S $(COMPILE_CXXFLAGS) $(_VPATH_SRCS)
%.s: %.cc
%.s: %.cc $(call mkdir_deps,$(MDDEPDIR))
$(CCC) -S $(COMPILE_CXXFLAGS) $(_VPATH_SRCS)
%.s: %.c
%.s: %.c $(call mkdir_deps,$(MDDEPDIR))
$(CC) -S $(COMPILE_CFLAGS) $(_VPATH_SRCS)
%.i: %.cpp
%.i: %.cpp $(call mkdir_deps,$(MDDEPDIR))
$(CCC) -C -E $(COMPILE_CXXFLAGS) $(_VPATH_SRCS) > $*.i
%.i: %.cc
%.i: %.cc $(call mkdir_deps,$(MDDEPDIR))
$(CCC) -C -E $(COMPILE_CXXFLAGS) $(_VPATH_SRCS) > $*.i
%.i: %.c
%.i: %.c $(call mkdir_deps,$(MDDEPDIR))
$(CC) -C -E $(COMPILE_CFLAGS) $(_VPATH_SRCS) > $*.i
%.i: %.mm
%.i: %.mm $(call mkdir_deps,$(MDDEPDIR))
$(CCC) -C -E $(COMPILE_CXXFLAGS) $(COMPILE_CMMFLAGS) $(_VPATH_SRCS) > $*.i
%.res: %.rc
@ -1356,6 +1350,7 @@ endif
# objdir/_tests/modules/. If TESTING_JS_MODULE_DIR is defined, that path
# wlll be appended to the output directory.
ifdef ENABLE_TESTS
ifdef TESTING_JS_MODULES
testmodulesdir = $(DEPTH)/_tests/modules/$(TESTING_JS_MODULE_DIR)
@ -1367,6 +1362,7 @@ TESTING_JS_MODULES_DEST := $(testmodulesdir)
INSTALL_TARGETS += TESTING_JS_MODULES
endif
endif
endif
################################################################################
@ -1482,9 +1478,6 @@ endif
# dependency directory in the object directory, where we really need
# it.
$(CURDIR)/$(MDDEPDIR):
$(MKDIR) -p $@
ifneq (,$(filter-out all chrome default export realchrome tools clean clobber clobber_all distclean realclean,$(MAKECMDGOALS)))
MDDEPEND_FILES := $(strip $(wildcard $(foreach file,$(OBJS) $(PROGOBJS) $(HOST_OBJS) $(HOST_PROGOBJS) $(TARGETS) $(XPIDLSRCS:.idl=.h) $(XPIDLSRCS:.idl=.xpt),$(MDDEPDIR)/$(notdir $(file)).pp) $(addprefix $(MDDEPDIR)/,$(EXTRA_MDDEPEND_FILES))))

View File

@ -1616,6 +1616,50 @@ if test "$MOZ_PROFILING" -a -z "$STRIP_FLAGS"; then
STRIP_FLAGS="--strip-debug"
fi
dnl ========================================================
dnl = Use incremental GC
dnl ========================================================
JSGC_INCREMENTAL=1
MOZ_ARG_DISABLE_BOOL(gcincremental,
[ --disable-gcincremental Disable incremental GC],
JSGC_INCREMENTAL= )
if test -n "$JSGC_INCREMENTAL"; then
AC_DEFINE(JSGC_INCREMENTAL)
fi
dnl ========================================================
dnl = Use generational GC
dnl ========================================================
MOZ_ARG_ENABLE_BOOL(gcgenerational,
[ --enable-gcgenerational Enable generational GC],
JSGC_GENERATIONAL=1,
JSGC_GENERATIONAL= )
if test -n "$JSGC_GENERATIONAL"; then
AC_DEFINE(JSGC_GENERATIONAL)
fi
dnl ========================================================
dnl = Perform moving GC stack rooting analysis
dnl ========================================================
MOZ_ARG_ENABLE_BOOL(root-analysis,
[ --enable-root-analysis Enable moving GC stack root analysis],
JSGC_ROOT_ANALYSIS=1,
JSGC_ROOT_ANALYSIS= )
if test -n "$JSGC_ROOT_ANALYSIS"; then
AC_DEFINE(JSGC_ROOT_ANALYSIS)
fi
dnl ========================================================
dnl = Use exact stack rooting for GC
dnl ========================================================
MOZ_ARG_ENABLE_BOOL(exact-rooting,
[ --enable-exact-rooting Enable use of exact stack roots for GC],
JSGC_USE_EXACT_ROOTING=1,
JSGC_USE_EXACT_ROOTING= )
if test -n "$JSGC_USE_EXACT_ROOTING"; then
AC_DEFINE(JSGC_USE_EXACT_ROOTING)
fi
dnl ========================================================
dnl = Use Valgrind
dnl ========================================================

View File

@ -83,7 +83,6 @@ XPIDLSRCS = \
nsIXMLHttpRequest.idl \
nsIContentSecurityPolicy.idl \
nsIMessageManager.idl \
nsIWebSocket.idl \
nsIEventSource.idl \
$(NULL)

View File

@ -83,9 +83,3 @@ interface nsIDOMMozBlobBuilder : nsISupports
[implicit_jscontext] void append(in jsval data,
[optional] in DOMString endings);
};
dictionary BlobPropertyBag
{
DOMString type;
DOMString endings = "transparent";
};

View File

@ -1,95 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set sw=2 ts=8 et tw=80 : */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsISupports.idl"
interface nsIDOMEventListener;
interface nsIPrincipal;
interface nsIScriptContext;
interface nsPIDOMWindow;
interface nsIDOMDOMStringList;
interface nsIVariant;
%{C++
#include "nsTArray.h"
class nsString;
%}
[ref] native nsStringTArrayRef(nsTArray<nsString>);
/**
* The nsIWebSocket interface enables Web applications to maintain
* bidirectional communications with server-side processes as described in:
*
* http://dev.w3.org/html5/websockets/
*
*/
[scriptable, uuid(5224dbe7-58ac-43e6-93ba-f288a1421dff)]
interface nsIWebSocket : nsISupports
{
readonly attribute DOMString url;
readonly attribute DOMString extensions;
readonly attribute DOMString protocol;
//ready state
const unsigned short CONNECTING = 0;
const unsigned short OPEN = 1;
const unsigned short CLOSING = 2;
const unsigned short CLOSED = 3;
readonly attribute unsigned short readyState;
readonly attribute unsigned long bufferedAmount;
// "blob" by default: can set to "blob" or "arraybuffer": setting to other
// values will throw SYNTAX_ERR exception.
attribute DOMString binaryType;
// event handler attributes
[implicit_jscontext] attribute jsval onopen;
[implicit_jscontext] attribute jsval onmessage;
[implicit_jscontext] attribute jsval onerror;
[implicit_jscontext] attribute jsval onclose;
/**
* Transmits data to other end of the connection.
* @param data The data to be transmitted. Arraybuffers and Blobs are sent as
* binary data. Strings are sent as UTF-8 text data. Other types are
* converted to a String and sent as a String.
* @return if the connection is still established and the data was queued or
* sent successfully.
*/
[implicit_jscontext] void send(in nsIVariant data);
/**
* Closes the Web Socket connection or connection attempt, if any.
* If the connection is already closed, it does nothing.
*/
[optional_argc] void close([optional] in unsigned short code,
[optional] in DOMString reason);
/**
* Initialize the object for use from C++ code with the principal, script
* context, and owner window that should be used.
*
* @param principal The principal to use for the request. This must not be
* null.
* @param scriptContext The script context to use for the request. May be
* null.
* @param ownerWindow The associated window for the request. May be null.
* @param url The url for opening the socket. This must not be empty, and
* must have an absolute url, using either the ws or wss schemes.
* @param protocol Specifies array of sub-protocols acceptable to the client.
* If the length of the array is at least one, the server
* must select one of the listed sub-protocols for the
* connection to be successful. If empty, no sub-protocol is
* specified. The server selected sub-protocol can be read
* from the protocol attribute after connection.
*/
[noscript] void init(in nsIPrincipal principal,
in nsIScriptContext scriptContext,
in nsPIDOMWindow ownerWindow,
in DOMString url,
in nsStringTArrayRef protocol);
};

View File

@ -122,7 +122,7 @@ CPPSRCS = \
nsTraversal.cpp \
nsTreeSanitizer.cpp \
nsTreeWalker.cpp \
nsWebSocket.cpp \
WebSocket.cpp \
nsXHTMLContentSerializer.cpp \
nsXMLContentSerializer.cpp \
nsXMLHttpRequest.cpp \

View File

@ -0,0 +1,302 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set sw=2 ts=8 et tw=80 : */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef WebSocket_h__
#define WebSocket_h__
#include "mozilla/Util.h"
#include "nsWrapperCache.h"
#include "nsIWebSocketListener.h"
#include "nsISupports.h"
#include "mozilla/ErrorResult.h"
#include "mozilla/dom/TypedArray.h"
#include "mozilla/dom/BindingUtils.h"
// Need this for BinaryType.
#include "mozilla/dom/WebSocketBinding.h"
#include "jsfriendapi.h"
#include "nsISupportsUtils.h"
#include "nsCOMPtr.h"
#include "nsString.h"
#include "nsIPrincipal.h"
#include "nsCycleCollectionParticipant.h"
#include "nsIDOMEventListener.h"
#include "nsDOMEventTargetHelper.h"
#include "nsAutoPtr.h"
#include "nsIDOMDOMStringList.h"
#include "nsIInterfaceRequestor.h"
#include "nsIWebSocketChannel.h"
#include "nsIWebSocketListener.h"
#include "nsIObserver.h"
#include "nsIRequest.h"
#include "nsWeakReference.h"
#define DEFAULT_WS_SCHEME_PORT 80
#define DEFAULT_WSS_SCHEME_PORT 443
namespace mozilla {
namespace dom {
#define IMPL_EVENT_HANDLER(_lowercase) \
inline JSObject* GetOn##_lowercase(JSContext* aCx) \
{ \
JS::Value val; \
nsresult rv = GetOn##_lowercase(aCx, &val); \
return NS_SUCCEEDED(rv) ? JSVAL_TO_OBJECT(val) : nullptr; \
} \
void SetOn##_lowercase(JSContext* aCx, JSObject* aCallback, \
ErrorResult& aRv) \
{ \
aRv = SetOn##_lowercase(aCx, OBJECT_TO_JSVAL(aCallback)); \
} \
NS_IMETHOD GetOn##_lowercase(JSContext* cx, JS::Value* aVal); \
NS_IMETHOD SetOn##_lowercase(JSContext* cx, const JS::Value& aVal);
class WebSocket : public nsDOMEventTargetHelper,
public nsIInterfaceRequestor,
public nsIWebSocketListener,
public nsIObserver,
public nsSupportsWeakReference,
public nsIRequest
{
friend class CallDispatchConnectionCloseEvents;
friend class nsAutoCloseWS;
public:
enum {
CONNECTING = 0,
OPEN = 1,
CLOSING = 2,
CLOSED = 3
};
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS_INHERITED(WebSocket,
nsDOMEventTargetHelper)
NS_DECL_NSIINTERFACEREQUESTOR
NS_DECL_NSIWEBSOCKETLISTENER
NS_DECL_NSIOBSERVER
NS_DECL_NSIREQUEST
// nsIDOMEventTarget
NS_IMETHOD AddEventListener(const nsAString& aType,
nsIDOMEventListener *aListener,
bool aUseCapture,
bool aWantsUntrusted,
uint8_t optional_argc);
NS_IMETHOD RemoveEventListener(const nsAString& aType,
nsIDOMEventListener* aListener,
bool aUseCapture);
virtual void DisconnectFromOwner();
// nsWrapperCache
nsPIDOMWindow* GetParentObject() { return GetOwner(); }
JSObject* WrapObject(JSContext *cx,
JSObject *scope,
bool *triedToWrap);
public: // static helpers:
// Determine if preferences allow WebSocket
static bool PrefEnabled();
public: // WebIDL interface:
// Constructor:
static already_AddRefed<WebSocket> Constructor(JSContext *aCx,
nsISupports* aGlobal,
const nsAString& aUrl,
ErrorResult& rv);
static already_AddRefed<WebSocket> Constructor(JSContext *aCx,
nsISupports* aGlobal,
const nsAString& aUrl,
const nsAString& aProtocol,
ErrorResult& rv);
static already_AddRefed<WebSocket> Constructor(JSContext *aCx,
nsISupports* aGlobal,
const nsAString& aUrl,
const Sequence<nsString>& aProtocols,
ErrorResult& rv);
// webIDL: readonly attribute DOMString url
void GetUrl(nsAString& aResult);
// webIDL: readonly attribute unsigned short readyState;
uint16_t GetReadyState() { return (uint16_t)mReadyState; }
// webIDL: readonly attribute unsigned long bufferedAmount;
uint32_t GetBufferedAmount() { return (uint32_t) mOutgoingBufferedAmount; }
// webIDL: attribute Function? onopen;
IMPL_EVENT_HANDLER(open)
// webIDL: attribute Function? onerror;
IMPL_EVENT_HANDLER(error)
// webIDL: attribute Function? onclose;
IMPL_EVENT_HANDLER(close)
// webIDL: readonly attribute DOMString extensions;
void GetExtensions(nsAString& aResult);
// webIDL: readonly attribute DOMString protocol;
void GetProtocol(nsAString& aResult);
// webIDL: void close(optional unsigned short code, optional DOMString reason):
void Close(const Optional<uint16_t>& aCode,
const Optional<nsAString>& aReason,
ErrorResult& aRv);
// webIDL: attribute Function? onmessage;
IMPL_EVENT_HANDLER(message)
// webIDL: attribute DOMString binaryType;
BinaryType GetBinaryType() { return mBinaryType; }
void SetBinaryType(BinaryType aData) { mBinaryType = aData; }
// webIDL: void send(DOMString|Blob|ArrayBufferView data);
void Send(const nsAString& aData,
ErrorResult& aRv);
void Send(nsIDOMBlob* aData,
ErrorResult& aRv);
void Send(ArrayBuffer& aData,
ErrorResult& aRv);
void Send(ArrayBufferView& aData,
ErrorResult& aRv);
private: // constructor && distructor
WebSocket();
virtual ~WebSocket();
protected:
nsresult Init(JSContext* aCx,
nsIPrincipal* aPrincipal,
nsPIDOMWindow* aOwnerWindow,
const nsAString& aURL,
nsTArray<nsString>& aProtocolArray);
void Send(nsIInputStream* aMsgStream,
const nsACString& aMsgString,
uint32_t aMsgLength,
bool aIsBinary,
ErrorResult& aRv);
nsresult ParseURL(const nsString& aURL);
nsresult EstablishConnection();
// These methods when called can release the WebSocket object
nsresult FailConnection(uint16_t reasonCode,
const nsACString& aReasonString = EmptyCString());
nsresult CloseConnection(uint16_t reasonCode,
const nsACString& aReasonString = EmptyCString());
nsresult Disconnect();
nsresult ConsoleError();
nsresult PrintErrorOnConsole(const char* aBundleURI,
const PRUnichar* aError,
const PRUnichar** aFormatStrings,
uint32_t aFormatStringsLen);
nsresult DoOnMessageAvailable(const nsACString& aMsg,
bool isBinary);
// ConnectionCloseEvents: 'error' event if needed, then 'close' event.
// - These must not be dispatched while we are still within an incoming call
// from JS (ex: close()). Set 'sync' to false in that case to dispatch in a
// separate new event.
nsresult ScheduleConnectionCloseEvents(nsISupports* aContext,
nsresult aStatusCode,
bool sync);
// 2nd half of ScheduleConnectionCloseEvents, sometimes run in its own event.
void DispatchConnectionCloseEvents();
// These methods actually do the dispatch for various events.
nsresult CreateAndDispatchSimpleEvent(const nsString& aName);
nsresult CreateAndDispatchMessageEvent(const nsACString& aData,
bool isBinary);
nsresult CreateAndDispatchCloseEvent(bool aWasClean,
uint16_t aCode,
const nsString& aReason);
nsresult CreateResponseBlob(const nsACString& aData,
JSContext* aCx,
jsval& jsData);
// if there are "strong event listeners" (see comment in WebSocket.cpp) or
// outgoing not sent messages then this method keeps the object alive
// when js doesn't have strong references to it.
void UpdateMustKeepAlive();
// ATTENTION, when calling this method the object can be released
// (and possibly collected).
void DontKeepAliveAnyMore();
nsresult UpdateURI();
protected: //data
nsCOMPtr<nsIWebSocketChannel> mChannel;
// related to the WebSocket constructor steps
nsString mOriginalURL;
nsString mEffectiveURL; // after redirects
bool mSecure; // if true it is using SSL and the wss scheme,
// otherwise it is using the ws scheme with no SSL
bool mKeepingAlive;
bool mCheckMustKeepAlive;
bool mOnCloseScheduled;
bool mFailed;
bool mDisconnected;
// Set attributes of DOM 'onclose' message
bool mCloseEventWasClean;
nsString mCloseEventReason;
uint16_t mCloseEventCode;
nsCString mAsciiHost; // hostname
uint32_t mPort;
nsCString mResource; // [filepath[?query]]
nsString mUTF16Origin;
nsCOMPtr<nsIURI> mURI;
nsCString mRequestedProtocolList;
nsCString mEstablishedProtocol;
nsCString mEstablishedExtensions;
uint16_t mReadyState;
nsCOMPtr<nsIPrincipal> mPrincipal;
uint32_t mOutgoingBufferedAmount;
BinaryType mBinaryType;
// Web Socket owner information:
// - the script file name, UTF8 encoded.
// - source code line number where the Web Socket object was constructed.
// - the ID of the inner window where the script lives. Note that this may not
// be the same as the Web Socket owner window.
// These attributes are used for error reporting.
nsCString mScriptFile;
uint32_t mScriptLine;
uint64_t mInnerWindowID;
private:
WebSocket(const WebSocket& x) MOZ_DELETE; // prevent bad usage
WebSocket& operator=(const WebSocket& x) MOZ_DELETE;
};
} //namespace dom
} //namespace mozilla
#endif

View File

@ -5,6 +5,7 @@
#include "nsDOMBlobBuilder.h"
#include "jsfriendapi.h"
#include "mozilla/dom/BlobBinding.h"
#include "nsAutoPtr.h"
#include "nsDOMClassInfoID.h"
#include "nsIMultiplexInputStream.h"
@ -12,10 +13,10 @@
#include "nsTArray.h"
#include "nsJSUtils.h"
#include "nsContentUtils.h"
#include "DictionaryHelpers.h"
#include "nsIScriptError.h"
using namespace mozilla;
using namespace mozilla::dom;
NS_IMPL_ISUPPORTS_INHERITED1(nsDOMMultipartFile, nsDOMFile,
nsIJSNativeInitializer)
@ -181,14 +182,20 @@ nsDOMMultipartFile::InitInternal(JSContext* aCx,
{
bool nativeEOL = false;
if (aArgc > 1) {
mozilla::dom::BlobPropertyBag d;
nsresult rv = d.Init(aCx, &aArgv[1]);
NS_ENSURE_SUCCESS(rv, rv);
mContentType = d.type;
if (d.endings.EqualsLiteral("native")) {
nativeEOL = true;
} else if (!d.endings.EqualsLiteral("transparent")) {
return NS_ERROR_TYPE_ERR;
if (NS_IsMainThread()) {
BlobPropertyBag d;
if (!d.Init(aCx, aArgv[1])) {
return NS_ERROR_TYPE_ERR;
}
mContentType = d.type;
nativeEOL = d.endings == EndingTypesValues::Native;
} else {
BlobPropertyBagWorkers d;
if (!d.Init(aCx, aArgv[1])) {
return NS_ERROR_TYPE_ERR;
}
mContentType = d.type;
nativeEOL = d.endings == EndingTypesValues::Native;
}
}

View File

@ -2071,7 +2071,12 @@ nsNodeSelectorTearoff::QuerySelector(const nsAString& aSelector,
{
nsresult rv;
nsIContent* result = mNode->QuerySelector(aSelector, &rv);
return result ? CallQueryInterface(result, aReturn) : rv;
if (!result) {
*aReturn = nullptr;
return rv;
}
return CallQueryInterface(result, aReturn);
}
NS_IMETHODIMP

View File

@ -687,43 +687,37 @@ nsObjectLoadingContent::~nsObjectLoadingContent()
nsresult
nsObjectLoadingContent::InstantiatePluginInstance()
{
if (mType != eType_Plugin || mIsLoading) {
LOG(("OBJLC [%p]: Not instantiating loading or non-plugin object, type %u",
this, mType));
return NS_OK;
}
// Don't do anything if we already have an active instance.
if (mInstanceOwner) {
return NS_OK;
}
// Don't allow re-entry into initialization code.
if (mInstantiating) {
if (mInstanceOwner || mType != eType_Plugin || mIsLoading || mInstantiating) {
return NS_OK;
}
mInstantiating = true;
AutoSetInstantiatingToFalse autoInstantiating(this);
nsCOMPtr<nsIContent> thisContent =
do_QueryInterface(static_cast<nsIImageLoadingContent *>(this));
nsIDocument* doc = thisContent->GetCurrentDoc();
if (!doc || !InActiveDocument(thisContent)) {
NS_ERROR("Shouldn't be calling "
"InstantiatePluginInstance without an active document");
return NS_ERROR_FAILURE;
}
// Instantiating an instance can result in script execution, which
// can destroy this DOM object. Don't allow that for the scope
// of this method.
nsCOMPtr<nsIObjectLoadingContent> kungFuDeathGrip = this;
nsCOMPtr<nsIContent> thisContent =
do_QueryInterface(static_cast<nsIImageLoadingContent *>(this));
// Flush layout so that the plugin is initialized with the latest information.
nsIDocument* doc = thisContent->GetCurrentDoc();
if (!doc) {
return NS_ERROR_FAILURE;
}
if (!InActiveDocument(thisContent)) {
NS_ERROR("Shouldn't be calling "
"InstantiatePluginInstance in an inactive document");
return NS_ERROR_FAILURE;
}
// Flush layout so that the frame is created if possible and the plugin is
// initialized with the latest information.
doc->FlushPendingNotifications(Flush_Layout);
if (!thisContent->GetPrimaryFrame()) {
LOG(("OBJLC [%p]: Not instantiating plugin with no frame", this));
return NS_OK;
}
nsresult rv = NS_ERROR_FAILURE;
nsRefPtr<nsPluginHost> pluginHost =
already_AddRefed<nsPluginHost>(nsPluginHost::GetInst());
@ -1729,6 +1723,14 @@ nsObjectLoadingContent::LoadObject(bool aNotify,
oldType = mType;
oldState = ObjectState();
if (!thisContent->GetPrimaryFrame()) {
// We're un-rendered, and can't instantiate a plugin. HasNewFrame will
// re-start us when we can proceed.
LOG(("OBJLC [%p]: Aborting load - plugin-type, but no frame", this));
CloseChannel();
break;
}
rv = pluginHost->NewEmbeddedPluginStreamListener(mURI, this, nullptr,
getter_AddRefs(mFinalListener));
if (NS_SUCCEEDED(rv)) {

View File

@ -1,193 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set sw=2 ts=8 et tw=80 : */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef nsWebSocket_h__
#define nsWebSocket_h__
#include "nsISupportsUtils.h"
#include "nsIWebSocket.h"
#include "nsCOMPtr.h"
#include "nsString.h"
#include "nsIJSNativeInitializer.h"
#include "nsIPrincipal.h"
#include "nsCycleCollectionParticipant.h"
#include "nsIDOMEventListener.h"
#include "nsDOMEventTargetHelper.h"
#include "nsAutoPtr.h"
#include "nsIDOMDOMStringList.h"
#include "nsIInterfaceRequestor.h"
#include "nsIWebSocketChannel.h"
#include "nsIWebSocketListener.h"
#include "nsIObserver.h"
#include "nsIRequest.h"
#include "nsWeakReference.h"
#define DEFAULT_WS_SCHEME_PORT 80
#define DEFAULT_WSS_SCHEME_PORT 443
#define NS_WEBSOCKET_CID \
{ /* 7ca25214-98dc-40a6-bc1f-41ddbe41f46c */ \
0x7ca25214, 0x98dc, 0x40a6, \
{0xbc, 0x1f, 0x41, 0xdd, 0xbe, 0x41, 0xf4, 0x6c} }
#define NS_WEBSOCKET_CONTRACTID "@mozilla.org/websocket;1"
class CallDispatchConnectionCloseEvents;
class nsAutoCloseWS;
class nsWebSocket: public nsDOMEventTargetHelper,
public nsIWebSocket,
public nsIJSNativeInitializer,
public nsIInterfaceRequestor,
public nsIWebSocketListener,
public nsIObserver,
public nsSupportsWeakReference,
public nsIRequest
{
friend class CallDispatchConnectionCloseEvents;
friend class nsAutoCloseWS;
public:
nsWebSocket();
virtual ~nsWebSocket();
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS_INHERITED(nsWebSocket,
nsDOMEventTargetHelper)
NS_DECL_NSIWEBSOCKET
NS_DECL_NSIINTERFACEREQUESTOR
NS_DECL_NSIWEBSOCKETLISTENER
NS_DECL_NSIOBSERVER
NS_DECL_NSIREQUEST
// nsIJSNativeInitializer
NS_IMETHOD Initialize(nsISupports* aOwner, JSContext* aContext,
JSObject* aObject, uint32_t aArgc, jsval* aArgv);
// nsIDOMEventTarget
NS_IMETHOD AddEventListener(const nsAString& aType,
nsIDOMEventListener *aListener,
bool aUseCapture,
bool aWantsUntrusted,
uint8_t optional_argc);
NS_IMETHOD RemoveEventListener(const nsAString& aType,
nsIDOMEventListener* aListener,
bool aUseCapture);
// Determine if preferences allow WebSocket
static bool PrefEnabled();
virtual void DisconnectFromOwner();
protected:
nsresult ParseURL(const nsString& aURL);
nsresult EstablishConnection();
// These methods when called can release the WebSocket object
nsresult FailConnection(uint16_t reasonCode,
const nsACString& aReasonString = EmptyCString());
nsresult CloseConnection(uint16_t reasonCode,
const nsACString& aReasonString = EmptyCString());
nsresult Disconnect();
nsresult ConsoleError();
nsresult PrintErrorOnConsole(const char *aBundleURI,
const PRUnichar *aError,
const PRUnichar **aFormatStrings,
uint32_t aFormatStringsLen);
// Get msg info out of JS variable being sent (string, arraybuffer, blob)
nsresult GetSendParams(nsIVariant *aData, nsCString &aStringOut,
nsCOMPtr<nsIInputStream> &aStreamOut,
bool &aIsBinary, uint32_t &aOutgoingLength,
JSContext *aCx);
nsresult DoOnMessageAvailable(const nsACString & aMsg, bool isBinary);
// ConnectionCloseEvents: 'error' event if needed, then 'close' event.
// - These must not be dispatched while we are still within an incoming call
// from JS (ex: close()). Set 'sync' to false in that case to dispatch in a
// separate new event.
nsresult ScheduleConnectionCloseEvents(nsISupports *aContext,
nsresult aStatusCode,
bool sync);
// 2nd half of ScheduleConnectionCloseEvents, sometimes run in its own event.
void DispatchConnectionCloseEvents();
// These methods actually do the dispatch for various events.
nsresult CreateAndDispatchSimpleEvent(const nsString& aName);
nsresult CreateAndDispatchMessageEvent(const nsACString& aData,
bool isBinary);
nsresult CreateAndDispatchCloseEvent(bool aWasClean, uint16_t aCode,
const nsString &aReason);
nsresult CreateResponseBlob(const nsACString& aData, JSContext *aCx,
jsval &jsData);
// if there are "strong event listeners" (see comment in nsWebSocket.cpp) or
// outgoing not sent messages then this method keeps the object alive
// when js doesn't have strong references to it.
void UpdateMustKeepAlive();
// ATTENTION, when calling this method the object can be released
// (and possibly collected).
void DontKeepAliveAnyMore();
nsresult UpdateURI();
nsCOMPtr<nsIWebSocketChannel> mChannel;
// related to the WebSocket constructor steps
nsString mOriginalURL;
nsString mEffectiveURL; // after redirects
bool mSecure; // if true it is using SSL and the wss scheme,
// otherwise it is using the ws scheme with no SSL
bool mKeepingAlive;
bool mCheckMustKeepAlive;
bool mOnCloseScheduled;
bool mFailed;
bool mDisconnected;
// Set attributes of DOM 'onclose' message
bool mCloseEventWasClean;
nsString mCloseEventReason;
uint16_t mCloseEventCode;
nsCString mAsciiHost; // hostname
uint32_t mPort;
nsCString mResource; // [filepath[?query]]
nsString mUTF16Origin;
nsCOMPtr<nsIURI> mURI;
nsCString mRequestedProtocolList;
nsCString mEstablishedProtocol;
nsCString mEstablishedExtensions;
uint16_t mReadyState;
nsCOMPtr<nsIPrincipal> mPrincipal;
uint32_t mOutgoingBufferedAmount;
enum
{
WS_BINARY_TYPE_ARRAYBUFFER,
WS_BINARY_TYPE_BLOB,
} mBinaryType;
// Web Socket owner information:
// - the script file name, UTF8 encoded.
// - source code line number where the Web Socket object was constructed.
// - the ID of the inner window where the script lives. Note that this may not
// be the same as the Web Socket owner window.
// These attributes are used for error reporting.
nsCString mScriptFile;
uint32_t mScriptLine;
uint64_t mInnerWindowID;
private:
nsWebSocket(const nsWebSocket& x); // prevent bad usage
nsWebSocket& operator=(const nsWebSocket& x);
};
#endif

View File

@ -546,6 +546,7 @@ NS_INTERFACE_MAP_END
uint32_t nsCanvasRenderingContext2DAzure::sNumLivingContexts = 0;
uint8_t (*nsCanvasRenderingContext2DAzure::sUnpremultiplyTable)[256] = nullptr;
uint8_t (*nsCanvasRenderingContext2DAzure::sPremultiplyTable)[256] = nullptr;
DrawTarget* nsCanvasRenderingContext2DAzure::sErrorTarget = nullptr;
namespace mozilla {
namespace dom {
@ -577,7 +578,7 @@ NS_NewCanvasRenderingContext2DAzure(nsIDOMCanvasRenderingContext2D** aResult)
}
nsCanvasRenderingContext2DAzure::nsCanvasRenderingContext2DAzure()
: mValid(false), mZero(false), mOpaque(false), mResetLayer(true)
: mZero(false), mOpaque(false), mResetLayer(true)
, mIPC(false)
, mIsEntireFrameInvalid(false)
, mPredictManyRedrawCalls(false), mPathTransformWillUpdate(false)
@ -600,6 +601,7 @@ nsCanvasRenderingContext2DAzure::~nsCanvasRenderingContext2DAzure()
delete[] sPremultiplyTable;
sUnpremultiplyTable = nullptr;
sPremultiplyTable = nullptr;
NS_IF_RELEASE(sErrorTarget);
}
}
@ -649,7 +651,7 @@ nsCanvasRenderingContext2DAzure::Reset()
// only do this for non-docshell created contexts,
// since those are the ones that we created a surface for
if (mValid && !mDocShell) {
if (mTarget && IsTargetValid() && !mDocShell) {
gCanvasAzureMemoryUsed -= mWidth * mHeight * 4;
}
@ -658,7 +660,6 @@ nsCanvasRenderingContext2DAzure::Reset()
// Since the target changes the backing texture will change, and this will
// no longer be valid.
mThebesSurface = nullptr;
mValid = false;
mIsEntireFrameInvalid = false;
mPredictManyRedrawCalls = false;
@ -835,22 +836,15 @@ nsCanvasRenderingContext2DAzure::RedrawUser(const gfxRect& r)
Redraw(newr);
}
NS_IMETHODIMP
nsCanvasRenderingContext2DAzure::SetDimensions(int32_t width, int32_t height)
void
nsCanvasRenderingContext2DAzure::EnsureTarget()
{
RefPtr<DrawTarget> target;
// Zero sized surfaces cause issues, so just go with 1x1.
if (height == 0 || width == 0) {
mZero = true;
height = 1;
width = 1;
} else {
mZero = false;
if (mTarget) {
return;
}
// Check that the dimensions are sane
IntSize size(width, height);
// Check that the dimensions are sane
IntSize size(mWidth, mHeight);
if (size.width <= 0xFFFF && size.height <= 0xFFFF &&
size.width >= 0 && size.height >= 0) {
SurfaceFormat format = GetSurfaceFormat();
@ -866,42 +860,59 @@ nsCanvasRenderingContext2DAzure::SetDimensions(int32_t width, int32_t height)
nsContentUtils::PersistentLayerManagerForDocument(ownerDoc);
}
if (layerManager) {
target = layerManager->CreateDrawTarget(size, format);
} else {
target = gfxPlatform::GetPlatform()->CreateOffscreenDrawTarget(size, format);
}
if (layerManager) {
mTarget = layerManager->CreateDrawTarget(size, format);
} else {
mTarget = gfxPlatform::GetPlatform()->CreateOffscreenDrawTarget(size, format);
}
}
if (target) {
if (mTarget) {
if (gCanvasAzureMemoryReporter == nullptr) {
gCanvasAzureMemoryReporter = new NS_MEMORY_REPORTER_NAME(CanvasAzureMemory);
NS_RegisterMemoryReporter(gCanvasAzureMemoryReporter);
}
gCanvasAzureMemoryUsed += width * height * 4;
gCanvasAzureMemoryUsed += mWidth * mHeight * 4;
JSContext* context = nsContentUtils::GetCurrentJSContext();
if (context) {
JS_updateMallocCounter(context, width * height * 4);
JS_updateMallocCounter(context, mWidth * mHeight * 4);
}
}
return InitializeWithTarget(target, width, height);
mTarget->ClearRect(mgfx::Rect(Point(0, 0), Size(mWidth, mHeight)));
// always force a redraw, because if the surface dimensions were reset
// then the surface became cleared, and we need to redraw everything.
Redraw();
} else {
EnsureErrorTarget();
mTarget = sErrorTarget;
}
}
nsresult
nsCanvasRenderingContext2DAzure::Initialize(int32_t width, int32_t height)
NS_IMETHODIMP
nsCanvasRenderingContext2DAzure::SetDimensions(int32_t width, int32_t height)
{
mWidth = width;
mHeight = height;
ClearTarget();
if (!mValid) {
// Create a dummy target in the hopes that it will help us deal with users
// calling into us after having changed the size where the size resulted
// in an inability to create a correct DrawTarget.
mTarget = gfxPlatform::GetPlatform()->CreateOffscreenDrawTarget(IntSize(1, 1), FORMAT_B8G8R8A8);
// Zero sized surfaces cause issues, so just go with 1x1.
if (height == 0 || width == 0) {
mZero = true;
mWidth = 1;
mHeight = 1;
} else {
mZero = false;
mWidth = width;
mHeight = height;
}
return NS_OK;
}
void
nsCanvasRenderingContext2DAzure::ClearTarget()
{
Reset();
mResetLayer = true;
// set up the initial canvas defaults
@ -916,42 +927,6 @@ nsCanvasRenderingContext2DAzure::Initialize(int32_t width, int32_t height)
state->colorStyles[STYLE_FILL] = NS_RGB(0,0,0);
state->colorStyles[STYLE_STROKE] = NS_RGB(0,0,0);
state->shadowColor = NS_RGBA(0,0,0,0);
if (mTarget) {
mTarget->ClearRect(mgfx::Rect(Point(0, 0), Size(mWidth, mHeight)));
// always force a redraw, because if the surface dimensions were reset
// then the surface became cleared, and we need to redraw everything.
Redraw();
}
return mValid ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
}
nsresult
nsCanvasRenderingContext2DAzure::InitializeWithTarget(DrawTarget *target, int32_t width, int32_t height)
{
Reset();
NS_ASSERTION(mCanvasElement, "Must have a canvas element!");
mDocShell = nullptr;
// This first time this is called on this object is via
// nsHTMLCanvasElement::GetContext. If target was non-null then mTarget is
// non-null, otherwise we'll return an error here and GetContext won't
// return this context object and we'll never enter this code again.
// All other times this method is called, if target is null then
// mTarget won't be changed, i.e. it will remain non-null, or else it
// will be set to non-null.
// In all cases, any usable canvas context will have non-null mTarget.
if (target) {
mValid = true;
mTarget = target;
} else {
mValid = false;
}
return Initialize(width, height);
}
NS_IMETHODIMP
@ -960,25 +935,22 @@ nsCanvasRenderingContext2DAzure::InitializeWithSurface(nsIDocShell *shell, gfxAS
mDocShell = shell;
mThebesSurface = surface;
SetDimensions(width, height);
mTarget = gfxPlatform::GetPlatform()->CreateDrawTargetForSurface(surface, IntSize(width, height));
mValid = mTarget != nullptr;
if (!mTarget) {
EnsureErrorTarget();
mTarget = sErrorTarget;
}
return Initialize(width, height);
return NS_OK;
}
NS_IMETHODIMP
nsCanvasRenderingContext2DAzure::SetIsOpaque(bool isOpaque)
{
if (isOpaque == mOpaque)
return NS_OK;
mOpaque = isOpaque;
if (mValid) {
/* If we've already been created, let SetDimensions take care of
* recreating our surface
*/
return SetDimensions(mWidth, mHeight);
if (isOpaque != mOpaque) {
mOpaque = isOpaque;
ClearTarget();
}
return NS_OK;
@ -987,16 +959,9 @@ nsCanvasRenderingContext2DAzure::SetIsOpaque(bool isOpaque)
NS_IMETHODIMP
nsCanvasRenderingContext2DAzure::SetIsIPC(bool isIPC)
{
if (isIPC == mIPC)
return NS_OK;
mIPC = isIPC;
if (mValid) {
/* If we've already been created, let SetDimensions take care of
* recreating our surface
*/
return SetDimensions(mWidth, mHeight);
if (isIPC != mIPC) {
mIPC = isIPC;
ClearTarget();
}
return NS_OK;
@ -1007,7 +972,8 @@ nsCanvasRenderingContext2DAzure::Render(gfxContext *ctx, gfxPattern::GraphicsFil
{
nsresult rv = NS_OK;
if (!mValid || !mTarget) {
EnsureTarget();
if (!IsTargetValid()) {
return NS_ERROR_FAILURE;
}
@ -1051,7 +1017,8 @@ nsCanvasRenderingContext2DAzure::GetInputStream(const char *aMimeType,
const PRUnichar *aEncoderOptions,
nsIInputStream **aStream)
{
if (!mValid || !mTarget) {
EnsureTarget();
if (!IsTargetValid()) {
return NS_ERROR_FAILURE;
}
@ -1138,6 +1105,7 @@ nsCanvasRenderingContext2DAzure::GetCanvas(nsIDOMHTMLCanvasElement **canvas)
void
nsCanvasRenderingContext2DAzure::Save()
{
EnsureTarget();
mStyleStack[mStyleStack.Length() - 1].transform = mTarget->GetTransform();
mStyleStack.SetCapacity(mStyleStack.Length() + 1);
mStyleStack.AppendElement(CurrentState());
@ -1156,14 +1124,14 @@ nsCanvasRenderingContext2DAzure::Restore()
if (mStyleStack.Length() - 1 == 0)
return;
TransformWillUpdate();
for (uint32_t i = 0; i < CurrentState().clipsPushed.size(); i++) {
mTarget->PopClip();
}
mStyleStack.RemoveElementAt(mStyleStack.Length() - 1);
TransformWillUpdate();
mTarget->SetTransform(CurrentState().transform);
}
@ -1181,16 +1149,15 @@ nsCanvasRenderingContext2DAzure::MozRestore()
void
nsCanvasRenderingContext2DAzure::Scale(double x, double y, ErrorResult& error)
{
if (!mTarget) {
error.Throw(NS_ERROR_FAILURE);
return;
}
if (!FloatValidate(x,y)) {
return;
}
TransformWillUpdate();
if (!IsTargetValid()) {
error.Throw(NS_ERROR_FAILURE);
return;
}
Matrix newMatrix = mTarget->GetTransform();
mTarget->SetTransform(newMatrix.Scale(x, y));
@ -1207,16 +1174,16 @@ nsCanvasRenderingContext2DAzure::Scale(float x, float y)
void
nsCanvasRenderingContext2DAzure::Rotate(double angle, ErrorResult& error)
{
if (!mTarget) {
error.Throw(NS_ERROR_FAILURE);
return;
}
if (!FloatValidate(angle)) {
return;
}
TransformWillUpdate();
if (!IsTargetValid()) {
error.Throw(NS_ERROR_FAILURE);
return;
}
Matrix rotation = Matrix::Rotation(angle);
mTarget->SetTransform(rotation * mTarget->GetTransform());
@ -1233,16 +1200,15 @@ nsCanvasRenderingContext2DAzure::Rotate(float angle)
void
nsCanvasRenderingContext2DAzure::Translate(double x, double y, ErrorResult& error)
{
if (!mTarget) {
error.Throw(NS_ERROR_FAILURE);
return;
}
if (!FloatValidate(x,y)) {
return;
}
TransformWillUpdate();
if (!IsTargetValid()) {
error.Throw(NS_ERROR_FAILURE);
return;
}
Matrix newMatrix = mTarget->GetTransform();
mTarget->SetTransform(newMatrix.Translate(x, y));
@ -1261,16 +1227,15 @@ nsCanvasRenderingContext2DAzure::Transform(double m11, double m12, double m21,
double m22, double dx, double dy,
ErrorResult& error)
{
if (!mTarget) {
error.Throw(NS_ERROR_FAILURE);
return;
}
if (!FloatValidate(m11,m12,m21,m22,dx,dy)) {
return;
}
TransformWillUpdate();
if (!IsTargetValid()) {
error.Throw(NS_ERROR_FAILURE);
return;
}
Matrix matrix(m11, m12, m21, m22, dx, dy);
mTarget->SetTransform(matrix * mTarget->GetTransform());
@ -1291,16 +1256,15 @@ nsCanvasRenderingContext2DAzure::SetTransform(double m11, double m12,
double dx, double dy,
ErrorResult& error)
{
if (!mTarget) {
error.Throw(NS_ERROR_FAILURE);
return;
}
if (!FloatValidate(m11,m12,m21,m22,dx,dy)) {
return;
}
TransformWillUpdate();
if (!IsTargetValid()) {
error.Throw(NS_ERROR_FAILURE);
return;
}
Matrix matrix(m11, m12, m21, m22, dx, dy);
mTarget->SetTransform(matrix);
@ -1369,7 +1333,8 @@ nsCanvasRenderingContext2DAzure::SetMozCurrentTransform(JSContext* cx,
JSObject& currentTransform,
ErrorResult& error)
{
if (!mTarget) {
EnsureTarget();
if (!IsTargetValid()) {
error.Throw(NS_ERROR_FAILURE);
return;
}
@ -1397,12 +1362,7 @@ JSObject*
nsCanvasRenderingContext2DAzure::GetMozCurrentTransform(JSContext* cx,
ErrorResult& error) const
{
if (!mTarget) {
error.Throw(NS_ERROR_FAILURE);
return NULL;
}
return MatrixToJSObject(cx, mTarget->GetTransform(), error);
return MatrixToJSObject(cx, mTarget ? mTarget->GetTransform() : Matrix(), error);
}
NS_IMETHODIMP
@ -1422,7 +1382,8 @@ nsCanvasRenderingContext2DAzure::SetMozCurrentTransformInverse(JSContext* cx,
JSObject& currentTransform,
ErrorResult& error)
{
if (!mTarget) {
EnsureTarget();
if (!IsTargetValid()) {
error.Throw(NS_ERROR_FAILURE);
return;
}
@ -1454,8 +1415,7 @@ nsCanvasRenderingContext2DAzure::GetMozCurrentTransformInverse(JSContext* cx,
ErrorResult& error) const
{
if (!mTarget) {
error.Throw(NS_ERROR_FAILURE);
return NULL;
return MatrixToJSObject(cx, Matrix(), error);
}
Matrix ctm = mTarget->GetTransform();
@ -1902,6 +1862,7 @@ nsCanvasRenderingContext2DAzure::CreatePattern(const HTMLImageOrCanvasOrVideoEle
return NULL;
}
EnsureTarget();
RefPtr<SourceSurface> srcSurf =
gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(mTarget, res.mSurface);
@ -2005,7 +1966,7 @@ void
nsCanvasRenderingContext2DAzure::ClearRect(double x, double y, double w,
double h)
{
if (!FloatValidate(x,y,w,h)) {
if (!FloatValidate(x,y,w,h) || !mTarget) {
return;
}
@ -2079,6 +2040,7 @@ nsCanvasRenderingContext2DAzure::FillRect(double x, double y, double w,
mgfx::Rect bounds;
EnsureTarget();
if (NeedToDrawShadow()) {
bounds = mgfx::Rect(x, y, w, h);
bounds = mTarget->GetTransform().TransformBounds(bounds);
@ -2110,17 +2072,22 @@ nsCanvasRenderingContext2DAzure::StrokeRect(double x, double y, double w,
const ContextState &state = CurrentState();
mgfx::Rect bounds;
if (!w && !h) {
return;
}
EnsureTarget();
if (!IsTargetValid()) {
return;
}
if (NeedToDrawShadow()) {
bounds = mgfx::Rect(x - state.lineWidth / 2.0f, y - state.lineWidth / 2.0f,
w + state.lineWidth, h + state.lineWidth);
bounds = mTarget->GetTransform().TransformBounds(bounds);
}
if (!w && !h) {
return;
}
if (!h) {
CapStyle cap = CAP_BUTT;
if (state.lineJoin == JOIN_ROUND) {
@ -2491,6 +2458,7 @@ nsCanvasRenderingContext2DAzure::EnsureWritablePath()
return;
}
EnsureTarget();
if (!mPath) {
NS_ASSERTION(!mPathTransformWillUpdate, "mPathTransformWillUpdate should be false, if all paths are null");
mPathBuilder = mTarget->CreatePathBuilder(fillRule);
@ -2509,6 +2477,7 @@ nsCanvasRenderingContext2DAzure::EnsureUserSpacePath(bool aCommitTransform /* =
FillRule fillRule = CurrentState().fillRule;
if (!mPath && !mPathBuilder && !mDSPathBuilder) {
EnsureTarget();
mPathBuilder = mTarget->CreatePathBuilder(fillRule);
}
@ -2554,6 +2523,8 @@ nsCanvasRenderingContext2DAzure::EnsureUserSpacePath(bool aCommitTransform /* =
void
nsCanvasRenderingContext2DAzure::TransformWillUpdate()
{
EnsureTarget();
// Store the matrix that would transform the current path to device
// space.
if (mPath || mPathBuilder) {
@ -3037,6 +3008,7 @@ struct NS_STACK_CLASS nsCanvasBidiProcessorAzure : public nsBidiPresUtils::BidiP
float advanceSum = 0;
mCtx->EnsureTarget();
for (uint32_t c = 0; c < numRuns; c++) {
gfxFont *font = runs[c].mFont;
uint32_t endRun = 0;
@ -3237,8 +3209,14 @@ nsCanvasRenderingContext2DAzure::DrawOrMeasureText(const nsAString& aRawText,
processor.mPt = gfxPoint(aX, aY);
processor.mThebes =
new gfxContext(gfxPlatform::GetPlatform()->ScreenReferenceSurface());
Matrix matrix = mTarget->GetTransform();
processor.mThebes->SetMatrix(gfxMatrix(matrix._11, matrix._12, matrix._21, matrix._22, matrix._31, matrix._32));
// If we don't have a target then we don't have a transform. A target won't
// be needed in the case where we're measuring the text size. This allows
// to avoid creating a target if it's only being used to measure text sizes.
if (mTarget) {
Matrix matrix = mTarget->GetTransform();
processor.mThebes->SetMatrix(gfxMatrix(matrix._11, matrix._12, matrix._21, matrix._22, matrix._31, matrix._32));
}
processor.mCtx = this;
processor.mOp = aOp;
processor.mBoundingBox = gfxRect(0, 0, 0, 0);
@ -3328,6 +3306,7 @@ nsCanvasRenderingContext2DAzure::DrawOrMeasureText(const nsAString& aRawText,
processor.mPt.x *= processor.mAppUnitsPerDevPixel;
processor.mPt.y *= processor.mAppUnitsPerDevPixel;
EnsureTarget();
Matrix oldTransform = mTarget->GetTransform();
// if text is over aMaxWidth, then scale the text horizontally such that its
// width is precisely aMaxWidth
@ -3667,6 +3646,8 @@ nsCanvasRenderingContext2DAzure::DrawImage(const HTMLImageOrCanvasOrVideoElement
gfxIntSize imgSize;
Element* element;
EnsureTarget();
if (image.IsHTMLCanvasElement()) {
nsHTMLCanvasElement* canvas = image.GetAsHTMLCanvasElement();
element = canvas;
@ -3928,6 +3909,7 @@ nsCanvasRenderingContext2DAzure::DrawWindow(nsIDOMWindow* window, double x,
nsRefPtr<gfxContext> thebes = new gfxContext(drawSurf);
EnsureTarget();
Matrix matrix = mTarget->GetTransform();
thebes->SetMatrix(gfxMatrix(matrix._11, matrix._12, matrix._21,
matrix._22, matrix._31, matrix._32));
@ -4146,7 +4128,8 @@ nsCanvasRenderingContext2DAzure::GetImageData(JSContext* aCx, double aSx,
double aSy, double aSw,
double aSh, ErrorResult& error)
{
if (!mValid) {
EnsureTarget();
if (!IsTargetValid()) {
error.Throw(NS_ERROR_FAILURE);
return NULL;
}
@ -4339,6 +4322,20 @@ nsCanvasRenderingContext2DAzure::EnsurePremultiplyTable() {
}
}
void
nsCanvasRenderingContext2DAzure::EnsureErrorTarget()
{
if (sErrorTarget) {
return;
}
RefPtr<DrawTarget> errorTarget = gfxPlatform::GetPlatform()->CreateOffscreenDrawTarget(IntSize(1, 1), FORMAT_B8G8R8A8);
NS_ABORT_IF_FALSE(errorTarget, "Failed to allocate the error target!");
sErrorTarget = errorTarget;
NS_ADDREF(sErrorTarget);
}
void
nsCanvasRenderingContext2DAzure::FillRuleChanged()
{
@ -4407,10 +4404,6 @@ nsCanvasRenderingContext2DAzure::PutImageData_explicit(int32_t x, int32_t y, uin
bool hasDirtyRect, int32_t dirtyX, int32_t dirtyY,
int32_t dirtyWidth, int32_t dirtyHeight)
{
if (!mValid) {
return NS_ERROR_FAILURE;
}
if (w == 0 || h == 0) {
return NS_ERROR_DOM_SYNTAX_ERR;
}
@ -4499,6 +4492,11 @@ nsCanvasRenderingContext2DAzure::PutImageData_explicit(int32_t x, int32_t y, uin
}
}
EnsureTarget();
if (!IsTargetValid()) {
return NS_ERROR_FAILURE;
}
RefPtr<SourceSurface> sourceSurface =
mTarget->CreateSourceSurfaceFromData(imgsurf->Data(), IntSize(w, h), imgsurf->Stride(), FORMAT_B8G8R8A8);
@ -4516,13 +4514,7 @@ nsCanvasRenderingContext2DAzure::PutImageData_explicit(int32_t x, int32_t y, uin
NS_IMETHODIMP
nsCanvasRenderingContext2DAzure::GetThebesSurface(gfxASurface **surface)
{
if (!mTarget) {
nsRefPtr<gfxASurface> tmpSurf =
gfxPlatform::GetPlatform()->CreateOffscreenSurface(gfxIntSize(1, 1), gfxASurface::CONTENT_COLOR_ALPHA);
*surface = tmpSurf.forget().get();
return NS_OK;
}
EnsureTarget();
if (!mThebesSurface) {
mThebesSurface =
gfxPlatform::GetPlatform()->GetThebesSurfaceForDrawTarget(mTarget);
@ -4632,16 +4624,15 @@ nsCanvasRenderingContext2DAzure::GetCanvasLayer(nsDisplayListBuilder* aBuilder,
CanvasLayer *aOldLayer,
LayerManager *aManager)
{
if (!mValid) {
EnsureTarget();
if (!IsTargetValid()) {
// No DidTransactionCallback will be received, so mark the context clean
// now so future invalidations will be dispatched.
MarkContextClean();
return nullptr;
}
if (mTarget) {
mTarget->Flush();
}
mTarget->Flush();
if (!mResetLayer && aOldLayer) {
CanvasRenderingContext2DUserDataAzure* userData =
@ -4707,5 +4698,5 @@ nsCanvasRenderingContext2DAzure::MarkContextClean()
bool
nsCanvasRenderingContext2DAzure::ShouldForceInactiveLayer(LayerManager *aManager)
{
return !aManager->CanUseCanvasLayerForSize(gfxIntSize(mWidth, mHeight));
return !aManager->CanUseCanvasLayerForSize(gfxIntSize(mWidth, mHeight));
}

View File

@ -566,6 +566,8 @@ protected:
*/
static uint8_t (*sPremultiplyTable)[256];
static mozilla::gfx::DrawTarget* sErrorTarget;
// Some helpers. Doesn't modify a color on failure.
void SetStyleFromJSValue(JSContext* cx, JS::Value& value, Style whichStyle);
void SetStyleFromString(const nsAString& str, Style whichStyle);
@ -598,6 +600,11 @@ protected:
*/
void EnsurePremultiplyTable();
/**
* Creates the error target, if it doesn't exist
*/
static void EnsureErrorTarget();
/* This function ensures there is a writable pathbuilder available, this
* pathbuilder may be working in user space or in device space or
* device space.
@ -610,11 +617,33 @@ protected:
// used for the path.
void EnsureUserSpacePath(bool aCommitTransform = true);
/**
* Needs to be called before updating the transform. This makes a call to
* EnsureTarget() so you don't have to.
*/
void TransformWillUpdate();
// Report the fillRule has changed.
void FillRuleChanged();
/**
* Create the backing surfacing, if it doesn't exist. If there is an error
* in creating the target then it will put sErrorTarget in place. If there
* is in turn an error in creating the sErrorTarget then they would both
* be null so IsTargetValid() would still return null.
*/
void EnsureTarget();
/*
* Disposes an old target and prepares to lazily create a new target.
*/
void ClearTarget();
/**
* Check if the target is valid after calling EnsureTarget.
*/
bool IsTargetValid() { return mTarget != sErrorTarget; }
/**
* Returns the surface format this canvas should be allocated using. Takes
* into account mOpaque, platform requirements, etc.
@ -663,10 +692,6 @@ protected:
// Member vars
int32_t mWidth, mHeight;
// This is true when the canvas is valid, false otherwise, this occurs when
// for some reason initialization of the drawtarget fails. If the canvas
// is invalid certain behavior is expected.
bool mValid;
// This is true when the canvas is valid, but of zero size, this requires
// specific behavior on some operations.
bool mZero;
@ -684,7 +709,9 @@ protected:
// If mCanvasElement is not provided, then a docshell is
nsCOMPtr<nsIDocShell> mDocShell;
// our drawing surfaces, contexts, and layers
// This is created lazily so it is necessary to call EnsureTarget before
// accessing it. In the event of an error it will be equal to
// sErrorTarget.
mozilla::RefPtr<mozilla::gfx::DrawTarget> mTarget;
/**

View File

@ -21,14 +21,13 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=448602
function runTests() {
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
/*
Disabled due to lack of present support for JSD in JM
var jsdIDebuggerService = Components.interfaces.jsdIDebuggerService;
var jsd = Components.classes['@mozilla.org/js/jsd/debugger-service;1']
.getService(jsdIDebuggerService);
*/
var els = Components.classes["@mozilla.org/eventlistenerservice;1"]
var els = SpecialPowers.wrap(Components).classes["@mozilla.org/eventlistenerservice;1"]
.getService(Components.interfaces.nsIEventListenerService);
// Event listener info tests
@ -107,7 +106,7 @@ function runTests() {
var l2 = document.getElementById("testlevel2");
var l3 = document.getElementById("testlevel3");
var textnode = l3.firstChild;
var chain = els.getEventTargetChainFor(textnode, {});
var chain = SpecialPowers.unwrap(els.getEventTargetChainFor(textnode, {}));
ok(chain.length > 3, "Too short event target chain.");
is(chain[0], textnode, "Wrong chain item (1)");
is(chain[1], l3, "Wrong chain item (2)");

View File

@ -100,6 +100,7 @@ struct PluginHost {
uint64_t (*GetLength)(Decoder *aDecoder);
void (*SetMetaDataReadMode)(Decoder *aDecoder);
void (*SetPlaybackReadMode)(Decoder *aDecoder);
bool (*GetIntPref)(const char *aPref, int32_t *aResult);
};
struct Decoder {

View File

@ -3,6 +3,7 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/Preferences.h"
#include "mozilla/TimeStamp.h"
#include "nsTimeRanges.h"
#include "MediaResource.h"
@ -54,11 +55,34 @@ static void SetPlaybackReadMode(Decoder *aDecoder)
GetResource(aDecoder)->SetReadMode(nsMediaCacheStream::MODE_PLAYBACK);
}
class GetIntPrefEvent : public nsRunnable {
public:
GetIntPrefEvent(const char* aPref, int32_t* aResult)
: mPref(aPref), mResult(aResult) {}
NS_IMETHOD Run() {
return Preferences::GetInt(mPref, mResult);
}
private:
const char* mPref;
int32_t* mResult;
};
static bool GetIntPref(const char* aPref, int32_t* aResult)
{
// GetIntPref() is called on the decoder thread, but the Preferences API
// can only be called on the main thread. Post a runnable and wait.
NS_ENSURE_ARG_POINTER(aPref);
NS_ENSURE_ARG_POINTER(aResult);
nsCOMPtr<GetIntPrefEvent> event = new GetIntPrefEvent(aPref, aResult);
return NS_SUCCEEDED(NS_DispatchToMainThread(event, NS_DISPATCH_SYNC));
}
static PluginHost sPluginHost = {
Read,
GetLength,
SetMetaDataReadMode,
SetPlaybackReadMode
SetPlaybackReadMode,
GetIntPref
};
void nsMediaPluginHost::TryLoad(const char *name)

View File

@ -12,6 +12,3 @@
<handler event="keypress" key="z" command="cmd_undo" modifiers="accel"/>
<handler event="keypress" key="z" command="cmd_redo" modifiers="accel,shift" />
<handler event="keypress" key="a" command="cmd_selectAll" modifiers="accel"/>
<handler event="keypress" key="/" command="cmd_findTypeText" modifiers="shift any"/>
<handler event="keypress" key="'" command="cmd_findTypeLinks" modifiers="shift any"/>

View File

@ -24,6 +24,7 @@ let AppsUtils = {
// Clones a app, without the manifest.
cloneAppObject: function cloneAppObject(aApp) {
return {
name: aApp.name,
installOrigin: aApp.installOrigin,
origin: aApp.origin,
receipts: aApp.receipts ? JSON.parse(JSON.stringify(aApp.receipts)) : null,

View File

@ -179,6 +179,7 @@ let DOMApplicationRegistry = {
let app = this.webapps[aId];
this._readManifests([{ id: aId }], (function registerManifest(aResult) {
let manifest = aResult[0].manifest;
app.name = manifest.name;
this._registerSystemMessages(manifest, app);
this._registerActivities(manifest, app);
}).bind(this));
@ -368,6 +369,7 @@ let DOMApplicationRegistry = {
this.webapps[id] = appObject;
appObject.status = "installed";
appObject.name = app.manifest.name;
let manifest = new DOMApplicationManifest(app.manifest, app.origin);

View File

@ -171,7 +171,6 @@
#include "nsIDOMParser.h"
#include "nsIDOMSerializer.h"
#include "nsXMLHttpRequest.h"
#include "nsWebSocket.h"
#include "nsEventSource.h"
#include "nsIDOMSettingsManager.h"
#include "nsIDOMContactManager.h"
@ -1618,9 +1617,6 @@ static nsDOMClassInfoData sClassInfoData[] = {
NS_DEFINE_CLASSINFO_DATA(DesktopNotificationCenter, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(WebSocket, nsEventTargetSH,
EVENTTARGET_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(IDBFactory, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA_WITH_NAME(IDBFileHandle, FileHandle, nsEventTargetSH,
@ -1745,7 +1741,6 @@ NS_DEFINE_CONTRACT_CTOR(FileReader, NS_FILEREADER_CONTRACTID)
NS_DEFINE_CONTRACT_CTOR(ArchiveReader, NS_ARCHIVEREADER_CONTRACTID)
NS_DEFINE_CONTRACT_CTOR(FormData, NS_FORMDATA_CONTRACTID)
NS_DEFINE_CONTRACT_CTOR(XMLSerializer, NS_XMLSERIALIZER_CONTRACTID)
NS_DEFINE_CONTRACT_CTOR(WebSocket, NS_WEBSOCKET_CONTRACTID)
NS_DEFINE_CONTRACT_CTOR(XPathEvaluator, NS_XPATH_EVALUATOR_CONTRACTID)
NS_DEFINE_CONTRACT_CTOR(XSLTProcessor,
"@mozilla.org/document-transformer;1?type=xslt")
@ -1823,7 +1818,6 @@ static const nsConstructorFuncMapData kConstructorFuncMap[] =
NS_DEFINE_CONSTRUCTOR_FUNC_DATA(ArchiveReader, ArchiveReaderCtor)
NS_DEFINE_CONSTRUCTOR_FUNC_DATA(FormData, FormDataCtor)
NS_DEFINE_CONSTRUCTOR_FUNC_DATA(XMLSerializer, XMLSerializerCtor)
NS_DEFINE_CONSTRUCTOR_FUNC_DATA(WebSocket, WebSocketCtor)
NS_DEFINE_CONSTRUCTOR_FUNC_DATA(XPathEvaluator, XPathEvaluatorCtor)
NS_DEFINE_CONSTRUCTOR_FUNC_DATA(XSLTProcessor, XSLTProcessorCtor)
NS_DEFINE_CONSTRUCTOR_FUNC_DATA(EventSource, EventSourceCtor)
@ -2176,7 +2170,7 @@ bool
nsDOMClassInfo::ObjectIsNativeWrapper(JSContext* cx, JSObject* obj)
{
return xpc::WrapperFactory::IsXrayWrapper(obj) &&
!xpc::WrapperFactory::IsPartiallyTransparent(obj);
xpc::AccessCheck::wrapperSubsumes(obj);
}
nsDOMClassInfo::nsDOMClassInfo(nsDOMClassInfoData* aData) : mData(aData)
@ -4358,11 +4352,6 @@ nsDOMClassInfo::Init()
DOM_CLASSINFO_MAP_ENTRY(nsIDOMDesktopNotificationCenter)
DOM_CLASSINFO_MAP_END
DOM_CLASSINFO_MAP_BEGIN(WebSocket, nsIWebSocket)
DOM_CLASSINFO_MAP_ENTRY(nsIWebSocket)
DOM_CLASSINFO_MAP_ENTRY(nsIDOMEventTarget)
DOM_CLASSINFO_MAP_END
DOM_CLASSINFO_MAP_BEGIN(IDBFactory, nsIIDBFactory)
DOM_CLASSINFO_MAP_ENTRY(nsIIDBFactory)
DOM_CLASSINFO_MAP_END
@ -6713,13 +6702,6 @@ ConstructorEnabled(const nsGlobalNameStruct *aStruct, nsGlobalWindow *aWin)
return false;
}
// For now don't expose web sockets unless user has explicitly enabled them
if (aStruct->mDOMClassInfoID == eDOMClassInfo_WebSocket_id) {
if (!nsWebSocket::PrefEnabled()) {
return false;
}
}
// For now don't expose server events unless user has explicitly enabled them
if (aStruct->mDOMClassInfoID == eDOMClassInfo_EventSource_id) {
if (!nsEventSource::PrefEnabled()) {

View File

@ -484,9 +484,6 @@ DOMCI_CLASS(FormData)
DOMCI_CLASS(DesktopNotification)
DOMCI_CLASS(DesktopNotificationCenter)
// WebSocket
DOMCI_CLASS(WebSocket)
DOMCI_CLASS(IDBFactory)
DOMCI_CLASS(IDBFileHandle)
DOMCI_CLASS(IDBRequest)

View File

@ -19,6 +19,7 @@
#include "nsDOMTouchEvent.h"
#include "nsIDOMTouchEvent.h"
#include "nsObjectLoadingContent.h"
#include "nsFrame.h"
#include "nsIScrollableFrame.h"
@ -136,6 +137,10 @@ nsDOMWindowUtils::GetPresContext()
NS_IMETHODIMP
nsDOMWindowUtils::GetImageAnimationMode(uint16_t *aMode)
{
if (!IsUniversalXPConnectCapable()) {
return NS_ERROR_DOM_SECURITY_ERR;
}
NS_ENSURE_ARG_POINTER(aMode);
*aMode = 0;
nsPresContext* presContext = GetPresContext();
@ -149,6 +154,10 @@ nsDOMWindowUtils::GetImageAnimationMode(uint16_t *aMode)
NS_IMETHODIMP
nsDOMWindowUtils::SetImageAnimationMode(uint16_t aMode)
{
if (!IsUniversalXPConnectCapable()) {
return NS_ERROR_DOM_SECURITY_ERR;
}
nsPresContext* presContext = GetPresContext();
if (presContext) {
presContext->SetImageAnimationMode(aMode);
@ -200,6 +209,10 @@ nsDOMWindowUtils::GetDocumentMetadata(const nsAString& aName,
NS_IMETHODIMP
nsDOMWindowUtils::Redraw(uint32_t aCount, uint32_t *aDurationOut)
{
if (!IsUniversalXPConnectCapable()) {
return NS_ERROR_DOM_SECURITY_ERR;
}
if (aCount == 0)
aCount = 1;
@ -1119,6 +1132,10 @@ nsDOMWindowUtils::ElementFromPoint(float aX, float aY,
bool aFlushLayout,
nsIDOMElement** aReturn)
{
if (!IsUniversalXPConnectCapable()) {
return NS_ERROR_DOM_SECURITY_ERR;
}
nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
NS_ENSURE_STATE(window);
@ -1242,6 +1259,11 @@ nsDOMWindowUtils::CompareCanvases(nsIDOMHTMLCanvasElement *aCanvas1,
NS_IMETHODIMP
nsDOMWindowUtils::GetIsMozAfterPaintPending(bool *aResult)
{
if (!IsUniversalXPConnectCapable()) {
return NS_ERROR_DOM_SECURITY_ERR;
}
NS_ENSURE_ARG_POINTER(aResult);
*aResult = false;
nsPresContext* presContext = GetPresContext();
if (!presContext)
@ -1253,6 +1275,10 @@ nsDOMWindowUtils::GetIsMozAfterPaintPending(bool *aResult)
NS_IMETHODIMP
nsDOMWindowUtils::ClearMozAfterPaintEvents()
{
if (!IsUniversalXPConnectCapable()) {
return NS_ERROR_DOM_SECURITY_ERR;
}
nsPresContext* presContext = GetPresContext();
if (!presContext)
return NS_OK;
@ -1303,6 +1329,10 @@ nsDOMWindowUtils::SuppressEventHandling(bool aSuppress)
NS_IMETHODIMP
nsDOMWindowUtils::GetScrollXY(bool aFlushLayout, int32_t* aScrollX, int32_t* aScrollY)
{
if (!IsUniversalXPConnectCapable()) {
return NS_ERROR_DOM_SECURITY_ERR;
}
nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
NS_ENSURE_STATE(window);
@ -1331,6 +1361,10 @@ nsDOMWindowUtils::GetScrollXY(bool aFlushLayout, int32_t* aScrollX, int32_t* aSc
NS_IMETHODIMP
nsDOMWindowUtils::GetRootBounds(nsIDOMClientRect** aResult)
{
if (!IsUniversalXPConnectCapable()) {
return NS_ERROR_DOM_SECURITY_ERR;
}
// Weak ref, since we addref it below
nsClientRect* rect = new nsClientRect();
NS_ADDREF(*aResult = rect);
@ -1364,6 +1398,10 @@ nsDOMWindowUtils::GetRootBounds(nsIDOMClientRect** aResult)
NS_IMETHODIMP
nsDOMWindowUtils::GetIMEIsOpen(bool *aState)
{
if (!IsUniversalXPConnectCapable()) {
return NS_ERROR_DOM_SECURITY_ERR;
}
NS_ENSURE_ARG_POINTER(aState);
nsCOMPtr<nsIWidget> widget = GetWidget();
@ -1386,6 +1424,10 @@ nsDOMWindowUtils::GetIMEIsOpen(bool *aState)
NS_IMETHODIMP
nsDOMWindowUtils::GetIMEStatus(uint32_t *aState)
{
if (!IsUniversalXPConnectCapable()) {
return NS_ERROR_DOM_SECURITY_ERR;
}
NS_ENSURE_ARG_POINTER(aState);
nsCOMPtr<nsIWidget> widget = GetWidget();
@ -1400,6 +1442,10 @@ nsDOMWindowUtils::GetIMEStatus(uint32_t *aState)
NS_IMETHODIMP
nsDOMWindowUtils::GetFocusedInputType(char** aType)
{
if (!IsUniversalXPConnectCapable()) {
return NS_ERROR_DOM_SECURITY_ERR;
}
NS_ENSURE_ARG_POINTER(aType);
nsCOMPtr<nsIWidget> widget = GetWidget();
@ -1416,6 +1462,10 @@ NS_IMETHODIMP
nsDOMWindowUtils::FindElementWithViewId(nsViewID aID,
nsIDOMElement** aResult)
{
if (!IsUniversalXPConnectCapable()) {
return NS_ERROR_DOM_SECURITY_ERR;
}
if (aID == FrameMetrics::ROOT_SCROLL_ID) {
nsPresContext* presContext = GetPresContext();
if (!presContext) {
@ -1810,6 +1860,10 @@ nsDOMWindowUtils::GetVisitedDependentComputedStyle(
NS_IMETHODIMP
nsDOMWindowUtils::EnterModalState()
{
if (!IsUniversalXPConnectCapable()) {
return NS_ERROR_DOM_SECURITY_ERR;
}
nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
NS_ENSURE_STATE(window);
@ -1820,6 +1874,10 @@ nsDOMWindowUtils::EnterModalState()
NS_IMETHODIMP
nsDOMWindowUtils::LeaveModalState()
{
if (!IsUniversalXPConnectCapable()) {
return NS_ERROR_DOM_SECURITY_ERR;
}
nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
NS_ENSURE_STATE(window);
@ -1830,6 +1888,10 @@ nsDOMWindowUtils::LeaveModalState()
NS_IMETHODIMP
nsDOMWindowUtils::EnterModalStateWithWindow(nsIDOMWindow **aWindow)
{
if (!IsUniversalXPConnectCapable()) {
return NS_ERROR_DOM_SECURITY_ERR;
}
nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
NS_ENSURE_STATE(window);
@ -1841,6 +1903,10 @@ nsDOMWindowUtils::EnterModalStateWithWindow(nsIDOMWindow **aWindow)
NS_IMETHODIMP
nsDOMWindowUtils::LeaveModalStateWithWindow(nsIDOMWindow *aWindow)
{
if (!IsUniversalXPConnectCapable()) {
return NS_ERROR_DOM_SECURITY_ERR;
}
nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
NS_ENSURE_STATE(window);
@ -1851,6 +1917,10 @@ nsDOMWindowUtils::LeaveModalStateWithWindow(nsIDOMWindow *aWindow)
NS_IMETHODIMP
nsDOMWindowUtils::IsInModalState(bool *retval)
{
if (!IsUniversalXPConnectCapable()) {
return NS_ERROR_DOM_SECURITY_ERR;
}
nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
NS_ENSURE_STATE(window);
@ -1863,7 +1933,6 @@ nsDOMWindowUtils::GetParent(const JS::Value& aObject,
JSContext* aCx,
JS::Value* aParent)
{
// This wasn't privileged in the past, but better to expose less than more.
if (!IsUniversalXPConnectCapable()) {
return NS_ERROR_DOM_SECURITY_ERR;
}
@ -1889,6 +1958,10 @@ nsDOMWindowUtils::GetParent(const JS::Value& aObject,
NS_IMETHODIMP
nsDOMWindowUtils::GetOuterWindowID(uint64_t *aWindowID)
{
if (!IsUniversalXPConnectCapable()) {
return NS_ERROR_DOM_SECURITY_ERR;
}
nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
NS_ENSURE_STATE(window);
@ -1900,6 +1973,10 @@ nsDOMWindowUtils::GetOuterWindowID(uint64_t *aWindowID)
NS_IMETHODIMP
nsDOMWindowUtils::GetCurrentInnerWindowID(uint64_t *aWindowID)
{
if (!IsUniversalXPConnectCapable()) {
return NS_ERROR_DOM_SECURITY_ERR;
}
nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
NS_ENSURE_TRUE(window, NS_ERROR_NOT_AVAILABLE);
@ -1946,6 +2023,10 @@ nsDOMWindowUtils::ResumeTimeouts()
NS_IMETHODIMP
nsDOMWindowUtils::GetLayerManagerType(nsAString& aType)
{
if (!IsUniversalXPConnectCapable()) {
return NS_ERROR_DOM_SECURITY_ERR;
}
nsCOMPtr<nsIWidget> widget = GetWidget();
if (!widget)
return NS_ERROR_FAILURE;
@ -1962,6 +2043,10 @@ nsDOMWindowUtils::GetLayerManagerType(nsAString& aType)
NS_IMETHODIMP
nsDOMWindowUtils::StartFrameTimeRecording()
{
if (!IsUniversalXPConnectCapable()) {
return NS_ERROR_DOM_SECURITY_ERR;
}
nsCOMPtr<nsIWidget> widget = GetWidget();
if (!widget)
return NS_ERROR_FAILURE;
@ -1978,6 +2063,10 @@ nsDOMWindowUtils::StartFrameTimeRecording()
NS_IMETHODIMP
nsDOMWindowUtils::StopFrameTimeRecording(uint32_t *frameCount, float **frames)
{
if (!IsUniversalXPConnectCapable()) {
return NS_ERROR_DOM_SECURITY_ERR;
}
NS_ENSURE_ARG_POINTER(frameCount);
NS_ENSURE_ARG_POINTER(frames);
@ -2108,6 +2197,10 @@ nsDOMWindowUtils::RenderDocument(const nsRect& aRect,
nscolor aBackgroundColor,
gfxContext* aThebesContext)
{
if (!IsUniversalXPConnectCapable()) {
return NS_ERROR_DOM_SECURITY_ERR;
}
nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
@ -2132,6 +2225,10 @@ nsDOMWindowUtils::RenderDocument(const nsRect& aRect,
NS_IMETHODIMP
nsDOMWindowUtils::GetCursorType(int16_t *aCursor)
{
if (!IsUniversalXPConnectCapable()) {
return NS_ERROR_DOM_SECURITY_ERR;
}
NS_ENSURE_ARG_POINTER(aCursor);
nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
@ -2192,6 +2289,10 @@ nsDOMWindowUtils::GoOnline()
NS_IMETHODIMP
nsDOMWindowUtils::GetDisplayDPI(float *aDPI)
{
if (!IsUniversalXPConnectCapable()) {
return NS_ERROR_DOM_SECURITY_ERR;
}
nsCOMPtr<nsIWidget> widget = GetWidget();
if (!widget)
return NS_ERROR_FAILURE;
@ -2217,7 +2318,12 @@ nsDOMWindowUtils::GetOuterWindowWithId(uint64_t aWindowID,
NS_IMETHODIMP
nsDOMWindowUtils::WrapDOMFile(nsIFile *aFile,
nsIDOMFile **aDOMFile) {
nsIDOMFile **aDOMFile)
{
if (!IsUniversalXPConnectCapable()) {
return NS_ERROR_DOM_SECURITY_ERR;
}
NS_ADDREF(*aDOMFile = new nsDOMFileFile(aFile));
return NS_OK;
}
@ -2306,6 +2412,10 @@ nsDOMWindowUtils::GetMayHaveTouchEventListeners(bool* aResult)
NS_IMETHODIMP
nsDOMWindowUtils::CheckAndClearPaintedState(nsIDOMElement* aElement, bool* aResult)
{
if (!IsUniversalXPConnectCapable()) {
return NS_ERROR_DOM_SECURITY_ERR;
}
if (!aElement) {
return NS_ERROR_INVALID_ARG;
}
@ -2379,6 +2489,10 @@ nsDOMWindowUtils::GetFile(const nsAString& aName, const jsval& aBlobParts,
const jsval& aParameters, JSContext* aCx,
uint8_t aOptionalArgCount, nsIDOMFile** aResult)
{
if (!IsUniversalXPConnectCapable()) {
return NS_ERROR_DOM_SECURITY_ERR;
}
nsCOMPtr<nsISupports> file;
nsresult rv = GetFileOrBlob(aName, aBlobParts, aParameters, aCx,
aOptionalArgCount, getter_AddRefs(file));
@ -2395,6 +2509,10 @@ nsDOMWindowUtils::GetBlob(const jsval& aBlobParts, const jsval& aParameters,
JSContext* aCx, uint8_t aOptionalArgCount,
nsIDOMBlob** aResult)
{
if (!IsUniversalXPConnectCapable()) {
return NS_ERROR_DOM_SECURITY_ERR;
}
nsCOMPtr<nsISupports> blob;
nsresult rv = GetFileOrBlob(NullString(), aBlobParts, aParameters, aCx,
aOptionalArgCount, getter_AddRefs(blob));
@ -2410,6 +2528,9 @@ NS_IMETHODIMP
nsDOMWindowUtils::GetFileId(const jsval& aFile, JSContext* aCx,
int64_t* aResult)
{
if (!IsUniversalXPConnectCapable()) {
return NS_ERROR_DOM_SECURITY_ERR;
}
if (!JSVAL_IS_PRIMITIVE(aFile)) {
JSObject* obj = JSVAL_TO_OBJECT(aFile);
@ -2484,6 +2605,10 @@ nsDOMWindowUtils::GetFileReferences(const nsAString& aDatabaseName,
NS_IMETHODIMP
nsDOMWindowUtils::IsIncrementalGCEnabled(JSContext* cx, bool* aResult)
{
if (!IsUniversalXPConnectCapable()) {
return NS_ERROR_DOM_SECURITY_ERR;
}
*aResult = js::IsIncrementalGCEnabled(JS_GetRuntime(cx));
return NS_OK;
}
@ -2491,6 +2616,10 @@ nsDOMWindowUtils::IsIncrementalGCEnabled(JSContext* cx, bool* aResult)
NS_IMETHODIMP
nsDOMWindowUtils::StartPCCountProfiling(JSContext* cx)
{
if (!IsUniversalXPConnectCapable()) {
return NS_ERROR_DOM_SECURITY_ERR;
}
js::StartPCCountProfiling(cx);
return NS_OK;
}
@ -2498,6 +2627,10 @@ nsDOMWindowUtils::StartPCCountProfiling(JSContext* cx)
NS_IMETHODIMP
nsDOMWindowUtils::StopPCCountProfiling(JSContext* cx)
{
if (!IsUniversalXPConnectCapable()) {
return NS_ERROR_DOM_SECURITY_ERR;
}
js::StopPCCountProfiling(cx);
return NS_OK;
}
@ -2505,6 +2638,10 @@ nsDOMWindowUtils::StopPCCountProfiling(JSContext* cx)
NS_IMETHODIMP
nsDOMWindowUtils::PurgePCCounts(JSContext* cx)
{
if (!IsUniversalXPConnectCapable()) {
return NS_ERROR_DOM_SECURITY_ERR;
}
js::PurgePCCounts(cx);
return NS_OK;
}
@ -2512,6 +2649,10 @@ nsDOMWindowUtils::PurgePCCounts(JSContext* cx)
NS_IMETHODIMP
nsDOMWindowUtils::GetPCCountScriptCount(JSContext* cx, int32_t *result)
{
if (!IsUniversalXPConnectCapable()) {
return NS_ERROR_DOM_SECURITY_ERR;
}
*result = js::GetPCCountScriptCount(cx);
return NS_OK;
}
@ -2519,6 +2660,10 @@ nsDOMWindowUtils::GetPCCountScriptCount(JSContext* cx, int32_t *result)
NS_IMETHODIMP
nsDOMWindowUtils::GetPCCountScriptSummary(int32_t script, JSContext* cx, nsAString& result)
{
if (!IsUniversalXPConnectCapable()) {
return NS_ERROR_DOM_SECURITY_ERR;
}
JSString *text = js::GetPCCountScriptSummary(cx, script);
if (!text)
return NS_ERROR_FAILURE;
@ -2534,6 +2679,10 @@ nsDOMWindowUtils::GetPCCountScriptSummary(int32_t script, JSContext* cx, nsAStri
NS_IMETHODIMP
nsDOMWindowUtils::GetPCCountScriptContents(int32_t script, JSContext* cx, nsAString& result)
{
if (!IsUniversalXPConnectCapable()) {
return NS_ERROR_DOM_SECURITY_ERR;
}
JSString *text = js::GetPCCountScriptContents(cx, script);
if (!text)
return NS_ERROR_FAILURE;
@ -2549,6 +2698,10 @@ nsDOMWindowUtils::GetPCCountScriptContents(int32_t script, JSContext* cx, nsAStr
NS_IMETHODIMP
nsDOMWindowUtils::GetPaintingSuppressed(bool *aPaintingSuppressed)
{
if (!IsUniversalXPConnectCapable()) {
return NS_ERROR_DOM_SECURITY_ERR;
}
nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
nsIDocShell *docShell = window->GetDocShell();
@ -2616,6 +2769,10 @@ nsresult
nsDOMWindowUtils::RemoteFrameFullscreenChanged(nsIDOMElement* aFrameElement,
const nsAString& aNewOrigin)
{
if (!IsUniversalXPConnectCapable()) {
return NS_ERROR_DOM_SECURITY_ERR;
}
nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
NS_ENSURE_STATE(window);
@ -2629,6 +2786,10 @@ nsDOMWindowUtils::RemoteFrameFullscreenChanged(nsIDOMElement* aFrameElement,
nsresult
nsDOMWindowUtils::RemoteFrameFullscreenReverted()
{
if (!IsUniversalXPConnectCapable()) {
return NS_ERROR_DOM_SECURITY_ERR;
}
nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
NS_ENSURE_STATE(window);
@ -2642,6 +2803,83 @@ nsDOMWindowUtils::RemoteFrameFullscreenReverted()
nsresult
nsDOMWindowUtils::ExitFullscreen()
{
if (!IsUniversalXPConnectCapable()) {
return NS_ERROR_DOM_SECURITY_ERR;
}
nsIDocument::ExitFullScreen(/* async = */ false);
return NS_OK;
}
NS_IMETHODIMP
nsDOMWindowUtils::SelectAtPoint(float aX, float aY, PRUint32 aSelectBehavior,
bool *_retval)
{
*_retval = false;
if (!IsUniversalXPConnectCapable()) {
return NS_ERROR_DOM_SECURITY_ERR;
}
nsSelectionAmount amount;
switch (aSelectBehavior) {
case nsIDOMWindowUtils::SELECT_CHARACTER:
amount = eSelectCharacter;
break;
case nsIDOMWindowUtils::SELECT_CLUSTER:
amount = eSelectCluster;
break;
case nsIDOMWindowUtils::SELECT_WORD:
amount = eSelectWord;
break;
case nsIDOMWindowUtils::SELECT_LINE:
amount = eSelectLine;
break;
case nsIDOMWindowUtils::SELECT_BEGINLINE:
amount = eSelectBeginLine;
break;
case nsIDOMWindowUtils::SELECT_ENDLINE:
amount = eSelectEndLine;
break;
case nsIDOMWindowUtils::SELECT_PARAGRAPH:
amount = eSelectParagraph;
break;
case nsIDOMWindowUtils::SELECT_WORDNOSPACE:
amount = eSelectWordNoSpace;
break;
}
nsIPresShell* presShell = GetPresShell();
if (!presShell) {
return NS_ERROR_UNEXPECTED;
}
// The root frame for this content window
nsIFrame* rootFrame = presShell->FrameManager()->GetRootFrame();
if (!rootFrame) {
return NS_ERROR_UNEXPECTED;
}
// Get the target frame at the client coordinates passed to us
nsCOMPtr<nsIWidget> widget = GetWidget();
nsIntPoint pt(aX, aY);
nsPoint ptInRoot =
nsLayoutUtils::GetEventCoordinatesRelativeTo(widget, pt, rootFrame);
nsIFrame* targetFrame = nsLayoutUtils::GetFrameForPoint(rootFrame, ptInRoot);
// This can happen if the page hasn't loaded yet or if the point
// is outside the frame.
if (!targetFrame) {
return NS_ERROR_INVALID_ARG;
}
// Convert point to coordinates relative to the target frame, which is
// what targetFrame's SelectByTypeAtPoint expects.
nsPoint relPoint =
nsLayoutUtils::GetEventCoordinatesRelativeTo(widget, pt, targetFrame);
nsresult rv =
static_cast<nsFrame*>(targetFrame)->
SelectByTypeAtPoint(GetPresContext(), relPoint, amount, amount,
nsFrame::SELECT_ACCUMULATE);
*_retval = !NS_FAILED(rv);
return NS_OK;
}

View File

@ -236,6 +236,12 @@ DOMInterfaces = {
'headerFile': 'mozilla/dom/workers/bindings/XMLHttpRequestUpload.h'
}],
'WebSocket': [
{
'headerFile': 'WebSocket.h',
'implicitJSContext': [ 'constructor' ]
}],
####################################
# Test Interfaces of various sorts #
####################################

View File

@ -337,7 +337,7 @@ DeviceStorageFile::Remove()
void
DeviceStorageFile::CollectFiles(nsTArray<nsRefPtr<DeviceStorageFile> > &aFiles,
uint64_t aSince)
PRTime aSince)
{
nsString rootPath;
nsresult rv = mFile->GetPath(rootPath);
@ -350,7 +350,7 @@ DeviceStorageFile::CollectFiles(nsTArray<nsRefPtr<DeviceStorageFile> > &aFiles,
void
DeviceStorageFile::collectFilesInternal(nsTArray<nsRefPtr<DeviceStorageFile> > &aFiles,
uint64_t aSince,
PRTime aSince,
nsAString& aRootPath)
{
nsCOMPtr<nsISimpleEnumerator> e;
@ -847,7 +847,7 @@ NS_IMPL_RELEASE_INHERITED(nsDOMDeviceStorageCursor, DOMRequest)
nsDOMDeviceStorageCursor::nsDOMDeviceStorageCursor(nsIDOMWindow* aWindow,
nsIPrincipal* aPrincipal,
DeviceStorageFile* aFile,
uint64_t aSince)
PRTime aSince)
: DOMRequest(aWindow)
, mOkToCallContinue(false)
, mSince(aSince)

View File

@ -26,6 +26,7 @@ class nsPIDOMWindow;
#include "nsIDOMEventTarget.h"
#include "nsIObserver.h"
#include "mozilla/Mutex.h"
#include "prtime.h"
#include "DeviceStorage.h"
@ -63,8 +64,8 @@ public:
nsresult Remove();
nsresult Write(nsIInputStream* aInputStream);
nsresult Write(InfallibleTArray<uint8_t>& bits);
void CollectFiles(nsTArray<nsRefPtr<DeviceStorageFile> > &aFiles, uint64_t aSince = 0);
void collectFilesInternal(nsTArray<nsRefPtr<DeviceStorageFile> > &aFiles, uint64_t aSince, nsAString& aRootPath);
void CollectFiles(nsTArray<nsRefPtr<DeviceStorageFile> > &aFiles, PRTime aSince = 0);
void collectFilesInternal(nsTArray<nsRefPtr<DeviceStorageFile> > &aFiles, PRTime aSince, nsAString& aRootPath);
static void DirectoryDiskUsage(nsIFile* aFile, uint64_t* aSoFar);
@ -98,12 +99,12 @@ public:
nsDOMDeviceStorageCursor(nsIDOMWindow* aWindow,
nsIPrincipal* aPrincipal,
DeviceStorageFile* aFile,
uint64_t aSince);
PRTime aSince);
nsTArray<nsRefPtr<DeviceStorageFile> > mFiles;
bool mOkToCallContinue;
uint64_t mSince;
PRTime mSince;
virtual bool Recv__delete__(const bool& allow);
virtual void IPDLRelease();

View File

@ -13,8 +13,7 @@ const Services = Cu.import("resource://gre/modules/Services.jsm").Services;
const DOMIdentity = Cu.import("resource://gre/modules/DOMIdentity.jsm")
.DOMIdentity;
let util = window.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
let util = SpecialPowers.getDOMWindowUtils(window);
let outerWinId = util.outerWindowID;
const identity = navigator.id || navigator.mozId;

View File

@ -11,7 +11,7 @@
* We expose Gecko-internal helpers related to "web apps" through this
* sub-interface.
*/
[scriptable, uuid(764e8930-ff06-4f23-9a6a-8523b93ac09f)]
[scriptable, uuid(efe22f80-f973-11e1-8a00-b7888ac0d2b9)]
interface mozIApplication: mozIDOMApplication
{
/* Return true if this app has |permission|. */
@ -22,4 +22,7 @@ interface mozIApplication: mozIDOMApplication
/* Returns the local id of the app (not the uuid used for sync). */
readonly attribute unsigned long localId;
/* Name copied from the manifest */
readonly attribute DOMString name;
};

View File

@ -39,7 +39,7 @@ interface nsIFile;
interface nsIDOMTouch;
interface nsIDOMClientRect;
[scriptable, uuid(f7222baa-7c4b-4079-a9e0-db13cf797f58)]
[scriptable, uuid(8A7DA5AF-26FD-4449-8887-9BEADC938B0A)]
interface nsIDOMWindowUtils : nsISupports {
/**
@ -921,6 +921,33 @@ interface nsIDOMWindowUtils : nsISupports {
in unsigned long aLength,
in boolean aReverse);
/* Selection behaviors - mirror nsIFrame's nsSelectionAmount constants */
const unsigned long SELECT_CHARACTER = 0;
const unsigned long SELECT_CLUSTER = 1;
const unsigned long SELECT_WORD = 2;
const unsigned long SELECT_LINE = 3;
const unsigned long SELECT_BEGINLINE = 4;
const unsigned long SELECT_ENDLINE = 5;
const unsigned long SELECT_PARAGRAPH = 6;
const unsigned long SELECT_WORDNOSPACE = 7;
/**
* Select content at a client point based on a selection behavior if the
* underlying content is selectable. Selection will accumulate with any
* existing selection, callers should clear selection prior if needed.
* May fire selection changed events. Calls nsFrame's SelectByTypeAtPoint.
*
* @param aX, aY The selection point in client coordinates.
* @param aSelectType The selection behavior requested.
* @return True if a selection occured, false otherwise.
* @throw NS_ERROR_DOM_SECURITY_ERR, NS_ERROR_UNEXPECTED for utils
* issues, and NS_ERROR_INVALID_ARG for coordinates that are outside
* this window.
*/
boolean selectAtPoint(in float aX,
in float aY,
in unsigned long aSelectBehavior);
/**
* Perform the equivalent of:
* window.getComputedStyle(aElement, aPseudoElement).

View File

@ -95,6 +95,7 @@
#include "nsDOMFile.h"
#include "nsIRemoteBlob.h"
#include "ProcessUtils.h"
#include "StructuredCloneUtils.h"
#include "URIUtils.h"
#include "nsIScriptSecurityManager.h"
@ -296,6 +297,11 @@ ContentChild::Init(MessageLoop* aIOLoop,
GetCurrentProcId(),
startBackground ? hal::PROCESS_PRIORITY_BACKGROUND:
hal::PROCESS_PRIORITY_FOREGROUND);
if (mIsForApp && !mIsForBrowser) {
SetThisProcessName("(App)");
} else {
SetThisProcessName("Browser");
}
return true;
}

View File

@ -39,14 +39,13 @@ CrashReporterParent::RecvAddLibraryMappings(const InfallibleTArray<Mapping>& map
return true;
}
bool
CrashReporterParent::RecvAnnotateCrashReport(const nsCString& key,
const nsCString& data)
void
CrashReporterParent::AnnotateCrashReport(const nsCString& key,
const nsCString& data)
{
#ifdef MOZ_CRASHREPORTER
mNotes.Put(key, data);
#endif
return true;
}
bool
@ -82,22 +81,6 @@ CrashReporterParent::SetChildData(const NativeThreadId& tid,
}
#ifdef MOZ_CRASHREPORTER
bool
CrashReporterParent::GenerateHangCrashReport(const AnnotationTable* processNotes)
{
if (mChildDumpID.IsEmpty())
return false;
GenerateChildData(processNotes);
CrashReporter::AnnotationTable notes;
notes.Init(4);
notes.Put(nsDependentCString("HangID"), NS_ConvertUTF16toUTF8(mHangID));
if (!CrashReporter::AppendExtraData(mParentDumpID, notes))
NS_WARNING("problem appending parent data to .extra");
return true;
}
bool
CrashReporterParent::GenerateCrashReportForMinidump(nsIFile* minidump,
const AnnotationTable* processNotes)

View File

@ -34,13 +34,6 @@ public:
bool
GeneratePairedMinidump(Toplevel* t);
/* Attempt to create a bare-bones crash report for a hang, along with extra
process-specific annotations present in the given AnnotationTable. Returns
true if successful, false otherwise.
*/
bool
GenerateHangCrashReport(const AnnotationTable* processNotes);
/* Attempt to create a bare-bones crash report, along with extra process-
specific annotations present in the given AnnotationTable. Returns true if
successful, false otherwise.
@ -49,6 +42,12 @@ public:
bool
GenerateCrashReport(Toplevel* t, const AnnotationTable* processNotes);
/**
* Add the .extra data for an existing crash report.
*/
bool
GenerateChildData(const AnnotationTable* processNotes);
bool
GenerateCrashReportForMinidump(nsIFile* minidump,
const AnnotationTable* processNotes);
@ -63,18 +62,6 @@ public:
void
SetChildData(const NativeThreadId& id, const uint32_t& processType);
/* Returns the shared hang ID of a parent/child paired minidump.
GeneratePairedMinidump must be called first.
*/
const nsString& HangID() {
return mHangID;
}
/* Returns the ID of the parent minidump.
GeneratePairedMinidump must be called first.
*/
const nsString& ParentDumpID() {
return mParentDumpID;
}
/* Returns the ID of the child minidump.
GeneratePairedMinidump or GenerateCrashReport must be called first.
*/
@ -82,26 +69,27 @@ public:
return mChildDumpID;
}
void
AnnotateCrashReport(const nsCString& key, const nsCString& data);
protected:
virtual void ActorDestroy(ActorDestroyReason why);
virtual bool
RecvAddLibraryMappings(const InfallibleTArray<Mapping>& m);
virtual bool
RecvAnnotateCrashReport(const nsCString& key, const nsCString& data);
RecvAnnotateCrashReport(const nsCString& key, const nsCString& data) {
AnnotateCrashReport(key, data);
return true;
}
virtual bool
RecvAppendAppNotes(const nsCString& data);
#ifdef MOZ_CRASHREPORTER
bool
GenerateChildData(const AnnotationTable* processNotes);
AnnotationTable mNotes;
#endif
nsCString mAppNotes;
nsString mHangID;
nsString mChildDumpID;
nsString mParentDumpID;
NativeThreadId mMainThread;
time_t mStartTime;
uint32_t mProcessType;
@ -120,14 +108,10 @@ CrashReporterParent::GeneratePairedMinidump(Toplevel* t)
child = t->OtherProcess();
#endif
nsCOMPtr<nsIFile> childDump;
nsCOMPtr<nsIFile> parentDump;
if (CrashReporter::CreatePairedMinidumps(child,
mMainThread,
&mHangID,
getter_AddRefs(childDump),
getter_AddRefs(parentDump)) &&
CrashReporter::GetIDFromMinidump(childDump, mChildDumpID) &&
CrashReporter::GetIDFromMinidump(parentDump, mParentDumpID)) {
getter_AddRefs(childDump)) &&
CrashReporter::GetIDFromMinidump(childDump, mChildDumpID)) {
return true;
}
return false;

View File

@ -23,11 +23,13 @@
#include "mozilla/layout/RenderFrameChild.h"
#include "mozilla/StaticPtr.h"
#include "mozilla/unused.h"
#include "mozIApplication.h"
#include "nsComponentManagerUtils.h"
#include "nsComponentManagerUtils.h"
#include "nsContentUtils.h"
#include "nsEmbedCID.h"
#include "nsEventListenerManager.h"
#include "nsIAppsService.h"
#include "nsIBaseWindow.h"
#include "nsIComponentManager.h"
#include "nsIDOMClassInfo.h"
@ -677,6 +679,39 @@ TabChild::~TabChild()
}
}
void
TabChild::SetProcessNameToAppName()
{
if (mIsBrowserElement || (mAppId == nsIScriptSecurityManager::NO_APP_ID)) {
return;
}
nsCOMPtr<nsIAppsService> appsService =
do_GetService(APPS_SERVICE_CONTRACTID);
if (!appsService) {
NS_WARNING("No AppsService");
return;
}
nsresult rv;
nsCOMPtr<mozIDOMApplication> domApp;
rv = appsService->GetAppByLocalId(mAppId, getter_AddRefs(domApp));
if (NS_FAILED(rv) || !domApp) {
NS_WARNING("GetAppByLocalId failed");
return;
}
nsCOMPtr<mozIApplication> app = do_QueryInterface(domApp);
if (!app) {
NS_WARNING("app isn't a mozIApplication");
return;
}
nsAutoString appName;
rv = app->GetName(appName);
if (NS_FAILED(rv)) {
NS_WARNING("Failed to retrieve app name");
return;
}
SetThisProcessName(NS_LossyConvertUTF16toASCII(appName).get());
}
bool
TabChild::IsRootContentDocument()
{
@ -698,6 +733,7 @@ bool
TabChild::RecvLoadURL(const nsCString& uri)
{
printf("loading %s, %d\n", uri.get(), NS_IsMainThread());
SetProcessNameToAppName();
nsresult rv = mWebNav->LoadURI(NS_ConvertUTF8toUTF16(uri).get(),
nsIWebNavigation::LOAD_FLAGS_NONE,

View File

@ -48,6 +48,7 @@
#include "nsITabChild.h"
#include "mozilla/Attributes.h"
#include "FrameMetrics.h"
#include "ProcessUtils.h"
struct gfxMatrix;
@ -309,6 +310,7 @@ private:
bool InitTabChildGlobal(FrameScriptLoading aScriptLoading = DEFAULT_LOAD_SCRIPTS);
bool InitRenderingState();
void DestroyWindow();
void SetProcessNameToAppName();
// Call RecvShow(nsIntSize(0, 0)) and block future calls to RecvShow().
void DoFakeShow();

View File

@ -1,15 +1,9 @@
[DEFAULT]
b2g = true
browser = false
qemu = true
[test_mobile_networks.js]
b2g = true
browser = false
qemu = true
[test_mobile_voice_state.js]
b2g = true
browser = false
qemu = true
[test_mobile_iccinfo.js]
b2g = true
browser = false
qemu = true
[test_mobile_operator_names.js]

View File

@ -0,0 +1,77 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
MARIONETTE_TIMEOUT = 60000;
SpecialPowers.addPermission("mobileconnection", true, document);
let connection = navigator.mozMobileConnection;
ok(connection instanceof MozMobileConnection,
"connection is instanceof " + connection.constructor);
let voice = connection.voice;
ok(voice, "voice connection valid");
let network = voice.network;
ok(network, "voice network info valid");
let emulatorCmdPendingCount = 0;
function setEmulatorOperatorNames(longName, shortName) {
emulatorCmdPendingCount++;
let cmd = "operator set 0 " + longName + "," + shortName;
runEmulatorCmd(cmd, function (result) {
emulatorCmdPendingCount--;
let re = new RegExp("^" + longName + "," + shortName + ",");
ok(result[0].match(re), "Long/short name should be changed.");
});
}
function checkValidMccMnc() {
is(network.mcc, 310, "network.mcc");
is(network.mnc, 260, "network.mnc");
}
function doTestMobileOperatorNames(longName, shortName, callback) {
log("Testing '" + longName + "', '" + shortName + "':");
checkValidMccMnc();
connection.addEventListener("voicechange", function onvoicechange() {
connection.removeEventListener("voicechange", onvoicechange);
is(network.longName, longName, "network.longName");
is(network.shortName, shortName, "network.shortName");
checkValidMccMnc();
setTimeout(callback, 0);
});
setEmulatorOperatorNames(longName, shortName);
}
function testMobileOperatorNames() {
doTestMobileOperatorNames("Mozilla", "B2G", function () {
doTestMobileOperatorNames("Mozilla", "", function () {
doTestMobileOperatorNames("", "B2G", function () {
doTestMobileOperatorNames("", "", function () {
doTestMobileOperatorNames("Android", "Android", cleanUp);
});
});
});
});
}
function cleanUp() {
if (emulatorCmdPendingCount > 0) {
setTimeout(cleanUp, 100);
return;
}
SpecialPowers.removePermission("mobileconnection", document);
finish();
}
testMobileOperatorNames();

View File

@ -3224,6 +3224,7 @@ nsresult nsPluginInstanceOwner::Init(nsIContent* aContent)
// document is destroyed before we try to create the new one.
objFrame->PresContext()->EnsureVisible();
} else {
NS_NOTREACHED("Should not be initializing plugin without a frame");
return NS_ERROR_FAILURE;
}

View File

@ -174,28 +174,24 @@ PluginModuleParent::WriteExtraDataForMinidump(AnnotationTable& notes)
CrashReporterParent* crashReporter = CrashReporter();
if (crashReporter) {
const nsString& hangID = crashReporter->HangID();
if (!hangID.IsEmpty()) {
notes.Put(CS("HangID"), NS_ConvertUTF16toUTF8(hangID));
#ifdef XP_WIN
if (mPluginCpuUsageOnHang.Length() > 0) {
notes.Put(CS("NumberOfProcessors"),
nsPrintfCString("%d", PR_GetNumberOfProcessors()));
if (mPluginCpuUsageOnHang.Length() > 0) {
notes.Put(CS("NumberOfProcessors"),
nsPrintfCString("%d", PR_GetNumberOfProcessors()));
nsCString cpuUsageStr;
cpuUsageStr.AppendFloat(std::ceil(mPluginCpuUsageOnHang[0] * 100) / 100);
notes.Put(CS("PluginCpuUsage"), cpuUsageStr);
nsCString cpuUsageStr;
cpuUsageStr.AppendFloat(std::ceil(mPluginCpuUsageOnHang[0] * 100) / 100);
notes.Put(CS("PluginCpuUsage"), cpuUsageStr);
#ifdef MOZ_CRASHREPORTER_INJECTOR
for (uint32_t i=1; i<mPluginCpuUsageOnHang.Length(); ++i) {
for (uint32_t i=1; i<mPluginCpuUsageOnHang.Length(); ++i) {
nsCString tempStr;
tempStr.AppendFloat(std::ceil(mPluginCpuUsageOnHang[i] * 100) / 100);
notes.Put(nsPrintfCString("CpuUsageFlashProcess%d", i), tempStr);
}
#endif
}
#endif
}
#endif
}
}
#endif // MOZ_CRASHREPORTER
@ -297,14 +293,19 @@ PluginModuleParent::ShouldContinueFromReplyTimeout()
{
#ifdef MOZ_CRASHREPORTER
CrashReporterParent* crashReporter = CrashReporter();
crashReporter->AnnotateCrashReport(NS_LITERAL_CSTRING("PluginHang"),
NS_LITERAL_CSTRING("1"));
if (crashReporter->GeneratePairedMinidump(this)) {
mBrowserDumpID = crashReporter->ParentDumpID();
mPluginDumpID = crashReporter->ChildDumpID();
PLUGIN_LOG_DEBUG(
("generated paired browser/plugin minidumps: %s/%s (ID=%s)",
NS_ConvertUTF16toUTF8(mBrowserDumpID).get(),
NS_ConvertUTF16toUTF8(mPluginDumpID).get(),
NS_ConvertUTF16toUTF8(crashReporter->HangID()).get()));
("generated paired browser/plugin minidumps: %s)",
NS_ConvertUTF16toUTF8(mPluginDumpID).get()));
crashReporter->AnnotateCrashReport(
NS_LITERAL_CSTRING("additional_minidumps"),
NS_LITERAL_CSTRING("browser"));
// TODO: collect Flash minidumps here
} else {
NS_WARNING("failed to capture paired minidumps from hang");
}
@ -377,9 +378,9 @@ PluginModuleParent::ProcessFirstMinidump()
AnnotationTable notes;
notes.Init(4);
WriteExtraDataForMinidump(notes);
if (!mPluginDumpID.IsEmpty() && !mBrowserDumpID.IsEmpty()) {
crashReporter->GenerateHangCrashReport(&notes);
if (!mPluginDumpID.IsEmpty()) {
crashReporter->GenerateChildData(&notes);
return;
}

View File

@ -1,47 +1,12 @@
Components.utils.import("resource://gre/modules/KeyValueParser.jsm");
const Cc = Components.classes;
const Ci = Components.interfaces;
var success = false;
var observerFired = false;
function parseKeyValuePairs(text) {
var lines = text.split('\n');
var data = {};
for (let i = 0; i < lines.length; i++) {
if (lines[i] == '')
continue;
// can't just .split() because the value might contain = characters
let eq = lines[i].indexOf('=');
if (eq != -1) {
let [key, value] = [lines[i].substring(0, eq),
lines[i].substring(eq + 1)];
if (key && value)
data[key] = value.replace(/\\n/g, "\n").replace(/\\\\/g, "\\");
}
}
return data;
}
function parseKeyValuePairsFromFile(file) {
var fstream = Cc["@mozilla.org/network/file-input-stream;1"].
createInstance(Ci.nsIFileInputStream);
fstream.init(file, -1, 0, 0);
var is = Cc["@mozilla.org/intl/converter-input-stream;1"].
createInstance(Ci.nsIConverterInputStream);
is.init(fstream, "UTF-8", 1024, Ci.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER);
var str = {};
var contents = '';
while (is.readString(4096, str) != 0) {
contents += str.value;
}
is.close();
fstream.close();
return parseKeyValuePairs(contents);
}
var testObserver = {
idleHang: true,
@ -55,10 +20,8 @@ var testObserver = {
var pluginId = subject.getPropertyAsAString("pluginDumpID");
isnot(pluginId, "", "got a non-empty plugin crash id");
var browserId = subject.getPropertyAsAString("browserDumpID");
isnot(browserId, "", "got a non-empty browser crash id");
// check dump and extra files
// check plugin dump and extra files
let directoryService =
Cc["@mozilla.org/file/directory_service;1"].getService(Ci.nsIProperties);
let profD = directoryService.get("ProfD", Ci.nsIFile);
@ -66,18 +29,31 @@ var testObserver = {
let pluginDumpFile = profD.clone();
pluginDumpFile.append(pluginId + ".dmp");
ok(pluginDumpFile.exists(), "plugin minidump exists");
let browserDumpFile = profD.clone();
browserDumpFile.append(browserId + ".dmp");
ok(browserDumpFile.exists(), "browser minidump exists");
let pluginExtraFile = profD.clone();
pluginExtraFile.append(pluginId + ".extra");
ok(pluginExtraFile.exists(), "plugin extra file exists");
let browserExtraFile = profD.clone();
browserExtraFile.append(browserId + ".extra");
ok(pluginExtraFile.exists(), "browser extra file exists");
// check cpu usage field
let extraData = parseKeyValuePairsFromFile(pluginExtraFile);
// check additional dumps
ok("additional_minidumps" in extraData, "got field for additional minidumps");
let additionalDumps = extraData.additional_minidumps.split(',');
ok(additionalDumps.indexOf('browser') >= 0, "browser in additional_minidumps");
let additionalDumpFiles = [];
for (let name of additionalDumps) {
let file = profD.clone();
file.append(pluginId + "-" + name + ".dmp");
ok(file.exists(), "additional dump '"+name+"' exists");
if (file.exists()) {
additionalDumpFiles.push(file);
}
}
// check cpu usage field
ok("PluginCpuUsage" in extraData, "got extra field for plugin cpu usage");
let cpuUsage = parseFloat(extraData["PluginCpuUsage"]);
if (this.idleHang) {
@ -85,16 +61,17 @@ var testObserver = {
} else {
ok(cpuUsage > 0, "plugin cpu usage is >0%");
}
// check processor count field
ok("NumberOfProcessors" in extraData, "got extra field for processor count");
ok(parseInt(extraData["NumberOfProcessors"]) > 0, "number of processors is >0");
// cleanup, to be nice
pluginDumpFile.remove(false);
browserDumpFile.remove(false);
pluginExtraFile.remove(false);
browserExtraFile.remove(false);
for (let file of additionalDumpFiles) {
file.remove(false);
}
},
QueryInterface: function(iid) {

View File

@ -6,14 +6,15 @@
<script class="testbody" type="application/javascript">
SimpleTest.waitForExplicitFinish();
const isOSXLion = navigator.userAgent.indexOf("Mac OS X 10.7") != -1;
const isOSXMtnLion = navigator.userAgent.indexOf("Mac OS X 10.8") != -1;
if (isOSXLion || isOSXMtnLion) {
todo(false, "Can't test plugin crash notification on OS X 10.7 or 10.8, see bug 705047");
SimpleTest.finish();
}
window.frameLoaded = function frameLoaded_toCrash() {
const isOSXLion = navigator.userAgent.indexOf("Mac OS X 10.7") != -1;
const isOSXMtnLion = navigator.userAgent.indexOf("Mac OS X 10.8") != -1;
if (isOSXLion || isOSXMtnLion) {
todo(false, "Can't test plugin crash notification on OS X 10.7 or 10.8, see bug 705047");
SimpleTest.finish();
return;
}
if (!SimpleTest.testPluginIsOOP()) {
ok(true, "Skipping this test when test plugin is not OOP.");
SimpleTest.finish();

View File

@ -1081,8 +1081,10 @@ NPP_SetWindow(NPP instance, NPWindow* window)
if (instanceData->asyncDrawing == AD_BITMAP) {
if (instanceData->frontBuffer &&
instanceData->frontBuffer->size.width == window->width &&
instanceData->frontBuffer->size.height == window->height) {
instanceData->frontBuffer->size.width >= 0 &&
(uint32_t)instanceData->frontBuffer->size.width == window->width &&
instanceData ->frontBuffer->size.height >= 0 &&
(uint32_t)instanceData->frontBuffer->size.height == window->height) {
return NPERR_NO_ERROR;
}
if (instanceData->frontBuffer) {

View File

@ -2674,7 +2674,7 @@ let RIL = {
debug("Operator is currently unregistered");
}
if (longName && shortName && networkTuple) {
if (networkTuple) {
try {
this._processNetworkTuple(networkTuple, this.operator);
} catch (e) {

View File

@ -33,7 +33,6 @@ SimpleTest.waitForExplicitFinish();
* In other words, they obey the interface that |hold| expects its |accessor|
* parameter to obey.
*/
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
var popupMax = makePrefAccessor("dom.popup_maximum"),
popupEvents = makePrefAccessor("dom.popup_allowed_events"),
blockPopups = makePrefAccessor("dom.disable_open_during_load"),
@ -134,7 +133,6 @@ function check_sanity() {
}
setTimeout(function() {
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
check_sanity();
hold(blockPopups, true, run_tests);
SimpleTest.finish();

View File

@ -19,13 +19,11 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=534149
/** Test for Bug 534149 **/
function getIDs(iframe) {
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
var win = iframe.contentWindow;
// Force inner creation
win.document;
var util = win.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
.getInterface(Components.interfaces.nsIDOMWindowUtils);
var util = SpecialPowers.getDOMWindowUtils(win);
return [util.outerWindowID, util.currentInnerWindowID];
}
@ -46,19 +44,16 @@ var innerWindowDestroyID;
var outerWindowDestroyID;
function outerObserver(id) {
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
outerWindowDestroyID =
id.QueryInterface(Components.interfaces.nsISupportsPRUint64).data;
SpecialPowers.wrap(id).QueryInterface(Components.interfaces.nsISupportsPRUint64).data;
}
function innerObserver(id) {
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
innerWindowDestroyID =
id.QueryInterface(Components.interfaces.nsISupportsPRUint64).data;
SpecialPowers.wrap(id).QueryInterface(Components.interfaces.nsISupportsPRUint64).data;
}
function removeFrame(iframe) {
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
var obsSvc = Components.classes["@mozilla.org/observer-service;1"]
var obsSvc = SpecialPowers.wrap(Components).classes["@mozilla.org/observer-service;1"]
.getService(Components.interfaces.nsIObserverService);
obsSvc.addObserver(outerObserver, "outer-window-destroyed", false);
obsSvc.addObserver(innerObserver, "inner-window-destroyed", false);
@ -71,8 +66,7 @@ SimpleTest.waitForExplicitFinish();
SimpleTest.executeSoon(function() {
is(innerWindowDestroyID, i1inner, "inner window of frame 1 should be destroyed");
is(outerWindowDestroyID, i1outer, "outer window of frame 1 should be destroyed");
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
var obsSvc = Components.classes["@mozilla.org/observer-service;1"]
var obsSvc = SpecialPowers.wrap(Components).classes["@mozilla.org/observer-service;1"]
.getService(Components.interfaces.nsIObserverService);
obsSvc.removeObserver(outerObserver, "outer-window-destroyed");
obsSvc.removeObserver(innerObserver, "inner-window-destroyed");

View File

@ -51,9 +51,7 @@ function registerMockPromptService()
// leave the modal state -- this is done to trigger the necessary
// accounting for triggering the "stop showing more prompts" code for
// abusive pages.
var winUtils = this.domWindow
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
var winUtils = SpecialPowers.getDOMWindowUtils(this.domWindow);
var w = winUtils.enterModalStateWithWindow();
winUtils.leaveModalStateWithWindow(w);
},

View File

@ -52,13 +52,11 @@ function alter_file(uri, file) {
(function() {
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
var prefService = Components.classes["@mozilla.org/preferences-service;1"]
var prefService = SpecialPowers.wrap(Components).classes["@mozilla.org/preferences-service;1"]
.getService(Components.interfaces.nsIPrefService),
pm = Components.classes["@mozilla.org/permissionmanager;1"]
pm = SpecialPowers.wrap(Components).classes["@mozilla.org/permissionmanager;1"]
.getService(Components.interfaces.nsIPermissionManager),
ioService = Components.classes["@mozilla.org/network/io-service;1"]
ioService = SpecialPowers.wrap(Components).classes["@mozilla.org/network/io-service;1"]
.getService(Components.interfaces.nsIIOService);
ALLOW_ACTION = pm.ALLOW_ACTION;
@ -100,7 +98,7 @@ function alter_file(uri, file) {
makePopupPrivAccessor = function(uri) {
uri = ioService.newURI(uri, null, null);
var principal = Components.classes["@mozilla.org/scriptsecuritymanager;1"]
var principal = SpecialPowers.wrap(Components).classes["@mozilla.org/scriptsecuritymanager;1"]
.getService(Components.interfaces.nsIScriptSecurityManager)
.getNoAppCodebasePrincipal(uri);

View File

@ -46,6 +46,8 @@ MOCHITEST_CHROME_FILES = \
window_callback_wrapping.xul \
test_sandbox_postMessage.html \
test_sandbox_bindings.xul \
test_selectAtPoint.html \
selectAtPoint.html \
$(NULL)
ifeq (WINNT,$(OS_ARCH))

View File

@ -0,0 +1,271 @@
<!DOCTYPE HTML>
<html>
<head>
<title>nsIDOMWindowUtils::selectAtPoint test</title>
<script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css">
<script type="application/javascript;version=1.8">
let SimpleTest = window.opener.SimpleTest;
let Ci = Components.interfaces;
function ok() { window.opener.ok.apply(window.opener, arguments); }
function done() { window.opener.done.apply(window.opener, arguments); }
function dumpLn() {
for (let idx = 0; idx < arguments.length; idx++)
dump(arguments[idx] + " ");
dump("\n");
}
function getCharacterDims() {
let span = document.getElementById("measure");
let rect = span.getBoundingClientRect();
return { width: rect.right - rect.left,
height: rect.bottom - rect.top };
}
function setStart(aDWU, aX, aY, aSelectType)
{
// Clear any existing selection
let selection = document.getSelection();
selection.removeAllRanges();
// Select text
let result = aDWU.selectAtPoint(aX, aY, aSelectType);
ok(result == true, "selectAtPoint secceeded?");
}
function setEnd(aDWU, aX, aY, aSelectType)
{
// Select text
let result = aDWU.selectAtPoint(aX, aY, aSelectType);
ok(result == true, "selectAtPoint secceeded?");
}
function setSingle(aDWU, aX, aY, aSelectType, aSelectTypeStr, aExpectedSelectionText) {
// Clear any existing selection
let selection = document.getSelection();
selection.removeAllRanges();
// Select text
let result = aDWU.selectAtPoint(aX, aY, aSelectType);
ok(result == true, "selectAtPoint secceeded?");
}
function checkSelection(aDoc, aSelectTypeStr, aExpectedSelectionText) {
// Retrieve text selected
let selection = aDoc.getSelection();
let text = selection.toString();
// Test
let result = (text == aExpectedSelectionText);
ok(result, aSelectTypeStr + " selection text matches?");
if (!result) {
dumpLn(aSelectTypeStr + " selection text:", "[" + text + "] expected:[" + aExpectedSelectionText + "]" );
}
}
function doTest() {
let dwu = window.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
let os = Components.classes["@mozilla.org/xre/app-info;1"]
.getService(Ci.nsIXULRuntime).OS;
let isLinux = (os == "Linux");
let isMac = (os == "Darwin");
let isWindows = (os == "WINNT");
if (!isLinux && !isMac && !isWindows) {
done();
return;
}
window.scrollTo(0, 0);
// Trick to get character spacing - get the bounds around a
// single character trapped in a div.
let charDims = getCharacterDims();
// dumpLn("character dims:", charDims.width, charDims.height);
//
// Root frame selection
//
// First div in the main page
let div = document.getElementById("div1");
let rect = div.getBoundingClientRect();
// Centered on the first character in the sentence div
let targetPoint = { xPos: rect.left + (charDims.width / 2),
yPos: rect.top + (charDims.height / 2) };
setSingle(dwu, targetPoint.xPos, targetPoint.yPos, Ci.nsIDOMWindowUtils.SELECT_WORDNOSPACE);
checkSelection(document, "SELECT_WORDNOSPACE", "ttestselection1");
setSingle(dwu, targetPoint.xPos, targetPoint.yPos, Ci.nsIDOMWindowUtils.SELECT_WORD);
if (isLinux || isMac) {
checkSelection(document, "SELECT_WORD", "ttestselection1");
} else if (isWindows) {
checkSelection(document, "SELECT_WORD", "ttestselection1 ");
}
setSingle(dwu, targetPoint.xPos, targetPoint.yPos, Ci.nsIDOMWindowUtils.SELECT_PARAGRAPH);
checkSelection(document, "SELECT_PARAGRAPH", "ttestselection1 Lorem ipsum dolor sit amet, at duo debet graeci, vivendum vulputate per ut. Ne labore incorrupte vix. Cu copiosae postulant tincidunt ius, in illud appetere contentiones eos. Ei munere officiis assentior pro, nibh decore ius at.");
// Centered on the second character in the sentence div
let targetPoint = { xPos: rect.left + (charDims.width + (charDims.width / 2)),
yPos: rect.top + (charDims.height / 2) };
setSingle(dwu, targetPoint.xPos, targetPoint.yPos, Ci.nsIDOMWindowUtils.SELECT_CHARACTER);
checkSelection(document, "SELECT_CHARACTER", "te");
setSingle(dwu, targetPoint.xPos, targetPoint.yPos, Ci.nsIDOMWindowUtils.SELECT_CLUSTER);
checkSelection(document, "SELECT_CLUSTER", "te");
// Separate character blocks in a word 't(te)s(ts)election1'
let targetPoint = { xPos: rect.left + (charDims.width + (charDims.width / 2)),
yPos: rect.top + (charDims.height / 2) };
setStart(dwu, targetPoint.xPos, targetPoint.yPos, Ci.nsIDOMWindowUtils.SELECT_CHARACTER);
let targetPoint = { xPos: rect.left + ((charDims.width * 4) + (charDims.width / 2)),
yPos: rect.top + (charDims.height / 2) };
setEnd(dwu, targetPoint.xPos, targetPoint.yPos, Ci.nsIDOMWindowUtils.SELECT_CHARACTER);
if (isLinux || isMac) {
// XXX I think this is a bug, the right hand selection is 4.5 characters over with a
// monspaced font. what we want: t(te)s(ts)election1 what we get: t(te)st(se)lection1
checkSelection(document, "split selection", "tese");
} else if (isWindows) {
checkSelection(document, "split selection", "tets");
}
// Trying to select where there's no text, should fail but not throw
let result = dwu.selectAtPoint(rect.left - 20, rect.top - 20, Ci.nsIDOMWindowUtils.SELECT_CHARACTER, false);
ok(result == false, "couldn't select?");
// Second div in the main page
let div = document.getElementById("div2");
let rect = div.getBoundingClientRect();
// Centered on the first line, first character in the paragraph div
let targetPoint = { xPos: rect.left + (charDims.width / 2),
yPos: rect.top + (charDims.height / 2) };
setSingle(dwu, targetPoint.xPos + 50, targetPoint.yPos, Ci.nsIDOMWindowUtils.SELECT_PARAGRAPH);
checkSelection(document, "SELECT_PARAGRAPH", "Lorem ipsum dolor sit amet, at duo debet graeci, vivendum vulputate per ut. Ne labore incorrupte vix. Cu copiosae postulant tincidunt ius, in illud appetere contentiones eos.");
//
// Inner IFRAME selection tests
//
let frame = document.getElementById("frame1");
let dwuFrame = frame.contentDocument
.defaultView
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
frame.contentWindow.scrollTo(0, 0);
let rect = frame.getBoundingClientRect();
let targetPoint = { xPos: rect.left + (charDims.width / 2),
yPos: rect.top + (charDims.height / 2) };
setSingle(dwuFrame, targetPoint.xPos, targetPoint.yPos, Ci.nsIDOMWindowUtils.SELECT_WORDNOSPACE);
checkSelection(frame.contentWindow.document, "SELECT_WORDNOSPACE", "ttestselection2");
setSingle(dwuFrame, targetPoint.xPos, targetPoint.yPos, Ci.nsIDOMWindowUtils.SELECT_WORD);
if (isLinux || isMac) {
checkSelection(frame.contentWindow.document, "SELECT_WORD", "ttestselection2");
} else if (isWindows) {
checkSelection(frame.contentWindow.document, "SELECT_WORD", "ttestselection2 ");
}
setSingle(dwuFrame, targetPoint.xPos, targetPoint.yPos, Ci.nsIDOMWindowUtils.SELECT_PARAGRAPH);
checkSelection(frame.contentWindow.document, "SELECT_PARAGRAPH", "ttestselection2 Lorem ipsum dolor sit amet, at duo debet graeci, vivendum vulputate per ut.");
// Outside the frame should throw. This is a failure in coordinate setup of
// nsDOMWindowUtils::SelectAtPoint.
let thr = false;
try {
dwuFrame.selectAtPoint(rect.right + 50, rect.top, Ci.nsIDOMWindowUtils.SELECT_WORD, false);
} catch (ex) { thr = true; }
ok(thr == true, "selectAtPoint expected throw?");
done();
}
let frameLoad = false;
let pageLoad = false;
let painted = false;
function testReady() {
if (frameLoad && pageLoad && painted)
doTest();
}
function onFrameLoad() {
frameLoad = true;
testReady();
}
function onPageLoad() {
pageLoad = true;
testReady();
}
function onPaint() {
window.removeEventListener("MozAfterPaint", onPaint, false);
painted = true;
testReady();
}
window.addEventListener("MozAfterPaint", onPaint, false);
</script>
<style type="text/css">
body {
font-family: monospace;
margin-left: 40px;
margin-top: 40px;
padding: 0;
}
#div1 {
border: 1px solid red;
width: 400px;
height: 100px;
}
#frame1 {
display: block;
height: 100px;
width: 300px;
border: 1px solid blue;
padding: 0;
margin: 0;
}
#div2 {
border: 1px solid green;
}
#measure {
padding: 0px;
margin: 0px;
border: 1px solid red;
}
</style>
</head>
<body id="body" onload="onPageLoad();">
<div id="div1">ttestselection1 Lorem ipsum dolor sit amet, at duo debet graeci, vivendum vulputate per ut. Ne labore incorrupte vix. Cu copiosae postulant tincidunt ius, in illud appetere contentiones eos. Ei munere officiis assentior pro, nibh decore ius at.</div>
<br />
<iframe id="frame1" src="data:text/html,<html><body style='margin: 0; padding: 0; font-family: monospace;' onload='window.parent.onFrameLoad();'><div id='sel2'>ttestselection2 Lorem ipsum dolor sit amet, at duo debet graeci, vivendum vulputate per ut.</div><br/><br/></body></html>"></iframe>
<br/>
<div id="div2">Lorem ipsum dolor sit amet, at duo debet graeci, vivendum vulputate per ut. Ne labore incorrupte vix. Cu copiosae postulant tincidunt ius, in illud appetere contentiones eos.</div>
<br />
<span id="measure">t</span>
</body>
</html>

View File

@ -0,0 +1,21 @@
<!DOCTYPE HTML>
<html>
<head>
<title>nsIDOMWindowUtils::selectAtPoint test</title>
<script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css">
<script type="application/javascript">
SimpleTest.waitForExplicitFinish();
function done() {
testwindow.close();
SimpleTest.finish();
}
var testwindow = window.open("selectAtPoint.html", '_new', 'width=800,height=800');
</script>
</head>
<body>
<p id="display"></p>
<div id="content" style="display: none">
</body>
</html>

View File

@ -25,10 +25,7 @@
<script type="application/javascript;version=1.8">
// Enable privileges so we can use nsIDOMWindowUtils interface
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
var domWindowUtils = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
.getInterface(Components.interfaces.nsIDOMWindowUtils);
var domWindowUtils = SpecialPowers.getDOMWindowUtils(window);
/*
nsIDOMElement elementFromPoint(in long aX,

View File

@ -24,12 +24,9 @@
}
function testScrollXY() {
// Enable privileges so we can use nsIDOMWindowUtils interface
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
let iframe = document.getElementById("iframe");
let cwindow = iframe.contentWindow;
let domWindowUtils = cwindow.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
.getInterface(Components.interfaces.nsIDOMWindowUtils);
let domWindowUtils = SpecialPowers.getDOMWindowUtils(cwindow);
function checkGetScrollXYState(flush, vals, testName) {
let scrollX = {}, scrollY = {};
@ -64,8 +61,7 @@
function testHiddenIframe() {
let iframe = document.getElementById("hidden-iframe");
let cwindow = iframe.contentWindow;
let domWindowUtils = cwindow.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
.getInterface(Components.interfaces.nsIDOMWindowUtils);
let domWindowUtils = SpecialPowers.getDOMWindowUtils(cwindow);
// make sure getScrollXY doesn't throw
let scrollX = {}, scrollY = {};

View File

@ -6,6 +6,7 @@
<script type="text/javascript">
const DOM_QUOTA_REACHED = 2152924150;
const Cc = SpecialPowers.wrap(Components).classes;
function checkException(func, exc)
{
@ -22,12 +23,10 @@ function checkException(func, exc)
function doStep()
{
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
var io = Components.classes["@mozilla.org/network/io-service;1"]
var io = Cc["@mozilla.org/network/io-service;1"]
.getService(Components.interfaces.nsIIOService);
var uri = io.newURI(window.location, "", null);
var cp = Components.classes["@mozilla.org/cookie/permission;1"]
var cp = Cc["@mozilla.org/cookie/permission;1"]
.getService(Components.interfaces.nsICookiePermission);
cp.setAccess(uri, Components.interfaces.nsICookiePermission.ACCESS_SESSION);

View File

@ -9,12 +9,10 @@
function startTest()
{
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
var io = Components.classes["@mozilla.org/network/io-service;1"]
var io = SpecialPowers.wrap(Components).classes["@mozilla.org/network/io-service;1"]
.getService(Components.interfaces.nsIIOService);
var uri = io.newURI(window.location, "", null);
var cp = Components.classes["@mozilla.org/cookie/permission;1"]
var cp = SpecialPowers.wrap(Components).classes["@mozilla.org/cookie/permission;1"]
.getService(Components.interfaces.nsICookiePermission);
cp.setAccess(uri, Components.interfaces.nsICookiePermission.ACCESS_DENY);

View File

@ -19,12 +19,10 @@ function startTest()
localStorage.setItem("persistent1", "persistent value 1");
localStorage.setItem("persistent2", "persistent value 2");
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
var io = Components.classes["@mozilla.org/network/io-service;1"]
var io = SpecialPowers.wrap(Components).classes["@mozilla.org/network/io-service;1"]
.getService(Components.interfaces.nsIIOService);
var uri = io.newURI(window.location, "", null);
var cp = Components.classes["@mozilla.org/cookie/permission;1"]
var cp = SpecialPowers.wrap(Components).classes["@mozilla.org/cookie/permission;1"]
.getService(Components.interfaces.nsICookiePermission);
cp.setAccess(uri, Components.interfaces.nsICookiePermission.ACCESS_SESSION);

View File

@ -9,12 +9,10 @@
function startTest()
{
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
var io = Components.classes["@mozilla.org/network/io-service;1"]
var io = SpecialPowers.wrap(Components).classes["@mozilla.org/network/io-service;1"]
.getService(Components.interfaces.nsIIOService);
var uri = io.newURI(window.location, "", null);
var cp = Components.classes["@mozilla.org/cookie/permission;1"]
var cp = SpecialPowers.wrap(Components).classes["@mozilla.org/cookie/permission;1"]
.getService(Components.interfaces.nsICookiePermission);
is(localStorage.getItem("session only"), "session value", "Value present when cookies in session-only mode");

View File

@ -7,9 +7,7 @@
<script type="text/javascript">
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
Components.utils.import("resource://gre/modules/Services.jsm");
window.Services = SpecialPowers.Services;
// Set cookies behavior to "always reject".
Services.prefs.setIntPref("network.cookie.cookieBehavior", 2);

View File

@ -8,27 +8,27 @@
<script type="text/javascript">
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
const Cc = SpecialPowers.wrap(Components).classes;
var currentTest = 1;
var prefs = Components.classes["@mozilla.org/preferences-service;1"]
var prefs = Cc["@mozilla.org/preferences-service;1"]
.getService(Components.interfaces.nsIPrefBranch);
var io = Components.classes["@mozilla.org/network/io-service;1"]
var io = Cc["@mozilla.org/network/io-service;1"]
.getService(Components.interfaces.nsIIOService);
var uri = io.newURI(window.location, "", null);
var cp = Components.classes["@mozilla.org/cookie/permission;1"]
var cp = Cc["@mozilla.org/cookie/permission;1"]
.getService(Components.interfaces.nsICookiePermission);
var quota, quotaOffline;
function addOfflineApp(url)
{
var permissionManager = Components.classes["@mozilla.org/permissionmanager;1"]
var permissionManager = Cc["@mozilla.org/permissionmanager;1"]
.getService(Components.interfaces.nsIPermissionManager);
var uri = Components.classes["@mozilla.org/network/io-service;1"]
var uri = Cc["@mozilla.org/network/io-service;1"]
.getService(Components.interfaces.nsIIOService)
.newURI(url, null, null);
var principal = Components.classes["@mozilla.org/scriptsecuritymanager;1"]
var principal = Cc["@mozilla.org/scriptsecuritymanager;1"]
.getService(Components.interfaces.nsIScriptSecurityManager)
.getNoAppCodebasePrincipal(uri);
@ -38,12 +38,12 @@ function addOfflineApp(url)
function removeOfflineApp(url)
{
var permissionManager = Components.classes["@mozilla.org/permissionmanager;1"]
var permissionManager = Cc["@mozilla.org/permissionmanager;1"]
.getService(Components.interfaces.nsIPermissionManager);
var uri = Components.classes["@mozilla.org/network/io-service;1"]
var uri = Cc["@mozilla.org/network/io-service;1"]
.getService(Components.interfaces.nsIIOService)
.newURI(url, null, null);
var principal = Components.classes["@mozilla.org/scriptsecuritymanager;1"]
var principal = Cc["@mozilla.org/scriptsecuritymanager;1"]
.getService(Components.interfaces.nsIScriptSecurityManager)
.getNoAppCodebasePrincipal(uri);
@ -54,8 +54,6 @@ function doNextTest()
{
slave = frame;
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
switch (currentTest)
{
// Initialy setup the quota to testing value of 1024B and

37
dom/webidl/Blob.webidl Normal file
View File

@ -0,0 +1,37 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*
* The origin of this IDL file is
* http://dev.w3.org/2006/webapi/FileAPI/#blob
*
* Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
* liability, trademark and document use rules apply.
*/
/*
[Constructor, Constructor((ArrayBuffer or ArrayBufferView or Blob or DOMString)[] blobParts, optional BlobPropertyBag options)]
interface Blob {
readonly attribute unsigned long long size;
readonly attribute DOMString type;
//slice Blob into byte-ranged chunks
Blob slice(optional long long start,
optional long long end,
optional DOMString contentType);
void close();
};
*/
enum EndingTypes{"transparent", "native"};
dictionary BlobPropertyBag {
DOMString type = "";
EndingTypes endings = "transparent";
};

View File

@ -10,6 +10,7 @@ generated_webidl_files = \
webidl_files = \
AudioContext.webidl \
Blob.webidl \
CanvasRenderingContext2D.webidl \
CSSStyleDeclaration.webidl \
Function.webidl \
@ -18,6 +19,7 @@ webidl_files = \
Performance.webidl \
PerformanceNavigation.webidl \
PerformanceTiming.webidl \
WebSocket.webidl \
XMLHttpRequest.webidl \
XMLHttpRequestEventTarget.webidl \
XMLHttpRequestUpload.webidl \

View File

@ -0,0 +1,69 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*
* The origin of this IDL file is
* http://www.whatwg.org/html/#network
*
* © Copyright 2004-2011 Apple Computer, Inc., Mozilla Foundation, and Opera Software ASA.
* You are granted a license to use, reproduce and create derivative works of this document.
*/
enum BinaryType { "blob", "arraybuffer" };
[PrefControlled,
Constructor(DOMString url),
Constructor(DOMString url, DOMString protocols),
Constructor(DOMString url, sequence<DOMString> protocols)]
interface WebSocket : EventTarget {
readonly attribute DOMString url;
// ready state
const unsigned short CONNECTING = 0;
const unsigned short OPEN = 1;
const unsigned short CLOSING = 2;
const unsigned short CLOSED = 3;
readonly attribute unsigned short readyState;
readonly attribute unsigned long bufferedAmount;
// networking
[TreatNonCallableAsNull, SetterThrows]
attribute Function? onopen;
[TreatNonCallableAsNull, SetterThrows]
attribute Function? onerror;
[TreatNonCallableAsNull, SetterThrows]
attribute Function? onclose;
readonly attribute DOMString extensions;
readonly attribute DOMString protocol;
[Throws]
void close([Clamp] optional unsigned short code, optional DOMString reason);
// messaging
[TreatNonCallableAsNull, SetterThrows]
attribute Function? onmessage;
attribute BinaryType binaryType;
[Throws]
void send(DOMString data);
[Throws]
void send(Blob data);
[Throws]
void send(ArrayBuffer data);
[Throws]
void send(ArrayBufferView data);
};

View File

@ -26,9 +26,9 @@ Tests of DOM Worker Blob constructor
};
function f() {
onmessage = function(e) {
var b = new Blob([e.data, "World"],{});
var b = new Blob([e.data, "World"],{type: "text/plain"});
var fr = new FileReaderSync();
postMessage(fr.readAsText(b));
postMessage({text: fr.readAsText(b), type: b.type});
};
}
var b = new Blob([f,"f();"]);
@ -36,7 +36,8 @@ Tests of DOM Worker Blob constructor
var w = new Worker(u);
w.onmessage = function(e) {
URL.revokeObjectURL(u);
is(e.data, fr.result);
is(e.data.text, fr.result);
is(e.data.type, "text/plain");
SimpleTest.finish();
};
w.onerror = function(e) {

View File

@ -89,9 +89,7 @@ function onLoadIFrame()
QueryInterface(Components.interfaces.nsIInterfaceRequestor).
getInterface(Components.interfaces.nsISelectionDisplay).
QueryInterface(Components.interfaces.nsISelectionController);
var utils = window.
QueryInterface(Components.interfaces.nsIInterfaceRequestor).
getInterface(Components.interfaces.nsIDOMWindowUtils);
var utils = SpecialPowers.getDOMWindowUtils(window);
const nsIDOMNode = Components.interfaces.nsIDOMNode;
// move focus to the HTML editor

View File

@ -100,6 +100,111 @@ ToInsideIntRect(const gfxRect& aRect)
return nsIntRect(r.X(), r.Y(), r.Width(), r.Height());
}
// A context helper for BasicLayerManager::PaintLayer() that holds all the
// painting context together in a data structure so it can be easily passed
// around. It also uses ensures that the Transform and Opaque rect are restored
// to their former state on destruction.
class PaintContext {
public:
PaintContext(gfxContext* aTarget, Layer* aLayer,
LayerManager::DrawThebesLayerCallback aCallback,
void* aCallbackData, ReadbackProcessor* aReadback)
: mTarget(aTarget)
, mTargetMatrixSR(aTarget)
, mLayer(aLayer)
, mCallback(aCallback)
, mCallbackData(aCallbackData)
, mReadback(aReadback)
, mPushedOpaqueRect(false)
{}
~PaintContext()
{
// Matrix is restored by mTargetMatrixSR
if (mPushedOpaqueRect)
{
ClearOpaqueRect();
}
}
// Applies the effective 2D transform and returns true if it is a 2D
// transform. If it's a 3D transform then it applies an identity and returns
// false.
bool Apply2DTransform()
{
const gfx3DMatrix& effectiveTransform = mLayer->GetEffectiveTransform();
// Will return an identity matrix for 3d transforms.
bool is2D = effectiveTransform.CanDraw2D(&mTransform);
mTarget->SetMatrix(mTransform);
return is2D;
}
// Set the opaque rect to match the bounds of the visible region.
void AnnotateOpaqueRect()
{
const nsIntRegion& visibleRegion = mLayer->GetEffectiveVisibleRegion();
const nsIntRect& bounds = visibleRegion.GetBounds();
nsRefPtr<gfxASurface> currentSurface = mTarget->CurrentSurface();
if (mTarget->IsCairo()) {
const gfxRect& targetOpaqueRect = currentSurface->GetOpaqueRect();
// Try to annotate currentSurface with a region of pixels that have been
// (or will be) painted opaque, if no such region is currently set.
if (targetOpaqueRect.IsEmpty() && visibleRegion.GetNumRects() == 1 &&
(mLayer->GetContentFlags() & Layer::CONTENT_OPAQUE) &&
!mTransform.HasNonAxisAlignedTransform()) {
currentSurface->SetOpaqueRect(
mTarget->UserToDevice(gfxRect(bounds.x, bounds.y, bounds.width, bounds.height)));
mPushedOpaqueRect = true;
}
} else {
DrawTarget *dt = mTarget->GetDrawTarget();
const IntRect& targetOpaqueRect = dt->GetOpaqueRect();
// Try to annotate currentSurface with a region of pixels that have been
// (or will be) painted opaque, if no such region is currently set.
if (targetOpaqueRect.IsEmpty() && visibleRegion.GetNumRects() == 1 &&
(mLayer->GetContentFlags() & Layer::CONTENT_OPAQUE) &&
!mTransform.HasNonAxisAlignedTransform()) {
gfx::Rect opaqueRect = dt->GetTransform().TransformBounds(
gfx::Rect(bounds.x, bounds.y, bounds.width, bounds.height));
opaqueRect.RoundIn();
IntRect intOpaqueRect;
if (opaqueRect.ToIntRect(&intOpaqueRect)) {
mTarget->GetDrawTarget()->SetOpaqueRect(intOpaqueRect);
mPushedOpaqueRect = true;
}
}
}
}
// Clear the Opaque rect. Although this doesn't really restore it to it's
// previous state it will happen on the exit path of the PaintLayer() so when
// painting is complete the opaque rect qill be clear.
void ClearOpaqueRect() {
if (mTarget->IsCairo()) {
nsRefPtr<gfxASurface> currentSurface = mTarget->CurrentSurface();
currentSurface->SetOpaqueRect(gfxRect());
} else {
mTarget->GetDrawTarget()->SetOpaqueRect(IntRect());
}
}
gfxContext* mTarget;
gfxContextMatrixAutoSaveRestore mTargetMatrixSR;
Layer* mLayer;
LayerManager::DrawThebesLayerCallback mCallback;
void* mCallbackData;
ReadbackProcessor* mReadback;
gfxMatrix mTransform;
bool mPushedOpaqueRect;
};
BasicLayerManager::BasicLayerManager(nsIWidget* aWidget) :
#ifdef DEBUG
mPhase(PHASE_NONE),
@ -690,7 +795,71 @@ Transform3D(gfxASurface* aSource, gfxContext* aDest,
return destImage.forget();
}
void
BasicLayerManager::PaintSelfOrChildren(PaintContext& aPaintContext,
gfxContext* aGroupTarget)
{
BasicImplData* data = ToData(aPaintContext.mLayer);
if (aPaintContext.mLayer->GetFirstChild() &&
aPaintContext.mLayer->GetMaskLayer() &&
HasShadowManager()) {
// 'paint' the mask so that it gets sent to the shadow layer tree
static_cast<BasicImplData*>(aPaintContext.mLayer->GetMaskLayer()->ImplData())
->Paint(nullptr, nullptr);
}
/* Only paint ourself, or our children - This optimization relies on this! */
Layer* child = aPaintContext.mLayer->GetFirstChild();
if (!child) {
if (aPaintContext.mLayer->AsThebesLayer()) {
data->PaintThebes(aGroupTarget, aPaintContext.mLayer->GetMaskLayer(),
aPaintContext.mCallback, aPaintContext.mCallbackData,
aPaintContext.mReadback);
} else {
data->Paint(aGroupTarget, aPaintContext.mLayer->GetMaskLayer());
}
} else {
ReadbackProcessor readback;
ContainerLayer* container =
static_cast<ContainerLayer*>(aPaintContext.mLayer);
if (IsRetained()) {
readback.BuildUpdates(container);
}
nsAutoTArray<Layer*, 12> children;
container->SortChildrenBy3DZOrder(children);
for (uint32_t i = 0; i < children.Length(); i++) {
PaintLayer(aGroupTarget, children.ElementAt(i), aPaintContext.mCallback,
aPaintContext.mCallbackData, &readback);
if (mTransactionIncomplete)
break;
}
}
}
void
BasicLayerManager::FlushGroup(PaintContext& aPaintContext, bool aNeedsClipToVisibleRegion)
{
// If we're doing our own double-buffering, we need to avoid drawing
// the results of an incomplete transaction to the destination surface ---
// that could cause flicker. Double-buffering is implemented using a
// temporary surface for one or more container layers, so we need to stop
// those temporary surfaces from being composited to aTarget.
// ApplyDoubleBuffering guarantees that this container layer can't
// intersect any other leaf layers, so if the transaction is not yet marked
// incomplete, the contents of this container layer are the final contents
// for the window.
if (!mTransactionIncomplete) {
if (aNeedsClipToVisibleRegion) {
gfxUtils::ClipToRegion(aPaintContext.mTarget,
aPaintContext.mLayer->GetEffectiveVisibleRegion());
}
BasicContainerLayer* container = static_cast<BasicContainerLayer*>(aPaintContext.mLayer);
AutoSetOperator setOperator(aPaintContext.mTarget, container->GetOperator());
PaintWithMask(aPaintContext.mTarget, aPaintContext.mLayer->GetEffectiveOpacity(),
HasShadowManager() ? nullptr : aPaintContext.mLayer->GetMaskLayer());
}
}
void
BasicLayerManager::PaintLayer(gfxContext* aTarget,
@ -699,10 +868,11 @@ BasicLayerManager::PaintLayer(gfxContext* aTarget,
void* aCallbackData,
ReadbackProcessor* aReadback)
{
PaintContext paintContext(aTarget, aLayer, aCallback, aCallbackData, aReadback);
RenderTraceScope trace("BasicLayerManager::PaintLayer", "707070");
const nsIntRect* clipRect = aLayer->GetEffectiveClipRect();
const gfx3DMatrix& effectiveTransform = aLayer->GetEffectiveTransform();
// aLayer might not be a container layer, but if so we take care not to use
// the container variable
BasicContainerLayer* container = static_cast<BasicContainerLayer*>(aLayer);
@ -718,12 +888,10 @@ BasicLayerManager::PaintLayer(gfxContext* aTarget,
container->UseIntermediateSurface(),
"ContainerLayer with mask layer should force UseIntermediateSurface");
// If needsSaveRestore is false, we should still save and restore
// the CTM
gfxContextAutoSaveRestore contextSR;
bool needsSaveRestore = needsGroup || clipRect || needsClipToVisibleRegion;
gfxMatrix savedMatrix;
if (needsSaveRestore) {
aTarget->Save();
contextSR.SetContext(aTarget);
if (clipRect) {
aTarget->NewPath();
@ -731,17 +899,9 @@ BasicLayerManager::PaintLayer(gfxContext* aTarget,
aTarget->Clip();
}
}
savedMatrix = aTarget->CurrentMatrix();
gfxMatrix transform;
// Will return an identity matrix for 3d transforms, and is handled separately below.
bool is2D = effectiveTransform.CanDraw2D(&transform);
bool is2D = paintContext.Apply2DTransform();
NS_ABORT_IF_FALSE(is2D || needsGroup || !aLayer->GetFirstChild(), "Must PushGroup for 3d transforms!");
if (is2D) {
aTarget->SetMatrix(transform);
} else {
aTarget->SetMatrix(gfxMatrix());
}
const nsIntRegion& visibleRegion = aLayer->GetEffectiveVisibleRegion();
// If needsGroup is true, we'll clip to the visible region after we've popped the group
@ -750,181 +910,68 @@ BasicLayerManager::PaintLayer(gfxContext* aTarget,
// Don't need to clip to visible region again
needsClipToVisibleRegion = false;
}
bool pushedTargetOpaqueRect = false;
nsRefPtr<gfxASurface> currentSurface = aTarget->CurrentSurface();
DrawTarget *dt = aTarget->GetDrawTarget();
const nsIntRect& bounds = visibleRegion.GetBounds();
if (is2D) {
if (aTarget->IsCairo()) {
const gfxRect& targetOpaqueRect = currentSurface->GetOpaqueRect();
// Try to annotate currentSurface with a region of pixels that have been
// (or will be) painted opaque, if no such region is currently set.
if (targetOpaqueRect.IsEmpty() && visibleRegion.GetNumRects() == 1 &&
(aLayer->GetContentFlags() & Layer::CONTENT_OPAQUE) &&
!transform.HasNonAxisAlignedTransform()) {
currentSurface->SetOpaqueRect(
aTarget->UserToDevice(gfxRect(bounds.x, bounds.y, bounds.width, bounds.height)));
pushedTargetOpaqueRect = true;
}
} else {
const IntRect& targetOpaqueRect = dt->GetOpaqueRect();
// Try to annotate currentSurface with a region of pixels that have been
// (or will be) painted opaque, if no such region is currently set.
if (targetOpaqueRect.IsEmpty() && visibleRegion.GetNumRects() == 1 &&
(aLayer->GetContentFlags() & Layer::CONTENT_OPAQUE) &&
!transform.HasNonAxisAlignedTransform()) {
gfx::Rect opaqueRect = dt->GetTransform().TransformBounds(
gfx::Rect(bounds.x, bounds.y, bounds.width, bounds.height));
opaqueRect.RoundIn();
IntRect intOpaqueRect;
if (opaqueRect.ToIntRect(&intOpaqueRect)) {
aTarget->GetDrawTarget()->SetOpaqueRect(intOpaqueRect);
pushedTargetOpaqueRect = true;
}
}
}
paintContext.AnnotateOpaqueRect();
}
nsRefPtr<gfxContext> groupTarget;
nsRefPtr<gfxASurface> untransformedSurface;
bool clipIsEmpty = !aTarget || aTarget->GetClipExtents().IsEmpty();
if (!is2D && !clipIsEmpty) {
untransformedSurface =
gfxPlatform::GetPlatform()->CreateOffscreenSurface(gfxIntSize(bounds.width, bounds.height),
if (clipIsEmpty) {
PaintSelfOrChildren(paintContext, aTarget);
return;
}
if (is2D) {
if (needsGroup) {
nsRefPtr<gfxContext> groupTarget = PushGroupForLayer(aTarget, aLayer, aLayer->GetEffectiveVisibleRegion(),
&needsClipToVisibleRegion);
PaintSelfOrChildren(paintContext, groupTarget);
PopGroupToSourceWithCachedSurface(aTarget, groupTarget);
FlushGroup(paintContext, needsClipToVisibleRegion);
} else {
PaintSelfOrChildren(paintContext, aTarget);
}
} else {
const nsIntRect& bounds = visibleRegion.GetBounds();
nsRefPtr<gfxASurface> untransformedSurface =
gfxPlatform::GetPlatform()->CreateOffscreenSurface(gfxIntSize(bounds.width, bounds.height),
gfxASurface::CONTENT_COLOR_ALPHA);
if (!untransformedSurface) {
if (pushedTargetOpaqueRect) {
if (aTarget->IsCairo()) {
currentSurface->SetOpaqueRect(gfxRect(0, 0, 0, 0));
} else {
dt->SetOpaqueRect(IntRect());
}
}
NS_ASSERTION(needsSaveRestore, "Should always need to restore with 3d transforms!");
aTarget->Restore();
return;
}
untransformedSurface->SetDeviceOffset(gfxPoint(-bounds.x, -bounds.y));
groupTarget = new gfxContext(untransformedSurface);
} else if (needsGroup && !clipIsEmpty) {
groupTarget = PushGroupForLayer(aTarget, aLayer, aLayer->GetEffectiveVisibleRegion(),
&needsClipToVisibleRegion);
} else {
groupTarget = aTarget;
}
nsRefPtr<gfxContext> groupTarget = new gfxContext(untransformedSurface);
if (aLayer->GetFirstChild() &&
aLayer->GetMaskLayer() &&
HasShadowManager()) {
// 'paint' the mask so that it gets sent to the shadow layer tree
static_cast<BasicImplData*>(aLayer->GetMaskLayer()->ImplData())
->Paint(nullptr, nullptr);
}
PaintSelfOrChildren(paintContext, groupTarget);
/* Only paint ourself, or our children - This optimization relies on this! */
Layer* child = aLayer->GetFirstChild();
if (!child) {
#ifdef MOZ_LAYERS_HAVE_LOG
MOZ_LAYERS_LOG(("%s (0x%p) is covered: %i\n", __FUNCTION__,
(void*)aLayer, data->IsHidden()));
#endif
if (aLayer->AsThebesLayer()) {
data->PaintThebes(groupTarget,
aLayer->GetMaskLayer(),
aCallback, aCallbackData,
aReadback);
} else {
data->Paint(groupTarget, aLayer->GetMaskLayer());
}
} else {
ReadbackProcessor readback;
ContainerLayer* container = static_cast<ContainerLayer*>(aLayer);
if (IsRetained()) {
readback.BuildUpdates(container);
}
nsAutoTArray<Layer*, 12> children;
container->SortChildrenBy3DZOrder(children);
for (uint32_t i = 0; i < children.Length(); i++) {
PaintLayer(groupTarget, children.ElementAt(i), aCallback, aCallbackData, &readback);
if (mTransactionIncomplete)
break;
}
}
if (needsGroup) {
bool blitComplete = false;
if (is2D) {
PopGroupToSourceWithCachedSurface(aTarget, groupTarget);
} else {
// Temporary fast fix for bug 725886
// Revert these changes when 725886 is ready
if (!clipIsEmpty) {
NS_ABORT_IF_FALSE(untransformedSurface,
"We should always allocate an untransformed surface with 3d transforms!");
gfxPoint offset;
bool dontBlit = needsClipToVisibleRegion || mTransactionIncomplete ||
aLayer->GetEffectiveOpacity() != 1.0f;
// Temporary fast fix for bug 725886
// Revert these changes when 725886 is ready
NS_ABORT_IF_FALSE(untransformedSurface,
"We should always allocate an untransformed surface with 3d transforms!");
gfxPoint offset;
bool dontBlit = needsClipToVisibleRegion || mTransactionIncomplete ||
aLayer->GetEffectiveOpacity() != 1.0f;
#ifdef DEBUG
if (aLayer->GetDebugColorIndex() != 0) {
gfxRGBA color((aLayer->GetDebugColorIndex() & 1) ? 1.0 : 0.0,
(aLayer->GetDebugColorIndex() & 2) ? 1.0 : 0.0,
(aLayer->GetDebugColorIndex() & 4) ? 1.0 : 0.0,
1.0);
if (aLayer->GetDebugColorIndex() != 0) {
gfxRGBA color((aLayer->GetDebugColorIndex() & 1) ? 1.0 : 0.0,
(aLayer->GetDebugColorIndex() & 2) ? 1.0 : 0.0,
(aLayer->GetDebugColorIndex() & 4) ? 1.0 : 0.0,
1.0);
nsRefPtr<gfxContext> temp = new gfxContext(untransformedSurface);
temp->SetColor(color);
temp->Paint();
}
nsRefPtr<gfxContext> temp = new gfxContext(untransformedSurface);
temp->SetColor(color);
temp->Paint();
}
#endif
const gfx3DMatrix& effectiveTransform = aLayer->GetEffectiveTransform();
nsRefPtr<gfxASurface> result =
Transform3D(untransformedSurface, aTarget, bounds,
effectiveTransform, offset, dontBlit);
nsRefPtr<gfxASurface> result =
Transform3D(untransformedSurface, aTarget, bounds,
effectiveTransform, offset, dontBlit);
blitComplete = !result;
if (result) {
aTarget->SetSource(result, offset);
}
}
if (result) {
aTarget->SetSource(result, offset);
FlushGroup(paintContext, needsClipToVisibleRegion);
}
// If we're doing our own double-buffering, we need to avoid drawing
// the results of an incomplete transaction to the destination surface ---
// that could cause flicker. Double-buffering is implemented using a
// temporary surface for one or more container layers, so we need to stop
// those temporary surfaces from being composited to aTarget.
// ApplyDoubleBuffering guarantees that this container layer can't
// intersect any other leaf layers, so if the transaction is not yet marked
// incomplete, the contents of this container layer are the final contents
// for the window.
if (!mTransactionIncomplete && !blitComplete) {
if (needsClipToVisibleRegion) {
gfxUtils::ClipToRegion(aTarget, aLayer->GetEffectiveVisibleRegion());
}
AutoSetOperator setOperator(aTarget, container->GetOperator());
PaintWithMask(aTarget, aLayer->GetEffectiveOpacity(),
HasShadowManager() ? nullptr : aLayer->GetMaskLayer());
}
}
if (pushedTargetOpaqueRect) {
if (aTarget->IsCairo()) {
currentSurface->SetOpaqueRect(gfxRect(0, 0, 0, 0));
} else {
dt->SetOpaqueRect(IntRect());
}
}
if (needsSaveRestore) {
aTarget->Restore();
} else {
aTarget->SetMatrix(savedMatrix);
}
}

View File

@ -28,6 +28,7 @@ class ShadowCanvasLayer;
class ShadowColorLayer;
class ReadbackProcessor;
class ImageFactory;
class PaintContext;
/**
* This is a cairo/Thebes-only, main-thread-only implementation of layers.
@ -159,6 +160,15 @@ protected:
};
TransactionPhase mPhase;
// This is the main body of the PaintLayer routine which will if it has
// children, recurse into PaintLayer() otherwise it will paint using the
// underlying Paint() method of the Layer. It will not do both.
void PaintSelfOrChildren(PaintContext& aPaintContext, gfxContext* aGroupTarget);
// Paint the group onto the underlying target. This is used by PaintLayer to
// flush the group to the underlying target.
void FlushGroup(PaintContext& aPaintContext, bool aNeedsClipToVisibleRegion);
// Paints aLayer to mTarget.
void PaintLayer(gfxContext* aTarget,
Layer* aLayer,

View File

@ -500,10 +500,10 @@ gfxWindowsPlatform::UpdateRenderMode()
DWRITE_FACTORY_TYPE_SHARED,
__uuidof(IDWriteFactory),
reinterpret_cast<IUnknown**>(&factory));
mDWriteFactory = factory;
factory->Release();
if (SUCCEEDED(hr)) {
if (SUCCEEDED(hr) && factory) {
mDWriteFactory = factory;
factory->Release();
hr = mDWriteFactory->CreateTextAnalyzer(
getter_AddRefs(mDWriteAnalyzer));
}

View File

@ -105,6 +105,12 @@ ifeq ($(OS_TARGET),Android)
CPPSRCS += SharedMemoryBasic_android.cpp
endif #}
ifeq ($(OS_ARCH),Linux)
CPPSRCS += ProcessUtils_linux.cpp
else
CPPSRCS += ProcessUtils_none.cpp
endif
include $(topsrcdir)/ipc/app/defs.mk
DEFINES += -DMOZ_CHILD_PROCESS_NAME=\"$(MOZ_CHILD_PROCESS_NAME)\"
DEFINES += -DMOZ_CHILD_PROCESS_BUNDLE=\"$(MOZ_CHILD_PROCESS_BUNDLE)\"

17
ipc/glue/ProcessUtils.h Normal file
View File

@ -0,0 +1,17 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_ipc_ProcessUtils_h
#define mozilla_ipc_ProcessUtils_h
namespace mozilla {
namespace ipc {
void SetThisProcessName(const char *aName);
} // namespace ipc
} // namespace mozilla
#endif // ifndef mozilla_ipc_ProcessUtils_h

View File

@ -0,0 +1,20 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "ProcessUtils.h"
#include "nsString.h"
#include <sys/prctl.h>
namespace mozilla {
namespace ipc {
void SetThisProcessName(const char *aName)
{
prctl(PR_SET_NAME, (unsigned long)aName, 0uL, 0uL, 0uL);
}
} // namespace ipc
} // namespace mozilla

View File

@ -0,0 +1,16 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "ProcessUtils.h"
namespace mozilla {
namespace ipc {
void SetThisProcessName(const char *aString)
{
(void)aString;
}
} // namespace ipc
} // namespace mozilla

View File

@ -380,13 +380,7 @@ ifndef HOST_PROGOBJS
HOST_PROGOBJS = $(HOST_OBJS)
endif
# MAKE_DIRS: List of directories to build while looping over directories.
# A Makefile that needs $(MDDEPDIR) created but doesn't set any of these
# variables we know to check can just set NEED_MDDEPDIR explicitly.
ifneq (,$(OBJS)$(XPIDLSRCS)$(SIMPLE_PROGRAMS)$(NEED_MDDEPDIR))
MAKE_DIRS += $(CURDIR)/$(MDDEPDIR)
GARBAGE_DIRS += $(CURDIR)/$(MDDEPDIR)
endif
GARBAGE_DIRS += $(wildcard $(CURDIR)/$(MDDEPDIR))
#
# Tags: emacs (etags), vi (ctags)
@ -952,7 +946,7 @@ $(HOST_CMMOBJS): host_%.$(OBJ_SUFFIX): %.mm
$(REPORT_BUILD)
$(ELOG) $(HOST_CXX) $(HOST_OUTOPTION)$@ -c $(HOST_CXXFLAGS) $(HOST_CMMFLAGS) $(INCLUDES) $(NSPR_CFLAGS) $(_VPATH_SRCS)
$(COBJS): %.$(OBJ_SUFFIX): %.c
$(COBJS): %.$(OBJ_SUFFIX): %.c $(call mkdir_deps,$(MDDEPDIR))
$(REPORT_BUILD)
@$(MAKE_DEPS_AUTO_CC)
$(ELOG) $(CC) $(OUTOPTION)$@ -c $(COMPILE_CFLAGS) $(_VPATH_SRCS)
@ -982,45 +976,45 @@ $(SOBJS): %.$(OBJ_SUFFIX): %.S
#
# Please keep the next two rules in sync.
#
$(CCOBJS): %.$(OBJ_SUFFIX): %.cc
$(CCOBJS): %.$(OBJ_SUFFIX): %.cc $(call mkdir_deps,$(MDDEPDIR))
$(REPORT_BUILD)
@$(MAKE_DEPS_AUTO_CXX)
$(ELOG) $(CCC) $(OUTOPTION)$@ -c $(COMPILE_CXXFLAGS) $(_VPATH_SRCS)
$(CPPOBJS): %.$(OBJ_SUFFIX): %.cpp
$(CPPOBJS): %.$(OBJ_SUFFIX): %.cpp $(call mkdir_deps,$(MDDEPDIR))
$(REPORT_BUILD)
@$(MAKE_DEPS_AUTO_CXX)
$(ELOG) $(CCC) $(OUTOPTION)$@ -c $(COMPILE_CXXFLAGS) $(_VPATH_SRCS)
$(CMMOBJS): $(OBJ_PREFIX)%.$(OBJ_SUFFIX): %.mm
$(CMMOBJS): $(OBJ_PREFIX)%.$(OBJ_SUFFIX): %.mm $(call mkdir_deps,$(MDDEPDIR))
$(REPORT_BUILD)
@$(MAKE_DEPS_AUTO_CXX)
$(ELOG) $(CCC) -o $@ -c $(COMPILE_CXXFLAGS) $(COMPILE_CMMFLAGS) $(_VPATH_SRCS)
$(CMOBJS): $(OBJ_PREFIX)%.$(OBJ_SUFFIX): %.m
$(CMOBJS): $(OBJ_PREFIX)%.$(OBJ_SUFFIX): %.m $(call mkdir_deps,$(MDDEPDIR))
$(REPORT_BUILD)
@$(MAKE_DEPS_AUTO_CC)
$(ELOG) $(CC) -o $@ -c $(COMPILE_CFLAGS) $(COMPILE_CMFLAGS) $(_VPATH_SRCS)
%.s: %.cpp
%.s: %.cpp $(call mkdir_deps,$(MDDEPDIR))
$(CCC) -S $(COMPILE_CXXFLAGS) $(_VPATH_SRCS)
%.s: %.cc
%.s: %.cc $(call mkdir_deps,$(MDDEPDIR))
$(CCC) -S $(COMPILE_CXXFLAGS) $(_VPATH_SRCS)
%.s: %.c
%.s: %.c $(call mkdir_deps,$(MDDEPDIR))
$(CC) -S $(COMPILE_CFLAGS) $(_VPATH_SRCS)
%.i: %.cpp
%.i: %.cpp $(call mkdir_deps,$(MDDEPDIR))
$(CCC) -C -E $(COMPILE_CXXFLAGS) $(_VPATH_SRCS) > $*.i
%.i: %.cc
%.i: %.cc $(call mkdir_deps,$(MDDEPDIR))
$(CCC) -C -E $(COMPILE_CXXFLAGS) $(_VPATH_SRCS) > $*.i
%.i: %.c
%.i: %.c $(call mkdir_deps,$(MDDEPDIR))
$(CC) -C -E $(COMPILE_CFLAGS) $(_VPATH_SRCS) > $*.i
%.i: %.mm
%.i: %.mm $(call mkdir_deps,$(MDDEPDIR))
$(CCC) -C -E $(COMPILE_CXXFLAGS) $(COMPILE_CMMFLAGS) $(_VPATH_SRCS) > $*.i
%.res: %.rc
@ -1356,6 +1350,7 @@ endif
# objdir/_tests/modules/. If TESTING_JS_MODULE_DIR is defined, that path
# wlll be appended to the output directory.
ifdef ENABLE_TESTS
ifdef TESTING_JS_MODULES
testmodulesdir = $(DEPTH)/_tests/modules/$(TESTING_JS_MODULE_DIR)
@ -1367,6 +1362,7 @@ TESTING_JS_MODULES_DEST := $(testmodulesdir)
INSTALL_TARGETS += TESTING_JS_MODULES
endif
endif
endif
################################################################################
@ -1482,9 +1478,6 @@ endif
# dependency directory in the object directory, where we really need
# it.
$(CURDIR)/$(MDDEPDIR):
$(MKDIR) -p $@
ifneq (,$(filter-out all chrome default export realchrome tools clean clobber clobber_all distclean realclean,$(MAKECMDGOALS)))
MDDEPEND_FILES := $(strip $(wildcard $(foreach file,$(OBJS) $(PROGOBJS) $(HOST_OBJS) $(HOST_PROGOBJS) $(TARGETS) $(XPIDLSRCS:.idl=.h) $(XPIDLSRCS:.idl=.xpt),$(MDDEPDIR)/$(notdir $(file)).pp) $(addprefix $(MDDEPDIR)/,$(EXTRA_MDDEPEND_FILES))))

View File

@ -114,7 +114,8 @@ frontend::CompileScript(JSContext *cx, HandleObject scopeChain, StackFrame *call
// Global/eval script bindings are always empty (all names are added to the
// scope dynamically via JSOP_DEFFUN/VAR).
if (!script->bindings.initWithTemporaryStorage(cx, 0, 0, NULL))
InternalHandle<Bindings*> bindings(script, &script->bindings);
if (!Bindings::initWithTemporaryStorage(cx, bindings, 0, 0, NULL))
return NULL;
// We can specialize a bit for the given scope chain if that scope chain is the global object.
@ -327,7 +328,8 @@ frontend::CompileFunctionBody(JSContext *cx, HandleFunction fun, CompileOptions
if (!script)
return false;
if (!funpc.generateFunctionBindings(cx, &script->bindings))
InternalHandle<Bindings*> bindings(script, &script->bindings);
if (!funpc.generateFunctionBindings(cx, bindings))
return false;
BytecodeEmitter funbce(/* parent = */ NULL, &parser, &funsc, script, /* callerFrame = */ NULL,

View File

@ -296,7 +296,7 @@ AppendPackedBindings(const ParseContext *pc, const DeclVector &vec, Binding *dst
}
bool
ParseContext::generateFunctionBindings(JSContext *cx, Bindings *bindings) const
ParseContext::generateFunctionBindings(JSContext *cx, InternalHandle<Bindings*> bindings) const
{
JS_ASSERT(sc->inFunction());
@ -310,8 +310,11 @@ ParseContext::generateFunctionBindings(JSContext *cx, Bindings *bindings) const
AppendPackedBindings(this, args_, packedBindings);
AppendPackedBindings(this, vars_, packedBindings + args_.length());
if (!bindings->initWithTemporaryStorage(cx, args_.length(), vars_.length(), packedBindings))
if (!Bindings::initWithTemporaryStorage(cx, bindings, args_.length(), vars_.length(),
packedBindings))
{
return false;
}
if (bindings->hasAnyAliasedBindings() || sc->funHasExtensibleScope())
sc->funbox()->fun()->flags |= JSFUN_HEAVYWEIGHT;
@ -1257,7 +1260,9 @@ LeaveFunction(ParseNode *fn, Parser *parser, PropertyName *funName = NULL,
}
}
if (!funpc->generateFunctionBindings(cx, &funbox->bindings))
InternalHandle<Bindings*> bindings =
InternalHandle<Bindings*>::fromMarkedLocation(&funbox->bindings);
if (!funpc->generateFunctionBindings(cx, bindings))
return false;
funpc->lexdeps.releaseMap(cx);

View File

@ -151,7 +151,7 @@ struct ParseContext /* tree context for semantic checks */
* - Sometimes a script's bindings are accessed at runtime to retrieve the
* contents of the lexical scope (e.g., from the debugger).
*/
bool generateFunctionBindings(JSContext *cx, Bindings *bindings) const;
bool generateFunctionBindings(JSContext *cx, InternalHandle<Bindings*> bindings) const;
public:
ParseNode *yieldNode; /* parse node for a yield expression that might

View File

@ -11,9 +11,11 @@
#ifdef __cplusplus
#include "mozilla/TypeTraits.h"
#include "mozilla/GuardObjects.h"
#include "js/TemplateLib.h"
#include "js/Utility.h"
#include "jspubtd.h"
namespace js {
namespace gc {
@ -244,6 +246,73 @@ typedef JSObject * RawObject;
typedef JSString * RawString;
typedef Value RawValue;
/*
* InternalHandle is a handle to an internal pointer into a gcthing. Use
* InternalHandle when you have a pointer to a direct field of a gcthing, or
* when you need a parameter type for something that *may* be a pointer to a
* direct field of a gcthing.
*/
class InternalHandleBase
{
protected:
static void * const zeroPointer;
};
template <typename T>
class InternalHandle { };
template <typename T>
class InternalHandle<T*> : public InternalHandleBase
{
void * const *holder;
size_t offset;
public:
/*
* Create an InternalHandle using a Handle to the gcthing containing the
* field in question, and a pointer to the field.
*/
template<typename H>
InternalHandle(const Handle<H> &handle, T *field)
: holder((void**)handle.address()), offset(uintptr_t(field) - uintptr_t(handle.get()))
{
}
/*
* Create an InternalHandle to a field within a Rooted<>.
*/
template<typename R>
InternalHandle(const Rooted<R> &root, T *field)
: holder((void**)root.address()), offset(uintptr_t(field) - uintptr_t(root.get()))
{
}
T *get() const { return reinterpret_cast<T*>(uintptr_t(*holder) + offset); }
const T& operator *() const { return *get(); }
T* operator ->() const { return get(); }
static InternalHandle<T*> fromMarkedLocation(T *fieldPtr) {
return InternalHandle(fieldPtr);
}
private:
/*
* Create an InternalHandle to something that is not a pointer to a
* gcthing, and so does not need to be rooted in the first place. Use these
* InternalHandles to pass pointers into functions that also need to accept
* regular InternalHandles to gcthing fields.
*
* Make this private to prevent accidental misuse; this is only for
* fromMarkedLocation().
*/
InternalHandle(T *field)
: holder(reinterpret_cast<void * const *>(&zeroPointer)),
offset(uintptr_t(field))
{
}
};
extern mozilla::ThreadLocal<JSRuntime *> TlsRuntime;
/*
@ -394,7 +463,7 @@ typedef Rooted<Value> RootedValue;
*/
class SkipRoot
{
#if defined(DEBUG) && defined(JSGC_ROOT_ANALYSIS)
#if defined(DEBUG) && defined(JS_GC_ZEAL) && defined(JSGC_ROOT_ANALYSIS) && !defined(JS_THREADSAFE)
SkipRoot **stack, *prev;
const uint8_t *start;
@ -446,38 +515,30 @@ class SkipRoot
JS_DECL_USE_GUARD_OBJECT_NOTIFIER
};
JS_FRIEND_API(void) EnterAssertNoGCScope();
JS_FRIEND_API(void) LeaveAssertNoGCScope();
JS_FRIEND_API(bool) InNoGCScope();
/*
* This typedef is to annotate parameters that we have manually verified do not
* need rooting, as opposed to parameters that have not yet been considered.
* The scoped guard object AutoAssertNoGC forces the GC to assert if a GC is
* attempted while the guard object is live. If you have a GC-unsafe operation
* to perform, use this guard object to protect your opertion.
*/
typedef JSObject *RawObject;
class AutoAssertNoGC
{
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
#ifdef DEBUG
JS_FRIEND_API(bool) IsRootingUnnecessaryForContext(JSContext *cx);
JS_FRIEND_API(void) SetRootingUnnecessaryForContext(JSContext *cx, bool value);
JS_FRIEND_API(bool) RelaxRootChecksForContext(JSContext *cx);
#endif
class AssertRootingUnnecessary {
JS_DECL_USE_GUARD_OBJECT_NOTIFIER
#ifdef DEBUG
JSContext *cx;
bool prev;
#endif
public:
AssertRootingUnnecessary(JSContext *cx JS_GUARD_OBJECT_NOTIFIER_PARAM)
{
JS_GUARD_OBJECT_NOTIFIER_INIT;
AutoAssertNoGC(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM) {
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
#ifdef DEBUG
this->cx = cx;
prev = IsRootingUnnecessaryForContext(cx);
SetRootingUnnecessaryForContext(cx, true);
EnterAssertNoGCScope();
#endif
}
~AssertRootingUnnecessary() {
~AutoAssertNoGC() {
#ifdef DEBUG
SetRootingUnnecessaryForContext(cx, prev);
LeaveAssertNoGCScope();
#endif
}
};
@ -487,6 +548,8 @@ extern void
CheckStackRoots(JSContext *cx);
#endif
JS_FRIEND_API(bool) NeedRelaxedRootChecks();
/*
* Hook for dynamic root analysis. Checks the native stack and poisons
* references to GC things which have not been rooted.
@ -494,9 +557,9 @@ CheckStackRoots(JSContext *cx);
inline void MaybeCheckStackRoots(JSContext *cx, bool relax = true)
{
#ifdef DEBUG
JS_ASSERT(!IsRootingUnnecessaryForContext(cx));
JS_ASSERT(!InNoGCScope());
# if defined(JS_GC_ZEAL) && defined(JSGC_ROOT_ANALYSIS) && !defined(JS_THREADSAFE)
if (relax && RelaxRootChecksForContext(cx))
if (relax && NeedRelaxedRootChecks())
return;
CheckStackRoots(cx);
# endif

View File

@ -745,8 +745,41 @@ static JSBool js_NewRuntimeWasCalled = JS_FALSE;
*/
namespace JS {
mozilla::ThreadLocal<JSRuntime *> TlsRuntime;
#ifdef DEBUG
JS_FRIEND_API(void)
EnterAssertNoGCScope()
{
++TlsRuntime.get()->gcAssertNoGCDepth;
}
JS_FRIEND_API(void)
LeaveAssertNoGCScope()
{
--TlsRuntime.get()->gcAssertNoGCDepth;
JS_ASSERT(TlsRuntime.get()->gcAssertNoGCDepth >= 0);
}
JS_FRIEND_API(bool)
InNoGCScope()
{
return TlsRuntime.get()->gcAssertNoGCDepth > 0;
}
JS_FRIEND_API(bool)
NeedRelaxedRootChecks()
{
return TlsRuntime.get()->gcRelaxRootChecks;
}
#else
JS_FRIEND_API(void) EnterAssertNoGCScope() {}
JS_FRIEND_API(void) LeaveAssertNoGCScope() {}
JS_FRIEND_API(bool) InNoGCScope() { return false; }
JS_FRIEND_API(bool) NeedRelaxedRootChecks() { return false; }
#endif
} /* namespace JS */
static const JSSecurityCallbacks NullSecurityCallbacks = { };
JSRuntime::JSRuntime()
@ -822,6 +855,10 @@ JSRuntime::JSRuntime()
gcSliceBudget(SliceBudget::Unlimited),
gcIncrementalEnabled(true),
gcExactScanningEnabled(true),
#ifdef DEBUG
gcRelaxRootChecks(false),
gcAssertNoGCDepth(0),
#endif
gcPoke(false),
heapState(Idle),
#ifdef JS_GC_ZEAL
@ -3480,7 +3517,7 @@ JS_NewObject(JSContext *cx, JSClass *jsclasp, JSObject *protoArg, JSObject *pare
JS_ASSERT(!(clasp->flags & JSCLASS_IS_GLOBAL));
JSObject *obj = NewObjectWithClassProto(cx, clasp, proto, parent);
AssertRootingUnnecessary safe(cx);
AutoAssertNoGC nogc;
if (obj) {
if (clasp->ext.equality)
MarkTypeObjectFlags(cx, obj, OBJECT_FLAG_SPECIAL_EQUALITY);
@ -3508,7 +3545,7 @@ JS_NewObjectWithGivenProto(JSContext *cx, JSClass *jsclasp, JSObject *protoArg,
JS_ASSERT(!(clasp->flags & JSCLASS_IS_GLOBAL));
JSObject *obj = NewObjectWithGivenProto(cx, clasp, proto, parent);
AssertRootingUnnecessary safe(cx);
AutoAssertNoGC nogc;
if (obj)
MarkTypeObjectUnknownProperties(cx, obj->type());
return obj;
@ -4708,7 +4745,7 @@ JS_PUBLIC_API(JSBool)
JS_NextProperty(JSContext *cx, JSObject *iterobjArg, jsid *idp)
{
RootedObject iterobj(cx, iterobjArg);
AssertRootingUnnecessary safe(cx);
AutoAssertNoGC nogc;
int32_t i;
Shape *shape;
JSIdArray *ida;

View File

@ -1061,7 +1061,6 @@ class JS_PUBLIC_API(AutoGCRooter) {
SHAPERANGE = -20, /* js::Shape::Range::AutoRooter */
STACKSHAPE = -21, /* js::StackShape::AutoRooter */
STACKBASESHAPE=-22,/* js::StackBaseShape::AutoRooter */
BINDINGS = -23, /* js::Bindings::AutoRooter */
GETTERSETTER =-24, /* js::AutoRooterGetterSetter */
REGEXPSTATICS=-25, /* js::RegExpStatics::AutoRooter */
NAMEVECTOR = -26, /* js::AutoNameVector */

View File

@ -1200,9 +1200,6 @@ JSContext::JSContext(JSRuntime *rt)
localeCallbacks(NULL),
resolvingList(NULL),
generatingError(false),
#ifdef DEBUG
rootingUnnecessary(false),
#endif
compartment(NULL),
enterCompartmentDepth_(0),
savedFrameChains_(),
@ -1238,7 +1235,7 @@ JSContext::JSContext(JSRuntime *rt)
PodZero(&link);
#ifdef JSGC_ROOT_ANALYSIS
PodArrayZero(thingGCRooters);
#ifdef DEBUG
#if defined(JS_GC_ZEAL) && defined(DEBUG) && !defined(JS_THREADSAFE)
skipGCRooters = NULL;
#endif
#endif
@ -1264,30 +1261,6 @@ JSContext::~JSContext()
JS_ASSERT(!resolvingList);
}
#ifdef DEBUG
namespace JS {
JS_FRIEND_API(void)
SetRootingUnnecessaryForContext(JSContext *cx, bool value)
{
cx->rootingUnnecessary = value;
}
JS_FRIEND_API(bool)
IsRootingUnnecessaryForContext(JSContext *cx)
{
return cx->rootingUnnecessary;
}
JS_FRIEND_API(bool)
RelaxRootChecksForContext(JSContext *cx)
{
return cx->runtime->relaxRootChecks;
}
} /* namespace JS */
#endif
/*
* Since this function is only called in the context of a pending exception,
* the caller must subsequently take an error path. If wrapping fails, it will

View File

@ -655,14 +655,13 @@ struct JSRuntime : js::RuntimeFriendFields
SavedGCRoot(void *thing, JSGCTraceKind kind) : thing(thing), kind(kind) {}
};
js::Vector<SavedGCRoot, 0, js::SystemAllocPolicy> gcSavedRoots;
bool gcRelaxRootChecks;
int gcAssertNoGCDepth;
#endif
bool gcPoke;
#ifdef DEBUG
bool relaxRootChecks;
#endif
enum HeapState {
Idle, // doing nothing with the GC heap
Tracing, // tracing the GC heap without collecting, e.g. IterateCompartments()
@ -1242,10 +1241,6 @@ struct JSContext : js::ContextFriendFields
/* True if generating an error, to prevent runaway recursion. */
bool generatingError;
#ifdef DEBUG
bool rootingUnnecessary;
#endif
/* The current compartment. */
JSCompartment *compartment;

View File

@ -112,6 +112,8 @@ using namespace mozilla;
using namespace js;
using namespace js::gc;
void * const JS::InternalHandleBase::zeroPointer = NULL;
namespace js {
namespace gc {
@ -2448,12 +2450,6 @@ AutoGCRooter::trace(JSTracer *trc)
return;
}
case BINDINGS: {
Bindings::AutoRooter *rooter = static_cast<Bindings::AutoRooter *>(this);
rooter->trace(trc);
return;
}
case GETTERSETTER: {
AutoRooterGetterSetter::Inner *rooter = static_cast<AutoRooterGetterSetter::Inner *>(this);
if ((rooter->attrs & JSPROP_GETTER) && *rooter->pgetter)
@ -2513,12 +2509,6 @@ Shape::Range::AutoRooter::trace(JSTracer *trc)
MarkShapeRoot(trc, const_cast<Shape**>(&r->cursor), "Shape::Range::AutoRooter");
}
void
Bindings::AutoRooter::trace(JSTracer *trc)
{
bindings->trace(trc);
}
void
RegExpStatics::AutoRooter::trace(JSTracer *trc)
{
@ -4968,16 +4958,16 @@ JS::CheckStackRoots(JSContext *cx)
if (rt->gcZeal_ == ZealStackRootingSafeValue && !rt->gcExactScanningEnabled)
return;
// If this assertion fails, it means that an AssertRootingUnnecessary was
// placed around code that could trigger GC, and is therefore wrong. The
// AssertRootingUnnecessary should be removed and the code it was guarding
// should be modified to properly root any gcthings, and very possibly any
// code calling that function should also be modified if it was improperly
// If this assertion fails, it means that an AutoAssertNoGC was placed
// around code that could trigger GC, and is therefore wrong. The
// AutoAssertNoGC should be removed and the code it was guarding should be
// modified to properly root any gcthings, and very possibly any code
// calling that function should also be modified if it was improperly
// assuming that GC could not happen at all within the called function.
// (The latter may not apply if the AssertRootingUnnecessary only protected
// a portion of a function, so the callers were already assuming that GC
// could happen.)
JS_ASSERT(!cx->rootingUnnecessary);
// (The latter may not apply if the AutoAssertNoGC only protected a portion
// of a function, so the callers were already assuming that GC could
// happen.)
JS_ASSERT(!InNoGCScope());
// GCs can't happen when analysis/inference/compilation are active.
if (cx->compartment->activeAnalysis)

View File

@ -5644,7 +5644,7 @@ JSObject::makeLazyType(JSContext *cx)
RootedObject self(cx, this);
JSProtoKey key = JSCLASS_CACHED_PROTO_KEY(getClass());
TypeObject *type = cx->compartment->types.newTypeObject(cx, NULL, key, getProto());
AssertRootingUnnecessary safe(cx);
AutoAssertNoGC nogc;
if (!type) {
if (cx->typeInferenceEnabled())
cx->compartment->types.setPendingNukeTypes(cx);

View File

@ -31,7 +31,7 @@ JS_ALWAYS_INLINE void
js::PropertyCache::test(JSContext *cx, jsbytecode *pc, JSObject *&obj,
JSObject *&pobj, PropertyCacheEntry *&entry, PropertyName *&name)
{
AssertRootingUnnecessary assert(cx);
AutoAssertNoGC nogc;
JS_ASSERT(this == &cx->propertyCache());

View File

@ -61,23 +61,25 @@ Bindings::argumentsVarIndex(JSContext *cx) const
}
bool
Bindings::initWithTemporaryStorage(JSContext *cx, unsigned numArgs, unsigned numVars, Binding *bindingArray)
Bindings::initWithTemporaryStorage(JSContext *cx, InternalHandle<Bindings*> self,
unsigned numArgs, unsigned numVars,
Binding *bindingArray)
{
JS_ASSERT(!callObjShape_);
JS_ASSERT(bindingArrayAndFlag_ == TEMPORARY_STORAGE_BIT);
JS_ASSERT(!self->callObjShape_);
JS_ASSERT(self->bindingArrayAndFlag_ == TEMPORARY_STORAGE_BIT);
if (numArgs > UINT16_MAX || numVars > UINT16_MAX) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
numArgs_ > numVars_ ?
self->numArgs_ > self->numVars_ ?
JSMSG_TOO_MANY_FUN_ARGS :
JSMSG_TOO_MANY_LOCALS);
return false;
}
JS_ASSERT(!(uintptr_t(bindingArray) & TEMPORARY_STORAGE_BIT));
bindingArrayAndFlag_ = uintptr_t(bindingArray) | TEMPORARY_STORAGE_BIT;
numArgs_ = numArgs;
numVars_ = numVars;
self->bindingArrayAndFlag_ = uintptr_t(bindingArray) | TEMPORARY_STORAGE_BIT;
self->numArgs_ = numArgs;
self->numVars_ = numVars;
/*
* Get the initial shape to use when creating CallObjects for this script.
@ -91,8 +93,9 @@ Bindings::initWithTemporaryStorage(JSContext *cx, unsigned numArgs, unsigned num
JS_STATIC_ASSERT(CallObject::RESERVED_SLOTS == 2);
gc::AllocKind allocKind = gc::FINALIZE_OBJECT2_BACKGROUND;
JS_ASSERT(gc::GetGCKindSlots(allocKind) == CallObject::RESERVED_SLOTS);
callObjShape_ = EmptyShape::getInitialShape(cx, &CallClass, NULL, cx->global(),
allocKind, BaseShape::VAROBJ | BaseShape::DELEGATE);
self->callObjShape_ =
EmptyShape::getInitialShape(cx, &CallClass, NULL, cx->global(),
allocKind, BaseShape::VAROBJ | BaseShape::DELEGATE);
#ifdef DEBUG
HashSet<PropertyName *> added(cx);
@ -100,9 +103,9 @@ Bindings::initWithTemporaryStorage(JSContext *cx, unsigned numArgs, unsigned num
return false;
#endif
BindingIter bi(*this);
BindingIter bi(*self);
unsigned slot = CallObject::RESERVED_SLOTS;
for (unsigned i = 0, n = count(); i < n; i++, bi++) {
for (unsigned i = 0, n = self->count(); i < n; i++, bi++) {
if (!bi->aliased())
continue;
@ -124,8 +127,8 @@ Bindings::initWithTemporaryStorage(JSContext *cx, unsigned numArgs, unsigned num
unsigned frameIndex = bi.frameIndex();
StackShape child(nbase, id, slot++, 0, attrs, Shape::HAS_SHORTID, frameIndex);
callObjShape_ = callObjShape_->getChildBinding(cx, child);
if (!callObjShape_)
self->callObjShape_ = self->callObjShape_->getChildBinding(cx, child);
if (!self->callObjShape_)
return false;
}
JS_ASSERT(!bi);
@ -145,7 +148,9 @@ Bindings::switchToScriptStorage(Binding *newBindingArray)
}
bool
Bindings::clone(JSContext *cx, uint8_t *dstScriptData, HandleScript srcScript)
Bindings::clone(JSContext *cx, InternalHandle<Bindings*> self,
uint8_t *dstScriptData,
HandleScript srcScript)
{
/* The clone has the same bindingArray_ offset as 'src'. */
Bindings &src = srcScript->bindings;
@ -158,9 +163,9 @@ Bindings::clone(JSContext *cx, uint8_t *dstScriptData, HandleScript srcScript)
* Since atoms are shareable throughout the runtime, we can simply copy
* the source's bindingArray directly.
*/
if (!initWithTemporaryStorage(cx, src.numArgs(), src.numVars(), src.bindingArray()))
if (!initWithTemporaryStorage(cx, self, src.numArgs(), src.numVars(), src.bindingArray()))
return false;
switchToScriptStorage(dstPackedBindings);
self->switchToScriptStorage(dstPackedBindings);
return true;
}
@ -211,7 +216,8 @@ XDRScriptBindings(XDRState<mode> *xdr, LifoAllocScope &las, unsigned numArgs, un
bindingArray[i] = Binding(name, kind, aliased);
}
if (!script->bindings.initWithTemporaryStorage(cx, numArgs, numVars, bindingArray))
InternalHandle<Bindings*> bindings(script, &script->bindings);
if (!Bindings::initWithTemporaryStorage(cx, bindings, numArgs, numVars, bindingArray))
return false;
}
@ -2078,8 +2084,9 @@ js::CloneScript(JSContext *cx, HandleObject enclosingScope, HandleFunction fun,
/* Bindings */
Bindings bindings;
Bindings::AutoRooter bindingRooter(cx, &bindings);
if (!bindings.clone(cx, data, src))
InternalHandle<Bindings*> bindingsHandle =
InternalHandle<Bindings*>::fromMarkedLocation(&bindings);
if (!Bindings::clone(cx, bindingsHandle, data, src))
return NULL;
/* Objects */
@ -2144,6 +2151,7 @@ js::CloneScript(JSContext *cx, HandleObject enclosingScope, HandleFunction fun,
js_free(data);
return NULL;
}
AutoAssertNoGC nogc;
dst->bindings = bindings;

View File

@ -168,14 +168,17 @@ class Bindings
* storage is release, switchToScriptStorage must be called, providing a
* pointer into the Binding array stored in script->data.
*/
bool initWithTemporaryStorage(JSContext *cx, unsigned numArgs, unsigned numVars, Binding *bindingArray);
static bool initWithTemporaryStorage(JSContext *cx, InternalHandle<Bindings*> self,
unsigned numArgs, unsigned numVars,
Binding *bindingArray);
uint8_t *switchToScriptStorage(Binding *newStorage);
/*
* Clone srcScript's bindings (as part of js::CloneScript). dstScriptData
* is the pointer to what will eventually be dstScript->data.
*/
bool clone(JSContext *cx, uint8_t *dstScriptData, HandleScript srcScript);
static bool clone(JSContext *cx, InternalHandle<Bindings*> self, uint8_t *dstScriptData, HandleScript srcScript);
unsigned numArgs() const { return numArgs_; }
unsigned numVars() const { return numVars_; }
@ -194,26 +197,6 @@ class Bindings
bool hasAnyAliasedBindings() const { return !callObjShape_->isEmptyShape(); }
void trace(JSTracer *trc);
class AutoRooter;
};
class Bindings::AutoRooter : private AutoGCRooter
{
public:
explicit AutoRooter(JSContext *cx, Bindings *bindings_
JS_GUARD_OBJECT_NOTIFIER_PARAM)
: AutoGCRooter(cx, BINDINGS), bindings(bindings_), skip(cx, bindings_)
{
JS_GUARD_OBJECT_NOTIFIER_INIT;
}
friend void AutoGCRooter::trace(JSTracer *trc);
void trace(JSTracer *trc);
private:
Bindings *bindings;
SkipRoot skip;
JS_DECL_USE_GUARD_OBJECT_NOTIFIER
};
class ScriptCounts

View File

@ -3543,7 +3543,7 @@ RelaxRootChecks(JSContext *cx, unsigned argc, jsval *vp)
}
#ifdef DEBUG
cx->runtime->relaxRootChecks = true;
cx->runtime->gcRelaxRootChecks = true;
#endif
return true;

View File

@ -7,7 +7,9 @@
#include "XPCWrapper.h"
#include "AccessCheck.h"
#include "WrapperFactory.h"
#include "AccessCheck.h"
using namespace xpc;
namespace XPCNativeWrapper {
static inline
@ -37,8 +39,7 @@ UnwrapNW(JSContext *cx, unsigned argc, jsval *vp)
return true;
}
if (xpc::WrapperFactory::IsXrayWrapper(obj) &&
!xpc::WrapperFactory::IsPartiallyTransparent(obj)) {
if (WrapperFactory::IsXrayWrapper(obj) && AccessCheck::isChrome(obj)) {
return JS_GetProperty(cx, obj, "wrappedJSObject", vp);
}

View File

@ -10,7 +10,6 @@ dictionaries = [
[ 'WheelEventInit', 'nsIDOMWheelEvent.idl' ],
[ 'IDBObjectStoreParameters', 'nsIIDBDatabase.idl' ],
[ 'IDBIndexParameters', 'nsIIDBObjectStore.idl' ],
[ 'BlobPropertyBag', 'nsIDOMFile.idl' ],
[ 'MutationObserverInit', 'nsIDOMMutationObserver.idl' ],
[ 'WifiConnectionInfoEventInit', 'nsIWifiEventInits.idl' ],
[ 'WifiStatusChangeEventInit', 'nsIWifiEventInits.idl' ],

View File

@ -412,6 +412,7 @@ def write_cpp(iface, fd):
fd.write("nsresult\n%s::Init(JSContext* aCx, const jsval* aVal)\n" % iface.name)
fd.write("{\n"
" MOZ_ASSERT(NS_IsMainThread());\n"
" if (!aCx || !aVal) {\n"
" return NS_OK;\n"
" }\n"
@ -419,11 +420,8 @@ def write_cpp(iface, fd):
" return aVal->isNullOrUndefined() ? NS_OK : NS_ERROR_TYPE_ERR;\n"
" }\n\n"
" JSObject* obj = &aVal->toObject();\n"
" Maybe<nsCxPusher> pusher;\n"
" if (NS_IsMainThread()) {\n"
" pusher.construct();\n"
" NS_ENSURE_STATE(pusher.ref().Push(aCx, false));\n"
" }\n"
" nsCxPusher pusher;\n"
" NS_ENSURE_STATE(pusher.Push(aCx, false));\n"
" JSAutoRequest ar(aCx);\n"
" JSAutoCompartment ac(aCx, obj);\n")

View File

@ -429,9 +429,6 @@ members = [
# can't be quickstubbed
'-nsIXMLHttpRequest.upload',
# WebSocket
'nsIWebSocket.*',
# webgl
'nsIDOMWebGLRenderingContext.*',
# getContextAttributes is directly manipulating its return value

View File

@ -4380,11 +4380,8 @@ GetCompartmentPrivate(JSObject *object)
return GetCompartmentPrivate(compartment);
}
inline bool IsUniversalXPConnectEnabled(JSContext *cx)
inline bool IsUniversalXPConnectEnabled(JSCompartment *compartment)
{
JSCompartment *compartment = js::GetContextCompartment(cx);
if (!compartment)
return false;
CompartmentPrivate *priv =
static_cast<CompartmentPrivate*>(JS_GetCompartmentPrivate(compartment));
if (!priv)
@ -4392,16 +4389,29 @@ inline bool IsUniversalXPConnectEnabled(JSContext *cx)
return priv->universalXPConnectEnabled;
}
inline void EnableUniversalXPConnect(JSContext *cx)
inline bool IsUniversalXPConnectEnabled(JSContext *cx)
{
JSCompartment *compartment = js::GetContextCompartment(cx);
if (!compartment)
return;
return false;
return IsUniversalXPConnectEnabled(compartment);
}
inline bool EnableUniversalXPConnect(JSContext *cx)
{
JSCompartment *compartment = js::GetContextCompartment(cx);
if (!compartment)
return true;
CompartmentPrivate *priv =
static_cast<CompartmentPrivate*>(JS_GetCompartmentPrivate(compartment));
if (!priv)
return;
return true;
priv->universalXPConnectEnabled = true;
// Recompute all the cross-compartment wrappers leaving the newly-privileged
// compartment.
return js::RecomputeWrappers(cx, js::SingleCompartment(compartment),
js::AllCompartments());
}
}

View File

@ -52,6 +52,16 @@ AccessCheck::subsumes(JSCompartment *a, JSCompartment *b)
return subsumes;
}
// Does the compartment of the wrapper subsumes the compartment of the wrappee?
bool
AccessCheck::wrapperSubsumes(JSObject *wrapper)
{
MOZ_ASSERT(js::IsWrapper(wrapper));
JSObject *wrapped = js::UnwrapObject(wrapper);
return AccessCheck::subsumes(js::GetObjectCompartment(wrapper),
js::GetObjectCompartment(wrapped));
}
bool
AccessCheck::isLocationObjectSameOrigin(JSContext *cx, JSObject *wrapper)
{
@ -91,6 +101,12 @@ AccessCheck::isChrome(JSCompartment *compartment)
return NS_SUCCEEDED(ssm->IsSystemPrincipal(principal, &privileged)) && privileged;
}
bool
AccessCheck::isChrome(JSObject *obj)
{
return isChrome(js::GetObjectCompartment(obj));
}
bool
AccessCheck::callerIsChrome()
{
@ -205,7 +221,7 @@ AccessCheck::isCrossOriginAccessPermitted(JSContext *cx, JSObject *wrapper, jsid
// PUNCTURE Is always denied for cross-origin access.
if (act == Wrapper::PUNCTURE) {
return nsContentUtils::CallerHasUniversalXPConnect();
return false;
}
const char *name;
@ -270,7 +286,7 @@ AccessCheck::isSystemOnlyAccessPermitted(JSContext *cx)
return true;
}
return NS_SUCCEEDED(ssm->IsCapabilityEnabled("UniversalXPConnect", &privileged)) && privileged;
return false;
}
bool
@ -295,18 +311,7 @@ AccessCheck::isScriptAccessOnly(JSContext *cx, JSObject *wrapper)
if (flags & WrapperFactory::SCRIPT_ACCESS_ONLY_FLAG) {
if (flags & WrapperFactory::SOW_FLAG)
return !isSystemOnlyAccessPermitted(cx);
if (flags & WrapperFactory::PARTIALLY_TRANSPARENT)
return !XrayUtils::IsTransparent(cx, wrapper);
nsIScriptSecurityManager *ssm = XPCWrapper::GetSecurityManager();
if (!ssm)
return true;
// Bypass script-only status if UniversalXPConnect is enabled.
bool privileged;
return !NS_SUCCEEDED(ssm->IsCapabilityEnabled("UniversalXPConnect", &privileged)) ||
!privileged;
return true;
}
// In addition, chrome objects can explicitly opt-in by setting .scriptOnly to true.
@ -356,33 +361,6 @@ Deny(JSContext *cx, jsid id, Wrapper::Action act)
return false;
}
bool
PermitIfUniversalXPConnect(JSContext *cx, jsid id, Wrapper::Action act,
ExposedPropertiesOnly::Permission &perm)
{
// If UniversalXPConnect is enabled, allow access even if __exposedProps__ doesn't
// exists.
nsIScriptSecurityManager *ssm = XPCWrapper::GetSecurityManager();
if (!ssm) {
return false;
}
// Double-check that the subject principal according to CAPS is a content
// principal rather than the system principal. If it isn't, this check is
// meaningless.
NS_ASSERTION(!AccessCheck::callerIsChrome(), "About to do a meaningless security check!");
bool privileged;
if (NS_SUCCEEDED(ssm->IsCapabilityEnabled("UniversalXPConnect", &privileged)) &&
privileged) {
perm = ExposedPropertiesOnly::PermitPropertyAccess;
return true; // Allow
}
// Deny
return Deny(cx, id, act);
}
static bool
IsInSandbox(JSContext *cx, JSObject *obj)
{
@ -404,12 +382,12 @@ ExposedPropertiesOnly::check(JSContext *cx, JSObject *wrapper, jsid id, Wrapper:
perm = DenyAccess;
if (act == Wrapper::PUNCTURE)
return PermitIfUniversalXPConnect(cx, id, act, perm); // Deny
return Deny(cx, id, act);
jsid exposedPropsId = GetRTIdByIndex(cx, XPCJSRuntime::IDX_EXPOSEDPROPS);
// We need to enter the wrappee's compartment to look at __exposedProps__,
// but we need to be in the wrapper's compartment to check UniversalXPConnect.
// but we want to be in the wrapper's compartment if we call Deny().
//
// Unfortunately, |cx| can be in either compartment when we call ::check. :-(
JSAutoCompartment ac(cx, wrappedObject);
@ -451,7 +429,7 @@ ExposedPropertiesOnly::check(JSContext *cx, JSObject *wrapper, jsid id, Wrapper:
perm = PermitPropertyAccess;
return true;
}
return PermitIfUniversalXPConnect(cx, id, act, perm); // Deny
return Deny(cx, id, act);
}
if (id == JSID_VOID) {
@ -466,7 +444,7 @@ ExposedPropertiesOnly::check(JSContext *cx, JSObject *wrapper, jsid id, Wrapper:
if (exposedProps.isNullOrUndefined()) {
JSAutoCompartment wrapperAC(cx, wrapper);
return PermitIfUniversalXPConnect(cx, id, act, perm); // Deny
return Deny(cx, id, act);
}
if (!exposedProps.isObject()) {
@ -485,7 +463,7 @@ ExposedPropertiesOnly::check(JSContext *cx, JSObject *wrapper, jsid id, Wrapper:
}
if (desc.obj == NULL || !(desc.attrs & JSPROP_ENUMERATE)) {
JSAutoCompartment wrapperAC(cx, wrapper);
return PermitIfUniversalXPConnect(cx, id, act, perm); // Deny
return Deny(cx, id, act);
}
if (!JSVAL_IS_STRING(desc.value)) {
@ -531,7 +509,7 @@ ExposedPropertiesOnly::check(JSContext *cx, JSObject *wrapper, jsid id, Wrapper:
if ((act == Wrapper::SET && !(access & WRITE)) ||
(act != Wrapper::SET && !(access & READ))) {
JSAutoCompartment wrapperAC(cx, wrapper);
return PermitIfUniversalXPConnect(cx, id, act, perm); // Deny
return Deny(cx, id, act);
}
perm = PermitPropertyAccess;
@ -558,7 +536,15 @@ ComponentsObjectPolicy::check(JSContext *cx, JSObject *wrapper, jsid id, Wrapper
}
}
return PermitIfUniversalXPConnect(cx, id, act, perm); // Deny
// We don't have any way to recompute same-compartment Components wrappers,
// so we need this dynamic check. This can go away when we expose Components
// as SpecialPowers.wrap(Components) during automation.
if (xpc::IsUniversalXPConnectEnabled(cx)) {
perm = PermitPropertyAccess;
return true;
}
return Deny(cx, id, act);
}
}

View File

@ -19,7 +19,9 @@ namespace xpc {
class AccessCheck {
public:
static bool subsumes(JSCompartment *a, JSCompartment *b);
static bool wrapperSubsumes(JSObject *wrapper);
static bool isChrome(JSCompartment *compartment);
static bool isChrome(JSObject *obj);
static bool callerIsChrome();
static nsIPrincipal *getPrincipal(JSCompartment *compartment);
static bool isCrossOriginAccessPermitted(JSContext *cx, JSObject *obj, jsid id,

View File

@ -125,14 +125,10 @@ template<> SOW SOW::singleton(WrapperFactory::SCRIPT_ACCESS_ONLY_FLAG |
WrapperFactory::SOW_FLAG);
template<> SCSOW SCSOW::singleton(WrapperFactory::SCRIPT_ACCESS_ONLY_FLAG |
WrapperFactory::SOW_FLAG);
template<> XOW XOW::singleton(WrapperFactory::SCRIPT_ACCESS_ONLY_FLAG |
WrapperFactory::PARTIALLY_TRANSPARENT);
template<> PXOW PXOW::singleton(WrapperFactory::SCRIPT_ACCESS_ONLY_FLAG |
WrapperFactory::PARTIALLY_TRANSPARENT);
template<> DXOW DXOW::singleton(WrapperFactory::SCRIPT_ACCESS_ONLY_FLAG |
WrapperFactory::PARTIALLY_TRANSPARENT);
template<> NNXOW NNXOW::singleton(WrapperFactory::SCRIPT_ACCESS_ONLY_FLAG |
WrapperFactory::PARTIALLY_TRANSPARENT);
template<> XOW XOW::singleton(WrapperFactory::SCRIPT_ACCESS_ONLY_FLAG);
template<> PXOW PXOW::singleton(WrapperFactory::SCRIPT_ACCESS_ONLY_FLAG);
template<> DXOW DXOW::singleton(WrapperFactory::SCRIPT_ACCESS_ONLY_FLAG);
template<> NNXOW NNXOW::singleton(WrapperFactory::SCRIPT_ACCESS_ONLY_FLAG);
template<> LW LW::singleton(WrapperFactory::SHADOWING_FORBIDDEN);
template<> XLW XLW::singleton(WrapperFactory::SHADOWING_FORBIDDEN);

View File

@ -349,6 +349,8 @@ WrapperFactory::Rewrap(JSContext *cx, JSObject *obj, JSObject *wrappedProto, JSO
}
}
}
} else if (xpc::IsUniversalXPConnectEnabled(target)) {
wrapper = &CrossCompartmentWrapper::singleton;
} else if (AccessCheck::isChrome(origin)) {
JSFunction *fun = JS_GetObjectFunction(obj);
if (fun) {

Some files were not shown because too many files have changed in this diff Show More