merge the last green changeset on m-c to fx-team

This commit is contained in:
Tim Taubert 2011-08-04 14:12:03 +02:00
Родитель 35649df36e 4067f13aee
Коммит 5d28376b91
203 изменённых файлов: 4070 добавлений и 2149 удалений

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

@ -408,12 +408,9 @@ nsAccessibleWrap::CreateMaiInterfaces(void)
// the Component interface are supported by all nsIAccessible
interfacesBits |= 1 << MAI_INTERFACE_COMPONENT;
// Add Action interface if the action count is more than zero.
PRUint8 actionCount = 0;
nsresult rv = GetNumActions(&actionCount);
if (NS_SUCCEEDED(rv) && actionCount > 0) {
interfacesBits |= 1 << MAI_INTERFACE_ACTION;
}
// Add Action interface if the action count is more than zero.
if (ActionCount() > 0)
interfacesBits |= 1 << MAI_INTERFACE_ACTION;
//nsIAccessibleText
nsCOMPtr<nsIAccessibleText> accessInterfaceText;

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

@ -73,13 +73,8 @@ doActionCB(AtkAction *aAction, gint aActionIndex)
gint
getActionCountCB(AtkAction *aAction)
{
nsAccessibleWrap *accWrap = GetAccessibleWrap(ATK_OBJECT(aAction));
if (!accWrap)
return 0;
PRUint8 num = 0;
nsresult rv = accWrap->GetNumActions(&num);
return (NS_FAILED(rv)) ? 0 : static_cast<gint>(num);
nsAccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aAction));
return accWrap ? accWrap->ActionCount() : 0;
}
const gchar *

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

@ -132,27 +132,17 @@ AccGroupInfo::AccGroupInfo(nsAccessible* aItem, PRUint32 aRole) :
if (mParent)
return;
// Compute parent.
PRUint32 parentRole = parent->Role();
// In the case of ARIA row in treegrid, return treegrid since ARIA
// groups aren't used to organize levels in ARIA treegrids.
if (aRole == nsIAccessibleRole::ROLE_ROW &&
parentRole == nsIAccessibleRole::ROLE_TREE_TABLE) {
if (IsConceptualParent(aRole, parentRole))
mParent = parent;
return;
}
// In the case of ARIA tree, a tree can be arranged by using ARIA groups
// to organize levels. In this case the parent of the tree item will be
// a group and the previous treeitem of that should be the tree item
// parent. Or, if the parent is something other than a tree we will
// return that.
if (parentRole != nsIAccessibleRole::ROLE_GROUPING) {
mParent = parent;
// In the case of ARIA tree (not ARIA treegrid) a tree can be arranged by
// using ARIA groups to organize levels. In this case the parent of the tree
// item will be a group and the previous treeitem of that should be the tree
// item parent.
if (parentRole != nsIAccessibleRole::ROLE_GROUPING ||
aRole != nsIAccessibleRole::ROLE_OUTLINEITEM)
return;
}
nsAccessible* parentPrevSibling = parent->PrevSibling();
if (!parentPrevSibling)
@ -174,3 +164,37 @@ AccGroupInfo::AccGroupInfo(nsAccessible* aItem, PRUint32 aRole) :
if (parentPrevSiblingRole == nsIAccessibleRole::ROLE_OUTLINEITEM)
mParent = parentPrevSibling;
}
bool
AccGroupInfo::IsConceptualParent(PRUint32 aRole, PRUint32 aParentRole)
{
if (aParentRole == nsIAccessibleRole::ROLE_OUTLINE &&
aRole == nsIAccessibleRole::ROLE_OUTLINEITEM)
return true;
if ((aParentRole == nsIAccessibleRole::ROLE_TABLE ||
aParentRole == nsIAccessibleRole::ROLE_TREE_TABLE) &&
aRole == nsIAccessibleRole::ROLE_ROW)
return true;
if (aParentRole == nsIAccessibleRole::ROLE_ROW &&
(aRole == nsIAccessibleRole::ROLE_CELL ||
aRole == nsIAccessibleRole::ROLE_GRID_CELL))
return true;
if (aParentRole == nsIAccessibleRole::ROLE_LIST &&
aRole == nsIAccessibleRole::ROLE_LISTITEM)
return true;
if (aParentRole == nsIAccessibleRole::ROLE_COMBOBOX_LIST &&
aRole == nsIAccessibleRole::ROLE_COMBOBOX_OPTION)
return true;
if (aParentRole == nsIAccessibleRole::ROLE_LISTBOX &&
aRole == nsIAccessibleRole::ROLE_OPTION)
return true;
if (aParentRole == nsIAccessibleRole::ROLE_PAGETABLIST &&
aRole == nsIAccessibleRole::ROLE_PAGETAB)
return true;
if ((aParentRole == nsIAccessibleRole::ROLE_POPUP_MENU ||
aParentRole == nsIAccessibleRole::ROLE_MENUPOPUP) &&
aRole == nsIAccessibleRole::ROLE_MENUITEM)
return true;
return false;
}

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

@ -52,7 +52,7 @@ public:
PRInt32 PosInSet() const { return mPosInSet; }
PRUint32 SetSize() const { return mSetSize; }
nsAccessible* GetConceptualParent() const { return mParent; }
nsAccessible* ConceptualParent() const { return mParent; }
/**
* Create group info.
@ -88,6 +88,12 @@ private:
return aRole;
}
/**
* Return true if the given parent role is conceptual parent of the given
* role.
*/
static bool IsConceptualParent(PRUint32 aRole, PRUint32 aParentRole);
PRUint32 mPosInSet;
PRUint32 mSetSize;
nsAccessible* mParent;

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

@ -87,21 +87,6 @@ TextUpdater::DoUpdate(const nsAString& aNewText, const nsAString& aOldText,
PRUint32 oldLen = aOldText.Length(), newLen = aNewText.Length();
PRUint32 minLen = NS_MIN(oldLen, newLen);
// Text was appended or removed to/from the end.
if (aSkipStart == minLen) {
// If text has been appended to the end, fire text inserted event.
if (oldLen < newLen) {
UpdateTextNFireEvent(aNewText, Substring(aNewText, oldLen),
oldLen, PR_TRUE);
return;
}
// Text has been removed from the end, fire text removed event.
UpdateTextNFireEvent(aNewText, Substring(aOldText, newLen),
newLen, PR_FALSE);
return;
}
// Trim coinciding substrings from the end.
PRUint32 skipEnd = 0;
while (minLen - skipEnd > aSkipStart &&
@ -109,25 +94,6 @@ TextUpdater::DoUpdate(const nsAString& aNewText, const nsAString& aOldText,
skipEnd++;
}
// Text was appended or removed to/from the start.
if (skipEnd == minLen) {
// If text has been appended to the start, fire text inserted event.
if (oldLen < newLen) {
UpdateTextNFireEvent(aNewText, Substring(aNewText, 0, newLen - skipEnd),
0, PR_TRUE);
return;
}
// Text has been removed from the start, fire text removed event.
UpdateTextNFireEvent(aNewText, Substring(aOldText, 0, oldLen - skipEnd),
0, PR_FALSE);
return;
}
// Find the difference between strings and fire events.
// Note: we can skip initial and final coinciding characters since they don't
// affect the Levenshtein distance.
PRInt32 strLen1 = oldLen - aSkipStart - skipEnd;
PRInt32 strLen2 = newLen - aSkipStart - skipEnd;
@ -137,6 +103,42 @@ TextUpdater::DoUpdate(const nsAString& aNewText, const nsAString& aOldText,
// Increase offset of the text leaf on skipped characters amount.
mTextOffset += aSkipStart;
// It could be single insertion or removal or the case of long strings. Do not
// calculate the difference between long strings and prefer to fire pair of
// insert/remove events as the old string was replaced on the new one.
if (strLen1 == 0 || strLen2 == 0 ||
strLen1 > kMaxStrLen || strLen2 > kMaxStrLen) {
if (strLen1 > 0) {
// Fire text change event for removal.
nsRefPtr<AccEvent> textRemoveEvent =
new AccTextChangeEvent(mHyperText, mTextOffset, str1, PR_FALSE);
mDocument->FireDelayedAccessibleEvent(textRemoveEvent);
}
if (strLen2 > 0) {
// Fire text change event for insertion.
nsRefPtr<AccEvent> textInsertEvent =
new AccTextChangeEvent(mHyperText, mTextOffset, str2, PR_TRUE);
mDocument->FireDelayedAccessibleEvent(textInsertEvent);
}
// Fire value change event.
if (mHyperText->Role() == nsIAccessibleRole::ROLE_ENTRY) {
nsRefPtr<AccEvent> valueChangeEvent =
new AccEvent(nsIAccessibleEvent::EVENT_VALUE_CHANGE, mHyperText,
eAutoDetect, AccEvent::eRemoveDupes);
mDocument->FireDelayedAccessibleEvent(valueChangeEvent);
}
// Update the text.
mTextLeaf->SetText(aNewText);
return;
}
// Otherwise find the difference between strings and fire events.
// Note: we can skip initial and final coinciding characters since they don't
// affect the Levenshtein distance.
// Compute the flat structured matrix need to compute the difference.
PRUint32 len1 = strLen1 + 1, len2 = strLen2 + 1;
PRUint32* entries = new PRUint32[len1 * len2];
@ -238,27 +240,3 @@ TextUpdater::ComputeTextChangeEvents(const nsAString& aStr1,
if (colEnd)
FireDeleteEvent(Substring(aStr1, 0, colEnd), 0, aEvents);
}
void
TextUpdater::UpdateTextNFireEvent(const nsAString& aNewText,
const nsAString& aChangeText,
PRUint32 aAddlOffset,
PRBool aIsInserted)
{
// Fire text change event.
nsRefPtr<AccEvent> textChangeEvent =
new AccTextChangeEvent(mHyperText, mTextOffset + aAddlOffset, aChangeText,
aIsInserted);
mDocument->FireDelayedAccessibleEvent(textChangeEvent);
// Fire value change event.
if (mHyperText->Role() == nsIAccessibleRole::ROLE_ENTRY) {
nsRefPtr<AccEvent> valueChangeEvent =
new AccEvent(nsIAccessibleEvent::EVENT_VALUE_CHANGE, mHyperText,
eAutoDetect, AccEvent::eRemoveDupes);
mDocument->FireDelayedAccessibleEvent(valueChangeEvent);
}
// Update the text.
mTextLeaf->SetText(aNewText);
}

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

@ -108,11 +108,10 @@ private:
}
/**
* Update the text and fire text change/value change events.
* The constant used to skip string difference calculation in case of long
* strings.
*/
void UpdateTextNFireEvent(const nsAString& aNewText,
const nsAString& aChangeText, PRUint32 aAddlOffset,
PRBool aIsInserted);
const static PRUint32 kMaxStrLen = 1 << 6;
private:
nsDocAccessible* mDocument;

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

@ -1849,22 +1849,23 @@ nsAccessible::NativeRole()
// readonly attribute PRUint8 numActions
NS_IMETHODIMP
nsAccessible::GetNumActions(PRUint8 *aNumActions)
nsAccessible::GetNumActions(PRUint8* aActionCount)
{
NS_ENSURE_ARG_POINTER(aNumActions);
*aNumActions = 0;
NS_ENSURE_ARG_POINTER(aActionCount);
*aActionCount = 0;
if (IsDefunct())
return NS_ERROR_FAILURE;
PRUint32 actionRule = GetActionRule(State());
if (actionRule == eNoAction)
return NS_OK;
*aNumActions = 1;
*aActionCount = ActionCount();
return NS_OK;
}
PRUint8
nsAccessible::ActionCount()
{
return GetActionRule(State()) == eNoAction ? 0 : 1;
}
/* DOMString getAccActionName (in PRUint8 index); */
NS_IMETHODIMP
nsAccessible::GetActionName(PRUint8 aIndex, nsAString& aName)
@ -2140,7 +2141,7 @@ nsAccessible::GetRelationByType(PRUint32 aRelationType,
return NS_OK_NO_RELATION_TARGET;
return nsRelUtils::AddTarget(aRelationType, aRelation,
groupInfo->GetConceptualParent());
groupInfo->ConceptualParent());
}
// If accessible is in its own Window, or is the root of a document,

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

@ -418,6 +418,11 @@ public:
//////////////////////////////////////////////////////////////////////////////
// ActionAccessible
/**
* Return the number of actions that can be performed on this accessible.
*/
virtual PRUint8 ActionCount();
/**
* Return access key, such as Alt+D.
*/
@ -676,7 +681,7 @@ protected:
/**
* Return the action rule based on ARIA enum constants EActionRule
* (see nsARIAMap.h). Used by GetNumActions() and GetActionName().
* (see nsARIAMap.h). Used by ActionCount() and GetActionName().
*
* @param aStates [in] states of the accessible
*/

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

@ -237,12 +237,10 @@ nsApplicationAccessible::TakeFocus()
return NS_OK;
}
NS_IMETHODIMP
nsApplicationAccessible::GetNumActions(PRUint8 *aNumActions)
PRUint8
nsApplicationAccessible::ActionCount()
{
NS_ENSURE_ARG_POINTER(aNumActions);
*aNumActions = 0;
return NS_OK;
return 0;
}
NS_IMETHODIMP

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

@ -103,7 +103,6 @@ public:
NS_IMETHOD SetSelected(PRBool aIsSelected);
NS_IMETHOD TakeSelection();
NS_IMETHOD TakeFocus();
NS_IMETHOD GetNumActions(PRUint8 *aNumActions);
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString &aName);
NS_IMETHOD GetActionDescription(PRUint8 aIndex, nsAString &aDescription);
NS_IMETHOD DoAction(PRUint8 aIndex);
@ -129,6 +128,7 @@ public:
virtual void InvalidateChildren();
// ActionAccessible
virtual PRUint8 ActionCount();
virtual KeyBinding AccessKey() const;
protected:

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

@ -138,13 +138,10 @@ nsLinkableAccessible::GetValue(nsAString& aValue)
}
NS_IMETHODIMP
nsLinkableAccessible::GetNumActions(PRUint8 *aNumActions)
PRUint8
nsLinkableAccessible::ActionCount()
{
NS_ENSURE_ARG_POINTER(aNumActions);
*aNumActions = (mIsOnclick || mIsLink) ? 1 : 0;
return NS_OK;
return (mIsOnclick || mIsLink) ? 1 : 0;
}
NS_IMETHODIMP

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

@ -87,7 +87,6 @@ public:
NS_DECL_ISUPPORTS_INHERITED
// nsIAccessible
NS_IMETHOD GetNumActions(PRUint8 *_retval);
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
NS_IMETHOD DoAction(PRUint8 index);
NS_IMETHOD GetValue(nsAString& _retval);
@ -100,6 +99,7 @@ public:
virtual PRUint64 NativeState();
// ActionAccessible
virtual PRUint8 ActionCount();
virtual KeyBinding AccessKey() const;
// HyperLinkAccessible

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

@ -191,13 +191,10 @@ nsRadioButtonAccessible::
{
}
NS_IMETHODIMP
nsRadioButtonAccessible::GetNumActions(PRUint8 *aNumActions)
PRUint8
nsRadioButtonAccessible::ActionCount()
{
NS_ENSURE_ARG_POINTER(aNumActions);
*aNumActions = 1;
return NS_OK;
return 1;
}
NS_IMETHODIMP nsRadioButtonAccessible::GetActionName(PRUint8 aIndex, nsAString& aName)

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

@ -75,13 +75,15 @@ public:
nsRadioButtonAccessible(nsIContent *aContent, nsIWeakReference *aShell);
// nsIAccessible
NS_IMETHOD GetNumActions(PRUint8 *_retval);
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
NS_IMETHOD DoAction(PRUint8 aIndex);
// nsAccessible
virtual PRUint32 NativeRole();
// ActionAccessible
virtual PRUint8 ActionCount();
enum { eAction_Click = 0 };
};

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

@ -112,14 +112,11 @@ nsOuterDocAccessible::GetAttributesInternal(nsIPersistentProperties *aAttributes
////////////////////////////////////////////////////////////////////////////////
// nsIAccessible
NS_IMETHODIMP
nsOuterDocAccessible::GetNumActions(PRUint8 *aNumActions)
PRUint8
nsOuterDocAccessible::ActionCount()
{
NS_ENSURE_ARG_POINTER(aNumActions);
*aNumActions = 0;
// Internal frame, which is the doc's parent, should not have a click action.
return NS_OK;
return 0;
}
NS_IMETHODIMP

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

@ -58,7 +58,6 @@ public:
NS_DECL_ISUPPORTS_INHERITED
// nsIAccessible
NS_IMETHOD GetNumActions(PRUint8 *aNumActions);
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
NS_IMETHOD GetActionDescription(PRUint8 aIndex, nsAString& aDescription);
NS_IMETHOD DoAction(PRUint8 aIndex);
@ -77,6 +76,9 @@ public:
virtual PRBool AppendChild(nsAccessible *aAccessible);
virtual PRBool RemoveChild(nsAccessible *aAccessible);
// ActionAccessible
virtual PRUint8 ActionCount();
protected:
// nsAccessible
virtual void CacheChildren();

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

@ -78,10 +78,10 @@ nsHTMLCheckboxAccessible::NativeRole()
return nsIAccessibleRole::ROLE_CHECKBUTTON;
}
NS_IMETHODIMP nsHTMLCheckboxAccessible::GetNumActions(PRUint8 *_retval)
PRUint8
nsHTMLCheckboxAccessible::ActionCount()
{
*_retval = 1;
return NS_OK;
return 1;
}
NS_IMETHODIMP nsHTMLCheckboxAccessible::GetActionName(PRUint8 aIndex, nsAString& aName)
@ -237,10 +237,10 @@ nsHTMLButtonAccessible::
{
}
NS_IMETHODIMP nsHTMLButtonAccessible::GetNumActions(PRUint8 *_retval)
PRUint8
nsHTMLButtonAccessible::ActionCount()
{
*_retval = 1;
return NS_OK;
return 1;
}
NS_IMETHODIMP nsHTMLButtonAccessible::GetActionName(PRUint8 aIndex, nsAString& aName)
@ -325,10 +325,10 @@ nsHTML4ButtonAccessible::
{
}
NS_IMETHODIMP nsHTML4ButtonAccessible::GetNumActions(PRUint8 *_retval)
PRUint8
nsHTML4ButtonAccessible::ActionCount()
{
*_retval = 1;
return NS_OK;;
return 1;
}
NS_IMETHODIMP nsHTML4ButtonAccessible::GetActionName(PRUint8 aIndex, nsAString& aName)
@ -514,10 +514,10 @@ nsHTMLTextFieldAccessible::NativeState()
return state;
}
NS_IMETHODIMP nsHTMLTextFieldAccessible::GetNumActions(PRUint8 *_retval)
PRUint8
nsHTMLTextFieldAccessible::ActionCount()
{
*_retval = 1;
return NS_OK;;
return 1;
}
NS_IMETHODIMP nsHTMLTextFieldAccessible::GetActionName(PRUint8 aIndex, nsAString& aName)

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

