Merge from mozilla-central.

--HG--
rename : accessible/src/base/nsTextAttrs.cpp => accessible/src/base/TextAttrs.cpp
rename : accessible/src/base/nsTextAttrs.h => accessible/src/base/TextAttrs.h
This commit is contained in:
David Anderson 2012-03-12 12:27:40 -07:00
commit a0b4d7ed85
642 changed files with 29644 additions and 13170 deletions

View File

@ -571,3 +571,26 @@ interface nsIAccessibleTableChangeEvent: nsISupports
readonly attribute long numRowsOrCols;
};
/*
* An interface for virtual cursor changed events.
* Passes previous cursor position and text offsets.
*/
[scriptable, uuid(370e8b9b-2bbc-4bff-a9c7-16ddc54aea21)]
interface nsIAccessibleVirtualCursorChangeEvent : nsISupports
{
/**
* Previous object pointed at by virtual cursor. null if none.
*/
readonly attribute nsIAccessible oldAccessible;
/**
* Previous start offset of pivot. -1 if none.
*/
readonly attribute long oldStartOffset;
/**
* Previous end offset of pivot. -1 if none.
*/
readonly attribute long oldEndOffset;
};

View File

@ -380,3 +380,24 @@ AccTableChangeEvent::CreateXPCOMObject()
return event;
}
////////////////////////////////////////////////////////////////////////////////
// AccVCChangeEvent
////////////////////////////////////////////////////////////////////////////////
AccVCChangeEvent::
AccVCChangeEvent(nsAccessible* aAccessible,
nsIAccessible* aOldAccessible,
PRInt32 aOldStart, PRInt32 aOldEnd) :
AccEvent(::nsIAccessibleEvent::EVENT_VIRTUALCURSOR_CHANGED, aAccessible),
mOldAccessible(aOldAccessible), mOldStart(aOldStart), mOldEnd(aOldEnd)
{
}
already_AddRefed<nsAccEvent>
AccVCChangeEvent::CreateXPCOMObject()
{
nsAccEvent* event = new nsAccVirtualCursorChangeEvent(this);
NS_ADDREF(event);
return event;
}

View File

@ -129,7 +129,8 @@ public:
eShowEvent,
eCaretMoveEvent,
eSelectionChangeEvent,
eTableChangeEvent
eTableChangeEvent,
eVirtualCursorChangeEvent
};
static const EventGroup kEventGroup = eGenericEvent;
@ -399,6 +400,37 @@ private:
PRUint32 mNumRowsOrCols; // the number of inserted/deleted rows/columns
};
/**
* Accessible virtual cursor change event.
*/
class AccVCChangeEvent : public AccEvent
{
public:
AccVCChangeEvent(nsAccessible* aAccessible,
nsIAccessible* aOldAccessible,
PRInt32 aOldStart, PRInt32 aOldEnd);
virtual ~AccVCChangeEvent() { }
// AccEvent
virtual already_AddRefed<nsAccEvent> CreateXPCOMObject();
static const EventGroup kEventGroup = eVirtualCursorChangeEvent;
virtual unsigned int GetEventGroups() const
{
return AccEvent::GetEventGroups() | (1U << eVirtualCursorChangeEvent);
}
// AccTableChangeEvent
nsIAccessible* OldAccessible() const { return mOldAccessible; }
PRInt32 OldStartOffset() const { return mOldStart; }
PRInt32 OldEndOffset() const { return mOldEnd; }
private:
nsRefPtr<nsIAccessible> mOldAccessible;
PRInt32 mOldStart;
PRInt32 mOldEnd;
};
/**
* Downcast the generic accessible event object to derived type.

View File

@ -75,8 +75,8 @@ CPPSRCS = \
nsCaretAccessible.cpp \
nsTextAccessible.cpp \
nsTextEquivUtils.cpp \
nsTextAttrs.cpp \
StyleInfo.cpp \
TextAttrs.cpp \
TextUpdater.cpp \
$(NULL)

View File

@ -131,3 +131,12 @@ StyleInfo::FormatFontStyle(const nscoord& aValue, nsAString& aFormattedValue)
nsCSSProps::ValueToKeywordEnum(aValue, nsCSSProps::kFontStyleKTable);
AppendUTF8toUTF16(nsCSSKeywords::GetStringValue(keyword), aFormattedValue);
}
void
StyleInfo::FormatTextDecorationStyle(PRUint8 aValue, nsAString& aFormattedValue)
{
nsCSSKeyword keyword =
nsCSSProps::ValueToKeywordEnum(aValue,
nsCSSProps::kTextDecorationStyleKTable);
AppendUTF8toUTF16(nsCSSKeywords::GetStringValue(keyword), aFormattedValue);
}

View File

@ -62,6 +62,7 @@ public:
static void FormatColor(const nscolor& aValue, nsString& aFormattedValue);
static void FormatFontStyle(const nscoord& aValue, nsAString& aFormattedValue);
static void FormatTextDecorationStyle(PRUint8 aValue, nsAString& aFormattedValue);
private:
StyleInfo() MOZ_DELETE;

View File

@ -36,7 +36,7 @@
*
* ***** END LICENSE BLOCK ***** */
#include "nsTextAttrs.h"
#include "TextAttrs.h"
#include "nsAccUtils.h"
#include "nsCoreUtils.h"
@ -73,28 +73,18 @@ const char* const kCopyValue = nsnull;
static nsCSSTextAttrMapItem gCSSTextAttrsMap[] =
{
// CSS name CSS value Attribute name Attribute value
{ "text-decoration", "line-through", &nsGkAtoms::textLineThroughStyle, "solid" },
{ "text-decoration", "underline", &nsGkAtoms::textUnderlineStyle, "solid" },
// CSS name CSS value Attribute name Attribute value
{ "vertical-align", kAnyValue, &nsGkAtoms::textPosition, kCopyValue }
};
////////////////////////////////////////////////////////////////////////////////
// nsTextAttrs
// TextAttrsMgr
////////////////////////////////////////////////////////////////////////////////
nsTextAttrsMgr::nsTextAttrsMgr(nsHyperTextAccessible *aHyperTextAcc,
bool aIncludeDefAttrs,
nsAccessible *aOffsetAcc,
PRInt32 aOffsetAccIdx) :
mHyperTextAcc(aHyperTextAcc), mIncludeDefAttrs(aIncludeDefAttrs),
mOffsetAcc(aOffsetAcc), mOffsetAccIdx(aOffsetAccIdx)
{
}
nsresult
nsTextAttrsMgr::GetAttributes(nsIPersistentProperties *aAttributes,
PRInt32 *aStartHTOffset,
PRInt32 *aEndHTOffset)
void
TextAttrsMgr::GetAttributes(nsIPersistentProperties* aAttributes,
PRInt32* aStartHTOffset,
PRInt32* aEndHTOffset)
{
// 1. Hyper text accessible must be specified always.
// 2. Offset accessible and result hyper text offsets must be specified in
@ -108,7 +98,7 @@ nsTextAttrsMgr::GetAttributes(nsIPersistentProperties *aAttributes,
(!mOffsetAcc && mOffsetAccIdx == -1 &&
!aStartHTOffset && !aEndHTOffset &&
mIncludeDefAttrs && aAttributes)),
"Wrong usage of nsTextAttrsMgr!");
"Wrong usage of TextAttrsMgr!");
// Embedded objects are combined into own range with empty attributes set.
if (mOffsetAcc && nsAccUtils::IsEmbeddedObject(mOffsetAcc)) {
@ -130,7 +120,7 @@ nsTextAttrsMgr::GetAttributes(nsIPersistentProperties *aAttributes,
(*aEndHTOffset)++;
}
return NS_OK;
return;
}
// Get the content and frame of the accessible. In the case of document
@ -139,7 +129,7 @@ nsTextAttrsMgr::GetAttributes(nsIPersistentProperties *aAttributes,
nsIFrame *rootFrame = mHyperTextAcc->GetFrame();
NS_ASSERTION(rootFrame, "No frame for accessible!");
if (!rootFrame)
return NS_OK;
return;
nsIContent *offsetNode = nsnull, *offsetElm = nsnull;
nsIFrame *frame = nsnull;
@ -149,26 +139,18 @@ nsTextAttrsMgr::GetAttributes(nsIPersistentProperties *aAttributes,
frame = offsetElm->GetPrimaryFrame();
}
nsTArray<nsITextAttr*> textAttrArray(10);
nsTArray<TextAttr*> textAttrArray(9);
// "language" text attribute
nsLangTextAttr langTextAttr(mHyperTextAcc, hyperTextElm, offsetNode);
LangTextAttr langTextAttr(mHyperTextAcc, hyperTextElm, offsetNode);
textAttrArray.AppendElement(&langTextAttr);
// "text-line-through-style" text attribute
nsCSSTextAttr lineThroughTextAttr(0, hyperTextElm, offsetElm);
textAttrArray.AppendElement(&lineThroughTextAttr);
// "text-underline-style" text attribute
nsCSSTextAttr underlineTextAttr(1, hyperTextElm, offsetElm);
textAttrArray.AppendElement(&underlineTextAttr);
// "text-position" text attribute
nsCSSTextAttr posTextAttr(2, hyperTextElm, offsetElm);
CSSTextAttr posTextAttr(0, hyperTextElm, offsetElm);
textAttrArray.AppendElement(&posTextAttr);
// "background-color" text attribute
nsBGColorTextAttr bgColorTextAttr(rootFrame, frame);
BGColorTextAttr bgColorTextAttr(rootFrame, frame);
textAttrArray.AppendElement(&bgColorTextAttr);
// "color" text attribute
@ -180,7 +162,7 @@ nsTextAttrsMgr::GetAttributes(nsIPersistentProperties *aAttributes,
textAttrArray.AppendElement(&fontFamilyTextAttr);
// "font-size" text attribute
nsFontSizeTextAttr fontSizeTextAttr(rootFrame, frame);
FontSizeTextAttr fontSizeTextAttr(rootFrame, frame);
textAttrArray.AppendElement(&fontSizeTextAttr);
// "font-style" text attribute
@ -188,34 +170,28 @@ nsTextAttrsMgr::GetAttributes(nsIPersistentProperties *aAttributes,
textAttrArray.AppendElement(&fontStyleTextAttr);
// "font-weight" text attribute
nsFontWeightTextAttr fontWeightTextAttr(rootFrame, frame);
FontWeightTextAttr fontWeightTextAttr(rootFrame, frame);
textAttrArray.AppendElement(&fontWeightTextAttr);
// "text-underline(line-through)-style(color)" text attributes
TextDecorTextAttr textDecorTextAttr(rootFrame, frame);
textAttrArray.AppendElement(&textDecorTextAttr);
// Expose text attributes if applicable.
if (aAttributes) {
PRUint32 len = textAttrArray.Length();
for (PRUint32 idx = 0; idx < len; idx++) {
nsITextAttr *textAttr = textAttrArray[idx];
nsAutoString value;
if (textAttr->GetValue(value, mIncludeDefAttrs))
nsAccUtils::SetAccAttr(aAttributes, textAttr->GetName(), value);
}
for (PRUint32 idx = 0; idx < len; idx++)
textAttrArray[idx]->Expose(aAttributes, mIncludeDefAttrs);
}
nsresult rv = NS_OK;
// Expose text attributes range where they are applied if applicable.
if (mOffsetAcc)
rv = GetRange(textAttrArray, aStartHTOffset, aEndHTOffset);
textAttrArray.Clear();
return rv;
GetRange(textAttrArray, aStartHTOffset, aEndHTOffset);
}
nsresult
nsTextAttrsMgr::GetRange(const nsTArray<nsITextAttr*>& aTextAttrArray,
PRInt32 *aStartHTOffset, PRInt32 *aEndHTOffset)
void
TextAttrsMgr::GetRange(const nsTArray<TextAttr*>& aTextAttrArray,
PRInt32* aStartHTOffset, PRInt32* aEndHTOffset)
{
PRUint32 attrLen = aTextAttrArray.Length();
@ -228,12 +204,13 @@ nsTextAttrsMgr::GetRange(const nsTArray<nsITextAttr*>& aTextAttrArray,
if (nsAccUtils::IsEmbeddedObject(currAcc))
break;
nsIContent *currElm = nsCoreUtils::GetDOMElementFor(currAcc->GetContent());
NS_ENSURE_STATE(currElm);
nsIContent* currElm = nsCoreUtils::GetDOMElementFor(currAcc->GetContent());
if (!currElm)
return;
bool offsetFound = false;
for (PRUint32 attrIdx = 0; attrIdx < attrLen; attrIdx++) {
nsITextAttr *textAttr = aTextAttrArray[attrIdx];
TextAttr* textAttr = aTextAttrArray[attrIdx];
if (!textAttr->Equal(currElm)) {
offsetFound = true;
break;
@ -253,12 +230,13 @@ nsTextAttrsMgr::GetRange(const nsTArray<nsITextAttr*>& aTextAttrArray,
if (nsAccUtils::IsEmbeddedObject(currAcc))
break;
nsIContent *currElm = nsCoreUtils::GetDOMElementFor(currAcc->GetContent());
NS_ENSURE_STATE(currElm);
nsIContent* currElm = nsCoreUtils::GetDOMElementFor(currAcc->GetContent());
if (!currElm)
return;
bool offsetFound = false;
for (PRUint32 attrIdx = 0; attrIdx < attrLen; attrIdx++) {
nsITextAttr *textAttr = aTextAttrArray[attrIdx];
TextAttr* textAttr = aTextAttrArray[attrIdx];
// Alter the end offset when text attribute changes its value and stop
// the search.
@ -273,69 +251,68 @@ nsTextAttrsMgr::GetRange(const nsTArray<nsITextAttr*>& aTextAttrArray,
(*aEndHTOffset) += nsAccUtils::TextLength(currAcc);
}
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
// nsLangTextAttr
nsLangTextAttr::nsLangTextAttr(nsHyperTextAccessible *aRootAcc,
nsIContent *aRootContent, nsIContent *aContent) :
nsTextAttr<nsAutoString>(aContent == nsnull), mRootContent(aRootContent)
////////////////////////////////////////////////////////////////////////////////
// LangTextAttr
////////////////////////////////////////////////////////////////////////////////
TextAttrsMgr::LangTextAttr::
LangTextAttr(nsHyperTextAccessible* aRoot,
nsIContent* aRootElm, nsIContent* aElm) :
TTextAttr<nsString>(!aElm), mRootContent(aRootElm)
{
aRootAcc->Language(mRootNativeValue);
aRoot->Language(mRootNativeValue);
mIsRootDefined = !mRootNativeValue.IsEmpty();
if (aContent)
mIsDefined = GetLang(aContent, mNativeValue);
if (aElm)
mIsDefined = GetLang(aElm, mNativeValue);
}
bool
nsLangTextAttr::GetValueFor(nsIContent *aElm, nsAutoString *aValue)
TextAttrsMgr::LangTextAttr::
GetValueFor(nsIContent* aElm, nsString* aValue)
{
return GetLang(aElm, *aValue);
}
void
nsLangTextAttr::Format(const nsAutoString& aValue, nsAString& aFormattedValue)
TextAttrsMgr::LangTextAttr::
ExposeValue(nsIPersistentProperties* aAttributes, const nsString& aValue)
{
aFormattedValue = aValue;
nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::language, aValue);
}
bool
nsLangTextAttr::GetLang(nsIContent *aContent, nsAString& aLang)
TextAttrsMgr::LangTextAttr::
GetLang(nsIContent* aElm, nsAString& aLang)
{
nsCoreUtils::GetLanguageFor(aContent, mRootContent, aLang);
nsCoreUtils::GetLanguageFor(aElm, mRootContent, aLang);
return !aLang.IsEmpty();
}
////////////////////////////////////////////////////////////////////////////////
// nsCSSTextAttr
// CSSTextAttr
////////////////////////////////////////////////////////////////////////////////
nsCSSTextAttr::nsCSSTextAttr(PRUint32 aIndex, nsIContent *aRootContent,
nsIContent *aContent) :
nsTextAttr<nsAutoString>(aContent == nsnull), mIndex(aIndex)
TextAttrsMgr::CSSTextAttr::
CSSTextAttr(PRUint32 aIndex, nsIContent* aRootElm, nsIContent* aElm) :
TTextAttr<nsString>(!aElm), mIndex(aIndex)
{
mIsRootDefined = GetValueFor(aRootContent, &mRootNativeValue);
mIsRootDefined = GetValueFor(aRootElm, &mRootNativeValue);
if (aContent)
mIsDefined = GetValueFor(aContent, &mNativeValue);
}
nsIAtom*
nsCSSTextAttr::GetName() const
{
return *gCSSTextAttrsMap[mIndex].mAttrName;
if (aElm)
mIsDefined = GetValueFor(aElm, &mNativeValue);
}
bool
nsCSSTextAttr::GetValueFor(nsIContent *aContent, nsAutoString *aValue)
TextAttrsMgr::CSSTextAttr::
GetValueFor(nsIContent* aElm, nsString* aValue)
{
nsCOMPtr<nsIDOMCSSStyleDeclaration> currStyleDecl =
nsCoreUtils::GetComputedStyleDeclaration(EmptyString(), aContent);
nsCoreUtils::GetComputedStyleDeclaration(EmptyString(), aElm);
if (!currStyleDecl)
return false;
@ -353,22 +330,30 @@ nsCSSTextAttr::GetValueFor(nsIContent *aContent, nsAutoString *aValue)
}
void
nsCSSTextAttr::Format(const nsAutoString& aValue, nsAString& aFormattedValue)
TextAttrsMgr::CSSTextAttr::
ExposeValue(nsIPersistentProperties* aAttributes, const nsString& aValue)
{
const char *attrValue = gCSSTextAttrsMap[mIndex].mAttrValue;
if (attrValue != kCopyValue)
AppendASCIItoUTF16(attrValue, aFormattedValue);
else
aFormattedValue = 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);
}
////////////////////////////////////////////////////////////////////////////////
// nsBGColorTextAttr
// BGColorTextAttr
////////////////////////////////////////////////////////////////////////////////
nsBGColorTextAttr::nsBGColorTextAttr(nsIFrame *aRootFrame, nsIFrame *aFrame) :
nsTextAttr<nscolor>(aFrame == nsnull), mRootFrame(aRootFrame)
TextAttrsMgr::BGColorTextAttr::
BGColorTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame) :
TTextAttr<nscolor>(!aFrame), mRootFrame(aRootFrame)
{
mIsRootDefined = GetColor(mRootFrame, &mRootNativeValue);
if (aFrame)
@ -376,27 +361,28 @@ nsBGColorTextAttr::nsBGColorTextAttr(nsIFrame *aRootFrame, nsIFrame *aFrame) :
}
bool
nsBGColorTextAttr::GetValueFor(nsIContent *aContent, nscolor *aValue)
TextAttrsMgr::BGColorTextAttr::
GetValueFor(nsIContent* aElm, nscolor* aValue)
{
nsIFrame *frame = aContent->GetPrimaryFrame();
if (!frame)
return false;
return GetColor(frame, aValue);
nsIFrame* frame = aElm->GetPrimaryFrame();
return frame ? GetColor(frame, aValue) : false;
}
void
nsBGColorTextAttr::Format(const nscolor& aValue, nsAString& aFormattedValue)
TextAttrsMgr::BGColorTextAttr::
ExposeValue(nsIPersistentProperties* aAttributes, const nscolor& aValue)
{
nsAutoString value;
StyleInfo::FormatColor(aValue, value);
aFormattedValue = value;
nsAutoString formattedValue;
StyleInfo::FormatColor(aValue, formattedValue);
nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::backgroundColor,
formattedValue);
}
bool
nsBGColorTextAttr::GetColor(nsIFrame *aFrame, nscolor *aColor)
TextAttrsMgr::BGColorTextAttr::
GetColor(nsIFrame* aFrame, nscolor* aColor)
{
const nsStyleBackground *styleBackground = aFrame->GetStyleBackground();
const nsStyleBackground* styleBackground = aFrame->GetStyleBackground();
if (NS_GET_A(styleBackground->mBackgroundColor) > 0) {
*aColor = styleBackground->mBackgroundColor;
@ -423,8 +409,9 @@ nsBGColorTextAttr::GetColor(nsIFrame *aFrame, nscolor *aColor)
// ColorTextAttr
////////////////////////////////////////////////////////////////////////////////
ColorTextAttr::ColorTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame) :
nsTextAttr<nscolor>(!aFrame)
TextAttrsMgr::ColorTextAttr::
ColorTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame) :
TTextAttr<nscolor>(!aFrame)
{
mRootNativeValue = aRootFrame->GetStyleColor()->mColor;
mIsRootDefined = true;
@ -436,9 +423,10 @@ ColorTextAttr::ColorTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame) :
}
bool
ColorTextAttr::GetValueFor(nsIContent* aContent, nscolor* aValue)
TextAttrsMgr::ColorTextAttr::
GetValueFor(nsIContent* aElm, nscolor* aValue)
{
nsIFrame* frame = aContent->GetPrimaryFrame();
nsIFrame* frame = aElm->GetPrimaryFrame();
if (frame) {
*aValue = frame->GetStyleColor()->mColor;
return true;
@ -448,11 +436,12 @@ ColorTextAttr::GetValueFor(nsIContent* aContent, nscolor* aValue)
}
void
ColorTextAttr::Format(const nscolor& aValue, nsAString& aFormattedValue)
TextAttrsMgr::ColorTextAttr::
ExposeValue(nsIPersistentProperties* aAttributes, const nscolor& aValue)
{
nsAutoString value;
StyleInfo::FormatColor(aValue, value);
aFormattedValue = value;
nsAutoString formattedValue;
StyleInfo::FormatColor(aValue, formattedValue);
nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::color, formattedValue);
}
@ -460,8 +449,9 @@ ColorTextAttr::Format(const nscolor& aValue, nsAString& aFormattedValue)
// FontFamilyTextAttr
////////////////////////////////////////////////////////////////////////////////
FontFamilyTextAttr::FontFamilyTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame) :
nsTextAttr<nsAutoString>(aFrame == nsnull)
TextAttrsMgr::FontFamilyTextAttr::
FontFamilyTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame) :
TTextAttr<nsString>(!aFrame)
{
mIsRootDefined = GetFontFamily(aRootFrame, mRootNativeValue);
@ -470,24 +460,23 @@ FontFamilyTextAttr::FontFamilyTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame) :
}
bool
FontFamilyTextAttr::GetValueFor(nsIContent* aElm, nsAutoString* aValue)
TextAttrsMgr::FontFamilyTextAttr::
GetValueFor(nsIContent* aElm, nsString* aValue)
{
nsIFrame* frame = aElm->GetPrimaryFrame();
if (!frame)
return false;
return GetFontFamily(frame, *aValue);
return frame ? GetFontFamily(frame, *aValue) : false;
}
void
FontFamilyTextAttr::Format(const nsAutoString& aValue,
nsAString& aFormattedValue)
TextAttrsMgr::FontFamilyTextAttr::
ExposeValue(nsIPersistentProperties* aAttributes, const nsString& aValue)
{
aFormattedValue = aValue;
nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::font_family, aValue);
}
bool
FontFamilyTextAttr::GetFontFamily(nsIFrame* aFrame, nsAutoString& aFamily)
TextAttrsMgr::FontFamilyTextAttr::
GetFontFamily(nsIFrame* aFrame, nsString& aFamily)
{
nsRefPtr<nsFontMetrics> fm;
nsLayoutUtils::GetFontMetricsForFrame(aFrame, getter_AddRefs(fm));
@ -501,36 +490,40 @@ FontFamilyTextAttr::GetFontFamily(nsIFrame* aFrame, nsAutoString& aFamily)
////////////////////////////////////////////////////////////////////////////////
// nsFontSizeTextAttr
// FontSizeTextAttr
////////////////////////////////////////////////////////////////////////////////
nsFontSizeTextAttr::nsFontSizeTextAttr(nsIFrame *aRootFrame, nsIFrame *aFrame) :
nsTextAttr<nscoord>(aFrame == nsnull)
TextAttrsMgr::FontSizeTextAttr::
FontSizeTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame) :
TTextAttr<nscoord>(!aFrame)
{
mDC = aRootFrame->PresContext()->DeviceContext();
mRootNativeValue = GetFontSize(aRootFrame);
mRootNativeValue = aRootFrame->GetStyleFont()->mSize;
mIsRootDefined = true;
if (aFrame) {
mNativeValue = GetFontSize(aFrame);
mNativeValue = aFrame->GetStyleFont()->mSize;
mIsDefined = true;
}
}
bool
nsFontSizeTextAttr::GetValueFor(nsIContent *aContent, nscoord *aValue)
TextAttrsMgr::FontSizeTextAttr::
GetValueFor(nsIContent* aElm, nscoord* aValue)
{
nsIFrame *frame = aContent->GetPrimaryFrame();
if (!frame)
return false;
nsIFrame* frame = aElm->GetPrimaryFrame();
if (frame) {
*aValue = frame->GetStyleFont()->mSize;
return true;
}
*aValue = GetFontSize(frame);
return true;
return false;
}
void
nsFontSizeTextAttr::Format(const nscoord& aValue, nsAString& aFormattedValue)
TextAttrsMgr::FontSizeTextAttr::
ExposeValue(nsIPersistentProperties* aAttributes, const nscoord& aValue)
{
// Convert from nscoord to pt.
//
@ -548,13 +541,8 @@ nsFontSizeTextAttr::Format(const nscoord& aValue, nsAString& aFormattedValue)
nsAutoString value;
value.AppendInt(pts);
value.Append(NS_LITERAL_STRING("pt"));
aFormattedValue = value;
}
nscoord
nsFontSizeTextAttr::GetFontSize(nsIFrame *aFrame)
{
return aFrame->GetStyleFont()->mSize;
nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::font_size, value);
}
@ -562,8 +550,9 @@ nsFontSizeTextAttr::GetFontSize(nsIFrame *aFrame)
// FontStyleTextAttr
////////////////////////////////////////////////////////////////////////////////
FontStyleTextAttr::FontStyleTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame) :
nsTextAttr<nscoord>(!aFrame)
TextAttrsMgr::FontStyleTextAttr::
FontStyleTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame) :
TTextAttr<nscoord>(!aFrame)
{
mRootNativeValue = aRootFrame->GetStyleFont()->mFont.style;
mIsRootDefined = true;
@ -575,7 +564,8 @@ FontStyleTextAttr::FontStyleTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame) :
}
bool
FontStyleTextAttr::GetValueFor(nsIContent* aContent, nscoord* aValue)
TextAttrsMgr::FontStyleTextAttr::
GetValueFor(nsIContent* aContent, nscoord* aValue)
{
nsIFrame* frame = aContent->GetPrimaryFrame();
if (frame) {
@ -587,19 +577,23 @@ FontStyleTextAttr::GetValueFor(nsIContent* aContent, nscoord* aValue)
}
void
FontStyleTextAttr::Format(const nscoord& aValue, nsAString& aFormattedValue)
TextAttrsMgr::FontStyleTextAttr::
ExposeValue(nsIPersistentProperties* aAttributes, const nscoord& aValue)
{
StyleInfo::FormatFontStyle(aValue, aFormattedValue);
nsAutoString formattedValue;
StyleInfo::FormatFontStyle(aValue, formattedValue);
nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::font_style, formattedValue);
}
////////////////////////////////////////////////////////////////////////////////
// nsFontWeightTextAttr
// FontWeightTextAttr
////////////////////////////////////////////////////////////////////////////////
nsFontWeightTextAttr::nsFontWeightTextAttr(nsIFrame *aRootFrame,
nsIFrame *aFrame) :
nsTextAttr<PRInt32>(aFrame == nsnull)
TextAttrsMgr::FontWeightTextAttr::
FontWeightTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame) :
TTextAttr<PRInt32>(!aFrame)
{
mRootNativeValue = GetFontWeight(aRootFrame);
mIsRootDefined = true;
@ -611,26 +605,31 @@ nsFontWeightTextAttr::nsFontWeightTextAttr(nsIFrame *aRootFrame,
}
bool
nsFontWeightTextAttr::GetValueFor(nsIContent *aContent, PRInt32 *aValue)
TextAttrsMgr::FontWeightTextAttr::
GetValueFor(nsIContent* aElm, PRInt32* aValue)
{
nsIFrame *frame = aContent->GetPrimaryFrame();
if (!frame)
return false;
nsIFrame* frame = aElm->GetPrimaryFrame();
if (frame) {
*aValue = GetFontWeight(frame);
return true;
}
*aValue = GetFontWeight(frame);
return true;
return false;
}
void
nsFontWeightTextAttr::Format(const PRInt32& aValue, nsAString& aFormattedValue)
TextAttrsMgr::FontWeightTextAttr::
ExposeValue(nsIPersistentProperties* aAttributes, const PRInt32& aValue)
{
nsAutoString value;
value.AppendInt(aValue);
aFormattedValue = value;
nsAutoString formattedValue;
formattedValue.AppendInt(aValue);
nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::fontWeight, formattedValue);
}
PRInt32
nsFontWeightTextAttr::GetFontWeight(nsIFrame *aFrame)
TextAttrsMgr::FontWeightTextAttr::
GetFontWeight(nsIFrame* aFrame)
{
// nsFont::width isn't suitable here because it's necessary to expose real
// value of font weight (used font might not have some font weight values).
@ -664,3 +663,82 @@ nsFontWeightTextAttr::GetFontWeight(nsIFrame *aFrame)
return fontEntry->Weight();
#endif
}
////////////////////////////////////////////////////////////////////////////////
// TextDecorTextAttr
////////////////////////////////////////////////////////////////////////////////
TextAttrsMgr::TextDecorValue::
TextDecorValue(nsIFrame* aFrame)
{
const nsStyleTextReset* textReset = aFrame->GetStyleTextReset();
mStyle = textReset->GetDecorationStyle();
bool isForegroundColor = false;
textReset->GetDecorationColor(mColor, isForegroundColor);
if (isForegroundColor)
mColor = aFrame->GetStyleColor()->mColor;
mLine = textReset->mTextDecorationLine &
(NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE |
NS_STYLE_TEXT_DECORATION_LINE_LINE_THROUGH);
}
TextAttrsMgr::TextDecorTextAttr::
TextDecorTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame) :
TTextAttr<TextDecorValue>(!aFrame)
{
mRootNativeValue = TextDecorValue(aRootFrame);
mIsRootDefined = mRootNativeValue.IsDefined();
if (aFrame) {
mNativeValue = TextDecorValue(aFrame);
mIsDefined = mNativeValue.IsDefined();
}
}
bool
TextAttrsMgr::TextDecorTextAttr::
GetValueFor(nsIContent* aContent, TextDecorValue* aValue)
{
nsIFrame* frame = aContent->GetPrimaryFrame();
if (frame) {
*aValue = TextDecorValue(frame);
return aValue->IsDefined();
}
return false;
}
void
TextAttrsMgr::TextDecorTextAttr::
ExposeValue(nsIPersistentProperties* aAttributes, const TextDecorValue& aValue)
{
if (aValue.IsUnderline()) {
nsAutoString formattedStyle;
StyleInfo::FormatTextDecorationStyle(aValue.Style(), formattedStyle);
nsAccUtils::SetAccAttr(aAttributes,
nsGkAtoms::textUnderlineStyle,
formattedStyle);
nsAutoString formattedColor;
StyleInfo::FormatColor(aValue.Color(), formattedColor);
nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::textUnderlineColor,
formattedColor);
return;
}
if (aValue.IsLineThrough()) {
nsAutoString formattedStyle;
StyleInfo::FormatTextDecorationStyle(aValue.Style(), formattedStyle);
nsAccUtils::SetAccAttr(aAttributes,
nsGkAtoms::textLineThroughStyle,
formattedStyle);
nsAutoString formattedColor;
StyleInfo::FormatColor(aValue.Color(), formattedColor);
nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::textLineThroughColor,
formattedColor);
}
}

View File

@ -0,0 +1,443 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2007
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Alexander Surkov <surkov.alexander@gmail.com> (original author)
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsTextAttrs_h_
#define nsTextAttrs_h_
#include "nsIContent.h"
#include "nsIFrame.h"
#include "nsIPersistentProperties2.h"
#include "nsStyleConsts.h"
class nsHyperTextAccessible;
namespace mozilla {
namespace a11y {
/**
* Used to expose text attributes for the hyper text accessible (see
* nsHyperTextAccessible class).
*
* @note "invalid: spelling" text attribute is implemented entirely in
* nsHyperTextAccessible class.
*/
class TextAttrsMgr
{
public:
/**
* Constructor. Used to expose default text attributes.
*/
TextAttrsMgr(nsHyperTextAccessible* aHyperTextAcc) :
mHyperTextAcc(aHyperTextAcc), mIncludeDefAttrs(true),
mOffsetAcc(nsnull), mOffsetAccIdx(-1) { }
/**
* Constructor. Used to expose text attributes at the given offset.
*
* @param aHyperTextAcc [in] hyper text accessible text attributes are
* calculated for
* @param aIncludeDefAttrs [optional] indicates whether default text
* attributes should be included into list of exposed
* text attributes
* @param oOffsetAcc [optional] offset an accessible the text attributes
* should be calculated for
* @param oOffsetAccIdx [optional] index in parent of offset accessible
*/
TextAttrsMgr(nsHyperTextAccessible* aHyperTextAcc,
bool aIncludeDefAttrs,
nsAccessible* aOffsetAcc,
PRInt32 aOffsetAccIdx) :
mHyperTextAcc(aHyperTextAcc), mIncludeDefAttrs(aIncludeDefAttrs),
mOffsetAcc(aOffsetAcc), mOffsetAccIdx(aOffsetAccIdx) { }
/*
* Return text attributes and hyper text offsets where these attributes are
* applied. Offsets are calculated in the case of non default attributes.
*
* @note In the case of default attributes pointers on hyper text offsets
* must be skipped.
*
* @param aAttributes [in, out] text attributes list
* @param aStartHTOffset [out, optional] start hyper text offset
* @param aEndHTOffset [out, optional] end hyper text offset
*/
void GetAttributes(nsIPersistentProperties* aAttributes,
PRInt32* aStartHTOffset = nsnull,
PRInt32* aEndHTOffset = nsnull);
protected:
/**
* Calculates range (start and end offsets) of text where the text attributes
* are stretched. New offsets may be smaller if one of text attributes changes
* its value before or after the given offsets.
*
* @param aTextAttrArray [in] text attributes array
* @param aStartHTOffset [in, out] the start offset
* @param aEndHTOffset [in, out] the end offset
*/
class TextAttr;
void GetRange(const nsTArray<TextAttr*>& aTextAttrArray,
PRInt32* aStartHTOffset, PRInt32* aEndHTOffset);
private:
nsHyperTextAccessible* mHyperTextAcc;
bool mIncludeDefAttrs;
nsAccessible* mOffsetAcc;
PRInt32 mOffsetAccIdx;
protected:
/**
* Interface class of text attribute class implementations.
*/
class TextAttr
{
public:
/**
* Expose the text attribute to the given attribute set.
*
* @param aAttributes [in] the given attribute set
* @param aIncludeDefAttrValue [in] if true then attribute is exposed even
* if its value is the same as default one
*/
virtual void Expose(nsIPersistentProperties* aAttributes,
bool aIncludeDefAttrValue) = 0;
/**
* Return true if the text attribute value on the given element equals with
* predefined attribute value.
*/
virtual bool Equal(nsIContent* aElm) = 0;
};
/**
* Base class to work with text attributes. See derived classes below.
*/
template<class T>
class TTextAttr : public TextAttr
{
public:
TTextAttr(bool aGetRootValue) : mGetRootValue(aGetRootValue) {}
// ITextAttr
virtual void Expose(nsIPersistentProperties* aAttributes,
bool aIncludeDefAttrValue)
{
if (mGetRootValue) {
if (mIsRootDefined)
ExposeValue(aAttributes, mRootNativeValue);
return;
}
if (mIsDefined) {
if (aIncludeDefAttrValue || mRootNativeValue != mNativeValue)
ExposeValue(aAttributes, mNativeValue);
return;
}
if (aIncludeDefAttrValue && mIsRootDefined)
ExposeValue(aAttributes, mRootNativeValue);
}
virtual bool Equal(nsIContent* aElm)
{
T nativeValue;
bool isDefined = GetValueFor(aElm, &nativeValue);
if (!mIsDefined && !isDefined)
return true;
if (mIsDefined && isDefined)
return nativeValue == mNativeValue;
if (mIsDefined)
return mNativeValue == mRootNativeValue;
return nativeValue == mRootNativeValue;
}
protected:
// Expose the text attribute with the given value to attribute set.
virtual void ExposeValue(nsIPersistentProperties* aAttributes,
const T& aValue) = 0;
// Return native value for the given DOM element.
virtual bool GetValueFor(nsIContent* aElm, T* aValue) = 0;
// Indicates if root value should be exposed.
bool mGetRootValue;
// Native value and flag indicating if the value is defined (initialized in
// derived classes). Note, undefined native value means it is inherited
// from root.
T mNativeValue;
bool mIsDefined;
// Native root value and flag indicating if the value is defined (initialized
// in derived classes).
T mRootNativeValue;
bool mIsRootDefined;
};
/**
* Class is used for the work with 'language' text attribute.
*/
class LangTextAttr : public TTextAttr<nsString>
{
public:
LangTextAttr(nsHyperTextAccessible* aRoot, nsIContent* aRootElm,
nsIContent* aElm);
virtual ~LangTextAttr() { }
protected:
// TextAttr
virtual bool GetValueFor(nsIContent* aElm, nsString* aValue);
virtual void ExposeValue(nsIPersistentProperties* aAttributes,
const nsString& aValue);
private:
bool GetLang(nsIContent* aElm, nsAString& aLang);
nsCOMPtr<nsIContent> mRootContent;
};
/**
* 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.
*/
class BGColorTextAttr : public TTextAttr<nscolor>
{
public:
BGColorTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame);
virtual ~BGColorTextAttr() { }
protected:
// TextAttr
virtual bool GetValueFor(nsIContent* aElm, nscolor* aValue);
virtual void ExposeValue(nsIPersistentProperties* aAttributes,
const nscolor& aValue);
private:
bool GetColor(nsIFrame* aFrame, nscolor* aColor);
nsIFrame* mRootFrame;
};
/**
* Class is used for the work with 'color' text attribute.
*/
class ColorTextAttr : public TTextAttr<nscolor>
{
public:
ColorTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame);
virtual ~ColorTextAttr() { }
protected:
// TTextAttr
virtual bool GetValueFor(nsIContent* aElm, nscolor* aValue);
virtual void ExposeValue(nsIPersistentProperties* aAttributes,
const nscolor& aValue);
};
/**
* Class is used for the work with "font-family" text attribute.
*/
class FontFamilyTextAttr : public TTextAttr<nsString>
{
public:
FontFamilyTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame);
virtual ~FontFamilyTextAttr() { }
protected:
// TTextAttr
virtual bool GetValueFor(nsIContent* aElm, nsString* aValue);
virtual void ExposeValue(nsIPersistentProperties* aAttributes,
const nsString& aValue);
private:
bool GetFontFamily(nsIFrame* aFrame, nsString& aFamily);
};
/**
* Class is used for the work with "font-size" text attribute.
*/
class FontSizeTextAttr : public TTextAttr<nscoord>
{
public:
FontSizeTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame);
virtual ~FontSizeTextAttr() { }
protected:
// TTextAttr
virtual bool GetValueFor(nsIContent* aElm, nscoord* aValue);
virtual void ExposeValue(nsIPersistentProperties* aAttributes,
const nscoord& aValue);
private:
nsDeviceContext* mDC;
};
/**
* Class is used for the work with "font-style" text attribute.
*/
class FontStyleTextAttr : public TTextAttr<nscoord>
{
public:
FontStyleTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame);
virtual ~FontStyleTextAttr() { }
protected:
// TTextAttr
virtual bool GetValueFor(nsIContent* aContent, nscoord* aValue);
virtual void ExposeValue(nsIPersistentProperties* aAttributes,
const nscoord& aValue);
};
/**
* Class is used for the work with "font-weight" text attribute.
*/
class FontWeightTextAttr : public TTextAttr<PRInt32>
{
public:
FontWeightTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame);
virtual ~FontWeightTextAttr() { }
protected:
// TTextAttr
virtual bool GetValueFor(nsIContent* aElm, PRInt32* aValue);
virtual void ExposeValue(nsIPersistentProperties* aAttributes,
const PRInt32& aValue);
private:
PRInt32 GetFontWeight(nsIFrame* aFrame);
};
/**
* TextDecorTextAttr class is used for the work with
* "text-line-through-style", "text-line-through-color",
* "text-underline-style" and "text-underline-color" text attributes.
*/
class TextDecorValue
{
public:
TextDecorValue() { }
TextDecorValue(nsIFrame* aFrame);
nscolor Color() const { return mColor; }
PRUint8 Style() const { return mStyle; }
bool IsDefined() const
{ return IsUnderline() || IsLineThrough(); }
bool IsUnderline() const
{ return mLine & NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE; }
bool IsLineThrough() const
{ return mLine & NS_STYLE_TEXT_DECORATION_LINE_LINE_THROUGH; }
bool operator ==(const TextDecorValue& aValue)
{
return mColor == aValue.mColor && mLine == aValue.mLine &&
mStyle == aValue.mStyle;
}
bool operator !=(const TextDecorValue& aValue)
{ return !(*this == aValue); }
private:
nscolor mColor;
PRUint8 mLine;
PRUint8 mStyle;
};
class TextDecorTextAttr : public TTextAttr<TextDecorValue>
{
public:
TextDecorTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame);
virtual ~TextDecorTextAttr() { }
protected:
// TextAttr
virtual bool GetValueFor(nsIContent* aElm, TextDecorValue* aValue);
virtual void ExposeValue(nsIPersistentProperties* aAttributes,
const TextDecorValue& aValue);
};
}; // TextAttrMgr
} // namespace a11y
} // namespace mozilla
#endif

View File

@ -1450,6 +1450,23 @@ nsAccessible::GetAttributesInternal(nsIPersistentProperties *aAttributes)
if (!mContent->IsElement())
return NS_OK;
// Expose draggable object attribute?
nsCOMPtr<nsIDOMHTMLElement> htmlElement = do_QueryInterface(mContent);
if (htmlElement) {
bool draggable = false;
htmlElement->GetDraggable(&draggable);
if (draggable) {
nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::draggable,
NS_LITERAL_STRING("true"));
}
}
// Don't calculate CSS-based object attributes when no frame (i.e.
// the accessible is not unattached form three) or when the accessible is not
// primary for node (like list bullet or XUL tree items).
if (!mContent->GetPrimaryFrame() || !IsPrimaryForNode())
return NS_OK;
// CSS style based object attributes.
nsAutoString value;
StyleInfo styleInfo(mContent->AsElement(), mDoc->PresShell());
@ -1482,17 +1499,6 @@ nsAccessible::GetAttributesInternal(nsIPersistentProperties *aAttributes)
styleInfo.MarginBottom(value);
nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::marginBottom, value);
// Expose draggable object attribute?
nsCOMPtr<nsIDOMHTMLElement> htmlElement = do_QueryInterface(mContent);
if (htmlElement) {
bool draggable = false;
htmlElement->GetDraggable(&draggable);
if (draggable) {
nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::draggable,
NS_LITERAL_STRING("true"));
}
}
return NS_OK;
}

View File

@ -923,7 +923,8 @@ nsDocAccessible::OnPivotChanged(nsIAccessiblePivot* aPivot,
nsIAccessible* aOldAccessible,
PRInt32 aOldStart, PRInt32 aOldEnd)
{
nsRefPtr<AccEvent> event = new AccEvent(nsIAccessibleEvent::EVENT_VIRTUALCURSOR_CHANGED, this);
nsRefPtr<AccEvent> event = new AccVCChangeEvent(this, aOldAccessible,
aOldStart, aOldEnd);
nsEventShell::FireEvent(event);
return NS_OK;

View File

@ -1,426 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2007
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Alexander Surkov <surkov.alexander@gmail.com> (original author)
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsTextAttrs_h_
#define nsTextAttrs_h_
class nsHyperTextAccessible;
#include "nsIContent.h"
#include "nsIFrame.h"
#include "nsIPersistentProperties2.h"
class nsITextAttr;
/**
* Used to expose text attributes for the hyper text accessible (see
* nsHyperTextAccessible class). It is indended for the work with 'language' and
* CSS based text attributes.
*
* @note "invalid: spelling" text attrbiute is implemented entirerly in
* nsHyperTextAccessible class.
*/
class nsTextAttrsMgr
{
public:
/**
* Constructor. If instance of the class is intended to expose default text
* attributes then 'aIncludeDefAttrs' and 'aOffsetNode' argument must be
* skiped.
*
* @param aHyperTextAcc hyper text accessible text attributes are
* calculated for
* @param aHyperTextNode DOM node of the given hyper text accessbile
* @param aIncludeDefAttrs [optional] indicates whether default text
* attributes should be included into list of exposed
* text attributes.
* @param oOffsetNode [optional] DOM node represents hyper text offset
* inside hyper text accessible
*/
nsTextAttrsMgr(nsHyperTextAccessible *aHyperTextAcc,
bool aIncludeDefAttrs = true,
nsAccessible *aOffsetAcc = nsnull,
PRInt32 aOffsetAccIdx = -1);
/*
* Return text attributes and hyper text offsets where these attributes are
* applied. Offsets are calculated in the case of non default attributes.
*
* @note In the case of default attributes pointers on hyper text offsets
* must be skiped.
*
* @param aAttributes [in, out] text attributes list
* @param aStartHTOffset [out, optional] start hyper text offset
* @param aEndHTOffset [out, optional] end hyper text offset
*/
nsresult GetAttributes(nsIPersistentProperties *aAttributes,
PRInt32 *aStartHTOffset = nsnull,
PRInt32 *aEndHTOffset = nsnull);
protected:
/**
* Calculates range (start and end offsets) of text where the text attributes
* are stretched. New offsets may be smaller if one of text attributes changes
* its value before or after the given offsets.
*
* @param aTextAttrArray [in] text attributes array
* @param aStartHTOffset [in, out] the start offset
* @param aEndHTOffset [in, out] the end offset
*/
nsresult GetRange(const nsTArray<nsITextAttr*>& aTextAttrArray,
PRInt32 *aStartHTOffset, PRInt32 *aEndHTOffset);
private:
nsRefPtr<nsHyperTextAccessible> mHyperTextAcc;
bool mIncludeDefAttrs;
nsRefPtr<nsAccessible> mOffsetAcc;
PRInt32 mOffsetAccIdx;
};
////////////////////////////////////////////////////////////////////////////////
// Private implementation details
/**
* Interface class of text attribute class implementations.
*/
class nsITextAttr
{
public:
/**
* Return the name of text attribute.
*/
virtual nsIAtom* GetName() const = 0;
/**
* Retrieve the value of text attribute in out param, return true if differs
* from the default value of text attribute or if include default attribute
* value flag is setted.
*
* @param aValue [in, out] the value of text attribute
* @param aIncludeDefAttrValue [in] include default attribute value flag
* @return true if text attribute value differs from
* default or include default attribute value
* flag is applied
*/
virtual bool GetValue(nsAString& aValue, bool aIncludeDefAttrValue) = 0;
/**
* Return true if the text attribute value on the given element equals with
* predefined attribute value.
*/
virtual bool Equal(nsIContent *aContent) = 0;
};
/**
* Base class to work with text attributes. See derived classes below.
*/
template<class T>
class nsTextAttr : public nsITextAttr
{
public:
nsTextAttr(bool aGetRootValue) : mGetRootValue(aGetRootValue) {}
// nsITextAttr
virtual bool GetValue(nsAString& aValue, bool aIncludeDefAttrValue)
{
if (mGetRootValue) {
Format(mRootNativeValue, aValue);
return mIsRootDefined;
}
bool isDefined = mIsDefined;
T* nativeValue = &mNativeValue;
if (!isDefined) {
if (aIncludeDefAttrValue) {
isDefined = mIsRootDefined;
nativeValue = &mRootNativeValue;
}
} else if (!aIncludeDefAttrValue) {
isDefined = mRootNativeValue != mNativeValue;
}
if (!isDefined)
return false;
Format(*nativeValue, aValue);
return true;
}
virtual bool Equal(nsIContent *aContent)
{
T nativeValue;
bool isDefined = GetValueFor(aContent, &nativeValue);
if (!mIsDefined && !isDefined)
return true;
if (mIsDefined && isDefined)
return nativeValue == mNativeValue;
if (mIsDefined)
return mNativeValue == mRootNativeValue;
return nativeValue == mRootNativeValue;
}
protected:
// Return native value for the given DOM element.
virtual bool GetValueFor(nsIContent *aContent, T *aValue) = 0;
// Format native value to text attribute value.
virtual void Format(const T& aValue, nsAString& aFormattedValue) = 0;
// Indicates if root value should be exposed.
bool mGetRootValue;
// Native value and flag indicating if the value is defined (initialized in
// derived classes). Note, undefined native value means it is inherited
// from root.
T mNativeValue;
bool mIsDefined;
// Native root value and flag indicating if the value is defined (initialized
// in derived classes).
T mRootNativeValue;
bool mIsRootDefined;
};
/**
* Class is used for the work with 'language' text attribute in nsTextAttrsMgr
* class.
*/
class nsLangTextAttr : public nsTextAttr<nsAutoString>
{
public:
nsLangTextAttr(nsHyperTextAccessible *aRootAcc, nsIContent *aRootContent,
nsIContent *aContent);
// nsITextAttr
virtual nsIAtom *GetName() const { return nsGkAtoms::language; }
protected:
// nsTextAttr
virtual bool GetValueFor(nsIContent *aElm, nsAutoString *aValue);
virtual void Format(const nsAutoString& aValue, nsAString& aFormattedValue);
private:
bool GetLang(nsIContent *aContent, nsAString& aLang);
nsCOMPtr<nsIContent> mRootContent;
};
/**
* Class is used for the work with CSS based text attributes in nsTextAttrsMgr
* class.
*/
class nsCSSTextAttr : public nsTextAttr<nsAutoString>
{
public:
nsCSSTextAttr(PRUint32 aIndex, nsIContent *aRootContent,
nsIContent *aContent);
// nsITextAttr
virtual nsIAtom *GetName() const;
protected:
// nsTextAttr
virtual bool GetValueFor(nsIContent *aContent, nsAutoString *aValue);
virtual void Format(const nsAutoString& aValue, nsAString& aFormattedValue);
private:
PRInt32 mIndex;
};
/**
* Class is used for the work with 'background-color' text attribute in
* nsTextAttrsMgr class.
*/
class nsBGColorTextAttr : public nsTextAttr<nscolor>
{
public:
nsBGColorTextAttr(nsIFrame *aRootFrame, nsIFrame *aFrame);
// nsITextAttr
virtual nsIAtom *GetName() const { return nsGkAtoms::backgroundColor; }
protected:
// nsTextAttr
virtual bool GetValueFor(nsIContent *aContent, nscolor *aValue);
virtual void Format(const nscolor& aValue, nsAString& aFormattedValue);
private:
bool GetColor(nsIFrame *aFrame, nscolor *aColor);
nsIFrame *mRootFrame;
};
/**
* Class is used for the work with 'color' text attribute in nsTextAttrsMgr
* class.
*/
class ColorTextAttr : public nsTextAttr<nscolor>
{
public:
ColorTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame);
// nsITextAttr
virtual nsIAtom* GetName() const { return nsGkAtoms::color; }
protected:
// nsTextAttr
virtual bool GetValueFor(nsIContent* aContent, nscolor* aValue);
virtual void Format(const nscolor& aValue, nsAString& aFormattedValue);
};
/**
* Class is used for the work with "font-family" text attribute in
* nsTextAttrsMgr class.
*/
class FontFamilyTextAttr : public nsTextAttr<nsAutoString>
{
public:
FontFamilyTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame);
// nsITextAttr
virtual nsIAtom* GetName() const { return nsGkAtoms::font_family; }
protected:
// nsTextAttr
virtual bool GetValueFor(nsIContent* aContent, nsAutoString* aValue);
virtual void Format(const nsAutoString& aValue, nsAString& aFormattedValue);
private:
bool GetFontFamily(nsIFrame* aFrame, nsAutoString& aFamily);
};
/**
* Class is used for the work with "font-size" text attribute in nsTextAttrsMgr
* class.
*/
class nsFontSizeTextAttr : public nsTextAttr<nscoord>
{
public:
nsFontSizeTextAttr(nsIFrame *aRootFrame, nsIFrame *aFrame);
// nsITextAttr
virtual nsIAtom *GetName() const { return nsGkAtoms::font_size; }
protected:
// nsTextAttr
virtual bool GetValueFor(nsIContent *aContent, nscoord *aValue);
virtual void Format(const nscoord& aValue, nsAString& aFormattedValue);
private:
/**
* Return font size for the given frame.
*
* @param aFrame [in] the given frame to query font-size
* @return font size
*/
nscoord GetFontSize(nsIFrame *aFrame);
nsDeviceContext *mDC;
};
/**
* Class is used for the work with "font-style" text attribute in nsTextAttrsMgr
* class.
*/
class FontStyleTextAttr : public nsTextAttr<nscoord>
{
public:
FontStyleTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame);
// nsITextAttr
virtual nsIAtom* GetName() const { return nsGkAtoms::font_style; }
protected:
// nsTextAttr
virtual bool GetValueFor(nsIContent* aContent, nscoord* aValue);
virtual void Format(const nscoord &aValue, nsAString &aFormattedValue);
};
/**
* Class is used for the work with "font-weight" text attribute in
* nsTextAttrsMgr class.
*/
class nsFontWeightTextAttr : public nsTextAttr<PRInt32>
{
public:
nsFontWeightTextAttr(nsIFrame *aRootFrame, nsIFrame *aFrame);
// nsITextAttr
virtual nsIAtom *GetName() const { return nsGkAtoms::fontWeight; }
protected:
// nsTextAttr
virtual bool GetValueFor(nsIContent *aElm, PRInt32 *aValue);
virtual void Format(const PRInt32& aValue, nsAString& aFormattedValue);
private:
/**
* Return font weight for the given frame.
*
* @param aFrame [in] the given frame to query font weight
* @return font weight
*/
PRInt32 GetFontWeight(nsIFrame *aFrame);
};
#endif

View File

@ -42,9 +42,9 @@
#include "nsAccessibilityService.h"
#include "nsAccUtils.h"
#include "nsDocAccessible.h"
#include "nsTextAttrs.h"
#include "Role.h"
#include "States.h"
#include "TextAttrs.h"
#include "nsIClipboard.h"
#include "nsContentUtils.h"
@ -1130,8 +1130,8 @@ nsHyperTextAccessible::GetTextAttributes(bool aIncludeDefAttrs,
// default attributes if they were requested, otherwise return empty set.
if (aOffset == 0) {
if (aIncludeDefAttrs) {
nsTextAttrsMgr textAttrsMgr(this, true, nsnull, -1);
return textAttrsMgr.GetAttributes(*aAttributes);
TextAttrsMgr textAttrsMgr(this);
textAttrsMgr.GetAttributes(*aAttributes);
}
return NS_OK;
}
@ -1143,11 +1143,9 @@ nsHyperTextAccessible::GetTextAttributes(bool aIncludeDefAttrs,
PRInt32 endOffset = GetChildOffset(accAtOffsetIdx + 1);
PRInt32 offsetInAcc = aOffset - startOffset;
nsTextAttrsMgr textAttrsMgr(this, aIncludeDefAttrs, accAtOffset,
accAtOffsetIdx);
nsresult rv = textAttrsMgr.GetAttributes(*aAttributes, &startOffset,
&endOffset);
NS_ENSURE_SUCCESS(rv, rv);
TextAttrsMgr textAttrsMgr(this, aIncludeDefAttrs, accAtOffset,
accAtOffsetIdx);
textAttrsMgr.GetAttributes(*aAttributes, &startOffset, &endOffset);
// Compute spelling attributes on text accessible only.
nsIFrame *offsetFrame = accAtOffset->GetFrame();
@ -1186,8 +1184,9 @@ nsHyperTextAccessible::GetDefaultTextAttributes(nsIPersistentProperties **aAttri
NS_ADDREF(*aAttributes = attributes);
nsTextAttrsMgr textAttrsMgr(this, true);
return textAttrsMgr.GetAttributes(*aAttributes);
TextAttrsMgr textAttrsMgr(this);
textAttrsMgr.GetAttributes(*aAttributes);
return NS_OK;
}
PRInt32

View File

@ -253,3 +253,40 @@ nsAccTableChangeEvent::GetNumRowsOrCols(PRInt32* aNumRowsOrCols)
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
// nsAccVirtualCursorChangeEvent
////////////////////////////////////////////////////////////////////////////////
NS_IMPL_ISUPPORTS_INHERITED1(nsAccVirtualCursorChangeEvent, nsAccEvent,
nsIAccessibleVirtualCursorChangeEvent)
NS_IMETHODIMP
nsAccVirtualCursorChangeEvent::GetOldAccessible(nsIAccessible** aOldAccessible)
{
NS_ENSURE_ARG_POINTER(aOldAccessible);
*aOldAccessible =
static_cast<AccVCChangeEvent*>(mEvent.get())->OldAccessible();
NS_IF_ADDREF(*aOldAccessible);
return NS_OK;
}
NS_IMETHODIMP
nsAccVirtualCursorChangeEvent::GetOldStartOffset(PRInt32* aOldStartOffset)
{
NS_ENSURE_ARG_POINTER(aOldStartOffset);
*aOldStartOffset =
static_cast<AccVCChangeEvent*>(mEvent.get())->OldStartOffset();
return NS_OK;
}
NS_IMETHODIMP
nsAccVirtualCursorChangeEvent::GetOldEndOffset(PRInt32* aOldEndOffset)
{
NS_ENSURE_ARG_POINTER(aOldEndOffset);
*aOldEndOffset =
static_cast<AccVCChangeEvent*>(mEvent.get())->OldEndOffset();
return NS_OK;
}

View File

@ -164,5 +164,25 @@ private:
nsAccTableChangeEvent& operator =(const nsAccTableChangeEvent&);
};
/**
* Accessible virtual cursor change event.
*/
class nsAccVirtualCursorChangeEvent : public nsAccEvent,
public nsIAccessibleVirtualCursorChangeEvent
{
public:
nsAccVirtualCursorChangeEvent(AccVCChangeEvent* aEvent) :
nsAccEvent(aEvent) { }
virtual ~nsAccVirtualCursorChangeEvent() { }
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIACCESSIBLEVIRTUALCURSORCHANGEEVENT
private:
nsAccVirtualCursorChangeEvent() MOZ_DELETE;
nsAccVirtualCursorChangeEvent(const nsAccVirtualCursorChangeEvent&) MOZ_DELETE;
nsAccVirtualCursorChangeEvent& operator =(const nsAccVirtualCursorChangeEvent&) MOZ_DELETE;
};
#endif

View File

@ -47,6 +47,23 @@ function testCSSAttrs(aID)
testAttrs(aID, attrs, true);
}
/**
* Test the accessible that it doesn't have CSS-based object attributes.
*/
function testAbsentCSSAttrs(aID)
{
var attrs = {
"display": "",
"text-align": "",
"text-indent": "",
"margin-left": "",
"margin-right": "",
"margin-top": "",
"margin-bottom": ""
};
testAbsentAttrs(aID, attrs);
}
/**
* Test group object attributes (posinset, setsize and level) and
* nsIAccessible::groupPosition() method.

View File

@ -82,6 +82,9 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=689540
testCSSAttrs("tr");
testCSSAttrs("td");
// no CSS-based object attributes
testAbsentCSSAttrs(getAccessible("listitem").firstChild);
SimpleTest.finish();
}
@ -111,6 +114,11 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=689540
title="Don't use GetComputedStyle for object attribute calculation">
Mozilla Bug 714579
</a>
<a target="_blank"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=729831"
title="Don't expose CSS-based object attributes on not in tree accessible and accessible having no DOM element">
Mozilla Bug 729831
</a>
<p id="display"></p>
<div id="content" style="display: none"></div>
@ -189,5 +197,9 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=689540
<td id="td">td</td>
</tr>
</table>
<ul>
<li id="listitem">item
</ul>
</body>
</html>

View File

@ -269,13 +269,19 @@
attrs = {};
testTextAttrs(ID, 84, attrs, defAttrs, 83, 91);
attrs = { "text-underline-style": "solid" };
attrs = {
"text-underline-style": "solid",
"text-underline-color": gComputedStyle.color
};
testTextAttrs(ID, 92, attrs, defAttrs, 91, 101);
attrs = {};
testTextAttrs(ID, 102, attrs, defAttrs, 101, 109);
attrs = { "text-line-through-style": "solid" };
attrs = {
"text-line-through-style": "solid",
"text-line-through-color": gComputedStyle.color
};
testTextAttrs(ID, 110, attrs, defAttrs, 109, 122);
attrs = {};
@ -323,13 +329,19 @@
attrs = {};
testTextAttrs(ID, 85, attrs, defAttrs, 84, 92);
attrs = { "text-underline-style": "solid" };
attrs = {
"text-underline-style": "solid",
"text-underline-color": gComputedStyle.color
};
testTextAttrs(ID, 93, attrs, defAttrs, 92, 102);
attrs = {};
testTextAttrs(ID, 103, attrs, defAttrs, 102, 110);
attrs = { "text-line-through-style": "solid" };
attrs = {
"text-line-through-style": "solid",
"text-line-through-color": gComputedStyle.color
};
testTextAttrs(ID, 111, attrs, defAttrs, 110, 123);
attrs = {};
@ -437,6 +449,48 @@
attrs = { };
testTextAttrs(ID, 31, attrs, defAttrs, 31, 45);
//////////////////////////////////////////////////////////////////////////
// area17, "text-decoration" tests
ID = "area17";
defAttrs = buildDefaultTextAttrs(ID, "12pt");
testDefaultTextAttrs(ID, defAttrs);
attrs = {
"text-underline-style": "solid",
"text-underline-color": "rgb(0, 0, 0)",
};
testTextAttrs(ID, 0, attrs, defAttrs, 0, 10);
attrs = {
"text-underline-style": "solid",
"text-underline-color": "rgb(0, 0, 255)",
};
testTextAttrs(ID, 10, attrs, defAttrs, 10, 15);
attrs = {
"text-underline-style": "dotted",
"text-underline-color": "rgb(0, 0, 0)",
};
testTextAttrs(ID, 15, attrs, defAttrs, 15, 22);
attrs = {
"text-line-through-style": "solid",
"text-line-through-color": "rgb(0, 0, 0)",
};
testTextAttrs(ID, 22, attrs, defAttrs, 22, 34);
attrs = {
"text-line-through-style": "solid",
"text-line-through-color": "rgb(0, 0, 255)",
};
testTextAttrs(ID, 34, attrs, defAttrs, 34, 39);
attrs = {
"text-line-through-style": "wavy",
"text-line-through-color": "rgb(0, 0, 0)",
};
testTextAttrs(ID, 39, attrs, defAttrs, 39, 44);
SimpleTest.finish();
}
@ -450,12 +504,17 @@
href="https://bugzilla.mozilla.org/show_bug.cgi?id=345759"
title="Implement text attributes">
Mozilla Bug 345759
</a><br>
</a>
<a target="_blank"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=473576"
title="font-family text attribute should expose actual font used">
Mozilla Bug 473576
</a>
<a target="_blank"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=523304"
title="expose text-underline-color and text-line-through-color text attributes">
Mozilla Bug 523304
</a>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
@ -546,5 +605,15 @@
<span style="font-family: Comic Sans MS, cursive;">text</span>text
<span style="font-family: sans-serif, fantasy;">text</span>text
</p>
<p id="area17">
<span style="-moz-text-decoration-line: underline;">underline
</span><span style="text-decoration: underline; -moz-text-decoration-color: blue;">blue
</span><span style="text-decoration: underline; -moz-text-decoration-style: dotted;">dotted
</span><span style="-moz-text-decoration-line: line-through;">linethrough
</span><span style="text-decoration: line-through; -moz-text-decoration-color: blue;">blue
</span><span style="text-decoration: line-through; -moz-text-decoration-style: wavy;">wavy
</span>
</p>
</body>
</html>

View File

@ -10,6 +10,8 @@ const nsIAccessibleCaretMoveEvent =
Components.interfaces.nsIAccessibleCaretMoveEvent;
const nsIAccessibleTextChangeEvent =
Components.interfaces.nsIAccessibleTextChangeEvent;
const nsIAccessibleVirtualCursorChangeEvent =
Components.interfaces.nsIAccessibleVirtualCursorChangeEvent;
const nsIAccessibleStates = Components.interfaces.nsIAccessibleStates;
const nsIAccessibleRole = Components.interfaces.nsIAccessibleRole;

View File

@ -74,6 +74,15 @@ function virtualCursorChangedChecker(aDocAcc, aIdOrNameOrAcc, aTextOffsets)
this.check = function virtualCursorChangedChecker_check(aEvent)
{
SimpleTest.info("virtualCursorChangedChecker_check");
var event = null;
try {
event = aEvent.QueryInterface(nsIAccessibleVirtualCursorChangeEvent);
} catch (e) {
SimpleTest.ok(false, "Does not support correct interface: " + e);
}
var position = aDocAcc.virtualCursor.position;
var idMatches = position.DOMNode.id == aIdOrNameOrAcc;
@ -90,9 +99,38 @@ function virtualCursorChangedChecker(aDocAcc, aIdOrNameOrAcc, aTextOffsets)
SimpleTest.is(aDocAcc.virtualCursor.endOffset, aTextOffsets[1],
"wrong end offset");
}
var prevPosAndOffset = virtualCursorChangedChecker.
getPreviousPosAndOffset(aDocAcc.virtualCursor);
if (prevPosAndOffset) {
SimpleTest.is(event.oldAccessible, prevPosAndOffset.position,
"previous position does not match");
SimpleTest.is(event.oldStartOffset, prevPosAndOffset.startOffset,
"previous start offset does not match");
SimpleTest.is(event.oldEndOffset, prevPosAndOffset.endOffset,
"previous end offset does not match");
}
};
}
virtualCursorChangedChecker.prevPosAndOffset = {};
virtualCursorChangedChecker.storePreviousPosAndOffset =
function storePreviousPosAndOffset(aPivot)
{
virtualCursorChangedChecker.prevPosAndOffset[aPivot] =
{position: aPivot.position,
startOffset: aPivot.startOffset,
endOffset: aPivot.endOffset};
};
virtualCursorChangedChecker.getPreviousPosAndOffset =
function getPreviousPosAndOffset(aPivot)
{
return virtualCursorChangedChecker.prevPosAndOffset[aPivot];
};
/**
* Set a text range in the pivot and wait for virtual cursor change event.
*
@ -105,6 +143,8 @@ function setVirtualCursorRangeInvoker(aDocAcc, aTextAccessible, aTextOffsets)
{
this.invoke = function virtualCursorChangedInvoker_invoke()
{
virtualCursorChangedChecker.
storePreviousPosAndOffset(aDocAcc.virtualCursor);
SimpleTest.info(prettyName(aTextAccessible) + " " + aTextOffsets);
aDocAcc.virtualCursor.setTextRange(aTextAccessible,
aTextOffsets[0],
@ -136,6 +176,8 @@ function setVirtualCursorPosInvoker(aDocAcc, aPivotMoveMethod, aRule,
{
this.invoke = function virtualCursorChangedInvoker_invoke()
{
virtualCursorChangedChecker.
storePreviousPosAndOffset(aDocAcc.virtualCursor);
var moved = aDocAcc.virtualCursor[aPivotMoveMethod](aRule);
SimpleTest.ok((aIdOrNameOrAcc && moved) || (!aIdOrNameOrAcc && !moved),
"moved pivot");

View File

@ -1,5 +1,5 @@
<?xml version="1.0"?>
<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist" lastupdate="1330367012000">
<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist" lastupdate="1331241604000">
<emItems>
<emItem blockID="i58" id="webmaster@buzzzzvideos.info">
<versionRange minVersion="0" maxVersion="*">
@ -19,18 +19,6 @@
</emItem>
<emItem blockID="i43" id="supportaccessplugin@gmail.com">
</emItem>
<emItem blockID="i38" id="{B7082FAA-CB62-4872-9106-E42DD88EDE45}">
<versionRange minVersion="0.1" maxVersion="3.3.0.*">
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
<versionRange minVersion="3.7a1" maxVersion="*" />
</targetApplication>
</versionRange>
<versionRange minVersion="3.3.1" maxVersion="*">
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
<versionRange minVersion="5.0a1" maxVersion="*" />
</targetApplication>
</versionRange>
</emItem>
<emItem blockID="i65" id="activity@facebook.com">
<versionRange minVersion="0" maxVersion="*">
</versionRange>
@ -63,18 +51,6 @@
</emItem>
<emItem blockID="i10" id="{8CE11043-9A15-4207-A565-0C94C42D590D}">
</emItem>
<emItem blockID="i1" id="mozilla_cc@internetdownloadmanager.com">
<versionRange minVersion="2.1" maxVersion="3.3">
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
<versionRange minVersion="3.0a1" maxVersion="*" />
</targetApplication>
</versionRange>
<versionRange minVersion=" " maxVersion="6.9.8">
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
<versionRange minVersion="3.7a1pre" maxVersion="*" />
</targetApplication>
</versionRange>
</emItem>
<emItem blockID="i63" id="youtube@youtuber.com">
<versionRange minVersion="0" maxVersion="*">
</versionRange>
@ -89,18 +65,8 @@
<versionRange minVersion="0" maxVersion="*">
</versionRange>
</emItem>
<emItem blockID="i4" id="{4B3803EA-5230-4DC3-A7FC-33638F3D3542}">
<versionRange minVersion="1.2" maxVersion="1.2">
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
<versionRange minVersion="3.0a1" maxVersion="*" />
</targetApplication>
</versionRange>
</emItem>
<emItem blockID="i50" id="firebug@software.joehewitt.com">
<versionRange minVersion="0" maxVersion="0">
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
<versionRange minVersion="9.0a1" maxVersion="9.*" />
</targetApplication>
<emItem blockID="i72" id="{4ED1F68A-5463-4931-9384-8FFF5ED91D92}">
<versionRange minVersion="0" maxVersion="3.4.1.194" severity="1">
</versionRange>
</emItem>
<emItem blockID="i40" id="{28387537-e3f9-4ed7-860c-11e69af4a8a0}">
@ -121,13 +87,6 @@
</emItem>
<emItem blockID="i7" id="{2224e955-00e9-4613-a844-ce69fccaae91}">
</emItem>
<emItem blockID="i46" id="{841468a1-d7f4-4bd3-84e6-bb0f13a06c64}">
<versionRange minVersion="0.1" maxVersion="*">
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
<versionRange minVersion="9.0a1" maxVersion="9.0" />
</targetApplication>
</versionRange>
</emItem>
<emItem blockID="i67" id="youtube2@youtube2.com">
<versionRange minVersion="0" maxVersion="*">
</versionRange>
@ -136,35 +95,18 @@
<versionRange minVersion="0" maxVersion="*">
</versionRange>
</emItem>
<emItem blockID="i23" id="firefox@bandoo.com">
<versionRange minVersion="5.0" maxVersion="5.0" severity="1">
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
<versionRange minVersion="3.7a1pre" maxVersion="*" />
</targetApplication>
<emItem blockID="i56" id="flash@adobe.com">
<versionRange minVersion="0" maxVersion="*">
</versionRange>
</emItem>
<emItem blockID="i55" id="youtube@youtube7.com">
<versionRange minVersion="0" maxVersion="*">
</versionRange>
</emItem>
<emItem blockID="i11" id="yslow@yahoo-inc.com">
<versionRange minVersion="2.0.5" maxVersion="2.0.5">
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
<versionRange minVersion="3.5.7" maxVersion="*" />
</targetApplication>
</versionRange>
</emItem>
<emItem blockID="i22" id="ShopperReports@ShopperReports.com">
<versionRange minVersion="3.1.22.0" maxVersion="3.1.22.0">
</versionRange>
</emItem>
<emItem blockID="i2" id="fdm_ffext@freedownloadmanager.org">
<versionRange minVersion="1.0" maxVersion="1.3.1">
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
<versionRange minVersion="3.0a1" maxVersion="*" />
</targetApplication>
</versionRange>
</emItem>
<emItem blockID="i44" id="sigma@labs.mozilla">
</emItem>
<emItem blockID="i5" id="support@daemon-tools.cc">
@ -203,17 +145,6 @@
<versionRange minVersion="2.2" maxVersion="2.2">
</versionRange>
</emItem>
<emItem blockID="i56" id="flash@adobe.com">
<versionRange minVersion="0" maxVersion="*">
</versionRange>
</emItem>
<emItem blockID="i45" id="{22119944-ED35-4ab1-910B-E619EA06A115}">
<versionRange minVersion="0.1" maxVersion="7.6.1">
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
<versionRange minVersion="8.0a1" maxVersion="*" />
</targetApplication>
</versionRange>
</emItem>
<emItem blockID="i19" id="{46551EC9-40F0-4e47-8E18-8E5CF550CFB8}">
<versionRange minVersion="1.1b1" maxVersion="1.1b1">
</versionRange>
@ -230,39 +161,11 @@
<versionRange minVersion="0" maxVersion="*">
</versionRange>
</emItem>
<emItem blockID="i24" id="{6E19037A-12E3-4295-8915-ED48BC341614}">
<versionRange minVersion="0.1" maxVersion="1.3.328.4" severity="1">
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
<versionRange minVersion="3.7a1pre" maxVersion="*" />
</targetApplication>
</versionRange>
</emItem>
<emItem blockID="i15" id="personas@christopher.beard">
<versionRange minVersion="1.6" maxVersion="1.6">
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
<versionRange minVersion="3.6" maxVersion="3.6.*" />
</targetApplication>
</versionRange>
</emItem>
<emItem blockID="i21" id="support@update-firefox.com">
</emItem>
</emItems>
<pluginItems>
<pluginItem blockID="p26">
<match name="name" exp="^Yahoo Application State Plugin$" /> <match name="description" exp="^Yahoo Application State Plugin$" /> <match name="filename" exp="npYState.dll" /> <versionRange >
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
<versionRange minVersion="3.0a1" maxVersion="3.*" />
</targetApplication>
</versionRange>
</pluginItem>
<pluginItem blockID="p27">
<match name="name" exp="QuickTime Plug-in 7[.]1[.]" /> <match name="filename" exp="npqtplugin.?[.]dll" /> <versionRange >
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
<versionRange minVersion="3.0a1" maxVersion="3.*" />
</targetApplication>
</versionRange>
</pluginItem>
<pluginItem blockID="p28">
<match name="filename" exp="NPFFAddOn.dll" /> <versionRange >
</versionRange>
@ -271,24 +174,10 @@
<match name="filename" exp="NPMySrch.dll" /> <versionRange >
</versionRange>
</pluginItem>
<pluginItem blockID="p32">
<match name="filename" exp="npViewpoint.dll" /> <versionRange >
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
<versionRange minVersion="3.0" maxVersion="*" />
</targetApplication>
</versionRange>
</pluginItem>
<pluginItem blockID="p33">
<match name="name" exp="[0-6]\.0\.[01]\d{2}\.\d+" /> <match name="filename" exp="npdeploytk.dll" /> <versionRange severity="1">
</versionRange>
</pluginItem>
<pluginItem blockID="p34">
<match name="filename" exp="[Nn][Pp][Jj][Pp][Ii]1[56]0_[0-9]+\.[Dd][Ll][Ll]" /> <versionRange >
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
<versionRange minVersion="3.6a1pre" maxVersion="*" />
</targetApplication>
</versionRange>
</pluginItem>
</pluginItems>
<gfxItems>

View File

@ -291,12 +291,12 @@
</menu>
<menu id="pageStyleMenu" label="&pageStyleMenu.label;"
accesskey="&pageStyleMenu.accesskey;" observes="isImage">
<menupopup onpopupshowing="stylesheetFillPopup(this);"
oncommand="stylesheetSwitchAll(window.content, event.target.getAttribute('data')); setStyleDisabled(false);">
<menupopup onpopupshowing="gPageStyleMenu.fillPopup(this);"
oncommand="gPageStyleMenu.switchStyleSheet(event.target.getAttribute('data'));">
<menuitem id="menu_pageStyleNoStyle"
label="&pageStyleNoStyle.label;"
accesskey="&pageStyleNoStyle.accesskey;"
oncommand="setStyleDisabled(true); event.stopPropagation();"
oncommand="gPageStyleMenu.disableStyle(); event.stopPropagation();"
type="radio"/>
<menuitem id="menu_pageStylePersistentOnly"
label="&pageStylePersistentOnly.label;"

View File

@ -5331,8 +5331,6 @@ function setToolbarVisibility(toolbar, isVisible) {
var TabsOnTop = {
init: function TabsOnTop_init() {
this._initialized = true;
this.syncUI();
Services.prefs.addObserver(this._prefName, this, false);
},
@ -5345,9 +5343,6 @@ var TabsOnTop = {
},
syncUI: function () {
if (!this._initialized)
return;
let userEnabled = Services.prefs.getBoolPref(this._prefName);
let enabled = userEnabled && gBrowser.tabContainer.visible;
@ -6097,23 +6092,23 @@ function charsetLoadListener(event) {
var gPageStyleMenu = {
getAllStyleSheets: function (frameset) {
_getAllStyleSheets: function (frameset) {
var styleSheetsArray = Array.slice(frameset.document.styleSheets);
for (let i = 0; i < frameset.frames.length; i++) {
let frameSheets = this.getAllStyleSheets(frameset.frames[i]);
let frameSheets = this._getAllStyleSheets(frameset.frames[i]);
styleSheetsArray = styleSheetsArray.concat(frameSheets);
}
return styleSheetsArray;
},
stylesheetFillPopup: function (menuPopup) {
fillPopup: function (menuPopup) {
var noStyle = menuPopup.firstChild;
var persistentOnly = noStyle.nextSibling;
var sep = persistentOnly.nextSibling;
while (sep.nextSibling)
menuPopup.removeChild(sep.nextSibling);
var styleSheets = this.getAllStyleSheets(window.content);
var styleSheets = this._getAllStyleSheets(window.content);
var currentStyleSheets = {};
var styleDisabled = getMarkupDocumentViewer().authorStyleDisabled;
var haveAltSheets = false;
@ -6161,12 +6156,12 @@ var gPageStyleMenu = {
return true;
},
stylesheetInFrame: function (frame, title) {
_stylesheetInFrame: function (frame, title) {
return Array.some(frame.document.styleSheets,
function (stylesheet) stylesheet.title == title);
},
stylesheetSwitchFrame: function (frame, title) {
_stylesheetSwitchFrame: function (frame, title) {
var docStyleSheets = frame.document.styleSheets;
for (let i = 0; i < docStyleSheets.length; ++i) {
@ -6181,26 +6176,34 @@ var gPageStyleMenu = {
}
},
stylesheetSwitchAll: function (frameset, title) {
if (!title || title == "_nostyle" || this.stylesheetInFrame(frameset, title))
this.stylesheetSwitchFrame(frameset, title);
_stylesheetSwitchAll: function (frameset, title) {
if (!title || title == "_nostyle" || this._stylesheetInFrame(frameset, title))
this._stylesheetSwitchFrame(frameset, title);
for (let i = 0; i < frameset.frames.length; i++)
this.stylesheetSwitchAll(frameset.frames[i], title);
this._stylesheetSwitchAll(frameset.frames[i], title);
},
setStyleDisabled: function (disabled) {
getMarkupDocumentViewer().authorStyleDisabled = disabled;
switchStyleSheet: function (title, contentWindow) {
getMarkupDocumentViewer().authorStyleDisabled = false;
this._stylesheetSwitchAll(contentWindow || content, title);
},
disableStyle: function () {
getMarkupDocumentViewer().authorStyleDisabled = true;
},
};
/* Legacy global page-style functions */
var getAllStyleSheets = gPageStyleMenu.getAllStyleSheets;
var stylesheetFillPopup = gPageStyleMenu.stylesheetFillPopup;
var stylesheetInFrame = gPageStyleMenu.stylesheetInFrame;
var stylesheetSwitchFrame = gPageStyleMenu.stylesheetSwitchFrame;
var stylesheetSwitchAll = gPageStyleMenu.stylesheetSwitchAll;
var setStyleDisabled = gPageStyleMenu.setStyleDisabled;
var getAllStyleSheets = gPageStyleMenu._getAllStyleSheets.bind(gPageStyleMenu);
var stylesheetFillPopup = gPageStyleMenu.fillPopup.bind(gPageStyleMenu);
function stylesheetSwitchAll(contentWindow, title) {
gPageStyleMenu.switchStyleSheet(title, contentWindow);
}
function setStyleDisabled(disabled) {
if (disabled)
gPageStyleMenu.disableStyle();
}
var BrowserOffline = {

0
browser/base/content/global-scripts.inc Normal file → Executable file
View File

View File

@ -2779,9 +2779,7 @@
Services.prefs.addObserver("browser.tabs.", this._prefObserver, false);
window.addEventListener("resize", this, false);
this.updateVisibility();
this._propagateVisibility();
window.addEventListener("load", this, false);
]]>
</constructor>
@ -2841,15 +2839,19 @@
this.parentNode && this.parentNode.localName == "toolbar" ? this.parentNode : this;
]]></field>
<field name="_propagatedVisibilityOnce">false</field>
<property name="visible"
onget="return !this._container.collapsed;">
<setter><![CDATA[
if (val == this.visible)
if (val == this.visible &&
this._propagatedVisibilityOnce)
return val;
this._container.collapsed = !val;
this._propagateVisibility();
this._propagatedVisibilityOnce = true;
return val;
]]></setter>
@ -3080,6 +3082,9 @@
<parameter name="aEvent"/>
<body><![CDATA[
switch (aEvent.type) {
case "load":
this.updateVisibility();
break;
case "resize":
if (aEvent.target != window)
break;

View File

@ -14,7 +14,7 @@ function test() {
function checkPageStyleMenu() {
var menupopup = document.getElementById("pageStyleMenu")
.getElementsByTagName("menupopup")[0];
stylesheetFillPopup(menupopup);
gPageStyleMenu.fillPopup(menupopup);
var items = [];
var current = menupopup.getElementsByTagName("menuseparator")[0];

View File

@ -64,6 +64,9 @@ XPCOMUtils.defineLazyGetter(this, "PlacesUtils", function() {
return PlacesUtils;
});
XPCOMUtils.defineLazyModuleGetter(this, "KeywordURLResetPrompter",
"resource:///modules/KeywordURLResetPrompter.jsm");
const PREF_PLUGINS_NOTIFYUSER = "plugins.update.notifyUser";
const PREF_PLUGINS_UPDATEURL = "plugins.update.url";
@ -277,6 +280,13 @@ BrowserGlue.prototype = {
this._initPlaces();
}
break;
case "defaultURIFixup-using-keyword-pref":
if (KeywordURLResetPrompter.shouldPrompt) {
let keywordURI = subject.QueryInterface(Ci.nsIURI);
KeywordURLResetPrompter.prompt(this.getMostRecentBrowserWindow(),
keywordURI);
}
break;
}
},
@ -306,6 +316,7 @@ BrowserGlue.prototype = {
os.addObserver(this, "distribution-customization-complete", false);
os.addObserver(this, "places-shutdown", false);
this._isPlacesShutdownObserver = true;
os.addObserver(this, "defaultURIFixup-using-keyword-pref", false);
},
// cleanup (called on application shutdown)
@ -334,6 +345,7 @@ BrowserGlue.prototype = {
os.removeObserver(this, "places-database-locked");
if (this._isPlacesShutdownObserver)
os.removeObserver(this, "places-shutdown");
os.removeObserver(this, "defaultURIFixup-using-keyword-pref");
},
_onAppDefaults: function BG__onAppDefaults() {

View File

@ -50,8 +50,8 @@ function test() {
Array.forEach(tab.linkedBrowser.contentDocument.styleSheets, function(aSS, aIx) {
pendingCount++;
let ssTitle = aSS.title;
stylesheetSwitchAll(tab.linkedBrowser.contentWindow, ssTitle);
gPageStyleMenu.switchStyleSheet(ssTitle, tab.linkedBrowser.contentWindow);
let newTab = gBrowser.duplicateTab(tab);
newTab.linkedBrowser.addEventListener("load", function(aEvent) {
newTab.linkedBrowser.removeEventListener("load", arguments.callee, true);

View File

@ -568,6 +568,7 @@ DebuggerUI.prototype = {
let dbg = this.getDebugger(this.aWindow.gBrowser.selectedTab);
dbg.debuggerWindow.SourceScripts.setEditorMode(aSourceUrl, aContentType);
dbg.editor.setText(aSourceText);
dbg.editor.resetUndo();
let doc = dbg.frame.contentDocument;
let scripts = doc.getElementById("scripts");
let elt = scripts.getElementsByAttribute("value", aSourceUrl)[0];

View File

@ -615,6 +615,7 @@ var SourceScripts = {
window.editor.setText(aScript.text);
window.updateEditorBreakpoints();
}
window.editor.resetUndo();
}
};

View File

@ -45,10 +45,29 @@
<!ENTITY % debuggerDTD SYSTEM "chrome://browser/locale/devtools/debugger.dtd" >
%debuggerDTD;
]>
<?xul-overlay href="chrome://global/content/editMenuOverlay.xul"?>
<?xul-overlay href="chrome://browser/content/source-editor-overlay.xul"?>
<xul:window xmlns="http://www.w3.org/1999/xhtml"
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<xul:script type="text/javascript" src="chrome://global/content/globalOverlay.js"/>
<xul:script type="text/javascript" src="debugger.js"/>
<xul:script type="text/javascript" src="debugger-view.js"/>
<xul:popupset id="debugger-popups">
<xul:menupopup id="sourceEditorContextMenu"
onpopupshowing="goUpdateSourceEditorMenuItems()">
<xul:menuitem id="se-cMenu-copy"/>
<xul:menuseparator/>
<xul:menuitem id="se-cMenu-selectAll"/>
<xul:menuseparator/>
<xul:menuitem id="se-cMenu-find"/>
<xul:menuitem id="se-cMenu-findAgain"/>
<xul:menuseparator/>
<xul:menuitem id="se-cMenu-gotoLine"/>
</xul:menupopup>
</xul:popupset>
<xul:commandset id="editMenuCommands"/>
<xul:commandset id="sourceEditorCommands"/>
<xul:keyset id="sourceEditorKeys"/>
<div id="body" class="vbox flex">
<xul:toolbar id="dbg-toolbar">

View File

@ -74,6 +74,7 @@ _BROWSER_TEST_FILES = \
browser_dbg_select-line.js \
browser_dbg_clean-exit.js \
browser_dbg_bug723069_editor-breakpoints.js \
browser_dbg_bug731394_editor-contextmenu.js \
head.js \
$(NULL)

View File

@ -0,0 +1,102 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Bug 731394: test the debugger source editor default context menu.
*/
const TAB_URL = EXAMPLE_URL + "browser_dbg_script-switching.html";
let gPane = null;
let gTab = null;
let gDebuggee = null;
let gDebugger = null;
function test()
{
let tempScope = {};
Cu.import("resource:///modules/source-editor.jsm", tempScope);
let SourceEditor = tempScope.SourceEditor;
let contextMenu = null;
debug_tab_pane(TAB_URL, function(aTab, aDebuggee, aPane) {
gTab = aTab;
gDebuggee = aDebuggee;
gPane = aPane;
gDebugger = gPane.debuggerWindow;
gPane.activeThread.addOneTimeListener("scriptsadded", function() {
Services.tm.currentThread.dispatch({ run: onScriptsAdded }, 0);
});
gDebuggee.firstCall();
});
function onScriptsAdded()
{
let scripts = gDebugger.DebuggerView.Scripts._scripts;
is(gDebugger.StackFrames.activeThread.state, "paused",
"Should only be getting stack frames while paused.");
is(scripts.itemCount, 2, "Found the expected number of scripts.");
let editor = gDebugger.editor;
isnot(editor.getText().indexOf("debugger"), -1,
"The correct script was loaded initially.");
contextMenu = gDebugger.document.getElementById("sourceEditorContextMenu");
ok(contextMenu, "source editor context menupopup");
ok(editor.readOnly, "editor is read only");
editor.focus();
editor.setSelection(0, 10);
contextMenu.addEventListener("popupshown", function onPopupShown() {
contextMenu.removeEventListener("popupshown", onPopupShown, false);
executeSoon(testContextMenu);
}, false);
contextMenu.openPopup(editor.editorElement, "overlap", 0, 0, true, false);
}
function testContextMenu()
{
let document = gDebugger.document;
ok(document.getElementById("editMenuCommands"),
"#editMenuCommands found");
ok(!document.getElementById("editMenuKeys"),
"#editMenuKeys not found");
ok(document.getElementById("sourceEditorCommands"),
"#sourceEditorCommands found");
ok(document.getElementById("sourceEditorKeys"),
"#sourceEditorKeys found");
// Map command ids to their expected disabled state.
let commands = {"se-cmd-undo": true, "se-cmd-redo": true,
"se-cmd-cut": true, "se-cmd-paste": true,
"se-cmd-delete": true, "cmd_findAgain": true,
"cmd_findPrevious": true, "cmd_find": false,
"cmd_gotoLine": false, "cmd_copy": false,
"se-cmd-selectAll": false};
for (let id in commands) {
let element = document.getElementById(id);
is(element.hasAttribute("disabled"), commands[id],
id + " hasAttribute('disabled') check");
}
executeSoon(function() {
contextMenu.hidePopup();
gDebugger.StackFrames.activeThread.resume(finish);
});
}
registerCleanupFunction(function() {
removeTab(gTab);
gPane = null;
gTab = null;
gDebuggee = null;
gDebugger = null;
});
}

View File

@ -10,7 +10,7 @@ browser.jar:
content/browser/devtools/cssruleview.xul (styleinspector/cssruleview.xul)
content/browser/devtools/styleinspector.css (styleinspector/styleinspector.css)
content/browser/orion.js (sourceeditor/orion/orion.js)
content/browser/source-editor-overlay.xul (sourceeditor/source-editor-overlay.xul)
* content/browser/source-editor-overlay.xul (sourceeditor/source-editor-overlay.xul)
* content/browser/debugger.xul (debugger/debugger.xul)
content/browser/debugger.css (debugger/debugger.css)
content/browser/debugger.js (debugger/debugger.js)

View File

@ -111,21 +111,6 @@
modifiers="accel"/>
-->
<key id="key_cut"
key="&cutCmd.key;"
modifiers="accel"/>
<key id="key_copy"
key="&copyCmd.key;"
modifiers="accel"/>
<key id="key_paste"
key="&pasteCmd.key;"
modifiers="accel"/>
<key id="key_selectAll" key="&selectAllCmd.key;" modifiers="accel"/>
<key id="key_undo" key="&undoCmd.key;" modifiers="accel"
command="se-cmd-undo"/>
<key id="key_redo" key="&undoCmd.key;" modifiers="accel,shift"
command="se-cmd-redo"/>
<key id="sp-key-run"
key="&run.key;"
command="sp-cmd-run"
@ -146,28 +131,6 @@
key="&webConsoleCmd.commandkey;"
command="sp-cmd-webConsole"
modifiers="accel,shift"/>
<key id="key_find"
key="&findCmd.key;"
command="cmd_find"
modifiers="accel"/>
#ifdef XP_MACOSX
<key id="key_findAgain"
key="&findAgainCmd.key;"
command="cmd_findAgain"
modifiers="accel"/>
<key id="key_findPrevious"
key="&findPreviousCmd.key;"
command="cmd_findPrevious"
modifiers="accel,shift"/>
#else
<key id="key_findAgain"
keycode="VK_F3"
command="cmd_findAgain"/>
<key id="key_findPrevious"
keycode="VK_F3"
command="cmd_findPrevious"
modifiers="shift"/>
#endif
<key id="key_openHelp"
keycode="VK_F1"
command="sp-cmd-documentationLink"/>
@ -219,56 +182,20 @@
<menu id="sp-edit-menu" label="&editMenu.label;"
accesskey="&editMenu.accesskey;">
<menupopup id="sp-menu_editpopup"
onpopupshowing="goUpdateGlobalEditMenuItems()">
<menuitem id="sp-menu-undo"
label="&undoCmd.label;"
key="key_undo"
accesskey="&undoCmd.accesskey;"
command="se-cmd-undo"/>
<menuitem id="sp-menu-redo"
label="&redoCmd.label;"
key="key_redo"
accesskey="&redoCmd.accesskey;"
command="se-cmd-redo"/>
onpopupshowing="goUpdateSourceEditorMenuItems()">
<menuitem id="se-menu-undo"/>
<menuitem id="se-menu-redo"/>
<menuseparator/>
<menuitem id="sp-menu-cut"
label="&cutCmd.label;"
key="key_cut"
accesskey="&cutCmd.accesskey;"
command="cmd_cut"/>
<menuitem id="sp-menu-copy"
label="&copyCmd.label;"
key="key_copy"
accesskey="&copyCmd.accesskey;"
command="cmd_copy"/>
<menuitem id="sp-menu-paste"
label="&pasteCmd.label;"
key="key_paste"
accesskey="&pasteCmd.accesskey;"
command="cmd_paste"/>
<menuitem id="se-menu-cut"/>
<menuitem id="se-menu-copy"/>
<menuitem id="se-menu-paste"/>
<menuseparator/>
<menuitem id="sp-menu-selectAll"
label="&selectAllCmd.label;"
key="key_selectAll"
accesskey="&selectAllCmd.accesskey;"
command="cmd_selectAll"/>
<menuitem id="se-menu-selectAll"/>
<menuseparator/>
<menuitem id="sp-menu-find"
label="&findCmd.label;"
accesskey="&findCmd.accesskey;"
key="key_find"
command="cmd_find"/>
<menuitem id="sp-menu-findAgain"
label="&findAgainCmd.label;"
accesskey="&findAgainCmd.accesskey;"
key="key_findAgain"
command="cmd_findAgain"/>
<menuitem id="se-menu-find"/>
<menuitem id="se-menu-findAgain"/>
<menuseparator/>
<menuitem id="sp-menu-gotoLine"
label="&gotoLineCmd.label;"
accesskey="&gotoLineCmd.accesskey;"
key="key_gotoLine"
command="cmd_gotoLine"/>
<menuitem id="se-menu-gotoLine"/>
</menupopup>
</menu>
@ -338,13 +265,13 @@
<popupset id="scratchpad-popups">
<menupopup id="scratchpad-text-popup"
onpopupshowing="goUpdateGlobalEditMenuItems()">
<menuitem id="menu_cut"/>
<menuitem id="menu_copy"/>
<menuitem id="menu_paste"/>
<menuitem id="menu_delete"/>
onpopupshowing="goUpdateSourceEditorMenuItems()">
<menuitem id="se-cMenu-cut"/>
<menuitem id="se-cMenu-copy"/>
<menuitem id="se-cMenu-paste"/>
<menuitem id="se-cMenu-delete"/>
<menuseparator/>
<menuitem id="menu_selectAll"/>
<menuitem id="se-cMenu-selectAll"/>
<menuseparator/>
<menuitem id="sp-text-run"
label="&run.label;"
@ -370,7 +297,7 @@
</popupset>
<notificationbox id="scratchpad-notificationbox" flex="1">
<hbox id="scratchpad-editor" flex="1" context="scratchpad-text-popup" />
<hbox id="scratchpad-editor" flex="1"/>
</notificationbox>
</window>

View File

@ -27,7 +27,7 @@ function runTests()
let doc = gScratchpadWindow.document;
let winUtils = gScratchpadWindow.QueryInterface(Ci.nsIInterfaceRequestor).
getInterface(Ci.nsIDOMWindowUtils);
let OS = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime).OS;
let OS = Services.appinfo.OS;
info("will test the Edit menu");
@ -51,9 +51,9 @@ function runTests()
let menuPopup = editMenu.menupopup;
ok(menuPopup, "the Edit menupopup");
let cutItem = doc.getElementById("sp-menu-cut");
let cutItem = doc.getElementById("se-menu-cut");
ok(cutItem, "the Cut menuitem");
let pasteItem = doc.getElementById("sp-menu-paste");
let pasteItem = doc.getElementById("se-menu-paste");
ok(pasteItem, "the Paste menuitem");
let anchor = doc.documentElement;
@ -174,9 +174,9 @@ function runTests()
menuPopup = doc.getElementById("scratchpad-text-popup");
ok(menuPopup, "the context menupopup");
cutItem = doc.getElementById("menu_cut");
cutItem = doc.getElementById("se-cMenu-cut");
ok(cutItem, "the Cut menuitem");
pasteItem = doc.getElementById("menu_paste");
pasteItem = doc.getElementById("se-cMenu-paste");
ok(pasteItem, "the Paste menuitem");
sp.setText("bug 699130: hello world! (context menu)");

View File

@ -24,6 +24,7 @@
* Kenny Heaton <kennyheaton@gmail.com>
* Spyros Livathinos <livathinos.spyros@gmail.com>
* Allen Eubank <adeubank@gmail.com>
* Girish Sharma <scrapmachines@gmail.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
@ -63,6 +64,14 @@ const ORION_IFRAME = "data:text/html;charset=utf8,<!DOCTYPE html>" +
const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
/**
* Maximum allowed vertical offset for the line index when you call
* SourceEditor.setCaretPosition().
*
* @type number
*/
const VERTICAL_OFFSET = 3;
/**
* The primary selection update delay. On Linux, the X11 primary selection is
* updated to hold the currently selected text.
@ -109,6 +118,10 @@ const ORION_ANNOTATION_TYPES = {
* Default key bindings in the Orion editor.
*/
const DEFAULT_KEYBINDINGS = [
{
action: "enter",
code: Ci.nsIDOMKeyEvent.DOM_VK_ENTER,
},
{
action: "undo",
code: Ci.nsIDOMKeyEvent.DOM_VK_Z,
@ -465,6 +478,10 @@ SourceEditor.prototype = {
*/
_doTab: function SE__doTab()
{
if (this.readOnly) {
return false;
}
let indent = "\t";
let selection = this.getSelection();
let model = this._model;
@ -515,6 +532,10 @@ SourceEditor.prototype = {
*/
_doUnindentLines: function SE__doUnindentLines()
{
if (this.readOnly) {
return true;
}
let indent = "\t";
let selection = this.getSelection();
@ -569,6 +590,10 @@ SourceEditor.prototype = {
*/
_doEnter: function SE__doEnter()
{
if (this.readOnly) {
return false;
}
let selection = this.getSelection();
if (selection.start != selection.end) {
return false;
@ -1309,10 +1334,56 @@ SourceEditor.prototype = {
* The new caret line location. Line numbers start from 0.
* @param number [aColumn=0]
* Optional. The new caret column location. Columns start from 0.
* @param number [aAlign=0]
* Optional. Position of the line with respect to viewport.
* Allowed values are:
* SourceEditor.VERTICAL_ALIGN.TOP target line at top of view.
* SourceEditor.VERTICAL_ALIGN.CENTER target line at center of view.
* SourceEditor.VERTICAL_ALIGN.BOTTOM target line at bottom of view.
*/
setCaretPosition: function SE_setCaretPosition(aLine, aColumn)
setCaretPosition: function SE_setCaretPosition(aLine, aColumn, aAlign)
{
this.setCaretOffset(this._model.getLineStart(aLine) + (aColumn || 0));
let editorHeight = this._view.getClientArea().height;
let lineHeight = this._view.getLineHeight();
let linesVisible = Math.floor(editorHeight/lineHeight);
let halfVisible = Math.round(linesVisible/2);
let firstVisible = this.getTopIndex();
let lastVisible = this._view.getBottomIndex();
let caretOffset = this._model.getLineStart(aLine) + (aColumn || 0);
this._view.setSelection(caretOffset, caretOffset, false);
// If the target line is in view, skip the vertical alignment part.
if (aLine <= lastVisible && aLine >= firstVisible) {
this._view.showSelection();
return;
}
// Setting the offset so that the line always falls in the upper half
// of visible lines (lower half for BOTTOM aligned).
// VERTICAL_OFFSET is the maximum allowed value.
let offset = Math.min(halfVisible, VERTICAL_OFFSET);
let topIndex;
switch (aAlign) {
case this.VERTICAL_ALIGN.CENTER:
topIndex = Math.max(aLine - halfVisible, 0);
break;
case this.VERTICAL_ALIGN.BOTTOM:
topIndex = Math.max(aLine - linesVisible + offset, 0);
break;
default: // this.VERTICAL_ALIGN.TOP.
topIndex = Math.max(aLine - offset, 0);
break;
}
// Bringing down the topIndex to total lines in the editor if exceeding.
topIndex = Math.min(topIndex, this.getLineCount());
this.setTopIndex(topIndex);
let location = this._view.getLocationAtOffset(caretOffset);
this._view.setHorizontalPixel(location.x);
},
/**

View File

@ -35,80 +35,203 @@
- the terms of any one of the MPL, the GPL or the LGPL.
-
- ***** END LICENSE BLOCK ***** -->
<!DOCTYPE overlay SYSTEM "chrome://browser/locale/devtools/sourceeditor.dtd">
<!DOCTYPE overlay [
<!ENTITY % editMenuStrings SYSTEM "chrome://global/locale/editMenuOverlay.dtd">
%editMenuStrings;
<!ENTITY % sourceEditorStrings SYSTEM "chrome://browser/locale/devtools/sourceeditor.dtd">
%sourceEditorStrings;
]>
<overlay id="sourceEditorOverlay"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<!-- This Source Editor overlay requires the editMenuOverlay.xul to be loaded.
The globalOverlay.js script is also required in the XUL document where
the source-editor-overlay.xul is loaded. -->
the source-editor-overlay.xul is loaded. Do not use #editMenuKeys to
avoid conflicts! -->
<script type="application/javascript">
function goUpdateSourceEditorMenuItems()
{
goUpdateGlobalEditMenuItems();
let commands = ['se-cmd-undo', 'se-cmd-redo', 'se-cmd-cut', 'se-cmd-paste',
'se-cmd-delete'];
commands.forEach(goUpdateCommand);
}
</script>
<commandset id="sourceEditorCommands">
<command id="cmd_find" oncommand="goDoCommand('cmd_find')"/>
<command id="cmd_findAgain" oncommand="goDoCommand('cmd_findAgain')" disabled="true"/>
<command id="cmd_findPrevious" oncommand="goDoCommand('cmd_findPrevious')" disabled="true"/>
<command id="cmd_gotoLine" oncommand="goDoCommand('cmd_gotoLine')"/>
<command id="se-cmd-selectAll" oncommand="goDoCommand('se-cmd-selectAll')"/>
<command id="se-cmd-cut" oncommand="goDoCommand('se-cmd-cut')" disabled="true"/>
<command id="se-cmd-paste" oncommand="goDoCommand('se-cmd-paste')" disabled="true"/>
<command id="se-cmd-delete" oncommand="goDoCommand('se-cmd-delete')" disabled="true"/>
<command id="se-cmd-undo" oncommand="goDoCommand('se-cmd-undo')" disabled="true"/>
<command id="se-cmd-redo" oncommand="goDoCommand('se-cmd-redo')" disabled="true"/>
</commandset>
<keyset id="sourceEditorKeys">
<!-- Do not use both #sourceEditorKeys and #editMenuKeys in the same
document to avoid conflicts! -->
<key id="key_undo"
key="&undoCmd.key;"
modifiers="accel"
command="se-cmd-undo"/>
#ifdef XP_UNIX
<key id="key_redo"
key="&undoCmd.key;"
modifiers="accel,shift"
command="se-cmd-redo"/>
#else
<key id="key_redo"
key="&redoCmd.key;"
modifiers="accel"
command="se-cmd-redo"/>
#endif
<key id="key_cut"
key="&cutCmd.key;"
modifiers="accel"
command="se-cmd-cut"/>
<key id="key_copy"
key="&copyCmd.key;"
modifiers="accel"
command="cmd_copy"/>
<key id="key_paste"
key="&pasteCmd.key;"
modifiers="accel"
command="se-cmd-paste"/>
<key id="key_gotoLine"
key="&gotoLineCmd.key;"
command="cmd_gotoLine"
modifiers="accel"/>
<key id="key_delete"
keycode="VK_DELETE"
command="se-cmd-delete"/>
<key id="key_selectAll"
key="&selectAllCmd.key;"
modifiers="accel"
command="se-cmd-selectAll"/>
<key id="key_find"
key="&findCmd.key;"
modifiers="accel"
command="cmd_find"/>
<key id="key_findAgain"
key="&findAgainCmd.key;"
modifiers="accel"
command="cmd_findAgain"/>
<key id="key_findPrevious"
key="&findAgainCmd.key;"
modifiers="shift,accel"
command="cmd_findPrevious"/>
<key id="key_findAgain2"
keycode="&findAgainCmd.key2;"
command="cmd_findAgain"/>
<key id="key_findPrevious2"
keycode="&findAgainCmd.key2;"
modifiers="shift"
command="cmd_findPrevious"/>
</keyset>
<menupopup id="sourceEditorContextMenu"
onpopupshowing="goUpdateGlobalEditMenuItems()">
<menuitem id="se-menu-undo"
label="&undoCmd.label;"
key="key_undo"
accesskey="&undoCmd.accesskey;"
command="se-cmd-undo"/>
<menuseparator/>
<menuitem id="se-menu-cut"
label="&cutCmd.label;"
key="key_cut"
accesskey="&cutCmd.accesskey;"
command="cmd_cut"/>
<menuitem id="se-menu-copy"
label="&copyCmd.label;"
key="key_copy"
accesskey="&copyCmd.accesskey;"
command="cmd_copy"/>
<menuitem id="se-menu-paste"
label="&pasteCmd.label;"
key="key_paste"
accesskey="&pasteCmd.accesskey;"
command="cmd_paste"/>
<menuitem id="se-menu-delete"
label="&deleteCmd.label;"
key="key_delete"
accesskey="&deleteCmd.accesskey;"
command="cmd_delete"/>
<menuseparator/>
<menuitem id="se-menu-selectAll"
label="&selectAllCmd.label;"
key="key_selectAll"
accesskey="&selectAllCmd.accesskey;"
command="cmd_selectAll"/>
<menuseparator/>
<menuitem id="se-menu-find"
label="&findCmd.label;"
accesskey="&findCmd.accesskey;"
key="key_find"
command="cmd_find"/>
<menuitem id="se-menu-findAgain"
label="&findAgainCmd.label;"
accesskey="&findAgainCmd.accesskey;"
key="key_findAgain"
command="cmd_findAgain"/>
<menuseparator/>
<menuitem id="se-menu-gotoLine"
label="&gotoLineCmd.label;"
accesskey="&gotoLineCmd.accesskey;"
key="key_gotoLine"
command="cmd_gotoLine"/>
</menupopup>
<!-- Items for the Edit menu -->
<menuitem id="se-menu-undo"
label="&undoCmd.label;"
key="key_undo"
accesskey="&undoCmd.accesskey;"
command="se-cmd-undo"/>
<menuitem id="se-menu-redo"
label="&redoCmd.label;"
key="key_redo"
accesskey="&redoCmd.accesskey;"
command="se-cmd-redo"/>
<menuitem id="se-menu-cut"
label="&cutCmd.label;"
key="key_cut"
accesskey="&cutCmd.accesskey;"
command="se-cmd-cut"/>
<menuitem id="se-menu-copy"
label="&copyCmd.label;"
key="key_copy"
accesskey="&copyCmd.accesskey;"
command="cmd_copy"/>
<menuitem id="se-menu-paste"
label="&pasteCmd.label;"
key="key_paste"
accesskey="&pasteCmd.accesskey;"
command="se-cmd-paste"/>
<menuitem id="se-menu-delete"
label="&deleteCmd.label;"
key="key_delete"
accesskey="&deleteCmd.accesskey;"
command="se-cmd-delete"/>
<menuitem id="se-menu-selectAll"
label="&selectAllCmd.label;"
key="key_selectAll"
accesskey="&selectAllCmd.accesskey;"
command="se-cmd-selectAll"/>
<menuitem id="se-menu-find"
label="&findCmd.label;"
accesskey="&findCmd.accesskey;"
key="key_find"
command="cmd_find"/>
<menuitem id="se-menu-findAgain"
label="&findAgainCmd.label;"
accesskey="&findAgainCmd.accesskey;"
key="key_findAgain"
command="cmd_findAgain"/>
<menuitem id="se-menu-gotoLine"
label="&gotoLineCmd.label;"
accesskey="&gotoLineCmd.accesskey;"
key="key_gotoLine"
command="cmd_gotoLine"/>
<!-- Items for context menus -->
<menuitem id="se-cMenu-undo"
label="&undoCmd.label;"
key="key_undo"
accesskey="&undoCmd.accesskey;"
command="se-cmd-undo"/>
<menuitem id="se-cMenu-cut"
label="&cutCmd.label;"
key="key_cut"
accesskey="&cutCmd.accesskey;"
command="se-cmd-cut"/>
<menuitem id="se-cMenu-copy"
label="&copyCmd.label;"
key="key_copy"
accesskey="&copyCmd.accesskey;"
command="cmd_copy"/>
<menuitem id="se-cMenu-paste"
label="&pasteCmd.label;"
key="key_paste"
accesskey="&pasteCmd.accesskey;"
command="se-cmd-paste"/>
<menuitem id="se-cMenu-delete"
label="&deleteCmd.label;"
key="key_delete"
accesskey="&deleteCmd.accesskey;"
command="se-cmd-delete"/>
<menuitem id="se-cMenu-selectAll"
label="&selectAllCmd.label;"
key="key_selectAll"
accesskey="&selectAllCmd.accesskey;"
command="se-cmd-selectAll"/>
<menuitem id="se-cMenu-find"
label="&findCmd.label;"
accesskey="&findCmd.accesskey;"
key="key_find"
command="cmd_find"/>
<menuitem id="se-cMenu-findAgain"
label="&findAgainCmd.label;"
accesskey="&findAgainCmd.accesskey;"
key="key_findAgain"
command="cmd_findAgain"/>
<menuitem id="se-cMenu-gotoLine"
label="&gotoLineCmd.label;"
accesskey="&gotoLineCmd.accesskey;"
key="key_gotoLine"
command="cmd_gotoLine"/>
</overlay>

View File

@ -253,6 +253,10 @@ SourceEditorController.prototype = {
case "cmd_gotoLine":
case "se-cmd-undo":
case "se-cmd-redo":
case "se-cmd-cut":
case "se-cmd-paste":
case "se-cmd-delete":
case "se-cmd-selectAll":
result = true;
break;
default:
@ -278,6 +282,7 @@ SourceEditorController.prototype = {
switch (aCommand) {
case "cmd_find":
case "cmd_gotoLine":
case "se-cmd-selectAll":
result = true;
break;
case "cmd_findAgain":
@ -290,6 +295,19 @@ SourceEditorController.prototype = {
case "se-cmd-redo":
result = this._editor.canRedo();
break;
case "se-cmd-cut":
case "se-cmd-delete": {
let selection = this._editor.getSelection();
result = selection.start != selection.end && !this._editor.readOnly;
break;
}
case "se-cmd-paste": {
let window = this._editor._view._frameWindow;
let controller = window.controllers.getControllerForCommand("cmd_paste");
result = !this._editor.readOnly &&
controller.isCommandEnabled("cmd_paste");
break;
}
default:
result = false;
break;
@ -320,12 +338,26 @@ SourceEditorController.prototype = {
case "cmd_gotoLine":
this._editor.ui.gotoLine();
break;
case "se-cmd-selectAll":
this._editor._view.invokeAction("selectAll");
break;
case "se-cmd-undo":
this._editor.undo();
break;
case "se-cmd-redo":
this._editor.redo();
break;
case "se-cmd-cut":
this._editor.ui._ownerWindow.goDoCommand("cmd_cut");
break;
case "se-cmd-paste":
this._editor.ui._ownerWindow.goDoCommand("cmd_paste");
break;
case "se-cmd-delete": {
let selection = this._editor.getSelection();
this._editor.setText("", selection.start, selection.end);
break;
}
}
},

View File

@ -312,6 +312,16 @@ SourceEditor.EVENTS = {
DIRTY_CHANGED: "DirtyChanged",
};
/**
* Allowed vertical alignment options for the line index
* when you call SourceEditor.setCaretPosition().
*/
SourceEditor.VERTICAL_ALIGN = {
TOP: 0,
CENTER: 1,
BOTTOM: 2,
};
/**
* Extend a destination object with properties from a source object.
*
@ -336,6 +346,7 @@ extend(SourceEditor.prototype, {
MODES: SourceEditor.MODES,
THEMES: SourceEditor.THEMES,
DEFAULTS: SourceEditor.DEFAULTS,
VERTICAL_ALIGN: SourceEditor.VERTICAL_ALIGN,
_lastFind: null,

View File

@ -60,6 +60,7 @@ _BROWSER_TEST_FILES = \
browser_bug712982_line_ruler_click.js \
browser_bug725618_moveLines_shortcut.js \
browser_bug700893_dirty_state.js \
browser_bug729480_line_vertical_align.js \
head.js \
libs:: $(_BROWSER_TEST_FILES)

View File

@ -0,0 +1,99 @@
/* vim: set ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
let tempScope = {};
Cu.import("resource:///modules/source-editor.jsm", tempScope);
let SourceEditor = tempScope.SourceEditor;
let testWin;
let editor;
const VERTICAL_OFFSET = 3;
function test()
{
waitForExplicitFinish();
const windowUrl = "data:application/vnd.mozilla.xul+xml,<?xml version='1.0'?>" +
"<window xmlns='http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul'" +
" title='test for bug 729480 - allow setCaretPosition align the target line" +
" vertically in view according to a third argument'" +
" width='300' height='300'><box flex='1'/></window>";
const windowFeatures = "chrome,titlebar,toolbar,centerscreen,dialog=no";
testWin = Services.ww.openWindow(null, windowUrl, "_blank", windowFeatures, null);
testWin.addEventListener("load", function onWindowLoad() {
testWin.removeEventListener("load", onWindowLoad, false);
waitForFocus(initEditor, testWin);
}, false);
}
function initEditor()
{
let box = testWin.document.querySelector("box");
editor = new SourceEditor();
editor.init(box, {showLineNumbers: true}, editorLoaded);
}
function editorLoaded()
{
editor.focus();
// setting 3 pages of lines containing the line number.
let view = editor._view;
let lineHeight = view.getLineHeight();
let editorHeight = view.getClientArea().height;
let linesPerPage = Math.floor(editorHeight / lineHeight);
let totalLines = 3 * linesPerPage;
let text = "";
for (let i = 0; i < totalLines; i++) {
text += "Line " + i + "\n";
}
editor.setText(text);
editor.setCaretOffset(0);
let offset = Math.min(Math.round(linesPerPage/2), VERTICAL_OFFSET);
// Building the iterator array.
// [line, alignment, topIndex_check]
let iterateOn = [
[0, "TOP", 0],
[25, "TOP", 25 - offset],
// Case when the target line is already in view.
[27, "TOP", 25 - offset],
[0, "BOTTOM", 0],
[5, "BOTTOM", 0],
[38, "BOTTOM", 38 - linesPerPage + offset],
[0, "CENTER", 0],
[4, "CENTER", 0],
[34, "CENTER", 34 - Math.round(linesPerPage/2)]
];
function testEnd() {
editor.destroy();
testWin.close();
testWin = editor = null;
waitForFocus(finish, window);
}
function testPosition(pos) {
is(editor.getTopIndex(), iterateOn[pos][2], "scroll is correct for test #" + pos);
iterator(++pos);
}
function iterator(i) {
if (i == iterateOn.length) {
testEnd();
} else {
editor.setCaretPosition(iterateOn[i][0], 0,
editor.VERTICAL_ALIGN[iterateOn[i][1]]);
executeSoon(testPosition.bind(this, i));
}
}
iterator(0);
}

View File

@ -201,11 +201,21 @@ function editorLoaded()
editor.setText("foobar");
is(editor.getText(), "foobar", "editor allows programmatic changes (setText)");
EventUtils.synthesizeKey("VK_RETURN", {}, testWin);
is(editor.getText(), "foobar", "Enter key does nothing");
EventUtils.synthesizeKey("VK_TAB", {}, testWin);
is(editor.getText(), "foobar", "Tab does nothing");
editor.setText(" foobar");
EventUtils.synthesizeKey("VK_TAB", {shiftKey: true}, testWin);
is(editor.getText(), " foobar", "Shift+Tab does nothing");
editor.readOnly = false;
editor.setCaretOffset(editor.getCharCount());
EventUtils.synthesizeKey("-", {}, testWin);
is(editor.getText(), "foobar-", "editor is now editable again");
is(editor.getText(), " foobar-", "editor is now editable again");
// Test the Selection event.

View File

@ -57,7 +57,22 @@
<xul:script type="application/javascript" src="chrome://global/content/globalOverlay.js"/>
<xul:popupset id="style-editor-popups">
<xul:menupopup id="sourceEditorContextMenu"/>
<xul:menupopup id="sourceEditorContextMenu"
onpopupshowing="goUpdateSourceEditorMenuItems()">
<xul:menuitem id="se-cMenu-undo"/>
<xul:menuseparator/>
<xul:menuitem id="se-cMenu-cut"/>
<xul:menuitem id="se-cMenu-copy"/>
<xul:menuitem id="se-cMenu-paste"/>
<xul:menuitem id="se-cMenu-delete"/>
<xul:menuseparator/>
<xul:menuitem id="se-cMenu-selectAll"/>
<xul:menuseparator/>
<xul:menuitem id="se-cMenu-find"/>
<xul:menuitem id="se-cMenu-findAgain"/>
<xul:menuseparator/>
<xul:menuitem id="se-cMenu-gotoLine"/>
</xul:menupopup>
</xul:popupset>
<xul:commandset id="editMenuCommands"/>
@ -66,7 +81,6 @@
<xul:command id="style-editor-cmd-close" oncommand="window.close();"/>
</xul:commandset>
<xul:keyset id="editMenuKeys"/>
<xul:keyset id="sourceEditorKeys"/>
<xul:keyset id="style-editor-keyset">
<xul:key id="style-editor-key-close"

View File

@ -333,6 +333,22 @@ telemetryYesButtonLabel2 = Yes, I want to help
telemetryYesButtonAccessKey = Y
telemetryNoButtonLabel = No
telemetryNoButtonAccessKey = N
# Keyword.URL reset prompt
# LOCALIZATION NOTE (keywordPrompt.message):
# - %1$S is brandShortName
# - %2$S is a host name (e.g. "somewebsearch.com") from the current value of keyword.URL
# - %3$S is the name of the default search engine (e.g. "Google")
keywordPrompt.message = %1$S is using '%2$S' for searches from the location bar. Would you like to restore the default search (%3$S)?
# LOCALIZATION NOTE (keywordPrompt.yesButton): %1$S is the name of the default search engine
keywordPrompt.yesButton = Yes, use %1$S
keywordPrompt.yesButton.accessKey = Y
# LOCALIZATION NOTE (keywordPrompt.noButton): %1$S is a host name (e.g. "somewebsearch.com") from the current value of keyword.URL
keywordPrompt.noButton = No, continue using '%1$S'
keywordPrompt.noButton.accessKey = N
# Telemetry opt-out prompt for Aurora and Nightly
# LOCALIZATION NOTE (telemetryOptOutPrompt): %1$S and %3$S will be replaced by
# brandFullName, and %2$S by the value of the toolkit.telemetry.server_owner preference.

View File

@ -43,50 +43,6 @@
<!ENTITY editMenu.label "Edit">
<!ENTITY editMenu.accesskey "E">
<!ENTITY undoCmd.label "Undo">
<!ENTITY undoCmd.key "Z">
<!ENTITY undoCmd.accesskey "U">
<!ENTITY redoCmd.label "Redo">
<!ENTITY redoCmd.key "Y">
<!ENTITY redoCmd.accesskey "R">
<!ENTITY cutCmd.label "Cut">
<!ENTITY cutCmd.key "X">
<!ENTITY cutCmd.accesskey "t">
<!ENTITY copyCmd.label "Copy">
<!ENTITY copyCmd.key "C">
<!ENTITY copyCmd.accesskey "C">
<!ENTITY pasteCmd.label "Paste">
<!ENTITY pasteCmd.key "V">
<!ENTITY pasteCmd.accesskey "P">
<!ENTITY selectAllCmd.label "Select All">
<!ENTITY selectAllCmd.key "A">
<!ENTITY selectAllCmd.accesskey "A">
<!ENTITY findCmd.label "Find…">
<!ENTITY findCmd.key "F">
<!ENTITY findCmd.accesskey "F">
<!ENTITY findAgainCmd.label "Find Again…">
<!-- LOCALIZATION NOTE (findAgainCmd.key): This key is used only on Macs.
- Windows and Linux builds use the F3 key which is not localizable on purpose.
-->
<!ENTITY findAgainCmd.key "G">
<!ENTITY findAgainCmd.accesskey "g">
<!-- LOCALIZATION NOTE (findPreviousCmd.key): This key is used only on Macs.
- Windows and Linux builds use the Shift-F3 key which is not localizable on
- purpose.
-->
<!ENTITY findPreviousCmd.key "G">
<!ENTITY gotoLineCmd.label "Jump to line…">
<!ENTITY gotoLineCmd.key "J">
<!ENTITY gotoLineCmd.accesskey "J">
<!ENTITY run.label "Run">
<!ENTITY run.accesskey "R">
<!ENTITY run.key "r">

View File

@ -10,23 +10,6 @@
- A good criteria is the language in which you'd find the best
- documentation on web development on the web. -->
<!ENTITY undoCmd.label "Undo">
<!ENTITY undoCmd.accesskey "U">
<!ENTITY cutCmd.label "Cut">
<!ENTITY cutCmd.accesskey "t">
<!ENTITY copyCmd.label "Copy">
<!ENTITY copyCmd.accesskey "C">
<!ENTITY pasteCmd.label "Paste">
<!ENTITY pasteCmd.accesskey "P">
<!ENTITY deleteCmd.label "Delete">
<!ENTITY deleteCmd.accesskey "D">
<!ENTITY selectAllCmd.label "Select All">
<!ENTITY selectAllCmd.accesskey "A">
<!ENTITY findCmd.label "Find…">
<!ENTITY findCmd.accesskey "F">
<!ENTITY findAgainCmd.label "Find Again…">
<!ENTITY findAgainCmd.accesskey "g">
<!ENTITY gotoLineCmd.label "Jump to line…">
<!ENTITY gotoLineCmd.key "J">
<!ENTITY gotoLineCmd.accesskey "J">

View File

@ -0,0 +1,105 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
let EXPORTED_SYMBOLS = [ "KeywordURLResetPrompter" ];
const Ci = Components.interfaces;
const Cc = Components.classes;
const Cu = Components.utils;
Cu.import("resource://gre/modules/Services.jsm");
const KEYWORD_PROMPT_REV = 1;
let KeywordURLResetPrompter = {
get shouldPrompt() {
let keywordURLUserSet = Services.prefs.prefHasUserValue("keyword.URL");
let declinedRev;
try {
declinedRev = Services.prefs.getIntPref("browser.keywordURLPromptDeclined");
} catch (ex) {}
return keywordURLUserSet && declinedRev != KEYWORD_PROMPT_REV;
},
prompt: function KeywordURLResetPrompter_prompt(win, keywordURI) {
let tabbrowser = win.gBrowser;
let notifyBox = tabbrowser.getNotificationBox();
let existingNotification = notifyBox.getNotificationWithValue("keywordURL-reset");
if (existingNotification)
return;
// Find the name/URI of this build's original default engine.
// XXX: Can't use originalDefaultEngine getter here, because that doesn't
// use the default pref branch.
let defaultURI;
let defaultEngine;
try {
let defaultPB = Services.prefs.getDefaultBranch(null);
let defaultName = defaultPB.getComplexValue("browser.search.defaultenginename",
Ci.nsIPrefLocalizedString).data;
defaultEngine = Services.search.getEngineByName(defaultName);
defaultURI = defaultEngine.getSubmission("foo").uri;
} catch (ex) {
// Something went horribly wrong! bail out
return;
}
// If the user-set value has the same base domain as the default, don't
// prompt.
let keywordBaseDomain;
try {
keywordBaseDomain = Services.eTLD.getBaseDomain(keywordURI);
if (keywordBaseDomain == Services.eTLD.getBaseDomain(defaultURI))
return;
} catch (ex) {}
if (!keywordBaseDomain)
return;
let brandBundle = Services.strings.createBundle("chrome://branding/locale/brand.properties");
let brandShortName = brandBundle.GetStringFromName("brandShortName");
let browserBundle = win.gNavigatorBundle;
let msg = browserBundle.getFormattedString("keywordPrompt.message",
[brandShortName, keywordBaseDomain,
defaultEngine.name]);
let buttons = [
{
label: browserBundle.getFormattedString("keywordPrompt.yesButton",
[defaultEngine.name]),
accessKey: browserBundle.getString("keywordPrompt.yesButton.accessKey"),
popup: null,
callback: function(aNotificationBar, aButton) {
Services.prefs.clearUserPref("keyword.URL");
try {
// If the currently loaded URI still has the same base domain as the
// keyword URI (this is used as a rough approximation of whether the
// user is still seeing search results as opposed to having clicked
// on a result link), load the default engine's searchForm URL so
// that they can re-do their search.
let currentBaseDomain = Services.eTLD.getBaseDomain(tabbrowser.currentURI);
if (currentBaseDomain == keywordBaseDomain)
tabbrowser.loadURI(defaultEngine.searchForm);
} catch (ex) {}
}
},
{
label: browserBundle.getFormattedString("keywordPrompt.noButton",
[keywordBaseDomain]),
accessKey: browserBundle.getString("keywordPrompt.noButton.accessKey"),
popup: null,
callback: function(aNotificationBar, aButton) {
Services.prefs.setIntPref("browser.keywordURLPromptDeclined", KEYWORD_PROMPT_REV);
}
}
];
let notification = notifyBox.appendNotification(msg, "keywordURL-reset", null, notifyBox.PRIORITY_WARNING_HIGH, buttons);
notification.setAttribute("hideclose", true);
// stick around for a few page loads in case there are redirects involved
notification.persistence = 3;
}
}

View File

@ -52,6 +52,7 @@ EXTRA_JS_MODULES = \
NewTabUtils.jsm \
offlineAppCache.jsm \
TelemetryTimestamps.jsm \
KeywordURLResetPrompter.jsm \
$(NULL)
ifeq ($(MOZ_WIDGET_TOOLKIT),windows)

View File

@ -205,7 +205,7 @@
.ruleview-rule-source {
background-color: -moz-dialog;
color: #0091ff;
color: -moz-dialogText;
padding: 2px 5px;
cursor: pointer;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 863 B

View File

@ -207,7 +207,7 @@
.ruleview-rule-source {
background-color: -moz-dialog;
color: #0091ff;
color: -moz-dialogText;
padding: 2px 5px;
cursor: pointer;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 863 B

View File

@ -205,7 +205,7 @@
.ruleview-rule-source {
background-color: -moz-dialog;
color: #0091ff;
color: -moz-dialogText;
padding: 2px 5px;
cursor: pointer;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 863 B

View File

@ -960,10 +960,10 @@ ifdef MSMANIFEST_TOOL
endif # MSVC with manifest tool
else
ifeq ($(CPP_PROG_LINK),1)
$(EXPAND_CCC) $(CXXFLAGS) -o $@ $< $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(MOZ_GLUE_PROGRAM_LDFLAGS) $(WRAP_LDFLAGS) $(LIBS_DIR) $(LIBS) $(OS_LIBS) $(EXTRA_LIBS) $(BIN_FLAGS)
$(EXPAND_CCC) $(CXXFLAGS) -o $@ $< $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(WRAP_LDFLAGS) $(LIBS_DIR) $(LIBS) $(MOZ_GLUE_PROGRAM_LDFLAGS) $(OS_LIBS) $(EXTRA_LIBS) $(BIN_FLAGS)
@$(call CHECK_STDCXX,$@)
else
$(EXPAND_CC) $(CFLAGS) $(OUTOPTION)$@ $< $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(MOZ_GLUE_PROGRAM_LDFLAGS) $(WRAP_LDFLAGS) $(LIBS_DIR) $(LIBS) $(OS_LIBS) $(EXTRA_LIBS) $(BIN_FLAGS)
$(EXPAND_CC) $(CFLAGS) $(OUTOPTION)$@ $< $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(WRAP_LDFLAGS) $(LIBS_DIR) $(LIBS) $(MOZ_GLUE_PROGRAM_LDFLAGS) $(OS_LIBS) $(EXTRA_LIBS) $(BIN_FLAGS)
endif # CPP_PROG_LINK
endif # WINNT && !GNU_CC

View File

@ -4931,6 +4931,10 @@ MOZ_ARG_HEADER(Toolkit Options)
AC_MSG_ERROR([You must specify a default toolkit (perhaps $_PLATFORM_DEFAULT_TOOLKIT).])
fi
MOZ_ARG_WITHOUT_BOOL(x,
[ --without-x Build without X11],
WITHOUT_X11=1)
dnl ========================================================
dnl = Enable the toolkit as needed =
dnl ========================================================
@ -4965,16 +4969,17 @@ cairo-gtk2|cairo-gtk2-x11)
cairo-qt)
MOZ_WIDGET_TOOLKIT=qt
MOZ_ENABLE_QT=1
MOZ_ENABLE_XREMOTE=1
if test -z "$WITHOUT_X11"; then
MOZ_ENABLE_XREMOTE=1
MOZ_WEBGL_GLX=1
MOZ_X11=1
AC_DEFINE(MOZ_X11)
XT_LIBS=
fi
MOZ_WEBGL=1
MOZ_WEBGL_GLX=1
USE_ELF_DYNSTR_GC=
AC_DEFINE(MOZ_X11)
MOZ_X11=1
USE_FC_FREETYPE=1
XT_LIBS=
TK_CFLAGS='$(MOZ_QT_CFLAGS)'
TK_LIBS='$(MOZ_QT_LIBS)'
AC_DEFINE(MOZ_WIDGET_QT)
@ -8843,6 +8848,9 @@ fi
dnl Check for missing components
if test "$COMPILE_ENVIRONMENT"; then
if test "$MOZ_X11"; then
if test "$WITHOUT_X11"; then
AC_MSG_ERROR([--without-x specified and MOZ_X11 still defined])
fi
dnl ====================================================
dnl = Check if X headers exist
dnl ====================================================

View File

@ -0,0 +1,32 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef CORSMode_h_
#define CORSMode_h_
namespace mozilla {
enum CORSMode {
/**
* The default of not using CORS to validate cross-origin loads.
*/
CORS_NONE,
/**
* Validate cross-site loads using CORS, but do not send any credentials
* (cookies, HTTP auth logins, etc) along with the request.
*/
CORS_ANONYMOUS,
/**
* Validate cross-site loads using CORS, and send credentials such as cookies
* and HTTP auth logins along with the request.
*/
CORS_USE_CREDENTIALS
};
} // namespace mozilla
#endif /* CORSMode_h_ */

View File

@ -79,13 +79,17 @@ nsXMLNameSpaceMap.h \
nsIXFormsUtilityService.h \
$(NULL)
EXPORTS_NAMESPACES = mozilla/dom
EXPORTS_NAMESPACES = mozilla/dom mozilla
EXPORTS_mozilla/dom = \
Element.h \
FromParser.h \
$(NULL)
EXPORTS_mozilla = \
CORSMode.h \
$(NULL)
SDK_XPIDLSRCS = \
nsISelection.idl \
$(NULL)
@ -97,7 +101,6 @@ XPIDLSRCS = \
nsIDOMFileReader.idl \
nsIDOMFileList.idl \
nsIDOMFileException.idl \
nsIDOMFileError.idl \
nsIDOMFormData.idl \
nsIDOMParser.idl \
nsIDOMSerializer.idl \

View File

@ -1619,7 +1619,43 @@ public:
* case for ASCII characters a-z.
*/
static bool EqualsIgnoreASCIICase(const nsAString& aStr1,
const nsAString& aStr2);
const nsAString& aStr2);
/**
* Case insensitive comparison between a string and an ASCII literal.
* This must ONLY be applied to an actual literal string. Do not attempt
* to use it with a regular char* pointer, or with a char array variable.
* The template trick to acquire the array length at compile time without
* using a macro is due to Corey Kosak, which much thanks.
*/
static bool EqualsLiteralIgnoreASCIICase(const nsAString& aStr1,
const char* aStr2,
const PRUint32 len);
#ifdef NS_DISABLE_LITERAL_TEMPLATE
static inline bool
EqualsLiteralIgnoreASCIICase(const nsAString& aStr1,
const char* aStr2)
{
PRUint32 len = strlen(aStr2);
return EqualsLiteralIgnoreASCIICase(aStr1, aStr2, len);
}
#else
template<int N>
static inline bool
EqualsLiteralIgnoreASCIICase(const nsAString& aStr1,
const char (&aStr2)[N])
{
return EqualsLiteralIgnoreASCIICase(aStr1, aStr2, N-1);
}
template<int N>
static inline bool
EqualsLiteralIgnoreASCIICase(const nsAString& aStr1,
char (&aStr2)[N])
{
const char* s = aStr2;
return EqualsLiteralIgnoreASCIICase(aStr1, s, N-1);
}
#endif
/**
* Convert ASCII A-Z to a-z.

View File

@ -43,7 +43,6 @@
#include "nsIFile.h"
#include "nsIDOMFile.h"
#include "nsIDOMFileList.h"
#include "nsIDOMFileError.h"
#include "nsIInputStream.h"
#include "nsIJSNativeInitializer.h"
#include "nsIMutable.h"
@ -53,12 +52,13 @@
#include "nsIXMLHttpRequest.h"
#include "prmem.h"
#include "nsAutoPtr.h"
#include "mozilla/dom/indexedDB/FileInfo.h"
#include "mozilla/dom/indexedDB/FileManager.h"
#include "mozilla/dom/indexedDB/IndexedDatabaseManager.h"
#include "mozilla/GuardObjects.h"
#include "mozilla/StandardInteger.h"
#include "mozilla/dom/DOMError.h"
#include "mozilla/dom/indexedDB/FileInfo.h"
#include "mozilla/dom/indexedDB/FileManager.h"
#include "mozilla/dom/indexedDB/IndexedDatabaseManager.h"
class nsIFile;
class nsIInputStream;
@ -363,18 +363,6 @@ private:
nsCOMArray<nsIDOMFile> mFiles;
};
class nsDOMFileError : public nsIDOMFileError
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIDOMFILEERROR
nsDOMFileError(PRUint16 aErrorCode) : mCode(aErrorCode) {}
private:
PRUint16 mCode;
};
class NS_STACK_CLASS nsDOMFileInternalUrlHolder {
public:
nsDOMFileInternalUrlHolder(nsIDOMBlob* aFile, nsIPrincipal* aPrincipal

View File

@ -1,50 +0,0 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Mozilla Corporation
* Portions created by the Initial Developer are Copyright (C) 2007
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "domstubs.idl"
[scriptable, uuid(4BDAFB64-15E2-49C1-A090-4315A7884A56)]
interface nsIDOMFileError : nsISupports
{
const unsigned short NOT_FOUND_ERR = 1;
const unsigned short SECURITY_ERR = 2;
const unsigned short ABORT_ERR = 3;
const unsigned short NOT_READABLE_ERR = 4;
const unsigned short ENCODING_ERR = 5;
readonly attribute unsigned short code;
};

View File

@ -39,9 +39,9 @@
interface nsIDOMEventListener;
interface nsIDOMBlob;
interface nsIDOMFileError;
interface nsIDOMDOMError;
[scriptable, builtinclass, uuid(d158de26-904e-4731-b42c-8b3a4d172703)]
[scriptable, builtinclass, uuid(faed1779-b523-4060-8c3b-7199f347b273)]
interface nsIDOMFileReader : nsIDOMEventTarget
{
[implicit_jscontext]
@ -59,7 +59,7 @@ interface nsIDOMFileReader : nsIDOMEventTarget
[implicit_jscontext]
readonly attribute jsval result;
readonly attribute nsIDOMFileError error;
readonly attribute nsIDOMDOMError error;
attribute nsIDOMEventListener onloadstart;
attribute nsIDOMEventListener onprogress;

View File

@ -1424,7 +1424,8 @@ public:
/**
* Called by nsParser to preload images. Can be removed and code moved
* to nsPreloadURIs::PreloadURIs() in file nsParser.cpp whenever the
* parser-module is linked with gklayout-module.
* parser-module is linked with gklayout-module. aCrossOriginAttr should
* be a void string if the attr is not present.
*/
virtual void MaybePreLoadImage(nsIURI* uri,
const nsAString& aCrossOriginAttr) = 0;

View File

@ -47,6 +47,7 @@
#include "nsIParser.h"
#include "nsContentCreatorFunctions.h"
#include "nsIDOMHTMLScriptElement.h"
#include "mozilla/CORSMode.h"
#define NS_ISCRIPTELEMENT_IID \
{ 0x24ab3ff2, 0xd75e, 0x4be4, \
@ -258,6 +259,15 @@ public:
return block;
}
/**
* Get the CORS mode of the script element
*/
virtual mozilla::CORSMode GetCORSMode() const
{
/* Default to no CORS */
return mozilla::CORS_NONE;
}
protected:
/**
* Processes the script if it's in the document-tree and links to or

View File

@ -119,13 +119,13 @@ FileIOObject::DispatchError(nsresult rv, nsAString& finalEvent)
// Set the status attribute, and dispatch the error event
switch (rv) {
case NS_ERROR_FILE_NOT_FOUND:
mError = new nsDOMFileError(nsIDOMFileError::NOT_FOUND_ERR);
mError = DOMError::CreateWithName(NS_LITERAL_STRING("NotFoundError"));
break;
case NS_ERROR_FILE_ACCESS_DENIED:
mError = new nsDOMFileError(nsIDOMFileError::SECURITY_ERR);
mError = DOMError::CreateWithName(NS_LITERAL_STRING("SecurityError"));
break;
default:
mError = new nsDOMFileError(nsIDOMFileError::NOT_READABLE_ERR);
mError = DOMError::CreateWithName(NS_LITERAL_STRING("NotReadableError"));
break;
}
@ -258,14 +258,17 @@ FileIOObject::OnStopRequest(nsIRequest* aRequest, nsISupports* aContext,
NS_IMETHODIMP
FileIOObject::Abort()
{
if (mReadyState != 1)
if (mReadyState != 1) {
// XXX The spec doesn't say this
return NS_ERROR_DOM_FILE_ABORT_ERR;
}
ClearProgressEventTimer();
mReadyState = 2; // There are DONE constants on multiple interfaces,
// but they all have value 2.
mError = new nsDOMFileError(nsIDOMFileError::ABORT_ERR);
// XXX The spec doesn't say this
mError = DOMError::CreateWithName(NS_LITERAL_STRING("AbortError"));
nsString finalEvent;
nsresult rv = DoAbort(finalEvent);
@ -285,7 +288,7 @@ FileIOObject::GetReadyState(PRUint16 *aReadyState)
}
NS_IMETHODIMP
FileIOObject::GetError(nsIDOMFileError** aError)
FileIOObject::GetError(nsIDOMDOMError** aError)
{
NS_IF_ADDREF(*aError = mError);
return NS_OK;

View File

@ -45,9 +45,10 @@
#include "nsIDOMFile.h"
#include "nsIStreamListener.h"
#include "nsITimer.h"
#include "nsCOMPtr.h"
#include "mozilla/dom/DOMError.h"
#define NS_PROGRESS_EVENT_INTERVAL 50
namespace mozilla {
@ -69,7 +70,7 @@ public:
// Common methods
NS_METHOD Abort();
NS_METHOD GetReadyState(PRUint16* aReadyState);
NS_METHOD GetError(nsIDOMFileError** aError);
NS_METHOD GetError(nsIDOMDOMError** aError);
NS_DECL_AND_IMPL_EVENT_HANDLER(abort);
NS_DECL_AND_IMPL_EVENT_HANDLER(error);
@ -108,7 +109,7 @@ protected:
bool mProgressEventWasDelayed;
bool mTimerIsActive;
nsCOMPtr<nsIDOMFileError> mError;
nsCOMPtr<nsIDOMDOMError> mError;
nsCOMPtr<nsIChannel> mChannel;
PRUint16 mReadyState;

View File

@ -714,7 +714,7 @@ nsAttrValue::GetEnumString(nsAString& aResult, bool aRealTag) const
if (table->value == val) {
aResult.AssignASCII(table->tag);
if (!aRealTag && allEnumBits & NS_ATTRVALUE_ENUMTABLE_VALUE_NEEDS_TO_UPPER) {
ToUpperCase(aResult);
nsContentUtils::ASCIIToUpper(aResult);
}
return;
}
@ -1316,7 +1316,7 @@ nsAttrValue::ParseEnumValue(const nsAString& aValue,
if (!equals) {
nsAutoString tag;
tag.AssignASCII(tableEntry->tag);
ToUpperCase(tag);
nsContentUtils::ASCIIToUpper(tag);
if ((equals = tag.Equals(aValue))) {
value |= NS_ATTRVALUE_ENUMTABLE_VALUE_NEEDS_TO_UPPER;
}

View File

@ -617,8 +617,9 @@ nsContentSink::ProcessLinkHeader(nsIContent* aElement,
if (media.IsEmpty()) {
media = value;
// HTML4.0 spec is inconsistent, make it case INSENSITIVE
ToLowerCase(media);
// The HTML5 spec is formulated in terms of the CSS3 spec,
// which specifies that media queries are case insensitive.
nsContentUtils::ASCIIToLower(media);
}
} else if (attr.LowerCaseEqualsLiteral("anchor")) {
if (anchor.IsEmpty()) {
@ -757,7 +758,7 @@ nsContentSink::ProcessMETATag(nsIContent* aContent)
nsAutoString result;
aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::content, result);
if (!result.IsEmpty()) {
ToLowerCase(header);
nsContentUtils::ASCIIToLower(header);
nsCOMPtr<nsIAtom> fieldAtom(do_GetAtom(header));
rv = ProcessHeaderData(fieldAtom, result, aContent);
}
@ -769,7 +770,7 @@ nsContentSink::ProcessMETATag(nsIContent* aContent)
nsAutoString result;
aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::content, result);
if (!result.IsEmpty()) {
ToLowerCase(result);
nsContentUtils::ASCIIToLower(result);
mDocument->SetHeaderData(nsGkAtoms::handheldFriendly, result);
}
}

View File

@ -5393,6 +5393,7 @@ nsContentUtils::ASCIIToUpper(const nsAString& aSource, nsAString& aDest)
}
}
/* static */
bool
nsContentUtils::EqualsIgnoreASCIICase(const nsAString& aStr1,
const nsAString& aStr2)
@ -5415,7 +5416,7 @@ nsContentUtils::EqualsIgnoreASCIICase(const nsAString& aStr1,
return false;
}
// We know they only differ in the 0x0020 bit.
// We know they can only differ in the 0x0020 bit.
// Likely the two chars are the same, so check that first
if (c1 != c2) {
// They do differ, but since it's only in the 0x0020 bit, check if it's
@ -5430,6 +5431,44 @@ nsContentUtils::EqualsIgnoreASCIICase(const nsAString& aStr1,
return true;
}
/* static */
bool
nsContentUtils::EqualsLiteralIgnoreASCIICase(const nsAString& aStr1,
const char* aStr2,
const PRUint32 len)
{
if (aStr1.Length() != len) {
return false;
}
const PRUnichar* str1 = aStr1.BeginReading();
const char* str2 = aStr2;
const PRUnichar* end = str1 + len;
while (str1 < end) {
PRUnichar c1 = *str1++;
PRUnichar c2 = *str2++;
// First check if any bits other than the 0x0020 differs
if ((c1 ^ c2) & 0xffdf) {
return false;
}
// We know they can only differ in the 0x0020 bit.
// Likely the two chars are the same, so check that first
if (c1 != c2) {
// They do differ, but since it's only in the 0x0020 bit, check if it's
// the same ascii char, but just differing in case
PRUnichar c1Upper = c1 & 0xffdf;
if (!('A' <= c1Upper && c1Upper <= 'Z')) {
return false;
}
}
}
return true;
}
/* static */
nsIInterfaceRequestor*
nsContentUtils::GetSameOriginChecker()

View File

@ -210,11 +210,11 @@ nsDOMAttribute::GetNameAtom(nsIContent* aContent)
mNodeInfo->NamespaceID() == kNameSpaceID_None &&
aContent->IsInHTMLDocument() &&
aContent->IsHTML()) {
nsAutoString name;
mNodeInfo->NameAtom()->ToString(name);
nsAutoString lower;
ToLowerCase(name, lower);
nsCOMPtr<nsIAtom> nameAtom = do_GetAtom(lower);
nsString name;
mNodeInfo->GetName(name);
nsAutoString lowercaseName;
nsContentUtils::ASCIIToLower(name, lowercaseName);
nsCOMPtr<nsIAtom> nameAtom = do_GetAtom(lowercaseName);
nameAtom.swap(result);
} else {
nsCOMPtr<nsIAtom> nameAtom = mNodeInfo->NameAtom();

View File

@ -335,9 +335,7 @@ nsDOMAttributeMap::SetNamedItemInternal(nsIDOMNode *aNode,
else {
if (mContent->IsInHTMLDocument() &&
mContent->IsHTML()) {
nsAutoString lower;
ToLowerCase(name, lower);
name = lower;
nsContentUtils::ASCIIToLower(name);
}
rv = mContent->NodeInfo()->NodeInfoManager()->

View File

@ -632,27 +632,6 @@ nsDOMFileList::Item(PRUint32 aIndex, nsIDOMFile **aFile)
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////
// nsDOMFileError implementation
DOMCI_DATA(FileError, nsDOMFileError)
NS_INTERFACE_MAP_BEGIN(nsDOMFileError)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMFileError)
NS_INTERFACE_MAP_ENTRY(nsIDOMFileError)
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(FileError)
NS_INTERFACE_MAP_END
NS_IMPL_ADDREF(nsDOMFileError)
NS_IMPL_RELEASE(nsDOMFileError)
NS_IMETHODIMP
nsDOMFileError::GetCode(PRUint16* aCode)
{
*aCode = mCode;
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////
// nsDOMFileInternalUrlHolder implementation

View File

@ -255,7 +255,7 @@ nsDOMFileReader::GetResult(JSContext* aCx, jsval* aResult)
}
NS_IMETHODIMP
nsDOMFileReader::GetError(nsIDOMFileError** aError)
nsDOMFileReader::GetError(nsIDOMDOMError** aError)
{
return FileIOObject::GetError(aError);
}

View File

@ -54,7 +54,6 @@
#include "nsIDOMFile.h"
#include "nsIDOMFileReader.h"
#include "nsIDOMFileList.h"
#include "nsIDOMFileError.h"
#include "nsIInputStream.h"
#include "nsCOMPtr.h"
#include "nsIStreamLoader.h"

View File

@ -3247,6 +3247,14 @@ nsIDocument::TakeFrameRequestCallbacks(FrameRequestCallbackList& aCallbacks)
mFrameRequestCallbacks.Clear();
}
PLDHashOperator RequestDiscardEnumerator(imgIRequest* aKey,
PRUint32 aData,
void* userArg)
{
aKey->RequestDiscard();
return PL_DHASH_NEXT;
}
void
nsDocument::DeleteShell()
{
@ -3255,6 +3263,11 @@ nsDocument::DeleteShell()
RevokeAnimationFrameNotifications();
}
// When our shell goes away, request that all our images be immediately
// discarded, so we don't carry around decoded image data for a document we
// no longer intend to paint.
mImageTracker.EnumerateRead(RequestDiscardEnumerator, nsnull);
mPresShell = nsnull;
}
@ -4414,7 +4427,7 @@ nsDocument::CreateElement(const nsAString& aTagName,
bool needsLowercase = IsHTML() && !IsLowercaseASCII(aTagName);
nsAutoString lcTagName;
if (needsLowercase) {
ToLowerCase(aTagName, lcTagName);
nsContentUtils::ASCIIToLower(aTagName, lcTagName);
}
rv = CreateElem(needsLowercase ? lcTagName : aTagName,
@ -7724,14 +7737,20 @@ nsDocument::MaybePreLoadImage(nsIURI* uri, const nsAString &aCrossOriginAttr)
}
nsLoadFlags loadFlags = nsIRequest::LOAD_NORMAL;
if (aCrossOriginAttr.LowerCaseEqualsLiteral("anonymous")) {
switch (nsGenericElement::StringToCORSMode(aCrossOriginAttr)) {
case CORS_NONE:
// Nothing to do
break;
case CORS_ANONYMOUS:
loadFlags |= imgILoader::LOAD_CORS_ANONYMOUS;
} else if (aCrossOriginAttr.LowerCaseEqualsLiteral("use-credentials")) {
break;
case CORS_USE_CREDENTIALS:
loadFlags |= imgILoader::LOAD_CORS_USE_CREDENTIALS;
break;
default:
/* should never happen */
MOZ_NOT_REACHED("Unknown CORS mode!");
}
// else should we err on the side of not doing the preload if
// aCrossOriginAttr is nonempty? Let's err on the side of doing the
// preload as CORS_NONE.
// Image not in cache - trigger preload
nsCOMPtr<imgIRequest> request;
@ -8309,26 +8328,32 @@ nsDocument::RemoveImage(imgIRequest* aImage)
// If the count is now zero, remove from the tracker.
// Otherwise, set the new value.
if (count == 0) {
mImageTracker.Remove(aImage);
} else {
if (count != 0) {
mImageTracker.Put(aImage, count);
return NS_OK;
}
mImageTracker.Remove(aImage);
nsresult rv = NS_OK;
// If we removed the image from the tracker and we're locking images, unlock
// this image.
if (count == 0 && mLockingImages)
// Now that we're no longer tracking this image, unlock it if we'd
// previously locked it.
if (mLockingImages) {
rv = aImage->UnlockImage();
}
// If we removed the image from the tracker and we're animating images,
// remove our request to animate this image.
if (count == 0 && mAnimatingImages) {
// If we're animating images, remove our request to animate this one.
if (mAnimatingImages) {
nsresult rv2 = aImage->DecrementAnimationConsumers();
rv = NS_SUCCEEDED(rv) ? rv2 : rv;
}
// Request that the image be discarded if nobody else holds a lock on it.
// Do this even if !mLockingImages, because even if we didn't just unlock
// this image, it might still be a candidate for discarding.
aImage->RequestDiscard();
return rv;
}

View File

@ -159,6 +159,8 @@
#include "nsLayoutStatics.h"
#include "mozilla/Telemetry.h"
#include "mozilla/CORSMode.h"
using namespace mozilla;
using namespace mozilla::dom;
@ -2853,15 +2855,16 @@ nsGenericElement::GetAttributeNS(const nsAString& aNamespaceURI,
nsContentUtils::NameSpaceManager()->GetNameSpaceID(aNamespaceURI);
if (nsid == kNameSpaceID_Unknown) {
// Unknown namespace means no attr...
aReturn.Truncate();
// Unknown namespace means no attribute.
SetDOMStringToNull(aReturn);
return NS_OK;
}
nsCOMPtr<nsIAtom> name = do_GetAtom(aLocalName);
GetAttr(nsid, name, aReturn);
bool hasAttr = GetAttr(nsid, name, aReturn);
if (!hasAttr) {
SetDOMStringToNull(aReturn);
}
return NS_OK;
}
@ -6235,6 +6238,48 @@ nsGenericElement::SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf) const
mAttrsAndChildren.SizeOfExcludingThis(aMallocSizeOf);
}
static const nsAttrValue::EnumTable kCORSAttributeTable[] = {
// Order matters here
// See ParseCORSValue
{ "anonymous", CORS_ANONYMOUS },
{ "use-credentials", CORS_USE_CREDENTIALS },
{ 0 }
};
/* static */ void
nsGenericElement::ParseCORSValue(const nsAString& aValue,
nsAttrValue& aResult)
{
DebugOnly<bool> success =
aResult.ParseEnumValue(aValue, kCORSAttributeTable, false,
// default value is anonymous if aValue is
// not a value we understand
&kCORSAttributeTable[0]);
MOZ_ASSERT(success);
}
/* static */ CORSMode
nsGenericElement::StringToCORSMode(const nsAString& aValue)
{
if (aValue.IsVoid()) {
return CORS_NONE;
}
nsAttrValue val;
nsGenericElement::ParseCORSValue(aValue, val);
return CORSMode(val.GetEnumValue());
}
/* static */ CORSMode
nsGenericElement::AttrValueToCORSMode(const nsAttrValue* aValue)
{
if (!aValue) {
return CORS_NONE;
}
return CORSMode(aValue->GetEnumValue());
}
#define EVENT(name_, id_, type_, struct_) \
NS_IMETHODIMP nsINode::GetOn##name_(JSContext *cx, jsval *vp) { \
nsEventListenerManager *elm = GetListenerManager(false); \

View File

@ -65,6 +65,7 @@
#include "nsDOMClassInfoID.h" // DOMCI_DATA
#include "nsIDOMTouchEvent.h"
#include "nsIInlineEventHandlers.h"
#include "mozilla/CORSMode.h"
#include "nsISMILAttr.h"
@ -640,6 +641,25 @@ public:
void *aData);
static void MarkUserDataHandler(void* aObject, nsIAtom* aKey, void* aChild,
void* aData);
/**
* Parse a string into an nsAttrValue for a CORS attribute. This
* never fails. The resulting value is an enumerated value whose
* GetEnumValue() returns one of the above constants.
*/
static void ParseCORSValue(const nsAString& aValue, nsAttrValue& aResult);
/**
* Return the CORS mode for a given string
*/
static mozilla::CORSMode StringToCORSMode(const nsAString& aValue);
/**
* Return the CORS mode for a given nsAttrValue (which may be null,
* but if not should have been parsed via ParseCORSValue).
*/
static mozilla::CORSMode AttrValueToCORSMode(const nsAttrValue* aValue);
protected:
/*
* Named-bools for use with SetAttrAndNotify to make call sites easier to

View File

@ -2004,8 +2004,10 @@ GK_ATOM(setsize, "setsize")
GK_ATOM(tableCellIndex, "table-cell-index")
GK_ATOM(textAlign, "text-align")
GK_ATOM(textIndent, "text-indent")
GK_ATOM(textLineThroughColor, "text-line-through-color")
GK_ATOM(textLineThroughStyle, "text-line-through-style")
GK_ATOM(textPosition, "text-position")
GK_ATOM(textUnderlineColor, "text-underline-color")
GK_ATOM(textUnderlineStyle, "text-underline-style")
GK_ATOM(toolbarname, "toolbarname")
GK_ATOM(toolbarseparator, "toolbarseparator")

View File

@ -60,7 +60,7 @@
#include "nsThreadUtils.h"
#include "nsNetUtil.h"
#include "nsAsyncDOMEvent.h"
#include "nsGenericHTMLElement.h"
#include "nsGenericElement.h"
#include "nsIPresShell.h"
#include "nsEventStates.h"
@ -82,6 +82,8 @@
#include "mozAutoDocUpdate.h"
#include "mozilla/dom/Element.h"
using namespace mozilla;
#ifdef DEBUG_chb
static void PrintReqURL(imgIRequest* req) {
if (!req) {
@ -775,9 +777,9 @@ nsImageLoadingContent::LoadImage(nsIURI* aNewURI,
nsLoadFlags loadFlags = aLoadFlags;
PRInt32 corsmode = GetCORSMode();
if (corsmode == nsGenericHTMLElement::CORS_ANONYMOUS) {
if (corsmode == CORS_ANONYMOUS) {
loadFlags |= imgILoader::LOAD_CORS_ANONYMOUS;
} else if (corsmode == nsGenericHTMLElement::CORS_USE_CREDENTIALS) {
} else if (corsmode == CORS_USE_CREDENTIALS) {
loadFlags |= imgILoader::LOAD_CORS_USE_CREDENTIALS;
}
@ -1187,8 +1189,8 @@ nsImageLoadingContent::CreateStaticImageClone(nsImageLoadingContent* aDest) cons
aDest->mSuppressed = mSuppressed;
}
nsGenericHTMLElement::CORSMode
CORSMode
nsImageLoadingContent::GetCORSMode()
{
return nsGenericHTMLElement::CORS_NONE;
return CORS_NONE;
}

View File

@ -54,6 +54,7 @@
#include "nsString.h"
#include "nsEventStates.h"
#include "nsGenericHTMLElement.h"
#include "mozilla/CORSMode.h"
class nsIURI;
class nsIDocument;
@ -183,7 +184,7 @@ protected:
* Returns the CORS mode that will be used for all future image loads. The
* default implementation returns CORS_NONE unconditionally.
*/
virtual nsGenericHTMLElement::CORSMode GetCORSMode();
virtual mozilla::CORSMode GetCORSMode();
private:
/**

View File

@ -74,13 +74,17 @@
#include "nsChannelPolicy.h"
#include "nsCRT.h"
#include "nsContentCreatorFunctions.h"
#include "nsGenericElement.h"
#include "nsCrossSiteListenerProxy.h"
#include "mozilla/FunctionTimer.h"
#include "mozilla/CORSMode.h"
#ifdef PR_LOGGING
static PRLogModuleInfo* gCspPRLog;
#endif
using namespace mozilla;
using namespace mozilla::dom;
//////////////////////////////////////////////////////////////
@ -90,11 +94,14 @@ using namespace mozilla::dom;
class nsScriptLoadRequest : public nsISupports {
public:
nsScriptLoadRequest(nsIScriptElement* aElement,
PRUint32 aVersion)
PRUint32 aVersion,
CORSMode aCORSMode)
: mElement(aElement),
mLoading(true),
mIsInline(true),
mJSVersion(aVersion), mLineNo(1)
mJSVersion(aVersion),
mLineNo(1),
mCORSMode(aCORSMode)
{
}
@ -122,6 +129,7 @@ public:
nsCOMPtr<nsIURI> mURI;
nsCOMPtr<nsIPrincipal> mOriginPrincipal;
PRInt32 mLineNo;
const CORSMode mCORSMode;
};
// The nsScriptLoadRequest is passed as the context to necko, and thus
@ -293,7 +301,6 @@ nsScriptLoader::StartLoad(nsScriptLoadRequest *aRequest, const nsAString &aType)
}
nsCOMPtr<nsILoadGroup> loadGroup = mDocument->GetDocumentLoadGroup();
nsCOMPtr<nsIStreamLoader> loader;
nsCOMPtr<nsPIDOMWindow> window(do_QueryInterface(mDocument->GetScriptGlobalObject()));
if (!window) {
@ -332,10 +339,21 @@ nsScriptLoader::StartLoad(nsScriptLoadRequest *aRequest, const nsAString &aType)
httpChannel->SetReferrer(mDocument->GetDocumentURI());
}
nsCOMPtr<nsIStreamLoader> loader;
rv = NS_NewStreamLoader(getter_AddRefs(loader), this);
NS_ENSURE_SUCCESS(rv, rv);
rv = channel->AsyncOpen(loader, aRequest);
nsCOMPtr<nsIStreamListener> listener = loader.get();
if (aRequest->mCORSMode != CORS_NONE) {
bool withCredentials = (aRequest->mCORSMode == CORS_USE_CREDENTIALS);
listener =
new nsCORSListenerProxy(listener, mDocument->NodePrincipal(), channel,
withCredentials, &rv);
NS_ENSURE_SUCCESS(rv, rv);
}
rv = channel->AsyncOpen(listener, aRequest);
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
@ -551,6 +569,7 @@ nsScriptLoader::ProcessScriptElement(nsIScriptElement *aElement)
if (!scriptURI) {
return false;
}
CORSMode ourCORSMode = aElement->GetCORSMode();
nsTArray<PreloadInfo>::index_type i =
mPreloads.IndexOf(scriptURI.get(), 0, PreloadURIComparator());
if (i != nsTArray<PreloadInfo>::NoIndex) {
@ -565,7 +584,8 @@ nsScriptLoader::ProcessScriptElement(nsIScriptElement *aElement)
// the charset we have now.
nsAutoString elementCharset;
aElement->GetScriptCharset(elementCharset);
if (elementCharset.Equals(preloadCharset)) {
if (elementCharset.Equals(preloadCharset) &&
ourCORSMode == request->mCORSMode) {
rv = CheckContentPolicy(mDocument, aElement, request->mURI, type);
NS_ENSURE_SUCCESS(rv, false);
} else {
@ -576,7 +596,7 @@ nsScriptLoader::ProcessScriptElement(nsIScriptElement *aElement)
if (!request) {
// no usable preload
request = new nsScriptLoadRequest(aElement, version);
request = new nsScriptLoadRequest(aElement, version, ourCORSMode);
request->mURI = scriptURI;
request->mIsInline = false;
request->mLoading = true;
@ -697,7 +717,8 @@ nsScriptLoader::ProcessScriptElement(nsIScriptElement *aElement)
}
}
request = new nsScriptLoadRequest(aElement, version);
// Inline scripts ignore ther CORS mode and are always CORS_NONE
request = new nsScriptLoadRequest(aElement, version, CORS_NONE);
request->mJSVersion = version;
request->mLoading = false;
request->mIsInline = true;
@ -1228,9 +1249,14 @@ nsScriptLoader::PrepareLoadedRequest(nsScriptLoadRequest* aRequest,
}
nsCOMPtr<nsIChannel> channel = do_QueryInterface(req);
rv = nsContentUtils::GetSecurityManager()->
GetChannelPrincipal(channel, getter_AddRefs(aRequest->mOriginPrincipal));
NS_ENSURE_SUCCESS(rv, rv);
// If this load was subject to a CORS check; don't flag it with a
// separate origin principal, so that it will treat our document's
// principal as the origin principal
if (aRequest->mCORSMode == CORS_NONE) {
rv = nsContentUtils::GetSecurityManager()->
GetChannelPrincipal(channel, getter_AddRefs(aRequest->mOriginPrincipal));
NS_ENSURE_SUCCESS(rv, rv);
}
if (aStringLen) {
// Check the charset attribute to determine script charset.
@ -1325,14 +1351,17 @@ nsScriptLoader::ParsingComplete(bool aTerminated)
void
nsScriptLoader::PreloadURI(nsIURI *aURI, const nsAString &aCharset,
const nsAString &aType)
const nsAString &aType,
const nsAString &aCrossOrigin)
{
// Check to see if scripts has been turned off.
if (!mEnabled || !mDocument->IsScriptEnabled()) {
return;
}
nsRefPtr<nsScriptLoadRequest> request = new nsScriptLoadRequest(nsnull, 0);
nsRefPtr<nsScriptLoadRequest> request =
new nsScriptLoadRequest(nsnull, 0,
nsGenericElement::StringToCORSMode(aCrossOrigin));
request->mURI = aURI;
request->mIsInline = false;
request->mLoading = true;

View File

@ -238,9 +238,12 @@ public:
* @param aURI The URI of the external script.
* @param aCharset The charset parameter for the script.
* @param aType The type parameter for the script.
* @param aCrossOrigin The crossorigin attribute for the script.
* Void if not present.
*/
virtual void PreloadURI(nsIURI *aURI, const nsAString &aCharset,
const nsAString &aType);
const nsAString &aType,
const nsAString &aCrossOrigin);
private:
/**

View File

@ -185,7 +185,7 @@ PRUint32 nsStyleLinkElement::ParseLinkTypes(const nsAString& aTypes)
while (current != done) {
if (nsContentUtils::IsHTMLWhitespace(*current)) {
if (inString) {
ToLowerCase(Substring(start, current), subString);
nsContentUtils::ASCIIToLower(Substring(start, current), subString);
linkMask |= ToLinkMask(subString);
inString = false;
}
@ -199,8 +199,8 @@ PRUint32 nsStyleLinkElement::ParseLinkTypes(const nsAString& aTypes)
++current;
}
if (inString) {
ToLowerCase(Substring(start, current), subString);
linkMask |= ToLinkMask(subString);
nsContentUtils::ASCIIToLower(Substring(start, current), subString);
linkMask |= ToLinkMask(subString);
}
return linkMask;
}

View File

@ -562,6 +562,11 @@ _TEST_FILES2 = \
test_bug726364.html \
test_bug698381.html \
test_bug711047.html \
test_bug696301-1.html \
test_bug696301-2.html \
bug696301-script-1.js \
bug696301-script-1.js^headers^ \
bug696301-script-2.js \
$(NULL)
_CHROME_FILES = \

View File

@ -0,0 +1,3 @@
var a = 0;
var global = "ran";
c();

View File

@ -0,0 +1 @@
Access-Control-Allow-Origin: *

View File

@ -0,0 +1,3 @@
var a = 0;
var global = "ran";
c();

View File

@ -0,0 +1,78 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=696301
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 696301</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=696301">Mozilla Bug 696301</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript">
var errorFired = false;
var global = "";
window.onerror = function(message, uri, line) {
is(message, "Script error.", "Should have empty error message");
is(uri,
"http://example.com/tests/content/base/test/bug696301-script-1.js",
"Should have correct script URI");
is(line, 0, "Shouldn't have a line here");
errorFired = true;
}
</script>
<script src="http://example.com/tests/content/base/test/bug696301-script-1.js"></script>
<script>
is(errorFired, true, "Should have error in different origin script");
is(global, "ran", "Different origin script should have run");
</script>
<script type="application/javascript">
errorFired = false;
global = "";
window.onerror = function(message, uri, line) {
is(message, "c is not defined", "Should have correct error message");
is(uri,
"http://example.com/tests/content/base/test/bug696301-script-1.js",
"Should also have correct script URI");
is(line, 3, "Should have a line here");
errorFired = true;
}
</script>
<script src="http://example.com/tests/content/base/test/bug696301-script-1.js"
crossorigin></script>
<script>
is(errorFired, true, "Should have error in different origin script with CORS");
is(global, "ran", "Different origin script with CORS should have run");
</script>
<script type="application/javascript">
errorFired = false;
global = "";
window.onerror = function(message, uri, line) {
is(message, "Error loading script", "Should have correct error message");
is(uri,
"http://example.com/tests/content/base/test/bug696301-script-2.js",
"Should still have correct script URI even when failing CORS");
is(line, 1, "Load failures seem to count as line 1");
errorFired = true;
}
</script>
<script src="http://example.com/tests/content/base/test/bug696301-script-2.js"
crossorigin></script>
<script>
is(errorFired, true,
"Should have error when different origin script fails CORS check");
is(global, "", "Different origin script that fails CORS should not have run");
</script>
</pre>
</body>
</html>

View File

@ -0,0 +1,80 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=696301
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 696301</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=696301">Mozilla Bug 696301</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<!-- Test SVG script here -->
<svg>
<script type="application/javascript">
var errorFired = false;
var global = "";
window.onerror = function(message, uri, line) {
is(message, "Script error.", "Should have empty error message");
is(uri,
"http://example.com/tests/content/base/test/bug696301-script-1.js",
"Should have correct script URI");
is(line, 0, "Shouldn't have a line here");
errorFired = true;
}
</script>
<script xlink:href="http://example.com/tests/content/base/test/bug696301-script-1.js"></script>
<script>
is(errorFired, true, "Should have error in different origin script");
is(global, "ran", "Different origin script should have run");
</script>
<script type="application/javascript">
errorFired = false;
global = "";
window.onerror = function(message, uri, line) {
is(message, "c is not defined", "Should have correct error message");
is(uri,
"http://example.com/tests/content/base/test/bug696301-script-1.js",
"Should also have correct script URI");
is(line, 3, "Should have a line here");
errorFired = true;
}
</script>
<script xlink:href="http://example.com/tests/content/base/test/bug696301-script-1.js"
crossorigin></script>
<script>
is(errorFired, true, "Should have error in different origin script with CORS");
is(global, "ran", "Different origin script with CORS should have run");
</script>
<script type="application/javascript">
errorFired = false;
global = "";
window.onerror = function(message, uri, line) {
is(message, "Error loading script", "Should have correct error message");
is(uri,
"http://example.com/tests/content/base/test/bug696301-script-2.js",
"Should still have correct script URI even when failing CORS");
is(line, 1, "Load failures seem to count as line 1");
errorFired = true;
}
</script>
<script xlink:href="http://example.com/tests/content/base/test/bug696301-script-2.js"
crossorigin></script>
<script>
is(errorFired, true,
"Should have error when different origin script fails CORS check");
is(global, "", "Different origin script that fails CORS should not have run");
</script>
</svg>
</pre>
</body>
</html>

View File

@ -3,4 +3,5 @@ load 421715-1.html
load 553938-1.html
load 647480.html
load 0px-size-font-667225.html
load texImage2D.html
load 729116.html

View File

@ -0,0 +1,8 @@
<!doctype html>
<canvas></canvas>
<script>
var canvas = document.body.firstChild,
gl = canvas.getContext("experimental-webgl");
gl.texImage2D(0, 0, 0, 0, 0, { get width() { throw 7 }, get height() { throw 7 }, data: new Uint8ClampedArray(10) });
gl.texSubImage2D(0, 0, 0, 0, 0, 0, { get width() { throw 7 }, get height() { throw 7 }, data: new Uint8ClampedArray(10) });
</script>

View File

@ -382,6 +382,133 @@ nsIDOMWebGLRenderingContext_ReadPixels(JSContext *cx, unsigned argc, jsval *vp)
}
class CallTexImage2D
{
private:
nsIDOMWebGLRenderingContext* self;
WebGLenum target;
WebGLint level;
WebGLenum internalformat;
WebGLenum format;
WebGLenum type;
public:
explicit CallTexImage2D(nsIDOMWebGLRenderingContext* aSelf,
WebGLenum aTarget,
WebGLint aLevel,
WebGLenum aInternalformat,
WebGLenum aFormat,
WebGLenum aType)
: self(aSelf)
, target(aTarget)
, level(aLevel)
, internalformat(aInternalformat)
, format(aFormat)
, type(aType)
{}
nsresult DoCallForImageData(WebGLsizei width, WebGLsizei height,
JSObject* pixels)
{
return self->TexImage2D_imageData(target, level, internalformat, width,
height, 0, format, type, pixels);
}
nsresult DoCallForElement(mozilla::dom::Element* elt)
{
return self->TexImage2D_dom(target, level, internalformat, format, type,
elt);
}
};
class CallTexSubImage2D
{
private:
nsIDOMWebGLRenderingContext* self;
WebGLenum target;
WebGLint level;
WebGLint xoffset;
WebGLint yoffset;
WebGLenum format;
WebGLenum type;
public:
explicit CallTexSubImage2D(nsIDOMWebGLRenderingContext* aSelf,
WebGLenum aTarget,
WebGLint aLevel,
WebGLint aXoffset,
WebGLint aYoffset,
WebGLenum aFormat,
WebGLenum aType)
: self(aSelf)
, target(aTarget)
, level(aLevel)
, xoffset(aXoffset)
, yoffset(aYoffset)
, format(aFormat)
, type(aType)
{}
nsresult DoCallForImageData(WebGLsizei width, WebGLsizei height,
JSObject* pixels)
{
return self->TexSubImage2D_imageData(target, level, xoffset, yoffset,
width, height, format, type,
pixels);
}
nsresult DoCallForElement(mozilla::dom::Element* elt)
{
return self->TexSubImage2D_dom(target, level, xoffset, yoffset, format,
type, elt);
}
};
template<class T>
static bool
TexImage2DImageDataOrElement(JSContext* cx, T& self, JS::Value* object)
{
MOZ_ASSERT(object && object->isObject());
nsGenericElement* elt;
xpc_qsSelfRef eltRef;
if (NS_SUCCEEDED(xpc_qsUnwrapArg<nsGenericElement>(
cx, *object, &elt, &eltRef.ptr, object))) {
nsresult rv = self.DoCallForElement(elt);
return NS_SUCCEEDED(rv) || xpc_qsThrow(cx, rv);
}
// Failed to interpret object as an Element, now try to interpret it as
// ImageData.
JSObject* imageData = &object->toObject();
jsval js_width, js_height, js_data;
if (!JS_GetProperty(cx, imageData, "width", &js_width) ||
!JS_GetProperty(cx, imageData, "height", &js_height) ||
!JS_GetProperty(cx, imageData, "data", &js_data)) {
return false;
}
if (js_width == JSVAL_VOID ||
js_height == JSVAL_VOID ||
!js_data.isObject())
{
return xpc_qsThrow(cx, NS_ERROR_FAILURE);
}
int32_t int_width, int_height;
JSObject *obj_data = JSVAL_TO_OBJECT(js_data);
if (!JS_ValueToECMAInt32(cx, js_width, &int_width) ||
!JS_ValueToECMAInt32(cx, js_height, &int_height))
{
return false;
}
if (!js_IsTypedArray(obj_data))
{
return xpc_qsThrow(cx, NS_ERROR_FAILURE);
}
nsresult rv = self.DoCallForImageData(int_width, int_height, obj_data);
return NS_SUCCEEDED(rv) || xpc_qsThrow(cx, rv);
}
/*
* TexImage2D takes:
* TexImage2D(uint, int, uint, int, int, int, uint, uint, ArrayBufferView)
@ -412,65 +539,21 @@ nsIDOMWebGLRenderingContext_TexImage2D(JSContext *cx, unsigned argc, jsval *vp)
// arguments common to all cases
GET_UINT32_ARG(argv0, 0);
GET_INT32_ARG(argv1, 1);
GET_UINT32_ARG(argv2, 2);
if (argc > 5 &&
!JSVAL_IS_PRIMITIVE(argv[5]))
{
if (argc > 5 && !JSVAL_IS_PRIMITIVE(argv[5])) {
// implement the variants taking a DOMElement as argv[5]
GET_UINT32_ARG(argv2, 2);
GET_UINT32_ARG(argv3, 3);
GET_UINT32_ARG(argv4, 4);
nsIDOMElement *elt;
xpc_qsSelfRef eltRef;
rv = xpc_qsUnwrapArg<nsIDOMElement>(cx, argv[5], &elt, &eltRef.ptr, &argv[5]);
if (NS_FAILED(rv)) return JS_FALSE;
rv = self->TexImage2D_dom(argv0, argv1, argv2, argv3, argv4, elt);
// NS_ERROR_DOM_SECURITY_ERR indicates we tried to load a cross-domain element, so
// bail out immediately, don't try to interprete as ImageData
if (rv == NS_ERROR_DOM_SECURITY_ERR) {
xpc_qsThrowBadArg(cx, rv, vp, 5);
return JS_FALSE;
CallTexImage2D selfCaller(self, argv0, argv1, argv2, argv3, argv4);
if (!TexImage2DImageDataOrElement(cx, selfCaller, argv + 5)) {
return false;
}
if (NS_FAILED(rv)) {
// failed to interprete argv[5] as a DOMElement, now try to interprete it as ImageData
JSObject *argv5 = JSVAL_TO_OBJECT(argv[5]);
jsval js_width, js_height, js_data;
JS_GetProperty(cx, argv5, "width", &js_width);
JS_GetProperty(cx, argv5, "height", &js_height);
JS_GetProperty(cx, argv5, "data", &js_data);
if (js_width == JSVAL_VOID ||
js_height == JSVAL_VOID ||
!js_data.isObject())
{
xpc_qsThrowBadArg(cx, NS_ERROR_FAILURE, vp, 5);
return JS_FALSE;
}
int32_t int_width, int_height;
JSObject *obj_data = JSVAL_TO_OBJECT(js_data);
if (!JS_ValueToECMAInt32(cx, js_width, &int_width) ||
!JS_ValueToECMAInt32(cx, js_height, &int_height))
{
return JS_FALSE;
}
if (!js_IsTypedArray(obj_data))
{
xpc_qsThrowBadArg(cx, NS_ERROR_FAILURE, vp, 5);
return JS_FALSE;
}
rv = self->TexImage2D_imageData(argv0, argv1, argv2,
int_width, int_height, 0,
argv3, argv4, js::TypedArray::getTypedArray(obj_data));
}
} else if (argc > 8 &&
JSVAL_IS_OBJECT(argv[8])) // here, we allow null !
{
rv = NS_OK;
} else if (argc > 8 && JSVAL_IS_OBJECT(argv[8])) {
// here, we allow null !
// implement the variants taking a buffer/array as argv[8]
GET_UINT32_ARG(argv2, 2);
GET_INT32_ARG(argv3, 3);
GET_INT32_ARG(argv4, 4);
GET_INT32_ARG(argv5, 5);
@ -536,61 +619,17 @@ nsIDOMWebGLRenderingContext_TexSubImage2D(JSContext *cx, unsigned argc, jsval *v
GET_INT32_ARG(argv2, 2);
GET_INT32_ARG(argv3, 3);
if (argc > 6 &&
!JSVAL_IS_PRIMITIVE(argv[6]))
{
// implement the variants taking a DOMElement as argv[6]
if (argc > 6 && !JSVAL_IS_PRIMITIVE(argv[6])) {
// implement the variants taking a DOMElement or an ImageData as argv[6]
GET_UINT32_ARG(argv4, 4);
GET_UINT32_ARG(argv5, 5);
nsIDOMElement *elt;
xpc_qsSelfRef eltRef;
rv = xpc_qsUnwrapArg<nsIDOMElement>(cx, argv[6], &elt, &eltRef.ptr, &argv[6]);
if (NS_FAILED(rv)) return JS_FALSE;
rv = self->TexSubImage2D_dom(argv0, argv1, argv2, argv3, argv4, argv5, elt);
// NS_ERROR_DOM_SECURITY_ERR indicates we tried to load a cross-domain element, so
// bail out immediately, don't try to interprete as ImageData
if (rv == NS_ERROR_DOM_SECURITY_ERR) {
xpc_qsThrowBadArg(cx, rv, vp, 6);
return JS_FALSE;
CallTexSubImage2D selfCaller(self, argv0, argv1, argv2, argv3, argv4, argv5);
if (!TexImage2DImageDataOrElement(cx, selfCaller, argv + 6)) {
return false;
}
if (NS_FAILED(rv)) {
// failed to interprete argv[6] as a DOMElement, now try to interprete it as ImageData
JSObject *argv6 = JSVAL_TO_OBJECT(argv[6]);
jsval js_width, js_height, js_data;
JS_GetProperty(cx, argv6, "width", &js_width);
JS_GetProperty(cx, argv6, "height", &js_height);
JS_GetProperty(cx, argv6, "data", &js_data);
if (js_width == JSVAL_VOID ||
js_height == JSVAL_VOID ||
!js_data.isObject())
{
xpc_qsThrowBadArg(cx, NS_ERROR_FAILURE, vp, 6);
return JS_FALSE;
}
int32_t int_width, int_height;
JSObject *obj_data = JSVAL_TO_OBJECT(js_data);
if (!JS_ValueToECMAInt32(cx, js_width, &int_width) ||
!JS_ValueToECMAInt32(cx, js_height, &int_height))
{
return JS_FALSE;
}
if (!js_IsTypedArray(obj_data))
{
xpc_qsThrowBadArg(cx, NS_ERROR_FAILURE, vp, 6);
return JS_FALSE;
}
rv = self->TexSubImage2D_imageData(argv0, argv1, argv2, argv3,
int_width, int_height,
argv4, argv5,
js::TypedArray::getTypedArray(obj_data));
}
} else if (argc > 8 &&
!JSVAL_IS_PRIMITIVE(argv[8]))
{
rv = NS_OK;
} else if (argc > 8 && !JSVAL_IS_PRIMITIVE(argv[8])) {
// implement the variants taking a buffer/array as argv[8]
GET_INT32_ARG(argv4, 4);
GET_INT32_ARG(argv5, 5);

View File

@ -815,7 +815,7 @@ protected:
int dstFormat, bool dstPremultiplied,
size_t dstTexelSize);
nsresult DOMElementToImageSurface(nsIDOMElement *imageOrCanvas,
nsresult DOMElementToImageSurface(dom::Element* imageOrCanvas,
gfxImageSurface **imageOut,
int *format);

View File

@ -70,6 +70,7 @@
#endif
using namespace mozilla;
using namespace mozilla::dom;
static bool BaseTypeAndSizeFromUniformType(WebGLenum uType, WebGLenum *baseType, WebGLint *unitSize);
static WebGLenum InternalFormatForFormatAndType(WebGLenum format, WebGLenum type, bool isGLES2);
@ -3966,11 +3967,10 @@ WebGLContext::ConvertImage(size_t width, size_t height, size_t srcStride, size_t
}
nsresult
WebGLContext::DOMElementToImageSurface(nsIDOMElement *imageOrCanvas,
WebGLContext::DOMElementToImageSurface(Element* imageOrCanvas,
gfxImageSurface **imageOut, int *format)
{
nsCOMPtr<nsIContent> content = do_QueryInterface(imageOrCanvas);
if (!content) {
if (!imageOrCanvas) {
return NS_ERROR_FAILURE;
}
@ -3984,7 +3984,7 @@ WebGLContext::DOMElementToImageSurface(nsIDOMElement *imageOrCanvas,
flags |= nsLayoutUtils::SFE_NO_PREMULTIPLY_ALPHA;
nsLayoutUtils::SurfaceFromElementResult res =
nsLayoutUtils::SurfaceFromElement(content->AsElement(), flags);
nsLayoutUtils::SurfaceFromElement(imageOrCanvas, flags);
if (!res.mSurface)
return NS_ERROR_FAILURE;
if (res.mSurface->GetType() != gfxASurface::SurfaceTypeImage) {
@ -4016,7 +4016,7 @@ WebGLContext::DOMElementToImageSurface(nsIDOMElement *imageOrCanvas,
// part 2: if the DOM element is a canvas, check that it's not write-only.
// That would indicate a tainted canvas, i.e. a canvas that could contain
// cross-domain image data.
if (nsHTMLCanvasElement* canvas = nsHTMLCanvasElement::FromContent(content)) {
if (nsHTMLCanvasElement* canvas = nsHTMLCanvasElement::FromContent(imageOrCanvas)) {
if (canvas->IsWriteOnly()) {
LogMessageIfVerbose("The canvas used as source for texImage2D here is tainted (write-only). It is forbidden "
"to load a WebGL texture from a tainted canvas. A Canvas becomes tainted for example "
@ -5082,7 +5082,7 @@ WebGLContext::TexImage2D_imageData(WebGLenum target, WebGLint level, WebGLenum i
NS_IMETHODIMP
WebGLContext::TexImage2D_dom(WebGLenum target, WebGLint level, WebGLenum internalformat,
WebGLenum format, GLenum type, nsIDOMElement *elt)
WebGLenum format, GLenum type, Element* elt)
{
if (!IsContextStable())
return NS_OK;
@ -5272,7 +5272,7 @@ NS_IMETHODIMP
WebGLContext::TexSubImage2D_dom(WebGLenum target, WebGLint level,
WebGLint xoffset, WebGLint yoffset,
WebGLenum format, WebGLenum type,
nsIDOMElement *elt)
Element *elt)
{
if (!IsContextStable())
return NS_OK;

View File

@ -7591,7 +7591,7 @@ ok(!_thrown_outer, ctx.canvas.id + ' should not throw exception');
<!-- [[[ test_2d.imageData.create.type.html ]]] -->
<p>Canvas test: 2d.imageData.create.type - bug 433004</p>
<!-- Testing: createImageData() returns an ImageData object containing a CanvasPixelArray object -->
<!-- Testing: createImageData() returns an ImageData object containing a Uint8ClampedArray object -->
<canvas id="c261" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
<script>
@ -7604,12 +7604,12 @@ var _thrown_outer = false;
try {
todo(window.ImageData !== undefined, "window.ImageData !== undefined");
todo(window.CanvasPixelArray !== undefined, "window.CanvasPixelArray !== undefined");
ok(window.Uint8ClampedArray !== undefined, "window.Uint8ClampedArray !== undefined");
window.ImageData.prototype.thisImplementsImageData = true;
window.CanvasPixelArray.prototype.thisImplementsCanvasPixelArray = true;
window.Uint8ClampedArray.prototype.thisImplementsUint8ClampedArray = true;
var imgdata = ctx.createImageData(1, 1);
ok(imgdata.thisImplementsImageData, "imgdata.thisImplementsImageData");
ok(imgdata.data.thisImplementsCanvasPixelArray, "imgdata.data.thisImplementsCanvasPixelArray");
ok(imgdata.data.thisImplementsUint8ClampedArray, "imgdata.data.thisImplementsUint8ClampedArray");
} catch (e) {
_thrown_outer = true;
@ -7623,7 +7623,7 @@ todo(!_thrown_outer, ctx.canvas.id + ' should not throw exception');
<!-- [[[ test_2d.imageData.create1.type.html ]]] -->
<p>Canvas test: 2d.imageData.create1.type - bug 630040</p>
<!-- Testing: createImageData(imgdata) returns an ImageData object containing a CanvasPixelArray object -->
<!-- Testing: createImageData(imgdata) returns an ImageData object containing a Uint8ClampedArray object -->
<canvas id="c261a" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
<script>
@ -7636,12 +7636,12 @@ var _thrown_outer = false;
try {
todo(window.ImageData !== undefined, "window.ImageData !== undefined");
todo(window.CanvasPixelArray !== undefined, "window.CanvasPixelArray !== undefined");
ok(window.Uint8ClampedArray !== undefined, "window.Uint8ClampedArray !== undefined");
window.ImageData.prototype.thisImplementsImageData = true;
window.CanvasPixelArray.prototype.thisImplementsCanvasPixelArray = true;
window.Uint8ClampedArray.prototype.thisImplementsUint8ClampedArray = true;
var imgdata = ctx.createImageData(ctx.createImageData(1, 1));
todo(imgdata.thisImplementsImageData, "imgdata.thisImplementsImageData");
todo(imgdata.data.thisImplementsCanvasPixelArray, "imgdata.data.thisImplementsCanvasPixelArray");
ok(imgdata.data.thisImplementsUint8ClampedArray, "imgdata.data.thisImplementsUint8ClampedArray");
} catch (e) {
_thrown_outer = true;
@ -8229,7 +8229,7 @@ ok(!_thrown_outer, ctx.canvas.id + ' should not throw exception');
<!-- [[[ test_2d.imageData.get.type.html ]]] -->
<p>Canvas test: 2d.imageData.get.type</p>
<!-- Testing: getImageData() returns an ImageData object containing a CanvasPixelArray object -->
<!-- Testing: getImageData() returns an ImageData object containing a Uint8ClampedArray object -->
<canvas id="c276" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
<script>
@ -8242,12 +8242,12 @@ var _thrown_outer = false;
try {
todo(window.ImageData !== undefined, "window.ImageData !== undefined");
todo(window.CanvasPixelArray !== undefined, "window.CanvasPixelArray !== undefined");
ok(window.Uint8ClampedArray !== undefined, "window.Uint8ClampedArray !== undefined");
window.ImageData.prototype.thisImplementsImageData = true;
window.CanvasPixelArray.prototype.thisImplementsCanvasPixelArray = true;
window.Uint8ClampedArray.prototype.thisImplementsUint8ClampedArray = true;
var imgdata = ctx.getImageData(0, 0, 1, 1);
ok(imgdata.thisImplementsImageData, "imgdata.thisImplementsImageData");
ok(imgdata.data.thisImplementsCanvasPixelArray, "imgdata.data.thisImplementsCanvasPixelArray");
ok(imgdata.data.thisImplementsUint8ClampedArray, "imgdata.data.thisImplementsUint8ClampedArray");
} catch (e) {
_thrown_outer = true;

View File

@ -6,5 +6,6 @@ load 457776-1.html
load 496308-1.html
load 682637-1.html
load eventctor-nulldictionary.html
load eventctor-nullstorage.html
load recursive-onload.html
load recursive-DOMNodeInserted.html

View File

@ -0,0 +1,4 @@
<!DOCTYPE html>
<script>
new StorageEvent("").storageArea;
</script>

View File

@ -50,6 +50,7 @@
#include "nsIObserver.h"
#include "nsAudioStream.h"
#include "VideoFrameContainer.h"
#include "mozilla/CORSMode.h"
// Define to output information on decoding and painting framerate
/* #define DEBUG_FRAME_RATE 1 */
@ -71,7 +72,7 @@ public:
CANPLAY_YES
};
CORSMode GetCORSMode() {
mozilla::CORSMode GetCORSMode() {
return mCORSMode;
}
@ -781,7 +782,7 @@ protected:
bool mMediaSecurityVerified;
// The CORS mode when loading the media element
CORSMode mCORSMode;
mozilla::CORSMode mCORSMode;
};
#endif

View File

@ -2488,24 +2488,25 @@ nsGenericHTMLElement::GetContentEditable(nsAString& aContentEditable)
nsresult
nsGenericHTMLElement::SetContentEditable(const nsAString& aContentEditable)
{
nsString contentEditable;
ToLowerCase(aContentEditable, contentEditable);
if (contentEditable.EqualsLiteral("inherit")) {
if (nsContentUtils::EqualsLiteralIgnoreASCIICase(aContentEditable, "inherit")) {
UnsetAttr(kNameSpaceID_None, nsGkAtoms::contenteditable, true);
return NS_OK;
}
if (!contentEditable.EqualsLiteral("true") &&
!contentEditable.EqualsLiteral("false")) {
return NS_ERROR_DOM_SYNTAX_ERR;
if (nsContentUtils::EqualsLiteralIgnoreASCIICase(aContentEditable, "true")) {
SetAttr(kNameSpaceID_None, nsGkAtoms::contenteditable, NS_LITERAL_STRING("true"), true);
return NS_OK;
}
if (nsContentUtils::EqualsLiteralIgnoreASCIICase(aContentEditable, "false")) {
SetAttr(kNameSpaceID_None, nsGkAtoms::contenteditable, NS_LITERAL_STRING("false"), true);
return NS_OK;
}
SetAttr(kNameSpaceID_None, nsGkAtoms::contenteditable, contentEditable,
true);
return NS_OK;
return NS_ERROR_DOM_SYNTAX_ERR;
}
nsresult
@ -2886,14 +2887,6 @@ nsGenericHTMLFormElement::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
return nsGenericHTMLElement::PreHandleEvent(aVisitor);
}
const nsAttrValue::EnumTable nsGenericHTMLElement::kCORSAttributeTable[] = {
// Order matters here
// See ParseAttribute in nsHTMLImageElement or nsHTMLMediaElement
{ "anonymous", nsGenericHTMLElement::CORS_ANONYMOUS },
{ "use-credentials", nsGenericHTMLElement::CORS_USE_CREDENTIALS },
{ 0 }
};
/* virtual */
bool
nsGenericHTMLFormElement::IsDisabled() const

View File

@ -530,7 +530,7 @@ public:
* Returns the current disabled state of the element.
*/
virtual bool IsDisabled() const {
return HasAttr(kNameSpaceID_None, nsGkAtoms::disabled);
return false;
}
bool IsHidden() const
@ -538,32 +538,6 @@ public:
return HasAttr(kNameSpaceID_None, nsGkAtoms::hidden);
}
/**
* Shared cross-origin resource sharing attributes so they don't get
* duplicated on every CORS-enabled element
*/
enum CORSMode {
/**
* The default of not using CORS to validate cross-origin loads.
*/
CORS_NONE,
/**
* Validate cross-site loads using CORS, but do not send any credentials
* (cookies, HTTP auth logins, etc) along with the request.
*/
CORS_ANONYMOUS,
/**
* Validate cross-site loads using CORS, and send credentials such as cookies
* and HTTP auth logins along with the request.
*/
CORS_USE_CREDENTIALS
};
const static nsAttrValue::EnumTable kCORSAttributeTable[];
protected:
/**
* Add/remove this element to the documents name cache

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