зеркало из https://github.com/mozilla/gecko-dev.git
Merge TM -> JM
This commit is contained in:
Коммит
4c0de7be7e
1
.hgtags
1
.hgtags
|
@ -54,3 +54,4 @@ dba2abb7db57078c5a4810884834d3056a5d56c2 last-mozilla-central
|
|||
2f83edbbeef0de7dd901411d270da61106c8afae bsmedberg-static-xpcom-registration-base
|
||||
138f593553b66c9f815e8f57870c19d6347f7702 UPDATE_PACKAGING_R12
|
||||
138f593553b66c9f815e8f57870c19d6347f7702 UPDATE_PACKAGING_R13
|
||||
138f593553b66c9f815e8f57870c19d6347f7702 UPDATE_PACKAGING_R11_1_MU
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Corporation.
|
||||
* Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
|
|
|
@ -1081,7 +1081,7 @@ nsAccessibleWrap::FirePlatformEvent(AccEvent* aEvent)
|
|||
case nsIAccessibleEvent::EVENT_FOCUS:
|
||||
{
|
||||
MAI_LOG_DEBUG(("\n\nReceived: EVENT_FOCUS\n"));
|
||||
nsRefPtr<nsRootAccessible> rootAccWrap = accWrap->GetRootAccessible();
|
||||
nsRootAccessible* rootAccWrap = accWrap->RootAccessible();
|
||||
if (rootAccWrap && rootAccWrap->mActivated) {
|
||||
atk_focus_tracker_notify(atkObj);
|
||||
// Fire state change event for focus
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Corporation.
|
||||
* Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
|
|
|
@ -219,7 +219,7 @@ NotificationController::WillRefresh(mozilla::TimeStamp aTime)
|
|||
#endif
|
||||
|
||||
mTreeConstructedState = eTreeConstructed;
|
||||
mDocument->CacheChildrenInSubtree(mDocument);
|
||||
mDocument->NotifyOfInitialUpdate();
|
||||
|
||||
NS_ASSERTION(mContentInsertions.Length() == 0,
|
||||
"Pending content insertions while initial accessible tree isn't created!");
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Corporation.
|
||||
* Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Corporation.
|
||||
* Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Corporation.
|
||||
* Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Corporation.
|
||||
* Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
|
|
|
@ -285,7 +285,8 @@ nsAccessNode::GetDocAccessible() const
|
|||
GetAccService()->GetDocAccessible(mContent->GetOwnerDoc()) : nsnull;
|
||||
}
|
||||
|
||||
already_AddRefed<nsRootAccessible> nsAccessNode::GetRootAccessible()
|
||||
nsRootAccessible*
|
||||
nsAccessNode::RootAccessible() const
|
||||
{
|
||||
nsCOMPtr<nsIDocShellTreeItem> docShellTreeItem =
|
||||
nsCoreUtils::GetDocShellTreeItemFor(mContent);
|
||||
|
@ -300,9 +301,8 @@ already_AddRefed<nsRootAccessible> nsAccessNode::GetRootAccessible()
|
|||
return nsnull;
|
||||
}
|
||||
|
||||
nsDocAccessible *docAcc = nsAccUtils::GetDocAccessibleFor(root);
|
||||
nsRefPtr<nsRootAccessible> rootAcc = do_QueryObject(docAcc);
|
||||
return rootAcc.forget();
|
||||
nsDocAccessible* docAcc = nsAccUtils::GetDocAccessibleFor(root);
|
||||
return docAcc ? docAcc->AsRoot() : nsnull;
|
||||
}
|
||||
|
||||
nsIFrame*
|
||||
|
@ -347,8 +347,8 @@ nsAccessNode::GetRootDocument(nsIAccessibleDocument **aRootDocument)
|
|||
{
|
||||
NS_ENSURE_ARG_POINTER(aRootDocument);
|
||||
|
||||
nsRefPtr<nsRootAccessible> rootDocument = GetRootAccessible();
|
||||
NS_IF_ADDREF(*aRootDocument = rootDocument.get());
|
||||
nsRootAccessible* rootDocument = RootAccessible();
|
||||
NS_IF_ADDREF(*aRootDocument = rootDocument);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -105,7 +105,7 @@ public:
|
|||
/**
|
||||
* Return the root document accessible for this accessnode.
|
||||
*/
|
||||
already_AddRefed<nsRootAccessible> GetRootAccessible();
|
||||
nsRootAccessible* RootAccessible() const;
|
||||
|
||||
/**
|
||||
* Reference to a node of focused accessible.
|
||||
|
|
|
@ -559,6 +559,21 @@ nsAccessibilityService::PresShellDestroyed(nsIPresShell *aPresShell)
|
|||
docAccessible->Shutdown();
|
||||
}
|
||||
|
||||
void
|
||||
nsAccessibilityService::PresShellActivated(nsIPresShell* aPresShell)
|
||||
{
|
||||
nsIDocument* DOMDoc = aPresShell->GetDocument();
|
||||
if (DOMDoc) {
|
||||
nsDocAccessible* document = GetDocAccessibleFromCache(DOMDoc);
|
||||
if (document) {
|
||||
nsRootAccessible* rootDocument = document->RootAccessible();
|
||||
NS_ASSERTION(rootDocument, "Entirely broken tree: no root document!");
|
||||
if (rootDocument)
|
||||
rootDocument->DocumentActivated(document);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsAccessibilityService::RecreateAccessible(nsIPresShell* aPresShell,
|
||||
nsIContent* aContent)
|
||||
|
|
|
@ -124,6 +124,11 @@ public:
|
|||
|
||||
virtual void PresShellDestroyed(nsIPresShell* aPresShell);
|
||||
|
||||
/**
|
||||
* Notify that presshell is activated.
|
||||
*/
|
||||
virtual void PresShellActivated(nsIPresShell* aPresShell);
|
||||
|
||||
virtual void RecreateAccessible(nsIPresShell* aPresShell,
|
||||
nsIContent* aContent);
|
||||
|
||||
|
|
|
@ -364,6 +364,9 @@ public:
|
|||
inline bool IsHyperText() const { return mFlags & eHyperTextAccessible; }
|
||||
nsHyperTextAccessible* AsHyperText();
|
||||
|
||||
inline bool IsRoot() const { return mFlags & eRootAccessible; }
|
||||
nsRootAccessible* AsRoot();
|
||||
|
||||
inline bool IsTextLeaf() const { return mFlags & eTextLeafAccessible; }
|
||||
nsTextAccessible* AsTextLeaf();
|
||||
|
||||
|
@ -509,7 +512,8 @@ protected:
|
|||
enum AccessibleTypes {
|
||||
eApplicationAccessible = 1 << 2,
|
||||
eHyperTextAccessible = 1 << 3,
|
||||
eTextLeafAccessible = 1 << 4
|
||||
eRootAccessible = 1 << 4,
|
||||
eTextLeafAccessible = 1 << 5
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -770,7 +770,7 @@ nsresult nsDocAccessible::AddEventListeners()
|
|||
nsCOMPtr<nsIDocShellTreeItem> rootTreeItem;
|
||||
docShellTreeItem->GetRootTreeItem(getter_AddRefs(rootTreeItem));
|
||||
if (rootTreeItem) {
|
||||
nsRefPtr<nsRootAccessible> rootAccessible = GetRootAccessible();
|
||||
nsRootAccessible* rootAccessible = RootAccessible();
|
||||
NS_ENSURE_TRUE(rootAccessible, NS_ERROR_FAILURE);
|
||||
nsRefPtr<nsCaretAccessible> caretAccessible = rootAccessible->GetCaretAccessible();
|
||||
if (caretAccessible) {
|
||||
|
@ -817,7 +817,7 @@ nsresult nsDocAccessible::RemoveEventListeners()
|
|||
NS_RELEASE_THIS(); // Kung fu death grip
|
||||
}
|
||||
|
||||
nsRefPtr<nsRootAccessible> rootAccessible(GetRootAccessible());
|
||||
nsRootAccessible* rootAccessible = RootAccessible();
|
||||
if (rootAccessible) {
|
||||
nsRefPtr<nsCaretAccessible> caretAccessible = rootAccessible->GetCaretAccessible();
|
||||
if (caretAccessible) {
|
||||
|
@ -1135,7 +1135,7 @@ nsDocAccessible::ARIAAttributeChanged(nsIContent* aContent, nsIAtom* aAttribute)
|
|||
nsCOMPtr<nsINode> focusedNode = GetCurrentFocus();
|
||||
if (nsCoreUtils::GetRoleContent(focusedNode) == aContent) {
|
||||
nsAccessible* focusedAcc = GetAccService()->GetAccessible(focusedNode);
|
||||
nsRefPtr<nsRootAccessible> rootAcc = GetRootAccessible();
|
||||
nsRootAccessible* rootAcc = RootAccessible();
|
||||
if (rootAcc && focusedAcc) {
|
||||
rootAcc->FireAccessibleFocusEvent(focusedAcc, nsnull, PR_TRUE);
|
||||
}
|
||||
|
@ -1500,6 +1500,20 @@ nsDocAccessible::CacheChildren()
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Protected members
|
||||
|
||||
void
|
||||
nsDocAccessible::NotifyOfInitialUpdate()
|
||||
{
|
||||
// The content element may be changed before the initial update and then we
|
||||
// miss the notification (since content tree change notifications are ignored
|
||||
// prior to initial update). Make sure the content element is valid.
|
||||
nsIContent* contentElm = nsCoreUtils::GetRoleContent(mDocument);
|
||||
if (contentElm && mContent != contentElm)
|
||||
mContent = contentElm;
|
||||
|
||||
// Build initial tree.
|
||||
CacheChildrenInSubtree(this);
|
||||
}
|
||||
|
||||
void
|
||||
nsDocAccessible::AddDependentIDsFor(nsAccessible* aRelProvider,
|
||||
nsIAtom* aRelAttr)
|
||||
|
|
|
@ -345,6 +345,13 @@ protected:
|
|||
virtual void GetBoundsRect(nsRect& aRect, nsIFrame** aRelativeFrame);
|
||||
virtual nsresult AddEventListeners();
|
||||
virtual nsresult RemoveEventListeners();
|
||||
|
||||
/**
|
||||
* Notify this document that was bound to the accessible document tree.
|
||||
* Can be overridden by wrappers to prepare initialization work.
|
||||
*/
|
||||
virtual void NotifyOfInitialUpdate();
|
||||
|
||||
void AddScrollListener();
|
||||
void RemoveScrollListener();
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Corporation.
|
||||
* Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Corporation.
|
||||
* Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
|
|
|
@ -112,6 +112,7 @@ nsRootAccessible::
|
|||
nsIWeakReference *aShell) :
|
||||
nsDocAccessibleWrap(aDocument, aRootContent, aShell)
|
||||
{
|
||||
mFlags |= eRootAccessible;
|
||||
}
|
||||
|
||||
nsRootAccessible::~nsRootAccessible()
|
||||
|
@ -308,6 +309,9 @@ nsresult nsRootAccessible::RemoveEventListeners()
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// public
|
||||
|
||||
nsCaretAccessible*
|
||||
nsRootAccessible::GetCaretAccessible()
|
||||
{
|
||||
|
@ -435,6 +439,11 @@ nsRootAccessible::FireCurrentFocusEvent()
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsRootAccessible::DocumentActivated(nsDocAccessible* aDocument)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsIDOMEventListener
|
||||
|
||||
|
|
|
@ -124,6 +124,11 @@ public:
|
|||
|
||||
nsCaretAccessible *GetCaretAccessible();
|
||||
|
||||
/**
|
||||
* Notify that the sub document presshell was activated.
|
||||
*/
|
||||
virtual void DocumentActivated(nsDocAccessible* aDocument);
|
||||
|
||||
protected:
|
||||
NS_DECL_RUNNABLEMETHOD(nsRootAccessible, FireCurrentFocusEvent)
|
||||
|
||||
|
@ -164,4 +169,11 @@ protected:
|
|||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsRootAccessible, NS_ROOTACCESSIBLE_IMPL_CID)
|
||||
|
||||
inline nsRootAccessible*
|
||||
nsAccessible::AsRoot()
|
||||
{
|
||||
return mFlags & eRootAccessible ?
|
||||
static_cast<nsRootAccessible*>(this) : nsnull;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -365,7 +365,7 @@ GetNativeFromGeckoAccessible(nsIAccessible *anAccessible)
|
|||
// (which might be the owning NSWindow in the application, for example).
|
||||
//
|
||||
// get the native root accessible, and tell it to return its first parent unignored accessible.
|
||||
nsRefPtr<nsRootAccessible> root(mGeckoAccessible->GetRootAccessible());
|
||||
nsRootAccessible* root = mGeckoAccessible->RootAccessible();
|
||||
id nativeParent = GetNativeFromGeckoAccessible(static_cast<nsIAccessible*>(root));
|
||||
NSAssert1 (nativeParent, @"!!! we can't find a parent for %@", self);
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Corporation.
|
||||
* Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Corporation.
|
||||
* Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Corporation.
|
||||
* Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Corporation.
|
||||
* Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
|
|
|
@ -53,6 +53,7 @@ CPPSRCS = \
|
|||
nsDocAccessibleWrap.cpp \
|
||||
nsHTMLWin32ObjectAccessible.cpp \
|
||||
nsARIAGridAccessibleWrap.cpp \
|
||||
nsRootAccessibleWrap.cpp \
|
||||
nsXULMenuAccessibleWrap.cpp \
|
||||
nsXULListboxAccessibleWrap.cpp \
|
||||
nsXULTreeGridAccessibleWrap.cpp \
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Corporation.
|
||||
* Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Corporation.
|
||||
* Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
|
|
|
@ -776,6 +776,13 @@ nsAccessNodeWrap::WindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
case WM_NCHITTEST:
|
||||
{
|
||||
LRESULT lRet = ::DefWindowProc(hWnd, msg, wParam, lParam);
|
||||
if (HTCLIENT == lRet)
|
||||
lRet = HTTRANSPARENT;
|
||||
return lRet;
|
||||
}
|
||||
}
|
||||
|
||||
return ::DefWindowProcW(hWnd, msg, wParam, lParam);
|
||||
|
|
|
@ -1772,7 +1772,7 @@ void nsAccessibleWrap::UpdateSystemCaret()
|
|||
// off-screen model can follow the caret
|
||||
::DestroyCaret();
|
||||
|
||||
nsRefPtr<nsRootAccessible> rootAccessible = GetRootAccessible();
|
||||
nsRootAccessible* rootAccessible = RootAccessible();
|
||||
if (!rootAccessible) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -252,28 +252,6 @@ STDMETHODIMP nsDocAccessibleWrap::get_accValue(
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsAccessNode
|
||||
|
||||
PRBool
|
||||
nsDocAccessibleWrap::Init()
|
||||
{
|
||||
if (nsWinUtils::IsWindowEmulationEnabled()) {
|
||||
// Create window for tab document.
|
||||
if (nsWinUtils::IsTabDocument(mDocument)) {
|
||||
nsRefPtr<nsRootAccessible> root = GetRootAccessible();
|
||||
mHWND = nsWinUtils::CreateNativeWindow(kClassNameTabContent,
|
||||
static_cast<HWND>(root->GetNativeWindow()));
|
||||
|
||||
nsAccessibleWrap::sHWNDCache.Put(mHWND, this);
|
||||
|
||||
} else {
|
||||
nsDocAccessible* parentDocument = ParentDocument();
|
||||
if (parentDocument)
|
||||
mHWND = parentDocument->GetNativeWindow();
|
||||
}
|
||||
}
|
||||
|
||||
return nsDocAccessible::Init();
|
||||
}
|
||||
|
||||
void
|
||||
nsDocAccessibleWrap::Shutdown()
|
||||
{
|
||||
|
@ -291,10 +269,51 @@ nsDocAccessibleWrap::Shutdown()
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsDocAccessible
|
||||
// nsDocAccessible public
|
||||
|
||||
void*
|
||||
nsDocAccessibleWrap::GetNativeWindow() const
|
||||
{
|
||||
return mHWND ? mHWND : nsDocAccessible::GetNativeWindow();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsDocAccessible protected
|
||||
|
||||
void
|
||||
nsDocAccessibleWrap::NotifyOfInitialUpdate()
|
||||
{
|
||||
nsDocAccessible::NotifyOfInitialUpdate();
|
||||
|
||||
if (nsWinUtils::IsWindowEmulationEnabled()) {
|
||||
// Create window for tab document.
|
||||
if (nsWinUtils::IsTabDocument(mDocument)) {
|
||||
nsRootAccessible* rootDocument = RootAccessible();
|
||||
|
||||
PRBool isActive = PR_TRUE;
|
||||
PRInt32 x = CW_USEDEFAULT, y = CW_USEDEFAULT, width = 0, height = 0;
|
||||
if (nsWinUtils::IsWindowEmulationEnabled(kDolphinModuleHandle)) {
|
||||
GetBounds(&x, &y, &width, &height);
|
||||
PRInt32 rootX = 0, rootY = 0, rootWidth = 0, rootHeight = 0;
|
||||
rootDocument->GetBounds(&rootX, &rootY, &rootWidth, &rootHeight);
|
||||
x = rootX - x;
|
||||
y -= rootY;
|
||||
|
||||
nsCOMPtr<nsISupports> container = mDocument->GetContainer();
|
||||
nsCOMPtr<nsIDocShell> docShell = do_QueryInterface(container);
|
||||
docShell->GetIsActive(&isActive);
|
||||
}
|
||||
|
||||
HWND parentWnd = static_cast<HWND>(rootDocument->GetNativeWindow());
|
||||
mHWND = nsWinUtils::CreateNativeWindow(kClassNameTabContent, parentWnd,
|
||||
x, y, width, height, isActive);
|
||||
|
||||
nsAccessibleWrap::sHWNDCache.Put(mHWND, this);
|
||||
|
||||
} else {
|
||||
nsDocAccessible* parentDocument = ParentDocument();
|
||||
if (parentDocument)
|
||||
mHWND = parentDocument->GetNativeWindow();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -90,7 +90,6 @@ public:
|
|||
/* [retval][out] */ BSTR __RPC_FAR *pszValue);
|
||||
|
||||
// nsAccessNode
|
||||
virtual PRBool Init();
|
||||
virtual void Shutdown();
|
||||
|
||||
// nsAccessibleWrap
|
||||
|
@ -99,6 +98,10 @@ public:
|
|||
// nsDocAccessible
|
||||
virtual void* GetNativeWindow() const;
|
||||
|
||||
protected:
|
||||
// nsDocAccessible
|
||||
virtual void NotifyOfInitialUpdate();
|
||||
|
||||
protected:
|
||||
void* mHWND;
|
||||
};
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2011
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Alexander Surkov <surkov.alexander@gmail.com> (origianl author)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsRootAccessibleWrap.h"
|
||||
|
||||
#include "nsWinUtils.h"
|
||||
|
||||
#include "nsIDOMEventTarget.h"
|
||||
#include "nsIEventListenerManager.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Constructor/desctructor
|
||||
|
||||
nsRootAccessibleWrap::
|
||||
nsRootAccessibleWrap(nsIDocument* aDocument, nsIContent* aRootContent,
|
||||
nsIWeakReference* aShell) :
|
||||
nsRootAccessible(aDocument, aRootContent, aShell)
|
||||
{
|
||||
}
|
||||
|
||||
nsRootAccessibleWrap::~nsRootAccessibleWrap()
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsRootAccessible
|
||||
|
||||
void
|
||||
nsRootAccessibleWrap::DocumentActivated(nsDocAccessible* aDocument)
|
||||
{
|
||||
if (nsWinUtils::IsWindowEmulationEnabled(kDolphinModuleHandle) &&
|
||||
nsWinUtils::IsTabDocument(aDocument->GetDocumentNode())) {
|
||||
PRUint32 count = mChildDocuments.Length();
|
||||
for (PRUint32 idx = 0; idx < count; idx++) {
|
||||
nsDocAccessible* childDoc = mChildDocuments[idx];
|
||||
HWND childDocHWND = static_cast<HWND>(childDoc->GetNativeWindow());
|
||||
if (childDoc != aDocument)
|
||||
nsWinUtils::HideNativeWindow(childDocHWND);
|
||||
else
|
||||
nsWinUtils::ShowNativeWindow(childDocHWND);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -20,7 +20,8 @@
|
|||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Original Author: Aaron Leventhal (aaronl@netscape.com)
|
||||
* Aaron Leventhal <aaronl@netscape.com> (original author)
|
||||
* Alexander Surkov <surkov.alexander@gmail.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
|
@ -36,15 +37,20 @@
|
|||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
/* For documentation of the accessibility architecture,
|
||||
* see http://lxr.mozilla.org/seamonkey/source/accessible/accessible-docs.html
|
||||
*/
|
||||
|
||||
#ifndef _nsRootAccessibleWrap_H_
|
||||
#define _nsRootAccessibleWrap_H_
|
||||
|
||||
#include "nsRootAccessible.h"
|
||||
|
||||
typedef class nsRootAccessible nsRootAccessibleWrap;
|
||||
class nsRootAccessibleWrap : public nsRootAccessible
|
||||
{
|
||||
public:
|
||||
nsRootAccessibleWrap(nsIDocument* aDocument, nsIContent* aRootContent,
|
||||
nsIWeakReference* aShell);
|
||||
virtual ~nsRootAccessibleWrap();
|
||||
|
||||
// nsRootAccessible
|
||||
virtual void DocumentActivated(nsDocAccessible* aDocument);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Corporation.
|
||||
* Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
|
@ -40,8 +40,9 @@
|
|||
|
||||
#include "nsWinUtils.h"
|
||||
|
||||
#include "nsAccessibleWrap.h"
|
||||
#include "nsIWinAccessNode.h"
|
||||
#include "nsRootAccessible.h"
|
||||
|
||||
#include "nsArrayUtils.h"
|
||||
#include "nsIDocShellTreeItem.h"
|
||||
|
||||
|
@ -116,25 +117,41 @@ nsWinUtils::RegisterNativeWindow(LPCWSTR aWindowClass)
|
|||
}
|
||||
|
||||
HWND
|
||||
nsWinUtils::CreateNativeWindow(LPCWSTR aWindowClass, HWND aParentWnd)
|
||||
nsWinUtils::CreateNativeWindow(LPCWSTR aWindowClass, HWND aParentWnd,
|
||||
int aX, int aY, int aWidth, int aHeight,
|
||||
bool aIsActive)
|
||||
{
|
||||
return ::CreateWindowW(aWindowClass,
|
||||
L"NetscapeDispatchWnd",
|
||||
WS_CHILD | WS_VISIBLE,
|
||||
CW_USEDEFAULT, CW_USEDEFAULT,
|
||||
0, 0,
|
||||
aParentWnd,
|
||||
NULL,
|
||||
GetModuleHandle(NULL),
|
||||
NULL);
|
||||
return ::CreateWindowExW(WS_EX_TRANSPARENT, aWindowClass,
|
||||
L"NetscapeDispatchWnd",
|
||||
WS_CHILD | (aIsActive ? WS_VISIBLE : 0),
|
||||
aX, aY, aWidth, aHeight,
|
||||
aParentWnd,
|
||||
NULL,
|
||||
GetModuleHandle(NULL),
|
||||
NULL);
|
||||
}
|
||||
|
||||
void
|
||||
nsWinUtils::ShowNativeWindow(HWND aWnd)
|
||||
{
|
||||
::ShowWindow(aWnd, SW_SHOW);
|
||||
}
|
||||
|
||||
void
|
||||
nsWinUtils::HideNativeWindow(HWND aWnd)
|
||||
{
|
||||
::SetWindowPos(aWnd, NULL, 0, 0, 0, 0,
|
||||
SWP_HIDEWINDOW | SWP_NOSIZE | SWP_NOMOVE |
|
||||
SWP_NOZORDER | SWP_NOACTIVATE);
|
||||
}
|
||||
|
||||
bool
|
||||
nsWinUtils::IsWindowEmulationEnabled()
|
||||
nsWinUtils::IsWindowEmulationEnabled(LPCWSTR kModuleHandle)
|
||||
{
|
||||
return ::GetModuleHandleW(kJAWSModuleHandle) ||
|
||||
return kModuleHandle ? ::GetModuleHandleW(kModuleHandle) :
|
||||
::GetModuleHandleW(kJAWSModuleHandle) ||
|
||||
::GetModuleHandleW(kWEModuleHandle) ||
|
||||
::GetModuleHandleW(kDolphnModuleHandle);
|
||||
::GetModuleHandleW(kDolphinModuleHandle);
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Corporation.
|
||||
* Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
|
@ -51,7 +51,7 @@ const LPCWSTR kClassNameTabContent = L"MozillaContentWindowClass";
|
|||
|
||||
const LPCWSTR kJAWSModuleHandle = L"jhook";
|
||||
const LPCWSTR kWEModuleHandle = L"gwm32inc";
|
||||
const LPCWSTR kDolphnModuleHandle = L"dolwinhk";
|
||||
const LPCWSTR kDolphinModuleHandle = L"dolwinhk";
|
||||
|
||||
class nsWinUtils
|
||||
{
|
||||
|
@ -71,12 +71,24 @@ public:
|
|||
/**
|
||||
* Helper to create a window.
|
||||
*/
|
||||
static HWND CreateNativeWindow(LPCWSTR aWindowClass, HWND aParentWnd);
|
||||
static HWND CreateNativeWindow(LPCWSTR aWindowClass, HWND aParentWnd,
|
||||
int aX, int aY, int aWidth, int aHeight,
|
||||
bool aIsActive);
|
||||
|
||||
/**
|
||||
* Helper to show window.
|
||||
*/
|
||||
static void ShowNativeWindow(HWND aWnd);
|
||||
|
||||
/**
|
||||
* Helper to hide window.
|
||||
*/
|
||||
static void HideNativeWindow(HWND aWnd);
|
||||
|
||||
/**
|
||||
* Return true if window emulation is enabled.
|
||||
*/
|
||||
static bool IsWindowEmulationEnabled();
|
||||
static bool IsWindowEmulationEnabled(LPCWSTR kModuleHandle = 0);
|
||||
|
||||
/**
|
||||
* Return true if the given document node is for tab document accessible.
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Corporation.
|
||||
* Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Corporation.
|
||||
* Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Corporation.
|
||||
* Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Corporation.
|
||||
* Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Corporation.
|
||||
* Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Corporation.
|
||||
* Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
|
|
|
@ -100,12 +100,12 @@ _TEST_FILES =\
|
|||
test_keys.html \
|
||||
$(warning test_nsIAccessible_comboboxes.xul temporarily disabled) \
|
||||
test_nsIAccessible_selects.html \
|
||||
test_nsIAccessible_focus.html \
|
||||
test_nsIAccessibleDocument.html \
|
||||
test_nsIAccessibleImage.html \
|
||||
test_nsIAccessNode_utils.html \
|
||||
test_nsOuterDocAccessible.html \
|
||||
test_role_nsHyperTextAcc.html \
|
||||
test_takeFocus.html \
|
||||
test_text_caret.html \
|
||||
test_textboxes.html \
|
||||
test_textboxes.xul \
|
||||
|
|
|
@ -59,13 +59,14 @@ const EXT_STATE_VERTICAL = nsIAccessibleStates.EXT_STATE_VERTICAL;
|
|||
* @param aExtraState The extra state bits that are wanted.
|
||||
* @param aAbsentState State bits that are not wanted.
|
||||
* @param aAbsentExtraState Extra state bits that are not wanted.
|
||||
* @param aTestName The test name.
|
||||
*/
|
||||
function testStates(aAccOrElmOrID, aState, aExtraState, aAbsentState,
|
||||
aAbsentExtraState)
|
||||
aAbsentExtraState, aTestName)
|
||||
{
|
||||
var [state, extraState] = getStates(aAccOrElmOrID);
|
||||
|
||||
var id = prettyName(aAccOrElmOrID);
|
||||
var id = prettyName(aAccOrElmOrID) + (aTestName ? " [" + aTestName + "]": "");
|
||||
|
||||
// Primary test.
|
||||
isState(state & aState, aState, false,
|
||||
|
|
|
@ -45,15 +45,13 @@ relativesrcdir = accessible/states
|
|||
include $(DEPTH)/config/autoconf.mk
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
# temporarily disabled test (bug 562328)
|
||||
# test_frames.html \
|
||||
|
||||
_TEST_FILES =\
|
||||
test_aria.html \
|
||||
test_aria_imgmap.html \
|
||||
test_doc.html \
|
||||
test_docarticle.html \
|
||||
test_editablebody.html \
|
||||
test_frames.html \
|
||||
test_inputs.html \
|
||||
test_inputs.xul \
|
||||
test_link.html \
|
||||
|
@ -63,6 +61,7 @@ _TEST_FILES =\
|
|||
z_frames_article.html \
|
||||
z_frames_checkbox.html \
|
||||
z_frames_textbox.html \
|
||||
z_frames_update.html \
|
||||
$(NULL)
|
||||
|
||||
libs:: $(_TEST_FILES)
|
||||
|
|
|
@ -84,5 +84,6 @@
|
|||
|
||||
<div id="document" role="document">document</div>
|
||||
<div id="editable_document" role="document" contentEditable="true">editable document</doc>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -23,24 +23,31 @@
|
|||
frameDocArticle = document.getElementById("frame_doc_article").contentDocument;
|
||||
frameDocCheckbox = document.getElementById("frame_doc_checkbox").contentDocument;
|
||||
frameDocTextbox = document.getElementById("frame_doc_textbox").contentDocument;
|
||||
|
||||
testStates(frameDoc, STATE_READONLY);
|
||||
testStates(frameDocArticle, STATE_READONLY);
|
||||
testStates(frameDocCheckbox, 0, 0, STATE_READONLY);
|
||||
testStates(frameDocTextbox, 0, EXT_STATE_EDITABLE);
|
||||
|
||||
testStates(frameDoc, STATE_READONLY, 0, 0, 0, "test1: frameDoc");
|
||||
testStates(frameDocArticle, STATE_READONLY, 0, 0, 0, "test1: frameDocArticle");
|
||||
testStates(frameDocCheckbox, 0, 0, STATE_READONLY, 0, "test1: frameDocCheckbox");
|
||||
testStates(frameDocTextbox, 0, EXT_STATE_EDITABLE, 0, 0, "test1: frameDocTextbox");
|
||||
|
||||
frameDoc.designMode = "on";
|
||||
testStates(frameDoc, 0, EXT_STATE_EDITABLE);
|
||||
testStates(frameDocArticle, STATE_READONLY);
|
||||
testStates(frameDocCheckbox, 0, 0, STATE_READONLY);
|
||||
testStates(frameDocTextbox, 0, EXT_STATE_EDITABLE);
|
||||
testStates(frameDoc, 0, EXT_STATE_EDITABLE, 0, 0, "test2: frameDoc");
|
||||
testStates(frameDocArticle, STATE_READONLY, 0, 0, 0, "test2: frameDocArticle");
|
||||
testStates(frameDocCheckbox, 0, 0, STATE_READONLY, 0, "test2: frameDocCheckbox");
|
||||
testStates(frameDocTextbox, 0, EXT_STATE_EDITABLE, 0, 0, "test2: frameDocTextbox");
|
||||
|
||||
frameDocArticle.designMode = "on";
|
||||
testStates(frameDocArticle, 0, EXT_STATE_EDITABLE);
|
||||
testStates(frameDocArticle, 0, EXT_STATE_EDITABLE, 0, 0, "test3: frameDocArticle");
|
||||
|
||||
frameDocCheckbox.designMode = "on";
|
||||
testStates(frameDocCheckbox, 0, 0, STATE_READONLY);
|
||||
|
||||
testStates(frameDocCheckbox, 0, 0, STATE_READONLY, 0, "test4: frameDocCheckbox");
|
||||
|
||||
// Replace iframe document body before the document accessible tree is
|
||||
// created. Check the states are updated for new body.
|
||||
var frameUpdateDoc =
|
||||
document.getElementById("frame_updatedoc").contentDocument;
|
||||
testStates(frameUpdateDoc, 0, EXT_STATE_EDITABLE,
|
||||
STATE_READONLY, EXT_STATE_STALE, "test5: frameUpdateDoc");
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
|
@ -52,18 +59,24 @@
|
|||
<body>
|
||||
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=467387"
|
||||
title="Expose non-editable documents as readonly, regardless of role">
|
||||
Mozilla Bug 467387
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=467387"
|
||||
title="Expose non-editable documents as readonly, regardless of role">
|
||||
Mozilla Bug 467387
|
||||
</a>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=638106"
|
||||
title="CKEditor document should be editable">
|
||||
Mozilla Bug 638106
|
||||
</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
|
||||
|
||||
<iframe id="frame_doc" src="z_frames.html"></iframe>
|
||||
<iframe id="frame_doc_article" src="z_frames_article.html"></iframe>
|
||||
<iframe id="frame_doc_checkbox" src="z_frames_checkbox.html"></iframe>
|
||||
<iframe id="frame_doc_textbox" src="z_frames_textbox.html"></iframe>
|
||||
<iframe id="frame_updatedoc" src="z_frames_update.html"></iframe>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
<html>
|
||||
<head>
|
||||
<script>
|
||||
function replaceBody()
|
||||
{
|
||||
var accRetrieval = Components.classes["@mozilla.org/accessibleRetrieval;1"].
|
||||
getService(Components.interfaces.nsIAccessibleRetrieval);
|
||||
accRetrieval.getAccessibleFor(document);
|
||||
|
||||
var newBody = document.createElement("body");
|
||||
newBody.setAttribute("contentEditable", "true");
|
||||
newBody.textContent = "New Hello";
|
||||
document.documentElement.replaceChild(newBody, document.body);
|
||||
getComputedStyle(newBody, "").color;
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body onload="replaceBody();">
|
||||
OLD hello
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,144 +0,0 @@
|
|||
<html>
|
||||
|
||||
<head>
|
||||
<title>nsIAccessible::takeFocus testing</title>
|
||||
|
||||
<link rel="stylesheet" type="text/css"
|
||||
href="chrome://mochikit/content/tests/SimpleTest/test.css" />
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/MochiKit/packed.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="common.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="events.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Test
|
||||
|
||||
function doTest()
|
||||
{
|
||||
// focus ARIA link
|
||||
var ID = "aria-link";
|
||||
var linkAcc = getAccessible(ID);
|
||||
|
||||
gFocusManager.listenElement(linkAcc, ID, doTest2);
|
||||
linkAcc.takeFocus();
|
||||
}
|
||||
|
||||
function doTest2()
|
||||
{
|
||||
// focus first child of ARIA link
|
||||
var ID = "aria-link2";
|
||||
var linkAcc = getAccessible(ID);
|
||||
|
||||
gFocusManager.listenElement(linkAcc, ID, doTest3);
|
||||
linkAcc.firstChild.takeFocus();
|
||||
}
|
||||
|
||||
function doTest3()
|
||||
{
|
||||
// focus html:a
|
||||
var ID = "link";
|
||||
var linkAcc = getAccessible(ID);
|
||||
|
||||
gFocusManager.listenElement(linkAcc, ID, finishTest);
|
||||
linkAcc.takeFocus();
|
||||
}
|
||||
|
||||
function finishTest()
|
||||
{
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTest);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Helpers
|
||||
|
||||
var gFocusManager =
|
||||
{
|
||||
// Public
|
||||
listenElement: function listenElement(aAccOrID, aPrettyName, aCallback)
|
||||
{
|
||||
registerA11yEventListener(nsIAccessibleEvent.EVENT_FOCUS, this);
|
||||
|
||||
var elmObj = {};
|
||||
this.mAcc = getAccessible(aAccOrID, null, elmObj);
|
||||
this.mElm = elmObj.value;
|
||||
this.mName = aPrettyName ? aPrettyName : aAccOrID;
|
||||
this.mCallback = aCallback;
|
||||
|
||||
window.setTimeout(
|
||||
function(aFocusMgr)
|
||||
{
|
||||
aFocusMgr.checkWasFocusHandled();
|
||||
// Try to work around bug 573085 by using a timeout that's a lot
|
||||
// bigger than our refresh driver period.
|
||||
}, 100, this);
|
||||
},
|
||||
|
||||
// Private
|
||||
handleEvent: function handleEvent(aAccEvent)
|
||||
{
|
||||
var node = aAccEvent.DOMNode;
|
||||
if (node == this.mElm)
|
||||
this.mIsFocusHandled = true;
|
||||
},
|
||||
|
||||
checkWasFocusHandled: function checkWasFocusHandled()
|
||||
{
|
||||
window.setTimeout(
|
||||
function(aFocusMgr)
|
||||
{
|
||||
unregisterA11yEventListener(nsIAccessibleEvent.EVENT_FOCUS, this);
|
||||
|
||||
ok(aFocusMgr.mIsFocusHandled,
|
||||
"Focus wasn't received for element with ID " + aFocusMgr.mName + ".");
|
||||
|
||||
var states = {}, extraStates = {};
|
||||
aFocusMgr.mAcc.getState(states, extraStates);
|
||||
// XXX see bug 455840. Only fails on aria-link, the other two are OK.
|
||||
// When fixing this bug, remove the if statement and else block and "todo" statement.
|
||||
if (states.value & nsIAccessibleStates.STATE_FOCUSED)
|
||||
ok(states.value & nsIAccessibleStates.STATE_FOCUSED,
|
||||
"No focused state for element with ID " + aFocusMgr.mName + ".");
|
||||
else
|
||||
todo(states.value & nsIAccessibleStates.STATE_FOCUSED,
|
||||
"No focused state for element with ID " + aFocusMgr.mName + ".");
|
||||
|
||||
aFocusMgr.mCallback();
|
||||
}, 0, this);
|
||||
},
|
||||
|
||||
mAcc: null,
|
||||
mElm: null,
|
||||
mName: "",
|
||||
mIsFocusHandled: false
|
||||
};
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=452710"
|
||||
title="nsIAccessible::takeFocus testing">
|
||||
Mozilla Bug 452710
|
||||
</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
|
||||
<span id="aria-link" role="link" tabindex="0">link</span>
|
||||
<span id="aria-link2" role="link" tabindex="0">link</span>
|
||||
|
||||
<a id="link" href="">link</span>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,82 @@
|
|||
<html>
|
||||
|
||||
<head>
|
||||
<title>nsIAccessible::takeFocus testing</title>
|
||||
|
||||
<link rel="stylesheet" type="text/css"
|
||||
href="chrome://mochikit/content/tests/SimpleTest/test.css" />
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/MochiKit/packed.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="common.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="states.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="events.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Test
|
||||
|
||||
var gQueue = null;
|
||||
|
||||
function takeFocusInvoker(aID)
|
||||
{
|
||||
this.accessible = getAccessible(aID);
|
||||
|
||||
this.eventSeq = [ new invokerChecker(EVENT_FOCUS, this.accessible) ];
|
||||
|
||||
this.invoke = function takeFocusInvoker_invoke()
|
||||
{
|
||||
this.accessible.takeFocus();
|
||||
}
|
||||
|
||||
this.finalCheck = function takeFocusInvoker()
|
||||
{
|
||||
testStates(this.accessible, STATE_FOCUSED);
|
||||
}
|
||||
|
||||
this.getID = function takeFocusInvoker_getID()
|
||||
{
|
||||
return "takeFocus for " + prettyName(aID);
|
||||
}
|
||||
}
|
||||
|
||||
function doTest()
|
||||
{
|
||||
gQueue = new eventQueue();
|
||||
|
||||
gQueue.push(new takeFocusInvoker("aria-link"));
|
||||
gQueue.push(new takeFocusInvoker("aria-link2"));
|
||||
gQueue.push(new takeFocusInvoker("link"));
|
||||
|
||||
gQueue.invoke(); // Will call SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTest);
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=452710"
|
||||
title="nsIAccessible::takeFocus testing">
|
||||
Mozilla Bug 452710
|
||||
</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
|
||||
<span id="aria-link" role="link" tabindex="0">link</span>
|
||||
<span id="aria-link2" role="link" tabindex="0">link</span>
|
||||
|
||||
<a id="link" href="">link</span>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -26,6 +26,14 @@ function testCharacterCount(aIDs, aCount)
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test text between two given offsets
|
||||
*
|
||||
* @param aIDs [in] an array of accessible IDs to test
|
||||
* @param aStartOffset [in] the start offset within the text to test
|
||||
* @param aEndOffset [in] the end offset up to which the text is tested
|
||||
* @param aText [in] the expected result from the test
|
||||
*/
|
||||
function testText(aIDs, aStartOffset, aEndOffset, aText)
|
||||
{
|
||||
for (var i = 0; i < aIDs.length; i++)
|
||||
|
@ -43,6 +51,34 @@ function testText(aIDs, aStartOffset, aEndOffset, aText)
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test password text between two given offsets
|
||||
*
|
||||
* @param aIDs [in] an array of accessible IDs to test
|
||||
* @param aStartOffset [in] the start offset within the text to test
|
||||
* @param aEndOffset [in] the end offset up to which the text is tested
|
||||
* @param aText [in] the expected result from the test
|
||||
*
|
||||
* @note All this function does is test that getText doe snot expose the
|
||||
* password text itself, but something else.
|
||||
*/
|
||||
function testPasswordText(aIDs, aStartOffset, aEndOffset, aText)
|
||||
{
|
||||
for (var i = 0; i < aIDs.length; i++)
|
||||
{
|
||||
var acc = getAccessible(aIDs[i], nsIAccessibleText);
|
||||
try {
|
||||
isnot(acc.getText(aStartOffset, aEndOffset), aText,
|
||||
"getText: plain text between start and end offsets '" + aStartOffset +
|
||||
"', '" + aEndOffset + " for '" + prettyName(aIDs[i]) + "'");
|
||||
} catch (e) {
|
||||
ok(false,
|
||||
"getText fails between start and end offsets '" + aStartOffset +
|
||||
"', '" + aEndOffset + " for '" + prettyName(aIDs[i]) + "'");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test getTextAtOffset for BOUNDARY_CHAR over different elements.
|
||||
*
|
||||
|
|
|
@ -49,6 +49,7 @@ _TEST_FILES = \
|
|||
doc.html \
|
||||
test_doc.html \
|
||||
test_hypertext.html \
|
||||
test_passwords.html \
|
||||
test_singleline.html \
|
||||
test_whitespaces.html \
|
||||
test_words.html \
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>nsIAccessibleText getText related function tests for text and password inputs</title>
|
||||
<link rel="stylesheet" type="text/css"
|
||||
href="chrome://mochikit/content/tests/SimpleTest/test.css" />
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/MochiKit/packed.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="../common.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="../text.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
function doTest()
|
||||
{
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// regular text and password inputs
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// characterCount and getText for regular text field
|
||||
|
||||
var IDs = [ "username" ];
|
||||
testCharacterCount(IDs, 4);
|
||||
testText(IDs, 0, 4, "test");
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// characterCount and getText for password field
|
||||
|
||||
IDs = [ "password" ];
|
||||
testCharacterCount(IDs, 4);
|
||||
testPasswordText(IDs, 0, 4, "test");
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTest);
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<a target="_blank"
|
||||
title="mochitest for getText for password fields"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=415943">Mozilla Bug 415943</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
|
||||
<form action="post.php" method="post">
|
||||
<label for="username">User name:</label>
|
||||
<input id="username" value="test"><br />
|
||||
<label for="password">Password:</label>
|
||||
<input type="password" id="password" value="test"/>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
|
@ -6,7 +6,7 @@
|
|||
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
title="Accessible XUL menulist and textbox @autocomplete hierarchy tests">
|
||||
|
||||
<script type="application/javascript"
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/MochiKit/packed.js" />
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
|
||||
|
@ -33,15 +33,18 @@
|
|||
role: ROLE_COMBOBOX_LIST,
|
||||
children: [
|
||||
{
|
||||
role: ROLE_COMBOBOX_OPTION
|
||||
role: ROLE_COMBOBOX_OPTION,
|
||||
children: []
|
||||
},
|
||||
{
|
||||
role: ROLE_COMBOBOX_OPTION
|
||||
role: ROLE_COMBOBOX_OPTION,
|
||||
children: []
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
testAccessibleTree("menulist", accTree);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
@ -52,7 +55,9 @@
|
|||
children: [
|
||||
{
|
||||
role: ROLE_ENTRY,
|
||||
children: [ ] // no text leaf accessible for text node
|
||||
children: [
|
||||
// no text leaf accessible for text node
|
||||
]
|
||||
},
|
||||
{
|
||||
role: ROLE_COMBOBOX_LIST, // context menu
|
||||
|
@ -60,15 +65,18 @@
|
|||
},
|
||||
{
|
||||
role: ROLE_PUSHBUTTON, // dropmarker
|
||||
children: []
|
||||
},
|
||||
{
|
||||
role: ROLE_COMBOBOX_LIST, // option list
|
||||
children: [
|
||||
{
|
||||
role: ROLE_COMBOBOX_OPTION
|
||||
role: ROLE_COMBOBOX_OPTION,
|
||||
children: []
|
||||
},
|
||||
{
|
||||
role: ROLE_COMBOBOX_OPTION
|
||||
role: ROLE_COMBOBOX_OPTION,
|
||||
children: []
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -84,49 +92,138 @@
|
|||
// textbox@type=autocomplete #1 (history)
|
||||
|
||||
accTree = {
|
||||
// textbox
|
||||
role: ROLE_AUTOCOMPLETE,
|
||||
children: [
|
||||
{
|
||||
// html:input
|
||||
role: ROLE_ENTRY,
|
||||
children: [
|
||||
{
|
||||
// #text
|
||||
role: ROLE_TEXT_LEAF,
|
||||
name: "http://mochi.test:8888/redirect-a11y.html"
|
||||
name: "http://mochi.test:8888/redirect-a11y.html",
|
||||
children: []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
// xul:menupopup
|
||||
role: ROLE_COMBOBOX_LIST, // context menu popup
|
||||
children: [ ]
|
||||
children: []
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
// XPFE and Toolkit autocomplete widgets differ.
|
||||
var ac1h = document.getElementById("autocomplete");
|
||||
if ("clearResults" in ac1h) {
|
||||
SimpleTest.ok(true, "Testing (Old) XPFE autocomplete widget. (ac1h)");
|
||||
|
||||
// Popup is always created.
|
||||
accTree.children.push(
|
||||
{
|
||||
// xul:panel
|
||||
role: ROLE_COMBOBOX_LIST,
|
||||
children: [
|
||||
{
|
||||
// xul:tree
|
||||
role: ROLE_TABLE,
|
||||
children: [
|
||||
{
|
||||
// xul:treecols
|
||||
role: ROLE_LIST,
|
||||
children: [
|
||||
{
|
||||
// xul:treecol
|
||||
role: ROLE_COLUMNHEADER,
|
||||
children: []
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
);
|
||||
} else {
|
||||
SimpleTest.ok(true, "Testing (New) Toolkit autocomplete widget. (ac1h)");
|
||||
|
||||
// Popup is lazily created, so not present in this case.
|
||||
}
|
||||
|
||||
testAccessibleTree("autocomplete", accTree);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// textbox@type=autocomplete #2 (child menupoup)
|
||||
|
||||
accTree = {
|
||||
// textbox
|
||||
role: ROLE_AUTOCOMPLETE,
|
||||
children: [
|
||||
{
|
||||
// menupopup
|
||||
role: ROLE_COMBOBOX_LIST, // autocomplete menu popup
|
||||
children: [
|
||||
{
|
||||
role: ROLE_COMBOBOX_OPTION
|
||||
// menuitem
|
||||
role: ROLE_COMBOBOX_OPTION,
|
||||
children: []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
// html:input
|
||||
role: ROLE_ENTRY,
|
||||
children: [ ] // no text leaf accessible for text node
|
||||
children: [
|
||||
// no text leaf accessible for text node
|
||||
]
|
||||
},
|
||||
{
|
||||
// xul:menupopup
|
||||
role: ROLE_COMBOBOX_LIST, // context menu popup
|
||||
children: [ ]
|
||||
children: []
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
// XPFE and Toolkit autocomplete widgets differ.
|
||||
var ac2cmp = document.getElementById("autocomplete2");
|
||||
if ("clearResults" in ac2cmp) {
|
||||
SimpleTest.ok(true, "Testing (Old) XPFE autocomplete widget. (ac2mp)");
|
||||
|
||||
// Popup is always created.
|
||||
accTree.children.push(
|
||||
{
|
||||
// xul:panel
|
||||
role: ROLE_COMBOBOX_LIST,
|
||||
children: [
|
||||
{
|
||||
// xul:tree
|
||||
role: ROLE_TABLE,
|
||||
children: [
|
||||
{
|
||||
// xul:treecols
|
||||
role: ROLE_LIST,
|
||||
children: [
|
||||
{
|
||||
// xul:treecol
|
||||
role: ROLE_COLUMNHEADER,
|
||||
children: []
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
);
|
||||
} else {
|
||||
SimpleTest.ok(true, "Testing (New) Toolkit autocomplete widget. (ac2mp)");
|
||||
|
||||
// Popup is lazily created, so not present in this case.
|
||||
}
|
||||
|
||||
testAccessibleTree("autocomplete2", accTree);
|
||||
|
||||
SimpleTest.finish()
|
||||
|
@ -184,4 +281,3 @@
|
|||
</hbox>
|
||||
|
||||
</window>
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
title="Accessible XUL tabbrowser hierarchy tests">
|
||||
|
||||
<script type="application/javascript"
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/MochiKit/packed.js" />
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
|
||||
|
@ -36,8 +36,7 @@
|
|||
var handleDroppedLink = null;
|
||||
var XULBrowserWindow = {
|
||||
isBusy: false,
|
||||
setOverLink: function (link, b) {
|
||||
}
|
||||
setOverLink: function (link, b) {}
|
||||
};
|
||||
var gFindBar = {
|
||||
hidden: true
|
||||
|
@ -53,60 +52,159 @@
|
|||
aRequest,
|
||||
aStateFlags,
|
||||
aStatus)
|
||||
{
|
||||
if (aStateFlags & Ci.nsIWebProgressListener.STATE_STOP)
|
||||
testAccTree();
|
||||
}
|
||||
};
|
||||
{
|
||||
if (aStateFlags & Ci.nsIWebProgressListener.STATE_STOP) {
|
||||
tabBrowser.removeProgressListener(progressListener);
|
||||
|
||||
SimpleTest.executeSoon(testAccTree);
|
||||
}
|
||||
}
|
||||
};
|
||||
tabBrowser.addProgressListener(progressListener,
|
||||
Ci.nsIWebProgress.NOTIFY_STATE_WINDOW);
|
||||
|
||||
// Test XUL and HTML documents.
|
||||
tabBrowser.loadTabs(["about:", "about:mozilla"], false, true);
|
||||
}
|
||||
|
||||
function testAccTree()
|
||||
{
|
||||
var tabBrowser = document.getElementById("tabbrowser");
|
||||
|
||||
////////////////////
|
||||
// Tab bar
|
||||
////////////////////
|
||||
var tabsAccTree = {
|
||||
// xul:tabs
|
||||
role: ROLE_PAGETABLIST,
|
||||
children: [
|
||||
{
|
||||
role: ROLE_PAGETAB,
|
||||
children: [
|
||||
{
|
||||
role: ROLE_PUSHBUTTON
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
role: ROLE_PAGETAB,
|
||||
children: [
|
||||
{
|
||||
role: ROLE_PUSHBUTTON
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
role: ROLE_PUSHBUTTON
|
||||
}
|
||||
// Children depend on application (UI): see below.
|
||||
]
|
||||
};
|
||||
testAccessibleTree(getNode("tabbrowser").tabContainer, tabsAccTree);
|
||||
|
||||
// SeaMonkey and Firefox tabbrowser UIs differ.
|
||||
if ("restoreTab" in tabBrowser) {
|
||||
SimpleTest.ok(true, "Testing SeaMonkey tabbrowser UI.");
|
||||
|
||||
tabsAccTree.children.splice(0, 0,
|
||||
{
|
||||
// xul:toolbarbutton ("Open a new tab")
|
||||
role: ROLE_PUSHBUTTON,
|
||||
children: []
|
||||
},
|
||||
{
|
||||
// xul:tab ("about:")
|
||||
role: ROLE_PAGETAB,
|
||||
children: []
|
||||
},
|
||||
{
|
||||
// tab ("about:mozilla")
|
||||
role: ROLE_PAGETAB,
|
||||
children: []
|
||||
},
|
||||
{
|
||||
// xul:toolbarbutton ("List all tabs")
|
||||
role: ROLE_PUSHBUTTON,
|
||||
children: [
|
||||
{
|
||||
// xul:menupopup
|
||||
role: ROLE_MENUPOPUP,
|
||||
children: []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
// xul:toolbarbutton ("Close current tab")
|
||||
role: ROLE_PUSHBUTTON,
|
||||
children: []
|
||||
}
|
||||
);
|
||||
} else {
|
||||
SimpleTest.ok(true, "Testing Firefox tabbrowser UI.");
|
||||
|
||||
// NB: The (3) buttons are not visible, unless manually hovered,
|
||||
// probably due to size reduction in this test.
|
||||
tabsAccTree.children.splice(0, 0,
|
||||
{
|
||||
// xul:tab ("about:")
|
||||
role: ROLE_PAGETAB,
|
||||
children: [
|
||||
{
|
||||
// xul:toolbarbutton ("Close Tab")
|
||||
role: ROLE_PUSHBUTTON,
|
||||
children: []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
// tab ("about:mozilla")
|
||||
role: ROLE_PAGETAB,
|
||||
children: [
|
||||
{
|
||||
// xul:toolbarbutton ("Close Tab")
|
||||
role: ROLE_PUSHBUTTON,
|
||||
children: []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
// xul:toolbarbutton ("Open a new tab")
|
||||
role: ROLE_PUSHBUTTON,
|
||||
children: []
|
||||
}
|
||||
// "List all tabs" dropdown
|
||||
// XXX: This child(?) is not present in this test.
|
||||
// I'm not sure why (though probably expected).
|
||||
);
|
||||
}
|
||||
|
||||
testAccessibleTree(tabBrowser.tabContainer, tabsAccTree);
|
||||
|
||||
////////////////////
|
||||
// Tab contents
|
||||
////////////////////
|
||||
var tabboxAccTree = {
|
||||
// xul:tabpanels
|
||||
role: ROLE_PANE,
|
||||
children: [
|
||||
{
|
||||
role: ROLE_PROPERTYPAGE
|
||||
// xul:notificationbox
|
||||
role: ROLE_PROPERTYPAGE,
|
||||
children: [
|
||||
{
|
||||
// xul:browser
|
||||
role: ROLE_INTERNAL_FRAME,
|
||||
children: [
|
||||
{
|
||||
// #document ("about:")
|
||||
role: ROLE_DOCUMENT
|
||||
// children: [ ... ] // Ignore document content.
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
role: ROLE_PROPERTYPAGE
|
||||
// notificationbox
|
||||
role: ROLE_PROPERTYPAGE,
|
||||
children: [
|
||||
{
|
||||
// browser
|
||||
role: ROLE_INTERNAL_FRAME,
|
||||
children: [
|
||||
{
|
||||
// #document ("about:mozilla")
|
||||
role: ROLE_DOCUMENT
|
||||
// children: [ ... ] // Ignore document content.
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
testAccessibleTree(getNode("tabbrowser").mTabBox.tabpanels,
|
||||
tabboxAccTree);
|
||||
testAccessibleTree(tabBrowser.mTabBox.tabpanels, tabboxAccTree);
|
||||
|
||||
SimpleTest.finish()
|
||||
}
|
||||
|
@ -158,4 +256,3 @@
|
|||
</vbox>
|
||||
|
||||
</window>
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
title="Accessible XUL textbox and textarea hierarchy tests">
|
||||
|
||||
<script type="application/javascript"
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/MochiKit/packed.js" />
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
|
||||
|
@ -23,7 +23,9 @@
|
|||
|
||||
function doTest()
|
||||
{
|
||||
////////////////////
|
||||
// textbox
|
||||
////////////////////
|
||||
var accTree = {
|
||||
role: ROLE_ENTRY,
|
||||
children: [
|
||||
|
@ -33,6 +35,8 @@
|
|||
}
|
||||
]
|
||||
};
|
||||
|
||||
// default textbox
|
||||
testAccessibleTree("txc1", accTree);
|
||||
|
||||
// number textbox
|
||||
|
@ -42,9 +46,11 @@
|
|||
testAccessibleTree("txc3", accTree);
|
||||
|
||||
// timed textbox
|
||||
testAccessibleTree("txc4", accTree);
|
||||
testAccessibleTree("txc4_deprecated", accTree);
|
||||
|
||||
////////////////////
|
||||
// password textbox
|
||||
////////////////////
|
||||
accTree = {
|
||||
role: ROLE_PASSWORD_TEXT,
|
||||
children: [
|
||||
|
@ -57,7 +63,9 @@
|
|||
|
||||
testAccessibleTree("txc5", accTree);
|
||||
|
||||
////////////////////
|
||||
// multiline textbox
|
||||
////////////////////
|
||||
accTree = {
|
||||
role: ROLE_ENTRY,
|
||||
children: [
|
||||
|
@ -74,29 +82,96 @@
|
|||
|
||||
testAccessibleTree("txc6", accTree);
|
||||
|
||||
////////////////////
|
||||
// autocomplete textbox
|
||||
////////////////////
|
||||
accTree = {
|
||||
// textbox
|
||||
role: ROLE_AUTOCOMPLETE,
|
||||
children: [
|
||||
{
|
||||
// html:input
|
||||
role: ROLE_ENTRY,
|
||||
children: [
|
||||
{
|
||||
// #text
|
||||
role: ROLE_TEXT_LEAF,
|
||||
children: []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
// xul:menupopup
|
||||
role: ROLE_COMBOBOX_LIST,
|
||||
children: []
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
testAccessibleTree("txc7", accTree);
|
||||
// XPFE and Toolkit autocomplete widgets differ.
|
||||
var txc7 = document.getElementById("txc7");
|
||||
if ("clearResults" in txc7) {
|
||||
SimpleTest.ok(true, "Testing (Old) XPFE autocomplete widget.");
|
||||
|
||||
SimpleTest.finish();
|
||||
// Popup is always created. (See code below.)
|
||||
|
||||
accTree.children.push(
|
||||
{
|
||||
// xul:panel
|
||||
role: ROLE_COMBOBOX_LIST,
|
||||
children: [
|
||||
{
|
||||
// xul:tree
|
||||
role: ROLE_TABLE,
|
||||
children: [
|
||||
{
|
||||
// xul:treecols
|
||||
role: ROLE_LIST,
|
||||
children: [
|
||||
{
|
||||
// xul:treecol
|
||||
role: ROLE_COLUMNHEADER,
|
||||
children: []
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
);
|
||||
} else {
|
||||
SimpleTest.ok(true, "Testing (New) Toolkit autocomplete widget.");
|
||||
|
||||
// Dumb access to trigger popup lazy creation. (See code below.)
|
||||
txc7.popup;
|
||||
|
||||
accTree.children.push(
|
||||
{
|
||||
role: ROLE_LIST,
|
||||
children: [
|
||||
{
|
||||
role: ROLE_LIST,
|
||||
children: [
|
||||
{
|
||||
role: ROLE_COLUMNHEADER,
|
||||
children: []
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// Delay txc7 test a bit, to let Toolkit popup lazy creation complete.
|
||||
function test_txc7() {
|
||||
testAccessibleTree("txc7", accTree);
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
// SimpleTest.executeSoon() doesn't help here: use setTimeout() with a little delay.
|
||||
setTimeout(test_txc7, 25);
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
@ -122,7 +197,9 @@
|
|||
<textbox id="txc1" value="hello"/>
|
||||
<textbox id="txc2" type="number" value="44"/>
|
||||
<textbox id="txc3" type="search" value="hello"/>
|
||||
<textbox id="txc4" type="timed" value="hello"/>
|
||||
<!-- This textbox triggers "Warning: Timed textboxes are deprecated. Consider using type="search" instead.".
|
||||
Yet let's test it too as long as it's (still) supported. -->
|
||||
<textbox id="txc4_deprecated" type="timed" value="hello"/>
|
||||
<textbox id="txc5" type="password" value="hello"/>
|
||||
<textbox id="txc6" multiline="true" value="hello"/>
|
||||
<textbox id="txc7" type="autocomplete" value="hello"/>
|
||||
|
@ -130,4 +207,3 @@
|
|||
</hbox>
|
||||
|
||||
</window>
|
||||
|
||||
|
|
|
@ -3653,13 +3653,10 @@ function retrieveToolbarIconsizesFromTheme() {
|
|||
// toolbar. A custom property cannot be used because getComputedStyle can
|
||||
// only return the values of standard CSS properties.
|
||||
let counterReset = getComputedStyle(aToolbar).counterReset;
|
||||
if (counterReset == "smallicons 0") {
|
||||
if (counterReset == "smallicons 0")
|
||||
aToolbar.setAttribute("iconsize", "small");
|
||||
document.persist(aToolbar.id, "iconsize");
|
||||
} else if (counterReset == "largeicons 0") {
|
||||
else if (counterReset == "largeicons 0")
|
||||
aToolbar.setAttribute("iconsize", "large");
|
||||
document.persist(aToolbar.id, "iconsize");
|
||||
}
|
||||
}
|
||||
|
||||
Array.forEach(gNavToolbox.childNodes, retrieveToolbarIconsize);
|
||||
|
|
|
@ -3750,11 +3750,23 @@
|
|||
</xul:hbox>
|
||||
</content>
|
||||
|
||||
<implementation>
|
||||
<implementation implements="nsIDOMEventListener">
|
||||
<constructor><![CDATA[
|
||||
window.addEventListener("findbaropen", this, false);
|
||||
]]></constructor>
|
||||
|
||||
<destructor><![CDATA[
|
||||
window.removeEventListener("findbaropen", this, false);
|
||||
]]></destructor>
|
||||
|
||||
<property name="label">
|
||||
<setter><![CDATA[
|
||||
if (!this.label)
|
||||
this.removeAttribute("mirror");
|
||||
if (!this.label) {
|
||||
if (window.gFindBarInitialized && !window.gFindBar.hidden)
|
||||
this.setAttribute("mirror", "true");
|
||||
else
|
||||
this.removeAttribute("mirror");
|
||||
}
|
||||
|
||||
this.style.minWidth = this.getAttribute("type") == "status" &&
|
||||
this.getAttribute("previoustype") == "status"
|
||||
|
@ -3768,6 +3780,15 @@
|
|||
</getter>
|
||||
</property>
|
||||
|
||||
<method name="handleEvent">
|
||||
<parameter name="event"/>
|
||||
<body><![CDATA[
|
||||
if (event.type == "findbaropen" &&
|
||||
this.label)
|
||||
this.setAttribute("mirror", "true");
|
||||
]]></body>
|
||||
</method>
|
||||
|
||||
<method name="_mirror">
|
||||
<body>
|
||||
if (this.hasAttribute("mirror"))
|
||||
|
|
|
@ -705,6 +705,88 @@ 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];
|
||||
|
@ -724,48 +806,8 @@ function test_cancel_restart() {
|
|||
let button = document.getAnonymousElementByAttribute(notification, "anonid", "cancel");
|
||||
|
||||
// Cancel the download
|
||||
info("Cancelling download");
|
||||
EventUtils.synthesizeMouse(button, 2, 2, {});
|
||||
|
||||
// Downloads cannot be restarted synchronously, bug 611755
|
||||
executeSoon(function() {
|
||||
// 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;
|
||||
|
|
|
@ -184,16 +184,23 @@ function test() {
|
|||
waitForExplicitFinish();
|
||||
|
||||
gTestWin = openDialog(location, "", "chrome,all,dialog=no", "about:blank");
|
||||
gTestWin.addEventListener("load", function (event) {
|
||||
info("Window loaded.");
|
||||
gTestWin.removeEventListener("load", arguments.callee, false);
|
||||
Services.obs.addObserver(function(aSubject, aTopic, aData) {
|
||||
if (aSubject != gTestWin)
|
||||
return;
|
||||
|
||||
Services.obs.removeObserver(arguments.callee, "browser-delayed-startup-finished");
|
||||
|
||||
info("Browser window opened");
|
||||
waitForFocus(function() {
|
||||
info("Setting up browser...");
|
||||
setupTestBrowserWindow();
|
||||
info("Running tests...");
|
||||
executeSoon(runNextTest);
|
||||
}, gTestWin.content, true);
|
||||
}, false);
|
||||
info("Browser window focused");
|
||||
waitForFocus(function() {
|
||||
info("Setting up browser...");
|
||||
setupTestBrowserWindow();
|
||||
info("Running tests...");
|
||||
executeSoon(runNextTest);
|
||||
}, gTestWin.content, true);
|
||||
}, gTestWin);
|
||||
}, "browser-delayed-startup-finished", false);
|
||||
}
|
||||
|
||||
// Click handler used to steal click events.
|
||||
|
|
|
@ -283,7 +283,7 @@ function setupHistory() {
|
|||
let today = new Date();
|
||||
today.setHours(0);
|
||||
today.setMinutes(0);
|
||||
today.setSeconds(30);
|
||||
today.setSeconds(1);
|
||||
bhist.addPageWithDetails(makeURI("http://today.com/"), "Today", today.valueOf() * 1000);
|
||||
|
||||
let lastYear = new Date();
|
||||
|
@ -526,7 +526,7 @@ function setupDownloads() {
|
|||
let today = new Date();
|
||||
today.setHours(0);
|
||||
today.setMinutes(0);
|
||||
today.setSeconds(30);
|
||||
today.setSeconds(1);
|
||||
|
||||
data = {
|
||||
id: "5555554",
|
||||
|
|
|
@ -1085,7 +1085,17 @@
|
|||
</xul:menu>
|
||||
</content>
|
||||
|
||||
<implementation>
|
||||
<implementation implements="nsIDOMEventListener">
|
||||
<constructor><![CDATA[
|
||||
this._parentMenupopup.addEventListener("DOMMenuItemActive", this, false);
|
||||
this._parentMenupopup.addEventListener("popuphidden", this, false);
|
||||
]]></constructor>
|
||||
|
||||
<destructor><![CDATA[
|
||||
this._parentMenupopup.removeEventListener("DOMMenuItemActive", this, false);
|
||||
this._parentMenupopup.removeEventListener("popuphidden", this, false);
|
||||
]]></destructor>
|
||||
|
||||
<field name="menuitem" readonly="true">
|
||||
document.getAnonymousElementByAttribute(this, "anonid", "menuitem");
|
||||
</field>
|
||||
|
@ -1096,14 +1106,39 @@
|
|||
<field name="_menuDelay">600</field>
|
||||
|
||||
<field name="_parentMenupopup"><![CDATA[
|
||||
let node = this.parentNode;
|
||||
while (node) {
|
||||
if (node.localName == "menupopup")
|
||||
break;
|
||||
node = node.parentNode;
|
||||
}
|
||||
node;
|
||||
this._getParentMenupopup(this);
|
||||
]]></field>
|
||||
|
||||
<method name="_getParentMenupopup">
|
||||
<parameter name="aNode"/>
|
||||
<body><![CDATA[
|
||||
let node = aNode.parentNode;
|
||||
while (node) {
|
||||
if (node.localName == "menupopup")
|
||||
break;
|
||||
node = node.parentNode;
|
||||
}
|
||||
return node;
|
||||
]]></body>
|
||||
</method>
|
||||
|
||||
<method name="handleEvent">
|
||||
<parameter name="event"/>
|
||||
<body><![CDATA[
|
||||
switch (event.type) {
|
||||
case "DOMMenuItemActive":
|
||||
if (this.getAttribute("active") == "true" &&
|
||||
event.target != this &&
|
||||
this._getParentMenupopup(event.target) == this._parentMenupopup)
|
||||
this.removeAttribute("active");
|
||||
break;
|
||||
case "popuphidden":
|
||||
if (event.target == this._parentMenupopup)
|
||||
this.removeAttribute("active");
|
||||
break;
|
||||
}
|
||||
]]></body>
|
||||
</method>
|
||||
</implementation>
|
||||
|
||||
<handlers>
|
||||
|
@ -1112,6 +1147,10 @@
|
|||
this.getAttribute("disabled") != "true") {
|
||||
this.setAttribute("active", "true");
|
||||
|
||||
let event = document.createEvent("Events");
|
||||
event.initEvent("DOMMenuItemActive", true, false);
|
||||
this.dispatchEvent(event);
|
||||
|
||||
let self = this;
|
||||
setTimeout(function () {
|
||||
if (self.getAttribute("active") == "true")
|
||||
|
@ -1120,24 +1159,6 @@
|
|||
}
|
||||
]]></handler>
|
||||
|
||||
<handler event="mouseout"><![CDATA[
|
||||
if (this.menu.open)
|
||||
return;
|
||||
|
||||
let node = event.relatedTarget;
|
||||
while (node) {
|
||||
if (node == this)
|
||||
return;
|
||||
node = node.parentNode;
|
||||
}
|
||||
this.removeAttribute("active");
|
||||
]]></handler>
|
||||
|
||||
<handler event="popuphidden"><![CDATA[
|
||||
if (event.target == this.firstChild)
|
||||
this.removeAttribute("active");
|
||||
]]></handler>
|
||||
|
||||
<handler event="popupshowing"><![CDATA[
|
||||
if (event.target == this.firstChild &&
|
||||
this._parentMenupopup._currentPopup)
|
||||
|
@ -1145,6 +1166,12 @@
|
|||
]]></handler>
|
||||
|
||||
<handler event="click" phase="capturing"><![CDATA[
|
||||
if (this.getAttribute("disabled") == "true") {
|
||||
// Prevent the command from being carried out
|
||||
event.stopPropagation();
|
||||
return;
|
||||
}
|
||||
|
||||
let node = event.originalTarget;
|
||||
while (true) {
|
||||
if (node == this.menuitem)
|
||||
|
|
|
@ -200,6 +200,7 @@ gTests.push({
|
|||
itemType: null,
|
||||
window: null,
|
||||
_itemId: null,
|
||||
_cleanShutdown: false,
|
||||
|
||||
setup: function() {
|
||||
// Add a bookmark in unsorted bookmarks folder.
|
||||
|
@ -222,31 +223,27 @@ gTests.push({
|
|||
var tagsField = this.window.document.getElementById("editBMPanel_tagsField");
|
||||
var self = this;
|
||||
|
||||
function windowObserver(aSubject, aTopic, aData) {
|
||||
if (aTopic == "domwindowclosed" &&
|
||||
aSubject.QueryInterface(Ci.nsIDOMWindow).location == DIALOG_URL) {
|
||||
ww.unregisterNotification(windowObserver);
|
||||
tagsField.popup.removeEventListener("popuphidden", popupListener, true);
|
||||
ok(false, "Dialog window should not be closed by pressing Enter on the autocomplete popup");
|
||||
this.window.addEventListener("unload", function(event) {
|
||||
self.window.removeEventListener("unload", arguments.callee, true);
|
||||
tagsField.popup.removeEventListener("popuphidden", popupListener, true);
|
||||
ok(self._cleanShutdown, "Dialog window should not be closed by pressing Enter on the autocomplete popup");
|
||||
executeSoon(function () {
|
||||
self.finish();
|
||||
}
|
||||
}
|
||||
});
|
||||
}, true);
|
||||
|
||||
var popupListener = {
|
||||
handleEvent: function(aEvent) {
|
||||
switch (aEvent.type) {
|
||||
case "popuphidden":
|
||||
// Everything worked fine, we can stop observing the window.
|
||||
ww.unregisterNotification(windowObserver);
|
||||
tagsField.popup.removeEventListener("popuphidden", this, true);
|
||||
self._cleanShutdown = true;
|
||||
self.window.document.documentElement.cancelDialog();
|
||||
self.finish();
|
||||
break;
|
||||
case "popupshown":
|
||||
tagsField.popup.removeEventListener("popupshown", this, true);
|
||||
// In case this test fails the window will close, we should mark the
|
||||
// failure and continue, to avoid timing out.
|
||||
ww.registerNotification(windowObserver);
|
||||
// In case this test fails the window will close, the test will fail
|
||||
// since we didn't set _cleanShutdown.
|
||||
var tree = tagsField.popup.tree;
|
||||
// Focus and select first result.
|
||||
isnot(tree, null, "Autocomplete results tree exists");
|
||||
|
@ -318,12 +315,14 @@ gTests.push({
|
|||
var namePicker = this.window.document.getElementById("editBMPanel_namePicker");
|
||||
var userEnteredName = this.window.document.getElementById("editBMPanel_userEnteredName");
|
||||
var self = this;
|
||||
|
||||
this.window.addEventListener("unload", function(event) {
|
||||
this.window.removeEventListener("unload", arguments.callee, false);
|
||||
executeSoon(function() {
|
||||
self.finish();
|
||||
});
|
||||
}, false);
|
||||
self.window.removeEventListener("unload", arguments.callee, false);
|
||||
executeSoon(function () {
|
||||
self.finish();
|
||||
});
|
||||
}, false);
|
||||
|
||||
namePicker.value = "n";
|
||||
userEnteredName.label = "n";
|
||||
info("About to focus the namePicker field");
|
||||
|
@ -357,6 +356,7 @@ gTests.push({
|
|||
itemType: null,
|
||||
window: null,
|
||||
_itemId: null,
|
||||
_cleanShutdown: false,
|
||||
|
||||
setup: function() {
|
||||
// Add a bookmark in unsorted bookmarks folder.
|
||||
|
@ -379,31 +379,27 @@ gTests.push({
|
|||
var tagsField = this.window.document.getElementById("editBMPanel_tagsField");
|
||||
var self = this;
|
||||
|
||||
function windowObserver(aSubject, aTopic, aData) {
|
||||
if (aTopic == "domwindowclosed" &&
|
||||
aSubject.QueryInterface(Ci.nsIDOMWindow).location == DIALOG_URL) {
|
||||
ww.unregisterNotification(windowObserver);
|
||||
tagsField.popup.removeEventListener("popuphidden", popupListener, true);
|
||||
ok(false, "Dialog window should not be closed by pressing Escape on the autocomplete popup");
|
||||
this.window.addEventListener("unload", function(event) {
|
||||
self.window.removeEventListener("unload", arguments.callee, true);
|
||||
tagsField.popup.removeEventListener("popuphidden", popupListener, true);
|
||||
ok(self._cleanShutdown, "Dialog window should not be closed by pressing Escape on the autocomplete popup");
|
||||
executeSoon(function () {
|
||||
self.finish();
|
||||
}
|
||||
}
|
||||
});
|
||||
}, true);
|
||||
|
||||
var popupListener = {
|
||||
handleEvent: function(aEvent) {
|
||||
switch (aEvent.type) {
|
||||
case "popuphidden":
|
||||
// Everything worked fine, we can stop observing the window.
|
||||
ww.unregisterNotification(windowObserver);
|
||||
tagsField.popup.removeEventListener("popuphidden", this, true);
|
||||
// Everything worked fine.
|
||||
self._cleanShutdown = true;
|
||||
self.window.document.documentElement.cancelDialog();
|
||||
self.finish();
|
||||
break;
|
||||
case "popupshown":
|
||||
tagsField.popup.removeEventListener("popupshown", this, true);
|
||||
// In case this test fails the window will close, we should mark the
|
||||
// failure and continue, to avoid timing out.
|
||||
ww.registerNotification(windowObserver);
|
||||
// In case this test fails the window will close, the test will fail
|
||||
// since we didn't set _cleanShutdown.
|
||||
var tree = tagsField.popup.tree;
|
||||
// Focus and select first result.
|
||||
isnot(tree, null, "Autocomplete results tree exists");
|
||||
|
@ -479,16 +475,13 @@ gTests.push({
|
|||
var folderTree = this.window.document.getElementById("editBMPanel_folderTree");
|
||||
var self = this;
|
||||
|
||||
function windowObserver(aSubject, aTopic, aData) {
|
||||
if (aTopic == "domwindowclosed" &&
|
||||
aSubject.QueryInterface(Ci.nsIDOMWindow).location == DIALOG_URL_MINIMAL_UI) {
|
||||
ww.unregisterNotification(windowObserver);
|
||||
ok(self._cleanShutdown,
|
||||
"Dialog window should not be closed by pressing ESC in folder name textbox");
|
||||
this.window.addEventListener("unload", function(event) {
|
||||
self.window.removeEventListener("unload", arguments.callee, true);
|
||||
ok(self._cleanShutdown, "Dialog window should not be closed by pressing ESC in folder name textbox");
|
||||
executeSoon(function () {
|
||||
self.finish();
|
||||
}
|
||||
}
|
||||
ww.registerNotification(windowObserver);
|
||||
});
|
||||
}, true);
|
||||
|
||||
folderTree.addEventListener("DOMAttrModified", function onDOMAttrModified(event) {
|
||||
if (event.attrName != "place")
|
||||
|
|
|
@ -39,44 +39,41 @@
|
|||
// panels are clickable in both LTR and RTL modes.
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
const BOOKMARKS_SIDEBAR_ID = "viewBookmarksSidebar";
|
||||
const BOOKMARKS_SIDEBAR_TREE_ID = "bookmarks-view";
|
||||
const HISTORY_SIDEBAR_ID = "viewHistorySidebar";
|
||||
const HISTORY_SIDEBAR_TREE_ID = "historyTree";
|
||||
|
||||
// Initialization.
|
||||
let os = Cc["@mozilla.org/observer-service;1"].
|
||||
getService(Ci.nsIObserverService);
|
||||
let bs = PlacesUtils.bookmarks;
|
||||
let hs = PlacesUtils.history;
|
||||
let sidebarBox = document.getElementById("sidebar-box");
|
||||
let sidebar = document.getElementById("sidebar");
|
||||
waitForExplicitFinish();
|
||||
const TEST_URL = "http://mochi.test:8888/browser/browser/components/places/tests/browser/sidebarpanels_click_test_page.html";
|
||||
|
||||
// If a sidebar is already open, close it.
|
||||
if (!sidebarBox.hidden) {
|
||||
if (!document.getElementById("sidebar-box").hidden) {
|
||||
info("Unexpected sidebar found - a previous test failed to cleanup correctly");
|
||||
toggleSidebar();
|
||||
}
|
||||
|
||||
const TEST_URL = "http://mochi.test:8888/browser/browser/components/places/tests/browser/sidebarpanels_click_test_page.html";
|
||||
|
||||
let sidebar = document.getElementById("sidebar");
|
||||
let tests = [];
|
||||
let currentTest;
|
||||
|
||||
tests.push({
|
||||
_itemID: null,
|
||||
init: function() {
|
||||
// Add a bookmark to the Unfiled Bookmarks folder.
|
||||
this._itemID = bs.insertBookmark(bs.unfiledBookmarksFolder,
|
||||
PlacesUtils._uri(TEST_URL),
|
||||
bs.DEFAULT_INDEX, "test");
|
||||
this._itemID = PlacesUtils.bookmarks.insertBookmark(
|
||||
PlacesUtils.unfiledBookmarksFolderId, PlacesUtils._uri(TEST_URL),
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX, "test"
|
||||
);
|
||||
},
|
||||
prepare: function() {
|
||||
},
|
||||
selectNode: function(tree) {
|
||||
tree.selectItems([this._itemID]);
|
||||
},
|
||||
cleanup: function() {
|
||||
bs.removeFolderChildren(bs.unfiledBookmarksFolder);
|
||||
cleanup: function(aCallback) {
|
||||
PlacesUtils.bookmarks.removeFolderChildren(PlacesUtils.unfiledBookmarksFolderId);
|
||||
executeSoon(aCallback);
|
||||
},
|
||||
sidebarName: BOOKMARKS_SIDEBAR_ID,
|
||||
treeName: BOOKMARKS_SIDEBAR_TREE_ID,
|
||||
|
@ -86,11 +83,11 @@ function test() {
|
|||
tests.push({
|
||||
init: function() {
|
||||
// Add a history entry.
|
||||
this.cleanup();
|
||||
let uri = PlacesUtils._uri(TEST_URL);
|
||||
hs.addVisit(uri, Date.now() * 1000, null, hs.TRANSITION_TYPED, false, 0);
|
||||
let gh = hs.QueryInterface(Ci.nsIGlobalHistory2);
|
||||
ok(gh.isVisited(uri), "Item is visited");
|
||||
PlacesUtils.history.addVisit(uri, Date.now() * 1000, null,
|
||||
PlacesUtils.history.TRANSITION_TYPED,
|
||||
false, 0);
|
||||
ok(PlacesUtils.ghistory2.isVisited(uri), "Item is visited");
|
||||
},
|
||||
prepare: function() {
|
||||
sidebar.contentDocument.getElementById("byvisited").doCommand();
|
||||
|
@ -100,66 +97,46 @@ function test() {
|
|||
is(tree.selectedNode.uri, TEST_URL, "The correct visit has been selected");
|
||||
is(tree.selectedNode.itemId, -1, "The selected node is not bookmarked");
|
||||
},
|
||||
cleanup: function() {
|
||||
hs.QueryInterface(Ci.nsIBrowserHistory)
|
||||
.removeAllPages();
|
||||
cleanup: function(aCallback) {
|
||||
waitForClearHistory(aCallback);
|
||||
},
|
||||
sidebarName: HISTORY_SIDEBAR_ID,
|
||||
treeName: HISTORY_SIDEBAR_TREE_ID,
|
||||
desc: "History sidebar test"
|
||||
});
|
||||
|
||||
let currentTest;
|
||||
|
||||
function testPlacesPanel(preFunc, postFunc) {
|
||||
currentTest.init();
|
||||
|
||||
sidebar.addEventListener("load", function() {
|
||||
sidebar.removeEventListener("load", arguments.callee, true);
|
||||
|
||||
let doc = sidebar.contentDocument;
|
||||
let tree = doc.getElementById(currentTest.treeName);
|
||||
let tbo = tree.treeBoxObject;
|
||||
|
||||
executeSoon(function() {
|
||||
currentTest.prepare();
|
||||
|
||||
if (preFunc)
|
||||
preFunc();
|
||||
|
||||
function observer(aSubject, aTopic, aData) {
|
||||
info("alert dialog observed as expected");
|
||||
os.removeObserver(observer, "common-dialog-loaded");
|
||||
os.removeObserver(observer, "tabmodal-dialog-loaded");
|
||||
Services.obs.removeObserver(observer, "common-dialog-loaded");
|
||||
Services.obs.removeObserver(observer, "tabmodal-dialog-loaded");
|
||||
|
||||
aSubject.Dialog.ui.button0.click();
|
||||
|
||||
executeSoon(function () {
|
||||
toggleSidebar(currentTest.sidebarName);
|
||||
currentTest.cleanup();
|
||||
postFunc();
|
||||
currentTest.cleanup(postFunc);
|
||||
});
|
||||
}
|
||||
os.addObserver(observer, "common-dialog-loaded", false);
|
||||
os.addObserver(observer, "tabmodal-dialog-loaded", false);
|
||||
Services.obs.addObserver(observer, "common-dialog-loaded", false);
|
||||
Services.obs.addObserver(observer, "tabmodal-dialog-loaded", false);
|
||||
|
||||
let tree = sidebar.contentDocument.getElementById(currentTest.treeName);
|
||||
|
||||
// Select the inserted places item.
|
||||
currentTest.selectNode(tree);
|
||||
is(tbo.view.selection.count, 1,
|
||||
"The test node should be successfully selected");
|
||||
// Get its row ID.
|
||||
let min = {}, max = {};
|
||||
tbo.view.selection.getRangeAt(0, min, max);
|
||||
let rowID = min.value;
|
||||
tbo.ensureRowIsVisible(rowID);
|
||||
|
||||
// Calculate the click coordinates.
|
||||
let x = {}, y = {}, width = {}, height = {};
|
||||
tbo.getCoordsForCellItem(rowID, tree.columns[0], "text",
|
||||
x, y, width, height);
|
||||
x = x.value + width.value / 2;
|
||||
y = y.value + height.value / 2;
|
||||
// Simulate the click.
|
||||
EventUtils.synthesizeMouse(tree.body, x, y, {}, doc.defaultView);
|
||||
synthesizeClickOnSelectedTreeCell(tree);
|
||||
// Now, wait for the observer to catch the alert dialog.
|
||||
// If something goes wrong, the test will time out at this stage.
|
||||
// Note that for the history sidebar, the URL itself is not opened,
|
||||
|
@ -171,45 +148,69 @@ function test() {
|
|||
toggleSidebar(currentTest.sidebarName);
|
||||
}
|
||||
|
||||
function synthesizeClickOnSelectedTreeCell(aTree) {
|
||||
let tbo = aTree.treeBoxObject;
|
||||
is(tbo.view.selection.count, 1,
|
||||
"The test node should be successfully selected");
|
||||
// Get selection rowID.
|
||||
let min = {}, max = {};
|
||||
tbo.view.selection.getRangeAt(0, min, max);
|
||||
let rowID = min.value;
|
||||
tbo.ensureRowIsVisible(rowID);
|
||||
|
||||
// Calculate the click coordinates.
|
||||
let x = {}, y = {}, width = {}, height = {};
|
||||
tbo.getCoordsForCellItem(rowID, aTree.columns[0], "text",
|
||||
x, y, width, height);
|
||||
x = x.value + width.value / 2;
|
||||
y = y.value + height.value / 2;
|
||||
// Simulate the click.
|
||||
EventUtils.synthesizeMouse(aTree.body, x, y, {},
|
||||
aTree.ownerDocument.defaultView);
|
||||
}
|
||||
|
||||
function changeSidebarDirection(aDirection) {
|
||||
document.getElementById("sidebar")
|
||||
.contentDocument
|
||||
.documentElement
|
||||
.style.direction = aDirection;
|
||||
sidebar.contentDocument.documentElement.style.direction = aDirection;
|
||||
}
|
||||
|
||||
function waitForClearHistory(aCallback) {
|
||||
Services.obs.addObserver(function(aSubject, aTopic, aData) {
|
||||
Services.obs.removeObserver(arguments.callee, PlacesUtils.TOPIC_EXPIRATION_FINISHED);
|
||||
aCallback(aSubject, aTopic, aData);
|
||||
}, PlacesUtils.TOPIC_EXPIRATION_FINISHED, false);
|
||||
PlacesUtils.bhistory.removeAllPages();
|
||||
}
|
||||
|
||||
function runNextTest() {
|
||||
// Remove any extraneous tabs.
|
||||
for (let tabCount = gBrowser.tabContainer.childNodes.length;
|
||||
tabCount > 1; tabCount--) {
|
||||
gBrowser.selectedTab = gBrowser.tabContainer.childNodes[tabCount - 1];
|
||||
gBrowser.removeCurrentTab();
|
||||
// Remove eventual tabs created by previous sub-tests.
|
||||
while (gBrowser.tabs.length > 1) {
|
||||
gBrowser.removeTab(gBrowser.tabContainer.lastChild);
|
||||
}
|
||||
|
||||
if (tests.length == 0)
|
||||
if (tests.length == 0) {
|
||||
finish();
|
||||
}
|
||||
else {
|
||||
// Create a new tab for our test to use.
|
||||
// Create a new tab and run the test.
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
|
||||
// Now we can run our test.
|
||||
currentTest = tests.shift();
|
||||
testPlacesPanel(function() {
|
||||
changeSidebarDirection("ltr");
|
||||
info("Running " + currentTest.desc + " in LTR mode");
|
||||
}, function() {
|
||||
executeSoon(function() {
|
||||
testPlacesPanel(function() {
|
||||
// Run the test in RTL mode.
|
||||
changeSidebarDirection("rtl");
|
||||
info("Running " + currentTest.desc + " in RTL mode");
|
||||
}, function() {
|
||||
executeSoon(runNextTest);
|
||||
});
|
||||
});
|
||||
});
|
||||
changeSidebarDirection("ltr");
|
||||
info("Running " + currentTest.desc + " in LTR mode");
|
||||
},
|
||||
function() {
|
||||
testPlacesPanel(function() {
|
||||
// Run the test in RTL mode.
|
||||
changeSidebarDirection("rtl");
|
||||
info("Running " + currentTest.desc + " in RTL mode");
|
||||
},
|
||||
function() {
|
||||
runNextTest();
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
runNextTest();
|
||||
// Ensure history is clean before starting the test.
|
||||
waitForClearHistory(runNextTest);
|
||||
}
|
||||
|
|
|
@ -4026,7 +4026,7 @@ SessionStoreService.prototype = {
|
|||
// Initialize the file output stream.
|
||||
var ostream = Cc["@mozilla.org/network/safe-file-output-stream;1"].
|
||||
createInstance(Ci.nsIFileOutputStream);
|
||||
ostream.init(aFile, 0x02 | 0x08 | 0x20, 0600, 0);
|
||||
ostream.init(aFile, 0x02 | 0x08 | 0x20, 0600, ostream.DEFER_OPEN);
|
||||
|
||||
// Obtain a converter to convert our data to a UTF-8 encoded input stream.
|
||||
var converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"].
|
||||
|
|
|
@ -77,8 +77,8 @@ function checkState(tab) {
|
|||
ok(!doc.getElementById("new-elem"), "new-elem should be removed.");
|
||||
|
||||
// Clean up after ourselves and finish the test.
|
||||
tab.linkedBrowser.removeEventListener("popstate", arguments.callee, false);
|
||||
tab.linkedBrowser.removeEventListener("load", arguments.callee, false);
|
||||
tab.linkedBrowser.removeEventListener("popstate", arguments.callee, true);
|
||||
tab.linkedBrowser.removeEventListener("load", arguments.callee, true);
|
||||
gBrowser.removeTab(tab);
|
||||
finish();
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ es-ES
|
|||
es-MX
|
||||
et
|
||||
eu
|
||||
fa
|
||||
fi
|
||||
fr
|
||||
fy-NL
|
||||
|
|
Двоичный файл не отображается.
До Ширина: | Высота: | Размер: 151 B После Ширина: | Высота: | Размер: 394 B |
|
@ -186,11 +186,16 @@
|
|||
background-image: -moz-linear-gradient(@toolbarHighlight@, rgba(255,255,255,0));
|
||||
}
|
||||
|
||||
#main-window[sizemode="normal"] #TabsToolbar[tabsontop="true"]:not([inFullscreen="true"]):not(:-moz-lwtheme) {
|
||||
#main-window[sizemode=normal] #TabsToolbar[tabsontop=true]:not([inFullscreen]) {
|
||||
padding-left: 4px;
|
||||
padding-right: 4px;
|
||||
}
|
||||
|
||||
#main-window[sizemode=normal] #TabsToolbar[tabsontop=false]:not([inFullscreen]) {
|
||||
padding-left: 2px;
|
||||
padding-right: 2px;
|
||||
}
|
||||
|
||||
/* Make the window draggable by glassed toolbars (bug 555081) */
|
||||
#toolbar-menubar:not([autohide="true"]),
|
||||
#TabsToolbar[tabsontop="true"],
|
||||
|
@ -321,3 +326,72 @@
|
|||
#close-button:hover:active {
|
||||
-moz-image-region: rect(32px, 49px, 48px, 32px);
|
||||
}
|
||||
|
||||
/* ::::: splitmenu highlight style that imitates Windows 7 start menu ::::: */
|
||||
@media all and (-moz-windows-default-theme) {
|
||||
.splitmenu-menuitem,
|
||||
.splitmenu-menu {
|
||||
-moz-appearance: none;
|
||||
padding-top: 2px;
|
||||
padding-bottom: 2px;
|
||||
border: 1px solid transparent;
|
||||
}
|
||||
.splitmenu-menuitem {
|
||||
-moz-margin-end: 0;
|
||||
}
|
||||
.splitmenu-menu {
|
||||
-moz-margin-start: -1px;
|
||||
}
|
||||
.splitmenu-menuitem:-moz-locale-dir(ltr),
|
||||
.splitmenu-menu:-moz-locale-dir(rtl) {
|
||||
border-top-left-radius: 3px;
|
||||
border-bottom-left-radius: 3px;
|
||||
}
|
||||
.splitmenu-menu:-moz-locale-dir(ltr),
|
||||
.splitmenu-menuitem:-moz-locale-dir(rtl) {
|
||||
border-top-right-radius: 3px;
|
||||
border-bottom-right-radius: 3px;
|
||||
}
|
||||
|
||||
.splitmenu-menuitem > .menu-text {
|
||||
-moz-margin-start: 1px !important;
|
||||
-moz-margin-end: 3px !important;
|
||||
}
|
||||
.splitmenu-menu > .menu-right {
|
||||
-moz-margin-end: -3px;
|
||||
}
|
||||
|
||||
.splitmenu-menuitem[iconic],
|
||||
.splitmenu-menu[iconic] {
|
||||
padding-bottom: 1px;
|
||||
}
|
||||
.splitmenu-menuitem[iconic] > .menu-iconic-left {
|
||||
margin-top: -3px;
|
||||
margin-bottom: -2px;
|
||||
-moz-margin-start: -1px;
|
||||
}
|
||||
.splitmenu-menuitem[iconic] > .menu-iconic-text {
|
||||
-moz-margin-start: 2px !important;
|
||||
-moz-margin-end: 3px !important;
|
||||
}
|
||||
.splitmenu-menu[iconic] > .menu-right {
|
||||
margin-top: -1px;
|
||||
}
|
||||
|
||||
.splitmenu-menuitem[_moz-menuactive],
|
||||
.splitmenu-menu[_moz-menuactive] {
|
||||
background-color: transparent;
|
||||
background-image: -moz-linear-gradient(#fafbfd, #ebf3fd);
|
||||
border-color: #aeccf1;
|
||||
}
|
||||
|
||||
.splitmenu-menuitem[disabled][_moz-menuactive],
|
||||
.splitmenu-menu[disabled][_moz-menuactive] {
|
||||
background-image: -moz-linear-gradient(#f8f9f9, #eaeaea);
|
||||
border-color: #d8d7d7;
|
||||
}
|
||||
|
||||
.splitmenu-menu[_moz-menuactive]:not(:hover):not([open]) {
|
||||
background-image: none;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1533,6 +1533,15 @@ richlistitem[type~="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-
|
|||
-moz-linear-gradient(bottom, @toolbarShadowColor@ 1px, rgba(0,0,0,.05) 1px, transparent 50%);
|
||||
}
|
||||
|
||||
%ifndef WINSTRIPE_AERO
|
||||
@media all and (-moz-windows-default-theme) {
|
||||
#main-window[sizemode=normal] #TabsToolbar:not([inFullscreen]) {
|
||||
padding-left: 2px;
|
||||
padding-right: 2px;
|
||||
}
|
||||
}
|
||||
%endif
|
||||
|
||||
.tabbrowser-tab,
|
||||
.tabs-newtab-button {
|
||||
-moz-appearance: none;
|
||||
|
@ -1540,12 +1549,12 @@ richlistitem[type~="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-
|
|||
-moz-linear-gradient(-moz-dialog, -moz-dialog);
|
||||
background-origin: border-box;
|
||||
background-position: 1px 2px;
|
||||
background-size: 100% -moz-calc(100% - 2px);
|
||||
background-size: -moz-calc(100% - 2px) -moz-calc(100% - 2px);
|
||||
background-repeat: no-repeat;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
-moz-border-image: url(tabbrowser/tab.png) 4 5 3 6 / 4px 5px 3px 6px repeat stretch;
|
||||
border-radius: 10px 8px 0 0;
|
||||
-moz-border-image: url(tabbrowser/tab.png) 6 3 4 / 6px 3px 4px repeat stretch;
|
||||
border-radius: 7px 7px 0 0;
|
||||
}
|
||||
|
||||
.tabbrowser-tab:hover,
|
||||
|
@ -1623,6 +1632,7 @@ richlistitem[type~="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-
|
|||
height: 16px;
|
||||
list-style-image: url("chrome://global/skin/icons/folder-item.png");
|
||||
-moz-image-region: rect(0px, 16px, 16px, 0px);
|
||||
-moz-margin-start: 2px;
|
||||
-moz-margin-end: 3px;
|
||||
}
|
||||
|
||||
|
@ -1640,8 +1650,8 @@ richlistitem[type~="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-
|
|||
|
||||
.tab-throbber[pinned],
|
||||
.tab-icon-image[pinned] {
|
||||
-moz-margin-start: 2px;
|
||||
-moz-margin-end: 2px;
|
||||
-moz-margin-start: 5px;
|
||||
-moz-margin-end: 5px;
|
||||
}
|
||||
|
||||
/* tabbrowser-tab focus ring */
|
||||
|
@ -1756,7 +1766,7 @@ richlistitem[type~="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-
|
|||
}
|
||||
|
||||
.tabs-newtab-button {
|
||||
width: 31px;
|
||||
width: 30px;
|
||||
}
|
||||
|
||||
.tabs-newtab-button:hover:active,
|
||||
|
|
Двоичные данные
browser/themes/winstripe/browser/tabbrowser/tab.png
Двоичные данные
browser/themes/winstripe/browser/tabbrowser/tab.png
Двоичный файл не отображается.
До Ширина: | Высота: | Размер: 353 B После Ширина: | Высота: | Размер: 238 B |
|
@ -558,6 +558,7 @@ MOZ_GTK2_LIBS = @MOZ_GTK2_LIBS@
|
|||
MOZ_QT_CFLAGS = @MOZ_QT_CFLAGS@
|
||||
MOZ_QT_LIBS = @MOZ_QT_LIBS@
|
||||
MOZ_ENABLE_QTNETWORK = @MOZ_ENABLE_QTNETWORK@
|
||||
MOZ_ENABLE_QTMOBILITY = @MOZ_ENABLE_QTMOBILITY@
|
||||
MOZ_ENABLE_CONTENTACTION = @MOZ_ENABLE_CONTENTACTION@
|
||||
MOZ_ENABLE_MEEGOTOUCHSHARE = @MOZ_ENABLE_MEEGOTOUCHSHARE@
|
||||
|
||||
|
|
|
@ -0,0 +1,335 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
usage = """%prog: A test for OOM conditions in the shell.
|
||||
|
||||
%prog finds segfaults and other errors caused by incorrect handling of
|
||||
allocation during OOM (out-of-memory) conditions.
|
||||
"""
|
||||
|
||||
help = """Check for regressions only. This runs a set of files with a known
|
||||
number of OOM errors (specified by REGRESSION_COUNT), and exits with a non-zero
|
||||
result if more or less errors are found. See js/src/Makefile.in for invocation.
|
||||
"""
|
||||
|
||||
|
||||
import hashlib
|
||||
import re
|
||||
import shlex
|
||||
import subprocess
|
||||
import sys
|
||||
import threading
|
||||
import time
|
||||
|
||||
from optparse import OptionParser
|
||||
|
||||
#####################################################################
|
||||
# Utility functions
|
||||
#####################################################################
|
||||
def run(args, stdin=None):
|
||||
class ThreadWorker(threading.Thread):
|
||||
def __init__(self, pipe):
|
||||
super(ThreadWorker, self).__init__()
|
||||
self.all = ""
|
||||
self.pipe = pipe
|
||||
self.setDaemon(True)
|
||||
|
||||
def run(self):
|
||||
while True:
|
||||
line = self.pipe.readline()
|
||||
if line == '': break
|
||||
else:
|
||||
self.all += line
|
||||
|
||||
try:
|
||||
if type(args) == str:
|
||||
args = shlex.split(args)
|
||||
|
||||
args = [str(a) for a in args] # convert to strs
|
||||
|
||||
stdin_pipe = subprocess.PIPE if stdin else None
|
||||
proc = subprocess.Popen(args, stdin=stdin_pipe, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
if stdin_pipe:
|
||||
proc.stdin.write(stdin)
|
||||
proc.stdin.close()
|
||||
|
||||
stdout_worker = ThreadWorker(proc.stdout)
|
||||
stderr_worker = ThreadWorker(proc.stderr)
|
||||
stdout_worker.start()
|
||||
stderr_worker.start()
|
||||
|
||||
proc.wait()
|
||||
stdout_worker.join()
|
||||
stderr_worker.join()
|
||||
|
||||
except KeyboardInterrupt, e:
|
||||
sys.exit(-1)
|
||||
|
||||
stdout, stderr = stdout_worker.all, stderr_worker.all
|
||||
result = (stdout, stderr, proc.returncode)
|
||||
return result
|
||||
|
||||
def get_js_files():
|
||||
(out, err, exit) = run('find ../jit-test/tests -name "*.js"')
|
||||
if (err, exit) == ("", 0):
|
||||
sys.exit("Wrong directory, run from an objdir")
|
||||
return out.split()
|
||||
|
||||
|
||||
|
||||
#####################################################################
|
||||
# Blacklisting
|
||||
#####################################################################
|
||||
def in_blacklist(sig):
|
||||
return sig in blacklist
|
||||
|
||||
def add_to_blacklist(sig):
|
||||
blacklist[sig] = blacklist.get(sig, 0)
|
||||
blacklist[sig] += 1
|
||||
|
||||
# How often is a particular lines important for this.
|
||||
def count_lines():
|
||||
"""Keep track of the amount of times individual lines occur, in order to
|
||||
prioritize the errors which occur most frequently."""
|
||||
counts = {}
|
||||
for string,count in blacklist.items():
|
||||
for line in string.split("\n"):
|
||||
counts[line] = counts.get(line, 0) + count
|
||||
|
||||
lines = []
|
||||
for k,v in counts.items():
|
||||
lines.append("%6d: %s" % (v,k))
|
||||
|
||||
lines.sort()
|
||||
|
||||
countlog = file("../OOM_count_log", "w")
|
||||
countlog.write("\n".join(lines))
|
||||
countlog.flush()
|
||||
countlog.close()
|
||||
|
||||
|
||||
#####################################################################
|
||||
# Output cleaning
|
||||
#####################################################################
|
||||
def clean_voutput(err):
|
||||
# Skip what we can't reproduce
|
||||
err = re.sub(r"^--\d+-- run: /usr/bin/dsymutil \"shell/js\"$", "", err, flags=re.MULTILINE)
|
||||
err = re.sub(r"^==\d+==", "", err, flags=re.MULTILINE)
|
||||
err = re.sub(r"^\*\*\d+\*\*", "", err, flags=re.MULTILINE)
|
||||
err = re.sub(r"^\s+by 0x[0-9A-Fa-f]+: ", "by: ", err, flags=re.MULTILINE)
|
||||
err = re.sub(r"^\s+at 0x[0-9A-Fa-f]+: ", "at: ", err, flags=re.MULTILINE)
|
||||
err = re.sub(r"(^\s+Address 0x)[0-9A-Fa-f]+( is not stack'd)", r"\1\2", err, flags=re.MULTILINE)
|
||||
err = re.sub(r"(^\s+Invalid write of size )\d+", r"\1x", err, flags=re.MULTILINE)
|
||||
err = re.sub(r"(^\s+Invalid read of size )\d+", r"\1x", err, flags=re.MULTILINE)
|
||||
err = re.sub(r"(^\s+Address 0x)[0-9A-Fa-f]+( is )\d+( bytes inside a block of size )[0-9,]+( free'd)", r"\1\2\3\4", err, flags=re.MULTILINE)
|
||||
|
||||
# Skip the repeating bit due to the segfault
|
||||
lines = []
|
||||
for l in err.split('\n'):
|
||||
if l == " Process terminating with default action of signal 11 (SIGSEGV)":
|
||||
break
|
||||
lines.append(l)
|
||||
err = '\n'.join(lines)
|
||||
|
||||
return err
|
||||
|
||||
def remove_failed_allocation_backtraces(err):
|
||||
lines = []
|
||||
|
||||
add = True
|
||||
for l in err.split('\n'):
|
||||
|
||||
# Set start and end conditions for including text
|
||||
if l == " The site of the failed allocation is:":
|
||||
add = False
|
||||
elif l[:2] not in ['by: ', 'at:']:
|
||||
add = True
|
||||
|
||||
if add:
|
||||
lines.append(l)
|
||||
|
||||
|
||||
err = '\n'.join(lines)
|
||||
|
||||
return err
|
||||
|
||||
|
||||
def clean_output(err):
|
||||
err = re.sub(r"^js\(\d+,0x[0-9a-f]+\) malloc: \*\*\* error for object 0x[0-9a-f]+: pointer being freed was not allocated\n\*\*\* set a breakppoint in malloc_error_break to debug\n$", "pointer being freed was not allocated", err, flags=re.MULTILINE)
|
||||
|
||||
return err
|
||||
|
||||
|
||||
#####################################################################
|
||||
# Consts, etc
|
||||
#####################################################################
|
||||
|
||||
command_template = 'shell/js' \
|
||||
+ ' -m -j -p' \
|
||||
+ ' -e "const platform=\'darwin\'; const libdir=\'../jit-test/lib/\';"' \
|
||||
+ ' -f ../jit-test/lib/prolog.js' \
|
||||
+ ' -f %s'
|
||||
|
||||
|
||||
# Blacklists are things we don't want to see in our logs again (though we do
|
||||
# want to count them when they happen). Whitelists we do want to see in our
|
||||
# logs again, principally because the information we have isn't enough.
|
||||
|
||||
blacklist = {}
|
||||
add_to_blacklist(r"('', '', 1)") # 1 means OOM if the shell hasn't launched yet.
|
||||
add_to_blacklist(r"('', 'out of memory\n', 1)")
|
||||
|
||||
whitelist = set()
|
||||
whitelist.add(r"('', 'out of memory\n', -11)") # -11 means OOM
|
||||
whitelist.add(r"('', 'out of memory\nout of memory\n', -11)")
|
||||
|
||||
|
||||
|
||||
#####################################################################
|
||||
# Program
|
||||
#####################################################################
|
||||
|
||||
# Options
|
||||
parser = OptionParser(usage=usage)
|
||||
parser.add_option("-r", "--regression", action="store", metavar="REGRESSION_COUNT", help=help,
|
||||
type="int", dest="regression", default=0) # TODO: support a value of zero, eventually
|
||||
|
||||
(OPTIONS, args) = parser.parse_args()
|
||||
|
||||
|
||||
if OPTIONS.regression:
|
||||
# TODO: This should be expanded as we get a better hang of the OOM problems.
|
||||
# For now, we'll just check that the number of OOMs in one short file does not
|
||||
# increase.
|
||||
files = ["../jit-test/tests/arguments/args-createontrace.js"]
|
||||
else:
|
||||
files = get_js_files()
|
||||
|
||||
# Use a command-line arg to reduce the set of files
|
||||
if len (args):
|
||||
files = [f for f in files if f.find(args[0]) != -1]
|
||||
|
||||
|
||||
if OPTIONS.regression:
|
||||
# Don't use a logfile, this is automated for tinderbox.
|
||||
log = file("../OOM_log", "w")
|
||||
|
||||
|
||||
num_failures = 0
|
||||
for f in files:
|
||||
|
||||
# Run it once to establish boundaries
|
||||
command = (command_template + ' -O') % (f)
|
||||
out, err, exit = run(command)
|
||||
max = re.match(".*OOM max count: (\d+).*", out, flags=re.DOTALL).groups()[0]
|
||||
max = int(max)
|
||||
|
||||
# OOMs don't recover well for the first 20 allocations or so.
|
||||
# TODO: revisit this.
|
||||
for i in range(20, max):
|
||||
|
||||
if OPTIONS.regression == None:
|
||||
print "Testing allocation %d/%d in %s" % (i,max,f)
|
||||
|
||||
command = (command_template + ' -A %d') % (f, i)
|
||||
out, err, exit = run(command)
|
||||
|
||||
# Success (5 is SM's exit code for controlled errors)
|
||||
if exit == 5 and err.find("out of memory") != -1:
|
||||
continue
|
||||
|
||||
# Failure
|
||||
else:
|
||||
|
||||
if OPTIONS.regression:
|
||||
# Just count them
|
||||
num_failures += 1
|
||||
continue
|
||||
|
||||
#########################################################################
|
||||
# The regression tests ends above. The rest of this is for running the
|
||||
# script manually.
|
||||
#########################################################################
|
||||
|
||||
problem = str((out, err, exit))
|
||||
if in_blacklist(problem) and problem not in whitelist:
|
||||
add_to_blacklist(problem)
|
||||
continue
|
||||
|
||||
add_to_blacklist(problem)
|
||||
|
||||
|
||||
# Get valgrind output for a good stack trace
|
||||
vcommand = "valgrind --dsymutil=yes -q --log-file=OOM_valgrind_log_file " + command
|
||||
run(vcommand)
|
||||
vout = file("OOM_valgrind_log_file").read()
|
||||
vout = clean_voutput(vout)
|
||||
sans_alloc_sites = remove_failed_allocation_backtraces(vout)
|
||||
|
||||
# Don't print duplicate information
|
||||
if in_blacklist(sans_alloc_sites):
|
||||
add_to_blacklist(sans_alloc_sites)
|
||||
continue
|
||||
|
||||
add_to_blacklist(sans_alloc_sites)
|
||||
|
||||
log.write ("\n")
|
||||
log.write ("\n")
|
||||
log.write ("=========================================================================")
|
||||
log.write ("\n")
|
||||
log.write ("An allocation failure at\n\tallocation %d/%d in %s\n\tcauses problems (detected using bug 624094)" % (i, max, f))
|
||||
log.write ("\n")
|
||||
log.write ("\n")
|
||||
|
||||
log.write ("Command (from obj directory, using patch from bug 624094):\n " + command)
|
||||
log.write ("\n")
|
||||
log.write ("\n")
|
||||
log.write ("stdout, stderr, exitcode:\n " + problem)
|
||||
log.write ("\n")
|
||||
log.write ("\n")
|
||||
|
||||
double_free = err.find("pointer being freed was not allocated") != -1
|
||||
oom_detected = err.find("out of memory") != -1
|
||||
multiple_oom_detected = err.find("out of memory\nout of memory") != -1
|
||||
segfault_detected = exit == -11
|
||||
|
||||
log.write ("Diagnosis: ")
|
||||
log.write ("\n")
|
||||
if multiple_oom_detected:
|
||||
log.write (" - Multiple OOMs reported")
|
||||
log.write ("\n")
|
||||
if segfault_detected:
|
||||
log.write (" - segfault")
|
||||
log.write ("\n")
|
||||
if not oom_detected:
|
||||
log.write (" - No OOM checking")
|
||||
log.write ("\n")
|
||||
if double_free:
|
||||
log.write (" - Double free")
|
||||
log.write ("\n")
|
||||
|
||||
log.write ("\n")
|
||||
|
||||
log.write ("Valgrind info:\n" + vout)
|
||||
log.write ("\n")
|
||||
log.write ("\n")
|
||||
log.flush()
|
||||
|
||||
if not OPTIONS.regression == None:
|
||||
count_lines()
|
||||
|
||||
|
||||
# Do the actual regression check
|
||||
if OPTIONS.regression:
|
||||
expected_num_failures = OPTIONS.regression
|
||||
|
||||
if num_failures != expected_num_failures:
|
||||
|
||||
print "TEST-UNEXPECTED-FAIL |",
|
||||
if num_failures > expected_num_failures:
|
||||
print "More out-of-memory errors were found (%s) than expected (%d). This probably means an allocation site has been added without a NULL-check. If this is unavoidable, you can account for it by updating Makefile.in." % (num_failures, expected_num_failures),
|
||||
else:
|
||||
print "Congratulations, you have removed %d out-of-memory error(s) (%d remain)! Please account for it by updating Makefile.in." % (expected_num_failures - num_failures, num_failures),
|
||||
sys.exit(-1)
|
||||
else:
|
||||
print 'TEST-PASS | find_OOM_errors | Found the expected number of OOM errors (%d)' % (expected_num_failures)
|
||||
|
22
configure.in
22
configure.in
|
@ -5488,6 +5488,26 @@ incorrect])
|
|||
MOZ_ENABLE_QTNETWORK=1
|
||||
AC_DEFINE(MOZ_ENABLE_QTNETWORK)
|
||||
fi
|
||||
|
||||
MOZ_ENABLE_QTMOBILITY=
|
||||
PKG_CHECK_MODULES(_QTMOBILITY, QtSensors,
|
||||
MOZ_ENABLE_QTMOBILITY=1,
|
||||
MOZ_ENABLE_QTMOBILITY=)
|
||||
if test "$MOZ_ENABLE_QTMOBILITY"; then
|
||||
MOZ_ENABLE_QTMOBILITY=1
|
||||
MOZ_QT_CFLAGS="$MOZ_QT_CFLAGS $_QTMOBILITY_CFLAGS"
|
||||
MOZ_QT_LIBS="$MOZ_QT_LIBS $_QTMOBILITY_LIBS"
|
||||
else
|
||||
AC_CHECK_LIB(QtSensors, main, [
|
||||
MOZ_ENABLE_QTMOBILITY=1
|
||||
MOZ_QT_CFLAGS="$MOZ_QT_CFLAGS -I/usr/include/qt4/QtMobility"
|
||||
MOZ_QT_CFLAGS="$MOZ_QT_CFLAGS -I/usr/include/qt4/QtSensors"
|
||||
MOZ_QT_LIBS="$MOZ_QT_LIBS -lQtSensors"
|
||||
])
|
||||
fi
|
||||
if test "$MOZ_ENABLE_QTMOBILITY"; then
|
||||
AC_DEFINE(MOZ_ENABLE_QTMOBILITY)
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_SUBST(GTK_CONFIG)
|
||||
|
@ -5498,6 +5518,7 @@ AC_SUBST(MOZ_ENABLE_GTK2)
|
|||
AC_SUBST(MOZ_ENABLE_PHOTON)
|
||||
AC_SUBST(MOZ_ENABLE_QT)
|
||||
AC_SUBST(MOZ_ENABLE_QTNETWORK)
|
||||
AC_SUBST(MOZ_ENABLE_QTMOBILITY)
|
||||
AC_SUBST(MOZ_ENABLE_XREMOTE)
|
||||
AC_SUBST(MOZ_GTK2_CFLAGS)
|
||||
AC_SUBST(MOZ_GTK2_LIBS)
|
||||
|
@ -9666,6 +9687,7 @@ if test "$MOZ_MEMORY"; then
|
|||
export MOZ_MEMORY_LDFLAGS
|
||||
fi
|
||||
fi
|
||||
export MOZ_APP_NAME
|
||||
AC_OUTPUT_SUBDIRS(js/src)
|
||||
ac_configure_args="$_SUBDIR_CONFIG_ARGS"
|
||||
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" class="reftest-wait">
|
||||
|
||||
<script>
|
||||
<![CDATA[
|
||||
|
||||
window.addEventListener("load", function () {
|
||||
document.documentElement.appendChild(document.getElementById("a"));
|
||||
setTimeout(function () {
|
||||
document.getElementById("x").setAttribute("id", "m1");
|
||||
document.documentElement.removeAttribute("class");
|
||||
}, 0);
|
||||
}, false);
|
||||
|
||||
]]>
|
||||
</script>
|
||||
|
||||
<g id="a">
|
||||
<path id="x"/>
|
||||
<text>
|
||||
<textPath xlink:href="#m1">Text</textPath>
|
||||
<textPath xlink:href="#m1">Text</textPath>
|
||||
|
||||
</text>
|
||||
</g>
|
||||
|
||||
</svg>
|
После Ширина: | Высота: | Размер: 588 B |
|
@ -0,0 +1,26 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" class="reftest-wait">
|
||||
|
||||
<script>
|
||||
<![CDATA[
|
||||
|
||||
window.addEventListener("load", function () {
|
||||
document.documentElement.appendChild(document.getElementById("a"));
|
||||
setTimeout(function () {
|
||||
document.getElementById("x").removeAttribute("id");
|
||||
document.documentElement.removeAttribute("class");
|
||||
}, 0);
|
||||
}, false);
|
||||
|
||||
]]>
|
||||
</script>
|
||||
|
||||
<g id="a">
|
||||
<path id="x"/>
|
||||
<text>
|
||||
<textPath xlink:href="#m1">Text</textPath>
|
||||
<textPath xlink:href="#m1">Text</textPath>
|
||||
|
||||
</text>
|
||||
</g>
|
||||
|
||||
</svg>
|
После Ширина: | Высота: | Размер: 585 B |
|
@ -86,3 +86,5 @@ load 593302-2.html
|
|||
load 610571-1.html
|
||||
load 604262-1.html
|
||||
load 628599-1.html
|
||||
load 637214-1.svg
|
||||
load 637214-2.svg
|
||||
|
|
|
@ -1699,12 +1699,12 @@ public:
|
|||
* a presentation with an associated widget, and use that widget's
|
||||
* layer manager.
|
||||
*
|
||||
* If one can't be found, a BasicLayerManager is created and returned.
|
||||
*
|
||||
* @param aDoc the document for which to return a layer manager.
|
||||
* @param aAllowRetaining an outparam that states whether the returned
|
||||
* layer manager should be used for retained layers
|
||||
*/
|
||||
static already_AddRefed<mozilla::layers::LayerManager>
|
||||
LayerManagerForDocument(nsIDocument *aDoc);
|
||||
LayerManagerForDocument(nsIDocument *aDoc, bool *aAllowRetaining = nsnull);
|
||||
|
||||
/**
|
||||
* Returns a layer manager to use for the given document. Basically we
|
||||
|
@ -1716,12 +1716,12 @@ public:
|
|||
* forseeable future. This function should be used carefully as it may change
|
||||
* the document's layer manager.
|
||||
*
|
||||
* If one can't be found, a BasicLayerManager is created and returned.
|
||||
*
|
||||
* @param aDoc the document for which to return a layer manager.
|
||||
* @param aAllowRetaining an outparam that states whether the returned
|
||||
* layer manager should be used for retained layers
|
||||
*/
|
||||
static already_AddRefed<mozilla::layers::LayerManager>
|
||||
PersistentLayerManagerForDocument(nsIDocument *aDoc);
|
||||
PersistentLayerManagerForDocument(nsIDocument *aDoc, bool *aAllowRetaining = nsnull);
|
||||
|
||||
/**
|
||||
* Determine whether a content node is focused or not,
|
||||
|
@ -1898,6 +1898,19 @@ private:
|
|||
MOZILLA_DECL_USE_GUARD_OBJECT_NOTIFIER
|
||||
};
|
||||
|
||||
class NS_STACK_CLASS nsAutoRemovableScriptBlocker {
|
||||
public:
|
||||
nsAutoRemovableScriptBlocker(MOZILLA_GUARD_OBJECT_NOTIFIER_ONLY_PARAM) {
|
||||
MOZILLA_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
nsContentUtils::AddRemovableScriptBlocker();
|
||||
}
|
||||
~nsAutoRemovableScriptBlocker() {
|
||||
nsContentUtils::RemoveRemovableScriptBlocker();
|
||||
}
|
||||
private:
|
||||
MOZILLA_DECL_USE_GUARD_OBJECT_NOTIFIER
|
||||
};
|
||||
|
||||
class NS_STACK_CLASS mozAutoRemovableBlockerRemover
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -1626,9 +1626,6 @@ protected:
|
|||
PRPackedBool mIsRegularHTML;
|
||||
PRPackedBool mIsXUL;
|
||||
|
||||
// Sync document.close behavior with document.open() (bug 627729)
|
||||
PRPackedBool mForceOldParserForHotmail;
|
||||
|
||||
enum {
|
||||
eTriUnset = 0,
|
||||
eTriFalse,
|
||||
|
|
|
@ -162,7 +162,7 @@ CSPPolicyURIListener.prototype = {
|
|||
}
|
||||
else {
|
||||
// problem fetching policy so fail closed
|
||||
this._csp.refinePolicy("allow 'none'", null, this._docURI, this._docRequest);
|
||||
this._csp.refinePolicy("allow 'none'", this._docURI, this._docRequest);
|
||||
}
|
||||
// resume the parent document request
|
||||
this._docRequest.resume();
|
||||
|
|
|
@ -6354,7 +6354,8 @@ static nsIView* GetDisplayRootFor(nsIView* aView)
|
|||
}
|
||||
|
||||
static already_AddRefed<LayerManager>
|
||||
LayerManagerForDocumentInternal(nsIDocument *aDoc, bool aRequirePersistent)
|
||||
LayerManagerForDocumentInternal(nsIDocument *aDoc, bool aRequirePersistent,
|
||||
bool* aAllowRetaining)
|
||||
{
|
||||
nsIDocument* doc = aDoc;
|
||||
nsIDocument* displayDoc = doc->GetDisplayDocument();
|
||||
|
@ -6394,7 +6395,8 @@ LayerManagerForDocumentInternal(nsIDocument *aDoc, bool aRequirePersistent)
|
|||
nsRefPtr<LayerManager> manager =
|
||||
static_cast<nsIWidget_MOZILLA_2_0_BRANCH*>(widget)->
|
||||
GetLayerManager(aRequirePersistent ? nsIWidget_MOZILLA_2_0_BRANCH::LAYER_MANAGER_PERSISTENT :
|
||||
nsIWidget_MOZILLA_2_0_BRANCH::LAYER_MANAGER_CURRENT);
|
||||
nsIWidget_MOZILLA_2_0_BRANCH::LAYER_MANAGER_CURRENT,
|
||||
aAllowRetaining);
|
||||
return manager.forget();
|
||||
}
|
||||
}
|
||||
|
@ -6406,15 +6408,15 @@ LayerManagerForDocumentInternal(nsIDocument *aDoc, bool aRequirePersistent)
|
|||
}
|
||||
|
||||
already_AddRefed<LayerManager>
|
||||
nsContentUtils::LayerManagerForDocument(nsIDocument *aDoc)
|
||||
nsContentUtils::LayerManagerForDocument(nsIDocument *aDoc, bool *aAllowRetaining)
|
||||
{
|
||||
return LayerManagerForDocumentInternal(aDoc, false);
|
||||
return LayerManagerForDocumentInternal(aDoc, false, aAllowRetaining);
|
||||
}
|
||||
|
||||
already_AddRefed<LayerManager>
|
||||
nsContentUtils::PersistentLayerManagerForDocument(nsIDocument *aDoc)
|
||||
nsContentUtils::PersistentLayerManagerForDocument(nsIDocument *aDoc, bool *aAllowRetaining)
|
||||
{
|
||||
return LayerManagerForDocumentInternal(aDoc, true);
|
||||
return LayerManagerForDocumentInternal(aDoc, true, aAllowRetaining);
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
@ -251,8 +251,7 @@ nsCrossSiteListenerProxy::CheckRequestApproved(nsIRequest* aRequest)
|
|||
rv = nsContentUtils::GetASCIIOrigin(mRequestingPrincipal, origin);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!allowedOriginHeader.Equals(origin) ||
|
||||
origin.EqualsLiteral("null")) {
|
||||
if (!allowedOriginHeader.Equals(origin)) {
|
||||
return NS_ERROR_DOM_BAD_URI;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -52,6 +52,7 @@
|
|||
#include "nsIFile.h"
|
||||
#include "nsIFileStreams.h"
|
||||
#include "nsIInputStream.h"
|
||||
#include "nsIIPCSerializable.h"
|
||||
#include "nsIMIMEService.h"
|
||||
#include "nsIPlatformCharset.h"
|
||||
#include "nsISeekableStream.h"
|
||||
|
@ -75,7 +76,8 @@ using namespace mozilla;
|
|||
// from NS_NewByteInputStream is held alive as long as the
|
||||
// stream is. We do that by passing back this class instead.
|
||||
class DataOwnerAdapter : public nsIInputStream,
|
||||
public nsISeekableStream {
|
||||
public nsISeekableStream
|
||||
{
|
||||
typedef nsDOMMemoryFile::DataOwner DataOwner;
|
||||
public:
|
||||
static nsresult Create(DataOwner* aDataOwner,
|
||||
|
@ -103,7 +105,9 @@ private:
|
|||
nsCOMPtr<nsISeekableStream> mSeekableStream;
|
||||
};
|
||||
|
||||
NS_IMPL_THREADSAFE_ISUPPORTS2(DataOwnerAdapter, nsIInputStream, nsISeekableStream)
|
||||
NS_IMPL_THREADSAFE_ISUPPORTS2(DataOwnerAdapter,
|
||||
nsIInputStream,
|
||||
nsISeekableStream)
|
||||
|
||||
nsresult DataOwnerAdapter::Create(DataOwner* aDataOwner,
|
||||
PRUint32 aStart,
|
||||
|
|
|
@ -889,6 +889,7 @@ TransferZoomLevels(nsIDocument* aFromDoc,
|
|||
return;
|
||||
|
||||
toCtxt->SetFullZoom(fromCtxt->GetFullZoom());
|
||||
toCtxt->SetMinFontSize(fromCtxt->MinFontSize());
|
||||
toCtxt->SetTextZoom(fromCtxt->TextZoom());
|
||||
}
|
||||
|
||||
|
@ -4103,6 +4104,10 @@ nsDocument::MozSetImageElement(const nsAString& aImageElementId,
|
|||
if (aImageElementId.IsEmpty())
|
||||
return NS_OK;
|
||||
|
||||
// Hold a script blocker while calling SetImageElement since that can call
|
||||
// out to id-observers
|
||||
nsAutoScriptBlocker scriptBlocker;
|
||||
|
||||
nsCOMPtr<nsIContent> content = do_QueryInterface(aImageElement);
|
||||
nsIdentifierMapEntry *entry = mIdentifierMap.PutEntry(aImageElementId);
|
||||
if (entry) {
|
||||
|
|
|
@ -2236,6 +2236,8 @@ nsGenericElement::SetPrefix(const nsAString& aPrefix)
|
|||
return NS_ERROR_DOM_NAMESPACE_ERR;
|
||||
}
|
||||
|
||||
nsAutoScriptBlocker scriptBlocker;
|
||||
|
||||
nsCOMPtr<nsINodeInfo> newNodeInfo;
|
||||
nsresult rv = nsContentUtils::PrefixChanged(mNodeInfo, prefix,
|
||||
getter_AddRefs(newNodeInfo));
|
||||
|
@ -4657,6 +4659,10 @@ nsGenericElement::SetAttr(PRInt32 aNamespaceID, nsIAtom* aName,
|
|||
nsNodeUtils::AttributeWillChange(this, aNamespaceID, aName, modType);
|
||||
}
|
||||
|
||||
// Hold a script blocker while calling ParseAttribute since that can call
|
||||
// out to id-observers
|
||||
nsAutoRemovableScriptBlocker scriptBlocker;
|
||||
|
||||
nsAttrValue attrValue;
|
||||
if (!ParseAttribute(aNamespaceID, aName, aValue, attrValue)) {
|
||||
attrValue.SetTo(aValue);
|
||||
|
|
|
@ -1749,6 +1749,7 @@ GK_ATOM(DeleteTxnName, "Deleting")
|
|||
// IPC stuff
|
||||
GK_ATOM(Remote, "remote")
|
||||
GK_ATOM(RemoteId, "_remote_id")
|
||||
GK_ATOM(DisplayPort, "_displayport")
|
||||
|
||||
// Names for system metrics
|
||||
GK_ATOM(scrollbar_start_backward, "scrollbar-start-backward")
|
||||
|
|
|
@ -131,6 +131,7 @@ nsresult
|
|||
nsStyledElement::UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
|
||||
PRBool aNotify)
|
||||
{
|
||||
nsAutoRemovableScriptBlocker scriptBlocker;
|
||||
if (aAttribute == nsGkAtoms::id && aNameSpaceID == kNameSpaceID_None) {
|
||||
// Have to do this before clearing flag. See RemoveFromIdTable
|
||||
RemoveFromIdTable();
|
||||
|
|
|
@ -12,7 +12,6 @@ function handleRequest(request, response)
|
|||
|
||||
// X-Frame-Options header value
|
||||
if (query['xfo'] == "deny") {
|
||||
for (var i = 0 ; i < 0x7fffff ; i++) { }
|
||||
response.setHeader("X-Frame-Options", "DENY", false);
|
||||
}
|
||||
else if (query['xfo'] == "sameorigin") {
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
// timer has to be alive so it can't be eaten by the GC.
|
||||
var timer;
|
||||
|
||||
function handleRequest(request, response)
|
||||
{
|
||||
response.setHeader("Cache-Control", "no-cache", false);
|
||||
|
@ -5,7 +8,7 @@ function handleRequest(request, response)
|
|||
// The "stray" open comment at the end of the write is important!
|
||||
response.write("document.write(\"<script charset='utf-8' src='script-2_bug597345.js'></script><!--\")");
|
||||
response.processAsync();
|
||||
var timer = Components.classes["@mozilla.org/timer;1"]
|
||||
timer = Components.classes["@mozilla.org/timer;1"]
|
||||
.createInstance(Components.interfaces.nsITimer);
|
||||
timer.initWithCallback(function() {
|
||||
response.finish();
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
// timer needs to be global so it can't be eaten by GC.
|
||||
var timer;
|
||||
|
||||
function handleRequest(request, response)
|
||||
{
|
||||
response.setHeader("Cache-Control", "no-cache", false);
|
||||
response.setHeader("Content-Type", "text/javascript", false);
|
||||
response.write("ok(asyncRan, 'Async script should have run first.'); firstRan = true;");
|
||||
response.processAsync();
|
||||
var timer = Components.classes["@mozilla.org/timer;1"]
|
||||
.createInstance(Components.interfaces.nsITimer);
|
||||
timer = Components.classes["@mozilla.org/timer;1"]
|
||||
.createInstance(Components.interfaces.nsITimer);
|
||||
timer.initWithCallback(function() {
|
||||
response.finish();
|
||||
}, 200, Components.interfaces.nsITimer.TYPE_ONE_SHOT);
|
||||
|
|
|
@ -110,9 +110,8 @@ function runTest() {
|
|||
];
|
||||
|
||||
if (isNullOrigin) {
|
||||
passTests = ["*", "\t \t* \t "];
|
||||
passTests = ["*", "\t \t* \t ", "null"];
|
||||
failTests = failTests.filter(function(v) { return v != origin });
|
||||
failTests.push("null");
|
||||
}
|
||||
|
||||
for each(allowOrigin in passTests) {
|
||||
|
|
|
@ -22,9 +22,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=421602
|
|||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
var img1loaded = false;
|
||||
var img2loaded = false;
|
||||
var img1errored = false;
|
||||
var img2errored = false;
|
||||
|
||||
function gc() {
|
||||
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
||||
|
@ -36,10 +34,13 @@ function gc() {
|
|||
// Our test image
|
||||
function loadTestImage() {
|
||||
var img1 = new Image();
|
||||
img1.onload = function() { img1loaded = true; }
|
||||
img1.onload = function() {
|
||||
img1loaded = true;
|
||||
finishTest();
|
||||
}
|
||||
img1.onerror = function() {
|
||||
is(img2errored, false, "Image 2 should not error before image 1");
|
||||
img1errored = true;
|
||||
finishTest();
|
||||
}
|
||||
img1.src = window.location.href + "?image1=true";
|
||||
}
|
||||
|
@ -48,17 +49,9 @@ loadTestImage();
|
|||
// Probably overkill to gc() more than once, but let's be safe
|
||||
gc(); gc(); gc();
|
||||
|
||||
// And now our "wrap the test up" image.
|
||||
var img2 = new Image();
|
||||
img2.onload = function() { img2loaded = true; }
|
||||
img2.onerror = function() { img2errored = true; finishTest(); }
|
||||
img2.src = window.location.href + "?image2=true";
|
||||
|
||||
function finishTest() {
|
||||
is(img1errored, true, "Image 1 should error");
|
||||
is(img2errored, true, "Image 2 should error");
|
||||
is(img1loaded, false, "Image 1 should not load");
|
||||
is(img2loaded, false, "Image 2 should not load");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -61,6 +61,8 @@
|
|||
|
||||
#include "GLContextProvider.h"
|
||||
|
||||
#include "gfxCrashReporterUtils.h"
|
||||
|
||||
#ifdef MOZ_SVG
|
||||
#include "nsSVGEffects.h"
|
||||
#endif
|
||||
|
@ -349,6 +351,8 @@ WebGLContext::SetContextOptions(nsIPropertyBag *aOptions)
|
|||
NS_IMETHODIMP
|
||||
WebGLContext::SetDimensions(PRInt32 width, PRInt32 height)
|
||||
{
|
||||
ScopedGfxFeatureReporter reporter("WebGL");
|
||||
|
||||
if (mWidth == width && mHeight == height)
|
||||
return NS_OK;
|
||||
|
||||
|
@ -527,6 +531,7 @@ WebGLContext::SetDimensions(PRInt32 width, PRInt32 height)
|
|||
gl->fClearStencil(0);
|
||||
gl->fClear(LOCAL_GL_COLOR_BUFFER_BIT | LOCAL_GL_DEPTH_BUFFER_BIT | LOCAL_GL_STENCIL_BUFFER_BIT);
|
||||
|
||||
reporter.SetSuccessful();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -378,9 +378,9 @@ PRBool WebGLContext::ValidateTexFormatAndType(WebGLenum format, WebGLenum type,
|
|||
|
||||
PRBool WebGLContext::ValidateAttribIndex(WebGLuint index, const char *info)
|
||||
{
|
||||
if (index > mAttribBuffers.Length()) {
|
||||
if (index >= mAttribBuffers.Length()) {
|
||||
if (index == WebGLuint(-1)) {
|
||||
ErrorInvalidValue("%s: index -1 is invalid. That probably comes from a getAttribLication() call, "
|
||||
ErrorInvalidValue("%s: index -1 is invalid. That probably comes from a getAttribLocation() call, "
|
||||
"where this return value -1 means that the passed name didn't correspond to an active attribute in "
|
||||
"the specified program.", info);
|
||||
} else {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// files that end in .txt list other tests
|
||||
// other lines are assumed to be .html files
|
||||
|
||||
conformance/00_test_list.txt
|
||||
|
||||
// files that end in .txt list other tests
|
||||
// other lines are assumed to be .html files
|
||||
|
||||
conformance/00_test_list.txt
|
||||
|
||||
|
|
|
@ -1,24 +1,13 @@
|
|||
This is a local copy of the WebGL conformance suite.
|
||||
|
||||
SVN revision: 13113
|
||||
This is a local copy of the WebGL conformance suite, version 1.0.0.
|
||||
|
||||
The canonical location for this testsuite is:
|
||||
|
||||
https://cvs.khronos.org/svn/repos/registry/trunk/public/webgl/sdk/tests/
|
||||
https://cvs.khronos.org/svn/repos/registry/trunk/public/webgl/conformance-suites/1.0.0/webgl-conformance-tests.html
|
||||
|
||||
All files and directories in this directory, with the exceptions listed below, come from
|
||||
upstream and should not be modified without corresponding upstream fixes and/or a
|
||||
patch file in the "patches" directory. The exceptions (the Mozilla-specific files) are:
|
||||
patch file in this directory. The exceptions (the Mozilla-specific files) are:
|
||||
* README.mozilla (this file)
|
||||
* failing_tests.txt
|
||||
* failing_tests_*.txt
|
||||
* Makefile.in
|
||||
* the "mozilla" directory, if any
|
||||
* the "patches" directory, if any
|
||||
|
||||
Moreover, the files named 00_test_list.txt are temporarily renamed to 00_testFIXME_list.txt to work around bug 584611, quote:
|
||||
> In mochitest, we tell people that mochitests should start with test_. The
|
||||
> actual truth is that we match anything with a test_ in it.
|
||||
|
||||
The "mozilla" directory contains integration of this test suite into Mozilla's
|
||||
testing system.
|
||||
|
||||
* *.patch files, if any
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
Welcome to the WebGL Conformance Test Suite
|
||||
===========================================
|
||||
|
||||
This is the initial release of the WebGL conformance test suite.
|
||||
|
||||
NOTE TO USERS: Unless you are a WebGL implementor, there is no need to submit
|
||||
a conformance result using this process. Should you discover bugs in your
|
||||
browser's WebGL implementation, either via this test suite or otherwise,
|
||||
please report them to your browser vendor's bug tracking system.
|
||||
|
||||
FOR WEBGL IMPLEMENTORS: Please follow the isntructions below to create
|
||||
a formal conformance submission.'
|
||||
|
||||
1) Open webgl-conformance-tests.html in your target browser
|
||||
|
||||
2) Press the "run tests" button
|
||||
|
||||
3) At the end of the run, press "display text summary"
|
||||
|
||||
4) Verify that the User Agent and WebGL renderer strings identify your browser and target correctly.
|
||||
|
||||
5) Copy the contents of the text summary (starting with "WebGL Conformance Test Results") and send via email to
|
||||
--- NEED ADDRESS HERE --- @khronos.org
|
||||
|
||||
|
||||
- Version 1.0.0
|
||||
- February 24, 2011
|
||||
|
|
@ -4,9 +4,12 @@ array-unit-tests.html
|
|||
bad-arguments-test.html
|
||||
buffer-bind-test.html
|
||||
buffer-data-array-buffer.html
|
||||
buffer-preserve-test.html
|
||||
canvas-test.html
|
||||
constants.html
|
||||
context-attributes-alpha-depth-stencil-antialias.html
|
||||
context-lost-restored.html
|
||||
context-lost.html
|
||||
context-type-test.html
|
||||
copy-tex-image-and-sub-image-2d.html
|
||||
draw-arrays-out-of-bounds.html
|
||||
|
@ -24,7 +27,11 @@ gl-enum-tests.html
|
|||
gl-get-active-attribute.html
|
||||
gl-get-active-uniform.html
|
||||
gl-get-calls.html
|
||||
gl-getshadersource.html
|
||||
gl-getstring.html
|
||||
gl-min-attribs.html
|
||||
# gl-min-textures.html
|
||||
gl-min-uniforms.html
|
||||
gl-object-get-calls.html
|
||||
gl-pixelstorei.html
|
||||
gl-scissor-test.html
|
||||
|
@ -35,8 +42,9 @@ gl-uniform-bool.html
|
|||
gl-uniformmatrix4fv.html
|
||||
gl-unknown-uniform.html
|
||||
gl-vertex-attrib.html
|
||||
gl-vertex-attrib-zero-issues.html
|
||||
gl-vertexattribpointer.html
|
||||
glsl-2types-of-textures-on-same-unit.html
|
||||
#glsl-2types-of-textures-on-same-unit.html
|
||||
glsl-conformance.html
|
||||
incorrect-context-object-behaviour.html
|
||||
index-validation-copies-indices.html
|
||||
|
@ -44,6 +52,7 @@ index-validation-crash-with-buffer-sub-data.html
|
|||
index-validation-verifies-too-many-indices.html
|
||||
index-validation-with-resized-buffer.html
|
||||
index-validation.html
|
||||
instanceof-test.html
|
||||
invalid-UTF-16.html
|
||||
invalid-passed-params.html
|
||||
is-object.html
|
||||
|
@ -52,6 +61,9 @@ more-than-65536-points.html
|
|||
null-object-behaviour.html
|
||||
null-uniform-location.html
|
||||
object-deletion-behaviour.html
|
||||
oes-standard-derivatives.html
|
||||
oes-texture-float.html
|
||||
oes-vertex-array-object.html
|
||||
origin-clean-conformance.html
|
||||
point-size.html
|
||||
program-test.html
|
||||
|
@ -67,6 +79,7 @@ tex-image-and-uniform-binding-bugs.html
|
|||
tex-image-with-format-and-type.html
|
||||
tex-image-with-invalid-data.html
|
||||
tex-input-validation.html
|
||||
tex-sub-image-2d-bad-args.html
|
||||
tex-sub-image-2d.html
|
||||
texparameter-test.html
|
||||
texture-active-bind-2.html
|
||||
|
@ -82,3 +95,5 @@ uniform-samplers-test.html
|
|||
uninitialized-test.html
|
||||
viewport-unchanged-upon-resize.html
|
||||
webgl-specific.html
|
||||
more/00_test_list.txt
|
||||
|
||||
|
|
|
@ -186,6 +186,95 @@ function testConstructWithTypedArrayOfSignedValues(type, name) {
|
|||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Test cases for integral types.
|
||||
// Some JavaScript engines need separate copies of this code in order
|
||||
// to exercise all of their optimized code paths.
|
||||
//
|
||||
|
||||
function testIntegralArrayTruncationBehavior(type, name, unsigned) {
|
||||
running('test integral array truncation behavior for ' + name);
|
||||
|
||||
var sourceData;
|
||||
var expectedResults;
|
||||
|
||||
if (unsigned) {
|
||||
sourceData = [0.6, 10.6];
|
||||
expectedResults = [0, 10];
|
||||
} else {
|
||||
sourceData = [0.6, 10.6, -0.6, -10.6];
|
||||
expectedResults = [0, 10, 0, -10];
|
||||
}
|
||||
|
||||
var numIterations = 10;
|
||||
var array = new type(numIterations);
|
||||
|
||||
// The code block in each of the case statements below is identical, but some
|
||||
// JavaScript engines need separate copies in order to exercise all of
|
||||
// their optimized code paths.
|
||||
|
||||
try {
|
||||
switch (type) {
|
||||
case Int8Array:
|
||||
for (var ii = 0; ii < sourceData.length; ++ii) {
|
||||
for (var jj = 0; jj < numIterations; ++jj) {
|
||||
array[jj] = sourceData[ii];
|
||||
assertEq('Storing ' + sourceData[ii], expectedResults[ii], array[jj]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Int16Array:
|
||||
for (var ii = 0; ii < sourceData.length; ++ii) {
|
||||
for (var jj = 0; jj < numIterations; ++jj) {
|
||||
array[jj] = sourceData[ii];
|
||||
assertEq('Storing ' + sourceData[ii], expectedResults[ii], array[jj]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Int32Array:
|
||||
for (var ii = 0; ii < sourceData.length; ++ii) {
|
||||
for (var jj = 0; jj < numIterations; ++jj) {
|
||||
array[jj] = sourceData[ii];
|
||||
assertEq('Storing ' + sourceData[ii], expectedResults[ii], array[jj]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Uint8Array:
|
||||
for (var ii = 0; ii < sourceData.length; ++ii) {
|
||||
for (var jj = 0; jj < numIterations; ++jj) {
|
||||
array[jj] = sourceData[ii];
|
||||
assertEq('Storing ' + sourceData[ii], expectedResults[ii], array[jj]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Uint16Array:
|
||||
for (var ii = 0; ii < sourceData.length; ++ii) {
|
||||
for (var jj = 0; jj < numIterations; ++jj) {
|
||||
array[jj] = sourceData[ii];
|
||||
assertEq('Storing ' + sourceData[ii], expectedResults[ii], array[jj]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Uint32Array:
|
||||
for (var ii = 0; ii < sourceData.length; ++ii) {
|
||||
for (var jj = 0; jj < numIterations; ++jj) {
|
||||
array[jj] = sourceData[ii];
|
||||
assertEq('Storing ' + sourceData[ii], expectedResults[ii], array[jj]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
fail("Unhandled type");
|
||||
break;
|
||||
}
|
||||
|
||||
pass();
|
||||
} catch (e) {
|
||||
fail(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Test cases for both signed and unsigned types
|
||||
//
|
||||
|
@ -314,8 +403,8 @@ function negativeTestSetFromArray(type, name) {
|
|||
}
|
||||
}
|
||||
|
||||
function testSlice(type, name) {
|
||||
running('test ' + name + ' Slice');
|
||||
function testSubarray(type, name) {
|
||||
running('test ' + name + ' Subarray');
|
||||
try {
|
||||
var array = new type([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
|
||||
var subarray = array.subarray(0, 5);
|
||||
|
@ -334,8 +423,8 @@ function testSlice(type, name) {
|
|||
}
|
||||
}
|
||||
|
||||
function negativeTestSlice(type, name) {
|
||||
running('negativeTest ' + name + ' Slice');
|
||||
function negativeTestSubarray(type, name) {
|
||||
running('negativeTest ' + name + ' Subarray');
|
||||
try {
|
||||
var array = new type([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
|
||||
subarray = array.subarray(5, 11);
|
||||
|
@ -354,17 +443,31 @@ function negativeTestSlice(type, name) {
|
|||
}
|
||||
}
|
||||
|
||||
function testBoundaryConditions(type, name, lowValue, expectedLowValue, highValue, expectedHighValue) {
|
||||
running('test ' + name + ' BoundaryConditions(' +
|
||||
lowValue + ', ' + expectedLowValue + ', ' +
|
||||
highValue + ', ' + expectedHighValue + ')');
|
||||
function testSetBoundaryConditions(type, name, testValues, expectedValues) {
|
||||
running('test ' + name + ' SetBoundaryConditions');
|
||||
try {
|
||||
var array = new type(1);
|
||||
assertEq('Array length', 1, array.length);
|
||||
array[0] = lowValue;
|
||||
assertEq('Element 0', expectedLowValue, array[0]);
|
||||
array[0] = highValue;
|
||||
assertEq('Element 0', expectedHighValue, array[0]);
|
||||
for (var ii = 0; ii < testValues.length; ++ii) {
|
||||
for (var jj = 0; jj < 10; ++jj) {
|
||||
array[0] = testValues[ii];
|
||||
assertEq('Element 0', expectedValues[ii], array[0]);
|
||||
}
|
||||
}
|
||||
pass();
|
||||
} catch (e) {
|
||||
fail(e);
|
||||
}
|
||||
}
|
||||
|
||||
function testConstructionBoundaryConditions(type, name, testValues, expectedValues) {
|
||||
running('test ' + name + ' ConstructionBoundaryConditions');
|
||||
try {
|
||||
var array = new type(testValues);
|
||||
assertEq('Array length', testValues.length, array.length);
|
||||
for (var ii = 0; ii < testValues.length; ++ii) {
|
||||
assertEq('Element ' + ii, expectedValues[ii], array[ii]);
|
||||
}
|
||||
pass();
|
||||
} catch (e) {
|
||||
fail(e);
|
||||
|
@ -476,8 +579,8 @@ function testConstructionWithBothArrayBufferAndLength(type, name, elementSizeInB
|
|||
var array;
|
||||
var typeSize;
|
||||
|
||||
function testSlicingWithOutOfRangeValues(type, name, sz) {
|
||||
debug("Testing slicing of " + name);
|
||||
function testSubarrayWithOutOfRangeValues(type, name, sz) {
|
||||
debug("Testing subarray of " + name);
|
||||
try {
|
||||
var buffer = new ArrayBuffer(32);
|
||||
array = new type(buffer);
|
||||
|
@ -497,15 +600,15 @@ function testSlicingWithOutOfRangeValues(type, name, sz) {
|
|||
shouldBe("array.length", "0");
|
||||
}
|
||||
} catch (e) {
|
||||
testFailed("Slicing of " + name + " threw exception");
|
||||
testFailed("Subarray of " + name + " threw exception");
|
||||
}
|
||||
} catch (e) {
|
||||
testFailed("Exception: " + e);
|
||||
}
|
||||
}
|
||||
|
||||
function testSlicingWithDefaultValues(type, name, sz) {
|
||||
debug("Testing slicing with default inputs of " + name);
|
||||
function testSubarrayWithDefaultValues(type, name, sz) {
|
||||
debug("Testing subarray with default inputs of " + name);
|
||||
try {
|
||||
var buffer = new ArrayBuffer(32);
|
||||
array = new type(buffer);
|
||||
|
@ -517,7 +620,7 @@ function testSlicingWithDefaultValues(type, name, sz) {
|
|||
shouldBe("array.subarray(-2).length", "2");
|
||||
shouldBe("array.subarray(-2147483648).length", "(32 / typeSize)");
|
||||
} catch (e) {
|
||||
testFailed("Slicing of " + name + " threw exception");
|
||||
testFailed("Subarray of " + name + " threw exception");
|
||||
}
|
||||
} catch (e) {
|
||||
testFailed("Exception: " + e);
|
||||
|
@ -584,6 +687,81 @@ function negativeTestGetAndSetMethods(type, name) {
|
|||
}
|
||||
}
|
||||
|
||||
function testNaNConversion(type, name) {
|
||||
running('test storing NaN in ' + name);
|
||||
|
||||
var array = new type([1, 1]);
|
||||
var results = [];
|
||||
|
||||
// The code block in each of the case statements below is identical, but some
|
||||
// JavaScript engines need separate copies in order to exercise all of
|
||||
// their optimized code paths.
|
||||
try {
|
||||
switch (type) {
|
||||
case Float32Array:
|
||||
for (var i = 0; i < array.length; ++i) {
|
||||
array[i] = NaN;
|
||||
results[i] = array[i];
|
||||
}
|
||||
break;
|
||||
case Int8Array:
|
||||
for (var i = 0; i < array.length; ++i) {
|
||||
array[i] = NaN;
|
||||
results[i] = array[i];
|
||||
}
|
||||
break;
|
||||
case Int16Array:
|
||||
for (var i = 0; i < array.length; ++i) {
|
||||
array[i] = NaN;
|
||||
results[i] = array[i];
|
||||
}
|
||||
break;
|
||||
case Int32Array:
|
||||
for (var i = 0; i < array.length; ++i) {
|
||||
array[i] = NaN;
|
||||
results[i] = array[i];
|
||||
}
|
||||
break;
|
||||
case Uint8Array:
|
||||
for (var i = 0; i < array.length; ++i) {
|
||||
array[i] = NaN;
|
||||
results[i] = array[i];
|
||||
}
|
||||
break;
|
||||
case Uint16Array:
|
||||
for (var i = 0; i < array.length; ++i) {
|
||||
array[i] = NaN;
|
||||
results[i] = array[i];
|
||||
}
|
||||
break;
|
||||
case Uint32Array:
|
||||
for (var i = 0; i < array.length; ++i) {
|
||||
array[i] = NaN;
|
||||
results[i] = array[i];
|
||||
}
|
||||
break;
|
||||
default:
|
||||
fail("Unhandled type");
|
||||
break;
|
||||
}
|
||||
|
||||
// Some types preserve NaN values; all other types convert NaN to zero.
|
||||
if (type === Float32Array) {
|
||||
assert('initial NaN preserved', isNaN(new type([NaN])[0]));
|
||||
for (var i = 0; i < array.length; ++i)
|
||||
assert('NaN preserved via setter', isNaN(results[i]));
|
||||
} else {
|
||||
assertEq('initial NaN converted to zero', 0, new type([NaN])[0]);
|
||||
for (var i = 0; i < array.length; ++i)
|
||||
assertEq('NaN converted to zero by setter', 0, results[i]);
|
||||
}
|
||||
|
||||
pass();
|
||||
} catch (e) {
|
||||
fail(e);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Test driver
|
||||
//
|
||||
|
@ -596,54 +774,54 @@ function runTests() {
|
|||
var testCases =
|
||||
[ {name: "Float32Array",
|
||||
unsigned: false,
|
||||
integral: false,
|
||||
elementSizeInBytes: 4,
|
||||
low: -500.5,
|
||||
expectedLow: -500.5,
|
||||
high: 500.5,
|
||||
expectedHigh: 500.5},
|
||||
testValues: [ -500.5, 500.5 ],
|
||||
expectedValues: [ -500.5, 500.5 ]
|
||||
},
|
||||
{name: "Int8Array",
|
||||
unsigned: false,
|
||||
integral: true,
|
||||
elementSizeInBytes: 1,
|
||||
low: -128,
|
||||
expectedLow: -128,
|
||||
high: 127,
|
||||
expectedHigh: 127},
|
||||
testValues: [ -128, 127, -129, 128 ],
|
||||
expectedValues: [ -128, 127, 127, -128 ]
|
||||
},
|
||||
{name: "Int16Array",
|
||||
unsigned: false,
|
||||
integral: true,
|
||||
elementSizeInBytes: 2,
|
||||
low: -32768,
|
||||
expectedLow: -32768,
|
||||
high: 32767,
|
||||
expectedHigh: 32767},
|
||||
testValues: [ -32768, 32767, -32769, 32768 ],
|
||||
expectedValues: [ -32768, 32767, 32767, -32768 ]
|
||||
},
|
||||
{name: "Int32Array",
|
||||
unsigned: false,
|
||||
integral: true,
|
||||
elementSizeInBytes: 4,
|
||||
low: -2147483648,
|
||||
expectedLow: -2147483648,
|
||||
high: 2147483647,
|
||||
expectedHigh: 2147483647},
|
||||
testValues: [ -2147483648, 2147483647, -2147483649, 2147483648 ],
|
||||
expectedValues: [ -2147483648, 2147483647, 2147483647, -2147483648 ]
|
||||
},
|
||||
{name: "Uint8Array",
|
||||
unsigned: true,
|
||||
integral: true,
|
||||
elementSizeInBytes: 1,
|
||||
low: 0,
|
||||
expectedLow: 0,
|
||||
high: 255,
|
||||
expectedHigh: 255},
|
||||
testValues: [ 0, 255, -1, 256 ],
|
||||
expectedValues: [ 0, 255, 255, 0 ]
|
||||
},
|
||||
{name: "Uint16Array",
|
||||
unsigned: true,
|
||||
integral: true,
|
||||
elementSizeInBytes: 2,
|
||||
low: 0,
|
||||
expectedLow: 0,
|
||||
high: 65535,
|
||||
expectedHigh: 65535},
|
||||
testValues: [ 0, 65535, -1, 65536 ],
|
||||
expectedValues: [ 0, 65535, 65535, 0 ]
|
||||
},
|
||||
{name: "Uint32Array",
|
||||
unsigned: true,
|
||||
integral: true,
|
||||
elementSizeInBytes: 4,
|
||||
low: 0,
|
||||
expectedLow: 0,
|
||||
high: 4294967295,
|
||||
expectedHigh: 4294967295} ];
|
||||
|
||||
testValues: [ 0, 4294967295, -1, 4294967296 ],
|
||||
expectedValues: [ 0, 4294967295, 4294967295, 0 ]
|
||||
}
|
||||
];
|
||||
for (var i = 0; i < testCases.length; i++) {
|
||||
var testCase = testCases[i];
|
||||
running(testCase.name);
|
||||
|
@ -662,20 +840,25 @@ function runTests() {
|
|||
testConstructWithArrayOfSignedValues(type, name);
|
||||
testConstructWithTypedArrayOfSignedValues(type, name);
|
||||
}
|
||||
if (testCase.integral) {
|
||||
testIntegralArrayTruncationBehavior(type, name, testCase.unsigned);
|
||||
}
|
||||
testGetWithOutOfRangeIndices(type, name);
|
||||
testOffsetsAndSizes(type, name, testCase.elementSizeInBytes);
|
||||
testSetFromTypedArray(type, name);
|
||||
negativeTestSetFromTypedArray(type, name);
|
||||
testSetFromArray(type, name);
|
||||
negativeTestSetFromArray(type, name);
|
||||
testSlice(type, name);
|
||||
negativeTestSlice(type, name);
|
||||
testBoundaryConditions(type,
|
||||
name,
|
||||
testCase.low,
|
||||
testCase.expectedLow,
|
||||
testCase.high,
|
||||
testCase.expectedHigh);
|
||||
testSubarray(type, name);
|
||||
negativeTestSubarray(type, name);
|
||||
testSetBoundaryConditions(type,
|
||||
name,
|
||||
testCase.testValues,
|
||||
testCase.expectedValues);
|
||||
testConstructionBoundaryConditions(type,
|
||||
name,
|
||||
testCase.testValues,
|
||||
testCase.expectedValues);
|
||||
testConstructionWithNullBuffer(type, name);
|
||||
testConstructionWithOutOfRangeValues(type, name);
|
||||
testConstructionWithNegativeOutOfRangeValues(type, name);
|
||||
|
@ -683,12 +866,13 @@ function runTests() {
|
|||
testConstructionWithUnalignedLength(type, name, testCase.elementSizeInBytes);
|
||||
testConstructionOfHugeArray(type, name, testCase.elementSizeInBytes);
|
||||
testConstructionWithBothArrayBufferAndLength(type, name, testCase.elementSizeInBytes);
|
||||
testSlicingWithOutOfRangeValues(type, name, testCase.elementSizeInBytes);
|
||||
testSlicingWithDefaultValues(type, name, testCase.elementSizeInBytes);
|
||||
testSubarrayWithOutOfRangeValues(type, name, testCase.elementSizeInBytes);
|
||||
testSubarrayWithDefaultValues(type, name, testCase.elementSizeInBytes);
|
||||
testSettingFromArrayWithOutOfRangeOffset(type, name);
|
||||
testSettingFromFakeArrayWithOutOfRangeLength(type, name);
|
||||
testSettingFromTypedArrayWithOutOfRangeOffset(type, name);
|
||||
negativeTestGetAndSetMethods(type, name);
|
||||
testNaNConversion(type, name);
|
||||
}
|
||||
|
||||
printSummary();
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче