Merge mozilla-central to electrolysis.

This commit is contained in:
Benjamin Smedberg 2009-10-20 12:08:28 -04:00
Родитель 57879814f0 ea120921fe
Коммит 9ae75c423f
1271 изменённых файлов: 11388 добавлений и 35688 удалений

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

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

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

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

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

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

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

@ -408,14 +408,30 @@ nsAccUtils::GetARIATreeItemParent(nsIAccessible *aStartTreeItem,
nsIAccessible **aTreeItemParentResult)
{
*aTreeItemParentResult = nsnull;
nsCOMPtr<nsIAccessible> 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<nsIAccessible> 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<nsIDOMNode> treeItemNode;
accessNode->GetDOMNode(getter_AddRefs(treeItemNode));
nsCOMPtr<nsIContent> 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<nsIAccessible> 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<nsIAccessible> prevAccessible;
parentAccessible->GetPreviousSibling(getter_AddRefs(prevAccessible));
if (!prevAccessible)

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

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

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

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

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

@ -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<nsIAccessible> accTarget;
nsAccUtils::GetARIATreeItemParent(this, content,
getter_AddRefs(accTarget));
return nsRelUtils::AddTarget(aRelationType, aRelation, accTarget);
}

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

@ -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<nsIDOMElement> cellElement;
rv = GetCellAt(aRow, aColumn, *getter_AddRefs(cellElement));
nsresult rv = GetCellAt(aRow, aColumn, *getter_AddRefs(cellElement));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIAccessibilityService>
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)
{

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

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

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

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

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

@ -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<nsIAccessible> 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)
{

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

@ -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<nsIAccessible> mNativeAccessible;

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

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

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

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

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

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

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

@ -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!");
}
}
/**

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

@ -0,0 +1,54 @@
<!DOCTYPE html>
<html>
<head>
<title>Plugin tests</title>
<link rel="stylesheet" type="text/css"
href="chrome://mochikit/content/tests/SimpleTest/test.css" />
<script type="application/javascript"
src="chrome://mochikit/content/MochiKit/packed.js"></script>
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript"
src="chrome://mochikit/content/a11y/accessible/common.js"></script>
<script type="application/javascript"
src="chrome://mochikit/content/a11y/accessible/role.js"></script>
<script type="application/javascript"
src="chrome://mochikit/content/a11y/accessible/states.js"></script>
<script type="application/javascript">
function doTest()
{
if (!WIN) {
ok(true,
"Nothing to test because accessible plugins are supported on Windows only");
SimpleTest.finish();
return;
}
testRole("plugin", ROLE_EMBEDDED_OBJECT);
testStates("plugin", STATE_UNAVAILABLE);
SimpleTest.finish();
}
SimpleTest.waitForExplicitFinish();
addA11yLoadEvent(doTest);
</script>
</head>
<body>
<a target="_blank"
title="embed and object HTML tags should be given an accessible role of embedded object"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=485270">Mozilla Bug 485270</a>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
</pre>
<embed id="plugin" type="application/x-test" width="300" height="300"></embed>
</body>
</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 @@
<div role="treeitem" id="treeitem3">Blue</div>
<div role="treeitem" id="treeitem4" aria-level="1">Green</div>
<div role="treeitem" id="treeitem5" aria-level="2">Light green</div>
<div role="group">
<div role="treeitem" id="treeitem6">Super light green</div>
</div>
</div>
<div role="treegrid" id="treegrid">
<div role="row" id="treegridrow1">
<span role="gridcell">cell1</span><span role="gridcell">cell2</span>
</div>
<div role="row" id="treegridrow2" aria-level="1">
<span role="gridcell">cell3</span><span role="gridcell">cell4</span>
</div>
<div role="row" id="treegridrow3" aria-level="2">
<span role="gridcell">cell5</span><span role="gridcell">cell6</span>
</div>
</div>
<iframe id="iframe"></iframe>

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

@ -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 @@
<div id="offscreen_log" role="log" class="offscreen">
<div id="aria_offscreen_textbox" role="textbox" aria-readonly="true">This text should be offscreen</div>
</div>
<a id="aria_menuitem_link" role="menuitem" href="foo">menuitem</a>
<a id="aria_button_link" role="button" href="foo">button</a>
<a id="aria_checkbox_link" role="checkbox" href="foo">checkbox</a>
<!-- strange edge case: please don't do this in the wild -->
<a id="aria_link_link" role="link" href="foo">link</a>
<a id="aria_link_anchor" role="link" name="link_anchor">link</a>
<!-- landmarks: links -->
<a id="aria_application_link" role="application" href="foo">app</a>
<a id="aria_main_link" role="main" href="foo">main</a>
<a id="aria_navigation_link" role="navigation" href="foo">nav</a>
<!-- landmarks: anchors -->
<a id="aria_application_anchor" role="application" name="app_anchor">app</a>
<a id="aria_main_anchor" role="main" name="main_anchor">main</a>
<a id="aria_navigation_anchor" role="navigation" name="nav_anchor">nav</a>
</body>
</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
</a>
<a target="_blank"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=501659"
title="HTML table's isRowSelected/isColumnSelected shouldn't fail if row or column has cell holes">
Mozilla Bug 501659
</a>
<p id="display"></p>
<div id="content" style="display: none"></div>
@ -122,6 +144,37 @@
</tr>
</tbody>
</table>
<table border="1" id="tableinsane">
<thead>
<tr>
<th>col1</th>
<th>col2</th>
<th>col3</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
</tr>
<tr>
<td rowspan="3">4</td>
<td colspan="4">5</td>
</tr>
<tr>
<td>6</td>
<td rowspan="2">7</td>
</tr>
<tr>
<td>8</td>
<td>9</td>
<td>10</td>
</tr>
</tbody>
</table>
</center>
</body>
</html>

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

@ -0,0 +1,81 @@
<html>
<head>
<title>nsIAccessible value testing</title>
<link rel="stylesheet" type="text/css"
href="chrome://mochikit/content/tests/SimpleTest/test.css" />
<style type="text/css">
.offscreen {
position: absolute;
left: -5000px;
top: -5000px;
height: 100px;
width: 100px;
}
</style>
<script type="application/javascript"
src="chrome://mochikit/content/MochiKit/packed.js"></script>
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript"
src="chrome://mochikit/content/a11y/accessible/common.js"></script>
<script type="application/javascript">
function doTest()
{
function testValue(aID, aValue)
{
var acc = getAccessible(aID);
if (!acc)
return;
is(acc.value, aValue, "Wrong value for " + aID + "!");
}
var href = "chrome://mochikit/content/a11y/accessible/foo";
// roles that can't live as nsHTMLLinkAccessibles
testValue("aria_menuitem_link", "");
testValue("aria_button_link", "");
testValue("aria_checkbox_link", "");
testValue("aria_application_link", "");
// roles that can live as nsHTMLLinkAccessibles
testValue("aria_link_link", href);
testValue("aria_main_link", href);
testValue("aria_navigation_link", href);
SimpleTest.finish();
}
SimpleTest.waitForExplicitFinish();
addA11yLoadEvent(doTest);
</script>
</head>
<body>
<a target="_blank"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=494807"
title="Do not expose a11y info specific to hyperlinks when role is overridden using ARIA">
Mozilla Bug 494807
</a><br />
<a id="aria_menuitem_link" role="menuitem" href="foo">menuitem</a>
<a id="aria_button_link" role="button" href="foo">button</a>
<a id="aria_checkbox_link" role="checkbox" href="foo">checkbox</a>
<!-- landmark links -->
<a id="aria_application_link" role="application" href="foo">app</a>
<a id="aria_main_link" role="main" href="foo">main</a>
<a id="aria_navigation_link" role="navigation" href="foo">nav</a>
<!-- strange edge case: please don't do this in the wild -->
<a id="aria_link_link" role="link" href="foo">link</a>
</body>
</html>

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

@ -298,9 +298,6 @@ libs::
endif
endif
libs::
touch $(DIST)/bin/.autoreg
libs:: $(srcdir)/profile/prefs.js
$(INSTALL) $(IFLAGS1) $^ $(DIST)/bin/defaults/profile

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

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

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

@ -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();
}
]]></script>
</head>
@ -369,10 +441,17 @@ function generateTextForTextNode(node, indent, textFragmentAccumulator) {
&aboutSupport.appBasicsProfileDir;
</th>
<td id="profile-box">
<td>
<button onclick="openProfileDirectory()">
#ifdef XP_MACOSX
&aboutSupport.showMac.label;
#else
&aboutSupport.show.label;
#endif
</button>
</td>
</tr>
<tr>
<th class="column">
&aboutSupport.appBasicsPlugins;

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

@ -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;
},
/**

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

@ -289,7 +289,7 @@
<image id="thepreviewimage"/>
</hbox>
<hbox id="brokenimagecontainer" pack="center" collapsed="true">
<image id="brokenimage" src="resource:///res/broken-image.png"/>
<image id="brokenimage" src="resource://gre-resources/broken-image.png"/>
</hbox>
</vbox>
</vbox>

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

@ -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;
]]></body>
</method>
#ifdef XP_MACOSX
<field name="_scrollButtonDownBox">
document.getAnonymousElementByAttribute(this, "anonid", "down-box");
</field>
<field name="_scrollButtonDownBoxAnimate">
document.getAnonymousElementByAttribute(this, "anonid", "down-box-animate");
</field>
#endif
</implementation>
<handlers>
@ -2882,10 +2874,6 @@
var tabs = document.getBindingParent(this);
tabs.removeAttribute("overflow");
#ifdef XP_MACOSX
this._scrollButtonDownBox.collapsed = true;
this._scrollButtonDownBoxAnimate.collapsed = true;
#endif
]]></handler>
<handler event="overflow"><![CDATA[
if (event.detail == 0)
@ -2893,59 +2881,9 @@
var tabs = document.getBindingParent(this);
tabs.setAttribute("overflow", "true");
#ifdef XP_MACOSX
this._scrollButtonDownBox.collapsed = false;
this._scrollButtonDownBoxAnimate.collapsed = false;
#endif
this.ensureElementIsVisible(tabs.selectedItem, false);
]]></handler>
#ifdef XP_MACOSX
<handler event="UpdatedScrollButtonsDisabledState"><![CDATA[
// fix for bug #352353
// unlike the scrollup button on the tab strip (which is a
// simple toolbarbutton) the scrolldown button is
// a more complicated stack of boxes and a toolbarbutton
// so that we can animate when a tab is opened offscreen.
// in order to style the box with the actual background image
// we need to manually set the disable state to match the
// disable state of the toolbarbutton.
this._scrollButtonDownBox
.setAttribute("disabled", this._scrollButtonDown.disabled);
]]></handler>
#endif
</handlers>
#ifdef XP_MACOSX
<content>
<xul:toolbarbutton class="scrollbutton-up" collapsed="true"
xbl:inherits="orient"
anonid="scrollbutton-up"
onclick="_distanceScroll(event);"
onmousedown="_startScroll(-1);"
onmouseover="_continueScroll(-1);"
onmouseup="_stopScroll();"
onmouseout="_pauseScroll();"/>
<xul:scrollbox xbl:inherits="orient,align,pack,dir" flex="1" anonid="scrollbox">
<children/>
</xul:scrollbox>
<xul:stack align="center" pack="end" class="scrollbutton-down-stack">
<xul:hbox flex="1" class="scrollbutton-down-box"
collapsed="true" anonid="down-box"/>
<xul:hbox flex="1" class="scrollbutton-down-box-animate"
collapsed="true" anonid="down-box-animate"/>
<xul:toolbarbutton class="scrollbutton-down" collapsed="true"
xbl:inherits="orient"
anonid="scrollbutton-down"
onclick="_distanceScroll(event);"
onmousedown="_startScroll(1);"
onmouseover="_continueScroll(1);"
onmouseup="_stopScroll();"
onmouseout="_pauseScroll();"/>
</xul:stack>
</content>
#endif
</binding>
<binding id="tabbrowser-tabs"
@ -2981,15 +2919,12 @@
<xul:toolbarbutton class="tabs-newtab-button" anonid="newtab-button"
command="cmd_newNavigatorTab"
tooltiptext="&newTabButton.tooltip;"/>
<xul:stack align="center" pack="end">
<xul:hbox flex="1" class="tabs-alltabs-box-animate" anonid="alltabs-box-animate"/>
<xul:toolbarbutton class="tabs-alltabs-button" anonid="alltabs-button"
type="menu"
tooltiptext="&listAllTabs.label;">
<xul:menupopup class="tabs-alltabs-popup" anonid="alltabs-popup"
position="after_end"/>
</xul:toolbarbutton>
</xul:stack>
<xul:toolbarbutton class="tabs-alltabs-button" anonid="alltabs-button"
type="menu"
tooltiptext="&listAllTabs.label;">
<xul:menupopup class="tabs-alltabs-popup" anonid="alltabs-popup"
position="after_end"/>
</xul:toolbarbutton>
<xul:toolbarbutton anonid="tabs-closebutton"
class="close-button tabs-closebutton"/>
</xul:hbox>
@ -3168,19 +3103,13 @@
"anonid", "alltabs-popup");
</field>
<field name="mAllTabsBoxAnimate">
document.getAnonymousElementByAttribute(this,
"anonid",
"alltabs-box-animate");
<field name="_animateElement">
this.mTabstrip._scrollButtonDown;
</field>
#ifdef XP_MACOSX
<field name="mDownBoxAnimate">
this.mTabstrip._scrollButtonDownBoxAnimate;
</field>
#endif
<field name="_animateTimer">null</field>
<field name="_animateBaseOpacity">null</field>
<field name="_animateBaseColor">null</field>
<field name="_animateStep">-1</field>
<field name="_animateDelay">25</field>
<field name="_animatePercents">
@ -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 = "";
}
]]></body>
</method>
@ -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);
]]></body>
</method>
<method name="notify">
<parameter name="aTimer"/>
<body><![CDATA[
if (!document)
aTimer.cancel();
var percent = this._animatePercents[this._animateStep];
this.mAllTabsBoxAnimate.style.opacity = percent;
#ifdef XP_MACOSX
this.mDownBoxAnimate.style.opacity = percent;
#endif
var opacity = this._animateBaseOpacity * this._animatePercents[this._animateStep];
this._animateElement.style.outlineColor =
this._animateBaseColor.replace("$opacity", opacity);
if (this._animateStep < (this._animatePercents.length - 1))
this._animateStep++;
@ -3527,14 +3471,9 @@
var tabs = tabcontainer.childNodes;
// Listen for changes in the tab bar.
var tabbrowser = document.getBindingParent(tabcontainer);
tabbrowser.addEventListener("TabOpen", this, false);
tabcontainer.addEventListener("TabOpen", this, false);
tabcontainer.mTabstrip.addEventListener("scroll", this, false);
// if an animation is in progress and the user
// clicks on the "all tabs" button, stop the animation
tabcontainer._stopAnimation();
for (var i = 0; i < tabs.length; i++) {
this._createTabMenuItem(tabs[i]);
}
@ -3554,7 +3493,7 @@
}
var tabcontainer = document.getBindingParent(this);
tabcontainer.mTabstrip.removeEventListener("scroll", this, false);
document.getBindingParent(tabcontainer).removeEventListener("TabOpen", this, false);
tabcontainer.removeEventListener("TabOpen", this, false);
]]></handler>
<handler event="DOMMenuItemActive">

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

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

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

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

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

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

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

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

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

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

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

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

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

@ -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,<html><head><link href='about:logo' rel='shortcut icon'>");
}
function record(aName) {

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

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

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

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

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

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

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

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

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

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

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

@ -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 <annie.sullivan@gmail.com>
#
# Alternatively, the contents of this file may be used under the terms of
# either the GNU General Public License Version 2 or later (the "GPL"), or
# 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 *****
<vbox id="advancedSearch">
<hbox align="center">
<label value="&advancedSearch.match.label;" control="advancedSearchType"/>
<menulist id="advancedSearchType"
oncommand="PlacesQueryBuilder.doSearch();">
<menupopup>
<menuitem value="and" label="&advancedSearch.all.label;"/>
<menuitem value="or" label="&advancedSearch.any.label;"/>
</menupopup>
</menulist>
<label value="&advancedSearch.rules.label;"/>
</hbox>
<grid flex="1">
<columns>
<column flex="1"/>
<column flex="1"/>
<column flex="0"/>
<column flex="0"/>
</columns>
<rows id="advancedSearchRows">
<row id="advancedSearch0Row" flex="1" hidden="true">
<menulist id="advancedSearch0Subject" flex="1">
<menupopup>
<menuitem value="keyword"
label="&advancedSearch.subj_keyword.label;"
selected="true"
rowid="1"
id="advancedSearch0SubjectKeyword"
oncommand="PlacesQueryBuilder.showSearch(this.getAttribute('rowid'), PlacesQueryBuilder._keywordSearch);"/>
<menuitem value="visited"
label="&advancedSearch.subj_visited.label;"
rowid="1"
id="advancedSearch0SubjectVisited"
oncommand="PlacesQueryBuilder.showSearch(this.getAttribute('rowid'), PlacesQueryBuilder._timeSearch);"/>
<menuitem value="location"
label="&advancedSearch.subj_location.label;"
rowid="1"
id="advancedSearch0SubjectLocation"
oncommand="PlacesQueryBuilder.showSearch(this.getAttribute('rowid'), PlacesQueryBuilder._locationSearch);"/>
</menupopup>
</menulist>
<hbox flex="1" align="center">
<menulist id="advancedSearch0LocationMenulist"
oncommand="PlacesQueryBuilder.doSearch();"
hidden="true">
<menupopup>
<menuitem id="advancedSearch0LocationMenuSelected"
value="startswith"
label="&advancedSearch.location_startswith.label;"
selected="true"/>
<menuitem value="is"
label="&advancedSearch.location_is.label;"/>
<menuitem value="onsite"
label="&advancedSearch.location_onsite.label;"/>
</menupopup>
</menulist>
<menulist id="advancedSearch0TimeMenulist" hidden="true">
<menupopup>
<menuitem value="on"
id="advancedSearch0TimeDefault"
label="&advancedSearch.time_is.label;"
selected="true"
rowid="1"
oncommand="PlacesQueryBuilder.showSearch(this.getAttribute('rowid'), PlacesQueryBuilder._timeSearch);"/>
<menuitem value="before"
label="&advancedSearch.time_before.label;"
rowid="1"
oncommand="PlacesQueryBuilder.showSearch(this.getAttribute('rowid'), PlacesQueryBuilder._timeSearch);"/>
<menuitem value="after"
label="&advancedSearch.time_after.label;"
rowid="1"
oncommand="PlacesQueryBuilder.showSearch(this.getAttribute('rowid'), PlacesQueryBuilder._timeSearch);"/>
<menuitem value="inLast"
label="&advancedSearch.time_inlast.label;"
rowid="1"
oncommand="PlacesQueryBuilder.showSearch(this.getAttribute('rowid'), PlacesQueryBuilder._timeInLastSearch);"/>
</menupopup>
</menulist>
<textbox type="search"
timeout="50"
id="advancedSearch0Textbox"
flex="1"
oncommand="PlacesQueryBuilder.doSearch();"/>
<textbox type="search"
timeout="50"
id="advancedSearch0TimePicker"
hidden="true" flex="1"
rowid="1"
oncommand="PlacesQueryBuilder.onDateTyped(event, this.getAttribute('rowid'));"
onclick="PlacesQueryBuilder.handleTimePickerClick(event, this.getAttribute('rowid'));"/>
<popup id="advancedSearch0DatePopup"
onpopupshowing="this.setAttribute('showing', true);"
onpopuphidden="this.removeAttribute('showing');">
<vbox id="advancedSearch0Calendar"
class="history-calendar"
rowid="1"
onselectionchanged="return PlacesQueryBuilder.onCalendarChanged(event, event.target.getAttribute('rowid'));"/>
</popup>
<menulist id="advancedSearch0TimeMenulist2"
oncommand="PlacesQueryBuilder.doSearch();"
hidden="true">
<menupopup>
<menuitem value="days"
label="&advancedSearch.last_days.label;"
selected="true"/>
<menuitem value="weeks"
label="&advancedSearch.last_weeks.label;"/>
<menuitem value="months"
label="&advancedSearch.last_months.label;"/>
</menupopup>
</menulist>
</hbox>
<button id="advancedSearch0Minus"
label="&advancedSearch.minus.label;"
class="small advancedSearchMinus"
oncommand="PlacesQueryBuilder.removeRow(event.target.parentNode);"/>
<button id="advancedSearch0Plus"
label="&advancedSearch.plus.label;"
class="small advancedSearchPlus"
command="OrganizerCommand_search:moreCriteria"/>
</row>
</rows>
</grid>
</vbox>

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

@ -1,5 +0,0 @@
.day1 { background-color:white; }
.day2 { background-color:#EEE; }
.green { background-color:green; }
.red { background-color:red; }

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

@ -1,20 +0,0 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<html>
<head>
<title></title>
<style type="text/css">
body { background-color:white; color:black; font-family:verdana,helvetica;}
.item { font-size:9pt; padding:3px; padding-top:0px; margin-top:0px; }
.itemnew { font-size:9pt; padding:3px; margin-left:5em; border-top:1px dotted #888; padding-top:0px; }
.time { font-size:7pt; border-top:2px solid black; margin-top:10px; margin-bottom:2px; font-weight:bold; }
.host { font-size:7pt; font-weight:bold; color:#888; width:8em; overflow:hidden; }
.title { margin:0px; padding:2px; }
.url { font-size:7pt; color:#080; padding-left:12em; }
.favicon { padding-right:8px; position:relative; top:2px; }
</style>
</head>
<body>
</body>
</html>

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

@ -1,297 +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 Mozilla Places
*
* 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):
* Brett Wilson <brettw@gmail.com> (original author)
*
* 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 ***** */
window.addEventListener("load", BW_startup, false);
var BW_frame;
var BW_historyService = Components.classes["@mozilla.org/browser/nav-history-service;1"].
getService(Components.interfaces.nsINavHistoryService);
var BW_result;
var loadedIframe = false;
var loadedBretts = false;
function BW_startup() {
BW_frame = document.getElementById("theframe");
var options = BW_historyService.getNewQueryOptions();
options.sortingMode = options.SORT_BY_DATE_DESCENDING;
options.resultType = options.RESULTS_AS_VISIT;
options.maxResults = 200;
var query = BW_historyService.getNewQuery();
BW_result = BW_historyService.executeQuery(query, options);
BW_result.root.containerOpen = true;
BW_frame.contentWindow.addEventListener("load", BW_fill, true);
loadedBretts = true;
if (loadedIframe && loadedBretts)
BW_fill();
//BW_frame.onload = BW_fill;
//BW_frame.contentDocument.onLoad = BW_fill;
//BW_fill();
}
function BW_loadiframe() {
loadedIframe = true;
if (loadedIframe && loadedBretts)
BW_fill();
}
function BW_getTLD(host) {
var count = 0;
for (var i = host.length - 2; i > 0; i --) {
if (host[i] == '.') {
count ++;
if (count == 2) {
return host.substr(i + 1);
}
}
}
return host;
}
var BW_filled = false;
function BW_fill() {
if (BW_filled)
return;
BW_filled = true;
BW_frame.setAttribute('onload', '');
var container = BW_result.root;
var length = container.childCount;
dump("doc = " + BW_frame.contentDocument + "\n");
var doc = BW_frame.contentDocument;
var ios = Components.classes["@mozilla.org/network/io-service;1"].
getService(Components.interfaces.nsIIOService);
var dateformat = Components.classes["@mozilla.org/intl/scriptabledateformat;1"]
.getService(Components.interfaces.nsIScriptableDateFormat);
var table = doc.createElement('table');
doc.body.appendChild(table);
var counts = new Array(240);
for (var i = 0; i < counts.length; i ++) {
counts[i] = 0;
}
var now = new Date();
now.setHours(0);
now.setMinutes(0);
now.setSeconds(0);
now.setMilliseconds(0);
now.setDate(now.getDate()+1);
var tonightUS = now.getTime() * 1000;
var usPerHour = 3600000000;
var previousSession = -1;
var previousMS = 18437736874454810627;
var previousHost = "";
for (var i = 0; i < length; i ++) {
var child = container.getChild(i);
child.QueryInterface(Components.interfaces.nsINavHistoryVisitResultNode);
var session = child.sessionId;
var thisBin = Math.floor((tonightUS - child.time) / usPerHour);
if (thisBin >= 0 && thisBin < counts.length) {
counts[thisBin] = counts[thisBin] + 1;
}
var ms = child.time / 1000;
var addedTime = false;
if (previousMS - ms > 600000) {
addedTime = true;
var t = new Date(ms);
var tr = doc.createElement('tr');
table.appendChild(tr);
var td = doc.createElement('td');
td.setAttribute('colspan', '2');
td.setAttribute('class', 'time');
tr.appendChild(td);
var timestring = dateformat.FormatDateTime("",
dateformat.dateFormatShort,
dateformat.timeFormatNoSeconds,
t.getFullYear(),
t.getMonth(),
t.getDate(),
t.getHours(),
t.getMinutes(),
0);
var timetext = doc.createTextNode(timestring);
td.appendChild(timetext);
}
previousMS = ms;
var tr = doc.createElement('tr');
table.appendChild(tr);
// URL
var spec;
var uri;
try {
spec = child.uri;
uri = ios.newURI(spec, null, null);
} catch(e) {
spec = null;
uri = null;
}
// host name if needed on left
var td = doc.createElement('td');
td.setAttribute('valign', 'top');
td.setAttribute('align', 'right');
td.setAttribute('class', 'host');
tr.appendChild(td);
var host = BW_getTLD(uri.host);
if (addedTime || host != previousHost) {
// add host name
var hosttext = doc.createTextNode(host);
td.appendChild(hosttext);
}
previousHost = host;
// right section
var td = doc.createElement('td');
td.setAttribute('valign', 'top');
tr.appendChild(td);
if (! addedTime && (i == 0 || child.sessionId != previousSession))
td.setAttribute('class', 'itemnew');
else
td.setAttribute('class', 'item');
previousSession = session;
// title div and text
var titlediv = doc.createElement('div');
titlediv.setAttribute('class', 'title');
var imgelt = doc.createElement('img');
if (child.icon)
imgelt.setAttribute('src', child.icon.spec);
else
imgelt.setAttribute('src', 'chrome://browser/skin/places/defaultFavicon.png');
imgelt.setAttribute('width', 16);
imgelt.setAttribute('height', 16);
imgelt.setAttribute('class', 'favicon');
titlediv.appendChild(imgelt);
var titletext = doc.createTextNode(child.title);
titlediv.appendChild(titletext);
td.appendChild(titlediv);
// URL
if (spec) {
/* // this does bold host names
var host = uri.host;
var hostStart = spec.indexOf(host);
if (hostStart >= 0) {
var prehost = spec.substring(0, hostStart);
var prehosttext = doc.createTextNode(prehost);
var posthost = spec.substring(hostStart + host.length, spec.length);
var posthosttext = doc.createTextNode(posthost);
var hosttext = doc.createTextNode(host);
var boldElement = doc.createElement('b');
boldElement.appendChild(hosttext);
var urldiv = doc.createElement('div');
urldiv.setAttribute('class', 'url');
urldiv.appendChild(prehosttext);
urldiv.appendChild(boldElement);
urldiv.appendChild(posthosttext);
td.appendChild(urldiv);
}
*/
var urldiv = doc.createElement('div');
urldiv.setAttribute('class', 'url');
var urltext = doc.createTextNode(spec);
urldiv.appendChild(urltext);
td.appendChild(urldiv);
}
}
// smooth the counts
var counts2 = new Array(counts.length);
for (var i = 0; i < counts.length; i ++) {
var ttl = 0;
var acc = 0;
for (var j = -2; j <= 2; j ++) {
if (i + j < 0) continue;
if (i + j >= counts.length) continue;
var scale;
if (j == -2 || j == 2) scale = 0.33;
else if (j == -1 || j == 1) scale = 0.66;
else scale = 1.0;
acc += counts[i+j] * scale;
ttl += scale;
}
counts2[i] = Math.round(acc);
}
// fill in the day bargraphs
var daylist = document.getElementById("daylist");
for (var i = 0; i < counts2.length / 24; i ++) {
var day = document.createElement('hbox');
day.setAttribute('align', 'center');
if (i % 2)
day.setAttribute('class', 'day2');
else
day.setAttribute('class', 'day1');
daylist.appendChild(day);
var text = document.createTextNode("Today - " + i );
var description = document.createElement('description');
description.setAttribute('flex', '1');
description.appendChild(text);
day.appendChild(description);
var bars = document.createElement('vbox');
bars.setAttribute('align', 'end');
day.appendChild(bars);
for (var b = 0; b < 24; b++) {
var box = document.createElement('hbox');
box.setAttribute('width', '' + counts2[i*24 + b]);
box.setAttribute('height', '1');
box.setAttribute('class', 'green');
bars.appendChild(box);
}
}
}

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

@ -1,9 +1,3 @@
%ifdef PLACES_QUERY_BUILDER
.history-calendar {
-moz-binding: url("chrome://browser/content/places/places.xml#calendar");
}
%endif
#contentTitle {
width: 0px;
}

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

@ -88,11 +88,6 @@ var PlacesOrganizer = {
// Set up the search UI.
PlacesSearchBox.init();
#ifdef PLACES_QUERY_BUILDER
// Set up the advanced query builder UI
PlacesQueryBuilder.init();
#endif
window.addEventListener("AppCommand", this, true);
#ifdef XP_MACOSX
// 1. Map Edit->Find command to OrganizerCommand_find:all. Need to map
@ -788,12 +783,7 @@ var PlacesOrganizer = {
// Get the place: uri for the query.
// If the advanced query builder is showing, use that.
var options = this.getCurrentOptions();
#ifdef PLACES_QUERY_BUILDER
var queries = PlacesQueryBuilder.queries;
#else
var queries = this.getCurrentQueries();
#endif
var placeSpec = PlacesUtils.history.queriesToQueryString(queries,
queries.length,
@ -997,12 +987,6 @@ var PlacesSearchBox = {
// Hide the advanced search controls when the user hasn't searched
var searchModifiers = document.getElementById("searchModifiers");
searchModifiers.hidden = false;
#ifdef PLACES_QUERY_BUILDER
// if new search, open builder with pre-populated text row
if (PlacesQueryBuilder.numRows == 0)
document.getElementById("OrganizerCommand_search:moreCriteria").doCommand();
#endif
},
hideSearchUI: function PSB_hideSearchUI() {
@ -1019,470 +1003,6 @@ var PlacesQueryBuilder = {
queries: [],
queryOptions: null,
#ifdef PLACES_QUERY_BUILDER
numRows: 0,
/**
* The maximum number of terms that can be added.
*/
_maxRows: null,
_keywordSearch: {
advancedSearch_N_Subject: "advancedSearch_N_SubjectKeyword",
advancedSearch_N_LocationMenulist: false,
advancedSearch_N_TimeMenulist: false,
advancedSearch_N_Textbox: "",
advancedSearch_N_TimePicker: false,
advancedSearch_N_TimeMenulist2: false
},
_locationSearch: {
advancedSearch_N_Subject: "advancedSearch_N_SubjectLocation",
advancedSearch_N_LocationMenulist: "advancedSearch_N_LocationMenuSelected",
advancedSearch_N_TimeMenulist: false,
advancedSearch_N_Textbox: "",
advancedSearch_N_TimePicker: false,
advancedSearch_N_TimeMenulist2: false
},
_timeSearch: {
advancedSearch_N_Subject: "advancedSearch_N_SubjectVisited",
advancedSearch_N_LocationMenulist: false,
advancedSearch_N_TimeMenulist: true,
advancedSearch_N_Textbox: false,
advancedSearch_N_TimePicker: "date",
advancedSearch_N_TimeMenulist2: false
},
_timeInLastSearch: {
advancedSearch_N_Subject: "advancedSearch_N_SubjectVisited",
advancedSearch_N_LocationMenulist: false,
advancedSearch_N_TimeMenulist: true,
advancedSearch_N_Textbox: "7",
advancedSearch_N_TimePicker: false,
advancedSearch_N_TimeMenulist2: true
},
_nextSearch: null,
_queryBuilders: null,
init: function PQB_init() {
// Initialize advanced search
this._nextSearch = {
"keyword": this._timeSearch,
"visited": this._locationSearch,
"location": null
};
this._queryBuilders = {
"keyword": this.setKeywordQuery,
"visited": this.setVisitedQuery,
"location": this.setLocationQuery
};
this._maxRows = this._queryBuilders.length;
this._dateService = Cc["@mozilla.org/intl/scriptabledateformat;1"].
getService(Ci.nsIScriptableDateFormat);
},
/**
* Hides the query builder, and the match rule UI if visible.
*/
hide: function PQB_hide() {
var advancedSearch = document.getElementById("advancedSearch");
// Need to collapse the advanced search box.
advancedSearch.collapsed = true;
},
/**
* Shows the query builder
*/
show: function PQB_show() {
var advancedSearch = document.getElementById("advancedSearch");
advancedSearch.collapsed = false;
},
toggleVisibility: function ABP_toggleVisibility() {
var expander = document.getElementById("organizerScopeBarExpander");
var advancedSearch = document.getElementById("advancedSearch");
if (advancedSearch.collapsed) {
advancedSearch.collapsed = false;
expander.className = "expander-down";
expander.setAttribute("tooltiptext",
expander.getAttribute("tooltiptextdown"));
}
else {
advancedSearch.collapsed = true;
expander.className = "expander-up"
expander.setAttribute("tooltiptext",
expander.getAttribute("tooltiptextup"));
}
},
/**
* Includes the rowId in the id attribute of an element in a row newly
* created from the template row.
* @param element
* The element whose id attribute needs to be updated.
* @param rowId
* The index of the new row.
*/
_setRowId: function PQB__setRowId(element, rowId) {
if (element.id)
element.id = element.id.replace("advancedSearch0", "advancedSearch" + rowId);
if (element.hasAttribute("rowid"))
element.setAttribute("rowid", rowId);
for (var i = 0; i < element.childNodes.length; ++i) {
this._setRowId(element.childNodes[i], rowId);
}
},
_updateUIForRowChange: function PQB__updateUIForRowChange() {
// Update the "can add more criteria" command to make sure various +
// buttons are disabled.
var command = document.getElementById("OrganizerCommand_search:moreCriteria");
if (this.numRows >= this._maxRows)
command.setAttribute("disabled", "true");
else
command.removeAttribute("disabled");
},
/**
* Adds a row to the view, prefilled with the next query subject. If the
* query builder is not visible, it will be shown.
*/
addRow: function PQB_addRow() {
// Limits the number of rows that can be added based on the maximum number
// of search query subjects.
if (this.numRows >= this._maxRows)
return;
// Clone the template row and unset the hidden attribute.
var gridRows = document.getElementById("advancedSearchRows");
var newRow = gridRows.firstChild.cloneNode(true);
newRow.hidden = false;
// Determine what the search type is based on the last visible row. If this
// is the first row, the type is "keyword search". Otherwise, it's the next
// in the sequence after the one defined by the previous visible row's
// Subject selector, as defined in _nextSearch.
var searchType = this._keywordSearch;
var lastMenu = document.getElementById("advancedSearch" +
this.numRows +
"Subject");
if (this.numRows > 0 && lastMenu && lastMenu.selectedItem)
searchType = this._nextSearch[lastMenu.selectedItem.value];
// There is no "next" search type. We are here in error.
if (!searchType)
return;
// We don't insert into the document until _after_ the searchType is
// determined, since this will interfere with the computation.
gridRows.appendChild(newRow);
this._setRowId(newRow, ++this.numRows);
// Ensure the Advanced Search container is visible, if this is the first
// row being added.
if (this.numRows == 1) {
this.show();
// Pre-fill the search terms field with the value from the one on the
// toolbar.
// For some reason, setting.value here synchronously does not appear to
// work.
var searchTermsField = document.getElementById("advancedSearch1Textbox");
if (searchTermsField)
setTimeout(function() { searchTermsField.value = PlacesSearchBox.value; }, 10);
this.queries = PlacesOrganizer.getCurrentQueries();
return;
}
this.showSearch(this.numRows, searchType);
this._updateUIForRowChange();
},
/**
* Remove a row from the set of terms
* @param row
* The row to remove. If this is null, the last row will be removed.
* If there are no more rows, the query builder will be hidden.
*/
removeRow: function PQB_removeRow(row) {
if (!row)
row = document.getElementById("advancedSearch" + this.numRows + "Row");
row.parentNode.removeChild(row);
--this.numRows;
if (this.numRows < 1) {
this.hide();
// Re-do the original toolbar-search-box search that the user used to
// spawn the advanced UI... this effectively "reverts" the UI to the
// point it was in before they began monkeying with advanced search.
PlacesSearchBox.search(PlacesSearchBox.value);
return;
}
this.doSearch();
this._updateUIForRowChange();
},
onDateTyped: function PQB_onDateTyped(event, row) {
var textbox = document.getElementById("advancedSearch" + row + "TimePicker");
var dateString = textbox.value;
var dateArr = dateString.split("-");
// The date can be split into a range by the '-' character, i.e.
// 9/5/05 - 10/2/05. Unfortunately, dates can also be written like
// 9-5-05 - 10-2-05. Try to parse the date based on how many hyphens
// there are.
var d0 = null;
var d1 = null;
// If there are an even number of elements in the date array, try to
// parse it as a range of two dates.
if ((dateArr.length & 1) == 0) {
var mid = dateArr.length / 2;
var dateStr0 = dateArr[0];
var dateStr1 = dateArr[mid];
for (var i = 1; i < mid; ++i) {
dateStr0 += "-" + dateArr[i];
dateStr1 += "-" + dateArr[i + mid];
}
d0 = new Date(dateStr0);
d1 = new Date(dateStr1);
}
// If that didn't work, try to parse it as a single date.
if (d0 == null || d0 == "Invalid Date") {
d0 = new Date(dateString);
}
if (d0 != null && d0 != "Invalid Date") {
// Parsing succeeded -- update the calendar.
var calendar = document.getElementById("advancedSearch" + row + "Calendar");
if (d0.getFullYear() < 2000)
d0.setFullYear(2000 + (d0.getFullYear() % 100));
if (d1 != null && d1 != "Invalid Date") {
if (d1.getFullYear() < 2000)
d1.setFullYear(2000 + (d1.getFullYear() % 100));
calendar.updateSelection(d0, d1);
}
else {
calendar.updateSelection(d0, d0);
}
// And update the search.
this.doSearch();
}
},
onCalendarChanged: function PQB_onCalendarChanged(event, row) {
var calendar = document.getElementById("advancedSearch" + row + "Calendar");
var begin = calendar.beginrange;
var end = calendar.endrange;
// If the calendar doesn't have a begin/end, don't change the textbox.
if (begin == null || end == null)
return true;
// If the begin and end are the same day, only fill that into the textbox.
var textbox = document.getElementById("advancedSearch" + row + "TimePicker");
var beginDate = begin.getDate();
var beginMonth = begin.getMonth() + 1;
var beginYear = begin.getFullYear();
var endDate = end.getDate();
var endMonth = end.getMonth() + 1;
var endYear = end.getFullYear();
if (beginDate == endDate && beginMonth == endMonth && beginYear == endYear) {
// Just one date.
textbox.value = this._dateService.FormatDate("",
this._dateService.dateFormatShort,
beginYear,
beginMonth,
beginDate);
}
else
{
// Two dates.
var beginStr = this._dateService.FormatDate("",
this._dateService.dateFormatShort,
beginYear,
beginMonth,
beginDate);
var endStr = this._dateService.FormatDate("",
this._dateService.dateFormatShort,
endYear,
endMonth,
endDate);
textbox.value = beginStr + " - " + endStr;
}
// Update the search.
this.doSearch();
return true;
},
handleTimePickerClick: function PQB_handleTimePickerClick(event, row) {
var popup = document.getElementById("advancedSearch" + row + "DatePopup");
if (popup.showing)
popup.hidePopup();
else {
var textbox = document.getElementById("advancedSearch" + row + "TimePicker");
popup.showPopup(textbox, -1, -1, "popup", "bottomleft", "topleft");
}
},
showSearch: function PQB_showSearch(row, values) {
for (val in values) {
var id = val.replace("_N_", row);
var element = document.getElementById(id);
if (values[val] || typeof(values[val]) == "string") {
if (typeof(values[val]) == "string") {
if (values[val] == "date") {
// "date" means that the current date should be filled into the
// textbox, and the calendar for the row updated.
var d = new Date();
element.value = this._dateService.FormatDate("",
this._dateService.dateFormatShort,
d.getFullYear(),
d.getMonth() + 1,
d.getDate());
var calendar = document.getElementById("advancedSearch" + row + "Calendar");
calendar.updateSelection(d, d);
}
else if (element.nodeName == "textbox") {
// values[val] is the initial value of the textbox.
element.value = values[val];
} else {
// values[val] is the menuitem which should be selected.
var itemId = values[val].replace("_N_", row);
var item = document.getElementById(itemId);
element.selectedItem = item;
}
}
element.hidden = false;
}
else {
element.hidden = true;
}
}
this.doSearch();
},
setKeywordQuery: function PQB_setKeywordQuery(query, prefix) {
query.searchTerms += document.getElementById(prefix + "Textbox").value + " ";
},
setLocationQuery: function PQB_setLocationQuery(query, prefix) {
var type = document.getElementById(prefix + "LocationMenulist").selectedItem.value;
if (type == "onsite") {
query.domain = document.getElementById(prefix + "Textbox").value;
}
else {
query.uriIsPrefix = (type == "startswith");
var spec = document.getElementById(prefix + "Textbox").value;
var ios = Cc["@mozilla.org/network/io-service;1"].
getService(Ci.nsIIOService);
try {
query.uri = ios.newURI(spec, null, null);
}
catch (e) {
// Invalid input can cause newURI to barf, that's OK, tack "http://"
// onto the front and try again to see if the user omitted it
try {
query.uri = ios.newURI("http://" + spec, null, null);
}
catch (e) {
// OK, they have entered something which can never match. This should
// not happen.
}
}
}
},
setVisitedQuery: function PQB_setVisitedQuery(query, prefix) {
var searchType = document.getElementById(prefix + "TimeMenulist").selectedItem.value;
const DAY_MSEC = 86400000;
switch (searchType) {
case "on":
var calendar = document.getElementById(prefix + "Calendar");
var begin = calendar.beginrange.getTime();
var end = calendar.endrange.getTime();
if (begin == end) {
end = begin + DAY_MSEC;
}
query.beginTime = begin * 1000;
query.endTime = end * 1000;
break;
case "before":
var calendar = document.getElementById(prefix + "Calendar");
var time = calendar.beginrange.getTime();
query.endTime = time * 1000;
break;
case "after":
var calendar = document.getElementById(prefix + "Calendar");
var time = calendar.endrange.getTime();
query.beginTime = time * 1000;
break;
case "inLast":
var textbox = document.getElementById(prefix + "Textbox");
var amount = parseInt(textbox.value);
amount = amount * DAY_MSEC;
var menulist = document.getElementById(prefix + "TimeMenulist2");
if (menulist.selectedItem.value == "weeks")
amount = amount * 7;
else if (menulist.selectedItem.value == "months")
amount = amount * 30;
var now = new Date();
now = now - amount;
query.beginTime = now * 1000;
break;
}
},
doSearch: function PQB_doSearch() {
// Create the individual queries.
var queryType = document.getElementById("advancedSearchType").selectedItem.value;
this.queries = [];
if (queryType == "and")
this.queries.push(PlacesUtils.history.getNewQuery());
var updated = 0;
for (var i = 1; updated < this.numRows; ++i) {
var prefix = "advancedSearch" + i;
// The user can remove rows from the middle and start of the list, not
// just from the end, so we need to make sure that this row actually
// exists before attempting to construct a query for it.
var querySubjectElement = document.getElementById(prefix + "Subject");
if (querySubjectElement) {
// If the queries are being AND-ed, put all the rows in one query.
// If they're being OR-ed, add a separate query for each row.
var query;
if (queryType == "and")
query = this.queries[0];
else
query = PlacesUtils.history.getNewQuery();
var querySubject = querySubjectElement.value;
this._queryBuilders[querySubject](query, prefix);
if (queryType == "or")
this.queries.push(query);
++updated;
}
}
// Make sure we're getting uri results, not visits
this.options = PlacesOrganizer.getCurrentOptions();
this.options.resultType = this.options.RESULT_TYPE_URI;
// XXXben - find some public way of doing this!
PlacesOrganizer._content.load(this.queries, this.options);
// Update the details panel
PlacesOrganizer.onContentTreeSelect();
},
#endif
/**
* Called when a scope button in the scope bar is clicked.
* @param aButton

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

@ -1,426 +0,0 @@
<?xml version="1.0"?>
<bindings id="placesBindings"
xmlns="http://www.mozilla.org/xbl"
xmlns:xbl="http://www.mozilla.org/xbl"
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
#ifdef PLACES_QUERY_BUILDER
<binding id="calendar">
<content>
<xul:vbox class="calendar-box">
<xul:hbox class="calendar-header">
<xul:label anonid="prevmonth" class="calendar-month-jump">&#xab;</xul:label>
<xul:label anonid="monthtitle" class="calendar-month-title" flex="1"/>
<xul:label anonid="nextmonth" class="calendar-month-jump">&#xbb;</xul:label>
</xul:hbox>
<xul:tooltip anonid="calendartooltip">
<!-- FIXME -->
</xul:tooltip>
<xul:grid anonid="calendargrid" class="calendar-grid">
<xul:columns><xul:column flex="1"/><xul:column flex="1"/><xul:column flex="1"/><xul:column flex="1"/><xul:column flex="1"/><xul:column flex="1"/><xul:column flex="1"/></xul:columns>
<xul:rows>
<xul:row class="calendar-day-header">
<xul:label anonid="calendarhead0"></xul:label>
<xul:label anonid="calendarhead1"></xul:label>
<xul:label anonid="calendarhead2"></xul:label>
<xul:label anonid="calendarhead3"></xul:label>
<xul:label anonid="calendarhead4"></xul:label>
<xul:label anonid="calendarhead5"></xul:label>
<xul:label anonid="calendarhead6"></xul:label>
</xul:row>
<!-- The "00" is so that the table has the correct dimensions (most
numbers are the same width) when it is first displayed. The
default definition for "calendar-day" should have the same color
fore- and background so you won't see this. -->
<xul:row>
<xul:label anonid="calendar0" class="calendar-day" tooltip="calendartooltip">00</xul:label>
<xul:label anonid="calendar1" class="calendar-day" tooltip="calendartooltip">00</xul:label>
<xul:label anonid="calendar2" class="calendar-day" tooltip="calendartooltip">00</xul:label>
<xul:label anonid="calendar3" class="calendar-day" tooltip="calendartooltip">00</xul:label>
<xul:label anonid="calendar4" class="calendar-day" tooltip="calendartooltip">00</xul:label>
<xul:label anonid="calendar5" class="calendar-day" tooltip="calendartooltip">00</xul:label>
<xul:label anonid="calendar6" class="calendar-day" tooltip="calendartooltip">00</xul:label>
</xul:row>
<xul:row>
<xul:label anonid="calendar7" class="calendar-day" tooltip="calendartooltip">00</xul:label>
<xul:label anonid="calendar8" class="calendar-day" tooltip="calendartooltip">00</xul:label>
<xul:label anonid="calendar9" class="calendar-day" tooltip="calendartooltip">00</xul:label>
<xul:label anonid="calendar10" class="calendar-day" tooltip="calendartooltip">00</xul:label>
<xul:label anonid="calendar11" class="calendar-day" tooltip="calendartooltip">00</xul:label>
<xul:label anonid="calendar12" class="calendar-day" tooltip="calendartooltip">00</xul:label>
<xul:label anonid="calendar13" class="calendar-day" tooltip="calendartooltip">00</xul:label>
</xul:row>
<xul:row>
<xul:label anonid="calendar14" class="calendar-day" tooltip="calendartooltip">00</xul:label>
<xul:label anonid="calendar15" class="calendar-day" tooltip="calendartooltip">00</xul:label>
<xul:label anonid="calendar16" class="calendar-day" tooltip="calendartooltip">00</xul:label>
<xul:label anonid="calendar17" class="calendar-day" tooltip="calendartooltip">00</xul:label>
<xul:label anonid="calendar18" class="calendar-day" tooltip="calendartooltip">00</xul:label>
<xul:label anonid="calendar19" class="calendar-day" tooltip="calendartooltip">00</xul:label>
<xul:label anonid="calendar20" class="calendar-day" tooltip="calendartooltip">00</xul:label>
</xul:row>
<xul:row>
<xul:label anonid="calendar21" class="calendar-day" tooltip="calendartooltip">00</xul:label>
<xul:label anonid="calendar22" class="calendar-day" tooltip="calendartooltip">00</xul:label>
<xul:label anonid="calendar23" class="calendar-day" tooltip="calendartooltip">00</xul:label>
<xul:label anonid="calendar24" class="calendar-day" tooltip="calendartooltip">00</xul:label>
<xul:label anonid="calendar25" class="calendar-day" tooltip="calendartooltip">00</xul:label>
<xul:label anonid="calendar26" class="calendar-day" tooltip="calendartooltip">00</xul:label>
<xul:label anonid="calendar27" class="calendar-day" tooltip="calendartooltip">00</xul:label>
</xul:row>
<xul:row>
<xul:label anonid="calendar28" class="calendar-day" tooltip="calendartooltip">00</xul:label>
<xul:label anonid="calendar29" class="calendar-day" tooltip="calendartooltip">00</xul:label>
<xul:label anonid="calendar30" class="calendar-day" tooltip="calendartooltip">00</xul:label>
<xul:label anonid="calendar31" class="calendar-day" tooltip="calendartooltip">00</xul:label>
<xul:label anonid="calendar32" class="calendar-day" tooltip="calendartooltip">00</xul:label>
<xul:label anonid="calendar33" class="calendar-day" tooltip="calendartooltip">00</xul:label>
<xul:label anonid="calendar34" class="calendar-day" tooltip="calendartooltip">00</xul:label>
</xul:row>
<xul:row>
<xul:label anonid="calendar35" class="calendar-day" tooltip="calendartooltip">00</xul:label>
<xul:label anonid="calendar36" class="calendar-day" tooltip="calendartooltip">00</xul:label>
<xul:label anonid="calendar37" class="calendar-day" tooltip="calendartooltip">00</xul:label>
<xul:label anonid="calendar38" class="calendar-day" tooltip="calendartooltip">00</xul:label>
<xul:label anonid="calendar39" class="calendar-day" tooltip="calendartooltip">00</xul:label>
<xul:label anonid="calendar40" class="calendar-day" tooltip="calendartooltip">00</xul:label>
<xul:label anonid="calendar41" class="calendar-day" tooltip="calendartooltip">00</xul:label>
</xul:row>
</xul:rows>
</xul:grid>
</xul:vbox>
</content>
<implementation>
<constructor><![CDATA[
var grid = document.getAnonymousElementByAttribute(this, "anonid",
"calendargrid");
this._numCells = 42; // max number of cells displayable in the calendar
this._cellPrefix = "calendar"; // value before the number in the ID of cells
this._currentMonth = -1;
this._currentYear = -1;
this._cell0Date = null; // date for top left of calendar
this._selectNothing = false;
this._selectBegin = null;
this._selectEnd = null;
// localized stuff, FIXME: move somewhere else
this._pref_firstDayOfWeek = 0; // 0 = Sunday, 1 = Monday
this._pref_dayHeaders = ["S", "M", "T", "W", "T", "F", "S"];
this._pref_shortMonthNames = ["Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
// day headers
for (var i = 0; i < 7; i ++) {
var cell = document.getAnonymousElementByAttribute(this, "anonid",
"calendarhead" + i);
cell.value = this._pref_dayHeaders[i];
}
// cell item
var calendargrid = document.getAnonymousElementByAttribute(this, "anonid", "calendargrid");
this._days = new Array(this._numCells);
this._selected = new Array(this._numCells);
for (var i = 0; i < this._numCells; i ++) {
this._days[i] = document.getAnonymousElementByAttribute(this, "anonid", this._cellPrefix + i);
this._selected[i] = false;
}
// month navigation hooks
var myself = this;
document.getAnonymousElementByAttribute(this, "anonid", "prevmonth").
addEventListener("click", function() { myself.jumpMonth(-1); }, false);
document.getAnonymousElementByAttribute(this, "anonid", "nextmonth").
addEventListener("click", function() { myself.jumpMonth(1); }, false);
// day selection hooks
calendargrid.addEventListener("mousedown", function(event) { myself.mouseDown(event); }, false);
calendargrid.addEventListener("mouseup", function(event) { myself.mouseUp(event); }, false);
calendargrid.addEventListener("mousemove", function(event) { myself.mouseMove(event); }, false);
this.visibleMonth = new Date(); // today
]]></constructor>
<property name="visibleMonth">
<getter>
return new Date(this._visibleMonth);
</getter>
<setter>
this._visibleMonth = new Date(val.getFullYear(), val.getMonth(), 1);
this.drawMonth();
</setter>
</property>
<property name="beginrange">
<getter>
if (! this._selectBegin)
return null;
else
return new Date(this._selectBegin);
</getter>
<setter>
this._selectNothing = false;
this._selectBegin = val;
this.updateSelection(this._selectBegin, this._selectEnd);
this.fireRangeEvent();
</setter>
</property>
<property name="endrange">
<getter>
if (! this._selectEnd)
return null;
else
return new Date(this._selectEnd);
</getter>
<setter>
this._selectNothing = false;
this._selectEnd = val;
this.updateSelection(this._selectBegin, this._selectEnd);
this.fireRangeEvent();
</setter>
</property>
<!-- Use this to set the range at once. It will be more efficient than
setting begin and end independently since there will be only one
redraw. Set updateVisible to have the calendar change the active
month if necessary. -->
<method name="setRange">
<parameter name="begin"/>
<parameter name="end"/>
<parameter name="updateVisible"/>
<body><![CDATA[
if (updateVisible && end) {
// this just tries to make the end range visible. If there is no
// end range, we don't do anything. We might want to set the visible
// month to the begin range in this case, but I don't think this
// situation arises in practice.
var daysToEnd = this.daysBetweenDates(end, this._cell0Date);
if (daysToEnd < 0 || daysToEnd >= this._numCells) {
// reselect month for end range
this.visibleMonth = end;
}
}
this._selectNothing = false;
this.updateSelection(begin, end);
this.fireRangeEvent();
]]></body>
</method>
<!-- Normally, null begin and end means select all, so you can set
this if you don't want anything selected.-->
<property name="selectNothing">
<getter>
return this._selectNothing;
</getter>
<setter>
this._selectNothing = val;
</setter>
</property>
<!--===== jumpMonth =====-->
<method name="jumpMonth">
<parameter name="relative"/>
<body><![CDATA[
var newMonth = this._visibleMonth.getMonth() + relative;
var newYear = this._visibleMonth.getFullYear() + Math.floor(newMonth / 12);
newMonth = (newMonth + 12) % 12;
this._visibleMonth = new Date(newYear, newMonth, 1);
this.drawMonth();
]]></body>
</method>
<!--===== mouseDown =====-->
<method name="mouseDown">
<parameter name="event"/>
<body><![CDATA[
var date = this.cellToDate(event.target.getAttribute("anonid"));
if (! date)
return;
this._selectNothing = false;
this._dragging = true;
this._mouseDownOn = date;
this.updateSelection(date, date);
]]></body>
</method>
<!--===== mouseUp =====-->
<method name="mouseUp">
<parameter name="event"/>
<body><![CDATA[
this._dragging = false;
this.fireRangeEvent();
]]></body>
</method>
<!--===== mouseMove =====-->
<method name="mouseMove">
<parameter name="event"/>
<body><![CDATA[
if (! this._dragging)
return;
var date = this.cellToDate(event.target.getAttribute("anonid"));
if (! date)
return;
this.updateSelection(this._mouseDownOn, date);
]]></body>
</method>
<!--===== updateSelection =====-->
<method name="updateSelection">
<parameter name="begin"/>
<parameter name="end"/>
<body><![CDATA[
var realBegin = begin;
var realEnd = end;
if (begin && end && begin.getTime() > end.getTime()) {
this._selectBegin = end;
this._selectEnd = begin;
} else {
this._selectBegin = begin;
this._selectEnd = end;
}
this.drawSelection();
]]></body>
</method>
<!--===== daysBetweenDates =====-->
<method name="daysBetweenDates">
<parameter name="a"/>
<parameter name="b"/>
<body>
var msDiff = a.getTime() - b.getTime();
return Math.floor(msDiff / 86400000); // 1000ms/s * 60s/m * 60m/h * 24h/d = 86400000ms/d
</body>
</method>
<!--===== suppressRangeEvents =====-->
<field name="suppressRangeEvents">false</field>
<!--===== fireRangeEvent =====-->
<method name="fireRangeEvent"><body><![CDATA[
if (this.suppressRangeEvents)
return true;
var event = document.createEvent("Events");
event.initEvent("selectionchanged", false, true);
// handle dom event handlers
var noCancel = this.dispatchEvent(event);
// handle any xml attribute event handlers
var handler = this.getAttribute("onselectionchanged");
if (handler != "") {
var fn = new Function("event", handler);
var returned = fn(event);
if (returned == false)
noCancel = false;
}
return noCancel;
]]></body></method>
<!--===== drawSelection =====-->
<method name="drawSelection"><body><![CDATA[
var beginIndex;
var endIndex;
if (this._selectNothing) {
beginIndex = -1;
endIndex = -1;
} else {
if (! this._selectBegin) {
beginIndex = 0;
} else {
beginIndex = this.daysBetweenDates(this._selectBegin, this._cell0Date);
}
if (! this._selectEnd) {
endIndex = this._numCells - 1;
} else {
endIndex = this.daysBetweenDates(this._selectEnd, this._cell0Date);
}
}
for (var i = 0; i < this._numCells; i ++) {
var sel = (i >= beginIndex && i <= endIndex);
if (sel != this._selected[i]) {
this._days[i].setAttribute("selected", sel ? "true" : "");
this._selected[i] = sel;
}
}
]]></body></method>
<!--===== cellToDate =====-->
<method name="cellToDate">
<parameter name="cellName"/>
<body><![CDATA[
if (! cellName)
return null;
var tail = cellName.substring(this._cellPrefix.length);
if (tail[0] < "0" || tail[0] > '9') {
return null;
}
var cellNumber = Number(tail);
var d = new Date(this._cell0Date);
d.setDate(d.getDate() + cellNumber);
return d;
]]></body>
</method>
<!--===== drawMonth =====-->
<method name="drawMonth"><body><![CDATA[
var curCell = 0;
var monthIndex = this._visibleMonth.getMonth();
var yearNumber = this._visibleMonth.getFullYear();
var firstOfMonth = new Date(yearNumber, monthIndex, 1);
// update title
document.getAnonymousElementByAttribute(this, "anonid", "monthtitle").value =
this._pref_shortMonthNames[monthIndex] + " " + yearNumber;
// first, fill in any days of the previous month in the first week
var numPrefixDays = firstOfMonth.getDay() - this._pref_firstDayOfWeek;
var curDay = firstOfMonth;
curDay.setDate(firstOfMonth.getDate() - numPrefixDays);
this._cell0Date = new Date(curDay); // save the first cell
for (var i = 0; i < numPrefixDays; i ++) {
var cell = document.getAnonymousElementByAttribute(this, "anonid", this._cellPrefix + curCell);
cell.setAttribute("month", "other");
cell.value = curDay.getDate();
curCell ++;
curDay.setDate(curDay.getDate() + 1);
}
// now fill in the rest of this month
while (curDay.getMonth() == monthIndex) {
var cell = document.getAnonymousElementByAttribute(this, "anonid", this._cellPrefix + curCell);
cell.setAttribute("month", "this");
cell.value = curDay.getDate();
curCell ++;
curDay.setDate(curDay.getDate() + 1);
}
// fill out the end of this week with next month
while (curDay.getDay() != this._pref_firstDayOfWeek) {
var cell = document.getAnonymousElementByAttribute(this, "anonid", this._cellPrefix + curCell);
cell.setAttribute("month", "other");
cell.value = curDay.getDate();
curCell ++;
curDay.setDate(curDay.getDate() + 1);
}
// fill the bottom row with days from the next month
while (curCell < this._numCells) {
var cell = document.getAnonymousElementByAttribute(this, "anonid", this._cellPrefix + curCell);
cell.setAttribute("month", "other");
cell.value = curDay.getDate();
curCell ++;
curDay.setDate(curDay.getDate() + 1);
}
this.drawSelection();
]]></body></method>
</implementation>
</binding> <!-- end calendar -->
#endif
</bindings>

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

@ -289,25 +289,6 @@
#endif
id="viewMenu" label="&views.label;">
<menupopup id="viewMenuPopup">
<!--
<menuitem id="viewDetails"
type="radio"
#ifdef XP_MACOSX
label="&view.detailsMacOSX.label;"
#else
label="&view.details.label;"
#endif
accesskey="&view.details.accesskey;">
</menuitem>
<menuseparator id="addonsSeparator"/>
<menuitem id="viewAddons"
command=""
label="&view.addons.label;"
accesskey="&view.addons.label;"/>
<menuseparator id="sortingSeparator"/>
-->
<menu id="viewColumns"
label="&view.columns.label;" accesskey="&view.columns.accesskey;">
@ -331,14 +312,6 @@
oncommand="ViewMenu.setSortColumn(null, 'descending'); event.stopPropagation();"/>
</menupopup>
</menu>
<!--
<menuseparator id="groupingSeparator" observes="placesBC_grouping:separator"/>
<menuitem id="viewGroupNone" type="radio" name="group"
observes="placesBC_grouping:off"/>
<menuitem id="viewGroupGroup" type="radio" name="group"
observes="placesBC_grouping:on"/>
-->
</menupopup>
#ifdef XP_MACOSX
</toolbarbutton>
@ -441,18 +414,8 @@
<button id="saveSearch" class="small"
label="&saveSearch.label;" accesskey="&saveSearch.accesskey;"
command="OrganizerCommand_search:save"/>
#ifdef PLACES_QUERY_BUILDER
<button id="organizerScopeBarExpander"
class="expander-down"
tooltiptext="&search.scopeBarExpanderDown.tooltip;"
tooltiptextdown="&search.scopeBarExpanderDown.tooltip;"
tooltiptextup="&search.scopeBarExpanderUp.tooltip;"
oncommand="PlacesQueryBuilder.toggleVisibility();"/>
</toolbar>
#include advancedSearch.inc
#else
</toolbar>
#endif
</vbox>
<vbox flex="1">
<tree id="placeContent" class="placesTree" context="placesContext"

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

@ -1140,22 +1140,26 @@
halfInd = Math.ceil(halfInd);
translateX = 0 - this._scrollbox.getBoundingClientRect().right -
halfInd;
if (dropPoint.beforeIndex == -1)
translateX += this.lastChild.getBoundingClientRect().left;
else if (this.childNodes.length) {
translateX += this.childNodes[dropPoint.beforeIndex]
if (this.firstChild) {
if (dropPoint.beforeIndex == -1)
translateX += this.lastChild.getBoundingClientRect().left;
else {
translateX += this.childNodes[dropPoint.beforeIndex]
.getBoundingClientRect().right;
}
}
}
else {
halfInd = Math.floor(halfInd);
translateX = 0 - this._scrollbox.getBoundingClientRect().left +
halfInd;
if (dropPoint.beforeIndex == -1)
translateX += this.lastChild.getBoundingClientRect().right;
else if (this.childNodes.length) {
translateX += this.childNodes[dropPoint.beforeIndex]
.getBoundingClientRect().left;
if (this.firstChild) {
if (dropPoint.beforeIndex == -1)
translateX += this.lastChild.getBoundingClientRect().right;
else {
translateX += this.childNodes[dropPoint.beforeIndex]
.getBoundingClientRect().left;
}
}
}

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

@ -1,12 +1,11 @@
browser.jar:
# Provide another URI for the bookmarkProperties dialog so we can persist the
# attributes separately
* content/browser/places/bookmarkProperties2.xul (content/bookmarkProperties.xul)
* content/browser/places/bookmarkProperties2.xul (content/bookmarkProperties.xul)
* content/browser/places/places.xul (content/places.xul)
* content/browser/places/places.js (content/places.js)
* content/browser/places/places.xml (content/places.xml)
content/browser/places/places.css (content/places.css)
* content/browser/places/organizer.css (content/organizer.css)
content/browser/places/organizer.css (content/organizer.css)
* content/browser/places/bookmarkProperties.xul (content/bookmarkProperties.xul)
* content/browser/places/bookmarkProperties.js (content/bookmarkProperties.js)
* content/browser/places/placesOverlay.xul (content/placesOverlay.xul)
@ -16,10 +15,6 @@ browser.jar:
* content/browser/places/utils.js (content/utils.js)
* content/browser/places/controller.js (content/controller.js)
* content/browser/places/treeView.js (content/treeView.js)
* content/browser/places/demos/time.xul (content/demos/time.xul)
* content/browser/places/demos/time.html (content/demos/time.html)
* content/browser/places/demos/time.css (content/demos/time.css)
* content/browser/places/demos/time.js (content/demos/time.js)
# keep the Places version of the history sidebar at history/history-panel.xul
# to prevent having to worry about between versions of the browser
* content/browser/history/history-panel.xul (content/history-panel.xul)

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

@ -48,14 +48,16 @@ _CHROME_FILES = \
perf_large_delete.xul \
$(NULL)
# XXX disabled tests, not working properly yet
# browser_ui_history_menu.js
# browser_ui_locationbar.js
# XXX disabled tests, random failures
# browser_ui_bookmarks_sidebar.js
# Disabled due to bad interactions with next tests.
# browser_ui_locationbar.js
# Disabled due to random failures.
# browser_ui_bookmarks_sidebar.js
_BROWSER_TEST_FILES = \
browser_ui_000_data.js \
browser_ui_history_menu.js \
browser_ui_history_sidebar.js \
browser_ui_history_sidebar_2.js \
browser_ui_history_sidebar_3.js \
$(NULL)
libs:: $(_CHROME_FILES)

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

@ -20,6 +20,7 @@
*
* Contributor(s):
* Dietrich Ayala <dietrich@mozilla.com>
* Marco Bonardo <mak77@bonardo.net>
*
* 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
@ -62,13 +63,13 @@ var bs = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
getService(Ci.nsINavBookmarksService);
function add_visit(aURI, aDate) {
var placeID = hs.addVisit(aURI,
var visitId = hs.addVisit(aURI,
aDate,
null, // no referrer
hs.TRANSITION_TYPED, // user typed in URL bar
false, // not redirect
0);
return placeID;
return visitId;
}
function add_bookmark(aURI) {
@ -86,7 +87,7 @@ var ptests = [];
/*********************** end header **********************/
const TEST_REPEAT_COUNT = 10;
const TEST_REPEAT_COUNT = 6;
// test duration of bookmarks sidebar opening
ptests.push({
@ -116,18 +117,19 @@ ptests.push({
var avgDuration = totalDuration/this.times.length;
var report = make_test_report("open_bookmarks_sidebar", avgDuration);
ok(true, report);
runNextTest();
setTimeout(runNextTest, 0);
}
});
function test() {
// kick off tests
runNextTest();
setTimeout(runNextTest, 0);
}
function runNextTest() {
if (ptests.length > 0)
if (ptests.length > 0) {
ptests.shift().run();
}
else
finish();
}

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

@ -20,6 +20,7 @@
*
* Contributor(s):
* Dietrich Ayala <dietrich@mozilla.com>
* Marco Bonardo <mak77@bonardo.net>
*
* 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
@ -40,8 +41,6 @@ Tests the performance of opening the history menu.
*/
/*********************** begin header **********************/
waitForExplicitFinish();
const TEST_IDENTIFIER = "ui-perf-test";
const TEST_SUITE = "places";
@ -60,14 +59,17 @@ var hs = Cc["@mozilla.org/browser/nav-history-service;1"].
var bs = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
getService(Ci.nsINavBookmarksService);
var historyMenu = document.getElementById("history-menu");
var historyPopup = document.getElementById("goPopup");
function add_visit(aURI, aDate) {
var placeID = hs.addVisit(aURI,
var visitId = hs.addVisit(aURI,
aDate,
null, // no referrer
hs.TRANSITION_TYPED, // user typed in URL bar
false, // not redirect
0);
return placeID;
return visitId;
}
function add_bookmark(aURI) {
@ -85,38 +87,56 @@ var ptests = [];
/*********************** end header **********************/
const TEST_REPEAT_COUNT = 6;
// test duration of history menu opening
ptests.push({
name: "open_history_menu",
times: [],
run: function() {
var menu = document.getElementById("history-menu");
ok(menu, "history menu should exist!");
var self = this;
var start = Date.now();
var popup = document.getElementById("goPopup");
popup.addEventListener("popupshown", function() {
var duration = Date.now() - start;
var report = make_test_report("open_history_menu", duration);
ok(true, report);
// clean up
popup.removeEventListener("popupshown", arguments.callee, false);
menu.open = false;
runNextTest();
}, false);
// XXX does not work, is still open=false immediately after setting it to true
//menu.open = true;
// XXX does nada
//EventUtils.sendMouseEvent({type:"click"}, "history-menu");
historyPopup.addEventListener("popupshown", function() {
historyPopup.removeEventListener("popupshown", arguments.callee, true);
executeSoon(function() {
var duration = Date.now() - start;
historyPopup.hidePopup();
historyMenu.open = false;
self.times.push(duration);
if (self.times.length == TEST_REPEAT_COUNT)
self.finish();
else
self.run();
});
}, true);
historyMenu.open = true;
historyPopup.openPopup();
},
finish: function() {
processTestResult(this);
setTimeout(runNextTest, 0);
}
});
function processTestResult(aTest) {
aTest.times.sort(); // sort the scores
aTest.times.pop(); // remove worst
aTest.times.shift(); // remove best
var totalDuration = aTest.times.reduce(function(time, total){ return time + total; });
var avgDuration = totalDuration/aTest.times.length;
var report = make_test_report(aTest.name, avgDuration);
ok(true, report);
}
function test() {
// Skip test on Mac due to native menus.
if (navigator.platform.toLowerCase().indexOf("mac") != -1)
return;
waitForExplicitFinish();
// kick off tests
runNextTest();
setTimeout(runNextTest, 0);
}
function runNextTest() {

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

@ -20,6 +20,7 @@
*
* Contributor(s):
* Dietrich Ayala <dietrich@mozilla.com>
* Marco Bonardo <mak77@bonardo.net>
*
* 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
@ -87,7 +88,7 @@ var ptests = [];
/*********************** end header **********************/
const TEST_REPEAT_COUNT = 10;
const TEST_REPEAT_COUNT = 6;
// test duration of history sidebar opening
// default: bydayandsite
@ -113,7 +114,7 @@ ptests.push({
},
finish: function() {
processTestResult(this);
runNextTest();
setTimeout(runNextTest, 0);
}
});
@ -141,7 +142,7 @@ ptests.push({
},
finish: function() {
processTestResult(this);
runNextTest();
setTimeout(runNextTest, 0);
}
});
@ -169,63 +170,7 @@ ptests.push({
},
finish: function() {
processTestResult(this);
runNextTest();
}
});
// byvisited
ptests.push({
name: "history_sidebar_byvisited",
times: [],
run: function() {
var self = this;
var start = Date.now();
sidebar.addEventListener("load", function() {
sidebar.removeEventListener("load", arguments.callee, true);
executeSoon(function() {
var duration = Date.now() - start;
sidebar.contentDocument.getElementById("byvisited").doCommand();
toggleSidebar("viewHistorySidebar", false);
self.times.push(duration);
if (self.times.length == TEST_REPEAT_COUNT)
self.finish();
else
self.run();
});
}, true);
toggleSidebar("viewHistorySidebar", true);
},
finish: function() {
processTestResult(this);
runNextTest();
}
});
// bylastvisited
ptests.push({
name: "history_sidebar_bylastvisited",
times: [],
run: function() {
var self = this;
var start = Date.now();
sidebar.addEventListener("load", function() {
sidebar.removeEventListener("load", arguments.callee, true);
executeSoon(function() {
var duration = Date.now() - start;
sidebar.contentDocument.getElementById("bylastvisited").doCommand();
toggleSidebar("viewHistorySidebar", false);
self.times.push(duration);
if (self.times.length == TEST_REPEAT_COUNT)
self.finish();
else
self.run();
});
}, true);
toggleSidebar("viewHistorySidebar", true);
},
finish: function() {
processTestResult(this);
runNextTest();
setTimeout(runNextTest, 0);
}
});
@ -241,7 +186,7 @@ function processTestResult(aTest) {
function test() {
// kick off tests
runNextTest();
setTimeout(runNextTest, 0);
}
function runNextTest() {

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

@ -0,0 +1,142 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Mozilla Corporation.
* Portions created by the Initial Developer are Copyright (C) 2008
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Dietrich Ayala <dietrich@mozilla.com>
* Marco Bonardo <mak77@bonardo.net>
*
* 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 ***** */
/*
Tests the performance of opening the History
sidebar in all the available views.
*/
/*********************** begin header **********************/
waitForExplicitFinish();
const TEST_IDENTIFIER = "ui-perf-test";
const TEST_SUITE = "places";
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cr = Components.results;
var wm = Cc["@mozilla.org/appshell/window-mediator;1"].
getService(Ci.nsIWindowMediator);
var win = wm.getMostRecentWindow("navigator:browser");
var ios = Cc["@mozilla.org/network/io-service;1"].
getService(Ci.nsIIOService);
var hs = Cc["@mozilla.org/browser/nav-history-service;1"].
getService(Ci.nsINavHistoryService);
var bs = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
getService(Ci.nsINavBookmarksService);
var sidebar = document.getElementById("sidebar");
function add_visit(aURI, aDate) {
var visitId = hs.addVisit(aURI,
aDate,
null, // no referrer
hs.TRANSITION_TYPED, // user typed in URL bar
false, // not redirect
0);
return visitId;
}
function add_bookmark(aURI) {
var bId = bs.insertBookmark(bs.unfiledBookmarksFolder, aURI,
bs.DEFAULT_INDEX, "bookmark/" + aURI.spec);
return bId;
}
function make_test_report(testName, result, units) {
return [TEST_IDENTIFIER, TEST_SUITE, testName, result, units||"ms"].join(":");
}
// Each test is an obj w/ a name property and run method
var ptests = [];
/*********************** end header **********************/
const TEST_REPEAT_COUNT = 6;
// test duration of history sidebar opening
// byvisited
ptests.push({
name: "history_sidebar_byvisited",
times: [],
run: function() {
var self = this;
var start = Date.now();
sidebar.addEventListener("load", function() {
sidebar.removeEventListener("load", arguments.callee, true);
executeSoon(function() {
var duration = Date.now() - start;
sidebar.contentDocument.getElementById("byvisited").doCommand();
toggleSidebar("viewHistorySidebar", false);
self.times.push(duration);
if (self.times.length == TEST_REPEAT_COUNT)
self.finish();
else
self.run();
});
}, true);
toggleSidebar("viewHistorySidebar", true);
},
finish: function() {
processTestResult(this);
setTimeout(runNextTest, 0);
}
});
function processTestResult(aTest) {
aTest.times.sort(); // sort the scores
aTest.times.pop(); // remove worst
aTest.times.shift(); // remove best
var totalDuration = aTest.times.reduce(function(time, total){ return time + total; });
var avgDuration = totalDuration/aTest.times.length;
var report = make_test_report(aTest.name, avgDuration);
ok(true, report);
}
function test() {
// kick off tests
setTimeout(runNextTest, 0);
}
function runNextTest() {
if (ptests.length > 0)
ptests.shift().run();
else
finish();
}

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

@ -0,0 +1,142 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Mozilla Corporation.
* Portions created by the Initial Developer are Copyright (C) 2008
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Dietrich Ayala <dietrich@mozilla.com>
* Marco Bonardo <mak77@bonardo.net>
*
* 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 ***** */
/*
Tests the performance of opening the History
sidebar in all the available views.
*/
/*********************** begin header **********************/
waitForExplicitFinish();
const TEST_IDENTIFIER = "ui-perf-test";
const TEST_SUITE = "places";
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cr = Components.results;
var wm = Cc["@mozilla.org/appshell/window-mediator;1"].
getService(Ci.nsIWindowMediator);
var win = wm.getMostRecentWindow("navigator:browser");
var ios = Cc["@mozilla.org/network/io-service;1"].
getService(Ci.nsIIOService);
var hs = Cc["@mozilla.org/browser/nav-history-service;1"].
getService(Ci.nsINavHistoryService);
var bs = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
getService(Ci.nsINavBookmarksService);
var sidebar = document.getElementById("sidebar");
function add_visit(aURI, aDate) {
var visitId = hs.addVisit(aURI,
aDate,
null, // no referrer
hs.TRANSITION_TYPED, // user typed in URL bar
false, // not redirect
0);
return visitId;
}
function add_bookmark(aURI) {
var bId = bs.insertBookmark(bs.unfiledBookmarksFolder, aURI,
bs.DEFAULT_INDEX, "bookmark/" + aURI.spec);
return bId;
}
function make_test_report(testName, result, units) {
return [TEST_IDENTIFIER, TEST_SUITE, testName, result, units||"ms"].join(":");
}
// Each test is an obj w/ a name property and run method
var ptests = [];
/*********************** end header **********************/
const TEST_REPEAT_COUNT = 6;
// test duration of history sidebar opening
// bylastvisited
ptests.push({
name: "history_sidebar_bylastvisited",
times: [],
run: function() {
var self = this;
var start = Date.now();
sidebar.addEventListener("load", function() {
sidebar.removeEventListener("load", arguments.callee, true);
executeSoon(function() {
var duration = Date.now() - start;
sidebar.contentDocument.getElementById("bylastvisited").doCommand();
toggleSidebar("viewHistorySidebar", false);
self.times.push(duration);
if (self.times.length == TEST_REPEAT_COUNT)
self.finish();
else
self.run();
});
}, true);
toggleSidebar("viewHistorySidebar", true);
},
finish: function() {
processTestResult(this);
setTimeout(runNextTest, 0);
}
});
function processTestResult(aTest) {
aTest.times.sort(); // sort the scores
aTest.times.pop(); // remove worst
aTest.times.shift(); // remove best
var totalDuration = aTest.times.reduce(function(time, total){ return time + total; });
var avgDuration = totalDuration/aTest.times.length;
var report = make_test_report(aTest.name, avgDuration);
ok(true, report);
}
function test() {
// kick off tests
setTimeout(runNextTest, 0);
}
function runNextTest() {
if (ptests.length > 0)
ptests.shift().run();
else
finish();
}

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

@ -20,6 +20,7 @@
*
* Contributor(s):
* Dietrich Ayala <dietrich@mozilla.com>
* Marco Bonardo <mak77@bonardo.net>
*
* 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
@ -59,15 +60,20 @@ var hs = Cc["@mozilla.org/browser/nav-history-service;1"].
getService(Ci.nsINavHistoryService);
var bs = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
getService(Ci.nsINavBookmarksService);
var prefs = Cc["@mozilla.org/preferences-service;1"].
getService(Ci.nsIPrefBranch);
var maxResults = prefs.getIntPref("browser.urlbar.maxRichResults");
var onSearchComplete = gURLBar.onSearchComplete;
function add_visit(aURI, aDate) {
var placeID = hs.addVisit(aURI,
var visitId = hs.addVisit(aURI,
aDate,
null, // no referrer
hs.TRANSITION_TYPED, // user typed in URL bar
false, // not redirect
0);
return placeID;
return visitId;
}
function add_bookmark(aURI) {
@ -85,30 +91,61 @@ var ptests = [];
/*********************** end header **********************/
// test duration of history menu opening
const TEST_REPEAT_COUNT = 6;
// test duration of locationbar searching
ptests.push({
name: "open_locationbar_default",
times: [],
run: function() {
var urlbar = document.getElementById("urlbar");
urlbar.addEventListener("onsearchcomplete", function() {
urlbar.removeEventListener("onsearchcomplete", arguments.callee, false);
runNextTest();
}, false);
urlbar.value = "example";
urlbar.select();
EventUtils.synthesizeKey("VK_RETURN", {});
var self = this;
var start = Date.now();
var acItemsCount = 1;
gURLBar.onSearchComplete = function() {
executeSoon(function() {
var duration = Date.now() - start;
self.times.push(duration);
if (self.times.length == TEST_REPEAT_COUNT)
self.finish();
else
self.run();
});
};
window.focus();
gURLBar.focus();
var synthesizeSearch = function() {
EventUtils.synthesizeKey("VK_BACK_SPACE", {});
EventUtils.synthesizeKey("e", {});
};
waitForFocus(synthesizeSearch);
},
finish: function() {
gURLBar.value = "";
processTestResult(this);
setTimeout(runNextTest, 0);
}
});
function processTestResult(aTest) {
aTest.times.sort(); // sort the scores
aTest.times.pop(); // remove worst
aTest.times.shift(); // remove best
var totalDuration = aTest.times.reduce(function(time, total){ return time + total; });
var avgDuration = totalDuration/aTest.times.length;
var report = make_test_report(aTest.name, avgDuration);
ok(true, report);
}
function test() {
// kick off tests
runNextTest();
setTimeout(runNextTest, 0);
}
function runNextTest() {
if (ptests.length > 0)
ptests.shift().run();
else
else {
gURLBar.onSearchComplete = onSearchComplete;
finish();
}
}

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

@ -87,7 +87,7 @@ function test()
// Close the window if it's already open
let wm = Cc["@mozilla.org/appshell/window-mediator;1"].
getService(Ci.nsIWindowMediator);
let win = wm.getMostRecentWindow("Places:Orgainzier");
let win = wm.getMostRecentWindow("Places:Organizer");
if (win)
win.close();

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

@ -329,3 +329,15 @@ function flush_main_thread_events()
while (tm.mainThread.hasPendingEvents())
tm.mainThread.processNextEvent(false);
}
// These tests are known to randomly fail due to bug 507790 when database
// flushes are active, so we turn off syncing for them.
let randomFailingSyncTests = [
"test_browserGlue_smartBookmarks.js",
];
let currentTestFilename = do_get_file(_TEST_FILE[0], true).leafName;
if (randomFailingSyncTests.indexOf(currentTestFilename) != -1) {
print("Test " + currentTestFilename + " is known random due to bug 507790, disabling PlacesDBFlush component.");
let sync = Cc["@mozilla.org/places/sync;1"].getService(Ci.nsIObserver);
sync.observe(null, "places-debug-stop-sync", null);
}

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

@ -1,65 +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 Places.
*
* The Initial Developer of the Original Code is
* Mozilla.org
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Dietrich Ayala <dietrich@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* 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 ***** */
// put cleanup of the bookmarks test here.
// Run the event loop to be more like the browser, which normally runs the
// event loop long before code like this would run.
// Not doing so could cause us to close the connection before all tasks have
// been completed, and that would crash badly.
flush_main_thread_events();
// XPCShell doesn't dispatch quit-application, to ensure cleanup we have to
// dispatch it after each test run.
var os = Cc['@mozilla.org/observer-service;1'].
getService(Ci.nsIObserverService);
os.notifyObservers(null, "quit-application-granted", null);
os.notifyObservers(null, "quit-application", null);
// Run the event loop, since we enqueue some statement finalization.
flush_main_thread_events();
// try to close the connection so we can remove places.sqlite
var pip = Cc["@mozilla.org/browser/nav-history-service;1"].
getService(Ci.nsINavHistoryService).
QueryInterface(Ci.nsPIPlacesDatabase);
if (pip.DBConnection.connectionReady) {
pip.commitPendingChanges();
pip.finalizeInternalStatements();
pip.DBConnection.close();
do_check_false(pip.DBConnection.connectionReady);
}

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

@ -132,12 +132,15 @@ function continue_test() {
// Check distribution prefs have been created.
do_check_eq(ps.getCharPref(PREF_DISTRIBUTION_ID), "516444");
// Remove the distribution file.
do_test_finished();
}
do_register_cleanup(function() {
// Remove the distribution file, even if the test failed, otherwise all
// next tests will import it.
let iniFile = dirSvc.get("XCurProcD", Ci.nsIFile);
iniFile.append("distribution");
iniFile.append("distribution.ini");
iniFile.remove(false);
do_check_false(iniFile.exists());
do_test_finished();
}
});

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

@ -205,15 +205,16 @@ tests.push({
do_check_false(ps.getBoolPref(PREF_RESTORE_DEFAULT_BOOKMARKS));
do_check_false(ps.getBoolPref(PREF_IMPORT_BOOKMARKS_HTML));
finish_test();
do_test_finished();
}
});
//------------------------------------------------------------------------------
function finish_test() {
// Simulate application closing to remove the idle observer and avoid leaks.
os.notifyObservers(null, "quit-application-granted", null);
// Clean up database from all bookmarks.
remove_all_bookmarks();
do_test_finished();
}
@ -222,16 +223,13 @@ function next_test() {
// Clean up database from all bookmarks.
remove_all_bookmarks();
// Simulate application closing to remove the idle observer and avoid leaks.
os.notifyObservers(null, "quit-application-granted", null);
// nsBrowserGlue stops observing topics after first notification,
// so we add back the observer to test additional runs.
os.addObserver(bg, TOPIC_PLACES_INIT_COMPLETE, false);
// Execute next test.
let test = tests.shift();
dump("\nTEST " + (++testIndex) + ": " + test.description);
print("\nTEST " + (++testIndex) + ": " + test.description);
test.exec();
}

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

@ -139,7 +139,7 @@ tests.push({
do_check_eq(profileBookmarksJSONFile.lastModifiedTime, lastMod);
do_check_eq(profileBookmarksJSONFile.fileSize, fileSize);
finish_test();
do_test_finished();
}
});

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

@ -51,26 +51,34 @@
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
#ifdef XP_MACOSX
<title></title>
#else
<title>&privatebrowsingpage.title;</title>
#endif
<link rel="stylesheet" href="chrome://global/skin/netError.css" type="text/css" media="all"/>
<link rel="stylesheet" href="chrome://browser/skin/aboutPrivateBrowsing.css" type="text/css" media="all"/>
<script type="application/x-javascript;version=1.7"><![CDATA[
const Cc = Components.classes;
const Ci = Components.interfaces;
window.__defineGetter__("mainWindow", function() {
delete window.mainWindow;
return window.mainWindow = window.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShellTreeItem)
.rootTreeItem
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindow);
});
var pb = Cc["@mozilla.org/privatebrowsing;1"].
getService(Ci.nsIPrivateBrowsingService);
if (!pb.privateBrowsingEnabled) {
document.title = "]]>&privatebrowsingpage.title.normal;<![CDATA[";
setFavIcon("chrome://global/skin/icons/question-16.png");
} else {
#ifndef XP_MACOSX
document.title = "]]>&privatebrowsingpage.title;<![CDATA[";
#endif
setFavIcon("chrome://browser/skin/Privacy-16.png");
}
var mainWindow = window.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShellTreeItem)
.rootTreeItem
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindow);
// Focus the location bar
mainWindow.focusAndSelectUrlBar();
function openSanitizeDialog() {
let browserGlue = Cc["@mozilla.org/browser/browserglue;1"].
@ -83,21 +91,17 @@
icon.setAttribute("rel", "icon");
icon.setAttribute("type", "image/png");
icon.setAttribute("href", url);
document.getElementsByTagName("head")[0].appendChild(icon);
var head = document.getElementsByTagName("head")[0];
head.insertBefore(icon, head.firstChild);
}
function onLoad() {
document.addEventListener("DOMContentLoaded", function () {
let selector;
let pb = Cc["@mozilla.org/privatebrowsing;1"].
getService(Ci.nsIPrivateBrowsingService);
if (!pb.privateBrowsingEnabled) {
document.body.setAttribute("class", "normal");
document.title = document.body.getAttribute("normaltitle");
setFavIcon("chrome://global/skin/icons/question-16.png");
selector = ".showPrivate";
}
else {
setFavIcon("chrome://browser/skin/Privacy-16.png");
selector = ".showNormal";
}
@ -113,18 +117,12 @@
let moreInfoLink = document.getElementById("moreInfoLink");
if (moreInfoLink)
moreInfoLink.setAttribute("href", moreInfoURL + "private-browsing");
// Focus the location bar
if (mainWindow.gURLBar)
mainWindow.gURLBar.focus();
}
}, false);
]]></script>
</head>
<body dir="&locale.dir;"
class="private"
onload="onLoad();"
normaltitle="&privatebrowsingpage.title.normal;">
class="private">
<!-- PAGE CONTAINER (for styling purposes only) -->
<div id="errorPageContainer">

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

@ -124,6 +124,9 @@ PrivateBrowsingService.prototype = {
// List of view source window URIs for restoring later
_viewSrcURLs: [],
// List of nsIXULWindows we are going to be closing during the transition
_windowsToClose: [],
// XPCOM registration
classDescription: "PrivateBrowsing Service",
contractID: "@mozilla.org/privatebrowsing;1",
@ -208,12 +211,20 @@ PrivateBrowsingService.prototype = {
// just in case the only remaining window after setBrowserState is different.
// it probably shouldn't be with the current sessionstore impl, but we shouldn't
// rely on behaviour the API doesn't guarantee
let browser = this._getBrowserWindow().gBrowser;
browserWindow = this._getBrowserWindow();
let browser = browserWindow.gBrowser;
// this ensures a clean slate from which to transition into or out of
// private browsing
browser.addTab();
browser.getBrowserForTab(browser.tabContainer.firstChild).stop();
browser.removeTab(browser.tabContainer.firstChild);
browserWindow.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShellTreeItem)
.treeOwner
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIXULWindow)
.docShell.contentViewer.resetCloseWindow();
}
}
}
@ -298,6 +309,20 @@ PrivateBrowsingService.prototype = {
getMostRecentWindow("navigator:browser");
},
_ensureCanCloseWindows: function PBS__ensureCanCloseWindows() {
let windowMediator = Cc["@mozilla.org/appshell/window-mediator;1"].
getService(Ci.nsIWindowMediator);
let windowsEnum = windowMediator.getXULWindowEnumerator("navigator:browser");
while (windowsEnum.hasMoreElements()) {
let win = windowsEnum.getNext().QueryInterface(Ci.nsIXULWindow);
if (win.docShell.contentViewer.permitUnload(true))
this._windowsToClose.push(win);
else
throw Cr.NS_ERROR_ABORT;
}
},
_closePageInfoWindows: function PBS__closePageInfoWindows() {
let pageInfoEnum = Cc["@mozilla.org/appshell/window-mediator;1"].
getService(Ci.nsIWindowMediator).
@ -401,6 +426,8 @@ PrivateBrowsingService.prototype = {
return;
}
this._ensureCanCloseWindows();
this._autoStarted = this._prefs.getBoolPref("browser.privatebrowsing.autostart");
this._inPrivateBrowsing = val != false;
@ -422,9 +449,16 @@ PrivateBrowsingService.prototype = {
this._onAfterPrivateBrowsingModeChange();
}
} catch (ex) {
Cu.reportError("Exception thrown while processing the " +
"private browsing mode change request: " + ex.toString());
// We aborted the transition to/from private browsing, we must restore the
// beforeunload handling on all the windows for which we switched it off.
for (let i = 0; i < this._windowsToClose.length; i++)
this._windowsToClose[i].docShell.contentViewer.resetCloseWindow();
// We don't log an error when the transition is canceled from beforeunload
if (ex != Cr.NS_ERROR_ABORT)
Cu.reportError("Exception thrown while processing the " +
"private browsing mode change request: " + ex.toString());
} finally {
this._windowsToClose = [];
this._alreadyChangingMode = false;
}
},

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

