mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Merge from mozilla-central.
--HG-- rename : accessible/src/base/nsTextAttrs.cpp => accessible/src/base/TextAttrs.cpp rename : accessible/src/base/nsTextAttrs.h => accessible/src/base/TextAttrs.h
This commit is contained in:
commit
a0b4d7ed85
@ -571,3 +571,26 @@ interface nsIAccessibleTableChangeEvent: nsISupports
|
||||
readonly attribute long numRowsOrCols;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* An interface for virtual cursor changed events.
|
||||
* Passes previous cursor position and text offsets.
|
||||
*/
|
||||
[scriptable, uuid(370e8b9b-2bbc-4bff-a9c7-16ddc54aea21)]
|
||||
interface nsIAccessibleVirtualCursorChangeEvent : nsISupports
|
||||
{
|
||||
/**
|
||||
* Previous object pointed at by virtual cursor. null if none.
|
||||
*/
|
||||
readonly attribute nsIAccessible oldAccessible;
|
||||
|
||||
/**
|
||||
* Previous start offset of pivot. -1 if none.
|
||||
*/
|
||||
readonly attribute long oldStartOffset;
|
||||
|
||||
/**
|
||||
* Previous end offset of pivot. -1 if none.
|
||||
*/
|
||||
readonly attribute long oldEndOffset;
|
||||
};
|
||||
|
@ -380,3 +380,24 @@ AccTableChangeEvent::CreateXPCOMObject()
|
||||
return event;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// AccVCChangeEvent
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AccVCChangeEvent::
|
||||
AccVCChangeEvent(nsAccessible* aAccessible,
|
||||
nsIAccessible* aOldAccessible,
|
||||
PRInt32 aOldStart, PRInt32 aOldEnd) :
|
||||
AccEvent(::nsIAccessibleEvent::EVENT_VIRTUALCURSOR_CHANGED, aAccessible),
|
||||
mOldAccessible(aOldAccessible), mOldStart(aOldStart), mOldEnd(aOldEnd)
|
||||
{
|
||||
}
|
||||
|
||||
already_AddRefed<nsAccEvent>
|
||||
AccVCChangeEvent::CreateXPCOMObject()
|
||||
{
|
||||
nsAccEvent* event = new nsAccVirtualCursorChangeEvent(this);
|
||||
NS_ADDREF(event);
|
||||
return event;
|
||||
}
|
||||
|
@ -129,7 +129,8 @@ public:
|
||||
eShowEvent,
|
||||
eCaretMoveEvent,
|
||||
eSelectionChangeEvent,
|
||||
eTableChangeEvent
|
||||
eTableChangeEvent,
|
||||
eVirtualCursorChangeEvent
|
||||
};
|
||||
|
||||
static const EventGroup kEventGroup = eGenericEvent;
|
||||
@ -399,6 +400,37 @@ private:
|
||||
PRUint32 mNumRowsOrCols; // the number of inserted/deleted rows/columns
|
||||
};
|
||||
|
||||
/**
|
||||
* Accessible virtual cursor change event.
|
||||
*/
|
||||
class AccVCChangeEvent : public AccEvent
|
||||
{
|
||||
public:
|
||||
AccVCChangeEvent(nsAccessible* aAccessible,
|
||||
nsIAccessible* aOldAccessible,
|
||||
PRInt32 aOldStart, PRInt32 aOldEnd);
|
||||
|
||||
virtual ~AccVCChangeEvent() { }
|
||||
|
||||
// AccEvent
|
||||
virtual already_AddRefed<nsAccEvent> CreateXPCOMObject();
|
||||
|
||||
static const EventGroup kEventGroup = eVirtualCursorChangeEvent;
|
||||
virtual unsigned int GetEventGroups() const
|
||||
{
|
||||
return AccEvent::GetEventGroups() | (1U << eVirtualCursorChangeEvent);
|
||||
}
|
||||
|
||||
// AccTableChangeEvent
|
||||
nsIAccessible* OldAccessible() const { return mOldAccessible; }
|
||||
PRInt32 OldStartOffset() const { return mOldStart; }
|
||||
PRInt32 OldEndOffset() const { return mOldEnd; }
|
||||
|
||||
private:
|
||||
nsRefPtr<nsIAccessible> mOldAccessible;
|
||||
PRInt32 mOldStart;
|
||||
PRInt32 mOldEnd;
|
||||
};
|
||||
|
||||
/**
|
||||
* Downcast the generic accessible event object to derived type.
|
||||
|
@ -75,8 +75,8 @@ CPPSRCS = \
|
||||
nsCaretAccessible.cpp \
|
||||
nsTextAccessible.cpp \
|
||||
nsTextEquivUtils.cpp \
|
||||
nsTextAttrs.cpp \
|
||||
StyleInfo.cpp \
|
||||
TextAttrs.cpp \
|
||||
TextUpdater.cpp \
|
||||
$(NULL)
|
||||
|
||||
|
@ -131,3 +131,12 @@ StyleInfo::FormatFontStyle(const nscoord& aValue, nsAString& aFormattedValue)
|
||||
nsCSSProps::ValueToKeywordEnum(aValue, nsCSSProps::kFontStyleKTable);
|
||||
AppendUTF8toUTF16(nsCSSKeywords::GetStringValue(keyword), aFormattedValue);
|
||||
}
|
||||
|
||||
void
|
||||
StyleInfo::FormatTextDecorationStyle(PRUint8 aValue, nsAString& aFormattedValue)
|
||||
{
|
||||
nsCSSKeyword keyword =
|
||||
nsCSSProps::ValueToKeywordEnum(aValue,
|
||||
nsCSSProps::kTextDecorationStyleKTable);
|
||||
AppendUTF8toUTF16(nsCSSKeywords::GetStringValue(keyword), aFormattedValue);
|
||||
}
|
||||
|
@ -62,6 +62,7 @@ public:
|
||||
|
||||
static void FormatColor(const nscolor& aValue, nsString& aFormattedValue);
|
||||
static void FormatFontStyle(const nscoord& aValue, nsAString& aFormattedValue);
|
||||
static void FormatTextDecorationStyle(PRUint8 aValue, nsAString& aFormattedValue);
|
||||
|
||||
private:
|
||||
StyleInfo() MOZ_DELETE;
|
||||
|
@ -36,7 +36,7 @@
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsTextAttrs.h"
|
||||
#include "TextAttrs.h"
|
||||
|
||||
#include "nsAccUtils.h"
|
||||
#include "nsCoreUtils.h"
|
||||
@ -74,25 +74,15 @@ const char* const kCopyValue = nsnull;
|
||||
static nsCSSTextAttrMapItem gCSSTextAttrsMap[] =
|
||||
{
|
||||
// CSS name CSS value Attribute name Attribute value
|
||||
{ "text-decoration", "line-through", &nsGkAtoms::textLineThroughStyle, "solid" },
|
||||
{ "text-decoration", "underline", &nsGkAtoms::textUnderlineStyle, "solid" },
|
||||
{ "vertical-align", kAnyValue, &nsGkAtoms::textPosition, kCopyValue }
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsTextAttrs
|
||||
// TextAttrsMgr
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
nsTextAttrsMgr::nsTextAttrsMgr(nsHyperTextAccessible *aHyperTextAcc,
|
||||
bool aIncludeDefAttrs,
|
||||
nsAccessible *aOffsetAcc,
|
||||
PRInt32 aOffsetAccIdx) :
|
||||
mHyperTextAcc(aHyperTextAcc), mIncludeDefAttrs(aIncludeDefAttrs),
|
||||
mOffsetAcc(aOffsetAcc), mOffsetAccIdx(aOffsetAccIdx)
|
||||
{
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsTextAttrsMgr::GetAttributes(nsIPersistentProperties *aAttributes,
|
||||
void
|
||||
TextAttrsMgr::GetAttributes(nsIPersistentProperties* aAttributes,
|
||||
PRInt32* aStartHTOffset,
|
||||
PRInt32* aEndHTOffset)
|
||||
{
|
||||
@ -108,7 +98,7 @@ nsTextAttrsMgr::GetAttributes(nsIPersistentProperties *aAttributes,
|
||||
(!mOffsetAcc && mOffsetAccIdx == -1 &&
|
||||
!aStartHTOffset && !aEndHTOffset &&
|
||||
mIncludeDefAttrs && aAttributes)),
|
||||
"Wrong usage of nsTextAttrsMgr!");
|
||||
"Wrong usage of TextAttrsMgr!");
|
||||
|
||||
// Embedded objects are combined into own range with empty attributes set.
|
||||
if (mOffsetAcc && nsAccUtils::IsEmbeddedObject(mOffsetAcc)) {
|
||||
@ -130,7 +120,7 @@ nsTextAttrsMgr::GetAttributes(nsIPersistentProperties *aAttributes,
|
||||
(*aEndHTOffset)++;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the content and frame of the accessible. In the case of document
|
||||
@ -139,7 +129,7 @@ nsTextAttrsMgr::GetAttributes(nsIPersistentProperties *aAttributes,
|
||||
nsIFrame *rootFrame = mHyperTextAcc->GetFrame();
|
||||
NS_ASSERTION(rootFrame, "No frame for accessible!");
|
||||
if (!rootFrame)
|
||||
return NS_OK;
|
||||
return;
|
||||
|
||||
nsIContent *offsetNode = nsnull, *offsetElm = nsnull;
|
||||
nsIFrame *frame = nsnull;
|
||||
@ -149,26 +139,18 @@ nsTextAttrsMgr::GetAttributes(nsIPersistentProperties *aAttributes,
|
||||
frame = offsetElm->GetPrimaryFrame();
|
||||
}
|
||||
|
||||
nsTArray<nsITextAttr*> textAttrArray(10);
|
||||
nsTArray<TextAttr*> textAttrArray(9);
|
||||
|
||||
// "language" text attribute
|
||||
nsLangTextAttr langTextAttr(mHyperTextAcc, hyperTextElm, offsetNode);
|
||||
LangTextAttr langTextAttr(mHyperTextAcc, hyperTextElm, offsetNode);
|
||||
textAttrArray.AppendElement(&langTextAttr);
|
||||
|
||||
// "text-line-through-style" text attribute
|
||||
nsCSSTextAttr lineThroughTextAttr(0, hyperTextElm, offsetElm);
|
||||
textAttrArray.AppendElement(&lineThroughTextAttr);
|
||||
|
||||
// "text-underline-style" text attribute
|
||||
nsCSSTextAttr underlineTextAttr(1, hyperTextElm, offsetElm);
|
||||
textAttrArray.AppendElement(&underlineTextAttr);
|
||||
|
||||
// "text-position" text attribute
|
||||
nsCSSTextAttr posTextAttr(2, hyperTextElm, offsetElm);
|
||||
CSSTextAttr posTextAttr(0, hyperTextElm, offsetElm);
|
||||
textAttrArray.AppendElement(&posTextAttr);
|
||||
|
||||
// "background-color" text attribute
|
||||
nsBGColorTextAttr bgColorTextAttr(rootFrame, frame);
|
||||
BGColorTextAttr bgColorTextAttr(rootFrame, frame);
|
||||
textAttrArray.AppendElement(&bgColorTextAttr);
|
||||
|
||||
// "color" text attribute
|
||||
@ -180,7 +162,7 @@ nsTextAttrsMgr::GetAttributes(nsIPersistentProperties *aAttributes,
|
||||
textAttrArray.AppendElement(&fontFamilyTextAttr);
|
||||
|
||||
// "font-size" text attribute
|
||||
nsFontSizeTextAttr fontSizeTextAttr(rootFrame, frame);
|
||||
FontSizeTextAttr fontSizeTextAttr(rootFrame, frame);
|
||||
textAttrArray.AppendElement(&fontSizeTextAttr);
|
||||
|
||||
// "font-style" text attribute
|
||||
@ -188,33 +170,27 @@ nsTextAttrsMgr::GetAttributes(nsIPersistentProperties *aAttributes,
|
||||
textAttrArray.AppendElement(&fontStyleTextAttr);
|
||||
|
||||
// "font-weight" text attribute
|
||||
nsFontWeightTextAttr fontWeightTextAttr(rootFrame, frame);
|
||||
FontWeightTextAttr fontWeightTextAttr(rootFrame, frame);
|
||||
textAttrArray.AppendElement(&fontWeightTextAttr);
|
||||
|
||||
// "text-underline(line-through)-style(color)" text attributes
|
||||
TextDecorTextAttr textDecorTextAttr(rootFrame, frame);
|
||||
textAttrArray.AppendElement(&textDecorTextAttr);
|
||||
|
||||
// Expose text attributes if applicable.
|
||||
if (aAttributes) {
|
||||
PRUint32 len = textAttrArray.Length();
|
||||
for (PRUint32 idx = 0; idx < len; idx++) {
|
||||
nsITextAttr *textAttr = textAttrArray[idx];
|
||||
|
||||
nsAutoString value;
|
||||
if (textAttr->GetValue(value, mIncludeDefAttrs))
|
||||
nsAccUtils::SetAccAttr(aAttributes, textAttr->GetName(), value);
|
||||
for (PRUint32 idx = 0; idx < len; idx++)
|
||||
textAttrArray[idx]->Expose(aAttributes, mIncludeDefAttrs);
|
||||
}
|
||||
}
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
// Expose text attributes range where they are applied if applicable.
|
||||
if (mOffsetAcc)
|
||||
rv = GetRange(textAttrArray, aStartHTOffset, aEndHTOffset);
|
||||
|
||||
textAttrArray.Clear();
|
||||
return rv;
|
||||
GetRange(textAttrArray, aStartHTOffset, aEndHTOffset);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsTextAttrsMgr::GetRange(const nsTArray<nsITextAttr*>& aTextAttrArray,
|
||||
void
|
||||
TextAttrsMgr::GetRange(const nsTArray<TextAttr*>& aTextAttrArray,
|
||||
PRInt32* aStartHTOffset, PRInt32* aEndHTOffset)
|
||||
{
|
||||
PRUint32 attrLen = aTextAttrArray.Length();
|
||||
@ -229,11 +205,12 @@ nsTextAttrsMgr::GetRange(const nsTArray<nsITextAttr*>& aTextAttrArray,
|
||||
break;
|
||||
|
||||
nsIContent* currElm = nsCoreUtils::GetDOMElementFor(currAcc->GetContent());
|
||||
NS_ENSURE_STATE(currElm);
|
||||
if (!currElm)
|
||||
return;
|
||||
|
||||
bool offsetFound = false;
|
||||
for (PRUint32 attrIdx = 0; attrIdx < attrLen; attrIdx++) {
|
||||
nsITextAttr *textAttr = aTextAttrArray[attrIdx];
|
||||
TextAttr* textAttr = aTextAttrArray[attrIdx];
|
||||
if (!textAttr->Equal(currElm)) {
|
||||
offsetFound = true;
|
||||
break;
|
||||
@ -254,11 +231,12 @@ nsTextAttrsMgr::GetRange(const nsTArray<nsITextAttr*>& aTextAttrArray,
|
||||
break;
|
||||
|
||||
nsIContent* currElm = nsCoreUtils::GetDOMElementFor(currAcc->GetContent());
|
||||
NS_ENSURE_STATE(currElm);
|
||||
if (!currElm)
|
||||
return;
|
||||
|
||||
bool offsetFound = false;
|
||||
for (PRUint32 attrIdx = 0; attrIdx < attrLen; attrIdx++) {
|
||||
nsITextAttr *textAttr = aTextAttrArray[attrIdx];
|
||||
TextAttr* textAttr = aTextAttrArray[attrIdx];
|
||||
|
||||
// Alter the end offset when text attribute changes its value and stop
|
||||
// the search.
|
||||
@ -273,69 +251,68 @@ nsTextAttrsMgr::GetRange(const nsTArray<nsITextAttr*>& aTextAttrArray,
|
||||
|
||||
(*aEndHTOffset) += nsAccUtils::TextLength(currAcc);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsLangTextAttr
|
||||
|
||||
nsLangTextAttr::nsLangTextAttr(nsHyperTextAccessible *aRootAcc,
|
||||
nsIContent *aRootContent, nsIContent *aContent) :
|
||||
nsTextAttr<nsAutoString>(aContent == nsnull), mRootContent(aRootContent)
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// LangTextAttr
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TextAttrsMgr::LangTextAttr::
|
||||
LangTextAttr(nsHyperTextAccessible* aRoot,
|
||||
nsIContent* aRootElm, nsIContent* aElm) :
|
||||
TTextAttr<nsString>(!aElm), mRootContent(aRootElm)
|
||||
{
|
||||
aRootAcc->Language(mRootNativeValue);
|
||||
aRoot->Language(mRootNativeValue);
|
||||
mIsRootDefined = !mRootNativeValue.IsEmpty();
|
||||
|
||||
if (aContent)
|
||||
mIsDefined = GetLang(aContent, mNativeValue);
|
||||
if (aElm)
|
||||
mIsDefined = GetLang(aElm, mNativeValue);
|
||||
}
|
||||
|
||||
bool
|
||||
nsLangTextAttr::GetValueFor(nsIContent *aElm, nsAutoString *aValue)
|
||||
TextAttrsMgr::LangTextAttr::
|
||||
GetValueFor(nsIContent* aElm, nsString* aValue)
|
||||
{
|
||||
return GetLang(aElm, *aValue);
|
||||
}
|
||||
|
||||
void
|
||||
nsLangTextAttr::Format(const nsAutoString& aValue, nsAString& aFormattedValue)
|
||||
TextAttrsMgr::LangTextAttr::
|
||||
ExposeValue(nsIPersistentProperties* aAttributes, const nsString& aValue)
|
||||
{
|
||||
aFormattedValue = aValue;
|
||||
nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::language, aValue);
|
||||
}
|
||||
|
||||
bool
|
||||
nsLangTextAttr::GetLang(nsIContent *aContent, nsAString& aLang)
|
||||
TextAttrsMgr::LangTextAttr::
|
||||
GetLang(nsIContent* aElm, nsAString& aLang)
|
||||
{
|
||||
nsCoreUtils::GetLanguageFor(aContent, mRootContent, aLang);
|
||||
nsCoreUtils::GetLanguageFor(aElm, mRootContent, aLang);
|
||||
return !aLang.IsEmpty();
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsCSSTextAttr
|
||||
// CSSTextAttr
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
nsCSSTextAttr::nsCSSTextAttr(PRUint32 aIndex, nsIContent *aRootContent,
|
||||
nsIContent *aContent) :
|
||||
nsTextAttr<nsAutoString>(aContent == nsnull), mIndex(aIndex)
|
||||
TextAttrsMgr::CSSTextAttr::
|
||||
CSSTextAttr(PRUint32 aIndex, nsIContent* aRootElm, nsIContent* aElm) :
|
||||
TTextAttr<nsString>(!aElm), mIndex(aIndex)
|
||||
{
|
||||
mIsRootDefined = GetValueFor(aRootContent, &mRootNativeValue);
|
||||
mIsRootDefined = GetValueFor(aRootElm, &mRootNativeValue);
|
||||
|
||||
if (aContent)
|
||||
mIsDefined = GetValueFor(aContent, &mNativeValue);
|
||||
}
|
||||
|
||||
nsIAtom*
|
||||
nsCSSTextAttr::GetName() const
|
||||
{
|
||||
return *gCSSTextAttrsMap[mIndex].mAttrName;
|
||||
if (aElm)
|
||||
mIsDefined = GetValueFor(aElm, &mNativeValue);
|
||||
}
|
||||
|
||||
bool
|
||||
nsCSSTextAttr::GetValueFor(nsIContent *aContent, nsAutoString *aValue)
|
||||
TextAttrsMgr::CSSTextAttr::
|
||||
GetValueFor(nsIContent* aElm, nsString* aValue)
|
||||
{
|
||||
nsCOMPtr<nsIDOMCSSStyleDeclaration> currStyleDecl =
|
||||
nsCoreUtils::GetComputedStyleDeclaration(EmptyString(), aContent);
|
||||
nsCoreUtils::GetComputedStyleDeclaration(EmptyString(), aElm);
|
||||
if (!currStyleDecl)
|
||||
return false;
|
||||
|
||||
@ -353,22 +330,30 @@ nsCSSTextAttr::GetValueFor(nsIContent *aContent, nsAutoString *aValue)
|
||||
}
|
||||
|
||||
void
|
||||
nsCSSTextAttr::Format(const nsAutoString& aValue, nsAString& aFormattedValue)
|
||||
TextAttrsMgr::CSSTextAttr::
|
||||
ExposeValue(nsIPersistentProperties* aAttributes, const nsString& aValue)
|
||||
{
|
||||
const char* attrValue = gCSSTextAttrsMap[mIndex].mAttrValue;
|
||||
if (attrValue != kCopyValue)
|
||||
AppendASCIItoUTF16(attrValue, aFormattedValue);
|
||||
else
|
||||
aFormattedValue = aValue;
|
||||
if (attrValue != kCopyValue) {
|
||||
nsAutoString formattedValue;
|
||||
AppendASCIItoUTF16(attrValue, formattedValue);
|
||||
nsAccUtils::SetAccAttr(aAttributes, *gCSSTextAttrsMap[mIndex].mAttrName,
|
||||
formattedValue);
|
||||
return;
|
||||
}
|
||||
|
||||
nsAccUtils::SetAccAttr(aAttributes, *gCSSTextAttrsMap[mIndex].mAttrName,
|
||||
aValue);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsBGColorTextAttr
|
||||
// BGColorTextAttr
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
nsBGColorTextAttr::nsBGColorTextAttr(nsIFrame *aRootFrame, nsIFrame *aFrame) :
|
||||
nsTextAttr<nscolor>(aFrame == nsnull), mRootFrame(aRootFrame)
|
||||
TextAttrsMgr::BGColorTextAttr::
|
||||
BGColorTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame) :
|
||||
TTextAttr<nscolor>(!aFrame), mRootFrame(aRootFrame)
|
||||
{
|
||||
mIsRootDefined = GetColor(mRootFrame, &mRootNativeValue);
|
||||
if (aFrame)
|
||||
@ -376,25 +361,26 @@ nsBGColorTextAttr::nsBGColorTextAttr(nsIFrame *aRootFrame, nsIFrame *aFrame) :
|
||||
}
|
||||
|
||||
bool
|
||||
nsBGColorTextAttr::GetValueFor(nsIContent *aContent, nscolor *aValue)
|
||||
TextAttrsMgr::BGColorTextAttr::
|
||||
GetValueFor(nsIContent* aElm, nscolor* aValue)
|
||||
{
|
||||
nsIFrame *frame = aContent->GetPrimaryFrame();
|
||||
if (!frame)
|
||||
return false;
|
||||
|
||||
return GetColor(frame, aValue);
|
||||
nsIFrame* frame = aElm->GetPrimaryFrame();
|
||||
return frame ? GetColor(frame, aValue) : false;
|
||||
}
|
||||
|
||||
void
|
||||
nsBGColorTextAttr::Format(const nscolor& aValue, nsAString& aFormattedValue)
|
||||
TextAttrsMgr::BGColorTextAttr::
|
||||
ExposeValue(nsIPersistentProperties* aAttributes, const nscolor& aValue)
|
||||
{
|
||||
nsAutoString value;
|
||||
StyleInfo::FormatColor(aValue, value);
|
||||
aFormattedValue = value;
|
||||
nsAutoString formattedValue;
|
||||
StyleInfo::FormatColor(aValue, formattedValue);
|
||||
nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::backgroundColor,
|
||||
formattedValue);
|
||||
}
|
||||
|
||||
bool
|
||||
nsBGColorTextAttr::GetColor(nsIFrame *aFrame, nscolor *aColor)
|
||||
TextAttrsMgr::BGColorTextAttr::
|
||||
GetColor(nsIFrame* aFrame, nscolor* aColor)
|
||||
{
|
||||
const nsStyleBackground* styleBackground = aFrame->GetStyleBackground();
|
||||
|
||||
@ -423,8 +409,9 @@ nsBGColorTextAttr::GetColor(nsIFrame *aFrame, nscolor *aColor)
|
||||
// ColorTextAttr
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ColorTextAttr::ColorTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame) :
|
||||
nsTextAttr<nscolor>(!aFrame)
|
||||
TextAttrsMgr::ColorTextAttr::
|
||||
ColorTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame) :
|
||||
TTextAttr<nscolor>(!aFrame)
|
||||
{
|
||||
mRootNativeValue = aRootFrame->GetStyleColor()->mColor;
|
||||
mIsRootDefined = true;
|
||||
@ -436,9 +423,10 @@ ColorTextAttr::ColorTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame) :
|
||||
}
|
||||
|
||||
bool
|
||||
ColorTextAttr::GetValueFor(nsIContent* aContent, nscolor* aValue)
|
||||
TextAttrsMgr::ColorTextAttr::
|
||||
GetValueFor(nsIContent* aElm, nscolor* aValue)
|
||||
{
|
||||
nsIFrame* frame = aContent->GetPrimaryFrame();
|
||||
nsIFrame* frame = aElm->GetPrimaryFrame();
|
||||
if (frame) {
|
||||
*aValue = frame->GetStyleColor()->mColor;
|
||||
return true;
|
||||
@ -448,11 +436,12 @@ ColorTextAttr::GetValueFor(nsIContent* aContent, nscolor* aValue)
|
||||
}
|
||||
|
||||
void
|
||||
ColorTextAttr::Format(const nscolor& aValue, nsAString& aFormattedValue)
|
||||
TextAttrsMgr::ColorTextAttr::
|
||||
ExposeValue(nsIPersistentProperties* aAttributes, const nscolor& aValue)
|
||||
{
|
||||
nsAutoString value;
|
||||
StyleInfo::FormatColor(aValue, value);
|
||||
aFormattedValue = value;
|
||||
nsAutoString formattedValue;
|
||||
StyleInfo::FormatColor(aValue, formattedValue);
|
||||
nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::color, formattedValue);
|
||||
}
|
||||
|
||||
|
||||
@ -460,8 +449,9 @@ ColorTextAttr::Format(const nscolor& aValue, nsAString& aFormattedValue)
|
||||
// FontFamilyTextAttr
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
FontFamilyTextAttr::FontFamilyTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame) :
|
||||
nsTextAttr<nsAutoString>(aFrame == nsnull)
|
||||
TextAttrsMgr::FontFamilyTextAttr::
|
||||
FontFamilyTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame) :
|
||||
TTextAttr<nsString>(!aFrame)
|
||||
{
|
||||
mIsRootDefined = GetFontFamily(aRootFrame, mRootNativeValue);
|
||||
|
||||
@ -470,24 +460,23 @@ FontFamilyTextAttr::FontFamilyTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame) :
|
||||
}
|
||||
|
||||
bool
|
||||
FontFamilyTextAttr::GetValueFor(nsIContent* aElm, nsAutoString* aValue)
|
||||
TextAttrsMgr::FontFamilyTextAttr::
|
||||
GetValueFor(nsIContent* aElm, nsString* aValue)
|
||||
{
|
||||
nsIFrame* frame = aElm->GetPrimaryFrame();
|
||||
if (!frame)
|
||||
return false;
|
||||
|
||||
return GetFontFamily(frame, *aValue);
|
||||
return frame ? GetFontFamily(frame, *aValue) : false;
|
||||
}
|
||||
|
||||
void
|
||||
FontFamilyTextAttr::Format(const nsAutoString& aValue,
|
||||
nsAString& aFormattedValue)
|
||||
TextAttrsMgr::FontFamilyTextAttr::
|
||||
ExposeValue(nsIPersistentProperties* aAttributes, const nsString& aValue)
|
||||
{
|
||||
aFormattedValue = aValue;
|
||||
nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::font_family, aValue);
|
||||
}
|
||||
|
||||
bool
|
||||
FontFamilyTextAttr::GetFontFamily(nsIFrame* aFrame, nsAutoString& aFamily)
|
||||
TextAttrsMgr::FontFamilyTextAttr::
|
||||
GetFontFamily(nsIFrame* aFrame, nsString& aFamily)
|
||||
{
|
||||
nsRefPtr<nsFontMetrics> fm;
|
||||
nsLayoutUtils::GetFontMetricsForFrame(aFrame, getter_AddRefs(fm));
|
||||
@ -501,36 +490,40 @@ FontFamilyTextAttr::GetFontFamily(nsIFrame* aFrame, nsAutoString& aFamily)
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsFontSizeTextAttr
|
||||
// FontSizeTextAttr
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
nsFontSizeTextAttr::nsFontSizeTextAttr(nsIFrame *aRootFrame, nsIFrame *aFrame) :
|
||||
nsTextAttr<nscoord>(aFrame == nsnull)
|
||||
TextAttrsMgr::FontSizeTextAttr::
|
||||
FontSizeTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame) :
|
||||
TTextAttr<nscoord>(!aFrame)
|
||||
{
|
||||
mDC = aRootFrame->PresContext()->DeviceContext();
|
||||
|
||||
mRootNativeValue = GetFontSize(aRootFrame);
|
||||
mRootNativeValue = aRootFrame->GetStyleFont()->mSize;
|
||||
mIsRootDefined = true;
|
||||
|
||||
if (aFrame) {
|
||||
mNativeValue = GetFontSize(aFrame);
|
||||
mNativeValue = aFrame->GetStyleFont()->mSize;
|
||||
mIsDefined = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
nsFontSizeTextAttr::GetValueFor(nsIContent *aContent, nscoord *aValue)
|
||||
TextAttrsMgr::FontSizeTextAttr::
|
||||
GetValueFor(nsIContent* aElm, nscoord* aValue)
|
||||
{
|
||||
nsIFrame *frame = aContent->GetPrimaryFrame();
|
||||
if (!frame)
|
||||
return false;
|
||||
|
||||
*aValue = GetFontSize(frame);
|
||||
nsIFrame* frame = aElm->GetPrimaryFrame();
|
||||
if (frame) {
|
||||
*aValue = frame->GetStyleFont()->mSize;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
nsFontSizeTextAttr::Format(const nscoord& aValue, nsAString& aFormattedValue)
|
||||
TextAttrsMgr::FontSizeTextAttr::
|
||||
ExposeValue(nsIPersistentProperties* aAttributes, const nscoord& aValue)
|
||||
{
|
||||
// Convert from nscoord to pt.
|
||||
//
|
||||
@ -548,13 +541,8 @@ nsFontSizeTextAttr::Format(const nscoord& aValue, nsAString& aFormattedValue)
|
||||
nsAutoString value;
|
||||
value.AppendInt(pts);
|
||||
value.Append(NS_LITERAL_STRING("pt"));
|
||||
aFormattedValue = value;
|
||||
}
|
||||
|
||||
nscoord
|
||||
nsFontSizeTextAttr::GetFontSize(nsIFrame *aFrame)
|
||||
{
|
||||
return aFrame->GetStyleFont()->mSize;
|
||||
nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::font_size, value);
|
||||
}
|
||||
|
||||
|
||||
@ -562,8 +550,9 @@ nsFontSizeTextAttr::GetFontSize(nsIFrame *aFrame)
|
||||
// FontStyleTextAttr
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
FontStyleTextAttr::FontStyleTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame) :
|
||||
nsTextAttr<nscoord>(!aFrame)
|
||||
TextAttrsMgr::FontStyleTextAttr::
|
||||
FontStyleTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame) :
|
||||
TTextAttr<nscoord>(!aFrame)
|
||||
{
|
||||
mRootNativeValue = aRootFrame->GetStyleFont()->mFont.style;
|
||||
mIsRootDefined = true;
|
||||
@ -575,7 +564,8 @@ FontStyleTextAttr::FontStyleTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame) :
|
||||
}
|
||||
|
||||
bool
|
||||
FontStyleTextAttr::GetValueFor(nsIContent* aContent, nscoord* aValue)
|
||||
TextAttrsMgr::FontStyleTextAttr::
|
||||
GetValueFor(nsIContent* aContent, nscoord* aValue)
|
||||
{
|
||||
nsIFrame* frame = aContent->GetPrimaryFrame();
|
||||
if (frame) {
|
||||
@ -587,19 +577,23 @@ FontStyleTextAttr::GetValueFor(nsIContent* aContent, nscoord* aValue)
|
||||
}
|
||||
|
||||
void
|
||||
FontStyleTextAttr::Format(const nscoord& aValue, nsAString& aFormattedValue)
|
||||
TextAttrsMgr::FontStyleTextAttr::
|
||||
ExposeValue(nsIPersistentProperties* aAttributes, const nscoord& aValue)
|
||||
{
|
||||
StyleInfo::FormatFontStyle(aValue, aFormattedValue);
|
||||
nsAutoString formattedValue;
|
||||
StyleInfo::FormatFontStyle(aValue, formattedValue);
|
||||
|
||||
nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::font_style, formattedValue);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsFontWeightTextAttr
|
||||
// FontWeightTextAttr
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
nsFontWeightTextAttr::nsFontWeightTextAttr(nsIFrame *aRootFrame,
|
||||
nsIFrame *aFrame) :
|
||||
nsTextAttr<PRInt32>(aFrame == nsnull)
|
||||
TextAttrsMgr::FontWeightTextAttr::
|
||||
FontWeightTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame) :
|
||||
TTextAttr<PRInt32>(!aFrame)
|
||||
{
|
||||
mRootNativeValue = GetFontWeight(aRootFrame);
|
||||
mIsRootDefined = true;
|
||||
@ -611,26 +605,31 @@ nsFontWeightTextAttr::nsFontWeightTextAttr(nsIFrame *aRootFrame,
|
||||
}
|
||||
|
||||
bool
|
||||
nsFontWeightTextAttr::GetValueFor(nsIContent *aContent, PRInt32 *aValue)
|
||||
TextAttrsMgr::FontWeightTextAttr::
|
||||
GetValueFor(nsIContent* aElm, PRInt32* aValue)
|
||||
{
|
||||
nsIFrame *frame = aContent->GetPrimaryFrame();
|
||||
if (!frame)
|
||||
return false;
|
||||
|
||||
nsIFrame* frame = aElm->GetPrimaryFrame();
|
||||
if (frame) {
|
||||
*aValue = GetFontWeight(frame);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
nsFontWeightTextAttr::Format(const PRInt32& aValue, nsAString& aFormattedValue)
|
||||
TextAttrsMgr::FontWeightTextAttr::
|
||||
ExposeValue(nsIPersistentProperties* aAttributes, const PRInt32& aValue)
|
||||
{
|
||||
nsAutoString value;
|
||||
value.AppendInt(aValue);
|
||||
aFormattedValue = value;
|
||||
nsAutoString formattedValue;
|
||||
formattedValue.AppendInt(aValue);
|
||||
|
||||
nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::fontWeight, formattedValue);
|
||||
}
|
||||
|
||||
PRInt32
|
||||
nsFontWeightTextAttr::GetFontWeight(nsIFrame *aFrame)
|
||||
TextAttrsMgr::FontWeightTextAttr::
|
||||
GetFontWeight(nsIFrame* aFrame)
|
||||
{
|
||||
// nsFont::width isn't suitable here because it's necessary to expose real
|
||||
// value of font weight (used font might not have some font weight values).
|
||||
@ -664,3 +663,82 @@ nsFontWeightTextAttr::GetFontWeight(nsIFrame *aFrame)
|
||||
return fontEntry->Weight();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// TextDecorTextAttr
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TextAttrsMgr::TextDecorValue::
|
||||
TextDecorValue(nsIFrame* aFrame)
|
||||
{
|
||||
const nsStyleTextReset* textReset = aFrame->GetStyleTextReset();
|
||||
mStyle = textReset->GetDecorationStyle();
|
||||
|
||||
bool isForegroundColor = false;
|
||||
textReset->GetDecorationColor(mColor, isForegroundColor);
|
||||
if (isForegroundColor)
|
||||
mColor = aFrame->GetStyleColor()->mColor;
|
||||
|
||||
mLine = textReset->mTextDecorationLine &
|
||||
(NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE |
|
||||
NS_STYLE_TEXT_DECORATION_LINE_LINE_THROUGH);
|
||||
}
|
||||
|
||||
TextAttrsMgr::TextDecorTextAttr::
|
||||
TextDecorTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame) :
|
||||
TTextAttr<TextDecorValue>(!aFrame)
|
||||
{
|
||||
mRootNativeValue = TextDecorValue(aRootFrame);
|
||||
mIsRootDefined = mRootNativeValue.IsDefined();
|
||||
|
||||
if (aFrame) {
|
||||
mNativeValue = TextDecorValue(aFrame);
|
||||
mIsDefined = mNativeValue.IsDefined();
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
TextAttrsMgr::TextDecorTextAttr::
|
||||
GetValueFor(nsIContent* aContent, TextDecorValue* aValue)
|
||||
{
|
||||
nsIFrame* frame = aContent->GetPrimaryFrame();
|
||||
if (frame) {
|
||||
*aValue = TextDecorValue(frame);
|
||||
return aValue->IsDefined();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
TextAttrsMgr::TextDecorTextAttr::
|
||||
ExposeValue(nsIPersistentProperties* aAttributes, const TextDecorValue& aValue)
|
||||
{
|
||||
if (aValue.IsUnderline()) {
|
||||
nsAutoString formattedStyle;
|
||||
StyleInfo::FormatTextDecorationStyle(aValue.Style(), formattedStyle);
|
||||
nsAccUtils::SetAccAttr(aAttributes,
|
||||
nsGkAtoms::textUnderlineStyle,
|
||||
formattedStyle);
|
||||
|
||||
nsAutoString formattedColor;
|
||||
StyleInfo::FormatColor(aValue.Color(), formattedColor);
|
||||
nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::textUnderlineColor,
|
||||
formattedColor);
|
||||
return;
|
||||
}
|
||||
|
||||
if (aValue.IsLineThrough()) {
|
||||
nsAutoString formattedStyle;
|
||||
StyleInfo::FormatTextDecorationStyle(aValue.Style(), formattedStyle);
|
||||
nsAccUtils::SetAccAttr(aAttributes,
|
||||
nsGkAtoms::textLineThroughStyle,
|
||||
formattedStyle);
|
||||
|
||||
nsAutoString formattedColor;
|
||||
StyleInfo::FormatColor(aValue.Color(), formattedColor);
|
||||
nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::textLineThroughColor,
|
||||
formattedColor);
|
||||
}
|
||||
}
|
443
accessible/src/base/TextAttrs.h
Normal file
443
accessible/src/base/TextAttrs.h
Normal file
@ -0,0 +1,443 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2007
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Alexander Surkov <surkov.alexander@gmail.com> (original author)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef nsTextAttrs_h_
|
||||
#define nsTextAttrs_h_
|
||||
|
||||
#include "nsIContent.h"
|
||||
#include "nsIFrame.h"
|
||||
#include "nsIPersistentProperties2.h"
|
||||
#include "nsStyleConsts.h"
|
||||
|
||||
class nsHyperTextAccessible;
|
||||
|
||||
namespace mozilla {
|
||||
namespace a11y {
|
||||
|
||||
/**
|
||||
* Used to expose text attributes for the hyper text accessible (see
|
||||
* nsHyperTextAccessible class).
|
||||
*
|
||||
* @note "invalid: spelling" text attribute is implemented entirely in
|
||||
* nsHyperTextAccessible class.
|
||||
*/
|
||||
class TextAttrsMgr
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Constructor. Used to expose default text attributes.
|
||||
*/
|
||||
TextAttrsMgr(nsHyperTextAccessible* aHyperTextAcc) :
|
||||
mHyperTextAcc(aHyperTextAcc), mIncludeDefAttrs(true),
|
||||
mOffsetAcc(nsnull), mOffsetAccIdx(-1) { }
|
||||
|
||||
/**
|
||||
* Constructor. Used to expose text attributes at the given offset.
|
||||
*
|
||||
* @param aHyperTextAcc [in] hyper text accessible text attributes are
|
||||
* calculated for
|
||||
* @param aIncludeDefAttrs [optional] indicates whether default text
|
||||
* attributes should be included into list of exposed
|
||||
* text attributes
|
||||
* @param oOffsetAcc [optional] offset an accessible the text attributes
|
||||
* should be calculated for
|
||||
* @param oOffsetAccIdx [optional] index in parent of offset accessible
|
||||
*/
|
||||
TextAttrsMgr(nsHyperTextAccessible* aHyperTextAcc,
|
||||
bool aIncludeDefAttrs,
|
||||
nsAccessible* aOffsetAcc,
|
||||
PRInt32 aOffsetAccIdx) :
|
||||
mHyperTextAcc(aHyperTextAcc), mIncludeDefAttrs(aIncludeDefAttrs),
|
||||
mOffsetAcc(aOffsetAcc), mOffsetAccIdx(aOffsetAccIdx) { }
|
||||
|
||||
/*
|
||||
* Return text attributes and hyper text offsets where these attributes are
|
||||
* applied. Offsets are calculated in the case of non default attributes.
|
||||
*
|
||||
* @note In the case of default attributes pointers on hyper text offsets
|
||||
* must be skipped.
|
||||
*
|
||||
* @param aAttributes [in, out] text attributes list
|
||||
* @param aStartHTOffset [out, optional] start hyper text offset
|
||||
* @param aEndHTOffset [out, optional] end hyper text offset
|
||||
*/
|
||||
void GetAttributes(nsIPersistentProperties* aAttributes,
|
||||
PRInt32* aStartHTOffset = nsnull,
|
||||
PRInt32* aEndHTOffset = nsnull);
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Calculates range (start and end offsets) of text where the text attributes
|
||||
* are stretched. New offsets may be smaller if one of text attributes changes
|
||||
* its value before or after the given offsets.
|
||||
*
|
||||
* @param aTextAttrArray [in] text attributes array
|
||||
* @param aStartHTOffset [in, out] the start offset
|
||||
* @param aEndHTOffset [in, out] the end offset
|
||||
*/
|
||||
class TextAttr;
|
||||
void GetRange(const nsTArray<TextAttr*>& aTextAttrArray,
|
||||
PRInt32* aStartHTOffset, PRInt32* aEndHTOffset);
|
||||
|
||||
private:
|
||||
nsHyperTextAccessible* mHyperTextAcc;
|
||||
|
||||
bool mIncludeDefAttrs;
|
||||
|
||||
nsAccessible* mOffsetAcc;
|
||||
PRInt32 mOffsetAccIdx;
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* Interface class of text attribute class implementations.
|
||||
*/
|
||||
class TextAttr
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Expose the text attribute to the given attribute set.
|
||||
*
|
||||
* @param aAttributes [in] the given attribute set
|
||||
* @param aIncludeDefAttrValue [in] if true then attribute is exposed even
|
||||
* if its value is the same as default one
|
||||
*/
|
||||
virtual void Expose(nsIPersistentProperties* aAttributes,
|
||||
bool aIncludeDefAttrValue) = 0;
|
||||
|
||||
/**
|
||||
* Return true if the text attribute value on the given element equals with
|
||||
* predefined attribute value.
|
||||
*/
|
||||
virtual bool Equal(nsIContent* aElm) = 0;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Base class to work with text attributes. See derived classes below.
|
||||
*/
|
||||
template<class T>
|
||||
class TTextAttr : public TextAttr
|
||||
{
|
||||
public:
|
||||
TTextAttr(bool aGetRootValue) : mGetRootValue(aGetRootValue) {}
|
||||
|
||||
// ITextAttr
|
||||
virtual void Expose(nsIPersistentProperties* aAttributes,
|
||||
bool aIncludeDefAttrValue)
|
||||
{
|
||||
if (mGetRootValue) {
|
||||
if (mIsRootDefined)
|
||||
ExposeValue(aAttributes, mRootNativeValue);
|
||||
return;
|
||||
}
|
||||
|
||||
if (mIsDefined) {
|
||||
if (aIncludeDefAttrValue || mRootNativeValue != mNativeValue)
|
||||
ExposeValue(aAttributes, mNativeValue);
|
||||
return;
|
||||
}
|
||||
|
||||
if (aIncludeDefAttrValue && mIsRootDefined)
|
||||
ExposeValue(aAttributes, mRootNativeValue);
|
||||
}
|
||||
|
||||
virtual bool Equal(nsIContent* aElm)
|
||||
{
|
||||
T nativeValue;
|
||||
bool isDefined = GetValueFor(aElm, &nativeValue);
|
||||
|
||||
if (!mIsDefined && !isDefined)
|
||||
return true;
|
||||
|
||||
if (mIsDefined && isDefined)
|
||||
return nativeValue == mNativeValue;
|
||||
|
||||
if (mIsDefined)
|
||||
return mNativeValue == mRootNativeValue;
|
||||
|
||||
return nativeValue == mRootNativeValue;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
// Expose the text attribute with the given value to attribute set.
|
||||
virtual void ExposeValue(nsIPersistentProperties* aAttributes,
|
||||
const T& aValue) = 0;
|
||||
|
||||
// Return native value for the given DOM element.
|
||||
virtual bool GetValueFor(nsIContent* aElm, T* aValue) = 0;
|
||||
|
||||
// Indicates if root value should be exposed.
|
||||
bool mGetRootValue;
|
||||
|
||||
// Native value and flag indicating if the value is defined (initialized in
|
||||
// derived classes). Note, undefined native value means it is inherited
|
||||
// from root.
|
||||
T mNativeValue;
|
||||
bool mIsDefined;
|
||||
|
||||
// Native root value and flag indicating if the value is defined (initialized
|
||||
// in derived classes).
|
||||
T mRootNativeValue;
|
||||
bool mIsRootDefined;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Class is used for the work with 'language' text attribute.
|
||||
*/
|
||||
class LangTextAttr : public TTextAttr<nsString>
|
||||
{
|
||||
public:
|
||||
LangTextAttr(nsHyperTextAccessible* aRoot, nsIContent* aRootElm,
|
||||
nsIContent* aElm);
|
||||
virtual ~LangTextAttr() { }
|
||||
|
||||
protected:
|
||||
|
||||
// TextAttr
|
||||
virtual bool GetValueFor(nsIContent* aElm, nsString* aValue);
|
||||
virtual void ExposeValue(nsIPersistentProperties* aAttributes,
|
||||
const nsString& aValue);
|
||||
|
||||
private:
|
||||
bool GetLang(nsIContent* aElm, nsAString& aLang);
|
||||
nsCOMPtr<nsIContent> mRootContent;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Class is used for the work with CSS based text attributes.
|
||||
*/
|
||||
class CSSTextAttr : public TTextAttr<nsString>
|
||||
{
|
||||
public:
|
||||
CSSTextAttr(PRUint32 aIndex, nsIContent* aRootElm, nsIContent* aElm);
|
||||
virtual ~CSSTextAttr() { }
|
||||
|
||||
protected:
|
||||
|
||||
// TextAttr
|
||||
virtual bool GetValueFor(nsIContent* aElm, nsString* aValue);
|
||||
virtual void ExposeValue(nsIPersistentProperties* aAttributes,
|
||||
const nsString& aValue);
|
||||
|
||||
private:
|
||||
PRInt32 mIndex;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Class is used for the work with 'background-color' text attribute.
|
||||
*/
|
||||
class BGColorTextAttr : public TTextAttr<nscolor>
|
||||
{
|
||||
public:
|
||||
BGColorTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame);
|
||||
virtual ~BGColorTextAttr() { }
|
||||
|
||||
protected:
|
||||
|
||||
// TextAttr
|
||||
virtual bool GetValueFor(nsIContent* aElm, nscolor* aValue);
|
||||
virtual void ExposeValue(nsIPersistentProperties* aAttributes,
|
||||
const nscolor& aValue);
|
||||
|
||||
private:
|
||||
bool GetColor(nsIFrame* aFrame, nscolor* aColor);
|
||||
nsIFrame* mRootFrame;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Class is used for the work with 'color' text attribute.
|
||||
*/
|
||||
class ColorTextAttr : public TTextAttr<nscolor>
|
||||
{
|
||||
public:
|
||||
ColorTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame);
|
||||
virtual ~ColorTextAttr() { }
|
||||
|
||||
protected:
|
||||
|
||||
// TTextAttr
|
||||
virtual bool GetValueFor(nsIContent* aElm, nscolor* aValue);
|
||||
virtual void ExposeValue(nsIPersistentProperties* aAttributes,
|
||||
const nscolor& aValue);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Class is used for the work with "font-family" text attribute.
|
||||
*/
|
||||
class FontFamilyTextAttr : public TTextAttr<nsString>
|
||||
{
|
||||
public:
|
||||
FontFamilyTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame);
|
||||
virtual ~FontFamilyTextAttr() { }
|
||||
|
||||
protected:
|
||||
|
||||
// TTextAttr
|
||||
virtual bool GetValueFor(nsIContent* aElm, nsString* aValue);
|
||||
virtual void ExposeValue(nsIPersistentProperties* aAttributes,
|
||||
const nsString& aValue);
|
||||
|
||||
private:
|
||||
|
||||
bool GetFontFamily(nsIFrame* aFrame, nsString& aFamily);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Class is used for the work with "font-size" text attribute.
|
||||
*/
|
||||
class FontSizeTextAttr : public TTextAttr<nscoord>
|
||||
{
|
||||
public:
|
||||
FontSizeTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame);
|
||||
virtual ~FontSizeTextAttr() { }
|
||||
|
||||
protected:
|
||||
|
||||
// TTextAttr
|
||||
virtual bool GetValueFor(nsIContent* aElm, nscoord* aValue);
|
||||
virtual void ExposeValue(nsIPersistentProperties* aAttributes,
|
||||
const nscoord& aValue);
|
||||
|
||||
private:
|
||||
nsDeviceContext* mDC;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Class is used for the work with "font-style" text attribute.
|
||||
*/
|
||||
class FontStyleTextAttr : public TTextAttr<nscoord>
|
||||
{
|
||||
public:
|
||||
FontStyleTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame);
|
||||
virtual ~FontStyleTextAttr() { }
|
||||
|
||||
protected:
|
||||
|
||||
// TTextAttr
|
||||
virtual bool GetValueFor(nsIContent* aContent, nscoord* aValue);
|
||||
virtual void ExposeValue(nsIPersistentProperties* aAttributes,
|
||||
const nscoord& aValue);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Class is used for the work with "font-weight" text attribute.
|
||||
*/
|
||||
class FontWeightTextAttr : public TTextAttr<PRInt32>
|
||||
{
|
||||
public:
|
||||
FontWeightTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame);
|
||||
virtual ~FontWeightTextAttr() { }
|
||||
|
||||
protected:
|
||||
|
||||
// TTextAttr
|
||||
virtual bool GetValueFor(nsIContent* aElm, PRInt32* aValue);
|
||||
virtual void ExposeValue(nsIPersistentProperties* aAttributes,
|
||||
const PRInt32& aValue);
|
||||
|
||||
private:
|
||||
PRInt32 GetFontWeight(nsIFrame* aFrame);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* TextDecorTextAttr class is used for the work with
|
||||
* "text-line-through-style", "text-line-through-color",
|
||||
* "text-underline-style" and "text-underline-color" text attributes.
|
||||
*/
|
||||
|
||||
class TextDecorValue
|
||||
{
|
||||
public:
|
||||
TextDecorValue() { }
|
||||
TextDecorValue(nsIFrame* aFrame);
|
||||
|
||||
nscolor Color() const { return mColor; }
|
||||
PRUint8 Style() const { return mStyle; }
|
||||
|
||||
bool IsDefined() const
|
||||
{ return IsUnderline() || IsLineThrough(); }
|
||||
bool IsUnderline() const
|
||||
{ return mLine & NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE; }
|
||||
bool IsLineThrough() const
|
||||
{ return mLine & NS_STYLE_TEXT_DECORATION_LINE_LINE_THROUGH; }
|
||||
|
||||
bool operator ==(const TextDecorValue& aValue)
|
||||
{
|
||||
return mColor == aValue.mColor && mLine == aValue.mLine &&
|
||||
mStyle == aValue.mStyle;
|
||||
}
|
||||
bool operator !=(const TextDecorValue& aValue)
|
||||
{ return !(*this == aValue); }
|
||||
|
||||
private:
|
||||
nscolor mColor;
|
||||
PRUint8 mLine;
|
||||
PRUint8 mStyle;
|
||||
};
|
||||
|
||||
class TextDecorTextAttr : public TTextAttr<TextDecorValue>
|
||||
{
|
||||
public:
|
||||
TextDecorTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame);
|
||||
virtual ~TextDecorTextAttr() { }
|
||||
|
||||
protected:
|
||||
|
||||
// TextAttr
|
||||
virtual bool GetValueFor(nsIContent* aElm, TextDecorValue* aValue);
|
||||
virtual void ExposeValue(nsIPersistentProperties* aAttributes,
|
||||
const TextDecorValue& aValue);
|
||||
};
|
||||
|
||||
}; // TextAttrMgr
|
||||
|
||||
} // namespace a11y
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
@ -1450,6 +1450,23 @@ nsAccessible::GetAttributesInternal(nsIPersistentProperties *aAttributes)
|
||||
if (!mContent->IsElement())
|
||||
return NS_OK;
|
||||
|
||||
// Expose draggable object attribute?
|
||||
nsCOMPtr<nsIDOMHTMLElement> htmlElement = do_QueryInterface(mContent);
|
||||
if (htmlElement) {
|
||||
bool draggable = false;
|
||||
htmlElement->GetDraggable(&draggable);
|
||||
if (draggable) {
|
||||
nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::draggable,
|
||||
NS_LITERAL_STRING("true"));
|
||||
}
|
||||
}
|
||||
|
||||
// Don't calculate CSS-based object attributes when no frame (i.e.
|
||||
// the accessible is not unattached form three) or when the accessible is not
|
||||
// primary for node (like list bullet or XUL tree items).
|
||||
if (!mContent->GetPrimaryFrame() || !IsPrimaryForNode())
|
||||
return NS_OK;
|
||||
|
||||
// CSS style based object attributes.
|
||||
nsAutoString value;
|
||||
StyleInfo styleInfo(mContent->AsElement(), mDoc->PresShell());
|
||||
@ -1482,17 +1499,6 @@ nsAccessible::GetAttributesInternal(nsIPersistentProperties *aAttributes)
|
||||
styleInfo.MarginBottom(value);
|
||||
nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::marginBottom, value);
|
||||
|
||||
// Expose draggable object attribute?
|
||||
nsCOMPtr<nsIDOMHTMLElement> htmlElement = do_QueryInterface(mContent);
|
||||
if (htmlElement) {
|
||||
bool draggable = false;
|
||||
htmlElement->GetDraggable(&draggable);
|
||||
if (draggable) {
|
||||
nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::draggable,
|
||||
NS_LITERAL_STRING("true"));
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -923,7 +923,8 @@ nsDocAccessible::OnPivotChanged(nsIAccessiblePivot* aPivot,
|
||||
nsIAccessible* aOldAccessible,
|
||||
PRInt32 aOldStart, PRInt32 aOldEnd)
|
||||
{
|
||||
nsRefPtr<AccEvent> event = new AccEvent(nsIAccessibleEvent::EVENT_VIRTUALCURSOR_CHANGED, this);
|
||||
nsRefPtr<AccEvent> event = new AccVCChangeEvent(this, aOldAccessible,
|
||||
aOldStart, aOldEnd);
|
||||
nsEventShell::FireEvent(event);
|
||||
|
||||
return NS_OK;
|
||||
|
@ -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 "nsAccUtils.h"
|
||||
#include "nsDocAccessible.h"
|
||||
#include "nsTextAttrs.h"
|
||||
#include "Role.h"
|
||||
#include "States.h"
|
||||
#include "TextAttrs.h"
|
||||
|
||||
#include "nsIClipboard.h"
|
||||
#include "nsContentUtils.h"
|
||||
@ -1130,8 +1130,8 @@ nsHyperTextAccessible::GetTextAttributes(bool aIncludeDefAttrs,
|
||||
// default attributes if they were requested, otherwise return empty set.
|
||||
if (aOffset == 0) {
|
||||
if (aIncludeDefAttrs) {
|
||||
nsTextAttrsMgr textAttrsMgr(this, true, nsnull, -1);
|
||||
return textAttrsMgr.GetAttributes(*aAttributes);
|
||||
TextAttrsMgr textAttrsMgr(this);
|
||||
textAttrsMgr.GetAttributes(*aAttributes);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
@ -1143,11 +1143,9 @@ nsHyperTextAccessible::GetTextAttributes(bool aIncludeDefAttrs,
|
||||
PRInt32 endOffset = GetChildOffset(accAtOffsetIdx + 1);
|
||||
PRInt32 offsetInAcc = aOffset - startOffset;
|
||||
|
||||
nsTextAttrsMgr textAttrsMgr(this, aIncludeDefAttrs, accAtOffset,
|
||||
TextAttrsMgr textAttrsMgr(this, aIncludeDefAttrs, accAtOffset,
|
||||
accAtOffsetIdx);
|
||||
nsresult rv = textAttrsMgr.GetAttributes(*aAttributes, &startOffset,
|
||||
&endOffset);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
textAttrsMgr.GetAttributes(*aAttributes, &startOffset, &endOffset);
|
||||
|
||||
// Compute spelling attributes on text accessible only.
|
||||
nsIFrame *offsetFrame = accAtOffset->GetFrame();
|
||||
@ -1186,8 +1184,9 @@ nsHyperTextAccessible::GetDefaultTextAttributes(nsIPersistentProperties **aAttri
|
||||
|
||||
NS_ADDREF(*aAttributes = attributes);
|
||||
|
||||
nsTextAttrsMgr textAttrsMgr(this, true);
|
||||
return textAttrsMgr.GetAttributes(*aAttributes);
|
||||
TextAttrsMgr textAttrsMgr(this);
|
||||
textAttrsMgr.GetAttributes(*aAttributes);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRInt32
|
||||
|
@ -253,3 +253,40 @@ nsAccTableChangeEvent::GetNumRowsOrCols(PRInt32* aNumRowsOrCols)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsAccVirtualCursorChangeEvent
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
NS_IMPL_ISUPPORTS_INHERITED1(nsAccVirtualCursorChangeEvent, nsAccEvent,
|
||||
nsIAccessibleVirtualCursorChangeEvent)
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAccVirtualCursorChangeEvent::GetOldAccessible(nsIAccessible** aOldAccessible)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aOldAccessible);
|
||||
|
||||
*aOldAccessible =
|
||||
static_cast<AccVCChangeEvent*>(mEvent.get())->OldAccessible();
|
||||
NS_IF_ADDREF(*aOldAccessible);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAccVirtualCursorChangeEvent::GetOldStartOffset(PRInt32* aOldStartOffset)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aOldStartOffset);
|
||||
|
||||
*aOldStartOffset =
|
||||
static_cast<AccVCChangeEvent*>(mEvent.get())->OldStartOffset();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAccVirtualCursorChangeEvent::GetOldEndOffset(PRInt32* aOldEndOffset)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aOldEndOffset);
|
||||
|
||||
*aOldEndOffset =
|
||||
static_cast<AccVCChangeEvent*>(mEvent.get())->OldEndOffset();
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -164,5 +164,25 @@ private:
|
||||
nsAccTableChangeEvent& operator =(const nsAccTableChangeEvent&);
|
||||
};
|
||||
|
||||
/**
|
||||
* Accessible virtual cursor change event.
|
||||
*/
|
||||
class nsAccVirtualCursorChangeEvent : public nsAccEvent,
|
||||
public nsIAccessibleVirtualCursorChangeEvent
|
||||
{
|
||||
public:
|
||||
nsAccVirtualCursorChangeEvent(AccVCChangeEvent* aEvent) :
|
||||
nsAccEvent(aEvent) { }
|
||||
virtual ~nsAccVirtualCursorChangeEvent() { }
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_NSIACCESSIBLEVIRTUALCURSORCHANGEEVENT
|
||||
|
||||
private:
|
||||
nsAccVirtualCursorChangeEvent() MOZ_DELETE;
|
||||
nsAccVirtualCursorChangeEvent(const nsAccVirtualCursorChangeEvent&) MOZ_DELETE;
|
||||
nsAccVirtualCursorChangeEvent& operator =(const nsAccVirtualCursorChangeEvent&) MOZ_DELETE;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -47,6 +47,23 @@ function testCSSAttrs(aID)
|
||||
testAttrs(aID, attrs, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the accessible that it doesn't have CSS-based object attributes.
|
||||
*/
|
||||
function testAbsentCSSAttrs(aID)
|
||||
{
|
||||
var attrs = {
|
||||
"display": "",
|
||||
"text-align": "",
|
||||
"text-indent": "",
|
||||
"margin-left": "",
|
||||
"margin-right": "",
|
||||
"margin-top": "",
|
||||
"margin-bottom": ""
|
||||
};
|
||||
testAbsentAttrs(aID, attrs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test group object attributes (posinset, setsize and level) and
|
||||
* nsIAccessible::groupPosition() method.
|
||||
|
@ -82,6 +82,9 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=689540
|
||||
testCSSAttrs("tr");
|
||||
testCSSAttrs("td");
|
||||
|
||||
// no CSS-based object attributes
|
||||
testAbsentCSSAttrs(getAccessible("listitem").firstChild);
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
@ -111,6 +114,11 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=689540
|
||||
title="Don't use GetComputedStyle for object attribute calculation">
|
||||
Mozilla Bug 714579
|
||||
</a>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=729831"
|
||||
title="Don't expose CSS-based object attributes on not in tree accessible and accessible having no DOM element">
|
||||
Mozilla Bug 729831
|
||||
</a>
|
||||
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
@ -189,5 +197,9 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=689540
|
||||
<td id="td">td</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<ul>
|
||||
<li id="listitem">item
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -269,13 +269,19 @@
|
||||
attrs = {};
|
||||
testTextAttrs(ID, 84, attrs, defAttrs, 83, 91);
|
||||
|
||||
attrs = { "text-underline-style": "solid" };
|
||||
attrs = {
|
||||
"text-underline-style": "solid",
|
||||
"text-underline-color": gComputedStyle.color
|
||||
};
|
||||
testTextAttrs(ID, 92, attrs, defAttrs, 91, 101);
|
||||
|
||||
attrs = {};
|
||||
testTextAttrs(ID, 102, attrs, defAttrs, 101, 109);
|
||||
|
||||
attrs = { "text-line-through-style": "solid" };
|
||||
attrs = {
|
||||
"text-line-through-style": "solid",
|
||||
"text-line-through-color": gComputedStyle.color
|
||||
};
|
||||
testTextAttrs(ID, 110, attrs, defAttrs, 109, 122);
|
||||
|
||||
attrs = {};
|
||||
@ -323,13 +329,19 @@
|
||||
attrs = {};
|
||||
testTextAttrs(ID, 85, attrs, defAttrs, 84, 92);
|
||||
|
||||
attrs = { "text-underline-style": "solid" };
|
||||
attrs = {
|
||||
"text-underline-style": "solid",
|
||||
"text-underline-color": gComputedStyle.color
|
||||
};
|
||||
testTextAttrs(ID, 93, attrs, defAttrs, 92, 102);
|
||||
|
||||
attrs = {};
|
||||
testTextAttrs(ID, 103, attrs, defAttrs, 102, 110);
|
||||
|
||||
attrs = { "text-line-through-style": "solid" };
|
||||
attrs = {
|
||||
"text-line-through-style": "solid",
|
||||
"text-line-through-color": gComputedStyle.color
|
||||
};
|
||||
testTextAttrs(ID, 111, attrs, defAttrs, 110, 123);
|
||||
|
||||
attrs = {};
|
||||
@ -437,6 +449,48 @@
|
||||
attrs = { };
|
||||
testTextAttrs(ID, 31, attrs, defAttrs, 31, 45);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// area17, "text-decoration" tests
|
||||
ID = "area17";
|
||||
defAttrs = buildDefaultTextAttrs(ID, "12pt");
|
||||
testDefaultTextAttrs(ID, defAttrs);
|
||||
|
||||
attrs = {
|
||||
"text-underline-style": "solid",
|
||||
"text-underline-color": "rgb(0, 0, 0)",
|
||||
};
|
||||
testTextAttrs(ID, 0, attrs, defAttrs, 0, 10);
|
||||
|
||||
attrs = {
|
||||
"text-underline-style": "solid",
|
||||
"text-underline-color": "rgb(0, 0, 255)",
|
||||
};
|
||||
testTextAttrs(ID, 10, attrs, defAttrs, 10, 15);
|
||||
|
||||
attrs = {
|
||||
"text-underline-style": "dotted",
|
||||
"text-underline-color": "rgb(0, 0, 0)",
|
||||
};
|
||||
testTextAttrs(ID, 15, attrs, defAttrs, 15, 22);
|
||||
|
||||
attrs = {
|
||||
"text-line-through-style": "solid",
|
||||
"text-line-through-color": "rgb(0, 0, 0)",
|
||||
};
|
||||
testTextAttrs(ID, 22, attrs, defAttrs, 22, 34);
|
||||
|
||||
attrs = {
|
||||
"text-line-through-style": "solid",
|
||||
"text-line-through-color": "rgb(0, 0, 255)",
|
||||
};
|
||||
testTextAttrs(ID, 34, attrs, defAttrs, 34, 39);
|
||||
|
||||
attrs = {
|
||||
"text-line-through-style": "wavy",
|
||||
"text-line-through-color": "rgb(0, 0, 0)",
|
||||
};
|
||||
testTextAttrs(ID, 39, attrs, defAttrs, 39, 44);
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
@ -450,12 +504,17 @@
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=345759"
|
||||
title="Implement text attributes">
|
||||
Mozilla Bug 345759
|
||||
</a><br>
|
||||
</a>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=473576"
|
||||
title="font-family text attribute should expose actual font used">
|
||||
Mozilla Bug 473576
|
||||
</a>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=523304"
|
||||
title="expose text-underline-color and text-line-through-color text attributes">
|
||||
Mozilla Bug 523304
|
||||
</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
@ -546,5 +605,15 @@
|
||||
<span style="font-family: Comic Sans MS, cursive;">text</span>text
|
||||
<span style="font-family: sans-serif, fantasy;">text</span>text
|
||||
</p>
|
||||
|
||||
<p id="area17">
|
||||
<span style="-moz-text-decoration-line: underline;">underline
|
||||
</span><span style="text-decoration: underline; -moz-text-decoration-color: blue;">blue
|
||||
</span><span style="text-decoration: underline; -moz-text-decoration-style: dotted;">dotted
|
||||
</span><span style="-moz-text-decoration-line: line-through;">linethrough
|
||||
</span><span style="text-decoration: line-through; -moz-text-decoration-color: blue;">blue
|
||||
</span><span style="text-decoration: line-through; -moz-text-decoration-style: wavy;">wavy
|
||||
</span>
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -10,6 +10,8 @@ const nsIAccessibleCaretMoveEvent =
|
||||
Components.interfaces.nsIAccessibleCaretMoveEvent;
|
||||
const nsIAccessibleTextChangeEvent =
|
||||
Components.interfaces.nsIAccessibleTextChangeEvent;
|
||||
const nsIAccessibleVirtualCursorChangeEvent =
|
||||
Components.interfaces.nsIAccessibleVirtualCursorChangeEvent;
|
||||
|
||||
const nsIAccessibleStates = Components.interfaces.nsIAccessibleStates;
|
||||
const nsIAccessibleRole = Components.interfaces.nsIAccessibleRole;
|
||||
|
@ -74,6 +74,15 @@ function virtualCursorChangedChecker(aDocAcc, aIdOrNameOrAcc, aTextOffsets)
|
||||
|
||||
this.check = function virtualCursorChangedChecker_check(aEvent)
|
||||
{
|
||||
SimpleTest.info("virtualCursorChangedChecker_check");
|
||||
|
||||
var event = null;
|
||||
try {
|
||||
event = aEvent.QueryInterface(nsIAccessibleVirtualCursorChangeEvent);
|
||||
} catch (e) {
|
||||
SimpleTest.ok(false, "Does not support correct interface: " + e);
|
||||
}
|
||||
|
||||
var position = aDocAcc.virtualCursor.position;
|
||||
|
||||
var idMatches = position.DOMNode.id == aIdOrNameOrAcc;
|
||||
@ -90,9 +99,38 @@ function virtualCursorChangedChecker(aDocAcc, aIdOrNameOrAcc, aTextOffsets)
|
||||
SimpleTest.is(aDocAcc.virtualCursor.endOffset, aTextOffsets[1],
|
||||
"wrong end offset");
|
||||
}
|
||||
|
||||
var prevPosAndOffset = virtualCursorChangedChecker.
|
||||
getPreviousPosAndOffset(aDocAcc.virtualCursor);
|
||||
|
||||
if (prevPosAndOffset) {
|
||||
SimpleTest.is(event.oldAccessible, prevPosAndOffset.position,
|
||||
"previous position does not match");
|
||||
SimpleTest.is(event.oldStartOffset, prevPosAndOffset.startOffset,
|
||||
"previous start offset does not match");
|
||||
SimpleTest.is(event.oldEndOffset, prevPosAndOffset.endOffset,
|
||||
"previous end offset does not match");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
virtualCursorChangedChecker.prevPosAndOffset = {};
|
||||
|
||||
virtualCursorChangedChecker.storePreviousPosAndOffset =
|
||||
function storePreviousPosAndOffset(aPivot)
|
||||
{
|
||||
virtualCursorChangedChecker.prevPosAndOffset[aPivot] =
|
||||
{position: aPivot.position,
|
||||
startOffset: aPivot.startOffset,
|
||||
endOffset: aPivot.endOffset};
|
||||
};
|
||||
|
||||
virtualCursorChangedChecker.getPreviousPosAndOffset =
|
||||
function getPreviousPosAndOffset(aPivot)
|
||||
{
|
||||
return virtualCursorChangedChecker.prevPosAndOffset[aPivot];
|
||||
};
|
||||
|
||||
/**
|
||||
* Set a text range in the pivot and wait for virtual cursor change event.
|
||||
*
|
||||
@ -105,6 +143,8 @@ function setVirtualCursorRangeInvoker(aDocAcc, aTextAccessible, aTextOffsets)
|
||||
{
|
||||
this.invoke = function virtualCursorChangedInvoker_invoke()
|
||||
{
|
||||
virtualCursorChangedChecker.
|
||||
storePreviousPosAndOffset(aDocAcc.virtualCursor);
|
||||
SimpleTest.info(prettyName(aTextAccessible) + " " + aTextOffsets);
|
||||
aDocAcc.virtualCursor.setTextRange(aTextAccessible,
|
||||
aTextOffsets[0],
|
||||
@ -136,6 +176,8 @@ function setVirtualCursorPosInvoker(aDocAcc, aPivotMoveMethod, aRule,
|
||||
{
|
||||
this.invoke = function virtualCursorChangedInvoker_invoke()
|
||||
{
|
||||
virtualCursorChangedChecker.
|
||||
storePreviousPosAndOffset(aDocAcc.virtualCursor);
|
||||
var moved = aDocAcc.virtualCursor[aPivotMoveMethod](aRule);
|
||||
SimpleTest.ok((aIdOrNameOrAcc && moved) || (!aIdOrNameOrAcc && !moved),
|
||||
"moved pivot");
|
||||
|
@ -1,5 +1,5 @@
|
||||
<?xml version="1.0"?>
|
||||
<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist" lastupdate="1330367012000">
|
||||
<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist" lastupdate="1331241604000">
|
||||
<emItems>
|
||||
<emItem blockID="i58" id="webmaster@buzzzzvideos.info">
|
||||
<versionRange minVersion="0" maxVersion="*">
|
||||
@ -19,18 +19,6 @@
|
||||
</emItem>
|
||||
<emItem blockID="i43" id="supportaccessplugin@gmail.com">
|
||||
</emItem>
|
||||
<emItem blockID="i38" id="{B7082FAA-CB62-4872-9106-E42DD88EDE45}">
|
||||
<versionRange minVersion="0.1" maxVersion="3.3.0.*">
|
||||
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
|
||||
<versionRange minVersion="3.7a1" maxVersion="*" />
|
||||
</targetApplication>
|
||||
</versionRange>
|
||||
<versionRange minVersion="3.3.1" maxVersion="*">
|
||||
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
|
||||
<versionRange minVersion="5.0a1" maxVersion="*" />
|
||||
</targetApplication>
|
||||
</versionRange>
|
||||
</emItem>
|
||||
<emItem blockID="i65" id="activity@facebook.com">
|
||||
<versionRange minVersion="0" maxVersion="*">
|
||||
</versionRange>
|
||||
@ -63,18 +51,6 @@
|
||||
</emItem>
|
||||
<emItem blockID="i10" id="{8CE11043-9A15-4207-A565-0C94C42D590D}">
|
||||
</emItem>
|
||||
<emItem blockID="i1" id="mozilla_cc@internetdownloadmanager.com">
|
||||
<versionRange minVersion="2.1" maxVersion="3.3">
|
||||
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
|
||||
<versionRange minVersion="3.0a1" maxVersion="*" />
|
||||
</targetApplication>
|
||||
</versionRange>
|
||||
<versionRange minVersion=" " maxVersion="6.9.8">
|
||||
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
|
||||
<versionRange minVersion="3.7a1pre" maxVersion="*" />
|
||||
</targetApplication>
|
||||
</versionRange>
|
||||
</emItem>
|
||||
<emItem blockID="i63" id="youtube@youtuber.com">
|
||||
<versionRange minVersion="0" maxVersion="*">
|
||||
</versionRange>
|
||||
@ -89,18 +65,8 @@
|
||||
<versionRange minVersion="0" maxVersion="*">
|
||||
</versionRange>
|
||||
</emItem>
|
||||
<emItem blockID="i4" id="{4B3803EA-5230-4DC3-A7FC-33638F3D3542}">
|
||||
<versionRange minVersion="1.2" maxVersion="1.2">
|
||||
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
|
||||
<versionRange minVersion="3.0a1" maxVersion="*" />
|
||||
</targetApplication>
|
||||
</versionRange>
|
||||
</emItem>
|
||||
<emItem blockID="i50" id="firebug@software.joehewitt.com">
|
||||
<versionRange minVersion="0" maxVersion="0">
|
||||
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
|
||||
<versionRange minVersion="9.0a1" maxVersion="9.*" />
|
||||
</targetApplication>
|
||||
<emItem blockID="i72" id="{4ED1F68A-5463-4931-9384-8FFF5ED91D92}">
|
||||
<versionRange minVersion="0" maxVersion="3.4.1.194" severity="1">
|
||||
</versionRange>
|
||||
</emItem>
|
||||
<emItem blockID="i40" id="{28387537-e3f9-4ed7-860c-11e69af4a8a0}">
|
||||
@ -121,13 +87,6 @@
|
||||
</emItem>
|
||||
<emItem blockID="i7" id="{2224e955-00e9-4613-a844-ce69fccaae91}">
|
||||
</emItem>
|
||||
<emItem blockID="i46" id="{841468a1-d7f4-4bd3-84e6-bb0f13a06c64}">
|
||||
<versionRange minVersion="0.1" maxVersion="*">
|
||||
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
|
||||
<versionRange minVersion="9.0a1" maxVersion="9.0" />
|
||||
</targetApplication>
|
||||
</versionRange>
|
||||
</emItem>
|
||||
<emItem blockID="i67" id="youtube2@youtube2.com">
|
||||
<versionRange minVersion="0" maxVersion="*">
|
||||
</versionRange>
|
||||
@ -136,35 +95,18 @@
|
||||
<versionRange minVersion="0" maxVersion="*">
|
||||
</versionRange>
|
||||
</emItem>
|
||||
<emItem blockID="i23" id="firefox@bandoo.com">
|
||||
<versionRange minVersion="5.0" maxVersion="5.0" severity="1">
|
||||
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
|
||||
<versionRange minVersion="3.7a1pre" maxVersion="*" />
|
||||
</targetApplication>
|
||||
<emItem blockID="i56" id="flash@adobe.com">
|
||||
<versionRange minVersion="0" maxVersion="*">
|
||||
</versionRange>
|
||||
</emItem>
|
||||
<emItem blockID="i55" id="youtube@youtube7.com">
|
||||
<versionRange minVersion="0" maxVersion="*">
|
||||
</versionRange>
|
||||
</emItem>
|
||||
<emItem blockID="i11" id="yslow@yahoo-inc.com">
|
||||
<versionRange minVersion="2.0.5" maxVersion="2.0.5">
|
||||
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
|
||||
<versionRange minVersion="3.5.7" maxVersion="*" />
|
||||
</targetApplication>
|
||||
</versionRange>
|
||||
</emItem>
|
||||
<emItem blockID="i22" id="ShopperReports@ShopperReports.com">
|
||||
<versionRange minVersion="3.1.22.0" maxVersion="3.1.22.0">
|
||||
</versionRange>
|
||||
</emItem>
|
||||
<emItem blockID="i2" id="fdm_ffext@freedownloadmanager.org">
|
||||
<versionRange minVersion="1.0" maxVersion="1.3.1">
|
||||
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
|
||||
<versionRange minVersion="3.0a1" maxVersion="*" />
|
||||
</targetApplication>
|
||||
</versionRange>
|
||||
</emItem>
|
||||
<emItem blockID="i44" id="sigma@labs.mozilla">
|
||||
</emItem>
|
||||
<emItem blockID="i5" id="support@daemon-tools.cc">
|
||||
@ -203,17 +145,6 @@
|
||||
<versionRange minVersion="2.2" maxVersion="2.2">
|
||||
</versionRange>
|
||||
</emItem>
|
||||
<emItem blockID="i56" id="flash@adobe.com">
|
||||
<versionRange minVersion="0" maxVersion="*">
|
||||
</versionRange>
|
||||
</emItem>
|
||||
<emItem blockID="i45" id="{22119944-ED35-4ab1-910B-E619EA06A115}">
|
||||
<versionRange minVersion="0.1" maxVersion="7.6.1">
|
||||
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
|
||||
<versionRange minVersion="8.0a1" maxVersion="*" />
|
||||
</targetApplication>
|
||||
</versionRange>
|
||||
</emItem>
|
||||
<emItem blockID="i19" id="{46551EC9-40F0-4e47-8E18-8E5CF550CFB8}">
|
||||
<versionRange minVersion="1.1b1" maxVersion="1.1b1">
|
||||
</versionRange>
|
||||
@ -230,39 +161,11 @@
|
||||
<versionRange minVersion="0" maxVersion="*">
|
||||
</versionRange>
|
||||
</emItem>
|
||||
<emItem blockID="i24" id="{6E19037A-12E3-4295-8915-ED48BC341614}">
|
||||
<versionRange minVersion="0.1" maxVersion="1.3.328.4" severity="1">
|
||||
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
|
||||
<versionRange minVersion="3.7a1pre" maxVersion="*" />
|
||||
</targetApplication>
|
||||
</versionRange>
|
||||
</emItem>
|
||||
<emItem blockID="i15" id="personas@christopher.beard">
|
||||
<versionRange minVersion="1.6" maxVersion="1.6">
|
||||
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
|
||||
<versionRange minVersion="3.6" maxVersion="3.6.*" />
|
||||
</targetApplication>
|
||||
</versionRange>
|
||||
</emItem>
|
||||
<emItem blockID="i21" id="support@update-firefox.com">
|
||||
</emItem>
|
||||
</emItems>
|
||||
|
||||
<pluginItems>
|
||||
<pluginItem blockID="p26">
|
||||
<match name="name" exp="^Yahoo Application State Plugin$" /> <match name="description" exp="^Yahoo Application State Plugin$" /> <match name="filename" exp="npYState.dll" /> <versionRange >
|
||||
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
|
||||
<versionRange minVersion="3.0a1" maxVersion="3.*" />
|
||||
</targetApplication>
|
||||
</versionRange>
|
||||
</pluginItem>
|
||||
<pluginItem blockID="p27">
|
||||
<match name="name" exp="QuickTime Plug-in 7[.]1[.]" /> <match name="filename" exp="npqtplugin.?[.]dll" /> <versionRange >
|
||||
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
|
||||
<versionRange minVersion="3.0a1" maxVersion="3.*" />
|
||||
</targetApplication>
|
||||
</versionRange>
|
||||
</pluginItem>
|
||||
<pluginItem blockID="p28">
|
||||
<match name="filename" exp="NPFFAddOn.dll" /> <versionRange >
|
||||
</versionRange>
|
||||
@ -271,24 +174,10 @@
|
||||
<match name="filename" exp="NPMySrch.dll" /> <versionRange >
|
||||
</versionRange>
|
||||
</pluginItem>
|
||||
<pluginItem blockID="p32">
|
||||
<match name="filename" exp="npViewpoint.dll" /> <versionRange >
|
||||
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
|
||||
<versionRange minVersion="3.0" maxVersion="*" />
|
||||
</targetApplication>
|
||||
</versionRange>
|
||||
</pluginItem>
|
||||
<pluginItem blockID="p33">
|
||||
<match name="name" exp="[0-6]\.0\.[01]\d{2}\.\d+" /> <match name="filename" exp="npdeploytk.dll" /> <versionRange severity="1">
|
||||
</versionRange>
|
||||
</pluginItem>
|
||||
<pluginItem blockID="p34">
|
||||
<match name="filename" exp="[Nn][Pp][Jj][Pp][Ii]1[56]0_[0-9]+\.[Dd][Ll][Ll]" /> <versionRange >
|
||||
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
|
||||
<versionRange minVersion="3.6a1pre" maxVersion="*" />
|
||||
</targetApplication>
|
||||
</versionRange>
|
||||
</pluginItem>
|
||||
</pluginItems>
|
||||
|
||||
<gfxItems>
|
||||
|
@ -291,12 +291,12 @@
|
||||
</menu>
|
||||
<menu id="pageStyleMenu" label="&pageStyleMenu.label;"
|
||||
accesskey="&pageStyleMenu.accesskey;" observes="isImage">
|
||||
<menupopup onpopupshowing="stylesheetFillPopup(this);"
|
||||
oncommand="stylesheetSwitchAll(window.content, event.target.getAttribute('data')); setStyleDisabled(false);">
|
||||
<menupopup onpopupshowing="gPageStyleMenu.fillPopup(this);"
|
||||
oncommand="gPageStyleMenu.switchStyleSheet(event.target.getAttribute('data'));">
|
||||
<menuitem id="menu_pageStyleNoStyle"
|
||||
label="&pageStyleNoStyle.label;"
|
||||
accesskey="&pageStyleNoStyle.accesskey;"
|
||||
oncommand="setStyleDisabled(true); event.stopPropagation();"
|
||||
oncommand="gPageStyleMenu.disableStyle(); event.stopPropagation();"
|
||||
type="radio"/>
|
||||
<menuitem id="menu_pageStylePersistentOnly"
|
||||
label="&pageStylePersistentOnly.label;"
|
||||
|
@ -5331,8 +5331,6 @@ function setToolbarVisibility(toolbar, isVisible) {
|
||||
|
||||
var TabsOnTop = {
|
||||
init: function TabsOnTop_init() {
|
||||
this._initialized = true;
|
||||
this.syncUI();
|
||||
Services.prefs.addObserver(this._prefName, this, false);
|
||||
},
|
||||
|
||||
@ -5345,9 +5343,6 @@ var TabsOnTop = {
|
||||
},
|
||||
|
||||
syncUI: function () {
|
||||
if (!this._initialized)
|
||||
return;
|
||||
|
||||
let userEnabled = Services.prefs.getBoolPref(this._prefName);
|
||||
let enabled = userEnabled && gBrowser.tabContainer.visible;
|
||||
|
||||
@ -6097,23 +6092,23 @@ function charsetLoadListener(event) {
|
||||
|
||||
var gPageStyleMenu = {
|
||||
|
||||
getAllStyleSheets: function (frameset) {
|
||||
_getAllStyleSheets: function (frameset) {
|
||||
var styleSheetsArray = Array.slice(frameset.document.styleSheets);
|
||||
for (let i = 0; i < frameset.frames.length; i++) {
|
||||
let frameSheets = this.getAllStyleSheets(frameset.frames[i]);
|
||||
let frameSheets = this._getAllStyleSheets(frameset.frames[i]);
|
||||
styleSheetsArray = styleSheetsArray.concat(frameSheets);
|
||||
}
|
||||
return styleSheetsArray;
|
||||
},
|
||||
|
||||
stylesheetFillPopup: function (menuPopup) {
|
||||
fillPopup: function (menuPopup) {
|
||||
var noStyle = menuPopup.firstChild;
|
||||
var persistentOnly = noStyle.nextSibling;
|
||||
var sep = persistentOnly.nextSibling;
|
||||
while (sep.nextSibling)
|
||||
menuPopup.removeChild(sep.nextSibling);
|
||||
|
||||
var styleSheets = this.getAllStyleSheets(window.content);
|
||||
var styleSheets = this._getAllStyleSheets(window.content);
|
||||
var currentStyleSheets = {};
|
||||
var styleDisabled = getMarkupDocumentViewer().authorStyleDisabled;
|
||||
var haveAltSheets = false;
|
||||
@ -6161,12 +6156,12 @@ var gPageStyleMenu = {
|
||||
return true;
|
||||
},
|
||||
|
||||
stylesheetInFrame: function (frame, title) {
|
||||
_stylesheetInFrame: function (frame, title) {
|
||||
return Array.some(frame.document.styleSheets,
|
||||
function (stylesheet) stylesheet.title == title);
|
||||
},
|
||||
|
||||
stylesheetSwitchFrame: function (frame, title) {
|
||||
_stylesheetSwitchFrame: function (frame, title) {
|
||||
var docStyleSheets = frame.document.styleSheets;
|
||||
|
||||
for (let i = 0; i < docStyleSheets.length; ++i) {
|
||||
@ -6181,26 +6176,34 @@ var gPageStyleMenu = {
|
||||
}
|
||||
},
|
||||
|
||||
stylesheetSwitchAll: function (frameset, title) {
|
||||
if (!title || title == "_nostyle" || this.stylesheetInFrame(frameset, title))
|
||||
this.stylesheetSwitchFrame(frameset, title);
|
||||
_stylesheetSwitchAll: function (frameset, title) {
|
||||
if (!title || title == "_nostyle" || this._stylesheetInFrame(frameset, title))
|
||||
this._stylesheetSwitchFrame(frameset, title);
|
||||
|
||||
for (let i = 0; i < frameset.frames.length; i++)
|
||||
this.stylesheetSwitchAll(frameset.frames[i], title);
|
||||
this._stylesheetSwitchAll(frameset.frames[i], title);
|
||||
},
|
||||
|
||||
setStyleDisabled: function (disabled) {
|
||||
getMarkupDocumentViewer().authorStyleDisabled = disabled;
|
||||
switchStyleSheet: function (title, contentWindow) {
|
||||
getMarkupDocumentViewer().authorStyleDisabled = false;
|
||||
this._stylesheetSwitchAll(contentWindow || content, title);
|
||||
},
|
||||
|
||||
disableStyle: function () {
|
||||
getMarkupDocumentViewer().authorStyleDisabled = true;
|
||||
},
|
||||
};
|
||||
|
||||
/* Legacy global page-style functions */
|
||||
var getAllStyleSheets = gPageStyleMenu.getAllStyleSheets;
|
||||
var stylesheetFillPopup = gPageStyleMenu.stylesheetFillPopup;
|
||||
var stylesheetInFrame = gPageStyleMenu.stylesheetInFrame;
|
||||
var stylesheetSwitchFrame = gPageStyleMenu.stylesheetSwitchFrame;
|
||||
var stylesheetSwitchAll = gPageStyleMenu.stylesheetSwitchAll;
|
||||
var setStyleDisabled = gPageStyleMenu.setStyleDisabled;
|
||||
var getAllStyleSheets = gPageStyleMenu._getAllStyleSheets.bind(gPageStyleMenu);
|
||||
var stylesheetFillPopup = gPageStyleMenu.fillPopup.bind(gPageStyleMenu);
|
||||
function stylesheetSwitchAll(contentWindow, title) {
|
||||
gPageStyleMenu.switchStyleSheet(title, contentWindow);
|
||||
}
|
||||
function setStyleDisabled(disabled) {
|
||||
if (disabled)
|
||||
gPageStyleMenu.disableStyle();
|
||||
}
|
||||
|
||||
|
||||
var BrowserOffline = {
|
||||
|
0
browser/base/content/global-scripts.inc
Normal file → Executable file
0
browser/base/content/global-scripts.inc
Normal file → Executable file
@ -2779,9 +2779,7 @@
|
||||
|
||||
Services.prefs.addObserver("browser.tabs.", this._prefObserver, false);
|
||||
window.addEventListener("resize", this, false);
|
||||
|
||||
this.updateVisibility();
|
||||
this._propagateVisibility();
|
||||
window.addEventListener("load", this, false);
|
||||
]]>
|
||||
</constructor>
|
||||
|
||||
@ -2841,15 +2839,19 @@
|
||||
this.parentNode && this.parentNode.localName == "toolbar" ? this.parentNode : this;
|
||||
]]></field>
|
||||
|
||||
<field name="_propagatedVisibilityOnce">false</field>
|
||||
|
||||
<property name="visible"
|
||||
onget="return !this._container.collapsed;">
|
||||
<setter><![CDATA[
|
||||
if (val == this.visible)
|
||||
if (val == this.visible &&
|
||||
this._propagatedVisibilityOnce)
|
||||
return val;
|
||||
|
||||
this._container.collapsed = !val;
|
||||
|
||||
this._propagateVisibility();
|
||||
this._propagatedVisibilityOnce = true;
|
||||
|
||||
return val;
|
||||
]]></setter>
|
||||
@ -3080,6 +3082,9 @@
|
||||
<parameter name="aEvent"/>
|
||||
<body><![CDATA[
|
||||
switch (aEvent.type) {
|
||||
case "load":
|
||||
this.updateVisibility();
|
||||
break;
|
||||
case "resize":
|
||||
if (aEvent.target != window)
|
||||
break;
|
||||
|
@ -14,7 +14,7 @@ function test() {
|
||||
function checkPageStyleMenu() {
|
||||
var menupopup = document.getElementById("pageStyleMenu")
|
||||
.getElementsByTagName("menupopup")[0];
|
||||
stylesheetFillPopup(menupopup);
|
||||
gPageStyleMenu.fillPopup(menupopup);
|
||||
|
||||
var items = [];
|
||||
var current = menupopup.getElementsByTagName("menuseparator")[0];
|
||||
|
@ -64,6 +64,9 @@ XPCOMUtils.defineLazyGetter(this, "PlacesUtils", function() {
|
||||
return PlacesUtils;
|
||||
});
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "KeywordURLResetPrompter",
|
||||
"resource:///modules/KeywordURLResetPrompter.jsm");
|
||||
|
||||
const PREF_PLUGINS_NOTIFYUSER = "plugins.update.notifyUser";
|
||||
const PREF_PLUGINS_UPDATEURL = "plugins.update.url";
|
||||
|
||||
@ -277,6 +280,13 @@ BrowserGlue.prototype = {
|
||||
this._initPlaces();
|
||||
}
|
||||
break;
|
||||
case "defaultURIFixup-using-keyword-pref":
|
||||
if (KeywordURLResetPrompter.shouldPrompt) {
|
||||
let keywordURI = subject.QueryInterface(Ci.nsIURI);
|
||||
KeywordURLResetPrompter.prompt(this.getMostRecentBrowserWindow(),
|
||||
keywordURI);
|
||||
}
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
@ -306,6 +316,7 @@ BrowserGlue.prototype = {
|
||||
os.addObserver(this, "distribution-customization-complete", false);
|
||||
os.addObserver(this, "places-shutdown", false);
|
||||
this._isPlacesShutdownObserver = true;
|
||||
os.addObserver(this, "defaultURIFixup-using-keyword-pref", false);
|
||||
},
|
||||
|
||||
// cleanup (called on application shutdown)
|
||||
@ -334,6 +345,7 @@ BrowserGlue.prototype = {
|
||||
os.removeObserver(this, "places-database-locked");
|
||||
if (this._isPlacesShutdownObserver)
|
||||
os.removeObserver(this, "places-shutdown");
|
||||
os.removeObserver(this, "defaultURIFixup-using-keyword-pref");
|
||||
},
|
||||
|
||||
_onAppDefaults: function BG__onAppDefaults() {
|
||||
|
@ -50,7 +50,7 @@ function test() {
|
||||
Array.forEach(tab.linkedBrowser.contentDocument.styleSheets, function(aSS, aIx) {
|
||||
pendingCount++;
|
||||
let ssTitle = aSS.title;
|
||||
stylesheetSwitchAll(tab.linkedBrowser.contentWindow, ssTitle);
|
||||
gPageStyleMenu.switchStyleSheet(ssTitle, tab.linkedBrowser.contentWindow);
|
||||
|
||||
let newTab = gBrowser.duplicateTab(tab);
|
||||
newTab.linkedBrowser.addEventListener("load", function(aEvent) {
|
||||
|
@ -568,6 +568,7 @@ DebuggerUI.prototype = {
|
||||
let dbg = this.getDebugger(this.aWindow.gBrowser.selectedTab);
|
||||
dbg.debuggerWindow.SourceScripts.setEditorMode(aSourceUrl, aContentType);
|
||||
dbg.editor.setText(aSourceText);
|
||||
dbg.editor.resetUndo();
|
||||
let doc = dbg.frame.contentDocument;
|
||||
let scripts = doc.getElementById("scripts");
|
||||
let elt = scripts.getElementsByAttribute("value", aSourceUrl)[0];
|
||||
|
@ -615,6 +615,7 @@ var SourceScripts = {
|
||||
window.editor.setText(aScript.text);
|
||||
window.updateEditorBreakpoints();
|
||||
}
|
||||
window.editor.resetUndo();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -45,10 +45,29 @@
|
||||
<!ENTITY % debuggerDTD SYSTEM "chrome://browser/locale/devtools/debugger.dtd" >
|
||||
%debuggerDTD;
|
||||
]>
|
||||
<?xul-overlay href="chrome://global/content/editMenuOverlay.xul"?>
|
||||
<?xul-overlay href="chrome://browser/content/source-editor-overlay.xul"?>
|
||||
<xul:window xmlns="http://www.w3.org/1999/xhtml"
|
||||
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
<xul:script type="text/javascript" src="chrome://global/content/globalOverlay.js"/>
|
||||
<xul:script type="text/javascript" src="debugger.js"/>
|
||||
<xul:script type="text/javascript" src="debugger-view.js"/>
|
||||
<xul:popupset id="debugger-popups">
|
||||
<xul:menupopup id="sourceEditorContextMenu"
|
||||
onpopupshowing="goUpdateSourceEditorMenuItems()">
|
||||
<xul:menuitem id="se-cMenu-copy"/>
|
||||
<xul:menuseparator/>
|
||||
<xul:menuitem id="se-cMenu-selectAll"/>
|
||||
<xul:menuseparator/>
|
||||
<xul:menuitem id="se-cMenu-find"/>
|
||||
<xul:menuitem id="se-cMenu-findAgain"/>
|
||||
<xul:menuseparator/>
|
||||
<xul:menuitem id="se-cMenu-gotoLine"/>
|
||||
</xul:menupopup>
|
||||
</xul:popupset>
|
||||
<xul:commandset id="editMenuCommands"/>
|
||||
<xul:commandset id="sourceEditorCommands"/>
|
||||
<xul:keyset id="sourceEditorKeys"/>
|
||||
|
||||
<div id="body" class="vbox flex">
|
||||
<xul:toolbar id="dbg-toolbar">
|
||||
|
@ -74,6 +74,7 @@ _BROWSER_TEST_FILES = \
|
||||
browser_dbg_select-line.js \
|
||||
browser_dbg_clean-exit.js \
|
||||
browser_dbg_bug723069_editor-breakpoints.js \
|
||||
browser_dbg_bug731394_editor-contextmenu.js \
|
||||
head.js \
|
||||
$(NULL)
|
||||
|
||||
|
@ -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/styleinspector.css (styleinspector/styleinspector.css)
|
||||
content/browser/orion.js (sourceeditor/orion/orion.js)
|
||||
content/browser/source-editor-overlay.xul (sourceeditor/source-editor-overlay.xul)
|
||||
* content/browser/source-editor-overlay.xul (sourceeditor/source-editor-overlay.xul)
|
||||
* content/browser/debugger.xul (debugger/debugger.xul)
|
||||
content/browser/debugger.css (debugger/debugger.css)
|
||||
content/browser/debugger.js (debugger/debugger.js)
|
||||
|
@ -111,21 +111,6 @@
|
||||
modifiers="accel"/>
|
||||
-->
|
||||
|
||||
<key id="key_cut"
|
||||
key="&cutCmd.key;"
|
||||
modifiers="accel"/>
|
||||
|
||||
<key id="key_copy"
|
||||
key="©Cmd.key;"
|
||||
modifiers="accel"/>
|
||||
<key id="key_paste"
|
||||
key="&pasteCmd.key;"
|
||||
modifiers="accel"/>
|
||||
<key id="key_selectAll" key="&selectAllCmd.key;" modifiers="accel"/>
|
||||
<key id="key_undo" key="&undoCmd.key;" modifiers="accel"
|
||||
command="se-cmd-undo"/>
|
||||
<key id="key_redo" key="&undoCmd.key;" modifiers="accel,shift"
|
||||
command="se-cmd-redo"/>
|
||||
<key id="sp-key-run"
|
||||
key="&run.key;"
|
||||
command="sp-cmd-run"
|
||||
@ -146,28 +131,6 @@
|
||||
key="&webConsoleCmd.commandkey;"
|
||||
command="sp-cmd-webConsole"
|
||||
modifiers="accel,shift"/>
|
||||
<key id="key_find"
|
||||
key="&findCmd.key;"
|
||||
command="cmd_find"
|
||||
modifiers="accel"/>
|
||||
#ifdef XP_MACOSX
|
||||
<key id="key_findAgain"
|
||||
key="&findAgainCmd.key;"
|
||||
command="cmd_findAgain"
|
||||
modifiers="accel"/>
|
||||
<key id="key_findPrevious"
|
||||
key="&findPreviousCmd.key;"
|
||||
command="cmd_findPrevious"
|
||||
modifiers="accel,shift"/>
|
||||
#else
|
||||
<key id="key_findAgain"
|
||||
keycode="VK_F3"
|
||||
command="cmd_findAgain"/>
|
||||
<key id="key_findPrevious"
|
||||
keycode="VK_F3"
|
||||
command="cmd_findPrevious"
|
||||
modifiers="shift"/>
|
||||
#endif
|
||||
<key id="key_openHelp"
|
||||
keycode="VK_F1"
|
||||
command="sp-cmd-documentationLink"/>
|
||||
@ -219,56 +182,20 @@
|
||||
<menu id="sp-edit-menu" label="&editMenu.label;"
|
||||
accesskey="&editMenu.accesskey;">
|
||||
<menupopup id="sp-menu_editpopup"
|
||||
onpopupshowing="goUpdateGlobalEditMenuItems()">
|
||||
<menuitem id="sp-menu-undo"
|
||||
label="&undoCmd.label;"
|
||||
key="key_undo"
|
||||
accesskey="&undoCmd.accesskey;"
|
||||
command="se-cmd-undo"/>
|
||||
<menuitem id="sp-menu-redo"
|
||||
label="&redoCmd.label;"
|
||||
key="key_redo"
|
||||
accesskey="&redoCmd.accesskey;"
|
||||
command="se-cmd-redo"/>
|
||||
onpopupshowing="goUpdateSourceEditorMenuItems()">
|
||||
<menuitem id="se-menu-undo"/>
|
||||
<menuitem id="se-menu-redo"/>
|
||||
<menuseparator/>
|
||||
<menuitem id="sp-menu-cut"
|
||||
label="&cutCmd.label;"
|
||||
key="key_cut"
|
||||
accesskey="&cutCmd.accesskey;"
|
||||
command="cmd_cut"/>
|
||||
<menuitem id="sp-menu-copy"
|
||||
label="©Cmd.label;"
|
||||
key="key_copy"
|
||||
accesskey="©Cmd.accesskey;"
|
||||
command="cmd_copy"/>
|
||||
<menuitem id="sp-menu-paste"
|
||||
label="&pasteCmd.label;"
|
||||
key="key_paste"
|
||||
accesskey="&pasteCmd.accesskey;"
|
||||
command="cmd_paste"/>
|
||||
<menuitem id="se-menu-cut"/>
|
||||
<menuitem id="se-menu-copy"/>
|
||||
<menuitem id="se-menu-paste"/>
|
||||
<menuseparator/>
|
||||
<menuitem id="sp-menu-selectAll"
|
||||
label="&selectAllCmd.label;"
|
||||
key="key_selectAll"
|
||||
accesskey="&selectAllCmd.accesskey;"
|
||||
command="cmd_selectAll"/>
|
||||
<menuitem id="se-menu-selectAll"/>
|
||||
<menuseparator/>
|
||||
<menuitem id="sp-menu-find"
|
||||
label="&findCmd.label;"
|
||||
accesskey="&findCmd.accesskey;"
|
||||
key="key_find"
|
||||
command="cmd_find"/>
|
||||
<menuitem id="sp-menu-findAgain"
|
||||
label="&findAgainCmd.label;"
|
||||
accesskey="&findAgainCmd.accesskey;"
|
||||
key="key_findAgain"
|
||||
command="cmd_findAgain"/>
|
||||
<menuitem id="se-menu-find"/>
|
||||
<menuitem id="se-menu-findAgain"/>
|
||||
<menuseparator/>
|
||||
<menuitem id="sp-menu-gotoLine"
|
||||
label="&gotoLineCmd.label;"
|
||||
accesskey="&gotoLineCmd.accesskey;"
|
||||
key="key_gotoLine"
|
||||
command="cmd_gotoLine"/>
|
||||
<menuitem id="se-menu-gotoLine"/>
|
||||
</menupopup>
|
||||
</menu>
|
||||
|
||||
@ -338,13 +265,13 @@
|
||||
|
||||
<popupset id="scratchpad-popups">
|
||||
<menupopup id="scratchpad-text-popup"
|
||||
onpopupshowing="goUpdateGlobalEditMenuItems()">
|
||||
<menuitem id="menu_cut"/>
|
||||
<menuitem id="menu_copy"/>
|
||||
<menuitem id="menu_paste"/>
|
||||
<menuitem id="menu_delete"/>
|
||||
onpopupshowing="goUpdateSourceEditorMenuItems()">
|
||||
<menuitem id="se-cMenu-cut"/>
|
||||
<menuitem id="se-cMenu-copy"/>
|
||||
<menuitem id="se-cMenu-paste"/>
|
||||
<menuitem id="se-cMenu-delete"/>
|
||||
<menuseparator/>
|
||||
<menuitem id="menu_selectAll"/>
|
||||
<menuitem id="se-cMenu-selectAll"/>
|
||||
<menuseparator/>
|
||||
<menuitem id="sp-text-run"
|
||||
label="&run.label;"
|
||||
@ -370,7 +297,7 @@
|
||||
</popupset>
|
||||
|
||||
<notificationbox id="scratchpad-notificationbox" flex="1">
|
||||
<hbox id="scratchpad-editor" flex="1" context="scratchpad-text-popup" />
|
||||
<hbox id="scratchpad-editor" flex="1"/>
|
||||
</notificationbox>
|
||||
|
||||
</window>
|
||||
|
@ -27,7 +27,7 @@ function runTests()
|
||||
let doc = gScratchpadWindow.document;
|
||||
let winUtils = gScratchpadWindow.QueryInterface(Ci.nsIInterfaceRequestor).
|
||||
getInterface(Ci.nsIDOMWindowUtils);
|
||||
let OS = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime).OS;
|
||||
let OS = Services.appinfo.OS;
|
||||
|
||||
info("will test the Edit menu");
|
||||
|
||||
@ -51,9 +51,9 @@ function runTests()
|
||||
|
||||
let menuPopup = editMenu.menupopup;
|
||||
ok(menuPopup, "the Edit menupopup");
|
||||
let cutItem = doc.getElementById("sp-menu-cut");
|
||||
let cutItem = doc.getElementById("se-menu-cut");
|
||||
ok(cutItem, "the Cut menuitem");
|
||||
let pasteItem = doc.getElementById("sp-menu-paste");
|
||||
let pasteItem = doc.getElementById("se-menu-paste");
|
||||
ok(pasteItem, "the Paste menuitem");
|
||||
|
||||
let anchor = doc.documentElement;
|
||||
@ -174,9 +174,9 @@ function runTests()
|
||||
|
||||
menuPopup = doc.getElementById("scratchpad-text-popup");
|
||||
ok(menuPopup, "the context menupopup");
|
||||
cutItem = doc.getElementById("menu_cut");
|
||||
cutItem = doc.getElementById("se-cMenu-cut");
|
||||
ok(cutItem, "the Cut menuitem");
|
||||
pasteItem = doc.getElementById("menu_paste");
|
||||
pasteItem = doc.getElementById("se-cMenu-paste");
|
||||
ok(pasteItem, "the Paste menuitem");
|
||||
|
||||
sp.setText("bug 699130: hello world! (context menu)");
|
||||
|
@ -24,6 +24,7 @@
|
||||
* Kenny Heaton <kennyheaton@gmail.com>
|
||||
* Spyros Livathinos <livathinos.spyros@gmail.com>
|
||||
* Allen Eubank <adeubank@gmail.com>
|
||||
* Girish Sharma <scrapmachines@gmail.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
@ -63,6 +64,14 @@ const ORION_IFRAME = "data:text/html;charset=utf8,<!DOCTYPE html>" +
|
||||
|
||||
const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
|
||||
|
||||
/**
|
||||
* Maximum allowed vertical offset for the line index when you call
|
||||
* SourceEditor.setCaretPosition().
|
||||
*
|
||||
* @type number
|
||||
*/
|
||||
const VERTICAL_OFFSET = 3;
|
||||
|
||||
/**
|
||||
* The primary selection update delay. On Linux, the X11 primary selection is
|
||||
* updated to hold the currently selected text.
|
||||
@ -109,6 +118,10 @@ const ORION_ANNOTATION_TYPES = {
|
||||
* Default key bindings in the Orion editor.
|
||||
*/
|
||||
const DEFAULT_KEYBINDINGS = [
|
||||
{
|
||||
action: "enter",
|
||||
code: Ci.nsIDOMKeyEvent.DOM_VK_ENTER,
|
||||
},
|
||||
{
|
||||
action: "undo",
|
||||
code: Ci.nsIDOMKeyEvent.DOM_VK_Z,
|
||||
@ -465,6 +478,10 @@ SourceEditor.prototype = {
|
||||
*/
|
||||
_doTab: function SE__doTab()
|
||||
{
|
||||
if (this.readOnly) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let indent = "\t";
|
||||
let selection = this.getSelection();
|
||||
let model = this._model;
|
||||
@ -515,6 +532,10 @@ SourceEditor.prototype = {
|
||||
*/
|
||||
_doUnindentLines: function SE__doUnindentLines()
|
||||
{
|
||||
if (this.readOnly) {
|
||||
return true;
|
||||
}
|
||||
|
||||
let indent = "\t";
|
||||
|
||||
let selection = this.getSelection();
|
||||
@ -569,6 +590,10 @@ SourceEditor.prototype = {
|
||||
*/
|
||||
_doEnter: function SE__doEnter()
|
||||
{
|
||||
if (this.readOnly) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let selection = this.getSelection();
|
||||
if (selection.start != selection.end) {
|
||||
return false;
|
||||
@ -1309,10 +1334,56 @@ SourceEditor.prototype = {
|
||||
* The new caret line location. Line numbers start from 0.
|
||||
* @param number [aColumn=0]
|
||||
* Optional. The new caret column location. Columns start from 0.
|
||||
* @param number [aAlign=0]
|
||||
* Optional. Position of the line with respect to viewport.
|
||||
* Allowed values are:
|
||||
* SourceEditor.VERTICAL_ALIGN.TOP target line at top of view.
|
||||
* SourceEditor.VERTICAL_ALIGN.CENTER target line at center of view.
|
||||
* SourceEditor.VERTICAL_ALIGN.BOTTOM target line at bottom of view.
|
||||
*/
|
||||
setCaretPosition: function SE_setCaretPosition(aLine, aColumn)
|
||||
setCaretPosition: function SE_setCaretPosition(aLine, aColumn, aAlign)
|
||||
{
|
||||
this.setCaretOffset(this._model.getLineStart(aLine) + (aColumn || 0));
|
||||
let editorHeight = this._view.getClientArea().height;
|
||||
let lineHeight = this._view.getLineHeight();
|
||||
let linesVisible = Math.floor(editorHeight/lineHeight);
|
||||
let halfVisible = Math.round(linesVisible/2);
|
||||
let firstVisible = this.getTopIndex();
|
||||
let lastVisible = this._view.getBottomIndex();
|
||||
let caretOffset = this._model.getLineStart(aLine) + (aColumn || 0);
|
||||
|
||||
this._view.setSelection(caretOffset, caretOffset, false);
|
||||
|
||||
// If the target line is in view, skip the vertical alignment part.
|
||||
if (aLine <= lastVisible && aLine >= firstVisible) {
|
||||
this._view.showSelection();
|
||||
return;
|
||||
}
|
||||
|
||||
// Setting the offset so that the line always falls in the upper half
|
||||
// of visible lines (lower half for BOTTOM aligned).
|
||||
// VERTICAL_OFFSET is the maximum allowed value.
|
||||
let offset = Math.min(halfVisible, VERTICAL_OFFSET);
|
||||
|
||||
let topIndex;
|
||||
switch (aAlign) {
|
||||
case this.VERTICAL_ALIGN.CENTER:
|
||||
topIndex = Math.max(aLine - halfVisible, 0);
|
||||
break;
|
||||
|
||||
case this.VERTICAL_ALIGN.BOTTOM:
|
||||
topIndex = Math.max(aLine - linesVisible + offset, 0);
|
||||
break;
|
||||
|
||||
default: // this.VERTICAL_ALIGN.TOP.
|
||||
topIndex = Math.max(aLine - offset, 0);
|
||||
break;
|
||||
}
|
||||
// Bringing down the topIndex to total lines in the editor if exceeding.
|
||||
topIndex = Math.min(topIndex, this.getLineCount());
|
||||
this.setTopIndex(topIndex);
|
||||
|
||||
let location = this._view.getLocationAtOffset(caretOffset);
|
||||
this._view.setHorizontalPixel(location.x);
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -35,43 +35,122 @@
|
||||
- the terms of any one of the MPL, the GPL or the LGPL.
|
||||
-
|
||||
- ***** END LICENSE BLOCK ***** -->
|
||||
<!DOCTYPE overlay SYSTEM "chrome://browser/locale/devtools/sourceeditor.dtd">
|
||||
<!DOCTYPE overlay [
|
||||
<!ENTITY % editMenuStrings SYSTEM "chrome://global/locale/editMenuOverlay.dtd">
|
||||
%editMenuStrings;
|
||||
<!ENTITY % sourceEditorStrings SYSTEM "chrome://browser/locale/devtools/sourceeditor.dtd">
|
||||
%sourceEditorStrings;
|
||||
]>
|
||||
<overlay id="sourceEditorOverlay"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
|
||||
<!-- This Source Editor overlay requires the editMenuOverlay.xul to be loaded.
|
||||
The globalOverlay.js script is also required in the XUL document where
|
||||
the source-editor-overlay.xul is loaded. -->
|
||||
the source-editor-overlay.xul is loaded. Do not use #editMenuKeys to
|
||||
avoid conflicts! -->
|
||||
|
||||
<script type="application/javascript">
|
||||
function goUpdateSourceEditorMenuItems()
|
||||
{
|
||||
goUpdateGlobalEditMenuItems();
|
||||
let commands = ['se-cmd-undo', 'se-cmd-redo', 'se-cmd-cut', 'se-cmd-paste',
|
||||
'se-cmd-delete'];
|
||||
commands.forEach(goUpdateCommand);
|
||||
}
|
||||
</script>
|
||||
|
||||
<commandset id="sourceEditorCommands">
|
||||
<command id="cmd_find" oncommand="goDoCommand('cmd_find')"/>
|
||||
<command id="cmd_findAgain" oncommand="goDoCommand('cmd_findAgain')" disabled="true"/>
|
||||
<command id="cmd_findPrevious" oncommand="goDoCommand('cmd_findPrevious')" disabled="true"/>
|
||||
<command id="cmd_gotoLine" oncommand="goDoCommand('cmd_gotoLine')"/>
|
||||
<command id="se-cmd-selectAll" oncommand="goDoCommand('se-cmd-selectAll')"/>
|
||||
<command id="se-cmd-cut" oncommand="goDoCommand('se-cmd-cut')" disabled="true"/>
|
||||
<command id="se-cmd-paste" oncommand="goDoCommand('se-cmd-paste')" disabled="true"/>
|
||||
<command id="se-cmd-delete" oncommand="goDoCommand('se-cmd-delete')" disabled="true"/>
|
||||
<command id="se-cmd-undo" oncommand="goDoCommand('se-cmd-undo')" disabled="true"/>
|
||||
<command id="se-cmd-redo" oncommand="goDoCommand('se-cmd-redo')" disabled="true"/>
|
||||
</commandset>
|
||||
|
||||
<keyset id="sourceEditorKeys">
|
||||
<!-- Do not use both #sourceEditorKeys and #editMenuKeys in the same
|
||||
document to avoid conflicts! -->
|
||||
<key id="key_undo"
|
||||
key="&undoCmd.key;"
|
||||
modifiers="accel"
|
||||
command="se-cmd-undo"/>
|
||||
#ifdef XP_UNIX
|
||||
<key id="key_redo"
|
||||
key="&undoCmd.key;"
|
||||
modifiers="accel,shift"
|
||||
command="se-cmd-redo"/>
|
||||
#else
|
||||
<key id="key_redo"
|
||||
key="&redoCmd.key;"
|
||||
modifiers="accel"
|
||||
command="se-cmd-redo"/>
|
||||
#endif
|
||||
<key id="key_cut"
|
||||
key="&cutCmd.key;"
|
||||
modifiers="accel"
|
||||
command="se-cmd-cut"/>
|
||||
<key id="key_copy"
|
||||
key="©Cmd.key;"
|
||||
modifiers="accel"
|
||||
command="cmd_copy"/>
|
||||
<key id="key_paste"
|
||||
key="&pasteCmd.key;"
|
||||
modifiers="accel"
|
||||
command="se-cmd-paste"/>
|
||||
<key id="key_gotoLine"
|
||||
key="&gotoLineCmd.key;"
|
||||
command="cmd_gotoLine"
|
||||
modifiers="accel"/>
|
||||
<key id="key_delete"
|
||||
keycode="VK_DELETE"
|
||||
command="se-cmd-delete"/>
|
||||
<key id="key_selectAll"
|
||||
key="&selectAllCmd.key;"
|
||||
modifiers="accel"
|
||||
command="se-cmd-selectAll"/>
|
||||
<key id="key_find"
|
||||
key="&findCmd.key;"
|
||||
modifiers="accel"
|
||||
command="cmd_find"/>
|
||||
<key id="key_findAgain"
|
||||
key="&findAgainCmd.key;"
|
||||
modifiers="accel"
|
||||
command="cmd_findAgain"/>
|
||||
<key id="key_findPrevious"
|
||||
key="&findAgainCmd.key;"
|
||||
modifiers="shift,accel"
|
||||
command="cmd_findPrevious"/>
|
||||
<key id="key_findAgain2"
|
||||
keycode="&findAgainCmd.key2;"
|
||||
command="cmd_findAgain"/>
|
||||
<key id="key_findPrevious2"
|
||||
keycode="&findAgainCmd.key2;"
|
||||
modifiers="shift"
|
||||
command="cmd_findPrevious"/>
|
||||
</keyset>
|
||||
|
||||
<menupopup id="sourceEditorContextMenu"
|
||||
onpopupshowing="goUpdateGlobalEditMenuItems()">
|
||||
<!-- Items for the Edit menu -->
|
||||
|
||||
<menuitem id="se-menu-undo"
|
||||
label="&undoCmd.label;"
|
||||
key="key_undo"
|
||||
accesskey="&undoCmd.accesskey;"
|
||||
command="se-cmd-undo"/>
|
||||
<menuseparator/>
|
||||
<menuitem id="se-menu-redo"
|
||||
label="&redoCmd.label;"
|
||||
key="key_redo"
|
||||
accesskey="&redoCmd.accesskey;"
|
||||
command="se-cmd-redo"/>
|
||||
<menuitem id="se-menu-cut"
|
||||
label="&cutCmd.label;"
|
||||
key="key_cut"
|
||||
accesskey="&cutCmd.accesskey;"
|
||||
command="cmd_cut"/>
|
||||
command="se-cmd-cut"/>
|
||||
<menuitem id="se-menu-copy"
|
||||
label="©Cmd.label;"
|
||||
key="key_copy"
|
||||
@ -81,19 +160,17 @@
|
||||
label="&pasteCmd.label;"
|
||||
key="key_paste"
|
||||
accesskey="&pasteCmd.accesskey;"
|
||||
command="cmd_paste"/>
|
||||
command="se-cmd-paste"/>
|
||||
<menuitem id="se-menu-delete"
|
||||
label="&deleteCmd.label;"
|
||||
key="key_delete"
|
||||
accesskey="&deleteCmd.accesskey;"
|
||||
command="cmd_delete"/>
|
||||
<menuseparator/>
|
||||
command="se-cmd-delete"/>
|
||||
<menuitem id="se-menu-selectAll"
|
||||
label="&selectAllCmd.label;"
|
||||
key="key_selectAll"
|
||||
accesskey="&selectAllCmd.accesskey;"
|
||||
command="cmd_selectAll"/>
|
||||
<menuseparator/>
|
||||
command="se-cmd-selectAll"/>
|
||||
<menuitem id="se-menu-find"
|
||||
label="&findCmd.label;"
|
||||
accesskey="&findCmd.accesskey;"
|
||||
@ -104,11 +181,57 @@
|
||||
accesskey="&findAgainCmd.accesskey;"
|
||||
key="key_findAgain"
|
||||
command="cmd_findAgain"/>
|
||||
<menuseparator/>
|
||||
<menuitem id="se-menu-gotoLine"
|
||||
label="&gotoLineCmd.label;"
|
||||
accesskey="&gotoLineCmd.accesskey;"
|
||||
key="key_gotoLine"
|
||||
command="cmd_gotoLine"/>
|
||||
</menupopup>
|
||||
|
||||
<!-- Items for 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="©Cmd.label;"
|
||||
key="key_copy"
|
||||
accesskey="©Cmd.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>
|
||||
|
@ -253,6 +253,10 @@ SourceEditorController.prototype = {
|
||||
case "cmd_gotoLine":
|
||||
case "se-cmd-undo":
|
||||
case "se-cmd-redo":
|
||||
case "se-cmd-cut":
|
||||
case "se-cmd-paste":
|
||||
case "se-cmd-delete":
|
||||
case "se-cmd-selectAll":
|
||||
result = true;
|
||||
break;
|
||||
default:
|
||||
@ -278,6 +282,7 @@ SourceEditorController.prototype = {
|
||||
switch (aCommand) {
|
||||
case "cmd_find":
|
||||
case "cmd_gotoLine":
|
||||
case "se-cmd-selectAll":
|
||||
result = true;
|
||||
break;
|
||||
case "cmd_findAgain":
|
||||
@ -290,6 +295,19 @@ SourceEditorController.prototype = {
|
||||
case "se-cmd-redo":
|
||||
result = this._editor.canRedo();
|
||||
break;
|
||||
case "se-cmd-cut":
|
||||
case "se-cmd-delete": {
|
||||
let selection = this._editor.getSelection();
|
||||
result = selection.start != selection.end && !this._editor.readOnly;
|
||||
break;
|
||||
}
|
||||
case "se-cmd-paste": {
|
||||
let window = this._editor._view._frameWindow;
|
||||
let controller = window.controllers.getControllerForCommand("cmd_paste");
|
||||
result = !this._editor.readOnly &&
|
||||
controller.isCommandEnabled("cmd_paste");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
result = false;
|
||||
break;
|
||||
@ -320,12 +338,26 @@ SourceEditorController.prototype = {
|
||||
case "cmd_gotoLine":
|
||||
this._editor.ui.gotoLine();
|
||||
break;
|
||||
case "se-cmd-selectAll":
|
||||
this._editor._view.invokeAction("selectAll");
|
||||
break;
|
||||
case "se-cmd-undo":
|
||||
this._editor.undo();
|
||||
break;
|
||||
case "se-cmd-redo":
|
||||
this._editor.redo();
|
||||
break;
|
||||
case "se-cmd-cut":
|
||||
this._editor.ui._ownerWindow.goDoCommand("cmd_cut");
|
||||
break;
|
||||
case "se-cmd-paste":
|
||||
this._editor.ui._ownerWindow.goDoCommand("cmd_paste");
|
||||
break;
|
||||
case "se-cmd-delete": {
|
||||
let selection = this._editor.getSelection();
|
||||
this._editor.setText("", selection.start, selection.end);
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -312,6 +312,16 @@ SourceEditor.EVENTS = {
|
||||
DIRTY_CHANGED: "DirtyChanged",
|
||||
};
|
||||
|
||||
/**
|
||||
* Allowed vertical alignment options for the line index
|
||||
* when you call SourceEditor.setCaretPosition().
|
||||
*/
|
||||
SourceEditor.VERTICAL_ALIGN = {
|
||||
TOP: 0,
|
||||
CENTER: 1,
|
||||
BOTTOM: 2,
|
||||
};
|
||||
|
||||
/**
|
||||
* Extend a destination object with properties from a source object.
|
||||
*
|
||||
@ -336,6 +346,7 @@ extend(SourceEditor.prototype, {
|
||||
MODES: SourceEditor.MODES,
|
||||
THEMES: SourceEditor.THEMES,
|
||||
DEFAULTS: SourceEditor.DEFAULTS,
|
||||
VERTICAL_ALIGN: SourceEditor.VERTICAL_ALIGN,
|
||||
|
||||
_lastFind: null,
|
||||
|
||||
|
@ -60,6 +60,7 @@ _BROWSER_TEST_FILES = \
|
||||
browser_bug712982_line_ruler_click.js \
|
||||
browser_bug725618_moveLines_shortcut.js \
|
||||
browser_bug700893_dirty_state.js \
|
||||
browser_bug729480_line_vertical_align.js \
|
||||
head.js \
|
||||
|
||||
libs:: $(_BROWSER_TEST_FILES)
|
||||
|
@ -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,6 +201,16 @@ function editorLoaded()
|
||||
editor.setText("foobar");
|
||||
is(editor.getText(), "foobar", "editor allows programmatic changes (setText)");
|
||||
|
||||
EventUtils.synthesizeKey("VK_RETURN", {}, testWin);
|
||||
is(editor.getText(), "foobar", "Enter key does nothing");
|
||||
|
||||
EventUtils.synthesizeKey("VK_TAB", {}, testWin);
|
||||
is(editor.getText(), "foobar", "Tab does nothing");
|
||||
|
||||
editor.setText(" foobar");
|
||||
EventUtils.synthesizeKey("VK_TAB", {shiftKey: true}, testWin);
|
||||
is(editor.getText(), " foobar", "Shift+Tab does nothing");
|
||||
|
||||
editor.readOnly = false;
|
||||
|
||||
editor.setCaretOffset(editor.getCharCount());
|
||||
|
@ -57,7 +57,22 @@
|
||||
<xul:script type="application/javascript" src="chrome://global/content/globalOverlay.js"/>
|
||||
|
||||
<xul:popupset id="style-editor-popups">
|
||||
<xul:menupopup id="sourceEditorContextMenu"/>
|
||||
<xul:menupopup id="sourceEditorContextMenu"
|
||||
onpopupshowing="goUpdateSourceEditorMenuItems()">
|
||||
<xul:menuitem id="se-cMenu-undo"/>
|
||||
<xul:menuseparator/>
|
||||
<xul:menuitem id="se-cMenu-cut"/>
|
||||
<xul:menuitem id="se-cMenu-copy"/>
|
||||
<xul:menuitem id="se-cMenu-paste"/>
|
||||
<xul:menuitem id="se-cMenu-delete"/>
|
||||
<xul:menuseparator/>
|
||||
<xul:menuitem id="se-cMenu-selectAll"/>
|
||||
<xul:menuseparator/>
|
||||
<xul:menuitem id="se-cMenu-find"/>
|
||||
<xul:menuitem id="se-cMenu-findAgain"/>
|
||||
<xul:menuseparator/>
|
||||
<xul:menuitem id="se-cMenu-gotoLine"/>
|
||||
</xul:menupopup>
|
||||
</xul:popupset>
|
||||
|
||||
<xul:commandset id="editMenuCommands"/>
|
||||
@ -66,7 +81,6 @@
|
||||
<xul:command id="style-editor-cmd-close" oncommand="window.close();"/>
|
||||
</xul:commandset>
|
||||
|
||||
<xul:keyset id="editMenuKeys"/>
|
||||
<xul:keyset id="sourceEditorKeys"/>
|
||||
<xul:keyset id="style-editor-keyset">
|
||||
<xul:key id="style-editor-key-close"
|
||||
|
@ -333,6 +333,22 @@ telemetryYesButtonLabel2 = Yes, I want to help
|
||||
telemetryYesButtonAccessKey = Y
|
||||
telemetryNoButtonLabel = No
|
||||
telemetryNoButtonAccessKey = N
|
||||
|
||||
# Keyword.URL reset prompt
|
||||
# LOCALIZATION NOTE (keywordPrompt.message):
|
||||
# - %1$S is brandShortName
|
||||
# - %2$S is a host name (e.g. "somewebsearch.com") from the current value of keyword.URL
|
||||
# - %3$S is the name of the default search engine (e.g. "Google")
|
||||
keywordPrompt.message = %1$S is using '%2$S' for searches from the location bar. Would you like to restore the default search (%3$S)?
|
||||
|
||||
# LOCALIZATION NOTE (keywordPrompt.yesButton): %1$S is the name of the default search engine
|
||||
keywordPrompt.yesButton = Yes, use %1$S
|
||||
keywordPrompt.yesButton.accessKey = Y
|
||||
|
||||
# LOCALIZATION NOTE (keywordPrompt.noButton): %1$S is a host name (e.g. "somewebsearch.com") from the current value of keyword.URL
|
||||
keywordPrompt.noButton = No, continue using '%1$S'
|
||||
keywordPrompt.noButton.accessKey = N
|
||||
|
||||
# Telemetry opt-out prompt for Aurora and Nightly
|
||||
# LOCALIZATION NOTE (telemetryOptOutPrompt): %1$S and %3$S will be replaced by
|
||||
# brandFullName, and %2$S by the value of the toolkit.telemetry.server_owner preference.
|
||||
|
@ -43,50 +43,6 @@
|
||||
<!ENTITY editMenu.label "Edit">
|
||||
<!ENTITY editMenu.accesskey "E">
|
||||
|
||||
<!ENTITY undoCmd.label "Undo">
|
||||
<!ENTITY undoCmd.key "Z">
|
||||
<!ENTITY undoCmd.accesskey "U">
|
||||
|
||||
<!ENTITY redoCmd.label "Redo">
|
||||
<!ENTITY redoCmd.key "Y">
|
||||
<!ENTITY redoCmd.accesskey "R">
|
||||
|
||||
<!ENTITY cutCmd.label "Cut">
|
||||
<!ENTITY cutCmd.key "X">
|
||||
<!ENTITY cutCmd.accesskey "t">
|
||||
|
||||
<!ENTITY copyCmd.label "Copy">
|
||||
<!ENTITY copyCmd.key "C">
|
||||
<!ENTITY copyCmd.accesskey "C">
|
||||
|
||||
<!ENTITY pasteCmd.label "Paste">
|
||||
<!ENTITY pasteCmd.key "V">
|
||||
<!ENTITY pasteCmd.accesskey "P">
|
||||
|
||||
<!ENTITY selectAllCmd.label "Select All">
|
||||
<!ENTITY selectAllCmd.key "A">
|
||||
<!ENTITY selectAllCmd.accesskey "A">
|
||||
|
||||
<!ENTITY findCmd.label "Find…">
|
||||
<!ENTITY findCmd.key "F">
|
||||
<!ENTITY findCmd.accesskey "F">
|
||||
|
||||
<!ENTITY findAgainCmd.label "Find Again…">
|
||||
<!-- LOCALIZATION NOTE (findAgainCmd.key): This key is used only on Macs.
|
||||
- Windows and Linux builds use the F3 key which is not localizable on purpose.
|
||||
-->
|
||||
<!ENTITY findAgainCmd.key "G">
|
||||
<!ENTITY findAgainCmd.accesskey "g">
|
||||
<!-- LOCALIZATION NOTE (findPreviousCmd.key): This key is used only on Macs.
|
||||
- Windows and Linux builds use the Shift-F3 key which is not localizable on
|
||||
- purpose.
|
||||
-->
|
||||
<!ENTITY findPreviousCmd.key "G">
|
||||
|
||||
<!ENTITY gotoLineCmd.label "Jump to line…">
|
||||
<!ENTITY gotoLineCmd.key "J">
|
||||
<!ENTITY gotoLineCmd.accesskey "J">
|
||||
|
||||
<!ENTITY run.label "Run">
|
||||
<!ENTITY run.accesskey "R">
|
||||
<!ENTITY run.key "r">
|
||||
|
@ -10,23 +10,6 @@
|
||||
- A good criteria is the language in which you'd find the best
|
||||
- documentation on web development on the web. -->
|
||||
|
||||
<!ENTITY undoCmd.label "Undo">
|
||||
<!ENTITY undoCmd.accesskey "U">
|
||||
<!ENTITY cutCmd.label "Cut">
|
||||
<!ENTITY cutCmd.accesskey "t">
|
||||
<!ENTITY copyCmd.label "Copy">
|
||||
<!ENTITY copyCmd.accesskey "C">
|
||||
<!ENTITY pasteCmd.label "Paste">
|
||||
<!ENTITY pasteCmd.accesskey "P">
|
||||
<!ENTITY deleteCmd.label "Delete">
|
||||
<!ENTITY deleteCmd.accesskey "D">
|
||||
<!ENTITY selectAllCmd.label "Select All">
|
||||
<!ENTITY selectAllCmd.accesskey "A">
|
||||
<!ENTITY findCmd.label "Find…">
|
||||
<!ENTITY findCmd.accesskey "F">
|
||||
<!ENTITY findAgainCmd.label "Find Again…">
|
||||
<!ENTITY findAgainCmd.accesskey "g">
|
||||
<!ENTITY gotoLineCmd.label "Jump to line…">
|
||||
<!ENTITY gotoLineCmd.key "J">
|
||||
<!ENTITY gotoLineCmd.accesskey "J">
|
||||
|
||||
|
105
browser/modules/KeywordURLResetPrompter.jsm
Normal file
105
browser/modules/KeywordURLResetPrompter.jsm
Normal file
@ -0,0 +1,105 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
let EXPORTED_SYMBOLS = [ "KeywordURLResetPrompter" ];
|
||||
|
||||
const Ci = Components.interfaces;
|
||||
const Cc = Components.classes;
|
||||
const Cu = Components.utils;
|
||||
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
const KEYWORD_PROMPT_REV = 1;
|
||||
|
||||
let KeywordURLResetPrompter = {
|
||||
get shouldPrompt() {
|
||||
let keywordURLUserSet = Services.prefs.prefHasUserValue("keyword.URL");
|
||||
let declinedRev;
|
||||
try {
|
||||
declinedRev = Services.prefs.getIntPref("browser.keywordURLPromptDeclined");
|
||||
} catch (ex) {}
|
||||
|
||||
return keywordURLUserSet && declinedRev != KEYWORD_PROMPT_REV;
|
||||
},
|
||||
|
||||
prompt: function KeywordURLResetPrompter_prompt(win, keywordURI) {
|
||||
let tabbrowser = win.gBrowser;
|
||||
let notifyBox = tabbrowser.getNotificationBox();
|
||||
|
||||
let existingNotification = notifyBox.getNotificationWithValue("keywordURL-reset");
|
||||
if (existingNotification)
|
||||
return;
|
||||
|
||||
// Find the name/URI of this build's original default engine.
|
||||
// XXX: Can't use originalDefaultEngine getter here, because that doesn't
|
||||
// use the default pref branch.
|
||||
let defaultURI;
|
||||
let defaultEngine;
|
||||
try {
|
||||
let defaultPB = Services.prefs.getDefaultBranch(null);
|
||||
let defaultName = defaultPB.getComplexValue("browser.search.defaultenginename",
|
||||
Ci.nsIPrefLocalizedString).data;
|
||||
defaultEngine = Services.search.getEngineByName(defaultName);
|
||||
defaultURI = defaultEngine.getSubmission("foo").uri;
|
||||
} catch (ex) {
|
||||
// Something went horribly wrong! bail out
|
||||
return;
|
||||
}
|
||||
|
||||
// If the user-set value has the same base domain as the default, don't
|
||||
// prompt.
|
||||
let keywordBaseDomain;
|
||||
try {
|
||||
keywordBaseDomain = Services.eTLD.getBaseDomain(keywordURI);
|
||||
if (keywordBaseDomain == Services.eTLD.getBaseDomain(defaultURI))
|
||||
return;
|
||||
} catch (ex) {}
|
||||
|
||||
if (!keywordBaseDomain)
|
||||
return;
|
||||
|
||||
let brandBundle = Services.strings.createBundle("chrome://branding/locale/brand.properties");
|
||||
let brandShortName = brandBundle.GetStringFromName("brandShortName");
|
||||
|
||||
let browserBundle = win.gNavigatorBundle;
|
||||
let msg = browserBundle.getFormattedString("keywordPrompt.message",
|
||||
[brandShortName, keywordBaseDomain,
|
||||
defaultEngine.name]);
|
||||
let buttons = [
|
||||
{
|
||||
label: browserBundle.getFormattedString("keywordPrompt.yesButton",
|
||||
[defaultEngine.name]),
|
||||
accessKey: browserBundle.getString("keywordPrompt.yesButton.accessKey"),
|
||||
popup: null,
|
||||
callback: function(aNotificationBar, aButton) {
|
||||
Services.prefs.clearUserPref("keyword.URL");
|
||||
try {
|
||||
// If the currently loaded URI still has the same base domain as the
|
||||
// keyword URI (this is used as a rough approximation of whether the
|
||||
// user is still seeing search results as opposed to having clicked
|
||||
// on a result link), load the default engine's searchForm URL so
|
||||
// that they can re-do their search.
|
||||
let currentBaseDomain = Services.eTLD.getBaseDomain(tabbrowser.currentURI);
|
||||
if (currentBaseDomain == keywordBaseDomain)
|
||||
tabbrowser.loadURI(defaultEngine.searchForm);
|
||||
} catch (ex) {}
|
||||
}
|
||||
},
|
||||
{
|
||||
label: browserBundle.getFormattedString("keywordPrompt.noButton",
|
||||
[keywordBaseDomain]),
|
||||
accessKey: browserBundle.getString("keywordPrompt.noButton.accessKey"),
|
||||
popup: null,
|
||||
callback: function(aNotificationBar, aButton) {
|
||||
Services.prefs.setIntPref("browser.keywordURLPromptDeclined", KEYWORD_PROMPT_REV);
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
let notification = notifyBox.appendNotification(msg, "keywordURL-reset", null, notifyBox.PRIORITY_WARNING_HIGH, buttons);
|
||||
notification.setAttribute("hideclose", true);
|
||||
// stick around for a few page loads in case there are redirects involved
|
||||
notification.persistence = 3;
|
||||
}
|
||||
}
|
@ -52,6 +52,7 @@ EXTRA_JS_MODULES = \
|
||||
NewTabUtils.jsm \
|
||||
offlineAppCache.jsm \
|
||||
TelemetryTimestamps.jsm \
|
||||
KeywordURLResetPrompter.jsm \
|
||||
$(NULL)
|
||||
|
||||
ifeq ($(MOZ_WIDGET_TOOLKIT),windows)
|
||||
|
@ -205,7 +205,7 @@
|
||||
|
||||
.ruleview-rule-source {
|
||||
background-color: -moz-dialog;
|
||||
color: #0091ff;
|
||||
color: -moz-dialogText;
|
||||
padding: 2px 5px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 863 B |
@ -207,7 +207,7 @@
|
||||
|
||||
.ruleview-rule-source {
|
||||
background-color: -moz-dialog;
|
||||
color: #0091ff;
|
||||
color: -moz-dialogText;
|
||||
padding: 2px 5px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 863 B |
@ -205,7 +205,7 @@
|
||||
|
||||
.ruleview-rule-source {
|
||||
background-color: -moz-dialog;
|
||||
color: #0091ff;
|
||||
color: -moz-dialogText;
|
||||
padding: 2px 5px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 863 B |
@ -960,10 +960,10 @@ ifdef MSMANIFEST_TOOL
|
||||
endif # MSVC with manifest tool
|
||||
else
|
||||
ifeq ($(CPP_PROG_LINK),1)
|
||||
$(EXPAND_CCC) $(CXXFLAGS) -o $@ $< $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(MOZ_GLUE_PROGRAM_LDFLAGS) $(WRAP_LDFLAGS) $(LIBS_DIR) $(LIBS) $(OS_LIBS) $(EXTRA_LIBS) $(BIN_FLAGS)
|
||||
$(EXPAND_CCC) $(CXXFLAGS) -o $@ $< $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(WRAP_LDFLAGS) $(LIBS_DIR) $(LIBS) $(MOZ_GLUE_PROGRAM_LDFLAGS) $(OS_LIBS) $(EXTRA_LIBS) $(BIN_FLAGS)
|
||||
@$(call CHECK_STDCXX,$@)
|
||||
else
|
||||
$(EXPAND_CC) $(CFLAGS) $(OUTOPTION)$@ $< $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(MOZ_GLUE_PROGRAM_LDFLAGS) $(WRAP_LDFLAGS) $(LIBS_DIR) $(LIBS) $(OS_LIBS) $(EXTRA_LIBS) $(BIN_FLAGS)
|
||||
$(EXPAND_CC) $(CFLAGS) $(OUTOPTION)$@ $< $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(WRAP_LDFLAGS) $(LIBS_DIR) $(LIBS) $(MOZ_GLUE_PROGRAM_LDFLAGS) $(OS_LIBS) $(EXTRA_LIBS) $(BIN_FLAGS)
|
||||
endif # CPP_PROG_LINK
|
||||
endif # WINNT && !GNU_CC
|
||||
|
||||
|
18
configure.in
18
configure.in
@ -4931,6 +4931,10 @@ MOZ_ARG_HEADER(Toolkit Options)
|
||||
AC_MSG_ERROR([You must specify a default toolkit (perhaps $_PLATFORM_DEFAULT_TOOLKIT).])
|
||||
fi
|
||||
|
||||
MOZ_ARG_WITHOUT_BOOL(x,
|
||||
[ --without-x Build without X11],
|
||||
WITHOUT_X11=1)
|
||||
|
||||
dnl ========================================================
|
||||
dnl = Enable the toolkit as needed =
|
||||
dnl ========================================================
|
||||
@ -4965,16 +4969,17 @@ cairo-gtk2|cairo-gtk2-x11)
|
||||
cairo-qt)
|
||||
MOZ_WIDGET_TOOLKIT=qt
|
||||
MOZ_ENABLE_QT=1
|
||||
if test -z "$WITHOUT_X11"; then
|
||||
MOZ_ENABLE_XREMOTE=1
|
||||
MOZ_WEBGL=1
|
||||
MOZ_WEBGL_GLX=1
|
||||
USE_ELF_DYNSTR_GC=
|
||||
|
||||
AC_DEFINE(MOZ_X11)
|
||||
MOZ_X11=1
|
||||
USE_FC_FREETYPE=1
|
||||
AC_DEFINE(MOZ_X11)
|
||||
XT_LIBS=
|
||||
fi
|
||||
|
||||
MOZ_WEBGL=1
|
||||
USE_ELF_DYNSTR_GC=
|
||||
USE_FC_FREETYPE=1
|
||||
TK_CFLAGS='$(MOZ_QT_CFLAGS)'
|
||||
TK_LIBS='$(MOZ_QT_LIBS)'
|
||||
AC_DEFINE(MOZ_WIDGET_QT)
|
||||
@ -8843,6 +8848,9 @@ fi
|
||||
dnl Check for missing components
|
||||
if test "$COMPILE_ENVIRONMENT"; then
|
||||
if test "$MOZ_X11"; then
|
||||
if test "$WITHOUT_X11"; then
|
||||
AC_MSG_ERROR([--without-x specified and MOZ_X11 still defined])
|
||||
fi
|
||||
dnl ====================================================
|
||||
dnl = Check if X headers exist
|
||||
dnl ====================================================
|
||||
|
32
content/base/public/CORSMode.h
Normal file
32
content/base/public/CORSMode.h
Normal file
@ -0,0 +1,32 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef CORSMode_h_
|
||||
#define CORSMode_h_
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
enum CORSMode {
|
||||
/**
|
||||
* The default of not using CORS to validate cross-origin loads.
|
||||
*/
|
||||
CORS_NONE,
|
||||
|
||||
/**
|
||||
* Validate cross-site loads using CORS, but do not send any credentials
|
||||
* (cookies, HTTP auth logins, etc) along with the request.
|
||||
*/
|
||||
CORS_ANONYMOUS,
|
||||
|
||||
/**
|
||||
* Validate cross-site loads using CORS, and send credentials such as cookies
|
||||
* and HTTP auth logins along with the request.
|
||||
*/
|
||||
CORS_USE_CREDENTIALS
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif /* CORSMode_h_ */
|
@ -79,13 +79,17 @@ nsXMLNameSpaceMap.h \
|
||||
nsIXFormsUtilityService.h \
|
||||
$(NULL)
|
||||
|
||||
EXPORTS_NAMESPACES = mozilla/dom
|
||||
EXPORTS_NAMESPACES = mozilla/dom mozilla
|
||||
|
||||
EXPORTS_mozilla/dom = \
|
||||
Element.h \
|
||||
FromParser.h \
|
||||
$(NULL)
|
||||
|
||||
EXPORTS_mozilla = \
|
||||
CORSMode.h \
|
||||
$(NULL)
|
||||
|
||||
SDK_XPIDLSRCS = \
|
||||
nsISelection.idl \
|
||||
$(NULL)
|
||||
@ -97,7 +101,6 @@ XPIDLSRCS = \
|
||||
nsIDOMFileReader.idl \
|
||||
nsIDOMFileList.idl \
|
||||
nsIDOMFileException.idl \
|
||||
nsIDOMFileError.idl \
|
||||
nsIDOMFormData.idl \
|
||||
nsIDOMParser.idl \
|
||||
nsIDOMSerializer.idl \
|
||||
|
@ -1621,6 +1621,42 @@ public:
|
||||
static bool EqualsIgnoreASCIICase(const nsAString& aStr1,
|
||||
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.
|
||||
*/
|
||||
|
@ -43,7 +43,6 @@
|
||||
#include "nsIFile.h"
|
||||
#include "nsIDOMFile.h"
|
||||
#include "nsIDOMFileList.h"
|
||||
#include "nsIDOMFileError.h"
|
||||
#include "nsIInputStream.h"
|
||||
#include "nsIJSNativeInitializer.h"
|
||||
#include "nsIMutable.h"
|
||||
@ -53,12 +52,13 @@
|
||||
#include "nsIXMLHttpRequest.h"
|
||||
#include "prmem.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "mozilla/dom/indexedDB/FileInfo.h"
|
||||
#include "mozilla/dom/indexedDB/FileManager.h"
|
||||
#include "mozilla/dom/indexedDB/IndexedDatabaseManager.h"
|
||||
|
||||
#include "mozilla/GuardObjects.h"
|
||||
#include "mozilla/StandardInteger.h"
|
||||
#include "mozilla/dom/DOMError.h"
|
||||
#include "mozilla/dom/indexedDB/FileInfo.h"
|
||||
#include "mozilla/dom/indexedDB/FileManager.h"
|
||||
#include "mozilla/dom/indexedDB/IndexedDatabaseManager.h"
|
||||
|
||||
class nsIFile;
|
||||
class nsIInputStream;
|
||||
@ -363,18 +363,6 @@ private:
|
||||
nsCOMArray<nsIDOMFile> mFiles;
|
||||
};
|
||||
|
||||
class nsDOMFileError : public nsIDOMFileError
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIDOMFILEERROR
|
||||
|
||||
nsDOMFileError(PRUint16 aErrorCode) : mCode(aErrorCode) {}
|
||||
|
||||
private:
|
||||
PRUint16 mCode;
|
||||
};
|
||||
|
||||
class NS_STACK_CLASS nsDOMFileInternalUrlHolder {
|
||||
public:
|
||||
nsDOMFileInternalUrlHolder(nsIDOMBlob* aFile, nsIPrincipal* aPrincipal
|
||||
|
@ -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 nsIDOMBlob;
|
||||
interface nsIDOMFileError;
|
||||
interface nsIDOMDOMError;
|
||||
|
||||
[scriptable, builtinclass, uuid(d158de26-904e-4731-b42c-8b3a4d172703)]
|
||||
[scriptable, builtinclass, uuid(faed1779-b523-4060-8c3b-7199f347b273)]
|
||||
interface nsIDOMFileReader : nsIDOMEventTarget
|
||||
{
|
||||
[implicit_jscontext]
|
||||
@ -59,7 +59,7 @@ interface nsIDOMFileReader : nsIDOMEventTarget
|
||||
|
||||
[implicit_jscontext]
|
||||
readonly attribute jsval result;
|
||||
readonly attribute nsIDOMFileError error;
|
||||
readonly attribute nsIDOMDOMError error;
|
||||
|
||||
attribute nsIDOMEventListener onloadstart;
|
||||
attribute nsIDOMEventListener onprogress;
|
||||
|
@ -1424,7 +1424,8 @@ public:
|
||||
/**
|
||||
* Called by nsParser to preload images. Can be removed and code moved
|
||||
* to nsPreloadURIs::PreloadURIs() in file nsParser.cpp whenever the
|
||||
* parser-module is linked with gklayout-module.
|
||||
* parser-module is linked with gklayout-module. aCrossOriginAttr should
|
||||
* be a void string if the attr is not present.
|
||||
*/
|
||||
virtual void MaybePreLoadImage(nsIURI* uri,
|
||||
const nsAString& aCrossOriginAttr) = 0;
|
||||
|
@ -47,6 +47,7 @@
|
||||
#include "nsIParser.h"
|
||||
#include "nsContentCreatorFunctions.h"
|
||||
#include "nsIDOMHTMLScriptElement.h"
|
||||
#include "mozilla/CORSMode.h"
|
||||
|
||||
#define NS_ISCRIPTELEMENT_IID \
|
||||
{ 0x24ab3ff2, 0xd75e, 0x4be4, \
|
||||
@ -258,6 +259,15 @@ public:
|
||||
return block;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the CORS mode of the script element
|
||||
*/
|
||||
virtual mozilla::CORSMode GetCORSMode() const
|
||||
{
|
||||
/* Default to no CORS */
|
||||
return mozilla::CORS_NONE;
|
||||
}
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Processes the script if it's in the document-tree and links to or
|
||||
|
@ -119,13 +119,13 @@ FileIOObject::DispatchError(nsresult rv, nsAString& finalEvent)
|
||||
// Set the status attribute, and dispatch the error event
|
||||
switch (rv) {
|
||||
case NS_ERROR_FILE_NOT_FOUND:
|
||||
mError = new nsDOMFileError(nsIDOMFileError::NOT_FOUND_ERR);
|
||||
mError = DOMError::CreateWithName(NS_LITERAL_STRING("NotFoundError"));
|
||||
break;
|
||||
case NS_ERROR_FILE_ACCESS_DENIED:
|
||||
mError = new nsDOMFileError(nsIDOMFileError::SECURITY_ERR);
|
||||
mError = DOMError::CreateWithName(NS_LITERAL_STRING("SecurityError"));
|
||||
break;
|
||||
default:
|
||||
mError = new nsDOMFileError(nsIDOMFileError::NOT_READABLE_ERR);
|
||||
mError = DOMError::CreateWithName(NS_LITERAL_STRING("NotReadableError"));
|
||||
break;
|
||||
}
|
||||
|
||||
@ -258,14 +258,17 @@ FileIOObject::OnStopRequest(nsIRequest* aRequest, nsISupports* aContext,
|
||||
NS_IMETHODIMP
|
||||
FileIOObject::Abort()
|
||||
{
|
||||
if (mReadyState != 1)
|
||||
if (mReadyState != 1) {
|
||||
// XXX The spec doesn't say this
|
||||
return NS_ERROR_DOM_FILE_ABORT_ERR;
|
||||
}
|
||||
|
||||
ClearProgressEventTimer();
|
||||
|
||||
mReadyState = 2; // There are DONE constants on multiple interfaces,
|
||||
// but they all have value 2.
|
||||
mError = new nsDOMFileError(nsIDOMFileError::ABORT_ERR);
|
||||
// XXX The spec doesn't say this
|
||||
mError = DOMError::CreateWithName(NS_LITERAL_STRING("AbortError"));
|
||||
|
||||
nsString finalEvent;
|
||||
nsresult rv = DoAbort(finalEvent);
|
||||
@ -285,7 +288,7 @@ FileIOObject::GetReadyState(PRUint16 *aReadyState)
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
FileIOObject::GetError(nsIDOMFileError** aError)
|
||||
FileIOObject::GetError(nsIDOMDOMError** aError)
|
||||
{
|
||||
NS_IF_ADDREF(*aError = mError);
|
||||
return NS_OK;
|
||||
|
@ -45,9 +45,10 @@
|
||||
#include "nsIDOMFile.h"
|
||||
#include "nsIStreamListener.h"
|
||||
#include "nsITimer.h"
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
#include "mozilla/dom/DOMError.h"
|
||||
|
||||
#define NS_PROGRESS_EVENT_INTERVAL 50
|
||||
|
||||
namespace mozilla {
|
||||
@ -69,7 +70,7 @@ public:
|
||||
// Common methods
|
||||
NS_METHOD Abort();
|
||||
NS_METHOD GetReadyState(PRUint16* aReadyState);
|
||||
NS_METHOD GetError(nsIDOMFileError** aError);
|
||||
NS_METHOD GetError(nsIDOMDOMError** aError);
|
||||
|
||||
NS_DECL_AND_IMPL_EVENT_HANDLER(abort);
|
||||
NS_DECL_AND_IMPL_EVENT_HANDLER(error);
|
||||
@ -108,7 +109,7 @@ protected:
|
||||
bool mProgressEventWasDelayed;
|
||||
bool mTimerIsActive;
|
||||
|
||||
nsCOMPtr<nsIDOMFileError> mError;
|
||||
nsCOMPtr<nsIDOMDOMError> mError;
|
||||
nsCOMPtr<nsIChannel> mChannel;
|
||||
|
||||
PRUint16 mReadyState;
|
||||
|
@ -714,7 +714,7 @@ nsAttrValue::GetEnumString(nsAString& aResult, bool aRealTag) const
|
||||
if (table->value == val) {
|
||||
aResult.AssignASCII(table->tag);
|
||||
if (!aRealTag && allEnumBits & NS_ATTRVALUE_ENUMTABLE_VALUE_NEEDS_TO_UPPER) {
|
||||
ToUpperCase(aResult);
|
||||
nsContentUtils::ASCIIToUpper(aResult);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -1316,7 +1316,7 @@ nsAttrValue::ParseEnumValue(const nsAString& aValue,
|
||||
if (!equals) {
|
||||
nsAutoString tag;
|
||||
tag.AssignASCII(tableEntry->tag);
|
||||
ToUpperCase(tag);
|
||||
nsContentUtils::ASCIIToUpper(tag);
|
||||
if ((equals = tag.Equals(aValue))) {
|
||||
value |= NS_ATTRVALUE_ENUMTABLE_VALUE_NEEDS_TO_UPPER;
|
||||
}
|
||||
|
@ -617,8 +617,9 @@ nsContentSink::ProcessLinkHeader(nsIContent* aElement,
|
||||
if (media.IsEmpty()) {
|
||||
media = value;
|
||||
|
||||
// HTML4.0 spec is inconsistent, make it case INSENSITIVE
|
||||
ToLowerCase(media);
|
||||
// The HTML5 spec is formulated in terms of the CSS3 spec,
|
||||
// which specifies that media queries are case insensitive.
|
||||
nsContentUtils::ASCIIToLower(media);
|
||||
}
|
||||
} else if (attr.LowerCaseEqualsLiteral("anchor")) {
|
||||
if (anchor.IsEmpty()) {
|
||||
@ -757,7 +758,7 @@ nsContentSink::ProcessMETATag(nsIContent* aContent)
|
||||
nsAutoString result;
|
||||
aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::content, result);
|
||||
if (!result.IsEmpty()) {
|
||||
ToLowerCase(header);
|
||||
nsContentUtils::ASCIIToLower(header);
|
||||
nsCOMPtr<nsIAtom> fieldAtom(do_GetAtom(header));
|
||||
rv = ProcessHeaderData(fieldAtom, result, aContent);
|
||||
}
|
||||
@ -769,7 +770,7 @@ nsContentSink::ProcessMETATag(nsIContent* aContent)
|
||||
nsAutoString result;
|
||||
aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::content, result);
|
||||
if (!result.IsEmpty()) {
|
||||
ToLowerCase(result);
|
||||
nsContentUtils::ASCIIToLower(result);
|
||||
mDocument->SetHeaderData(nsGkAtoms::handheldFriendly, result);
|
||||
}
|
||||
}
|
||||
|
@ -5393,6 +5393,7 @@ nsContentUtils::ASCIIToUpper(const nsAString& aSource, nsAString& aDest)
|
||||
}
|
||||
}
|
||||
|
||||
/* static */
|
||||
bool
|
||||
nsContentUtils::EqualsIgnoreASCIICase(const nsAString& aStr1,
|
||||
const nsAString& aStr2)
|
||||
@ -5415,7 +5416,45 @@ nsContentUtils::EqualsIgnoreASCIICase(const nsAString& aStr1,
|
||||
return false;
|
||||
}
|
||||
|
||||
// We know they only differ in the 0x0020 bit.
|
||||
// We know they can only differ in the 0x0020 bit.
|
||||
// Likely the two chars are the same, so check that first
|
||||
if (c1 != c2) {
|
||||
// They do differ, but since it's only in the 0x0020 bit, check if it's
|
||||
// the same ascii char, but just differing in case
|
||||
PRUnichar c1Upper = c1 & 0xffdf;
|
||||
if (!('A' <= c1Upper && c1Upper <= 'Z')) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
|
@ -210,11 +210,11 @@ nsDOMAttribute::GetNameAtom(nsIContent* aContent)
|
||||
mNodeInfo->NamespaceID() == kNameSpaceID_None &&
|
||||
aContent->IsInHTMLDocument() &&
|
||||
aContent->IsHTML()) {
|
||||
nsAutoString name;
|
||||
mNodeInfo->NameAtom()->ToString(name);
|
||||
nsAutoString lower;
|
||||
ToLowerCase(name, lower);
|
||||
nsCOMPtr<nsIAtom> nameAtom = do_GetAtom(lower);
|
||||
nsString name;
|
||||
mNodeInfo->GetName(name);
|
||||
nsAutoString lowercaseName;
|
||||
nsContentUtils::ASCIIToLower(name, lowercaseName);
|
||||
nsCOMPtr<nsIAtom> nameAtom = do_GetAtom(lowercaseName);
|
||||
nameAtom.swap(result);
|
||||
} else {
|
||||
nsCOMPtr<nsIAtom> nameAtom = mNodeInfo->NameAtom();
|
||||
|
@ -335,9 +335,7 @@ nsDOMAttributeMap::SetNamedItemInternal(nsIDOMNode *aNode,
|
||||
else {
|
||||
if (mContent->IsInHTMLDocument() &&
|
||||
mContent->IsHTML()) {
|
||||
nsAutoString lower;
|
||||
ToLowerCase(name, lower);
|
||||
name = lower;
|
||||
nsContentUtils::ASCIIToLower(name);
|
||||
}
|
||||
|
||||
rv = mContent->NodeInfo()->NodeInfoManager()->
|
||||
|
@ -632,27 +632,6 @@ nsDOMFileList::Item(PRUint32 aIndex, nsIDOMFile **aFile)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// nsDOMFileError implementation
|
||||
|
||||
DOMCI_DATA(FileError, nsDOMFileError)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN(nsDOMFileError)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMFileError)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMFileError)
|
||||
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(FileError)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
NS_IMPL_ADDREF(nsDOMFileError)
|
||||
NS_IMPL_RELEASE(nsDOMFileError)
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMFileError::GetCode(PRUint16* aCode)
|
||||
{
|
||||
*aCode = mCode;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// nsDOMFileInternalUrlHolder implementation
|
||||
|
||||
|
@ -255,7 +255,7 @@ nsDOMFileReader::GetResult(JSContext* aCx, jsval* aResult)
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMFileReader::GetError(nsIDOMFileError** aError)
|
||||
nsDOMFileReader::GetError(nsIDOMDOMError** aError)
|
||||
{
|
||||
return FileIOObject::GetError(aError);
|
||||
}
|
||||
|
@ -54,7 +54,6 @@
|
||||
#include "nsIDOMFile.h"
|
||||
#include "nsIDOMFileReader.h"
|
||||
#include "nsIDOMFileList.h"
|
||||
#include "nsIDOMFileError.h"
|
||||
#include "nsIInputStream.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIStreamLoader.h"
|
||||
|
@ -3247,6 +3247,14 @@ nsIDocument::TakeFrameRequestCallbacks(FrameRequestCallbackList& aCallbacks)
|
||||
mFrameRequestCallbacks.Clear();
|
||||
}
|
||||
|
||||
PLDHashOperator RequestDiscardEnumerator(imgIRequest* aKey,
|
||||
PRUint32 aData,
|
||||
void* userArg)
|
||||
{
|
||||
aKey->RequestDiscard();
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
void
|
||||
nsDocument::DeleteShell()
|
||||
{
|
||||
@ -3255,6 +3263,11 @@ nsDocument::DeleteShell()
|
||||
RevokeAnimationFrameNotifications();
|
||||
}
|
||||
|
||||
// When our shell goes away, request that all our images be immediately
|
||||
// discarded, so we don't carry around decoded image data for a document we
|
||||
// no longer intend to paint.
|
||||
mImageTracker.EnumerateRead(RequestDiscardEnumerator, nsnull);
|
||||
|
||||
mPresShell = nsnull;
|
||||
}
|
||||
|
||||
@ -4414,7 +4427,7 @@ nsDocument::CreateElement(const nsAString& aTagName,
|
||||
bool needsLowercase = IsHTML() && !IsLowercaseASCII(aTagName);
|
||||
nsAutoString lcTagName;
|
||||
if (needsLowercase) {
|
||||
ToLowerCase(aTagName, lcTagName);
|
||||
nsContentUtils::ASCIIToLower(aTagName, lcTagName);
|
||||
}
|
||||
|
||||
rv = CreateElem(needsLowercase ? lcTagName : aTagName,
|
||||
@ -7724,14 +7737,20 @@ nsDocument::MaybePreLoadImage(nsIURI* uri, const nsAString &aCrossOriginAttr)
|
||||
}
|
||||
|
||||
nsLoadFlags loadFlags = nsIRequest::LOAD_NORMAL;
|
||||
if (aCrossOriginAttr.LowerCaseEqualsLiteral("anonymous")) {
|
||||
switch (nsGenericElement::StringToCORSMode(aCrossOriginAttr)) {
|
||||
case CORS_NONE:
|
||||
// Nothing to do
|
||||
break;
|
||||
case CORS_ANONYMOUS:
|
||||
loadFlags |= imgILoader::LOAD_CORS_ANONYMOUS;
|
||||
} else if (aCrossOriginAttr.LowerCaseEqualsLiteral("use-credentials")) {
|
||||
break;
|
||||
case CORS_USE_CREDENTIALS:
|
||||
loadFlags |= imgILoader::LOAD_CORS_USE_CREDENTIALS;
|
||||
break;
|
||||
default:
|
||||
/* should never happen */
|
||||
MOZ_NOT_REACHED("Unknown CORS mode!");
|
||||
}
|
||||
// else should we err on the side of not doing the preload if
|
||||
// aCrossOriginAttr is nonempty? Let's err on the side of doing the
|
||||
// preload as CORS_NONE.
|
||||
|
||||
// Image not in cache - trigger preload
|
||||
nsCOMPtr<imgIRequest> request;
|
||||
@ -8309,26 +8328,32 @@ nsDocument::RemoveImage(imgIRequest* aImage)
|
||||
|
||||
// If the count is now zero, remove from the tracker.
|
||||
// Otherwise, set the new value.
|
||||
if (count == 0) {
|
||||
mImageTracker.Remove(aImage);
|
||||
} else {
|
||||
if (count != 0) {
|
||||
mImageTracker.Put(aImage, count);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
mImageTracker.Remove(aImage);
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
// If we removed the image from the tracker and we're locking images, unlock
|
||||
// this image.
|
||||
if (count == 0 && mLockingImages)
|
||||
// Now that we're no longer tracking this image, unlock it if we'd
|
||||
// previously locked it.
|
||||
if (mLockingImages) {
|
||||
rv = aImage->UnlockImage();
|
||||
}
|
||||
|
||||
// If we removed the image from the tracker and we're animating images,
|
||||
// remove our request to animate this image.
|
||||
if (count == 0 && mAnimatingImages) {
|
||||
// If we're animating images, remove our request to animate this one.
|
||||
if (mAnimatingImages) {
|
||||
nsresult rv2 = aImage->DecrementAnimationConsumers();
|
||||
rv = NS_SUCCEEDED(rv) ? rv2 : rv;
|
||||
}
|
||||
|
||||
// Request that the image be discarded if nobody else holds a lock on it.
|
||||
// Do this even if !mLockingImages, because even if we didn't just unlock
|
||||
// this image, it might still be a candidate for discarding.
|
||||
aImage->RequestDiscard();
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -159,6 +159,8 @@
|
||||
#include "nsLayoutStatics.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
|
||||
#include "mozilla/CORSMode.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
|
||||
@ -2853,15 +2855,16 @@ nsGenericElement::GetAttributeNS(const nsAString& aNamespaceURI,
|
||||
nsContentUtils::NameSpaceManager()->GetNameSpaceID(aNamespaceURI);
|
||||
|
||||
if (nsid == kNameSpaceID_Unknown) {
|
||||
// Unknown namespace means no attr...
|
||||
|
||||
aReturn.Truncate();
|
||||
|
||||
// Unknown namespace means no attribute.
|
||||
SetDOMStringToNull(aReturn);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIAtom> name = do_GetAtom(aLocalName);
|
||||
GetAttr(nsid, name, aReturn);
|
||||
bool hasAttr = GetAttr(nsid, name, aReturn);
|
||||
if (!hasAttr) {
|
||||
SetDOMStringToNull(aReturn);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -6235,6 +6238,48 @@ nsGenericElement::SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf) const
|
||||
mAttrsAndChildren.SizeOfExcludingThis(aMallocSizeOf);
|
||||
}
|
||||
|
||||
static const nsAttrValue::EnumTable kCORSAttributeTable[] = {
|
||||
// Order matters here
|
||||
// See ParseCORSValue
|
||||
{ "anonymous", CORS_ANONYMOUS },
|
||||
{ "use-credentials", CORS_USE_CREDENTIALS },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
/* static */ void
|
||||
nsGenericElement::ParseCORSValue(const nsAString& aValue,
|
||||
nsAttrValue& aResult)
|
||||
{
|
||||
DebugOnly<bool> success =
|
||||
aResult.ParseEnumValue(aValue, kCORSAttributeTable, false,
|
||||
// default value is anonymous if aValue is
|
||||
// not a value we understand
|
||||
&kCORSAttributeTable[0]);
|
||||
MOZ_ASSERT(success);
|
||||
}
|
||||
|
||||
/* static */ CORSMode
|
||||
nsGenericElement::StringToCORSMode(const nsAString& aValue)
|
||||
{
|
||||
if (aValue.IsVoid()) {
|
||||
return CORS_NONE;
|
||||
}
|
||||
|
||||
nsAttrValue val;
|
||||
nsGenericElement::ParseCORSValue(aValue, val);
|
||||
return CORSMode(val.GetEnumValue());
|
||||
}
|
||||
|
||||
/* static */ CORSMode
|
||||
nsGenericElement::AttrValueToCORSMode(const nsAttrValue* aValue)
|
||||
{
|
||||
if (!aValue) {
|
||||
return CORS_NONE;
|
||||
}
|
||||
|
||||
return CORSMode(aValue->GetEnumValue());
|
||||
}
|
||||
|
||||
#define EVENT(name_, id_, type_, struct_) \
|
||||
NS_IMETHODIMP nsINode::GetOn##name_(JSContext *cx, jsval *vp) { \
|
||||
nsEventListenerManager *elm = GetListenerManager(false); \
|
||||
|
@ -65,6 +65,7 @@
|
||||
#include "nsDOMClassInfoID.h" // DOMCI_DATA
|
||||
#include "nsIDOMTouchEvent.h"
|
||||
#include "nsIInlineEventHandlers.h"
|
||||
#include "mozilla/CORSMode.h"
|
||||
|
||||
#include "nsISMILAttr.h"
|
||||
|
||||
@ -640,6 +641,25 @@ public:
|
||||
void *aData);
|
||||
static void MarkUserDataHandler(void* aObject, nsIAtom* aKey, void* aChild,
|
||||
void* aData);
|
||||
|
||||
/**
|
||||
* Parse a string into an nsAttrValue for a CORS attribute. This
|
||||
* never fails. The resulting value is an enumerated value whose
|
||||
* GetEnumValue() returns one of the above constants.
|
||||
*/
|
||||
static void ParseCORSValue(const nsAString& aValue, nsAttrValue& aResult);
|
||||
|
||||
/**
|
||||
* Return the CORS mode for a given string
|
||||
*/
|
||||
static mozilla::CORSMode StringToCORSMode(const nsAString& aValue);
|
||||
|
||||
/**
|
||||
* Return the CORS mode for a given nsAttrValue (which may be null,
|
||||
* but if not should have been parsed via ParseCORSValue).
|
||||
*/
|
||||
static mozilla::CORSMode AttrValueToCORSMode(const nsAttrValue* aValue);
|
||||
|
||||
protected:
|
||||
/*
|
||||
* Named-bools for use with SetAttrAndNotify to make call sites easier to
|
||||
|
@ -2004,8 +2004,10 @@ GK_ATOM(setsize, "setsize")
|
||||
GK_ATOM(tableCellIndex, "table-cell-index")
|
||||
GK_ATOM(textAlign, "text-align")
|
||||
GK_ATOM(textIndent, "text-indent")
|
||||
GK_ATOM(textLineThroughColor, "text-line-through-color")
|
||||
GK_ATOM(textLineThroughStyle, "text-line-through-style")
|
||||
GK_ATOM(textPosition, "text-position")
|
||||
GK_ATOM(textUnderlineColor, "text-underline-color")
|
||||
GK_ATOM(textUnderlineStyle, "text-underline-style")
|
||||
GK_ATOM(toolbarname, "toolbarname")
|
||||
GK_ATOM(toolbarseparator, "toolbarseparator")
|
||||
|
@ -60,7 +60,7 @@
|
||||
#include "nsThreadUtils.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsAsyncDOMEvent.h"
|
||||
#include "nsGenericHTMLElement.h"
|
||||
#include "nsGenericElement.h"
|
||||
|
||||
#include "nsIPresShell.h"
|
||||
#include "nsEventStates.h"
|
||||
@ -82,6 +82,8 @@
|
||||
#include "mozAutoDocUpdate.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
#ifdef DEBUG_chb
|
||||
static void PrintReqURL(imgIRequest* req) {
|
||||
if (!req) {
|
||||
@ -775,9 +777,9 @@ nsImageLoadingContent::LoadImage(nsIURI* aNewURI,
|
||||
|
||||
nsLoadFlags loadFlags = aLoadFlags;
|
||||
PRInt32 corsmode = GetCORSMode();
|
||||
if (corsmode == nsGenericHTMLElement::CORS_ANONYMOUS) {
|
||||
if (corsmode == CORS_ANONYMOUS) {
|
||||
loadFlags |= imgILoader::LOAD_CORS_ANONYMOUS;
|
||||
} else if (corsmode == nsGenericHTMLElement::CORS_USE_CREDENTIALS) {
|
||||
} else if (corsmode == CORS_USE_CREDENTIALS) {
|
||||
loadFlags |= imgILoader::LOAD_CORS_USE_CREDENTIALS;
|
||||
}
|
||||
|
||||
@ -1187,8 +1189,8 @@ nsImageLoadingContent::CreateStaticImageClone(nsImageLoadingContent* aDest) cons
|
||||
aDest->mSuppressed = mSuppressed;
|
||||
}
|
||||
|
||||
nsGenericHTMLElement::CORSMode
|
||||
CORSMode
|
||||
nsImageLoadingContent::GetCORSMode()
|
||||
{
|
||||
return nsGenericHTMLElement::CORS_NONE;
|
||||
return CORS_NONE;
|
||||
}
|
||||
|
@ -54,6 +54,7 @@
|
||||
#include "nsString.h"
|
||||
#include "nsEventStates.h"
|
||||
#include "nsGenericHTMLElement.h"
|
||||
#include "mozilla/CORSMode.h"
|
||||
|
||||
class nsIURI;
|
||||
class nsIDocument;
|
||||
@ -183,7 +184,7 @@ protected:
|
||||
* Returns the CORS mode that will be used for all future image loads. The
|
||||
* default implementation returns CORS_NONE unconditionally.
|
||||
*/
|
||||
virtual nsGenericHTMLElement::CORSMode GetCORSMode();
|
||||
virtual mozilla::CORSMode GetCORSMode();
|
||||
|
||||
private:
|
||||
/**
|
||||
|
@ -74,13 +74,17 @@
|
||||
#include "nsChannelPolicy.h"
|
||||
#include "nsCRT.h"
|
||||
#include "nsContentCreatorFunctions.h"
|
||||
#include "nsGenericElement.h"
|
||||
#include "nsCrossSiteListenerProxy.h"
|
||||
|
||||
#include "mozilla/FunctionTimer.h"
|
||||
#include "mozilla/CORSMode.h"
|
||||
|
||||
#ifdef PR_LOGGING
|
||||
static PRLogModuleInfo* gCspPRLog;
|
||||
#endif
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
@ -90,11 +94,14 @@ using namespace mozilla::dom;
|
||||
class nsScriptLoadRequest : public nsISupports {
|
||||
public:
|
||||
nsScriptLoadRequest(nsIScriptElement* aElement,
|
||||
PRUint32 aVersion)
|
||||
PRUint32 aVersion,
|
||||
CORSMode aCORSMode)
|
||||
: mElement(aElement),
|
||||
mLoading(true),
|
||||
mIsInline(true),
|
||||
mJSVersion(aVersion), mLineNo(1)
|
||||
mJSVersion(aVersion),
|
||||
mLineNo(1),
|
||||
mCORSMode(aCORSMode)
|
||||
{
|
||||
}
|
||||
|
||||
@ -122,6 +129,7 @@ public:
|
||||
nsCOMPtr<nsIURI> mURI;
|
||||
nsCOMPtr<nsIPrincipal> mOriginPrincipal;
|
||||
PRInt32 mLineNo;
|
||||
const CORSMode mCORSMode;
|
||||
};
|
||||
|
||||
// The nsScriptLoadRequest is passed as the context to necko, and thus
|
||||
@ -293,7 +301,6 @@ nsScriptLoader::StartLoad(nsScriptLoadRequest *aRequest, const nsAString &aType)
|
||||
}
|
||||
|
||||
nsCOMPtr<nsILoadGroup> loadGroup = mDocument->GetDocumentLoadGroup();
|
||||
nsCOMPtr<nsIStreamLoader> loader;
|
||||
|
||||
nsCOMPtr<nsPIDOMWindow> window(do_QueryInterface(mDocument->GetScriptGlobalObject()));
|
||||
if (!window) {
|
||||
@ -332,10 +339,21 @@ nsScriptLoader::StartLoad(nsScriptLoadRequest *aRequest, const nsAString &aType)
|
||||
httpChannel->SetReferrer(mDocument->GetDocumentURI());
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIStreamLoader> loader;
|
||||
rv = NS_NewStreamLoader(getter_AddRefs(loader), this);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = channel->AsyncOpen(loader, aRequest);
|
||||
nsCOMPtr<nsIStreamListener> listener = loader.get();
|
||||
|
||||
if (aRequest->mCORSMode != CORS_NONE) {
|
||||
bool withCredentials = (aRequest->mCORSMode == CORS_USE_CREDENTIALS);
|
||||
listener =
|
||||
new nsCORSListenerProxy(listener, mDocument->NodePrincipal(), channel,
|
||||
withCredentials, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
rv = channel->AsyncOpen(listener, aRequest);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return NS_OK;
|
||||
@ -551,6 +569,7 @@ nsScriptLoader::ProcessScriptElement(nsIScriptElement *aElement)
|
||||
if (!scriptURI) {
|
||||
return false;
|
||||
}
|
||||
CORSMode ourCORSMode = aElement->GetCORSMode();
|
||||
nsTArray<PreloadInfo>::index_type i =
|
||||
mPreloads.IndexOf(scriptURI.get(), 0, PreloadURIComparator());
|
||||
if (i != nsTArray<PreloadInfo>::NoIndex) {
|
||||
@ -565,7 +584,8 @@ nsScriptLoader::ProcessScriptElement(nsIScriptElement *aElement)
|
||||
// the charset we have now.
|
||||
nsAutoString elementCharset;
|
||||
aElement->GetScriptCharset(elementCharset);
|
||||
if (elementCharset.Equals(preloadCharset)) {
|
||||
if (elementCharset.Equals(preloadCharset) &&
|
||||
ourCORSMode == request->mCORSMode) {
|
||||
rv = CheckContentPolicy(mDocument, aElement, request->mURI, type);
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
} else {
|
||||
@ -576,7 +596,7 @@ nsScriptLoader::ProcessScriptElement(nsIScriptElement *aElement)
|
||||
|
||||
if (!request) {
|
||||
// no usable preload
|
||||
request = new nsScriptLoadRequest(aElement, version);
|
||||
request = new nsScriptLoadRequest(aElement, version, ourCORSMode);
|
||||
request->mURI = scriptURI;
|
||||
request->mIsInline = false;
|
||||
request->mLoading = true;
|
||||
@ -697,7 +717,8 @@ nsScriptLoader::ProcessScriptElement(nsIScriptElement *aElement)
|
||||
}
|
||||
}
|
||||
|
||||
request = new nsScriptLoadRequest(aElement, version);
|
||||
// Inline scripts ignore ther CORS mode and are always CORS_NONE
|
||||
request = new nsScriptLoadRequest(aElement, version, CORS_NONE);
|
||||
request->mJSVersion = version;
|
||||
request->mLoading = false;
|
||||
request->mIsInline = true;
|
||||
@ -1228,9 +1249,14 @@ nsScriptLoader::PrepareLoadedRequest(nsScriptLoadRequest* aRequest,
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIChannel> channel = do_QueryInterface(req);
|
||||
// If this load was subject to a CORS check; don't flag it with a
|
||||
// separate origin principal, so that it will treat our document's
|
||||
// principal as the origin principal
|
||||
if (aRequest->mCORSMode == CORS_NONE) {
|
||||
rv = nsContentUtils::GetSecurityManager()->
|
||||
GetChannelPrincipal(channel, getter_AddRefs(aRequest->mOriginPrincipal));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
if (aStringLen) {
|
||||
// Check the charset attribute to determine script charset.
|
||||
@ -1325,14 +1351,17 @@ nsScriptLoader::ParsingComplete(bool aTerminated)
|
||||
|
||||
void
|
||||
nsScriptLoader::PreloadURI(nsIURI *aURI, const nsAString &aCharset,
|
||||
const nsAString &aType)
|
||||
const nsAString &aType,
|
||||
const nsAString &aCrossOrigin)
|
||||
{
|
||||
// Check to see if scripts has been turned off.
|
||||
if (!mEnabled || !mDocument->IsScriptEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsRefPtr<nsScriptLoadRequest> request = new nsScriptLoadRequest(nsnull, 0);
|
||||
nsRefPtr<nsScriptLoadRequest> request =
|
||||
new nsScriptLoadRequest(nsnull, 0,
|
||||
nsGenericElement::StringToCORSMode(aCrossOrigin));
|
||||
request->mURI = aURI;
|
||||
request->mIsInline = false;
|
||||
request->mLoading = true;
|
||||
|
@ -238,9 +238,12 @@ public:
|
||||
* @param aURI The URI of the external script.
|
||||
* @param aCharset The charset parameter for the script.
|
||||
* @param aType The type parameter for the script.
|
||||
* @param aCrossOrigin The crossorigin attribute for the script.
|
||||
* Void if not present.
|
||||
*/
|
||||
virtual void PreloadURI(nsIURI *aURI, const nsAString &aCharset,
|
||||
const nsAString &aType);
|
||||
const nsAString &aType,
|
||||
const nsAString &aCrossOrigin);
|
||||
|
||||
private:
|
||||
/**
|
||||
|
@ -185,7 +185,7 @@ PRUint32 nsStyleLinkElement::ParseLinkTypes(const nsAString& aTypes)
|
||||
while (current != done) {
|
||||
if (nsContentUtils::IsHTMLWhitespace(*current)) {
|
||||
if (inString) {
|
||||
ToLowerCase(Substring(start, current), subString);
|
||||
nsContentUtils::ASCIIToLower(Substring(start, current), subString);
|
||||
linkMask |= ToLinkMask(subString);
|
||||
inString = false;
|
||||
}
|
||||
@ -199,7 +199,7 @@ PRUint32 nsStyleLinkElement::ParseLinkTypes(const nsAString& aTypes)
|
||||
++current;
|
||||
}
|
||||
if (inString) {
|
||||
ToLowerCase(Substring(start, current), subString);
|
||||
nsContentUtils::ASCIIToLower(Substring(start, current), subString);
|
||||
linkMask |= ToLinkMask(subString);
|
||||
}
|
||||
return linkMask;
|
||||
|
@ -562,6 +562,11 @@ _TEST_FILES2 = \
|
||||
test_bug726364.html \
|
||||
test_bug698381.html \
|
||||
test_bug711047.html \
|
||||
test_bug696301-1.html \
|
||||
test_bug696301-2.html \
|
||||
bug696301-script-1.js \
|
||||
bug696301-script-1.js^headers^ \
|
||||
bug696301-script-2.js \
|
||||
$(NULL)
|
||||
|
||||
_CHROME_FILES = \
|
||||
|
3
content/base/test/bug696301-script-1.js
Normal file
3
content/base/test/bug696301-script-1.js
Normal file
@ -0,0 +1,3 @@
|
||||
var a = 0;
|
||||
var global = "ran";
|
||||
c();
|
1
content/base/test/bug696301-script-1.js^headers^
Normal file
1
content/base/test/bug696301-script-1.js^headers^
Normal file
@ -0,0 +1 @@
|
||||
Access-Control-Allow-Origin: *
|
3
content/base/test/bug696301-script-2.js
Normal file
3
content/base/test/bug696301-script-2.js
Normal file
@ -0,0 +1,3 @@
|
||||
var a = 0;
|
||||
var global = "ran";
|
||||
c();
|
78
content/base/test/test_bug696301-1.html
Normal file
78
content/base/test/test_bug696301-1.html
Normal file
@ -0,0 +1,78 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=696301
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test for Bug 696301</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=696301">Mozilla Bug 696301</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
var errorFired = false;
|
||||
var global = "";
|
||||
window.onerror = function(message, uri, line) {
|
||||
is(message, "Script error.", "Should have empty error message");
|
||||
is(uri,
|
||||
"http://example.com/tests/content/base/test/bug696301-script-1.js",
|
||||
"Should have correct script URI");
|
||||
is(line, 0, "Shouldn't have a line here");
|
||||
errorFired = true;
|
||||
}
|
||||
</script>
|
||||
<script src="http://example.com/tests/content/base/test/bug696301-script-1.js"></script>
|
||||
<script>
|
||||
is(errorFired, true, "Should have error in different origin script");
|
||||
is(global, "ran", "Different origin script should have run");
|
||||
</script>
|
||||
|
||||
<script type="application/javascript">
|
||||
errorFired = false;
|
||||
global = "";
|
||||
window.onerror = function(message, uri, line) {
|
||||
is(message, "c is not defined", "Should have correct error message");
|
||||
is(uri,
|
||||
"http://example.com/tests/content/base/test/bug696301-script-1.js",
|
||||
"Should also have correct script URI");
|
||||
is(line, 3, "Should have a line here");
|
||||
errorFired = true;
|
||||
}
|
||||
</script>
|
||||
<script src="http://example.com/tests/content/base/test/bug696301-script-1.js"
|
||||
crossorigin></script>
|
||||
<script>
|
||||
is(errorFired, true, "Should have error in different origin script with CORS");
|
||||
is(global, "ran", "Different origin script with CORS should have run");
|
||||
</script>
|
||||
|
||||
<script type="application/javascript">
|
||||
errorFired = false;
|
||||
global = "";
|
||||
window.onerror = function(message, uri, line) {
|
||||
is(message, "Error loading script", "Should have correct error message");
|
||||
is(uri,
|
||||
"http://example.com/tests/content/base/test/bug696301-script-2.js",
|
||||
"Should still have correct script URI even when failing CORS");
|
||||
is(line, 1, "Load failures seem to count as line 1");
|
||||
errorFired = true;
|
||||
}
|
||||
</script>
|
||||
<script src="http://example.com/tests/content/base/test/bug696301-script-2.js"
|
||||
crossorigin></script>
|
||||
<script>
|
||||
is(errorFired, true,
|
||||
"Should have error when different origin script fails CORS check");
|
||||
is(global, "", "Different origin script that fails CORS should not have run");
|
||||
</script>
|
||||
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
80
content/base/test/test_bug696301-2.html
Normal file
80
content/base/test/test_bug696301-2.html
Normal file
@ -0,0 +1,80 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=696301
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test for Bug 696301</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=696301">Mozilla Bug 696301</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
<!-- Test SVG script here -->
|
||||
<svg>
|
||||
<script type="application/javascript">
|
||||
var errorFired = false;
|
||||
var global = "";
|
||||
window.onerror = function(message, uri, line) {
|
||||
is(message, "Script error.", "Should have empty error message");
|
||||
is(uri,
|
||||
"http://example.com/tests/content/base/test/bug696301-script-1.js",
|
||||
"Should have correct script URI");
|
||||
is(line, 0, "Shouldn't have a line here");
|
||||
errorFired = true;
|
||||
}
|
||||
</script>
|
||||
<script xlink:href="http://example.com/tests/content/base/test/bug696301-script-1.js"></script>
|
||||
<script>
|
||||
is(errorFired, true, "Should have error in different origin script");
|
||||
is(global, "ran", "Different origin script should have run");
|
||||
</script>
|
||||
|
||||
<script type="application/javascript">
|
||||
errorFired = false;
|
||||
global = "";
|
||||
window.onerror = function(message, uri, line) {
|
||||
is(message, "c is not defined", "Should have correct error message");
|
||||
is(uri,
|
||||
"http://example.com/tests/content/base/test/bug696301-script-1.js",
|
||||
"Should also have correct script URI");
|
||||
is(line, 3, "Should have a line here");
|
||||
errorFired = true;
|
||||
}
|
||||
</script>
|
||||
<script xlink:href="http://example.com/tests/content/base/test/bug696301-script-1.js"
|
||||
crossorigin></script>
|
||||
<script>
|
||||
is(errorFired, true, "Should have error in different origin script with CORS");
|
||||
is(global, "ran", "Different origin script with CORS should have run");
|
||||
</script>
|
||||
|
||||
<script type="application/javascript">
|
||||
errorFired = false;
|
||||
global = "";
|
||||
window.onerror = function(message, uri, line) {
|
||||
is(message, "Error loading script", "Should have correct error message");
|
||||
is(uri,
|
||||
"http://example.com/tests/content/base/test/bug696301-script-2.js",
|
||||
"Should still have correct script URI even when failing CORS");
|
||||
is(line, 1, "Load failures seem to count as line 1");
|
||||
errorFired = true;
|
||||
}
|
||||
</script>
|
||||
<script xlink:href="http://example.com/tests/content/base/test/bug696301-script-2.js"
|
||||
crossorigin></script>
|
||||
<script>
|
||||
is(errorFired, true,
|
||||
"Should have error when different origin script fails CORS check");
|
||||
is(global, "", "Different origin script that fails CORS should not have run");
|
||||
</script>
|
||||
</svg>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
@ -3,4 +3,5 @@ load 421715-1.html
|
||||
load 553938-1.html
|
||||
load 647480.html
|
||||
load 0px-size-font-667225.html
|
||||
load texImage2D.html
|
||||
load 729116.html
|
||||
|
8
content/canvas/crashtests/texImage2D.html
Normal file
8
content/canvas/crashtests/texImage2D.html
Normal file
@ -0,0 +1,8 @@
|
||||
<!doctype html>
|
||||
<canvas></canvas>
|
||||
<script>
|
||||
var canvas = document.body.firstChild,
|
||||
gl = canvas.getContext("experimental-webgl");
|
||||
gl.texImage2D(0, 0, 0, 0, 0, { get width() { throw 7 }, get height() { throw 7 }, data: new Uint8ClampedArray(10) });
|
||||
gl.texSubImage2D(0, 0, 0, 0, 0, 0, { get width() { throw 7 }, get height() { throw 7 }, data: new Uint8ClampedArray(10) });
|
||||
</script>
|
@ -382,6 +382,133 @@ nsIDOMWebGLRenderingContext_ReadPixels(JSContext *cx, unsigned argc, jsval *vp)
|
||||
}
|
||||
|
||||
|
||||
class CallTexImage2D
|
||||
{
|
||||
private:
|
||||
nsIDOMWebGLRenderingContext* self;
|
||||
WebGLenum target;
|
||||
WebGLint level;
|
||||
WebGLenum internalformat;
|
||||
WebGLenum format;
|
||||
WebGLenum type;
|
||||
|
||||
public:
|
||||
explicit CallTexImage2D(nsIDOMWebGLRenderingContext* aSelf,
|
||||
WebGLenum aTarget,
|
||||
WebGLint aLevel,
|
||||
WebGLenum aInternalformat,
|
||||
WebGLenum aFormat,
|
||||
WebGLenum aType)
|
||||
: self(aSelf)
|
||||
, target(aTarget)
|
||||
, level(aLevel)
|
||||
, internalformat(aInternalformat)
|
||||
, format(aFormat)
|
||||
, type(aType)
|
||||
{}
|
||||
|
||||
nsresult DoCallForImageData(WebGLsizei width, WebGLsizei height,
|
||||
JSObject* pixels)
|
||||
{
|
||||
return self->TexImage2D_imageData(target, level, internalformat, width,
|
||||
height, 0, format, type, pixels);
|
||||
}
|
||||
nsresult DoCallForElement(mozilla::dom::Element* elt)
|
||||
{
|
||||
return self->TexImage2D_dom(target, level, internalformat, format, type,
|
||||
elt);
|
||||
}
|
||||
};
|
||||
|
||||
class CallTexSubImage2D
|
||||
{
|
||||
private:
|
||||
nsIDOMWebGLRenderingContext* self;
|
||||
WebGLenum target;
|
||||
WebGLint level;
|
||||
WebGLint xoffset;
|
||||
WebGLint yoffset;
|
||||
WebGLenum format;
|
||||
WebGLenum type;
|
||||
|
||||
public:
|
||||
explicit CallTexSubImage2D(nsIDOMWebGLRenderingContext* aSelf,
|
||||
WebGLenum aTarget,
|
||||
WebGLint aLevel,
|
||||
WebGLint aXoffset,
|
||||
WebGLint aYoffset,
|
||||
WebGLenum aFormat,
|
||||
WebGLenum aType)
|
||||
|
||||
: self(aSelf)
|
||||
, target(aTarget)
|
||||
, level(aLevel)
|
||||
, xoffset(aXoffset)
|
||||
, yoffset(aYoffset)
|
||||
, format(aFormat)
|
||||
, type(aType)
|
||||
{}
|
||||
|
||||
nsresult DoCallForImageData(WebGLsizei width, WebGLsizei height,
|
||||
JSObject* pixels)
|
||||
{
|
||||
return self->TexSubImage2D_imageData(target, level, xoffset, yoffset,
|
||||
width, height, format, type,
|
||||
pixels);
|
||||
}
|
||||
nsresult DoCallForElement(mozilla::dom::Element* elt)
|
||||
{
|
||||
return self->TexSubImage2D_dom(target, level, xoffset, yoffset, format,
|
||||
type, elt);
|
||||
}
|
||||
};
|
||||
|
||||
template<class T>
|
||||
static bool
|
||||
TexImage2DImageDataOrElement(JSContext* cx, T& self, JS::Value* object)
|
||||
{
|
||||
MOZ_ASSERT(object && object->isObject());
|
||||
|
||||
nsGenericElement* elt;
|
||||
xpc_qsSelfRef eltRef;
|
||||
if (NS_SUCCEEDED(xpc_qsUnwrapArg<nsGenericElement>(
|
||||
cx, *object, &elt, &eltRef.ptr, object))) {
|
||||
nsresult rv = self.DoCallForElement(elt);
|
||||
return NS_SUCCEEDED(rv) || xpc_qsThrow(cx, rv);
|
||||
}
|
||||
|
||||
// Failed to interpret object as an Element, now try to interpret it as
|
||||
// ImageData.
|
||||
JSObject* imageData = &object->toObject();
|
||||
|
||||
jsval js_width, js_height, js_data;
|
||||
if (!JS_GetProperty(cx, imageData, "width", &js_width) ||
|
||||
!JS_GetProperty(cx, imageData, "height", &js_height) ||
|
||||
!JS_GetProperty(cx, imageData, "data", &js_data)) {
|
||||
return false;
|
||||
}
|
||||
if (js_width == JSVAL_VOID ||
|
||||
js_height == JSVAL_VOID ||
|
||||
!js_data.isObject())
|
||||
{
|
||||
return xpc_qsThrow(cx, NS_ERROR_FAILURE);
|
||||
}
|
||||
int32_t int_width, int_height;
|
||||
JSObject *obj_data = JSVAL_TO_OBJECT(js_data);
|
||||
if (!JS_ValueToECMAInt32(cx, js_width, &int_width) ||
|
||||
!JS_ValueToECMAInt32(cx, js_height, &int_height))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!js_IsTypedArray(obj_data))
|
||||
{
|
||||
return xpc_qsThrow(cx, NS_ERROR_FAILURE);
|
||||
}
|
||||
|
||||
nsresult rv = self.DoCallForImageData(int_width, int_height, obj_data);
|
||||
return NS_SUCCEEDED(rv) || xpc_qsThrow(cx, rv);
|
||||
}
|
||||
|
||||
/*
|
||||
* TexImage2D takes:
|
||||
* TexImage2D(uint, int, uint, int, int, int, uint, uint, ArrayBufferView)
|
||||
@ -412,65 +539,21 @@ nsIDOMWebGLRenderingContext_TexImage2D(JSContext *cx, unsigned argc, jsval *vp)
|
||||
// arguments common to all cases
|
||||
GET_UINT32_ARG(argv0, 0);
|
||||
GET_INT32_ARG(argv1, 1);
|
||||
|
||||
if (argc > 5 &&
|
||||
!JSVAL_IS_PRIMITIVE(argv[5]))
|
||||
{
|
||||
// implement the variants taking a DOMElement as argv[5]
|
||||
GET_UINT32_ARG(argv2, 2);
|
||||
|
||||
if (argc > 5 && !JSVAL_IS_PRIMITIVE(argv[5])) {
|
||||
// implement the variants taking a DOMElement as argv[5]
|
||||
GET_UINT32_ARG(argv3, 3);
|
||||
GET_UINT32_ARG(argv4, 4);
|
||||
|
||||
nsIDOMElement *elt;
|
||||
xpc_qsSelfRef eltRef;
|
||||
rv = xpc_qsUnwrapArg<nsIDOMElement>(cx, argv[5], &elt, &eltRef.ptr, &argv[5]);
|
||||
if (NS_FAILED(rv)) return JS_FALSE;
|
||||
|
||||
rv = self->TexImage2D_dom(argv0, argv1, argv2, argv3, argv4, elt);
|
||||
|
||||
// NS_ERROR_DOM_SECURITY_ERR indicates we tried to load a cross-domain element, so
|
||||
// bail out immediately, don't try to interprete as ImageData
|
||||
if (rv == NS_ERROR_DOM_SECURITY_ERR) {
|
||||
xpc_qsThrowBadArg(cx, rv, vp, 5);
|
||||
return JS_FALSE;
|
||||
CallTexImage2D selfCaller(self, argv0, argv1, argv2, argv3, argv4);
|
||||
if (!TexImage2DImageDataOrElement(cx, selfCaller, argv + 5)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
// failed to interprete argv[5] as a DOMElement, now try to interprete it as ImageData
|
||||
JSObject *argv5 = JSVAL_TO_OBJECT(argv[5]);
|
||||
|
||||
jsval js_width, js_height, js_data;
|
||||
JS_GetProperty(cx, argv5, "width", &js_width);
|
||||
JS_GetProperty(cx, argv5, "height", &js_height);
|
||||
JS_GetProperty(cx, argv5, "data", &js_data);
|
||||
if (js_width == JSVAL_VOID ||
|
||||
js_height == JSVAL_VOID ||
|
||||
!js_data.isObject())
|
||||
{
|
||||
xpc_qsThrowBadArg(cx, NS_ERROR_FAILURE, vp, 5);
|
||||
return JS_FALSE;
|
||||
}
|
||||
int32_t int_width, int_height;
|
||||
JSObject *obj_data = JSVAL_TO_OBJECT(js_data);
|
||||
if (!JS_ValueToECMAInt32(cx, js_width, &int_width) ||
|
||||
!JS_ValueToECMAInt32(cx, js_height, &int_height))
|
||||
{
|
||||
return JS_FALSE;
|
||||
}
|
||||
if (!js_IsTypedArray(obj_data))
|
||||
{
|
||||
xpc_qsThrowBadArg(cx, NS_ERROR_FAILURE, vp, 5);
|
||||
return JS_FALSE;
|
||||
}
|
||||
rv = self->TexImage2D_imageData(argv0, argv1, argv2,
|
||||
int_width, int_height, 0,
|
||||
argv3, argv4, js::TypedArray::getTypedArray(obj_data));
|
||||
}
|
||||
} else if (argc > 8 &&
|
||||
JSVAL_IS_OBJECT(argv[8])) // here, we allow null !
|
||||
{
|
||||
rv = NS_OK;
|
||||
} else if (argc > 8 && JSVAL_IS_OBJECT(argv[8])) {
|
||||
// here, we allow null !
|
||||
// implement the variants taking a buffer/array as argv[8]
|
||||
GET_UINT32_ARG(argv2, 2);
|
||||
GET_INT32_ARG(argv3, 3);
|
||||
GET_INT32_ARG(argv4, 4);
|
||||
GET_INT32_ARG(argv5, 5);
|
||||
@ -536,61 +619,17 @@ nsIDOMWebGLRenderingContext_TexSubImage2D(JSContext *cx, unsigned argc, jsval *v
|
||||
GET_INT32_ARG(argv2, 2);
|
||||
GET_INT32_ARG(argv3, 3);
|
||||
|
||||
if (argc > 6 &&
|
||||
!JSVAL_IS_PRIMITIVE(argv[6]))
|
||||
{
|
||||
// implement the variants taking a DOMElement as argv[6]
|
||||
if (argc > 6 && !JSVAL_IS_PRIMITIVE(argv[6])) {
|
||||
// implement the variants taking a DOMElement or an ImageData as argv[6]
|
||||
GET_UINT32_ARG(argv4, 4);
|
||||
GET_UINT32_ARG(argv5, 5);
|
||||
|
||||
nsIDOMElement *elt;
|
||||
xpc_qsSelfRef eltRef;
|
||||
rv = xpc_qsUnwrapArg<nsIDOMElement>(cx, argv[6], &elt, &eltRef.ptr, &argv[6]);
|
||||
if (NS_FAILED(rv)) return JS_FALSE;
|
||||
|
||||
rv = self->TexSubImage2D_dom(argv0, argv1, argv2, argv3, argv4, argv5, elt);
|
||||
|
||||
// NS_ERROR_DOM_SECURITY_ERR indicates we tried to load a cross-domain element, so
|
||||
// bail out immediately, don't try to interprete as ImageData
|
||||
if (rv == NS_ERROR_DOM_SECURITY_ERR) {
|
||||
xpc_qsThrowBadArg(cx, rv, vp, 6);
|
||||
return JS_FALSE;
|
||||
CallTexSubImage2D selfCaller(self, argv0, argv1, argv2, argv3, argv4, argv5);
|
||||
if (!TexImage2DImageDataOrElement(cx, selfCaller, argv + 6)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
// failed to interprete argv[6] as a DOMElement, now try to interprete it as ImageData
|
||||
JSObject *argv6 = JSVAL_TO_OBJECT(argv[6]);
|
||||
jsval js_width, js_height, js_data;
|
||||
JS_GetProperty(cx, argv6, "width", &js_width);
|
||||
JS_GetProperty(cx, argv6, "height", &js_height);
|
||||
JS_GetProperty(cx, argv6, "data", &js_data);
|
||||
if (js_width == JSVAL_VOID ||
|
||||
js_height == JSVAL_VOID ||
|
||||
!js_data.isObject())
|
||||
{
|
||||
xpc_qsThrowBadArg(cx, NS_ERROR_FAILURE, vp, 6);
|
||||
return JS_FALSE;
|
||||
}
|
||||
int32_t int_width, int_height;
|
||||
JSObject *obj_data = JSVAL_TO_OBJECT(js_data);
|
||||
if (!JS_ValueToECMAInt32(cx, js_width, &int_width) ||
|
||||
!JS_ValueToECMAInt32(cx, js_height, &int_height))
|
||||
{
|
||||
return JS_FALSE;
|
||||
}
|
||||
if (!js_IsTypedArray(obj_data))
|
||||
{
|
||||
xpc_qsThrowBadArg(cx, NS_ERROR_FAILURE, vp, 6);
|
||||
return JS_FALSE;
|
||||
}
|
||||
rv = self->TexSubImage2D_imageData(argv0, argv1, argv2, argv3,
|
||||
int_width, int_height,
|
||||
argv4, argv5,
|
||||
js::TypedArray::getTypedArray(obj_data));
|
||||
}
|
||||
} else if (argc > 8 &&
|
||||
!JSVAL_IS_PRIMITIVE(argv[8]))
|
||||
{
|
||||
rv = NS_OK;
|
||||
} else if (argc > 8 && !JSVAL_IS_PRIMITIVE(argv[8])) {
|
||||
// implement the variants taking a buffer/array as argv[8]
|
||||
GET_INT32_ARG(argv4, 4);
|
||||
GET_INT32_ARG(argv5, 5);
|
||||
|
@ -815,7 +815,7 @@ protected:
|
||||
int dstFormat, bool dstPremultiplied,
|
||||
size_t dstTexelSize);
|
||||
|
||||
nsresult DOMElementToImageSurface(nsIDOMElement *imageOrCanvas,
|
||||
nsresult DOMElementToImageSurface(dom::Element* imageOrCanvas,
|
||||
gfxImageSurface **imageOut,
|
||||
int *format);
|
||||
|
||||
|
@ -70,6 +70,7 @@
|
||||
#endif
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
|
||||
static bool BaseTypeAndSizeFromUniformType(WebGLenum uType, WebGLenum *baseType, WebGLint *unitSize);
|
||||
static WebGLenum InternalFormatForFormatAndType(WebGLenum format, WebGLenum type, bool isGLES2);
|
||||
@ -3966,11 +3967,10 @@ WebGLContext::ConvertImage(size_t width, size_t height, size_t srcStride, size_t
|
||||
}
|
||||
|
||||
nsresult
|
||||
WebGLContext::DOMElementToImageSurface(nsIDOMElement *imageOrCanvas,
|
||||
WebGLContext::DOMElementToImageSurface(Element* imageOrCanvas,
|
||||
gfxImageSurface **imageOut, int *format)
|
||||
{
|
||||
nsCOMPtr<nsIContent> content = do_QueryInterface(imageOrCanvas);
|
||||
if (!content) {
|
||||
if (!imageOrCanvas) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
@ -3984,7 +3984,7 @@ WebGLContext::DOMElementToImageSurface(nsIDOMElement *imageOrCanvas,
|
||||
flags |= nsLayoutUtils::SFE_NO_PREMULTIPLY_ALPHA;
|
||||
|
||||
nsLayoutUtils::SurfaceFromElementResult res =
|
||||
nsLayoutUtils::SurfaceFromElement(content->AsElement(), flags);
|
||||
nsLayoutUtils::SurfaceFromElement(imageOrCanvas, flags);
|
||||
if (!res.mSurface)
|
||||
return NS_ERROR_FAILURE;
|
||||
if (res.mSurface->GetType() != gfxASurface::SurfaceTypeImage) {
|
||||
@ -4016,7 +4016,7 @@ WebGLContext::DOMElementToImageSurface(nsIDOMElement *imageOrCanvas,
|
||||
// part 2: if the DOM element is a canvas, check that it's not write-only.
|
||||
// That would indicate a tainted canvas, i.e. a canvas that could contain
|
||||
// cross-domain image data.
|
||||
if (nsHTMLCanvasElement* canvas = nsHTMLCanvasElement::FromContent(content)) {
|
||||
if (nsHTMLCanvasElement* canvas = nsHTMLCanvasElement::FromContent(imageOrCanvas)) {
|
||||
if (canvas->IsWriteOnly()) {
|
||||
LogMessageIfVerbose("The canvas used as source for texImage2D here is tainted (write-only). It is forbidden "
|
||||
"to load a WebGL texture from a tainted canvas. A Canvas becomes tainted for example "
|
||||
@ -5082,7 +5082,7 @@ WebGLContext::TexImage2D_imageData(WebGLenum target, WebGLint level, WebGLenum i
|
||||
|
||||
NS_IMETHODIMP
|
||||
WebGLContext::TexImage2D_dom(WebGLenum target, WebGLint level, WebGLenum internalformat,
|
||||
WebGLenum format, GLenum type, nsIDOMElement *elt)
|
||||
WebGLenum format, GLenum type, Element* elt)
|
||||
{
|
||||
if (!IsContextStable())
|
||||
return NS_OK;
|
||||
@ -5272,7 +5272,7 @@ NS_IMETHODIMP
|
||||
WebGLContext::TexSubImage2D_dom(WebGLenum target, WebGLint level,
|
||||
WebGLint xoffset, WebGLint yoffset,
|
||||
WebGLenum format, WebGLenum type,
|
||||
nsIDOMElement *elt)
|
||||
Element *elt)
|
||||
{
|
||||
if (!IsContextStable())
|
||||
return NS_OK;
|
||||
|
@ -7591,7 +7591,7 @@ ok(!_thrown_outer, ctx.canvas.id + ' should not throw exception');
|
||||
<!-- [[[ test_2d.imageData.create.type.html ]]] -->
|
||||
|
||||
<p>Canvas test: 2d.imageData.create.type - bug 433004</p>
|
||||
<!-- Testing: createImageData() returns an ImageData object containing a CanvasPixelArray object -->
|
||||
<!-- Testing: createImageData() returns an ImageData object containing a Uint8ClampedArray object -->
|
||||
<canvas id="c261" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
|
||||
<script>
|
||||
|
||||
@ -7604,12 +7604,12 @@ var _thrown_outer = false;
|
||||
try {
|
||||
|
||||
todo(window.ImageData !== undefined, "window.ImageData !== undefined");
|
||||
todo(window.CanvasPixelArray !== undefined, "window.CanvasPixelArray !== undefined");
|
||||
ok(window.Uint8ClampedArray !== undefined, "window.Uint8ClampedArray !== undefined");
|
||||
window.ImageData.prototype.thisImplementsImageData = true;
|
||||
window.CanvasPixelArray.prototype.thisImplementsCanvasPixelArray = true;
|
||||
window.Uint8ClampedArray.prototype.thisImplementsUint8ClampedArray = true;
|
||||
var imgdata = ctx.createImageData(1, 1);
|
||||
ok(imgdata.thisImplementsImageData, "imgdata.thisImplementsImageData");
|
||||
ok(imgdata.data.thisImplementsCanvasPixelArray, "imgdata.data.thisImplementsCanvasPixelArray");
|
||||
ok(imgdata.data.thisImplementsUint8ClampedArray, "imgdata.data.thisImplementsUint8ClampedArray");
|
||||
|
||||
} catch (e) {
|
||||
_thrown_outer = true;
|
||||
@ -7623,7 +7623,7 @@ todo(!_thrown_outer, ctx.canvas.id + ' should not throw exception');
|
||||
<!-- [[[ test_2d.imageData.create1.type.html ]]] -->
|
||||
|
||||
<p>Canvas test: 2d.imageData.create1.type - bug 630040</p>
|
||||
<!-- Testing: createImageData(imgdata) returns an ImageData object containing a CanvasPixelArray object -->
|
||||
<!-- Testing: createImageData(imgdata) returns an ImageData object containing a Uint8ClampedArray object -->
|
||||
<canvas id="c261a" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
|
||||
<script>
|
||||
|
||||
@ -7636,12 +7636,12 @@ var _thrown_outer = false;
|
||||
try {
|
||||
|
||||
todo(window.ImageData !== undefined, "window.ImageData !== undefined");
|
||||
todo(window.CanvasPixelArray !== undefined, "window.CanvasPixelArray !== undefined");
|
||||
ok(window.Uint8ClampedArray !== undefined, "window.Uint8ClampedArray !== undefined");
|
||||
window.ImageData.prototype.thisImplementsImageData = true;
|
||||
window.CanvasPixelArray.prototype.thisImplementsCanvasPixelArray = true;
|
||||
window.Uint8ClampedArray.prototype.thisImplementsUint8ClampedArray = true;
|
||||
var imgdata = ctx.createImageData(ctx.createImageData(1, 1));
|
||||
todo(imgdata.thisImplementsImageData, "imgdata.thisImplementsImageData");
|
||||
todo(imgdata.data.thisImplementsCanvasPixelArray, "imgdata.data.thisImplementsCanvasPixelArray");
|
||||
ok(imgdata.data.thisImplementsUint8ClampedArray, "imgdata.data.thisImplementsUint8ClampedArray");
|
||||
|
||||
} catch (e) {
|
||||
_thrown_outer = true;
|
||||
@ -8229,7 +8229,7 @@ ok(!_thrown_outer, ctx.canvas.id + ' should not throw exception');
|
||||
<!-- [[[ test_2d.imageData.get.type.html ]]] -->
|
||||
|
||||
<p>Canvas test: 2d.imageData.get.type</p>
|
||||
<!-- Testing: getImageData() returns an ImageData object containing a CanvasPixelArray object -->
|
||||
<!-- Testing: getImageData() returns an ImageData object containing a Uint8ClampedArray object -->
|
||||
<canvas id="c276" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
|
||||
<script>
|
||||
|
||||
@ -8242,12 +8242,12 @@ var _thrown_outer = false;
|
||||
try {
|
||||
|
||||
todo(window.ImageData !== undefined, "window.ImageData !== undefined");
|
||||
todo(window.CanvasPixelArray !== undefined, "window.CanvasPixelArray !== undefined");
|
||||
ok(window.Uint8ClampedArray !== undefined, "window.Uint8ClampedArray !== undefined");
|
||||
window.ImageData.prototype.thisImplementsImageData = true;
|
||||
window.CanvasPixelArray.prototype.thisImplementsCanvasPixelArray = true;
|
||||
window.Uint8ClampedArray.prototype.thisImplementsUint8ClampedArray = true;
|
||||
var imgdata = ctx.getImageData(0, 0, 1, 1);
|
||||
ok(imgdata.thisImplementsImageData, "imgdata.thisImplementsImageData");
|
||||
ok(imgdata.data.thisImplementsCanvasPixelArray, "imgdata.data.thisImplementsCanvasPixelArray");
|
||||
ok(imgdata.data.thisImplementsUint8ClampedArray, "imgdata.data.thisImplementsUint8ClampedArray");
|
||||
|
||||
} catch (e) {
|
||||
_thrown_outer = true;
|
||||
|
@ -6,5 +6,6 @@ load 457776-1.html
|
||||
load 496308-1.html
|
||||
load 682637-1.html
|
||||
load eventctor-nulldictionary.html
|
||||
load eventctor-nullstorage.html
|
||||
load recursive-onload.html
|
||||
load recursive-DOMNodeInserted.html
|
||||
|
4
content/events/crashtests/eventctor-nullstorage.html
Normal file
4
content/events/crashtests/eventctor-nullstorage.html
Normal file
@ -0,0 +1,4 @@
|
||||
<!DOCTYPE html>
|
||||
<script>
|
||||
new StorageEvent("").storageArea;
|
||||
</script>
|
@ -50,6 +50,7 @@
|
||||
#include "nsIObserver.h"
|
||||
#include "nsAudioStream.h"
|
||||
#include "VideoFrameContainer.h"
|
||||
#include "mozilla/CORSMode.h"
|
||||
|
||||
// Define to output information on decoding and painting framerate
|
||||
/* #define DEBUG_FRAME_RATE 1 */
|
||||
@ -71,7 +72,7 @@ public:
|
||||
CANPLAY_YES
|
||||
};
|
||||
|
||||
CORSMode GetCORSMode() {
|
||||
mozilla::CORSMode GetCORSMode() {
|
||||
return mCORSMode;
|
||||
}
|
||||
|
||||
@ -781,7 +782,7 @@ protected:
|
||||
bool mMediaSecurityVerified;
|
||||
|
||||
// The CORS mode when loading the media element
|
||||
CORSMode mCORSMode;
|
||||
mozilla::CORSMode mCORSMode;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -2488,26 +2488,27 @@ nsGenericHTMLElement::GetContentEditable(nsAString& aContentEditable)
|
||||
nsresult
|
||||
nsGenericHTMLElement::SetContentEditable(const nsAString& aContentEditable)
|
||||
{
|
||||
nsString contentEditable;
|
||||
ToLowerCase(aContentEditable, contentEditable);
|
||||
|
||||
if (contentEditable.EqualsLiteral("inherit")) {
|
||||
if (nsContentUtils::EqualsLiteralIgnoreASCIICase(aContentEditable, "inherit")) {
|
||||
UnsetAttr(kNameSpaceID_None, nsGkAtoms::contenteditable, true);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (!contentEditable.EqualsLiteral("true") &&
|
||||
!contentEditable.EqualsLiteral("false")) {
|
||||
return NS_ERROR_DOM_SYNTAX_ERR;
|
||||
}
|
||||
|
||||
SetAttr(kNameSpaceID_None, nsGkAtoms::contenteditable, contentEditable,
|
||||
true);
|
||||
if (nsContentUtils::EqualsLiteralIgnoreASCIICase(aContentEditable, "true")) {
|
||||
SetAttr(kNameSpaceID_None, nsGkAtoms::contenteditable, NS_LITERAL_STRING("true"), true);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (nsContentUtils::EqualsLiteralIgnoreASCIICase(aContentEditable, "false")) {
|
||||
SetAttr(kNameSpaceID_None, nsGkAtoms::contenteditable, NS_LITERAL_STRING("false"), true);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return NS_ERROR_DOM_SYNTAX_ERR;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsGenericHTMLElement::GetIsContentEditable(bool* aContentEditable)
|
||||
{
|
||||
@ -2886,14 +2887,6 @@ nsGenericHTMLFormElement::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
|
||||
return nsGenericHTMLElement::PreHandleEvent(aVisitor);
|
||||
}
|
||||
|
||||
const nsAttrValue::EnumTable nsGenericHTMLElement::kCORSAttributeTable[] = {
|
||||
// Order matters here
|
||||
// See ParseAttribute in nsHTMLImageElement or nsHTMLMediaElement
|
||||
{ "anonymous", nsGenericHTMLElement::CORS_ANONYMOUS },
|
||||
{ "use-credentials", nsGenericHTMLElement::CORS_USE_CREDENTIALS },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
/* virtual */
|
||||
bool
|
||||
nsGenericHTMLFormElement::IsDisabled() const
|
||||
|
@ -530,7 +530,7 @@ public:
|
||||
* Returns the current disabled state of the element.
|
||||
*/
|
||||
virtual bool IsDisabled() const {
|
||||
return HasAttr(kNameSpaceID_None, nsGkAtoms::disabled);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IsHidden() const
|
||||
@ -538,32 +538,6 @@ public:
|
||||
return HasAttr(kNameSpaceID_None, nsGkAtoms::hidden);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shared cross-origin resource sharing attributes so they don't get
|
||||
* duplicated on every CORS-enabled element
|
||||
*/
|
||||
|
||||
enum CORSMode {
|
||||
/**
|
||||
* The default of not using CORS to validate cross-origin loads.
|
||||
*/
|
||||
CORS_NONE,
|
||||
|
||||
/**
|
||||
* Validate cross-site loads using CORS, but do not send any credentials
|
||||
* (cookies, HTTP auth logins, etc) along with the request.
|
||||
*/
|
||||
CORS_ANONYMOUS,
|
||||
|
||||
/**
|
||||
* Validate cross-site loads using CORS, and send credentials such as cookies
|
||||
* and HTTP auth logins along with the request.
|
||||
*/
|
||||
CORS_USE_CREDENTIALS
|
||||
};
|
||||
|
||||
const static nsAttrValue::EnumTable kCORSAttributeTable[];
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Add/remove this element to the documents name cache
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user