@ -59,13 +59,15 @@ public:
nsHTMLCheckboxAccessible(nsIContent *aContent, nsIWeakReference *aShell);
// nsIAccessible
NS_IMETHOD GetNumActions(PRUint8 *_retval);
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
NS_IMETHOD DoAction(PRUint8 index);
// nsAccessible
virtual PRUint32 NativeRole();
virtual PRUint64 NativeState();
// ActionAccessible
virtual PRUint8 ActionCount();
};
@ -98,7 +100,6 @@ public:
nsHTMLButtonAccessible(nsIContent *aContent, nsIWeakReference *aShell);
// nsIAccessible
NS_IMETHOD GetNumActions(PRUint8 *_retval);
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
NS_IMETHOD DoAction(PRUint8 index);
@ -106,6 +107,9 @@ public:
virtual nsresult GetNameInternal(nsAString& aName);
virtual PRUint32 NativeRole();
virtual PRUint64 NativeState();
// ActionAccessible
virtual PRUint8 ActionCount();
};
@ -121,13 +125,15 @@ public:
nsHTML4ButtonAccessible(nsIContent *aContent, nsIWeakReference *aShell);
// nsIAccessible
NS_IMETHOD GetNumActions(PRUint8 *_retval);
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
NS_IMETHOD DoAction(PRUint8 index);
// nsAccessible
virtual PRUint32 NativeRole();
virtual PRUint64 NativeState();
// ActionAccessible
virtual PRUint8 ActionCount();
};
@ -146,7 +152,6 @@ public:
// nsIAccessible
NS_IMETHOD GetValue(nsAString& _retval);
NS_IMETHOD GetNumActions(PRUint8 *_retval);
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
NS_IMETHOD DoAction(PRUint8 index);
@ -157,6 +162,9 @@ public:
virtual nsresult GetNameInternal(nsAString& aName);
virtual PRUint32 NativeRole();
virtual PRUint64 NativeState();
// ActionAccessible
virtual PRUint8 ActionCount();
};

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

@ -131,22 +131,11 @@ nsHTMLImageAccessible::NativeRole()
////////////////////////////////////////////////////////////////////////////////
// nsIAccessible
NS_IMETHODIMP
nsHTMLImageAccessible::GetNumActions(PRUint8 *aNumActions)
PRUint8
nsHTMLImageAccessible::ActionCount()
{
NS_ENSURE_ARG_POINTER(aNumActions);
*aNumActions = 0;
if (IsDefunct())
return NS_ERROR_FAILURE;
nsresult rv= nsLinkableAccessible::GetNumActions(aNumActions);
NS_ENSURE_SUCCESS(rv, rv);
if (HasLongDesc())
(*aNumActions)++;
return NS_OK;
PRUint8 actionCount = nsLinkableAccessible::ActionCount();
return HasLongDesc() ? actionCount + 1 : actionCount;
}
NS_IMETHODIMP
@ -248,9 +237,5 @@ nsHTMLImageAccessible::IsValidLongDescIndex(PRUint8 aIndex)
if (!HasLongDesc())
return PR_FALSE;
PRUint8 numActions = 0;
nsresult rv = nsLinkableAccessible::GetNumActions(&numActions);
NS_ENSURE_SUCCESS(rv, PR_FALSE);
return (aIndex == numActions);
return aIndex == nsLinkableAccessible::ActionCount();
}

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

@ -57,7 +57,6 @@ public:
NS_DECL_ISUPPORTS_INHERITED
// nsIAccessible
NS_IMETHOD GetNumActions(PRUint8 *aNumActions);
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
NS_IMETHOD DoAction(PRUint8 index);
@ -70,6 +69,9 @@ public:
virtual PRUint64 NativeState();
virtual nsresult GetAttributesInternal(nsIPersistentProperties *aAttributes);
// ActionAccessible
virtual PRUint8 ActionCount();
private:
/**
* Determine if this image accessible has a longdesc attribute.

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

@ -120,16 +120,10 @@ nsHTMLLinkAccessible::GetValue(nsAString& aValue)
return presShell->GetLinkLocation(DOMNode, aValue);
}
NS_IMETHODIMP
nsHTMLLinkAccessible::GetNumActions(PRUint8 *aNumActions)
PRUint8
nsHTMLLinkAccessible::ActionCount()
{
NS_ENSURE_ARG_POINTER(aNumActions);
if (!IsLinked())
return nsHyperTextAccessible::GetNumActions(aNumActions);
*aNumActions = 1;
return NS_OK;
return IsLinked() ? 1 : nsHyperTextAccessible::ActionCount();
}
NS_IMETHODIMP

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

@ -52,7 +52,6 @@ public:
// nsIAccessible
NS_IMETHOD GetValue(nsAString& aValue);
NS_IMETHOD GetNumActions(PRUint8 *aNumActions);
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
NS_IMETHOD DoAction(PRUint8 aIndex);
@ -60,6 +59,9 @@ public:
virtual PRUint32 NativeRole();
virtual PRUint64 NativeState();
// ActionAccessible
virtual PRUint8 ActionCount();
// HyperLinkAccessible
virtual bool IsLink();
virtual already_AddRefed<nsIURI> AnchorURIAt(PRUint32 aAnchorIndex);

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

@ -371,10 +371,10 @@ NS_IMETHODIMP nsHTMLSelectOptionAccessible::GetActionName(PRUint8 aIndex, nsAStr
return NS_ERROR_INVALID_ARG;
}
NS_IMETHODIMP nsHTMLSelectOptionAccessible::GetNumActions(PRUint8 *_retval)
PRUint8
nsHTMLSelectOptionAccessible::ActionCount()
{
*_retval = 1;
return NS_OK;
return 1;
}
NS_IMETHODIMP nsHTMLSelectOptionAccessible::DoAction(PRUint8 index)
@ -616,9 +616,10 @@ NS_IMETHODIMP nsHTMLSelectOptGroupAccessible::GetActionName(PRUint8 aIndex, nsAS
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsHTMLSelectOptGroupAccessible::GetNumActions(PRUint8 *_retval)
PRUint8
nsHTMLSelectOptGroupAccessible::ActionCount()
{
return NS_ERROR_NOT_IMPLEMENTED;
return 0;
}
////////////////////////////////////////////////////////////////////////////////
@ -773,11 +774,10 @@ NS_IMETHODIMP nsHTMLComboboxAccessible::GetValue(nsAString& aValue)
return option ? option->GetName(aValue) : NS_OK;
}
/** Just one action ( click ). */
NS_IMETHODIMP nsHTMLComboboxAccessible::GetNumActions(PRUint8 *aNumActions)
PRUint8
nsHTMLComboboxAccessible::ActionCount()
{
*aNumActions = 1;
return NS_OK;
return 1;
}
/**

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

@ -108,7 +108,6 @@ public:
// nsIAccessible
NS_IMETHOD DoAction(PRUint8 index);
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
NS_IMETHOD GetNumActions(PRUint8 *_retval);
NS_IMETHOD SetSelected(PRBool aSelect);
// nsAccessible
@ -120,6 +119,9 @@ public:
virtual void GetPositionAndSizeInternal(PRInt32 *aPosInSet,
PRInt32 *aSetSize);
// ActionAccessible
virtual PRUint8 ActionCount();
/**
* Return focused option if any.
*/
@ -154,12 +156,14 @@ public:
// nsIAccessible
NS_IMETHOD DoAction(PRUint8 index);
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
NS_IMETHOD GetNumActions(PRUint8 *_retval);
// nsAccessible
virtual PRUint32 NativeRole();
virtual PRUint64 NativeState();
// ActionAccessible
virtual PRUint8 ActionCount();
protected:
// nsAccessible
virtual void CacheChildren();
@ -185,7 +189,6 @@ public:
// nsIAccessible
NS_IMETHOD GetValue(nsAString& _retval);
NS_IMETHOD DoAction(PRUint8 index);
NS_IMETHOD GetNumActions(PRUint8 *aNumActions);
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
// nsAccessNode
@ -197,6 +200,9 @@ public:
virtual PRUint64 NativeState();
virtual void InvalidateChildren();
// ActionAccessible
virtual PRUint8 ActionCount();
protected:
// nsAccessible
virtual void CacheChildren();

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

@ -63,21 +63,19 @@ CAccessibleAction::QueryInterface(REFIID iid, void** ppv)
// IAccessibleAction
STDMETHODIMP
CAccessibleAction::nActions(long *aNumActions)
CAccessibleAction::nActions(long* aActionCount)
{
__try {
*aNumActions = 0;
if (!aActionCount)
return E_INVALIDARG;
nsCOMPtr<nsIAccessible> acc(do_QueryObject(this));
if (!acc)
*aActionCount = 0;
nsRefPtr<nsAccessible> acc(do_QueryObject(this));
if (!acc || acc->IsDefunct())
return E_FAIL;
PRUint8 count = 0;
nsresult rv = acc->GetNumActions(&count);
if (NS_FAILED(rv))
return GetHRESULT(rv);
*aNumActions = count;
*aActionCount = acc->ActionCount();
return S_OK;
} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }

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

@ -234,9 +234,16 @@ __try {
STDMETHODIMP nsAccessibleWrap::get_accChildCount( long __RPC_FAR *pcountChildren)
{
__try {
if (!pcountChildren)
return E_INVALIDARG;
*pcountChildren = 0;
if (IsDefunct())
return E_FAIL;
if (nsAccUtils::MustPrune(this))
return NS_OK;
return S_OK;
*pcountChildren = GetChildCount();
} __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }

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

@ -545,13 +545,10 @@ nsXFormsSelectableItemAccessible::GetValue(nsAString& aValue)
return sXFormsService->GetValue(DOMNode, aValue);
}
NS_IMETHODIMP
nsXFormsSelectableItemAccessible::GetNumActions(PRUint8 *aCount)
PRUint8
nsXFormsSelectableItemAccessible::ActionCount()
{
NS_ENSURE_ARG_POINTER(aCount);
*aCount = 1;
return NS_OK;
return 1;
}
NS_IMETHODIMP

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

@ -190,9 +190,11 @@ public:
nsIWeakReference *aShell);
NS_IMETHOD GetValue(nsAString& aValue);
NS_IMETHOD GetNumActions(PRUint8 *aCount);
NS_IMETHOD DoAction(PRUint8 aIndex);
// ActionAccessible
virtual PRUint8 ActionCount();
protected:
bool IsSelected();
};

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

@ -115,13 +115,10 @@ nsXFormsTriggerAccessible::GetValue(nsAString& aValue)
return NS_OK;
}
NS_IMETHODIMP
nsXFormsTriggerAccessible::GetNumActions(PRUint8 *aCount)
PRUint8
nsXFormsTriggerAccessible::ActionCount()
{
NS_ENSURE_ARG_POINTER(aCount);
*aCount = 1;
return NS_OK;
return 1;
}
NS_IMETHODIMP
@ -163,13 +160,10 @@ nsXFormsInputAccessible::NativeRole()
return nsIAccessibleRole::ROLE_ENTRY;
}
NS_IMETHODIMP
nsXFormsInputAccessible::GetNumActions(PRUint8* aCount)
PRUint8
nsXFormsInputAccessible::ActionCount()
{
NS_ENSURE_ARG_POINTER(aCount);
*aCount = 1;
return NS_OK;
return 1;
}
NS_IMETHODIMP
@ -225,13 +219,10 @@ nsXFormsInputBooleanAccessible::NativeState()
return state;
}
NS_IMETHODIMP
nsXFormsInputBooleanAccessible::GetNumActions(PRUint8 *aCount)
PRUint8
nsXFormsInputBooleanAccessible::ActionCount()
{
NS_ENSURE_ARG_POINTER(aCount);
*aCount = 1;
return NS_OK;
return 1;
}
NS_IMETHODIMP

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

@ -81,12 +81,14 @@ public:
// nsIAccessible
NS_IMETHOD GetValue(nsAString& aValue);
NS_IMETHOD GetNumActions(PRUint8 *aCount);
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
NS_IMETHOD DoAction(PRUint8 aIndex);
// nsAccessible
virtual PRUint32 NativeRole();
// ActionAccessible
virtual PRUint8 ActionCount();
};
/**
@ -101,12 +103,14 @@ public:
NS_DECL_ISUPPORTS_INHERITED
// nsIAccessible
NS_IMETHOD GetNumActions(PRUint8 *aCount);
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
NS_IMETHOD DoAction(PRUint8 aIndex);
// nsAccessible
virtual PRUint32 NativeRole();
// ActionAccessible
virtual PRUint8 ActionCount();
};
/**
@ -119,13 +123,15 @@ public:
nsXFormsInputBooleanAccessible(nsIContent *aContent, nsIWeakReference *aShell);
// nsIAccessible
NS_IMETHOD GetNumActions(PRUint8 *aCount);
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
NS_IMETHOD DoAction(PRUint8 aIndex);
// nsAccessible
virtual PRUint32 NativeRole();
virtual PRUint64 NativeState();
// ActionAccessible
virtual PRUint8 ActionCount();
};
/**

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

@ -70,13 +70,10 @@ nsXFormsDropmarkerWidgetAccessible::NativeState()
return isOpen ? states::PRESSED: 0;
}
NS_IMETHODIMP
nsXFormsDropmarkerWidgetAccessible::GetNumActions(PRUint8 *aCount)
PRUint8
nsXFormsDropmarkerWidgetAccessible::ActionCount()
{
NS_ENSURE_ARG_POINTER(aCount);
*aCount = 1;
return NS_OK;
return 1;
}
NS_IMETHODIMP

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

@ -55,13 +55,15 @@ public:
nsIWeakReference *aShell);
// nsIAccessible
NS_IMETHOD GetNumActions(PRUint8 *aCount);
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
NS_IMETHOD DoAction(PRUint8 aIndex);
// nsAccessible
virtual PRUint32 NativeRole();
virtual PRUint64 NativeState();
// ActionAccessible
virtual PRUint8 ActionCount();
};

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

@ -151,15 +151,11 @@ nsXULComboboxAccessible::GetAllowsAnonChildAccessibles()
// menuitems
return PR_FALSE;
}
NS_IMETHODIMP
nsXULComboboxAccessible::GetNumActions(PRUint8 *aNumActions)
PRUint8
nsXULComboboxAccessible::ActionCount()
{
NS_ENSURE_ARG_POINTER(aNumActions);
// Just one action (click).
*aNumActions = 1;
return NS_OK;
return 1;
}
NS_IMETHODIMP

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

@ -56,7 +56,6 @@ public:
// nsIAccessible
NS_IMETHOD GetValue(nsAString& aValue);
NS_IMETHOD DoAction(PRUint8 aIndex);
NS_IMETHOD GetNumActions(PRUint8 *aNumActions);
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
// nsAccessible
@ -64,6 +63,9 @@ public:
virtual PRUint32 NativeRole();
virtual PRUint64 NativeState();
virtual PRBool GetAllowsAnonChildAccessibles();
// ActionAccessible
virtual PRUint8 ActionCount();
};
#endif

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

@ -82,13 +82,10 @@ NS_IMPL_ISUPPORTS_INHERITED0(nsXULButtonAccessible, nsAccessible)
////////////////////////////////////////////////////////////////////////////////
// nsXULButtonAccessible: nsIAccessible
NS_IMETHODIMP
nsXULButtonAccessible::GetNumActions(PRUint8 *aCount)
PRUint8
nsXULButtonAccessible::ActionCount()
{
NS_ENSURE_ARG_POINTER(aCount);
*aCount = 1;
return NS_OK;
return 1;
}
NS_IMETHODIMP
@ -249,10 +246,10 @@ nsXULDropmarkerAccessible::
{
}
NS_IMETHODIMP nsXULDropmarkerAccessible::GetNumActions(PRUint8 *aResult)
PRUint8
nsXULDropmarkerAccessible::ActionCount()
{
*aResult = 1;
return NS_OK;
return 1;
}
PRBool nsXULDropmarkerAccessible::DropmarkerOpen(PRBool aToggleOpen)
@ -320,7 +317,6 @@ nsXULDropmarkerAccessible::NativeState()
return DropmarkerOpen(PR_FALSE) ? states::PRESSED : 0;
}
////////////////////////////////////////////////////////////////////////////////
// nsXULCheckboxAccessible
////////////////////////////////////////////////////////////////////////////////
@ -337,10 +333,10 @@ nsXULCheckboxAccessible::NativeRole()
return nsIAccessibleRole::ROLE_CHECKBUTTON;
}
NS_IMETHODIMP nsXULCheckboxAccessible::GetNumActions(PRUint8 *_retval)
PRUint8
nsXULCheckboxAccessible::ActionCount()
{
*_retval = 1;
return NS_OK;
return 1;
}
/**
@ -686,6 +682,9 @@ NS_IMPL_ISUPPORTS_INHERITED3(nsXULTextFieldAccessible, nsAccessible, nsHyperText
NS_IMETHODIMP nsXULTextFieldAccessible::GetValue(nsAString& aValue)
{
if (IsDefunct())
return NS_ERROR_FAILURE;
PRUint64 state = NativeState();
if (state & states::PROTECTED) // Don't return password text!
@ -753,14 +752,13 @@ nsXULTextFieldAccessible::NativeRole()
return nsIAccessibleRole::ROLE_ENTRY;
}
/**
* Only one actions available
*/
NS_IMETHODIMP nsXULTextFieldAccessible::GetNumActions(PRUint8 *_retval)
PRUint8
nsXULTextFieldAccessible::ActionCount()
{
*_retval = 1;
return NS_OK;
return 1;
}
/**

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

@ -67,7 +67,6 @@ public:
NS_DECL_ISUPPORTS_INHERITED
// nsIAccessible
NS_IMETHOD GetNumActions(PRUint8 *_retval);
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
NS_IMETHOD DoAction(PRUint8 index);
@ -75,6 +74,9 @@ public:
virtual PRUint32 NativeRole();
virtual PRUint64 NativeState();
// ActionAccessible
virtual PRUint8 ActionCount();
protected:
// nsAccessible
@ -95,13 +97,15 @@ public:
nsXULCheckboxAccessible(nsIContent *aContent, nsIWeakReference *aShell);
// nsIAccessible
NS_IMETHOD GetNumActions(PRUint8 *_retval);
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
NS_IMETHOD DoAction(PRUint8 index);
// nsAccessible
virtual PRUint32 NativeRole();
virtual PRUint64 NativeState();
// ActionAccessible
virtual PRUint8 ActionCount();
};
/**
@ -114,7 +118,6 @@ public:
nsXULDropmarkerAccessible(nsIContent *aContent, nsIWeakReference *aShell);
// nsIAccessible
NS_IMETHOD GetNumActions(PRUint8 *_retval);
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
NS_IMETHOD DoAction(PRUint8 index);
@ -122,6 +125,9 @@ public:
virtual PRUint32 NativeRole();
virtual PRUint64 NativeState();
// ActionAccessible
virtual PRUint8 ActionCount();
private:
PRBool DropmarkerOpen(PRBool aToggleOpen);
};
@ -240,7 +246,6 @@ public:
// nsIAccessible
NS_IMETHOD GetValue(nsAString& aValue);
NS_IMETHOD GetNumActions(PRUint8 *_retval);
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
NS_IMETHOD DoAction(PRUint8 index);
@ -253,6 +258,9 @@ public:
virtual PRUint64 NativeState();
virtual PRBool GetAllowsAnonChildAccessibles();
// ActionAccessible
virtual PRUint8 ActionCount();
protected:
// nsAccessible
virtual void CacheChildren();

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

@ -95,13 +95,10 @@ nsXULColumnItemAccessible::NativeState()
return states::READONLY;
}
NS_IMETHODIMP
nsXULColumnItemAccessible::GetNumActions(PRUint8 *aNumActions)
PRUint8
nsXULColumnItemAccessible::ActionCount()
{
NS_ENSURE_ARG_POINTER(aNumActions);
*aNumActions = 1;
return NS_OK;
return 1;
}
NS_IMETHODIMP

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

@ -72,7 +72,6 @@ public:
nsXULColumnItemAccessible(nsIContent *aContent, nsIWeakReference *aShell);
// nsIAccessible
NS_IMETHOD GetNumActions(PRUint8 *aNumActions);
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
NS_IMETHOD DoAction(PRUint8 aIndex);
@ -80,6 +79,9 @@ public:
virtual PRUint32 NativeRole();
virtual PRUint64 NativeState();
// ActionAccessible
virtual PRUint8 ActionCount();
enum { eAction_Click = 0 };
};

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

@ -565,10 +565,10 @@ NS_IMETHODIMP nsXULMenuitemAccessible::GetActionName(PRUint8 aIndex, nsAString&
return NS_ERROR_INVALID_ARG;
}
NS_IMETHODIMP nsXULMenuitemAccessible::GetNumActions(PRUint8 *_retval)
PRUint8
nsXULMenuitemAccessible::ActionCount()
{
*_retval = 1;
return NS_OK;
return 1;
}
@ -612,12 +612,12 @@ NS_IMETHODIMP nsXULMenuSeparatorAccessible::GetActionName(PRUint8 aIndex, nsAStr
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsXULMenuSeparatorAccessible::GetNumActions(PRUint8 *_retval)
PRUint8
nsXULMenuSeparatorAccessible::ActionCount()
{
return NS_ERROR_NOT_IMPLEMENTED;
return 0;
}
////////////////////////////////////////////////////////////////////////////////
// nsXULMenupopupAccessible
////////////////////////////////////////////////////////////////////////////////

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

@ -84,7 +84,6 @@ public:
// nsIAccessible
NS_IMETHOD DoAction(PRUint8 index);
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
NS_IMETHOD GetNumActions(PRUint8 *_retval);
// nsAccessible
virtual void Description(nsString& aDescription);
@ -98,6 +97,7 @@ public:
virtual PRBool GetAllowsAnonChildAccessibles();
// ActionAccessible
virtual PRUint8 ActionCount();
virtual KeyBinding AccessKey() const;
virtual KeyBinding KeyboardShortcut() const;
};
@ -113,12 +113,14 @@ public:
// nsIAccessible
NS_IMETHOD DoAction(PRUint8 index);
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
NS_IMETHOD GetNumActions(PRUint8 *_retval);
// nsAccessible
virtual nsresult GetNameInternal(nsAString& aName);
virtual PRUint32 NativeRole();
virtual PRUint64 NativeState();
// ActionAccessible
virtual PRUint8 ActionCount();
};

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

@ -97,13 +97,10 @@ nsXULSliderAccessible::GetValue(nsAString& aValue)
return GetSliderAttr(nsAccessibilityAtoms::curpos, aValue);
}
NS_IMETHODIMP
nsXULSliderAccessible::GetNumActions(PRUint8 *aCount)
PRUint8
nsXULSliderAccessible::ActionCount()
{
NS_ENSURE_ARG_POINTER(aCount);
*aCount = 1;
return NS_OK;
return 1;
}
NS_IMETHODIMP

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

@ -56,7 +56,6 @@ public:
// nsIAccessible
NS_IMETHOD GetValue(nsAString& aValue);
NS_IMETHOD GetNumActions(PRUint8 *aCount);
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
NS_IMETHOD DoAction(PRUint8 aIndex);
@ -68,6 +67,9 @@ public:
virtual PRUint64 NativeState();
virtual PRBool GetAllowsAnonChildAccessibles();
// ActionAccessible
virtual PRUint8 ActionCount();
protected:
already_AddRefed<nsIContent> GetSliderNode();

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

@ -65,10 +65,10 @@ nsXULTabAccessible::
////////////////////////////////////////////////////////////////////////////////
// nsXULTabAccessible: nsIAccessible
NS_IMETHODIMP nsXULTabAccessible::GetNumActions(PRUint8 *_retval)
PRUint8
nsXULTabAccessible::ActionCount()
{
*_retval = 1;
return NS_OK;
return 1;
}
/** Return the name of our only action */
@ -191,13 +191,10 @@ nsXULTabsAccessible::NativeRole()
return nsIAccessibleRole::ROLE_PAGETABLIST;
}
NS_IMETHODIMP
nsXULTabsAccessible::GetNumActions(PRUint8 *aCount)
PRUint8
nsXULTabsAccessible::ActionCount()
{
NS_ENSURE_ARG_POINTER(aCount);
*aCount = 0;
return NS_OK;
return 0;
}
/** no value */

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

@ -54,7 +54,6 @@ public:
nsXULTabAccessible(nsIContent *aContent, nsIWeakReference *aShell);
// nsIAccessible
NS_IMETHOD GetNumActions(PRUint8 *_retval);
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
NS_IMETHOD DoAction(PRUint8 index);
NS_IMETHOD GetRelationByType(PRUint32 aRelationType,
@ -65,6 +64,9 @@ public:
PRInt32 *aSetSize);
virtual PRUint32 NativeRole();
virtual PRUint64 NativeState();
// ActionAccessible
virtual PRUint8 ActionCount();
};
@ -77,12 +79,14 @@ public:
nsXULTabsAccessible(nsIContent *aContent, nsIWeakReference *aShell);
// nsIAccessible
NS_IMETHOD GetNumActions(PRUint8 *_retval);
NS_IMETHOD GetValue(nsAString& _retval);
// nsAccessible
virtual nsresult GetNameInternal(nsAString& aName);
virtual PRUint32 NativeRole();
// ActionAccessible
virtual PRUint8 ActionCount();
};

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

@ -189,13 +189,10 @@ nsXULLinkAccessible::NativeState()
return nsHyperTextAccessible::NativeState() | states::LINKED;
}
NS_IMETHODIMP
nsXULLinkAccessible::GetNumActions(PRUint8 *aNumActions)
PRUint8
nsXULLinkAccessible::ActionCount()
{
NS_ENSURE_ARG_POINTER(aNumActions);
*aNumActions = 1;
return NS_OK;
return 1;
}
NS_IMETHODIMP

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

@ -87,7 +87,6 @@ public:
// nsIAccessible
NS_IMETHOD GetValue(nsAString& aValue);
NS_IMETHOD GetNumActions(PRUint8 *aNumActions);
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
NS_IMETHOD DoAction(PRUint8 aIndex);
@ -96,6 +95,9 @@ public:
virtual PRUint32 NativeRole();
virtual PRUint64 NativeState();
// ActionAccessible
virtual PRUint8 ActionCount();
// HyperLinkAccessible
virtual bool IsLink();
virtual PRUint32 StartOffset();

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

@ -784,19 +784,12 @@ nsXULTreeItemAccessibleBase::GetRelationByType(PRUint32 aRelationType,
return nsAccessible::GetRelationByType(aRelationType, aRelation);
}
NS_IMETHODIMP
nsXULTreeItemAccessibleBase::GetNumActions(PRUint8 *aActionsCount)
PRUint8
nsXULTreeItemAccessibleBase::ActionCount()
{
NS_ENSURE_ARG_POINTER(aActionsCount);
*aActionsCount = 0;
if (IsDefunct())
return NS_ERROR_FAILURE;
// "activate" action is available for all treeitems, "expand/collapse" action
// is avaible for treeitem which is container.
*aActionsCount = IsExpandable() ? 2 : 1;
return NS_OK;
return IsExpandable() ? 2 : 1;
}
NS_IMETHODIMP

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

@ -195,7 +195,6 @@ public:
PRInt32 *aSimilarItemsInGroup,
PRInt32 *aPositionInGroup);
NS_IMETHOD GetNumActions(PRUint8 *aCount);
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
NS_IMETHOD DoAction(PRUint8 aIndex);
@ -209,6 +208,9 @@ public:
virtual PRInt32 IndexInParent() const;
virtual nsAccessible* FocusedChild();
// ActionAccessible
virtual PRUint8 ActionCount();
// nsXULTreeItemAccessibleBase
NS_DECLARE_STATIC_IID_ACCESSOR(NS_XULTREEITEMBASEACCESSIBLE_IMPL_CID)

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

@ -919,28 +919,20 @@ nsXULTreeGridCellAccessible::GetBounds(PRInt32 *aX, PRInt32 *aY,
return NS_OK;
}
NS_IMETHODIMP
nsXULTreeGridCellAccessible::GetNumActions(PRUint8 *aActionsCount)
PRUint8
nsXULTreeGridCellAccessible::ActionCount()
{
NS_ENSURE_ARG_POINTER(aActionsCount);
*aActionsCount = 0;
if (IsDefunct())
return NS_ERROR_FAILURE;
PRBool isCycler = PR_FALSE;
mColumn->GetCycler(&isCycler);
if (isCycler) {
*aActionsCount = 1;
return NS_OK;
}
if (isCycler)
return 1;
PRInt16 type;
mColumn->GetType(&type);
if (type == nsITreeColumn::TYPE_CHECKBOX && IsEditable())
*aActionsCount = 1;
return 1;
return NS_OK;
return 0;
}
NS_IMETHODIMP

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

@ -148,7 +148,6 @@ public:
NS_IMETHOD GetBounds(PRInt32 *aX, PRInt32 *aY,
PRInt32 *aWidth, PRInt32 *aHeight);
NS_IMETHOD GetNumActions(PRUint8 *aCount);
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
NS_IMETHOD DoAction(PRUint8 aIndex);
@ -163,9 +162,12 @@ public:
// nsAccessible
virtual nsAccessible* FocusedChild();
virtual nsresult GetAttributesInternal(nsIPersistentProperties *aAttributes);
virtual PRInt32 IndexInParent() const;
virtual PRUint32 NativeRole();
virtual PRUint64 NativeState();
virtual PRInt32 IndexInParent() const;
// ActionAccessible
virtual PRUint8 ActionCount();
// nsXULTreeGridCellAccessible
NS_DECLARE_STATIC_IID_ACCESSOR(NS_XULTREEGRIDCELLACCESSIBLE_IMPL_CID)

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

@ -24,6 +24,7 @@
const kRemoval = 0;
const kInsertion = 1;
const kUnexpected = true;
function changeText(aContainerID, aValue, aEventList)
{
@ -32,14 +33,22 @@
this.textData = this.textNode.data;
this.eventSeq = [ ];
this.unexpectedEventSeq = [ ];
for (var i = 0; i < aEventList.length; i++) {
var isInserted = aEventList[i][0];
var str = aEventList[i][1];
var offset = aEventList[i][2];
var event = aEventList[i];
var isInserted = event[0];
var str = event[1];
var offset = event[2];
var checker = new textChangeChecker(this.containerNode, offset,
offset + str.length, str,
isInserted);
this.eventSeq.push(checker);
if (eventItem[3] == kUnexpected)
this.unexpectedEventSeq.push(checker);
else
this.eventSeq.push(checker);
}
this.invoke = function changeText_invoke()
@ -54,6 +63,13 @@
}
}
function expStr(x, doublings)
{
for (var i = 0; i < doublings; ++i)
x = x + x;
return x;
}
////////////////////////////////////////////////////////////////////////////
// Do tests
@ -167,6 +183,34 @@
];
gQueue.push(new changeText("p11", "levenshtein", events));
//////////////////////////////////////////////////////////////////////////
// long strings, remove/insert pair as the old string was replaced on
// new one
var longStr1 = expStr("x", 16);
var longStr2 = expStr("X", 16);
var newStr = "a" + longStr1 + "b", insStr = longStr1, rmStr = "";
events = [
[ kRemoval, rmStr, 1, kUnexpected ],
[ kInsertion, insStr, 1 ]
];
gQueue.push(new changeText("p12", newStr, events));
newStr = "a" + longStr2 + "b", insStr = longStr2, rmStr = longStr1;
events = [
[ kRemoval, rmStr, 1 ],
[ kInsertion, insStr, 1]
];
gQueue.push(new changeText("p12", newStr, events));
newStr = "ab", insStr = "", rmStr = longStr2;
events = [
[ kRemoval, rmStr, 1 ],
[ kInsertion, insStr, 1, kUnexpected ]
];
gQueue.push(new changeText("p12", newStr, events));
gQueue.invoke(); // Will call SimpleTest.finish();
}
@ -201,5 +245,6 @@
<p id="p9">abcDEFabc</p>
<p id="p10">!abcdef@</p>
<p id="p11">meilenstein</p>
<p id="p12">ab</p>
</body>
</html>

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

@ -69,6 +69,10 @@
testRelation("treeitem4", RELATION_NODE_CHILD_OF, "tree");
testRelation("treeitem5", RELATION_NODE_CHILD_OF, "treeitem4");
// no relation node_child_of for accessible contained in an unexpected
// parent
testRelation("treeitem6", RELATION_NODE_CHILD_OF, null);
// 'node child of' relation for the document having window, returns
// direct accessible parent (fixed in bug 419770).
var iframeElmObj = {};
@ -146,6 +150,11 @@
title="mochitests for accessible relations">
Mozilla Bug 475298
</a><br/>
<a target="_blank"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=673389"
title="node_child_of on an item not in a proper container">
Mozilla Bug 67389
</a><br/>
<p id="display"></p>
<div id="content" style="display: none">
@ -192,6 +201,8 @@
<description role="treeitem" id="treeitem5" aria-level="2">Light green</description>
</vbox>
<description role="treeitem" id="treeitem6">Dark green</description>
<iframe id="iframe"/>
<hbox id="tablist" role="tablist">

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

@ -1372,19 +1372,15 @@
// aReferrerURI is null or undefined if the tab is opened from
// an external application or bookmark, i.e. somewhere other
// than the current tab.
if (aRelatedToCurrent == null ? aReferrerURI : aRelatedToCurrent) {
if ((aRelatedToCurrent == null ? aReferrerURI : aRelatedToCurrent) &&
Services.prefs.getBoolPref("browser.tabs.insertRelatedAfterCurrent")) {
let newTabPos = (this._lastRelatedTab ||
this.selectedTab)._tPos + 1;
if (this._lastRelatedTab)
this._lastRelatedTab.owner = null;
else
t.owner = this.selectedTab;
if (!this.selectedTab.pinned &&
Services.prefs.getBoolPref("browser.tabs.insertRelatedAfterCurrent"))
this.moveTabTo(t, newTabPos);
this.moveTabTo(t, newTabPos);
this._lastRelatedTab = t;
}

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

@ -153,6 +153,7 @@ _BROWSER_FILES = \
browser_zbug569342.js \
browser_bug575561.js \
browser_bug577121.js \
browser_bug578534.js \
browser_bug579872.js \
browser_bug580638.js \
browser_bug580956.js \

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

@ -0,0 +1,61 @@
/* ***** 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 bug 578534 test.
*
* The Initial Developer of the Original Code is
* Sindre Dammann <sindrebugzilla@gmail.com>
* Portions created by the Initial Developer are Copyright (C) 2010
* 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 ***** */
function test() {
let uriString = "http://example.com/";
let cookieBehavior = "network.cookie.cookieBehavior";
let uriObj = Services.io.newURI(uriString, null, null)
let cp = Components.classes["@mozilla.org/cookie/permission;1"]
.getService(Components.interfaces.nsICookiePermission);
Services.prefs.setIntPref(cookieBehavior, 2);
cp.setAccess(uriObj, cp.ACCESS_ALLOW);
gBrowser.selectedTab = gBrowser.addTab(uriString);
waitForExplicitFinish();
gBrowser.selectedBrowser.addEventListener("load", onTabLoaded, true);
function onTabLoaded() {
is(gBrowser.selectedBrowser.contentWindow.navigator.cookieEnabled, true,
"navigator.cookieEnabled should be true");
// Clean up
gBrowser.selectedBrowser.removeEventListener("load", onTabLoaded, true);
gBrowser.removeTab(gBrowser.selectedTab);
Services.prefs.setIntPref(cookieBehavior, 0);
cp.setAccess(uriObj, cp.ACCESS_DEFAULT);
finish();
}
}

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

@ -78,14 +78,5 @@ function test() {
testPosition(7, 8, "blank tab without referrer opens at the end");
testPosition(8, 9, "tab without referrer opens at the end");
gBrowser.selectedTab = tabs[0];
gBrowser.pinTab(gBrowser.selectedTab);
addTab("http://mochi.test:8888/#8", gBrowser.currentURI);
testPosition(9, 10, "tab with referrer should open at the end when the selected tab is pinned");
gBrowser.selectedTab = tabs[9];
gBrowser.removeTab(tabs.pop());
is(gBrowser.selectedTab, tabs[0],
"opening a tab from a pinned tab, selecting it and closing it should go back to the pinned tab");
tabs.forEach(gBrowser.removeTab, gBrowser);
}

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

@ -566,6 +566,7 @@ void ElfSegment::addSection(ElfSection *section)
if ((*i)->getAddr() > section->getAddr())
break;
sections.insert(i, section);
section->addToSegment(this);
}
unsigned int ElfSegment::getFileSize()
@ -636,8 +637,10 @@ ElfSegment *ElfSegment::splitBefore(ElfSection *section)
phdr.p_memsz = (unsigned int)-1;
ElfSegment *segment = new ElfSegment(&phdr);
for (rm = i; i != sections.end(); ++i)
for (rm = i; i != sections.end(); ++i) {
(*i)->removeFromSegment(this);
segment->addSection(*i);
}
sections.erase(rm, sections.end());
return segment;

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

@ -41,6 +41,7 @@
#include <cstring>
#include <iostream>
#include <fstream>
#include <algorithm>
#include <elf.h>
#include <asm/byteorder.h>
@ -370,7 +371,8 @@ public:
(getType() == SHT_GNU_HASH) ||
(getType() == SHT_GNU_verdef) ||
(getType() == SHT_GNU_verneed) ||
(getType() == SHT_GNU_versym)) &&
(getType() == SHT_GNU_versym) ||
isInSegmentType(PT_INTERP)) &&
(getFlags() & SHF_ALLOC);
}
@ -410,6 +412,20 @@ public:
file.seekp(getOffset());
file.write(data, getSize());
}
private:
friend class ElfSegment;
void addToSegment(ElfSegment *segment) {
segments.push_back(segment);
}
void removeFromSegment(ElfSegment *segment) {
std::vector<ElfSegment *>::iterator i = std::find(segments.begin(), segments.end(), segment);
segments.erase(i, i + 1);
}
bool isInSegmentType(unsigned int type);
protected:
Elf_Shdr shdr;
char *data;
@ -419,6 +435,7 @@ private:
SectionInfo info;
ElfSection *next, *previous;
int index;
std::vector<ElfSegment *> segments;
};
class ElfSegment {
@ -636,6 +653,13 @@ inline unsigned int Elf::getSize() {
return section->getOffset() + section->getSize();
}
inline bool ElfSection::isInSegmentType(unsigned int type) {
for (std::vector<ElfSegment *>::iterator seg = segments.begin(); seg != segments.end(); seg++)
if ((*seg)->getType() == type)
return true;
return false;
}
inline ElfLocation::ElfLocation(ElfSection *section, unsigned int off, enum position pos)
: section(section) {
if ((pos == ABSOLUTE) && section)

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

@ -68,7 +68,7 @@ nsJSPrincipalsSubsume(JSPrincipals *jsprin, JSPrincipals *other)
nsJSPrincipals *nsjsprin = static_cast<nsJSPrincipals *>(jsprin);
nsJSPrincipals *nsother = static_cast<nsJSPrincipals *>(other);
JSBool result;
PRBool result;
nsresult rv = nsjsprin->nsIPrincipalPtr->Subsumes(nsother->nsIPrincipalPtr,
&result);
return NS_SUCCEEDED(rv) && result;

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

@ -128,7 +128,7 @@ netscape_security_isPrivilegeEnabled(JSContext *cx, uintN argc, jsval *vp)
if (!obj)
return JS_FALSE;
JSBool result = JS_FALSE;
PRBool result = PR_FALSE;
if (JSString *str = getStringArgument(cx, obj, 0, argc, JS_ARGV(cx, vp))) {
JSAutoByteString cap(cx, str);
if (!cap)

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

@ -9396,6 +9396,20 @@ xpcom/xpcom-config.h
xpcom/xpcom-private.h
)
# Hack around an Apple bug that effects the egrep that comes with OS X 10.7.
# "arch -arch i386 egrep" always uses the 32-bit Intel part of the egrep fat
# binary, even on 64-bit systems. It should work on OS X 10.4.5 and up. We
# (apparently) only need this hack when egrep's "pattern" is particularly
# long (as in the following code). See bug 655339.
case "$host" in
x86_64-apple-darwin*)
FIXED_EGREP="arch -arch i386 egrep"
;;
*)
FIXED_EGREP="egrep"
;;
esac
# Save the defines header file before autoconf removes it.
# (Do not add AC_DEFINE calls after this line.)
_CONFIG_TMP=confdefs-tmp.h
@ -9419,7 +9433,7 @@ if test -n "$_NON_GLOBAL_ACDEFINES"; then
fi
_EGREP_PATTERN="${_EGREP_PATTERN}dummy_never_defined)"
sort confdefs.h | egrep -v "$_EGREP_PATTERN" >> $_CONFIG_TMP
sort confdefs.h | $FIXED_EGREP -v "$_EGREP_PATTERN" >> $_CONFIG_TMP
if test "$?" != 0; then
AC_MSG_ERROR([Error outputting config definitions])
@ -9450,7 +9464,7 @@ EOF
dnl Probably shouldn't call this manually but we always want the output of DEFS
rm -f confdefs.h.save
mv confdefs.h confdefs.h.save
egrep -v "$_EGREP_PATTERN" confdefs.h.save > confdefs.h
$FIXED_EGREP -v "$_EGREP_PATTERN" confdefs.h.save > confdefs.h
if test "$?" != 0; then
AC_MSG_ERROR([Error outputting confdefs.h])
fi

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

@ -1855,7 +1855,8 @@ private:
#ifdef DEBUG
static PRUint32 sDOMNodeRemovedSuppressCount;
#endif
static nsCOMArray<nsIRunnable>* sBlockedScriptRunners;
// Not an nsCOMArray because removing elements from those is slower
static nsTArray< nsCOMPtr<nsIRunnable> >* sBlockedScriptRunners;
static PRUint32 sRunnersCountAtFirstBlocker;
static PRUint32 sScriptBlockerCountWhereRunnersPrevented;

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

@ -43,6 +43,13 @@ interface nsIDOMEventListener;
interface nsIPrincipal;
interface nsIScriptContext;
interface nsPIDOMWindow;
interface nsIDOMDOMStringList;
%{C++
#include "nsTArray.h"
class nsString;
%}
[ref] native nsStringTArrayRef(nsTArray<nsString>);
/**
* The nsIMozWebSocket interface enables Web applications to maintain
@ -51,10 +58,11 @@ interface nsPIDOMWindow;
* http://dev.w3.org/html5/websockets/
*
*/
[scriptable, uuid(662691db-2b99-4461-801b-fbb72d99a4b9)]
[scriptable, uuid(5b124f54-7d46-4bc0-8507-e58ed22c19b9)]
interface nsIMozWebSocket : nsISupports
{
readonly attribute DOMString url;
readonly attribute DOMString extensions;
readonly attribute DOMString protocol;
//ready state
@ -85,7 +93,8 @@ interface nsIMozWebSocket : nsISupports
* Closes the Web Socket connection or connection attempt, if any.
* If the connection is already closed, it does nothing.
*/
void close();
[optional_argc] void close([optional] in unsigned short code,
[optional] in DOMString reason);
/**
* Initialize the object for use from C++ code with the principal, script
@ -98,13 +107,16 @@ interface nsIMozWebSocket : nsISupports
* @param ownerWindow The associated window for the request. May be null.
* @param url The url for opening the socket. This must not be empty, and
* must have an absolute url, using either the ws or wss schemes.
* @param protocol Specifies a sub-protocol that the server must support for
* the connection to be successful. If empty, no protocol is
* specified.
* @param protocol Specifies array of sub-protocols acceptable to the client.
* If the length of the array is at least one, the server
* must select one of the listed sub-protocols for the
* connection to be successful. If empty, no sub-protocol is
* specified. The server selected sub-protocol can be read
* from the protocol attribute after connection.
*/
[noscript] void init(in nsIPrincipal principal,
in nsIScriptContext scriptContext,
in nsPIDOMWindow ownerWindow,
in DOMString url,
in DOMString protocol);
in nsStringTArrayRef protocol);
};

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

@ -249,7 +249,7 @@ PRUint32 nsContentUtils::sScriptBlockerCount = 0;
#ifdef DEBUG
PRUint32 nsContentUtils::sDOMNodeRemovedSuppressCount = 0;
#endif
nsCOMArray<nsIRunnable>* nsContentUtils::sBlockedScriptRunners = nsnull;
nsTArray< nsCOMPtr<nsIRunnable> >* nsContentUtils::sBlockedScriptRunners = nsnull;
PRUint32 nsContentUtils::sRunnersCountAtFirstBlocker = 0;
PRUint32 nsContentUtils::sScriptBlockerCountWhereRunnersPrevented = 0;
nsIInterfaceRequestor* nsContentUtils::sSameOriginChecker = nsnull;
@ -382,8 +382,7 @@ nsContentUtils::Init()
}
}
sBlockedScriptRunners = new nsCOMArray<nsIRunnable>;
NS_ENSURE_TRUE(sBlockedScriptRunners, NS_ERROR_OUT_OF_MEMORY);
sBlockedScriptRunners = new nsTArray< nsCOMPtr<nsIRunnable> >;
Preferences::AddBoolVarCache(&sAllowXULXBL_for_file,
"dom.allow_XUL_XBL_for_file");
@ -1227,7 +1226,7 @@ nsContentUtils::Shutdown()
}
NS_ASSERTION(!sBlockedScriptRunners ||
sBlockedScriptRunners->Count() == 0,
sBlockedScriptRunners->Length() == 0,
"How'd this happen?");
delete sBlockedScriptRunners;
sBlockedScriptRunners = nsnull;
@ -3877,7 +3876,6 @@ nsContentUtils::SetNodeTextContent(nsIContent* aContent,
if (aTryReuse && !aValue.IsEmpty()) {
PRUint32 removeIndex = 0;
// i is unsigned, so i >= is always true
for (PRUint32 i = 0; i < childCount; ++i) {
nsIContent* child = aContent->GetChildAt(removeIndex);
if (removeIndex == 0 && child && child->IsNodeOfType(nsINode::eTEXT)) {
@ -3896,9 +3894,8 @@ nsContentUtils::SetNodeTextContent(nsIContent* aContent,
}
}
else {
// i is unsigned, so i >= is always true
for (PRUint32 i = childCount; i-- != 0; ) {
aContent->RemoveChildAt(i, PR_TRUE);
for (PRUint32 i = 0; i < childCount; ++i) {
aContent->RemoveChildAt(0, PR_TRUE);
}
}
@ -4496,7 +4493,7 @@ nsContentUtils::AddScriptBlocker()
if (!sScriptBlockerCount) {
NS_ASSERTION(sRunnersCountAtFirstBlocker == 0,
"Should not already have a count");
sRunnersCountAtFirstBlocker = sBlockedScriptRunners->Count();
sRunnersCountAtFirstBlocker = sBlockedScriptRunners->Length();
}
++sScriptBlockerCount;
}
@ -4525,7 +4522,7 @@ nsContentUtils::RemoveScriptBlocker()
}
PRUint32 firstBlocker = sRunnersCountAtFirstBlocker;
PRUint32 lastBlocker = (PRUint32)sBlockedScriptRunners->Count();
PRUint32 lastBlocker = sBlockedScriptRunners->Length();
PRUint32 originalFirstBlocker = firstBlocker;
PRUint32 blockersCount = lastBlocker - firstBlocker;
sRunnersCountAtFirstBlocker = 0;
@ -4541,7 +4538,7 @@ nsContentUtils::RemoveScriptBlocker()
"Bad count");
NS_ASSERTION(!sScriptBlockerCount, "This is really bad");
}
sBlockedScriptRunners->RemoveObjectsAt(originalFirstBlocker, blockersCount);
sBlockedScriptRunners->RemoveElementsAt(originalFirstBlocker, blockersCount);
}
/* static */
@ -4557,7 +4554,7 @@ nsContentUtils::AddScriptRunner(nsIRunnable* aRunnable)
NS_ERROR("Adding a script runner when that is prevented!");
return PR_FALSE;
}
return sBlockedScriptRunners->AppendObject(aRunnable);
return sBlockedScriptRunners->AppendElement(aRunnable) != nsnull;
}
nsCOMPtr<nsIRunnable> run = aRunnable;

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

@ -77,6 +77,7 @@
#include "nsILoadGroup.h"
#include "nsIRequest.h"
#include "mozilla/Preferences.h"
#include "nsDOMLists.h"
using namespace mozilla;
@ -295,14 +296,19 @@ nsWebSocketEstablishedConnection::Init(nsWebSocket *aOwner)
NS_ENSURE_SUCCESS(rv, rv);
}
if (!mOwner->mProtocol.IsEmpty())
rv = mWebSocketChannel->SetProtocol(mOwner->mProtocol);
if (!mOwner->mRequestedProtocolList.IsEmpty()) {
rv = mWebSocketChannel->SetProtocol(mOwner->mRequestedProtocolList);
NS_ENSURE_SUCCESS(rv, rv);
}
nsCString asciiOrigin;
rv = nsContentUtils::GetASCIIOrigin(mOwner->mPrincipal, asciiOrigin);
NS_ENSURE_SUCCESS(rv, rv);
nsCString utf8Origin;
CopyUTF16toUTF8(mOwner->mUTF16Origin, utf8Origin);
ToLowerCase(asciiOrigin);
rv = mWebSocketChannel->AsyncOpen(mOwner->mURI,
utf8Origin, this, nsnull);
asciiOrigin, this, nsnull);
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
@ -388,7 +394,8 @@ nsWebSocketEstablishedConnection::Close()
return NS_OK;
}
return mWebSocketChannel->Close();
return mWebSocketChannel->Close(mOwner->mClientReasonCode,
mOwner->mClientReason);
}
nsresult
@ -503,8 +510,10 @@ nsWebSocketEstablishedConnection::OnStart(nsISupports *aContext)
if (!mOwner)
return NS_OK;
if (!mOwner->mProtocol.IsEmpty())
mWebSocketChannel->GetProtocol(mOwner->mProtocol);
if (!mOwner->mRequestedProtocolList.IsEmpty())
mWebSocketChannel->GetProtocol(mOwner->mEstablishedProtocol);
mWebSocketChannel->GetExtensions(mOwner->mEstablishedExtensions);
mStatus = CONN_CONNECTED_AND_READY;
mOwner->SetReadyState(nsIMozWebSocket::OPEN);
@ -529,7 +538,7 @@ nsWebSocketEstablishedConnection::OnStop(nsISupports *aContext,
if (NS_FAILED(aStatusCode)) {
ConsoleError();
if (mOwner && mOwner->mReadyState != nsIMozWebSocket::CONNECTING) {
if (mOwner) {
nsresult rv =
mOwner->CreateAndDispatchSimpleEvent(NS_LITERAL_STRING("error"));
if (NS_FAILED(rv))
@ -559,9 +568,15 @@ nsWebSocketEstablishedConnection::OnAcknowledge(nsISupports *aContext,
}
NS_IMETHODIMP
nsWebSocketEstablishedConnection::OnServerClose(nsISupports *aContext)
nsWebSocketEstablishedConnection::OnServerClose(nsISupports *aContext,
PRUint16 aCode,
const nsACString &aReason)
{
NS_ABORT_IF_FALSE(NS_IsMainThread(), "Not running on main thread");
if (mOwner) {
mOwner->mServerReasonCode = aCode;
CopyUTF8toUTF16(aReason, mOwner->mServerReason);
}
Close(); /* reciprocate! */
return NS_OK;
@ -609,6 +624,8 @@ nsWebSocketEstablishedConnection::GetInterface(const nsIID &aIID,
nsWebSocket::nsWebSocket() : mKeepingAlive(PR_FALSE),
mCheckMustKeepAlive(PR_TRUE),
mTriggeredCloseEvent(PR_FALSE),
mClientReasonCode(0),
mServerReasonCode(nsIWebSocketChannel::CLOSE_ABNORMAL),
mReadyState(nsIMozWebSocket::CONNECTING),
mOutgoingBufferedAmount(0),
mScriptLine(0),
@ -676,8 +693,9 @@ NS_IMPL_RELEASE_INHERITED(nsWebSocket, nsDOMEventTargetWrapperCache)
/**
* This Initialize method is called from XPConnect via nsIJSNativeInitializer.
* It is used for constructing our nsWebSocket from JavaScript. It expects a URL
* string parameter and an optional protocol parameter. It also initializes the
* principal, the script context and the window owner.
* string parameter and an optional protocol parameter which may be a string or
* an array of strings. It also initializes the principal, the script context and
* the window owner.
*/
NS_IMETHODIMP
nsWebSocket::Initialize(nsISupports* aOwner,
@ -687,7 +705,7 @@ nsWebSocket::Initialize(nsISupports* aOwner,
jsval* aArgv)
{
NS_ABORT_IF_FALSE(NS_IsMainThread(), "Not running on main thread");
nsAutoString urlParam, protocolParam;
nsAutoString urlParam;
if (!PrefEnabled()) {
return NS_ERROR_DOM_SECURITY_ERR;
@ -714,24 +732,6 @@ nsWebSocket::Initialize(nsISupports* aOwner,
urlParam.Assign(chars, length);
deleteProtector.clear();
if (aArgc == 2) {
jsstr = JS_ValueToString(aContext, aArgv[1]);
if (!jsstr) {
return NS_ERROR_DOM_SYNTAX_ERR;
}
deleteProtector.set(jsstr);
chars = JS_GetStringCharsAndLength(aContext, jsstr, &length);
if (!chars) {
return NS_ERROR_OUT_OF_MEMORY;
}
protocolParam.Assign(chars, length);
if (protocolParam.IsEmpty()) {
return NS_ERROR_DOM_SYNTAX_ERR;
}
}
nsCOMPtr<nsPIDOMWindow> ownerWindow = do_QueryInterface(aOwner);
NS_ENSURE_STATE(ownerWindow);
@ -745,7 +745,62 @@ nsWebSocket::Initialize(nsISupports* aOwner,
nsCOMPtr<nsIPrincipal> principal = scriptPrincipal->GetPrincipal();
NS_ENSURE_STATE(principal);
return Init(principal, scriptContext, ownerWindow, urlParam, protocolParam);
nsTArray<nsString> protocolArray;
if (aArgc == 2) {
JSObject *jsobj;
if (JSVAL_IS_OBJECT(aArgv[1]) &&
(jsobj = JSVAL_TO_OBJECT(aArgv[1])) &&
JS_IsArrayObject(aContext, jsobj)) {
jsuint len;
JS_GetArrayLength(aContext, jsobj, &len);
for (PRUint32 index = 0; index < len; ++index) {
jsval value;
if (!JS_GetElement(aContext, jsobj, index, &value))
return NS_ERROR_DOM_SYNTAX_ERR;
jsstr = JS_ValueToString(aContext, value);
if (!jsstr)
return NS_ERROR_DOM_SYNTAX_ERR;
deleteProtector.set(jsstr);
chars = JS_GetStringCharsAndLength(aContext, jsstr, &length);
if (!chars)
return NS_ERROR_OUT_OF_MEMORY;
nsDependentString protocolElement(chars, length);
if (protocolElement.IsEmpty())
return NS_ERROR_DOM_SYNTAX_ERR;
if (protocolArray.Contains(protocolElement))
return NS_ERROR_DOM_SYNTAX_ERR;
if (protocolElement.FindChar(',') != -1) /* interferes w/list */
return NS_ERROR_DOM_SYNTAX_ERR;
protocolArray.AppendElement(protocolElement);
deleteProtector.clear();
}
} else {
jsstr = JS_ValueToString(aContext, aArgv[1]);
if (!jsstr)
return NS_ERROR_DOM_SYNTAX_ERR;
deleteProtector.set(jsstr);
chars = JS_GetStringCharsAndLength(aContext, jsstr, &length);
if (!chars)
return NS_ERROR_OUT_OF_MEMORY;
nsDependentString protocolElement(chars, length);
if (protocolElement.IsEmpty())
return NS_ERROR_DOM_SYNTAX_ERR;
if (protocolElement.FindChar(',') != -1) /* interferes w/list */
return NS_ERROR_DOM_SYNTAX_ERR;
protocolArray.AppendElement(protocolElement);
}
}
return Init(principal, scriptContext, ownerWindow, urlParam, protocolArray);
}
//-----------------------------------------------------------------------------
@ -766,7 +821,7 @@ nsWebSocket::EstablishConnection()
rv = conn->Init(this);
mConnection = conn;
if (NS_FAILED(rv)) {
Close();
Close(0, EmptyString(), 0);
mConnection = nsnull;
return rv;
}
@ -777,14 +832,18 @@ nsWebSocket::EstablishConnection()
class nsWSCloseEvent : public nsRunnable
{
public:
nsWSCloseEvent(nsWebSocket *aWebSocket, PRBool aWasClean)
nsWSCloseEvent(nsWebSocket *aWebSocket, PRBool aWasClean,
PRUint16 aCode, const nsString &aReason)
: mWebSocket(aWebSocket),
mWasClean(aWasClean)
mWasClean(aWasClean),
mCode(aCode),
mReason(aReason)
{}
NS_IMETHOD Run()
{
nsresult rv = mWebSocket->CreateAndDispatchCloseEvent(mWasClean);
nsresult rv = mWebSocket->CreateAndDispatchCloseEvent(mWasClean,
mCode, mReason);
mWebSocket->UpdateMustKeepAlive();
return rv;
}
@ -792,6 +851,8 @@ public:
private:
nsRefPtr<nsWebSocket> mWebSocket;
PRBool mWasClean;
PRUint16 mCode;
nsString mReason;
};
nsresult
@ -879,7 +940,9 @@ nsWebSocket::CreateAndDispatchMessageEvent(const nsACString& aData)
}
nsresult
nsWebSocket::CreateAndDispatchCloseEvent(PRBool aWasClean)
nsWebSocket::CreateAndDispatchCloseEvent(PRBool aWasClean,
PRUint16 aCode,
const nsString &aReason)
{
NS_ABORT_IF_FALSE(NS_IsMainThread(), "Not running on main thread");
nsresult rv;
@ -901,7 +964,7 @@ nsWebSocket::CreateAndDispatchCloseEvent(PRBool aWasClean)
nsCOMPtr<nsIDOMCloseEvent> closeEvent = do_QueryInterface(event);
rv = closeEvent->InitCloseEvent(NS_LITERAL_STRING("close"),
PR_FALSE, PR_FALSE,
aWasClean);
aWasClean, aCode, aReason);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIPrivateDOMEvent> privateEvent = do_QueryInterface(event);
@ -959,7 +1022,10 @@ nsWebSocket::SetReadyState(PRUint16 aNewReadyState)
if (mConnection) {
// The close event must be dispatched asynchronously.
nsCOMPtr<nsIRunnable> event =
new nsWSCloseEvent(this, mConnection->ClosedCleanly());
new nsWSCloseEvent(this,
mConnection->ClosedCleanly(),
mServerReasonCode,
mServerReason);
mOutgoingBufferedAmount += mConnection->GetOutgoingBufferedAmount();
mConnection = nsnull; // this is no longer necessary
@ -1019,10 +1085,6 @@ nsWebSocket::ParseURL(const nsString& aURL)
rv = parsedURL->GetQuery(query);
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_SYNTAX_ERR);
nsCString origin;
rv = nsContentUtils::GetASCIIOrigin(mPrincipal, origin);
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_SYNTAX_ERR);
if (scheme.LowerCaseEqualsLiteral("ws")) {
mSecure = PR_FALSE;
mPort = (port == -1) ? DEFAULT_WS_SCHEME_PORT : port;
@ -1033,9 +1095,9 @@ nsWebSocket::ParseURL(const nsString& aURL)
return NS_ERROR_DOM_SYNTAX_ERR;
}
ToLowerCase(origin);
CopyUTF8toUTF16(origin, mUTF16Origin);
rv = nsContentUtils::GetUTFOrigin(parsedURL, mUTF16Origin);
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_SYNTAX_ERR);
mAsciiHost = host;
ToLowerCase(mAsciiHost);
@ -1058,26 +1120,6 @@ nsWebSocket::ParseURL(const nsString& aURL)
return NS_OK;
}
nsresult
nsWebSocket::SetProtocol(const nsString& aProtocol)
{
if (aProtocol.IsEmpty()) {
return NS_ERROR_DOM_SYNTAX_ERR;
}
PRUint32 length = aProtocol.Length();
PRUint32 i;
for (i = 0; i < length; ++i) {
if (aProtocol[i] < static_cast<PRUnichar>(0x0021) ||
aProtocol[i] > static_cast<PRUnichar>(0x007E)) {
return NS_ERROR_DOM_SYNTAX_ERR;
}
}
CopyUTF16toUTF8(aProtocol, mProtocol);
return NS_OK;
}
//-----------------------------------------------------------------------------
// Methods that keep alive the WebSocket object when:
// 1. the object has registered event listeners that can be triggered
@ -1193,10 +1235,17 @@ nsWebSocket::GetUrl(nsAString& aURL)
return NS_OK;
}
NS_IMETHODIMP
nsWebSocket::GetExtensions(nsAString& aExtensions)
{
CopyUTF8toUTF16(mEstablishedExtensions, aExtensions);
return NS_OK;
}
NS_IMETHODIMP
nsWebSocket::GetProtocol(nsAString& aProtocol)
{
CopyUTF8toUTF16(mProtocol, aProtocol);
CopyUTF8toUTF16(mEstablishedProtocol, aProtocol);
return NS_OK;
}
@ -1237,6 +1286,26 @@ NS_WEBSOCKET_IMPL_DOMEVENTLISTENER(error, mOnErrorListener)
NS_WEBSOCKET_IMPL_DOMEVENTLISTENER(message, mOnMessageListener)
NS_WEBSOCKET_IMPL_DOMEVENTLISTENER(close, mOnCloseListener)
static PRBool
ContainsUnpairedSurrogates(const nsAString& aData)
{
// Check for unpaired surrogates.
PRUint32 i, length = aData.Length();
for (i = 0; i < length; ++i) {
if (NS_IS_LOW_SURROGATE(aData[i])) {
return PR_TRUE;
}
if (NS_IS_HIGH_SURROGATE(aData[i])) {
++i;
if (i == length || !NS_IS_LOW_SURROGATE(aData[i])) {
return PR_TRUE;
}
continue;
}
}
return PR_FALSE;
}
NS_IMETHODIMP
nsWebSocket::Send(const nsAString& aData)
{
@ -1246,20 +1315,8 @@ nsWebSocket::Send(const nsAString& aData)
return NS_ERROR_DOM_INVALID_STATE_ERR;
}
// Check for unpaired surrogates.
PRUint32 i, length = aData.Length();
for (i = 0; i < length; ++i) {
if (NS_IS_LOW_SURROGATE(aData[i])) {
return NS_ERROR_DOM_SYNTAX_ERR;
}
if (NS_IS_HIGH_SURROGATE(aData[i])) {
if (i + 1 == length || !NS_IS_LOW_SURROGATE(aData[i + 1])) {
return NS_ERROR_DOM_SYNTAX_ERR;
}
++i;
continue;
}
}
if (ContainsUnpairedSurrogates(aData))
return NS_ERROR_DOM_SYNTAX_ERR;
if (mReadyState == nsIMozWebSocket::CLOSING ||
mReadyState == nsIMozWebSocket::CLOSED) {
@ -1273,9 +1330,34 @@ nsWebSocket::Send(const nsAString& aData)
}
NS_IMETHODIMP
nsWebSocket::Close()
nsWebSocket::Close(PRUint16 code, const nsAString & reason, PRUint8 argc)
{
NS_ABORT_IF_FALSE(NS_IsMainThread(), "Not running on main thread");
// the reason code is optional, but if provided it must be in a specific range
if (argc >= 1) {
if (code != 1000 && (code < 3000 || code > 4999))
return NS_ERROR_DOM_INVALID_ACCESS_ERR;
}
nsCAutoString utf8Reason;
if (argc >= 2) {
if (ContainsUnpairedSurrogates(reason))
return NS_ERROR_DOM_SYNTAX_ERR;
CopyUTF16toUTF8(reason, utf8Reason);
// The API requires the UTF-8 string to be 123 or less bytes
if (utf8Reason.Length() > 123)
return NS_ERROR_DOM_SYNTAX_ERR;
}
// Format checks for reason and code both passed, they can now be assigned.
if (argc >= 1)
mClientReasonCode = code;
if (argc >= 2)
mClientReason = utf8Reason;
if (mReadyState == nsIMozWebSocket::CLOSING ||
mReadyState == nsIMozWebSocket::CLOSED) {
return NS_OK;
@ -1306,7 +1388,7 @@ nsWebSocket::Init(nsIPrincipal* aPrincipal,
nsIScriptContext* aScriptContext,
nsPIDOMWindow* aOwnerWindow,
const nsAString& aURL,
const nsAString& aProtocol)
nsTArray<nsString> & protocolArray)
{
NS_ABORT_IF_FALSE(NS_IsMainThread(), "Not running on main thread");
nsresult rv;
@ -1364,10 +1446,17 @@ nsWebSocket::Init(nsIPrincipal* aPrincipal,
return NS_ERROR_DOM_SECURITY_ERR;
}
// sets the protocol
if (!aProtocol.IsEmpty()) {
rv = SetProtocol(PromiseFlatString(aProtocol));
NS_ENSURE_SUCCESS(rv, rv);
// Assign the sub protocol list and scan it for illegal values
for (PRUint32 index = 0; index < protocolArray.Length(); ++index) {
for (PRUint32 i = 0; i < protocolArray[index].Length(); ++i) {
if (protocolArray[index][i] < static_cast<PRUnichar>(0x0021) ||
protocolArray[index][i] > static_cast<PRUnichar>(0x007E))
return NS_ERROR_DOM_SYNTAX_ERR;
}
if (!mRequestedProtocolList.IsEmpty())
mRequestedProtocolList.Append(NS_LITERAL_CSTRING(", "));
AppendUTF16toUTF8(protocolArray[index], mRequestedProtocolList);
}
// the constructor should throw a SYNTAX_ERROR only if it fails to parse the

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

@ -50,6 +50,7 @@
#include "nsIDOMEventListener.h"
#include "nsDOMEventTargetWrapperCache.h"
#include "nsAutoPtr.h"
#include "nsIDOMDOMStringList.h"
#define DEFAULT_WS_SCHEME_PORT 80
#define DEFAULT_WSS_SCHEME_PORT 443
@ -104,12 +105,12 @@ public:
protected:
nsresult ParseURL(const nsString& aURL);
nsresult SetProtocol(const nsString& aProtocol);
nsresult EstablishConnection();
nsresult CreateAndDispatchSimpleEvent(const nsString& aName);
nsresult CreateAndDispatchMessageEvent(const nsACString& aData);
nsresult CreateAndDispatchCloseEvent(PRBool aWasClean);
nsresult CreateAndDispatchCloseEvent(PRBool aWasClean, PRUint16 aCode,
const nsString &aReason);
// called from mConnection accordingly to the situation
void SetReadyState(PRUint16 aNewReadyState);
@ -136,13 +137,20 @@ protected:
PRPackedBool mCheckMustKeepAlive;
PRPackedBool mTriggeredCloseEvent;
nsCString mClientReason;
PRUint16 mClientReasonCode;
nsString mServerReason;
PRUint16 mServerReasonCode;
nsCString mAsciiHost; // hostname
PRUint32 mPort;
nsCString mResource; // [filepath[?query]]
nsString mUTF16Origin;
nsCOMPtr<nsIURI> mURI;
nsCString mProtocol;
nsCString mRequestedProtocolList;
nsCString mEstablishedProtocol;
nsCString mEstablishedExtensions;
PRUint16 mReadyState;

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

@ -3,20 +3,24 @@
<script type="text/javascript">
var url1 = "data:text/html;charset=utf-8,1st%20page";
function soon(f) {
return function() { setTimeout(f, 0); };
}
function doe() {
document.body.innerHTML = "<iframe src='about:blank'></iframe>";
document.body.innerHTML += "<iframe src='about:blank'></iframe>";
window.frames[0].frameElement.onload = doe2;
window.frames[0].frameElement.onload = soon(doe2);
window.frames[0].location.replace(url1);
}
function doe2() {
window.frames[0].location = 'data:text/html;charset=utf-8,2nd%20page';
window.frames[0].frameElement.onload = doe3;
window.frames[0].frameElement.onload = soon(doe3);
}
function doe3() {
window.frames[0].frameElement.onload = doe4;
window.frames[0].frameElement.onload = soon(doe4);
history.go(-1);
}

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

@ -5,11 +5,15 @@ var url1 = "data:text/html;charset=utf-8,1st%20page";
var win0 = null;
function soon(f) {
return function() { setTimeout(f, 0); };
}
function doe() {
document.body.innerHTML = "<iframe src='about:blank'></iframe>";
document.body.innerHTML += "<iframe src='about:blank'></iframe>";
win0 = window.frames[0];
win0.frameElement.onload = doe2;
win0.frameElement.onload = soon(doe2);
win0.location.replace(url1);
}
@ -17,24 +21,44 @@ function doe2() {
// Add some iframes/docshells. Session history should still work.
var ifr1 = document.createElement("iframe");
document.body.insertBefore(ifr1, document.body.firstChild);
ifr1.onload = soon(doe3);
var ifr2 = document.createElement("iframe");
document.body.insertBefore(ifr2, document.body.firstChild);
ifr2.onload = soon(doe3);
var ifr3 = document.createElement("iframe");
document.body.insertBefore(ifr3, document.body.firstChild);
win0.frameElement.onload = doe3;
ifr3.onload = soon(doe3);
}
var doe3_count = 0;
function doe3() {
// Wait until all three iframes have loaded about:blank before navigating
// win0.
doe3_count++;
if (doe3_count < 3) {
return;
}
if (doe3_count > 3) {
ok(false, 'Unexpected ' + doe3_count + 'th call to doe3.');
return;
}
win0.frameElement.onload = soon(doe4);
win0.location = 'data:text/html;charset=utf-8,2nd%20page';
}
function doe3() {
win0.frameElement.onload = doe4;
function doe4() {
win0.frameElement.onload = soon(doe5);
history.go(-1);
}
function doe4() {
function doe5() {
opener.is(win0.location, url1, "History.go(-1) didn't work?");
close();
}
</script>
</head>
<body onload="doe();" onunload="opener.nextTest();">
<body onload="setTimeout(doe, 0);" onunload="opener.nextTest();">
</body></html>

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

@ -7,24 +7,28 @@ import sys
def web_socket_do_extra_handshake(request):
# must set request.ws_protocol to the selected version from ws_requested_protocols
request.ws_protocol = request.ws_requested_protocols[0]
for x in request.ws_requested_protocols:
if x != "test-does-not-exist":
request.ws_protocol = x
break
if request.ws_protocol == "test-2.1":
time.sleep(5)
time.sleep(3)
pass
elif request.ws_protocol == "test-9":
time.sleep(5)
time.sleep(3)
pass
elif request.ws_protocol == "test-10":
time.sleep(5)
time.sleep(3)
pass
elif request.ws_protocol == "test-19":
raise ValueError('Aborting (test-19)')
elif request.ws_protocol == "test-20" or request.ws_protocol == "test-17":
time.sleep(10)
time.sleep(3)
pass
elif request.ws_protocol == "test-22":
time.sleep(60)
# The timeout is 5 seconds
time.sleep(13)
pass
else:
pass
@ -47,18 +51,7 @@ def web_socket_transfer_data(request):
msgutil.send_message(request, resp.decode('utf-8'))
msgutil.close_connection(request)
elif request.ws_protocol == "test-7":
try:
while not request.client_terminated:
msgutil.receive_message(request)
except msgutil.ConnectionTerminatedException, e:
pass
msgutil.send_message(request, "server data")
msgutil.send_message(request, "server data")
msgutil.send_message(request, "server data")
msgutil.send_message(request, "server data")
msgutil.send_message(request, "server data")
time.sleep(30)
msgutil.close_connection(request, True)
msgutil.send_message(request, "test-7 data")
elif request.ws_protocol == "test-10":
msgutil.close_connection(request)
elif request.ws_protocol == "test-11":
@ -82,16 +75,35 @@ def web_socket_transfer_data(request):
msgutil.close_connection(request, True)
return
elif request.ws_protocol == "test-17" or request.ws_protocol == "test-21":
time.sleep(5)
time.sleep(2)
resp = "wrong message"
if msgutil.receive_message(request) == "client data":
resp = "server data"
msgutil.send_message(request, resp.decode('utf-8'))
time.sleep(5)
time.sleep(2)
msgutil.close_connection(request)
time.sleep(5)
elif request.ws_protocol == "test-20":
msgutil.send_message(request, "server data")
msgutil.close_connection(request)
elif request.ws_protocol == "test-34":
request.ws_stream.close_connection(1001, "going away now")
elif request.ws_protocol == "test-35a":
while not request.client_terminated:
msgutil.receive_message(request)
global test35code
test35code = request.ws_close_code
global test35reason
test35reason = request.ws_close_reason
elif request.ws_protocol == "test-35b":
request.ws_stream.close_connection(test35code + 1, test35reason)
elif request.ws_protocol == "test-37b":
while not request.client_terminated:
msgutil.receive_message(request)
global test37code
test37code = request.ws_close_code
global test37reason
test37reason = request.ws_close_reason
elif request.ws_protocol == "test-37c":
request.ws_stream.close_connection(test37code, test37reason)
while not request.client_terminated:
msgutil.receive_message(request)

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

@ -23,8 +23,7 @@
* 4. client tries to connect using a relative url;
* 5. client uses an invalid protocol value;
* 6. counter and encoding check;
* 7. client calls close() and the server keeps sending messages and it doesn't
* send the close frame;
* 7. onmessage event origin property check
* 8. client calls close() and the server sends the close frame in
* acknowledgement;
* 9. client closes the connection before the ws connection is established;
@ -45,14 +44,32 @@
* 22. server takes too long to establish the ws connection;
* 23. see bug 664692 - feature detection should detect MozWebSocket but not
* WebSocket on window object;
* 24. server rejects sub-protocol string
* 25. ctor with valid empty sub-protocol array
* 26. ctor with invalid sub-protocol array containing 1 empty element
* 27. ctor with invalid sub-protocol array containing an empty element in list
* 28. ctor using valid 1 element sub-protocol array
* 29. ctor using all valid 5 element sub-protocol array
* 30. ctor using valid 1 element sub-protocol array with element server will
* reject
* 31. ctor using valid 2 element sub-protocol array with 1 element server
* will reject and one server will accept.
* 32. ctor using invalid sub-protocol array that contains duplicate items
* 33. default close code test
* 34. test for receiving custom close code and reason
* 35. test for sending custom close code and reason
* 36. negative test for sending out of range close code
* 37. negative test for too long of a close reason
* 38. ensure extensions attribute is defined
* 39. a basic wss:// connectivity test
* 40. negative test for wss:// with no cert
*/
var first_test = 1;
var last_test = 23;
var last_test = 40;
var current_test = first_test;
var timeoutToAbortTest = 60000;
var all_ws = [];
function shouldNotOpen(e)
@ -93,6 +110,10 @@ function shouldCloseNotCleanly(e)
ok(!e.wasClean, "the ws connection in test " + ws._testNumber + " shouldn't be closed cleanly");
}
function ignoreError(e)
{
}
function CreateTestWS(ws_location, ws_protocol)
{
var ws;
@ -141,13 +162,9 @@ function forcegc()
function doTest(number)
{
if (doTest.timeoutId !== null) {
clearTimeout(doTest.timeoutId);
doTest.timeoutId = null;
}
if (number > last_test) {
setTimeout(finishWSTest, 30000); // wait for the close events be dispatched
ranAllTests = true;
maybeFinished();
return;
}
@ -160,12 +177,6 @@ function doTest(number)
return;
}
doTest.timeoutId = setTimeout(function()
{
ok(false, "test " + number + " took too long to finish!");
doTest(number + 1);
}, timeoutToAbortTest);
fnTest._started = true;
fnTest();
}
@ -184,36 +195,67 @@ function test1()
}
// this test expects that the serialization list to connect to the proxy
// is empty
// is empty. Use different domain so we can run this in the background
// and not delay other tests.
var waitTest2Part1 = false;
var waitTest2Part2 = false;
function test2()
{
var ws1 = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", "test-2.1");
waitTest2Part1 = true;
waitTest2Part2 = true;
var ws1 = CreateTestWS("ws://sub2.test2.example.com/tests/content/base/test/file_websocket", "test-2.1");
current_test--; // CreateTestWS incremented this
var ws2 = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", "test-2.2");
var ws2 = CreateTestWS("ws://sub2.test2.example.com/tests/content/base/test/file_websocket", "test-2.2");
var ws2CanConnect = false;
// the server will delay ws1 for 5 seconds
// the server will delay ws1 for 5 seconds, but the other tests can
// proceed in parallel
doTest(3);
ws1.onopen = function()
{
ok(true, "ws1 open in test 2");
ws2CanConnect = true;
ws1.close();
}
ws1.onclose = function(e)
{
waitTest2Part1 = false;
maybeFinished();
};
ws2.onopen = function()
{
ok(ws2CanConnect, "shouldn't connect yet in test-2!");
doTest(3);
ws2.close();
}
ws2.onclose = function(e)
{
waitTest2Part2 = false;
maybeFinished();
};
}
function test3()
{
var hasError = false;
var ws = CreateTestWS("ws://this.websocket.server.probably.does.not.exist");
ws.onopen = shouldNotOpen;
ws.onerror = function (e)
{
hasError = true;
}
ws.onclose = function(e)
{
shouldCloseNotCleanly(e);
ok(hasError, "rcvd onerror event");
doTest(4);
};
}
@ -283,25 +325,26 @@ function test6()
function test7()
{
// with pywebsockets for -06 ths test no longer does anything useful
// as the server handles the receipt of the close event directly, not
// as part of the wsh - so we cannot fake the non-clean close which is
// what we're trying to do here.
var ws = CreateTestWS("ws://sub2.test2.example.org/tests/content/base/test/file_websocket", "test-7");
var gotmsg = false;
ok(true, "test disabled");
current_test++;
doTest(8);
// var ws = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", "test-7");
// ws.onopen = function()
// {
// ws.close();
// }
// ws.onclose = function(e)
// {
// shouldCloseNotCleanly(e);
// doTest(8);
// };
ws.onopen = function()
{
ok(true, "test 7 open");
}
ws.onmessage = function(e)
{
ok(true, "test 7 message");
ok(e.origin == "ws://sub2.test2.example.org", "onmessage origin set to ws:// host");
gotmsg = true;
ws.close();
}
ws.onclose = function(e)
{
ok(gotmsg, "recvd message in test 7 before close");
shouldCloseCleanly(e);
doTest(8);
};
}
function test8()
@ -309,6 +352,7 @@ function test8()
var ws = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", "test-8");
ws.onopen = function()
{
ok(ws.protocol == "test-8", "test-8 subprotocol selection");
ws.close();
}
ws.onclose = function(e)
@ -318,23 +362,40 @@ function test8()
};
}
var waitTest9 = false;
function test9()
{
var ws = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", "test-9");
waitTest9 = true;
var ws = CreateTestWS("ws://test2.example.org/tests/content/base/test/file_websocket", "test-9");
ws.onopen = shouldNotOpen;
ws.onclose = function(e)
{
shouldCloseNotCleanly(e);
doTest(10);
waitTest9 = false;
maybeFinished();
};
ws.close();
// the server injects a delay, so proceed with this in the background
doTest(10);
}
var waitTest10 = false;
function test10()
{
var ws = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", "test-10");
ws.onclose = shouldCloseCleanly;
waitTest10 = true;
var ws = CreateTestWS("ws://sub1.test1.example.com/tests/content/base/test/file_websocket", "test-10");
ws.onclose = function(e)
{
shouldCloseCleanly(e);
waitTest10 = false;
maybeFinished();
}
try {
ws.send("client data");
@ -345,8 +406,12 @@ function test10()
}
ws.onopen = function()
{
doTest(11);
ok(true, "test 10 opened");
ws.close();
}
// proceed with this test in the background
doTest(11);
}
function test11()
@ -377,6 +442,8 @@ function test11()
function test12()
{
ok(true,"test 12");
var ws = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", "test-12");
ws.onopen = function()
{
@ -473,9 +540,13 @@ function test16()
var status_test17 = "not started";
var waitTest17 = false;
window._test17 = function()
{
var local_ws = new MozWebSocket("ws://mochi.test:8888/tests/content/base/test/file_websocket", "test-17");
waitTest17 = true;
var local_ws = new MozWebSocket("ws://sub1.test2.example.org/tests/content/base/test/file_websocket", "test-17");
local_ws._testNumber = "local17";
local_ws._testNumber = current_test++;
@ -506,13 +577,17 @@ window._test17 = function()
shouldCloseCleanly(e);
status_test17 = "closed";
forcegc();
doTest(18);
forcegc();
waitTest17 = false;
maybeFinished();
};
local_ws = null;
window._test17 = null;
forcegc();
// do this in the background
doTest(18);
forcegc();
}
function test17()
@ -528,6 +603,7 @@ function test18()
{
var ws = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket_http_resource.txt");
ws.onopen = shouldNotOpen;
ws.onerror = ignoreError;
ws.onclose = function(e)
{
shouldCloseNotCleanly(e);
@ -539,6 +615,7 @@ function test19()
{
var ws = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", "test-19");
ws.onopen = shouldNotOpen;
ws.onerror = ignoreError;
ws.onclose = function(e)
{
shouldCloseNotCleanly(e);
@ -546,9 +623,13 @@ function test19()
};
}
var waitTest20 = false;
window._test20 = function()
{
var local_ws = new MozWebSocket("ws://mochi.test:8888/tests/content/base/test/file_websocket", "test-20");
waitTest20 = true;
var local_ws = new MozWebSocket("ws://sub1.test1.example.org/tests/content/base/test/file_websocket", "test-20");
local_ws._testNumber = "local20";
local_ws._testNumber = current_test++;
@ -559,13 +640,17 @@ window._test20 = function()
local_ws.onclose = function(e)
{
shouldCloseCleanly(e);
doTest(21);
ok(true, "test 20 closed despite gc");
waitTest20 = false;
maybeFinished();
};
local_ws = null;
window._test20 = null;
forcegc();
// let test run in the background
doTest(21);
}
function test20()
@ -573,20 +658,19 @@ function test20()
window._test20();
}
var timeoutTest21;
var waitTest21 = false;
window._test21 = function()
{
waitTest21 = true;
var local_ws = new MozWebSocket("ws://mochi.test:8888/tests/content/base/test/file_websocket", "test-21");
local_ws._testNumber = current_test++;
var received_message = false;
local_ws.onopen = function(e)
{
e.target.send("client data");
timeoutTest21 = setTimeout(function()
{
ok(false, "Didn't received message on test-21!");
}, 15000);
forcegc();
e.target.onopen = null;
forcegc();
@ -599,8 +683,8 @@ window._test21 = function()
local_ws.onmessage = function(e)
{
clearTimeout(timeoutTest21);
ok(e.data == "server data", "Bad message in test-21");
received_message = true;
forcegc();
e.target.onmessage = null;
forcegc();
@ -609,12 +693,17 @@ window._test21 = function()
local_ws.onclose = function(e)
{
shouldCloseCleanly(e);
doTest(22);
ok(received_message, "close transitioned through onmessage");
waitTest21 = false;
maybeFinished();
};
local_ws = null;
window._test21 = null;
forcegc();
doTest(22);
}
function test21()
@ -622,32 +711,437 @@ function test21()
window._test21();
}
var waitTest22 = false;
function test22()
{
var ws = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", "test-22");
waitTest22 = true;
const pref_open = "network.websocket.timeout.open";
var oldpref_open_value = 20;
oldpref_open_value = SpecialPowers.getIntPref(pref_open);
SpecialPowers.setIntPref(pref_open, 5);
var ws = CreateTestWS("ws://sub2.test2.example.org/tests/content/base/test/file_websocket", "test-22");
ws.onopen = shouldNotOpen;
ws.onerror = ignoreError;
ws.onclose = function(e)
{
shouldCloseNotCleanly(e);
doTest(23);
waitTest22 = false;
maybeFinished();
};
SpecialPowers.setIntPref(pref_open, oldpref_open_value);
doTest(23);
}
function test23()
{
current_test++;
is(false, "WebSocket" in window, "WebSocket shouldn't be available on window object");
is(true, "MozWebSocket" in window, "MozWebSocket should be available on window object");
doTest(24);
}
function finishWSTest()
function test24()
{
var ws = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", "test-does-not-exist");
ws.onopen = shouldNotOpen;
ws.onclose = function(e)
{
shouldCloseNotCleanly(e);
doTest(25);
};
ws.onerror = function()
{
}
}
function test25()
{
var prots=[];
var ws = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", prots);
// This test errors because the server requires a sub-protocol, but
// the test just wants to ensure that the ctor doesn't generate an
// exception
ws.onerror = ignoreError;
ws.onopen = shouldNotOpen;
ws.onclose = function(e)
{
ok(ws.protocol == "", "test25 subprotocol selection");
ok(true, "test 25 protocol array close");
doTest(26);
};
}
function test26()
{
var prots=[""];
try {
var ws = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", prots);
ok(false, "testing empty element sub protocol array");
}
catch (e) {
ok(true, "testing empty sub element protocol array");
}
doTest(27);
}
function test27()
{
var prots=["test27", ""];
try {
var ws = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", prots);
ok(false, "testing empty element mixed sub protocol array");
}
catch (e) {
ok(true, "testing empty element mixed sub protocol array");
}
doTest(28);
}
function test28()
{
var prots=["test28"];
var ws = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", prots);
ws.onopen = function(e)
{
ok(true, "test 28 protocol array open");
ws.close();
};
ws.onclose = function(e)
{
ok(ws.protocol == "test28", "test28 subprotocol selection");
ok(true, "test 28 protocol array close");
doTest(29);
};
}
function test29()
{
var prots=["test29a", "test29b"];
var ws = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", prots);
ws.onopen = function(e)
{
ok(true, "test 29 protocol array open");
ws.close();
};
ws.onclose = function(e)
{
ok(true, "test 29 protocol array close");
doTest(30);
};
}
function test30()
{
var prots=["test-does-not-exist"];
var ws = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", prots);
ws.onopen = shouldNotOpen;
ws.onclose = function(e)
{
shouldCloseNotCleanly(e);
doTest(31);
};
ws.onerror = function()
{
}
}
function test31()
{
var prots=["test-does-not-exist", "test31"];
var ws = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", prots);
ws.onopen = function(e)
{
ok(true, "test 31 protocol array open");
ws.close();
};
ws.onclose = function(e)
{
ok(ws.protocol == "test31", "test31 subprotocol selection");
ok(true, "test 31 protocol array close");
doTest(32);
};
}
function test32()
{
var prots=["test32","test32"];
try {
var ws = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", prots);
ok(false, "testing duplicated element sub protocol array");
}
catch (e) {
ok(true, "testing duplicated sub element protocol array");
}
doTest(33);
}
function test33()
{
var prots=["test33"];
var ws = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", prots);
ws.onopen = function(e)
{
ok(true, "test 33 open");
ws.close();
};
ws.onclose = function(e)
{
ok(true, "test 33 close");
ok(e.wasClean, "test 33 closed cleanly");
ok(e.code == 1000, "test 33 had normal 1000 error code");
doTest(34);
};
}
function test34()
{
var prots=["test-34"];
var ws = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", prots);
ws.onopen = function(e)
{
ok(true, "test 34 open");
ws.close();
};
ws.onclose = function(e)
{
ok(true, "test 34 close");
ok(e.wasClean, "test 34 closed cleanly");
ok(e.code == 1001, "test 34 custom server code");
ok(e.reason == "going away now", "test 34 custom server reason");
doTest(35);
};
}
function test35()
{
var ws = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", "test-35a");
ws.onopen = function(e)
{
ok(true, "test 35a open");
ws.close(3500, "my code");
};
ws.onclose = function(e)
{
ok(true, "test 35a close");
ok(e.wasClean, "test 35a closed cleanly");
current_test--; // CreateTestWS for 35a incremented this
var wsb = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", "test-35b");
wsb.onopen = function(e)
{
ok(true, "test 35b open");
wsb.close();
};
wsb.onclose = function(e)
{
ok(true, "test 35b close");
ok(e.wasClean, "test 35b closed cleanly");
ok(e.code == 3501, "test 35 custom server code");
ok(e.reason == "my code", "test 35 custom server reason");
doTest(36);
};
}
}
function test36()
{
var prots=["test-36"];
var ws = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", prots);
ws.onopen = function(e)
{
ok(true, "test 36 open");
try {
ws.close(13200);
ok(false, "testing custom close code out of range");
}
catch (e) {
ok(true, "testing custom close code out of range");
ws.close(3200);
}
};
ws.onclose = function(e)
{
ok(true, "test 36 close");
ok(e.wasClean, "test 36 closed cleanly");
doTest(37);
};
}
function test37()
{
var prots=["test-37"];
var ws = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", prots);
ws.onopen = function(e)
{
ok(true, "test 37 open");
try {
ws.close(3100,"0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123");
ok(false, "testing custom close reason out of range");
}
catch (e) {
ok(true, "testing custom close reason out of range");
ws.close(3100,"012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012");
}
};
ws.onclose = function(e)
{
ok(true, "test 37 close");
ok(e.wasClean, "test 37 closed cleanly");
current_test--; // CreateTestWS for 37 incremented this
var wsb = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", "test-37b");
wsb.onopen = function(e)
{
// now test that a rejected close code and reason dont persist
ok(true, "test 37b open");
try {
wsb.close(3101,"0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123");
ok(false, "testing custom close reason out of range 37b");
}
catch (e) {
ok(true, "testing custom close reason out of range 37b");
wsb.close();
}
}
wsb.onclose = function(e)
{
ok(true, "test 37b close");
ok(e.wasClean, "test 37b closed cleanly");
current_test--; // CreateTestWS for 37 incremented this
var wsc = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", "test-37c");
wsc.onopen = function(e)
{
ok(true, "test 37c open");
wsc.close();
}
wsc.onclose = function(e)
{
ok(e.code != 3101, "test 37c custom server code not present");
ok(e.reason == "", "test 37c custom server reason not present");
doTest(38);
}
}
}
}
function test38()
{
var prots=["test-38"];
var ws = CreateTestWS("ws://mochi.test:8888/tests/content/base/test/file_websocket", prots);
ws.onopen = function(e)
{
ok(true, "test 38 open");
ok(ws.extensions != undefined, "extensions attribute defined");
ok(ws.extensions == "deflate-stream", "extensions attribute deflate-stream");
ws.close();
};
ws.onclose = function(e)
{
ok(true, "test 38 close");
doTest(39);
};
}
function test39()
{
var prots=["test-39"];
var ws = CreateTestWS("wss://example.com/tests/content/base/test/file_websocket", prots);
status_test39 = "started";
ws.onopen = function(e)
{
status_test39 = "opened";
ok(true, "test 39 open");
ws.close();
};
ws.onclose = function(e)
{
ok(true, "test 39 close");
ok(status_test39 == "opened", "test 39 did open");
doTest(40);
};
}
function test40()
{
var prots=["test-40"];
var ws = CreateTestWS("wss://nocert.example.com/tests/content/base/test/file_websocket", prots);
status_test40 = "started";
ws.onerror = ignoreError;
ws.onopen = function(e)
{
status_test40 = "opened";
ok(false, "test 40 open");
ws.close();
};
ws.onclose = function(e)
{
ok(true, "test 40 close");
ok(status_test40 == "started", "test 40 did not open");
doTest(41);
};
}
var ranAllTests = false;
function maybeFinished()
{
if (!ranAllTests)
return;
if (waitTest2Part1 || waitTest2Part2 || waitTest9 || waitTest10 ||
waitTest17 || waitTest20 || waitTest21 || waitTest22)
return;
for (i = 0; i < all_ws.length; ++i) {
if (all_ws[i] != shouldNotReceiveCloseEvent &&
!all_ws[i]._receivedCloseEvent) {
ok(false, "didn't called close on test " + all_ws[i]._testNumber + "!");
}
}
SimpleTest.finish();
}

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

@ -56,16 +56,34 @@ nsDOMCloseEvent::GetWasClean(PRBool *aWasClean)
return NS_OK;
}
NS_IMETHODIMP
nsDOMCloseEvent::GetCode(PRUint16 *aCode)
{
*aCode = mReasonCode;
return NS_OK;
}
NS_IMETHODIMP
nsDOMCloseEvent::GetReason(nsAString & aReason)
{
aReason = mReason;
return NS_OK;
}
NS_IMETHODIMP
nsDOMCloseEvent::InitCloseEvent(const nsAString& aType,
PRBool aCanBubble,
PRBool aCancelable,
PRBool aWasClean)
PRBool aWasClean,
PRUint16 aReasonCode,
const nsAString &aReason)
{
nsresult rv = nsDOMEvent::InitEvent(aType, aCanBubble, aCancelable);
NS_ENSURE_SUCCESS(rv, rv);
mWasClean = aWasClean;
mReasonCode = aReasonCode;
mReason = aReason;
return NS_OK;
}

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

@ -53,9 +53,9 @@ class nsDOMCloseEvent : public nsDOMEvent,
{
public:
nsDOMCloseEvent(nsPresContext* aPresContext, nsEvent* aEvent)
: nsDOMEvent(aPresContext, aEvent), mWasClean(PR_FALSE)
{
}
: nsDOMEvent(aPresContext, aEvent),
mWasClean(PR_FALSE),
mReasonCode(1005) {}
NS_DECL_ISUPPORTS_INHERITED
@ -66,6 +66,8 @@ public:
private:
PRBool mWasClean;
PRUint16 mReasonCode;
nsString mReason;
};
#endif // nsDOMCloseEvent_h__

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

@ -758,9 +758,9 @@ nsGenericHTMLElement::SetInnerHTML(const nsAString& aInnerHTML)
mozAutoDocUpdate updateBatch(doc, UPDATE_CONTENT_MODEL, PR_TRUE);
// Remove childnodes.
// i is unsigned, so i >= is always true
for (PRUint32 i = GetChildCount(); i-- != 0; ) {
RemoveChildAt(i, PR_TRUE);
PRUint32 childCount = GetChildCount();
for (PRUint32 i = 0; i < childCount; ++i) {
RemoveChildAt(0, PR_TRUE);
}
nsCOMPtr<nsIDOMDocumentFragment> df;

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

@ -581,18 +581,21 @@ nsHTMLCanvasElement::UpdateContext(nsIPropertyBag *aNewContextOptions)
rv = mCurrentContext->SetIsOpaque(GetIsOpaque());
if (NS_FAILED(rv)) {
mCurrentContext = nsnull;
mCurrentContextId.AssignLiteral("");
return rv;
}
rv = mCurrentContext->SetContextOptions(aNewContextOptions);
if (NS_FAILED(rv)) {
mCurrentContext = nsnull;
mCurrentContextId.AssignLiteral("");
return rv;
}
rv = mCurrentContext->SetDimensions(sz.width, sz.height);
if (NS_FAILED(rv)) {
mCurrentContext = nsnull;
mCurrentContextId.AssignLiteral("");
return rv;
}

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

@ -239,7 +239,8 @@ MapAttributesIntoRule(const nsMappedAttributes* aAttributes,
}
}
}
if (aData->mSIDs & NS_STYLE_INHERIT_BIT(TextReset)) {
if (aData->mSIDs & NS_STYLE_INHERIT_BIT(TextReset) &&
aData->mPresContext->CompatibilityMode() == eCompatibility_NavQuirks) {
// Make <a><font color="red">text</font></a> give the text a red underline
// in quirks mode. The NS_STYLE_TEXT_DECORATION_LINE_OVERRIDE_ALL flag only
// affects quirks mode rendering.

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

@ -37,6 +37,10 @@ var nodes = [
[ "button", HTMLButtonElement ]
];
function soon(f) {
return function() { setTimeout(f, 0); }
}
function startTest(frameid) {
is(childUnloaded, false, "Child not unloaded yet");
@ -53,7 +57,7 @@ function startTest(frameid) {
is(node.disabled, true, "check for " + id + " state change");
}
$(frameid).onload = function () { continueTest(frameid) };
$(frameid).onload = soon(function() { continueTest(frameid) });
// Do this off a timeout so it's not treated like a replace load.
function loadBlank() {
@ -74,7 +78,7 @@ function continueTest(frameid) {
"Check for " + id, id + " should be null");
}
$(frameid).onload = function() { finishTest(frameid) };
$(frameid).onload = soon(function() { finishTest(frameid); });
// Do this off a timeout too. Why, I'm not sure. Something in session
// history creates another history state if we don't. :(
@ -117,7 +121,7 @@ function finishTest(frameid) {
// XXXbz this is a nasty hack to deal with the content sink. See above.
testIs = flipper;
$("frame2").onload = function () { startTest("frame2") };
$("frame2").onload = soon(function() { startTest("frame2"); });
$("frame2").src = "bug277724_iframe2.xhtml";
}
}
@ -130,7 +134,7 @@ SimpleTest.waitForExplicitFinish();
without a frame tree -->
<div id="content" style="visibility: hidden">
<iframe src="bug277724_iframe1.html" id="frame1"
onload="startTest('frame1')"></iframe>
onload="setTimeout(function() { startTest('frame1') }, 0)"></iframe>
<iframe src="" id="frame2"></iframe>
</div>
</body>

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

@ -1497,6 +1497,7 @@ nsHTMLDocument::SetCookie(const nsAString& aCookie)
window->GetPrompter(getter_AddRefs(prompt));
}
// The for getting the URI matches nsNavigator::GetCookieEnabled
nsCOMPtr<nsIURI> codebaseURI;
NodePrincipal()->GetURI(getter_AddRefs(codebaseURI));

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

@ -2435,6 +2435,29 @@ nsXULElement::SetDrawsInTitlebar(PRBool aState)
}
}
class MarginSetter : public nsRunnable
{
public:
MarginSetter(nsIWidget* aWidget) :
mWidget(aWidget), mMargin(-1, -1, -1, -1)
{}
MarginSetter(nsIWidget *aWidget, const nsIntMargin& aMargin) :
mWidget(aWidget), mMargin(aMargin)
{}
NS_IMETHOD Run()
{
// SetNonClientMargins can dispatch native events, hence doing
// it off a script runner.
mWidget->SetNonClientMargins(mMargin);
return NS_OK;
}
private:
nsCOMPtr<nsIWidget> mWidget;
nsIntMargin mMargin;
};
void
nsXULElement::SetChromeMargins(const nsAString* aValue)
{
@ -2453,7 +2476,7 @@ nsXULElement::SetChromeMargins(const nsAString* aValue)
data.Assign(*aValue);
if (attrValue.ParseIntMarginValue(data) &&
attrValue.GetIntMarginValue(margins)) {
mainWidget->SetNonClientMargins(margins);
nsContentUtils::AddScriptRunner(new MarginSetter(mainWidget, margins));
}
}
@ -2464,8 +2487,7 @@ nsXULElement::ResetChromeMargins()
if (!mainWidget)
return;
// See nsIWidget
nsIntMargin margins(-1,-1,-1,-1);
mainWidget->SetNonClientMargins(margins);
nsContentUtils::AddScriptRunner(new MarginSetter(mainWidget));
}
PRBool

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

@ -1335,9 +1335,8 @@ nsDocShell::LoadURI(nsIURI * aURI,
PRUint32 selfBusy = BUSY_FLAGS_NONE;
parentDS->GetBusyFlags(&parentBusy);
GetBusyFlags(&selfBusy);
if (((parentBusy & BUSY_FLAGS_BUSY) ||
(selfBusy & BUSY_FLAGS_BUSY)) &&
shEntry) {
if (parentBusy & BUSY_FLAGS_BUSY ||
selfBusy & BUSY_FLAGS_BUSY) {
loadType = LOAD_NORMAL_REPLACE;
shEntry = nsnull;
}

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

@ -64,6 +64,7 @@ _BROWSER_TEST_FILES = \
favicon_bug655270.ico \
browser_bug670318.js \
file_bug670318.html \
browser_bug673467.js \
$(NULL)
libs:: $(_BROWSER_TEST_FILES)

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

@ -0,0 +1,49 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
// Test for bug 673467. In a new tab, load a page which inserts a new iframe
// before the load and then sets its location during the load. This should
// create just one SHEntry.
var doc = "data:text/html,<html><body onload='load()'>" +
"<script>" +
" var iframe = document.createElement('iframe');" +
" iframe.id = 'iframe';" +
" document.documentElement.appendChild(iframe);" +
" function load() {" +
" iframe.src = 'data:text/html,Hello!';" +
" }" +
"</script>" +
"</body></html>"
function test() {
waitForExplicitFinish();
let tab = gBrowser.addTab(doc);
let tabBrowser = tab.linkedBrowser;
tabBrowser.addEventListener('load', function(aEvent) {
tabBrowser.removeEventListener('load', arguments.callee, true);
// The main page has loaded. Now wait for the iframe to load.
let iframe = tabBrowser.contentWindow.document.getElementById('iframe');
iframe.addEventListener('load', function(aEvent) {
// Wait for the iframe to load the new document, not about:blank.
if (!iframe.src)
return;
iframe.removeEventListener('load', arguments.callee, true);
let shistory = tabBrowser.contentWindow
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.sessionHistory;
is(shistory.count, 1, 'shistory count should be 1.');
gBrowser.removeTab(tab);
finish();
}, true);
}, true);
}

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

@ -6938,7 +6938,7 @@ nsWindowSH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
// that named child frames will override external properties
// which have been registered with the script namespace manager.
JSBool did_resolve = JS_FALSE;
PRBool did_resolve = PR_FALSE;
rv = GlobalResolve(win, cx, obj, id, &did_resolve);
NS_ENSURE_SUCCESS(rv, rv);
@ -7078,7 +7078,7 @@ nsWindowSH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
win->InitJavaProperties();
PRBool hasProp;
JSBool hasProp;
PRBool ok = ::JS_HasPropertyById(cx, obj, id, &hasProp);
isResolvingJavaProperties = PR_FALSE;
@ -7796,7 +7796,8 @@ nsEventReceiverSH::NewResolve(nsIXPConnectWrappedNative *wrapper,
JSAutoRequest ar(cx);
JSObject *proto = ::JS_GetPrototype(cx, obj);
PRBool ok = PR_TRUE, hasProp = PR_FALSE;
PRBool ok = PR_TRUE;
JSBool hasProp = JS_FALSE;
if (!proto || ((ok = ::JS_HasPropertyById(cx, proto, id, &hasProp)) &&
!hasProp)) {
// Make sure the flags here match those in

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

@ -190,6 +190,7 @@
#include "nsIXULWindow.h"
#include "nsEventStateManager.h"
#include "nsITimedChannel.h"
#include "nsICookiePermission.h"
#ifdef MOZ_XUL
#include "nsXULPopupManager.h"
#include "nsIDOMXULControlElement.h"
@ -10914,6 +10915,36 @@ nsNavigator::GetCookieEnabled(PRBool *aCookieEnabled)
(Preferences::GetInt("network.cookie.cookieBehavior",
COOKIE_BEHAVIOR_REJECT) != COOKIE_BEHAVIOR_REJECT);
// Check whether an exception overrides the global cookie behavior
// Note that the code for getting the URI here matches that in
// nsHTMLDocument::SetCookie.
nsCOMPtr<nsIDocument> doc = do_GetInterface(mDocShell);
if (!doc) {
return NS_OK;
}
nsCOMPtr<nsIURI> codebaseURI;
doc->NodePrincipal()->GetURI(getter_AddRefs(codebaseURI));
if (!codebaseURI) {
// Not a codebase, so technically can't set cookies, but let's
// just return the default value.
return NS_OK;
}
nsCOMPtr<nsICookiePermission> permMgr =
do_GetService(NS_COOKIEPERMISSION_CONTRACTID);
NS_ENSURE_TRUE(permMgr, NS_OK);
// Pass null for the channel, just like the cookie service does
nsCookieAccess access;
nsresult rv = permMgr->CanAccess(codebaseURI, nsnull, &access);
NS_ENSURE_SUCCESS(rv, NS_OK);
if (access != nsICookiePermission::ACCESS_DEFAULT) {
*aCookieEnabled = access != nsICookiePermission::ACCESS_DENY;
}
return NS_OK;
}

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

@ -1015,7 +1015,7 @@ nsJSContext::JSOptionChangedCallback(const char *pref, void *data)
#ifdef JS_GC_ZEAL
PRInt32 zeal = Preferences::GetInt(js_zeal_option_str, -1);
PRInt32 frequency = Preferences::GetInt(js_zeal_frequency_str, JS_DEFAULT_ZEAL_FREQ);
PRBool compartment = Preferences::GetBool(js_zeal_compartment_str, JS_FALSE);
PRBool compartment = Preferences::GetBool(js_zeal_compartment_str, PR_FALSE);
if (zeal >= 0)
::JS_SetGCZeal(context->mContext, (PRUint8)zeal, frequency, compartment);
#endif

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

@ -45,13 +45,17 @@
* For more information on this interface, please see
* http://dev.w3.org/html5/websockets/#closeevent
*/
[scriptable, uuid(a94d4379-eba2-45f4-be3a-6cc2fa1453a8)]
[scriptable, uuid(f83d9d6d-6c0c-418c-b12a-438e76d5866b)]
interface nsIDOMCloseEvent : nsIDOMEvent
{
readonly attribute boolean wasClean;
readonly attribute unsigned short code;
readonly attribute DOMString reason;
void initCloseEvent(in DOMString aType,
in boolean aCanBubble,
in boolean aCancelable,
in boolean aWasClean);
in boolean aCanBubble,
in boolean aCancelable,
in boolean aWasClean,
in unsigned short aReasonCode,
in DOMString aReason);
};

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

@ -108,3 +108,6 @@ IsSupportedWarning=Use of attributes' isSupported() is deprecated.
IsEqualNodeWarning=Use of attributes' isEqualNode() is deprecated.
TextContentWarning=Use of attributes' textContent attribute is deprecated. Use value instead.
EnablePrivilegeWarning=Use of enablePrivilege is deprecated. Please use code that runs with the system principal (e.g. an extension) instead.
nsIJSONDecodeDeprecatedWarning=nsIJSON.decode is deprecated. Please use JSON.parse instead.
nsIJSONEncodeDeprecatedWarning=nsIJSON.encode is deprecated. Please use JSON.stringify instead.

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

@ -52,6 +52,7 @@
#include "nsXPCOMStrings.h"
#include "nsNetUtil.h"
#include "nsContentUtils.h"
#include "nsIScriptError.h"
#include "nsCRTGlue.h"
#include "nsAutoPtr.h"
#include "nsIScriptSecurityManager.h"
@ -76,11 +77,29 @@ nsJSON::~nsJSON()
{
}
enum DeprecationWarning { EncodeWarning, DecodeWarning };
static nsresult
WarnDeprecatedMethod(DeprecationWarning warning)
{
return nsContentUtils::ReportToConsole(nsContentUtils::eDOM_PROPERTIES,
warning == EncodeWarning
? "nsIJSONEncodeDeprecatedWarning"
: "nsIJSONDecodeDeprecatedWarning",
nsnull, 0,
nsnull,
EmptyString(), 0, 0,
nsIScriptError::warningFlag,
"DOM Core");
}
NS_IMETHODIMP
nsJSON::Encode(nsAString &aJSON)
{
// This function should only be called from JS.
nsresult rv;
nsresult rv = WarnDeprecatedMethod(EncodeWarning);
if (NS_FAILED(rv))
return rv;
nsJSONWriter writer;
rv = EncodeInternal(&writer);
@ -424,13 +443,17 @@ nsJSONWriter::WriteToStream(nsIOutputStream *aStream,
NS_IMETHODIMP
nsJSON::Decode(const nsAString& json)
{
nsresult rv = WarnDeprecatedMethod(DecodeWarning);
if (NS_FAILED(rv))
return rv;
const PRUnichar *data;
PRUint32 len = NS_StringGetData(json, &data);
nsCOMPtr<nsIInputStream> stream;
nsresult rv = NS_NewByteInputStream(getter_AddRefs(stream),
(const char*) data,
len * sizeof(PRUnichar),
NS_ASSIGNMENT_DEPEND);
rv = NS_NewByteInputStream(getter_AddRefs(stream),
reinterpret_cast<const char*>(data),
len * sizeof(PRUnichar),
NS_ASSIGNMENT_DEPEND);
NS_ENSURE_SUCCESS(rv, rv);
return DecodeInternal(stream, len, PR_FALSE);
}

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

@ -1169,8 +1169,10 @@ DOMStorageImpl::GetKey(bool aCallerSecure, PRUint32 aIndex, nsAString& aKey)
// maybe we need to have a lazily populated key array here or
// something?
if (UseDB())
if (UseDB()) {
mItemsCached = PR_FALSE;
CacheKeysFromDB();
}
IndexFinderData data(aCallerSecure, aIndex);
mItems.EnumerateEntries(IndexFinder, &data);

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

@ -49,6 +49,7 @@ include $(topsrcdir)/config/rules.mk
_TEST_FILES = \
frameBug624047.html \
frameChromeSlave.html \
frameKeySync.html \
frameMasterEqual.html \
frameMasterNotEqual.html \
frameSlaveEqual.html \
@ -67,6 +68,7 @@ _TEST_FILES = \
test_cookieSession-phase1.html \
test_cookieSession-phase2.html \
test_embededNulls.html \
test_keySync.html \
test_localStorageBase.html \
test_localStorageBasePrivateBrowsing.html \
test_localStorageBaseSessionOnly.html \

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

@ -0,0 +1,51 @@
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>frame for localStorage test</title>
<script type="text/javascript" src="interOriginFrame.js"></script>
<script type="text/javascript">
var currentStep = parseInt(location.search.substring(1));
function doStep()
{
switch (currentStep)
{
case 1:
localStorage.clear();
break;
case 2:
localStorage.setItem("a", "1");
is(localStorage["a"], "1", "Value a=1 set");
break;
case 3:
try {
is(localStorage.key(0), "a", "Key 'a' present in 'key' array")
}
catch (exc) {
ok(false, "Shouldn't throw when accessing key(0) " + exc);
}
is(localStorage["a"], "1", "Value a=1 set");
break;
default:
return finishTest();
}
// Increase by two to as odd number are executed in a window separate from
// where even step are.
++currentStep;
++currentStep;
return true;
}
</script>
</head>
<body onload="postMsg('frame loaded');">
</body>
</html>

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

@ -0,0 +1,36 @@
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>localStorage equal origins</title>
<script type="text/javascript" src="/MochiKit/packed.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="interOriginTest2.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
<!--
This test loads two frames from the same origin, clears in one frame,
sets a single key in another and then checks key(0) in the first frame.
-->
<script type="text/javascript">
function startTest()
{
masterFrameOrigin = "http://example.org:80";
slaveFrameOrigin = "http://example.org:80";
masterFrame.location = masterFrameOrigin + framePath + "frameKeySync.html?1";
slaveFrame.location = slaveFrameOrigin + framePath + "frameKeySync.html?2";
}
SimpleTest.waitForExplicitFinish();
</script>
</head>
<body onload="startTest();">
<iframe src="" name="masterFrame"></iframe>
<iframe src="" name="slaveFrame"></iframe>
</body>
</html>

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

@ -338,14 +338,7 @@ public:
return NS_ERROR_FAILURE;
}
for (CompartmentStats *stats = data.compartmentStatsVector.begin();
stats != data.compartmentStatsVector.end();
++stats)
{
ReportCompartmentStats(*stats, mPathPrefix, aCallback, aClosure);
}
ReportJSStackSizeForRuntime(mRuntime, mPathPrefix, aCallback, aClosure);
ReportJSRuntimeStats(data, mPathPrefix, aCallback, aClosure);
return NS_OK;
}

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

@ -1171,6 +1171,7 @@ public:
} else {
mShaderType = RGBALayerProgramType;
}
Resize(aSize);
} else {
// Convert RGB24 to either ARGB32 on mobile. We can't
// generate GL_RGB data, so we'll always have an alpha byte
@ -1185,9 +1186,6 @@ public:
// We currently always use BGRA type textures
mShaderType = BGRALayerProgramType;
}
// We resize here so we should have a valid buffer after creation
Resize(aSize);
}
virtual ~TextureImageEGL()
@ -1382,12 +1380,22 @@ public:
virtual void BindTexture(GLenum aTextureUnit)
{
// Ensure the texture is allocated before it is used.
if (mTextureState == Created) {
Resize(mSize);
}
mGLContext->fActiveTexture(aTextureUnit);
mGLContext->fBindTexture(LOCAL_GL_TEXTURE_2D, mTexture);
mGLContext->fActiveTexture(LOCAL_GL_TEXTURE0);
}
virtual GLuint GetTextureID() {
virtual GLuint GetTextureID()
{
// Ensure the texture is allocated before it is used.
if (mTextureState == Created) {
Resize(mSize);
}
return mTexture;
};

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

@ -2573,7 +2573,7 @@ jsdService::AsyncOn (jsdIActivationCallback *activationCallback)
}
NS_IMETHODIMP
jsdService::RecompileForDebugMode (JSContext *cx, JSCompartment *comp, JSBool mode) {
jsdService::RecompileForDebugMode (JSContext *cx, JSCompartment *comp, PRBool mode) {
NS_ASSERTION(NS_IsMainThread(), "wrong thread");
/* XPConnect now does this work itself, so this IDL entry point is no longer used. */
return NS_ERROR_NOT_IMPLEMENTED;

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

@ -4,13 +4,15 @@
#include "tests.h"
#include "jscntxt.h"
#include "jscompartment.h"
#include "jsnum.h"
#include "vm/String.h"
#include "vm/String-inl.h"
BEGIN_TEST(testIndexToString)
{
struct TestPair {
const struct TestPair {
uint32 num;
const char *expected;
} tests[] = {
@ -43,9 +45,13 @@ BEGIN_TEST(testIndexToString)
};
for (size_t i = 0, sz = JS_ARRAY_LENGTH(tests); i < sz; i++) {
JSString *str = js::IndexToString(cx, tests[i].num);
uint32 u = tests[i].num;
JSString *str = js::IndexToString(cx, u);
CHECK(str);
if (!JSAtom::hasUintStatic(u))
CHECK(cx->compartment->dtoaCache.lookup(10, u) == str);
JSBool match = JS_FALSE;
CHECK(JS_StringEqualsAscii(cx, str, tests[i].expected, &match));
CHECK(match);

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

@ -2688,6 +2688,8 @@ JS_GetGCParameter(JSRuntime *rt, JSGCParamKey key)
return uint32(rt->gcMode);
case JSGC_UNUSED_CHUNKS:
return uint32(rt->gcChunksWaitingToExpire);
case JSGC_TOTAL_CHUNKS:
return uint32(rt->gcUserChunkSet.count() + rt->gcSystemChunkSet.count());
default:
JS_ASSERT(key == JSGC_NUMBER);
return rt->gcNumber;

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

@ -1671,7 +1671,7 @@ JS_CallTracer(JSTracer *trc, void *thing, uint32 kind);
* that stores the reference.
*
* When printer callback is not null, the arg and index arguments are
* available to the callback as debugPrinterArg and debugPrintIndex fields
* available to the callback as debugPrintArg and debugPrintIndex fields
* of JSTracer.
*
* The storage for name or callback's arguments needs to live only until
@ -1831,7 +1831,10 @@ typedef enum JSGCParamKey {
JSGC_MODE = 6,
/* Number of GC chunks waiting to expire. */
JSGC_UNUSED_CHUNKS = 7
JSGC_UNUSED_CHUNKS = 7,
/* Total number of allocated GC chunks. */
JSGC_TOTAL_CHUNKS = 8
} JSGCParamKey;
typedef enum JSGCMode {

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

@ -123,6 +123,7 @@ const char *const js_common_atom_names[] = {
js_apply_str, /* applyAtom */
js_arguments_str, /* argumentsAtom */
js_arity_str, /* arityAtom */
js_BYTES_PER_ELEMENT_str, /* BYTES_PER_ELEMENTAtom */
js_call_str, /* callAtom */
js_callee_str, /* calleeAtom */
js_caller_str, /* callerAtom */
@ -243,6 +244,7 @@ const char js_anonymous_str[] = "anonymous";
const char js_apply_str[] = "apply";
const char js_arguments_str[] = "arguments";
const char js_arity_str[] = "arity";
const char js_BYTES_PER_ELEMENT_str[] = "BYTES_PER_ELEMENT";
const char js_call_str[] = "call";
const char js_callee_str[] = "callee";
const char js_caller_str[] = "caller";

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

@ -246,6 +246,7 @@ struct JSAtomState
JSAtom *applyAtom;
JSAtom *argumentsAtom;
JSAtom *arityAtom;
JSAtom *BYTES_PER_ELEMENTAtom;
JSAtom *callAtom;
JSAtom *calleeAtom;
JSAtom *callerAtom;
@ -413,6 +414,7 @@ extern const char js_anonymous_str[];
extern const char js_apply_str[];
extern const char js_arguments_str[];
extern const char js_arity_str[];
extern const char js_BYTES_PER_ELEMENT_str[];
extern const char js_call_str[];
extern const char js_callee_str[];
extern const char js_caller_str[];

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

@ -3093,7 +3093,7 @@ AllocateSwitchConstant(JSContext *cx)
/*
* Sometimes, let-slots are pushed to the JS stack before we logically enter
* the let scope. For example,
* for (let x = EXPR;;) BODY
* let (x = EXPR) BODY
* compiles to roughly {enterblock; EXPR; setlocal x; BODY; leaveblock} even
* though EXPR is evaluated in the enclosing scope; it does not see x.
*
@ -4184,10 +4184,6 @@ EmitVariables(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn,
*/
let = (pn->pn_op == JSOP_NOP);
forInVar = (pn->pn_xflags & PNX_FORINVAR) != 0;
#if JS_HAS_BLOCK_SCOPE
bool popScope = (inLetHead || (let && (cg->flags & TCF_IN_FOR_INIT)));
JS_ASSERT_IF(popScope, let);
#endif
off = noteIndex = -1;
for (pn2 = pn->pn_head; ; pn2 = next) {
@ -4320,23 +4316,11 @@ EmitVariables(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn,
return JS_FALSE;
}
#if JS_HAS_BLOCK_SCOPE
/* Evaluate expr in the outer lexical scope if requested. */
TempPopScope tps;
if (popScope && !tps.popBlock(cx, cg))
return JS_FALSE;
#endif
oldflags = cg->flags;
cg->flags &= ~TCF_IN_FOR_INIT;
if (!js_EmitTree(cx, cg, pn3))
return JS_FALSE;
cg->flags |= oldflags & TCF_IN_FOR_INIT;
#if JS_HAS_BLOCK_SCOPE
if (popScope && !tps.repushBlock(cx, cg))
return JS_FALSE;
#endif
}
}
@ -6681,8 +6665,18 @@ js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn)
}
#if JS_HAS_BLOCK_SCOPE
case TOK_LET:
/* Let statements have their variable declarations on the left. */
case TOK_LET: {
/*
* pn represents one of these syntactic constructs:
* let-expression: (let (x = y) EXPR)
* let-statement: let (x = y) { ... }
* let-declaration in statement context: let x = y;
* let-declaration in for-loop head: for (let ...) ...
*
* Let-expressions and let-statements are represented as binary nodes
* with their variable declarations on the left and the body on the
* right.
*/
if (pn->pn_arity == PN_BINARY) {
pn2 = pn->pn_right;
pn = pn->pn_left;
@ -6690,13 +6684,27 @@ js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn)
pn2 = NULL;
}
/* Non-null pn2 means that pn is the variable list from a let head. */
/*
* Non-null pn2 means that pn is the variable list from a let head.
*
* Use TempPopScope to evaluate the expressions in the enclosing scope.
* This also causes the initializing assignments to be emitted in the
* enclosing scope, but the assignment opcodes emitted here
* (essentially just setlocal, though destructuring assignment uses
* other additional opcodes) do not care about the block chain.
*/
JS_ASSERT(pn->pn_arity == PN_LIST);
TempPopScope tps;
bool popScope = pn2 || (cg->flags & TCF_IN_FOR_INIT);
if (popScope && !tps.popBlock(cx, cg))
return JS_FALSE;
if (!EmitVariables(cx, cg, pn, pn2 != NULL, &noteIndex))
return JS_FALSE;
tmp = CG_OFFSET(cg);
if (popScope && !tps.repushBlock(cx, cg))
return JS_FALSE;
/* Thus non-null pn2 is the body of the let block or expression. */
tmp = CG_OFFSET(cg);
if (pn2 && !js_EmitTree(cx, cg, pn2))
return JS_FALSE;
@ -6706,6 +6714,7 @@ js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn)
return JS_FALSE;
}
break;
}
#endif /* JS_HAS_BLOCK_SCOPE */
#if JS_HAS_GENERATORS

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