Merge MC -> JM

This commit is contained in:
Brian Hackett 2011-08-09 13:29:11 -07:00
commit c743913090
1389 changed files with 107489 additions and 104598 deletions

View File

@ -408,12 +408,9 @@ nsAccessibleWrap::CreateMaiInterfaces(void)
// the Component interface are supported by all nsIAccessible
interfacesBits |= 1 << MAI_INTERFACE_COMPONENT;
// Add Action interface if the action count is more than zero.
PRUint8 actionCount = 0;
nsresult rv = GetNumActions(&actionCount);
if (NS_SUCCEEDED(rv) && actionCount > 0) {
interfacesBits |= 1 << MAI_INTERFACE_ACTION;
}
// Add Action interface if the action count is more than zero.
if (ActionCount() > 0)
interfacesBits |= 1 << MAI_INTERFACE_ACTION;
//nsIAccessibleText
nsCOMPtr<nsIAccessibleText> accessInterfaceText;

View File

@ -73,13 +73,8 @@ doActionCB(AtkAction *aAction, gint aActionIndex)
gint
getActionCountCB(AtkAction *aAction)
{
nsAccessibleWrap *accWrap = GetAccessibleWrap(ATK_OBJECT(aAction));
if (!accWrap)
return 0;
PRUint8 num = 0;
nsresult rv = accWrap->GetNumActions(&num);
return (NS_FAILED(rv)) ? 0 : static_cast<gint>(num);
nsAccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aAction));
return accWrap ? accWrap->ActionCount() : 0;
}
const gchar *

View File

@ -132,27 +132,17 @@ AccGroupInfo::AccGroupInfo(nsAccessible* aItem, PRUint32 aRole) :
if (mParent)
return;
// Compute parent.
PRUint32 parentRole = parent->Role();
// In the case of ARIA row in treegrid, return treegrid since ARIA
// groups aren't used to organize levels in ARIA treegrids.
if (aRole == nsIAccessibleRole::ROLE_ROW &&
parentRole == nsIAccessibleRole::ROLE_TREE_TABLE) {
if (IsConceptualParent(aRole, parentRole))
mParent = parent;
return;
}
// In the case of ARIA tree, a tree can be arranged by using ARIA groups
// to organize levels. In this case the parent of the tree item will be
// a group and the previous treeitem of that should be the tree item
// parent. Or, if the parent is something other than a tree we will
// return that.
if (parentRole != nsIAccessibleRole::ROLE_GROUPING) {
mParent = parent;
// In the case of ARIA tree (not ARIA treegrid) a tree can be arranged by
// using ARIA groups to organize levels. In this case the parent of the tree
// item will be a group and the previous treeitem of that should be the tree
// item parent.
if (parentRole != nsIAccessibleRole::ROLE_GROUPING ||
aRole != nsIAccessibleRole::ROLE_OUTLINEITEM)
return;
}
nsAccessible* parentPrevSibling = parent->PrevSibling();
if (!parentPrevSibling)
@ -174,3 +164,37 @@ AccGroupInfo::AccGroupInfo(nsAccessible* aItem, PRUint32 aRole) :
if (parentPrevSiblingRole == nsIAccessibleRole::ROLE_OUTLINEITEM)
mParent = parentPrevSibling;
}
bool
AccGroupInfo::IsConceptualParent(PRUint32 aRole, PRUint32 aParentRole)
{
if (aParentRole == nsIAccessibleRole::ROLE_OUTLINE &&
aRole == nsIAccessibleRole::ROLE_OUTLINEITEM)
return true;
if ((aParentRole == nsIAccessibleRole::ROLE_TABLE ||
aParentRole == nsIAccessibleRole::ROLE_TREE_TABLE) &&
aRole == nsIAccessibleRole::ROLE_ROW)
return true;
if (aParentRole == nsIAccessibleRole::ROLE_ROW &&
(aRole == nsIAccessibleRole::ROLE_CELL ||
aRole == nsIAccessibleRole::ROLE_GRID_CELL))
return true;
if (aParentRole == nsIAccessibleRole::ROLE_LIST &&
aRole == nsIAccessibleRole::ROLE_LISTITEM)
return true;
if (aParentRole == nsIAccessibleRole::ROLE_COMBOBOX_LIST &&
aRole == nsIAccessibleRole::ROLE_COMBOBOX_OPTION)
return true;
if (aParentRole == nsIAccessibleRole::ROLE_LISTBOX &&
aRole == nsIAccessibleRole::ROLE_OPTION)
return true;
if (aParentRole == nsIAccessibleRole::ROLE_PAGETABLIST &&
aRole == nsIAccessibleRole::ROLE_PAGETAB)
return true;
if ((aParentRole == nsIAccessibleRole::ROLE_POPUP_MENU ||
aParentRole == nsIAccessibleRole::ROLE_MENUPOPUP) &&
aRole == nsIAccessibleRole::ROLE_MENUITEM)
return true;
return false;
}

View File

@ -52,7 +52,7 @@ public:
PRInt32 PosInSet() const { return mPosInSet; }
PRUint32 SetSize() const { return mSetSize; }
nsAccessible* GetConceptualParent() const { return mParent; }
nsAccessible* ConceptualParent() const { return mParent; }
/**
* Create group info.
@ -88,6 +88,12 @@ private:
return aRole;
}
/**
* Return true if the given parent role is conceptual parent of the given
* role.
*/
static bool IsConceptualParent(PRUint32 aRole, PRUint32 aParentRole);
PRUint32 mPosInSet;
PRUint32 mSetSize;
nsAccessible* mParent;

View File