@ -80,19 +80,11 @@ function test() {
let tab = gBrowser.selectedTab = gBrowser.addTab();
let browser = gBrowser.selectedBrowser;
browser.stop();
// ensure that the test is run after the titlebar has been updated
let timer = null;
let _updateTitlebar = gBrowser.updateTitlebar;
gBrowser.updateTitlebar = function() {
if (timer) {
timer.cancel();
timer = null;
}
timer = Cc["@mozilla.org/timer;1"].
createInstance(Ci.nsITimer);
timer.initWithCallback(function () {
_updateTitlebar.apply(gBrowser, arguments);
gBrowser.updateTitlebar = _updateTitlebar;
browser.addEventListener("pageshow", function () {
browser.removeEventListener("pageshow", arguments.callee, false);
executeSoon(function () {
is(document.title, expected_title, "The window title for " + url +
" is correct (" + (insidePB ? "inside" : "outside") +
" private browsing mode)");
@ -115,8 +107,8 @@ function test() {
setTimeout(funcNext, 0);
};
}, false);
}, 300, Ci.nsITimer.TYPE_ONE_SHOT);
};
});
}, false);
browser.loadURI(url);
}

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

@ -564,7 +564,6 @@ function test_cache_cleared()
observe: function(aSubject, aTopic, aData)
{
os.removeObserver(observer, "cacheservice:empty-cache");
shutdownPlaces();
do_test_finished();
}
};

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

@ -155,6 +155,4 @@ function do_test()
// And check our data
for (let i = 0; i < data.length; i++)
check_active_download(data[i].source, !data[i].removed);
shutdownPlaces();
}

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

@ -110,15 +110,6 @@ function cleanUp()
}
cleanUp();
/**
* Finalize Places statements during quit-application in order to prevent leaks
*/
function shutdownPlaces() {
let os = Cc["@mozilla.org/observer-service;1"].
getService(Ci.nsIObserverService);
os.notifyObservers(null, "quit-application", null);
}
var PRIVATEBROWSING_CONTRACT_ID;
function run_test_on_all_services() {
var contractIDs = [

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

@ -269,6 +269,8 @@ SessionStoreService.prototype = {
// make sure that at least the first window doesn't have anything hidden
delete this._initialState.windows[0].hidden;
// Since nothing is hidden in the first window, it cannot be a popup
delete this._initialState.windows[0].isPopup;
}
catch (ex) { debug("The session file is invalid: " + ex); }
}

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

@ -44,12 +44,14 @@ function test() {
let tab = gBrowser.addTab(testURL);
tab.linkedBrowser.addEventListener("load", function(aEvent) {
this.removeEventListener("load", arguments.callee, true);
let doc = tab.linkedBrowser.contentDocument;
is(doc.getElementById("storageTestItem").textContent, "PENDING",
"sessionStorage value has been set");
let tab2 = gBrowser.duplicateTab(tab);
tab2.linkedBrowser.addEventListener("load", function(aEvent) {
this.removeEventListener("load", arguments.callee, true);
let doc2 = tab2.linkedBrowser.contentDocument;
is(doc2.getElementById("storageTestItem").textContent, "SUCCESS",
"sessionStorage value has been duplicated");

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

@ -99,11 +99,13 @@ function test() {
"browser/components/sessionstore/test/browser/browser_346337_sample.html";
let tab = tabbrowser.addTab(testURL);
tab.linkedBrowser.addEventListener("load", function(aEvent) {
this.removeEventListener("load", arguments.callee, true);
for (let xpath in fieldList)
setFormValue(tab, xpath, fieldList[xpath]);
let tab2 = tabbrowser.duplicateTab(tab);
tab2.linkedBrowser.addEventListener("load", function(aEvent) {
this.removeEventListener("load", arguments.callee, true);
for (let xpath in fieldList)
ok(compareFormValue(tab2, xpath, fieldList[xpath]),
"The value for \"" + xpath + "\" was correctly restored");
@ -114,6 +116,7 @@ function test() {
tab = undoCloseTab();
tab.linkedBrowser.addEventListener("load", function(aEvent) {
this.removeEventListener("load", arguments.callee, true);
for (let xpath in fieldList)
if (fieldList[xpath])
ok(!compareFormValue(tab, xpath, fieldList[xpath]),

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

@ -45,6 +45,7 @@ function test() {
key = "Unique name: " + Math.random();
value = "Unique value: " + Date.now();
let tab = tabbrowser.addTab();
tab.linkedBrowser.stop();
// test adding
ok(test(function() ss.setTabValue(tab, key, value)), "store a tab value");
@ -74,6 +75,7 @@ function test() {
let testURL = "about:";
tab = tabbrowser.addTab(testURL);
tab.linkedBrowser.addEventListener("load", function(aEvent) {
this.removeEventListener("load", arguments.callee, true);
// make sure that the next closed tab will increase getClosedTabCount
gPrefService.setIntPref("browser.sessionstore.max_tabs_undo", max_tabs_undo + 1);
@ -89,6 +91,7 @@ function test() {
ok(tab, "undoCloseTab doesn't throw")
tab.linkedBrowser.addEventListener("load", function(aEvent) {
this.removeEventListener("load", arguments.callee, true);
is(this.currentURI.spec, testURL, "correct tab was reopened");
// clean up

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

@ -248,6 +248,7 @@ function test() {
// The previously closed window should be restored
newWin = openDialog(location, "_blank", CHROME_FEATURES);
newWin.addEventListener("load", function() {
this.removeEventListener("load", arguments.callee, true);
executeSoon(function() {
is(newWin.gBrowser.browsers.length, TEST_URLS.length + 1,
"Restored window in-session with otherpopup windows around");
@ -281,6 +282,7 @@ function test() {
// The previously closed window should NOT be restored
newWin = openDialog(location, "_blank", CHROME_FEATURES);
newWin.addEventListener("load", function() {
this.removeEventListener("load", arguments.callee, true);
executeSoon(function() {
is(newWin.gBrowser.browsers.length, 1,
"Did not restore in private browing mode");
@ -293,6 +295,7 @@ function test() {
newWin = openDialog(location, "_blank", CHROME_FEATURES);
newWin.addEventListener("load", function() {
this.removeEventListener("load", arguments.callee, true);
executeSoon(function() {
is(newWin.gBrowser.browsers.length, TEST_URLS.length + 1,
"Restored after leaving private browsing again");
@ -334,6 +337,7 @@ function test() {
// open a new window the previously closed window should be restored to
newWin = openDialog(location, "_blank", CHROME_FEATURES);
newWin.addEventListener("load", function() {
this.removeEventListener("load", arguments.callee, true);
executeSoon(function() {
is(newWin.gBrowser.browsers.length, TEST_URLS.length + 1,
"Restored window and associated tabs in session");
@ -364,6 +368,7 @@ function test() {
// gets a chance.
let popup = openDialog(location, "popup", POPUP_FEATURES, TEST_URLS[1]);
popup.addEventListener("load", function() {
this.removeEventListener("load", arguments.callee, true);
is(popup.gBrowser.browsers.length, 1,
"Did not restore the popup window (1)");
popup.BrowserTryToCloseWindow();

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

@ -57,6 +57,7 @@ function test() {
ss.setTabState(tab, "{ entries: [] }");
tab.linkedBrowser.addEventListener("load", function(aEvent) {
this.removeEventListener("load", arguments.callee, true);
ok(history.count == 0, "the tab was restored without any history whatsoever");
tabbrowser.removeTab(tab);

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

@ -21,6 +21,7 @@ function test() {
let tab = tabbrowser.addTab(testURL);
ss.setTabValue(tab, key, value);
tab.linkedBrowser.addEventListener("load", function(aEvent) {
this.removeEventListener("load", arguments.callee, true);
// get the tab's state
let state = ss.getTabState(tab);
ok(state, "get the tab's state");
@ -51,6 +52,7 @@ function test() {
// set the tab's state
ss.setTabState(tab2, state.toSource());
tab2.linkedBrowser.addEventListener("load", function(aEvent) {
this.removeEventListener("load", arguments.callee, true);
// verify the correctness of the restored tab
ok(ss.getTabValue(tab2, key2) == value2 && this.currentURI.spec == testURL,
"the tab's state was correctly restored");
@ -64,6 +66,7 @@ function test() {
tabbrowser.removeTab(tab2);
duplicateTab.linkedBrowser.addEventListener("load", function(aEvent) {
this.removeEventListener("load", arguments.callee, true);
// verify the correctness of the duplicated tab
ok(ss.getTabValue(duplicateTab, key2) == value2 && this.currentURI.spec == testURL,
"correctly duplicated the tab's state");

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

@ -63,7 +63,7 @@ function test() {
newWin.gBrowser.removeEventListener("load", arguments.callee, true);
executeSoon(function() {
newWin.gBrowser.addTab();
newWin.gBrowser.addTab().linkedBrowser.stop();
executeSoon(function() {
// mark the window with some unique data to be restored later on
ss.setWindowValue(newWin, uniqueKey, uniqueValue);
@ -87,6 +87,7 @@ function test() {
"The reopened window was removed from Recently Closed Windows");
newWin2.addEventListener("load", function(aEvent) {
this.removeEventListener("load", arguments.callee, false);
newWin2.gBrowser.addEventListener("SSTabRestored", function(aEvent) {
newWin2.gBrowser.removeEventListener("SSTabRestored", arguments.callee, true);
@ -142,12 +143,14 @@ function test() {
let url = "http://window" + windowsToOpen.length + ".example.com";
let window = openDialog(location, "_blank", settings, url);
window.addEventListener("load", function(aEvent) {
this.removeEventListener("load", arguments.callee, true);
window.gBrowser.addEventListener("load", function(aEvent) {
this.removeEventListener("load", arguments.callee, true);
// the window _should_ have state with a tab of url, but it doesn't
// always happend before window.close(). addTab ensure we don't treat
// this window as a stateless window
window.gBrowser.addTab();
window.gBrowser.removeEventListener("load", arguments.callee, true);
executeSoon(function() {
window.close();
executeSoon(function() {

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

@ -21,6 +21,7 @@
* Contributor(s):
* Ehsan Akhgari <ehsan.akhgari@gmail.com>
* Paul OShannessy <paul@oshannessy.com>
* Marco Bonardo <mak77@bonardo.net>
*
* 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
@ -39,20 +40,20 @@
function test() {
/** Private Browsing Test for Bug 394759 **/
// test setup
waitForExplicitFinish();
// private browsing service
// Setup.
let pb = Cc["@mozilla.org/privatebrowsing;1"].
getService(Ci.nsIPrivateBrowsingService);
let ss = Cc["@mozilla.org/browser/sessionstore;1"].
getService(Ci.nsISessionStore);
let ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].
getService(Ci.nsIWindowWatcher);
// Remove the sessionstore.js file before setting the interval to 0
let profilePath = Cc["@mozilla.org/file/directory_service;1"].
getService(Ci.nsIProperties).
get("ProfD", Ci.nsIFile);
// sessionstore service
let ss = Cc["@mozilla.org/browser/sessionstore;1"].
getService(Ci.nsISessionStore);
// Remove the sessionstore.js file before setting the interval to 0
let sessionStoreJS = profilePath.clone();
sessionStoreJS.append("sessionstore.js");
if (sessionStoreJS.exists())
@ -79,93 +80,98 @@ function test() {
let closedWindowCount = ss.getClosedWindowCount();
is(closedWindowCount, 0, "Correctly set window count");
let testURL_A = "about:config";
let testURL_B = "about:mozilla";
// Prevent VM timers issues, cache now and increment it manually.
const NOW = Date.now();
let uniqueKey_A = "bug 394759 Non-PB";
let uniqueValue_A = "unik" + Date.now();
let uniqueKey_B = "bug 394759 PB";
let uniqueValue_B = "uniq" + Date.now();
// Open a window
let newWin = openDialog(location, "_blank", "chrome,all,dialog=no", testURL_A);
newWin.addEventListener("load", function(aEvent) {
newWin.removeEventListener("load", arguments.callee, false);
newWin.gBrowser.addEventListener("load", function(aEvent) {
newWin.gBrowser.removeEventListener("load", arguments.callee, true);
info("Window has been loaded");
executeSoon(function() {
newWin.gBrowser.addTab();
executeSoon(function() {
// mark the window with some unique data to be restored later on
ss.setWindowValue(newWin, uniqueKey_A, uniqueValue_A);
newWin.close();
// ensure that we incremented # of close windows
is(ss.getClosedWindowCount(), closedWindowCount + 1,
"The closed window was added to the list");
// ensure we added window to undo list
let data = JSON.parse(ss.getClosedWindowData())[0];
ok(data.toSource().indexOf(uniqueValue_A) > -1,
"The closed window data was stored correctly");
// enter private browsing mode
pb.privateBrowsingEnabled = true;
ok(pb.privateBrowsingEnabled, "private browsing enabled");
// ensure that we have 0 undo windows when entering PB
is(ss.getClosedWindowCount(), 0,
"Recently Closed Windows are removed when entering Private Browsing");
is(ss.getClosedWindowData(), "[]",
"Recently Closed Windows data is cleared when entering Private Browsing");
// open another window in PB
let pbWin = openDialog(location, "_blank", "chrome,all,dialog=no", testURL_B);
pbWin.addEventListener("load", function(aEvent) {
pbWin.removeEventListener("load", arguments.callee, false);
pbWin.gBrowser.addEventListener("load", function(aEvent) {
pbWin.gBrowser.removeEventListener("load", arguments.callee, true);
const TESTS = [
{ url: "about:config",
key: "bug 394759 Non-PB",
value: "uniq" + (++NOW) },
{ url: "about:mozilla",
key: "bug 394759 PB",
value: "uniq" + (++NOW) },
];
function openWindowAndTest(aTestIndex, aRunNextTestInPBMode) {
info("Opening new window");
let windowObserver = {
observe: function(aSubject, aTopic, aData) {
if (aTopic === "domwindowopened") {
ww.unregisterNotification(this);
info("New window has been opened");
let win = aSubject.QueryInterface(Ci.nsIDOMWindow);
win.addEventListener("load", function onLoad(event) {
win.removeEventListener("load", onLoad, false);
info("New window has been loaded");
win.gBrowser.addEventListener("load", function(aEvent) {
win.gBrowser.removeEventListener("load", arguments.callee, true);
info("New window browser has been loaded");
executeSoon(function() {
// Add another tab, though it's not strictly needed
pbWin.gBrowser.addTab();
// Add a tab.
win.gBrowser.addTab();
executeSoon(function() {
// mark the window with some unique data to be restored later on
ss.setWindowValue(pbWin, uniqueKey_B, uniqueValue_B);
// Mark the window with some unique data to be restored later on.
ss.setWindowValue(win, TESTS[aTestIndex].key, TESTS[aTestIndex].value);
pbWin.close();
win.close();
// ensure we added window to undo list
let data = JSON.parse(ss.getClosedWindowData())[0];
ok(data.toSource().indexOf(uniqueValue_B) > -1,
"The closed window data was stored correctly in PB mode");
// exit private browsing mode
pb.privateBrowsingEnabled = false;
ok(!pb.privateBrowsingEnabled, "private browsing disabled");
// ensure that we still have the closed windows from before
// Ensure that we incremented # of close windows.
is(ss.getClosedWindowCount(), closedWindowCount + 1,
"The correct number of recently closed windows were restored " +
"when exiting PB mode");
"The closed window was added to the list");
// Ensure we added window to undo list.
let data = JSON.parse(ss.getClosedWindowData())[0];
ok(data.toSource().indexOf(uniqueValue_A) > -1,
"The data associated with the recently closed window was " +
"restored when exiting PB mode");
ok(data.toSource().indexOf(TESTS[aTestIndex].value) > -1,
"The closed window data was stored correctly");
// cleanup
gPrefService.clearUserPref("browser.sessionstore.interval");
finish();
if (aRunNextTestInPBMode) {
// Enter private browsing mode.
pb.privateBrowsingEnabled = true;
ok(pb.privateBrowsingEnabled, "private browsing enabled");
// Ensure that we have 0 undo windows when entering PB.
is(ss.getClosedWindowCount(), 0,
"Recently Closed Windows are removed when entering Private Browsing");
is(ss.getClosedWindowData(), "[]",
"Recently Closed Windows data is cleared when entering Private Browsing");
}
else {
// Exit private browsing mode.
pb.privateBrowsingEnabled = false;
ok(!pb.privateBrowsingEnabled, "private browsing disabled");
// Ensure that we still have the closed windows from before.
is(ss.getClosedWindowCount(), closedWindowCount + 1,
"The correct number of recently closed windows were restored " +
"when exiting PB mode");
let data = JSON.parse(ss.getClosedWindowData())[0];
ok(data.toSource().indexOf(TESTS[aTestIndex].value) > -1,
"The data associated with the recently closed window was " +
"restored when exiting PB mode");
}
if (aTestIndex == TESTS.length - 1) {
// Cleanup and finish.
gPrefService.clearUserPref("browser.sessionstore.interval");
finish();
}
else {
// Run next test.
openWindowAndTest(aTestIndex + 1, !aRunNextTestInPBMode);
}
});
});
}, true);
}, false);
});
});
}, true);
}, false);
}
}
};
ww.registerNotification(windowObserver);
// Open a window.
openDialog(location, "_blank", "chrome,all,dialog=no", TESTS[aTestIndex].url);
}
openWindowAndTest(0, true);
}

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

@ -45,6 +45,7 @@ function test() {
let tab = gBrowser.addTab(testUrl);
tab.linkedBrowser.addEventListener("load", function(aEvent) {
this.removeEventListener("load", arguments.callee, true);
// enable all stylesheets and verify that they're correctly persisted
Array.forEach(tab.linkedBrowser.contentDocument.styleSheets, function(aSS, aIx) {
pendingCount++;
@ -53,6 +54,7 @@ function test() {
let newTab = gBrowser.duplicateTab(tab);
newTab.linkedBrowser.addEventListener("load", function(aEvent) {
this.removeEventListener("load", arguments.callee, true);
let states = Array.map(newTab.linkedBrowser.contentDocument.styleSheets,
function(aSS) !aSS.disabled);
let correct = states.indexOf(true) == aIx && states.indexOf(true, aIx + 1) == -1;
@ -72,6 +74,7 @@ function test() {
tab.linkedBrowser.markupDocumentViewer.authorStyleDisabled = true;
let newTab = gBrowser.duplicateTab(tab);
newTab.linkedBrowser.addEventListener("load", function(aEvent) {
this.removeEventListener("load", arguments.callee, true);
is(newTab.linkedBrowser.markupDocumentViewer.authorStyleDisabled, true,
"disabled all stylesheets");

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

@ -47,6 +47,7 @@ function test() {
// set a unique value on a new, blank tab
var tab = gBrowser.addTab();
tab.linkedBrowser.stop();
ss.setTabValue(tab, uniqueName, uniqueValue);
let valueWasCleaned = false;

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

@ -51,6 +51,7 @@ function test() {
"browser/components/sessionstore/test/browser/browser_454908_sample.html";
let tab = gBrowser.addTab(testURL);
tab.linkedBrowser.addEventListener("load", function(aEvent) {
this.removeEventListener("load", arguments.callee, true);
let doc = tab.linkedBrowser.contentDocument;
for (let id in fieldValues)
doc.getElementById(id).value = fieldValues[id];
@ -59,6 +60,7 @@ function test() {
tab = undoCloseTab();
tab.linkedBrowser.addEventListener("load", function(aEvent) {
this.removeEventListener("load", arguments.callee, true);
let doc = tab.linkedBrowser.contentDocument;
for (let id in fieldValues) {
let node = doc.getElementById(id);

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

@ -46,6 +46,7 @@ function test() {
"browser/components/sessionstore/test/browser/browser_456342_sample.xhtml";
let tab = gBrowser.addTab(testURL);
tab.linkedBrowser.addEventListener("load", function(aEvent) {
this.removeEventListener("load", arguments.callee, true);
gBrowser.removeTab(tab);
let ss = Cc["@mozilla.org/browser/sessionstore;1"]

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

@ -60,7 +60,8 @@ function test() {
// wait for all frames to load (and reload!) completely
if (frameCount++ < 2)
return;
this.removeEventListener("load", arguments.callee, true);
let maxWait = Date.now() + 1000;
executeSoon(function() {
let iframes = tab2.linkedBrowser.contentWindow.frames;

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

@ -9,6 +9,7 @@
<script type="application/javascript">
frames[0].addEventListener("DOMContentLoaded", function() {
frames[0].removeEventListener("DOMContentLoaded", arguments.callee, false);
frames[0].document.designMode = "on";
frames[0].document.__defineGetter__("designMode", function() {
// inject a cross domain file ...

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

@ -67,6 +67,7 @@ function test() {
// open a window and add the above closed tab list
let newWin = openDialog(location, "_blank", "chrome,all,dialog=no");
newWin.addEventListener("load", function(aEvent) {
this.removeEventListener("load", arguments.callee, false);
gPrefService.setIntPref("browser.sessionstore.max_tabs_undo",
test_state.windows[0]._closedTabs.length);
ss.setWindowState(newWin, JSON.stringify(test_state), true);

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

@ -48,6 +48,7 @@ function test() {
executeSoon(function() {
let tab2 = gBrowser.duplicateTab(tab);
tab2.linkedBrowser.addEventListener("461743", function(aEvent) {
tab2.linkedBrowser.removeEventListener("461743", arguments.callee, true);
is(aEvent.data, "done", "XSS injection was attempted");
executeSoon(function() {

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

@ -30,6 +30,10 @@
var event = document.createEvent("MessageEvent");
event.initMessageEvent("461743", true, false, "done", location.href, "", window);
document.dispatchEvent(event);
frames[0].document.removeEventListener("DOMNodeInserted", loadChrome, true);
frames[0].document.removeEventListener("DOMNodeInserted", delay, true);
frames[0].document.removeEventListener("DOMNodeInserted", loadExploit, true);
frames[0].document.removeEventListener("DOMNodeInserted", done, true);
}
frames[0].document.addEventListener("DOMNodeInserted", loadChrome, true);

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

@ -69,7 +69,8 @@ function test() {
// wait for all frames to load (and reload!) completely
if (frameCount++ < 4)
return;
this.removeEventListener("load", arguments.callee, true);
let win = tab2.linkedBrowser.contentWindow;
isnot(win.frames[0].document.getElementById("original").value, uniqueValue,
"subframes must match URL to get text restored");

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

@ -69,7 +69,8 @@ function test() {
// wait for all frames to load completely
if (frameCount++ < 5)
return;
this.removeEventListener("load", arguments.callee, true);
let doc = tab2.linkedBrowser.contentDocument;
let win = tab2.linkedBrowser.contentWindow;
isnot(doc.getElementById("out1").value,

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

@ -75,6 +75,7 @@ function test() {
// open a window and add the above closed tab list
let newWin = openDialog(location, "_blank", "chrome,all,dialog=no");
newWin.addEventListener("load", function(aEvent) {
this.removeEventListener("load", arguments.callee, false);
gPrefService.setIntPref("browser.sessionstore.max_tabs_undo",
test_state.windows[0]._closedTabs.length);
ss.setWindowState(newWin, JSON.stringify(test_state), true);

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

@ -54,6 +54,7 @@ function test() {
frameCount = 0;
let tab2 = gBrowser.duplicateTab(tab);
tab2.linkedBrowser.addEventListener("464620_a", function(aEvent) {
tab2.linkedBrowser.removeEventListener("464620_a", arguments.callee, true);
is(aEvent.data, "done", "XSS injection was attempted");
// let form restoration complete and take into account the

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

@ -54,6 +54,7 @@ function test() {
frameCount = 0;
let tab2 = gBrowser.duplicateTab(tab);
tab2.linkedBrowser.addEventListener("464620_b", function(aEvent) {
tab2.linkedBrowser.removeEventListener("464620_b", arguments.callee, true);
is(aEvent.data, "done", "XSS injection was attempted");
// let form restoration complete and take into account the

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

@ -49,6 +49,7 @@ function test() {
// open a window and set a value on it
let newWin = openDialog(location, "_blank", "chrome,all,dialog=no");
newWin.addEventListener("load", function(aEvent) {
this.removeEventListener("load", arguments.callee, false);
ss.setWindowValue(newWin, uniqueKey1, uniqueValue1);
let newState = { windows: [{ tabs:[{ entries: [] }], extData: {} }] };

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

@ -45,12 +45,14 @@ function test() {
let tab = gBrowser.addTab(testURL);
tab.linkedBrowser.addEventListener("load", function(aEvent) {
this.removeEventListener("load", arguments.callee, true);
let doc = tab.linkedBrowser.contentDocument;
doc.getElementById("reverse_thief").value = "/home/user/secret2";
doc.getElementById("bystander").value = testPath;
let tab2 = gBrowser.duplicateTab(tab);
tab2.linkedBrowser.addEventListener("load", function(aEvent) {
this.removeEventListener("load", arguments.callee, true);
doc = tab2.linkedBrowser.contentDocument;
is(doc.getElementById("thief").value, "",
"file path wasn't set to text field value");

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

@ -9,6 +9,7 @@
<script>
window.addEventListener("DOMContentLoaded", function() {
window.removeEventListener("DOMContentLoaded", arguments.callee, false);
if (!document.location.hash) {
document.location.hash = "#ready";
}

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

@ -43,6 +43,7 @@ function test() {
"browser/components/sessionstore/test/browser/browser_476161_sample.html";
let tab = gBrowser.addTab(testURL);
tab.linkedBrowser.addEventListener("load", function(aEvent) {
this.removeEventListener("load", arguments.callee, true);
let doc = tab.linkedBrowser.contentDocument;
doc.getElementById("modify1").value += Math.random();
@ -50,6 +51,7 @@ function test() {
let tab2 = gBrowser.duplicateTab(tab);
tab2.linkedBrowser.addEventListener("load", function(aEvent) {
this.removeEventListener("load", arguments.callee, true);
let doc = tab2.linkedBrowser.contentDocument;
let changed = doc.getElementById("changed").textContent.trim().split();

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

@ -42,6 +42,7 @@ function test() {
let newWin = openDialog(location, "_blank", "chrome,all,dialog=no");
newWin.addEventListener("load", function(aEvent) {
this.removeEventListener("load", arguments.callee, false);
let newState = { windows: [{
tabs: [{ entries: [] }],
_closedTabs: [{

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

@ -108,8 +108,11 @@ function test() {
// cleanup
this.window.close();
// if we're all done, explicitly finish
if (++completedTests == numTests)
if (++completedTests == numTests) {
this.window.removeEventListener("load", this, false);
this.window.removeEventListener("SSTabRestoring", this, false);
finish();
}
},
handleLoad: function (aEvent) {

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

@ -10,7 +10,7 @@ function test() {
let browser = tab.linkedBrowser;
browser.addEventListener("load", function loadListener(e) {
browser.removeEventListener("load", arguments.callee, false);
browser.removeEventListener("load", arguments.callee, true);
// Scroll the content document
browser.contentWindow.scrollTo(1100, 1200);
@ -21,7 +21,7 @@ function test() {
let newTab = ss.undoCloseTab(window, 0);
newTab.addEventListener("SSTabRestored", function tabRestored(e) {
newTab.removeEventListener("SSTabRestored", arguments.callee, false);
newTab.removeEventListener("SSTabRestored", arguments.callee, true);
let newBrowser = newTab.linkedBrowser;

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

@ -45,12 +45,14 @@ function test() {
"browser/components/sessionstore/test/browser/browser_485482_sample.html";
let tab = gBrowser.addTab(testURL);
tab.linkedBrowser.addEventListener("load", function(aEvent) {
this.removeEventListener("load", arguments.callee, true);
let doc = tab.linkedBrowser.contentDocument;
doc.querySelector("input[type=text]").value = uniqueValue;
doc.querySelector("input[type=checkbox]").checked = true;
let tab2 = gBrowser.duplicateTab(tab);
tab2.linkedBrowser.addEventListener("load", function(aEvent) {
this.removeEventListener("load", arguments.callee, true);
doc = tab2.linkedBrowser.contentDocument;
is(doc.querySelector("input[type=text]").value, uniqueValue,
"generated XPath expression was valid");

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

@ -44,6 +44,7 @@ function test() {
let tab = gBrowser.addTab();
tab.linkedBrowser.addEventListener("load", function(aEvent) {
this.removeEventListener("load", arguments.callee, true);
ss.setTabValue(tab, "bug485563", uniqueValue);
let tabState = eval("(" + ss.getTabState(tab) + ")");
is(tabState.extData["bug485563"], uniqueValue,

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