This commit is contained in:
Henri Sivonen 2009-06-26 18:22:48 +03:00
Родитель ec7a74cb9e 0858e6b05c
Коммит fb74340ed2
551 изменённых файлов: 34380 добавлений и 7156 удалений

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

@ -59,7 +59,6 @@ XPIDLSRCS = \
nsIAccessibleRole.idl \
nsIAccessibleStates.idl \
nsIAccessibleDocument.idl \
nsPIAccessibleDocument.idl \
nsIAccessibleProvider.idl \
nsIAccessibleSelectable.idl \
nsIAccessNode.idl \

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

@ -54,9 +54,7 @@
*
* There are no nsIAccessibleRole enums for the following landmark roles:
* banner, contentinfo, main, navigation, note, search, secondary, seealso, breadcrumbs
*/
static const nsStateMapEntry kEndEntry = {nsnull, 0, 0}; // To fill in array of state mappings
*/
nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
{
@ -67,8 +65,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eNoValue,
eNoAction,
eNoLiveAttr,
kNoReqStates,
kEndEntry
kNoReqStates
},
{
"alertdialog",
@ -77,8 +74,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eNoValue,
eNoAction,
eNoLiveAttr,
kNoReqStates,
kEndEntry
kNoReqStates
},
{
"application",
@ -87,8 +83,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eNoValue,
eNoAction,
eNoLiveAttr,
kNoReqStates,
kEndEntry
kNoReqStates
},
{
"article",
@ -97,8 +92,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eNoValue,
eNoAction,
eNoLiveAttr,
nsIAccessibleStates::STATE_READONLY,
kEndEntry
nsIAccessibleStates::STATE_READONLY
},
{
"button",
@ -108,9 +102,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eClickAction,
eNoLiveAttr,
kNoReqStates,
{&nsAccessibilityAtoms::aria_pressed, kBoolState, nsIAccessibleStates::STATE_PRESSED | nsIAccessibleStates::STATE_CHECKABLE},
{&nsAccessibilityAtoms::aria_pressed, "mixed", nsIAccessibleStates::STATE_MIXED | nsIAccessibleStates::STATE_CHECKABLE},
kEndEntry
eARIAPressed
},
{
"checkbox",
@ -119,11 +111,9 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eNoValue,
eCheckUncheckAction,
eNoLiveAttr,
nsIAccessibleStates::STATE_CHECKABLE,
{&nsAccessibilityAtoms::aria_checked, kBoolState, nsIAccessibleStates::STATE_CHECKED},
{&nsAccessibilityAtoms::aria_checked, "mixed", nsIAccessibleStates::STATE_MIXED},
{&nsAccessibilityAtoms::aria_readonly, kBoolState, nsIAccessibleStates::STATE_READONLY},
kEndEntry
kNoReqStates,
eARIACheckableMixed,
eARIAReadonly
},
{
"columnheader",
@ -133,10 +123,8 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eSortAction,
eNoLiveAttr,
kNoReqStates,
{&nsAccessibilityAtoms::aria_selected, kBoolState, nsIAccessibleStates::STATE_SELECTED | nsIAccessibleStates::STATE_SELECTABLE},
{&nsAccessibilityAtoms::aria_selected, "false", nsIAccessibleStates::STATE_SELECTABLE},
{&nsAccessibilityAtoms::aria_readonly, kBoolState, nsIAccessibleStates::STATE_READONLY},
kEndEntry
eARIASelected,
eARIAReadonly
},
{
"combobox",
@ -146,9 +134,8 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eOpenCloseAction,
eNoLiveAttr,
nsIAccessibleStates::STATE_COLLAPSED | nsIAccessibleStates::STATE_HASPOPUP,
// Manually map EXT_STATE_SUPPORTS_AUTOCOMPLETION aria-autocomplete
{&nsAccessibilityAtoms::aria_readonly, kBoolState, nsIAccessibleStates::STATE_READONLY},
kEndEntry
eARIAAutoComplete,
eARIAReadonly
},
{
"dialog",
@ -157,8 +144,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eNoValue,
eNoAction,
eNoLiveAttr,
kNoReqStates,
kEndEntry
kNoReqStates
},
{
"document",
@ -167,8 +153,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eNoValue,
eNoAction,
eNoLiveAttr,
nsIAccessibleStates::STATE_READONLY,
kEndEntry
nsIAccessibleStates::STATE_READONLY
},
{
"grid",
@ -178,9 +163,8 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eNoAction,
eNoLiveAttr,
nsIAccessibleStates::STATE_FOCUSABLE,
{&nsAccessibilityAtoms::aria_multiselectable, kBoolState, nsIAccessibleStates::STATE_MULTISELECTABLE | nsIAccessibleStates::STATE_EXTSELECTABLE},
{&nsAccessibilityAtoms::aria_readonly, kBoolState, nsIAccessibleStates::STATE_READONLY},
kEndEntry
eARIAMultiSelectable,
eARIAReadonly
},
{
"gridcell",
@ -190,10 +174,8 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eNoAction,
eNoLiveAttr,
kNoReqStates,
{&nsAccessibilityAtoms::aria_selected, kBoolState, nsIAccessibleStates::STATE_SELECTED | nsIAccessibleStates::STATE_SELECTABLE},
{&nsAccessibilityAtoms::aria_selected, "false", nsIAccessibleStates::STATE_SELECTABLE},
{&nsAccessibilityAtoms::aria_readonly, kBoolState, nsIAccessibleStates::STATE_READONLY},
kEndEntry
eARIASelected,
eARIAReadonly
},
{
"group",
@ -202,8 +184,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eNoValue,
eNoAction,
eNoLiveAttr,
kNoReqStates,
kEndEntry
kNoReqStates
},
{
"heading",
@ -212,8 +193,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eNoValue,
eNoAction,
eNoLiveAttr,
kNoReqStates,
kEndEntry
kNoReqStates
},
{
"img",
@ -222,8 +202,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eNoValue,
eNoAction,
eNoLiveAttr,
kNoReqStates,
kEndEntry
kNoReqStates
},
{
"label",
@ -232,8 +211,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eNoValue,
eNoAction,
eNoLiveAttr,
kNoReqStates,
kEndEntry
kNoReqStates
},
{
"link",
@ -242,8 +220,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eNoValue,
eJumpAction,
eNoLiveAttr,
nsIAccessibleStates::STATE_LINKED,
kEndEntry
nsIAccessibleStates::STATE_LINKED
},
{
"list",
@ -253,8 +230,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eNoAction,
eNoLiveAttr,
nsIAccessibleStates::STATE_READONLY,
{&nsAccessibilityAtoms::aria_multiselectable, kBoolState, nsIAccessibleStates::STATE_MULTISELECTABLE | nsIAccessibleStates::STATE_EXTSELECTABLE},
kEndEntry
eARIAMultiSelectable
},
{
"listbox",
@ -264,9 +240,8 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eNoAction,
eNoLiveAttr,
kNoReqStates,
{&nsAccessibilityAtoms::aria_readonly, kBoolState, nsIAccessibleStates::STATE_READONLY},
{&nsAccessibilityAtoms::aria_multiselectable, kBoolState, nsIAccessibleStates::STATE_MULTISELECTABLE | nsIAccessibleStates::STATE_EXTSELECTABLE},
kEndEntry
eARIAMultiSelectable,
eARIAReadonly
},
{
"listitem",
@ -276,12 +251,8 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eNoAction, // XXX: should depend on state, parent accessible
eNoLiveAttr,
nsIAccessibleStates::STATE_READONLY,
{&nsAccessibilityAtoms::aria_selected, kBoolState, nsIAccessibleStates::STATE_SELECTED | nsIAccessibleStates::STATE_SELECTABLE},
{&nsAccessibilityAtoms::aria_selected, "false", nsIAccessibleStates::STATE_SELECTABLE},
{&nsAccessibilityAtoms::aria_checked, kBoolState, nsIAccessibleStates::STATE_CHECKED | nsIAccessibleStates::STATE_CHECKABLE},
{&nsAccessibilityAtoms::aria_checked, "mixed", nsIAccessibleStates::STATE_MIXED | nsIAccessibleStates::STATE_CHECKABLE},
{&nsAccessibilityAtoms::aria_checked, "false", nsIAccessibleStates::STATE_CHECKABLE},
kEndEntry
eARIASelected,
eARIACheckedMixed
},
{
"log",
@ -290,8 +261,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eNoValue,
eNoAction,
ePoliteLiveAttr,
kNoReqStates,
kEndEntry
kNoReqStates
},
{
"marquee",
@ -300,8 +270,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eNoValue,
eNoAction,
eOffLiveAttr,
kNoReqStates,
kEndEntry
kNoReqStates
},
{
"math",
@ -310,8 +279,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eNoValue,
eNoAction,
eNoLiveAttr,
kNoReqStates,
kEndEntry
kNoReqStates
},
{
"menu",
@ -321,8 +289,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eNoAction, // XXX: technically accessibles of menupopup role haven't
// any action, but menu can be open or close.
eNoLiveAttr,
kNoReqStates,
kEndEntry
kNoReqStates
},
{
"menubar",
@ -331,8 +298,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eNoValue,
eNoAction,
eNoLiveAttr,
kNoReqStates,
kEndEntry
kNoReqStates
},
{
"menuitem",
@ -342,10 +308,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eClickAction,
eNoLiveAttr,
kNoReqStates,
{&nsAccessibilityAtoms::aria_checked, kBoolState, nsIAccessibleStates::STATE_CHECKED | nsIAccessibleStates::STATE_CHECKABLE},
{&nsAccessibilityAtoms::aria_checked, "mixed", nsIAccessibleStates::STATE_MIXED | nsIAccessibleStates::STATE_CHECKABLE},
{&nsAccessibilityAtoms::aria_checked, "false", nsIAccessibleStates::STATE_CHECKABLE},
kEndEntry
eARIACheckedMixed
},
{
"menuitemcheckbox",
@ -354,10 +317,8 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eNoValue,
eClickAction,
eNoLiveAttr,
nsIAccessibleStates::STATE_CHECKABLE,
{&nsAccessibilityAtoms::aria_checked, kBoolState, nsIAccessibleStates::STATE_CHECKED },
{&nsAccessibilityAtoms::aria_checked, "mixed", nsIAccessibleStates::STATE_MIXED},
kEndEntry
kNoReqStates,
eARIACheckableMixed
},
{
"menuitemradio",
@ -366,9 +327,8 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eNoValue,
eClickAction,
eNoLiveAttr,
nsIAccessibleStates::STATE_CHECKABLE,
{&nsAccessibilityAtoms::aria_checked, kBoolState, nsIAccessibleStates::STATE_CHECKED },
kEndEntry
kNoReqStates,
eARIACheckableBool
},
{
"option",
@ -378,12 +338,8 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eSelectAction,
eNoLiveAttr,
kNoReqStates,
{&nsAccessibilityAtoms::aria_selected, kBoolState, nsIAccessibleStates::STATE_SELECTED | nsIAccessibleStates::STATE_SELECTABLE},
{&nsAccessibilityAtoms::aria_selected, "false", nsIAccessibleStates::STATE_SELECTABLE},
{&nsAccessibilityAtoms::aria_checked, kBoolState, nsIAccessibleStates::STATE_CHECKED | nsIAccessibleStates::STATE_CHECKABLE},
{&nsAccessibilityAtoms::aria_checked, "mixed", nsIAccessibleStates::STATE_MIXED | nsIAccessibleStates::STATE_CHECKABLE},
{&nsAccessibilityAtoms::aria_checked, "false", nsIAccessibleStates::STATE_CHECKABLE},
kEndEntry
eARIASelected,
eARIACheckedMixed
},
{
"presentation",
@ -392,8 +348,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eNoValue,
eNoAction,
eNoLiveAttr,
kNoReqStates,
kEndEntry
kNoReqStates
},
{
"progressbar",
@ -402,8 +357,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eHasValueMinMax,
eNoAction,
eNoLiveAttr,
nsIAccessibleStates::STATE_READONLY,
kEndEntry
nsIAccessibleStates::STATE_READONLY
},
{
"radio",
@ -412,9 +366,8 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eNoValue,
eSelectAction,
eNoLiveAttr,
nsIAccessibleStates::STATE_CHECKABLE,
{&nsAccessibilityAtoms::aria_checked, kBoolState, nsIAccessibleStates::STATE_CHECKED},
kEndEntry
kNoReqStates,
eARIACheckableBool
},
{
"radiogroup",
@ -423,8 +376,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eNoValue,
eNoAction,
eNoLiveAttr,
kNoReqStates,
kEndEntry
kNoReqStates
},
{
"region",
@ -433,8 +385,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eNoValue,
eNoAction,
eNoLiveAttr,
kNoReqStates,
kEndEntry
kNoReqStates
},
{
"row",
@ -444,9 +395,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eNoAction,
eNoLiveAttr,
kNoReqStates,
{&nsAccessibilityAtoms::aria_selected, kBoolState, nsIAccessibleStates::STATE_SELECTED | nsIAccessibleStates::STATE_SELECTABLE},
{&nsAccessibilityAtoms::aria_selected, "false", nsIAccessibleStates::STATE_SELECTABLE},
kEndEntry
eARIASelected
},
{
"rowheader",
@ -456,10 +405,8 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eSortAction,
eNoLiveAttr,
kNoReqStates,
{&nsAccessibilityAtoms::aria_selected, kBoolState, nsIAccessibleStates::STATE_SELECTED | nsIAccessibleStates::STATE_SELECTABLE},
{&nsAccessibilityAtoms::aria_selected, "false", nsIAccessibleStates::STATE_SELECTABLE},
{&nsAccessibilityAtoms::aria_readonly, kBoolState, nsIAccessibleStates::STATE_READONLY},
kEndEntry
eARIASelected,
eARIAReadonly
},
{
"section",
@ -468,8 +415,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eNoValue,
eNoAction,
eNoLiveAttr,
kNoReqStates,
kEndEntry
kNoReqStates
},
{
"separator",
@ -478,8 +424,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eNoValue,
eNoAction,
eNoLiveAttr,
kNoReqStates,
kEndEntry
kNoReqStates
},
{
"slider",
@ -489,8 +434,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eNoAction,
eNoLiveAttr,
kNoReqStates,
{&nsAccessibilityAtoms::aria_readonly, kBoolState, nsIAccessibleStates::STATE_READONLY},
kEndEntry
eARIAReadonly
},
{
"spinbutton",
@ -500,8 +444,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eNoAction,
eNoLiveAttr,
kNoReqStates,
{&nsAccessibilityAtoms::aria_readonly, kBoolState, nsIAccessibleStates::STATE_READONLY},
kEndEntry
eARIAReadonly
},
{
"status",
@ -510,8 +453,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eNoValue,
eNoAction,
ePoliteLiveAttr,
kNoReqStates,
kEndEntry
kNoReqStates
},
{
"tab",
@ -520,8 +462,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eNoValue,
eSwitchAction,
eNoLiveAttr,
kNoReqStates,
kEndEntry
kNoReqStates
},
{
"tablist",
@ -530,8 +471,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eNoValue,
eNoAction,
ePoliteLiveAttr,
kNoReqStates,
kEndEntry
kNoReqStates
},
{
"tabpanel",
@ -540,8 +480,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eNoValue,
eNoAction,
eNoLiveAttr,
kNoReqStates,
kEndEntry
kNoReqStates
},
{
"textbox",
@ -551,12 +490,9 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eActivateAction,
eNoLiveAttr,
kNoReqStates,
// Manually map EXT_STATE_SINGLE_LINE and EXT_STATE_MULTI_LINE FROM aria-multiline
// Manually map EXT_STATE_SUPPORTS_AUTOCOMPLETION aria-autocomplete
{&nsAccessibilityAtoms::aria_autocomplete, "list", nsIAccessibleStates::STATE_HASPOPUP},
{&nsAccessibilityAtoms::aria_autocomplete, "both", nsIAccessibleStates::STATE_HASPOPUP},
{&nsAccessibilityAtoms::aria_readonly, kBoolState, nsIAccessibleStates::STATE_READONLY},
kEndEntry
eARIAAutoComplete,
eARIAMultiline,
eARIAReadonlyOrEditable
},
{
"timer",
@ -565,8 +501,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eNoValue,
eNoAction,
eOffLiveAttr,
kNoReqStates,
kEndEntry
kNoReqStates
},
{
"toolbar",
@ -575,8 +510,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eNoValue,
eNoAction,
eNoLiveAttr,
kNoReqStates,
kEndEntry
kNoReqStates
},
{
"tooltip",
@ -585,8 +519,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eNoValue,
eNoAction,
eNoLiveAttr,
kNoReqStates,
kEndEntry
kNoReqStates
},
{
"tree",
@ -596,9 +529,8 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eNoAction,
eNoLiveAttr,
kNoReqStates,
{&nsAccessibilityAtoms::aria_readonly, kBoolState, nsIAccessibleStates::STATE_READONLY},
{&nsAccessibilityAtoms::aria_multiselectable, kBoolState, nsIAccessibleStates::STATE_MULTISELECTABLE | nsIAccessibleStates::STATE_EXTSELECTABLE},
kEndEntry
eARIAReadonly,
eARIAMultiSelectable
},
{
"treegrid",
@ -608,9 +540,8 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
eNoAction,
eNoLiveAttr,
kNoReqStates,
{&nsAccessibilityAtoms::aria_readonly, kBoolState, nsIAccessibleStates::STATE_READONLY},
{&nsAccessibilityAtoms::aria_multiselectable, kBoolState, nsIAccessibleStates::STATE_MULTISELECTABLE | nsIAccessibleStates::STATE_EXTSELECTABLE},
kEndEntry
eARIAReadonly,
eARIAMultiSelectable
},
{
"treeitem",
@ -621,12 +552,8 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
// on states
eNoLiveAttr,
kNoReqStates,
{&nsAccessibilityAtoms::aria_selected, kBoolState, nsIAccessibleStates::STATE_SELECTED | nsIAccessibleStates::STATE_SELECTABLE},
{&nsAccessibilityAtoms::aria_selected, "false", nsIAccessibleStates::STATE_SELECTABLE},
{&nsAccessibilityAtoms::aria_checked, kBoolState, nsIAccessibleStates::STATE_CHECKED | nsIAccessibleStates::STATE_CHECKABLE},
{&nsAccessibilityAtoms::aria_checked, "mixed", nsIAccessibleStates::STATE_MIXED | nsIAccessibleStates::STATE_CHECKABLE},
{&nsAccessibilityAtoms::aria_checked, "false", nsIAccessibleStates::STATE_CHECKABLE},
kEndEntry
eARIASelected,
eARIACheckedMixed
}
};
@ -639,8 +566,7 @@ nsRoleMapEntry nsARIAMap::gLandmarkRoleMap = {
eNoValue,
eNoAction,
eNoLiveAttr,
kNoReqStates,
kEndEntry
kNoReqStates
};
nsRoleMapEntry nsARIAMap::gEmptyRoleMap = {
@ -650,8 +576,89 @@ nsRoleMapEntry nsARIAMap::gEmptyRoleMap = {
eNoValue,
eNoAction,
eNoLiveAttr,
kNoReqStates,
kEndEntry
kNoReqStates
};
nsStateMapEntry nsARIAMap::gWAIStateMap[] = {
// eARIANone
nsStateMapEntry(),
// eARIAAutoComplete
nsStateMapEntry(&nsAccessibilityAtoms::aria_autocomplete,
"inline", 0, nsIAccessibleStates::EXT_STATE_SUPPORTS_AUTOCOMPLETION,
"list", nsIAccessibleStates::STATE_HASPOPUP, nsIAccessibleStates::EXT_STATE_SUPPORTS_AUTOCOMPLETION,
"both", nsIAccessibleStates::STATE_HASPOPUP, nsIAccessibleStates::EXT_STATE_SUPPORTS_AUTOCOMPLETION),
// eARIABusy
nsStateMapEntry(&nsAccessibilityAtoms::aria_busy,
"true", nsIAccessibleStates::STATE_BUSY, 0,
"error", nsIAccessibleStates::STATE_INVALID, 0),
// eARIACheckableBool
nsStateMapEntry(&nsAccessibilityAtoms::aria_checked, kBoolType,
nsIAccessibleStates::STATE_CHECKABLE,
nsIAccessibleStates::STATE_CHECKED, 0,
0, 0, PR_TRUE),
// eARIACheckableMixed
nsStateMapEntry(&nsAccessibilityAtoms::aria_checked, kMixedType,
nsIAccessibleStates::STATE_CHECKABLE,
nsIAccessibleStates::STATE_CHECKED, 0,
0, 0, PR_TRUE),
// eARIACheckedMixed
nsStateMapEntry(&nsAccessibilityAtoms::aria_checked, kMixedType,
nsIAccessibleStates::STATE_CHECKABLE,
nsIAccessibleStates::STATE_CHECKED, 0),
// eARIADisabled
nsStateMapEntry(&nsAccessibilityAtoms::aria_disabled, kBoolType, 0,
nsIAccessibleStates::STATE_UNAVAILABLE, 0),
// eARIAExpanded
nsStateMapEntry(&nsAccessibilityAtoms::aria_expanded, kBoolType, 0,
nsIAccessibleStates::STATE_EXPANDED, 0,
nsIAccessibleStates::STATE_COLLAPSED, 0),
// eARIAHasPopup
nsStateMapEntry(&nsAccessibilityAtoms::aria_haspopup, kBoolType, 0,
nsIAccessibleStates::STATE_HASPOPUP, 0),
// eARIAInvalid
nsStateMapEntry(&nsAccessibilityAtoms::aria_invalid, kBoolType, 0,
nsIAccessibleStates::STATE_INVALID, 0),
// eARIAMultiline
nsStateMapEntry(&nsAccessibilityAtoms::aria_multiline, kBoolType, 0,
0, nsIAccessibleStates::EXT_STATE_MULTI_LINE,
0, nsIAccessibleStates::EXT_STATE_SINGLE_LINE, PR_TRUE),
// eARIAMultiSelectable
nsStateMapEntry(&nsAccessibilityAtoms::aria_multiselectable, kBoolType, 0,
nsIAccessibleStates::STATE_MULTISELECTABLE | nsIAccessibleStates::STATE_EXTSELECTABLE, 0),
// eARIAPressed
nsStateMapEntry(&nsAccessibilityAtoms::aria_pressed, kMixedType,
nsIAccessibleStates::STATE_CHECKABLE,
nsIAccessibleStates::STATE_PRESSED, 0),
// eARIAReadonly
nsStateMapEntry(&nsAccessibilityAtoms::aria_readonly, kBoolType, 0,
nsIAccessibleStates::STATE_READONLY, 0),
// eARIAReadonlyOrEditable
nsStateMapEntry(&nsAccessibilityAtoms::aria_readonly, kBoolType, 0,
nsIAccessibleStates::STATE_READONLY, 0,
0, nsIAccessibleStates::EXT_STATE_EDITABLE, PR_TRUE),
// eARIARequired
nsStateMapEntry(&nsAccessibilityAtoms::aria_required, kBoolType, 0,
nsIAccessibleStates::STATE_REQUIRED, 0),
// eARIASelected
nsStateMapEntry(&nsAccessibilityAtoms::aria_selected, kBoolType,
nsIAccessibleStates::STATE_SELECTABLE,
nsIAccessibleStates::STATE_SELECTED, 0)
};
/**
@ -659,16 +666,14 @@ nsRoleMapEntry nsARIAMap::gEmptyRoleMap = {
* The following state rules are applied to any accessible element,
* whether there is an ARIA role or not:
*/
nsStateMapEntry nsARIAMap::gWAIUnivStateMap[] = {
{&nsAccessibilityAtoms::aria_required, kBoolState, nsIAccessibleStates::STATE_REQUIRED},
{&nsAccessibilityAtoms::aria_invalid, kBoolState, nsIAccessibleStates::STATE_INVALID},
{&nsAccessibilityAtoms::aria_haspopup, kBoolState, nsIAccessibleStates::STATE_HASPOPUP},
{&nsAccessibilityAtoms::aria_busy, "true", nsIAccessibleStates::STATE_BUSY},
{&nsAccessibilityAtoms::aria_busy, "error", nsIAccessibleStates::STATE_INVALID},
{&nsAccessibilityAtoms::aria_disabled, kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
{&nsAccessibilityAtoms::aria_expanded, kBoolState, nsIAccessibleStates::STATE_EXPANDED},
{&nsAccessibilityAtoms::aria_expanded, "false", nsIAccessibleStates::STATE_COLLAPSED},
kEndEntry
eStateMapEntryID nsARIAMap::gWAIUnivStateMap[] = {
eARIARequired,
eARIAInvalid,
eARIAHasPopup,
eARIABusy,
eARIADisabled,
eARIAExpanded,
eARIANone
};
@ -709,3 +714,144 @@ nsAttributeCharacteristics nsARIAMap::gWAIUnivAttrMap[] = {
};
PRUint32 nsARIAMap::gWAIUnivAttrMapLength = NS_ARRAY_LENGTH(nsARIAMap::gWAIUnivAttrMap);
////////////////////////////////////////////////////////////////////////////////
// nsStateMapEntry
nsStateMapEntry:: nsStateMapEntry(nsIAtom **aAttrName, eStateValueType aType,
PRUint32 aPermanentState,
PRUint32 aTrueState, PRUint32 aTrueExtraState,
PRUint32 aFalseState, PRUint32 aFalseExtraState,
PRBool aDefinedIfAbsent) :
attributeName(aAttrName), isToken(PR_TRUE), permanentState(aPermanentState)
{
value1 = "false";
state1 = aFalseState;
extraState1 = aFalseExtraState;
if (aType == kMixedType) {
value2 = "mixed";
state2 = nsIAccessibleStates::STATE_MIXED;
extraState2 = 0;
}
defaultState = aTrueState;
defaultExtraState = aTrueExtraState;
definedIfAbsent = aDefinedIfAbsent;
}
nsStateMapEntry::nsStateMapEntry(nsIAtom **aAttrName,
const char *aValue1,
PRUint32 aState1, PRUint32 aExtraState1,
const char *aValue2,
PRUint32 aState2, PRUint32 aExtraState2,
const char *aValue3,
PRUint32 aState3, PRUint32 aExtraState3) :
attributeName(aAttrName), isToken(PR_FALSE), permanentState(0),
value1(aValue1), state1(aState1), extraState1(aExtraState1),
value2(aValue2), state2(aState2), extraState2(aExtraState2),
value3(aValue3), state3(aState3), extraState3(aExtraState3),
defaultState(0), defaultExtraState(0), definedIfAbsent(PR_FALSE)
{
}
PRBool
nsStateMapEntry::MapToStates(nsIContent *aContent,
PRUint32 *aState, PRUint32 *aExtraState,
eStateMapEntryID aStateMapEntryID)
{
// Return true if we should continue.
if (aStateMapEntryID == eARIANone)
return PR_FALSE;
const nsStateMapEntry& entry = nsARIAMap::gWAIStateMap[aStateMapEntryID];
if (entry.isToken) {
// If attribute is considered as defined when it's absent then let's act
// attribute value is "false" supposedly.
PRBool hasAttr = aContent->HasAttr(kNameSpaceID_None, *entry.attributeName);
if (entry.definedIfAbsent && !hasAttr) {
if (entry.permanentState)
*aState |= entry.permanentState;
if (entry.state1)
*aState |= entry.state1;
if (aExtraState && entry.extraState1)
*aExtraState |= entry.extraState1;
return PR_TRUE;
}
// We only have attribute state mappings for NMTOKEN (and boolean) based
// ARIA attributes. According to spec, a value of "undefined" is to be
// treated equivalent to "", or the absence of the attribute. We bail out
// for this case here.
// Note: If this method happens to be called with a non-token based
// attribute, for example: aria-label="" or aria-label="undefined", we will
// bail out and not explore a state mapping, which is safe.
if (!hasAttr ||
aContent->AttrValueIs(kNameSpaceID_None, *entry.attributeName,
nsAccessibilityAtoms::_empty, eCaseMatters) ||
aContent->AttrValueIs(kNameSpaceID_None, *entry.attributeName,
nsAccessibilityAtoms::_undefined, eCaseMatters)) {
if (entry.permanentState)
*aState &= ~entry.permanentState;
return PR_TRUE;
}
if (entry.permanentState)
*aState |= entry.permanentState;
}
nsAutoString attrValue;
if (!aContent->GetAttr(kNameSpaceID_None, *entry.attributeName, attrValue))
return PR_TRUE;
// Apply states for matched value. If no values was matched then apply default
// states.
PRBool applyDefaultStates = PR_TRUE;
if (entry.value1) {
if (attrValue.EqualsASCII(entry.value1)) {
applyDefaultStates = PR_FALSE;
if (entry.state1)
*aState |= entry.state1;
if (aExtraState && entry.extraState1)
*aExtraState |= entry.extraState1;
} else if (entry.value2) {
if (attrValue.EqualsASCII(entry.value2)) {
applyDefaultStates = PR_FALSE;
if (entry.state2)
*aState |= entry.state2;
if (aExtraState && entry.extraState2)
*aExtraState |= entry.extraState2;
} else if (entry.value3) {
if (attrValue.EqualsASCII(entry.value3)) {
applyDefaultStates = PR_FALSE;
if (entry.state3)
*aState |= entry.state3;
if (aExtraState && entry.extraState3)
*aExtraState |= entry.extraState3;
}
}
}
}
if (applyDefaultStates) {
if (entry.defaultState)
*aState |= entry.defaultState;
if (entry.defaultExtraState && aExtraState)
*aExtraState |= entry.defaultExtraState;
}
return PR_TRUE;
}

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

@ -43,14 +43,35 @@
#include "prtypes.h"
#include "nsAccessibilityAtoms.h"
// Is nsIAccessible value supported for this role or not?
#include "nsIContent.h"
////////////////////////////////////////////////////////////////////////////////
// Value constants
/**
* Used to define if role requires to expose nsIAccessibleValue.
*/
enum EValueRule
{
/**
* nsIAccessibleValue isn't exposed.
*/
eNoValue,
eHasValueMinMax // Supports value, min and max from aria-valuenow, aria-valuemin and aria-valuemax
/**
* nsIAccessibleValue is implemented, supports value, min and max from
* aria-valuenow, aria-valuemin and aria-valuemax.
*/
eHasValueMinMax
};
// Should we expose action based on the ARIA role?
////////////////////////////////////////////////////////////////////////////////
// Action constants
/**
* Used to define if the role requires to expose action.
*/
enum EActionRule
{
eNoAction,
@ -65,6 +86,13 @@ enum EActionRule
eSwitchAction
};
////////////////////////////////////////////////////////////////////////////////
// Live region constants
/**
* Used to define if role exposes default value of aria-live attribute.
*/
enum ELiveAttrRule
{
eNoLiveAttr,
@ -72,11 +100,23 @@ enum ELiveAttrRule
ePoliteLiveAttr
};
// Role mapping rule
////////////////////////////////////////////////////////////////////////////////
// Role constants
/**
* ARIA role overrides role from native markup.
*/
const PRBool kUseMapRole = PR_TRUE;
/**
* ARIA role doesn't override the role from native markup.
*/
const PRBool kUseNativeRole = PR_FALSE;
// ARIA attribute characteristic masks, grow as needed
////////////////////////////////////////////////////////////////////////////////
// ARIA attribute characteristic masks
/**
* This mask indicates the attribute should not be exposed as an object
@ -92,29 +132,132 @@ const PRUint8 ATTR_BYPASSOBJ = 0x0001;
*/
const PRUint8 ATTR_VALTOKEN = 0x0010;
// Used for an nsStateMapEntry if a given state attribute supports "true" and "false"
#define kBoolState 0
// Used in nsRoleMapEntry.state if no nsIAccessibleStates are automatic for a given role
#define kNoReqStates 0
// For this name and value pair, what is the nsIAccessibleStates mapping.
// nsStateMapEntry.state
struct nsStateMapEntry
{
nsIAtom** attributeName; // nsnull indicates last entry in map
const char* attributeValue; // magic value of kBoolState (0) means supports "true" and "false"
PRUint32 state; // If match, this is the nsIAccessibleStates to map to
};
// Small footprint storage of persistent aria attribute characteristics
/**
* Small footprint storage of persistent aria attribute characteristics.
*/
struct nsAttributeCharacteristics
{
nsIAtom** attributeName;
const PRUint8 characteristics;
};
// For each ARIA role, this maps the nsIAccessible information
////////////////////////////////////////////////////////////////////////////////
// State map entry
/**
* Used in nsRoleMapEntry.state if no nsIAccessibleStates are automatic for
* a given role.
*/
#define kNoReqStates 0
enum eStateValueType
{
kBoolType,
kMixedType
};
/**
* ID for state map entry, used in nsRoleMapEntry.
*/
enum eStateMapEntryID
{
eARIANone,
eARIAAutoComplete,
eARIABusy,
eARIACheckableBool,
eARIACheckableMixed,
eARIACheckedMixed,
eARIADisabled,
eARIAExpanded,
eARIAHasPopup,
eARIAInvalid,
eARIAMultiline,
eARIAMultiSelectable,
eARIAPressed,
eARIAReadonly,
eARIAReadonlyOrEditable,
eARIARequired,
eARIASelected
};
class nsStateMapEntry
{
public:
/**
* Used to create stub.
*/
nsStateMapEntry() {}
/**
* Used for ARIA attributes having boolean or mixed values.
*/
nsStateMapEntry(nsIAtom **aAttrName, eStateValueType aType,
PRUint32 aPermanentState,
PRUint32 aTrueState, PRUint32 aTrueExtraState,
PRUint32 aFalseState = 0, PRUint32 aFalseExtraState = 0,
PRBool aDefinedIfAbsent = PR_FALSE);
/**
* Used for ARIA attributes having enumerated values.
*/
nsStateMapEntry(nsIAtom **aAttrName,
const char *aValue1, PRUint32 aState1, PRUint32 aExtraState1,
const char *aValue2, PRUint32 aState2, PRUint32 aExtraState2,
const char *aValue3 = 0, PRUint32 aState3 = 0,
PRUint32 aExtraState3 = 0);
/**
* Maps ARIA state map pointed by state map entry ID to accessible states.
*
* @param aContent [in] node of the accessible
* @param aState [in/out] accessible states
* @param aExtraState [in/out] accessible extra states
* @param aStateMapEntryID [in] state map entry ID
* @return true if state map entry ID is valid
*/
static PRBool MapToStates(nsIContent *aContent,
PRUint32 *aState, PRUint32 *aExtraState,
eStateMapEntryID aStateMapEntryID);
private:
// ARIA attribute name
nsIAtom** attributeName;
// Indicates if attribute is token (can be undefined)
PRBool isToken;
// State applied always if attribute is defined
PRUint32 permanentState;
// States applied if attribute value is matched to the stored value
const char* value1;
PRUint32 state1;
PRUint32 extraState1;
const char* value2;
PRUint32 state2;
PRUint32 extraState2;
const char* value3;
PRUint32 state3;
PRUint32 extraState3;
// States applied if no stored values above are matched
PRUint32 defaultState;
PRUint32 defaultExtraState;
// Permanent and false states are applied if attribute is absent
PRBool definedIfAbsent;
};
////////////////////////////////////////////////////////////////////////////////
// Role map entry
/**
* For each ARIA role, this maps the nsIAccessible information.
*/
struct nsRoleMapEntry
{
// ARIA role: string representation such as "button"
@ -144,16 +287,15 @@ struct nsRoleMapEntry
// Currently you cannot have unlimited mappings, because
// a variable sized array would not allow the use of
// C++'s struct initialization feature.
nsStateMapEntry attributeMap1;
nsStateMapEntry attributeMap2;
nsStateMapEntry attributeMap3;
nsStateMapEntry attributeMap4;
nsStateMapEntry attributeMap5;
nsStateMapEntry attributeMap6;
nsStateMapEntry attributeMap7;
nsStateMapEntry attributeMap8;
eStateMapEntryID attributeMap1;
eStateMapEntryID attributeMap2;
eStateMapEntryID attributeMap3;
};
////////////////////////////////////////////////////////////////////////////////
// ARIA map
/**
* These are currently initialized (hardcoded) in nsARIAMap.cpp,
* and provide the mappings for WAI-ARIA roles and properties using the
@ -180,11 +322,16 @@ struct nsARIAMap
*/
static nsRoleMapEntry gEmptyRoleMap;
/**
* State map of ARIA state attributes.
*/
static nsStateMapEntry gWAIStateMap[];
/**
* State map of ARIA states applied to any accessible not depending on
* the role.
*/
static nsStateMapEntry gWAIUnivStateMap[];
static eStateMapEntryID gWAIUnivStateMap[];
/**
* Map of attribute to attribute characteristics.

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

@ -45,6 +45,7 @@
#include "nsAccessibleEventData.h"
#include "nsHyperTextAccessible.h"
#include "nsHTMLTableAccessible.h"
#include "nsDocAccessible.h"
#include "nsAccessibilityAtoms.h"
#include "nsAccessibleTreeWalker.h"
#include "nsAccessible.h"
@ -747,6 +748,26 @@ nsAccUtils::QueryAccessibleTable(nsIAccessibleTable *aAccessibleTable)
return accessible;
}
already_AddRefed<nsDocAccessible>
nsAccUtils::QueryAccessibleDocument(nsIAccessible *aAccessible)
{
nsDocAccessible* accessible = nsnull;
if (aAccessible)
CallQueryInterface(aAccessible, &accessible);
return accessible;
}
already_AddRefed<nsDocAccessible>
nsAccUtils::QueryAccessibleDocument(nsIAccessibleDocument *aAccessibleDocument)
{
nsDocAccessible* accessible = nsnull;
if (aAccessibleDocument)
CallQueryInterface(aAccessibleDocument, &accessible);
return accessible;
}
#ifdef DEBUG_A11Y
PRBool

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

@ -55,6 +55,7 @@
class nsAccessNode;
class nsAccessible;
class nsHTMLTableAccessible;
class nsDocAccessible;
class nsAccUtils
{
@ -340,7 +341,19 @@ public:
*/
static already_AddRefed<nsHTMLTableAccessible>
QueryAccessibleTable(nsIAccessibleTable *aAccessibleTable);
/**
* Query nsDocAccessible from the given nsIAccessible.
*/
static already_AddRefed<nsDocAccessible>
QueryAccessibleDocument(nsIAccessible *aAccessible);
/**
* Query nsDocAccessible from the given nsIAccessibleDocument.
*/
static already_AddRefed<nsDocAccessible>
QueryAccessibleDocument(nsIAccessibleDocument *aAccessibleDocument);
#ifdef DEBUG_A11Y
/**
* Detect whether the given accessible object implements nsIAccessibleText,

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

@ -42,7 +42,6 @@
#include "nsHashtable.h"
#include "nsIAccessibilityService.h"
#include "nsIAccessibleDocument.h"
#include "nsPIAccessibleDocument.h"
#include "nsIDocShell.h"
#include "nsIDocShellTreeItem.h"
#include "nsIDocument.h"
@ -192,10 +191,10 @@ nsAccessNode::Init()
void* uniqueID;
GetUniqueID(&uniqueID);
nsCOMPtr<nsPIAccessibleDocument> privateDocAccessible =
do_QueryInterface(docAccessible);
NS_ASSERTION(privateDocAccessible, "No private docaccessible for docaccessible");
privateDocAccessible->CacheAccessNode(uniqueID, this);
nsRefPtr<nsDocAccessible> docAcc =
nsAccUtils::QueryAccessibleDocument(docAccessible);
NS_ASSERTION(docAcc, "No nsDocAccessible for document accessible!");
docAcc->CacheAccessNode(uniqueID, this);
// Make sure an ancestor in real content is cached
// so that nsDocAccessible::RefreshNodes() can find the anonymous subtree to release when

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

@ -43,8 +43,7 @@
* This class wraps up the creation (and destruction) of the standard
* set of atoms used in the accessibility module. These objects
* are created when the are needed by accessibility is being used and they
* are destroyed when the last nsRootAccessible is destroyed via
* nsRootAccessible::ShutdownAll()
* are destroyed when the last nsRootAccessible is destroyed.
*/
class nsAccessibilityAtoms {

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

@ -242,9 +242,11 @@ NS_IMETHODIMP nsAccessibilityService::ProcessDocLoadEvent(nsITimer *aTimer, void
nsCOMPtr<nsIAccessible> accessible;
GetAccessibleFor(docNode, getter_AddRefs(accessible));
nsCOMPtr<nsPIAccessibleDocument> privDocAccessible = do_QueryInterface(accessible);
NS_ENSURE_STATE(privDocAccessible);
privDocAccessible->FireDocLoadEvents(aEventType);
nsRefPtr<nsDocAccessible> docAcc =
nsAccUtils::QueryAccessibleDocument(accessible);
NS_ENSURE_STATE(docAcc);
docAcc->FireDocLoadEvents(aEventType);
return NS_OK;
}
@ -307,12 +309,12 @@ NS_IMETHODIMP nsAccessibilityService::OnLocationChange(nsIWebProgress *aWebProgr
nsCOMPtr<nsIAccessibleDocument> accessibleDoc =
nsAccessNode::GetDocAccessibleFor(domDocRootNode);
nsCOMPtr<nsPIAccessibleDocument> privateAccessibleDoc =
do_QueryInterface(accessibleDoc);
if (!privateAccessibleDoc) {
return NS_OK;
}
return privateAccessibleDoc->FireAnchorJumpEvent();
nsRefPtr<nsDocAccessible> docAcc =
nsAccUtils::QueryAccessibleDocument(accessibleDoc);
if (docAcc)
docAcc->FireAnchorJumpEvent();
return NS_OK;
}
/* void onStatusChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsresult aStatus, in wstring aMessage); */
@ -2040,12 +2042,12 @@ NS_IMETHODIMP nsAccessibilityService::InvalidateSubtreeFor(nsIPresShell *aShell,
NS_ENSURE_ARG_POINTER(aShell);
nsCOMPtr<nsIAccessibleDocument> accessibleDoc =
nsAccessNode::GetDocAccessibleFor(aShell->GetDocument());
nsCOMPtr<nsPIAccessibleDocument> privateAccessibleDoc =
do_QueryInterface(accessibleDoc);
if (!privateAccessibleDoc) {
return NS_OK;
}
return privateAccessibleDoc->InvalidateCacheSubtree(aChangeContent, aEvent);
nsRefPtr<nsDocAccessible> docAcc =
nsAccUtils::QueryAccessibleDocument(accessibleDoc);
if (docAcc)
docAcc->InvalidateCacheSubtree(aChangeContent, aEvent);
return NS_OK;
}
//////////////////////////////////////////////////////////////////////

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

@ -281,7 +281,7 @@ nsAccessible::GetName(nsAString& aName)
nsCOMPtr<nsIXBLAccessible> xblAccessible(do_QueryInterface(mDOMNode));
if (xblAccessible) {
nsresult rv = xblAccessible->GetAccessibleName(aName);
xblAccessible->GetAccessibleName(aName);
if (!aName.IsEmpty())
return NS_OK;
}
@ -1891,45 +1891,6 @@ nsAccessible::GroupPosition(PRInt32 *aGroupLevel,
return NS_OK;
}
PRBool nsAccessible::MappedAttrState(nsIContent *aContent, PRUint32 *aStateInOut,
nsStateMapEntry *aStateMapEntry)
{
// Return true if we should continue
if (!aStateMapEntry->attributeName) {
return PR_FALSE; // Stop looking -- no more states
}
// We only have attribute state mappings for NMTOKEN (and boolean) based
// ARIA attributes. According to spec, a value of "undefined" is to be
// treated equivalent to "", or the absence of the attribute. We bail out
// for this case here.
// Note: If this method happens to be called with a non-token based
// attribute, for example: aria-label="" or aria-label="undefined", we will
// bail out and not explore a state mapping, which is safe.
if (!nsAccUtils::HasDefinedARIAToken(aContent, *aStateMapEntry->attributeName)) {
return PR_TRUE;
}
nsAutoString attribValue;
if (aContent->GetAttr(kNameSpaceID_None, *aStateMapEntry->attributeName, attribValue)) {
if (aStateMapEntry->attributeValue == kBoolState) {
// No attribute value map specified in state map entry indicates state cleared
if (attribValue.EqualsLiteral("false") ||
attribValue.EqualsLiteral("mixed")) {
*aStateInOut &= ~aStateMapEntry->state;
}
else {
*aStateInOut |= aStateMapEntry->state;
}
}
else if (NS_ConvertUTF16toUTF8(attribValue).Equals(aStateMapEntry->attributeValue)) {
*aStateInOut |= aStateMapEntry->state;
}
}
return PR_TRUE;
}
NS_IMETHODIMP
nsAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
{
@ -1947,7 +1908,7 @@ nsAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
NS_ENSURE_A11Y_SUCCESS(rv, rv);
// Apply ARIA states to be sure accessible states will be overriden.
GetARIAState(aState);
GetARIAState(aState, aExtraState);
if (mRoleMapEntry && mRoleMapEntry->role == nsIAccessibleRole::ROLE_PAGETAB) {
if (*aState & nsIAccessibleStates::STATE_FOCUSED) {
@ -2019,33 +1980,6 @@ nsAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
rv = GetRole(&role);
NS_ENSURE_SUCCESS(rv, rv);
if (role == nsIAccessibleRole::ROLE_ENTRY ||
role == nsIAccessibleRole::ROLE_COMBOBOX) {
nsCOMPtr<nsIContent> content = nsCoreUtils::GetRoleContent(mDOMNode);
NS_ENSURE_STATE(content);
nsAutoString autocomplete;
if (content->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_autocomplete, autocomplete) &&
(autocomplete.EqualsIgnoreCase("inline") ||
autocomplete.EqualsIgnoreCase("list") ||
autocomplete.EqualsIgnoreCase("both"))) {
*aExtraState |= nsIAccessibleStates::EXT_STATE_SUPPORTS_AUTOCOMPLETION;
}
// XXX We can remove this hack once we support RDF-based role & state maps
if (mRoleMapEntry && mRoleMapEntry->role == nsIAccessibleRole::ROLE_ENTRY) {
PRBool isMultiLine = content->AttrValueIs(kNameSpaceID_None, nsAccessibilityAtoms::aria_multiline,
nsAccessibilityAtoms::_true, eCaseMatters);
*aExtraState |= isMultiLine ? nsIAccessibleStates::EXT_STATE_MULTI_LINE :
nsIAccessibleStates::EXT_STATE_SINGLE_LINE;
if (0 == (*aState & nsIAccessibleStates::STATE_READONLY))
*aExtraState |= nsIAccessibleStates::EXT_STATE_EDITABLE; // Not readonly
else // We're readonly: make sure editable state wasn't set by impl class
*aExtraState &= ~nsIAccessibleStates::EXT_STATE_EDITABLE;
}
}
// For some reasons DOM node may have not a frame. We tract such accessibles
// as invisible.
nsIFrame *frame = GetFrame();
@ -2077,7 +2011,7 @@ nsAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
}
nsresult
nsAccessible::GetARIAState(PRUint32 *aState)
nsAccessible::GetARIAState(PRUint32 *aState, PRUint32 *aExtraState)
{
// Test for universal states first
nsIContent *content = nsCoreUtils::GetRoleContent(mDOMNode);
@ -2086,7 +2020,8 @@ nsAccessible::GetARIAState(PRUint32 *aState)
}
PRUint32 index = 0;
while (MappedAttrState(content, aState, &nsARIAMap::gWAIUnivStateMap[index])) {
while (nsStateMapEntry::MapToStates(content, aState, aExtraState,
nsARIAMap::gWAIUnivStateMap[index])) {
++ index;
}
@ -2126,14 +2061,12 @@ nsAccessible::GetARIAState(PRUint32 *aState)
// Note: the readonly bitflag will be overridden later if content is editable
*aState |= mRoleMapEntry->state;
if (MappedAttrState(content, aState, &mRoleMapEntry->attributeMap1) &&
MappedAttrState(content, aState, &mRoleMapEntry->attributeMap2) &&
MappedAttrState(content, aState, &mRoleMapEntry->attributeMap3) &&
MappedAttrState(content, aState, &mRoleMapEntry->attributeMap4) &&
MappedAttrState(content, aState, &mRoleMapEntry->attributeMap5) &&
MappedAttrState(content, aState, &mRoleMapEntry->attributeMap6) &&
MappedAttrState(content, aState, &mRoleMapEntry->attributeMap7)) {
MappedAttrState(content, aState, &mRoleMapEntry->attributeMap8);
if (nsStateMapEntry::MapToStates(content, aState, aExtraState,
mRoleMapEntry->attributeMap1) &&
nsStateMapEntry::MapToStates(content, aState, aExtraState,
mRoleMapEntry->attributeMap2)) {
nsStateMapEntry::MapToStates(content, aState, aExtraState,
mRoleMapEntry->attributeMap3);
}
return NS_OK;

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

@ -148,8 +148,9 @@ public:
* method.
*
* @param [in/out] where to fill the states into.
* @param [in/out] where to fill the extra states into
*/
virtual nsresult GetARIAState(PRUint32 *aState);
virtual nsresult GetARIAState(PRUint32 *aState, PRUint32 *aExtraState);
/**
* Returns the accessible name provided by native markup. It doesn't take
@ -279,7 +280,6 @@ public:
}
protected:
PRBool MappedAttrState(nsIContent *aContent, PRUint32 *aStateInOut, nsStateMapEntry *aStateMapEntry);
virtual nsIFrame* GetBoundsFrame();
virtual void GetBoundsRect(nsRect& aRect, nsIFrame** aRelativeFrame);
PRBool IsVisible(PRBool *aIsOffscreen);

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

@ -385,6 +385,9 @@ nsAccEvent::ApplyEventRules(nsCOMArray<nsIAccessibleEvent> &aEventsToFire)
}
}
} break; // case eRemoveDupes
default:
break; // case eAllowDupes, eDoNotEmit
} // switch
} // for (tail)
}

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

@ -78,8 +78,8 @@ PRBool
nsCoreUtils::HasListener(nsIContent *aContent, const nsAString& aEventType)
{
NS_ENSURE_TRUE(aContent, PR_FALSE);
nsCOMPtr<nsIEventListenerManager> listenerManager;
aContent->GetListenerManager(PR_FALSE, getter_AddRefs(listenerManager));
nsIEventListenerManager* listenerManager =
aContent->GetListenerManager(PR_FALSE);
return listenerManager && listenerManager->HasListenersFor(aEventType);
}
@ -201,7 +201,7 @@ nsCoreUtils::GetDOMNodeFromDOMPoint(nsIDOMNode *aNode, PRUint32 aOffset)
nsCOMPtr<nsIContent> content(do_QueryInterface(aNode));
if (content && content->IsNodeOfType(nsINode::eELEMENT)) {
PRInt32 childCount = static_cast<PRInt32>(content->GetChildCount());
PRUint32 childCount = content->GetChildCount();
NS_ASSERTION(aOffset >= 0 && aOffset <= childCount,
"Wrong offset of the DOM point!");

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

@ -150,6 +150,18 @@ ElementTraverser(const void *aKey, nsIAccessNode *aAccessNode,
return PL_DHASH_NEXT;
}
// What we want is: NS_INTERFACE_MAP_ENTRY(self) for static IID accessors,
// but some of our classes have an ambiguous base class of nsISupports which
// prevents this from working (the default macro converts it to nsISupports,
// then addrefs it, then returns it). Therefore, we expand the macro here and
// change it so that it works. Yuck.
#define NS_INTERFACE_MAP_STATIC_AMBIGUOUS(_class) \
if (aIID.Equals(NS_GET_IID(_class))) { \
NS_ADDREF(this); \
*aInstancePtr = this; \
return NS_OK; \
} else
NS_IMPL_CYCLE_COLLECTION_CLASS(nsDocAccessible)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsDocAccessible, nsAccessible)
@ -163,14 +175,14 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsDocAccessible, nsAccessible)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsDocAccessible)
NS_INTERFACE_MAP_STATIC_AMBIGUOUS(nsDocAccessible)
NS_INTERFACE_MAP_ENTRY(nsIAccessibleDocument)
NS_INTERFACE_MAP_ENTRY(nsPIAccessibleDocument)
NS_INTERFACE_MAP_ENTRY(nsIDocumentObserver)
NS_INTERFACE_MAP_ENTRY(nsIMutationObserver)
NS_INTERFACE_MAP_ENTRY(nsIScrollPositionListener)
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIAccessibleDocument)
NS_INTERFACE_MAP_ENTRY(nsIObserver)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIAccessibleDocument)
NS_INTERFACE_MAP_END_INHERITING(nsHyperTextAccessible)
NS_IMPL_ADDREF_INHERITED(nsDocAccessible, nsHyperTextAccessible)
@ -328,16 +340,16 @@ nsDocAccessible::GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState)
}
nsresult
nsDocAccessible::GetARIAState(PRUint32 *aState)
nsDocAccessible::GetARIAState(PRUint32 *aState, PRUint32 *aExtraState)
{
// Combine with states from outer doc
NS_ENSURE_ARG_POINTER(aState);
nsresult rv = nsAccessible::GetARIAState(aState);
nsresult rv = nsAccessible::GetARIAState(aState, aExtraState);
NS_ENSURE_SUCCESS(rv, rv);
nsRefPtr<nsAccessible> parent = nsAccUtils::QueryAccessible(mParent);
if (parent) // Allow iframe/frame etc. to have final state override via ARIA
return parent->GetARIAState(aState);
return parent->GetARIAState(aState, aExtraState);
return rv;
}
@ -553,7 +565,7 @@ NS_IMETHODIMP nsDocAccessible::GetCachedAccessNode(void *aUniqueID, nsIAccessNod
return NS_OK;
}
NS_IMETHODIMP
void
nsDocAccessible::CacheAccessNode(void *aUniqueID, nsIAccessNode *aAccessNode)
{
// If there is an access node for the given unique ID then let's shutdown it.
@ -568,7 +580,6 @@ nsDocAccessible::CacheAccessNode(void *aUniqueID, nsIAccessNode *aAccessNode)
}
PutCacheEntry(mAccessNodeCache, aUniqueID, aAccessNode);
return NS_OK;
}
NS_IMETHODIMP nsDocAccessible::GetParent(nsIAccessible **aParent)
@ -692,6 +703,15 @@ nsDocAccessible::GetFrame()
return root;
}
PRBool
nsDocAccessible::IsDefunct()
{
if (nsHyperTextAccessibleWrap::IsDefunct())
return PR_TRUE;
return !mDocument;
}
void nsDocAccessible::GetBoundsRect(nsRect& aBounds, nsIFrame** aRelativeFrame)
{
*aRelativeFrame = GetFrame();
@ -822,11 +842,12 @@ nsresult nsDocAccessible::RemoveEventListeners()
return NS_OK;
}
NS_IMETHODIMP nsDocAccessible::FireAnchorJumpEvent()
void
nsDocAccessible::FireAnchorJumpEvent()
{
if (!mIsContentLoaded || !mDocument) {
return NS_OK;
}
if (!mIsContentLoaded || !mDocument)
return;
nsCOMPtr<nsISupports> container = mDocument->GetContainer();
nsCOMPtr<nsIWebNavigation> webNav(do_GetInterface(container));
nsCAutoString theURL;
@ -854,15 +875,13 @@ NS_IMETHODIMP nsDocAccessible::FireAnchorJumpEvent()
mIsAnchorJumped = PR_TRUE;
lastAnchor.Assign(currentAnchor);
}
return NS_OK;
}
NS_IMETHODIMP nsDocAccessible::FireDocLoadEvents(PRUint32 aEventType)
void
nsDocAccessible::FireDocLoadEvents(PRUint32 aEventType)
{
if (!mDocument || !mWeakShell) {
return NS_OK; // Document has been shut down
}
if (IsDefunct())
return;
PRBool isFinished =
(aEventType == nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_COMPLETE ||
@ -871,15 +890,16 @@ NS_IMETHODIMP nsDocAccessible::FireDocLoadEvents(PRUint32 aEventType)
mIsContentLoaded = isFinished;
if (isFinished) {
if (mIsLoadCompleteFired)
return NS_OK;
return;
mIsLoadCompleteFired = PR_TRUE;
}
nsCOMPtr<nsIDocShellTreeItem> treeItem =
nsCoreUtils::GetDocShellTreeItemFor(mDOMNode);
if (!treeItem) {
return NS_OK;
}
if (!treeItem)
return;
nsCOMPtr<nsIDocShellTreeItem> sameTypeRoot;
treeItem->GetSameTypeRootTreeItem(getter_AddRefs(sameTypeRoot));
@ -928,7 +948,6 @@ NS_IMETHODIMP nsDocAccessible::FireDocLoadEvents(PRUint32 aEventType)
nsAccUtils::FireAccEvent(aEventType, this);
}
return NS_OK;
}
void nsDocAccessible::ScrollTimerCallback(nsITimer *aTimer, void *aClosure)
@ -1569,14 +1588,14 @@ nsDocAccessible::FireDelayedAccessibleEvent(nsIAccessibleEvent *aEvent)
// so that event gets fired via FlushEventsCallback
NS_ADDREF_THIS(); // Kung fu death grip to prevent crash in callback
mFireEventTimer->InitWithFuncCallback(FlushEventsCallback,
static_cast<nsPIAccessibleDocument*>(this),
0, nsITimer::TYPE_ONE_SHOT);
this, 0, nsITimer::TYPE_ONE_SHOT);
}
return NS_OK;
}
NS_IMETHODIMP nsDocAccessible::FlushPendingEvents()
void
nsDocAccessible::FlushPendingEvents()
{
mInFlushPendingEvents = PR_TRUE;
PRUint32 length = mEventsToFire.Count();
@ -1685,12 +1704,12 @@ NS_IMETHODIMP nsDocAccessible::FlushPendingEvents()
if (accessible) {
if (eventType == nsIAccessibleEvent::EVENT_INTERNAL_LOAD) {
nsCOMPtr<nsPIAccessibleDocument> docAccessible =
do_QueryInterface(accessible);
NS_ASSERTION(docAccessible, "No doc accessible for doc load event");
if (docAccessible) {
docAccessible->FireDocLoadEvents(nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_COMPLETE);
}
nsRefPtr<nsDocAccessible> docAcc =
nsAccUtils::QueryAccessibleDocument(accessible);
NS_ASSERTION(docAcc, "No doc accessible for doc load event");
if (docAcc)
docAcc->FireDocLoadEvents(nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_COMPLETE);
}
else if (eventType == nsIAccessibleEvent::EVENT_TEXT_CARET_MOVED) {
nsCOMPtr<nsIAccessibleText> accessibleText = do_QueryInterface(accessible);
@ -1759,12 +1778,11 @@ NS_IMETHODIMP nsDocAccessible::FlushPendingEvents()
nsAccEvent::ResetLastInputState();
mInFlushPendingEvents = PR_FALSE;
return NS_OK;
}
void nsDocAccessible::FlushEventsCallback(nsITimer *aTimer, void *aClosure)
{
nsPIAccessibleDocument *accessibleDoc = static_cast<nsPIAccessibleDocument*>(aClosure);
nsDocAccessible *accessibleDoc = static_cast<nsDocAccessible*>(aClosure);
NS_ASSERTION(accessibleDoc, "How did we get here without an accessible document?");
if (accessibleDoc) {
// A lot of crashes were happening here, so now we're reffing the doc
@ -1880,8 +1898,9 @@ void nsDocAccessible::RefreshNodes(nsIDOMNode *aStartNode)
mAccessNodeCache.Remove(uniqueID);
}
NS_IMETHODIMP nsDocAccessible::InvalidateCacheSubtree(nsIContent *aChild,
PRUint32 aChangeEventType)
void
nsDocAccessible::InvalidateCacheSubtree(nsIContent *aChild,
PRUint32 aChangeEventType)
{
PRBool isHiding =
aChangeEventType == nsIAccessibleEvent::EVENT_ASYNCH_HIDE ||
@ -1908,11 +1927,12 @@ NS_IMETHODIMP nsDocAccessible::InvalidateCacheSubtree(nsIContent *aChild,
// instead of just the accessible tree, although that would be faster
// Otherwise we might miss the nsAccessNode's that are not nsAccessible's.
NS_ENSURE_TRUE(mDOMNode, NS_ERROR_FAILURE);
NS_ENSURE_TRUE(mDOMNode,);
nsCOMPtr<nsIDOMNode> childNode = aChild ? do_QueryInterface(aChild) : mDOMNode;
nsCOMPtr<nsIPresShell> presShell = GetPresShell();
NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE);
NS_ENSURE_TRUE(presShell,);
if (!mIsContentLoaded) {
// Still loading document
@ -1925,10 +1945,12 @@ NS_IMETHODIMP nsDocAccessible::InvalidateCacheSubtree(nsIContent *aChild,
// Leave early, and ensure mAccChildCount stays uninitialized instead of 0,
// which it is if anyone asks for its children right now.
InvalidateChildren();
return NS_OK;
return;
}
nsIEventStateManager *esm = presShell->GetPresContext()->EventStateManager();
NS_ENSURE_TRUE(esm, NS_ERROR_FAILURE);
NS_ENSURE_TRUE(esm,);
if (!esm->IsHandlingUserInputExternal()) {
// Changes during page load, but not caused by user input
// Just invalidate accessible hierarchy and return,
@ -1942,7 +1964,7 @@ NS_IMETHODIMP nsDocAccessible::InvalidateCacheSubtree(nsIContent *aChild,
nsRefPtr<nsAccessible> containerAcc =
nsAccUtils::QueryAccessible(containerAccessible);
containerAcc->InvalidateChildren();
return NS_OK;
return;
}
// else: user input, so we must fall through and for full handling,
// e.g. fire the mutation events. Note: user input could cause DOM_CREATE
@ -1998,7 +2020,7 @@ NS_IMETHODIMP nsDocAccessible::InvalidateCacheSubtree(nsIContent *aChild,
// This often happens when visibility is cleared for node,
// which hides an entire subtree -- we get notified for each
// node in the subtree and need to collate the hide events ourselves.
return NS_OK;
return;
}
}
}
@ -2010,7 +2032,8 @@ NS_IMETHODIMP nsDocAccessible::InvalidateCacheSubtree(nsIContent *aChild,
// Fire an event if the accessible existed for node being hidden, otherwise
// for the first line accessible descendants. Fire before the accessible(s) away.
nsresult rv = FireShowHideEvents(childNode, PR_FALSE, removalEventType, PR_TRUE, PR_FALSE);
NS_ENSURE_SUCCESS(rv, rv);
NS_ENSURE_SUCCESS(rv,);
if (childNode != mDOMNode) { // Fire text change unless the node being removed is for this doc
// When a node is hidden or removed, the text in an ancestor hyper text will lose characters
// At this point we still have the frame and accessible for this node if there was one
@ -2102,11 +2125,9 @@ NS_IMETHODIMP nsDocAccessible::InvalidateCacheSubtree(nsIContent *aChild,
new nsAccReorderEvent(containerAccessible, isAsynch,
isUnconditionalEvent,
aChild ? childNode.get() : nsnull);
NS_ENSURE_TRUE(reorderEvent, NS_ERROR_OUT_OF_MEMORY);
NS_ENSURE_TRUE(reorderEvent,);
FireDelayedAccessibleEvent(reorderEvent);
return NS_OK;
}
NS_IMETHODIMP

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

@ -41,7 +41,6 @@
#include "nsHyperTextAccessibleWrap.h"
#include "nsIAccessibleDocument.h"
#include "nsPIAccessibleDocument.h"
#include "nsIDocument.h"
#include "nsIDocumentObserver.h"
#include "nsIEditor.h"
@ -56,9 +55,16 @@ class nsIScrollableView;
const PRUint32 kDefaultCacheSize = 256;
#define NS_DOCACCESSIBLE_IMPL_CID \
{ /* 0ed1be1d-52a7-4bfd-b4f5-0de7caed4617 */ \
0x0ed1be1d, \
0x52a7, \
0x4bfd, \
{ 0xb4, 0xf5, 0x0d, 0xe7, 0xca, 0xed, 0x46, 0x17 } \
}
class nsDocAccessible : public nsHyperTextAccessibleWrap,
public nsIAccessibleDocument,
public nsPIAccessibleDocument,
public nsIDocumentObserver,
public nsIObserver,
public nsIScrollPositionListener,
@ -68,73 +74,119 @@ class nsDocAccessible : public nsHyperTextAccessibleWrap,
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsDocAccessible, nsAccessible)
NS_DECL_NSIACCESSIBLEDOCUMENT
NS_DECL_NSPIACCESSIBLEDOCUMENT
NS_DECLARE_STATIC_IID_ACCESSOR(NS_DOCACCESSIBLE_IMPL_CID)
NS_DECL_NSIOBSERVER
public:
nsDocAccessible(nsIDOMNode *aNode, nsIWeakReference* aShell);
virtual ~nsDocAccessible();
public:
nsDocAccessible(nsIDOMNode *aNode, nsIWeakReference* aShell);
virtual ~nsDocAccessible();
// nsIAccessible
NS_IMETHOD GetName(nsAString& aName);
NS_IMETHOD GetDescription(nsAString& aDescription);
NS_IMETHOD GetAttributes(nsIPersistentProperties **aAttributes);
NS_IMETHOD GetFocusedChild(nsIAccessible **aFocusedChild);
NS_IMETHOD GetParent(nsIAccessible **aParent);
NS_IMETHOD TakeFocus(void);
// nsIAccessible
NS_IMETHOD GetName(nsAString& aName);
NS_IMETHOD GetDescription(nsAString& aDescription);
NS_IMETHOD GetAttributes(nsIPersistentProperties **aAttributes);
NS_IMETHOD GetFocusedChild(nsIAccessible **aFocusedChild);
NS_IMETHOD GetParent(nsIAccessible **aParent);
NS_IMETHOD TakeFocus(void);
// ----- nsIScrollPositionListener ---------------------------
NS_IMETHOD ScrollPositionWillChange(nsIScrollableView *aView, nscoord aX, nscoord aY);
virtual void ViewPositionDidChange(nsIScrollableView* aScrollable) {}
NS_IMETHOD ScrollPositionDidChange(nsIScrollableView *aView, nscoord aX, nscoord aY);
// nsIScrollPositionListener
NS_IMETHOD ScrollPositionWillChange(nsIScrollableView *aView,
nscoord aX, nscoord aY);
virtual void ViewPositionDidChange(nsIScrollableView* aScrollable) {}
NS_IMETHOD ScrollPositionDidChange(nsIScrollableView *aView,
nscoord aX, nscoord aY);
// nsIDocumentObserver
NS_DECL_NSIDOCUMENTOBSERVER
// nsIDocumentObserver
NS_DECL_NSIDOCUMENTOBSERVER
static void FlushEventsCallback(nsITimer *aTimer, void *aClosure);
// nsAccessNode
virtual nsresult Init();
virtual nsresult Shutdown();
virtual nsIFrame* GetFrame();
virtual PRBool IsDefunct();
// nsAccessNode
virtual nsresult Init();
virtual nsresult Shutdown();
virtual nsIFrame* GetFrame();
// nsAccessible
// nsAccessible
virtual nsresult GetRoleInternal(PRUint32 *aRole);
virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
virtual nsresult GetARIAState(PRUint32 *aState);
virtual nsresult GetARIAState(PRUint32 *aState, PRUint32 *aExtraState);
virtual void SetRoleMapEntry(nsRoleMapEntry* aRoleMapEntry);
// nsIAccessibleText
NS_IMETHOD GetAssociatedEditor(nsIEditor **aEditor);
// nsIAccessibleText
NS_IMETHOD GetAssociatedEditor(nsIEditor **aEditor);
/**
* Non-virtual method to fire a delayed event after a 0 length timeout
*
* @param aEvent - the nsIAccessibleEvent event type
* @param aDOMNode - DOM node the accesible event should be fired for
* @param aAllowDupes - eAllowDupes: more than one event of the same type is allowed.
* eCoalesceFromSameSubtree: if two events are in the same subtree,
* only the event on ancestor is used
* eRemoveDupes (default): events of the same type are discarded
* (the last one is used)
*
* @param aIsAsynch - set to PR_TRUE if this is not being called from code
* synchronous with a DOM event
*/
nsresult FireDelayedToolkitEvent(PRUint32 aEvent, nsIDOMNode *aDOMNode,
nsAccEvent::EEventRule aAllowDupes = nsAccEvent::eRemoveDupes,
PRBool aIsAsynch = PR_FALSE);
// nsDocAccessible
/**
* Fire accessible event in timeout.
*
* @param aEvent - the event to fire
*/
nsresult FireDelayedAccessibleEvent(nsIAccessibleEvent *aEvent);
/**
* Non-virtual method to fire a delayed event after a 0 length timeout.
*
* @param aEvent [in] the nsIAccessibleEvent event type
* @param aDOMNode [in] DOM node the accesible event should be fired for
* @param aAllowDupes [in] rule to process an event (see EEventRule constants)
* @param aIsAsynch [in] set to PR_TRUE if this is not being called from
* code synchronous with a DOM event
*/
nsresult FireDelayedToolkitEvent(PRUint32 aEvent, nsIDOMNode *aDOMNode,
nsAccEvent::EEventRule aAllowDupes = nsAccEvent::eRemoveDupes,
PRBool aIsAsynch = PR_FALSE);
void ShutdownChildDocuments(nsIDocShellTreeItem *aStart);
/**
* Fire accessible event after timeout.
*
* @param aEvent [in] the event to fire
*/
nsresult FireDelayedAccessibleEvent(nsIAccessibleEvent *aEvent);
/**
* Find the accessible object in the accessibility cache that corresponds to
* the given node or the first ancestor of it that has an accessible object
* associated with it. Clear that accessible object's parent's cache of
* accessible children and remove the accessible object and any descendants
* from the accessible cache. Fires proper events. New accessible objects will
* be created and cached again on demand.
*
* @param aContent [in] the child that is changing
* @param aEvent [in] the event from nsIAccessibleEvent that caused
* the change.
*/
void InvalidateCacheSubtree(nsIContent *aContent, PRUint32 aEvent);
/**
* Cache access node.
*
* @param aUniquID [in] the unique identifier of accessible
* @param aAccessNode [in] accessible to cache
*/
void CacheAccessNode(void *aUniqueID, nsIAccessNode *aAccessNode);
/**
* Fires pending events.
*/
void FlushPendingEvents();
/**
* Fire document load events.
*
* @param aEventType [in] nsIAccessibleEvent constant
*/
virtual void FireDocLoadEvents(PRUint32 aEventType);
/**
* Process the case when anchor was clicked.
*/
virtual void FireAnchorJumpEvent();
/**
* Used to flush pending events, called after timeout. See FlushPendingEvents.
*/
static void FlushEventsCallback(nsITimer *aTimer, void *aClosure);
protected:
/**
* Iterates through sub documents and shut them down.
*/
void ShutdownChildDocuments(nsIDocShellTreeItem *aStart);
protected:
virtual void GetBoundsRect(nsRect& aRect, nsIFrame** aRelativeFrame);
virtual nsresult AddEventListeners();
virtual nsresult RemoveEventListeners();
@ -230,4 +282,7 @@ protected:
static nsIAtom *gLastFocusedFrameType;
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsDocAccessible,
NS_DOCACCESSIBLE_IMPL_CID)
#endif

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

@ -1070,27 +1070,26 @@ nsRootAccessible::GetRelationByType(PRUint32 aRelationType,
return NS_OK;
}
NS_IMETHODIMP nsRootAccessible::FireDocLoadEvents(PRUint32 aEventType)
void
nsRootAccessible::FireDocLoadEvents(PRUint32 aEventType)
{
if (!mDocument || !mWeakShell) {
return NS_OK; // Document has been shut down
}
if (IsDefunct())
return;
nsCOMPtr<nsIDocShellTreeItem> docShellTreeItem =
nsCoreUtils::GetDocShellTreeItemFor(mDOMNode);
NS_ASSERTION(docShellTreeItem, "No doc shell tree item for document");
NS_ENSURE_TRUE(docShellTreeItem, NS_ERROR_FAILURE);
if (!docShellTreeItem)
return;
PRInt32 contentType;
docShellTreeItem->GetItemType(&contentType);
if (contentType == nsIDocShellTreeItem::typeContent) {
return nsDocAccessibleWrap::FireDocLoadEvents(aEventType); // Content might need to fire event
}
if (contentType == nsIDocShellTreeItem::typeContent)
nsDocAccessibleWrap::FireDocLoadEvents(aEventType); // Content might need to fire event
// Root chrome: don't fire event
mIsContentLoaded = (aEventType == nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_COMPLETE ||
aEventType == nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_STOPPED);
return NS_OK;
}
nsresult

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

@ -69,33 +69,32 @@ class nsRootAccessible : public nsDocAccessibleWrap,
{
NS_DECL_ISUPPORTS_INHERITED
public:
nsRootAccessible(nsIDOMNode *aDOMNode, nsIWeakReference* aShell);
virtual ~nsRootAccessible();
public:
nsRootAccessible(nsIDOMNode *aDOMNode, nsIWeakReference* aShell);
virtual ~nsRootAccessible();
// nsIAccessible
NS_IMETHOD GetName(nsAString& aName);
NS_IMETHOD GetParent(nsIAccessible * *aParent);
NS_IMETHOD GetRelationByType(PRUint32 aRelationType,
nsIAccessibleRelation **aRelation);
// nsIAccessible
NS_IMETHOD GetName(nsAString& aName);
NS_IMETHOD GetParent(nsIAccessible * *aParent);
NS_IMETHOD GetRelationByType(PRUint32 aRelationType,
nsIAccessibleRelation **aRelation);
// ----- nsPIAccessibleDocument -----------------------
NS_IMETHOD FireDocLoadEvents(PRUint32 aEventType);
// nsIDOMEventListener
NS_IMETHOD HandleEvent(nsIDOMEvent* aEvent);
// ----- nsIDOMEventListener --------------------------
NS_IMETHOD HandleEvent(nsIDOMEvent* aEvent);
// nsAccessNode
virtual nsresult Init();
virtual nsresult Shutdown();
// nsAccessNode
virtual nsresult Init();
virtual nsresult Shutdown();
// nsAccessible
virtual nsresult GetRoleInternal(PRUint32 *aRole);
virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
// nsAccessible
virtual nsresult GetRoleInternal(PRUint32 *aRole);
virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
// nsDocAccessible
virtual void FireDocLoadEvents(PRUint32 aEventType);
void ShutdownAll();
NS_DECLARE_STATIC_IID_ACCESSOR(NS_ROOTACCESSIBLE_IMPL_CID)
// nsRootAccessible
NS_DECLARE_STATIC_IID_ACCESSOR(NS_ROOTACCESSIBLE_IMPL_CID)
/**
* Fire an accessible focus event for the current focusAccssible

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

@ -296,7 +296,7 @@ nsHTMLButtonAccessible::GetRoleInternal(PRUint32 *aRole)
nsresult
nsHTMLButtonAccessible::GetNameInternal(nsAString& aName)
{
nsresult rv = nsAccessible::GetNameInternal(aName);
nsAccessible::GetNameInternal(aName);
if (!aName.IsEmpty())
return NS_OK;

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

@ -1389,7 +1389,7 @@ NS_IMETHODIMP nsHTMLTableAccessible::IsProbablyForLayout(PRBool *aIsProbablyForL
PRUint32 length;
nodeList->GetLength(&length);
nsAutoString color, lastRowColor;
for (PRInt32 rowCount = 0; rowCount < length; rowCount ++) {
for (PRUint32 rowCount = 0; rowCount < length; rowCount ++) {
nsCOMPtr<nsIDOMNode> rowNode;
nodeList->Item(rowCount, getter_AddRefs(rowNode));

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

@ -161,7 +161,8 @@ __try {
return E_FAIL;
}
NS_IMETHODIMP nsDocAccessibleWrap::FireAnchorJumpEvent()
void
nsDocAccessibleWrap::FireAnchorJumpEvent()
{
// Staying on the same page, jumping to a named anchor
// Fire EVENT_SCROLLING_START on first leaf accessible -- because some
@ -171,19 +172,19 @@ NS_IMETHODIMP nsDocAccessibleWrap::FireAnchorJumpEvent()
// we have to move forward in the document to get one
nsDocAccessible::FireAnchorJumpEvent();
if (!mIsAnchorJumped)
return NS_OK;
return;
nsCOMPtr<nsIDOMNode> focusNode;
if (mIsAnchor) {
nsCOMPtr<nsISelectionController> selCon(do_QueryReferent(mWeakShell));
if (!selCon) {
return NS_OK;
}
if (!selCon)
return;
nsCOMPtr<nsISelection> domSel;
selCon->GetSelection(nsISelectionController::SELECTION_NORMAL, getter_AddRefs(domSel));
if (!domSel) {
return NS_OK;
}
if (!domSel)
return;
domSel->GetFocusNode(getter_AddRefs(focusNode));
}
else {
@ -193,8 +194,6 @@ NS_IMETHODIMP nsDocAccessibleWrap::FireAnchorJumpEvent()
nsCOMPtr<nsIAccessible> accessible = GetFirstAvailableAccessible(focusNode, PR_TRUE);
nsAccUtils::FireAccEvent(nsIAccessibleEvent::EVENT_SCROLLING_START,
accessible);
return NS_OK;
}
STDMETHODIMP nsDocAccessibleWrap::get_URL(/* [out] */ BSTR __RPC_FAR *aURL)

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

@ -92,7 +92,7 @@ public:
/* [optional][in] */ VARIANT varChild,
/* [retval][out] */ BSTR __RPC_FAR *pszValue);
NS_IMETHOD FireAnchorJumpEvent();
virtual void FireAnchorJumpEvent();
};
#endif

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

@ -872,6 +872,18 @@ already_AddRefed<nsIDOMNode> nsXULTextFieldAccessible::GetInputField()
return inputField;
}
nsresult
nsXULTextFieldAccessible::GetARIAState(PRUint32 *aState, PRUint32 *aExtraState)
{
nsresult rv = nsHyperTextAccessibleWrap::GetARIAState(aState, aExtraState);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
nsStateMapEntry::MapToStates(content, aState, aExtraState, eARIAAutoComplete);
return NS_OK;
}
nsresult
nsXULTextFieldAccessible::GetStateInternal(PRUint32 *aState,
PRUint32 *aExtraState)

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

@ -204,6 +204,7 @@ public:
NS_IMETHOD GetAssociatedEditor(nsIEditor **aEditor);
// nsAccessible
virtual nsresult GetARIAState(PRUint32 *aState, PRUint32 *aExtraState);
virtual nsresult GetRoleInternal(PRUint32 *aRole);
virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
virtual PRBool GetAllowsAnonChildAccessibles();

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

@ -48,7 +48,7 @@ include $(topsrcdir)/config/rules.mk
_TEST_FILES =\
letters.gif \
moz.png \
$(topsrcdir)/content/media/video/test/bug461281.ogg \
$(topsrcdir)/content/media/test/bug461281.ogg \
longdesc_src.html \
actions.js \
attributes.js \

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

@ -49,6 +49,7 @@ const nsIPropertyElement = Components.interfaces.nsIPropertyElement;
////////////////////////////////////////////////////////////////////////////////
// States
const STATE_BUSY = nsIAccessibleStates.STATE_BUSY;
const STATE_CHECKED = nsIAccessibleStates.STATE_CHECKED;
const STATE_CHECKABLE = nsIAccessibleStates.STATE_CHECKABLE;
const STATE_COLLAPSED = nsIAccessibleStates.STATE_COLLAPSED;
@ -57,12 +58,14 @@ const STATE_EXTSELECTABLE = nsIAccessibleStates.STATE_EXTSELECTABLE;
const STATE_FOCUSABLE = nsIAccessibleStates.STATE_FOCUSABLE;
const STATE_FOCUSED = nsIAccessibleStates.STATE_FOCUSED;
const STATE_HASPOPUP = nsIAccessibleStates.STATE_HASPOPUP;
const STATE_INVALID = nsIAccessibleStates.STATE_INVALID;
const STATE_LINKED = nsIAccessibleStates.STATE_LINKED;
const STATE_MIXED = nsIAccessibleStates.STATE_MIXED;
const STATE_MULTISELECTABLE = nsIAccessibleStates.STATE_MULTISELECTABLE;
const STATE_OFFSCREEN = nsIAccessibleStates.STATE_OFFSCREEN;
const STATE_PRESSED = nsIAccessibleStates.STATE_PRESSED;
const STATE_READONLY = nsIAccessibleStates.STATE_READONLY;
const STATE_REQUIRED = nsIAccessibleStates.STATE_REQUIRED;
const STATE_SELECTABLE = nsIAccessibleStates.STATE_SELECTABLE;
const STATE_SELECTED = nsIAccessibleStates.STATE_SELECTED;
const STATE_TRAVERSED = nsIAccessibleStates.STATE_TRAVERSED;
@ -71,9 +74,8 @@ const STATE_UNAVAILABLE = nsIAccessibleStates.STATE_UNAVAILABLE;
const EXT_STATE_EDITABLE = nsIAccessibleStates.EXT_STATE_EDITABLE;
const EXT_STATE_EXPANDABLE = nsIAccessibleStates.EXT_STATE_EXPANDABLE;
const EXT_STATE_HORIZONTAL = nsIAccessibleStates.EXT_STATE_HORIZONTAL;
const EXT_STATE_INVALID = nsIAccessibleStates.STATE_INVALID;
const EXT_STATE_MULTI_LINE = nsIAccessibleStates.EXT_STATE_MULTI_LINE;
const EXT_STATE_REQUIRED = nsIAccessibleStates.STATE_REQUIRED;
const EXT_STATE_SINGLE_LINE = nsIAccessibleStates.EXT_STATE_SINGLE_LINE;
const EXT_STATE_SUPPORTS_AUTOCOMPLETION =
nsIAccessibleStates.EXT_STATE_SUPPORTS_AUTOCOMPLETION;
@ -108,7 +110,7 @@ function addA11yLoadEvent(aFunc)
var accDoc = getAccessible(document);
var state = {};
accDoc.getState(state, {});
if (state.value & nsIAccessibleStates.STATE_BUSY)
if (state.value & STATE_BUSY)
return waitForDocLoad();
aFunc.call();
@ -326,9 +328,12 @@ function statesToString(aStates, aExtraStates)
var list = gAccRetrieval.getStringStates(aStates, aExtraStates);
var str = "";
for (var index = 0; index < list.length; index++)
for (var index = 0; index < list.length - 1; index++)
str += list.item(index) + ", ";
if (list.length != 0)
str += list.item(index)
return str;
}

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

@ -1,3 +1,11 @@
////////////////////////////////////////////////////////////////////////////////
// Helper functions for accessible states testing.
//
// requires:
// common.js
//
////////////////////////////////////////////////////////////////////////////////
/**
* Tests the states and extra states of the given accessible.
* Also tests for unwanted states and extra states.
@ -17,55 +25,73 @@ function testStates(aAccOrElmOrID, aState, aExtraState, aAbsentState,
var id = prettyName(aAccOrElmOrID);
is(state & aState, aState,
"wrong state bits for " + id + "!");
// Primary test.
isState(state & aState, aState, false,
"wrong state bits for " + id + "!");
if (aExtraState)
is(extraState & aExtraState, aExtraState,
"wrong extra state bits for " + id + "!");
isState(extraState & aExtraState, aExtraState, true,
"wrong extra state bits for " + id + "!");
if (aAbsentState)
is(state & aAbsentState, 0,
"state bits should not be present in ID " + id + "!");
isState(state & aAbsentState, 0, false,
"state bits should not be present in ID " + id + "!");
if (aAbsentExtraState)
is(extraState & aAbsentExtraState, 0,
"extraState bits should not be present in ID " + id + "!");
isState(extraState & aAbsentExtraState, 0, true,
"extraState bits should not be present in ID " + id + "!");
// Additional test.
// readonly/editable
if (state & STATE_READONLY)
is(extraState & EXT_STATE_EDITABLE, 0,
"Read-only " + id + " cannot be editable!");
isState(extraState & EXT_STATE_EDITABLE, 0, true,
"Read-only " + id + " cannot be editable!");
if (extraState & EXT_STATE_EDITABLE)
is(state & STATE_READONLY, 0,
"Editable " + id + " cannot be readonly!");
isState(state & STATE_READONLY, 0, true,
"Editable " + id + " cannot be readonly!");
// multiline/singleline
if (extraState & EXT_STATE_MULTI_LINE)
isState(extraState & EXT_STATE_SINGLE_LINE, 0, true,
"Multiline " + id + " cannot be singleline!");
if (extraState & EXT_STATE_SINGLE_LINE)
isState(extraState & EXT_STATE_MULTI_LINE, 0, true,
"Singleline " + id + " cannot be multiline!");
// expanded/collapsed/expandable
if (state & STATE_COLLAPSED || state & STATE_EXPANDED)
is(extraState & EXT_STATE_EXPANDABLE, EXT_STATE_EXPANDABLE,
"Collapsed or expanded " + id + " should be expandable!");
isState(extraState & EXT_STATE_EXPANDABLE, EXT_STATE_EXPANDABLE, true,
"Collapsed or expanded " + id + " should be expandable!");
if (state & STATE_COLLAPSED)
is(state & STATE_EXPANDED, 0,
"Collapsed " + id + " cannot be expanded!");
isState(state & STATE_EXPANDED, 0, false,
"Collapsed " + id + " cannot be expanded!");
if (state & STATE_EXPANDED)
is(state & STATE_COLLAPSED, 0,
"Expanded " + id + " cannot be collapsed!");
isState(state & STATE_COLLAPSED, 0, false,
"Expanded " + id + " cannot be collapsed!");
// checked/mixed/checkable
if (state & STATE_CHECKED || state & STATE_MIXED)
is(state & STATE_CHECKABLE, STATE_CHECKABLE,
"Checked or mixed element must be checkable!");
isState(state & STATE_CHECKABLE, STATE_CHECKABLE, false,
"Checked or mixed element must be checkable!");
if (state & STATE_CHECKED)
is(state & STATE_MIXED, 0, "Checked element cannot be state mixed!");
isState(state & STATE_MIXED, 0, false,
"Checked element cannot be state mixed!");
if (state & STATE_MIXED)
is(state & STATE_CHECKED, 0, "Mixed element cannot be state checked!");
isState(state & STATE_CHECKED, 0, false,
"Mixed element cannot be state checked!");
// unavailable
if ((state & STATE_UNAVAILABLE)
&& (getRole(aAccOrElmOrID) != ROLE_GROUPING))
is(state & STATE_FOCUSABLE, STATE_FOCUSABLE,
"Disabled " + id + " must be focusable!");
isState(state & STATE_FOCUSABLE, STATE_FOCUSABLE, false,
"Disabled " + id + " must be focusable!");
}
/**
@ -122,3 +148,31 @@ function getStates(aAccOrElmOrID)
return [state.value, extraState.value];
}
////////////////////////////////////////////////////////////////////////////////
// Private implementation details
/**
* Analogy of SimpleTest.is function used to compare states.
*/
function isState(aState1, aState2, aIsExtraStates, aMsg)
{
if (aState1 == aState2) {
ok(true, aMsg);
return;
}
var got = "0";
if (aState1) {
got = statesToString(aIsExtraStates ? 0 : aState1,
aIsExtraStates ? aState1 : 0);
}
var expected = "0";
if (aState2) {
expected = statesToString(aIsExtraStates ? 0 : aState2,
aIsExtraStates ? aState2 : 0);
}
ok(false, aMsg + "got '" + got + "', expected '" + expected + "'");
}

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

@ -22,25 +22,25 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=452388
<script type="application/javascript">
function doTest()
{
// test (treeitem) selectable and selected states
testStates("treeitem_selected_true", (STATE_SELECTABLE | STATE_SELECTED));
testStates("treeitem_selected_false", STATE_SELECTABLE, 0, STATE_SELECTED);
testStates("treeitem_selected_empty", 0, 0, (STATE_SELECTABLE | STATE_SELECTED));
testStates("treeitem_selected_undefined", 0, 0, (STATE_SELECTABLE | STATE_SELECTED));
testStates("treeitem_selected_absent", 0, 0, (STATE_SELECTABLE | STATE_SELECTED));
// test aria-pressed state mapping to roles PUSHBUTTON vs TOGGLEBUTTON
testRole("button_pressed_true", ROLE_TOGGLE_BUTTON);
testRole("button_pressed_false", ROLE_TOGGLE_BUTTON);
testRole("button_pressed_empty", ROLE_PUSHBUTTON);
testRole("button_pressed_undefined", ROLE_PUSHBUTTON);
testRole("button_pressed_absent", ROLE_PUSHBUTTON);
// test (menuitem) checkable and checked states
testStates("menuitem_checked_true", (STATE_CHECKABLE | STATE_CHECKED));
testStates("menuitem_checked_false", STATE_CHECKABLE, 0, STATE_CHECKED);
testStates("menuitem_checked_empty", 0, 0, (STATE_CHECKABLE | STATE_CHECKED));
testStates("menuitem_checked_undefined", 0, 0, (STATE_CHECKABLE | STATE_CHECKED));
testStates("menuitem_checked_absent", 0, 0, (STATE_CHECKABLE | STATE_CHECKED));
// test button aria-pressed states
testStates("button_pressed_true", STATE_PRESSED | STATE_CHECKABLE);
testStates("button_pressed_false", STATE_CHECKABLE, 0, STATE_PRESSED);
testStates("button_pressed_empty", 0, 0, STATE_PRESSED | STATE_CHECKABLE);
testStates("button_pressed_undefined", 0, 0, STATE_PRESSED | STATE_CHECKABLE);
testStates("button_pressed_absent", 0, 0, STATE_PRESSED | STATE_CHECKABLE);
// test (checkbox) checkable and checked states
testStates("checkbox_checked_true", (STATE_CHECKABLE | STATE_CHECKED));
testStates("checkbox_checked_false", STATE_CHECKABLE, 0, STATE_CHECKED);
testStates("checkbox_checked_empty", STATE_CHECKABLE, 0, STATE_CHECKED);
testStates("checkbox_checked_undefined", STATE_CHECKABLE, 0, STATE_CHECKED);
testStates("checkbox_checked_empty", 0 , 0, STATE_CHECKABLE | STATE_CHECKED);
testStates("checkbox_checked_undefined", 0, 0, STATE_CHECKABLE | STATE_CHECKED);
testStates("checkbox_checked_absent", STATE_CHECKABLE, 0, STATE_CHECKED);
// test native checkbox checked state and aria-checked state (if conflict, native wins)
@ -49,27 +49,124 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=452388
testStates("native_checkbox_nativechecked_ariaempty", (STATE_CHECKABLE | STATE_CHECKED));
testStates("native_checkbox_nativechecked_ariaundefined", (STATE_CHECKABLE | STATE_CHECKED));
testStates("native_checkbox_nativechecked_ariaabsent", (STATE_CHECKABLE | STATE_CHECKED));
testStates("native_checkbox_nativeunchecked_ariatrue", STATE_CHECKABLE, 0, STATE_CHECKED);
testStates("native_checkbox_nativeunchecked_ariafalse", STATE_CHECKABLE, 0, STATE_CHECKED);
testStates("native_checkbox_nativeunchecked_ariaempty", STATE_CHECKABLE, 0, STATE_CHECKED);
testStates("native_checkbox_nativeunchecked_ariaundefined", STATE_CHECKABLE, 0, STATE_CHECKED);
testStates("native_checkbox_nativeunchecked_ariaabsent", STATE_CHECKABLE, 0, STATE_CHECKED);
// test button aria-pressed states
testStates("button_pressed_true", STATE_PRESSED | STATE_CHECKABLE);
testStates("button_pressed_false", 0, 0, STATE_PRESSED | STATE_CHECKABLE);
testStates("button_pressed_empty", 0, 0, STATE_PRESSED | STATE_CHECKABLE);
testStates("button_pressed_undefined", 0, 0, STATE_PRESSED | STATE_CHECKABLE);
testStates("button_pressed_absent", 0, 0, STATE_PRESSED | STATE_CHECKABLE);
// test aria-pressed state mapping to roles PUSHBUTTON vs TOGGLEBUTTON
testRole("button_pressed_true", ROLE_TOGGLE_BUTTON);
testRole("button_pressed_false", ROLE_TOGGLE_BUTTON);
testRole("button_pressed_empty", ROLE_PUSHBUTTON);
testRole("button_pressed_undefined", ROLE_PUSHBUTTON);
testRole("button_pressed_absent", ROLE_PUSHBUTTON);
// test (checkbox) readonly states
testStates("checkbox_readonly_true", STATE_READONLY);
testStates("checkbox_readonly_false", 0, 0, STATE_READONLY);
testStates("checkbox_readonly_empty", 0, 0, STATE_READONLY);
testStates("checkbox_readonly_undefined", 0, 0, STATE_READONLY);
testStates("checkbox_readonly_absent", 0, 0, STATE_READONLY);
// test (checkbox) required states
testStates("checkbox_required_true", STATE_REQUIRED);
testStates("checkbox_required_false", 0, 0, STATE_REQUIRED);
testStates("checkbox_required_empty", 0, 0, STATE_REQUIRED);
testStates("checkbox_required_undefined", 0, 0, STATE_REQUIRED);
testStates("checkbox_required_absent", 0, 0, STATE_REQUIRED);
// test (checkbox) invalid states
testStates("checkbox_invalid_true", STATE_INVALID);
testStates("checkbox_invalid_false", 0, 0, STATE_INVALID);
testStates("checkbox_invalid_empty", 0, 0, STATE_INVALID);
testStates("checkbox_invalid_undefined", 0, 0, STATE_INVALID);
testStates("checkbox_invalid_absent", 0, 0, STATE_INVALID);
// test (checkbox) disabled states
testStates("checkbox_disabled_true", STATE_UNAVAILABLE);
testStates("checkbox_disabled_false", 0, 0, STATE_UNAVAILABLE);
testStates("checkbox_disabled_empty", 0, 0, STATE_UNAVAILABLE);
testStates("checkbox_disabled_undefined", 0, 0, STATE_UNAVAILABLE);
testStates("checkbox_disabled_absent", 0, 0, STATE_UNAVAILABLE);
// test (listbox) multiselectable states
testStates("listbox_multiselectable_true", STATE_MULTISELECTABLE | STATE_EXTSELECTABLE);
testStates("listbox_multiselectable_false", 0, 0, STATE_MULTISELECTABLE | STATE_EXTSELECTABLE);
testStates("listbox_multiselectable_empty", 0, 0, STATE_MULTISELECTABLE | STATE_EXTSELECTABLE);
testStates("listbox_multiselectable_undefined", 0, 0, STATE_MULTISELECTABLE | STATE_EXTSELECTABLE);
testStates("listbox_multiselectable_absent", 0, 0, STATE_MULTISELECTABLE | STATE_EXTSELECTABLE);
// test (listitem) checkable and checked states
testStates("listitem_checked_true", (STATE_CHECKABLE | STATE_CHECKED));
testStates("listitem_checked_false", STATE_CHECKABLE, 0, STATE_CHECKED);
testStates("listitem_checked_empty", 0 , 0, STATE_CHECKABLE | STATE_CHECKED);
testStates("listitem_checked_undefined", 0, 0, STATE_CHECKABLE | STATE_CHECKED);
testStates("listitem_checked_absent", 0, 0, STATE_CHECKABLE | STATE_CHECKED);
// test (menuitem) checkable and checked states
testStates("menuitem_checked_true", (STATE_CHECKABLE | STATE_CHECKED));
testStates("menuitem_checked_false", STATE_CHECKABLE, 0, STATE_CHECKED);
testStates("menuitem_checked_empty", 0, 0, (STATE_CHECKABLE | STATE_CHECKED));
testStates("menuitem_checked_undefined", 0, 0, (STATE_CHECKABLE | STATE_CHECKED));
testStates("menuitem_checked_absent", 0, 0, (STATE_CHECKABLE | STATE_CHECKED));
// test (menuitemradio) checkable and checked states
testStates("menuitemradio_checked_true", (STATE_CHECKABLE | STATE_CHECKED));
testStates("menuitemradio_checked_false", STATE_CHECKABLE, 0, STATE_CHECKED);
testStates("menuitemradio_checked_empty", 0, 0, (STATE_CHECKABLE | STATE_CHECKED));
testStates("menuitemradio_checked_undefined", 0, 0, (STATE_CHECKABLE | STATE_CHECKED));
testStates("menuitemradio_checked_absent", STATE_CHECKABLE, 0, STATE_CHECKED);
// test (radio) checkable and checked states
testStates("radio_checked_true", (STATE_CHECKABLE | STATE_CHECKED));
testStates("radio_checked_false", STATE_CHECKABLE, 0, STATE_CHECKED);
testStates("radio_checked_empty", 0, 0, (STATE_CHECKABLE | STATE_CHECKED));
testStates("radio_checked_undefined", 0, 0, (STATE_CHECKABLE | STATE_CHECKED));
testStates("radio_checked_absent", STATE_CHECKABLE, 0, STATE_CHECKED);
// test (textbox) multiline states
testStates("textbox_multiline_true", 0, EXT_STATE_MULTI_LINE);
testStates("textbox_multiline_false", 0, EXT_STATE_SINGLE_LINE);
testStates("textbox_multiline_empty", 0, 0, 0, EXT_STATE_SINGLE_LINE | EXT_STATE_MULTI_LINE);
testStates("textbox_multiline_undefined", 0, 0, 0, EXT_STATE_SINGLE_LINE | EXT_STATE_MULTI_LINE);
testStates("textbox_multiline_absent", 0, EXT_STATE_SINGLE_LINE);
// test (textbox) readonly states
testStates("textbox_readonly_true", STATE_READONLY);
testStates("textbox_readonly_false", 0, EXT_STATE_EDITABLE, STATE_READONLY);
testStates("textbox_readonly_empty", 0, 0, STATE_READONLY, EXT_STATE_EDITABLE);
testStates("textbox_readonly_undefined", 0, 0, STATE_READONLY, EXT_STATE_EDITABLE);
testStates("textbox_readonly_absent", 0, EXT_STATE_EDITABLE, STATE_READONLY);
// test native textbox readonly state and aria-readonly state (if conflict, native wins)
testStates("native_textbox_nativereadonly_ariatrue", STATE_READONLY);
testStates("native_textbox_nativereadonly_ariafalse", STATE_READONLY);
testStates("native_textbox_nativereadonly_ariaempty", STATE_READONLY);
testStates("native_textbox_nativereadonly_ariaundefined", STATE_READONLY);
testStates("native_textbox_nativereadonly_ariaabsent", STATE_READONLY);
testStates("native_textbox_nativeeditable_ariatrue", 0, 0, STATE_READONLY);
testStates("native_textbox_nativeeditable_ariafalse", 0, 0, STATE_READONLY);
testStates("native_textbox_nativeeditable_ariaempty", 0, 0, STATE_READONLY);
testStates("native_textbox_nativeeditable_ariaundefined", 0, 0, STATE_READONLY);
testStates("native_textbox_nativeeditable_ariaabsent", 0, 0, STATE_READONLY);
// test (treeitem) selectable and selected states
testStates("treeitem_selected_true", (STATE_SELECTABLE | STATE_SELECTED));
testStates("treeitem_selected_false", STATE_SELECTABLE, 0, STATE_SELECTED);
testStates("treeitem_selected_empty", 0, 0, (STATE_SELECTABLE | STATE_SELECTED));
testStates("treeitem_selected_undefined", 0, 0, (STATE_SELECTABLE | STATE_SELECTED));
testStates("treeitem_selected_absent", 0, 0, (STATE_SELECTABLE | STATE_SELECTED));
// test (treeitem) haspopup states
testStates("treeitem_haspopup_true", STATE_HASPOPUP);
testStates("treeitem_haspopup_false", 0, 0, STATE_HASPOPUP);
testStates("treeitem_haspopup_empty", 0, 0, STATE_HASPOPUP);
testStates("treeitem_haspopup_undefined", 0, 0, STATE_HASPOPUP);
testStates("treeitem_haspopup_absent", 0, 0, STATE_HASPOPUP);
// test (treeitem) expandable and expanded/collapsed states
testStates("treeitem_expanded_true", STATE_EXPANDED, EXT_STATE_EXPANDABLE);
testStates("treeitem_expanded_false", STATE_COLLAPSED, EXT_STATE_EXPANDABLE);
testStates("treeitem_expanded_empty", 0, 0, STATE_EXPANDED | STATE_COLLAPSED, EXT_STATE_EXPANDABLE);
testStates("treeitem_expanded_undefined", 0, 0, STATE_EXPANDED | STATE_COLLAPSED, EXT_STATE_EXPANDABLE);
testStates("treeitem_expanded_absent", 0, 0, STATE_EXPANDED | STATE_COLLAPSED, EXT_STATE_EXPANDABLE);
SimpleTest.finish();
}
@ -79,48 +176,151 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=452388
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=452388">Mozilla Bug 452388</a>
<a target="_blank"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=452388">
Mozilla Bug 452388
</a>
<a target="_blank"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=499653"
title="Unify ARIA state attributes mapping rules">
Mozilla Bug 499653
</a>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
</pre>
<div id="treeitem_selected_true" role="treeitem" aria-selected="true">This treeitem has aria-selected="true" and should get STATE_SELECTABLE. It should also get STATE_SELECTED.</div>
<div id="treeitem_selected_false" role="treeitem" aria-selected="false">This treeitem has aria-selected="false" and should get STATE_SELECTABLE.</div>
<div id="treeitem_selected_empty" role="treeitem" aria-selected="">This treeitem has aria-selected="" and should <emph>not</emph> get STATE_SELECTABLE.</div>
<div id="treeitem_selected_undefined" role="treeitem" aria-selected="undefined">This treeitem has aria-selected="undefined" and should <emph>not</emph> get STATE_SELECTABLE.</div>
<div id="treeitem_selected_absent" role="treeitem">This treeitem has <emph>no</emph> aria-selected attribute and should <emph>not</emph> get STATE_SELECTABLE.</div>
<div id="menuitem_checked_true" role="menuitem" aria-checked="true">This menuitem has aria-checked="true" and should get STATE_CHECKABLE. It should also get STATE_checked.</div>
<div id="menuitem_checked_false" role="menuitem" aria-checked="false">This menuitem has aria-checked="false" and should get STATE_CHECKABLE.</div>
<div id="menuitem_checked_empty" role="menuitem" aria-checked="">This menuitem has aria-checked="" and should <emph>not</emph> get STATE_CHECKABLE.</div>
<div id="menuitem_checked_undefined" role="menuitem" aria-checked="undefined">This menuitem has aria-checked="undefined" and should <emph>not</emph> get STATE_CHECKABLE.</div>
<div id="menuitem_checked_absent" role="menuitem">This menuitem has <emph>no</emph> aria-checked attribute and should <emph>not</emph> get STATE_CHECKABLE.</div>
<div id="button_pressed_true" role="button" aria-pressed="true">This button has aria-pressed="true" and should get ROLE_TOGGLE_BUTTON. It should also get STATE_PRESSED.</div>
<div id="button_pressed_false" role="button" aria-pressed="false">This button has aria-pressed="false" and should get ROLE_TOGGLE_BUTTON.</div>
<div id="button_pressed_empty" role="button" aria-pressed="">This button has aria-pressed="" and should <emph>not</emph> get ROLE_BUTTON.</div>
<div id="button_pressed_undefined" role="button" aria-pressed="undefined">This button has aria-pressed="undefined" and should <emph>not</emph> get ROLE_TOGGLE_BUTTON.</div>
<div id="button_pressed_absent" role="button">This button has <emph>no</emph> aria-pressed attribute and should <emph>not</emph> get ROLE_TOGGLE_BUTTON.</div>
<div id="checkbox_checked_true" role="checkbox" aria-checked="true">This checkbox has aria-checked="true" and should get STATE_CHECKABLE. It should also get STATE_checked.</div>
<div id="checkbox_checked_false" role="checkbox" aria-checked="false">This checkbox has aria-checked="false" and should get STATE_CHECKABLE.</div>
<div id="checkbox_checked_empty" role="checkbox" aria-checked="">This checkbox has aria-checked="" and should <emph>not</emph> get STATE_CHECKABLE.</div>
<div id="checkbox_checked_undefined" role="checkbox" aria-checked="undefined">This checkbox has aria-checked="undefined" and should <emph>not</emph> get STATE_CHECKABLE.</div>
<div id="checkbox_checked_absent" role="checkbox">This checkbox has <emph>no</emph> aria-checked attribute and should <emph>not</emph> get STATE_CHECKABLE.</div>
<div id="checkbox_checked_absent" role="checkbox">This checkbox has <emph>no</emph> aria-checked attribute and should get STATE_CHECKABLE.</div>
<form action="">
<input id="native_checkbox_nativechecked_ariatrue" type="checkbox" checked="checked" aria-checked="true"/>
<input id="native_checkbox_nativechecked_ariafalse" type="checkbox" checked="checked" aria-checked="false"/>
<input id="native_checkbox_nativechecked_ariaempty" type="checkbox" checked="checked" aria-checked=""/>
<input id="native_checkbox_nativechecked_ariaundefined" type="checkbox" checked="checked" aria-checked="undefined"/>
<input id="native_checkbox_nativechecked_ariaabsent" type="checkbox" checked="checked" aria-checked="false"/>
<input id="native_checkbox_nativechecked_ariaabsent" type="checkbox" checked="checked"/>
<input id="native_checkbox_nativeunchecked_ariatrue" type="checkbox" aria-checked="true"/>
<input id="native_checkbox_nativeunchecked_ariafalse" type="checkbox" aria-checked="false"/>
<input id="native_checkbox_nativeunchecked_ariaempty" type="checkbox" aria-checked=""/>
<input id="native_checkbox_nativeunchecked_ariaundefined" type="checkbox" aria-checked="undefined"/>
<input id="native_checkbox_nativeunchecked_ariaabsent" type="checkbox" aria-checked="false"/>
<input id="native_checkbox_nativeunchecked_ariaabsent" type="checkbox"/>
</form>
<div id="button_pressed_true" role="button" aria-pressed="true">This button has aria-pressed="true" and should get ROLE_TOGGLE_BUTTON. It should also get STATE_PRESSED.</div>
<div id="button_pressed_false" role="button" aria-pressed="false">This button has aria-pressed="false" and should get ROLE_TOGGLE_BUTTON.</div>
<div id="button_pressed_empty" role="button" aria-pressed="">This button has aria-pressed="" and should <emph>not</emph> get ROLE_BUTTON.</div>
<div id="button_pressed_undefined" role="button" aria-pressed="undefined">This button has aria-pressed="undefined" and should <emph>not</emph> get ROLE_TOGGLE_BUTTON.</div>
<div id="button_pressed_absent" role="button">This button has <emph>no</emph> aria-pressed attribute and should <emph>not</emph> get ROLE_TOGGLE_BUTTON.</div>
<div id="checkbox_readonly_true" role="checkbox" aria-readonly="true">This checkbox has aria-readonly="true" and should get STATE_READONLY.</div>
<div id="checkbox_readonly_false" role="checkbox" aria-readonly="false">This checkbox has aria-readonly="false" and should <emph>not</emph> get STATE_READONLY.</div>
<div id="checkbox_readonly_empty" role="checkbox" aria-readonly="">This checkbox has aria-readonly="" and should <emph>not</emph> get STATE_READONLY.</div>
<div id="checkbox_readonly_undefined" role="checkbox" aria-readonly="undefined">This checkbox has aria-readonly="undefined" and should <emph>not</emph> get STATE_READONLY.</div>
<div id="checkbox_readonly_absent" role="checkbox">This checkbox has <emph>no</emph> aria-readonly attribute and should <emph>not</emph> get STATE_READONLY.</div>
<div id="checkbox_required_true" role="checkbox" aria-required="true">This checkbox has aria-required="true" and should get STATE_REQUIRED.</div>
<div id="checkbox_required_false" role="checkbox" aria-required="false">This checkbox has aria-required="false" and should <emph>not</emph> get STATE_REQUIRED.</div>
<div id="checkbox_required_empty" role="checkbox" aria-required="">This checkbox has aria-required="" and should <emph>not</emph> get STATE_REQUIRED.</div>
<div id="checkbox_required_undefined" role="checkbox" aria-required="undefined">This checkbox has aria-required="undefined" and should <emph>not</emph> get STATE_REQUIRED.</div>
<div id="checkbox_required_absent" role="checkbox">This checkbox has <emph>no</emph> aria-required attribute and should <emph>not</emph> get STATE_REQUIRED.</div>
<div id="checkbox_invalid_true" role="checkbox" aria-invalid="true">This checkbox has aria-invalid="true" and should get STATE_INVALID.</div>
<div id="checkbox_invalid_false" role="checkbox" aria-invalid="false">This checkbox has aria-invalid="false" and should <emph>not</emph> get STATE_INVALID.</div>
<div id="checkbox_invalid_empty" role="checkbox" aria-invalid="">This checkbox has aria-invalid="" and should <emph>not</emph> get STATE_INVALID.</div>
<div id="checkbox_invalid_undefined" role="checkbox" aria-invalid="undefined">This checkbox has aria-invalid="undefined" and should <emph>not</emph> get STATE_INVALID.</div>
<div id="checkbox_invalid_absent" role="checkbox">This checkbox has <emph>no</emph> aria-invalid attribute and should <emph>not</emph> get STATE_INVALID.</div>
<div id="checkbox_disabled_true" role="checkbox" aria-disabled="true" tabindex="0">This checkbox has aria-disabled="true" and should get STATE_DISABLED.</div>
<div id="checkbox_disabled_false" role="checkbox" aria-disabled="false">This checkbox has aria-disabled="false" and should <emph>not</emph> get STATE_DISABLED.</div>
<div id="checkbox_disabled_empty" role="checkbox" aria-disabled="">This checkbox has aria-disabled="" and should <emph>not</emph> get STATE_DISABLED.</div>
<div id="checkbox_disabled_undefined" role="checkbox" aria-disabled="undefined">This checkbox has aria-disabled="undefined" and should <emph>not</emph> get STATE_DISABLED.</div>
<div id="checkbox_disabled_absent" role="checkbox">This checkbox has <emph>no</emph> aria-disabled attribute and should <emph>not</emph> get STATE_DISABLED.</div>
<div id="listbox_multiselectable_true" role="listbox" aria-multiselectable="true">
<div id="listitem_checked_true" role="listitem" aria-checked="true">item</div>
</div>
<div id="listbox_multiselectable_false" role="listbox" aria-multiselectable="false">
<div id="listitem_checked_false" role="listitem" aria-checked="false">item</div>
</div>
<div id="listbox_multiselectable_empty" role="listbox" aria-multiselectable="">
<div id="listitem_checked_empty" role="listitem" aria-checked="">item</div>
</div>
<div id="listbox_multiselectable_undefined" role="listbox" aria-multiselectable="undefined">
<div id="listitem_checked_undefined" role="listitem" aria-checked="undefined">item</div>
</div>
<div id="listbox_multiselectable_absent" role="listbox">
<div id="listitem_checked_absent" role="listitem">item</div>
</div>
<div role="menu">
<div id="menuitem_checked_true" role="menuitem" aria-checked="true">This menuitem has aria-checked="true" and should get STATE_CHECKABLE. It should also get STATE_checked.</div>
<div id="menuitem_checked_false" role="menuitem" aria-checked="false">This menuitem has aria-checked="false" and should get STATE_CHECKABLE.</div>
<div id="menuitem_checked_empty" role="menuitem" aria-checked="">This menuitem has aria-checked="" and should <emph>not</emph> get STATE_CHECKABLE.</div>
<div id="menuitem_checked_undefined" role="menuitem" aria-checked="undefined">This menuitem has aria-checked="undefined" and should <emph>not</emph> get STATE_CHECKABLE.</div>
<div id="menuitem_checked_absent" role="menuitem">This menuitem has <emph>no</emph> aria-checked attribute and should <emph>not</emph> get STATE_CHECKABLE.</div>
<div id="menuitemradio_checked_true" role="menuitemradio" aria-checked="true">This menuitem has aria-checked="true" and should get STATE_CHECKABLE. It should also get STATE_checked.</div>
<div id="menuitemradio_checked_false" role="menuitemradio" aria-checked="false">This menuitem has aria-checked="false" and should get STATE_CHECKABLE.</div>
<div id="menuitemradio_checked_empty" role="menuitemradio" aria-checked="">This menuitem has aria-checked="" and should <emph>not</emph> get STATE_CHECKABLE.</div>
<div id="menuitemradio_checked_undefined" role="menuitemradio" aria-checked="undefined">This menuitem has aria-checked="undefined" and should <emph>not</emph> get STATE_CHECKABLE.</div>
<div id="menuitemradio_checked_absent" role="menuitemradio">This menuitem has <emph>no</emph> aria-checked attribute but should get STATE_CHECKABLE.</div>
</div>
<div id="radio_checked_true" role="radio" aria-checked="true">This menuitem has aria-checked="true" and should get STATE_CHECKABLE. It should also get STATE_CHECKED.</div>
<div id="radio_checked_false" role="radio" aria-checked="false">This menuitem has aria-checked="false" and should get STATE_CHECKABLE.</div>
<div id="radio_checked_empty" role="radio" aria-checked="">This menuitem has aria-checked="" and should <emph>not</emph> get STATE_CHECKABLE.</div>
<div id="radio_checked_undefined" role="radio" aria-checked="undefined">This menuitem has aria-checked="undefined" and should <emph>not</emph> get STATE_CHECKABLE.</div>
<div id="radio_checked_absent" role="radio">This menuitem has <emph>no</emph> aria-checked attribute but should get STATE_CHECKABLE.</div>
<div id="textbox_readonly_true" role="textbox" aria-readonly="true"></div>
<div id="textbox_readonly_false" role="textbox" aria-readonly="false"></div>
<div id="textbox_readonly_empty" role="textbox" aria-readonly=""></div>
<div id="textbox_readonly_undefined" role="textbox" aria-readonly="undefined"></div>
<div id="textbox_readonly_absent" role="textbox"></div>
<div id="textbox_multiline_true" role="textbox" aria-multiline="true"></div>
<div id="textbox_multiline_false" role="textbox" aria-multiline="false"></div>
<div id="textbox_multiline_empty" role="textbox" aria-multiline=""></div>
<div id="textbox_multiline_undefined" role="textbox" aria-multiline="undefined"></div>
<div id="textbox_multiline_absent" role="textbox"></div>
<form action="">
<input id="native_textbox_nativereadonly_ariatrue" readonly="readonly" aria-readonly="true"/>
<input id="native_textbox_nativereadonly_ariafalse" readonly="readonly" aria-readonly="false"/>
<input id="native_textbox_nativereadonly_ariaempty" readonly="readonly" aria-readonly=""/>
<input id="native_textbox_nativereadonly_ariaundefined" readonly="readonly" aria-readonly="undefined"/>
<input id="native_textbox_nativereadonly_ariaabsent" readonly="readonly"/>
<input id="native_textbox_nativeeditable_ariatrue" aria-readonly="true"/>
<input id="native_textbox_nativeeditable_ariafalse" aria-readonly="false"/>
<input id="native_textbox_nativeeditable_ariaempty" aria-readonly=""/>
<input id="native_textbox_nativeeditable_ariaundefined" aria-readonly="undefined"/>
<input id="native_textbox_nativeeditable_ariaabsent"/>
</form>
<div role="tree">
<div id="treeitem_selected_true" role="treeitem" aria-selected="true">This treeitem has aria-selected="true" and should get STATE_SELECTABLE. It should also get STATE_SELECTED.</div>
<div id="treeitem_selected_false" role="treeitem" aria-selected="false">This treeitem has aria-selected="false" and should get STATE_SELECTABLE.</div>
<div id="treeitem_selected_empty" role="treeitem" aria-selected="">This treeitem has aria-selected="" and should <emph>not</emph> get STATE_SELECTABLE.</div>
<div id="treeitem_selected_undefined" role="treeitem" aria-selected="undefined">This treeitem has aria-selected="undefined" and should <emph>not</emph> get STATE_SELECTABLE.</div>
<div id="treeitem_selected_absent" role="treeitem">This treeitem has <emph>no</emph> aria-selected attribute and should <emph>not</emph> get STATE_SELECTABLE.</div>
<div id="treeitem_haspopup_true" role="treeitem" aria-haspopup="true">This treeitem has aria-haspopup="true" and should get STATE_HASPOPUP.</div>
<div id="treeitem_haspopup_false" role="treeitem" aria-haspopup="false">This treeitem has aria-haspopup="false" and should get STATE_HASPOPUP.</div>
<div id="treeitem_haspopup_empty" role="treeitem" aria-haspopup="">This treeitem has aria-haspopup="" and should <emph>not</emph> get STATE_HASPOPUP.</div>
<div id="treeitem_haspopup_undefined" role="treeitem" aria-haspopup="undefined">This treeitem has aria-haspopup="undefined" and should <emph>not</emph> get STATE_HASPOPUP.</div>
<div id="treeitem_haspopup_absent" role="treeitem">This treeitem has <emph>no</emph> aria-haspopup attribute and should <emph>not</emph> get STATE_HASPOPUP.</div>
<div id="treeitem_expanded_true" role="treeitem" aria-expanded="true">This treeitem has aria-expanded="true" and should get STATE_EXPANDABLE. It should also get STATE_EXPANDED.</div>
<div id="treeitem_expanded_false" role="treeitem" aria-expanded="false">This treeitem has aria-expanded="false" and should get STATE_EXPANDABLE. It should also get STATE_COLLAPSED.</div>
<div id="treeitem_expanded_empty" role="treeitem" aria-expanded="">This treeitem has aria-expanded="" and should <emph>not</emph> get STATE_EXPANDABLE.</div>
<div id="treeitem_expanded_undefined" role="treeitem" aria-expanded="undefined">This treeitem has aria-expanded="undefined" and should <emph>not</emph> get STATE_EXPANDABLE.</div>
<div id="treeitem_expanded_absent" role="treeitem">This treeitem has <emph>no</emph> aria-expanded attribute and should <emph>not</emph> get STATE_EXPANDABLE.</div>
</div>
</body>
</html>

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

@ -68,7 +68,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=418368
var normalHyperlinkAcc = getAccessible("NormalHyperlink",
[nsIAccessibleHyperLink]);
testThis("NormalHyperlink", normalHyperlinkAcc, ROLE_LINK, 1,
"Mozilla Foundation", true, 18, 19);
"Mozilla Foundation", true, 17, 18);
is(normalHyperlinkAcc.getURI(0).spec, "http://www.mozilla.org/",
"URI wrong for normalHyperlinkElement!");
testStates(normalHyperlinkAcc,
@ -84,7 +84,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=418368
var ariaHyperlinkAcc = getAccessible("AriaHyperlink",
[nsIAccessibleHyperLink]);
testThis("AriaHyperlink", ariaHyperlinkAcc, ROLE_LINK, 1,
"Mozilla Foundation Home", true, 32, 33);
"Mozilla Foundation Home", true, 30, 31);
testStates(ariaHyperlinkAcc,
(STATE_FOCUSABLE | STATE_LINKED),
(EXT_STATE_HORIZONTAL));
@ -110,7 +110,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=418368
var imageMapHyperlinkAcc = getAccessible("imgmap",
[nsIAccessibleHyperLink]);
testThis("imgmap", imageMapHyperlinkAcc, ROLE_IMAGE_MAP, 2, "b", true,
83, 84);
79, 80);
is(imageMapHyperlinkAcc.getURI(0).spec,
"http://www.bbc.co.uk/radio4/atoz/index.shtml#b", "URI wrong!");
is(imageMapHyperlinkAcc.getURI(1).spec,
@ -137,7 +137,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=418368
// empty hyperlink
var EmptyHLAcc = getAccessible("emptyLink",
[nsIAccessibleHyperLink]);
testThis("emptyLink", EmptyHLAcc, ROLE_LINK, 1, null, true, 98, 99);
testThis("emptyLink", EmptyHLAcc, ROLE_LINK, 1, null, true, 93, 94);
testStates(EmptyHLAcc,
(STATE_FOCUSABLE | STATE_LINKED),
(EXT_STATE_HORIZONTAL));
@ -148,7 +148,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=418368
var hyperlinkWithSpanAcc = getAccessible("LinkWithSpan",
[nsIAccessibleHyperLink]);
testThis("LinkWithSpan", hyperlinkWithSpanAcc, ROLE_LINK, 1,
"Heise Online", true, 124, 125);
"Heise Online", true, 119, 120);
is(hyperlinkWithSpanAcc.getURI(0).spec, "http://www.heise.de/",
"URI wrong for hyperlinkElementWithSpan!");
testStates(hyperlinkWithSpanAcc,
@ -165,7 +165,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=418368
var namedAnchorAcc = getAccessible("namedAnchor",
[nsIAccessibleHyperLink]);
testThis("namedAnchor", namedAnchorAcc, ROLE_LINK, 1,
"This should never be of state_linked", true, 202, 203);
"This should never be of state_linked", true, 196, 197);
testStates(namedAnchorAcc,
(STATE_SELECTABLE),
(EXT_STATE_HORIZONTAL), (STATE_FOCUSABLE | STATE_LINKED));
@ -176,7 +176,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=418368
var noLinkAcc = getAccessible("noLink",
[nsIAccessibleHyperLink]);
testThis("noLink", noLinkAcc, ROLE_LINK, 1,
"This should never be of state_linked", true, 262, 263);
"This should never be of state_linked", true, 254, 255);
testStates(noLinkAcc,
0,
(EXT_STATE_HORIZONTAL), (STATE_FOCUSABLE | STATE_LINKED));
@ -187,7 +187,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=418368
var linkWithClickAcc = getAccessible("linkWithClick",
[nsIAccessibleHyperLink]);
testThis("linkWithClick", linkWithClickAcc, ROLE_LINK, 1,
"This should have state_linked", true, 301, 302);
"This should have state_linked", true, 292, 293);
testStates(linkWithClickAcc,
(STATE_LINKED),
(EXT_STATE_HORIZONTAL));
@ -201,7 +201,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=418368
// Link with title attribute, no name from the subtree (bug 438325).
var id = "linkWithTitleNoNameFromSubtree";
var linkAcc = getAccessible(id, [nsIAccessibleHyperLink]);
testThis(id, linkAcc, ROLE_LINK, 1, "Link with title", true, 354, 355);
testThis(id, linkAcc, ROLE_LINK, 1, "Link with title", true, 344, 345);
testStates(linkAcc,
(STATE_LINKED),
(EXT_STATE_HORIZONTAL));
@ -212,8 +212,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=418368
// (bug 438325).
id = "linkWithTitleNameFromSubtree";
linkAcc = getAccessible(id, [nsIAccessibleHyperLink]);
testThis(id, linkAcc, ROLE_LINK, 1, "the name from subtree", true, 403,
404);
testThis(id, linkAcc, ROLE_LINK, 1, "the name from subtree", true, 393,
394);
testStates(linkAcc,
(STATE_LINKED),
(EXT_STATE_HORIZONTAL));
@ -223,8 +223,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=418368
// Link with title attribute, name from the nested html:img (bug 438325).
id = "linkWithTitleNameFromImg";
linkAcc = getAccessible(id, [nsIAccessibleHyperLink]);
testThis(id, linkAcc, ROLE_LINK, 1, "The title for link", true, 458,
459);
testThis(id, linkAcc, ROLE_LINK, 1, "The title for link", true, 447,
448);
testStates(linkAcc,
(STATE_LINKED),
(EXT_STATE_HORIZONTAL));
@ -235,7 +235,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=418368
id = "linkWithLabelNoNameFromSubtree";
linkAcc = getAccessible(id, [nsIAccessibleHyperLink]);
testThis(id, linkAcc, ROLE_LINK, 1, "Link with label and nested image:",
true, 462, 463);
true, 450, 451);
testStates(linkAcc,
(STATE_LINKED),
(EXT_STATE_HORIZONTAL));
@ -250,78 +250,64 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=418368
addLoadEvent(doTest);
</script>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=418368">Mozilla Bug 418368</a>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
</pre>
<br>Simple link:<br>
<a id="NormalHyperlink" href="http://www.mozilla.org">Mozilla Foundation</a>
<br>ARIA link:<br>
<span id="AriaHyperlink" role="link"
<body><a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=418368">Mozilla Bug 418368</a
><p id="display"></p
><div id="content" style="display: none"></div
><pre id="test">
</pre
><br
>Simple link:<br
><a id="NormalHyperlink" href="http://www.mozilla.org">Mozilla Foundation</a
><br>ARIA link:<br
><span id="AriaHyperlink" role="link"
onclick="window.open('http://www.mozilla.org/');"
tabindex="0">Mozilla Foundation Home</span>
<br>Invalid, non-focusable hyperlink:<br>
<span id="InvalidAriaHyperlink" role="link" aria-invalid="true"
onclick="window.open('http:/www.mozilla.org/');">Invalid link</span>
<br>Image map:<br>
<map name="atoz_map">
<area href="http://www.bbc.co.uk/radio4/atoz/index.shtml#b"
tabindex="0">Mozilla Foundation Home</span
><br
>Invalid, non-focusable hyperlink:<br
><span id="InvalidAriaHyperlink" role="link" aria-invalid="true"
onclick="window.open('http:/www.mozilla.org/');">Invalid link</span
><br>Image map:<br
><map name="atoz_map"
><area href="http://www.bbc.co.uk/radio4/atoz/index.shtml#b"
coords="17,0,30,14"
alt="b"
shape="rect"></area>
<area href="http://www.bbc.co.uk/radio4/atoz/index.shtml#a"
coords="0,0,13,14"
alt="a"
shape="rect"></area>
</map>
<img width="447" id="imgmap"
height="15"
usemap="#atoz_map"
src="letters.gif"></img>
<br>Empty link:<br>
<a id="emptyLink" href=""><img src=""></img></a>
<br>Link with embedded span<br>
<a id="LinkWithSpan" href="http://www.heise.de/"><span lang="de">Heise Online</span></a>
<br>Named anchor, must not have "linked" state for it to be exposed correctly:<br>
<a id="namedAnchor" name="named_anchor">This should never be of state_linked</a>
<br>Link having no attributes, must not have "linked" state:</br>
<a id="noLink">This should never be of state_linked</a>
<br>Link with registered 'click' event: </br>
<a id="linkWithClick" onclick="var clicked = true;">This should have state_linked</a>
<br>Link with title attribute (no name from subtree): </br>
<a id="linkWithTitleNoNameFromSubtree" href="http://www.heise.de/"
title="Link with title"><img src=""/></a>
<br>Link with title attribute (name from subtree): </br>
<a id="linkWithTitleNameFromSubtree" href="http://www.heise.de/"
title="Link with title">the name from subtree</a>
<br>Link with title attribute (name from nested image): </br>
<a id="linkWithTitleNameFromImg" href="http://www.heise.de/"
title="Link with title"><img src="" alt="The title for link"/></a>
<br><label for="linkWithLabelNoNameFromSubtree">Link with label and nested image: </label></br>
<a id="linkWithLabelNoNameFromSubtree"
href="http://www.heise.de/"><img src=""/></a>
<br>Map that is used to group links (www.w3.org/TR/WCAG10-HTML-TECHS/#group-bypass),
also see the bug 431615:<br>
<map id="linksmap" title="Site navigation">
<ul>
<li><a href="http://mozilla.org">About the project</a></li>
<li><a href="http://mozilla.org">Sites and sounds</a></li>
</ul>
</map>
</body>
shape="rect"></area
><area href="http://www.bbc.co.uk/radio4/atoz/index.shtml#a"
coords="0,0,13,14"
alt="a"
shape="rect"></area
></map
><img width="447" id="imgmap"
height="15"
usemap="#atoz_map"
src="letters.gif"></img
><br>Empty link:<br
><a id="emptyLink" href=""><img src=""></img></a
><br>Link with embedded span<br
><a id="LinkWithSpan" href="http://www.heise.de/"><span lang="de">Heise Online</span></a
><br>Named anchor, must not have "linked" state for it to be exposed correctly:<br
><a id="namedAnchor" name="named_anchor">This should never be of state_linked</a
><br>Link having no attributes, must not have "linked" state:</br
><a id="noLink">This should never be of state_linked</a
><br>Link with registered 'click' event: </br
><a id="linkWithClick" onclick="var clicked = true;">This should have state_linked</a
><br>Link with title attribute (no name from subtree): </br
><a id="linkWithTitleNoNameFromSubtree" href="http://www.heise.de/"
title="Link with title"><img src=""/></a
><br>Link with title attribute (name from subtree): </br
><a id="linkWithTitleNameFromSubtree" href="http://www.heise.de/"
title="Link with title">the name from subtree</a
><br>Link with title attribute (name from nested image): </br
><a id="linkWithTitleNameFromImg" href="http://www.heise.de/"
title="Link with title"><img src="" alt="The title for link"/></a
><br><label for="linkWithLabelNoNameFromSubtree">Link with label and nested image: </label></br
><a id="linkWithLabelNoNameFromSubtree"
href="http://www.heise.de/"><img src=""/></a
><br>Map that is used to group links (www.w3.org/TR/WCAG10-HTML-TECHS/#group-bypass), also see the bug 431615:<br
><map id="linksmap" title="Site navigation"><ul
><li><a href="http://mozilla.org">About the project</a></li
><li><a href="http://mozilla.org">Sites and sounds</a></li
></ul
></map
></body>
</html>

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

@ -43,22 +43,22 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=428248
testThis("NormalHyperlink", 14, 0, "Mozilla Foundation");
// ARIA hyperlink
testThis("AriaHyperlink", 28, 1, "Mozilla Foundation Home");
testThis("AriaHyperlink", 27, 1, "Mozilla Foundation Home");
// ARIA hyperlink with status invalid
testThis("InvalidAriaHyperlink", 64, 2, "Invalid link");
testThis("InvalidAriaHyperlink", 63, 2, "Invalid link");
// image map, but not its link children. They are not part of hypertext.
testThis("imgmap", 78, 3, "b");
testThis("imgmap", 76, 3, "b");
// empty hyperlink
testThis("emptyLink", 93, 4, null);
testThis("emptyLink", 90, 4, null);
// normal hyperlink with embedded span
testThis("LinkWithSpan", 119, 5, "Heise Online");
testThis("LinkWithSpan", 116, 5, "Heise Online");
// Named anchor
testThis("namedAnchor", 197, 6, "This should never be of state_linked");
testThis("namedAnchor", 193, 6, "This should never be of state_linked");
SimpleTest.finish();
}
@ -74,37 +74,35 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=428248
<div id="content" style="display: none"></div>
<pre id="test">
</pre>
<p id="testParagraph">
<br>Simple link:<br>
<a id="NormalHyperlink" href="http://www.mozilla.org">Mozilla Foundation</a>
<br>ARIA link:<br>
<span id="AriaHyperlink" role="link"
onclick="window.open('http://www.mozilla.org/');"
tabindex="0">Mozilla Foundation Home</span>
<br>Invalid, non-focusable hyperlink:<br>
<span id="InvalidAriaHyperlink" role="link" aria-invalid="true"
onclick="window.open('http:/www.mozilla.org/');">Invalid link</span>
<br>Image map:<br>
<map name="atoz_map">
<area href="http://www.bbc.co.uk/radio4/atoz/index.shtml#b"
coords="17,0,30,14"
alt="b"
shape="rect"></area>
<area href="http://www.bbc.co.uk/radio4/atoz/index.shtml#a"
coords="0,0,13,14"
alt="a"
shape="rect"></area>
</map>
<img width="447" id="imgmap"
<p id="testParagraph"><br
>Simple link:<br
><a id="NormalHyperlink" href="http://www.mozilla.org">Mozilla Foundation</a><br
>ARIA link:<br
><span id="AriaHyperlink" role="link"
onclick="window.open('http://www.mozilla.org/');"
tabindex="0">Mozilla Foundation Home</span><br
>Invalid, non-focusable hyperlink:<br
><span id="InvalidAriaHyperlink" role="link" aria-invalid="true"
onclick="window.open('http:/www.mozilla.org/');">Invalid link</span><br
>Image map:<br
><map name="atoz_map"><area href="http://www.bbc.co.uk/radio4/atoz/index.shtml#b"
coords="17,0,30,14"
alt="b"
shape="rect"></area
><area href="http://www.bbc.co.uk/radio4/atoz/index.shtml#a"
coords="0,0,13,14"
alt="a"
shape="rect"></area></map
><img width="447" id="imgmap"
height="15"
usemap="#atoz_map"
src="letters.gif"></img>
<br>Empty link:<br>
<a id="emptyLink" href=""><img src=""></img></a>
<br>Link with embedded span<br>
<a id="LinkWithSpan" href="http://www.heise.de/"><span lang="de">Heise Online</span></a>
<br>Named anchor, must not have "linked" state for it to be exposed correctly:<br>
<a id="namedAnchor" name="named_anchor">This should never be of state_linked</a>
src="letters.gif"></img><br
>Empty link:<br
><a id="emptyLink" href=""><img src=""></img></a><br
>Link with embedded span<br
><a id="LinkWithSpan" href="http://www.heise.de/"><span lang="de">Heise Online</span></a><br
>Named anchor, must not have "linked" state for it to be exposed correctly:<br
><a id="namedAnchor" name="named_anchor">This should never be of state_linked</a>
</p>
</body>
</html>

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

@ -31,9 +31,24 @@
<script type="application/javascript">
function doTest()
{
// aria_autocomplete
testStates("textbox_autocomplete_inline", 0, EXT_STATE_SUPPORTS_AUTOCOMPLETION);
testStates("textbox_autocomplete_list", STATE_HASPOPUP, EXT_STATE_SUPPORTS_AUTOCOMPLETION);
testStates("textbox_autocomplete_both", STATE_HASPOPUP, EXT_STATE_SUPPORTS_AUTOCOMPLETION);
testStates("combobox_autocomplete_inline", STATE_HASPOPUP, EXT_STATE_SUPPORTS_AUTOCOMPLETION);
testStates("combobox_autocomplete_list", STATE_HASPOPUP, EXT_STATE_SUPPORTS_AUTOCOMPLETION);
testStates("combobox_autocomplete_both", STATE_HASPOPUP, EXT_STATE_SUPPORTS_AUTOCOMPLETION);
// aria-busy
testStates("textbox_busy_false", 0, 0, STATE_BUSY);
testStates("textbox_busy_true", STATE_BUSY);
testStates("textbox_busy_error", STATE_INVALID);
// aria-expanded
testStates("combobox", STATE_COLLAPSED);
testStates("combobox_expanded", STATE_EXPANDED);
// tri-state checkbox
var checkboxElem = getNode("check1");
if (checkboxElem) {
testStates(checkboxElem, STATE_CHECKED);
@ -43,6 +58,7 @@
testStates(checkboxElem, STATE_MIXED, 0);
}
// aria-checked
testStates("aria_checked_checkbox", STATE_CHECKED);
testStates("aria_mixed_checkbox", STATE_MIXED);
@ -50,6 +66,7 @@
// disabled, too. See bug 429285.
testStatesInSubtree("group", STATE_UNAVAILABLE);
// offscreen test
testStates("aria_offscreen_textbox", STATE_OFFSCREEN);
SimpleTest.finish();
@ -73,13 +90,28 @@
title="Propagate aria-disabled to descendants">
Mozilla Bug 429285
</a>
<a target="_blank"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=499653"
title="Unify ARIA state attributes mapping rules">
Mozilla Bug 499653
</a>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
</pre>
<div id="combobox" role="combobox">combobox</div>
<div id="textbox_autocomplete_inline" role="textbox" aria-autocomplete="inline"></div>
<div id="textbox_autocomplete_list" role="textbox" aria-autocomplete="list"></div>
<div id="textbox_autocomplete_both" role="textbox" aria-autocomplete="both"></div>
<div id="combobox_autocomplete_inline" role="combobox" aria-autocomplete="inline"></div>
<div id="combobox_autocomplete_list" role="combobox" aria-autocomplete="list"></div>
<div id="combobox_autocomplete_both" role="combobox" aria-autocomplete="both"></div>
<div id="textbox_busy_false" role="textbox" aria-busy="false"></div>
<div id="textbox_busy_true" role="textbox" aria-busy="true"></div>
<div id="textbox_busy_error" role="textbox" aria-busy="error"></div>
<div id="combobox" role="combobox">combobox</div>
<div id="combobox_expanded" role="combobox"
aria-expanded="true">combobox</div>

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

@ -745,7 +745,6 @@ var HistoryMenu = {
var menuPopup = aEvent.target;
var resultNode = menuPopup.getResultNode();
var wasOpen = resultNode.containerOpen;
resultNode.containerOpen = true;
document.getElementById("endHistorySeparator").hidden =
resultNode.childCount == 0;

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

@ -220,17 +220,23 @@
<ul>
<li>Josh Aas</li>
<li>Robert Accettura</li>
<li>Lucas Adamski</li>
<li>Ehsan Akhgari</li>
<li>Sean Alamares</li>
<li>Pedro Alves</li>
<li>David Anderson</li>
<li>Harvey Anderson</li>
<li>Smokey Ardisson</li>
<li>Rob Arnold</li>
<li>Tomoya Asai</li>
<li>Chris AtLee</li>
<li>Dietrich Ayala</li>
<li>Mitchell Baker</li>
<li>Rhian Baker</li>
<li>Jeff Balogh</li>
<li>Honza Bambas</li>
<li>Jan Bambas</li>
<li>Rey Bango</li>
<li>Mark Banner</li>
<li>Jason Barnabe</li>
<li>David Baron</li>
@ -247,6 +253,7 @@
<li>Christian Biesinger</li>
<li>Al Billings</li>
<li>Seth Bindernagel</li>
<li>Lukas Blakk</li>
<li>Jim Blandy</li>
<li>Chris Blizzard</li>
<li>Jamey Boje</li>
@ -258,9 +265,11 @@
<li>Jennifer Boriss</li>
<li>Dan Born</li>
<li>Arpad Borsos</li>
<li>David Boswell</li>
<li>Ondřej Brablc</li>
<li>Catherine Brady</li>
<li>Dave Bragsalla</li>
<li>Alex Buchanan</li>
<li>Igor Bukanov</li>
<li>Simon Bünzli</li>
<li>Lapo Calamandrei</li>
@ -273,6 +282,7 @@
<li>Emily Chen</li>
<li>Ginn Chen</li>
<li>Pascal Chevrel</li>
<li>Adam Christian</li>
<li>Tony Chung</li>
<li>Bob Clary</li>
<li>Wil Clouser</li>
@ -280,19 +290,25 @@
<li>Majken Connor</li>
<li>Mike Connor</li>
<li>Chris Cooper</li>
<li>Eric Cooper</li>
<li>Paul Craciunoiu</li>
<li>Brian Crowder</li>
<li>John Daggett</li>
<li>David Dahl</li>
<li>Michael Davis</li>
<li>Neil Deakin</li>
<li>Julie Deroche</li>
<li>Aakash Desai</li>
<li>Ryan Doherty</li>
<li>Justin Dolske</li>
<li>Stephen Donner</li>
<li>Asa Dotzler</li>
<li>Chris Double</li>
<li>Joe Drew</li>
<li>Jason Duell</li>
<li>Karsten Düsterloh</li>
<li>Brendan Eich</li>
<li>Daniel Einspanjer</li>
<li>Kai Engert</li>
<li>Steve England</li>
<li>Madhava Enros</li>
@ -311,6 +327,7 @@
<li>Eli Friedman</li>
<li>Andreas Gal</li>
<li>Steven Garrity</li>
<li>Armen Zambrano Gasparnian</li>
<li>Serge Gautherie</li>
<li>Kevin Gerich</li>
<li>Taras Glek</li>
@ -320,6 +337,7 @@
<li>Matthew Gregan</li>
<li>Will Guaraldi</li>
<li>Adam Guthrie</li>
<li>Mohammad Reza Haghighat</li>
<li>Andrei Hajdukewycz</li>
<li>Trevor Hardcastle</li>
<li>Basil Hashem</li>
@ -337,11 +355,14 @@
<li>Bobby Holley</li>
<li>Mike Hommey</li>
<li>Stephen Horlander</li>
<li>Barbara Hueppe</li>
<li>Anthony Hughes</li>
<li>David Humphrey</li>
<li>Takeshi Ichimaru</li>
<li>Chris Ilias</li>
<li>Eri Inoue </li>
<li>Eri Inoue</li>
<li>Joichi Ito</li>
<li>Steven Johnson</li>
<li>Laurent Jouanneau</li>
<li>Robert Kaiser</li>
<li>Gen Kanai</li>
@ -351,10 +372,12 @@
<li>Michael Kaply</li>
<li>Mitch Kapor</li>
<li>Kazuyoshi Kato</li>
<li>Tomomi Kato</li>
<li>Alfred Kayser</li>
<li>Jonathan Kew</li>
<li>Paul Kim</li>
<li>Masatoshi Kimura</li>
<li>Austin King</li>
<li>Ria Klaassen</li>
<li>Marcia Knous</li>
<li>Nelson Ko</li>
@ -362,7 +385,9 @@
<li>Gary Kwong</li>
<li>David Lanham</li>
<li>Brad Lassey</li>
<li>Delphine Lebédel</li>
<li>Edward Lee</li>
<li>Neil Lee</li>
<li>Raymond Lee</li>
<li>Garrett LeSage</li>
<li>Aaron Leventhal</li>
@ -381,6 +406,7 @@
<li>Gervase Markham</li>
<li>Sean Martell</li>
<li>Jim Mathies</li>
<li>Erica McClure</li>
<li>Graeme McCutcheon</li>
<li>Patrick McManus</li>
<li>Heather Meeker</li>
@ -388,6 +414,7 @@
<li>Myk Melez</li>
<li>Federico Mena-Quintero</li>
<li>Mark Mentovai</li>
<li>Laura Mesa</li>
<li>Steven Michaud</li>
<li>Matthew Middleton</li>
<li>Ted Mielczarek</li>
@ -396,27 +423,33 @@
<li>Dan Mills</li>
<li>Michael Monreal</li>
<li>Simon Montagu</li>
<li>Derek Moore</li>
<li>Mike Morgan</li>
<li>Tiffney Mortensen</li>
<li>Dan Mosedale</li>
<li>Michael Moy</li>
<li>Jeff Muizelaar</li>
<li>Masayuki Nakano</li>
<li>Murali Nandigama</li>
<li>Marria Nazif</li>
<li>Kev Needham</li>
<li>Kaori Negoro</li>
<li>Nicholas Nethercote</li>
<li>Ben Newman</li>
<li>Nick Nguyen</li>
<li>Johnathan Nightingale</li>
<li>Andreas Nilsson</li>
<li>Timothy Nikkel</li>
<li>Andreas Nilsson</li>
<li>Tristan Nitot</li>
<li>Alice Nodelman</li>
<li>Matthew Noorenberghe </li>
<li>Matthew Noorenberghe</li>
<li>Michal Novotny</li>
<li>Robert O'Callahan</li>
<li>John O'Duinn</li>
<li>Paul O'Shannessy</li>
<li>Jan Odvárko</li>
<li>Tomoyuki Okazaki</li>
<li>Les Orchard</li>
<li>Jeremy Orem</li>
<li>Jason Orendorff</li>
<li>Hideo Oshima</li>
@ -431,23 +464,29 @@
<li>Ulisse Perusin</li>
<li>Olli Pettay</li>
<li>Julien Pierre</li>
<li>Anthony Piraino</li>
<li>Alex Polvi</li>
<li>Nickolay Ponomarev</li>
<li>Dan Portillo</li>
<li>Karen Prescott</li>
<li>Florian Quèze</li>
<li>Krupa Raj</li>
<li>Arun Ranganathan</li>
<li>Neil Rashbrook</li>
<li>Bret Reckard</li>
<li>J. Paul Reed</li>
<li>Rick Reitmaier</li>
<li>Robert Relyea</li>
<li>John Resig</li>
<li>Deb Richardson</li>
<li>Tim Riley</li>
<li>Phil Ringnalda</li>
<li>Julien Rivaud</li>
<li>Mikeal Rogers</li>
<li>David Rolnitzky</li>
<li>Asaf Romano</li>
<li>Oleg Romashin</li>
<li>Paul Rouget</li>
<li>Tim Rowley</li>
<li>Jesse Ruderman</li>
<li>Brian Ryner</li>
@ -456,6 +495,7 @@
<li>Atsushi Sakai</li>
<li>Eiko Sakuma</li>
<li>Andrei Saprykin</li>
<li>Aki Sasaki</li>
<li>Ken Saunders</li>
<li>Robert Sayre</li>
<li>Mike Schroepfer</li>
@ -492,17 +532,24 @@
<li>Brandon Sterne</li>
<li>Rob Stradling</li>
<li>Robert Strong</li>
<li>Jay Sullivan</li>
<li>Vicky Sun</li>
<li>Alexander Surkov</li>
<li>Mark Surman</li>
<li>Andrew Sutherland</li>
<li>Clint Talbert</li>
<li>Margaret Tallman</li>
<li>David Tenser</li>
<li>Chris Thomas</li>
<li>Nick Thomas</li>
<li>Laura Thomson</li>
<li>Karl Tomlinson</li>
<li>Dave Townsend</li>
<li>Aaron Train</li>
<li>Phong Tran</li>
<li>Ben Turner</li>
<li>Doug Turner</li>
<li>Amié Tyrrel</li>
<li>Peter Van der Beken</li>
<li>Peter van der Woude</li>
<li>Teune van Steeg</li>
@ -523,6 +570,7 @@
<li>Steffen Wilberg</li>
<li>Drew Willcoxon</li>
<li>Shawn Wilsher</li>
<li>Kathleen Wilson</li>
<li>Dan Witte</li>
<li>John Wolfe</li>
<li>Steve Won</li>

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

@ -242,17 +242,25 @@ function openUILinkIn( url, where, allowThirdPartyFixup, postData, referrerUrl )
loadInBackground = !loadInBackground;
// fall through
case "tab":
var browser = w.getBrowser();
let browser = w.getBrowser();
browser.loadOneTab(url, referrerUrl, null, postData, loadInBackground,
allowThirdPartyFixup || false);
break;
}
// Focus the content but don't raise the window, since the URI we just loaded
// may have resulted in a new frontmost window (e.g. "javascript:window.open('');").
var browser = w.getBrowserFromContentWindow(w.content);
if (browser)
browser.focus();
// If this window is active, focus the target window. Otherwise, focus the
// content but don't raise the window, since the URI we just loaded may have
// resulted in a new frontmost window (e.g. "javascript:window.open('');").
var fm = Components.classes["@mozilla.org/focus-manager;1"].
getService(Components.interfaces.nsIFocusManager);
if (window == fm.activeWindow) {
w.content.focus();
}
else {
let browser = w.getBrowserFromContentWindow(w.content);
if (browser)
browser.focus();
}
}
// Used as an onclick handler for UI elements with link-like behavior.

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

@ -154,7 +154,7 @@ PlacesController.prototype = {
var result = this._view.getResult();
if (result) {
var container = asContainer(result.root);
if (container.childCount > 0);
if (container.containerOpen && container.childCount > 0);
return true;
}
}

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

@ -748,7 +748,7 @@
return;
var children = popup.childNodes;
for (var i = 0; i < children.length; i++) {
for (var i = popup._startMarker + 1; i < children.length; i++) {
if (children[i].node == aNode) {
this._self.removeItem(children[i]);
if (!popup.hasChildNodes() ||
@ -771,7 +771,7 @@
var popup = this._getPopupForContainer(aNewParent);
var index = popup._startMarker + 1 + aNewIndex;
var children = popup.childNodes;
for (var i = 0; i < children.length; i++) {
for (var i = popup._startMarker + 1; i < children.length; i++) {
var menuItem = children[i];
if (menuItem.node == aItem) {
popup.removeChild(menuItem);
@ -787,24 +787,24 @@
if (!parentNode)
return;
if (PlacesUtils.nodeIsSeparator(aNode)) {
// nothing to do when a separator changes
return;
}
var popup = this._getPopupForContainer(parentNode);
if (!popup._built)
return;
var children = popup.childNodes;
var menuitem;
for (var i = 0; i < children.length; i++) {
for (var i = popup._startMarker + 1; i < children.length; i++) {
if (children[i].node == aNode) {
menuitem = children[i];
break;
}
}
if (PlacesUtils.nodeIsSeparator(aNode)) {
// nothing to do when a separator changes
return;
}
var iconURI = aNode.icon;
if (iconURI) {
var spec = iconURI.spec;
@ -837,7 +837,7 @@
return;
var children = popup.childNodes;
for (var i = 0; i < children.length; i++) {
for (var i = popup._startMarker + 1; i < children.length; i++) {
if (children[i].node == aOldNode) {
var next = children[i].nextSibling;
this._self.removeItem(children[i]);

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

@ -129,8 +129,10 @@
<field name="_chevron">document.getAnonymousElementByAttribute(this, "class", "chevron")</field>
<field name="_openedMenuButton">null</field>
<field name="_allowPopupShowing">true</field>
<field name="_result">null</field>
<field name="_resultNode">null</field>
<!-- nsIPlacesView -->
<method name="getResult">
@ -526,7 +528,7 @@
return;
var children = popup.childNodes;
for (var i = 0; i < children.length; i++) {
for (var i = popup._startMarker + 1; i < children.length; i++) {
if (children[i].node == aNode) {
this._self.removeItem(children[i]);
if (!popup.hasChildNodes() ||
@ -559,7 +561,7 @@
this._self.insertBefore(button, children[aNewIndex]);
if (chevronPopup) {
// Maintain chevron in sync
menuitem = chevronPopup.childNodes[i];
var menuitem = chevronPopup.childNodes[i];
chevronPopup.removeChild(menuitem);
chevronPopup.insertBefore(menuitem,
chevronPopup.childNodes[aNewIndex]);
@ -569,14 +571,16 @@
}
}
}
var popup = this._getPopupForContainer(aNewParent);
var children = popup.childNodes;
for (var i = 0; i < children.length; i++) {
var menuItem = children[i];
if (menuItem.node == aItem) {
popup.removeChild(menuItem);
popup.insertBefore(menuItem, children[aNewIndex]);
return;
else {
var popup = this._getPopupForContainer(aNewParent);
var children = popup.childNodes;
for (var i = popup._startMarker + 1; i < children.length; i++) {
var menuItem = children[i];
if (menuItem.node == aItem) {
popup.removeChild(menuItem);
popup.insertBefore(menuItem, children[aNewIndex]);
return;
}
}
}
},
@ -587,6 +591,11 @@
if (!parentNode)
return;
if (PlacesUtils.nodeIsSeparator(aNode)) {
// nothing to do when a separator changes
return;
}
var element;
var onToolbar = false;
if (parentNode == this._self.getResultNode()) {
@ -607,7 +616,7 @@
return;
var children = popup.childNodes;
for (var i = 0; i < children.length; i++) {
for (var i = popup._startMarker + 1; i < children.length; i++) {
if (children[i].node == aNode) {
element = children[i];
break;
@ -616,11 +625,6 @@
var title = PlacesUIUtils.getBestTitle(aNode);
}
if (PlacesUtils.nodeIsSeparator(aNode)) {
// nothing to do when a separator changes
return;
}
var iconURI = aNode.icon;
if (iconURI) {
var spec = iconURI.spec;
@ -662,8 +666,6 @@
}
}
}
else
this._forwardToChildView(aParentNode, "itemReplaced", arguments);
},
containerOpened: function TV_V_containerOpened(aNode) {
@ -950,7 +952,7 @@
// * Timer to turn off indicator bar.
if (aTimer == this._ibTimer) {
ib = this._dropIndicatorBar.removeAttribute('dragging');
this._dropIndicatorBar.removeAttribute('dragging');
this._ibTimer = null;
}
@ -1195,14 +1197,17 @@
}
]]></handler>
#ifdef XP_UNIX
#ifndef XP_MACOSX
<handler event="mousedown"><![CDATA[
var target = event.target;
if (event.button == 0 &&
target.localName == "toolbarbutton" &&
target.getAttribute("type") == "menu") {
this._allowPopupShowing = false;
// This is a container, we will open the menu if the user clicks
// or drag toward down or after a delay
// On Linux we can open the popup only after a delay.
// Indeed as soon as the menupopup opens we are unable to start a
// drag event. See bug 500081 for details.
this._mouseDownTimer = Cc["@mozilla.org/timer;1"]
.createInstance(Ci.nsITimer);
var callback = {
@ -1214,15 +1219,12 @@
}
};
this._mouseDownTimer.initWithCallback(callback, 500,
this._mouseDownTimer.initWithCallback(callback, 300,
Ci.nsITimer.TYPE_ONE_SHOT);
}
else {
// allow opening popups, like the chevron and context menus
this._allowPopupShowing = true;
}
]]></handler>
#endif
#endif
<handler event="mouseup"><![CDATA[
if (event.button != 0)
return;

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

@ -355,8 +355,6 @@ public:
// nsIContentSink (superclass of nsIHTMLContentSink)
NS_IMETHOD WillParse() { return NS_OK; }
NS_IMETHOD WillBuildModel() { return NS_OK; }
NS_IMETHOD DidBuildModel() { return NS_OK; }
NS_IMETHOD WillInterrupt() { return NS_OK; }
NS_IMETHOD WillResume() { return NS_OK; }
NS_IMETHOD SetParser(nsIParser* aParser) { return NS_OK; }

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

@ -329,13 +329,29 @@ function placesAggregateTransactions(name, transactions) {
this._name = name;
this.container = -1;
this.redoTransaction = this.doTransaction;
// Check child transactions number. We will batch if we have more than
// MIN_TRANSACTIONS_FOR_BATCH total number of transactions.
var countTransactions = function(aTransactions, aTxnCount) {
for (let i = 0;
i < aTransactions.length && aTxnCount < MIN_TRANSACTIONS_FOR_BATCH;
i++, aTxnCount++) {
let txn = aTransactions[i].wrappedJSObject;
if (txn && txn.childTransactions && txn.childTransactions.length)
aTxnCount = countTransactions(txn.childTransactions, aTxnCount);
}
return aTxnCount;
}
var txnCount = countTransactions(transactions, 0);
this._useBatch = txnCount >= MIN_TRANSACTIONS_FOR_BATCH;
}
placesAggregateTransactions.prototype = {
__proto__: placesBaseTransaction.prototype,
doTransaction: function PAT_doTransaction() {
if (this._transactions.length >= MIN_TRANSACTIONS_FOR_BATCH) {
if (this._useBatch) {
var callback = {
_self: this,
runBatched: function() {
@ -349,7 +365,7 @@ placesAggregateTransactions.prototype = {
},
undoTransaction: function PAT_undoTransaction() {
if (this._transactions.length >= MIN_TRANSACTIONS_FOR_BATCH) {
if (this._useBatch) {
var callback = {
_self: this,
runBatched: function() {
@ -363,7 +379,9 @@ placesAggregateTransactions.prototype = {
},
commit: function PAT_commit(aUndo) {
var transactions = this._transactions;
// Use a copy of the transactions array, so we won't reverse the original
// one on undoing.
var transactions = this._transactions.slice(0);
if (aUndo)
transactions.reverse();
for (var i = 0; i < transactions.length; i++) {
@ -386,7 +404,7 @@ function placesCreateFolderTransactions(aName, aContainer, aIndex,
this._index = typeof(aIndex) == "number" ? aIndex : -1;
this._annotations = aAnnotations;
this._id = null;
this._childItemsTransactions = aChildItemsTransactions || [];
this.childTransactions = aChildItemsTransactions || [];
this.redoTransaction = this.doTransaction;
}
@ -403,19 +421,25 @@ placesCreateFolderTransactions.prototype = {
if (this._annotations && this._annotations.length > 0)
PlacesUtils.setAnnotationsForItem(this._id, this._annotations);
for (var i = 0; i < this._childItemsTransactions.length; ++i) {
var txn = this._childItemsTransactions[i];
txn.wrappedJSObject.container = this._id;
txn.doTransaction();
if (this.childTransactions.length) {
// Set the new container id into child transactions.
for (var i = 0; i < this.childTransactions.length; ++i) {
this.childTransactions[i].wrappedJSObject.container = this._id;
}
let aggregateTxn = new placesAggregateTransactions("Create folder childTxn",
this.childTransactions);
aggregateTxn.doTransaction();
}
},
undoTransaction: function PCFT_undoTransaction() {
// Undo transactions should always be done in reverse order.
for (var i = this._childItemsTransactions.length - 1; i >= 0 ; i--) {
var txn = this._childItemsTransactions[i];
txn.undoTransaction();
if (this.childTransactions.length) {
let aggregateTxn = new placesAggregateTransactions("Create folder childTxn",
this.childTransactions);
aggregateTxn.undoTransaction();
}
// Remove item only after all child transactions have been reverted.
PlacesUtils.bookmarks.removeFolder(this._id);
}
@ -430,7 +454,7 @@ function placesCreateItemTransactions(aURI, aContainer, aIndex, aTitle,
this._title = aTitle;
this._keyword = aKeyword;
this._annotations = aAnnotations;
this._childTransactions = aChildTransactions || [];
this.childTransactions = aChildTransactions || [];
this.redoTransaction = this.doTransaction;
}
@ -448,20 +472,26 @@ placesCreateItemTransactions.prototype = {
PlacesUtils.bookmarks.setKeywordForBookmark(this._id, this._keyword);
if (this._annotations && this._annotations.length > 0)
PlacesUtils.setAnnotationsForItem(this._id, this._annotations);
for (var i = 0; i < this._childTransactions.length; ++i) {
var txn = this._childTransactions[i];
txn.wrappedJSObject.id = this._id;
txn.doTransaction();
if (this.childTransactions.length) {
// Set the new item id into child transactions.
for (var i = 0; i < this.childTransactions.length; ++i) {
this.childTransactions[i].wrappedJSObject.id = this._id;
}
let aggregateTxn = new placesAggregateTransactions("Create item childTxn",
this.childTransactions);
aggregateTxn.doTransaction();
}
},
undoTransaction: function PCIT_undoTransaction() {
// Undo transactions should always be done in reverse order.
for (var i = this._childTransactions.length - 1; i >= 0; i--) {
var txn = this._childTransactions[i];
txn.undoTransaction();
if (this.childTransactions.length) {
// Undo transactions should always be done in reverse order.
let aggregateTxn = new placesAggregateTransactions("Create item childTxn",
this.childTransactions);
aggregateTxn.undoTransaction();
}
// Remove item only after all child transactions have been reverted.
PlacesUtils.bookmarks.removeItem(this._id);
}
@ -598,9 +628,10 @@ function placesRemoveItemTransaction(aItemId) {
this._id = aItemId;
this._itemType = PlacesUtils.bookmarks.getItemType(this._id);
if (this._itemType == Ci.nsINavBookmarksService.TYPE_FOLDER) {
this._transactions = [];
this._removeTxn = PlacesUtils.bookmarks
.getRemoveFolderTransaction(this._id);
this.childTransactions = this._getFolderContentsTransactions();
// Remove this folder itself.
let txn = PlacesUtils.bookmarks.getRemoveFolderTransaction(this._id);
this.childTransactions.push(txn);
}
else if (this._itemType == Ci.nsINavBookmarksService.TYPE_BOOKMARK) {
this._uri = PlacesUtils.bookmarks.getBookmarkURI(this._id);
@ -623,14 +654,9 @@ placesRemoveItemTransaction.prototype = {
this._oldIndex = PlacesUtils.bookmarks.getItemIndex(this._id);
if (this._itemType == Ci.nsINavBookmarksService.TYPE_FOLDER) {
this._saveFolderContents();
// Remove children backwards to preserve parent-child relationships.
for (var i = this._transactions.length - 1; i >= 0; --i)
this._transactions[i].doTransaction();
// Remove this folder itself.
this._removeTxn.doTransaction();
let aggregateTxn = new placesAggregateTransactions("Remove item childTxn",
this.childTransactions);
aggregateTxn.doTransaction();
}
else {
PlacesUtils.bookmarks.removeItem(this._id);
@ -658,10 +684,9 @@ placesRemoveItemTransaction.prototype = {
PlacesUtils.bookmarks.setKeywordForBookmark(this._id, this._keyword);
}
else if (this._itemType == Ci.nsINavBookmarksService.TYPE_FOLDER) {
this._removeTxn.undoTransaction();
// Create children forwards to preserve parent-child relationships.
for (var i = 0; i < this._transactions.length; ++i)
this._transactions[i].undoTransaction();
let aggregateTxn = new placesAggregateTransactions("Remove item childTxn",
this.childTransactions);
aggregateTxn.undoTransaction();
}
else // TYPE_SEPARATOR
this._id = PlacesUtils.bookmarks.insertSeparator(this._oldContainer, this._oldIndex);
@ -674,18 +699,21 @@ placesRemoveItemTransaction.prototype = {
},
/**
* Create a flat, ordered list of transactions for a depth-first recreation
* Returns a flat, ordered list of transactions for a depth-first recreation
* of items within this folder.
*/
_saveFolderContents: function PRIT__saveFolderContents() {
this._transactions = [];
_getFolderContentsTransactions:
function PRIT__getFolderContentsTransactions() {
var transactions = [];
var contents =
PlacesUtils.getFolderContents(this._id, false, false).root;
for (var i = 0; i < contents.childCount; ++i) {
this._transactions
.push(new placesRemoveItemTransaction(contents.getChild(i).itemId));
let txn = new placesRemoveItemTransaction(contents.getChild(i).itemId);
transactions.push(txn);
}
contents.containerOpen = false;
// Reverse transactions to preserve parent-child relationship.
return transactions.reverse();
}
};

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

@ -60,6 +60,8 @@ _BROWSER_TEST_FILES = \
browser_library_left_pane_commands.js \
browser_drag_bookmarks_on_toolbar.js \
browser_library_middleclick.js \
browser_library_views_liveupdate.js \
browser_views_liveupdate.js \
$(NULL)
libs:: $(_BROWSER_TEST_FILES)

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

@ -84,6 +84,10 @@ var gTabsListener = {
if (gCurrentTest.URIs.indexOf(spec) != -1 )
this._loadedURIs.push(spec);
var fm = Components.classes["@mozilla.org/focus-manager;1"].
getService(Components.interfaces.nsIFocusManager);
is(fm.activeWindow, gBrowser.ownerDocument.defaultView, "window made active");
if (this._loadedURIs.length == gCurrentTest.URIs.length) {
// We have correctly opened all URIs.

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

@ -0,0 +1,320 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Mozilla Corporation.
* Portions created by the Initial Developer are Copyright (C) 2009
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Marco Bonardo <mak77@bonardo.net>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/**
* Tests Library Left pane view for liveupdate.
*/
const Cc = Components.classes;
const Ci = Components.interfaces;
var gLibrary = null;
function test() {
waitForExplicitFinish();
// Sanity checks.
ok(PlacesUtils, "PlacesUtils in context");
ok(PlacesUIUtils, "PlacesUIUtils in context");
// Open Library, we will check the left pane.
var ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].
getService(Ci.nsIWindowWatcher);
var windowObserver = {
observe: function(aSubject, aTopic, aData) {
if (aTopic === "domwindowopened") {
ww.unregisterNotification(this);
gLibrary = aSubject.QueryInterface(Ci.nsIDOMWindow);
gLibrary.addEventListener("load", function onLoad(event) {
gLibrary.removeEventListener("load", onLoad, false);
executeSoon(startTest);
}, false);
}
}
};
ww.registerNotification(windowObserver);
ww.openWindow(null,
"chrome://browser/content/places/places.xul",
"",
"chrome,toolbar=yes,dialog=no,resizable",
null);
}
/**
* Adds bookmarks observer, and executes a bunch of bookmarks operations.
*/
function startTest() {
var bs = PlacesUtils.bookmarks;
// Add bookmarks observer.
bs.addObserver(bookmarksObserver, false);
var addedBookmarks = [];
// MENU
ok(true, "*** Acting on menu bookmarks");
var id = bs.insertBookmark(bs.bookmarksMenuFolder,
PlacesUtils._uri("http://bm1.mozilla.org/"),
bs.DEFAULT_INDEX,
"bm1");
addedBookmarks.push(id);
id = bs.insertBookmark(bs.bookmarksMenuFolder,
PlacesUtils._uri("place:"),
bs.DEFAULT_INDEX,
"bm2");
addedBookmarks.push(id);
id = bs.insertSeparator(bs.bookmarksMenuFolder, bs.DEFAULT_INDEX);
addedBookmarks.push(id);
id = bs.createFolder(bs.bookmarksMenuFolder,
"bmf",
bs.DEFAULT_INDEX);
addedBookmarks.push(id);
id = bs.insertBookmark(id,
PlacesUtils._uri("http://bmf1.mozilla.org/"),
bs.DEFAULT_INDEX,
"bmf1");
addedBookmarks.push(id);
bs.moveItem(id, bs.bookmarksMenuFolder, 0);
// TOOLBAR
ok(true, "*** Acting on toolbar bookmarks");
bs.insertBookmark(bs.toolbarFolder,
PlacesUtils._uri("http://tb1.mozilla.org/"),
bs.DEFAULT_INDEX,
"tb1");
addedBookmarks.push(id);
id = bs.insertBookmark(bs.toolbarFolder,
PlacesUtils._uri("place:"),
bs.DEFAULT_INDEX,
"tb2");
addedBookmarks.push(id);
id = bs.insertSeparator(bs.toolbarFolder, bs.DEFAULT_INDEX);
addedBookmarks.push(id);
id = bs.createFolder(bs.toolbarFolder,
"tbf",
bs.DEFAULT_INDEX);
addedBookmarks.push(id);
id = bs.insertBookmark(id,
PlacesUtils._uri("http://tbf1.mozilla.org/"),
bs.DEFAULT_INDEX,
"bmf1");
addedBookmarks.push(id);
bs.moveItem(id, bs.toolbarFolder, 0);
// UNSORTED
ok(true, "*** Acting on unsorted bookmarks");
id = bs.insertBookmark(bs.unfiledBookmarksFolder,
PlacesUtils._uri("http://ub1.mozilla.org/"),
bs.DEFAULT_INDEX,
"ub1");
addedBookmarks.push(id);
id = bs.insertBookmark(bs.unfiledBookmarksFolder,
PlacesUtils._uri("place:"),
bs.DEFAULT_INDEX,
"ub2");
addedBookmarks.push(id);
id = bs.insertSeparator(bs.unfiledBookmarksFolder, bs.DEFAULT_INDEX);
addedBookmarks.push(id);
id = bs.createFolder(bs.unfiledBookmarksFolder,
"ubf",
bs.DEFAULT_INDEX);
addedBookmarks.push(id);
id = bs.insertBookmark(id,
PlacesUtils._uri("http://ubf1.mozilla.org/"),
bs.DEFAULT_INDEX,
"ubf1");
addedBookmarks.push(id);
bs.moveItem(id, bs.unfiledBookmarksFolder, 0);
// Remove all added bookmarks.
addedBookmarks.forEach(function (aItem) {
// If we remove an item after its containing folder has been removed,
// this will throw, but we can ignore that.
try {
bs.removeItem(aItem);
} catch (ex) {}
});
// Remove bookmarks observer.
bs.removeObserver(bookmarksObserver);
finishTest();
}
/**
* Restores browser state and calls finish.
*/
function finishTest() {
// Close Library window.
gLibrary.close();
finish();
}
/**
* The observer is where magic happens, for every change we do it will look for
* nodes positions in the affected views.
*/
var bookmarksObserver = {
QueryInterface: function PSB_QueryInterface(aIID) {
if (aIID.equals(Ci.nsINavBookmarkObserver) ||
aIID.equals(Ci.nsISupports))
return this;
throw Cr.NS_NOINTERFACE;
},
// nsINavBookmarkObserver
onItemAdded: function PSB_onItemAdded(aItemId, aFolderId, aIndex) {
var node = null;
var index = null;
[node, index] = getNodeForTreeItem(aItemId, gLibrary.PlacesOrganizer._places);
// Left pane should not be updated for normal bookmarks or separators.
var type = PlacesUtils.bookmarks.getItemType(aItemId);
switch (type) {
case PlacesUtils.bookmarks.TYPE_BOOKMARK:
var uriString = PlacesUtils.bookmarks.getBookmarkURI(aItemId).spec;
var isQuery = uriString.substr(0, 6) == "place:";
if (isQuery) {
isnot(node, null, "Found new Places node in left pane");
ok(index >= 0, "Node is at index " + index);
break;
}
// Fallback to separator case if this is not a query.
case PlacesUtils.bookmarks.TYPE_SEPARATOR:
is(node, null, "New Places node not added in left pane");
break;
default:
isnot(node, null, "Found new Places node in left pane");
ok(index >= 0, "Node is at index " + index);
}
},
onItemRemoved: function PSB_onItemRemoved(aItemId, aFolder, aIndex) {
var node = null;
var index = null;
[node, index] = getNodeForTreeItem(aItemId, gLibrary.PlacesOrganizer._places);
is(node, null, "Places node not found in left pane");
},
onItemMoved: function(aItemId,
aOldFolderId, aOldIndex,
aNewFolderId, aNewIndex) {
var node = null;
var index = null;
[node, index] = getNodeForTreeItem(aItemId, gLibrary.PlacesOrganizer._places);
// Left pane should not be updated for normal bookmarks or separators.
var type = PlacesUtils.bookmarks.getItemType(aItemId);
switch (type) {
case PlacesUtils.bookmarks.TYPE_BOOKMARK:
var uriString = PlacesUtils.bookmarks.getBookmarkURI(aItemId).spec;
var isQuery = uriString.substr(0, 6) == "place:";
if (isQuery) {
isnot(node, null, "Found new Places node in left pane");
ok(index >= 0, "Node is at index " + index);
break;
}
// Fallback to separator case if this is not a query.
case type == PlacesUtils.bookmarks.TYPE_SEPARATOR:
is(node, null, "New Places node not added in left pane");
break;
default:
isnot(node, null, "Found new Places node in left pane");
ok(index >= 0, "Node is at index " + index);
}
},
onBeginUpdateBatch: function PSB_onBeginUpdateBatch() {},
onEndUpdateBatch: function PSB_onEndUpdateBatch() {},
onBeforeItemRemoved: function PSB_onBeforeItemRemoved(aItemId) {},
onItemVisited: function() {},
onItemChanged: function PSB_onItemChanged(aItemId, aProperty,
aIsAnnotationProperty, aValue) {}
};
/**
* Get places node and index for an itemId in a tree view.
*
* @param aItemId
* item id of the item to search.
* @returns [node, index] or [null, null] if not found.
*/
function getNodeForTreeItem(aItemId, aTree) {
function findNode(aContainerIndex) {
if (aTree.view.isContainerEmpty(aContainerIndex))
return [null, null];
// The rowCount limit is just for sanity, but we will end looping when
// we have checked the last child of this container or we have found node.
for (var i = aContainerIndex + 1; i < aTree.view.rowCount; i++) {
var node = aTree.view.nodeForTreeIndex(i);
if (node.itemId == aItemId) {
// Minus one because we want relative index inside the container.
return [node, i - aTree.view.getParentIndex(i) - 1];
}
if (PlacesUtils.nodeIsFolder(node)) {
// Open container.
aTree.view.toggleOpenState(i);
// Search inside it.
var foundNode = findNode(i);
// Close container.
aTree.view.toggleOpenState(i);
// Return node if found.
if (foundNode[0] != null)
return foundNode;
}
// We have finished walking this container.
if (!aTree.view.hasNextSibling(aContainerIndex + 1, i))
break;
}
return [null, null]
}
// Root node is hidden, so we need to manually walk the first level.
for (var i = 0; i < aTree.view.rowCount; i++) {
// Open container.
aTree.view.toggleOpenState(i);
// Search inside it.
var foundNode = findNode(i);
// Close container.
aTree.view.toggleOpenState(i);
// Return node if found.
if (foundNode[0] != null)
return foundNode;
}
return [null, null];
}

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

@ -0,0 +1,438 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Mozilla Corporation.
* Portions created by the Initial Developer are Copyright (C) 2009
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Marco Bonardo <mak77@bonardo.net>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/**
* Tests Places views (menu, toolbar, tree) for liveupdate.
*/
const Cc = Components.classes;
const Ci = Components.interfaces;
function test() {
dump("Starting test browser_views_liveupdate.js\n");
waitForExplicitFinish();
// Sanity checks.
ok(PlacesUtils, "PlacesUtils in context");
ok(PlacesUIUtils, "PlacesUIUtils in context");
// Open bookmarks menu.
var menu = document.getElementById("bookmarksMenu");
menu.open = true;
// Open bookmarks sidebar.
var sidebar = document.getElementById("sidebar");
sidebar.addEventListener("load", function() {
sidebar.removeEventListener("load", arguments.callee, true);
// Need to executeSoon since the tree is initialized on sidebar load.
executeSoon(startTest);
}, true);
toggleSidebar("viewBookmarksSidebar", true);
}
/**
* Adds bookmarks observer, and executes a bunch of bookmarks operations.
*/
function startTest() {
var bs = PlacesUtils.bookmarks;
// Add bookmarks observer.
bs.addObserver(bookmarksObserver, false);
var addedBookmarks = [];
// MENU
ok(true, "*** Acting on menu bookmarks");
var id = bs.insertBookmark(bs.bookmarksMenuFolder,
PlacesUtils._uri("http://bm1.mozilla.org/"),
bs.DEFAULT_INDEX,
"bm1");
addedBookmarks.push(id);
id = bs.insertBookmark(bs.bookmarksMenuFolder,
PlacesUtils._uri("place:"),
bs.DEFAULT_INDEX,
"bm2");
addedBookmarks.push(id);
id = bs.insertSeparator(bs.bookmarksMenuFolder, bs.DEFAULT_INDEX);
addedBookmarks.push(id);
id = bs.createFolder(bs.bookmarksMenuFolder,
"bmf",
bs.DEFAULT_INDEX);
addedBookmarks.push(id);
id = bs.insertBookmark(id,
PlacesUtils._uri("http://bmf1.mozilla.org/"),
bs.DEFAULT_INDEX,
"bmf1");
addedBookmarks.push(id);
bs.moveItem(id, bs.bookmarksMenuFolder, 0);
// TOOLBAR
ok(true, "*** Acting on toolbar bookmarks");
id = bs.insertBookmark(bs.toolbarFolder,
PlacesUtils._uri("http://tb1.mozilla.org/"),
bs.DEFAULT_INDEX,
"tb1");
addedBookmarks.push(id);
id = bs.insertBookmark(bs.toolbarFolder,
PlacesUtils._uri("place:"),
bs.DEFAULT_INDEX,
"tb2");
addedBookmarks.push(id);
id = bs.insertSeparator(bs.toolbarFolder, bs.DEFAULT_INDEX);
addedBookmarks.push(id);
id = bs.createFolder(bs.toolbarFolder,
"tbf",
bs.DEFAULT_INDEX);
addedBookmarks.push(id);
id = bs.insertBookmark(id,
PlacesUtils._uri("http://tbf1.mozilla.org/"),
bs.DEFAULT_INDEX,
"bmf1");
addedBookmarks.push(id);
bs.moveItem(id, bs.toolbarFolder, 0);
// UNSORTED
ok(true, "*** Acting on unsorted bookmarks");
id = bs.insertBookmark(bs.unfiledBookmarksFolder,
PlacesUtils._uri("http://ub1.mozilla.org/"),
bs.DEFAULT_INDEX,
"ub1");
addedBookmarks.push(id);
id = bs.insertBookmark(bs.unfiledBookmarksFolder,
PlacesUtils._uri("place:"),
bs.DEFAULT_INDEX,
"ub2");
addedBookmarks.push(id);
id = bs.insertSeparator(bs.unfiledBookmarksFolder, bs.DEFAULT_INDEX);
addedBookmarks.push(id);
id = bs.createFolder(bs.unfiledBookmarksFolder,
"ubf",
bs.DEFAULT_INDEX);
addedBookmarks.push(id);
id = bs.insertBookmark(id,
PlacesUtils._uri("http://ubf1.mozilla.org/"),
bs.DEFAULT_INDEX,
"bubf1");
addedBookmarks.push(id);
bs.moveItem(id, bs.unfiledBookmarksFolder, 0);
// Remove all added bookmarks.
addedBookmarks.forEach(function (aItem) {
// If we remove an item after its containing folder has been removed,
// this will throw, but we can ignore that.
try {
bs.removeItem(aItem);
} catch (ex) {}
});
// Remove bookmarks observer.
bs.removeObserver(bookmarksObserver);
finishTest();
}
/**
* Restores browser state and calls finish.
*/
function finishTest() {
// Close bookmarks menu.
var menu = document.getElementById("bookmarksMenu");
menu.open = false;
// Close bookmarks sidebar.
toggleSidebar("viewBookmarksSidebar", false);
finish();
}
/**
* The observer is where magic happens, for every change we do it will look for
* nodes positions in the affected views.
*/
var bookmarksObserver = {
QueryInterface: function PSB_QueryInterface(aIID) {
if (aIID.equals(Ci.nsINavBookmarkObserver) ||
aIID.equals(Ci.nsISupports))
return this;
throw Cr.NS_NOINTERFACE;
},
// nsINavBookmarkObserver
onItemAdded: function PSB_onItemAdded(aItemId, aFolderId, aIndex) {
var views = getViewsForFolder(aFolderId);
ok(views.length > 0, "Found affected views: " + views);
// Check that item has been added in the correct position.
for (var i = 0; i < views.length; i++) {
var node = null;
var index = null;
[node, index] = searchItemInView(aItemId, views[i]);
isnot(node, null, "Found new Places node in " + views[i]);
is(index, aIndex, "Node is at index " + index);
}
},
onItemRemoved: function PSB_onItemRemoved(aItemId, aFolder, aIndex) {
var views = getViewsForFolder(aFolderId);
ok(views.length > 0, "Found affected views: " + views);
// Check that item has been removed.
for (var i = 0; i < views.length; i++) {
var node = null;
var index = null;
[node, index] = searchItemInView(aItemId, views[i]);
is(node, null, "Places node not found in " + views[i]);
}
},
onItemMoved: function(aItemId,
aOldFolderId, aOldIndex,
aNewFolderId, aNewIndex) {
var views = getViewsForFolder(aNewFolderId);
ok(views.length > 0, "Found affected views: " + views);
// Check that item has been moved in the correct position.
for (var i = 0; i < views.length; i++) {
var node = null;
var index = null;
[node, index] = searchItemInView(aItemId, views[i]);
isnot(node, null, "Found new Places node in " + views[i]);
is(index, aNewIndex, "Node is at index " + index);
}
},
onBeginUpdateBatch: function PSB_onBeginUpdateBatch() {},
onEndUpdateBatch: function PSB_onEndUpdateBatch() {},
onBeforeItemRemoved: function PSB_onBeforeItemRemoved(aItemId) {},
onItemVisited: function() {},
onItemChanged: function PSB_onItemChanged(aItemId, aProperty,
aIsAnnotationProperty, aValue) {}
};
/**
* Search an item id in a view.
*
* @param aItemId
* item id of the item to search.
* @param aView
* either "toolbar", "menu" or "sidebar"
* @returns [node, index] or [null, null] if not found.
*/
function searchItemInView(aItemId, aView) {
var node = null;
var index = null;
switch (aView) {
case "toolbar":
return getNodeForToolbarItem(aItemId);
case "menu":
return getNodeForMenuItem(aItemId);
case "sidebar":
return getNodeForSidebarItem(aItemId);
}
return [null, null];
}
/**
* Get places node and index for an itemId in bookmarks toolbar view.
*
* @param aItemId
* item id of the item to search.
* @returns [node, index] or [null, null] if not found.
*/
function getNodeForToolbarItem(aItemId) {
var toolbar = document.getElementById("bookmarksBarContent");
function findNode(aContainer) {
var children = aContainer.childNodes;
for (var i = 0, staticNodes = 0; i < children.length; i++) {
var child = children[i];
// Is this a Places node?
if (!child.node) {
staticNodes++;
continue;
}
if (child.node.itemId == aItemId)
return [child.node, i - staticNodes];
// Don't search in queries, they could contain our item in a
// different position. Search only folders
if (PlacesUtils.nodeIsFolder(child.node)) {
var popup = child.lastChild;
popup.showPopup(popup);
foundNode = findNode(popup);
popup.hidePopup();
if (foundNode[0] != null)
return foundNode;
}
}
return [null, null];
}
return findNode(toolbar);
}
/**
* Get places node and index for an itemId in bookmarks menu view.
*
* @param aItemId
* item id of the item to search.
* @returns [node, index] or [null, null] if not found.
*/
function getNodeForMenuItem(aItemId) {
var menu = document.getElementById("bookmarksMenu");
function findNode(aContainer) {
var children = aContainer.childNodes;
for (var i = 0, staticNodes = 0; i < children.length; i++) {
var child = children[i];
// Is this a Places node?
if (!child.node) {
staticNodes++;
continue;
}
if (child.node.itemId == aItemId)
return [child.node, i - staticNodes];
// Don't search in queries, they could contain our item in a
// different position. Search only folders
if (PlacesUtils.nodeIsFolder(child.node)) {
var popup = child.lastChild;
// XXX Why is this needed on Linux and Mac?
popup.showPopup(popup);
child.open = true;
foundNode = findNode(popup);
popup.hidePopup();
child.open = false;
if (foundNode[0] != null)
return foundNode;
}
}
return [null, null];
}
return findNode(menu.lastChild);
}
/**
* Get places node and index for an itemId in sidebar tree view.
*
* @param aItemId
* item id of the item to search.
* @returns [node, index] or [null, null] if not found.
*/
function getNodeForSidebarItem(aItemId) {
ok(true, "getNodeForSidebar");
var sidebar = document.getElementById("sidebar");
var tree = sidebar.contentDocument.getElementById("bookmarks-view");
function findNode(aContainerIndex) {
if (tree.view.isContainerEmpty(aContainerIndex))
return [null, null];
// The rowCount limit is just for sanity, but we will end looping when
// we have checked the last child of this container or we have found node.
for (var i = aContainerIndex + 1; i < tree.view.rowCount; i++) {
var node = tree.view.nodeForTreeIndex(i);
if (node.itemId == aItemId) {
// Minus one because we want relative index inside the container.
return [node, i - tree.view.getParentIndex(i) - 1];
}
if (PlacesUtils.nodeIsFolder(node)) {
// Open container.
tree.view.toggleOpenState(i);
// Search inside it.
var foundNode = findNode(i);
// Close container.
tree.view.toggleOpenState(i);
// Return node if found.
if (foundNode[0] != null)
return foundNode;
}
// We have finished walking this container.
if (!tree.view.hasNextSibling(aContainerIndex + 1, i))
break;
}
return [null, null]
}
// Root node is hidden, so we need to manually walk the first level.
for (var i = 0; i < tree.view.rowCount; i++) {
// Open container.
tree.view.toggleOpenState(i);
// Search inside it.
var foundNode = findNode(i);
// Close container.
tree.view.toggleOpenState(i);
// Return node if found.
if (foundNode[0] != null)
return foundNode;
}
return [null, null];
}
/**
* Get views affected by changes to a folder.
*
* @param aFolderId:
* item id of the folder we have changed.
* @returns a subset of views: ["toolbar", "menu", "sidebar"]
*/
function getViewsForFolder(aFolderId) {
var rootId = aFolderId;
while (!PlacesUtils.isRootItem(rootId))
rootId = PlacesUtils.bookmarks.getFolderIdForItem(rootId);
switch (rootId) {
case PlacesUtils.toolbarFolderId:
return ["toolbar", "sidebar"]
break;
case PlacesUtils.bookmarksMenuFolderId:
// XXX Skip menu tests on Mac, due to native menubar.
if (navigator.platform.toLowerCase().indexOf("mac") != -1)
return ["sidebar"];
return ["menu", "sidebar"]
break;
case PlacesUtils.unfiledBookmarksFolderId:
return ["sidebar"]
break;
}
return new Array();
}

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

@ -664,6 +664,8 @@ function run_test() {
do_check_eq(bmsvc.getItemIndex(bkmk3_1Id), -1);
do_check_eq(bmsvc.getItemIndex(bkmk3_2Id), -1);
do_check_eq(bmsvc.getItemIndex(bkmk3_3Id), -1);
// Check last removed item id.
do_check_eq(observer._itemRemovedId, bkmk3Id);
txn.undoTransaction();
var newBkmk1Id = bmsvc.getIdForItemAt(root, 0);
@ -685,6 +687,9 @@ function run_test() {
do_check_eq(bmsvc.getFolderIdForItem(newBkmk3_3Id), newBkmk3Id);
do_check_eq(bmsvc.getItemType(newBkmk3_3Id), bmsvc.TYPE_FOLDER);
do_check_eq(bmsvc.getItemTitle(newBkmk3_3Id), "folder");
// Check last added back item id.
// Notice items are restored in reverse order.
do_check_eq(observer._itemAddedId, newBkmk1Id);
txn.redoTransaction();
do_check_eq(bmsvc.getItemIndex(newBkmk1Id), -1);
@ -693,6 +698,8 @@ function run_test() {
do_check_eq(bmsvc.getItemIndex(newBkmk3_1Id), -1);
do_check_eq(bmsvc.getItemIndex(newBkmk3_2Id), -1);
do_check_eq(bmsvc.getItemIndex(newBkmk3_3Id), -1);
// Check last removed item id.
do_check_eq(observer._itemRemovedId, newBkmk3Id);
txn.undoTransaction();
newBkmk1Id = bmsvc.getIdForItemAt(root, 0);
@ -714,6 +721,9 @@ function run_test() {
do_check_eq(bmsvc.getFolderIdForItem(newBkmk3_3Id), newBkmk3Id);
do_check_eq(bmsvc.getItemType(newBkmk3_3Id), bmsvc.TYPE_FOLDER);
do_check_eq(bmsvc.getItemTitle(newBkmk3_3Id), "folder");
// Check last added back item id.
// Notice items are restored in reverse order.
do_check_eq(observer._itemAddedId, newBkmk1Id);
// Test creating an item with child transactions.
var childTxns = [];

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

@ -1,66 +0,0 @@
; dept.mmh
;
; Derived from MakeMSI's dept.mmh file:
; (C)opyright Dennis Bareis, Australia, 2003. All rights reserved.
;----------------------------------------------------------------------------
;--- Define Version number of this install support --------------------------
;----------------------------------------------------------------------------
#ifdef DEPT_VERSION
;--- Die, already included -----------------------------------------------
#error ^You have already included "<?InputComponent>"^
#endif
#define DEPT_VERSION 03.171
;----------------------------------------------------------------------------
;--- Obsolete values (don't use!) -------------------------------------------
;----------------------------------------------------------------------------
#define? DEPT_SUPPORT_WEB_URL
;----------------------------------------------------------------------------
;--- Define some Department details -----------------------------------------
;----------------------------------------------------------------------------
#define? DEPT_ARP_URL_PUBLISHER
#define? DEPT_ARP_URL_TECHNICAL_SUPPORT <$DEPT_SUPPORT_WEB_URL>
#define? DEPT_ARP_URL_APPLICATION_UPDATE_INFORMATION
#define? DEPT_NAME Mozilla.Org
#define? DEPT_ADDRESS United States
#define? DEPT_MSI_MANUFACTURER <$DEPT_NAME>
#define? DEPT_MSI_AUTHOR <$DEPT_NAME>
;#define? COMPANY_CONTACT_NAME Fred Nerk
;#define? COMPANY_CONTACT_NAME_PHONE (03)1234-5678
#define? COMPANY_PACKAGED_BY Packaged by <$DEPT_NAME> (<$DEPT_ADDRESS>).
;----------------------------------------------------------------------------
;--- Define the types of boxes your department/company supports -------------
;----------------------------------------------------------------------------
#ifndef COMPANY_DEFINE_DEPARTMENTS_PLATFORMS
#(
#define COMPANY_DEFINE_DEPARTMENTS_PLATFORMS ;;COMPANY.MMH expands...
;--- User must override... -------------------------------------------
<$Platform "TEST" DESC=^Testing (NOT SUPPORTED)^ PLATDIR="Testing-Unsupported">
#)
#endif
;----------------------------------------------------------------------------
;--- Load MAKEMSI support ---------------------------------------------------
;----------------------------------------------------------------------------
#NextId PUSH
#include "mozilla.mmh"
#NextId POP
;----------------------------------------------------------------------------
;--- Make sure we record details about this header --------------------------
;----------------------------------------------------------------------------
<$SourceFile Version="<$DEPT_VERSION>">
;----------------------------------------------------------------------------
;--- Start "location" status information (if allowed) -----------------------
;----------------------------------------------------------------------------
<$LocationVerboseOn> ;;Outputs messages during length processing (to prove it hasn't hung etc)

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

@ -284,7 +284,12 @@ endif
ident:
@$(PYTHON) $(topsrcdir)/config/printconfigsetting.py $(STAGEDIST)/application.ini App SourceStamp
@printf "fx_revision "
@$(PYTHON) $(topsrcdir)/config/printconfigsetting.py \
$(STAGEDIST)/application.ini App SourceStamp
@printf "buildid "
@$(PYTHON) $(topsrcdir)/config/printconfigsetting.py \
$(STAGEDIST)/application.ini App BuildID
#These make targets call prepare-repackages by setting different UPLOAD_DIR
prepare-upload-latest-%:

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

@ -1214,7 +1214,7 @@ tabpanels {
border: 1px dotted transparent;
}
.tabbrowser-tab[selected="true"]:focus > .tab-text {
.tabbrowser-tab:focus > .tab-text {
border: 1px dotted -moz-DialogText;
}

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

@ -1561,7 +1561,7 @@ tabbrowser > tabbox {
background-color: -moz-mac-chrome-active;
}
.tabbrowser-tab[selected="true"]:focus > .tab-text {
.tabbrowser-tab:focus > .tab-text {
-moz-box-shadow: 0 0 4px -moz-mac-focusring,
0 0 4px -moz-mac-focusring,
0 0 3px -moz-mac-focusring,

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

@ -1404,7 +1404,7 @@ tabpanels {
border: 1px dotted transparent;
}
.tabbrowser-tab[selected="true"]:focus > .tab-text {
.tabbrowser-tab:focus > .tab-text {
border: 1px dotted -moz-DialogText;
}

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

@ -62,8 +62,8 @@
ac_add_options() {
for _opt
do
# Escape shell characters, space, tab, dollar, quote, backslash.
_opt=`echo $_opt | sed -e 's/\([\ \ \$\"\\]\)/\\\\\1/g;s/@\([^@]*\)@/\$\1/g;'`
# Escape shell characters, space, tab, dollar, quote, backslash, parentheses.
_opt=`echo $_opt | sed -e 's/\([\ \ \$\"\\\(\)]\)/\\\\\1/g;s/@\([^@]*\)@/\$\1/g;'`
_opt=`echo $_opt | sed -e 's/@\([^@]*\)@/\$(\1)/g'`
# Avoid adding duplicates

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

@ -129,7 +129,7 @@ export::
-DMOZ_NATIVE_PNG=$(MOZ_NATIVE_PNG) \
-DMOZ_NATIVE_JPEG=$(MOZ_NATIVE_JPEG) \
$(srcdir)/system-headers | $(PERL) $(topsrcdir)/nsprpub/config/make-system-wrappers.pl system_wrappers
$(INSTALL) system_wrappers $(DIST)/include
$(INSTALL) system_wrappers $(DIST)
GARBAGE_DIRS += system_wrappers
endif

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

@ -1138,44 +1138,11 @@ HOST_OS_ARCH=`echo $host_os | sed -e 's|/|_|g'`
# Master "Core Components" macros for getting the OS target #
#######################################################################
#
# Note: OS_TARGET should be specified on the command line for gmake.
# When OS_TARGET=WIN95 is specified, then a Windows 95 target is built.
# The difference between the Win95 target and the WinNT target is that
# the WinNT target uses Windows NT specific features not available
# in Windows 95. The Win95 target will run on Windows NT, but (supposedly)
# at lesser performance (the Win95 target uses threads; the WinNT target
# uses fibers).
#
# If OS_TARGET is not specified, it defaults to $(OS_ARCH), i.e., no
# cross-compilation.
#
#
# The following hack allows one to build on a WIN95 machine (as if
# s/he were cross-compiling on a WINNT host for a WIN95 target).
# It also accomodates for MKS's uname.exe. If you never intend
# to do development on a WIN95 machine, you don't need this hack.
#
case "$OS_ARCH" in
WIN95)
OS_ARCH=WINNT
OS_TARGET=WIN95
;;
Windows_95)
OS_ARCH=Windows_NT
OS_TARGET=WIN95
;;
Windows_98)
OS_ARCH=Windows_NT
OS_TARGET=WIN95
;;
CYGWIN_9*|CYGWIN_ME*)
OS_ARCH='CYGWIN_NT-4.0'
OS_TARGET=WIN95
;;
esac
#
# Define and override various archtecture-specific variables, including
# HOST_OS_ARCH
@ -1420,9 +1387,6 @@ esac
if test -z "$OS_TARGET"; then
OS_TARGET=$OS_ARCH
fi
if test "$OS_TARGET" = "WIN95"; then
OS_RELEASE="4.0"
fi
OS_CONFIG="${OS_TARGET}${OS_RELEASE}"
dnl ========================================================
@ -2123,7 +2087,7 @@ case "$target" in
AC_DEFINE(HAVE_LOCALTIME_R)
TARGET_MD_ARCH=win32
_PLATFORM_DEFAULT_TOOLKIT='windows'
_PLATFORM_DEFAULT_TOOLKIT='cairo-windows'
BIN_SUFFIX='.exe'
USE_SHORT_LIBNAME=1
MOZ_ENABLE_POSTSCRIPT=
@ -2193,8 +2157,8 @@ case "$target" in
MKSHLIB_UNFORCE_ALL=
DSO_LDOPTS=-SUBSYSTEM:WINDOWS
_USE_CPP_INCLUDE_FLAG=1
_DEFINES_CFLAGS='-FI $(DEPTH)/mozilla-config.h -DMOZILLA_CLIENT'
_DEFINES_CXXFLAGS='-FI $(DEPTH)/mozilla-config.h -DMOZILLA_CLIENT'
_DEFINES_CFLAGS='-FI mozilla-config.h -DMOZILLA_CLIENT'
_DEFINES_CXXFLAGS='-FI mozilla-config.h -DMOZILLA_CLIENT'
CFLAGS="$CFLAGS -W3 -Gy -Fd\$(COMPILE_PDBFILE)"
CXXFLAGS="$CXXFLAGS -W3 -Gy -Fd\$(COMPILE_PDBFILE)"
LIBS="$LIBS kernel32.lib user32.lib gdi32.lib winmm.lib wsock32.lib advapi32.lib"
@ -3068,7 +3032,7 @@ EOF
])
if test "$ac_cv_have_visibility_builtin_bug" = "no" -a \
"$ac_cv_have_visibility_class_bug" = "no"; then
VISIBILITY_FLAGS='-I$(DIST)/include/system_wrappers -include $(topsrcdir)/config/gcc_hidden.h'
VISIBILITY_FLAGS='-I$(DIST)/system_wrappers -include $(topsrcdir)/config/gcc_hidden.h'
WRAP_SYSTEM_INCLUDES=1
else
VISIBILITY_FLAGS='-fvisibility=hidden'
@ -4828,8 +4792,7 @@ MOZ_ARG_HEADER(Toolkit Options)
Mac OS X - cairo-cocoa
Neutrino/QNX - photon
OS/2 - cairo-os2
Win32 - cairo-windows
WinCE - windows
Win32/WinCE - cairo-windows
Gtk2 with DirectFB - cairo-gtk2-dfb
* - cairo-gtk2
* - cairo-qt],
@ -7657,15 +7620,15 @@ if test "$MOZ_TREE_CAIRO"; then
DDRAW_SURFACE_FEATURE=
else
WIN32_FONT_FEATURE=
fi
AC_TRY_COMPILE([#include <ddraw.h>], [int foo = DDLOCK_WAITNOTBUSY;], HAS_DDRAW=1, HAS_DDRAW=)
if test -z "$HAS_DDRAW"; then
AC_MSG_WARN([DirectDraw ddraw.h header not found or it's missing DDLOCK_WAITNOTBUSY, disabling DirectDraw surface. If you have an older SDK (such as the CE5 SDK), try copying in ddraw.lib and ddraw.h from the WM6 SDK.])
DDRAW_SURFACE_FEATURE=
else
DDRAW_SURFACE_FEATURE="#define CAIRO_HAS_DDRAW_SURFACE 1"
fi
fi
AC_TRY_COMPILE([#include <ddraw.h>], [int foo = DDLOCK_WAITNOTBUSY;], HAS_DDRAW=1, HAS_DDRAW=)
if test -z "$HAS_DDRAW"; then
AC_MSG_WARN([DirectDraw ddraw.h header not found or it's missing DDLOCK_WAITNOTBUSY, disabling DirectDraw surface. If you have an older SDK (such as the CE5 SDK), try copying in ddraw.lib and ddraw.h from the WM6 SDK.])
DDRAW_SURFACE_FEATURE=
else
DDRAW_SURFACE_FEATURE="#define CAIRO_HAS_DDRAW_SURFACE 1"
fi
PDF_SURFACE_FEATURE="#define CAIRO_HAS_PDF_SURFACE 1"
fi
if test "$MOZ_WIDGET_TOOLKIT" = "os2"; then

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

@ -937,11 +937,9 @@ public:
* @param aNode The node for which to get the eventlistener manager.
* @param aCreateIfNotFound If PR_FALSE, returns a listener manager only if
* one already exists.
* @param aResult [out] Set to the eventlistener manager for aNode.
*/
static nsresult GetListenerManager(nsINode *aNode,
PRBool aCreateIfNotFound,
nsIEventListenerManager **aResult);
static nsIEventListenerManager* GetListenerManager(nsINode* aNode,
PRBool aCreateIfNotFound);
/**
* Remove the eventlistener manager for aNode.
@ -1259,6 +1257,15 @@ public:
*/
static already_AddRefed<nsIDragSession> GetDragSession();
/*
* Initialize and set the dataTransfer field of an nsDragEvent.
*/
static nsresult SetDataTransferInEvent(nsDragEvent* aDragEvent);
// filters the drag and drop action to fit within the effects allowed and
// returns it.
static PRUint32 FilterDropEffect(PRUint32 aAction, PRUint32 aEffectAllowed);
/**
* Return true if aURI is a local file URI (i.e. file://).
*/

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

@ -64,7 +64,7 @@ interface nsIURI;
* sufficient, when combined with the imageBlockingStatus information.)
*/
[scriptable, uuid(7744c6d3-5c60-4b7b-a526-4fe9d5ac7e97)]
[scriptable, uuid(e036857e-3417-4812-a5f2-89668a616781)]
interface nsIImageLoadingContent : imgIDecoderObserver
{
/**
@ -167,4 +167,12 @@ interface nsIImageLoadingContent : imgIDecoderObserver
* @throws NS_ERROR_NOT_AVAILABLE if there is no current URI to reload
*/
void forceReload();
/**
* Enables/disables image state forcing. When |aForce| is PR_TRUE, we force
* nsImageLoadingContent::ImageState() to return |aState|. Call again with |aForce|
* as PR_FALSE to revert ImageState() to its original behaviour.
*/
void forceImageState(in boolean aForce, in long aState);
};

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

@ -143,8 +143,11 @@ enum {
NODE_HAS_EDGE_CHILD_SELECTOR |
NODE_HAS_SLOW_SELECTOR_NOAPPEND,
NODE_MAY_HAVE_CONTENT_EDITABLE_ATTR
= 0x00040000U,
// Four bits for the script-type ID
NODE_SCRIPT_TYPE_OFFSET = 18,
NODE_SCRIPT_TYPE_OFFSET = 19,
NODE_SCRIPT_TYPE_SIZE = 4,

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

@ -100,8 +100,6 @@ public:
// nsIContentSink
NS_IMETHOD WillParse(void) { return NS_OK; }
NS_IMETHOD WillBuildModel(void) { return NS_OK; }
NS_IMETHOD DidBuildModel(void) { return NS_OK; }
NS_IMETHOD WillInterrupt(void) { return NS_OK; }
NS_IMETHOD WillResume(void) { return NS_OK; }
NS_IMETHOD SetParser(nsIParser* aParser) { return NS_OK; }

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

@ -162,6 +162,8 @@ static NS_DEFINE_CID(kXTFServiceCID, NS_XTFSERVICE_CID);
#include "nsCPrefetchService.h"
#include "nsIChromeRegistry.h"
#include "nsIMIMEHeaderParam.h"
#include "nsIDOMDragEvent.h"
#include "nsDOMDataTransfer.h"
#include "nsHtml5Module.h"
#ifdef IBMBIDI
@ -3390,8 +3392,7 @@ nsContentUtils::HasMutationListeners(nsINode* aNode,
if (aNode->IsInDoc()) {
nsCOMPtr<nsPIDOMEventTarget> piTarget(do_QueryInterface(window));
if (piTarget) {
nsCOMPtr<nsIEventListenerManager> manager;
piTarget->GetListenerManager(PR_FALSE, getter_AddRefs(manager));
nsIEventListenerManager* manager = piTarget->GetListenerManager(PR_FALSE);
if (manager) {
PRBool hasListeners = PR_FALSE;
manager->HasMutationListeners(&hasListeners);
@ -3406,8 +3407,7 @@ nsContentUtils::HasMutationListeners(nsINode* aNode,
// might not be in our chain. If we don't have a window, we might have a
// mutation listener. Check quickly to see.
while (aNode) {
nsCOMPtr<nsIEventListenerManager> manager;
aNode->GetListenerManager(PR_FALSE, getter_AddRefs(manager));
nsIEventListenerManager* manager = aNode->GetListenerManager(PR_FALSE);
if (manager) {
PRBool hasListeners = PR_FALSE;
manager->HasMutationListeners(&hasListeners);
@ -3451,22 +3451,19 @@ nsContentUtils::TraverseListenerManager(nsINode *aNode,
}
}
nsresult
nsIEventListenerManager*
nsContentUtils::GetListenerManager(nsINode *aNode,
PRBool aCreateIfNotFound,
nsIEventListenerManager **aResult)
PRBool aCreateIfNotFound)
{
*aResult = nsnull;
if (!aCreateIfNotFound && !aNode->HasFlag(NODE_HAS_LISTENERMANAGER)) {
return NS_OK;
return nsnull;
}
if (!sEventListenerManagersHash.ops) {
// We're already shut down, don't bother creating an event listener
// manager.
return NS_ERROR_NOT_AVAILABLE;
return nsnull;
}
if (!aCreateIfNotFound) {
@ -3475,10 +3472,9 @@ nsContentUtils::GetListenerManager(nsINode *aNode,
(PL_DHashTableOperate(&sEventListenerManagersHash, aNode,
PL_DHASH_LOOKUP));
if (PL_DHASH_ENTRY_IS_BUSY(entry)) {
*aResult = entry->mListenerManager;
NS_ADDREF(*aResult);
return entry->mListenerManager;
}
return NS_OK;
return nsnull;
}
EventListenerManagerMapEntry *entry =
@ -3487,7 +3483,7 @@ nsContentUtils::GetListenerManager(nsINode *aNode,
PL_DHASH_ADD));
if (!entry) {
return NS_ERROR_OUT_OF_MEMORY;
return nsnull;
}
if (!entry->mListenerManager) {
@ -3497,7 +3493,7 @@ nsContentUtils::GetListenerManager(nsINode *aNode,
if (NS_FAILED(rv)) {
PL_DHashTableRawRemove(&sEventListenerManagersHash, entry);
return rv;
return nsnull;
}
entry->mListenerManager->SetListenerTarget(aNode);
@ -3505,9 +3501,7 @@ nsContentUtils::GetListenerManager(nsINode *aNode,
aNode->SetFlags(NODE_HAS_LISTENERMANAGER);
}
NS_ADDREF(*aResult = entry->mListenerManager);
return NS_OK;
return entry->mListenerManager;
}
/* static */
@ -4584,6 +4578,115 @@ nsContentUtils::GetDragSession()
return dragSession;
}
/* static */
nsresult
nsContentUtils::SetDataTransferInEvent(nsDragEvent* aDragEvent)
{
if (aDragEvent->dataTransfer || !NS_IS_TRUSTED_EVENT(aDragEvent))
return NS_OK;
// For draggesture and dragstart events, the data transfer object is
// created before the event fires, so it should already be set. For other
// drag events, get the object from the drag session.
NS_ASSERTION(aDragEvent->message != NS_DRAGDROP_GESTURE &&
aDragEvent->message != NS_DRAGDROP_START,
"draggesture event created without a dataTransfer");
nsCOMPtr<nsIDragSession> dragSession = GetDragSession();
NS_ENSURE_TRUE(dragSession, NS_OK); // no drag in progress
nsCOMPtr<nsIDOMDataTransfer> initialDataTransfer;
dragSession->GetDataTransfer(getter_AddRefs(initialDataTransfer));
if (!initialDataTransfer) {
// A dataTransfer won't exist when a drag was started by some other
// means, for instance calling the drag service directly, or a drag
// from another application. In either case, a new dataTransfer should
// be created that reflects the data. Pass true to the constructor for
// the aIsExternal argument, so that only system access is allowed.
PRUint32 action = 0;
dragSession->GetDragAction(&action);
initialDataTransfer =
new nsDOMDataTransfer(aDragEvent->message, action);
NS_ENSURE_TRUE(initialDataTransfer, NS_ERROR_OUT_OF_MEMORY);
// now set it in the drag session so we don't need to create it again
dragSession->SetDataTransfer(initialDataTransfer);
}
// each event should use a clone of the original dataTransfer.
nsCOMPtr<nsIDOMNSDataTransfer> initialDataTransferNS =
do_QueryInterface(initialDataTransfer);
NS_ENSURE_TRUE(initialDataTransferNS, NS_ERROR_FAILURE);
initialDataTransferNS->Clone(aDragEvent->message, aDragEvent->userCancelled,
getter_AddRefs(aDragEvent->dataTransfer));
NS_ENSURE_TRUE(aDragEvent->dataTransfer, NS_ERROR_OUT_OF_MEMORY);
// for the dragenter and dragover events, initialize the drop effect
// from the drop action, which platform specific widget code sets before
// the event is fired based on the keyboard state.
if (aDragEvent->message == NS_DRAGDROP_ENTER ||
aDragEvent->message == NS_DRAGDROP_OVER) {
nsCOMPtr<nsIDOMNSDataTransfer> newDataTransfer =
do_QueryInterface(aDragEvent->dataTransfer);
NS_ENSURE_TRUE(newDataTransfer, NS_ERROR_FAILURE);
PRUint32 action, effectAllowed;
dragSession->GetDragAction(&action);
newDataTransfer->GetEffectAllowedInt(&effectAllowed);
newDataTransfer->SetDropEffectInt(FilterDropEffect(action, effectAllowed));
}
else if (aDragEvent->message == NS_DRAGDROP_DROP ||
aDragEvent->message == NS_DRAGDROP_DRAGDROP ||
aDragEvent->message == NS_DRAGDROP_END) {
// For the drop and dragend events, set the drop effect based on the
// last value that the dropEffect had. This will have been set in
// nsEventStateManager::PostHandleEvent for the last dragenter or
// dragover event.
nsCOMPtr<nsIDOMNSDataTransfer> newDataTransfer =
do_QueryInterface(aDragEvent->dataTransfer);
NS_ENSURE_TRUE(newDataTransfer, NS_ERROR_FAILURE);
PRUint32 dropEffect;
initialDataTransferNS->GetDropEffectInt(&dropEffect);
newDataTransfer->SetDropEffectInt(dropEffect);
}
return NS_OK;
}
/* static */
PRUint32
nsContentUtils::FilterDropEffect(PRUint32 aAction, PRUint32 aEffectAllowed)
{
// It is possible for the drag action to include more than one action, but
// the widget code which sets the action from the keyboard state should only
// be including one. If multiple actions were set, we just consider them in
// the following order:
// copy, link, move
if (aAction & nsIDragService::DRAGDROP_ACTION_COPY)
aAction = nsIDragService::DRAGDROP_ACTION_COPY;
else if (aAction & nsIDragService::DRAGDROP_ACTION_LINK)
aAction = nsIDragService::DRAGDROP_ACTION_LINK;
else if (aAction & nsIDragService::DRAGDROP_ACTION_MOVE)
aAction = nsIDragService::DRAGDROP_ACTION_MOVE;
// Filter the action based on the effectAllowed. If the effectAllowed
// doesn't include the action, then that action cannot be done, so adjust
// the action to something that is allowed. For a copy, adjust to move or
// link. For a move, adjust to copy or link. For a link, adjust to move or
// link. Otherwise, use none.
if (aAction & aEffectAllowed ||
aEffectAllowed == nsIDragService::DRAGDROP_ACTION_UNINITIALIZED)
return aAction;
if (aEffectAllowed & nsIDragService::DRAGDROP_ACTION_MOVE)
return nsIDragService::DRAGDROP_ACTION_MOVE;
if (aEffectAllowed & nsIDragService::DRAGDROP_ACTION_COPY)
return nsIDragService::DRAGDROP_ACTION_COPY;
if (aEffectAllowed & nsIDragService::DRAGDROP_ACTION_LINK)
return nsIDragService::DRAGDROP_ACTION_LINK;
return nsIDragService::DRAGDROP_ACTION_NONE;
}
/* static */
PRBool
nsContentUtils::URIIsLocalFile(nsIURI *aURI)

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

@ -758,46 +758,37 @@ nsDOMAttribute::DispatchDOMEvent(nsEvent* aEvent, nsIDOMEvent* aDOMEvent,
aPresContext, aEventStatus);
}
nsresult
nsDOMAttribute::GetListenerManager(PRBool aCreateIfNotFound,
nsIEventListenerManager** aResult)
nsIEventListenerManager*
nsDOMAttribute::GetListenerManager(PRBool aCreateIfNotFound)
{
return nsContentUtils::GetListenerManager(this, aCreateIfNotFound, aResult);
return nsContentUtils::GetListenerManager(this, aCreateIfNotFound);
}
nsresult
nsDOMAttribute::AddEventListenerByIID(nsIDOMEventListener *aListener,
const nsIID& aIID)
{
nsCOMPtr<nsIEventListenerManager> elm;
nsresult rv = GetListenerManager(PR_TRUE, getter_AddRefs(elm));
if (elm) {
return elm->AddEventListenerByIID(aListener, aIID, NS_EVENT_FLAG_BUBBLE);
}
return rv;
nsIEventListenerManager* elm = GetListenerManager(PR_TRUE);
NS_ENSURE_STATE(elm);
return elm->AddEventListenerByIID(aListener, aIID, NS_EVENT_FLAG_BUBBLE);
}
nsresult
nsDOMAttribute::RemoveEventListenerByIID(nsIDOMEventListener *aListener,
const nsIID& aIID)
{
nsCOMPtr<nsIEventListenerManager> elm;
GetListenerManager(PR_FALSE, getter_AddRefs(elm));
if (elm) {
return elm->RemoveEventListenerByIID(aListener, aIID, NS_EVENT_FLAG_BUBBLE);
}
return NS_OK;
nsIEventListenerManager* elm = GetListenerManager(PR_FALSE);
return elm ?
elm->RemoveEventListenerByIID(aListener, aIID, NS_EVENT_FLAG_BUBBLE) :
NS_OK;
}
nsresult
nsDOMAttribute::GetSystemEventGroup(nsIDOMEventGroup** aGroup)
{
nsCOMPtr<nsIEventListenerManager> elm;
nsresult rv = GetListenerManager(PR_TRUE, getter_AddRefs(elm));
if (elm) {
return elm->GetSystemEventGroupLM(aGroup);
}
return rv;
nsIEventListenerManager* elm = GetListenerManager(PR_TRUE);
NS_ENSURE_STATE(elm);
return elm->GetSystemEventGroupLM(aGroup);
}
nsresult

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

@ -104,8 +104,7 @@ public:
virtual nsresult DispatchDOMEvent(nsEvent* aEvent, nsIDOMEvent* aDOMEvent,
nsPresContext* aPresContext,
nsEventStatus* aEventStatus);
virtual nsresult GetListenerManager(PRBool aCreateIfNotFound,
nsIEventListenerManager** aResult);
virtual nsIEventListenerManager* GetListenerManager(PRBool aCreateIfNotFound);
virtual nsresult AddEventListenerByIID(nsIDOMEventListener *aListener,
const nsIID& aIID);
virtual nsresult RemoveEventListenerByIID(nsIDOMEventListener *aListener,

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

@ -168,7 +168,7 @@ static NS_DEFINE_CID(kDOMEventGroupCID, NS_DOMEVENTGROUP_CID);
#include "nsIXULDocument.h"
#include "nsIPrompt.h"
#include "nsIPropertyBag2.h"
#include "nsIDOMPageTransitionEvent.h"
#include "nsFrameLoader.h"
#include "mozAutoDocUpdate.h"
@ -572,7 +572,7 @@ NS_INTERFACE_TABLE_HEAD(nsDOMStyleSheetList)
nsIDocumentObserver,
nsIMutationObserver)
NS_INTERFACE_TABLE_TO_MAP_SEGUE
NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(DocumentStyleSheetList)
NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(StyleSheetList)
NS_INTERFACE_MAP_END
@ -6018,42 +6018,27 @@ nsDocument::GetOwnerDocument(nsIDOMDocument** aOwnerDocument)
return nsINode::GetOwnerDocument(aOwnerDocument);
}
nsresult
nsDocument::GetListenerManager(PRBool aCreateIfNotFound,
nsIEventListenerManager** aInstancePtrResult)
nsIEventListenerManager*
nsDocument::GetListenerManager(PRBool aCreateIfNotFound)
{
if (mListenerManager) {
*aInstancePtrResult = mListenerManager;
NS_ADDREF(*aInstancePtrResult);
return NS_OK;
}
if (!aCreateIfNotFound) {
*aInstancePtrResult = nsnull;
return NS_OK;
if (mListenerManager || !aCreateIfNotFound) {
return mListenerManager;
}
nsresult rv = NS_NewEventListenerManager(getter_AddRefs(mListenerManager));
NS_ENSURE_SUCCESS(rv, rv);
NS_ENSURE_SUCCESS(rv, nsnull);
mListenerManager->SetListenerTarget(static_cast<nsIDocument *>(this));
*aInstancePtrResult = mListenerManager;
NS_ADDREF(*aInstancePtrResult);
return NS_OK;
return mListenerManager;
}
nsresult
nsDocument::GetSystemEventGroup(nsIDOMEventGroup **aGroup)
{
nsCOMPtr<nsIEventListenerManager> manager;
if (NS_SUCCEEDED(GetListenerManager(PR_TRUE, getter_AddRefs(manager))) &&
manager) {
return manager->GetSystemEventGroupLM(aGroup);
}
return NS_ERROR_FAILURE;
nsIEventListenerManager* manager = GetListenerManager(PR_TRUE);
NS_ENSURE_STATE(manager);
return manager->GetSystemEventGroupLM(aGroup);
}
nsresult
@ -6093,28 +6078,19 @@ nsresult
nsDocument::AddEventListenerByIID(nsIDOMEventListener *aListener,
const nsIID& aIID)
{
nsCOMPtr<nsIEventListenerManager> manager;
GetListenerManager(PR_TRUE, getter_AddRefs(manager));
if (manager) {
manager->AddEventListenerByIID(aListener, aIID, NS_EVENT_FLAG_BUBBLE);
return NS_OK;
}
return NS_ERROR_FAILURE;
nsIEventListenerManager* manager = GetListenerManager(PR_TRUE);
NS_ENSURE_STATE(manager);
return manager->AddEventListenerByIID(aListener, aIID, NS_EVENT_FLAG_BUBBLE);
}
nsresult
nsDocument::RemoveEventListenerByIID(nsIDOMEventListener *aListener,
const nsIID& aIID)
{
if (!mListenerManager) {
return NS_ERROR_FAILURE;
}
mListenerManager->RemoveEventListenerByIID(aListener, aIID,
NS_EVENT_FLAG_BUBBLE);
return NS_OK;
return mListenerManager ?
mListenerManager->RemoveEventListenerByIID(aListener, aIID,
NS_EVENT_FLAG_BUBBLE) :
NS_OK;
}
nsresult
@ -6159,17 +6135,10 @@ nsDocument::AddGroupedEventListener(const nsAString& aType,
PRBool aUseCapture,
nsIDOMEventGroup *aEvtGrp)
{
nsCOMPtr<nsIEventListenerManager> manager;
nsresult rv = GetListenerManager(PR_TRUE, getter_AddRefs(manager));
if (NS_SUCCEEDED(rv) && manager) {
PRInt32 flags = aUseCapture ? NS_EVENT_FLAG_CAPTURE : NS_EVENT_FLAG_BUBBLE;
manager->AddEventListenerByType(aListener, aType, flags, aEvtGrp);
return NS_OK;
}
return rv;
nsIEventListenerManager* manager = GetListenerManager(PR_TRUE);
NS_ENSURE_STATE(manager);
PRInt32 flags = aUseCapture ? NS_EVENT_FLAG_CAPTURE : NS_EVENT_FLAG_BUBBLE;
return manager->AddEventListenerByType(aListener, aType, flags, aEvtGrp);
}
NS_IMETHODIMP
@ -6178,14 +6147,11 @@ nsDocument::RemoveGroupedEventListener(const nsAString& aType,
PRBool aUseCapture,
nsIDOMEventGroup *aEvtGrp)
{
if (!mListenerManager) {
return NS_ERROR_FAILURE;
if (mListenerManager) {
PRInt32 flags = aUseCapture ? NS_EVENT_FLAG_CAPTURE : NS_EVENT_FLAG_BUBBLE;
mListenerManager->RemoveEventListenerByType(aListener, aType, flags,
aEvtGrp);
}
PRInt32 flags = aUseCapture ? NS_EVENT_FLAG_CAPTURE : NS_EVENT_FLAG_BUBBLE;
mListenerManager->RemoveEventListenerByType(aListener, aType, flags,
aEvtGrp);
return NS_OK;
}
@ -6206,9 +6172,8 @@ nsDocument::AddEventListener(const nsAString& aType,
nsIDOMEventListener *aListener,
PRBool aUseCapture, PRBool aWantsUntrusted)
{
nsCOMPtr<nsIEventListenerManager> manager;
nsresult rv = GetListenerManager(PR_TRUE, getter_AddRefs(manager));
NS_ENSURE_SUCCESS(rv, rv);
nsIEventListenerManager* manager = GetListenerManager(PR_TRUE);
NS_ENSURE_STATE(manager);
PRInt32 flags = aUseCapture ? NS_EVENT_FLAG_CAPTURE : NS_EVENT_FLAG_BUBBLE;
@ -6853,8 +6818,8 @@ nsDocument::CanSavePresentation(nsIRequest *aNewRequest)
// Check our event listener manager for unload/beforeunload listeners.
nsCOMPtr<nsPIDOMEventTarget> piTarget = do_QueryInterface(mScriptGlobalObject);
if (piTarget) {
nsCOMPtr<nsIEventListenerManager> manager;
piTarget->GetListenerManager(PR_FALSE, getter_AddRefs(manager));
nsIEventListenerManager* manager =
piTarget->GetListenerManager(PR_FALSE);
if (manager && manager->HasUnloadListeners()) {
return PR_FALSE;
}
@ -7092,14 +7057,24 @@ nsDocument::CheckAncestryAndGetFrame(nsIDocument* aDocument) const
}
void
nsDocument::DispatchEventToWindow(nsEvent *aEvent)
nsDocument::DispatchPageTransition(nsPIDOMEventTarget* aDispatchTarget,
const nsAString& aType,
PRBool aPersisted)
{
nsPIDOMWindow *window = GetWindow();
if (!window)
return;
aEvent->target = static_cast<nsIDocument*>(this);
nsEventDispatcher::Dispatch(window, nsnull, aEvent);
if (aDispatchTarget) {
nsCOMPtr<nsIDOMEvent> event;
CreateEvent(NS_LITERAL_STRING("pagetransition"), getter_AddRefs(event));
nsCOMPtr<nsIDOMPageTransitionEvent> ptEvent = do_QueryInterface(event);
nsCOMPtr<nsIPrivateDOMEvent> pEvent = do_QueryInterface(ptEvent);
if (pEvent && NS_SUCCEEDED(ptEvent->InitPageTransitionEvent(aType, PR_TRUE,
PR_TRUE,
aPersisted))) {
pEvent->SetTrusted(PR_TRUE);
pEvent->SetTarget(this);
nsEventDispatcher::DispatchDOMEvent(aDispatchTarget, nsnull, event,
nsnull, nsnull);
}
}
}
void
@ -7138,14 +7113,10 @@ nsDocument::OnPageShow(PRBool aPersisted, nsIDOMEventTarget* aDispatchStartTarge
mAnimationController->OnPageShow();
}
#endif
nsPageTransitionEvent event(PR_TRUE, NS_PAGE_SHOW, aPersisted);
if (aDispatchStartTarget) {
event.target = static_cast<nsIDocument*>(this);
nsEventDispatcher::Dispatch(aDispatchStartTarget, nsnull, &event);
} else {
DispatchEventToWindow(&event);
}
nsCOMPtr<nsPIDOMEventTarget> target =
aDispatchStartTarget ? do_QueryInterface(aDispatchStartTarget) :
do_QueryInterface(GetWindow());
DispatchPageTransition(target, NS_LITERAL_STRING("pageshow"), aPersisted);
}
void
@ -7184,13 +7155,10 @@ nsDocument::OnPageHide(PRBool aPersisted, nsIDOMEventTarget* aDispatchStartTarge
#endif
// Now send out a PageHide event.
nsPageTransitionEvent event(PR_TRUE, NS_PAGE_HIDE, aPersisted);
if (aDispatchStartTarget) {
event.target = static_cast<nsIDocument*>(this);
nsEventDispatcher::Dispatch(aDispatchStartTarget, nsnull, &event);
} else {
DispatchEventToWindow(&event);
}
nsCOMPtr<nsPIDOMEventTarget> target =
aDispatchStartTarget ? do_QueryInterface(aDispatchStartTarget) :
do_QueryInterface(GetWindow());
DispatchPageTransition(target, NS_LITERAL_STRING("pagehide"), aPersisted);
mVisible = PR_FALSE;
}

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

@ -816,8 +816,7 @@ public:
virtual nsresult DispatchDOMEvent(nsEvent* aEvent, nsIDOMEvent* aDOMEvent,
nsPresContext* aPresContext,
nsEventStatus* aEventStatus);
virtual nsresult GetListenerManager(PRBool aCreateIfNotFound,
nsIEventListenerManager** aResult);
virtual nsIEventListenerManager* GetListenerManager(PRBool aCreateIfNotFound);
virtual nsresult AddEventListenerByIID(nsIDOMEventListener *aListener,
const nsIID& aIID);
virtual nsresult RemoveEventListenerByIID(nsIDOMEventListener *aListener,
@ -1079,8 +1078,9 @@ protected:
return kNameSpaceID_None;
}
// Dispatch an event to the ScriptGlobalObject for this document
void DispatchEventToWindow(nsEvent *aEvent);
void DispatchPageTransition(nsPIDOMEventTarget* aDispatchTarget,
const nsAString& aType,
PRBool aPersisted);
// nsContentList match functions for GetElementsByClassName
static PRBool MatchClassNames(nsIContent* aContent, PRInt32 aNamespaceID,

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

@ -686,46 +686,37 @@ nsGenericDOMDataNode::DispatchDOMEvent(nsEvent* aEvent,
aPresContext, aEventStatus);
}
nsresult
nsGenericDOMDataNode::GetListenerManager(PRBool aCreateIfNotFound,
nsIEventListenerManager** aResult)
nsIEventListenerManager*
nsGenericDOMDataNode::GetListenerManager(PRBool aCreateIfNotFound)
{
return nsContentUtils::GetListenerManager(this, aCreateIfNotFound, aResult);
return nsContentUtils::GetListenerManager(this, aCreateIfNotFound);
}
nsresult
nsGenericDOMDataNode::AddEventListenerByIID(nsIDOMEventListener *aListener,
const nsIID& aIID)
{
nsCOMPtr<nsIEventListenerManager> elm;
nsresult rv = GetListenerManager(PR_TRUE, getter_AddRefs(elm));
if (elm) {
return elm->AddEventListenerByIID(aListener, aIID, NS_EVENT_FLAG_BUBBLE);
}
return rv;
nsIEventListenerManager* elm = GetListenerManager(PR_TRUE);
NS_ENSURE_STATE(elm);
return elm->AddEventListenerByIID(aListener, aIID, NS_EVENT_FLAG_BUBBLE);
}
nsresult
nsGenericDOMDataNode::RemoveEventListenerByIID(nsIDOMEventListener *aListener,
const nsIID& aIID)
{
nsCOMPtr<nsIEventListenerManager> elm;
GetListenerManager(PR_FALSE, getter_AddRefs(elm));
if (elm) {
return elm->RemoveEventListenerByIID(aListener, aIID, NS_EVENT_FLAG_BUBBLE);
}
return NS_OK;
nsIEventListenerManager* elm = GetListenerManager(PR_FALSE);
return elm ?
elm->RemoveEventListenerByIID(aListener, aIID, NS_EVENT_FLAG_BUBBLE) :
NS_OK;
}
nsresult
nsGenericDOMDataNode::GetSystemEventGroup(nsIDOMEventGroup** aGroup)
{
nsCOMPtr<nsIEventListenerManager> elm;
nsresult rv = GetListenerManager(PR_TRUE, getter_AddRefs(elm));
if (elm) {
return elm->GetSystemEventGroupLM(aGroup);
}
return rv;
nsIEventListenerManager* elm = GetListenerManager(PR_TRUE);
NS_ENSURE_STATE(elm);
return elm->GetSystemEventGroupLM(aGroup);
}
PRUint32

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

@ -172,8 +172,7 @@ public:
virtual nsresult DispatchDOMEvent(nsEvent* aEvent, nsIDOMEvent* aDOMEvent,
nsPresContext* aPresContext,
nsEventStatus* aEventStatus);
virtual nsresult GetListenerManager(PRBool aCreateIfNotFound,
nsIEventListenerManager** aResult);
virtual nsIEventListenerManager* GetListenerManager(PRBool aCreateIfNotFound);
virtual nsresult AddEventListenerByIID(nsIDOMEventListener *aListener,
const nsIID& aIID);
virtual nsresult RemoveEventListenerByIID(nsIDOMEventListener *aListener,

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

@ -251,46 +251,37 @@ nsINode::UnsetProperty(PRUint16 aCategory, nsIAtom *aPropertyName,
aStatus);
}
nsresult
nsGenericElement::GetListenerManager(PRBool aCreateIfNotFound,
nsIEventListenerManager** aResult)
nsIEventListenerManager*
nsGenericElement::GetListenerManager(PRBool aCreateIfNotFound)
{
return nsContentUtils::GetListenerManager(this, aCreateIfNotFound, aResult);
return nsContentUtils::GetListenerManager(this, aCreateIfNotFound);
}
nsresult
nsGenericElement::AddEventListenerByIID(nsIDOMEventListener *aListener,
const nsIID& aIID)
{
nsCOMPtr<nsIEventListenerManager> elm;
nsresult rv = GetListenerManager(PR_TRUE, getter_AddRefs(elm));
if (elm) {
return elm->AddEventListenerByIID(aListener, aIID, NS_EVENT_FLAG_BUBBLE);
}
return rv;
nsIEventListenerManager* elm = GetListenerManager(PR_TRUE);
NS_ENSURE_STATE(elm);
return elm->AddEventListenerByIID(aListener, aIID, NS_EVENT_FLAG_BUBBLE);
}
nsresult
nsGenericElement::RemoveEventListenerByIID(nsIDOMEventListener *aListener,
const nsIID& aIID)
{
nsCOMPtr<nsIEventListenerManager> elm;
GetListenerManager(PR_FALSE, getter_AddRefs(elm));
if (elm) {
return elm->RemoveEventListenerByIID(aListener, aIID, NS_EVENT_FLAG_BUBBLE);
}
return NS_OK;
nsIEventListenerManager* elm = GetListenerManager(PR_FALSE);
return elm ?
elm->RemoveEventListenerByIID(aListener, aIID, NS_EVENT_FLAG_BUBBLE) :
NS_OK;
}
nsresult
nsGenericElement::GetSystemEventGroup(nsIDOMEventGroup** aGroup)
{
nsCOMPtr<nsIEventListenerManager> elm;
nsresult rv = GetListenerManager(PR_TRUE, getter_AddRefs(elm));
if (elm) {
return elm->GetSystemEventGroupLM(aGroup);
}
return rv;
nsIEventListenerManager* elm = GetListenerManager(PR_TRUE);
NS_ENSURE_STATE(elm);
return elm->GetSystemEventGroupLM(aGroup);
}
nsINode::nsSlots*
@ -1618,11 +1609,9 @@ nsDOMEventRTTearoff::LastRelease()
nsresult
nsDOMEventRTTearoff::GetDOM3EventTarget(nsIDOM3EventTarget **aTarget)
{
nsCOMPtr<nsIEventListenerManager> listener_manager;
nsresult rv =
mNode->GetListenerManager(PR_TRUE, getter_AddRefs(listener_manager));
NS_ENSURE_SUCCESS(rv, rv);
nsIEventListenerManager* listener_manager =
mNode->GetListenerManager(PR_TRUE);
NS_ENSURE_STATE(listener_manager);
return CallQueryInterface(listener_manager, aTarget);
}
@ -1662,11 +1651,8 @@ nsDOMEventRTTearoff::RemoveEventListener(const nsAString& aType,
NS_IMETHODIMP
nsDOMEventRTTearoff::DispatchEvent(nsIDOMEvent *aEvt, PRBool* _retval)
{
nsCOMPtr<nsIEventListenerManager> listener_manager;
nsresult rv =
mNode->GetListenerManager(PR_TRUE, getter_AddRefs(listener_manager));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIDOMEventTarget> target = do_QueryInterface(listener_manager);
nsCOMPtr<nsIDOMEventTarget> target =
do_QueryInterface(mNode->GetListenerManager(PR_TRUE));
NS_ENSURE_STATE(target);
return target->DispatchEvent(aEvt, _retval);
}
@ -1719,10 +1705,9 @@ nsDOMEventRTTearoff::AddEventListener(const nsAString& aType,
PRBool aUseCapture,
PRBool aWantsUntrusted)
{
nsCOMPtr<nsIEventListenerManager> listener_manager;
nsresult rv =
mNode->GetListenerManager(PR_TRUE, getter_AddRefs(listener_manager));
NS_ENSURE_SUCCESS(rv, rv);
nsIEventListenerManager* listener_manager =
mNode->GetListenerManager(PR_TRUE);
NS_ENSURE_STATE(listener_manager);
PRInt32 flags = aUseCapture ? NS_EVENT_FLAG_CAPTURE : NS_EVENT_FLAG_BUBBLE;
@ -4138,21 +4123,16 @@ nsGenericElement::AddScriptEventListener(nsIAtom* aEventName,
PRBool defer = PR_TRUE;
nsCOMPtr<nsIEventListenerManager> manager;
nsresult rv = GetEventListenerManagerForAttr(getter_AddRefs(manager),
getter_AddRefs(target),
&defer);
NS_ENSURE_SUCCESS(rv, rv);
GetEventListenerManagerForAttr(getter_AddRefs(manager),
getter_AddRefs(target),
&defer);
NS_ENSURE_STATE(manager);
if (manager) {
defer = defer && aDefer; // only defer if everyone agrees...
PRUint32 lang = GetScriptTypeID();
rv =
manager->AddScriptEventListener(target, aEventName, aValue, lang, defer,
!nsContentUtils::IsChromeDoc(ownerDoc));
}
return rv;
defer = defer && aDefer; // only defer if everyone agrees...
PRUint32 lang = GetScriptTypeID();
return
manager->AddScriptEventListener(target, aEventName, aValue, lang, defer,
!nsContentUtils::IsChromeDoc(ownerDoc));
}
@ -4392,12 +4372,12 @@ nsGenericElement::GetEventListenerManagerForAttr(nsIEventListenerManager** aMana
nsISupports** aTarget,
PRBool* aDefer)
{
nsresult rv = GetListenerManager(PR_TRUE, aManager);
if (NS_SUCCEEDED(rv)) {
NS_ADDREF(*aTarget = static_cast<nsIContent*>(this));
}
*aManager = GetListenerManager(PR_TRUE);
*aDefer = PR_TRUE;
return rv;
NS_ENSURE_STATE(*aManager);
NS_ADDREF(*aManager);
NS_ADDREF(*aTarget = static_cast<nsIContent*>(this));
return NS_OK;
}
nsGenericElement::nsAttrInfo

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

@ -360,8 +360,7 @@ public:
virtual nsresult DispatchDOMEvent(nsEvent* aEvent, nsIDOMEvent* aDOMEvent,
nsPresContext* aPresContext,
nsEventStatus* aEventStatus);
virtual nsresult GetListenerManager(PRBool aCreateIfNotFound,
nsIEventListenerManager** aResult);
virtual nsIEventListenerManager* GetListenerManager(PRBool aCreateIfNotFound);
virtual nsresult AddEventListenerByIID(nsIDOMEventListener *aListener,
const nsIID& aIID);
virtual nsresult RemoveEventListenerByIID(nsIDOMEventListener *aListener,

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

@ -109,7 +109,8 @@ nsImageLoadingContent::nsImageLoadingContent()
// mBroken starts out true, since an image without a URI is broken....
mBroken(PR_TRUE),
mUserDisabled(PR_FALSE),
mSuppressed(PR_FALSE)
mSuppressed(PR_FALSE),
mIsImageStateForced(PR_FALSE)
{
if (!nsContentUtils::GetImgLoader()) {
mLoadingEnabled = PR_FALSE;
@ -617,10 +618,18 @@ nsImageLoadingContent::LoadImage(nsIURI* aNewURI,
return NS_OK;
}
nsresult
nsImageLoadingContent::ForceImageState(PRBool aForce, PRInt32 aState)
{
mIsImageStateForced = aForce;
mForcedImageState = aState;
return NS_OK;
}
PRInt32
nsImageLoadingContent::ImageState() const
{
return
return mIsImageStateForced ? mForcedImageState :
(mBroken * NS_EVENT_STATE_BROKEN) |
(mUserDisabled * NS_EVENT_STATE_USERDISABLED) |
(mSuppressed * NS_EVENT_STATE_SUPPRESSED) |

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

@ -260,10 +260,21 @@ private:
*/
ImageObserver mObserverList;
/**
* When mIsImageStateForced is true, this holds the ImageState that we'll
* return in ImageState().
*/
PRInt32 mForcedImageState;
PRInt16 mImageBlockingStatus;
PRPackedBool mLoadingEnabled : 1;
PRPackedBool mStartingLoad : 1;
/**
* When true, we return mForcedImageState from ImageState().
*/
PRPackedBool mIsImageStateForced : 1;
/**
* The state we had the last time we checked whether we needed to notify the
* document of a state change. These are maintained by UpdateImageState.

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

@ -222,9 +222,8 @@ nsNodeUtils::LastRelease(nsINode* aNode)
if (aNode->HasFlag(NODE_HAS_LISTENERMANAGER)) {
#ifdef DEBUG
if (nsContentUtils::IsInitialized()) {
nsCOMPtr<nsIEventListenerManager> manager;
nsContentUtils::GetListenerManager(aNode, PR_FALSE,
getter_AddRefs(manager));
nsIEventListenerManager* manager =
nsContentUtils::GetListenerManager(aNode, PR_FALSE);
if (!manager) {
NS_ERROR("Huh, our bit says we have a listener manager list, "
"but there's nothing in the hash!?!!");
@ -583,8 +582,7 @@ nsNodeUtils::CloneAndAdopt(nsINode *aNode, PRBool aClone, PRBool aDeep,
nsPIDOMWindow* window = newDoc->GetInnerWindow();
if (window) {
nsCOMPtr<nsIEventListenerManager> elm;
aNode->GetListenerManager(PR_FALSE, getter_AddRefs(elm));
nsIEventListenerManager* elm = aNode->GetListenerManager(PR_FALSE);
if (elm) {
window->SetMutationListeners(elm->MutationListenerBits());
if (elm->MayHavePaintEventListener()) {

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

@ -85,8 +85,6 @@
#include "nsObjectLoadingContent.h"
#include "mozAutoDocUpdate.h"
static NS_DEFINE_CID(kCPluginManagerCID, NS_PLUGINMANAGER_CID);
#ifdef PR_LOGGING
static PRLogModuleInfo* gObjectLog = PR_NewLogModule("objlc");
#endif
@ -301,7 +299,7 @@ IsSupportedImage(const nsCString& aMimeType)
static PRBool
IsSupportedPlugin(const nsCString& aMIMEType)
{
nsCOMPtr<nsIPluginHost> host(do_GetService("@mozilla.org/plugin/host;1"));
nsCOMPtr<nsIPluginHost> host(do_GetService(MOZ_PLUGIN_HOST_CONTRACTID));
if (!host) {
return PR_FALSE;
}
@ -339,7 +337,7 @@ IsPluginEnabledByExtension(nsIURI* uri, nsCString& mimeType)
if (ext.IsEmpty())
return PR_FALSE;
nsCOMPtr<nsIPluginHost> host(do_GetService("@mozilla.org/plugin/host;1"));
nsCOMPtr<nsIPluginHost> host(do_GetService(MOZ_PLUGIN_HOST_CONTRACTID));
const char* typeFromExt;
if (host &&
NS_SUCCEEDED(host->IsPluginEnabledForExtension(ext.get(), typeFromExt))) {
@ -1584,7 +1582,7 @@ nsObjectLoadingContent::TypeForClassID(const nsAString& aClassID,
nsACString& aType)
{
// Need a plugin host for any class id support
nsCOMPtr<nsIPluginHost> pluginHost(do_GetService(kCPluginManagerCID));
nsCOMPtr<nsIPluginHost> pluginHost(do_GetService(MOZ_PLUGIN_HOST_CONTRACTID));
if (!pluginHost) {
return NS_ERROR_NOT_AVAILABLE;
}
@ -1834,7 +1832,7 @@ nsObjectLoadingContent::GetPluginSupportState(nsIContent* aContent,
/* static */ PluginSupportState
nsObjectLoadingContent::GetPluginDisabledState(const nsCString& aContentType)
{
nsCOMPtr<nsIPluginHost> host(do_GetService("@mozilla.org/plugin/host;1"));
nsCOMPtr<nsIPluginHost> host(do_GetService(MOZ_PLUGIN_HOST_CONTRACTID));
if (!host) {
return ePluginUnsupported;
}

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

@ -56,7 +56,6 @@
#include "nsIDocumentEncoder.h"
#include "nsTArray.h"
class nsPlainTextSerializer : public nsIContentSerializer,
public nsIHTMLContentSink,
public nsIHTMLToTextSink
@ -97,8 +96,6 @@ public:
// nsIContentSink
NS_IMETHOD WillParse(void) { return NS_OK; }
NS_IMETHOD WillBuildModel(void) { return NS_OK; }
NS_IMETHOD DidBuildModel(void) { return NS_OK; }
NS_IMETHOD WillInterrupt(void) { return NS_OK; }
NS_IMETHOD WillResume(void) { return NS_OK; }
NS_IMETHOD SetParser(nsIParser* aParser) { return NS_OK; }

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

@ -465,14 +465,6 @@ public:
{
return mInner->SetTarget(aTarget);
}
NS_IMETHOD SetCurrentTarget(nsIDOMEventTarget* aTarget)
{
return mInner->SetCurrentTarget(aTarget);
}
NS_IMETHOD SetOriginalTarget(nsIDOMEventTarget* aTarget)
{
return mInner->SetOriginalTarget(aTarget);
}
NS_IMETHOD_(PRBool) IsDispatchStopped()
{
return mInner->IsDispatchStopped();
@ -481,10 +473,6 @@ public:
{
return mInner->GetInternalNSEvent();
}
NS_IMETHOD_(PRBool) HasOriginalTarget()
{
return mInner->HasOriginalTarget();
}
NS_IMETHOD SetTrusted(PRBool aTrusted)
{
return mInner->SetTrusted(aTrusted);

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

@ -313,6 +313,10 @@ _TEST_FILES = test_bug5141.html \
file_htmlserializer_ipv6.html \
file_htmlserializer_ipv6_out.html \
test_bug498433.html \
test_bug498897.html \
file_bug498897.html \
file_bug498897.html^headers^ \
file_bug498897.css \
$(NULL)
# Disabled; see bug 492181
# test_plugin_freezing.html

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

@ -0,0 +1 @@
body { background: orange; }

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

@ -0,0 +1,23 @@
<html>
<head>
<title>Testcase for bug 498897</title>
<script type="application/javascript" language="javascript">
<!--
function test()
{
var hadException = false;
try {
document.createComment('a');
}
catch (e) {
hadException = true;
}
parent.ok(!hadException, "Shouldn't have got an exception!");
parent.testFinished();
}
//-->
</script>
</head>
<body onload="test();">
</body>
</html>

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

@ -0,0 +1 @@
Link: <file_bug498897.css>; rel=stylesheet

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

@ -80,6 +80,8 @@ categoryManager.addCategoryEntry("content-policy", policyName, policyName, false
var tests = ["SCRIPT", "IMAGE", "STYLESHEET", "OBJECT", "DOCUMENT", "SUBDOCUMENT", "XBL", "XMLHTTPREQUEST"];
var curTest = -1;
var div;
SimpleTest.waitForExplicitFinish();
setTimeout(runNextTest, 0);
@ -89,6 +91,12 @@ function runNextTest() {
if (curTest >= 0) {
var type = "TYPE_" + tests[curTest];
is(lastContentType, Ci.nsIContentPolicy[type], "Content policies triggered for " + type);
if (tests[curTest] == "XBL")
{
//XXX Removing binding to work-around a memory leak (bugs 478528, 499735).
document.removeBinding(div, testURL);
}
}
curTest++;
@ -165,7 +173,7 @@ function request_subdocument() {
function request_xbl() {
var content = $("content");
var div = document.createElement("div");
div = document.createElement("div");
content.appendChild(div);
document.addBinding(div, testURL);

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

@ -0,0 +1,108 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=498897
-->
<head>
<title>Test for Bug 498897</title>
<script type="application/javascript" src="/MochiKit/packed.js"></script>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=498897">Mozilla Bug 498897</a>
<p id="display"><iframe id="testframe"></iframe></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript">
/** Test for Bug 498897 **/
var checkedLoad = false;
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
const Cc = Components.classes;
const Ci = Components.interfaces;
// Content policy / factory implementation for the test
var policyID = Components.ID("{65944d64-2390-422e-bea3-80d0af7f69ef}");
var policyName = "@mozilla.org/498897_testpolicy;1";
var policy = {
// nsISupports implementation
QueryInterface: function(iid) {
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
if (iid.equals(Ci.nsISupports) ||
iid.equals(Ci.nsIFactory) ||
iid.equals(Ci.nsIContentPolicy))
return this;
throw Components.results.NS_ERROR_NO_INTERFACE;
},
// nsIFactory implementation
createInstance: function(outer, iid) {
return this.QueryInterface(iid);
},
// nsIContentPolicy implementation
shouldLoad: function(contentType, contentLocation, requestOrigin, context,
mimeTypeGuess, extra) {
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
if (contentLocation instanceof Ci.nsIURL &&
contentLocation.fileName == "file_bug498897.css" &&
requestOrigin instanceof Ci.nsIURL &&
requestOrigin.fileName == "file_bug498897.html") {
checkedLoad = true;
}
return Ci.nsIContentPolicy.ACCEPT;
},
shouldProcess: function(contentType, contentLocation, requestOrigin, context,
mimeTypeGuess, extra) {
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
return Ci.nsIContentPolicy.ACCEPT;
}
}
var componentManager = Components.manager
.QueryInterface(Ci.nsIComponentRegistrar);
componentManager.registerFactory(policyID, "Test content policy for bug 498897",
policyName, policy);
var categoryManager =
Cc["@mozilla.org/categorymanager;1"].getService(Ci.nsICategoryManager);
categoryManager.addCategoryEntry("content-policy", policyName, policyName,
false, true);
function testFinished()
{
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
ok(checkedLoad, "Content policy didn't get called!");
categoryManager.deleteCategoryEntry("content-policy", policyName, false);
setTimeout(function() {
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
componentManager.unregisterFactory(policyID, policy);
SimpleTest.finish();
}, 0);
}
SimpleTest.waitForExplicitFinish();
document.getElementById("testframe").src = "file_bug498897.html";
</script>
</pre>
</body>
</html>

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

@ -0,0 +1,94 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Vladimir Vukicevic <vladimir@pobox.com>
* Portions created by the Initial Developer are Copyright (C) 2009
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "prmem.h"
#include "nsIServiceManager.h"
#include "nsIDOMDocument.h"
#include "nsIDocument.h"
#include "nsIDOMCanvasRenderingContext2D.h"
#include "nsICanvasRenderingContextInternal.h"
#include "nsICanvasElement.h"
#include "nsIPrincipal.h"
#include "nsINode.h"
#include "nsGfxCIID.h"
#include "nsTArray.h"
#include "CanvasUtils.h"
using namespace mozilla;
void
CanvasUtils::DoDrawImageSecurityCheck(nsICanvasElement *aCanvasElement,
nsIPrincipal *aPrincipal,
PRBool forceWriteOnly)
{
// Callers should ensure that mCanvasElement is non-null before calling this
if (!aCanvasElement) {
NS_WARNING("DoDrawImageSecurityCheck called without canvas element!");
return;
}
if (aCanvasElement->IsWriteOnly())
return;
// If we explicitly set WriteOnly just do it and get out
if (forceWriteOnly) {
aCanvasElement->SetWriteOnly();
return;
}
if (aPrincipal == nsnull)
return;
nsCOMPtr<nsINode> elem = do_QueryInterface(aCanvasElement);
if (elem) { // XXXbz How could this actually be null?
PRBool subsumes;
nsresult rv =
elem->NodePrincipal()->Subsumes(aPrincipal, &subsumes);
if (NS_SUCCEEDED(rv) && subsumes) {
// This canvas has access to that image anyway
return;
}
}
aCanvasElement->SetWriteOnly();
}

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

@ -1,4 +1,4 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
@ -15,11 +15,10 @@
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 2003
* Vladimir Vukicevic <vladimir@pobox.com>
* Portions created by the Initial Developer are Copyright (C) 2009
* the Initial Developer. All Rights Reserved.
*
* Original Author: Aaron Leventhal (aaronl@netscape.com)
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
@ -36,32 +35,49 @@
*
* ***** END LICENSE BLOCK ***** */
#include "nsISupports.idl"
#ifndef _CANVASUTILS_H_
#define _CANVASUTILS_H_
interface nsIAccessNode;
interface nsIContent;
#include "prtypes.h"
#include "nsContentUtils.h"
#include "nsICanvasElement.h"
#include "nsIPrincipal.h"
#include "nsIDOMElement.h"
#include "nsRect.h"
[uuid(fa9cafac-9562-49ad-afcf-911ab1e4e4fb)]
#include "gfxASurface.h"
interface nsPIAccessibleDocument : nsISupports
{
/**
* Find the accessible object in the accessibility cache that
* corresponds to aStartNode or the first ancestor of aStartNode
* that has an accessible object associated with it.
* Clear that accessible object's parent's cache of accessible children and
* and remove the accessible object and any decendents from the accessible cache.
* New accessible objects will be created and cached again on demand.
* @param aChangeContent The child that is changing
* @param aEvent The event from nsIAccessibleEvent that caused the change:
* Must be one of: EVENT_REORDER (change),
* EVENT_SHOW (make visible or create) or
* EVENT_HIDE (destroy or hide)
*/
void invalidateCacheSubtree(in nsIContent aChangeContent,
in PRUint32 aChangeEvent);
void cacheAccessNode(in voidPtr aUniqueID, in nsIAccessNode aAccessNode);
void flushPendingEvents();
void fireDocLoadEvents(in PRUint32 aEventType);
void fireAnchorJumpEvent();
namespace mozilla {
class CanvasUtils {
public:
// Check that the rectangle [x,y,w,h] is a subrectangle of [0,0,realWidth,realHeight]
static PRBool CheckSaneSubrectSize(PRInt32 x, PRInt32 y, PRInt32 w, PRInt32 h,
PRInt32 realWidth, PRInt32 realHeight)
{
if (w <= 0 || h <= 0 || x < 0 || y < 0)
return PR_FALSE;
if (x >= realWidth || w > (realWidth - x) ||
y >= realHeight || h > (realHeight - y))
return PR_FALSE;
return PR_TRUE;
}
// Flag aCanvasElement as write-only if drawing an image with aPrincipal
// onto it would make it such.
static void DoDrawImageSecurityCheck(nsICanvasElement *aCanvasElement,
nsIPrincipal *aPrincipal,
PRBool forceWriteOnly);
private:
// this can't be instantiated
CanvasUtils() { }
};
}
#endif /* _CANVASUTILS_H_ */

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

@ -68,17 +68,11 @@ REQUIRES = \
qcms \
$(NULL)
# XXX some platforms can't handle building
# an empty .a/lib. Remove this dummy.cpp
# whenever w have a rendering context
# that doesn't depend on any non-default
# libraries.
CPPSRCS = dummy.cpp \
$(NULL)
ifdef MOZ_ENABLE_CANVAS
CPPSRCS += nsCanvasRenderingContext2D.cpp
endif
CPPSRCS = \
CanvasUtils.cpp \
nsCanvasRenderingContext2D.cpp \
$(NULL)
# we don't want the shared lib, but we want to force the creation of a static lib.
FORCE_STATIC_LIB = 1

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

@ -1,9 +0,0 @@
/*
* This file only exists because some platforms can't handle building an empty .a
* file, or .lib, or whatever (e.g. OS X, possibly Win32).
*
* Need at least one external symbol for some linkers to create a proper
* archive file: https://bugzilla.mozilla.org/show_bug.cgi?id=311143
*/
void concvsdummy(void) {}

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

@ -55,15 +55,9 @@
#include "nsIPresShell.h"
#include "nsIVariant.h"
#include "imgIRequest.h"
#include "imgIContainer.h"
#include "gfxIImageFrame.h"
#include "nsIDOMHTMLCanvasElement.h"
#include "nsICanvasElement.h"
#include "nsIDOMHTMLImageElement.h"
#include "nsIImageLoadingContent.h"
#include "nsIInterfaceRequestorUtils.h"
#include "nsIImage.h"
#include "nsIFrame.h"
#include "nsDOMError.h"
#include "nsIScriptError.h"
@ -110,17 +104,15 @@
#include "nsBidiPresUtils.h"
#ifdef MOZ_MEDIA
#include "nsHTMLVideoElement.h"
#endif
#include "CanvasUtils.h"
using namespace mozilla;
#ifndef M_PI
#define M_PI 3.14159265358979323846
#define M_PI_2 1.57079632679489661923
#endif
static PRBool CheckSaneSubrectSize (PRInt32 x, PRInt32 y, PRInt32 w, PRInt32 h, PRInt32 realWidth, PRInt32 realHeight);
/* Float validation stuff */
#define VALIDATE(_f) if (!JSDOUBLE_IS_FINITE(_f)) return PR_FALSE
@ -360,14 +352,6 @@ protected:
*/
void ApplyStyle(Style aWhichStyle, PRBool aUseGlobalAlpha = PR_TRUE);
// If aPrincipal is not subsumed by this canvas element, then
// we make the canvas write-only so bad guys can't extract the pixel
// data. If forceWriteOnly is set, we force write only to be set
// and ignore aPrincipal. (This is used for when the original data came
// from a <canvas> that had write-only set.)
void DoDrawImageSecurityCheck(nsIPrincipal* aPrincipal,
PRBool forceWriteOnly);
// Member vars
PRInt32 mWidth, mHeight;
PRPackedBool mValid;
@ -390,7 +374,13 @@ protected:
* Flag to avoid duplicate calls to InvalidateFrame. Set to true whenever
* Redraw is called, reset to false when Render is called.
*/
PRBool mIsFrameInvalid;
PRBool mIsEntireFrameInvalid;
/**
* Number of times we've invalidated before calling redraw
*/
PRUint32 mInvalidateCount;
static const PRUint32 kCanvasMaxInvalidateCount = 100;
/**
* Returns true iff the the given operator should affect areas of the
@ -478,8 +468,11 @@ protected:
/**
* Draws the current path in the given style. Takes care of
* any shadow drawing and will use intermediate surfaces as needed.
*
* If dirtyRect is given, it will contain the device-space dirty
* rectangle of the draw operation.
*/
nsresult DrawPath(Style style);
nsresult DrawPath(Style style, gfxRect *dirtyRect = nsnull);
/**
* Draws a rectangle in the given style; used by FillRect and StrokeRect.
@ -614,14 +607,6 @@ protected:
static PRBool ConvertJSValToDouble(double* aProp, JSContext* aContext,
jsval aValue);
// thebes helpers
nsresult ThebesSurfaceFromElement(nsIDOMElement *imgElt,
PRBool forceCopy,
gfxASurface **aSurface,
PRInt32 *widthOut, PRInt32 *heightOut,
nsIPrincipal **prinOut,
PRBool *forceWriteOnlyOut);
// other helpers
void GetAppUnitsValues(PRUint32 *perDevPixel, PRUint32 *perCSSPixel) {
// If we don't have a canvas element, we just return something generic.
@ -677,8 +662,8 @@ NS_NewCanvasRenderingContext2D(nsIDOMCanvasRenderingContext2D** aResult)
nsCanvasRenderingContext2D::nsCanvasRenderingContext2D()
: mValid(PR_FALSE), mOpaque(PR_FALSE), mCanvasElement(nsnull),
mSaveCount(0), mIsFrameInvalid(PR_FALSE), mLastStyle(STYLE_MAX),
mStyleStack(20)
mSaveCount(0), mIsEntireFrameInvalid(PR_FALSE), mInvalidateCount(0),
mLastStyle(STYLE_MAX), mStyleStack(20)
{
}
@ -693,7 +678,7 @@ nsCanvasRenderingContext2D::Destroy()
mSurface = nsnull;
mThebes = nsnull;
mValid = PR_FALSE;
mIsFrameInvalid = PR_FALSE;
mIsEntireFrameInvalid = PR_FALSE;
}
nsresult
@ -791,43 +776,6 @@ nsCanvasRenderingContext2D::DirtyAllStyles()
}
}
void
nsCanvasRenderingContext2D::DoDrawImageSecurityCheck(nsIPrincipal* aPrincipal,
PRBool forceWriteOnly)
{
// Callers should ensure that mCanvasElement is non-null before calling this
if (!mCanvasElement) {
NS_WARNING("DoDrawImageSecurityCheck called without canvas element!");
return;
}
if (mCanvasElement->IsWriteOnly())
return;
// If we explicitly set WriteOnly just do it and get out
if (forceWriteOnly) {
mCanvasElement->SetWriteOnly();
return;
}
if (aPrincipal == nsnull)
return;
nsCOMPtr<nsINode> elem = do_QueryInterface(mCanvasElement);
if (elem) { // XXXbz How could this actually be null?
PRBool subsumes;
nsresult rv =
elem->NodePrincipal()->Subsumes(aPrincipal, &subsumes);
if (NS_SUCCEEDED(rv) && subsumes) {
// This canvas has access to that image anyway
return;
}
}
mCanvasElement->SetWriteOnly();
}
void
nsCanvasRenderingContext2D::ApplyStyle(Style aWhichStyle,
PRBool aUseGlobalAlpha)
@ -850,8 +798,9 @@ nsCanvasRenderingContext2D::ApplyStyle(Style aWhichStyle,
if (!mCanvasElement)
return;
DoDrawImageSecurityCheck(pattern->Principal(),
pattern->GetForceWriteOnly());
CanvasUtils::DoDrawImageSecurityCheck(mCanvasElement,
pattern->Principal(),
pattern->GetForceWriteOnly());
gfxPattern* gpat = pattern->GetPattern();
@ -883,12 +832,11 @@ nsCanvasRenderingContext2D::Redraw()
if (!mCanvasElement)
return NS_OK;
if (!mIsFrameInvalid) {
mIsFrameInvalid = PR_TRUE;
return mCanvasElement->InvalidateFrame();
}
if (mIsEntireFrameInvalid)
return NS_OK;
return NS_OK;
mIsEntireFrameInvalid = PR_TRUE;
return mCanvasElement->InvalidateFrame();
}
nsresult
@ -897,12 +845,13 @@ nsCanvasRenderingContext2D::Redraw(const gfxRect& r)
if (!mCanvasElement)
return NS_OK;
if (!mIsFrameInvalid) {
mIsFrameInvalid = PR_TRUE;
return mCanvasElement->InvalidateFrameSubrect(r);
}
if (mIsEntireFrameInvalid)
return NS_OK;
return NS_OK;
if (++mInvalidateCount > kCanvasMaxInvalidateCount)
return Redraw();
return mCanvasElement->InvalidateFrameSubrect(r);
}
NS_IMETHODIMP
@ -1013,7 +962,9 @@ nsCanvasRenderingContext2D::Render(gfxContext *ctx, gfxPattern::GraphicsFilter a
if (mOpaque)
ctx->SetOperator(op);
mIsFrameInvalid = PR_FALSE;
mIsEntireFrameInvalid = PR_FALSE;
mInvalidateCount = 0;
return rv;
}
@ -1333,7 +1284,6 @@ nsCanvasRenderingContext2D::CreatePattern(nsIDOMHTMLElement *image,
const nsAString& repeat,
nsIDOMCanvasPattern **_retval)
{
nsresult rv;
gfxPattern::GraphicsExtend extend;
if (repeat.IsEmpty() || repeat.EqualsLiteral("repeat")) {
@ -1351,22 +1301,17 @@ nsCanvasRenderingContext2D::CreatePattern(nsIDOMHTMLElement *image,
return NS_ERROR_DOM_SYNTAX_ERR;
}
PRInt32 imgWidth, imgHeight;
nsCOMPtr<nsIPrincipal> principal;
PRBool forceWriteOnly = PR_FALSE;
nsRefPtr<gfxASurface> imgsurf;
rv = ThebesSurfaceFromElement(image, PR_TRUE,
getter_AddRefs(imgsurf), &imgWidth, &imgHeight,
getter_AddRefs(principal), &forceWriteOnly);
if (NS_FAILED(rv))
return rv;
nsLayoutUtils::SurfaceFromElementResult res =
nsLayoutUtils::SurfaceFromElement(image, nsLayoutUtils::SFE_WANT_NEW_SURFACE);
if (!res.mSurface)
return NS_ERROR_NOT_AVAILABLE;
nsRefPtr<gfxPattern> thebespat = new gfxPattern(imgsurf);
nsRefPtr<gfxPattern> thebespat = new gfxPattern(res.mSurface);
thebespat->SetExtend(extend);
nsRefPtr<nsCanvasPattern> pat = new nsCanvasPattern(thebespat, principal,
forceWriteOnly);
nsRefPtr<nsCanvasPattern> pat = new nsCanvasPattern(thebespat, res.mPrincipal,
res.mIsWriteOnly);
if (!pat)
return NS_ERROR_OUT_OF_MEMORY;
@ -1524,7 +1469,7 @@ nsCanvasRenderingContext2D::ShadowFinalize(gfxAlphaBoxBlur& blur)
}
nsresult
nsCanvasRenderingContext2D::DrawPath(Style style)
nsCanvasRenderingContext2D::DrawPath(Style style, gfxRect *dirtyRect)
{
/*
* Need an intermediate surface when:
@ -1591,6 +1536,12 @@ nsCanvasRenderingContext2D::DrawPath(Style style)
else
mThebes->Stroke();
// XXX do some more work to calculate the extents of shadows
// XXX handle stroke extents
if (dirtyRect && style == STYLE_FILL && !doDrawShadow) {
*dirtyRect = mThebes->GetUserPathExtent();
}
if (doUseIntermediateSurface) {
mThebes->PopGroupToSource();
DirtyAllStyles();
@ -1598,6 +1549,15 @@ nsCanvasRenderingContext2D::DrawPath(Style style)
mThebes->Paint(CurrentState().StyleIsColor(style) ? 1.0 : CurrentState().globalAlpha);
}
if (dirtyRect) {
if (style != STYLE_FILL || doDrawShadow) {
// just use the clip extents
*dirtyRect = mThebes->GetClipExtents();
}
*dirtyRect = mThebes->UserToDevice(*dirtyRect);
}
return NS_OK;
}
@ -1619,7 +1579,8 @@ nsCanvasRenderingContext2D::ClearRect(float x, float y, float w, float h)
mThebes->Rectangle(gfxRect(x, y, w, h));
mThebes->Fill();
return Redraw();
gfxRect dirty = mThebes->UserToDevice(mThebes->GetUserPathExtent());
return Redraw(dirty);
}
nsresult
@ -1633,11 +1594,12 @@ nsCanvasRenderingContext2D::DrawRect(const gfxRect& rect, Style style)
mThebes->NewPath();
mThebes->Rectangle(rect);
nsresult rv = DrawPath(style);
gfxRect dirty;
nsresult rv = DrawPath(style, &dirty);
if (NS_FAILED(rv))
return rv;
return Redraw();
return Redraw(dirty);
}
NS_IMETHODIMP
@ -1673,19 +1635,21 @@ nsCanvasRenderingContext2D::ClosePath()
NS_IMETHODIMP
nsCanvasRenderingContext2D::Fill()
{
nsresult rv = DrawPath(STYLE_FILL);
gfxRect dirty;
nsresult rv = DrawPath(STYLE_FILL, &dirty);
if (NS_FAILED(rv))
return rv;
return Redraw();
return Redraw(dirty);
}
NS_IMETHODIMP
nsCanvasRenderingContext2D::Stroke()
{
nsresult rv = DrawPath(STYLE_STROKE);
gfxRect dirty;
nsresult rv = DrawPath(STYLE_STROKE, &dirty);
if (NS_FAILED(rv))
return rv;
return Redraw();
return Redraw(dirty);
}
NS_IMETHODIMP
@ -2301,8 +2265,7 @@ nsCanvasRenderingContext2D::DrawOrMeasureText(const nsAString& aRawText,
processor.mThebes = mThebes;
processor.mOp = aOp;
processor.mBoundingBox = gfxRect(0, 0, 0, 0);
// need to measure size if using an intermediate surface for drawing
processor.mDoMeasureBoundingBox = doDrawShadow;
processor.mDoMeasureBoundingBox = doDrawShadow || !mIsEntireFrameInvalid;
processor.mFontgrp = GetCurrentFontStyle();
NS_ASSERTION(processor.mFontgrp, "font group is null");
@ -2396,6 +2359,9 @@ nsCanvasRenderingContext2D::DrawOrMeasureText(const nsAString& aRawText,
mThebes->Translate(-trans);
}
// save the previous bounding box
gfxRect boundingBox = processor.mBoundingBox;
// don't ever need to measure the bounding box twice
processor.mDoMeasureBoundingBox = PR_FALSE;
@ -2477,6 +2443,9 @@ nsCanvasRenderingContext2D::DrawOrMeasureText(const nsAString& aRawText,
} else if (doUseIntermediateSurface)
mThebes->Paint(CurrentState().StyleIsColor(STYLE_FILL) ? 1.0 : CurrentState().globalAlpha);
if (aOp == nsCanvasRenderingContext2D::TEXT_DRAW_OPERATION_FILL && !doDrawShadow)
return Redraw(mThebes->UserToDevice(boundingBox));
return Redraw();
}
@ -2542,7 +2511,8 @@ nsCanvasRenderingContext2D::MozDrawText(const nsAString& textToDraw)
nsnull,
nsnull,
nsnull);
return NS_OK;
return Redraw();
}
NS_IMETHODIMP
@ -2651,10 +2621,12 @@ nsCanvasRenderingContext2D::MozTextAlongPath(const nsAString& textToDraw, PRBool
x += 2 * halfAdvance;
}
if(stroke)
if (stroke) {
ApplyStyle(STYLE_STROKE);
else
mThebes->NewPath();
} else {
ApplyStyle(STYLE_FILL);
}
for(PRUint32 i = 0; i < strLength; i++)
{
@ -2679,9 +2651,12 @@ nsCanvasRenderingContext2D::MozTextAlongPath(const nsAString& textToDraw, PRBool
mThebes->SetMatrix(matrix);
}
if (stroke)
mThebes->Stroke();
delete [] cp;
return NS_OK;
return Redraw();
}
//
@ -2919,6 +2894,7 @@ NS_IMETHODIMP
nsCanvasRenderingContext2D::DrawImage()
{
nsresult rv;
gfxRect dirty;
// we can't do a security check without a canvas element, so
// just skip this entirely
@ -2959,22 +2935,33 @@ nsCanvasRenderingContext2D::DrawImage()
ctx, argv[0]))
return NS_ERROR_DOM_TYPE_MISMATCH_ERR;
PRInt32 imgWidth, imgHeight;
nsCOMPtr<nsIPrincipal> principal;
PRBool forceWriteOnly = PR_FALSE;
gfxMatrix matrix;
nsRefPtr<gfxPattern> pattern;
nsRefPtr<gfxPath> path;
nsRefPtr<gfxASurface> imgsurf;
#ifdef WINCE
nsRefPtr<gfxASurface> currentSurface;
#endif
rv = ThebesSurfaceFromElement(imgElt, PR_FALSE,
getter_AddRefs(imgsurf), &imgWidth, &imgHeight,
getter_AddRefs(principal), &forceWriteOnly);
if (NS_FAILED(rv))
return rv;
DoDrawImageSecurityCheck(principal, forceWriteOnly);
nsLayoutUtils::SurfaceFromElementResult res =
nsLayoutUtils::SurfaceFromElement(imgElt);
if (!res.mSurface)
return NS_ERROR_NOT_AVAILABLE;
#ifndef WINCE
// On non-CE, force a copy if we're using drawImage with our destination
// as a source to work around some Cairo self-copy semantics issues.
if (res.mSurface == mSurface) {
res = nsLayoutUtils::SurfaceFromElement(imgElt, nsLayoutUtils::SFE_WANT_NEW_SURFACE);
if (!res.mSurface)
return NS_ERROR_NOT_AVAILABLE;
}
#endif
nsRefPtr<gfxASurface> imgsurf = res.mSurface;
nsCOMPtr<nsIPrincipal> principal = res.mPrincipal;
gfxIntSize imgSize = res.mSize;
PRBool forceWriteOnly = res.mIsWriteOnly;
CanvasUtils::DoDrawImageSecurityCheck(mCanvasElement, principal, forceWriteOnly);
gfxContextPathAutoSaveRestore pathSR(mThebes, PR_FALSE);
@ -2987,16 +2974,16 @@ nsCanvasRenderingContext2D::DrawImage()
GET_ARG(&dx, argv[1]);
GET_ARG(&dy, argv[2]);
sx = sy = 0.0;
dw = sw = (double) imgWidth;
dh = sh = (double) imgHeight;
dw = sw = (double) imgSize.width;
dh = sh = (double) imgSize.height;
} else if (argc == 5) {
GET_ARG(&dx, argv[1]);
GET_ARG(&dy, argv[2]);
GET_ARG(&dw, argv[3]);
GET_ARG(&dh, argv[4]);
sx = sy = 0.0;
sw = (double) imgWidth;
sh = (double) imgHeight;
sw = (double) imgSize.width;
sh = (double) imgSize.height;
} else if (argc == 9) {
GET_ARG(&sx, argv[1]);
GET_ARG(&sy, argv[2]);
@ -3027,8 +3014,8 @@ nsCanvasRenderingContext2D::DrawImage()
// check args
if (sx < 0.0 || sy < 0.0 ||
sw < 0.0 || sw > (double) imgWidth ||
sh < 0.0 || sh > (double) imgHeight ||
sw < 0.0 || sw > (double) imgSize.width ||
sh < 0.0 || sh > (double) imgSize.height ||
dw < 0.0 || dh < 0.0)
{
// XXX ERRMSG we need to report an error to developers here! (bug 329026)
@ -3118,6 +3105,8 @@ nsCanvasRenderingContext2D::DrawImage()
} else
mThebes->Clip(clip);
dirty = mThebes->UserToDevice(clip);
mThebes->Paint(CurrentState().globalAlpha);
}
@ -3134,7 +3123,7 @@ nsCanvasRenderingContext2D::DrawImage()
FINISH:
if (NS_SUCCEEDED(rv))
rv = Redraw();
rv = Redraw(dirty);
return rv;
}
@ -3258,192 +3247,6 @@ nsCanvasRenderingContext2D::ConvertJSValToXPCObject(nsISupports** aSupports, REF
return JS_FALSE;
}
/* thebes ARGB32 surfaces are ARGB stored as a packed 32-bit integer; on little-endian
* platforms, they appear as BGRA bytes in the surface data. The color values are also
* stored with premultiplied alpha.
*
* If forceCopy is FALSE, a surface may be returned that's only valid during the current
* operation. If it's TRUE, a copy will always be made that can safely be retained.
*/
nsresult
nsCanvasRenderingContext2D::ThebesSurfaceFromElement(nsIDOMElement *imgElt,
PRBool forceCopy,
gfxASurface **aSurface,
PRInt32 *widthOut,
PRInt32 *heightOut,
nsIPrincipal **prinOut,
PRBool *forceWriteOnlyOut)
{
nsresult rv;
nsCOMPtr<nsINode> node = do_QueryInterface(imgElt);
/* If it's a Canvas, grab its internal surface as necessary */
nsCOMPtr<nsICanvasElement> canvas = do_QueryInterface(imgElt);
if (node && canvas) {
PRUint32 w, h;
rv = canvas->GetSize(&w, &h);
NS_ENSURE_SUCCESS(rv, rv);
nsRefPtr<gfxASurface> sourceSurface;
if (!forceCopy && canvas->CountContexts() == 1) {
nsICanvasRenderingContextInternal *srcCanvas = canvas->GetContextAtIndex(0);
rv = srcCanvas->GetThebesSurface(getter_AddRefs(sourceSurface));
#ifndef WINCE
// force a copy if we couldn't get the surface, or if it's
// the same as what we have
if (sourceSurface == mSurface || NS_FAILED(rv))
#else
// force a copy if we couldn't get the surface
if (NS_FAILED(rv))
#endif
sourceSurface = nsnull;
}
if (sourceSurface == nsnull) {
nsRefPtr<gfxASurface> surf =
gfxPlatform::GetPlatform()->CreateOffscreenSurface
(gfxIntSize(w, h), gfxASurface::ImageFormatARGB32);
nsRefPtr<gfxContext> ctx = new gfxContext(surf);
rv = canvas->RenderContexts(ctx, gfxPattern::FILTER_NEAREST);
if (NS_FAILED(rv))
return rv;
sourceSurface = surf;
}
*aSurface = sourceSurface.forget().get();
*widthOut = w;
*heightOut = h;
NS_ADDREF(*prinOut = node->NodePrincipal());
*forceWriteOnlyOut = canvas->IsWriteOnly();
return NS_OK;
}
#ifdef MOZ_MEDIA
/* Maybe it's <video>? */
nsCOMPtr<nsIDOMHTMLVideoElement> ve = do_QueryInterface(imgElt);
if (node && ve) {
nsHTMLVideoElement *video = static_cast<nsHTMLVideoElement*>(ve.get());
/* If it doesn't have a principal, just bail */
nsCOMPtr<nsIPrincipal> principal = video->GetCurrentPrincipal();
if (!principal)
return NS_ERROR_DOM_SECURITY_ERR;
PRUint32 videoWidth, videoHeight;
rv = video->GetVideoWidth(&videoWidth);
rv |= video->GetVideoHeight(&videoHeight);
if (NS_FAILED(rv))
return NS_ERROR_NOT_AVAILABLE;
nsRefPtr<gfxASurface> surf =
gfxPlatform::GetPlatform()->CreateOffscreenSurface
(gfxIntSize(videoWidth, videoHeight), gfxASurface::ImageFormatARGB32);
nsRefPtr<gfxContext> ctx = new gfxContext(surf);
ctx->SetOperator(gfxContext::OPERATOR_SOURCE);
video->Paint(ctx, gfxPattern::FILTER_NEAREST, gfxRect(0, 0, videoWidth, videoHeight));
*aSurface = surf.forget().get();
*widthOut = videoWidth;
*heightOut = videoHeight;
*prinOut = principal.forget().get();
*forceWriteOnlyOut = PR_FALSE;
return NS_OK;
}
#endif
/* Finally, check if it's a normal image */
nsCOMPtr<imgIContainer> imgContainer;
nsCOMPtr<nsIImageLoadingContent> imageLoader = do_QueryInterface(imgElt);
if (!imageLoader)
return NS_ERROR_NOT_AVAILABLE;
nsCOMPtr<imgIRequest> imgRequest;
rv = imageLoader->GetRequest(nsIImageLoadingContent::CURRENT_REQUEST,
getter_AddRefs(imgRequest));
NS_ENSURE_SUCCESS(rv, rv);
if (!imgRequest)
// XXX ERRMSG we need to report an error to developers here! (bug 329026)
return NS_ERROR_NOT_AVAILABLE;
PRUint32 status;
imgRequest->GetImageStatus(&status);
if ((status & imgIRequest::STATUS_LOAD_COMPLETE) == 0)
return NS_ERROR_NOT_AVAILABLE;
// In case of data: URIs, we want to ignore principals;
// they should have the originating content's principal,
// but that's broken at the moment in imgLib.
nsCOMPtr<nsIURI> uri;
rv = imgRequest->GetURI(getter_AddRefs(uri));
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_SECURITY_ERR);
PRBool isDataURI = PR_FALSE;
rv = uri->SchemeIs("data", &isDataURI);
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_SECURITY_ERR);
// Data URIs are always OK; set the principal
// to null to indicate that.
if (isDataURI) {
*prinOut = nsnull;
} else {
rv = imgRequest->GetImagePrincipal(prinOut);
NS_ENSURE_SUCCESS(rv, rv);
NS_ENSURE_TRUE(*prinOut, NS_ERROR_DOM_SECURITY_ERR);
}
*forceWriteOnlyOut = PR_FALSE;
rv = imgRequest->GetImage(getter_AddRefs(imgContainer));
NS_ENSURE_SUCCESS(rv, rv);
if (!imgContainer)
return NS_ERROR_NOT_AVAILABLE;
nsCOMPtr<gfxIImageFrame> frame;
rv = imgContainer->GetCurrentFrame(getter_AddRefs(frame));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIImage> img(do_GetInterface(frame));
PRInt32 imgWidth, imgHeight;
rv = frame->GetWidth(&imgWidth);
rv |= frame->GetHeight(&imgHeight);
if (NS_FAILED(rv))
return NS_ERROR_FAILURE;
if (widthOut)
*widthOut = imgWidth;
if (heightOut)
*heightOut = imgHeight;
nsRefPtr<gfxPattern> gfxpattern;
img->GetPattern(getter_AddRefs(gfxpattern));
nsRefPtr<gfxASurface> gfxsurf = gfxpattern->GetSurface();
if (!gfxsurf) {
gfxsurf = new gfxImageSurface (gfxIntSize(imgWidth, imgHeight), gfxASurface::ImageFormatARGB32);
nsRefPtr<gfxContext> ctx = new gfxContext(gfxsurf);
ctx->SetOperator(gfxContext::OPERATOR_SOURCE);
ctx->SetPattern(gfxpattern);
ctx->Paint();
}
*aSurface = gfxsurf.forget().get();
return NS_OK;
}
/* Check that the rect [x,y,w,h] is a valid subrect of [0,0,realWidth,realHeight]
* without overflowing any integers and the like.
*/
@ -3566,7 +3369,6 @@ nsCanvasRenderingContext2D::DrawWindow(nsIDOMWindow* aWindow, float aX, float aY
// we're drawing; aX and aY are drawn to 0,0 in current user
// space.
gfxRect damageRect = mThebes->UserToDevice(gfxRect(0, 0, aW, aH));
damageRect.RoundOut();
Redraw(damageRect);
@ -3614,7 +3416,7 @@ nsCanvasRenderingContext2D::GetImageData()
if (!JS_ConvertArguments (ctx, argc, argv, "jjjj", &x, &y, &w, &h))
return NS_ERROR_DOM_SYNTAX_ERR;
if (!CheckSaneSubrectSize (x, y, w, h, mWidth, mHeight))
if (!CanvasUtils::CheckSaneSubrectSize (x, y, w, h, mWidth, mHeight))
return NS_ERROR_DOM_SYNTAX_ERR;
nsAutoArrayPtr<PRUint8> surfaceData (new (std::nothrow) PRUint8[w * h * 4]);
@ -3802,7 +3604,7 @@ nsCanvasRenderingContext2D::PutImageData()
return NS_ERROR_DOM_SYNTAX_ERR;
dataArray = JSVAL_TO_OBJECT(v);
if (!CheckSaneSubrectSize (x, y, w, h, mWidth, mHeight))
if (!CanvasUtils::CheckSaneSubrectSize (x, y, w, h, mWidth, mHeight))
return NS_ERROR_DOM_SYNTAX_ERR;
jsuint arrayLen;
@ -3908,6 +3710,9 @@ nsCanvasRenderingContext2D::PutImageData()
gfxContextPathAutoSaveRestore pathSR(mThebes);
gfxContextAutoSaveRestore autoSR(mThebes);
// ignore clipping region, as per spec
mThebes->ResetClip();
mThebes->IdentityMatrix();
mThebes->Translate(gfxPoint(x, y));
mThebes->NewPath();
@ -3969,7 +3774,7 @@ nsCanvasRenderingContext2D::CreateImageData()
// check for overflow when calculating len
PRUint32 len0 = w * h;
if (len0 / w != h)
if (len0 / w != (PRUint32) h)
return NS_ERROR_DOM_INDEX_SIZE_ERR;
PRUint32 len = len0 * 4;
if (len / 4 != len0)

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

@ -48,7 +48,7 @@ ctx.rect(0, 0, 50, 50);
ctx.clip();
ctx.putImageData(imgdata, 0, 0);
isPixel(ctx, 25,25, 0,255,0,255, "25,25", "0,255,0,255", 2);
todo_isPixel(ctx, 75,25, 0,255,0,255, "75,25", "0,255,0,255", 2);
isPixel(ctx, 75,25, 0,255,0,255, "75,25", "0,255,0,255", 2);
SimpleTest.finish();

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

@ -46,13 +46,14 @@ class nsPresContext;
* Event listener manager interface.
*/
#define NS_IPRIVATEDOMEVENT_IID \
{0x5b3543d3, 0x84ed, 0x4b59, \
{0x95, 0xca, 0xa4, 0x21, 0xf2, 0x59, 0x22, 0x22}}
{ 0x1da4c501, 0xe87e, 0x49b4, \
{ 0xb0, 0x49, 0xdf, 0x9f, 0xc3, 0x6b, 0x56, 0xd4 } }
class nsIDOMEventTarget;
class nsIDOMEvent;
class nsEvent;
class nsCommandEvent;
class nsRegion;
class nsIPrivateDOMEvent : public nsISupports
{
@ -61,11 +62,8 @@ public:
NS_IMETHOD DuplicatePrivateData() = 0;
NS_IMETHOD SetTarget(nsIDOMEventTarget* aTarget) = 0;
NS_IMETHOD SetCurrentTarget(nsIDOMEventTarget* aTarget) = 0;
NS_IMETHOD SetOriginalTarget(nsIDOMEventTarget* aTarget) = 0;
NS_IMETHOD_(PRBool) IsDispatchStopped() = 0;
NS_IMETHOD_(nsEvent*) GetInternalNSEvent() = 0;
NS_IMETHOD_(PRBool) HasOriginalTarget() = 0;
NS_IMETHOD SetTrusted(PRBool aTrusted) = 0;
};
@ -92,9 +90,9 @@ NS_NewDOMPopupBlockedEvent(nsIDOMEvent** aResult, nsPresContext* aPresContext, n
nsresult
NS_NewDOMTextEvent(nsIDOMEvent** aResult, nsPresContext* aPresContext, class nsTextEvent* aEvent);
nsresult
NS_NewDOMBeforeUnloadEvent(nsIDOMEvent** aResult, nsPresContext* aPresContext, class nsBeforePageUnloadEvent* aEvent);
NS_NewDOMBeforeUnloadEvent(nsIDOMEvent** aResult, nsPresContext* aPresContext, nsEvent* aEvent);
nsresult
NS_NewDOMPageTransitionEvent(nsIDOMEvent** aResult, nsPresContext* aPresContext, class nsPageTransitionEvent* aEvent);
NS_NewDOMPageTransitionEvent(nsIDOMEvent** aResult, nsPresContext* aPresContext, nsEvent* aEvent);
#ifdef MOZ_SVG
nsresult
NS_NewDOMSVGEvent(nsIDOMEvent** aResult, nsPresContext* aPresContext, class nsEvent* aEvent);
@ -110,7 +108,11 @@ NS_NewDOMMessageEvent(nsIDOMEvent** aInstancePtrResult, nsPresContext* aPresCont
nsresult
NS_NewDOMProgressEvent(nsIDOMEvent** aInstancePtrResult, nsPresContext* aPresContext, class nsEvent* aEvent);
nsresult
NS_NewDOMNotifyPaintEvent(nsIDOMEvent** aResult, nsPresContext* aPresContext, class nsNotifyPaintEvent* aEvent);
NS_NewDOMNotifyPaintEvent(nsIDOMEvent** aResult, nsPresContext* aPresContext,
nsEvent* aEvent,
PRUint32 aEventType = 0,
const nsRegion* aSameOriginRegion = nsnull,
const nsRegion* aCrossDocRegion = nsnull);
nsresult
NS_NewDOMSimpleGestureEvent(nsIDOMEvent** aInstancePtrResult, nsPresContext* aPresContext, class nsSimpleGestureEvent* aEvent);
#endif // nsIPrivateDOMEvent_h__

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

@ -50,10 +50,10 @@ class nsIDOMEventListener;
class nsIDOMEventGroup;
class nsIScriptContext;
// 25982813-af2e-4ab6-b512-e6c6ada6d0ec
// e6579895-a23c-4afc-872a-d53da71def5d
#define NS_PIDOMEVENTTARGET_IID \
{ 0x358f2990, 0x5107, 0x49ba, \
{ 0x88, 0x94, 0x14, 0x34, 0x86, 0xd5, 0x99, 0x85 } }
{ 0xe6579895, 0xa23c, 0x4afc, \
{ 0x87, 0x2a, 0xd5, 0x3d, 0xa7, 0x1d, 0xef, 0x5d } }
class nsPIDOMEventTarget : public nsISupports
{
@ -137,12 +137,10 @@ public:
/**
* Get the event listener manager, the guy you talk to to register for events
* on this node.
* @param aCreateIfNotFound If PR_FALSE, returns a listener manager only if
* one already exists. [IN]
* @param aResult The event listener manager [OUT]
* @param aMayCreate If PR_FALSE, returns a listener manager only if
* one already exists.
*/
virtual nsresult GetListenerManager(PRBool aCreateIfNotFound,
nsIEventListenerManager** aResult) = 0;
virtual nsIEventListenerManager* GetListenerManager(PRBool aMayCreate) = 0;
/**
* Add an event listener for nsIID.

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

@ -39,33 +39,6 @@
#include "nsDOMBeforeUnloadEvent.h"
#include "nsContentUtils.h"
nsDOMBeforeUnloadEvent::nsDOMBeforeUnloadEvent(nsPresContext* aPresContext,
nsBeforePageUnloadEvent* aEvent)
: nsDOMEvent(aPresContext, aEvent ? aEvent :
new nsBeforePageUnloadEvent(PR_FALSE,
NS_BEFORE_PAGE_UNLOAD_EVENT))
{
NS_ASSERTION(mEvent->eventStructType == NS_BEFORE_PAGE_UNLOAD_EVENT,
"event type mismatch");
if (aEvent) {
mEventIsInternal = PR_FALSE;
}
else {
mEventIsInternal = PR_TRUE;
mEvent->time = PR_Now();
}
}
nsDOMBeforeUnloadEvent::~nsDOMBeforeUnloadEvent()
{
if (mEventIsInternal &&
mEvent->eventStructType == NS_BEFORE_PAGE_UNLOAD_EVENT) {
delete static_cast<nsBeforePageUnloadEvent*>(mEvent);
mEvent = nsnull;
}
}
NS_IMPL_ADDREF_INHERITED(nsDOMBeforeUnloadEvent, nsDOMEvent)
NS_IMPL_RELEASE_INHERITED(nsDOMBeforeUnloadEvent, nsDOMEvent)
@ -77,22 +50,20 @@ NS_INTERFACE_MAP_END_INHERITING(nsDOMEvent)
NS_IMETHODIMP
nsDOMBeforeUnloadEvent::SetReturnValue(const nsAString& aReturnValue)
{
((nsBeforePageUnloadEvent *)mEvent)->text = aReturnValue;
mText = aReturnValue;
return NS_OK; // Don't throw an exception
}
NS_IMETHODIMP
nsDOMBeforeUnloadEvent::GetReturnValue(nsAString& aReturnValue)
{
aReturnValue = ((nsBeforePageUnloadEvent *)mEvent)->text;
aReturnValue = mText;
return NS_OK; // Don't throw an exception
}
nsresult NS_NewDOMBeforeUnloadEvent(nsIDOMEvent** aInstancePtrResult,
nsPresContext* aPresContext,
nsBeforePageUnloadEvent *aEvent)
nsEvent *aEvent)
{
nsDOMBeforeUnloadEvent* it =
new nsDOMBeforeUnloadEvent(aPresContext, aEvent);

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

@ -46,9 +46,8 @@ class nsDOMBeforeUnloadEvent : public nsIDOMBeforeUnloadEvent,
public nsDOMEvent
{
public:
nsDOMBeforeUnloadEvent(nsPresContext* aPresContext,
nsBeforePageUnloadEvent* aEvent);
virtual ~nsDOMBeforeUnloadEvent();
nsDOMBeforeUnloadEvent(nsPresContext* aPresContext, nsEvent* aEvent)
: nsDOMEvent(aPresContext, aEvent) {}
NS_DECL_ISUPPORTS_INHERITED
@ -57,6 +56,8 @@ public:
// nsIDOMBeforeUnloadEvent Interface
NS_DECL_NSIDOMBEFOREUNLOADEVENT
protected:
nsString mText;
};
#endif // nsDOMBeforeUnloadEvent_h__

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

@ -74,6 +74,7 @@ public:
friend class nsDOMDragEvent;
friend class nsEventStateManager;
friend class nsContentUtils;
protected:

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

@ -118,6 +118,10 @@ nsDOMDragEvent::InitDragEventNS(const nsAString & aNamespaceURIArg,
NS_IMETHODIMP
nsDOMDragEvent::GetDataTransfer(nsIDOMDataTransfer** aDataTransfer)
{
// the dataTransfer field of the event caches the DataTransfer associated
// with the drag. It is initialized when an attempt is made to retrieve it
// rather that when the event is created to avoid duplicating the data when
// no listener ever uses it.
*aDataTransfer = nsnull;
if (!mEvent || mEvent->eventStructType != NS_DRAG_EVENT) {
@ -125,125 +129,17 @@ nsDOMDragEvent::GetDataTransfer(nsIDOMDataTransfer** aDataTransfer)
return NS_OK;
}
// the dataTransfer field of the event caches the DataTransfer associated
// with the drag. It is initialized when an attempt is made to retrieve it
// rather that when the event is created to avoid duplicating the data when
// no listener ever uses it.
nsDragEvent* dragEvent = static_cast<nsDragEvent*>(mEvent);
if (dragEvent->dataTransfer) {
CallQueryInterface(dragEvent->dataTransfer, aDataTransfer);
return NS_OK;
}
// for synthetic events, just use the supplied data transfer object
if (mEventIsInternal) {
NS_IF_ADDREF(*aDataTransfer = dragEvent->dataTransfer);
return NS_OK;
}
// For draggesture and dragstart events, the data transfer object is
// created before the event fires, so it should already be set. For other
// drag events, get the object from the drag session.
NS_ASSERTION(mEvent->message != NS_DRAGDROP_GESTURE &&
mEvent->message != NS_DRAGDROP_START,
"draggesture event created without a dataTransfer");
nsCOMPtr<nsIDragSession> dragSession = nsContentUtils::GetDragSession();
NS_ENSURE_TRUE(dragSession, NS_OK); // no drag in progress
nsCOMPtr<nsIDOMDataTransfer> initialDataTransfer;
dragSession->GetDataTransfer(getter_AddRefs(initialDataTransfer));
if (!initialDataTransfer) {
// A dataTransfer won't exist when a drag was started by some other
// means, for instance calling the drag service directly, or a drag
// from another application. In either case, a new dataTransfer should
// be created that reflects the data. Pass true to the constructor for
// the aIsExternal argument, so that only system access is allowed.
PRUint32 action = 0;
dragSession->GetDragAction(&action);
initialDataTransfer =
new nsDOMDataTransfer(mEvent->message, action);
NS_ENSURE_TRUE(initialDataTransfer, NS_ERROR_OUT_OF_MEMORY);
// now set it in the drag session so we don't need to create it again
dragSession->SetDataTransfer(initialDataTransfer);
}
// each event should use a clone of the original dataTransfer.
nsCOMPtr<nsIDOMNSDataTransfer> initialDataTransferNS =
do_QueryInterface(initialDataTransfer);
NS_ENSURE_TRUE(initialDataTransferNS, NS_ERROR_FAILURE);
initialDataTransferNS->Clone(mEvent->message, dragEvent->userCancelled,
getter_AddRefs(dragEvent->dataTransfer));
NS_ENSURE_TRUE(dragEvent->dataTransfer, NS_ERROR_OUT_OF_MEMORY);
// for the dragenter and dragover events, initialize the drop effect
// from the drop action, which platform specific widget code sets before
// the event is fired based on the keyboard state.
if (mEvent->message == NS_DRAGDROP_ENTER ||
mEvent->message == NS_DRAGDROP_OVER) {
nsCOMPtr<nsIDOMNSDataTransfer> newDataTransfer =
do_QueryInterface(dragEvent->dataTransfer);
NS_ENSURE_TRUE(newDataTransfer, NS_ERROR_FAILURE);
PRUint32 action, effectAllowed;
dragSession->GetDragAction(&action);
newDataTransfer->GetEffectAllowedInt(&effectAllowed);
newDataTransfer->SetDropEffectInt(FilterDropEffect(action, effectAllowed));
}
else if (mEvent->message == NS_DRAGDROP_DROP ||
mEvent->message == NS_DRAGDROP_DRAGDROP ||
mEvent->message == NS_DRAGDROP_END) {
// For the drop and dragend events, set the drop effect based on the
// last value that the dropEffect had. This will have been set in
// nsEventStateManager::PostHandleEvent for the last dragenter or
// dragover event.
nsCOMPtr<nsIDOMNSDataTransfer> newDataTransfer =
do_QueryInterface(dragEvent->dataTransfer);
NS_ENSURE_TRUE(newDataTransfer, NS_ERROR_FAILURE);
PRUint32 dropEffect;
initialDataTransferNS->GetDropEffectInt(&dropEffect);
newDataTransfer->SetDropEffectInt(dropEffect);
// for synthetic events, just use the supplied data transfer object even if null
if (!mEventIsInternal) {
nsresult rv = nsContentUtils::SetDataTransferInEvent(dragEvent);
NS_ENSURE_SUCCESS(rv, rv);
}
NS_IF_ADDREF(*aDataTransfer = dragEvent->dataTransfer);
return NS_OK;
}
// static
PRUint32
nsDOMDragEvent::FilterDropEffect(PRUint32 aAction, PRUint32 aEffectAllowed)
{
// It is possible for the drag action to include more than one action, but
// the widget code which sets the action from the keyboard state should only
// be including one. If multiple actions were set, we just consider them in
// the following order:
// copy, link, move
if (aAction & nsIDragService::DRAGDROP_ACTION_COPY)
aAction = nsIDragService::DRAGDROP_ACTION_COPY;
else if (aAction & nsIDragService::DRAGDROP_ACTION_LINK)
aAction = nsIDragService::DRAGDROP_ACTION_LINK;
else if (aAction & nsIDragService::DRAGDROP_ACTION_MOVE)
aAction = nsIDragService::DRAGDROP_ACTION_MOVE;
// Filter the action based on the effectAllowed. If the effectAllowed
// doesn't include the action, then that action cannot be done, so adjust
// the action to something that is allowed. For a copy, adjust to move or
// link. For a move, adjust to copy or link. For a link, adjust to move or
// link. Otherwise, use none.
if (aAction & aEffectAllowed ||
aEffectAllowed == nsIDragService::DRAGDROP_ACTION_UNINITIALIZED)
return aAction;
if (aEffectAllowed & nsIDragService::DRAGDROP_ACTION_MOVE)
return nsIDragService::DRAGDROP_ACTION_MOVE;
if (aEffectAllowed & nsIDragService::DRAGDROP_ACTION_COPY)
return nsIDragService::DRAGDROP_ACTION_COPY;
if (aEffectAllowed & nsIDragService::DRAGDROP_ACTION_LINK)
return nsIDragService::DRAGDROP_ACTION_LINK;
return nsIDragService::DRAGDROP_ACTION_NONE;
}
nsresult NS_NewDOMDragEvent(nsIDOMEvent** aInstancePtrResult,
nsPresContext* aPresContext,
nsDragEvent *aEvent)

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

@ -57,9 +57,6 @@ public:
NS_DECL_NSIDOMDRAGEVENT
NS_FORWARD_TO_NSDOMMOUSEEVENT
// filters the action to fit within the effects allowed and returns it.
static PRUint32 FilterDropEffect(PRUint32 aAction, PRUint32 aEffectAllowed);
};
nsresult NS_NewDOMDragEvent(nsIDOMEvent** aInstancePtrResult,

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

@ -342,12 +342,6 @@ nsDOMEvent::GetOriginalTarget(nsIDOMEventTarget** aOriginalTarget)
return GetTarget(aOriginalTarget);
}
NS_IMETHODIMP_(PRBool)
nsDOMEvent::HasOriginalTarget()
{
return !!mEvent->originalTarget;
}
NS_IMETHODIMP
nsDOMEvent::SetTrusted(PRBool aTrusted)
{
@ -532,6 +526,8 @@ nsDOMEvent::SetEventType(const nsAString& aEventTypeArg)
else if (atom == nsGkAtoms::oncompositionend)
mEvent->message = NS_COMPOSITION_END;
} else if (mEvent->eventStructType == NS_EVENT) {
if (atom == nsGkAtoms::onMozAfterPaint)
mEvent->message = NS_AFTERPAINT;
if (atom == nsGkAtoms::onfocus)
mEvent->message = NS_FOCUS_CONTENT;
else if (atom == nsGkAtoms::onblur)
@ -548,6 +544,8 @@ nsDOMEvent::SetEventType(const nsAString& aEventTypeArg)
mEvent->message = NS_LOAD;
else if (atom == nsGkAtoms::onunload)
mEvent->message = NS_PAGE_UNLOAD;
else if (atom == nsGkAtoms::onbeforeunload)
mEvent->message = NS_BEFORE_PAGE_UNLOAD;
else if (atom == nsGkAtoms::onabort)
mEvent->message = NS_IMAGE_ABORT;
else if (atom == nsGkAtoms::onerror)
@ -562,6 +560,10 @@ nsDOMEvent::SetEventType(const nsAString& aEventTypeArg)
mEvent->message = NS_CUT;
else if (atom == nsGkAtoms::onpaste)
mEvent->message = NS_PASTE;
else if (atom == nsGkAtoms::onpageshow)
mEvent->message = NS_PAGE_SHOW;
else if (atom == nsGkAtoms::onpagehide)
mEvent->message = NS_PAGE_HIDE;
} else if (mEvent->eventStructType == NS_MUTATION_EVENT) {
if (atom == nsGkAtoms::onDOMAttrModified)
mEvent->message = NS_MUTATION_ATTRMODIFIED;
@ -586,11 +588,6 @@ nsDOMEvent::SetEventType(const nsAString& aEventTypeArg)
mEvent->message = NS_UI_FOCUSOUT;
else if (atom == nsGkAtoms::oninput)
mEvent->message = NS_FORM_INPUT;
} else if (mEvent->eventStructType == NS_PAGETRANSITION_EVENT) {
if (atom == nsGkAtoms::onpageshow)
mEvent->message = NS_PAGE_SHOW;
else if (atom == nsGkAtoms::onpagehide)
mEvent->message = NS_PAGE_HIDE;
} else if (mEvent->eventStructType == NS_XUL_COMMAND_EVENT) {
if (atom == nsGkAtoms::oncommand)
mEvent->message = NS_XUL_COMMAND;
@ -665,10 +662,6 @@ nsDOMEvent::SetEventType(const nsAString& aEventTypeArg)
mEvent->message = NS_MEDIA_ERROR;
}
#endif // MOZ_MEDIA
else if (mEvent->eventStructType == NS_NOTIFYPAINT_EVENT) {
if (atom == nsGkAtoms::onMozAfterPaint)
mEvent->message = NS_AFTERPAINT;
}
else if (mEvent->eventStructType == NS_SIMPLE_GESTURE_EVENT) {
if (atom == nsGkAtoms::onMozSwipeGesture)
mEvent->message = NS_SIMPLE_GESTURE_SWIPE;
@ -943,27 +936,12 @@ NS_METHOD nsDOMEvent::DuplicatePrivateData()
NS_ENSURE_TRUE(newEvent, NS_ERROR_OUT_OF_MEMORY);
break;
}
case NS_BEFORE_PAGE_UNLOAD_EVENT:
{
newEvent = new nsBeforePageUnloadEvent(PR_FALSE, msg);
NS_ENSURE_TRUE(newEvent, NS_ERROR_OUT_OF_MEMORY);
static_cast<nsBeforePageUnloadEvent*>(newEvent)->text =
static_cast<nsBeforePageUnloadEvent*>(mEvent)->text;
break;
}
case NS_UI_EVENT:
{
newEvent = new nsUIEvent(PR_FALSE, msg,
static_cast<nsUIEvent*>(mEvent)->detail);
break;
}
case NS_PAGETRANSITION_EVENT:
{
newEvent =
new nsPageTransitionEvent(PR_FALSE, msg,
((nsPageTransitionEvent*) mEvent)->persisted);
break;
}
#ifdef MOZ_SVG
case NS_SVG_EVENT:
{
@ -990,14 +968,6 @@ NS_METHOD nsDOMEvent::DuplicatePrivateData()
static_cast<nsXULCommandEvent*>(mEvent)->sourceEvent;
break;
}
case NS_NOTIFYPAINT_EVENT:
{
nsNotifyPaintEvent* event = static_cast<nsNotifyPaintEvent*>(mEvent);
newEvent =
new nsNotifyPaintEvent(PR_FALSE, msg,
event->sameDocRegion, event->crossDocRegion);
break;
}
case NS_SIMPLE_GESTURE_EVENT:
{
nsSimpleGestureEvent* oldSimpleGestureEvent = static_cast<nsSimpleGestureEvent*>(mEvent);
@ -1059,36 +1029,6 @@ NS_METHOD nsDOMEvent::SetTarget(nsIDOMEventTarget* aTarget)
return NS_OK;
}
NS_METHOD nsDOMEvent::SetCurrentTarget(nsIDOMEventTarget* aCurrentTarget)
{
#ifdef DEBUG
{
nsCOMPtr<nsPIDOMWindow> win = do_QueryInterface(aCurrentTarget);
NS_ASSERTION(!win || !win->IsInnerWindow(),
"Uh, inner window set as event target!");
}
#endif
mEvent->currentTarget = aCurrentTarget;
return NS_OK;
}
NS_METHOD nsDOMEvent::SetOriginalTarget(nsIDOMEventTarget* aOriginalTarget)
{
#ifdef DEBUG
{
nsCOMPtr<nsPIDOMWindow> win = do_QueryInterface(aOriginalTarget);
NS_ASSERTION(!win || !win->IsInnerWindow(),
"Uh, inner window set as event target!");
}
#endif
mEvent->originalTarget = aOriginalTarget;
return NS_OK;
}
NS_IMETHODIMP_(PRBool)
nsDOMEvent::IsDispatchStopped()
{
@ -1557,6 +1497,14 @@ nsDOMEvent::ReportWrongPropertyAccessWarning(const char* aPropertyName)
"DOM Events");
}
NS_IMETHODIMP
nsDOMEvent::GetPreventDefault(PRBool* aReturn)
{
NS_ENSURE_ARG_POINTER(aReturn);
*aReturn = mEvent && (mEvent->flags & NS_EVENT_FLAG_NO_DEFAULT);
return NS_OK;
}
nsresult NS_NewDOMEvent(nsIDOMEvent** aInstancePtrResult,
nsPresContext* aPresContext,
nsEvent *aEvent)

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

@ -188,11 +188,8 @@ public:
// nsIPrivateDOMEvent interface
NS_IMETHOD DuplicatePrivateData();
NS_IMETHOD SetTarget(nsIDOMEventTarget* aTarget);
NS_IMETHOD SetCurrentTarget(nsIDOMEventTarget* aCurrentTarget);
NS_IMETHOD SetOriginalTarget(nsIDOMEventTarget* aOriginalTarget);
NS_IMETHOD_(PRBool) IsDispatchStopped();
NS_IMETHOD_(nsEvent*) GetInternalNSEvent();
NS_IMETHOD_(PRBool) HasOriginalTarget();
NS_IMETHOD SetTrusted(PRBool aTrusted);
static PopupControlState GetEventPopupControlState(nsEvent *aEvent);

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

@ -111,8 +111,7 @@ nsDOMEventTargetHelper::RemoveEventListener(const nsAString& aType,
nsIDOMEventListener* aListener,
PRBool aUseCapture)
{
nsCOMPtr<nsIEventListenerManager> elm;
GetListenerManager(PR_FALSE, getter_AddRefs(elm));
nsIEventListenerManager* elm = GetListenerManager(PR_FALSE);
if (elm) {
PRInt32 flags = aUseCapture ? NS_EVENT_FLAG_CAPTURE : NS_EVENT_FLAG_BUBBLE;
elm->RemoveEventListenerByType(aListener, aType, flags, nsnull);
@ -127,8 +126,7 @@ nsDOMEventTargetHelper::AddEventListener(const nsAString& aType,
PRBool aUseCapture,
PRBool aWantsUntrusted)
{
nsCOMPtr<nsIEventListenerManager> elm;
GetListenerManager(PR_TRUE, getter_AddRefs(elm));
nsIEventListenerManager* elm = GetListenerManager(PR_TRUE);
NS_ENSURE_STATE(elm);
PRInt32 flags = aUseCapture ? NS_EVENT_FLAG_CAPTURE : NS_EVENT_FLAG_BUBBLE;
if (aWantsUntrusted) {
@ -220,57 +218,46 @@ nsDOMEventTargetHelper::DispatchDOMEvent(nsEvent* aEvent,
aEventStatus);
}
nsresult
nsDOMEventTargetHelper::GetListenerManager(PRBool aCreateIfNotFound,
nsIEventListenerManager** aResult)
nsIEventListenerManager*
nsDOMEventTargetHelper::GetListenerManager(PRBool aCreateIfNotFound)
{
if (!mListenerManager) {
if (!aCreateIfNotFound) {
*aResult = nsnull;
return NS_OK;
return nsnull;
}
nsresult rv = NS_NewEventListenerManager(getter_AddRefs(mListenerManager));
NS_ENSURE_SUCCESS(rv, rv);
NS_ENSURE_SUCCESS(rv, nsnull);
mListenerManager->SetListenerTarget(static_cast<nsPIDOMEventTarget*>(this));
}
NS_ADDREF(*aResult = mListenerManager);
return NS_OK;
return mListenerManager;
}
nsresult
nsDOMEventTargetHelper::AddEventListenerByIID(nsIDOMEventListener *aListener,
const nsIID& aIID)
{
nsCOMPtr<nsIEventListenerManager> elm;
GetListenerManager(PR_TRUE, getter_AddRefs(elm));
if (elm) {
elm->AddEventListenerByIID(aListener, aIID, NS_EVENT_FLAG_BUBBLE);
}
return NS_OK;
nsIEventListenerManager* elm = GetListenerManager(PR_TRUE);
NS_ENSURE_STATE(elm);
return elm->AddEventListenerByIID(aListener, aIID, NS_EVENT_FLAG_BUBBLE);
}
nsresult
nsDOMEventTargetHelper::RemoveEventListenerByIID(nsIDOMEventListener *aListener,
const nsIID& aIID)
{
nsCOMPtr<nsIEventListenerManager> elm;
GetListenerManager(PR_FALSE, getter_AddRefs(elm));
if (elm) {
return elm->RemoveEventListenerByIID(aListener, aIID, NS_EVENT_FLAG_BUBBLE);
}
return NS_OK;
nsIEventListenerManager* elm = GetListenerManager(PR_FALSE);
return elm ?
elm->RemoveEventListenerByIID(aListener, aIID, NS_EVENT_FLAG_BUBBLE) :
NS_OK;
}
nsresult
nsDOMEventTargetHelper::GetSystemEventGroup(nsIDOMEventGroup** aGroup)
{
nsCOMPtr<nsIEventListenerManager> elm;
nsresult rv = GetListenerManager(PR_TRUE, getter_AddRefs(elm));
if (elm) {
return elm->GetSystemEventGroupLM(aGroup);
}
return rv;
nsIEventListenerManager* elm = GetListenerManager(PR_TRUE);
NS_ENSURE_STATE(elm);
return elm->GetSystemEventGroupLM(aGroup);
}
nsIScriptContext*

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

@ -85,8 +85,7 @@ public:
virtual nsresult DispatchDOMEvent(nsEvent* aEvent, nsIDOMEvent* aDOMEvent,
nsPresContext* aPresContext,
nsEventStatus* aEventStatus);
virtual nsresult GetListenerManager(PRBool aCreateIfNotFound,
nsIEventListenerManager** aResult);
virtual nsIEventListenerManager* GetListenerManager(PRBool aCreateIfNotFound);
virtual nsresult AddEventListenerByIID(nsIDOMEventListener *aListener,
const nsIID& aIID);
virtual nsresult RemoveEventListenerByIID(nsIDOMEventListener *aListener,

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

@ -41,27 +41,20 @@
#include "nsClientRect.h"
nsDOMNotifyPaintEvent::nsDOMNotifyPaintEvent(nsPresContext* aPresContext,
nsNotifyPaintEvent* aEvent)
: nsDOMEvent(aPresContext, aEvent ? aEvent :
new nsNotifyPaintEvent(PR_FALSE, 0, nsRegion(), nsRegion()))
{
if (aEvent) {
mEventIsInternal = PR_FALSE;
}
else
{
mEventIsInternal = PR_TRUE;
mEvent->time = PR_Now();
}
}
nsDOMNotifyPaintEvent::~nsDOMNotifyPaintEvent()
nsEvent* aEvent,
PRUint32 aEventType,
const nsRegion* aSameDocRegion,
const nsRegion* aCrossDocRegion)
: nsDOMEvent(aPresContext, aEvent)
{
if (mEventIsInternal) {
if (mEvent->eventStructType == NS_NOTIFYPAINT_EVENT) {
delete static_cast<nsNotifyPaintEvent*>(mEvent);
mEvent = nsnull;
}
if (mEvent) {
mEvent->message = aEventType;
}
if (aSameDocRegion) {
mSameDocRegion = *aSameDocRegion;
}
if (aCrossDocRegion) {
mCrossDocRegion = *aCrossDocRegion;
}
}
@ -76,13 +69,11 @@ NS_IMPL_RELEASE_INHERITED(nsDOMNotifyPaintEvent, nsDOMEvent)
nsRegion
nsDOMNotifyPaintEvent::GetRegion()
{
nsNotifyPaintEvent* event = static_cast<nsNotifyPaintEvent*>(mEvent);
nsRegion r;
if (nsContentUtils::IsCallerTrustedForRead()) {
r.Or(event->sameDocRegion, event->crossDocRegion);
r.Or(mSameDocRegion, mCrossDocRegion);
} else {
r = event->sameDocRegion;
r = mSameDocRegion;
}
return r;
}
@ -127,10 +118,14 @@ nsDOMNotifyPaintEvent::GetClientRects(nsIDOMClientRectList** aResult)
nsresult NS_NewDOMNotifyPaintEvent(nsIDOMEvent** aInstancePtrResult,
nsPresContext* aPresContext,
nsNotifyPaintEvent *aEvent)
nsEvent *aEvent,
PRUint32 aEventType,
const nsRegion* aSameOriginRegion,
const nsRegion* aCrossDocRegion)
{
nsDOMNotifyPaintEvent* it =
new nsDOMNotifyPaintEvent(aPresContext, aEvent);
new nsDOMNotifyPaintEvent(aPresContext, aEvent, aEventType,
aSameOriginRegion, aCrossDocRegion);
if (nsnull == it) {
return NS_ERROR_OUT_OF_MEMORY;
}

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

@ -46,9 +46,11 @@ class nsDOMNotifyPaintEvent : public nsIDOMNotifyPaintEvent,
public nsDOMEvent
{
public:
nsDOMNotifyPaintEvent(nsPresContext* aPresContext,
nsNotifyPaintEvent* aEvent);
virtual ~nsDOMNotifyPaintEvent();
nsDOMNotifyPaintEvent(nsPresContext* aPresContext,
nsEvent* aEvent,
PRUint32 aEventType,
const nsRegion* aSameOriginRegion,
const nsRegion* aCrossDocRegion);
NS_DECL_ISUPPORTS_INHERITED
@ -59,6 +61,9 @@ public:
private:
nsRegion GetRegion();
nsRegion mSameDocRegion;
nsRegion mCrossDocRegion;
};
#endif // nsDOMNotifyPaintEvent_h_

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

@ -39,21 +39,6 @@
#include "nsDOMPageTransitionEvent.h"
#include "nsContentUtils.h"
nsDOMPageTransitionEvent::nsDOMPageTransitionEvent(nsPresContext* aPresContext,
nsPageTransitionEvent* aEvent)
: nsDOMEvent(aPresContext, aEvent ? aEvent :
new nsPageTransitionEvent(PR_FALSE, 0, PR_FALSE))
{
if ( aEvent ) {
mEventIsInternal = PR_FALSE;
}
else
{
mEventIsInternal = PR_TRUE;
mEvent->time = PR_Now();
}
}
NS_INTERFACE_MAP_BEGIN(nsDOMPageTransitionEvent)
NS_INTERFACE_MAP_ENTRY(nsIDOMPageTransitionEvent)
NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(PageTransitionEvent)
@ -65,7 +50,7 @@ NS_IMPL_RELEASE_INHERITED(nsDOMPageTransitionEvent, nsDOMEvent)
NS_IMETHODIMP
nsDOMPageTransitionEvent::GetPersisted(PRBool* aPersisted)
{
*aPersisted = static_cast<nsPageTransitionEvent*>(mEvent)->persisted;
*aPersisted = mPersisted;
return NS_OK;
}
@ -78,13 +63,13 @@ nsDOMPageTransitionEvent::InitPageTransitionEvent(const nsAString &aTypeArg,
nsresult rv = nsDOMEvent::InitEvent(aTypeArg, aCanBubbleArg, aCancelableArg);
NS_ENSURE_SUCCESS(rv, rv);
static_cast<nsPageTransitionEvent*>(mEvent)->persisted = aPersisted;
mPersisted = aPersisted;
return NS_OK;
}
nsresult NS_NewDOMPageTransitionEvent(nsIDOMEvent** aInstancePtrResult,
nsPresContext* aPresContext,
nsPageTransitionEvent *aEvent)
nsEvent *aEvent)
{
nsDOMPageTransitionEvent* it =
new nsDOMPageTransitionEvent(aPresContext, aEvent);

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

@ -46,15 +46,17 @@ class nsDOMPageTransitionEvent : public nsIDOMPageTransitionEvent,
public nsDOMEvent
{
public:
nsDOMPageTransitionEvent(nsPresContext* aPresContext,
nsPageTransitionEvent* aEvent);
nsDOMPageTransitionEvent(nsPresContext* aPresContext, nsEvent* aEvent) :
nsDOMEvent(aPresContext, aEvent), mPersisted(PR_FALSE) {}
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIDOMPAGETRANSITIONEVENT
// Forward to base class
NS_FORWARD_TO_NSDOMEVENT
protected:
PRBool mPersisted;
};
#endif // nsDOMPageTransitionEvent_h__

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

@ -368,15 +368,6 @@ nsDOMUIEvent::GetIsChar(PRBool* aIsChar)
}
}
NS_IMETHODIMP
nsDOMUIEvent::GetPreventDefault(PRBool* aReturn)
{
NS_ENSURE_ARG_POINTER(aReturn);
*aReturn = mEvent && (mEvent->flags & NS_EVENT_FLAG_NO_DEFAULT);
return NS_OK;
}
NS_METHOD nsDOMUIEvent::GetCompositionReply(nsTextEventReply** aReply)
{
if((mEvent->message == NS_COMPOSITION_START) ||

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

@ -71,6 +71,7 @@ public:
// Forward to nsDOMEvent
NS_FORWARD_TO_NSDOMEVENT
NS_FORWARD_NSIDOMNSEVENT(nsDOMEvent::)
protected:
// Internal helper functions

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

@ -233,7 +233,7 @@ nsEventTargetChainItem::HandleEvent(nsEventChainPostVisitor& aVisitor,
if (!aMayHaveNewListenerManagers) {
return NS_OK;
}
mTarget->GetListenerManager(PR_FALSE, getter_AddRefs(mManager));
mManager = mTarget->GetListenerManager(PR_FALSE);
}
if (mManager) {
NS_ASSERTION(aVisitor.mEvent->currentTarget == nsnull,
@ -325,8 +325,6 @@ nsEventTargetChainItem::HandleEventTargetChain(nsEventChainPostVisitor& aVisitor
if (!(aVisitor.mEvent->flags & NS_EVENT_FLAG_CANT_BUBBLE) || newTarget) {
if ((!(aVisitor.mEvent->flags & NS_EVENT_FLAG_NO_CONTENT_DISPATCH) ||
item->ForceContentDispatch()) &&
(!(aFlags & NS_EVENT_FLAG_SYSTEM_EVENT) ||
aVisitor.mEventStatus != nsEventStatus_eConsumeNoDefault) &&
!(aVisitor.mEvent->flags & NS_EVENT_FLAG_STOP_DISPATCH)) {
item->HandleEvent(aVisitor, aFlags & NS_EVENT_BUBBLE_MASK,
createdELMs != nsEventListenerManager::sCreatedCount);
@ -643,15 +641,6 @@ nsEventDispatcher::CreateEvent(nsPresContext* aPresContext,
case NS_TEXT_EVENT:
return NS_NewDOMTextEvent(aDOMEvent, aPresContext,
static_cast<nsTextEvent*>(aEvent));
case NS_BEFORE_PAGE_UNLOAD_EVENT:
return
NS_NewDOMBeforeUnloadEvent(aDOMEvent, aPresContext,
static_cast<nsBeforePageUnloadEvent*>
(aEvent));
case NS_PAGETRANSITION_EVENT:
return NS_NewDOMPageTransitionEvent(aDOMEvent, aPresContext,
static_cast<nsPageTransitionEvent*>
(aEvent));
#ifdef MOZ_SVG
case NS_SVG_EVENT:
return NS_NewDOMSVGEvent(aDOMEvent, aPresContext,
@ -668,10 +657,6 @@ nsEventDispatcher::CreateEvent(nsPresContext* aPresContext,
case NS_COMMAND_EVENT:
return NS_NewDOMCommandEvent(aDOMEvent, aPresContext,
static_cast<nsCommandEvent*>(aEvent));
case NS_NOTIFYPAINT_EVENT:
return NS_NewDOMNotifyPaintEvent(aDOMEvent, aPresContext,
static_cast<nsNotifyPaintEvent*>
(aEvent));
case NS_SIMPLE_GESTURE_EVENT:
return NS_NewDOMSimpleGestureEvent(aDOMEvent, aPresContext,
static_cast<nsSimpleGestureEvent*>(aEvent));
@ -735,6 +720,10 @@ nsEventDispatcher::CreateEvent(nsPresContext* aPresContext,
return NS_NewDOMNotifyPaintEvent(aDOMEvent, aPresContext, nsnull);
if (aEventType.LowerCaseEqualsLiteral("simplegestureevent"))
return NS_NewDOMSimpleGestureEvent(aDOMEvent, aPresContext, nsnull);
if (aEventType.LowerCaseEqualsLiteral("beforeunloadevent"))
return NS_NewDOMBeforeUnloadEvent(aDOMEvent, aPresContext, nsnull);
if (aEventType.LowerCaseEqualsLiteral("pagetransition"))
return NS_NewDOMPageTransitionEvent(aDOMEvent, aPresContext, nsnull);
return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
}

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

@ -49,15 +49,12 @@
#include "nsIDOMFocusListener.h"
#include "nsIDOMFormListener.h"
#include "nsIDOMLoadListener.h"
#include "nsIDOMDragListener.h"
#include "nsIDOMTextListener.h"
#include "nsIDOMCompositionListener.h"
#include "nsIDOMXULListener.h"
#include "nsIDOMUIListener.h"
#include "nsITextControlFrame.h"
#ifdef MOZ_SVG
#include "nsIDOMSVGListener.h"
#include "nsIDOMSVGZoomListener.h"
#include "nsGkAtoms.h"
#endif // MOZ_SVG
#include "nsIEventStateManager.h"
@ -247,19 +244,6 @@ static const EventDispatchData sLoadEvents[] = {
{ NS_BEFORE_PAGE_UNLOAD, HANDLER(&nsIDOMLoadListener::BeforeUnload) }
};
static const EventDispatchData sDragEvents[] = {
{ NS_DRAGDROP_ENTER, HANDLER(&nsIDOMDragListener::DragEnter) },
{ NS_DRAGDROP_OVER_SYNTH, HANDLER(&nsIDOMDragListener::DragOver) },
{ NS_DRAGDROP_EXIT_SYNTH, HANDLER(&nsIDOMDragListener::DragExit) },
{ NS_DRAGDROP_DRAGDROP, HANDLER(&nsIDOMDragListener::DragDrop) },
{ NS_DRAGDROP_GESTURE, HANDLER(&nsIDOMDragListener::DragGesture) },
{ NS_DRAGDROP_DRAG, HANDLER(&nsIDOMDragListener::Drag) },
{ NS_DRAGDROP_END, HANDLER(&nsIDOMDragListener::DragEnd) },
{ NS_DRAGDROP_START, HANDLER(&nsIDOMDragListener::DragStart) },
{ NS_DRAGDROP_LEAVE_SYNTH, HANDLER(&nsIDOMDragListener::DragLeave) },
{ NS_DRAGDROP_DROP, HANDLER(&nsIDOMDragListener::Drop) }
};
static const EventDispatchData sXULEvents[] = {
{ NS_XUL_POPUP_SHOWING, HANDLER(&nsIDOMXULListener::PopupShowing) },
{ NS_XUL_POPUP_SHOWN, HANDLER(&nsIDOMXULListener::PopupShown) },
@ -277,21 +261,6 @@ static const EventDispatchData sUIEvents[] = {
{ NS_UI_FOCUSOUT, HANDLER(&nsIDOMUIListener::FocusOut) }
};
#ifdef MOZ_SVG
static const EventDispatchData sSVGEvents[] = {
{ NS_SVG_LOAD, HANDLER(&nsIDOMSVGListener::Load) },
{ NS_SVG_UNLOAD, HANDLER(&nsIDOMSVGListener::Unload) },
{ NS_SVG_ABORT, HANDLER(&nsIDOMSVGListener::Abort) },
{ NS_SVG_ERROR, HANDLER(&nsIDOMSVGListener::Error) },
{ NS_SVG_RESIZE, HANDLER(&nsIDOMSVGListener::Resize) },
{ NS_SVG_SCROLL, HANDLER(&nsIDOMSVGListener::Scroll) }
};
static const EventDispatchData sSVGZoomEvents[] = {
{ NS_SVG_ZOOM, HANDLER(&nsIDOMSVGZoomListener::Zoom) }
};
#endif // MOZ_SVG
#define IMPL_EVENTTYPEDATA(type) \
{ \
s##type##Events, \
@ -309,16 +278,10 @@ static const EventTypeData sEventTypes[] = {
IMPL_EVENTTYPEDATA(Load),
IMPL_EVENTTYPEDATA(Focus),
IMPL_EVENTTYPEDATA(Form),
IMPL_EVENTTYPEDATA(Drag),
IMPL_EVENTTYPEDATA(Text),
IMPL_EVENTTYPEDATA(Composition),
IMPL_EVENTTYPEDATA(XUL),
IMPL_EVENTTYPEDATA(UI)
#ifdef MOZ_SVG
,
IMPL_EVENTTYPEDATA(SVG),
IMPL_EVENTTYPEDATA(SVGZoom)
#endif // MOZ_SVG
};
// Strong references to event groups
@ -564,6 +527,7 @@ nsEventListenerManager::RemoveEventListener(nsIDOMEventListener *aListener,
(EVENT_TYPE_EQUALS(ls, aType, aUserType) ||
(!(ls->mEventType) &&
EVENT_TYPE_DATA_EQUALS(ls->mTypeData, aTypeData)))) {
nsRefPtr<nsEventListenerManager> kungFuDeathGrip = this;
mListeners.RemoveElementAt(i);
mNoListenerForEvent = NS_EVENT_TYPE_NULL;
mNoListenerForEventAtom = nsnull;

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