@ -55,7 +55,7 @@
NotificationController::NotificationController(nsDocAccessible* aDocument,
nsIPresShell* aPresShell) :
mObservingState(eNotObservingRefresh), mDocument(aDocument),
mPresShell(aPresShell), mTreeConstructedState(eTreeConstructionPending)
mPresShell(aPresShell)
{
mTextHash.Init();
@ -154,10 +154,6 @@ NotificationController::ScheduleContentInsertion(nsAccessible* aContainer,
nsIContent* aStartChildNode,
nsIContent* aEndChildNode)
{
// Ignore content insertions until we constructed accessible tree.
if (mTreeConstructedState == eTreeConstructionPending)
return;
nsRefPtr<ContentInsertion> insertion = new ContentInsertion(mDocument,
aContainer);
if (insertion && insertion->InitChildList(aStartChildNode, aEndChildNode) &&
@ -207,7 +203,7 @@ NotificationController::WillRefresh(mozilla::TimeStamp aTime)
mObservingState = eRefreshProcessingForUpdate;
// Initial accessible tree construction.
if (mTreeConstructedState == eTreeConstructionPending) {
if (!mDocument->HasLoadState(nsDocAccessible::eTreeConstructed)) {
// If document is not bound to parent at this point then the document is not
// ready yet (process notifications later).
if (!mDocument->IsBoundToParent())
@ -218,8 +214,7 @@ NotificationController::WillRefresh(mozilla::TimeStamp aTime)
mDocument.get(), mDocument->GetDocumentNode());
#endif
mTreeConstructedState = eTreeConstructed;
mDocument->NotifyOfInitialUpdate();
mDocument->DoInitialUpdate();
NS_ASSERTION(mContentInsertions.Length() == 0,
"Pending content insertions while initial accessible tree isn't created!");
@ -250,8 +245,8 @@ NotificationController::WillRefresh(mozilla::TimeStamp aTime)
mTextHash.Clear();
// Bind hanging child documents.
PRUint32 childDocCount = mHangingChildDocuments.Length();
for (PRUint32 idx = 0; idx < childDocCount; idx++) {
PRUint32 hangingDocCnt = mHangingChildDocuments.Length();
for (PRUint32 idx = 0; idx < hangingDocCnt; idx++) {
nsDocAccessible* childDoc = mHangingChildDocuments[idx];
nsIContent* ownerContent = mDocument->GetDocumentNode()->
@ -271,6 +266,25 @@ NotificationController::WillRefresh(mozilla::TimeStamp aTime)
}
mHangingChildDocuments.Clear();
// If the document is ready and all its subdocuments are completely loaded
// then process the document load.
if (mDocument->HasLoadState(nsDocAccessible::eReady) &&
!mDocument->HasLoadState(nsDocAccessible::eCompletelyLoaded) &&
hangingDocCnt == 0) {
PRUint32 childDocCnt = mDocument->ChildDocumentCount(), childDocIdx = 0;
for (; childDocIdx < childDocCnt; childDocIdx++) {
nsDocAccessible* childDoc = mDocument->GetChildDocumentAt(childDocIdx);
if (!childDoc->HasLoadState(nsDocAccessible::eCompletelyLoaded))
break;
}
if (childDocIdx == childDocCnt) {
mDocument->ProcessLoad();
if (!mDocument)
return;
}
}
// Process only currently queued generic notifications.
nsTArray < nsRefPtr<Notification> > notifications;
notifications.SwapElements(mNotifications);
@ -310,10 +324,12 @@ NotificationController::WillRefresh(mozilla::TimeStamp aTime)
return;
}
// Stop further processing if there are no newly queued insertions,
// notifications or events.
// Stop further processing if there are no new notifications of any kind or
// events and document load is processed.
if (mContentInsertions.Length() == 0 && mNotifications.Length() == 0 &&
mEvents.Length() == 0 &&
mEvents.Length() == 0 && mTextHash.Count() == 0 &&
mHangingChildDocuments.Length() == 0 &&
mDocument->HasLoadState(nsDocAccessible::eCompletelyLoaded) &&
mPresShell->RemoveRefreshObserver(this, Flush_Display)) {
mObservingState = eNotObservingRefresh;
}

View File

@ -127,14 +127,6 @@ public:
NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(NotificationController)
/**
* Return true when tree is constructed.
*/
inline bool IsTreeConstructed()
{
return mTreeConstructedState == eTreeConstructed;
}
/**
* Shutdown the notification controller.
*/
@ -155,11 +147,8 @@ public:
*/
inline void ScheduleTextUpdate(nsIContent* aTextNode)
{
// Ignore the notification if initial tree construction hasn't been done yet.
if (mTreeConstructedState != eTreeConstructionPending &&
mTextHash.PutEntry(aTextNode)) {
if (mTextHash.PutEntry(aTextNode))
ScheduleProcessing();
}
}
/**
@ -299,17 +288,6 @@ private:
*/
nsIPresShell* mPresShell;
/**
* Indicate whether initial construction of the document's accessible tree
* performed or pending. When the document accessible is created then
* we construct its initial accessible tree.
*/
enum eTreeConstructedState {
eTreeConstructed,
eTreeConstructionPending
};
eTreeConstructedState mTreeConstructedState;
/**
* Child documents that needs to be bound to the tree.
*/

View File

@ -87,21 +87,6 @@ TextUpdater::DoUpdate(const nsAString& aNewText, const nsAString& aOldText,
PRUint32 oldLen = aOldText.Length(), newLen = aNewText.Length();
PRUint32 minLen = NS_MIN(oldLen, newLen);
// Text was appended or removed to/from the end.
if (aSkipStart == minLen) {
// If text has been appended to the end, fire text inserted event.
if (oldLen < newLen) {
UpdateTextNFireEvent(aNewText, Substring(aNewText, oldLen),
oldLen, PR_TRUE);
return;
}
// Text has been removed from the end, fire text removed event.
UpdateTextNFireEvent(aNewText, Substring(aOldText, newLen),
newLen, PR_FALSE);
return;
}
// Trim coinciding substrings from the end.
PRUint32 skipEnd = 0;
while (minLen - skipEnd > aSkipStart &&
@ -109,25 +94,6 @@ TextUpdater::DoUpdate(const nsAString& aNewText, const nsAString& aOldText,
skipEnd++;
}
// Text was appended or removed to/from the start.
if (skipEnd == minLen) {
// If text has been appended to the start, fire text inserted event.
if (oldLen < newLen) {
UpdateTextNFireEvent(aNewText, Substring(aNewText, 0, newLen - skipEnd),
0, PR_TRUE);
return;
}
// Text has been removed from the start, fire text removed event.
UpdateTextNFireEvent(aNewText, Substring(aOldText, 0, oldLen - skipEnd),
0, PR_FALSE);
return;
}
// Find the difference between strings and fire events.
// Note: we can skip initial and final coinciding characters since they don't
// affect the Levenshtein distance.
PRInt32 strLen1 = oldLen - aSkipStart - skipEnd;
PRInt32 strLen2 = newLen - aSkipStart - skipEnd;
@ -137,6 +103,42 @@ TextUpdater::DoUpdate(const nsAString& aNewText, const nsAString& aOldText,
// Increase offset of the text leaf on skipped characters amount.
mTextOffset += aSkipStart;
// It could be single insertion or removal or the case of long strings. Do not
// calculate the difference between long strings and prefer to fire pair of
// insert/remove events as the old string was replaced on the new one.
if (strLen1 == 0 || strLen2 == 0 ||
strLen1 > kMaxStrLen || strLen2 > kMaxStrLen) {
if (strLen1 > 0) {
// Fire text change event for removal.
nsRefPtr<AccEvent> textRemoveEvent =
new AccTextChangeEvent(mHyperText, mTextOffset, str1, PR_FALSE);
mDocument->FireDelayedAccessibleEvent(textRemoveEvent);
}
if (strLen2 > 0) {
// Fire text change event for insertion.
nsRefPtr<AccEvent> textInsertEvent =
new AccTextChangeEvent(mHyperText, mTextOffset, str2, PR_TRUE);
mDocument->FireDelayedAccessibleEvent(textInsertEvent);
}
// Fire value change event.
if (mHyperText->Role() == nsIAccessibleRole::ROLE_ENTRY) {
nsRefPtr<AccEvent> valueChangeEvent =
new AccEvent(nsIAccessibleEvent::EVENT_VALUE_CHANGE, mHyperText,
eAutoDetect, AccEvent::eRemoveDupes);
mDocument->FireDelayedAccessibleEvent(valueChangeEvent);
}
// Update the text.
mTextLeaf->SetText(aNewText);
return;
}
// Otherwise find the difference between strings and fire events.
// Note: we can skip initial and final coinciding characters since they don't
// affect the Levenshtein distance.
// Compute the flat structured matrix need to compute the difference.
PRUint32 len1 = strLen1 + 1, len2 = strLen2 + 1;
PRUint32* entries = new PRUint32[len1 * len2];
@ -238,27 +240,3 @@ TextUpdater::ComputeTextChangeEvents(const nsAString& aStr1,
if (colEnd)
FireDeleteEvent(Substring(aStr1, 0, colEnd), 0, aEvents);
}
void
TextUpdater::UpdateTextNFireEvent(const nsAString& aNewText,
const nsAString& aChangeText,
PRUint32 aAddlOffset,
PRBool aIsInserted)
{
// Fire text change event.
nsRefPtr<AccEvent> textChangeEvent =
new AccTextChangeEvent(mHyperText, mTextOffset + aAddlOffset, aChangeText,
aIsInserted);
mDocument->FireDelayedAccessibleEvent(textChangeEvent);
// Fire value change event.
if (mHyperText->Role() == nsIAccessibleRole::ROLE_ENTRY) {
nsRefPtr<AccEvent> valueChangeEvent =
new AccEvent(nsIAccessibleEvent::EVENT_VALUE_CHANGE, mHyperText,
eAutoDetect, AccEvent::eRemoveDupes);
mDocument->FireDelayedAccessibleEvent(valueChangeEvent);
}
// Update the text.
mTextLeaf->SetText(aNewText);
}

View File

@ -108,11 +108,10 @@ private:
}
/**
* Update the text and fire text change/value change events.
* The constant used to skip string difference calculation in case of long
* strings.
*/
void UpdateTextNFireEvent(const nsAString& aNewText,
const nsAString& aChangeText, PRUint32 aAddlOffset,
PRBool aIsInserted);
const static PRUint32 kMaxStrLen = 1 << 6;
private:
nsDocAccessible* mDocument;

View File

@ -106,7 +106,9 @@ nsARIAGridAccessible::GetColumnCount(PRInt32 *acolumnCount)
return NS_ERROR_FAILURE;
AccIterator rowIter(this, filters::GetRow);
nsAccessible *row = rowIter.GetNext();
nsAccessible* row = rowIter.GetNext();
if (!row)
return NS_OK;
AccIterator cellIter(row, filters::GetCell);
nsAccessible *cell = nsnull;

View File

@ -190,9 +190,6 @@ nsAccDocManager::OnStateChange(nsIWebProgress *aWebProgress,
NS_LOG_ACCDOCLOAD("start document loading", aWebProgress, aRequest,
aStateFlags)
if (!IsEventTargetDocument(document))
return NS_OK;
nsDocAccessible* docAcc = mDocAccessibleCache.GetWeak(document);
if (!docAcc)
return NS_OK;
@ -201,32 +198,17 @@ nsAccDocManager::OnStateChange(nsIWebProgress *aWebProgress,
nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(webNav));
NS_ENSURE_STATE(docShell);
// Fire reload and state busy events on existing document accessible while
// event from user input flag can be calculated properly and accessible
// is alive. When new document gets loaded then this one is destroyed.
bool isReloading = false;
PRUint32 loadType;
docShell->GetLoadType(&loadType);
if (loadType == LOAD_RELOAD_NORMAL ||
loadType == LOAD_RELOAD_BYPASS_CACHE ||
loadType == LOAD_RELOAD_BYPASS_PROXY ||
loadType == LOAD_RELOAD_BYPASS_PROXY_AND_CACHE) {
// Fire reload event.
nsRefPtr<AccEvent> reloadEvent =
new AccEvent(nsIAccessibleEvent::EVENT_DOCUMENT_RELOAD, docAcc);
nsEventShell::FireEvent(reloadEvent);
isReloading = true;
}
// Mark the document accessible as loading, if it stays alive then we'll mark
// it as loaded when we receive proper notification.
docAcc->MarkAsLoading();
// Fire state busy change event. Use delayed event since we don't care
// actually if event isn't delivered when the document goes away like a shot.
nsRefPtr<AccEvent> stateEvent =
new AccStateChangeEvent(document, states::BUSY, PR_TRUE);
docAcc->FireDelayedAccessibleEvent(stateEvent);
docAcc->NotifyOfLoading(isReloading);
return NS_OK;
}
@ -338,54 +320,7 @@ nsAccDocManager::HandleDOMDocumentLoad(nsIDocument *aDocument,
return;
}
// Mark the document as loaded to drop off the busy state flag on it.
docAcc->MarkAsLoaded();
// Do not fire document complete/stop events for root chrome document
// accessibles and for frame/iframe documents because
// a) screen readers start working on focus event in the case of root chrome
// documents
// b) document load event on sub documents causes screen readers to act is if
// entire page is reloaded.
if (!IsEventTargetDocument(aDocument))
return;
// Fire complete/load stopped if the load event type is given.
if (aLoadEventType) {
nsRefPtr<AccEvent> loadEvent = new AccEvent(aLoadEventType, aDocument);
docAcc->FireDelayedAccessibleEvent(loadEvent);
}
// Fire busy state change event.
nsRefPtr<AccEvent> stateEvent =
new AccStateChangeEvent(aDocument, states::BUSY, PR_FALSE);
docAcc->FireDelayedAccessibleEvent(stateEvent);
}
PRBool
nsAccDocManager::IsEventTargetDocument(nsIDocument *aDocument) const
{
nsCOMPtr<nsISupports> container = aDocument->GetContainer();
nsCOMPtr<nsIDocShellTreeItem> docShellTreeItem =
do_QueryInterface(container);
NS_ASSERTION(docShellTreeItem, "No document shell for document!");
nsCOMPtr<nsIDocShellTreeItem> parentTreeItem;
docShellTreeItem->GetParent(getter_AddRefs(parentTreeItem));
// It's not a root document.
if (parentTreeItem) {
nsCOMPtr<nsIDocShellTreeItem> sameTypeRoot;
docShellTreeItem->GetSameTypeRootTreeItem(getter_AddRefs(sameTypeRoot));
// It's not a sub document, i.e. a frame or iframe.
return (sameTypeRoot == docShellTreeItem);
}
// It's not chrome root document.
PRInt32 contentType;
docShellTreeItem->GetItemType(&contentType);
return (contentType == nsIDocShellTreeItem::typeContent);
docAcc->NotifyOfLoad(aLoadEventType);
}
void

View File

@ -120,24 +120,6 @@ private:
void HandleDOMDocumentLoad(nsIDocument *aDocument,
PRUint32 aLoadEventType);
/**
* Return true if accessibility events accompanying document accessible
* loading should be fired.
*
* The rules are: do not fire events for root chrome document accessibles and
* for sub document accessibles (like HTML frame of iframe) of the loading
* document accessible.
*
* XXX: in general AT expect events for document accessible loading into
* tabbrowser, events from other document accessibles may break AT. We need to
* figure out what AT wants to know about loading page (for example, some of
* them have separate processing of iframe documents on the page and therefore
* they need a way to distinguish sub documents from page document). Ideally
* we should make events firing for any loaded document and provide additional
* info AT are needing.
*/
PRBool IsEventTargetDocument(nsIDocument *aDocument) const;
/**
* Add 'pagehide' and 'DOMContentLoaded' event listeners.
*/

View File

@ -43,7 +43,7 @@
It is designed to be used as inline input to nsAccessibilityAtoms.cpp *only*
through the magic of C preprocessing.
All entires must be enclosed in the macro ACCESSIBILITY_ATOM which will have cruel
All entries must be enclosed in the macro ACCESSIBILITY_ATOM which will have cruel
and unusual things done to it
It is recommended (but not strictly necessary) to keep all entries

View File

@ -663,6 +663,11 @@ PRUint64
nsAccessible::NativeState()
{
PRUint64 state = 0;
nsDocAccessible* document = GetDocAccessible();
if (!document || !document->IsInDocument(this))
state |= states::STALE;
PRBool disabled = PR_FALSE;
if (mContent->IsElement()) {
nsEventStates elementState = mContent->AsElement()->State();
@ -1849,22 +1854,23 @@ nsAccessible::NativeRole()
// readonly attribute PRUint8 numActions
NS_IMETHODIMP
nsAccessible::GetNumActions(PRUint8 *aNumActions)
nsAccessible::GetNumActions(PRUint8* aActionCount)
{
NS_ENSURE_ARG_POINTER(aNumActions);
*aNumActions = 0;
NS_ENSURE_ARG_POINTER(aActionCount);
*aActionCount = 0;
if (IsDefunct())
return NS_ERROR_FAILURE;
PRUint32 actionRule = GetActionRule(State());
if (actionRule == eNoAction)
return NS_OK;
*aNumActions = 1;
*aActionCount = ActionCount();
return NS_OK;
}
PRUint8
nsAccessible::ActionCount()
{
return GetActionRule(State()) == eNoAction ? 0 : 1;
}
/* DOMString getAccActionName (in PRUint8 index); */
NS_IMETHODIMP
nsAccessible::GetActionName(PRUint8 aIndex, nsAString& aName)
@ -2140,7 +2146,7 @@ nsAccessible::GetRelationByType(PRUint32 aRelationType,
return NS_OK_NO_RELATION_TARGET;
return nsRelUtils::AddTarget(aRelationType, aRelation,
groupInfo->GetConceptualParent());
groupInfo->ConceptualParent());
}
// If accessible is in its own Window, or is the root of a document,

View File

@ -418,6 +418,11 @@ public:
//////////////////////////////////////////////////////////////////////////////
// ActionAccessible
/**
* Return the number of actions that can be performed on this accessible.
*/
virtual PRUint8 ActionCount();
/**
* Return access key, such as Alt+D.
*/
@ -676,7 +681,7 @@ protected:
/**
* Return the action rule based on ARIA enum constants EActionRule
* (see nsARIAMap.h). Used by GetNumActions() and GetActionName().
* (see nsARIAMap.h). Used by ActionCount() and GetActionName().
*
* @param aStates [in] states of the accessible
*/

View File

@ -237,12 +237,10 @@ nsApplicationAccessible::TakeFocus()
return NS_OK;
}
NS_IMETHODIMP
nsApplicationAccessible::GetNumActions(PRUint8 *aNumActions)
PRUint8
nsApplicationAccessible::ActionCount()
{
NS_ENSURE_ARG_POINTER(aNumActions);
*aNumActions = 0;
return NS_OK;
return 0;
}
NS_IMETHODIMP

View File

@ -103,7 +103,6 @@ public:
NS_IMETHOD SetSelected(PRBool aIsSelected);
NS_IMETHOD TakeSelection();
NS_IMETHOD TakeFocus();
NS_IMETHOD GetNumActions(PRUint8 *aNumActions);
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString &aName);
NS_IMETHOD GetActionDescription(PRUint8 aIndex, nsAString &aDescription);
NS_IMETHOD DoAction(PRUint8 aIndex);
@ -129,6 +128,7 @@ public:
virtual void InvalidateChildren();
// ActionAccessible
virtual PRUint8 ActionCount();
virtual KeyBinding AccessKey() const;
protected:

View File

@ -138,13 +138,10 @@ nsLinkableAccessible::GetValue(nsAString& aValue)
}
NS_IMETHODIMP
nsLinkableAccessible::GetNumActions(PRUint8 *aNumActions)
PRUint8
nsLinkableAccessible::ActionCount()
{
NS_ENSURE_ARG_POINTER(aNumActions);
*aNumActions = (mIsOnclick || mIsLink) ? 1 : 0;
return NS_OK;
return (mIsOnclick || mIsLink) ? 1 : 0;
}
NS_IMETHODIMP

View File

@ -87,7 +87,6 @@ public:
NS_DECL_ISUPPORTS_INHERITED
// nsIAccessible
NS_IMETHOD GetNumActions(PRUint8 *_retval);
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
NS_IMETHOD DoAction(PRUint8 index);
NS_IMETHOD GetValue(nsAString& _retval);
@ -100,6 +99,7 @@ public:
virtual PRUint64 NativeState();
// ActionAccessible
virtual PRUint8 ActionCount();
virtual KeyBinding AccessKey() const;
// HyperLinkAccessible

View File

@ -105,7 +105,8 @@ nsDocAccessible::
nsDocAccessible(nsIDocument *aDocument, nsIContent *aRootContent,
nsIWeakReference *aShell) :
nsHyperTextAccessibleWrap(aRootContent, aShell),
mDocument(aDocument), mScrollPositionChangedTicks(0), mIsLoaded(PR_FALSE)
mDocument(aDocument), mScrollPositionChangedTicks(0),
mLoadState(eTreeConstructionPending), mLoadEventType(0)
{
mFlags |= eDocAccessible;
@ -309,11 +310,16 @@ nsDocAccessible::NativeState()
state |= states::FOCUSED;
}
// Expose state busy until the document is loaded or tree is constructed.
if (!mIsLoaded || !mNotificationController->IsTreeConstructed()) {
state |= states::BUSY | states::STALE;
}
// Expose stale state until the document is ready (DOM is loaded and tree is
// constructed).
if (!HasLoadState(eReady))
state |= states::STALE;
// Expose state busy until the document and all its subdocuments is completely
// loaded.
if (!HasLoadState(eCompletelyLoaded))
state |= states::BUSY;
nsIFrame* frame = GetFrame();
if (!frame || !nsCoreUtils::CheckVisibilityInParentChain(frame)) {
state |= states::INVISIBLE | states::OFFSCREEN;
@ -605,7 +611,7 @@ nsDocAccessible::Init()
// this point (this can happen because a11y is started late or DOM document
// having no container was loaded.
if (mDocument->GetReadyStateEnum() == nsIDocument::READYSTATE_COMPLETE)
mIsLoaded = PR_TRUE;
mLoadState |= eDOMLoaded;
AddEventListeners();
return PR_TRUE;
@ -1376,8 +1382,9 @@ nsDocAccessible::ContentInserted(nsIContent* aContainerNode,
nsIContent* aStartChildNode,
nsIContent* aEndChildNode)
{
/// Pend tree update on content insertion until layout.
if (mNotificationController) {
// Ignore content insertions until we constructed accessible tree. Otherwise
// schedule tree update on content insertion after layout.
if (mNotificationController && HasLoadState(eTreeConstructed)) {
// Update the whole tree of this document accessible when the container is
// null (document element is inserted or removed).
nsAccessible* container = aContainerNode ?
@ -1467,8 +1474,36 @@ nsDocAccessible::CacheChildren()
// Protected members
void
nsDocAccessible::NotifyOfInitialUpdate()
nsDocAccessible::NotifyOfLoading(bool aIsReloading)
{
// Mark the document accessible as loading, if it stays alive then we'll mark
// it as loaded when we receive proper notification.
mLoadState &= ~eDOMLoaded;
if (!IsLoadEventTarget())
return;
if (aIsReloading) {
// Fire reload and state busy events on existing document accessible while
// event from user input flag can be calculated properly and accessible
// is alive. When new document gets loaded then this one is destroyed.
nsRefPtr<AccEvent> reloadEvent =
new AccEvent(nsIAccessibleEvent::EVENT_DOCUMENT_RELOAD, this);
nsEventShell::FireEvent(reloadEvent);
}
// Fire state busy change event. Use delayed event since we don't care
// actually if event isn't delivered when the document goes away like a shot.
nsRefPtr<AccEvent> stateEvent =
new AccStateChangeEvent(mDocument, states::BUSY, PR_TRUE);
FireDelayedAccessibleEvent(stateEvent);
}
void
nsDocAccessible::DoInitialUpdate()
{
mLoadState |= eTreeConstructed;
// 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.
@ -1491,6 +1526,34 @@ nsDocAccessible::NotifyOfInitialUpdate()
}
}
void
nsDocAccessible::ProcessLoad()
{
mLoadState |= eCompletelyLoaded;
// Do not fire document complete/stop events for root chrome document
// accessibles and for frame/iframe documents because
// a) screen readers start working on focus event in the case of root chrome
// documents
// b) document load event on sub documents causes screen readers to act is if
// entire page is reloaded.
if (!IsLoadEventTarget())
return;
// Fire complete/load stopped if the load event type is given.
if (mLoadEventType) {
nsRefPtr<AccEvent> loadEvent = new AccEvent(mLoadEventType, this);
nsEventShell::FireEvent(loadEvent);
mLoadEventType = 0;
}
// Fire busy state change event.
nsRefPtr<AccEvent> stateEvent =
new AccStateChangeEvent(this, states::BUSY, PR_FALSE);
nsEventShell::FireEvent(stateEvent);
}
void
nsDocAccessible::AddDependentIDsFor(nsAccessible* aRelProvider,
nsIAtom* aRelAttr)
@ -1964,3 +2027,30 @@ nsDocAccessible::ShutdownChildrenInSubtree(nsAccessible* aAccessible)
UnbindFromDocument(aAccessible);
}
bool
nsDocAccessible::IsLoadEventTarget() const
{
nsCOMPtr<nsISupports> container = mDocument->GetContainer();
nsCOMPtr<nsIDocShellTreeItem> docShellTreeItem =
do_QueryInterface(container);
NS_ASSERTION(docShellTreeItem, "No document shell for document!");
nsCOMPtr<nsIDocShellTreeItem> parentTreeItem;
docShellTreeItem->GetParent(getter_AddRefs(parentTreeItem));
// It's not a root document.
if (parentTreeItem) {
nsCOMPtr<nsIDocShellTreeItem> sameTypeRoot;
docShellTreeItem->GetSameTypeRootTreeItem(getter_AddRefs(sameTypeRoot));
// It's not a sub document, i.e. a frame or iframe.
return (sameTypeRoot == docShellTreeItem);
}
// It's not chrome root document.
PRInt32 contentType;
docShellTreeItem->GetItemType(&contentType);
return (contentType == nsIDocShellTreeItem::typeContent);
}

View File

@ -134,19 +134,34 @@ public:
*/
PRBool IsContentLoaded() const
{
// eDOMLoaded flag check is used for error pages as workaround to make this
// method return correct result since error pages do not receive 'pageshow'
// event and as consequence nsIDocument::IsShowing() returns false.
return mDocument && mDocument->IsVisible() &&
(mDocument->IsShowing() || mIsLoaded);
(mDocument->IsShowing() || HasLoadState(eDOMLoaded));
}
/**
* Marks this document as loaded or loading, used to expose busy state.
* The loaded flag has special meaning for error pages and used as workaround
* to make IsContentLoaded() return correct result since these pages do not
* receive pageshow event and as consequence nsIDocument::IsShowing() returns
* false.
* Document load states.
*/
void MarkAsLoaded() { mIsLoaded = PR_TRUE; }
void MarkAsLoading() { mIsLoaded = PR_FALSE; }
enum LoadState {
// initial tree construction is pending
eTreeConstructionPending = 0,
// initial tree construction done
eTreeConstructed = 1,
// DOM document is loaded.
eDOMLoaded = 1 << 1,
// document is ready
eReady = eTreeConstructed | eDOMLoaded,
// document and all its subdocuments are ready
eCompletelyLoaded = eReady | 1 << 2
};
/**
* Return true if the document has given document state.
*/
bool HasLoadState(LoadState aState) const
{ return (mLoadState & aState) == aState; }
/**
* Return a native window handler or pointer depending on platform.
@ -235,9 +250,19 @@ public:
/**
* Return whether the given DOM node has an accessible or not.
*/
inline bool HasAccessible(nsINode* aNode)
inline bool HasAccessible(nsINode* aNode) const
{ return GetAccessible(aNode); }
/**
* Return true if the given accessible is in document.
*/
inline bool IsInDocument(nsAccessible* aAccessible) const
{
return GetAccessible(aNode);
nsAccessible* acc = aAccessible;
while (acc && !acc->IsPrimaryForNode())
acc = acc->Parent();
return acc ? mNodeToAccessibleMap.Get(acc->GetNode()) : false;
}
/**
@ -316,7 +341,8 @@ public:
{
NS_ASSERTION(mNotificationController, "The document was shut down!");
if (mNotificationController)
// Ignore the notification if initial tree construction hasn't been done yet.
if (mNotificationController && HasLoadState(eTreeConstructed))
mNotificationController->ScheduleTextUpdate(aTextNode);
}
@ -336,10 +362,29 @@ protected:
virtual nsresult RemoveEventListeners();
/**
* Notify this document that was bound to the accessible document tree.
* Marks this document as loaded or loading.
*/
inline void NotifyOfLoad(PRUint32 aLoadEventType)
{
mLoadState |= eDOMLoaded;
mLoadEventType = aLoadEventType;
}
void NotifyOfLoading(bool aIsReloading);
friend class nsAccDocManager;
/**
* Perform initial update (create accessible tree).
* Can be overridden by wrappers to prepare initialization work.
*/
virtual void NotifyOfInitialUpdate();
virtual void DoInitialUpdate();
/**
* Process document load notification, fire document load and state busy
* events if applicable.
*/
void ProcessLoad();
void AddScrollListener();
void RemoveScrollListener();
@ -473,6 +518,24 @@ protected:
*/
void ShutdownChildrenInSubtree(nsAccessible *aAccessible);
/**
* Return true if accessibility events accompanying document accessible
* loading should be fired.
*
* The rules are: do not fire events for root chrome document accessibles and
* for sub document accessibles (like HTML frame of iframe) of the loading
* document accessible.
*
* XXX: in general AT expect events for document accessible loading into
* tabbrowser, events from other document accessibles may break AT. We need to
* figure out what AT wants to know about loading page (for example, some of
* them have separate processing of iframe documents on the page and therefore
* they need a way to distinguish sub documents from page document). Ideally
* we should make events firing for any loaded document and provide additional
* info AT are needing.
*/
bool IsLoadEventTarget() const;
/**
* Used to fire scrolling end event after page scroll.
*
@ -481,6 +544,8 @@ protected:
*/
static void ScrollTimerCallback(nsITimer* aTimer, void* aClosure);
protected:
/**
* Cache of accessibles within this document accessible.
*/
@ -492,12 +557,15 @@ protected:
nsCOMPtr<nsITimer> mScrollWatchTimer;
PRUint16 mScrollPositionChangedTicks; // Used for tracking scroll events
protected:
/**
* Bit mask of document load states (@see LoadState).
*/
PRUint32 mLoadState;
/**
* Specifies if the document was loaded, used for error pages only.
* Type of document load event fired after the document is loaded completely.
*/
PRPackedBool mIsLoaded;
PRUint32 mLoadEventType;
static PRUint64 gLastFocusedAccessiblesState;

View File

@ -191,13 +191,10 @@ nsRadioButtonAccessible::
{
}
NS_IMETHODIMP
nsRadioButtonAccessible::GetNumActions(PRUint8 *aNumActions)
PRUint8
nsRadioButtonAccessible::ActionCount()
{
NS_ENSURE_ARG_POINTER(aNumActions);
*aNumActions = 1;
return NS_OK;
return 1;
}
NS_IMETHODIMP nsRadioButtonAccessible::GetActionName(PRUint8 aIndex, nsAString& aName)

View File

@ -75,13 +75,15 @@ public:
nsRadioButtonAccessible(nsIContent *aContent, nsIWeakReference *aShell);
// nsIAccessible
NS_IMETHOD GetNumActions(PRUint8 *_retval);
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
NS_IMETHOD DoAction(PRUint8 aIndex);
// nsAccessible
virtual PRUint32 NativeRole();
// ActionAccessible
virtual PRUint8 ActionCount();
enum { eAction_Click = 0 };
};

View File

@ -112,14 +112,11 @@ nsOuterDocAccessible::GetAttributesInternal(nsIPersistentProperties *aAttributes
////////////////////////////////////////////////////////////////////////////////
// nsIAccessible
NS_IMETHODIMP
nsOuterDocAccessible::GetNumActions(PRUint8 *aNumActions)
PRUint8
nsOuterDocAccessible::ActionCount()
{
NS_ENSURE_ARG_POINTER(aNumActions);
*aNumActions = 0;
// Internal frame, which is the doc's parent, should not have a click action.
return NS_OK;
return 0;
}
NS_IMETHODIMP

View File

@ -58,7 +58,6 @@ public:
NS_DECL_ISUPPORTS_INHERITED
// nsIAccessible
NS_IMETHOD GetNumActions(PRUint8 *aNumActions);
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
NS_IMETHOD GetActionDescription(PRUint8 aIndex, nsAString& aDescription);
NS_IMETHOD DoAction(PRUint8 aIndex);
@ -77,6 +76,9 @@ public:
virtual PRBool AppendChild(nsAccessible *aAccessible);
virtual PRBool RemoveChild(nsAccessible *aAccessible);
// ActionAccessible
virtual PRUint8 ActionCount();
protected:
// nsAccessible
virtual void CacheChildren();

View File

@ -49,8 +49,7 @@
#include "nsHashtable.h"
#include "nsCaretAccessible.h"
#include "nsIDocument.h"
#include "nsIDOMFocusListener.h"
#include "nsIDOMFormListener.h"
#include "nsIDOMEventListener.h"
#define NS_ROOTACCESSIBLE_IMPL_CID \
{ /* eaba2cf0-21b1-4e2b-b711-d3a89dcd5e1a */ \

View File

@ -78,10 +78,10 @@ nsHTMLCheckboxAccessible::NativeRole()
return nsIAccessibleRole::ROLE_CHECKBUTTON;
}
NS_IMETHODIMP nsHTMLCheckboxAccessible::GetNumActions(PRUint8 *_retval)
PRUint8
nsHTMLCheckboxAccessible::ActionCount()
{
*_retval = 1;
return NS_OK;
return 1;
}
NS_IMETHODIMP nsHTMLCheckboxAccessible::GetActionName(PRUint8 aIndex, nsAString& aName)
@ -237,10 +237,10 @@ nsHTMLButtonAccessible::
{
}
NS_IMETHODIMP nsHTMLButtonAccessible::GetNumActions(PRUint8 *_retval)
PRUint8
nsHTMLButtonAccessible::ActionCount()
{
*_retval = 1;
return NS_OK;
return 1;
}
NS_IMETHODIMP nsHTMLButtonAccessible::GetActionName(PRUint8 aIndex, nsAString& aName)
@ -325,10 +325,10 @@ nsHTML4ButtonAccessible::
{
}
NS_IMETHODIMP nsHTML4ButtonAccessible::GetNumActions(PRUint8 *_retval)
PRUint8
nsHTML4ButtonAccessible::ActionCount()
{
*_retval = 1;
return NS_OK;;
return 1;
}
NS_IMETHODIMP nsHTML4ButtonAccessible::GetActionName(PRUint8 aIndex, nsAString& aName)
@ -514,10 +514,10 @@ nsHTMLTextFieldAccessible::NativeState()
return state;
}
NS_IMETHODIMP nsHTMLTextFieldAccessible::GetNumActions(PRUint8 *_retval)
PRUint8
nsHTMLTextFieldAccessible::ActionCount()
{
*_retval = 1;
return NS_OK;;
return 1;
}
NS_IMETHODIMP nsHTMLTextFieldAccessible::GetActionName(PRUint8 aIndex, nsAString& aName)

View File

@ -59,13 +59,15 @@ public:
nsHTMLCheckboxAccessible(nsIContent *aContent, nsIWeakReference *aShell);
// nsIAccessible
NS_IMETHOD GetNumActions(PRUint8 *_retval);
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
NS_IMETHOD DoAction(PRUint8 index);
// nsAccessible
virtual PRUint32 NativeRole();
virtual PRUint64 NativeState();
// ActionAccessible
virtual PRUint8 ActionCount();
};
@ -98,7 +100,6 @@ public:
nsHTMLButtonAccessible(nsIContent *aContent, nsIWeakReference *aShell);
// nsIAccessible
NS_IMETHOD GetNumActions(PRUint8 *_retval);
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
NS_IMETHOD DoAction(PRUint8 index);
@ -106,6 +107,9 @@ public:
virtual nsresult GetNameInternal(nsAString& aName);
virtual PRUint32 NativeRole();
virtual PRUint64 NativeState();
// ActionAccessible
virtual PRUint8 ActionCount();
};
@ -121,13 +125,15 @@ public:
nsHTML4ButtonAccessible(nsIContent *aContent, nsIWeakReference *aShell);
// nsIAccessible
NS_IMETHOD GetNumActions(PRUint8 *_retval);
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
NS_IMETHOD DoAction(PRUint8 index);
// nsAccessible
virtual PRUint32 NativeRole();
virtual PRUint64 NativeState();
// ActionAccessible
virtual PRUint8 ActionCount();
};
@ -146,7 +152,6 @@ public:
// nsIAccessible
NS_IMETHOD GetValue(nsAString& _retval);
NS_IMETHOD GetNumActions(PRUint8 *_retval);
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
NS_IMETHOD DoAction(PRUint8 index);
@ -157,6 +162,9 @@ public:
virtual nsresult GetNameInternal(nsAString& aName);
virtual PRUint32 NativeRole();
virtual PRUint64 NativeState();
// ActionAccessible
virtual PRUint8 ActionCount();
};

View File

@ -131,22 +131,11 @@ nsHTMLImageAccessible::NativeRole()
////////////////////////////////////////////////////////////////////////////////
// nsIAccessible
NS_IMETHODIMP
nsHTMLImageAccessible::GetNumActions(PRUint8 *aNumActions)
PRUint8
nsHTMLImageAccessible::ActionCount()
{
NS_ENSURE_ARG_POINTER(aNumActions);
*aNumActions = 0;
if (IsDefunct())
return NS_ERROR_FAILURE;
nsresult rv= nsLinkableAccessible::GetNumActions(aNumActions);
NS_ENSURE_SUCCESS(rv, rv);
if (HasLongDesc())
(*aNumActions)++;
return NS_OK;
PRUint8 actionCount = nsLinkableAccessible::ActionCount();
return HasLongDesc() ? actionCount + 1 : actionCount;
}
NS_IMETHODIMP
@ -248,9 +237,5 @@ nsHTMLImageAccessible::IsValidLongDescIndex(PRUint8 aIndex)
if (!HasLongDesc())
return PR_FALSE;
PRUint8 numActions = 0;
nsresult rv = nsLinkableAccessible::GetNumActions(&numActions);
NS_ENSURE_SUCCESS(rv, PR_FALSE);
return (aIndex == numActions);
return aIndex == nsLinkableAccessible::ActionCount();
}

View File

@ -57,7 +57,6 @@ public:
NS_DECL_ISUPPORTS_INHERITED
// nsIAccessible
NS_IMETHOD GetNumActions(PRUint8 *aNumActions);
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
NS_IMETHOD DoAction(PRUint8 index);
@ -70,6 +69,9 @@ public:
virtual PRUint64 NativeState();
virtual nsresult GetAttributesInternal(nsIPersistentProperties *aAttributes);
// ActionAccessible
virtual PRUint8 ActionCount();
private:
/**
* Determine if this image accessible has a longdesc attribute.

View File

@ -120,16 +120,10 @@ nsHTMLLinkAccessible::GetValue(nsAString& aValue)
return presShell->GetLinkLocation(DOMNode, aValue);
}
NS_IMETHODIMP
nsHTMLLinkAccessible::GetNumActions(PRUint8 *aNumActions)
PRUint8
nsHTMLLinkAccessible::ActionCount()
{
NS_ENSURE_ARG_POINTER(aNumActions);
if (!IsLinked())
return nsHyperTextAccessible::GetNumActions(aNumActions);
*aNumActions = 1;
return NS_OK;
return IsLinked() ? 1 : nsHyperTextAccessible::ActionCount();
}
NS_IMETHODIMP

View File

@ -52,7 +52,6 @@ public:
// nsIAccessible
NS_IMETHOD GetValue(nsAString& aValue);
NS_IMETHOD GetNumActions(PRUint8 *aNumActions);
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
NS_IMETHOD DoAction(PRUint8 aIndex);
@ -60,6 +59,9 @@ public:
virtual PRUint32 NativeRole();
virtual PRUint64 NativeState();
// ActionAccessible
virtual PRUint8 ActionCount();
// HyperLinkAccessible
virtual bool IsLink();
virtual already_AddRefed<nsIURI> AnchorURIAt(PRUint32 aAnchorIndex);

View File

@ -371,10 +371,10 @@ NS_IMETHODIMP nsHTMLSelectOptionAccessible::GetActionName(PRUint8 aIndex, nsAStr
return NS_ERROR_INVALID_ARG;
}
NS_IMETHODIMP nsHTMLSelectOptionAccessible::GetNumActions(PRUint8 *_retval)
PRUint8
nsHTMLSelectOptionAccessible::ActionCount()
{
*_retval = 1;
return NS_OK;
return 1;
}
NS_IMETHODIMP nsHTMLSelectOptionAccessible::DoAction(PRUint8 index)
@ -616,9 +616,10 @@ NS_IMETHODIMP nsHTMLSelectOptGroupAccessible::GetActionName(PRUint8 aIndex, nsAS
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsHTMLSelectOptGroupAccessible::GetNumActions(PRUint8 *_retval)
PRUint8
nsHTMLSelectOptGroupAccessible::ActionCount()
{
return NS_ERROR_NOT_IMPLEMENTED;
return 0;
}
////////////////////////////////////////////////////////////////////////////////
@ -773,11 +774,10 @@ NS_IMETHODIMP nsHTMLComboboxAccessible::GetValue(nsAString& aValue)
return option ? option->GetName(aValue) : NS_OK;
}
/** Just one action ( click ). */
NS_IMETHODIMP nsHTMLComboboxAccessible::GetNumActions(PRUint8 *aNumActions)
PRUint8
nsHTMLComboboxAccessible::ActionCount()
{
*aNumActions = 1;
return NS_OK;
return 1;
}
/**

View File

@ -108,7 +108,6 @@ public:
// nsIAccessible
NS_IMETHOD DoAction(PRUint8 index);
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
NS_IMETHOD GetNumActions(PRUint8 *_retval);
NS_IMETHOD SetSelected(PRBool aSelect);
// nsAccessible
@ -120,6 +119,9 @@ public:
virtual void GetPositionAndSizeInternal(PRInt32 *aPosInSet,
PRInt32 *aSetSize);
// ActionAccessible
virtual PRUint8 ActionCount();
/**
* Return focused option if any.
*/
@ -154,12 +156,14 @@ public:
// nsIAccessible
NS_IMETHOD DoAction(PRUint8 index);
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
NS_IMETHOD GetNumActions(PRUint8 *_retval);
// nsAccessible
virtual PRUint32 NativeRole();
virtual PRUint64 NativeState();
// ActionAccessible
virtual PRUint8 ActionCount();
protected:
// nsAccessible
virtual void CacheChildren();
@ -185,7 +189,6 @@ public:
// nsIAccessible
NS_IMETHOD GetValue(nsAString& _retval);
NS_IMETHOD DoAction(PRUint8 index);
NS_IMETHOD GetNumActions(PRUint8 *aNumActions);
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
// nsAccessNode
@ -197,6 +200,9 @@ public:
virtual PRUint64 NativeState();
virtual void InvalidateChildren();
// ActionAccessible
virtual PRUint8 ActionCount();
protected:
// nsAccessible
virtual void CacheChildren();

View File

@ -63,21 +63,19 @@ CAccessibleAction::QueryInterface(REFIID iid, void** ppv)
// IAccessibleAction
STDMETHODIMP
CAccessibleAction::nActions(long *aNumActions)
CAccessibleAction::nActions(long* aActionCount)
{
__try {
*aNumActions = 0;
if (!aActionCount)
return E_INVALIDARG;
nsCOMPtr<nsIAccessible> acc(do_QueryObject(this));
if (!acc)
*aActionCount = 0;
nsRefPtr<nsAccessible> acc(do_QueryObject(this));
if (!acc || acc->IsDefunct())
return E_FAIL;
PRUint8 count = 0;
nsresult rv = acc->GetNumActions(&count);
if (NS_FAILED(rv))
return GetHRESULT(rv);
*aNumActions = count;
*aActionCount = acc->ActionCount();
return S_OK;
} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }

View File

@ -234,9 +234,16 @@ __try {
STDMETHODIMP nsAccessibleWrap::get_accChildCount( long __RPC_FAR *pcountChildren)
{
__try {
if (!pcountChildren)
return E_INVALIDARG;
*pcountChildren = 0;
if (IsDefunct())
return E_FAIL;
if (nsAccUtils::MustPrune(this))
return NS_OK;
return S_OK;
*pcountChildren = GetChildCount();
} __except(FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }

View File

@ -268,9 +268,9 @@ nsDocAccessibleWrap::GetNativeWindow() const
// nsDocAccessible protected
void
nsDocAccessibleWrap::NotifyOfInitialUpdate()
nsDocAccessibleWrap::DoInitialUpdate()
{
nsDocAccessible::NotifyOfInitialUpdate();
nsDocAccessible::DoInitialUpdate();
if (nsWinUtils::IsWindowEmulationStarted()) {
// Create window for tab document.

View File

@ -97,7 +97,7 @@ public:
protected:
// nsDocAccessible
virtual void NotifyOfInitialUpdate();
virtual void DoInitialUpdate();
protected:
void* mHWND;

View File

@ -545,13 +545,10 @@ nsXFormsSelectableItemAccessible::GetValue(nsAString& aValue)
return sXFormsService->GetValue(DOMNode, aValue);
}
NS_IMETHODIMP
nsXFormsSelectableItemAccessible::GetNumActions(PRUint8 *aCount)
PRUint8
nsXFormsSelectableItemAccessible::ActionCount()
{
NS_ENSURE_ARG_POINTER(aCount);
*aCount = 1;
return NS_OK;
return 1;
}
NS_IMETHODIMP

View File

@ -190,9 +190,11 @@ public:
nsIWeakReference *aShell);
NS_IMETHOD GetValue(nsAString& aValue);
NS_IMETHOD GetNumActions(PRUint8 *aCount);
NS_IMETHOD DoAction(PRUint8 aIndex);
// ActionAccessible
virtual PRUint8 ActionCount();
protected:
bool IsSelected();
};

View File

@ -115,13 +115,10 @@ nsXFormsTriggerAccessible::GetValue(nsAString& aValue)
return NS_OK;
}
NS_IMETHODIMP
nsXFormsTriggerAccessible::GetNumActions(PRUint8 *aCount)
PRUint8
nsXFormsTriggerAccessible::ActionCount()
{
NS_ENSURE_ARG_POINTER(aCount);
*aCount = 1;
return NS_OK;
return 1;
}
NS_IMETHODIMP
@ -163,13 +160,10 @@ nsXFormsInputAccessible::NativeRole()
return nsIAccessibleRole::ROLE_ENTRY;
}
NS_IMETHODIMP
nsXFormsInputAccessible::GetNumActions(PRUint8* aCount)
PRUint8
nsXFormsInputAccessible::ActionCount()
{
NS_ENSURE_ARG_POINTER(aCount);
*aCount = 1;
return NS_OK;
return 1;
}
NS_IMETHODIMP
@ -225,13 +219,10 @@ nsXFormsInputBooleanAccessible::NativeState()
return state;
}
NS_IMETHODIMP
nsXFormsInputBooleanAccessible::GetNumActions(PRUint8 *aCount)
PRUint8
nsXFormsInputBooleanAccessible::ActionCount()
{
NS_ENSURE_ARG_POINTER(aCount);
*aCount = 1;
return NS_OK;
return 1;
}
NS_IMETHODIMP

View File

@ -81,12 +81,14 @@ public:
// nsIAccessible
NS_IMETHOD GetValue(nsAString& aValue);
NS_IMETHOD GetNumActions(PRUint8 *aCount);
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
NS_IMETHOD DoAction(PRUint8 aIndex);
// nsAccessible
virtual PRUint32 NativeRole();
// ActionAccessible
virtual PRUint8 ActionCount();
};
/**
@ -101,12 +103,14 @@ public:
NS_DECL_ISUPPORTS_INHERITED
// nsIAccessible
NS_IMETHOD GetNumActions(PRUint8 *aCount);
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
NS_IMETHOD DoAction(PRUint8 aIndex);
// nsAccessible
virtual PRUint32 NativeRole();
// ActionAccessible
virtual PRUint8 ActionCount();
};
/**
@ -119,13 +123,15 @@ public:
nsXFormsInputBooleanAccessible(nsIContent *aContent, nsIWeakReference *aShell);
// nsIAccessible
NS_IMETHOD GetNumActions(PRUint8 *aCount);
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
NS_IMETHOD DoAction(PRUint8 aIndex);
// nsAccessible
virtual PRUint32 NativeRole();
virtual PRUint64 NativeState();
// ActionAccessible
virtual PRUint8 ActionCount();
};
/**

View File

@ -70,13 +70,10 @@ nsXFormsDropmarkerWidgetAccessible::NativeState()
return isOpen ? states::PRESSED: 0;
}
NS_IMETHODIMP
nsXFormsDropmarkerWidgetAccessible::GetNumActions(PRUint8 *aCount)
PRUint8
nsXFormsDropmarkerWidgetAccessible::ActionCount()
{
NS_ENSURE_ARG_POINTER(aCount);
*aCount = 1;
return NS_OK;
return 1;
}
NS_IMETHODIMP

View File

@ -55,13 +55,15 @@ public:
nsIWeakReference *aShell);
// nsIAccessible
NS_IMETHOD GetNumActions(PRUint8 *aCount);
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
NS_IMETHOD DoAction(PRUint8 aIndex);
// nsAccessible
virtual PRUint32 NativeRole();
virtual PRUint64 NativeState();
// ActionAccessible
virtual PRUint8 ActionCount();
};

View File

@ -151,15 +151,11 @@ nsXULComboboxAccessible::GetAllowsAnonChildAccessibles()
// menuitems
return PR_FALSE;
}
NS_IMETHODIMP
nsXULComboboxAccessible::GetNumActions(PRUint8 *aNumActions)
PRUint8
nsXULComboboxAccessible::ActionCount()
{
NS_ENSURE_ARG_POINTER(aNumActions);
// Just one action (click).
*aNumActions = 1;
return NS_OK;
return 1;
}
NS_IMETHODIMP

View File

@ -56,7 +56,6 @@ public:
// nsIAccessible
NS_IMETHOD GetValue(nsAString& aValue);
NS_IMETHOD DoAction(PRUint8 aIndex);
NS_IMETHOD GetNumActions(PRUint8 *aNumActions);
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
// nsAccessible
@ -64,6 +63,9 @@ public:
virtual PRUint32 NativeRole();
virtual PRUint64 NativeState();
virtual PRBool GetAllowsAnonChildAccessibles();
// ActionAccessible
virtual PRUint8 ActionCount();
};
#endif

View File

@ -82,13 +82,10 @@ NS_IMPL_ISUPPORTS_INHERITED0(nsXULButtonAccessible, nsAccessible)
////////////////////////////////////////////////////////////////////////////////
// nsXULButtonAccessible: nsIAccessible
NS_IMETHODIMP
nsXULButtonAccessible::GetNumActions(PRUint8 *aCount)
PRUint8
nsXULButtonAccessible::ActionCount()
{
NS_ENSURE_ARG_POINTER(aCount);
*aCount = 1;
return NS_OK;
return 1;
}
NS_IMETHODIMP
@ -249,10 +246,10 @@ nsXULDropmarkerAccessible::
{
}
NS_IMETHODIMP nsXULDropmarkerAccessible::GetNumActions(PRUint8 *aResult)
PRUint8
nsXULDropmarkerAccessible::ActionCount()
{
*aResult = 1;
return NS_OK;
return 1;
}
PRBool nsXULDropmarkerAccessible::DropmarkerOpen(PRBool aToggleOpen)
@ -320,7 +317,6 @@ nsXULDropmarkerAccessible::NativeState()
return DropmarkerOpen(PR_FALSE) ? states::PRESSED : 0;
}
////////////////////////////////////////////////////////////////////////////////
// nsXULCheckboxAccessible
////////////////////////////////////////////////////////////////////////////////
@ -337,10 +333,10 @@ nsXULCheckboxAccessible::NativeRole()
return nsIAccessibleRole::ROLE_CHECKBUTTON;
}
NS_IMETHODIMP nsXULCheckboxAccessible::GetNumActions(PRUint8 *_retval)
PRUint8
nsXULCheckboxAccessible::ActionCount()
{
*_retval = 1;
return NS_OK;
return 1;
}
/**
@ -686,6 +682,9 @@ NS_IMPL_ISUPPORTS_INHERITED3(nsXULTextFieldAccessible, nsAccessible, nsHyperText
NS_IMETHODIMP nsXULTextFieldAccessible::GetValue(nsAString& aValue)
{
if (IsDefunct())
return NS_ERROR_FAILURE;
PRUint64 state = NativeState();
if (state & states::PROTECTED) // Don't return password text!
@ -753,14 +752,13 @@ nsXULTextFieldAccessible::NativeRole()
return nsIAccessibleRole::ROLE_ENTRY;
}
/**
* Only one actions available
*/
NS_IMETHODIMP nsXULTextFieldAccessible::GetNumActions(PRUint8 *_retval)
PRUint8
nsXULTextFieldAccessible::ActionCount()
{
*_retval = 1;
return NS_OK;
return 1;
}
/**

View File

@ -67,7 +67,6 @@ public:
NS_DECL_ISUPPORTS_INHERITED
// nsIAccessible
NS_IMETHOD GetNumActions(PRUint8 *_retval);
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
NS_IMETHOD DoAction(PRUint8 index);
@ -75,6 +74,9 @@ public:
virtual PRUint32 NativeRole();
virtual PRUint64 NativeState();
// ActionAccessible
virtual PRUint8 ActionCount();
protected:
// nsAccessible
@ -95,13 +97,15 @@ public:
nsXULCheckboxAccessible(nsIContent *aContent, nsIWeakReference *aShell);
// nsIAccessible
NS_IMETHOD GetNumActions(PRUint8 *_retval);
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
NS_IMETHOD DoAction(PRUint8 index);
// nsAccessible
virtual PRUint32 NativeRole();
virtual PRUint64 NativeState();
// ActionAccessible
virtual PRUint8 ActionCount();
};
/**
@ -114,7 +118,6 @@ public:
nsXULDropmarkerAccessible(nsIContent *aContent, nsIWeakReference *aShell);
// nsIAccessible
NS_IMETHOD GetNumActions(PRUint8 *_retval);
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
NS_IMETHOD DoAction(PRUint8 index);
@ -122,6 +125,9 @@ public:
virtual PRUint32 NativeRole();
virtual PRUint64 NativeState();
// ActionAccessible
virtual PRUint8 ActionCount();
private:
PRBool DropmarkerOpen(PRBool aToggleOpen);
};
@ -240,7 +246,6 @@ public:
// nsIAccessible
NS_IMETHOD GetValue(nsAString& aValue);
NS_IMETHOD GetNumActions(PRUint8 *_retval);
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
NS_IMETHOD DoAction(PRUint8 index);
@ -253,6 +258,9 @@ public:
virtual PRUint64 NativeState();
virtual PRBool GetAllowsAnonChildAccessibles();
// ActionAccessible
virtual PRUint8 ActionCount();
protected:
// nsAccessible
virtual void CacheChildren();

View File

@ -95,13 +95,10 @@ nsXULColumnItemAccessible::NativeState()
return states::READONLY;
}
NS_IMETHODIMP
nsXULColumnItemAccessible::GetNumActions(PRUint8 *aNumActions)
PRUint8
nsXULColumnItemAccessible::ActionCount()
{
NS_ENSURE_ARG_POINTER(aNumActions);
*aNumActions = 1;
return NS_OK;
return 1;
}
NS_IMETHODIMP

View File

@ -72,7 +72,6 @@ public:
nsXULColumnItemAccessible(nsIContent *aContent, nsIWeakReference *aShell);
// nsIAccessible
NS_IMETHOD GetNumActions(PRUint8 *aNumActions);
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
NS_IMETHOD DoAction(PRUint8 aIndex);
@ -80,6 +79,9 @@ public:
virtual PRUint32 NativeRole();
virtual PRUint64 NativeState();
// ActionAccessible
virtual PRUint8 ActionCount();
enum { eAction_Click = 0 };
};

View File

@ -565,10 +565,10 @@ NS_IMETHODIMP nsXULMenuitemAccessible::GetActionName(PRUint8 aIndex, nsAString&
return NS_ERROR_INVALID_ARG;
}
NS_IMETHODIMP nsXULMenuitemAccessible::GetNumActions(PRUint8 *_retval)
PRUint8
nsXULMenuitemAccessible::ActionCount()
{
*_retval = 1;
return NS_OK;
return 1;
}
@ -612,12 +612,12 @@ NS_IMETHODIMP nsXULMenuSeparatorAccessible::GetActionName(PRUint8 aIndex, nsAStr
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsXULMenuSeparatorAccessible::GetNumActions(PRUint8 *_retval)
PRUint8
nsXULMenuSeparatorAccessible::ActionCount()
{
return NS_ERROR_NOT_IMPLEMENTED;
return 0;
}
////////////////////////////////////////////////////////////////////////////////
// nsXULMenupopupAccessible
////////////////////////////////////////////////////////////////////////////////

View File

@ -84,7 +84,6 @@ public:
// nsIAccessible
NS_IMETHOD DoAction(PRUint8 index);
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
NS_IMETHOD GetNumActions(PRUint8 *_retval);
// nsAccessible
virtual void Description(nsString& aDescription);
@ -98,6 +97,7 @@ public:
virtual PRBool GetAllowsAnonChildAccessibles();
// ActionAccessible
virtual PRUint8 ActionCount();
virtual KeyBinding AccessKey() const;
virtual KeyBinding KeyboardShortcut() const;
};
@ -113,12 +113,14 @@ public:
// nsIAccessible
NS_IMETHOD DoAction(PRUint8 index);
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
NS_IMETHOD GetNumActions(PRUint8 *_retval);
// nsAccessible
virtual nsresult GetNameInternal(nsAString& aName);
virtual PRUint32 NativeRole();
virtual PRUint64 NativeState();
// ActionAccessible
virtual PRUint8 ActionCount();
};

View File

@ -97,13 +97,10 @@ nsXULSliderAccessible::GetValue(nsAString& aValue)
return GetSliderAttr(nsAccessibilityAtoms::curpos, aValue);
}
NS_IMETHODIMP
nsXULSliderAccessible::GetNumActions(PRUint8 *aCount)
PRUint8
nsXULSliderAccessible::ActionCount()
{
NS_ENSURE_ARG_POINTER(aCount);
*aCount = 1;
return NS_OK;
return 1;
}
NS_IMETHODIMP

View File

@ -56,7 +56,6 @@ public:
// nsIAccessible
NS_IMETHOD GetValue(nsAString& aValue);
NS_IMETHOD GetNumActions(PRUint8 *aCount);
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
NS_IMETHOD DoAction(PRUint8 aIndex);
@ -68,6 +67,9 @@ public:
virtual PRUint64 NativeState();
virtual PRBool GetAllowsAnonChildAccessibles();
// ActionAccessible
virtual PRUint8 ActionCount();
protected:
already_AddRefed<nsIContent> GetSliderNode();

View File

@ -65,10 +65,10 @@ nsXULTabAccessible::
////////////////////////////////////////////////////////////////////////////////
// nsXULTabAccessible: nsIAccessible
NS_IMETHODIMP nsXULTabAccessible::GetNumActions(PRUint8 *_retval)
PRUint8
nsXULTabAccessible::ActionCount()
{
*_retval = 1;
return NS_OK;
return 1;
}
/** Return the name of our only action */
@ -191,13 +191,10 @@ nsXULTabsAccessible::NativeRole()
return nsIAccessibleRole::ROLE_PAGETABLIST;
}
NS_IMETHODIMP
nsXULTabsAccessible::GetNumActions(PRUint8 *aCount)
PRUint8
nsXULTabsAccessible::ActionCount()
{
NS_ENSURE_ARG_POINTER(aCount);
*aCount = 0;
return NS_OK;
return 0;
}
/** no value */

View File

@ -54,7 +54,6 @@ public:
nsXULTabAccessible(nsIContent *aContent, nsIWeakReference *aShell);
// nsIAccessible
NS_IMETHOD GetNumActions(PRUint8 *_retval);
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
NS_IMETHOD DoAction(PRUint8 index);
NS_IMETHOD GetRelationByType(PRUint32 aRelationType,
@ -65,6 +64,9 @@ public:
PRInt32 *aSetSize);
virtual PRUint32 NativeRole();
virtual PRUint64 NativeState();
// ActionAccessible
virtual PRUint8 ActionCount();
};
@ -77,12 +79,14 @@ public:
nsXULTabsAccessible(nsIContent *aContent, nsIWeakReference *aShell);
// nsIAccessible
NS_IMETHOD GetNumActions(PRUint8 *_retval);
NS_IMETHOD GetValue(nsAString& _retval);
// nsAccessible
virtual nsresult GetNameInternal(nsAString& aName);
virtual PRUint32 NativeRole();
// ActionAccessible
virtual PRUint8 ActionCount();
};

View File

@ -189,13 +189,10 @@ nsXULLinkAccessible::NativeState()
return nsHyperTextAccessible::NativeState() | states::LINKED;
}
NS_IMETHODIMP
nsXULLinkAccessible::GetNumActions(PRUint8 *aNumActions)
PRUint8
nsXULLinkAccessible::ActionCount()
{
NS_ENSURE_ARG_POINTER(aNumActions);
*aNumActions = 1;
return NS_OK;
return 1;
}
NS_IMETHODIMP

