From 25484458944977a8313f3bc9baebfa403dfb5aad Mon Sep 17 00:00:00 2001 From: Alexander Surkov Date: Fri, 14 May 2010 18:55:00 +0900 Subject: [PATCH] Bug 552944 - No relationship between tabs and associated property page in new tabbrowser construct, r=enn, davidb, marcoz, sr=neil --HG-- rename : accessible/tests/mochitest/test_relations.html => accessible/tests/mochitest/relations/test_general.html rename : accessible/tests/mochitest/test_relations.xul => accessible/tests/mochitest/relations/test_general.xul rename : accessible/tests/mochitest/test_relations_tree.xul => accessible/tests/mochitest/relations/test_tree.xul --- accessible/public/nsIAccessibleProvider.idl | 15 +- .../src/base/nsAccessibilityService.cpp | 6 +- accessible/src/xul/nsXULTabAccessible.cpp | 193 +++++------------- accessible/src/xul/nsXULTabAccessible.h | 35 ++-- accessible/tests/mochitest/Makefile.in | 5 +- .../tests/mochitest/relations/Makefile.in | 56 +++++ .../test_general.html} | 0 .../test_general.xul} | 0 .../mochitest/relations/test_tabbrowser.xul | 121 +++++++++++ .../test_tree.xul} | 0 .../tests/mochitest/tree/test_tabbox.xul | 39 ++-- .../tests/mochitest/tree/test_tabbrowser.xul | 12 +- dom/interfaces/xul/Makefile.in | 1 + .../xul/nsIDOMXULRelatedElement.idl | 51 +++++ toolkit/content/widgets/tabbox.xml | 155 ++++++++++---- 15 files changed, 462 insertions(+), 227 deletions(-) create mode 100644 accessible/tests/mochitest/relations/Makefile.in rename accessible/tests/mochitest/{test_relations.html => relations/test_general.html} (100%) rename accessible/tests/mochitest/{test_relations.xul => relations/test_general.xul} (100%) create mode 100644 accessible/tests/mochitest/relations/test_tabbrowser.xul rename accessible/tests/mochitest/{test_relations_tree.xul => relations/test_tree.xul} (100%) create mode 100644 dom/interfaces/xul/nsIDOMXULRelatedElement.idl diff --git a/accessible/public/nsIAccessibleProvider.idl b/accessible/public/nsIAccessibleProvider.idl index a2d196629b16..8559cbe8719f 100644 --- a/accessible/public/nsIAccessibleProvider.idl +++ b/accessible/public/nsIAccessibleProvider.idl @@ -45,7 +45,7 @@ object. For that XBL binding of element should implement the interface. */ -[scriptable, uuid(89fb8270-4f25-11df-9879-0800200c9a66)] +[scriptable, uuid(ac0639d5-f95b-4e2b-970c-9eab281fb6a5)] interface nsIAccessibleProvider : nsISupports { /** @@ -92,15 +92,12 @@ interface nsIAccessibleProvider : nsISupports const long XULRadioButton = 0x00001015; const long XULRadioGroup = 0x00001016; - /** The single tab in a dialog or tabbrowser/editor interface */ + /** Used for XUL tab element */ const long XULTab = 0x00001017; - - /** A combination of a tabs object and a tabpanels object */ - const long XULTabBox = 0x00001018; - - /** The collection of tab objects, usable in the TabBox and independent of it - as well */ - const long XULTabs = 0x00001019; + /** Used for XUL tabs element, a container for tab elements */ + const long XULTabs = 0x00001018; + /** Used for XUL tabpanels container element */ + const long XULTabpanels = 0x00001019; const long XULText = 0x0000101A; const long XULTextBox = 0x0000101B; diff --git a/accessible/src/base/nsAccessibilityService.cpp b/accessible/src/base/nsAccessibilityService.cpp index b0407f28c1c5..28dc36a330cf 100644 --- a/accessible/src/base/nsAccessibilityService.cpp +++ b/accessible/src/base/nsAccessibilityService.cpp @@ -1916,12 +1916,12 @@ nsAccessibilityService::CreateAccessibleByType(nsIDOMNode *aNode, case nsIAccessibleProvider::XULTab: accessible = new nsXULTabAccessible(aNode, aWeakShell); break; - case nsIAccessibleProvider::XULTabBox: - accessible = new nsXULTabBoxAccessible(aNode, aWeakShell); - break; case nsIAccessibleProvider::XULTabs: accessible = new nsXULTabsAccessible(aNode, aWeakShell); break; + case nsIAccessibleProvider::XULTabpanels: + accessible = new nsXULTabpanelsAccessible(aNode, aWeakShell); + break; case nsIAccessibleProvider::XULText: accessible = new nsXULTextAccessible(aNode, aWeakShell); break; diff --git a/accessible/src/xul/nsXULTabAccessible.cpp b/accessible/src/xul/nsXULTabAccessible.cpp index 046f2f4376bf..976a09a7d94c 100644 --- a/accessible/src/xul/nsXULTabAccessible.cpp +++ b/accessible/src/xul/nsXULTabAccessible.cpp @@ -47,6 +47,7 @@ #include "nsIDOMDocument.h" #include "nsIDOMXULSelectCntrlEl.h" #include "nsIDOMXULSelectCntrlItemEl.h" +#include "nsIDOMXULRelatedElement.h" //////////////////////////////////////////////////////////////////////////////// // nsXULTabAccessible @@ -149,56 +150,20 @@ nsXULTabAccessible::GetRelationByType(PRUint32 aRelationType, return NS_OK; // Expose 'LABEL_FOR' relation on tab accessible for tabpanel accessible. - // XXX: It makes sense to require the interface from xul:tab to get linked - // tabpanel element. nsCOMPtr content(do_QueryInterface(mDOMNode)); - - // Check whether tab and tabpanel are related by 'linkedPanel' attribute on - // xul:tab element. - rv = nsRelUtils::AddTargetFromIDRefAttr(aRelationType, aRelation, content, - nsAccessibilityAtoms::linkedPanel, - PR_TRUE); - NS_ENSURE_SUCCESS(rv, rv); - - if (rv != NS_OK_NO_RELATION_TARGET) + nsCOMPtr tabsElm = + do_QueryInterface(content->GetParent()); + if (!tabsElm) return NS_OK; - // If there is no 'linkedPanel' attribute on xul:tab element then we - // assume tab and tabpanels are related 1 to 1. We follow algorithm from - // the setter 'selectedIndex' of tabbox.xml#tabs binding. + nsCOMPtr tabpanelNode; + tabsElm->GetRelatedElement(mDOMNode, getter_AddRefs(tabpanelNode)); + if (!tabpanelNode) + return NS_OK; - nsAccessible* tabsAcc = GetParent(); - NS_ENSURE_TRUE(nsAccUtils::Role(tabsAcc) == nsIAccessibleRole::ROLE_PAGETABLIST, - NS_ERROR_FAILURE); - - PRInt32 tabIndex = -1; - - PRInt32 childCount = tabsAcc->GetChildCount(); - for (PRInt32 childIdx = 0; childIdx < childCount; childIdx++) { - nsAccessible* childAcc = tabsAcc->GetChildAt(childIdx); - if (nsAccUtils::Role(childAcc) == nsIAccessibleRole::ROLE_PAGETAB) - tabIndex++; - - if (childAcc == this) - break; - } - - nsAccessible* tabBoxAcc = tabsAcc->GetParent(); - NS_ENSURE_TRUE(nsAccUtils::Role(tabBoxAcc) == nsIAccessibleRole::ROLE_PANE, - NS_ERROR_FAILURE); - - childCount = tabBoxAcc->GetChildCount(); - for (PRInt32 childIdx = 0; childIdx < childCount; childIdx++) { - nsAccessible* childAcc = tabBoxAcc->GetChildAt(childIdx); - if (nsAccUtils::Role(childAcc) == nsIAccessibleRole::ROLE_PROPERTYPAGE) { - if (tabIndex == 0) - return nsRelUtils::AddTarget(aRelationType, aRelation, childAcc); - - tabIndex--; - } - } - - return NS_OK; + nsCOMPtr tabpanelContent(do_QueryInterface(tabpanelNode)); + return nsRelUtils::AddTargetFromContent(aRelationType, aRelation, + tabpanelContent); } void @@ -211,40 +176,15 @@ nsXULTabAccessible::GetPositionAndSizeInternal(PRInt32 *aPosInSet, //////////////////////////////////////////////////////////////////////////////// -// nsXULTabBoxAccessible +// nsXULTabsAccessible //////////////////////////////////////////////////////////////////////////////// -/** - * XUL TabBox - * to facilitate naming of the tabPanels object we will give this the name - * of the selected tab in the tabs object. - */ - -/** Constructor */ -nsXULTabBoxAccessible::nsXULTabBoxAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell): -nsAccessibleWrap(aNode, aShell) -{ -} - -/** We are a window*/ -nsresult -nsXULTabBoxAccessible::GetRoleInternal(PRUint32 *aRole) +nsXULTabsAccessible:: + nsXULTabsAccessible(nsIDOMNode *aNode, nsIWeakReference *aShell) : + nsXULSelectableAccessible(aNode, aShell) { - *aRole = nsIAccessibleRole::ROLE_PANE; - return NS_OK; } -/** - * XUL Tabs - the s really stands for strip. this is a collection of tab objects - */ - -/** Constructor */ -nsXULTabsAccessible::nsXULTabsAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell): -nsXULSelectableAccessible(aNode, aShell) -{ -} - -/** We are a Page Tab List */ nsresult nsXULTabsAccessible::GetRoleInternal(PRUint32 *aRole) { @@ -252,10 +192,12 @@ nsXULTabsAccessible::GetRoleInternal(PRUint32 *aRole) return NS_OK; } -/** no actions */ -NS_IMETHODIMP nsXULTabsAccessible::GetNumActions(PRUint8 *_retval) +NS_IMETHODIMP +nsXULTabsAccessible::GetNumActions(PRUint8 *aCount) { - *_retval = 0; + NS_ENSURE_ARG_POINTER(aCount); + *aCount = 0; + return NS_OK; } @@ -272,8 +214,28 @@ nsXULTabsAccessible::GetNameInternal(nsAString& aName) return NS_OK; } + +//////////////////////////////////////////////////////////////////////////////// +// nsXULTabpanelsAccessible +//////////////////////////////////////////////////////////////////////////////// + +nsXULTabpanelsAccessible:: + nsXULTabpanelsAccessible(nsIDOMNode *aNode, nsIWeakReference *aShell) : + nsAccessibleWrap(aNode, aShell) +{ +} + +nsresult +nsXULTabpanelsAccessible::GetRoleInternal(PRUint32 *aRole) +{ + *aRole = nsIAccessibleRole::ROLE_PANE; + return NS_OK; +} + + //////////////////////////////////////////////////////////////////////////////// // nsXULTabpanelAccessible +//////////////////////////////////////////////////////////////////////////////// nsXULTabpanelAccessible:: nsXULTabpanelAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell): @@ -299,71 +261,18 @@ nsXULTabpanelAccessible::GetRelationByType(PRUint32 aRelationType, return NS_OK; // Expose 'LABELLED_BY' relation on tabpanel accessible for tab accessible. - nsCOMPtr tabBoxAcc; - GetParent(getter_AddRefs(tabBoxAcc)); - NS_ENSURE_TRUE(nsAccUtils::Role(tabBoxAcc) == nsIAccessibleRole::ROLE_PANE, - NS_ERROR_FAILURE); - - PRInt32 tabpanelIndex = -1; - nsCOMPtr tabsAcc; - - PRBool isTabpanelFound = PR_FALSE; - nsCOMPtr childAcc; - tabBoxAcc->GetFirstChild(getter_AddRefs(childAcc)); - while (childAcc && (!tabsAcc || !isTabpanelFound)) { - if (nsAccUtils::Role(childAcc) == nsIAccessibleRole::ROLE_PAGETABLIST) - tabsAcc = childAcc; - - if (!isTabpanelFound && - nsAccUtils::Role(childAcc) == nsIAccessibleRole::ROLE_PROPERTYPAGE) - tabpanelIndex++; - - if (childAcc == this) - isTabpanelFound = PR_TRUE; - - nsCOMPtr acc; - childAcc->GetNextSibling(getter_AddRefs(acc)); - childAcc.swap(acc); - } - - if (!tabsAcc || tabpanelIndex == -1) + nsCOMPtr content(do_QueryInterface(mDOMNode)); + nsCOMPtr tabpanelsElm = + do_QueryInterface(content->GetParent()); + if (!tabpanelsElm) return NS_OK; - nsCOMPtr content(do_QueryInterface(mDOMNode)); - nsIAtom *atomID = content->GetID(); + nsCOMPtr tabNode; + tabpanelsElm->GetRelatedElement(mDOMNode, getter_AddRefs(tabNode)); + if (!tabNode) + return NS_OK; - nsCOMPtr foundTabAcc; - tabsAcc->GetFirstChild(getter_AddRefs(childAcc)); - while (childAcc) { - if (nsAccUtils::Role(childAcc) == nsIAccessibleRole::ROLE_PAGETAB) { - if (atomID) { - nsCOMPtr tabAccNode(do_QueryInterface(childAcc)); - nsCOMPtr tabNode; - tabAccNode->GetDOMNode(getter_AddRefs(tabNode)); - nsCOMPtr tabContent(do_QueryInterface(tabNode)); - NS_ENSURE_TRUE(tabContent, NS_ERROR_FAILURE); - - if (tabContent->AttrValueIs(kNameSpaceID_None, - nsAccessibilityAtoms::linkedPanel, atomID, - eCaseMatters)) { - return nsRelUtils::AddTarget(aRelationType, aRelation, childAcc); - } - } - - if (tabpanelIndex == 0) { - foundTabAcc = childAcc; - if (!atomID) - break; - } - - tabpanelIndex--; - } - - nsCOMPtr acc; - childAcc->GetNextSibling(getter_AddRefs(acc)); - childAcc.swap(acc); - } - - return nsRelUtils::AddTarget(aRelationType, aRelation, foundTabAcc); + nsCOMPtr tabContent(do_QueryInterface(tabNode)); + return nsRelUtils::AddTargetFromContent(aRelationType, aRelation, + tabContent); } - diff --git a/accessible/src/xul/nsXULTabAccessible.h b/accessible/src/xul/nsXULTabAccessible.h index cf4d28a80950..c9ea0886183d 100644 --- a/accessible/src/xul/nsXULTabAccessible.h +++ b/accessible/src/xul/nsXULTabAccessible.h @@ -44,7 +44,7 @@ #include "nsXULMenuAccessible.h" /** - * An individual tab, xul:tab element + * An individual tab, xul:tab element. */ class nsXULTabAccessible : public nsAccessibleWrap { @@ -67,22 +67,9 @@ public: virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState); }; -/** - * Contains a tabs object and a tabPanels object. A complete - * entity with relationships between tabs and content to - * be displayed in the tabpanels object - */ -class nsXULTabBoxAccessible : public nsAccessibleWrap -{ -public: - nsXULTabBoxAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell); - - // nsAccessible - virtual nsresult GetRoleInternal(PRUint32 *aRole); -}; /** - * A container of tab obejcts, xul:tabs element. + * A container of tab objects, xul:tabs element. */ class nsXULTabsAccessible : public nsXULSelectableAccessible { @@ -98,11 +85,29 @@ public: virtual nsresult GetRoleInternal(PRUint32 *aRole); }; + +/** + * A container of tab panels, xul:tabpanels element. + */ +class nsXULTabpanelsAccessible : public nsAccessibleWrap +{ +public: + nsXULTabpanelsAccessible(nsIDOMNode *aNode, nsIWeakReference *aShell); + + // nsAccessible + virtual nsresult GetRoleInternal(PRUint32 *aRole); +}; + + /** * A tabpanel object, child elements of xul:tabpanels element. Note,the object * is created from nsAccessibilityService::GetAccessibleForDeckChildren() * method and we do not use nsIAccessibleProvider interface here because * all children of xul:tabpanels element acts as xul:tabpanel element. + * + * XXX: we need to move the class logic into generic class since + * for example we do not create instance of this class for XUL textbox used as + * a tabpanel. */ class nsXULTabpanelAccessible : public nsAccessibleWrap { diff --git a/accessible/tests/mochitest/Makefile.in b/accessible/tests/mochitest/Makefile.in index 5fb2b0c048d6..3eb22c1cc37b 100644 --- a/accessible/tests/mochitest/Makefile.in +++ b/accessible/tests/mochitest/Makefile.in @@ -42,7 +42,7 @@ srcdir = @srcdir@ VPATH = @srcdir@ relativesrcdir = accessible -DIRS = actions attributes events selectable states tree +DIRS = actions attributes events relations selectable states tree include $(DEPTH)/config/autoconf.mk include $(topsrcdir)/config/rules.mk @@ -104,9 +104,6 @@ _TEST_FILES =\ test_nsIAccessibleImage.html \ test_nsIAccessNode_utils.html \ test_nsOuterDocAccessible.html \ - test_relations.html \ - test_relations.xul \ - test_relations_tree.xul \ test_role_nsHyperTextAcc.html \ test_table_1.html \ test_table_4.html \ diff --git a/accessible/tests/mochitest/relations/Makefile.in b/accessible/tests/mochitest/relations/Makefile.in new file mode 100644 index 000000000000..813f7b6a4632 --- /dev/null +++ b/accessible/tests/mochitest/relations/Makefile.in @@ -0,0 +1,56 @@ +# +# ***** BEGIN LICENSE BLOCK ***** +# Version: MPL 1.1/GPL 2.0/LGPL 2.1 +# +# The contents of this file are subject to the Mozilla Public License Version +# 1.1 (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +# for the specific language governing rights and limitations under the +# License. +# +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Mozilla Corporation. +# Portions created by the Initial Developer are Copyright (C) 2010 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Alexander Surkov (original author) +# +# Alternatively, the contents of this file may be used under the terms of +# either of the GNU General Public License Version 2 or later (the "GPL"), +# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), +# in which case the provisions of the GPL or the LGPL are applicable instead +# of those above. If you wish to allow use of your version of this file only +# under the terms of either the GPL or the LGPL, and not to allow others to +# use your version of this file under the terms of the MPL, indicate your +# decision by deleting the provisions above and replace them with the notice +# and other provisions required by the GPL or the LGPL. If you do not delete +# the provisions above, a recipient may use your version of this file under +# the terms of any one of the MPL, the GPL or the LGPL. +# +# ***** END LICENSE BLOCK ***** + +DEPTH = ../../../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ +relativesrcdir = accessible/relations + +include $(DEPTH)/config/autoconf.mk +include $(topsrcdir)/config/rules.mk + +_TEST_FILES =\ + test_general.html \ + test_general.xul \ + test_tabbrowser.xul \ + test_tree.xul \ + $(NULL) + +libs:: $(_TEST_FILES) + $(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/a11y/$(relativesrcdir) diff --git a/accessible/tests/mochitest/test_relations.html b/accessible/tests/mochitest/relations/test_general.html similarity index 100% rename from accessible/tests/mochitest/test_relations.html rename to accessible/tests/mochitest/relations/test_general.html diff --git a/accessible/tests/mochitest/test_relations.xul b/accessible/tests/mochitest/relations/test_general.xul similarity index 100% rename from accessible/tests/mochitest/test_relations.xul rename to accessible/tests/mochitest/relations/test_general.xul diff --git a/accessible/tests/mochitest/relations/test_tabbrowser.xul b/accessible/tests/mochitest/relations/test_tabbrowser.xul new file mode 100644 index 000000000000..24ebdc09cea3 --- /dev/null +++ b/accessible/tests/mochitest/relations/test_tabbrowser.xul @@ -0,0 +1,121 @@ + + + + + + + + + + + + + Mozilla Bug 552944 +
+

+ +
+      
+ + + + + + + + + + + + + + + + +
+ +
+ diff --git a/accessible/tests/mochitest/test_relations_tree.xul b/accessible/tests/mochitest/relations/test_tree.xul similarity index 100% rename from accessible/tests/mochitest/test_relations_tree.xul rename to accessible/tests/mochitest/relations/test_tree.xul diff --git a/accessible/tests/mochitest/tree/test_tabbox.xul b/accessible/tests/mochitest/tree/test_tabbox.xul index f24a1979ce70..44d66930d868 100644 --- a/accessible/tests/mochitest/tree/test_tabbox.xul +++ b/accessible/tests/mochitest/tree/test_tabbox.xul @@ -27,21 +27,23 @@ // tabbox var accTree = { - role: ROLE_PANE, + role: ROLE_PAGETABLIST, children: [ { - role: ROLE_PAGETABLIST, - children: [ - { - role: ROLE_PAGETAB, - children: [] - }, - { - role: ROLE_PAGETAB, - children: [] - } - ] + role: ROLE_PAGETAB, + children: [] }, + { + role: ROLE_PAGETAB, + children: [] + } + ] + }; + testAccessibleTree("tabs", accTree); + + accTree = { + role: ROLE_PANE, + children: [ { role: ROLE_PROPERTYPAGE, children: [] @@ -52,7 +54,7 @@ } ] }; - testAccessibleTree("tabbox", accTree); + testAccessibleTree("tabpanels", accTree); SimpleTest.finish() } @@ -69,6 +71,11 @@ title=" WARNING: Bad accessible tree!: [tabbrowser tab] "> Mozilla Bug 540389
+ + Mozilla Bug 552944 +

@@ -77,12 +84,12 @@ - - + + - + diff --git a/accessible/tests/mochitest/tree/test_tabbrowser.xul b/accessible/tests/mochitest/tree/test_tabbrowser.xul index 691f161c7872..4cc728d97e31 100644 --- a/accessible/tests/mochitest/tree/test_tabbrowser.xul +++ b/accessible/tests/mochitest/tree/test_tabbrowser.xul @@ -91,6 +91,8 @@ } ] }; + testAccessibleTree(getNode("tabbrowser").tabContainer, tabsAccTree); + var tabboxAccTree = { role: ROLE_PANE, children: [ @@ -102,8 +104,9 @@ } ] }; - testAccessibleTree(getNode("tabbrowser").tabContainer, tabsAccTree); - testAccessibleTree(getNode("tabbrowser").mTabBox, tabboxAccTree); + + testAccessibleTree(getNode("tabbrowser").mTabBox.tabpanels, + tabboxAccTree); SimpleTest.finish() } @@ -120,6 +123,11 @@ title=" WARNING: Bad accessible tree!: [tabbrowser tab] "> Mozilla Bug 540389
+ + Mozilla Bug 552944 +

