This commit is contained in:
Brian Hackett 2011-04-28 13:02:47 -07:00
Родитель 5608b46053 003f619b7f
Коммит ae1bb92435
1683 изменённых файлов: 47355 добавлений и 39218 удалений

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

@ -88,11 +88,6 @@ DIST_GARBAGE = config.cache config.log config.status config-defs.h \
netwerk/necko-config.h xpcom/xpcom-config.h xpcom/xpcom-private.h \
$(topsrcdir)/.mozconfig.mk $(topsrcdir)/.mozconfig.out
ifdef WINCE
check::
$(PYTHON) $(topsrcdir)/build/mobile/devicemanager-utils.py copy $(DIST)/bin
endif
default alldep all:: $(topsrcdir)/configure config.status
$(RM) -r $(DIST)/sdk
$(RM) -r $(DIST)/include
@ -195,21 +190,6 @@ endif
mv $(SYMBOL_INDEX_NAME).tmp $(SYMBOL_INDEX_NAME)
cd $(DIST)/crashreporter-symbols && \
zip -r9D "../$(PKG_PATH)$(SYMBOL_ARCHIVE_BASENAME).zip" . -i "*.sym" -i "*.txt"
else
ifdef WINCE
ifdef SYMBOLSTORE_PATH
echo building symbol store with symstore.exe
$(RM) -r $(DIST)/symbols
$(RM) "$(DIST)/$(SYMBOL_ARCHIVE_BASENAME).zip"
$(NSINSTALL) -D $(DIST)/symbols
$(SYMBOLSTORE_PATH) add -r -f "$(subst /,\,$(shell pwd -W))\*.PDB" \
-s $(DIST)/symbols/ -t "$(MOZ_PKG_APPNAME)" -v "$(MOZ_PKG_VERSION)"
echo packing symbols
$(NSINSTALL) -D $(DIST)/$(PKG_PATH)
cd $(DIST)/symbols && \
zip -r9D "../$(PKG_PATH)$(SYMBOL_ARCHIVE_BASENAME).zip" .
endif # SYMBOLSTORE_PATH
endif # WINCE
endif # MOZ_CRASHREPORTER
uploadsymbols:

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

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

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

@ -50,7 +50,7 @@
#include "nsAccEvent.h"
#include "nsIDOMDocument.h"
#include "nsIEventStateManager.h"
#include "nsEventStateManager.h"
#include "nsIServiceManager.h"
#ifdef MOZ_XUL
#include "nsIDOMXULMultSelectCntrlEl.h"
@ -203,7 +203,7 @@ AccEvent::CaptureIsFromUserInput(EIsFromUserInput aIsFromUserInput)
return;
}
nsIEventStateManager *esm = presShell->GetPresContext()->EventStateManager();
nsEventStateManager *esm = presShell->GetPresContext()->EventStateManager();
if (!esm) {
NS_NOTREACHED("There should always be an ESM for an event");
return;

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

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

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

@ -75,7 +75,7 @@
#include "nsRootAccessibleWrap.h"
#include "nsTextFragment.h"
#include "mozilla/Services.h"
#include "nsIEventStateManager.h"
#include "nsEventStates.h"
#ifdef MOZ_XUL
#include "nsXULAlertAccessible.h"

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

@ -99,7 +99,7 @@
#include "nsWhitespaceTokenizer.h"
#include "nsAttrName.h"
#include "nsNetUtil.h"
#include "nsIEventStateManager.h"
#include "nsEventStates.h"
#ifdef NS_DEBUG
#include "nsIDOMCharacterData.h"

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

@ -60,7 +60,7 @@
#include "nsIPresShell.h"
#include "nsPresContext.h"
#include "nsIScrollableFrame.h"
#include "nsIEventStateManager.h"
#include "nsEventStateManager.h"
#include "nsISelection2.h"
#include "nsISelectionController.h"
#include "nsPIDOMWindow.h"
@ -206,7 +206,7 @@ nsCoreUtils::GetAccessKeyFor(nsIContent *aContent)
// Accesskeys are registered by @accesskey attribute only. At first check
// whether it is presented on the given element to avoid the slow
// nsIEventStateManager::GetRegisteredAccessKey() method.
// nsEventStateManager::GetRegisteredAccessKey() method.
if (!aContent->HasAttr(kNameSpaceID_None, nsAccessibilityAtoms::accesskey))
return 0;
@ -222,13 +222,11 @@ nsCoreUtils::GetAccessKeyFor(nsIContent *aContent)
if (!presContext)
return 0;
nsIEventStateManager *esm = presContext->EventStateManager();
nsEventStateManager *esm = presContext->EventStateManager();
if (!esm)
return 0;
PRUint32 key = 0;
esm->GetRegisteredAccessKey(aContent, &key);
return key;
return esm->GetRegisteredAccessKey(aContent);
}
nsIContent *
@ -761,47 +759,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

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

@ -110,7 +110,7 @@ public:
/**
* Return an accesskey registered on the given element by
* nsIEventStateManager or 0 if there is no registered accesskey.
* nsEventStateManager or 0 if there is no registered accesskey.
*
* @param aContent - the given element.
*/
@ -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);
};

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

@ -61,7 +61,7 @@
#include "nsPIDOMWindow.h"
#include "nsIDOMXULPopupElement.h"
#include "nsIEditingSession.h"
#include "nsIEventStateManager.h"
#include "nsEventStateManager.h"
#include "nsIFrame.h"
#include "nsHTMLSelectAccessible.h"
#include "nsIInterfaceRequestorUtils.h"

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

@ -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
@ -466,7 +466,7 @@ nsFontSizeTextAttr::Format(const nscoord& aValue, nsAString& aFormattedValue)
//
// XXX todo: consider sharing this code with layout module? (bug 474621)
float px =
NSAppUnitsToFloatPixels(aValue, nsIDeviceContext::AppUnitsPerCSSPixel());
NSAppUnitsToFloatPixels(aValue, nsDeviceContext::AppUnitsPerCSSPixel());
// Each pt is 4/3 of a CSS pixel.
int pts = NS_lround(px*3/4);
@ -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

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

@ -337,7 +337,7 @@ private:
*/
nscoord GetFontSize(nsIFrame *aFrame);
nsIDeviceContext *mDC;
nsDeviceContext *mDC;
};

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

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

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

@ -42,7 +42,7 @@
#include "States.h"
#include "nsCoreUtils.h"
#include "nsIEventStateManager.h"
#include "nsEventStates.h"
////////////////////////////////////////////////////////////////////////////////
// nsHTMLLinkAccessible

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

@ -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"
@ -311,7 +310,7 @@ nsHyperTextAccessible::GetPosAndText(PRInt32& aStartOffset, PRInt32& aEndOffset,
*aEndFrame = nsnull;
}
if (aBoundsRect) {
aBoundsRect->Empty();
aBoundsRect->SetEmpty();
}
if (aStartAcc)
*aStartAcc = nsnull;

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

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

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

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

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

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

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

@ -280,16 +280,6 @@ nsXULMenuitemAccessible::
{
}
PRBool
nsXULMenuitemAccessible::Init()
{
if (!nsAccessibleWrap::Init())
return PR_FALSE;
nsCoreUtils::GeneratePopupTree(mContent);
return PR_TRUE;
}
PRUint64
nsXULMenuitemAccessible::NativeState()
{
@ -411,7 +401,7 @@ nsXULMenuitemAccessible::GetKeyboardShortcut(nsAString& aAccessKey)
static PRInt32 gMenuAccesskeyModifier = -1; // magic value of -1 indicates unitialized state
// We do not use nsCoreUtils::GetAccesskeyFor() because accesskeys for
// menu are't registered by nsIEventStateManager.
// menu are't registered by nsEventStateManager.
nsAutoString accesskey;
mContent->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::accesskey,
accesskey);

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

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

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

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

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

@ -75,17 +75,6 @@ probes/Makefile
extensions/Makefile
"
if [ "$WINCE" ]; then
add_makefiles "
build/wince/tools/Makefile
build/wince/shunt/Makefile
build/wince/shunt/include/windows.h
build/wince/shunt/include/ymath.h
build/wince/shunt/include/stdlib.h
build/wince/shunt/include/sys/Makefile
"
fi
if [ "$MOZ_MEMORY" -a "$LIBXUL_SDK" = "" ]; then
add_makefiles "
memory/jemalloc/Makefile

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

@ -84,7 +84,7 @@ include $(topsrcdir)/config/rules.mk
else
# Build a binary bootstrapping with XRE_main
ifneq (,$(filter OS2 WINCE WINNT,$(OS_ARCH)))
ifneq (,$(filter OS2 WINNT,$(OS_ARCH)))
PROGRAM = $(MOZ_APP_NAME)$(BIN_SUFFIX)
else
PROGRAM = $(MOZ_APP_NAME)-bin$(BIN_SUFFIX)
@ -161,16 +161,8 @@ include $(topsrcdir)/config/config.mk
ifdef _MSC_VER
# Always enter a Windows program through wmain, whether or not we're
# a console application.
ifdef WINCE
WIN32_EXE_LDFLAGS += -ENTRY:mainWCRTStartup
else
WIN32_EXE_LDFLAGS += -ENTRY:wmainCRTStartup
endif
endif
ifdef WINCE
EXTRA_DSO_LDOPTS += $(call EXPAND_LIBNAME,corelibc)
endif
ifdef BUILD_STATIC_LIBS
include $(topsrcdir)/config/static-config.mk
@ -189,7 +181,7 @@ OS_LIBS += $(call EXPAND_LIBNAME,comctl32 comdlg32 uuid shell32 ole32 oleaut32 v
OS_LIBS += $(call EXPAND_LIBNAME,usp10 msimg32)
endif
ifneq (,$(filter WINNT WINCE,$(OS_ARCH)))
ifeq ($(OS_ARCH),WINNT)
RCINCLUDE = splash.rc
ifndef GNU_CC
RCFLAGS += -DMOZ_PHOENIX -I$(srcdir)
@ -248,7 +240,7 @@ endif
endif
endif
ifneq (,$(filter-out OS2 WINNT WINCE,$(OS_ARCH)))
ifneq (,$(filter-out OS2 WINNT,$(OS_ARCH)))
$(MOZ_APP_NAME):: $(topsrcdir)/build/unix/mozilla.in $(GLOBAL_DEPS)
cat $< | sed -e "s|%MOZAPPDIR%|$(installdir)|" \
@ -290,13 +282,6 @@ libs::
endif
endif
ifdef WINCE
ifdef MOZ_FASTSTART
libs::
cp -f $(DIST)/bin/faststartstub.exe $(DIST)/bin/$(MOZ_APP_NAME)faststart.exe
endif
endif
libs:: $(srcdir)/profile/prefs.js
$(INSTALL) $(IFLAGS1) $^ $(DIST)/bin/defaults/profile

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

@ -26,6 +26,28 @@
<key>CFBundleTypeRole</key>
<string>Viewer</string>
</dict>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>svg</string>
</array>
<key>CFBundleTypeIconFile</key>
<string>document.icns</string>
<key>CFBundleTypeMIMETypes</key>
<array>
<string>image/svg+xml</string>
</array>
<key>CFBundleTypeName</key>
<string>SVG document</string>
<key>CFBundleTypeOSTypes</key>
<array>
<string>TEXT</string>
</array>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
<key>NSDocumentClass</key>
<string>BrowserDocument</string>
</dict>
<dict>
<key>CFBundleTypeExtensions</key>
<array>

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

@ -308,12 +308,7 @@ pref("browser.download.saveLinkAsFilenameTimeout", 1000);
pref("browser.download.useDownloadDir", true);
#ifdef WINCE
pref("browser.download.folderList", 2);
pref("browser.download.dir", "\\Storage Card");
#else
pref("browser.download.folderList", 1);
#endif
pref("browser.download.manager.showAlertOnComplete", true);
pref("browser.download.manager.showAlertInterval", 2000);
pref("browser.download.manager.retention", 2);
@ -371,11 +366,7 @@ pref("browser.link.open_newwindow", 3);
pref("browser.link.open_newwindow.restriction", 2);
// Tabbed browser
#ifndef WINCE
pref("browser.tabs.autoHide", false);
#else
pref("browser.tabs.autoHide", true);
#endif
pref("browser.tabs.closeWindowWithLastTab", true);
pref("browser.tabs.insertRelatedAfterCurrent", true);
pref("browser.tabs.warnOnClose", true);
@ -425,11 +416,6 @@ pref("javascript.options.showInConsole", true);
pref("general.warnOnAboutConfig", false);
#endif
#ifdef WINCE
// Set the threshold higher to avoid some slow script warnings
pref("dom.max_script_run_time", 20);
#endif
// This is the pref to control the location bar, change this to true to
// force this - this makes the origin of popup windows more obvious to avoid
// spoofing. We would rather not do it by default because it affects UE for web
@ -775,11 +761,7 @@ pref("browser.rights.3.shown", false);
pref("browser.rights.override", true);
#endif
#ifdef WINCE
pref("browser.sessionstore.resume_from_crash", false);
#else
pref("browser.sessionstore.resume_from_crash", true);
#endif
pref("browser.sessionstore.resume_session_once", false);
// minimal interval between two save operations in milliseconds
@ -899,39 +881,6 @@ pref("browser.bookmarks.editDialog.firstEditField", "namePicker");
pref("geo.wifi.uri", "https://www.google.com/loc/json");
pref("geo.wifi.protocol", 0);
#ifdef WINCE
// tweak awesomebar -- increase the delay until a search happens.
pref("browser.urlbar.delay", 250);
// disable safe browsing, due to perf hit
pref("browser.safebrowsing.enabled", false);
pref("browser.safebrowsing.malware.enabled", false);
// don't check for default browser
pref("browser.shell.checkDefaultBrowser", false);
// disable bfcache for memory
pref("browser.sessionhistory.max_total_viewers", 0);
pref("browser.sessionhistory.optimize_eviction", false);
// tweak default content sink prefs
pref("content.sink.interactive_deflect_count", 10); /* default 0 */
pref("content.sink.perf_deflect_count", 50); /* default 200 */
pref("content.sink.interactive_parse_time", 5000); /* default 3000 */
pref("content.sink.perf_parse_time", 150000); /* default 360000 */
pref("content.sink.pending_event_mode", 0); /* default 1 */
pref("content.sink.event_probe_rate", 1); /* default 1 */
pref("content.sink.interactive_time", 750000); /* default 750000 */
pref("content.sink.initial_perf_time", 500000); /* default 2000000 */
pref("content.sink.enable_perf_mode", 0); /* default 0; 0 == switch, 1 == stay interactive, 2 == stay perf */
// Write sessionstore.js less often
pref("browser.sessionstore.interval", 60000);
#endif /* WINCE */
// Whether to use a panel that looks like an OS X sheet for customization
#ifdef XP_MACOSX
pref("toolbar.customization.usesheet", true);
@ -946,6 +895,7 @@ pref("toolbar.customization.usesheet", false);
pref("dom.ipc.plugins.enabled.i386", false);
pref("dom.ipc.plugins.enabled.i386.flash player.plugin", true);
pref("dom.ipc.plugins.enabled.i386.javaplugin2_npapi.plugin", true);
pref("dom.ipc.plugins.enabled.i386.javaappletplugin.plugin", true);
// x86_64 ipc preferences
pref("dom.ipc.plugins.enabled.x86_64", true);
#else
@ -953,7 +903,6 @@ pref("dom.ipc.plugins.enabled", true);
#endif
#ifdef XP_WIN
#ifndef WINCE
pref("browser.taskbar.previews.enable", false);
pref("browser.taskbar.previews.max", 20);
pref("browser.taskbar.previews.cachetime", 5);
@ -964,7 +913,6 @@ pref("browser.taskbar.lists.maxListItemCount", 7);
pref("browser.taskbar.lists.tasks.enabled", true);
pref("browser.taskbar.lists.refreshInSeconds", 120);
#endif
#endif
#ifdef MOZ_SERVICES_SYNC
// The sync engines to use.

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

@ -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) \
@ -76,10 +75,8 @@ DEFINES += -DHAVE_SHELL_SERVICE=1
endif
ifneq (,$(filter windows cocoa gtk2, $(MOZ_WIDGET_TOOLKIT)))
ifneq ($(OS_ARCH),WINCE)
DEFINES += -DCONTEXT_COPY_IMAGE_CONTENTS=1
endif
endif
ifneq (,$(filter windows, $(MOZ_WIDGET_TOOLKIT)))
DEFINES += -DCAN_DRAW_IN_TITLEBAR=1

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

@ -2,52 +2,12 @@
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;
/* min-width and min-height create room for the logo */
min-width: 210px;
min-height: 210px;
margin-top:20px;
-moz-margin-start: 30px;
}
%endif
#rightBox {
background-image: url("chrome://branding/content/about-wordmark.png");
background-repeat: no-repeat;
/* padding-top creates room for the wordmark */
padding-top: 38px;
margin-top:20px;
%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) {
@ -56,9 +16,6 @@
#bottomBox {
padding: 15px 10px 0;
%ifndef MOZ_OFFICIAL_BRANDING
background-color: rgba(0,0,0,.7);
%endif
}
#version {
@ -87,7 +44,6 @@
}
#updateDeck > hbox > label:not([class="text-link"]) {
color: #909090;
font-style:italic;
}
@ -111,17 +67,6 @@
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;
padding: 0;
@ -132,13 +77,16 @@
margin-top: 10px;
}
#channelSelectorStart {
-moz-margin-start: 0;
}
#channelMenulist {
margin: 0;
}
.channel-description {
margin: 10px 0;
text-align: center;
}
#detailsBox,

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

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

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

