зеркало из https://github.com/mozilla/gecko-dev.git
merge the last green changeset on m-c to fx-team
This commit is contained in:
Коммит
5d28376b91
|
@ -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)
|
||||
|
|
18
configure.in
18
configure.in
|
@ -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, ¬eIndex))
|
||||
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
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче