Merge last green changeset from inbound to mozilla-central

This commit is contained in:
Matt Brubeck 2012-03-12 13:31:31 -07:00
commit d937bfd92a
100 changed files with 1512 additions and 460 deletions

View File

@ -51,32 +51,6 @@
using namespace mozilla;
using namespace mozilla::a11y;
////////////////////////////////////////////////////////////////////////////////
// Constants and structures
/**
* Item of the gCSSTextAttrsMap map.
*/
struct nsCSSTextAttrMapItem
{
const char* mCSSName;
const char* mCSSValue;
nsIAtom** mAttrName;
const char* mAttrValue;
};
/**
* The map of CSS properties to text attributes.
*/
const char* const kAnyValue = nsnull;
const char* const kCopyValue = nsnull;
static nsCSSTextAttrMapItem gCSSTextAttrsMap[] =
{
// CSS name CSS value Attribute name Attribute value
{ "vertical-align", kAnyValue, &nsGkAtoms::textPosition, kCopyValue }
};
////////////////////////////////////////////////////////////////////////////////
// TextAttrsMgr
////////////////////////////////////////////////////////////////////////////////
@ -139,62 +113,61 @@ TextAttrsMgr::GetAttributes(nsIPersistentProperties* aAttributes,
frame = offsetElm->GetPrimaryFrame();
}
nsTArray<TextAttr*> textAttrArray(9);
// "language" text attribute
LangTextAttr langTextAttr(mHyperTextAcc, hyperTextElm, offsetNode);
textAttrArray.AppendElement(&langTextAttr);
// "text-position" text attribute
CSSTextAttr posTextAttr(0, hyperTextElm, offsetElm);
textAttrArray.AppendElement(&posTextAttr);
// "background-color" text attribute
BGColorTextAttr bgColorTextAttr(rootFrame, frame);
textAttrArray.AppendElement(&bgColorTextAttr);
// "color" text attribute
ColorTextAttr colorTextAttr(rootFrame, frame);
textAttrArray.AppendElement(&colorTextAttr);
// "font-family" text attribute
FontFamilyTextAttr fontFamilyTextAttr(rootFrame, frame);
textAttrArray.AppendElement(&fontFamilyTextAttr);
// "font-size" text attribute
FontSizeTextAttr fontSizeTextAttr(rootFrame, frame);
textAttrArray.AppendElement(&fontSizeTextAttr);
// "font-style" text attribute
FontStyleTextAttr fontStyleTextAttr(rootFrame, frame);
textAttrArray.AppendElement(&fontStyleTextAttr);
// "font-weight" text attribute
FontWeightTextAttr fontWeightTextAttr(rootFrame, frame);
textAttrArray.AppendElement(&fontWeightTextAttr);
// "text-underline(line-through)-style(color)" text attributes
TextDecorTextAttr textDecorTextAttr(rootFrame, frame);
textAttrArray.AppendElement(&textDecorTextAttr);
// "text-position" text attribute
TextPosTextAttr textPosTextAttr(rootFrame, frame);
TextAttr* attrArray[] =
{
&langTextAttr,
&bgColorTextAttr,
&colorTextAttr,
&fontFamilyTextAttr,
&fontSizeTextAttr,
&fontStyleTextAttr,
&fontWeightTextAttr,
&textDecorTextAttr,
&textPosTextAttr
};
// Expose text attributes if applicable.
if (aAttributes) {
PRUint32 len = textAttrArray.Length();
for (PRUint32 idx = 0; idx < len; idx++)
textAttrArray[idx]->Expose(aAttributes, mIncludeDefAttrs);
for (PRUint32 idx = 0; idx < ArrayLength(attrArray); idx++)
attrArray[idx]->Expose(aAttributes, mIncludeDefAttrs);
}
// Expose text attributes range where they are applied if applicable.
if (mOffsetAcc)
GetRange(textAttrArray, aStartHTOffset, aEndHTOffset);
GetRange(attrArray, ArrayLength(attrArray), aStartHTOffset, aEndHTOffset);
}
void
TextAttrsMgr::GetRange(const nsTArray<TextAttr*>& aTextAttrArray,
TextAttrsMgr::GetRange(TextAttr* aAttrArray[], PRUint32 aAttrArrayLen,
PRInt32* aStartHTOffset, PRInt32* aEndHTOffset)
{
PRUint32 attrLen = aTextAttrArray.Length();
// Navigate backward from anchor accessible to find start offset.
for (PRInt32 childIdx = mOffsetAccIdx - 1; childIdx >= 0; childIdx--) {
nsAccessible *currAcc = mHyperTextAcc->GetChildAt(childIdx);
@ -209,8 +182,8 @@ TextAttrsMgr::GetRange(const nsTArray<TextAttr*>& aTextAttrArray,
return;
bool offsetFound = false;
for (PRUint32 attrIdx = 0; attrIdx < attrLen; attrIdx++) {
TextAttr* textAttr = aTextAttrArray[attrIdx];
for (PRUint32 attrIdx = 0; attrIdx < aAttrArrayLen; attrIdx++) {
TextAttr* textAttr = aAttrArray[attrIdx];
if (!textAttr->Equal(currElm)) {
offsetFound = true;
break;
@ -235,8 +208,8 @@ TextAttrsMgr::GetRange(const nsTArray<TextAttr*>& aTextAttrArray,
return;
bool offsetFound = false;
for (PRUint32 attrIdx = 0; attrIdx < attrLen; attrIdx++) {
TextAttr* textAttr = aTextAttrArray[attrIdx];
for (PRUint32 attrIdx = 0; attrIdx < aAttrArrayLen; attrIdx++) {
TextAttr* textAttr = aAttrArray[attrIdx];
// Alter the end offset when text attribute changes its value and stop
// the search.
@ -293,60 +266,6 @@ TextAttrsMgr::LangTextAttr::
}
////////////////////////////////////////////////////////////////////////////////
// CSSTextAttr
////////////////////////////////////////////////////////////////////////////////
TextAttrsMgr::CSSTextAttr::
CSSTextAttr(PRUint32 aIndex, nsIContent* aRootElm, nsIContent* aElm) :
TTextAttr<nsString>(!aElm), mIndex(aIndex)
{
mIsRootDefined = GetValueFor(aRootElm, &mRootNativeValue);
if (aElm)
mIsDefined = GetValueFor(aElm, &mNativeValue);
}
bool
TextAttrsMgr::CSSTextAttr::
GetValueFor(nsIContent* aElm, nsString* aValue)
{
nsCOMPtr<nsIDOMCSSStyleDeclaration> currStyleDecl =
nsCoreUtils::GetComputedStyleDeclaration(EmptyString(), aElm);
if (!currStyleDecl)
return false;
NS_ConvertASCIItoUTF16 cssName(gCSSTextAttrsMap[mIndex].mCSSName);
nsresult rv = currStyleDecl->GetPropertyValue(cssName, *aValue);
if (NS_FAILED(rv))
return true;
const char *cssValue = gCSSTextAttrsMap[mIndex].mCSSValue;
if (cssValue != kAnyValue && !aValue->EqualsASCII(cssValue))
return false;
return true;
}
void
TextAttrsMgr::CSSTextAttr::
ExposeValue(nsIPersistentProperties* aAttributes, const nsString& aValue)
{
const char* attrValue = gCSSTextAttrsMap[mIndex].mAttrValue;
if (attrValue != kCopyValue) {
nsAutoString formattedValue;
AppendASCIItoUTF16(attrValue, formattedValue);
nsAccUtils::SetAccAttr(aAttributes, *gCSSTextAttrsMap[mIndex].mAttrName,
formattedValue);
return;
}
nsAccUtils::SetAccAttr(aAttributes, *gCSSTextAttrsMap[mIndex].mAttrName,
aValue);
}
////////////////////////////////////////////////////////////////////////////////
// BGColorTextAttr
////////////////////////////////////////////////////////////////////////////////
@ -742,3 +661,104 @@ TextAttrsMgr::TextDecorTextAttr::
formattedColor);
}
}
////////////////////////////////////////////////////////////////////////////////
// TextPosTextAttr
////////////////////////////////////////////////////////////////////////////////
TextAttrsMgr::TextPosTextAttr::
TextPosTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame) :
TTextAttr<TextPosValue>(!aFrame)
{
mRootNativeValue = GetTextPosValue(aRootFrame);
mIsRootDefined = mRootNativeValue != eTextPosNone;
if (aFrame) {
mNativeValue = GetTextPosValue(aFrame);
mIsDefined = mNativeValue != eTextPosNone;
}
}
bool
TextAttrsMgr::TextPosTextAttr::
GetValueFor(nsIContent* aContent, TextPosValue* aValue)
{
nsIFrame* frame = aContent->GetPrimaryFrame();
if (frame) {
*aValue = GetTextPosValue(frame);
return *aValue != eTextPosNone;
}
return false;
}
void
TextAttrsMgr::TextPosTextAttr::
ExposeValue(nsIPersistentProperties* aAttributes, const TextPosValue& aValue)
{
switch (aValue) {
case eTextPosBaseline:
nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::textPosition,
NS_LITERAL_STRING("baseline"));
break;
case eTextPosSub:
nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::textPosition,
NS_LITERAL_STRING("sub"));
break;
case eTextPosSuper:
nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::textPosition,
NS_LITERAL_STRING("super"));
break;
}
}
TextAttrsMgr::TextPosValue
TextAttrsMgr::TextPosTextAttr::
GetTextPosValue(nsIFrame* aFrame) const
{
const nsStyleCoord& styleCoord = aFrame->GetStyleTextReset()->mVerticalAlign;
switch (styleCoord.GetUnit()) {
case eStyleUnit_Enumerated:
switch (styleCoord.GetIntValue()) {
case NS_STYLE_VERTICAL_ALIGN_BASELINE:
return eTextPosBaseline;
case NS_STYLE_VERTICAL_ALIGN_SUB:
return eTextPosSub;
case NS_STYLE_VERTICAL_ALIGN_SUPER:
return eTextPosSuper;
// No good guess for these:
// NS_STYLE_VERTICAL_ALIGN_TOP
// NS_STYLE_VERTICAL_ALIGN_TEXT_TOP
// NS_STYLE_VERTICAL_ALIGN_MIDDLE
// NS_STYLE_VERTICAL_ALIGN_TEXT_BOTTOM
// NS_STYLE_VERTICAL_ALIGN_BOTTOM
// NS_STYLE_VERTICAL_ALIGN_MIDDLE_WITH_BASELINE
// Do not expose value of text-position attribute.
default:
break;
}
return eTextPosNone;
case eStyleUnit_Percent:
{
float percentValue = styleCoord.GetPercentValue();
return percentValue > 0 ?
eTextPosSuper :
(percentValue < 0 ? eTextPosSub : eTextPosBaseline);
}
case eStyleUnit_Coord:
{
nscoord coordValue = styleCoord.GetCoordValue();
return coordValue > 0 ?
eTextPosSuper :
(coordValue < 0 ? eTextPosSub : eTextPosBaseline);
}
}
return eTextPosNone;
}

View File

@ -107,11 +107,12 @@ protected:
* its value before or after the given offsets.
*
* @param aTextAttrArray [in] text attributes array
* @param aAttrArrayLen [in] text attributes array length
* @param aStartHTOffset [in, out] the start offset
* @param aEndHTOffset [in, out] the end offset
*/
class TextAttr;
void GetRange(const nsTArray<TextAttr*>& aTextAttrArray,
void GetRange(TextAttr* aAttrArray[], PRUint32 aAttrArrayLen,
PRInt32* aStartHTOffset, PRInt32* aEndHTOffset);
private:
@ -157,7 +158,7 @@ protected:
public:
TTextAttr(bool aGetRootValue) : mGetRootValue(aGetRootValue) {}
// ITextAttr
// TextAttr
virtual void Expose(nsIPersistentProperties* aAttributes,
bool aIncludeDefAttrValue)
{
@ -242,27 +243,6 @@ protected:
};
/**
* Class is used for the work with CSS based text attributes.
*/
class CSSTextAttr : public TTextAttr<nsString>
{
public:
CSSTextAttr(PRUint32 aIndex, nsIContent* aRootElm, nsIContent* aElm);
virtual ~CSSTextAttr() { }
protected:
// TextAttr
virtual bool GetValueFor(nsIContent* aElm, nsString* aValue);
virtual void ExposeValue(nsIPersistentProperties* aAttributes,
const nsString& aValue);
private:
PRInt32 mIndex;
};
/**
* Class is used for the work with 'background-color' text attribute.
*/
@ -435,6 +415,34 @@ protected:
const TextDecorValue& aValue);
};
/**
* Class is used for the work with "text-position" text attribute.
*/
enum TextPosValue {
eTextPosNone = 0,
eTextPosBaseline,
eTextPosSub,
eTextPosSuper
};
class TextPosTextAttr : public TTextAttr<TextPosValue>
{
public:
TextPosTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame);
virtual ~TextPosTextAttr() { }
protected:
// TextAttr
virtual bool GetValueFor(nsIContent* aElm, TextPosValue* aValue);
virtual void ExposeValue(nsIPersistentProperties* aAttributes,
const TextPosValue& aValue);
private:
TextPosValue GetTextPosValue(nsIFrame* aFrame) const;
};
}; // TextAttrMgr
} // namespace a11y

View File

@ -181,6 +181,30 @@
attrs = {"text-position": gComputedStyle.verticalAlign};
testTextAttrs(ID, 55, attrs, defAttrs, 55, 64);
attrs = {};
testTextAttrs(ID, 64, attrs, defAttrs, 64, 69);
attrs = { "text-position": "super" };
testTextAttrs(ID, 69, attrs, defAttrs, 69, 84);
attrs = {};
testTextAttrs(ID, 84, attrs, defAttrs, 84, 89);
attrs = { "text-position": "sub" };
testTextAttrs(ID, 89, attrs, defAttrs, 89, 102);
attrs = {};
testTextAttrs(ID, 102, attrs, defAttrs, 102, 107);
attrs = { "text-position": "super" };
testTextAttrs(ID, 107, attrs, defAttrs, 107, 123);
attrs = {};
testTextAttrs(ID, 123, attrs, defAttrs, 123, 128);
attrs = { "text-position": "sub" };
testTextAttrs(ID, 128, attrs, defAttrs, 128, 142);
//////////////////////////////////////////////////////////////////////////
// area7
ID = "area7";
@ -505,6 +529,11 @@
title="Implement text attributes">
Mozilla Bug 345759
</a>
<a target="_blank"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=473569"
title="Restrict text-position to allowed values">
Mozilla Bug 473569
</a>
<a target="_blank"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=473576"
title="font-family text attribute should expose actual font used">
@ -549,7 +578,11 @@
This <sup>sentence</sup> has the word
<span style="vertical-align:super;">sentence</span> in
<sub>superscript</sub> and
<span style="vertical-align:sub;">subscript</span>
<span style="vertical-align:sub;">subscript</span> and
<span style="vertical-align:20%;">superscript 20%</span> and
<span style="vertical-align:-20%;">subscript 20%</span> and
<span style="vertical-align:20px;">superscript 20px</span> and
<span style="vertical-align:-20px;">subscript 20px</span>
</p>
<p lang="en" id="area7">

View File

@ -376,31 +376,26 @@ PlacesViewBase.prototype = {
_setLivemarkStatusMenuItem:
function PVB_setLivemarkStatusMenuItem(aPopup, aStatus) {
let statusMenuitem = aPopup._statusMenuitem;
let stringId = "";
if (aStatus == Ci.mozILivemark.STATUS_LOADING)
stringId = "bookmarksLivemarkLoading";
else if (aStatus == Ci.mozILivemark.STATUS_FAILED)
stringId = "bookmarksLivemarkFailed";
if (stringId && !statusMenuitem) {
if (!statusMenuitem) {
// Create the status menuitem and cache it in the popup object.
statusMenuitem = document.createElement("menuitem");
statusMenuitem.setAttribute("livemarkStatus", stringId);
statusMenuitem.className = "livemarkstatus-menuitem";
statusMenuitem.setAttribute("label", PlacesUIUtils.getString(stringId));
statusMenuitem.setAttribute("disabled", true);
aPopup.insertBefore(statusMenuitem, aPopup._startMarker.nextSibling);
aPopup._statusMenuitem = statusMenuitem;
}
else if (stringId &&
statusMenuitem.getAttribute("livemarkStatus") != stringId) {
if (aStatus == Ci.mozILivemark.STATUS_LOADING ||
aStatus == Ci.mozILivemark.STATUS_FAILED) {
// Status has changed, update the cached status menuitem.
let stringId = aStatus == Ci.mozILivemark.STATUS_LOADING ?
"bookmarksLivemarkLoading" : "bookmarksLivemarkFailed";
statusMenuitem.setAttribute("label", PlacesUIUtils.getString(stringId));
if (aPopup._startMarker.nextSibling != statusMenuitem)
aPopup.insertBefore(statusMenuitem, aPopup._startMarker.nextSibling);
}
else if (!stringId && statusMenuitem) {
else {
// The livemark has finished loading.
aPopup.removeChild(aPopup._statusMenuitem);
aPopup._statusMenuitem = null;
}
},
@ -1017,9 +1012,10 @@ PlacesToolbar.prototype = {
_updateChevronPopupNodesVisibility:
function PT__updateChevronPopupNodesVisibility() {
for (let i = 0; i < this._chevronPopup.childNodes.length; i++) {
this._chevronPopup.childNodes[i].hidden =
this._rootElt.childNodes[i].style.visibility != "hidden";
for (let i = 0, node = this._chevronPopup._startMarker.nextSibling;
node != this._chevronPopup._endMarker;
i++, node = node.nextSibling) {
node.hidden = this._rootElt.childNodes[i].style.visibility != "hidden";
}
},

View File

@ -18,3 +18,6 @@ ac_add_options --with-ccache=/usr/bin/ccache
# Treat warnings as errors in directories with FAIL_ON_WARNINGS.
ac_add_options --enable-warnings-as-errors
# Package js shell.
export MOZ_PACKAGE_JSSHELL=1

View File

@ -27,3 +27,6 @@ ac_add_options --with-ccache=/usr/bin/ccache
# Treat warnings as errors in directories with FAIL_ON_WARNINGS.
ac_add_options --enable-warnings-as-errors
# Package js shell.
export MOZ_PACKAGE_JSSHELL=1

View File

@ -21,3 +21,6 @@ ac_add_options --enable-warnings-as-errors
# Enable parallel compiling
mk_add_options MOZ_MAKE_FLAGS="-j4"
# Package js shell.
export MOZ_PACKAGE_JSSHELL=1

View File

@ -15,3 +15,6 @@ mk_add_options MOZ_MAKE_FLAGS="-j4"
# Treat warnings as errors in directories with FAIL_ON_WARNINGS.
ac_add_options --enable-warnings-as-errors
# Package js shell.
export MOZ_PACKAGE_JSSHELL=1

View File

@ -27,3 +27,6 @@ ac_add_options --with-ccache=/usr/bin/ccache
# Treat warnings as errors in directories with FAIL_ON_WARNINGS.
ac_add_options --enable-warnings-as-errors
# Package js shell.
export MOZ_PACKAGE_JSSHELL=1

View File

@ -21,3 +21,6 @@ ac_add_options --enable-warnings-as-errors
# Enable parallel compiling
mk_add_options MOZ_MAKE_FLAGS="-j4"
# Package js shell.
export MOZ_PACKAGE_JSSHELL=1

View File

@ -22,3 +22,6 @@ ac_add_options --with-macbundlename-prefix=Firefox
# Treat warnings as errors in directories with FAIL_ON_WARNINGS.
ac_add_options --enable-warnings-as-errors
# Package js shell.
export MOZ_PACKAGE_JSSHELL=1

View File

@ -17,3 +17,6 @@ ac_add_options --enable-warnings-as-errors
# Enable parallel compiling
mk_add_options MOZ_MAKE_FLAGS="-j4"
# Package js shell.
export MOZ_PACKAGE_JSSHELL=1

View File

@ -10,3 +10,6 @@ mk_add_options MOZ_MAKE_FLAGS="-j4"
export MOZILLA_OFFICIAL=1
ac_add_options --with-macbundlename-prefix=Firefox
# Package js shell.
export MOZ_PACKAGE_JSSHELL=1

View File

@ -15,3 +15,6 @@ ac_add_options --with-macbundlename-prefix=Firefox
# Treat warnings as errors in directories with FAIL_ON_WARNINGS.
ac_add_options --enable-warnings-as-errors
# Package js shell.
export MOZ_PACKAGE_JSSHELL=1

View File

@ -8,3 +8,6 @@ export MOZILLA_OFFICIAL=1
mk_add_options MOZ_MAKE_FLAGS=-j1
. $topsrcdir/browser/config/mozconfigs/win32/vs2010-mozconfig
# Package js shell.
export MOZ_PACKAGE_JSSHELL=1

View File

@ -17,3 +17,6 @@ export MOZ_TELEMETRY_REPORTING=1
mk_add_options MOZ_MAKE_FLAGS=-j1
. $topsrcdir/browser/config/mozconfigs/win32/vs2010-mozconfig
# Package js shell.
export MOZ_PACKAGE_JSSHELL=1

View File

@ -13,3 +13,6 @@ export MOZILLA_OFFICIAL=1
export MOZ_TELEMETRY_REPORTING=1
. $topsrcdir/browser/config/mozconfigs/win32/vs2010-mozconfig
# Package js shell.
export MOZ_PACKAGE_JSSHELL=1

View File

@ -9,3 +9,8 @@ ac_add_options --enable-signmar
export MOZILLA_OFFICIAL=1
mk_add_options MOZ_MAKE_FLAGS=-j1
# Package js shell.
export MOZ_PACKAGE_JSSHELL=1
. $topsrcdir/browser/config/mozconfigs/win64/vs2010-mozconfig

View File

@ -18,3 +18,8 @@ export MOZILLA_OFFICIAL=1
export MOZ_TELEMETRY_REPORTING=1
mk_add_options MOZ_MAKE_FLAGS=-j1
# Package js shell.
export MOZ_PACKAGE_JSSHELL=1
. $topsrcdir/browser/config/mozconfigs/win64/vs2010-mozconfig

View File

@ -0,0 +1,16 @@
export INCLUDE=/c/tools/msvs10/vc/include:/c/tools/msvs10/vc/atlmfc/include:/c/tools/sdks/v7.0/include:/c/tools/sdks/v7.0/include/atl:/c/tools/sdks/dx10/include
export LIBPATH=/c/tools/msvs10/vc/lib/amd64:/c/tools/msvs10/vc/atlmfc/lib/amd64
export LIB=/c/tools/msvs10/vc/lib/amd64:/c/tools/msvs10/vc/atlmfc/lib/amd64:/c/tools/sdks/v7.0/lib/x64:/c/tools/sdks/dx10/lib/x64
export PATH="/c/tools/msvs10/Common7/IDE:/c/tools/msvs10/VC/BIN/amd64:/c/tools/msvs10/VC/BIN/x86_amd64:/c/tools/msvs10/VC/BIN:/c/tools/msvs10/Common7/Tools:/c/tools/msvs10/VC/VCPackages:${PATH}"
export WIN32_REDIST_DIR=/c/tools/msvs10/VC/redist/x64/Microsoft.VC100.CRT
# Use 32bit linker for PGO crash bug.
# https://connect.microsoft.com/VisualStudio/feedback/details/686117/
export LD=/c/tools/msvs10/VC/BIN/x86_amd64/link.exe
mk_add_options "export LIB=$LIB"
mk_add_options "export LIBPATH=$LIBPATH"
mk_add_options "export PATH=$PATH"
mk_add_options "export INCLUDE=$INCLUDE"
mk_add_options "export WIN32_REDIST_DIR=$WIN32_REDIST_DIR"

View File

@ -450,41 +450,33 @@ RPMBUILD = @RPMBUILD@
ifdef MOZ_NATIVE_JPEG
JPEG_CFLAGS = @JPEG_CFLAGS@
JPEG_LIBS = @JPEG_LIBS@
JPEG_REQUIRES =
else
JPEG_CFLAGS = @MOZ_JPEG_CFLAGS@
JPEG_LIBS = @MOZ_JPEG_LIBS@
JPEG_REQUIRES = jpeg
endif
ifdef MOZ_NATIVE_ZLIB
ZLIB_CFLAGS = @ZLIB_CFLAGS@
ZLIB_LIBS = @ZLIB_LIBS@
ZLIB_REQUIRES =
else
ZLIB_CFLAGS = @MOZ_ZLIB_CFLAGS@
MOZ_ZLIB_LIBS = @MOZ_ZLIB_LIBS@
ZLIB_REQUIRES = zlib
endif
ifdef MOZ_NATIVE_BZ2
BZ2_CFLAGS = @BZ2_CFLAGS@
BZ2_LIBS = @BZ2_LIBS@
BZ2_REQUIRES =
else
BZ2_CFLAGS = @MOZ_BZ2_CFLAGS@
BZ2_LIBS = @MOZ_BZ2_LIBS@
BZ2_REQUIRES = libbz2
endif
ifdef MOZ_NATIVE_PNG
PNG_CFLAGS = @PNG_CFLAGS@
PNG_LIBS = @PNG_LIBS@
PNG_REQUIRES =
else
PNG_CFLAGS = @MOZ_PNG_CFLAGS@
PNG_LIBS = @MOZ_PNG_LIBS@
PNG_REQUIRES = png
endif
QCMS_LIBS = @QCMS_LIBS@
@ -707,6 +699,8 @@ MOZ_INSTRUMENT_EVENT_LOOP = @MOZ_INSTRUMENT_EVENT_LOOP@
MOZ_SYSTEM_PLY = @MOZ_SYSTEM_PLY@
MOZ_PACKAGE_JSSHELL = @MOZ_PACKAGE_JSSHELL@
# We only want to do the pymake sanity on Windows, other os's can cope
ifeq ($(HOST_OS_ARCH),WINNT)
# Ensure invariants between GNU Make and pymake

View File

@ -1911,9 +1911,6 @@ echo-dirs:
echo-module:
@echo $(MODULE)
echo-requires:
@echo $(REQUIRES)
echo-depth-path:
@$(topsrcdir)/build/unix/print-depth-path.sh
@ -2020,7 +2017,6 @@ FREEZE_VARIABLES = \
DIRS \
LIBRARY \
MODULE \
REQUIRES \
SHORT_LIBNAME \
TIERS \
EXTRA_COMPONENTS \

View File

@ -8831,6 +8831,8 @@ AC_SUBST(LIBJPEG_TURBO_X86_ASM)
AC_SUBST(LIBJPEG_TURBO_X64_ASM)
AC_SUBST(LIBJPEG_TURBO_ARM_ASM)
AC_SUBST(MOZ_PACKAGE_JSSHELL)
AC_MSG_CHECKING([for posix_fallocate])
AC_TRY_LINK([#define _XOPEN_SOURCE 600
#include <fcntl.h>],

View File

@ -59,6 +59,8 @@
#include "mozilla/dom/indexedDB/FileInfo.h"
#include "mozilla/dom/indexedDB/FileManager.h"
#include "mozilla/dom/indexedDB/IndexedDatabaseManager.h"
#include "nsWrapperCache.h"
#include "nsCycleCollectionParticipant.h"
class nsIFile;
class nsIInputStream;
@ -326,22 +328,38 @@ protected:
nsRefPtr<DataOwner> mDataOwner;
};
class nsDOMFileList : public nsIDOMFileList
class nsDOMFileList MOZ_FINAL : public nsIDOMFileList,
public nsWrapperCache
{
public:
NS_DECL_ISUPPORTS
nsDOMFileList(nsISupports *aParent) : mParent(aParent)
{
SetIsProxy();
}
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(nsDOMFileList)
NS_DECL_NSIDOMFILELIST
virtual JSObject* WrapObject(JSContext *cx, XPCWrappedNativeScope *scope,
bool *triedToWrap);
nsISupports* GetParentObject()
{
return mParent;
}
void Disconnect()
{
mParent = nsnull;
}
bool Append(nsIDOMFile *aFile) { return mFiles.AppendObject(aFile); }
bool Remove(PRUint32 aIndex) { return mFiles.RemoveObjectAt(aIndex); }
void Clear() { return mFiles.Clear(); }
nsIDOMFile* GetItemAt(PRUint32 aIndex)
{
return mFiles.SafeObjectAt(aIndex);
}
static nsDOMFileList* FromSupports(nsISupports* aSupports)
{
#ifdef DEBUG
@ -361,6 +379,7 @@ public:
private:
nsCOMArray<nsIDOMFile> mFiles;
nsISupports *mParent;
};
class NS_STACK_CLASS nsDOMFileInternalUrlHolder {

View File

@ -43,5 +43,6 @@ interface nsIDOMFile;
interface nsIDOMFileList : nsISupports
{
readonly attribute unsigned long length;
nsIDOMFile item(in unsigned long index);
[getter,forward(getItemAt)] nsIDOMFile item(in unsigned long index);
[noscript,notxpcom,nostdcall] nsIDOMFile getItemAt(in unsigned long index);
};

View File

@ -67,6 +67,7 @@
#include "plbase64.h"
#include "prmem.h"
#include "dombindings.h"
using namespace mozilla;
using namespace mozilla::dom;
@ -607,14 +608,39 @@ nsDOMMemoryFile::GetInternalStream(nsIInputStream **aStream)
DOMCI_DATA(FileList, nsDOMFileList)
NS_INTERFACE_MAP_BEGIN(nsDOMFileList)
NS_IMPL_CYCLE_COLLECTION_CLASS(nsDOMFileList)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsDOMFileList)
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsDOMFileList)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsDOMFileList)
NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
NS_IMPL_CYCLE_COLLECTION_TRACE_END
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsDOMFileList)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMFileList)
NS_INTERFACE_MAP_ENTRY(nsIDOMFileList)
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(FileList)
NS_INTERFACE_MAP_END
NS_IMPL_ADDREF(nsDOMFileList)
NS_IMPL_RELEASE(nsDOMFileList)
NS_IMPL_CYCLE_COLLECTING_ADDREF(nsDOMFileList)
NS_IMPL_CYCLE_COLLECTING_RELEASE(nsDOMFileList)
JSObject*
nsDOMFileList::WrapObject(JSContext *cx, XPCWrappedNativeScope *scope,
bool *triedToWrap)
{
return mozilla::dom::binding::FileList::create(cx, scope, this, triedToWrap);
}
nsIDOMFile*
nsDOMFileList::GetItemAt(PRUint32 aIndex)
{
return mFiles.SafeObjectAt(aIndex);
}
NS_IMETHODIMP
nsDOMFileList::GetLength(PRUint32* aLength)
@ -627,7 +653,7 @@ nsDOMFileList::GetLength(PRUint32* aLength)
NS_IMETHODIMP
nsDOMFileList::Item(PRUint32 aIndex, nsIDOMFile **aFile)
{
NS_IF_ADDREF(*aFile = GetItemAt(aIndex));
NS_IF_ADDREF(*aFile = nsDOMFileList::GetItemAt(aIndex));
return NS_OK;
}

View File

@ -8465,7 +8465,8 @@ NS_IMETHODIMP
nsDocument::CreateTouchList(nsIVariant* aPoints,
nsIDOMTouchList** aRetVal)
{
nsRefPtr<nsDOMTouchList> retval = new nsDOMTouchList();
nsRefPtr<nsDOMTouchList> retval =
new nsDOMTouchList(static_cast<nsIDocument*>(this));
if (aPoints) {
PRUint16 type;
aPoints->GetDataType(&type);

View File

@ -2314,7 +2314,7 @@ nsGenericElement::GetClientRects(nsIDOMClientRectList** aResult)
{
*aResult = nsnull;
nsRefPtr<nsClientRectList> rectList = new nsClientRectList();
nsRefPtr<nsClientRectList> rectList = new nsClientRectList(this);
nsIFrame* frame = GetPrimaryFrame(Flush_Layout);
if (!frame) {

View File

@ -2499,7 +2499,8 @@ nsRange::GetClientRects(nsIDOMClientRectList** aResult)
if (!mStartParent)
return NS_OK;
nsRefPtr<nsClientRectList> rectList = new nsClientRectList();
nsRefPtr<nsClientRectList> rectList =
new nsClientRectList(static_cast<nsIDOMRange*>(this));
if (!rectList)
return NS_ERROR_OUT_OF_MEMORY;

View File

@ -58,7 +58,20 @@
using namespace mozilla;
NS_IMPL_CYCLE_COLLECTION_2(nsDOMDataTransfer, mDragTarget, mDragImage)
NS_IMPL_CYCLE_COLLECTION_CLASS(nsDOMDataTransfer)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsDOMDataTransfer)
if (tmp->mFiles) {
tmp->mFiles->Disconnect();
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mFiles)
}
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mDragTarget)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mDragImage)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsDOMDataTransfer)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mFiles)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mDragTarget)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mDragImage)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTING_ADDREF(nsDOMDataTransfer)
NS_IMPL_CYCLE_COLLECTING_RELEASE(nsDOMDataTransfer)
@ -235,7 +248,7 @@ nsDOMDataTransfer::GetFiles(nsIDOMFileList** aFileList)
return NS_OK;
if (!mFiles) {
mFiles = new nsDOMFileList();
mFiles = new nsDOMFileList(static_cast<nsIDOMDataTransfer*>(this));
NS_ENSURE_TRUE(mFiles, NS_ERROR_OUT_OF_MEMORY);
PRUint32 count = mItems.Length();

View File

@ -105,6 +105,13 @@ protected:
PRUint32 aDragImageX,
PRUint32 aDragImageY);
~nsDOMDataTransfer()
{
if (mFiles) {
mFiles->Disconnect();
}
}
static const char sEffects[8][9];
public:

View File

@ -103,7 +103,8 @@ nsDOMNotifyPaintEvent::GetBoundingClientRect(nsIDOMClientRect** aResult)
NS_IMETHODIMP
nsDOMNotifyPaintEvent::GetClientRects(nsIDOMClientRectList** aResult)
{
nsRefPtr<nsClientRectList> rectList = new nsClientRectList();
nsRefPtr<nsClientRectList> rectList =
new nsClientRectList(static_cast<nsIDOMEvent*>(static_cast<nsDOMEvent*>(this)));
if (!rectList)
return NS_ERROR_OUT_OF_MEMORY;
@ -125,7 +126,8 @@ nsDOMNotifyPaintEvent::GetClientRects(nsIDOMClientRectList** aResult)
NS_IMETHODIMP
nsDOMNotifyPaintEvent::GetPaintRequests(nsIDOMPaintRequestList** aResult)
{
nsRefPtr<nsPaintRequestList> requests = new nsPaintRequestList();
nsRefPtr<nsPaintRequestList> requests =
new nsPaintRequestList(static_cast<nsDOMEvent*>(this));
if (!requests)
return NS_ERROR_OUT_OF_MEMORY;

View File

@ -160,16 +160,13 @@ nsDOMTouch::Equals(nsIDOMTouch* aTouch)
}
// TouchList
nsDOMTouchList::nsDOMTouchList(nsTArray<nsCOMPtr<nsIDOMTouch> > &aTouches)
{
mPoints.AppendElements(aTouches);
}
DOMCI_DATA(TouchList, nsDOMTouchList)
NS_IMPL_CYCLE_COLLECTION_CLASS(nsDOMTouchList)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsDOMTouchList)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_ENTRY(nsIDOMTouchList)
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(TouchList)
@ -177,10 +174,16 @@ NS_INTERFACE_MAP_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsDOMTouchList)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSTARRAY_OF_NSCOMPTR(mPoints)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mParent)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsDOMTouchList)
NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
NS_IMPL_CYCLE_COLLECTION_TRACE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsDOMTouchList)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSTARRAY(mPoints)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mParent)
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTING_ADDREF(nsDOMTouchList)
@ -196,7 +199,7 @@ nsDOMTouchList::GetLength(PRUint32* aLength)
NS_IMETHODIMP
nsDOMTouchList::Item(PRUint32 aIndex, nsIDOMTouch** aRetVal)
{
NS_IF_ADDREF(*aRetVal = mPoints.SafeElementAt(aIndex, nsnull));
NS_IF_ADDREF(*aRetVal = nsDOMTouchList::GetItemAt(aIndex));
return NS_OK;
}
@ -216,6 +219,12 @@ nsDOMTouchList::IdentifiedTouch(PRInt32 aIdentifier, nsIDOMTouch** aRetVal)
return NS_OK;
}
nsIDOMTouch*
nsDOMTouchList::GetItemAt(PRUint32 aIndex)
{
return mPoints.SafeElementAt(aIndex, nsnull);
}
// TouchEvent
nsDOMTouchEvent::nsDOMTouchEvent(nsPresContext* aPresContext,
@ -322,9 +331,11 @@ nsDOMTouchEvent::GetTouches(nsIDOMTouchList** aTouches)
unchangedTouches.AppendElement(touches[i]);
}
}
t = new nsDOMTouchList(unchangedTouches);
t = new nsDOMTouchList(static_cast<nsIDOMTouchEvent*>(this),
unchangedTouches);
} else {
t = new nsDOMTouchList(touchEvent->touches);
t = new nsDOMTouchList(static_cast<nsIDOMTouchEvent*>(this),
touchEvent->touches);
}
mTouches = t;
return CallQueryInterface(mTouches, aTouches);
@ -354,7 +365,8 @@ nsDOMTouchEvent::GetTargetTouches(nsIDOMTouchList** aTargetTouches)
}
}
}
mTargetTouches = new nsDOMTouchList(targetTouches);
mTargetTouches = new nsDOMTouchList(static_cast<nsIDOMTouchEvent*>(this),
targetTouches);
return CallQueryInterface(mTargetTouches, aTargetTouches);
}
@ -376,7 +388,8 @@ nsDOMTouchEvent::GetChangedTouches(nsIDOMTouchList** aChangedTouches)
changedTouches.AppendElement(touches[i]);
}
}
mChangedTouches = new nsDOMTouchList(changedTouches);
mChangedTouches = new nsDOMTouchList(static_cast<nsIDOMTouchEvent*>(this),
changedTouches);
return CallQueryInterface(mChangedTouches, aChangedTouches);
}

View File

@ -41,6 +41,8 @@
#include "nsIDOMTouchEvent.h"
#include "nsString.h"
#include "nsTArray.h"
#include "nsIDocument.h"
#include "dombindings.h"
class nsDOMTouch : public nsIDOMTouch
{
@ -127,27 +129,46 @@ protected:
float mForce;
};
class nsDOMTouchList : public nsIDOMTouchList
class nsDOMTouchList MOZ_FINAL : public nsIDOMTouchList,
public nsWrapperCache
{
public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_CLASS(nsDOMTouchList)
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(nsDOMTouchList)
NS_DECL_NSIDOMTOUCHLIST
nsDOMTouchList() { }
nsDOMTouchList(nsTArray<nsCOMPtr<nsIDOMTouch> > &aTouches);
nsDOMTouchList(nsISupports *aParent) : mParent(aParent)
{
SetIsProxy();
}
nsDOMTouchList(nsISupports *aParent,
nsTArray<nsCOMPtr<nsIDOMTouch> > &aTouches)
: mPoints(aTouches),
mParent(aParent)
{
SetIsProxy();
}
virtual JSObject* WrapObject(JSContext *cx, XPCWrappedNativeScope *scope,
bool *triedToWrap)
{
return mozilla::dom::binding::TouchList::create(cx, scope, this,
triedToWrap);
}
nsISupports *GetParentObject()
{
return mParent;
}
void Append(nsIDOMTouch* aPoint)
{
mPoints.AppendElement(aPoint);
}
nsIDOMTouch* GetItemAt(PRUint32 aIndex)
{
return mPoints.SafeElementAt(aIndex, nsnull);
}
protected:
nsTArray<nsCOMPtr<nsIDOMTouch> > mPoints;
nsCOMPtr<nsISupports> mParent;
};
class nsDOMTouchEvent : public nsDOMUIEvent,

View File

@ -41,6 +41,7 @@
#include "nsDOMClassInfoID.h"
#include "nsClientRect.h"
#include "nsIFrame.h"
#include "nsContentUtils.h"
DOMCI_DATA(PaintRequest, nsPaintRequest)
@ -83,15 +84,28 @@ nsPaintRequest::GetReason(nsAString& aResult)
DOMCI_DATA(PaintRequestList, nsPaintRequestList)
NS_IMPL_CYCLE_COLLECTION_CLASS(nsPaintRequestList)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsPaintRequestList)
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mParent)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsPaintRequestList)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mParent)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsPaintRequestList)
NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
NS_IMPL_CYCLE_COLLECTION_TRACE_END
NS_INTERFACE_TABLE_HEAD(nsPaintRequestList)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_TABLE1(nsPaintRequestList, nsIDOMPaintRequestList)
NS_INTERFACE_TABLE_TO_MAP_SEGUE
NS_INTERFACE_TABLE_TO_MAP_SEGUE_CYCLE_COLLECTION(nsPaintRequestList)
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(PaintRequestList)
NS_INTERFACE_MAP_END
NS_IMPL_ADDREF(nsPaintRequestList)
NS_IMPL_RELEASE(nsPaintRequestList)
NS_IMPL_CYCLE_COLLECTING_ADDREF(nsPaintRequestList)
NS_IMPL_CYCLE_COLLECTING_RELEASE(nsPaintRequestList)
NS_IMETHODIMP
nsPaintRequestList::GetLength(PRUint32* aLength)
@ -103,6 +117,12 @@ nsPaintRequestList::GetLength(PRUint32* aLength)
NS_IMETHODIMP
nsPaintRequestList::Item(PRUint32 aIndex, nsIDOMPaintRequest** aReturn)
{
NS_IF_ADDREF(*aReturn = GetItemAt(aIndex));
NS_IF_ADDREF(*aReturn = nsPaintRequestList::GetItemAt(aIndex));
return NS_OK;
}
nsIDOMPaintRequest*
nsPaintRequestList::GetItemAt(PRUint32 aIndex)
{
return mArray.SafeObjectAt(aIndex);
}

View File

@ -42,7 +42,8 @@
#include "nsIDOMPaintRequest.h"
#include "nsIDOMPaintRequestList.h"
#include "nsPresContext.h"
#include "nsClientRect.h"
#include "nsIDOMEvent.h"
#include "dombindings.h"
class nsPaintRequest : public nsIDOMPaintRequest
{
@ -61,21 +62,33 @@ private:
nsInvalidateRequestList::Request mRequest;
};
class nsPaintRequestList : public nsIDOMPaintRequestList
class nsPaintRequestList MOZ_FINAL : public nsIDOMPaintRequestList,
public nsWrapperCache
{
public:
nsPaintRequestList() {}
nsPaintRequestList(nsIDOMEvent *aParent) : mParent(aParent)
{
SetIsProxy();
}
NS_DECL_ISUPPORTS
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(nsPaintRequestList)
NS_DECL_NSIDOMPAINTREQUESTLIST
void Append(nsIDOMPaintRequest* aElement) { mArray.AppendObject(aElement); }
nsIDOMPaintRequest* GetItemAt(PRUint32 aIndex)
virtual JSObject* WrapObject(JSContext *cx, XPCWrappedNativeScope *scope,
bool *triedToWrap)
{
return mArray.SafeObjectAt(aIndex);
return mozilla::dom::binding::PaintRequestList::create(cx, scope, this,
triedToWrap);
}
nsISupports* GetParentObject()
{
return mParent;
}
void Append(nsIDOMPaintRequest* aElement) { mArray.AppendObject(aElement); }
static nsPaintRequestList* FromSupports(nsISupports* aSupports)
{
#ifdef DEBUG
@ -97,6 +110,7 @@ private:
~nsPaintRequestList() {}
nsCOMArray<nsIDOMPaintRequest> mArray;
nsCOMPtr<nsIDOMEvent> mParent;
};
#endif /*NSPAINTREQUEST_H_*/

View File

@ -41,6 +41,7 @@
#include "nsDOMClassInfoID.h"
#include "nsPresContext.h"
#include "dombindings.h"
DOMCI_DATA(ClientRect, nsClientRect)
@ -102,14 +103,28 @@ nsClientRect::GetHeight(float* aResult)
DOMCI_DATA(ClientRectList, nsClientRectList)
NS_IMPL_CYCLE_COLLECTION_CLASS(nsClientRectList)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsClientRectList)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mParent)
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsClientRectList)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mParent)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsClientRectList)
NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
NS_IMPL_CYCLE_COLLECTION_TRACE_END
NS_INTERFACE_TABLE_HEAD(nsClientRectList)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_TABLE1(nsClientRectList, nsIDOMClientRectList)
NS_INTERFACE_TABLE_TO_MAP_SEGUE
NS_INTERFACE_TABLE_TO_MAP_SEGUE_CYCLE_COLLECTION(nsClientRectList)
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(ClientRectList)
NS_INTERFACE_MAP_END
NS_IMPL_ADDREF(nsClientRectList)
NS_IMPL_RELEASE(nsClientRectList)
NS_IMPL_CYCLE_COLLECTING_ADDREF(nsClientRectList)
NS_IMPL_CYCLE_COLLECTING_RELEASE(nsClientRectList)
NS_IMETHODIMP
@ -122,10 +137,24 @@ nsClientRectList::GetLength(PRUint32* aLength)
NS_IMETHODIMP
nsClientRectList::Item(PRUint32 aIndex, nsIDOMClientRect** aReturn)
{
NS_IF_ADDREF(*aReturn = GetItemAt(aIndex));
NS_IF_ADDREF(*aReturn = nsClientRectList::GetItemAt(aIndex));
return NS_OK;
}
nsIDOMClientRect*
nsClientRectList::GetItemAt(PRUint32 aIndex)
{
return mArray.SafeObjectAt(aIndex);
}
JSObject*
nsClientRectList::WrapObject(JSContext *cx, XPCWrappedNativeScope *scope,
bool *triedToWrap)
{
return mozilla::dom::binding::ClientRectList::create(cx, scope, this,
triedToWrap);
}
static double
RoundFloat(double aValue)
{

View File

@ -44,6 +44,8 @@
#include "nsCOMArray.h"
#include "nsRect.h"
#include "nsCOMPtr.h"
#include "nsWrapperCache.h"
#include "nsCycleCollectionParticipant.h"
class nsClientRect : public nsIDOMClientRect
{
@ -64,22 +66,30 @@ protected:
float mX, mY, mWidth, mHeight;
};
class nsClientRectList : public nsIDOMClientRectList
class nsClientRectList MOZ_FINAL : public nsIDOMClientRectList,
public nsWrapperCache
{
public:
nsClientRectList() {}
nsClientRectList(nsISupports *aParent) : mParent(aParent)
{
SetIsProxy();
}
NS_DECL_ISUPPORTS
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(nsClientRectList)
NS_DECL_NSIDOMCLIENTRECTLIST
void Append(nsIDOMClientRect* aElement) { mArray.AppendObject(aElement); }
virtual JSObject* WrapObject(JSContext *cx, XPCWrappedNativeScope *scope,
bool *triedToWrap);
nsIDOMClientRect* GetItemAt(PRUint32 aIndex)
nsISupports* GetParentObject()
{
return mArray.SafeObjectAt(aIndex);
return mParent;
}
void Append(nsIDOMClientRect* aElement) { mArray.AppendObject(aElement); }
static nsClientRectList* FromSupports(nsISupports* aSupports)
{
#ifdef DEBUG
@ -101,6 +111,7 @@ protected:
virtual ~nsClientRectList() {}
nsCOMArray<nsIDOMClientRect> mArray;
nsCOMPtr<nsISupports> mParent;
};
#endif /*NSCLIENTRECT_H_*/

View File

@ -587,6 +587,9 @@ nsHTMLInputElement::nsHTMLInputElement(already_AddRefed<nsINodeInfo> aNodeInfo,
nsHTMLInputElement::~nsHTMLInputElement()
{
if (mFileList) {
mFileList->Disconnect();
}
DestroyImageLoadingContent();
FreeData();
}
@ -634,7 +637,10 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsHTMLInputElement,
nsGenericHTMLFormElement)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mControllers)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMARRAY(mFiles)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mFileList);
if (tmp->mFileList) {
tmp->mFileList->Disconnect();
tmp->mFileList = nsnull;
}
//XXX should unlink more?
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
@ -2773,7 +2779,7 @@ nsHTMLInputElement::GetFiles(nsIDOMFileList** aFileList)
}
if (!mFileList) {
mFileList = new nsDOMFileList();
mFileList = new nsDOMFileList(static_cast<nsIContent*>(this));
if (!mFileList) return NS_ERROR_OUT_OF_MEMORY;
UpdateFileList();

View File

@ -37,9 +37,6 @@
*
* ***** END LICENSE BLOCK ***** */
#include "nsISeekableStream.h"
#include "nsClassHashtable.h"
#include "nsTArray.h"
#include "nsBuiltinDecoder.h"
#include "nsBuiltinDecoderReader.h"
#include "nsBuiltinDecoderStateMachine.h"

View File

@ -40,16 +40,10 @@
#define nsBuiltinDecoderReader_h_
#include <nsDeque.h>
#include "Layers.h"
#include "ImageLayers.h"
#include "nsClassHashtable.h"
#include "mozilla/TimeStamp.h"
#include "nsSize.h"
#include "nsRect.h"
#include "mozilla/ReentrantMonitor.h"
class nsBuiltinDecoderStateMachine;
// Stores info relevant to presenting media frames.
class nsVideoInfo {
public:

View File

@ -39,20 +39,8 @@
#include "nsMediaDecoder.h"
#include "MediaResource.h"
#include "prlog.h"
#include "prmem.h"
#include "nsIFrame.h"
#include "nsIDocument.h"
#include "nsThreadUtils.h"
#include "nsIDOMHTMLMediaElement.h"
#include "nsNetUtil.h"
#include "nsHTMLMediaElement.h"
#include "gfxContext.h"
#include "nsPresContext.h"
#include "nsDOMError.h"
#include "nsDisplayList.h"
#include "nsSVGEffects.h"
#include "VideoUtils.h"
using namespace mozilla;

View File

@ -38,22 +38,16 @@
#if !defined(nsMediaDecoder_h_)
#define nsMediaDecoder_h_
#include "mozilla/XPCOM.h"
#include "nsIPrincipal.h"
#include "nsSize.h"
#include "prlog.h"
#include "gfxContext.h"
#include "gfxRect.h"
#include "nsITimer.h"
#include "ImageLayers.h"
#include "mozilla/ReentrantMonitor.h"
#include "nsIMemoryReporter.h"
#include "VideoFrameContainer.h"
class nsHTMLMediaElement;
class nsIStreamListener;
class nsTimeRanges;
class nsIMemoryReporter;
class nsIPrincipal;
class nsITimer;
namespace mozilla {
class MediaResource;

View File

@ -36,7 +36,6 @@
*
* ***** END LICENSE BLOCK ***** */
#include "nsError.h"
#include "nsBuiltinDecoderStateMachine.h"
#include "nsBuiltinDecoder.h"
#include "MediaResource.h"
#include "nsWaveReader.h"

View File

@ -40,7 +40,8 @@
#include "nsBuiltinDecoderReader.h"
class nsMediaDecoder;
class nsBuiltinDecoder;
class nsTimeRanges;
class nsWaveReader : public nsBuiltinDecoderReader
{

View File

@ -41,10 +41,15 @@
#include "nsBuiltinDecoder.h"
#include "MediaResource.h"
#include "nsWebMReader.h"
#include "nsWebMBufferedParser.h"
#include "VideoUtils.h"
#include "nsTimeRanges.h"
#include "mozilla/Preferences.h"
#define VPX_DONT_DEFINE_STDINT_TYPES
#include "vpx/vp8dx.h"
#include "vpx/vpx_decoder.h"
using namespace mozilla;
using namespace mozilla::layers;

View File

@ -43,13 +43,11 @@
#include "nsDeque.h"
#include "nsBuiltinDecoderReader.h"
#include "nsWebMBufferedParser.h"
#include "nsAutoRef.h"
#include "nestegg/nestegg.h"
#define VPX_DONT_DEFINE_STDINT_TYPES
#include "vpx/vpx_decoder.h"
#include "vpx/vp8dx.h"
#include "vpx/vpx_codec.h"
#ifdef MOZ_TREMOR
#include "tremor/ivorbiscodec.h"
@ -57,7 +55,7 @@
#include "vorbis/codec.h"
#endif
class nsMediaDecoder;
class nsWebMBufferedState;
// Holds a nestegg_packet, and its file offset. This is needed so we
// know the offset in the file we've played up to, in order to calculate

View File

@ -40,6 +40,8 @@
#include "nsDOMError.h"
#include "SVGAnimatedLengthList.h"
#include "nsCOMPtr.h"
#include "nsContentUtils.h"
#include "dombindings.h"
// See the comment in this file's header.
@ -72,11 +74,16 @@ NS_IMPL_CYCLE_COLLECTION_CLASS(DOMSVGLengthList)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(DOMSVGLengthList)
// No need to null check tmp - script/SMIL can't detach us from mAList
( tmp->IsAnimValList() ? tmp->mAList->mAnimVal : tmp->mAList->mBaseVal ) = nsnull;
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mAList)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mAList)
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(DOMSVGLengthList)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mAList)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mAList)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(DOMSVGLengthList)
NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
NS_IMPL_CYCLE_COLLECTION_TRACE_END
NS_IMPL_CYCLE_COLLECTING_ADDREF(DOMSVGLengthList)
NS_IMPL_CYCLE_COLLECTING_RELEASE(DOMSVGLengthList)
@ -86,14 +93,22 @@ DOMCI_DATA(SVGLengthList, mozilla::DOMSVGLengthList)
namespace mozilla {
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DOMSVGLengthList)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_ENTRY(nsIDOMSVGLengthList)
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGLengthList)
NS_INTERFACE_MAP_END
JSObject*
DOMSVGLengthList::WrapObject(JSContext *cx, XPCWrappedNativeScope *scope,
bool *triedToWrap)
{
return mozilla::dom::binding::SVGLengthList::create(cx, scope, this,
triedToWrap);
}
nsIDOMSVGLength*
DOMSVGLengthList::GetItemWithoutAddRef(PRUint32 aIndex)
DOMSVGLengthList::GetItemAt(PRUint32 aIndex)
{
if (IsAnimValList()) {
Element()->FlushAnimations();
@ -220,7 +235,7 @@ NS_IMETHODIMP
DOMSVGLengthList::GetItem(PRUint32 index,
nsIDOMSVGLength **_retval)
{
*_retval = GetItemWithoutAddRef(index);
*_retval = GetItemAt(index);
if (!*_retval) {
return NS_ERROR_DOM_INDEX_SIZE_ERR;
}

View File

@ -69,19 +69,22 @@ class DOMSVGLength;
*
* Our DOM items are created lazily on demand as and when script requests them.
*/
class DOMSVGLengthList : public nsIDOMSVGLengthList
class DOMSVGLengthList : public nsIDOMSVGLengthList,
public nsWrapperCache
{
friend class DOMSVGLength;
public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_CLASS(DOMSVGLengthList)
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(DOMSVGLengthList)
NS_DECL_NSIDOMSVGLENGTHLIST
DOMSVGLengthList(DOMSVGAnimatedLengthList *aAList,
const SVGLengthList &aInternalList)
: mAList(aAList)
{
SetIsProxy();
// aInternalList must be passed in explicitly because we can't use
// InternalList() here. (Because it depends on IsAnimValList, which depends
// on this object having been assigned to aAList's mBaseVal or mAnimVal,
@ -99,6 +102,14 @@ public:
}
};
virtual JSObject* WrapObject(JSContext *cx, XPCWrappedNativeScope *scope,
bool *triedToWrap);
nsISupports* GetParentObject()
{
return static_cast<nsIContent*>(Element());
}
/**
* This will normally be the same as InternalList().Length(), except if we've
* hit OOM in which case our length will be zero.
@ -110,8 +121,6 @@ public:
return mItems.Length();
}
nsIDOMSVGLength* GetItemWithoutAddRef(PRUint32 aIndex);
/// Called to notify us to syncronize our length and detach excess items.
void InternalListLengthWillChange(PRUint32 aNewLength);

View File

@ -40,6 +40,8 @@
#include "nsDOMError.h"
#include "SVGAnimatedNumberList.h"
#include "nsCOMPtr.h"
#include "nsContentUtils.h"
#include "dombindings.h"
// See the comment in this file's header.
@ -72,11 +74,16 @@ NS_IMPL_CYCLE_COLLECTION_CLASS(DOMSVGNumberList)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(DOMSVGNumberList)
// No need to null check tmp - script/SMIL can't detach us from mAList
( tmp->IsAnimValList() ? tmp->mAList->mAnimVal : tmp->mAList->mBaseVal ) = nsnull;
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mAList)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mAList)
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(DOMSVGNumberList)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mAList)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mAList)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(DOMSVGNumberList)
NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
NS_IMPL_CYCLE_COLLECTION_TRACE_END
NS_IMPL_CYCLE_COLLECTING_ADDREF(DOMSVGNumberList)
NS_IMPL_CYCLE_COLLECTING_RELEASE(DOMSVGNumberList)
@ -86,14 +93,23 @@ DOMCI_DATA(SVGNumberList, mozilla::DOMSVGNumberList)
namespace mozilla {
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DOMSVGNumberList)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_ENTRY(nsIDOMSVGNumberList)
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGNumberList)
NS_INTERFACE_MAP_END
JSObject*
DOMSVGNumberList::WrapObject(JSContext *cx, XPCWrappedNativeScope *scope,
bool *triedToWrap)
{
return mozilla::dom::binding::SVGNumberList::create(cx, scope, this,
triedToWrap);
}
nsIDOMSVGNumber*
DOMSVGNumberList::GetItemWithoutAddRef(PRUint32 aIndex)
DOMSVGNumberList::GetItemAt(PRUint32 aIndex)
{
if (IsAnimValList()) {
Element()->FlushAnimations();
@ -220,7 +236,7 @@ NS_IMETHODIMP
DOMSVGNumberList::GetItem(PRUint32 index,
nsIDOMSVGNumber **_retval)
{
*_retval = GetItemWithoutAddRef(index);
*_retval = GetItemAt(index);
if (!*_retval) {
return NS_ERROR_DOM_INDEX_SIZE_ERR;
}

View File

@ -68,19 +68,22 @@ class DOMSVGNumber;
*
* Our DOM items are created lazily on demand as and when script requests them.
*/
class DOMSVGNumberList : public nsIDOMSVGNumberList
class DOMSVGNumberList : public nsIDOMSVGNumberList,
public nsWrapperCache
{
friend class DOMSVGNumber;
public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_CLASS(DOMSVGNumberList)
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(DOMSVGNumberList)
NS_DECL_NSIDOMSVGNUMBERLIST
DOMSVGNumberList(DOMSVGAnimatedNumberList *aAList,
const SVGNumberList &aInternalList)
: mAList(aAList)
{
SetIsProxy();
// aInternalList must be passed in explicitly because we can't use
// InternalList() here. (Because it depends on IsAnimValList, which depends
// on this object having been assigned to aAList's mBaseVal or mAnimVal,
@ -98,6 +101,14 @@ public:
}
}
virtual JSObject* WrapObject(JSContext *cx, XPCWrappedNativeScope *scope,
bool *triedToWrap);
nsISupports* GetParentObject()
{
return static_cast<nsIContent*>(Element());
}
/**
* This will normally be the same as InternalList().Length(), except if we've
* hit OOM in which case our length will be zero.
@ -109,8 +120,6 @@ public:
return mItems.Length();
}
nsIDOMSVGNumber* GetItemWithoutAddRef(PRUint32 aIndex);
/// Called to notify us to syncronize our length and detach excess items.
void InternalListLengthWillChange(PRUint32 aNewLength);

View File

@ -42,6 +42,8 @@
#include "nsCOMPtr.h"
#include "nsSVGAttrTearoffTable.h"
#include "SVGPathSegUtils.h"
#include "dombindings.h"
#include "nsContentUtils.h"
// See the comment in this file's header.
@ -50,7 +52,19 @@ namespace mozilla {
static nsSVGAttrTearoffTable<void, DOMSVGPathSegList>
sSVGPathSegListTearoffTable;
NS_SVG_VAL_IMPL_CYCLE_COLLECTION(DOMSVGPathSegList, mElement)
NS_IMPL_CYCLE_COLLECTION_CLASS(DOMSVGPathSegList)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(DOMSVGPathSegList)
// No unlinking of mElement, we'd need to null out the value pointer (the
// object it points to is held by the element) and null-check it everywhere.
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(DOMSVGPathSegList)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR_AMBIGUOUS(mElement, nsIContent)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(DOMSVGPathSegList)
NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
NS_IMPL_CYCLE_COLLECTION_TRACE_END
NS_IMPL_CYCLE_COLLECTING_ADDREF(DOMSVGPathSegList)
NS_IMPL_CYCLE_COLLECTING_RELEASE(DOMSVGPathSegList)
@ -60,6 +74,7 @@ DOMCI_DATA(SVGPathSegList, mozilla::DOMSVGPathSegList)
namespace mozilla {
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DOMSVGPathSegList)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_ENTRY(nsIDOMSVGPathSegList)
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGPathSegList)
@ -97,8 +112,16 @@ DOMSVGPathSegList::~DOMSVGPathSegList()
sSVGPathSegListTearoffTable.RemoveTearoff(key);
}
JSObject*
DOMSVGPathSegList::WrapObject(JSContext *cx, XPCWrappedNativeScope *scope,
bool *triedToWrap)
{
return mozilla::dom::binding::SVGPathSegList::create(cx, scope, this,
triedToWrap);
}
nsIDOMSVGPathSeg*
DOMSVGPathSegList::GetItemWithoutAddRef(PRUint32 aIndex)
DOMSVGPathSegList::GetItemAt(PRUint32 aIndex)
{
if (IsAnimValList()) {
Element()->FlushAnimations();
@ -327,7 +350,7 @@ NS_IMETHODIMP
DOMSVGPathSegList::GetItem(PRUint32 aIndex,
nsIDOMSVGPathSeg **_retval)
{
*_retval = GetItemWithoutAddRef(aIndex);
*_retval = GetItemAt(aIndex);
if (!*_retval) {
return NS_ERROR_DOM_INDEX_SIZE_ERR;
}

View File

@ -78,15 +78,24 @@ class SVGAnimatedPathSegList;
*
* Our DOM items are created lazily on demand as and when script requests them.
*/
class DOMSVGPathSegList : public nsIDOMSVGPathSegList
class DOMSVGPathSegList : public nsIDOMSVGPathSegList,
public nsWrapperCache
{
friend class DOMSVGPathSeg;
public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_CLASS(DOMSVGPathSegList)
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(DOMSVGPathSegList)
NS_DECL_NSIDOMSVGPATHSEGLIST
virtual JSObject* WrapObject(JSContext *cx, XPCWrappedNativeScope *scope,
bool *triedToWrap);
nsISupports* GetParentObject()
{
return static_cast<nsIContent*>(mElement);
}
/**
* Factory method to create and return a DOMSVGPathSegList wrapper
* for a given internal SVGPathData object. The factory takes care
@ -128,8 +137,6 @@ public:
return mItems.Length();
}
nsIDOMSVGPathSeg* GetItemWithoutAddRef(PRUint32 aIndex);
/**
* WATCH OUT! If you add code to call this on a baseVal wrapper, then you
* must also call it on the animVal wrapper too if necessary!! See other
@ -164,6 +171,8 @@ private:
: mElement(aElement)
, mIsAnimValList(aIsAnimValList)
{
SetIsProxy();
InternalListWillChangeTo(InternalList()); // Sync mItems
}

View File

@ -41,6 +41,8 @@
#include "SVGAnimatedPointList.h"
#include "nsCOMPtr.h"
#include "nsSVGAttrTearoffTable.h"
#include "nsContentUtils.h"
#include "dombindings.h"
// See the comment in this file's header.
@ -69,7 +71,19 @@ namespace mozilla {
static nsSVGAttrTearoffTable<void, DOMSVGPointList>
sSVGPointListTearoffTable;
NS_SVG_VAL_IMPL_CYCLE_COLLECTION(DOMSVGPointList, mElement)
NS_IMPL_CYCLE_COLLECTION_CLASS(DOMSVGPointList)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(DOMSVGPointList)
// No unlinking of mElement, we'd need to null out the value pointer (the
// object it points to is held by the element) and null-check it everywhere.
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(DOMSVGPointList)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR_AMBIGUOUS(mElement, nsIContent)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(DOMSVGPointList)
NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
NS_IMPL_CYCLE_COLLECTION_TRACE_END
NS_IMPL_CYCLE_COLLECTING_ADDREF(DOMSVGPointList)
NS_IMPL_CYCLE_COLLECTING_RELEASE(DOMSVGPointList)
@ -79,6 +93,7 @@ DOMCI_DATA(SVGPointList, mozilla::DOMSVGPointList)
namespace mozilla {
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DOMSVGPointList)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_ENTRY(nsIDOMSVGPointList)
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGPointList)
@ -116,8 +131,16 @@ DOMSVGPointList::~DOMSVGPointList()
sSVGPointListTearoffTable.RemoveTearoff(key);
}
JSObject*
DOMSVGPointList::WrapObject(JSContext *cx, XPCWrappedNativeScope *scope,
bool *triedToWrap)
{
return mozilla::dom::binding::SVGPointList::create(cx, scope, this,
triedToWrap);
}
nsIDOMSVGPoint*
DOMSVGPointList::GetItemWithoutAddRef(PRUint32 aIndex)
DOMSVGPointList::GetItemAt(PRUint32 aIndex)
{
if (IsAnimValList()) {
Element()->FlushAnimations();
@ -271,7 +294,7 @@ NS_IMETHODIMP
DOMSVGPointList::GetItem(PRUint32 aIndex,
nsIDOMSVGPoint **_retval)
{
*_retval = GetItemWithoutAddRef(aIndex);
*_retval = GetItemAt(aIndex);
if (!*_retval) {
return NS_ERROR_DOM_INDEX_SIZE_ERR;
}

View File

@ -78,15 +78,24 @@ class SVGAnimatedPointList;
*
* Our DOM items are created lazily on demand as and when script requests them.
*/
class DOMSVGPointList : public nsIDOMSVGPointList
class DOMSVGPointList : public nsIDOMSVGPointList,
public nsWrapperCache
{
friend class DOMSVGPoint;
public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_CLASS(DOMSVGPointList)
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(DOMSVGPointList)
NS_DECL_NSIDOMSVGPOINTLIST
virtual JSObject* WrapObject(JSContext *cx, XPCWrappedNativeScope *scope,
bool *triedToWrap);
nsISupports* GetParentObject()
{
return static_cast<nsIContent*>(mElement);
}
/**
* Factory method to create and return a DOMSVGPointList wrapper
* for a given internal SVGPointList object. The factory takes care
@ -128,8 +137,6 @@ public:
return mItems.Length();
}
nsIDOMSVGPoint* GetItemWithoutAddRef(PRUint32 aIndex);
/**
* WATCH OUT! If you add code to call this on a baseVal wrapper, then you
* must also call it on the animVal wrapper too if necessary!! See other
@ -164,6 +171,8 @@ private:
: mElement(aElement)
, mIsAnimValList(aIsAnimValList)
{
SetIsProxy();
InternalListWillChangeTo(InternalList()); // Sync mItems
}

View File

@ -42,6 +42,8 @@
#include "DOMSVGMatrix.h"
#include "SVGAnimatedTransformList.h"
#include "nsSVGElement.h"
#include "nsContentUtils.h"
#include "dombindings.h"
// local helper functions
namespace {
@ -72,11 +74,16 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(DOMSVGTransformList)
// No need to null check tmp - script/SMIL can't detach us from mAList
( tmp->IsAnimValList() ? tmp->mAList->mAnimVal : tmp->mAList->mBaseVal ) =
nsnull;
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mAList)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mAList)
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(DOMSVGTransformList)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mAList)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mAList)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(DOMSVGTransformList)
NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
NS_IMPL_CYCLE_COLLECTION_TRACE_END
NS_IMPL_CYCLE_COLLECTING_ADDREF(DOMSVGTransformList)
NS_IMPL_CYCLE_COLLECTING_RELEASE(DOMSVGTransformList)
@ -86,6 +93,7 @@ DOMCI_DATA(SVGTransformList, mozilla::DOMSVGTransformList)
namespace mozilla {
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DOMSVGTransformList)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_ENTRY(nsIDOMSVGTransformList)
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGTransformList)
@ -94,8 +102,16 @@ NS_INTERFACE_MAP_END
//----------------------------------------------------------------------
// DOMSVGTransformList methods:
JSObject*
DOMSVGTransformList::WrapObject(JSContext *cx, XPCWrappedNativeScope *scope,
bool *triedToWrap)
{
return mozilla::dom::binding::SVGTransformList::create(cx, scope, this,
triedToWrap);
}
nsIDOMSVGTransform*
DOMSVGTransformList::GetItemWithoutAddRef(PRUint32 aIndex)
DOMSVGTransformList::GetItemAt(PRUint32 aIndex)
{
if (IsAnimValList()) {
Element()->FlushAnimations();
@ -234,7 +250,7 @@ DOMSVGTransformList::Initialize(nsIDOMSVGTransform *newItem,
NS_IMETHODIMP
DOMSVGTransformList::GetItem(PRUint32 index, nsIDOMSVGTransform **_retval)
{
*_retval = GetItemWithoutAddRef(index);
*_retval = GetItemAt(index);
if (!*_retval) {
return NS_ERROR_DOM_INDEX_SIZE_ERR;
}

View File

@ -64,19 +64,22 @@ class DOMSVGTransform;
*
* See the architecture comment in DOMSVGAnimatedTransformList.h.
*/
class DOMSVGTransformList : public nsIDOMSVGTransformList
class DOMSVGTransformList : public nsIDOMSVGTransformList,
public nsWrapperCache
{
friend class DOMSVGTransform;
public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_CLASS(DOMSVGTransformList)
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(DOMSVGTransformList)
NS_DECL_NSIDOMSVGTRANSFORMLIST
DOMSVGTransformList(DOMSVGAnimatedTransformList *aAList,
const SVGTransformList &aInternalList)
: mAList(aAList)
{
SetIsProxy();
// aInternalList must be passed in explicitly because we can't use
// InternalList() here. (Because it depends on IsAnimValList, which depends
// on this object having been assigned to aAList's mBaseVal or mAnimVal,
@ -94,6 +97,14 @@ public:
}
}
virtual JSObject* WrapObject(JSContext *cx, XPCWrappedNativeScope *scope,
bool *triedToWrap);
nsISupports* GetParentObject()
{
return static_cast<nsIContent*>(Element());
}
/**
* This will normally be the same as InternalList().Length(), except if we've
* hit OOM in which case our length will be zero.
@ -105,8 +116,6 @@ public:
return mItems.Length();
}
nsIDOMSVGTransform* GetItemWithoutAddRef(PRUint32 aIndex);
/// Called to notify us to synchronize our length and detach excess items.
void InternalListLengthWillChange(PRUint32 aNewLength);

View File

@ -10640,7 +10640,7 @@ nsSVGListSH<ListInterfaceType, ListType>::GetItemAt(nsISupports *aNative,
}
#endif
return list->GetItemWithoutAddRef(aIndex);
return list->GetItemAt(aIndex);
}

View File

@ -42,5 +42,6 @@
interface nsIDOMClientRectList : nsISupports
{
readonly attribute unsigned long length;
nsIDOMClientRect item(in unsigned long index);
[getter,forward(getItemAt)] nsIDOMClientRect item(in unsigned long index);
[noscript,notxpcom,nostdcall] nsIDOMClientRect getItemAt(in unsigned long index);
};

View File

@ -44,5 +44,6 @@ interface nsIDOMPaintRequest;
interface nsIDOMPaintRequestList : nsISupports
{
readonly attribute unsigned long length;
nsIDOMPaintRequest item(in unsigned long index);
[getter,forward(getItemAt)] nsIDOMPaintRequest item(in unsigned long index);
[noscript,notxpcom,nostdcall] nsIDOMPaintRequest getItemAt(in unsigned long index);
};

View File

@ -73,7 +73,8 @@ interface nsIDOMTouch : nsISupports {
[scriptable, uuid(60706eb7-d50d-4379-b01c-e78e6af84213)]
interface nsIDOMTouchList : nsISupports {
readonly attribute unsigned long length;
nsIDOMTouch item(in unsigned long index);
[getter,forward(getItemAt)] nsIDOMTouch item(in unsigned long index);
[noscript,notxpcom,nostdcall] nsIDOMTouch getItemAt(in unsigned long index);
nsIDOMTouch identifiedTouch(in long identifier);
};

View File

@ -52,6 +52,7 @@ interface nsIDOMSVGLengthList : nsISupports
// raises(nsIDOMDOMException, nsIDOMSVGException);
nsIDOMSVGLength getItem(in unsigned long index);
// raises(nsIDOMDOMException);
[getter,noscript,notxpcom,nostdcall] nsIDOMSVGLength getItemAt(in unsigned long index);
nsIDOMSVGLength insertItemBefore(in nsIDOMSVGLength newItem, in unsigned long index);
// raises(nsIDOMDOMException, nsIDOMSVGException);
nsIDOMSVGLength replaceItem(in nsIDOMSVGLength newItem, in unsigned long index);

View File

@ -52,6 +52,7 @@ interface nsIDOMSVGNumberList : nsISupports
// raises(nsIDOMDOMException, nsIDOMSVGException);
nsIDOMSVGNumber getItem(in unsigned long index);
// raises(nsIDOMDOMException);
[getter,noscript,notxpcom,nostdcall] nsIDOMSVGNumber getItemAt(in unsigned long index);
nsIDOMSVGNumber insertItemBefore(in nsIDOMSVGNumber newItem, in unsigned long index);
// raises(nsIDOMDOMException, nsIDOMSVGException);
nsIDOMSVGNumber replaceItem(in nsIDOMSVGNumber newItem, in unsigned long index);

View File

@ -52,6 +52,7 @@ interface nsIDOMSVGPathSegList : nsISupports
// raises(nsIDOMDOMException, nsIDOMSVGException);
nsIDOMSVGPathSeg getItem(in unsigned long index);
// raises(nsIDOMDOMException);
[getter,noscript,notxpcom,nostdcall] nsIDOMSVGPathSeg getItemAt(in unsigned long index);
nsIDOMSVGPathSeg insertItemBefore(in nsIDOMSVGPathSeg newItem, in unsigned long index);
// raises(nsIDOMDOMException, nsIDOMSVGException);
nsIDOMSVGPathSeg replaceItem(in nsIDOMSVGPathSeg newItem, in unsigned long index);

View File

@ -52,6 +52,7 @@ interface nsIDOMSVGPointList : nsISupports
// raises( DOMException, SVGException );
nsIDOMSVGPoint getItem (in unsigned long index);
// raises( DOMException );
[getter,noscript,notxpcom,nostdcall] nsIDOMSVGPoint getItemAt(in unsigned long index);
nsIDOMSVGPoint insertItemBefore(in nsIDOMSVGPoint newItem, in unsigned long index);
// raises( DOMException, SVGException );
nsIDOMSVGPoint replaceItem(in nsIDOMSVGPoint newItem, in unsigned long index);

View File

@ -53,6 +53,7 @@ interface nsIDOMSVGTransformList : nsISupports
// raises( DOMException, SVGException );
nsIDOMSVGTransform getItem(in unsigned long index);
// raises( DOMException );
[getter,noscript,notxpcom,nostdcall] nsIDOMSVGTransform getItemAt(in unsigned long index);
nsIDOMSVGTransform insertItemBefore(in nsIDOMSVGTransform newItem,
in unsigned long index);
// raises( DOMException, SVGException );

View File

@ -1488,7 +1488,7 @@ nsNPAPIPluginInstance::InitAsyncSurface(NPSize *size, NPImageFormat format,
if (mOwner)
return mOwner->InitAsyncSurface(size, format, initData, surface);
return NS_ERROR_FAILURE;
return NPERR_GENERIC_ERROR;
}
NPError
@ -1497,7 +1497,7 @@ nsNPAPIPluginInstance::FinalizeAsyncSurface(NPAsyncSurface *surface)
if (mOwner)
return mOwner->FinalizeAsyncSurface(surface);
return NS_ERROR_FAILURE;
return NPERR_GENERIC_ERROR;
}
void

View File

@ -804,12 +804,12 @@ NPBool nsPluginInstanceOwner::ConvertPoint(double sourceX, double sourceY, NPCoo
NPError nsPluginInstanceOwner::InitAsyncSurface(NPSize *size, NPImageFormat format,
void *initData, NPAsyncSurface *surface)
{
return NPERR_GENERIC_ERROR;
return NPERR_INCOMPATIBLE_VERSION_ERROR;
}
NPError nsPluginInstanceOwner::FinalizeAsyncSurface(NPAsyncSurface *)
{
return NPERR_GENERIC_ERROR;
return NPERR_INCOMPATIBLE_VERSION_ERROR;
}
void nsPluginInstanceOwner::SetCurrentAsyncSurface(NPAsyncSurface *, NPRect*)

View File

@ -93,6 +93,8 @@ static void do_qt_pixmap_unref (void *data)
delete pmap;
}
static gfxImageFormat sOffscreenFormat = gfxASurface::ImageFormatRGB24;
#ifndef MOZ_PANGO
typedef nsDataHashtable<nsStringHashKey, nsRefPtr<FontFamily> > FontTable;
typedef nsDataHashtable<nsCStringHashKey, nsTArray<nsRefPtr<FontEntry> > > PrefFontTable;
@ -151,6 +153,9 @@ gfxQtPlatform::gfxQtPlatform()
// Qt doesn't provide a public API to detect the graphicssystem type. We hack
// around this by checking what type of graphicssystem a test QPixmap uses.
QPixmap pixmap(1, 1);
if (pixmap.depth() == 16) {
sOffscreenFormat = gfxASurface::ImageFormatRGB16_565;
}
#if (QT_VERSION < QT_VERSION_CHECK(4,8,0))
if (pixmap.paintEngine())
sDefaultQtPaintEngineType = pixmap.paintEngine()->type();
@ -589,9 +594,5 @@ gfxQtPlatform::GetDPI()
gfxImageFormat
gfxQtPlatform::GetOffscreenFormat()
{
if (qApp->desktop()->depth() == 16) {
return gfxASurface::ImageFormatRGB16_565;
}
return gfxASurface::ImageFormatRGB24;
return sOffscreenFormat;
}

View File

@ -1911,9 +1911,6 @@ echo-dirs:
echo-module:
@echo $(MODULE)
echo-requires:
@echo $(REQUIRES)
echo-depth-path:
@$(topsrcdir)/build/unix/print-depth-path.sh
@ -2020,7 +2017,6 @@ FREEZE_VARIABLES = \
DIRS \
LIBRARY \
MODULE \
REQUIRES \
SHORT_LIBNAME \
TIERS \
EXTRA_COMPONENTS \

View File

@ -97,6 +97,7 @@ LOCAL_INCLUDES = \
-I$(srcdir)/../loader \
-I$(topsrcdir)/caps/include \
-I$(topsrcdir)/content/base/src \
-I$(topsrcdir)/content/events/src \
-I$(topsrcdir)/content/html/content/src \
-I$(topsrcdir)/content/html/document/src \
-I$(topsrcdir)/content/svg/content/src \

View File

@ -269,7 +269,7 @@ def writeArgumentUnboxing(f, i, name, type, haveCcx, optional, rvdeclared,
elif haveCcx:
f.write(" xpc_qsThrowBadArgWithCcx(ccx, rv, %d);\n" % i)
else:
f.write(" xpc_qsThrowBadArg(cx, rv, vp, %d);\n" % i)
f.write(" xpc_qsThrowBadArgWithDetails(cx, rv, %d, %s, %s);\n" % (i, "\"\"", "\"\""))
f.write(" return JS_FALSE;\n"
" }\n")
return True

View File

@ -6,10 +6,25 @@ classes = {
prefableClasses = {
'DOMTokenList': 'nsDOMTokenList',
'DOMSettableTokenList': 'nsDOMSettableTokenList',
'ClientRectList': 'nsClientRectList',
'PaintRequestList': 'nsPaintRequestList',
'TouchList': 'nsDOMTouchList',
'FileList': 'nsDOMFileList',
'SVGLengthList': 'mozilla::DOMSVGLengthList',
'SVGNumberList': 'mozilla::DOMSVGNumberList',
'SVGPathSegList': 'mozilla::DOMSVGPathSegList',
'SVGPointList': 'mozilla::DOMSVGPointList',
'SVGTransformList': 'mozilla::DOMSVGTransformList',
}
irregularFilenames = {
'nsHTMLOptionCollection': 'nsHTMLSelectElement',
'nsClientRectList': 'nsClientRect',
'nsPaintRequestList': 'nsPaintRequest',
'nsIDOMTouch': 'nsIDOMTouchEvent',
'nsIDOMTouchList': 'nsIDOMTouchEvent',
'nsDOMTouchList': 'nsDOMTouchEvent',
'nsDOMFileList': 'nsDOMFile',
}
customInheritance = {

View File

@ -326,23 +326,28 @@ def completeConfiguration(conf, includePath, cachedir):
# === Generating the header file
def needsForwardDeclaration(type):
return isInterfaceType(type) or (type.kind == 'native' and type.specialtype is None)
def getTypes(classes, map={}):
def addType(types, type, map):
def getTranslatedType(type):
return map.get(type, type)
type = xpidl.unaliasType(type)
if isInterfaceType(type) or (type.kind == 'native' and type.specialtype is None):
types.add(getTranslatedType(type.name))
def getTypes(classes, map):
types = set()
for clazz in classes.itervalues():
types.add(getTranslatedType(clazz.nativeClass))
if clazz.indexGetter and needsForwardDeclaration(clazz.realIndexGetter.realtype):
types.add(getTranslatedType(clazz.realIndexGetter.realtype.name))
if clazz.indexSetter and needsForwardDeclaration(clazz.realIndexSetter.realtype):
types.add(getTranslatedType(clazz.realIndexSetter.realtype.name))
if clazz.nameGetter and needsForwardDeclaration(clazz.realNameGetter.realtype):
types.add(getTranslatedType(clazz.realNameGetter.realtype.name))
return sorted(types)
types.add(map.get(clazz.nativeClass, clazz.nativeClass))
if clazz.indexGetter:
addType(types, clazz.realIndexGetter.realtype, map)
if clazz.indexSetter:
addType(types, clazz.realIndexSetter.realtype, map)
if clazz.nameGetter:
addType(types, clazz.realNameGetter.realtype, map)
if clazz.nameSetter:
addType(types, clazz.realNameSetter.realtype, map)
return types
listDefinitionTemplate = (
"class ${name} {\n"
@ -373,7 +378,7 @@ def writeHeaderFile(filename, config):
"#define " + headerMacro + "\n\n")
namespaces = []
for type in getTypes(config.classes, {}):
for type in sorted(getTypes(config.classes, {})):
newNamespaces = type.split('::')
type = newNamespaces.pop()
j = 0
@ -633,30 +638,20 @@ def writeStubFile(filename, config, interfaces):
f = open(filename, 'w')
filesIncluded = set()
def includeType(type):
type = unaliasType(type)
if type.kind in ('builtin', 'native'):
return None
file = conf.irregularFilenames.get(type.name, type.name) + '.h'
if file not in filesIncluded:
f.write('#include "%s"\n' % file)
filesIncluded.add(file)
return type
def writeIncludesForMember(member):
assert member.kind in ('attribute', 'method')
resulttype = includeType(member.realtype)
if member.kind == 'method':
for p in member.params:
includeType(p.realtype)
return resulttype
headerFilename = re.sub(r'(\.cpp)?$', '.h', filename)
try:
f.write("/* THIS FILE IS AUTOGENERATED - DO NOT EDIT */\n\n")
f.write("".join([("#include \"%s.h\"\n" % re.sub(r'(([^:]+::)*)', '', type)) for type in getTypes(config.classes, config.irregularFilenames)]))
types = getTypes(config.classes, config.irregularFilenames)
for clazz in config.classes.itervalues():
for member in clazz.members:
addType(types, member.realtype, config.irregularFilenames)
if member.kind == 'method':
for p in member.params:
addType(types, p.realtype, config.irregularFilenames)
f.write("".join([("#include \"%s.h\"\n" % re.sub(r'(([^:]+::)*)', '', type)) for type in sorted(types)]))
f.write("\n")
f.write("namespace mozilla {\n"

View File

@ -2451,8 +2451,7 @@ gfxPoint3D GetDeltaToMozTransformOrigin(const nsIFrame* aFrame,
*/
static
gfxPoint3D GetDeltaToMozPerspectiveOrigin(const nsIFrame* aFrame,
float aAppUnitsPerPixel,
const nsRect* aBoundsOverride)
float aAppUnitsPerPixel)
{
NS_PRECONDITION(aFrame, "Can't get delta for a null frame!");
NS_PRECONDITION(aFrame->GetStyleDisplay()->HasTransform(),
@ -2469,8 +2468,7 @@ gfxPoint3D GetDeltaToMozPerspectiveOrigin(const nsIFrame* aFrame,
// How do we handle aBoundsOverride in the latter case?
nsIFrame* parent = aFrame->GetParentStyleContextFrame();
const nsStyleDisplay* display = aFrame->GetParent()->GetStyleDisplay();
nsRect boundingRect = (aBoundsOverride ? *aBoundsOverride :
nsDisplayTransform::GetFrameBoundsForTransform(parent));
nsRect boundingRect = nsDisplayTransform::GetFrameBoundsForTransform(parent);
/* Allows us to access named variables by index. */
gfxPoint3D result;
@ -2554,8 +2552,9 @@ nsDisplayTransform::GetResultingTransformMatrix(const nsIFrame* aFrame,
aFrame->PresContext(),
dummy, bounds, aAppUnitsPerPixel);
} else {
NS_ASSERTION(aFrame->GetStyleDisplay()->mTransformStyle == NS_STYLE_TRANSFORM_STYLE_PRESERVE_3D,
"If we don't have a transform, then we must be at least attempting to preserve the transforms of our children");
NS_ASSERTION(aFrame->GetStyleDisplay()->mTransformStyle == NS_STYLE_TRANSFORM_STYLE_PRESERVE_3D ||
aFrame->GetStyleDisplay()->mBackfaceVisibility == NS_STYLE_BACKFACE_VISIBILITY_HIDDEN,
"If we don't have a transform, then we must have another reason to have an nsDisplayTransform created");
}
const nsStyleDisplay* parentDisp = nsnull;
@ -2573,7 +2572,7 @@ nsDisplayTransform::GetResultingTransformMatrix(const nsIFrame* aFrame,
/* At the point when perspective is applied, we have been translated to the transform origin.
* The translation to the perspective origin is the difference between these values.
*/
gfxPoint3D toPerspectiveOrigin = GetDeltaToMozPerspectiveOrigin(aFrame, aAppUnitsPerPixel, aBoundsOverride);
gfxPoint3D toPerspectiveOrigin = GetDeltaToMozPerspectiveOrigin(aFrame, aAppUnitsPerPixel);
result = result * nsLayoutUtils::ChangeMatrixBasis(toPerspectiveOrigin - toMozOrigin, perspective);
}

View File

@ -185,6 +185,7 @@ _TEST_FILES = \
test_bug718809.html \
test_font_inflation_reftests.html \
test_bug725426.html \
test_bug731777.html \
$(NULL)
# Tests for bugs 441782, 467672 and 570378 don't pass reliably on Windows, because of bug 469208

View File

@ -0,0 +1,49 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test for Bug 731777</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<style>
#container {
position: relative;
height: 300px;
width: 300px;
margin: 50px 100px;
border: 2px solid blue;
background-color: #044B0A;
-moz-perspective: 500px;
overflow:hidden;
}
#inner {
margin: 0px;
width: 480px;
border: 2px solid blue;
height: 220px;
background-color: #844BCA;
-moz-transform: rotateY(91deg) translateX(0px) translateZ(0px);
-moz-transition: 5s;
}
</style>
</head>
<body>
<div id="container">
<div id="inner"></div>
</div>
<pre id="test">
<script type="application/javascript">
/** Test for Bug 731777 **/
is(document.elementFromPoint(325,170), document.getElementById("inner"), "Able to hit transformed object");
is(document.elementFromPoint(405,170), document.getElementById("inner"), "Able to hit transformed object");
</script>
</pre>
</body>
</html>

View File

@ -159,57 +159,6 @@ nsFileControlFrame::DestroyFrom(nsIFrame* aDestructRoot)
nsBlockFrame::DestroyFrom(aDestructRoot);
}
struct CaptureCallbackData {
nsICapturePicker* picker;
PRUint32* mode;
};
typedef struct CaptureCallbackData CaptureCallbackData;
bool CapturePickerAcceptCallback(const nsAString& aAccept, void* aClosure)
{
nsresult rv;
bool captureEnabled;
CaptureCallbackData* closure = (CaptureCallbackData*)aClosure;
if (StringBeginsWith(aAccept,
NS_LITERAL_STRING("image/"))) {
rv = closure->picker->ModeMayBeAvailable(nsICapturePicker::MODE_STILL,
&captureEnabled);
NS_ENSURE_SUCCESS(rv, true);
if (captureEnabled) {
*closure->mode = nsICapturePicker::MODE_STILL;
return false;
}
} else if (StringBeginsWith(aAccept,
NS_LITERAL_STRING("audio/"))) {
rv = closure->picker->ModeMayBeAvailable(nsICapturePicker::MODE_AUDIO_CLIP,
&captureEnabled);
NS_ENSURE_SUCCESS(rv, true);
if (captureEnabled) {
*closure->mode = nsICapturePicker::MODE_AUDIO_CLIP;
return false;
}
} else if (StringBeginsWith(aAccept,
NS_LITERAL_STRING("video/"))) {
rv = closure->picker->ModeMayBeAvailable(nsICapturePicker::MODE_VIDEO_CLIP,
&captureEnabled);
NS_ENSURE_SUCCESS(rv, true);
if (captureEnabled) {
*closure->mode = nsICapturePicker::MODE_VIDEO_CLIP;
return false;
}
rv = closure->picker->ModeMayBeAvailable(nsICapturePicker::MODE_VIDEO_NO_SOUND_CLIP,
&captureEnabled);
NS_ENSURE_SUCCESS(rv, true);
if (captureEnabled) {
*closure->mode = nsICapturePicker::MODE_VIDEO_NO_SOUND_CLIP;
return false;
}
}
return true;
}
nsresult
nsFileControlFrame::CreateAnonymousContent(nsTArray<ContentInfo>& aElements)
{
@ -282,15 +231,12 @@ nsFileControlFrame::CreateAnonymousContent(nsTArray<ContentInfo>& aElements)
nsCOMPtr<nsICapturePicker> capturePicker;
capturePicker = do_GetService("@mozilla.org/capturepicker;1");
if (capturePicker) {
PRUint32 mode = 0;
CaptureCallbackData data;
data.picker = capturePicker;
data.mode = &mode;
ParseAcceptAttribute(&CapturePickerAcceptCallback, (void*)&data);
data.mode = GetCaptureMode(data);
if (mode != 0) {
mCaptureMouseListener->mMode = mode;
if (data.mode != 0) {
mCaptureMouseListener->mMode = data.mode;
nodeInfo = doc->NodeInfoManager()->GetNodeInfo(nsGkAtoms::input, nsnull,
kNameSpaceID_XHTML,
nsIDOMNode::ELEMENT_NODE);
@ -747,19 +693,51 @@ nsFileControlFrame::CreateAccessible()
}
#endif
void
nsFileControlFrame::ParseAcceptAttribute(AcceptAttrCallback aCallback,
void* aClosure) const
PRUint32
nsFileControlFrame::GetCaptureMode(const CaptureCallbackData& aData)
{
nsAutoString accept;
mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::accept, accept);
PRInt32 filters = nsHTMLInputElement::FromContent(mContent)->GetFilterFromAccept();
nsresult rv;
bool captureEnabled;
HTMLSplitOnSpacesTokenizer tokenizer(accept, ',');
// Empty loop body because aCallback is doing the work
while (tokenizer.hasMoreTokens() &&
(*aCallback)(tokenizer.nextToken(), aClosure));
if (filters == nsIFilePicker::filterImages) {
rv = aData.picker->ModeMayBeAvailable(nsICapturePicker::MODE_STILL,
&captureEnabled);
NS_ENSURE_SUCCESS(rv, 0);
if (captureEnabled) {
return nsICapturePicker::MODE_STILL;
}
return 0;
}
if (filters == nsIFilePicker::filterAudio) {
rv = aData.picker->ModeMayBeAvailable(nsICapturePicker::MODE_AUDIO_CLIP,
&captureEnabled);
NS_ENSURE_SUCCESS(rv, 0);
if (captureEnabled) {
return nsICapturePicker::MODE_AUDIO_CLIP;
}
return 0;
}
if (filters == nsIFilePicker::filterVideo) {
rv = aData.picker->ModeMayBeAvailable(nsICapturePicker::MODE_VIDEO_CLIP,
&captureEnabled);
NS_ENSURE_SUCCESS(rv, 0);
if (captureEnabled) {
return nsICapturePicker::MODE_VIDEO_CLIP;
}
rv = aData.picker->ModeMayBeAvailable(nsICapturePicker::MODE_VIDEO_NO_SOUND_CLIP,
&captureEnabled);
NS_ENSURE_SUCCESS(rv, 0);
if (captureEnabled) {
return nsICapturePicker::MODE_VIDEO_NO_SOUND_CLIP;
}
return 0;
}
return 0;
}
////////////////////////////////////////////////////////////
// Mouse listener implementation

View File

@ -94,13 +94,19 @@ public:
#ifdef ACCESSIBILITY
virtual already_AddRefed<nsAccessible> CreateAccessible();
#endif
#endif
typedef bool (*AcceptAttrCallback)(const nsAString&, void*);
void ParseAcceptAttribute(AcceptAttrCallback aCallback, void* aClosure) const;
protected:
struct CaptureCallbackData {
nsICapturePicker* picker;
PRUint32 mode;
};
PRUint32 GetCaptureMode(const CaptureCallbackData& aData);
class MouseListener;
friend class MouseListener;
class MouseListener : public nsIDOMEventListener {

View File

@ -995,6 +995,18 @@ nsIFrame::HasPerspective() const
return false;
}
bool
nsIFrame::ChildrenHavePerspective() const
{
const nsStyleDisplay *disp = GetStyleContext()->GetStyleDisplay();
if (disp &&
disp->mChildPerspective.GetUnit() == eStyleUnit_Coord &&
disp->mChildPerspective.GetCoordValue() > 0.0) {
return true;
}
return false;
}
nsRect
nsIFrame::GetContentRectRelativeToSelf() const
{
@ -6771,12 +6783,17 @@ nsIFrame::FinishAndStoreOverflow(nsOverflowAreas& aOverflowAreas,
}
if (Preserves3DChildren()) {
ComputePreserve3DChildrenOverflow(aOverflowAreas, newBounds);
} else if (HasPerspective()) {
RecomputePerspectiveChildrenOverflow(this, &newBounds);
} else if (ChildrenHavePerspective()) {
RecomputePerspectiveChildrenOverflow(this->GetStyleContext(), &newBounds);
}
} else {
Properties().Delete(nsIFrame::PreTransformOverflowAreasProperty());
if (ChildrenHavePerspective()) {
nsRect newBounds(nsPoint(0, 0), aNewSize);
RecomputePerspectiveChildrenOverflow(this->GetStyleContext(), &newBounds);
}
}
bool anyOverflowChanged;
if (aOverflowAreas != nsOverflowAreas(bounds, bounds)) {
@ -6833,7 +6850,7 @@ nsIFrame::FinishAndStoreOverflow(nsOverflowAreas& aOverflowAreas,
}
void
nsIFrame::RecomputePerspectiveChildrenOverflow(const nsIFrame* aStartFrame, const nsRect* aBounds)
nsIFrame::RecomputePerspectiveChildrenOverflow(const nsStyleContext* aStartStyle, const nsRect* aBounds)
{
// Children may check our size when getting our transform, make sure it's valid.
nsSize oldSize = GetSize();
@ -6856,8 +6873,11 @@ nsIFrame::RecomputePerspectiveChildrenOverflow(const nsIFrame* aStartFrame, cons
boundsOverflow.SetAllTo(bounds);
child->FinishAndStoreOverflow(boundsOverflow, bounds.Size());
}
} else if (child->GetParentStyleContextFrame() != aStartFrame) {
child->RecomputePerspectiveChildrenOverflow(aStartFrame, nsnull);
} else if (child->GetStyleContext()->GetParent() == aStartStyle ||
child->GetStyleContext() == aStartStyle) {
// Recurse into frames with the same style context, or a direct
// child style context.
child->RecomputePerspectiveChildrenOverflow(aStartStyle, nsnull);
}
}
}

View File

@ -1245,10 +1245,12 @@ public:
bool HasPerspective() const;
bool ChildrenHavePerspective() const;
// Calculate the overflow size of all child frames, taking preserve-3d into account
void ComputePreserve3DChildrenOverflow(nsOverflowAreas& aOverflowAreas, const nsRect& aBounds);
void RecomputePerspectiveChildrenOverflow(const nsIFrame* aStartFrame, const nsRect* aBounds);
void RecomputePerspectiveChildrenOverflow(const nsStyleContext* aStartStyle, const nsRect* aBounds);
/**
* Event handling of GUI events.

View File

@ -0,0 +1,43 @@
<!DOCTYPE html>
<html>
<body>
<style>
#container {
position: relative;
margin: 10px auto;
width: 450px;
height: 281px;
z-index: 1;
-moz-perspective: 1000px;
}
#card {
width: 100%;
height: 100%;
-moz-transform-style: preserve-3d;
-moz-transform: rotateY(165deg);
}
.face {
position: absolute;
width: 100%;
height: 100%;
-moz-backface-visibility: hidden;
background: red;
}
.face.back {
display: block;
-moz-transform: rotateY(180deg);
-moz-box-sizing: border-box;
padding: 10px;
color: white;
text-align: center;
background: green;
}
</style>
<div id="container" class="hover">
<div id="card">
<div class="back face">
</div>
</div>
</div>
</body></html>

View File

@ -0,0 +1,45 @@
<!DOCTYPE html>
<html>
<body>
<style>
#container {
position: relative;
margin: 10px auto;
width: 450px;
height: 281px;
z-index: 1;
-moz-perspective: 1000px;
}
#card {
width: 100%;
height: 100%;
-moz-transform-style: preserve-3d;
-moz-transform: rotateY(165deg);
}
.face {
position: absolute;
width: 100%;
height: 100%;
-moz-backface-visibility: hidden;
background: red;
}
.face.back {
display: block;
-moz-transform: rotateY(180deg);
-moz-box-sizing: border-box;
padding: 10px;
color: white;
text-align: center;
background: green;
}
</style>
<div id="container" class="hover">
<div id="card">
<div class="front face">
</div>
<div class="back face">
</div>
</div>
</div>
</body></html>

View File

@ -34,6 +34,7 @@ fails-if(Android) == scale3d-all-separate.html scale3d-1-ref.html
!= backface-visibility-1a.html about:blank
== backface-visibility-1b.html about:blank
== backface-visibility-1c.html about:blank
== backface-visibility-2.html backface-visibility-2-ref.html
!= perspective-origin-1a.html rotatex-perspective-1a.html
== perspective-origin-1b.html perspective-origin-1a.html
== perspective-origin-2a.html perspective-origin-2-ref.html

View File

@ -1666,7 +1666,9 @@ struct nsStyleDisplay {
/* Returns whether the element has the -moz-transform property. */
bool HasTransform() const {
return mSpecifiedTransform != nsnull || mTransformStyle == NS_STYLE_TRANSFORM_STYLE_PRESERVE_3D;
return mSpecifiedTransform != nsnull ||
mTransformStyle == NS_STYLE_TRANSFORM_STYLE_PRESERVE_3D ||
mBackfaceVisibility == NS_STYLE_BACKFACE_VISIBILITY_HIDDEN;
}
};

View File

@ -52,6 +52,7 @@ import android.graphics.BitmapFactory;
import android.os.Build;
import android.os.Bundle;
import android.text.Editable;
import android.text.Spanned;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.util.Log;
@ -195,7 +196,22 @@ public class AwesomeBar extends Activity implements GeckoEventListener {
mText.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {
// do nothing
String text = s.toString();
mAwesomeTabs.filter(text);
// If awesome bar has compositing string, don't call updateGoButton().
// Since that method resets IME, composing state will be borken.
Object[] spans = s.getSpans(0, s.length(), Object.class);
if (spans != null) {
for (Object span : spans) {
if ((s.getSpanFlags(span) & Spanned.SPAN_COMPOSING) != 0) {
// Found composition string.
return;
}
}
}
// no composition string. It is safe to update IME flags.
updateGoButton(text);
}
public void beforeTextChanged(CharSequence s, int start, int count,
@ -205,10 +221,7 @@ public class AwesomeBar extends Activity implements GeckoEventListener {
public void onTextChanged(CharSequence s, int start, int before,
int count) {
String text = s.toString();
mAwesomeTabs.filter(text);
updateGoButton(text);
// do nothing
}
});

View File

@ -53,12 +53,6 @@ EXPORT_LIBRARY = 1
EXPORTS = nsBrowserComponents.h
REQUIRES = \
xpcom \
string \
pref \
$(NULL)
XPIDL_MODULE = browsercomps
XPIDLSRCS = nsIShellService.idl

View File

@ -53,12 +53,6 @@ EXPORT_LIBRARY = 1
EXPORTS = nsBrowserComponents.h
REQUIRES = \
xpcom \
string \
pref \
$(NULL)
XPIDL_MODULE = browsercomps
XPIDLSRCS = nsIShellService.idl

View File

@ -133,12 +133,20 @@ public:
static void RecordSlowStatement(const nsACString &statement,
const nsACString &dbName,
PRUint32 delay);
static void RecordChromeHang(PRUint32 duration,
const Telemetry::HangStack &callStack,
SharedLibraryInfo &moduleMap);
static nsresult GetHistogramEnumId(const char *name, Telemetry::ID *id);
struct StmtStats {
PRUint32 hitCount;
PRUint32 totalTime;
};
typedef nsBaseHashtableET<nsCStringHashKey, StmtStats> SlowSQLEntryType;
struct HangReport {
PRUint32 duration;
Telemetry::HangStack callStack;
SharedLibraryInfo moduleMap;
};
private:
static bool StatementReflector(SlowSQLEntryType *entry, JSContext *cx,
@ -181,6 +189,8 @@ private:
// AutoHashtable here.
nsTHashtable<nsCStringHashKey> mTrackedDBs;
Mutex mHashMutex;
nsTArray<HangReport> mHangReports;
Mutex mHangReportsMutex;
};
TelemetryImpl* TelemetryImpl::sTelemetry = NULL;
@ -460,7 +470,8 @@ WrapAndReturnHistogram(Histogram *h, JSContext *cx, jsval *ret)
TelemetryImpl::TelemetryImpl():
mHistogramMap(Telemetry::HistogramCount),
mCanRecord(XRE_GetProcessType() == GeckoProcessType_Default),
mHashMutex("Telemetry::mHashMutex")
mHashMutex("Telemetry::mHashMutex"),
mHangReportsMutex("Telemetry::mHangReportsMutex")
{
// A whitelist to prevent Telemetry reporting on Addon & Thunderbird DBs
const char *trackedDBs[] = {
@ -942,6 +953,144 @@ TelemetryImpl::GetSlowSQL(JSContext *cx, jsval *ret)
return NS_OK;
}
NS_IMETHODIMP
TelemetryImpl::GetChromeHangs(JSContext *cx, jsval *ret)
{
MutexAutoLock hangReportMutex(mHangReportsMutex);
JSObject *reportArray = JS_NewArrayObject(cx, 0, nsnull);
if (!reportArray) {
return NS_ERROR_FAILURE;
}
*ret = OBJECT_TO_JSVAL(reportArray);
// Each hang report is an object in the 'chromeHangs' array
for (size_t i = 0; i < mHangReports.Length(); ++i) {
JSObject *reportObj = JS_NewObject(cx, NULL, NULL, NULL);
if (!reportObj) {
return NS_ERROR_FAILURE;
}
jsval reportObjVal = OBJECT_TO_JSVAL(reportObj);
if (!JS_SetElement(cx, reportArray, i, &reportObjVal)) {
return NS_ERROR_FAILURE;
}
// Record the hang duration (expressed in seconds)
JSBool ok = JS_DefineProperty(cx, reportObj, "duration",
INT_TO_JSVAL(mHangReports[i].duration),
NULL, NULL, JSPROP_ENUMERATE);
if (!ok) {
return NS_ERROR_FAILURE;
}
// Represent call stack PCs as strings
// (JS can't represent all 64-bit integer values)
JSObject *pcArray = JS_NewArrayObject(cx, 0, nsnull);
if (!pcArray) {
return NS_ERROR_FAILURE;
}
ok = JS_DefineProperty(cx, reportObj, "stack", OBJECT_TO_JSVAL(pcArray),
NULL, NULL, JSPROP_ENUMERATE);
if (!ok) {
return NS_ERROR_FAILURE;
}
const PRUint32 pcCount = mHangReports[i].callStack.Length();
for (size_t pcIndex = 0; pcIndex < pcCount; ++pcIndex) {
nsCAutoString pcString;
pcString.AppendPrintf("0x%p", mHangReports[i].callStack[pcIndex]);
JSString *str = JS_NewStringCopyZ(cx, pcString.get());
if (!str) {
return NS_ERROR_FAILURE;
}
jsval v = STRING_TO_JSVAL(str);
if (!JS_SetElement(cx, pcArray, pcIndex, &v)) {
return NS_ERROR_FAILURE;
}
}
// Record memory map info
JSObject *moduleArray = JS_NewArrayObject(cx, 0, nsnull);
if (!moduleArray) {
return NS_ERROR_FAILURE;
}
ok = JS_DefineProperty(cx, reportObj, "memoryMap",
OBJECT_TO_JSVAL(moduleArray),
NULL, NULL, JSPROP_ENUMERATE);
if (!ok) {
return NS_ERROR_FAILURE;
}
const PRUint32 moduleCount = mHangReports[i].moduleMap.GetSize();
for (size_t moduleIndex = 0; moduleIndex < moduleCount; ++moduleIndex) {
// Current module
const SharedLibrary &module =
mHangReports[i].moduleMap.GetEntry(moduleIndex);
JSObject *moduleInfoArray = JS_NewArrayObject(cx, 0, nsnull);
if (!moduleInfoArray) {
return NS_ERROR_FAILURE;
}
jsval val = OBJECT_TO_JSVAL(moduleInfoArray);
if (!JS_SetElement(cx, moduleArray, moduleIndex, &val)) {
return NS_ERROR_FAILURE;
}
// Start address
nsCAutoString addressString;
addressString.AppendPrintf("0x%p", module.GetStart());
JSString *str = JS_NewStringCopyZ(cx, addressString.get());
if (!str) {
return NS_ERROR_FAILURE;
}
val = STRING_TO_JSVAL(str);
if (!JS_SetElement(cx, moduleInfoArray, 0, &val)) {
return NS_ERROR_FAILURE;
}
// Module name
str = JS_NewStringCopyZ(cx, module.GetName());
if (!str) {
return NS_ERROR_FAILURE;
}
val = STRING_TO_JSVAL(str);
if (!JS_SetElement(cx, moduleInfoArray, 1, &val)) {
return NS_ERROR_FAILURE;
}
// Module size in memory
val = INT_TO_JSVAL(int32_t(module.GetEnd() - module.GetStart()));
if (!JS_SetElement(cx, moduleInfoArray, 2, &val)) {
return NS_ERROR_FAILURE;
}
// "PDB Age" identifier
val = INT_TO_JSVAL(0);
#if defined(MOZ_PROFILING) && defined(XP_WIN)
val = INT_TO_JSVAL(module.GetPdbAge());
#endif
if (!JS_SetElement(cx, moduleInfoArray, 3, &val)) {
return NS_ERROR_FAILURE;
}
// "PDB Signature" GUID
char guidString[NSID_LENGTH] = { 0 };
#if defined(MOZ_PROFILING) && defined(XP_WIN)
module.GetPdbSignature().ToProvidedString(guidString);
#endif
str = JS_NewStringCopyZ(cx, guidString);
if (!str) {
return NS_ERROR_FAILURE;
}
val = STRING_TO_JSVAL(str);
if (!JS_SetElement(cx, moduleInfoArray, 4, &val)) {
return NS_ERROR_FAILURE;
}
}
}
return NS_OK;
}
NS_IMETHODIMP
TelemetryImpl::GetRegisteredHistograms(JSContext *cx, jsval *ret)
{
@ -1378,6 +1527,34 @@ TelemetryImpl::RecordSlowStatement(const nsACString &statement,
entry->mData.totalTime += delay;
}
void
TelemetryImpl::RecordChromeHang(PRUint32 duration,
const Telemetry::HangStack &callStack,
SharedLibraryInfo &moduleMap)
{
MOZ_ASSERT(sTelemetry);
if (!sTelemetry->mCanRecord) {
return;
}
MutexAutoLock hangReportMutex(sTelemetry->mHangReportsMutex);
// Only report the modules which changed since the first hang report
if (sTelemetry->mHangReports.Length()) {
SharedLibraryInfo &firstModuleMap =
sTelemetry->mHangReports[0].moduleMap;
for (size_t i = 0; i < moduleMap.GetSize(); ++i) {
if (firstModuleMap.Contains(moduleMap.GetEntry(i))) {
moduleMap.RemoveEntries(i, i + 1);
--i;
}
}
}
HangReport newReport = { duration, callStack, moduleMap };
sTelemetry->mHangReports.AppendElement(newReport);
}
NS_IMPL_THREADSAFE_ISUPPORTS1(TelemetryImpl, nsITelemetry)
NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsITelemetry, TelemetryImpl::CreateTelemetryInstance)
@ -1459,6 +1636,13 @@ void Init()
MOZ_ASSERT(telemetryService);
}
void RecordChromeHang(PRUint32 duration,
const Telemetry::HangStack &callStack,
SharedLibraryInfo &moduleMap)
{
TelemetryImpl::RecordChromeHang(duration, callStack, moduleMap);
}
} // namespace Telemetry
} // namespace mozilla

View File

@ -42,6 +42,9 @@
#include "mozilla/GuardObjects.h"
#include "mozilla/TimeStamp.h"
#include "mozilla/StartupTimeline.h"
#include "nsTArray.h"
#include "nsStringGlue.h"
#include "shared-libraries.h"
namespace base {
class Histogram;
@ -156,6 +159,22 @@ void RecordSlowSQLStatement(const nsACString &statement,
*/
const PRUint32 kSlowStatementThreshold = 100;
/**
* nsTArray of pointers representing PCs on a call stack
*/
typedef nsTArray<uintptr_t> HangStack;
/**
* Record the main thread's call stack after it hangs.
*
* @param duration - Approximate duration of main thread hang in seconds
* @param callStack - Array of PCs from the hung call stack
* @param moduleMap - Array of info about modules in memory (for symbolication)
*/
void RecordChromeHang(PRUint32 duration,
const HangStack &callStack,
SharedLibraryInfo &moduleMap);
} // namespace Telemetry
} // namespace mozilla
#endif // Telemetry_h__

View File

@ -453,6 +453,7 @@ TelemetryPing.prototype = {
payloadObj.simpleMeasurements = getSimpleMeasurements();
payloadObj.histograms = this.getHistograms(Telemetry.histogramSnapshots);
payloadObj.slowSQL = Telemetry.slowSQL;
payloadObj.chromeHangs = Telemetry.chromeHangs;
payloadObj.addonHistograms = this.getAddonHistograms();
}
if (Object.keys(this._slowSQLStartup.mainThread).length

View File

@ -70,7 +70,7 @@ interface nsITelemetrySaveSessionDataCallback : nsISupports
void handle(in bool success);
};
[scriptable, uuid(db854295-478d-4de9-8211-d73ed7d81cd0)]
[scriptable, uuid(f23a2c8d-9286-42e9-ab1b-ed287eeade6d)]
interface nsITelemetry : nsISupports
{
/**
@ -118,6 +118,14 @@ interface nsITelemetry : nsISupports
[implicit_jscontext]
readonly attribute jsval slowSQL;
/*
* An array of chrome hang reports. Each element is a hang report represented
* as an object containing the hang duration, call stack PCs and information
* about modules in memory.
*/
[implicit_jscontext]
readonly attribute jsval chromeHangs;
/**
* An object whose properties are the names of histograms defined in
* TelemetryHistograms.h and whose corresponding values are the textual

View File

@ -56,7 +56,6 @@ CPPSRCS += \
$(NULL)
ifeq ($(OS_ARCH),WINNT)
REQUIRES += widget gfx
CPPSRCS += \
nsDllMain.cpp \
$(NULL)
@ -82,7 +81,6 @@ DEFINES += -DZLIB_DLL=1
endif
ifeq ($(OS_ARCH),OS2)
REQUIRES += widget gfx
CPPSRCS += \
nsGFXDeps.cpp \

View File

@ -827,10 +827,12 @@ ifdef MOZ_POST_STAGING_CMD
cd $(DIST)/$(STAGEPATH)$(MOZ_PKG_DIR)$(_BINPATH) && $(MOZ_POST_STAGING_CMD)
endif # MOZ_POST_STAGING_CMD
ifndef LIBXUL_SDK
ifdef MOZ_PACKAGE_JSSHELL
# Package JavaScript Shell
@echo "Packaging JavaScript Shell..."
$(RM) $(PKG_JSSHELL)
$(MAKE_JSSHELL)
endif # MOZ_PACKAGE_JSSHELL
endif # LIBXUL_SDK
make-package: stage-package $(PACKAGE_XULRUNNER) make-sourcestamp-file

View File

@ -48,6 +48,7 @@ EXPORTS = \
sampler.h \
sps_sampler.h \
thread_helper.h \
shared-libraries.h \
$(NULL)
LOCAL_INCLUDES += \

View File

@ -54,6 +54,10 @@ interface nsIProfiler : nsISupports
* Every object has three properties: start, end, and name.
* start and end are integers describing the address range that the library
* occupies in memory. name is the path of the library as a string.
*
* On Windows profiling builds, the shared library objects will have
* additional pdbSignature and pdbAge properties for uniquely identifying
* shared library versions for stack symbolication.
*/
AString getSharedLibraryInformation();
};

View File

@ -96,6 +96,10 @@ AddSharedLibraryInfoToStream(std::ostream& aStream, SharedLibrary& aLib)
aStream << "\"start\":" << aLib.GetStart();
aStream << ",\"end\":" << aLib.GetEnd();
aStream << ",\"name\":\"" << aLib.GetName() << "\"";
#ifdef XP_WIN
aStream << ",\"pdbSignature\":\"" << aLib.GetPdbSignature().ToString() << "\"";
aStream << ",\"pdbAge\":" << aLib.GetPdbAge();
#endif
aStream << "}";
}

View File

@ -21,6 +21,7 @@
*
* Contributor(s):
* Jeff Muizelaar <jmuizelaar@mozilla.com>
* Vladan Djeric <vdjeric@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@ -38,10 +39,65 @@
#include <windows.h>
#include <tlhelp32.h>
#include <Dbghelp.h>
#include "shared-libraries.h"
#include "nsWindowsHelpers.h"
#define CV_SIGNATURE 0x53445352 // 'SDSR'
struct CodeViewRecord70
{
uint32_t signature;
GUID pdbSignature;
uint32_t pdbAge;
uint8_t pdbFileName[1];
};
static bool GetPdbInfo(uintptr_t aStart, nsID& aSignature, uint32_t& aAge)
{
if (!aStart) {
return false;
}
PIMAGE_DOS_HEADER dosHeader = reinterpret_cast<PIMAGE_DOS_HEADER>(aStart);
if (dosHeader->e_magic != IMAGE_DOS_SIGNATURE) {
return false;
}
PIMAGE_NT_HEADERS ntHeaders = reinterpret_cast<PIMAGE_NT_HEADERS>(
aStart + dosHeader->e_lfanew);
if (ntHeaders->Signature != IMAGE_NT_SIGNATURE) {
return false;
}
uint32_t relativeVirtualAddress =
ntHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress;
if (!relativeVirtualAddress) {
return false;
}
PIMAGE_DEBUG_DIRECTORY debugDirectory =
reinterpret_cast<PIMAGE_DEBUG_DIRECTORY>(aStart + relativeVirtualAddress);
if (!debugDirectory || debugDirectory->Type != IMAGE_DEBUG_TYPE_CODEVIEW) {
return false;
}
CodeViewRecord70 *debugInfo = reinterpret_cast<CodeViewRecord70 *>(
aStart + debugDirectory->AddressOfRawData);
if (!debugInfo || debugInfo->signature != CV_SIGNATURE) {
return false;
}
aAge = debugInfo->pdbAge;
GUID& pdbSignature = debugInfo->pdbSignature;
aSignature.m0 = pdbSignature.Data1;
aSignature.m1 = pdbSignature.Data2;
aSignature.m2 = pdbSignature.Data3;
memcpy(aSignature.m3, pdbSignature.Data4, sizeof(pdbSignature.Data4));
return true;
}
SharedLibraryInfo SharedLibraryInfo::GetInfoForSelf()
{
SharedLibraryInfo sharedLibraryInfo;
@ -52,11 +108,17 @@ SharedLibraryInfo SharedLibraryInfo::GetInfoForSelf()
module.dwSize = sizeof(MODULEENTRY32);
if (Module32First(snap, &module)) {
do {
SharedLibrary shlib((uintptr_t)module.modBaseAddr,
(uintptr_t)module.modBaseAddr+module.modBaseSize,
0, // DLLs are always mapped at offset 0 on Windows
module.szModule);
sharedLibraryInfo.AddSharedLibrary(shlib);
nsID pdbSig;
uint32_t pdbAge;
if (GetPdbInfo((uintptr_t)module.modBaseAddr, pdbSig, pdbAge)) {
SharedLibrary shlib((uintptr_t)module.modBaseAddr,
(uintptr_t)module.modBaseAddr+module.modBaseSize,
0, // DLLs are always mapped at offset 0 on Windows
pdbSig,
pdbAge,
module.szModule);
sharedLibraryInfo.AddSharedLibrary(shlib);
}
} while (Module32Next(snap, &module));
}

View File

@ -36,17 +36,31 @@
*
* ***** END LICENSE BLOCK ***** */
#include <algorithm>
#include <vector>
#include <string.h>
#include <stdlib.h>
#include <mozilla/StandardInteger.h>
#include <nsID.h>
class SharedLibrary {
public:
SharedLibrary(unsigned long aStart, unsigned long aEnd, unsigned long aOffset, char *aName)
SharedLibrary(unsigned long aStart,
unsigned long aEnd,
unsigned long aOffset,
#ifdef XP_WIN
nsID aPdbSignature,
unsigned long aPdbAge,
#endif
char *aName)
: mStart(aStart)
, mEnd(aEnd)
, mOffset(aOffset)
#ifdef XP_WIN
, mPdbSignature(aPdbSignature)
, mPdbAge(aPdbAge)
#endif
, mName(strdup(aName))
{}
@ -54,6 +68,10 @@ public:
: mStart(aEntry.mStart)
, mEnd(aEntry.mEnd)
, mOffset(aEntry.mOffset)
#ifdef XP_WIN
, mPdbSignature(aEntry.mPdbSignature)
, mPdbAge(aEntry.mPdbAge)
#endif
, mName(strdup(aEntry.mName))
{}
@ -65,20 +83,43 @@ public:
mStart = aEntry.mStart;
mEnd = aEntry.mEnd;
mOffset = aEntry.mOffset;
#ifdef XP_WIN
mPdbSignature = aEntry.mPdbSignature;
mPdbAge = aEntry.mPdbAge;
#endif
if (mName)
free(mName);
mName = strdup(aEntry.mName);
return *this;
}
bool operator==(const SharedLibrary& other) const
{
bool equal = ((mStart == other.mStart) &&
(mEnd == other.mEnd) &&
(mOffset == other.mOffset) &&
(mName && other.mName && (strcmp(mName, other.mName) == 0)));
#ifdef XP_WIN
equal = equal &&
(mPdbSignature.Equals(other.mPdbSignature)) &&
(mPdbAge == other.mPdbAge);
#endif
return equal;
}
~SharedLibrary()
{
free(mName);
mName = NULL;
}
uintptr_t GetStart() { return mStart; }
uintptr_t GetEnd() { return mEnd; }
char* GetName() { return mName; }
uintptr_t GetStart() const { return mStart; }
uintptr_t GetEnd() const { return mEnd; }
#ifdef XP_WIN
nsID GetPdbSignature() const { return mPdbSignature; }
uint32_t GetPdbAge() const { return mPdbAge; }
#endif
char* GetName() const { return mName; }
private:
explicit SharedLibrary() {}
@ -86,9 +127,20 @@ private:
uintptr_t mStart;
uintptr_t mEnd;
uintptr_t mOffset;
#ifdef XP_WIN
// Windows-specific PDB file identifiers
nsID mPdbSignature;
uint32_t mPdbAge;
#endif
char *mName;
};
static bool
CompareAddresses(const SharedLibrary& first, const SharedLibrary& second)
{
return first.GetStart() < second.GetStart();
}
class SharedLibraryInfo {
public:
static SharedLibraryInfo GetInfoForSelf();
@ -104,10 +156,34 @@ public:
return mEntries[i];
}
size_t GetSize()
// Removes items in the range [first, last)
// i.e. element at the "last" index is not removed
void RemoveEntries(size_t first, size_t last)
{
mEntries.erase(mEntries.begin() + first, mEntries.begin() + last);
}
bool Contains(const SharedLibrary& searchItem) const
{
return (mEntries.end() !=
std::find(mEntries.begin(), mEntries.end(), searchItem));
}
size_t GetSize() const
{
return mEntries.size();
}
void SortByAddress()
{
std::sort(mEntries.begin(), mEntries.end(), CompareAddresses);
}
void Clear()
{
mEntries.clear();
}
private:
std::vector<SharedLibrary> mEntries;
};

View File

@ -38,8 +38,10 @@
#include "mozilla/HangMonitor.h"
#include "mozilla/Monitor.h"
#include "mozilla/Preferences.h"
#include "mozilla/Telemetry.h"
#include "nsXULAppAPI.h"
#include "nsThreadUtils.h"
#include "nsStackWalk.h"
#ifdef MOZ_CRASHREPORTER
#include "nsExceptionHandler.h"
@ -49,6 +51,10 @@
#include <windows.h>
#endif
#if defined(MOZ_PROFILING) && defined(XP_WIN)
#define REPORT_CHROME_HANGS
#endif
namespace mozilla { namespace HangMonitor {
/**
@ -59,6 +65,8 @@ volatile bool gDebugDisableHangMonitor = false;
const char kHangMonitorPrefName[] = "hangmonitor.timeout";
const char kTelemetryPrefName[] = "toolkit.telemetry.enabled";
// Monitor protects gShutdown and gTimeout, but not gTimestamp which rely on
// being atomically set by the processor; synchronization doesn't really matter
// in this use case.
@ -76,11 +84,28 @@ bool gShutdown;
// we're currently not processing events.
volatile PRIntervalTime gTimestamp;
#ifdef REPORT_CHROME_HANGS
// Main thread ID used in reporting chrome hangs under Windows
static HANDLE winMainThreadHandle = NULL;
// Default timeout for reporting chrome hangs to Telemetry (10 seconds)
static const PRInt32 DEFAULT_CHROME_HANG_INTERVAL = 10;
#endif
// PrefChangedFunc
int
PrefChanged(const char*, void*)
{
PRInt32 newval = Preferences::GetInt(kHangMonitorPrefName);
#ifdef REPORT_CHROME_HANGS
// Monitor chrome hangs on the profiling branch if Telemetry enabled
if (newval == 0) {
PRBool telemetryEnabled = Preferences::GetBool(kTelemetryPrefName);
if (telemetryEnabled) {
newval = DEFAULT_CHROME_HANG_INTERVAL;
}
}
#endif
MonitorAutoLock lock(*gMonitor);
if (newval != gTimeout) {
gTimeout = newval;
@ -111,6 +136,76 @@ Crash()
NS_RUNTIMEABORT("HangMonitor triggered");
}
#ifdef REPORT_CHROME_HANGS
static void
ChromeStackWalker(void *aPC, void *aClosure)
{
MOZ_ASSERT(aClosure);
Telemetry::HangStack *callStack =
reinterpret_cast< Telemetry::HangStack* >(aClosure);
callStack->AppendElement(reinterpret_cast<uintptr_t>(aPC));
}
static void
GetChromeHangReport(Telemetry::HangStack &callStack, SharedLibraryInfo &moduleMap)
{
MOZ_ASSERT(winMainThreadHandle);
moduleMap = SharedLibraryInfo::GetInfoForSelf();
moduleMap.SortByAddress();
DWORD ret = ::SuspendThread(winMainThreadHandle);
if (ret == -1) {
callStack.Clear();
moduleMap.Clear();
return;
}
NS_StackWalk(ChromeStackWalker, 0, &callStack,
reinterpret_cast<uintptr_t>(winMainThreadHandle));
ret = ::ResumeThread(winMainThreadHandle);
if (ret == -1) {
callStack.Clear();
moduleMap.Clear();
return;
}
// Remove all modules not referenced by a PC on the stack
Telemetry::HangStack sortedStack = callStack;
sortedStack.Sort();
size_t moduleIndex = 0;
size_t stackIndex = 0;
bool unreferencedModule = true;
while (stackIndex < sortedStack.Length() && moduleIndex < moduleMap.GetSize()) {
uintptr_t pc = sortedStack[stackIndex];
SharedLibrary& module = moduleMap.GetEntry(moduleIndex);
uintptr_t moduleStart = module.GetStart();
uintptr_t moduleEnd = module.GetEnd() - 1;
if (moduleStart <= pc && pc <= moduleEnd) {
// If the current PC is within the current module, mark module as used
unreferencedModule = false;
++stackIndex;
} else if (pc > moduleEnd) {
if (unreferencedModule) {
// Remove module if no PCs within its address range
moduleMap.RemoveEntries(moduleIndex, moduleIndex + 1);
} else {
// Module was referenced on stack, but current PC belongs to later module
unreferencedModule = true;
++moduleIndex;
}
} else {
// PC does not belong to any module
++stackIndex;
}
}
// Clean up remaining unreferenced modules, i.e. module addresses > max(pc)
if (moduleIndex + 1 < moduleMap.GetSize()) {
moduleMap.RemoveEntries(moduleIndex + 1, moduleMap.GetSize());
}
}
#endif
void
ThreadMain(void*)
{
@ -122,6 +217,9 @@ ThreadMain(void*)
PRIntervalTime lastTimestamp = 0;
int waitCount = 0;
Telemetry::HangStack hangStack;
SharedLibraryInfo hangModuleMap;
while (true) {
if (gShutdown) {
return; // Exit the thread
@ -143,15 +241,27 @@ ThreadMain(void*)
gTimeout > 0) {
++waitCount;
if (waitCount == 2) {
#ifdef REPORT_CHROME_HANGS
GetChromeHangReport(hangStack, hangModuleMap);
#else
PRInt32 delay =
PRInt32(PR_IntervalToSeconds(now - timestamp));
if (delay > gTimeout) {
MonitorAutoUnlock unlock(*gMonitor);
Crash();
}
#endif
}
}
else {
#ifdef REPORT_CHROME_HANGS
if (waitCount >= 2) {
PRUint32 hangDuration = PR_IntervalToSeconds(now - lastTimestamp);
Telemetry::RecordChromeHang(hangDuration, hangStack, hangModuleMap);
hangStack.Clear();
hangModuleMap.Clear();
}
#endif
lastTimestamp = timestamp;
waitCount = 0;
}
@ -182,6 +292,14 @@ Startup()
Preferences::RegisterCallback(PrefChanged, kHangMonitorPrefName, NULL);
PrefChanged(NULL, NULL);
#ifdef REPORT_CHROME_HANGS
Preferences::RegisterCallback(PrefChanged, kTelemetryPrefName, NULL);
winMainThreadHandle =
OpenThread(THREAD_ALL_ACCESS, FALSE, GetCurrentThreadId());
if (!winMainThreadHandle)
return;
#endif
// Don't actually start measuring hangs until we hit the main event loop.
// This potentially misses a small class of really early startup hangs,
// but avoids dealing with some xpcshell tests and other situations which