зеркало из https://github.com/mozilla/gecko-dev.git
Merge mozilla-central to tracemonkey
This commit is contained in:
Коммит
f28cd0f53f
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -337,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>
|
||||
|
|
|
@ -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">
|
||||
|
@ -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]);
|
||||
|
@ -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;
|
||||
|
|
|
@ -2766,7 +2766,7 @@ SessionStoreService.prototype = {
|
|||
let normalWindowIndex = 0;
|
||||
// try to find a non-popup window in this._closedWindows
|
||||
while (normalWindowIndex < this._closedWindows.length &&
|
||||
this._closedWindows[normalWindowIndex].isPopup)
|
||||
!!this._closedWindows[normalWindowIndex].isPopup)
|
||||
normalWindowIndex++;
|
||||
if (normalWindowIndex >= maxWindowsUndo)
|
||||
spliceTo = normalWindowIndex + 1;
|
||||
|
|
|
@ -113,7 +113,7 @@ function test() {
|
|||
|
||||
function test_behavior (callback) {
|
||||
// helper function that does the actual testing
|
||||
function openWindowRec(windowsToOpen, expectedResults) {
|
||||
function openWindowRec(windowsToOpen, expectedResults, recCallback) {
|
||||
// do actual checking
|
||||
if (!windowsToOpen.length) {
|
||||
let closedWindowData = JSON.parse(ss.getClosedWindowData());
|
||||
|
@ -130,7 +130,7 @@ function test() {
|
|||
"There were " + oResults.normal + " normal windows to repoen");
|
||||
|
||||
// cleanup & return
|
||||
executeSoon(callback);
|
||||
executeSoon(recCallback);
|
||||
return;
|
||||
}
|
||||
// hack to force window to be considered a popup (toolbar=no didn't work)
|
||||
|
@ -149,7 +149,7 @@ function test() {
|
|||
executeSoon(function() {
|
||||
window.close();
|
||||
executeSoon(function() {
|
||||
openWindowRec(windowsToOpen, expectedResults);
|
||||
openWindowRec(windowsToOpen, expectedResults, recCallback);
|
||||
});
|
||||
});
|
||||
}, true);
|
||||
|
|
|
@ -641,9 +641,7 @@ msvcr80.dll
|
|||
#else
|
||||
mozcrt19.dll
|
||||
#endif
|
||||
xpicleanup.exe
|
||||
#else
|
||||
xpicleanup
|
||||
#endif
|
||||
xpicleanup@BIN_SUFFIX@
|
||||
chrome.manifest
|
||||
install.rdf
|
||||
|
|
|
@ -64,8 +64,6 @@ vpath book%.inc @srcdir@/en-US/profile
|
|||
endif
|
||||
|
||||
|
||||
run_for_effects_too := if ! test -d $(DIST)/branding; then $(NSINSTALL) -D $(DIST)/branding; fi)
|
||||
|
||||
ifdef MOZ_BRANDING_DIRECTORY
|
||||
SUBMAKEFILES += \
|
||||
$(DEPTH)/$(MOZ_BRANDING_DIRECTORY)/Makefile \
|
||||
|
@ -104,6 +102,11 @@ include $(topsrcdir)/config/rules.mk
|
|||
|
||||
include $(topsrcdir)/toolkit/locales/l10n.mk
|
||||
|
||||
$(STAGEDIST): $(DIST)/branding
|
||||
|
||||
$(DIST)/branding:
|
||||
$(NSINSTALL) -D $@
|
||||
|
||||
libs::
|
||||
@if test -f "$(LOCALE_SRCDIR)/existing-profile-defaults.js"; then \
|
||||
$(PERL) $(topsrcdir)/config/preprocessor.pl $(PREF_PPFLAGS) $(DEFINES) $(ACDEFINES) $(XULPPFLAGS) \
|
||||
|
@ -284,7 +287,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
|
||||
|
|
|
@ -546,9 +546,6 @@ STATIC_LIBIDL = @STATIC_LIBIDL@
|
|||
|
||||
MOZ_NATIVE_MAKEDEPEND = @SYSTEM_MAKEDEPEND@
|
||||
|
||||
# Used for LD_LIBRARY_PATH
|
||||
LIBS_PATH = @LIBS_PATH@
|
||||
|
||||
MOZ_AUTO_DEPS = @MOZ_AUTO_DEPS@
|
||||
COMPILER_DEPEND = @COMPILER_DEPEND@
|
||||
MDDEPDIR := @MDDEPDIR@
|
||||
|
|
|
@ -946,12 +946,6 @@ endif # NO_PROFILE_GUIDED_OPTIMIZE
|
|||
checkout:
|
||||
$(MAKE) -C $(topsrcdir) -f client.mk checkout
|
||||
|
||||
run_viewer: $(FINAL_TARGET)/viewer
|
||||
cd $(FINAL_TARGET); \
|
||||
MOZILLA_FIVE_HOME=`pwd` \
|
||||
LD_LIBRARY_PATH=".:$(LIBS_PATH):$$LD_LIBRARY_PATH" \
|
||||
viewer
|
||||
|
||||
clean clobber realclean clobber_all:: $(SUBMAKEFILES)
|
||||
-rm -f $(ALL_TRASH)
|
||||
-rm -rf $(ALL_TRASH_DIRS)
|
||||
|
@ -2106,7 +2100,7 @@ endif
|
|||
# Fake targets. Always run these rules, even if a file/directory with that
|
||||
# name already exists.
|
||||
#
|
||||
.PHONY: all alltags boot checkout chrome realchrome clean clobber clobber_all export install libs makefiles realclean run_viewer run_apprunner tools $(DIRS) $(TOOL_DIRS) FORCE
|
||||
.PHONY: all alltags boot checkout chrome realchrome clean clobber clobber_all export install libs makefiles realclean run_apprunner tools $(DIRS) $(TOOL_DIRS) FORCE
|
||||
|
||||
# Used as a dependency to force targets to rebuild
|
||||
FORCE:
|
||||
|
|
12
configure.in
12
configure.in
|
@ -3032,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'
|
||||
|
@ -8325,16 +8325,6 @@ if test "$ACCESSIBILITY" -a "$MOZ_ENABLE_GTK2" ; then
|
|||
AC_DEFINE_UNQUOTED(ATK_REV_VERSION, $ATK_REV_VERSION)
|
||||
fi
|
||||
|
||||
# Used for LD_LIBRARY_PATH of run_viewer target
|
||||
LIBS_PATH=
|
||||
for lib_arg in $NSPR_LIBS $TK_LIBS; do
|
||||
case $lib_arg in
|
||||
-L* ) LIBS_PATH="${LIBS_PATH:+$LIBS_PATH:}"`expr $lib_arg : "-L\(.*\)"` ;;
|
||||
* ) ;;
|
||||
esac
|
||||
done
|
||||
AC_SUBST(LIBS_PATH)
|
||||
|
||||
dnl ========================================================
|
||||
dnl Use cygwin wrapper for win32 builds, except MSYS/MinGW
|
||||
dnl ========================================================
|
||||
|
|
|
@ -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);
|
||||
|
||||
};
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,60 @@
|
|||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
#include "prmem.h"
|
||||
|
||||
interface nsIAccessNode;
|
||||
interface nsIContent;
|
||||
#include "nsIServiceManager.h"
|
||||
|
||||
[uuid(fa9cafac-9562-49ad-afcf-911ab1e4e4fb)]
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIDOMCanvasRenderingContext2D.h"
|
||||
#include "nsICanvasRenderingContextInternal.h"
|
||||
#include "nsICanvasElement.h"
|
||||
#include "nsIPrincipal.h"
|
||||
#include "nsINode.h"
|
||||
|
||||
interface nsPIAccessibleDocument : nsISupports
|
||||
#include "nsGfxCIID.h"
|
||||
|
||||
#include "nsTArray.h"
|
||||
|
||||
#include "CanvasUtils.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
void
|
||||
CanvasUtils::DoDrawImageSecurityCheck(nsICanvasElement *aCanvasElement,
|
||||
nsIPrincipal *aPrincipal,
|
||||
PRBool forceWriteOnly)
|
||||
{
|
||||
/**
|
||||
* 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();
|
||||
};
|
||||
// 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: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* -*- 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,8 +15,8 @@
|
|||
* 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) 1998
|
||||
* Vladimir Vukicevic <vladimir@pobox.com>
|
||||
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
|
@ -35,28 +35,49 @@
|
|||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
#include "nspluginroot.idl"
|
||||
#ifndef _CANVASUTILS_H_
|
||||
#define _CANVASUTILS_H_
|
||||
|
||||
%{C++
|
||||
#include "nsplugindefs.h"
|
||||
%}
|
||||
#include "prtypes.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsICanvasElement.h"
|
||||
#include "nsIPrincipal.h"
|
||||
#include "nsIDOMElement.h"
|
||||
#include "nsRect.h"
|
||||
|
||||
[uuid(57b4e2f0-019b-11d2-815b-006008119d7a)]
|
||||
interface nsIWindowlessPluginInstancePeer : nsISupports
|
||||
{
|
||||
/**
|
||||
* Corresponds to NPN_InvalidateRect
|
||||
*/
|
||||
void invalidateRect(in nsPluginRectPtr aRect);
|
||||
#include "gfxASurface.h"
|
||||
|
||||
/**
|
||||
* Corresponds to NPN_InvalidateRegion
|
||||
*/
|
||||
void invalidateRegion(in nsPluginRegion aRegion);
|
||||
namespace mozilla {
|
||||
|
||||
/**
|
||||
* Corresponds to NPN_ForceRedraw
|
||||
*/
|
||||
void forceRedraw();
|
||||
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;
|
||||
|
@ -3972,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)
|
||||
|
|
|
@ -256,11 +256,24 @@ public:
|
|||
*/
|
||||
already_AddRefed<nsILoadGroup> GetDocumentLoadGroup();
|
||||
|
||||
/**
|
||||
* Returns PR_TRUE if the media has played or completed a seek.
|
||||
* Used by video frame to determine whether to paint the poster.
|
||||
*/
|
||||
PRBool GetPlayedOrSeeked() { return mHasPlayedOrSeeked; }
|
||||
|
||||
protected:
|
||||
class MediaLoadListener;
|
||||
class LoadNextSourceEvent;
|
||||
class SelectResourceEvent;
|
||||
|
||||
/**
|
||||
* Changes mHasPlayedOrSeeked to aValue. If mHasPlayedOrSeeked changes
|
||||
* we'll force a reflow so that the video frame gets reflowed to reflect
|
||||
* the poster hiding or showing immediately.
|
||||
*/
|
||||
void SetPlayedOrSeeked(PRBool aValue);
|
||||
|
||||
/**
|
||||
* Create a decoder for the given aMIMEType. Returns false if we
|
||||
* were unable to create the decoder.
|
||||
|
@ -469,4 +482,8 @@ protected:
|
|||
// PR_TRUE if we are allowed to suspend the decoder because we were paused,
|
||||
// autobuffer and autoplay were not set, and we loaded the first frame.
|
||||
PRPackedBool mAllowSuspendAfterFirstFrame;
|
||||
|
||||
// PR_TRUE if we've played or completed a seek. We use this to determine
|
||||
// when the poster frame should be shown.
|
||||
PRPackedBool mHasPlayedOrSeeked;
|
||||
};
|
||||
|
|
|
@ -413,6 +413,7 @@ NS_IMETHODIMP nsHTMLMediaElement::Load()
|
|||
{
|
||||
if (mIsRunningLoadMethod)
|
||||
return NS_OK;
|
||||
SetPlayedOrSeeked(PR_FALSE);
|
||||
mIsRunningLoadMethod = PR_TRUE;
|
||||
AbortExistingLoads();
|
||||
QueueSelectResourceTask();
|
||||
|
@ -784,7 +785,8 @@ nsHTMLMediaElement::nsHTMLMediaElement(nsINodeInfo *aNodeInfo, PRBool aFromParse
|
|||
mDelayingLoadEvent(PR_FALSE),
|
||||
mIsRunningSelectResource(PR_FALSE),
|
||||
mSuspendedAfterFirstFrame(PR_FALSE),
|
||||
mAllowSuspendAfterFirstFrame(PR_TRUE)
|
||||
mAllowSuspendAfterFirstFrame(PR_TRUE),
|
||||
mHasPlayedOrSeeked(PR_FALSE)
|
||||
{
|
||||
RegisterFreezableElement();
|
||||
}
|
||||
|
@ -813,9 +815,29 @@ void nsHTMLMediaElement::StopSuspendingAfterFirstFrame()
|
|||
}
|
||||
}
|
||||
|
||||
void nsHTMLMediaElement::SetPlayedOrSeeked(PRBool aValue)
|
||||
{
|
||||
if (aValue == mHasPlayedOrSeeked)
|
||||
return;
|
||||
|
||||
mHasPlayedOrSeeked = aValue;
|
||||
|
||||
// Force a reflow so that the poster frame hides or shows immediately.
|
||||
nsIDocument *doc = GetDocument();
|
||||
if (!doc) return;
|
||||
nsIPresShell *presShell = doc->GetPrimaryShell();
|
||||
if (!presShell) return;
|
||||
nsIFrame* frame = presShell->GetPrimaryFrameFor(this);
|
||||
if (!frame) return;
|
||||
presShell->FrameNeedsReflow(frame,
|
||||
nsIPresShell::eTreeChange,
|
||||
NS_FRAME_IS_DIRTY);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsHTMLMediaElement::Play()
|
||||
{
|
||||
StopSuspendingAfterFirstFrame();
|
||||
SetPlayedOrSeeked(PR_TRUE);
|
||||
|
||||
if (mNetworkState == nsIDOMHTMLMediaElement::NETWORK_EMPTY) {
|
||||
nsresult rv = Load();
|
||||
|
@ -1204,6 +1226,7 @@ nsresult nsHTMLMediaElement::InitializeDecoderForChannel(nsIChannel *aChannel,
|
|||
mDecoder->SetVolume(mMuted ? 0.0 : mVolume);
|
||||
|
||||
if (!mPaused) {
|
||||
SetPlayedOrSeeked(PR_TRUE);
|
||||
rv = mDecoder->Play();
|
||||
}
|
||||
|
||||
|
@ -1301,6 +1324,7 @@ void nsHTMLMediaElement::SeekStarted()
|
|||
void nsHTMLMediaElement::SeekCompleted()
|
||||
{
|
||||
mPlayingBeforeSeek = PR_FALSE;
|
||||
SetPlayedOrSeeked(PR_TRUE);
|
||||
DispatchAsyncSimpleEvent(NS_LITERAL_STRING("seeked"));
|
||||
}
|
||||
|
||||
|
@ -1454,6 +1478,7 @@ void nsHTMLMediaElement::NotifyAutoplayDataReady()
|
|||
mAutoplayEnabled) {
|
||||
mPaused = PR_FALSE;
|
||||
if (mDecoder) {
|
||||
SetPlayedOrSeeked(PR_TRUE);
|
||||
mDecoder->Play();
|
||||
}
|
||||
DispatchAsyncSimpleEvent(NS_LITERAL_STRING("play"));
|
||||
|
|
|
@ -158,3 +158,5 @@ nsHTMLVideoElement::GetAttributeMappingFunction() const
|
|||
{
|
||||
return &MapAttributesIntoRule;
|
||||
}
|
||||
|
||||
NS_IMPL_URI_ATTR(nsHTMLVideoElement, Poster, poster)
|
||||
|
|
|
@ -41,11 +41,83 @@ VPATH = @srcdir@
|
|||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
ifdef MOZ_MEDIA
|
||||
DIRS = \
|
||||
video \
|
||||
MODULE = content
|
||||
LIBRARY_NAME = gkconmedia_s
|
||||
LIBXUL_LIBRARY = 1
|
||||
|
||||
REQUIRES = \
|
||||
xpcom \
|
||||
string \
|
||||
gfx \
|
||||
content \
|
||||
thebes \
|
||||
layout \
|
||||
widget \
|
||||
dom \
|
||||
js \
|
||||
locale \
|
||||
unicharutil \
|
||||
webshell \
|
||||
uriloader \
|
||||
htmlparser \
|
||||
necko \
|
||||
view \
|
||||
pref \
|
||||
docshell \
|
||||
xpconnect \
|
||||
xuldoc \
|
||||
caps \
|
||||
editor \
|
||||
imglib2 \
|
||||
mimetype \
|
||||
exthandler \
|
||||
uconv \
|
||||
intl \
|
||||
plugin \
|
||||
cairo \
|
||||
libpixman \
|
||||
$(NULL)
|
||||
|
||||
EXPORTS = \
|
||||
nsMediaDecoder.h \
|
||||
nsMediaStream.h \
|
||||
nsMediaCache.h \
|
||||
$(NULL)
|
||||
|
||||
CPPSRCS = \
|
||||
nsMediaDecoder.cpp \
|
||||
nsMediaCache.cpp \
|
||||
nsMediaStream.cpp \
|
||||
$(NULL)
|
||||
|
||||
ifdef MOZ_SYDNEYAUDIO
|
||||
EXPORTS += \
|
||||
nsAudioStream.h \
|
||||
$(NULL)
|
||||
CPPSRCS += \
|
||||
nsAudioStream.cpp \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
DIRS =
|
||||
|
||||
ifdef MOZ_OGG
|
||||
DIRS += ogg
|
||||
endif
|
||||
|
||||
ifdef MOZ_WAVE
|
||||
DIRS += wave
|
||||
endif
|
||||
|
||||
ifdef ENABLE_TESTS
|
||||
DIRS += test
|
||||
endif
|
||||
|
||||
FORCE_STATIC_LIB = 1
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
INCLUDES += \
|
||||
-I$(srcdir)/../base/src \
|
||||
-I$(srcdir)/../html/content/src \
|
||||
$(NULL)
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
DEPTH = ../../../..
|
||||
DEPTH = ../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
@ -42,7 +42,7 @@ VPATH = @srcdir@
|
|||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
MODULE = content
|
||||
LIBRARY_NAME = gkconvideo_s
|
||||
LIBRARY_NAME = gkconogg_s
|
||||
LIBXUL_LIBRARY = 1
|
||||
|
||||
REQUIRES = \
|
||||
|
@ -78,36 +78,21 @@ REQUIRES = \
|
|||
libpixman \
|
||||
$(NULL)
|
||||
|
||||
EXPORTS += \
|
||||
nsChannelReader.h \
|
||||
nsOggDecoder.h \
|
||||
$(NULL)
|
||||
|
||||
CPPSRCS = \
|
||||
nsMediaDecoder.cpp \
|
||||
nsMediaCache.cpp \
|
||||
nsMediaStream.cpp \
|
||||
$(NULL)
|
||||
|
||||
ifdef MOZ_SYDNEYAUDIO
|
||||
CPPSRCS += \
|
||||
nsAudioStream.cpp \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
ifdef MOZ_OGG
|
||||
CPPSRCS += \
|
||||
nsChannelReader.cpp \
|
||||
nsOggDecoder.cpp \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
ifdef MOZ_WAVE
|
||||
CPPSRCS += \
|
||||
nsWaveDecoder.cpp \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
FORCE_STATIC_LIB = 1
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
INCLUDES += \
|
||||
-I$(srcdir)/../../../base/src \
|
||||
-I$(srcdir)/../../../html/content/src \
|
||||
-I$(srcdir)/../../base/src \
|
||||
-I$(srcdir)/../../html/content/src \
|
||||
$(NULL)
|
|
@ -34,11 +34,11 @@
|
|||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
DEPTH = ../../../..
|
||||
DEPTH = ../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
relativesrcdir = content/media/video/test
|
||||
relativesrcdir = content/media/test
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
include $(topsrcdir)/config/rules.mk
|
|
@ -7,7 +7,7 @@ function handleRequest(request, response)
|
|||
createInstance(Components.interfaces.nsIFileInputStream);
|
||||
var bis = Components.classes["@mozilla.org/binaryinputstream;1"].
|
||||
createInstance(Components.interfaces.nsIBinaryInputStream);
|
||||
var paths = "tests/content/media/video/test/320x240.ogv";
|
||||
var paths = "tests/content/media/test/320x240.ogv";
|
||||
var split = paths.split("/");
|
||||
for(var i = 0; i < split.length; ++i) {
|
||||
file.append(split[i]);
|
|
@ -7,7 +7,7 @@ function handleRequest(request, response)
|
|||
createInstance(Components.interfaces.nsIFileInputStream);
|
||||
var bis = Components.classes["@mozilla.org/binaryinputstream;1"].
|
||||
createInstance(Components.interfaces.nsIBinaryInputStream);
|
||||
var paths = "tests/content/media/video/test/320x240.ogv";
|
||||
var paths = "tests/content/media/test/320x240.ogv";
|
||||
var split = paths.split("/");
|
||||
for(var i = 0; i < split.length; ++i) {
|
||||
file.append(split[i]);
|
|
@ -7,7 +7,7 @@ function handleRequest(request, response)
|
|||
createInstance(Components.interfaces.nsIFileInputStream);
|
||||
var bis = Components.classes["@mozilla.org/binaryinputstream;1"].
|
||||
createInstance(Components.interfaces.nsIBinaryInputStream);
|
||||
var paths = "tests/content/media/video/test/320x240.ogv";
|
||||
var paths = "tests/content/media/test/320x240.ogv";
|
||||
var split = paths.split("/");
|
||||
for(var i = 0; i < split.length; ++i) {
|
||||
file.append(split[i]);
|
|
@ -7,7 +7,7 @@ function handleRequest(request, response)
|
|||
createInstance(Components.interfaces.nsIFileInputStream);
|
||||
var bis = Components.classes["@mozilla.org/binaryinputstream;1"].
|
||||
createInstance(Components.interfaces.nsIBinaryInputStream);
|
||||
var paths = "tests/content/media/video/test/320x240.ogv";
|
||||
var paths = "tests/content/media/test/320x240.ogv";
|
||||
var split = paths.split("/");
|
||||
for(var i = 0; i < split.length; ++i) {
|
||||
file.append(split[i]);
|
|
@ -7,7 +7,7 @@ function handleRequest(request, response)
|
|||
createInstance(Components.interfaces.nsIFileInputStream);
|
||||
var bis = Components.classes["@mozilla.org/binaryinputstream;1"].
|
||||
createInstance(Components.interfaces.nsIBinaryInputStream);
|
||||
var paths = "tests/content/media/video/test/320x240.ogv";
|
||||
var paths = "tests/content/media/test/320x240.ogv";
|
||||
var split = paths.split("/");
|
||||
for(var i = 0; i < split.length; ++i) {
|
||||
file.append(split[i]);
|
|
@ -7,7 +7,7 @@ function handleRequest(request, response)
|
|||
createInstance(Components.interfaces.nsIFileInputStream);
|
||||
var bis = Components.classes["@mozilla.org/binaryinputstream;1"].
|
||||
createInstance(Components.interfaces.nsIBinaryInputStream);
|
||||
var paths = "tests/content/media/video/test/320x240.ogv";
|
||||
var paths = "tests/content/media/test/320x240.ogv";
|
||||
var split = paths.split("/");
|
||||
for(var i = 0; i < split.length; ++i) {
|
||||
file.append(split[i]);
|
|
@ -7,7 +7,7 @@ function handleRequest(request, response)
|
|||
if (getState(key[1]) == "redirect") {
|
||||
var origin = request.host == "localhost" ? "example.org" : "localhost:8888";
|
||||
response.setStatusLine(request.httpVersion, 303, "See Other");
|
||||
response.setHeader("Location", "http://" + origin + "/tests/content/media/video/test/seek.ogv");
|
||||
response.setHeader("Location", "http://" + origin + "/tests/content/media/test/seek.ogv");
|
||||
response.setHeader("Content-Type", "text/html");
|
||||
return;
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ function handleRequest(request, response)
|
|||
createInstance(Components.interfaces.nsIFileInputStream);
|
||||
var bis = Components.classes["@mozilla.org/binaryinputstream;1"].
|
||||
createInstance(Components.interfaces.nsIBinaryInputStream);
|
||||
var paths = "tests/content/media/video/test/seek.ogv";
|
||||
var paths = "tests/content/media/test/seek.ogv";
|
||||
var split = paths.split("/");
|
||||
for(var i = 0; i < split.length; ++i) {
|
||||
file.append(split[i]);
|
|
@ -4,67 +4,67 @@
|
|||
<body onload="setTimeout(load, 0);" onunload="done()">
|
||||
<script>
|
||||
|
||||
// Page URL: http://example.org/tests/content/media/video/test/file_access_controls.html
|
||||
// Page URL: http://example.org/tests/content/media/test/file_access_controls.html
|
||||
|
||||
var gTests = [
|
||||
{
|
||||
// Test 0
|
||||
url: "redirect.sjs?http://example.com/tests/content/media/video/test/320x240.ogv",
|
||||
url: "redirect.sjs?http://example.com/tests/content/media/test/320x240.ogv",
|
||||
result: "error",
|
||||
description: "Won't load when redirected to different domain",
|
||||
},{
|
||||
// Test 1
|
||||
url: "redirect.sjs?http://example.com/tests/content/media/video/test/320x240.allow-origin.ogv",
|
||||
url: "redirect.sjs?http://example.com/tests/content/media/test/320x240.allow-origin.ogv",
|
||||
result: "loaded",
|
||||
description: "Can load when redirected to different domain with allow-origin",
|
||||
},{
|
||||
// Test 2
|
||||
url: "redirect.sjs?http://test1.example.org/tests/content/media/video/test/320x240.ogv",
|
||||
url: "redirect.sjs?http://test1.example.org/tests/content/media/test/320x240.ogv",
|
||||
result: "error",
|
||||
description: "Won't load when redirected to subdomain",
|
||||
},{
|
||||
// Test 3
|
||||
url: "redirect.sjs?http://test1.example.org/tests/content/media/video/test/320x240.allow-origin.ogv",
|
||||
url: "redirect.sjs?http://test1.example.org/tests/content/media/test/320x240.allow-origin.ogv",
|
||||
result: "loaded",
|
||||
description: "Can load when redirected to subdomain with allow-origin",
|
||||
},{
|
||||
// Test 4
|
||||
url: "redirect.sjs?http://example.org/tests/content/media/video/test/320x240.ogv",
|
||||
url: "redirect.sjs?http://example.org/tests/content/media/test/320x240.ogv",
|
||||
result: "loaded",
|
||||
description: "Can load when redirected to same domain",
|
||||
},{
|
||||
// Test 5
|
||||
url: "http://example.org/tests/content/media/video/test/320x240.ogv",
|
||||
url: "http://example.org/tests/content/media/test/320x240.ogv",
|
||||
result: "loaded",
|
||||
description: "Can load from same domain"
|
||||
},{
|
||||
// Test 6
|
||||
url: "http://example.org:8000/tests/content/media/video/test/320x240.ogv",
|
||||
url: "http://example.org:8000/tests/content/media/test/320x240.ogv",
|
||||
result: "error",
|
||||
description: "Won't load from differnet port on same domain"
|
||||
},{
|
||||
// Test 7
|
||||
url: "http://example.org:8000/tests/content/media/video/test/320x240.allow-origin.ogv",
|
||||
url: "http://example.org:8000/tests/content/media/test/320x240.allow-origin.ogv",
|
||||
result: "loaded",
|
||||
description: "Can load from different port on same domain with allow-origin",
|
||||
},{
|
||||
// Test 8
|
||||
url: "http://example.com/tests/content/media/video/test/320x240.ogv",
|
||||
url: "http://example.com/tests/content/media/test/320x240.ogv",
|
||||
result: "error",
|
||||
description: "Won't load cross domain",
|
||||
},{
|
||||
// Test 9
|
||||
url: "http://example.com/tests/content/media/video/test/320x240.allow-origin.ogv",
|
||||
url: "http://example.com/tests/content/media/test/320x240.allow-origin.ogv",
|
||||
result: "loaded",
|
||||
description: "Can load cross domain with allow-origin",
|
||||
},{
|
||||
// Test 10
|
||||
url: "http://test1.example.org/tests/content/media/video/test/320x240.allow-origin.ogv",
|
||||
url: "http://test1.example.org/tests/content/media/test/320x240.allow-origin.ogv",
|
||||
result: "loaded",
|
||||
description: "Can load from subdomain with allow-origin",
|
||||
},{
|
||||
// Test 11
|
||||
url: "http://test1.example.org/tests/content/media/video/test/320x240.ogv",
|
||||
url: "http://test1.example.org/tests/content/media/test/320x240.ogv",
|
||||
result: "error",
|
||||
description: "Won't load from subdomain",
|
||||
}
|
||||
|
@ -95,7 +95,7 @@ function createVideo() {
|
|||
function load() {
|
||||
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
||||
opener.is(window.location.href,
|
||||
"http://example.org/tests/content/media/video/test/file_access_controls.html",
|
||||
"http://example.org/tests/content/media/test/file_access_controls.html",
|
||||
"We must be on a example.org:80");
|
||||
|
||||
// Ensure access control check pref is on.
|
|
@ -20,7 +20,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=451958
|
|||
/** Test for Bug 451958 **/
|
||||
|
||||
function run() {
|
||||
window.open("http://example.org:80/tests/content/media/video/test/file_access_controls.html", "", "width=500,height=500");
|
||||
window.open("http://example.org:80/tests/content/media/test/file_access_controls.html", "", "width=500,height=500");
|
||||
}
|
||||
|
||||
function done() {
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче