mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-28 23:31:56 +00:00
Merge inbound to m-c
This commit is contained in:
commit
e400a12724
@ -259,7 +259,7 @@ endif
|
||||
|
||||
ifdef MOZ_PSEUDO_DERECURSE
|
||||
# Interdependencies for parallel export.
|
||||
js/xpconnect/src/export: dom/bindings/export
|
||||
js/xpconnect/src/export: dom/bindings/export xpcom/xpidl/export
|
||||
accessible/src/xpcom/export: xpcom/xpidl/export
|
||||
js/src/export: mfbt/export
|
||||
ifdef ENABLE_CLANG_PLUGIN
|
||||
|
@ -18,8 +18,7 @@ endif
|
||||
xpcAccEvents.cpp: $(srcdir)/AccEvents.conf \
|
||||
$(srcdir)/AccEventGen.py \
|
||||
$(LIBXUL_DIST)/sdk/bin/header.py \
|
||||
$(LIBXUL_DIST)/sdk/bin/xpidl.py \
|
||||
$(DEPTH)/js/src/js-confdefs.h
|
||||
$(LIBXUL_DIST)/sdk/bin/xpidl.py
|
||||
$(PYTHON) $(topsrcdir)/config/pythonpath.py \
|
||||
-I$(LIBXUL_DIST)/sdk/bin \
|
||||
$(srcdir)/AccEventGen.py \
|
||||
|
@ -574,7 +574,11 @@ pref("browser.gesture.twist.left", "cmd_gestureRotateLeft");
|
||||
pref("browser.gesture.twist.end", "cmd_gestureRotateEnd");
|
||||
pref("browser.gesture.tap", "cmd_fullZoomReset");
|
||||
|
||||
#ifndef RELEASE_BUILD
|
||||
pref("browser.snapshots.limit", 5);
|
||||
#else
|
||||
pref("browser.snapshots.limit", 0);
|
||||
#endif
|
||||
|
||||
// 0: Nothing happens
|
||||
// 1: Scrolling contents
|
||||
|
@ -7,8 +7,6 @@ include $(topsrcdir)/config/config.mk
|
||||
|
||||
abs_srcdir = $(abspath $(srcdir))
|
||||
|
||||
CHROME_DEPS += $(abs_srcdir)/content/overrides/app-license.html
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
PRE_RELEASE_SUFFIX := ""
|
||||
|
@ -139,7 +139,6 @@
|
||||
footertype="promobox"
|
||||
orient="vertical"
|
||||
ignorekeys="true"
|
||||
consumeoutsideclicks="true"
|
||||
hidden="true"
|
||||
onpopupshown="StarUI.panelShown(event);"
|
||||
aria-labelledby="editBookmarkPanelTitle">
|
||||
@ -188,7 +187,6 @@
|
||||
<panel id="UITourTooltip"
|
||||
type="arrow"
|
||||
hidden="true"
|
||||
consumeoutsideclicks="false"
|
||||
noautofocus="true"
|
||||
align="start"
|
||||
orient="vertical"
|
||||
@ -203,7 +201,6 @@
|
||||
<panel id="socialActivatedNotification"
|
||||
type="arrow"
|
||||
hidden="true"
|
||||
consumeoutsideclicks="true"
|
||||
align="start"
|
||||
orient="horizontal"
|
||||
role="alert">
|
||||
@ -234,7 +231,6 @@
|
||||
orient="horizontal"
|
||||
onpopupshowing="SocialShare.onShowing()"
|
||||
onpopuphidden="SocialShare.onHidden()"
|
||||
consumeoutsideclicks="true"
|
||||
hidden="true">
|
||||
<vbox class="social-share-toolbar">
|
||||
<vbox id="social-share-provider-buttons" flex="1"/>
|
||||
@ -255,7 +251,6 @@
|
||||
hidden="true"
|
||||
flip="slide"
|
||||
rolluponmousewheel="true"
|
||||
consumeoutsideclicks="false"
|
||||
noautofocus="true"
|
||||
position="topcenter topright"/>
|
||||
|
||||
@ -313,7 +308,6 @@
|
||||
type="arrow"
|
||||
hidden="true"
|
||||
noautofocus="true"
|
||||
consumeoutsideclicks="true"
|
||||
onpopupshown="if (event.target == this)
|
||||
gIdentityHandler.onPopupShown(event);"
|
||||
orient="vertical"
|
||||
|
@ -46,7 +46,6 @@
|
||||
type="arrow"
|
||||
orient="vertical"
|
||||
level="top"
|
||||
consumeoutsideclicks="true"
|
||||
onpopupshown="DownloadsPanel.onPopupShown(event);"
|
||||
onpopuphidden="DownloadsPanel.onPopupHidden(event);">
|
||||
<!-- The following popup menu should be a child of the panel element,
|
||||
|
@ -11,7 +11,6 @@ ifdef MOZILLA_OFFICIAL
|
||||
DEFINES += -DMOZILLA_OFFICIAL
|
||||
endif
|
||||
|
||||
GRE_MILESTONE := $(shell tail -n 1 $(topsrcdir)/config/milestone.txt 2>/dev/null || tail -1 $(topsrcdir)/config/milestone.txt)
|
||||
GRE_BUILDID := $(shell cat $(DEPTH)/config/buildid)
|
||||
DEFINES += -DGRE_MILESTONE=$(GRE_MILESTONE) -DGRE_BUILDID=$(GRE_BUILDID)
|
||||
|
||||
|
@ -95,6 +95,7 @@ oddly_ordered_inclnames = set([
|
||||
'ctypes/typedefs.h', # Included multiple times in the body of ctypes/CTypes.h
|
||||
'jsautokw.h', # Included in the body of frontend/TokenStream.h
|
||||
'jswin.h', # Must be #included before <psapi.h>
|
||||
'machine/endian.h', # Must be included after <sys/types.h> on BSD
|
||||
'winbase.h', # Must precede other system headers(?)
|
||||
'windef.h' # Must precede other system headers(?)
|
||||
])
|
||||
|
@ -195,9 +195,8 @@ MOZ_PSEUDO_DERECURSE :=
|
||||
endif
|
||||
endif
|
||||
|
||||
# Disable MOZ_PSEUDO_DERECURSE on the second PGO pass until it's widely
|
||||
# tested.
|
||||
ifdef MOZ_PROFILE_USE
|
||||
# Disable MOZ_PSEUDO_DERECURSE on PGO builds until it's fixed.
|
||||
ifneq (,$(MOZ_PROFILE_USE)$(MOZ_PROFILE_GENERATE))
|
||||
MOZ_PSEUDO_DERECURSE :=
|
||||
endif
|
||||
|
||||
|
@ -1331,7 +1331,7 @@ endif
|
||||
endif
|
||||
endif
|
||||
|
||||
libs realchrome:: $(CHROME_DEPS) $(FINAL_TARGET)/chrome
|
||||
libs realchrome:: $(FINAL_TARGET)/chrome
|
||||
$(call py_action,jar_maker,\
|
||||
$(QUIET) -j $(FINAL_TARGET)/chrome \
|
||||
$(MAKE_JARS_FLAGS) $(XULPPFLAGS) $(DEFINES) $(ACDEFINES) \
|
||||
|
@ -38,6 +38,7 @@
|
||||
#include "nsIDOMWindow.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "nsDisplayList.h"
|
||||
#include "nsFocusManager.h"
|
||||
|
||||
#include "nsTArray.h"
|
||||
|
||||
@ -1712,6 +1713,90 @@ CanvasRenderingContext2D::Stroke()
|
||||
Redraw();
|
||||
}
|
||||
|
||||
void CanvasRenderingContext2D::DrawSystemFocusRing(mozilla::dom::Element& aElement)
|
||||
{
|
||||
EnsureUserSpacePath();
|
||||
|
||||
if (!mPath) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(DrawCustomFocusRing(aElement)) {
|
||||
Save();
|
||||
|
||||
// set state to conforming focus state
|
||||
ContextState& state = CurrentState();
|
||||
state.globalAlpha = 1.0;
|
||||
state.shadowBlur = 0;
|
||||
state.shadowOffset.x = 0;
|
||||
state.shadowOffset.y = 0;
|
||||
state.op = mozilla::gfx::OP_OVER;
|
||||
|
||||
state.lineCap = CAP_BUTT;
|
||||
state.lineJoin = mozilla::gfx::JOIN_MITER_OR_BEVEL;
|
||||
state.lineWidth = 1;
|
||||
CurrentState().dash.Clear();
|
||||
|
||||
// color and style of the rings is the same as for image maps
|
||||
// set the background focus color
|
||||
CurrentState().SetColorStyle(STYLE_STROKE, NS_RGBA(255, 255, 255, 255));
|
||||
// draw the focus ring
|
||||
Stroke();
|
||||
|
||||
// set dashing for foreground
|
||||
FallibleTArray<mozilla::gfx::Float>& dash = CurrentState().dash;
|
||||
dash.AppendElement(1);
|
||||
dash.AppendElement(1);
|
||||
|
||||
// set the foreground focus color
|
||||
CurrentState().SetColorStyle(STYLE_STROKE, NS_RGBA(0,0,0, 255));
|
||||
// draw the focus ring
|
||||
Stroke();
|
||||
|
||||
Restore();
|
||||
}
|
||||
}
|
||||
|
||||
bool CanvasRenderingContext2D::DrawCustomFocusRing(mozilla::dom::Element& aElement)
|
||||
{
|
||||
EnsureUserSpacePath();
|
||||
|
||||
HTMLCanvasElement* canvas = GetCanvas();
|
||||
|
||||
if (!canvas|| !nsContentUtils::ContentIsDescendantOf(&aElement, canvas)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsIFocusManager* fm = nsFocusManager::GetFocusManager();
|
||||
if (fm) {
|
||||
// check that the element i focused
|
||||
nsCOMPtr<nsIDOMElement> focusedElement;
|
||||
fm->GetFocusedElement(getter_AddRefs(focusedElement));
|
||||
if (SameCOMIdentity(aElement.AsDOMNode(), focusedElement)) {
|
||||
// get the bounds of the current path
|
||||
mgfx::Rect bounds;
|
||||
bounds = mPath->GetBounds(mTarget->GetTransform());
|
||||
|
||||
// and set them as the accessible area
|
||||
nsRect rect(canvas->ClientLeft() + bounds.x, canvas->ClientTop() + bounds.y,
|
||||
bounds.width, bounds.height);
|
||||
rect.x *= AppUnitsPerCSSPixel();
|
||||
rect.y *= AppUnitsPerCSSPixel();
|
||||
rect.width *= AppUnitsPerCSSPixel();
|
||||
rect.height *= AppUnitsPerCSSPixel();
|
||||
|
||||
nsIFrame* frame = aElement.GetPrimaryFrame();
|
||||
if(frame) {
|
||||
frame->SetRect(rect);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
CanvasRenderingContext2D::Clip(const CanvasWindingRule& winding)
|
||||
{
|
||||
|
@ -171,6 +171,8 @@ public:
|
||||
void BeginPath();
|
||||
void Fill(const CanvasWindingRule& winding);
|
||||
void Stroke();
|
||||
void DrawSystemFocusRing(mozilla::dom::Element& element);
|
||||
bool DrawCustomFocusRing(mozilla::dom::Element& element);
|
||||
void Clip(const CanvasWindingRule& winding);
|
||||
bool IsPointInPath(double x, double y, const CanvasWindingRule& winding);
|
||||
bool IsPointInStroke(double x, double y);
|
||||
|
@ -890,6 +890,7 @@ protected:
|
||||
// -------------------------------------------------------------------------
|
||||
// WebGL extensions (implemented in WebGLContextExtensions.cpp)
|
||||
enum WebGLExtensionID {
|
||||
EXT_sRGB,
|
||||
EXT_texture_filter_anisotropic,
|
||||
OES_element_index_uint,
|
||||
OES_standard_derivatives,
|
||||
@ -952,7 +953,7 @@ protected:
|
||||
bool ValidateGLSLVariableName(const nsAString& name, const char *info);
|
||||
bool ValidateGLSLCharacter(PRUnichar c);
|
||||
bool ValidateGLSLString(const nsAString& string, const char *info);
|
||||
|
||||
bool ValidateTexImage2DFormat(GLenum format, const char* info);
|
||||
bool ValidateTexImage2DTarget(GLenum target, GLsizei width, GLsizei height, const char* info);
|
||||
bool ValidateCompressedTextureSize(GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height, uint32_t byteLength, const char* info);
|
||||
bool ValidateLevelWidthHeightForTarget(GLenum target, GLint level, GLsizei width, GLsizei height, const char* info);
|
||||
|
@ -17,6 +17,7 @@ using namespace mozilla::gl;
|
||||
|
||||
// must match WebGLContext::WebGLExtensionID
|
||||
static const char *sExtensionNames[] = {
|
||||
"EXT_sRGB",
|
||||
"EXT_texture_filter_anisotropic",
|
||||
"OES_element_index_uint",
|
||||
"OES_standard_derivatives",
|
||||
@ -113,6 +114,8 @@ bool WebGLContext::IsExtensionSupported(WebGLExtensionID ext) const
|
||||
gl->IsExtensionSupported(GLContext::ANGLE_depth_texture);
|
||||
case ANGLE_instanced_arrays:
|
||||
return WebGLExtensionInstancedArrays::IsSupported(this);
|
||||
case EXT_sRGB:
|
||||
return WebGLExtensionSRGB::IsSupported(this);
|
||||
default:
|
||||
// For warnings-as-errors.
|
||||
break;
|
||||
@ -257,6 +260,9 @@ WebGLContext::EnableExtension(WebGLExtensionID ext)
|
||||
case ANGLE_instanced_arrays:
|
||||
obj = new WebGLExtensionInstancedArrays(this);
|
||||
break;
|
||||
case EXT_sRGB:
|
||||
obj = new WebGLExtensionSRGB(this);
|
||||
break;
|
||||
default:
|
||||
MOZ_ASSERT(false, "should not get there.");
|
||||
}
|
||||
|
@ -584,7 +584,7 @@ WebGLContext::CopyTexImage2D(GLenum target,
|
||||
|
||||
sizeMayChange = width != imageInfo.Width() ||
|
||||
height != imageInfo.Height() ||
|
||||
internalformat != imageInfo.Format() ||
|
||||
internalformat != imageInfo.InternalFormat() ||
|
||||
type != imageInfo.Type();
|
||||
}
|
||||
|
||||
@ -661,7 +661,7 @@ WebGLContext::CopyTexSubImage2D(GLenum target,
|
||||
if (yoffset + height > texHeight || yoffset + height < 0)
|
||||
return ErrorInvalidValue("copyTexSubImage2D: yoffset+height is too large");
|
||||
|
||||
GLenum format = imageInfo.Format();
|
||||
GLenum format = imageInfo.InternalFormat();
|
||||
bool texFormatRequiresAlpha = format == LOCAL_GL_RGBA ||
|
||||
format == LOCAL_GL_ALPHA ||
|
||||
format == LOCAL_GL_LUMINANCE_ALPHA;
|
||||
@ -1045,7 +1045,7 @@ WebGLContext::BindFakeBlackTexturesHelper(
|
||||
}
|
||||
|
||||
bool alpha = s == WebGLTextureFakeBlackStatus::UninitializedImageData &&
|
||||
FormatHasAlpha(boundTexturesArray[i]->ImageInfoBase().Format());
|
||||
FormatHasAlpha(boundTexturesArray[i]->ImageInfoBase().InternalFormat());
|
||||
ScopedDeletePtr<FakeBlackTexture>&
|
||||
blackTexturePtr = alpha
|
||||
? transparentTextureScopedPtr
|
||||
@ -1205,7 +1205,7 @@ WebGLContext::GenerateMipmap(GLenum target)
|
||||
if (!tex->IsFirstImagePowerOfTwo())
|
||||
return ErrorInvalidOperation("generateMipmap: Level zero of texture does not have power-of-two width and height.");
|
||||
|
||||
GLenum format = tex->ImageInfoAt(imageTarget, 0).Format();
|
||||
GLenum format = tex->ImageInfoAt(imageTarget, 0).InternalFormat();
|
||||
if (IsTextureFormatCompressed(format))
|
||||
return ErrorInvalidOperation("generateMipmap: Texture data at level zero is compressed.");
|
||||
|
||||
@ -1415,6 +1415,15 @@ WebGLContext::GetFramebufferAttachmentParameter(JSContext* cx,
|
||||
|
||||
if (fba.Renderbuffer()) {
|
||||
switch (pname) {
|
||||
case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT:
|
||||
if (IsExtensionEnabled(EXT_sRGB)) {
|
||||
const GLenum internalFormat = fba.Renderbuffer()->InternalFormat();
|
||||
return (internalFormat == LOCAL_GL_SRGB_EXT ||
|
||||
internalFormat == LOCAL_GL_SRGB_ALPHA_EXT ||
|
||||
internalFormat == LOCAL_GL_SRGB8_ALPHA8_EXT) ?
|
||||
JS::NumberValue(uint32_t(LOCAL_GL_SRGB_EXT)) :
|
||||
JS::NumberValue(uint32_t(LOCAL_GL_LINEAR));
|
||||
}
|
||||
case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
|
||||
return JS::NumberValue(uint32_t(LOCAL_GL_RENDERBUFFER));
|
||||
|
||||
@ -1429,6 +1438,16 @@ WebGLContext::GetFramebufferAttachmentParameter(JSContext* cx,
|
||||
}
|
||||
} else if (fba.Texture()) {
|
||||
switch (pname) {
|
||||
case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT:
|
||||
if (IsExtensionEnabled(EXT_sRGB)) {
|
||||
const GLenum internalFormat =
|
||||
fba.Texture()->ImageInfoBase().InternalFormat();
|
||||
return (internalFormat == LOCAL_GL_SRGB_EXT ||
|
||||
internalFormat == LOCAL_GL_SRGB_ALPHA_EXT) ?
|
||||
JS::NumberValue(uint32_t(LOCAL_GL_SRGB_EXT)) :
|
||||
JS::NumberValue(uint32_t(LOCAL_GL_LINEAR));
|
||||
}
|
||||
|
||||
case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
|
||||
return JS::NumberValue(uint32_t(LOCAL_GL_TEXTURE));
|
||||
|
||||
@ -2493,6 +2512,8 @@ WebGLContext::RenderbufferStorage(GLenum target, GLenum internalformat, GLsizei
|
||||
// We emulate this in WebGLRenderbuffer if we don't have the requisite extension.
|
||||
internalformatForGL = LOCAL_GL_DEPTH24_STENCIL8;
|
||||
break;
|
||||
case LOCAL_GL_SRGB8_ALPHA8_EXT:
|
||||
break;
|
||||
default:
|
||||
return ErrorInvalidEnumInfo("renderbufferStorage: internalformat", internalformat);
|
||||
}
|
||||
@ -3679,7 +3700,7 @@ GLenum WebGLContext::CheckedTexImage2D(GLenum target,
|
||||
const WebGLTexture::ImageInfo& imageInfo = tex->ImageInfoAt(target, level);
|
||||
sizeMayChange = width != imageInfo.Width() ||
|
||||
height != imageInfo.Height() ||
|
||||
format != imageInfo.Format() ||
|
||||
format != imageInfo.InternalFormat() ||
|
||||
type != imageInfo.Type();
|
||||
}
|
||||
|
||||
@ -3708,18 +3729,8 @@ WebGLContext::TexImage2D_base(GLenum target, GLint level, GLenum internalformat,
|
||||
return;
|
||||
}
|
||||
|
||||
switch (format) {
|
||||
case LOCAL_GL_RGB:
|
||||
case LOCAL_GL_RGBA:
|
||||
case LOCAL_GL_ALPHA:
|
||||
case LOCAL_GL_LUMINANCE:
|
||||
case LOCAL_GL_LUMINANCE_ALPHA:
|
||||
case LOCAL_GL_DEPTH_COMPONENT:
|
||||
case LOCAL_GL_DEPTH_STENCIL:
|
||||
break;
|
||||
default:
|
||||
return ErrorInvalidEnumInfo("texImage2D: internal format", internalformat);
|
||||
}
|
||||
if (!ValidateTexImage2DFormat(format, "texImage2D: format"))
|
||||
return;
|
||||
|
||||
if (format != internalformat)
|
||||
return ErrorInvalidOperation("texImage2D: format does not match internalformat");
|
||||
@ -3791,6 +3802,23 @@ WebGLContext::TexImage2D_base(GLenum target, GLint level, GLenum internalformat,
|
||||
// format == internalformat, as checked above and as required by ES.
|
||||
internalformat = InternalFormatForFormatAndType(format, type, gl->IsGLES2());
|
||||
|
||||
// Handle ES2 and GL differences when supporting sRGB internal formats. GL ES
|
||||
// requires that format == internalformat, but GL will fail in this case.
|
||||
// GL requires:
|
||||
// format -> internalformat
|
||||
// GL_RGB GL_SRGB_EXT
|
||||
// GL_RGBA GL_SRGB_ALPHA_EXT
|
||||
if (!gl->IsGLES2()) {
|
||||
switch (internalformat) {
|
||||
case LOCAL_GL_SRGB_EXT:
|
||||
format = LOCAL_GL_RGB;
|
||||
break;
|
||||
case LOCAL_GL_SRGB_ALPHA_EXT:
|
||||
format = LOCAL_GL_RGBA;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
GLenum error = LOCAL_GL_NO_ERROR;
|
||||
|
||||
WebGLImageDataStatus imageInfoStatusIfSuccess = WebGLImageDataStatus::NoImageData;
|
||||
@ -3839,7 +3867,7 @@ WebGLContext::TexImage2D_base(GLenum target, GLint level, GLenum internalformat,
|
||||
// have NoImageData at this point.
|
||||
MOZ_ASSERT(imageInfoStatusIfSuccess != WebGLImageDataStatus::NoImageData);
|
||||
|
||||
tex->SetImageInfo(target, level, width, height, format, type, imageInfoStatusIfSuccess);
|
||||
tex->SetImageInfo(target, level, width, height, internalformat, type, imageInfoStatusIfSuccess);
|
||||
|
||||
ReattachTextureToAnyFramebufferToWorkAroundBugs(tex, level);
|
||||
}
|
||||
@ -3959,7 +3987,7 @@ WebGLContext::TexSubImage2D_base(GLenum target, GLint level,
|
||||
return ErrorInvalidValue("texSubImage2D: subtexture rectangle out of bounds");
|
||||
|
||||
// Require the format and type in texSubImage2D to match that of the existing texture as created by texImage2D
|
||||
if (imageInfo.Format() != format || imageInfo.Type() != type)
|
||||
if (imageInfo.InternalFormat() != format || imageInfo.Type() != type)
|
||||
return ErrorInvalidOperation("texSubImage2D: format or type doesn't match the existing texture");
|
||||
|
||||
if (imageInfo.HasUninitializedImageData()) {
|
||||
@ -4157,8 +4185,10 @@ WebGLTexelFormat mozilla::GetWebGLTexelFormat(GLenum format, GLenum type)
|
||||
if (type == LOCAL_GL_UNSIGNED_BYTE) {
|
||||
switch (format) {
|
||||
case LOCAL_GL_RGBA:
|
||||
case LOCAL_GL_SRGB_ALPHA_EXT:
|
||||
return WebGLTexelFormat::RGBA8;
|
||||
case LOCAL_GL_RGB:
|
||||
case LOCAL_GL_SRGB_EXT:
|
||||
return WebGLTexelFormat::RGB8;
|
||||
case LOCAL_GL_ALPHA:
|
||||
return WebGLTexelFormat::A8;
|
||||
|
@ -300,6 +300,32 @@ bool WebGLContext::ValidateGLSLString(const nsAString& string, const char *info)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WebGLContext::ValidateTexImage2DFormat(GLenum format, const char* info)
|
||||
{
|
||||
if (IsExtensionEnabled(EXT_sRGB)) {
|
||||
switch (format) {
|
||||
case LOCAL_GL_SRGB_EXT:
|
||||
case LOCAL_GL_SRGB_ALPHA_EXT:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
switch (format) {
|
||||
case LOCAL_GL_RGB:
|
||||
case LOCAL_GL_RGBA:
|
||||
case LOCAL_GL_ALPHA:
|
||||
case LOCAL_GL_LUMINANCE:
|
||||
case LOCAL_GL_LUMINANCE_ALPHA:
|
||||
case LOCAL_GL_DEPTH_COMPONENT:
|
||||
case LOCAL_GL_DEPTH_STENCIL:
|
||||
return true;
|
||||
break;
|
||||
}
|
||||
|
||||
ErrorInvalidEnumInfo(info, format);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool WebGLContext::ValidateTexImage2DTarget(GLenum target, GLsizei width, GLsizei height,
|
||||
const char* info)
|
||||
{
|
||||
@ -464,8 +490,10 @@ uint32_t WebGLContext::GetBitsPerTexel(GLenum format, GLenum type)
|
||||
case LOCAL_GL_LUMINANCE_ALPHA:
|
||||
return 2 * multiplier;
|
||||
case LOCAL_GL_RGB:
|
||||
case LOCAL_GL_SRGB_EXT:
|
||||
return 3 * multiplier;
|
||||
case LOCAL_GL_RGBA:
|
||||
case LOCAL_GL_SRGB_ALPHA_EXT:
|
||||
return 4 * multiplier;
|
||||
case LOCAL_GL_COMPRESSED_RGB_PVRTC_2BPPV1:
|
||||
case LOCAL_GL_COMPRESSED_RGBA_PVRTC_2BPPV1:
|
||||
@ -562,9 +590,11 @@ bool WebGLContext::ValidateTexFormatAndType(GLenum format, GLenum type, int jsAr
|
||||
*texelSize = 2 * texMultiplier;
|
||||
return true;
|
||||
case LOCAL_GL_RGB:
|
||||
case LOCAL_GL_SRGB_EXT:
|
||||
*texelSize = 3 * texMultiplier;
|
||||
return true;
|
||||
case LOCAL_GL_RGBA:
|
||||
case LOCAL_GL_SRGB_ALPHA_EXT:
|
||||
*texelSize = 4 * texMultiplier;
|
||||
return true;
|
||||
default:
|
||||
|
40
content/canvas/src/WebGLExtensionSRGB.cpp
Normal file
40
content/canvas/src/WebGLExtensionSRGB.cpp
Normal file
@ -0,0 +1,40 @@
|
||||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* 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 "WebGLContext.h"
|
||||
#include "WebGLExtensions.h"
|
||||
#include "mozilla/dom/WebGLRenderingContextBinding.h"
|
||||
#include "GLContext.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
WebGLExtensionSRGB::WebGLExtensionSRGB(WebGLContext* context)
|
||||
: WebGLExtensionBase(context)
|
||||
{
|
||||
MOZ_ASSERT(IsSupported(context), "should not construct WebGLExtensionSRGB: "
|
||||
"sRGB is unsupported.");
|
||||
gl::GLContext* gl = context->GL();
|
||||
if (!gl->IsGLES()) {
|
||||
// Desktop OpenGL requires the following to be enabled to support
|
||||
// sRGB operations on framebuffers
|
||||
gl->MakeCurrent();
|
||||
gl->fEnable(LOCAL_GL_FRAMEBUFFER_SRGB_EXT);
|
||||
}
|
||||
}
|
||||
|
||||
WebGLExtensionSRGB::~WebGLExtensionSRGB()
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
WebGLExtensionSRGB::IsSupported(const WebGLContext* context)
|
||||
{
|
||||
gl::GLContext* gl = context->GL();
|
||||
|
||||
return gl->IsSupported(gl::GLFeature::sRGB);
|
||||
}
|
||||
|
||||
|
||||
IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionSRGB)
|
@ -109,6 +109,18 @@ public:
|
||||
DECL_WEBGL_EXTENSION_GOOP
|
||||
};
|
||||
|
||||
class WebGLExtensionSRGB
|
||||
: public WebGLExtensionBase
|
||||
{
|
||||
public:
|
||||
WebGLExtensionSRGB(WebGLContext*);
|
||||
virtual ~WebGLExtensionSRGB();
|
||||
|
||||
static bool IsSupported(const WebGLContext* context);
|
||||
|
||||
DECL_WEBGL_EXTENSION_GOOP
|
||||
};
|
||||
|
||||
class WebGLExtensionStandardDerivatives
|
||||
: public WebGLExtensionBase
|
||||
{
|
||||
|
@ -48,7 +48,7 @@ bool
|
||||
WebGLFramebuffer::Attachment::HasAlpha() const {
|
||||
GLenum format = 0;
|
||||
if (Texture() && Texture()->HasImageInfoAt(mTexImageTarget, mTexImageLevel))
|
||||
format = Texture()->ImageInfoAt(mTexImageTarget, mTexImageLevel).Format();
|
||||
format = Texture()->ImageInfoAt(mTexImageTarget, mTexImageLevel).InternalFormat();
|
||||
else if (Renderbuffer())
|
||||
format = Renderbuffer()->InternalFormat();
|
||||
return FormatHasAlpha(format);
|
||||
@ -105,6 +105,26 @@ WebGLFramebuffer::Attachment::HasSameDimensionsAs(const Attachment& other) const
|
||||
thisRect->HasSameDimensionsAs(*otherRect);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
IsValidAttachedTextureColorFormat(GLenum format) {
|
||||
return (
|
||||
/* linear 8-bit formats */
|
||||
format == LOCAL_GL_ALPHA ||
|
||||
format == LOCAL_GL_LUMINANCE ||
|
||||
format == LOCAL_GL_LUMINANCE_ALPHA ||
|
||||
format == LOCAL_GL_RGB ||
|
||||
format == LOCAL_GL_RGBA ||
|
||||
/* sRGB 8-bit formats */
|
||||
format == LOCAL_GL_SRGB_EXT ||
|
||||
format == LOCAL_GL_SRGB_ALPHA_EXT ||
|
||||
/* linear float32 formats */
|
||||
format == LOCAL_GL_ALPHA32F_ARB ||
|
||||
format == LOCAL_GL_LUMINANCE32F_ARB ||
|
||||
format == LOCAL_GL_LUMINANCE_ALPHA32F_ARB ||
|
||||
format == LOCAL_GL_RGB32F_ARB ||
|
||||
format == LOCAL_GL_RGBA32F_ARB);
|
||||
}
|
||||
|
||||
bool
|
||||
WebGLFramebuffer::Attachment::IsComplete() const {
|
||||
const WebGLRectangleObject *thisRect = RectangleObject();
|
||||
@ -118,7 +138,7 @@ WebGLFramebuffer::Attachment::IsComplete() const {
|
||||
if (!mTexturePtr->HasImageInfoAt(mTexImageTarget, mTexImageLevel))
|
||||
return false;
|
||||
|
||||
GLenum format = mTexturePtr->ImageInfoAt(mTexImageTarget, mTexImageLevel).Format();
|
||||
GLenum format = mTexturePtr->ImageInfoAt(mTexImageTarget, mTexImageLevel).InternalFormat();
|
||||
|
||||
if (mAttachmentPoint == LOCAL_GL_DEPTH_ATTACHMENT) {
|
||||
return format == LOCAL_GL_DEPTH_COMPONENT;
|
||||
@ -128,11 +148,7 @@ WebGLFramebuffer::Attachment::IsComplete() const {
|
||||
}
|
||||
else if (mAttachmentPoint >= LOCAL_GL_COLOR_ATTACHMENT0 &&
|
||||
mAttachmentPoint < GLenum(LOCAL_GL_COLOR_ATTACHMENT0 + WebGLContext::sMaxColorAttachments)) {
|
||||
return (format == LOCAL_GL_ALPHA ||
|
||||
format == LOCAL_GL_LUMINANCE ||
|
||||
format == LOCAL_GL_LUMINANCE_ALPHA ||
|
||||
format == LOCAL_GL_RGB ||
|
||||
format == LOCAL_GL_RGBA);
|
||||
return IsValidAttachedTextureColorFormat(format);
|
||||
}
|
||||
MOZ_CRASH("Invalid WebGL attachment poin?");
|
||||
}
|
||||
@ -153,7 +169,8 @@ WebGLFramebuffer::Attachment::IsComplete() const {
|
||||
mAttachmentPoint < GLenum(LOCAL_GL_COLOR_ATTACHMENT0 + WebGLContext::sMaxColorAttachments)) {
|
||||
return (format == LOCAL_GL_RGB565 ||
|
||||
format == LOCAL_GL_RGB5_A1 ||
|
||||
format == LOCAL_GL_RGBA4);
|
||||
format == LOCAL_GL_RGBA4 ||
|
||||
format == LOCAL_GL_SRGB8_ALPHA8_EXT);
|
||||
}
|
||||
MOZ_CRASH("Invalid WebGL attachment poin?");
|
||||
}
|
||||
|
@ -107,6 +107,7 @@ WebGLRenderbuffer::MemoryUsage() const {
|
||||
primarySize = 3*pixels;
|
||||
break;
|
||||
case LOCAL_GL_RGBA8:
|
||||
case LOCAL_GL_SRGB8_ALPHA8_EXT:
|
||||
case LOCAL_GL_DEPTH24_STENCIL8:
|
||||
case LOCAL_GL_DEPTH_COMPONENT32:
|
||||
primarySize = 4*pixels;
|
||||
|
@ -48,7 +48,7 @@ int64_t
|
||||
WebGLTexture::ImageInfo::MemoryUsage() const {
|
||||
if (mImageDataStatus == WebGLImageDataStatus::NoImageData)
|
||||
return 0;
|
||||
int64_t texelSizeInBits = WebGLContext::GetBitsPerTexel(mFormat, mType);
|
||||
int64_t texelSizeInBits = WebGLContext::GetBitsPerTexel(mInternalFormat, mType);
|
||||
return int64_t(mWidth) * int64_t(mHeight) * texelSizeInBits / 8;
|
||||
}
|
||||
|
||||
@ -418,7 +418,7 @@ WebGLTexture::DoDeferredImageInitialization(GLenum imageTarget, GLint level)
|
||||
mContext->MakeContextCurrent();
|
||||
gl::ScopedBindTexture autoBindTex(mContext->gl, GLName(), mTarget);
|
||||
|
||||
WebGLTexelFormat texelformat = GetWebGLTexelFormat(imageInfo.mFormat, imageInfo.mType);
|
||||
WebGLTexelFormat texelformat = GetWebGLTexelFormat(imageInfo.mInternalFormat, imageInfo.mType);
|
||||
uint32_t texelsize = WebGLTexelConversions::TexelBytesForFormat(texelformat);
|
||||
CheckedUint32 checked_byteLength
|
||||
= WebGLContext::GetImageSize(
|
||||
@ -430,9 +430,9 @@ WebGLTexture::DoDeferredImageInitialization(GLenum imageTarget, GLint level)
|
||||
void *zeros = calloc(1, checked_byteLength.value());
|
||||
|
||||
mContext->UpdateWebGLErrorAndClearGLError();
|
||||
mContext->gl->fTexImage2D(imageTarget, level, imageInfo.mFormat,
|
||||
mContext->gl->fTexImage2D(imageTarget, level, imageInfo.mInternalFormat,
|
||||
imageInfo.mWidth, imageInfo.mHeight,
|
||||
0, imageInfo.mFormat, imageInfo.mType,
|
||||
0, imageInfo.mInternalFormat, imageInfo.mType,
|
||||
zeros);
|
||||
GLenum error = LOCAL_GL_NO_ERROR;
|
||||
mContext->UpdateWebGLErrorAndClearGLError(&error);
|
||||
|
@ -80,7 +80,7 @@ public:
|
||||
{
|
||||
public:
|
||||
ImageInfo()
|
||||
: mFormat(0)
|
||||
: mInternalFormat(0)
|
||||
, mType(0)
|
||||
, mImageDataStatus(WebGLImageDataStatus::NoImageData)
|
||||
{}
|
||||
@ -88,7 +88,7 @@ public:
|
||||
ImageInfo(GLsizei width, GLsizei height,
|
||||
GLenum format, GLenum type, WebGLImageDataStatus status)
|
||||
: WebGLRectangleObject(width, height)
|
||||
, mFormat(format)
|
||||
, mInternalFormat(format)
|
||||
, mType(type)
|
||||
, mImageDataStatus(status)
|
||||
{
|
||||
@ -100,7 +100,7 @@ public:
|
||||
return mImageDataStatus == a.mImageDataStatus &&
|
||||
mWidth == a.mWidth &&
|
||||
mHeight == a.mHeight &&
|
||||
mFormat == a.mFormat &&
|
||||
mInternalFormat == a.mInternalFormat &&
|
||||
mType == a.mType;
|
||||
}
|
||||
bool operator!=(const ImageInfo& a) const {
|
||||
@ -120,10 +120,10 @@ public:
|
||||
return mImageDataStatus == WebGLImageDataStatus::UninitializedImageData;
|
||||
}
|
||||
int64_t MemoryUsage() const;
|
||||
GLenum Format() const { return mFormat; }
|
||||
GLenum InternalFormat() const { return mInternalFormat; }
|
||||
GLenum Type() const { return mType; }
|
||||
protected:
|
||||
GLenum mFormat, mType;
|
||||
GLenum mInternalFormat, mType;
|
||||
WebGLImageDataStatus mImageDataStatus;
|
||||
|
||||
friend class WebGLTexture;
|
||||
|
@ -55,6 +55,7 @@ if CONFIG['MOZ_WEBGL']:
|
||||
'WebGLExtensionElementIndexUint.cpp',
|
||||
'WebGLExtensionInstancedArrays.cpp',
|
||||
'WebGLExtensionLoseContext.cpp',
|
||||
'WebGLExtensionSRGB.cpp',
|
||||
'WebGLExtensionStandardDerivatives.cpp',
|
||||
'WebGLExtensionTextureFilterAnisotropic.cpp',
|
||||
'WebGLExtensionTextureFloat.cpp',
|
||||
|
@ -91,6 +91,7 @@ support-files =
|
||||
[test_bug866575.html]
|
||||
[test_bug902651.html]
|
||||
[test_canvas.html]
|
||||
[test_canvas_focusring.html]
|
||||
[test_canvas_font_setter.html]
|
||||
[test_canvas_strokeStyle_getter.html]
|
||||
[test_drawImageIncomplete.html]
|
||||
|
18
content/canvas/test/reftest/drawCustomFocusRing-ref.html
Normal file
18
content/canvas/test/reftest/drawCustomFocusRing-ref.html
Normal file
@ -0,0 +1,18 @@
|
||||
<!--docytpe html-->
|
||||
<html><head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
||||
<meta charset="UTF-8">
|
||||
<script>
|
||||
window.onload=function(){
|
||||
var c=document.getElementById("myCanvas").getContext("2d");
|
||||
c.beginPath();
|
||||
c.strokeRect(10, 10, 200, 200);
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<canvas id="myCanvas" height="500" width="500" style="border:1px solid black">
|
||||
|
||||
</canvas>
|
||||
|
||||
</body></html>
|
32
content/canvas/test/reftest/drawCustomFocusRing.html
Normal file
32
content/canvas/test/reftest/drawCustomFocusRing.html
Normal file
@ -0,0 +1,32 @@
|
||||
<!--docytpe html-->
|
||||
<html><head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
||||
<meta charset="UTF-8">
|
||||
<script>
|
||||
window.onload=function(){
|
||||
var c=document.getElementById("myCanvas").getContext("2d");
|
||||
var in1=document.getElementById("in1");
|
||||
var in2=document.getElementById("in2");
|
||||
in1.onfocus=function(){
|
||||
c.beginPath();
|
||||
c.rect(10, 10, 200, 200);
|
||||
if(c.drawCustomFocusRing(in1)) {
|
||||
c.stroke();
|
||||
}
|
||||
c.beginPath();
|
||||
c.rect(10, 220, 200, 200);
|
||||
if(c.drawCustomFocusRing(in2)) {
|
||||
c.stroke();
|
||||
}
|
||||
}
|
||||
in1.focus();
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<canvas id="myCanvas" height="500" width="500" style="border:1px solid black">
|
||||
<input id="in1" type="range" min="1" max="12">
|
||||
<input id="in2" type="range" min="1" max="12">
|
||||
</canvas>
|
||||
|
||||
</body></html>
|
18
content/canvas/test/reftest/drawSystemFocusRing-ref.html
Normal file
18
content/canvas/test/reftest/drawSystemFocusRing-ref.html
Normal file
@ -0,0 +1,18 @@
|
||||
<!--docytpe html-->
|
||||
<html><head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
||||
<meta charset="UTF-8">
|
||||
<script>
|
||||
window.onload=function(){
|
||||
var c=document.getElementById("myCanvas").getContext("2d");
|
||||
c.beginPath();
|
||||
c.mozDash = [1,1];
|
||||
c.strokeRect(10, 10, 200, 200);
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<canvas id="myCanvas" height="500" width="500" style="border:1px solid black">
|
||||
</canvas>
|
||||
|
||||
</body></html>
|
28
content/canvas/test/reftest/drawSystemFocusRing.html
Normal file
28
content/canvas/test/reftest/drawSystemFocusRing.html
Normal file
@ -0,0 +1,28 @@
|
||||
<!--docytpe html-->
|
||||
<html><head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
||||
<meta charset="UTF-8">
|
||||
<script>
|
||||
window.onload=function(){
|
||||
var c=document.getElementById("myCanvas").getContext("2d");
|
||||
var in1=document.getElementById("in1");
|
||||
var in2=document.getElementById("in2");
|
||||
in1.onfocus=function(){
|
||||
c.beginPath();
|
||||
c.rect(10, 10, 200, 200);
|
||||
c.drawSystemFocusRing(in1);
|
||||
c.beginPath();
|
||||
c.rect(10, 220, 200, 200);
|
||||
c.drawSystemFocusRing(in2);
|
||||
}
|
||||
in1.focus();
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<canvas id="myCanvas" height="500" width="500" style="border:1px solid black">
|
||||
<input id="in1" type="range" min="1" max="12">
|
||||
<input id="in2" type="range" min="1" max="12">
|
||||
</canvas>
|
||||
|
||||
</body></html>
|
@ -188,3 +188,7 @@ skip-if(!winWidget) pref(webgl.prefer-native-gl,true) pref(webgl.prefer-16bpp,tr
|
||||
|
||||
# Bug 815648
|
||||
== stroketext-shadow.html stroketext-shadow-ref.html
|
||||
|
||||
# focus rings
|
||||
pref(canvas.focusring.enabled,true) skip-if(B2G) skip-if(Android&&AndroidVersion<15,8,500) skip-if(winWidget) needs-focus == drawSystemFocusRing.html drawSystemFocusRing-ref.html
|
||||
pref(canvas.focusring.enabled,true) skip-if(B2G) skip-if(Android&&AndroidVersion<15,8,500) skip-if(winWidget) needs-focus == drawCustomFocusRing.html drawCustomFocusRing-ref.html
|
||||
|
98
content/canvas/test/test_canvas_focusring.html
Normal file
98
content/canvas/test/test_canvas_focusring.html
Normal file
@ -0,0 +1,98 @@
|
||||
<!DOCTYPE HTML>
|
||||
<title>Canvas Tests</title>
|
||||
<script src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" href="/tests/SimpleTest/test.css">
|
||||
<body>
|
||||
<script>
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
const Cc = SpecialPowers.Cc;
|
||||
const Cr = SpecialPowers.Cr;
|
||||
SpecialPowers.setBoolPref("canvas.focusring.enabled", true);
|
||||
</script>
|
||||
|
||||
<p>Canvas test: drawCustomFocusRing</p>
|
||||
<canvas id="c688" class="output" width="100" height="50">+
|
||||
<input id="button1" type="range" min="1" max="12"></input>
|
||||
<input id="button2" type="range" min="1" max="12"></input>
|
||||
</canvas>
|
||||
<script type="text/javascript">
|
||||
function test_drawCustomFocusRing_canvas() {
|
||||
var c = document.getElementById("c688");
|
||||
var ctx = c.getContext("2d");
|
||||
ctx.beginPath();
|
||||
var b1 = document.getElementById('button1');
|
||||
var b2 = document.getElementById('button2');
|
||||
ok(!ctx.drawCustomFocusRing(b1), "button 1 is focused");
|
||||
ok(!ctx.drawCustomFocusRing(b2), "button 2 is focused");
|
||||
b1.focus();
|
||||
ok(ctx.drawCustomFocusRing(b1), "button 1 should not be focused");
|
||||
}
|
||||
</script>
|
||||
|
||||
<p>Canvas test: drawSystemFocusRing</p>
|
||||
<canvas id="c689" class="output" width="50" height="25">
|
||||
<input id="button3" type="range" min="1" max="12"></input>
|
||||
<input id="button4" type="range" min="1" max="12"></input>
|
||||
</canvas>
|
||||
<script type="text/javascript">
|
||||
function isEmptyCanvas(ctx, w, h) {
|
||||
var imgdata = ctx.getImageData(0, 0, w, h);
|
||||
for(var x = 0; x < w*h*4; x++)
|
||||
if(imgdata.data[x] != 0)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
function test_drawSystemFocusRing_canvas() {
|
||||
var c = document.getElementById("c689");
|
||||
var ctx = c.getContext("2d");
|
||||
var b1 = document.getElementById('button3');
|
||||
var b2 = document.getElementById('button4');
|
||||
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
|
||||
ctx.beginPath();
|
||||
ctx.rect(10, 10, 30, 30);
|
||||
ctx.drawSystemFocusRing(b1);
|
||||
ok(isEmptyCanvas(ctx, ctx.canvas.width, ctx.canvas.height), "focus of button 1 is drawn");
|
||||
|
||||
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
|
||||
ctx.beginPath();
|
||||
ctx.rect(50, 10, 30, 30);
|
||||
ctx.drawSystemFocusRing(b2);
|
||||
ctx.rect(50, 10, 30, 30);
|
||||
ctx.drawSystemFocusRing(b2);
|
||||
ok(isEmptyCanvas(ctx, ctx.canvas.width, ctx.canvas.height), "focus of button 2 is drawn");
|
||||
|
||||
b1.focus();
|
||||
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
|
||||
ctx.beginPath();
|
||||
ctx.rect(10, 10, 30, 30);
|
||||
ctx.drawSystemFocusRing(b1);
|
||||
ok(!isEmptyCanvas(ctx, ctx.canvas.width, ctx.canvas.height) , "focus of button 1 is not drawn");
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
<script>
|
||||
|
||||
function runTests() {
|
||||
try {
|
||||
test_drawCustomFocusRing_canvas();
|
||||
} catch(e) {
|
||||
throw e;
|
||||
ok(false, "unexpected exception thrown in: test_drawCustomFocusRing_canvas");
|
||||
}
|
||||
try {
|
||||
test_drawSystemFocusRing_canvas();
|
||||
} catch(e) {
|
||||
throw e;
|
||||
ok(false, "unexpected exception thrown in: test_drawSystemFocusRing_canvas");
|
||||
}
|
||||
|
||||
SpecialPowers.setBoolPref("canvas.focusring.enabled", false);
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
addLoadEvent(runTests);
|
||||
|
||||
</script>
|
@ -6,4 +6,4 @@ webgl-debug-renderer-info.html
|
||||
webgl-debug-shaders.html
|
||||
--min-version 1.0.2 webgl-compressed-texture-s3tc.html
|
||||
--min-version 1.0.2 webgl-depth-texture.html
|
||||
|
||||
ext-sRGB.html
|
||||
|
363
content/canvas/test/webgl/conformance/extensions/ext-sRGB.html
Normal file
363
content/canvas/test/webgl/conformance/extensions/ext-sRGB.html
Normal file
@ -0,0 +1,363 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
||||
<script src="../../resources/js-test-pre.js"></script>
|
||||
<script src="../resources/webgl-test.js"></script>
|
||||
<script src="../resources/webgl-test-utils.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="description"></div>
|
||||
<div id="console"></div>
|
||||
<canvas id="canvas" width="16" height="16" style="width: 50px; height: 50px; border: 1px solid black;"></canvas>
|
||||
|
||||
<!-- Shaders to test output -->
|
||||
<script id="vertexShader" type="x-shader/x-vertex">
|
||||
attribute vec4 aPosition;
|
||||
void main() {
|
||||
gl_Position = aPosition;
|
||||
}
|
||||
</script>
|
||||
|
||||
<script id="fragmentShader" type="x-shader/x-fragment">
|
||||
precision mediump float;
|
||||
uniform float uColor;
|
||||
void main() {
|
||||
gl_FragColor = vec4(uColor, uColor, uColor, 1);
|
||||
}
|
||||
</script>
|
||||
|
||||
<script>
|
||||
"use strict";
|
||||
|
||||
var wtu = WebGLTestUtils;
|
||||
var canvas;
|
||||
var gl;
|
||||
var ext = null;
|
||||
|
||||
function getExtension() {
|
||||
ext = gl.getExtension("EXT_sRGB");
|
||||
}
|
||||
|
||||
function listsExtension() {
|
||||
var supported = gl.getSupportedExtensions();
|
||||
return (supported.indexOf("EXT_sRGB") >= 0);
|
||||
}
|
||||
|
||||
function readLocation(x, y) {
|
||||
var pixel = new Uint8Array(1 * 1 * 4);
|
||||
var px = Math.floor(x * canvas.drawingBufferWidth);
|
||||
var py = Math.floor(y * canvas.drawingBufferHeight);
|
||||
gl.readPixels(px, py, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, pixel);
|
||||
return pixel;
|
||||
}
|
||||
|
||||
function toVec3String(val) {
|
||||
if (typeof(val) == 'number') {
|
||||
return toVec3String([val, val, val]);
|
||||
}
|
||||
return '[' + val[0] + ', ' + val[1] + ', ' + val[2] + ']';
|
||||
}
|
||||
|
||||
var e = 2; // Amount of variance to allow in result pixels - may need to be tweaked higher
|
||||
|
||||
function expectResult(target, successMessage, failureMessage) {
|
||||
var anyDiffer = false;
|
||||
var source = readLocation(0.5, 0.5);
|
||||
for (var m = 0; m < 3; m++) {
|
||||
if (Math.abs(source[m] - target) > e) {
|
||||
anyDiffer = true;
|
||||
testFailed(failureMessage + "; should be " + toVec3String(target) + ", was " + toVec3String(source));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!anyDiffer) {
|
||||
testPassed(successMessage);
|
||||
}
|
||||
}
|
||||
|
||||
function createGreysRGBTexture(gl, color) {
|
||||
var numPixels = gl.drawingBufferWidth * gl.drawingBufferHeight;
|
||||
var size = numPixels * 3;
|
||||
var buf = new Uint8Array(size);
|
||||
for (var ii = 0; ii < numPixels; ++ii) {
|
||||
var off = ii * 3;
|
||||
buf[off + 0] = color;
|
||||
buf[off + 1] = color;
|
||||
buf[off + 2] = color;
|
||||
}
|
||||
|
||||
var tex = gl.createTexture();
|
||||
gl.bindTexture(gl.TEXTURE_2D, tex);
|
||||
gl.texImage2D(gl.TEXTURE_2D,
|
||||
0,
|
||||
ext.SRGB_EXT,
|
||||
gl.drawingBufferWidth,
|
||||
gl.drawingBufferHeight,
|
||||
0,
|
||||
ext.SRGB_EXT,
|
||||
gl.UNSIGNED_BYTE,
|
||||
buf);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
||||
return tex;
|
||||
}
|
||||
|
||||
function testValidFormat(fn, internalFormat, formatName) {
|
||||
fn(internalFormat);
|
||||
glErrorShouldBe(gl, gl.NO_ERROR, "was able to create type " + formatName);
|
||||
}
|
||||
|
||||
function testInvalidFormat(fn, internalFormat, formatName) {
|
||||
fn(internalFormat);
|
||||
var err = gl.getError();
|
||||
if (err == gl.NO_ERROR) {
|
||||
testFailed("should NOT be able to create type " + formatName);
|
||||
} else if (err == gl.INVALID_OPERATION) {
|
||||
testFailed("should return gl.INVALID_ENUM for type " + formatName);
|
||||
} else if (err == gl.INVALID_ENUM) {
|
||||
testPassed("not able to create invalid format: " + formatName);
|
||||
}
|
||||
}
|
||||
|
||||
var textureFormatFixture = {
|
||||
desc: "Checking texture formats",
|
||||
create: function(format) {
|
||||
var tex = gl.createTexture();
|
||||
gl.bindTexture(gl.TEXTURE_2D, tex);
|
||||
gl.texImage2D(gl.TEXTURE_2D,
|
||||
0, // level
|
||||
format, // internalFormat
|
||||
gl.drawingBufferWidth, // width
|
||||
gl.drawingBufferHeight, // height
|
||||
0, // border
|
||||
format, // format
|
||||
gl.UNSIGNED_BYTE, // type
|
||||
null); // data
|
||||
},
|
||||
tests: [
|
||||
{
|
||||
desc: "Checking valid formats",
|
||||
fn: testValidFormat,
|
||||
formats: [ 'SRGB_EXT', 'SRGB_ALPHA_EXT' ]
|
||||
},
|
||||
{
|
||||
desc: "Checking invalid formats",
|
||||
fn: testInvalidFormat,
|
||||
formats: [ 'SRGB8_ALPHA8_EXT' ]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
var renderbufferFormatFixture = {
|
||||
desc: "Checking renderbuffer formats",
|
||||
create: function(format) {
|
||||
var rbo = gl.createRenderbuffer();
|
||||
gl.bindRenderbuffer(gl.RENDERBUFFER, rbo);
|
||||
gl.renderbufferStorage(gl.RENDERBUFFER,
|
||||
format,
|
||||
gl.drawingBufferWidth,
|
||||
gl.drawingBufferHeight);
|
||||
},
|
||||
tests: [
|
||||
{
|
||||
desc: "Checking valid formats",
|
||||
fn: testValidFormat,
|
||||
formats: [ 'SRGB8_ALPHA8_EXT' ]
|
||||
},
|
||||
{
|
||||
desc: "Checking invalid formats",
|
||||
fn: testInvalidFormat,
|
||||
formats: [ 'SRGB_EXT', 'SRGB_ALPHA_EXT' ]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
|
||||
description("Test sRGB texture support");
|
||||
|
||||
debug("");
|
||||
debug("Canvas.getContext");
|
||||
|
||||
canvas = document.getElementById("canvas");
|
||||
gl = wtu.create3DContext(canvas);
|
||||
if (!gl) {
|
||||
testFailed("context does not exist");
|
||||
} else {
|
||||
testPassed("context exists");
|
||||
|
||||
debug("");
|
||||
debug("Checking sRGB texture support");
|
||||
|
||||
// Query the extension and store globally so shouldBe can access it
|
||||
ext = gl.getExtension("EXT_sRGB");
|
||||
|
||||
if (!ext) {
|
||||
testPassed("No EXT_sRGB support -- this is legal");
|
||||
|
||||
runSupportedTest(false);
|
||||
} else {
|
||||
testPassed("Successfully enabled EXT_sRGB extension");
|
||||
|
||||
runSupportedTest(true);
|
||||
|
||||
gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);
|
||||
|
||||
runFormatTest(textureFormatFixture);
|
||||
runFormatTest(renderbufferFormatFixture);
|
||||
runTextureReadConversionTest();
|
||||
runFramebufferTextureConversionTest();
|
||||
runFramebufferRenderbufferConversionTest();
|
||||
}
|
||||
}
|
||||
|
||||
function runSupportedTest(extensionEnabled) {
|
||||
if (listsExtension()) {
|
||||
if (extensionEnabled) {
|
||||
testPassed("EXT_sRGB listed as supported and getExtension succeeded");
|
||||
} else {
|
||||
testFailed("EXT_sRGB listed as supported but getExtension failed");
|
||||
}
|
||||
} else {
|
||||
if (extensionEnabled) {
|
||||
testFailed("EXT_sRGB not listed as supported but getExtension succeeded");
|
||||
} else {
|
||||
testPassed("EXT_sRGB not listed as supported and getExtension failed -- this is legal");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function runFormatTest(fixture) {
|
||||
debug("");
|
||||
debug(fixture.desc);
|
||||
|
||||
for (var tt = 0; tt < fixture.tests.length; ++tt) {
|
||||
var test = fixture.tests[tt];
|
||||
debug(test.desc);
|
||||
|
||||
for (var ii = 0; ii < test.formats.length; ++ii) {
|
||||
var formatName = test.formats[ii];
|
||||
test.fn(fixture.create, ext[formatName], "ext." + formatName);
|
||||
}
|
||||
|
||||
if (tt != fixture.tests.length - 1)
|
||||
debug("");
|
||||
}
|
||||
}
|
||||
|
||||
function runTextureReadConversionTest() {
|
||||
debug("");
|
||||
debug("Test the conversion of colors from sRGB to linear on texture read");
|
||||
|
||||
// Draw
|
||||
var conversions = [
|
||||
[ 0, 0 ],
|
||||
[ 63, 13 ],
|
||||
[ 127, 54 ],
|
||||
[ 191, 133 ],
|
||||
[ 255, 255 ]
|
||||
];
|
||||
|
||||
var program = wtu.setupTexturedQuad(gl);
|
||||
gl.uniform1i(gl.getUniformLocation(program, "tex2d"), 0);
|
||||
|
||||
for (var ii = 0; ii < conversions.length; ii++) {
|
||||
var tex = createGreysRGBTexture(gl, conversions[ii][0]);
|
||||
wtu.drawQuad(gl);
|
||||
expectResult(conversions[ii][1],
|
||||
"sRGB texture read returned correct data",
|
||||
"sRGB texture read returned incorrect data");
|
||||
}
|
||||
}
|
||||
|
||||
function runFramebufferTextureConversionTest() {
|
||||
debug("");
|
||||
debug("Test the conversion of colors from linear to sRGB on framebuffer (texture) write");
|
||||
|
||||
var program = wtu.setupProgram(gl, ['vertexShader', 'fragmentShader'], ['aPosition'], [0]);
|
||||
var tex = createGreysRGBTexture(gl, 0);
|
||||
var fbo = gl.createFramebuffer();
|
||||
gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
|
||||
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0);
|
||||
glErrorShouldBe(gl, gl.NO_ERROR);
|
||||
|
||||
shouldBe('gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, ext.FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT)', 'ext.SRGB_EXT');
|
||||
shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE");
|
||||
|
||||
// Draw
|
||||
var conversions = [
|
||||
[ 0, 0 ],
|
||||
[ 13, 63 ],
|
||||
[ 54, 127 ],
|
||||
[ 133, 191 ],
|
||||
[ 255, 255 ]
|
||||
];
|
||||
|
||||
wtu.setupUnitQuad(gl, 0);
|
||||
|
||||
for (var ii = 0; ii < conversions.length; ii++) {
|
||||
gl.uniform1f(gl.getUniformLocation(program, "uColor"), conversions[ii][0]/255.0);
|
||||
wtu.drawQuad(gl, [0, 0, 0, 0]);
|
||||
expectResult(conversions[ii][1],
|
||||
"framebuffer (texture) read returned correct data",
|
||||
"framebuffer (texture) read returned incorrect data");
|
||||
}
|
||||
|
||||
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
|
||||
}
|
||||
|
||||
function runFramebufferRenderbufferConversionTest() {
|
||||
debug("");
|
||||
debug("Test the conversion of colors from linear to sRGB on framebuffer (renderbuffer) write");
|
||||
|
||||
function createsRGBFramebuffer(gl, width, height) {
|
||||
var rbo = gl.createRenderbuffer();
|
||||
gl.bindRenderbuffer(gl.RENDERBUFFER, rbo);
|
||||
gl.renderbufferStorage(gl.RENDERBUFFER, ext.SRGB8_ALPHA8_EXT, width, height);
|
||||
glErrorShouldBe(gl, gl.NO_ERROR);
|
||||
|
||||
var fbo = gl.createFramebuffer();
|
||||
gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
|
||||
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0,
|
||||
gl.RENDERBUFFER, rbo);
|
||||
glErrorShouldBe(gl, gl.NO_ERROR);
|
||||
|
||||
shouldBe('gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, ext.FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT)', 'ext.SRGB_EXT');
|
||||
shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE");
|
||||
|
||||
return fbo;
|
||||
}
|
||||
|
||||
// Draw
|
||||
var conversions = [
|
||||
[ 0, 0 ],
|
||||
[ 13, 63 ],
|
||||
[ 54, 127 ],
|
||||
[ 133, 191 ],
|
||||
[ 255, 255 ]
|
||||
];
|
||||
|
||||
var program = wtu.setupProgram(gl, ['vertexShader', 'fragmentShader'], ['aPosition'], [0]);
|
||||
wtu.setupUnitQuad(gl, 0);
|
||||
var fbo = createsRGBFramebuffer(gl, 4, 4);
|
||||
|
||||
for (var ii = 0; ii < conversions.length; ii++) {
|
||||
gl.uniform1f(gl.getUniformLocation(program, "uColor"), conversions[ii][0]/255.0);
|
||||
wtu.drawQuad(gl, [0, 0, 0, 0]);
|
||||
expectResult(conversions[ii][1],
|
||||
"framebuffer (renderbuffer) read returned the correct data",
|
||||
"framebuffer (renderbuffer) read returned incorrect data");
|
||||
}
|
||||
}
|
||||
|
||||
debug("");
|
||||
var successfullyParsed = true;
|
||||
</script>
|
||||
<script>finishTest();</script>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -142,7 +142,8 @@ public:
|
||||
// mLeftOverData != INT_MIN means that the panning model was HRTF and a
|
||||
// tail-time reference was added. Even if the model is now equalpower,
|
||||
// the reference will need to be removed.
|
||||
if (mLeftOverData > 0) {
|
||||
if (mLeftOverData > 0 &&
|
||||
mPanningModelFunction == &PannerNodeEngine::HRTFPanningFunction) {
|
||||
mLeftOverData -= WEBAUDIO_BLOCK_SIZE;
|
||||
} else {
|
||||
if (mLeftOverData != INT_MIN) {
|
||||
|
@ -3762,7 +3762,7 @@ nsGlobalWindow::GetScriptableContent(JSContext* aCx, JS::Value* aVal)
|
||||
ErrorResult rv;
|
||||
JS::Rooted<JSObject*> content(aCx, GetContent(aCx, rv));
|
||||
if (!rv.Failed()) {
|
||||
*aVal = JS::ObjectValue(*content);
|
||||
*aVal = JS::ObjectOrNullValue(content);
|
||||
}
|
||||
|
||||
return rv.ErrorCode();
|
||||
|
@ -1310,6 +1310,11 @@ DOMInterfaces = {
|
||||
'headerFile': 'WebGLExtensions.h'
|
||||
},
|
||||
|
||||
'WebGLExtensionSRGB': {
|
||||
'nativeType': 'mozilla::WebGLExtensionSRGB',
|
||||
'headerFile': 'WebGLExtensions.h'
|
||||
},
|
||||
|
||||
'WebGLExtensionStandardDerivatives': {
|
||||
'nativeType': 'mozilla::WebGLExtensionStandardDerivatives',
|
||||
'headerFile': 'WebGLExtensions.h'
|
||||
|
@ -80,6 +80,7 @@ class nsGeolocationRequest
|
||||
void SendLocation(nsIDOMGeoPosition* location);
|
||||
bool WantsHighAccuracy() {return !mShutdown && mOptions && mOptions->mEnableHighAccuracy;}
|
||||
void SetTimeoutTimer();
|
||||
void NotifyErrorAndShutdown(uint16_t);
|
||||
nsIPrincipal* GetPrincipal();
|
||||
|
||||
~nsGeolocationRequest();
|
||||
@ -350,6 +351,13 @@ NS_IMPL_CYCLE_COLLECTION_3(nsGeolocationRequest, mCallback, mErrorCallback, mLoc
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsGeolocationRequest::Notify(nsITimer* aTimer)
|
||||
{
|
||||
NotifyErrorAndShutdown(nsIDOMGeoPositionError::TIMEOUT);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsGeolocationRequest::NotifyErrorAndShutdown(uint16_t aErrorCode)
|
||||
{
|
||||
MOZ_ASSERT(!mShutdown, "timeout after shutdown");
|
||||
|
||||
@ -358,13 +366,11 @@ nsGeolocationRequest::Notify(nsITimer* aTimer)
|
||||
mLocator->RemoveRequest(this);
|
||||
}
|
||||
|
||||
NotifyError(nsIDOMGeoPositionError::TIMEOUT);
|
||||
NotifyError(aErrorCode);
|
||||
|
||||
if (!mShutdown) {
|
||||
SetTimeoutTimer();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -1140,13 +1146,13 @@ Geolocation::NotifyError(uint16_t aErrorCode)
|
||||
}
|
||||
|
||||
for (uint32_t i = mPendingCallbacks.Length(); i > 0; i--) {
|
||||
mPendingCallbacks[i-1]->NotifyError(aErrorCode);
|
||||
RemoveRequest(mPendingCallbacks[i-1]);
|
||||
mPendingCallbacks[i-1]->NotifyErrorAndShutdown(aErrorCode);
|
||||
//NotifyErrorAndShutdown() removes the request from the array
|
||||
}
|
||||
|
||||
// notify everyone that is watching
|
||||
for (uint32_t i = 0; i < mWatchingCallbacks.Length(); i++) {
|
||||
mWatchingCallbacks[i]->NotifyError(aErrorCode);
|
||||
mWatchingCallbacks[i]->NotifyErrorAndShutdown(aErrorCode);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
@ -175,22 +175,30 @@ WifiGeoPositionProvider.prototype = {
|
||||
|
||||
// This is a background load
|
||||
|
||||
xhr.open("POST", url, true);
|
||||
try {
|
||||
xhr.open("POST", url, true);
|
||||
} catch (e) {
|
||||
triggerError();
|
||||
return;
|
||||
}
|
||||
xhr.setRequestHeader("Content-Type", "application/json; charset=UTF-8");
|
||||
xhr.responseType = "json";
|
||||
xhr.mozBackgroundRequest = true;
|
||||
xhr.channel.loadFlags = Ci.nsIChannel.LOAD_ANONYMOUS;
|
||||
xhr.onerror = function() {
|
||||
LOG("onerror: " + xhr);
|
||||
triggerError();
|
||||
};
|
||||
|
||||
xhr.onload = function() {
|
||||
LOG("gls returned status: " + xhr.status + " --> " + JSON.stringify(xhr.response));
|
||||
if (xhr.channel instanceof Ci.nsIHttpChannel && xhr.status != 200) {
|
||||
triggerError();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!xhr.response || !xhr.response.location) {
|
||||
triggerError();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -223,4 +231,8 @@ WifiGeoPositionProvider.prototype = {
|
||||
},
|
||||
};
|
||||
|
||||
function triggerError() {
|
||||
Cc["@mozilla.org/geolocation/service;1"].getService(Ci.nsIGeolocationUpdate)
|
||||
.notifyError(Ci.nsIDOMGeoPositionError.POSITION_UNAVAILABLE);
|
||||
}
|
||||
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([WifiGeoPositionProvider]);
|
||||
|
@ -51,6 +51,11 @@ function delay_geolocationProvider(delay, callback)
|
||||
SpecialPowers.pushPrefEnv({"set": [["geo.wifi.uri", "http://mochi.test:8888/tests/dom/tests/mochitest/geolocation/network_geolocation.sjs?delay=" + delay]]}, callback);
|
||||
}
|
||||
|
||||
function send404_geolocationProvider(callback)
|
||||
{
|
||||
SpecialPowers.pushPrefEnv({"set": [["geo.wifi.uri", "http://mochi.test:8888/tests/dom/tests/mochitest/geolocation/network_geolocation.sjs?action=send404"]]}, callback);
|
||||
}
|
||||
|
||||
function check_geolocation(location) {
|
||||
|
||||
ok(location, "Check to see if this location is non-null");
|
||||
|
@ -12,6 +12,7 @@ support-files =
|
||||
[test_cancelWatch.html]
|
||||
[test_clearWatch.html]
|
||||
[test_clearWatch_invalid.html]
|
||||
[test_errorcheck.html]
|
||||
[test_geolocation_is_undefined_when_pref_is_off.html]
|
||||
[test_handlerSpinsEventLoop.html]
|
||||
[test_manyCurrentConcurrent.html]
|
||||
|
@ -37,6 +37,7 @@ function handleRequest(request, response)
|
||||
var params = parseQueryString(request.queryString);
|
||||
|
||||
if (params.action == "stop-responding") {
|
||||
response.processAsync();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -64,6 +65,10 @@ function handleRequest(request, response)
|
||||
if ('delay' in params) {
|
||||
delay = params.delay;
|
||||
}
|
||||
if (params.action === "send404") {
|
||||
response.setStatusLine("1.0", 404, "Not Found");
|
||||
position = '';
|
||||
}
|
||||
timer = Components.classes["@mozilla.org/timer;1"].createInstance(Components.interfaces.nsITimer);
|
||||
timer.initWithCallback(function() {
|
||||
response.write(position);
|
||||
|
49
dom/tests/mochitest/geolocation/test_errorcheck.html
Normal file
49
dom/tests/mochitest/geolocation/test_errorcheck.html
Normal file
@ -0,0 +1,49 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=684722
|
||||
-->
|
||||
<head>
|
||||
<title>Test for ErrorChecking </title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="text/javascript" src="geolocation_common.js"></script>
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=684722">Mozilla Bug 684722</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
resume_geolocationProvider(function() {
|
||||
force_prompt(true, test1);
|
||||
});
|
||||
|
||||
function test1() {
|
||||
send404_geolocationProvider(test2);
|
||||
}
|
||||
|
||||
function errorCallback(error) {
|
||||
is(error.code,
|
||||
SpecialPowers.Ci.nsIDOMGeoPositionError.POSITION_UNAVAILABLE, "Geolocation error handler fired");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
function successCallback(position) {
|
||||
test2();
|
||||
}
|
||||
|
||||
function test2() {
|
||||
navigator.geolocation.getCurrentPosition(successCallback, errorCallback);
|
||||
}
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -77,10 +77,10 @@ interface CanvasRenderingContext2D {
|
||||
// NOT IMPLEMENTED void fill(Path path);
|
||||
void stroke();
|
||||
// NOT IMPLEMENTED void stroke(Path path);
|
||||
// NOT IMPLEMENTED void drawSystemFocusRing(Element element);
|
||||
// NOT IMPLEMENTED void drawSystemFocusRing(Path path, Element element);
|
||||
// NOT IMPLEMENTED boolean drawCustomFocusRing(Element element);
|
||||
// NOT IMPLEMENTED boolean drawCustomFocusRing(Path path, Element element);
|
||||
[Pref="canvas.focusring.enabled"] void drawSystemFocusRing(Element element);
|
||||
// NOT IMPLEMENTED void drawSystemFocusRing(Path path, HTMLElement element);
|
||||
[Pref="canvas.focusring.enabled"] boolean drawCustomFocusRing(Element element);
|
||||
// NOT IMPLEMENTED boolean drawCustomFocusRing(Path path, HTMLElement element);
|
||||
// NOT IMPLEMENTED void scrollPathIntoView();
|
||||
// NOT IMPLEMENTED void scrollPathIntoView(Path path);
|
||||
void clip(optional CanvasWindingRule winding = "nonzero");
|
||||
|
@ -830,6 +830,15 @@ interface WebGLExtensionTextureFilterAnisotropic
|
||||
const GLenum MAX_TEXTURE_MAX_ANISOTROPY_EXT = 0x84FF;
|
||||
};
|
||||
|
||||
[NoInterfaceObject]
|
||||
interface WebGLExtensionSRGB
|
||||
{
|
||||
const GLenum SRGB_EXT = 0x8C40;
|
||||
const GLenum SRGB_ALPHA_EXT = 0x8C42;
|
||||
const GLenum SRGB8_ALPHA8_EXT = 0x8C43;
|
||||
const GLenum FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT = 0x8210;
|
||||
};
|
||||
|
||||
[NoInterfaceObject]
|
||||
interface WebGLExtensionStandardDerivatives {
|
||||
const GLenum FRAGMENT_SHADER_DERIVATIVE_HINT_OES = 0x8B8B;
|
||||
|
@ -74,23 +74,19 @@ struct NativeFont {
|
||||
* mCompositionOp - The operator that indicates how the source and destination
|
||||
* patterns are blended.
|
||||
* mAntiAliasMode - The AntiAlias mode used for this drawing operation.
|
||||
* mSnapping - Whether this operation is snapped to pixel boundaries.
|
||||
*/
|
||||
struct DrawOptions {
|
||||
DrawOptions(Float aAlpha = 1.0f,
|
||||
CompositionOp aCompositionOp = OP_OVER,
|
||||
AntialiasMode aAntialiasMode = AA_DEFAULT,
|
||||
Snapping aSnapping = SNAP_NONE)
|
||||
AntialiasMode aAntialiasMode = AA_DEFAULT)
|
||||
: mAlpha(aAlpha)
|
||||
, mCompositionOp(aCompositionOp)
|
||||
, mAntialiasMode(aAntialiasMode)
|
||||
, mSnapping(aSnapping)
|
||||
{}
|
||||
|
||||
Float mAlpha;
|
||||
CompositionOp mCompositionOp : 8;
|
||||
AntialiasMode mAntialiasMode : 3;
|
||||
Snapping mSnapping : 1;
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -296,8 +296,6 @@ struct AutoPaintSetup {
|
||||
mPaint.setAntiAlias(false);
|
||||
}
|
||||
|
||||
MOZ_ASSERT(aOptions.mSnapping == SNAP_NONE, "Pixel snapping not supported yet!");
|
||||
|
||||
// TODO: We could skip the temporary for operator_source and just
|
||||
// clear the clip rect. The other operators would be harder
|
||||
// but could be worth it to skip pushing a group.
|
||||
|
@ -104,7 +104,6 @@ enum CompositionOp { OP_OVER, OP_ADD, OP_ATOP, OP_OUT, OP_IN, OP_SOURCE, OP_DEST
|
||||
enum ExtendMode { EXTEND_CLAMP, EXTEND_REPEAT, EXTEND_REFLECT };
|
||||
enum FillRule { FILL_WINDING, FILL_EVEN_ODD };
|
||||
enum AntialiasMode { AA_NONE, AA_GRAY, AA_SUBPIXEL, AA_DEFAULT };
|
||||
enum Snapping { SNAP_NONE, SNAP_ALIGNED };
|
||||
enum Filter { FILTER_GOOD, FILTER_LINEAR, FILTER_POINT };
|
||||
enum PatternType { PATTERN_COLOR, PATTERN_SURFACE, PATTERN_LINEAR_GRADIENT, PATTERN_RADIAL_GRADIENT };
|
||||
enum JoinStyle { JOIN_BEVEL, JOIN_ROUND, JOIN_MITER, JOIN_MITER_OR_BEVEL };
|
||||
|
@ -116,6 +116,10 @@ static const char *sExtensionNames[] = {
|
||||
"GL_EXT_transform_feedback",
|
||||
"GL_NV_transform_feedback",
|
||||
"GL_ANGLE_depth_texture",
|
||||
"GL_EXT_sRGB",
|
||||
"GL_EXT_texture_sRGB",
|
||||
"GL_ARB_framebuffer_sRGB",
|
||||
"GL_EXT_framebuffer_sRGB",
|
||||
"GL_KHR_debug",
|
||||
nullptr
|
||||
};
|
||||
@ -599,7 +603,7 @@ GLContext::InitWithPrefix(const char *prefix, bool trygl)
|
||||
if (Renderer() == RendererAdrenoTM320) {
|
||||
MarkUnsupported(GLFeature::standard_derivatives);
|
||||
}
|
||||
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
// The Mac Nvidia driver, for versions up to and including 10.8, don't seem
|
||||
// to properly support this. See 814839
|
||||
@ -1204,6 +1208,29 @@ GLContext::CanUploadSubTextures()
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
GLContext::CanReadSRGBFromFBOTexture()
|
||||
{
|
||||
if (!mWorkAroundDriverBugs)
|
||||
return true;
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
// Bug 843668:
|
||||
// MacOSX 10.6 reports to support EXT_framebuffer_sRGB and
|
||||
// EXT_texture_sRGB but fails to convert from sRGB to linear
|
||||
// when writing to an sRGB texture attached to an FBO.
|
||||
SInt32 major, minor;
|
||||
::Gestalt(gestaltSystemVersionMajor, &major);
|
||||
::Gestalt(gestaltSystemVersionMinor, &minor);
|
||||
if (major == 10 && minor <= 6) {
|
||||
return false;
|
||||
}
|
||||
#endif // XP_MACOSX
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool GLContext::sPowerOfTwoForced = false;
|
||||
bool GLContext::sPowerOfTwoPrefCached = false;
|
||||
|
||||
|
@ -99,6 +99,7 @@ namespace GLFeature {
|
||||
packed_depth_stencil,
|
||||
query_objects,
|
||||
robustness,
|
||||
sRGB,
|
||||
standard_derivatives,
|
||||
texture_float,
|
||||
texture_float_linear,
|
||||
@ -395,6 +396,10 @@ public:
|
||||
EXT_transform_feedback,
|
||||
NV_transform_feedback,
|
||||
ANGLE_depth_texture,
|
||||
EXT_sRGB,
|
||||
EXT_texture_sRGB,
|
||||
ARB_framebuffer_sRGB,
|
||||
EXT_framebuffer_sRGB,
|
||||
KHR_debug,
|
||||
Extensions_Max,
|
||||
Extensions_End
|
||||
@ -2448,6 +2453,7 @@ public:
|
||||
}
|
||||
|
||||
bool CanUploadSubTextures();
|
||||
bool CanReadSRGBFromFBOTexture();
|
||||
|
||||
static void PlatformStartup();
|
||||
|
||||
|
@ -195,7 +195,7 @@ static const FeatureInfo sFeatureInfoArr[] = {
|
||||
/*
|
||||
* XXX_occlusion_query_boolean provide ANY_SAMPLES_PASSED_CONSERVATIVE,
|
||||
* but EXT_occlusion_query_boolean is only a OpenGL ES extension. But
|
||||
* it is supported on desktop if ARB_ES3_compatibility because
|
||||
* it is supported on desktop if ARB_ES3_compatibility because
|
||||
* EXT_occlusion_query_boolean (added in OpenGL ES 3.0).
|
||||
*/
|
||||
},
|
||||
@ -249,6 +249,15 @@ static const FeatureInfo sFeatureInfoArr[] = {
|
||||
GLContext::Extensions_End
|
||||
}
|
||||
},
|
||||
{
|
||||
"sRGB",
|
||||
300, // OpenGL version
|
||||
300, // OpenGL ES version
|
||||
{
|
||||
GLContext::EXT_sRGB,
|
||||
GLContext::Extensions_End
|
||||
}
|
||||
},
|
||||
{
|
||||
"standard_derivatives",
|
||||
200, // OpenGL version
|
||||
@ -387,6 +396,18 @@ GLContext::InitFeatures()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Bug 843668: Work around limitation of the feature system.
|
||||
// For sRGB support under OpenGL to match OpenGL ES spec, check for both
|
||||
// EXT_texture_sRGB and EXT_framebuffer_sRGB is required.
|
||||
const bool aresRGBExtensionsAvailable =
|
||||
IsExtensionSupported(EXT_texture_sRGB) &&
|
||||
(IsExtensionSupported(ARB_framebuffer_sRGB) ||
|
||||
IsExtensionSupported(EXT_framebuffer_sRGB));
|
||||
|
||||
mAvailableFeatures[GLFeature::sRGB] =
|
||||
aresRGBExtensionsAvailable &&
|
||||
CanReadSRGBFromFBOTexture();
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -501,6 +501,7 @@ CompositorParent::ScheduleComposition()
|
||||
void
|
||||
CompositorParent::Composite()
|
||||
{
|
||||
profiler_tracing("Paint", "Composite", TRACING_INTERVAL_START);
|
||||
PROFILER_LABEL("CompositorParent", "Composite");
|
||||
NS_ABORT_IF_FALSE(CompositorThreadID() == PlatformThread::CurrentId(),
|
||||
"Composite can only be called on the compositor thread");
|
||||
|
@ -123,7 +123,7 @@ if os_win:
|
||||
'src/chrome/common/process_watcher_win.cc',
|
||||
'src/chrome/common/transport_dib_win.cc',
|
||||
]
|
||||
else:
|
||||
elif not CONFIG['MOZ_NATIVE_LIBEVENT']:
|
||||
SOURCES += [
|
||||
'src/third_party/libevent/buffer.c',
|
||||
'src/third_party/libevent/bufferevent.c',
|
||||
@ -203,9 +203,10 @@ if os_macosx:
|
||||
'src/chrome/common/chrome_paths_mac.mm',
|
||||
'src/chrome/common/mach_ipc_mac.mm',
|
||||
]
|
||||
SOURCES += [
|
||||
'src/third_party/libevent/kqueue.c',
|
||||
]
|
||||
if not CONFIG['MOZ_NATIVE_LIBEVENT']:
|
||||
SOURCES += [
|
||||
'src/third_party/libevent/kqueue.c',
|
||||
]
|
||||
|
||||
if os_linux:
|
||||
SOURCES += [
|
||||
@ -227,13 +228,14 @@ if os_linux:
|
||||
GENERATED_SOURCES += [
|
||||
'src/base/moc_message_pump_qt.cc',
|
||||
]
|
||||
if CONFIG['OS_TARGET'] != 'Android':
|
||||
if not CONFIG['MOZ_NATIVE_LIBEVENT']:
|
||||
if CONFIG['OS_TARGET'] != 'Android':
|
||||
SOURCES += [
|
||||
'src/third_party/libevent/epoll_sub.c',
|
||||
]
|
||||
SOURCES += [
|
||||
'src/third_party/libevent/epoll_sub.c',
|
||||
'src/third_party/libevent/epoll.c',
|
||||
]
|
||||
SOURCES += [
|
||||
'src/third_party/libevent/epoll.c',
|
||||
]
|
||||
|
||||
if os_bsd:
|
||||
SOURCES += [
|
||||
@ -259,9 +261,10 @@ if os_bsd:
|
||||
GENERATED_SOURCES += [
|
||||
'src/base/moc_message_pump_qt.cc',
|
||||
]
|
||||
SOURCES += [
|
||||
'src/third_party/libevent/kqueue.c',
|
||||
]
|
||||
if not CONFIG['MOZ_NATIVE_LIBEVENT']:
|
||||
SOURCES += [
|
||||
'src/third_party/libevent/kqueue.c',
|
||||
]
|
||||
|
||||
if CONFIG['_MSC_VER']:
|
||||
SOURCES += [
|
||||
|
@ -8,6 +8,7 @@
|
||||
#define js_RootingAPI_h
|
||||
|
||||
#include "mozilla/GuardObjects.h"
|
||||
#include "mozilla/LinkedList.h"
|
||||
#include "mozilla/NullPtr.h"
|
||||
#include "mozilla/TypeTraits.h"
|
||||
|
||||
@ -143,6 +144,7 @@ struct Cell;
|
||||
namespace JS {
|
||||
|
||||
template <typename T> class Rooted;
|
||||
template <typename T> class PersistentRooted;
|
||||
|
||||
/* This is exposing internal state of the GC for inlining purposes. */
|
||||
JS_FRIEND_API(bool) isGCEnabled();
|
||||
@ -440,6 +442,11 @@ class MOZ_NONHEAP_CLASS Handle : public js::HandleBase<T>
|
||||
Handle(const Rooted<S> &root,
|
||||
typename mozilla::EnableIf<mozilla::IsConvertible<S, T>::value, int>::Type dummy = 0);
|
||||
|
||||
template <typename S>
|
||||
inline
|
||||
Handle(const PersistentRooted<S> &root,
|
||||
typename mozilla::EnableIf<mozilla::IsConvertible<S, T>::value, int>::Type dummy = 0);
|
||||
|
||||
/* Construct a read only handle from a mutable handle. */
|
||||
template <typename S>
|
||||
inline
|
||||
@ -484,6 +491,7 @@ class MOZ_STACK_CLASS MutableHandle : public js::MutableHandleBase<T>
|
||||
{
|
||||
public:
|
||||
inline MutableHandle(Rooted<T> *root);
|
||||
inline MutableHandle(PersistentRooted<T> *root);
|
||||
MutableHandle(int) MOZ_DELETE;
|
||||
#ifdef MOZ_HAVE_CXX11_NULLPTR
|
||||
MutableHandle(decltype(nullptr)) MOZ_DELETE;
|
||||
@ -797,13 +805,6 @@ template <>
|
||||
class Rooted<JSStableString *>;
|
||||
#endif
|
||||
|
||||
typedef Rooted<JSObject*> RootedObject;
|
||||
typedef Rooted<JSFunction*> RootedFunction;
|
||||
typedef Rooted<JSScript*> RootedScript;
|
||||
typedef Rooted<JSString*> RootedString;
|
||||
typedef Rooted<jsid> RootedId;
|
||||
typedef Rooted<JS::Value> RootedValue;
|
||||
|
||||
} /* namespace JS */
|
||||
|
||||
namespace js {
|
||||
@ -1024,6 +1025,14 @@ Handle<T>::Handle(const Rooted<S> &root,
|
||||
ptr = reinterpret_cast<const T *>(root.address());
|
||||
}
|
||||
|
||||
template <typename T> template <typename S>
|
||||
inline
|
||||
Handle<T>::Handle(const PersistentRooted<S> &root,
|
||||
typename mozilla::EnableIf<mozilla::IsConvertible<S, T>::value, int>::Type dummy)
|
||||
{
|
||||
ptr = reinterpret_cast<const T *>(root.address());
|
||||
}
|
||||
|
||||
template <typename T> template <typename S>
|
||||
inline
|
||||
Handle<T>::Handle(MutableHandle<S> &root,
|
||||
@ -1041,6 +1050,123 @@ MutableHandle<T>::MutableHandle(Rooted<T> *root)
|
||||
ptr = root->address();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline
|
||||
MutableHandle<T>::MutableHandle(PersistentRooted<T> *root)
|
||||
{
|
||||
static_assert(sizeof(MutableHandle<T>) == sizeof(T *),
|
||||
"MutableHandle must be binary compatible with T*.");
|
||||
ptr = root->address();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* A copyable, assignable global GC root type with arbitrary lifetime, an
|
||||
* infallible constructor, and automatic unrooting on destruction.
|
||||
*
|
||||
* These roots can be used in heap-allocated data structures, so they are not
|
||||
* associated with any particular JSContext or stack. They are registered with
|
||||
* the JSRuntime itself, without locking, so they require a full JSContext to be
|
||||
* constructed, not one of its more restricted superclasses.
|
||||
*
|
||||
* Note that you must not use an PersistentRooted in an object owned by a JS
|
||||
* object:
|
||||
*
|
||||
* Whenever one object whose lifetime is decided by the GC refers to another
|
||||
* such object, that edge must be traced only if the owning JS object is traced.
|
||||
* This applies not only to JS objects (which obviously are managed by the GC)
|
||||
* but also to C++ objects owned by JS objects.
|
||||
*
|
||||
* If you put a PersistentRooted in such a C++ object, that is almost certainly
|
||||
* a leak. When a GC begins, the referent of the PersistentRooted is treated as
|
||||
* live, unconditionally (because a PersistentRooted is a *root*), even if the
|
||||
* JS object that owns it is unreachable. If there is any path from that
|
||||
* referent back to the JS object, then the C++ object containing the
|
||||
* PersistentRooted will not be destructed, and the whole blob of objects will
|
||||
* not be freed, even if there are no references to them from the outside.
|
||||
*
|
||||
* In the context of Firefox, this is a severe restriction: almost everything in
|
||||
* Firefox is owned by some JS object or another, so using PersistentRooted in
|
||||
* such objects would introduce leaks. For these kinds of edges, Heap<T> or
|
||||
* TenuredHeap<T> would be better types. It's up to the implementor of the type
|
||||
* containing Heap<T> or TenuredHeap<T> members to make sure their referents get
|
||||
* marked when the object itself is marked.
|
||||
*/
|
||||
template<typename T>
|
||||
class PersistentRooted : public mozilla::LinkedListElement<PersistentRooted<T> > {
|
||||
typedef mozilla::LinkedList<PersistentRooted> List;
|
||||
typedef mozilla::LinkedListElement<PersistentRooted> Element;
|
||||
|
||||
void registerWithRuntime(JSRuntime *rt) {
|
||||
JS::shadow::Runtime *srt = JS::shadow::Runtime::asShadowRuntime(rt);
|
||||
srt->getPersistentRootedList<T>().insertBack(this);
|
||||
}
|
||||
|
||||
public:
|
||||
PersistentRooted(JSContext *cx) : ptr(js::GCMethods<T>::initial())
|
||||
{
|
||||
registerWithRuntime(js::GetRuntime(cx));
|
||||
}
|
||||
|
||||
PersistentRooted(JSContext *cx, T initial) : ptr(initial)
|
||||
{
|
||||
registerWithRuntime(js::GetRuntime(cx));
|
||||
}
|
||||
|
||||
PersistentRooted(JSRuntime *rt) : ptr(js::GCMethods<T>::initial())
|
||||
{
|
||||
registerWithRuntime(rt);
|
||||
}
|
||||
|
||||
PersistentRooted(JSRuntime *rt, T initial) : ptr(initial)
|
||||
{
|
||||
registerWithRuntime(rt);
|
||||
}
|
||||
|
||||
PersistentRooted(PersistentRooted &rhs) : ptr(rhs.ptr)
|
||||
{
|
||||
/*
|
||||
* Copy construction takes advantage of the fact that the original
|
||||
* is already inserted, and simply adds itself to whatever list the
|
||||
* original was on - no JSRuntime pointer needed.
|
||||
*/
|
||||
rhs.setNext(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* Important: Return a reference here so passing a Rooted<T> to
|
||||
* something that takes a |const T&| is not a GC hazard.
|
||||
*/
|
||||
operator const T&() const { return ptr; }
|
||||
T operator->() const { return ptr; }
|
||||
T *address() { return &ptr; }
|
||||
const T *address() const { return &ptr; }
|
||||
T &get() { return ptr; }
|
||||
const T &get() const { return ptr; }
|
||||
|
||||
T &operator=(T value) {
|
||||
JS_ASSERT(!js::GCMethods<T>::poisoned(value));
|
||||
ptr = value;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
T &operator=(const PersistentRooted &value) {
|
||||
ptr = value;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void set(T value) {
|
||||
JS_ASSERT(!js::GCMethods<T>::poisoned(value));
|
||||
ptr = value;
|
||||
}
|
||||
|
||||
bool operator!=(const T &other) const { return ptr != other; }
|
||||
bool operator==(const T &other) const { return ptr == other; }
|
||||
|
||||
private:
|
||||
T ptr;
|
||||
};
|
||||
|
||||
} /* namespace JS */
|
||||
|
||||
namespace js {
|
||||
|
@ -57,6 +57,8 @@ namespace JS {
|
||||
class Value;
|
||||
template <typename T> class Handle;
|
||||
template <typename T> class MutableHandle;
|
||||
template <typename T> class Rooted;
|
||||
template <typename T> class PersistentRooted;
|
||||
|
||||
typedef Handle<JSFunction*> HandleFunction;
|
||||
typedef Handle<jsid> HandleId;
|
||||
@ -72,6 +74,20 @@ typedef MutableHandle<JSScript*> MutableHandleScript;
|
||||
typedef MutableHandle<JSString*> MutableHandleString;
|
||||
typedef MutableHandle<Value> MutableHandleValue;
|
||||
|
||||
typedef Rooted<JSObject*> RootedObject;
|
||||
typedef Rooted<JSFunction*> RootedFunction;
|
||||
typedef Rooted<JSScript*> RootedScript;
|
||||
typedef Rooted<JSString*> RootedString;
|
||||
typedef Rooted<jsid> RootedId;
|
||||
typedef Rooted<JS::Value> RootedValue;
|
||||
|
||||
typedef PersistentRooted<JSFunction*> PersistentRootedFunction;
|
||||
typedef PersistentRooted<jsid> PersistentRootedId;
|
||||
typedef PersistentRooted<JSObject*> PersistentRootedObject;
|
||||
typedef PersistentRooted<JSScript*> PersistentRootedScript;
|
||||
typedef PersistentRooted<JSString*> PersistentRootedString;
|
||||
typedef PersistentRooted<Value> PersistentRootedValue;
|
||||
|
||||
} // namespace JS
|
||||
|
||||
#endif /* js_TypeDecls_h */
|
||||
|
@ -94,6 +94,14 @@ using JS::RootedScript;
|
||||
using JS::RootedString;
|
||||
using JS::RootedValue;
|
||||
|
||||
using JS::PersistentRooted;
|
||||
using JS::PersistentRootedFunction;
|
||||
using JS::PersistentRootedId;
|
||||
using JS::PersistentRootedObject;
|
||||
using JS::PersistentRootedScript;
|
||||
using JS::PersistentRootedString;
|
||||
using JS::PersistentRootedValue;
|
||||
|
||||
using JS::Handle;
|
||||
using JS::HandleFunction;
|
||||
using JS::HandleId;
|
||||
|
@ -95,6 +95,7 @@ oddly_ordered_inclnames = set([
|
||||
'ctypes/typedefs.h', # Included multiple times in the body of ctypes/CTypes.h
|
||||
'jsautokw.h', # Included in the body of frontend/TokenStream.h
|
||||
'jswin.h', # Must be #included before <psapi.h>
|
||||
'machine/endian.h', # Must be included after <sys/types.h> on BSD
|
||||
'winbase.h', # Must precede other system headers(?)
|
||||
'windef.h' # Must precede other system headers(?)
|
||||
])
|
||||
|
@ -195,9 +195,8 @@ MOZ_PSEUDO_DERECURSE :=
|
||||
endif
|
||||
endif
|
||||
|
||||
# Disable MOZ_PSEUDO_DERECURSE on the second PGO pass until it's widely
|
||||
# tested.
|
||||
ifdef MOZ_PROFILE_USE
|
||||
# Disable MOZ_PSEUDO_DERECURSE on PGO builds until it's fixed.
|
||||
ifneq (,$(MOZ_PROFILE_USE)$(MOZ_PROFILE_GENERATE))
|
||||
MOZ_PSEUDO_DERECURSE :=
|
||||
endif
|
||||
|
||||
|
@ -1331,7 +1331,7 @@ endif
|
||||
endif
|
||||
endif
|
||||
|
||||
libs realchrome:: $(CHROME_DEPS) $(FINAL_TARGET)/chrome
|
||||
libs realchrome:: $(FINAL_TARGET)/chrome
|
||||
$(call py_action,jar_maker,\
|
||||
$(QUIET) -j $(FINAL_TARGET)/chrome \
|
||||
$(MAKE_JARS_FLAGS) $(XULPPFLAGS) $(DEFINES) $(ACDEFINES) \
|
||||
|
@ -49,6 +49,9 @@ ffi_call_SYSV:
|
||||
movl 16(%ebp),%ecx
|
||||
subl %ecx,%esp
|
||||
|
||||
/* Align the stack pointer to 16-bytes */
|
||||
andl $0xfffffff0, %esp
|
||||
|
||||
movl %esp,%eax
|
||||
|
||||
/* Place all of the ffi_prep_args in position */
|
||||
|
31
js/src/ctypes/patches-libffi/07-bug-928381.patch
Normal file
31
js/src/ctypes/patches-libffi/07-bug-928381.patch
Normal file
@ -0,0 +1,31 @@
|
||||
# HG changeset patch
|
||||
# User Landry Breuil <landry@openbsd.org>
|
||||
# Date 1382105758 -7200
|
||||
# Fri Oct 18 16:15:58 2013 +0200
|
||||
# Node ID 5f82dae8c495a7fddf5ed935eb2a8be7f47b9bd8
|
||||
# Parent d50df2233e95f4d45b35eddbfbe84bcdda6a11e2
|
||||
Bug 928381 - ctypes/libffi: Fix stack alignment on *BSD/i386 r=glandium
|
||||
|
||||
diff --git a/js/src/ctypes/libffi/src/x86/freebsd.S b/js/src/ctypes/libffi/src/x86/freebsd.S
|
||||
--- a/js/src/ctypes/libffi/src/x86/freebsd.S
|
||||
+++ b/js/src/ctypes/libffi/src/x86/freebsd.S
|
||||
@@ -44,16 +44,19 @@ ffi_call_SYSV:
|
||||
pushl %ebp
|
||||
.LCFI0:
|
||||
movl %esp,%ebp
|
||||
.LCFI1:
|
||||
/* Make room for all of the new args. */
|
||||
movl 16(%ebp),%ecx
|
||||
subl %ecx,%esp
|
||||
|
||||
+ /* Align the stack pointer to 16-bytes */
|
||||
+ andl $0xfffffff0, %esp
|
||||
+
|
||||
movl %esp,%eax
|
||||
|
||||
/* Place all of the ffi_prep_args in position */
|
||||
pushl 12(%ebp)
|
||||
pushl %eax
|
||||
call *8(%ebp)
|
||||
|
||||
/* Return stack to previous state and call the function */
|
@ -126,7 +126,7 @@ FoldBinaryNumeric(ExclusiveContext *cx, JSOp op, ParseNode *pn1, ParseNode *pn2,
|
||||
i = ToInt32(d);
|
||||
j = ToInt32(d2);
|
||||
j &= 31;
|
||||
d = (op == JSOP_LSH) ? i << j : i >> j;
|
||||
d = int32_t((op == JSOP_LSH) ? uint32_t(i) << j : i >> j);
|
||||
break;
|
||||
|
||||
case JSOP_URSH:
|
||||
|
@ -14,6 +14,9 @@
|
||||
namespace js {
|
||||
namespace gc {
|
||||
|
||||
void
|
||||
MarkPersistentRootedChains(JSTracer *trc);
|
||||
|
||||
void
|
||||
MarkRuntime(JSTracer *trc, bool useSavedRoots = false);
|
||||
|
||||
|
@ -617,6 +617,44 @@ JSPropertyDescriptor::trace(JSTracer *trc)
|
||||
}
|
||||
}
|
||||
|
||||
// Mark a chain of PersistentRooted pointers that might be null.
|
||||
template<typename Referent>
|
||||
static void
|
||||
MarkPersistentRootedChain(JSTracer *trc,
|
||||
mozilla::LinkedList<PersistentRooted<Referent *> > &list,
|
||||
void (*marker)(JSTracer *trc, Referent **ref, const char *name),
|
||||
const char *name)
|
||||
{
|
||||
for (PersistentRooted<Referent *> *r = list.getFirst();
|
||||
r != nullptr;
|
||||
r = r->getNext())
|
||||
{
|
||||
if (r->get())
|
||||
marker(trc, r->address(), name);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
js::gc::MarkPersistentRootedChains(JSTracer *trc)
|
||||
{
|
||||
JSRuntime *rt = trc->runtime;
|
||||
|
||||
MarkPersistentRootedChain(trc, rt->functionPersistentRooteds, &MarkObjectRoot,
|
||||
"PersistentRooted<JSFunction *>");
|
||||
MarkPersistentRootedChain(trc, rt->objectPersistentRooteds, &MarkObjectRoot,
|
||||
"PersistentRooted<JSObject *>");
|
||||
MarkPersistentRootedChain(trc, rt->scriptPersistentRooteds, &MarkScriptRoot,
|
||||
"PersistentRooted<JSScript *>");
|
||||
MarkPersistentRootedChain(trc, rt->stringPersistentRooteds, &MarkStringRoot,
|
||||
"PersistentRooted<JSString *>");
|
||||
|
||||
// Mark the PersistentRooted chains of types that are never null.
|
||||
for (JS::PersistentRootedId *r = rt->idPersistentRooteds.getFirst(); r != nullptr; r = r->getNext())
|
||||
MarkIdRoot(trc, r->address(), "PersistentRooted<jsid>");
|
||||
for (JS::PersistentRootedValue *r = rt->valuePersistentRooteds.getFirst(); r != nullptr; r = r->getNext())
|
||||
MarkValueRoot(trc, r->address(), "PersistentRooted<Value>");
|
||||
}
|
||||
|
||||
void
|
||||
js::gc::MarkRuntime(JSTracer *trc, bool useSavedRoots)
|
||||
{
|
||||
@ -661,6 +699,8 @@ js::gc::MarkRuntime(JSTracer *trc, bool useSavedRoots)
|
||||
}
|
||||
}
|
||||
|
||||
MarkPersistentRootedChains(trc);
|
||||
|
||||
if (rt->scriptAndCountsVector) {
|
||||
ScriptAndCountsVector &vec = *rt->scriptAndCountsVector;
|
||||
for (size_t i = 0; i < vec.length(); i++)
|
||||
|
@ -11,3 +11,19 @@ assertIteratorNext(it, 1000);
|
||||
assertIteratorNext(it, 1);
|
||||
assertIteratorNext(it, 2000);
|
||||
assertIteratorDone(it, undefined);
|
||||
|
||||
// test that .keys() and .entries() have the same behaviour
|
||||
|
||||
arr = [0, 1, 2];
|
||||
var ki = arr.keys();
|
||||
var ei = arr.entries();
|
||||
arr[0] = 1000;
|
||||
arr[2] = 2000;
|
||||
assertIteratorNext(ki, 0);
|
||||
assertIteratorNext(ei, [0, 1000]);
|
||||
assertIteratorNext(ki, 1);
|
||||
assertIteratorNext(ei, [1, 1]);
|
||||
assertIteratorNext(ki, 2);
|
||||
assertIteratorNext(ei, [2, 2000]);
|
||||
assertIteratorDone(ki, undefined);
|
||||
assertIteratorDone(ei, undefined);
|
||||
|
11
js/src/jit-test/tests/for-of/array-iterator-empty.js
Normal file
11
js/src/jit-test/tests/for-of/array-iterator-empty.js
Normal file
@ -0,0 +1,11 @@
|
||||
// Array.keys() and .entries() on an empty array produce empty iterators
|
||||
|
||||
var arr = [];
|
||||
var ki = arr.keys(), ei = arr.entries();
|
||||
var p = Object.getPrototypeOf(ki);
|
||||
assertEq(Object.getPrototypeOf(ei), p);
|
||||
|
||||
for (let k of ki)
|
||||
throw "FAIL";
|
||||
for (let [k, v] of ei)
|
||||
throw "FAIL";
|
@ -6,9 +6,16 @@ load(libdir + "iteration.js");
|
||||
|
||||
function test(obj) {
|
||||
var it = Array.prototype[std_iterator].call(obj);
|
||||
for (var i = 0; i < (obj.length >>> 0); i++)
|
||||
var ki = Array.prototype.keys.call(obj);
|
||||
var ei = Array.prototype.entries.call(obj);
|
||||
for (var i = 0; i < (obj.length >>> 0); i++) {
|
||||
assertIteratorNext(it, obj[i]);
|
||||
assertIteratorNext(ki, i);
|
||||
assertIteratorNext(ei, [i, obj[i]]);
|
||||
}
|
||||
assertIteratorDone(it, undefined);
|
||||
assertIteratorDone(ki, undefined);
|
||||
assertIteratorDone(ei, undefined);
|
||||
}
|
||||
|
||||
test({length: 0});
|
||||
|
@ -5,10 +5,22 @@ load(libdir + "iteration.js");
|
||||
|
||||
var arr = [0, 1];
|
||||
var it = arr[std_iterator]();
|
||||
var ki = arr.keys();
|
||||
var ei = arr.entries();
|
||||
assertIteratorNext(it, 0);
|
||||
assertIteratorNext(ki, 0);
|
||||
assertIteratorNext(ei, [0, 0]);
|
||||
assertIteratorNext(it, 1);
|
||||
assertIteratorNext(ki, 1);
|
||||
assertIteratorNext(ei, [1, 1]);
|
||||
arr[2] = 2;
|
||||
arr.length = 4;
|
||||
assertIteratorNext(it, 2);
|
||||
assertIteratorNext(ki, 2);
|
||||
assertIteratorNext(ei, [2, 2]);
|
||||
assertIteratorNext(it, undefined);
|
||||
assertIteratorNext(ki, 3);
|
||||
assertIteratorNext(ei, [3, undefined]);
|
||||
assertIteratorDone(it, undefined);
|
||||
assertIteratorDone(ki, undefined);
|
||||
assertIteratorDone(ei, undefined);
|
||||
|
16
js/src/jit-test/tests/for-of/array-iterator-keys-entries.js
Normal file
16
js/src/jit-test/tests/for-of/array-iterator-keys-entries.js
Normal file
@ -0,0 +1,16 @@
|
||||
// array.keys() returns an iterator over the index of elements
|
||||
// and array.entries() returns an iterator that yields pairs [index, element].
|
||||
|
||||
load(libdir + "iteration.js");
|
||||
|
||||
var data = [1, 2, 3, "abc"];
|
||||
|
||||
var ki = data.keys();
|
||||
for (var i = 0; i < data.length; i++)
|
||||
assertIteratorResult(ki.next(), i, false);
|
||||
assertIteratorDone(ki, undefined);
|
||||
|
||||
var ei = data.entries();
|
||||
for (var i = 0; i < data.length; i++)
|
||||
assertIteratorResult(ei.next(), [i, data[i]], false);
|
||||
assertIteratorDone(ei, undefined);
|
@ -6,4 +6,6 @@ load(libdir + "iteration.js");
|
||||
for (var v of [undefined, null]) {
|
||||
// ES6 draft 2013-09-05 section 22.1.5.1.
|
||||
assertThrowsInstanceOf(function () { Array.prototype[std_iterator].call(v); }, TypeError);
|
||||
assertThrowsInstanceOf(function () { Array.prototype.keys.call(v); }, TypeError);
|
||||
assertThrowsInstanceOf(function () { Array.prototype.entries.call(v); }, TypeError);
|
||||
}
|
||||
|
@ -4,7 +4,8 @@ load(libdir + "asserts.js");
|
||||
load(libdir + "iteration.js");
|
||||
|
||||
var s = '';
|
||||
var it = Array.prototype[std_iterator].call(Proxy.create({
|
||||
|
||||
var proxyObj = {
|
||||
get: function (recipient, name) {
|
||||
if (name == 'length') {
|
||||
s += 'L';
|
||||
@ -14,7 +15,9 @@ var it = Array.prototype[std_iterator].call(Proxy.create({
|
||||
return name;
|
||||
}
|
||||
}
|
||||
}));
|
||||
};
|
||||
|
||||
var it = Array.prototype[std_iterator].call(Proxy.create(proxyObj));
|
||||
|
||||
assertIteratorNext(it, "0");
|
||||
s += ' ';
|
||||
@ -22,3 +25,23 @@ assertIteratorNext(it, "1");
|
||||
s += ' ';
|
||||
assertIteratorDone(it, undefined);
|
||||
assertEq(s, "L0 L1 L");
|
||||
|
||||
s = '';
|
||||
var ki = Array.prototype.keys.call(Proxy.create(proxyObj));
|
||||
|
||||
assertIteratorNext(ki, 0);
|
||||
s += ' ';
|
||||
assertIteratorNext(ki, 1);
|
||||
s += ' ';
|
||||
assertIteratorDone(ki, undefined);
|
||||
assertEq(s, "L L L");
|
||||
|
||||
s = '';
|
||||
var ei = Array.prototype.entries.call(Proxy.create(proxyObj));
|
||||
|
||||
assertIteratorNext(ei, [0, "0"]);
|
||||
s += ' ';
|
||||
assertIteratorNext(ei, [1, "1"]);
|
||||
s += ' ';
|
||||
assertIteratorDone(ei, undefined);
|
||||
assertEq(s, "L0 L1 L");
|
||||
|
@ -5,7 +5,16 @@ load(libdir + "iteration.js");
|
||||
|
||||
var arr = [0, 1, 2];
|
||||
var it = arr[std_iterator]();
|
||||
var ki = arr.keys();
|
||||
var ei = arr.entries();
|
||||
|
||||
assertIteratorNext(it, 0);
|
||||
assertIteratorNext(it, 1);
|
||||
assertIteratorNext(ki, 0);
|
||||
assertIteratorNext(ki, 1);
|
||||
assertIteratorNext(ei, [0, 0]);
|
||||
assertIteratorNext(ei, [1, 1]);
|
||||
arr.length = 1;
|
||||
assertIteratorDone(it, undefined);
|
||||
assertIteratorDone(ki, undefined);
|
||||
assertIteratorDone(ei, undefined);
|
||||
|
@ -4,6 +4,10 @@ load(libdir + "iteration.js");
|
||||
|
||||
var proto = Object.getPrototypeOf([][std_iterator]());
|
||||
assertEq(Object.getPrototypeOf(proto), Iterator.prototype);
|
||||
proto = Object.getPrototypeOf([].keys());
|
||||
assertEq(Object.getPrototypeOf(proto), Iterator.prototype);
|
||||
proto = Object.getPrototypeOf([].entries());
|
||||
assertEq(Object.getPrototypeOf(proto), Iterator.prototype);
|
||||
|
||||
function check(it) {
|
||||
assertEq(typeof it, 'object');
|
||||
@ -21,3 +25,7 @@ function check(it) {
|
||||
|
||||
check([][std_iterator]());
|
||||
check(Array.prototype[std_iterator].call({}));
|
||||
check([].keys());
|
||||
check(Array.prototype.keys.call({}));
|
||||
check([].entries());
|
||||
check(Array.prototype.entries.call({}));
|
||||
|
@ -50,6 +50,7 @@ SOURCES += [
|
||||
'testOps.cpp',
|
||||
'testOriginPrincipals.cpp',
|
||||
'testParseJSON.cpp',
|
||||
'testPersistentRooted.cpp',
|
||||
'testProfileStrings.cpp',
|
||||
'testPropCache.cpp',
|
||||
'testRegExp.cpp',
|
||||
|
185
js/src/jsapi-tests/testPersistentRooted.cpp
Normal file
185
js/src/jsapi-tests/testPersistentRooted.cpp
Normal file
@ -0,0 +1,185 @@
|
||||
/* 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/. */
|
||||
|
||||
#if defined(JSGC_USE_EXACT_ROOTING)
|
||||
|
||||
#include "js/Class.h"
|
||||
#include "jsapi-tests/tests.h"
|
||||
|
||||
using namespace JS;
|
||||
|
||||
struct BarkWhenTracedClass {
|
||||
static int finalizeCount;
|
||||
static int traceCount;
|
||||
|
||||
static const JSClass class_;
|
||||
static void finalize(JSFreeOp *fop, JSObject *obj) { finalizeCount++; }
|
||||
static void trace(JSTracer *trc, JSObject *obj) { traceCount++; }
|
||||
static void reset() { finalizeCount = 0; traceCount = 0; }
|
||||
};
|
||||
|
||||
int BarkWhenTracedClass::finalizeCount;
|
||||
int BarkWhenTracedClass::traceCount;
|
||||
|
||||
const JSClass BarkWhenTracedClass::class_ = {
|
||||
"BarkWhenTracedClass", 0,
|
||||
JS_PropertyStub,
|
||||
JS_DeletePropertyStub,
|
||||
JS_PropertyStub,
|
||||
JS_StrictPropertyStub,
|
||||
JS_EnumerateStub,
|
||||
JS_ResolveStub,
|
||||
JS_ConvertStub,
|
||||
finalize,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
trace
|
||||
};
|
||||
|
||||
struct Kennel {
|
||||
PersistentRootedObject obj;
|
||||
Kennel(JSContext *cx) : obj(cx) { }
|
||||
Kennel(JSContext *cx, const HandleObject &woof) : obj(cx, woof) { };
|
||||
};
|
||||
|
||||
// A function for allocating a Kennel and a barker. Only allocating
|
||||
// PersistentRooteds on the heap, and in this function, helps ensure that the
|
||||
// conservative GC doesn't find stray references to the barker. Ugh.
|
||||
JS_NEVER_INLINE static Kennel *
|
||||
Allocate(JSContext *cx)
|
||||
{
|
||||
RootedObject barker(cx, JS_NewObject(cx, &BarkWhenTracedClass::class_, nullptr, nullptr));
|
||||
if (!barker)
|
||||
return nullptr;
|
||||
|
||||
return new Kennel(cx, barker);
|
||||
}
|
||||
|
||||
// Do a GC, expecting |n| barkers to be finalized.
|
||||
static bool
|
||||
GCFinalizesNBarkers(JSContext *cx, int n)
|
||||
{
|
||||
int preGCTrace = BarkWhenTracedClass::traceCount;
|
||||
int preGCFinalize = BarkWhenTracedClass::finalizeCount;
|
||||
|
||||
JS_GC(JS_GetRuntime(cx));
|
||||
|
||||
return (BarkWhenTracedClass::finalizeCount == preGCFinalize + n &&
|
||||
BarkWhenTracedClass::traceCount > preGCTrace);
|
||||
}
|
||||
|
||||
// PersistentRooted instances protect their contents from being recycled.
|
||||
BEGIN_TEST(test_PersistentRooted)
|
||||
{
|
||||
BarkWhenTracedClass::reset();
|
||||
|
||||
Kennel *kennel = Allocate(cx);
|
||||
CHECK(kennel);
|
||||
|
||||
// GC should be able to find our barker.
|
||||
CHECK(GCFinalizesNBarkers(cx, 0));
|
||||
|
||||
delete(kennel);
|
||||
|
||||
// Now GC should not be able to find the barker.
|
||||
JS_GC(JS_GetRuntime(cx));
|
||||
CHECK(BarkWhenTracedClass::finalizeCount == 1);
|
||||
|
||||
return true;
|
||||
}
|
||||
END_TEST(test_PersistentRooted)
|
||||
|
||||
// GC should not be upset by null PersistentRooteds.
|
||||
BEGIN_TEST(test_PersistentRootedNull)
|
||||
{
|
||||
BarkWhenTracedClass::reset();
|
||||
|
||||
Kennel kennel(cx);
|
||||
CHECK(!kennel.obj);
|
||||
|
||||
JS_GC(JS_GetRuntime(cx));
|
||||
CHECK(BarkWhenTracedClass::finalizeCount == 0);
|
||||
|
||||
return true;
|
||||
}
|
||||
END_TEST(test_PersistentRootedNull)
|
||||
|
||||
// Copy construction works.
|
||||
BEGIN_TEST(test_PersistentRootedCopy)
|
||||
{
|
||||
BarkWhenTracedClass::reset();
|
||||
|
||||
Kennel *kennel = Allocate(cx);
|
||||
CHECK(kennel);
|
||||
|
||||
CHECK(GCFinalizesNBarkers(cx, 0));
|
||||
|
||||
// Copy construction! AMAZING!
|
||||
Kennel *newKennel = new Kennel(*kennel);
|
||||
|
||||
CHECK(GCFinalizesNBarkers(cx, 0));
|
||||
|
||||
delete(kennel);
|
||||
|
||||
CHECK(GCFinalizesNBarkers(cx, 0));
|
||||
|
||||
delete(newKennel);
|
||||
|
||||
// Now that kennel and nowKennel are both deallocated, GC should not be
|
||||
// able to find the barker.
|
||||
JS_GC(JS_GetRuntime(cx));
|
||||
CHECK(BarkWhenTracedClass::finalizeCount == 1);
|
||||
|
||||
return true;
|
||||
}
|
||||
END_TEST(test_PersistentRootedCopy)
|
||||
|
||||
// Assignment works.
|
||||
BEGIN_TEST(test_PersistentRootedAssign)
|
||||
{
|
||||
BarkWhenTracedClass::reset();
|
||||
|
||||
Kennel *kennel = Allocate(cx);
|
||||
CHECK(kennel);
|
||||
|
||||
CHECK(GCFinalizesNBarkers(cx, 0));
|
||||
|
||||
// Allocate a new, empty kennel.
|
||||
Kennel *kennel2 = new Kennel(cx);
|
||||
|
||||
// Assignment! ASTONISHING!
|
||||
*kennel2 = *kennel;
|
||||
|
||||
// With both kennels referring to the same barker, it is held alive.
|
||||
CHECK(GCFinalizesNBarkers(cx, 0));
|
||||
|
||||
delete(kennel2);
|
||||
|
||||
// The destination of the assignment alone holds the barker alive.
|
||||
CHECK(GCFinalizesNBarkers(cx, 0));
|
||||
|
||||
// Allocate a second barker.
|
||||
kennel2 = Allocate(cx);
|
||||
CHECK(kennel);
|
||||
|
||||
*kennel = *kennel2;
|
||||
|
||||
// Nothing refers to the first kennel any more.
|
||||
CHECK(GCFinalizesNBarkers(cx, 1));
|
||||
|
||||
delete(kennel);
|
||||
delete(kennel2);
|
||||
|
||||
// Now that kennel and kennel2 are both deallocated, GC should not be
|
||||
// able to find the barker.
|
||||
JS_GC(JS_GetRuntime(cx));
|
||||
CHECK(BarkWhenTracedClass::finalizeCount == 2);
|
||||
|
||||
return true;
|
||||
}
|
||||
END_TEST(test_PersistentRootedAssign)
|
||||
|
||||
#endif // defined(JSGC_USE_EXACT_ROOTING)
|
@ -2968,6 +2968,8 @@ static const JSFunctionSpec array_methods[] = {
|
||||
JS_SELF_HOSTED_FN("findIndex", "ArrayFindIndex", 1,0),
|
||||
|
||||
JS_SELF_HOSTED_FN("@@iterator", "ArrayValues", 0,0),
|
||||
JS_SELF_HOSTED_FN("entries", "ArrayEntries", 0,0),
|
||||
JS_SELF_HOSTED_FN("keys", "ArrayKeys", 0,0),
|
||||
JS_FS_END
|
||||
};
|
||||
|
||||
|
@ -53,8 +53,8 @@
|
||||
|
||||
/* BSDs */
|
||||
#elif defined(JS_HAVE_MACHINE_ENDIAN_H)
|
||||
# include <machine/endian.h>
|
||||
# include <sys/types.h>
|
||||
# include <machine/endian.h>
|
||||
|
||||
# if defined(_BYTE_ORDER)
|
||||
# if _BYTE_ORDER == _LITTLE_ENDIAN
|
||||
|
@ -1027,6 +1027,13 @@ js_FinishGC(JSRuntime *rt)
|
||||
rt->gcChunkPool.expireAndFree(rt, true);
|
||||
|
||||
rt->gcRootsHash.clear();
|
||||
|
||||
rt->functionPersistentRooteds.clear();
|
||||
rt->idPersistentRooteds.clear();
|
||||
rt->objectPersistentRooteds.clear();
|
||||
rt->scriptPersistentRooteds.clear();
|
||||
rt->stringPersistentRooteds.clear();
|
||||
rt->valuePersistentRooteds.clear();
|
||||
}
|
||||
|
||||
template <typename T> struct BarrierOwner {};
|
||||
|
@ -651,7 +651,7 @@ js::Int32ToAtom<NoGC>(ExclusiveContext *cx, int32_t si);
|
||||
static char *
|
||||
IntToCString(ToCStringBuf *cbuf, int i, size_t *len, int base = 10)
|
||||
{
|
||||
unsigned u = (i < 0) ? -i : i;
|
||||
unsigned u = (i < 0) ? -unsigned(i) : i;
|
||||
|
||||
RangedPtr<char> cp(cbuf->sbuf + ToCStringBuf::sbufSize - 1, cbuf->sbuf, ToCStringBuf::sbufSize);
|
||||
char *end = cp.get();
|
||||
|
@ -260,7 +260,9 @@ ToInteger(JSContext *cx, HandleValue v, double *dp)
|
||||
inline bool
|
||||
SafeAdd(int32_t one, int32_t two, int32_t *res)
|
||||
{
|
||||
*res = one + two;
|
||||
// Use unsigned for the 32-bit operation since signed overflow gets
|
||||
// undefined behavior.
|
||||
*res = uint32_t(one) + uint32_t(two);
|
||||
int64_t ores = (int64_t)one + (int64_t)two;
|
||||
return ores == (int64_t)*res;
|
||||
}
|
||||
@ -268,7 +270,7 @@ SafeAdd(int32_t one, int32_t two, int32_t *res)
|
||||
inline bool
|
||||
SafeSub(int32_t one, int32_t two, int32_t *res)
|
||||
{
|
||||
*res = one - two;
|
||||
*res = uint32_t(one) - uint32_t(two);
|
||||
int64_t ores = (int64_t)one - (int64_t)two;
|
||||
return ores == (int64_t)*res;
|
||||
}
|
||||
@ -276,7 +278,7 @@ SafeSub(int32_t one, int32_t two, int32_t *res)
|
||||
inline bool
|
||||
SafeMul(int32_t one, int32_t two, int32_t *res)
|
||||
{
|
||||
*res = one * two;
|
||||
*res = uint32_t(one) * uint32_t(two);
|
||||
int64_t ores = (int64_t)one * (int64_t)two;
|
||||
return ores == (int64_t)*res;
|
||||
}
|
||||
|
@ -11,6 +11,7 @@
|
||||
* JS public API typedefs.
|
||||
*/
|
||||
|
||||
#include "mozilla/LinkedList.h"
|
||||
#include "mozilla/NullPtr.h"
|
||||
#include "mozilla/PodOperations.h"
|
||||
|
||||
@ -173,9 +174,12 @@ typedef bool (*JSInitCallback)(void);
|
||||
typedef void
|
||||
(* JSTraceDataOp)(JSTracer *trc, void *data);
|
||||
|
||||
void js_FinishGC(JSRuntime *rt);
|
||||
|
||||
namespace js {
|
||||
namespace gc {
|
||||
class StoreBuffer;
|
||||
void MarkPersistentRootedChains(JSTracer *);
|
||||
}
|
||||
}
|
||||
|
||||
@ -224,8 +228,49 @@ struct Runtime
|
||||
static JS::shadow::Runtime *asShadowRuntime(JSRuntime *rt) {
|
||||
return reinterpret_cast<JS::shadow::Runtime*>(rt);
|
||||
}
|
||||
|
||||
/* Allow inlining of PersistentRooted constructors and destructors. */
|
||||
private:
|
||||
template <typename Referent> friend class JS::PersistentRooted;
|
||||
friend void js::gc::MarkPersistentRootedChains(JSTracer *);
|
||||
friend void ::js_FinishGC(JSRuntime *rt);
|
||||
|
||||
mozilla::LinkedList<PersistentRootedFunction> functionPersistentRooteds;
|
||||
mozilla::LinkedList<PersistentRootedId> idPersistentRooteds;
|
||||
mozilla::LinkedList<PersistentRootedObject> objectPersistentRooteds;
|
||||
mozilla::LinkedList<PersistentRootedScript> scriptPersistentRooteds;
|
||||
mozilla::LinkedList<PersistentRootedString> stringPersistentRooteds;
|
||||
mozilla::LinkedList<PersistentRootedValue> valuePersistentRooteds;
|
||||
|
||||
/* Specializations of this return references to the appropriate list. */
|
||||
template<typename Referent>
|
||||
inline mozilla::LinkedList<PersistentRooted<Referent> > &getPersistentRootedList();
|
||||
};
|
||||
|
||||
template<>
|
||||
inline mozilla::LinkedList<PersistentRootedFunction>
|
||||
&Runtime::getPersistentRootedList<JSFunction *>() { return functionPersistentRooteds; }
|
||||
|
||||
template<>
|
||||
inline mozilla::LinkedList<PersistentRootedId>
|
||||
&Runtime::getPersistentRootedList<jsid>() { return idPersistentRooteds; }
|
||||
|
||||
template<>
|
||||
inline mozilla::LinkedList<PersistentRootedObject>
|
||||
&Runtime::getPersistentRootedList<JSObject *>() { return objectPersistentRooteds; }
|
||||
|
||||
template<>
|
||||
inline mozilla::LinkedList<PersistentRootedScript>
|
||||
&Runtime::getPersistentRootedList<JSScript *>() { return scriptPersistentRooteds; }
|
||||
|
||||
template<>
|
||||
inline mozilla::LinkedList<PersistentRootedString>
|
||||
&Runtime::getPersistentRootedList<JSString *>() { return stringPersistentRooteds; }
|
||||
|
||||
template<>
|
||||
inline mozilla::LinkedList<PersistentRootedValue>
|
||||
&Runtime::getPersistentRootedList<Value>() { return valuePersistentRooteds; }
|
||||
|
||||
} /* namespace shadow */
|
||||
} /* namespace JS */
|
||||
|
||||
|
@ -606,7 +606,7 @@ BitLsh(JSContext *cx, HandleValue lhs, HandleValue rhs, int *out)
|
||||
int32_t left, right;
|
||||
if (!ToInt32(cx, lhs, &left) || !ToInt32(cx, rhs, &right))
|
||||
return false;
|
||||
*out = left << (right & 31);
|
||||
*out = uint32_t(left) << (right & 31);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1067,9 +1067,11 @@ AddOperation(JSContext *cx, MutableHandleValue lhs, MutableHandleValue rhs, Valu
|
||||
{
|
||||
if (lhs.isInt32() && rhs.isInt32()) {
|
||||
int32_t l = lhs.toInt32(), r = rhs.toInt32();
|
||||
double d = double(l) + double(r);
|
||||
res->setNumber(d);
|
||||
return true;
|
||||
int32_t t;
|
||||
if (JS_LIKELY(SafeAdd(l, r, &t))) {
|
||||
res->setInt32(t);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ToPrimitive(cx, lhs))
|
||||
|
@ -77,8 +77,7 @@ dom_quickstubs.h: dom_quickstubs.cpp
|
||||
dom_quickstubs.cpp: $(srcdir)/dom_quickstubs.qsconf \
|
||||
$(srcdir)/qsgen.py \
|
||||
$(LIBXUL_DIST)/sdk/bin/header.py \
|
||||
$(LIBXUL_DIST)/sdk/bin/xpidl.py \
|
||||
$(DEPTH)/js/src/js-confdefs.h
|
||||
$(LIBXUL_DIST)/sdk/bin/xpidl.py
|
||||
$(PYTHON) $(topsrcdir)/config/pythonpath.py \
|
||||
$(PLY_INCLUDE) \
|
||||
-I$(LIBXUL_DIST)/sdk/bin \
|
||||
@ -98,8 +97,7 @@ DictionaryHelpers.cpp: $(srcdir)/dictionary_helper_gen.conf \
|
||||
event_impl_gen.conf \
|
||||
$(srcdir)/dictionary_helper_gen.py \
|
||||
$(LIBXUL_DIST)/sdk/bin/header.py \
|
||||
$(LIBXUL_DIST)/sdk/bin/xpidl.py \
|
||||
$(DEPTH)/js/src/js-confdefs.h
|
||||
$(LIBXUL_DIST)/sdk/bin/xpidl.py
|
||||
$(PYTHON) $(topsrcdir)/config/pythonpath.py \
|
||||
$(PLY_INCLUDE) \
|
||||
-I$(LIBXUL_DIST)/sdk/bin \
|
||||
@ -122,8 +120,7 @@ GeneratedEvents.h: $(srcdir)/dictionary_helper_gen.conf \
|
||||
$(srcdir)/dictionary_helper_gen.py \
|
||||
$(srcdir)/event_impl_gen.py \
|
||||
$(LIBXUL_DIST)/sdk/bin/header.py \
|
||||
$(LIBXUL_DIST)/sdk/bin/xpidl.py \
|
||||
$(DEPTH)/js/src/js-confdefs.h
|
||||
$(LIBXUL_DIST)/sdk/bin/xpidl.py
|
||||
$(PYTHON) $(topsrcdir)/config/pythonpath.py \
|
||||
$(PLY_INCLUDE) \
|
||||
-I$(LIBXUL_DIST)/sdk/bin \
|
||||
@ -141,8 +138,7 @@ GeneratedEvents.cpp: DictionaryHelpers.h \
|
||||
$(srcdir)/dictionary_helper_gen.py \
|
||||
$(srcdir)/event_impl_gen.py \
|
||||
$(LIBXUL_DIST)/sdk/bin/header.py \
|
||||
$(LIBXUL_DIST)/sdk/bin/xpidl.py \
|
||||
$(DEPTH)/js/src/js-confdefs.h
|
||||
$(LIBXUL_DIST)/sdk/bin/xpidl.py
|
||||
$(PYTHON) $(topsrcdir)/config/pythonpath.py \
|
||||
$(PLY_INCLUDE) \
|
||||
-I$(LIBXUL_DIST)/sdk/bin \
|
||||
|
@ -777,11 +777,7 @@ nsLayoutUtils::GetChildListNameFor(nsIFrame* aChildFrame)
|
||||
"Unexpected parent");
|
||||
#endif // DEBUG
|
||||
|
||||
// XXX FIXME: Bug 350740
|
||||
// Return here, because the postcondition for this function actually
|
||||
// fails for this case, since the popups are not in a "real" frame list
|
||||
// in the popup set.
|
||||
return nsIFrame::kPopupList;
|
||||
id = nsIFrame::kPopupList;
|
||||
#endif // MOZ_XUL
|
||||
} else {
|
||||
NS_ASSERTION(aChildFrame->IsFloating(), "not a floated frame");
|
||||
@ -792,17 +788,24 @@ nsLayoutUtils::GetChildListNameFor(nsIFrame* aChildFrame)
|
||||
nsIAtom* childType = aChildFrame->GetType();
|
||||
if (nsGkAtoms::menuPopupFrame == childType) {
|
||||
nsIFrame* parent = aChildFrame->GetParent();
|
||||
nsIFrame* firstPopup = (parent)
|
||||
? parent->GetFirstChild(nsIFrame::kPopupList)
|
||||
: nullptr;
|
||||
NS_ASSERTION(!firstPopup || !firstPopup->GetNextSibling(),
|
||||
"We assume popupList only has one child, but it has more.");
|
||||
id = firstPopup == aChildFrame
|
||||
? nsIFrame::kPopupList
|
||||
: nsIFrame::kPrincipalList;
|
||||
MOZ_ASSERT(parent, "nsMenuPopupFrame can't be the root frame");
|
||||
if (parent) {
|
||||
if (parent->GetType() == nsGkAtoms::popupSetFrame) {
|
||||
id = nsIFrame::kPopupList;
|
||||
} else {
|
||||
nsIFrame* firstPopup = parent->GetFirstChild(nsIFrame::kPopupList);
|
||||
MOZ_ASSERT(!firstPopup || !firstPopup->GetNextSibling(),
|
||||
"We assume popupList only has one child, but it has more.");
|
||||
id = firstPopup == aChildFrame
|
||||
? nsIFrame::kPopupList
|
||||
: nsIFrame::kPrincipalList;
|
||||
}
|
||||
} else {
|
||||
id = nsIFrame::kPrincipalList;
|
||||
}
|
||||
} else if (nsGkAtoms::tableColGroupFrame == childType) {
|
||||
id = nsIFrame::kColGroupList;
|
||||
} else if (nsGkAtoms::tableCaptionFrame == aChildFrame->GetType()) {
|
||||
} else if (nsGkAtoms::tableCaptionFrame == childType) {
|
||||
id = nsIFrame::kCaptionList;
|
||||
} else {
|
||||
id = nsIFrame::kPrincipalList;
|
||||
|
@ -1394,7 +1394,7 @@ nsComboboxControlFrame::SetInitialChildList(ChildListID aListID,
|
||||
//nsIRollupListener
|
||||
//----------------------------------------------------------------------
|
||||
bool
|
||||
nsComboboxControlFrame::Rollup(uint32_t aCount, nsIContent** aLastRolledUp)
|
||||
nsComboboxControlFrame::Rollup(uint32_t aCount, const nsIntPoint* pos, nsIContent** aLastRolledUp)
|
||||
{
|
||||
if (!mDroppedDown)
|
||||
return false;
|
||||
|
@ -164,7 +164,7 @@ public:
|
||||
* Hide the dropdown menu and stop capturing mouse events.
|
||||
* @note This method might destroy |this|.
|
||||
*/
|
||||
virtual bool Rollup(uint32_t aCount, nsIContent** aLastRolledUp) MOZ_OVERRIDE;
|
||||
virtual bool Rollup(uint32_t aCount, const nsIntPoint* pos, nsIContent** aLastRolledUp) MOZ_OVERRIDE;
|
||||
virtual void NotifyGeometryChange() MOZ_OVERRIDE;
|
||||
|
||||
/**
|
||||
|
@ -993,7 +993,8 @@ nsContainerFrame::PositionChildViews(nsIFrame* aFrame)
|
||||
// Recursively walk aFrame's child frames.
|
||||
// Process the additional child lists, but skip the popup list as the
|
||||
// view for popups is managed by the parent. Currently only nsMenuFrame
|
||||
// has a popupList and during layout will call nsMenuPopupFrame::AdjustView.
|
||||
// and nsPopupSetFrame have a popupList and during layout will adjust the
|
||||
// view manually to position the popup.
|
||||
ChildListIterator lists(aFrame);
|
||||
for (; !lists.IsDone(); lists.Next()) {
|
||||
if (lists.CurrentID() == kPopupList) {
|
||||
|
@ -136,7 +136,6 @@ MOCHITEST_FILES = test_acid3_test46.html \
|
||||
test_pointer-events.html \
|
||||
file_position_sticky.html \
|
||||
test_position_sticky.html \
|
||||
test_property_database.html \
|
||||
test_priority_preservation.html \
|
||||
test_property_syntax_errors.html \
|
||||
test_redundant_font_download.html \
|
||||
@ -180,7 +179,6 @@ MOCHITEST_FILES = test_acid3_test46.html \
|
||||
test_visited_pref.html \
|
||||
test_visited_reftests.html \
|
||||
animation_utils.js \
|
||||
css_properties.js \
|
||||
property_database.js \
|
||||
descriptor_database.js \
|
||||
unstyled.xml \
|
||||
@ -217,7 +215,7 @@ MOCHITEST_FILES = test_acid3_test46.html \
|
||||
viewport_units_iframe.html \
|
||||
$(NULL)
|
||||
|
||||
_VISITED_REFTEST_FILES = \
|
||||
VISITED_REFTEST_FILES = \
|
||||
$(shell find $(topsrcdir)/layout/reftests/css-visited/ -name '*.html' -o -name '*.xhtml') \
|
||||
$(topsrcdir)/layout/reftests/svg/pseudo-classes-02.svg \
|
||||
$(topsrcdir)/layout/reftests/svg/pseudo-classes-02-ref.svg \
|
||||
@ -225,17 +223,21 @@ _VISITED_REFTEST_FILES = \
|
||||
$(topsrcdir)/layout/reftests/svg/as-image/svg-image-visited-1-helper.svg \
|
||||
$(topsrcdir)/layout/reftests/svg/as-image/svg-image-visited-2-helper.svg \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
VISITED_REFTEST_DEST = $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)/css-visited/
|
||||
INSTALL_TARGETS += VISITED_REFTEST
|
||||
|
||||
DEFINES += -DMOZILLA_INTERNAL_API
|
||||
|
||||
ifdef COMPILE_ENVIRONMENT
|
||||
MOCHITEST_FILES += \
|
||||
test_property_database.html \
|
||||
css_properties.js \
|
||||
$(NULL)
|
||||
|
||||
css_properties.js: host_ListCSSProperties$(HOST_BIN_SUFFIX) css_properties_like_longhand.js Makefile
|
||||
$(RM) $@
|
||||
./host_ListCSSProperties$(HOST_BIN_SUFFIX) > $@
|
||||
cat $(srcdir)/css_properties_like_longhand.js >> $@
|
||||
|
||||
GARBAGE += css_properties.js
|
||||
|
||||
libs:: $(_VISITED_REFTEST_FILES)
|
||||
$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)/css-visited/
|
||||
endif
|
||||
|
@ -282,7 +282,7 @@ public:
|
||||
NS_DECL_NSIDOMEVENTLISTENER
|
||||
|
||||
// nsIRollupListener
|
||||
virtual bool Rollup(uint32_t aCount, nsIContent** aLastRolledUp) MOZ_OVERRIDE;
|
||||
virtual bool Rollup(uint32_t aCount, const nsIntPoint* pos, nsIContent** aLastRolledUp) MOZ_OVERRIDE;
|
||||
virtual bool ShouldRollupOnMouseWheelEvent() MOZ_OVERRIDE;
|
||||
virtual bool ShouldConsumeOnMouseWheelEvent() MOZ_OVERRIDE;
|
||||
virtual bool ShouldRollupOnMouseActivate() MOZ_OVERRIDE;
|
||||
|
@ -82,17 +82,30 @@ nsPopupSetFrame::SetInitialChildList(ChildListID aListID,
|
||||
nsFrameList& aChildList)
|
||||
{
|
||||
if (aListID == kPopupList) {
|
||||
// XXXmats this asserts because we don't implement
|
||||
// GetChildList(kPopupList) so nsCSSFrameConstructor
|
||||
// believes it's empty and calls us multiple times.
|
||||
//NS_ASSERTION(mPopupList.IsEmpty(),
|
||||
// "SetInitialChildList on non-empty child list");
|
||||
NS_ASSERTION(mPopupList.IsEmpty(),
|
||||
"SetInitialChildList on non-empty child list");
|
||||
AddPopupFrameList(aChildList);
|
||||
return NS_OK;
|
||||
}
|
||||
return nsBoxFrame::SetInitialChildList(aListID, aChildList);
|
||||
}
|
||||
|
||||
const nsFrameList&
|
||||
nsPopupSetFrame::GetChildList(ChildListID aListID) const
|
||||
{
|
||||
if (kPopupList == aListID) {
|
||||
return mPopupList;
|
||||
}
|
||||
return nsBoxFrame::GetChildList(aListID);
|
||||
}
|
||||
|
||||
void
|
||||
nsPopupSetFrame::GetChildLists(nsTArray<ChildList>* aLists) const
|
||||
{
|
||||
nsBoxFrame::GetChildLists(aLists);
|
||||
mPopupList.AppendIfNonempty(aLists, kPopupList);
|
||||
}
|
||||
|
||||
void
|
||||
nsPopupSetFrame::DestroyFrom(nsIFrame* aDestructRoot)
|
||||
{
|
||||
@ -145,61 +158,3 @@ nsPopupSetFrame::AddPopupFrameList(nsFrameList& aPopupFrameList)
|
||||
#endif
|
||||
mPopupList.InsertFrames(nullptr, nullptr, aPopupFrameList);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
void
|
||||
nsPopupSetFrame::List(FILE* out, int32_t aIndent, uint32_t aFlags) const
|
||||
{
|
||||
ListGeneric(out, aIndent, aFlags);
|
||||
|
||||
// Output the children
|
||||
bool outputOneList = false;
|
||||
ChildListIterator lists(this);
|
||||
for (; !lists.IsDone(); lists.Next()) {
|
||||
if (outputOneList) {
|
||||
IndentBy(out, aIndent);
|
||||
}
|
||||
outputOneList = true;
|
||||
fprintf(out, "%s<\n", mozilla::layout::ChildListName(lists.CurrentID()));
|
||||
nsFrameList::Enumerator childFrames(lists.CurrentList());
|
||||
for (; !childFrames.AtEnd(); childFrames.Next()) {
|
||||
nsIFrame* kid = childFrames.get();
|
||||
// Verify the child frame's parent frame pointer is correct
|
||||
NS_ASSERTION(kid->GetParent() == this, "bad parent frame pointer");
|
||||
|
||||
// Have the child frame list
|
||||
kid->List(out, aIndent + 1, aFlags);
|
||||
}
|
||||
IndentBy(out, aIndent);
|
||||
fputs(">\n", out);
|
||||
}
|
||||
|
||||
// XXXmats the above is copy-pasted from nsContainerFrame::List which is lame,
|
||||
// clean this up after bug 399111 is implemented.
|
||||
|
||||
if (!mPopupList.IsEmpty()) {
|
||||
fputs("<\n", out);
|
||||
++aIndent;
|
||||
IndentBy(out, aIndent);
|
||||
fputs(mozilla::layout::ChildListName(kPopupList), out);
|
||||
fputs(" for ", out);
|
||||
ListTag(out);
|
||||
fputs(" <\n", out);
|
||||
++aIndent;
|
||||
for (nsFrameList::Enumerator e(mPopupList); !e.AtEnd(); e.Next()) {
|
||||
e.get()->List(out, aIndent, aFlags);
|
||||
}
|
||||
--aIndent;
|
||||
IndentBy(out, aIndent);
|
||||
fputs(">\n", out);
|
||||
--aIndent;
|
||||
IndentBy(out, aIndent);
|
||||
fputs(">\n", out);
|
||||
outputOneList = true;
|
||||
}
|
||||
|
||||
if (!outputOneList) {
|
||||
fputs("<>\n", out);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -36,6 +36,9 @@ public:
|
||||
NS_IMETHOD SetInitialChildList(ChildListID aListID,
|
||||
nsFrameList& aChildList) MOZ_OVERRIDE;
|
||||
|
||||
virtual const nsFrameList& GetChildList(ChildListID aList) const MOZ_OVERRIDE;
|
||||
virtual void GetChildLists(nsTArray<ChildList>* aLists) const MOZ_OVERRIDE;
|
||||
|
||||
NS_IMETHOD DoLayout(nsBoxLayoutState& aBoxLayoutState) MOZ_OVERRIDE;
|
||||
|
||||
// Used to destroy our popup frames.
|
||||
@ -44,7 +47,6 @@ public:
|
||||
virtual nsIAtom* GetType() const MOZ_OVERRIDE;
|
||||
|
||||
#ifdef DEBUG
|
||||
void List(FILE* out, int32_t aIndent, uint32_t aFlags = 0) const MOZ_OVERRIDE;
|
||||
NS_IMETHOD GetFrameName(nsAString& aResult) const MOZ_OVERRIDE
|
||||
{
|
||||
return MakeFrameName(NS_LITERAL_STRING("PopupSet"), aResult);
|
||||
|
@ -180,7 +180,7 @@ nsXULPopupManager::GetInstance()
|
||||
}
|
||||
|
||||
bool
|
||||
nsXULPopupManager::Rollup(uint32_t aCount, nsIContent** aLastRolledUp)
|
||||
nsXULPopupManager::Rollup(uint32_t aCount, const nsIntPoint* pos, nsIContent** aLastRolledUp)
|
||||
{
|
||||
bool consume = false;
|
||||
|
||||
@ -202,6 +202,20 @@ nsXULPopupManager::Rollup(uint32_t aCount, nsIContent** aLastRolledUp)
|
||||
}
|
||||
|
||||
consume = item->Frame()->ConsumeOutsideClicks();
|
||||
// If the click was over the anchor, always consume the click. This way,
|
||||
// clicking on a menu doesn't reopen the menu.
|
||||
if (!consume && pos) {
|
||||
nsCOMPtr<nsIContent> anchor = item->Frame()->GetAnchor();
|
||||
if (anchor && anchor->GetPrimaryFrame()) {
|
||||
// It's possible that some other element is above the anchor at the same
|
||||
// position, but the only thing that would happen is that the mouse
|
||||
// event will get consumed, so here only a quick coordinates check is
|
||||
// done rather than a slower complete check of what is at that location.
|
||||
if (anchor->GetPrimaryFrame()->GetScreenRect().Contains(*pos)) {
|
||||
consume = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if a number of popups to close has been specified, determine the last
|
||||
// popup to close
|
||||
@ -2005,7 +2019,7 @@ nsXULPopupManager::HandleKeyboardEventWithKeyCode(
|
||||
#endif
|
||||
// close popups or deactivate menubar when Tab or F10 are pressed
|
||||
if (aTopVisibleMenuItem) {
|
||||
Rollup(0, nullptr);
|
||||
Rollup(0, nullptr, nullptr);
|
||||
} else if (mActiveMenuBar) {
|
||||
mActiveMenuBar->MenuClosed();
|
||||
}
|
||||
@ -2240,7 +2254,7 @@ nsXULPopupManager::KeyDown(nsIDOMKeyEvent* aKeyEvent)
|
||||
// The access key just went down and no other
|
||||
// modifiers are already down.
|
||||
if (mPopups)
|
||||
Rollup(0, nullptr);
|
||||
Rollup(0, nullptr, nullptr);
|
||||
else if (mActiveMenuBar)
|
||||
mActiveMenuBar->MenuClosed();
|
||||
}
|
||||
|
@ -421,6 +421,9 @@ pref("ui.scrollToClick", 0);
|
||||
pref("accessibility.tabfocus_applies_to_xul", true);
|
||||
#endif
|
||||
|
||||
// provide ability to turn on support for canvas focus rings
|
||||
pref("canvas.focusring.enabled", false);
|
||||
|
||||
// We want the ability to forcibly disable platform a11y, because
|
||||
// some non-a11y-related components attempt to bring it up. See bug
|
||||
// 538530 for details about Windows; we have a pref here that allows it
|
||||
|
@ -404,7 +404,7 @@ class MozbuildObject(ProcessExecutionMixin):
|
||||
args = self._make_path(force_pymake=force_pymake)
|
||||
|
||||
if directory:
|
||||
args.extend(['-C', directory])
|
||||
args.extend(['-C', directory.replace(os.sep, '/')])
|
||||
|
||||
if filename:
|
||||
args.extend(['-f', filename])
|
||||
|
@ -1387,6 +1387,10 @@ NS_IMETHODIMP
|
||||
nsNSSCertificateDB::ConstructX509FromBase64(const char *base64,
|
||||
nsIX509Cert **_retval)
|
||||
{
|
||||
nsNSSShutDownPreventionLock locker;
|
||||
if (isAlreadyShutDown()) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
NS_ENSURE_ARG_POINTER(_retval);
|
||||
|
||||
// sure would be nice to have a smart pointer class for PL_ allocations
|
||||
@ -1410,10 +1414,6 @@ nsNSSCertificateDB::ConstructX509FromBase64(const char *base64,
|
||||
lengthDER--;
|
||||
}
|
||||
|
||||
nsNSSShutDownPreventionLock locker;
|
||||
if (isAlreadyShutDown()) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
SECItem secitem_cert;
|
||||
secitem_cert.type = siDERCertBuffer;
|
||||
|
@ -16,6 +16,12 @@ int min_log_level = 0;
|
||||
namespace logging
|
||||
{
|
||||
|
||||
DcheckState g_dcheck_state = DISABLE_DCHECK_FOR_NON_OFFICIAL_RELEASE_BUILDS;
|
||||
|
||||
DcheckState get_dcheck_state() {
|
||||
return g_dcheck_state;
|
||||
}
|
||||
|
||||
LogMessage::LogMessage(const char* file, int line, LogSeverity severity,
|
||||
int ctr) :
|
||||
line_(line)
|
||||
|
@ -184,6 +184,7 @@
|
||||
"dom/tests/mochitest/geolocation/test_allowWatch.html": "TIMED_OUT",
|
||||
"dom/tests/mochitest/geolocation/test_cachedPosition.html": "TIMED_OUT",
|
||||
"dom/tests/mochitest/geolocation/test_clearWatch.html": "TIMED_OUT",
|
||||
"dom/tests/mochitest/geolocation/test_errorcheck.html": "TIMED_OUT",
|
||||
"dom/tests/mochitest/geolocation/test_handlerSpinsEventLoop.html": "Don't run modal tests on Android",
|
||||
"dom/tests/mochitest/geolocation/test_manyCurrentConcurrent.html": "TIMED_OUT",
|
||||
"dom/tests/mochitest/geolocation/test_manyCurrentSerial.html": "TIMED_OUT",
|
||||
|
@ -254,6 +254,7 @@
|
||||
"dom/tests/mochitest/geolocation/test_allowWatch.html": "TIMED_OUT",
|
||||
"dom/tests/mochitest/geolocation/test_cachedPosition.html": "TIMED_OUT",
|
||||
"dom/tests/mochitest/geolocation/test_clearWatch.html": "TIMED_OUT",
|
||||
"dom/tests/mochitest/geolocation/test_errorcheck.html": "TIMED_OUT",
|
||||
"dom/tests/mochitest/geolocation/test_handlerSpinsEventLoop.html": "Don't run modal tests on Android",
|
||||
"dom/tests/mochitest/geolocation/test_manyCurrentConcurrent.html": "TIMED_OUT",
|
||||
"dom/tests/mochitest/geolocation/test_manyCurrentSerial.html": "TIMED_OUT",
|
||||
|
@ -100,6 +100,7 @@
|
||||
"content/base/test/test_child_process_shutdown_message.html":"specialpowers.wrap issue, NS_ERROR_XPC_GS_RETURNED_FAILURE",
|
||||
"content/base/test/test_messagemanager_assertpermission.html":"specialpowers.wrap issue, NS_ERROR_XPC_GS_RETURNED_FAILURE",
|
||||
|
||||
"content/canvas/test/test_canvas_focusring.html":"specialpowers.wrap",
|
||||
|
||||
"content/html/content/test/test_formSubmission.html":"NS_ERROR_FILE_TARGET_DOES_NOT_EXIST",
|
||||
|
||||
@ -353,6 +354,7 @@
|
||||
"dom/tests/mochitest/geolocation/test_cancelWatch.html":"",
|
||||
"dom/tests/mochitest/geolocation/test_clearWatch.html":"",
|
||||
"dom/tests/mochitest/geolocation/test_clearWatch_invalid.html":"",
|
||||
"dom/tests/mochitest/geolocation/test_errorcheck.html": "",
|
||||
"dom/tests/mochitest/geolocation/test_handlerSpinsEventLoop.html": "showmodaldialog",
|
||||
"dom/tests/mochitest/geolocation/test_manyCurrentConcurrent.html":"",
|
||||
"dom/tests/mochitest/geolocation/test_manyCurrentSerial.html":"",
|
||||
|
@ -3,9 +3,6 @@
|
||||
# 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/.
|
||||
|
||||
|
||||
CHROME_DEPS = buildconfig.html
|
||||
|
||||
USE_RCS_MK := 1
|
||||
include $(topsrcdir)/config/makefiles/makeutils.mk
|
||||
|
||||
|
@ -313,7 +313,7 @@
|
||||
</binding>
|
||||
|
||||
<binding id="arrowpanel" extends="chrome://global/content/bindings/popup.xml#panel">
|
||||
<content flip="both" side="top" position="bottomcenter topleft">
|
||||
<content flip="both" side="top" position="bottomcenter topleft" consumeoutsideclicks="false">
|
||||
<xul:box anonid="container" class="panel-arrowcontainer" flex="1"
|
||||
xbl:inherits="side,panelopen">
|
||||
<xul:box anonid="arrowbox" class="panel-arrowbox">
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user