diff --git a/dom/interfaces/xul/Makefile.in b/dom/interfaces/xul/Makefile.in index 99f64b0ce862..7522b20d07b5 100644 --- a/dom/interfaces/xul/Makefile.in +++ b/dom/interfaces/xul/Makefile.in @@ -61,6 +61,7 @@ XPIDLSRCS = \ nsIDOMXULLabeledControlEl.idl \ nsIDOMXULMenuListElement.idl \ nsIDOMXULPopupElement.idl \ + nsIDOMXULRelatedElement.idl \ nsIDOMXULSelectCntrlEl.idl \ nsIDOMXULSelectCntrlItemEl.idl \ nsIDOMXULMultSelectCntrlEl.idl \ diff --git a/dom/interfaces/xul/nsIDOMXULRelatedElement.idl b/dom/interfaces/xul/nsIDOMXULRelatedElement.idl new file mode 100644 index 000000000000..1c1cb9522404 --- /dev/null +++ b/dom/interfaces/xul/nsIDOMXULRelatedElement.idl @@ -0,0 +1,51 @@ +/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Alexander Surkov (original author) + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "domstubs.idl" + +[scriptable, uuid(9fbac05a-fb27-470d-8e5f-028b2dc54ad0)] +interface nsIDOMXULRelatedElement : nsISupports +{ + /** + * Retrun an element associated with the given element. It's implemented + * by container elements having relation between their items. For example, + * this interface is implemented by XUL tabs and XUL tabpanels elements + * and used to get XUL tab element by linked tab panel and vice versa. + */ + nsIDOMNode getRelatedElement(in nsIDOMNode aElement); +}; diff --git a/toolkit/content/widgets/tabbox.xml b/toolkit/content/widgets/tabbox.xml index 47dd11fd35e1..6a5d95b4d8e0 100644 --- a/toolkit/content/widgets/tabbox.xml +++ b/toolkit/content/widgets/tabbox.xml @@ -13,15 +13,7 @@ - - - - - - - + - + - + + + + + + + + + + + @@ -347,31 +389,13 @@ this.setAttribute("value", tab.value); - if (this.tabbox) { + let linkedPanel = this.getRelatedElement(tab); + if (linkedPanel) { this.tabbox.setAttribute("selectedIndex", val); - var tabpanels = this.tabbox.tabpanels; - // This will cause an onselect event to fire for the tabpanel element. - if (tabpanels) { - // find an id - let linkedPanelId = tab.linkedPanel; - let linkedPanel = null; - if (linkedPanelId) { - let ownerDoc = tab.ownerDocument; - let bindingParent = ownerDoc.getBindingParent(tab); - if (bindingParent) { - linkedPanel = - ownerDoc.getAnonymousElementByAttribute(bindingParent, - "id", - linkedPanelId); - } - else - linkedPanel = ownerDoc.getElementById(linkedPanelId); - } - if (linkedPanel) - tabpanels.selectedPanel = linkedPanel; - else - tabpanels.selectedIndex = val; - } + + // This will cause an onselect event to fire for the tabpanel + // element. + this.tabbox.tabpanels.selectedPanel = linkedPanel; } if (!alreadySelected) { @@ -555,7 +579,66 @@ - + + + + + + + + + + + + + + + + + + + this.childNodes.item(this.selectedIndex)