View File

@ -87,7 +87,6 @@ public:
// nsIAccessible
NS_IMETHOD GetValue(nsAString& aValue);
NS_IMETHOD GetNumActions(PRUint8 *aNumActions);
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
NS_IMETHOD DoAction(PRUint8 aIndex);
@ -96,6 +95,9 @@ public:
virtual PRUint32 NativeRole();
virtual PRUint64 NativeState();
// ActionAccessible
virtual PRUint8 ActionCount();
// HyperLinkAccessible
virtual bool IsLink();
virtual PRUint32 StartOffset();

View File

@ -784,19 +784,12 @@ nsXULTreeItemAccessibleBase::GetRelationByType(PRUint32 aRelationType,
return nsAccessible::GetRelationByType(aRelationType, aRelation);
}
NS_IMETHODIMP
nsXULTreeItemAccessibleBase::GetNumActions(PRUint8 *aActionsCount)
PRUint8
nsXULTreeItemAccessibleBase::ActionCount()
{
NS_ENSURE_ARG_POINTER(aActionsCount);
*aActionsCount = 0;
if (IsDefunct())
return NS_ERROR_FAILURE;
// "activate" action is available for all treeitems, "expand/collapse" action
// is avaible for treeitem which is container.
*aActionsCount = IsExpandable() ? 2 : 1;
return NS_OK;
return IsExpandable() ? 2 : 1;
}
NS_IMETHODIMP

View File

@ -195,7 +195,6 @@ public:
PRInt32 *aSimilarItemsInGroup,
PRInt32 *aPositionInGroup);
NS_IMETHOD GetNumActions(PRUint8 *aCount);
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
NS_IMETHOD DoAction(PRUint8 aIndex);
@ -209,6 +208,9 @@ public:
virtual PRInt32 IndexInParent() const;
virtual nsAccessible* FocusedChild();
// ActionAccessible
virtual PRUint8 ActionCount();
// nsXULTreeItemAccessibleBase
NS_DECLARE_STATIC_IID_ACCESSOR(NS_XULTREEITEMBASEACCESSIBLE_IMPL_CID)

View File

@ -919,28 +919,20 @@ nsXULTreeGridCellAccessible::GetBounds(PRInt32 *aX, PRInt32 *aY,
return NS_OK;
}
NS_IMETHODIMP
nsXULTreeGridCellAccessible::GetNumActions(PRUint8 *aActionsCount)
PRUint8
nsXULTreeGridCellAccessible::ActionCount()
{
NS_ENSURE_ARG_POINTER(aActionsCount);
*aActionsCount = 0;
if (IsDefunct())
return NS_ERROR_FAILURE;
PRBool isCycler = PR_FALSE;
mColumn->GetCycler(&isCycler);
if (isCycler) {
*aActionsCount = 1;
return NS_OK;
}
if (isCycler)
return 1;
PRInt16 type;
mColumn->GetType(&type);
if (type == nsITreeColumn::TYPE_CHECKBOX && IsEditable())
*aActionsCount = 1;
return 1;
return NS_OK;
return 0;
}
NS_IMETHODIMP

View File

@ -148,7 +148,6 @@ public:
NS_IMETHOD GetBounds(PRInt32 *aX, PRInt32 *aY,
PRInt32 *aWidth, PRInt32 *aHeight);
NS_IMETHOD GetNumActions(PRUint8 *aCount);
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
NS_IMETHOD DoAction(PRUint8 aIndex);
@ -163,9 +162,12 @@ public:
// nsAccessible
virtual nsAccessible* FocusedChild();
virtual nsresult GetAttributesInternal(nsIPersistentProperties *aAttributes);
virtual PRInt32 IndexInParent() const;
virtual PRUint32 NativeRole();
virtual PRUint64 NativeState();
virtual PRInt32 IndexInParent() const;
// ActionAccessible
virtual PRUint8 ActionCount();
// nsXULTreeGridCellAccessible
NS_DECLARE_STATIC_IID_ACCESSOR(NS_XULTREEGRIDCELLACCESSIBLE_IMPL_CID)

View File

@ -24,6 +24,7 @@
const kRemoval = 0;
const kInsertion = 1;
const kUnexpected = true;
function changeText(aContainerID, aValue, aEventList)
{
@ -32,14 +33,22 @@
this.textData = this.textNode.data;
this.eventSeq = [ ];
this.unexpectedEventSeq = [ ];
for (var i = 0; i < aEventList.length; i++) {
var isInserted = aEventList[i][0];
var str = aEventList[i][1];
var offset = aEventList[i][2];
var event = aEventList[i];
var isInserted = event[0];
var str = event[1];
var offset = event[2];
var checker = new textChangeChecker(this.containerNode, offset,
offset + str.length, str,
isInserted);
this.eventSeq.push(checker);
if (eventItem[3] == kUnexpected)
this.unexpectedEventSeq.push(checker);
else
this.eventSeq.push(checker);
}
this.invoke = function changeText_invoke()
@ -54,6 +63,13 @@
}
}
function expStr(x, doublings)
{
for (var i = 0; i < doublings; ++i)
x = x + x;
return x;
}
////////////////////////////////////////////////////////////////////////////
// Do tests
@ -167,6 +183,34 @@
];
gQueue.push(new changeText("p11", "levenshtein", events));
//////////////////////////////////////////////////////////////////////////
// long strings, remove/insert pair as the old string was replaced on
// new one
var longStr1 = expStr("x", 16);
var longStr2 = expStr("X", 16);
var newStr = "a" + longStr1 + "b", insStr = longStr1, rmStr = "";
events = [
[ kRemoval, rmStr, 1, kUnexpected ],
[ kInsertion, insStr, 1 ]
];
gQueue.push(new changeText("p12", newStr, events));
newStr = "a" + longStr2 + "b", insStr = longStr2, rmStr = longStr1;
events = [
[ kRemoval, rmStr, 1 ],
[ kInsertion, insStr, 1]
];
gQueue.push(new changeText("p12", newStr, events));
newStr = "ab", insStr = "", rmStr = longStr2;
events = [
[ kRemoval, rmStr, 1 ],
[ kInsertion, insStr, 1, kUnexpected ]
];
gQueue.push(new changeText("p12", newStr, events));
gQueue.invoke(); // Will call SimpleTest.finish();
}
@ -201,5 +245,6 @@
<p id="p9">abcDEFabc</p>
<p id="p10">!abcdef@</p>
<p id="p11">meilenstein</p>
<p id="p12">ab</p>
</body>
</html>

View File

@ -69,6 +69,10 @@
testRelation("treeitem4", RELATION_NODE_CHILD_OF, "tree");
testRelation("treeitem5", RELATION_NODE_CHILD_OF, "treeitem4");
// no relation node_child_of for accessible contained in an unexpected
// parent
testRelation("treeitem6", RELATION_NODE_CHILD_OF, null);
// 'node child of' relation for the document having window, returns
// direct accessible parent (fixed in bug 419770).
var iframeElmObj = {};
@ -146,6 +150,11 @@
title="mochitests for accessible relations">
Mozilla Bug 475298
</a><br/>
<a target="_blank"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=673389"
title="node_child_of on an item not in a proper container">
Mozilla Bug 67389
</a><br/>
<p id="display"></p>
<div id="content" style="display: none">
@ -192,6 +201,8 @@
<description role="treeitem" id="treeitem5" aria-level="2">Light green</description>
</vbox>
<description role="treeitem" id="treeitem6">Dark green</description>
<iframe id="iframe"/>
<hbox id="tablist" role="tablist">

View File

@ -24,6 +24,8 @@
src="../role.js" />
<script type="application/javascript"
src="../relations.js" />
<script type="application/javascript"
src="../events.js" />
<script type="application/javascript" src="chrome://global/content/globalOverlay.js"/>
<script type="application/javascript">
@ -49,19 +51,28 @@
{
var tabBrowser = document.getElementById("tabbrowser");
var progressListener =
{
onStateChange: function onStateChange(aWebProgress,
aRequest,
aStateFlags,
aStatus)
{
if (aStateFlags & Ci.nsIWebProgressListener.STATE_STOP)
testRelations();
}
};
// Load documents into tabs and wait for reorder events caused by these
// documents load before we start the test.
var docURIs = ["about:", "about:mozilla"];
tabBrowser.addProgressListener(progressListener);
var handler = {
handleEvent: function handleEvent(aEvent) {
var target = aEvent.accessible;
if (target.role == ROLE_INTERNAL_FRAME &&
target.parent.parent == getAccessible(this.tabBrowser.mTabBox.tabpanels)) {
this.reorderCnt++;
}
if (this.reorderCnt == docURIs.length) {
unregisterA11yEventListener(EVENT_REORDER, this);
testRelations();
}
},
tabBrowser: tabBrowser,
reorderCnt: 0
};
registerA11yEventListener(EVENT_REORDER, handler);
tabBrowser.loadTabs(["about:", "about:mozilla"], false, true);
}

View File

@ -58,6 +58,7 @@ _TEST_FILES =\
test_inputs.xul \
test_link.html \
test_popup.xul \
test_stale.html \
test_textbox.xul \
test_tree.xul \
z_frames.html \

View File

@ -0,0 +1,115 @@
<!DOCTYPE html>
<html>
<head>
<title>Stale state 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">
function addChild(aContainerID)
{
this.containerNode = getNode(aContainerID);
this.childNode = null;
this.eventSeq = [
new invokerChecker(EVENT_REORDER, this.containerNode)
];
this.invoke = function addChild_invoke()
{
this.childNode = document.createElement("div");
this.containerNode.appendChild(this.childNode);
}
this.finalCheck = function addChild_finalCheck()
{
// no stale state should be set
testStates(this.childNode, 0, 0, 0, EXT_STATE_STALE);
}
this.getID = function addChild_getID()
{
return "add child for " + prettyName(aContainerID);
}
}
function removeChildChecker(aInvoker)
{
this.type = EVENT_HIDE;
this.__defineGetter__("target", function() { return aInvoker.child; });
this.check = function removeChildChecker_check()
{
// stale state should be set
testStates(aInvoker.child, 0, EXT_STATE_STALE);
}
}
function removeChild(aContainerID)
{
this.containerNode = getNode(aContainerID);
this.child = null;
this.eventSeq = [
new removeChildChecker(this)
];
this.invoke = function removeChild_invoke()
{
var childNode = this.containerNode.firstChild;
this.child = getAccessible(childNode);
this.containerNode.removeChild(childNode);
}
this.getID = function removeChild_getID()
{
return "remove child from " + prettyName(aContainerID);
}
}
//gA11yEventDumpToConsole = true; //debugging
var gQueue = null;
function doTest()
{
gQueue = new eventQueue();
gQueue.push(new addChild("container"));
gQueue.push(new removeChild("container"));
gQueue.invoke(); // will call SimpleTest.finish()
}
SimpleTest.waitForExplicitFinish();
addA11yLoadEvent(doTest);
</script>
</head>
<body role="">
<a target="_blank"
title="Expose stale state on accessibles unattached from tree"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=676267">Mozilla Bug 676267</a>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
</pre>
<div id="container"></div>
</body>
</html>

View File

@ -48,7 +48,7 @@ function testTableStruct(aIdentifier, aCellsArray, aColHeaderType,
tableNode.localName == "tree";
var rowCount = aCellsArray.length;
var colsCount = aCellsArray[0].length;
var colsCount = aCellsArray[0] ? aCellsArray[0].length : 0;
// Test table accessible tree.
var tableObj = {

View File

@ -50,6 +50,14 @@
testTableStruct("grid2", cellsArray);
//////////////////////////////////////////////////////////////////////////
// ARIA grid of wrong markup
cellsArray = [ ];
testTableStruct("grid3", cellsArray);
cellsArray = [ [] ];
testTableStruct("grid4", cellsArray);
SimpleTest.finish();
}
@ -68,6 +76,9 @@
<a target="_blank"
title="nsHTMLTableCellAccessible is used in dojo's crazy ARIA grid"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=513848">Mozilla Bug 513848</a>
<a target="_blank"
title="Crash [@ AccIterator::GetNext()]"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=675861">Mozilla Bug 675861</a>
<p id="display"></p>
<div id="content" style="display: none"></div>
@ -133,5 +144,8 @@
</div>
</div>
<!-- Wrong markup ARIA grid -->
<div role="grid" id="grid3"></div>
<div role="grid" id="grid4"><div role="row"></div></div>
</body>
</html>

View File

@ -23,6 +23,8 @@
src="../common.js" />
<script type="application/javascript"
src="../role.js" />
<script type="application/javascript"
src="../events.js" />
<script type="application/javascript" src="chrome://global/content/globalOverlay.js"/>
<script type="application/javascript">
@ -47,24 +49,31 @@
{
var tabBrowser = document.getElementById("tabbrowser");
var progressListener =
{
onStateChange: function onStateChange(aWebProgress,
aRequest,
aStateFlags,
aStatus)
{
if (aStateFlags & Ci.nsIWebProgressListener.STATE_STOP) {
tabBrowser.removeProgressListener(progressListener);
// Load documents into tabs and wait for reorder events caused by these
// documents load before we start the test.
var docURIs = ["about:", "about:mozilla"];
SimpleTest.executeSoon(testAccTree);
var handler = {
handleEvent: function handleEvent(aEvent) {
var target = aEvent.accessible;
if (target.role == ROLE_INTERNAL_FRAME &&
target.parent.parent == getAccessible(this.tabBrowser.mTabBox.tabpanels)) {
this.reorderCnt++;
}
}
if (this.reorderCnt == docURIs.length) {
unregisterA11yEventListener(EVENT_REORDER, this);
testAccTree();
}
},
tabBrowser: tabBrowser,
reorderCnt: 0
};
tabBrowser.addProgressListener(progressListener);
registerA11yEventListener(EVENT_REORDER, handler);
// Test XUL and HTML documents.
tabBrowser.loadTabs(["about:", "about:mozilla"], false, true);
tabBrowser.loadTabs(docURIs, false, true);
}
function testAccTree()

View File

@ -205,13 +205,6 @@ libs::
$(INSTALL) $(IFLAGS1) $(DIST)/branding/default48.png $(DIST)/bin/chrome/icons/default
endif
ifdef MOZ_SPLASHSCREEN
ifeq ($(MOZ_WIDGET_TOOLKIT),windows)
libs::
$(INSTALL) $(IFLAGS1) $(DIST)/branding/splash.bmp $(DIST)/bin
endif
endif
libs:: $(srcdir)/profile/prefs.js
$(INSTALL) $(IFLAGS1) $^ $(DIST)/bin/defaults/profile

View File

@ -0,0 +1,213 @@
<?xml version="1.0"?>
<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist" lastupdate="1311096050000">
<emItems>
<emItem blockID="i41" id="{99079a25-328f-4bd4-be04-00955acaa0a7}">
<versionRange minVersion="0.1" maxVersion="4.3.0.00" severity="1">
</versionRange>
</emItem>
<emItem blockID="i8" id="{B13721C7-F507-4982-B2E5-502A71474FED}">
<versionRange minVersion=" " severity="1">
</versionRange>
</emItem>
<emItem blockID="i38" id="{B7082FAA-CB62-4872-9106-E42DD88EDE45}">
<versionRange minVersion="0.1" maxVersion="3.3.0.*">
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
<versionRange minVersion="3.7a1" maxVersion="*" />
</targetApplication>
</versionRange>
<versionRange minVersion="3.3.1" maxVersion="*">
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
<versionRange minVersion="5.0a1" maxVersion="*" />
</targetApplication>
</versionRange>
</emItem>
<emItem blockID="i19" id="{46551EC9-40F0-4e47-8E18-8E5CF550CFB8}">
<versionRange minVersion="1.1b1" maxVersion="1.1b1">
</versionRange>
</emItem>
<emItem blockID="i16" id="{27182e60-b5f3-411c-b545-b44205977502}">
<versionRange minVersion="1.0" maxVersion="1.0">
</versionRange>
</emItem>
<emItem blockID="i39" id="{c2d64ff7-0ab8-4263-89c9-ea3b0f8f050c}">
<versionRange minVersion="0.1" maxVersion="4.3.0.00" severity="1">
</versionRange>
</emItem>
<emItem blockID="i10" id="{8CE11043-9A15-4207-A565-0C94C42D590D}">
</emItem>
<emItem blockID="i1" id="mozilla_cc@internetdownloadmanager.com">
<versionRange minVersion="2.1" maxVersion="3.3">
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
<versionRange minVersion="3.0a1" maxVersion="*" />
</targetApplication>
</versionRange>
<versionRange minVersion=" " maxVersion="6.9.8">
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
<versionRange minVersion="3.7a1pre" maxVersion="*" />
</targetApplication>
</versionRange>
</emItem>
<emItem blockID="i18" id="msntoolbar@msn.com">
<versionRange minVersion=" " maxVersion="6.*">
</versionRange>
</emItem>
<emItem blockID="i13" id="{E8E88AB0-7182-11DF-904E-6045E0D72085}">
</emItem>
<emItem blockID="i4" id="{4B3803EA-5230-4DC3-A7FC-33638F3D3542}">
<versionRange minVersion="1.2" maxVersion="1.2">
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
<versionRange minVersion="3.0a1" maxVersion="*" />
</targetApplication>
</versionRange>
</emItem>
<emItem blockID="i40" id="{28387537-e3f9-4ed7-860c-11e69af4a8a0}">
<versionRange minVersion="0.1" maxVersion="4.3.0.00" severity="1">
</versionRange>
</emItem>
<emItem blockID="i23" id="firefox@bandoo.com">
<versionRange minVersion="5.0" maxVersion="5.0" severity="1">
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
<versionRange minVersion="3.7a1pre" maxVersion="*" />
</targetApplication>
</versionRange>
</emItem>
<emItem blockID="i22" id="ShopperReports@ShopperReports.com">
<versionRange minVersion="3.1.22.0" maxVersion="3.1.22.0">
</versionRange>
</emItem>
<emItem blockID="i2" id="fdm_ffext@freedownloadmanager.org">
<versionRange minVersion="1.0" maxVersion="1.3.1">
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
<versionRange minVersion="3.0a1" maxVersion="*" />
</targetApplication>
</versionRange>
</emItem>
<emItem blockID="i5" id="support@daemon-tools.cc">
<versionRange minVersion=" " maxVersion="1.0.0.5">
</versionRange>
</emItem>
<emItem blockID="i6" id="{3f963a5b-e555-4543-90e2-c3908898db71}">
<versionRange minVersion=" " maxVersion="8.5">
</versionRange>
</emItem>
<emItem blockID="i12" id="masterfiler@gmail.com">
<versionRange severity="3">
</versionRange>
</emItem>
<emItem blockID="i20" id="{AB2CE124-6272-4b12-94A9-7303C7397BD1}">
<versionRange minVersion="0.1" maxVersion="5.2.0.7164" severity="1">
</versionRange>
</emItem>
<emItem blockID="i11" id="yslow@yahoo-inc.com">
<versionRange minVersion="2.0.5" maxVersion="2.0.5">
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
<versionRange minVersion="3.5.7" maxVersion="*" />
</targetApplication>
</versionRange>
</emItem>
<emItem blockID="i17" id="{3252b9ae-c69a-4eaf-9502-dc9c1f6c009e}">
<versionRange minVersion="2.2" maxVersion="2.2">
</versionRange>
</emItem>
<emItem blockID="i3" id="langpack-vi-VN@firefox.mozilla.org">
<versionRange minVersion="2.0" maxVersion="2.0">
</versionRange>
</emItem>
<emItem blockID="i7" id="{2224e955-00e9-4613-a844-ce69fccaae91}">
</emItem>
<emItem blockID="i24" id="{6E19037A-12E3-4295-8915-ED48BC341614}">
<versionRange minVersion="0.1" maxVersion="1.3.328.4" severity="1">
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
<versionRange minVersion="3.7a1pre" maxVersion="*" />
</targetApplication>
</versionRange>
</emItem>
<emItem blockID="i15" id="personas@christopher.beard">
<versionRange minVersion="1.6" maxVersion="1.6">
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
<versionRange minVersion="3.6" maxVersion="3.6.*" />
</targetApplication>
</versionRange>
</emItem>
<emItem blockID="i21" id="support@update-firefox.com">
</emItem>
</emItems>
<pluginItems>
<pluginItem blockID="p26">
<match name="name" exp="^Yahoo Application State Plugin$" /> <match name="description" exp="^Yahoo Application State Plugin$" /> <match name="filename" exp="npYState.dll" /> <versionRange >
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
<versionRange minVersion="3.0a1" maxVersion="3.*" />
</targetApplication>
</versionRange>
</pluginItem>
<pluginItem blockID="p27">
<match name="name" exp="QuickTime Plug-in 7[.]1[.]" /> <match name="filename" exp="npqtplugin.?[.]dll" /> <versionRange >
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
<versionRange minVersion="3.0a1" maxVersion="3.*" />
</targetApplication>
</versionRange>
</pluginItem>
<pluginItem blockID="p28">
<match name="filename" exp="NPFFAddOn.dll" /> <versionRange >
</versionRange>
</pluginItem>
<pluginItem blockID="p31">
<match name="filename" exp="NPMySrch.dll" /> <versionRange >
</versionRange>
</pluginItem>
<pluginItem blockID="p32">
<match name="filename" exp="npViewpoint.dll" /> <versionRange >
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
<versionRange minVersion="3.0" maxVersion="*" />
</targetApplication>
</versionRange>
</pluginItem>
<pluginItem blockID="p33">
<match name="name" exp="[0-6]\.0\.[01]\d{2}\.\d+" /> <match name="filename" exp="npdeploytk.dll" /> <versionRange severity="1">
</versionRange>
</pluginItem>
<pluginItem blockID="p34">
<match name="filename" exp="[Nn][Pp][Jj][Pp][Ii]1[56]0_[0-9]+\.[Dd][Ll][Ll]" /> <versionRange >
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
<versionRange minVersion="3.6a1pre" maxVersion="*" />
</targetApplication>
</versionRange>
</pluginItem>
</pluginItems>
<gfxItems>
<gfxBlacklistEntry blockID="g35">
<os>WINNT 6.1</os>
<vendor>0x10de</vendor>
<devices>
<device>0x0a6c</device>
</devices>
<feature>DIRECT2D</feature>
<featureStatus>BLOCKED_DRIVER_VERSION</featureStatus>
<driverVersion>8.17.12.5896</driverVersion>
<driverVersionComparator>LESS_THAN_OR_EQUAL</driverVersionComparator>
</gfxBlacklistEntry>
<gfxBlacklistEntry blockID="g36">
<os>WINNT 6.1</os>
<vendor>0x10de</vendor>
<devices>
<device>0x0a6c</device>
</devices>
<feature>DIRECT3D_9_LAYERS</feature>
<featureStatus>BLOCKED_DRIVER_VERSION</featureStatus>
<driverVersion>8.17.12.5896</driverVersion>
<driverVersionComparator>LESS_THAN_OR_EQUAL</driverVersionComparator>
</gfxBlacklistEntry>
<gfxBlacklistEntry blockID="g37">
<os>WINNT 5.1</os>
<vendor>0x10de</vendor>
<feature>DIRECT3D_9_LAYERS</feature>
<featureStatus>BLOCKED_DRIVER_VERSION</featureStatus>
<driverVersion>7.0.0.0</driverVersion>
<driverVersionComparator>GREATER_THAN_OR_EQUAL</driverVersionComparator>
</gfxBlacklistEntry>
</gfxItems>
</blocklist>

View File

@ -36,6 +36,7 @@
#
# ***** END LICENSE BLOCK *****
<menuseparator id="page-menu-separator"/>
<menuitem id="spell-no-suggestions"
disabled="true"
label="&spellNoSuggestions.label;"/>

View File

@ -220,6 +220,7 @@
# Mac: Cmd+K (cross platform binding)
# Cmd+Opt+F (platform convention)
# Win: Ctrl+K (cross platform binding)
# Ctrl+E (IE compat)
#
# We support Ctrl+K on all platforms now and advertise it in the menu since it is
# our standard - it is a "safe" choice since it is near no harmful keys like "W" as
@ -232,6 +233,9 @@
#ifdef XP_MACOSX
<key id="key_search2" key="&findOnCmd.commandkey;" command="Tools:Search" modifiers="accel,alt"/>
#endif
#ifdef XP_WIN
<key id="key_search2" key="&searchFocus.commandkey2;" command="Tools:Search" modifiers="accel"/>
#endif
#ifdef XP_GNOME
<key id="key_search2" key="&searchFocusUnix.commandkey;" command="Tools:Search" modifiers="accel"/>
<key id="key_openDownloads" key="&downloadsUnix.commandkey;" command="Tools:Downloads" modifiers="accel,shift"/>

View File

@ -40,6 +40,20 @@
// gSyncUI handles updating the tools menu
let gSyncUI = {
_obs: ["weave:service:sync:start",
"weave:service:sync:finish",
"weave:service:sync:error",
"weave:service:sync:delayed",
"weave:service:quota:remaining",
"weave:service:setup-complete",
"weave:service:login:start",
"weave:service:login:finish",
"weave:service:login:error",
"weave:service:logout:finish",
"weave:service:start-over"],
_unloaded: false,
init: function SUI_init() {
// Proceed to set up the UI if Sync has already started up.
// Otherwise we'll do it when Sync is firing up.
@ -52,31 +66,26 @@ let gSyncUI = {
// Remove the observer if the window is closed before the observer
// was triggered.
window.addEventListener("unload", function() {
window.removeEventListener("unload", arguments.callee, false);
window.addEventListener("unload", function onUnload() {
gSyncUI._unloaded = true;
window.removeEventListener("unload", onUnload, false);
Services.obs.removeObserver(gSyncUI, "weave:service:ready");
if (Weave.Status.ready) {
gSyncUI._obs.forEach(function(topic) {
Services.obs.removeObserver(gSyncUI, topic);
});
}
}, false);
},
initUI: function SUI_initUI() {
let obs = ["weave:service:sync:start",
"weave:service:sync:finish",
"weave:service:sync:error",
"weave:service:sync:delayed",
"weave:service:quota:remaining",
"weave:service:setup-complete",
"weave:service:login:start",
"weave:service:login:finish",
"weave:service:login:error",
"weave:service:logout:finish",
"weave:service:start-over"];
// If this is a browser window?
if (gBrowser) {
obs.push("weave:notification:added");
this._obs.push("weave:notification:added");
}
obs.forEach(function(topic) {
this._obs.forEach(function(topic) {
Services.obs.addObserver(this, topic, true);
}, this);
@ -93,7 +102,7 @@ let gSyncUI = {
}
this.updateUI();
},
initNotifications: function SUI_initNotifications() {
const XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
let notificationbox = document.createElementNS(XULNS, "notificationbox");
@ -151,7 +160,7 @@ let gSyncUI = {
let popup = document.getElementById("alltabs-popup");
if (!popup)
return;
let menuitem = document.createElement("menuitem");
menuitem.setAttribute("id", "sync-tabs-menuitem");
menuitem.setAttribute("label", label);
@ -295,7 +304,7 @@ let gSyncUI = {
let win = Services.wm.getMostRecentWindow("Sync:ViewQuota");
if (win)
win.focus();
else
else
Services.ww.activeWindow.openDialog(
"chrome://browser/content/syncQuota.xul", "",
"centerscreen,chrome,dialog,modal");
@ -414,8 +423,13 @@ let gSyncUI = {
this.updateUI();
},
observe: function SUI_observe(subject, topic, data) {
if (this._unloaded) {
Cu.reportError("SyncUI observer called after unload: " + topic);
return;
}
switch (topic) {
case "weave:service:sync:start":
this.onActivityStart();

View File

@ -216,6 +216,12 @@ XPCOMUtils.defineLazyServiceGetter(this, "gCrashReporter",
"nsICrashReporter");
#endif
XPCOMUtils.defineLazyGetter(this, "PageMenu", function() {
let tmp = {};
Cu.import("resource://gre/modules/PageMenu.jsm", tmp);
return new tmp.PageMenu();
});
/**
* We can avoid adding multiple load event listeners and save some time by adding
* one listener that calls all real handlers.

View File

@ -234,14 +234,6 @@
close="true"
onpopuphiding="InspectorUI.closeInspectorUI();"
label="&inspectPanelTitle.label;">
<toolbar id="inspector-toolbar"
nowindowdrag="true">
<toolbarbutton id="inspector-inspect-toolbutton"
label="&inspectButton.label;"
accesskey="&inspectButton.accesskey;"
class="toolbarbutton-text"
command="Inspector:Inspect"/>
</toolbar>
<hbox id="tree-panel-resizer-box" align="end">
<spacer flex="1" />
<resizer dir="bottomend" />
@ -281,10 +273,10 @@
oncommand="BrowserFullScreen();"/>
</menupopup>
<menupopup id="contentAreaContextMenu"
<menupopup id="contentAreaContextMenu" pagemenu="start"
onpopupshowing="if (event.target != this)
return true;
gContextMenu = new nsContextMenu(this, gBrowser);
gContextMenu = new nsContextMenu(this, gBrowser, event.shiftKey);
if (gContextMenu.shouldDisplay)
updateEditUIVisibility();
return gContextMenu.shouldDisplay;"
@ -971,6 +963,19 @@
</hbox>
<vbox id="browser-bottombox" layer="true">
<toolbar id="inspector-toolbar"
nowindowdrag="true"
hidden="true">
<toolbarbutton id="inspector-inspect-toolbutton"
label="&inspectButton.label;"
accesskey="&inspectButton.accesskey;"
class="toolbarbutton-text"
command="Inspector:Inspect"/>
<toolbarseparator />
<hbox id="inspector-tools">
<!-- registered tools go here -->
</hbox>
</toolbar>
<toolbar id="addon-bar"
toolbarname="&addonBarCmd.label;" accesskey="&addonBarCmd.accesskey;"
collapsed="true"
@ -1004,7 +1009,7 @@
<svg:svg height="0">
<svg:mask id="pinstripe-keyhole-forward-mask" maskContentUnits="objectBoundingBox">
<svg:rect x="0" y="0" width="1" height="1" fill="white"/>
<svg:circle cx="-0.46" cy="0.48" r="0.65"/>
<svg:circle cx="-0.41" cy="0.5" r="0.65"/>
</svg:mask>
<svg:mask id="pinstripe-tab-ontop-left-curve-mask" maskContentUnits="userSpaceOnUse">
<svg:circle cx="9" cy="3" r="3" fill="white"/>

View File

@ -222,6 +222,7 @@ Highlighter.prototype = {
this.highlighterContainer = null;
this.win = null
this.browser = null;
this.toolbar = null;
},
/**
@ -758,6 +759,8 @@ var InspectorUI = {
this.browser = gBrowser.selectedBrowser;
this.win = this.browser.contentWindow;
this.winID = this.getWindowID(this.win);
this.toolbar = document.getElementById("inspector-toolbar");
if (!this.domplate) {
Cu.import("resource:///modules/domplate.jsm", this);
this.domplateUtils.setDOM(window);
@ -765,6 +768,7 @@ var InspectorUI = {
this.openTreePanel();
this.toolbar.hidden = false;
this.inspectCmd.setAttribute("checked", true);
},
@ -818,6 +822,7 @@ var InspectorUI = {
}
this.closing = true;
this.toolbar.hidden = true;
if (!aKeepStore) {
InspectorStore.deleteStore(this.winID);
@ -897,8 +902,10 @@ var InspectorUI = {
/**
* Stop inspecting webpage, detach page listeners, disable highlighter
* event listeners.
* @param aPreventScroll
* Prevent scroll in the HTML tree?
*/
stopInspecting: function IUI_stopInspecting()
stopInspecting: function IUI_stopInspecting(aPreventScroll)
{
if (!this.inspecting) {
return;
@ -908,7 +915,7 @@ var InspectorUI = {
this.detachPageListeners();
this.inspecting = false;
if (this.highlighter.node) {
this.select(this.highlighter.node, true, true);
this.select(this.highlighter.node, true, true, !aPreventScroll);
} else {
this.select(null, true, true);
}
@ -1048,9 +1055,16 @@ var InspectorUI = {
}
if (node) {
if (hitTwisty)
if (hitTwisty) {
this.ioBox.toggleObject(node);
this.select(node, false, false);
} else {
if (this.inspecting) {
this.stopInspecting(true);
} else {
this.select(node, true, false);
this.highlighter.highlightNode(node);
}
}
}
},
@ -1277,7 +1291,7 @@ var InspectorUI = {
this.tools[id] = aRegObj;
}
let toolbar = document.getElementById("inspector-toolbar");
let toolbox = document.getElementById("inspector-tools");
let btn = document.createElement("toolbarbutton");
btn.setAttribute("id", aRegObj.buttonId);
btn.setAttribute("label", aRegObj.label);
@ -1285,7 +1299,7 @@ var InspectorUI = {
btn.setAttribute("accesskey", aRegObj.accesskey);
btn.setAttribute("class", "toolbarbutton-text");
btn.setAttribute("image", aRegObj.icon || "");
toolbar.appendChild(btn);
toolbox.appendChild(btn);
btn.addEventListener("click",
function IUI_ToolButtonClick(aEvent) {

View File

@ -61,14 +61,14 @@
#
# ***** END LICENSE BLOCK *****
function nsContextMenu(aXulMenu, aBrowser) {
function nsContextMenu(aXulMenu, aBrowser, aIsShift) {
this.shouldDisplay = true;
this.initMenu(aBrowser);
this.initMenu(aBrowser, aXulMenu, aIsShift);
}
// Prototype for nsContextMenu "class."
nsContextMenu.prototype = {
initMenu: function CM_initMenu(aBrowser) {
initMenu: function CM_initMenu(aBrowser, aXulMenu, aIsShift) {
// Get contextual info.
this.setTarget(document.popupNode, document.popupRangeParent,
document.popupRangeOffset);
@ -76,6 +76,12 @@ nsContextMenu.prototype = {
return;
this.browser = aBrowser;
this.hasPageMenu = false;
if (!aIsShift) {
this.hasPageMenu = PageMenu.init(this.target, aXulMenu);
}
this.isFrameImage = document.getElementById("isFrameImage");
this.ellipsis = "\u2026";
try {
@ -90,6 +96,7 @@ nsContextMenu.prototype = {
},
initItems: function CM_initItems() {
this.initPageMenuSeparator();
this.initOpenItems();
this.initNavigationItems();
this.initViewItems();
@ -100,6 +107,10 @@ nsContextMenu.prototype = {
this.initMediaPlayerItems();
},
initPageMenuSeparator: function CM_initPageMenuSeparator() {
this.showItem("page-menu-separator", this.hasPageMenu);
},
initOpenItems: function CM_initOpenItems() {
var isMailtoInternal = false;
if (this.onMailtoLink) {

View File

@ -1372,19 +1372,15 @@
// aReferrerURI is null or undefined if the tab is opened from
// an external application or bookmark, i.e. somewhere other
// than the current tab.
if (aRelatedToCurrent == null ? aReferrerURI : aRelatedToCurrent) {
if ((aRelatedToCurrent == null ? aReferrerURI : aRelatedToCurrent) &&
Services.prefs.getBoolPref("browser.tabs.insertRelatedAfterCurrent")) {
let newTabPos = (this._lastRelatedTab ||
this.selectedTab)._tPos + 1;
if (this._lastRelatedTab)
this._lastRelatedTab.owner = null;
else
t.owner = this.selectedTab;
if (!this.selectedTab.pinned &&
Services.prefs.getBoolPref("browser.tabs.insertRelatedAfterCurrent"))
this.moveTabTo(t, newTabPos);
this.moveTabTo(t, newTabPos);
this._lastRelatedTab = t;
}

View File

@ -263,11 +263,10 @@ function GroupItem(listOfEls, options) {
if (options.dontPush) {
this.setZ(drag.zIndex);
drag.zIndex++;
} else
} else {
// Calling snap will also trigger pushAway
this.snap(immediately);
if ($container)
this.setBounds(rectToBe, immediately);
}
if (!options.immediately && listOfEls.length > 0)
$container.hide().fadeIn();
@ -1656,11 +1655,12 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), {
container.mousedown(function(e) {
let target = e.target;
// only set the last mouse down target if it is a left click, not on the
// close button, not on the new tab button, not on the title bar and its
// element
// close button, not on the expand button, not on the title bar and its
// elements
if (Utils.isLeftClick(e) &&
self.$closeButton[0] != target &&
self.$titlebar[0] != target &&
self.$expander[0] != target &&
!self.$titlebar.contains(target) &&
!self.$appTabTray.contains(target)) {
lastMouseDownTarget = target;
@ -2233,12 +2233,14 @@ let GroupItems = {
// Function: groupItemStorageSanity
// Given persistent storage data for a groupItem, returns true if it appears to not be damaged.
groupItemStorageSanity: function GroupItems_groupItemStorageSanity(groupItemData) {
// TODO: check everything
// Bug 586555
var sane = true;
if (!Utils.isRect(groupItemData.bounds)) {
let sane = true;
if (!groupItemData.bounds || !Utils.isRect(groupItemData.bounds)) {
Utils.log('GroupItems.groupItemStorageSanity: bad bounds', groupItemData.bounds);
sane = false;
} else if ((groupItemData.userSize &&
!Utils.isPoint(groupItemData.userSize)) ||
!groupItemData.id) {
sane = false;
}
return sane;

View File

@ -310,9 +310,14 @@ Item.prototype = {
// Parameters:
// immediately - boolean for doing the pushAway without animation
pushAway: function Item_pushAway(immediately) {
var items = Items.getTopLevelItems();
// we need at least two top-level items to push something away
if (items.length < 2)
return;
var buffer = Math.floor(Items.defaultGutter / 2);
var items = Items.getTopLevelItems();
// setup each Item's pushAwayData attribute:
items.forEach(function pushAway_setupPushAwayData(item) {
var data = {};

View File

@ -433,7 +433,8 @@ let UI = {
Utils.assert(item, "item must be given");
if (item.isATabItem) {
GroupItems.setActiveGroupItem(item.parent);
if (item.parent)
GroupItems.setActiveGroupItem(item.parent);
this._setActiveTab(item);
} else {
GroupItems.setActiveGroupItem(item);

View File

@ -153,6 +153,7 @@ _BROWSER_FILES = \
browser_zbug569342.js \
browser_bug575561.js \
browser_bug577121.js \
browser_bug578534.js \
browser_bug579872.js \
browser_bug580638.js \
browser_bug580956.js \
@ -187,15 +188,6 @@ _BROWSER_FILES = \
browser_gestureSupport.js \
browser_getshortcutoruri.js \
browser_hide_removing.js \
browser_scratchpad_initialization.js \
browser_scratchpad_contexts.js \
browser_scratchpad_tab_switch.js \
browser_scratchpad_execute_print.js \
browser_scratchpad_inspect.js \
browser_scratchpad_files.js \
browser_scratchpad_ui.js \
browser_scratchpad_bug_646070_chrome_context_pref.js \
browser_scratchpad_bug_660560_tab.js \
browser_overflowScroll.js \
browser_locationBarExternalLoad.js \
browser_pageInfo.js \

View File

@ -11,15 +11,14 @@
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Satchel Test Code.
* The Original Code is bug 578534 test.
*
* The Initial Developer of the Original Code is
* Mozilla Corporation.
* Portions created by the Initial Developer are Copyright (C) 2008
* Sindre Dammann <sindrebugzilla@gmail.com>
* Portions created by the Initial Developer are Copyright (C) 2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Mike Connor <mconnor@mozilla.com> (Original Author)
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@ -35,29 +34,28 @@
*
* ***** END LICENSE BLOCK ***** */
// Test to make sure we drop formhistory.dat when clearing form history
function test() {
let uriString = "http://example.com/";
let cookieBehavior = "network.cookie.cookieBehavior";
let uriObj = Services.io.newURI(uriString, null, null)
let cp = Components.classes["@mozilla.org/cookie/permission;1"]
.getService(Components.interfaces.nsICookiePermission);
Services.prefs.setIntPref(cookieBehavior, 2);
function run_test()
{
var file = do_get_file("formhistory.dat");
var profileDir = dirSvc.get("ProfD", Ci.nsIFile);
var formhistFile = profileDir.clone();
formhistFile.append("formhistory.dat");
// Cleanup from any previous test.
if (formhistFile.exists())
formhistFile.remove(false);
do_check_false(formhistFile.exists());
// Copy a formhistory.dat into place
file.copyTo(profileDir, "formhistory.dat");
do_check_true(formhistFile.exists());
// Clear form history, test that file was deleted.
var formHistory = Cc["@mozilla.org/satchel/form-history;1"].
getService(Ci.nsIFormHistory2);
formHistory.removeAllEntries();
do_check_false(formhistFile.exists());
cp.setAccess(uriObj, cp.ACCESS_ALLOW);
gBrowser.selectedTab = gBrowser.addTab(uriString);
waitForExplicitFinish();
gBrowser.selectedBrowser.addEventListener("load", onTabLoaded, true);
function onTabLoaded() {
is(gBrowser.selectedBrowser.contentWindow.navigator.cookieEnabled, true,
"navigator.cookieEnabled should be true");
// Clean up
gBrowser.selectedBrowser.removeEventListener("load", onTabLoaded, true);
gBrowser.removeTab(gBrowser.selectedTab);
Services.prefs.setIntPref(cookieBehavior, 0);
cp.setAccess(uriObj, cp.ACCESS_DEFAULT);
finish();
}
}

View File

@ -78,14 +78,5 @@ function test() {
testPosition(7, 8, "blank tab without referrer opens at the end");
testPosition(8, 9, "tab without referrer opens at the end");
gBrowser.selectedTab = tabs[0];
gBrowser.pinTab(gBrowser.selectedTab);
addTab("http://mochi.test:8888/#8", gBrowser.currentURI);
testPosition(9, 10, "tab with referrer should open at the end when the selected tab is pinned");
gBrowser.selectedTab = tabs[9];
gBrowser.removeTab(tabs.pop());
is(gBrowser.selectedTab, tabs[0],
"opening a tab from a pinned tab, selecting it and closing it should go back to the pinned tab");
tabs.forEach(gBrowser.removeTab, gBrowser);
}

View File

@ -52,6 +52,7 @@ function runInspectorTests()
Services.obs.addObserver(finishInspectorTests,
INSPECTOR_NOTIFICATIONS.CLOSED, false);
ok(!InspectorUI.toolbar.hidden, "toolbar is visible");
let iframe = document.getElementById("inspector-tree-iframe");
is(InspectorUI.treeIFrame, iframe, "Inspector IFrame matches");
ok(InspectorUI.inspecting, "Inspector is inspecting");
@ -71,6 +72,7 @@ function finishInspectorTests()
ok(!InspectorUI.highlighter, "Highlighter is gone");
ok(!InspectorUI.isTreePanelOpen, "Inspector Tree Panel is closed");
ok(!InspectorUI.inspecting, "Inspector is not inspecting");
ok(InspectorUI.toolbar.hidden, "toolbar is hidden");
gBrowser.removeCurrentTab();
finish();

View File

@ -0,0 +1,61 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
function test() {
waitForExplicitFinish();
let doc;
let node1;
let node2;
gBrowser.selectedTab = gBrowser.addTab();
gBrowser.selectedBrowser.addEventListener("load", function onload() {
gBrowser.selectedBrowser.removeEventListener("load", onload, true);
doc = content.document;
waitForFocus(setupTest, content);
}, true);
content.location = "data:text/html,<div><p></p></div>";
function setupTest() {
node1 = doc.querySelector("div");
node2 = doc.querySelector("p");
Services.obs.addObserver(runTests, INSPECTOR_NOTIFICATIONS.OPENED, false);
InspectorUI.toggleInspectorUI();
}
function runTests() {
Services.obs.removeObserver(runTests, INSPECTOR_NOTIFICATIONS.OPENED);
testNode1();
}
function testNode1() {
let box = InspectorUI.ioBox.createObjectBox(node1);
box.click();
executeSoon(function() {
is(InspectorUI.selection, node1, "selection matches node");
is(InspectorUI.highlighter.node, node1, "selection matches node");
testNode2();
});
}
function testNode2() {
let box = InspectorUI.ioBox.createObjectBox(node2);
box.click();
executeSoon(function() {
is(InspectorUI.selection, node2, "selection matches node");
is(InspectorUI.highlighter.node, node2, "selection matches node");
Services.obs.addObserver(finishUp, INSPECTOR_NOTIFICATIONS.CLOSED, false);
InspectorUI.closeInspectorUI();
});
}
function finishUp() {
Services.obs.removeObserver(finishUp, INSPECTOR_NOTIFICATIONS.CLOSED);
doc = node1 = node2 = null;
gBrowser.removeCurrentTab();
finish();
}
}

View File

@ -21,6 +21,40 @@ Browser context menu subtest.
<textarea id="test-textarea">chssseesbbbie</textarea> <!-- a weird word which generates only one suggestion -->
<div id="test-contenteditable" contenteditable="true">chssseefsbbbie</div> <!-- a more weird word which generates no suggestions -->
<input id="test-input-spellcheck" type="text" spellcheck="true" autofocus value="prodkjfgigrty"> <!-- this one also generates one suggestion -->
<div contextmenu="myMenu">
<p id="test-pagemenu" hopeless="true">I've got a context menu!</p>
<menu id="myMenu" type="context">
<menuitem label="Plain item" onclick="document.getElementById('test-pagemenu').removeAttribute('hopeless');"></menuitem>
<menuitem label="Disabled item" disabled></menuitem>
<menu>
<menuitem type="checkbox" label="Checkbox" checked></menuitem>
</menu>
<menu>
<menuitem type="radio" label="Radio1" checked></menuitem>
<menuitem type="radio" label="Radio2"></menuitem>
<menuitem type="radio" label="Radio3"></menuitem>
</menu>
<menu>
<menuitem label="Item w/ icon" icon="favicon.ico"></menuitem>
<menuitem label="Item w/ bad icon" icon="data://www.mozilla.org/favicon.ico"></menuitem>
</menu>
<menu label="Submenu">
<menuitem type="radio" label="Radio1" radiogroup="rg"></menuitem>
<menuitem type="radio" label="Radio2" checked radiogroup="rg"></menuitem>
<menuitem type="radio" label="Radio3" radiogroup="rg"></menuitem>
<menu>
<menuitem type="checkbox" label="Checkbox"></menuitem>
</menu>
</menu>
<menu hidden>
<menuitem label="Bogus item"></menuitem>
</menu>
<menu>
</menu>
<menuitem label="Hidden item" hidden></menuitem>
<menuitem></menuitem>
</menu>
</div>
</body>
</html>

View File

@ -150,6 +150,8 @@ _BROWSER_FILES = \
browser_tabview_bug663421.js \
browser_tabview_bug665502.js \
browser_tabview_bug669694.js \
browser_tabview_bug673196.js \
browser_tabview_bug673729.js \
browser_tabview_click_group.js \
browser_tabview_dragdrop.js \
browser_tabview_exit_button.js \

View File

@ -3,75 +3,75 @@
function test() {
waitForExplicitFinish();
newWindowWithTabView(onTabViewWindowLoaded);
newWindowWithTabView(onTabViewShown);
}
function onTabViewWindowLoaded(win) {
win.removeEventListener("tabviewshown", onTabViewWindowLoaded, false);
ok(win.TabView.isVisible(), "Tab View is visible");
let contentWindow = win.document.getElementById("tab-view").contentWindow;
let [originalTab] = win.gBrowser.visibleTabs;
function onTabViewShown(win) {
registerCleanupFunction(function () win.close());
let contentWindow = win.TabView.getContentWindow();
let currentGroup = contentWindow.GroupItems.getActiveGroupItem();
function checkResized(diffX, diffY, shouldResize, text, callback) {
let {width: origWidth, height: origHeight} = currentGroup.getBounds();
resizeWindow(win, diffX, diffY, function () {
let {width: newWidth, height: newHeight} = currentGroup.getBounds();
let resized = (origWidth != newWidth || origHeight != newHeight);
is(resized, shouldResize, text + ": The group should " +
(shouldResize ? "" : "not ") + "have been resized");
callback();
});
}
function next() {
let test = tests.shift();
if (test)
checkResized.apply(this, test.concat([next]));
else
finishTest();
}
function finishTest() {
// reset the usersize of the group, so this should clear the "cramped" feeling.
currentGroup.setSize(100, 100, true);
currentGroup.setUserSize();
checkResized(400, 400, false, "After clearing the cramp", finish);
}
let tests = [
// diffX, diffY, shouldResize, text
[ -50, -50, false, "A little smaller"],
[ 50, 50, false, "A little bigger"],
[-400, -400, true, "Much smaller"],
[ 400, 400, true, "Bigger after much smaller"],
[-400, -400, true, "Much smaller"]
];
// setup
currentGroup.setSize(600, 600, true);
currentGroup.setUserSize();
let down1 = function down1(resized) {
checkResized(currentGroup, 50, 50, false, "A little bigger", up1, contentWindow, win);
};
let up1 = function up1(resized) {
checkResized(currentGroup, -400, -400, true, "Much smaller", down2, contentWindow, win);
}
let down2 = function down2(resized) {
checkResized(currentGroup, 400, 400, undefined,
"Bigger after much smaller: TODO (bug 625668): the group should be resized!",
up2, contentWindow, win);
};
let up2 = function up2(resized) {
checkResized(currentGroup, -400, -400, undefined,
"Much smaller: TODO (bug 625668): the group should be resized!",
down3, contentWindow, win);
}
let down3 = function down3(resized) {
// reset the usersize of the group, so this should clear the "cramped" feeling.
currentGroup.setSize(100,100,true);
currentGroup.setUserSize();
checkResized(currentGroup, 400, 400, false,
"After clearing the cramp",
up3, contentWindow, win);
};
let up3 = function up3(resized) {
win.close();
finish();
}
// start by making it a little smaller.
checkResized(currentGroup, -50, -50, false, "A little smaller", down1, contentWindow, win);
// run the tests
next();
}
function simulateResizeBy(xDiff, yDiff, win) {
win = win || window;
// ----------
function resizeWindow(win, diffX, diffY, callback) {
let targetWidth = win.outerWidth + diffX;
let targetHeight = win.outerHeight + diffY;
win.resizeBy(xDiff, yDiff);
}
function checkResized(item, xDiff, yDiff, expectResized, note, callback, contentWindow, win) {
let originalBounds = new contentWindow.Rect(item.getBounds());
simulateResizeBy(xDiff, yDiff, win);
let newBounds = item.getBounds();
let resized = !newBounds.equals(originalBounds);
if (expectResized !== undefined)
is(resized, expectResized, note + ": The group should " +
(expectResized ? "" : "not ") + "be resized");
callback(resized);
win.addEventListener("resize", function onResize() {
let {outerWidth: width, outerHeight: height} = win;
if (width != targetWidth || height != targetHeight)
return;
win.removeEventListener("resize", onResize, false);
executeSoon(callback);
}, false);
win.resizeBy(diffX, diffY);
}

View File

@ -0,0 +1,36 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
function test() {
function onLoad(win) {
registerCleanupFunction(function () win.close());
win.gBrowser.addTab();
}
function onShow(win) {
let cw = win.TabView.getContentWindow();
let group = cw.GroupItems.groupItems[0];
// shrink the group to make some room for dragging
group.setSize(200, 200, true);
waitForFocus(function () {
let target = group.getChild(0).container;
EventUtils.synthesizeMouseAtCenter(target, {type: "mousedown"}, cw);
EventUtils.synthesizeMouse(target, 0, 300, {type: "mousemove"}, cw);
EventUtils.synthesizeMouseAtCenter(target, {type: "mouseup"}, cw);
let newGroup = cw.GroupItems.groupItems[1];
let groupBounds = newGroup.getBounds();
let safeWindowBounds = cw.Items.getSafeWindowBounds();
ok(safeWindowBounds.contains(groupBounds),
"new group is within safe window bounds");
finish();
}, cw);
}
waitForExplicitFinish();
newWindowWithTabView(onShow, onLoad);
}

View File

@ -0,0 +1,42 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
function test() {
waitForExplicitFinish();
newWindowWithTabView(function (win) {
let cw = win.TabView.getContentWindow();
// turn off zoom animations
cw.gPrefBranch.setBoolPref("animate_zoom", false);
registerCleanupFunction(function () {
cw.gPrefBranch.clearUserPref("animate_zoom");
win.close();
});
let group = cw.GroupItems.groupItems[0];
group.setSize(100, 100, true);
while (!group.isStacked())
win.gBrowser.addTab();
waitForFocus(function () {
whenGroupIsExpanded(group, function () {
ok(win.TabView.isVisible(), "tabview is visible");
finish();
});
let expander = group.$expander[0];
EventUtils.synthesizeMouseAtCenter(expander, {}, cw);
}, cw);
});
}
// ----------
function whenGroupIsExpanded(group, callback) {
group.addSubscriber("expanded", function onExpanded() {
group.removeSubscriber("expanded", onExpanded);
executeSoon(callback);
});
}

View File

@ -22,7 +22,7 @@ function onTabViewLoadedAndShown() {
ok(TabView.isVisible(), "Tab View is visible");
// Establish initial state
contentWindow = document.getElementById("tab-view").contentWindow;
contentWindow = TabView.getContentWindow();
verifyCleanState("start");
// register a clean up for private browsing just in case
@ -50,40 +50,37 @@ function onTabViewLoadedAndShown() {
}
// Create a second tab
gBrowser.loadOneTab("about:robots", { inBackground: false });
gBrowser.addTab("about:robots");
is(gBrowser.tabs.length, 2, "we now have 2 tabs");
registerCleanupFunction(function() {
gBrowser.removeTab(gBrowser.tabs[1]);
});
afterAllTabsLoaded(function() {
showTabView(function() {
// Get normal tab urls
for (let a = 0; a < gBrowser.tabs.length; a++)
normalURLs.push(gBrowser.tabs[a].linkedBrowser.currentURI.spec);
// Get normal tab urls
for (let a = 0; a < gBrowser.tabs.length; a++)
normalURLs.push(gBrowser.tabs[a].linkedBrowser.currentURI.spec);
// verify that we're all set up for our test
verifyNormal();
// verify that we're all set up for our test
verifyNormal();
// go into private browsing and make sure Tab View becomes hidden
togglePBAndThen(function() {
whenTabViewIsHidden(function() {
ok(!TabView.isVisible(), "Tab View is no longer visible");
// go into private browsing and make sure Tab View becomes hidden
togglePBAndThen(function() {
whenTabViewIsHidden(function() {
ok(!TabView.isVisible(), "Tab View is no longer visible");
verifyPB();
verifyPB();
// exit private browsing and make sure Tab View is shown again
togglePBAndThen(function() {
whenTabViewIsShown(function() {
ok(TabView.isVisible(), "Tab View is visible again");
verifyNormal();
// exit private browsing and make sure Tab View is shown again
togglePBAndThen(function() {
whenTabViewIsShown(function() {
ok(TabView.isVisible(), "Tab View is visible again");
verifyNormal();
hideTabView(onTabViewHidden);
});
hideTabView(onTabViewHidden);
});
});
});
});
});
});
}
@ -103,6 +100,8 @@ function onTabViewHidden() {
// end game
ok(!TabView.isVisible(), "we finish with Tab View not visible");
registerCleanupFunction(verifyCleanState); // verify after all cleanups
gBrowser.selectedTab = gBrowser.tabs[0];
finish();
});
});

View File

@ -24,11 +24,11 @@ netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
const Cc = Components.classes;
const Ci = Components.interfaces;
function openContextMenuFor(element) {
function openContextMenuFor(element, shiftkey) {
// Context menu should be closed before we open it again.
is(contextMenu.state, "closed", "checking if popup is closed");
var eventDetails = { type : "contextmenu", button : 2 };
var eventDetails = { type : "contextmenu", button : 2, shiftKey : shiftkey };
synthesizeMouse(element, 2, 2, eventDetails, element.ownerDocument.defaultView);
}
@ -50,7 +50,15 @@ function executeCopyCommand(command, expectedValue)
is(input.value, expectedValue, "paste for command " + command);
}
function getVisibleMenuItems(aMenu) {
function invokeItemAction(ident)
{
var item = contextMenu.getElementsByAttribute("ident", ident)[0];
ok(item, "Got generated XUL menu item");
item.doCommand();
is(pagemenu.hasAttribute("hopeless"), false, "attribute got removed");
}
function getVisibleMenuItems(aMenu, aData) {
var items = [];
var accessKeys = {};
for (var i = 0; i < aMenu.childNodes.length; i++) {
@ -62,10 +70,14 @@ function getVisibleMenuItems(aMenu) {
if (key)
key = key.toLowerCase();
var isGenerated = item.hasAttribute("generated");
if (item.nodeName == "menuitem") {
var isSpellSuggestion = item.className == "spell-suggestion";
if (isSpellSuggestion) {
is(item.id, "", "child menuitem #" + i + " is a spelling suggestion");
} else if (isGenerated) {
is(item.id, "", "child menuitem #" + i + " is a generated item");
} else {
ok(item.id, "child menuitem #" + i + " has an ID");
}
@ -74,6 +86,8 @@ function getVisibleMenuItems(aMenu) {
if (isSpellSuggestion) {
is(key, "", "Spell suggestions shouldn't have an access key");
items.push("*" + label);
} else if (isGenerated) {
items.push("+" + label);
} else if (item.id.indexOf("spell-check-dictionary-") != 0 &&
item.id != "spell-no-suggestions") {
ok(key, "menuitem " + item.id + " has an access key");
@ -82,21 +96,35 @@ function getVisibleMenuItems(aMenu) {
else
accessKeys[key] = item.id;
}
if (!isSpellSuggestion) {
if (!isSpellSuggestion && !isGenerated) {
items.push(item.id);
}
items.push(!item.disabled);
if (isGenerated) {
var p = {};
p.type = item.getAttribute("type");
p.icon = item.getAttribute("image");
p.checked = item.hasAttribute("checked");
p.disabled = item.hasAttribute("disabled");
items.push(p);
} else {
items.push(!item.disabled);
}
} else if (item.nodeName == "menuseparator") {
ok(true, "--- seperator id is " + item.id);
items.push("---");
items.push(null);
} else if (item.nodeName == "menu") {
if (isGenerated) {
item.id = "generated-submenu-" + aData.generatedSubmenuId++;
}
ok(item.id, "child menu #" + i + " has an ID");
ok(key, "menu has an access key");
if (accessKeys[key])
ok(false, "menu " + item.id + " has same accesskey as " + accessKeys[key]);
else
accessKeys[key] = item.id;
if (!isGenerated) {
ok(key, "menu has an access key");
if (accessKeys[key])
ok(false, "menu " + item.id + " has same accesskey as " + accessKeys[key]);
else
accessKeys[key] = item.id;
}
items.push(item.id);
items.push(!item.disabled);
// Add a dummy item to that the indexes in checkMenu are the same
@ -113,7 +141,8 @@ function getVisibleMenuItems(aMenu) {
function checkContextMenu(expectedItems) {
is(contextMenu.state, "open", "checking if popup is open");
checkMenu(contextMenu, expectedItems);
var data = { generatedSubmenuId: 1 };
checkMenu(contextMenu, expectedItems, data);
}
/*
@ -129,8 +158,8 @@ function checkContextMenu(expectedItems) {
* "lol", false] // item disabled
*
*/
function checkMenu(menu, expectedItems) {
var actualItems = getVisibleMenuItems(menu);
function checkMenu(menu, expectedItems, data) {
var actualItems = getVisibleMenuItems(menu, data);
//ok(false, "Items are: " + actualItems);
for (var i = 0; i < expectedItems.length; i+=2) {
var actualItem = actualItems[i];
@ -142,11 +171,40 @@ function checkMenu(menu, expectedItems) {
var menuID = expectedItems[i - 2]; // The last item was the menu ID.
var submenu = menu.getElementsByAttribute("id", menuID)[0];
ok(submenu && submenu.nodeName == "menu", "got expected submenu element");
checkMenu(submenu.menupopup, expectedItem);
checkMenu(submenu.menupopup, expectedItem, data);
} else {
is(actualItem, expectedItem,
"checking item #" + i/2 + " (" + expectedItem + ") name");
if (expectedEnabled != null)
if (typeof expectedEnabled == "object" && expectedEnabled != null ||
typeof actualEnabled == "object" && actualEnabled != null) {
ok(!(actualEnabled == null), "actualEnabled is not null");
ok(!(expectedEnabled == null), "expectedEnabled is not null");
is(typeof actualEnabled, typeof expectedEnabled, "checking types");
if (typeof actualEnabled != typeof expectedEnabled ||
actualEnabled == null || expectedEnabled == null)
continue;
is(actualEnabled.type, expectedEnabled.type,
"checking item #" + i/2 + " (" + expectedItem + ") type attr value");
var icon = actualEnabled.icon;
if (icon) {
var tmp = "";
var j = icon.length - 1;
while (j && icon[j] != "/") {
tmp = icon[j--] + tmp;
}
icon = tmp;
}
is(icon, expectedEnabled.icon,
"checking item #" + i/2 + " (" + expectedItem + ") icon attr value");
is(actualEnabled.checked, expectedEnabled.checked,
"checking item #" + i/2 + " (" + expectedItem + ") has checked attr");
is(actualEnabled.disabled, expectedEnabled.disabled,
"checking item #" + i/2 + " (" + expectedItem + ") has disabled attr");
} else if (expectedEnabled != null)
is(actualEnabled, expectedEnabled,
"checking item #" + i/2 + " (" + expectedItem + ") enabled state");
}
@ -408,9 +466,70 @@ function runTest(testNum) {
openContextMenuFor(link); // Invoke context menu for next test.
break;
case 15:
case 15:
executeCopyCommand("cmd_copyLink", "http://mozilla.com/");
closeContextMenu();
openContextMenuFor(pagemenu); // Invoke context menu for next test.
break;
case 16:
// Context menu for element with assigned content context menu
checkContextMenu(["+Plain item", {type: "", icon: "", checked: false, disabled: false},
"+Disabled item", {type: "", icon: "", checked: false, disabled: true},
"---", null,
"+Checkbox", {type: "checkbox", icon: "", checked: true, disabled: false},
"---", null,
"+Radio1", {type: "checkbox", icon: "", checked: true, disabled: false},
"+Radio2", {type: "checkbox", icon: "", checked: false, disabled: false},
"+Radio3", {type: "checkbox", icon: "", checked: false, disabled: false},
"---", null,
"+Item w/ icon", {type: "", icon: "favicon.ico", checked: false, disabled: false},
"+Item w/ bad icon", {type: "", icon: "", checked: false, disabled: false},
"---", null,
"generated-submenu-1", true,
["+Radio1", {type: "checkbox", icon: "", checked: false, disabled: false},
"+Radio2", {type: "checkbox", icon: "", checked: true, disabled: false},
"+Radio3", {type: "checkbox", icon: "", checked: false, disabled: false},
"---", null,
"+Checkbox", {type: "checkbox", icon: "", checked: false, disabled: false}], null,
"---", null,
"context-back", false,
"context-forward", false,
"context-reload", true,
"context-stop", false,
"---", null,
"context-bookmarkpage", true,
"context-savepage", true,
"context-sendpage", true,
"---", null,
"context-viewbgimage", false,
"context-selectall", true,
"---", null,
"context-viewsource", true,
"context-viewinfo", true]);
invokeItemAction("0");
closeContextMenu();
openContextMenuFor(pagemenu, true); // Invoke context menu for next test.
break;
case 17:
// Context menu for element with assigned content context menu
// The shift key should bypass content context menu processing
checkContextMenu(["context-back", false,
"context-forward", false,
"context-reload", true,
"context-stop", false,
"---", null,
"context-bookmarkpage", true,
"context-savepage", true,
"context-sendpage", true,
"---", null,
"context-viewbgimage", false,
"context-selectall", true,
"---", null,
"context-viewsource", true,
"context-viewinfo", true]);
subwindow.close();
SimpleTest.finish();
@ -437,7 +556,7 @@ function runTest(testNum) {
var testNum = 1;
var subwindow, chromeWin, contextMenu;
var text, link, mailto, input, img, canvas, video_ok, video_bad, video_bad2,
iframe, textarea, contenteditable, inputspell;
iframe, textarea, contenteditable, inputspell, pagemenu;
function startTest() {
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
@ -470,6 +589,7 @@ function startTest() {
textarea = subwindow.document.getElementById("test-textarea");
contenteditable = subwindow.document.getElementById("test-contenteditable");
inputspell = subwindow.document.getElementById("test-input-spellcheck");
pagemenu = subwindow.document.getElementById("test-pagemenu");
contextMenu.addEventListener("popupshown", function() { runTest(++testNum); }, false);
runTest(1);

View File

@ -80,10 +80,10 @@
<popupset id="mainPopupSet">
<tooltip id="aHTMLTooltip" onpopupshowing="return FillInHTMLTooltip(document.tooltipNode);"/>
<menupopup id="contentAreaContextMenu"
<menupopup id="contentAreaContextMenu" pagemenu="start"
onpopupshowing="if (event.target != this)
return true;
gContextMenu = new nsContextMenu(this, getPanelBrowser());
gContextMenu = new nsContextMenu(this, getPanelBrowser(), event.shiftKey);
if (gContextMenu.shouldDisplay)
document.popupNode = this.triggerNode;
return gContextMenu.shouldDisplay;"

View File

@ -32,8 +32,6 @@ browser.jar:
* content/browser/content.js (content/content.js)
* content/browser/fullscreen-video.xhtml (content/fullscreen-video.xhtml)
* content/browser/inspector.html (content/inspector.html)
* content/browser/scratchpad.xul (content/scratchpad.xul)
* content/browser/scratchpad.js (content/scratchpad.js)
* content/browser/pageinfo/pageInfo.xul (content/pageinfo/pageInfo.xul)
* content/browser/pageinfo/pageInfo.js (content/pageinfo/pageInfo.js)
* content/browser/pageinfo/pageInfo.css (content/pageinfo/pageInfo.css)

View File

@ -60,10 +60,6 @@ WINDOWS_BRANDING_FILES = \
wizWatermark.bmp \
$(NULL)
ifdef MOZ_SPLASHSCREEN
WINDOWS_BRANDING_FILES += splash.bmp
endif
OSX_BRANDING_FILES = \
background.png \
firefox.icns \

Binary file not shown.

Before

Width:  |  Height:  |  Size: 232 KiB

View File

@ -60,10 +60,6 @@ WINDOWS_BRANDING_FILES = \
wizWatermark.bmp \
$(NULL)
ifdef MOZ_SPLASHSCREEN
WINDOWS_BRANDING_FILES += splash.bmp
endif
OSX_BRANDING_FILES = \
background.png \
firefox.icns \

Binary file not shown.

Before

Width:  |  Height:  |  Size: 232 KiB

Some files were not shown because too many files have changed in this diff Show More