diff --git a/.hgignore b/.hgignore index 6c043f2fdb5b..171ba1a624a0 100644 --- a/.hgignore +++ b/.hgignore @@ -4,6 +4,7 @@ ~$ \.pyc$ (^|/)TAGS$ +(^|/)ID$ (^|/)\.DS_Store$ # User files that may appear at the root @@ -12,7 +13,6 @@ ^configure$ ^config\.cache$ ^config\.log$ -^ID$ # Empty marker file that's generated when we check out NSS ^security/manager/\.nss\.checkout$ @@ -27,6 +27,8 @@ _OPT\.OBJ/ # SpiderMonkey configury ^js/src/configure$ ^js/src/autom4te.cache$ +# SpiderMonkey test result logs +^js/src/tests/results-.*\.(html|txt)$ # Java HTML5 parser classes ^parser/html/java/(html|java)parser/ diff --git a/accessible/public/nsIAccessibleRole.idl b/accessible/public/nsIAccessibleRole.idl index ebf6510ae620..49b86dbb4c12 100644 --- a/accessible/public/nsIAccessibleRole.idl +++ b/accessible/public/nsIAccessibleRole.idl @@ -44,7 +44,7 @@ * @note - When adding a new role, be sure to also add it to nsRoleMap.h for * each platform. */ -[scriptable, uuid(6793ca5c-c7cb-41db-9fb9-c16c0525f962)] +[scriptable, uuid(f134da65-39a8-4330-843c-5bd42780b34c)] interface nsIAccessibleRole : nsISupports { /** @@ -776,10 +776,15 @@ interface nsIAccessibleRole : nsISupports */ const unsigned long ROLE_GRID_CELL = 121; + /** + * Represents an embedded object. It is used for html:object or html:embed. + */ + const unsigned long ROLE_EMBEDDED_OBJECT = 122; + /** * It's not role actually. This constant is important to help ensure * nsRoleMap's are synchronized. */ - const unsigned long ROLE_LAST_ENTRY = 122; + const unsigned long ROLE_LAST_ENTRY = 123; }; diff --git a/accessible/src/atk/nsRoleMap.h b/accessible/src/atk/nsRoleMap.h index bea513a58eff..e41a84e86cf3 100644 --- a/accessible/src/atk/nsRoleMap.h +++ b/accessible/src/atk/nsRoleMap.h @@ -168,6 +168,7 @@ static const PRUint32 atkRoleMap[] = { ATK_ROLE_LIST, // nsIAccessibleRole::ROLE_LISTBOX 119 ATK_ROLE_UNKNOWN, // nsIAccessibleRole::ROLE_FLAT_EQUATION 120 ATK_ROLE_TABLE_CELL, // nsIAccessibleRole::ROLE_GRID_CELL 121 + ATK_ROLE_PANEL, // nsIAccessibleRole::ROLE_EMBEDDED_OBJECT 122 kROLE_ATK_LAST_ENTRY // nsIAccessibleRole::ROLE_LAST_ENTRY }; diff --git a/accessible/src/base/nsAccUtils.cpp b/accessible/src/base/nsAccUtils.cpp index 74e1e7976fde..66edc110cc96 100644 --- a/accessible/src/base/nsAccUtils.cpp +++ b/accessible/src/base/nsAccUtils.cpp @@ -408,14 +408,30 @@ nsAccUtils::GetARIATreeItemParent(nsIAccessible *aStartTreeItem, nsIAccessible **aTreeItemParentResult) { *aTreeItemParentResult = nsnull; + + nsCOMPtr parentAccessible; + aStartTreeItem->GetParent(getter_AddRefs(parentAccessible)); + if (!parentAccessible) + return; + + PRUint32 startTreeItemRole = nsAccUtils::Role(aStartTreeItem); + + // Calculate tree grid row parent only if the row inside of ARIA treegrid. + if (startTreeItemRole == nsIAccessibleRole::ROLE_ROW) { + PRUint32 role = nsAccUtils::Role(parentAccessible); + if (role != nsIAccessibleRole::ROLE_TREE_TABLE) + return; + } + + // This is a tree or treegrid that uses aria-level to define levels, so find + // the first previous sibling accessible where level is defined to be less + // than the current level. nsAutoString levelStr; - PRInt32 level = 0; if (nsAccUtils::HasDefinedARIAToken(aStartContent, nsAccessibilityAtoms::aria_level) && aStartContent->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_level, levelStr)) { - // This is a tree that uses aria-level to define levels, so find the first previous - // sibling accessible where level is defined to be less than the current level + PRInt32 success; - level = levelStr.ToInteger(&success); + PRInt32 level = levelStr.ToInteger(&success); if (level > 1 && NS_SUCCEEDED(success)) { nsCOMPtr currentAccessible = aStartTreeItem, prevAccessible; while (PR_TRUE) { @@ -426,8 +442,9 @@ nsAccUtils::GetARIATreeItemParent(nsIAccessible *aStartTreeItem, break; // Reached top of tree, no higher level found } PRUint32 role = nsAccUtils::Role(currentAccessible); - if (role != nsIAccessibleRole::ROLE_OUTLINEITEM) + if (role != startTreeItemRole) continue; + nsCOMPtr treeItemNode; accessNode->GetDOMNode(getter_AddRefs(treeItemNode)); nsCOMPtr treeItemContent = do_QueryInterface(treeItemNode); @@ -445,19 +462,25 @@ nsAccUtils::GetARIATreeItemParent(nsIAccessible *aStartTreeItem, } } - // Possibly a tree arranged by using role="group" to organize levels - // In this case the parent of the tree item will be a group and the - // previous sibling of that should be the tree item parent. - // Or, if the parent is something other than a tree we will return that. - nsCOMPtr parentAccessible; - aStartTreeItem->GetParent(getter_AddRefs(parentAccessible)); - if (!parentAccessible) - return; + // In the case of ARIA treegrid, return its parent since ARIA group isn't + // used to organize levels in ARIA treegrids. + + if (startTreeItemRole == nsIAccessibleRole::ROLE_ROW) { + NS_ADDREF(*aTreeItemParentResult = parentAccessible); + return; // The container for the tree grid rows + } + + // In the case of ARIA tree, a tree can be arranged by using role="group" to + // organize levels. In this case the parent of the tree item will be a group + // and the previous sibling of that should be the tree item parent. Or, if + // the parent is something other than a tree we will return that. + PRUint32 role = nsAccUtils::Role(parentAccessible); if (role != nsIAccessibleRole::ROLE_GROUPING) { NS_ADDREF(*aTreeItemParentResult = parentAccessible); return; // The container for the tree items } + nsCOMPtr prevAccessible; parentAccessible->GetPreviousSibling(getter_AddRefs(prevAccessible)); if (!prevAccessible) diff --git a/accessible/src/base/nsAccessibilityService.cpp b/accessible/src/base/nsAccessibilityService.cpp index 82cf73650bd8..5626ce2f5ee2 100644 --- a/accessible/src/base/nsAccessibilityService.cpp +++ b/accessible/src/base/nsAccessibilityService.cpp @@ -548,6 +548,15 @@ nsAccessibilityService::CreateHTMLAccessibleByMarkup(nsIFrame *aFrame, *aAccessible = new nsHTMLListAccessible(aNode, aWeakShell); } else if (tag == nsAccessibilityAtoms::a) { + + // Only some roles truly enjoy life as nsHTMLLinkAccessibles, for details + // see closed bug 494807. + nsRoleMapEntry *roleMapEntry = nsAccUtils::GetRoleMapEntry(aNode); + if (roleMapEntry && roleMapEntry->role != nsIAccessibleRole::ROLE_NOTHING + && roleMapEntry->role != nsIAccessibleRole::ROLE_LINK) { + return CreateHyperTextAccessible(aFrame, aAccessible); + } + *aAccessible = new nsHTMLLinkAccessible(aNode, aWeakShell); } else if (tag == nsAccessibilityAtoms::li && aFrame->GetType() != nsAccessibilityAtoms::blockFrame) { @@ -763,15 +772,16 @@ nsAccessibilityService::CreateHTMLObjectFrameAccessible(nsObjectFrame *aFrame, nsCOMPtr pluginInstance ; aFrame->GetPluginInstance(*getter_AddRefs(pluginInstance)); if (pluginInstance) { + // Note: pluginPort will be null if windowless. HWND pluginPort = nsnull; aFrame->GetPluginPort(&pluginPort); - if (pluginPort) { - *aAccessible = new nsHTMLWin32ObjectOwnerAccessible(node, weakShell, pluginPort); - if (*aAccessible) { - NS_ADDREF(*aAccessible); - return NS_OK; - } - } + + *aAccessible = + new nsHTMLWin32ObjectOwnerAccessible(node, weakShell, pluginPort); + NS_ENSURE_TRUE(*aAccessible, NS_ERROR_OUT_OF_MEMORY); + + NS_ADDREF(*aAccessible); + return NS_OK; } #endif diff --git a/accessible/src/base/nsAccessibilityService.h b/accessible/src/base/nsAccessibilityService.h index 6d16fa6d4d04..4cdf478c4431 100644 --- a/accessible/src/base/nsAccessibilityService.h +++ b/accessible/src/base/nsAccessibilityService.h @@ -289,7 +289,8 @@ static const char kRoleNames[][20] = { "listbox rich option", //ROLE_RICH_OPTION "listbox", //ROLE_LISTBOX "flat equation", //ROLE_FLAT_EQUATION - "gridcell" //ROLE_GRID_CELL + "gridcell", //ROLE_GRID_CELL + "embedded object" //ROLE_EMBEDDED_OBJECT }; /** diff --git a/accessible/src/base/nsAccessible.cpp b/accessible/src/base/nsAccessible.cpp index 4c25cfa5de0b..69fa187f48ee 100644 --- a/accessible/src/base/nsAccessible.cpp +++ b/accessible/src/base/nsAccessible.cpp @@ -2492,13 +2492,16 @@ nsAccessible::GetRelationByType(PRUint32 aRelationType, if (rv != NS_OK_NO_RELATION_TARGET) return NS_OK; // XXX bug 381599, avoid performance problems + // This is an ARIA tree or treegrid that doesn't use owns, so we need to + // get the parent the hard way. if (mRoleMapEntry && - mRoleMapEntry->role == nsIAccessibleRole::ROLE_OUTLINEITEM) { - // This is an ARIA tree that doesn't use owns, so we need to get - // the parent the hard way. + (mRoleMapEntry->role == nsIAccessibleRole::ROLE_OUTLINEITEM || + mRoleMapEntry->role == nsIAccessibleRole::ROLE_ROW)) { + nsCOMPtr accTarget; nsAccUtils::GetARIATreeItemParent(this, content, getter_AddRefs(accTarget)); + return nsRelUtils::AddTarget(aRelationType, aRelation, accTarget); } diff --git a/accessible/src/html/nsHTMLTableAccessible.cpp b/accessible/src/html/nsHTMLTableAccessible.cpp index 38919197d44c..0b1aeb13eb06 100644 --- a/accessible/src/html/nsHTMLTableAccessible.cpp +++ b/accessible/src/html/nsHTMLTableAccessible.cpp @@ -924,20 +924,12 @@ NS_IMETHODIMP nsHTMLTableAccessible::GetCellAt(PRInt32 aRow, PRInt32 aColumn, nsIAccessible **aTableCellAccessible) { - NS_ENSURE_TRUE(IsValidRow(aRow) && IsValidColumn(aColumn), NS_ERROR_INVALID_ARG); - - nsresult rv = NS_OK; - nsCOMPtr cellElement; - rv = GetCellAt(aRow, aColumn, *getter_AddRefs(cellElement)); + nsresult rv = GetCellAt(aRow, aColumn, *getter_AddRefs(cellElement)); NS_ENSURE_SUCCESS(rv, rv); - nsCOMPtr - accService(do_GetService("@mozilla.org/accessibilityService;1")); - NS_ENSURE_TRUE(accService, NS_ERROR_FAILURE); - - return accService->GetAccessibleInWeakShell(cellElement, mWeakShell, - aTableCellAccessible); + return GetAccService()->GetAccessibleInWeakShell(cellElement, mWeakShell, + aTableCellAccessible); } NS_IMETHODIMP @@ -946,8 +938,6 @@ nsHTMLTableAccessible::GetCellIndexAt(PRInt32 aRow, PRInt32 aColumn, { NS_ENSURE_ARG_POINTER(aIndex); - NS_ENSURE_TRUE(IsValidRow(aRow) && IsValidColumn(aColumn), NS_ERROR_INVALID_ARG); - nsITableLayout *tableLayout = GetTableLayout(); NS_ENSURE_STATE(tableLayout); @@ -970,7 +960,10 @@ nsHTMLTableAccessible::GetColumnIndexAt(PRInt32 aIndex, PRInt32 *aColumn) NS_ENSURE_STATE(tableLayout); PRInt32 row; - return tableLayout->GetRowAndColumnByIndex(aIndex, &row, aColumn); + nsresult rv = tableLayout->GetRowAndColumnByIndex(aIndex, &row, aColumn); + NS_ENSURE_SUCCESS(rv, rv); + + return (row == -1 || *aColumn == -1) ? NS_ERROR_INVALID_ARG : NS_OK; } NS_IMETHODIMP @@ -985,7 +978,10 @@ nsHTMLTableAccessible::GetRowIndexAt(PRInt32 aIndex, PRInt32 *aRow) NS_ENSURE_STATE(tableLayout); PRInt32 column; - return tableLayout->GetRowAndColumnByIndex(aIndex, aRow, &column); + nsresult rv = tableLayout->GetRowAndColumnByIndex(aIndex, aRow, &column); + NS_ENSURE_SUCCESS(rv, rv); + + return (*aRow == -1 || column == -1) ? NS_ERROR_INVALID_ARG : NS_OK; } NS_IMETHODIMP @@ -993,9 +989,6 @@ nsHTMLTableAccessible::GetColumnExtentAt(PRInt32 aRowIndex, PRInt32 aColumnIndex, PRInt32 *aExtentCount) { - NS_ENSURE_TRUE(IsValidRow(aRowIndex) && IsValidColumn(aColumnIndex), - NS_ERROR_INVALID_ARG); - nsITableLayout *tableLayout = GetTableLayout(); NS_ENSURE_STATE(tableLayout); @@ -1003,19 +996,18 @@ nsHTMLTableAccessible::GetColumnExtentAt(PRInt32 aRowIndex, PRInt32 startRowIndex, startColIndex, rowSpan, colSpan, actualRowSpan; PRBool isSelected; - return tableLayout-> + nsresult rv = tableLayout-> GetCellDataAt(aRowIndex, aColumnIndex, *getter_AddRefs(domElement), startRowIndex, startColIndex, rowSpan, colSpan, actualRowSpan, *aExtentCount, isSelected); + + return (rv == NS_TABLELAYOUT_CELL_NOT_FOUND) ? NS_ERROR_INVALID_ARG : NS_OK; } NS_IMETHODIMP nsHTMLTableAccessible::GetRowExtentAt(PRInt32 aRowIndex, PRInt32 aColumnIndex, PRInt32 *aExtentCount) { - NS_ENSURE_TRUE(IsValidRow(aRowIndex) && IsValidColumn(aColumnIndex), - NS_ERROR_INVALID_ARG); - nsITableLayout *tableLayout = GetTableLayout(); NS_ENSURE_STATE(tableLayout); @@ -1023,10 +1015,12 @@ nsHTMLTableAccessible::GetRowExtentAt(PRInt32 aRowIndex, PRInt32 aColumnIndex, PRInt32 startRowIndex, startColIndex, rowSpan, colSpan, actualColSpan; PRBool isSelected; - return tableLayout-> + nsresult rv = tableLayout-> GetCellDataAt(aRowIndex, aColumnIndex, *getter_AddRefs(domElement), startRowIndex, startColIndex, rowSpan, colSpan, *aExtentCount, actualColSpan, isSelected); + + return (rv == NS_TABLELAYOUT_CELL_NOT_FOUND) ? NS_ERROR_INVALID_ARG : NS_OK; } NS_IMETHODIMP @@ -1042,51 +1036,63 @@ nsHTMLTableAccessible::GetRowDescription(PRInt32 aRow, nsAString &_retval) } NS_IMETHODIMP -nsHTMLTableAccessible::IsColumnSelected(PRInt32 aColumn, PRBool *_retval) +nsHTMLTableAccessible::IsColumnSelected(PRInt32 aColumn, PRBool *aIsSelected) { - NS_ENSURE_ARG_POINTER(_retval); + NS_ENSURE_ARG_POINTER(aIsSelected); + *aIsSelected = PR_FALSE; - NS_ENSURE_TRUE(IsValidColumn(aColumn), NS_ERROR_INVALID_ARG); - - nsresult rv = NS_OK; - - PRInt32 rows; - rv = GetRowCount(&rows); + PRInt32 colCount = 0; + nsresult rv = GetColumnCount(&colCount); NS_ENSURE_SUCCESS(rv, rv); - for (PRInt32 index = 0; index < rows; index++) { - rv = IsCellSelected(index, aColumn, _retval); - NS_ENSURE_SUCCESS(rv, rv); - if (!*_retval) { - break; + if (aColumn < 0 || aColumn >= colCount) + return NS_ERROR_INVALID_ARG; + + PRInt32 rowCount = 0; + rv = GetRowCount(&rowCount); + NS_ENSURE_SUCCESS(rv, rv); + + for (PRInt32 rowIdx = 0; rowIdx < rowCount; rowIdx++) { + PRBool isSelected = PR_FALSE; + rv = IsCellSelected(rowIdx, aColumn, &isSelected); + if (NS_SUCCEEDED(rv)) { + *aIsSelected = isSelected; + if (!isSelected) + break; } } - return rv; + return NS_OK; } NS_IMETHODIMP -nsHTMLTableAccessible::IsRowSelected(PRInt32 aRow, PRBool *_retval) +nsHTMLTableAccessible::IsRowSelected(PRInt32 aRow, PRBool *aIsSelected) { - NS_ENSURE_ARG_POINTER(_retval); + NS_ENSURE_ARG_POINTER(aIsSelected); + *aIsSelected = PR_FALSE; - NS_ENSURE_TRUE(IsValidRow(aRow), NS_ERROR_INVALID_ARG); - - nsresult rv = NS_OK; - - PRInt32 columns; - rv = GetColumnCount(&columns); + PRInt32 rowCount = 0; + nsresult rv = GetRowCount(&rowCount); NS_ENSURE_SUCCESS(rv, rv); - for (PRInt32 index = 0; index < columns; index++) { - rv = IsCellSelected(aRow, index, _retval); - NS_ENSURE_SUCCESS(rv, rv); - if (!*_retval) { - break; + if (aRow < 0 || aRow >= rowCount) + return NS_ERROR_INVALID_ARG; + + PRInt32 colCount = 0; + rv = GetColumnCount(&colCount); + NS_ENSURE_SUCCESS(rv, rv); + + for (PRInt32 colIdx = 0; colIdx < colCount; colIdx++) { + PRBool isSelected = PR_FALSE; + rv = IsCellSelected(aRow, colIdx, &isSelected); + if (NS_SUCCEEDED(rv)) { + *aIsSelected = isSelected; + if (!isSelected) + break; } } - return rv; + return NS_OK; } NS_IMETHODIMP @@ -1096,9 +1102,6 @@ nsHTMLTableAccessible::IsCellSelected(PRInt32 aRow, PRInt32 aColumn, NS_ENSURE_ARG_POINTER(aIsSelected); *aIsSelected = PR_FALSE; - NS_ENSURE_TRUE(IsValidRow(aRow) && IsValidColumn(aColumn), - NS_ERROR_INVALID_ARG); - nsITableLayout *tableLayout = GetTableLayout(); NS_ENSURE_STATE(tableLayout); @@ -1116,22 +1119,6 @@ nsHTMLTableAccessible::IsCellSelected(PRInt32 aRow, PRInt32 aColumn, return rv; } -PRBool -nsHTMLTableAccessible::IsValidColumn(PRInt32 aColumn) -{ - PRInt32 colCount = 0; - nsresult rv = GetColumnCount(&colCount); - return NS_SUCCEEDED(rv) && (aColumn >= 0) && (aColumn < colCount); -} - -PRBool -nsHTMLTableAccessible::IsValidRow(PRInt32 aRow) -{ - PRInt32 rowCount = 0; - nsresult rv = GetRowCount(&rowCount); - return NS_SUCCEEDED(rv) && (aRow >= 0) && (aRow < rowCount); -} - NS_IMETHODIMP nsHTMLTableAccessible::SelectRow(PRInt32 aRow) { diff --git a/accessible/src/html/nsHTMLTableAccessible.h b/accessible/src/html/nsHTMLTableAccessible.h index 835e7bb64e9d..68d0b2adb2e0 100644 --- a/accessible/src/html/nsHTMLTableAccessible.h +++ b/accessible/src/html/nsHTMLTableAccessible.h @@ -143,20 +143,6 @@ public: // nsHTMLTableAccessible - /** - * Returns true if the column index is in the valid column range. - * - * @param aColumn The index to check for validity. - */ - PRBool IsValidColumn(PRInt32 aColumn); - - /** - * Returns true if the given index is in the valid row range. - * - * @param aRow The index to check for validity. - */ - PRBool IsValidRow(PRInt32 aRow); - /** * Retun cell element at the given row and column index. */ diff --git a/accessible/src/mac/nsRoleMap.h b/accessible/src/mac/nsRoleMap.h index 7c6e2279814b..77fdb96bbf51 100644 --- a/accessible/src/mac/nsRoleMap.h +++ b/accessible/src/mac/nsRoleMap.h @@ -164,5 +164,6 @@ static const NSString* AXRoles [] = { NSAccessibilityListRole, // ROLE_LISTBOX NSAccessibilityUnknownRole, // ROLE_FLAT_EQUATION NSAccessibilityGroupRole, // ROLE_GRID_CELL + NSAccessibilityGroupRole, // ROLE_EMBEDDED_OBJECT @"ROLE_LAST_ENTRY" // ROLE_LAST_ENTRY. bogus role that will never be shown (just marks the end of this array)! }; diff --git a/accessible/src/msaa/nsHTMLWin32ObjectAccessible.cpp b/accessible/src/msaa/nsHTMLWin32ObjectAccessible.cpp index a96c7e022321..9885dbdbde31 100644 --- a/accessible/src/msaa/nsHTMLWin32ObjectAccessible.cpp +++ b/accessible/src/msaa/nsHTMLWin32ObjectAccessible.cpp @@ -39,13 +39,21 @@ #include "nsHTMLWin32ObjectAccessible.h" #include "nsAccessibleWrap.h" +//////////////////////////////////////////////////////////////////////////////// +// nsHTMLWin32ObjectOwnerAccessible +//////////////////////////////////////////////////////////////////////////////// -nsHTMLWin32ObjectOwnerAccessible::nsHTMLWin32ObjectOwnerAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell, void* aHwnd): -nsAccessibleWrap(aNode, aShell) +nsHTMLWin32ObjectOwnerAccessible:: + nsHTMLWin32ObjectOwnerAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell, + void* aHwnd) : + nsAccessibleWrap(aNode, aShell) { mHwnd = aHwnd; } +//////////////////////////////////////////////////////////////////////////////// +// nsHTMLWin32ObjectOwnerAccessible: nsAccessNode implementation + nsresult nsHTMLWin32ObjectOwnerAccessible::Shutdown() { @@ -54,37 +62,83 @@ nsHTMLWin32ObjectOwnerAccessible::Shutdown() return NS_OK; } -/** - * Our only child is a nsHTMLWin32ObjectAccessible - */ -NS_IMETHODIMP nsHTMLWin32ObjectOwnerAccessible::GetFirstChild(nsIAccessible **aFirstChild) +//////////////////////////////////////////////////////////////////////////////// +// nsHTMLWin32ObjectOwnerAccessible: nsIAccessible implementation + +NS_IMETHODIMP +nsHTMLWin32ObjectOwnerAccessible::GetFirstChild(nsIAccessible **aFirstChild) { - *aFirstChild = mNativeAccessible; + NS_ENSURE_ARG_POINTER(aFirstChild); + *aFirstChild = nsnull; + + // Our only child is a nsHTMLWin32ObjectAccessible object. if (!mNativeAccessible) { - if (!mHwnd) { + if (!mHwnd) return NS_OK; - } - mNativeAccessible = new nsHTMLWin32ObjectAccessible(mHwnd) ; + + mNativeAccessible = new nsHTMLWin32ObjectAccessible(mHwnd); + NS_ENSURE_TRUE(mNativeAccessible, NS_ERROR_OUT_OF_MEMORY); + SetFirstChild(mNativeAccessible); - *aFirstChild = mNativeAccessible; } + + *aFirstChild = mNativeAccessible; NS_IF_ADDREF(*aFirstChild); + return NS_OK; } -NS_IMETHODIMP nsHTMLWin32ObjectOwnerAccessible::GetLastChild(nsIAccessible **aLastChild) +NS_IMETHODIMP +nsHTMLWin32ObjectOwnerAccessible::GetLastChild(nsIAccessible **aLastChild) { return GetFirstChild(aLastChild); } -NS_IMETHODIMP nsHTMLWin32ObjectOwnerAccessible::GetChildCount(PRInt32 *aChildCount) +NS_IMETHODIMP +nsHTMLWin32ObjectOwnerAccessible::GetChildCount(PRInt32 *aChildCount) { + NS_ENSURE_ARG_POINTER(aChildCount); + nsCOMPtr onlyChild; GetFirstChild(getter_AddRefs(onlyChild)); *aChildCount = onlyChild ? 1 : 0; return NS_OK; } + +//////////////////////////////////////////////////////////////////////////////// +// nsHTMLWin32ObjectOwnerAccessible: nsAccessible implementation + +nsresult +nsHTMLWin32ObjectOwnerAccessible::GetRoleInternal(PRUint32 *aRole) +{ + NS_ENSURE_ARG_POINTER(aRole); + + *aRole = nsIAccessibleRole::ROLE_EMBEDDED_OBJECT; + return NS_OK; +} + +nsresult +nsHTMLWin32ObjectOwnerAccessible::GetStateInternal(PRUint32 *aState, + PRUint32 *aExtraState) +{ + nsresult rv = nsAccessibleWrap::GetStateInternal(aState, aExtraState); + if (rv == NS_OK_DEFUNCT_OBJECT) + return rv; + + // XXX: No HWND means this is windowless plugin which is not accessible in + // the meantime. + if (!mHwnd) + *aState = nsIAccessibleStates::STATE_UNAVAILABLE; + + return rv; +} + + +//////////////////////////////////////////////////////////////////////////////// +// nsHTMLWin32ObjectAccessible +//////////////////////////////////////////////////////////////////////////////// + nsHTMLWin32ObjectAccessible::nsHTMLWin32ObjectAccessible(void* aHwnd): nsLeafAccessible(nsnull, nsnull) { diff --git a/accessible/src/msaa/nsHTMLWin32ObjectAccessible.h b/accessible/src/msaa/nsHTMLWin32ObjectAccessible.h index c6c6c88be758..721586262bbe 100644 --- a/accessible/src/msaa/nsHTMLWin32ObjectAccessible.h +++ b/accessible/src/msaa/nsHTMLWin32ObjectAccessible.h @@ -64,6 +64,10 @@ public: // nsAccessNode virtual nsresult Shutdown(); + // nsAccessible + virtual nsresult GetRoleInternal(PRUint32 *aRole); + virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState); + protected: void* mHwnd; nsCOMPtr mNativeAccessible; diff --git a/accessible/src/msaa/nsRoleMap.h b/accessible/src/msaa/nsRoleMap.h index b659050b599a..cfb9ff4e1897 100644 --- a/accessible/src/msaa/nsRoleMap.h +++ b/accessible/src/msaa/nsRoleMap.h @@ -440,6 +440,9 @@ static const WindowsRoleMapItem gWindowsRoleMap[] = { // nsIAccessibleRole::ROLE_GRID_CELL { ROLE_SYSTEM_CELL, ROLE_SYSTEM_CELL }, + // nsIAccessibleRole::ROLE_EMBEDDED_OBJECT + { USE_ROLE_STRING, IA2_ROLE_EMBEDDED_OBJECT }, + // nsIAccessibleRole::ROLE_LAST_ENTRY { ROLE_WINDOWS_LAST_ENTRY, ROLE_WINDOWS_LAST_ENTRY } }; diff --git a/accessible/tests/mochitest/Makefile.in b/accessible/tests/mochitest/Makefile.in index c60e57f48cf6..b5c30e17c22c 100644 --- a/accessible/tests/mochitest/Makefile.in +++ b/accessible/tests/mochitest/Makefile.in @@ -89,6 +89,7 @@ _TEST_FILES =\ test_elm_filectrl.html \ test_elm_listbox.xul \ $(warning test_elm_media.html temporarily disabled) \ + test_elm_plugin.html \ test_elm_tree.xul \ test_elm_txtcntnr.html \ test_events_caretmove.html \ @@ -159,6 +160,7 @@ _TEST_FILES =\ test_textattrs.html \ test_textboxes.html \ test_textboxes.xul \ + test_value.html \ test_value.xul \ testTextboxes.js \ treeview.css \ diff --git a/accessible/tests/mochitest/role.js b/accessible/tests/mochitest/role.js index 6fe231a42e0f..cfd84357dad4 100644 --- a/accessible/tests/mochitest/role.js +++ b/accessible/tests/mochitest/role.js @@ -12,6 +12,7 @@ const ROLE_COMBOBOX_LIST = nsIAccessibleRole.ROLE_COMBOBOX_LIST; const ROLE_COMBOBOX_OPTION = nsIAccessibleRole.ROLE_COMBOBOX_OPTION; const ROLE_COLUMNHEADER = nsIAccessibleRole.ROLE_COLUMNHEADER; const ROLE_DOCUMENT = nsIAccessibleRole.ROLE_DOCUMENT; +const ROLE_EMBEDDED_OBJECT = nsIAccessibleRole.ROLE_EMBEDDED_OBJECT; const ROLE_ENTRY = nsIAccessibleRole.ROLE_ENTRY; const ROLE_FLAT_EQUATION = nsIAccessibleRole.ROLE_FLAT_EQUATION; const ROLE_FORM = nsIAccessibleRole.ROLE_FORM; diff --git a/accessible/tests/mochitest/states.js b/accessible/tests/mochitest/states.js index dac460b903d8..79909f37ab47 100644 --- a/accessible/tests/mochitest/states.js +++ b/accessible/tests/mochitest/states.js @@ -94,10 +94,12 @@ function testStates(aAccOrElmOrID, aState, aExtraState, aAbsentState, } // unavailable - if ((state & STATE_UNAVAILABLE) - && (getRole(aAccOrElmOrID) != ROLE_GROUPING)) - isState(state & STATE_FOCUSABLE, STATE_FOCUSABLE, false, - "Disabled " + id + " must be focusable!"); + if (state & STATE_UNAVAILABLE) { + var role = getRole(aAccOrElmOrID); + if (role != ROLE_GROUPING && role != ROLE_EMBEDDED_OBJECT) + isState(state & STATE_FOCUSABLE, STATE_FOCUSABLE, false, + "Disabled " + id + " must be focusable!"); + } } /** diff --git a/accessible/tests/mochitest/test_elm_plugin.html b/accessible/tests/mochitest/test_elm_plugin.html new file mode 100644 index 000000000000..0938d38fe277 --- /dev/null +++ b/accessible/tests/mochitest/test_elm_plugin.html @@ -0,0 +1,54 @@ + + + + Plugin tests + + + + + + + + + + + + + + Mozilla Bug 485270 +

+ +
+  
+ + + + diff --git a/accessible/tests/mochitest/test_relations.html b/accessible/tests/mochitest/test_relations.html index a931333489ed..e7cf25717f5f 100644 --- a/accessible/tests/mochitest/test_relations.html +++ b/accessible/tests/mochitest/test_relations.html @@ -49,6 +49,12 @@ testRelation("treeitem3", RELATION_NODE_CHILD_OF, "tree"); testRelation("treeitem4", RELATION_NODE_CHILD_OF, "tree"); testRelation("treeitem5", RELATION_NODE_CHILD_OF, "treeitem4"); + testRelation("treeitem6", RELATION_NODE_CHILD_OF, "treeitem5"); + + // 'node child of' relation for row role of treegrid + testRelation("treegridrow1", RELATION_NODE_CHILD_OF, "treegrid"); + testRelation("treegridrow2", RELATION_NODE_CHILD_OF, "treegrid"); + testRelation("treegridrow3", RELATION_NODE_CHILD_OF, "treegridrow2"); // 'node child of' relation for the document having window, returns // direct accessible parent (fixed in bug 419770). @@ -147,6 +153,21 @@
Blue
Green
Light green
+
+
Super light green
+
+ + +
+
+ cell1cell2 +
+
+ cell3cell4 +
+
+ cell5cell6 +
diff --git a/accessible/tests/mochitest/test_states.html b/accessible/tests/mochitest/test_states.html index 5fd664c075b2..c9246367f828 100644 --- a/accessible/tests/mochitest/test_states.html +++ b/accessible/tests/mochitest/test_states.html @@ -69,6 +69,30 @@ // offscreen test testStates("aria_offscreen_textbox", STATE_OFFSCREEN); + // + // This section tests aria roles on links/anchors for underlying + // nsHTMLLinkAccessible creation. (see closed bug 494807) + // + + // strong roles + testStates("aria_menuitem_link", 0, 0, STATE_LINKED); + testStates("aria_button_link", 0, 0, STATE_LINKED); + testStates("aria_checkbox_link", 0, 0, STATE_LINKED); + + // strong landmark + testStates("aria_application_link", 0, 0, STATE_LINKED); + testStates("aria_application_anchor", 0, 0, STATE_SELECTABLE); + + // strange cases + testStates("aria_link_link", STATE_LINKED); + testStates("aria_link_anchor", STATE_SELECTABLE); + + // some weak landmarks + testStates("aria_main_link", STATE_LINKED); + testStates("aria_navigation_link", STATE_LINKED); + testStates("aria_main_anchor", STATE_SELECTABLE); + testStates("aria_navigation_anchor", STATE_SELECTABLE); + SimpleTest.finish(); } @@ -140,5 +164,24 @@
This text should be offscreen
+ + menuitem + button + checkbox + + + link + link + + + app + main + nav + + + app + main + nav + diff --git a/accessible/tests/mochitest/test_table_sels.html b/accessible/tests/mochitest/test_table_sels.html index b08e397f42d3..c789ed1faf30 100644 --- a/accessible/tests/mochitest/test_table_sels.html +++ b/accessible/tests/mochitest/test_table_sels.html @@ -22,6 +22,9 @@ function doTest() { + ////////////////////////////////////////////////////////////////////////// + // table + var cellsArray = [ [false, false, false, kColSpanned, false, false, false, false], @@ -53,6 +56,20 @@ var accTable = getAccessible("table", [nsIAccessibleTable]); ok(!accTable.isProbablyForLayout(), "table is not for layout"); + ////////////////////////////////////////////////////////////////////////// + // table instane + + cellsArray = + [ + [false, false, false, -1, -1], + [false, false, false, -1, -1], + [false, false, kColSpanned, kColSpanned, -1], + [kRowSpanned, false, false, -1, -1], + [kRowSpanned, false, kRowSpanned, false, false] + ]; + + testTableSelection("tableinsane", cellsArray); + SimpleTest.finish(); } @@ -77,6 +94,11 @@ title="nsIAccessiblTable selectRows does not unselect previously selected rows"> Mozilla Bug 417929 + + Mozilla Bug 501659 +

@@ -122,6 +144,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
col1col2col3
123
45
67
8910
+ diff --git a/accessible/tests/mochitest/test_value.html b/accessible/tests/mochitest/test_value.html new file mode 100644 index 000000000000..dcc84f7069ee --- /dev/null +++ b/accessible/tests/mochitest/test_value.html @@ -0,0 +1,81 @@ + + + + nsIAccessible value testing + + + + + + + + + + + + + + + + + + Mozilla Bug 494807 +
+ + menuitem + button + checkbox + + + app + main + nav + + + link + + + diff --git a/browser/app/Makefile.in b/browser/app/Makefile.in index 211b0386b4b4..7ecd49bcd94f 100644 --- a/browser/app/Makefile.in +++ b/browser/app/Makefile.in @@ -298,9 +298,6 @@ libs:: endif endif -libs:: - touch $(DIST)/bin/.autoreg - libs:: $(srcdir)/profile/prefs.js $(INSTALL) $(IFLAGS1) $^ $(DIST)/bin/defaults/profile diff --git a/browser/app/profile/firefox.js b/browser/app/profile/firefox.js index 8e4552e95730..e5f0b7070da5 100644 --- a/browser/app/profile/firefox.js +++ b/browser/app/profile/firefox.js @@ -338,7 +338,6 @@ pref("browser.tabs.warnOnClose", true); pref("browser.tabs.warnOnOpen", true); pref("browser.tabs.maxOpenBeforeWarn", 15); pref("browser.tabs.loadInBackground", true); -pref("browser.tabs.loadFolderAndReplace", true); pref("browser.tabs.opentabfor.middleclick", true); pref("browser.tabs.loadDivertedInBackground", false); pref("browser.tabs.loadBookmarksInBackground", false); diff --git a/browser/base/content/aboutSupport.xhtml b/browser/base/content/aboutSupport.xhtml index 47cc4cb3269d..a3951b3b3b6a 100644 --- a/browser/base/content/aboutSupport.xhtml +++ b/browser/base/content/aboutSupport.xhtml @@ -134,6 +134,43 @@ td { const Cc = Components.classes; const Ci = Components.interfaces; +// We use a preferences whitelist to make sure we only show preferences that +// are useful for support and won't compromise the user's privacy. Note that +// entries are *prefixes*: for example, "accessibility." applies to all prefs +// under the "accessibility.*" branch. +const Whitelist = [ + "accessibility.", + "browser.fixup.", + "browser.history_expire_", + "browser.link.open_newwindow", + "browser.mousewheel.", + "browser.places.", + "browser.startup.homepage", + "browser.tabs.", + "browser.zoom.", + "dom.", + "extensions.checkCompatibility", + "extensions.lastAppVersion", + "font.", + "general.useragent.", + "gfx.color_management.mode", + "javascript.", + "keyword.", + "layout.css.dpi", + "network.", + "places.", + "print.", + "privacy.", + "security." +]; + +// The blacklist, unlike the whitelist, is a list of regular expressions. +const Blacklist = [ + /^print[.]print_to_filename$/, + /^print[.].*[.]print_to_filename$/, + /^network[.]proxy[.].*$/ +]; + window.onload = function () { // Get the FUEL Application object. let Application = Cc["@mozilla.org/fuel/application;1"] @@ -144,16 +181,9 @@ window.onload = function () { .getService(Ci.nsIURLFormatter); let supportUrl = urlFormatter.formatURLPref("app.support.baseURL"); - // Get the profile directory. - let propertiesService = Cc["@mozilla.org/file/directory_service;1"] - .getService(Ci.nsIProperties); - let currProfD = propertiesService.get("ProfD", Ci.nsIFile); - let profileDir = currProfD.path; - // Update the application basics section. document.getElementById("application-box").textContent = Application.name; document.getElementById("version-box").textContent = Application.version; - document.getElementById("profile-box").textContent = profileDir; document.getElementById("supportLink").href = supportUrl; // Update the other sections. @@ -193,7 +223,7 @@ function populatePreferencesSection() { let trPrefs = []; for each (let pref in sortedPrefs) { let tdName = createElement("td", pref.name, "pref-name"); - let tdValue = createElement("td", pref.value, "pref-value"); + let tdValue = createElement("td", formatPrefValue(pref.value), "pref-value"); let tr = createParentElement("tr", [tdName, tdValue]); trPrefs.push(tr); } @@ -201,6 +231,18 @@ function populatePreferencesSection() { appendChildren(document.getElementById("prefs-tbody"), trPrefs); } +function formatPrefValue(prefValue) { + // Some pref values are really long and don't have spaces. This can cause + // problems when copying and pasting into some WYSIWYG editors. In general + // the exact contents of really long pref values aren't particularly useful, + // so we truncate them to some reasonable length. + let maxPrefValueLen = 120; + let text = "" + prefValue; + if (text.length > maxPrefValueLen) + text = text.substring(0, maxPrefValueLen) + "…"; + return text; +} + function getModifiedPrefs() { // We use the low-level prefs API to identify prefs that have been // modified, rather that Application.prefs.all since the latter is @@ -209,13 +251,27 @@ function getModifiedPrefs() { let prefService = Cc["@mozilla.org/preferences-service;1"] .getService(Ci.nsIPrefService); let prefRootBranch = prefService.getBranch(""); - let prefNames = prefRootBranch.getChildList("", { value: 0 }); + let prefNames = getWhitelistedPrefNames(prefRootBranch); let prefs = [Application.prefs.get(prefName) for each (prefName in prefNames) - if (prefRootBranch.prefHasUserValue(prefName))]; + if (prefRootBranch.prefHasUserValue(prefName) + && !isBlacklisted(prefName))]; return prefs; } +function getWhitelistedPrefNames(prefRootBranch) { + let results = []; + for each (let prefStem in Whitelist) { + let prefNames = prefRootBranch.getChildList(prefStem, {}); + results = results.concat(prefNames); + } + return results; +} + +function isBlacklisted(prefName) { + return Blacklist.some(function (re) {return re.test(prefName);}); +} + function createParentElement(tagName, childElems) { let elem = document.createElement(tagName); appendChildren(elem, childElems); @@ -275,7 +331,10 @@ function createTextForElement(elem) { // Trim extraneous whitespace before newlines, then squash extraneous // blank lines. text = text.replace(/[ \t]+\n/g, "\n"); - text = text.replace(/\n\n\n*/g, "\n\n"); + text = text.replace(/\n\n\n+/g, "\n\n"); + + // Actual CR/LF pairs are needed for some Windows text editors. + text = text.replace(/\n/g, "\r\n"); return text; } @@ -316,6 +375,19 @@ function generateTextForTextNode(node, indent, textFragmentAccumulator) { textFragmentAccumulator.push(text); } +function openProfileDirectory() { + // Get the profile directory. + let propertiesService = Cc["@mozilla.org/file/directory_service;1"] + .getService(Ci.nsIProperties); + let currProfD = propertiesService.get("ProfD", Ci.nsIFile); + let profileDir = currProfD.path; + + // Show the profile directory. + let nsLocalFile = Components.Constructor("@mozilla.org/file/local;1", + "nsILocalFile", "initWithPath"); + new nsLocalFile(profileDir).reveal(); +} + ]]> @@ -369,10 +441,17 @@ function generateTextForTextNode(node, indent, textFragmentAccumulator) { &aboutSupport.appBasicsProfileDir; - + + - + &aboutSupport.appBasicsPlugins; diff --git a/browser/base/content/browser.js b/browser/base/content/browser.js index d74130322895..e24edbac6136 100644 --- a/browser/base/content/browser.js +++ b/browser/base/content/browser.js @@ -220,8 +220,13 @@ function SetClickAndHoldHandlers() { if (aEvent.button == 0 && aEvent.target == aEvent.currentTarget && !aEvent.currentTarget.open && - !aEvent.currentTarget.disabled) - aEvent.currentTarget.doCommand(); + !aEvent.currentTarget.disabled) { + let cmdEvent = document.createEvent("xulcommandevent"); + cmdEvent.initCommandEvent("command", true, true, window, 0, + aEvent.ctrlKey, aEvent.altKey, aEvent.shiftKey, + aEvent.metaKey, null); + aEvent.currentTarget.dispatchEvent(cmdEvent); + } } function stopTimer(aEvent) { @@ -786,13 +791,14 @@ let gGestureSupport = { _power: function GS__power(aArray) { // Create a bitmask based on the length of the array let num = 1 << aArray.length; - while (--num >= 0) + while (--num >= 0) { // Only select array elements where the current bit is set - yield aArray.reduce(function(aPrev, aCurr, aIndex) { + yield aArray.reduce(function (aPrev, aCurr, aIndex) { if (num & 1 << aIndex) aPrev.push(aCurr); return aPrev; }, []); + } }, /** @@ -807,47 +813,44 @@ let gGestureSupport = { * command is found, no value is returned (undefined). */ _doAction: function GS__doAction(aEvent, aGesture) { - // Create a fake event that pretends the gesture is a button click - let fakeEvent = { shiftKey: aEvent.shiftKey, ctrlKey: aEvent.ctrlKey, - metaKey: aEvent.metaKey, altKey: aEvent.altKey, button: 0 }; - // Create an array of pressed keys in a fixed order so that a command for // "meta" is preferred over "ctrl" when both buttons are pressed (and a // command for both don't exist) let keyCombos = []; - const keys = ["shift", "alt", "ctrl", "meta"]; - for each (let key in keys) + ["shift", "alt", "ctrl", "meta"].forEach(function (key) { if (aEvent[key + "Key"]) keyCombos.push(key); + }); - try { - // Try each combination of key presses in decreasing order for commands - for (let subCombo in this._power(keyCombos)) { - // Convert a gesture and pressed keys into the corresponding command - // action where the preference has the gesture before "shift" before - // "alt" before "ctrl" before "meta" all separated by periods - let command = this._getPref(aGesture.concat(subCombo).join(".")); + // Try each combination of key presses in decreasing order for commands + for each (let subCombo in this._power(keyCombos)) { + // Convert a gesture and pressed keys into the corresponding command + // action where the preference has the gesture before "shift" before + // "alt" before "ctrl" before "meta" all separated by periods + let command; + try { + command = this._getPref(aGesture.concat(subCombo).join(".")); + } catch (e) {} - // Do the command if we found one to do - if (command) { - let node = document.getElementById(command); - // Use the command element if it exists - if (node && node.hasAttribute("oncommand")) { - // XXX: Use node.oncommand(event) once bug 246720 is fixed - if (node.getAttribute("disabled") != "true") - new Function("event", node.getAttribute("oncommand")). - call(node, fakeEvent); - } - // Otherwise it should be a "standard" command - else - goDoCommand(command); + if (!command) + continue; - return command; + let node = document.getElementById(command); + if (node) { + if (node.getAttribute("disabled") != "true") { + let cmdEvent = document.createEvent("xulcommandevent"); + cmdEvent.initCommandEvent("command", true, true, window, 0, + aEvent.ctrlKey, aEvent.altKey, aEvent.shiftKey, + aEvent.metaKey, null); + node.dispatchEvent(cmdEvent); } + } else { + goDoCommand(command); } + + return command; } - // The generator ran out of key combinations, so just do nothing - catch (e) {} + return null; }, /** diff --git a/browser/base/content/pageinfo/pageInfo.xul b/browser/base/content/pageinfo/pageInfo.xul index a4e237f0d574..71533bbc2de4 100644 --- a/browser/base/content/pageinfo/pageInfo.xul +++ b/browser/base/content/pageinfo/pageInfo.xul @@ -289,7 +289,7 @@ - + diff --git a/browser/base/content/tabbrowser.xml b/browser/base/content/tabbrowser.xml index 5ec9de5af361..b97ccb013863 100644 --- a/browser/base/content/tabbrowser.xml +++ b/browser/base/content/tabbrowser.xml @@ -525,7 +525,7 @@ if (aWebProgress.DOMWindow == this.mBrowser.contentWindow && aWebProgress.isLoadingDocument) - this.mTabBrowser.setIcon(this.mTab, null); + this.mTabBrowser.getBrowserForTab(this.mTab).mIconURL = null; // changing location, clear out the missing plugins list this.mBrowser.missingPlugins = null; @@ -1266,7 +1266,7 @@ "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul", "tab"); - var blank = (aURI == "about:blank"); + var blank = !aURI || (aURI == "about:blank"); if (blank) t.setAttribute("label", this.mStringBundle.getString("tabs.untitled")); @@ -2865,14 +2865,6 @@ return document.getBindingParent(this).childNodes; ]]> -#ifdef XP_MACOSX - - document.getAnonymousElementByAttribute(this, "anonid", "down-box"); - - - document.getAnonymousElementByAttribute(this, "anonid", "down-box-animate"); - -#endif @@ -2882,10 +2874,6 @@ var tabs = document.getBindingParent(this); tabs.removeAttribute("overflow"); -#ifdef XP_MACOSX - this._scrollButtonDownBox.collapsed = true; - this._scrollButtonDownBoxAnimate.collapsed = true; -#endif ]]> - -#ifdef XP_MACOSX - -#endif - - -#ifdef XP_MACOSX - - - - - - - - - - - -#endif - - - - - - + + + @@ -3168,19 +3103,13 @@ "anonid", "alltabs-popup"); - - document.getAnonymousElementByAttribute(this, - "anonid", - "alltabs-box-animate"); + + this.mTabstrip._scrollButtonDown; -#ifdef XP_MACOSX - - this.mTabstrip._scrollButtonDownBoxAnimate; - -#endif - null + null + null -1 25 @@ -3199,10 +3128,8 @@ this._animateTimer.cancel(); this._animateStep = -1; - this.mAllTabsBoxAnimate.style.opacity = 0.0; -#ifdef XP_MACOSX - this.mDownBoxAnimate.style.opacity = 0.0; -#endif + this._animateElement.style.outlineColor = ""; + this._animateElement.style.outlineStyle = ""; } ]]> @@ -3232,32 +3159,49 @@ selected.left - scrollRect.left); } + this._stopAnimation(); + + const DEFAULT_OPACITY = .7; + var self = this; + this._animateBaseColor = + window.getComputedStyle(this._animateElement, null) + .outlineColor + .replace(/^rgb\((.*)\)$/, "rgba($1, " + DEFAULT_OPACITY + ")") + .replace(/([^, ]*)\)/, function (m0, m1) { + self._animateBaseOpacity = parseFloat(m1); + return "$opacity)"; + }); + // start the flash timer this._animateStep = 0; + var outlineWidth = + Math.ceil(Math.min(this._animateElement.clientHeight, + this._animateElement.clientWidth) * .6) + "px"; + this._animateElement.style.outlineWidth = outlineWidth; + this._animateElement.style.outlineOffset = "-" + outlineWidth; + this._animateElement.style.outlineColor = "rgba(0,0,0,0)"; + this._animateElement.style.outlineStyle = "solid"; + if (!this._animateTimer) this._animateTimer = Components.classes["@mozilla.org/timer;1"] .createInstance(Components.interfaces.nsITimer); - else - this._animateTimer.cancel(); this._animateTimer.initWithCallback(this, this._animateDelay, this._animateTimer.TYPE_REPEATING_SLACK); ]]> - + diff --git a/browser/base/content/test/browser_bug386835.js b/browser/base/content/test/browser_bug386835.js index f4c630cdcbc9..88e78fc8318b 100644 --- a/browser/base/content/test/browser_bug386835.js +++ b/browser/base/content/test/browser_bug386835.js @@ -2,8 +2,8 @@ var gTestPage = "http://example.org/browser/browser/base/content/test/dummy_page var gTestImage = "http://example.org/browser/browser/base/content/test/moz.png"; var gTab1, gTab2, gTab3; var gLevel; -const kBack = 0; -const kForward = 1; +const BACK = 0; +const FORWARD = 1; function test() { waitForExplicitFinish(); @@ -59,8 +59,8 @@ function imageLoaded() { } function imageZoomSwitch() { - navigate(kBack, function() { - navigate(kForward, function() { + navigate(BACK, function () { + navigate(FORWARD, function () { zoomTest(gTab1, 1, "Tab 1 should not be zoomed when an image loads"); gBrowser.selectedTab = gTab2; zoomTest(gTab1, 1, "Tab 1 should still not be zoomed when deselected"); @@ -116,9 +116,9 @@ function testPrintPreview(aTab, aCallback) { aCallback(); }; - let printPreview = new Function(document.getElementById("cmd_printPreview") - .getAttribute("oncommand")); - executeSoon(printPreview); + executeSoon(function () { + document.getElementById("cmd_printPreview").doCommand(); + }); } function finishTest() { @@ -145,12 +145,12 @@ function load(tab, url, cb) { } function navigate(direction, cb) { - gBrowser.addEventListener("pageshow", function(event) { + gBrowser.addEventListener("pageshow", function (event) { gBrowser.removeEventListener("pageshow", arguments.callee, true); - setTimeout(cb, 0); + executeSoon(cb); }, true); - if (direction == kBack) + if (direction == BACK) gBrowser.goBack(); - else if (direction == kForward) + else if (direction == FORWARD) gBrowser.goForward(); } diff --git a/browser/base/content/test/browser_bug416661.js b/browser/base/content/test/browser_bug416661.js index 728a05688a35..5f274a0afbfd 100644 --- a/browser/base/content/test/browser_bug416661.js +++ b/browser/base/content/test/browser_bug416661.js @@ -26,6 +26,7 @@ function continue_test_prefNotSet () { } function end_test_prefNotSet() { + tabElm.linkedBrowser.removeEventListener("load", end_test_prefNotSet, true); is(ZoomManager.zoom, zoomLevel, "the zoom level should have persisted"); // Reset the zoom so that other tests have a fresh zoom level diff --git a/browser/base/content/test/browser_bug427559.js b/browser/base/content/test/browser_bug427559.js index fe5a51e94440..cba1e7cb1501 100644 --- a/browser/base/content/test/browser_bug427559.js +++ b/browser/base/content/test/browser_bug427559.js @@ -49,6 +49,7 @@ function test() { gBrowser.selectedTab = gBrowser.addTab(); gBrowser.selectedBrowser.addEventListener("load", function () { + gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true); setTimeout(function () { var testPageWin = content; diff --git a/browser/base/content/test/browser_bug432599.js b/browser/base/content/test/browser_bug432599.js index 089594be22eb..4749ad872d45 100644 --- a/browser/base/content/test/browser_bug432599.js +++ b/browser/base/content/test/browser_bug432599.js @@ -46,6 +46,7 @@ let invokers = [invokeUsingStarButton, invokeUsingCtrlD]; let currentInvoker = 0; function initTest() { + gBrowser.selectedBrowser.removeEventListener("load", initTest, true); // first, bookmark the page Application.bookmarks.toolbar.addBookmark("Bug 432599 Test", makeURI(testURL)); diff --git a/browser/base/content/test/browser_bug435035.js b/browser/base/content/test/browser_bug435035.js index 9335a38a843a..ae865ef1286a 100644 --- a/browser/base/content/test/browser_bug435035.js +++ b/browser/base/content/test/browser_bug435035.js @@ -3,6 +3,7 @@ function test() { gBrowser.selectedTab = gBrowser.addTab(); gBrowser.selectedBrowser.addEventListener("load", function () { + gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true); is(document.getElementById("identity-box").className, gIdentityHandler.IDENTITY_MODE_MIXED_CONTENT, "identity box has class name for mixed content"); diff --git a/browser/base/content/test/browser_bug477014.js b/browser/base/content/test/browser_bug477014.js index a65d5a35698e..47840eb67f6e 100644 --- a/browser/base/content/test/browser_bug477014.js +++ b/browser/base/content/test/browser_bug477014.js @@ -49,13 +49,11 @@ function test() { // we get here if the test is executed before the pageshow // event for the window's first tab if (!tabToDetach || - tabToDetach.linkedBrowser.contentDocument != event.target) { - return; - } + tabToDetach.linkedBrowser.contentDocument != event.target) + return; if (!newWindow) { - var pageShowFunc = arguments.callee; - gBrowser.removeEventListener("pageshow", pageShowFunc, false); + gBrowser.removeEventListener("pageshow", onPageShow, false); // prepare the tab (set icon and busy state) // we have to set these only after onState* notification, otherwise @@ -69,7 +67,7 @@ function test() { // wait for gBrowser to come along function onLoad(event) { newWindow.gBrowser - .addEventListener("pageshow", pageShowFunc, false); + .addEventListener("pageshow", onPageShow, false); newWindow.removeEventListener("load", arguments.callee, false); } newWindow.addEventListener("load", onLoad, false); diff --git a/browser/base/content/test/browser_bug521216.js b/browser/base/content/test/browser_bug521216.js index d47fefafae32..41bc1062e845 100644 --- a/browser/base/content/test/browser_bug521216.js +++ b/browser/base/content/test/browser_bug521216.js @@ -1,4 +1,4 @@ -var expected = ["TabOpen", "onLinkIconAvailable", "onLocationChange", "onStateChange"]; +var expected = ["TabOpen", "onLocationChange", "onStateChange", "onLinkIconAvailable"]; var actual = []; var tabIndex = -1; __defineGetter__("tab", function () gBrowser.tabContainer.childNodes[tabIndex]); @@ -8,7 +8,7 @@ function test() { tabIndex = gBrowser.tabContainer.childElementCount; gBrowser.addTabsProgressListener(progressListener); gBrowser.tabContainer.addEventListener("TabOpen", TabOpen, false); - gBrowser.addTab("http://example.org/browser/browser/base/content/test/dummy_page.html"); + gBrowser.addTab("data:text/html,"); } function record(aName) { diff --git a/browser/base/content/test/browser_discovery.js b/browser/base/content/test/browser_discovery.js index 1d98f24fbe3e..83db9bcbe62d 100644 --- a/browser/base/content/test/browser_discovery.js +++ b/browser/base/content/test/browser_discovery.js @@ -1,19 +1,16 @@ -var gBrowserHandler; +var currentHandler; var browser; function doc() browser.contentDocument; function setHandlerFunc(aResultFunc) { - DOMLinkHandler.handleEvent = function (event) { - gBrowserHandler.call(DOMLinkHandler, event); - aResultFunc(); - } + if (currentHandler) + gBrowser.removeEventListener("DOMLinkAdded", currentHandler, false); + gBrowser.addEventListener("DOMLinkAdded", aResultFunc, false); + currentHandler = aResultFunc; } function test() { - gBrowserHandler = DOMLinkHandler.handleEvent; - ok(gBrowserHandler, "found browser handler"); - waitForExplicitFinish(); gBrowser.selectedTab = gBrowser.addTab(); @@ -120,10 +117,7 @@ function runMultipleEnginesTestAndFinalize() { is(browser.engines[0].uri, "http://first.mozilla.com/search.xml", "first engine wins"); gBrowser.removeCurrentTab(); - - // Reset the default link handler - DOMLinkHandler.handleEvent = gBrowserHandler; - + gBrowser.removeEventListener("DOMLinkAdded", currentHandler, false); finish(); } diff --git a/browser/base/content/test/browser_pageInfo.js b/browser/base/content/test/browser_pageInfo.js index 97df14f4e247..2953d9f5b9e1 100644 --- a/browser/base/content/test/browser_pageInfo.js +++ b/browser/base/content/test/browser_pageInfo.js @@ -1,20 +1,24 @@ +var obs = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService); + function test() { waitForExplicitFinish(); - var pageInfo, obs, atTest = 0; - var gTestPage = gBrowser.addTab(); - gBrowser.selectedTab = gTestPage; - gTestPage.linkedBrowser.addEventListener("load", handleLoad, true); + var pageInfo, atTest = 0; + gBrowser.selectedTab = gBrowser.addTab(); + gBrowser.selectedBrowser.addEventListener("load", function () { + gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true); + pageInfo = BrowserPageInfo(); + obs.addObserver(observer, "page-info-dialog-loaded", false); + }, true); content.location = "https://example.com/browser/browser/base/content/test/feed_tab.html"; - gTestPage.focus(); var observer = { observe: function(win, topic, data) { if (topic != "page-info-dialog-loaded") return; - switch(atTest) { + switch (atTest) { case 0: atTest++; handlePageInfo(); @@ -33,14 +37,6 @@ function test() { } } - function handleLoad() { - - pageInfo = BrowserPageInfo(); - obs = Components.classes["@mozilla.org/observer-service;1"] - .getService(Components.interfaces.nsIObserverService); - obs.addObserver(observer, "page-info-dialog-loaded", false); - } - function $(aId) { return pageInfo.document.getElementById(aId) }; function handlePageInfo() { @@ -82,17 +78,16 @@ function test() { } function testLockDoubleClick() { - var pageInfoDialogs = Components.classes["@mozilla.org/appshell/window-mediator;1"] - .getService(Components.interfaces.nsIWindowMediator) - .getEnumerator("Browser:page-info"); + var pageInfoDialogs = Cc["@mozilla.org/appshell/window-mediator;1"] + .getService(Ci.nsIWindowMediator) + .getEnumerator("Browser:page-info"); var i = 0; - while(pageInfoDialogs.hasMoreElements()) { + while (pageInfoDialogs.hasMoreElements()) { i++; pageInfo = pageInfoDialogs.getNext(); pageInfo.close(); } is(i, 1, "When the lock is clicked twice there should be only one page info dialog"); - gTestPage.focus(); gBrowser.removeCurrentTab(); finish(); } diff --git a/browser/base/content/utilityOverlay.js b/browser/base/content/utilityOverlay.js index c37cae869851..bd5525e75f77 100644 --- a/browser/base/content/utilityOverlay.js +++ b/browser/base/content/utilityOverlay.js @@ -377,10 +377,8 @@ function openAboutDialog() if (win) win.focus(); else { - // XXXmano: define minimizable=no although it does nothing on OS X - // (see Bug 287162); remove this comment once Bug 287162 is fixed... - window.open("chrome://browser/content/aboutDialog.xul", "About", - "chrome, resizable=no, minimizable=no"); + window.openDialog("chrome://browser/content/aboutDialog.xul", "About", + "chrome, resizable=no, minimizable=no"); } #else window.openDialog("chrome://browser/content/aboutDialog.xul", "About", "centerscreen,chrome,resizable=no"); diff --git a/browser/components/migration/src/nsOperaProfileMigrator.cpp b/browser/components/migration/src/nsOperaProfileMigrator.cpp index c45107dfbf12..906486ff10ff 100644 --- a/browser/components/migration/src/nsOperaProfileMigrator.cpp +++ b/browser/components/migration/src/nsOperaProfileMigrator.cpp @@ -884,7 +884,9 @@ nsOperaCookieMigrator::AddCookieOverride(nsIPermissionManager* aManager) rv = aManager->Add(uri, "cookie", (mCurrHandlingInfo == 1 || mCurrHandlingInfo == 3) ? (PRUint32) nsIPermissionManager::ALLOW_ACTION - : (PRUint32) nsIPermissionManager::DENY_ACTION); + : (PRUint32) nsIPermissionManager::DENY_ACTION, + nsIPermissionManager::EXPIRE_NEVER, + 0); mCurrHandlingInfo = 0; diff --git a/browser/components/nsBrowserGlue.js b/browser/components/nsBrowserGlue.js index 1132877c609e..7c6259949486 100644 --- a/browser/components/nsBrowserGlue.js +++ b/browser/components/nsBrowserGlue.js @@ -78,7 +78,6 @@ const BrowserGlueServiceFactory = { // Constructor function BrowserGlue() { - XPCOMUtils.defineLazyServiceGetter(this, "_prefs", "@mozilla.org/preferences-service;1", "nsIPrefBranch"); @@ -91,14 +90,24 @@ function BrowserGlue() { "@mozilla.org/widget/idleservice;1", "nsIIdleService"); - XPCOMUtils.defineLazyServiceGetter(this, "_observerService", - "@mozilla.org/observer-service;1", - "nsIObserverService"); - XPCOMUtils.defineLazyGetter(this, "_distributionCustomizer", function() { return new DistributionCustomizer(); }); + XPCOMUtils.defineLazyGetter(this, "_sanitizer", + function() { + let sanitizerScope = {}; + Cc["@mozilla.org/moz/jssubscript-loader;1"]. + getService(Ci.mozIJSSubScriptLoader). + loadSubScript("chrome://browser/content/sanitize.js", sanitizerScope); + return sanitizerScope.Sanitizer; + }); + + // The observer service is immediately used in _init(), so there's no reason + // to have a getter. + this._observerService = Cc["@mozilla.org/observer-service;1"]. + getService(Ci.nsIObserverService); + this._init(); } @@ -109,15 +118,17 @@ function BrowserGlue() { #endif BrowserGlue.prototype = { - _saveSession: false, _isIdleObserver: false, _isPlacesInitObserver: false, _isPlacesLockedObserver: false, _isPlacesDatabaseLocked: false, - _setPrefToSaveSession: function() + _setPrefToSaveSession: function(aForce) { + if (!this._saveSession && !aForce) + return; + this._prefs.setBoolPref("browser.sessionstore.resume_session_once", true); // This method can be called via [NSApplication terminate:] on Mac, which @@ -153,12 +164,9 @@ BrowserGlue.prototype = { this._onQuitRequest(subject, data); break; case "quit-application-granted": - if (this._saveSession) { - this._setPrefToSaveSession(); - } - // Everything that uses Places during shutdown should be here, since - // on quit-application Places database connection will be closed - // and history synchronization could fail. + // This pref must be set here because SessionStore will use its value + // on quit-application. + this._setPrefToSaveSession(); this._onProfileShutdown(); break; #ifdef OBSERVE_LASTWINDOW_CLOSE_TOPICS @@ -168,12 +176,11 @@ BrowserGlue.prototype = { this._onQuitRequest(subject, "lastwindow"); break; case "browser-lastwindow-close-granted": - if (this._saveSession) - this._setPrefToSaveSession(); + this._setPrefToSaveSession(); break; #endif case "session-save": - this._setPrefToSaveSession(); + this._setPrefToSaveSession(true); subject.QueryInterface(Ci.nsISupportsPRBool); subject.data = true; break; @@ -191,8 +198,8 @@ BrowserGlue.prototype = { break; case "places-database-locked": this._isPlacesDatabaseLocked = true; - // stop observing, so further attempts to load history service - // do not show the prompt. + // Stop observing, so further attempts to load history service + // will not show the prompt. this._observerService.removeObserver(this, "places-database-locked"); this._isPlacesLockedObserver = false; break; @@ -268,7 +275,7 @@ BrowserGlue.prototype = { // profile startup handler (contains profile initialization routines) _onProfileStartup: function() { - this.Sanitizer.onStartup(); + this._sanitizer.onStartup(); // check if we're in safe mode var app = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULAppInfo). QueryInterface(Ci.nsIXULRuntime); @@ -302,7 +309,8 @@ BrowserGlue.prototype = { } } - this._observerService.notifyObservers(null, "browser-ui-startup-complete", ""); + this._observerService + .notifyObservers(null, "browser-ui-startup-complete", ""); }, // profile shutdown handler (contains profile cleanup routines) @@ -311,7 +319,7 @@ BrowserGlue.prototype = { this._shutdownPlaces(); this._idleService.removeIdleObserver(this, BOOKMARKS_BACKUP_IDLE_TIME); this._isIdleObserver = false; - this.Sanitizer.onShutdown(); + this._sanitizer.onShutdown(); }, // Browser startup complete. All initial windows have opened. @@ -572,17 +580,6 @@ BrowserGlue.prototype = { browser.selectedTab = browser.addTab(updateUrl); }, - // returns the (cached) Sanitizer constructor - get Sanitizer() - { - if(typeof(Sanitizer) != "function") { // we should dynamically load the script - Cc["@mozilla.org/moz/jssubscript-loader;1"]. - getService(Ci.mozIJSSubScriptLoader). - loadSubScript("chrome://browser/content/sanitize.js", null); - } - return Sanitizer; - }, - /** * Initialize Places * - imports the bookmarks html file if bookmarks database is empty, try to @@ -907,7 +904,7 @@ BrowserGlue.prototype = { sanitize: function(aParentWindow) { - this.Sanitizer.sanitize(aParentWindow); + this._sanitizer.sanitize(aParentWindow); }, ensurePlacesDefaultQueriesInitialized: function() { @@ -921,7 +918,7 @@ BrowserGlue.prototype = { const SMART_BOOKMARKS_ANNO = "Places/SmartBookmark"; const SMART_BOOKMARKS_PREF = "browser.places.smartBookmarksVersion"; - // XXX should this be a pref? see bug #399268 + // TODO bug 399268: should this be a pref? const MAX_RESULTS = 10; // get current smart bookmarks version diff --git a/browser/components/places/content/advancedSearch.inc b/browser/components/places/content/advancedSearch.inc deleted file mode 100644 index 4c358afc998e..000000000000 --- a/browser/components/places/content/advancedSearch.inc +++ /dev/null @@ -1,165 +0,0 @@ -# ***** 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 the Places Organizer Query Builder. -# -# The Initial Developer of the Original Code is Google Inc. -# Portions created by the Initial Developer are Copyright (C) 2006 -# the Initial Developer. All Rights Reserved. -# -# Contributor(s): -# Annie Sullivan -# -# 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 ***** - - - - - - - - - - - - -