mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-26 06:11:37 +00:00
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:
commit
76ab271ead
@ -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);
|
||||
|
@ -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 {
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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 */
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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[] = {
|
||||
|
@ -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
|
||||
|
||||
|
@ -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))))
|
||||
|
||||
|
44
configure.in
44
configure.in
@ -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 ========================================================
|
||||
|
@ -83,7 +83,6 @@ XPIDLSRCS = \
|
||||
nsIXMLHttpRequest.idl \
|
||||
nsIContentSecurityPolicy.idl \
|
||||
nsIMessageManager.idl \
|
||||
nsIWebSocket.idl \
|
||||
nsIEventSource.idl \
|
||||
$(NULL)
|
||||
|
||||
|
@ -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";
|
||||
};
|
||||
|
@ -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);
|
||||
};
|
@ -122,7 +122,7 @@ CPPSRCS = \
|
||||
nsTraversal.cpp \
|
||||
nsTreeSanitizer.cpp \
|
||||
nsTreeWalker.cpp \
|
||||
nsWebSocket.cpp \
|
||||
WebSocket.cpp \
|
||||
nsXHTMLContentSerializer.cpp \
|
||||
nsXMLContentSerializer.cpp \
|
||||
nsXMLHttpRequest.cpp \
|
||||
|
File diff suppressed because it is too large
Load Diff
302
content/base/src/WebSocket.h
Normal file
302
content/base/src/WebSocket.h
Normal 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
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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)) {
|
||||
|
@ -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
|
@ -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));
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
/**
|
||||
|
@ -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)");
|
||||
|
@ -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 {
|
||||
|
@ -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)
|
||||
|
@ -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"/>
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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()) {
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -236,6 +236,12 @@ DOMInterfaces = {
|
||||
'headerFile': 'mozilla/dom/workers/bindings/XMLHttpRequestUpload.h'
|
||||
}],
|
||||
|
||||
'WebSocket': [
|
||||
{
|
||||
'headerFile': 'WebSocket.h',
|
||||
'implicitJSContext': [ 'constructor' ]
|
||||
}],
|
||||
|
||||
####################################
|
||||
# Test Interfaces of various sorts #
|
||||
####################################
|
||||
|
@ -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)
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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).
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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();
|
||||
|
@ -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]
|
||||
|
77
dom/network/tests/marionette/test_mobile_operator_names.js
Normal file
77
dom/network/tests/marionette/test_mobile_operator_names.js
Normal 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();
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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(¬es);
|
||||
|
||||
if (!mPluginDumpID.IsEmpty()) {
|
||||
crashReporter->GenerateChildData(¬es);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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();
|
||||
|
@ -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) {
|
||||
|
@ -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) {
|
||||
|
@ -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();
|
||||
|
@ -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");
|
||||
|
@ -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);
|
||||
},
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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))
|
||||
|
271
dom/tests/mochitest/chrome/selectAtPoint.html
Normal file
271
dom/tests/mochitest/chrome/selectAtPoint.html
Normal 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>
|
21
dom/tests/mochitest/chrome/test_selectAtPoint.html
Normal file
21
dom/tests/mochitest/chrome/test_selectAtPoint.html
Normal 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>
|
||||
|
@ -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,
|
||||
|
@ -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 = {};
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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");
|
||||
|
@ -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);
|
||||
|
@ -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
37
dom/webidl/Blob.webidl
Normal 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";
|
||||
|
||||
};
|
@ -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 \
|
||||
|
69
dom/webidl/WebSocket.webidl
Normal file
69
dom/webidl/WebSocket.webidl
Normal 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);
|
||||
};
|
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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
17
ipc/glue/ProcessUtils.h
Normal 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
|
||||
|
20
ipc/glue/ProcessUtils_linux.cpp
Normal file
20
ipc/glue/ProcessUtils_linux.cpp
Normal 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
|
16
ipc/glue/ProcessUtils_none.cpp
Normal file
16
ipc/glue/ProcessUtils_none.cpp
Normal 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
|
@ -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))))
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
117
js/src/gc/Root.h
117
js/src/gc/Root.h
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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());
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -3543,7 +3543,7 @@ RelaxRootChecks(JSContext *cx, unsigned argc, jsval *vp)
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
cx->runtime->relaxRootChecks = true;
|
||||
cx->runtime->gcRelaxRootChecks = true;
|
||||
#endif
|
||||
|
||||
return true;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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' ],
|
||||
|
@ -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")
|
||||
|
||||
|
@ -429,9 +429,6 @@ members = [
|
||||
# can't be quickstubbed
|
||||
'-nsIXMLHttpRequest.upload',
|
||||
|
||||
# WebSocket
|
||||
'nsIWebSocket.*',
|
||||
|
||||
# webgl
|
||||
'nsIDOMWebGLRenderingContext.*',
|
||||
# getContextAttributes is directly manipulating its return value
|
||||
|
@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user