diff --git a/CLOBBER b/CLOBBER index cc2cb7ee4f26..0e5e67c75aa0 100644 --- a/CLOBBER +++ b/CLOBBER @@ -18,4 +18,4 @@ # Modifying this file will now automatically clobber the buildbot machines \o/ # -Australis landing. +More Windows WebIDL changes. diff --git a/Makefile.in b/Makefile.in index 6ae7359f5a2b..fba5cd3b3881 100644 --- a/Makefile.in +++ b/Makefile.in @@ -253,13 +253,6 @@ endif ifdef BUILD_JS js/src/Makefile: subsrcdir := js/src -ifdef ENABLE_TESTS -# Incorporate static tier directories into tests. This should be incorporated -# into moz.build files someday. -check:: - $(call SUBMAKE,$@,js/src) -endif - ifdef MOZ_PSEUDO_DERECURSE # Interdependencies for parallel export. js/xpconnect/src/export: dom/bindings/export xpcom/xpidl/export diff --git a/accessible/moz.build b/accessible/moz.build index dbd2b9f8dd25..eadf65148c7d 100644 --- a/accessible/moz.build +++ b/accessible/moz.build @@ -7,5 +7,3 @@ DIRS += ['public', 'src'] TEST_DIRS += ['tests'] -MODULE = 'accessibility' - diff --git a/accessible/public/ia2/Makefile.in b/accessible/public/ia2/Makefile.in index 94c1dc180169..b00410aa64dc 100644 --- a/accessible/public/ia2/Makefile.in +++ b/accessible/public/ia2/Makefile.in @@ -10,8 +10,6 @@ DEFINES += -DREGISTER_PROXY_DLL GARBAGE += $(MIDL_GENERATED_FILES) -FORCE_SHARED_LIB = 1 - # Please keep this list in sync with the moz.build file until the rest of this # Makefile is ported over. MIDL_INTERFACES = \ diff --git a/accessible/public/ia2/moz.build b/accessible/public/ia2/moz.build index ba9c2b6207fb..be2265e8d1a2 100644 --- a/accessible/public/ia2/moz.build +++ b/accessible/public/ia2/moz.build @@ -4,6 +4,6 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -MODULE = 'accessibility' LIBRARY_NAME = 'IA2Marshal' +FORCE_SHARED_LIB = True diff --git a/accessible/public/moz.build b/accessible/public/moz.build index be9cc2aea0dc..9c6446b8f375 100644 --- a/accessible/public/moz.build +++ b/accessible/public/moz.build @@ -35,7 +35,7 @@ XPIDL_SOURCES += [ 'nsIXBLAccessible.idl', ] -MODULE = 'accessibility' +XPIDL_MODULE = 'accessibility' EXPORTS += [ 'nsIAccessibilityService.h', diff --git a/accessible/public/msaa/Makefile.in b/accessible/public/msaa/Makefile.in index 05a6fb1a9b92..fed4aaf8c522 100644 --- a/accessible/public/msaa/Makefile.in +++ b/accessible/public/msaa/Makefile.in @@ -8,8 +8,6 @@ DEFINES += -DREGISTER_PROXY_DLL GARBAGE += $(MIDL_GENERATED_FILES) done_gen dlldata.c -FORCE_SHARED_LIB = 1 - MIDL_GENERATED_FILES = \ ISimpleDOMNode.h \ ISimpleDOMNode_p.c \ diff --git a/accessible/public/msaa/moz.build b/accessible/public/msaa/moz.build index c268719ddd16..6321c5d31d52 100644 --- a/accessible/public/msaa/moz.build +++ b/accessible/public/msaa/moz.build @@ -4,8 +4,6 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -MODULE = 'accessibility' - LIBRARY_NAME = 'AccessibleMarshal' GENERATED_SOURCES += [ @@ -17,3 +15,5 @@ GENERATED_SOURCES += [ 'ISimpleDOMText_i.c', 'ISimpleDOMText_p.c', ] + +FORCE_SHARED_LIB = True diff --git a/accessible/public/nsIAccessibleEditableText.idl b/accessible/public/nsIAccessibleEditableText.idl index 64d199b9d34d..9f4066570788 100644 --- a/accessible/public/nsIAccessibleEditableText.idl +++ b/accessible/public/nsIAccessibleEditableText.idl @@ -6,24 +6,9 @@ #include "nsISupports.idl" -interface nsIEditor; - -[scriptable, uuid(e242d495-5cde-4b1c-8c84-2525b14939f5)] +[scriptable, uuid(93d0ba57-0d20-49d1-aede-8fde6699855d)] interface nsIAccessibleEditableText : nsISupports { - /** - * Sets the attributes for the text between the two given indices. The old - * attributes are replaced by the new list of attributes. For example, - * sets font styles, such as italic, bold... - * - * @param startPos - start index of the text whose attributes are modified. - * @param endPos - end index of the text whose attributes are modified. - * @param attributes - set of attributes that replaces the old list of - * attributes of the specified text portion. - */ - void setAttributes (in long startPos, in long endPos, - in nsISupports attributes); - /** * Replaces the text represented by this object by the given text. */ @@ -35,7 +20,8 @@ interface nsIAccessibleEditableText : nsISupports * @param text - text that is inserted. * @param position - index at which to insert the text. */ - void insertText (in AString text, in long position); + [binaryname(ScriptableInsertText)] + void insertText(in AString text, in long position); /** * Copies the text range into the clipboard. @@ -43,7 +29,8 @@ interface nsIAccessibleEditableText : nsISupports * @param startPos - start index of the text to moved into the clipboard. * @param endPos - end index of the text to moved into the clipboard. */ - void copyText (in long startPos, in long endPos); + [binaryname(ScriptableCopyText)] + void copyText(in long startPos, in long endPos); /** * Deletes a range of text and copies it to the clipboard. @@ -51,7 +38,8 @@ interface nsIAccessibleEditableText : nsISupports * @param startPos - start index of the text to be deleted. * @param endOffset - end index of the text to be deleted. */ - void cutText (in long startPos, in long endPos); + [binaryname(ScriptableCutText)] + void cutText(in long startPos, in long endPos); /** * Deletes a range of text. @@ -59,7 +47,8 @@ interface nsIAccessibleEditableText : nsISupports * @param startPos - start index of the text to be deleted. * @param endPos - end index of the text to be deleted. */ - void deleteText (in long startPos, in long endPos); + [binaryname(ScriptableDeleteText)] + void deleteText(in long startPos, in long endPos); /** * Pastes text from the clipboard. @@ -67,5 +56,6 @@ interface nsIAccessibleEditableText : nsISupports * @param position - index at which to insert the text from the system * clipboard into the text represented by this object. */ - void pasteText (in long position); + [binaryname(ScriptablePasteText)] + void pasteText(in long position); }; diff --git a/accessible/public/nsIAccessibleText.idl b/accessible/public/nsIAccessibleText.idl index bd0f28bbda5d..d271ced31084 100644 --- a/accessible/public/nsIAccessibleText.idl +++ b/accessible/public/nsIAccessibleText.idl @@ -11,7 +11,7 @@ typedef long AccessibleTextBoundary; interface nsIAccessible; interface nsIPersistentProperties; -[scriptable, uuid(43d81eb0-1215-4dc4-9226-a4355bd2d20d)] +[scriptable, uuid(1e63dd8b-173d-4a68-8ade-fd671abbe1ee)] interface nsIAccessibleText : nsISupports { // In parameters for character offsets: @@ -32,6 +32,7 @@ interface nsIAccessibleText : nsISupports * The current current caret offset. * If set < 0 then caret will be placed at the end of the text */ + [binaryname(ScriptableCaretOffset)] attribute long caretOffset; readonly attribute long characterCount; @@ -168,6 +169,7 @@ interface nsIAccessibleText : nsISupports * @param scrollType defines how to scroll (see nsIAccessibleScrollType for * available constants) */ + [binaryname(ScriptableScrollSubstringTo)] void scrollSubstringTo(in long startIndex, in long endIndex, in unsigned long scrollType); @@ -183,6 +185,7 @@ interface nsIAccessibleText : nsISupports * @param x defines the x coordinate * @param y defines the y coordinate */ + [binaryname(ScriptableScrollSubstringToPoint)] void scrollSubstringToPoint(in long startIndex, in long endIndex, in unsigned long coordinateType, in long x, in long y); diff --git a/accessible/src/atk/AccessibleWrap.cpp b/accessible/src/atk/AccessibleWrap.cpp index 6a5df3134ea3..8de738ece68a 100644 --- a/accessible/src/atk/AccessibleWrap.cpp +++ b/accessible/src/atk/AccessibleWrap.cpp @@ -157,6 +157,7 @@ static const gchar* getNameCB (AtkObject *aAtkObj); const gchar* getDescriptionCB (AtkObject *aAtkObj); static AtkRole getRoleCB(AtkObject *aAtkObj); static AtkAttributeSet* getAttributesCB(AtkObject *aAtkObj); +static const gchar* GetLocaleCB(AtkObject*); static AtkObject* getParentCB(AtkObject *aAtkObj); static gint getChildCountCB(AtkObject *aAtkObj); static AtkObject* refChildCB(AtkObject *aAtkObj, gint aChildIndex); @@ -489,6 +490,7 @@ classInitCB(AtkObjectClass *aClass) aClass->get_index_in_parent = getIndexInParentCB; aClass->get_role = getRoleCB; aClass->get_attributes = getAttributesCB; + aClass->get_object_locale = GetLocaleCB; aClass->ref_state_set = refStateSetCB; aClass->ref_relation_set = refRelationSetCB; @@ -754,6 +756,18 @@ getAttributesCB(AtkObject *aAtkObj) return accWrap ? GetAttributeSet(accWrap) : nullptr; } +const gchar* +GetLocaleCB(AtkObject* aAtkObj) +{ + AccessibleWrap* accWrap = GetAccessibleWrap(aAtkObj); + if (!accWrap) + return nullptr; + + nsAutoString locale; + accWrap->Language(locale); + return AccessibleWrap::ReturnString(locale); +} + AtkObject * getParentCB(AtkObject *aAtkObj) { @@ -982,6 +996,7 @@ AccessibleWrap::HandleAccEvent(AccEvent* aEvent) { a11y::RootAccessible* rootAccWrap = accWrap->RootAccessible(); if (rootAccWrap && rootAccWrap->mActivated) { + atk_focus_tracker_notify(atkObj); // Fire state change event for focus atk_object_notify_state_change(atkObj, ATK_STATE_FOCUSED, true); return NS_OK; @@ -1167,6 +1182,7 @@ AccessibleWrap::HandleAccEvent(AccEvent* aEvent) break; case nsIAccessibleEvent::EVENT_MENUPOPUP_START: + atk_focus_tracker_notify(atkObj); // fire extra focus event atk_object_notify_state_change(atkObj, ATK_STATE_VISIBLE, true); atk_object_notify_state_change(atkObj, ATK_STATE_SHOWING, true); break; diff --git a/accessible/src/atk/Makefile.in b/accessible/src/atk/Makefile.in index 044404dfe0ff..6f52656bfa01 100644 --- a/accessible/src/atk/Makefile.in +++ b/accessible/src/atk/Makefile.in @@ -2,7 +2,6 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -EXPORT_LIBRARY = .. include $(topsrcdir)/config/rules.mk ifdef MOZ_ENABLE_GTK diff --git a/accessible/src/atk/moz.build b/accessible/src/atk/moz.build index 9d0cf96e7ba1..f5caab62e44b 100644 --- a/accessible/src/atk/moz.build +++ b/accessible/src/atk/moz.build @@ -4,8 +4,6 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -MODULE = 'accessibility' - EXPORTS.mozilla.a11y += [ 'AccessibleWrap.h', 'HyperTextAccessibleWrap.h', @@ -33,10 +31,6 @@ SOURCES += [ 'UtilInterface.cpp', ] -LIBRARY_NAME = 'accessibility_toolkit_s' - -LIBXUL_LIBRARY = True - LOCAL_INCLUDES += [ '../base', '../generic', @@ -46,3 +40,4 @@ LOCAL_INCLUDES += [ '/other-licenses/atk-1.0', ] +FINAL_LIBRARY = 'xul' diff --git a/accessible/src/atk/nsMaiInterfaceEditableText.cpp b/accessible/src/atk/nsMaiInterfaceEditableText.cpp index e96d9324e3a2..6f76940a4efc 100644 --- a/accessible/src/atk/nsMaiInterfaceEditableText.cpp +++ b/accessible/src/atk/nsMaiInterfaceEditableText.cpp @@ -7,7 +7,7 @@ #include "InterfaceInitFuncs.h" #include "Accessible-inl.h" -#include "HyperTextAccessible.h" +#include "HyperTextAccessible-inl.h" #include "nsMai.h" #include "nsString.h" @@ -28,7 +28,7 @@ setTextContentsCB(AtkEditableText *aText, const gchar *aString) return; NS_ConvertUTF8toUTF16 strContent(aString); - text->SetTextContents(strContent); + text->ReplaceText(strContent); } static void diff --git a/accessible/src/atk/nsMaiInterfaceHypertext.cpp b/accessible/src/atk/nsMaiInterfaceHypertext.cpp index d0d836306060..7baa58cf1fb4 100644 --- a/accessible/src/atk/nsMaiInterfaceHypertext.cpp +++ b/accessible/src/atk/nsMaiInterfaceHypertext.cpp @@ -26,7 +26,7 @@ getLinkCB(AtkHypertext *aText, gint aLinkIndex) HyperTextAccessible* hyperText = accWrap->AsHyperText(); NS_ENSURE_TRUE(hyperText, nullptr); - Accessible* hyperLink = hyperText->GetLinkAt(aLinkIndex); + Accessible* hyperLink = hyperText->LinkAt(aLinkIndex); if (!hyperLink) return nullptr; @@ -49,7 +49,7 @@ getLinkCountCB(AtkHypertext *aText) HyperTextAccessible* hyperText = accWrap->AsHyperText(); NS_ENSURE_TRUE(hyperText, -1); - return hyperText->GetLinkCount(); + return hyperText->LinkCount(); } static gint @@ -62,11 +62,7 @@ getLinkIndexCB(AtkHypertext *aText, gint aCharIndex) HyperTextAccessible* hyperText = accWrap->AsHyperText(); NS_ENSURE_TRUE(hyperText, -1); - int32_t index = -1; - nsresult rv = hyperText->GetLinkIndexAtOffset(aCharIndex, &index); - NS_ENSURE_SUCCESS(rv, -1); - - return index; + return hyperText->LinkIndexAtOffset(aCharIndex); } } diff --git a/accessible/src/atk/nsMaiInterfaceText.cpp b/accessible/src/atk/nsMaiInterfaceText.cpp index df41df047996..3e373d2d44f4 100644 --- a/accessible/src/atk/nsMaiInterfaceText.cpp +++ b/accessible/src/atk/nsMaiInterfaceText.cpp @@ -7,7 +7,7 @@ #include "InterfaceInitFuncs.h" #include "Accessible-inl.h" -#include "HyperTextAccessible.h" +#include "HyperTextAccessible-inl.h" #include "nsMai.h" #include "nsIAccessibleTypes.h" @@ -43,8 +43,7 @@ getTextCB(AtkText *aText, gint aStartOffset, gint aEndOffset) return nullptr; nsAutoString autoStr; - nsresult rv = text->GetText(aStartOffset, aEndOffset, autoStr); - NS_ENSURE_SUCCESS(rv, nullptr); + text->TextSubstring(aStartOffset, aEndOffset, autoStr); ConvertTexttoAsterisks(accWrap, autoStr); NS_ConvertUTF16toUTF8 cautoStr(autoStr); @@ -68,18 +67,14 @@ getTextAfterOffsetCB(AtkText *aText, gint aOffset, nsAutoString autoStr; int32_t startOffset = 0, endOffset = 0; - nsresult rv = - text->GetTextAfterOffset(aOffset, aBoundaryType, - &startOffset, &endOffset, autoStr); + text->TextAfterOffset(aOffset, aBoundaryType, &startOffset, &endOffset, autoStr); *aStartOffset = startOffset; *aEndOffset = endOffset; - NS_ENSURE_SUCCESS(rv, nullptr); - - ConvertTexttoAsterisks(accWrap, autoStr); - NS_ConvertUTF16toUTF8 cautoStr(autoStr); - return (cautoStr.get()) ? g_strdup(cautoStr.get()) : nullptr; + ConvertTexttoAsterisks(accWrap, autoStr); + NS_ConvertUTF16toUTF8 cautoStr(autoStr); + return (cautoStr.get()) ? g_strdup(cautoStr.get()) : nullptr; } static gchar* @@ -97,14 +92,10 @@ getTextAtOffsetCB(AtkText *aText, gint aOffset, nsAutoString autoStr; int32_t startOffset = 0, endOffset = 0; - nsresult rv = - text->GetTextAtOffset(aOffset, aBoundaryType, - &startOffset, &endOffset, autoStr); + text->TextAtOffset(aOffset, aBoundaryType, &startOffset, &endOffset, autoStr); *aStartOffset = startOffset; *aEndOffset = endOffset; - NS_ENSURE_SUCCESS(rv, nullptr); - ConvertTexttoAsterisks(accWrap, autoStr); NS_ConvertUTF16toUTF8 cautoStr(autoStr); return (cautoStr.get()) ? g_strdup(cautoStr.get()) : nullptr; @@ -148,19 +139,16 @@ getTextBeforeOffsetCB(AtkText *aText, gint aOffset, if (!text || !text->IsTextRole()) return nullptr; - nsAutoString autoStr; - int32_t startOffset = 0, endOffset = 0; - nsresult rv = - text->GetTextBeforeOffset(aOffset, aBoundaryType, - &startOffset, &endOffset, autoStr); - *aStartOffset = startOffset; - *aEndOffset = endOffset; + nsAutoString autoStr; + int32_t startOffset = 0, endOffset = 0; + text->TextBeforeOffset(aOffset, aBoundaryType, + &startOffset, &endOffset, autoStr); + *aStartOffset = startOffset; + *aEndOffset = endOffset; - NS_ENSURE_SUCCESS(rv, nullptr); - - ConvertTexttoAsterisks(accWrap, autoStr); - NS_ConvertUTF16toUTF8 cautoStr(autoStr); - return (cautoStr.get()) ? g_strdup(cautoStr.get()) : nullptr; + ConvertTexttoAsterisks(accWrap, autoStr); + NS_ConvertUTF16toUTF8 cautoStr(autoStr); + return (cautoStr.get()) ? g_strdup(cautoStr.get()) : nullptr; } static gint @@ -174,9 +162,7 @@ getCaretOffsetCB(AtkText *aText) if (!text || !text->IsTextRole()) return 0; - int32_t offset; - nsresult rv = text->GetCaretOffset(&offset); - return (NS_FAILED(rv)) ? 0 : static_cast(offset); + return static_cast(text->CaretOffset()); } static AtkAttributeSet* @@ -195,17 +181,14 @@ getRunAttributesCB(AtkText *aText, gint aOffset, if (!text || !text->IsTextRole()) return nullptr; - nsCOMPtr attributes; - int32_t startOffset = 0, endOffset = 0; - nsresult rv = text->GetTextAttributes(false, aOffset, - &startOffset, &endOffset, - getter_AddRefs(attributes)); - NS_ENSURE_SUCCESS(rv, nullptr); + int32_t startOffset = 0, endOffset = 0; + nsCOMPtr attributes = + text->TextAttributes(false, aOffset, &startOffset, &endOffset); - *aStartOffset = startOffset; - *aEndOffset = endOffset; + *aStartOffset = startOffset; + *aEndOffset = endOffset; - return ConvertToAtkAttributeSet(attributes); + return ConvertToAtkAttributeSet(attributes); } static AtkAttributeSet* @@ -219,12 +202,8 @@ getDefaultAttributesCB(AtkText *aText) if (!text || !text->IsTextRole()) return nullptr; - nsCOMPtr attributes; - nsresult rv = text->GetDefaultTextAttributes(getter_AddRefs(attributes)); - if (NS_FAILED(rv)) - return nullptr; - - return ConvertToAtkAttributeSet(attributes); + nsCOMPtr attributes = text->DefaultTextAttributes(); + return ConvertToAtkAttributeSet(attributes); } static void @@ -241,27 +220,17 @@ getCharacterExtentsCB(AtkText *aText, gint aOffset, if (!text || !text->IsTextRole()) return; - int32_t extY = 0, extX = 0; - int32_t extWidth = 0, extHeight = 0; - uint32_t geckoCoordType; if (aCoords == ATK_XY_SCREEN) geckoCoordType = nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE; else geckoCoordType = nsIAccessibleCoordinateType::COORDTYPE_WINDOW_RELATIVE; -#ifdef DEBUG - nsresult rv = -#endif - text->GetCharacterExtents(aOffset, &extX, &extY, - &extWidth, &extHeight, - geckoCoordType); - *aX = extX; - *aY = extY; - *aWidth = extWidth; - *aHeight = extHeight; - NS_ASSERTION(NS_SUCCEEDED(rv), - "MaiInterfaceText::GetCharacterExtents, failed\n"); + nsIntRect rect = text->CharBounds(aOffset, geckoCoordType); + *aX = rect.x; + *aY = rect.y; + *aWidth = rect.width; + *aHeight = rect.height; } static void @@ -276,28 +245,17 @@ getRangeExtentsCB(AtkText *aText, gint aStartOffset, gint aEndOffset, if (!text || !text->IsTextRole()) return; - int32_t extY = 0, extX = 0; - int32_t extWidth = 0, extHeight = 0; - uint32_t geckoCoordType; if (aCoords == ATK_XY_SCREEN) geckoCoordType = nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE; else geckoCoordType = nsIAccessibleCoordinateType::COORDTYPE_WINDOW_RELATIVE; -#ifdef DEBUG - nsresult rv = -#endif - text->GetRangeExtents(aStartOffset, aEndOffset, - &extX, &extY, - &extWidth, &extHeight, - geckoCoordType); - aRect->x = extX; - aRect->y = extY; - aRect->width = extWidth; - aRect->height = extHeight; - NS_ASSERTION(NS_SUCCEEDED(rv), - "MaiInterfaceText::GetRangeExtents, failed\n"); + nsIntRect rect = text->TextBounds(aStartOffset, aEndOffset, geckoCoordType); + aRect->x = rect.x; + aRect->y = rect.y; + aRect->width = rect.width; + aRect->height = rect.height; } static gint @@ -325,15 +283,11 @@ getOffsetAtPointCB(AtkText *aText, if (!text || !text->IsTextRole()) return -1; - int32_t offset = 0; - uint32_t geckoCoordType; - if (aCoords == ATK_XY_SCREEN) - geckoCoordType = nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE; - else - geckoCoordType = nsIAccessibleCoordinateType::COORDTYPE_WINDOW_RELATIVE; - - text->GetOffsetAtPoint(aX, aY, geckoCoordType, &offset); - return static_cast(offset); + return static_cast( + text->OffsetAtPoint(aX, aY, + (aCoords == ATK_XY_SCREEN ? + nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE : + nsIAccessibleCoordinateType::COORDTYPE_WINDOW_RELATIVE))); } static gint @@ -347,10 +301,7 @@ getTextSelectionCountCB(AtkText *aText) if (!text || !text->IsTextRole()) return 0; - int32_t selectionCount; - nsresult rv = text->GetSelectionCount(&selectionCount); - - return NS_FAILED(rv) ? 0 : selectionCount; + return text->SelectionCount(); } static gchar* @@ -365,15 +316,12 @@ getTextSelectionCB(AtkText *aText, gint aSelectionNum, if (!text || !text->IsTextRole()) return nullptr; - int32_t startOffset = 0, endOffset = 0; - nsresult rv = text->GetSelectionBounds(aSelectionNum, - &startOffset, &endOffset); + int32_t startOffset = 0, endOffset = 0; + text->SelectionBoundsAt(aSelectionNum, &startOffset, &endOffset); *aStartOffset = startOffset; *aEndOffset = endOffset; - NS_ENSURE_SUCCESS(rv, nullptr); - return getTextCB(aText, *aStartOffset, *aEndOffset); } @@ -389,11 +337,9 @@ addTextSelectionCB(AtkText *aText, HyperTextAccessible* text = accWrap->AsHyperText(); if (!text || !text->IsTextRole()) - return false; + return FALSE; - nsresult rv = text->AddSelection(aStartOffset, aEndOffset); - - return NS_SUCCEEDED(rv) ? TRUE : FALSE; + return text->AddToSelection(aStartOffset, aEndOffset); } static gboolean @@ -406,11 +352,9 @@ removeTextSelectionCB(AtkText *aText, HyperTextAccessible* text = accWrap->AsHyperText(); if (!text || !text->IsTextRole()) - return false; + return FALSE; - nsresult rv = text->RemoveSelection(aSelectionNum); - - return NS_SUCCEEDED(rv) ? TRUE : FALSE; + return text->RemoveFromSelection(aSelectionNum); } static gboolean @@ -423,11 +367,9 @@ setTextSelectionCB(AtkText *aText, gint aSelectionNum, HyperTextAccessible* text = accWrap->AsHyperText(); if (!text || !text->IsTextRole()) - return false; + return FALSE; - nsresult rv = text->SetSelectionBounds(aSelectionNum, - aStartOffset, aEndOffset); - return NS_SUCCEEDED(rv) ? TRUE : FALSE; + return text->SetSelectionBoundsAt(aSelectionNum, aStartOffset, aEndOffset); } static gboolean @@ -438,11 +380,11 @@ setCaretOffsetCB(AtkText *aText, gint aOffset) return FALSE; HyperTextAccessible* text = accWrap->AsHyperText(); - if (!text || !text->IsTextRole()) - return false; + if (!text || !text->IsTextRole() || !text->IsValidOffset(aOffset)) + return FALSE; - nsresult rv = text->SetCaretOffset(aOffset); - return NS_SUCCEEDED(rv) ? TRUE : FALSE; + text->SetCaretOffset(aOffset); + return TRUE; } } diff --git a/accessible/src/atk/nsMaiInterfaceValue.cpp b/accessible/src/atk/nsMaiInterfaceValue.cpp index 2810f482af45..e7b2279cc03b 100644 --- a/accessible/src/atk/nsMaiInterfaceValue.cpp +++ b/accessible/src/atk/nsMaiInterfaceValue.cpp @@ -5,11 +5,14 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "InterfaceInitFuncs.h" -#include "mozilla/Likely.h" #include "AccessibleWrap.h" #include "nsMai.h" +#include "mozilla/FloatingPoint.h" +#include "mozilla/Likely.h" + +using namespace mozilla; using namespace mozilla::a11y; extern "C" { @@ -21,18 +24,13 @@ getCurrentValueCB(AtkValue *obj, GValue *value) if (!accWrap) return; - nsCOMPtr accValue; - accWrap->QueryInterface(NS_GET_IID(nsIAccessibleValue), - getter_AddRefs(accValue)); - if (!accValue) - return; + memset (value, 0, sizeof (GValue)); + double accValue = accWrap->CurValue(); + if (IsNaN(accValue)) + return; - memset (value, 0, sizeof (GValue)); - double accDouble; - if (NS_FAILED(accValue->GetCurrentValue(&accDouble))) - return; - g_value_init (value, G_TYPE_DOUBLE); - g_value_set_double (value, accDouble); + g_value_init (value, G_TYPE_DOUBLE); + g_value_set_double (value, accValue); } static void @@ -42,18 +40,13 @@ getMaximumValueCB(AtkValue *obj, GValue *value) if (!accWrap) return; - nsCOMPtr accValue; - accWrap->QueryInterface(NS_GET_IID(nsIAccessibleValue), - getter_AddRefs(accValue)); - if (!accValue) - return; + memset(value, 0, sizeof (GValue)); + double accValue = accWrap->MaxValue(); + if (IsNaN(accValue)) + return; - memset (value, 0, sizeof (GValue)); - double accDouble; - if (NS_FAILED(accValue->GetMaximumValue(&accDouble))) - return; - g_value_init (value, G_TYPE_DOUBLE); - g_value_set_double (value, accDouble); + g_value_init(value, G_TYPE_DOUBLE); + g_value_set_double(value, accValue); } static void @@ -63,18 +56,13 @@ getMinimumValueCB(AtkValue *obj, GValue *value) if (!accWrap) return; - nsCOMPtr accValue; - accWrap->QueryInterface(NS_GET_IID(nsIAccessibleValue), - getter_AddRefs(accValue)); - if (!accValue) - return; + memset(value, 0, sizeof (GValue)); + double accValue = accWrap->MinValue(); + if (IsNaN(accValue)) + return; - memset (value, 0, sizeof (GValue)); - double accDouble; - if (NS_FAILED(accValue->GetMinimumValue(&accDouble))) - return; - g_value_init (value, G_TYPE_DOUBLE); - g_value_set_double (value, accDouble); + g_value_init(value, G_TYPE_DOUBLE); + g_value_set_double(value, accValue); } static void @@ -84,18 +72,13 @@ getMinimumIncrementCB(AtkValue *obj, GValue *minimumIncrement) if (!accWrap) return; - nsCOMPtr accValue; - accWrap->QueryInterface(NS_GET_IID(nsIAccessibleValue), - getter_AddRefs(accValue)); - if (!accValue) - return; + memset(minimumIncrement, 0, sizeof (GValue)); + double accValue = accWrap->Step(); + if (IsNaN(accValue)) + accValue = 0; // zero if the minimum increment is undefined - memset (minimumIncrement, 0, sizeof (GValue)); - double accDouble; - if (NS_FAILED(accValue->GetMinimumIncrement(&accDouble))) - return; - g_value_init (minimumIncrement, G_TYPE_DOUBLE); - g_value_set_double (minimumIncrement, accDouble); + g_value_init(minimumIncrement, G_TYPE_DOUBLE); + g_value_set_double(minimumIncrement, accValue); } static gboolean @@ -105,13 +88,8 @@ setCurrentValueCB(AtkValue *obj, const GValue *value) if (!accWrap) return FALSE; - nsCOMPtr accValue; - accWrap->QueryInterface(NS_GET_IID(nsIAccessibleValue), - getter_AddRefs(accValue)); - NS_ENSURE_TRUE(accValue, FALSE); - - double accDouble =g_value_get_double (value); - return !NS_FAILED(accValue->SetCurrentValue(accDouble)); + double accValue =g_value_get_double(value); + return accWrap->SetCurValue(accValue); } } diff --git a/accessible/src/base/Logging.cpp b/accessible/src/base/Logging.cpp index 0e5b79629abc..435b79f358b1 100644 --- a/accessible/src/base/Logging.cpp +++ b/accessible/src/base/Logging.cpp @@ -99,22 +99,19 @@ LogDocShellState(nsIDocument* aDocumentNode) printf("docshell busy: "); nsAutoCString docShellBusy; - nsCOMPtr container = aDocumentNode->GetContainer(); - if (container) { - nsCOMPtr docShell = do_QueryInterface(container); - uint32_t busyFlags = nsIDocShell::BUSY_FLAGS_NONE; - docShell->GetBusyFlags(&busyFlags); - if (busyFlags == nsIDocShell::BUSY_FLAGS_NONE) - printf("'none'"); - if (busyFlags & nsIDocShell::BUSY_FLAGS_BUSY) - printf("'busy'"); - if (busyFlags & nsIDocShell::BUSY_FLAGS_BEFORE_PAGE_LOAD) - printf(", 'before page load'"); - if (busyFlags & nsIDocShell::BUSY_FLAGS_PAGE_LOADING) - printf(", 'page loading'"); - } else { + nsCOMPtr docShell = aDocumentNode->GetDocShell(); + uint32_t busyFlags = nsIDocShell::BUSY_FLAGS_NONE; + docShell->GetBusyFlags(&busyFlags); + if (busyFlags == nsIDocShell::BUSY_FLAGS_NONE) + printf("'none'"); + if (busyFlags & nsIDocShell::BUSY_FLAGS_BUSY) + printf("'busy'"); + if (busyFlags & nsIDocShell::BUSY_FLAGS_BEFORE_PAGE_LOAD) + printf(", 'before page load'"); + if (busyFlags & nsIDocShell::BUSY_FLAGS_PAGE_LOADING) + printf(", 'page loading'"); + printf("[failed]"); - } } static void @@ -132,8 +129,7 @@ static void LogDocShellTree(nsIDocument* aDocumentNode) { if (aDocumentNode->IsActive()) { - nsCOMPtr container = aDocumentNode->GetContainer(); - nsCOMPtr treeItem(do_QueryInterface(container)); + nsCOMPtr treeItem(aDocumentNode->GetDocShell()); nsCOMPtr parentTreeItem; treeItem->GetParent(getter_AddRefs(parentTreeItem)); nsCOMPtr rootTreeItem; diff --git a/accessible/src/base/NotificationController.cpp b/accessible/src/base/NotificationController.cpp index 8c9f8e7fa1a9..fc34c5b5423e 100644 --- a/accessible/src/base/NotificationController.cpp +++ b/accessible/src/base/NotificationController.cpp @@ -15,10 +15,6 @@ using namespace mozilla; using namespace mozilla::a11y; -// Defines the number of selection add/remove events in the queue when they -// aren't packed into single selection within event. -const unsigned int kSelChangeCountToPack = 5; - //////////////////////////////////////////////////////////////////////////////// // NotificationCollector //////////////////////////////////////////////////////////////////////////////// diff --git a/accessible/src/base/SelectionManager.cpp b/accessible/src/base/SelectionManager.cpp index 744fb30e2337..b9d1b6cd3fa2 100644 --- a/accessible/src/base/SelectionManager.cpp +++ b/accessible/src/base/SelectionManager.cpp @@ -130,8 +130,8 @@ SelectionManager::ProcessTextSelChangeEvent(AccEvent* aEvent) if (!caretCntr) return; - int32_t caretOffset = -1; - if (NS_SUCCEEDED(caretCntr->GetCaretOffset(&caretOffset)) && caretOffset != -1) { + int32_t caretOffset = caretCntr->CaretOffset(); + if (caretOffset != -1) { nsRefPtr caretMoveEvent = new AccCaretMoveEvent(caretCntr, caretOffset, aEvent->FromUserInput()); nsEventShell::FireEvent(caretMoveEvent); diff --git a/accessible/src/base/moz.build b/accessible/src/base/moz.build index b9089a4db1aa..224d84492a66 100644 --- a/accessible/src/base/moz.build +++ b/accessible/src/base/moz.build @@ -6,8 +6,6 @@ include('../shared.mozbuild') -MODULE = 'accessibility' - EXPORTS += [ 'AccEvent.h', 'nsAccessibilityService.h' @@ -29,7 +27,7 @@ if CONFIG['MOZ_DEBUG']: 'Logging.h', ] -SOURCES += [ +UNIFIED_SOURCES += [ 'AccCollector.cpp', 'AccEvent.cpp', 'AccGroupInfo.cpp', @@ -56,14 +54,10 @@ SOURCES += [ ] if a11y_log: - SOURCES += [ + UNIFIED_SOURCES += [ 'Logging.cpp', ] -LIBRARY_NAME = 'accessibility_base_s' - -LIBXUL_LIBRARY = True - LOCAL_INCLUDES += [ '../../../content/xbl/src', '../../../ipc/chromium/src', @@ -95,3 +89,5 @@ else: LOCAL_INCLUDES += [ '../other', ] + +FINAL_LIBRARY = 'xul' diff --git a/accessible/src/base/nsAccessibilityService.cpp b/accessible/src/base/nsAccessibilityService.cpp index 5804fb435284..0ea3d82ef5f6 100644 --- a/accessible/src/base/nsAccessibilityService.cpp +++ b/accessible/src/base/nsAccessibilityService.cpp @@ -200,8 +200,7 @@ nsAccessibilityService::GetRootDocumentAccessible(nsIPresShell* aPresShell, nsIPresShell* ps = aPresShell; nsIDocument* documentNode = aPresShell->GetDocument(); if (documentNode) { - nsCOMPtr container = documentNode->GetContainer(); - nsCOMPtr treeItem(do_QueryInterface(container)); + nsCOMPtr treeItem(documentNode->GetDocShell()); if (treeItem) { nsCOMPtr rootTreeItem; treeItem->GetRootTreeItem(getter_AddRefs(rootTreeItem)); diff --git a/accessible/src/base/nsAccessiblePivot.cpp b/accessible/src/base/nsAccessiblePivot.cpp index 48052ac29288..c4094147fa1a 100644 --- a/accessible/src/base/nsAccessiblePivot.cpp +++ b/accessible/src/base/nsAccessiblePivot.cpp @@ -305,7 +305,7 @@ nsAccessiblePivot::MoveNextByText(TextBoundaryType aBoundary, bool* aResult) Accessible* root = GetActiveRoot(); while (true) { Accessible* curPosition = tempPosition; - HyperTextAccessible* text; + HyperTextAccessible* text = nullptr; // Find the nearest text node using a preorder traversal starting from // the current node. if (!(text = tempPosition->AsHyperText())) { @@ -370,9 +370,8 @@ nsAccessiblePivot::MoveNextByText(TextBoundaryType aBoundary, bool* aResult) nsAutoString unusedText; int32_t newStart = 0, newEnd = 0, currentEnd = tempEnd; - text->GetTextAtOffset(tempEnd, endBoundary, &newStart, &tempEnd, unusedText); - text->GetTextBeforeOffset(tempEnd, startBoundary, &newStart, &newEnd, - unusedText); + text->TextAtOffset(tempEnd, endBoundary, &newStart, &tempEnd, unusedText); + text->TextBeforeOffset(tempEnd, startBoundary, &newStart, &newEnd, unusedText); int32_t potentialStart = newEnd == tempEnd ? newStart : newEnd; tempStart = potentialStart > tempStart ? potentialStart : currentEnd; @@ -494,15 +493,14 @@ nsAccessiblePivot::MovePreviousByText(TextBoundaryType aBoundary, bool* aResult) nsAutoString unusedText; int32_t newStart = 0, newEnd = 0, currentStart = tempStart, potentialEnd = 0; - text->GetTextBeforeOffset(tempStart, startBoundary, &newStart, &newEnd, - unusedText); + text->TextBeforeOffset(tempStart, startBoundary, &newStart, &newEnd, unusedText); if (newStart < tempStart) tempStart = newEnd >= currentStart ? newStart : newEnd; else // XXX: In certain odd cases newStart is equal to tempStart - text->GetTextBeforeOffset(tempStart - 1, startBoundary, &newStart, - &tempStart, unusedText); - text->GetTextAtOffset(tempStart, endBoundary, &newStart, &potentialEnd, - unusedText); + text->TextBeforeOffset(tempStart - 1, startBoundary, &newStart, + &tempStart, unusedText); + text->TextAtOffset(tempStart, endBoundary, &newStart, &potentialEnd, + unusedText); tempEnd = potentialEnd < tempEnd ? potentialEnd : currentStart; // The offset range we've obtained might have embedded characters in it, diff --git a/accessible/src/base/nsCoreUtils.cpp b/accessible/src/base/nsCoreUtils.cpp index 00ccb9a702aa..13aee385f1ff 100644 --- a/accessible/src/base/nsCoreUtils.cpp +++ b/accessible/src/base/nsCoreUtils.cpp @@ -394,17 +394,14 @@ nsCoreUtils::GetDocShellFor(nsINode *aNode) if (!aNode) return nullptr; - nsCOMPtr container = aNode->OwnerDoc()->GetContainer(); - nsCOMPtr docShell = do_QueryInterface(container); + nsCOMPtr docShell = aNode->OwnerDoc()->GetDocShell(); return docShell.forget(); } bool nsCoreUtils::IsRootDocument(nsIDocument *aDocument) { - nsCOMPtr container = aDocument->GetContainer(); - nsCOMPtr docShellTreeItem = - do_QueryInterface(container); + nsCOMPtr docShellTreeItem = aDocument->GetDocShell(); NS_ASSERTION(docShellTreeItem, "No document shell for document!"); nsCOMPtr parentTreeItem; @@ -416,9 +413,7 @@ nsCoreUtils::IsRootDocument(nsIDocument *aDocument) bool nsCoreUtils::IsContentDocument(nsIDocument *aDocument) { - nsCOMPtr container = aDocument->GetContainer(); - nsCOMPtr docShellTreeItem = - do_QueryInterface(container); + nsCOMPtr docShellTreeItem = aDocument->GetDocShell(); NS_ASSERTION(docShellTreeItem, "No document shell tree item for document!"); int32_t contentType; @@ -429,8 +424,7 @@ nsCoreUtils::IsContentDocument(nsIDocument *aDocument) bool nsCoreUtils::IsTabDocument(nsIDocument* aDocumentNode) { - nsCOMPtr container = aDocumentNode->GetContainer(); - nsCOMPtr treeItem(do_QueryInterface(container)); + nsCOMPtr treeItem(aDocumentNode->GetDocShell()); nsCOMPtr parentTreeItem; treeItem->GetParent(getter_AddRefs(parentTreeItem)); diff --git a/accessible/src/generic/Accessible.cpp b/accessible/src/generic/Accessible.cpp index 8f2ce0bdaff3..b4b6a103b679 100644 --- a/accessible/src/generic/Accessible.cpp +++ b/accessible/src/generic/Accessible.cpp @@ -78,6 +78,7 @@ #endif #include "mozilla/Assertions.h" +#include "mozilla/FloatingPoint.h" #include "mozilla/MouseEvents.h" #include "mozilla/unused.h" #include "mozilla/Preferences.h" @@ -376,10 +377,8 @@ Accessible::AccessKey() const nsIDocument* document = mContent->GetCurrentDoc(); if (!document) return KeyBinding(); - nsCOMPtr container = document->GetContainer(); - if (!container) - return KeyBinding(); - nsCOMPtr treeItem(do_QueryInterface(container)); + + nsCOMPtr treeItem(document->GetDocShell()); if (!treeItem) return KeyBinding(); @@ -1293,9 +1292,7 @@ Accessible::NativeAttributes() nsCoreUtils::GetRoleContent(doc)); // Allow ARIA live region markup from outer documents to override - nsCOMPtr container = doc->GetContainer(); - nsCOMPtr docShellTreeItem = - do_QueryInterface(container); + nsCOMPtr docShellTreeItem = doc->GetDocShell(); if (!docShellTreeItem) break; @@ -1672,61 +1669,53 @@ Accessible::Value(nsString& aValue) } } -// nsIAccessibleValue -NS_IMETHODIMP -Accessible::GetMaximumValue(double *aMaximumValue) +double +Accessible::MaxValue() const { - return GetAttrValue(nsGkAtoms::aria_valuemax, aMaximumValue); + return AttrNumericValue(nsGkAtoms::aria_valuemax); } -NS_IMETHODIMP -Accessible::GetMinimumValue(double *aMinimumValue) +double +Accessible::MinValue() const { - return GetAttrValue(nsGkAtoms::aria_valuemin, aMinimumValue); + return AttrNumericValue(nsGkAtoms::aria_valuemin); } -NS_IMETHODIMP -Accessible::GetMinimumIncrement(double *aMinIncrement) +double +Accessible::Step() const { - NS_ENSURE_ARG_POINTER(aMinIncrement); - *aMinIncrement = 0; - - // No mimimum increment in dynamic content spec right now - return NS_OK_NO_ARIA_VALUE; + return UnspecifiedNaN(); // no mimimum increment (step) in ARIA. } -NS_IMETHODIMP -Accessible::GetCurrentValue(double *aValue) +double +Accessible::CurValue() const { - return GetAttrValue(nsGkAtoms::aria_valuenow, aValue); + return AttrNumericValue(nsGkAtoms::aria_valuenow); } -NS_IMETHODIMP -Accessible::SetCurrentValue(double aValue) +bool +Accessible::SetCurValue(double aValue) { - if (IsDefunct()) - return NS_ERROR_FAILURE; - if (!mRoleMapEntry || mRoleMapEntry->valueRule == eNoValue) - return NS_OK_NO_ARIA_VALUE; + return false; const uint32_t kValueCannotChange = states::READONLY | states::UNAVAILABLE; - if (State() & kValueCannotChange) - return NS_ERROR_FAILURE; + return false; - double minValue = 0; - if (NS_SUCCEEDED(GetMinimumValue(&minValue)) && aValue < minValue) - return NS_ERROR_INVALID_ARG; + double checkValue = MinValue(); + if (!IsNaN(checkValue) && aValue < checkValue) + return false; - double maxValue = 0; - if (NS_SUCCEEDED(GetMaximumValue(&maxValue)) && aValue > maxValue) - return NS_ERROR_INVALID_ARG; + checkValue = MaxValue(); + if (!IsNaN(checkValue) && aValue > checkValue) + return false; - nsAutoString newValue; - newValue.AppendFloat(aValue); - return mContent->SetAttr(kNameSpaceID_None, - nsGkAtoms::aria_valuenow, newValue, true); + nsAutoString strValue; + strValue.AppendFloat(aValue); + + return NS_SUCCEEDED( + mContent->SetAttr(kNameSpaceID_None, nsGkAtoms::aria_valuenow, strValue, true)); } /* void setName (in DOMString name); */ @@ -3116,31 +3105,19 @@ Accessible::GetFirstAvailableAccessible(nsINode *aStartNode) const return nullptr; } -nsresult -Accessible::GetAttrValue(nsIAtom *aProperty, double *aValue) +double +Accessible::AttrNumericValue(nsIAtom* aAttr) const { - NS_ENSURE_ARG_POINTER(aValue); - *aValue = 0; - - if (IsDefunct()) - return NS_ERROR_FAILURE; // Node already shut down - - if (!mRoleMapEntry || mRoleMapEntry->valueRule == eNoValue) - return NS_OK_NO_ARIA_VALUE; + if (!mRoleMapEntry || mRoleMapEntry->valueRule == eNoValue) + return UnspecifiedNaN(); nsAutoString attrValue; - mContent->GetAttr(kNameSpaceID_None, aProperty, attrValue); - - // Return zero value if there is no attribute or its value is empty. - if (attrValue.IsEmpty()) - return NS_OK; + if (!mContent->GetAttr(kNameSpaceID_None, aAttr, attrValue)) + return UnspecifiedNaN(); nsresult error = NS_OK; double value = attrValue.ToDouble(&error); - if (NS_SUCCEEDED(error)) - *aValue = value; - - return NS_OK; + return NS_FAILED(error) ? UnspecifiedNaN() : value; } uint32_t diff --git a/accessible/src/generic/Accessible.h b/accessible/src/generic/Accessible.h index 9af7eee2eb4b..279745603305 100644 --- a/accessible/src/generic/Accessible.h +++ b/accessible/src/generic/Accessible.h @@ -13,9 +13,9 @@ #include "nsIAccessible.h" #include "nsIAccessibleHyperLink.h" -#include "nsIAccessibleValue.h" #include "nsIAccessibleStates.h" #include "xpcAccessibleSelectable.h" +#include "xpcAccessibleValue.h" #include "nsIContent.h" #include "nsString.h" @@ -105,7 +105,7 @@ typedef nsRefPtrHashtable, Accessible> class Accessible : public nsIAccessible, public nsIAccessibleHyperLink, public xpcAccessibleSelectable, - public nsIAccessibleValue + public xpcAccessibleValue { public: Accessible(nsIContent* aContent, DocAccessible* aDoc); @@ -116,7 +116,6 @@ public: NS_DECL_NSIACCESSIBLE NS_DECL_NSIACCESSIBLEHYPERLINK - NS_DECL_NSIACCESSIBLEVALUE NS_DECLARE_STATIC_IID_ACCESSOR(NS_ACCESSIBLE_IMPL_IID) ////////////////////////////////////////////////////////////////////////////// @@ -245,6 +244,16 @@ public: return state; } + /** + * Return if accessible is unavailable. + */ + bool Unavailable() const + { + uint64_t state = NativelyUnavailable() ? states::UNAVAILABLE : 0; + ApplyARIAState(&state); + return state & states::UNAVAILABLE; + } + /** * Return the states of accessible, not taking into account ARIA states. * Use State() to get complete set of states. @@ -688,6 +697,15 @@ public: */ virtual bool UnselectAll(); + ////////////////////////////////////////////////////////////////////////////// + // Value (numeric value interface) + + virtual double MaxValue() const; + virtual double MinValue() const; + virtual double CurValue() const; + virtual double Step() const; + virtual bool SetCurValue(double aValue); + ////////////////////////////////////////////////////////////////////////////// // Widgets @@ -911,14 +929,12 @@ protected: nsIContent* GetAtomicRegion() const; /** - * Get numeric value of the given ARIA attribute. + * Return numeric value of the given ARIA attribute, NaN if not applicable. * - * @param aAriaProperty - the ARIA property we're using - * @param aValue - value of the attribute - * - * @return - NS_OK_NO_ARIA_VALUE if there is no setted ARIA attribute + * @param aARIAProperty [in] the ARIA property we're using + * @return a numeric value */ - nsresult GetAttrValue(nsIAtom *aAriaProperty, double *aValue); + double AttrNumericValue(nsIAtom* aARIAAttr) const; /** * Return the action rule based on ARIA enum constants EActionRule diff --git a/accessible/src/generic/DocAccessible.cpp b/accessible/src/generic/DocAccessible.cpp index 909c41ab1ba7..5963ce45c03d 100644 --- a/accessible/src/generic/DocAccessible.cpp +++ b/accessible/src/generic/DocAccessible.cpp @@ -688,8 +688,7 @@ DocAccessible::GetBoundsRect(nsRect& aBounds, nsIFrame** aRelativeFrame) nsresult DocAccessible::AddEventListeners() { - nsCOMPtr container = mDocumentNode->GetContainer(); - nsCOMPtr docShellTreeItem(do_QueryInterface(container)); + nsCOMPtr docShellTreeItem(mDocumentNode->GetDocShell()); // We want to add a command observer only if the document is content and has // an editor. @@ -721,8 +720,7 @@ DocAccessible::RemoveEventListeners() if (mDocumentNode) { mDocumentNode->RemoveObserver(this); - nsCOMPtr container = mDocumentNode->GetContainer(); - nsCOMPtr docShellTreeItem(do_QueryInterface(container)); + nsCOMPtr docShellTreeItem(mDocumentNode->GetDocShell()); NS_ASSERTION(docShellTreeItem, "doc should support nsIDocShellTreeItem."); if (docShellTreeItem) { @@ -870,7 +868,12 @@ DocAccessible::AttributeWillChange(nsIDocument* aDocument, aAttribute == nsGkAtoms::aria_pressed) { mARIAAttrOldValue = (aModType != nsIDOMMutationEvent::ADDITION) ? nsAccUtils::GetARIAToken(aElement, aAttribute) : nullptr; + return; } + + if (aAttribute == nsGkAtoms::aria_disabled || + aAttribute == nsGkAtoms::disabled) + mStateBitWasOn = accessible->Unavailable(); } void @@ -938,22 +941,24 @@ DocAccessible::AttributeChangedImpl(Accessible* aAccessible, // Universal boolean properties that don't require a role. Fire the state // change when disabled or aria-disabled attribute is set. + // Note. Checking the XUL or HTML namespace would not seem to gain us + // anything, because disabled attribute really is going to mean the same + // thing in any namespace. + // Note. We use the attribute instead of the disabled state bit because + // ARIA's aria-disabled does not affect the disabled state bit. if (aAttribute == nsGkAtoms::disabled || aAttribute == nsGkAtoms::aria_disabled) { - - // Note. Checking the XUL or HTML namespace would not seem to gain us - // anything, because disabled attribute really is going to mean the same - // thing in any namespace. - - // Note. We use the attribute instead of the disabled state bit because - // ARIA's aria-disabled does not affect the disabled state bit. + // Do nothing if state wasn't changed (like @aria-disabled was removed but + // @disabled is still presented). + if (aAccessible->Unavailable() == mStateBitWasOn) + return; nsRefPtr enabledChangeEvent = - new AccStateChangeEvent(aAccessible, states::ENABLED); + new AccStateChangeEvent(aAccessible, states::ENABLED, mStateBitWasOn); FireDelayedEvent(enabledChangeEvent); nsRefPtr sensitiveChangeEvent = - new AccStateChangeEvent(aAccessible, states::SENSITIVE); + new AccStateChangeEvent(aAccessible, states::SENSITIVE, mStateBitWasOn); FireDelayedEvent(sensitiveChangeEvent); return; } @@ -1987,8 +1992,7 @@ DocAccessible::ShutdownChildrenInSubtree(Accessible* aAccessible) bool DocAccessible::IsLoadEventTarget() const { - nsCOMPtr container = mDocumentNode->GetContainer(); - nsCOMPtr treeItem = do_QueryInterface(container); + nsCOMPtr treeItem = mDocumentNode->GetDocShell(); NS_ASSERTION(treeItem, "No document shell for document!"); nsCOMPtr parentTreeItem; diff --git a/accessible/src/generic/DocAccessible.h b/accessible/src/generic/DocAccessible.h index 6de2c3d7cc2e..b17737d43077 100644 --- a/accessible/src/generic/DocAccessible.h +++ b/accessible/src/generic/DocAccessible.h @@ -533,10 +533,16 @@ protected: nsCOMPtr mAnchorJumpElm; /** - * Keep the ARIA attribute old value that is initialized by - * AttributeWillChange and used by AttributeChanged notifications. + * A generic state (see items below) before the attribute value was changed. + * @see AttributeWillChange and AttributeChanged notifications. */ - nsIAtom* mARIAAttrOldValue; + union { + // ARIA attribute value + nsIAtom* mARIAAttrOldValue; + + // True if the accessible state bit was on + bool mStateBitWasOn; + }; nsTArray > mChildDocuments; diff --git a/accessible/src/generic/FormControlAccessible.cpp b/accessible/src/generic/FormControlAccessible.cpp index 02323a5554eb..435d898391bf 100644 --- a/accessible/src/generic/FormControlAccessible.cpp +++ b/accessible/src/generic/FormControlAccessible.cpp @@ -8,6 +8,7 @@ #include "FormControlAccessible.h" #include "Role.h" +#include "mozilla/FloatingPoint.h" #include "nsIDOMHTMLFormElement.h" #include "nsIDOMXULElement.h" #include "nsIDOMXULControlElement.h" @@ -82,14 +83,12 @@ ProgressMeterAccessible::Value(nsString& aValue) if (!aValue.IsEmpty()) return; - double maxValue = 0; - nsresult rv = GetMaximumValue(&maxValue); - if (NS_FAILED(rv) || maxValue == 0) + double maxValue = MaxValue(); + if (IsNaN(maxValue) || maxValue == 0) return; - double curValue = 0; - GetCurrentValue(&curValue); - if (NS_FAILED(rv)) + double curValue = CurValue(); + if (IsNaN(curValue)) return; // Treat the current value bigger than maximum as 100%. @@ -101,77 +100,62 @@ ProgressMeterAccessible::Value(nsString& aValue) } template -NS_IMETHODIMP -ProgressMeterAccessible::GetMaximumValue(double* aMaximumValue) +double +ProgressMeterAccessible::MaxValue() const { - nsresult rv = LeafAccessible::GetMaximumValue(aMaximumValue); - if (rv != NS_OK_NO_ARIA_VALUE) - return rv; + double value = LeafAccessible::MaxValue(); + if (!IsNaN(value)) + return value; - nsAutoString value; - if (mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::max, value)) { + nsAutoString strValue; + if (mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::max, strValue)) { nsresult result = NS_OK; - *aMaximumValue = value.ToDouble(&result); - return result; + value = strValue.ToDouble(&result); + if (NS_SUCCEEDED(result)) + return value; } - *aMaximumValue = Max; - return NS_OK; + return Max; } template -NS_IMETHODIMP -ProgressMeterAccessible::GetMinimumValue(double* aMinimumValue) +double +ProgressMeterAccessible::MinValue() const { - nsresult rv = LeafAccessible::GetMinimumValue(aMinimumValue); - if (rv != NS_OK_NO_ARIA_VALUE) - return rv; - - *aMinimumValue = 0; - return NS_OK; + double value = LeafAccessible::MinValue(); + return IsNaN(value) ? 0 : value; } template -NS_IMETHODIMP -ProgressMeterAccessible::GetMinimumIncrement(double* aMinimumIncrement) +double +ProgressMeterAccessible::Step() const { - nsresult rv = LeafAccessible::GetMinimumIncrement(aMinimumIncrement); - if (rv != NS_OK_NO_ARIA_VALUE) - return rv; - - *aMinimumIncrement = 0; - return NS_OK; + double value = LeafAccessible::Step(); + return IsNaN(value) ? 0 : value; } template -NS_IMETHODIMP -ProgressMeterAccessible::GetCurrentValue(double* aCurrentValue) +double +ProgressMeterAccessible::CurValue() const { - nsresult rv = LeafAccessible::GetCurrentValue(aCurrentValue); - if (rv != NS_OK_NO_ARIA_VALUE) - return rv; + double value = LeafAccessible::CurValue(); + if (!IsNaN(value)) + return value; nsAutoString attrValue; - mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::value, attrValue); - - // Return zero value if there is no attribute or its value is empty. - if (attrValue.IsEmpty()) - return NS_OK; + if (!mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::value, attrValue)) + return UnspecifiedNaN(); nsresult error = NS_OK; - double value = attrValue.ToDouble(&error); - if (NS_FAILED(error)) - return NS_OK; // Zero value because of wrong markup. - - *aCurrentValue = value; - return NS_OK; + value = attrValue.ToDouble(&error); + return NS_FAILED(error) ? UnspecifiedNaN() : value; } template -NS_IMETHODIMP -ProgressMeterAccessible::SetCurrentValue(double aValue) +bool +ProgressMeterAccessible::SetCurValue(double aValue) { - return NS_ERROR_FAILURE; // Progress meters are readonly. + return false; // progress meters are readonly. } //////////////////////////////////////////////////////////////////////////////// diff --git a/accessible/src/generic/FormControlAccessible.h b/accessible/src/generic/FormControlAccessible.h index cbd129c1bf7a..88521a3e1d67 100644 --- a/accessible/src/generic/FormControlAccessible.h +++ b/accessible/src/generic/FormControlAccessible.h @@ -28,13 +28,19 @@ public: } NS_DECL_ISUPPORTS_INHERITED - NS_DECL_NSIACCESSIBLEVALUE // Accessible virtual void Value(nsString& aValue); virtual mozilla::a11y::role NativeRole(); virtual uint64_t NativeState(); + // Value + virtual double MaxValue() const MOZ_OVERRIDE; + virtual double MinValue() const MOZ_OVERRIDE; + virtual double CurValue() const MOZ_OVERRIDE; + virtual double Step() const MOZ_OVERRIDE; + virtual bool SetCurValue(double aValue) MOZ_OVERRIDE; + // Widgets virtual bool IsWidget() const; }; diff --git a/accessible/src/generic/HyperTextAccessible-inl.h b/accessible/src/generic/HyperTextAccessible-inl.h new file mode 100644 index 000000000000..680ba0620786 --- /dev/null +++ b/accessible/src/generic/HyperTextAccessible-inl.h @@ -0,0 +1,164 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef mozilla_a11y_HyperTextAccessible_inl_h__ +#define mozilla_a11y_HyperTextAccessible_inl_h__ + +#include "HyperTextAccessible.h" + +#include "nsAccUtils.h" + +#include "nsIClipboard.h" +#include "nsIEditor.h" +#include "nsIPersistentProperties2.h" +#include "nsIPlaintextEditor.h" + +namespace mozilla { +namespace a11y { + +inline bool +HyperTextAccessible::IsValidOffset(int32_t aOffset) +{ + int32_t offset = ConvertMagicOffset(aOffset); + return offset >= 0 && offset <= static_cast(CharacterCount()); +} + +inline bool +HyperTextAccessible::IsValidRange(int32_t aStartOffset, int32_t aEndOffset) +{ + int32_t startOffset = ConvertMagicOffset(aStartOffset); + if (startOffset < 0) + return false; + + int32_t endOffset = ConvertMagicOffset(aEndOffset); + if (endOffset < 0 || startOffset > endOffset) + return false; + + return endOffset <= static_cast(CharacterCount()); +} + +inline nsIntRect +HyperTextAccessible::TextBounds(int32_t aStartOffset, int32_t aEndOffset, + uint32_t aCoordType) +{ + nsIntRect bounds; + GetPosAndText(aStartOffset, aEndOffset, nullptr, nullptr, &bounds); + nsAccUtils::ConvertScreenCoordsTo(&bounds.x, &bounds.y, aCoordType, this); + return bounds; +} + +inline bool +HyperTextAccessible::AddToSelection(int32_t aStartOffset, int32_t aEndOffset) +{ + Selection* domSel = DOMSelection(); + return domSel && + SetSelectionBoundsAt(domSel->GetRangeCount(), aStartOffset, aEndOffset); +} + +inline void +HyperTextAccessible::ReplaceText(const nsAString& aText) +{ + int32_t numChars = CharacterCount(); + if (numChars != 0) + DeleteText(0, numChars); + + InsertText(aText, 0); +} + +inline void +HyperTextAccessible::InsertText(const nsAString& aText, int32_t aPosition) +{ + nsCOMPtr editor = GetEditor(); + nsCOMPtr peditor(do_QueryInterface(editor)); + if (peditor) { + SetSelectionRange(aPosition, aPosition); + peditor->InsertText(aText); + } +} + +inline void +HyperTextAccessible::CopyText(int32_t aStartPos, int32_t aEndPos) + { + nsCOMPtr editor = GetEditor(); + if (editor) { + SetSelectionRange(aStartPos, aEndPos); + editor->Copy(); + } + } + +inline void +HyperTextAccessible::CutText(int32_t aStartPos, int32_t aEndPos) + { + nsCOMPtr editor = GetEditor(); + if (editor) { + SetSelectionRange(aStartPos, aEndPos); + editor->Cut(); + } + } + +inline void +HyperTextAccessible::DeleteText(int32_t aStartPos, int32_t aEndPos) +{ + nsCOMPtr editor = GetEditor(); + if (editor) { + SetSelectionRange(aStartPos, aEndPos); + editor->DeleteSelection(nsIEditor::eNone, nsIEditor::eStrip); + } +} + +inline void +HyperTextAccessible::PasteText(int32_t aPosition) +{ + nsCOMPtr editor = GetEditor(); + if (editor) { + SetSelectionRange(aPosition, aPosition); + editor->Paste(nsIClipboard::kGlobalClipboard); + } +} + +inline int32_t +HyperTextAccessible::ConvertMagicOffset(int32_t aOffset) +{ + if (aOffset == nsIAccessibleText::TEXT_OFFSET_END_OF_TEXT) + return CharacterCount(); + + if (aOffset == nsIAccessibleText::TEXT_OFFSET_CARET) + return CaretOffset(); + + return aOffset; +} + +inline int32_t +HyperTextAccessible::AdjustCaretOffset(int32_t aOffset) const +{ + // It is the same character offset when the caret is visually at the very + // end of a line or the start of a new line (soft line break). Getting text + // at the line should provide the line with the visual caret, otherwise + // screen readers will announce the wrong line as the user presses up or + // down arrow and land at the end of a line. + if (aOffset > 0) { + nsRefPtr frameSelection = FrameSelection(); + if (frameSelection && + frameSelection->GetHint() == nsFrameSelection::HINTLEFT) { + return aOffset - 1; + } + } + return aOffset; +} + +inline Selection* +HyperTextAccessible::DOMSelection() const +{ + nsRefPtr frameSelection = FrameSelection(); + return frameSelection ? + frameSelection->GetSelection(nsISelectionController::SELECTION_NORMAL) : + nullptr; +} + +} // namespace a11y +} // namespace mozilla + +#endif + diff --git a/accessible/src/generic/HyperTextAccessible.cpp b/accessible/src/generic/HyperTextAccessible.cpp index 566e269cc69c..5b9ef6ffe635 100644 --- a/accessible/src/generic/HyperTextAccessible.cpp +++ b/accessible/src/generic/HyperTextAccessible.cpp @@ -4,11 +4,10 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#include "HyperTextAccessible.h" +#include "HyperTextAccessible-inl.h" #include "Accessible-inl.h" #include "nsAccessibilityService.h" -#include "nsAccUtils.h" #include "nsIAccessibleTypes.h" #include "DocAccessible.h" #include "Role.h" @@ -17,18 +16,15 @@ #include "TreeWalker.h" #include "nsCaret.h" -#include "nsIClipboard.h" #include "nsContentUtils.h" #include "nsFocusManager.h" #include "nsIDOMRange.h" #include "nsIEditingSession.h" -#include "nsIEditor.h" #include "nsIFrame.h" #include "nsFrameSelection.h" #include "nsILineIterator.h" #include "nsIInterfaceRequestorUtils.h" #include "nsIPersistentProperties2.h" -#include "nsIPlaintextEditor.h" #include "nsIScrollableFrame.h" #include "nsIServiceManager.h" #include "nsTextFragment.h" @@ -46,43 +42,19 @@ using namespace mozilla::a11y; HyperTextAccessible:: HyperTextAccessible(nsIContent* aNode, DocAccessible* aDoc) : - AccessibleWrap(aNode, aDoc) + AccessibleWrap(aNode, aDoc), xpcAccessibleHyperText() { mGenericTypes |= eHyperText; } -NS_IMPL_ADDREF_INHERITED(HyperTextAccessible, AccessibleWrap) -NS_IMPL_RELEASE_INHERITED(HyperTextAccessible, AccessibleWrap) - nsresult HyperTextAccessible::QueryInterface(REFNSIID aIID, void** aInstancePtr) { - *aInstancePtr = nullptr; - - // ARIA roles that these interfaces are not appropriate for. - if (!IsTextRole()) - return Accessible::QueryInterface(aIID, aInstancePtr); - - if (aIID.Equals(NS_GET_IID(nsIAccessibleText))) { - *aInstancePtr = static_cast(this); - NS_ADDREF_THIS(); - return NS_OK; - } - - if (aIID.Equals(NS_GET_IID(nsIAccessibleHyperText))) { - *aInstancePtr = static_cast(this); - NS_ADDREF_THIS(); - return NS_OK; - } - - if (aIID.Equals(NS_GET_IID(nsIAccessibleEditableText))) { - *aInstancePtr = static_cast(this); - NS_ADDREF_THIS(); - return NS_OK; - } - - return Accessible::QueryInterface(aIID, aInstancePtr); + xpcAccessibleHyperText::QueryInterface(aIID, aInstancePtr); + return *aInstancePtr ? NS_OK : Accessible::QueryInterface(aIID, aInstancePtr); } +NS_IMPL_ADDREF_INHERITED(HyperTextAccessible, AccessibleWrap) +NS_IMPL_RELEASE_INHERITED(HyperTextAccessible, AccessibleWrap) role HyperTextAccessible::NativeRole() @@ -407,41 +379,37 @@ HyperTextAccessible::GetPosAndText(int32_t& aStartOffset, int32_t& aEndOffset, return startFrame; } -NS_IMETHODIMP -HyperTextAccessible::GetText(int32_t aStartOffset, int32_t aEndOffset, - nsAString& aText) +void +HyperTextAccessible::TextSubstring(int32_t aStartOffset, int32_t aEndOffset, + nsAString& aText) { aText.Truncate(); - if (IsDefunct()) - return NS_ERROR_FAILURE; - int32_t startOffset = ConvertMagicOffset(aStartOffset); int32_t endOffset = ConvertMagicOffset(aEndOffset); int32_t startChildIdx = GetChildIndexAtOffset(startOffset); - if (startChildIdx == -1) { - // 0 offsets are considered valid for empty text. - return (startOffset == 0 && endOffset == 0) ? NS_OK : NS_ERROR_INVALID_ARG; - } + if (startChildIdx == -1) + return; int32_t endChildIdx = GetChildIndexAtOffset(endOffset); if (endChildIdx == -1) - return NS_ERROR_INVALID_ARG; + return; if (startChildIdx == endChildIdx) { int32_t childOffset = GetChildOffset(startChildIdx); - NS_ENSURE_STATE(childOffset != -1); + if (childOffset == -1) + return; Accessible* child = GetChildAt(startChildIdx); child->AppendTextTo(aText, startOffset - childOffset, endOffset - startOffset); - - return NS_OK; + return; } int32_t startChildOffset = GetChildOffset(startChildIdx); - NS_ENSURE_STATE(startChildOffset != -1); + if (startChildOffset == -1) + return; Accessible* startChild = GetChildAt(startChildIdx); startChild->AppendTextTo(aText, startOffset - startChildOffset); @@ -452,56 +420,18 @@ HyperTextAccessible::GetText(int32_t aStartOffset, int32_t aEndOffset, } int32_t endChildOffset = GetChildOffset(endChildIdx); - NS_ENSURE_STATE(endChildOffset != -1); + if (endChildOffset == -1) + return; Accessible* endChild = GetChildAt(endChildIdx); endChild->AppendTextTo(aText, 0, endOffset - endChildOffset); - - return NS_OK; -} - -/* - * Gets the character count. - */ -NS_IMETHODIMP -HyperTextAccessible::GetCharacterCount(int32_t* aCharacterCount) -{ - NS_ENSURE_ARG_POINTER(aCharacterCount); - *aCharacterCount = 0; - - if (IsDefunct()) - return NS_ERROR_FAILURE; - - *aCharacterCount = CharacterCount(); - return NS_OK; -} - -/* - * Gets the specified character. - */ -NS_IMETHODIMP -HyperTextAccessible::GetCharacterAtOffset(int32_t aOffset, PRUnichar* aCharacter) -{ - NS_ENSURE_ARG_POINTER(aCharacter); - *aCharacter = L'\0'; - - if (IsDefunct()) - return NS_ERROR_FAILURE; - - nsAutoString character; - if (GetCharAt(aOffset, eGetAt, character)) { - *aCharacter = character.First(); - return NS_OK; - } - - return NS_ERROR_INVALID_ARG; } Accessible* HyperTextAccessible::DOMPointToHypertextOffset(nsINode* aNode, int32_t aNodeOffset, int32_t* aHyperTextOffset, - bool aIsEndOffset) + bool aIsEndOffset) const { if (!aHyperTextOffset) return nullptr; @@ -864,26 +794,25 @@ HyperTextAccessible::FindLineBoundary(int32_t aOffset, return -1; } -/** - * nsIAccessibleText impl. - */ -NS_IMETHODIMP -HyperTextAccessible::GetTextBeforeOffset(int32_t aOffset, - AccessibleTextBoundary aBoundaryType, - int32_t* aStartOffset, - int32_t* aEndOffset, nsAString& aText) +void +HyperTextAccessible::TextBeforeOffset(int32_t aOffset, + AccessibleTextBoundary aBoundaryType, + int32_t* aStartOffset, int32_t* aEndOffset, + nsAString& aText) { - if (IsDefunct()) - return NS_ERROR_FAILURE; - if (aBoundaryType == BOUNDARY_CHAR) { GetCharAt(aOffset, eGetBefore, aText, aStartOffset, aEndOffset); - return NS_OK; + return; } + *aStartOffset = *aEndOffset = 0; + aText.Truncate(); + int32_t convertedOffset = ConvertMagicOffset(aOffset); - if (convertedOffset < 0) - return NS_ERROR_INVALID_ARG; + if (convertedOffset < 0) { + NS_ERROR("Wrong given offset!"); + return; + } int32_t adjustedOffset = convertedOffset; if (aOffset == nsIAccessibleText::TEXT_OFFSET_CARET) @@ -892,7 +821,7 @@ HyperTextAccessible::GetTextBeforeOffset(int32_t aOffset, switch (aBoundaryType) { case BOUNDARY_CHAR: MOZ_ASSUME_UNREACHABLE("Already handled!"); - return NS_ERROR_FAILURE; + break; case BOUNDARY_WORD_START: { // If the offset is a word start (except text length offset) then move @@ -909,20 +838,23 @@ HyperTextAccessible::GetTextBeforeOffset(int32_t aOffset, *aStartOffset = FindWordBoundary(*aEndOffset, eDirPrevious, eStartWord); } } - return GetText(*aStartOffset, *aEndOffset, aText); + TextSubstring(*aStartOffset, *aEndOffset, aText); + break; } case BOUNDARY_WORD_END: { // Move word backward twice to find start and end offsets. *aEndOffset = FindWordBoundary(convertedOffset, eDirPrevious, eEndWord); *aStartOffset = FindWordBoundary(*aEndOffset, eDirPrevious, eEndWord); - return GetText(*aStartOffset, *aEndOffset, aText); + TextSubstring(*aStartOffset, *aEndOffset, aText); + break; } case BOUNDARY_LINE_START: *aStartOffset = FindLineBoundary(adjustedOffset, ePrevLineBegin); *aEndOffset = FindLineBoundary(adjustedOffset, eThisLineBegin); - return GetText(*aStartOffset, *aEndOffset, aText); + TextSubstring(*aStartOffset, *aEndOffset, aText); + break; case BOUNDARY_LINE_END: { *aEndOffset = FindLineBoundary(adjustedOffset, ePrevLineEnd); @@ -932,31 +864,31 @@ HyperTextAccessible::GetTextBeforeOffset(int32_t aOffset, tmpOffset--; *aStartOffset = FindLineBoundary(tmpOffset, ePrevLineEnd); - return GetText(*aStartOffset, *aEndOffset, aText); + TextSubstring(*aStartOffset, *aEndOffset, aText); + break; } - - default: - return NS_ERROR_INVALID_ARG; } } -NS_IMETHODIMP -HyperTextAccessible::GetTextAtOffset(int32_t aOffset, - AccessibleTextBoundary aBoundaryType, - int32_t* aStartOffset, - int32_t* aEndOffset, nsAString& aText) +void +HyperTextAccessible::TextAtOffset(int32_t aOffset, + AccessibleTextBoundary aBoundaryType, + int32_t* aStartOffset, int32_t* aEndOffset, + nsAString& aText) { - if (IsDefunct()) - return NS_ERROR_FAILURE; + *aStartOffset = *aEndOffset = 0; + aText.Truncate(); int32_t adjustedOffset = ConvertMagicOffset(aOffset); - if (adjustedOffset < 0) - return NS_ERROR_INVALID_ARG; + if (adjustedOffset < 0) { + NS_ERROR("Wrong given offset!"); + return; + } switch (aBoundaryType) { case BOUNDARY_CHAR: - return GetCharAt(aOffset, eGetAt, aText, aStartOffset, aEndOffset) ? - NS_OK : NS_ERROR_INVALID_ARG; + GetCharAt(aOffset, eGetAt, aText, aStartOffset, aEndOffset); + break; case BOUNDARY_WORD_START: if (aOffset == nsIAccessibleText::TEXT_OFFSET_CARET) @@ -964,7 +896,8 @@ HyperTextAccessible::GetTextAtOffset(int32_t aOffset, *aEndOffset = FindWordBoundary(adjustedOffset, eDirNext, eStartWord); *aStartOffset = FindWordBoundary(*aEndOffset, eDirPrevious, eStartWord); - return GetText(*aStartOffset, *aEndOffset, aText); + TextSubstring(*aStartOffset, *aEndOffset, aText); + break; case BOUNDARY_WORD_END: // Ignore the spec and follow what WebKitGtk does because Orca expects it, @@ -972,7 +905,8 @@ HyperTextAccessible::GetTextAtOffset(int32_t aOffset, // (WebKitGtk behavior) instead the current word (AKT spec). *aEndOffset = FindWordBoundary(adjustedOffset, eDirNext, eEndWord); *aStartOffset = FindWordBoundary(*aEndOffset, eDirPrevious, eEndWord); - return GetText(*aStartOffset, *aEndOffset, aText); + TextSubstring(*aStartOffset, *aEndOffset, aText); + break; case BOUNDARY_LINE_START: if (aOffset == nsIAccessibleText::TEXT_OFFSET_CARET) @@ -980,7 +914,8 @@ HyperTextAccessible::GetTextAtOffset(int32_t aOffset, *aStartOffset = FindLineBoundary(adjustedOffset, eThisLineBegin); *aEndOffset = FindLineBoundary(adjustedOffset, eNextLineBegin); - return GetText(*aStartOffset, *aEndOffset, aText); + TextSubstring(*aStartOffset, *aEndOffset, aText); + break; case BOUNDARY_LINE_END: if (aOffset == nsIAccessibleText::TEXT_OFFSET_CARET) @@ -989,30 +924,30 @@ HyperTextAccessible::GetTextAtOffset(int32_t aOffset, // In contrast to word end boundary we follow the spec here. *aStartOffset = FindLineBoundary(adjustedOffset, ePrevLineEnd); *aEndOffset = FindLineBoundary(adjustedOffset, eThisLineEnd); - return GetText(*aStartOffset, *aEndOffset, aText); - - default: - return NS_ERROR_INVALID_ARG; + TextSubstring(*aStartOffset, *aEndOffset, aText); + break; } } -NS_IMETHODIMP -HyperTextAccessible::GetTextAfterOffset(int32_t aOffset, - AccessibleTextBoundary aBoundaryType, - int32_t* aStartOffset, - int32_t* aEndOffset, nsAString& aText) +void +HyperTextAccessible::TextAfterOffset(int32_t aOffset, + AccessibleTextBoundary aBoundaryType, + int32_t* aStartOffset, int32_t* aEndOffset, + nsAString& aText) { - if (IsDefunct()) - return NS_ERROR_FAILURE; - if (aBoundaryType == BOUNDARY_CHAR) { GetCharAt(aOffset, eGetAfter, aText, aStartOffset, aEndOffset); - return NS_OK; + return; } + *aStartOffset = *aEndOffset = 0; + aText.Truncate(); + int32_t convertedOffset = ConvertMagicOffset(aOffset); - if (convertedOffset < 0) - return NS_ERROR_INVALID_ARG; + if (convertedOffset < 0) { + NS_ERROR("Wrong given offset!"); + return; + } int32_t adjustedOffset = convertedOffset; if (aOffset == nsIAccessibleText::TEXT_OFFSET_CARET) @@ -1021,13 +956,14 @@ HyperTextAccessible::GetTextAfterOffset(int32_t aOffset, switch (aBoundaryType) { case BOUNDARY_CHAR: MOZ_ASSUME_UNREACHABLE("Already handled!"); - return NS_ERROR_FAILURE; + break; case BOUNDARY_WORD_START: // Move word forward twice to find start and end offsets. *aStartOffset = FindWordBoundary(adjustedOffset, eDirNext, eStartWord); *aEndOffset = FindWordBoundary(*aStartOffset, eDirNext, eStartWord); - return GetText(*aStartOffset, *aEndOffset, aText); + TextSubstring(*aStartOffset, *aEndOffset, aText); + break; case BOUNDARY_WORD_END: // If the offset is a word end (except 0 offset) then move forward to find @@ -1044,61 +980,38 @@ HyperTextAccessible::GetTextAfterOffset(int32_t aOffset, *aEndOffset = FindWordBoundary(*aStartOffset, eDirNext, eEndWord); } } - return GetText(*aStartOffset, *aEndOffset, aText); + TextSubstring(*aStartOffset, *aEndOffset, aText); + break; case BOUNDARY_LINE_START: *aStartOffset = FindLineBoundary(adjustedOffset, eNextLineBegin); *aEndOffset = FindLineBoundary(*aStartOffset, eNextLineBegin); - return GetText(*aStartOffset, *aEndOffset, aText); + TextSubstring(*aStartOffset, *aEndOffset, aText); + break; case BOUNDARY_LINE_END: *aStartOffset = FindLineBoundary(adjustedOffset, eThisLineEnd); *aEndOffset = FindLineBoundary(adjustedOffset, eNextLineEnd); - return GetText(*aStartOffset, *aEndOffset, aText); - - default: - return NS_ERROR_INVALID_ARG; + TextSubstring(*aStartOffset, *aEndOffset, aText); + break; } } -// nsIPersistentProperties -// nsIAccessibleText::getTextAttributes(in boolean includeDefAttrs, -// in long offset, -// out long rangeStartOffset, -// out long rangeEndOffset); -NS_IMETHODIMP -HyperTextAccessible::GetTextAttributes(bool aIncludeDefAttrs, - int32_t aOffset, +already_AddRefed +HyperTextAccessible::TextAttributes(bool aIncludeDefAttrs, int32_t aOffset, int32_t* aStartOffset, - int32_t* aEndOffset, - nsIPersistentProperties** aAttributes) + int32_t* aEndOffset) { // 1. Get each attribute and its ranges one after another. // 2. As we get each new attribute, we pass the current start and end offsets // as in/out parameters. In other words, as attributes are collected, // the attribute range itself can only stay the same or get smaller. - NS_ENSURE_ARG_POINTER(aStartOffset); - *aStartOffset = 0; - - NS_ENSURE_ARG_POINTER(aEndOffset); - *aEndOffset = 0; - - if (IsDefunct()) - return NS_ERROR_FAILURE; + *aStartOffset = *aEndOffset = 0; + nsCOMPtr attributes = + do_CreateInstance(NS_PERSISTENTPROPERTIES_CONTRACTID); int32_t offset = ConvertMagicOffset(aOffset); - - if (aAttributes) { - *aAttributes = nullptr; - - nsCOMPtr attributes = - do_CreateInstance(NS_PERSISTENTPROPERTIES_CONTRACTID); - NS_ENSURE_TRUE(attributes, NS_ERROR_OUT_OF_MEMORY); - - NS_ADDREF(*aAttributes = attributes); - } - Accessible* accAtOffset = GetChildAtOffset(offset); if (!accAtOffset) { // Offset 0 is correct offset when accessible has empty text. Include @@ -1106,11 +1019,11 @@ HyperTextAccessible::GetTextAttributes(bool aIncludeDefAttrs, if (offset == 0) { if (aIncludeDefAttrs) { TextAttrsMgr textAttrsMgr(this); - textAttrsMgr.GetAttributes(*aAttributes); + textAttrsMgr.GetAttributes(attributes); } - return NS_OK; + return attributes.forget(); } - return NS_ERROR_INVALID_ARG; + return nullptr; } int32_t accAtOffsetIdx = accAtOffset->IndexInParent(); @@ -1120,48 +1033,33 @@ HyperTextAccessible::GetTextAttributes(bool aIncludeDefAttrs, TextAttrsMgr textAttrsMgr(this, aIncludeDefAttrs, accAtOffset, accAtOffsetIdx); - textAttrsMgr.GetAttributes(*aAttributes, &startOffset, &endOffset); + textAttrsMgr.GetAttributes(attributes, &startOffset, &endOffset); // Compute spelling attributes on text accessible only. nsIFrame *offsetFrame = accAtOffset->GetFrame(); if (offsetFrame && offsetFrame->GetType() == nsGkAtoms::textFrame) { int32_t nodeOffset = 0; - nsresult rv = RenderedToContentOffset(offsetFrame, offsetInAcc, - &nodeOffset); - NS_ENSURE_SUCCESS(rv, rv); + RenderedToContentOffset(offsetFrame, offsetInAcc, &nodeOffset); // Set 'misspelled' text attribute. - rv = GetSpellTextAttribute(accAtOffset->GetNode(), nodeOffset, - &startOffset, &endOffset, - aAttributes ? *aAttributes : nullptr); - NS_ENSURE_SUCCESS(rv, rv); + GetSpellTextAttribute(accAtOffset->GetNode(), nodeOffset, + &startOffset, &endOffset, attributes); } *aStartOffset = startOffset; *aEndOffset = endOffset; - return NS_OK; + return attributes.forget(); } -// nsIPersistentProperties -// nsIAccessibleText::defaultTextAttributes -NS_IMETHODIMP -HyperTextAccessible::GetDefaultTextAttributes(nsIPersistentProperties** aAttributes) +already_AddRefed +HyperTextAccessible::DefaultTextAttributes() { - NS_ENSURE_ARG_POINTER(aAttributes); - *aAttributes = nullptr; - - if (IsDefunct()) - return NS_ERROR_FAILURE; - nsCOMPtr attributes = do_CreateInstance(NS_PERSISTENTPROPERTIES_CONTRACTID); - NS_ENSURE_TRUE(attributes, NS_ERROR_OUT_OF_MEMORY); - - NS_ADDREF(*aAttributes = attributes); TextAttrsMgr textAttrsMgr(this); - textAttrsMgr.GetAttributes(*aAttributes); - return NS_OK; + textAttrsMgr.GetAttributes(attributes); + return attributes.forget(); } int32_t @@ -1255,59 +1153,12 @@ HyperTextAccessible::NativeAttributes() return attributes.forget(); } -/* - * Given an offset, the x, y, width, and height values are filled appropriately. - */ -NS_IMETHODIMP -HyperTextAccessible::GetCharacterExtents(int32_t aOffset, int32_t* aX, int32_t* aY, - int32_t* aWidth, int32_t* aHeight, - uint32_t aCoordType) +int32_t +HyperTextAccessible::OffsetAtPoint(int32_t aX, int32_t aY, uint32_t aCoordType) { - return GetRangeExtents(aOffset, aOffset + 1, aX, aY, aWidth, aHeight, aCoordType); -} - -/* - * Given a start & end offset, the x, y, width, and height values are filled appropriately. - */ -NS_IMETHODIMP -HyperTextAccessible::GetRangeExtents(int32_t aStartOffset, int32_t aEndOffset, - int32_t* aX, int32_t* aY, - int32_t* aWidth, int32_t* aHeight, - uint32_t aCoordType) -{ - nsIntRect boundsRect; - nsIFrame *endFrameUnused; - if (!GetPosAndText(aStartOffset, aEndOffset, nullptr, &endFrameUnused, &boundsRect) || - boundsRect.IsEmpty()) { - return NS_ERROR_FAILURE; - } - - *aX = boundsRect.x; - *aY = boundsRect.y; - *aWidth = boundsRect.width; - *aHeight = boundsRect.height; - - nsAccUtils::ConvertScreenCoordsTo(aX, aY, aCoordType, this); - return NS_OK; -} - -/* - * Gets the offset of the character located at coordinates x and y. x and y are interpreted as being relative to - * the screen or this widget's window depending on coords. - */ -NS_IMETHODIMP -HyperTextAccessible::GetOffsetAtPoint(int32_t aX, int32_t aY, - uint32_t aCoordType, int32_t* aOffset) -{ - *aOffset = -1; - - if (IsDefunct()) - return NS_ERROR_FAILURE; - - nsIFrame *hyperFrame = GetFrame(); - if (!hyperFrame) { - return NS_ERROR_FAILURE; - } + nsIFrame* hyperFrame = GetFrame(); + if (!hyperFrame) + return -1; nsIntPoint coords = nsAccUtils::ConvertToScreenCoords(aX, aY, aCoordType, this); @@ -1318,7 +1169,7 @@ HyperTextAccessible::GetOffsetAtPoint(int32_t aX, int32_t aY, nsRect frameScreenRect = hyperFrame->GetScreenRectInAppUnits(); if (!frameScreenRect.Contains(coordsInAppUnits.x, coordsInAppUnits.y)) - return NS_OK; // Not found, will return -1 + return -1; // Not found nsPoint pointInHyperText(coordsInAppUnits.x - frameScreenRect.x, coordsInAppUnits.y - frameScreenRect.y); @@ -1334,12 +1185,12 @@ HyperTextAccessible::GetOffsetAtPoint(int32_t aX, int32_t aY, Accessible* childAcc = mChildren[childIdx]; nsIFrame *primaryFrame = childAcc->GetFrame(); - NS_ENSURE_TRUE(primaryFrame, NS_ERROR_FAILURE); + NS_ENSURE_TRUE(primaryFrame, -1); nsIFrame *frame = primaryFrame; while (frame) { nsIContent *content = frame->GetContent(); - NS_ENSURE_TRUE(content, NS_ERROR_FAILURE); + NS_ENSURE_TRUE(content, -1); nsPoint pointInFrame = pointInHyperText - frame->GetOffsetTo(hyperFrame); nsSize frameSize = frame->GetSize(); if (pointInFrame.x < frameSize.width && pointInFrame.y < frameSize.height) { @@ -1348,17 +1199,16 @@ HyperTextAccessible::GetOffsetAtPoint(int32_t aX, int32_t aY, nsIFrame::ContentOffsets contentOffsets = frame->GetContentOffsetsFromPointExternal(pointInFrame, nsIFrame::IGNORE_SELECTION_STYLE); if (contentOffsets.IsNull() || contentOffsets.content != content) { - return NS_OK; // Not found, will return -1 + return -1; // Not found } uint32_t addToOffset; nsresult rv = ContentToRenderedOffset(primaryFrame, contentOffsets.offset, &addToOffset); - NS_ENSURE_SUCCESS(rv, rv); + NS_ENSURE_SUCCESS(rv, -1); offset += addToOffset; } - *aOffset = offset; - return NS_OK; + return offset; } frame = frame->GetNextContinuation(); } @@ -1366,164 +1216,7 @@ HyperTextAccessible::GetOffsetAtPoint(int32_t aX, int32_t aY, offset += nsAccUtils::TextLength(childAcc); } - return NS_OK; // Not found, will return -1 -} - - -//////////////////////////////////////////////////////////////////////////////// -// nsIAccessibleHyperText - -NS_IMETHODIMP -HyperTextAccessible::GetLinkCount(int32_t* aLinkCount) -{ - NS_ENSURE_ARG_POINTER(aLinkCount); - *aLinkCount = 0; - - if (IsDefunct()) - return NS_ERROR_FAILURE; - - *aLinkCount = GetLinkCount(); - return NS_OK; -} - -NS_IMETHODIMP -HyperTextAccessible::GetLinkAt(int32_t aIndex, nsIAccessibleHyperLink** aLink) -{ - NS_ENSURE_ARG_POINTER(aLink); - *aLink = nullptr; - - if (IsDefunct()) - return NS_ERROR_FAILURE; - - Accessible* link = GetLinkAt(aIndex); - if (link) - CallQueryInterface(link, aLink); - - return NS_OK; -} - -NS_IMETHODIMP -HyperTextAccessible::GetLinkIndex(nsIAccessibleHyperLink* aLink, - int32_t* aIndex) -{ - NS_ENSURE_ARG_POINTER(aLink); - - if (IsDefunct()) - return NS_ERROR_FAILURE; - - nsRefPtr link(do_QueryObject(aLink)); - *aIndex = GetLinkIndex(link); - return NS_OK; -} - -NS_IMETHODIMP -HyperTextAccessible::GetLinkIndexAtOffset(int32_t aOffset, int32_t* aLinkIndex) -{ - NS_ENSURE_ARG_POINTER(aLinkIndex); - *aLinkIndex = -1; // API says this magic value means 'not found' - - if (IsDefunct()) - return NS_ERROR_FAILURE; - - *aLinkIndex = GetLinkIndexAtOffset(aOffset); - return NS_OK; -} - -/** - * nsIAccessibleEditableText impl. - */ -NS_IMETHODIMP -HyperTextAccessible::SetAttributes(int32_t aStartPos, int32_t aEndPos, - nsISupports* aAttributes) -{ - return NS_ERROR_NOT_IMPLEMENTED; -} - -NS_IMETHODIMP -HyperTextAccessible::SetTextContents(const nsAString& aText) -{ - int32_t numChars = CharacterCount(); - if (numChars == 0 || NS_SUCCEEDED(DeleteText(0, numChars))) { - return InsertText(aText, 0); - } - return NS_ERROR_FAILURE; -} - -NS_IMETHODIMP -HyperTextAccessible::InsertText(const nsAString& aText, int32_t aPosition) -{ - if (IsDefunct()) - return NS_ERROR_FAILURE; - - nsCOMPtr editor = GetEditor(); - - nsCOMPtr peditor(do_QueryInterface(editor)); - NS_ENSURE_STATE(peditor); - - nsresult rv = SetSelectionRange(aPosition, aPosition); - NS_ENSURE_SUCCESS(rv, rv); - - return peditor->InsertText(aText); -} - -NS_IMETHODIMP -HyperTextAccessible::CopyText(int32_t aStartPos, int32_t aEndPos) -{ - if (IsDefunct()) - return NS_ERROR_FAILURE; - - nsCOMPtr editor = GetEditor(); - NS_ENSURE_STATE(editor); - - nsresult rv = SetSelectionRange(aStartPos, aEndPos); - NS_ENSURE_SUCCESS(rv, rv); - - return editor->Copy(); -} - -NS_IMETHODIMP -HyperTextAccessible::CutText(int32_t aStartPos, int32_t aEndPos) -{ - if (IsDefunct()) - return NS_ERROR_FAILURE; - - nsCOMPtr editor = GetEditor(); - NS_ENSURE_STATE(editor); - - nsresult rv = SetSelectionRange(aStartPos, aEndPos); - NS_ENSURE_SUCCESS(rv, rv); - - return editor->Cut(); -} - -NS_IMETHODIMP -HyperTextAccessible::DeleteText(int32_t aStartPos, int32_t aEndPos) -{ - if (IsDefunct()) - return NS_ERROR_FAILURE; - - nsCOMPtr editor = GetEditor(); - NS_ENSURE_STATE(editor); - - nsresult rv = SetSelectionRange(aStartPos, aEndPos); - NS_ENSURE_SUCCESS(rv, rv); - - return editor->DeleteSelection(nsIEditor::eNone, nsIEditor::eStrip); -} - -NS_IMETHODIMP -HyperTextAccessible::PasteText(int32_t aPosition) -{ - if (IsDefunct()) - return NS_ERROR_FAILURE; - - nsCOMPtr editor = GetEditor(); - NS_ENSURE_STATE(editor); - - nsresult rv = SetSelectionRange(aPosition, aPosition); - NS_ENSURE_SUCCESS(rv, rv); - - return editor->Paste(nsIClipboard::kGlobalClipboard); + return -1; // Not found } already_AddRefed @@ -1583,15 +1276,11 @@ HyperTextAccessible::SetSelectionRange(int32_t aStartPos, int32_t aEndPos) TakeFocus(); // Set the selection - SetSelectionBounds(0, aStartPos, aEndPos); + SetSelectionBoundsAt(0, aStartPos, aEndPos); // If range 0 was successfully set, clear any additional selection // ranges remaining from previous selection - nsRefPtr frameSelection = FrameSelection(); - NS_ENSURE_STATE(frameSelection); - - Selection* domSel = - frameSelection->GetSelection(nsISelectionController::SELECTION_NORMAL); + Selection* domSel = DOMSelection(); NS_ENSURE_STATE(domSel); for (int32_t idx = domSel->GetRangeCount() - 1; idx > 0; idx--) @@ -1617,29 +1306,14 @@ HyperTextAccessible::SetSelectionRange(int32_t aStartPos, int32_t aEndPos) return NS_OK; } -NS_IMETHODIMP -HyperTextAccessible::SetCaretOffset(int32_t aCaretOffset) +int32_t +HyperTextAccessible::CaretOffset() const { - return SetSelectionRange(aCaretOffset, aCaretOffset); -} - -/* - * Gets the offset position of the caret (cursor). - */ -NS_IMETHODIMP -HyperTextAccessible::GetCaretOffset(int32_t* aCaretOffset) -{ - NS_ENSURE_ARG_POINTER(aCaretOffset); - *aCaretOffset = -1; - - if (IsDefunct()) - return NS_ERROR_FAILURE; - // Not focused focusable accessible except document accessible doesn't have // a caret. if (!IsDoc() && !FocusMgr()->IsFocused(this) && (InteractiveState() & states::FOCUSABLE)) { - return NS_OK; + return -1; } // No caret if the focused node is not inside this DOM node and this DOM node @@ -1647,16 +1321,12 @@ HyperTextAccessible::GetCaretOffset(int32_t* aCaretOffset) FocusManager::FocusDisposition focusDisp = FocusMgr()->IsInOrContainsFocus(this); if (focusDisp == FocusManager::eNone) - return NS_OK; + return -1; // Turn the focus node and offset of the selection into caret hypretext // offset. - nsRefPtr frameSelection = FrameSelection(); - NS_ENSURE_STATE(frameSelection); - - Selection* domSel = - frameSelection->GetSelection(nsISelectionController::SELECTION_NORMAL); - NS_ENSURE_STATE(domSel); + Selection* domSel = DOMSelection(); + NS_ENSURE_TRUE(domSel, -1); nsINode* focusNode = domSel->GetFocusNode(); int32_t focusOffset = domSel->GetFocusOffset(); @@ -1664,17 +1334,18 @@ HyperTextAccessible::GetCaretOffset(int32_t* aCaretOffset) // No caret if this DOM node is inside of focused node but the selection's // focus point is not inside of this DOM node. if (focusDisp == FocusManager::eContainedByFocus) { - nsINode *resultNode = + nsINode* resultNode = nsCoreUtils::GetDOMNodeFromDOMPoint(focusNode, focusOffset); nsINode* thisNode = GetNode(); if (resultNode != thisNode && !nsCoreUtils::IsAncestorOf(thisNode, resultNode)) - return NS_OK; + return -1; } - DOMPointToHypertextOffset(focusNode, focusOffset, aCaretOffset); - return NS_OK; + int32_t caretOffset = -1; + DOMPointToHypertextOffset(focusNode, focusOffset, &caretOffset); + return caretOffset; } int32_t @@ -1779,26 +1450,21 @@ HyperTextAccessible::GetCaretRect(nsIWidget** aWidget) // ((content screen origin) - (content offset in the widget)) = widget origin on the screen caretRect.MoveBy((*aWidget)->WidgetToScreenOffset() - (*aWidget)->GetClientOffset()); - int32_t caretOffset = -1; - GetCaretOffset(&caretOffset); - // Correct for character size, so that caret always matches the size of // the character. This is important for font size transitions, and is // necessary because the Gecko caret uses the previous character's size as // the user moves forward in the text by character. - int32_t charX = 0, charY = 0, charWidth = 0, charHeight = 0; - if (NS_SUCCEEDED(GetCharacterExtents(caretOffset, &charX, &charY, - &charWidth, &charHeight, - nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE))) { - caretRect.height -= charY - caretRect.y; - caretRect.y = charY; + nsIntRect charRect = CharBounds(CaretOffset(), + nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE); + if (!charRect.IsEmpty()) { + caretRect.height -= charRect.y - caretRect.y; + caretRect.y = charRect.y; } - return caretRect; } already_AddRefed -HyperTextAccessible::FrameSelection() +HyperTextAccessible::FrameSelection() const { nsIFrame* frame = GetFrame(); return frame ? frame->GetFrameSelection() : nullptr; @@ -1846,32 +1512,19 @@ HyperTextAccessible::GetSelectionDOMRanges(int16_t aType, } } -/* - * Gets the number of selected regions. - */ -NS_IMETHODIMP -HyperTextAccessible::GetSelectionCount(int32_t* aSelectionCount) +int32_t +HyperTextAccessible::SelectionCount() { - NS_ENSURE_ARG_POINTER(aSelectionCount); - *aSelectionCount = 0; - nsTArray ranges; GetSelectionDOMRanges(nsISelectionController::SELECTION_NORMAL, &ranges); - *aSelectionCount = int32_t(ranges.Length()); - - return NS_OK; + return ranges.Length(); } -/* - * Gets the start and end offset of the specified selection. - */ -NS_IMETHODIMP -HyperTextAccessible::GetSelectionBounds(int32_t aSelectionNum, - int32_t* aStartOffset, - int32_t* aEndOffset) +bool +HyperTextAccessible::SelectionBoundsAt(int32_t aSelectionNum, + int32_t* aStartOffset, + int32_t* aEndOffset) { - NS_ENSURE_ARG_POINTER(aStartOffset); - NS_ENSURE_ARG_POINTER(aEndOffset); *aStartOffset = *aEndOffset = 0; nsTArray ranges; @@ -1879,7 +1532,7 @@ HyperTextAccessible::GetSelectionBounds(int32_t aSelectionNum, uint32_t rangeCount = ranges.Length(); if (aSelectionNum < 0 || aSelectionNum >= rangeCount) - return NS_ERROR_INVALID_ARG; + return false; nsRange* range = ranges[aSelectionNum]; @@ -1908,128 +1561,83 @@ HyperTextAccessible::GetSelectionBounds(int32_t aSelectionNum, } DOMPointToHypertextOffset(endNode, endOffset, aEndOffset, true); - return NS_OK; + return true; } -/* - * Changes the start and end offset of the specified selection. - */ -NS_IMETHODIMP -HyperTextAccessible::SetSelectionBounds(int32_t aSelectionNum, - int32_t aStartOffset, - int32_t aEndOffset) +bool +HyperTextAccessible::SetSelectionBoundsAt(int32_t aSelectionNum, + int32_t aStartOffset, + int32_t aEndOffset) { - if (IsDefunct()) - return NS_ERROR_FAILURE; - - if (aSelectionNum < 0) - return NS_ERROR_INVALID_ARG; - int32_t startOffset = ConvertMagicOffset(aStartOffset); int32_t endOffset = ConvertMagicOffset(aEndOffset); - nsRefPtr frameSelection = FrameSelection(); - NS_ENSURE_STATE(frameSelection); - - Selection* domSel = - frameSelection->GetSelection(nsISelectionController::SELECTION_NORMAL); - NS_ENSURE_STATE(domSel); - - uint32_t rangeCount = domSel->GetRangeCount(); - if (rangeCount < static_cast(aSelectionNum)) - return NS_ERROR_INVALID_ARG; + Selection* domSel = DOMSelection(); + if (!domSel) + return false; nsRefPtr range; + uint32_t rangeCount = domSel->GetRangeCount(); if (aSelectionNum == rangeCount) range = new nsRange(mContent); else range = domSel->GetRangeAt(aSelectionNum); - nsresult rv = HypertextOffsetsToDOMRange(startOffset, endOffset, range); - NS_ENSURE_SUCCESS(rv, rv); + if (!range) + return false; + + HypertextOffsetsToDOMRange(startOffset, endOffset, range); // If new range was created then add it, otherwise notify selection listeners // that existing selection range was changed. if (aSelectionNum == rangeCount) - return domSel->AddRange(range); + return NS_SUCCEEDED(domSel->AddRange(range)); domSel->RemoveRange(range); - domSel->AddRange(range); - return NS_OK; + return NS_SUCCEEDED(domSel->AddRange(range)); } -/* - * Adds a selection bounded by the specified offsets. - */ -NS_IMETHODIMP -HyperTextAccessible::AddSelection(int32_t aStartOffset, int32_t aEndOffset) +bool +HyperTextAccessible::RemoveFromSelection(int32_t aSelectionNum) { - nsRefPtr frameSelection = FrameSelection(); - NS_ENSURE_STATE(frameSelection); - - Selection* domSel = - frameSelection->GetSelection(nsISelectionController::SELECTION_NORMAL); - NS_ENSURE_STATE(domSel); - - return SetSelectionBounds(domSel->GetRangeCount(), aStartOffset, aEndOffset); -} - -/* - * Removes the specified selection. - */ -NS_IMETHODIMP -HyperTextAccessible::RemoveSelection(int32_t aSelectionNum) -{ - nsRefPtr frameSelection = FrameSelection(); - NS_ENSURE_STATE(frameSelection); - - Selection* domSel = - frameSelection->GetSelection(nsISelectionController::SELECTION_NORMAL); - NS_ENSURE_STATE(domSel); + Selection* domSel = DOMSelection(); + if (!domSel) + return false; if (aSelectionNum < 0 || aSelectionNum >= domSel->GetRangeCount()) - return NS_ERROR_INVALID_ARG; + return false; - return domSel->RemoveRange(domSel->GetRangeAt(aSelectionNum)); + domSel->RemoveRange(domSel->GetRangeAt(aSelectionNum)); + return true; } -// void nsIAccessibleText:: -// scrollSubstringTo(in long startIndex, in long endIndex, -// in unsigned long scrollType); -NS_IMETHODIMP -HyperTextAccessible::ScrollSubstringTo(int32_t aStartIndex, int32_t aEndIndex, +void +HyperTextAccessible::ScrollSubstringTo(int32_t aStartOffset, int32_t aEndOffset, uint32_t aScrollType) { - if (IsDefunct()) - return NS_ERROR_FAILURE; - nsRefPtr range = new nsRange(mContent); - nsresult rv = HypertextOffsetsToDOMRange(aStartIndex, aEndIndex, range); - NS_ENSURE_SUCCESS(rv, rv); - - return nsCoreUtils::ScrollSubstringTo(GetFrame(), range, aScrollType); + nsresult rv = HypertextOffsetsToDOMRange(aStartOffset, aEndOffset, range); + if (NS_SUCCEEDED(rv)) + nsCoreUtils::ScrollSubstringTo(GetFrame(), range, aScrollType); } -// void nsIAccessibleText:: -// scrollSubstringToPoint(in long startIndex, in long endIndex, -// in unsigned long coordinateType, -// in long x, in long y); -NS_IMETHODIMP -HyperTextAccessible::ScrollSubstringToPoint(int32_t aStartIndex, - int32_t aEndIndex, +void +HyperTextAccessible::ScrollSubstringToPoint(int32_t aStartOffset, + int32_t aEndOffset, uint32_t aCoordinateType, int32_t aX, int32_t aY) { nsIFrame *frame = GetFrame(); if (!frame) - return NS_ERROR_FAILURE; + return; nsIntPoint coords = nsAccUtils::ConvertToScreenCoords(aX, aY, aCoordinateType, this); nsRefPtr range = new nsRange(mContent); - nsresult rv = HypertextOffsetsToDOMRange(aStartIndex, aEndIndex, range); - NS_ENSURE_SUCCESS(rv, rv); + nsresult rv = HypertextOffsetsToDOMRange(aStartOffset, aEndOffset, range); + if (NS_FAILED(rv)) + return; nsPresContext* presContext = frame->PresContext(); nsPoint coordsInAppUnits = @@ -2057,7 +1665,8 @@ HyperTextAccessible::ScrollSubstringToPoint(int32_t aStartIndex, int16_t vPercent = offsetPointY * 100 / size.height; rv = nsCoreUtils::ScrollSubstringTo(frame, range, vPercent, hPercent); - NS_ENSURE_SUCCESS(rv, rv); + if (NS_FAILED(rv)) + return; initialScrolled = true; } else { @@ -2070,8 +1679,6 @@ HyperTextAccessible::ScrollSubstringToPoint(int32_t aStartIndex, } frame = parentFrame; } - - return NS_OK; } //////////////////////////////////////////////////////////////////////////////// @@ -2152,7 +1759,7 @@ HyperTextAccessible::CacheChildren() nsresult HyperTextAccessible::ContentToRenderedOffset(nsIFrame* aFrame, int32_t aContentOffset, - uint32_t* aRenderedOffset) + uint32_t* aRenderedOffset) const { if (!aFrame) { // Current frame not rendered -- this can happen if text is set on @@ -2188,7 +1795,7 @@ HyperTextAccessible::ContentToRenderedOffset(nsIFrame* aFrame, int32_t aContentO nsresult HyperTextAccessible::RenderedToContentOffset(nsIFrame* aFrame, uint32_t aRenderedOffset, - int32_t* aContentOffset) + int32_t* aContentOffset) const { if (IsTextField()) { *aContentOffset = aRenderedOffset; diff --git a/accessible/src/generic/HyperTextAccessible.h b/accessible/src/generic/HyperTextAccessible.h index 4db7fc852e93..eccd4d784add 100644 --- a/accessible/src/generic/HyperTextAccessible.h +++ b/accessible/src/generic/HyperTextAccessible.h @@ -6,11 +6,9 @@ #ifndef mozilla_a11y_HyperTextAccessible_h__ #define mozilla_a11y_HyperTextAccessible_h__ -#include "nsIAccessibleText.h" -#include "nsIAccessibleHyperText.h" -#include "nsIAccessibleEditableText.h" - #include "AccessibleWrap.h" +#include "nsIAccessibleTypes.h" +#include "xpcAccessibleHyperText.h" #include "nsFrameSelection.h" #include "nsISelectionController.h" @@ -35,18 +33,13 @@ const PRUnichar kForcedNewLineChar = '\n'; * Special Accessible that knows how contain both text and embedded objects */ class HyperTextAccessible : public AccessibleWrap, - public nsIAccessibleText, - public nsIAccessibleHyperText, - public nsIAccessibleEditableText + public xpcAccessibleHyperText { public: HyperTextAccessible(nsIContent* aContent, DocAccessible* aDoc); virtual ~HyperTextAccessible() { } NS_DECL_ISUPPORTS_INHERITED - NS_DECL_NSIACCESSIBLETEXT - NS_DECL_NSIACCESSIBLEHYPERTEXT - NS_DECL_NSIACCESSIBLEEDITABLETEXT // Accessible virtual int32_t GetLevelInternal(); @@ -59,13 +52,13 @@ public: // HyperTextAccessible (static helper method) - // Convert content offset to rendered text offset + // Convert content offset to rendered text offset nsresult ContentToRenderedOffset(nsIFrame *aFrame, int32_t aContentOffset, - uint32_t *aRenderedOffset); - + uint32_t *aRenderedOffset) const; + // Convert rendered text offset to content offset nsresult RenderedToContentOffset(nsIFrame *aFrame, uint32_t aRenderedOffset, - int32_t *aContentOffset); + int32_t *aContentOffset) const; ////////////////////////////////////////////////////////////////////////////// // HyperLinkAccessible @@ -73,15 +66,13 @@ public: /** * Return link count within this hypertext accessible. */ - uint32_t GetLinkCount() - { - return EmbeddedChildCount(); - } + uint32_t LinkCount() + { return EmbeddedChildCount(); } /** * Return link accessible at the given index. */ - Accessible* GetLinkAt(uint32_t aIndex) + Accessible* LinkAt(uint32_t aIndex) { return GetEmbeddedChildAt(aIndex); } @@ -89,7 +80,7 @@ public: /** * Return index for the given link accessible. */ - int32_t GetLinkIndex(Accessible* aLink) + int32_t LinkIndexOf(Accessible* aLink) { return GetIndexOfEmbeddedChild(aLink); } @@ -97,10 +88,10 @@ public: /** * Return link accessible at the given text offset. */ - int32_t GetLinkIndexAtOffset(uint32_t aOffset) + int32_t LinkIndexAtOffset(uint32_t aOffset) { Accessible* child = GetChildAtOffset(aOffset); - return child ? GetLinkIndex(child) : -1; + return child ? LinkIndexOf(child) : -1; } ////////////////////////////////////////////////////////////////////////////// @@ -134,7 +125,7 @@ public: Accessible* DOMPointToHypertextOffset(nsINode *aNode, int32_t aNodeOffset, int32_t* aHypertextOffset, - bool aIsEndOffset = false); + bool aIsEndOffset = false) const; /** * Turn a start and end hypertext offsets into DOM range. @@ -208,6 +199,37 @@ public: bool GetCharAt(int32_t aOffset, EGetTextType aShift, nsAString& aChar, int32_t* aStartOffset = nullptr, int32_t* aEndOffset = nullptr); + /** + * Return text between given offsets. + */ + void TextSubstring(int32_t aStartOffset, int32_t aEndOffset, nsAString& aText); + + /** + * Return text before/at/after the given offset corresponding to + * the boundary type. + */ + void TextBeforeOffset(int32_t aOffset, AccessibleTextBoundary aBoundaryType, + int32_t* aStartOffset, int32_t* aEndOffset, + nsAString& aText); + void TextAtOffset(int32_t aOffset, AccessibleTextBoundary aBoundaryType, + int32_t* aStartOffset, int32_t* aEndOffset, + nsAString& aText); + void TextAfterOffset(int32_t aOffset, AccessibleTextBoundary aBoundaryType, + int32_t* aStartOffset, int32_t* aEndOffset, + nsAString& aText); + + /** + * Return text attributes for the given text range. + */ + already_AddRefed + TextAttributes(bool aIncludeDefAttrs, int32_t aOffset, + int32_t* aStartOffset, int32_t* aEndOffset); + + /** + * Return text attributes applied to the accessible. + */ + already_AddRefed DefaultTextAttributes(); + /** * Return text offset of the given child accessible within hypertext * accessible. @@ -247,14 +269,34 @@ public: } /** - * Return the bounds of the text between given start and end offset. + * Return true if the given offset/range is valid. */ - nsIntRect GetTextBounds(int32_t aStartOffset, int32_t aEndOffset) - { - nsIntRect bounds; - GetPosAndText(aStartOffset, aEndOffset, nullptr, nullptr, &bounds); - return bounds; - } + bool IsValidOffset(int32_t aOffset); + bool IsValidRange(int32_t aStartOffset, int32_t aEndOffset); + + /** + * Return an offset at the given point. + */ + int32_t OffsetAtPoint(int32_t aX, int32_t aY, uint32_t aCoordType); + + /** + * Return a rect of the given text range relative given coordinate system. + */ + nsIntRect TextBounds(int32_t aStartOffset, int32_t aEndOffset, + uint32_t aCoordType = nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE); + + /** + * Return a rect for character at given offset relative given coordinate + * system. + */ + nsIntRect CharBounds(int32_t aOffset, uint32_t aCoordType) + { return TextBounds(aOffset, aOffset + 1, aCoordType); } + + /** + * Get/set caret offset, if no caret then -1. + */ + int32_t CaretOffset() const; + void SetCaretOffset(int32_t aOffset) { SetSelectionRange(aOffset, aOffset); } /** * Provide the line number for the caret. @@ -271,9 +313,60 @@ public: */ nsIntRect GetCaretRect(nsIWidget** aWidget); + /** + * Return selected regions count within the accessible. + */ + int32_t SelectionCount(); + + /** + * Return the start and end offset of the specified selection. + */ + bool SelectionBoundsAt(int32_t aSelectionNum, + int32_t* aStartOffset, int32_t* aEndOffset); + + /* + * Changes the start and end offset of the specified selection. + * @return true if succeeded + */ + bool SetSelectionBoundsAt(int32_t aSelectionNum, + int32_t aStartOffset, int32_t aEndOffset); + + /** + * Adds a selection bounded by the specified offsets. + * @return true if succeeded + */ + bool AddToSelection(int32_t aStartOffset, int32_t aEndOffset); + + /* + * Removes the specified selection. + * @return true if succeeded + */ + bool RemoveFromSelection(int32_t aSelectionNum); + + /** + * Scroll the given text range into view. + */ + void ScrollSubstringTo(int32_t aStartOffset, int32_t aEndOffset, + uint32_t aScrollType); + + /** + * Scroll the given text range to the given point. + */ + void ScrollSubstringToPoint(int32_t aStartOffset, + int32_t aEndOffset, + uint32_t aCoordinateType, + int32_t aX, int32_t aY); + ////////////////////////////////////////////////////////////////////////////// // EditableTextAccessible + void ReplaceText(const nsAString& aText); + void InsertText(const nsAString& aText, int32_t aPosition); + void CopyText(int32_t aStartPos, int32_t aEndPos); + void CutText(int32_t aStartPos, int32_t aEndPos); + void DeleteText(int32_t aStartPos, int32_t aEndPos); + void PasteText(int32_t aPosition); + /** * Return the editor associated with the accessible. */ @@ -289,39 +382,12 @@ protected: /** * Transform magic offset into text offset. */ - int32_t ConvertMagicOffset(int32_t aOffset) - { - if (aOffset == nsIAccessibleText::TEXT_OFFSET_END_OF_TEXT) - return CharacterCount(); - - if (aOffset == nsIAccessibleText::TEXT_OFFSET_CARET) { - int32_t caretOffset = -1; - GetCaretOffset(&caretOffset); - return caretOffset; - } - - return aOffset; - } + int32_t ConvertMagicOffset(int32_t aOffset); /** * Adjust an offset the caret stays at to get a text by line boundary. */ - int32_t AdjustCaretOffset(int32_t aOffset) - { - // It is the same character offset when the caret is visually at the very - // end of a line or the start of a new line (soft line break). Getting text - // at the line should provide the line with the visual caret, otherwise - // screen readers will announce the wrong line as the user presses up or - // down arrow and land at the end of a line. - if (aOffset > 0) { - nsRefPtr frameSelection = FrameSelection(); - if (frameSelection && - frameSelection->GetHint() == nsFrameSelection::HINTLEFT) { - return aOffset - 1; - } - } - return aOffset; - } + int32_t AdjustCaretOffset(int32_t aOffset) const; /** * Return true if the given offset points to terminal empty line if any. @@ -427,9 +493,10 @@ protected: // Selection helpers /** - * Return frame selection object for the accessible. + * Return frame/DOM selection object for the accessible. */ - virtual already_AddRefed FrameSelection(); + virtual already_AddRefed FrameSelection() const; + Selection* DOMSelection() const; /** * Return selection ranges within the accessible subtree. @@ -443,7 +510,7 @@ protected: Accessible* aAccessible, mozilla::a11y::DOMPoint* aPoint); - + /** * Return hyper text offset for the specified bound of the given DOM range. * If the bound is outside of the hyper text then offset value is either @@ -466,7 +533,7 @@ protected: * Set 'misspelled' text attribute and return range offsets where the * attibute is stretched. If the text is not misspelled at the given offset * then we expose only range offsets where text is not misspelled. The method - * is used by GetTextAttributes() method. + * is used by TextAttributes() method. * * @param aIncludeDefAttrs [in] points whether text attributes having default * values of attributes should be included diff --git a/accessible/src/generic/moz.build b/accessible/src/generic/moz.build index 2149a5c3879f..5db24877cd10 100644 --- a/accessible/src/generic/moz.build +++ b/accessible/src/generic/moz.build @@ -4,15 +4,13 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -MODULE = 'accessibility' - EXPORTS.mozilla.a11y += [ 'Accessible.h', 'DocAccessible.h', 'HyperTextAccessible.h', ] -SOURCES += [ +UNIFIED_SOURCES += [ 'Accessible.cpp', 'ApplicationAccessible.cpp', 'ARIAGridAccessible.cpp', @@ -27,10 +25,6 @@ SOURCES += [ 'TextLeafAccessible.cpp', ] -LIBRARY_NAME = 'accessibility_generic_s' - -LIBXUL_LIBRARY = True - LOCAL_INCLUDES += [ '../../../layout/generic', '../../../layout/xul/base/src', @@ -56,3 +50,5 @@ else: LOCAL_INCLUDES += [ '../other', ] + +FINAL_LIBRARY = 'xul' diff --git a/accessible/src/html/HTMLFormControlAccessible.cpp b/accessible/src/html/HTMLFormControlAccessible.cpp index 1384b4b35f9b..bc3601fb49e3 100644 --- a/accessible/src/html/HTMLFormControlAccessible.cpp +++ b/accessible/src/html/HTMLFormControlAccessible.cpp @@ -27,6 +27,7 @@ #include "nsIServiceManager.h" #include "nsITextControlFrame.h" +#include "mozilla/FloatingPoint.h" #include "mozilla/Preferences.h" using namespace mozilla; @@ -545,9 +546,6 @@ HTMLFileInputAccessible::HandleAccEvent(AccEvent* aEvent) // HTMLRangeAccessible //////////////////////////////////////////////////////////////////////////////// -NS_IMPL_ISUPPORTS_INHERITED1(HTMLRangeAccessible, LeafAccessible, - nsIAccessibleValue) - role HTMLRangeAccessible::NativeRole() { @@ -570,58 +568,53 @@ HTMLRangeAccessible::Value(nsString& aValue) HTMLInputElement::FromContent(mContent)->GetValue(aValue); } -NS_IMETHODIMP -HTMLRangeAccessible::GetMaximumValue(double* aMaximumValue) +double +HTMLRangeAccessible::MaxValue() const { - nsresult rv = LeafAccessible::GetMaximumValue(aMaximumValue); - if (rv != NS_OK_NO_ARIA_VALUE) - return rv; + double value = LeafAccessible::MaxValue(); + if (!IsNaN(value)) + return value; - *aMaximumValue = HTMLInputElement::FromContent(mContent)->GetMaximum().toDouble(); - return NS_OK; + return HTMLInputElement::FromContent(mContent)->GetMaximum().toDouble(); } -NS_IMETHODIMP -HTMLRangeAccessible::GetMinimumValue(double* aMinimumValue) +double +HTMLRangeAccessible::MinValue() const { - nsresult rv = LeafAccessible::GetMinimumValue(aMinimumValue); - if (rv != NS_OK_NO_ARIA_VALUE) - return rv; + double value = LeafAccessible::MinValue(); + if (!IsNaN(value)) + return value; - *aMinimumValue = HTMLInputElement::FromContent(mContent)->GetMinimum().toDouble(); - return NS_OK; + return HTMLInputElement::FromContent(mContent)->GetMinimum().toDouble(); } - -NS_IMETHODIMP -HTMLRangeAccessible::GetMinimumIncrement(double* aMinimumIncrement) +double +HTMLRangeAccessible::Step() const { - nsresult rv = LeafAccessible::GetMinimumIncrement(aMinimumIncrement); - if (rv != NS_OK_NO_ARIA_VALUE) - return rv; + double value = LeafAccessible::Step(); + if (!IsNaN(value)) + return value; - *aMinimumIncrement = HTMLInputElement::FromContent(mContent)->GetStep().toDouble(); - return NS_OK; + return HTMLInputElement::FromContent(mContent)->GetStep().toDouble(); } -NS_IMETHODIMP -HTMLRangeAccessible::GetCurrentValue(double* aCurrentValue) +double +HTMLRangeAccessible::CurValue() const { - nsresult rv = LeafAccessible::GetCurrentValue(aCurrentValue); - if (rv != NS_OK_NO_ARIA_VALUE) - return rv; + double value = LeafAccessible::CurValue(); + if (!IsNaN(value)) + return value; - *aCurrentValue = HTMLInputElement::FromContent(mContent)->GetValueAsDecimal().toDouble(); - return NS_OK; + return HTMLInputElement::FromContent(mContent)->GetValueAsDecimal().toDouble(); } -NS_IMETHODIMP -HTMLRangeAccessible::SetCurrentValue(double aValue) +bool +HTMLRangeAccessible::SetCurValue(double aValue) { ErrorResult er; HTMLInputElement::FromContent(mContent)->SetValueAsNumber(aValue, er); - return er.ErrorCode(); + return !er.Failed(); } diff --git a/accessible/src/html/HTMLFormControlAccessible.h b/accessible/src/html/HTMLFormControlAccessible.h index 44fd50514a1b..843227b59563 100644 --- a/accessible/src/html/HTMLFormControlAccessible.h +++ b/accessible/src/html/HTMLFormControlAccessible.h @@ -172,13 +172,17 @@ public: mStateFlags |= eHasNumericValue; } - NS_DECL_ISUPPORTS_INHERITED - NS_DECL_NSIACCESSIBLEVALUE - // Accessible virtual void Value(nsString& aValue); virtual mozilla::a11y::role NativeRole(); + // Value + virtual double MaxValue() const MOZ_OVERRIDE; + virtual double MinValue() const MOZ_OVERRIDE; + virtual double CurValue() const MOZ_OVERRIDE; + virtual double Step() const MOZ_OVERRIDE; + virtual bool SetCurValue(double aValue) MOZ_OVERRIDE; + // Widgets virtual bool IsWidget() const; }; diff --git a/accessible/src/html/moz.build b/accessible/src/html/moz.build index ca13704ae244..4452eb34e973 100644 --- a/accessible/src/html/moz.build +++ b/accessible/src/html/moz.build @@ -4,9 +4,7 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -MODULE = 'accessibility' - -SOURCES += [ +UNIFIED_SOURCES += [ 'HTMLCanvasAccessible.cpp', 'HTMLElementAccessibles.cpp', 'HTMLFormControlAccessible.cpp', @@ -17,10 +15,6 @@ SOURCES += [ 'HTMLTableAccessible.cpp', ] -LIBRARY_NAME = 'accessibility_html_s' - -LIBXUL_LIBRARY = True - LOCAL_INCLUDES += [ '../../../layout/generic', '../../../layout/tables', @@ -47,3 +41,5 @@ else: LOCAL_INCLUDES += [ '../other', ] + +FINAL_LIBRARY = 'xul' diff --git a/accessible/src/jsat/AccessFu.jsm b/accessible/src/jsat/AccessFu.jsm index 43cacb5f7fbc..c82fe3e28fd9 100644 --- a/accessible/src/jsat/AccessFu.jsm +++ b/accessible/src/jsat/AccessFu.jsm @@ -86,7 +86,7 @@ this.AccessFu = { Cu.import('resource://gre/modules/accessibility/TouchAdapter.jsm'); Cu.import('resource://gre/modules/accessibility/Presentation.jsm'); - Logger.info('enable'); + Logger.info('Enabled'); for each (let mm in Utils.AllMessageManagers) { this._addMessageListeners(mm); @@ -145,7 +145,7 @@ this.AccessFu = { this._enabled = false; - Logger.info('disable'); + Logger.info('Disabled'); Utils.win.document.removeChild(this.stylesheet.get()); @@ -524,9 +524,8 @@ var Output = { for (let action of aActions) { let window = Utils.win; - Logger.info('tts.' + action.method, - '"' + action.data + '"', - JSON.stringify(action.options)); + Logger.debug('tts.' + action.method, '"' + action.data + '"', + JSON.stringify(action.options)); if (!action.options.enqueue && this.webspeechEnabled) { window.speechSynthesis.cancel(); @@ -715,8 +714,8 @@ var Input = { _handleGesture: function _handleGesture(aGesture) { let gestureName = aGesture.type + aGesture.touches.length; - Logger.info('Gesture', aGesture.type, - '(fingers: ' + aGesture.touches.length + ')'); + Logger.debug('Gesture', aGesture.type, + '(fingers: ' + aGesture.touches.length + ')'); switch (gestureName) { case 'dwell1': diff --git a/accessible/src/jsat/Constants.jsm b/accessible/src/jsat/Constants.jsm new file mode 100644 index 000000000000..5dcc1d4697f4 --- /dev/null +++ b/accessible/src/jsat/Constants.jsm @@ -0,0 +1,39 @@ +const Ci = Components.interfaces; +const Cu = Components.utils; + +Cu.import('resource://gre/modules/XPCOMUtils.jsm'); + +this.EXPORTED_SYMBOLS = ['Roles', 'Events', 'Relations', 'Filters']; + +function ConstantsMap (aObject, aPrefix) { + let offset = aPrefix.length; + for (var name in aObject) { + if (name.indexOf(aPrefix) === 0) { + this[name.slice(offset)] = aObject[name]; + } + } +} + +XPCOMUtils.defineLazyGetter( + this, 'Roles', + function() { + return new ConstantsMap(Ci.nsIAccessibleRole, 'ROLE_'); + }); + +XPCOMUtils.defineLazyGetter( + this, 'Events', + function() { + return new ConstantsMap(Ci.nsIAccessibleEvent, 'EVENT_'); + }); + +XPCOMUtils.defineLazyGetter( + this, 'Relations', + function() { + return new ConstantsMap(Ci.nsIAccessibleRelation, 'RELATION_'); + }); + +XPCOMUtils.defineLazyGetter( + this, 'Filters', + function() { + return new ConstantsMap(Ci.nsIAccessibleTraversalRule, 'FILTER_'); + }); diff --git a/accessible/src/jsat/EventManager.jsm b/accessible/src/jsat/EventManager.jsm index 781b647e431f..920cdca07505 100644 --- a/accessible/src/jsat/EventManager.jsm +++ b/accessible/src/jsat/EventManager.jsm @@ -7,21 +7,6 @@ const Ci = Components.interfaces; const Cu = Components.utils; -const EVENT_VIRTUALCURSOR_CHANGED = Ci.nsIAccessibleEvent.EVENT_VIRTUALCURSOR_CHANGED; -const EVENT_STATE_CHANGE = Ci.nsIAccessibleEvent.EVENT_STATE_CHANGE; -const EVENT_SCROLLING_START = Ci.nsIAccessibleEvent.EVENT_SCROLLING_START; -const EVENT_TEXT_CARET_MOVED = Ci.nsIAccessibleEvent.EVENT_TEXT_CARET_MOVED; -const EVENT_TEXT_INSERTED = Ci.nsIAccessibleEvent.EVENT_TEXT_INSERTED; -const EVENT_TEXT_REMOVED = Ci.nsIAccessibleEvent.EVENT_TEXT_REMOVED; -const EVENT_FOCUS = Ci.nsIAccessibleEvent.EVENT_FOCUS; -const EVENT_SHOW = Ci.nsIAccessibleEvent.EVENT_SHOW; -const EVENT_HIDE = Ci.nsIAccessibleEvent.EVENT_HIDE; - -const ROLE_INTERNAL_FRAME = Ci.nsIAccessibleRole.ROLE_INTERNAL_FRAME; -const ROLE_DOCUMENT = Ci.nsIAccessibleRole.ROLE_DOCUMENT; -const ROLE_CHROME_WINDOW = Ci.nsIAccessibleRole.ROLE_CHROME_WINDOW; -const ROLE_TEXT_LEAF = Ci.nsIAccessibleRole.ROLE_TEXT_LEAF; - const TEXT_NODE = 3; Cu.import('resource://gre/modules/XPCOMUtils.jsm'); @@ -35,6 +20,10 @@ XPCOMUtils.defineLazyModuleGetter(this, 'Presentation', 'resource://gre/modules/accessibility/Presentation.jsm'); XPCOMUtils.defineLazyModuleGetter(this, 'TraversalRules', 'resource://gre/modules/accessibility/TraversalRules.jsm'); +XPCOMUtils.defineLazyModuleGetter(this, 'Roles', + 'resource://gre/modules/accessibility/Constants.jsm'); +XPCOMUtils.defineLazyModuleGetter(this, 'Events', + 'resource://gre/modules/accessibility/Constants.jsm'); this.EXPORTED_SYMBOLS = ['EventManager']; @@ -57,7 +46,7 @@ this.EventManager.prototype = { start: function start() { try { if (!this._started) { - Logger.info('EventManager.start', Utils.MozBuildApp); + Logger.debug('EventManager.start'); this._started = true; @@ -84,7 +73,7 @@ this.EventManager.prototype = { if (!this._started) { return; } - Logger.info('EventManager.stop', Utils.MozBuildApp); + Logger.debug('EventManager.stop'); AccessibilityEventObserver.removeListener(this); try { this.webProgress.removeProgressListener(this); @@ -144,7 +133,7 @@ this.EventManager.prototype = { // Don't bother with non-content events in firefox. if (Utils.MozBuildApp == 'browser' && - aEvent.eventType != EVENT_VIRTUALCURSOR_CHANGED && + aEvent.eventType != Events.VIRTUALCURSOR_CHANGED && // XXX Bug 442005 results in DocAccessible::getDocType returning // NS_ERROR_FAILURE. Checking for aEvent.accessibleDocument.docType == // 'window' does not currently work. @@ -154,12 +143,12 @@ this.EventManager.prototype = { } switch (aEvent.eventType) { - case EVENT_VIRTUALCURSOR_CHANGED: + case Events.VIRTUALCURSOR_CHANGED: { let pivot = aEvent.accessible. QueryInterface(Ci.nsIAccessibleDocument).virtualCursor; let position = pivot.position; - if (position && position.role == ROLE_INTERNAL_FRAME) + if (position && position.role == Roles.INTERNAL_FRAME) break; let event = aEvent. QueryInterface(Ci.nsIAccessibleVirtualCursorChangeEvent); @@ -174,7 +163,7 @@ this.EventManager.prototype = { break; } - case EVENT_STATE_CHANGE: + case Events.STATE_CHANGE: { let event = aEvent.QueryInterface(Ci.nsIAccessibleStateChangeEvent); if (event.state == Ci.nsIAccessibleStates.STATE_CHECKED && @@ -191,13 +180,13 @@ this.EventManager.prototype = { } break; } - case EVENT_SCROLLING_START: + case Events.SCROLLING_START: { let vc = Utils.getVirtualCursor(aEvent.accessibleDocument); vc.moveNext(TraversalRules.Simple, aEvent.accessible, true); break; } - case EVENT_TEXT_CARET_MOVED: + case Events.TEXT_CARET_MOVED: { let acc = aEvent.accessible; let characterCount = acc. @@ -233,7 +222,7 @@ this.EventManager.prototype = { this.editState = editState; break; } - case EVENT_SHOW: + case Events.SHOW: { let {liveRegion, isPolite} = this._handleLiveRegion(aEvent, ['additions', 'all']); @@ -242,14 +231,14 @@ this.EventManager.prototype = { break; } // Show for text is handled by the EVENT_TEXT_INSERTED handler. - if (aEvent.accessible.role === ROLE_TEXT_LEAF) { + if (aEvent.accessible.role === Roles.TEXT_LEAF) { break; } - this._dequeueLiveEvent(EVENT_HIDE, liveRegion); + this._dequeueLiveEvent(Events.HIDE, liveRegion); this.present(Presentation.liveRegion(liveRegion, isPolite, false)); break; } - case EVENT_HIDE: + case Events.HIDE: { let {liveRegion, isPolite} = this._handleLiveRegion( aEvent.QueryInterface(Ci.nsIAccessibleHideEvent), @@ -259,14 +248,14 @@ this.EventManager.prototype = { break; } // Hide for text is handled by the EVENT_TEXT_REMOVED handler. - if (aEvent.accessible.role === ROLE_TEXT_LEAF) { + if (aEvent.accessible.role === Roles.TEXT_LEAF) { break; } - this._queueLiveEvent(EVENT_HIDE, liveRegion, isPolite); + this._queueLiveEvent(Events.HIDE, liveRegion, isPolite); break; } - case EVENT_TEXT_INSERTED: - case EVENT_TEXT_REMOVED: + case Events.TEXT_INSERTED: + case Events.TEXT_REMOVED: { let {liveRegion, isPolite} = this._handleLiveRegion(aEvent, ['text', 'all']); @@ -277,12 +266,12 @@ this.EventManager.prototype = { } break; } - case EVENT_FOCUS: + case Events.FOCUS: { // Put vc where the focus is at let acc = aEvent.accessible; let doc = aEvent.accessibleDocument; - if (acc.role != ROLE_DOCUMENT && doc.role != ROLE_CHROME_WINDOW) { + if (acc.role != Roles.DOCUMENT && doc.role != Roles.CHROME_WINDOW) { let vc = Utils.getVirtualCursor(doc); vc.moveNext(TraversalRules.Simple, acc, true); } @@ -314,11 +303,11 @@ this.EventManager.prototype = { return; } if (aLiveRegion) { - if (aEvent.eventType === EVENT_TEXT_REMOVED) { - this._queueLiveEvent(EVENT_TEXT_REMOVED, aLiveRegion, aIsPolite, + if (aEvent.eventType === Events.TEXT_REMOVED) { + this._queueLiveEvent(Events.TEXT_REMOVED, aLiveRegion, aIsPolite, modifiedText); } else { - this._dequeueLiveEvent(EVENT_TEXT_REMOVED, aLiveRegion); + this._dequeueLiveEvent(Events.TEXT_REMOVED, aLiveRegion); this.present(Presentation.liveRegion(aLiveRegion, aIsPolite, false, modifiedText)); } diff --git a/accessible/src/jsat/Makefile.in b/accessible/src/jsat/Makefile.in index a26c4544f744..c580d191c1bf 100644 --- a/accessible/src/jsat/Makefile.in +++ b/accessible/src/jsat/Makefile.in @@ -1,19 +1,3 @@ # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this file, # You can obtain one at http://mozilla.org/MPL/2.0/. - -INSTALL_TARGETS += ACCESSFU - -ACCESSFU_FILES := \ - AccessFu.jsm \ - EventManager.jsm \ - jar.mn \ - Makefile.in \ - OutputGenerator.jsm \ - Presentation.jsm \ - TouchAdapter.jsm \ - TraversalRules.jsm \ - Utils.jsm \ - $(NULL) - -ACCESSFU_DEST = $(FINAL_TARGET)/modules/accessibility diff --git a/accessible/src/jsat/OutputGenerator.jsm b/accessible/src/jsat/OutputGenerator.jsm index 1605d1e400cf..3cab3c00f12e 100644 --- a/accessible/src/jsat/OutputGenerator.jsm +++ b/accessible/src/jsat/OutputGenerator.jsm @@ -18,10 +18,6 @@ const NAME_FROM_SUBTREE_RULE = 0x10; const OUTPUT_DESC_FIRST = 0; const OUTPUT_DESC_LAST = 1; -const ROLE_LISTITEM = Ci.nsIAccessibleRole.ROLE_LISTITEM; -const ROLE_STATICTEXT = Ci.nsIAccessibleRole.ROLE_STATICTEXT; -const ROLE_LINK = Ci.nsIAccessibleRole.ROLE_LINK; - Cu.import('resource://gre/modules/XPCOMUtils.jsm'); XPCOMUtils.defineLazyModuleGetter(this, 'Utils', 'resource://gre/modules/accessibility/Utils.jsm'); @@ -31,6 +27,8 @@ XPCOMUtils.defineLazyModuleGetter(this, 'Logger', 'resource://gre/modules/accessibility/Utils.jsm'); XPCOMUtils.defineLazyModuleGetter(this, 'PluralForm', 'resource://gre/modules/PluralForm.jsm'); +XPCOMUtils.defineLazyModuleGetter(this, 'Roles', + 'resource://gre/modules/accessibility/Constants.jsm'); var gStringBundle = Cc['@mozilla.org/intl/stringbundle;1']. getService(Ci.nsIStringBundleService). @@ -697,8 +695,8 @@ this.BrailleGenerator = { let braille = this.objectOutputFunctions._generateBaseOutput.apply(this, arguments); if (aAccessible.indexInParent === 1 && - aAccessible.parent.role == ROLE_LISTITEM && - aAccessible.previousSibling.role == ROLE_STATICTEXT) { + aAccessible.parent.role == Roles.LISTITEM && + aAccessible.previousSibling.role == Roles.STATICTEXT) { if (aAccessible.parent.parent && aAccessible.parent.parent.DOMNode && aAccessible.parent.parent.DOMNode.nodeName == 'UL') { braille.unshift('*'); @@ -755,7 +753,7 @@ this.BrailleGenerator = { statictext: function statictext(aAccessible, aRoleStr, aStates, aFlags) { // Since we customize the list bullet's output, we add the static // text from the first node in each listitem, so skip it here. - if (aAccessible.parent.role == ROLE_LISTITEM) { + if (aAccessible.parent.role == Roles.LISTITEM) { return []; } @@ -788,7 +786,7 @@ this.BrailleGenerator = { }, _getContextStart: function _getContextStart(aContext) { - if (aContext.accessible.parent.role == ROLE_LINK) { + if (aContext.accessible.parent.role == Roles.LINK) { return [aContext.accessible.parent]; } diff --git a/accessible/src/jsat/TouchAdapter.jsm b/accessible/src/jsat/TouchAdapter.jsm index fa65e2aee383..87a680f8d6ab 100644 --- a/accessible/src/jsat/TouchAdapter.jsm +++ b/accessible/src/jsat/TouchAdapter.jsm @@ -46,7 +46,7 @@ this.TouchAdapter = { SYNTH_ID: -1, start: function TouchAdapter_start() { - Logger.info('TouchAdapter.start'); + Logger.debug('TouchAdapter.start'); this._touchPoints = {}; this._dwellTimeout = 0; @@ -64,7 +64,7 @@ this.TouchAdapter = { }, stop: function TouchAdapter_stop() { - Logger.info('TouchAdapter.stop'); + Logger.debug('TouchAdapter.stop'); let target = Utils.win; diff --git a/accessible/src/jsat/TraversalRules.jsm b/accessible/src/jsat/TraversalRules.jsm index 983ebb96f1e6..e8599d416eae 100644 --- a/accessible/src/jsat/TraversalRules.jsm +++ b/accessible/src/jsat/TraversalRules.jsm @@ -9,61 +9,24 @@ const Ci = Components.interfaces; const Cu = Components.utils; const Cr = Components.results; -const FILTER_IGNORE = Ci.nsIAccessibleTraversalRule.FILTER_IGNORE; -const FILTER_MATCH = Ci.nsIAccessibleTraversalRule.FILTER_MATCH; -const FILTER_IGNORE_SUBTREE = Ci.nsIAccessibleTraversalRule.FILTER_IGNORE_SUBTREE; - -const ROLE_MENUITEM = Ci.nsIAccessibleRole.ROLE_MENUITEM; -const ROLE_LINK = Ci.nsIAccessibleRole.ROLE_LINK; -const ROLE_PAGETAB = Ci.nsIAccessibleRole.ROLE_PAGETAB; -const ROLE_GRAPHIC = Ci.nsIAccessibleRole.ROLE_GRAPHIC; -const ROLE_STATICTEXT = Ci.nsIAccessibleRole.ROLE_STATICTEXT; -const ROLE_TEXT_LEAF = Ci.nsIAccessibleRole.ROLE_TEXT_LEAF; -const ROLE_PUSHBUTTON = Ci.nsIAccessibleRole.ROLE_PUSHBUTTON; -const ROLE_SPINBUTTON = Ci.nsIAccessibleRole.ROLE_SPINBUTTON; -const ROLE_CHECKBUTTON = Ci.nsIAccessibleRole.ROLE_CHECKBUTTON; -const ROLE_RADIOBUTTON = Ci.nsIAccessibleRole.ROLE_RADIOBUTTON; -const ROLE_COMBOBOX = Ci.nsIAccessibleRole.ROLE_COMBOBOX; -const ROLE_PROGRESSBAR = Ci.nsIAccessibleRole.ROLE_PROGRESSBAR; -const ROLE_BUTTONDROPDOWN = Ci.nsIAccessibleRole.ROLE_BUTTONDROPDOWN; -const ROLE_BUTTONMENU = Ci.nsIAccessibleRole.ROLE_BUTTONMENU; -const ROLE_CHECK_MENU_ITEM = Ci.nsIAccessibleRole.ROLE_CHECK_MENU_ITEM; -const ROLE_PASSWORD_TEXT = Ci.nsIAccessibleRole.ROLE_PASSWORD_TEXT; -const ROLE_RADIO_MENU_ITEM = Ci.nsIAccessibleRole.ROLE_RADIO_MENU_ITEM; -const ROLE_TOGGLE_BUTTON = Ci.nsIAccessibleRole.ROLE_TOGGLE_BUTTON; -const ROLE_KEY = Ci.nsIAccessibleRole.ROLE_KEY; -const ROLE_ENTRY = Ci.nsIAccessibleRole.ROLE_ENTRY; -const ROLE_LIST = Ci.nsIAccessibleRole.ROLE_LIST; -const ROLE_DEFINITION_LIST = Ci.nsIAccessibleRole.ROLE_DEFINITION_LIST; -const ROLE_LISTITEM = Ci.nsIAccessibleRole.ROLE_LISTITEM; -const ROLE_BUTTONDROPDOWNGRID = Ci.nsIAccessibleRole.ROLE_BUTTONDROPDOWNGRID; -const ROLE_LISTBOX = Ci.nsIAccessibleRole.ROLE_LISTBOX; -const ROLE_OPTION = Ci.nsIAccessibleRole.ROLE_OPTION; -const ROLE_SLIDER = Ci.nsIAccessibleRole.ROLE_SLIDER; -const ROLE_HEADING = Ci.nsIAccessibleRole.ROLE_HEADING; -const ROLE_HEADER = Ci.nsIAccessibleRole.ROLE_HEADER; -const ROLE_TERM = Ci.nsIAccessibleRole.ROLE_TERM; -const ROLE_SEPARATOR = Ci.nsIAccessibleRole.ROLE_SEPARATOR; -const ROLE_TABLE = Ci.nsIAccessibleRole.ROLE_TABLE; -const ROLE_INTERNAL_FRAME = Ci.nsIAccessibleRole.ROLE_INTERNAL_FRAME; -const ROLE_PARAGRAPH = Ci.nsIAccessibleRole.ROLE_PARAGRAPH; -const ROLE_SECTION = Ci.nsIAccessibleRole.ROLE_SECTION; -const ROLE_LABEL = Ci.nsIAccessibleRole.ROLE_LABEL; - this.EXPORTED_SYMBOLS = ['TraversalRules']; Cu.import('resource://gre/modules/accessibility/Utils.jsm'); Cu.import('resource://gre/modules/XPCOMUtils.jsm'); +XPCOMUtils.defineLazyModuleGetter(this, 'Roles', + 'resource://gre/modules/accessibility/Constants.jsm'); +XPCOMUtils.defineLazyModuleGetter(this, 'Filters', + 'resource://gre/modules/accessibility/Constants.jsm'); let gSkipEmptyImages = new PrefCache('accessibility.accessfu.skip_empty_images'); function BaseTraversalRule(aRoles, aMatchFunc) { this._explicitMatchRoles = new Set(aRoles); this._matchRoles = aRoles; - if (aRoles.indexOf(ROLE_LABEL) < 0) { - this._matchRoles.push(ROLE_LABEL); + if (aRoles.indexOf(Roles.LABEL) < 0) { + this._matchRoles.push(Roles.LABEL); } - this._matchFunc = aMatchFunc || function (acc) { return FILTER_MATCH; }; + this._matchFunc = aMatchFunc || function (acc) { return Filters.MATCH; }; } BaseTraversalRule.prototype = { @@ -80,20 +43,20 @@ BaseTraversalRule.prototype = { match: function BaseTraversalRule_match(aAccessible) { let role = aAccessible.role; - if (role == ROLE_INTERNAL_FRAME) { + if (role == Roles.INTERNAL_FRAME) { return (Utils.getMessageManager(aAccessible.DOMNode)) ? - FILTER_MATCH | FILTER_IGNORE_SUBTREE : FILTER_IGNORE; + Filters.MATCH | Filters.IGNORE_SUBTREE : Filters.IGNORE; } let matchResult = this._explicitMatchRoles.has(role) ? - this._matchFunc(aAccessible) : FILTER_IGNORE; + this._matchFunc(aAccessible) : Filters.IGNORE; // If we are on a label that nests a checkbox/radio we should land on it. // It is a bigger touch target, and it reduces clutter. - if (role == ROLE_LABEL && !(matchResult & FILTER_IGNORE_SUBTREE)) { + if (role == Roles.LABEL && !(matchResult & Filters.IGNORE_SUBTREE)) { let control = Utils.getEmbeddedControl(aAccessible); if (control && this._explicitMatchRoles.has(control.role)) { - matchResult = this._matchFunc(control) | FILTER_IGNORE_SUBTREE; + matchResult = this._matchFunc(control) | Filters.IGNORE_SUBTREE; } } @@ -104,32 +67,32 @@ BaseTraversalRule.prototype = { }; var gSimpleTraversalRoles = - [ROLE_MENUITEM, - ROLE_LINK, - ROLE_PAGETAB, - ROLE_GRAPHIC, - ROLE_STATICTEXT, - ROLE_TEXT_LEAF, - ROLE_PUSHBUTTON, - ROLE_CHECKBUTTON, - ROLE_RADIOBUTTON, - ROLE_COMBOBOX, - ROLE_PROGRESSBAR, - ROLE_BUTTONDROPDOWN, - ROLE_BUTTONMENU, - ROLE_CHECK_MENU_ITEM, - ROLE_PASSWORD_TEXT, - ROLE_RADIO_MENU_ITEM, - ROLE_TOGGLE_BUTTON, - ROLE_ENTRY, - ROLE_KEY, - ROLE_HEADER, - ROLE_HEADING, - ROLE_SLIDER, - ROLE_SPINBUTTON, - ROLE_OPTION, + [Roles.MENUITEM, + Roles.LINK, + Roles.PAGETAB, + Roles.GRAPHIC, + Roles.STATICTEXT, + Roles.TEXT_LEAF, + Roles.PUSHBUTTON, + Roles.CHECKBUTTON, + Roles.RADIOBUTTON, + Roles.COMBOBOX, + Roles.PROGRESSBAR, + Roles.BUTTONDROPDOWN, + Roles.BUTTONMENU, + Roles.CHECK_MENU_ITEM, + Roles.PASSWORD_TEXT, + Roles.RADIO_MENU_ITEM, + Roles.TOGGLE_BUTTON, + Roles.ENTRY, + Roles.KEY, + Roles.HEADER, + Roles.HEADING, + Roles.SLIDER, + Roles.SPINBUTTON, + Roles.OPTION, // Used for traversing in to child OOP frames. - ROLE_INTERNAL_FRAME]; + Roles.INTERNAL_FRAME]; this.TraversalRules = { Simple: new BaseTraversalRule( @@ -146,47 +109,47 @@ this.TraversalRules = { } switch (aAccessible.role) { - case ROLE_COMBOBOX: + case Roles.COMBOBOX: // We don't want to ignore the subtree because this is often // where the list box hangs out. - return FILTER_MATCH; - case ROLE_TEXT_LEAF: + return Filters.MATCH; + case Roles.TEXT_LEAF: { // Nameless text leaves are boring, skip them. let name = aAccessible.name; if (name && name.trim()) - return FILTER_MATCH; + return Filters.MATCH; else - return FILTER_IGNORE; + return Filters.IGNORE; } - case ROLE_STATICTEXT: + case Roles.STATICTEXT: { let parent = aAccessible.parent; // Ignore prefix static text in list items. They are typically bullets or numbers. if (parent.childCount > 1 && aAccessible.indexInParent == 0 && - parent.role == ROLE_LISTITEM) - return FILTER_IGNORE; + parent.role == Roles.LISTITEM) + return Filters.IGNORE; - return FILTER_MATCH; + return Filters.MATCH; } - case ROLE_GRAPHIC: + case Roles.GRAPHIC: return TraversalRules._shouldSkipImage(aAccessible); - case ROLE_LINK: - case ROLE_HEADER: - case ROLE_HEADING: + case Roles.LINK: + case Roles.HEADER: + case Roles.HEADING: return hasZeroOrSingleChildDescendants() ? - (FILTER_MATCH | FILTER_IGNORE_SUBTREE) : (FILTER_IGNORE); + (Filters.MATCH | Filters.IGNORE_SUBTREE) : (Filters.IGNORE); default: // Ignore the subtree, if there is one. So that we don't land on // the same content that was already presented by its parent. - return FILTER_MATCH | - FILTER_IGNORE_SUBTREE; + return Filters.MATCH | + Filters.IGNORE_SUBTREE; } } ), Anchor: new BaseTraversalRule( - [ROLE_LINK], + [Roles.LINK], function Anchor_match(aAccessible) { // We want to ignore links, only focus named anchors. @@ -194,67 +157,67 @@ this.TraversalRules = { let extraState = {}; aAccessible.getState(state, extraState); if (state.value & Ci.nsIAccessibleStates.STATE_LINKED) { - return FILTER_IGNORE; + return Filters.IGNORE; } else { - return FILTER_MATCH; + return Filters.MATCH; } }), Button: new BaseTraversalRule( - [ROLE_PUSHBUTTON, - ROLE_SPINBUTTON, - ROLE_TOGGLE_BUTTON, - ROLE_BUTTONDROPDOWN, - ROLE_BUTTONDROPDOWNGRID]), + [Roles.PUSHBUTTON, + Roles.SPINBUTTON, + Roles.TOGGLE_BUTTON, + Roles.BUTTONDROPDOWN, + Roles.BUTTONDROPDOWNGRID]), Combobox: new BaseTraversalRule( - [ROLE_COMBOBOX, - ROLE_LISTBOX]), + [Roles.COMBOBOX, + Roles.LISTBOX]), Landmark: new BaseTraversalRule( [], function Landmark_match(aAccessible) { - return Utils.getLandmarkName(aAccessible) ? FILTER_MATCH : - FILTER_IGNORE; + return Utils.getLandmarkName(aAccessible) ? Filters.MATCH : + Filters.IGNORE; } ), Entry: new BaseTraversalRule( - [ROLE_ENTRY, - ROLE_PASSWORD_TEXT]), + [Roles.ENTRY, + Roles.PASSWORD_TEXT]), FormElement: new BaseTraversalRule( - [ROLE_PUSHBUTTON, - ROLE_SPINBUTTON, - ROLE_TOGGLE_BUTTON, - ROLE_BUTTONDROPDOWN, - ROLE_BUTTONDROPDOWNGRID, - ROLE_COMBOBOX, - ROLE_LISTBOX, - ROLE_ENTRY, - ROLE_PASSWORD_TEXT, - ROLE_PAGETAB, - ROLE_RADIOBUTTON, - ROLE_RADIO_MENU_ITEM, - ROLE_SLIDER, - ROLE_CHECKBUTTON, - ROLE_CHECK_MENU_ITEM]), + [Roles.PUSHBUTTON, + Roles.SPINBUTTON, + Roles.TOGGLE_BUTTON, + Roles.BUTTONDROPDOWN, + Roles.BUTTONDROPDOWNGRID, + Roles.COMBOBOX, + Roles.LISTBOX, + Roles.ENTRY, + Roles.PASSWORD_TEXT, + Roles.PAGETAB, + Roles.RADIOBUTTON, + Roles.RADIO_MENU_ITEM, + Roles.SLIDER, + Roles.CHECKBUTTON, + Roles.CHECK_MENU_ITEM]), Graphic: new BaseTraversalRule( - [ROLE_GRAPHIC], + [Roles.GRAPHIC], function Graphic_match(aAccessible) { return TraversalRules._shouldSkipImage(aAccessible); }), Heading: new BaseTraversalRule( - [ROLE_HEADING]), + [Roles.HEADING]), ListItem: new BaseTraversalRule( - [ROLE_LISTITEM, - ROLE_TERM]), + [Roles.LISTITEM, + Roles.TERM]), Link: new BaseTraversalRule( - [ROLE_LINK], + [Roles.LINK], function Link_match(aAccessible) { // We want to ignore anchors, only focus real links. @@ -262,50 +225,50 @@ this.TraversalRules = { let extraState = {}; aAccessible.getState(state, extraState); if (state.value & Ci.nsIAccessibleStates.STATE_LINKED) { - return FILTER_MATCH; + return Filters.MATCH; } else { - return FILTER_IGNORE; + return Filters.IGNORE; } }), List: new BaseTraversalRule( - [ROLE_LIST, - ROLE_DEFINITION_LIST]), + [Roles.LIST, + Roles.DEFINITION_LIST]), PageTab: new BaseTraversalRule( - [ROLE_PAGETAB]), + [Roles.PAGETAB]), Paragraph: new BaseTraversalRule( - [ROLE_PARAGRAPH, - ROLE_SECTION], + [Roles.PARAGRAPH, + Roles.SECTION], function Paragraph_match(aAccessible) { for (let child = aAccessible.firstChild; child; child = child.nextSibling) { - if (child.role === ROLE_TEXT_LEAF) { - return FILTER_MATCH | FILTER_IGNORE_SUBTREE; + if (child.role === Roles.TEXT_LEAF) { + return Filters.MATCH | Filters.IGNORE_SUBTREE; } } - return FILTER_IGNORE; + return Filters.IGNORE; }), RadioButton: new BaseTraversalRule( - [ROLE_RADIOBUTTON, - ROLE_RADIO_MENU_ITEM]), + [Roles.RADIOBUTTON, + Roles.RADIO_MENU_ITEM]), Separator: new BaseTraversalRule( - [ROLE_SEPARATOR]), + [Roles.SEPARATOR]), Table: new BaseTraversalRule( - [ROLE_TABLE]), + [Roles.TABLE]), Checkbox: new BaseTraversalRule( - [ROLE_CHECKBUTTON, - ROLE_CHECK_MENU_ITEM]), + [Roles.CHECKBUTTON, + Roles.CHECK_MENU_ITEM]), _shouldSkipImage: function _shouldSkipImage(aAccessible) { if (gSkipEmptyImages.value && aAccessible.name === '') { - return FILTER_IGNORE; + return Filters.IGNORE; } - return FILTER_MATCH; + return Filters.MATCH; } }; diff --git a/accessible/src/jsat/Utils.jsm b/accessible/src/jsat/Utils.jsm index 38aaf7f2d0b7..48b82631b79a 100644 --- a/accessible/src/jsat/Utils.jsm +++ b/accessible/src/jsat/Utils.jsm @@ -8,19 +8,17 @@ const Cu = Components.utils; const Cc = Components.classes; const Ci = Components.interfaces; -const EVENT_STATE_CHANGE = Ci.nsIAccessibleEvent.EVENT_STATE_CHANGE; - -const ROLE_CELL = Ci.nsIAccessibleRole.ROLE_CELL; -const ROLE_COLUMNHEADER = Ci.nsIAccessibleRole.ROLE_COLUMNHEADER; -const ROLE_ROWHEADER = Ci.nsIAccessibleRole.ROLE_ROWHEADER; - -const RELATION_LABEL_FOR = Ci.nsIAccessibleRelation.RELATION_LABEL_FOR; - Cu.import("resource://gre/modules/XPCOMUtils.jsm"); XPCOMUtils.defineLazyModuleGetter(this, 'Services', 'resource://gre/modules/Services.jsm'); XPCOMUtils.defineLazyModuleGetter(this, 'Rect', 'resource://gre/modules/Geometry.jsm'); +XPCOMUtils.defineLazyModuleGetter(this, 'Roles', + 'resource://gre/modules/accessibility/Constants.jsm'); +XPCOMUtils.defineLazyModuleGetter(this, 'Events', + 'resource://gre/modules/accessibility/Constants.jsm'); +XPCOMUtils.defineLazyModuleGetter(this, 'Relations', + 'resource://gre/modules/accessibility/Constants.jsm'); this.EXPORTED_SYMBOLS = ['Utils', 'Logger', 'PivotContext', 'PrefCache']; @@ -297,7 +295,7 @@ this.Utils = { getEmbeddedControl: function getEmbeddedControl(aLabel) { if (aLabel) { - let relation = aLabel.getRelationByType(RELATION_LABEL_FOR); + let relation = aLabel.getRelationByType(Relations.LABEL_FOR); for (let i = 0; i < relation.targetsCount; i++) { let target = relation.getTarget(i); if (target.parent === aLabel) { @@ -399,7 +397,7 @@ this.Logger = { eventToString: function eventToString(aEvent) { let str = Utils.AccRetrieval.getStringEventType(aEvent.eventType); - if (aEvent.eventType == EVENT_STATE_CHANGE) { + if (aEvent.eventType == Events.STATE_CHANGE) { let event = aEvent.QueryInterface(Ci.nsIAccessibleStateChangeEvent); let stateStrings = event.isExtraState ? Utils.AccRetrieval.getStringStates(0, event.state) : @@ -633,7 +631,7 @@ PivotContext.prototype = { if (!aAccessible) { return null; } - if ([ROLE_CELL, ROLE_COLUMNHEADER, ROLE_ROWHEADER].indexOf( + if ([Roles.CELL, Roles.COLUMNHEADER, Roles.ROWHEADER].indexOf( aAccessible.role) < 0) { return null; } @@ -694,12 +692,12 @@ PivotContext.prototype = { cellInfo.columnHeaders = []; if (cellInfo.columnChanged && cellInfo.current.role !== - ROLE_COLUMNHEADER) { + Roles.COLUMNHEADER) { cellInfo.columnHeaders = [headers for (headers of getHeaders( cellInfo.current.columnHeaderCells))]; } cellInfo.rowHeaders = []; - if (cellInfo.rowChanged && cellInfo.current.role === ROLE_CELL) { + if (cellInfo.rowChanged && cellInfo.current.role === Roles.CELL) { cellInfo.rowHeaders = [headers for (headers of getHeaders( cellInfo.current.rowHeaderCells))]; } diff --git a/accessible/src/jsat/content-script.js b/accessible/src/jsat/content-script.js index 69101a78b84f..cf2354a17ba2 100644 --- a/accessible/src/jsat/content-script.js +++ b/accessible/src/jsat/content-script.js @@ -5,9 +5,6 @@ let Ci = Components.interfaces; let Cu = Components.utils; -const ROLE_ENTRY = Ci.nsIAccessibleRole.ROLE_ENTRY; -const ROLE_INTERNAL_FRAME = Ci.nsIAccessibleRole.ROLE_INTERNAL_FRAME; - const MOVEMENT_GRANULARITY_CHARACTER = 1; const MOVEMENT_GRANULARITY_WORD = 2; const MOVEMENT_GRANULARITY_PARAGRAPH = 8; @@ -25,6 +22,8 @@ XPCOMUtils.defineLazyModuleGetter(this, 'EventManager', 'resource://gre/modules/accessibility/EventManager.jsm'); XPCOMUtils.defineLazyModuleGetter(this, 'ObjectWrapper', 'resource://gre/modules/ObjectWrapper.jsm'); +XPCOMUtils.defineLazyModuleGetter(this, 'Roles', + 'resource://gre/modules/accessibility/Constants.jsm'); Logger.debug('content-script.js'); @@ -137,7 +136,7 @@ function forwardToParent(aMessage) { function forwardToChild(aMessage, aListener, aVCPosition) { let acc = aVCPosition || Utils.getVirtualCursor(content.document).position; - if (!Utils.isAliveAndVisible(acc) || acc.role != ROLE_INTERNAL_FRAME) { + if (!Utils.isAliveAndVisible(acc) || acc.role != Roles.INTERNAL_FRAME) { return false; } @@ -165,7 +164,7 @@ function activateCurrent(aMessage) { Logger.debug('activateCurrent'); function activateAccessible(aAccessible) { if (aMessage.json.activateIfKey && - aAccessible.role != Ci.nsIAccessibleRole.ROLE_KEY) { + aAccessible.role != Roles.KEY) { // Only activate keys, don't do anything on other objects. return; } @@ -219,7 +218,7 @@ function activateCurrent(aMessage) { } let focusedAcc = Utils.AccRetrieval.getAccessibleFor(content.document.activeElement); - if (focusedAcc && focusedAcc.role === ROLE_ENTRY) { + if (focusedAcc && focusedAcc.role === Roles.ENTRY) { moveCaretTo(focusedAcc, aMessage.json.offset); return; } diff --git a/accessible/src/jsat/moz.build b/accessible/src/jsat/moz.build index c271ec3908ce..a7871002320f 100644 --- a/accessible/src/jsat/moz.build +++ b/accessible/src/jsat/moz.build @@ -3,3 +3,16 @@ # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. + +JS_MODULES_PATH = 'modules/accessibility' + +EXTRA_JS_MODULES += [ + 'AccessFu.jsm', + 'Constants.jsm', + 'EventManager.jsm', + 'OutputGenerator.jsm', + 'Presentation.jsm', + 'TouchAdapter.jsm', + 'TraversalRules.jsm', + 'Utils.jsm' +] diff --git a/accessible/src/mac/Makefile.in b/accessible/src/mac/Makefile.in index f90485468414..1f01ece1d8f8 100644 --- a/accessible/src/mac/Makefile.in +++ b/accessible/src/mac/Makefile.in @@ -2,7 +2,6 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -EXPORT_LIBRARY = .. include $(topsrcdir)/config/rules.mk ifneq ($(A11Y_LOG),0) diff --git a/accessible/src/mac/moz.build b/accessible/src/mac/moz.build index 0444daa4f3e0..91a37b16f877 100644 --- a/accessible/src/mac/moz.build +++ b/accessible/src/mac/moz.build @@ -4,8 +4,6 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -MODULE = 'accessibility' - EXPORTS += [ 'mozAccessibleProtocol.h', ] @@ -15,9 +13,7 @@ EXPORTS.mozilla.a11y += [ 'HyperTextAccessibleWrap.h', ] -LIBRARY_NAME = 'accessibility_toolkit_s' - -SOURCES += [ +UNIFIED_SOURCES += [ 'AccessibleWrap.mm', 'DocAccessibleWrap.mm', 'MacUtils.mm', @@ -30,8 +26,6 @@ SOURCES += [ 'RootAccessibleWrap.mm', ] -LIBXUL_LIBRARY = True - LOCAL_INCLUDES += [ '../base', '../generic', @@ -43,3 +37,4 @@ LOCAL_INCLUDES += [ '/widget/xpwidgets', ] +FINAL_LIBRARY = 'xul' diff --git a/accessible/src/mac/mozTextAccessible.mm b/accessible/src/mac/mozTextAccessible.mm index 05d426e7c98f..fcf1d764b71c 100644 --- a/accessible/src/mac/mozTextAccessible.mm +++ b/accessible/src/mac/mozTextAccessible.mm @@ -4,9 +4,8 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "Accessible-inl.h" -#include "AccessibleWrap.h" +#include "HyperTextAccessible-inl.h" #include "TextLeafAccessible.h" -#include "nsIAccessibleTypes.h" #include "nsCocoaUtils.h" #include "nsObjCExceptions.h" @@ -213,10 +212,10 @@ ToNSString(id aValue) #endif return nil; } - + int32_t start = range.location; int32_t end = start + range.length; - nsIntRect bounds = mGeckoTextAccessible->GetTextBounds(start, end); + nsIntRect bounds = mGeckoTextAccessible->TextBounds(start, end); return [NSValue valueWithRect:nsCocoaUtils::GeckoRectToCocoaRect(bounds)]; } @@ -263,21 +262,13 @@ ToNSString(id aValue) if (!stringValue) return; - int32_t start = 0; - int32_t end = 0; - - nsresult rv = mGeckoTextAccessible->GetSelectionBounds(0, &start, &end); - NS_ENSURE_SUCCESS(rv,); - - rv = mGeckoTextAccessible->DeleteText(start, end - start); - NS_ENSURE_SUCCESS(rv,); + int32_t start = 0, end = 0; + mGeckoTextAccessible->SelectionBoundsAt(0, &start, &end); + mGeckoTextAccessible->DeleteText(start, end - start); nsString text; nsCocoaUtils::GetStringForNSString(stringValue, text); - rv = mGeckoTextAccessible->InsertText(text, start); - NS_ENSURE_SUCCESS(rv,); - - return; + mGeckoTextAccessible->InsertText(text, start); } if ([attribute isEqualToString:NSAccessibilitySelectedTextRangeAttribute]) { @@ -285,10 +276,8 @@ ToNSString(id aValue) if (!ToNSRange(value, &range)) return; - nsresult rv = mGeckoTextAccessible->SetSelectionBounds(0, range.location, - range.location + range.length); - NS_ENSURE_SUCCESS(rv,); - + mGeckoTextAccessible->SetSelectionBoundsAt(0, range.location, + range.location + range.length); return; } @@ -374,10 +363,9 @@ ToNSString(id aValue) return @""; nsAutoString text; - nsresult rv = mGeckoTextAccessible-> - GetText(0, nsIAccessibleText::TEXT_OFFSET_END_OF_TEXT, text); - NS_ENSURE_SUCCESS(rv, @""); - + mGeckoTextAccessible->TextSubstring(0, + nsIAccessibleText::TEXT_OFFSET_END_OF_TEXT, + text); return nsCocoaUtils::ToNSString(text); } @@ -398,11 +386,8 @@ ToNSString(id aValue) NS_OBJC_BEGIN_TRY_ABORT_BLOCK_RETURN; if (mGeckoTextAccessible) { - int32_t start, end; - start = end = 0; - nsresult rv = mGeckoTextAccessible->GetSelectionBounds(0, &start, &end); - NS_ENSURE_SUCCESS(rv, 0); - + int32_t start = 0, end = 0; + mGeckoTextAccessible->SelectionBoundsAt(0, &start, &end); return (end - start); } return 0; @@ -415,12 +400,11 @@ ToNSString(id aValue) NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL; if (mGeckoTextAccessible) { - int32_t start, end; - start = end = 0; - mGeckoTextAccessible->GetSelectionBounds(0, &start, &end); + int32_t start = 0, end = 0; + mGeckoTextAccessible->SelectionBoundsAt(0, &start, &end); if (start != end) { nsAutoString selText; - mGeckoTextAccessible->GetText(start, end, selText); + mGeckoTextAccessible->TextSubstring(start, end, selText); return nsCocoaUtils::ToNSString(selText); } } @@ -436,21 +420,14 @@ ToNSString(id aValue) if (mGeckoTextAccessible) { int32_t start = 0; int32_t end = 0; - int32_t count = 0; - - nsresult rv = mGeckoTextAccessible->GetSelectionCount(&count); - NS_ENSURE_SUCCESS(rv, nil); + int32_t count = mGeckoTextAccessible->SelectionCount(); if (count) { - rv = mGeckoTextAccessible->GetSelectionBounds(0, &start, &end); - NS_ENSURE_SUCCESS(rv, nil); - + mGeckoTextAccessible->SelectionBoundsAt(0, &start, &end); return [NSValue valueWithRange:NSMakeRange(start, end - start)]; } - rv = mGeckoTextAccessible->GetCaretOffset(&start); - NS_ENSURE_SUCCESS(rv, nil); - + start = mGeckoTextAccessible->CaretOffset(); return [NSValue valueWithRange:NSMakeRange(start != -1 ? start : 0, 0)]; } return [NSValue valueWithRange:NSMakeRange(0, 0)]; @@ -488,8 +465,8 @@ ToNSString(id aValue) NS_PRECONDITION(mGeckoTextAccessible && range, "no Gecko text accessible or range"); nsAutoString text; - mGeckoTextAccessible->GetText(range->location, - range->location + range->length, text); + mGeckoTextAccessible->TextSubstring(range->location, + range->location + range->length, text); return nsCocoaUtils::ToNSString(text); } diff --git a/accessible/src/other/Makefile.in b/accessible/src/other/Makefile.in index f90485468414..1f01ece1d8f8 100644 --- a/accessible/src/other/Makefile.in +++ b/accessible/src/other/Makefile.in @@ -2,7 +2,6 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -EXPORT_LIBRARY = .. include $(topsrcdir)/config/rules.mk ifneq ($(A11Y_LOG),0) diff --git a/accessible/src/other/moz.build b/accessible/src/other/moz.build index f8b6e15b260d..99d36cd368fd 100644 --- a/accessible/src/other/moz.build +++ b/accessible/src/other/moz.build @@ -4,8 +4,6 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -MODULE = 'accessibility' - EXPORTS.mozilla.a11y += [ 'AccessibleWrap.h', 'HyperTextAccessibleWrap.h', @@ -16,10 +14,6 @@ SOURCES += [ 'Platform.cpp', ] -LIBRARY_NAME = 'accessibility_toolkit_s' - -LIBXUL_LIBRARY = True - LOCAL_INCLUDES += [ '../base', '../generic', @@ -27,3 +21,4 @@ LOCAL_INCLUDES += [ '../xul', ] +FINAL_LIBRARY = 'xul' diff --git a/accessible/src/windows/ia2/ia2AccessibleEditableText.cpp b/accessible/src/windows/ia2/ia2AccessibleEditableText.cpp index b6842a6c6ee0..668f6ff43f1c 100644 --- a/accessible/src/windows/ia2/ia2AccessibleEditableText.cpp +++ b/accessible/src/windows/ia2/ia2AccessibleEditableText.cpp @@ -8,6 +8,7 @@ #include "ia2AccessibleEditableText.h" #include "AccessibleEditableText_i.c" +#include "HyperTextAccessible-inl.h" #include "HyperTextAccessibleWrap.h" #include "nsCOMPtr.h" @@ -26,8 +27,11 @@ ia2AccessibleEditableText::copyText(long aStartOffset, long aEndOffset) if (textAcc->IsDefunct()) return CO_E_OBJNOTCONNECTED; - nsresult rv = textAcc->CopyText(aStartOffset, aEndOffset); - return GetHRESULT(rv); + if (!textAcc->IsValidRange(aStartOffset, aEndOffset)) + return E_INVALIDARG; + + textAcc->CopyText(aStartOffset, aEndOffset); + return S_OK; A11Y_TRYBLOCK_END } @@ -41,8 +45,11 @@ ia2AccessibleEditableText::deleteText(long aStartOffset, long aEndOffset) if (textAcc->IsDefunct()) return CO_E_OBJNOTCONNECTED; - nsresult rv = textAcc->DeleteText(aStartOffset, aEndOffset); - return GetHRESULT(rv); + if (!textAcc->IsValidRange(aStartOffset, aEndOffset)) + return E_INVALIDARG; + + textAcc->DeleteText(aStartOffset, aEndOffset); + return S_OK; A11Y_TRYBLOCK_END } @@ -56,11 +63,14 @@ ia2AccessibleEditableText::insertText(long aOffset, BSTR *aText) if (textAcc->IsDefunct()) return CO_E_OBJNOTCONNECTED; + if (!textAcc->IsValidOffset(aOffset)) + return E_INVALIDARG; + uint32_t length = ::SysStringLen(*aText); nsAutoString text(*aText, length); - nsresult rv = textAcc->InsertText(text, aOffset); - return GetHRESULT(rv); + textAcc->InsertText(text, aOffset); + return S_OK; A11Y_TRYBLOCK_END } @@ -74,8 +84,11 @@ ia2AccessibleEditableText::cutText(long aStartOffset, long aEndOffset) if (textAcc->IsDefunct()) return CO_E_OBJNOTCONNECTED; - nsresult rv = textAcc->CutText(aStartOffset, aEndOffset); - return GetHRESULT(rv); + if (!textAcc->IsValidRange(aStartOffset, aEndOffset)) + return E_INVALIDARG; + + textAcc->CutText(aStartOffset, aEndOffset); + return S_OK; A11Y_TRYBLOCK_END } @@ -89,8 +102,11 @@ ia2AccessibleEditableText::pasteText(long aOffset) if (textAcc->IsDefunct()) return CO_E_OBJNOTCONNECTED; - nsresult rv = textAcc->PasteText(aOffset); - return GetHRESULT(rv); + if (!textAcc->IsValidOffset(aOffset)) + return E_INVALIDARG; + + textAcc->PasteText(aOffset); + return S_OK; A11Y_TRYBLOCK_END } @@ -105,15 +121,16 @@ ia2AccessibleEditableText::replaceText(long aStartOffset, long aEndOffset, if (textAcc->IsDefunct()) return CO_E_OBJNOTCONNECTED; - nsresult rv = textAcc->DeleteText(aStartOffset, aEndOffset); - if (NS_FAILED(rv)) - return GetHRESULT(rv); + if (!textAcc->IsValidRange(aStartOffset, aEndOffset)) + return E_INVALIDARG; + + textAcc->DeleteText(aStartOffset, aEndOffset); uint32_t length = ::SysStringLen(*aText); nsAutoString text(*aText, length); + textAcc->InsertText(text, aStartOffset); - rv = textAcc->InsertText(text, aStartOffset); - return GetHRESULT(rv); + return S_OK; A11Y_TRYBLOCK_END } diff --git a/accessible/src/windows/ia2/ia2AccessibleHypertext.cpp b/accessible/src/windows/ia2/ia2AccessibleHypertext.cpp index 12af891db32a..bf9436621c59 100644 --- a/accessible/src/windows/ia2/ia2AccessibleHypertext.cpp +++ b/accessible/src/windows/ia2/ia2AccessibleHypertext.cpp @@ -30,7 +30,7 @@ ia2AccessibleHypertext::get_nHyperlinks(long* aHyperlinkCount) if (hyperText->IsDefunct()) return CO_E_OBJNOTCONNECTED; - *aHyperlinkCount = hyperText->GetLinkCount(); + *aHyperlinkCount = hyperText->LinkCount(); return S_OK; A11Y_TRYBLOCK_END @@ -51,7 +51,7 @@ ia2AccessibleHypertext::get_hyperlink(long aLinkIndex, if (hyperText->IsDefunct()) return CO_E_OBJNOTCONNECTED; - Accessible* hyperLink = hyperText->GetLinkAt(aLinkIndex); + Accessible* hyperLink = hyperText->LinkAt(aLinkIndex); if (!hyperLink) return E_FAIL; @@ -77,7 +77,7 @@ ia2AccessibleHypertext::get_hyperlinkIndex(long aCharIndex, long* aHyperlinkInde if (hyperAcc->IsDefunct()) return CO_E_OBJNOTCONNECTED; - *aHyperlinkIndex = hyperAcc->GetLinkIndexAtOffset(aCharIndex); + *aHyperlinkIndex = hyperAcc->LinkIndexAtOffset(aCharIndex); return S_OK; A11Y_TRYBLOCK_END diff --git a/accessible/src/windows/ia2/ia2AccessibleText.cpp b/accessible/src/windows/ia2/ia2AccessibleText.cpp index 5d3b8b9347e7..fe5ec3d292d9 100644 --- a/accessible/src/windows/ia2/ia2AccessibleText.cpp +++ b/accessible/src/windows/ia2/ia2AccessibleText.cpp @@ -11,9 +11,7 @@ #include "AccessibleText_i.c" #include "HyperTextAccessibleWrap.h" - -#include "nsIPersistentProperties2.h" -#include "nsIAccessibleTypes.h" +#include "HyperTextAccessible-inl.h" using namespace mozilla::a11y; @@ -28,8 +26,8 @@ ia2AccessibleText::addSelection(long aStartOffset, long aEndOffset) if (textAcc->IsDefunct()) return CO_E_OBJNOTCONNECTED; - nsresult rv = textAcc->AddSelection(aStartOffset, aEndOffset); - return GetHRESULT(rv); + return textAcc->AddToSelection(aStartOffset, aEndOffset) ? + S_OK : E_INVALIDARG; A11Y_TRYBLOCK_END } @@ -52,13 +50,9 @@ ia2AccessibleText::get_attributes(long aOffset, long *aStartOffset, return CO_E_OBJNOTCONNECTED; int32_t startOffset = 0, endOffset = 0; - nsCOMPtr attributes; - nsresult rv = textAcc->GetTextAttributes(true, aOffset, - &startOffset, &endOffset, - getter_AddRefs(attributes)); - if (NS_FAILED(rv)) - return GetHRESULT(rv); - + nsCOMPtr attributes = + textAcc->TextAttributes(true, aOffset, &startOffset, &endOffset); + HRESULT hr = AccessibleWrap::ConvertToIA2Attributes(attributes, aTextAttributes); if (FAILED(hr)) @@ -86,13 +80,8 @@ ia2AccessibleText::get_caretOffset(long *aOffset) if (textAcc->IsDefunct()) return CO_E_OBJNOTCONNECTED; - int32_t offset = 0; - nsresult rv = textAcc->GetCaretOffset(&offset); - if (NS_FAILED(rv)) - return GetHRESULT(rv); - - *aOffset = offset; - return offset != -1 ? S_OK : S_FALSE; + *aOffset = textAcc->CaretOffset(); + return *aOffset != -1 ? S_OK : S_FALSE; A11Y_TRYBLOCK_END } @@ -100,18 +89,14 @@ ia2AccessibleText::get_caretOffset(long *aOffset) STDMETHODIMP ia2AccessibleText::get_characterExtents(long aOffset, enum IA2CoordinateType aCoordType, - long *aX, long *aY, - long *aWidth, long *aHeight) + long* aX, long* aY, + long* aWidth, long* aHeight) { A11Y_TRYBLOCK_BEGIN if (!aX || !aY || !aWidth || !aHeight) return E_INVALIDARG; - - *aX = 0; - *aY = 0; - *aWidth = 0; - *aHeight = 0; + *aX = *aY = *aWidth = *aHeight = 0; HyperTextAccessible* textAcc = static_cast(this); if (textAcc->IsDefunct()) @@ -121,41 +106,31 @@ ia2AccessibleText::get_characterExtents(long aOffset, nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE : nsIAccessibleCoordinateType::COORDTYPE_PARENT_RELATIVE; - int32_t x = 0, y =0, width = 0, height = 0; - nsresult rv = textAcc->GetCharacterExtents (aOffset, &x, &y, &width, &height, - geckoCoordType); - if (NS_FAILED(rv)) - return GetHRESULT(rv); + nsIntRect rect = textAcc->CharBounds(aOffset, geckoCoordType); - *aX = x; - *aY = y; - *aWidth = width; - *aHeight = height; + *aX = rect.x; + *aY = rect.y; + *aWidth = rect.width; + *aHeight = rect.height; return S_OK; A11Y_TRYBLOCK_END } STDMETHODIMP -ia2AccessibleText::get_nSelections(long *aNSelections) +ia2AccessibleText::get_nSelections(long* aNSelections) { A11Y_TRYBLOCK_BEGIN if (!aNSelections) return E_INVALIDARG; - *aNSelections = 0; HyperTextAccessible* textAcc = static_cast(this); if (textAcc->IsDefunct()) return CO_E_OBJNOTCONNECTED; - int32_t selCount = 0; - nsresult rv = textAcc->GetSelectionCount(&selCount); - if (NS_FAILED(rv)) - return GetHRESULT(rv); - - *aNSelections = selCount; + *aNSelections = textAcc->SelectionCount(); return S_OK; A11Y_TRYBLOCK_END @@ -164,13 +139,12 @@ ia2AccessibleText::get_nSelections(long *aNSelections) STDMETHODIMP ia2AccessibleText::get_offsetAtPoint(long aX, long aY, enum IA2CoordinateType aCoordType, - long *aOffset) + long* aOffset) { A11Y_TRYBLOCK_BEGIN if (!aOffset) return E_INVALIDARG; - *aOffset = 0; HyperTextAccessible* textAcc = static_cast(this); @@ -181,38 +155,29 @@ ia2AccessibleText::get_offsetAtPoint(long aX, long aY, nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE : nsIAccessibleCoordinateType::COORDTYPE_PARENT_RELATIVE; - int32_t offset = 0; - nsresult rv = textAcc->GetOffsetAtPoint(aX, aY, geckoCoordType, &offset); - if (NS_FAILED(rv)) - return GetHRESULT(rv); - - *aOffset = offset; - return S_OK; + *aOffset = textAcc->OffsetAtPoint(aX, aY, geckoCoordType); + return *aOffset == -1 ? S_FALSE : S_OK; A11Y_TRYBLOCK_END } STDMETHODIMP -ia2AccessibleText::get_selection(long aSelectionIndex, long *aStartOffset, - long *aEndOffset) +ia2AccessibleText::get_selection(long aSelectionIndex, long* aStartOffset, + long* aEndOffset) { A11Y_TRYBLOCK_BEGIN if (!aStartOffset || !aEndOffset) return E_INVALIDARG; - - *aStartOffset = 0; - *aEndOffset = 0; + *aStartOffset = *aEndOffset = 0; HyperTextAccessible* textAcc = static_cast(this); if (textAcc->IsDefunct()) return CO_E_OBJNOTCONNECTED; int32_t startOffset = 0, endOffset = 0; - nsresult rv = textAcc->GetSelectionBounds(aSelectionIndex, - &startOffset, &endOffset); - if (NS_FAILED(rv)) - return GetHRESULT(rv); + if (!textAcc->SelectionBoundsAt(aSelectionIndex, &startOffset, &endOffset)) + return E_INVALIDARG; *aStartOffset = startOffset; *aEndOffset = endOffset; @@ -222,7 +187,7 @@ ia2AccessibleText::get_selection(long aSelectionIndex, long *aStartOffset, } STDMETHODIMP -ia2AccessibleText::get_text(long aStartOffset, long aEndOffset, BSTR *aText) +ia2AccessibleText::get_text(long aStartOffset, long aEndOffset, BSTR* aText) { A11Y_TRYBLOCK_BEGIN @@ -235,11 +200,11 @@ ia2AccessibleText::get_text(long aStartOffset, long aEndOffset, BSTR *aText) if (textAcc->IsDefunct()) return CO_E_OBJNOTCONNECTED; - nsAutoString text; - nsresult rv = textAcc->GetText(aStartOffset, aEndOffset, text); - if (NS_FAILED(rv)) - return GetHRESULT(rv); + if (!textAcc->IsValidRange(aStartOffset, aEndOffset)) + return E_INVALIDARG; + nsAutoString text; + textAcc->TextSubstring(aStartOffset, aEndOffset, text); if (text.IsEmpty()) return S_FALSE; @@ -252,40 +217,38 @@ ia2AccessibleText::get_text(long aStartOffset, long aEndOffset, BSTR *aText) STDMETHODIMP ia2AccessibleText::get_textBeforeOffset(long aOffset, enum IA2TextBoundaryType aBoundaryType, - long *aStartOffset, long *aEndOffset, - BSTR *aText) + long* aStartOffset, long* aEndOffset, + BSTR* aText) { A11Y_TRYBLOCK_BEGIN if (!aStartOffset || !aEndOffset || !aText) return E_INVALIDARG; - *aStartOffset = 0; - *aEndOffset = 0; + *aStartOffset = *aEndOffset = 0; *aText = nullptr; HyperTextAccessible* textAcc = static_cast(this); if (textAcc->IsDefunct()) return CO_E_OBJNOTCONNECTED; - nsresult rv = NS_OK; + if (textAcc->IsValidOffset(aOffset)) + return E_INVALIDARG; + nsAutoString text; int32_t startOffset = 0, endOffset = 0; if (aBoundaryType == IA2_TEXT_BOUNDARY_ALL) { startOffset = 0; endOffset = textAcc->CharacterCount(); - rv = textAcc->GetText(startOffset, endOffset, text); + textAcc->TextSubstring(startOffset, endOffset, text); } else { AccessibleTextBoundary boundaryType = GetGeckoTextBoundary(aBoundaryType); if (boundaryType == -1) return S_FALSE; - rv = textAcc->GetTextBeforeOffset(aOffset, boundaryType, - &startOffset, &endOffset, text); - } - if (NS_FAILED(rv)) - return GetHRESULT(rv); + textAcc->TextBeforeOffset(aOffset, boundaryType, &startOffset, &endOffset, text); + } *aStartOffset = startOffset; *aEndOffset = endOffset; @@ -302,8 +265,8 @@ ia2AccessibleText::get_textBeforeOffset(long aOffset, STDMETHODIMP ia2AccessibleText::get_textAfterOffset(long aOffset, enum IA2TextBoundaryType aBoundaryType, - long *aStartOffset, long *aEndOffset, - BSTR *aText) + long* aStartOffset, long* aEndOffset, + BSTR* aText) { A11Y_TRYBLOCK_BEGIN @@ -318,25 +281,23 @@ ia2AccessibleText::get_textAfterOffset(long aOffset, if (textAcc->IsDefunct()) return CO_E_OBJNOTCONNECTED; - nsresult rv = NS_OK; + if (textAcc->IsValidOffset(aOffset)) + return E_INVALIDARG; + nsAutoString text; int32_t startOffset = 0, endOffset = 0; if (aBoundaryType == IA2_TEXT_BOUNDARY_ALL) { startOffset = 0; endOffset = textAcc->CharacterCount(); - rv = textAcc->GetText(startOffset, endOffset, text); + textAcc->TextSubstring(startOffset, endOffset, text); } else { AccessibleTextBoundary boundaryType = GetGeckoTextBoundary(aBoundaryType); if (boundaryType == -1) return S_FALSE; - rv = textAcc->GetTextAfterOffset(aOffset, boundaryType, - &startOffset, &endOffset, text); + textAcc->TextAfterOffset(aOffset, boundaryType, &startOffset, &endOffset, text); } - if (NS_FAILED(rv)) - return GetHRESULT(rv); - *aStartOffset = startOffset; *aEndOffset = endOffset; @@ -352,41 +313,37 @@ ia2AccessibleText::get_textAfterOffset(long aOffset, STDMETHODIMP ia2AccessibleText::get_textAtOffset(long aOffset, enum IA2TextBoundaryType aBoundaryType, - long *aStartOffset, long *aEndOffset, - BSTR *aText) + long* aStartOffset, long* aEndOffset, + BSTR* aText) { A11Y_TRYBLOCK_BEGIN if (!aStartOffset || !aEndOffset || !aText) return E_INVALIDARG; - *aStartOffset = 0; - *aEndOffset = 0; + *aStartOffset = *aEndOffset = 0; *aText = nullptr; HyperTextAccessible* textAcc = static_cast(this); if (textAcc->IsDefunct()) return CO_E_OBJNOTCONNECTED; - nsresult rv = NS_OK; + if (textAcc->IsValidOffset(aOffset)) + return E_INVALIDARG; + nsAutoString text; int32_t startOffset = 0, endOffset = 0; - if (aBoundaryType == IA2_TEXT_BOUNDARY_ALL) { startOffset = 0; endOffset = textAcc->CharacterCount(); - rv = textAcc->GetText(startOffset, endOffset, text); + textAcc->TextSubstring(startOffset, endOffset, text); } else { AccessibleTextBoundary boundaryType = GetGeckoTextBoundary(aBoundaryType); if (boundaryType == -1) return S_FALSE; - rv = textAcc->GetTextAtOffset(aOffset, boundaryType, - &startOffset, &endOffset, text); + textAcc->TextAtOffset(aOffset, boundaryType, &startOffset, &endOffset, text); } - if (NS_FAILED(rv)) - return GetHRESULT(rv); - *aStartOffset = startOffset; *aEndOffset = endOffset; @@ -408,8 +365,8 @@ ia2AccessibleText::removeSelection(long aSelectionIndex) if (textAcc->IsDefunct()) return CO_E_OBJNOTCONNECTED; - nsresult rv = textAcc->RemoveSelection(aSelectionIndex); - return GetHRESULT(rv); + return textAcc->RemoveFromSelection(aSelectionIndex) ? + S_OK : E_INVALIDARG; A11Y_TRYBLOCK_END } @@ -423,8 +380,11 @@ ia2AccessibleText::setCaretOffset(long aOffset) if (textAcc->IsDefunct()) return CO_E_OBJNOTCONNECTED; - nsresult rv = textAcc->SetCaretOffset(aOffset); - return GetHRESULT(rv); + if (!textAcc->IsValidOffset(aOffset)) + return E_INVALIDARG; + + textAcc->SetCaretOffset(aOffset); + return S_OK; A11Y_TRYBLOCK_END } @@ -439,21 +399,19 @@ ia2AccessibleText::setSelection(long aSelectionIndex, long aStartOffset, if (textAcc->IsDefunct()) return CO_E_OBJNOTCONNECTED; - nsresult rv = textAcc->SetSelectionBounds(aSelectionIndex, - aStartOffset, aEndOffset); - return GetHRESULT(rv); + return textAcc->SetSelectionBoundsAt(aSelectionIndex, aStartOffset, aEndOffset) ? + S_OK : E_INVALIDARG; A11Y_TRYBLOCK_END } STDMETHODIMP -ia2AccessibleText::get_nCharacters(long *aNCharacters) +ia2AccessibleText::get_nCharacters(long* aNCharacters) { A11Y_TRYBLOCK_BEGIN if (!aNCharacters) return E_INVALIDARG; - *aNCharacters = 0; HyperTextAccessible* textAcc = static_cast(this); @@ -476,8 +434,11 @@ ia2AccessibleText::scrollSubstringTo(long aStartIndex, long aEndIndex, if (textAcc->IsDefunct()) return CO_E_OBJNOTCONNECTED; - nsresult rv = textAcc->ScrollSubstringTo(aStartIndex, aEndIndex, aScrollType); - return GetHRESULT(rv); + if (!textAcc->IsValidRange(aStartIndex, aEndIndex)) + return E_INVALIDARG; + + textAcc->ScrollSubstringTo(aStartIndex, aEndIndex, aScrollType); + return S_OK; A11Y_TRYBLOCK_END } @@ -493,13 +454,16 @@ ia2AccessibleText::scrollSubstringToPoint(long aStartIndex, long aEndIndex, if (textAcc->IsDefunct()) return CO_E_OBJNOTCONNECTED; + if (!textAcc->IsValidRange(aStartIndex, aEndIndex)) + return E_INVALIDARG; + uint32_t geckoCoordType = (aCoordType == IA2_COORDTYPE_SCREEN_RELATIVE) ? nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE : nsIAccessibleCoordinateType::COORDTYPE_PARENT_RELATIVE; - nsresult rv = textAcc->ScrollSubstringToPoint(aStartIndex, aEndIndex, - geckoCoordType, aX, aY); - return GetHRESULT(rv); + textAcc->ScrollSubstringToPoint(aStartIndex, aEndIndex, + geckoCoordType, aX, aY); + return S_OK; A11Y_TRYBLOCK_END } diff --git a/accessible/src/windows/ia2/ia2AccessibleValue.cpp b/accessible/src/windows/ia2/ia2AccessibleValue.cpp index 7634ad9aa0a0..861bf4b4555b 100644 --- a/accessible/src/windows/ia2/ia2AccessibleValue.cpp +++ b/accessible/src/windows/ia2/ia2AccessibleValue.cpp @@ -13,6 +13,8 @@ #include "Accessible-inl.h" #include "IUnknownImpl.h" +#include "mozilla/FloatingPoint.h" + using namespace mozilla::a11y; // IUnknown @@ -55,10 +57,9 @@ ia2AccessibleValue::get_currentValue(VARIANT* aCurrentValue) if (valueAcc->IsDefunct()) return CO_E_OBJNOTCONNECTED; - double currentValue = 0; - nsresult rv = valueAcc->GetCurrentValue(¤tValue); - if (NS_FAILED(rv)) - return GetHRESULT(rv); + double currentValue = valueAcc->CurValue(); + if (IsNaN(currentValue)) + return S_FALSE; aCurrentValue->vt = VT_R8; aCurrentValue->dblVal = currentValue; @@ -79,8 +80,7 @@ ia2AccessibleValue::setCurrentValue(VARIANT aValue) if (aValue.vt != VT_R8) return E_INVALIDARG; - nsresult rv = valueAcc->SetCurrentValue(aValue.dblVal); - return GetHRESULT(rv); + return valueAcc->SetCurValue(aValue.dblVal) ? S_OK : E_FAIL; A11Y_TRYBLOCK_END } @@ -99,10 +99,9 @@ ia2AccessibleValue::get_maximumValue(VARIANT* aMaximumValue) if (valueAcc->IsDefunct()) return CO_E_OBJNOTCONNECTED; - double maximumValue = 0; - nsresult rv = valueAcc->GetMaximumValue(&maximumValue); - if (NS_FAILED(rv)) - return GetHRESULT(rv); + double maximumValue = valueAcc->MaxValue(); + if (IsNaN(maximumValue)) + return S_FALSE; aMaximumValue->vt = VT_R8; aMaximumValue->dblVal = maximumValue; @@ -125,10 +124,9 @@ ia2AccessibleValue::get_minimumValue(VARIANT* aMinimumValue) if (valueAcc->IsDefunct()) return CO_E_OBJNOTCONNECTED; - double minimumValue = 0; - nsresult rv = valueAcc->GetMinimumValue(&minimumValue); - if (NS_FAILED(rv)) - return GetHRESULT(rv); + double minimumValue = valueAcc->MinValue(); + if (IsNaN(minimumValue)) + return S_FALSE; aMinimumValue->vt = VT_R8; aMinimumValue->dblVal = minimumValue; diff --git a/accessible/src/windows/ia2/moz.build b/accessible/src/windows/ia2/moz.build index 66fe70153850..33b68b8fb365 100644 --- a/accessible/src/windows/ia2/moz.build +++ b/accessible/src/windows/ia2/moz.build @@ -4,8 +4,6 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -MODULE = 'accessibility' - EXPORTS += [ 'ia2Accessible.h', 'ia2AccessibleAction.h', @@ -32,8 +30,6 @@ SOURCES += [ 'ia2AccessibleValue.cpp', ] -LIBXUL_LIBRARY = True - LOCAL_INCLUDES += [ '../../base', '../../generic', @@ -43,7 +39,4 @@ LOCAL_INCLUDES += [ '../msaa', ] -LIBRARY_NAME = 'accessibility_toolkit_ia2_s' - -EXPORT_LIBRARY = True - +FINAL_LIBRARY = 'xul' diff --git a/accessible/src/windows/msaa/IUnknownImpl.cpp b/accessible/src/windows/msaa/IUnknownImpl.cpp index f6ae9f6a132c..4a9fa5383b23 100644 --- a/accessible/src/windows/msaa/IUnknownImpl.cpp +++ b/accessible/src/windows/msaa/IUnknownImpl.cpp @@ -23,7 +23,7 @@ GetHRESULT(nsresult aResult) case NS_OK: return S_OK; - case NS_ERROR_INVALID_ARG: case NS_ERROR_INVALID_POINTER: + case NS_ERROR_INVALID_ARG: return E_INVALIDARG; case NS_ERROR_OUT_OF_MEMORY: diff --git a/accessible/src/windows/msaa/IUnknownImpl.h b/accessible/src/windows/msaa/IUnknownImpl.h index 50f0376f5083..619dcb8ae76e 100644 --- a/accessible/src/windows/msaa/IUnknownImpl.h +++ b/accessible/src/windows/msaa/IUnknownImpl.h @@ -9,7 +9,6 @@ #define mozilla_a11y_IUnknownImpl_h_ #include -#undef CreateEvent // thank you windows you're such a helper #include "nsError.h" // Avoid warning C4509 like "nonstandard extension used: diff --git a/accessible/src/windows/msaa/moz.build b/accessible/src/windows/msaa/moz.build index 2d5365df5321..4ef11761c0f2 100644 --- a/accessible/src/windows/msaa/moz.build +++ b/accessible/src/windows/msaa/moz.build @@ -4,8 +4,6 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -MODULE = 'accessibility' - EXPORTS += [ 'IUnknownImpl.h', ] @@ -42,8 +40,6 @@ if CONFIG['MOZ_XUL']: 'XULTreeGridAccessibleWrap.cpp', ] -LIBXUL_LIBRARY = True - LOCAL_INCLUDES += [ '../../../../content/base/src', '../../../../content/events/src', @@ -57,9 +53,6 @@ LOCAL_INCLUDES += [ '../uia', ] -LIBRARY_NAME = 'accessibility_toolkit_msaa_s' - -EXPORT_LIBRARY = True - include('/ipc/chromium/chromium-config.mozbuild') +FINAL_LIBRARY = 'xul' diff --git a/accessible/src/windows/sdn/moz.build b/accessible/src/windows/sdn/moz.build index 4d65d287dffd..1ea1388f2ccb 100644 --- a/accessible/src/windows/sdn/moz.build +++ b/accessible/src/windows/sdn/moz.build @@ -4,16 +4,12 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -MODULE = 'accessibility' - SOURCES += [ 'sdnAccessible.cpp', 'sdnDocAccessible.cpp', 'sdnTextAccessible.cpp', ] -LIBXUL_LIBRARY = True - LOCAL_INCLUDES += [ '../../base', '../../generic', @@ -27,7 +23,4 @@ LOCAL_INCLUDES += [ # macros which conflicts with std::min/max. Suppress the macros: DEFINES['NOMINMAX'] = True -LIBRARY_NAME = 'accessibility_toolkit_sdn_s' - -EXPORT_LIBRARY = True - +FINAL_LIBRARY = 'xul' diff --git a/accessible/src/windows/uia/Makefile.in b/accessible/src/windows/uia/Makefile.in index 393f68a9a045..f45459f78b37 100644 --- a/accessible/src/windows/uia/Makefile.in +++ b/accessible/src/windows/uia/Makefile.in @@ -2,8 +2,6 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -EXPORT_LIBRARY = .. - # The midl generated code include Windows headers which defines min and max # macros which conflicts with std::min/max. Suppress the macros: OS_CXXFLAGS += -DNOMINMAX diff --git a/accessible/src/windows/uia/moz.build b/accessible/src/windows/uia/moz.build index 5d15fb561426..cda2c9a59f77 100644 --- a/accessible/src/windows/uia/moz.build +++ b/accessible/src/windows/uia/moz.build @@ -4,14 +4,10 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -MODULE = 'accessibility' - SOURCES += [ 'uiaRawElmProvider.cpp', ] -LIBXUL_LIBRARY = True - LOCAL_INCLUDES += [ '../../base', '../../generic', @@ -21,5 +17,4 @@ LOCAL_INCLUDES += [ '../msaa', ] -LIBRARY_NAME = 'accessibility_toolkit_uia_s' - +FINAL_LIBRARY = 'xul' diff --git a/accessible/src/xpcom/moz.build b/accessible/src/xpcom/moz.build index b9fb8e31f0c2..3f964b450237 100644 --- a/accessible/src/xpcom/moz.build +++ b/accessible/src/xpcom/moz.build @@ -4,27 +4,25 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -MODULE = 'accessibility' - EXPORTS += [ + 'xpcAccessibleHyperText.h', 'xpcAccessibleSelectable.h', + 'xpcAccessibleValue.h', ] -SOURCES += [ +UNIFIED_SOURCES += [ 'nsAccessibleRelation.cpp', + 'xpcAccessibleHyperText.cpp', 'xpcAccessibleSelectable.cpp', 'xpcAccessibleTable.cpp', 'xpcAccessibleTableCell.cpp', + 'xpcAccessibleValue.cpp', ] GENERATED_SOURCES += [ 'xpcAccEvents.cpp', ] -LIBRARY_NAME = 'accessibility_xpcom_s' - -LIBXUL_LIBRARY = True - LOCAL_INCLUDES += [ '../base', '../generic', @@ -46,3 +44,5 @@ else: LOCAL_INCLUDES += [ '../other', ] + +FINAL_LIBRARY = 'xul' diff --git a/accessible/src/xpcom/xpcAccessibleHyperText.cpp b/accessible/src/xpcom/xpcAccessibleHyperText.cpp new file mode 100644 index 000000000000..3b1e7c22d54f --- /dev/null +++ b/accessible/src/xpcom/xpcAccessibleHyperText.cpp @@ -0,0 +1,507 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "xpcAccessibleHyperText.h" + +#include "HyperTextAccessible-inl.h" + +#include "nsIPersistentProperties2.h" + +using namespace mozilla::a11y; + +//////////////////////////////////////////////////////////////////////////////// +// nsISupports + +nsresult +xpcAccessibleHyperText::QueryInterface(REFNSIID aIID, void** aInstancePtr) +{ + *aInstancePtr = nullptr; + + HyperTextAccessible* text = static_cast(this); + if (!text->IsTextRole()) + return NS_ERROR_NO_INTERFACE; + + if (aIID.Equals(NS_GET_IID(nsIAccessibleText))) + *aInstancePtr = static_cast(text); + else if (aIID.Equals(NS_GET_IID(nsIAccessibleEditableText))) + *aInstancePtr = static_cast(text); + else if (aIID.Equals(NS_GET_IID(nsIAccessibleHyperText))) + *aInstancePtr = static_cast(text); + else + return NS_ERROR_NO_INTERFACE; + + NS_ADDREF(text); + return NS_OK; +} + +//////////////////////////////////////////////////////////////////////////////// +// nsIAccessibleText + +NS_IMETHODIMP +xpcAccessibleHyperText::GetCharacterCount(int32_t* aCharacterCount) +{ + NS_ENSURE_ARG_POINTER(aCharacterCount); + *aCharacterCount = 0; + + HyperTextAccessible* text = static_cast(this); + if (text->IsDefunct()) + return NS_ERROR_FAILURE; + + *aCharacterCount = text->CharacterCount(); + return NS_OK; +} + +NS_IMETHODIMP +xpcAccessibleHyperText::GetText(int32_t aStartOffset, int32_t aEndOffset, + nsAString& aText) +{ + aText.Truncate(); + + HyperTextAccessible* text = static_cast(this); + if (text->IsDefunct()) + return NS_ERROR_FAILURE; + + text->TextSubstring(aStartOffset, aEndOffset, aText); + return NS_OK; +} + +NS_IMETHODIMP +xpcAccessibleHyperText::GetTextBeforeOffset(int32_t aOffset, + AccessibleTextBoundary aBoundaryType, + int32_t* aStartOffset, + int32_t* aEndOffset, + nsAString& aText) +{ + NS_ENSURE_ARG_POINTER(aStartOffset); + NS_ENSURE_ARG_POINTER(aEndOffset); + *aStartOffset = *aEndOffset = 0; + aText.Truncate(); + + HyperTextAccessible* text = static_cast(this); + if (text->IsDefunct()) + return NS_ERROR_FAILURE; + + text->TextBeforeOffset(aOffset, aBoundaryType, aStartOffset, aEndOffset, aText); + return NS_OK; +} + +NS_IMETHODIMP +xpcAccessibleHyperText::GetTextAtOffset(int32_t aOffset, + AccessibleTextBoundary aBoundaryType, + int32_t* aStartOffset, + int32_t* aEndOffset, nsAString& aText) +{ + NS_ENSURE_ARG_POINTER(aStartOffset); + NS_ENSURE_ARG_POINTER(aEndOffset); + *aStartOffset = *aEndOffset = 0; + aText.Truncate(); + + HyperTextAccessible* text = static_cast(this); + if (text->IsDefunct()) + return NS_ERROR_FAILURE; + + text->TextAtOffset(aOffset, aBoundaryType, aStartOffset, aEndOffset, aText); + return NS_OK; +} + +NS_IMETHODIMP +xpcAccessibleHyperText::GetTextAfterOffset(int32_t aOffset, + AccessibleTextBoundary aBoundaryType, + int32_t* aStartOffset, + int32_t* aEndOffset, nsAString& aText) +{ + NS_ENSURE_ARG_POINTER(aStartOffset); + NS_ENSURE_ARG_POINTER(aEndOffset); + *aStartOffset = *aEndOffset = 0; + aText.Truncate(); + + HyperTextAccessible* text = static_cast(this); + if (text->IsDefunct()) + return NS_ERROR_FAILURE; + + text->TextAfterOffset(aOffset, aBoundaryType, aStartOffset, aEndOffset, aText); + return NS_OK; +} + +NS_IMETHODIMP +xpcAccessibleHyperText::GetCharacterAtOffset(int32_t aOffset, + PRUnichar* aCharacter) +{ + NS_ENSURE_ARG_POINTER(aCharacter); + *aCharacter = L'\0'; + + HyperTextAccessible* text = static_cast(this); + if (text->IsDefunct()) + return NS_ERROR_FAILURE; + + nsAutoString character; + if (text->GetCharAt(aOffset, eGetAt, character)) { + *aCharacter = character.First(); + return NS_OK; + } + + return NS_ERROR_INVALID_ARG; +} + +NS_IMETHODIMP +xpcAccessibleHyperText::GetTextAttributes(bool aIncludeDefAttrs, + int32_t aOffset, + int32_t* aStartOffset, + int32_t* aEndOffset, + nsIPersistentProperties** aAttributes) +{ + NS_ENSURE_ARG_POINTER(aStartOffset); + NS_ENSURE_ARG_POINTER(aEndOffset); + NS_ENSURE_ARG_POINTER(aAttributes); + *aStartOffset = *aEndOffset = 0; + *aAttributes = nullptr; + + HyperTextAccessible* text = static_cast(this); + if (text->IsDefunct()) + return NS_ERROR_FAILURE; + + nsCOMPtr attrs = + text->TextAttributes(aIncludeDefAttrs, aOffset, aStartOffset, aEndOffset); + attrs.swap(*aAttributes); + + return NS_OK; +} + +NS_IMETHODIMP +xpcAccessibleHyperText::GetDefaultTextAttributes(nsIPersistentProperties** aAttributes) +{ + NS_ENSURE_ARG_POINTER(aAttributes); + *aAttributes = nullptr; + + HyperTextAccessible* text = static_cast(this); + if (text->IsDefunct()) + return NS_ERROR_FAILURE; + + nsCOMPtr attrs = text->DefaultTextAttributes(); + attrs.swap(*aAttributes); + return NS_OK; +} + +NS_IMETHODIMP +xpcAccessibleHyperText::GetCharacterExtents(int32_t aOffset, + int32_t* aX, int32_t* aY, + int32_t* aWidth, int32_t* aHeight, + uint32_t aCoordType) +{ + NS_ENSURE_ARG_POINTER(aX); + NS_ENSURE_ARG_POINTER(aY); + NS_ENSURE_ARG_POINTER(aWidth); + NS_ENSURE_ARG_POINTER(aHeight); + *aX = *aY = *aWidth = *aHeight; + + HyperTextAccessible* text = static_cast(this); + if (text->IsDefunct()) + return NS_ERROR_FAILURE; + + nsIntRect rect = text->CharBounds(aOffset, aCoordType); + *aX = rect.x; *aY = rect.y; + *aWidth = rect.width; *aHeight = rect.height; + return NS_OK; +} + +NS_IMETHODIMP +xpcAccessibleHyperText::GetRangeExtents(int32_t aStartOffset, int32_t aEndOffset, + int32_t* aX, int32_t* aY, + int32_t* aWidth, int32_t* aHeight, + uint32_t aCoordType) +{ + NS_ENSURE_ARG_POINTER(aX); + NS_ENSURE_ARG_POINTER(aY); + NS_ENSURE_ARG_POINTER(aWidth); + NS_ENSURE_ARG_POINTER(aHeight); + *aX = *aY = *aWidth = *aHeight = 0; + + HyperTextAccessible* text = static_cast(this); + if (text->IsDefunct()) + return NS_ERROR_FAILURE; + + nsIntRect rect = text->TextBounds(aStartOffset, aEndOffset, aCoordType); + *aX = rect.x; *aY = rect.y; + *aWidth = rect.width; *aHeight = rect.height; + return NS_OK; +} + +NS_IMETHODIMP +xpcAccessibleHyperText::GetOffsetAtPoint(int32_t aX, int32_t aY, + uint32_t aCoordType, int32_t* aOffset) +{ + NS_ENSURE_ARG_POINTER(aOffset); + *aOffset = -1; + + HyperTextAccessible* text = static_cast(this); + if (text->IsDefunct()) + return NS_ERROR_FAILURE; + + *aOffset = text->OffsetAtPoint(aX, aY, aCoordType); + return NS_OK; +} + +NS_IMETHODIMP +xpcAccessibleHyperText::GetScriptableCaretOffset(int32_t* aCaretOffset) +{ + NS_ENSURE_ARG_POINTER(aCaretOffset); + *aCaretOffset = -1; + + HyperTextAccessible* text = static_cast(this); + if (text->IsDefunct()) + return NS_ERROR_FAILURE; + + *aCaretOffset = text->CaretOffset(); + return NS_OK; +} + +NS_IMETHODIMP +xpcAccessibleHyperText::SetScriptableCaretOffset(int32_t aCaretOffset) +{ + HyperTextAccessible* text = static_cast(this); + if (text->IsDefunct()) + return NS_ERROR_FAILURE; + + text->SetCaretOffset(aCaretOffset); + return NS_OK; +} + +NS_IMETHODIMP +xpcAccessibleHyperText::GetSelectionCount(int32_t* aSelectionCount) +{ + NS_ENSURE_ARG_POINTER(aSelectionCount); + *aSelectionCount = 0; + + HyperTextAccessible* text = static_cast(this); + if (text->IsDefunct()) + return NS_ERROR_FAILURE; + + *aSelectionCount = text->SelectionCount(); + return NS_OK; +} + +NS_IMETHODIMP +xpcAccessibleHyperText::GetSelectionBounds(int32_t aSelectionNum, + int32_t* aStartOffset, + int32_t* aEndOffset) +{ + NS_ENSURE_ARG_POINTER(aStartOffset); + NS_ENSURE_ARG_POINTER(aEndOffset); + *aStartOffset = *aEndOffset = 0; + + HyperTextAccessible* text = static_cast(this); + if (text->IsDefunct()) + return NS_ERROR_FAILURE; + + if (aSelectionNum < 0 || aSelectionNum >= text->SelectionCount()) + return NS_ERROR_INVALID_ARG; + + text->SelectionBoundsAt(aSelectionNum, aStartOffset, aEndOffset); + return NS_OK; +} + +NS_IMETHODIMP +xpcAccessibleHyperText::SetSelectionBounds(int32_t aSelectionNum, + int32_t aStartOffset, + int32_t aEndOffset) +{ + HyperTextAccessible* text = static_cast(this); + if (text->IsDefunct()) + return NS_ERROR_FAILURE; + + if (aSelectionNum < 0 || + !text->SetSelectionBoundsAt(aSelectionNum, aStartOffset, aEndOffset)) + return NS_ERROR_INVALID_ARG; + + return NS_OK; +} + +NS_IMETHODIMP +xpcAccessibleHyperText::AddSelection(int32_t aStartOffset, int32_t aEndOffset) +{ + HyperTextAccessible* text = static_cast(this); + if (text->IsDefunct()) + return NS_ERROR_FAILURE; + + text->AddToSelection(aStartOffset, aEndOffset); + return NS_OK; +} + +NS_IMETHODIMP +xpcAccessibleHyperText::RemoveSelection(int32_t aSelectionNum) +{ + HyperTextAccessible* text = static_cast(this); + if (text->IsDefunct()) + return NS_ERROR_FAILURE; + + text->RemoveFromSelection(aSelectionNum); + return NS_OK; +} + +NS_IMETHODIMP +xpcAccessibleHyperText::ScriptableScrollSubstringTo(int32_t aStartOffset, + int32_t aEndOffset, + uint32_t aScrollType) +{ + HyperTextAccessible* text = static_cast(this); + if (text->IsDefunct()) + return NS_ERROR_FAILURE; + + text->ScrollSubstringTo(aStartOffset, aEndOffset, aScrollType); + return NS_OK; +} + +NS_IMETHODIMP +xpcAccessibleHyperText::ScriptableScrollSubstringToPoint(int32_t aStartOffset, + int32_t aEndOffset, + uint32_t aCoordinateType, + int32_t aX, int32_t aY) +{ + HyperTextAccessible* text = static_cast(this); + if (text->IsDefunct()) + return NS_ERROR_FAILURE; + + text->ScrollSubstringToPoint(aStartOffset, aEndOffset, aCoordinateType, aX, aY); + return NS_OK; +} + +//////////////////////////////////////////////////////////////////////////////// +// nsIAccessibleEditableText + +NS_IMETHODIMP +xpcAccessibleHyperText::SetTextContents(const nsAString& aText) +{ + HyperTextAccessible* text = static_cast(this); + if (text->IsDefunct()) + return NS_ERROR_FAILURE; + + text->ReplaceText(aText); + return NS_OK; +} + +NS_IMETHODIMP +xpcAccessibleHyperText::ScriptableInsertText(const nsAString& aText, + int32_t aOffset) +{ + HyperTextAccessible* text = static_cast(this); + if (text->IsDefunct()) + return NS_ERROR_FAILURE; + + text->InsertText(aText, aOffset); + return NS_OK; +} + +NS_IMETHODIMP +xpcAccessibleHyperText::ScriptableCopyText(int32_t aStartOffset, + int32_t aEndOffset) +{ + HyperTextAccessible* text = static_cast(this); + if (text->IsDefunct()) + return NS_ERROR_FAILURE; + + text->CopyText(aStartOffset, aEndOffset); + return NS_OK; +} + +NS_IMETHODIMP +xpcAccessibleHyperText::ScriptableCutText(int32_t aStartOffset, + int32_t aEndOffset) +{ + HyperTextAccessible* text = static_cast(this); + if (text->IsDefunct()) + return NS_ERROR_FAILURE; + + text->CutText(aStartOffset, aEndOffset); + return NS_OK; +} + +NS_IMETHODIMP +xpcAccessibleHyperText::ScriptableDeleteText(int32_t aStartOffset, + int32_t aEndOffset) +{ + HyperTextAccessible* text = static_cast(this); + if (text->IsDefunct()) + return NS_ERROR_FAILURE; + + text->DeleteText(aStartOffset, aEndOffset); + return NS_OK; +} + +NS_IMETHODIMP +xpcAccessibleHyperText::ScriptablePasteText(int32_t aOffset) +{ + HyperTextAccessible* text = static_cast(this); + if (text->IsDefunct()) + return NS_ERROR_FAILURE; + + text->PasteText(aOffset); + return NS_OK; +} + +//////////////////////////////////////////////////////////////////////////////// +// nsIAccessibleHyperText + +NS_IMETHODIMP +xpcAccessibleHyperText::GetLinkCount(int32_t* aLinkCount) +{ + NS_ENSURE_ARG_POINTER(aLinkCount); + *aLinkCount = 0; + + HyperTextAccessible* text = static_cast(this); + if (text->IsDefunct()) + return NS_ERROR_FAILURE; + + *aLinkCount = text->LinkCount(); + return NS_OK; +} + +NS_IMETHODIMP +xpcAccessibleHyperText::GetLinkAt(int32_t aIndex, nsIAccessibleHyperLink** aLink) +{ + NS_ENSURE_ARG_POINTER(aLink); + *aLink = nullptr; + + HyperTextAccessible* text = static_cast(this); + if (text->IsDefunct()) + return NS_ERROR_FAILURE; + + nsCOMPtr link = text->LinkAt(aIndex); + link.forget(aLink); + + return NS_OK; +} + +NS_IMETHODIMP +xpcAccessibleHyperText::GetLinkIndex(nsIAccessibleHyperLink* aLink, + int32_t* aIndex) +{ + NS_ENSURE_ARG_POINTER(aLink); + NS_ENSURE_ARG_POINTER(aIndex); + *aIndex = -1; + + HyperTextAccessible* text = static_cast(this); + if (text->IsDefunct()) + return NS_ERROR_FAILURE; + + nsRefPtr link(do_QueryObject(aLink)); + *aIndex = text->LinkIndexOf(link); + return NS_OK; +} + +NS_IMETHODIMP +xpcAccessibleHyperText::GetLinkIndexAtOffset(int32_t aOffset, + int32_t* aLinkIndex) +{ + NS_ENSURE_ARG_POINTER(aLinkIndex); + *aLinkIndex = -1; // API says this magic value means 'not found' + + HyperTextAccessible* text = static_cast(this); + if (text->IsDefunct()) + return NS_ERROR_FAILURE; + + *aLinkIndex = text->LinkIndexAtOffset(aOffset); + return NS_OK; +} diff --git a/accessible/src/xpcom/xpcAccessibleHyperText.h b/accessible/src/xpcom/xpcAccessibleHyperText.h new file mode 100644 index 000000000000..6e03aa5482f7 --- /dev/null +++ b/accessible/src/xpcom/xpcAccessibleHyperText.h @@ -0,0 +1,39 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef mozilla_a11y_xpcAccessibleHyperText_h_ +#define mozilla_a11y_xpcAccessibleHyperText_h_ + +#include "nsIAccessibleText.h" +#include "nsIAccessibleHyperText.h" +#include "nsIAccessibleEditableText.h" + +namespace mozilla { +namespace a11y { + +class xpcAccessibleHyperText : public nsIAccessibleText, + public nsIAccessibleEditableText, + public nsIAccessibleHyperText +{ +public: + NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr); + + NS_DECL_NSIACCESSIBLETEXT + NS_DECL_NSIACCESSIBLEHYPERTEXT + NS_DECL_NSIACCESSIBLEEDITABLETEXT + +private: + xpcAccessibleHyperText() { } + friend class HyperTextAccessible; + + xpcAccessibleHyperText(const xpcAccessibleHyperText&) MOZ_DELETE; + xpcAccessibleHyperText& operator =(const xpcAccessibleHyperText&) MOZ_DELETE; +}; + +} // namespace a11y +} // namespace mozilla + +#endif // mozilla_a11y_xpcAccessibleHyperText_h_ diff --git a/accessible/src/xpcom/xpcAccessibleValue.cpp b/accessible/src/xpcom/xpcAccessibleValue.cpp new file mode 100644 index 000000000000..89caa28dcf04 --- /dev/null +++ b/accessible/src/xpcom/xpcAccessibleValue.cpp @@ -0,0 +1,90 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "xpcAccessibleValue.h" +#include "Accessible.h" + +using namespace mozilla; +using namespace mozilla::a11y; + +NS_IMETHODIMP +xpcAccessibleValue::GetMaximumValue(double* aValue) +{ + NS_ENSURE_ARG_POINTER(aValue); + *aValue = 0; + + Accessible* acc = static_cast(this); + if (acc->IsDefunct()) + return NS_ERROR_FAILURE; + + double value = acc->MaxValue(); + if (!IsNaN(value)) + *aValue = value; + + return NS_OK; +} + +NS_IMETHODIMP +xpcAccessibleValue::GetMinimumValue(double* aValue) +{ + NS_ENSURE_ARG_POINTER(aValue); + *aValue = 0; + + Accessible* acc = static_cast(this); + if (acc->IsDefunct()) + return NS_ERROR_FAILURE; + + double value = acc->MinValue(); + if (!IsNaN(value)) + *aValue = value; + + return NS_OK; +} + +NS_IMETHODIMP +xpcAccessibleValue::GetCurrentValue(double* aValue) +{ + NS_ENSURE_ARG_POINTER(aValue); + *aValue = 0; + + Accessible* acc = static_cast(this); + if (acc->IsDefunct()) + return NS_ERROR_FAILURE; + + double value = acc->CurValue(); + if (!IsNaN(value)) + *aValue = value; + + return NS_OK; +} + +NS_IMETHODIMP +xpcAccessibleValue::SetCurrentValue(double aValue) +{ + Accessible* acc = static_cast(this); + if (acc->IsDefunct()) + return NS_ERROR_FAILURE; + + acc->SetCurValue(aValue); + return NS_OK; +} + +NS_IMETHODIMP +xpcAccessibleValue::GetMinimumIncrement(double* aValue) +{ + NS_ENSURE_ARG_POINTER(aValue); + *aValue = 0; + + Accessible* acc = static_cast(this); + if (acc->IsDefunct()) + return NS_ERROR_FAILURE; + + double value = acc->Step(); + if (!IsNaN(value)) + *aValue = value; + + return NS_OK; +} diff --git a/accessible/src/xpcom/xpcAccessibleValue.h b/accessible/src/xpcom/xpcAccessibleValue.h new file mode 100644 index 000000000000..0110d4edacfb --- /dev/null +++ b/accessible/src/xpcom/xpcAccessibleValue.h @@ -0,0 +1,35 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef mozilla_a11y_xpcAccessibleValue_h_ +#define mozilla_a11y_xpcAccessibleValue_h_ + +#include "nsIAccessibleValue.h" + +namespace mozilla { +namespace a11y { + +class xpcAccessibleValue : public nsIAccessibleValue +{ +public: + NS_IMETHOD GetMaximumValue(double* aValue) MOZ_FINAL MOZ_OVERRIDE; + NS_IMETHOD GetMinimumValue(double* aValue) MOZ_FINAL MOZ_OVERRIDE; + NS_IMETHOD GetCurrentValue(double* aValue) MOZ_FINAL MOZ_OVERRIDE; + NS_IMETHOD SetCurrentValue(double aValue) MOZ_FINAL MOZ_OVERRIDE; + NS_IMETHOD GetMinimumIncrement(double* aMinIncrement) MOZ_FINAL MOZ_OVERRIDE; + +private: + xpcAccessibleValue() { } + friend class Accessible; + + xpcAccessibleValue(const xpcAccessibleValue&) MOZ_DELETE; + xpcAccessibleValue& operator =(const xpcAccessibleValue&) MOZ_DELETE; +}; + +} // namespace a11y +} // namespace mozilla + +#endif diff --git a/accessible/src/xul/XULFormControlAccessible.cpp b/accessible/src/xul/XULFormControlAccessible.cpp index befb3ffb4727..2064b469631d 100644 --- a/accessible/src/xul/XULFormControlAccessible.cpp +++ b/accessible/src/xul/XULFormControlAccessible.cpp @@ -811,7 +811,7 @@ XULTextFieldAccessible::CacheChildren() // XULTextFieldAccessible: HyperTextAccessible protected already_AddRefed -XULTextFieldAccessible::FrameSelection() +XULTextFieldAccessible::FrameSelection() const { nsCOMPtr inputContent(GetInputField()); NS_ASSERTION(inputContent, "No input content"); diff --git a/accessible/src/xul/XULFormControlAccessible.h b/accessible/src/xul/XULFormControlAccessible.h index 3d7dbd7b46d2..a2e1d9f7705e 100644 --- a/accessible/src/xul/XULFormControlAccessible.h +++ b/accessible/src/xul/XULFormControlAccessible.h @@ -250,7 +250,7 @@ protected: virtual void CacheChildren(); // HyperTextAccessible - virtual already_AddRefed FrameSelection(); + virtual already_AddRefed FrameSelection() const; // nsXULTextFieldAccessible already_AddRefed GetInputField() const; diff --git a/accessible/src/xul/XULSliderAccessible.cpp b/accessible/src/xul/XULSliderAccessible.cpp index ec8f1028bb96..ba1f052343e0 100644 --- a/accessible/src/xul/XULSliderAccessible.cpp +++ b/accessible/src/xul/XULSliderAccessible.cpp @@ -11,6 +11,7 @@ #include "nsIFrame.h" #include "mozilla/dom/Element.h" +#include "mozilla/FloatingPoint.h" using namespace mozilla::a11y; @@ -25,12 +26,6 @@ XULSliderAccessible:: mStateFlags |= eHasNumericValue; } -// nsISupports - -NS_IMPL_ISUPPORTS_INHERITED1(XULSliderAccessible, - AccessibleWrap, - nsIAccessibleValue) - // Accessible role @@ -99,64 +94,39 @@ XULSliderAccessible::DoAction(uint8_t aIndex) return NS_OK; } -// nsIAccessibleValue - -NS_IMETHODIMP -XULSliderAccessible::GetMaximumValue(double* aValue) +double +XULSliderAccessible::MaxValue() const { - nsresult rv = AccessibleWrap::GetMaximumValue(aValue); - - // ARIA redefined maximum value. - if (rv != NS_OK_NO_ARIA_VALUE) - return rv; - - return GetSliderAttr(nsGkAtoms::maxpos, aValue); + double value = AccessibleWrap::MaxValue(); + return IsNaN(value) ? GetSliderAttr(nsGkAtoms::maxpos) : value; } -NS_IMETHODIMP -XULSliderAccessible::GetMinimumValue(double* aValue) +double +XULSliderAccessible::MinValue() const { - nsresult rv = AccessibleWrap::GetMinimumValue(aValue); - - // ARIA redefined minmum value. - if (rv != NS_OK_NO_ARIA_VALUE) - return rv; - - return GetSliderAttr(nsGkAtoms::minpos, aValue); + double value = AccessibleWrap::MinValue(); + return IsNaN(value) ? GetSliderAttr(nsGkAtoms::minpos) : value; } -NS_IMETHODIMP -XULSliderAccessible::GetMinimumIncrement(double* aValue) +double +XULSliderAccessible::Step() const { - nsresult rv = AccessibleWrap::GetMinimumIncrement(aValue); - - // ARIA redefined minimum increment value. - if (rv != NS_OK_NO_ARIA_VALUE) - return rv; - - return GetSliderAttr(nsGkAtoms::increment, aValue); + double value = AccessibleWrap::Step(); + return IsNaN(value) ? GetSliderAttr(nsGkAtoms::increment) : value; } -NS_IMETHODIMP -XULSliderAccessible::GetCurrentValue(double* aValue) +double +XULSliderAccessible::CurValue() const { - nsresult rv = AccessibleWrap::GetCurrentValue(aValue); - - // ARIA redefined current value. - if (rv != NS_OK_NO_ARIA_VALUE) - return rv; - - return GetSliderAttr(nsGkAtoms::curpos, aValue); + double value = AccessibleWrap::CurValue(); + return IsNaN(value) ? GetSliderAttr(nsGkAtoms::curpos) : value; } -NS_IMETHODIMP -XULSliderAccessible::SetCurrentValue(double aValue) +bool +XULSliderAccessible::SetCurValue(double aValue) { - nsresult rv = AccessibleWrap::SetCurrentValue(aValue); - - // ARIA redefined current value. - if (rv != NS_OK_NO_ARIA_VALUE) - return rv; + if (AccessibleWrap::SetCurValue(aValue)) + return true; return SetSliderAttr(nsGkAtoms::curpos, aValue); } @@ -184,7 +154,7 @@ XULSliderAccessible::GetSliderElement() const } nsresult -XULSliderAccessible::GetSliderAttr(nsIAtom* aName, nsAString& aValue) +XULSliderAccessible::GetSliderAttr(nsIAtom* aName, nsAString& aValue) const { aValue.Truncate(); @@ -211,35 +181,26 @@ XULSliderAccessible::SetSliderAttr(nsIAtom* aName, const nsAString& aValue) return NS_OK; } -nsresult -XULSliderAccessible::GetSliderAttr(nsIAtom* aName, double* aValue) +double +XULSliderAccessible::GetSliderAttr(nsIAtom* aName) const { - NS_ENSURE_ARG_POINTER(aValue); - *aValue = 0; - nsAutoString attrValue; nsresult rv = GetSliderAttr(aName, attrValue); - NS_ENSURE_SUCCESS(rv, rv); - - // Return zero value if there is no attribute or its value is empty. - if (attrValue.IsEmpty()) - return NS_OK; + if (NS_FAILED(rv)) + return UnspecifiedNaN(); nsresult error = NS_OK; double value = attrValue.ToDouble(&error); - if (NS_SUCCEEDED(error)) - *aValue = value; - - return NS_OK; + return NS_FAILED(error) ? UnspecifiedNaN() : value; } -nsresult +bool XULSliderAccessible::SetSliderAttr(nsIAtom* aName, double aValue) { nsAutoString value; value.AppendFloat(aValue); - return SetSliderAttr(aName, value); + return NS_SUCCEEDED(SetSliderAttr(aName, value)); } diff --git a/accessible/src/xul/XULSliderAccessible.h b/accessible/src/xul/XULSliderAccessible.h index 36e74486813f..3d23a7b55b1a 100644 --- a/accessible/src/xul/XULSliderAccessible.h +++ b/accessible/src/xul/XULSliderAccessible.h @@ -21,16 +21,10 @@ class XULSliderAccessible : public AccessibleWrap public: XULSliderAccessible(nsIContent* aContent, DocAccessible* aDoc); - // nsISupports - NS_DECL_ISUPPORTS_INHERITED - // nsIAccessible NS_IMETHOD GetActionName(uint8_t aIndex, nsAString& aName); NS_IMETHOD DoAction(uint8_t aIndex); - // nsIAccessibleValue - NS_DECL_NSIACCESSIBLEVALUE - // Accessible virtual void Value(nsString& aValue); virtual a11y::role NativeRole(); @@ -38,6 +32,13 @@ public: virtual bool NativelyUnavailable() const; virtual bool CanHaveAnonChildren(); + // Value + virtual double MaxValue() const MOZ_OVERRIDE; + virtual double MinValue() const MOZ_OVERRIDE; + virtual double CurValue() const MOZ_OVERRIDE; + virtual double Step() const MOZ_OVERRIDE; + virtual bool SetCurValue(double aValue) MOZ_OVERRIDE; + // ActionAccessible virtual uint8_t ActionCount(); @@ -47,11 +48,11 @@ protected: */ nsIContent* GetSliderElement() const; - nsresult GetSliderAttr(nsIAtom *aName, nsAString& aValue); + nsresult GetSliderAttr(nsIAtom *aName, nsAString& aValue) const; nsresult SetSliderAttr(nsIAtom *aName, const nsAString& aValue); - nsresult GetSliderAttr(nsIAtom *aName, double *aValue); - nsresult SetSliderAttr(nsIAtom *aName, double aValue); + double GetSliderAttr(nsIAtom *aName) const; + bool SetSliderAttr(nsIAtom *aName, double aValue); private: mutable nsCOMPtr mSliderNode; diff --git a/accessible/src/xul/moz.build b/accessible/src/xul/moz.build index 323404d5a955..6584b0b55c8b 100644 --- a/accessible/src/xul/moz.build +++ b/accessible/src/xul/moz.build @@ -4,9 +4,7 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -MODULE = 'accessibility' - -SOURCES += [ +UNIFIED_SOURCES += [ 'XULAlertAccessible.cpp', 'XULColorPickerAccessible.cpp', 'XULComboboxAccessible.cpp', @@ -21,10 +19,6 @@ SOURCES += [ 'XULTreeGridAccessible.cpp', ] -LIBRARY_NAME = 'accessibility_xul_s' - -LIBXUL_LIBRARY = True - LOCAL_INCLUDES += [ '../../../layout/generic', '../../../layout/xul/base/src', @@ -52,3 +46,5 @@ else: LOCAL_INCLUDES += [ '../other', ] + +FINAL_LIBRARY = 'xul' diff --git a/accessible/tests/mochitest/events.js b/accessible/tests/mochitest/events.js index 2676a8187826..525d56d6631d 100644 --- a/accessible/tests/mochitest/events.js +++ b/accessible/tests/mochitest/events.js @@ -1959,7 +1959,12 @@ var gA11yEventObserver = var type = eventTypeToString(event.eventType); var info = "Event type: " + type; - if (event instanceof nsIAccessibleTextChangeEvent) { + if (event instanceof nsIAccessibleStateChangeEvent) { + var stateStr = statesToString(event.isExtraState ? 0 : event.state, + event.isExtraState ? event.state : 0); + info += ", state: " + stateStr + ", is enabled: " + event.isEnabled; + + } else if (event instanceof nsIAccessibleTextChangeEvent) { info += ", start: " + event.start + ", length: " + event.length + ", " + (event.isInserted ? "inserted" : "removed") + " text: " + event.modifiedText; diff --git a/accessible/tests/mochitest/events/test_statechange.html b/accessible/tests/mochitest/events/test_statechange.html index d877f6dd4b86..f4557376b548 100644 --- a/accessible/tests/mochitest/events/test_statechange.html +++ b/accessible/tests/mochitest/events/test_statechange.html @@ -143,18 +143,46 @@ new stateChangeChecker(aState, aIsExtraState, true, getNode(aID)) ]; - this.invoke = function dupeStateChange_invoke() + this.invoke = function oppositeStateChange_invoke() { getNode(aID).setAttribute(aAttr, "false"); getNode(aID).setAttribute(aAttr, "true"); } - this.getID = function dupeStateChange_getID() + this.getID = function oppositeStateChange_getID() { return "opposite state change events"; } } + /** + * Change concomitant ARIA and native attribute at once. + */ + function echoingStateChange(aID, aARIAAttr, aAttr, aValue, + aState, aIsExtraState, aIsEnabled) + { + this.eventSeq = [ + new stateChangeChecker(aState, aIsExtraState, aIsEnabled, getNode(aID)) + ]; + + this.invoke = function echoingStateChange_invoke() + { + if (aValue == null) { + getNode(aID).removeAttribute(aARIAAttr); + getNode(aID).removeAttribute(aAttr); + + } else { + getNode(aID).setAttribute(aARIAAttr, aValue); + getNode(aID).setAttribute(aAttr, aValue); + } + } + + this.getID = function echoingStateChange_getID() + { + return "enchoing ARIA and native attributes change"; + } + } + //////////////////////////////////////////////////////////////////////////// // Do tests @@ -193,6 +221,11 @@ gQueue.push(new oppositeStateChange("div", "aria-busy", STATE_BUSY, false)); + gQueue.push(new echoingStateChange("text1", "aria-disabled", "disabled", "true", + EXT_STATE_ENABLED, true, false)); + gQueue.push(new echoingStateChange("text1", "aria-disabled", "disabled", null, + EXT_STATE_ENABLED, true, true)); + gQueue.invoke(); // Will call SimpleTest.finish(); } @@ -223,6 +256,11 @@ title="Fire statechange event whenever checked state is changed not depending on focused state"> Bug 788389 + + Bug 926812 +

@@ -242,6 +280,8 @@
+ +
diff --git a/accessible/tests/mochitest/jsat/jsatcommon.js b/accessible/tests/mochitest/jsat/jsatcommon.js index 640989252b64..7331da10dcca 100644 --- a/accessible/tests/mochitest/jsat/jsatcommon.js +++ b/accessible/tests/mochitest/jsat/jsatcommon.js @@ -92,6 +92,7 @@ var AccessFuTest = { finish: function AccessFuTest_finish() { // Disable the console service logging. Logger.test = false; + Logger.logLevel = Logger.INFO; AccessFu.doneCallback = function doneCallback() { // This is being called once AccessFu has been shut down. // Detach AccessFu from everything it attached itself to. @@ -136,6 +137,7 @@ var AccessFuTest = { AccessFu.readyCallback = function readyCallback() { // Enable logging to the console service. Logger.test = true; + Logger.logLevel = Logger.DEBUG; // This is being called once accessibility has been turned on. if (AccessFuTest._waitForExplicitFinish) { diff --git a/accessible/tests/mochitest/text.js b/accessible/tests/mochitest/text.js index 09d34ca2cca2..081a188a2caf 100644 --- a/accessible/tests/mochitest/text.js +++ b/accessible/tests/mochitest/text.js @@ -415,7 +415,7 @@ function testTextSetSelection(aID, aStartOffset, aEndOffset, var text = acc.getText(0, -1); acc.setSelectionBounds(aSelectionIndex, aStartOffset, aEndOffset); - + is(acc.selectionCount, aSelectionsCount, text + ": failed to set selection at index '" + aSelectionIndex + "': selectionCount after"); diff --git a/accessible/tests/mochitest/value/test_progress.html b/accessible/tests/mochitest/value/test_progress.html index cdccbdc3f526..b99cce14c7ea 100644 --- a/accessible/tests/mochitest/value/test_progress.html +++ b/accessible/tests/mochitest/value/test_progress.html @@ -21,7 +21,7 @@ function doTest() { // HTML5 progress element tests - testValue("pr_indeterminate", "0%", 0, 0, 1, 0); + testValue("pr_indeterminate", "", 0, 0, 1, 0); testValue("pr_zero", "0%", 0, 0, 1, 0); testValue("pr_zeropointfive", "50%", 0.5, 0, 1, 0); testValue("pr_one", "100%", 1, 0, 1, 0); diff --git a/accessible/tests/mochitest/value/test_progress.xul b/accessible/tests/mochitest/value/test_progress.xul index a9aa8a6823ba..5ae4a358f7fc 100644 --- a/accessible/tests/mochitest/value/test_progress.xul +++ b/accessible/tests/mochitest/value/test_progress.xul @@ -21,7 +21,7 @@ // progressmeter testValue("pm1", "50%", 50, 0, 100, 0); testValue("pm2", "50%", 500, 0, 1000, 0); - testValue("pm3", "0%", 0, 0, 100, 0); + testValue("pm3", "", 0, 0, 100, 0); // scale testValue("sc1", "500", 500, 0, 1000, 10); diff --git a/accessible/tests/moz.build b/accessible/tests/moz.build index c86ff643d491..a6669fdeae50 100644 --- a/accessible/tests/moz.build +++ b/accessible/tests/moz.build @@ -6,5 +6,3 @@ DIRS += ['mochitest'] -MODULE = 'test_accessibility' - diff --git a/b2g/app/b2g.js b/b2g/app/b2g.js index 6d69bf5a1c7b..f7a4b69e1dab 100644 --- a/b2g/app/b2g.js +++ b/b2g/app/b2g.js @@ -42,6 +42,12 @@ pref("network.protocol-handler.warn-external.tel", false); pref("network.protocol-handler.warn-external.mailto", false); pref("network.protocol-handler.warn-external.vnd.youtube", false); +/* protocol expose prefs */ +// By default, all protocol handlers are exposed. This means that the browser +// will response to openURL commands for all URL types. It will also try to open +// link clicks inside the browser before failing over to the system handlers. +pref("network.protocol-handler.expose.rtsp", false); + /* http prefs */ pref("network.http.pipelining", true); pref("network.http.pipelining.ssl", true); diff --git a/b2g/app/ua-update.json.in b/b2g/app/ua-update.json.in index e8b6ad6e7aaf..54978442fcc5 100644 --- a/b2g/app/ua-update.json.in +++ b/b2g/app/ua-update.json.in @@ -3,16 +3,12 @@ // Send these sites a custom user-agent. Bugs to remove each override after // evangelism are included. { - // bug 826330, uol.com.br - "uol.com.br": "Mozilla/5.0 (Linux; Android 4.0.4; Galaxy Nexus Build/IMM76B) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.133 Mobile Safari/535.19", // bug 826335, globo.com "globo.com": "\\(Mobile#(Android; Mobile", // bug 826338, yahoo.com "yahoo.com": "\\(Mobile#(Android; Mobile", // bug 826342, mercadolivre.com.br "mercadolivre.com.br": "\\(Mobile#(Android; Mobile", - // bug 826343, ig.com.br - "ig.com.br": "\\(Mobile#(Android; Mobile", // bug 826344, abril.com.br "abril.com.br": "\\(Mobile#(Android; Mobile", // bug 826347, msn.com @@ -61,8 +57,6 @@ "webmotors.com.br": "\\(Mobile#(Android; Mobile", // bug 827661, mercadolibre.com.co "mercadolibre.com.co": "\\(Mobile#(Android; Mobile", - // bug 827664, elespectador.com - "elespectador.com": "\\(Mobile#(Android; Mobile", // bug 827668, scribd.com "scribd.com": "\\(Mobile#(Android; Mobile", // bug 827670, elpais.com.co @@ -99,8 +93,6 @@ "fotocasa.es": "\\(Mobile#(Android; Mobile", // bug 828406, orange.es "orange.es": "\\(Mobile#(Android; Mobile", - // bug 828414, paginasamarillas.es - "paginasamarillas.es": "\\(Mobile#(Android; Mobile", // bug 828416, loteriasyapuestas.es "loteriasyapuestas.es": "\\(Mobile#(Android; Mobile", // bug 828418, bbva.es @@ -149,8 +141,6 @@ "games.com": "\\(Mobile#(Android; Mobile", // bug 843156, orbitz.com "orbitz.com": "\\(Mobile#(Android; Mobile", - // bug 843158, starwoodhotels.com - "starwoodhotels.com": "\\(Mobile#(Android; Mobile", // bug 843160, ehow.com "ehow.com": "\\(Mobile#(Android; Mobile", // bug 843162, urbanspoon.com @@ -169,8 +159,6 @@ "slashgear.com": "\\(Mobile#(Android; Mobile", // bug 843186, chevrolet.com "chevrolet.com": "\\(Mobile#(Android; Mobile", - // bug 848854, deadline.com - "deadline.com": "\\(Mobile#(Android; Mobile", // bug 866577, 3g.qq.com "3g.qq.com": "\\(Mobile#(Android; Mobile", // bug 878222, arukereso.hu @@ -219,8 +207,6 @@ "naslovi.net": "\\(Mobile#(Android; Mobile", // bug 878284, softonic.com "softonic.com": "\\(Mobile#(Android; Mobile", - // bug 878286, yandex.ru - "yandex.ru": "\\(Mobile#(Android; Mobile", // bug 878630, ask.com "ask.com": "\\(Mobile#(Android; Mobile", // bug 878632, banorte.com diff --git a/b2g/chrome/content/payment.js b/b2g/chrome/content/payment.js index a08ae41300d1..ba1b43b8d858 100644 --- a/b2g/chrome/content/payment.js +++ b/b2g/chrome/content/payment.js @@ -191,21 +191,22 @@ let PaymentProvider = { }, #ifdef MOZ_B2G_RIL - // Until bug 814629 is done, we only have support for a single SIM, so we - // can only provide information for a single ICC. However, we return an array - // so the payment provider facing API won't need to change once we support - // multiple SIMs. + // Bug 938993. Support Multi-SIM for Payments. + get iccInfo() { + delete this.iccInfo; + return this.iccInfo = iccProvider.getIccInfo(0); + }, get iccIds() { - return [iccProvider.iccInfo.iccid]; + return [this.iccInfo.iccid]; }, get mcc() { - return [iccProvider.iccInfo.mcc]; + return [this.iccInfo.mcc]; }, get mnc() { - return [iccProvider.iccInfo.mnc]; + return [this.iccInfo.mnc]; }, _silentNumbers: null, diff --git a/b2g/components/moz.build b/b2g/components/moz.build index d4286f2a1ce8..a0ed6421f002 100644 --- a/b2g/components/moz.build +++ b/b2g/components/moz.build @@ -6,8 +6,6 @@ TEST_DIRS += ['test'] -MODULE = 'B2GComponents' - EXTRA_COMPONENTS += [ 'ActivitiesGlue.js', 'AlertsService.js', diff --git a/b2g/components/test/moz.build b/b2g/components/test/moz.build index 99d23a409214..191c90f0b92d 100644 --- a/b2g/components/test/moz.build +++ b/b2g/components/test/moz.build @@ -4,9 +4,4 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -MODULE = 'B2GComponents' - XPCSHELL_TESTS_MANIFESTS += ['unit/xpcshell.ini'] - -FAIL_ON_WARNINGS = True - diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index 86df0ab382be..f456db391c04 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -1,4 +1,4 @@ { - "revision": "2e7106da13e91ea119801a50a39c9e7ebb1d912e", + "revision": "32c72fb8d857627ed39e4e07e1a4efaa1d3caace", "repo_path": "/integration/gaia-central" } diff --git a/browser/app/profile/firefox.js b/browser/app/profile/firefox.js index ce22d2eb1e81..446a06b85b7d 100644 --- a/browser/app/profile/firefox.js +++ b/browser/app/profile/firefox.js @@ -659,9 +659,18 @@ pref("plugins.update.notifyUser", false); pref("plugins.click_to_play", true); -// let all plugins except Flash default to click-to-play +#ifdef RELEASE_BUILD +// For now, plugins other than Java and Flash are enabled in beta/release +// and click-to-activate in earlier channels. +pref("plugin.default.state", 2); +#else pref("plugin.default.state", 1); +#endif + +// Flash is enabled by default, and Java is click-to-activate by default on +// all channels. pref("plugin.state.flash", 2); +pref("plugin.state.java", 1); // display door hanger if flash not installed pref("plugins.notifyMissingFlash", true); @@ -1227,14 +1236,6 @@ pref("devtools.hud.loglimit.console", 200); pref("devtools.editor.tabsize", 4); pref("devtools.editor.expandtab", true); -// Tells which component you want to use for source editing in developer tools. -// -// Available components: -// "orion" - this is the Orion source code editor from the Eclipse project. It -// provides programmer-specific editor features such as syntax highlighting, -// indenting and bracket recognition. -pref("devtools.editor.component", "orion"); - // Enable the Font Inspector pref("devtools.fontinspector.enabled", true); diff --git a/browser/base/content/aboutDialog.js b/browser/base/content/aboutDialog.js index ea8350cbbb8b..a35b3ebcaaed 100644 --- a/browser/base/content/aboutDialog.js +++ b/browser/base/content/aboutDialog.js @@ -21,17 +21,22 @@ function init(aEvent) distroIdField.value = distroId + " - " + distroVersion; distroIdField.style.display = "block"; - // This must be set last because it might not exist due to bug 895473. - var distroAbout = Services.prefs.getComplexValue("distribution.about", - Components.interfaces.nsISupportsString); - var distroField = document.getElementById("distribution"); - distroField.value = distroAbout; - distroField.style.display = "block"; + try { + // This is in its own try catch due to bug 895473 and bug 900925. + var distroAbout = Services.prefs.getComplexValue("distribution.about", + Components.interfaces.nsISupportsString); + var distroField = document.getElementById("distribution"); + distroField.value = distroAbout; + distroField.style.display = "block"; + } + catch (ex) { + // Pref is unset + Components.utils.reportError(ex); + } } } catch (e) { // Pref is unset - Components.utils.reportError(e); } // Include the build ID and display warning if this is an "a#" (nightly or aurora) build diff --git a/browser/base/content/abouthealthreport/abouthealth.js b/browser/base/content/abouthealthreport/abouthealth.js index 84c054bca44b..1475ce3599ed 100644 --- a/browser/base/content/abouthealthreport/abouthealth.js +++ b/browser/base/content/abouthealthreport/abouthealth.js @@ -24,6 +24,11 @@ const prefs = new Preferences("datareporting.healthreport."); let healthReportWrapper = { init: function () { + if (!reporter) { + healthReportWrapper.handleInitFailure(); + return; + } + reporter.onInit().then(healthReportWrapper.refreshPayload, healthReportWrapper.handleInitFailure); diff --git a/browser/base/content/browser-gestureSupport.js b/browser/base/content/browser-gestureSupport.js index 1cc1b236c395..36d79f7f2b02 100644 --- a/browser/base/content/browser-gestureSupport.js +++ b/browser/base/content/browser-gestureSupport.js @@ -659,6 +659,7 @@ let gHistorySwipeAnimation = { */ stopAnimation: function HSA_stopAnimation() { gHistorySwipeAnimation._removeBoxes(); + this._historyIndex = gBrowser.webNavigation.sessionHistory.index; }, /** @@ -724,23 +725,27 @@ let gHistorySwipeAnimation = { * An event to process. */ handleEvent: function HSA_handleEvent(aEvent) { + let browser = gBrowser.selectedBrowser; switch (aEvent.type) { case "TabClose": - let browser = gBrowser.getBrowserForTab(aEvent.target); - this._removeTrackedSnapshot(-1, browser); + let browserForTab = gBrowser.getBrowserForTab(aEvent.target); + this._removeTrackedSnapshot(-1, browserForTab); break; case "DOMModalDialogClosed": this.stopAnimation(); break; case "pageshow": + if (aEvent.target == browser.contentDocument) { + this.stopAnimation(); + } + break; case "popstate": - if (aEvent.target != gBrowser.selectedBrowser.contentDocument) - break; - this.stopAnimation(); - this._historyIndex = gBrowser.webNavigation.sessionHistory.index; + if (aEvent.target == browser.contentDocument.defaultView) { + this.stopAnimation(); + } break; case "pagehide": - if (aEvent.target == gBrowser.selectedBrowser.contentDocument) { + if (aEvent.target == browser.contentDocument) { // Take and compress a snapshot of a page whenever it's about to be // navigated away from. We already have a snapshot of the page if an // animation is running, so we're left with compressing it. diff --git a/browser/base/content/browser-plugins.js b/browser/base/content/browser-plugins.js index 1e398c163300..e4ca961d6ca2 100644 --- a/browser/base/content/browser-plugins.js +++ b/browser/base/content/browser-plugins.js @@ -963,6 +963,9 @@ var gPluginHandler = { return; } + Services.telemetry.getHistogramById("PLUGINS_INFOBAR_SHOWN"). + add(true); + let message; // Icons set directly cannot be manipulated using moz-image-region, so // we use CSS classes instead. @@ -1001,21 +1004,26 @@ var gPluginHandler = { } } - // These strings are temporary no-string-change for branch uplift let buttons = [ { - label: gNavigatorBundle.getString("pluginBlockNow.label"), - accessKey: gNavigatorBundle.getString("pluginBlockNow.accesskey"), + label: gNavigatorBundle.getString("pluginContinueBlocking.label"), + accessKey: gNavigatorBundle.getString("pluginContinueBlocking.accesskey"), callback: function() { + Services.telemetry.getHistogramById("PLUGINS_INFOBAR_BLOCK"). + add(true); + Services.perms.addFromPrincipal(aBrowser.contentDocument.nodePrincipal, "plugin-hidden-notification", Services.perms.DENY_ACTION); } }, { - label: gNavigatorBundle.getString("offlineApps.allow"), - accessKey: gNavigatorBundle.getString("offlineApps.allowAccessKey"), + label: gNavigatorBundle.getString("pluginActivateTrigger.label"), + accessKey: gNavigatorBundle.getString("pluginActivateTrigger.accesskey"), callback: function() { + Services.telemetry.getHistogramById("PLUGINS_INFOBAR_ALLOW"). + add(true); + let curNotification = PopupNotifications.getNotification("click-to-play-plugins", aBrowser); diff --git a/browser/base/content/browser.css b/browser/base/content/browser.css index f361d5889a43..fad2b682ee7f 100644 --- a/browser/base/content/browser.css +++ b/browser/base/content/browser.css @@ -119,6 +119,19 @@ tabbrowser { max-width 230ms ease-out; } +.tab-background { + /* Explicitly set the visibility to override the value (collapsed) + * we inherit from #TabsToolbar[collapsed] upon opening a browser window. */ + visibility: visible; + /* This transition is only applied when opening a new tab. Closing tabs + * are just hidden so we don't need to adjust the delay for that. */ + transition: visibility 0ms 25ms; +} + +.tab-background[selected]:not([fadein]):not([pinned]) { + visibility: hidden; +} + .tab-throbber:not([fadein]):not([pinned]), .tab-label:not([fadein]):not([pinned]), .tab-icon-image:not([fadein]):not([pinned]), @@ -185,6 +198,36 @@ toolbar[customizing] > .overflow-button { #titlebar-fullscreen-button { -moz-appearance: -moz-mac-fullscreen-button; } + +/* Because these buttons don't move, they should always be aligned the same, + * left and right were deprecated, so we have to do work to get it to mean that: */ +#titlebar-buttonbox-container:-moz-locale-dir(ltr) { + -moz-box-align: start; +} + +#titlebar-buttonbox-container:-moz-locale-dir(rtl) { + -moz-box-align: end; +} + +/* Fullscreen and caption buttons don't move with RTL on OS X so override the automatic ordering. */ +#titlebar-fullscreen-button:-moz-locale-dir(ltr), +#titlebar-buttonbox-container:-moz-locale-dir(rtl), +.titlebar-placeholder[type="fullscreen-button"]:-moz-locale-dir(ltr), +.titlebar-placeholder[type="caption-buttons"]:-moz-locale-dir(rtl) { + -moz-box-ordinal-group: 1000; +} + +#titlebar-fullscreen-button:-moz-locale-dir(rtl), +#titlebar-buttonbox-container:-moz-locale-dir(ltr), +.titlebar-placeholder[type="caption-buttons"]:-moz-locale-dir(ltr), +.titlebar-placeholder[type="fullscreen-button"]:-moz-locale-dir(rtl) { + -moz-box-ordinal-group: 0; +} +%else +/* On non-OSX, these should be start-aligned */ +#titlebar-buttonbox-container { + -moz-box-align: start; +} %endif %ifdef XP_WIN diff --git a/browser/base/content/browser.js b/browser/base/content/browser.js index fac713990e39..45ef66e8e754 100644 --- a/browser/base/content/browser.js +++ b/browser/base/content/browser.js @@ -6338,14 +6338,21 @@ var gIdentityHandler = { let nsIWebProgressListener = Ci.nsIWebProgressListener; // For some URIs like data: we can't get a host and so can't do - // anything useful here. Chrome URIs however get special treatment. + // anything useful here. let unknown = false; try { uri.host; } catch (e) { unknown = true; } - if ((uri.scheme == "chrome" || uri.scheme == "about") && - uri.spec !== "about:blank") { + // Chrome URIs however get special treatment. Some chrome URIs are + // whitelisted to provide a positive security signal to the user. + let chromeWhitelist = ["about:addons", "about:app-manager", "about:config", + "about:crashes", "about:healthreport", "about:home", + "about:newaddon", "about:permissions", "about:preferences", + "about:privatebrowsing", "about:sessionstore", + "about:support", "about:welcomeback"]; + let lowercaseSpec = uri.spec.toLowerCase(); + if (chromeWhitelist.some(function(whitelistedSpec) lowercaseSpec.startsWith(whitelistedSpec))) { this.setMode(this.IDENTITY_MODE_CHROMEUI); } else if (unknown) { this.setMode(this.IDENTITY_MODE_UNKNOWN); diff --git a/browser/base/content/browser.xul b/browser/base/content/browser.xul index 3303293bae86..4c8ece0a491d 100644 --- a/browser/base/content/browser.xul +++ b/browser/base/content/browser.xul @@ -423,11 +423,7 @@ - + @@ -435,7 +431,7 @@ #ifdef XP_MACOSX - + #endif diff --git a/browser/base/content/pageinfo/pageInfo.js b/browser/base/content/pageinfo/pageInfo.js index f3ba788a8c1b..4999a17b29a6 100644 --- a/browser/base/content/pageinfo/pageInfo.js +++ b/browser/base/content/pageinfo/pageInfo.js @@ -475,8 +475,7 @@ function openCacheEntry(key, cb) }, onCacheEntryAvailable: function(entry, isNew, appCache, status) { cb(entry); - }, - get mainThreadOnly() { return true; } + } }; diskStorage.asyncOpenURI(Services.io.newURI(key, null, null), "", nsICacheStorage.OPEN_READONLY, checkCacheListener); } diff --git a/browser/base/content/tabbrowser.xml b/browser/base/content/tabbrowser.xml index 98735de61cbe..40d1233bd3fc 100644 --- a/browser/base/content/tabbrowser.xml +++ b/browser/base/content/tabbrowser.xml @@ -4643,7 +4643,7 @@ - diff --git a/browser/base/content/test/general/browser.ini b/browser/base/content/test/general/browser.ini index ee6064992930..56f451e49366 100644 --- a/browser/base/content/test/general/browser.ini +++ b/browser/base/content/test/general/browser.ini @@ -10,6 +10,13 @@ support-files = blockPluginHard.xml blockPluginVulnerableNoUpdate.xml blockPluginVulnerableUpdatable.xml + browser_bug479408_sample.html + browser_bug678392-1.html + browser_bug678392-2.html + browser_clearplugindata.html + browser_clearplugindata_noage.html + browser_registerProtocolHandler_notification.html + browser_tab_dragdrop2_frame1.xul bug564387.html bug564387_video1.ogv bug564387_video1.ogv^headers^ @@ -107,6 +114,8 @@ run-if = crashreporter [browser_aboutSyncProgress.js] [browser_addKeywordSearch.js] [browser_alltabslistener.js] +[browser_backButtonFitts.js] +skip-if = os != "win" # The Fitts Law back button is only supported on Windows (bug 571454) [browser_blob-channelname.js] [browser_bookmark_titles.js] skip-if = toolkit == "windows" # Disabled on Windows due to frequent failures (bugs 825739, 841341) @@ -141,7 +150,6 @@ skip-if = toolkit == "cocoa" [browser_bug462673.js] [browser_bug477014.js] [browser_bug479408.js] -[browser_bug479408_sample.html] [browser_bug481560.js] [browser_bug484315.js] [browser_bug491431.js] @@ -194,8 +202,6 @@ run-if = toolkit == "cocoa" [browser_bug655584.js] [browser_bug664672.js] [browser_bug676619.js] -[browser_bug678392-1.html] -[browser_bug678392-2.html] [browser_bug678392.js] [browser_bug710878.js] [browser_bug719271.js] @@ -227,9 +233,7 @@ run-if = toolkit == "cocoa" [browser_bug902156.js] [browser_bug906190.js] [browser_canonizeURL.js] -[browser_clearplugindata.html] [browser_clearplugindata.js] -[browser_clearplugindata_noage.html] [browser_contentAreaClick.js] [browser_contextSearchTabPosition.js] [browser_ctrlTab.js] @@ -296,10 +300,8 @@ skip-if = true # disabled until the tree view is added [browser_tab_drag_drop_perwindow.js] [browser_tab_dragdrop.js] [browser_tab_dragdrop2.js] -[browser_tab_dragdrop2_frame1.xul] [browser_tabbar_big_widgets.js] skip-if = os == "linux" # No tabs in titlebar on linux - [browser_tabfocus.js] [browser_tabopen_reflows.js] [browser_tabs_isActive.js] @@ -325,5 +327,4 @@ skip-if = os == "linux" # No tabs in titlebar on linux [browser_wyciwyg_urlbarCopying.js] [browser_zbug569342.js] [browser_registerProtocolHandler_notification.js] -[browser_registerProtocolHandler_notification.html] [browser_no_mcb_on_http_site.js] diff --git a/browser/base/content/test/general/browser_backButtonFitts.js b/browser/base/content/test/general/browser_backButtonFitts.js new file mode 100644 index 000000000000..2b4eab637b2c --- /dev/null +++ b/browser/base/content/test/general/browser_backButtonFitts.js @@ -0,0 +1,30 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +function test () { + waitForExplicitFinish(); + var firstLocation = "http://example.org/browser/browser/base/content/test/general/dummy_page.html"; + gBrowser.selectedTab = gBrowser.addTab(firstLocation); + gBrowser.selectedBrowser.addEventListener("pageshow", function onPageShow1() { + gBrowser.selectedBrowser.removeEventListener("pageshow", onPageShow1); + gBrowser.selectedBrowser.contentWindow.history.pushState("page2", "page2", "page2"); + window.maximize(); + + // Find where the nav-bar is vertically. + var navBar = document.getElementById("nav-bar"); + var boundingRect = navBar.getBoundingClientRect(); + var yPixel = boundingRect.top + Math.floor(boundingRect.height / 2); + var xPixel = 0; // Use the first pixel of the screen since it is maximized. + + gBrowser.selectedBrowser.contentWindow.addEventListener("popstate", function onPopState() { + gBrowser.selectedBrowser.contentWindow.removeEventListener("popstate", onPopState); + is(gBrowser.selectedBrowser.contentDocument.location.href, firstLocation, + "Clicking the first pixel should have navigated back."); + window.restore(); + gBrowser.removeCurrentTab(); + finish(); + }); + EventUtils.synthesizeMouseAtPoint(xPixel, yPixel, {}, window); + }); +} diff --git a/browser/base/content/test/general/browser_bug590206.js b/browser/base/content/test/general/browser_bug590206.js index c661053bface..077e9f01880a 100644 --- a/browser/base/content/test/general/browser_bug590206.js +++ b/browser/base/content/test/general/browser_bug590206.js @@ -61,14 +61,16 @@ function test_blank() { function test_chrome() { let oldTab = gBrowser.selectedTab; + // Since users aren't likely to type in full chrome URLs, we won't show + // the positive security indicator on it, but we will show it on about:addons. loadNewTab("chrome://mozapps/content/extensions/extensions.xul", function(aNewTab) { - is(getIdentityMode(), "chromeUI", "Identity should be chrome"); + is(getIdentityMode(), "unknownIdentity", "Identity should be unknown"); gBrowser.selectedTab = oldTab; is(getIdentityMode(), "unknownIdentity", "Identity should be unknown"); gBrowser.selectedTab = aNewTab; - is(getIdentityMode(), "chromeUI", "Identity should be chrome"); + is(getIdentityMode(), "unknownIdentity", "Identity should be unknown"); gBrowser.removeTab(aNewTab); diff --git a/browser/base/content/test/general/browser_save_private_link_perwindowpb.js b/browser/base/content/test/general/browser_save_private_link_perwindowpb.js index c5ae3ee93629..893256beb31a 100644 --- a/browser/base/content/test/general/browser_save_private_link_perwindowpb.js +++ b/browser/base/content/test/general/browser_save_private_link_perwindowpb.js @@ -107,8 +107,6 @@ function test() { aWindow.gBrowser.contentWindow); }); }); - - aWindow.gBrowser.selectedBrowser.loadURI(testURI); } function testOnWindow(aOptions, aCallback) { diff --git a/browser/components/about/moz.build b/browser/components/about/moz.build index 30a425a22e65..21f0551fa2c2 100644 --- a/browser/components/about/moz.build +++ b/browser/components/about/moz.build @@ -4,8 +4,6 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -MODULE = 'browserabout' - EXPORTS.mozilla.browser += [ 'AboutRedirector.h', ] @@ -14,6 +12,4 @@ SOURCES += [ 'AboutRedirector.cpp', ] -LIBRARY_NAME = 'browserabout_s' - -FORCE_STATIC_LIB = True +FINAL_LIBRARY = 'browsercomps' diff --git a/browser/components/build/Makefile.in b/browser/components/build/Makefile.in index 4282704b36f1..8bfe19e0d924 100644 --- a/browser/components/build/Makefile.in +++ b/browser/components/build/Makefile.in @@ -2,10 +2,6 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -SHORT_LIBNAME = brwsrcmp -MODULE_NAME = nsBrowserCompsModule -FORCE_SHARED_LIB = 1 - ifeq ($(OS_ARCH),WINNT) OS_LIBS += $(call EXPAND_LIBNAME,ole32 shell32 shlwapi) endif @@ -21,19 +17,8 @@ ifeq ($(OS_ARCH),WINNT) OS_LIBS += $(call EXPAND_LIBNAME,version) endif -SHARED_LIBRARY_LIBS = \ - ../feeds/src/$(LIB_PREFIX)browser_feeds_s.$(LIB_SUFFIX) \ - ../about/$(LIB_PREFIX)browserabout_s.$(LIB_SUFFIX) \ - ../dirprovider/$(LIB_PREFIX)browserdir_s.$(LIB_SUFFIX) \ - $(NULL) - -ifneq (,$(filter windows cocoa gtk2 gtk3, $(MOZ_WIDGET_TOOLKIT))) -SHARED_LIBRARY_LIBS += ../shell/src/$(LIB_PREFIX)shellservice_s.$(LIB_SUFFIX) -endif - EXTRA_DSO_LDOPTS += \ - $(call EXPAND_LIBNAME_PATH,unicharutil_external_s,$(LIBXUL_DIST)/lib) \ - $(XPCOM_STATICRUNTIME_GLUE_LDOPTS) \ + $(XPCOM_GLUE_LDOPTS) \ $(MOZ_COMPONENT_LIBS) \ $(NULL) @@ -42,7 +27,6 @@ EXTRA_DSO_LDOPTS += $(MOZ_JS_LIBS) endif LOCAL_INCLUDES += -I$(srcdir)/../migration/src -SHARED_LIBRARY_LIBS += ../migration/src/$(LIB_PREFIX)migration_s.$(LIB_SUFFIX) # Mac: Need to link with CoreFoundation for Mac Migrators (PList reading code) # GTK2: Need to link with glib for GNOME shell service diff --git a/browser/components/build/moz.build b/browser/components/build/moz.build index 554fdb0f8101..549783a04a3d 100644 --- a/browser/components/build/moz.build +++ b/browser/components/build/moz.build @@ -4,8 +4,6 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -MODULE = 'browsercomps' - EXPORTS += [ 'nsBrowserCompsCID.h', ] @@ -18,3 +16,4 @@ LIBRARY_NAME = 'browsercomps' IS_COMPONENT = True +FORCE_SHARED_LIB = True diff --git a/browser/components/customizableui/src/CustomizableUI.jsm b/browser/components/customizableui/src/CustomizableUI.jsm index c2cc976fd544..2685e8527d56 100644 --- a/browser/components/customizableui/src/CustomizableUI.jsm +++ b/browser/components/customizableui/src/CustomizableUI.jsm @@ -359,6 +359,12 @@ let CustomizableUIInternal = { this.beginBatchUpdate(); + // Restore nav-bar visibility since it may have been hidden + // through a migration path (bug 938980) or an add-on. + if (aArea == CustomizableUI.AREA_NAVBAR) { + aAreaNode.collapsed = false; + } + let currentNode = container.firstChild; let placementsToRemove = new Set(); for (let id of aPlacements) { @@ -861,24 +867,27 @@ let CustomizableUIInternal = { if (node) { let parent = node.parentNode; while (parent && !(parent.customizationTarget || - parent.localName == "toolbarpaletteitem")) { + parent == aWindow.gNavToolbox.palette)) { parent = parent.parentNode; } - if (parent && ((parent.customizationTarget == node.parentNode && - gBuildWindows.get(aWindow).has(parent.toolbox)) || - parent.localName == "toolbarpaletteitem")) { - // Normalize the removable attribute. For backwards compat, if - // the widget is not defined in a toolbox palette then absence - // of the "removable" attribute means it is not removable. - if (!node.hasAttribute("removable")) { - parent = parent.localName == "toolbarpaletteitem" ? parent.parentNode : parent; - // If we first see this in customization mode, it may be in the - // customization palette instead of the toolbox palette. - node.setAttribute("removable", !parent.customizationTarget); + if (parent) { + let nodeInArea = node.parentNode.localName == "toolbarpaletteitem" ? + node.parentNode : node; + // Check if we're in a customization target, or in the palette: + if ((parent.customizationTarget == nodeInArea.parentNode && + gBuildWindows.get(aWindow).has(parent.toolbox)) || + aWindow.gNavToolbox.palette == nodeInArea.parentNode) { + // Normalize the removable attribute. For backwards compat, if + // the widget is not located in a toolbox palette then absence + // of the "removable" attribute means it is not removable. + if (!node.hasAttribute("removable")) { + // If we first see this in customization mode, it may be in the + // customization palette instead of the toolbox palette. + node.setAttribute("removable", !parent.customizationTarget); + } + return node; } - - return node; } } @@ -890,8 +899,8 @@ let CustomizableUIInternal = { let node = toolbox.palette.querySelector(idToSelector(aId)); if (node) { // Normalize the removable attribute. For backwards compat, this - // is optional if the widget is defined in the toolbox palette, - // and defaults to *true*, unlike if it was defined elsewhere. + // is optional if the widget is located in the toolbox palette, + // and defaults to *true*, unlike if it was located elsewhere. if (!node.hasAttribute("removable")) { node.setAttribute("removable", true); } @@ -1078,19 +1087,23 @@ let CustomizableUIInternal = { /* * If people put things in the panel which need more than single-click interaction, * we don't want to close it. Right now we check for text inputs and menu buttons. - * Anything else we should take care of? + * We also check for being outside of any toolbaritem/toolbarbutton, ie on a blank + * part of the menu. */ _isOnInteractiveElement: function(aEvent) { let target = aEvent.originalTarget; - let panel = aEvent.currentTarget; + let panel = this._getPanelForNode(aEvent.currentTarget); let inInput = false; let inMenu = false; - while (!inInput && !inMenu && target != aEvent.currentTarget) { - inInput = target.localName == "input"; + let inItem = false; + while (!inInput && !inMenu && !inItem && target != panel) { + let tagName = target.localName; + inInput = tagName == "input"; inMenu = target.type == "menu"; + inItem = tagName == "toolbaritem" || tagName == "toolbarbutton"; target = target.parentNode; } - return inMenu || inInput; + return inMenu || inInput || !inItem; }, hidePanelForNode: function(aNode) { @@ -1496,6 +1509,16 @@ let CustomizableUIInternal = { } gPalette.set(widget.id, widget); + + // Clear our caches: + gGroupWrapperCache.delete(widget.id); + for (let [win, ] of gBuildWindows) { + let cache = gSingleWrapperCache.get(win); + if (cache) { + cache.delete(widget.id); + } + } + this.notifyListeners("onWidgetCreated", widget.id); if (widget.defaultArea) { @@ -1954,6 +1977,9 @@ this.CustomizableUI = { get TYPE_MENU_PANEL() "menu-panel", get TYPE_TOOLBAR() "toolbar", + get WIDE_PANEL_CLASS() "panel-wide-item", + get PANEL_COLUMN_COUNT() 3, + addListener: function(aListener) { CustomizableUIInternal.addListener(aListener); }, @@ -2068,6 +2094,12 @@ this.CustomizableUI = { onWidgetDrag: function(aWidgetId, aArea) { CustomizableUIInternal.notifyListeners("onWidgetDrag", aWidgetId, aArea); }, + notifyStartCustomizing: function(aWindow) { + CustomizableUIInternal.notifyListeners("onCustomizeStart", aWindow); + }, + notifyEndCustomizing: function(aWindow) { + CustomizableUIInternal.notifyListeners("onCustomizeEnd", aWindow); + }, isAreaOverflowable: function(aAreaId) { let area = gAreas.get(aAreaId); return area ? area.get("type") == this.TYPE_TOOLBAR && area.get("overflowable") diff --git a/browser/components/customizableui/src/CustomizableWidgets.jsm b/browser/components/customizableui/src/CustomizableWidgets.jsm index 5f1fd8e23a66..c70907c90c45 100644 --- a/browser/components/customizableui/src/CustomizableWidgets.jsm +++ b/browser/components/customizableui/src/CustomizableWidgets.jsm @@ -40,14 +40,14 @@ function setAttributes(aNode, aAttrs) { function updateCombinedWidgetStyle(aNode, aArea, aModifyAutoclose) { let inPanel = (aArea == CustomizableUI.AREA_PANEL); - let cls = inPanel ? "panel-combined-button" : "toolbarbutton-1"; - if (!aArea) - cls = null; + let cls = inPanel ? "panel-combined-button" : null; let attrs = {class: cls}; if (aModifyAutoclose) { attrs.noautoclose = inPanel ? true : null; } for (let i = 0, l = aNode.childNodes.length; i < l; ++i) { + if (aNode.childNodes[i].localName == "separator") + continue; setAttributes(aNode.childNodes[i], attrs); } } @@ -297,7 +297,7 @@ const CustomizableWidgets = [{ const kPanelId = "PanelUI-popup"; let inPanel = (this.currentArea == CustomizableUI.AREA_PANEL); let noautoclose = inPanel ? "true" : null; - let cls = inPanel ? "panel-combined-button" : "toolbarbutton-1"; + let cls = inPanel ? "panel-combined-button" : null; if (!this.currentArea) cls = null; @@ -333,7 +333,9 @@ const CustomizableWidgets = [{ node.classList.add("toolbaritem-combined-buttons"); node.classList.add(kWidePanelItemClass); - buttons.forEach(function(aButton) { + buttons.forEach(function(aButton, aIndex) { + if (aIndex != 0) + node.appendChild(aDocument.createElementNS(kNSXUL, "separator")); let btnNode = aDocument.createElementNS(kNSXUL, "toolbarbutton"); setAttributes(btnNode, aButton); if (inPanel) @@ -342,7 +344,7 @@ const CustomizableWidgets = [{ }); // The middle node is the 'Reset Zoom' button. - let zoomResetButton = node.childNodes[1]; + let zoomResetButton = node.childNodes[2]; let window = aDocument.defaultView; function updateZoomResetButton() { //XXXgijs in some tests we get called very early, and there's no docShell on the @@ -439,7 +441,7 @@ const CustomizableWidgets = [{ defaultArea: CustomizableUI.AREA_PANEL, onBuild: function(aDocument) { let inPanel = (this.currentArea == CustomizableUI.AREA_PANEL); - let cls = inPanel ? "panel-combined-button" : "toolbarbutton-1"; + let cls = inPanel ? "panel-combined-button" : null; if (!this.currentArea) cls = null; @@ -473,7 +475,9 @@ const CustomizableWidgets = [{ node.classList.add("toolbaritem-combined-buttons"); node.classList.add(kWidePanelItemClass); - buttons.forEach(function(aButton) { + buttons.forEach(function(aButton, aIndex) { + if (aIndex != 0) + node.appendChild(aDocument.createElementNS(kNSXUL, "separator")); let btnNode = aDocument.createElementNS(kNSXUL, "toolbarbutton"); setAttributes(btnNode, aButton); if (inPanel) diff --git a/browser/components/customizableui/src/CustomizeMode.jsm b/browser/components/customizableui/src/CustomizeMode.jsm index 27e5d768aa95..7bc14da542b9 100644 --- a/browser/components/customizableui/src/CustomizeMode.jsm +++ b/browser/components/customizableui/src/CustomizeMode.jsm @@ -14,10 +14,6 @@ const kPaletteId = "customization-palette"; const kAboutURI = "about:customizing"; const kDragDataTypePrefix = "text/toolbarwrapper-id/"; const kPlaceholderClass = "panel-customization-placeholder"; -const kWidePanelItemClass = "panel-wide-item"; -// TODO(bug 885574): Merge this constant with the one in CustomizableWidgets.jsm, -// maybe just use a pref for this. -const kColumnsInMenuPanel = 3; const kSkipSourceNodePref = "browser.uiCustomization.skipSourceNodeCheck"; Cu.import("resource://gre/modules/Services.jsm"); @@ -25,6 +21,8 @@ Cu.import("resource:///modules/CustomizableUI.jsm"); Cu.import("resource://gre/modules/XPCOMUtils.jsm"); Cu.import("resource://gre/modules/Task.jsm"); Cu.import("resource://gre/modules/Promise.jsm"); +XPCOMUtils.defineLazyModuleGetter(this, "DragPositionManager", + "resource:///modules/DragPositionManager.jsm"); let gModuleName = "[CustomizeMode]"; #include logging.js @@ -113,6 +111,7 @@ CustomizeMode.prototype = { this.document.documentElement._lightweightTheme.disable(); this.dispatchToolboxEvent("beforecustomization"); + CustomizableUI.notifyStartCustomizing(this.window); let window = this.window; let document = this.document; @@ -218,6 +217,7 @@ CustomizeMode.prototype = { window.gNavToolbox.removeEventListener("toolbarvisibilitychange", this); + DragPositionManager.stop(); window.PanelUI.mainView.removeEventListener("contextmenu", this, true); this.visiblePalette.removeEventListener("dragstart", this, true); this.visiblePalette.removeEventListener("dragover", this, true); @@ -286,6 +286,7 @@ CustomizeMode.prototype = { this._changed = false; this._transitioning = false; this.dispatchToolboxEvent("aftercustomization"); + CustomizableUI.notifyEndCustomizing(this.window); }.bind(this)).then(null, ERROR); }, @@ -512,6 +513,8 @@ CustomizeMode.prototype = { let toolbarItem = aWrapper.firstChild; if (!toolbarItem) { ERROR("no toolbarItem child for " + aWrapper.tagName + "#" + aWrapper.id); + aWrapper.remove(); + return null; } if (aWrapper.hasAttribute("itemchecked")) { @@ -775,13 +778,16 @@ CustomizeMode.prototype = { __dumpDragData(aEvent); let item = aEvent.target; while (item && item.localName != "toolbarpaletteitem") { - if (item.localName == "toolbar" || - item.classList.contains(kPlaceholderClass)) { + if (item.localName == "toolbar") { return; } item = item.parentNode; } + if (item.classList.contains(kPlaceholderClass)) { + return; + } + let dt = aEvent.dataTransfer; let documentId = aEvent.target.ownerDocument.documentElement.id; let draggedItem = item.firstChild; @@ -797,22 +803,28 @@ CustomizeMode.prototype = { // Hack needed so that the dragimage will still show the // item as it appeared before it was hidden. - let win = aEvent.target.ownerDocument.defaultView; - win.setTimeout(function() { + this._initializeDragAfterMove = function() { // For automated tests, we sometimes start exiting customization mode // before this fires, which leaves us with placeholders inserted after // we've exited. So we need to check that we are indeed customizing. if (this._customizing && !this._transitioning) { item.hidden = true; this._showPanelCustomizationPlaceholders(); + DragPositionManager.start(this.window); } - }.bind(this), 0); + this._initializeDragAfterMove = null; + this.window.clearTimeout(this._dragInitializeTimeout); + }.bind(this); + this._dragInitializeTimeout = this.window.setTimeout(this._initializeDragAfterMove, 0); }, _onDragOver: function(aEvent) { if (this._isUnwantedDragDrop(aEvent)) { return; } + if (this._initializeDragAfterMove) { + this._initializeDragAfterMove(); + } __dumpDragData(aEvent); @@ -845,7 +857,8 @@ CustomizeMode.prototype = { return; } - let targetNode = this._getDragOverNode(aEvent, targetArea); + let targetIsToolbar = CustomizableUI.getAreaType(targetArea.id) == "toolbar"; + let targetNode = this._getDragOverNode(aEvent, targetArea, targetIsToolbar, draggedItemId); // We need to determine the place that the widget is being dropped in // the target. @@ -863,20 +876,15 @@ CustomizeMode.prototype = { dragValue = "after"; } else { dragOverItem = targetParent.children[position]; - // Check if the aDraggedItem is hovered past the first half of dragOverItem - let window = dragOverItem.ownerDocument.defaultView; - let direction = window.getComputedStyle(dragOverItem, null).direction; - let itemRect = dragOverItem.getBoundingClientRect(); - let dropTargetCenter = itemRect.left + (itemRect.width / 2); - if (targetParent == window.PanelUI.contents) { - dragValue = "true"; - if (direction == "ltr" && aEvent.clientX > dropTargetCenter) { - position++; - } else if (direction == "rtl" && aEvent.clientX < dropTargetCenter) { - position--; - } + if (!targetIsToolbar) { + dragValue = "before"; dragOverItem = position == -1 ? targetParent.firstChild : targetParent.children[position]; } else { + // Check if the aDraggedItem is hovered past the first half of dragOverItem + let window = dragOverItem.ownerDocument.defaultView; + let direction = window.getComputedStyle(dragOverItem, null).direction; + let itemRect = dragOverItem.getBoundingClientRect(); + let dropTargetCenter = itemRect.left + (itemRect.width / 2); let existingDir = dragOverItem.getAttribute("dragover"); if ((existingDir == "before") == (direction == "ltr")) { dropTargetCenter += (parseInt(dragOverItem.style.borderLeftWidth) || 0) / 2; @@ -890,12 +898,12 @@ CustomizeMode.prototype = { } if (this._dragOverItem && dragOverItem != this._dragOverItem) { - this._setDragActive(this._dragOverItem, false); + this._cancelDragActive(this._dragOverItem, dragOverItem); } if (dragOverItem != this._dragOverItem || dragValue != dragOverItem.getAttribute("dragover")) { if (dragOverItem != targetArea.customizationTarget) { - this._setDragActive(dragOverItem, dragValue, draggedItemId); + this._setDragActive(dragOverItem, dragValue, draggedItemId, targetIsToolbar); } this._dragOverItem = dragOverItem; } @@ -910,6 +918,8 @@ CustomizeMode.prototype = { } __dumpDragData(aEvent); + this._initializeDragAfterMove = null; + this.window.clearTimeout(this._dragInitializeTimeout); let targetArea = this._getCustomizableParent(aEvent.currentTarget); let document = aEvent.target.ownerDocument; @@ -918,8 +928,8 @@ CustomizeMode.prototype = { aEvent.dataTransfer.mozGetDataAt(kDragDataTypePrefix + documentId, 0); let draggedWrapper = document.getElementById("wrapper-" + draggedItemId); let originArea = this._getCustomizableParent(draggedWrapper); - if (this._dragWidthMap) { - this._dragWidthMap.clear(); + if (this._dragSizeMap) { + this._dragSizeMap.clear(); } // Do nothing if the target area or origin area are not customizable. if (!targetArea || !originArea) { @@ -943,7 +953,7 @@ CustomizeMode.prototype = { targetNode = targetNode.firstChild; } - this._setDragActive(this._dragOverItem, false); + this._cancelDragActive(this._dragOverItem, null, true); this._removePanelCustomizationPlaceholders(); try { @@ -1067,8 +1077,14 @@ CustomizeMode.prototype = { __dumpDragData(aEvent); - if (this._dragOverItem) { - this._setDragActive(this._dragOverItem, false); + // When leaving customization areas, cancel the drag on the last dragover item + // We've attached the listener to areas, so aEvent.currentTarget will be the area. + // We don't care about dragexit events fired on descendants of the area, + // so we check that the event's target is the same as the area to which the listener + // was attached. + if (this._dragOverItem && aEvent.target == aEvent.currentTarget) { + this._cancelDragActive(this._dragOverItem); + this._dragOverItem = null; } }, @@ -1076,6 +1092,8 @@ CustomizeMode.prototype = { if (this._isUnwantedDragDrop(aEvent)) { return; } + this._initializeDragAfterMove = null; + this.window.clearTimeout(this._dragInitializeTimeout); __dumpDragData(aEvent); let document = aEvent.target.ownerDocument; @@ -1114,176 +1132,131 @@ CustomizeMode.prototype = { mozSourceNode.ownerDocument.defaultView != this.window; }, - _setDragActive: function(aItem, aValue, aDraggedItemId) { + _setDragActive: function(aItem, aValue, aDraggedItemId, aInToolbar) { if (!aItem) { return; } - if (aValue) { - if (aItem.hasAttribute("dragover") != aValue) { - aItem.setAttribute("dragover", aValue); + if (aItem.hasAttribute("dragover") != aValue) { + aItem.setAttribute("dragover", aValue); + let window = aItem.ownerDocument.defaultView; + let draggedItem = window.document.getElementById(aDraggedItemId); + if (!aInToolbar) { + this._setPanelDragActive(aItem, draggedItem, aValue); + } else { // Calculate width of the item when it'd be dropped in this position - let window = aItem.ownerDocument.defaultView; - let draggedItem = window.document.getElementById(aDraggedItemId); - let width = this._getDragItemWidth(aItem, draggedItem); - if (width) { - let panelContents = window.PanelUI.contents; - if (aItem.parentNode == panelContents) { - this._setPanelDragActive(aItem, draggedItem, width); - } else { - let direction = window.getComputedStyle(aItem).direction; - let prop, otherProp; - // If we're inserting before in ltr, or after in rtl: - if ((aValue == "before") == (direction == "ltr")) { - prop = "borderLeftWidth"; - otherProp = "border-right-width"; - } else { - // otherwise: - prop = "borderRightWidth"; - otherProp = "border-left-width"; - } - aItem.style[prop] = width; - aItem.style.removeProperty(otherProp); - } + let width = this._getDragItemSize(aItem, draggedItem).width; + let direction = window.getComputedStyle(aItem).direction; + let prop, otherProp; + // If we're inserting before in ltr, or after in rtl: + if ((aValue == "before") == (direction == "ltr")) { + prop = "borderLeftWidth"; + otherProp = "border-right-width"; + } else { + // otherwise: + prop = "borderRightWidth"; + otherProp = "border-left-width"; } + aItem.style[prop] = width + 'px'; + aItem.style.removeProperty(otherProp); } - } else { + } + }, + _cancelDragActive: function(aItem, aNextItem, aNoTransition) { + let currentArea = this._getCustomizableParent(aItem); + if (!currentArea) { + return; + } + let isToolbar = CustomizableUI.getAreaType(currentArea.id) == "toolbar"; + if (isToolbar) { aItem.removeAttribute("dragover"); // Remove both property values in the case that the end padding // had been set. aItem.style.removeProperty("border-left-width"); aItem.style.removeProperty("border-right-width"); - } - }, - - _setPanelDragActive: function(aDragOverNode, aDraggedItem, aWidth) { - let document = aDragOverNode.ownerDocument; - let window = document.defaultView; - let panelContents = window.PanelUI.contents; - while (!aDragOverNode.id && aDragOverNode.parentNode != panelContents) - aDragOverNode = aDragOverNode.parentNode; - if (!aDragOverNode.id) - return; - - if (!aDragOverNode.previousSibling || - !aDragOverNode.previousSibling.classList.contains(kPlaceholderClass)) { - let isPlaceholderAtEnd = function(aPlaceholder) { - do { - aPlaceholder = aPlaceholder.nextSibling; - if (!aPlaceholder) - return true; - if (!aPlaceholder.classList.contains(kPlaceholderClass)) - return false; - } while (aPlaceholder.nextSibling) - return true; - } - - let resetAnimAttributes = function(aPlaceholder) { - if (!aPlaceholder) + } else { + if (aNextItem) { + let nextArea = this._getCustomizableParent(aNextItem); + if (nextArea == currentArea) { + // No need to do anything if we're still dragging in this area: return; - aPlaceholder.removeAttribute("expand"); - aPlaceholder.removeAttribute("contract"); - aPlaceholder.removeAttribute("hidden"); - aPlaceholder.style.removeProperty("width"); - } - - let placeholders = Array.slice(panelContents.getElementsByClassName(kPlaceholderClass)); - - let toExpand = placeholders.shift(); - let toContract = placeholders.shift(); - if (toContract && isPlaceholderAtEnd(toContract)) - toContract = null; - // Seek to find hidden placeholders first to use for the expand transition. - while (toExpand.getAttribute("hidden") != "true" && placeholders.length) - toExpand = placeholders.shift(); - - if (toExpand.transitioning || (toContract && toContract.transitioning)) - return; - - let wasHidden = (toContract && toContract.getAttribute("hidden") == "true") || - toExpand.getAttribute("hidden") == "true"; - resetAnimAttributes(toContract); - resetAnimAttributes(toExpand); - - aDragOverNode.parentNode.insertBefore(toExpand, aDragOverNode); - toExpand.style.width = "0px"; - toExpand.setAttribute("expand", "true"); - toExpand.transitioning = true; - if (toContract) { - toContract.style.width = aWidth; - toContract.setAttribute("contract", "true"); - toContract.transitioning = true; - } - - window.mozRequestAnimationFrame(() => { - if (toContract) - toContract.style.width = "0px"; - toExpand.style.width = aWidth; - }); - toExpand.addEventListener("transitionend", function expandTransitionEnd() { - toExpand.removeEventListener("transitionend", expandTransitionEnd, false); - toExpand.transitioning = false; - }); - if (toContract) { - toContract.addEventListener("transitionend", function contractTransitionEnd() { - toContract.removeEventListener("transitionend", contractTransitionEnd, false); - panelContents.appendChild(toContract); - if (wasHidden) - toContract.setAttribute("hidden", "true"); - toContract.transitioning = false; - }); + } } + // Otherwise, clear everything out: + let positionManager = DragPositionManager.getManagerForArea(currentArea); + positionManager.clearPlaceholders(currentArea, aNoTransition); } }, - _getDragItemWidth: function(aDragOverNode, aDraggedItem) { - // Cache it good, cache it real good. - if (!this._dragWidthMap) - this._dragWidthMap = new WeakMap(); - if (!this._dragWidthMap.has(aDraggedItem)) - this._dragWidthMap.set(aDraggedItem, new WeakMap()); - let itemMap = this._dragWidthMap.get(aDraggedItem); + _setPanelDragActive: function(aDragOverNode, aDraggedItem, aValue) { let targetArea = this._getCustomizableParent(aDragOverNode); - if (!targetArea) - return; - // Return the width for this target from cache, if it exists. - let width = itemMap.get(targetArea); - if (width) - return width; + let positionManager = DragPositionManager.getManagerForArea(targetArea); + let draggedSize = this._getDragItemSize(aDragOverNode, aDraggedItem); + let isWide = aDraggedItem.classList.contains(CustomizableUI.WIDE_PANEL_CLASS); + positionManager.insertPlaceholder(targetArea, aDragOverNode, isWide, draggedSize); + }, - // Calculate width of the item when it'd be dropped in this position. + _getDragItemSize: function(aDragOverNode, aDraggedItem) { + // Cache it good, cache it real good. + if (!this._dragSizeMap) + this._dragSizeMap = new WeakMap(); + if (!this._dragSizeMap.has(aDraggedItem)) + this._dragSizeMap.set(aDraggedItem, new WeakMap()); + let itemMap = this._dragSizeMap.get(aDraggedItem); + let targetArea = this._getCustomizableParent(aDragOverNode); + let currentArea = this._getCustomizableParent(aDraggedItem); + // Return the size for this target from cache, if it exists. + let size = itemMap.get(targetArea); + if (size) + return size; + + // Calculate size of the item when it'd be dropped in this position. let currentParent = aDraggedItem.parentNode; let currentSibling = aDraggedItem.nextSibling; - - // Move the widget temporarily next to the placeholder. - aDragOverNode.parentNode.insertBefore(aDraggedItem, aDragOverNode); - // Update the node's areaType. - let areaType = CustomizableUI.getAreaType(targetArea.id); const kAreaType = "cui-areatype"; - let currentType = aDraggedItem.hasAttribute(kAreaType) && - aDraggedItem.getAttribute(kAreaType); - if (areaType) - aDraggedItem.setAttribute(kAreaType, areaType); - CustomizableUI.onWidgetDrag(aDraggedItem.id, targetArea.id); - // Fetch the new width. - width = Math.floor(aDraggedItem.getBoundingClientRect().width) + "px"; - // Put the item back into its previous position. - if (currentSibling) - currentParent.insertBefore(aDraggedItem, currentSibling); - else - currentParent.appendChild(aDraggedItem); - // restore the areaType - if (areaType) { - if (currentType === false) - aDraggedItem.removeAttribute(kAreaType); - else - aDraggedItem.setAttribute(kAreaType, currentType); + let areaType, currentType; + + if (targetArea != currentArea) { + // Move the widget temporarily next to the placeholder. + aDragOverNode.parentNode.insertBefore(aDraggedItem, aDragOverNode); + // Update the node's areaType. + areaType = CustomizableUI.getAreaType(targetArea.id); + currentType = aDraggedItem.hasAttribute(kAreaType) && + aDraggedItem.getAttribute(kAreaType); + if (areaType) + aDraggedItem.setAttribute(kAreaType, areaType); + this.wrapToolbarItem(aDraggedItem, areaType || "palette"); + CustomizableUI.onWidgetDrag(aDraggedItem.id, targetArea.id); + } else { + aDraggedItem.parentNode.hidden = false; } - CustomizableUI.onWidgetDrag(aDraggedItem.id); - // Cache the found value of width for this target. - itemMap.set(targetArea, width); - return width; + + // Fetch the new size. + let rect = aDraggedItem.parentNode.getBoundingClientRect(); + size = {width: rect.width, height: rect.height}; + // Cache the found value of size for this target. + itemMap.set(targetArea, size); + + if (targetArea != currentArea) { + this.unwrapToolbarItem(aDraggedItem.parentNode); + // Put the item back into its previous position. + if (currentSibling) + currentParent.insertBefore(aDraggedItem, currentSibling); + else + currentParent.appendChild(aDraggedItem); + // restore the areaType + if (areaType) { + if (currentType === false) + aDraggedItem.removeAttribute(kAreaType); + else + aDraggedItem.setAttribute(kAreaType, currentType); + } + CustomizableUI.onWidgetDrag(aDraggedItem.id); + } else { + aDraggedItem.parentNode.hidden = true; + } + return size; }, _getCustomizableParent: function(aElement) { @@ -1298,7 +1271,7 @@ CustomizeMode.prototype = { return null; }, - _getDragOverNode: function(aEvent, aAreaElement) { + _getDragOverNode: function(aEvent, aAreaElement, aInToolbar, aDraggedItemId) { let expectedParent = aAreaElement.customizationTarget || aAreaElement; // Our tests are stupid. Cope: if (!aEvent.clientX && !aEvent.clientY) { @@ -1314,9 +1287,16 @@ CustomizeMode.prototype = { dragX = Math.min(bounds.right, Math.max(dragX, bounds.left)); dragY = Math.min(bounds.bottom, Math.max(dragY, bounds.top)); - let targetNode = aAreaElement.ownerDocument.elementFromPoint(dragX, dragY); - while (targetNode && targetNode.parentNode != expectedParent) { - targetNode = targetNode.parentNode; + let targetNode; + if (aInToolbar) { + targetNode = aAreaElement.ownerDocument.elementFromPoint(dragX, dragY); + while (targetNode && targetNode.parentNode != expectedParent) { + targetNode = targetNode.parentNode; + } + } else { + let positionManager = DragPositionManager.getManagerForArea(aAreaElement); + // Find the closest node: + targetNode = positionManager.find(aAreaElement, dragX, dragY, aDraggedItemId); } return targetNode || aEvent.target; }, @@ -1326,7 +1306,7 @@ CustomizeMode.prototype = { let doc = aEvent.target.ownerDocument; doc.documentElement.setAttribute("customizing-movingItem", true); let item = this._getWrapper(aEvent.target); - if (item) { + if (item && !item.classList.contains(kPlaceholderClass)) { item.setAttribute("mousedown", "true"); } }, @@ -1351,35 +1331,37 @@ CustomizeMode.prototype = { }, _showPanelCustomizationPlaceholders: function() { - this._removePanelCustomizationPlaceholders(); let doc = this.document; let contents = this.panelUIContents; - let visibleWideItems = contents.querySelectorAll("toolbarpaletteitem:not([hidden]) > ." + kWidePanelItemClass); - let visibleChildren = contents.querySelectorAll("toolbarpaletteitem:not([hidden])"); - // TODO(bug 885578): Still doesn't handle a hole when there is a wide - // widget located at the bottom of the panel. let narrowItemsAfterWideItem = 0; let node = contents.lastChild; - while (node && !node.classList.contains(kWidePanelItemClass) && - (!node.firstChild || !node.firstChild.classList.contains(kWidePanelItemClass))) { - if (!node.hidden) { + while (node && !node.classList.contains(CustomizableUI.WIDE_PANEL_CLASS) && + (!node.firstChild || !node.firstChild.classList.contains(CustomizableUI.WIDE_PANEL_CLASS))) { + if (!node.hidden && !node.classList.contains(kPlaceholderClass)) { narrowItemsAfterWideItem++; } node = node.previousSibling; } - let orphanedItems = narrowItemsAfterWideItem % kColumnsInMenuPanel; - let placeholders = kColumnsInMenuPanel - orphanedItems; + let orphanedItems = narrowItemsAfterWideItem % CustomizableUI.PANEL_COLUMN_COUNT; + let placeholders = CustomizableUI.PANEL_COLUMN_COUNT - orphanedItems; - while (placeholders--) { - let placeholder = doc.createElement("toolbarpaletteitem"); - placeholder.classList.add(kPlaceholderClass); - //XXXjaws The toolbarbutton child here is only necessary to get - // the styling right here. - let placeholderChild = doc.createElement("toolbarbutton"); - placeholderChild.classList.add(kPlaceholderClass + "-child"); - placeholder.appendChild(placeholderChild); - contents.appendChild(placeholder); + let currentPlaceholderCount = contents.querySelectorAll("." + kPlaceholderClass).length; + if (placeholders > currentPlaceholderCount) { + while (placeholders-- > currentPlaceholderCount) { + let placeholder = doc.createElement("toolbarpaletteitem"); + placeholder.classList.add(kPlaceholderClass); + //XXXjaws The toolbarbutton child here is only necessary to get + // the styling right here. + let placeholderChild = doc.createElement("toolbarbutton"); + placeholderChild.classList.add(kPlaceholderClass + "-child"); + placeholder.appendChild(placeholderChild); + contents.appendChild(placeholder); + } + } else if (placeholders < currentPlaceholderCount) { + while (placeholders++ < currentPlaceholderCount) { + contents.querySelectorAll("." + kPlaceholderClass)[0].remove(); + } } }, @@ -1409,6 +1391,9 @@ function getPlaceForItem(aElement) { } function __dumpDragData(aEvent, caller) { + if (!gDebug) { + return; + } let str = "Dumping drag data (CustomizeMode.jsm) {\n"; str += " type: " + aEvent["type"] + "\n"; for (let el of ["target", "currentTarget", "relatedTarget"]) { diff --git a/browser/components/customizableui/src/DragPositionManager.jsm b/browser/components/customizableui/src/DragPositionManager.jsm new file mode 100644 index 000000000000..48564bc9ad4d --- /dev/null +++ b/browser/components/customizableui/src/DragPositionManager.jsm @@ -0,0 +1,367 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +"use strict"; + +Components.utils.import("resource:///modules/CustomizableUI.jsm"); + +let gManagers = new WeakMap(); + +const kPaletteId = "customization-palette"; +const kPlaceholderClass = "panel-customization-placeholder"; + +this.EXPORTED_SYMBOLS = ["DragPositionManager"]; + +function AreaPositionManager(aContainer) { + // Caching the direction and bounds of the container for quick access later: + let window = aContainer.ownerDocument.defaultView; + this._dir = window.getComputedStyle(aContainer).direction; + let containerRect = aContainer.getBoundingClientRect(); + this._containerInfo = { + left: containerRect.left, + right: containerRect.right, + width: containerRect.width + }; + this._inPanel = aContainer.id == CustomizableUI.AREA_PANEL; + this._horizontalDistance = null; + this.update(aContainer); +} + +AreaPositionManager.prototype = { + _nodePositionStore: null, + _wideCache: null, + + update: function(aContainer) { + let window = aContainer.ownerDocument.defaultView; + this._nodePositionStore = new WeakMap(); + this._wideCache = new Set(); + let last = null; + let singleItemHeight; + for (let child of aContainer.children) { + if (child.hidden) { + continue; + } + let isNodeWide = this._checkIfWide(child); + if (isNodeWide) { + this._wideCache.add(child.id); + } + let coordinates = this._lazyStoreGet(child); + // We keep a baseline horizontal distance between non-wide nodes around + // for use when we can't compare with previous/next nodes + if (!this._horizontalDistance && last && !isNodeWide) { + this._horizontalDistance = coordinates.left - last.left; + } + // We also keep the basic height of non-wide items for use below: + if (!isNodeWide && !singleItemHeight) { + singleItemHeight = coordinates.height; + } + last = !isNodeWide ? coordinates : null; + } + if (this._inPanel) { + this._heightToWidthFactor = CustomizableUI.PANEL_COLUMN_COUNT; + } else { + this._heightToWidthFactor = this._containerInfo.width / singleItemHeight; + } + }, + + /** + * Find the closest node in the container given the coordinates. + * "Closest" is defined in a somewhat strange manner: we prefer nodes + * which are in the same row over nodes that are in a different row. + * In order to implement this, we use a weighted cartesian distance + * where dy is more heavily weighted by a factor corresponding to the + * ratio between the container's width and the height of its elements. + */ + find: function(aContainer, aX, aY, aDraggedItemId) { + let closest = null; + let minCartesian = Number.MAX_VALUE; + for (let node of aContainer.children) { + let coordinates = this._lazyStoreGet(node); + let hDiff = coordinates.x - aX; + let vDiff = coordinates.y - aY; + // For wide widgets, we're always going to be further from the center + // horizontally. Compensate: + if (this.isWide(node)) { + hDiff /= CustomizableUI.PANEL_COLUMN_COUNT; + } + // Then compensate for the height/width ratio so that we prefer items + // which are in the same row: + hDiff /= this._heightToWidthFactor; + + let cartesianDiff = hDiff * hDiff + vDiff * vDiff; + if (cartesianDiff < minCartesian) { + minCartesian = cartesianDiff; + closest = node; + } + } + + // Now correct this node based on what we're dragging + if (closest) { + let doc = aContainer.ownerDocument; + let draggedItem = doc.getElementById(aDraggedItemId); + // If dragging a wide item, always pick the first item in a row: + if (draggedItem && + draggedItem.classList.contains(CustomizableUI.WIDE_PANEL_CLASS)) { + return this._firstInRow(closest); + } + let targetBounds = this._lazyStoreGet(closest); + let farSide = this._dir == "ltr" ? "right" : "left"; + let outsideX = targetBounds[farSide]; + // Check if we're closer to the next target than to this one: + // Only move if we're not targeting a node in a different row: + if (aY > targetBounds.top && aY < targetBounds.bottom) { + if ((this._dir == "ltr" && aX > outsideX) || + (this._dir == "rtl" && aX < outsideX)) { + return closest.nextSibling || aContainer; + } + } + } + return closest; + }, + + /** + * "Insert" a "placeholder" by shifting the subsequent children out of the + * way. We go through all the children, and shift them based on the position + * they would have if we had inserted something before aBefore. We use CSS + * transforms for this, which are CSS transitioned. + */ + insertPlaceholder: function(aContainer, aBefore, aWide, aSize) { + let isShifted = false; + let shiftDown = aWide; + for (let child of aContainer.children) { + // Don't need to shift hidden nodes: + if (child.getAttribute("hidden") == "true") { + continue; + } + // If this is the node before which we're inserting, start shifting + // everything that comes after. One exception is inserting at the end + // of the menupanel, in which case we do not shift the placeholders: + if (child == aBefore && !child.classList.contains(kPlaceholderClass)) { + isShifted = true; + // If the node before which we're inserting is wide, we should + // shift everything one row down: + if (!shiftDown && this.isWide(child)) { + shiftDown = true; + } + } + // If we're moving items before a wide node that were already there, + // it's possible it's not necessary to shift nodes + // including & after the wide node. + if (this.__undoShift) { + isShifted = false; + } + if (isShifted) { + // Conversely, if we're adding something before a wide node, for + // simplicity's sake we move everything including the wide node down: + if (this.__moveDown) { + shiftDown = true; + } + // Determine the CSS transform based on the next node: + child.style.transform = this._getNextPos(child, shiftDown, aSize); + } else { + // If we're not shifting this node, reset the transform + child.style.transform = ""; + } + } + delete this.__moveDown; + delete this.__undoShift; + }, + + isWide: function(aNode) { + return this._wideCache.has(aNode.id); + }, + + _checkIfWide: function(aNode) { + return this._inPanel && aNode && aNode.firstChild && + aNode.firstChild.classList.contains(CustomizableUI.WIDE_PANEL_CLASS); + }, + + /** + * Reset all the transforms in this container, optionally without + * transitioning them. + * @param aContainer the container in which to reset transforms + * @param aNoTransition if truthy, adds a notransition attribute to the node + * while resetting the transform. + */ + clearPlaceholders: function(aContainer, aNoTransition) { + for (let child of aContainer.children) { + if (aNoTransition) { + child.setAttribute("notransition", true); + } + child.style.transform = ""; + if (aNoTransition) { + // Need to force a reflow otherwise this won't work. + child.getBoundingClientRect(); + child.removeAttribute("notransition"); + } + } + }, + + _getNextPos: function(aNode, aShiftDown, aSize) { + // Shifting down is easy: + if (this._inPanel && aShiftDown) { + return "translate(0, " + aSize.height + "px)"; + } + return this._diffWithNext(aNode, aSize); + }, + + _diffWithNext: function(aNode, aSize) { + let xDiff; + let yDiff = null; + let nodeBounds = this._lazyStoreGet(aNode); + let side = this._dir == "ltr" ? "left" : "right"; + let next = this._getVisibleSiblingForDirection(aNode, "next"); + // First we determine the transform along the x axis. + // Usually, there will be a next node to base this on: + if (next) { + let otherBounds = this._lazyStoreGet(next); + xDiff = otherBounds[side] - nodeBounds[side]; + // If the next node is a wide item in the panel, check if we could maybe + // just move further out in the same row, without snapping to the next + // one. This happens, for example, if moving an item that's before a wide + // node within its own row of items. There will be space to drop this + // item within the row, and the rest of the items do not need to shift. + if (this.isWide(next)) { + let otherXDiff = this._moveNextBasedOnPrevious(aNode, nodeBounds, + this._firstInRow(aNode)); + // If this has the same sign as our original shift, we're still + // snapping to the start of the row. In this case, we should move + // everything after us a row down, so as not to display two nodes on + // top of each other: + // (we would be able to get away with checking for equality instead of + // equal signs here, but one of these is based on the x coordinate of + // the first item in row N and one on that for row N - 1, so this is + // safer, as their margins might differ) + if ((otherXDiff < 0) == (xDiff < 0)) { + this.__moveDown = true; + } else { + // Otherwise, we succeeded and can move further out. This also means + // we can stop shifting the rest of the content: + xDiff = otherXDiff; + this.__undoShift = true; + } + } else { + // We set this explicitly because otherwise some strange difference + // between the height and the actual difference between line creeps in + // and messes with alignments + yDiff = otherBounds.top - nodeBounds.top; + } + } else { + // We don't have a sibling whose position we can use. First, let's see + // if we're also the first item (which complicates things): + let firstNode = this._firstInRow(aNode); + if (aNode == firstNode) { + // Maybe we stored the horizontal distance between non-wide nodes, + // if not, we'll use the width of the incoming node as a proxy: + xDiff = this._horizontalDistance || aSize.width; + } else { + // If not, we should be able to get the distance to the previous node + // and use the inverse, unless there's no room for another node (ie we + // are the last node and there's no room for another one) + xDiff = this._moveNextBasedOnPrevious(aNode, nodeBounds, firstNode); + } + } + + // If we've not determined the vertical difference yet, check it here + if (yDiff === null) { + // If the next node is behind rather than in front, we must have moved + // vertically: + if ((xDiff > 0 && this._dir == "rtl") || (xDiff < 0 && this._dir == "ltr")) { + yDiff = aSize.height; + } else { + // Otherwise, we haven't + yDiff = 0; + } + } + return "translate(" + xDiff + "px, " + yDiff + "px)"; + }, + + /** + * Helper function to find the transform a node if there isn't a next node + * to base that on. + * @param aNode the node to transform + * @param aNodeBounds the bounding rect info of this node + * @param aFirstNodeInRow the first node in aNode's row + */ + _moveNextBasedOnPrevious: function(aNode, aNodeBounds, aFirstNodeInRow) { + let next = this._getVisibleSiblingForDirection(aNode, "previous"); + let otherBounds = this._lazyStoreGet(next); + let side = this._dir == "ltr" ? "left" : "right"; + let xDiff = aNodeBounds[side] - otherBounds[side]; + // If, however, this means we move outside the container's box + // (i.e. the row in which this item is placed is full) + // we should move it to align with the first item in the next row instead + let bound = this._containerInfo[this._dir == "ltr" ? "right" : "left"]; + if ((this._dir == "ltr" && xDiff + aNodeBounds.right > bound) || + (this._dir == "rtl" && xDiff + aNodeBounds.left < bound)) { + xDiff = this._lazyStoreGet(aFirstNodeInRow)[side] - aNodeBounds[side]; + } + return xDiff; + }, + + /** + * Get position details from our cache. If the node is not yet cached, get its position + * information and cache it now. + * @param aNode the node whose position info we want + * @return the position info + */ + _lazyStoreGet: function(aNode) { + let rect = this._nodePositionStore.get(aNode); + if (!rect) { + rect = aNode.getBoundingClientRect(); + rect.x = rect.left + rect.width / 2; + rect.y = rect.top + rect.height / 2; + this._nodePositionStore.set(aNode, rect); + } + return rect; + }, + + _firstInRow: function(aNode) { + let bound = this._lazyStoreGet(aNode).top; + let rv = aNode; + let prev; + while (rv && (prev = this._getVisibleSiblingForDirection(rv, "previous"))) { + if (this._lazyStoreGet(prev).bottom <= bound) { + return rv; + } + rv = prev; + } + return rv; + }, + + _getVisibleSiblingForDirection: function(aNode, aDirection) { + let rv = aNode; + do { + rv = rv[aDirection + "Sibling"]; + } while (rv && rv.getAttribute("hidden") == "true") + return rv; + } +} + +let DragPositionManager = { + start: function(aWindow) { + let areas = CustomizableUI.areas.filter((area) => CustomizableUI.getAreaType(area) != "toolbar"); + areas = areas.map((area) => CustomizableUI.getCustomizeTargetForArea(area, aWindow)); + areas.push(aWindow.document.getElementById(kPaletteId)); + for (let areaNode of areas) { + let positionManager = gManagers.get(areaNode); + if (positionManager) { + positionManager.update(areaNode); + } else { + gManagers.set(areaNode, new AreaPositionManager(areaNode)); + } + } + }, + + stop: function() { + gManagers.clear(); + }, + + getManagerForArea: function(aArea) { + return gManagers.get(aArea); + } +}; + +Object.freeze(DragPositionManager); + diff --git a/browser/components/customizableui/src/PanelWideWidgetTracker.jsm b/browser/components/customizableui/src/PanelWideWidgetTracker.jsm index 8aa28a7ab0f7..6fcb31e219cb 100644 --- a/browser/components/customizableui/src/PanelWideWidgetTracker.jsm +++ b/browser/components/customizableui/src/PanelWideWidgetTracker.jsm @@ -23,13 +23,6 @@ let gWideWidgets = new Set(); // All the widgets we know of: let gSeenWidgets = new Set(); -// The class by which we recognize wide widgets: -const kWidePanelItemClass = "panel-wide-item"; - -// TODO(bug 885574): Merge this constant with the one in CustomizeMode.jsm, -// maybe just use a pref for this. -const kColumnsInMenuPanel = 3; - let PanelWideWidgetTracker = { // Listeners used to validate panel contents whenever they change: onWidgetAdded: function(aWidgetId, aArea, aPosition) { @@ -61,7 +54,7 @@ let PanelWideWidgetTracker = { // Furthermore, onWidgetCreated only fires for API-based widgets, not for XUL ones. onWidgetAfterDOMChange: function(aNode, aNextNode, aContainer) { if (!gSeenWidgets.has(aNode.id)) { - if (aNode.classList.contains(kWidePanelItemClass)) { + if (aNode.classList.contains(CustomizableUI.WIDE_PANEL_CLASS)) { gWideWidgets.add(aNode.id); } gSeenWidgets.add(aNode.id); @@ -137,12 +130,12 @@ let PanelWideWidgetTracker = { } } - if (fixedPos !== null || prevSiblingCount % kColumnsInMenuPanel) { + if (fixedPos !== null || prevSiblingCount % CustomizableUI.PANEL_COLUMN_COUNT) { let desiredPos = (fixedPos !== null) ? fixedPos : gPanelPlacements.indexOf(aWidgetId); - let desiredChange = -(prevSiblingCount % kColumnsInMenuPanel); + let desiredChange = -(prevSiblingCount % CustomizableUI.PANEL_COLUMN_COUNT); if (aMoveForwards && fixedPos == null) { // +1 because otherwise we'd count ourselves: - desiredChange = kColumnsInMenuPanel + desiredChange + 1; + desiredChange = CustomizableUI.PANEL_COLUMN_COUNT + desiredChange + 1; } desiredPos += desiredChange; CustomizableUI.moveWidgetWithinArea(aWidgetId, desiredPos); diff --git a/browser/components/customizableui/src/moz.build b/browser/components/customizableui/src/moz.build index d82151e22573..8b5064ddf8eb 100644 --- a/browser/components/customizableui/src/moz.build +++ b/browser/components/customizableui/src/moz.build @@ -5,6 +5,7 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. EXTRA_JS_MODULES += [ + 'DragPositionManager.jsm', 'ScrollbarSampler.jsm', ] diff --git a/browser/components/customizableui/test/browser.ini b/browser/components/customizableui/test/browser.ini index 5b05e094b063..c80d3284a82d 100644 --- a/browser/components/customizableui/test/browser.ini +++ b/browser/components/customizableui/test/browser.ini @@ -35,4 +35,7 @@ skip-if = true # Because this test is about the menubar, it can't be run on mac skip-if = os == "mac" +[browser_938980_navbar_collapsed.js] +[browser_940946_removable_from_navbar_customizemode.js] +[browser_941083_invalidate_wrapper_cache_createWidget.js] [browser_panel_toggle.js] diff --git a/browser/components/customizableui/test/browser_876926_customize_mode_wrapping.js b/browser/components/customizableui/test/browser_876926_customize_mode_wrapping.js index 9d4d4289e90f..75875e417b0d 100644 --- a/browser/components/customizableui/test/browser_876926_customize_mode_wrapping.js +++ b/browser/components/customizableui/test/browser_876926_customize_mode_wrapping.js @@ -114,14 +114,7 @@ let gTests = [ setup: startCustomizing, run: function() { otherWin = yield openAndLoadWindow(null, true); - // Open and close the panel to force its construction: - let shownPromise = promisePanelShown(otherWin); - otherWin.PanelUI.toggle({type: "command"}); - yield shownPromise; - let hiddenPromise = promisePanelHidden(otherWin); - otherWin.PanelUI.toggle({type: "command"}); - yield hiddenPromise; - + yield otherWin.PanelUI.ensureReady(); ok(CustomizableUI.inDefaultState, "Should start in default state"); for (let widgetId of [kXULWidgetId, kAPIWidgetId]) { diff --git a/browser/components/customizableui/test/browser_938980_navbar_collapsed.js b/browser/components/customizableui/test/browser_938980_navbar_collapsed.js new file mode 100644 index 000000000000..d032be2c211a --- /dev/null +++ b/browser/components/customizableui/test/browser_938980_navbar_collapsed.js @@ -0,0 +1,26 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +let gTests = [ + { + desc: "Customization reset should restore visibility to default-visible toolbars.", + setup: null, + run: function() { + let navbar = document.getElementById("nav-bar"); + is(navbar.collapsed, false, "Test should start with navbar visible"); + navbar.collapsed = true; + is(navbar.collapsed, true, "navbar should be hidden now"); + + yield resetCustomization(); + + is(navbar.collapsed, false, "Customization reset should restore visibility to the navbar"); + }, + teardown: null + }, +]; + +function test() { + waitForExplicitFinish(); + runTests(gTests); +} diff --git a/browser/components/customizableui/test/browser_940946_removable_from_navbar_customizemode.js b/browser/components/customizableui/test/browser_940946_removable_from_navbar_customizemode.js new file mode 100644 index 000000000000..ef3b22957b96 --- /dev/null +++ b/browser/components/customizableui/test/browser_940946_removable_from_navbar_customizemode.js @@ -0,0 +1,33 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +const kTestBtnId = "test-removable-navbar-customize-mode"; + +let gTests = [ + { + desc: "Items without the removable attribute in the navbar should be considered non-removable", + setup: function() { + let btn = createDummyXULButton(kTestBtnId, "Test removable in navbar in customize mode"); + document.getElementById("nav-bar").customizationTarget.appendChild(btn); + return startCustomizing(); + }, + run: function() { + ok(!CustomizableUI.isWidgetRemovable(kTestBtnId), "Widget should not be considered removable"); + }, + teardown: function() { + yield endCustomizing(); + document.getElementById(kTestBtnId).remove(); + } + }, +]; +function asyncCleanup() { + yield endCustomizing(); + yield resetCustomization(); +} + +function test() { + waitForExplicitFinish(); + runTests(gTests, asyncCleanup); +} + diff --git a/browser/components/customizableui/test/browser_941083_invalidate_wrapper_cache_createWidget.js b/browser/components/customizableui/test/browser_941083_invalidate_wrapper_cache_createWidget.js new file mode 100644 index 000000000000..c322b0a47db1 --- /dev/null +++ b/browser/components/customizableui/test/browser_941083_invalidate_wrapper_cache_createWidget.js @@ -0,0 +1,38 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +// See https://bugzilla.mozilla.org/show_bug.cgi?id=941083 + +const kWidgetId = "test-invalidate-wrapper-cache"; + +let gTests = [ + { + desc: "Check createWidget invalidates the widget cache", + run: function() { + let groupWrapper = CustomizableUI.getWidget(kWidgetId); + ok(groupWrapper, "Should get group wrapper."); + let singleWrapper = groupWrapper.forWindow(window); + ok(singleWrapper, "Should get single wrapper."); + + CustomizableUI.createWidget({id: kWidgetId, label: "Test invalidating widgets caching"}); + + let newGroupWrapper = CustomizableUI.getWidget(kWidgetId); + ok(newGroupWrapper, "Should get a group wrapper again."); + isnot(newGroupWrapper, groupWrapper, "Wrappers shouldn't be the same."); + isnot(newGroupWrapper.provider, groupWrapper.provider, "Wrapper providers shouldn't be the same."); + + let newSingleWrapper = newGroupWrapper.forWindow(window); + isnot(newSingleWrapper, singleWrapper, "Single wrappers shouldn't be the same."); + isnot(newSingleWrapper.provider, singleWrapper.provider, "Single wrapper providers shouldn't be the same."); + + CustomizableUI.destroyWidget(kWidgetId); + ok(!CustomizableUI.getWidget(kWidgetId), "Shouldn't get a wrapper after destroying the widget."); + }, + }, +]; + +function test() { + waitForExplicitFinish(); + runTests(gTests); +} diff --git a/browser/components/dirprovider/moz.build b/browser/components/dirprovider/moz.build index c78e77689b17..92aab83e37fc 100644 --- a/browser/components/dirprovider/moz.build +++ b/browser/components/dirprovider/moz.build @@ -4,8 +4,6 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -MODULE = 'browserdir' - EXPORTS.mozilla.browser += [ 'DirectoryProvider.h', ] @@ -14,10 +12,8 @@ SOURCES += [ 'DirectoryProvider.cpp', ] -LIBRARY_NAME = 'browserdir_s' - XPCSHELL_TESTS_MANIFESTS += [ 'tests/unit/xpcshell.ini', ] -FORCE_STATIC_LIB = True +FINAL_LIBRARY = 'browsercomps' diff --git a/browser/components/feeds/public/moz.build b/browser/components/feeds/public/moz.build index aa73befb9797..3f1b6d29a936 100644 --- a/browser/components/feeds/public/moz.build +++ b/browser/components/feeds/public/moz.build @@ -10,5 +10,5 @@ XPIDL_SOURCES += [ 'nsIWebContentConverterRegistrar.idl', ] -MODULE = 'browser-feeds' +XPIDL_MODULE = 'browser-feeds' diff --git a/browser/components/feeds/src/moz.build b/browser/components/feeds/src/moz.build index bdcea5af9c39..777f012ceea1 100644 --- a/browser/components/feeds/src/moz.build +++ b/browser/components/feeds/src/moz.build @@ -4,8 +4,6 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -MODULE = 'browser_feeds' - SOURCES += [ 'nsFeedSniffer.cpp', ] @@ -20,6 +18,4 @@ EXTRA_PP_COMPONENTS += [ 'FeedWriter.js', ] -LIBRARY_NAME = 'browser_feeds_s' - -FORCE_STATIC_LIB = True +FINAL_LIBRARY = 'browsercomps' diff --git a/browser/components/migration/public/moz.build b/browser/components/migration/public/moz.build index ec07bba1e526..b496622bc3cb 100644 --- a/browser/components/migration/public/moz.build +++ b/browser/components/migration/public/moz.build @@ -8,5 +8,5 @@ XPIDL_SOURCES += [ 'nsIBrowserProfileMigrator.idl', ] -MODULE = 'migration' +XPIDL_MODULE = 'migration' diff --git a/browser/components/migration/src/moz.build b/browser/components/migration/src/moz.build index e8ecd4f5bbdb..bf0a8cc53f63 100644 --- a/browser/components/migration/src/moz.build +++ b/browser/components/migration/src/moz.build @@ -4,8 +4,6 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -MODULE = 'migration' - if CONFIG['OS_ARCH'] == 'WINNT': SOURCES += [ 'nsIEHistoryEnumerator.cpp', @@ -36,10 +34,8 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa': 'SafariProfileMigrator.js', ] -LIBRARY_NAME = 'migration_s' - EXTRA_PP_JS_MODULES += [ 'MigrationUtils.jsm', ] -FORCE_STATIC_LIB = True +FINAL_LIBRARY = 'browsercomps' diff --git a/browser/components/moz.build b/browser/components/moz.build index 7284adb906f2..f9319973706e 100644 --- a/browser/components/moz.build +++ b/browser/components/moz.build @@ -31,8 +31,6 @@ XPIDL_SOURCES += [ XPIDL_MODULE = 'browsercompsbase' -MODULE = 'browsercomps' - EXTRA_COMPONENTS += [ 'BrowserComponents.manifest', ] diff --git a/browser/components/nsBrowserContentHandler.js b/browser/components/nsBrowserContentHandler.js index 1624089522b4..466950c1d7c9 100644 --- a/browser/components/nsBrowserContentHandler.js +++ b/browser/components/nsBrowserContentHandler.js @@ -549,7 +549,7 @@ nsBrowserContentHandler.prototype = { } var overridePage = ""; - var haveUpdateSession = false; + var willRestoreSession = false; try { // Read the old value of homepage_override.mstone before // needHomepageOverride updates it, so that we can later add it to the @@ -568,11 +568,15 @@ nsBrowserContentHandler.prototype = { overridePage = Services.urlFormatter.formatURLPref("startup.homepage_welcome_url"); break; case OVERRIDE_NEW_MSTONE: - // Check whether we have a session to restore. If we do, we assume - // that this is an "update" session. + // Check whether we will restore a session. If we will, we assume + // that this is an "update" session. This does not take crashes + // into account because that requires waiting for the session file + // to be read. If a crash occurs after updating, before restarting, + // we may open the startPage in addition to restoring the session. var ss = Components.classes["@mozilla.org/browser/sessionstartup;1"] .getService(Components.interfaces.nsISessionStartup); - haveUpdateSession = ss.doRestore(); + willRestoreSession = ss.isAutomaticRestoreEnabled(); + overridePage = Services.urlFormatter.formatURLPref("startup.homepage_override_url"); if (prefb.prefHasUserValue("app.update.postupdate")) overridePage = getPostUpdateOverridePage(overridePage); @@ -600,7 +604,7 @@ nsBrowserContentHandler.prototype = { startPage = ""; // Only show the startPage if we're not restoring an update session. - if (overridePage && startPage && !haveUpdateSession) + if (overridePage && startPage && !willRestoreSession) return overridePage + "|" + startPage; return overridePage || startPage || "about:blank"; diff --git a/browser/components/privatebrowsing/test/browser/browser.ini b/browser/components/privatebrowsing/test/browser/browser.ini index 7383ec84655d..2b71c0723132 100644 --- a/browser/components/privatebrowsing/test/browser/browser.ini +++ b/browser/components/privatebrowsing/test/browser/browser.ini @@ -1,5 +1,15 @@ [DEFAULT] support-files = + browser_privatebrowsing_concurrent_page.html + browser_privatebrowsing_cookieacceptdialog.html + browser_privatebrowsing_geoprompt_page.html + browser_privatebrowsing_localStorage_before_after_page.html + browser_privatebrowsing_localStorage_before_after_page2.html + browser_privatebrowsing_localStorage_page1.html + browser_privatebrowsing_localStorage_page2.html + browser_privatebrowsing_placesTitleNoUpdate.html + browser_privatebrowsing_protocolhandler_page.html + browser_privatebrowsing_windowtitle_page.html head.js popup.html title.sjs @@ -7,42 +17,31 @@ support-files = [browser_privatebrowsing_DownloadLastDirWithCPS.js] [browser_privatebrowsing_aboutHomeButtonAfterWindowClose.js] [browser_privatebrowsing_aboutSessionRestore.js] -# [browser_privatebrowsing_cache.js] -# Disabled for too many intermittent failures (bug 895390) +[browser_privatebrowsing_cache.js] [browser_privatebrowsing_certexceptionsui.js] [browser_privatebrowsing_concurrent.js] -[browser_privatebrowsing_concurrent_page.html] -[browser_privatebrowsing_cookieacceptdialog.html] [browser_privatebrowsing_cookieacceptdialog.js] [browser_privatebrowsing_crh.js] [browser_privatebrowsing_downloadLastDir.js] [browser_privatebrowsing_downloadLastDir_c.js] [browser_privatebrowsing_downloadLastDir_toggle.js] [browser_privatebrowsing_geoprompt.js] -[browser_privatebrowsing_geoprompt_page.html] [browser_privatebrowsing_lastpbcontextexited.js] [browser_privatebrowsing_localStorage.js] [browser_privatebrowsing_localStorage_before_after.js] -[browser_privatebrowsing_localStorage_before_after_page.html] -[browser_privatebrowsing_localStorage_before_after_page2.html] -[browser_privatebrowsing_localStorage_page1.html] -[browser_privatebrowsing_localStorage_page2.html] [browser_privatebrowsing_noSessionRestoreMenuOption.js] [browser_privatebrowsing_nonbrowser.js] [browser_privatebrowsing_openLocationLastURL.js] [browser_privatebrowsing_opendir.js] [browser_privatebrowsing_openlocation.js] -[browser_privatebrowsing_placesTitleNoUpdate.html] [browser_privatebrowsing_placesTitleNoUpdate.js] [browser_privatebrowsing_placestitle.js] [browser_privatebrowsing_popupblocker.js] [browser_privatebrowsing_protocolhandler.js] -[browser_privatebrowsing_protocolhandler_page.html] [browser_privatebrowsing_sidebar.js] [browser_privatebrowsing_theming.js] [browser_privatebrowsing_ui.js] [browser_privatebrowsing_urlbarfocus.js] [browser_privatebrowsing_windowtitle.js] -[browser_privatebrowsing_windowtitle_page.html] [browser_privatebrowsing_zoom.js] [browser_privatebrowsing_zoomrestore.js] diff --git a/browser/components/sessionstore/moz.build b/browser/components/sessionstore/moz.build index fefd9cc3975a..59bb71ca6a4e 100644 --- a/browser/components/sessionstore/moz.build +++ b/browser/components/sessionstore/moz.build @@ -11,7 +11,7 @@ XPIDL_SOURCES += [ 'nsISessionStore.idl', ] -MODULE = 'sessionstore' +XPIDL_MODULE = 'sessionstore' XPCSHELL_TESTS_MANIFESTS += [ 'test/unit/xpcshell.ini', diff --git a/browser/components/sessionstore/nsISessionStartup.idl b/browser/components/sessionstore/nsISessionStartup.idl index a8e786d03e96..a1121a76660a 100644 --- a/browser/components/sessionstore/nsISessionStartup.idl +++ b/browser/components/sessionstore/nsISessionStartup.idl @@ -10,7 +10,7 @@ * - and allows to restore everything into one window. */ -[scriptable, uuid(51f4b9f0-f3d2-11e2-bb62-2c24dd830245)] +[scriptable, uuid(6c79d4c1-f071-4c5c-a7fb-676adb144584)] interface nsISessionStartup: nsISupports { /** @@ -23,12 +23,18 @@ interface nsISessionStartup: nsISupports readonly attribute jsval state; /** - * Determines whether there is a pending session restore and makes sure that - * we're initialized before returning. If we're not yet this will read the - * session file synchronously. + * Determines whether there is a pending session restore. Should only be + * called after initialization has completed. */ boolean doRestore(); + /** + * Determines whether automatic session restoration is enabled for this + * launch of the browser. This does not include crash restoration, and will + * return false if restoration will only be caused by a crash. + */ + boolean isAutomaticRestoreEnabled(); + /** * Returns whether we will restore a session that ends up replacing the * homepage. The browser uses this to not start loading the homepage if diff --git a/browser/components/sessionstore/src/SessionFile.jsm b/browser/components/sessionstore/src/SessionFile.jsm index ad46237ffc05..9c059bb5e542 100644 --- a/browser/components/sessionstore/src/SessionFile.jsm +++ b/browser/components/sessionstore/src/SessionFile.jsm @@ -38,16 +38,10 @@ Cu.import("resource://gre/modules/AsyncShutdown.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "TelemetryStopwatch", "resource://gre/modules/TelemetryStopwatch.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "NetUtil", - "resource://gre/modules/NetUtil.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "FileUtils", - "resource://gre/modules/FileUtils.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "Task", "resource://gre/modules/Task.jsm"); XPCOMUtils.defineLazyServiceGetter(this, "Telemetry", "@mozilla.org/base/telemetry;1", "nsITelemetry"); -XPCOMUtils.defineLazyModuleGetter(this, "Deprecated", - "resource://gre/modules/Deprecated.jsm"); this.SessionFile = { /** @@ -56,15 +50,6 @@ this.SessionFile = { read: function () { return SessionFileInternal.read(); }, - /** - * Read the contents of the session file, synchronously. - */ - syncRead: function () { - Deprecated.warning( - "syncRead is deprecated and will be removed in a future version", - "https://bugzilla.mozilla.org/show_bug.cgi?id=532150") - return SessionFileInternal.syncRead(); - }, /** * Write the contents of the session file, asynchronously. */ @@ -161,60 +146,6 @@ let SessionFileInternal = { */ _isClosed: false, - /** - * Utility function to safely read a file synchronously. - * @param aPath - * A path to read the file from. - * @returns string if successful, undefined otherwise. - */ - readAuxSync: function (aPath) { - let text; - try { - let file = new FileUtils.File(aPath); - let chan = NetUtil.newChannel(file); - let stream = chan.open(); - text = NetUtil.readInputStreamToString(stream, stream.available(), - {charset: "utf-8"}); - } catch (e if e.result == Components.results.NS_ERROR_FILE_NOT_FOUND) { - // Ignore exceptions about non-existent files. - } catch (ex) { - // Any other error. - Cu.reportError(ex); - } finally { - return text; - } - }, - - /** - * Read the sessionstore file synchronously. - * - * This function is meant to serve as a fallback in case of race - * between a synchronous usage of the API and asynchronous - * initialization. - * - * In case if sessionstore.js file does not exist or is corrupted (something - * happened between backup and write), attempt to read the sessionstore.bak - * instead. - */ - syncRead: function () { - // Start measuring the duration of the synchronous read. - TelemetryStopwatch.start("FX_SESSION_RESTORE_SYNC_READ_FILE_MS"); - // First read the sessionstore.js. - let text = this.readAuxSync(this.path); - if (typeof text === "undefined") { - // If sessionstore.js does not exist or is corrupted, read sessionstore.bak. - text = this.readAuxSync(this.backupPath); - } - // Finish the telemetry probe and return an empty string. - TelemetryStopwatch.finish("FX_SESSION_RESTORE_SYNC_READ_FILE_MS"); - text = text || ""; - - // The worker needs to know the initial state read from - // disk so that writeLoadStateOnceAfterStartup() works. - SessionWorker.post("setInitialState", [text]); - return text; - }, - read: function () { return SessionWorker.post("read").then(msg => { this._recordTelemetry(msg.telemetry); diff --git a/browser/components/sessionstore/src/SessionWorker.js b/browser/components/sessionstore/src/SessionWorker.js index 0d50b2f4ab82..c62464265eed 100644 --- a/browser/components/sessionstore/src/SessionWorker.js +++ b/browser/components/sessionstore/src/SessionWorker.js @@ -73,30 +73,6 @@ let Agent = { // The path to sessionstore.bak backupPath: OS.Path.join(OS.Constants.Path.profileDir, "sessionstore.bak"), - /** - * This method is only intended to be called by SessionFile.syncRead() and - * can be removed when we're not supporting synchronous SessionStore - * initialization anymore. When sessionstore.js is read from disk - * synchronously the state string must be supplied to the worker manually by - * calling this method. - */ - setInitialState: function (aState) { - // SessionFile.syncRead() should not be called after startup has finished. - // Thus we also don't support any setInitialState() calls after we already - // wrote the loadState to disk. - if (this.hasWrittenLoadStateOnce) { - throw new Error("writeLoadStateOnceAfterStartup() must only be called once."); - } - - // Initial state might have been filled by read() already but yet we might - // be called by SessionFile.syncRead() before SessionStore.jsm had a chance - // to call writeLoadStateOnceAfterStartup(). It's safe to ignore - // setInitialState() calls if this happens. - if (!this.initialState) { - this.initialState = aState; - } - }, - /** * Read the session from disk. * In case sessionstore.js does not exist, attempt to read sessionstore.bak. diff --git a/browser/components/sessionstore/src/nsSessionStartup.js b/browser/components/sessionstore/src/nsSessionStartup.js index 5f4dc2145550..42e0987ff3e0 100644 --- a/browser/components/sessionstore/src/nsSessionStartup.js +++ b/browser/components/sessionstore/src/nsSessionStartup.js @@ -48,6 +48,9 @@ XPCOMUtils.defineLazyModuleGetter(this, "SessionFile", const STATE_RUNNING_STR = "running"; +// 'browser.startup.page' preference value to resume the previous session. +const BROWSER_STARTUP_RESUME_SESSION = 3; + function debug(aMsg) { aMsg = ("SessionStartup: " + aMsg).replace(/\S{80}/g, "$&\n"); Services.console.logStringMessage(aMsg); @@ -138,7 +141,7 @@ SessionStartup.prototype = { let doResumeSessionOnce = Services.prefs.getBoolPref("browser.sessionstore.resume_session_once"); let doResumeSession = doResumeSessionOnce || - Services.prefs.getIntPref("browser.startup.page") == 3; + Services.prefs.getIntPref("browser.startup.page") == BROWSER_STARTUP_RESUME_SESSION; // If this is a normal restore then throw away any previous session if (!doResumeSessionOnce) @@ -226,9 +229,9 @@ SessionStartup.prototype = { }, /** - * Determines whether there is a pending session restore and makes sure that - * we're initialized before returning. If we're not yet this will read the - * session file synchronously. + * Determines whether there is a pending session restore. Should only be + * called after initialization has completed. + * @throws Error if initialization is not complete yet. * @returns bool */ doRestore: function sss_doRestore() { @@ -236,6 +239,18 @@ SessionStartup.prototype = { return this._willRestore(); }, + /** + * Determines whether automatic session restoration is enabled for this + * launch of the browser. This does not include crash restoration. In + * particular, if session restore is configured to restore only in case of + * crash, this method returns false. + * @returns bool + */ + isAutomaticRestoreEnabled: function () { + return Services.prefs.getBoolPref("browser.sessionstore.resume_session_once") || + Services.prefs.getIntPref("browser.startup.page") == BROWSER_STARTUP_RESUME_SESSION; + }, + /** * Determines whether there is a pending session restore. * @returns bool @@ -275,20 +290,12 @@ SessionStartup.prototype = { return this._sessionType; }, - // Ensure that initialization is complete. - // If initialization is not complete yet, fall back to a synchronous - // initialization and kill ongoing asynchronous initialization + // Ensure that initialization is complete. If initialization is not complete + // yet, something is attempting to use the old synchronous initialization, + // throw an error. _ensureInitialized: function sss__ensureInitialized() { - try { - if (this._initialized) { - // Initialization is complete, nothing else to do - return; - } - let contents = SessionFile.syncRead(); - this._onSessionFileRead(contents); - } catch(ex) { - debug("ensureInitialized: could not read session " + ex + ", " + ex.stack); - throw ex; + if (!this._initialized) { + throw new Error("Session Store is not initialized."); } }, diff --git a/browser/components/sessionstore/test/browser_625016.js b/browser/components/sessionstore/test/browser_625016.js index b6263cd59abf..1f1c2d2b3d2a 100644 --- a/browser/components/sessionstore/test/browser_625016.js +++ b/browser/components/sessionstore/test/browser_625016.js @@ -40,17 +40,21 @@ function setup() { } function onSaveState() { + try { + ss.getWindowValue(newWin, "foobar"); + } catch (e) { + // The window is untracked which means that the saveState() call isn't the + // one we're waiting for. It's most likely been triggered by an async + // collection running in the background. + waitForSaveState(onSaveState); + return; + } + // Double check that we have no closed windows is(ss.getClosedWindowCount(), 0, "no closed windows on first save"); Services.obs.addObserver(observe1, "sessionstore-state-write", false); - try { - ss.getWindowValue(newWin, "foobar"); - } catch (e) { - ok(false, "window is untracked!"); - } - // Now close the new window, which should trigger another save event newWin.close(); } diff --git a/browser/components/sessionstore/test/browser_833286_atomic_backup.js b/browser/components/sessionstore/test/browser_833286_atomic_backup.js index f4d7ab41ac60..7f482273cbf3 100644 --- a/browser/components/sessionstore/test/browser_833286_atomic_backup.js +++ b/browser/components/sessionstore/test/browser_833286_atomic_backup.js @@ -104,11 +104,6 @@ function testReadBackup() { let ssDataRead = yield SessionFile.read(); is(ssDataRead, gSSData, "SessionFile.read read sessionstore.js correctly."); - // Read sessionstore.js with SessionFile.syncRead. - ssDataRead = SessionFile.syncRead(); - is(ssDataRead, gSSData, - "SessionFile.syncRead read sessionstore.js correctly."); - // Remove sessionstore.js to test fallback onto sessionstore.bak. yield OS.File.remove(path); ssExists = yield OS.File.exists(path); @@ -119,11 +114,6 @@ function testReadBackup() { is(ssDataRead, gSSBakData, "SessionFile.read read sessionstore.bak correctly."); - // Read sessionstore.bak with SessionFile.syncRead. - ssDataRead = SessionFile.syncRead(); - is(ssDataRead, gSSBakData, - "SessionFile.syncRead read sessionstore.bak correctly."); - nextTest(testBackupUnchanged); } diff --git a/browser/components/sessionstore/test/unit/test_startup_nosession_sync.js b/browser/components/sessionstore/test/unit/test_startup_nosession_sync.js deleted file mode 100644 index a06770a39ebd..000000000000 --- a/browser/components/sessionstore/test/unit/test_startup_nosession_sync.js +++ /dev/null @@ -1,15 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ - - -// Test nsISessionStartup.sessionType in the following scenario: -// - no sessionstore.js; -// - the session store has not been loaded yet, so we have to trigger -// synchronous fallback - -function run_test() { - do_get_profile(); - let startup = Cc["@mozilla.org/browser/sessionstartup;1"]. - getService(Ci.nsISessionStartup); - do_check_eq(startup.sessionType, Ci.nsISessionStartup.NO_SESSION); -} \ No newline at end of file diff --git a/browser/components/sessionstore/test/unit/test_startup_session_sync.js b/browser/components/sessionstore/test/unit/test_startup_session_sync.js deleted file mode 100644 index f8e56d3e9fa7..000000000000 --- a/browser/components/sessionstore/test/unit/test_startup_session_sync.js +++ /dev/null @@ -1,17 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ - - -// Test nsISessionStartup.sessionType in the following scenario: -// - valid sessionstore.js; -// - the session store has not been loaded yet, so we have to trigger -// synchronous fallback - -function run_test() { - let profd = do_get_profile(); - let source = do_get_file("data/sessionstore_valid.js"); - source.copyTo(profd, "sessionstore.js"); - let startup = Cc["@mozilla.org/browser/sessionstartup;1"]. - getService(Ci.nsISessionStartup); - do_check_eq(startup.sessionType, Ci.nsISessionStartup.DEFER_SESSION); -} \ No newline at end of file diff --git a/browser/components/sessionstore/test/unit/xpcshell.ini b/browser/components/sessionstore/test/unit/xpcshell.ini index 10737448add5..509e68905a8a 100644 --- a/browser/components/sessionstore/test/unit/xpcshell.ini +++ b/browser/components/sessionstore/test/unit/xpcshell.ini @@ -6,7 +6,5 @@ support-files = data/sessionstore_valid.js [test_backup.js] [test_backup_once.js] -[test_startup_nosession_sync.js] [test_startup_nosession_async.js] -[test_startup_session_sync.js] [test_startup_session_async.js] diff --git a/browser/components/shell/public/moz.build b/browser/components/shell/public/moz.build index 080193ce3aad..53f78cb6d1e0 100644 --- a/browser/components/shell/public/moz.build +++ b/browser/components/shell/public/moz.build @@ -17,5 +17,5 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa': 'nsIMacShellService.idl', ] -MODULE = 'shellservice' +XPIDL_MODULE = 'shellservice' diff --git a/browser/components/shell/src/moz.build b/browser/components/shell/src/moz.build index 46d508daf81c..d426904cc24d 100644 --- a/browser/components/shell/src/moz.build +++ b/browser/components/shell/src/moz.build @@ -4,8 +4,6 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -MODULE = 'shellservice' - if CONFIG['OS_ARCH'] == 'WINNT': SOURCES += [ 'nsWindowsShellService.cpp', @@ -20,11 +18,9 @@ elif CONFIG['MOZ_WIDGET_GTK']: ] if SOURCES: - LIBRARY_NAME = 'shellservice_s' + FINAL_LIBRARY = 'browsercomps' EXTRA_COMPONENTS += [ 'nsSetDefaultBrowser.js', 'nsSetDefaultBrowser.manifest', ] - -FORCE_STATIC_LIB = True diff --git a/browser/components/shell/src/nsWindowsShellService.cpp b/browser/components/shell/src/nsWindowsShellService.cpp index 30f9cf355d45..e0cc7ca6a12f 100644 --- a/browser/components/shell/src/nsWindowsShellService.cpp +++ b/browser/components/shell/src/nsWindowsShellService.cpp @@ -460,13 +460,13 @@ nsWindowsShellService::IsDefaultBrowser(bool aStartupCheck, // Close the key that was opened. ::RegCloseKey(theKey); if (REG_FAILED(res) || - !valueData.Equals(currValue, CaseInsensitiveCompare)) { + _wcsicmp(valueData.get(), currValue)) { // Key wasn't set or was set to something other than our registry entry. NS_ConvertUTF8toUTF16 oldValueData(settings->oldValueData); offset = oldValueData.Find("%APPPATH%"); oldValueData.Replace(offset, 9, appLongPath); // The current registry value doesn't match the current or the old format. - if (!oldValueData.Equals(currValue, CaseInsensitiveCompare)) { + if (_wcsicmp(oldValueData.get(), currValue)) { *aIsDefaultBrowser = false; return NS_OK; } @@ -579,7 +579,7 @@ nsWindowsShellService::IsDefaultBrowser(bool aStartupCheck, // Don't update the FTP protocol handler's shell open command when the // current registry value doesn't exist or matches the old format. if (REG_FAILED(res) || - !oldValueOpen.Equals(currValue, CaseInsensitiveCompare)) { + _wcsicmp(oldValueOpen.get(), currValue)) { ::RegCloseKey(theKey); return NS_OK; } diff --git a/browser/components/test/browser_bug538331.js b/browser/components/test/browser_bug538331.js index d559795db52a..eedaba1965b7 100644 --- a/browser/components/test/browser_bug538331.js +++ b/browser/components/test/browser_bug538331.js @@ -118,6 +118,10 @@ function test() { waitForExplicitFinish(); + // Reset the startup page pref since it may have been set by other tests + // and we will assume it is default. + Services.prefs.clearUserPref('browser.startup.page'); + if (gPrefService.prefHasUserValue(PREF_MSTONE)) { gOriginalMStone = gPrefService.getCharPref(PREF_MSTONE); } diff --git a/browser/devtools/debugger/debugger-controller.js b/browser/devtools/debugger/debugger-controller.js index f6ca29d0d5f4..0b70fd9a6770 100644 --- a/browser/devtools/debugger/debugger-controller.js +++ b/browser/devtools/debugger/debugger-controller.js @@ -1398,12 +1398,36 @@ EventListeners.prototype = { */ scheduleEventListenersFetch: function() { let getListeners = aCallback => gThreadClient.eventListeners(aResponse => { - this._onEventListeners(aResponse); + if (aResponse.error) { + let msg = "Error getting event listeners: " + aResponse.message; + DevToolsUtils.reportException("scheduleEventListenersFetch", msg); + return; + } - // Notify that event listeners were fetched and shown in the view, - // and callback to resume the active thread if necessary. - window.emit(EVENTS.EVENT_LISTENERS_FETCHED); - aCallback && aCallback(); + promise.all(aResponse.listeners.map(listener => { + const deferred = promise.defer(); + + gThreadClient.pauseGrip(listener.function).getDefinitionSite(aResponse => { + if (aResponse.error) { + const msg = "Error getting function definition site: " + aResponse.message; + DevToolsUtils.reportException("scheduleEventListenersFetch", msg); + deferred.reject(msg); + return; + } + + listener.function.url = aResponse.url; + deferred.resolve(listener); + }); + + return deferred.promise; + })).then(listeners => { + this._onEventListeners(listeners); + + // Notify that event listeners were fetched and shown in the view, + // and callback to resume the active thread if necessary. + window.emit(EVENTS.EVENT_LISTENERS_FETCHED); + aCallback && aCallback(); + }); }); // Make sure we're not sending a batch of closely repeated requests. @@ -1418,18 +1442,11 @@ EventListeners.prototype = { }, /** - * Callback for the debugger's active thread eventListeners() method. + * Callback for a debugger's successful active thread eventListeners() call. */ - _onEventListeners: function(aResponse) { - if (aResponse.error) { - let msg = "Error getting event listeners: " + aResponse.message; - Cu.reportError(msg); - dumpn(msg); - return; - } - + _onEventListeners: function(aListeners) { // Add all the listeners in the debugger view event linsteners container. - for (let listener of aResponse.listeners) { + for (let listener of aListeners) { DebuggerView.EventListeners.addListener(listener, { staged: true }); } diff --git a/browser/devtools/debugger/debugger-panes.js b/browser/devtools/debugger/debugger-panes.js index 1af08b2c9db4..82ef6a0b3bb7 100644 --- a/browser/devtools/debugger/debugger-panes.js +++ b/browser/devtools/debugger/debugger-panes.js @@ -1516,6 +1516,7 @@ WatchExpressionsView.prototype = Heritage.extend(WidgetMethods, { case e.DOM_VK_RETURN: case e.DOM_VK_ENTER: case e.DOM_VK_ESCAPE: + e.stopPropagation(); DebuggerView.editor.focus(); return; } diff --git a/browser/devtools/debugger/debugger-view.js b/browser/devtools/debugger/debugger-view.js index cdaba68164f8..666506f72799 100644 --- a/browser/devtools/debugger/debugger-view.js +++ b/browser/devtools/debugger/debugger-view.js @@ -189,11 +189,12 @@ let DebuggerView = { dumpn("Initializing the DebuggerView editor"); let extraKeys = {}; - let searchKey = document.getElementById("tokenSearchKey").getAttribute("key"); - extraKeys[Editor.accel(searchKey)] = (cm) => { - DebuggerView.Filtering._doTokenSearch(); - }; - + let tokenSearch = document.getElementById("tokenSearchKey").getAttribute("key"); + let globalSearch = document.getElementById("globalSearchKey").getAttribute("key"); + let tokenSearchShortcut = Editor.accel(tokenSearch); + let globalSearchShortcut = Editor.accel(globalSearch, { alt: true }); + extraKeys[tokenSearchShortcut] = () => this.Filtering._doTokenSearch(); + extraKeys[globalSearchShortcut] = () => this.Filtering._doGlobalSearch(); extraKeys[Editor.keyFor("jumpToLine")] = false; this.editor = new Editor({ diff --git a/browser/devtools/debugger/test/browser_dbg_event-listeners.js b/browser/devtools/debugger/test/browser_dbg_event-listeners.js index f4807c635645..83c2f2fd3176 100644 --- a/browser/devtools/debugger/test/browser_dbg_event-listeners.js +++ b/browser/devtools/debugger/test/browser_dbg_event-listeners.js @@ -60,55 +60,77 @@ function testEventListeners(aThreadClient) { let deferred = promise.defer(); aThreadClient.eventListeners(aPacket => { + if (aPacket.error) { + let msg = "Error getting event listeners: " + aPacket.message; + ok(false, msg); + deferred.reject(msg); + return; + } + is(aPacket.listeners.length, 3, "Found all event listeners."); - let types = []; + promise.all(aPacket.listeners.map(listener => { + const lDeferred = promise.defer(); + aThreadClient.pauseGrip(listener.function).getDefinitionSite(aResponse => { + if (aResponse.error) { + const msg = "Error getting function definition site: " + aResponse.message; + ok(false, msg); + lDeferred.reject(msg); + return; + } + listener.function.url = aResponse.url; + lDeferred.resolve(listener); + }); + return lDeferred.promise; + })).then(listeners => { + let types = []; - for (let l of aPacket.listeners) { - let node = l.node; - ok(node, "There is a node property."); - ok(node.object, "There is a node object property."); - ok(node.selector == "window" || - content.document.querySelectorAll(node.selector).length == 1, - "The node property is a unique CSS selector."); + for (let l of listeners) { + let node = l.node; + ok(node, "There is a node property."); + ok(node.object, "There is a node object property."); + ok(node.selector == "window" || + content.document.querySelectorAll(node.selector).length == 1, + "The node property is a unique CSS selector."); - let func = l.function; - ok(func, "There is a function property."); - is(func.type, "object", "The function form is of type 'object'."); - is(func.class, "Function", "The function form is of class 'Function'."); - is(func.url, TAB_URL, "The function url is correct."); + let func = l.function; + ok(func, "There is a function property."); + is(func.type, "object", "The function form is of type 'object'."); + is(func.class, "Function", "The function form is of class 'Function'."); + is(func.url, TAB_URL, "The function url is correct."); - is(l.allowsUntrusted, true, - "'allowsUntrusted' property has the right value."); - is(l.inSystemEventGroup, false, - "'inSystemEventGroup' property has the right value."); + is(l.allowsUntrusted, true, + "'allowsUntrusted' property has the right value."); + is(l.inSystemEventGroup, false, + "'inSystemEventGroup' property has the right value."); - types.push(l.type); + types.push(l.type); - if (l.type == "keyup") { - is(l.capturing, true, - "Capturing property has the right value."); - is(l.isEventHandler, false, - "'isEventHandler' property has the right value."); - } else if (l.type == "load") { - is(l.capturing, false, - "Capturing property has the right value."); - is(l.isEventHandler, false, - "'isEventHandler' property has the right value."); - } else { - is(l.capturing, false, - "Capturing property has the right value."); - is(l.isEventHandler, true, - "'isEventHandler' property has the right value."); + if (l.type == "keyup") { + is(l.capturing, true, + "Capturing property has the right value."); + is(l.isEventHandler, false, + "'isEventHandler' property has the right value."); + } else if (l.type == "load") { + is(l.capturing, false, + "Capturing property has the right value."); + is(l.isEventHandler, false, + "'isEventHandler' property has the right value."); + } else { + is(l.capturing, false, + "Capturing property has the right value."); + is(l.isEventHandler, true, + "'isEventHandler' property has the right value."); + } } - } - ok(types.indexOf("click") != -1, "Found the click handler."); - ok(types.indexOf("change") != -1, "Found the change handler."); - ok(types.indexOf("keyup") != -1, "Found the keyup handler."); + ok(types.indexOf("click") != -1, "Found the click handler."); + ok(types.indexOf("change") != -1, "Found the change handler."); + ok(types.indexOf("keyup") != -1, "Found the keyup handler."); - aThreadClient.resume(deferred.resolve); + aThreadClient.resume(deferred.resolve); + }); }); return deferred.promise; diff --git a/browser/devtools/debugger/test/head.js b/browser/devtools/debugger/test/head.js index f02257d1f2d3..4aaf7bd2bf38 100644 --- a/browser/devtools/debugger/test/head.js +++ b/browser/devtools/debugger/test/head.js @@ -35,6 +35,10 @@ registerCleanupFunction(function() { // Properly shut down the server to avoid memory leaks. DebuggerServer.destroy(); + + // Debugger tests use a lot of memory, so force a GC to help fragmentation. + info("Forcing GC after debugger test."); + Cu.forceGC(); }); // Import the GCLI test helper diff --git a/browser/devtools/devtools-clhandler.js b/browser/devtools/devtools-clhandler.js index 8ed267f1c906..0d071b9982de 100644 --- a/browser/devtools/devtools-clhandler.js +++ b/browser/devtools/devtools-clhandler.js @@ -30,7 +30,7 @@ devtoolsCommandlineHandler.prototype = { if (!window) { let devtools = Cu.import("resource://gre/modules/devtools/Loader.jsm", {}).devtools; // Load the browser devtools main module as the loader's main module. - devtools.main("main"); + Cu.import("resource:///modules/devtools/gDevTools.jsm"); let hudservice = devtools.require("devtools/webconsole/hudservice"); let console = Cu.import("resource://gre/modules/devtools/Console.jsm", {}).console; hudservice.toggleBrowserConsole().then(null, console.error); diff --git a/browser/devtools/fontinspector/test/browser.ini b/browser/devtools/fontinspector/test/browser.ini index c9f47cca0c18..68503270e7db 100644 --- a/browser/devtools/fontinspector/test/browser.ini +++ b/browser/devtools/fontinspector/test/browser.ini @@ -1,5 +1,6 @@ [DEFAULT] +support-files = + browser_font.woff + browser_fontinspector.html -[browser_font.woff] -[browser_fontinspector.html] [browser_fontinspector.js] diff --git a/browser/devtools/framework/gDevTools.jsm b/browser/devtools/framework/gDevTools.jsm index 1948bd3b8471..2b2c55865024 100644 --- a/browser/devtools/framework/gDevTools.jsm +++ b/browser/devtools/framework/gDevTools.jsm @@ -52,6 +52,7 @@ DevTools.prototype = { * - id: Unique identifier for this tool (string|required) * - visibilityswitch: Property name to allow us to hide this tool from the * DevTools Toolbox. + * A falsy value indicates that it cannot be hidden. * - icon: URL pointing to a graphic which will be used as the src for an * 16x16 img tag (string|required) * - url: URL pointing to a XUL/XHTML document containing the user interface @@ -69,8 +70,13 @@ DevTools.prototype = { throw new Error("Invalid definition.id"); } - toolDefinition.visibilityswitch = toolDefinition.visibilityswitch || - "devtools." + toolId + ".enabled"; + // Make sure that additional tools will always be able to be hidden. + // When being called from main.js, defaultTools has not yet been exported. + // But, we can assume that in this case, it is a default tool. + if (devtools.defaultTools && devtools.defaultTools.indexOf(toolDefinition) == -1) { + toolDefinition.visibilityswitch = "devtools." + toolId + ".enabled"; + } + this._tools.set(toolId, toolDefinition); this.emit("tool-registered", toolId); @@ -139,7 +145,7 @@ DevTools.prototype = { let tool = this._tools.get(toolId); if (!tool) { return null; - } else if (tool.id == "options") { + } else if (!tool.visibilityswitch) { return tool; } @@ -553,7 +559,8 @@ let gDevToolsBrowser = { // Skip if the tool is disabled. try { - if (!Services.prefs.getBoolPref(toolDefinition.visibilityswitch)) { + if (toolDefinition.visibilityswitch && + !Services.prefs.getBoolPref(toolDefinition.visibilityswitch)) { return; } } catch(e) {} diff --git a/browser/devtools/framework/test/browser.ini b/browser/devtools/framework/test/browser.ini index cd6d07899a37..f3172c4a7ef4 100644 --- a/browser/devtools/framework/test/browser.ini +++ b/browser/devtools/framework/test/browser.ini @@ -1,5 +1,8 @@ [DEFAULT] -support-files = head.js +support-files = + browser_toolbox_options_disablejs.html + browser_toolbox_options_disablejs_iframe.html + head.js [browser_devtools_api.js] [browser_dynamic_tool_enabling.js] @@ -10,9 +13,7 @@ support-files = head.js [browser_toolbox_highlight.js] [browser_toolbox_hosts.js] [browser_toolbox_options.js] -[browser_toolbox_options_disablejs.html] [browser_toolbox_options_disablejs.js] -[browser_toolbox_options_disablejs_iframe.html] [browser_toolbox_raise.js] skip-if = os == "win" [browser_toolbox_ready.js] diff --git a/browser/devtools/framework/test/browser_toolbox_options.js b/browser/devtools/framework/test/browser_toolbox_options.js index c4500aa5807a..725b3cf0ee04 100644 --- a/browser/devtools/framework/test/browser_toolbox_options.js +++ b/browser/devtools/framework/test/browser_toolbox_options.js @@ -105,8 +105,15 @@ function testToggleTools() { let toolNodes = panelWin.document.querySelectorAll("#default-tools-box > checkbox:not([unsupported])"); let enabledTools = Array.prototype.filter.call(toolNodes, node => node.checked); + let toggleableTools = gDevTools.getDefaultTools().filter(tool=>tool.visibilityswitch); + for (let node of toolNodes) { + let id = node.getAttribute("id"); + ok (toggleableTools.some(tool=>tool.id === id), + "There should be a toggle checkbox for: " + id); + } + // Store modified pref names so that they can be cleared on error. - for (let tool of gDevTools.getDefaultTools()) { + for (let tool of toggleableTools) { let pref = tool.visibilityswitch; modifiedPrefs.push(pref); } diff --git a/browser/devtools/framework/toolbox-options.js b/browser/devtools/framework/toolbox-options.js index a5465393d96b..6321fb8764d2 100644 --- a/browser/devtools/framework/toolbox-options.js +++ b/browser/devtools/framework/toolbox-options.js @@ -115,10 +115,10 @@ OptionsPanel.prototype = { }; // Populating the default tools lists - for (let tool of gDevTools.getDefaultTools()) { - if (tool.id == "options") { - continue; - } + let toggleableTools = gDevTools.getDefaultTools().filter(tool => { + return tool.visibilityswitch + }); + for (let tool of toggleableTools) { defaultToolsBox.appendChild(createToolCheckbox(tool)); } diff --git a/browser/devtools/framework/toolbox-options.xul b/browser/devtools/framework/toolbox-options.xul index 50567c6568f9..63dc3a35f6df 100644 --- a/browser/devtools/framework/toolbox-options.xul +++ b/browser/devtools/framework/toolbox-options.xul @@ -22,7 +22,7 @@