Merge mozilla-centra to Places
1
.hgtags
|
@ -61,3 +61,4 @@ b70744835d94e54eec97b8fd186c96da5708a506 PRE_MOBILE_MERGE
|
|||
b70744835d94e54eec97b8fd186c96da5708a506 PRE_MOBILE_MERGE_20110406
|
||||
a71bd564ebf5bf4f93d13e84114f759c263130b0 MOBILE_MERGE_DONE
|
||||
a71bd564ebf5bf4f93d13e84114f759c263130b0 MOBILE_MERGE_DONE_20110406
|
||||
a95d426422816513477e5863add1b00ac7041dcb AURORA_BASE_20110412
|
||||
|
|
|
@ -38,6 +38,9 @@
|
|||
|
||||
#include "nsAccessNodeWrap.h"
|
||||
#include "nsApplicationAccessibleWrap.h"
|
||||
#include "nsMaiInterfaceText.h"
|
||||
|
||||
PRBool nsAccessNodeWrap::gHaveNewTextSignals = PR_FALSE;
|
||||
|
||||
/* For documentation of the accessibility architecture,
|
||||
* see http://lxr.mozilla.org/seamonkey/source/accessible/accessible-docs.html
|
||||
|
@ -68,6 +71,7 @@ nsAccessNodeWrap::~nsAccessNodeWrap()
|
|||
void nsAccessNodeWrap::InitAccessibility()
|
||||
{
|
||||
nsAccessNode::InitXPAccessibility();
|
||||
gHaveNewTextSignals = g_signal_lookup("text-insert", ATK_TYPE_TEXT);
|
||||
}
|
||||
|
||||
void nsAccessNodeWrap::ShutdownAccessibility()
|
||||
|
|
|
@ -53,6 +53,13 @@ public: // construction, destruction
|
|||
|
||||
static void InitAccessibility();
|
||||
static void ShutdownAccessibility();
|
||||
|
||||
/*
|
||||
* do we have text-remove and text-insert signals if not we need to use
|
||||
* text-changed see nsAccessibleWrap::FireAtkTextChangedEvent() and
|
||||
* bug 619002
|
||||
*/
|
||||
static PRBool gHaveNewTextSignals;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1361,14 +1361,27 @@ nsAccessibleWrap::FireAtkTextChangedEvent(AccEvent* aEvent,
|
|||
PRInt32 start = event->GetStartOffset();
|
||||
PRUint32 length = event->GetLength();
|
||||
PRBool isInserted = event->IsTextInserted();
|
||||
|
||||
PRBool isFromUserInput = aEvent->IsFromUserInput();
|
||||
char* signal_name = nsnull;
|
||||
|
||||
char *signal_name = g_strconcat(isInserted ? "text_changed::insert" : "text_changed::delete",
|
||||
isFromUserInput ? "" : kNonUserInputEvent, NULL);
|
||||
g_signal_emit_by_name(aObject, signal_name, start, length);
|
||||
g_free (signal_name);
|
||||
if (gHaveNewTextSignals) {
|
||||
nsAutoString text;
|
||||
event->GetModifiedText(text);
|
||||
signal_name = g_strconcat(isInserted ? "text-insert" : "text-remove",
|
||||
isFromUserInput ? "" : "::system", NULL);
|
||||
g_signal_emit_by_name(aObject, signal_name, start, length,
|
||||
NS_ConvertUTF16toUTF8(text).get());
|
||||
} else {
|
||||
// XXX remove this code and the gHaveNewTextSignals check when we can
|
||||
// stop supporting old atk since it doesn't really work anyway
|
||||
// see bug 619002
|
||||
signal_name = g_strconcat(isInserted ? "text_changed::insert" :
|
||||
"text_changed::delete",
|
||||
isFromUserInput ? "" : kNonUserInputEvent, NULL);
|
||||
g_signal_emit_by_name(aObject, signal_name, start, length);
|
||||
}
|
||||
|
||||
g_free(signal_name);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -64,7 +64,6 @@ ACCESSIBILITY_ATOM(_false, "false")
|
|||
ACCESSIBILITY_ATOM(image, "image")
|
||||
ACCESSIBILITY_ATOM(menu, "menu")
|
||||
ACCESSIBILITY_ATOM(menuButton, "menu-button")
|
||||
ACCESSIBILITY_ATOM(menugenerated, "menugenerated")
|
||||
ACCESSIBILITY_ATOM(multiple, "multiple")
|
||||
ACCESSIBILITY_ATOM(open, "open")
|
||||
ACCESSIBILITY_ATOM(password, "password")
|
||||
|
|
|
@ -695,9 +695,6 @@ nsAccessible::IsVisible(PRBool* aIsOffscreen)
|
|||
PRUint64
|
||||
nsAccessible::NativeState()
|
||||
{
|
||||
if (IsDefunct())
|
||||
return states::DEFUNCT;
|
||||
|
||||
PRUint64 state = 0;
|
||||
nsEventStates intrinsicState = mContent->IntrinsicState();
|
||||
|
||||
|
@ -1527,10 +1524,10 @@ nsAccessible::GetState(PRUint32* aState, PRUint32* aExtraState)
|
|||
PRUint64
|
||||
nsAccessible::State()
|
||||
{
|
||||
PRUint64 state = NativeState();
|
||||
if (state & states::DEFUNCT)
|
||||
return state;
|
||||
if (IsDefunct())
|
||||
return states::DEFUNCT;
|
||||
|
||||
PRUint64 state = NativeState();
|
||||
// Apply ARIA states to be sure accessible states will be overriden.
|
||||
ApplyARIAState(&state);
|
||||
|
||||
|
|
|
@ -144,7 +144,7 @@ nsApplicationAccessible::GetKeyboardShortcut(nsAString &aKeyboardShortcut)
|
|||
PRUint64
|
||||
nsApplicationAccessible::State()
|
||||
{
|
||||
return NativeState();
|
||||
return IsDefunct() ? states::DEFUNCT : 0;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -375,7 +375,7 @@ nsApplicationAccessible::NativeRole()
|
|||
PRUint64
|
||||
nsApplicationAccessible::NativeState()
|
||||
{
|
||||
return IsDefunct() ? states::DEFUNCT : 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -761,47 +761,6 @@ nsCoreUtils::IsColumnHidden(nsITreeColumn *aColumn)
|
|||
nsAccessibilityAtoms::_true, eCaseMatters);
|
||||
}
|
||||
|
||||
void
|
||||
nsCoreUtils::GeneratePopupTree(nsIContent *aContent, PRBool aIsAnon)
|
||||
{
|
||||
// Set menugenerated="true" on the menupopup node to generate the sub-menu
|
||||
// items if they have not been generated.
|
||||
|
||||
nsCOMPtr<nsIDOMNodeList> list;
|
||||
if (aIsAnon) {
|
||||
nsIDocument* document = aContent->GetCurrentDoc();
|
||||
if (document)
|
||||
document->GetXBLChildNodesFor(aContent, getter_AddRefs(list));
|
||||
|
||||
} else {
|
||||
list = aContent->GetChildNodesList();
|
||||
}
|
||||
|
||||
PRUint32 length = 0;
|
||||
if (!list || NS_FAILED(list->GetLength(&length)))
|
||||
return;
|
||||
|
||||
for (PRUint32 idx = 0; idx < length; idx++) {
|
||||
nsCOMPtr<nsIDOMNode> childNode;
|
||||
list->Item(idx, getter_AddRefs(childNode));
|
||||
nsCOMPtr<nsIContent> child(do_QueryInterface(childNode));
|
||||
|
||||
PRBool isPopup = child->NodeInfo()->Equals(nsAccessibilityAtoms::menupopup,
|
||||
kNameSpaceID_XUL) ||
|
||||
child->NodeInfo()->Equals(nsAccessibilityAtoms::panel,
|
||||
kNameSpaceID_XUL);
|
||||
if (isPopup && !child->AttrValueIs(kNameSpaceID_None,
|
||||
nsAccessibilityAtoms::menugenerated,
|
||||
nsAccessibilityAtoms::_true,
|
||||
eCaseMatters)) {
|
||||
|
||||
child->SetAttr(kNameSpaceID_None, nsAccessibilityAtoms::menugenerated,
|
||||
NS_LITERAL_STRING("true"), PR_TRUE);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsAccessibleDOMStringList
|
||||
|
|
|
@ -367,16 +367,6 @@ public:
|
|||
return aContent->NodeInfo()->Equals(nsAccessibilityAtoms::th) ||
|
||||
aContent->HasAttr(kNameSpaceID_None, nsAccessibilityAtoms::scope);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates frames for popup subtree.
|
||||
*
|
||||
* @param aContent [in] DOM node containing the menupopup element as a child
|
||||
* @param aIsAnon [in] specifies whether popup should be searched inside of
|
||||
* anonymous or explicit content
|
||||
*/
|
||||
static void GeneratePopupTree(nsIContent *aContent,
|
||||
PRBool aIsAnon = PR_FALSE);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -294,10 +294,6 @@ nsDocAccessible::GetDescription(nsAString& aDescription)
|
|||
PRUint64
|
||||
nsDocAccessible::NativeState()
|
||||
{
|
||||
|
||||
if (IsDefunct())
|
||||
return states::DEFUNCT;
|
||||
|
||||
// The root content of the document might be removed so that mContent is
|
||||
// out of date.
|
||||
PRUint64 state = (mContent->GetCurrentDoc() == mDocument) ?
|
||||
|
|
|
@ -89,7 +89,7 @@ nsOuterDocAccessible::GetChildAtPoint(PRInt32 aX, PRInt32 aY,
|
|||
nsAccessible* child = GetChildAt(0);
|
||||
NS_ENSURE_TRUE(child, nsnull);
|
||||
|
||||
if (aWhichChild = eDeepestChild)
|
||||
if (aWhichChild == eDeepestChild)
|
||||
return child->GetChildAtPoint(aX, aY, eDeepestChild);
|
||||
return child;
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
|
||||
#include "gfxFont.h"
|
||||
#include "gfxUserFontSet.h"
|
||||
#include "nsIThebesFontMetrics.h"
|
||||
#include "nsFontMetrics.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Constants and structures
|
||||
|
@ -532,13 +532,12 @@ nsFontWeightTextAttr::GetFontWeight(nsIFrame *aFrame)
|
|||
|
||||
gfxUserFontSet *fs = aFrame->PresContext()->GetUserFontSet();
|
||||
|
||||
nsCOMPtr<nsIFontMetrics> fm;
|
||||
nsRefPtr<nsFontMetrics> fm;
|
||||
aFrame->PresContext()->DeviceContext()->
|
||||
GetMetricsFor(styleFont->mFont, aFrame->GetStyleVisibility()->mLanguage,
|
||||
fs, *getter_AddRefs(fm));
|
||||
|
||||
nsCOMPtr<nsIThebesFontMetrics> tfm = do_QueryInterface(fm);
|
||||
gfxFontGroup *fontGroup = tfm->GetThebesFontGroup();
|
||||
gfxFontGroup *fontGroup = fm->GetThebesFontGroup();
|
||||
gfxFont *font = fontGroup->GetFontAt(0);
|
||||
|
||||
// When there doesn't exist a bold font in the family and so the rendering of
|
||||
|
|
|
@ -422,6 +422,9 @@ nsHTMLTextFieldAccessible::GetNameInternal(nsAString& aName)
|
|||
|
||||
NS_IMETHODIMP nsHTMLTextFieldAccessible::GetValue(nsAString& _retval)
|
||||
{
|
||||
if (IsDefunct())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
if (NativeState() & states::PROTECTED) // Don't return password text!
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
|
|
|
@ -150,7 +150,7 @@ nsHTMLBRAccessible::NativeRole()
|
|||
PRUint64
|
||||
nsHTMLBRAccessible::NativeState()
|
||||
{
|
||||
return IsDefunct() ? states::DEFUNCT : states::READONLY;
|
||||
return states::READONLY;
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
|
|
@ -58,7 +58,6 @@
|
|||
#include "nsIDOMXULDocument.h"
|
||||
#include "nsIEditingSession.h"
|
||||
#include "nsIEditor.h"
|
||||
#include "nsIFontMetrics.h"
|
||||
#include "nsIFrame.h"
|
||||
#include "nsFrameSelection.h"
|
||||
#include "nsILineIterator.h"
|
||||
|
|
|
@ -77,10 +77,7 @@ nsHTMLWin32ObjectOwnerAccessible::NativeState()
|
|||
{
|
||||
// XXX: No HWND means this is windowless plugin which is not accessible in
|
||||
// the meantime.
|
||||
if (mHwnd)
|
||||
return nsAccessibleWrap::NativeState();
|
||||
|
||||
return IsDefunct() ? states::DEFUNCT : states::UNAVAILABLE;
|
||||
return mHwnd ? nsAccessibleWrap::NativeState() : states::UNAVAILABLE;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -36,19 +36,14 @@
|
|||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
// NOTE: alphabetically ordered
|
||||
#include "nsTextAccessibleWrap.h"
|
||||
#include "ISimpleDOMText_i.c"
|
||||
|
||||
#include "nsCoreUtils.h"
|
||||
#include "nsDocAccessible.h"
|
||||
|
||||
#include "nsIThebesFontMetrics.h"
|
||||
#include "nsIFrame.h"
|
||||
#include "nsFontMetrics.h"
|
||||
#include "nsPresContext.h"
|
||||
#include "nsIPresShell.h"
|
||||
#include "nsIRenderingContext.h"
|
||||
#include "nsIComponentManager.h"
|
||||
|
||||
#include "gfxFont.h"
|
||||
|
||||
|
@ -260,16 +255,14 @@ __try {
|
|||
return E_FAIL;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIFontMetrics> fm;
|
||||
nsRefPtr<nsFontMetrics> fm;
|
||||
frame->PresContext()->DeviceContext()->
|
||||
GetMetricsFor(frame->GetStyleFont()->mFont,
|
||||
frame->GetStyleVisibility()->mLanguage,
|
||||
frame->PresContext()->GetUserFontSet(),
|
||||
*getter_AddRefs(fm));
|
||||
|
||||
nsCOMPtr<nsIThebesFontMetrics> tfm = do_QueryInterface(fm);
|
||||
const nsString& name = tfm->GetThebesFontGroup()->GetFontAt(0)->GetName();
|
||||
|
||||
const nsString& name = fm->GetThebesFontGroup()->GetFontAt(0)->GetName();
|
||||
if (name.IsEmpty())
|
||||
return S_FALSE;
|
||||
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
#include "nsRect.h"
|
||||
|
||||
class nsIFrame;
|
||||
class nsIRenderingContext;
|
||||
class nsRenderingContext;
|
||||
|
||||
class nsTextAccessibleWrap : public nsTextAccessible,
|
||||
public ISimpleDOMText
|
||||
|
|
|
@ -153,10 +153,6 @@ nsXFormsAccessible::GetValue(nsAString& aValue)
|
|||
PRUint64
|
||||
nsXFormsAccessible::NativeState()
|
||||
{
|
||||
|
||||
if (IsDefunct())
|
||||
return states::DEFUNCT;
|
||||
|
||||
NS_ENSURE_TRUE(sXFormsService, 0);
|
||||
|
||||
nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mContent));
|
||||
|
|
|
@ -60,10 +60,6 @@ nsXFormsDropmarkerWidgetAccessible::NativeRole()
|
|||
PRUint64
|
||||
nsXFormsDropmarkerWidgetAccessible::NativeState()
|
||||
{
|
||||
|
||||
if (IsDefunct())
|
||||
return states::DEFUNCT;
|
||||
|
||||
PRBool isOpen = PR_FALSE;
|
||||
nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mContent));
|
||||
nsresult rv = sXFormsService->IsDropmarkerOpen(DOMNode, &isOpen);
|
||||
|
|
|
@ -116,19 +116,6 @@ nsXULColorPickerAccessible::
|
|||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsXULColorPickerAccessible: nsAccessNode
|
||||
|
||||
PRBool
|
||||
nsXULColorPickerAccessible::Init()
|
||||
{
|
||||
if (!nsXULColorPickerTileAccessible::Init())
|
||||
return PR_FALSE;
|
||||
|
||||
nsCoreUtils::GeneratePopupTree(mContent, PR_TRUE);
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsXULColorPickerAccessible: nsAccessible
|
||||
|
||||
|
|
|
@ -68,9 +68,6 @@ class nsXULColorPickerAccessible : public nsXULColorPickerTileAccessible
|
|||
public:
|
||||
nsXULColorPickerAccessible(nsIContent *aContent, nsIWeakReference *aShell);
|
||||
|
||||
// nsAccessNode
|
||||
virtual PRBool Init();
|
||||
|
||||
// nsAccessible
|
||||
virtual PRUint32 NativeRole();
|
||||
virtual PRUint64 NativeState();
|
||||
|
|
|
@ -57,16 +57,6 @@ nsXULComboboxAccessible::
|
|||
{
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsXULComboboxAccessible::Init()
|
||||
{
|
||||
if (!nsAccessibleWrap::Init())
|
||||
return PR_FALSE;
|
||||
|
||||
nsCoreUtils::GeneratePopupTree(mContent);
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
PRUint32
|
||||
nsXULComboboxAccessible::NativeRole()
|
||||
{
|
||||
|
|
|
@ -60,9 +60,6 @@ public:
|
|||
NS_IMETHOD GetNumActions(PRUint8 *aNumActions);
|
||||
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
|
||||
|
||||
// nsAccessNode
|
||||
virtual PRBool Init();
|
||||
|
||||
// nsAccessible
|
||||
virtual PRUint32 NativeRole();
|
||||
virtual PRUint64 NativeState();
|
||||
|
|
|
@ -109,21 +109,6 @@ nsXULButtonAccessible::DoAction(PRUint8 aIndex)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsXULButtonAccessible: nsAccessNode
|
||||
|
||||
PRBool
|
||||
nsXULButtonAccessible::Init()
|
||||
{
|
||||
if (!nsAccessibleWrap::Init())
|
||||
return PR_FALSE;
|
||||
|
||||
if (ContainsMenu())
|
||||
nsCoreUtils::GeneratePopupTree(mContent);
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsXULButtonAccessible: nsAccessible
|
||||
|
||||
|
@ -330,10 +315,6 @@ nsXULDropmarkerAccessible::NativeRole()
|
|||
PRUint64
|
||||
nsXULDropmarkerAccessible::NativeState()
|
||||
{
|
||||
|
||||
if (IsDefunct())
|
||||
return states::DEFUNCT;
|
||||
|
||||
return DropmarkerOpen(PR_FALSE) ? states::PRESSED : 0;
|
||||
}
|
||||
|
||||
|
@ -815,7 +796,7 @@ nsXULToolbarSeparatorAccessible::NativeRole()
|
|||
PRUint64
|
||||
nsXULToolbarSeparatorAccessible::NativeState()
|
||||
{
|
||||
return IsDefunct() ? states::DEFUNCT : 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -66,9 +66,6 @@ public:
|
|||
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
|
||||
NS_IMETHOD DoAction(PRUint8 index);
|
||||
|
||||
// nsAccessNode
|
||||
virtual PRBool Init();
|
||||
|
||||
// nsAccessible
|
||||
virtual PRUint32 NativeRole();
|
||||
virtual PRUint64 NativeState();
|
||||
|
|
|
@ -67,7 +67,7 @@ nsXULColumnsAccessible::NativeRole()
|
|||
PRUint64
|
||||
nsXULColumnsAccessible::NativeState()
|
||||
{
|
||||
return IsDefunct() ? states::DEFUNCT : states::READONLY;
|
||||
return states::READONLY;
|
||||
}
|
||||
|
||||
|
||||
|
@ -90,7 +90,7 @@ nsXULColumnItemAccessible::NativeRole()
|
|||
PRUint64
|
||||
nsXULColumnItemAccessible::NativeState()
|
||||
{
|
||||
return IsDefunct() ? states::DEFUNCT : states::READONLY;
|
||||
return states::READONLY;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -906,12 +906,8 @@ nsXULListitemAccessible::NativeRole()
|
|||
PRUint64
|
||||
nsXULListitemAccessible::NativeState()
|
||||
{
|
||||
if (mIsCheckbox) {
|
||||
if (mIsCheckbox)
|
||||
return nsXULMenuitemAccessible::NativeState();
|
||||
}
|
||||
|
||||
if (IsDefunct())
|
||||
return states::DEFUNCT;
|
||||
|
||||
PRUint64 states = states::FOCUSABLE | states::SELECTABLE;
|
||||
|
||||
|
|
|
@ -280,16 +280,6 @@ nsXULMenuitemAccessible::
|
|||
{
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsXULMenuitemAccessible::Init()
|
||||
{
|
||||
if (!nsAccessibleWrap::Init())
|
||||
return PR_FALSE;
|
||||
|
||||
nsCoreUtils::GeneratePopupTree(mContent);
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
PRUint64
|
||||
nsXULMenuitemAccessible::NativeState()
|
||||
{
|
||||
|
|
|
@ -89,9 +89,6 @@ public:
|
|||
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
|
||||
NS_IMETHOD GetNumActions(PRUint8 *_retval);
|
||||
|
||||
// nsAccessNode
|
||||
virtual PRBool Init();
|
||||
|
||||
// nsAccessible
|
||||
virtual nsresult GetNameInternal(nsAString& aName);
|
||||
virtual PRUint32 NativeRole();
|
||||
|
|
|
@ -927,10 +927,6 @@ nsXULTreeItemAccessibleBase::GroupPosition(PRInt32 *aGroupLevel,
|
|||
PRUint64
|
||||
nsXULTreeItemAccessibleBase::NativeState()
|
||||
{
|
||||
|
||||
if (IsDefunct())
|
||||
return states::DEFUNCT;
|
||||
|
||||
// focusable and selectable states
|
||||
PRUint64 state = states::FOCUSABLE | states::SELECTABLE;
|
||||
|
||||
|
|
|
@ -1165,10 +1165,6 @@ nsXULTreeGridCellAccessible::NativeRole()
|
|||
PRUint64
|
||||
nsXULTreeGridCellAccessible::NativeState()
|
||||
{
|
||||
|
||||
if (IsDefunct())
|
||||
return states::DEFUNCT;
|
||||
|
||||
// selectable/selected state
|
||||
PRUint64 states = states::SELECTABLE;
|
||||
|
||||
|
|
|
@ -29,7 +29,12 @@
|
|||
{
|
||||
ID: "menu",
|
||||
actionName: "click",
|
||||
events: CLICK_EVENTS
|
||||
events: CLICK_EVENTS,
|
||||
// Wait for focus event, it guarantees us the submenu tree is created,
|
||||
// that's necessary for next test.
|
||||
eventSeq: [
|
||||
new invokerChecker(EVENT_FOCUS, getNode("menu"))
|
||||
]
|
||||
},
|
||||
{
|
||||
ID: "submenu",
|
||||
|
|
|
@ -51,7 +51,6 @@ _TEST_FILES =\
|
|||
test_aria_globals.html \
|
||||
test_aria_imgmap.html \
|
||||
test_button.xul \
|
||||
test_colorpicker.xul \
|
||||
test_combobox.xul \
|
||||
test_cssoverflow.html \
|
||||
test_dochierarchy.html \
|
||||
|
@ -65,7 +64,6 @@ _TEST_FILES =\
|
|||
test_img.html \
|
||||
test_list.html \
|
||||
test_media.html \
|
||||
test_menu.xul \
|
||||
test_select.html \
|
||||
test_tabbox.xul \
|
||||
test_tabbrowser.xul \
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
function doTest()
|
||||
{
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// button1
|
||||
// button
|
||||
|
||||
var accTree = {
|
||||
role: ROLE_PUSHBUTTON,
|
||||
|
@ -34,112 +34,14 @@
|
|||
testAccessibleTree("button1", accTree);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// button2
|
||||
|
||||
accTree = {
|
||||
role: ROLE_PUSHBUTTON,
|
||||
name: "hello",
|
||||
children: [
|
||||
{
|
||||
role: ROLE_MENUPOPUP,
|
||||
children: [
|
||||
{
|
||||
role: ROLE_MENUITEM
|
||||
},
|
||||
{
|
||||
role: ROLE_MENUITEM
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
testAccessibleTree("button2", accTree);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// button3
|
||||
|
||||
accTree = {
|
||||
role: ROLE_PUSHBUTTON,
|
||||
name: "hello",
|
||||
children: [
|
||||
{
|
||||
role: ROLE_MENUPOPUP,
|
||||
children: [
|
||||
{
|
||||
role: ROLE_MENUITEM
|
||||
},
|
||||
{
|
||||
role: ROLE_MENUITEM
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
role: ROLE_PUSHBUTTON,
|
||||
children: [
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
testAccessibleTree("button3", accTree);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// button4
|
||||
// toolbarbutton
|
||||
|
||||
var accTree = {
|
||||
role: ROLE_PUSHBUTTON,
|
||||
name: "hello",
|
||||
children: [ ]
|
||||
};
|
||||
testAccessibleTree("button4", accTree);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// button5
|
||||
|
||||
accTree = {
|
||||
role: ROLE_PUSHBUTTON,
|
||||
name: "hello",
|
||||
children: [
|
||||
{
|
||||
role: ROLE_MENUPOPUP,
|
||||
children: [
|
||||
{
|
||||
role: ROLE_MENUITEM
|
||||
},
|
||||
{
|
||||
role: ROLE_MENUITEM
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
testAccessibleTree("button5", accTree);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// button6
|
||||
|
||||
accTree = {
|
||||
role: ROLE_PUSHBUTTON,
|
||||
name: "hello",
|
||||
children: [
|
||||
{
|
||||
role: ROLE_MENUPOPUP,
|
||||
children: [
|
||||
{
|
||||
role: ROLE_MENUITEM
|
||||
},
|
||||
{
|
||||
role: ROLE_MENUITEM
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
role: ROLE_PUSHBUTTON,
|
||||
children: [
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
testAccessibleTree("button6", accTree);
|
||||
testAccessibleTree("button2", accTree);
|
||||
|
||||
SimpleTest.finish()
|
||||
}
|
||||
|
@ -165,32 +67,7 @@
|
|||
|
||||
<vbox flex="1">
|
||||
<button id="button1" label="hello"/>
|
||||
<button id="button2" type="menu" label="hello">
|
||||
<menupopup>
|
||||
<menuitem label="menuitem"/>
|
||||
<menuitem label="menuitem"/>
|
||||
</menupopup>
|
||||
</button>
|
||||
<button id="button3" type="menu-button" label="hello">
|
||||
<menupopup>
|
||||
<menuitem label="menuitem"/>
|
||||
<menuitem label="menuitem"/>
|
||||
</menupopup>
|
||||
</button>
|
||||
|
||||
<toolbarbutton id="button4" label="hello"/>
|
||||
<toolbarbutton id="button5" type="menu" label="hello">
|
||||
<menupopup>
|
||||
<menuitem label="menuitem"/>
|
||||
<menuitem label="menuitem"/>
|
||||
</menupopup>
|
||||
</toolbarbutton>
|
||||
<toolbarbutton id="button6" type="menu-button" label="hello">
|
||||
<menupopup>
|
||||
<menuitem label="menuitem"/>
|
||||
<menuitem label="menuitem"/>
|
||||
</menupopup>
|
||||
</toolbarbutton>
|
||||
<toolbarbutton id="button2" label="hello"/>
|
||||
</vbox>
|
||||
</hbox>
|
||||
|
||||
|
|
|
@ -1,75 +0,0 @@
|
|||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
|
||||
type="text/css"?>
|
||||
|
||||
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
title="Accessible XUL button hierarchy tests">
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/MochiKit/packed.js" />
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
|
||||
|
||||
<script type="application/javascript"
|
||||
src="../common.js" />
|
||||
<script type="application/javascript"
|
||||
src="../role.js" />
|
||||
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Test
|
||||
|
||||
function doTest()
|
||||
{
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// button1
|
||||
|
||||
var accTree = {
|
||||
role: ROLE_BUTTONDROPDOWNGRID,
|
||||
children: [
|
||||
{
|
||||
role: ROLE_ALERT,
|
||||
children: [ ]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
var colorButtons = accTree.children[0].children;
|
||||
for (var idx = 0; idx < 70; idx++) {
|
||||
var obj = { role: ROLE_PUSHBUTTON };
|
||||
colorButtons.push(obj);
|
||||
}
|
||||
|
||||
testAccessibleTree("colorpicker", accTree);
|
||||
|
||||
SimpleTest.finish()
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTest);
|
||||
]]>
|
||||
</script>
|
||||
|
||||
<hbox flex="1" style="overflow: auto;">
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=249292"
|
||||
title="Ensure accessible children for toolbarbutton types 'menu' and 'menu-button'">
|
||||
Mozilla Bug 249292
|
||||
</a><br/>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
</div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
</body>
|
||||
|
||||
<vbox flex="1">
|
||||
<colorpicker id="colorpicker" type="button"/>
|
||||
</vbox>
|
||||
</hbox>
|
||||
|
||||
</window>
|
||||
|
|
@ -1,86 +0,0 @@
|
|||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
|
||||
type="text/css"?>
|
||||
|
||||
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
title="Accessible XUL menu hierarchy tests">
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/MochiKit/packed.js" />
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
|
||||
|
||||
<script type="application/javascript"
|
||||
src="../common.js" />
|
||||
<script type="application/javascript"
|
||||
src="../role.js" />
|
||||
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Test
|
||||
|
||||
function doTest()
|
||||
{
|
||||
if (LINUX || SOLARIS) {
|
||||
// XXX: bug 527646
|
||||
|
||||
todo(false, "Failure on Linux and Solaris.");
|
||||
SimpleTest.finish();
|
||||
return;
|
||||
}
|
||||
|
||||
var accTree = {
|
||||
role: ROLE_PARENT_MENUITEM,
|
||||
name: "menu",
|
||||
children: [
|
||||
{
|
||||
role: ROLE_MENUPOPUP,
|
||||
children: [
|
||||
{
|
||||
role: ROLE_MENUITEM
|
||||
},
|
||||
{
|
||||
role: ROLE_MENUITEM
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
testAccessibleTree("menu", accTree);
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTest);
|
||||
]]>
|
||||
</script>
|
||||
|
||||
<hbox flex="1" style="overflow: auto;">
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=249292"
|
||||
title="Ensure accessible children for toolbarbutton types 'menu' and 'menu-button'">
|
||||
Mozilla Bug 249292
|
||||
</a><br/>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
</div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
</body>
|
||||
|
||||
<vbox flex="1">
|
||||
<menu id="menu" label="menu">
|
||||
<menupopup>
|
||||
<menuitem label="menuitem"/>
|
||||
<menuitem label="menuitem"/>
|
||||
</menupopup>
|
||||
</menu>
|
||||
</vbox>
|
||||
</hbox>
|
||||
|
||||
</window>
|
||||
|
|
@ -47,11 +47,14 @@ include $(topsrcdir)/config/rules.mk
|
|||
|
||||
_TEST_FILES =\
|
||||
test_ariadialog.html \
|
||||
test_colorpicker.xul \
|
||||
test_contextmenu.xul \
|
||||
test_doc.html \
|
||||
test_gencontent.html \
|
||||
test_list_editabledoc.html \
|
||||
test_list.html \
|
||||
test_menu.xul \
|
||||
test_menubutton.xul \
|
||||
test_recreation.html \
|
||||
test_select.html \
|
||||
test_textleaf.html \
|
||||
|
|
|
@ -0,0 +1,152 @@
|
|||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
|
||||
type="text/css"?>
|
||||
|
||||
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
title="Accessible XUL button hierarchy tests">
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/MochiKit/packed.js" />
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
|
||||
|
||||
<script type="application/javascript"
|
||||
src="../common.js" />
|
||||
<script type="application/javascript"
|
||||
src="../role.js" />
|
||||
<script type="application/javascript"
|
||||
src="../events.js" />
|
||||
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Test
|
||||
|
||||
function openColorpicker(aColorpickerID)
|
||||
{
|
||||
this.node = getNode(aColorpickerID);
|
||||
|
||||
this.eventSeq = [];
|
||||
|
||||
var it = new colorButtonIterator(this.node);
|
||||
for (var btnNode = it.next(); btnNode = it.next(); btnNode)
|
||||
this.eventSeq.push(new invokerChecker(EVENT_SHOW, btnNode));
|
||||
|
||||
var popupNode = getPopupNode(this.node);
|
||||
this.eventSeq.push(new invokerChecker(EVENT_REORDER, popupNode));
|
||||
|
||||
this.invoke = function openColorpicker_invoke()
|
||||
{
|
||||
var tree =
|
||||
{ BUTTONDROPDOWNGRID: [
|
||||
{ ALERT: [ ] }
|
||||
] };
|
||||
testAccessibleTree(this.node, tree);
|
||||
|
||||
this.node.showPopup();
|
||||
}
|
||||
|
||||
this.finalCheck = function openColorpicker_finalCheck()
|
||||
{
|
||||
var tree =
|
||||
{ BUTTONDROPDOWNGRID: [
|
||||
{ ALERT: [ ] }
|
||||
] };
|
||||
|
||||
var colorButtons = tree.BUTTONDROPDOWNGRID[0].ALERT;
|
||||
var it = new colorButtonIterator(this.node);
|
||||
while (it.next()) {
|
||||
var obj = { PUSHBUTTON: [ ] };
|
||||
colorButtons.push(obj);
|
||||
}
|
||||
|
||||
testAccessibleTree(this.node, tree);
|
||||
}
|
||||
|
||||
this.getID = function openColorpicker_getID()
|
||||
{
|
||||
return "open colorpicker " + prettyName(aColorpickerID);
|
||||
}
|
||||
}
|
||||
|
||||
function getPopupNode(aColorpickerNode)
|
||||
{
|
||||
return aColorpickerNode.mPicker.parentNode;
|
||||
}
|
||||
|
||||
function colorButtonIterator(aColorpickerNode)
|
||||
{
|
||||
this.container = aColorpickerNode.mPicker.mBox;
|
||||
this.group = this.container.firstChild;
|
||||
this.item = null;
|
||||
|
||||
this.next = function colorButtonIterator_next()
|
||||
{
|
||||
if (!this.group)
|
||||
return null;
|
||||
|
||||
if (!this.item) {
|
||||
this.item = this.group.firstChild;
|
||||
return this.item;
|
||||
}
|
||||
|
||||
if (this.item.nextSibling) {
|
||||
this.item = this.item.nextSibling;
|
||||
return this.item;
|
||||
}
|
||||
|
||||
if (this.group.nextSibling) {
|
||||
this.group = this.group.nextSibling;
|
||||
this.item = this.group.firstChild;
|
||||
return this.item;
|
||||
}
|
||||
|
||||
this.group = null;
|
||||
this.item = null;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
//gA11yEventDumpToConsole = true; // debug stuff
|
||||
|
||||
var gQueue = null;
|
||||
function doTest()
|
||||
{
|
||||
gQueue = new eventQueue();
|
||||
gQueue.push(new openColorpicker("colorpicker"));
|
||||
gQueue.invoke(); // Will call SimpleTest.finish()
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTest);
|
||||
]]>
|
||||
</script>
|
||||
|
||||
<hbox flex="1" style="overflow: auto;">
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=249292"
|
||||
title="Ensure accessible children for toolbarbutton types 'menu' and 'menu-button'">
|
||||
Mozilla Bug 249292
|
||||
</a>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=630486"
|
||||
title="Don't force accessible creation for popup children.">
|
||||
Mozilla Bug 630486
|
||||
</a>
|
||||
<br/>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
</div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
</body>
|
||||
|
||||
<vbox flex="1">
|
||||
<colorpicker id="colorpicker" type="button"/>
|
||||
</vbox>
|
||||
</hbox>
|
||||
|
||||
</window>
|
||||
|
|
@ -0,0 +1,321 @@
|
|||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
|
||||
type="text/css"?>
|
||||
|
||||
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
title="menu tree and events">
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/MochiKit/packed.js" />
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"/>
|
||||
|
||||
<script type="application/javascript"
|
||||
src="../common.js" />
|
||||
<script type="application/javascript"
|
||||
src="../events.js" />
|
||||
<script type="application/javascript"
|
||||
src="../role.js" />
|
||||
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
|
||||
function openMenu(aID, aTree)
|
||||
{
|
||||
this.eventSeq = [
|
||||
new invokerChecker(EVENT_MENUPOPUP_START, getNode(aID))
|
||||
];
|
||||
|
||||
this.invoke = function openMenu_invoke()
|
||||
{
|
||||
var button = getNode("button");
|
||||
getNode(aID).openPopup(button, "after_start", 0, 0, true, false);
|
||||
}
|
||||
|
||||
this.finalCheck = function openMenu_finalCheck(aEvent)
|
||||
{
|
||||
testAccessibleTree(aID, aTree);
|
||||
}
|
||||
|
||||
this.getID = function openMenu_getID()
|
||||
{
|
||||
return "open menu " + prettyName(aID);
|
||||
}
|
||||
}
|
||||
|
||||
function selectNextMenuItem(aID)
|
||||
{
|
||||
this.eventSeq = [
|
||||
new invokerChecker(EVENT_FOCUS, getNode(aID))
|
||||
];
|
||||
|
||||
this.invoke = function selectMenuItem_invoke()
|
||||
{
|
||||
synthesizeKey("VK_DOWN", { });
|
||||
}
|
||||
|
||||
this.getID = function selectMenuItem_getID()
|
||||
{
|
||||
return "select menuitem " + prettyName(aID);
|
||||
}
|
||||
}
|
||||
|
||||
function openSubMenu(aSubMenuID, aItemID, aMenuID, aTree)
|
||||
{
|
||||
this.eventSeq = [
|
||||
new invokerChecker(EVENT_FOCUS, getNode(aItemID)),
|
||||
];
|
||||
|
||||
this.invoke = function openSubMenu_invoke()
|
||||
{
|
||||
synthesizeKey("VK_ENTER", { });
|
||||
}
|
||||
|
||||
this.finalCheck = function openSubMenu_finalCheck(aEvent)
|
||||
{
|
||||
testAccessibleTree(aMenuID, aTree);
|
||||
}
|
||||
|
||||
this.getID = function openSubMenu_getID()
|
||||
{
|
||||
return "open submenu " + prettyName(aSubMenuID) + " focusing item " + prettyName(aItemID);
|
||||
}
|
||||
}
|
||||
|
||||
function closeSubMenu(aSubMenuID, aItemID)
|
||||
{
|
||||
this.eventSeq = [
|
||||
new invokerChecker(EVENT_FOCUS, getNode(aItemID)),
|
||||
];
|
||||
|
||||
this.invoke = function closeSubMenu_invoke()
|
||||
{
|
||||
synthesizeKey("VK_ESCAPE", { });
|
||||
}
|
||||
|
||||
this.getID = function closeSubMenu_getID()
|
||||
{
|
||||
return "close submenu " + prettyName(aSubMenuID) + " focusing item " + prettyName(aItemID);
|
||||
}
|
||||
}
|
||||
|
||||
function closeMenu(aID)
|
||||
{
|
||||
this.eventSeq = [
|
||||
new invokerChecker(EVENT_MENUPOPUP_END, getNode(aID))
|
||||
];
|
||||
|
||||
this.invoke = function closeMenu_invoke()
|
||||
{
|
||||
synthesizeKey("VK_ESCAPE", { });
|
||||
}
|
||||
|
||||
this.getID = function closeMenu_getID()
|
||||
{
|
||||
return "close menu " + prettyName(aID);
|
||||
}
|
||||
}
|
||||
|
||||
//gA11yEventDumpID = "eventdump";
|
||||
//gA11yEventDumpToConsole = true;
|
||||
|
||||
var gQueue = null;
|
||||
var gContextTree = {};
|
||||
|
||||
// Linux and Windows menu trees discrepancy: bug 527646.
|
||||
|
||||
/**
|
||||
* Return the context menu tree before submenus were open.
|
||||
*/
|
||||
function getMenuTree1()
|
||||
{
|
||||
if (LINUX || SOLARIS) {
|
||||
var tree = {
|
||||
role: ROLE_MENUPOPUP,
|
||||
children: [
|
||||
{
|
||||
name: "item0",
|
||||
role: ROLE_MENUITEM,
|
||||
children: []
|
||||
},
|
||||
{
|
||||
name: "item1",
|
||||
role: ROLE_MENUITEM,
|
||||
children: []
|
||||
},
|
||||
{
|
||||
name: "item2",
|
||||
role: ROLE_PARENT_MENUITEM,
|
||||
children: [ ]
|
||||
}
|
||||
]
|
||||
};
|
||||
return tree;
|
||||
}
|
||||
|
||||
// Windows
|
||||
var tree = {
|
||||
role: ROLE_MENUPOPUP,
|
||||
children: [
|
||||
{
|
||||
name: "item0",
|
||||
role: ROLE_MENUITEM,
|
||||
children: []
|
||||
},
|
||||
{
|
||||
name: "item1",
|
||||
role: ROLE_MENUITEM,
|
||||
children: []
|
||||
},
|
||||
{
|
||||
name: "item2",
|
||||
role: ROLE_PARENT_MENUITEM,
|
||||
children: [
|
||||
{
|
||||
name: "item2",
|
||||
role: ROLE_MENUPOPUP,
|
||||
children: [ ]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
return tree;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return context menu tree when submenu was open.
|
||||
*/
|
||||
function getMenuTree2()
|
||||
{
|
||||
var tree = getMenuTree1();
|
||||
if (LINUX || SOLARIS) {
|
||||
var submenuTree =
|
||||
{
|
||||
name: "item2.0",
|
||||
role: ROLE_PARENT_MENUITEM,
|
||||
children: [ ]
|
||||
};
|
||||
tree.children[2].children.push(submenuTree);
|
||||
return tree;
|
||||
}
|
||||
|
||||
// Windows
|
||||
var submenuTree =
|
||||
{
|
||||
name: "item2.0",
|
||||
role: ROLE_PARENT_MENUITEM,
|
||||
children: [
|
||||
{
|
||||
name: "item2.0",
|
||||
role: ROLE_MENUPOPUP,
|
||||
children: [ ]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
tree.children[2].children[0].children.push(submenuTree);
|
||||
return tree;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return context menu tree when subsub menu was open.
|
||||
*/
|
||||
function getMenuTree3()
|
||||
{
|
||||
var tree = getMenuTree2();
|
||||
var subsubmenuTree =
|
||||
{
|
||||
name: "item2.0.0",
|
||||
role: ROLE_MENUITEM,
|
||||
children: []
|
||||
};
|
||||
|
||||
if (LINUX || SOLARIS)
|
||||
tree.children[2].children[0].\(subsubmenuTree);
|
||||
else
|
||||
tree.children[2].children[0].children[0].children[0].children.push(subsubmenuTree);
|
||||
|
||||
return tree;
|
||||
}
|
||||
|
||||
|
||||
function doTests()
|
||||
{
|
||||
gQueue = new eventQueue();
|
||||
|
||||
// Check initial empty tree
|
||||
testAccessibleTree("context", { MENUPOPUP: [] });
|
||||
|
||||
// Open context menu and check that menu item accesibles are created.
|
||||
gQueue.push(new openMenu("context", getMenuTree1()));
|
||||
|
||||
// Select items and check focus event on them.
|
||||
gQueue.push(new selectNextMenuItem("item0"));
|
||||
gQueue.push(new selectNextMenuItem("item1"));
|
||||
gQueue.push(new selectNextMenuItem("item2"));
|
||||
|
||||
// Open sub menu and check menu accessible tree and focus event.
|
||||
gQueue.push(new openSubMenu("submenu2", "item2.0",
|
||||
"context", getMenuTree2()));
|
||||
gQueue.push(new openSubMenu("submenu2.0", "item2.0.0",
|
||||
"context", getMenuTree3()));
|
||||
|
||||
// Close submenus and check that focus goes to parent.
|
||||
gQueue.push(new closeSubMenu("submenu2.0", "item2.0"));
|
||||
gQueue.push(new closeSubMenu("submenu2", "item2"));
|
||||
|
||||
gQueue.push(new closeMenu("context"));
|
||||
|
||||
gQueue.invoke(); // Will call SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTests);
|
||||
]]>
|
||||
</script>
|
||||
|
||||
<hbox flex="1" style="overflow: auto;">
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=630194"
|
||||
title="Update accessible tree when opening the menu popup">
|
||||
Mozilla Bug 630194
|
||||
</a>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=630486"
|
||||
title="Don't force accessible creation for popup children.">
|
||||
Mozilla Bug 630486
|
||||
</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
</div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
</body>
|
||||
|
||||
<vbox flex="1">
|
||||
|
||||
<menupopup id="context">
|
||||
<menuitem id="item0" label="item0"/>
|
||||
<menuitem id="item1" label="item1"/>
|
||||
<menu id="item2" label="item2">
|
||||
<menupopup id="submenu2">
|
||||
<menu id="item2.0" label="item2.0">
|
||||
<menupopup id="submenu2.0">
|
||||
<menuitem id="item2.0.0" label="item2.0.0"/>
|
||||
</menupopup>
|
||||
</menu>
|
||||
</menupopup>
|
||||
</menu>
|
||||
</menupopup>
|
||||
|
||||
<button context="context" id="button">btn</button>
|
||||
|
||||
<vbox id="eventdump" role="log"/>
|
||||
</vbox>
|
||||
</hbox>
|
||||
</window>
|
|
@ -4,39 +4,72 @@
|
|||
type="text/css"?>
|
||||
|
||||
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
title="menu tree and events">
|
||||
title="Accessible XUL menu hierarchy tests">
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/MochiKit/packed.js" />
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"/>
|
||||
|
||||
<script type="application/javascript"
|
||||
src="../common.js" />
|
||||
<script type="application/javascript"
|
||||
src="../events.js" />
|
||||
<script type="application/javascript"
|
||||
src="../role.js" />
|
||||
<script type="application/javascript"
|
||||
src="../events.js" />
|
||||
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
function openMenu(aID, aTree)
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Invokers
|
||||
|
||||
function openMenu(aID)
|
||||
{
|
||||
this.menuNode = getNode(aID),
|
||||
|
||||
this.eventSeq = [
|
||||
new invokerChecker(EVENT_MENUPOPUP_START, getNode(aID))
|
||||
new invokerChecker(EVENT_FOCUS, this.menuNode)
|
||||
];
|
||||
|
||||
this.invoke = function openMenu_invoke()
|
||||
{
|
||||
var button = getNode("button");
|
||||
getNode(aID).openPopup(button, "after_start", 0, 0, true, false);
|
||||
var tree;
|
||||
if (LINUX || SOLARIS) {
|
||||
tree =
|
||||
{ PARENT_MENUITEM: [ ] };
|
||||
|
||||
} else {
|
||||
tree =
|
||||
{ PARENT_MENUITEM: [
|
||||
{ MENUPOPUP: [ ] }
|
||||
] };
|
||||
}
|
||||
testAccessibleTree(aID, tree);
|
||||
|
||||
// Show menu.
|
||||
this.menuNode.open = true;
|
||||
}
|
||||
|
||||
this.finalCheck = function openMenu_finalCheck(aEvent)
|
||||
this.finalCheck = function openMenu_finalCheck()
|
||||
{
|
||||
testAccessibleTree(aID, aTree);
|
||||
var tree;
|
||||
if (LINUX || SOLARIS) {
|
||||
tree =
|
||||
{ PARENT_MENUITEM: [
|
||||
{ MENUITEM: [ ] },
|
||||
{ MENUITEM: [ ] }
|
||||
] };
|
||||
|
||||
} else {
|
||||
tree =
|
||||
{ PARENT_MENUITEM: [
|
||||
{ MENUPOPUP: [
|
||||
{ MENUITEM: [ ] },
|
||||
{ MENUITEM: [ ] }
|
||||
] }
|
||||
] };
|
||||
}
|
||||
testAccessibleTree(aID, tree);
|
||||
}
|
||||
|
||||
this.getID = function openMenu_getID()
|
||||
|
@ -45,233 +78,53 @@
|
|||
}
|
||||
}
|
||||
|
||||
function selectNextMenuItem(aID)
|
||||
{
|
||||
this.eventSeq = [
|
||||
new invokerChecker(EVENT_FOCUS, getNode(aID))
|
||||
];
|
||||
|
||||
this.invoke = function selectMenuItem_invoke()
|
||||
{
|
||||
synthesizeKey("VK_DOWN", { });
|
||||
}
|
||||
|
||||
this.getID = function selectMenuItem_getID()
|
||||
{
|
||||
return "select menuitem " + prettyName(aID);
|
||||
}
|
||||
}
|
||||
|
||||
function openSubMenu(aSubMenuID, aItemID)
|
||||
{
|
||||
this.eventSeq = [
|
||||
new invokerChecker(EVENT_FOCUS, getNode(aItemID)),
|
||||
];
|
||||
|
||||
this.invoke = function openSubMenu_invoke()
|
||||
{
|
||||
synthesizeKey("VK_ENTER", { });
|
||||
}
|
||||
|
||||
this.finalCheck = function openSubMenu_finalCheck(aEvent)
|
||||
{
|
||||
getAccessible(aItemID);
|
||||
}
|
||||
|
||||
this.getID = function openSubMenu_getID()
|
||||
{
|
||||
return "open submenu " + prettyName(aSubMenuID) + " focusing item " + prettyName(aItemID);
|
||||
}
|
||||
}
|
||||
|
||||
function closeSubMenu(aSubMenuID, aItemID)
|
||||
{
|
||||
this.eventSeq = [
|
||||
new invokerChecker(EVENT_FOCUS, getNode(aItemID)),
|
||||
];
|
||||
|
||||
this.invoke = function closeSubMenu_invoke()
|
||||
{
|
||||
synthesizeKey("VK_ESCAPE", { });
|
||||
}
|
||||
|
||||
this.getID = function closeSubMenu_getID()
|
||||
{
|
||||
return "close submenu " + prettyName(aSubMenuID) + " focusing item " + prettyName(aItemID);
|
||||
}
|
||||
}
|
||||
|
||||
function closeMenu(aID)
|
||||
{
|
||||
this.eventSeq = [
|
||||
new invokerChecker(EVENT_MENUPOPUP_END, getNode(aID))
|
||||
];
|
||||
|
||||
this.invoke = function closeMenu_invoke()
|
||||
{
|
||||
synthesizeKey("VK_ESCAPE", { });
|
||||
}
|
||||
|
||||
this.getID = function closeMenu_getID()
|
||||
{
|
||||
return "close menu " + prettyName(aID);
|
||||
}
|
||||
}
|
||||
|
||||
//gA11yEventDumpID = "eventdump";
|
||||
//gA11yEventDumpToConsole = true;
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Test
|
||||
|
||||
var gQueue = null;
|
||||
var gContextTree = {};
|
||||
|
||||
// bug 527646
|
||||
if (LINUX || SOLARIS) {
|
||||
gContextTree = {
|
||||
role: ROLE_MENUPOPUP,
|
||||
children: [
|
||||
{
|
||||
name: "item0",
|
||||
role: ROLE_MENUITEM,
|
||||
children: []
|
||||
},
|
||||
{
|
||||
name: "item1",
|
||||
role: ROLE_MENUITEM,
|
||||
children: []
|
||||
},
|
||||
{
|
||||
name: "item2",
|
||||
role: ROLE_PARENT_MENUITEM,
|
||||
children: [
|
||||
{
|
||||
name: "item2.0",
|
||||
role: ROLE_PARENT_MENUITEM,
|
||||
children: [
|
||||
{
|
||||
name: "item2.0.0",
|
||||
role: ROLE_MENUITEM,
|
||||
children: []
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
} else {
|
||||
gContextTree = {
|
||||
role: ROLE_MENUPOPUP,
|
||||
children: [
|
||||
{
|
||||
name: "item0",
|
||||
role: ROLE_MENUITEM,
|
||||
children: []
|
||||
},
|
||||
{
|
||||
name: "item1",
|
||||
role: ROLE_MENUITEM,
|
||||
children: []
|
||||
},
|
||||
{
|
||||
name: "item2",
|
||||
role: ROLE_PARENT_MENUITEM,
|
||||
children: [
|
||||
{
|
||||
name: "item2",
|
||||
role: ROLE_MENUPOPUP,
|
||||
children: [
|
||||
{
|
||||
name: "item2.0",
|
||||
role: ROLE_PARENT_MENUITEM,
|
||||
children: [
|
||||
{
|
||||
name: "item2.0",
|
||||
role: ROLE_MENUPOPUP,
|
||||
children: [
|
||||
{
|
||||
name: "item2.0.0",
|
||||
role: ROLE_MENUITEM,
|
||||
children: []
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
function doTests()
|
||||
function doTest()
|
||||
{
|
||||
gQueue = new eventQueue();
|
||||
|
||||
// Check initial empty tree
|
||||
testAccessibleTree("context", { MENUPOPUP: [] });
|
||||
|
||||
// Open context menu and check that menu item accesibles are created.
|
||||
gQueue.push(new openMenu("context", gContextTree));
|
||||
|
||||
// Select items and check focus event on them.
|
||||
gQueue.push(new selectNextMenuItem("item0"));
|
||||
gQueue.push(new selectNextMenuItem("item1"));
|
||||
gQueue.push(new selectNextMenuItem("item2"));
|
||||
|
||||
// Open sub menu and check menu item accessibles and focus event.
|
||||
gQueue.push(new openSubMenu("submenu2", "item2.0"));
|
||||
gQueue.push(new openSubMenu("submenu2.0", "item2.0.0"));
|
||||
|
||||
// Close submenus and check that focus goes to parent.
|
||||
gQueue.push(new closeSubMenu("submenu2.0", "item2.0"));
|
||||
gQueue.push(new closeSubMenu("submenu2", "item2"));
|
||||
|
||||
gQueue.push(new closeMenu("context"));
|
||||
|
||||
gQueue.push(new openMenu("menu"));
|
||||
gQueue.invoke(); // Will call SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTests);
|
||||
addA11yLoadEvent(doTest);
|
||||
]]>
|
||||
</script>
|
||||
|
||||
<hbox flex="1" style="overflow: auto;">
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=630194"
|
||||
title="Update accessible tree when opening the menu popup">
|
||||
Mozilla Bug 630194
|
||||
</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
</div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
</body>
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=249292"
|
||||
title="Ensure accessible children for toolbarbutton types 'menu' and 'menu-button'">
|
||||
Mozilla Bug 249292
|
||||
</a>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=630486"
|
||||
title="Don't force accessible creation for popup children.">
|
||||
Mozilla Bug 630486
|
||||
</a>
|
||||
<br/>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
</div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
</body>
|
||||
|
||||
<vbox flex="1">
|
||||
|
||||
<menupopup id="context">
|
||||
<menuitem id="item0" label="item0"/>
|
||||
<menuitem id="item1" label="item1"/>
|
||||
<menu id="item2" label="item2">
|
||||
<menupopup id="submenu2">
|
||||
<menu id="item2.0" label="item2.0">
|
||||
<menupopup id="submenu2.0">
|
||||
<menuitem id="item2.0.0" label="item2.0.0"/>
|
||||
</menupopup>
|
||||
</menu>
|
||||
<menubar>
|
||||
<menu id="menu" label="menu">
|
||||
<menupopup>
|
||||
<menuitem label="menuitem"/>
|
||||
<menuitem label="menuitem"/>
|
||||
</menupopup>
|
||||
</menu>
|
||||
</menupopup>
|
||||
|
||||
<button context="context" id="button">btn</button>
|
||||
|
||||
<vbox id="eventdump" role="log"/>
|
||||
</menubar>
|
||||
</vbox>
|
||||
</hbox>
|
||||
|
||||
</window>
|
||||
|
||||
|
|
|
@ -0,0 +1,179 @@
|
|||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
|
||||
type="text/css"?>
|
||||
|
||||
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
title="Accessible XUL button hierarchy tests">
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/MochiKit/packed.js" />
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
|
||||
|
||||
<script type="application/javascript"
|
||||
src="../common.js" />
|
||||
<script type="application/javascript"
|
||||
src="../role.js" />
|
||||
<script type="application/javascript"
|
||||
src="../events.js" />
|
||||
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Invokers
|
||||
|
||||
function openMenu(aButtonID)
|
||||
{
|
||||
this.buttonNode = getNode(aButtonID);
|
||||
this.menupoupNode = this.buttonNode.firstChild;
|
||||
|
||||
this.eventSeq = [
|
||||
new invokerChecker(EVENT_REORDER, this.menupoupNode)
|
||||
];
|
||||
|
||||
this.invoke = function openMenu_invoke()
|
||||
{
|
||||
var tree =
|
||||
{ PUSHBUTTON: [
|
||||
{ MENUPOPUP: [ ] }
|
||||
] };
|
||||
testAccessibleTree(this.buttonNode, tree);
|
||||
|
||||
this.buttonNode.open = true;
|
||||
}
|
||||
|
||||
this.finalCheck = function openMenu_finalCheck()
|
||||
{
|
||||
var tree =
|
||||
{ PUSHBUTTON: [
|
||||
{ MENUPOPUP: [
|
||||
{ MENUITEM: [ ] },
|
||||
{ MENUITEM: [ ] }
|
||||
] }
|
||||
] };
|
||||
testAccessibleTree(this.buttonNode, tree);
|
||||
}
|
||||
|
||||
this.getID = function openMenu_getID()
|
||||
{
|
||||
return "open menu for button " + prettyName(aButtonID);
|
||||
}
|
||||
}
|
||||
|
||||
function openMenuButton(aButtonID)
|
||||
{
|
||||
this.buttonNode = getNode(aButtonID);
|
||||
this.menupoupNode = this.buttonNode.firstChild;
|
||||
|
||||
this.eventSeq = [
|
||||
new invokerChecker(EVENT_REORDER, this.menupoupNode)
|
||||
];
|
||||
|
||||
this.invoke = function openMenu_invoke()
|
||||
{
|
||||
var tree =
|
||||
{ PUSHBUTTON: [
|
||||
{ MENUPOPUP: [ ] },
|
||||
{ PUSHBUTTON: [ ] }
|
||||
] };
|
||||
testAccessibleTree(this.buttonNode, tree);
|
||||
|
||||
this.buttonNode.open = true;
|
||||
}
|
||||
|
||||
this.finalCheck = function openMenu_finalCheck()
|
||||
{
|
||||
var tree =
|
||||
{ PUSHBUTTON: [
|
||||
{ MENUPOPUP: [
|
||||
{ MENUITEM: [ ] },
|
||||
{ MENUITEM: [ ] }
|
||||
] },
|
||||
{ PUSHBUTTON: [ ] }
|
||||
] };
|
||||
testAccessibleTree(this.buttonNode, tree);
|
||||
}
|
||||
|
||||
this.getID = function openMenu_getID()
|
||||
{
|
||||
return "open menu for menu button " + prettyName(aButtonID);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Do test
|
||||
|
||||
gA11yEventDumpToConsole = true; // debug stuff
|
||||
|
||||
var gQueue = null;
|
||||
|
||||
function doTest()
|
||||
{
|
||||
gQueue = new eventQueue();
|
||||
|
||||
gQueue.push(new openMenu("button1"));
|
||||
gQueue.push(new openMenuButton("button2"));
|
||||
gQueue.push(new openMenu("button3"));
|
||||
gQueue.push(new openMenuButton("button4"));
|
||||
|
||||
gQueue.invoke(); // SimpleTest.finish()
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTest);
|
||||
]]>
|
||||
</script>
|
||||
|
||||
<hbox flex="1" style="overflow: auto;">
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=249292"
|
||||
title="Ensure accessible children for toolbarbutton types 'menu' and 'menu-button'">
|
||||
Mozilla Bug 249292
|
||||
</a>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=630486"
|
||||
title="Don't force accessible creation for popup children.">
|
||||
Mozilla Bug 630486
|
||||
</a>
|
||||
<br/>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
</div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
</body>
|
||||
|
||||
<vbox flex="1">
|
||||
<button id="button1" type="menu" label="hello">
|
||||
<menupopup>
|
||||
<menuitem label="menuitem"/>
|
||||
<menuitem label="menuitem"/>
|
||||
</menupopup>
|
||||
</button>
|
||||
<button id="button2" type="menu-button" label="hello">
|
||||
<menupopup>
|
||||
<menuitem label="menuitem"/>
|
||||
<menuitem label="menuitem"/>
|
||||
</menupopup>
|
||||
</button>
|
||||
|
||||
<toolbarbutton id="button3" type="menu" label="hello">
|
||||
<menupopup>
|
||||
<menuitem label="menuitem"/>
|
||||
<menuitem label="menuitem"/>
|
||||
</menupopup>
|
||||
</toolbarbutton>
|
||||
<toolbarbutton id="button4" type="menu-button" label="hello">
|
||||
<menupopup>
|
||||
<menuitem label="menuitem"/>
|
||||
<menuitem label="menuitem"/>
|
||||
</menupopup>
|
||||
</toolbarbutton>
|
||||
</vbox>
|
||||
</hbox>
|
||||
|
||||
</window>
|
||||
|
|
@ -48,7 +48,7 @@ DIRS = {972ce4c6-7e08-4474-a285-3208198ce6fd}
|
|||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
ifeq (beta,$(MOZ_UPDATE_CHANNEL))
|
||||
ifneq (,$(filter aurora beta,$(MOZ_UPDATE_CHANNEL)))
|
||||
EXTENSIONS = \
|
||||
testpilot@labs.mozilla.com \
|
||||
$(NULL)
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://testpilot/content/browser.css" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://testpilot-os/skin/feedback.css" type="text/css"?>
|
||||
|
||||
<!DOCTYPE overlay [
|
||||
<!ENTITY % testpilotDTD SYSTEM "chrome://testpilot/locale/main.dtd">
|
||||
|
|
|
@ -57,16 +57,6 @@
|
|||
image="chrome://testpilot-os/skin/feedback-frown-16x16.png"
|
||||
label = "&testpilot.sad.label;"
|
||||
oncommand="TestPilotWindowUtils.openFeedbackPage('sad');"/>
|
||||
<menuitem id="feedback-menu-broken-button"
|
||||
class="menuitem-iconic"
|
||||
image="chrome://testpilot-os/skin/feedback-broken-website.png"
|
||||
label = "&testpilot.broken.label;"
|
||||
oncommand="TestPilotWindowUtils.openFeedbackPage('broken');"/>
|
||||
<menuitem id="feedback-menu-idea-button"
|
||||
class="menuitem-iconic"
|
||||
image="chrome://testpilot-os/skin/feedback-idea.png"
|
||||
label = "&testpilot.idea.label;"
|
||||
oncommand="TestPilotWindowUtils.openFeedbackPage('idea');"/>
|
||||
<menuseparator/>
|
||||
<menuitem id="feedback-menu-show-studies"
|
||||
label="&testpilot.allYourStudies.label;"
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
xmlns:em="http://www.mozilla.org/2004/em-rdf#">
|
||||
<Description about="urn:mozilla:install-manifest">
|
||||
<em:id>testpilot@labs.mozilla.com</em:id>
|
||||
<em:version>1.0.6</em:version>
|
||||
<em:version>1.0.9</em:version>
|
||||
<em:type>2</em:type>
|
||||
|
||||
<!-- Target Application this extension can install into,
|
||||
|
@ -13,7 +13,7 @@
|
|||
<Description>
|
||||
<em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
|
||||
<em:minVersion>3.5</em:minVersion>
|
||||
<em:maxVersion>4.0.*</em:maxVersion>
|
||||
<em:maxVersion>5.0</em:maxVersion>
|
||||
</Description>
|
||||
</em:targetApplication>
|
||||
|
||||
|
|
|
@ -119,14 +119,11 @@ ExperimentDataStore.prototype = {
|
|||
for (i = 0; i < this._columns.length; i++) {
|
||||
let datum = uiEvent[this._columns[i].property];
|
||||
switch (this._columns[i].type) {
|
||||
case TYPE_INT_32:
|
||||
insStmt.bindInt32Parameter(i, datum);
|
||||
break;
|
||||
case TYPE_DOUBLE:
|
||||
insStmt.bindDoubleParameter(i, datum);
|
||||
case TYPE_INT_32: case TYPE_DOUBLE:
|
||||
insStmt.params[i] = datum;
|
||||
break;
|
||||
case TYPE_STRING:
|
||||
insStmt.bindUTF8StringParameter(i, sanitizeString(datum));
|
||||
insStmt.params[i] = sanitizeString(datum);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -104,12 +104,18 @@ var FeedbackManager = {
|
|||
*/
|
||||
let ioService = Cc["@mozilla.org/network/io-service;1"]
|
||||
.getService(Ci.nsIIOService);
|
||||
let uri = ioService.newURI(url, null, null);
|
||||
let path = uri.path;
|
||||
if (uri.host == "input.mozilla.com") {
|
||||
if (path.indexOf("feedback" > -1) || path.indexOf("happy" > -1) || path.indexOf("sad" > -1)) {
|
||||
return true;
|
||||
try {
|
||||
let uri = ioService.newURI(url, null, null);
|
||||
let path = uri.path;
|
||||
if (uri.host == "input.mozilla.com") {
|
||||
if (path.indexOf("feedback") > -1 || path.indexOf("happy") > -1 || path.indexOf("sad") > -1) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} catch(e) {
|
||||
/* newURI throws an exception if we try to parse urls like "about:config". (Bug 644582)
|
||||
* Those are not the urls we're looking for anyway. */
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
|
|
@ -94,22 +94,12 @@ var TestPilotUIBuilder = {
|
|||
} catch (e) {
|
||||
}
|
||||
}
|
||||
|
||||
/* Show and hide Feedback menu items based on version -- if user is on beta channel in
|
||||
* the final version, they get the 'broken' and 'idea' items. Otherwise they get
|
||||
* 'happy' and 'sad'.*/
|
||||
if (this.isBetaChannel() && this.appVersionIsFinal()) {
|
||||
window.document.getElementById("feedback-menu-happy-button").setAttribute("hidden", "true");
|
||||
window.document.getElementById("feedback-menu-sad-button").setAttribute("hidden", "true");
|
||||
} else {
|
||||
window.document.getElementById("feedback-menu-broken-button").setAttribute("hidden", "true");
|
||||
window.document.getElementById("feedback-menu-idea-button").setAttribute("hidden", "true");
|
||||
}
|
||||
},
|
||||
|
||||
isBetaChannel: function() {
|
||||
// Nightly channel is treated the same as default channel.
|
||||
return (this._prefs.getCharPref(UPDATE_CHANNEL_PREF) == "beta");
|
||||
// Beta and aurora channels use feedback interface; nightly and release channels don't.
|
||||
let channel = this._prefs.getCharPref(UPDATE_CHANNEL_PREF);
|
||||
return (channel == "beta") || (channel == "betatest") || (channel == "aurora");
|
||||
},
|
||||
|
||||
appVersionIsFinal: function() {
|
||||
|
|
|
@ -47,6 +47,7 @@ const LOCALE_PREF = "general.useragent.locale";
|
|||
const EXTENSION_ID = "testpilot@labs.mozilla.com";
|
||||
const PREFIX_NS_EM = "http://www.mozilla.org/2004/em-rdf#";
|
||||
const PREFIX_ITEM_URI = "urn:mozilla:item:";
|
||||
const UPDATE_CHANNEL_PREF = "app.update.channel";
|
||||
|
||||
/* The following preference, if present, stores answers to the basic panel
|
||||
* survey, which tell us user's general tech level, and so should be included
|
||||
|
@ -116,6 +117,19 @@ let MetadataCollector = {
|
|||
accessibilities.push({ name: prefName, value: prefValue });
|
||||
}
|
||||
|
||||
/* Detect accessibility instantiation
|
||||
* (David Bolter's code from bug 577694) */
|
||||
let enabled;
|
||||
try {
|
||||
enabled = Components.manager.QueryInterface(Ci.nsIServiceManager)
|
||||
.isServiceInstantiatedByContractID(
|
||||
"@mozilla.org/accessibilityService;1",
|
||||
Ci.nsISupports);
|
||||
} catch (ex) {
|
||||
enabled = false;
|
||||
}
|
||||
accessibilities.push({name: "isInstantiated", value: enabled});
|
||||
|
||||
return accessibilities;
|
||||
},
|
||||
|
||||
|
@ -155,6 +169,10 @@ let MetadataCollector = {
|
|||
}
|
||||
},
|
||||
|
||||
getUpdateChannel: function MetadataCollector_getUpdateChannel() {
|
||||
return Application.prefs.getValue(UPDATE_CHANNEL_PREF, "");
|
||||
},
|
||||
|
||||
getMetadata: function MetadataCollector_getMetadata(callback) {
|
||||
let self = this;
|
||||
self.getTestPilotVersion(function(tpVersion) {
|
||||
|
@ -165,7 +183,8 @@ let MetadataCollector = {
|
|||
fxVersion: self.getVersion(),
|
||||
operatingSystem: self.getOperatingSystem(),
|
||||
tpVersion: tpVersion,
|
||||
surveyAnswers: self.getSurveyAnswers()}
|
||||
surveyAnswers: self.getSurveyAnswers(),
|
||||
updateChannel: self.getUpdateChannel()}
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -185,15 +185,10 @@ let TestPilotSetup = {
|
|||
return this.__obs;
|
||||
},
|
||||
|
||||
_isFfx4BetaVersion: function TPS__isFfx4BetaVersion() {
|
||||
let result = Cc["@mozilla.org/xpcom/version-comparator;1"]
|
||||
.getService(Ci.nsIVersionComparator)
|
||||
.compare("3.7a1pre", this._application.version);
|
||||
if (result < 0) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
_isBetaChannel: function TPS__isBetaChannel() {
|
||||
// Beta and aurora channels use feedback interface; nightly and release channels don't.
|
||||
let channel = this._prefs.getValue(UPDATE_CHANNEL_PREF, "");
|
||||
return (channel == "beta") || (channel == "betatest") || (channel == "aurora");
|
||||
},
|
||||
|
||||
_setPrefDefaultsForVersion: function TPS__setPrefDefaultsForVersion() {
|
||||
|
@ -205,7 +200,7 @@ let TestPilotSetup = {
|
|||
let prefBranch = ps.getDefaultBranch("");
|
||||
/* note we're setting default values, not current values -- these
|
||||
* get overridden by any user set values. */
|
||||
if (this._isFfx4BetaVersion()) {
|
||||
if (this._isBetaChannel()) {
|
||||
prefBranch.setBoolPref(POPUP_SHOW_ON_NEW, true);
|
||||
prefBranch.setIntPref(POPUP_CHECK_INTERVAL, 600000);
|
||||
} else {
|
||||
|
@ -262,7 +257,7 @@ let TestPilotSetup = {
|
|||
let currVersion = self._prefs.getValue(VERSION_PREF, "firstrun");
|
||||
|
||||
if (currVersion != self.version) {
|
||||
if(!self._isFfx4BetaVersion()) {
|
||||
if(!self._isBetaChannel()) {
|
||||
self._prefs.setValue(VERSION_PREF, self.version);
|
||||
let browser = self._getFrontBrowserWindow().getBrowser();
|
||||
let url = self._prefs.getValue(FIRST_RUN_PREF, "");
|
||||
|
@ -386,7 +381,7 @@ let TestPilotSetup = {
|
|||
let popup = doc.getElementById("pilot-notification-popup");
|
||||
|
||||
let anchor;
|
||||
if (this._isFfx4BetaVersion()) {
|
||||
if (this._isBetaChannel()) {
|
||||
/* If we're in the Ffx4Beta version, popups come down from feedback
|
||||
* button, but if we're in the standalone extension version, they
|
||||
* come up from status bar icon. */
|
||||
|
|
|
@ -552,6 +552,21 @@ TestPilotExperiment.prototype = {
|
|||
}
|
||||
},
|
||||
|
||||
getStudyMetadata: function TestPilotExperiment_getStudyMetadata() {
|
||||
try {
|
||||
if (this._handlers.getStudyMetadata) {
|
||||
let metadata = this._handlers.getStudyMetadata();
|
||||
if (metadata.length) {
|
||||
// getStudyMetadata must return an array, otherwise it is invalid.
|
||||
return metadata;
|
||||
}
|
||||
}
|
||||
} catch(e) {
|
||||
this._logger.warn("Error in getStudyMetadata: " + e);
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
_reschedule: function TestPilotExperiment_reschedule() {
|
||||
// Schedule next run of test:
|
||||
// add recurrence interval to start date and store!
|
||||
|
@ -753,6 +768,15 @@ TestPilotExperiment.prototype = {
|
|||
json.metadata = md;
|
||||
json.metadata.task_guid = self.getGuid(self._id);
|
||||
json.metadata.event_headers = self._dataStore.getPropertyNames();
|
||||
let moreMd = self.getStudyMetadata();
|
||||
if (moreMd) {
|
||||
for (let i = 0; i < moreMd.length; i++) {
|
||||
if (moreMd[i].name && moreMd[i].value) {
|
||||
json.metadata[ moreMd[i].name ] = moreMd[i].value; // TODO sanitize strings?
|
||||
// TODO handle case where name or value are something other than strings?
|
||||
}
|
||||
}
|
||||
}
|
||||
self._dataStore.getJSONRows(function(rows) {
|
||||
json.events = rows;
|
||||
callback( JSON.stringify(json) );
|
||||
|
|
|
@ -62,8 +62,7 @@ EXTRA_JS_MODULES = \
|
|||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
PRE_RELEASE_SUFFIX := $(shell $(PYTHON) $(topsrcdir)/config/printprereleasesuffix.py \
|
||||
$(shell cat $(srcdir)/../config/version.txt))
|
||||
PRE_RELEASE_SUFFIX := ""
|
||||
|
||||
DEFINES += \
|
||||
-DMOZ_APP_VERSION=$(MOZ_APP_VERSION) \
|
||||
|
|
|
@ -1,16 +1,28 @@
|
|||
#aboutDialog {
|
||||
padding-top: 0;
|
||||
-moz-padding-end: 0;
|
||||
padding-bottom: 10px;
|
||||
-moz-padding-start: 0;
|
||||
width: 620px;
|
||||
}
|
||||
|
||||
/* Official branding has Firefox logo on the left side of the window.
|
||||
Nightly/aurora branding has background image applied to entire window. */
|
||||
%ifdef MOZ_OFFICIAL_BRANDING
|
||||
#clientBox {
|
||||
background-color: #F7F7F7;
|
||||
color: #222222;
|
||||
}
|
||||
%else
|
||||
#aboutDialogContainer {
|
||||
background-image: url("chrome://branding/content/about-background.png");
|
||||
background-repeat: no-repeat;
|
||||
background-color: #000;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.text-link {
|
||||
color: #fff !important;
|
||||
}
|
||||
%endif
|
||||
|
||||
%ifdef MOZ_OFFICIAL_BRANDING
|
||||
#leftBox {
|
||||
background-image: url("chrome://branding/content/about-logo.png");
|
||||
background-repeat: no-repeat;
|
||||
|
@ -20,6 +32,7 @@
|
|||
margin-top:20px;
|
||||
-moz-margin-start: 30px;
|
||||
}
|
||||
%endif
|
||||
|
||||
#rightBox {
|
||||
background-image: url("chrome://branding/content/about-wordmark.png");
|
||||
|
@ -27,8 +40,14 @@
|
|||
/* padding-top creates room for the wordmark */
|
||||
padding-top: 38px;
|
||||
margin-top:20px;
|
||||
-moz-margin-end: 30px;
|
||||
-moz-margin-start: 30px;
|
||||
%ifdef MOZ_OFFICIAL_BRANDING
|
||||
margin-left: 30px;
|
||||
margin-right: 30px;
|
||||
%else
|
||||
/* this margin prevents text from overlapping the planet image */
|
||||
margin-left: 280px;
|
||||
margin-right: 20px;
|
||||
%endif
|
||||
}
|
||||
|
||||
#rightBox:-moz-locale-dir(rtl) {
|
||||
|
@ -37,10 +56,13 @@
|
|||
|
||||
#bottomBox {
|
||||
padding: 15px 10px 0;
|
||||
%ifndef MOZ_OFFICIAL_BRANDING
|
||||
background-color: rgba(0,0,0,.7);
|
||||
%endif
|
||||
}
|
||||
|
||||
#version {
|
||||
margin-top: 5px;
|
||||
margin-top: 10px;
|
||||
-moz-margin-start: 0;
|
||||
}
|
||||
|
||||
|
@ -89,12 +111,16 @@
|
|||
margin: 0 40px;
|
||||
}
|
||||
|
||||
/* we assume trademark text only appears in offical builds */
|
||||
%ifdef MOZ_OFFICIAL_BRANDING
|
||||
#trademark {
|
||||
font-size: xx-small;
|
||||
text-align: center;
|
||||
color: #999999;
|
||||
margin-top: 10px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
%endif
|
||||
|
||||
#currentChannel {
|
||||
margin: 0;
|
||||
|
|
|
@ -65,9 +65,9 @@ function init(aEvent)
|
|||
// Pref is unset
|
||||
}
|
||||
|
||||
// Include the build ID if this is a "pre" (i.e. non-release) build
|
||||
// Include the build ID if this is an "a#" (nightly or aurora) build
|
||||
let version = Services.appinfo.version;
|
||||
if (version.indexOf("pre") != -1) {
|
||||
if (/a\d+$/.test(version)) {
|
||||
let buildID = Services.appinfo.appBuildID;
|
||||
let buildDate = buildID.slice(0,4) + "-" + buildID.slice(4,6) + "-" + buildID.slice(6,8);
|
||||
document.getElementById("version").value += " (" + buildDate + ")";
|
||||
|
|
|
@ -70,7 +70,7 @@
|
|||
|
||||
<script type="application/javascript" src="chrome://browser/content/aboutDialog.js"/>
|
||||
|
||||
<vbox>
|
||||
<vbox id="aboutDialogContainer">
|
||||
<hbox id="clientBox">
|
||||
<vbox id="leftBox" flex="1"/>
|
||||
<vbox id="rightBox" flex="1">
|
||||
|
|
|
@ -356,7 +356,9 @@
|
|||
<key id="key_quitApplication" key="&quitApplicationCmdMac.key;" command="cmd_quitApplication" modifiers="accel"/>
|
||||
#endif
|
||||
|
||||
#ifdef FULL_BROWSER_WINDOW
|
||||
<key id="key_undoCloseTab" command="History:UndoCloseTab" key="&tabCmd.commandkey;" modifiers="accel,shift"/>
|
||||
#endif
|
||||
<key id="key_undoCloseWindow" command="History:UndoCloseWindow" key="&newNavigatorCmd.key;" modifiers="accel,shift"/>
|
||||
|
||||
#ifdef XP_GNOME
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
|
||||
let TabView = {
|
||||
_deck: null,
|
||||
_iframe: null,
|
||||
_window: null,
|
||||
_firstUseExperienced: false,
|
||||
_browserKeyHandlerInitialized: false,
|
||||
|
@ -135,17 +136,17 @@ let TabView = {
|
|||
this._deck = document.getElementById("tab-view-deck");
|
||||
|
||||
// ___ create the frame
|
||||
let iframe = document.createElement("iframe");
|
||||
iframe.id = "tab-view";
|
||||
iframe.setAttribute("transparent", "true");
|
||||
iframe.flex = 1;
|
||||
this._iframe = document.createElement("iframe");
|
||||
this._iframe.id = "tab-view";
|
||||
this._iframe.setAttribute("transparent", "true");
|
||||
this._iframe.flex = 1;
|
||||
|
||||
if (typeof callback == "function")
|
||||
window.addEventListener("tabviewframeinitialized", callback, false);
|
||||
|
||||
iframe.setAttribute("src", "chrome://browser/content/tabview.html");
|
||||
this._deck.appendChild(iframe);
|
||||
this._window = iframe.contentWindow;
|
||||
this._iframe.setAttribute("src", "chrome://browser/content/tabview.html");
|
||||
this._deck.appendChild(this._iframe);
|
||||
this._window = this._iframe.contentWindow;
|
||||
|
||||
if (this._tabShowEventListener) {
|
||||
gBrowser.tabContainer.removeEventListener(
|
||||
|
@ -163,19 +164,18 @@ let TabView = {
|
|||
},
|
||||
|
||||
// ----------
|
||||
isVisible: function() {
|
||||
return (this._deck ? this._deck.selectedIndex == 1 : false);
|
||||
isVisible: function TabView_isVisible() {
|
||||
return (this._deck ? this._deck.selectedPanel == this._iframe : false);
|
||||
},
|
||||
|
||||
// ----------
|
||||
show: function() {
|
||||
if (this.isVisible())
|
||||
return;
|
||||
|
||||
|
||||
let self = this;
|
||||
this._initFrame(function() {
|
||||
let event = document.createEvent("Events");
|
||||
event.initEvent("tabviewshow", false, false);
|
||||
dispatchEvent(event);
|
||||
self._window.UI.showTabView(true);
|
||||
});
|
||||
},
|
||||
|
||||
|
@ -184,9 +184,7 @@ let TabView = {
|
|||
if (!this.isVisible())
|
||||
return;
|
||||
|
||||
let event = document.createEvent("Events");
|
||||
event.initEvent("tabviewhide", false, false);
|
||||
dispatchEvent(event);
|
||||
this._window.UI.exit();
|
||||
},
|
||||
|
||||
// ----------
|
||||
|
|
|
@ -4034,16 +4034,19 @@ var FullScreen = {
|
|||
// controls on nav bar.
|
||||
var fullscreenflex = document.getElementById("fullscreenflex");
|
||||
var fullscreenctls = document.getElementById("window-controls");
|
||||
var ctlsOnTabbar = TabsOnTop.enabled &&
|
||||
!gPrefService.getBoolPref("browser.tabs.autoHide");
|
||||
if (fullscreenctls.parentNode.id == "nav-bar" && ctlsOnTabbar) {
|
||||
var navbar = document.getElementById("nav-bar");
|
||||
var ctlsOnTabbar = window.toolbar.visible &&
|
||||
(navbar.collapsed ||
|
||||
(TabsOnTop.enabled &&
|
||||
!gPrefService.getBoolPref("browser.tabs.autoHide")));
|
||||
if (fullscreenctls.parentNode == navbar && ctlsOnTabbar) {
|
||||
document.getElementById("TabsToolbar").appendChild(fullscreenctls);
|
||||
// we don't need this space in tabs-on-top mode, so prevent it from
|
||||
// being shown
|
||||
fullscreenflex.removeAttribute("fullscreencontrol");
|
||||
}
|
||||
else if (fullscreenctls.parentNode.id == "TabsToolbar" && !ctlsOnTabbar) {
|
||||
document.getElementById("nav-bar").appendChild(fullscreenctls);
|
||||
navbar.appendChild(fullscreenctls);
|
||||
fullscreenflex.setAttribute("fullscreencontrol", "true");
|
||||
}
|
||||
|
||||
|
|
|
@ -107,7 +107,9 @@
|
|||
|
||||
# All sets except for popupsets (commands, keys, stringbundles and broadcasters) *must* go into the
|
||||
# browser-sets.inc file for sharing with hiddenWindow.xul.
|
||||
#define FULL_BROWSER_WINDOW
|
||||
#include browser-sets.inc
|
||||
#undef FULL_BROWSER_WINDOW
|
||||
|
||||
<popupset id="mainPopupSet">
|
||||
<menupopup id="tabContextMenu"
|
||||
|
@ -461,7 +463,7 @@
|
|||
#endif
|
||||
|
||||
<deck flex="1" id="tab-view-deck">
|
||||
<vbox flex="1">
|
||||
<vbox flex="1" id="browser-panel">
|
||||
|
||||
<toolbox id="navigator-toolbox"
|
||||
defaultmode="icons" mode="icons"
|
||||
|
|
|
@ -96,8 +96,7 @@ let gOpenLocationLastURL = {
|
|||
}
|
||||
},
|
||||
reset: function() {
|
||||
if (prefSvc.prefHasUserValue(LAST_URL_PREF))
|
||||
prefSvc.clearUserPref(LAST_URL_PREF);
|
||||
prefSvc.clearUserPref(LAST_URL_PREF);
|
||||
gOpenLocationLastURLData = "";
|
||||
}
|
||||
};
|
||||
|
|
|
@ -47,3 +47,11 @@ tabpanels {
|
|||
.tab-throbber[busy] + .tab-icon-image {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.closing-tabs-spacer {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.tabbrowser-tabs:not(:hover) > .tabbrowser-arrowscrollbox > .closing-tabs-spacer {
|
||||
-moz-transition: width .15s ease-out;
|
||||
}
|
||||
|
|
|
@ -33,6 +33,8 @@
|
|||
- Dão Gottwald <dao@mozilla.com>
|
||||
- Paul O’Shannessy <paul@oshannessy.com>
|
||||
- Rob Arnold <tellrob@gmail.com>
|
||||
- Frank Yan <fyan@mozilla.com>
|
||||
- Patrick Walton <pcwalton@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
|
||||
|
@ -234,6 +236,7 @@
|
|||
|
||||
this.moveTabTo(aTab, this._numPinnedTabs);
|
||||
aTab.setAttribute("pinned", "true");
|
||||
this.tabContainer._unlockTabSizing();
|
||||
this.tabContainer._positionPinnedTabs();
|
||||
this.tabContainer.adjustTabstrip();
|
||||
|
||||
|
@ -258,6 +261,7 @@
|
|||
aTab.setAttribute("fadein", "true");
|
||||
aTab.removeAttribute("pinned");
|
||||
aTab.style.MozMarginStart = "";
|
||||
this.tabContainer._unlockTabSizing();
|
||||
this.tabContainer._positionPinnedTabs();
|
||||
this.tabContainer.adjustTabstrip();
|
||||
|
||||
|
@ -810,7 +814,7 @@
|
|||
}
|
||||
} catch (e) {}
|
||||
|
||||
if (window.TabView) {
|
||||
if ("TabView" in window) {
|
||||
let groupName = TabView.getActiveGroupName();
|
||||
if (groupName)
|
||||
newTitle = groupName + sep + newTitle;
|
||||
|
@ -824,7 +828,7 @@
|
|||
<method name="updateTitlebar">
|
||||
<body>
|
||||
<![CDATA[
|
||||
if (window.TabView && TabView.isVisible()) {
|
||||
if ("TabView" in window && TabView.isVisible()) {
|
||||
// ToDo: this will be removed when we gain ability to draw to the menu bar.
|
||||
// Bug 586175
|
||||
this.ownerDocument.title = TabView.windowTitle;
|
||||
|
@ -1204,6 +1208,8 @@
|
|||
t.setAttribute("onerror", "this.removeAttribute('image');");
|
||||
t.className = "tabbrowser-tab";
|
||||
|
||||
this.tabContainer._unlockTabSizing();
|
||||
|
||||
// When overflowing, new tabs are scrolled into view smoothly, which
|
||||
// doesn't go well together with the width transition. So we skip the
|
||||
// transition in that case.
|
||||
|
@ -1435,8 +1441,10 @@
|
|||
<parameter name="aParams"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
if (aParams)
|
||||
if (aParams) {
|
||||
var animate = aParams.animate;
|
||||
var byMouse = aParams.byMouse;
|
||||
}
|
||||
|
||||
// Handle requests for synchronously removing an already
|
||||
// asynchronously closing tab.
|
||||
|
@ -1451,6 +1459,11 @@
|
|||
if (!this._beginRemoveTab(aTab, false, null, true))
|
||||
return;
|
||||
|
||||
if (!aTab.pinned && !aTab.hidden && aTab._fullyOpen && byMouse)
|
||||
this.tabContainer._lockTabSizing(aTab);
|
||||
else
|
||||
this.tabContainer._unlockTabSizing();
|
||||
|
||||
if (!animate /* the caller didn't opt in */ ||
|
||||
isLastTab ||
|
||||
aTab.pinned ||
|
||||
|
@ -1463,6 +1476,7 @@
|
|||
}
|
||||
|
||||
this._blurTab(aTab);
|
||||
aTab.style.maxWidth = ""; // ensure that fade-out transition happens
|
||||
aTab.removeAttribute("fadein");
|
||||
|
||||
setTimeout(function (tab, tabbrowser) {
|
||||
|
@ -1637,6 +1651,10 @@
|
|||
|
||||
// update tab close buttons state
|
||||
this.tabContainer.adjustTabstrip();
|
||||
|
||||
setTimeout(function(tabs) {
|
||||
tabs._lastTabClosedByMouse = false;
|
||||
}, 0, this.tabContainer);
|
||||
}
|
||||
|
||||
// update first-tab/last-tab/beforeselected/afterselected attributes
|
||||
|
@ -2412,6 +2430,7 @@
|
|||
this.mPanelContainer.childNodes[0].id = uniqueId;
|
||||
this.mCurrentTab.linkedPanel = uniqueId;
|
||||
this.mCurrentTab._tPos = 0;
|
||||
this.mCurrentTab._fullyOpen = true;
|
||||
this.mCurrentTab.linkedBrowser = this.mCurrentBrowser;
|
||||
|
||||
// set up the shared autoscroll popup
|
||||
|
@ -2591,25 +2610,28 @@
|
|||
</implementation>
|
||||
|
||||
<handlers>
|
||||
<handler event="underflow"><![CDATA[
|
||||
if (event.detail == 0)
|
||||
return; // Ignore vertical events
|
||||
<handler event="underflow" phase="capturing"><![CDATA[
|
||||
if (event.detail == 0)
|
||||
return; // Ignore vertical events
|
||||
|
||||
var tabs = document.getBindingParent(this);
|
||||
tabs.removeAttribute("overflow");
|
||||
var tabs = document.getBindingParent(this);
|
||||
tabs.removeAttribute("overflow");
|
||||
|
||||
tabs.tabbrowser._removingTabs.forEach(tabs.tabbrowser.removeTab,
|
||||
tabs.tabbrowser);
|
||||
if (tabs._lastTabClosedByMouse)
|
||||
tabs._expandSpacerBy(this._scrollButtonDown.clientWidth);
|
||||
|
||||
tabs._positionPinnedTabs();
|
||||
tabs.tabbrowser._removingTabs.forEach(tabs.tabbrowser.removeTab,
|
||||
tabs.tabbrowser);
|
||||
|
||||
tabs._positionPinnedTabs();
|
||||
]]></handler>
|
||||
<handler event="overflow"><![CDATA[
|
||||
if (event.detail == 0)
|
||||
return; // Ignore vertical events
|
||||
if (event.detail == 0)
|
||||
return; // Ignore vertical events
|
||||
|
||||
var tabs = document.getBindingParent(this);
|
||||
tabs.setAttribute("overflow", "true");
|
||||
tabs._positionPinnedTabs();
|
||||
var tabs = document.getBindingParent(this);
|
||||
tabs.setAttribute("overflow", "true");
|
||||
tabs._positionPinnedTabs();
|
||||
]]></handler>
|
||||
</handlers>
|
||||
</binding>
|
||||
|
@ -2640,6 +2662,8 @@
|
|||
command="cmd_newNavigatorTab"
|
||||
onclick="checkForMiddleClick(this, event);"
|
||||
tooltiptext="&newTabButton.tooltip;"/>
|
||||
<xul:spacer class="closing-tabs-spacer" anonid="closing-tabs-spacer"
|
||||
style="width: 0;"/>
|
||||
</xul:arrowscrollbox>
|
||||
</content>
|
||||
|
||||
|
@ -2811,6 +2835,104 @@
|
|||
]]></body>
|
||||
</method>
|
||||
|
||||
<field name="_closingTabsSpacer">
|
||||
document.getAnonymousElementByAttribute(this, "anonid", "closing-tabs-spacer");
|
||||
</field>
|
||||
|
||||
<field name="_tabDefaultMaxWidth">NaN</field>
|
||||
<field name="_lastTabClosedByMouse">false</field>
|
||||
<field name="_hasTabTempMaxWidth">false</field>
|
||||
<field name="_usingClosingTabsSpacer">false</field>
|
||||
|
||||
<!-- Try to keep the active tab's close button under the mouse cursor -->
|
||||
<method name="_lockTabSizing">
|
||||
<parameter name="aTab"/>
|
||||
<body><![CDATA[
|
||||
var tabs = this.tabbrowser.visibleTabs;
|
||||
if (!tabs.length)
|
||||
return;
|
||||
|
||||
var isEndTab = (aTab._tPos > tabs[tabs.length-1]._tPos);
|
||||
var tabWidth = aTab.getBoundingClientRect().width;
|
||||
|
||||
if (!this._tabDefaultMaxWidth)
|
||||
this._tabDefaultMaxWidth =
|
||||
parseFloat(window.getComputedStyle(aTab).maxWidth);
|
||||
this._lastTabClosedByMouse = true;
|
||||
|
||||
if (this.getAttribute("overflow") == "true") {
|
||||
// Don't need to do anything if we're in overflow mode and aren't scrolled
|
||||
// all the way to the right, or if we're closing the last tab.
|
||||
if (isEndTab || !this.mTabstrip._scrollButtonDown.disabled)
|
||||
return;
|
||||
|
||||
// If the tab has an owner that will become the active tab, the owner will
|
||||
// be to the left of it, so we actually want the left tab to slide over.
|
||||
// This can't be done as easily in non-overflow mode, so we don't bother.
|
||||
if (aTab.owner)
|
||||
return;
|
||||
|
||||
this._expandSpacerBy(tabWidth);
|
||||
} else { // non-overflow mode
|
||||
// Locking is neither in effect nor needed, so let tabs expand normally.
|
||||
if (isEndTab && !this._hasTabTempMaxWidth)
|
||||
return;
|
||||
|
||||
let numPinned = this.tabbrowser._numPinnedTabs;
|
||||
// Force tabs to stay the same width, unless we're closing the last tab,
|
||||
// which case we need to let them expand just enough so that the overall
|
||||
// tabbar width is the same.
|
||||
if (isEndTab) {
|
||||
let numNormalTabs = tabs.length - numPinned;
|
||||
tabWidth = tabWidth * (numNormalTabs + 1) / numNormalTabs;
|
||||
if (tabWidth > this._tabDefaultMaxWidth)
|
||||
tabWidth = this._tabDefaultMaxWidth;
|
||||
}
|
||||
tabWidth += "px";
|
||||
for (let i = numPinned; i < tabs.length; i++) {
|
||||
let tab = tabs[i];
|
||||
tab.style.maxWidth = tabWidth;
|
||||
if (!isEndTab) { // keep tabs the same width
|
||||
tab.style.MozTransition = "none";
|
||||
tab.clientTop; // flush styles to skip animation; see bug 649247
|
||||
tab.style.MozTransition = "";
|
||||
}
|
||||
}
|
||||
this._hasTabTempMaxWidth = true;
|
||||
this.tabbrowser.addEventListener("mousemove", this, false);
|
||||
window.addEventListener("mouseout", this, false);
|
||||
}
|
||||
]]></body>
|
||||
</method>
|
||||
|
||||
<method name="_expandSpacerBy">
|
||||
<parameter name="pixels"/>
|
||||
<body><![CDATA[
|
||||
let spacer = this._closingTabsSpacer;
|
||||
spacer.style.width = parseFloat(spacer.style.width) + pixels + "px";
|
||||
this._usingClosingTabsSpacer = true;
|
||||
this.tabbrowser.addEventListener("mousemove", this, false);
|
||||
window.addEventListener("mouseout", this, false);
|
||||
]]></body>
|
||||
</method>
|
||||
|
||||
<method name="_unlockTabSizing">
|
||||
<body><![CDATA[
|
||||
this.tabbrowser.removeEventListener("mousemove", this, false);
|
||||
window.removeEventListener("mouseout", this, false);
|
||||
if (this._hasTabTempMaxWidth) {
|
||||
this._hasTabTempMaxWidth = false;
|
||||
let tabs = this.tabbrowser.visibleTabs;
|
||||
for (let i = 0; i < tabs.length; i++)
|
||||
tabs[i].style.maxWidth = "";
|
||||
}
|
||||
if (this._usingClosingTabsSpacer) {
|
||||
this._usingClosingTabsSpacer = false;
|
||||
this._closingTabsSpacer.style.width = 0;
|
||||
}
|
||||
]]></body>
|
||||
</method>
|
||||
|
||||
<method name="_positionPinnedTabs">
|
||||
<body><![CDATA[
|
||||
var numPinned = this.tabbrowser._numPinnedTabs;
|
||||
|
@ -2864,6 +2986,16 @@
|
|||
}
|
||||
this.tabbrowser.updateWindowResizers();
|
||||
break;
|
||||
case "mouseout":
|
||||
// If the "related target" (the node to which the pointer went) is not
|
||||
// a child of the current document, the mouse just left the window.
|
||||
let relatedTarget = aEvent.relatedTarget;
|
||||
if (relatedTarget && relatedTarget.ownerDocument == document)
|
||||
break;
|
||||
case "mousemove":
|
||||
if (document.getElementById("tabContextMenu").state != "open")
|
||||
this._unlockTabSizing();
|
||||
break;
|
||||
}
|
||||
]]></body>
|
||||
</method>
|
||||
|
@ -2999,8 +3131,9 @@
|
|||
<method name="_handleNewTab">
|
||||
<parameter name="tab"/>
|
||||
<body><![CDATA[
|
||||
if (tab.parentNode != this)
|
||||
if (tab.parentNode != this || tab._fullyOpen)
|
||||
return;
|
||||
tab._fullyOpen = true;
|
||||
|
||||
this.adjustTabstrip();
|
||||
|
||||
|
@ -3019,7 +3152,7 @@
|
|||
this.mTabstrip._updateScrollButtonsDisabledState();
|
||||
]]></body>
|
||||
</method>
|
||||
|
||||
|
||||
<method name="_canAdvanceToTab">
|
||||
<parameter name="aTab"/>
|
||||
<body>
|
||||
|
@ -3073,7 +3206,7 @@
|
|||
|
||||
if (event.target.localName == "tab") {
|
||||
if (this.childNodes.length > 1 || !this._closeWindowWithLastTab)
|
||||
this.tabbrowser.removeTab(event.target, {animate: true});
|
||||
this.tabbrowser.removeTab(event.target, {animate: true, byMouse: true});
|
||||
} else if (event.originalTarget.localName == "box") {
|
||||
BrowserOpenTab();
|
||||
} else {
|
||||
|
@ -3399,7 +3532,7 @@
|
|||
// Reset the "ignored click" flag
|
||||
this._ignoredClick = false;
|
||||
|
||||
tabContainer.tabbrowser.removeTab(bindingParent, {animate: true});
|
||||
tabContainer.tabbrowser.removeTab(bindingParent, {animate: true, byMouse: true});
|
||||
tabContainer._blockDblClick = true;
|
||||
|
||||
/* XXXmano hack (see bug 343628):
|
||||
|
@ -3487,6 +3620,7 @@
|
|||
|
||||
<field name="mOverCloseButton">false</field>
|
||||
<field name="mCorrespondingMenuitem">null</field>
|
||||
<field name="_fullyOpen">false</field>
|
||||
</implementation>
|
||||
|
||||
<handlers>
|
||||
|
|
|
@ -1147,7 +1147,9 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), {
|
|||
let $icon = iQ(icon);
|
||||
if ($icon.data("xulTab") == event.target) {
|
||||
$icon.attr("src", Utils.defaultFaviconURL);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
},
|
||||
|
||||
|
@ -1193,9 +1195,10 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), {
|
|||
iQ(".appTabIcon", this.$appTabTray).each(function(icon) {
|
||||
let $icon = iQ(icon);
|
||||
if ($icon.data("xulTab") != xulTab)
|
||||
return;
|
||||
return true;
|
||||
|
||||
$icon.remove();
|
||||
return false;
|
||||
});
|
||||
|
||||
// adjust the tray
|
||||
|
@ -1215,7 +1218,7 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), {
|
|||
elements.each(function(icon) {
|
||||
let $icon = iQ(icon);
|
||||
if ($icon.data("xulTab") != xulTab)
|
||||
return;
|
||||
return true;
|
||||
|
||||
let targetIndex = xulTab._tPos;
|
||||
|
||||
|
@ -1226,6 +1229,7 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), {
|
|||
iQ(".appTabIcon:nth-child(" + (targetIndex + 1) + ")", self.$appTabTray)[0]);
|
||||
else
|
||||
$icon.appendTo(self.$appTabTray);
|
||||
return false;
|
||||
});
|
||||
},
|
||||
|
||||
|
@ -1668,13 +1672,12 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), {
|
|||
|
||||
// Create new tab and zoom in on it after a double click
|
||||
container.mousedown(function(e) {
|
||||
if (!Utils.isLeftClick(e))
|
||||
if (!Utils.isLeftClick(e) || self.$titlebar[0] == e.target ||
|
||||
self.$titlebar.contains(e.target)) {
|
||||
self._lastClick = 0;
|
||||
self._lastClickPositions = null;
|
||||
return;
|
||||
|
||||
// clicking in the title bar shouldn't create new tabs
|
||||
if (self.$titlebar[0] == e.target || self.$titlebar.contains(e.target))
|
||||
return;
|
||||
|
||||
}
|
||||
if (Date.now() - self._lastClick <= UI.DBLCLICK_INTERVAL &&
|
||||
(self._lastClickPositions.x - UI.DBLCLICK_OFFSET) <= e.clientX &&
|
||||
(self._lastClickPositions.x + UI.DBLCLICK_OFFSET) >= e.clientX &&
|
||||
|
@ -1788,7 +1791,12 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), {
|
|||
|
||||
this.resizeOptions.minWidth = GroupItems.minGroupWidth;
|
||||
this.resizeOptions.minHeight = GroupItems.minGroupHeight;
|
||||
this.resizeOptions.start = function () self._unfreezeItemSize();
|
||||
|
||||
let start = this.resizeOptions.start;
|
||||
this.resizeOptions.start = function (event) {
|
||||
start.call(self, event);
|
||||
self._unfreezeItemSize();
|
||||
}
|
||||
|
||||
if (value) {
|
||||
immediately ? this.$resizer.show() : this.$resizer.fadeIn();
|
||||
|
@ -2033,10 +2041,11 @@ let GroupItems = {
|
|||
iQ(".appTabIcon", groupItem.$appTabTray).each(function(icon) {
|
||||
let $icon = iQ(icon);
|
||||
if ($icon.data("xulTab") != xulTab)
|
||||
return;
|
||||
return true;
|
||||
|
||||
if (iconUrl != $icon.attr("src"))
|
||||
$icon.attr("src", iconUrl);
|
||||
return false;
|
||||
});
|
||||
});
|
||||
},
|
||||
|
|
|
@ -217,9 +217,7 @@ iQClass.prototype = {
|
|||
Utils.assert(false, "each's argument must be a function");
|
||||
return null;
|
||||
}
|
||||
for (let i = 0; this[i] != null; i++) {
|
||||
callback(this[i]);
|
||||
}
|
||||
for (let i = 0; this[i] != null && callback(this[i]) !== false; i++) {}
|
||||
return this;
|
||||
},
|
||||
|
||||
|
|
|
@ -661,7 +661,7 @@ Item.prototype = {
|
|||
.unbind('mousemove', handleMouseMove)
|
||||
.unbind('mouseup', handleMouseUp);
|
||||
|
||||
if (dropTarget) {
|
||||
if (startSent && dropTarget) {
|
||||
var dropOptions = dropTarget.dropOptions;
|
||||
if (dropOptions && typeof dropOptions.drop == "function")
|
||||
dropOptions.drop.apply(dropTarget, [e]);
|
||||
|
|
|
@ -132,7 +132,7 @@ var TabUtils = {
|
|||
// of active Panoramas as well as for windows in which
|
||||
// Panorama has yet to be activated. We uses object sniffing to
|
||||
// determine the type of tab and then returns its name.
|
||||
return tab.label != undefined ? tab.label : tab.$tabTitle[0].innerHTML;
|
||||
return tab.label != undefined ? tab.label : tab.$tabTitle[0].textContent;
|
||||
},
|
||||
|
||||
// ---------
|
||||
|
|
|
@ -13,6 +13,7 @@ body {
|
|||
}
|
||||
|
||||
#content {
|
||||
overflow: -moz-hidden-unscrollable;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
|
|
|
@ -33,6 +33,7 @@ var gWindow = window.parent;
|
|||
var gBrowser = gWindow.gBrowser;
|
||||
var gTabView = gWindow.TabView;
|
||||
var gTabViewDeck = gWindow.document.getElementById("tab-view-deck");
|
||||
var gBrowserPanel = gWindow.document.getElementById("browser-panel");
|
||||
var gTabViewFrame = gWindow.document.getElementById("tab-view");
|
||||
|
||||
# NB: Certain files need to evaluate before others
|
||||
|
|
|
@ -163,11 +163,6 @@ let UI = {
|
|||
this._storageSanity(data);
|
||||
this._pageBounds = data.pageBounds;
|
||||
|
||||
// ___ hook into the browser
|
||||
gWindow.addEventListener("tabviewshow", function() {
|
||||
self.showTabView(true);
|
||||
}, false);
|
||||
|
||||
// ___ currentTab
|
||||
this._currentTab = gBrowser.selectedTab;
|
||||
|
||||
|
@ -188,36 +183,41 @@ let UI = {
|
|||
});
|
||||
}
|
||||
if (e.originalTarget.id == "content") {
|
||||
// Create an orphan tab on double click
|
||||
if (Date.now() - self._lastClick <= self.DBLCLICK_INTERVAL &&
|
||||
(self._lastClickPositions.x - self.DBLCLICK_OFFSET) <= e.clientX &&
|
||||
(self._lastClickPositions.x + self.DBLCLICK_OFFSET) >= e.clientX &&
|
||||
(self._lastClickPositions.y - self.DBLCLICK_OFFSET) <= e.clientY &&
|
||||
(self._lastClickPositions.y + self.DBLCLICK_OFFSET) >= e.clientY) {
|
||||
GroupItems.setActiveGroupItem(null);
|
||||
TabItems.creatingNewOrphanTab = true;
|
||||
|
||||
let newTab =
|
||||
gBrowser.loadOneTab("about:blank", { inBackground: true });
|
||||
|
||||
let box =
|
||||
new Rect(e.clientX - Math.floor(TabItems.tabWidth/2),
|
||||
e.clientY - Math.floor(TabItems.tabHeight/2),
|
||||
TabItems.tabWidth, TabItems.tabHeight);
|
||||
newTab._tabViewTabItem.setBounds(box, true);
|
||||
newTab._tabViewTabItem.pushAway(true);
|
||||
UI.setActiveTab(newTab._tabViewTabItem);
|
||||
|
||||
TabItems.creatingNewOrphanTab = false;
|
||||
newTab._tabViewTabItem.zoomIn(true);
|
||||
|
||||
if (!Utils.isLeftClick(e)) {
|
||||
self._lastClick = 0;
|
||||
self._lastClickPositions = null;
|
||||
gTabView.firstUseExperienced = true;
|
||||
} else {
|
||||
self._lastClick = Date.now();
|
||||
self._lastClickPositions = new Point(e.clientX, e.clientY);
|
||||
self._createGroupItemOnDrag(e);
|
||||
// Create an orphan tab on double click
|
||||
if (Date.now() - self._lastClick <= self.DBLCLICK_INTERVAL &&
|
||||
(self._lastClickPositions.x - self.DBLCLICK_OFFSET) <= e.clientX &&
|
||||
(self._lastClickPositions.x + self.DBLCLICK_OFFSET) >= e.clientX &&
|
||||
(self._lastClickPositions.y - self.DBLCLICK_OFFSET) <= e.clientY &&
|
||||
(self._lastClickPositions.y + self.DBLCLICK_OFFSET) >= e.clientY) {
|
||||
GroupItems.setActiveGroupItem(null);
|
||||
TabItems.creatingNewOrphanTab = true;
|
||||
|
||||
let newTab =
|
||||
gBrowser.loadOneTab("about:blank", { inBackground: true });
|
||||
|
||||
let box =
|
||||
new Rect(e.clientX - Math.floor(TabItems.tabWidth/2),
|
||||
e.clientY - Math.floor(TabItems.tabHeight/2),
|
||||
TabItems.tabWidth, TabItems.tabHeight);
|
||||
newTab._tabViewTabItem.setBounds(box, true);
|
||||
newTab._tabViewTabItem.pushAway(true);
|
||||
UI.setActiveTab(newTab._tabViewTabItem);
|
||||
|
||||
TabItems.creatingNewOrphanTab = false;
|
||||
newTab._tabViewTabItem.zoomIn(true);
|
||||
|
||||
self._lastClick = 0;
|
||||
self._lastClickPositions = null;
|
||||
gTabView.firstUseExperienced = true;
|
||||
} else {
|
||||
self._lastClick = Date.now();
|
||||
self._lastClickPositions = new Point(e.clientX, e.clientY);
|
||||
self._createGroupItemOnDrag(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -226,10 +226,6 @@ let UI = {
|
|||
self.uninit();
|
||||
});
|
||||
|
||||
gWindow.addEventListener("tabviewhide", function() {
|
||||
self.exit();
|
||||
}, false);
|
||||
|
||||
// ___ setup key handlers
|
||||
this._setTabViewFrameKeyHandlers();
|
||||
|
||||
|
@ -425,7 +421,7 @@ let UI = {
|
|||
// Function: isTabViewVisible
|
||||
// Returns true if the TabView UI is currently shown.
|
||||
isTabViewVisible: function UI_isTabViewVisible() {
|
||||
return gTabViewDeck.selectedIndex == 1;
|
||||
return gTabViewDeck.selectedPanel == gTabViewFrame;
|
||||
},
|
||||
|
||||
// ---------
|
||||
|
@ -464,7 +460,7 @@ let UI = {
|
|||
// Restore the full height when showing TabView
|
||||
gTabViewFrame.style.marginTop = "";
|
||||
#endif
|
||||
gTabViewDeck.selectedIndex = 1;
|
||||
gTabViewDeck.selectedPanel = gTabViewFrame;
|
||||
gWindow.TabsInTitlebar.allowedBy("tabview-open", false);
|
||||
gTabViewFrame.contentWindow.focus();
|
||||
|
||||
|
@ -546,7 +542,7 @@ let UI = {
|
|||
// as well as avoiding the flash of black as we animate out
|
||||
gTabViewFrame.style.marginTop = gBrowser.boxObject.y + "px";
|
||||
#endif
|
||||
gTabViewDeck.selectedIndex = 0;
|
||||
gTabViewDeck.selectedPanel = gBrowserPanel;
|
||||
gWindow.TabsInTitlebar.allowedBy("tabview-open", true);
|
||||
gBrowser.contentWindow.focus();
|
||||
|
||||
|
|
|
@ -130,6 +130,7 @@ _BROWSER_FILES = \
|
|||
browser_tabview_bug641802.js \
|
||||
browser_tabview_bug644097.js \
|
||||
browser_tabview_bug645653.js \
|
||||
browser_tabview_bug649006.js \
|
||||
browser_tabview_dragdrop.js \
|
||||
browser_tabview_exit_button.js \
|
||||
browser_tabview_expander.js \
|
||||
|
|
|
@ -2,66 +2,53 @@
|
|||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
window.addEventListener('tabviewshown', onTabViewWindowLoaded, false);
|
||||
TabView.toggle();
|
||||
}
|
||||
let cw, search, searchButton;
|
||||
|
||||
function onTabViewWindowLoaded() {
|
||||
window.removeEventListener('tabviewshown', onTabViewWindowLoaded, false);
|
||||
|
||||
let contentWindow = document.getElementById('tab-view').contentWindow;
|
||||
let search = contentWindow.document.getElementById('search');
|
||||
let searchButton = contentWindow.document.getElementById('searchbutton');
|
||||
|
||||
let isSearchEnabled = function () {
|
||||
return 'none' != search.style.display;
|
||||
}
|
||||
|
||||
let assertSearchIsEnabled = function () {
|
||||
ok(isSearchEnabled(), 'search is enabled');
|
||||
isnot(search.style.display, "none", "search is enabled");
|
||||
}
|
||||
|
||||
|
||||
let assertSearchIsDisabled = function () {
|
||||
ok(!isSearchEnabled(), 'search is disabled');
|
||||
is(search.style.display, "none", "search is disabled");
|
||||
}
|
||||
|
||||
|
||||
let testSearchInitiatedByKeyPress = function () {
|
||||
EventUtils.synthesizeKey('a', {});
|
||||
EventUtils.synthesizeKey("a", {}, cw);
|
||||
assertSearchIsEnabled();
|
||||
|
||||
EventUtils.synthesizeKey('VK_BACK_SPACE', {});
|
||||
|
||||
EventUtils.synthesizeKey("VK_BACK_SPACE", {}, cw);
|
||||
assertSearchIsDisabled();
|
||||
}
|
||||
|
||||
|
||||
let testSearchInitiatedByMouseClick = function () {
|
||||
EventUtils.sendMouseEvent({type: 'mousedown'}, searchButton, contentWindow);
|
||||
EventUtils.sendMouseEvent({type: "mousedown"}, searchButton, cw);
|
||||
assertSearchIsEnabled();
|
||||
|
||||
EventUtils.synthesizeKey('a', {});
|
||||
EventUtils.synthesizeKey('VK_BACK_SPACE', {});
|
||||
EventUtils.synthesizeKey('VK_BACK_SPACE', {});
|
||||
|
||||
EventUtils.synthesizeKey("a", {}, cw);
|
||||
EventUtils.synthesizeKey("VK_BACK_SPACE", {}, cw);
|
||||
EventUtils.synthesizeKey("VK_BACK_SPACE", {}, cw);
|
||||
assertSearchIsEnabled();
|
||||
|
||||
EventUtils.synthesizeKey('VK_ESCAPE', {});
|
||||
|
||||
EventUtils.synthesizeKey("VK_ESCAPE", {}, cw);
|
||||
assertSearchIsDisabled();
|
||||
}
|
||||
|
||||
let finishTest = function () {
|
||||
let onTabViewHidden = function () {
|
||||
window.removeEventListener('tabviewhidden', onTabViewHidden, false);
|
||||
|
||||
waitForExplicitFinish();
|
||||
|
||||
newWindowWithTabView(function (win) {
|
||||
registerCleanupFunction(function () win.close());
|
||||
|
||||
cw = win.TabView.getContentWindow();
|
||||
search = cw.document.getElementById("search");
|
||||
searchButton = cw.document.getElementById("searchbutton");
|
||||
|
||||
SimpleTest.waitForFocus(function () {
|
||||
assertSearchIsDisabled();
|
||||
|
||||
testSearchInitiatedByKeyPress();
|
||||
testSearchInitiatedByMouseClick();
|
||||
|
||||
finish();
|
||||
}
|
||||
|
||||
window.addEventListener('tabviewhidden', onTabViewHidden, false);
|
||||
TabView.hide();
|
||||
}
|
||||
|
||||
assertSearchIsDisabled();
|
||||
|
||||
testSearchInitiatedByKeyPress();
|
||||
testSearchInitiatedByMouseClick();
|
||||
|
||||
finishTest();
|
||||
}, cw);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -25,8 +25,10 @@ function onTabViewWindowLoaded() {
|
|||
window.removeEventListener("tabviewshown", onTabViewWindowLoaded, false);
|
||||
ok(TabView.isVisible(), "Tab View is visible");
|
||||
|
||||
let contentWindow = document.getElementById("tab-view").contentWindow;
|
||||
testOne(contentWindow);
|
||||
afterAllTabItemsUpdated(function() {
|
||||
let contentWindow = document.getElementById("tab-view").contentWindow;
|
||||
testOne(contentWindow);
|
||||
});
|
||||
}
|
||||
|
||||
function testOne(contentWindow) {
|
||||
|
|
|
@ -2,71 +2,44 @@
|
|||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
newWindowWithTabView(onTabViewWindowLoaded);
|
||||
}
|
||||
let checkUpdateTimes = function (groupItem) {
|
||||
let children = groupItem.getChildren();
|
||||
let earliestUpdateTime = children.shift()._testLastTabUpdateTime;
|
||||
|
||||
let contentWindow = null;
|
||||
|
||||
function onTabViewWindowLoaded(win) {
|
||||
ok(win.TabView.isVisible(), "Tab View is visible");
|
||||
|
||||
contentWindow = win.TabView.getContentWindow();
|
||||
|
||||
// Preparation
|
||||
//
|
||||
let numTabs = 10;
|
||||
let groupItem = createGroupItemWithBlankTabs(win, 150, 150, 100,
|
||||
numTabs, false);
|
||||
|
||||
// Ensure that group is stacked
|
||||
ok(groupItem.isStacked(), "Group item is stacked");
|
||||
|
||||
// Force updates to be deferred
|
||||
contentWindow.TabItems.pausePainting();
|
||||
let children = groupItem.getChildren();
|
||||
is(children.length, numTabs, "Correct number of tabitems created");
|
||||
|
||||
let leftToUpdate = numTabs;
|
||||
let testFunc = function(tabItem) {
|
||||
tabItem.removeSubscriber(tabItem, "updated");
|
||||
if (--leftToUpdate>0)
|
||||
return;
|
||||
// Now that everything is updated, compare update times.
|
||||
// All tabs in the group should have updated AFTER the first one.
|
||||
let earliest = children[0]._lastTabUpdateTime;
|
||||
for (let c=1; c<children.length; ++c)
|
||||
ok(earliest <= children[c]._lastTabUpdateTime,
|
||||
"Stacked group item update ("+children[c]._lastTabUpdateTime+") > first item ("+earliest+")");
|
||||
shutDown(win, groupItem);
|
||||
};
|
||||
|
||||
for (let c=0; c<children.length; ++c) {
|
||||
let tabItem = children[c];
|
||||
tabItem.addSubscriber(tabItem, "updated", testFunc);
|
||||
contentWindow.TabItems.update(tabItem.tab);
|
||||
children.forEach(function (tabItem) {
|
||||
let updateTime = tabItem._testLastTabUpdateTime;
|
||||
ok(earliestUpdateTime <= updateTime, "Stacked group item update (" +
|
||||
updateTime + ") > first item (" + earliestUpdateTime + ")");
|
||||
});
|
||||
}
|
||||
|
||||
// Let the update queue start again
|
||||
contentWindow.TabItems.resumePainting();
|
||||
}
|
||||
waitForExplicitFinish();
|
||||
|
||||
function shutDown(win, groupItem) {
|
||||
// Shut down
|
||||
let groupItemCount = contentWindow.GroupItems.groupItems.length;
|
||||
closeGroupItem(groupItem, function() {
|
||||
// check the number of groups.
|
||||
is(contentWindow.GroupItems.groupItems.length, --groupItemCount,
|
||||
"The number of groups is decreased by 1");
|
||||
let onTabViewHidden = function() {
|
||||
win.removeEventListener("tabviewhidden", onTabViewHidden, false);
|
||||
// assert that we're no longer in tab view
|
||||
ok(!TabView.isVisible(), "Tab View is hidden");
|
||||
win.close();
|
||||
ok(win.closed, "new window is closed");
|
||||
finish();
|
||||
};
|
||||
win.addEventListener("tabviewhidden", onTabViewHidden, false);
|
||||
win.TabView.toggle();
|
||||
newWindowWithTabView(function (win) {
|
||||
registerCleanupFunction(function () win.close());
|
||||
|
||||
let numTabsToUpdate = 10;
|
||||
let groupItem = createGroupItemWithBlankTabs(win, 150, 150, 100, numTabsToUpdate, false);
|
||||
ok(groupItem.isStacked(), "groupItem is stacked");
|
||||
|
||||
let cw = win.TabView.getContentWindow();
|
||||
cw.TabItems.pausePainting();
|
||||
|
||||
groupItem.getChildren().forEach(function (tabItem) {
|
||||
tabItem.addSubscriber(tabItem, "updated", function () {
|
||||
tabItem.removeSubscriber(tabItem, "updated");
|
||||
tabItem._testLastTabUpdateTime = tabItem._lastTabUpdateTime;
|
||||
|
||||
if (--numTabsToUpdate)
|
||||
return;
|
||||
|
||||
checkUpdateTimes(groupItem);
|
||||
finish();
|
||||
});
|
||||
|
||||
cw.TabItems.update(tabItem.tab);
|
||||
});
|
||||
|
||||
cw.TabItems.resumePainting();
|
||||
});
|
||||
}
|
||||
|
|
|
@ -4,84 +4,61 @@
|
|||
let originalTab;
|
||||
let orphanedTab;
|
||||
let contentWindow;
|
||||
let contentElement;
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
window.addEventListener("tabviewshown", onTabViewWindowLoaded, false);
|
||||
TabView.show();
|
||||
}
|
||||
|
||||
function onTabViewWindowLoaded() {
|
||||
window.removeEventListener("tabviewshown", onTabViewWindowLoaded, false);
|
||||
|
||||
contentWindow = document.getElementById("tab-view").contentWindow;
|
||||
originalTab = gBrowser.visibleTabs[0];
|
||||
|
||||
test1();
|
||||
showTabView(function() {
|
||||
contentWindow = TabView.getContentWindow();
|
||||
contentElement = contentWindow.document.getElementById("content");
|
||||
originalTab = gBrowser.visibleTabs[0];
|
||||
test1();
|
||||
});
|
||||
}
|
||||
|
||||
function test1() {
|
||||
is(contentWindow.GroupItems.getOrphanedTabs().length, 0, "No orphaned tabs");
|
||||
|
||||
let onTabViewHidden = function() {
|
||||
window.removeEventListener("tabviewhidden", onTabViewHidden, false);
|
||||
|
||||
let onTabViewShown = function() {
|
||||
window.removeEventListener("tabviewshown", onTabViewShown, false);
|
||||
|
||||
is(contentWindow.GroupItems.getOrphanedTabs().length, 1,
|
||||
whenTabViewIsHidden(function() {
|
||||
showTabView(function() {
|
||||
is(contentWindow.GroupItems.getOrphanedTabs().length, 1,
|
||||
"An orphaned tab is created");
|
||||
orphanedTab = contentWindow.GroupItems.getOrphanedTabs()[0].tab;
|
||||
|
||||
test2();
|
||||
};
|
||||
window.addEventListener("tabviewshown", onTabViewShown, false);
|
||||
TabView.show();
|
||||
};
|
||||
window.addEventListener("tabviewhidden", onTabViewHidden, false);
|
||||
});
|
||||
});
|
||||
|
||||
// first click
|
||||
EventUtils.sendMouseEvent(
|
||||
{ type: "mousedown" }, contentWindow.document.getElementById("content"),
|
||||
contentWindow);
|
||||
EventUtils.sendMouseEvent(
|
||||
{ type: "mouseup" }, contentWindow.document.getElementById("content"),
|
||||
contentWindow);
|
||||
mouseClick(contentElement, 0);
|
||||
// second click
|
||||
EventUtils.sendMouseEvent(
|
||||
{ type: "mousedown" }, contentWindow.document.getElementById("content"),
|
||||
contentWindow);
|
||||
EventUtils.sendMouseEvent(
|
||||
{ type: "mouseup" }, contentWindow.document.getElementById("content"),
|
||||
contentWindow);
|
||||
mouseClick(contentElement, 0);
|
||||
}
|
||||
|
||||
function test2() {
|
||||
let groupItem = createEmptyGroupItem(contentWindow, 300, 300, 200);
|
||||
is(groupItem.getChildren().length, 0, "The group is empty");
|
||||
|
||||
let onTabViewHidden = function() {
|
||||
window.removeEventListener("tabviewhidden", onTabViewHidden, false);
|
||||
|
||||
hideTabView(function() {
|
||||
is(groupItem.getChildren().length, 1, "A tab is created inside the group");
|
||||
|
||||
|
||||
gBrowser.selectedTab = originalTab;
|
||||
gBrowser.removeTab(orphanedTab);
|
||||
gBrowser.removeTab(groupItem.getChildren()[0].tab);
|
||||
|
||||
finish();
|
||||
};
|
||||
window.addEventListener("tabviewhidden", onTabViewHidden, false);
|
||||
});
|
||||
|
||||
// first click
|
||||
EventUtils.sendMouseEvent(
|
||||
{ type: "mousedown" }, groupItem.container, contentWindow);
|
||||
EventUtils.sendMouseEvent(
|
||||
{ type: "mouseup" }, groupItem.container, contentWindow);
|
||||
mouseClick(groupItem.container, 0);
|
||||
// second click
|
||||
EventUtils.sendMouseEvent(
|
||||
{ type: "mousedown" }, groupItem.container, contentWindow);
|
||||
EventUtils.sendMouseEvent(
|
||||
{ type: "mouseup" }, groupItem.container, contentWindow);
|
||||
mouseClick(groupItem.container, 0);
|
||||
}
|
||||
|
||||
function mouseClick(targetElement, buttonCode) {
|
||||
EventUtils.sendMouseEvent(
|
||||
{ type: "mousedown", button: buttonCode }, targetElement, contentWindow);
|
||||
EventUtils.sendMouseEvent(
|
||||
{ type: "mouseup", button: buttonCode }, targetElement, contentWindow);
|
||||
}
|
||||
|
|
|
@ -20,10 +20,6 @@ function test() {
|
|||
prefix + ": panorama button should not be in the toolbar");
|
||||
}
|
||||
|
||||
let assertNumberOfGroups = function (num) {
|
||||
is(cw.GroupItems.groupItems.length, num, prefix + ': there are ' + num + ' groups');
|
||||
}
|
||||
|
||||
let assertNumberOfTabs = function (num) {
|
||||
is(win.gBrowser.tabs.length, num, prefix + ': there are ' + num + ' tabs');
|
||||
}
|
||||
|
@ -91,7 +87,7 @@ function test() {
|
|||
assertToolbarButtonExists();
|
||||
|
||||
next();
|
||||
});
|
||||
}, win);
|
||||
}
|
||||
|
||||
let testDragToCreateOrphan = function (tab) {
|
||||
|
@ -124,14 +120,19 @@ function test() {
|
|||
prefix = 're-adding-after-removal';
|
||||
assertToolbarButtonNotExists();
|
||||
|
||||
TabView.firstUseExperienced = true;
|
||||
win.TabView.firstUseExperienced = true;
|
||||
assertToolbarButtonExists();
|
||||
removeToolbarButton();
|
||||
|
||||
TabView.firstUseExperienced = true;
|
||||
TabView._addToolbarButton();
|
||||
|
||||
assertToolbarButtonNotExists();
|
||||
next();
|
||||
|
||||
win.close();
|
||||
|
||||
newWindowWithTabView(function (newWin) {
|
||||
win = newWin;
|
||||
win.TabView.firstUseExperienced = true;
|
||||
assertToolbarButtonNotExists();
|
||||
next();
|
||||
});
|
||||
}
|
||||
|
||||
let tests = [testNameGroup, testDragToCreateGroup, testCreateOrphan,
|
||||
|
@ -140,39 +141,39 @@ function test() {
|
|||
let next = function () {
|
||||
let test = tests.shift();
|
||||
|
||||
if (win)
|
||||
win.close();
|
||||
|
||||
if (!test) {
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
|
||||
newWindowWithTabView(
|
||||
function (newWin) {
|
||||
cw = win.TabView.getContentWindow();
|
||||
let groupItem = cw.GroupItems.groupItems[0];
|
||||
groupItem.setSize(200, 200, true);
|
||||
groupItem.setUserSize();
|
||||
if (win)
|
||||
win.close();
|
||||
|
||||
TabView.firstUseExperienced = false;
|
||||
|
||||
let onLoad = function (newWin) {
|
||||
win = newWin;
|
||||
removeToolbarButton();
|
||||
}
|
||||
|
||||
let onShow = function () {
|
||||
cw = win.TabView.getContentWindow();
|
||||
|
||||
let groupItem = cw.GroupItems.groupItems[0];
|
||||
groupItem.setSize(200, 200, true);
|
||||
groupItem.setUserSize();
|
||||
|
||||
SimpleTest.waitForFocus(function () {
|
||||
assertToolbarButtonNotExists();
|
||||
test();
|
||||
},
|
||||
function(newWin) {
|
||||
win = newWin;
|
||||
removeToolbarButton();
|
||||
TabView.firstUseExperienced = false;
|
||||
TabView.init();
|
||||
}
|
||||
);
|
||||
}, cw);
|
||||
}
|
||||
|
||||
newWindowWithTabView(onShow, onLoad);
|
||||
}
|
||||
|
||||
waitForExplicitFinish();
|
||||
|
||||
registerCleanupFunction(function () {
|
||||
if (win && !win.closed)
|
||||
win.close();
|
||||
});
|
||||
registerCleanupFunction(function () win && win.close());
|
||||
|
||||
next();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,94 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
let contentWindow;
|
||||
let contentElement;
|
||||
let groupItem;
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
registerCleanupFunction(function () {
|
||||
hideTabView(function () {});
|
||||
});
|
||||
|
||||
showTabView(function() {
|
||||
contentWindow = TabView.getContentWindow();
|
||||
contentElement = contentWindow.document.getElementById("content");
|
||||
test1();
|
||||
});
|
||||
}
|
||||
|
||||
function test1() {
|
||||
is(gBrowser.tabs.length, 1,
|
||||
"Total number of tabs is 1 before right button double click");
|
||||
// first click
|
||||
mouseClick(contentElement, 2);
|
||||
// second click
|
||||
mouseClick(contentElement, 2);
|
||||
|
||||
is(gBrowser.tabs.length, 1,
|
||||
"Total number of tabs is 1 after right button double click");
|
||||
test2();
|
||||
}
|
||||
|
||||
|
||||
function test2() {
|
||||
is(gBrowser.tabs.length, 1,
|
||||
"Total number of tabs is 1 before left, right and left mouse clicks");
|
||||
|
||||
// first click
|
||||
mouseClick(contentElement, 0);
|
||||
// second click
|
||||
mouseClick(contentElement, 2);
|
||||
// third click
|
||||
mouseClick(contentElement, 0);
|
||||
|
||||
is(gBrowser.tabs.length, 1,
|
||||
"Total number of tabs is 1 before left, right and left mouse clicks");
|
||||
test3();
|
||||
}
|
||||
|
||||
function test3() {
|
||||
ok(contentWindow.GroupItems.groupItems.length, 1, "Only one group item exists");
|
||||
groupItem = contentWindow.GroupItems.groupItems[0];
|
||||
|
||||
is(groupItem.getChildren().length, 1,
|
||||
"The number of tab items in the group is 1 before right button double click");
|
||||
|
||||
// first click
|
||||
mouseClick(groupItem.container, 2);
|
||||
// second click
|
||||
mouseClick(groupItem.container, 2);
|
||||
|
||||
is(groupItem.getChildren().length, 1,
|
||||
"The number of tab items in the group is 1 after right button double click");
|
||||
test4();
|
||||
}
|
||||
|
||||
function test4() {
|
||||
is(groupItem.getChildren().length, 1,
|
||||
"The number of tab items in the group is 1 before left, right, left mouse clicks");
|
||||
|
||||
// first click
|
||||
mouseClick(groupItem.container, 0);
|
||||
// second click
|
||||
mouseClick(groupItem.container, 2);
|
||||
// third click
|
||||
mouseClick(groupItem.container, 0);
|
||||
|
||||
is(groupItem.getChildren().length, 1,
|
||||
"The number of tab items in the group is 1 before left, right, left mouse clicks");
|
||||
|
||||
hideTabView(function() {
|
||||
is(gBrowser.tabs.length, 1, "Total number of tabs is 1 after all tests");
|
||||
finish();
|
||||
});
|
||||
}
|
||||
|
||||
function mouseClick(targetElement, buttonCode) {
|
||||
EventUtils.sendMouseEvent(
|
||||
{ type: "mousedown", button: buttonCode }, targetElement, contentWindow);
|
||||
EventUtils.sendMouseEvent(
|
||||
{ type: "mouseup", button: buttonCode }, targetElement, contentWindow);
|
||||
}
|
||||
|
|
@ -1,8 +1,6 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
let tabViewShownCount = 0;
|
||||
|
||||
// ----------
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
@ -10,20 +8,12 @@ function test() {
|
|||
// verify initial state
|
||||
ok(!TabView.isVisible(), "Tab View starts hidden");
|
||||
|
||||
// use the Tab View button to launch it for the first time
|
||||
window.addEventListener("tabviewshown", onTabViewLoadedAndShown("ltr"), false);
|
||||
toggleTabView();
|
||||
}
|
||||
|
||||
function toggleTabView() {
|
||||
let tabViewCommand = document.getElementById("Browser:ToggleTabView");
|
||||
tabViewCommand.doCommand();
|
||||
showTabView(onTabViewLoadedAndShown("ltr"));
|
||||
}
|
||||
|
||||
// ----------
|
||||
function onTabViewLoadedAndShown(dir) {
|
||||
return function() {
|
||||
window.removeEventListener("tabviewshown", arguments.callee, false);
|
||||
ok(TabView.isVisible(), "Tab View is visible.");
|
||||
|
||||
let contentWindow = document.getElementById("tab-view").contentWindow;
|
||||
|
@ -32,24 +22,20 @@ function onTabViewLoadedAndShown(dir) {
|
|||
"The direction should be set to " + dir.toUpperCase());
|
||||
|
||||
// kick off the series
|
||||
window.addEventListener("tabviewhidden", onTabViewHidden(dir), false);
|
||||
TabView.toggle();
|
||||
hideTabView(onTabViewHidden(dir));
|
||||
};
|
||||
}
|
||||
|
||||
// ----------
|
||||
function onTabViewHidden(dir) {
|
||||
return function() {
|
||||
window.removeEventListener("tabviewhidden", arguments.callee, false);
|
||||
ok(!TabView.isVisible(), "Tab View is hidden.");
|
||||
|
||||
if (dir == "ltr") {
|
||||
// Switch to RTL mode
|
||||
Services.prefs.setCharPref("intl.uidirection.en-US", "rtl");
|
||||
|
||||
// use the Tab View button to launch it for the second time
|
||||
window.addEventListener("tabviewshown", onTabViewLoadedAndShown("rtl"), false);
|
||||
toggleTabView();
|
||||
showTabView(onTabViewLoadedAndShown("rtl"));
|
||||
} else {
|
||||
// Switch to LTR mode
|
||||
Services.prefs.clearUserPref("intl.uidirection.en-US");
|
||||
|
@ -58,4 +44,3 @@ function onTabViewHidden(dir) {
|
|||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ browser.jar:
|
|||
% style chrome://global/content/customizeToolbar.xul chrome://browser/skin/
|
||||
* content/browser/aboutDialog.xul (content/aboutDialog.xul)
|
||||
* content/browser/aboutDialog.js (content/aboutDialog.js)
|
||||
content/browser/aboutDialog.css (content/aboutDialog.css)
|
||||
* content/browser/aboutDialog.css (content/aboutDialog.css)
|
||||
* content/browser/aboutRobots.xhtml (content/aboutRobots.xhtml)
|
||||
* content/browser/aboutHome.xhtml (content/aboutHome.xhtml)
|
||||
* content/browser/aboutHome.js (content/aboutHome.js)
|
||||
|
|
После Ширина: | Высота: | Размер: 1.1 KiB |
|
@ -1,59 +1,46 @@
|
|||
# ***** 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 Firefox.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# the Mozilla Foundation <http://www.mozilla.org>
|
||||
# Portions created by the Initial Developer are Copyright (C) 2010
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
# in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
# of those above. If you wish to allow use of your version of this file only
|
||||
# under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
# use your version of this file under the terms of the MPL, indicate your
|
||||
# decision by deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this file under
|
||||
# the terms of any one of the MPL, the GPL or the LGPL.
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
DEPTH = ../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
MODULE = xpcom
|
||||
XPIDL_MODULE = xpcom_typelib_testxpt
|
||||
NO_DIST_INSTALL = 1
|
||||
|
||||
XPIDLSRCS = xptiITestInterface.idl
|
||||
|
||||
XPCSHELL_TESTS = xptunit
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
xpcom_typelib_test.jar:: $(XPIDL_GEN_DIR)/$(XPIDL_MODULE).xpt
|
||||
$(RM) -f $@
|
||||
cd $(XPIDL_GEN_DIR) && $(ZIP) -q ../$(@F) $(^F)
|
||||
|
||||
libs:: xpcom_typelib_test.jar
|
||||
$(INSTALL) $^ $(FINAL_TARGET)/components
|
||||
# ***** 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 Mozilla Installer code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Mozilla Foundation
|
||||
# Portions created by the Initial Developer are Copyright (C) 2006
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Robert Strong <robert.bugzilla@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 *****
|
||||
|
||||
# NSIS branding defines for Aurora builds.
|
||||
# The official release build branding.nsi is located in other-license/branding/firefox/
|
||||
# The unofficial build branding.nsi is located in browser/branding/unofficial/
|
||||
|
||||
# BrandFullNameInternal is used for some registry and file system values
|
||||
# instead of BrandFullName and typically should not be modified.
|
||||
!define BrandFullNameInternal "Aurora"
|
||||
!define CompanyName "mozilla.org"
|
||||
!define URLInfoAbout "http://www.mozilla.org"
|
||||
!define URLUpdateInfo "http://www.mozilla.org/projects/firefox"
|
|
@ -0,0 +1 @@
|
|||
MOZ_APP_DISPLAYNAME=Aurora
|
После Ширина: | Высота: | Размер: 151 KiB |
После Ширина: | Высота: | Размер: 58 KiB |
После Ширина: | Высота: | Размер: 2.0 KiB |
После Ширина: | Высота: | Размер: 19 KiB |
После Ширина: | Высота: | Размер: 6.0 KiB |
После Ширина: | Высота: | Размер: 9.2 KiB |
|
@ -0,0 +1,10 @@
|
|||
browser.jar:
|
||||
% content branding %content/branding/ contentaccessible=yes
|
||||
content/branding/about.png (about.png)
|
||||
content/branding/about-background.png (about-background.png)
|
||||
content/branding/about-logo.png (about-logo.png)
|
||||
content/branding/about-wordmark.png (about-wordmark.png)
|
||||
content/branding/icon48.png (icon48.png)
|
||||
content/branding/icon64.png (icon64.png)
|
||||
content/branding/icon128.png (../mozicon128.png)
|
||||
content/branding/icon16.png (../default16.png)
|
После Ширина: | Высота: | Размер: 1.8 KiB |
После Ширина: | Высота: | Размер: 3.5 KiB |
После Ширина: | Высота: | Размер: 6.0 KiB |
После Ширина: | Высота: | Размер: 22 KiB |
После Ширина: | Высота: | Размер: 3.1 KiB |