@ -41,6 +41,7 @@
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<?xml-stylesheet href="chrome://browser/content/aboutDialog.css" type="text/css"?>
<?xml-stylesheet href="chrome://branding/content/aboutDialog.css" type="text/css"?>
<!DOCTYPE window [
<!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd" >
@ -127,8 +128,8 @@
</vbox>
<vbox id="channelSelector">
<hbox pack="center" align="center">
<label>&channel.selector.start;</label>
<hbox pack="start" align="center">
<label id="channelSelectorStart">&channel.selector.start;</label>
<menulist id="channelMenulist" onselect="gChannelSelector.selectChannel(this.selectedItem);">
<menupopup>
<menuitem id="releaseMenuitem" label="Release" value="release"/>
@ -146,9 +147,14 @@
<description id="auroraDescription" class="channel-description">&channel.aurora.description;</description>
</deck>
<hbox id="channelSelectorButtons" pack="center">
<hbox id="channelSelectorButtons" pack="end">
#ifdef XP_UNIX
<button oncommand="gChannelSelector.cancel();" label="&channel.selector.cancelButton;"/>
<button oncommand="gChannelSelector.apply();" label="&channel.selector.applyButton;"/>
#else
<button oncommand="gChannelSelector.apply();" label="&channel.selector.applyButton;"/>
<button oncommand="gChannelSelector.cancel();" label="&channel.selector.cancelButton;"/>
#endif
</hbox>
</vbox>
</deck>

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

@ -91,7 +91,6 @@
accesskey="&sendPageCmd.accesskey;"
command="Browser:SendLink"/>
<menuseparator/>
#ifndef WINCE
<menuitem id="menu_printSetup"
label="&printSetupCmd.label;"
accesskey="&printSetupCmd.accesskey;"
@ -114,7 +113,6 @@
oncommand="BrowserImport();"/>
#ifndef XP_MACOSX
<menuseparator/>
#endif
#endif
<menuitem id="goOfflineMenuitem"
label="&goOfflineCmd.label;"

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

@ -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,9 +38,12 @@
let TabView = {
_deck: null,
_iframe: null,
_window: null,
_firstUseExperienced: false,
_browserKeyHandlerInitialized: false,
_isFrameLoading: false,
_initFrameCallbacks: [],
VISIBILITY_IDENTIFIER: "tabview-visibility",
// ----------
@ -127,34 +130,52 @@ let TabView = {
// Creates the frame and calls the callback once it's loaded.
// If the frame already exists, calls the callback immediately.
_initFrame: function TabView__initFrame(callback) {
let hasCallback = typeof callback == "function";
if (this._window) {
if (typeof callback == "function")
if (hasCallback)
callback();
} else {
// ___ find the deck
this._deck = document.getElementById("tab-view-deck");
return;
}
// ___ create the frame
let iframe = document.createElement("iframe");
iframe.id = "tab-view";
iframe.setAttribute("transparent", "true");
iframe.flex = 1;
if (hasCallback)
this._initFrameCallbacks.push(callback);
if (typeof callback == "function")
window.addEventListener("tabviewframeinitialized", callback, false);
if (this._isFrameLoading)
return;
iframe.setAttribute("src", "chrome://browser/content/tabview.html");
this._deck.appendChild(iframe);
this._window = iframe.contentWindow;
this._isFrameLoading = true;
if (this._tabShowEventListener) {
// ___ find the deck
this._deck = document.getElementById("tab-view-deck");
// ___ create the frame
this._iframe = document.createElement("iframe");
this._iframe.id = "tab-view";
this._iframe.setAttribute("transparent", "true");
this._iframe.flex = 1;
let self = this;
window.addEventListener("tabviewframeinitialized", function onInit() {
window.removeEventListener("tabviewframeinitialized", onInit, false);
self._isFrameLoading = false;
self._window = self._iframe.contentWindow;
self._setBrowserKeyHandlers();
if (self._tabShowEventListener) {
gBrowser.tabContainer.removeEventListener(
"TabShow", this._tabShowEventListener, true);
this._tabShowEventListener = null;
"TabShow", self._tabShowEventListener, true);
self._tabShowEventListener = null;
}
this._setBrowserKeyHandlers();
}
self._initFrameCallbacks.forEach(function (cb) cb());
self._initFrameCallbacks = [];
}, false);
this._iframe.setAttribute("src", "chrome://browser/content/tabview.html");
this._deck.appendChild(this._iframe);
},
// ----------
@ -163,19 +184,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 +204,7 @@ let TabView = {
if (!this.isVisible())
return;
let event = document.createEvent("Events");
event.initEvent("tabviewhide", false, false);
dispatchEvent(event);
this._window.UI.exit();
},
// ----------

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

@ -188,7 +188,6 @@ let gInitialPages = [
XPCOMUtils.defineLazyGetter(this, "Win7Features", function () {
#ifdef XP_WIN
#ifndef WINCE
const WINTASKBAR_CONTRACTID = "@mozilla.org/windows-taskbar;1";
if (WINTASKBAR_CONTRACTID in Cc &&
Cc[WINTASKBAR_CONTRACTID].getService(Ci.nsIWinTaskbar).available) {
@ -204,7 +203,6 @@ XPCOMUtils.defineLazyGetter(this, "Win7Features", function () {
}
};
}
#endif
#endif
return null;
});
@ -3296,16 +3294,15 @@ const BrowserSearch = {
win.BrowserSearch.webSearch();
} else {
// If there are no open browser windows, open a new one
// This needs to be in a timeout so that we don't end up refocused
// in the url bar
function webSearchCallback() {
setTimeout(BrowserSearch.webSearch, 0);
function observer(subject, topic, data) {
if (subject == win) {
BrowserSearch.webSearch();
Services.obs.removeObserver(observer, "browser-delayed-startup-finished");
}
}
win = window.openDialog("chrome://browser/content/", "_blank",
"chrome,all,dialog=no", "about:blank");
win.addEventListener("load", webSearchCallback, false);
Services.obs.addObserver(observer, "browser-delayed-startup-finished", false);
}
return;
}
@ -4034,16 +4031,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");
}
@ -5557,7 +5557,7 @@ function middleMousePaste(event) {
// Strip embedded newlines and surrounding whitespace, to match the URL
// bar's behavior (stripsurroundingwhitespace)
clipboard.replace(/\s*\n\s*/g, "");
clipboard = clipboard.replace(/\s*\n\s*/g, "");
let url = getShortcutOrURI(clipboard);
try {
@ -7794,7 +7794,7 @@ var gIdentityHandler = {
dt.setData("text/uri-list", value);
dt.setData("text/plain", value);
dt.setData("text/html", htmlString);
dt.addElement(event.currentTarget);
dt.setDragImage(gProxyFavIcon, 16, 16);
}
};

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

@ -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,15 +463,11 @@
#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"
#ifdef WINCE
defaulticonsize="small" iconsize="small"
#else
iconsize="large"
#endif
tabsontop="true"
persist="tabsontop">
<!-- Menu -->
@ -497,13 +495,8 @@
<toolbar id="nav-bar" class="toolbar-primary chromeclass-toolbar"
toolbarname="&navbarCmd.label;" accesskey="&navbarCmd.accesskey;"
fullscreentoolbar="true" mode="icons" customizable="true"
#ifdef WINCE
iconsize="small" defaulticonsize="small"
defaultset="unified-back-forward-button,urlbar-container,reload-button,stop-button,search-container,home-button,bookmarks-menu-button-container,navigator-throbber,fullscreenflex,window-controls"
#else
iconsize="large"
defaultset="unified-back-forward-button,urlbar-container,reload-button,stop-button,search-container,home-button,bookmarks-menu-button-container,fullscreenflex,window-controls"
#endif
context="toolbar-context-menu">
<toolbaritem id="unified-back-forward-button" class="chromeclass-toolbar-additional"

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

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

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

@ -374,5 +374,7 @@ function previousVisitCount(host, endTimeReference) {
var result = historyService.executeQuery(query, options);
result.root.containerOpen = true;
return result.root.childCount;
var cc = result.root.childCount;
result.root.containerOpen = false;
return cc;
}

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

@ -357,15 +357,10 @@
let promptBox = {
appendPrompt : function(args, onCloseCallback) {
let count = browser.getAttribute("tabmodalPromptShowing");
if (count)
count = parseInt(count) + 1;
else
count = 1;
browser.setAttribute("tabmodalPromptShowing", count);
let newPrompt = document.createElementNS(XUL_NS, "tabmodalprompt");
stack.appendChild(newPrompt);
browser.setAttribute("tabmodalPromptShowing", true);
newPrompt.clientTop; // style flush to assure binding is attached
let tab = self._getTabForContentWindow(browser.contentWindow);
@ -374,21 +369,22 @@
},
removePrompt : function(aPrompt) {
let count = parseInt(browser.getAttribute("tabmodalPromptShowing"));
count--;
if (count)
browser.setAttribute("tabmodalPromptShowing", count);
else
browser.removeAttribute("tabmodalPromptShowing");
stack.removeChild(aPrompt);
let prompts = this.listPrompts();
if (prompts.length) {
let prompt = prompts[prompts.length - 1];
prompt.Dialog.setDefaultFocus();
} else {
browser.removeAttribute("tabmodalPromptShowing");
browser.focus();
}
},
listPrompts : function(aPrompt) {
let prompts = [];
let els = stack.getElementsByTagNameNS(XUL_NS, "tabmodalprompt");
// NodeList --> real JS array
for (let i = 0; i < els.length; i++)
prompts.push(els[i]);
let prompts = Array.slice(els);
return prompts;
},
};
@ -814,7 +810,7 @@
}
} catch (e) {}
if (window.TabView) {
if ("TabView" in window) {
let groupName = TabView.getActiveGroupName();
if (groupName)
newTitle = groupName + sep + newTitle;
@ -828,7 +824,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;
@ -952,6 +948,16 @@
// Adjust focus
do {
// If there's a tabmodal prompt showing, focus it.
if (newBrowser.hasAttribute("tabmodalPromptShowing")) {
let XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
let prompts = newBrowser.parentNode.getElementsByTagNameNS(XUL_NS, "tabmodalprompt");
let prompt = prompts[prompts.length - 1];
prompt.Dialog.setDefaultFocus();
break;
}
// Focus the location bar if it was previously focused for that tab.
// In full screen mode, only bother making the location bar visible
// if the tab is a blank one.
@ -1271,7 +1277,7 @@
notificationbox.appendChild(stack);
var position = this.tabs.length - 1;
var uniqueId = "panel" + Math.floor(Date.now()) + position;
var uniqueId = "panel" + Date.now() + position;
notificationbox.id = uniqueId;
t.linkedPanel = uniqueId;
t.linkedBrowser = b;

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

@ -166,8 +166,10 @@ function GroupItem(listOfEls, options) {
this.$titleShield = iQ('.title-shield', this.$titlebar);
this.setTitle(options.title);
var handleKeyDown = function(e) {
if (e.which == 13 || e.which == 27) { // return & escape
var handleKeyPress = function (e) {
if (e.keyCode == KeyEvent.DOM_VK_ESCAPE ||
e.keyCode == KeyEvent.DOM_VK_RETURN ||
e.keyCode == KeyEvent.DOM_VK_ENTER) {
(self.$title)[0].blur();
self.$title
.addClass("transparentBorder")
@ -204,7 +206,7 @@ function GroupItem(listOfEls, options) {
.mousedown(function(e) {
e.stopPropagation();
})
.keydown(handleKeyDown)
.keypress(handleKeyPress)
.keyup(handleKeyUp);
this.$titleShield
@ -1147,7 +1149,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 +1197,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 +1220,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 +1231,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 +1674,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 +1793,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 +2043,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();

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

@ -705,88 +705,6 @@ function test_renotify_installed() {
},
function test_cancel_restart() {
// If the XPI is already cached then the HTTP observer won't see the request
var cacheService = Cc["@mozilla.org/network/cache-service;1"].
getService(Ci.nsICacheService);
try {
cacheService.evictEntries(Components.interfaces.nsICache.STORE_ANYWHERE);
} catch(ex) {}
// Must be registered before any request starts
var observerService = Cc["@mozilla.org/network/http-activity-distributor;1"].
getService(Ci.nsIHttpActivityDistributor);
observerService.addObserver({
observeActivity: function(aChannel, aType, aSubtype, aTimestamp, aSizeData,
aStringData) {
aChannel.QueryInterface(Ci.nsIChannel);
// Wait for the first event for the download
if (aChannel.URI.spec != TESTROOT + "unsigned.xpi" ||
aType != Ci.nsIHttpActivityObserver.ACTIVITY_TYPE_HTTP_TRANSACTION ||
aSubtype != Ci.nsIHttpActivityObserver.ACTIVITY_SUBTYPE_REQUEST_HEADER)
return;
observerService.removeObserver(this);
info("Replacing channel");
aChannel.QueryInterface(Ci.nsITraceableChannel);
var listener = aChannel.setNewListener({
onStartRequest: function(aRequest, aContext) {
listener.onStartRequest(aRequest, aContext);
},
onDataAvailable: function(aRequest, aContext, aInputStream, aOffset, aCount) {
listener.onDataAvailable(aRequest, aContext, aInputStream, aOffset, aCount);
},
onStopRequest: function(aRequest, aContext, aStatusCode) {
listener.onStopRequest(aRequest, aContext, aStatusCode);
// Request should have been cancelled
is(aStatusCode, Components.results.NS_BINDING_ABORTED, "Should have seen a cancelled request");
// Notification should have changed to cancelled
let notification = PopupNotifications.panel.childNodes[0];
is(notification.id, "addon-install-cancelled-notification", "Should have seen the cancelled notification");
// Wait for the install confirmation dialog
wait_for_install_dialog(function(aWindow) {
// Wait for the complete notification
wait_for_notification(function(aPanel) {
let notification = aPanel.childNodes[0];
is(notification.id, "addon-install-complete-notification", "Should have seen the install complete");
is(notification.button.label, "Restart Now", "Should have seen the right button");
is(notification.getAttribute("label"),
"XPI Test will be installed after you restart " + gApp + ".",
"Should have seen the right message");
AddonManager.getAllInstalls(function(aInstalls) {
is(aInstalls.length, 1, "Should be one pending install");
aInstalls[0].cancel();
Services.perms.remove("example.com", "install");
wait_for_notification_close(runNextTest);
gBrowser.removeTab(gBrowser.selectedTab);
});
});
aWindow.document.documentElement.acceptDialog();
});
// Restart the download
info("Restarting download");
EventUtils.synthesizeMouse(notification.button, 20, 10, {});
// Should be back to a progress notification
ok(PopupNotifications.isPanelOpen, "Notification should still be open");
is(PopupNotifications.panel.childNodes.length, 1, "Should be only one notification");
notification = PopupNotifications.panel.childNodes[0];
is(notification.id, "addon-progress-notification", "Should have seen the progress notification");
}
});
}
});
// Wait for the progress notification
wait_for_notification(function(aPanel) {
let notification = aPanel.childNodes[0];
@ -806,8 +724,44 @@ function test_cancel_restart() {
let button = document.getAnonymousElementByAttribute(notification, "anonid", "cancel");
// Cancel the download
info("Cancelling download");
EventUtils.synthesizeMouse(button, 2, 2, {});
// Notification should have changed to cancelled
notification = aPanel.childNodes[0];
is(notification.id, "addon-install-cancelled-notification", "Should have seen the cancelled notification");
// Wait for the install confirmation dialog
wait_for_install_dialog(function(aWindow) {
// Wait for the complete notification
wait_for_notification(function(aPanel) {
let notification = aPanel.childNodes[0];
is(notification.id, "addon-install-complete-notification", "Should have seen the install complete");
is(notification.button.label, "Restart Now", "Should have seen the right button");
is(notification.getAttribute("label"),
"XPI Test will be installed after you restart " + gApp + ".",
"Should have seen the right message");
AddonManager.getAllInstalls(function(aInstalls) {
is(aInstalls.length, 1, "Should be one pending install");
aInstalls[0].cancel();
Services.perms.remove("example.com", "install");
wait_for_notification_close(runNextTest);
gBrowser.removeTab(gBrowser.selectedTab);
});
});
aWindow.document.documentElement.acceptDialog();
});
// Restart the download
EventUtils.synthesizeMouse(notification.button, 20, 10, {});
// Should be back to a progress notification
ok(PopupNotifications.isPanelOpen, "Notification should still be open");
is(PopupNotifications.panel.childNodes.length, 1, "Should be only one notification");
notification = aPanel.childNodes[0];
is(notification.id, "addon-progress-notification", "Should have seen the progress notification");
});
var pm = Services.perms;

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

@ -65,25 +65,25 @@ function createDocument()
function nodeGenerator()
{
let body = doc.body;
newProperty = "rand" + Math.floor(Date.now());
newProperty = "rand" + Date.now();
body[newProperty] = Math.round(Math.random() * 100);
InspectorUI.inspectNode(body);
yield;
let h1 = doc.querySelector("h1");
newProperty = "rand2" + Math.floor(Date.now());
newProperty = "rand2" + Date.now();
h1[newProperty] = "test" + Math.random();
InspectorUI.inspectNode(h1);
yield;
let first = doc.getElementById("first");
newProperty = "rand3" + Math.floor(Date.now());
newProperty = "rand3" + Date.now();
first[newProperty] = null;
InspectorUI.inspectNode(first);
yield;
let closing = doc.getElementById("closing");
newProperty = "bazbaz" + Math.floor(Date.now());
newProperty = "bazbaz" + Date.now();
closing[newProperty] = false;
InspectorUI.inspectNode(closing);
yield;

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

@ -130,6 +130,9 @@ _BROWSER_FILES = \
browser_tabview_bug641802.js \
browser_tabview_bug644097.js \
browser_tabview_bug645653.js \
browser_tabview_bug649006.js \
browser_tabview_bug649307.js \
browser_tabview_bug651311.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) {

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

@ -34,7 +34,7 @@ function setupTwo(win) {
// force all canvases to update, and hook in imageData save detection
tabItems.forEach(function(tabItem) {
contentWindow.TabItems._update(tabItem.tab);
contentWindow.TabItems.update(tabItem.tab);
tabItem.addSubscriber(tabItem, "savedCachedImageData", function(item) {
item.removeSubscriber(item, "savedCachedImageData");
--numTabsToSave;
@ -70,8 +70,7 @@ function setupTwo(win) {
restoredWin.removeEventListener(
"tabviewframeinitialized", onTabViewFrameInitialized, false);
let restoredContentWindow =
restoredWin.document.getElementById("tab-view").contentWindow;
let restoredContentWindow = restoredWin.TabView.getContentWindow();
// prevent TabItems._update being called before checking cached images
restoredContentWindow.TabItems._pauseUpdateForTest = true;
@ -134,8 +133,7 @@ let gTabsProgressListener = {
function updateAndCheck() {
// force all canvas to update
let contentWindow =
restoredWin.document.getElementById("tab-view").contentWindow;
let contentWindow = restoredWin.TabView.getContentWindow();
contentWindow.TabItems._pauseUpdateForTest = false;

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

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

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

@ -3,74 +3,46 @@
// Tests that groups behave properly when closing all tabs but app tabs.
let appTab, contentWindow;
let originalGroup, originalGroupTab, newGroup, newGroupTab;
function test() {
let cw, win, groupItem;
let onLoad = function (tvwin) {
win = tvwin;
registerCleanupFunction(function () win.close());
win.gBrowser.pinTab(win.gBrowser.tabs[0]);
win.gBrowser.loadOneTab("about:blank", {inBackground: true});
};
let onShow = function () {
cw = win.TabView.getContentWindow();
is(cw.GroupItems.groupItems.length, 1, "There's only one group");
groupItem = createEmptyGroupItem(cw, 200, 200, 20);
cw.GroupItems.setActiveGroupItem(groupItem);
executeSoon(function () hideTabView(onHide, win));
};
let onHide = function () {
let tab = win.gBrowser.loadOneTab("about:blank", {inBackground: true});
is(groupItem.getChildren().length, 1, "One tab is in the new group");
executeSoon(function () {
is(win.gBrowser.visibleTabs.length, 2, "There are two tabs displayed");
win.gBrowser.removeTab(tab);
is(groupItem.getChildren().length, 0, "No tabs are in the new group");
is(win.gBrowser.visibleTabs.length, 1, "There is one tab displayed");
is(cw.GroupItems.groupItems.length, 2, "There are two groups still");
showTabView(function () {
is(cw.GroupItems.groupItems.length, 1, "There is now only one group");
waitForFocus(finish);
}, win);
});
};
waitForExplicitFinish();
appTab = gBrowser.selectedTab;
gBrowser.pinTab(appTab);
originalGroupTab = gBrowser.addTab();
addEventListener("tabviewshown", createGroup, false);
TabView.toggle();
newWindowWithTabView(onShow, onLoad);
}
function createGroup() {
removeEventListener("tabviewshown", createGroup, false);
contentWindow = document.getElementById("tab-view").contentWindow;
is(contentWindow.GroupItems.groupItems.length, 1, "There's only one group");
originalGroup = contentWindow.GroupItems.groupItems[0];
// Create a new group.
let box = new contentWindow.Rect(20, 400, 300, 300);
newGroup = new contentWindow.GroupItem([], { bounds: box });
contentWindow.GroupItems.setActiveGroupItem(newGroup);
addEventListener("tabviewhidden", addTab, false);
TabView.toggle();
}
function addTab() {
removeEventListener("tabviewhidden", addTab, false);
newGroupTab = gBrowser.addTab();
is(newGroup.getChildren().length, 1, "One tab is in the new group");
executeSoon(removeTab);
}
function removeTab() {
is(gBrowser.visibleTabs.length, 2, "There are two tabs displayed");
gBrowser.removeTab(newGroupTab);
is(newGroup.getChildren().length, 0, "No tabs are in the new group");
is(gBrowser.visibleTabs.length, 1, "There is one tab displayed");
is(contentWindow.GroupItems.groupItems.length, 2,
"There are two groups still");
addEventListener("tabviewshown", checkForRemovedGroup, false);
TabView.toggle();
}
function checkForRemovedGroup() {
removeEventListener("tabviewshown", checkForRemovedGroup, false);
is(contentWindow.GroupItems.groupItems.length, 1,
"There is now only one group");
addEventListener("tabviewhidden", finishTest, false);
TabView.toggle();
}
function finishTest() {
removeEventListener("tabviewhidden", finishTest, false);
gBrowser.removeTab(originalGroupTab);
gBrowser.unpinTab(appTab);
finish();
}

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

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

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

@ -0,0 +1,43 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
function test() {
waitForExplicitFinish();
newWindowWithTabView(function (win) {
let cw = win.TabView.getContentWindow();
registerCleanupFunction(function () {
cw.gPrefBranch.clearUserPref("animate_zoom");
win.close();
});
cw.gPrefBranch.setBoolPref("animate_zoom", false);
let groupItem = cw.GroupItems.groupItems[0];
let shield = groupItem.$titleShield[0];
let keys = ["RETURN", "ENTER", "ESCAPE"];
ok(win.TabView.isVisible(), "tabview is visible");
let simulateKeyPress = function () {
let key = keys.shift();
if (!key) {
ok(win.TabView.isVisible(), "tabview is still visible");
finish();
return;
}
EventUtils.synthesizeMouseAtCenter(shield, {}, cw);
EventUtils.synthesizeKey("VK_" + key, {}, cw);
executeSoon(function () {
ok(win.TabView.isVisible(), "tabview is still visible [" + key + "]");
simulateKeyPress();
});
}
SimpleTest.waitForFocus(simulateKeyPress, cw);
});
}

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

@ -0,0 +1,38 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
function test() {
waitForExplicitFinish();
let callCount = 0;
newWindow(function (win) {
registerCleanupFunction(function () win.close());
win.TabView._initFrame(function () {
is(callCount++, 0, "call count is zero");
ok(win.TabView.getContentWindow().UI, "content window is loaded");
});
win.TabView._initFrame(function () {
is(callCount++, 1, "call count is one");
ok(win.TabView.getContentWindow().UI, "content window is loaded");
});
win.TabView._initFrame(function () {
is(callCount, 2, "call count is two");
ok(win.TabView.getContentWindow().UI, "content window is loaded");
finish();
});
});
}
function newWindow(callback) {
let opts = "chrome,all,dialog=no,height=800,width=800";
let win = window.openDialog(getBrowserURL(), "_blank", opts);
win.addEventListener("load", function onLoad() {
win.removeEventListener("load", onLoad, false);
callback(win);
}, false);
}

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

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

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

@ -64,7 +64,7 @@
<children/>
<html:input anonid="input"
class="autocomplete-textbox urlbar-input textbox-input uri-element-right-align"
flex="1" allowevents="true"
allowevents="true"
xbl:inherits="tooltiptext=inputtooltiptext,onfocus,onblur,value,type,maxlength,disabled,size,readonly,placeholder,tabindex,accesskey"/>
</xul:hbox>
<children includes="hbox"/>

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

@ -0,0 +1,20 @@
#aboutDialogContainer {
background-image: url("chrome://branding/content/about-background.png");
background-repeat: no-repeat;
background-color: #000;
color: #fff;
}
.text-link {
color: #fff !important;
}
#rightBox {
/* this margin prevents text from overlapping the planet image */
margin-left: 280px;
margin-right: 20px;
}
#bottomBox {
background-color: rgba(0,0,0,.7);
}

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

@ -8,3 +8,4 @@ browser.jar:
content/branding/icon64.png (icon64.png)
content/branding/icon128.png (../mozicon128.png)
content/branding/icon16.png (../default16.png)
content/branding/aboutDialog.css (aboutDialog.css)

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

@ -0,0 +1,20 @@
#aboutDialogContainer {
background-image: url("chrome://branding/content/about-background.png");
background-repeat: no-repeat;
background-color: #000;
color: #fff;
}
.text-link {
color: #fff !important;
}
#rightBox {
/* this margin prevents text from overlapping the planet image */
margin-left: 280px;
margin-right: 20px;
}
#bottomBox {
background-color: rgba(0,0,0,.7);
}

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

@ -8,3 +8,4 @@ browser.jar:
content/branding/icon64.png (icon64.png)
content/branding/icon128.png (../mozicon128.png)
content/branding/icon16.png (../default16.png)
content/branding/aboutDialog.css (aboutDialog.css)

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

До

Ширина:  |  Высота:  |  Размер: 90 KiB

После

Ширина:  |  Высота:  |  Размер: 90 KiB

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

До

Ширина:  |  Высота:  |  Размер: 54 KiB

После

Ширина:  |  Высота:  |  Размер: 54 KiB

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

До

Ширина:  |  Высота:  |  Размер: 2.6 KiB

После

Ширина:  |  Высота:  |  Размер: 2.6 KiB

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

До

Ширина:  |  Высота:  |  Размер: 48 KiB

После

Ширина:  |  Высота:  |  Размер: 48 KiB

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

@ -0,0 +1,31 @@
#clientBox {
background-color: #F7F7F7;
color: #222222;
}
#leftBox {
background-image: url("chrome://branding/content/about-logo.png");
background-repeat: no-repeat;
/* min-width and min-height create room for the logo */
min-width: 210px;
min-height: 210px;
margin-top:20px;
-moz-margin-start: 30px;
}
#rightBox {
margin-left: 30px;
margin-right: 30px;
}
#updateDeck > hbox > label:not([class="text-link"]) {
color: #909090;
}
#trademark {
font-size: xx-small;
text-align: center;
color: #999999;
margin-top: 10px;
margin-bottom: 10px;
}

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

До

Ширина:  |  Высота:  |  Размер: 5.5 KiB

После

Ширина:  |  Высота:  |  Размер: 5.5 KiB

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

До

Ширина:  |  Высота:  |  Размер: 9.2 KiB

После

Ширина:  |  Высота:  |  Размер: 9.2 KiB

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

@ -7,3 +7,4 @@ browser.jar:
content/branding/icon64.png (icon64.png)
content/branding/icon128.png (../mozicon128.png)
content/branding/icon16.png (../default16.png)
content/branding/aboutDialog.css (aboutDialog.css)

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

До

Ширина:  |  Высота:  |  Размер: 972 B

После

Ширина:  |  Высота:  |  Размер: 972 B

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

До

Ширина:  |  Высота:  |  Размер: 1.6 KiB

После

Ширина:  |  Высота:  |  Размер: 1.6 KiB

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

До

Ширина:  |  Высота:  |  Размер: 1.8 KiB

После

Ширина:  |  Высота:  |  Размер: 1.8 KiB

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

До

Ширина:  |  Высота:  |  Размер: 75 KiB

После

Ширина:  |  Высота:  |  Размер: 75 KiB

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

До

Ширина:  |  Высота:  |  Размер: 2.8 KiB

После

Ширина:  |  Высота:  |  Размер: 2.8 KiB

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

До

Ширина:  |  Высота:  |  Размер: 5.5 KiB

После

Ширина:  |  Высота:  |  Размер: 5.5 KiB

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