зеркало из https://github.com/mozilla/gecko-dev.git
Merge trunk into HTML5 repo
This commit is contained in:
Коммит
fb74340ed2
|
@ -59,7 +59,6 @@ XPIDLSRCS = \
|
|||
nsIAccessibleRole.idl \
|
||||
nsIAccessibleStates.idl \
|
||||
nsIAccessibleDocument.idl \
|
||||
nsPIAccessibleDocument.idl \
|
||||
nsIAccessibleProvider.idl \
|
||||
nsIAccessibleSelectable.idl \
|
||||
nsIAccessNode.idl \
|
||||
|
|
|
@ -54,9 +54,7 @@
|
|||
*
|
||||
* There are no nsIAccessibleRole enums for the following landmark roles:
|
||||
* banner, contentinfo, main, navigation, note, search, secondary, seealso, breadcrumbs
|
||||
*/
|
||||
|
||||
static const nsStateMapEntry kEndEntry = {nsnull, 0, 0}; // To fill in array of state mappings
|
||||
*/
|
||||
|
||||
nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
||||
{
|
||||
|
@ -67,8 +65,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
|||
eNoValue,
|
||||
eNoAction,
|
||||
eNoLiveAttr,
|
||||
kNoReqStates,
|
||||
kEndEntry
|
||||
kNoReqStates
|
||||
},
|
||||
{
|
||||
"alertdialog",
|
||||
|
@ -77,8 +74,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
|||
eNoValue,
|
||||
eNoAction,
|
||||
eNoLiveAttr,
|
||||
kNoReqStates,
|
||||
kEndEntry
|
||||
kNoReqStates
|
||||
},
|
||||
{
|
||||
"application",
|
||||
|
@ -87,8 +83,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
|||
eNoValue,
|
||||
eNoAction,
|
||||
eNoLiveAttr,
|
||||
kNoReqStates,
|
||||
kEndEntry
|
||||
kNoReqStates
|
||||
},
|
||||
{
|
||||
"article",
|
||||
|
@ -97,8 +92,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
|||
eNoValue,
|
||||
eNoAction,
|
||||
eNoLiveAttr,
|
||||
nsIAccessibleStates::STATE_READONLY,
|
||||
kEndEntry
|
||||
nsIAccessibleStates::STATE_READONLY
|
||||
},
|
||||
{
|
||||
"button",
|
||||
|
@ -108,9 +102,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
|||
eClickAction,
|
||||
eNoLiveAttr,
|
||||
kNoReqStates,
|
||||
{&nsAccessibilityAtoms::aria_pressed, kBoolState, nsIAccessibleStates::STATE_PRESSED | nsIAccessibleStates::STATE_CHECKABLE},
|
||||
{&nsAccessibilityAtoms::aria_pressed, "mixed", nsIAccessibleStates::STATE_MIXED | nsIAccessibleStates::STATE_CHECKABLE},
|
||||
kEndEntry
|
||||
eARIAPressed
|
||||
},
|
||||
{
|
||||
"checkbox",
|
||||
|
@ -119,11 +111,9 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
|||
eNoValue,
|
||||
eCheckUncheckAction,
|
||||
eNoLiveAttr,
|
||||
nsIAccessibleStates::STATE_CHECKABLE,
|
||||
{&nsAccessibilityAtoms::aria_checked, kBoolState, nsIAccessibleStates::STATE_CHECKED},
|
||||
{&nsAccessibilityAtoms::aria_checked, "mixed", nsIAccessibleStates::STATE_MIXED},
|
||||
{&nsAccessibilityAtoms::aria_readonly, kBoolState, nsIAccessibleStates::STATE_READONLY},
|
||||
kEndEntry
|
||||
kNoReqStates,
|
||||
eARIACheckableMixed,
|
||||
eARIAReadonly
|
||||
},
|
||||
{
|
||||
"columnheader",
|
||||
|
@ -133,10 +123,8 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
|||
eSortAction,
|
||||
eNoLiveAttr,
|
||||
kNoReqStates,
|
||||
{&nsAccessibilityAtoms::aria_selected, kBoolState, nsIAccessibleStates::STATE_SELECTED | nsIAccessibleStates::STATE_SELECTABLE},
|
||||
{&nsAccessibilityAtoms::aria_selected, "false", nsIAccessibleStates::STATE_SELECTABLE},
|
||||
{&nsAccessibilityAtoms::aria_readonly, kBoolState, nsIAccessibleStates::STATE_READONLY},
|
||||
kEndEntry
|
||||
eARIASelected,
|
||||
eARIAReadonly
|
||||
},
|
||||
{
|
||||
"combobox",
|
||||
|
@ -146,9 +134,8 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
|||
eOpenCloseAction,
|
||||
eNoLiveAttr,
|
||||
nsIAccessibleStates::STATE_COLLAPSED | nsIAccessibleStates::STATE_HASPOPUP,
|
||||
// Manually map EXT_STATE_SUPPORTS_AUTOCOMPLETION aria-autocomplete
|
||||
{&nsAccessibilityAtoms::aria_readonly, kBoolState, nsIAccessibleStates::STATE_READONLY},
|
||||
kEndEntry
|
||||
eARIAAutoComplete,
|
||||
eARIAReadonly
|
||||
},
|
||||
{
|
||||
"dialog",
|
||||
|
@ -157,8 +144,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
|||
eNoValue,
|
||||
eNoAction,
|
||||
eNoLiveAttr,
|
||||
kNoReqStates,
|
||||
kEndEntry
|
||||
kNoReqStates
|
||||
},
|
||||
{
|
||||
"document",
|
||||
|
@ -167,8 +153,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
|||
eNoValue,
|
||||
eNoAction,
|
||||
eNoLiveAttr,
|
||||
nsIAccessibleStates::STATE_READONLY,
|
||||
kEndEntry
|
||||
nsIAccessibleStates::STATE_READONLY
|
||||
},
|
||||
{
|
||||
"grid",
|
||||
|
@ -178,9 +163,8 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
|||
eNoAction,
|
||||
eNoLiveAttr,
|
||||
nsIAccessibleStates::STATE_FOCUSABLE,
|
||||
{&nsAccessibilityAtoms::aria_multiselectable, kBoolState, nsIAccessibleStates::STATE_MULTISELECTABLE | nsIAccessibleStates::STATE_EXTSELECTABLE},
|
||||
{&nsAccessibilityAtoms::aria_readonly, kBoolState, nsIAccessibleStates::STATE_READONLY},
|
||||
kEndEntry
|
||||
eARIAMultiSelectable,
|
||||
eARIAReadonly
|
||||
},
|
||||
{
|
||||
"gridcell",
|
||||
|
@ -190,10 +174,8 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
|||
eNoAction,
|
||||
eNoLiveAttr,
|
||||
kNoReqStates,
|
||||
{&nsAccessibilityAtoms::aria_selected, kBoolState, nsIAccessibleStates::STATE_SELECTED | nsIAccessibleStates::STATE_SELECTABLE},
|
||||
{&nsAccessibilityAtoms::aria_selected, "false", nsIAccessibleStates::STATE_SELECTABLE},
|
||||
{&nsAccessibilityAtoms::aria_readonly, kBoolState, nsIAccessibleStates::STATE_READONLY},
|
||||
kEndEntry
|
||||
eARIASelected,
|
||||
eARIAReadonly
|
||||
},
|
||||
{
|
||||
"group",
|
||||
|
@ -202,8 +184,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
|||
eNoValue,
|
||||
eNoAction,
|
||||
eNoLiveAttr,
|
||||
kNoReqStates,
|
||||
kEndEntry
|
||||
kNoReqStates
|
||||
},
|
||||
{
|
||||
"heading",
|
||||
|
@ -212,8 +193,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
|||
eNoValue,
|
||||
eNoAction,
|
||||
eNoLiveAttr,
|
||||
kNoReqStates,
|
||||
kEndEntry
|
||||
kNoReqStates
|
||||
},
|
||||
{
|
||||
"img",
|
||||
|
@ -222,8 +202,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
|||
eNoValue,
|
||||
eNoAction,
|
||||
eNoLiveAttr,
|
||||
kNoReqStates,
|
||||
kEndEntry
|
||||
kNoReqStates
|
||||
},
|
||||
{
|
||||
"label",
|
||||
|
@ -232,8 +211,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
|||
eNoValue,
|
||||
eNoAction,
|
||||
eNoLiveAttr,
|
||||
kNoReqStates,
|
||||
kEndEntry
|
||||
kNoReqStates
|
||||
},
|
||||
{
|
||||
"link",
|
||||
|
@ -242,8 +220,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
|||
eNoValue,
|
||||
eJumpAction,
|
||||
eNoLiveAttr,
|
||||
nsIAccessibleStates::STATE_LINKED,
|
||||
kEndEntry
|
||||
nsIAccessibleStates::STATE_LINKED
|
||||
},
|
||||
{
|
||||
"list",
|
||||
|
@ -253,8 +230,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
|||
eNoAction,
|
||||
eNoLiveAttr,
|
||||
nsIAccessibleStates::STATE_READONLY,
|
||||
{&nsAccessibilityAtoms::aria_multiselectable, kBoolState, nsIAccessibleStates::STATE_MULTISELECTABLE | nsIAccessibleStates::STATE_EXTSELECTABLE},
|
||||
kEndEntry
|
||||
eARIAMultiSelectable
|
||||
},
|
||||
{
|
||||
"listbox",
|
||||
|
@ -264,9 +240,8 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
|||
eNoAction,
|
||||
eNoLiveAttr,
|
||||
kNoReqStates,
|
||||
{&nsAccessibilityAtoms::aria_readonly, kBoolState, nsIAccessibleStates::STATE_READONLY},
|
||||
{&nsAccessibilityAtoms::aria_multiselectable, kBoolState, nsIAccessibleStates::STATE_MULTISELECTABLE | nsIAccessibleStates::STATE_EXTSELECTABLE},
|
||||
kEndEntry
|
||||
eARIAMultiSelectable,
|
||||
eARIAReadonly
|
||||
},
|
||||
{
|
||||
"listitem",
|
||||
|
@ -276,12 +251,8 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
|||
eNoAction, // XXX: should depend on state, parent accessible
|
||||
eNoLiveAttr,
|
||||
nsIAccessibleStates::STATE_READONLY,
|
||||
{&nsAccessibilityAtoms::aria_selected, kBoolState, nsIAccessibleStates::STATE_SELECTED | nsIAccessibleStates::STATE_SELECTABLE},
|
||||
{&nsAccessibilityAtoms::aria_selected, "false", nsIAccessibleStates::STATE_SELECTABLE},
|
||||
{&nsAccessibilityAtoms::aria_checked, kBoolState, nsIAccessibleStates::STATE_CHECKED | nsIAccessibleStates::STATE_CHECKABLE},
|
||||
{&nsAccessibilityAtoms::aria_checked, "mixed", nsIAccessibleStates::STATE_MIXED | nsIAccessibleStates::STATE_CHECKABLE},
|
||||
{&nsAccessibilityAtoms::aria_checked, "false", nsIAccessibleStates::STATE_CHECKABLE},
|
||||
kEndEntry
|
||||
eARIASelected,
|
||||
eARIACheckedMixed
|
||||
},
|
||||
{
|
||||
"log",
|
||||
|
@ -290,8 +261,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
|||
eNoValue,
|
||||
eNoAction,
|
||||
ePoliteLiveAttr,
|
||||
kNoReqStates,
|
||||
kEndEntry
|
||||
kNoReqStates
|
||||
},
|
||||
{
|
||||
"marquee",
|
||||
|
@ -300,8 +270,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
|||
eNoValue,
|
||||
eNoAction,
|
||||
eOffLiveAttr,
|
||||
kNoReqStates,
|
||||
kEndEntry
|
||||
kNoReqStates
|
||||
},
|
||||
{
|
||||
"math",
|
||||
|
@ -310,8 +279,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
|||
eNoValue,
|
||||
eNoAction,
|
||||
eNoLiveAttr,
|
||||
kNoReqStates,
|
||||
kEndEntry
|
||||
kNoReqStates
|
||||
},
|
||||
{
|
||||
"menu",
|
||||
|
@ -321,8 +289,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
|||
eNoAction, // XXX: technically accessibles of menupopup role haven't
|
||||
// any action, but menu can be open or close.
|
||||
eNoLiveAttr,
|
||||
kNoReqStates,
|
||||
kEndEntry
|
||||
kNoReqStates
|
||||
},
|
||||
{
|
||||
"menubar",
|
||||
|
@ -331,8 +298,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
|||
eNoValue,
|
||||
eNoAction,
|
||||
eNoLiveAttr,
|
||||
kNoReqStates,
|
||||
kEndEntry
|
||||
kNoReqStates
|
||||
},
|
||||
{
|
||||
"menuitem",
|
||||
|
@ -342,10 +308,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
|||
eClickAction,
|
||||
eNoLiveAttr,
|
||||
kNoReqStates,
|
||||
{&nsAccessibilityAtoms::aria_checked, kBoolState, nsIAccessibleStates::STATE_CHECKED | nsIAccessibleStates::STATE_CHECKABLE},
|
||||
{&nsAccessibilityAtoms::aria_checked, "mixed", nsIAccessibleStates::STATE_MIXED | nsIAccessibleStates::STATE_CHECKABLE},
|
||||
{&nsAccessibilityAtoms::aria_checked, "false", nsIAccessibleStates::STATE_CHECKABLE},
|
||||
kEndEntry
|
||||
eARIACheckedMixed
|
||||
},
|
||||
{
|
||||
"menuitemcheckbox",
|
||||
|
@ -354,10 +317,8 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
|||
eNoValue,
|
||||
eClickAction,
|
||||
eNoLiveAttr,
|
||||
nsIAccessibleStates::STATE_CHECKABLE,
|
||||
{&nsAccessibilityAtoms::aria_checked, kBoolState, nsIAccessibleStates::STATE_CHECKED },
|
||||
{&nsAccessibilityAtoms::aria_checked, "mixed", nsIAccessibleStates::STATE_MIXED},
|
||||
kEndEntry
|
||||
kNoReqStates,
|
||||
eARIACheckableMixed
|
||||
},
|
||||
{
|
||||
"menuitemradio",
|
||||
|
@ -366,9 +327,8 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
|||
eNoValue,
|
||||
eClickAction,
|
||||
eNoLiveAttr,
|
||||
nsIAccessibleStates::STATE_CHECKABLE,
|
||||
{&nsAccessibilityAtoms::aria_checked, kBoolState, nsIAccessibleStates::STATE_CHECKED },
|
||||
kEndEntry
|
||||
kNoReqStates,
|
||||
eARIACheckableBool
|
||||
},
|
||||
{
|
||||
"option",
|
||||
|
@ -378,12 +338,8 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
|||
eSelectAction,
|
||||
eNoLiveAttr,
|
||||
kNoReqStates,
|
||||
{&nsAccessibilityAtoms::aria_selected, kBoolState, nsIAccessibleStates::STATE_SELECTED | nsIAccessibleStates::STATE_SELECTABLE},
|
||||
{&nsAccessibilityAtoms::aria_selected, "false", nsIAccessibleStates::STATE_SELECTABLE},
|
||||
{&nsAccessibilityAtoms::aria_checked, kBoolState, nsIAccessibleStates::STATE_CHECKED | nsIAccessibleStates::STATE_CHECKABLE},
|
||||
{&nsAccessibilityAtoms::aria_checked, "mixed", nsIAccessibleStates::STATE_MIXED | nsIAccessibleStates::STATE_CHECKABLE},
|
||||
{&nsAccessibilityAtoms::aria_checked, "false", nsIAccessibleStates::STATE_CHECKABLE},
|
||||
kEndEntry
|
||||
eARIASelected,
|
||||
eARIACheckedMixed
|
||||
},
|
||||
{
|
||||
"presentation",
|
||||
|
@ -392,8 +348,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
|||
eNoValue,
|
||||
eNoAction,
|
||||
eNoLiveAttr,
|
||||
kNoReqStates,
|
||||
kEndEntry
|
||||
kNoReqStates
|
||||
},
|
||||
{
|
||||
"progressbar",
|
||||
|
@ -402,8 +357,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
|||
eHasValueMinMax,
|
||||
eNoAction,
|
||||
eNoLiveAttr,
|
||||
nsIAccessibleStates::STATE_READONLY,
|
||||
kEndEntry
|
||||
nsIAccessibleStates::STATE_READONLY
|
||||
},
|
||||
{
|
||||
"radio",
|
||||
|
@ -412,9 +366,8 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
|||
eNoValue,
|
||||
eSelectAction,
|
||||
eNoLiveAttr,
|
||||
nsIAccessibleStates::STATE_CHECKABLE,
|
||||
{&nsAccessibilityAtoms::aria_checked, kBoolState, nsIAccessibleStates::STATE_CHECKED},
|
||||
kEndEntry
|
||||
kNoReqStates,
|
||||
eARIACheckableBool
|
||||
},
|
||||
{
|
||||
"radiogroup",
|
||||
|
@ -423,8 +376,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
|||
eNoValue,
|
||||
eNoAction,
|
||||
eNoLiveAttr,
|
||||
kNoReqStates,
|
||||
kEndEntry
|
||||
kNoReqStates
|
||||
},
|
||||
{
|
||||
"region",
|
||||
|
@ -433,8 +385,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
|||
eNoValue,
|
||||
eNoAction,
|
||||
eNoLiveAttr,
|
||||
kNoReqStates,
|
||||
kEndEntry
|
||||
kNoReqStates
|
||||
},
|
||||
{
|
||||
"row",
|
||||
|
@ -444,9 +395,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
|||
eNoAction,
|
||||
eNoLiveAttr,
|
||||
kNoReqStates,
|
||||
{&nsAccessibilityAtoms::aria_selected, kBoolState, nsIAccessibleStates::STATE_SELECTED | nsIAccessibleStates::STATE_SELECTABLE},
|
||||
{&nsAccessibilityAtoms::aria_selected, "false", nsIAccessibleStates::STATE_SELECTABLE},
|
||||
kEndEntry
|
||||
eARIASelected
|
||||
},
|
||||
{
|
||||
"rowheader",
|
||||
|
@ -456,10 +405,8 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
|||
eSortAction,
|
||||
eNoLiveAttr,
|
||||
kNoReqStates,
|
||||
{&nsAccessibilityAtoms::aria_selected, kBoolState, nsIAccessibleStates::STATE_SELECTED | nsIAccessibleStates::STATE_SELECTABLE},
|
||||
{&nsAccessibilityAtoms::aria_selected, "false", nsIAccessibleStates::STATE_SELECTABLE},
|
||||
{&nsAccessibilityAtoms::aria_readonly, kBoolState, nsIAccessibleStates::STATE_READONLY},
|
||||
kEndEntry
|
||||
eARIASelected,
|
||||
eARIAReadonly
|
||||
},
|
||||
{
|
||||
"section",
|
||||
|
@ -468,8 +415,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
|||
eNoValue,
|
||||
eNoAction,
|
||||
eNoLiveAttr,
|
||||
kNoReqStates,
|
||||
kEndEntry
|
||||
kNoReqStates
|
||||
},
|
||||
{
|
||||
"separator",
|
||||
|
@ -478,8 +424,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
|||
eNoValue,
|
||||
eNoAction,
|
||||
eNoLiveAttr,
|
||||
kNoReqStates,
|
||||
kEndEntry
|
||||
kNoReqStates
|
||||
},
|
||||
{
|
||||
"slider",
|
||||
|
@ -489,8 +434,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
|||
eNoAction,
|
||||
eNoLiveAttr,
|
||||
kNoReqStates,
|
||||
{&nsAccessibilityAtoms::aria_readonly, kBoolState, nsIAccessibleStates::STATE_READONLY},
|
||||
kEndEntry
|
||||
eARIAReadonly
|
||||
},
|
||||
{
|
||||
"spinbutton",
|
||||
|
@ -500,8 +444,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
|||
eNoAction,
|
||||
eNoLiveAttr,
|
||||
kNoReqStates,
|
||||
{&nsAccessibilityAtoms::aria_readonly, kBoolState, nsIAccessibleStates::STATE_READONLY},
|
||||
kEndEntry
|
||||
eARIAReadonly
|
||||
},
|
||||
{
|
||||
"status",
|
||||
|
@ -510,8 +453,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
|||
eNoValue,
|
||||
eNoAction,
|
||||
ePoliteLiveAttr,
|
||||
kNoReqStates,
|
||||
kEndEntry
|
||||
kNoReqStates
|
||||
},
|
||||
{
|
||||
"tab",
|
||||
|
@ -520,8 +462,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
|||
eNoValue,
|
||||
eSwitchAction,
|
||||
eNoLiveAttr,
|
||||
kNoReqStates,
|
||||
kEndEntry
|
||||
kNoReqStates
|
||||
},
|
||||
{
|
||||
"tablist",
|
||||
|
@ -530,8 +471,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
|||
eNoValue,
|
||||
eNoAction,
|
||||
ePoliteLiveAttr,
|
||||
kNoReqStates,
|
||||
kEndEntry
|
||||
kNoReqStates
|
||||
},
|
||||
{
|
||||
"tabpanel",
|
||||
|
@ -540,8 +480,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
|||
eNoValue,
|
||||
eNoAction,
|
||||
eNoLiveAttr,
|
||||
kNoReqStates,
|
||||
kEndEntry
|
||||
kNoReqStates
|
||||
},
|
||||
{
|
||||
"textbox",
|
||||
|
@ -551,12 +490,9 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
|||
eActivateAction,
|
||||
eNoLiveAttr,
|
||||
kNoReqStates,
|
||||
// Manually map EXT_STATE_SINGLE_LINE and EXT_STATE_MULTI_LINE FROM aria-multiline
|
||||
// Manually map EXT_STATE_SUPPORTS_AUTOCOMPLETION aria-autocomplete
|
||||
{&nsAccessibilityAtoms::aria_autocomplete, "list", nsIAccessibleStates::STATE_HASPOPUP},
|
||||
{&nsAccessibilityAtoms::aria_autocomplete, "both", nsIAccessibleStates::STATE_HASPOPUP},
|
||||
{&nsAccessibilityAtoms::aria_readonly, kBoolState, nsIAccessibleStates::STATE_READONLY},
|
||||
kEndEntry
|
||||
eARIAAutoComplete,
|
||||
eARIAMultiline,
|
||||
eARIAReadonlyOrEditable
|
||||
},
|
||||
{
|
||||
"timer",
|
||||
|
@ -565,8 +501,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
|||
eNoValue,
|
||||
eNoAction,
|
||||
eOffLiveAttr,
|
||||
kNoReqStates,
|
||||
kEndEntry
|
||||
kNoReqStates
|
||||
},
|
||||
{
|
||||
"toolbar",
|
||||
|
@ -575,8 +510,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
|||
eNoValue,
|
||||
eNoAction,
|
||||
eNoLiveAttr,
|
||||
kNoReqStates,
|
||||
kEndEntry
|
||||
kNoReqStates
|
||||
},
|
||||
{
|
||||
"tooltip",
|
||||
|
@ -585,8 +519,7 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
|||
eNoValue,
|
||||
eNoAction,
|
||||
eNoLiveAttr,
|
||||
kNoReqStates,
|
||||
kEndEntry
|
||||
kNoReqStates
|
||||
},
|
||||
{
|
||||
"tree",
|
||||
|
@ -596,9 +529,8 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
|||
eNoAction,
|
||||
eNoLiveAttr,
|
||||
kNoReqStates,
|
||||
{&nsAccessibilityAtoms::aria_readonly, kBoolState, nsIAccessibleStates::STATE_READONLY},
|
||||
{&nsAccessibilityAtoms::aria_multiselectable, kBoolState, nsIAccessibleStates::STATE_MULTISELECTABLE | nsIAccessibleStates::STATE_EXTSELECTABLE},
|
||||
kEndEntry
|
||||
eARIAReadonly,
|
||||
eARIAMultiSelectable
|
||||
},
|
||||
{
|
||||
"treegrid",
|
||||
|
@ -608,9 +540,8 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
|||
eNoAction,
|
||||
eNoLiveAttr,
|
||||
kNoReqStates,
|
||||
{&nsAccessibilityAtoms::aria_readonly, kBoolState, nsIAccessibleStates::STATE_READONLY},
|
||||
{&nsAccessibilityAtoms::aria_multiselectable, kBoolState, nsIAccessibleStates::STATE_MULTISELECTABLE | nsIAccessibleStates::STATE_EXTSELECTABLE},
|
||||
kEndEntry
|
||||
eARIAReadonly,
|
||||
eARIAMultiSelectable
|
||||
},
|
||||
{
|
||||
"treeitem",
|
||||
|
@ -621,12 +552,8 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
|||
// on states
|
||||
eNoLiveAttr,
|
||||
kNoReqStates,
|
||||
{&nsAccessibilityAtoms::aria_selected, kBoolState, nsIAccessibleStates::STATE_SELECTED | nsIAccessibleStates::STATE_SELECTABLE},
|
||||
{&nsAccessibilityAtoms::aria_selected, "false", nsIAccessibleStates::STATE_SELECTABLE},
|
||||
{&nsAccessibilityAtoms::aria_checked, kBoolState, nsIAccessibleStates::STATE_CHECKED | nsIAccessibleStates::STATE_CHECKABLE},
|
||||
{&nsAccessibilityAtoms::aria_checked, "mixed", nsIAccessibleStates::STATE_MIXED | nsIAccessibleStates::STATE_CHECKABLE},
|
||||
{&nsAccessibilityAtoms::aria_checked, "false", nsIAccessibleStates::STATE_CHECKABLE},
|
||||
kEndEntry
|
||||
eARIASelected,
|
||||
eARIACheckedMixed
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -639,8 +566,7 @@ nsRoleMapEntry nsARIAMap::gLandmarkRoleMap = {
|
|||
eNoValue,
|
||||
eNoAction,
|
||||
eNoLiveAttr,
|
||||
kNoReqStates,
|
||||
kEndEntry
|
||||
kNoReqStates
|
||||
};
|
||||
|
||||
nsRoleMapEntry nsARIAMap::gEmptyRoleMap = {
|
||||
|
@ -650,8 +576,89 @@ nsRoleMapEntry nsARIAMap::gEmptyRoleMap = {
|
|||
eNoValue,
|
||||
eNoAction,
|
||||
eNoLiveAttr,
|
||||
kNoReqStates,
|
||||
kEndEntry
|
||||
kNoReqStates
|
||||
};
|
||||
|
||||
nsStateMapEntry nsARIAMap::gWAIStateMap[] = {
|
||||
// eARIANone
|
||||
nsStateMapEntry(),
|
||||
|
||||
// eARIAAutoComplete
|
||||
nsStateMapEntry(&nsAccessibilityAtoms::aria_autocomplete,
|
||||
"inline", 0, nsIAccessibleStates::EXT_STATE_SUPPORTS_AUTOCOMPLETION,
|
||||
"list", nsIAccessibleStates::STATE_HASPOPUP, nsIAccessibleStates::EXT_STATE_SUPPORTS_AUTOCOMPLETION,
|
||||
"both", nsIAccessibleStates::STATE_HASPOPUP, nsIAccessibleStates::EXT_STATE_SUPPORTS_AUTOCOMPLETION),
|
||||
|
||||
// eARIABusy
|
||||
nsStateMapEntry(&nsAccessibilityAtoms::aria_busy,
|
||||
"true", nsIAccessibleStates::STATE_BUSY, 0,
|
||||
"error", nsIAccessibleStates::STATE_INVALID, 0),
|
||||
|
||||
// eARIACheckableBool
|
||||
nsStateMapEntry(&nsAccessibilityAtoms::aria_checked, kBoolType,
|
||||
nsIAccessibleStates::STATE_CHECKABLE,
|
||||
nsIAccessibleStates::STATE_CHECKED, 0,
|
||||
0, 0, PR_TRUE),
|
||||
|
||||
// eARIACheckableMixed
|
||||
nsStateMapEntry(&nsAccessibilityAtoms::aria_checked, kMixedType,
|
||||
nsIAccessibleStates::STATE_CHECKABLE,
|
||||
nsIAccessibleStates::STATE_CHECKED, 0,
|
||||
0, 0, PR_TRUE),
|
||||
|
||||
// eARIACheckedMixed
|
||||
nsStateMapEntry(&nsAccessibilityAtoms::aria_checked, kMixedType,
|
||||
nsIAccessibleStates::STATE_CHECKABLE,
|
||||
nsIAccessibleStates::STATE_CHECKED, 0),
|
||||
|
||||
// eARIADisabled
|
||||
nsStateMapEntry(&nsAccessibilityAtoms::aria_disabled, kBoolType, 0,
|
||||
nsIAccessibleStates::STATE_UNAVAILABLE, 0),
|
||||
|
||||
// eARIAExpanded
|
||||
nsStateMapEntry(&nsAccessibilityAtoms::aria_expanded, kBoolType, 0,
|
||||
nsIAccessibleStates::STATE_EXPANDED, 0,
|
||||
nsIAccessibleStates::STATE_COLLAPSED, 0),
|
||||
|
||||
// eARIAHasPopup
|
||||
nsStateMapEntry(&nsAccessibilityAtoms::aria_haspopup, kBoolType, 0,
|
||||
nsIAccessibleStates::STATE_HASPOPUP, 0),
|
||||
|
||||
// eARIAInvalid
|
||||
nsStateMapEntry(&nsAccessibilityAtoms::aria_invalid, kBoolType, 0,
|
||||
nsIAccessibleStates::STATE_INVALID, 0),
|
||||
|
||||
// eARIAMultiline
|
||||
nsStateMapEntry(&nsAccessibilityAtoms::aria_multiline, kBoolType, 0,
|
||||
0, nsIAccessibleStates::EXT_STATE_MULTI_LINE,
|
||||
0, nsIAccessibleStates::EXT_STATE_SINGLE_LINE, PR_TRUE),
|
||||
|
||||
// eARIAMultiSelectable
|
||||
nsStateMapEntry(&nsAccessibilityAtoms::aria_multiselectable, kBoolType, 0,
|
||||
nsIAccessibleStates::STATE_MULTISELECTABLE | nsIAccessibleStates::STATE_EXTSELECTABLE, 0),
|
||||
|
||||
// eARIAPressed
|
||||
nsStateMapEntry(&nsAccessibilityAtoms::aria_pressed, kMixedType,
|
||||
nsIAccessibleStates::STATE_CHECKABLE,
|
||||
nsIAccessibleStates::STATE_PRESSED, 0),
|
||||
|
||||
// eARIAReadonly
|
||||
nsStateMapEntry(&nsAccessibilityAtoms::aria_readonly, kBoolType, 0,
|
||||
nsIAccessibleStates::STATE_READONLY, 0),
|
||||
|
||||
// eARIAReadonlyOrEditable
|
||||
nsStateMapEntry(&nsAccessibilityAtoms::aria_readonly, kBoolType, 0,
|
||||
nsIAccessibleStates::STATE_READONLY, 0,
|
||||
0, nsIAccessibleStates::EXT_STATE_EDITABLE, PR_TRUE),
|
||||
|
||||
// eARIARequired
|
||||
nsStateMapEntry(&nsAccessibilityAtoms::aria_required, kBoolType, 0,
|
||||
nsIAccessibleStates::STATE_REQUIRED, 0),
|
||||
|
||||
// eARIASelected
|
||||
nsStateMapEntry(&nsAccessibilityAtoms::aria_selected, kBoolType,
|
||||
nsIAccessibleStates::STATE_SELECTABLE,
|
||||
nsIAccessibleStates::STATE_SELECTED, 0)
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -659,16 +666,14 @@ nsRoleMapEntry nsARIAMap::gEmptyRoleMap = {
|
|||
* The following state rules are applied to any accessible element,
|
||||
* whether there is an ARIA role or not:
|
||||
*/
|
||||
nsStateMapEntry nsARIAMap::gWAIUnivStateMap[] = {
|
||||
{&nsAccessibilityAtoms::aria_required, kBoolState, nsIAccessibleStates::STATE_REQUIRED},
|
||||
{&nsAccessibilityAtoms::aria_invalid, kBoolState, nsIAccessibleStates::STATE_INVALID},
|
||||
{&nsAccessibilityAtoms::aria_haspopup, kBoolState, nsIAccessibleStates::STATE_HASPOPUP},
|
||||
{&nsAccessibilityAtoms::aria_busy, "true", nsIAccessibleStates::STATE_BUSY},
|
||||
{&nsAccessibilityAtoms::aria_busy, "error", nsIAccessibleStates::STATE_INVALID},
|
||||
{&nsAccessibilityAtoms::aria_disabled, kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
|
||||
{&nsAccessibilityAtoms::aria_expanded, kBoolState, nsIAccessibleStates::STATE_EXPANDED},
|
||||
{&nsAccessibilityAtoms::aria_expanded, "false", nsIAccessibleStates::STATE_COLLAPSED},
|
||||
kEndEntry
|
||||
eStateMapEntryID nsARIAMap::gWAIUnivStateMap[] = {
|
||||
eARIARequired,
|
||||
eARIAInvalid,
|
||||
eARIAHasPopup,
|
||||
eARIABusy,
|
||||
eARIADisabled,
|
||||
eARIAExpanded,
|
||||
eARIANone
|
||||
};
|
||||
|
||||
|
||||
|
@ -709,3 +714,144 @@ nsAttributeCharacteristics nsARIAMap::gWAIUnivAttrMap[] = {
|
|||
};
|
||||
|
||||
PRUint32 nsARIAMap::gWAIUnivAttrMapLength = NS_ARRAY_LENGTH(nsARIAMap::gWAIUnivAttrMap);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsStateMapEntry
|
||||
|
||||
nsStateMapEntry:: nsStateMapEntry(nsIAtom **aAttrName, eStateValueType aType,
|
||||
PRUint32 aPermanentState,
|
||||
PRUint32 aTrueState, PRUint32 aTrueExtraState,
|
||||
PRUint32 aFalseState, PRUint32 aFalseExtraState,
|
||||
PRBool aDefinedIfAbsent) :
|
||||
attributeName(aAttrName), isToken(PR_TRUE), permanentState(aPermanentState)
|
||||
{
|
||||
value1 = "false";
|
||||
state1 = aFalseState;
|
||||
extraState1 = aFalseExtraState;
|
||||
|
||||
if (aType == kMixedType) {
|
||||
value2 = "mixed";
|
||||
state2 = nsIAccessibleStates::STATE_MIXED;
|
||||
extraState2 = 0;
|
||||
}
|
||||
|
||||
defaultState = aTrueState;
|
||||
defaultExtraState = aTrueExtraState;
|
||||
|
||||
definedIfAbsent = aDefinedIfAbsent;
|
||||
}
|
||||
|
||||
nsStateMapEntry::nsStateMapEntry(nsIAtom **aAttrName,
|
||||
const char *aValue1,
|
||||
PRUint32 aState1, PRUint32 aExtraState1,
|
||||
const char *aValue2,
|
||||
PRUint32 aState2, PRUint32 aExtraState2,
|
||||
const char *aValue3,
|
||||
PRUint32 aState3, PRUint32 aExtraState3) :
|
||||
attributeName(aAttrName), isToken(PR_FALSE), permanentState(0),
|
||||
value1(aValue1), state1(aState1), extraState1(aExtraState1),
|
||||
value2(aValue2), state2(aState2), extraState2(aExtraState2),
|
||||
value3(aValue3), state3(aState3), extraState3(aExtraState3),
|
||||
defaultState(0), defaultExtraState(0), definedIfAbsent(PR_FALSE)
|
||||
{
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsStateMapEntry::MapToStates(nsIContent *aContent,
|
||||
PRUint32 *aState, PRUint32 *aExtraState,
|
||||
eStateMapEntryID aStateMapEntryID)
|
||||
{
|
||||
// Return true if we should continue.
|
||||
if (aStateMapEntryID == eARIANone)
|
||||
return PR_FALSE;
|
||||
|
||||
const nsStateMapEntry& entry = nsARIAMap::gWAIStateMap[aStateMapEntryID];
|
||||
|
||||
if (entry.isToken) {
|
||||
// If attribute is considered as defined when it's absent then let's act
|
||||
// attribute value is "false" supposedly.
|
||||
PRBool hasAttr = aContent->HasAttr(kNameSpaceID_None, *entry.attributeName);
|
||||
if (entry.definedIfAbsent && !hasAttr) {
|
||||
if (entry.permanentState)
|
||||
*aState |= entry.permanentState;
|
||||
if (entry.state1)
|
||||
*aState |= entry.state1;
|
||||
if (aExtraState && entry.extraState1)
|
||||
*aExtraState |= entry.extraState1;
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
// We only have attribute state mappings for NMTOKEN (and boolean) based
|
||||
// ARIA attributes. According to spec, a value of "undefined" is to be
|
||||
// treated equivalent to "", or the absence of the attribute. We bail out
|
||||
// for this case here.
|
||||
// Note: If this method happens to be called with a non-token based
|
||||
// attribute, for example: aria-label="" or aria-label="undefined", we will
|
||||
// bail out and not explore a state mapping, which is safe.
|
||||
if (!hasAttr ||
|
||||
aContent->AttrValueIs(kNameSpaceID_None, *entry.attributeName,
|
||||
nsAccessibilityAtoms::_empty, eCaseMatters) ||
|
||||
aContent->AttrValueIs(kNameSpaceID_None, *entry.attributeName,
|
||||
nsAccessibilityAtoms::_undefined, eCaseMatters)) {
|
||||
|
||||
if (entry.permanentState)
|
||||
*aState &= ~entry.permanentState;
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
if (entry.permanentState)
|
||||
*aState |= entry.permanentState;
|
||||
}
|
||||
|
||||
nsAutoString attrValue;
|
||||
if (!aContent->GetAttr(kNameSpaceID_None, *entry.attributeName, attrValue))
|
||||
return PR_TRUE;
|
||||
|
||||
// Apply states for matched value. If no values was matched then apply default
|
||||
// states.
|
||||
PRBool applyDefaultStates = PR_TRUE;
|
||||
if (entry.value1) {
|
||||
if (attrValue.EqualsASCII(entry.value1)) {
|
||||
applyDefaultStates = PR_FALSE;
|
||||
|
||||
if (entry.state1)
|
||||
*aState |= entry.state1;
|
||||
|
||||
if (aExtraState && entry.extraState1)
|
||||
*aExtraState |= entry.extraState1;
|
||||
|
||||
} else if (entry.value2) {
|
||||
if (attrValue.EqualsASCII(entry.value2)) {
|
||||
applyDefaultStates = PR_FALSE;
|
||||
|
||||
if (entry.state2)
|
||||
*aState |= entry.state2;
|
||||
|
||||
if (aExtraState && entry.extraState2)
|
||||
*aExtraState |= entry.extraState2;
|
||||
|
||||
} else if (entry.value3) {
|
||||
if (attrValue.EqualsASCII(entry.value3)) {
|
||||
applyDefaultStates = PR_FALSE;
|
||||
|
||||
if (entry.state3)
|
||||
*aState |= entry.state3;
|
||||
|
||||
if (aExtraState && entry.extraState3)
|
||||
*aExtraState |= entry.extraState3;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (applyDefaultStates) {
|
||||
if (entry.defaultState)
|
||||
*aState |= entry.defaultState;
|
||||
if (entry.defaultExtraState && aExtraState)
|
||||
*aExtraState |= entry.defaultExtraState;
|
||||
}
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
|
|
@ -43,14 +43,35 @@
|
|||
#include "prtypes.h"
|
||||
#include "nsAccessibilityAtoms.h"
|
||||
|
||||
// Is nsIAccessible value supported for this role or not?
|
||||
#include "nsIContent.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Value constants
|
||||
|
||||
/**
|
||||
* Used to define if role requires to expose nsIAccessibleValue.
|
||||
*/
|
||||
enum EValueRule
|
||||
{
|
||||
/**
|
||||
* nsIAccessibleValue isn't exposed.
|
||||
*/
|
||||
eNoValue,
|
||||
eHasValueMinMax // Supports value, min and max from aria-valuenow, aria-valuemin and aria-valuemax
|
||||
|
||||
/**
|
||||
* nsIAccessibleValue is implemented, supports value, min and max from
|
||||
* aria-valuenow, aria-valuemin and aria-valuemax.
|
||||
*/
|
||||
eHasValueMinMax
|
||||
};
|
||||
|
||||
// Should we expose action based on the ARIA role?
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Action constants
|
||||
|
||||
/**
|
||||
* Used to define if the role requires to expose action.
|
||||
*/
|
||||
enum EActionRule
|
||||
{
|
||||
eNoAction,
|
||||
|
@ -65,6 +86,13 @@ enum EActionRule
|
|||
eSwitchAction
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Live region constants
|
||||
|
||||
/**
|
||||
* Used to define if role exposes default value of aria-live attribute.
|
||||
*/
|
||||
enum ELiveAttrRule
|
||||
{
|
||||
eNoLiveAttr,
|
||||
|
@ -72,11 +100,23 @@ enum ELiveAttrRule
|
|||
ePoliteLiveAttr
|
||||
};
|
||||
|
||||
// Role mapping rule
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Role constants
|
||||
|
||||
/**
|
||||
* ARIA role overrides role from native markup.
|
||||
*/
|
||||
const PRBool kUseMapRole = PR_TRUE;
|
||||
|
||||
/**
|
||||
* ARIA role doesn't override the role from native markup.
|
||||
*/
|
||||
const PRBool kUseNativeRole = PR_FALSE;
|
||||
|
||||
// ARIA attribute characteristic masks, grow as needed
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// ARIA attribute characteristic masks
|
||||
|
||||
/**
|
||||
* This mask indicates the attribute should not be exposed as an object
|
||||
|
@ -92,29 +132,132 @@ const PRUint8 ATTR_BYPASSOBJ = 0x0001;
|
|||
*/
|
||||
const PRUint8 ATTR_VALTOKEN = 0x0010;
|
||||
|
||||
// Used for an nsStateMapEntry if a given state attribute supports "true" and "false"
|
||||
#define kBoolState 0
|
||||
|
||||
// Used in nsRoleMapEntry.state if no nsIAccessibleStates are automatic for a given role
|
||||
#define kNoReqStates 0
|
||||
|
||||
// For this name and value pair, what is the nsIAccessibleStates mapping.
|
||||
// nsStateMapEntry.state
|
||||
struct nsStateMapEntry
|
||||
{
|
||||
nsIAtom** attributeName; // nsnull indicates last entry in map
|
||||
const char* attributeValue; // magic value of kBoolState (0) means supports "true" and "false"
|
||||
PRUint32 state; // If match, this is the nsIAccessibleStates to map to
|
||||
};
|
||||
|
||||
// Small footprint storage of persistent aria attribute characteristics
|
||||
/**
|
||||
* Small footprint storage of persistent aria attribute characteristics.
|
||||
*/
|
||||
struct nsAttributeCharacteristics
|
||||
{
|
||||
nsIAtom** attributeName;
|
||||
const PRUint8 characteristics;
|
||||
};
|
||||
|
||||
// For each ARIA role, this maps the nsIAccessible information
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// State map entry
|
||||
|
||||
/**
|
||||
* Used in nsRoleMapEntry.state if no nsIAccessibleStates are automatic for
|
||||
* a given role.
|
||||
*/
|
||||
#define kNoReqStates 0
|
||||
|
||||
enum eStateValueType
|
||||
{
|
||||
kBoolType,
|
||||
kMixedType
|
||||
};
|
||||
|
||||
/**
|
||||
* ID for state map entry, used in nsRoleMapEntry.
|
||||
*/
|
||||
enum eStateMapEntryID
|
||||
{
|
||||
eARIANone,
|
||||
eARIAAutoComplete,
|
||||
eARIABusy,
|
||||
eARIACheckableBool,
|
||||
eARIACheckableMixed,
|
||||
eARIACheckedMixed,
|
||||
eARIADisabled,
|
||||
eARIAExpanded,
|
||||
eARIAHasPopup,
|
||||
eARIAInvalid,
|
||||
eARIAMultiline,
|
||||
eARIAMultiSelectable,
|
||||
eARIAPressed,
|
||||
eARIAReadonly,
|
||||
eARIAReadonlyOrEditable,
|
||||
eARIARequired,
|
||||
eARIASelected
|
||||
};
|
||||
|
||||
class nsStateMapEntry
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Used to create stub.
|
||||
*/
|
||||
nsStateMapEntry() {}
|
||||
|
||||
/**
|
||||
* Used for ARIA attributes having boolean or mixed values.
|
||||
*/
|
||||
nsStateMapEntry(nsIAtom **aAttrName, eStateValueType aType,
|
||||
PRUint32 aPermanentState,
|
||||
PRUint32 aTrueState, PRUint32 aTrueExtraState,
|
||||
PRUint32 aFalseState = 0, PRUint32 aFalseExtraState = 0,
|
||||
PRBool aDefinedIfAbsent = PR_FALSE);
|
||||
|
||||
/**
|
||||
* Used for ARIA attributes having enumerated values.
|
||||
*/
|
||||
nsStateMapEntry(nsIAtom **aAttrName,
|
||||
const char *aValue1, PRUint32 aState1, PRUint32 aExtraState1,
|
||||
const char *aValue2, PRUint32 aState2, PRUint32 aExtraState2,
|
||||
const char *aValue3 = 0, PRUint32 aState3 = 0,
|
||||
PRUint32 aExtraState3 = 0);
|
||||
|
||||
/**
|
||||
* Maps ARIA state map pointed by state map entry ID to accessible states.
|
||||
*
|
||||
* @param aContent [in] node of the accessible
|
||||
* @param aState [in/out] accessible states
|
||||
* @param aExtraState [in/out] accessible extra states
|
||||
* @param aStateMapEntryID [in] state map entry ID
|
||||
* @return true if state map entry ID is valid
|
||||
*/
|
||||
static PRBool MapToStates(nsIContent *aContent,
|
||||
PRUint32 *aState, PRUint32 *aExtraState,
|
||||
eStateMapEntryID aStateMapEntryID);
|
||||
|
||||
private:
|
||||
// ARIA attribute name
|
||||
nsIAtom** attributeName;
|
||||
|
||||
// Indicates if attribute is token (can be undefined)
|
||||
PRBool isToken;
|
||||
|
||||
// State applied always if attribute is defined
|
||||
PRUint32 permanentState;
|
||||
|
||||
// States applied if attribute value is matched to the stored value
|
||||
const char* value1;
|
||||
PRUint32 state1;
|
||||
PRUint32 extraState1;
|
||||
|
||||
const char* value2;
|
||||
PRUint32 state2;
|
||||
PRUint32 extraState2;
|
||||
|
||||
const char* value3;
|
||||
PRUint32 state3;
|
||||
PRUint32 extraState3;
|
||||
|
||||
// States applied if no stored values above are matched
|
||||
PRUint32 defaultState;
|
||||
PRUint32 defaultExtraState;
|
||||
|
||||
// Permanent and false states are applied if attribute is absent
|
||||
PRBool definedIfAbsent;
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Role map entry
|
||||
|
||||
/**
|
||||
* For each ARIA role, this maps the nsIAccessible information.
|
||||
*/
|
||||
struct nsRoleMapEntry
|
||||
{
|
||||
// ARIA role: string representation such as "button"
|
||||
|
@ -144,16 +287,15 @@ struct nsRoleMapEntry
|
|||
// Currently you cannot have unlimited mappings, because
|
||||
// a variable sized array would not allow the use of
|
||||
// C++'s struct initialization feature.
|
||||
nsStateMapEntry attributeMap1;
|
||||
nsStateMapEntry attributeMap2;
|
||||
nsStateMapEntry attributeMap3;
|
||||
nsStateMapEntry attributeMap4;
|
||||
nsStateMapEntry attributeMap5;
|
||||
nsStateMapEntry attributeMap6;
|
||||
nsStateMapEntry attributeMap7;
|
||||
nsStateMapEntry attributeMap8;
|
||||
eStateMapEntryID attributeMap1;
|
||||
eStateMapEntryID attributeMap2;
|
||||
eStateMapEntryID attributeMap3;
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// ARIA map
|
||||
|
||||
/**
|
||||
* These are currently initialized (hardcoded) in nsARIAMap.cpp,
|
||||
* and provide the mappings for WAI-ARIA roles and properties using the
|
||||
|
@ -180,11 +322,16 @@ struct nsARIAMap
|
|||
*/
|
||||
static nsRoleMapEntry gEmptyRoleMap;
|
||||
|
||||
/**
|
||||
* State map of ARIA state attributes.
|
||||
*/
|
||||
static nsStateMapEntry gWAIStateMap[];
|
||||
|
||||
/**
|
||||
* State map of ARIA states applied to any accessible not depending on
|
||||
* the role.
|
||||
*/
|
||||
static nsStateMapEntry gWAIUnivStateMap[];
|
||||
static eStateMapEntryID gWAIUnivStateMap[];
|
||||
|
||||
/**
|
||||
* Map of attribute to attribute characteristics.
|
||||
|
|
|
@ -45,6 +45,7 @@
|
|||
#include "nsAccessibleEventData.h"
|
||||
#include "nsHyperTextAccessible.h"
|
||||
#include "nsHTMLTableAccessible.h"
|
||||
#include "nsDocAccessible.h"
|
||||
#include "nsAccessibilityAtoms.h"
|
||||
#include "nsAccessibleTreeWalker.h"
|
||||
#include "nsAccessible.h"
|
||||
|
@ -747,6 +748,26 @@ nsAccUtils::QueryAccessibleTable(nsIAccessibleTable *aAccessibleTable)
|
|||
return accessible;
|
||||
}
|
||||
|
||||
already_AddRefed<nsDocAccessible>
|
||||
nsAccUtils::QueryAccessibleDocument(nsIAccessible *aAccessible)
|
||||
{
|
||||
nsDocAccessible* accessible = nsnull;
|
||||
if (aAccessible)
|
||||
CallQueryInterface(aAccessible, &accessible);
|
||||
|
||||
return accessible;
|
||||
}
|
||||
|
||||
already_AddRefed<nsDocAccessible>
|
||||
nsAccUtils::QueryAccessibleDocument(nsIAccessibleDocument *aAccessibleDocument)
|
||||
{
|
||||
nsDocAccessible* accessible = nsnull;
|
||||
if (aAccessibleDocument)
|
||||
CallQueryInterface(aAccessibleDocument, &accessible);
|
||||
|
||||
return accessible;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_A11Y
|
||||
|
||||
PRBool
|
||||
|
|
|
@ -55,6 +55,7 @@
|
|||
class nsAccessNode;
|
||||
class nsAccessible;
|
||||
class nsHTMLTableAccessible;
|
||||
class nsDocAccessible;
|
||||
|
||||
class nsAccUtils
|
||||
{
|
||||
|
@ -340,7 +341,19 @@ public:
|
|||
*/
|
||||
static already_AddRefed<nsHTMLTableAccessible>
|
||||
QueryAccessibleTable(nsIAccessibleTable *aAccessibleTable);
|
||||
|
||||
|
||||
/**
|
||||
* Query nsDocAccessible from the given nsIAccessible.
|
||||
*/
|
||||
static already_AddRefed<nsDocAccessible>
|
||||
QueryAccessibleDocument(nsIAccessible *aAccessible);
|
||||
|
||||
/**
|
||||
* Query nsDocAccessible from the given nsIAccessibleDocument.
|
||||
*/
|
||||
static already_AddRefed<nsDocAccessible>
|
||||
QueryAccessibleDocument(nsIAccessibleDocument *aAccessibleDocument);
|
||||
|
||||
#ifdef DEBUG_A11Y
|
||||
/**
|
||||
* Detect whether the given accessible object implements nsIAccessibleText,
|
||||
|
|
|
@ -42,7 +42,6 @@
|
|||
#include "nsHashtable.h"
|
||||
#include "nsIAccessibilityService.h"
|
||||
#include "nsIAccessibleDocument.h"
|
||||
#include "nsPIAccessibleDocument.h"
|
||||
#include "nsIDocShell.h"
|
||||
#include "nsIDocShellTreeItem.h"
|
||||
#include "nsIDocument.h"
|
||||
|
@ -192,10 +191,10 @@ nsAccessNode::Init()
|
|||
|
||||
void* uniqueID;
|
||||
GetUniqueID(&uniqueID);
|
||||
nsCOMPtr<nsPIAccessibleDocument> privateDocAccessible =
|
||||
do_QueryInterface(docAccessible);
|
||||
NS_ASSERTION(privateDocAccessible, "No private docaccessible for docaccessible");
|
||||
privateDocAccessible->CacheAccessNode(uniqueID, this);
|
||||
nsRefPtr<nsDocAccessible> docAcc =
|
||||
nsAccUtils::QueryAccessibleDocument(docAccessible);
|
||||
NS_ASSERTION(docAcc, "No nsDocAccessible for document accessible!");
|
||||
docAcc->CacheAccessNode(uniqueID, this);
|
||||
|
||||
// Make sure an ancestor in real content is cached
|
||||
// so that nsDocAccessible::RefreshNodes() can find the anonymous subtree to release when
|
||||
|
|
|
@ -43,8 +43,7 @@
|
|||
* This class wraps up the creation (and destruction) of the standard
|
||||
* set of atoms used in the accessibility module. These objects
|
||||
* are created when the are needed by accessibility is being used and they
|
||||
* are destroyed when the last nsRootAccessible is destroyed via
|
||||
* nsRootAccessible::ShutdownAll()
|
||||
* are destroyed when the last nsRootAccessible is destroyed.
|
||||
*/
|
||||
|
||||
class nsAccessibilityAtoms {
|
||||
|
|
|
@ -242,9 +242,11 @@ NS_IMETHODIMP nsAccessibilityService::ProcessDocLoadEvent(nsITimer *aTimer, void
|
|||
|
||||
nsCOMPtr<nsIAccessible> accessible;
|
||||
GetAccessibleFor(docNode, getter_AddRefs(accessible));
|
||||
nsCOMPtr<nsPIAccessibleDocument> privDocAccessible = do_QueryInterface(accessible);
|
||||
NS_ENSURE_STATE(privDocAccessible);
|
||||
privDocAccessible->FireDocLoadEvents(aEventType);
|
||||
nsRefPtr<nsDocAccessible> docAcc =
|
||||
nsAccUtils::QueryAccessibleDocument(accessible);
|
||||
NS_ENSURE_STATE(docAcc);
|
||||
|
||||
docAcc->FireDocLoadEvents(aEventType);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -307,12 +309,12 @@ NS_IMETHODIMP nsAccessibilityService::OnLocationChange(nsIWebProgress *aWebProgr
|
|||
|
||||
nsCOMPtr<nsIAccessibleDocument> accessibleDoc =
|
||||
nsAccessNode::GetDocAccessibleFor(domDocRootNode);
|
||||
nsCOMPtr<nsPIAccessibleDocument> privateAccessibleDoc =
|
||||
do_QueryInterface(accessibleDoc);
|
||||
if (!privateAccessibleDoc) {
|
||||
return NS_OK;
|
||||
}
|
||||
return privateAccessibleDoc->FireAnchorJumpEvent();
|
||||
nsRefPtr<nsDocAccessible> docAcc =
|
||||
nsAccUtils::QueryAccessibleDocument(accessibleDoc);
|
||||
if (docAcc)
|
||||
docAcc->FireAnchorJumpEvent();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void onStatusChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsresult aStatus, in wstring aMessage); */
|
||||
|
@ -2040,12 +2042,12 @@ NS_IMETHODIMP nsAccessibilityService::InvalidateSubtreeFor(nsIPresShell *aShell,
|
|||
NS_ENSURE_ARG_POINTER(aShell);
|
||||
nsCOMPtr<nsIAccessibleDocument> accessibleDoc =
|
||||
nsAccessNode::GetDocAccessibleFor(aShell->GetDocument());
|
||||
nsCOMPtr<nsPIAccessibleDocument> privateAccessibleDoc =
|
||||
do_QueryInterface(accessibleDoc);
|
||||
if (!privateAccessibleDoc) {
|
||||
return NS_OK;
|
||||
}
|
||||
return privateAccessibleDoc->InvalidateCacheSubtree(aChangeContent, aEvent);
|
||||
nsRefPtr<nsDocAccessible> docAcc =
|
||||
nsAccUtils::QueryAccessibleDocument(accessibleDoc);
|
||||
if (docAcc)
|
||||
docAcc->InvalidateCacheSubtree(aChangeContent, aEvent);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -281,7 +281,7 @@ nsAccessible::GetName(nsAString& aName)
|
|||
|
||||
nsCOMPtr<nsIXBLAccessible> xblAccessible(do_QueryInterface(mDOMNode));
|
||||
if (xblAccessible) {
|
||||
nsresult rv = xblAccessible->GetAccessibleName(aName);
|
||||
xblAccessible->GetAccessibleName(aName);
|
||||
if (!aName.IsEmpty())
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -1891,45 +1891,6 @@ nsAccessible::GroupPosition(PRInt32 *aGroupLevel,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
PRBool nsAccessible::MappedAttrState(nsIContent *aContent, PRUint32 *aStateInOut,
|
||||
nsStateMapEntry *aStateMapEntry)
|
||||
{
|
||||
// Return true if we should continue
|
||||
if (!aStateMapEntry->attributeName) {
|
||||
return PR_FALSE; // Stop looking -- no more states
|
||||
}
|
||||
|
||||
// We only have attribute state mappings for NMTOKEN (and boolean) based
|
||||
// ARIA attributes. According to spec, a value of "undefined" is to be
|
||||
// treated equivalent to "", or the absence of the attribute. We bail out
|
||||
// for this case here.
|
||||
// Note: If this method happens to be called with a non-token based
|
||||
// attribute, for example: aria-label="" or aria-label="undefined", we will
|
||||
// bail out and not explore a state mapping, which is safe.
|
||||
if (!nsAccUtils::HasDefinedARIAToken(aContent, *aStateMapEntry->attributeName)) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
nsAutoString attribValue;
|
||||
if (aContent->GetAttr(kNameSpaceID_None, *aStateMapEntry->attributeName, attribValue)) {
|
||||
if (aStateMapEntry->attributeValue == kBoolState) {
|
||||
// No attribute value map specified in state map entry indicates state cleared
|
||||
if (attribValue.EqualsLiteral("false") ||
|
||||
attribValue.EqualsLiteral("mixed")) {
|
||||
*aStateInOut &= ~aStateMapEntry->state;
|
||||
}
|
||||
else {
|
||||
*aStateInOut |= aStateMapEntry->state;
|
||||
}
|
||||
}
|
||||
else if (NS_ConvertUTF16toUTF8(attribValue).Equals(aStateMapEntry->attributeValue)) {
|
||||
*aStateInOut |= aStateMapEntry->state;
|
||||
}
|
||||
}
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
|
||||
{
|
||||
|
@ -1947,7 +1908,7 @@ nsAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
|
|||
NS_ENSURE_A11Y_SUCCESS(rv, rv);
|
||||
|
||||
// Apply ARIA states to be sure accessible states will be overriden.
|
||||
GetARIAState(aState);
|
||||
GetARIAState(aState, aExtraState);
|
||||
|
||||
if (mRoleMapEntry && mRoleMapEntry->role == nsIAccessibleRole::ROLE_PAGETAB) {
|
||||
if (*aState & nsIAccessibleStates::STATE_FOCUSED) {
|
||||
|
@ -2019,33 +1980,6 @@ nsAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
|
|||
rv = GetRole(&role);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (role == nsIAccessibleRole::ROLE_ENTRY ||
|
||||
role == nsIAccessibleRole::ROLE_COMBOBOX) {
|
||||
|
||||
nsCOMPtr<nsIContent> content = nsCoreUtils::GetRoleContent(mDOMNode);
|
||||
NS_ENSURE_STATE(content);
|
||||
|
||||
nsAutoString autocomplete;
|
||||
if (content->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::aria_autocomplete, autocomplete) &&
|
||||
(autocomplete.EqualsIgnoreCase("inline") ||
|
||||
autocomplete.EqualsIgnoreCase("list") ||
|
||||
autocomplete.EqualsIgnoreCase("both"))) {
|
||||
*aExtraState |= nsIAccessibleStates::EXT_STATE_SUPPORTS_AUTOCOMPLETION;
|
||||
}
|
||||
|
||||
// XXX We can remove this hack once we support RDF-based role & state maps
|
||||
if (mRoleMapEntry && mRoleMapEntry->role == nsIAccessibleRole::ROLE_ENTRY) {
|
||||
PRBool isMultiLine = content->AttrValueIs(kNameSpaceID_None, nsAccessibilityAtoms::aria_multiline,
|
||||
nsAccessibilityAtoms::_true, eCaseMatters);
|
||||
*aExtraState |= isMultiLine ? nsIAccessibleStates::EXT_STATE_MULTI_LINE :
|
||||
nsIAccessibleStates::EXT_STATE_SINGLE_LINE;
|
||||
if (0 == (*aState & nsIAccessibleStates::STATE_READONLY))
|
||||
*aExtraState |= nsIAccessibleStates::EXT_STATE_EDITABLE; // Not readonly
|
||||
else // We're readonly: make sure editable state wasn't set by impl class
|
||||
*aExtraState &= ~nsIAccessibleStates::EXT_STATE_EDITABLE;
|
||||
}
|
||||
}
|
||||
|
||||
// For some reasons DOM node may have not a frame. We tract such accessibles
|
||||
// as invisible.
|
||||
nsIFrame *frame = GetFrame();
|
||||
|
@ -2077,7 +2011,7 @@ nsAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsAccessible::GetARIAState(PRUint32 *aState)
|
||||
nsAccessible::GetARIAState(PRUint32 *aState, PRUint32 *aExtraState)
|
||||
{
|
||||
// Test for universal states first
|
||||
nsIContent *content = nsCoreUtils::GetRoleContent(mDOMNode);
|
||||
|
@ -2086,7 +2020,8 @@ nsAccessible::GetARIAState(PRUint32 *aState)
|
|||
}
|
||||
|
||||
PRUint32 index = 0;
|
||||
while (MappedAttrState(content, aState, &nsARIAMap::gWAIUnivStateMap[index])) {
|
||||
while (nsStateMapEntry::MapToStates(content, aState, aExtraState,
|
||||
nsARIAMap::gWAIUnivStateMap[index])) {
|
||||
++ index;
|
||||
}
|
||||
|
||||
|
@ -2126,14 +2061,12 @@ nsAccessible::GetARIAState(PRUint32 *aState)
|
|||
|
||||
// Note: the readonly bitflag will be overridden later if content is editable
|
||||
*aState |= mRoleMapEntry->state;
|
||||
if (MappedAttrState(content, aState, &mRoleMapEntry->attributeMap1) &&
|
||||
MappedAttrState(content, aState, &mRoleMapEntry->attributeMap2) &&
|
||||
MappedAttrState(content, aState, &mRoleMapEntry->attributeMap3) &&
|
||||
MappedAttrState(content, aState, &mRoleMapEntry->attributeMap4) &&
|
||||
MappedAttrState(content, aState, &mRoleMapEntry->attributeMap5) &&
|
||||
MappedAttrState(content, aState, &mRoleMapEntry->attributeMap6) &&
|
||||
MappedAttrState(content, aState, &mRoleMapEntry->attributeMap7)) {
|
||||
MappedAttrState(content, aState, &mRoleMapEntry->attributeMap8);
|
||||
if (nsStateMapEntry::MapToStates(content, aState, aExtraState,
|
||||
mRoleMapEntry->attributeMap1) &&
|
||||
nsStateMapEntry::MapToStates(content, aState, aExtraState,
|
||||
mRoleMapEntry->attributeMap2)) {
|
||||
nsStateMapEntry::MapToStates(content, aState, aExtraState,
|
||||
mRoleMapEntry->attributeMap3);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
|
|
@ -148,8 +148,9 @@ public:
|
|||
* method.
|
||||
*
|
||||
* @param [in/out] where to fill the states into.
|
||||
* @param [in/out] where to fill the extra states into
|
||||
*/
|
||||
virtual nsresult GetARIAState(PRUint32 *aState);
|
||||
virtual nsresult GetARIAState(PRUint32 *aState, PRUint32 *aExtraState);
|
||||
|
||||
/**
|
||||
* Returns the accessible name provided by native markup. It doesn't take
|
||||
|
@ -279,7 +280,6 @@ public:
|
|||
}
|
||||
|
||||
protected:
|
||||
PRBool MappedAttrState(nsIContent *aContent, PRUint32 *aStateInOut, nsStateMapEntry *aStateMapEntry);
|
||||
virtual nsIFrame* GetBoundsFrame();
|
||||
virtual void GetBoundsRect(nsRect& aRect, nsIFrame** aRelativeFrame);
|
||||
PRBool IsVisible(PRBool *aIsOffscreen);
|
||||
|
|
|
@ -385,6 +385,9 @@ nsAccEvent::ApplyEventRules(nsCOMArray<nsIAccessibleEvent> &aEventsToFire)
|
|||
}
|
||||
}
|
||||
} break; // case eRemoveDupes
|
||||
|
||||
default:
|
||||
break; // case eAllowDupes, eDoNotEmit
|
||||
} // switch
|
||||
} // for (tail)
|
||||
}
|
||||
|
|
|
@ -78,8 +78,8 @@ PRBool
|
|||
nsCoreUtils::HasListener(nsIContent *aContent, const nsAString& aEventType)
|
||||
{
|
||||
NS_ENSURE_TRUE(aContent, PR_FALSE);
|
||||
nsCOMPtr<nsIEventListenerManager> listenerManager;
|
||||
aContent->GetListenerManager(PR_FALSE, getter_AddRefs(listenerManager));
|
||||
nsIEventListenerManager* listenerManager =
|
||||
aContent->GetListenerManager(PR_FALSE);
|
||||
|
||||
return listenerManager && listenerManager->HasListenersFor(aEventType);
|
||||
}
|
||||
|
@ -201,7 +201,7 @@ nsCoreUtils::GetDOMNodeFromDOMPoint(nsIDOMNode *aNode, PRUint32 aOffset)
|
|||
nsCOMPtr<nsIContent> content(do_QueryInterface(aNode));
|
||||
if (content && content->IsNodeOfType(nsINode::eELEMENT)) {
|
||||
|
||||
PRInt32 childCount = static_cast<PRInt32>(content->GetChildCount());
|
||||
PRUint32 childCount = content->GetChildCount();
|
||||
NS_ASSERTION(aOffset >= 0 && aOffset <= childCount,
|
||||
"Wrong offset of the DOM point!");
|
||||
|
||||
|
|
|
@ -150,6 +150,18 @@ ElementTraverser(const void *aKey, nsIAccessNode *aAccessNode,
|
|||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
// What we want is: NS_INTERFACE_MAP_ENTRY(self) for static IID accessors,
|
||||
// but some of our classes have an ambiguous base class of nsISupports which
|
||||
// prevents this from working (the default macro converts it to nsISupports,
|
||||
// then addrefs it, then returns it). Therefore, we expand the macro here and
|
||||
// change it so that it works. Yuck.
|
||||
#define NS_INTERFACE_MAP_STATIC_AMBIGUOUS(_class) \
|
||||
if (aIID.Equals(NS_GET_IID(_class))) { \
|
||||
NS_ADDREF(this); \
|
||||
*aInstancePtr = this; \
|
||||
return NS_OK; \
|
||||
} else
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(nsDocAccessible)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsDocAccessible, nsAccessible)
|
||||
|
@ -163,14 +175,14 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsDocAccessible, nsAccessible)
|
|||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsDocAccessible)
|
||||
NS_INTERFACE_MAP_STATIC_AMBIGUOUS(nsDocAccessible)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIAccessibleDocument)
|
||||
NS_INTERFACE_MAP_ENTRY(nsPIAccessibleDocument)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDocumentObserver)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIMutationObserver)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIScrollPositionListener)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIAccessibleDocument)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIObserver)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIAccessibleDocument)
|
||||
NS_INTERFACE_MAP_END_INHERITING(nsHyperTextAccessible)
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(nsDocAccessible, nsHyperTextAccessible)
|
||||
|
@ -328,16 +340,16 @@ nsDocAccessible::GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState)
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsDocAccessible::GetARIAState(PRUint32 *aState)
|
||||
nsDocAccessible::GetARIAState(PRUint32 *aState, PRUint32 *aExtraState)
|
||||
{
|
||||
// Combine with states from outer doc
|
||||
NS_ENSURE_ARG_POINTER(aState);
|
||||
nsresult rv = nsAccessible::GetARIAState(aState);
|
||||
nsresult rv = nsAccessible::GetARIAState(aState, aExtraState);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsRefPtr<nsAccessible> parent = nsAccUtils::QueryAccessible(mParent);
|
||||
if (parent) // Allow iframe/frame etc. to have final state override via ARIA
|
||||
return parent->GetARIAState(aState);
|
||||
return parent->GetARIAState(aState, aExtraState);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
@ -553,7 +565,7 @@ NS_IMETHODIMP nsDocAccessible::GetCachedAccessNode(void *aUniqueID, nsIAccessNod
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
void
|
||||
nsDocAccessible::CacheAccessNode(void *aUniqueID, nsIAccessNode *aAccessNode)
|
||||
{
|
||||
// If there is an access node for the given unique ID then let's shutdown it.
|
||||
|
@ -568,7 +580,6 @@ nsDocAccessible::CacheAccessNode(void *aUniqueID, nsIAccessNode *aAccessNode)
|
|||
}
|
||||
|
||||
PutCacheEntry(mAccessNodeCache, aUniqueID, aAccessNode);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsDocAccessible::GetParent(nsIAccessible **aParent)
|
||||
|
@ -692,6 +703,15 @@ nsDocAccessible::GetFrame()
|
|||
return root;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsDocAccessible::IsDefunct()
|
||||
{
|
||||
if (nsHyperTextAccessibleWrap::IsDefunct())
|
||||
return PR_TRUE;
|
||||
|
||||
return !mDocument;
|
||||
}
|
||||
|
||||
void nsDocAccessible::GetBoundsRect(nsRect& aBounds, nsIFrame** aRelativeFrame)
|
||||
{
|
||||
*aRelativeFrame = GetFrame();
|
||||
|
@ -822,11 +842,12 @@ nsresult nsDocAccessible::RemoveEventListeners()
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsDocAccessible::FireAnchorJumpEvent()
|
||||
void
|
||||
nsDocAccessible::FireAnchorJumpEvent()
|
||||
{
|
||||
if (!mIsContentLoaded || !mDocument) {
|
||||
return NS_OK;
|
||||
}
|
||||
if (!mIsContentLoaded || !mDocument)
|
||||
return;
|
||||
|
||||
nsCOMPtr<nsISupports> container = mDocument->GetContainer();
|
||||
nsCOMPtr<nsIWebNavigation> webNav(do_GetInterface(container));
|
||||
nsCAutoString theURL;
|
||||
|
@ -854,15 +875,13 @@ NS_IMETHODIMP nsDocAccessible::FireAnchorJumpEvent()
|
|||
mIsAnchorJumped = PR_TRUE;
|
||||
lastAnchor.Assign(currentAnchor);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsDocAccessible::FireDocLoadEvents(PRUint32 aEventType)
|
||||
void
|
||||
nsDocAccessible::FireDocLoadEvents(PRUint32 aEventType)
|
||||
{
|
||||
if (!mDocument || !mWeakShell) {
|
||||
return NS_OK; // Document has been shut down
|
||||
}
|
||||
if (IsDefunct())
|
||||
return;
|
||||
|
||||
PRBool isFinished =
|
||||
(aEventType == nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_COMPLETE ||
|
||||
|
@ -871,15 +890,16 @@ NS_IMETHODIMP nsDocAccessible::FireDocLoadEvents(PRUint32 aEventType)
|
|||
mIsContentLoaded = isFinished;
|
||||
if (isFinished) {
|
||||
if (mIsLoadCompleteFired)
|
||||
return NS_OK;
|
||||
return;
|
||||
|
||||
mIsLoadCompleteFired = PR_TRUE;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDocShellTreeItem> treeItem =
|
||||
nsCoreUtils::GetDocShellTreeItemFor(mDOMNode);
|
||||
if (!treeItem) {
|
||||
return NS_OK;
|
||||
}
|
||||
if (!treeItem)
|
||||
return;
|
||||
|
||||
nsCOMPtr<nsIDocShellTreeItem> sameTypeRoot;
|
||||
treeItem->GetSameTypeRootTreeItem(getter_AddRefs(sameTypeRoot));
|
||||
|
||||
|
@ -928,7 +948,6 @@ NS_IMETHODIMP nsDocAccessible::FireDocLoadEvents(PRUint32 aEventType)
|
|||
|
||||
nsAccUtils::FireAccEvent(aEventType, this);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void nsDocAccessible::ScrollTimerCallback(nsITimer *aTimer, void *aClosure)
|
||||
|
@ -1569,14 +1588,14 @@ nsDocAccessible::FireDelayedAccessibleEvent(nsIAccessibleEvent *aEvent)
|
|||
// so that event gets fired via FlushEventsCallback
|
||||
NS_ADDREF_THIS(); // Kung fu death grip to prevent crash in callback
|
||||
mFireEventTimer->InitWithFuncCallback(FlushEventsCallback,
|
||||
static_cast<nsPIAccessibleDocument*>(this),
|
||||
0, nsITimer::TYPE_ONE_SHOT);
|
||||
this, 0, nsITimer::TYPE_ONE_SHOT);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsDocAccessible::FlushPendingEvents()
|
||||
void
|
||||
nsDocAccessible::FlushPendingEvents()
|
||||
{
|
||||
mInFlushPendingEvents = PR_TRUE;
|
||||
PRUint32 length = mEventsToFire.Count();
|
||||
|
@ -1685,12 +1704,12 @@ NS_IMETHODIMP nsDocAccessible::FlushPendingEvents()
|
|||
|
||||
if (accessible) {
|
||||
if (eventType == nsIAccessibleEvent::EVENT_INTERNAL_LOAD) {
|
||||
nsCOMPtr<nsPIAccessibleDocument> docAccessible =
|
||||
do_QueryInterface(accessible);
|
||||
NS_ASSERTION(docAccessible, "No doc accessible for doc load event");
|
||||
if (docAccessible) {
|
||||
docAccessible->FireDocLoadEvents(nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_COMPLETE);
|
||||
}
|
||||
nsRefPtr<nsDocAccessible> docAcc =
|
||||
nsAccUtils::QueryAccessibleDocument(accessible);
|
||||
NS_ASSERTION(docAcc, "No doc accessible for doc load event");
|
||||
|
||||
if (docAcc)
|
||||
docAcc->FireDocLoadEvents(nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_COMPLETE);
|
||||
}
|
||||
else if (eventType == nsIAccessibleEvent::EVENT_TEXT_CARET_MOVED) {
|
||||
nsCOMPtr<nsIAccessibleText> accessibleText = do_QueryInterface(accessible);
|
||||
|
@ -1759,12 +1778,11 @@ NS_IMETHODIMP nsDocAccessible::FlushPendingEvents()
|
|||
nsAccEvent::ResetLastInputState();
|
||||
|
||||
mInFlushPendingEvents = PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void nsDocAccessible::FlushEventsCallback(nsITimer *aTimer, void *aClosure)
|
||||
{
|
||||
nsPIAccessibleDocument *accessibleDoc = static_cast<nsPIAccessibleDocument*>(aClosure);
|
||||
nsDocAccessible *accessibleDoc = static_cast<nsDocAccessible*>(aClosure);
|
||||
NS_ASSERTION(accessibleDoc, "How did we get here without an accessible document?");
|
||||
if (accessibleDoc) {
|
||||
// A lot of crashes were happening here, so now we're reffing the doc
|
||||
|
@ -1880,8 +1898,9 @@ void nsDocAccessible::RefreshNodes(nsIDOMNode *aStartNode)
|
|||
mAccessNodeCache.Remove(uniqueID);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsDocAccessible::InvalidateCacheSubtree(nsIContent *aChild,
|
||||
PRUint32 aChangeEventType)
|
||||
void
|
||||
nsDocAccessible::InvalidateCacheSubtree(nsIContent *aChild,
|
||||
PRUint32 aChangeEventType)
|
||||
{
|
||||
PRBool isHiding =
|
||||
aChangeEventType == nsIAccessibleEvent::EVENT_ASYNCH_HIDE ||
|
||||
|
@ -1908,11 +1927,12 @@ NS_IMETHODIMP nsDocAccessible::InvalidateCacheSubtree(nsIContent *aChild,
|
|||
// instead of just the accessible tree, although that would be faster
|
||||
// Otherwise we might miss the nsAccessNode's that are not nsAccessible's.
|
||||
|
||||
NS_ENSURE_TRUE(mDOMNode, NS_ERROR_FAILURE);
|
||||
NS_ENSURE_TRUE(mDOMNode,);
|
||||
|
||||
nsCOMPtr<nsIDOMNode> childNode = aChild ? do_QueryInterface(aChild) : mDOMNode;
|
||||
|
||||
nsCOMPtr<nsIPresShell> presShell = GetPresShell();
|
||||
NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE);
|
||||
NS_ENSURE_TRUE(presShell,);
|
||||
|
||||
if (!mIsContentLoaded) {
|
||||
// Still loading document
|
||||
|
@ -1925,10 +1945,12 @@ NS_IMETHODIMP nsDocAccessible::InvalidateCacheSubtree(nsIContent *aChild,
|
|||
// Leave early, and ensure mAccChildCount stays uninitialized instead of 0,
|
||||
// which it is if anyone asks for its children right now.
|
||||
InvalidateChildren();
|
||||
return NS_OK;
|
||||
return;
|
||||
}
|
||||
|
||||
nsIEventStateManager *esm = presShell->GetPresContext()->EventStateManager();
|
||||
NS_ENSURE_TRUE(esm, NS_ERROR_FAILURE);
|
||||
NS_ENSURE_TRUE(esm,);
|
||||
|
||||
if (!esm->IsHandlingUserInputExternal()) {
|
||||
// Changes during page load, but not caused by user input
|
||||
// Just invalidate accessible hierarchy and return,
|
||||
|
@ -1942,7 +1964,7 @@ NS_IMETHODIMP nsDocAccessible::InvalidateCacheSubtree(nsIContent *aChild,
|
|||
nsRefPtr<nsAccessible> containerAcc =
|
||||
nsAccUtils::QueryAccessible(containerAccessible);
|
||||
containerAcc->InvalidateChildren();
|
||||
return NS_OK;
|
||||
return;
|
||||
}
|
||||
// else: user input, so we must fall through and for full handling,
|
||||
// e.g. fire the mutation events. Note: user input could cause DOM_CREATE
|
||||
|
@ -1998,7 +2020,7 @@ NS_IMETHODIMP nsDocAccessible::InvalidateCacheSubtree(nsIContent *aChild,
|
|||
// This often happens when visibility is cleared for node,
|
||||
// which hides an entire subtree -- we get notified for each
|
||||
// node in the subtree and need to collate the hide events ourselves.
|
||||
return NS_OK;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2010,7 +2032,8 @@ NS_IMETHODIMP nsDocAccessible::InvalidateCacheSubtree(nsIContent *aChild,
|
|||
// Fire an event if the accessible existed for node being hidden, otherwise
|
||||
// for the first line accessible descendants. Fire before the accessible(s) away.
|
||||
nsresult rv = FireShowHideEvents(childNode, PR_FALSE, removalEventType, PR_TRUE, PR_FALSE);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
NS_ENSURE_SUCCESS(rv,);
|
||||
|
||||
if (childNode != mDOMNode) { // Fire text change unless the node being removed is for this doc
|
||||
// When a node is hidden or removed, the text in an ancestor hyper text will lose characters
|
||||
// At this point we still have the frame and accessible for this node if there was one
|
||||
|
@ -2102,11 +2125,9 @@ NS_IMETHODIMP nsDocAccessible::InvalidateCacheSubtree(nsIContent *aChild,
|
|||
new nsAccReorderEvent(containerAccessible, isAsynch,
|
||||
isUnconditionalEvent,
|
||||
aChild ? childNode.get() : nsnull);
|
||||
NS_ENSURE_TRUE(reorderEvent, NS_ERROR_OUT_OF_MEMORY);
|
||||
NS_ENSURE_TRUE(reorderEvent,);
|
||||
|
||||
FireDelayedAccessibleEvent(reorderEvent);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
|
|
@ -41,7 +41,6 @@
|
|||
|
||||
#include "nsHyperTextAccessibleWrap.h"
|
||||
#include "nsIAccessibleDocument.h"
|
||||
#include "nsPIAccessibleDocument.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIDocumentObserver.h"
|
||||
#include "nsIEditor.h"
|
||||
|
@ -56,9 +55,16 @@ class nsIScrollableView;
|
|||
|
||||
const PRUint32 kDefaultCacheSize = 256;
|
||||
|
||||
#define NS_DOCACCESSIBLE_IMPL_CID \
|
||||
{ /* 0ed1be1d-52a7-4bfd-b4f5-0de7caed4617 */ \
|
||||
0x0ed1be1d, \
|
||||
0x52a7, \
|
||||
0x4bfd, \
|
||||
{ 0xb4, 0xf5, 0x0d, 0xe7, 0xca, 0xed, 0x46, 0x17 } \
|
||||
}
|
||||
|
||||
class nsDocAccessible : public nsHyperTextAccessibleWrap,
|
||||
public nsIAccessibleDocument,
|
||||
public nsPIAccessibleDocument,
|
||||
public nsIDocumentObserver,
|
||||
public nsIObserver,
|
||||
public nsIScrollPositionListener,
|
||||
|
@ -68,73 +74,119 @@ class nsDocAccessible : public nsHyperTextAccessibleWrap,
|
|||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsDocAccessible, nsAccessible)
|
||||
|
||||
NS_DECL_NSIACCESSIBLEDOCUMENT
|
||||
NS_DECL_NSPIACCESSIBLEDOCUMENT
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_DOCACCESSIBLE_IMPL_CID)
|
||||
|
||||
NS_DECL_NSIOBSERVER
|
||||
|
||||
public:
|
||||
nsDocAccessible(nsIDOMNode *aNode, nsIWeakReference* aShell);
|
||||
virtual ~nsDocAccessible();
|
||||
public:
|
||||
nsDocAccessible(nsIDOMNode *aNode, nsIWeakReference* aShell);
|
||||
virtual ~nsDocAccessible();
|
||||
|
||||
// nsIAccessible
|
||||
NS_IMETHOD GetName(nsAString& aName);
|
||||
NS_IMETHOD GetDescription(nsAString& aDescription);
|
||||
NS_IMETHOD GetAttributes(nsIPersistentProperties **aAttributes);
|
||||
NS_IMETHOD GetFocusedChild(nsIAccessible **aFocusedChild);
|
||||
NS_IMETHOD GetParent(nsIAccessible **aParent);
|
||||
NS_IMETHOD TakeFocus(void);
|
||||
// nsIAccessible
|
||||
NS_IMETHOD GetName(nsAString& aName);
|
||||
NS_IMETHOD GetDescription(nsAString& aDescription);
|
||||
NS_IMETHOD GetAttributes(nsIPersistentProperties **aAttributes);
|
||||
NS_IMETHOD GetFocusedChild(nsIAccessible **aFocusedChild);
|
||||
NS_IMETHOD GetParent(nsIAccessible **aParent);
|
||||
NS_IMETHOD TakeFocus(void);
|
||||
|
||||
// ----- nsIScrollPositionListener ---------------------------
|
||||
NS_IMETHOD ScrollPositionWillChange(nsIScrollableView *aView, nscoord aX, nscoord aY);
|
||||
virtual void ViewPositionDidChange(nsIScrollableView* aScrollable) {}
|
||||
NS_IMETHOD ScrollPositionDidChange(nsIScrollableView *aView, nscoord aX, nscoord aY);
|
||||
// nsIScrollPositionListener
|
||||
NS_IMETHOD ScrollPositionWillChange(nsIScrollableView *aView,
|
||||
nscoord aX, nscoord aY);
|
||||
virtual void ViewPositionDidChange(nsIScrollableView* aScrollable) {}
|
||||
NS_IMETHOD ScrollPositionDidChange(nsIScrollableView *aView,
|
||||
nscoord aX, nscoord aY);
|
||||
|
||||
// nsIDocumentObserver
|
||||
NS_DECL_NSIDOCUMENTOBSERVER
|
||||
// nsIDocumentObserver
|
||||
NS_DECL_NSIDOCUMENTOBSERVER
|
||||
|
||||
static void FlushEventsCallback(nsITimer *aTimer, void *aClosure);
|
||||
// nsAccessNode
|
||||
virtual nsresult Init();
|
||||
virtual nsresult Shutdown();
|
||||
virtual nsIFrame* GetFrame();
|
||||
virtual PRBool IsDefunct();
|
||||
|
||||
// nsAccessNode
|
||||
virtual nsresult Init();
|
||||
virtual nsresult Shutdown();
|
||||
virtual nsIFrame* GetFrame();
|
||||
|
||||
// nsAccessible
|
||||
// nsAccessible
|
||||
virtual nsresult GetRoleInternal(PRUint32 *aRole);
|
||||
virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
|
||||
virtual nsresult GetARIAState(PRUint32 *aState);
|
||||
virtual nsresult GetARIAState(PRUint32 *aState, PRUint32 *aExtraState);
|
||||
virtual void SetRoleMapEntry(nsRoleMapEntry* aRoleMapEntry);
|
||||
|
||||
// nsIAccessibleText
|
||||
NS_IMETHOD GetAssociatedEditor(nsIEditor **aEditor);
|
||||
// nsIAccessibleText
|
||||
NS_IMETHOD GetAssociatedEditor(nsIEditor **aEditor);
|
||||
|
||||
/**
|
||||
* Non-virtual method to fire a delayed event after a 0 length timeout
|
||||
*
|
||||
* @param aEvent - the nsIAccessibleEvent event type
|
||||
* @param aDOMNode - DOM node the accesible event should be fired for
|
||||
* @param aAllowDupes - eAllowDupes: more than one event of the same type is allowed.
|
||||
* eCoalesceFromSameSubtree: if two events are in the same subtree,
|
||||
* only the event on ancestor is used
|
||||
* eRemoveDupes (default): events of the same type are discarded
|
||||
* (the last one is used)
|
||||
*
|
||||
* @param aIsAsynch - set to PR_TRUE if this is not being called from code
|
||||
* synchronous with a DOM event
|
||||
*/
|
||||
nsresult FireDelayedToolkitEvent(PRUint32 aEvent, nsIDOMNode *aDOMNode,
|
||||
nsAccEvent::EEventRule aAllowDupes = nsAccEvent::eRemoveDupes,
|
||||
PRBool aIsAsynch = PR_FALSE);
|
||||
// nsDocAccessible
|
||||
|
||||
/**
|
||||
* Fire accessible event in timeout.
|
||||
*
|
||||
* @param aEvent - the event to fire
|
||||
*/
|
||||
nsresult FireDelayedAccessibleEvent(nsIAccessibleEvent *aEvent);
|
||||
/**
|
||||
* Non-virtual method to fire a delayed event after a 0 length timeout.
|
||||
*
|
||||
* @param aEvent [in] the nsIAccessibleEvent event type
|
||||
* @param aDOMNode [in] DOM node the accesible event should be fired for
|
||||
* @param aAllowDupes [in] rule to process an event (see EEventRule constants)
|
||||
* @param aIsAsynch [in] set to PR_TRUE if this is not being called from
|
||||
* code synchronous with a DOM event
|
||||
*/
|
||||
nsresult FireDelayedToolkitEvent(PRUint32 aEvent, nsIDOMNode *aDOMNode,
|
||||
nsAccEvent::EEventRule aAllowDupes = nsAccEvent::eRemoveDupes,
|
||||
PRBool aIsAsynch = PR_FALSE);
|
||||
|
||||
void ShutdownChildDocuments(nsIDocShellTreeItem *aStart);
|
||||
/**
|
||||
* Fire accessible event after timeout.
|
||||
*
|
||||
* @param aEvent [in] the event to fire
|
||||
*/
|
||||
nsresult FireDelayedAccessibleEvent(nsIAccessibleEvent *aEvent);
|
||||
|
||||
/**
|
||||
* Find the accessible object in the accessibility cache that corresponds to
|
||||
* the given node or the first ancestor of it that has an accessible object
|
||||
* associated with it. Clear that accessible object's parent's cache of
|
||||
* accessible children and remove the accessible object and any descendants
|
||||
* from the accessible cache. Fires proper events. New accessible objects will
|
||||
* be created and cached again on demand.
|
||||
*
|
||||
* @param aContent [in] the child that is changing
|
||||
* @param aEvent [in] the event from nsIAccessibleEvent that caused
|
||||
* the change.
|
||||
*/
|
||||
void InvalidateCacheSubtree(nsIContent *aContent, PRUint32 aEvent);
|
||||
|
||||
/**
|
||||
* Cache access node.
|
||||
*
|
||||
* @param aUniquID [in] the unique identifier of accessible
|
||||
* @param aAccessNode [in] accessible to cache
|
||||
*/
|
||||
void CacheAccessNode(void *aUniqueID, nsIAccessNode *aAccessNode);
|
||||
|
||||
/**
|
||||
* Fires pending events.
|
||||
*/
|
||||
void FlushPendingEvents();
|
||||
|
||||
/**
|
||||
* Fire document load events.
|
||||
*
|
||||
* @param aEventType [in] nsIAccessibleEvent constant
|
||||
*/
|
||||
virtual void FireDocLoadEvents(PRUint32 aEventType);
|
||||
|
||||
/**
|
||||
* Process the case when anchor was clicked.
|
||||
*/
|
||||
virtual void FireAnchorJumpEvent();
|
||||
|
||||
/**
|
||||
* Used to flush pending events, called after timeout. See FlushPendingEvents.
|
||||
*/
|
||||
static void FlushEventsCallback(nsITimer *aTimer, void *aClosure);
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Iterates through sub documents and shut them down.
|
||||
*/
|
||||
void ShutdownChildDocuments(nsIDocShellTreeItem *aStart);
|
||||
|
||||
protected:
|
||||
virtual void GetBoundsRect(nsRect& aRect, nsIFrame** aRelativeFrame);
|
||||
virtual nsresult AddEventListeners();
|
||||
virtual nsresult RemoveEventListeners();
|
||||
|
@ -230,4 +282,7 @@ protected:
|
|||
static nsIAtom *gLastFocusedFrameType;
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsDocAccessible,
|
||||
NS_DOCACCESSIBLE_IMPL_CID)
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1070,27 +1070,26 @@ nsRootAccessible::GetRelationByType(PRUint32 aRelationType,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsRootAccessible::FireDocLoadEvents(PRUint32 aEventType)
|
||||
void
|
||||
nsRootAccessible::FireDocLoadEvents(PRUint32 aEventType)
|
||||
{
|
||||
if (!mDocument || !mWeakShell) {
|
||||
return NS_OK; // Document has been shut down
|
||||
}
|
||||
if (IsDefunct())
|
||||
return;
|
||||
|
||||
nsCOMPtr<nsIDocShellTreeItem> docShellTreeItem =
|
||||
nsCoreUtils::GetDocShellTreeItemFor(mDOMNode);
|
||||
NS_ASSERTION(docShellTreeItem, "No doc shell tree item for document");
|
||||
NS_ENSURE_TRUE(docShellTreeItem, NS_ERROR_FAILURE);
|
||||
if (!docShellTreeItem)
|
||||
return;
|
||||
|
||||
PRInt32 contentType;
|
||||
docShellTreeItem->GetItemType(&contentType);
|
||||
if (contentType == nsIDocShellTreeItem::typeContent) {
|
||||
return nsDocAccessibleWrap::FireDocLoadEvents(aEventType); // Content might need to fire event
|
||||
}
|
||||
if (contentType == nsIDocShellTreeItem::typeContent)
|
||||
nsDocAccessibleWrap::FireDocLoadEvents(aEventType); // Content might need to fire event
|
||||
|
||||
// Root chrome: don't fire event
|
||||
mIsContentLoaded = (aEventType == nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_COMPLETE ||
|
||||
aEventType == nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_STOPPED);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
|
|
@ -69,33 +69,32 @@ class nsRootAccessible : public nsDocAccessibleWrap,
|
|||
{
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
public:
|
||||
nsRootAccessible(nsIDOMNode *aDOMNode, nsIWeakReference* aShell);
|
||||
virtual ~nsRootAccessible();
|
||||
public:
|
||||
nsRootAccessible(nsIDOMNode *aDOMNode, nsIWeakReference* aShell);
|
||||
virtual ~nsRootAccessible();
|
||||
|
||||
// nsIAccessible
|
||||
NS_IMETHOD GetName(nsAString& aName);
|
||||
NS_IMETHOD GetParent(nsIAccessible * *aParent);
|
||||
NS_IMETHOD GetRelationByType(PRUint32 aRelationType,
|
||||
nsIAccessibleRelation **aRelation);
|
||||
// nsIAccessible
|
||||
NS_IMETHOD GetName(nsAString& aName);
|
||||
NS_IMETHOD GetParent(nsIAccessible * *aParent);
|
||||
NS_IMETHOD GetRelationByType(PRUint32 aRelationType,
|
||||
nsIAccessibleRelation **aRelation);
|
||||
|
||||
// ----- nsPIAccessibleDocument -----------------------
|
||||
NS_IMETHOD FireDocLoadEvents(PRUint32 aEventType);
|
||||
// nsIDOMEventListener
|
||||
NS_IMETHOD HandleEvent(nsIDOMEvent* aEvent);
|
||||
|
||||
// ----- nsIDOMEventListener --------------------------
|
||||
NS_IMETHOD HandleEvent(nsIDOMEvent* aEvent);
|
||||
// nsAccessNode
|
||||
virtual nsresult Init();
|
||||
virtual nsresult Shutdown();
|
||||
|
||||
// nsAccessNode
|
||||
virtual nsresult Init();
|
||||
virtual nsresult Shutdown();
|
||||
// nsAccessible
|
||||
virtual nsresult GetRoleInternal(PRUint32 *aRole);
|
||||
virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
|
||||
|
||||
// nsAccessible
|
||||
virtual nsresult GetRoleInternal(PRUint32 *aRole);
|
||||
virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
|
||||
// nsDocAccessible
|
||||
virtual void FireDocLoadEvents(PRUint32 aEventType);
|
||||
|
||||
void ShutdownAll();
|
||||
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_ROOTACCESSIBLE_IMPL_CID)
|
||||
// nsRootAccessible
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_ROOTACCESSIBLE_IMPL_CID)
|
||||
|
||||
/**
|
||||
* Fire an accessible focus event for the current focusAccssible
|
||||
|
|
|
@ -296,7 +296,7 @@ nsHTMLButtonAccessible::GetRoleInternal(PRUint32 *aRole)
|
|||
nsresult
|
||||
nsHTMLButtonAccessible::GetNameInternal(nsAString& aName)
|
||||
{
|
||||
nsresult rv = nsAccessible::GetNameInternal(aName);
|
||||
nsAccessible::GetNameInternal(aName);
|
||||
if (!aName.IsEmpty())
|
||||
return NS_OK;
|
||||
|
||||
|
|
|
@ -1389,7 +1389,7 @@ NS_IMETHODIMP nsHTMLTableAccessible::IsProbablyForLayout(PRBool *aIsProbablyForL
|
|||
PRUint32 length;
|
||||
nodeList->GetLength(&length);
|
||||
nsAutoString color, lastRowColor;
|
||||
for (PRInt32 rowCount = 0; rowCount < length; rowCount ++) {
|
||||
for (PRUint32 rowCount = 0; rowCount < length; rowCount ++) {
|
||||
nsCOMPtr<nsIDOMNode> rowNode;
|
||||
nodeList->Item(rowCount, getter_AddRefs(rowNode));
|
||||
|
||||
|
|
|
@ -161,7 +161,8 @@ __try {
|
|||
return E_FAIL;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsDocAccessibleWrap::FireAnchorJumpEvent()
|
||||
void
|
||||
nsDocAccessibleWrap::FireAnchorJumpEvent()
|
||||
{
|
||||
// Staying on the same page, jumping to a named anchor
|
||||
// Fire EVENT_SCROLLING_START on first leaf accessible -- because some
|
||||
|
@ -171,19 +172,19 @@ NS_IMETHODIMP nsDocAccessibleWrap::FireAnchorJumpEvent()
|
|||
// we have to move forward in the document to get one
|
||||
nsDocAccessible::FireAnchorJumpEvent();
|
||||
if (!mIsAnchorJumped)
|
||||
return NS_OK;
|
||||
return;
|
||||
|
||||
nsCOMPtr<nsIDOMNode> focusNode;
|
||||
if (mIsAnchor) {
|
||||
nsCOMPtr<nsISelectionController> selCon(do_QueryReferent(mWeakShell));
|
||||
if (!selCon) {
|
||||
return NS_OK;
|
||||
}
|
||||
if (!selCon)
|
||||
return;
|
||||
|
||||
nsCOMPtr<nsISelection> domSel;
|
||||
selCon->GetSelection(nsISelectionController::SELECTION_NORMAL, getter_AddRefs(domSel));
|
||||
if (!domSel) {
|
||||
return NS_OK;
|
||||
}
|
||||
if (!domSel)
|
||||
return;
|
||||
|
||||
domSel->GetFocusNode(getter_AddRefs(focusNode));
|
||||
}
|
||||
else {
|
||||
|
@ -193,8 +194,6 @@ NS_IMETHODIMP nsDocAccessibleWrap::FireAnchorJumpEvent()
|
|||
nsCOMPtr<nsIAccessible> accessible = GetFirstAvailableAccessible(focusNode, PR_TRUE);
|
||||
nsAccUtils::FireAccEvent(nsIAccessibleEvent::EVENT_SCROLLING_START,
|
||||
accessible);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP nsDocAccessibleWrap::get_URL(/* [out] */ BSTR __RPC_FAR *aURL)
|
||||
|
|
|
@ -92,7 +92,7 @@ public:
|
|||
/* [optional][in] */ VARIANT varChild,
|
||||
/* [retval][out] */ BSTR __RPC_FAR *pszValue);
|
||||
|
||||
NS_IMETHOD FireAnchorJumpEvent();
|
||||
virtual void FireAnchorJumpEvent();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -872,6 +872,18 @@ already_AddRefed<nsIDOMNode> nsXULTextFieldAccessible::GetInputField()
|
|||
return inputField;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsXULTextFieldAccessible::GetARIAState(PRUint32 *aState, PRUint32 *aExtraState)
|
||||
{
|
||||
nsresult rv = nsHyperTextAccessibleWrap::GetARIAState(aState, aExtraState);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
|
||||
nsStateMapEntry::MapToStates(content, aState, aExtraState, eARIAAutoComplete);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsXULTextFieldAccessible::GetStateInternal(PRUint32 *aState,
|
||||
PRUint32 *aExtraState)
|
||||
|
|
|
@ -204,6 +204,7 @@ public:
|
|||
NS_IMETHOD GetAssociatedEditor(nsIEditor **aEditor);
|
||||
|
||||
// nsAccessible
|
||||
virtual nsresult GetARIAState(PRUint32 *aState, PRUint32 *aExtraState);
|
||||
virtual nsresult GetRoleInternal(PRUint32 *aRole);
|
||||
virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
|
||||
virtual PRBool GetAllowsAnonChildAccessibles();
|
||||
|
|
|
@ -48,7 +48,7 @@ include $(topsrcdir)/config/rules.mk
|
|||
_TEST_FILES =\
|
||||
letters.gif \
|
||||
moz.png \
|
||||
$(topsrcdir)/content/media/video/test/bug461281.ogg \
|
||||
$(topsrcdir)/content/media/test/bug461281.ogg \
|
||||
longdesc_src.html \
|
||||
actions.js \
|
||||
attributes.js \
|
||||
|
|
|
@ -49,6 +49,7 @@ const nsIPropertyElement = Components.interfaces.nsIPropertyElement;
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// States
|
||||
|
||||
const STATE_BUSY = nsIAccessibleStates.STATE_BUSY;
|
||||
const STATE_CHECKED = nsIAccessibleStates.STATE_CHECKED;
|
||||
const STATE_CHECKABLE = nsIAccessibleStates.STATE_CHECKABLE;
|
||||
const STATE_COLLAPSED = nsIAccessibleStates.STATE_COLLAPSED;
|
||||
|
@ -57,12 +58,14 @@ const STATE_EXTSELECTABLE = nsIAccessibleStates.STATE_EXTSELECTABLE;
|
|||
const STATE_FOCUSABLE = nsIAccessibleStates.STATE_FOCUSABLE;
|
||||
const STATE_FOCUSED = nsIAccessibleStates.STATE_FOCUSED;
|
||||
const STATE_HASPOPUP = nsIAccessibleStates.STATE_HASPOPUP;
|
||||
const STATE_INVALID = nsIAccessibleStates.STATE_INVALID;
|
||||
const STATE_LINKED = nsIAccessibleStates.STATE_LINKED;
|
||||
const STATE_MIXED = nsIAccessibleStates.STATE_MIXED;
|
||||
const STATE_MULTISELECTABLE = nsIAccessibleStates.STATE_MULTISELECTABLE;
|
||||
const STATE_OFFSCREEN = nsIAccessibleStates.STATE_OFFSCREEN;
|
||||
const STATE_PRESSED = nsIAccessibleStates.STATE_PRESSED;
|
||||
const STATE_READONLY = nsIAccessibleStates.STATE_READONLY;
|
||||
const STATE_REQUIRED = nsIAccessibleStates.STATE_REQUIRED;
|
||||
const STATE_SELECTABLE = nsIAccessibleStates.STATE_SELECTABLE;
|
||||
const STATE_SELECTED = nsIAccessibleStates.STATE_SELECTED;
|
||||
const STATE_TRAVERSED = nsIAccessibleStates.STATE_TRAVERSED;
|
||||
|
@ -71,9 +74,8 @@ const STATE_UNAVAILABLE = nsIAccessibleStates.STATE_UNAVAILABLE;
|
|||
const EXT_STATE_EDITABLE = nsIAccessibleStates.EXT_STATE_EDITABLE;
|
||||
const EXT_STATE_EXPANDABLE = nsIAccessibleStates.EXT_STATE_EXPANDABLE;
|
||||
const EXT_STATE_HORIZONTAL = nsIAccessibleStates.EXT_STATE_HORIZONTAL;
|
||||
const EXT_STATE_INVALID = nsIAccessibleStates.STATE_INVALID;
|
||||
const EXT_STATE_MULTI_LINE = nsIAccessibleStates.EXT_STATE_MULTI_LINE;
|
||||
const EXT_STATE_REQUIRED = nsIAccessibleStates.STATE_REQUIRED;
|
||||
const EXT_STATE_SINGLE_LINE = nsIAccessibleStates.EXT_STATE_SINGLE_LINE;
|
||||
const EXT_STATE_SUPPORTS_AUTOCOMPLETION =
|
||||
nsIAccessibleStates.EXT_STATE_SUPPORTS_AUTOCOMPLETION;
|
||||
|
||||
|
@ -108,7 +110,7 @@ function addA11yLoadEvent(aFunc)
|
|||
var accDoc = getAccessible(document);
|
||||
var state = {};
|
||||
accDoc.getState(state, {});
|
||||
if (state.value & nsIAccessibleStates.STATE_BUSY)
|
||||
if (state.value & STATE_BUSY)
|
||||
return waitForDocLoad();
|
||||
|
||||
aFunc.call();
|
||||
|
@ -326,9 +328,12 @@ function statesToString(aStates, aExtraStates)
|
|||
var list = gAccRetrieval.getStringStates(aStates, aExtraStates);
|
||||
|
||||
var str = "";
|
||||
for (var index = 0; index < list.length; index++)
|
||||
for (var index = 0; index < list.length - 1; index++)
|
||||
str += list.item(index) + ", ";
|
||||
|
||||
if (list.length != 0)
|
||||
str += list.item(index)
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,11 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Helper functions for accessible states testing.
|
||||
//
|
||||
// requires:
|
||||
// common.js
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Tests the states and extra states of the given accessible.
|
||||
* Also tests for unwanted states and extra states.
|
||||
|
@ -17,55 +25,73 @@ function testStates(aAccOrElmOrID, aState, aExtraState, aAbsentState,
|
|||
|
||||
var id = prettyName(aAccOrElmOrID);
|
||||
|
||||
is(state & aState, aState,
|
||||
"wrong state bits for " + id + "!");
|
||||
// Primary test.
|
||||
isState(state & aState, aState, false,
|
||||
"wrong state bits for " + id + "!");
|
||||
|
||||
if (aExtraState)
|
||||
is(extraState & aExtraState, aExtraState,
|
||||
"wrong extra state bits for " + id + "!");
|
||||
isState(extraState & aExtraState, aExtraState, true,
|
||||
"wrong extra state bits for " + id + "!");
|
||||
|
||||
if (aAbsentState)
|
||||
is(state & aAbsentState, 0,
|
||||
"state bits should not be present in ID " + id + "!");
|
||||
isState(state & aAbsentState, 0, false,
|
||||
"state bits should not be present in ID " + id + "!");
|
||||
|
||||
if (aAbsentExtraState)
|
||||
is(extraState & aAbsentExtraState, 0,
|
||||
"extraState bits should not be present in ID " + id + "!");
|
||||
isState(extraState & aAbsentExtraState, 0, true,
|
||||
"extraState bits should not be present in ID " + id + "!");
|
||||
|
||||
// Additional test.
|
||||
|
||||
// readonly/editable
|
||||
if (state & STATE_READONLY)
|
||||
is(extraState & EXT_STATE_EDITABLE, 0,
|
||||
"Read-only " + id + " cannot be editable!");
|
||||
isState(extraState & EXT_STATE_EDITABLE, 0, true,
|
||||
"Read-only " + id + " cannot be editable!");
|
||||
|
||||
if (extraState & EXT_STATE_EDITABLE)
|
||||
is(state & STATE_READONLY, 0,
|
||||
"Editable " + id + " cannot be readonly!");
|
||||
isState(state & STATE_READONLY, 0, true,
|
||||
"Editable " + id + " cannot be readonly!");
|
||||
|
||||
// multiline/singleline
|
||||
if (extraState & EXT_STATE_MULTI_LINE)
|
||||
isState(extraState & EXT_STATE_SINGLE_LINE, 0, true,
|
||||
"Multiline " + id + " cannot be singleline!");
|
||||
|
||||
if (extraState & EXT_STATE_SINGLE_LINE)
|
||||
isState(extraState & EXT_STATE_MULTI_LINE, 0, true,
|
||||
"Singleline " + id + " cannot be multiline!");
|
||||
|
||||
// expanded/collapsed/expandable
|
||||
if (state & STATE_COLLAPSED || state & STATE_EXPANDED)
|
||||
is(extraState & EXT_STATE_EXPANDABLE, EXT_STATE_EXPANDABLE,
|
||||
"Collapsed or expanded " + id + " should be expandable!");
|
||||
isState(extraState & EXT_STATE_EXPANDABLE, EXT_STATE_EXPANDABLE, true,
|
||||
"Collapsed or expanded " + id + " should be expandable!");
|
||||
|
||||
if (state & STATE_COLLAPSED)
|
||||
is(state & STATE_EXPANDED, 0,
|
||||
"Collapsed " + id + " cannot be expanded!");
|
||||
isState(state & STATE_EXPANDED, 0, false,
|
||||
"Collapsed " + id + " cannot be expanded!");
|
||||
|
||||
if (state & STATE_EXPANDED)
|
||||
is(state & STATE_COLLAPSED, 0,
|
||||
"Expanded " + id + " cannot be collapsed!");
|
||||
isState(state & STATE_COLLAPSED, 0, false,
|
||||
"Expanded " + id + " cannot be collapsed!");
|
||||
|
||||
// checked/mixed/checkable
|
||||
if (state & STATE_CHECKED || state & STATE_MIXED)
|
||||
is(state & STATE_CHECKABLE, STATE_CHECKABLE,
|
||||
"Checked or mixed element must be checkable!");
|
||||
isState(state & STATE_CHECKABLE, STATE_CHECKABLE, false,
|
||||
"Checked or mixed element must be checkable!");
|
||||
|
||||
if (state & STATE_CHECKED)
|
||||
is(state & STATE_MIXED, 0, "Checked element cannot be state mixed!");
|
||||
isState(state & STATE_MIXED, 0, false,
|
||||
"Checked element cannot be state mixed!");
|
||||
|
||||
if (state & STATE_MIXED)
|
||||
is(state & STATE_CHECKED, 0, "Mixed element cannot be state checked!");
|
||||
isState(state & STATE_CHECKED, 0, false,
|
||||
"Mixed element cannot be state checked!");
|
||||
|
||||
// unavailable
|
||||
if ((state & STATE_UNAVAILABLE)
|
||||
&& (getRole(aAccOrElmOrID) != ROLE_GROUPING))
|
||||
is(state & STATE_FOCUSABLE, STATE_FOCUSABLE,
|
||||
"Disabled " + id + " must be focusable!");
|
||||
isState(state & STATE_FOCUSABLE, STATE_FOCUSABLE, false,
|
||||
"Disabled " + id + " must be focusable!");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -122,3 +148,31 @@ function getStates(aAccOrElmOrID)
|
|||
|
||||
return [state.value, extraState.value];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Private implementation details
|
||||
|
||||
/**
|
||||
* Analogy of SimpleTest.is function used to compare states.
|
||||
*/
|
||||
function isState(aState1, aState2, aIsExtraStates, aMsg)
|
||||
{
|
||||
if (aState1 == aState2) {
|
||||
ok(true, aMsg);
|
||||
return;
|
||||
}
|
||||
|
||||
var got = "0";
|
||||
if (aState1) {
|
||||
got = statesToString(aIsExtraStates ? 0 : aState1,
|
||||
aIsExtraStates ? aState1 : 0);
|
||||
}
|
||||
|
||||
var expected = "0";
|
||||
if (aState2) {
|
||||
expected = statesToString(aIsExtraStates ? 0 : aState2,
|
||||
aIsExtraStates ? aState2 : 0);
|
||||
}
|
||||
|
||||
ok(false, aMsg + "got '" + got + "', expected '" + expected + "'");
|
||||
}
|
||||
|
|
|
@ -22,25 +22,25 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=452388
|
|||
<script type="application/javascript">
|
||||
function doTest()
|
||||
{
|
||||
// test (treeitem) selectable and selected states
|
||||
testStates("treeitem_selected_true", (STATE_SELECTABLE | STATE_SELECTED));
|
||||
testStates("treeitem_selected_false", STATE_SELECTABLE, 0, STATE_SELECTED);
|
||||
testStates("treeitem_selected_empty", 0, 0, (STATE_SELECTABLE | STATE_SELECTED));
|
||||
testStates("treeitem_selected_undefined", 0, 0, (STATE_SELECTABLE | STATE_SELECTED));
|
||||
testStates("treeitem_selected_absent", 0, 0, (STATE_SELECTABLE | STATE_SELECTED));
|
||||
// test aria-pressed state mapping to roles PUSHBUTTON vs TOGGLEBUTTON
|
||||
testRole("button_pressed_true", ROLE_TOGGLE_BUTTON);
|
||||
testRole("button_pressed_false", ROLE_TOGGLE_BUTTON);
|
||||
testRole("button_pressed_empty", ROLE_PUSHBUTTON);
|
||||
testRole("button_pressed_undefined", ROLE_PUSHBUTTON);
|
||||
testRole("button_pressed_absent", ROLE_PUSHBUTTON);
|
||||
|
||||
// test (menuitem) checkable and checked states
|
||||
testStates("menuitem_checked_true", (STATE_CHECKABLE | STATE_CHECKED));
|
||||
testStates("menuitem_checked_false", STATE_CHECKABLE, 0, STATE_CHECKED);
|
||||
testStates("menuitem_checked_empty", 0, 0, (STATE_CHECKABLE | STATE_CHECKED));
|
||||
testStates("menuitem_checked_undefined", 0, 0, (STATE_CHECKABLE | STATE_CHECKED));
|
||||
testStates("menuitem_checked_absent", 0, 0, (STATE_CHECKABLE | STATE_CHECKED));
|
||||
// test button aria-pressed states
|
||||
testStates("button_pressed_true", STATE_PRESSED | STATE_CHECKABLE);
|
||||
testStates("button_pressed_false", STATE_CHECKABLE, 0, STATE_PRESSED);
|
||||
testStates("button_pressed_empty", 0, 0, STATE_PRESSED | STATE_CHECKABLE);
|
||||
testStates("button_pressed_undefined", 0, 0, STATE_PRESSED | STATE_CHECKABLE);
|
||||
testStates("button_pressed_absent", 0, 0, STATE_PRESSED | STATE_CHECKABLE);
|
||||
|
||||
// test (checkbox) checkable and checked states
|
||||
testStates("checkbox_checked_true", (STATE_CHECKABLE | STATE_CHECKED));
|
||||
testStates("checkbox_checked_false", STATE_CHECKABLE, 0, STATE_CHECKED);
|
||||
testStates("checkbox_checked_empty", STATE_CHECKABLE, 0, STATE_CHECKED);
|
||||
testStates("checkbox_checked_undefined", STATE_CHECKABLE, 0, STATE_CHECKED);
|
||||
testStates("checkbox_checked_empty", 0 , 0, STATE_CHECKABLE | STATE_CHECKED);
|
||||
testStates("checkbox_checked_undefined", 0, 0, STATE_CHECKABLE | STATE_CHECKED);
|
||||
testStates("checkbox_checked_absent", STATE_CHECKABLE, 0, STATE_CHECKED);
|
||||
|
||||
// test native checkbox checked state and aria-checked state (if conflict, native wins)
|
||||
|
@ -49,27 +49,124 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=452388
|
|||
testStates("native_checkbox_nativechecked_ariaempty", (STATE_CHECKABLE | STATE_CHECKED));
|
||||
testStates("native_checkbox_nativechecked_ariaundefined", (STATE_CHECKABLE | STATE_CHECKED));
|
||||
testStates("native_checkbox_nativechecked_ariaabsent", (STATE_CHECKABLE | STATE_CHECKED));
|
||||
|
||||
|
||||
testStates("native_checkbox_nativeunchecked_ariatrue", STATE_CHECKABLE, 0, STATE_CHECKED);
|
||||
testStates("native_checkbox_nativeunchecked_ariafalse", STATE_CHECKABLE, 0, STATE_CHECKED);
|
||||
testStates("native_checkbox_nativeunchecked_ariaempty", STATE_CHECKABLE, 0, STATE_CHECKED);
|
||||
testStates("native_checkbox_nativeunchecked_ariaundefined", STATE_CHECKABLE, 0, STATE_CHECKED);
|
||||
testStates("native_checkbox_nativeunchecked_ariaabsent", STATE_CHECKABLE, 0, STATE_CHECKED);
|
||||
|
||||
// test button aria-pressed states
|
||||
testStates("button_pressed_true", STATE_PRESSED | STATE_CHECKABLE);
|
||||
testStates("button_pressed_false", 0, 0, STATE_PRESSED | STATE_CHECKABLE);
|
||||
testStates("button_pressed_empty", 0, 0, STATE_PRESSED | STATE_CHECKABLE);
|
||||
testStates("button_pressed_undefined", 0, 0, STATE_PRESSED | STATE_CHECKABLE);
|
||||
testStates("button_pressed_absent", 0, 0, STATE_PRESSED | STATE_CHECKABLE);
|
||||
|
||||
// test aria-pressed state mapping to roles PUSHBUTTON vs TOGGLEBUTTON
|
||||
testRole("button_pressed_true", ROLE_TOGGLE_BUTTON);
|
||||
testRole("button_pressed_false", ROLE_TOGGLE_BUTTON);
|
||||
testRole("button_pressed_empty", ROLE_PUSHBUTTON);
|
||||
testRole("button_pressed_undefined", ROLE_PUSHBUTTON);
|
||||
testRole("button_pressed_absent", ROLE_PUSHBUTTON);
|
||||
|
||||
// test (checkbox) readonly states
|
||||
testStates("checkbox_readonly_true", STATE_READONLY);
|
||||
testStates("checkbox_readonly_false", 0, 0, STATE_READONLY);
|
||||
testStates("checkbox_readonly_empty", 0, 0, STATE_READONLY);
|
||||
testStates("checkbox_readonly_undefined", 0, 0, STATE_READONLY);
|
||||
testStates("checkbox_readonly_absent", 0, 0, STATE_READONLY);
|
||||
|
||||
// test (checkbox) required states
|
||||
testStates("checkbox_required_true", STATE_REQUIRED);
|
||||
testStates("checkbox_required_false", 0, 0, STATE_REQUIRED);
|
||||
testStates("checkbox_required_empty", 0, 0, STATE_REQUIRED);
|
||||
testStates("checkbox_required_undefined", 0, 0, STATE_REQUIRED);
|
||||
testStates("checkbox_required_absent", 0, 0, STATE_REQUIRED);
|
||||
|
||||
// test (checkbox) invalid states
|
||||
testStates("checkbox_invalid_true", STATE_INVALID);
|
||||
testStates("checkbox_invalid_false", 0, 0, STATE_INVALID);
|
||||
testStates("checkbox_invalid_empty", 0, 0, STATE_INVALID);
|
||||
testStates("checkbox_invalid_undefined", 0, 0, STATE_INVALID);
|
||||
testStates("checkbox_invalid_absent", 0, 0, STATE_INVALID);
|
||||
|
||||
// test (checkbox) disabled states
|
||||
testStates("checkbox_disabled_true", STATE_UNAVAILABLE);
|
||||
testStates("checkbox_disabled_false", 0, 0, STATE_UNAVAILABLE);
|
||||
testStates("checkbox_disabled_empty", 0, 0, STATE_UNAVAILABLE);
|
||||
testStates("checkbox_disabled_undefined", 0, 0, STATE_UNAVAILABLE);
|
||||
testStates("checkbox_disabled_absent", 0, 0, STATE_UNAVAILABLE);
|
||||
|
||||
// test (listbox) multiselectable states
|
||||
testStates("listbox_multiselectable_true", STATE_MULTISELECTABLE | STATE_EXTSELECTABLE);
|
||||
testStates("listbox_multiselectable_false", 0, 0, STATE_MULTISELECTABLE | STATE_EXTSELECTABLE);
|
||||
testStates("listbox_multiselectable_empty", 0, 0, STATE_MULTISELECTABLE | STATE_EXTSELECTABLE);
|
||||
testStates("listbox_multiselectable_undefined", 0, 0, STATE_MULTISELECTABLE | STATE_EXTSELECTABLE);
|
||||
testStates("listbox_multiselectable_absent", 0, 0, STATE_MULTISELECTABLE | STATE_EXTSELECTABLE);
|
||||
|
||||
// test (listitem) checkable and checked states
|
||||
testStates("listitem_checked_true", (STATE_CHECKABLE | STATE_CHECKED));
|
||||
testStates("listitem_checked_false", STATE_CHECKABLE, 0, STATE_CHECKED);
|
||||
testStates("listitem_checked_empty", 0 , 0, STATE_CHECKABLE | STATE_CHECKED);
|
||||
testStates("listitem_checked_undefined", 0, 0, STATE_CHECKABLE | STATE_CHECKED);
|
||||
testStates("listitem_checked_absent", 0, 0, STATE_CHECKABLE | STATE_CHECKED);
|
||||
|
||||
// test (menuitem) checkable and checked states
|
||||
testStates("menuitem_checked_true", (STATE_CHECKABLE | STATE_CHECKED));
|
||||
testStates("menuitem_checked_false", STATE_CHECKABLE, 0, STATE_CHECKED);
|
||||
testStates("menuitem_checked_empty", 0, 0, (STATE_CHECKABLE | STATE_CHECKED));
|
||||
testStates("menuitem_checked_undefined", 0, 0, (STATE_CHECKABLE | STATE_CHECKED));
|
||||
testStates("menuitem_checked_absent", 0, 0, (STATE_CHECKABLE | STATE_CHECKED));
|
||||
|
||||
// test (menuitemradio) checkable and checked states
|
||||
testStates("menuitemradio_checked_true", (STATE_CHECKABLE | STATE_CHECKED));
|
||||
testStates("menuitemradio_checked_false", STATE_CHECKABLE, 0, STATE_CHECKED);
|
||||
testStates("menuitemradio_checked_empty", 0, 0, (STATE_CHECKABLE | STATE_CHECKED));
|
||||
testStates("menuitemradio_checked_undefined", 0, 0, (STATE_CHECKABLE | STATE_CHECKED));
|
||||
testStates("menuitemradio_checked_absent", STATE_CHECKABLE, 0, STATE_CHECKED);
|
||||
|
||||
// test (radio) checkable and checked states
|
||||
testStates("radio_checked_true", (STATE_CHECKABLE | STATE_CHECKED));
|
||||
testStates("radio_checked_false", STATE_CHECKABLE, 0, STATE_CHECKED);
|
||||
testStates("radio_checked_empty", 0, 0, (STATE_CHECKABLE | STATE_CHECKED));
|
||||
testStates("radio_checked_undefined", 0, 0, (STATE_CHECKABLE | STATE_CHECKED));
|
||||
testStates("radio_checked_absent", STATE_CHECKABLE, 0, STATE_CHECKED);
|
||||
|
||||
// test (textbox) multiline states
|
||||
testStates("textbox_multiline_true", 0, EXT_STATE_MULTI_LINE);
|
||||
testStates("textbox_multiline_false", 0, EXT_STATE_SINGLE_LINE);
|
||||
testStates("textbox_multiline_empty", 0, 0, 0, EXT_STATE_SINGLE_LINE | EXT_STATE_MULTI_LINE);
|
||||
testStates("textbox_multiline_undefined", 0, 0, 0, EXT_STATE_SINGLE_LINE | EXT_STATE_MULTI_LINE);
|
||||
testStates("textbox_multiline_absent", 0, EXT_STATE_SINGLE_LINE);
|
||||
|
||||
// test (textbox) readonly states
|
||||
testStates("textbox_readonly_true", STATE_READONLY);
|
||||
testStates("textbox_readonly_false", 0, EXT_STATE_EDITABLE, STATE_READONLY);
|
||||
testStates("textbox_readonly_empty", 0, 0, STATE_READONLY, EXT_STATE_EDITABLE);
|
||||
testStates("textbox_readonly_undefined", 0, 0, STATE_READONLY, EXT_STATE_EDITABLE);
|
||||
testStates("textbox_readonly_absent", 0, EXT_STATE_EDITABLE, STATE_READONLY);
|
||||
|
||||
// test native textbox readonly state and aria-readonly state (if conflict, native wins)
|
||||
testStates("native_textbox_nativereadonly_ariatrue", STATE_READONLY);
|
||||
testStates("native_textbox_nativereadonly_ariafalse", STATE_READONLY);
|
||||
testStates("native_textbox_nativereadonly_ariaempty", STATE_READONLY);
|
||||
testStates("native_textbox_nativereadonly_ariaundefined", STATE_READONLY);
|
||||
testStates("native_textbox_nativereadonly_ariaabsent", STATE_READONLY);
|
||||
|
||||
testStates("native_textbox_nativeeditable_ariatrue", 0, 0, STATE_READONLY);
|
||||
testStates("native_textbox_nativeeditable_ariafalse", 0, 0, STATE_READONLY);
|
||||
testStates("native_textbox_nativeeditable_ariaempty", 0, 0, STATE_READONLY);
|
||||
testStates("native_textbox_nativeeditable_ariaundefined", 0, 0, STATE_READONLY);
|
||||
testStates("native_textbox_nativeeditable_ariaabsent", 0, 0, STATE_READONLY);
|
||||
|
||||
// test (treeitem) selectable and selected states
|
||||
testStates("treeitem_selected_true", (STATE_SELECTABLE | STATE_SELECTED));
|
||||
testStates("treeitem_selected_false", STATE_SELECTABLE, 0, STATE_SELECTED);
|
||||
testStates("treeitem_selected_empty", 0, 0, (STATE_SELECTABLE | STATE_SELECTED));
|
||||
testStates("treeitem_selected_undefined", 0, 0, (STATE_SELECTABLE | STATE_SELECTED));
|
||||
testStates("treeitem_selected_absent", 0, 0, (STATE_SELECTABLE | STATE_SELECTED));
|
||||
|
||||
// test (treeitem) haspopup states
|
||||
testStates("treeitem_haspopup_true", STATE_HASPOPUP);
|
||||
testStates("treeitem_haspopup_false", 0, 0, STATE_HASPOPUP);
|
||||
testStates("treeitem_haspopup_empty", 0, 0, STATE_HASPOPUP);
|
||||
testStates("treeitem_haspopup_undefined", 0, 0, STATE_HASPOPUP);
|
||||
testStates("treeitem_haspopup_absent", 0, 0, STATE_HASPOPUP);
|
||||
|
||||
// test (treeitem) expandable and expanded/collapsed states
|
||||
testStates("treeitem_expanded_true", STATE_EXPANDED, EXT_STATE_EXPANDABLE);
|
||||
testStates("treeitem_expanded_false", STATE_COLLAPSED, EXT_STATE_EXPANDABLE);
|
||||
testStates("treeitem_expanded_empty", 0, 0, STATE_EXPANDED | STATE_COLLAPSED, EXT_STATE_EXPANDABLE);
|
||||
testStates("treeitem_expanded_undefined", 0, 0, STATE_EXPANDED | STATE_COLLAPSED, EXT_STATE_EXPANDABLE);
|
||||
testStates("treeitem_expanded_absent", 0, 0, STATE_EXPANDED | STATE_COLLAPSED, EXT_STATE_EXPANDABLE);
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
|
@ -79,48 +176,151 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=452388
|
|||
</head>
|
||||
<body>
|
||||
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=452388">Mozilla Bug 452388</a>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=452388">
|
||||
Mozilla Bug 452388
|
||||
</a>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=499653"
|
||||
title="Unify ARIA state attributes mapping rules">
|
||||
Mozilla Bug 499653
|
||||
</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
<div id="treeitem_selected_true" role="treeitem" aria-selected="true">This treeitem has aria-selected="true" and should get STATE_SELECTABLE. It should also get STATE_SELECTED.</div>
|
||||
<div id="treeitem_selected_false" role="treeitem" aria-selected="false">This treeitem has aria-selected="false" and should get STATE_SELECTABLE.</div>
|
||||
<div id="treeitem_selected_empty" role="treeitem" aria-selected="">This treeitem has aria-selected="" and should <emph>not</emph> get STATE_SELECTABLE.</div>
|
||||
<div id="treeitem_selected_undefined" role="treeitem" aria-selected="undefined">This treeitem has aria-selected="undefined" and should <emph>not</emph> get STATE_SELECTABLE.</div>
|
||||
<div id="treeitem_selected_absent" role="treeitem">This treeitem has <emph>no</emph> aria-selected attribute and should <emph>not</emph> get STATE_SELECTABLE.</div>
|
||||
|
||||
<div id="menuitem_checked_true" role="menuitem" aria-checked="true">This menuitem has aria-checked="true" and should get STATE_CHECKABLE. It should also get STATE_checked.</div>
|
||||
<div id="menuitem_checked_false" role="menuitem" aria-checked="false">This menuitem has aria-checked="false" and should get STATE_CHECKABLE.</div>
|
||||
<div id="menuitem_checked_empty" role="menuitem" aria-checked="">This menuitem has aria-checked="" and should <emph>not</emph> get STATE_CHECKABLE.</div>
|
||||
<div id="menuitem_checked_undefined" role="menuitem" aria-checked="undefined">This menuitem has aria-checked="undefined" and should <emph>not</emph> get STATE_CHECKABLE.</div>
|
||||
<div id="menuitem_checked_absent" role="menuitem">This menuitem has <emph>no</emph> aria-checked attribute and should <emph>not</emph> get STATE_CHECKABLE.</div>
|
||||
|
||||
<div id="button_pressed_true" role="button" aria-pressed="true">This button has aria-pressed="true" and should get ROLE_TOGGLE_BUTTON. It should also get STATE_PRESSED.</div>
|
||||
<div id="button_pressed_false" role="button" aria-pressed="false">This button has aria-pressed="false" and should get ROLE_TOGGLE_BUTTON.</div>
|
||||
<div id="button_pressed_empty" role="button" aria-pressed="">This button has aria-pressed="" and should <emph>not</emph> get ROLE_BUTTON.</div>
|
||||
<div id="button_pressed_undefined" role="button" aria-pressed="undefined">This button has aria-pressed="undefined" and should <emph>not</emph> get ROLE_TOGGLE_BUTTON.</div>
|
||||
<div id="button_pressed_absent" role="button">This button has <emph>no</emph> aria-pressed attribute and should <emph>not</emph> get ROLE_TOGGLE_BUTTON.</div>
|
||||
|
||||
<div id="checkbox_checked_true" role="checkbox" aria-checked="true">This checkbox has aria-checked="true" and should get STATE_CHECKABLE. It should also get STATE_checked.</div>
|
||||
<div id="checkbox_checked_false" role="checkbox" aria-checked="false">This checkbox has aria-checked="false" and should get STATE_CHECKABLE.</div>
|
||||
<div id="checkbox_checked_empty" role="checkbox" aria-checked="">This checkbox has aria-checked="" and should <emph>not</emph> get STATE_CHECKABLE.</div>
|
||||
<div id="checkbox_checked_undefined" role="checkbox" aria-checked="undefined">This checkbox has aria-checked="undefined" and should <emph>not</emph> get STATE_CHECKABLE.</div>
|
||||
<div id="checkbox_checked_absent" role="checkbox">This checkbox has <emph>no</emph> aria-checked attribute and should <emph>not</emph> get STATE_CHECKABLE.</div>
|
||||
<div id="checkbox_checked_absent" role="checkbox">This checkbox has <emph>no</emph> aria-checked attribute and should get STATE_CHECKABLE.</div>
|
||||
|
||||
<form action="">
|
||||
<input id="native_checkbox_nativechecked_ariatrue" type="checkbox" checked="checked" aria-checked="true"/>
|
||||
<input id="native_checkbox_nativechecked_ariafalse" type="checkbox" checked="checked" aria-checked="false"/>
|
||||
<input id="native_checkbox_nativechecked_ariaempty" type="checkbox" checked="checked" aria-checked=""/>
|
||||
<input id="native_checkbox_nativechecked_ariaundefined" type="checkbox" checked="checked" aria-checked="undefined"/>
|
||||
<input id="native_checkbox_nativechecked_ariaabsent" type="checkbox" checked="checked" aria-checked="false"/>
|
||||
<input id="native_checkbox_nativechecked_ariaabsent" type="checkbox" checked="checked"/>
|
||||
|
||||
<input id="native_checkbox_nativeunchecked_ariatrue" type="checkbox" aria-checked="true"/>
|
||||
<input id="native_checkbox_nativeunchecked_ariafalse" type="checkbox" aria-checked="false"/>
|
||||
<input id="native_checkbox_nativeunchecked_ariaempty" type="checkbox" aria-checked=""/>
|
||||
<input id="native_checkbox_nativeunchecked_ariaundefined" type="checkbox" aria-checked="undefined"/>
|
||||
<input id="native_checkbox_nativeunchecked_ariaabsent" type="checkbox" aria-checked="false"/>
|
||||
<input id="native_checkbox_nativeunchecked_ariaabsent" type="checkbox"/>
|
||||
</form>
|
||||
|
||||
<div id="button_pressed_true" role="button" aria-pressed="true">This button has aria-pressed="true" and should get ROLE_TOGGLE_BUTTON. It should also get STATE_PRESSED.</div>
|
||||
<div id="button_pressed_false" role="button" aria-pressed="false">This button has aria-pressed="false" and should get ROLE_TOGGLE_BUTTON.</div>
|
||||
<div id="button_pressed_empty" role="button" aria-pressed="">This button has aria-pressed="" and should <emph>not</emph> get ROLE_BUTTON.</div>
|
||||
<div id="button_pressed_undefined" role="button" aria-pressed="undefined">This button has aria-pressed="undefined" and should <emph>not</emph> get ROLE_TOGGLE_BUTTON.</div>
|
||||
<div id="button_pressed_absent" role="button">This button has <emph>no</emph> aria-pressed attribute and should <emph>not</emph> get ROLE_TOGGLE_BUTTON.</div>
|
||||
|
||||
|
||||
<div id="checkbox_readonly_true" role="checkbox" aria-readonly="true">This checkbox has aria-readonly="true" and should get STATE_READONLY.</div>
|
||||
<div id="checkbox_readonly_false" role="checkbox" aria-readonly="false">This checkbox has aria-readonly="false" and should <emph>not</emph> get STATE_READONLY.</div>
|
||||
<div id="checkbox_readonly_empty" role="checkbox" aria-readonly="">This checkbox has aria-readonly="" and should <emph>not</emph> get STATE_READONLY.</div>
|
||||
<div id="checkbox_readonly_undefined" role="checkbox" aria-readonly="undefined">This checkbox has aria-readonly="undefined" and should <emph>not</emph> get STATE_READONLY.</div>
|
||||
<div id="checkbox_readonly_absent" role="checkbox">This checkbox has <emph>no</emph> aria-readonly attribute and should <emph>not</emph> get STATE_READONLY.</div>
|
||||
|
||||
<div id="checkbox_required_true" role="checkbox" aria-required="true">This checkbox has aria-required="true" and should get STATE_REQUIRED.</div>
|
||||
<div id="checkbox_required_false" role="checkbox" aria-required="false">This checkbox has aria-required="false" and should <emph>not</emph> get STATE_REQUIRED.</div>
|
||||
<div id="checkbox_required_empty" role="checkbox" aria-required="">This checkbox has aria-required="" and should <emph>not</emph> get STATE_REQUIRED.</div>
|
||||
<div id="checkbox_required_undefined" role="checkbox" aria-required="undefined">This checkbox has aria-required="undefined" and should <emph>not</emph> get STATE_REQUIRED.</div>
|
||||
<div id="checkbox_required_absent" role="checkbox">This checkbox has <emph>no</emph> aria-required attribute and should <emph>not</emph> get STATE_REQUIRED.</div>
|
||||
|
||||
<div id="checkbox_invalid_true" role="checkbox" aria-invalid="true">This checkbox has aria-invalid="true" and should get STATE_INVALID.</div>
|
||||
<div id="checkbox_invalid_false" role="checkbox" aria-invalid="false">This checkbox has aria-invalid="false" and should <emph>not</emph> get STATE_INVALID.</div>
|
||||
<div id="checkbox_invalid_empty" role="checkbox" aria-invalid="">This checkbox has aria-invalid="" and should <emph>not</emph> get STATE_INVALID.</div>
|
||||
<div id="checkbox_invalid_undefined" role="checkbox" aria-invalid="undefined">This checkbox has aria-invalid="undefined" and should <emph>not</emph> get STATE_INVALID.</div>
|
||||
<div id="checkbox_invalid_absent" role="checkbox">This checkbox has <emph>no</emph> aria-invalid attribute and should <emph>not</emph> get STATE_INVALID.</div>
|
||||
|
||||
<div id="checkbox_disabled_true" role="checkbox" aria-disabled="true" tabindex="0">This checkbox has aria-disabled="true" and should get STATE_DISABLED.</div>
|
||||
<div id="checkbox_disabled_false" role="checkbox" aria-disabled="false">This checkbox has aria-disabled="false" and should <emph>not</emph> get STATE_DISABLED.</div>
|
||||
<div id="checkbox_disabled_empty" role="checkbox" aria-disabled="">This checkbox has aria-disabled="" and should <emph>not</emph> get STATE_DISABLED.</div>
|
||||
<div id="checkbox_disabled_undefined" role="checkbox" aria-disabled="undefined">This checkbox has aria-disabled="undefined" and should <emph>not</emph> get STATE_DISABLED.</div>
|
||||
<div id="checkbox_disabled_absent" role="checkbox">This checkbox has <emph>no</emph> aria-disabled attribute and should <emph>not</emph> get STATE_DISABLED.</div>
|
||||
|
||||
<div id="listbox_multiselectable_true" role="listbox" aria-multiselectable="true">
|
||||
<div id="listitem_checked_true" role="listitem" aria-checked="true">item</div>
|
||||
</div>
|
||||
<div id="listbox_multiselectable_false" role="listbox" aria-multiselectable="false">
|
||||
<div id="listitem_checked_false" role="listitem" aria-checked="false">item</div>
|
||||
</div>
|
||||
<div id="listbox_multiselectable_empty" role="listbox" aria-multiselectable="">
|
||||
<div id="listitem_checked_empty" role="listitem" aria-checked="">item</div>
|
||||
</div>
|
||||
<div id="listbox_multiselectable_undefined" role="listbox" aria-multiselectable="undefined">
|
||||
<div id="listitem_checked_undefined" role="listitem" aria-checked="undefined">item</div>
|
||||
</div>
|
||||
<div id="listbox_multiselectable_absent" role="listbox">
|
||||
<div id="listitem_checked_absent" role="listitem">item</div>
|
||||
</div>
|
||||
|
||||
<div role="menu">
|
||||
<div id="menuitem_checked_true" role="menuitem" aria-checked="true">This menuitem has aria-checked="true" and should get STATE_CHECKABLE. It should also get STATE_checked.</div>
|
||||
<div id="menuitem_checked_false" role="menuitem" aria-checked="false">This menuitem has aria-checked="false" and should get STATE_CHECKABLE.</div>
|
||||
<div id="menuitem_checked_empty" role="menuitem" aria-checked="">This menuitem has aria-checked="" and should <emph>not</emph> get STATE_CHECKABLE.</div>
|
||||
<div id="menuitem_checked_undefined" role="menuitem" aria-checked="undefined">This menuitem has aria-checked="undefined" and should <emph>not</emph> get STATE_CHECKABLE.</div>
|
||||
<div id="menuitem_checked_absent" role="menuitem">This menuitem has <emph>no</emph> aria-checked attribute and should <emph>not</emph> get STATE_CHECKABLE.</div>
|
||||
|
||||
<div id="menuitemradio_checked_true" role="menuitemradio" aria-checked="true">This menuitem has aria-checked="true" and should get STATE_CHECKABLE. It should also get STATE_checked.</div>
|
||||
<div id="menuitemradio_checked_false" role="menuitemradio" aria-checked="false">This menuitem has aria-checked="false" and should get STATE_CHECKABLE.</div>
|
||||
<div id="menuitemradio_checked_empty" role="menuitemradio" aria-checked="">This menuitem has aria-checked="" and should <emph>not</emph> get STATE_CHECKABLE.</div>
|
||||
<div id="menuitemradio_checked_undefined" role="menuitemradio" aria-checked="undefined">This menuitem has aria-checked="undefined" and should <emph>not</emph> get STATE_CHECKABLE.</div>
|
||||
<div id="menuitemradio_checked_absent" role="menuitemradio">This menuitem has <emph>no</emph> aria-checked attribute but should get STATE_CHECKABLE.</div>
|
||||
</div>
|
||||
|
||||
<div id="radio_checked_true" role="radio" aria-checked="true">This menuitem has aria-checked="true" and should get STATE_CHECKABLE. It should also get STATE_CHECKED.</div>
|
||||
<div id="radio_checked_false" role="radio" aria-checked="false">This menuitem has aria-checked="false" and should get STATE_CHECKABLE.</div>
|
||||
<div id="radio_checked_empty" role="radio" aria-checked="">This menuitem has aria-checked="" and should <emph>not</emph> get STATE_CHECKABLE.</div>
|
||||
<div id="radio_checked_undefined" role="radio" aria-checked="undefined">This menuitem has aria-checked="undefined" and should <emph>not</emph> get STATE_CHECKABLE.</div>
|
||||
<div id="radio_checked_absent" role="radio">This menuitem has <emph>no</emph> aria-checked attribute but should get STATE_CHECKABLE.</div>
|
||||
|
||||
<div id="textbox_readonly_true" role="textbox" aria-readonly="true"></div>
|
||||
<div id="textbox_readonly_false" role="textbox" aria-readonly="false"></div>
|
||||
<div id="textbox_readonly_empty" role="textbox" aria-readonly=""></div>
|
||||
<div id="textbox_readonly_undefined" role="textbox" aria-readonly="undefined"></div>
|
||||
<div id="textbox_readonly_absent" role="textbox"></div>
|
||||
|
||||
<div id="textbox_multiline_true" role="textbox" aria-multiline="true"></div>
|
||||
<div id="textbox_multiline_false" role="textbox" aria-multiline="false"></div>
|
||||
<div id="textbox_multiline_empty" role="textbox" aria-multiline=""></div>
|
||||
<div id="textbox_multiline_undefined" role="textbox" aria-multiline="undefined"></div>
|
||||
<div id="textbox_multiline_absent" role="textbox"></div>
|
||||
|
||||
<form action="">
|
||||
<input id="native_textbox_nativereadonly_ariatrue" readonly="readonly" aria-readonly="true"/>
|
||||
<input id="native_textbox_nativereadonly_ariafalse" readonly="readonly" aria-readonly="false"/>
|
||||
<input id="native_textbox_nativereadonly_ariaempty" readonly="readonly" aria-readonly=""/>
|
||||
<input id="native_textbox_nativereadonly_ariaundefined" readonly="readonly" aria-readonly="undefined"/>
|
||||
<input id="native_textbox_nativereadonly_ariaabsent" readonly="readonly"/>
|
||||
|
||||
<input id="native_textbox_nativeeditable_ariatrue" aria-readonly="true"/>
|
||||
<input id="native_textbox_nativeeditable_ariafalse" aria-readonly="false"/>
|
||||
<input id="native_textbox_nativeeditable_ariaempty" aria-readonly=""/>
|
||||
<input id="native_textbox_nativeeditable_ariaundefined" aria-readonly="undefined"/>
|
||||
<input id="native_textbox_nativeeditable_ariaabsent"/>
|
||||
</form>
|
||||
|
||||
<div role="tree">
|
||||
<div id="treeitem_selected_true" role="treeitem" aria-selected="true">This treeitem has aria-selected="true" and should get STATE_SELECTABLE. It should also get STATE_SELECTED.</div>
|
||||
<div id="treeitem_selected_false" role="treeitem" aria-selected="false">This treeitem has aria-selected="false" and should get STATE_SELECTABLE.</div>
|
||||
<div id="treeitem_selected_empty" role="treeitem" aria-selected="">This treeitem has aria-selected="" and should <emph>not</emph> get STATE_SELECTABLE.</div>
|
||||
<div id="treeitem_selected_undefined" role="treeitem" aria-selected="undefined">This treeitem has aria-selected="undefined" and should <emph>not</emph> get STATE_SELECTABLE.</div>
|
||||
<div id="treeitem_selected_absent" role="treeitem">This treeitem has <emph>no</emph> aria-selected attribute and should <emph>not</emph> get STATE_SELECTABLE.</div>
|
||||
|
||||
<div id="treeitem_haspopup_true" role="treeitem" aria-haspopup="true">This treeitem has aria-haspopup="true" and should get STATE_HASPOPUP.</div>
|
||||
<div id="treeitem_haspopup_false" role="treeitem" aria-haspopup="false">This treeitem has aria-haspopup="false" and should get STATE_HASPOPUP.</div>
|
||||
<div id="treeitem_haspopup_empty" role="treeitem" aria-haspopup="">This treeitem has aria-haspopup="" and should <emph>not</emph> get STATE_HASPOPUP.</div>
|
||||
<div id="treeitem_haspopup_undefined" role="treeitem" aria-haspopup="undefined">This treeitem has aria-haspopup="undefined" and should <emph>not</emph> get STATE_HASPOPUP.</div>
|
||||
<div id="treeitem_haspopup_absent" role="treeitem">This treeitem has <emph>no</emph> aria-haspopup attribute and should <emph>not</emph> get STATE_HASPOPUP.</div>
|
||||
|
||||
<div id="treeitem_expanded_true" role="treeitem" aria-expanded="true">This treeitem has aria-expanded="true" and should get STATE_EXPANDABLE. It should also get STATE_EXPANDED.</div>
|
||||
<div id="treeitem_expanded_false" role="treeitem" aria-expanded="false">This treeitem has aria-expanded="false" and should get STATE_EXPANDABLE. It should also get STATE_COLLAPSED.</div>
|
||||
<div id="treeitem_expanded_empty" role="treeitem" aria-expanded="">This treeitem has aria-expanded="" and should <emph>not</emph> get STATE_EXPANDABLE.</div>
|
||||
<div id="treeitem_expanded_undefined" role="treeitem" aria-expanded="undefined">This treeitem has aria-expanded="undefined" and should <emph>not</emph> get STATE_EXPANDABLE.</div>
|
||||
<div id="treeitem_expanded_absent" role="treeitem">This treeitem has <emph>no</emph> aria-expanded attribute and should <emph>not</emph> get STATE_EXPANDABLE.</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -68,7 +68,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=418368
|
|||
var normalHyperlinkAcc = getAccessible("NormalHyperlink",
|
||||
[nsIAccessibleHyperLink]);
|
||||
testThis("NormalHyperlink", normalHyperlinkAcc, ROLE_LINK, 1,
|
||||
"Mozilla Foundation", true, 18, 19);
|
||||
"Mozilla Foundation", true, 17, 18);
|
||||
is(normalHyperlinkAcc.getURI(0).spec, "http://www.mozilla.org/",
|
||||
"URI wrong for normalHyperlinkElement!");
|
||||
testStates(normalHyperlinkAcc,
|
||||
|
@ -84,7 +84,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=418368
|
|||
var ariaHyperlinkAcc = getAccessible("AriaHyperlink",
|
||||
[nsIAccessibleHyperLink]);
|
||||
testThis("AriaHyperlink", ariaHyperlinkAcc, ROLE_LINK, 1,
|
||||
"Mozilla Foundation Home", true, 32, 33);
|
||||
"Mozilla Foundation Home", true, 30, 31);
|
||||
testStates(ariaHyperlinkAcc,
|
||||
(STATE_FOCUSABLE | STATE_LINKED),
|
||||
(EXT_STATE_HORIZONTAL));
|
||||
|
@ -110,7 +110,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=418368
|
|||
var imageMapHyperlinkAcc = getAccessible("imgmap",
|
||||
[nsIAccessibleHyperLink]);
|
||||
testThis("imgmap", imageMapHyperlinkAcc, ROLE_IMAGE_MAP, 2, "b", true,
|
||||
83, 84);
|
||||
79, 80);
|
||||
is(imageMapHyperlinkAcc.getURI(0).spec,
|
||||
"http://www.bbc.co.uk/radio4/atoz/index.shtml#b", "URI wrong!");
|
||||
is(imageMapHyperlinkAcc.getURI(1).spec,
|
||||
|
@ -137,7 +137,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=418368
|
|||
// empty hyperlink
|
||||
var EmptyHLAcc = getAccessible("emptyLink",
|
||||
[nsIAccessibleHyperLink]);
|
||||
testThis("emptyLink", EmptyHLAcc, ROLE_LINK, 1, null, true, 98, 99);
|
||||
testThis("emptyLink", EmptyHLAcc, ROLE_LINK, 1, null, true, 93, 94);
|
||||
testStates(EmptyHLAcc,
|
||||
(STATE_FOCUSABLE | STATE_LINKED),
|
||||
(EXT_STATE_HORIZONTAL));
|
||||
|
@ -148,7 +148,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=418368
|
|||
var hyperlinkWithSpanAcc = getAccessible("LinkWithSpan",
|
||||
[nsIAccessibleHyperLink]);
|
||||
testThis("LinkWithSpan", hyperlinkWithSpanAcc, ROLE_LINK, 1,
|
||||
"Heise Online", true, 124, 125);
|
||||
"Heise Online", true, 119, 120);
|
||||
is(hyperlinkWithSpanAcc.getURI(0).spec, "http://www.heise.de/",
|
||||
"URI wrong for hyperlinkElementWithSpan!");
|
||||
testStates(hyperlinkWithSpanAcc,
|
||||
|
@ -165,7 +165,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=418368
|
|||
var namedAnchorAcc = getAccessible("namedAnchor",
|
||||
[nsIAccessibleHyperLink]);
|
||||
testThis("namedAnchor", namedAnchorAcc, ROLE_LINK, 1,
|
||||
"This should never be of state_linked", true, 202, 203);
|
||||
"This should never be of state_linked", true, 196, 197);
|
||||
testStates(namedAnchorAcc,
|
||||
(STATE_SELECTABLE),
|
||||
(EXT_STATE_HORIZONTAL), (STATE_FOCUSABLE | STATE_LINKED));
|
||||
|
@ -176,7 +176,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=418368
|
|||
var noLinkAcc = getAccessible("noLink",
|
||||
[nsIAccessibleHyperLink]);
|
||||
testThis("noLink", noLinkAcc, ROLE_LINK, 1,
|
||||
"This should never be of state_linked", true, 262, 263);
|
||||
"This should never be of state_linked", true, 254, 255);
|
||||
testStates(noLinkAcc,
|
||||
0,
|
||||
(EXT_STATE_HORIZONTAL), (STATE_FOCUSABLE | STATE_LINKED));
|
||||
|
@ -187,7 +187,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=418368
|
|||
var linkWithClickAcc = getAccessible("linkWithClick",
|
||||
[nsIAccessibleHyperLink]);
|
||||
testThis("linkWithClick", linkWithClickAcc, ROLE_LINK, 1,
|
||||
"This should have state_linked", true, 301, 302);
|
||||
"This should have state_linked", true, 292, 293);
|
||||
testStates(linkWithClickAcc,
|
||||
(STATE_LINKED),
|
||||
(EXT_STATE_HORIZONTAL));
|
||||
|
@ -201,7 +201,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=418368
|
|||
// Link with title attribute, no name from the subtree (bug 438325).
|
||||
var id = "linkWithTitleNoNameFromSubtree";
|
||||
var linkAcc = getAccessible(id, [nsIAccessibleHyperLink]);
|
||||
testThis(id, linkAcc, ROLE_LINK, 1, "Link with title", true, 354, 355);
|
||||
testThis(id, linkAcc, ROLE_LINK, 1, "Link with title", true, 344, 345);
|
||||
testStates(linkAcc,
|
||||
(STATE_LINKED),
|
||||
(EXT_STATE_HORIZONTAL));
|
||||
|
@ -212,8 +212,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=418368
|
|||
// (bug 438325).
|
||||
id = "linkWithTitleNameFromSubtree";
|
||||
linkAcc = getAccessible(id, [nsIAccessibleHyperLink]);
|
||||
testThis(id, linkAcc, ROLE_LINK, 1, "the name from subtree", true, 403,
|
||||
404);
|
||||
testThis(id, linkAcc, ROLE_LINK, 1, "the name from subtree", true, 393,
|
||||
394);
|
||||
testStates(linkAcc,
|
||||
(STATE_LINKED),
|
||||
(EXT_STATE_HORIZONTAL));
|
||||
|
@ -223,8 +223,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=418368
|
|||
// Link with title attribute, name from the nested html:img (bug 438325).
|
||||
id = "linkWithTitleNameFromImg";
|
||||
linkAcc = getAccessible(id, [nsIAccessibleHyperLink]);
|
||||
testThis(id, linkAcc, ROLE_LINK, 1, "The title for link", true, 458,
|
||||
459);
|
||||
testThis(id, linkAcc, ROLE_LINK, 1, "The title for link", true, 447,
|
||||
448);
|
||||
testStates(linkAcc,
|
||||
(STATE_LINKED),
|
||||
(EXT_STATE_HORIZONTAL));
|
||||
|
@ -235,7 +235,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=418368
|
|||
id = "linkWithLabelNoNameFromSubtree";
|
||||
linkAcc = getAccessible(id, [nsIAccessibleHyperLink]);
|
||||
testThis(id, linkAcc, ROLE_LINK, 1, "Link with label and nested image:",
|
||||
true, 462, 463);
|
||||
true, 450, 451);
|
||||
testStates(linkAcc,
|
||||
(STATE_LINKED),
|
||||
(EXT_STATE_HORIZONTAL));
|
||||
|
@ -250,78 +250,64 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=418368
|
|||
addLoadEvent(doTest);
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=418368">Mozilla Bug 418368</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
|
||||
<br>Simple link:<br>
|
||||
<a id="NormalHyperlink" href="http://www.mozilla.org">Mozilla Foundation</a>
|
||||
<br>ARIA link:<br>
|
||||
<span id="AriaHyperlink" role="link"
|
||||
<body><a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=418368">Mozilla Bug 418368</a
|
||||
><p id="display"></p
|
||||
><div id="content" style="display: none"></div
|
||||
><pre id="test">
|
||||
</pre
|
||||
><br
|
||||
>Simple link:<br
|
||||
><a id="NormalHyperlink" href="http://www.mozilla.org">Mozilla Foundation</a
|
||||
><br>ARIA link:<br
|
||||
><span id="AriaHyperlink" role="link"
|
||||
onclick="window.open('http://www.mozilla.org/');"
|
||||
tabindex="0">Mozilla Foundation Home</span>
|
||||
<br>Invalid, non-focusable hyperlink:<br>
|
||||
<span id="InvalidAriaHyperlink" role="link" aria-invalid="true"
|
||||
onclick="window.open('http:/www.mozilla.org/');">Invalid link</span>
|
||||
<br>Image map:<br>
|
||||
<map name="atoz_map">
|
||||
<area href="http://www.bbc.co.uk/radio4/atoz/index.shtml#b"
|
||||
tabindex="0">Mozilla Foundation Home</span
|
||||
><br
|
||||
>Invalid, non-focusable hyperlink:<br
|
||||
><span id="InvalidAriaHyperlink" role="link" aria-invalid="true"
|
||||
onclick="window.open('http:/www.mozilla.org/');">Invalid link</span
|
||||
><br>Image map:<br
|
||||
><map name="atoz_map"
|
||||
><area href="http://www.bbc.co.uk/radio4/atoz/index.shtml#b"
|
||||
coords="17,0,30,14"
|
||||
alt="b"
|
||||
shape="rect"></area>
|
||||
<area href="http://www.bbc.co.uk/radio4/atoz/index.shtml#a"
|
||||
coords="0,0,13,14"
|
||||
alt="a"
|
||||
shape="rect"></area>
|
||||
</map>
|
||||
<img width="447" id="imgmap"
|
||||
height="15"
|
||||
usemap="#atoz_map"
|
||||
src="letters.gif"></img>
|
||||
|
||||
<br>Empty link:<br>
|
||||
<a id="emptyLink" href=""><img src=""></img></a>
|
||||
|
||||
<br>Link with embedded span<br>
|
||||
<a id="LinkWithSpan" href="http://www.heise.de/"><span lang="de">Heise Online</span></a>
|
||||
|
||||
<br>Named anchor, must not have "linked" state for it to be exposed correctly:<br>
|
||||
<a id="namedAnchor" name="named_anchor">This should never be of state_linked</a>
|
||||
|
||||
<br>Link having no attributes, must not have "linked" state:</br>
|
||||
<a id="noLink">This should never be of state_linked</a>
|
||||
|
||||
<br>Link with registered 'click' event: </br>
|
||||
<a id="linkWithClick" onclick="var clicked = true;">This should have state_linked</a>
|
||||
|
||||
<br>Link with title attribute (no name from subtree): </br>
|
||||
<a id="linkWithTitleNoNameFromSubtree" href="http://www.heise.de/"
|
||||
title="Link with title"><img src=""/></a>
|
||||
|
||||
<br>Link with title attribute (name from subtree): </br>
|
||||
<a id="linkWithTitleNameFromSubtree" href="http://www.heise.de/"
|
||||
title="Link with title">the name from subtree</a>
|
||||
|
||||
<br>Link with title attribute (name from nested image): </br>
|
||||
<a id="linkWithTitleNameFromImg" href="http://www.heise.de/"
|
||||
title="Link with title"><img src="" alt="The title for link"/></a>
|
||||
|
||||
<br><label for="linkWithLabelNoNameFromSubtree">Link with label and nested image: </label></br>
|
||||
<a id="linkWithLabelNoNameFromSubtree"
|
||||
href="http://www.heise.de/"><img src=""/></a>
|
||||
|
||||
<br>Map that is used to group links (www.w3.org/TR/WCAG10-HTML-TECHS/#group-bypass),
|
||||
also see the bug 431615:<br>
|
||||
<map id="linksmap" title="Site navigation">
|
||||
<ul>
|
||||
<li><a href="http://mozilla.org">About the project</a></li>
|
||||
<li><a href="http://mozilla.org">Sites and sounds</a></li>
|
||||
</ul>
|
||||
</map>
|
||||
|
||||
</body>
|
||||
shape="rect"></area
|
||||
><area href="http://www.bbc.co.uk/radio4/atoz/index.shtml#a"
|
||||
coords="0,0,13,14"
|
||||
alt="a"
|
||||
shape="rect"></area
|
||||
></map
|
||||
><img width="447" id="imgmap"
|
||||
height="15"
|
||||
usemap="#atoz_map"
|
||||
src="letters.gif"></img
|
||||
><br>Empty link:<br
|
||||
><a id="emptyLink" href=""><img src=""></img></a
|
||||
><br>Link with embedded span<br
|
||||
><a id="LinkWithSpan" href="http://www.heise.de/"><span lang="de">Heise Online</span></a
|
||||
><br>Named anchor, must not have "linked" state for it to be exposed correctly:<br
|
||||
><a id="namedAnchor" name="named_anchor">This should never be of state_linked</a
|
||||
><br>Link having no attributes, must not have "linked" state:</br
|
||||
><a id="noLink">This should never be of state_linked</a
|
||||
><br>Link with registered 'click' event: </br
|
||||
><a id="linkWithClick" onclick="var clicked = true;">This should have state_linked</a
|
||||
><br>Link with title attribute (no name from subtree): </br
|
||||
><a id="linkWithTitleNoNameFromSubtree" href="http://www.heise.de/"
|
||||
title="Link with title"><img src=""/></a
|
||||
><br>Link with title attribute (name from subtree): </br
|
||||
><a id="linkWithTitleNameFromSubtree" href="http://www.heise.de/"
|
||||
title="Link with title">the name from subtree</a
|
||||
><br>Link with title attribute (name from nested image): </br
|
||||
><a id="linkWithTitleNameFromImg" href="http://www.heise.de/"
|
||||
title="Link with title"><img src="" alt="The title for link"/></a
|
||||
><br><label for="linkWithLabelNoNameFromSubtree">Link with label and nested image: </label></br
|
||||
><a id="linkWithLabelNoNameFromSubtree"
|
||||
href="http://www.heise.de/"><img src=""/></a
|
||||
><br>Map that is used to group links (www.w3.org/TR/WCAG10-HTML-TECHS/#group-bypass), also see the bug 431615:<br
|
||||
><map id="linksmap" title="Site navigation"><ul
|
||||
><li><a href="http://mozilla.org">About the project</a></li
|
||||
><li><a href="http://mozilla.org">Sites and sounds</a></li
|
||||
></ul
|
||||
></map
|
||||
></body>
|
||||
</html>
|
||||
|
|
|
@ -43,22 +43,22 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=428248
|
|||
testThis("NormalHyperlink", 14, 0, "Mozilla Foundation");
|
||||
|
||||
// ARIA hyperlink
|
||||
testThis("AriaHyperlink", 28, 1, "Mozilla Foundation Home");
|
||||
testThis("AriaHyperlink", 27, 1, "Mozilla Foundation Home");
|
||||
|
||||
// ARIA hyperlink with status invalid
|
||||
testThis("InvalidAriaHyperlink", 64, 2, "Invalid link");
|
||||
testThis("InvalidAriaHyperlink", 63, 2, "Invalid link");
|
||||
|
||||
// image map, but not its link children. They are not part of hypertext.
|
||||
testThis("imgmap", 78, 3, "b");
|
||||
testThis("imgmap", 76, 3, "b");
|
||||
|
||||
// empty hyperlink
|
||||
testThis("emptyLink", 93, 4, null);
|
||||
testThis("emptyLink", 90, 4, null);
|
||||
|
||||
// normal hyperlink with embedded span
|
||||
testThis("LinkWithSpan", 119, 5, "Heise Online");
|
||||
testThis("LinkWithSpan", 116, 5, "Heise Online");
|
||||
|
||||
// Named anchor
|
||||
testThis("namedAnchor", 197, 6, "This should never be of state_linked");
|
||||
testThis("namedAnchor", 193, 6, "This should never be of state_linked");
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
@ -74,37 +74,35 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=428248
|
|||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
<p id="testParagraph">
|
||||
<br>Simple link:<br>
|
||||
<a id="NormalHyperlink" href="http://www.mozilla.org">Mozilla Foundation</a>
|
||||
<br>ARIA link:<br>
|
||||
<span id="AriaHyperlink" role="link"
|
||||
onclick="window.open('http://www.mozilla.org/');"
|
||||
tabindex="0">Mozilla Foundation Home</span>
|
||||
<br>Invalid, non-focusable hyperlink:<br>
|
||||
<span id="InvalidAriaHyperlink" role="link" aria-invalid="true"
|
||||
onclick="window.open('http:/www.mozilla.org/');">Invalid link</span>
|
||||
<br>Image map:<br>
|
||||
<map name="atoz_map">
|
||||
<area href="http://www.bbc.co.uk/radio4/atoz/index.shtml#b"
|
||||
coords="17,0,30,14"
|
||||
alt="b"
|
||||
shape="rect"></area>
|
||||
<area href="http://www.bbc.co.uk/radio4/atoz/index.shtml#a"
|
||||
coords="0,0,13,14"
|
||||
alt="a"
|
||||
shape="rect"></area>
|
||||
</map>
|
||||
<img width="447" id="imgmap"
|
||||
<p id="testParagraph"><br
|
||||
>Simple link:<br
|
||||
><a id="NormalHyperlink" href="http://www.mozilla.org">Mozilla Foundation</a><br
|
||||
>ARIA link:<br
|
||||
><span id="AriaHyperlink" role="link"
|
||||
onclick="window.open('http://www.mozilla.org/');"
|
||||
tabindex="0">Mozilla Foundation Home</span><br
|
||||
>Invalid, non-focusable hyperlink:<br
|
||||
><span id="InvalidAriaHyperlink" role="link" aria-invalid="true"
|
||||
onclick="window.open('http:/www.mozilla.org/');">Invalid link</span><br
|
||||
>Image map:<br
|
||||
><map name="atoz_map"><area href="http://www.bbc.co.uk/radio4/atoz/index.shtml#b"
|
||||
coords="17,0,30,14"
|
||||
alt="b"
|
||||
shape="rect"></area
|
||||
><area href="http://www.bbc.co.uk/radio4/atoz/index.shtml#a"
|
||||
coords="0,0,13,14"
|
||||
alt="a"
|
||||
shape="rect"></area></map
|
||||
><img width="447" id="imgmap"
|
||||
height="15"
|
||||
usemap="#atoz_map"
|
||||
src="letters.gif"></img>
|
||||
<br>Empty link:<br>
|
||||
<a id="emptyLink" href=""><img src=""></img></a>
|
||||
<br>Link with embedded span<br>
|
||||
<a id="LinkWithSpan" href="http://www.heise.de/"><span lang="de">Heise Online</span></a>
|
||||
<br>Named anchor, must not have "linked" state for it to be exposed correctly:<br>
|
||||
<a id="namedAnchor" name="named_anchor">This should never be of state_linked</a>
|
||||
src="letters.gif"></img><br
|
||||
>Empty link:<br
|
||||
><a id="emptyLink" href=""><img src=""></img></a><br
|
||||
>Link with embedded span<br
|
||||
><a id="LinkWithSpan" href="http://www.heise.de/"><span lang="de">Heise Online</span></a><br
|
||||
>Named anchor, must not have "linked" state for it to be exposed correctly:<br
|
||||
><a id="namedAnchor" name="named_anchor">This should never be of state_linked</a>
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -31,9 +31,24 @@
|
|||
<script type="application/javascript">
|
||||
function doTest()
|
||||
{
|
||||
// aria_autocomplete
|
||||
testStates("textbox_autocomplete_inline", 0, EXT_STATE_SUPPORTS_AUTOCOMPLETION);
|
||||
testStates("textbox_autocomplete_list", STATE_HASPOPUP, EXT_STATE_SUPPORTS_AUTOCOMPLETION);
|
||||
testStates("textbox_autocomplete_both", STATE_HASPOPUP, EXT_STATE_SUPPORTS_AUTOCOMPLETION);
|
||||
testStates("combobox_autocomplete_inline", STATE_HASPOPUP, EXT_STATE_SUPPORTS_AUTOCOMPLETION);
|
||||
testStates("combobox_autocomplete_list", STATE_HASPOPUP, EXT_STATE_SUPPORTS_AUTOCOMPLETION);
|
||||
testStates("combobox_autocomplete_both", STATE_HASPOPUP, EXT_STATE_SUPPORTS_AUTOCOMPLETION);
|
||||
|
||||
// aria-busy
|
||||
testStates("textbox_busy_false", 0, 0, STATE_BUSY);
|
||||
testStates("textbox_busy_true", STATE_BUSY);
|
||||
testStates("textbox_busy_error", STATE_INVALID);
|
||||
|
||||
// aria-expanded
|
||||
testStates("combobox", STATE_COLLAPSED);
|
||||
testStates("combobox_expanded", STATE_EXPANDED);
|
||||
|
||||
// tri-state checkbox
|
||||
var checkboxElem = getNode("check1");
|
||||
if (checkboxElem) {
|
||||
testStates(checkboxElem, STATE_CHECKED);
|
||||
|
@ -43,6 +58,7 @@
|
|||
testStates(checkboxElem, STATE_MIXED, 0);
|
||||
}
|
||||
|
||||
// aria-checked
|
||||
testStates("aria_checked_checkbox", STATE_CHECKED);
|
||||
testStates("aria_mixed_checkbox", STATE_MIXED);
|
||||
|
||||
|
@ -50,6 +66,7 @@
|
|||
// disabled, too. See bug 429285.
|
||||
testStatesInSubtree("group", STATE_UNAVAILABLE);
|
||||
|
||||
// offscreen test
|
||||
testStates("aria_offscreen_textbox", STATE_OFFSCREEN);
|
||||
|
||||
SimpleTest.finish();
|
||||
|
@ -73,13 +90,28 @@
|
|||
title="Propagate aria-disabled to descendants">
|
||||
Mozilla Bug 429285
|
||||
</a>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=499653"
|
||||
title="Unify ARIA state attributes mapping rules">
|
||||
Mozilla Bug 499653
|
||||
</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
|
||||
<div id="combobox" role="combobox">combobox</div>
|
||||
<div id="textbox_autocomplete_inline" role="textbox" aria-autocomplete="inline"></div>
|
||||
<div id="textbox_autocomplete_list" role="textbox" aria-autocomplete="list"></div>
|
||||
<div id="textbox_autocomplete_both" role="textbox" aria-autocomplete="both"></div>
|
||||
<div id="combobox_autocomplete_inline" role="combobox" aria-autocomplete="inline"></div>
|
||||
<div id="combobox_autocomplete_list" role="combobox" aria-autocomplete="list"></div>
|
||||
<div id="combobox_autocomplete_both" role="combobox" aria-autocomplete="both"></div>
|
||||
|
||||
<div id="textbox_busy_false" role="textbox" aria-busy="false"></div>
|
||||
<div id="textbox_busy_true" role="textbox" aria-busy="true"></div>
|
||||
<div id="textbox_busy_error" role="textbox" aria-busy="error"></div>
|
||||
|
||||
<div id="combobox" role="combobox">combobox</div>
|
||||
<div id="combobox_expanded" role="combobox"
|
||||
aria-expanded="true">combobox</div>
|
||||
|
||||
|
|
|
@ -745,7 +745,6 @@ var HistoryMenu = {
|
|||
|
||||
var menuPopup = aEvent.target;
|
||||
var resultNode = menuPopup.getResultNode();
|
||||
var wasOpen = resultNode.containerOpen;
|
||||
resultNode.containerOpen = true;
|
||||
document.getElementById("endHistorySeparator").hidden =
|
||||
resultNode.childCount == 0;
|
||||
|
|
|
@ -220,17 +220,23 @@
|
|||
<ul>
|
||||
<li>Josh Aas</li>
|
||||
<li>Robert Accettura</li>
|
||||
<li>Lucas Adamski</li>
|
||||
<li>Ehsan Akhgari</li>
|
||||
<li>Sean Alamares</li>
|
||||
<li>Pedro Alves</li>
|
||||
<li>David Anderson</li>
|
||||
<li>Harvey Anderson</li>
|
||||
<li>Smokey Ardisson</li>
|
||||
<li>Rob Arnold</li>
|
||||
<li>Tomoya Asai</li>
|
||||
<li>Chris AtLee</li>
|
||||
<li>Dietrich Ayala</li>
|
||||
<li>Mitchell Baker</li>
|
||||
<li>Rhian Baker</li>
|
||||
<li>Jeff Balogh</li>
|
||||
<li>Honza Bambas</li>
|
||||
<li>Jan Bambas</li>
|
||||
<li>Rey Bango</li>
|
||||
<li>Mark Banner</li>
|
||||
<li>Jason Barnabe</li>
|
||||
<li>David Baron</li>
|
||||
|
@ -247,6 +253,7 @@
|
|||
<li>Christian Biesinger</li>
|
||||
<li>Al Billings</li>
|
||||
<li>Seth Bindernagel</li>
|
||||
<li>Lukas Blakk</li>
|
||||
<li>Jim Blandy</li>
|
||||
<li>Chris Blizzard</li>
|
||||
<li>Jamey Boje</li>
|
||||
|
@ -258,9 +265,11 @@
|
|||
<li>Jennifer Boriss</li>
|
||||
<li>Dan Born</li>
|
||||
<li>Arpad Borsos</li>
|
||||
<li>David Boswell</li>
|
||||
<li>Ondřej Brablc</li>
|
||||
<li>Catherine Brady</li>
|
||||
<li>Dave Bragsalla</li>
|
||||
<li>Alex Buchanan</li>
|
||||
<li>Igor Bukanov</li>
|
||||
<li>Simon Bünzli</li>
|
||||
<li>Lapo Calamandrei</li>
|
||||
|
@ -273,6 +282,7 @@
|
|||
<li>Emily Chen</li>
|
||||
<li>Ginn Chen</li>
|
||||
<li>Pascal Chevrel</li>
|
||||
<li>Adam Christian</li>
|
||||
<li>Tony Chung</li>
|
||||
<li>Bob Clary</li>
|
||||
<li>Wil Clouser</li>
|
||||
|
@ -280,19 +290,25 @@
|
|||
<li>Majken Connor</li>
|
||||
<li>Mike Connor</li>
|
||||
<li>Chris Cooper</li>
|
||||
<li>Eric Cooper</li>
|
||||
<li>Paul Craciunoiu</li>
|
||||
<li>Brian Crowder</li>
|
||||
<li>John Daggett</li>
|
||||
<li>David Dahl</li>
|
||||
<li>Michael Davis</li>
|
||||
<li>Neil Deakin</li>
|
||||
<li>Julie Deroche</li>
|
||||
<li>Aakash Desai</li>
|
||||
<li>Ryan Doherty</li>
|
||||
<li>Justin Dolske</li>
|
||||
<li>Stephen Donner</li>
|
||||
<li>Asa Dotzler</li>
|
||||
<li>Chris Double</li>
|
||||
<li>Joe Drew</li>
|
||||
<li>Jason Duell</li>
|
||||
<li>Karsten Düsterloh</li>
|
||||
<li>Brendan Eich</li>
|
||||
<li>Daniel Einspanjer</li>
|
||||
<li>Kai Engert</li>
|
||||
<li>Steve England</li>
|
||||
<li>Madhava Enros</li>
|
||||
|
@ -311,6 +327,7 @@
|
|||
<li>Eli Friedman</li>
|
||||
<li>Andreas Gal</li>
|
||||
<li>Steven Garrity</li>
|
||||
<li>Armen Zambrano Gasparnian</li>
|
||||
<li>Serge Gautherie</li>
|
||||
<li>Kevin Gerich</li>
|
||||
<li>Taras Glek</li>
|
||||
|
@ -320,6 +337,7 @@
|
|||
<li>Matthew Gregan</li>
|
||||
<li>Will Guaraldi</li>
|
||||
<li>Adam Guthrie</li>
|
||||
<li>Mohammad Reza Haghighat</li>
|
||||
<li>Andrei Hajdukewycz</li>
|
||||
<li>Trevor Hardcastle</li>
|
||||
<li>Basil Hashem</li>
|
||||
|
@ -337,11 +355,14 @@
|
|||
<li>Bobby Holley</li>
|
||||
<li>Mike Hommey</li>
|
||||
<li>Stephen Horlander</li>
|
||||
<li>Barbara Hueppe</li>
|
||||
<li>Anthony Hughes</li>
|
||||
<li>David Humphrey</li>
|
||||
<li>Takeshi Ichimaru</li>
|
||||
<li>Chris Ilias</li>
|
||||
<li>Eri Inoue </li>
|
||||
<li>Eri Inoue</li>
|
||||
<li>Joichi Ito</li>
|
||||
<li>Steven Johnson</li>
|
||||
<li>Laurent Jouanneau</li>
|
||||
<li>Robert Kaiser</li>
|
||||
<li>Gen Kanai</li>
|
||||
|
@ -351,10 +372,12 @@
|
|||
<li>Michael Kaply</li>
|
||||
<li>Mitch Kapor</li>
|
||||
<li>Kazuyoshi Kato</li>
|
||||
<li>Tomomi Kato</li>
|
||||
<li>Alfred Kayser</li>
|
||||
<li>Jonathan Kew</li>
|
||||
<li>Paul Kim</li>
|
||||
<li>Masatoshi Kimura</li>
|
||||
<li>Austin King</li>
|
||||
<li>Ria Klaassen</li>
|
||||
<li>Marcia Knous</li>
|
||||
<li>Nelson Ko</li>
|
||||
|
@ -362,7 +385,9 @@
|
|||
<li>Gary Kwong</li>
|
||||
<li>David Lanham</li>
|
||||
<li>Brad Lassey</li>
|
||||
<li>Delphine Lebédel</li>
|
||||
<li>Edward Lee</li>
|
||||
<li>Neil Lee</li>
|
||||
<li>Raymond Lee</li>
|
||||
<li>Garrett LeSage</li>
|
||||
<li>Aaron Leventhal</li>
|
||||
|
@ -381,6 +406,7 @@
|
|||
<li>Gervase Markham</li>
|
||||
<li>Sean Martell</li>
|
||||
<li>Jim Mathies</li>
|
||||
<li>Erica McClure</li>
|
||||
<li>Graeme McCutcheon</li>
|
||||
<li>Patrick McManus</li>
|
||||
<li>Heather Meeker</li>
|
||||
|
@ -388,6 +414,7 @@
|
|||
<li>Myk Melez</li>
|
||||
<li>Federico Mena-Quintero</li>
|
||||
<li>Mark Mentovai</li>
|
||||
<li>Laura Mesa</li>
|
||||
<li>Steven Michaud</li>
|
||||
<li>Matthew Middleton</li>
|
||||
<li>Ted Mielczarek</li>
|
||||
|
@ -396,27 +423,33 @@
|
|||
<li>Dan Mills</li>
|
||||
<li>Michael Monreal</li>
|
||||
<li>Simon Montagu</li>
|
||||
<li>Derek Moore</li>
|
||||
<li>Mike Morgan</li>
|
||||
<li>Tiffney Mortensen</li>
|
||||
<li>Dan Mosedale</li>
|
||||
<li>Michael Moy</li>
|
||||
<li>Jeff Muizelaar</li>
|
||||
<li>Masayuki Nakano</li>
|
||||
<li>Murali Nandigama</li>
|
||||
<li>Marria Nazif</li>
|
||||
<li>Kev Needham</li>
|
||||
<li>Kaori Negoro</li>
|
||||
<li>Nicholas Nethercote</li>
|
||||
<li>Ben Newman</li>
|
||||
<li>Nick Nguyen</li>
|
||||
<li>Johnathan Nightingale</li>
|
||||
<li>Andreas Nilsson</li>
|
||||
<li>Timothy Nikkel</li>
|
||||
<li>Andreas Nilsson</li>
|
||||
<li>Tristan Nitot</li>
|
||||
<li>Alice Nodelman</li>
|
||||
<li>Matthew Noorenberghe </li>
|
||||
<li>Matthew Noorenberghe</li>
|
||||
<li>Michal Novotny</li>
|
||||
<li>Robert O'Callahan</li>
|
||||
<li>John O'Duinn</li>
|
||||
<li>Paul O'Shannessy</li>
|
||||
<li>Jan Odvárko</li>
|
||||
<li>Tomoyuki Okazaki</li>
|
||||
<li>Les Orchard</li>
|
||||
<li>Jeremy Orem</li>
|
||||
<li>Jason Orendorff</li>
|
||||
<li>Hideo Oshima</li>
|
||||
|
@ -431,23 +464,29 @@
|
|||
<li>Ulisse Perusin</li>
|
||||
<li>Olli Pettay</li>
|
||||
<li>Julien Pierre</li>
|
||||
<li>Anthony Piraino</li>
|
||||
<li>Alex Polvi</li>
|
||||
<li>Nickolay Ponomarev</li>
|
||||
<li>Dan Portillo</li>
|
||||
<li>Karen Prescott</li>
|
||||
<li>Florian Quèze</li>
|
||||
<li>Krupa Raj</li>
|
||||
<li>Arun Ranganathan</li>
|
||||
<li>Neil Rashbrook</li>
|
||||
<li>Bret Reckard</li>
|
||||
<li>J. Paul Reed</li>
|
||||
<li>Rick Reitmaier</li>
|
||||
<li>Robert Relyea</li>
|
||||
<li>John Resig</li>
|
||||
<li>Deb Richardson</li>
|
||||
<li>Tim Riley</li>
|
||||
<li>Phil Ringnalda</li>
|
||||
<li>Julien Rivaud</li>
|
||||
<li>Mikeal Rogers</li>
|
||||
<li>David Rolnitzky</li>
|
||||
<li>Asaf Romano</li>
|
||||
<li>Oleg Romashin</li>
|
||||
<li>Paul Rouget</li>
|
||||
<li>Tim Rowley</li>
|
||||
<li>Jesse Ruderman</li>
|
||||
<li>Brian Ryner</li>
|
||||
|
@ -456,6 +495,7 @@
|
|||
<li>Atsushi Sakai</li>
|
||||
<li>Eiko Sakuma</li>
|
||||
<li>Andrei Saprykin</li>
|
||||
<li>Aki Sasaki</li>
|
||||
<li>Ken Saunders</li>
|
||||
<li>Robert Sayre</li>
|
||||
<li>Mike Schroepfer</li>
|
||||
|
@ -492,17 +532,24 @@
|
|||
<li>Brandon Sterne</li>
|
||||
<li>Rob Stradling</li>
|
||||
<li>Robert Strong</li>
|
||||
<li>Jay Sullivan</li>
|
||||
<li>Vicky Sun</li>
|
||||
<li>Alexander Surkov</li>
|
||||
<li>Mark Surman</li>
|
||||
<li>Andrew Sutherland</li>
|
||||
<li>Clint Talbert</li>
|
||||
<li>Margaret Tallman</li>
|
||||
<li>David Tenser</li>
|
||||
<li>Chris Thomas</li>
|
||||
<li>Nick Thomas</li>
|
||||
<li>Laura Thomson</li>
|
||||
<li>Karl Tomlinson</li>
|
||||
<li>Dave Townsend</li>
|
||||
<li>Aaron Train</li>
|
||||
<li>Phong Tran</li>
|
||||
<li>Ben Turner</li>
|
||||
<li>Doug Turner</li>
|
||||
<li>Amié Tyrrel</li>
|
||||
<li>Peter Van der Beken</li>
|
||||
<li>Peter van der Woude</li>
|
||||
<li>Teune van Steeg</li>
|
||||
|
@ -523,6 +570,7 @@
|
|||
<li>Steffen Wilberg</li>
|
||||
<li>Drew Willcoxon</li>
|
||||
<li>Shawn Wilsher</li>
|
||||
<li>Kathleen Wilson</li>
|
||||
<li>Dan Witte</li>
|
||||
<li>John Wolfe</li>
|
||||
<li>Steve Won</li>
|
||||
|
|
|
@ -242,17 +242,25 @@ function openUILinkIn( url, where, allowThirdPartyFixup, postData, referrerUrl )
|
|||
loadInBackground = !loadInBackground;
|
||||
// fall through
|
||||
case "tab":
|
||||
var browser = w.getBrowser();
|
||||
let browser = w.getBrowser();
|
||||
browser.loadOneTab(url, referrerUrl, null, postData, loadInBackground,
|
||||
allowThirdPartyFixup || false);
|
||||
break;
|
||||
}
|
||||
|
||||
// Focus the content but don't raise the window, since the URI we just loaded
|
||||
// may have resulted in a new frontmost window (e.g. "javascript:window.open('');").
|
||||
var browser = w.getBrowserFromContentWindow(w.content);
|
||||
if (browser)
|
||||
browser.focus();
|
||||
// If this window is active, focus the target window. Otherwise, focus the
|
||||
// content but don't raise the window, since the URI we just loaded may have
|
||||
// resulted in a new frontmost window (e.g. "javascript:window.open('');").
|
||||
var fm = Components.classes["@mozilla.org/focus-manager;1"].
|
||||
getService(Components.interfaces.nsIFocusManager);
|
||||
if (window == fm.activeWindow) {
|
||||
w.content.focus();
|
||||
}
|
||||
else {
|
||||
let browser = w.getBrowserFromContentWindow(w.content);
|
||||
if (browser)
|
||||
browser.focus();
|
||||
}
|
||||
}
|
||||
|
||||
// Used as an onclick handler for UI elements with link-like behavior.
|
||||
|
|
|
@ -154,7 +154,7 @@ PlacesController.prototype = {
|
|||
var result = this._view.getResult();
|
||||
if (result) {
|
||||
var container = asContainer(result.root);
|
||||
if (container.childCount > 0);
|
||||
if (container.containerOpen && container.childCount > 0);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -748,7 +748,7 @@
|
|||
return;
|
||||
|
||||
var children = popup.childNodes;
|
||||
for (var i = 0; i < children.length; i++) {
|
||||
for (var i = popup._startMarker + 1; i < children.length; i++) {
|
||||
if (children[i].node == aNode) {
|
||||
this._self.removeItem(children[i]);
|
||||
if (!popup.hasChildNodes() ||
|
||||
|
@ -771,7 +771,7 @@
|
|||
var popup = this._getPopupForContainer(aNewParent);
|
||||
var index = popup._startMarker + 1 + aNewIndex;
|
||||
var children = popup.childNodes;
|
||||
for (var i = 0; i < children.length; i++) {
|
||||
for (var i = popup._startMarker + 1; i < children.length; i++) {
|
||||
var menuItem = children[i];
|
||||
if (menuItem.node == aItem) {
|
||||
popup.removeChild(menuItem);
|
||||
|
@ -787,24 +787,24 @@
|
|||
if (!parentNode)
|
||||
return;
|
||||
|
||||
if (PlacesUtils.nodeIsSeparator(aNode)) {
|
||||
// nothing to do when a separator changes
|
||||
return;
|
||||
}
|
||||
|
||||
var popup = this._getPopupForContainer(parentNode);
|
||||
if (!popup._built)
|
||||
return;
|
||||
|
||||
var children = popup.childNodes;
|
||||
var menuitem;
|
||||
for (var i = 0; i < children.length; i++) {
|
||||
for (var i = popup._startMarker + 1; i < children.length; i++) {
|
||||
if (children[i].node == aNode) {
|
||||
menuitem = children[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (PlacesUtils.nodeIsSeparator(aNode)) {
|
||||
// nothing to do when a separator changes
|
||||
return;
|
||||
}
|
||||
|
||||
var iconURI = aNode.icon;
|
||||
if (iconURI) {
|
||||
var spec = iconURI.spec;
|
||||
|
@ -837,7 +837,7 @@
|
|||
return;
|
||||
|
||||
var children = popup.childNodes;
|
||||
for (var i = 0; i < children.length; i++) {
|
||||
for (var i = popup._startMarker + 1; i < children.length; i++) {
|
||||
if (children[i].node == aOldNode) {
|
||||
var next = children[i].nextSibling;
|
||||
this._self.removeItem(children[i]);
|
||||
|
|
|
@ -129,8 +129,10 @@
|
|||
<field name="_chevron">document.getAnonymousElementByAttribute(this, "class", "chevron")</field>
|
||||
|
||||
<field name="_openedMenuButton">null</field>
|
||||
<field name="_allowPopupShowing">true</field>
|
||||
|
||||
<field name="_result">null</field>
|
||||
<field name="_resultNode">null</field>
|
||||
|
||||
<!-- nsIPlacesView -->
|
||||
<method name="getResult">
|
||||
|
@ -526,7 +528,7 @@
|
|||
return;
|
||||
|
||||
var children = popup.childNodes;
|
||||
for (var i = 0; i < children.length; i++) {
|
||||
for (var i = popup._startMarker + 1; i < children.length; i++) {
|
||||
if (children[i].node == aNode) {
|
||||
this._self.removeItem(children[i]);
|
||||
if (!popup.hasChildNodes() ||
|
||||
|
@ -559,7 +561,7 @@
|
|||
this._self.insertBefore(button, children[aNewIndex]);
|
||||
if (chevronPopup) {
|
||||
// Maintain chevron in sync
|
||||
menuitem = chevronPopup.childNodes[i];
|
||||
var menuitem = chevronPopup.childNodes[i];
|
||||
chevronPopup.removeChild(menuitem);
|
||||
chevronPopup.insertBefore(menuitem,
|
||||
chevronPopup.childNodes[aNewIndex]);
|
||||
|
@ -569,14 +571,16 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
var popup = this._getPopupForContainer(aNewParent);
|
||||
var children = popup.childNodes;
|
||||
for (var i = 0; i < children.length; i++) {
|
||||
var menuItem = children[i];
|
||||
if (menuItem.node == aItem) {
|
||||
popup.removeChild(menuItem);
|
||||
popup.insertBefore(menuItem, children[aNewIndex]);
|
||||
return;
|
||||
else {
|
||||
var popup = this._getPopupForContainer(aNewParent);
|
||||
var children = popup.childNodes;
|
||||
for (var i = popup._startMarker + 1; i < children.length; i++) {
|
||||
var menuItem = children[i];
|
||||
if (menuItem.node == aItem) {
|
||||
popup.removeChild(menuItem);
|
||||
popup.insertBefore(menuItem, children[aNewIndex]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -587,6 +591,11 @@
|
|||
if (!parentNode)
|
||||
return;
|
||||
|
||||
if (PlacesUtils.nodeIsSeparator(aNode)) {
|
||||
// nothing to do when a separator changes
|
||||
return;
|
||||
}
|
||||
|
||||
var element;
|
||||
var onToolbar = false;
|
||||
if (parentNode == this._self.getResultNode()) {
|
||||
|
@ -607,7 +616,7 @@
|
|||
return;
|
||||
|
||||
var children = popup.childNodes;
|
||||
for (var i = 0; i < children.length; i++) {
|
||||
for (var i = popup._startMarker + 1; i < children.length; i++) {
|
||||
if (children[i].node == aNode) {
|
||||
element = children[i];
|
||||
break;
|
||||
|
@ -616,11 +625,6 @@
|
|||
var title = PlacesUIUtils.getBestTitle(aNode);
|
||||
}
|
||||
|
||||
if (PlacesUtils.nodeIsSeparator(aNode)) {
|
||||
// nothing to do when a separator changes
|
||||
return;
|
||||
}
|
||||
|
||||
var iconURI = aNode.icon;
|
||||
if (iconURI) {
|
||||
var spec = iconURI.spec;
|
||||
|
@ -662,8 +666,6 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
this._forwardToChildView(aParentNode, "itemReplaced", arguments);
|
||||
},
|
||||
|
||||
containerOpened: function TV_V_containerOpened(aNode) {
|
||||
|
@ -950,7 +952,7 @@
|
|||
|
||||
// * Timer to turn off indicator bar.
|
||||
if (aTimer == this._ibTimer) {
|
||||
ib = this._dropIndicatorBar.removeAttribute('dragging');
|
||||
this._dropIndicatorBar.removeAttribute('dragging');
|
||||
this._ibTimer = null;
|
||||
}
|
||||
|
||||
|
@ -1195,14 +1197,17 @@
|
|||
}
|
||||
]]></handler>
|
||||
|
||||
#ifdef XP_UNIX
|
||||
#ifndef XP_MACOSX
|
||||
<handler event="mousedown"><![CDATA[
|
||||
var target = event.target;
|
||||
if (event.button == 0 &&
|
||||
target.localName == "toolbarbutton" &&
|
||||
target.getAttribute("type") == "menu") {
|
||||
this._allowPopupShowing = false;
|
||||
// This is a container, we will open the menu if the user clicks
|
||||
// or drag toward down or after a delay
|
||||
// On Linux we can open the popup only after a delay.
|
||||
// Indeed as soon as the menupopup opens we are unable to start a
|
||||
// drag event. See bug 500081 for details.
|
||||
this._mouseDownTimer = Cc["@mozilla.org/timer;1"]
|
||||
.createInstance(Ci.nsITimer);
|
||||
var callback = {
|
||||
|
@ -1214,15 +1219,12 @@
|
|||
}
|
||||
};
|
||||
|
||||
this._mouseDownTimer.initWithCallback(callback, 500,
|
||||
this._mouseDownTimer.initWithCallback(callback, 300,
|
||||
Ci.nsITimer.TYPE_ONE_SHOT);
|
||||
}
|
||||
else {
|
||||
// allow opening popups, like the chevron and context menus
|
||||
this._allowPopupShowing = true;
|
||||
}
|
||||
]]></handler>
|
||||
|
||||
#endif
|
||||
#endif
|
||||
<handler event="mouseup"><![CDATA[
|
||||
if (event.button != 0)
|
||||
return;
|
||||
|
|
|
@ -355,8 +355,6 @@ public:
|
|||
|
||||
// nsIContentSink (superclass of nsIHTMLContentSink)
|
||||
NS_IMETHOD WillParse() { return NS_OK; }
|
||||
NS_IMETHOD WillBuildModel() { return NS_OK; }
|
||||
NS_IMETHOD DidBuildModel() { return NS_OK; }
|
||||
NS_IMETHOD WillInterrupt() { return NS_OK; }
|
||||
NS_IMETHOD WillResume() { return NS_OK; }
|
||||
NS_IMETHOD SetParser(nsIParser* aParser) { return NS_OK; }
|
||||
|
|
|
@ -329,13 +329,29 @@ function placesAggregateTransactions(name, transactions) {
|
|||
this._name = name;
|
||||
this.container = -1;
|
||||
this.redoTransaction = this.doTransaction;
|
||||
|
||||
// Check child transactions number. We will batch if we have more than
|
||||
// MIN_TRANSACTIONS_FOR_BATCH total number of transactions.
|
||||
var countTransactions = function(aTransactions, aTxnCount) {
|
||||
for (let i = 0;
|
||||
i < aTransactions.length && aTxnCount < MIN_TRANSACTIONS_FOR_BATCH;
|
||||
i++, aTxnCount++) {
|
||||
let txn = aTransactions[i].wrappedJSObject;
|
||||
if (txn && txn.childTransactions && txn.childTransactions.length)
|
||||
aTxnCount = countTransactions(txn.childTransactions, aTxnCount);
|
||||
}
|
||||
return aTxnCount;
|
||||
}
|
||||
|
||||
var txnCount = countTransactions(transactions, 0);
|
||||
this._useBatch = txnCount >= MIN_TRANSACTIONS_FOR_BATCH;
|
||||
}
|
||||
|
||||
placesAggregateTransactions.prototype = {
|
||||
__proto__: placesBaseTransaction.prototype,
|
||||
|
||||
doTransaction: function PAT_doTransaction() {
|
||||
if (this._transactions.length >= MIN_TRANSACTIONS_FOR_BATCH) {
|
||||
if (this._useBatch) {
|
||||
var callback = {
|
||||
_self: this,
|
||||
runBatched: function() {
|
||||
|
@ -349,7 +365,7 @@ placesAggregateTransactions.prototype = {
|
|||
},
|
||||
|
||||
undoTransaction: function PAT_undoTransaction() {
|
||||
if (this._transactions.length >= MIN_TRANSACTIONS_FOR_BATCH) {
|
||||
if (this._useBatch) {
|
||||
var callback = {
|
||||
_self: this,
|
||||
runBatched: function() {
|
||||
|
@ -363,7 +379,9 @@ placesAggregateTransactions.prototype = {
|
|||
},
|
||||
|
||||
commit: function PAT_commit(aUndo) {
|
||||
var transactions = this._transactions;
|
||||
// Use a copy of the transactions array, so we won't reverse the original
|
||||
// one on undoing.
|
||||
var transactions = this._transactions.slice(0);
|
||||
if (aUndo)
|
||||
transactions.reverse();
|
||||
for (var i = 0; i < transactions.length; i++) {
|
||||
|
@ -386,7 +404,7 @@ function placesCreateFolderTransactions(aName, aContainer, aIndex,
|
|||
this._index = typeof(aIndex) == "number" ? aIndex : -1;
|
||||
this._annotations = aAnnotations;
|
||||
this._id = null;
|
||||
this._childItemsTransactions = aChildItemsTransactions || [];
|
||||
this.childTransactions = aChildItemsTransactions || [];
|
||||
this.redoTransaction = this.doTransaction;
|
||||
}
|
||||
|
||||
|
@ -403,19 +421,25 @@ placesCreateFolderTransactions.prototype = {
|
|||
if (this._annotations && this._annotations.length > 0)
|
||||
PlacesUtils.setAnnotationsForItem(this._id, this._annotations);
|
||||
|
||||
for (var i = 0; i < this._childItemsTransactions.length; ++i) {
|
||||
var txn = this._childItemsTransactions[i];
|
||||
txn.wrappedJSObject.container = this._id;
|
||||
txn.doTransaction();
|
||||
if (this.childTransactions.length) {
|
||||
// Set the new container id into child transactions.
|
||||
for (var i = 0; i < this.childTransactions.length; ++i) {
|
||||
this.childTransactions[i].wrappedJSObject.container = this._id;
|
||||
}
|
||||
|
||||
let aggregateTxn = new placesAggregateTransactions("Create folder childTxn",
|
||||
this.childTransactions);
|
||||
aggregateTxn.doTransaction();
|
||||
}
|
||||
},
|
||||
|
||||
undoTransaction: function PCFT_undoTransaction() {
|
||||
// Undo transactions should always be done in reverse order.
|
||||
for (var i = this._childItemsTransactions.length - 1; i >= 0 ; i--) {
|
||||
var txn = this._childItemsTransactions[i];
|
||||
txn.undoTransaction();
|
||||
if (this.childTransactions.length) {
|
||||
let aggregateTxn = new placesAggregateTransactions("Create folder childTxn",
|
||||
this.childTransactions);
|
||||
aggregateTxn.undoTransaction();
|
||||
}
|
||||
|
||||
// Remove item only after all child transactions have been reverted.
|
||||
PlacesUtils.bookmarks.removeFolder(this._id);
|
||||
}
|
||||
|
@ -430,7 +454,7 @@ function placesCreateItemTransactions(aURI, aContainer, aIndex, aTitle,
|
|||
this._title = aTitle;
|
||||
this._keyword = aKeyword;
|
||||
this._annotations = aAnnotations;
|
||||
this._childTransactions = aChildTransactions || [];
|
||||
this.childTransactions = aChildTransactions || [];
|
||||
this.redoTransaction = this.doTransaction;
|
||||
}
|
||||
|
||||
|
@ -448,20 +472,26 @@ placesCreateItemTransactions.prototype = {
|
|||
PlacesUtils.bookmarks.setKeywordForBookmark(this._id, this._keyword);
|
||||
if (this._annotations && this._annotations.length > 0)
|
||||
PlacesUtils.setAnnotationsForItem(this._id, this._annotations);
|
||||
|
||||
for (var i = 0; i < this._childTransactions.length; ++i) {
|
||||
var txn = this._childTransactions[i];
|
||||
txn.wrappedJSObject.id = this._id;
|
||||
txn.doTransaction();
|
||||
|
||||
if (this.childTransactions.length) {
|
||||
// Set the new item id into child transactions.
|
||||
for (var i = 0; i < this.childTransactions.length; ++i) {
|
||||
this.childTransactions[i].wrappedJSObject.id = this._id;
|
||||
}
|
||||
let aggregateTxn = new placesAggregateTransactions("Create item childTxn",
|
||||
this.childTransactions);
|
||||
aggregateTxn.doTransaction();
|
||||
}
|
||||
},
|
||||
|
||||
undoTransaction: function PCIT_undoTransaction() {
|
||||
// Undo transactions should always be done in reverse order.
|
||||
for (var i = this._childTransactions.length - 1; i >= 0; i--) {
|
||||
var txn = this._childTransactions[i];
|
||||
txn.undoTransaction();
|
||||
if (this.childTransactions.length) {
|
||||
// Undo transactions should always be done in reverse order.
|
||||
let aggregateTxn = new placesAggregateTransactions("Create item childTxn",
|
||||
this.childTransactions);
|
||||
aggregateTxn.undoTransaction();
|
||||
}
|
||||
|
||||
// Remove item only after all child transactions have been reverted.
|
||||
PlacesUtils.bookmarks.removeItem(this._id);
|
||||
}
|
||||
|
@ -598,9 +628,10 @@ function placesRemoveItemTransaction(aItemId) {
|
|||
this._id = aItemId;
|
||||
this._itemType = PlacesUtils.bookmarks.getItemType(this._id);
|
||||
if (this._itemType == Ci.nsINavBookmarksService.TYPE_FOLDER) {
|
||||
this._transactions = [];
|
||||
this._removeTxn = PlacesUtils.bookmarks
|
||||
.getRemoveFolderTransaction(this._id);
|
||||
this.childTransactions = this._getFolderContentsTransactions();
|
||||
// Remove this folder itself.
|
||||
let txn = PlacesUtils.bookmarks.getRemoveFolderTransaction(this._id);
|
||||
this.childTransactions.push(txn);
|
||||
}
|
||||
else if (this._itemType == Ci.nsINavBookmarksService.TYPE_BOOKMARK) {
|
||||
this._uri = PlacesUtils.bookmarks.getBookmarkURI(this._id);
|
||||
|
@ -623,14 +654,9 @@ placesRemoveItemTransaction.prototype = {
|
|||
this._oldIndex = PlacesUtils.bookmarks.getItemIndex(this._id);
|
||||
|
||||
if (this._itemType == Ci.nsINavBookmarksService.TYPE_FOLDER) {
|
||||
this._saveFolderContents();
|
||||
|
||||
// Remove children backwards to preserve parent-child relationships.
|
||||
for (var i = this._transactions.length - 1; i >= 0; --i)
|
||||
this._transactions[i].doTransaction();
|
||||
|
||||
// Remove this folder itself.
|
||||
this._removeTxn.doTransaction();
|
||||
let aggregateTxn = new placesAggregateTransactions("Remove item childTxn",
|
||||
this.childTransactions);
|
||||
aggregateTxn.doTransaction();
|
||||
}
|
||||
else {
|
||||
PlacesUtils.bookmarks.removeItem(this._id);
|
||||
|
@ -658,10 +684,9 @@ placesRemoveItemTransaction.prototype = {
|
|||
PlacesUtils.bookmarks.setKeywordForBookmark(this._id, this._keyword);
|
||||
}
|
||||
else if (this._itemType == Ci.nsINavBookmarksService.TYPE_FOLDER) {
|
||||
this._removeTxn.undoTransaction();
|
||||
// Create children forwards to preserve parent-child relationships.
|
||||
for (var i = 0; i < this._transactions.length; ++i)
|
||||
this._transactions[i].undoTransaction();
|
||||
let aggregateTxn = new placesAggregateTransactions("Remove item childTxn",
|
||||
this.childTransactions);
|
||||
aggregateTxn.undoTransaction();
|
||||
}
|
||||
else // TYPE_SEPARATOR
|
||||
this._id = PlacesUtils.bookmarks.insertSeparator(this._oldContainer, this._oldIndex);
|
||||
|
@ -674,18 +699,21 @@ placesRemoveItemTransaction.prototype = {
|
|||
},
|
||||
|
||||
/**
|
||||
* Create a flat, ordered list of transactions for a depth-first recreation
|
||||
* Returns a flat, ordered list of transactions for a depth-first recreation
|
||||
* of items within this folder.
|
||||
*/
|
||||
_saveFolderContents: function PRIT__saveFolderContents() {
|
||||
this._transactions = [];
|
||||
_getFolderContentsTransactions:
|
||||
function PRIT__getFolderContentsTransactions() {
|
||||
var transactions = [];
|
||||
var contents =
|
||||
PlacesUtils.getFolderContents(this._id, false, false).root;
|
||||
for (var i = 0; i < contents.childCount; ++i) {
|
||||
this._transactions
|
||||
.push(new placesRemoveItemTransaction(contents.getChild(i).itemId));
|
||||
let txn = new placesRemoveItemTransaction(contents.getChild(i).itemId);
|
||||
transactions.push(txn);
|
||||
}
|
||||
contents.containerOpen = false;
|
||||
// Reverse transactions to preserve parent-child relationship.
|
||||
return transactions.reverse();
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -60,6 +60,8 @@ _BROWSER_TEST_FILES = \
|
|||
browser_library_left_pane_commands.js \
|
||||
browser_drag_bookmarks_on_toolbar.js \
|
||||
browser_library_middleclick.js \
|
||||
browser_library_views_liveupdate.js \
|
||||
browser_views_liveupdate.js \
|
||||
$(NULL)
|
||||
|
||||
libs:: $(_BROWSER_TEST_FILES)
|
||||
|
|
|
@ -84,6 +84,10 @@ var gTabsListener = {
|
|||
if (gCurrentTest.URIs.indexOf(spec) != -1 )
|
||||
this._loadedURIs.push(spec);
|
||||
|
||||
var fm = Components.classes["@mozilla.org/focus-manager;1"].
|
||||
getService(Components.interfaces.nsIFocusManager);
|
||||
is(fm.activeWindow, gBrowser.ownerDocument.defaultView, "window made active");
|
||||
|
||||
if (this._loadedURIs.length == gCurrentTest.URIs.length) {
|
||||
// We have correctly opened all URIs.
|
||||
|
||||
|
|
|
@ -0,0 +1,320 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Marco Bonardo <mak77@bonardo.net>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
/**
|
||||
* Tests Library Left pane view for liveupdate.
|
||||
*/
|
||||
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
|
||||
var gLibrary = null;
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
// Sanity checks.
|
||||
ok(PlacesUtils, "PlacesUtils in context");
|
||||
ok(PlacesUIUtils, "PlacesUIUtils in context");
|
||||
|
||||
// Open Library, we will check the left pane.
|
||||
var ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].
|
||||
getService(Ci.nsIWindowWatcher);
|
||||
var windowObserver = {
|
||||
observe: function(aSubject, aTopic, aData) {
|
||||
if (aTopic === "domwindowopened") {
|
||||
ww.unregisterNotification(this);
|
||||
gLibrary = aSubject.QueryInterface(Ci.nsIDOMWindow);
|
||||
gLibrary.addEventListener("load", function onLoad(event) {
|
||||
gLibrary.removeEventListener("load", onLoad, false);
|
||||
executeSoon(startTest);
|
||||
}, false);
|
||||
}
|
||||
}
|
||||
};
|
||||
ww.registerNotification(windowObserver);
|
||||
ww.openWindow(null,
|
||||
"chrome://browser/content/places/places.xul",
|
||||
"",
|
||||
"chrome,toolbar=yes,dialog=no,resizable",
|
||||
null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds bookmarks observer, and executes a bunch of bookmarks operations.
|
||||
*/
|
||||
function startTest() {
|
||||
var bs = PlacesUtils.bookmarks;
|
||||
// Add bookmarks observer.
|
||||
bs.addObserver(bookmarksObserver, false);
|
||||
var addedBookmarks = [];
|
||||
|
||||
// MENU
|
||||
ok(true, "*** Acting on menu bookmarks");
|
||||
var id = bs.insertBookmark(bs.bookmarksMenuFolder,
|
||||
PlacesUtils._uri("http://bm1.mozilla.org/"),
|
||||
bs.DEFAULT_INDEX,
|
||||
"bm1");
|
||||
addedBookmarks.push(id);
|
||||
id = bs.insertBookmark(bs.bookmarksMenuFolder,
|
||||
PlacesUtils._uri("place:"),
|
||||
bs.DEFAULT_INDEX,
|
||||
"bm2");
|
||||
addedBookmarks.push(id);
|
||||
id = bs.insertSeparator(bs.bookmarksMenuFolder, bs.DEFAULT_INDEX);
|
||||
addedBookmarks.push(id);
|
||||
id = bs.createFolder(bs.bookmarksMenuFolder,
|
||||
"bmf",
|
||||
bs.DEFAULT_INDEX);
|
||||
addedBookmarks.push(id);
|
||||
id = bs.insertBookmark(id,
|
||||
PlacesUtils._uri("http://bmf1.mozilla.org/"),
|
||||
bs.DEFAULT_INDEX,
|
||||
"bmf1");
|
||||
addedBookmarks.push(id);
|
||||
bs.moveItem(id, bs.bookmarksMenuFolder, 0);
|
||||
|
||||
// TOOLBAR
|
||||
ok(true, "*** Acting on toolbar bookmarks");
|
||||
bs.insertBookmark(bs.toolbarFolder,
|
||||
PlacesUtils._uri("http://tb1.mozilla.org/"),
|
||||
bs.DEFAULT_INDEX,
|
||||
"tb1");
|
||||
addedBookmarks.push(id);
|
||||
id = bs.insertBookmark(bs.toolbarFolder,
|
||||
PlacesUtils._uri("place:"),
|
||||
bs.DEFAULT_INDEX,
|
||||
"tb2");
|
||||
addedBookmarks.push(id);
|
||||
id = bs.insertSeparator(bs.toolbarFolder, bs.DEFAULT_INDEX);
|
||||
addedBookmarks.push(id);
|
||||
id = bs.createFolder(bs.toolbarFolder,
|
||||
"tbf",
|
||||
bs.DEFAULT_INDEX);
|
||||
addedBookmarks.push(id);
|
||||
id = bs.insertBookmark(id,
|
||||
PlacesUtils._uri("http://tbf1.mozilla.org/"),
|
||||
bs.DEFAULT_INDEX,
|
||||
"bmf1");
|
||||
addedBookmarks.push(id);
|
||||
bs.moveItem(id, bs.toolbarFolder, 0);
|
||||
|
||||
// UNSORTED
|
||||
ok(true, "*** Acting on unsorted bookmarks");
|
||||
id = bs.insertBookmark(bs.unfiledBookmarksFolder,
|
||||
PlacesUtils._uri("http://ub1.mozilla.org/"),
|
||||
bs.DEFAULT_INDEX,
|
||||
"ub1");
|
||||
addedBookmarks.push(id);
|
||||
id = bs.insertBookmark(bs.unfiledBookmarksFolder,
|
||||
PlacesUtils._uri("place:"),
|
||||
bs.DEFAULT_INDEX,
|
||||
"ub2");
|
||||
addedBookmarks.push(id);
|
||||
id = bs.insertSeparator(bs.unfiledBookmarksFolder, bs.DEFAULT_INDEX);
|
||||
addedBookmarks.push(id);
|
||||
id = bs.createFolder(bs.unfiledBookmarksFolder,
|
||||
"ubf",
|
||||
bs.DEFAULT_INDEX);
|
||||
addedBookmarks.push(id);
|
||||
id = bs.insertBookmark(id,
|
||||
PlacesUtils._uri("http://ubf1.mozilla.org/"),
|
||||
bs.DEFAULT_INDEX,
|
||||
"ubf1");
|
||||
addedBookmarks.push(id);
|
||||
bs.moveItem(id, bs.unfiledBookmarksFolder, 0);
|
||||
|
||||
// Remove all added bookmarks.
|
||||
addedBookmarks.forEach(function (aItem) {
|
||||
// If we remove an item after its containing folder has been removed,
|
||||
// this will throw, but we can ignore that.
|
||||
try {
|
||||
bs.removeItem(aItem);
|
||||
} catch (ex) {}
|
||||
});
|
||||
|
||||
// Remove bookmarks observer.
|
||||
bs.removeObserver(bookmarksObserver);
|
||||
finishTest();
|
||||
}
|
||||
|
||||
/**
|
||||
* Restores browser state and calls finish.
|
||||
*/
|
||||
function finishTest() {
|
||||
// Close Library window.
|
||||
gLibrary.close();
|
||||
finish();
|
||||
}
|
||||
|
||||
/**
|
||||
* The observer is where magic happens, for every change we do it will look for
|
||||
* nodes positions in the affected views.
|
||||
*/
|
||||
var bookmarksObserver = {
|
||||
QueryInterface: function PSB_QueryInterface(aIID) {
|
||||
if (aIID.equals(Ci.nsINavBookmarkObserver) ||
|
||||
aIID.equals(Ci.nsISupports))
|
||||
return this;
|
||||
throw Cr.NS_NOINTERFACE;
|
||||
},
|
||||
|
||||
// nsINavBookmarkObserver
|
||||
onItemAdded: function PSB_onItemAdded(aItemId, aFolderId, aIndex) {
|
||||
var node = null;
|
||||
var index = null;
|
||||
[node, index] = getNodeForTreeItem(aItemId, gLibrary.PlacesOrganizer._places);
|
||||
// Left pane should not be updated for normal bookmarks or separators.
|
||||
var type = PlacesUtils.bookmarks.getItemType(aItemId);
|
||||
switch (type) {
|
||||
case PlacesUtils.bookmarks.TYPE_BOOKMARK:
|
||||
var uriString = PlacesUtils.bookmarks.getBookmarkURI(aItemId).spec;
|
||||
var isQuery = uriString.substr(0, 6) == "place:";
|
||||
if (isQuery) {
|
||||
isnot(node, null, "Found new Places node in left pane");
|
||||
ok(index >= 0, "Node is at index " + index);
|
||||
break;
|
||||
}
|
||||
// Fallback to separator case if this is not a query.
|
||||
case PlacesUtils.bookmarks.TYPE_SEPARATOR:
|
||||
is(node, null, "New Places node not added in left pane");
|
||||
break;
|
||||
default:
|
||||
isnot(node, null, "Found new Places node in left pane");
|
||||
ok(index >= 0, "Node is at index " + index);
|
||||
}
|
||||
},
|
||||
|
||||
onItemRemoved: function PSB_onItemRemoved(aItemId, aFolder, aIndex) {
|
||||
var node = null;
|
||||
var index = null;
|
||||
[node, index] = getNodeForTreeItem(aItemId, gLibrary.PlacesOrganizer._places);
|
||||
is(node, null, "Places node not found in left pane");
|
||||
},
|
||||
|
||||
onItemMoved: function(aItemId,
|
||||
aOldFolderId, aOldIndex,
|
||||
aNewFolderId, aNewIndex) {
|
||||
var node = null;
|
||||
var index = null;
|
||||
[node, index] = getNodeForTreeItem(aItemId, gLibrary.PlacesOrganizer._places);
|
||||
// Left pane should not be updated for normal bookmarks or separators.
|
||||
var type = PlacesUtils.bookmarks.getItemType(aItemId);
|
||||
switch (type) {
|
||||
case PlacesUtils.bookmarks.TYPE_BOOKMARK:
|
||||
var uriString = PlacesUtils.bookmarks.getBookmarkURI(aItemId).spec;
|
||||
var isQuery = uriString.substr(0, 6) == "place:";
|
||||
if (isQuery) {
|
||||
isnot(node, null, "Found new Places node in left pane");
|
||||
ok(index >= 0, "Node is at index " + index);
|
||||
break;
|
||||
}
|
||||
// Fallback to separator case if this is not a query.
|
||||
case type == PlacesUtils.bookmarks.TYPE_SEPARATOR:
|
||||
is(node, null, "New Places node not added in left pane");
|
||||
break;
|
||||
default:
|
||||
isnot(node, null, "Found new Places node in left pane");
|
||||
ok(index >= 0, "Node is at index " + index);
|
||||
}
|
||||
},
|
||||
|
||||
onBeginUpdateBatch: function PSB_onBeginUpdateBatch() {},
|
||||
onEndUpdateBatch: function PSB_onEndUpdateBatch() {},
|
||||
onBeforeItemRemoved: function PSB_onBeforeItemRemoved(aItemId) {},
|
||||
onItemVisited: function() {},
|
||||
onItemChanged: function PSB_onItemChanged(aItemId, aProperty,
|
||||
aIsAnnotationProperty, aValue) {}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get places node and index for an itemId in a tree view.
|
||||
*
|
||||
* @param aItemId
|
||||
* item id of the item to search.
|
||||
* @returns [node, index] or [null, null] if not found.
|
||||
*/
|
||||
function getNodeForTreeItem(aItemId, aTree) {
|
||||
|
||||
function findNode(aContainerIndex) {
|
||||
if (aTree.view.isContainerEmpty(aContainerIndex))
|
||||
return [null, null];
|
||||
|
||||
// The rowCount limit is just for sanity, but we will end looping when
|
||||
// we have checked the last child of this container or we have found node.
|
||||
for (var i = aContainerIndex + 1; i < aTree.view.rowCount; i++) {
|
||||
var node = aTree.view.nodeForTreeIndex(i);
|
||||
|
||||
if (node.itemId == aItemId) {
|
||||
// Minus one because we want relative index inside the container.
|
||||
return [node, i - aTree.view.getParentIndex(i) - 1];
|
||||
}
|
||||
|
||||
if (PlacesUtils.nodeIsFolder(node)) {
|
||||
// Open container.
|
||||
aTree.view.toggleOpenState(i);
|
||||
// Search inside it.
|
||||
var foundNode = findNode(i);
|
||||
// Close container.
|
||||
aTree.view.toggleOpenState(i);
|
||||
// Return node if found.
|
||||
if (foundNode[0] != null)
|
||||
return foundNode;
|
||||
}
|
||||
|
||||
// We have finished walking this container.
|
||||
if (!aTree.view.hasNextSibling(aContainerIndex + 1, i))
|
||||
break;
|
||||
}
|
||||
return [null, null]
|
||||
}
|
||||
|
||||
// Root node is hidden, so we need to manually walk the first level.
|
||||
for (var i = 0; i < aTree.view.rowCount; i++) {
|
||||
// Open container.
|
||||
aTree.view.toggleOpenState(i);
|
||||
// Search inside it.
|
||||
var foundNode = findNode(i);
|
||||
// Close container.
|
||||
aTree.view.toggleOpenState(i);
|
||||
// Return node if found.
|
||||
if (foundNode[0] != null)
|
||||
return foundNode;
|
||||
}
|
||||
return [null, null];
|
||||
}
|
|
@ -0,0 +1,438 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Marco Bonardo <mak77@bonardo.net>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
/**
|
||||
* Tests Places views (menu, toolbar, tree) for liveupdate.
|
||||
*/
|
||||
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
|
||||
function test() {
|
||||
dump("Starting test browser_views_liveupdate.js\n");
|
||||
waitForExplicitFinish();
|
||||
|
||||
// Sanity checks.
|
||||
ok(PlacesUtils, "PlacesUtils in context");
|
||||
ok(PlacesUIUtils, "PlacesUIUtils in context");
|
||||
|
||||
// Open bookmarks menu.
|
||||
var menu = document.getElementById("bookmarksMenu");
|
||||
menu.open = true;
|
||||
|
||||
// Open bookmarks sidebar.
|
||||
var sidebar = document.getElementById("sidebar");
|
||||
sidebar.addEventListener("load", function() {
|
||||
sidebar.removeEventListener("load", arguments.callee, true);
|
||||
// Need to executeSoon since the tree is initialized on sidebar load.
|
||||
executeSoon(startTest);
|
||||
}, true);
|
||||
toggleSidebar("viewBookmarksSidebar", true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds bookmarks observer, and executes a bunch of bookmarks operations.
|
||||
*/
|
||||
function startTest() {
|
||||
var bs = PlacesUtils.bookmarks;
|
||||
// Add bookmarks observer.
|
||||
bs.addObserver(bookmarksObserver, false);
|
||||
var addedBookmarks = [];
|
||||
|
||||
// MENU
|
||||
ok(true, "*** Acting on menu bookmarks");
|
||||
var id = bs.insertBookmark(bs.bookmarksMenuFolder,
|
||||
PlacesUtils._uri("http://bm1.mozilla.org/"),
|
||||
bs.DEFAULT_INDEX,
|
||||
"bm1");
|
||||
addedBookmarks.push(id);
|
||||
id = bs.insertBookmark(bs.bookmarksMenuFolder,
|
||||
PlacesUtils._uri("place:"),
|
||||
bs.DEFAULT_INDEX,
|
||||
"bm2");
|
||||
addedBookmarks.push(id);
|
||||
id = bs.insertSeparator(bs.bookmarksMenuFolder, bs.DEFAULT_INDEX);
|
||||
addedBookmarks.push(id);
|
||||
id = bs.createFolder(bs.bookmarksMenuFolder,
|
||||
"bmf",
|
||||
bs.DEFAULT_INDEX);
|
||||
addedBookmarks.push(id);
|
||||
id = bs.insertBookmark(id,
|
||||
PlacesUtils._uri("http://bmf1.mozilla.org/"),
|
||||
bs.DEFAULT_INDEX,
|
||||
"bmf1");
|
||||
addedBookmarks.push(id);
|
||||
bs.moveItem(id, bs.bookmarksMenuFolder, 0);
|
||||
|
||||
// TOOLBAR
|
||||
ok(true, "*** Acting on toolbar bookmarks");
|
||||
id = bs.insertBookmark(bs.toolbarFolder,
|
||||
PlacesUtils._uri("http://tb1.mozilla.org/"),
|
||||
bs.DEFAULT_INDEX,
|
||||
"tb1");
|
||||
addedBookmarks.push(id);
|
||||
id = bs.insertBookmark(bs.toolbarFolder,
|
||||
PlacesUtils._uri("place:"),
|
||||
bs.DEFAULT_INDEX,
|
||||
"tb2");
|
||||
addedBookmarks.push(id);
|
||||
id = bs.insertSeparator(bs.toolbarFolder, bs.DEFAULT_INDEX);
|
||||
addedBookmarks.push(id);
|
||||
id = bs.createFolder(bs.toolbarFolder,
|
||||
"tbf",
|
||||
bs.DEFAULT_INDEX);
|
||||
addedBookmarks.push(id);
|
||||
id = bs.insertBookmark(id,
|
||||
PlacesUtils._uri("http://tbf1.mozilla.org/"),
|
||||
bs.DEFAULT_INDEX,
|
||||
"bmf1");
|
||||
addedBookmarks.push(id);
|
||||
bs.moveItem(id, bs.toolbarFolder, 0);
|
||||
|
||||
// UNSORTED
|
||||
ok(true, "*** Acting on unsorted bookmarks");
|
||||
id = bs.insertBookmark(bs.unfiledBookmarksFolder,
|
||||
PlacesUtils._uri("http://ub1.mozilla.org/"),
|
||||
bs.DEFAULT_INDEX,
|
||||
"ub1");
|
||||
addedBookmarks.push(id);
|
||||
id = bs.insertBookmark(bs.unfiledBookmarksFolder,
|
||||
PlacesUtils._uri("place:"),
|
||||
bs.DEFAULT_INDEX,
|
||||
"ub2");
|
||||
addedBookmarks.push(id);
|
||||
id = bs.insertSeparator(bs.unfiledBookmarksFolder, bs.DEFAULT_INDEX);
|
||||
addedBookmarks.push(id);
|
||||
id = bs.createFolder(bs.unfiledBookmarksFolder,
|
||||
"ubf",
|
||||
bs.DEFAULT_INDEX);
|
||||
addedBookmarks.push(id);
|
||||
id = bs.insertBookmark(id,
|
||||
PlacesUtils._uri("http://ubf1.mozilla.org/"),
|
||||
bs.DEFAULT_INDEX,
|
||||
"bubf1");
|
||||
addedBookmarks.push(id);
|
||||
bs.moveItem(id, bs.unfiledBookmarksFolder, 0);
|
||||
|
||||
// Remove all added bookmarks.
|
||||
addedBookmarks.forEach(function (aItem) {
|
||||
// If we remove an item after its containing folder has been removed,
|
||||
// this will throw, but we can ignore that.
|
||||
try {
|
||||
bs.removeItem(aItem);
|
||||
} catch (ex) {}
|
||||
});
|
||||
|
||||
// Remove bookmarks observer.
|
||||
bs.removeObserver(bookmarksObserver);
|
||||
finishTest();
|
||||
}
|
||||
|
||||
/**
|
||||
* Restores browser state and calls finish.
|
||||
*/
|
||||
function finishTest() {
|
||||
// Close bookmarks menu.
|
||||
var menu = document.getElementById("bookmarksMenu");
|
||||
menu.open = false;
|
||||
|
||||
// Close bookmarks sidebar.
|
||||
toggleSidebar("viewBookmarksSidebar", false);
|
||||
|
||||
finish();
|
||||
}
|
||||
|
||||
/**
|
||||
* The observer is where magic happens, for every change we do it will look for
|
||||
* nodes positions in the affected views.
|
||||
*/
|
||||
var bookmarksObserver = {
|
||||
QueryInterface: function PSB_QueryInterface(aIID) {
|
||||
if (aIID.equals(Ci.nsINavBookmarkObserver) ||
|
||||
aIID.equals(Ci.nsISupports))
|
||||
return this;
|
||||
throw Cr.NS_NOINTERFACE;
|
||||
},
|
||||
|
||||
// nsINavBookmarkObserver
|
||||
onItemAdded: function PSB_onItemAdded(aItemId, aFolderId, aIndex) {
|
||||
var views = getViewsForFolder(aFolderId);
|
||||
ok(views.length > 0, "Found affected views: " + views);
|
||||
|
||||
// Check that item has been added in the correct position.
|
||||
for (var i = 0; i < views.length; i++) {
|
||||
var node = null;
|
||||
var index = null;
|
||||
[node, index] = searchItemInView(aItemId, views[i]);
|
||||
isnot(node, null, "Found new Places node in " + views[i]);
|
||||
is(index, aIndex, "Node is at index " + index);
|
||||
}
|
||||
},
|
||||
|
||||
onItemRemoved: function PSB_onItemRemoved(aItemId, aFolder, aIndex) {
|
||||
var views = getViewsForFolder(aFolderId);
|
||||
ok(views.length > 0, "Found affected views: " + views);
|
||||
// Check that item has been removed.
|
||||
for (var i = 0; i < views.length; i++) {
|
||||
var node = null;
|
||||
var index = null;
|
||||
[node, index] = searchItemInView(aItemId, views[i]);
|
||||
is(node, null, "Places node not found in " + views[i]);
|
||||
}
|
||||
},
|
||||
|
||||
onItemMoved: function(aItemId,
|
||||
aOldFolderId, aOldIndex,
|
||||
aNewFolderId, aNewIndex) {
|
||||
var views = getViewsForFolder(aNewFolderId);
|
||||
ok(views.length > 0, "Found affected views: " + views);
|
||||
|
||||
// Check that item has been moved in the correct position.
|
||||
for (var i = 0; i < views.length; i++) {
|
||||
var node = null;
|
||||
var index = null;
|
||||
[node, index] = searchItemInView(aItemId, views[i]);
|
||||
isnot(node, null, "Found new Places node in " + views[i]);
|
||||
is(index, aNewIndex, "Node is at index " + index);
|
||||
}
|
||||
},
|
||||
|
||||
onBeginUpdateBatch: function PSB_onBeginUpdateBatch() {},
|
||||
onEndUpdateBatch: function PSB_onEndUpdateBatch() {},
|
||||
onBeforeItemRemoved: function PSB_onBeforeItemRemoved(aItemId) {},
|
||||
onItemVisited: function() {},
|
||||
onItemChanged: function PSB_onItemChanged(aItemId, aProperty,
|
||||
aIsAnnotationProperty, aValue) {}
|
||||
};
|
||||
|
||||
/**
|
||||
* Search an item id in a view.
|
||||
*
|
||||
* @param aItemId
|
||||
* item id of the item to search.
|
||||
* @param aView
|
||||
* either "toolbar", "menu" or "sidebar"
|
||||
* @returns [node, index] or [null, null] if not found.
|
||||
*/
|
||||
function searchItemInView(aItemId, aView) {
|
||||
var node = null;
|
||||
var index = null;
|
||||
switch (aView) {
|
||||
case "toolbar":
|
||||
return getNodeForToolbarItem(aItemId);
|
||||
case "menu":
|
||||
return getNodeForMenuItem(aItemId);
|
||||
case "sidebar":
|
||||
return getNodeForSidebarItem(aItemId);
|
||||
}
|
||||
|
||||
return [null, null];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get places node and index for an itemId in bookmarks toolbar view.
|
||||
*
|
||||
* @param aItemId
|
||||
* item id of the item to search.
|
||||
* @returns [node, index] or [null, null] if not found.
|
||||
*/
|
||||
function getNodeForToolbarItem(aItemId) {
|
||||
var toolbar = document.getElementById("bookmarksBarContent");
|
||||
|
||||
function findNode(aContainer) {
|
||||
var children = aContainer.childNodes;
|
||||
for (var i = 0, staticNodes = 0; i < children.length; i++) {
|
||||
var child = children[i];
|
||||
|
||||
// Is this a Places node?
|
||||
if (!child.node) {
|
||||
staticNodes++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (child.node.itemId == aItemId)
|
||||
return [child.node, i - staticNodes];
|
||||
|
||||
// Don't search in queries, they could contain our item in a
|
||||
// different position. Search only folders
|
||||
if (PlacesUtils.nodeIsFolder(child.node)) {
|
||||
var popup = child.lastChild;
|
||||
popup.showPopup(popup);
|
||||
foundNode = findNode(popup);
|
||||
popup.hidePopup();
|
||||
if (foundNode[0] != null)
|
||||
return foundNode;
|
||||
}
|
||||
}
|
||||
return [null, null];
|
||||
}
|
||||
|
||||
return findNode(toolbar);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get places node and index for an itemId in bookmarks menu view.
|
||||
*
|
||||
* @param aItemId
|
||||
* item id of the item to search.
|
||||
* @returns [node, index] or [null, null] if not found.
|
||||
*/
|
||||
function getNodeForMenuItem(aItemId) {
|
||||
var menu = document.getElementById("bookmarksMenu");
|
||||
|
||||
function findNode(aContainer) {
|
||||
var children = aContainer.childNodes;
|
||||
for (var i = 0, staticNodes = 0; i < children.length; i++) {
|
||||
var child = children[i];
|
||||
|
||||
// Is this a Places node?
|
||||
if (!child.node) {
|
||||
staticNodes++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (child.node.itemId == aItemId)
|
||||
return [child.node, i - staticNodes];
|
||||
|
||||
// Don't search in queries, they could contain our item in a
|
||||
// different position. Search only folders
|
||||
if (PlacesUtils.nodeIsFolder(child.node)) {
|
||||
var popup = child.lastChild;
|
||||
// XXX Why is this needed on Linux and Mac?
|
||||
popup.showPopup(popup);
|
||||
child.open = true;
|
||||
foundNode = findNode(popup);
|
||||
popup.hidePopup();
|
||||
child.open = false;
|
||||
if (foundNode[0] != null)
|
||||
return foundNode;
|
||||
}
|
||||
}
|
||||
return [null, null];
|
||||
}
|
||||
|
||||
return findNode(menu.lastChild);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get places node and index for an itemId in sidebar tree view.
|
||||
*
|
||||
* @param aItemId
|
||||
* item id of the item to search.
|
||||
* @returns [node, index] or [null, null] if not found.
|
||||
*/
|
||||
function getNodeForSidebarItem(aItemId) {
|
||||
ok(true, "getNodeForSidebar");
|
||||
var sidebar = document.getElementById("sidebar");
|
||||
var tree = sidebar.contentDocument.getElementById("bookmarks-view");
|
||||
|
||||
function findNode(aContainerIndex) {
|
||||
if (tree.view.isContainerEmpty(aContainerIndex))
|
||||
return [null, null];
|
||||
|
||||
// The rowCount limit is just for sanity, but we will end looping when
|
||||
// we have checked the last child of this container or we have found node.
|
||||
for (var i = aContainerIndex + 1; i < tree.view.rowCount; i++) {
|
||||
var node = tree.view.nodeForTreeIndex(i);
|
||||
|
||||
if (node.itemId == aItemId) {
|
||||
// Minus one because we want relative index inside the container.
|
||||
return [node, i - tree.view.getParentIndex(i) - 1];
|
||||
}
|
||||
|
||||
if (PlacesUtils.nodeIsFolder(node)) {
|
||||
// Open container.
|
||||
tree.view.toggleOpenState(i);
|
||||
// Search inside it.
|
||||
var foundNode = findNode(i);
|
||||
// Close container.
|
||||
tree.view.toggleOpenState(i);
|
||||
// Return node if found.
|
||||
if (foundNode[0] != null)
|
||||
return foundNode;
|
||||
}
|
||||
|
||||
// We have finished walking this container.
|
||||
if (!tree.view.hasNextSibling(aContainerIndex + 1, i))
|
||||
break;
|
||||
}
|
||||
return [null, null]
|
||||
}
|
||||
|
||||
// Root node is hidden, so we need to manually walk the first level.
|
||||
for (var i = 0; i < tree.view.rowCount; i++) {
|
||||
// Open container.
|
||||
tree.view.toggleOpenState(i);
|
||||
// Search inside it.
|
||||
var foundNode = findNode(i);
|
||||
// Close container.
|
||||
tree.view.toggleOpenState(i);
|
||||
// Return node if found.
|
||||
if (foundNode[0] != null)
|
||||
return foundNode;
|
||||
}
|
||||
return [null, null];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get views affected by changes to a folder.
|
||||
*
|
||||
* @param aFolderId:
|
||||
* item id of the folder we have changed.
|
||||
* @returns a subset of views: ["toolbar", "menu", "sidebar"]
|
||||
*/
|
||||
function getViewsForFolder(aFolderId) {
|
||||
var rootId = aFolderId;
|
||||
while (!PlacesUtils.isRootItem(rootId))
|
||||
rootId = PlacesUtils.bookmarks.getFolderIdForItem(rootId);
|
||||
|
||||
switch (rootId) {
|
||||
case PlacesUtils.toolbarFolderId:
|
||||
return ["toolbar", "sidebar"]
|
||||
break;
|
||||
case PlacesUtils.bookmarksMenuFolderId:
|
||||
// XXX Skip menu tests on Mac, due to native menubar.
|
||||
if (navigator.platform.toLowerCase().indexOf("mac") != -1)
|
||||
return ["sidebar"];
|
||||
return ["menu", "sidebar"]
|
||||
break;
|
||||
case PlacesUtils.unfiledBookmarksFolderId:
|
||||
return ["sidebar"]
|
||||
break;
|
||||
}
|
||||
return new Array();
|
||||
}
|
|
@ -664,6 +664,8 @@ function run_test() {
|
|||
do_check_eq(bmsvc.getItemIndex(bkmk3_1Id), -1);
|
||||
do_check_eq(bmsvc.getItemIndex(bkmk3_2Id), -1);
|
||||
do_check_eq(bmsvc.getItemIndex(bkmk3_3Id), -1);
|
||||
// Check last removed item id.
|
||||
do_check_eq(observer._itemRemovedId, bkmk3Id);
|
||||
|
||||
txn.undoTransaction();
|
||||
var newBkmk1Id = bmsvc.getIdForItemAt(root, 0);
|
||||
|
@ -685,6 +687,9 @@ function run_test() {
|
|||
do_check_eq(bmsvc.getFolderIdForItem(newBkmk3_3Id), newBkmk3Id);
|
||||
do_check_eq(bmsvc.getItemType(newBkmk3_3Id), bmsvc.TYPE_FOLDER);
|
||||
do_check_eq(bmsvc.getItemTitle(newBkmk3_3Id), "folder");
|
||||
// Check last added back item id.
|
||||
// Notice items are restored in reverse order.
|
||||
do_check_eq(observer._itemAddedId, newBkmk1Id);
|
||||
|
||||
txn.redoTransaction();
|
||||
do_check_eq(bmsvc.getItemIndex(newBkmk1Id), -1);
|
||||
|
@ -693,6 +698,8 @@ function run_test() {
|
|||
do_check_eq(bmsvc.getItemIndex(newBkmk3_1Id), -1);
|
||||
do_check_eq(bmsvc.getItemIndex(newBkmk3_2Id), -1);
|
||||
do_check_eq(bmsvc.getItemIndex(newBkmk3_3Id), -1);
|
||||
// Check last removed item id.
|
||||
do_check_eq(observer._itemRemovedId, newBkmk3Id);
|
||||
|
||||
txn.undoTransaction();
|
||||
newBkmk1Id = bmsvc.getIdForItemAt(root, 0);
|
||||
|
@ -714,6 +721,9 @@ function run_test() {
|
|||
do_check_eq(bmsvc.getFolderIdForItem(newBkmk3_3Id), newBkmk3Id);
|
||||
do_check_eq(bmsvc.getItemType(newBkmk3_3Id), bmsvc.TYPE_FOLDER);
|
||||
do_check_eq(bmsvc.getItemTitle(newBkmk3_3Id), "folder");
|
||||
// Check last added back item id.
|
||||
// Notice items are restored in reverse order.
|
||||
do_check_eq(observer._itemAddedId, newBkmk1Id);
|
||||
|
||||
// Test creating an item with child transactions.
|
||||
var childTxns = [];
|
||||
|
|
|
@ -1,66 +0,0 @@
|
|||
; dept.mmh
|
||||
;
|
||||
; Derived from MakeMSI's dept.mmh file:
|
||||
; (C)opyright Dennis Bareis, Australia, 2003. All rights reserved.
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
;--- Define Version number of this install support --------------------------
|
||||
;----------------------------------------------------------------------------
|
||||
#ifdef DEPT_VERSION
|
||||
;--- Die, already included -----------------------------------------------
|
||||
#error ^You have already included "<?InputComponent>"^
|
||||
#endif
|
||||
#define DEPT_VERSION 03.171
|
||||
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
;--- Obsolete values (don't use!) -------------------------------------------
|
||||
;----------------------------------------------------------------------------
|
||||
#define? DEPT_SUPPORT_WEB_URL
|
||||
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
;--- Define some Department details -----------------------------------------
|
||||
;----------------------------------------------------------------------------
|
||||
#define? DEPT_ARP_URL_PUBLISHER
|
||||
#define? DEPT_ARP_URL_TECHNICAL_SUPPORT <$DEPT_SUPPORT_WEB_URL>
|
||||
#define? DEPT_ARP_URL_APPLICATION_UPDATE_INFORMATION
|
||||
#define? DEPT_NAME Mozilla.Org
|
||||
#define? DEPT_ADDRESS United States
|
||||
#define? DEPT_MSI_MANUFACTURER <$DEPT_NAME>
|
||||
#define? DEPT_MSI_AUTHOR <$DEPT_NAME>
|
||||
;#define? COMPANY_CONTACT_NAME Fred Nerk
|
||||
;#define? COMPANY_CONTACT_NAME_PHONE (03)1234-5678
|
||||
#define? COMPANY_PACKAGED_BY Packaged by <$DEPT_NAME> (<$DEPT_ADDRESS>).
|
||||
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
;--- Define the types of boxes your department/company supports -------------
|
||||
;----------------------------------------------------------------------------
|
||||
#ifndef COMPANY_DEFINE_DEPARTMENTS_PLATFORMS
|
||||
#(
|
||||
#define COMPANY_DEFINE_DEPARTMENTS_PLATFORMS ;;COMPANY.MMH expands...
|
||||
|
||||
;--- User must override... -------------------------------------------
|
||||
<$Platform "TEST" DESC=^Testing (NOT SUPPORTED)^ PLATDIR="Testing-Unsupported">
|
||||
#)
|
||||
#endif
|
||||
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
;--- Load MAKEMSI support ---------------------------------------------------
|
||||
;----------------------------------------------------------------------------
|
||||
#NextId PUSH
|
||||
#include "mozilla.mmh"
|
||||
#NextId POP
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
;--- Make sure we record details about this header --------------------------
|
||||
;----------------------------------------------------------------------------
|
||||
<$SourceFile Version="<$DEPT_VERSION>">
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
;--- Start "location" status information (if allowed) -----------------------
|
||||
;----------------------------------------------------------------------------
|
||||
<$LocationVerboseOn> ;;Outputs messages during length processing (to prove it hasn't hung etc)
|
||||
|
|
@ -284,7 +284,12 @@ endif
|
|||
|
||||
|
||||
ident:
|
||||
@$(PYTHON) $(topsrcdir)/config/printconfigsetting.py $(STAGEDIST)/application.ini App SourceStamp
|
||||
@printf "fx_revision "
|
||||
@$(PYTHON) $(topsrcdir)/config/printconfigsetting.py \
|
||||
$(STAGEDIST)/application.ini App SourceStamp
|
||||
@printf "buildid "
|
||||
@$(PYTHON) $(topsrcdir)/config/printconfigsetting.py \
|
||||
$(STAGEDIST)/application.ini App BuildID
|
||||
|
||||
#These make targets call prepare-repackages by setting different UPLOAD_DIR
|
||||
prepare-upload-latest-%:
|
||||
|
|
|
@ -1214,7 +1214,7 @@ tabpanels {
|
|||
border: 1px dotted transparent;
|
||||
}
|
||||
|
||||
.tabbrowser-tab[selected="true"]:focus > .tab-text {
|
||||
.tabbrowser-tab:focus > .tab-text {
|
||||
border: 1px dotted -moz-DialogText;
|
||||
}
|
||||
|
||||
|
|
|
@ -1561,7 +1561,7 @@ tabbrowser > tabbox {
|
|||
background-color: -moz-mac-chrome-active;
|
||||
}
|
||||
|
||||
.tabbrowser-tab[selected="true"]:focus > .tab-text {
|
||||
.tabbrowser-tab:focus > .tab-text {
|
||||
-moz-box-shadow: 0 0 4px -moz-mac-focusring,
|
||||
0 0 4px -moz-mac-focusring,
|
||||
0 0 3px -moz-mac-focusring,
|
||||
|
|
|
@ -1404,7 +1404,7 @@ tabpanels {
|
|||
border: 1px dotted transparent;
|
||||
}
|
||||
|
||||
.tabbrowser-tab[selected="true"]:focus > .tab-text {
|
||||
.tabbrowser-tab:focus > .tab-text {
|
||||
border: 1px dotted -moz-DialogText;
|
||||
}
|
||||
|
||||
|
|
|
@ -62,8 +62,8 @@
|
|||
ac_add_options() {
|
||||
for _opt
|
||||
do
|
||||
# Escape shell characters, space, tab, dollar, quote, backslash.
|
||||
_opt=`echo $_opt | sed -e 's/\([\ \ \$\"\\]\)/\\\\\1/g;s/@\([^@]*\)@/\$\1/g;'`
|
||||
# Escape shell characters, space, tab, dollar, quote, backslash, parentheses.
|
||||
_opt=`echo $_opt | sed -e 's/\([\ \ \$\"\\\(\)]\)/\\\\\1/g;s/@\([^@]*\)@/\$\1/g;'`
|
||||
_opt=`echo $_opt | sed -e 's/@\([^@]*\)@/\$(\1)/g'`
|
||||
|
||||
# Avoid adding duplicates
|
||||
|
|
|
@ -129,7 +129,7 @@ export::
|
|||
-DMOZ_NATIVE_PNG=$(MOZ_NATIVE_PNG) \
|
||||
-DMOZ_NATIVE_JPEG=$(MOZ_NATIVE_JPEG) \
|
||||
$(srcdir)/system-headers | $(PERL) $(topsrcdir)/nsprpub/config/make-system-wrappers.pl system_wrappers
|
||||
$(INSTALL) system_wrappers $(DIST)/include
|
||||
$(INSTALL) system_wrappers $(DIST)
|
||||
|
||||
GARBAGE_DIRS += system_wrappers
|
||||
endif
|
||||
|
|
63
configure.in
63
configure.in
|
@ -1138,44 +1138,11 @@ HOST_OS_ARCH=`echo $host_os | sed -e 's|/|_|g'`
|
|||
# Master "Core Components" macros for getting the OS target #
|
||||
#######################################################################
|
||||
|
||||
#
|
||||
# Note: OS_TARGET should be specified on the command line for gmake.
|
||||
# When OS_TARGET=WIN95 is specified, then a Windows 95 target is built.
|
||||
# The difference between the Win95 target and the WinNT target is that
|
||||
# the WinNT target uses Windows NT specific features not available
|
||||
# in Windows 95. The Win95 target will run on Windows NT, but (supposedly)
|
||||
# at lesser performance (the Win95 target uses threads; the WinNT target
|
||||
# uses fibers).
|
||||
#
|
||||
# If OS_TARGET is not specified, it defaults to $(OS_ARCH), i.e., no
|
||||
# cross-compilation.
|
||||
#
|
||||
|
||||
#
|
||||
# The following hack allows one to build on a WIN95 machine (as if
|
||||
# s/he were cross-compiling on a WINNT host for a WIN95 target).
|
||||
# It also accomodates for MKS's uname.exe. If you never intend
|
||||
# to do development on a WIN95 machine, you don't need this hack.
|
||||
#
|
||||
case "$OS_ARCH" in
|
||||
WIN95)
|
||||
OS_ARCH=WINNT
|
||||
OS_TARGET=WIN95
|
||||
;;
|
||||
Windows_95)
|
||||
OS_ARCH=Windows_NT
|
||||
OS_TARGET=WIN95
|
||||
;;
|
||||
Windows_98)
|
||||
OS_ARCH=Windows_NT
|
||||
OS_TARGET=WIN95
|
||||
;;
|
||||
CYGWIN_9*|CYGWIN_ME*)
|
||||
OS_ARCH='CYGWIN_NT-4.0'
|
||||
OS_TARGET=WIN95
|
||||
;;
|
||||
esac
|
||||
|
||||
#
|
||||
# Define and override various archtecture-specific variables, including
|
||||
# HOST_OS_ARCH
|
||||
|
@ -1420,9 +1387,6 @@ esac
|
|||
if test -z "$OS_TARGET"; then
|
||||
OS_TARGET=$OS_ARCH
|
||||
fi
|
||||
if test "$OS_TARGET" = "WIN95"; then
|
||||
OS_RELEASE="4.0"
|
||||
fi
|
||||
OS_CONFIG="${OS_TARGET}${OS_RELEASE}"
|
||||
|
||||
dnl ========================================================
|
||||
|
@ -2123,7 +2087,7 @@ case "$target" in
|
|||
AC_DEFINE(HAVE_LOCALTIME_R)
|
||||
|
||||
TARGET_MD_ARCH=win32
|
||||
_PLATFORM_DEFAULT_TOOLKIT='windows'
|
||||
_PLATFORM_DEFAULT_TOOLKIT='cairo-windows'
|
||||
BIN_SUFFIX='.exe'
|
||||
USE_SHORT_LIBNAME=1
|
||||
MOZ_ENABLE_POSTSCRIPT=
|
||||
|
@ -2193,8 +2157,8 @@ case "$target" in
|
|||
MKSHLIB_UNFORCE_ALL=
|
||||
DSO_LDOPTS=-SUBSYSTEM:WINDOWS
|
||||
_USE_CPP_INCLUDE_FLAG=1
|
||||
_DEFINES_CFLAGS='-FI $(DEPTH)/mozilla-config.h -DMOZILLA_CLIENT'
|
||||
_DEFINES_CXXFLAGS='-FI $(DEPTH)/mozilla-config.h -DMOZILLA_CLIENT'
|
||||
_DEFINES_CFLAGS='-FI mozilla-config.h -DMOZILLA_CLIENT'
|
||||
_DEFINES_CXXFLAGS='-FI mozilla-config.h -DMOZILLA_CLIENT'
|
||||
CFLAGS="$CFLAGS -W3 -Gy -Fd\$(COMPILE_PDBFILE)"
|
||||
CXXFLAGS="$CXXFLAGS -W3 -Gy -Fd\$(COMPILE_PDBFILE)"
|
||||
LIBS="$LIBS kernel32.lib user32.lib gdi32.lib winmm.lib wsock32.lib advapi32.lib"
|
||||
|
@ -3068,7 +3032,7 @@ EOF
|
|||
])
|
||||
if test "$ac_cv_have_visibility_builtin_bug" = "no" -a \
|
||||
"$ac_cv_have_visibility_class_bug" = "no"; then
|
||||
VISIBILITY_FLAGS='-I$(DIST)/include/system_wrappers -include $(topsrcdir)/config/gcc_hidden.h'
|
||||
VISIBILITY_FLAGS='-I$(DIST)/system_wrappers -include $(topsrcdir)/config/gcc_hidden.h'
|
||||
WRAP_SYSTEM_INCLUDES=1
|
||||
else
|
||||
VISIBILITY_FLAGS='-fvisibility=hidden'
|
||||
|
@ -4828,8 +4792,7 @@ MOZ_ARG_HEADER(Toolkit Options)
|
|||
Mac OS X - cairo-cocoa
|
||||
Neutrino/QNX - photon
|
||||
OS/2 - cairo-os2
|
||||
Win32 - cairo-windows
|
||||
WinCE - windows
|
||||
Win32/WinCE - cairo-windows
|
||||
Gtk2 with DirectFB - cairo-gtk2-dfb
|
||||
* - cairo-gtk2
|
||||
* - cairo-qt],
|
||||
|
@ -7657,15 +7620,15 @@ if test "$MOZ_TREE_CAIRO"; then
|
|||
DDRAW_SURFACE_FEATURE=
|
||||
else
|
||||
WIN32_FONT_FEATURE=
|
||||
fi
|
||||
|
||||
AC_TRY_COMPILE([#include <ddraw.h>], [int foo = DDLOCK_WAITNOTBUSY;], HAS_DDRAW=1, HAS_DDRAW=)
|
||||
if test -z "$HAS_DDRAW"; then
|
||||
AC_MSG_WARN([DirectDraw ddraw.h header not found or it's missing DDLOCK_WAITNOTBUSY, disabling DirectDraw surface. If you have an older SDK (such as the CE5 SDK), try copying in ddraw.lib and ddraw.h from the WM6 SDK.])
|
||||
DDRAW_SURFACE_FEATURE=
|
||||
else
|
||||
DDRAW_SURFACE_FEATURE="#define CAIRO_HAS_DDRAW_SURFACE 1"
|
||||
fi
|
||||
fi
|
||||
AC_TRY_COMPILE([#include <ddraw.h>], [int foo = DDLOCK_WAITNOTBUSY;], HAS_DDRAW=1, HAS_DDRAW=)
|
||||
if test -z "$HAS_DDRAW"; then
|
||||
AC_MSG_WARN([DirectDraw ddraw.h header not found or it's missing DDLOCK_WAITNOTBUSY, disabling DirectDraw surface. If you have an older SDK (such as the CE5 SDK), try copying in ddraw.lib and ddraw.h from the WM6 SDK.])
|
||||
DDRAW_SURFACE_FEATURE=
|
||||
else
|
||||
DDRAW_SURFACE_FEATURE="#define CAIRO_HAS_DDRAW_SURFACE 1"
|
||||
fi
|
||||
PDF_SURFACE_FEATURE="#define CAIRO_HAS_PDF_SURFACE 1"
|
||||
fi
|
||||
if test "$MOZ_WIDGET_TOOLKIT" = "os2"; then
|
||||
|
|
|
@ -937,11 +937,9 @@ public:
|
|||
* @param aNode The node for which to get the eventlistener manager.
|
||||
* @param aCreateIfNotFound If PR_FALSE, returns a listener manager only if
|
||||
* one already exists.
|
||||
* @param aResult [out] Set to the eventlistener manager for aNode.
|
||||
*/
|
||||
static nsresult GetListenerManager(nsINode *aNode,
|
||||
PRBool aCreateIfNotFound,
|
||||
nsIEventListenerManager **aResult);
|
||||
static nsIEventListenerManager* GetListenerManager(nsINode* aNode,
|
||||
PRBool aCreateIfNotFound);
|
||||
|
||||
/**
|
||||
* Remove the eventlistener manager for aNode.
|
||||
|
@ -1259,6 +1257,15 @@ public:
|
|||
*/
|
||||
static already_AddRefed<nsIDragSession> GetDragSession();
|
||||
|
||||
/*
|
||||
* Initialize and set the dataTransfer field of an nsDragEvent.
|
||||
*/
|
||||
static nsresult SetDataTransferInEvent(nsDragEvent* aDragEvent);
|
||||
|
||||
// filters the drag and drop action to fit within the effects allowed and
|
||||
// returns it.
|
||||
static PRUint32 FilterDropEffect(PRUint32 aAction, PRUint32 aEffectAllowed);
|
||||
|
||||
/**
|
||||
* Return true if aURI is a local file URI (i.e. file://).
|
||||
*/
|
||||
|
|
|
@ -64,7 +64,7 @@ interface nsIURI;
|
|||
* sufficient, when combined with the imageBlockingStatus information.)
|
||||
*/
|
||||
|
||||
[scriptable, uuid(7744c6d3-5c60-4b7b-a526-4fe9d5ac7e97)]
|
||||
[scriptable, uuid(e036857e-3417-4812-a5f2-89668a616781)]
|
||||
interface nsIImageLoadingContent : imgIDecoderObserver
|
||||
{
|
||||
/**
|
||||
|
@ -167,4 +167,12 @@ interface nsIImageLoadingContent : imgIDecoderObserver
|
|||
* @throws NS_ERROR_NOT_AVAILABLE if there is no current URI to reload
|
||||
*/
|
||||
void forceReload();
|
||||
|
||||
/**
|
||||
* Enables/disables image state forcing. When |aForce| is PR_TRUE, we force
|
||||
* nsImageLoadingContent::ImageState() to return |aState|. Call again with |aForce|
|
||||
* as PR_FALSE to revert ImageState() to its original behaviour.
|
||||
*/
|
||||
void forceImageState(in boolean aForce, in long aState);
|
||||
|
||||
};
|
||||
|
|
|
@ -143,8 +143,11 @@ enum {
|
|||
NODE_HAS_EDGE_CHILD_SELECTOR |
|
||||
NODE_HAS_SLOW_SELECTOR_NOAPPEND,
|
||||
|
||||
NODE_MAY_HAVE_CONTENT_EDITABLE_ATTR
|
||||
= 0x00040000U,
|
||||
|
||||
// Four bits for the script-type ID
|
||||
NODE_SCRIPT_TYPE_OFFSET = 18,
|
||||
NODE_SCRIPT_TYPE_OFFSET = 19,
|
||||
|
||||
NODE_SCRIPT_TYPE_SIZE = 4,
|
||||
|
||||
|
|
|
@ -100,8 +100,6 @@ public:
|
|||
|
||||
// nsIContentSink
|
||||
NS_IMETHOD WillParse(void) { return NS_OK; }
|
||||
NS_IMETHOD WillBuildModel(void) { return NS_OK; }
|
||||
NS_IMETHOD DidBuildModel(void) { return NS_OK; }
|
||||
NS_IMETHOD WillInterrupt(void) { return NS_OK; }
|
||||
NS_IMETHOD WillResume(void) { return NS_OK; }
|
||||
NS_IMETHOD SetParser(nsIParser* aParser) { return NS_OK; }
|
||||
|
|
|
@ -162,6 +162,8 @@ static NS_DEFINE_CID(kXTFServiceCID, NS_XTFSERVICE_CID);
|
|||
#include "nsCPrefetchService.h"
|
||||
#include "nsIChromeRegistry.h"
|
||||
#include "nsIMIMEHeaderParam.h"
|
||||
#include "nsIDOMDragEvent.h"
|
||||
#include "nsDOMDataTransfer.h"
|
||||
#include "nsHtml5Module.h"
|
||||
|
||||
#ifdef IBMBIDI
|
||||
|
@ -3390,8 +3392,7 @@ nsContentUtils::HasMutationListeners(nsINode* aNode,
|
|||
if (aNode->IsInDoc()) {
|
||||
nsCOMPtr<nsPIDOMEventTarget> piTarget(do_QueryInterface(window));
|
||||
if (piTarget) {
|
||||
nsCOMPtr<nsIEventListenerManager> manager;
|
||||
piTarget->GetListenerManager(PR_FALSE, getter_AddRefs(manager));
|
||||
nsIEventListenerManager* manager = piTarget->GetListenerManager(PR_FALSE);
|
||||
if (manager) {
|
||||
PRBool hasListeners = PR_FALSE;
|
||||
manager->HasMutationListeners(&hasListeners);
|
||||
|
@ -3406,8 +3407,7 @@ nsContentUtils::HasMutationListeners(nsINode* aNode,
|
|||
// might not be in our chain. If we don't have a window, we might have a
|
||||
// mutation listener. Check quickly to see.
|
||||
while (aNode) {
|
||||
nsCOMPtr<nsIEventListenerManager> manager;
|
||||
aNode->GetListenerManager(PR_FALSE, getter_AddRefs(manager));
|
||||
nsIEventListenerManager* manager = aNode->GetListenerManager(PR_FALSE);
|
||||
if (manager) {
|
||||
PRBool hasListeners = PR_FALSE;
|
||||
manager->HasMutationListeners(&hasListeners);
|
||||
|
@ -3451,22 +3451,19 @@ nsContentUtils::TraverseListenerManager(nsINode *aNode,
|
|||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsIEventListenerManager*
|
||||
nsContentUtils::GetListenerManager(nsINode *aNode,
|
||||
PRBool aCreateIfNotFound,
|
||||
nsIEventListenerManager **aResult)
|
||||
PRBool aCreateIfNotFound)
|
||||
{
|
||||
*aResult = nsnull;
|
||||
|
||||
if (!aCreateIfNotFound && !aNode->HasFlag(NODE_HAS_LISTENERMANAGER)) {
|
||||
return NS_OK;
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
if (!sEventListenerManagersHash.ops) {
|
||||
// We're already shut down, don't bother creating an event listener
|
||||
// manager.
|
||||
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
if (!aCreateIfNotFound) {
|
||||
|
@ -3475,10 +3472,9 @@ nsContentUtils::GetListenerManager(nsINode *aNode,
|
|||
(PL_DHashTableOperate(&sEventListenerManagersHash, aNode,
|
||||
PL_DHASH_LOOKUP));
|
||||
if (PL_DHASH_ENTRY_IS_BUSY(entry)) {
|
||||
*aResult = entry->mListenerManager;
|
||||
NS_ADDREF(*aResult);
|
||||
return entry->mListenerManager;
|
||||
}
|
||||
return NS_OK;
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
EventListenerManagerMapEntry *entry =
|
||||
|
@ -3487,7 +3483,7 @@ nsContentUtils::GetListenerManager(nsINode *aNode,
|
|||
PL_DHASH_ADD));
|
||||
|
||||
if (!entry) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
if (!entry->mListenerManager) {
|
||||
|
@ -3497,7 +3493,7 @@ nsContentUtils::GetListenerManager(nsINode *aNode,
|
|||
if (NS_FAILED(rv)) {
|
||||
PL_DHashTableRawRemove(&sEventListenerManagersHash, entry);
|
||||
|
||||
return rv;
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
entry->mListenerManager->SetListenerTarget(aNode);
|
||||
|
@ -3505,9 +3501,7 @@ nsContentUtils::GetListenerManager(nsINode *aNode,
|
|||
aNode->SetFlags(NODE_HAS_LISTENERMANAGER);
|
||||
}
|
||||
|
||||
NS_ADDREF(*aResult = entry->mListenerManager);
|
||||
|
||||
return NS_OK;
|
||||
return entry->mListenerManager;
|
||||
}
|
||||
|
||||
/* static */
|
||||
|
@ -4584,6 +4578,115 @@ nsContentUtils::GetDragSession()
|
|||
return dragSession;
|
||||
}
|
||||
|
||||
/* static */
|
||||
nsresult
|
||||
nsContentUtils::SetDataTransferInEvent(nsDragEvent* aDragEvent)
|
||||
{
|
||||
if (aDragEvent->dataTransfer || !NS_IS_TRUSTED_EVENT(aDragEvent))
|
||||
return NS_OK;
|
||||
|
||||
// For draggesture and dragstart events, the data transfer object is
|
||||
// created before the event fires, so it should already be set. For other
|
||||
// drag events, get the object from the drag session.
|
||||
NS_ASSERTION(aDragEvent->message != NS_DRAGDROP_GESTURE &&
|
||||
aDragEvent->message != NS_DRAGDROP_START,
|
||||
"draggesture event created without a dataTransfer");
|
||||
|
||||
nsCOMPtr<nsIDragSession> dragSession = GetDragSession();
|
||||
NS_ENSURE_TRUE(dragSession, NS_OK); // no drag in progress
|
||||
|
||||
nsCOMPtr<nsIDOMDataTransfer> initialDataTransfer;
|
||||
dragSession->GetDataTransfer(getter_AddRefs(initialDataTransfer));
|
||||
if (!initialDataTransfer) {
|
||||
// A dataTransfer won't exist when a drag was started by some other
|
||||
// means, for instance calling the drag service directly, or a drag
|
||||
// from another application. In either case, a new dataTransfer should
|
||||
// be created that reflects the data. Pass true to the constructor for
|
||||
// the aIsExternal argument, so that only system access is allowed.
|
||||
PRUint32 action = 0;
|
||||
dragSession->GetDragAction(&action);
|
||||
initialDataTransfer =
|
||||
new nsDOMDataTransfer(aDragEvent->message, action);
|
||||
NS_ENSURE_TRUE(initialDataTransfer, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
// now set it in the drag session so we don't need to create it again
|
||||
dragSession->SetDataTransfer(initialDataTransfer);
|
||||
}
|
||||
|
||||
// each event should use a clone of the original dataTransfer.
|
||||
nsCOMPtr<nsIDOMNSDataTransfer> initialDataTransferNS =
|
||||
do_QueryInterface(initialDataTransfer);
|
||||
NS_ENSURE_TRUE(initialDataTransferNS, NS_ERROR_FAILURE);
|
||||
initialDataTransferNS->Clone(aDragEvent->message, aDragEvent->userCancelled,
|
||||
getter_AddRefs(aDragEvent->dataTransfer));
|
||||
NS_ENSURE_TRUE(aDragEvent->dataTransfer, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
// for the dragenter and dragover events, initialize the drop effect
|
||||
// from the drop action, which platform specific widget code sets before
|
||||
// the event is fired based on the keyboard state.
|
||||
if (aDragEvent->message == NS_DRAGDROP_ENTER ||
|
||||
aDragEvent->message == NS_DRAGDROP_OVER) {
|
||||
nsCOMPtr<nsIDOMNSDataTransfer> newDataTransfer =
|
||||
do_QueryInterface(aDragEvent->dataTransfer);
|
||||
NS_ENSURE_TRUE(newDataTransfer, NS_ERROR_FAILURE);
|
||||
|
||||
PRUint32 action, effectAllowed;
|
||||
dragSession->GetDragAction(&action);
|
||||
newDataTransfer->GetEffectAllowedInt(&effectAllowed);
|
||||
newDataTransfer->SetDropEffectInt(FilterDropEffect(action, effectAllowed));
|
||||
}
|
||||
else if (aDragEvent->message == NS_DRAGDROP_DROP ||
|
||||
aDragEvent->message == NS_DRAGDROP_DRAGDROP ||
|
||||
aDragEvent->message == NS_DRAGDROP_END) {
|
||||
// For the drop and dragend events, set the drop effect based on the
|
||||
// last value that the dropEffect had. This will have been set in
|
||||
// nsEventStateManager::PostHandleEvent for the last dragenter or
|
||||
// dragover event.
|
||||
nsCOMPtr<nsIDOMNSDataTransfer> newDataTransfer =
|
||||
do_QueryInterface(aDragEvent->dataTransfer);
|
||||
NS_ENSURE_TRUE(newDataTransfer, NS_ERROR_FAILURE);
|
||||
|
||||
PRUint32 dropEffect;
|
||||
initialDataTransferNS->GetDropEffectInt(&dropEffect);
|
||||
newDataTransfer->SetDropEffectInt(dropEffect);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* static */
|
||||
PRUint32
|
||||
nsContentUtils::FilterDropEffect(PRUint32 aAction, PRUint32 aEffectAllowed)
|
||||
{
|
||||
// It is possible for the drag action to include more than one action, but
|
||||
// the widget code which sets the action from the keyboard state should only
|
||||
// be including one. If multiple actions were set, we just consider them in
|
||||
// the following order:
|
||||
// copy, link, move
|
||||
if (aAction & nsIDragService::DRAGDROP_ACTION_COPY)
|
||||
aAction = nsIDragService::DRAGDROP_ACTION_COPY;
|
||||
else if (aAction & nsIDragService::DRAGDROP_ACTION_LINK)
|
||||
aAction = nsIDragService::DRAGDROP_ACTION_LINK;
|
||||
else if (aAction & nsIDragService::DRAGDROP_ACTION_MOVE)
|
||||
aAction = nsIDragService::DRAGDROP_ACTION_MOVE;
|
||||
|
||||
// Filter the action based on the effectAllowed. If the effectAllowed
|
||||
// doesn't include the action, then that action cannot be done, so adjust
|
||||
// the action to something that is allowed. For a copy, adjust to move or
|
||||
// link. For a move, adjust to copy or link. For a link, adjust to move or
|
||||
// link. Otherwise, use none.
|
||||
if (aAction & aEffectAllowed ||
|
||||
aEffectAllowed == nsIDragService::DRAGDROP_ACTION_UNINITIALIZED)
|
||||
return aAction;
|
||||
if (aEffectAllowed & nsIDragService::DRAGDROP_ACTION_MOVE)
|
||||
return nsIDragService::DRAGDROP_ACTION_MOVE;
|
||||
if (aEffectAllowed & nsIDragService::DRAGDROP_ACTION_COPY)
|
||||
return nsIDragService::DRAGDROP_ACTION_COPY;
|
||||
if (aEffectAllowed & nsIDragService::DRAGDROP_ACTION_LINK)
|
||||
return nsIDragService::DRAGDROP_ACTION_LINK;
|
||||
return nsIDragService::DRAGDROP_ACTION_NONE;
|
||||
}
|
||||
|
||||
/* static */
|
||||
PRBool
|
||||
nsContentUtils::URIIsLocalFile(nsIURI *aURI)
|
||||
|
|
|
@ -758,46 +758,37 @@ nsDOMAttribute::DispatchDOMEvent(nsEvent* aEvent, nsIDOMEvent* aDOMEvent,
|
|||
aPresContext, aEventStatus);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDOMAttribute::GetListenerManager(PRBool aCreateIfNotFound,
|
||||
nsIEventListenerManager** aResult)
|
||||
nsIEventListenerManager*
|
||||
nsDOMAttribute::GetListenerManager(PRBool aCreateIfNotFound)
|
||||
{
|
||||
return nsContentUtils::GetListenerManager(this, aCreateIfNotFound, aResult);
|
||||
return nsContentUtils::GetListenerManager(this, aCreateIfNotFound);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDOMAttribute::AddEventListenerByIID(nsIDOMEventListener *aListener,
|
||||
const nsIID& aIID)
|
||||
{
|
||||
nsCOMPtr<nsIEventListenerManager> elm;
|
||||
nsresult rv = GetListenerManager(PR_TRUE, getter_AddRefs(elm));
|
||||
if (elm) {
|
||||
return elm->AddEventListenerByIID(aListener, aIID, NS_EVENT_FLAG_BUBBLE);
|
||||
}
|
||||
return rv;
|
||||
nsIEventListenerManager* elm = GetListenerManager(PR_TRUE);
|
||||
NS_ENSURE_STATE(elm);
|
||||
return elm->AddEventListenerByIID(aListener, aIID, NS_EVENT_FLAG_BUBBLE);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDOMAttribute::RemoveEventListenerByIID(nsIDOMEventListener *aListener,
|
||||
const nsIID& aIID)
|
||||
{
|
||||
nsCOMPtr<nsIEventListenerManager> elm;
|
||||
GetListenerManager(PR_FALSE, getter_AddRefs(elm));
|
||||
if (elm) {
|
||||
return elm->RemoveEventListenerByIID(aListener, aIID, NS_EVENT_FLAG_BUBBLE);
|
||||
}
|
||||
return NS_OK;
|
||||
nsIEventListenerManager* elm = GetListenerManager(PR_FALSE);
|
||||
return elm ?
|
||||
elm->RemoveEventListenerByIID(aListener, aIID, NS_EVENT_FLAG_BUBBLE) :
|
||||
NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDOMAttribute::GetSystemEventGroup(nsIDOMEventGroup** aGroup)
|
||||
{
|
||||
nsCOMPtr<nsIEventListenerManager> elm;
|
||||
nsresult rv = GetListenerManager(PR_TRUE, getter_AddRefs(elm));
|
||||
if (elm) {
|
||||
return elm->GetSystemEventGroupLM(aGroup);
|
||||
}
|
||||
return rv;
|
||||
nsIEventListenerManager* elm = GetListenerManager(PR_TRUE);
|
||||
NS_ENSURE_STATE(elm);
|
||||
return elm->GetSystemEventGroupLM(aGroup);
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
|
|
@ -104,8 +104,7 @@ public:
|
|||
virtual nsresult DispatchDOMEvent(nsEvent* aEvent, nsIDOMEvent* aDOMEvent,
|
||||
nsPresContext* aPresContext,
|
||||
nsEventStatus* aEventStatus);
|
||||
virtual nsresult GetListenerManager(PRBool aCreateIfNotFound,
|
||||
nsIEventListenerManager** aResult);
|
||||
virtual nsIEventListenerManager* GetListenerManager(PRBool aCreateIfNotFound);
|
||||
virtual nsresult AddEventListenerByIID(nsIDOMEventListener *aListener,
|
||||
const nsIID& aIID);
|
||||
virtual nsresult RemoveEventListenerByIID(nsIDOMEventListener *aListener,
|
||||
|
|
|
@ -168,7 +168,7 @@ static NS_DEFINE_CID(kDOMEventGroupCID, NS_DOMEVENTGROUP_CID);
|
|||
#include "nsIXULDocument.h"
|
||||
#include "nsIPrompt.h"
|
||||
#include "nsIPropertyBag2.h"
|
||||
|
||||
#include "nsIDOMPageTransitionEvent.h"
|
||||
#include "nsFrameLoader.h"
|
||||
|
||||
#include "mozAutoDocUpdate.h"
|
||||
|
@ -572,7 +572,7 @@ NS_INTERFACE_TABLE_HEAD(nsDOMStyleSheetList)
|
|||
nsIDocumentObserver,
|
||||
nsIMutationObserver)
|
||||
NS_INTERFACE_TABLE_TO_MAP_SEGUE
|
||||
NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(DocumentStyleSheetList)
|
||||
NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(StyleSheetList)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
|
||||
|
@ -6018,42 +6018,27 @@ nsDocument::GetOwnerDocument(nsIDOMDocument** aOwnerDocument)
|
|||
return nsINode::GetOwnerDocument(aOwnerDocument);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDocument::GetListenerManager(PRBool aCreateIfNotFound,
|
||||
nsIEventListenerManager** aInstancePtrResult)
|
||||
nsIEventListenerManager*
|
||||
nsDocument::GetListenerManager(PRBool aCreateIfNotFound)
|
||||
{
|
||||
if (mListenerManager) {
|
||||
*aInstancePtrResult = mListenerManager;
|
||||
NS_ADDREF(*aInstancePtrResult);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
if (!aCreateIfNotFound) {
|
||||
*aInstancePtrResult = nsnull;
|
||||
return NS_OK;
|
||||
if (mListenerManager || !aCreateIfNotFound) {
|
||||
return mListenerManager;
|
||||
}
|
||||
|
||||
nsresult rv = NS_NewEventListenerManager(getter_AddRefs(mListenerManager));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
NS_ENSURE_SUCCESS(rv, nsnull);
|
||||
|
||||
mListenerManager->SetListenerTarget(static_cast<nsIDocument *>(this));
|
||||
|
||||
*aInstancePtrResult = mListenerManager;
|
||||
NS_ADDREF(*aInstancePtrResult);
|
||||
|
||||
return NS_OK;
|
||||
return mListenerManager;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDocument::GetSystemEventGroup(nsIDOMEventGroup **aGroup)
|
||||
{
|
||||
nsCOMPtr<nsIEventListenerManager> manager;
|
||||
if (NS_SUCCEEDED(GetListenerManager(PR_TRUE, getter_AddRefs(manager))) &&
|
||||
manager) {
|
||||
return manager->GetSystemEventGroupLM(aGroup);
|
||||
}
|
||||
|
||||
return NS_ERROR_FAILURE;
|
||||
nsIEventListenerManager* manager = GetListenerManager(PR_TRUE);
|
||||
NS_ENSURE_STATE(manager);
|
||||
return manager->GetSystemEventGroupLM(aGroup);
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -6093,28 +6078,19 @@ nsresult
|
|||
nsDocument::AddEventListenerByIID(nsIDOMEventListener *aListener,
|
||||
const nsIID& aIID)
|
||||
{
|
||||
nsCOMPtr<nsIEventListenerManager> manager;
|
||||
|
||||
GetListenerManager(PR_TRUE, getter_AddRefs(manager));
|
||||
if (manager) {
|
||||
manager->AddEventListenerByIID(aListener, aIID, NS_EVENT_FLAG_BUBBLE);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return NS_ERROR_FAILURE;
|
||||
nsIEventListenerManager* manager = GetListenerManager(PR_TRUE);
|
||||
NS_ENSURE_STATE(manager);
|
||||
return manager->AddEventListenerByIID(aListener, aIID, NS_EVENT_FLAG_BUBBLE);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDocument::RemoveEventListenerByIID(nsIDOMEventListener *aListener,
|
||||
const nsIID& aIID)
|
||||
{
|
||||
if (!mListenerManager) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
mListenerManager->RemoveEventListenerByIID(aListener, aIID,
|
||||
NS_EVENT_FLAG_BUBBLE);
|
||||
return NS_OK;
|
||||
return mListenerManager ?
|
||||
mListenerManager->RemoveEventListenerByIID(aListener, aIID,
|
||||
NS_EVENT_FLAG_BUBBLE) :
|
||||
NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -6159,17 +6135,10 @@ nsDocument::AddGroupedEventListener(const nsAString& aType,
|
|||
PRBool aUseCapture,
|
||||
nsIDOMEventGroup *aEvtGrp)
|
||||
{
|
||||
nsCOMPtr<nsIEventListenerManager> manager;
|
||||
|
||||
nsresult rv = GetListenerManager(PR_TRUE, getter_AddRefs(manager));
|
||||
if (NS_SUCCEEDED(rv) && manager) {
|
||||
PRInt32 flags = aUseCapture ? NS_EVENT_FLAG_CAPTURE : NS_EVENT_FLAG_BUBBLE;
|
||||
|
||||
manager->AddEventListenerByType(aListener, aType, flags, aEvtGrp);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return rv;
|
||||
nsIEventListenerManager* manager = GetListenerManager(PR_TRUE);
|
||||
NS_ENSURE_STATE(manager);
|
||||
PRInt32 flags = aUseCapture ? NS_EVENT_FLAG_CAPTURE : NS_EVENT_FLAG_BUBBLE;
|
||||
return manager->AddEventListenerByType(aListener, aType, flags, aEvtGrp);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -6178,14 +6147,11 @@ nsDocument::RemoveGroupedEventListener(const nsAString& aType,
|
|||
PRBool aUseCapture,
|
||||
nsIDOMEventGroup *aEvtGrp)
|
||||
{
|
||||
if (!mListenerManager) {
|
||||
return NS_ERROR_FAILURE;
|
||||
if (mListenerManager) {
|
||||
PRInt32 flags = aUseCapture ? NS_EVENT_FLAG_CAPTURE : NS_EVENT_FLAG_BUBBLE;
|
||||
mListenerManager->RemoveEventListenerByType(aListener, aType, flags,
|
||||
aEvtGrp);
|
||||
}
|
||||
|
||||
PRInt32 flags = aUseCapture ? NS_EVENT_FLAG_CAPTURE : NS_EVENT_FLAG_BUBBLE;
|
||||
|
||||
mListenerManager->RemoveEventListenerByType(aListener, aType, flags,
|
||||
aEvtGrp);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -6206,9 +6172,8 @@ nsDocument::AddEventListener(const nsAString& aType,
|
|||
nsIDOMEventListener *aListener,
|
||||
PRBool aUseCapture, PRBool aWantsUntrusted)
|
||||
{
|
||||
nsCOMPtr<nsIEventListenerManager> manager;
|
||||
nsresult rv = GetListenerManager(PR_TRUE, getter_AddRefs(manager));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
nsIEventListenerManager* manager = GetListenerManager(PR_TRUE);
|
||||
NS_ENSURE_STATE(manager);
|
||||
|
||||
PRInt32 flags = aUseCapture ? NS_EVENT_FLAG_CAPTURE : NS_EVENT_FLAG_BUBBLE;
|
||||
|
||||
|
@ -6853,8 +6818,8 @@ nsDocument::CanSavePresentation(nsIRequest *aNewRequest)
|
|||
// Check our event listener manager for unload/beforeunload listeners.
|
||||
nsCOMPtr<nsPIDOMEventTarget> piTarget = do_QueryInterface(mScriptGlobalObject);
|
||||
if (piTarget) {
|
||||
nsCOMPtr<nsIEventListenerManager> manager;
|
||||
piTarget->GetListenerManager(PR_FALSE, getter_AddRefs(manager));
|
||||
nsIEventListenerManager* manager =
|
||||
piTarget->GetListenerManager(PR_FALSE);
|
||||
if (manager && manager->HasUnloadListeners()) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
@ -7092,14 +7057,24 @@ nsDocument::CheckAncestryAndGetFrame(nsIDocument* aDocument) const
|
|||
}
|
||||
|
||||
void
|
||||
nsDocument::DispatchEventToWindow(nsEvent *aEvent)
|
||||
nsDocument::DispatchPageTransition(nsPIDOMEventTarget* aDispatchTarget,
|
||||
const nsAString& aType,
|
||||
PRBool aPersisted)
|
||||
{
|
||||
nsPIDOMWindow *window = GetWindow();
|
||||
if (!window)
|
||||
return;
|
||||
|
||||
aEvent->target = static_cast<nsIDocument*>(this);
|
||||
nsEventDispatcher::Dispatch(window, nsnull, aEvent);
|
||||
if (aDispatchTarget) {
|
||||
nsCOMPtr<nsIDOMEvent> event;
|
||||
CreateEvent(NS_LITERAL_STRING("pagetransition"), getter_AddRefs(event));
|
||||
nsCOMPtr<nsIDOMPageTransitionEvent> ptEvent = do_QueryInterface(event);
|
||||
nsCOMPtr<nsIPrivateDOMEvent> pEvent = do_QueryInterface(ptEvent);
|
||||
if (pEvent && NS_SUCCEEDED(ptEvent->InitPageTransitionEvent(aType, PR_TRUE,
|
||||
PR_TRUE,
|
||||
aPersisted))) {
|
||||
pEvent->SetTrusted(PR_TRUE);
|
||||
pEvent->SetTarget(this);
|
||||
nsEventDispatcher::DispatchDOMEvent(aDispatchTarget, nsnull, event,
|
||||
nsnull, nsnull);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -7138,14 +7113,10 @@ nsDocument::OnPageShow(PRBool aPersisted, nsIDOMEventTarget* aDispatchStartTarge
|
|||
mAnimationController->OnPageShow();
|
||||
}
|
||||
#endif
|
||||
|
||||
nsPageTransitionEvent event(PR_TRUE, NS_PAGE_SHOW, aPersisted);
|
||||
if (aDispatchStartTarget) {
|
||||
event.target = static_cast<nsIDocument*>(this);
|
||||
nsEventDispatcher::Dispatch(aDispatchStartTarget, nsnull, &event);
|
||||
} else {
|
||||
DispatchEventToWindow(&event);
|
||||
}
|
||||
nsCOMPtr<nsPIDOMEventTarget> target =
|
||||
aDispatchStartTarget ? do_QueryInterface(aDispatchStartTarget) :
|
||||
do_QueryInterface(GetWindow());
|
||||
DispatchPageTransition(target, NS_LITERAL_STRING("pageshow"), aPersisted);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -7184,13 +7155,10 @@ nsDocument::OnPageHide(PRBool aPersisted, nsIDOMEventTarget* aDispatchStartTarge
|
|||
#endif
|
||||
|
||||
// Now send out a PageHide event.
|
||||
nsPageTransitionEvent event(PR_TRUE, NS_PAGE_HIDE, aPersisted);
|
||||
if (aDispatchStartTarget) {
|
||||
event.target = static_cast<nsIDocument*>(this);
|
||||
nsEventDispatcher::Dispatch(aDispatchStartTarget, nsnull, &event);
|
||||
} else {
|
||||
DispatchEventToWindow(&event);
|
||||
}
|
||||
nsCOMPtr<nsPIDOMEventTarget> target =
|
||||
aDispatchStartTarget ? do_QueryInterface(aDispatchStartTarget) :
|
||||
do_QueryInterface(GetWindow());
|
||||
DispatchPageTransition(target, NS_LITERAL_STRING("pagehide"), aPersisted);
|
||||
|
||||
mVisible = PR_FALSE;
|
||||
}
|
||||
|
|
|
@ -816,8 +816,7 @@ public:
|
|||
virtual nsresult DispatchDOMEvent(nsEvent* aEvent, nsIDOMEvent* aDOMEvent,
|
||||
nsPresContext* aPresContext,
|
||||
nsEventStatus* aEventStatus);
|
||||
virtual nsresult GetListenerManager(PRBool aCreateIfNotFound,
|
||||
nsIEventListenerManager** aResult);
|
||||
virtual nsIEventListenerManager* GetListenerManager(PRBool aCreateIfNotFound);
|
||||
virtual nsresult AddEventListenerByIID(nsIDOMEventListener *aListener,
|
||||
const nsIID& aIID);
|
||||
virtual nsresult RemoveEventListenerByIID(nsIDOMEventListener *aListener,
|
||||
|
@ -1079,8 +1078,9 @@ protected:
|
|||
return kNameSpaceID_None;
|
||||
}
|
||||
|
||||
// Dispatch an event to the ScriptGlobalObject for this document
|
||||
void DispatchEventToWindow(nsEvent *aEvent);
|
||||
void DispatchPageTransition(nsPIDOMEventTarget* aDispatchTarget,
|
||||
const nsAString& aType,
|
||||
PRBool aPersisted);
|
||||
|
||||
// nsContentList match functions for GetElementsByClassName
|
||||
static PRBool MatchClassNames(nsIContent* aContent, PRInt32 aNamespaceID,
|
||||
|
|
|
@ -686,46 +686,37 @@ nsGenericDOMDataNode::DispatchDOMEvent(nsEvent* aEvent,
|
|||
aPresContext, aEventStatus);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsGenericDOMDataNode::GetListenerManager(PRBool aCreateIfNotFound,
|
||||
nsIEventListenerManager** aResult)
|
||||
nsIEventListenerManager*
|
||||
nsGenericDOMDataNode::GetListenerManager(PRBool aCreateIfNotFound)
|
||||
{
|
||||
return nsContentUtils::GetListenerManager(this, aCreateIfNotFound, aResult);
|
||||
return nsContentUtils::GetListenerManager(this, aCreateIfNotFound);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsGenericDOMDataNode::AddEventListenerByIID(nsIDOMEventListener *aListener,
|
||||
const nsIID& aIID)
|
||||
{
|
||||
nsCOMPtr<nsIEventListenerManager> elm;
|
||||
nsresult rv = GetListenerManager(PR_TRUE, getter_AddRefs(elm));
|
||||
if (elm) {
|
||||
return elm->AddEventListenerByIID(aListener, aIID, NS_EVENT_FLAG_BUBBLE);
|
||||
}
|
||||
return rv;
|
||||
nsIEventListenerManager* elm = GetListenerManager(PR_TRUE);
|
||||
NS_ENSURE_STATE(elm);
|
||||
return elm->AddEventListenerByIID(aListener, aIID, NS_EVENT_FLAG_BUBBLE);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsGenericDOMDataNode::RemoveEventListenerByIID(nsIDOMEventListener *aListener,
|
||||
const nsIID& aIID)
|
||||
{
|
||||
nsCOMPtr<nsIEventListenerManager> elm;
|
||||
GetListenerManager(PR_FALSE, getter_AddRefs(elm));
|
||||
if (elm) {
|
||||
return elm->RemoveEventListenerByIID(aListener, aIID, NS_EVENT_FLAG_BUBBLE);
|
||||
}
|
||||
return NS_OK;
|
||||
nsIEventListenerManager* elm = GetListenerManager(PR_FALSE);
|
||||
return elm ?
|
||||
elm->RemoveEventListenerByIID(aListener, aIID, NS_EVENT_FLAG_BUBBLE) :
|
||||
NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsGenericDOMDataNode::GetSystemEventGroup(nsIDOMEventGroup** aGroup)
|
||||
{
|
||||
nsCOMPtr<nsIEventListenerManager> elm;
|
||||
nsresult rv = GetListenerManager(PR_TRUE, getter_AddRefs(elm));
|
||||
if (elm) {
|
||||
return elm->GetSystemEventGroupLM(aGroup);
|
||||
}
|
||||
return rv;
|
||||
nsIEventListenerManager* elm = GetListenerManager(PR_TRUE);
|
||||
NS_ENSURE_STATE(elm);
|
||||
return elm->GetSystemEventGroupLM(aGroup);
|
||||
}
|
||||
|
||||
PRUint32
|
||||
|
|
|
@ -172,8 +172,7 @@ public:
|
|||
virtual nsresult DispatchDOMEvent(nsEvent* aEvent, nsIDOMEvent* aDOMEvent,
|
||||
nsPresContext* aPresContext,
|
||||
nsEventStatus* aEventStatus);
|
||||
virtual nsresult GetListenerManager(PRBool aCreateIfNotFound,
|
||||
nsIEventListenerManager** aResult);
|
||||
virtual nsIEventListenerManager* GetListenerManager(PRBool aCreateIfNotFound);
|
||||
virtual nsresult AddEventListenerByIID(nsIDOMEventListener *aListener,
|
||||
const nsIID& aIID);
|
||||
virtual nsresult RemoveEventListenerByIID(nsIDOMEventListener *aListener,
|
||||
|
|
|
@ -251,46 +251,37 @@ nsINode::UnsetProperty(PRUint16 aCategory, nsIAtom *aPropertyName,
|
|||
aStatus);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsGenericElement::GetListenerManager(PRBool aCreateIfNotFound,
|
||||
nsIEventListenerManager** aResult)
|
||||
nsIEventListenerManager*
|
||||
nsGenericElement::GetListenerManager(PRBool aCreateIfNotFound)
|
||||
{
|
||||
return nsContentUtils::GetListenerManager(this, aCreateIfNotFound, aResult);
|
||||
return nsContentUtils::GetListenerManager(this, aCreateIfNotFound);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsGenericElement::AddEventListenerByIID(nsIDOMEventListener *aListener,
|
||||
const nsIID& aIID)
|
||||
{
|
||||
nsCOMPtr<nsIEventListenerManager> elm;
|
||||
nsresult rv = GetListenerManager(PR_TRUE, getter_AddRefs(elm));
|
||||
if (elm) {
|
||||
return elm->AddEventListenerByIID(aListener, aIID, NS_EVENT_FLAG_BUBBLE);
|
||||
}
|
||||
return rv;
|
||||
nsIEventListenerManager* elm = GetListenerManager(PR_TRUE);
|
||||
NS_ENSURE_STATE(elm);
|
||||
return elm->AddEventListenerByIID(aListener, aIID, NS_EVENT_FLAG_BUBBLE);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsGenericElement::RemoveEventListenerByIID(nsIDOMEventListener *aListener,
|
||||
const nsIID& aIID)
|
||||
{
|
||||
nsCOMPtr<nsIEventListenerManager> elm;
|
||||
GetListenerManager(PR_FALSE, getter_AddRefs(elm));
|
||||
if (elm) {
|
||||
return elm->RemoveEventListenerByIID(aListener, aIID, NS_EVENT_FLAG_BUBBLE);
|
||||
}
|
||||
return NS_OK;
|
||||
nsIEventListenerManager* elm = GetListenerManager(PR_FALSE);
|
||||
return elm ?
|
||||
elm->RemoveEventListenerByIID(aListener, aIID, NS_EVENT_FLAG_BUBBLE) :
|
||||
NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsGenericElement::GetSystemEventGroup(nsIDOMEventGroup** aGroup)
|
||||
{
|
||||
nsCOMPtr<nsIEventListenerManager> elm;
|
||||
nsresult rv = GetListenerManager(PR_TRUE, getter_AddRefs(elm));
|
||||
if (elm) {
|
||||
return elm->GetSystemEventGroupLM(aGroup);
|
||||
}
|
||||
return rv;
|
||||
nsIEventListenerManager* elm = GetListenerManager(PR_TRUE);
|
||||
NS_ENSURE_STATE(elm);
|
||||
return elm->GetSystemEventGroupLM(aGroup);
|
||||
}
|
||||
|
||||
nsINode::nsSlots*
|
||||
|
@ -1618,11 +1609,9 @@ nsDOMEventRTTearoff::LastRelease()
|
|||
nsresult
|
||||
nsDOMEventRTTearoff::GetDOM3EventTarget(nsIDOM3EventTarget **aTarget)
|
||||
{
|
||||
nsCOMPtr<nsIEventListenerManager> listener_manager;
|
||||
nsresult rv =
|
||||
mNode->GetListenerManager(PR_TRUE, getter_AddRefs(listener_manager));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsIEventListenerManager* listener_manager =
|
||||
mNode->GetListenerManager(PR_TRUE);
|
||||
NS_ENSURE_STATE(listener_manager);
|
||||
return CallQueryInterface(listener_manager, aTarget);
|
||||
}
|
||||
|
||||
|
@ -1662,11 +1651,8 @@ nsDOMEventRTTearoff::RemoveEventListener(const nsAString& aType,
|
|||
NS_IMETHODIMP
|
||||
nsDOMEventRTTearoff::DispatchEvent(nsIDOMEvent *aEvt, PRBool* _retval)
|
||||
{
|
||||
nsCOMPtr<nsIEventListenerManager> listener_manager;
|
||||
nsresult rv =
|
||||
mNode->GetListenerManager(PR_TRUE, getter_AddRefs(listener_manager));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
nsCOMPtr<nsIDOMEventTarget> target = do_QueryInterface(listener_manager);
|
||||
nsCOMPtr<nsIDOMEventTarget> target =
|
||||
do_QueryInterface(mNode->GetListenerManager(PR_TRUE));
|
||||
NS_ENSURE_STATE(target);
|
||||
return target->DispatchEvent(aEvt, _retval);
|
||||
}
|
||||
|
@ -1719,10 +1705,9 @@ nsDOMEventRTTearoff::AddEventListener(const nsAString& aType,
|
|||
PRBool aUseCapture,
|
||||
PRBool aWantsUntrusted)
|
||||
{
|
||||
nsCOMPtr<nsIEventListenerManager> listener_manager;
|
||||
nsresult rv =
|
||||
mNode->GetListenerManager(PR_TRUE, getter_AddRefs(listener_manager));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
nsIEventListenerManager* listener_manager =
|
||||
mNode->GetListenerManager(PR_TRUE);
|
||||
NS_ENSURE_STATE(listener_manager);
|
||||
|
||||
PRInt32 flags = aUseCapture ? NS_EVENT_FLAG_CAPTURE : NS_EVENT_FLAG_BUBBLE;
|
||||
|
||||
|
@ -4138,21 +4123,16 @@ nsGenericElement::AddScriptEventListener(nsIAtom* aEventName,
|
|||
PRBool defer = PR_TRUE;
|
||||
nsCOMPtr<nsIEventListenerManager> manager;
|
||||
|
||||
nsresult rv = GetEventListenerManagerForAttr(getter_AddRefs(manager),
|
||||
getter_AddRefs(target),
|
||||
&defer);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
GetEventListenerManagerForAttr(getter_AddRefs(manager),
|
||||
getter_AddRefs(target),
|
||||
&defer);
|
||||
NS_ENSURE_STATE(manager);
|
||||
|
||||
if (manager) {
|
||||
defer = defer && aDefer; // only defer if everyone agrees...
|
||||
|
||||
PRUint32 lang = GetScriptTypeID();
|
||||
rv =
|
||||
manager->AddScriptEventListener(target, aEventName, aValue, lang, defer,
|
||||
!nsContentUtils::IsChromeDoc(ownerDoc));
|
||||
}
|
||||
|
||||
return rv;
|
||||
defer = defer && aDefer; // only defer if everyone agrees...
|
||||
PRUint32 lang = GetScriptTypeID();
|
||||
return
|
||||
manager->AddScriptEventListener(target, aEventName, aValue, lang, defer,
|
||||
!nsContentUtils::IsChromeDoc(ownerDoc));
|
||||
}
|
||||
|
||||
|
||||
|
@ -4392,12 +4372,12 @@ nsGenericElement::GetEventListenerManagerForAttr(nsIEventListenerManager** aMana
|
|||
nsISupports** aTarget,
|
||||
PRBool* aDefer)
|
||||
{
|
||||
nsresult rv = GetListenerManager(PR_TRUE, aManager);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
NS_ADDREF(*aTarget = static_cast<nsIContent*>(this));
|
||||
}
|
||||
*aManager = GetListenerManager(PR_TRUE);
|
||||
*aDefer = PR_TRUE;
|
||||
return rv;
|
||||
NS_ENSURE_STATE(*aManager);
|
||||
NS_ADDREF(*aManager);
|
||||
NS_ADDREF(*aTarget = static_cast<nsIContent*>(this));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsGenericElement::nsAttrInfo
|
||||
|
|
|
@ -360,8 +360,7 @@ public:
|
|||
virtual nsresult DispatchDOMEvent(nsEvent* aEvent, nsIDOMEvent* aDOMEvent,
|
||||
nsPresContext* aPresContext,
|
||||
nsEventStatus* aEventStatus);
|
||||
virtual nsresult GetListenerManager(PRBool aCreateIfNotFound,
|
||||
nsIEventListenerManager** aResult);
|
||||
virtual nsIEventListenerManager* GetListenerManager(PRBool aCreateIfNotFound);
|
||||
virtual nsresult AddEventListenerByIID(nsIDOMEventListener *aListener,
|
||||
const nsIID& aIID);
|
||||
virtual nsresult RemoveEventListenerByIID(nsIDOMEventListener *aListener,
|
||||
|
|
|
@ -109,7 +109,8 @@ nsImageLoadingContent::nsImageLoadingContent()
|
|||
// mBroken starts out true, since an image without a URI is broken....
|
||||
mBroken(PR_TRUE),
|
||||
mUserDisabled(PR_FALSE),
|
||||
mSuppressed(PR_FALSE)
|
||||
mSuppressed(PR_FALSE),
|
||||
mIsImageStateForced(PR_FALSE)
|
||||
{
|
||||
if (!nsContentUtils::GetImgLoader()) {
|
||||
mLoadingEnabled = PR_FALSE;
|
||||
|
@ -617,10 +618,18 @@ nsImageLoadingContent::LoadImage(nsIURI* aNewURI,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsImageLoadingContent::ForceImageState(PRBool aForce, PRInt32 aState)
|
||||
{
|
||||
mIsImageStateForced = aForce;
|
||||
mForcedImageState = aState;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRInt32
|
||||
nsImageLoadingContent::ImageState() const
|
||||
{
|
||||
return
|
||||
return mIsImageStateForced ? mForcedImageState :
|
||||
(mBroken * NS_EVENT_STATE_BROKEN) |
|
||||
(mUserDisabled * NS_EVENT_STATE_USERDISABLED) |
|
||||
(mSuppressed * NS_EVENT_STATE_SUPPRESSED) |
|
||||
|
|
|
@ -260,10 +260,21 @@ private:
|
|||
*/
|
||||
ImageObserver mObserverList;
|
||||
|
||||
/**
|
||||
* When mIsImageStateForced is true, this holds the ImageState that we'll
|
||||
* return in ImageState().
|
||||
*/
|
||||
PRInt32 mForcedImageState;
|
||||
|
||||
PRInt16 mImageBlockingStatus;
|
||||
PRPackedBool mLoadingEnabled : 1;
|
||||
PRPackedBool mStartingLoad : 1;
|
||||
|
||||
/**
|
||||
* When true, we return mForcedImageState from ImageState().
|
||||
*/
|
||||
PRPackedBool mIsImageStateForced : 1;
|
||||
|
||||
/**
|
||||
* The state we had the last time we checked whether we needed to notify the
|
||||
* document of a state change. These are maintained by UpdateImageState.
|
||||
|
|
|
@ -222,9 +222,8 @@ nsNodeUtils::LastRelease(nsINode* aNode)
|
|||
if (aNode->HasFlag(NODE_HAS_LISTENERMANAGER)) {
|
||||
#ifdef DEBUG
|
||||
if (nsContentUtils::IsInitialized()) {
|
||||
nsCOMPtr<nsIEventListenerManager> manager;
|
||||
nsContentUtils::GetListenerManager(aNode, PR_FALSE,
|
||||
getter_AddRefs(manager));
|
||||
nsIEventListenerManager* manager =
|
||||
nsContentUtils::GetListenerManager(aNode, PR_FALSE);
|
||||
if (!manager) {
|
||||
NS_ERROR("Huh, our bit says we have a listener manager list, "
|
||||
"but there's nothing in the hash!?!!");
|
||||
|
@ -583,8 +582,7 @@ nsNodeUtils::CloneAndAdopt(nsINode *aNode, PRBool aClone, PRBool aDeep,
|
|||
|
||||
nsPIDOMWindow* window = newDoc->GetInnerWindow();
|
||||
if (window) {
|
||||
nsCOMPtr<nsIEventListenerManager> elm;
|
||||
aNode->GetListenerManager(PR_FALSE, getter_AddRefs(elm));
|
||||
nsIEventListenerManager* elm = aNode->GetListenerManager(PR_FALSE);
|
||||
if (elm) {
|
||||
window->SetMutationListeners(elm->MutationListenerBits());
|
||||
if (elm->MayHavePaintEventListener()) {
|
||||
|
|
|
@ -85,8 +85,6 @@
|
|||
#include "nsObjectLoadingContent.h"
|
||||
#include "mozAutoDocUpdate.h"
|
||||
|
||||
static NS_DEFINE_CID(kCPluginManagerCID, NS_PLUGINMANAGER_CID);
|
||||
|
||||
#ifdef PR_LOGGING
|
||||
static PRLogModuleInfo* gObjectLog = PR_NewLogModule("objlc");
|
||||
#endif
|
||||
|
@ -301,7 +299,7 @@ IsSupportedImage(const nsCString& aMimeType)
|
|||
static PRBool
|
||||
IsSupportedPlugin(const nsCString& aMIMEType)
|
||||
{
|
||||
nsCOMPtr<nsIPluginHost> host(do_GetService("@mozilla.org/plugin/host;1"));
|
||||
nsCOMPtr<nsIPluginHost> host(do_GetService(MOZ_PLUGIN_HOST_CONTRACTID));
|
||||
if (!host) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
@ -339,7 +337,7 @@ IsPluginEnabledByExtension(nsIURI* uri, nsCString& mimeType)
|
|||
if (ext.IsEmpty())
|
||||
return PR_FALSE;
|
||||
|
||||
nsCOMPtr<nsIPluginHost> host(do_GetService("@mozilla.org/plugin/host;1"));
|
||||
nsCOMPtr<nsIPluginHost> host(do_GetService(MOZ_PLUGIN_HOST_CONTRACTID));
|
||||
const char* typeFromExt;
|
||||
if (host &&
|
||||
NS_SUCCEEDED(host->IsPluginEnabledForExtension(ext.get(), typeFromExt))) {
|
||||
|
@ -1584,7 +1582,7 @@ nsObjectLoadingContent::TypeForClassID(const nsAString& aClassID,
|
|||
nsACString& aType)
|
||||
{
|
||||
// Need a plugin host for any class id support
|
||||
nsCOMPtr<nsIPluginHost> pluginHost(do_GetService(kCPluginManagerCID));
|
||||
nsCOMPtr<nsIPluginHost> pluginHost(do_GetService(MOZ_PLUGIN_HOST_CONTRACTID));
|
||||
if (!pluginHost) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
@ -1834,7 +1832,7 @@ nsObjectLoadingContent::GetPluginSupportState(nsIContent* aContent,
|
|||
/* static */ PluginSupportState
|
||||
nsObjectLoadingContent::GetPluginDisabledState(const nsCString& aContentType)
|
||||
{
|
||||
nsCOMPtr<nsIPluginHost> host(do_GetService("@mozilla.org/plugin/host;1"));
|
||||
nsCOMPtr<nsIPluginHost> host(do_GetService(MOZ_PLUGIN_HOST_CONTRACTID));
|
||||
if (!host) {
|
||||
return ePluginUnsupported;
|
||||
}
|
||||
|
|
|
@ -56,7 +56,6 @@
|
|||
#include "nsIDocumentEncoder.h"
|
||||
#include "nsTArray.h"
|
||||
|
||||
|
||||
class nsPlainTextSerializer : public nsIContentSerializer,
|
||||
public nsIHTMLContentSink,
|
||||
public nsIHTMLToTextSink
|
||||
|
@ -97,8 +96,6 @@ public:
|
|||
|
||||
// nsIContentSink
|
||||
NS_IMETHOD WillParse(void) { return NS_OK; }
|
||||
NS_IMETHOD WillBuildModel(void) { return NS_OK; }
|
||||
NS_IMETHOD DidBuildModel(void) { return NS_OK; }
|
||||
NS_IMETHOD WillInterrupt(void) { return NS_OK; }
|
||||
NS_IMETHOD WillResume(void) { return NS_OK; }
|
||||
NS_IMETHOD SetParser(nsIParser* aParser) { return NS_OK; }
|
||||
|
|
|
@ -465,14 +465,6 @@ public:
|
|||
{
|
||||
return mInner->SetTarget(aTarget);
|
||||
}
|
||||
NS_IMETHOD SetCurrentTarget(nsIDOMEventTarget* aTarget)
|
||||
{
|
||||
return mInner->SetCurrentTarget(aTarget);
|
||||
}
|
||||
NS_IMETHOD SetOriginalTarget(nsIDOMEventTarget* aTarget)
|
||||
{
|
||||
return mInner->SetOriginalTarget(aTarget);
|
||||
}
|
||||
NS_IMETHOD_(PRBool) IsDispatchStopped()
|
||||
{
|
||||
return mInner->IsDispatchStopped();
|
||||
|
@ -481,10 +473,6 @@ public:
|
|||
{
|
||||
return mInner->GetInternalNSEvent();
|
||||
}
|
||||
NS_IMETHOD_(PRBool) HasOriginalTarget()
|
||||
{
|
||||
return mInner->HasOriginalTarget();
|
||||
}
|
||||
NS_IMETHOD SetTrusted(PRBool aTrusted)
|
||||
{
|
||||
return mInner->SetTrusted(aTrusted);
|
||||
|
|
|
@ -313,6 +313,10 @@ _TEST_FILES = test_bug5141.html \
|
|||
file_htmlserializer_ipv6.html \
|
||||
file_htmlserializer_ipv6_out.html \
|
||||
test_bug498433.html \
|
||||
test_bug498897.html \
|
||||
file_bug498897.html \
|
||||
file_bug498897.html^headers^ \
|
||||
file_bug498897.css \
|
||||
$(NULL)
|
||||
# Disabled; see bug 492181
|
||||
# test_plugin_freezing.html
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
body { background: orange; }
|
|
@ -0,0 +1,23 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>Testcase for bug 498897</title>
|
||||
<script type="application/javascript" language="javascript">
|
||||
<!--
|
||||
function test()
|
||||
{
|
||||
var hadException = false;
|
||||
try {
|
||||
document.createComment('a');
|
||||
}
|
||||
catch (e) {
|
||||
hadException = true;
|
||||
}
|
||||
parent.ok(!hadException, "Shouldn't have got an exception!");
|
||||
parent.testFinished();
|
||||
}
|
||||
//-->
|
||||
</script>
|
||||
</head>
|
||||
<body onload="test();">
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1 @@
|
|||
Link: <file_bug498897.css>; rel=stylesheet
|
|
@ -80,6 +80,8 @@ categoryManager.addCategoryEntry("content-policy", policyName, policyName, false
|
|||
var tests = ["SCRIPT", "IMAGE", "STYLESHEET", "OBJECT", "DOCUMENT", "SUBDOCUMENT", "XBL", "XMLHTTPREQUEST"];
|
||||
var curTest = -1;
|
||||
|
||||
var div;
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
setTimeout(runNextTest, 0);
|
||||
|
||||
|
@ -89,6 +91,12 @@ function runNextTest() {
|
|||
if (curTest >= 0) {
|
||||
var type = "TYPE_" + tests[curTest];
|
||||
is(lastContentType, Ci.nsIContentPolicy[type], "Content policies triggered for " + type);
|
||||
|
||||
if (tests[curTest] == "XBL")
|
||||
{
|
||||
//XXX Removing binding to work-around a memory leak (bugs 478528, 499735).
|
||||
document.removeBinding(div, testURL);
|
||||
}
|
||||
}
|
||||
|
||||
curTest++;
|
||||
|
@ -165,7 +173,7 @@ function request_subdocument() {
|
|||
function request_xbl() {
|
||||
var content = $("content");
|
||||
|
||||
var div = document.createElement("div");
|
||||
div = document.createElement("div");
|
||||
content.appendChild(div);
|
||||
|
||||
document.addBinding(div, testURL);
|
||||
|
|
|
@ -0,0 +1,108 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=498897
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 498897</title>
|
||||
<script type="application/javascript" src="/MochiKit/packed.js"></script>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=498897">Mozilla Bug 498897</a>
|
||||
<p id="display"><iframe id="testframe"></iframe></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
/** Test for Bug 498897 **/
|
||||
|
||||
var checkedLoad = false;
|
||||
|
||||
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
||||
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
|
||||
// Content policy / factory implementation for the test
|
||||
var policyID = Components.ID("{65944d64-2390-422e-bea3-80d0af7f69ef}");
|
||||
var policyName = "@mozilla.org/498897_testpolicy;1";
|
||||
var policy = {
|
||||
// nsISupports implementation
|
||||
QueryInterface: function(iid) {
|
||||
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
||||
|
||||
if (iid.equals(Ci.nsISupports) ||
|
||||
iid.equals(Ci.nsIFactory) ||
|
||||
iid.equals(Ci.nsIContentPolicy))
|
||||
return this;
|
||||
|
||||
throw Components.results.NS_ERROR_NO_INTERFACE;
|
||||
},
|
||||
|
||||
// nsIFactory implementation
|
||||
createInstance: function(outer, iid) {
|
||||
return this.QueryInterface(iid);
|
||||
},
|
||||
|
||||
// nsIContentPolicy implementation
|
||||
shouldLoad: function(contentType, contentLocation, requestOrigin, context,
|
||||
mimeTypeGuess, extra) {
|
||||
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
||||
|
||||
if (contentLocation instanceof Ci.nsIURL &&
|
||||
contentLocation.fileName == "file_bug498897.css" &&
|
||||
requestOrigin instanceof Ci.nsIURL &&
|
||||
requestOrigin.fileName == "file_bug498897.html") {
|
||||
checkedLoad = true;
|
||||
}
|
||||
|
||||
return Ci.nsIContentPolicy.ACCEPT;
|
||||
},
|
||||
|
||||
shouldProcess: function(contentType, contentLocation, requestOrigin, context,
|
||||
mimeTypeGuess, extra) {
|
||||
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
||||
|
||||
return Ci.nsIContentPolicy.ACCEPT;
|
||||
}
|
||||
}
|
||||
|
||||
var componentManager = Components.manager
|
||||
.QueryInterface(Ci.nsIComponentRegistrar);
|
||||
componentManager.registerFactory(policyID, "Test content policy for bug 498897",
|
||||
policyName, policy);
|
||||
|
||||
var categoryManager =
|
||||
Cc["@mozilla.org/categorymanager;1"].getService(Ci.nsICategoryManager);
|
||||
categoryManager.addCategoryEntry("content-policy", policyName, policyName,
|
||||
false, true);
|
||||
|
||||
function testFinished()
|
||||
{
|
||||
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
||||
|
||||
ok(checkedLoad, "Content policy didn't get called!");
|
||||
|
||||
categoryManager.deleteCategoryEntry("content-policy", policyName, false);
|
||||
|
||||
setTimeout(function() {
|
||||
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
||||
|
||||
componentManager.unregisterFactory(policyID, policy);
|
||||
|
||||
SimpleTest.finish();
|
||||
}, 0);
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
document.getElementById("testframe").src = "file_bug498897.html";
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,94 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Vladimir Vukicevic <vladimir@pobox.com>
|
||||
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "prmem.h"
|
||||
|
||||
#include "nsIServiceManager.h"
|
||||
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIDOMCanvasRenderingContext2D.h"
|
||||
#include "nsICanvasRenderingContextInternal.h"
|
||||
#include "nsICanvasElement.h"
|
||||
#include "nsIPrincipal.h"
|
||||
#include "nsINode.h"
|
||||
|
||||
#include "nsGfxCIID.h"
|
||||
|
||||
#include "nsTArray.h"
|
||||
|
||||
#include "CanvasUtils.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
void
|
||||
CanvasUtils::DoDrawImageSecurityCheck(nsICanvasElement *aCanvasElement,
|
||||
nsIPrincipal *aPrincipal,
|
||||
PRBool forceWriteOnly)
|
||||
{
|
||||
// Callers should ensure that mCanvasElement is non-null before calling this
|
||||
if (!aCanvasElement) {
|
||||
NS_WARNING("DoDrawImageSecurityCheck called without canvas element!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (aCanvasElement->IsWriteOnly())
|
||||
return;
|
||||
|
||||
// If we explicitly set WriteOnly just do it and get out
|
||||
if (forceWriteOnly) {
|
||||
aCanvasElement->SetWriteOnly();
|
||||
return;
|
||||
}
|
||||
|
||||
if (aPrincipal == nsnull)
|
||||
return;
|
||||
|
||||
nsCOMPtr<nsINode> elem = do_QueryInterface(aCanvasElement);
|
||||
if (elem) { // XXXbz How could this actually be null?
|
||||
PRBool subsumes;
|
||||
nsresult rv =
|
||||
elem->NodePrincipal()->Subsumes(aPrincipal, &subsumes);
|
||||
|
||||
if (NS_SUCCEEDED(rv) && subsumes) {
|
||||
// This canvas has access to that image anyway
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
aCanvasElement->SetWriteOnly();
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
|
@ -15,11 +15,10 @@
|
|||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2003
|
||||
* Vladimir Vukicevic <vladimir@pobox.com>
|
||||
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Original Author: Aaron Leventhal (aaronl@netscape.com)
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
|
@ -36,32 +35,49 @@
|
|||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
#ifndef _CANVASUTILS_H_
|
||||
#define _CANVASUTILS_H_
|
||||
|
||||
interface nsIAccessNode;
|
||||
interface nsIContent;
|
||||
#include "prtypes.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsICanvasElement.h"
|
||||
#include "nsIPrincipal.h"
|
||||
#include "nsIDOMElement.h"
|
||||
#include "nsRect.h"
|
||||
|
||||
[uuid(fa9cafac-9562-49ad-afcf-911ab1e4e4fb)]
|
||||
#include "gfxASurface.h"
|
||||
|
||||
interface nsPIAccessibleDocument : nsISupports
|
||||
{
|
||||
/**
|
||||
* Find the accessible object in the accessibility cache that
|
||||
* corresponds to aStartNode or the first ancestor of aStartNode
|
||||
* that has an accessible object associated with it.
|
||||
* Clear that accessible object's parent's cache of accessible children and
|
||||
* and remove the accessible object and any decendents from the accessible cache.
|
||||
* New accessible objects will be created and cached again on demand.
|
||||
* @param aChangeContent The child that is changing
|
||||
* @param aEvent The event from nsIAccessibleEvent that caused the change:
|
||||
* Must be one of: EVENT_REORDER (change),
|
||||
* EVENT_SHOW (make visible or create) or
|
||||
* EVENT_HIDE (destroy or hide)
|
||||
*/
|
||||
void invalidateCacheSubtree(in nsIContent aChangeContent,
|
||||
in PRUint32 aChangeEvent);
|
||||
void cacheAccessNode(in voidPtr aUniqueID, in nsIAccessNode aAccessNode);
|
||||
void flushPendingEvents();
|
||||
void fireDocLoadEvents(in PRUint32 aEventType);
|
||||
void fireAnchorJumpEvent();
|
||||
namespace mozilla {
|
||||
|
||||
class CanvasUtils {
|
||||
public:
|
||||
// Check that the rectangle [x,y,w,h] is a subrectangle of [0,0,realWidth,realHeight]
|
||||
|
||||
static PRBool CheckSaneSubrectSize(PRInt32 x, PRInt32 y, PRInt32 w, PRInt32 h,
|
||||
PRInt32 realWidth, PRInt32 realHeight)
|
||||
{
|
||||
if (w <= 0 || h <= 0 || x < 0 || y < 0)
|
||||
return PR_FALSE;
|
||||
|
||||
if (x >= realWidth || w > (realWidth - x) ||
|
||||
y >= realHeight || h > (realHeight - y))
|
||||
return PR_FALSE;
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
// Flag aCanvasElement as write-only if drawing an image with aPrincipal
|
||||
// onto it would make it such.
|
||||
|
||||
static void DoDrawImageSecurityCheck(nsICanvasElement *aCanvasElement,
|
||||
nsIPrincipal *aPrincipal,
|
||||
PRBool forceWriteOnly);
|
||||
|
||||
private:
|
||||
// this can't be instantiated
|
||||
CanvasUtils() { }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* _CANVASUTILS_H_ */
|
|
@ -68,17 +68,11 @@ REQUIRES = \
|
|||
qcms \
|
||||
$(NULL)
|
||||
|
||||
# XXX some platforms can't handle building
|
||||
# an empty .a/lib. Remove this dummy.cpp
|
||||
# whenever w have a rendering context
|
||||
# that doesn't depend on any non-default
|
||||
# libraries.
|
||||
CPPSRCS = dummy.cpp \
|
||||
$(NULL)
|
||||
|
||||
ifdef MOZ_ENABLE_CANVAS
|
||||
CPPSRCS += nsCanvasRenderingContext2D.cpp
|
||||
endif
|
||||
CPPSRCS = \
|
||||
CanvasUtils.cpp \
|
||||
nsCanvasRenderingContext2D.cpp \
|
||||
$(NULL)
|
||||
|
||||
# we don't want the shared lib, but we want to force the creation of a static lib.
|
||||
FORCE_STATIC_LIB = 1
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
/*
|
||||
* This file only exists because some platforms can't handle building an empty .a
|
||||
* file, or .lib, or whatever (e.g. OS X, possibly Win32).
|
||||
*
|
||||
* Need at least one external symbol for some linkers to create a proper
|
||||
* archive file: https://bugzilla.mozilla.org/show_bug.cgi?id=311143
|
||||
*/
|
||||
void concvsdummy(void) {}
|
||||
|
|
@ -55,15 +55,9 @@
|
|||
#include "nsIPresShell.h"
|
||||
#include "nsIVariant.h"
|
||||
|
||||
#include "imgIRequest.h"
|
||||
#include "imgIContainer.h"
|
||||
#include "gfxIImageFrame.h"
|
||||
#include "nsIDOMHTMLCanvasElement.h"
|
||||
#include "nsICanvasElement.h"
|
||||
#include "nsIDOMHTMLImageElement.h"
|
||||
#include "nsIImageLoadingContent.h"
|
||||
#include "nsIInterfaceRequestorUtils.h"
|
||||
#include "nsIImage.h"
|
||||
#include "nsIFrame.h"
|
||||
#include "nsDOMError.h"
|
||||
#include "nsIScriptError.h"
|
||||
|
@ -110,17 +104,15 @@
|
|||
|
||||
#include "nsBidiPresUtils.h"
|
||||
|
||||
#ifdef MOZ_MEDIA
|
||||
#include "nsHTMLVideoElement.h"
|
||||
#endif
|
||||
#include "CanvasUtils.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846
|
||||
#define M_PI_2 1.57079632679489661923
|
||||
#endif
|
||||
|
||||
static PRBool CheckSaneSubrectSize (PRInt32 x, PRInt32 y, PRInt32 w, PRInt32 h, PRInt32 realWidth, PRInt32 realHeight);
|
||||
|
||||
/* Float validation stuff */
|
||||
|
||||
#define VALIDATE(_f) if (!JSDOUBLE_IS_FINITE(_f)) return PR_FALSE
|
||||
|
@ -360,14 +352,6 @@ protected:
|
|||
*/
|
||||
void ApplyStyle(Style aWhichStyle, PRBool aUseGlobalAlpha = PR_TRUE);
|
||||
|
||||
// If aPrincipal is not subsumed by this canvas element, then
|
||||
// we make the canvas write-only so bad guys can't extract the pixel
|
||||
// data. If forceWriteOnly is set, we force write only to be set
|
||||
// and ignore aPrincipal. (This is used for when the original data came
|
||||
// from a <canvas> that had write-only set.)
|
||||
void DoDrawImageSecurityCheck(nsIPrincipal* aPrincipal,
|
||||
PRBool forceWriteOnly);
|
||||
|
||||
// Member vars
|
||||
PRInt32 mWidth, mHeight;
|
||||
PRPackedBool mValid;
|
||||
|
@ -390,7 +374,13 @@ protected:
|
|||
* Flag to avoid duplicate calls to InvalidateFrame. Set to true whenever
|
||||
* Redraw is called, reset to false when Render is called.
|
||||
*/
|
||||
PRBool mIsFrameInvalid;
|
||||
PRBool mIsEntireFrameInvalid;
|
||||
|
||||
/**
|
||||
* Number of times we've invalidated before calling redraw
|
||||
*/
|
||||
PRUint32 mInvalidateCount;
|
||||
static const PRUint32 kCanvasMaxInvalidateCount = 100;
|
||||
|
||||
/**
|
||||
* Returns true iff the the given operator should affect areas of the
|
||||
|
@ -478,8 +468,11 @@ protected:
|
|||
/**
|
||||
* Draws the current path in the given style. Takes care of
|
||||
* any shadow drawing and will use intermediate surfaces as needed.
|
||||
*
|
||||
* If dirtyRect is given, it will contain the device-space dirty
|
||||
* rectangle of the draw operation.
|
||||
*/
|
||||
nsresult DrawPath(Style style);
|
||||
nsresult DrawPath(Style style, gfxRect *dirtyRect = nsnull);
|
||||
|
||||
/**
|
||||
* Draws a rectangle in the given style; used by FillRect and StrokeRect.
|
||||
|
@ -614,14 +607,6 @@ protected:
|
|||
static PRBool ConvertJSValToDouble(double* aProp, JSContext* aContext,
|
||||
jsval aValue);
|
||||
|
||||
// thebes helpers
|
||||
nsresult ThebesSurfaceFromElement(nsIDOMElement *imgElt,
|
||||
PRBool forceCopy,
|
||||
gfxASurface **aSurface,
|
||||
PRInt32 *widthOut, PRInt32 *heightOut,
|
||||
nsIPrincipal **prinOut,
|
||||
PRBool *forceWriteOnlyOut);
|
||||
|
||||
// other helpers
|
||||
void GetAppUnitsValues(PRUint32 *perDevPixel, PRUint32 *perCSSPixel) {
|
||||
// If we don't have a canvas element, we just return something generic.
|
||||
|
@ -677,8 +662,8 @@ NS_NewCanvasRenderingContext2D(nsIDOMCanvasRenderingContext2D** aResult)
|
|||
|
||||
nsCanvasRenderingContext2D::nsCanvasRenderingContext2D()
|
||||
: mValid(PR_FALSE), mOpaque(PR_FALSE), mCanvasElement(nsnull),
|
||||
mSaveCount(0), mIsFrameInvalid(PR_FALSE), mLastStyle(STYLE_MAX),
|
||||
mStyleStack(20)
|
||||
mSaveCount(0), mIsEntireFrameInvalid(PR_FALSE), mInvalidateCount(0),
|
||||
mLastStyle(STYLE_MAX), mStyleStack(20)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -693,7 +678,7 @@ nsCanvasRenderingContext2D::Destroy()
|
|||
mSurface = nsnull;
|
||||
mThebes = nsnull;
|
||||
mValid = PR_FALSE;
|
||||
mIsFrameInvalid = PR_FALSE;
|
||||
mIsEntireFrameInvalid = PR_FALSE;
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -791,43 +776,6 @@ nsCanvasRenderingContext2D::DirtyAllStyles()
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsCanvasRenderingContext2D::DoDrawImageSecurityCheck(nsIPrincipal* aPrincipal,
|
||||
PRBool forceWriteOnly)
|
||||
{
|
||||
// Callers should ensure that mCanvasElement is non-null before calling this
|
||||
if (!mCanvasElement) {
|
||||
NS_WARNING("DoDrawImageSecurityCheck called without canvas element!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (mCanvasElement->IsWriteOnly())
|
||||
return;
|
||||
|
||||
// If we explicitly set WriteOnly just do it and get out
|
||||
if (forceWriteOnly) {
|
||||
mCanvasElement->SetWriteOnly();
|
||||
return;
|
||||
}
|
||||
|
||||
if (aPrincipal == nsnull)
|
||||
return;
|
||||
|
||||
nsCOMPtr<nsINode> elem = do_QueryInterface(mCanvasElement);
|
||||
if (elem) { // XXXbz How could this actually be null?
|
||||
PRBool subsumes;
|
||||
nsresult rv =
|
||||
elem->NodePrincipal()->Subsumes(aPrincipal, &subsumes);
|
||||
|
||||
if (NS_SUCCEEDED(rv) && subsumes) {
|
||||
// This canvas has access to that image anyway
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
mCanvasElement->SetWriteOnly();
|
||||
}
|
||||
|
||||
void
|
||||
nsCanvasRenderingContext2D::ApplyStyle(Style aWhichStyle,
|
||||
PRBool aUseGlobalAlpha)
|
||||
|
@ -850,8 +798,9 @@ nsCanvasRenderingContext2D::ApplyStyle(Style aWhichStyle,
|
|||
if (!mCanvasElement)
|
||||
return;
|
||||
|
||||
DoDrawImageSecurityCheck(pattern->Principal(),
|
||||
pattern->GetForceWriteOnly());
|
||||
CanvasUtils::DoDrawImageSecurityCheck(mCanvasElement,
|
||||
pattern->Principal(),
|
||||
pattern->GetForceWriteOnly());
|
||||
|
||||
gfxPattern* gpat = pattern->GetPattern();
|
||||
|
||||
|
@ -883,12 +832,11 @@ nsCanvasRenderingContext2D::Redraw()
|
|||
if (!mCanvasElement)
|
||||
return NS_OK;
|
||||
|
||||
if (!mIsFrameInvalid) {
|
||||
mIsFrameInvalid = PR_TRUE;
|
||||
return mCanvasElement->InvalidateFrame();
|
||||
}
|
||||
if (mIsEntireFrameInvalid)
|
||||
return NS_OK;
|
||||
|
||||
return NS_OK;
|
||||
mIsEntireFrameInvalid = PR_TRUE;
|
||||
return mCanvasElement->InvalidateFrame();
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -897,12 +845,13 @@ nsCanvasRenderingContext2D::Redraw(const gfxRect& r)
|
|||
if (!mCanvasElement)
|
||||
return NS_OK;
|
||||
|
||||
if (!mIsFrameInvalid) {
|
||||
mIsFrameInvalid = PR_TRUE;
|
||||
return mCanvasElement->InvalidateFrameSubrect(r);
|
||||
}
|
||||
if (mIsEntireFrameInvalid)
|
||||
return NS_OK;
|
||||
|
||||
return NS_OK;
|
||||
if (++mInvalidateCount > kCanvasMaxInvalidateCount)
|
||||
return Redraw();
|
||||
|
||||
return mCanvasElement->InvalidateFrameSubrect(r);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -1013,7 +962,9 @@ nsCanvasRenderingContext2D::Render(gfxContext *ctx, gfxPattern::GraphicsFilter a
|
|||
if (mOpaque)
|
||||
ctx->SetOperator(op);
|
||||
|
||||
mIsFrameInvalid = PR_FALSE;
|
||||
mIsEntireFrameInvalid = PR_FALSE;
|
||||
mInvalidateCount = 0;
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -1333,7 +1284,6 @@ nsCanvasRenderingContext2D::CreatePattern(nsIDOMHTMLElement *image,
|
|||
const nsAString& repeat,
|
||||
nsIDOMCanvasPattern **_retval)
|
||||
{
|
||||
nsresult rv;
|
||||
gfxPattern::GraphicsExtend extend;
|
||||
|
||||
if (repeat.IsEmpty() || repeat.EqualsLiteral("repeat")) {
|
||||
|
@ -1351,22 +1301,17 @@ nsCanvasRenderingContext2D::CreatePattern(nsIDOMHTMLElement *image,
|
|||
return NS_ERROR_DOM_SYNTAX_ERR;
|
||||
}
|
||||
|
||||
PRInt32 imgWidth, imgHeight;
|
||||
nsCOMPtr<nsIPrincipal> principal;
|
||||
PRBool forceWriteOnly = PR_FALSE;
|
||||
nsRefPtr<gfxASurface> imgsurf;
|
||||
rv = ThebesSurfaceFromElement(image, PR_TRUE,
|
||||
getter_AddRefs(imgsurf), &imgWidth, &imgHeight,
|
||||
getter_AddRefs(principal), &forceWriteOnly);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
nsLayoutUtils::SurfaceFromElementResult res =
|
||||
nsLayoutUtils::SurfaceFromElement(image, nsLayoutUtils::SFE_WANT_NEW_SURFACE);
|
||||
if (!res.mSurface)
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
nsRefPtr<gfxPattern> thebespat = new gfxPattern(imgsurf);
|
||||
nsRefPtr<gfxPattern> thebespat = new gfxPattern(res.mSurface);
|
||||
|
||||
thebespat->SetExtend(extend);
|
||||
|
||||
nsRefPtr<nsCanvasPattern> pat = new nsCanvasPattern(thebespat, principal,
|
||||
forceWriteOnly);
|
||||
nsRefPtr<nsCanvasPattern> pat = new nsCanvasPattern(thebespat, res.mPrincipal,
|
||||
res.mIsWriteOnly);
|
||||
if (!pat)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
|
@ -1524,7 +1469,7 @@ nsCanvasRenderingContext2D::ShadowFinalize(gfxAlphaBoxBlur& blur)
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsCanvasRenderingContext2D::DrawPath(Style style)
|
||||
nsCanvasRenderingContext2D::DrawPath(Style style, gfxRect *dirtyRect)
|
||||
{
|
||||
/*
|
||||
* Need an intermediate surface when:
|
||||
|
@ -1591,6 +1536,12 @@ nsCanvasRenderingContext2D::DrawPath(Style style)
|
|||
else
|
||||
mThebes->Stroke();
|
||||
|
||||
// XXX do some more work to calculate the extents of shadows
|
||||
// XXX handle stroke extents
|
||||
if (dirtyRect && style == STYLE_FILL && !doDrawShadow) {
|
||||
*dirtyRect = mThebes->GetUserPathExtent();
|
||||
}
|
||||
|
||||
if (doUseIntermediateSurface) {
|
||||
mThebes->PopGroupToSource();
|
||||
DirtyAllStyles();
|
||||
|
@ -1598,6 +1549,15 @@ nsCanvasRenderingContext2D::DrawPath(Style style)
|
|||
mThebes->Paint(CurrentState().StyleIsColor(style) ? 1.0 : CurrentState().globalAlpha);
|
||||
}
|
||||
|
||||
if (dirtyRect) {
|
||||
if (style != STYLE_FILL || doDrawShadow) {
|
||||
// just use the clip extents
|
||||
*dirtyRect = mThebes->GetClipExtents();
|
||||
}
|
||||
|
||||
*dirtyRect = mThebes->UserToDevice(*dirtyRect);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -1619,7 +1579,8 @@ nsCanvasRenderingContext2D::ClearRect(float x, float y, float w, float h)
|
|||
mThebes->Rectangle(gfxRect(x, y, w, h));
|
||||
mThebes->Fill();
|
||||
|
||||
return Redraw();
|
||||
gfxRect dirty = mThebes->UserToDevice(mThebes->GetUserPathExtent());
|
||||
return Redraw(dirty);
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -1633,11 +1594,12 @@ nsCanvasRenderingContext2D::DrawRect(const gfxRect& rect, Style style)
|
|||
mThebes->NewPath();
|
||||
mThebes->Rectangle(rect);
|
||||
|
||||
nsresult rv = DrawPath(style);
|
||||
gfxRect dirty;
|
||||
nsresult rv = DrawPath(style, &dirty);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
return Redraw();
|
||||
return Redraw(dirty);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -1673,19 +1635,21 @@ nsCanvasRenderingContext2D::ClosePath()
|
|||
NS_IMETHODIMP
|
||||
nsCanvasRenderingContext2D::Fill()
|
||||
{
|
||||
nsresult rv = DrawPath(STYLE_FILL);
|
||||
gfxRect dirty;
|
||||
nsresult rv = DrawPath(STYLE_FILL, &dirty);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
return Redraw();
|
||||
return Redraw(dirty);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCanvasRenderingContext2D::Stroke()
|
||||
{
|
||||
nsresult rv = DrawPath(STYLE_STROKE);
|
||||
gfxRect dirty;
|
||||
nsresult rv = DrawPath(STYLE_STROKE, &dirty);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
return Redraw();
|
||||
return Redraw(dirty);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -2301,8 +2265,7 @@ nsCanvasRenderingContext2D::DrawOrMeasureText(const nsAString& aRawText,
|
|||
processor.mThebes = mThebes;
|
||||
processor.mOp = aOp;
|
||||
processor.mBoundingBox = gfxRect(0, 0, 0, 0);
|
||||
// need to measure size if using an intermediate surface for drawing
|
||||
processor.mDoMeasureBoundingBox = doDrawShadow;
|
||||
processor.mDoMeasureBoundingBox = doDrawShadow || !mIsEntireFrameInvalid;
|
||||
|
||||
processor.mFontgrp = GetCurrentFontStyle();
|
||||
NS_ASSERTION(processor.mFontgrp, "font group is null");
|
||||
|
@ -2396,6 +2359,9 @@ nsCanvasRenderingContext2D::DrawOrMeasureText(const nsAString& aRawText,
|
|||
mThebes->Translate(-trans);
|
||||
}
|
||||
|
||||
// save the previous bounding box
|
||||
gfxRect boundingBox = processor.mBoundingBox;
|
||||
|
||||
// don't ever need to measure the bounding box twice
|
||||
processor.mDoMeasureBoundingBox = PR_FALSE;
|
||||
|
||||
|
@ -2477,6 +2443,9 @@ nsCanvasRenderingContext2D::DrawOrMeasureText(const nsAString& aRawText,
|
|||
} else if (doUseIntermediateSurface)
|
||||
mThebes->Paint(CurrentState().StyleIsColor(STYLE_FILL) ? 1.0 : CurrentState().globalAlpha);
|
||||
|
||||
if (aOp == nsCanvasRenderingContext2D::TEXT_DRAW_OPERATION_FILL && !doDrawShadow)
|
||||
return Redraw(mThebes->UserToDevice(boundingBox));
|
||||
|
||||
return Redraw();
|
||||
}
|
||||
|
||||
|
@ -2542,7 +2511,8 @@ nsCanvasRenderingContext2D::MozDrawText(const nsAString& textToDraw)
|
|||
nsnull,
|
||||
nsnull,
|
||||
nsnull);
|
||||
return NS_OK;
|
||||
|
||||
return Redraw();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -2651,10 +2621,12 @@ nsCanvasRenderingContext2D::MozTextAlongPath(const nsAString& textToDraw, PRBool
|
|||
x += 2 * halfAdvance;
|
||||
}
|
||||
|
||||
if(stroke)
|
||||
if (stroke) {
|
||||
ApplyStyle(STYLE_STROKE);
|
||||
else
|
||||
mThebes->NewPath();
|
||||
} else {
|
||||
ApplyStyle(STYLE_FILL);
|
||||
}
|
||||
|
||||
for(PRUint32 i = 0; i < strLength; i++)
|
||||
{
|
||||
|
@ -2679,9 +2651,12 @@ nsCanvasRenderingContext2D::MozTextAlongPath(const nsAString& textToDraw, PRBool
|
|||
mThebes->SetMatrix(matrix);
|
||||
}
|
||||
|
||||
if (stroke)
|
||||
mThebes->Stroke();
|
||||
|
||||
delete [] cp;
|
||||
|
||||
return NS_OK;
|
||||
return Redraw();
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -2919,6 +2894,7 @@ NS_IMETHODIMP
|
|||
nsCanvasRenderingContext2D::DrawImage()
|
||||
{
|
||||
nsresult rv;
|
||||
gfxRect dirty;
|
||||
|
||||
// we can't do a security check without a canvas element, so
|
||||
// just skip this entirely
|
||||
|
@ -2959,22 +2935,33 @@ nsCanvasRenderingContext2D::DrawImage()
|
|||
ctx, argv[0]))
|
||||
return NS_ERROR_DOM_TYPE_MISMATCH_ERR;
|
||||
|
||||
PRInt32 imgWidth, imgHeight;
|
||||
nsCOMPtr<nsIPrincipal> principal;
|
||||
PRBool forceWriteOnly = PR_FALSE;
|
||||
gfxMatrix matrix;
|
||||
nsRefPtr<gfxPattern> pattern;
|
||||
nsRefPtr<gfxPath> path;
|
||||
nsRefPtr<gfxASurface> imgsurf;
|
||||
#ifdef WINCE
|
||||
nsRefPtr<gfxASurface> currentSurface;
|
||||
#endif
|
||||
rv = ThebesSurfaceFromElement(imgElt, PR_FALSE,
|
||||
getter_AddRefs(imgsurf), &imgWidth, &imgHeight,
|
||||
getter_AddRefs(principal), &forceWriteOnly);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
DoDrawImageSecurityCheck(principal, forceWriteOnly);
|
||||
nsLayoutUtils::SurfaceFromElementResult res =
|
||||
nsLayoutUtils::SurfaceFromElement(imgElt);
|
||||
if (!res.mSurface)
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
#ifndef WINCE
|
||||
// On non-CE, force a copy if we're using drawImage with our destination
|
||||
// as a source to work around some Cairo self-copy semantics issues.
|
||||
if (res.mSurface == mSurface) {
|
||||
res = nsLayoutUtils::SurfaceFromElement(imgElt, nsLayoutUtils::SFE_WANT_NEW_SURFACE);
|
||||
if (!res.mSurface)
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
#endif
|
||||
|
||||
nsRefPtr<gfxASurface> imgsurf = res.mSurface;
|
||||
nsCOMPtr<nsIPrincipal> principal = res.mPrincipal;
|
||||
gfxIntSize imgSize = res.mSize;
|
||||
PRBool forceWriteOnly = res.mIsWriteOnly;
|
||||
|
||||
CanvasUtils::DoDrawImageSecurityCheck(mCanvasElement, principal, forceWriteOnly);
|
||||
|
||||
gfxContextPathAutoSaveRestore pathSR(mThebes, PR_FALSE);
|
||||
|
||||
|
@ -2987,16 +2974,16 @@ nsCanvasRenderingContext2D::DrawImage()
|
|||
GET_ARG(&dx, argv[1]);
|
||||
GET_ARG(&dy, argv[2]);
|
||||
sx = sy = 0.0;
|
||||
dw = sw = (double) imgWidth;
|
||||
dh = sh = (double) imgHeight;
|
||||
dw = sw = (double) imgSize.width;
|
||||
dh = sh = (double) imgSize.height;
|
||||
} else if (argc == 5) {
|
||||
GET_ARG(&dx, argv[1]);
|
||||
GET_ARG(&dy, argv[2]);
|
||||
GET_ARG(&dw, argv[3]);
|
||||
GET_ARG(&dh, argv[4]);
|
||||
sx = sy = 0.0;
|
||||
sw = (double) imgWidth;
|
||||
sh = (double) imgHeight;
|
||||
sw = (double) imgSize.width;
|
||||
sh = (double) imgSize.height;
|
||||
} else if (argc == 9) {
|
||||
GET_ARG(&sx, argv[1]);
|
||||
GET_ARG(&sy, argv[2]);
|
||||
|
@ -3027,8 +3014,8 @@ nsCanvasRenderingContext2D::DrawImage()
|
|||
|
||||
// check args
|
||||
if (sx < 0.0 || sy < 0.0 ||
|
||||
sw < 0.0 || sw > (double) imgWidth ||
|
||||
sh < 0.0 || sh > (double) imgHeight ||
|
||||
sw < 0.0 || sw > (double) imgSize.width ||
|
||||
sh < 0.0 || sh > (double) imgSize.height ||
|
||||
dw < 0.0 || dh < 0.0)
|
||||
{
|
||||
// XXX ERRMSG we need to report an error to developers here! (bug 329026)
|
||||
|
@ -3118,6 +3105,8 @@ nsCanvasRenderingContext2D::DrawImage()
|
|||
} else
|
||||
mThebes->Clip(clip);
|
||||
|
||||
dirty = mThebes->UserToDevice(clip);
|
||||
|
||||
mThebes->Paint(CurrentState().globalAlpha);
|
||||
}
|
||||
|
||||
|
@ -3134,7 +3123,7 @@ nsCanvasRenderingContext2D::DrawImage()
|
|||
|
||||
FINISH:
|
||||
if (NS_SUCCEEDED(rv))
|
||||
rv = Redraw();
|
||||
rv = Redraw(dirty);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
@ -3258,192 +3247,6 @@ nsCanvasRenderingContext2D::ConvertJSValToXPCObject(nsISupports** aSupports, REF
|
|||
return JS_FALSE;
|
||||
}
|
||||
|
||||
/* thebes ARGB32 surfaces are ARGB stored as a packed 32-bit integer; on little-endian
|
||||
* platforms, they appear as BGRA bytes in the surface data. The color values are also
|
||||
* stored with premultiplied alpha.
|
||||
*
|
||||
* If forceCopy is FALSE, a surface may be returned that's only valid during the current
|
||||
* operation. If it's TRUE, a copy will always be made that can safely be retained.
|
||||
*/
|
||||
|
||||
nsresult
|
||||
nsCanvasRenderingContext2D::ThebesSurfaceFromElement(nsIDOMElement *imgElt,
|
||||
PRBool forceCopy,
|
||||
gfxASurface **aSurface,
|
||||
PRInt32 *widthOut,
|
||||
PRInt32 *heightOut,
|
||||
nsIPrincipal **prinOut,
|
||||
PRBool *forceWriteOnlyOut)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
nsCOMPtr<nsINode> node = do_QueryInterface(imgElt);
|
||||
|
||||
/* If it's a Canvas, grab its internal surface as necessary */
|
||||
nsCOMPtr<nsICanvasElement> canvas = do_QueryInterface(imgElt);
|
||||
if (node && canvas) {
|
||||
PRUint32 w, h;
|
||||
rv = canvas->GetSize(&w, &h);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsRefPtr<gfxASurface> sourceSurface;
|
||||
|
||||
if (!forceCopy && canvas->CountContexts() == 1) {
|
||||
nsICanvasRenderingContextInternal *srcCanvas = canvas->GetContextAtIndex(0);
|
||||
rv = srcCanvas->GetThebesSurface(getter_AddRefs(sourceSurface));
|
||||
#ifndef WINCE
|
||||
// force a copy if we couldn't get the surface, or if it's
|
||||
// the same as what we have
|
||||
if (sourceSurface == mSurface || NS_FAILED(rv))
|
||||
#else
|
||||
// force a copy if we couldn't get the surface
|
||||
if (NS_FAILED(rv))
|
||||
#endif
|
||||
sourceSurface = nsnull;
|
||||
}
|
||||
|
||||
if (sourceSurface == nsnull) {
|
||||
nsRefPtr<gfxASurface> surf =
|
||||
gfxPlatform::GetPlatform()->CreateOffscreenSurface
|
||||
(gfxIntSize(w, h), gfxASurface::ImageFormatARGB32);
|
||||
nsRefPtr<gfxContext> ctx = new gfxContext(surf);
|
||||
rv = canvas->RenderContexts(ctx, gfxPattern::FILTER_NEAREST);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
sourceSurface = surf;
|
||||
}
|
||||
|
||||
*aSurface = sourceSurface.forget().get();
|
||||
*widthOut = w;
|
||||
*heightOut = h;
|
||||
|
||||
NS_ADDREF(*prinOut = node->NodePrincipal());
|
||||
*forceWriteOnlyOut = canvas->IsWriteOnly();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#ifdef MOZ_MEDIA
|
||||
/* Maybe it's <video>? */
|
||||
nsCOMPtr<nsIDOMHTMLVideoElement> ve = do_QueryInterface(imgElt);
|
||||
if (node && ve) {
|
||||
nsHTMLVideoElement *video = static_cast<nsHTMLVideoElement*>(ve.get());
|
||||
|
||||
/* If it doesn't have a principal, just bail */
|
||||
nsCOMPtr<nsIPrincipal> principal = video->GetCurrentPrincipal();
|
||||
if (!principal)
|
||||
return NS_ERROR_DOM_SECURITY_ERR;
|
||||
|
||||
PRUint32 videoWidth, videoHeight;
|
||||
rv = video->GetVideoWidth(&videoWidth);
|
||||
rv |= video->GetVideoHeight(&videoHeight);
|
||||
if (NS_FAILED(rv))
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
nsRefPtr<gfxASurface> surf =
|
||||
gfxPlatform::GetPlatform()->CreateOffscreenSurface
|
||||
(gfxIntSize(videoWidth, videoHeight), gfxASurface::ImageFormatARGB32);
|
||||
nsRefPtr<gfxContext> ctx = new gfxContext(surf);
|
||||
|
||||
ctx->SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
|
||||
video->Paint(ctx, gfxPattern::FILTER_NEAREST, gfxRect(0, 0, videoWidth, videoHeight));
|
||||
|
||||
*aSurface = surf.forget().get();
|
||||
*widthOut = videoWidth;
|
||||
*heightOut = videoHeight;
|
||||
|
||||
*prinOut = principal.forget().get();
|
||||
*forceWriteOnlyOut = PR_FALSE;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Finally, check if it's a normal image */
|
||||
nsCOMPtr<imgIContainer> imgContainer;
|
||||
nsCOMPtr<nsIImageLoadingContent> imageLoader = do_QueryInterface(imgElt);
|
||||
|
||||
if (!imageLoader)
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
nsCOMPtr<imgIRequest> imgRequest;
|
||||
rv = imageLoader->GetRequest(nsIImageLoadingContent::CURRENT_REQUEST,
|
||||
getter_AddRefs(imgRequest));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (!imgRequest)
|
||||
// XXX ERRMSG we need to report an error to developers here! (bug 329026)
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
PRUint32 status;
|
||||
imgRequest->GetImageStatus(&status);
|
||||
if ((status & imgIRequest::STATUS_LOAD_COMPLETE) == 0)
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
// In case of data: URIs, we want to ignore principals;
|
||||
// they should have the originating content's principal,
|
||||
// but that's broken at the moment in imgLib.
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
rv = imgRequest->GetURI(getter_AddRefs(uri));
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_SECURITY_ERR);
|
||||
|
||||
PRBool isDataURI = PR_FALSE;
|
||||
rv = uri->SchemeIs("data", &isDataURI);
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_SECURITY_ERR);
|
||||
|
||||
// Data URIs are always OK; set the principal
|
||||
// to null to indicate that.
|
||||
if (isDataURI) {
|
||||
*prinOut = nsnull;
|
||||
} else {
|
||||
rv = imgRequest->GetImagePrincipal(prinOut);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
NS_ENSURE_TRUE(*prinOut, NS_ERROR_DOM_SECURITY_ERR);
|
||||
}
|
||||
|
||||
*forceWriteOnlyOut = PR_FALSE;
|
||||
|
||||
rv = imgRequest->GetImage(getter_AddRefs(imgContainer));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!imgContainer)
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
nsCOMPtr<gfxIImageFrame> frame;
|
||||
rv = imgContainer->GetCurrentFrame(getter_AddRefs(frame));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIImage> img(do_GetInterface(frame));
|
||||
|
||||
PRInt32 imgWidth, imgHeight;
|
||||
rv = frame->GetWidth(&imgWidth);
|
||||
rv |= frame->GetHeight(&imgHeight);
|
||||
if (NS_FAILED(rv))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
if (widthOut)
|
||||
*widthOut = imgWidth;
|
||||
if (heightOut)
|
||||
*heightOut = imgHeight;
|
||||
|
||||
nsRefPtr<gfxPattern> gfxpattern;
|
||||
img->GetPattern(getter_AddRefs(gfxpattern));
|
||||
nsRefPtr<gfxASurface> gfxsurf = gfxpattern->GetSurface();
|
||||
|
||||
if (!gfxsurf) {
|
||||
gfxsurf = new gfxImageSurface (gfxIntSize(imgWidth, imgHeight), gfxASurface::ImageFormatARGB32);
|
||||
nsRefPtr<gfxContext> ctx = new gfxContext(gfxsurf);
|
||||
|
||||
ctx->SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
ctx->SetPattern(gfxpattern);
|
||||
ctx->Paint();
|
||||
}
|
||||
|
||||
*aSurface = gfxsurf.forget().get();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* Check that the rect [x,y,w,h] is a valid subrect of [0,0,realWidth,realHeight]
|
||||
* without overflowing any integers and the like.
|
||||
*/
|
||||
|
@ -3566,7 +3369,6 @@ nsCanvasRenderingContext2D::DrawWindow(nsIDOMWindow* aWindow, float aX, float aY
|
|||
// we're drawing; aX and aY are drawn to 0,0 in current user
|
||||
// space.
|
||||
gfxRect damageRect = mThebes->UserToDevice(gfxRect(0, 0, aW, aH));
|
||||
damageRect.RoundOut();
|
||||
|
||||
Redraw(damageRect);
|
||||
|
||||
|
@ -3614,7 +3416,7 @@ nsCanvasRenderingContext2D::GetImageData()
|
|||
if (!JS_ConvertArguments (ctx, argc, argv, "jjjj", &x, &y, &w, &h))
|
||||
return NS_ERROR_DOM_SYNTAX_ERR;
|
||||
|
||||
if (!CheckSaneSubrectSize (x, y, w, h, mWidth, mHeight))
|
||||
if (!CanvasUtils::CheckSaneSubrectSize (x, y, w, h, mWidth, mHeight))
|
||||
return NS_ERROR_DOM_SYNTAX_ERR;
|
||||
|
||||
nsAutoArrayPtr<PRUint8> surfaceData (new (std::nothrow) PRUint8[w * h * 4]);
|
||||
|
@ -3802,7 +3604,7 @@ nsCanvasRenderingContext2D::PutImageData()
|
|||
return NS_ERROR_DOM_SYNTAX_ERR;
|
||||
dataArray = JSVAL_TO_OBJECT(v);
|
||||
|
||||
if (!CheckSaneSubrectSize (x, y, w, h, mWidth, mHeight))
|
||||
if (!CanvasUtils::CheckSaneSubrectSize (x, y, w, h, mWidth, mHeight))
|
||||
return NS_ERROR_DOM_SYNTAX_ERR;
|
||||
|
||||
jsuint arrayLen;
|
||||
|
@ -3908,6 +3710,9 @@ nsCanvasRenderingContext2D::PutImageData()
|
|||
gfxContextPathAutoSaveRestore pathSR(mThebes);
|
||||
gfxContextAutoSaveRestore autoSR(mThebes);
|
||||
|
||||
// ignore clipping region, as per spec
|
||||
mThebes->ResetClip();
|
||||
|
||||
mThebes->IdentityMatrix();
|
||||
mThebes->Translate(gfxPoint(x, y));
|
||||
mThebes->NewPath();
|
||||
|
@ -3969,7 +3774,7 @@ nsCanvasRenderingContext2D::CreateImageData()
|
|||
|
||||
// check for overflow when calculating len
|
||||
PRUint32 len0 = w * h;
|
||||
if (len0 / w != h)
|
||||
if (len0 / w != (PRUint32) h)
|
||||
return NS_ERROR_DOM_INDEX_SIZE_ERR;
|
||||
PRUint32 len = len0 * 4;
|
||||
if (len / 4 != len0)
|
||||
|
|
|
@ -48,7 +48,7 @@ ctx.rect(0, 0, 50, 50);
|
|||
ctx.clip();
|
||||
ctx.putImageData(imgdata, 0, 0);
|
||||
isPixel(ctx, 25,25, 0,255,0,255, "25,25", "0,255,0,255", 2);
|
||||
todo_isPixel(ctx, 75,25, 0,255,0,255, "75,25", "0,255,0,255", 2);
|
||||
isPixel(ctx, 75,25, 0,255,0,255, "75,25", "0,255,0,255", 2);
|
||||
|
||||
SimpleTest.finish();
|
||||
|
||||
|
|
|
@ -46,13 +46,14 @@ class nsPresContext;
|
|||
* Event listener manager interface.
|
||||
*/
|
||||
#define NS_IPRIVATEDOMEVENT_IID \
|
||||
{0x5b3543d3, 0x84ed, 0x4b59, \
|
||||
{0x95, 0xca, 0xa4, 0x21, 0xf2, 0x59, 0x22, 0x22}}
|
||||
{ 0x1da4c501, 0xe87e, 0x49b4, \
|
||||
{ 0xb0, 0x49, 0xdf, 0x9f, 0xc3, 0x6b, 0x56, 0xd4 } }
|
||||
|
||||
class nsIDOMEventTarget;
|
||||
class nsIDOMEvent;
|
||||
class nsEvent;
|
||||
class nsCommandEvent;
|
||||
class nsRegion;
|
||||
|
||||
class nsIPrivateDOMEvent : public nsISupports
|
||||
{
|
||||
|
@ -61,11 +62,8 @@ public:
|
|||
|
||||
NS_IMETHOD DuplicatePrivateData() = 0;
|
||||
NS_IMETHOD SetTarget(nsIDOMEventTarget* aTarget) = 0;
|
||||
NS_IMETHOD SetCurrentTarget(nsIDOMEventTarget* aTarget) = 0;
|
||||
NS_IMETHOD SetOriginalTarget(nsIDOMEventTarget* aTarget) = 0;
|
||||
NS_IMETHOD_(PRBool) IsDispatchStopped() = 0;
|
||||
NS_IMETHOD_(nsEvent*) GetInternalNSEvent() = 0;
|
||||
NS_IMETHOD_(PRBool) HasOriginalTarget() = 0;
|
||||
NS_IMETHOD SetTrusted(PRBool aTrusted) = 0;
|
||||
};
|
||||
|
||||
|
@ -92,9 +90,9 @@ NS_NewDOMPopupBlockedEvent(nsIDOMEvent** aResult, nsPresContext* aPresContext, n
|
|||
nsresult
|
||||
NS_NewDOMTextEvent(nsIDOMEvent** aResult, nsPresContext* aPresContext, class nsTextEvent* aEvent);
|
||||
nsresult
|
||||
NS_NewDOMBeforeUnloadEvent(nsIDOMEvent** aResult, nsPresContext* aPresContext, class nsBeforePageUnloadEvent* aEvent);
|
||||
NS_NewDOMBeforeUnloadEvent(nsIDOMEvent** aResult, nsPresContext* aPresContext, nsEvent* aEvent);
|
||||
nsresult
|
||||
NS_NewDOMPageTransitionEvent(nsIDOMEvent** aResult, nsPresContext* aPresContext, class nsPageTransitionEvent* aEvent);
|
||||
NS_NewDOMPageTransitionEvent(nsIDOMEvent** aResult, nsPresContext* aPresContext, nsEvent* aEvent);
|
||||
#ifdef MOZ_SVG
|
||||
nsresult
|
||||
NS_NewDOMSVGEvent(nsIDOMEvent** aResult, nsPresContext* aPresContext, class nsEvent* aEvent);
|
||||
|
@ -110,7 +108,11 @@ NS_NewDOMMessageEvent(nsIDOMEvent** aInstancePtrResult, nsPresContext* aPresCont
|
|||
nsresult
|
||||
NS_NewDOMProgressEvent(nsIDOMEvent** aInstancePtrResult, nsPresContext* aPresContext, class nsEvent* aEvent);
|
||||
nsresult
|
||||
NS_NewDOMNotifyPaintEvent(nsIDOMEvent** aResult, nsPresContext* aPresContext, class nsNotifyPaintEvent* aEvent);
|
||||
NS_NewDOMNotifyPaintEvent(nsIDOMEvent** aResult, nsPresContext* aPresContext,
|
||||
nsEvent* aEvent,
|
||||
PRUint32 aEventType = 0,
|
||||
const nsRegion* aSameOriginRegion = nsnull,
|
||||
const nsRegion* aCrossDocRegion = nsnull);
|
||||
nsresult
|
||||
NS_NewDOMSimpleGestureEvent(nsIDOMEvent** aInstancePtrResult, nsPresContext* aPresContext, class nsSimpleGestureEvent* aEvent);
|
||||
#endif // nsIPrivateDOMEvent_h__
|
||||
|
|
|
@ -50,10 +50,10 @@ class nsIDOMEventListener;
|
|||
class nsIDOMEventGroup;
|
||||
class nsIScriptContext;
|
||||
|
||||
// 25982813-af2e-4ab6-b512-e6c6ada6d0ec
|
||||
// e6579895-a23c-4afc-872a-d53da71def5d
|
||||
#define NS_PIDOMEVENTTARGET_IID \
|
||||
{ 0x358f2990, 0x5107, 0x49ba, \
|
||||
{ 0x88, 0x94, 0x14, 0x34, 0x86, 0xd5, 0x99, 0x85 } }
|
||||
{ 0xe6579895, 0xa23c, 0x4afc, \
|
||||
{ 0x87, 0x2a, 0xd5, 0x3d, 0xa7, 0x1d, 0xef, 0x5d } }
|
||||
|
||||
class nsPIDOMEventTarget : public nsISupports
|
||||
{
|
||||
|
@ -137,12 +137,10 @@ public:
|
|||
/**
|
||||
* Get the event listener manager, the guy you talk to to register for events
|
||||
* on this node.
|
||||
* @param aCreateIfNotFound If PR_FALSE, returns a listener manager only if
|
||||
* one already exists. [IN]
|
||||
* @param aResult The event listener manager [OUT]
|
||||
* @param aMayCreate If PR_FALSE, returns a listener manager only if
|
||||
* one already exists.
|
||||
*/
|
||||
virtual nsresult GetListenerManager(PRBool aCreateIfNotFound,
|
||||
nsIEventListenerManager** aResult) = 0;
|
||||
virtual nsIEventListenerManager* GetListenerManager(PRBool aMayCreate) = 0;
|
||||
|
||||
/**
|
||||
* Add an event listener for nsIID.
|
||||
|
|
|
@ -39,33 +39,6 @@
|
|||
#include "nsDOMBeforeUnloadEvent.h"
|
||||
#include "nsContentUtils.h"
|
||||
|
||||
nsDOMBeforeUnloadEvent::nsDOMBeforeUnloadEvent(nsPresContext* aPresContext,
|
||||
nsBeforePageUnloadEvent* aEvent)
|
||||
: nsDOMEvent(aPresContext, aEvent ? aEvent :
|
||||
new nsBeforePageUnloadEvent(PR_FALSE,
|
||||
NS_BEFORE_PAGE_UNLOAD_EVENT))
|
||||
{
|
||||
NS_ASSERTION(mEvent->eventStructType == NS_BEFORE_PAGE_UNLOAD_EVENT,
|
||||
"event type mismatch");
|
||||
|
||||
if (aEvent) {
|
||||
mEventIsInternal = PR_FALSE;
|
||||
}
|
||||
else {
|
||||
mEventIsInternal = PR_TRUE;
|
||||
mEvent->time = PR_Now();
|
||||
}
|
||||
}
|
||||
|
||||
nsDOMBeforeUnloadEvent::~nsDOMBeforeUnloadEvent()
|
||||
{
|
||||
if (mEventIsInternal &&
|
||||
mEvent->eventStructType == NS_BEFORE_PAGE_UNLOAD_EVENT) {
|
||||
delete static_cast<nsBeforePageUnloadEvent*>(mEvent);
|
||||
mEvent = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(nsDOMBeforeUnloadEvent, nsDOMEvent)
|
||||
NS_IMPL_RELEASE_INHERITED(nsDOMBeforeUnloadEvent, nsDOMEvent)
|
||||
|
||||
|
@ -77,22 +50,20 @@ NS_INTERFACE_MAP_END_INHERITING(nsDOMEvent)
|
|||
NS_IMETHODIMP
|
||||
nsDOMBeforeUnloadEvent::SetReturnValue(const nsAString& aReturnValue)
|
||||
{
|
||||
((nsBeforePageUnloadEvent *)mEvent)->text = aReturnValue;
|
||||
|
||||
mText = aReturnValue;
|
||||
return NS_OK; // Don't throw an exception
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMBeforeUnloadEvent::GetReturnValue(nsAString& aReturnValue)
|
||||
{
|
||||
aReturnValue = ((nsBeforePageUnloadEvent *)mEvent)->text;
|
||||
|
||||
aReturnValue = mText;
|
||||
return NS_OK; // Don't throw an exception
|
||||
}
|
||||
|
||||
nsresult NS_NewDOMBeforeUnloadEvent(nsIDOMEvent** aInstancePtrResult,
|
||||
nsPresContext* aPresContext,
|
||||
nsBeforePageUnloadEvent *aEvent)
|
||||
nsEvent *aEvent)
|
||||
{
|
||||
nsDOMBeforeUnloadEvent* it =
|
||||
new nsDOMBeforeUnloadEvent(aPresContext, aEvent);
|
||||
|
|
|
@ -46,9 +46,8 @@ class nsDOMBeforeUnloadEvent : public nsIDOMBeforeUnloadEvent,
|
|||
public nsDOMEvent
|
||||
{
|
||||
public:
|
||||
nsDOMBeforeUnloadEvent(nsPresContext* aPresContext,
|
||||
nsBeforePageUnloadEvent* aEvent);
|
||||
virtual ~nsDOMBeforeUnloadEvent();
|
||||
nsDOMBeforeUnloadEvent(nsPresContext* aPresContext, nsEvent* aEvent)
|
||||
: nsDOMEvent(aPresContext, aEvent) {}
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
|
@ -57,6 +56,8 @@ public:
|
|||
|
||||
// nsIDOMBeforeUnloadEvent Interface
|
||||
NS_DECL_NSIDOMBEFOREUNLOADEVENT
|
||||
protected:
|
||||
nsString mText;
|
||||
};
|
||||
|
||||
#endif // nsDOMBeforeUnloadEvent_h__
|
||||
|
|
|
@ -74,6 +74,7 @@ public:
|
|||
|
||||
friend class nsDOMDragEvent;
|
||||
friend class nsEventStateManager;
|
||||
friend class nsContentUtils;
|
||||
|
||||
protected:
|
||||
|
||||
|
|
|
@ -118,6 +118,10 @@ nsDOMDragEvent::InitDragEventNS(const nsAString & aNamespaceURIArg,
|
|||
NS_IMETHODIMP
|
||||
nsDOMDragEvent::GetDataTransfer(nsIDOMDataTransfer** aDataTransfer)
|
||||
{
|
||||
// the dataTransfer field of the event caches the DataTransfer associated
|
||||
// with the drag. It is initialized when an attempt is made to retrieve it
|
||||
// rather that when the event is created to avoid duplicating the data when
|
||||
// no listener ever uses it.
|
||||
*aDataTransfer = nsnull;
|
||||
|
||||
if (!mEvent || mEvent->eventStructType != NS_DRAG_EVENT) {
|
||||
|
@ -125,125 +129,17 @@ nsDOMDragEvent::GetDataTransfer(nsIDOMDataTransfer** aDataTransfer)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
// the dataTransfer field of the event caches the DataTransfer associated
|
||||
// with the drag. It is initialized when an attempt is made to retrieve it
|
||||
// rather that when the event is created to avoid duplicating the data when
|
||||
// no listener ever uses it.
|
||||
nsDragEvent* dragEvent = static_cast<nsDragEvent*>(mEvent);
|
||||
if (dragEvent->dataTransfer) {
|
||||
CallQueryInterface(dragEvent->dataTransfer, aDataTransfer);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// for synthetic events, just use the supplied data transfer object
|
||||
if (mEventIsInternal) {
|
||||
NS_IF_ADDREF(*aDataTransfer = dragEvent->dataTransfer);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// For draggesture and dragstart events, the data transfer object is
|
||||
// created before the event fires, so it should already be set. For other
|
||||
// drag events, get the object from the drag session.
|
||||
NS_ASSERTION(mEvent->message != NS_DRAGDROP_GESTURE &&
|
||||
mEvent->message != NS_DRAGDROP_START,
|
||||
"draggesture event created without a dataTransfer");
|
||||
|
||||
nsCOMPtr<nsIDragSession> dragSession = nsContentUtils::GetDragSession();
|
||||
NS_ENSURE_TRUE(dragSession, NS_OK); // no drag in progress
|
||||
|
||||
nsCOMPtr<nsIDOMDataTransfer> initialDataTransfer;
|
||||
dragSession->GetDataTransfer(getter_AddRefs(initialDataTransfer));
|
||||
if (!initialDataTransfer) {
|
||||
// A dataTransfer won't exist when a drag was started by some other
|
||||
// means, for instance calling the drag service directly, or a drag
|
||||
// from another application. In either case, a new dataTransfer should
|
||||
// be created that reflects the data. Pass true to the constructor for
|
||||
// the aIsExternal argument, so that only system access is allowed.
|
||||
PRUint32 action = 0;
|
||||
dragSession->GetDragAction(&action);
|
||||
initialDataTransfer =
|
||||
new nsDOMDataTransfer(mEvent->message, action);
|
||||
NS_ENSURE_TRUE(initialDataTransfer, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
// now set it in the drag session so we don't need to create it again
|
||||
dragSession->SetDataTransfer(initialDataTransfer);
|
||||
}
|
||||
|
||||
// each event should use a clone of the original dataTransfer.
|
||||
nsCOMPtr<nsIDOMNSDataTransfer> initialDataTransferNS =
|
||||
do_QueryInterface(initialDataTransfer);
|
||||
NS_ENSURE_TRUE(initialDataTransferNS, NS_ERROR_FAILURE);
|
||||
initialDataTransferNS->Clone(mEvent->message, dragEvent->userCancelled,
|
||||
getter_AddRefs(dragEvent->dataTransfer));
|
||||
NS_ENSURE_TRUE(dragEvent->dataTransfer, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
// for the dragenter and dragover events, initialize the drop effect
|
||||
// from the drop action, which platform specific widget code sets before
|
||||
// the event is fired based on the keyboard state.
|
||||
if (mEvent->message == NS_DRAGDROP_ENTER ||
|
||||
mEvent->message == NS_DRAGDROP_OVER) {
|
||||
nsCOMPtr<nsIDOMNSDataTransfer> newDataTransfer =
|
||||
do_QueryInterface(dragEvent->dataTransfer);
|
||||
NS_ENSURE_TRUE(newDataTransfer, NS_ERROR_FAILURE);
|
||||
|
||||
PRUint32 action, effectAllowed;
|
||||
dragSession->GetDragAction(&action);
|
||||
newDataTransfer->GetEffectAllowedInt(&effectAllowed);
|
||||
newDataTransfer->SetDropEffectInt(FilterDropEffect(action, effectAllowed));
|
||||
}
|
||||
else if (mEvent->message == NS_DRAGDROP_DROP ||
|
||||
mEvent->message == NS_DRAGDROP_DRAGDROP ||
|
||||
mEvent->message == NS_DRAGDROP_END) {
|
||||
// For the drop and dragend events, set the drop effect based on the
|
||||
// last value that the dropEffect had. This will have been set in
|
||||
// nsEventStateManager::PostHandleEvent for the last dragenter or
|
||||
// dragover event.
|
||||
nsCOMPtr<nsIDOMNSDataTransfer> newDataTransfer =
|
||||
do_QueryInterface(dragEvent->dataTransfer);
|
||||
NS_ENSURE_TRUE(newDataTransfer, NS_ERROR_FAILURE);
|
||||
|
||||
PRUint32 dropEffect;
|
||||
initialDataTransferNS->GetDropEffectInt(&dropEffect);
|
||||
newDataTransfer->SetDropEffectInt(dropEffect);
|
||||
// for synthetic events, just use the supplied data transfer object even if null
|
||||
if (!mEventIsInternal) {
|
||||
nsresult rv = nsContentUtils::SetDataTransferInEvent(dragEvent);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
NS_IF_ADDREF(*aDataTransfer = dragEvent->dataTransfer);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// static
|
||||
PRUint32
|
||||
nsDOMDragEvent::FilterDropEffect(PRUint32 aAction, PRUint32 aEffectAllowed)
|
||||
{
|
||||
// It is possible for the drag action to include more than one action, but
|
||||
// the widget code which sets the action from the keyboard state should only
|
||||
// be including one. If multiple actions were set, we just consider them in
|
||||
// the following order:
|
||||
// copy, link, move
|
||||
if (aAction & nsIDragService::DRAGDROP_ACTION_COPY)
|
||||
aAction = nsIDragService::DRAGDROP_ACTION_COPY;
|
||||
else if (aAction & nsIDragService::DRAGDROP_ACTION_LINK)
|
||||
aAction = nsIDragService::DRAGDROP_ACTION_LINK;
|
||||
else if (aAction & nsIDragService::DRAGDROP_ACTION_MOVE)
|
||||
aAction = nsIDragService::DRAGDROP_ACTION_MOVE;
|
||||
|
||||
// Filter the action based on the effectAllowed. If the effectAllowed
|
||||
// doesn't include the action, then that action cannot be done, so adjust
|
||||
// the action to something that is allowed. For a copy, adjust to move or
|
||||
// link. For a move, adjust to copy or link. For a link, adjust to move or
|
||||
// link. Otherwise, use none.
|
||||
if (aAction & aEffectAllowed ||
|
||||
aEffectAllowed == nsIDragService::DRAGDROP_ACTION_UNINITIALIZED)
|
||||
return aAction;
|
||||
if (aEffectAllowed & nsIDragService::DRAGDROP_ACTION_MOVE)
|
||||
return nsIDragService::DRAGDROP_ACTION_MOVE;
|
||||
if (aEffectAllowed & nsIDragService::DRAGDROP_ACTION_COPY)
|
||||
return nsIDragService::DRAGDROP_ACTION_COPY;
|
||||
if (aEffectAllowed & nsIDragService::DRAGDROP_ACTION_LINK)
|
||||
return nsIDragService::DRAGDROP_ACTION_LINK;
|
||||
return nsIDragService::DRAGDROP_ACTION_NONE;
|
||||
}
|
||||
|
||||
nsresult NS_NewDOMDragEvent(nsIDOMEvent** aInstancePtrResult,
|
||||
nsPresContext* aPresContext,
|
||||
nsDragEvent *aEvent)
|
||||
|
|
|
@ -57,9 +57,6 @@ public:
|
|||
NS_DECL_NSIDOMDRAGEVENT
|
||||
|
||||
NS_FORWARD_TO_NSDOMMOUSEEVENT
|
||||
|
||||
// filters the action to fit within the effects allowed and returns it.
|
||||
static PRUint32 FilterDropEffect(PRUint32 aAction, PRUint32 aEffectAllowed);
|
||||
};
|
||||
|
||||
nsresult NS_NewDOMDragEvent(nsIDOMEvent** aInstancePtrResult,
|
||||
|
|
|
@ -342,12 +342,6 @@ nsDOMEvent::GetOriginalTarget(nsIDOMEventTarget** aOriginalTarget)
|
|||
return GetTarget(aOriginalTarget);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(PRBool)
|
||||
nsDOMEvent::HasOriginalTarget()
|
||||
{
|
||||
return !!mEvent->originalTarget;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMEvent::SetTrusted(PRBool aTrusted)
|
||||
{
|
||||
|
@ -532,6 +526,8 @@ nsDOMEvent::SetEventType(const nsAString& aEventTypeArg)
|
|||
else if (atom == nsGkAtoms::oncompositionend)
|
||||
mEvent->message = NS_COMPOSITION_END;
|
||||
} else if (mEvent->eventStructType == NS_EVENT) {
|
||||
if (atom == nsGkAtoms::onMozAfterPaint)
|
||||
mEvent->message = NS_AFTERPAINT;
|
||||
if (atom == nsGkAtoms::onfocus)
|
||||
mEvent->message = NS_FOCUS_CONTENT;
|
||||
else if (atom == nsGkAtoms::onblur)
|
||||
|
@ -548,6 +544,8 @@ nsDOMEvent::SetEventType(const nsAString& aEventTypeArg)
|
|||
mEvent->message = NS_LOAD;
|
||||
else if (atom == nsGkAtoms::onunload)
|
||||
mEvent->message = NS_PAGE_UNLOAD;
|
||||
else if (atom == nsGkAtoms::onbeforeunload)
|
||||
mEvent->message = NS_BEFORE_PAGE_UNLOAD;
|
||||
else if (atom == nsGkAtoms::onabort)
|
||||
mEvent->message = NS_IMAGE_ABORT;
|
||||
else if (atom == nsGkAtoms::onerror)
|
||||
|
@ -562,6 +560,10 @@ nsDOMEvent::SetEventType(const nsAString& aEventTypeArg)
|
|||
mEvent->message = NS_CUT;
|
||||
else if (atom == nsGkAtoms::onpaste)
|
||||
mEvent->message = NS_PASTE;
|
||||
else if (atom == nsGkAtoms::onpageshow)
|
||||
mEvent->message = NS_PAGE_SHOW;
|
||||
else if (atom == nsGkAtoms::onpagehide)
|
||||
mEvent->message = NS_PAGE_HIDE;
|
||||
} else if (mEvent->eventStructType == NS_MUTATION_EVENT) {
|
||||
if (atom == nsGkAtoms::onDOMAttrModified)
|
||||
mEvent->message = NS_MUTATION_ATTRMODIFIED;
|
||||
|
@ -586,11 +588,6 @@ nsDOMEvent::SetEventType(const nsAString& aEventTypeArg)
|
|||
mEvent->message = NS_UI_FOCUSOUT;
|
||||
else if (atom == nsGkAtoms::oninput)
|
||||
mEvent->message = NS_FORM_INPUT;
|
||||
} else if (mEvent->eventStructType == NS_PAGETRANSITION_EVENT) {
|
||||
if (atom == nsGkAtoms::onpageshow)
|
||||
mEvent->message = NS_PAGE_SHOW;
|
||||
else if (atom == nsGkAtoms::onpagehide)
|
||||
mEvent->message = NS_PAGE_HIDE;
|
||||
} else if (mEvent->eventStructType == NS_XUL_COMMAND_EVENT) {
|
||||
if (atom == nsGkAtoms::oncommand)
|
||||
mEvent->message = NS_XUL_COMMAND;
|
||||
|
@ -665,10 +662,6 @@ nsDOMEvent::SetEventType(const nsAString& aEventTypeArg)
|
|||
mEvent->message = NS_MEDIA_ERROR;
|
||||
}
|
||||
#endif // MOZ_MEDIA
|
||||
else if (mEvent->eventStructType == NS_NOTIFYPAINT_EVENT) {
|
||||
if (atom == nsGkAtoms::onMozAfterPaint)
|
||||
mEvent->message = NS_AFTERPAINT;
|
||||
}
|
||||
else if (mEvent->eventStructType == NS_SIMPLE_GESTURE_EVENT) {
|
||||
if (atom == nsGkAtoms::onMozSwipeGesture)
|
||||
mEvent->message = NS_SIMPLE_GESTURE_SWIPE;
|
||||
|
@ -943,27 +936,12 @@ NS_METHOD nsDOMEvent::DuplicatePrivateData()
|
|||
NS_ENSURE_TRUE(newEvent, NS_ERROR_OUT_OF_MEMORY);
|
||||
break;
|
||||
}
|
||||
case NS_BEFORE_PAGE_UNLOAD_EVENT:
|
||||
{
|
||||
newEvent = new nsBeforePageUnloadEvent(PR_FALSE, msg);
|
||||
NS_ENSURE_TRUE(newEvent, NS_ERROR_OUT_OF_MEMORY);
|
||||
static_cast<nsBeforePageUnloadEvent*>(newEvent)->text =
|
||||
static_cast<nsBeforePageUnloadEvent*>(mEvent)->text;
|
||||
break;
|
||||
}
|
||||
case NS_UI_EVENT:
|
||||
{
|
||||
newEvent = new nsUIEvent(PR_FALSE, msg,
|
||||
static_cast<nsUIEvent*>(mEvent)->detail);
|
||||
break;
|
||||
}
|
||||
case NS_PAGETRANSITION_EVENT:
|
||||
{
|
||||
newEvent =
|
||||
new nsPageTransitionEvent(PR_FALSE, msg,
|
||||
((nsPageTransitionEvent*) mEvent)->persisted);
|
||||
break;
|
||||
}
|
||||
#ifdef MOZ_SVG
|
||||
case NS_SVG_EVENT:
|
||||
{
|
||||
|
@ -990,14 +968,6 @@ NS_METHOD nsDOMEvent::DuplicatePrivateData()
|
|||
static_cast<nsXULCommandEvent*>(mEvent)->sourceEvent;
|
||||
break;
|
||||
}
|
||||
case NS_NOTIFYPAINT_EVENT:
|
||||
{
|
||||
nsNotifyPaintEvent* event = static_cast<nsNotifyPaintEvent*>(mEvent);
|
||||
newEvent =
|
||||
new nsNotifyPaintEvent(PR_FALSE, msg,
|
||||
event->sameDocRegion, event->crossDocRegion);
|
||||
break;
|
||||
}
|
||||
case NS_SIMPLE_GESTURE_EVENT:
|
||||
{
|
||||
nsSimpleGestureEvent* oldSimpleGestureEvent = static_cast<nsSimpleGestureEvent*>(mEvent);
|
||||
|
@ -1059,36 +1029,6 @@ NS_METHOD nsDOMEvent::SetTarget(nsIDOMEventTarget* aTarget)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_METHOD nsDOMEvent::SetCurrentTarget(nsIDOMEventTarget* aCurrentTarget)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
{
|
||||
nsCOMPtr<nsPIDOMWindow> win = do_QueryInterface(aCurrentTarget);
|
||||
|
||||
NS_ASSERTION(!win || !win->IsInnerWindow(),
|
||||
"Uh, inner window set as event target!");
|
||||
}
|
||||
#endif
|
||||
|
||||
mEvent->currentTarget = aCurrentTarget;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_METHOD nsDOMEvent::SetOriginalTarget(nsIDOMEventTarget* aOriginalTarget)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
{
|
||||
nsCOMPtr<nsPIDOMWindow> win = do_QueryInterface(aOriginalTarget);
|
||||
|
||||
NS_ASSERTION(!win || !win->IsInnerWindow(),
|
||||
"Uh, inner window set as event target!");
|
||||
}
|
||||
#endif
|
||||
|
||||
mEvent->originalTarget = aOriginalTarget;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(PRBool)
|
||||
nsDOMEvent::IsDispatchStopped()
|
||||
{
|
||||
|
@ -1557,6 +1497,14 @@ nsDOMEvent::ReportWrongPropertyAccessWarning(const char* aPropertyName)
|
|||
"DOM Events");
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMEvent::GetPreventDefault(PRBool* aReturn)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aReturn);
|
||||
*aReturn = mEvent && (mEvent->flags & NS_EVENT_FLAG_NO_DEFAULT);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult NS_NewDOMEvent(nsIDOMEvent** aInstancePtrResult,
|
||||
nsPresContext* aPresContext,
|
||||
nsEvent *aEvent)
|
||||
|
|
|
@ -188,11 +188,8 @@ public:
|
|||
// nsIPrivateDOMEvent interface
|
||||
NS_IMETHOD DuplicatePrivateData();
|
||||
NS_IMETHOD SetTarget(nsIDOMEventTarget* aTarget);
|
||||
NS_IMETHOD SetCurrentTarget(nsIDOMEventTarget* aCurrentTarget);
|
||||
NS_IMETHOD SetOriginalTarget(nsIDOMEventTarget* aOriginalTarget);
|
||||
NS_IMETHOD_(PRBool) IsDispatchStopped();
|
||||
NS_IMETHOD_(nsEvent*) GetInternalNSEvent();
|
||||
NS_IMETHOD_(PRBool) HasOriginalTarget();
|
||||
NS_IMETHOD SetTrusted(PRBool aTrusted);
|
||||
|
||||
static PopupControlState GetEventPopupControlState(nsEvent *aEvent);
|
||||
|
|
|
@ -111,8 +111,7 @@ nsDOMEventTargetHelper::RemoveEventListener(const nsAString& aType,
|
|||
nsIDOMEventListener* aListener,
|
||||
PRBool aUseCapture)
|
||||
{
|
||||
nsCOMPtr<nsIEventListenerManager> elm;
|
||||
GetListenerManager(PR_FALSE, getter_AddRefs(elm));
|
||||
nsIEventListenerManager* elm = GetListenerManager(PR_FALSE);
|
||||
if (elm) {
|
||||
PRInt32 flags = aUseCapture ? NS_EVENT_FLAG_CAPTURE : NS_EVENT_FLAG_BUBBLE;
|
||||
elm->RemoveEventListenerByType(aListener, aType, flags, nsnull);
|
||||
|
@ -127,8 +126,7 @@ nsDOMEventTargetHelper::AddEventListener(const nsAString& aType,
|
|||
PRBool aUseCapture,
|
||||
PRBool aWantsUntrusted)
|
||||
{
|
||||
nsCOMPtr<nsIEventListenerManager> elm;
|
||||
GetListenerManager(PR_TRUE, getter_AddRefs(elm));
|
||||
nsIEventListenerManager* elm = GetListenerManager(PR_TRUE);
|
||||
NS_ENSURE_STATE(elm);
|
||||
PRInt32 flags = aUseCapture ? NS_EVENT_FLAG_CAPTURE : NS_EVENT_FLAG_BUBBLE;
|
||||
if (aWantsUntrusted) {
|
||||
|
@ -220,57 +218,46 @@ nsDOMEventTargetHelper::DispatchDOMEvent(nsEvent* aEvent,
|
|||
aEventStatus);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDOMEventTargetHelper::GetListenerManager(PRBool aCreateIfNotFound,
|
||||
nsIEventListenerManager** aResult)
|
||||
nsIEventListenerManager*
|
||||
nsDOMEventTargetHelper::GetListenerManager(PRBool aCreateIfNotFound)
|
||||
{
|
||||
if (!mListenerManager) {
|
||||
if (!aCreateIfNotFound) {
|
||||
*aResult = nsnull;
|
||||
return NS_OK;
|
||||
return nsnull;
|
||||
}
|
||||
nsresult rv = NS_NewEventListenerManager(getter_AddRefs(mListenerManager));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
NS_ENSURE_SUCCESS(rv, nsnull);
|
||||
mListenerManager->SetListenerTarget(static_cast<nsPIDOMEventTarget*>(this));
|
||||
}
|
||||
|
||||
NS_ADDREF(*aResult = mListenerManager);
|
||||
return NS_OK;
|
||||
return mListenerManager;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDOMEventTargetHelper::AddEventListenerByIID(nsIDOMEventListener *aListener,
|
||||
const nsIID& aIID)
|
||||
{
|
||||
nsCOMPtr<nsIEventListenerManager> elm;
|
||||
GetListenerManager(PR_TRUE, getter_AddRefs(elm));
|
||||
if (elm) {
|
||||
elm->AddEventListenerByIID(aListener, aIID, NS_EVENT_FLAG_BUBBLE);
|
||||
}
|
||||
return NS_OK;
|
||||
nsIEventListenerManager* elm = GetListenerManager(PR_TRUE);
|
||||
NS_ENSURE_STATE(elm);
|
||||
return elm->AddEventListenerByIID(aListener, aIID, NS_EVENT_FLAG_BUBBLE);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDOMEventTargetHelper::RemoveEventListenerByIID(nsIDOMEventListener *aListener,
|
||||
const nsIID& aIID)
|
||||
{
|
||||
nsCOMPtr<nsIEventListenerManager> elm;
|
||||
GetListenerManager(PR_FALSE, getter_AddRefs(elm));
|
||||
if (elm) {
|
||||
return elm->RemoveEventListenerByIID(aListener, aIID, NS_EVENT_FLAG_BUBBLE);
|
||||
}
|
||||
return NS_OK;
|
||||
nsIEventListenerManager* elm = GetListenerManager(PR_FALSE);
|
||||
return elm ?
|
||||
elm->RemoveEventListenerByIID(aListener, aIID, NS_EVENT_FLAG_BUBBLE) :
|
||||
NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDOMEventTargetHelper::GetSystemEventGroup(nsIDOMEventGroup** aGroup)
|
||||
{
|
||||
nsCOMPtr<nsIEventListenerManager> elm;
|
||||
nsresult rv = GetListenerManager(PR_TRUE, getter_AddRefs(elm));
|
||||
if (elm) {
|
||||
return elm->GetSystemEventGroupLM(aGroup);
|
||||
}
|
||||
return rv;
|
||||
nsIEventListenerManager* elm = GetListenerManager(PR_TRUE);
|
||||
NS_ENSURE_STATE(elm);
|
||||
return elm->GetSystemEventGroupLM(aGroup);
|
||||
}
|
||||
|
||||
nsIScriptContext*
|
||||
|
|
|
@ -85,8 +85,7 @@ public:
|
|||
virtual nsresult DispatchDOMEvent(nsEvent* aEvent, nsIDOMEvent* aDOMEvent,
|
||||
nsPresContext* aPresContext,
|
||||
nsEventStatus* aEventStatus);
|
||||
virtual nsresult GetListenerManager(PRBool aCreateIfNotFound,
|
||||
nsIEventListenerManager** aResult);
|
||||
virtual nsIEventListenerManager* GetListenerManager(PRBool aCreateIfNotFound);
|
||||
virtual nsresult AddEventListenerByIID(nsIDOMEventListener *aListener,
|
||||
const nsIID& aIID);
|
||||
virtual nsresult RemoveEventListenerByIID(nsIDOMEventListener *aListener,
|
||||
|
|
|
@ -41,27 +41,20 @@
|
|||
#include "nsClientRect.h"
|
||||
|
||||
nsDOMNotifyPaintEvent::nsDOMNotifyPaintEvent(nsPresContext* aPresContext,
|
||||
nsNotifyPaintEvent* aEvent)
|
||||
: nsDOMEvent(aPresContext, aEvent ? aEvent :
|
||||
new nsNotifyPaintEvent(PR_FALSE, 0, nsRegion(), nsRegion()))
|
||||
{
|
||||
if (aEvent) {
|
||||
mEventIsInternal = PR_FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
mEventIsInternal = PR_TRUE;
|
||||
mEvent->time = PR_Now();
|
||||
}
|
||||
}
|
||||
|
||||
nsDOMNotifyPaintEvent::~nsDOMNotifyPaintEvent()
|
||||
nsEvent* aEvent,
|
||||
PRUint32 aEventType,
|
||||
const nsRegion* aSameDocRegion,
|
||||
const nsRegion* aCrossDocRegion)
|
||||
: nsDOMEvent(aPresContext, aEvent)
|
||||
{
|
||||
if (mEventIsInternal) {
|
||||
if (mEvent->eventStructType == NS_NOTIFYPAINT_EVENT) {
|
||||
delete static_cast<nsNotifyPaintEvent*>(mEvent);
|
||||
mEvent = nsnull;
|
||||
}
|
||||
if (mEvent) {
|
||||
mEvent->message = aEventType;
|
||||
}
|
||||
if (aSameDocRegion) {
|
||||
mSameDocRegion = *aSameDocRegion;
|
||||
}
|
||||
if (aCrossDocRegion) {
|
||||
mCrossDocRegion = *aCrossDocRegion;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -76,13 +69,11 @@ NS_IMPL_RELEASE_INHERITED(nsDOMNotifyPaintEvent, nsDOMEvent)
|
|||
nsRegion
|
||||
nsDOMNotifyPaintEvent::GetRegion()
|
||||
{
|
||||
nsNotifyPaintEvent* event = static_cast<nsNotifyPaintEvent*>(mEvent);
|
||||
|
||||
nsRegion r;
|
||||
if (nsContentUtils::IsCallerTrustedForRead()) {
|
||||
r.Or(event->sameDocRegion, event->crossDocRegion);
|
||||
r.Or(mSameDocRegion, mCrossDocRegion);
|
||||
} else {
|
||||
r = event->sameDocRegion;
|
||||
r = mSameDocRegion;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
@ -127,10 +118,14 @@ nsDOMNotifyPaintEvent::GetClientRects(nsIDOMClientRectList** aResult)
|
|||
|
||||
nsresult NS_NewDOMNotifyPaintEvent(nsIDOMEvent** aInstancePtrResult,
|
||||
nsPresContext* aPresContext,
|
||||
nsNotifyPaintEvent *aEvent)
|
||||
nsEvent *aEvent,
|
||||
PRUint32 aEventType,
|
||||
const nsRegion* aSameOriginRegion,
|
||||
const nsRegion* aCrossDocRegion)
|
||||
{
|
||||
nsDOMNotifyPaintEvent* it =
|
||||
new nsDOMNotifyPaintEvent(aPresContext, aEvent);
|
||||
new nsDOMNotifyPaintEvent(aPresContext, aEvent, aEventType,
|
||||
aSameOriginRegion, aCrossDocRegion);
|
||||
if (nsnull == it) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
|
|
@ -46,9 +46,11 @@ class nsDOMNotifyPaintEvent : public nsIDOMNotifyPaintEvent,
|
|||
public nsDOMEvent
|
||||
{
|
||||
public:
|
||||
nsDOMNotifyPaintEvent(nsPresContext* aPresContext,
|
||||
nsNotifyPaintEvent* aEvent);
|
||||
virtual ~nsDOMNotifyPaintEvent();
|
||||
nsDOMNotifyPaintEvent(nsPresContext* aPresContext,
|
||||
nsEvent* aEvent,
|
||||
PRUint32 aEventType,
|
||||
const nsRegion* aSameOriginRegion,
|
||||
const nsRegion* aCrossDocRegion);
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
|
@ -59,6 +61,9 @@ public:
|
|||
|
||||
private:
|
||||
nsRegion GetRegion();
|
||||
|
||||
nsRegion mSameDocRegion;
|
||||
nsRegion mCrossDocRegion;
|
||||
};
|
||||
|
||||
#endif // nsDOMNotifyPaintEvent_h_
|
||||
|
|
|
@ -39,21 +39,6 @@
|
|||
#include "nsDOMPageTransitionEvent.h"
|
||||
#include "nsContentUtils.h"
|
||||
|
||||
nsDOMPageTransitionEvent::nsDOMPageTransitionEvent(nsPresContext* aPresContext,
|
||||
nsPageTransitionEvent* aEvent)
|
||||
: nsDOMEvent(aPresContext, aEvent ? aEvent :
|
||||
new nsPageTransitionEvent(PR_FALSE, 0, PR_FALSE))
|
||||
{
|
||||
if ( aEvent ) {
|
||||
mEventIsInternal = PR_FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
mEventIsInternal = PR_TRUE;
|
||||
mEvent->time = PR_Now();
|
||||
}
|
||||
}
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN(nsDOMPageTransitionEvent)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMPageTransitionEvent)
|
||||
NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(PageTransitionEvent)
|
||||
|
@ -65,7 +50,7 @@ NS_IMPL_RELEASE_INHERITED(nsDOMPageTransitionEvent, nsDOMEvent)
|
|||
NS_IMETHODIMP
|
||||
nsDOMPageTransitionEvent::GetPersisted(PRBool* aPersisted)
|
||||
{
|
||||
*aPersisted = static_cast<nsPageTransitionEvent*>(mEvent)->persisted;
|
||||
*aPersisted = mPersisted;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -78,13 +63,13 @@ nsDOMPageTransitionEvent::InitPageTransitionEvent(const nsAString &aTypeArg,
|
|||
nsresult rv = nsDOMEvent::InitEvent(aTypeArg, aCanBubbleArg, aCancelableArg);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
static_cast<nsPageTransitionEvent*>(mEvent)->persisted = aPersisted;
|
||||
mPersisted = aPersisted;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult NS_NewDOMPageTransitionEvent(nsIDOMEvent** aInstancePtrResult,
|
||||
nsPresContext* aPresContext,
|
||||
nsPageTransitionEvent *aEvent)
|
||||
nsEvent *aEvent)
|
||||
{
|
||||
nsDOMPageTransitionEvent* it =
|
||||
new nsDOMPageTransitionEvent(aPresContext, aEvent);
|
||||
|
|
|
@ -46,15 +46,17 @@ class nsDOMPageTransitionEvent : public nsIDOMPageTransitionEvent,
|
|||
public nsDOMEvent
|
||||
{
|
||||
public:
|
||||
nsDOMPageTransitionEvent(nsPresContext* aPresContext,
|
||||
nsPageTransitionEvent* aEvent);
|
||||
|
||||
nsDOMPageTransitionEvent(nsPresContext* aPresContext, nsEvent* aEvent) :
|
||||
nsDOMEvent(aPresContext, aEvent), mPersisted(PR_FALSE) {}
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
NS_DECL_NSIDOMPAGETRANSITIONEVENT
|
||||
|
||||
// Forward to base class
|
||||
NS_FORWARD_TO_NSDOMEVENT
|
||||
protected:
|
||||
PRBool mPersisted;
|
||||
};
|
||||
|
||||
#endif // nsDOMPageTransitionEvent_h__
|
||||
|
|
|
@ -368,15 +368,6 @@ nsDOMUIEvent::GetIsChar(PRBool* aIsChar)
|
|||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMUIEvent::GetPreventDefault(PRBool* aReturn)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aReturn);
|
||||
*aReturn = mEvent && (mEvent->flags & NS_EVENT_FLAG_NO_DEFAULT);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_METHOD nsDOMUIEvent::GetCompositionReply(nsTextEventReply** aReply)
|
||||
{
|
||||
if((mEvent->message == NS_COMPOSITION_START) ||
|
||||
|
|
|
@ -71,6 +71,7 @@ public:
|
|||
// Forward to nsDOMEvent
|
||||
NS_FORWARD_TO_NSDOMEVENT
|
||||
|
||||
NS_FORWARD_NSIDOMNSEVENT(nsDOMEvent::)
|
||||
protected:
|
||||
|
||||
// Internal helper functions
|
||||
|
|
|
@ -233,7 +233,7 @@ nsEventTargetChainItem::HandleEvent(nsEventChainPostVisitor& aVisitor,
|
|||
if (!aMayHaveNewListenerManagers) {
|
||||
return NS_OK;
|
||||
}
|
||||
mTarget->GetListenerManager(PR_FALSE, getter_AddRefs(mManager));
|
||||
mManager = mTarget->GetListenerManager(PR_FALSE);
|
||||
}
|
||||
if (mManager) {
|
||||
NS_ASSERTION(aVisitor.mEvent->currentTarget == nsnull,
|
||||
|
@ -325,8 +325,6 @@ nsEventTargetChainItem::HandleEventTargetChain(nsEventChainPostVisitor& aVisitor
|
|||
if (!(aVisitor.mEvent->flags & NS_EVENT_FLAG_CANT_BUBBLE) || newTarget) {
|
||||
if ((!(aVisitor.mEvent->flags & NS_EVENT_FLAG_NO_CONTENT_DISPATCH) ||
|
||||
item->ForceContentDispatch()) &&
|
||||
(!(aFlags & NS_EVENT_FLAG_SYSTEM_EVENT) ||
|
||||
aVisitor.mEventStatus != nsEventStatus_eConsumeNoDefault) &&
|
||||
!(aVisitor.mEvent->flags & NS_EVENT_FLAG_STOP_DISPATCH)) {
|
||||
item->HandleEvent(aVisitor, aFlags & NS_EVENT_BUBBLE_MASK,
|
||||
createdELMs != nsEventListenerManager::sCreatedCount);
|
||||
|
@ -643,15 +641,6 @@ nsEventDispatcher::CreateEvent(nsPresContext* aPresContext,
|
|||
case NS_TEXT_EVENT:
|
||||
return NS_NewDOMTextEvent(aDOMEvent, aPresContext,
|
||||
static_cast<nsTextEvent*>(aEvent));
|
||||
case NS_BEFORE_PAGE_UNLOAD_EVENT:
|
||||
return
|
||||
NS_NewDOMBeforeUnloadEvent(aDOMEvent, aPresContext,
|
||||
static_cast<nsBeforePageUnloadEvent*>
|
||||
(aEvent));
|
||||
case NS_PAGETRANSITION_EVENT:
|
||||
return NS_NewDOMPageTransitionEvent(aDOMEvent, aPresContext,
|
||||
static_cast<nsPageTransitionEvent*>
|
||||
(aEvent));
|
||||
#ifdef MOZ_SVG
|
||||
case NS_SVG_EVENT:
|
||||
return NS_NewDOMSVGEvent(aDOMEvent, aPresContext,
|
||||
|
@ -668,10 +657,6 @@ nsEventDispatcher::CreateEvent(nsPresContext* aPresContext,
|
|||
case NS_COMMAND_EVENT:
|
||||
return NS_NewDOMCommandEvent(aDOMEvent, aPresContext,
|
||||
static_cast<nsCommandEvent*>(aEvent));
|
||||
case NS_NOTIFYPAINT_EVENT:
|
||||
return NS_NewDOMNotifyPaintEvent(aDOMEvent, aPresContext,
|
||||
static_cast<nsNotifyPaintEvent*>
|
||||
(aEvent));
|
||||
case NS_SIMPLE_GESTURE_EVENT:
|
||||
return NS_NewDOMSimpleGestureEvent(aDOMEvent, aPresContext,
|
||||
static_cast<nsSimpleGestureEvent*>(aEvent));
|
||||
|
@ -735,6 +720,10 @@ nsEventDispatcher::CreateEvent(nsPresContext* aPresContext,
|
|||
return NS_NewDOMNotifyPaintEvent(aDOMEvent, aPresContext, nsnull);
|
||||
if (aEventType.LowerCaseEqualsLiteral("simplegestureevent"))
|
||||
return NS_NewDOMSimpleGestureEvent(aDOMEvent, aPresContext, nsnull);
|
||||
if (aEventType.LowerCaseEqualsLiteral("beforeunloadevent"))
|
||||
return NS_NewDOMBeforeUnloadEvent(aDOMEvent, aPresContext, nsnull);
|
||||
if (aEventType.LowerCaseEqualsLiteral("pagetransition"))
|
||||
return NS_NewDOMPageTransitionEvent(aDOMEvent, aPresContext, nsnull);
|
||||
|
||||
return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
|
||||
}
|
||||
|
|
|
@ -49,15 +49,12 @@
|
|||
#include "nsIDOMFocusListener.h"
|
||||
#include "nsIDOMFormListener.h"
|
||||
#include "nsIDOMLoadListener.h"
|
||||
#include "nsIDOMDragListener.h"
|
||||
#include "nsIDOMTextListener.h"
|
||||
#include "nsIDOMCompositionListener.h"
|
||||
#include "nsIDOMXULListener.h"
|
||||
#include "nsIDOMUIListener.h"
|
||||
#include "nsITextControlFrame.h"
|
||||
#ifdef MOZ_SVG
|
||||
#include "nsIDOMSVGListener.h"
|
||||
#include "nsIDOMSVGZoomListener.h"
|
||||
#include "nsGkAtoms.h"
|
||||
#endif // MOZ_SVG
|
||||
#include "nsIEventStateManager.h"
|
||||
|
@ -247,19 +244,6 @@ static const EventDispatchData sLoadEvents[] = {
|
|||
{ NS_BEFORE_PAGE_UNLOAD, HANDLER(&nsIDOMLoadListener::BeforeUnload) }
|
||||
};
|
||||
|
||||
static const EventDispatchData sDragEvents[] = {
|
||||
{ NS_DRAGDROP_ENTER, HANDLER(&nsIDOMDragListener::DragEnter) },
|
||||
{ NS_DRAGDROP_OVER_SYNTH, HANDLER(&nsIDOMDragListener::DragOver) },
|
||||
{ NS_DRAGDROP_EXIT_SYNTH, HANDLER(&nsIDOMDragListener::DragExit) },
|
||||
{ NS_DRAGDROP_DRAGDROP, HANDLER(&nsIDOMDragListener::DragDrop) },
|
||||
{ NS_DRAGDROP_GESTURE, HANDLER(&nsIDOMDragListener::DragGesture) },
|
||||
{ NS_DRAGDROP_DRAG, HANDLER(&nsIDOMDragListener::Drag) },
|
||||
{ NS_DRAGDROP_END, HANDLER(&nsIDOMDragListener::DragEnd) },
|
||||
{ NS_DRAGDROP_START, HANDLER(&nsIDOMDragListener::DragStart) },
|
||||
{ NS_DRAGDROP_LEAVE_SYNTH, HANDLER(&nsIDOMDragListener::DragLeave) },
|
||||
{ NS_DRAGDROP_DROP, HANDLER(&nsIDOMDragListener::Drop) }
|
||||
};
|
||||
|
||||
static const EventDispatchData sXULEvents[] = {
|
||||
{ NS_XUL_POPUP_SHOWING, HANDLER(&nsIDOMXULListener::PopupShowing) },
|
||||
{ NS_XUL_POPUP_SHOWN, HANDLER(&nsIDOMXULListener::PopupShown) },
|
||||
|
@ -277,21 +261,6 @@ static const EventDispatchData sUIEvents[] = {
|
|||
{ NS_UI_FOCUSOUT, HANDLER(&nsIDOMUIListener::FocusOut) }
|
||||
};
|
||||
|
||||
#ifdef MOZ_SVG
|
||||
static const EventDispatchData sSVGEvents[] = {
|
||||
{ NS_SVG_LOAD, HANDLER(&nsIDOMSVGListener::Load) },
|
||||
{ NS_SVG_UNLOAD, HANDLER(&nsIDOMSVGListener::Unload) },
|
||||
{ NS_SVG_ABORT, HANDLER(&nsIDOMSVGListener::Abort) },
|
||||
{ NS_SVG_ERROR, HANDLER(&nsIDOMSVGListener::Error) },
|
||||
{ NS_SVG_RESIZE, HANDLER(&nsIDOMSVGListener::Resize) },
|
||||
{ NS_SVG_SCROLL, HANDLER(&nsIDOMSVGListener::Scroll) }
|
||||
};
|
||||
|
||||
static const EventDispatchData sSVGZoomEvents[] = {
|
||||
{ NS_SVG_ZOOM, HANDLER(&nsIDOMSVGZoomListener::Zoom) }
|
||||
};
|
||||
#endif // MOZ_SVG
|
||||
|
||||
#define IMPL_EVENTTYPEDATA(type) \
|
||||
{ \
|
||||
s##type##Events, \
|
||||
|
@ -309,16 +278,10 @@ static const EventTypeData sEventTypes[] = {
|
|||
IMPL_EVENTTYPEDATA(Load),
|
||||
IMPL_EVENTTYPEDATA(Focus),
|
||||
IMPL_EVENTTYPEDATA(Form),
|
||||
IMPL_EVENTTYPEDATA(Drag),
|
||||
IMPL_EVENTTYPEDATA(Text),
|
||||
IMPL_EVENTTYPEDATA(Composition),
|
||||
IMPL_EVENTTYPEDATA(XUL),
|
||||
IMPL_EVENTTYPEDATA(UI)
|
||||
#ifdef MOZ_SVG
|
||||
,
|
||||
IMPL_EVENTTYPEDATA(SVG),
|
||||
IMPL_EVENTTYPEDATA(SVGZoom)
|
||||
#endif // MOZ_SVG
|
||||
};
|
||||
|
||||
// Strong references to event groups
|
||||
|
@ -564,6 +527,7 @@ nsEventListenerManager::RemoveEventListener(nsIDOMEventListener *aListener,
|
|||
(EVENT_TYPE_EQUALS(ls, aType, aUserType) ||
|
||||
(!(ls->mEventType) &&
|
||||
EVENT_TYPE_DATA_EQUALS(ls->mTypeData, aTypeData)))) {
|
||||
nsRefPtr<nsEventListenerManager> kungFuDeathGrip = this;
|
||||
mListeners.RemoveElementAt(i);
|
||||
mNoListenerForEvent = NS_EVENT_TYPE_NULL;
|
||||
mNoListenerForEventAtom = nsnull;
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче