This commit is contained in:
Kartikaya Gupta 2012-03-12 10:41:42 -04:00
Родитель 44d9673164 c409d78680
Коммит 60f5962bb6
189 изменённых файлов: 3377 добавлений и 1649 удалений

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

@ -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

Просмотреть файл

@ -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

Просмотреть файл

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

Просмотреть файл

@ -269,13 +269,19 @@
attrs = {}; attrs = {};
testTextAttrs(ID, 84, attrs, defAttrs, 83, 91); 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); testTextAttrs(ID, 92, attrs, defAttrs, 91, 101);
attrs = {}; attrs = {};
testTextAttrs(ID, 102, attrs, defAttrs, 101, 109); 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); testTextAttrs(ID, 110, attrs, defAttrs, 109, 122);
attrs = {}; attrs = {};
@ -323,13 +329,19 @@
attrs = {}; attrs = {};
testTextAttrs(ID, 85, attrs, defAttrs, 84, 92); 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); testTextAttrs(ID, 93, attrs, defAttrs, 92, 102);
attrs = {}; attrs = {};
testTextAttrs(ID, 103, attrs, defAttrs, 102, 110); 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); testTextAttrs(ID, 111, attrs, defAttrs, 110, 123);
attrs = {}; attrs = {};
@ -437,6 +449,48 @@
attrs = { }; attrs = { };
testTextAttrs(ID, 31, attrs, defAttrs, 31, 45); 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(); SimpleTest.finish();
} }
@ -450,12 +504,17 @@
href="https://bugzilla.mozilla.org/show_bug.cgi?id=345759" href="https://bugzilla.mozilla.org/show_bug.cgi?id=345759"
title="Implement text attributes"> title="Implement text attributes">
Mozilla Bug 345759 Mozilla Bug 345759
</a><br> </a>
<a target="_blank" <a target="_blank"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=473576" href="https://bugzilla.mozilla.org/show_bug.cgi?id=473576"
title="font-family text attribute should expose actual font used"> title="font-family text attribute should expose actual font used">
Mozilla Bug 473576 Mozilla Bug 473576
</a> </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> <p id="display"></p>
<div id="content" style="display: none"></div> <div id="content" style="display: none"></div>
<pre id="test"> <pre id="test">
@ -546,5 +605,15 @@
<span style="font-family: Comic Sans MS, cursive;">text</span>text <span style="font-family: Comic Sans MS, cursive;">text</span>text
<span style="font-family: sans-serif, fantasy;">text</span>text <span style="font-family: sans-serif, fantasy;">text</span>text
</p> </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> </body>
</html> </html>

Просмотреть файл

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

Просмотреть файл

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

0
browser/base/content/global-scripts.inc Normal file → Executable file
Просмотреть файл

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

@ -45,10 +45,29 @@
<!ENTITY % debuggerDTD SYSTEM "chrome://browser/locale/devtools/debugger.dtd" > <!ENTITY % debuggerDTD SYSTEM "chrome://browser/locale/devtools/debugger.dtd" >
%debuggerDTD; %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" <xul:window xmlns="http://www.w3.org/1999/xhtml"
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> 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.js"/>
<xul:script type="text/javascript" src="debugger-view.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"> <div id="body" class="vbox flex">
<xul:toolbar id="dbg-toolbar"> <xul:toolbar id="dbg-toolbar">

Просмотреть файл

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

Просмотреть файл

@ -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;
});
}

Просмотреть файл

@ -10,7 +10,7 @@ browser.jar:
content/browser/devtools/cssruleview.xul (styleinspector/cssruleview.xul) content/browser/devtools/cssruleview.xul (styleinspector/cssruleview.xul)
content/browser/devtools/styleinspector.css (styleinspector/styleinspector.css) content/browser/devtools/styleinspector.css (styleinspector/styleinspector.css)
content/browser/orion.js (sourceeditor/orion/orion.js) 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.xul (debugger/debugger.xul)
content/browser/debugger.css (debugger/debugger.css) content/browser/debugger.css (debugger/debugger.css)
content/browser/debugger.js (debugger/debugger.js) content/browser/debugger.js (debugger/debugger.js)

Просмотреть файл

@ -111,21 +111,6 @@
modifiers="accel"/> 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 id="sp-key-run"
key="&run.key;" key="&run.key;"
command="sp-cmd-run" command="sp-cmd-run"
@ -146,28 +131,6 @@
key="&webConsoleCmd.commandkey;" key="&webConsoleCmd.commandkey;"
command="sp-cmd-webConsole" command="sp-cmd-webConsole"
modifiers="accel,shift"/> 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" <key id="key_openHelp"
keycode="VK_F1" keycode="VK_F1"
command="sp-cmd-documentationLink"/> command="sp-cmd-documentationLink"/>
@ -219,56 +182,20 @@
<menu id="sp-edit-menu" label="&editMenu.label;" <menu id="sp-edit-menu" label="&editMenu.label;"
accesskey="&editMenu.accesskey;"> accesskey="&editMenu.accesskey;">
<menupopup id="sp-menu_editpopup" <menupopup id="sp-menu_editpopup"
onpopupshowing="goUpdateGlobalEditMenuItems()"> onpopupshowing="goUpdateSourceEditorMenuItems()">
<menuitem id="sp-menu-undo" <menuitem id="se-menu-undo"/>
label="&undoCmd.label;" <menuitem id="se-menu-redo"/>
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"/>
<menuseparator/> <menuseparator/>
<menuitem id="sp-menu-cut" <menuitem id="se-menu-cut"/>
label="&cutCmd.label;" <menuitem id="se-menu-copy"/>
key="key_cut" <menuitem id="se-menu-paste"/>
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"/>
<menuseparator/> <menuseparator/>
<menuitem id="sp-menu-selectAll" <menuitem id="se-menu-selectAll"/>
label="&selectAllCmd.label;"
key="key_selectAll"
accesskey="&selectAllCmd.accesskey;"
command="cmd_selectAll"/>
<menuseparator/> <menuseparator/>
<menuitem id="sp-menu-find" <menuitem id="se-menu-find"/>
label="&findCmd.label;" <menuitem id="se-menu-findAgain"/>
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"/>
<menuseparator/> <menuseparator/>
<menuitem id="sp-menu-gotoLine" <menuitem id="se-menu-gotoLine"/>
label="&gotoLineCmd.label;"
accesskey="&gotoLineCmd.accesskey;"
key="key_gotoLine"
command="cmd_gotoLine"/>
</menupopup> </menupopup>
</menu> </menu>
@ -338,13 +265,13 @@
<popupset id="scratchpad-popups"> <popupset id="scratchpad-popups">
<menupopup id="scratchpad-text-popup" <menupopup id="scratchpad-text-popup"
onpopupshowing="goUpdateGlobalEditMenuItems()"> onpopupshowing="goUpdateSourceEditorMenuItems()">
<menuitem id="menu_cut"/> <menuitem id="se-cMenu-cut"/>
<menuitem id="menu_copy"/> <menuitem id="se-cMenu-copy"/>
<menuitem id="menu_paste"/> <menuitem id="se-cMenu-paste"/>
<menuitem id="menu_delete"/> <menuitem id="se-cMenu-delete"/>
<menuseparator/> <menuseparator/>
<menuitem id="menu_selectAll"/> <menuitem id="se-cMenu-selectAll"/>
<menuseparator/> <menuseparator/>
<menuitem id="sp-text-run" <menuitem id="sp-text-run"
label="&run.label;" label="&run.label;"
@ -370,7 +297,7 @@
</popupset> </popupset>
<notificationbox id="scratchpad-notificationbox" flex="1"> <notificationbox id="scratchpad-notificationbox" flex="1">
<hbox id="scratchpad-editor" flex="1" context="scratchpad-text-popup" /> <hbox id="scratchpad-editor" flex="1"/>
</notificationbox> </notificationbox>
</window> </window>

Просмотреть файл

@ -27,7 +27,7 @@ function runTests()
let doc = gScratchpadWindow.document; let doc = gScratchpadWindow.document;
let winUtils = gScratchpadWindow.QueryInterface(Ci.nsIInterfaceRequestor). let winUtils = gScratchpadWindow.QueryInterface(Ci.nsIInterfaceRequestor).
getInterface(Ci.nsIDOMWindowUtils); 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"); info("will test the Edit menu");
@ -51,9 +51,9 @@ function runTests()
let menuPopup = editMenu.menupopup; let menuPopup = editMenu.menupopup;
ok(menuPopup, "the Edit 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"); ok(cutItem, "the Cut menuitem");
let pasteItem = doc.getElementById("sp-menu-paste"); let pasteItem = doc.getElementById("se-menu-paste");
ok(pasteItem, "the Paste menuitem"); ok(pasteItem, "the Paste menuitem");
let anchor = doc.documentElement; let anchor = doc.documentElement;
@ -174,9 +174,9 @@ function runTests()
menuPopup = doc.getElementById("scratchpad-text-popup"); menuPopup = doc.getElementById("scratchpad-text-popup");
ok(menuPopup, "the context menupopup"); ok(menuPopup, "the context menupopup");
cutItem = doc.getElementById("menu_cut"); cutItem = doc.getElementById("se-cMenu-cut");
ok(cutItem, "the Cut menuitem"); ok(cutItem, "the Cut menuitem");
pasteItem = doc.getElementById("menu_paste"); pasteItem = doc.getElementById("se-cMenu-paste");
ok(pasteItem, "the Paste menuitem"); ok(pasteItem, "the Paste menuitem");
sp.setText("bug 699130: hello world! (context menu)"); sp.setText("bug 699130: hello world! (context menu)");

Просмотреть файл

@ -24,6 +24,7 @@
* Kenny Heaton <kennyheaton@gmail.com> * Kenny Heaton <kennyheaton@gmail.com>
* Spyros Livathinos <livathinos.spyros@gmail.com> * Spyros Livathinos <livathinos.spyros@gmail.com>
* Allen Eubank <adeubank@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 * 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 * 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"; 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 * The primary selection update delay. On Linux, the X11 primary selection is
* updated to hold the currently selected text. * updated to hold the currently selected text.
@ -109,6 +118,10 @@ const ORION_ANNOTATION_TYPES = {
* Default key bindings in the Orion editor. * Default key bindings in the Orion editor.
*/ */
const DEFAULT_KEYBINDINGS = [ const DEFAULT_KEYBINDINGS = [
{
action: "enter",
code: Ci.nsIDOMKeyEvent.DOM_VK_ENTER,
},
{ {
action: "undo", action: "undo",
code: Ci.nsIDOMKeyEvent.DOM_VK_Z, code: Ci.nsIDOMKeyEvent.DOM_VK_Z,
@ -465,6 +478,10 @@ SourceEditor.prototype = {
*/ */
_doTab: function SE__doTab() _doTab: function SE__doTab()
{ {
if (this.readOnly) {
return false;
}
let indent = "\t"; let indent = "\t";
let selection = this.getSelection(); let selection = this.getSelection();
let model = this._model; let model = this._model;
@ -515,6 +532,10 @@ SourceEditor.prototype = {
*/ */
_doUnindentLines: function SE__doUnindentLines() _doUnindentLines: function SE__doUnindentLines()
{ {
if (this.readOnly) {
return true;
}
let indent = "\t"; let indent = "\t";
let selection = this.getSelection(); let selection = this.getSelection();
@ -569,6 +590,10 @@ SourceEditor.prototype = {
*/ */
_doEnter: function SE__doEnter() _doEnter: function SE__doEnter()
{ {
if (this.readOnly) {
return false;
}
let selection = this.getSelection(); let selection = this.getSelection();
if (selection.start != selection.end) { if (selection.start != selection.end) {
return false; return false;
@ -1309,10 +1334,56 @@ SourceEditor.prototype = {
* The new caret line location. Line numbers start from 0. * The new caret line location. Line numbers start from 0.
* @param number [aColumn=0] * @param number [aColumn=0]
* Optional. The new caret column location. Columns start from 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);
}, },
/** /**

Просмотреть файл

@ -35,80 +35,203 @@
- the terms of any one of the MPL, the GPL or the LGPL. - the terms of any one of the MPL, the GPL or the LGPL.
- -
- ***** END LICENSE BLOCK ***** --> - ***** 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" <overlay id="sourceEditorOverlay"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<!-- This Source Editor overlay requires the editMenuOverlay.xul to be loaded. <!-- This Source Editor overlay requires the editMenuOverlay.xul to be loaded.
The globalOverlay.js script is also required in the XUL document where 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"> <commandset id="sourceEditorCommands">
<command id="cmd_find" oncommand="goDoCommand('cmd_find')"/> <command id="cmd_find" oncommand="goDoCommand('cmd_find')"/>
<command id="cmd_findAgain" oncommand="goDoCommand('cmd_findAgain')" disabled="true"/> <command id="cmd_findAgain" oncommand="goDoCommand('cmd_findAgain')" disabled="true"/>
<command id="cmd_findPrevious" oncommand="goDoCommand('cmd_findPrevious')" disabled="true"/> <command id="cmd_findPrevious" oncommand="goDoCommand('cmd_findPrevious')" disabled="true"/>
<command id="cmd_gotoLine" oncommand="goDoCommand('cmd_gotoLine')"/> <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-undo" oncommand="goDoCommand('se-cmd-undo')" disabled="true"/>
<command id="se-cmd-redo" oncommand="goDoCommand('se-cmd-redo')" disabled="true"/> <command id="se-cmd-redo" oncommand="goDoCommand('se-cmd-redo')" disabled="true"/>
</commandset> </commandset>
<keyset id="sourceEditorKeys"> <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 id="key_gotoLine"
key="&gotoLineCmd.key;" key="&gotoLineCmd.key;"
command="cmd_gotoLine" command="cmd_gotoLine"
modifiers="accel"/> 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> </keyset>
<menupopup id="sourceEditorContextMenu" <!-- Items for the Edit menu -->
onpopupshowing="goUpdateGlobalEditMenuItems()">
<menuitem id="se-menu-undo" <menuitem id="se-menu-undo"
label="&undoCmd.label;" label="&undoCmd.label;"
key="key_undo" key="key_undo"
accesskey="&undoCmd.accesskey;" accesskey="&undoCmd.accesskey;"
command="se-cmd-undo"/> command="se-cmd-undo"/>
<menuseparator/> <menuitem id="se-menu-redo"
<menuitem id="se-menu-cut" label="&redoCmd.label;"
label="&cutCmd.label;" key="key_redo"
key="key_cut" accesskey="&redoCmd.accesskey;"
accesskey="&cutCmd.accesskey;" command="se-cmd-redo"/>
command="cmd_cut"/> <menuitem id="se-menu-cut"
<menuitem id="se-menu-copy" label="&cutCmd.label;"
label="&copyCmd.label;" key="key_cut"
key="key_copy" accesskey="&cutCmd.accesskey;"
accesskey="&copyCmd.accesskey;" command="se-cmd-cut"/>
command="cmd_copy"/> <menuitem id="se-menu-copy"
<menuitem id="se-menu-paste" label="&copyCmd.label;"
label="&pasteCmd.label;" key="key_copy"
key="key_paste" accesskey="&copyCmd.accesskey;"
accesskey="&pasteCmd.accesskey;" command="cmd_copy"/>
command="cmd_paste"/> <menuitem id="se-menu-paste"
<menuitem id="se-menu-delete" label="&pasteCmd.label;"
label="&deleteCmd.label;" key="key_paste"
key="key_delete" accesskey="&pasteCmd.accesskey;"
accesskey="&deleteCmd.accesskey;" command="se-cmd-paste"/>
command="cmd_delete"/> <menuitem id="se-menu-delete"
<menuseparator/> label="&deleteCmd.label;"
<menuitem id="se-menu-selectAll" key="key_delete"
label="&selectAllCmd.label;" accesskey="&deleteCmd.accesskey;"
key="key_selectAll" command="se-cmd-delete"/>
accesskey="&selectAllCmd.accesskey;" <menuitem id="se-menu-selectAll"
command="cmd_selectAll"/> label="&selectAllCmd.label;"
<menuseparator/> key="key_selectAll"
<menuitem id="se-menu-find" accesskey="&selectAllCmd.accesskey;"
label="&findCmd.label;" command="se-cmd-selectAll"/>
accesskey="&findCmd.accesskey;" <menuitem id="se-menu-find"
key="key_find" label="&findCmd.label;"
command="cmd_find"/> accesskey="&findCmd.accesskey;"
<menuitem id="se-menu-findAgain" key="key_find"
label="&findAgainCmd.label;" command="cmd_find"/>
accesskey="&findAgainCmd.accesskey;" <menuitem id="se-menu-findAgain"
key="key_findAgain" label="&findAgainCmd.label;"
command="cmd_findAgain"/> accesskey="&findAgainCmd.accesskey;"
<menuseparator/> key="key_findAgain"
<menuitem id="se-menu-gotoLine" command="cmd_findAgain"/>
label="&gotoLineCmd.label;" <menuitem id="se-menu-gotoLine"
accesskey="&gotoLineCmd.accesskey;" label="&gotoLineCmd.label;"
key="key_gotoLine" accesskey="&gotoLineCmd.accesskey;"
command="cmd_gotoLine"/> key="key_gotoLine"
</menupopup> 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> </overlay>

Просмотреть файл

@ -253,6 +253,10 @@ SourceEditorController.prototype = {
case "cmd_gotoLine": case "cmd_gotoLine":
case "se-cmd-undo": case "se-cmd-undo":
case "se-cmd-redo": case "se-cmd-redo":
case "se-cmd-cut":
case "se-cmd-paste":
case "se-cmd-delete":
case "se-cmd-selectAll":
result = true; result = true;
break; break;
default: default:
@ -278,6 +282,7 @@ SourceEditorController.prototype = {
switch (aCommand) { switch (aCommand) {
case "cmd_find": case "cmd_find":
case "cmd_gotoLine": case "cmd_gotoLine":
case "se-cmd-selectAll":
result = true; result = true;
break; break;
case "cmd_findAgain": case "cmd_findAgain":
@ -290,6 +295,19 @@ SourceEditorController.prototype = {
case "se-cmd-redo": case "se-cmd-redo":
result = this._editor.canRedo(); result = this._editor.canRedo();
break; 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: default:
result = false; result = false;
break; break;
@ -320,12 +338,26 @@ SourceEditorController.prototype = {
case "cmd_gotoLine": case "cmd_gotoLine":
this._editor.ui.gotoLine(); this._editor.ui.gotoLine();
break; break;
case "se-cmd-selectAll":
this._editor._view.invokeAction("selectAll");
break;
case "se-cmd-undo": case "se-cmd-undo":
this._editor.undo(); this._editor.undo();
break; break;
case "se-cmd-redo": case "se-cmd-redo":
this._editor.redo(); this._editor.redo();
break; 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;
}
} }
}, },

Просмотреть файл

@ -312,6 +312,16 @@ SourceEditor.EVENTS = {
DIRTY_CHANGED: "DirtyChanged", 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. * Extend a destination object with properties from a source object.
* *
@ -336,6 +346,7 @@ extend(SourceEditor.prototype, {
MODES: SourceEditor.MODES, MODES: SourceEditor.MODES,
THEMES: SourceEditor.THEMES, THEMES: SourceEditor.THEMES,
DEFAULTS: SourceEditor.DEFAULTS, DEFAULTS: SourceEditor.DEFAULTS,
VERTICAL_ALIGN: SourceEditor.VERTICAL_ALIGN,
_lastFind: null, _lastFind: null,

Просмотреть файл

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

Просмотреть файл

@ -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);
}

Просмотреть файл

@ -201,11 +201,21 @@ function editorLoaded()
editor.setText("foobar"); editor.setText("foobar");
is(editor.getText(), "foobar", "editor allows programmatic changes (setText)"); 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.readOnly = false;
editor.setCaretOffset(editor.getCharCount()); editor.setCaretOffset(editor.getCharCount());
EventUtils.synthesizeKey("-", {}, testWin); 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. // Test the Selection event.

Просмотреть файл

@ -57,7 +57,22 @@
<xul:script type="application/javascript" src="chrome://global/content/globalOverlay.js"/> <xul:script type="application/javascript" src="chrome://global/content/globalOverlay.js"/>
<xul:popupset id="style-editor-popups"> <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:popupset>
<xul:commandset id="editMenuCommands"/> <xul:commandset id="editMenuCommands"/>
@ -66,7 +81,6 @@
<xul:command id="style-editor-cmd-close" oncommand="window.close();"/> <xul:command id="style-editor-cmd-close" oncommand="window.close();"/>
</xul:commandset> </xul:commandset>
<xul:keyset id="editMenuKeys"/>
<xul:keyset id="sourceEditorKeys"/> <xul:keyset id="sourceEditorKeys"/>
<xul:keyset id="style-editor-keyset"> <xul:keyset id="style-editor-keyset">
<xul:key id="style-editor-key-close" <xul:key id="style-editor-key-close"

Просмотреть файл

@ -43,50 +43,6 @@
<!ENTITY editMenu.label "Edit"> <!ENTITY editMenu.label "Edit">
<!ENTITY editMenu.accesskey "E"> <!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.label "Run">
<!ENTITY run.accesskey "R"> <!ENTITY run.accesskey "R">
<!ENTITY run.key "r"> <!ENTITY run.key "r">

Просмотреть файл

@ -10,23 +10,6 @@
- A good criteria is the language in which you'd find the best - A good criteria is the language in which you'd find the best
- documentation on web development on the web. --> - 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.label "Jump to line…">
<!ENTITY gotoLineCmd.key "J"> <!ENTITY gotoLineCmd.key "J">
<!ENTITY gotoLineCmd.accesskey "J"> <!ENTITY gotoLineCmd.accesskey "J">

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

@ -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_ */

Просмотреть файл

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

Просмотреть файл

@ -1619,7 +1619,43 @@ public:
* case for ASCII characters a-z. * case for ASCII characters a-z.
*/ */
static bool EqualsIgnoreASCIICase(const nsAString& aStr1, 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. * Convert ASCII A-Z to a-z.

Просмотреть файл

@ -43,7 +43,6 @@
#include "nsIFile.h" #include "nsIFile.h"
#include "nsIDOMFile.h" #include "nsIDOMFile.h"
#include "nsIDOMFileList.h" #include "nsIDOMFileList.h"
#include "nsIDOMFileError.h"
#include "nsIInputStream.h" #include "nsIInputStream.h"
#include "nsIJSNativeInitializer.h" #include "nsIJSNativeInitializer.h"
#include "nsIMutable.h" #include "nsIMutable.h"
@ -53,12 +52,13 @@
#include "nsIXMLHttpRequest.h" #include "nsIXMLHttpRequest.h"
#include "prmem.h" #include "prmem.h"
#include "nsAutoPtr.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/GuardObjects.h"
#include "mozilla/StandardInteger.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 nsIFile;
class nsIInputStream; class nsIInputStream;
@ -363,18 +363,6 @@ private:
nsCOMArray<nsIDOMFile> mFiles; 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 { class NS_STACK_CLASS nsDOMFileInternalUrlHolder {
public: public:
nsDOMFileInternalUrlHolder(nsIDOMBlob* aFile, nsIPrincipal* aPrincipal nsDOMFileInternalUrlHolder(nsIDOMBlob* aFile, nsIPrincipal* aPrincipal

Просмотреть файл

@ -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;
};

Просмотреть файл

@ -39,9 +39,9 @@
interface nsIDOMEventListener; interface nsIDOMEventListener;
interface nsIDOMBlob; 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 interface nsIDOMFileReader : nsIDOMEventTarget
{ {
[implicit_jscontext] [implicit_jscontext]
@ -59,7 +59,7 @@ interface nsIDOMFileReader : nsIDOMEventTarget
[implicit_jscontext] [implicit_jscontext]
readonly attribute jsval result; readonly attribute jsval result;
readonly attribute nsIDOMFileError error; readonly attribute nsIDOMDOMError error;
attribute nsIDOMEventListener onloadstart; attribute nsIDOMEventListener onloadstart;
attribute nsIDOMEventListener onprogress; attribute nsIDOMEventListener onprogress;

Просмотреть файл

@ -1424,7 +1424,8 @@ public:
/** /**
* Called by nsParser to preload images. Can be removed and code moved * Called by nsParser to preload images. Can be removed and code moved
* to nsPreloadURIs::PreloadURIs() in file nsParser.cpp whenever the * 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, virtual void MaybePreLoadImage(nsIURI* uri,
const nsAString& aCrossOriginAttr) = 0; const nsAString& aCrossOriginAttr) = 0;

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

@ -5393,6 +5393,7 @@ nsContentUtils::ASCIIToUpper(const nsAString& aSource, nsAString& aDest)
} }
} }
/* static */
bool bool
nsContentUtils::EqualsIgnoreASCIICase(const nsAString& aStr1, nsContentUtils::EqualsIgnoreASCIICase(const nsAString& aStr1,
const nsAString& aStr2) const nsAString& aStr2)
@ -5415,7 +5416,7 @@ nsContentUtils::EqualsIgnoreASCIICase(const nsAString& aStr1,
return false; 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 // Likely the two chars are the same, so check that first
if (c1 != c2) { if (c1 != c2) {
// They do differ, but since it's only in the 0x0020 bit, check if it's // 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; 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 */ /* static */
nsIInterfaceRequestor* nsIInterfaceRequestor*
nsContentUtils::GetSameOriginChecker() nsContentUtils::GetSameOriginChecker()

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

@ -632,27 +632,6 @@ nsDOMFileList::Item(PRUint32 aIndex, nsIDOMFile **aFile)
return NS_OK; 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 // nsDOMFileInternalUrlHolder implementation

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

@ -3247,6 +3247,14 @@ nsIDocument::TakeFrameRequestCallbacks(FrameRequestCallbackList& aCallbacks)
mFrameRequestCallbacks.Clear(); mFrameRequestCallbacks.Clear();
} }
PLDHashOperator RequestDiscardEnumerator(imgIRequest* aKey,
PRUint32 aData,
void* userArg)
{
aKey->RequestDiscard();
return PL_DHASH_NEXT;
}
void void
nsDocument::DeleteShell() nsDocument::DeleteShell()
{ {
@ -3255,6 +3263,11 @@ nsDocument::DeleteShell()
RevokeAnimationFrameNotifications(); 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; mPresShell = nsnull;
} }
@ -4414,7 +4427,7 @@ nsDocument::CreateElement(const nsAString& aTagName,
bool needsLowercase = IsHTML() && !IsLowercaseASCII(aTagName); bool needsLowercase = IsHTML() && !IsLowercaseASCII(aTagName);
nsAutoString lcTagName; nsAutoString lcTagName;
if (needsLowercase) { if (needsLowercase) {
ToLowerCase(aTagName, lcTagName); nsContentUtils::ASCIIToLower(aTagName, lcTagName);
} }
rv = CreateElem(needsLowercase ? lcTagName : aTagName, rv = CreateElem(needsLowercase ? lcTagName : aTagName,
@ -7724,14 +7737,20 @@ nsDocument::MaybePreLoadImage(nsIURI* uri, const nsAString &aCrossOriginAttr)
} }
nsLoadFlags loadFlags = nsIRequest::LOAD_NORMAL; 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; loadFlags |= imgILoader::LOAD_CORS_ANONYMOUS;
} else if (aCrossOriginAttr.LowerCaseEqualsLiteral("use-credentials")) { break;
case CORS_USE_CREDENTIALS:
loadFlags |= imgILoader::LOAD_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 // Image not in cache - trigger preload
nsCOMPtr<imgIRequest> request; nsCOMPtr<imgIRequest> request;
@ -8309,26 +8328,32 @@ nsDocument::RemoveImage(imgIRequest* aImage)
// If the count is now zero, remove from the tracker. // If the count is now zero, remove from the tracker.
// Otherwise, set the new value. // Otherwise, set the new value.
if (count == 0) { if (count != 0) {
mImageTracker.Remove(aImage);
} else {
mImageTracker.Put(aImage, count); mImageTracker.Put(aImage, count);
return NS_OK;
} }
mImageTracker.Remove(aImage);
nsresult rv = NS_OK; nsresult rv = NS_OK;
// If we removed the image from the tracker and we're locking images, unlock // Now that we're no longer tracking this image, unlock it if we'd
// this image. // previously locked it.
if (count == 0 && mLockingImages) if (mLockingImages) {
rv = aImage->UnlockImage(); rv = aImage->UnlockImage();
}
// If we removed the image from the tracker and we're animating images, // If we're animating images, remove our request to animate this one.
// remove our request to animate this image. if (mAnimatingImages) {
if (count == 0 && mAnimatingImages) {
nsresult rv2 = aImage->DecrementAnimationConsumers(); nsresult rv2 = aImage->DecrementAnimationConsumers();
rv = NS_SUCCEEDED(rv) ? rv2 : rv; 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; return rv;
} }

Просмотреть файл

@ -159,6 +159,8 @@
#include "nsLayoutStatics.h" #include "nsLayoutStatics.h"
#include "mozilla/Telemetry.h" #include "mozilla/Telemetry.h"
#include "mozilla/CORSMode.h"
using namespace mozilla; using namespace mozilla;
using namespace mozilla::dom; using namespace mozilla::dom;
@ -2853,15 +2855,16 @@ nsGenericElement::GetAttributeNS(const nsAString& aNamespaceURI,
nsContentUtils::NameSpaceManager()->GetNameSpaceID(aNamespaceURI); nsContentUtils::NameSpaceManager()->GetNameSpaceID(aNamespaceURI);
if (nsid == kNameSpaceID_Unknown) { if (nsid == kNameSpaceID_Unknown) {
// Unknown namespace means no attr... // Unknown namespace means no attribute.
SetDOMStringToNull(aReturn);
aReturn.Truncate();
return NS_OK; return NS_OK;
} }
nsCOMPtr<nsIAtom> name = do_GetAtom(aLocalName); nsCOMPtr<nsIAtom> name = do_GetAtom(aLocalName);
GetAttr(nsid, name, aReturn); bool hasAttr = GetAttr(nsid, name, aReturn);
if (!hasAttr) {
SetDOMStringToNull(aReturn);
}
return NS_OK; return NS_OK;
} }
@ -6235,6 +6238,48 @@ nsGenericElement::SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf) const
mAttrsAndChildren.SizeOfExcludingThis(aMallocSizeOf); 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_) \ #define EVENT(name_, id_, type_, struct_) \
NS_IMETHODIMP nsINode::GetOn##name_(JSContext *cx, jsval *vp) { \ NS_IMETHODIMP nsINode::GetOn##name_(JSContext *cx, jsval *vp) { \
nsEventListenerManager *elm = GetListenerManager(false); \ nsEventListenerManager *elm = GetListenerManager(false); \

Просмотреть файл

@ -65,6 +65,7 @@
#include "nsDOMClassInfoID.h" // DOMCI_DATA #include "nsDOMClassInfoID.h" // DOMCI_DATA
#include "nsIDOMTouchEvent.h" #include "nsIDOMTouchEvent.h"
#include "nsIInlineEventHandlers.h" #include "nsIInlineEventHandlers.h"
#include "mozilla/CORSMode.h"
#include "nsISMILAttr.h" #include "nsISMILAttr.h"
@ -640,6 +641,25 @@ public:
void *aData); void *aData);
static void MarkUserDataHandler(void* aObject, nsIAtom* aKey, void* aChild, static void MarkUserDataHandler(void* aObject, nsIAtom* aKey, void* aChild,
void* aData); 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: protected:
/* /*
* Named-bools for use with SetAttrAndNotify to make call sites easier to * Named-bools for use with SetAttrAndNotify to make call sites easier to

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

@ -238,9 +238,12 @@ public:
* @param aURI The URI of the external script. * @param aURI The URI of the external script.
* @param aCharset The charset parameter for the script. * @param aCharset The charset parameter for the script.
* @param aType The type 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, virtual void PreloadURI(nsIURI *aURI, const nsAString &aCharset,
const nsAString &aType); const nsAString &aType,
const nsAString &aCrossOrigin);
private: private:
/** /**

Просмотреть файл

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

Просмотреть файл

@ -562,6 +562,11 @@ _TEST_FILES2 = \
test_bug726364.html \ test_bug726364.html \
test_bug698381.html \ test_bug698381.html \
test_bug711047.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) $(NULL)
_CHROME_FILES = \ _CHROME_FILES = \

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

@ -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>

Просмотреть файл

@ -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>

Просмотреть файл

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

Просмотреть файл

@ -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>

Просмотреть файл

@ -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 takes:
* TexImage2D(uint, int, uint, int, int, int, uint, uint, ArrayBufferView) * 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 // arguments common to all cases
GET_UINT32_ARG(argv0, 0); GET_UINT32_ARG(argv0, 0);
GET_INT32_ARG(argv1, 1); GET_INT32_ARG(argv1, 1);
GET_UINT32_ARG(argv2, 2);
if (argc > 5 && if (argc > 5 && !JSVAL_IS_PRIMITIVE(argv[5])) {
!JSVAL_IS_PRIMITIVE(argv[5]))
{
// implement the variants taking a DOMElement as argv[5] // implement the variants taking a DOMElement as argv[5]
GET_UINT32_ARG(argv2, 2);
GET_UINT32_ARG(argv3, 3); GET_UINT32_ARG(argv3, 3);
GET_UINT32_ARG(argv4, 4); GET_UINT32_ARG(argv4, 4);
nsIDOMElement *elt; CallTexImage2D selfCaller(self, argv0, argv1, argv2, argv3, argv4);
xpc_qsSelfRef eltRef; if (!TexImage2DImageDataOrElement(cx, selfCaller, argv + 5)) {
rv = xpc_qsUnwrapArg<nsIDOMElement>(cx, argv[5], &elt, &eltRef.ptr, &argv[5]); return false;
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;
} }
rv = NS_OK;
if (NS_FAILED(rv)) { } else if (argc > 8 && JSVAL_IS_OBJECT(argv[8])) {
// failed to interprete argv[5] as a DOMElement, now try to interprete it as ImageData // here, we allow null !
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 !
{
// implement the variants taking a buffer/array as argv[8] // implement the variants taking a buffer/array as argv[8]
GET_UINT32_ARG(argv2, 2);
GET_INT32_ARG(argv3, 3); GET_INT32_ARG(argv3, 3);
GET_INT32_ARG(argv4, 4); GET_INT32_ARG(argv4, 4);
GET_INT32_ARG(argv5, 5); 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(argv2, 2);
GET_INT32_ARG(argv3, 3); GET_INT32_ARG(argv3, 3);
if (argc > 6 && if (argc > 6 && !JSVAL_IS_PRIMITIVE(argv[6])) {
!JSVAL_IS_PRIMITIVE(argv[6])) // implement the variants taking a DOMElement or an ImageData as argv[6]
{
// implement the variants taking a DOMElement as argv[6]
GET_UINT32_ARG(argv4, 4); GET_UINT32_ARG(argv4, 4);
GET_UINT32_ARG(argv5, 5); GET_UINT32_ARG(argv5, 5);
nsIDOMElement *elt; CallTexSubImage2D selfCaller(self, argv0, argv1, argv2, argv3, argv4, argv5);
xpc_qsSelfRef eltRef; if (!TexImage2DImageDataOrElement(cx, selfCaller, argv + 6)) {
rv = xpc_qsUnwrapArg<nsIDOMElement>(cx, argv[6], &elt, &eltRef.ptr, &argv[6]); return false;
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;
} }
rv = NS_OK;
if (NS_FAILED(rv)) { } else if (argc > 8 && !JSVAL_IS_PRIMITIVE(argv[8])) {
// 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]))
{
// implement the variants taking a buffer/array as argv[8] // implement the variants taking a buffer/array as argv[8]
GET_INT32_ARG(argv4, 4); GET_INT32_ARG(argv4, 4);
GET_INT32_ARG(argv5, 5); GET_INT32_ARG(argv5, 5);

Просмотреть файл

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

Просмотреть файл

@ -70,6 +70,7 @@
#endif #endif
using namespace mozilla; using namespace mozilla;
using namespace mozilla::dom;
static bool BaseTypeAndSizeFromUniformType(WebGLenum uType, WebGLenum *baseType, WebGLint *unitSize); static bool BaseTypeAndSizeFromUniformType(WebGLenum uType, WebGLenum *baseType, WebGLint *unitSize);
static WebGLenum InternalFormatForFormatAndType(WebGLenum format, WebGLenum type, bool isGLES2); 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 nsresult
WebGLContext::DOMElementToImageSurface(nsIDOMElement *imageOrCanvas, WebGLContext::DOMElementToImageSurface(Element* imageOrCanvas,
gfxImageSurface **imageOut, int *format) gfxImageSurface **imageOut, int *format)
{ {
nsCOMPtr<nsIContent> content = do_QueryInterface(imageOrCanvas); if (!imageOrCanvas) {
if (!content) {
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
@ -3984,7 +3984,7 @@ WebGLContext::DOMElementToImageSurface(nsIDOMElement *imageOrCanvas,
flags |= nsLayoutUtils::SFE_NO_PREMULTIPLY_ALPHA; flags |= nsLayoutUtils::SFE_NO_PREMULTIPLY_ALPHA;
nsLayoutUtils::SurfaceFromElementResult res = nsLayoutUtils::SurfaceFromElementResult res =
nsLayoutUtils::SurfaceFromElement(content->AsElement(), flags); nsLayoutUtils::SurfaceFromElement(imageOrCanvas, flags);
if (!res.mSurface) if (!res.mSurface)
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
if (res.mSurface->GetType() != gfxASurface::SurfaceTypeImage) { 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. // 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 // That would indicate a tainted canvas, i.e. a canvas that could contain
// cross-domain image data. // cross-domain image data.
if (nsHTMLCanvasElement* canvas = nsHTMLCanvasElement::FromContent(content)) { if (nsHTMLCanvasElement* canvas = nsHTMLCanvasElement::FromContent(imageOrCanvas)) {
if (canvas->IsWriteOnly()) { if (canvas->IsWriteOnly()) {
LogMessageIfVerbose("The canvas used as source for texImage2D here is tainted (write-only). It is forbidden " 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 " "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 NS_IMETHODIMP
WebGLContext::TexImage2D_dom(WebGLenum target, WebGLint level, WebGLenum internalformat, WebGLContext::TexImage2D_dom(WebGLenum target, WebGLint level, WebGLenum internalformat,
WebGLenum format, GLenum type, nsIDOMElement *elt) WebGLenum format, GLenum type, Element* elt)
{ {
if (!IsContextStable()) if (!IsContextStable())
return NS_OK; return NS_OK;
@ -5272,7 +5272,7 @@ NS_IMETHODIMP
WebGLContext::TexSubImage2D_dom(WebGLenum target, WebGLint level, WebGLContext::TexSubImage2D_dom(WebGLenum target, WebGLint level,
WebGLint xoffset, WebGLint yoffset, WebGLint xoffset, WebGLint yoffset,
WebGLenum format, WebGLenum type, WebGLenum format, WebGLenum type,
nsIDOMElement *elt) Element *elt)
{ {
if (!IsContextStable()) if (!IsContextStable())
return NS_OK; return NS_OK;

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

@ -2488,24 +2488,25 @@ nsGenericHTMLElement::GetContentEditable(nsAString& aContentEditable)
nsresult nsresult
nsGenericHTMLElement::SetContentEditable(const nsAString& aContentEditable) nsGenericHTMLElement::SetContentEditable(const nsAString& aContentEditable)
{ {
nsString contentEditable; if (nsContentUtils::EqualsLiteralIgnoreASCIICase(aContentEditable, "inherit")) {
ToLowerCase(aContentEditable, contentEditable);
if (contentEditable.EqualsLiteral("inherit")) {
UnsetAttr(kNameSpaceID_None, nsGkAtoms::contenteditable, true); UnsetAttr(kNameSpaceID_None, nsGkAtoms::contenteditable, true);
return NS_OK; return NS_OK;
} }
if (!contentEditable.EqualsLiteral("true") && if (nsContentUtils::EqualsLiteralIgnoreASCIICase(aContentEditable, "true")) {
!contentEditable.EqualsLiteral("false")) { SetAttr(kNameSpaceID_None, nsGkAtoms::contenteditable, NS_LITERAL_STRING("true"), true);
return NS_ERROR_DOM_SYNTAX_ERR;
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, return NS_ERROR_DOM_SYNTAX_ERR;
true);
return NS_OK;
} }
nsresult nsresult
@ -2886,14 +2887,6 @@ nsGenericHTMLFormElement::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
return nsGenericHTMLElement::PreHandleEvent(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 */ /* virtual */
bool bool
nsGenericHTMLFormElement::IsDisabled() const nsGenericHTMLFormElement::IsDisabled() const

Просмотреть файл

@ -530,7 +530,7 @@ public:
* Returns the current disabled state of the element. * Returns the current disabled state of the element.
*/ */
virtual bool IsDisabled() const { virtual bool IsDisabled() const {
return HasAttr(kNameSpaceID_None, nsGkAtoms::disabled); return false;
} }
bool IsHidden() const bool IsHidden() const
@ -538,32 +538,6 @@ public:
return HasAttr(kNameSpaceID_None, nsGkAtoms::hidden); 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: protected:
/** /**
* Add/remove this element to the documents name cache * Add/remove this element to the documents name cache

Просмотреть файл

@ -363,10 +363,8 @@ nsHTMLImageElement::ParseAttribute(PRInt32 aNamespaceID,
return ParseAlignValue(aValue, aResult); return ParseAlignValue(aValue, aResult);
} }
if (aAttribute == nsGkAtoms::crossorigin) { if (aAttribute == nsGkAtoms::crossorigin) {
return aResult.ParseEnumValue(aValue, nsGenericHTMLElement::kCORSAttributeTable, false, ParseCORSValue(aValue, aResult);
// default value is anonymous if aValue is return true;
// not a value we understand
&nsGenericHTMLElement::kCORSAttributeTable[0]);
} }
if (ParseImageAttribute(aAttribute, aValue, aResult)) { if (ParseImageAttribute(aAttribute, aValue, aResult)) {
return true; return true;
@ -662,17 +660,8 @@ nsHTMLImageElement::CopyInnerTo(nsGenericElement* aDest) const
return nsGenericHTMLElement::CopyInnerTo(aDest); return nsGenericHTMLElement::CopyInnerTo(aDest);
} }
nsGenericHTMLElement::CORSMode CORSMode
nsHTMLImageElement::GetCORSMode() nsHTMLImageElement::GetCORSMode()
{ {
nsGenericHTMLElement::CORSMode ret = nsGenericHTMLElement::CORS_NONE; return AttrValueToCORSMode(GetParsedAttr(nsGkAtoms::crossorigin));
const nsAttrValue* value = GetParsedAttr(nsGkAtoms::crossorigin);
if (value) {
NS_ASSERTION(value->Type() == nsAttrValue::eEnum,
"Why is this not an enum value?");
ret = nsGenericHTMLElement::CORSMode(value->GetEnumValue());
}
return ret;
} }

Просмотреть файл

@ -436,7 +436,9 @@ nsHTMLLinkElement::GetStyleSheetInfo(nsAString& aTitle,
} }
GetAttr(kNameSpaceID_None, nsGkAtoms::media, aMedia); GetAttr(kNameSpaceID_None, nsGkAtoms::media, aMedia);
ToLowerCase(aMedia); // HTML4.0 spec is inconsistent, make it case INSENSITIVE // The HTML5 spec is formulated in terms of the CSSOM spec, which specifies
// that media queries should be ASCII lowercased during serialization.
nsContentUtils::ASCIIToLower(aMedia);
nsAutoString mimeType; nsAutoString mimeType;
nsAutoString notUsed; nsAutoString notUsed;

Просмотреть файл

@ -951,14 +951,7 @@ nsresult nsHTMLMediaElement::LoadResource()
} }
// Set the media element's CORS mode only when loading a resource // Set the media element's CORS mode only when loading a resource
// By default, it's CORS_NONE mCORSMode = AttrValueToCORSMode(GetParsedAttr(nsGkAtoms::crossorigin));
mCORSMode = CORS_NONE;
const nsAttrValue* value = GetParsedAttr(nsGkAtoms::crossorigin);
if (value) {
NS_ASSERTION(value->Type() == nsAttrValue::eEnum,
"Why is this not an enum value?");
mCORSMode = CORSMode(value->GetEnumValue());
}
nsHTMLMediaElement* other = LookupMediaElementURITable(mLoadingSrc); nsHTMLMediaElement* other = LookupMediaElementURITable(mLoadingSrc);
if (other) { if (other) {
@ -1604,10 +1597,8 @@ bool nsHTMLMediaElement::ParseAttribute(PRInt32 aNamespaceID,
return true; return true;
} }
if (aAttribute == nsGkAtoms::crossorigin) { if (aAttribute == nsGkAtoms::crossorigin) {
return aResult.ParseEnumValue(aValue, kCORSAttributeTable, false, ParseCORSValue(aValue, aResult);
// default value is anonymous if aValue is return true;
// not a value we understand
&kCORSAttributeTable[0]);
} }
if (aAttribute == nsGkAtoms::preload) { if (aAttribute == nsGkAtoms::preload) {
return aResult.ParseEnumValue(aValue, kPreloadTable, false); return aResult.ParseEnumValue(aValue, kPreloadTable, false);

Просмотреть файл

@ -85,6 +85,10 @@ public:
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const; virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
virtual nsXPCClassInfo* GetClassInfo(); virtual nsXPCClassInfo* GetClassInfo();
virtual bool IsDisabled() const {
return HasAttr(kNameSpaceID_None, nsGkAtoms::disabled);
}
protected: protected:
/** /**

Просмотреть файл

@ -104,6 +104,10 @@ public:
nsresult CopyInnerTo(nsGenericElement* aDest) const; nsresult CopyInnerTo(nsGenericElement* aDest) const;
virtual nsXPCClassInfo* GetClassInfo(); virtual nsXPCClassInfo* GetClassInfo();
virtual bool IsDisabled() const {
return HasAttr(kNameSpaceID_None, nsGkAtoms::disabled);
}
protected: protected:
/** /**
* Get the select content element that contains this option, this * Get the select content element that contains this option, this

Просмотреть файл

@ -57,6 +57,7 @@
#include "nsTArray.h" #include "nsTArray.h"
#include "nsDOMJSUtils.h" #include "nsDOMJSUtils.h"
using namespace mozilla;
using namespace mozilla::dom; using namespace mozilla::dom;
class nsHTMLScriptElement : public nsGenericHTMLElement, class nsHTMLScriptElement : public nsGenericHTMLElement,
@ -108,11 +109,16 @@ public:
virtual void GetScriptText(nsAString& text); virtual void GetScriptText(nsAString& text);
virtual void GetScriptCharset(nsAString& charset); virtual void GetScriptCharset(nsAString& charset);
virtual void FreezeUriAsyncDefer(); virtual void FreezeUriAsyncDefer();
virtual CORSMode GetCORSMode() const;
// nsIContent // nsIContent
virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent, virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
nsIContent* aBindingParent, nsIContent* aBindingParent,
bool aCompileEventHandlers); bool aCompileEventHandlers);
virtual bool ParseAttribute(PRInt32 aNamespaceID,
nsIAtom* aAttribute,
const nsAString& aValue,
nsAttrValue& aResult);
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const; virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
@ -178,6 +184,22 @@ nsHTMLScriptElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
return NS_OK; return NS_OK;
} }
bool
nsHTMLScriptElement::ParseAttribute(PRInt32 aNamespaceID,
nsIAtom* aAttribute,
const nsAString& aValue,
nsAttrValue& aResult)
{
if (aNamespaceID == kNameSpaceID_None &&
aAttribute == nsGkAtoms::crossorigin) {
ParseCORSValue(aValue, aResult);
return true;
}
return nsGenericHTMLElement::ParseAttribute(aNamespaceID, aAttribute, aValue,
aResult);
}
nsresult nsresult
nsHTMLScriptElement::Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const nsHTMLScriptElement::Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const
{ {
@ -311,6 +333,12 @@ nsHTMLScriptElement::FreezeUriAsyncDefer()
mFrozen = true; mFrozen = true;
} }
CORSMode
nsHTMLScriptElement::GetCORSMode() const
{
return AttrValueToCORSMode(GetParsedAttr(nsGkAtoms::crossorigin));
}
bool bool
nsHTMLScriptElement::HasScriptContent() nsHTMLScriptElement::HasScriptContent()
{ {

Просмотреть файл

@ -340,7 +340,9 @@ nsHTMLStyleElement::GetStyleSheetInfo(nsAString& aTitle,
aTitle.Assign(title); aTitle.Assign(title);
GetAttr(kNameSpaceID_None, nsGkAtoms::media, aMedia); GetAttr(kNameSpaceID_None, nsGkAtoms::media, aMedia);
ToLowerCase(aMedia); // HTML4.0 spec is inconsistent, make it case INSENSITIVE // The HTML5 spec is formulated in terms of the CSSOM spec, which specifies
// that media queries should be ASCII lowercased during serialization.
nsContentUtils::ASCIIToLower(aMedia);
GetAttr(kNameSpaceID_None, nsGkAtoms::type, aType); GetAttr(kNameSpaceID_None, nsGkAtoms::type, aType);

Просмотреть файл

@ -61,6 +61,7 @@ var focusableElements = [
"<div tabindex=\"0\"></div>", "<div tabindex=\"0\"></div>",
"<div tabindex=\"1\"></div>", "<div tabindex=\"1\"></div>",
"<div contenteditable=\"true\"></div>", "<div contenteditable=\"true\"></div>",
"<div tabindex=\"0\" disabled></div>",
"<embed>", "<embed>",
"<embed tabindex=\"-1\">", "<embed tabindex=\"-1\">",
@ -165,7 +166,17 @@ var focusableElements = [
"<select tabindex=\"-1\"></select>", "<select tabindex=\"-1\"></select>",
"<select tabindex=\"0\"></select>", "<select tabindex=\"0\"></select>",
"<select tabindex=\"1\"></select>", "<select tabindex=\"1\"></select>",
"<select contenteditable=\"true\"></select>" "<select contenteditable=\"true\"></select>",
"<option tabindex='-1'></option>",
"<option tabindex='0'></option>",
"<option tabindex='1'></option>",
"<option contenteditable></option>",
"<optgroup tabindex='-1'></optgroup>",
"<optgroup tabindex='0'></optgroup>",
"<optgroup tabindex='1'></optgroup>",
"<optgroup contenteditable></optgroup>"
]; ];
var nonFocusableElements = [ var nonFocusableElements = [
@ -182,7 +193,6 @@ var nonFocusableElements = [
"<button type=\"submit\" disabled></button>", "<button type=\"submit\" disabled></button>",
"<div></div>", "<div></div>",
"<div tabindex=\"0\" disabled></div>",
"<div disabled></div>", "<div disabled></div>",
"<img>", "<img>",
@ -243,7 +253,13 @@ var nonFocusableElements = [
"<object></object>", "<object></object>",
"<select tabindex=\"0\" disabled></select>", "<select tabindex=\"0\" disabled></select>",
"<select disabled></select>" "<select disabled></select>",
"<option></option>",
"<option tabindex='1' disabled></option>",
"<optgroup></optgroup>",
"<optgroup tabindex='1' disabled></optgroup>"
]; ];
var focusableInContentEditable = [ var focusableInContentEditable = [
@ -268,6 +284,7 @@ var focusableInContentEditable = [
"<div tabindex=\"-1\"></div>", "<div tabindex=\"-1\"></div>",
"<div tabindex=\"0\"></div>", "<div tabindex=\"0\"></div>",
"<div tabindex=\"1\"></div>", "<div tabindex=\"1\"></div>",
"<div tabindex=\"0\" disabled></div>",
"<embed>", "<embed>",
"<embed tabindex=\"-1\">", "<embed tabindex=\"-1\">",
@ -365,7 +382,15 @@ var focusableInContentEditable = [
"<select tabindex=\"-1\"></select>", "<select tabindex=\"-1\"></select>",
"<select tabindex=\"0\"></select>", "<select tabindex=\"0\"></select>",
"<select tabindex=\"1\"></select>", "<select tabindex=\"1\"></select>",
"<select contenteditable=\"true\"></select>" "<select contenteditable=\"true\"></select>",
"<option tabindex='-1'></option>",
"<option tabindex='0'></option>",
"<option tabindex='1'></option>",
"<optgroup tabindex='-1'></optgroup>",
"<optgroup tabindex='0'></optgroup>",
"<optgroup tabindex='1'></optgroup>"
]; ];
var focusableInDesignMode = [ var focusableInDesignMode = [

Просмотреть файл

@ -1358,7 +1358,7 @@ nsHTMLDocument::Open(const nsAString& aContentTypeOrUrl,
contentType.AssignLiteral("text/html"); contentType.AssignLiteral("text/html");
if (aOptionalArgCount > 0) { if (aOptionalArgCount > 0) {
nsAutoString type; nsAutoString type;
ToLowerCase(aContentTypeOrUrl, type); nsContentUtils::ASCIIToLower(aContentTypeOrUrl, type);
nsCAutoString actualType, dummy; nsCAutoString actualType, dummy;
NS_ParseContentType(NS_ConvertUTF16toUTF8(type), actualType, dummy); NS_ParseContentType(NS_ConvertUTF16toUTF8(type), actualType, dummy);
if (!actualType.EqualsLiteral("text/html") && if (!actualType.EqualsLiteral("text/html") &&

Просмотреть файл

@ -86,6 +86,7 @@ public:
virtual void GetScriptText(nsAString& text); virtual void GetScriptText(nsAString& text);
virtual void GetScriptCharset(nsAString& charset); virtual void GetScriptCharset(nsAString& charset);
virtual void FreezeUriAsyncDefer(); virtual void FreezeUriAsyncDefer();
virtual CORSMode GetCORSMode() const;
// nsScriptElement // nsScriptElement
virtual bool HasScriptContent(); virtual bool HasScriptContent();
@ -96,6 +97,10 @@ public:
bool aCompileEventHandlers); bool aCompileEventHandlers);
virtual nsresult AfterSetAttr(PRInt32 aNamespaceID, nsIAtom* aName, virtual nsresult AfterSetAttr(PRInt32 aNamespaceID, nsIAtom* aName,
const nsAttrValue* aValue, bool aNotify); const nsAttrValue* aValue, bool aNotify);
virtual bool ParseAttribute(PRInt32 aNamespaceID,
nsIAtom* aAttribute,
const nsAString& aValue,
nsAttrValue& aResult);
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const; virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
@ -288,3 +293,26 @@ nsSVGScriptElement::AfterSetAttr(PRInt32 aNamespaceID, nsIAtom* aName,
return nsSVGScriptElementBase::AfterSetAttr(aNamespaceID, aName, return nsSVGScriptElementBase::AfterSetAttr(aNamespaceID, aName,
aValue, aNotify); aValue, aNotify);
} }
bool
nsSVGScriptElement::ParseAttribute(PRInt32 aNamespaceID,
nsIAtom* aAttribute,
const nsAString& aValue,
nsAttrValue& aResult)
{
if (aNamespaceID == kNameSpaceID_None &&
aAttribute == nsGkAtoms::crossorigin) {
ParseCORSValue(aValue, aResult);
return true;
}
return nsSVGScriptElementBase::ParseAttribute(aNamespaceID, aAttribute,
aValue, aResult);
}
CORSMode
nsSVGScriptElement::GetCORSMode() const
{
return AttrValueToCORSMode(GetParsedAttr(nsGkAtoms::crossorigin));
}

Просмотреть файл

@ -337,9 +337,9 @@ nsSVGStyleElement::GetStyleSheetInfo(nsAString& aTitle,
aTitle.Assign(title); aTitle.Assign(title);
GetAttr(kNameSpaceID_None, nsGkAtoms::media, aMedia); GetAttr(kNameSpaceID_None, nsGkAtoms::media, aMedia);
// SVG spec refers to the HTML4.0 spec which is inconsistent, make it // The SVG spec is formulated in terms of the CSS2 spec,
// case INSENSITIVE // which specifies that media queries are case insensitive.
ToLowerCase(aMedia); nsContentUtils::ASCIIToLower(aMedia);
GetAttr(kNameSpaceID_None, nsGkAtoms::type, aType); GetAttr(kNameSpaceID_None, nsGkAtoms::type, aType);
if (aType.IsEmpty()) { if (aType.IsEmpty()) {

Просмотреть файл

@ -932,21 +932,18 @@ nsXBLPrototypeHandler::ConstructPrototype(nsIContent* aKeyElement,
if (!key.IsEmpty()) { if (!key.IsEmpty()) {
if (mKeyMask == 0) if (mKeyMask == 0)
mKeyMask = cAllModifiers; mKeyMask = cAllModifiers;
ToLowerCase(key); nsContentUtils::ASCIIToLower(key);
// We have a charcode. // We have a charcode.
mMisc = 1; mMisc = 1;
mDetail = key[0]; mDetail = key[0];
const PRUint8 GTK2Modifiers = cShift | cControl | cShiftMask | cControlMask; const PRUint8 GTK2Modifiers = cShift | cControl | cShiftMask | cControlMask;
if ((mKeyMask & GTK2Modifiers) == GTK2Modifiers && if ((mKeyMask & GTK2Modifiers) == GTK2Modifiers &&
modifiers.First() != PRUnichar(',') && modifiers.First() != PRUnichar(',') && mDetail == 'u')
(mDetail == 'u' || mDetail == 'U'))
ReportKeyConflict(key.get(), modifiers.get(), aKeyElement, "GTK2Conflict"); ReportKeyConflict(key.get(), modifiers.get(), aKeyElement, "GTK2Conflict");
const PRUint8 WinModifiers = cControl | cAlt | cControlMask | cAltMask; const PRUint8 WinModifiers = cControl | cAlt | cControlMask | cAltMask;
if ((mKeyMask & WinModifiers) == WinModifiers && if ((mKeyMask & WinModifiers) == WinModifiers &&
modifiers.First() != PRUnichar(',') && modifiers.First() != PRUnichar(',') && ('a' <= mDetail && mDetail <= 'z'))
(('A' <= mDetail && mDetail <= 'Z') ||
('a' <= mDetail && mDetail <= 'z')))
ReportKeyConflict(key.get(), modifiers.get(), aKeyElement, "WinConflict"); ReportKeyConflict(key.get(), modifiers.get(), aKeyElement, "WinConflict");
} }
else { else {

Просмотреть файл

@ -44,8 +44,6 @@
#include "nsIAtom.h" #include "nsIAtom.h"
#include "nsUnicharUtils.h" #include "nsUnicharUtils.h"
#define TX_ToLowerCase ToLowerCase
typedef nsCaseInsensitiveStringComparator txCaseInsensitiveStringComparator; typedef nsCaseInsensitiveStringComparator txCaseInsensitiveStringComparator;
/** /**
@ -62,7 +60,7 @@ TX_ToLowerCaseAtom(nsIAtom* aAtom)
{ {
nsAutoString str; nsAutoString str;
aAtom->ToString(str); aAtom->ToString(str);
TX_ToLowerCase(str); nsContentUtils::ASCIIToLower(str);
return do_GetAtom(str); return do_GetAtom(str);
} }

Просмотреть файл

@ -938,7 +938,7 @@ txExprParser::resolveQName(const nsAString& aQName,
*aPrefix = 0; *aPrefix = 0;
if (aIsNameTest && aContext->caseInsensitiveNameTests()) { if (aIsNameTest && aContext->caseInsensitiveNameTests()) {
nsAutoString lcname; nsAutoString lcname;
TX_ToLowerCase(aQName, lcname); nsContentUtils::ASCIIToLower(aQName, lcname);
*aLocalName = NS_NewAtom(lcname); *aLocalName = NS_NewAtom(lcname);
} }
else { else {

Просмотреть файл

@ -453,7 +453,7 @@ txXPathNodeUtils::getLocalName(const txXPathNode& aNode, nsAString& aLocalName)
// Check for html // Check for html
if (aNode.Content()->NodeInfo()->NamespaceEquals(kNameSpaceID_None) && if (aNode.Content()->NodeInfo()->NamespaceEquals(kNameSpaceID_None) &&
aNode.Content()->IsHTML()) { aNode.Content()->IsHTML()) {
ToUpperCase(aLocalName); nsContentUtils::ASCIIToUpper(aLocalName);
} }
} }

Просмотреть файл

@ -228,23 +228,6 @@ txResultRecycler::getNodeSet(const txXPathNode& aNode, txAExprResult** aResult)
return NS_OK; return NS_OK;
} }
nsresult
txResultRecycler::getNodeSet(const txXPathNode& aNode, txNodeSet** aResult)
{
if (mNodeSetResults.isEmpty()) {
*aResult = new txNodeSet(aNode, this);
NS_ENSURE_TRUE(*aResult, NS_ERROR_OUT_OF_MEMORY);
}
else {
*aResult = static_cast<txNodeSet*>(mNodeSetResults.pop());
(*aResult)->append(aNode);
(*aResult)->mRecycler = this;
}
NS_ADDREF(*aResult);
return NS_OK;
}
nsresult nsresult
txResultRecycler::getNumberResult(double aValue, txAExprResult** aResult) txResultRecycler::getNumberResult(double aValue, txAExprResult** aResult)
{ {

Просмотреть файл

@ -86,7 +86,6 @@ public:
nsresult getNodeSet(txNodeSet** aResult); nsresult getNodeSet(txNodeSet** aResult);
nsresult getNodeSet(txNodeSet* aNodeSet, txNodeSet** aResult); nsresult getNodeSet(txNodeSet* aNodeSet, txNodeSet** aResult);
nsresult getNodeSet(const txXPathNode& aNode, txAExprResult** aResult); nsresult getNodeSet(const txXPathNode& aNode, txAExprResult** aResult);
nsresult getNodeSet(const txXPathNode& aNode, txNodeSet** aResult);
nsresult getNumberResult(double aValue, txAExprResult** aResult); nsresult getNumberResult(double aValue, txAExprResult** aResult);
/** /**

Просмотреть файл

@ -160,7 +160,7 @@ txMozillaXMLOutput::attribute(nsIAtom* aPrefix,
if (mOpenedElementIsHTML && aNsID == kNameSpaceID_None) { if (mOpenedElementIsHTML && aNsID == kNameSpaceID_None) {
nsAutoString lnameStr; nsAutoString lnameStr;
ToLowerCase(aLocalName, lnameStr); nsContentUtils::ASCIIToLower(aLocalName, lnameStr);
lname = do_GetAtom(lnameStr); lname = do_GetAtom(lnameStr);
} }
else { else {
@ -499,7 +499,7 @@ txMozillaXMLOutput::startElement(nsIAtom* aPrefix,
nsId = kNameSpaceID_XHTML; nsId = kNameSpaceID_XHTML;
nsAutoString lnameStr; nsAutoString lnameStr;
ToLowerCase(aLocalName, lnameStr); nsContentUtils::ASCIIToLower(aLocalName, lnameStr);
lname = do_GetAtom(lnameStr); lname = do_GetAtom(lnameStr);
} }
else { else {
@ -802,7 +802,7 @@ txMozillaXMLOutput::endHTMLElement(nsIContent* aElement)
nsAutoString value; nsAutoString value;
aElement->GetAttr(kNameSpaceID_None, nsGkAtoms::content, value); aElement->GetAttr(kNameSpaceID_None, nsGkAtoms::content, value);
if (!value.IsEmpty()) { if (!value.IsEmpty()) {
ToLowerCase(httpEquiv); nsContentUtils::ASCIIToLower(httpEquiv);
nsCOMPtr<nsIAtom> header = do_GetAtom(httpEquiv); nsCOMPtr<nsIAtom> header = do_GetAtom(httpEquiv);
processHTTPEquiv(header, value); processHTTPEquiv(header, value);
} }

Просмотреть файл

@ -788,11 +788,7 @@ nsXULPDGlobalObject::ClearGlobalObjectOwner()
if (this != nsXULPrototypeDocument::gSystemGlobal) if (this != nsXULPrototypeDocument::gSystemGlobal)
mCachedPrincipal = mGlobalObjectOwner->DocumentPrincipal(); mCachedPrincipal = mGlobalObjectOwner->DocumentPrincipal();
if (mContext) { mContext = NULL;
mContext->FinalizeContext();
mContext = NULL;
}
mGlobalObjectOwner = NULL; mGlobalObjectOwner = NULL;
} }

Просмотреть файл

@ -452,7 +452,6 @@
#include "nsDOMFile.h" #include "nsDOMFile.h"
#include "nsDOMFileReader.h" #include "nsDOMFileReader.h"
#include "nsIDOMFileException.h" #include "nsIDOMFileException.h"
#include "nsIDOMFileError.h"
#include "nsIDOMFormData.h" #include "nsIDOMFormData.h"
#include "nsIDOMDOMStringMap.h" #include "nsIDOMDOMStringMap.h"
@ -1394,8 +1393,6 @@ static nsDOMClassInfoData sClassInfoData[] = {
DOM_DEFAULT_SCRIPTABLE_FLAGS) DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(FileException, nsDOMGenericSH, NS_DEFINE_CLASSINFO_DATA(FileException, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS) DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(FileError, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(FileReader, nsEventTargetSH, NS_DEFINE_CLASSINFO_DATA(FileReader, nsEventTargetSH,
EVENTTARGET_SCRIPTABLE_FLAGS) EVENTTARGET_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(MozURLProperty, nsDOMGenericSH, NS_DEFINE_CLASSINFO_DATA(MozURLProperty, nsDOMGenericSH,
@ -3964,10 +3961,6 @@ nsDOMClassInfo::Init()
DOM_CLASSINFO_MAP_ENTRY(nsIDOMFileList) DOM_CLASSINFO_MAP_ENTRY(nsIDOMFileList)
DOM_CLASSINFO_MAP_END DOM_CLASSINFO_MAP_END
DOM_CLASSINFO_MAP_BEGIN(FileError, nsIDOMFileError)
DOM_CLASSINFO_MAP_ENTRY(nsIDOMFileError)
DOM_CLASSINFO_MAP_END
DOM_CLASSINFO_MAP_BEGIN(Blob, nsIDOMBlob) DOM_CLASSINFO_MAP_BEGIN(Blob, nsIDOMBlob)
DOM_CLASSINFO_MAP_ENTRY(nsIDOMBlob) DOM_CLASSINFO_MAP_ENTRY(nsIDOMBlob)
DOM_CLASSINFO_MAP_END DOM_CLASSINFO_MAP_END

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше