зеркало из https://github.com/mozilla/gecko-dev.git
Merge inbound to mozilla-central. a=merge
This commit is contained in:
Коммит
ff466e94c1
|
@ -38,7 +38,7 @@ static const uint32_t kGenericAccType = 0;
|
|||
static const nsRoleMapEntry sWAIRoleMaps[] =
|
||||
{
|
||||
{ // alert
|
||||
&nsGkAtoms::alert,
|
||||
nsGkAtoms::alert,
|
||||
roles::ALERT,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -48,7 +48,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
kNoReqStates
|
||||
},
|
||||
{ // alertdialog
|
||||
&nsGkAtoms::alertdialog,
|
||||
nsGkAtoms::alertdialog,
|
||||
roles::DIALOG,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -58,7 +58,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
kNoReqStates
|
||||
},
|
||||
{ // application
|
||||
&nsGkAtoms::application,
|
||||
nsGkAtoms::application,
|
||||
roles::APPLICATION,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -68,7 +68,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
kNoReqStates
|
||||
},
|
||||
{ // article
|
||||
&nsGkAtoms::article,
|
||||
nsGkAtoms::article,
|
||||
roles::ARTICLE,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -79,7 +79,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
eReadonlyUntilEditable
|
||||
},
|
||||
{ // banner
|
||||
&nsGkAtoms::banner,
|
||||
nsGkAtoms::banner,
|
||||
roles::NOTHING,
|
||||
kUseNativeRole,
|
||||
eNoValue,
|
||||
|
@ -89,7 +89,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
kNoReqStates
|
||||
},
|
||||
{ // button
|
||||
&nsGkAtoms::button,
|
||||
nsGkAtoms::button,
|
||||
roles::PUSHBUTTON,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -100,7 +100,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
// eARIAPressed is auto applied on any button
|
||||
},
|
||||
{ // cell
|
||||
&nsGkAtoms::cell,
|
||||
nsGkAtoms::cell,
|
||||
roles::CELL,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -110,7 +110,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
kNoReqStates
|
||||
},
|
||||
{ // checkbox
|
||||
&nsGkAtoms::checkbox,
|
||||
nsGkAtoms::checkbox,
|
||||
roles::CHECKBUTTON,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -122,7 +122,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
eARIAReadonly
|
||||
},
|
||||
{ // columnheader
|
||||
&nsGkAtoms::columnheader,
|
||||
nsGkAtoms::columnheader,
|
||||
roles::COLUMNHEADER,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -134,7 +134,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
eARIAReadonlyOrEditableIfDefined
|
||||
},
|
||||
{ // combobox, which consists of text input and popup
|
||||
&nsGkAtoms::combobox,
|
||||
nsGkAtoms::combobox,
|
||||
roles::EDITCOMBOBOX,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -147,7 +147,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
eARIAOrientation
|
||||
},
|
||||
{ // complementary
|
||||
&nsGkAtoms::complementary,
|
||||
nsGkAtoms::complementary,
|
||||
roles::NOTHING,
|
||||
kUseNativeRole,
|
||||
eNoValue,
|
||||
|
@ -157,7 +157,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
kNoReqStates
|
||||
},
|
||||
{ // contentinfo
|
||||
&nsGkAtoms::contentinfo,
|
||||
nsGkAtoms::contentinfo,
|
||||
roles::NOTHING,
|
||||
kUseNativeRole,
|
||||
eNoValue,
|
||||
|
@ -167,7 +167,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
kNoReqStates
|
||||
},
|
||||
{ // dialog
|
||||
&nsGkAtoms::dialog,
|
||||
nsGkAtoms::dialog,
|
||||
roles::DIALOG,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -177,7 +177,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
kNoReqStates
|
||||
},
|
||||
{ // directory
|
||||
&nsGkAtoms::directory,
|
||||
nsGkAtoms::directory,
|
||||
roles::LIST,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -187,7 +187,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
states::READONLY
|
||||
},
|
||||
{ // doc-abstract
|
||||
&nsGkAtoms::docAbstract,
|
||||
nsGkAtoms::docAbstract,
|
||||
roles::SECTION,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -197,7 +197,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
kNoReqStates
|
||||
},
|
||||
{ // doc-acknowledgments
|
||||
&nsGkAtoms::docAcknowledgments,
|
||||
nsGkAtoms::docAcknowledgments,
|
||||
roles::LANDMARK,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -207,7 +207,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
kNoReqStates
|
||||
},
|
||||
{ // doc-afterword
|
||||
&nsGkAtoms::docAfterword,
|
||||
nsGkAtoms::docAfterword,
|
||||
roles::LANDMARK,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -217,7 +217,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
kNoReqStates
|
||||
},
|
||||
{ // doc-appendix
|
||||
&nsGkAtoms::docAppendix,
|
||||
nsGkAtoms::docAppendix,
|
||||
roles::LANDMARK,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -227,7 +227,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
kNoReqStates
|
||||
},
|
||||
{ // doc-backlink
|
||||
&nsGkAtoms::docBacklink,
|
||||
nsGkAtoms::docBacklink,
|
||||
roles::LINK,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -237,7 +237,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
states::LINKED
|
||||
},
|
||||
{ // doc-biblioentry
|
||||
&nsGkAtoms::docBiblioentry,
|
||||
nsGkAtoms::docBiblioentry,
|
||||
roles::LISTITEM,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -247,7 +247,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
states::READONLY
|
||||
},
|
||||
{ // doc-bibliography
|
||||
&nsGkAtoms::docBibliography,
|
||||
nsGkAtoms::docBibliography,
|
||||
roles::LANDMARK,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -257,7 +257,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
kNoReqStates
|
||||
},
|
||||
{ // doc-biblioref
|
||||
&nsGkAtoms::docBiblioref,
|
||||
nsGkAtoms::docBiblioref,
|
||||
roles::LINK,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -267,7 +267,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
states::LINKED
|
||||
},
|
||||
{ // doc-chapter
|
||||
&nsGkAtoms::docChapter,
|
||||
nsGkAtoms::docChapter,
|
||||
roles::LANDMARK,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -277,7 +277,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
kNoReqStates
|
||||
},
|
||||
{ // doc-colophon
|
||||
&nsGkAtoms::docColophon,
|
||||
nsGkAtoms::docColophon,
|
||||
roles::SECTION,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -287,7 +287,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
kNoReqStates
|
||||
},
|
||||
{ // doc-conclusion
|
||||
&nsGkAtoms::docConclusion,
|
||||
nsGkAtoms::docConclusion,
|
||||
roles::LANDMARK,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -297,7 +297,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
kNoReqStates
|
||||
},
|
||||
{ // doc-cover
|
||||
&nsGkAtoms::docCover,
|
||||
nsGkAtoms::docCover,
|
||||
roles::GRAPHIC,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -307,7 +307,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
kNoReqStates
|
||||
},
|
||||
{ // doc-credit
|
||||
&nsGkAtoms::docCredit,
|
||||
nsGkAtoms::docCredit,
|
||||
roles::SECTION,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -317,7 +317,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
kNoReqStates
|
||||
},
|
||||
{ // doc-credits
|
||||
&nsGkAtoms::docCredits,
|
||||
nsGkAtoms::docCredits,
|
||||
roles::LANDMARK,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -327,7 +327,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
kNoReqStates
|
||||
},
|
||||
{ // doc-dedication
|
||||
&nsGkAtoms::docDedication,
|
||||
nsGkAtoms::docDedication,
|
||||
roles::SECTION,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -337,7 +337,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
kNoReqStates
|
||||
},
|
||||
{ // doc-endnote
|
||||
&nsGkAtoms::docEndnote,
|
||||
nsGkAtoms::docEndnote,
|
||||
roles::LISTITEM,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -347,7 +347,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
states::READONLY
|
||||
},
|
||||
{ // doc-endnotes
|
||||
&nsGkAtoms::docEndnotes,
|
||||
nsGkAtoms::docEndnotes,
|
||||
roles::LANDMARK,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -357,7 +357,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
kNoReqStates
|
||||
},
|
||||
{ // doc-epigraph
|
||||
&nsGkAtoms::docEpigraph,
|
||||
nsGkAtoms::docEpigraph,
|
||||
roles::SECTION,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -367,7 +367,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
kNoReqStates
|
||||
},
|
||||
{ // doc-epilogue
|
||||
&nsGkAtoms::docEpilogue,
|
||||
nsGkAtoms::docEpilogue,
|
||||
roles::LANDMARK,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -377,7 +377,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
kNoReqStates
|
||||
},
|
||||
{ // doc-errata
|
||||
&nsGkAtoms::docErrata,
|
||||
nsGkAtoms::docErrata,
|
||||
roles::LANDMARK,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -387,7 +387,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
kNoReqStates
|
||||
},
|
||||
{ // doc-example
|
||||
&nsGkAtoms::docExample,
|
||||
nsGkAtoms::docExample,
|
||||
roles::SECTION,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -397,7 +397,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
kNoReqStates
|
||||
},
|
||||
{ // doc-footnote
|
||||
&nsGkAtoms::docFootnote,
|
||||
nsGkAtoms::docFootnote,
|
||||
roles::FOOTNOTE,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -407,7 +407,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
kNoReqStates
|
||||
},
|
||||
{ // doc-foreword
|
||||
&nsGkAtoms::docForeword,
|
||||
nsGkAtoms::docForeword,
|
||||
roles::LANDMARK,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -417,7 +417,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
kNoReqStates
|
||||
},
|
||||
{ // doc-glossary
|
||||
&nsGkAtoms::docGlossary,
|
||||
nsGkAtoms::docGlossary,
|
||||
roles::LANDMARK,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -427,7 +427,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
kNoReqStates
|
||||
},
|
||||
{ // doc-glossref
|
||||
&nsGkAtoms::docGlossref,
|
||||
nsGkAtoms::docGlossref,
|
||||
roles::LINK,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -437,7 +437,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
states::LINKED
|
||||
},
|
||||
{ // doc-index
|
||||
&nsGkAtoms::docIndex,
|
||||
nsGkAtoms::docIndex,
|
||||
roles::NAVIGATION,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -447,7 +447,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
kNoReqStates
|
||||
},
|
||||
{ // doc-introduction
|
||||
&nsGkAtoms::docIntroduction,
|
||||
nsGkAtoms::docIntroduction,
|
||||
roles::LANDMARK,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -457,7 +457,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
kNoReqStates
|
||||
},
|
||||
{ // doc-noteref
|
||||
&nsGkAtoms::docNoteref,
|
||||
nsGkAtoms::docNoteref,
|
||||
roles::LINK,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -467,7 +467,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
states::LINKED
|
||||
},
|
||||
{ // doc-notice
|
||||
&nsGkAtoms::docNotice,
|
||||
nsGkAtoms::docNotice,
|
||||
roles::NOTE,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -477,7 +477,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
kNoReqStates
|
||||
},
|
||||
{ // doc-pagebreak
|
||||
&nsGkAtoms::docPagebreak,
|
||||
nsGkAtoms::docPagebreak,
|
||||
roles::SEPARATOR,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -487,7 +487,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
kNoReqStates
|
||||
},
|
||||
{ // doc-pagelist
|
||||
&nsGkAtoms::docPagelist,
|
||||
nsGkAtoms::docPagelist,
|
||||
roles::NAVIGATION,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -497,7 +497,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
kNoReqStates
|
||||
},
|
||||
{ // doc-part
|
||||
&nsGkAtoms::docPart,
|
||||
nsGkAtoms::docPart,
|
||||
roles::LANDMARK,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -507,7 +507,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
kNoReqStates
|
||||
},
|
||||
{ // doc-preface
|
||||
&nsGkAtoms::docPreface,
|
||||
nsGkAtoms::docPreface,
|
||||
roles::LANDMARK,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -517,7 +517,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
kNoReqStates
|
||||
},
|
||||
{ // doc-prologue
|
||||
&nsGkAtoms::docPrologue,
|
||||
nsGkAtoms::docPrologue,
|
||||
roles::LANDMARK,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -527,7 +527,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
kNoReqStates
|
||||
},
|
||||
{ // doc-pullquote
|
||||
&nsGkAtoms::docPullquote,
|
||||
nsGkAtoms::docPullquote,
|
||||
roles::SECTION,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -537,7 +537,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
kNoReqStates
|
||||
},
|
||||
{ // doc-qna
|
||||
&nsGkAtoms::docQna,
|
||||
nsGkAtoms::docQna,
|
||||
roles::SECTION,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -547,7 +547,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
kNoReqStates
|
||||
},
|
||||
{ // doc-subtitle
|
||||
&nsGkAtoms::docSubtitle,
|
||||
nsGkAtoms::docSubtitle,
|
||||
roles::HEADING,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -557,7 +557,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
kNoReqStates
|
||||
},
|
||||
{ // doc-tip
|
||||
&nsGkAtoms::docTip,
|
||||
nsGkAtoms::docTip,
|
||||
roles::NOTE,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -567,7 +567,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
kNoReqStates
|
||||
},
|
||||
{ // doc-toc
|
||||
&nsGkAtoms::docToc,
|
||||
nsGkAtoms::docToc,
|
||||
roles::NAVIGATION,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -577,7 +577,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
kNoReqStates
|
||||
},
|
||||
{ // document
|
||||
&nsGkAtoms::document,
|
||||
nsGkAtoms::document,
|
||||
roles::NON_NATIVE_DOCUMENT,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -588,7 +588,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
eReadonlyUntilEditable
|
||||
},
|
||||
{ // feed
|
||||
&nsGkAtoms::feed,
|
||||
nsGkAtoms::feed,
|
||||
roles::GROUPING,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -598,7 +598,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
kNoReqStates
|
||||
},
|
||||
{ // figure
|
||||
&nsGkAtoms::figure,
|
||||
nsGkAtoms::figure,
|
||||
roles::FIGURE,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -608,7 +608,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
kNoReqStates
|
||||
},
|
||||
{ // form
|
||||
&nsGkAtoms::form,
|
||||
nsGkAtoms::form,
|
||||
roles::FORM,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -618,7 +618,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
kNoReqStates
|
||||
},
|
||||
{ // graphics-document
|
||||
&nsGkAtoms::graphicsDocument,
|
||||
nsGkAtoms::graphicsDocument,
|
||||
roles::NON_NATIVE_DOCUMENT,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -629,7 +629,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
eReadonlyUntilEditable
|
||||
},
|
||||
{ // graphics-object
|
||||
&nsGkAtoms::graphicsObject,
|
||||
nsGkAtoms::graphicsObject,
|
||||
roles::GROUPING,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -639,7 +639,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
kNoReqStates
|
||||
},
|
||||
{ // graphics-symbol
|
||||
&nsGkAtoms::graphicsSymbol,
|
||||
nsGkAtoms::graphicsSymbol,
|
||||
roles::GRAPHIC,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -649,7 +649,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
kNoReqStates
|
||||
},
|
||||
{ // grid
|
||||
&nsGkAtoms::grid,
|
||||
nsGkAtoms::grid,
|
||||
roles::TABLE,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -662,7 +662,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
eFocusableUntilDisabled
|
||||
},
|
||||
{ // gridcell
|
||||
&nsGkAtoms::gridcell,
|
||||
nsGkAtoms::gridcell,
|
||||
roles::GRID_CELL,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -674,7 +674,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
eARIAReadonlyOrEditableIfDefined
|
||||
},
|
||||
{ // group
|
||||
&nsGkAtoms::group,
|
||||
nsGkAtoms::group,
|
||||
roles::GROUPING,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -684,7 +684,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
kNoReqStates
|
||||
},
|
||||
{ // heading
|
||||
&nsGkAtoms::heading,
|
||||
nsGkAtoms::heading,
|
||||
roles::HEADING,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -694,7 +694,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
kNoReqStates
|
||||
},
|
||||
{ // img
|
||||
&nsGkAtoms::img,
|
||||
nsGkAtoms::img,
|
||||
roles::GRAPHIC,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -704,7 +704,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
kNoReqStates
|
||||
},
|
||||
{ // key
|
||||
&nsGkAtoms::key,
|
||||
nsGkAtoms::key,
|
||||
roles::KEY,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -715,7 +715,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
eARIAPressed
|
||||
},
|
||||
{ // link
|
||||
&nsGkAtoms::link,
|
||||
nsGkAtoms::link,
|
||||
roles::LINK,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -725,7 +725,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
states::LINKED
|
||||
},
|
||||
{ // list
|
||||
&nsGkAtoms::list_,
|
||||
nsGkAtoms::list_,
|
||||
roles::LIST,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -735,7 +735,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
states::READONLY
|
||||
},
|
||||
{ // listbox
|
||||
&nsGkAtoms::listbox,
|
||||
nsGkAtoms::listbox,
|
||||
roles::LISTBOX,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -749,7 +749,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
eARIAOrientation
|
||||
},
|
||||
{ // listitem
|
||||
&nsGkAtoms::listitem,
|
||||
nsGkAtoms::listitem,
|
||||
roles::LISTITEM,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -759,7 +759,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
states::READONLY
|
||||
},
|
||||
{ // log
|
||||
&nsGkAtoms::log_,
|
||||
nsGkAtoms::log_,
|
||||
roles::NOTHING,
|
||||
kUseNativeRole,
|
||||
eNoValue,
|
||||
|
@ -769,7 +769,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
kNoReqStates
|
||||
},
|
||||
{ // main
|
||||
&nsGkAtoms::main,
|
||||
nsGkAtoms::main,
|
||||
roles::NOTHING,
|
||||
kUseNativeRole,
|
||||
eNoValue,
|
||||
|
@ -779,7 +779,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
kNoReqStates
|
||||
},
|
||||
{ // marquee
|
||||
&nsGkAtoms::marquee,
|
||||
nsGkAtoms::marquee,
|
||||
roles::ANIMATION,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -789,7 +789,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
kNoReqStates
|
||||
},
|
||||
{ // math
|
||||
&nsGkAtoms::math,
|
||||
nsGkAtoms::math,
|
||||
roles::FLAT_EQUATION,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -799,7 +799,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
kNoReqStates
|
||||
},
|
||||
{ // menu
|
||||
&nsGkAtoms::menu,
|
||||
nsGkAtoms::menu,
|
||||
roles::MENUPOPUP,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -811,7 +811,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
eARIAOrientation
|
||||
},
|
||||
{ // menubar
|
||||
&nsGkAtoms::menubar,
|
||||
nsGkAtoms::menubar,
|
||||
roles::MENUBAR,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -822,7 +822,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
eARIAOrientation
|
||||
},
|
||||
{ // menuitem
|
||||
&nsGkAtoms::menuitem,
|
||||
nsGkAtoms::menuitem,
|
||||
roles::MENUITEM,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -832,7 +832,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
kNoReqStates
|
||||
},
|
||||
{ // menuitemcheckbox
|
||||
&nsGkAtoms::menuitemcheckbox,
|
||||
nsGkAtoms::menuitemcheckbox,
|
||||
roles::CHECK_MENU_ITEM,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -844,7 +844,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
eARIAReadonly
|
||||
},
|
||||
{ // menuitemradio
|
||||
&nsGkAtoms::menuitemradio,
|
||||
nsGkAtoms::menuitemradio,
|
||||
roles::RADIO_MENU_ITEM,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -856,7 +856,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
eARIAReadonly
|
||||
},
|
||||
{ // navigation
|
||||
&nsGkAtoms::navigation,
|
||||
nsGkAtoms::navigation,
|
||||
roles::NOTHING,
|
||||
kUseNativeRole,
|
||||
eNoValue,
|
||||
|
@ -866,7 +866,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
kNoReqStates
|
||||
},
|
||||
{ // none
|
||||
&nsGkAtoms::none,
|
||||
nsGkAtoms::none,
|
||||
roles::NOTHING,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -876,7 +876,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
kNoReqStates
|
||||
},
|
||||
{ // note
|
||||
&nsGkAtoms::note_,
|
||||
nsGkAtoms::note_,
|
||||
roles::NOTE,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -886,7 +886,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
kNoReqStates
|
||||
},
|
||||
{ // option
|
||||
&nsGkAtoms::option,
|
||||
nsGkAtoms::option,
|
||||
roles::OPTION,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -898,7 +898,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
eARIACheckedMixed
|
||||
},
|
||||
{ // presentation
|
||||
&nsGkAtoms::presentation,
|
||||
nsGkAtoms::presentation,
|
||||
roles::NOTHING,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -908,7 +908,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
kNoReqStates
|
||||
},
|
||||
{ // progressbar
|
||||
&nsGkAtoms::progressbar,
|
||||
nsGkAtoms::progressbar,
|
||||
roles::PROGRESSBAR,
|
||||
kUseMapRole,
|
||||
eHasValueMinMax,
|
||||
|
@ -919,7 +919,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
eIndeterminateIfNoValue
|
||||
},
|
||||
{ // radio
|
||||
&nsGkAtoms::radio,
|
||||
nsGkAtoms::radio,
|
||||
roles::RADIOBUTTON,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -930,7 +930,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
eARIACheckableBool
|
||||
},
|
||||
{ // radiogroup
|
||||
&nsGkAtoms::radiogroup,
|
||||
nsGkAtoms::radiogroup,
|
||||
roles::RADIO_GROUP,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -942,7 +942,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
eARIAReadonly
|
||||
},
|
||||
{ // region
|
||||
&nsGkAtoms::region,
|
||||
nsGkAtoms::region,
|
||||
roles::REGION,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -952,7 +952,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
kNoReqStates
|
||||
},
|
||||
{ // row
|
||||
&nsGkAtoms::row,
|
||||
nsGkAtoms::row,
|
||||
roles::ROW,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -963,7 +963,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
eARIASelectable
|
||||
},
|
||||
{ // rowgroup
|
||||
&nsGkAtoms::rowgroup,
|
||||
nsGkAtoms::rowgroup,
|
||||
roles::GROUPING,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -973,7 +973,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
kNoReqStates
|
||||
},
|
||||
{ // rowheader
|
||||
&nsGkAtoms::rowheader,
|
||||
nsGkAtoms::rowheader,
|
||||
roles::ROWHEADER,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -985,7 +985,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
eARIAReadonlyOrEditableIfDefined
|
||||
},
|
||||
{ // scrollbar
|
||||
&nsGkAtoms::scrollbar,
|
||||
nsGkAtoms::scrollbar,
|
||||
roles::SCROLLBAR,
|
||||
kUseMapRole,
|
||||
eHasValueMinMax,
|
||||
|
@ -997,7 +997,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
eARIAReadonly
|
||||
},
|
||||
{ // search
|
||||
&nsGkAtoms::search,
|
||||
nsGkAtoms::search,
|
||||
roles::NOTHING,
|
||||
kUseNativeRole,
|
||||
eNoValue,
|
||||
|
@ -1007,7 +1007,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
kNoReqStates
|
||||
},
|
||||
{ // searchbox
|
||||
&nsGkAtoms::searchbox,
|
||||
nsGkAtoms::searchbox,
|
||||
roles::ENTRY,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -1020,7 +1020,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
eARIAReadonlyOrEditable
|
||||
},
|
||||
{ // separator
|
||||
&nsGkAtoms::separator_,
|
||||
nsGkAtoms::separator_,
|
||||
roles::SEPARATOR,
|
||||
kUseMapRole,
|
||||
eHasValueMinMaxIfFocusable,
|
||||
|
@ -1031,7 +1031,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
eARIAOrientation
|
||||
},
|
||||
{ // slider
|
||||
&nsGkAtoms::slider,
|
||||
nsGkAtoms::slider,
|
||||
roles::SLIDER,
|
||||
kUseMapRole,
|
||||
eHasValueMinMax,
|
||||
|
@ -1043,7 +1043,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
eARIAReadonly
|
||||
},
|
||||
{ // spinbutton
|
||||
&nsGkAtoms::spinbutton,
|
||||
nsGkAtoms::spinbutton,
|
||||
roles::SPINBUTTON,
|
||||
kUseMapRole,
|
||||
eHasValueMinMax,
|
||||
|
@ -1054,7 +1054,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
eARIAReadonly
|
||||
},
|
||||
{ // status
|
||||
&nsGkAtoms::status,
|
||||
nsGkAtoms::status,
|
||||
roles::STATUSBAR,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -1064,7 +1064,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
kNoReqStates
|
||||
},
|
||||
{ // switch
|
||||
&nsGkAtoms::svgSwitch,
|
||||
nsGkAtoms::svgSwitch,
|
||||
roles::SWITCH,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -1076,7 +1076,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
eARIAReadonly
|
||||
},
|
||||
{ // tab
|
||||
&nsGkAtoms::tab,
|
||||
nsGkAtoms::tab,
|
||||
roles::PAGETAB,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -1087,7 +1087,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
eARIASelectable
|
||||
},
|
||||
{ // table
|
||||
&nsGkAtoms::table,
|
||||
nsGkAtoms::table,
|
||||
roles::TABLE,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -1098,7 +1098,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
eARIASelectable
|
||||
},
|
||||
{ // tablist
|
||||
&nsGkAtoms::tablist,
|
||||
nsGkAtoms::tablist,
|
||||
roles::PAGETABLIST,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -1109,7 +1109,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
eARIAOrientation
|
||||
},
|
||||
{ // tabpanel
|
||||
&nsGkAtoms::tabpanel,
|
||||
nsGkAtoms::tabpanel,
|
||||
roles::PROPERTYPAGE,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -1119,7 +1119,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
kNoReqStates
|
||||
},
|
||||
{ // term
|
||||
&nsGkAtoms::term,
|
||||
nsGkAtoms::term,
|
||||
roles::TERM,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -1129,7 +1129,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
states::READONLY
|
||||
},
|
||||
{ // textbox
|
||||
&nsGkAtoms::textbox,
|
||||
nsGkAtoms::textbox,
|
||||
roles::ENTRY,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -1142,7 +1142,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
eARIAReadonlyOrEditable
|
||||
},
|
||||
{ // timer
|
||||
&nsGkAtoms::timer,
|
||||
nsGkAtoms::timer,
|
||||
roles::NOTHING,
|
||||
kUseNativeRole,
|
||||
eNoValue,
|
||||
|
@ -1151,7 +1151,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
kNoReqStates
|
||||
},
|
||||
{ // toolbar
|
||||
&nsGkAtoms::toolbar,
|
||||
nsGkAtoms::toolbar,
|
||||
roles::TOOLBAR,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -1162,7 +1162,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
eARIAOrientation
|
||||
},
|
||||
{ // tooltip
|
||||
&nsGkAtoms::tooltip,
|
||||
nsGkAtoms::tooltip,
|
||||
roles::TOOLTIP,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -1172,7 +1172,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
kNoReqStates
|
||||
},
|
||||
{ // tree
|
||||
&nsGkAtoms::tree,
|
||||
nsGkAtoms::tree,
|
||||
roles::OUTLINE,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -1186,7 +1186,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
eARIAOrientation
|
||||
},
|
||||
{ // treegrid
|
||||
&nsGkAtoms::treegrid,
|
||||
nsGkAtoms::treegrid,
|
||||
roles::TREE_TABLE,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -1200,7 +1200,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
eARIAOrientation
|
||||
},
|
||||
{ // treeitem
|
||||
&nsGkAtoms::treeitem,
|
||||
nsGkAtoms::treeitem,
|
||||
roles::OUTLINEITEM,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -1215,7 +1215,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
};
|
||||
|
||||
static const nsRoleMapEntry sLandmarkRoleMap = {
|
||||
&nsGkAtoms::_empty,
|
||||
nsGkAtoms::_empty,
|
||||
roles::NOTHING,
|
||||
kUseNativeRole,
|
||||
eNoValue,
|
||||
|
@ -1226,7 +1226,7 @@ static const nsRoleMapEntry sLandmarkRoleMap = {
|
|||
};
|
||||
|
||||
nsRoleMapEntry aria::gEmptyRoleMap = {
|
||||
&nsGkAtoms::_empty,
|
||||
nsGkAtoms::_empty,
|
||||
roles::NOTHING,
|
||||
kUseMapRole,
|
||||
eNoValue,
|
||||
|
@ -1261,48 +1261,48 @@ static const EStateRule sWAIUnivStateMap[] = {
|
|||
|
||||
struct AttrCharacteristics
|
||||
{
|
||||
nsStaticAtom** attributeName;
|
||||
const nsStaticAtom* const attributeName;
|
||||
const uint8_t characteristics;
|
||||
};
|
||||
|
||||
static const AttrCharacteristics gWAIUnivAttrMap[] = {
|
||||
{&nsGkAtoms::aria_activedescendant, ATTR_BYPASSOBJ },
|
||||
{&nsGkAtoms::aria_atomic, ATTR_BYPASSOBJ_IF_FALSE | ATTR_VALTOKEN | ATTR_GLOBAL },
|
||||
{&nsGkAtoms::aria_busy, ATTR_VALTOKEN | ATTR_GLOBAL },
|
||||
{&nsGkAtoms::aria_checked, ATTR_BYPASSOBJ | ATTR_VALTOKEN }, /* exposes checkable obj attr */
|
||||
{&nsGkAtoms::aria_controls, ATTR_BYPASSOBJ | ATTR_GLOBAL },
|
||||
{&nsGkAtoms::aria_describedby, ATTR_BYPASSOBJ | ATTR_GLOBAL },
|
||||
{&nsGkAtoms::aria_details, ATTR_BYPASSOBJ | ATTR_GLOBAL },
|
||||
{&nsGkAtoms::aria_disabled, ATTR_BYPASSOBJ | ATTR_VALTOKEN | ATTR_GLOBAL },
|
||||
{&nsGkAtoms::aria_dropeffect, ATTR_VALTOKEN | ATTR_GLOBAL },
|
||||
{&nsGkAtoms::aria_errormessage, ATTR_BYPASSOBJ | ATTR_GLOBAL },
|
||||
{&nsGkAtoms::aria_expanded, ATTR_BYPASSOBJ | ATTR_VALTOKEN },
|
||||
{&nsGkAtoms::aria_flowto, ATTR_BYPASSOBJ | ATTR_GLOBAL },
|
||||
{&nsGkAtoms::aria_grabbed, ATTR_VALTOKEN | ATTR_GLOBAL },
|
||||
{&nsGkAtoms::aria_haspopup, ATTR_BYPASSOBJ_IF_FALSE | ATTR_VALTOKEN | ATTR_GLOBAL },
|
||||
{&nsGkAtoms::aria_hidden, ATTR_BYPASSOBJ | ATTR_VALTOKEN | ATTR_GLOBAL }, /* handled special way */
|
||||
{&nsGkAtoms::aria_invalid, ATTR_BYPASSOBJ | ATTR_VALTOKEN | ATTR_GLOBAL },
|
||||
{&nsGkAtoms::aria_label, ATTR_BYPASSOBJ | ATTR_GLOBAL },
|
||||
{&nsGkAtoms::aria_labelledby, ATTR_BYPASSOBJ | ATTR_GLOBAL },
|
||||
{&nsGkAtoms::aria_level, ATTR_BYPASSOBJ }, /* handled via groupPosition */
|
||||
{&nsGkAtoms::aria_live, ATTR_VALTOKEN | ATTR_GLOBAL },
|
||||
{&nsGkAtoms::aria_modal, ATTR_BYPASSOBJ | ATTR_VALTOKEN | ATTR_GLOBAL },
|
||||
{&nsGkAtoms::aria_multiline, ATTR_BYPASSOBJ | ATTR_VALTOKEN },
|
||||
{&nsGkAtoms::aria_multiselectable, ATTR_BYPASSOBJ | ATTR_VALTOKEN },
|
||||
{&nsGkAtoms::aria_owns, ATTR_BYPASSOBJ | ATTR_GLOBAL },
|
||||
{&nsGkAtoms::aria_orientation, ATTR_VALTOKEN },
|
||||
{&nsGkAtoms::aria_posinset, ATTR_BYPASSOBJ }, /* handled via groupPosition */
|
||||
{&nsGkAtoms::aria_pressed, ATTR_BYPASSOBJ | ATTR_VALTOKEN },
|
||||
{&nsGkAtoms::aria_readonly, ATTR_BYPASSOBJ | ATTR_VALTOKEN },
|
||||
{&nsGkAtoms::aria_relevant, ATTR_BYPASSOBJ | ATTR_GLOBAL },
|
||||
{&nsGkAtoms::aria_required, ATTR_BYPASSOBJ | ATTR_VALTOKEN },
|
||||
{&nsGkAtoms::aria_selected, ATTR_BYPASSOBJ | ATTR_VALTOKEN },
|
||||
{&nsGkAtoms::aria_setsize, ATTR_BYPASSOBJ }, /* handled via groupPosition */
|
||||
{&nsGkAtoms::aria_sort, ATTR_VALTOKEN },
|
||||
{&nsGkAtoms::aria_valuenow, ATTR_BYPASSOBJ },
|
||||
{&nsGkAtoms::aria_valuemin, ATTR_BYPASSOBJ },
|
||||
{&nsGkAtoms::aria_valuemax, ATTR_BYPASSOBJ },
|
||||
{&nsGkAtoms::aria_valuetext, ATTR_BYPASSOBJ }
|
||||
{nsGkAtoms::aria_activedescendant, ATTR_BYPASSOBJ },
|
||||
{nsGkAtoms::aria_atomic, ATTR_BYPASSOBJ_IF_FALSE | ATTR_VALTOKEN | ATTR_GLOBAL },
|
||||
{nsGkAtoms::aria_busy, ATTR_VALTOKEN | ATTR_GLOBAL },
|
||||
{nsGkAtoms::aria_checked, ATTR_BYPASSOBJ | ATTR_VALTOKEN }, /* exposes checkable obj attr */
|
||||
{nsGkAtoms::aria_controls, ATTR_BYPASSOBJ | ATTR_GLOBAL },
|
||||
{nsGkAtoms::aria_describedby, ATTR_BYPASSOBJ | ATTR_GLOBAL },
|
||||
{nsGkAtoms::aria_details, ATTR_BYPASSOBJ | ATTR_GLOBAL },
|
||||
{nsGkAtoms::aria_disabled, ATTR_BYPASSOBJ | ATTR_VALTOKEN | ATTR_GLOBAL },
|
||||
{nsGkAtoms::aria_dropeffect, ATTR_VALTOKEN | ATTR_GLOBAL },
|
||||
{nsGkAtoms::aria_errormessage, ATTR_BYPASSOBJ | ATTR_GLOBAL },
|
||||
{nsGkAtoms::aria_expanded, ATTR_BYPASSOBJ | ATTR_VALTOKEN },
|
||||
{nsGkAtoms::aria_flowto, ATTR_BYPASSOBJ | ATTR_GLOBAL },
|
||||
{nsGkAtoms::aria_grabbed, ATTR_VALTOKEN | ATTR_GLOBAL },
|
||||
{nsGkAtoms::aria_haspopup, ATTR_BYPASSOBJ_IF_FALSE | ATTR_VALTOKEN | ATTR_GLOBAL },
|
||||
{nsGkAtoms::aria_hidden, ATTR_BYPASSOBJ | ATTR_VALTOKEN | ATTR_GLOBAL }, /* handled special way */
|
||||
{nsGkAtoms::aria_invalid, ATTR_BYPASSOBJ | ATTR_VALTOKEN | ATTR_GLOBAL },
|
||||
{nsGkAtoms::aria_label, ATTR_BYPASSOBJ | ATTR_GLOBAL },
|
||||
{nsGkAtoms::aria_labelledby, ATTR_BYPASSOBJ | ATTR_GLOBAL },
|
||||
{nsGkAtoms::aria_level, ATTR_BYPASSOBJ }, /* handled via groupPosition */
|
||||
{nsGkAtoms::aria_live, ATTR_VALTOKEN | ATTR_GLOBAL },
|
||||
{nsGkAtoms::aria_modal, ATTR_BYPASSOBJ | ATTR_VALTOKEN | ATTR_GLOBAL },
|
||||
{nsGkAtoms::aria_multiline, ATTR_BYPASSOBJ | ATTR_VALTOKEN },
|
||||
{nsGkAtoms::aria_multiselectable, ATTR_BYPASSOBJ | ATTR_VALTOKEN },
|
||||
{nsGkAtoms::aria_owns, ATTR_BYPASSOBJ | ATTR_GLOBAL },
|
||||
{nsGkAtoms::aria_orientation, ATTR_VALTOKEN },
|
||||
{nsGkAtoms::aria_posinset, ATTR_BYPASSOBJ }, /* handled via groupPosition */
|
||||
{nsGkAtoms::aria_pressed, ATTR_BYPASSOBJ | ATTR_VALTOKEN },
|
||||
{nsGkAtoms::aria_readonly, ATTR_BYPASSOBJ | ATTR_VALTOKEN },
|
||||
{nsGkAtoms::aria_relevant, ATTR_BYPASSOBJ | ATTR_GLOBAL },
|
||||
{nsGkAtoms::aria_required, ATTR_BYPASSOBJ | ATTR_VALTOKEN },
|
||||
{nsGkAtoms::aria_selected, ATTR_BYPASSOBJ | ATTR_VALTOKEN },
|
||||
{nsGkAtoms::aria_setsize, ATTR_BYPASSOBJ }, /* handled via groupPosition */
|
||||
{nsGkAtoms::aria_sort, ATTR_VALTOKEN },
|
||||
{nsGkAtoms::aria_valuenow, ATTR_BYPASSOBJ },
|
||||
{nsGkAtoms::aria_valuemin, ATTR_BYPASSOBJ },
|
||||
{nsGkAtoms::aria_valuemax, ATTR_BYPASSOBJ },
|
||||
{nsGkAtoms::aria_valuetext, ATTR_BYPASSOBJ }
|
||||
};
|
||||
|
||||
namespace {
|
||||
|
@ -1395,7 +1395,7 @@ uint8_t
|
|||
aria::AttrCharacteristicsFor(nsAtom* aAtom)
|
||||
{
|
||||
for (uint32_t i = 0; i < ArrayLength(gWAIUnivAttrMap); i++)
|
||||
if (*gWAIUnivAttrMap[i].attributeName == aAtom)
|
||||
if (gWAIUnivAttrMap[i].attributeName == aAtom)
|
||||
return gWAIUnivAttrMap[i].characteristics;
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -142,7 +142,7 @@ struct nsRoleMapEntry
|
|||
* Return true if matches to the given ARIA role.
|
||||
*/
|
||||
bool Is(nsAtom* aARIARole) const
|
||||
{ return *roleAtom == aARIARole; }
|
||||
{ return roleAtom == aARIARole; }
|
||||
|
||||
/**
|
||||
* Return true if ARIA role has the given accessible type.
|
||||
|
@ -154,10 +154,10 @@ struct nsRoleMapEntry
|
|||
* Return ARIA role.
|
||||
*/
|
||||
const nsDependentAtomString ARIARoleString() const
|
||||
{ return nsDependentAtomString(*roleAtom); }
|
||||
{ return nsDependentAtomString(roleAtom); }
|
||||
|
||||
// ARIA role: string representation such as "button"
|
||||
nsStaticAtom** roleAtom;
|
||||
nsStaticAtom* const roleAtom;
|
||||
|
||||
// Role mapping rule: maps to enum Role
|
||||
mozilla::a11y::role role;
|
||||
|
|
|
@ -24,7 +24,7 @@ struct EnumTypeData
|
|||
|
||||
// States if the attribute value is matched to the enum value. Used as
|
||||
// Element::AttrValuesArray, last item must be nullptr.
|
||||
nsStaticAtom* const* const mValues[4];
|
||||
nsStaticAtom* const mValues[4];
|
||||
|
||||
// States applied if corresponding enum values are matched.
|
||||
const uint64_t mStates[3];
|
||||
|
@ -89,9 +89,9 @@ aria::MapToState(EStateRule aRule, dom::Element* aElement, uint64_t* aState)
|
|||
{
|
||||
static const EnumTypeData data = {
|
||||
nsGkAtoms::aria_autocomplete,
|
||||
{ &nsGkAtoms::inlinevalue,
|
||||
&nsGkAtoms::list_,
|
||||
&nsGkAtoms::both, nullptr },
|
||||
{ nsGkAtoms::inlinevalue,
|
||||
nsGkAtoms::list_,
|
||||
nsGkAtoms::both, nullptr },
|
||||
{ states::SUPPORTS_AUTOCOMPLETION,
|
||||
states::HASPOPUP | states::SUPPORTS_AUTOCOMPLETION,
|
||||
states::HASPOPUP | states::SUPPORTS_AUTOCOMPLETION }, 0
|
||||
|
@ -105,8 +105,8 @@ aria::MapToState(EStateRule aRule, dom::Element* aElement, uint64_t* aState)
|
|||
{
|
||||
static const EnumTypeData data = {
|
||||
nsGkAtoms::aria_busy,
|
||||
{ &nsGkAtoms::_true,
|
||||
&nsGkAtoms::error, nullptr },
|
||||
{ nsGkAtoms::_true,
|
||||
nsGkAtoms::error, nullptr },
|
||||
{ states::BUSY,
|
||||
states::INVALID }, 0
|
||||
};
|
||||
|
@ -229,8 +229,8 @@ aria::MapToState(EStateRule aRule, dom::Element* aElement, uint64_t* aState)
|
|||
{
|
||||
static const EnumTypeData data = {
|
||||
nsGkAtoms::aria_orientation,
|
||||
{ &nsGkAtoms::horizontal,
|
||||
&nsGkAtoms::vertical, nullptr },
|
||||
{ nsGkAtoms::horizontal,
|
||||
nsGkAtoms::vertical, nullptr },
|
||||
{ states::HORIZONTAL,
|
||||
states::VERTICAL },
|
||||
states::HORIZONTAL | states::VERTICAL
|
||||
|
|
|
@ -302,7 +302,7 @@ TextAttrsMgr::InvalidTextAttr::
|
|||
do {
|
||||
if (nsAccUtils::HasDefinedARIAToken(elm, nsGkAtoms::aria_invalid)) {
|
||||
static Element::AttrValuesArray tokens[] =
|
||||
{ &nsGkAtoms::_false, &nsGkAtoms::grammar, &nsGkAtoms::spelling,
|
||||
{ nsGkAtoms::_false, nsGkAtoms::grammar, nsGkAtoms::spelling,
|
||||
nullptr };
|
||||
|
||||
int32_t idx = elm->AsElement()->FindAttrValueIn(kNameSpaceID_None,
|
||||
|
|
|
@ -120,7 +120,7 @@ XULMAP(
|
|||
panel,
|
||||
[](nsIContent* aContent, Accessible* aContext) -> Accessible* {
|
||||
static const Element::AttrValuesArray sIgnoreTypeVals[] =
|
||||
{ &nsGkAtoms::autocomplete_richlistbox, &nsGkAtoms::autocomplete, nullptr };
|
||||
{ nsGkAtoms::autocomplete_richlistbox, nsGkAtoms::autocomplete, nullptr };
|
||||
|
||||
if (!aContent->IsElement() ||
|
||||
aContent->AsElement()->FindAttrValueIn(kNameSpaceID_None, nsGkAtoms::type,
|
||||
|
|
|
@ -208,20 +208,19 @@ nsAccUtils::HasDefinedARIAToken(nsIContent *aContent, nsAtom *aAtom)
|
|||
return true;
|
||||
}
|
||||
|
||||
nsAtom*
|
||||
nsStaticAtom*
|
||||
nsAccUtils::GetARIAToken(dom::Element* aElement, nsAtom* aAttr)
|
||||
{
|
||||
if (!HasDefinedARIAToken(aElement, aAttr))
|
||||
return nsGkAtoms::_empty;
|
||||
|
||||
static Element::AttrValuesArray tokens[] =
|
||||
{ &nsGkAtoms::_false, &nsGkAtoms::_true,
|
||||
&nsGkAtoms::mixed, nullptr};
|
||||
{ nsGkAtoms::_false, nsGkAtoms::_true, nsGkAtoms::mixed, nullptr};
|
||||
|
||||
int32_t idx = aElement->FindAttrValueIn(kNameSpaceID_None,
|
||||
aAttr, tokens, eCaseMatters);
|
||||
if (idx >= 0)
|
||||
return *(tokens[idx]);
|
||||
return tokens[idx];
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
@ -101,7 +101,8 @@ public:
|
|||
/**
|
||||
* Return atomic value of ARIA attribute of boolean or NMTOKEN type.
|
||||
*/
|
||||
static nsAtom* GetARIAToken(mozilla::dom::Element* aElement, nsAtom* aAttr);
|
||||
static nsStaticAtom* GetARIAToken(mozilla::dom::Element* aElement,
|
||||
nsAtom* aAttr);
|
||||
|
||||
/**
|
||||
* Return document accessible for the given DOM node.
|
||||
|
|
|
@ -304,16 +304,16 @@ static int32_t sPlatformDisabledState = 0;
|
|||
// Markup maps array.
|
||||
|
||||
#define Attr(name, value) \
|
||||
{ &nsGkAtoms::name, &nsGkAtoms::value }
|
||||
{ nsGkAtoms::name, nsGkAtoms::value }
|
||||
|
||||
#define AttrFromDOM(name, DOMAttrName) \
|
||||
{ &nsGkAtoms::name, nullptr, &nsGkAtoms::DOMAttrName }
|
||||
{ nsGkAtoms::name, nullptr, nsGkAtoms::DOMAttrName }
|
||||
|
||||
#define AttrFromDOMIf(name, DOMAttrName, DOMAttrValue) \
|
||||
{ &nsGkAtoms::name, nullptr, &nsGkAtoms::DOMAttrName, &nsGkAtoms::DOMAttrValue }
|
||||
{ nsGkAtoms::name, nullptr, nsGkAtoms::DOMAttrName, nsGkAtoms::DOMAttrValue }
|
||||
|
||||
#define MARKUPMAP(atom, new_func, r, ... ) \
|
||||
{ &nsGkAtoms::atom, new_func, static_cast<a11y::role>(r), { __VA_ARGS__ } },
|
||||
{ nsGkAtoms::atom, new_func, static_cast<a11y::role>(r), { __VA_ARGS__ } },
|
||||
|
||||
static const HTMLMarkupMapInfo sHTMLMarkupMapList[] = {
|
||||
#include "MarkupMap.h"
|
||||
|
@ -323,7 +323,7 @@ static const HTMLMarkupMapInfo sHTMLMarkupMapList[] = {
|
|||
|
||||
#ifdef MOZ_XUL
|
||||
#define XULMAP(atom, ...) \
|
||||
{ &nsGkAtoms::atom, __VA_ARGS__ },
|
||||
{ nsGkAtoms::atom, __VA_ARGS__ },
|
||||
|
||||
#define XULMAP_TYPE(atom, new_type) \
|
||||
XULMAP( \
|
||||
|
@ -1350,11 +1350,11 @@ nsAccessibilityService::Init()
|
|||
eventListenerService->AddListenerChangeListener(this);
|
||||
|
||||
for (uint32_t i = 0; i < ArrayLength(sHTMLMarkupMapList); i++)
|
||||
mHTMLMarkupMap.Put(*sHTMLMarkupMapList[i].tag, &sHTMLMarkupMapList[i]);
|
||||
mHTMLMarkupMap.Put(sHTMLMarkupMapList[i].tag, &sHTMLMarkupMapList[i]);
|
||||
|
||||
#ifdef MOZ_XUL
|
||||
for (uint32_t i = 0; i < ArrayLength(sXULMarkupMapList); i++)
|
||||
mXULMarkupMap.Put(*sXULMarkupMapList[i].tag, &sXULMarkupMapList[i]);
|
||||
mXULMarkupMap.Put(sXULMarkupMapList[i].tag, &sXULMarkupMapList[i]);
|
||||
#endif
|
||||
|
||||
#ifdef A11Y_LOG
|
||||
|
@ -1616,10 +1616,10 @@ nsAccessibilityService::MarkupAttributes(const nsIContent* aContent,
|
|||
if (info->DOMAttrValue) {
|
||||
if (aContent->IsElement() &&
|
||||
aContent->AsElement()->AttrValueIs(kNameSpaceID_None,
|
||||
*info->DOMAttrName,
|
||||
*info->DOMAttrValue,
|
||||
info->DOMAttrName,
|
||||
info->DOMAttrValue,
|
||||
eCaseMatters)) {
|
||||
nsAccUtils::SetAccAttr(aAttributes, *info->name, *info->DOMAttrValue);
|
||||
nsAccUtils::SetAccAttr(aAttributes, info->name, info->DOMAttrValue);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
@ -1627,16 +1627,16 @@ nsAccessibilityService::MarkupAttributes(const nsIContent* aContent,
|
|||
nsAutoString value;
|
||||
|
||||
if (aContent->IsElement()) {
|
||||
aContent->AsElement()->GetAttr(kNameSpaceID_None, *info->DOMAttrName, value);
|
||||
aContent->AsElement()->GetAttr(kNameSpaceID_None, info->DOMAttrName, value);
|
||||
}
|
||||
|
||||
if (!value.IsEmpty())
|
||||
nsAccUtils::SetAccAttr(aAttributes, *info->name, value);
|
||||
nsAccUtils::SetAccAttr(aAttributes, info->name, value);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
nsAccUtils::SetAccAttr(aAttributes, *info->name, *info->value);
|
||||
nsAccUtils::SetAccAttr(aAttributes, info->name, info->value);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -53,16 +53,17 @@ xpcAccessibleApplication* XPCApplicationAcc();
|
|||
|
||||
typedef Accessible* (New_Accessible)(nsIContent* aContent, Accessible* aContext);
|
||||
|
||||
// These fields are not `nsStaticAtom* const` because MSVC doesn't like it.
|
||||
struct MarkupAttrInfo {
|
||||
nsStaticAtom** name;
|
||||
nsStaticAtom** value;
|
||||
nsStaticAtom* name;
|
||||
nsStaticAtom* value;
|
||||
|
||||
nsStaticAtom** DOMAttrName;
|
||||
nsStaticAtom** DOMAttrValue;
|
||||
nsStaticAtom* DOMAttrName;
|
||||
nsStaticAtom* DOMAttrValue;
|
||||
};
|
||||
|
||||
struct HTMLMarkupMapInfo {
|
||||
nsStaticAtom** tag;
|
||||
const nsStaticAtom* const tag;
|
||||
New_Accessible* new_func;
|
||||
a11y::role role;
|
||||
MarkupAttrInfo attrs[4];
|
||||
|
@ -70,7 +71,7 @@ struct HTMLMarkupMapInfo {
|
|||
|
||||
#ifdef MOZ_XUL
|
||||
struct XULMarkupMapInfo {
|
||||
nsStaticAtom** tag;
|
||||
const nsStaticAtom* const tag;
|
||||
New_Accessible* new_func;
|
||||
};
|
||||
#endif
|
||||
|
|
|
@ -1492,8 +1492,9 @@ nsAtom*
|
|||
Accessible::LandmarkRole() const
|
||||
{
|
||||
const nsRoleMapEntry* roleMapEntry = ARIARoleMap();
|
||||
return roleMapEntry && roleMapEntry->IsOfType(eLandmark) ?
|
||||
*(roleMapEntry->roleAtom) : nullptr;
|
||||
return roleMapEntry && roleMapEntry->IsOfType(eLandmark)
|
||||
? roleMapEntry->roleAtom
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
role
|
||||
|
|
|
@ -54,17 +54,17 @@ using namespace mozilla::a11y;
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Static member initialization
|
||||
|
||||
static nsStaticAtom** kRelationAttrs[] =
|
||||
static nsStaticAtom* const kRelationAttrs[] =
|
||||
{
|
||||
&nsGkAtoms::aria_labelledby,
|
||||
&nsGkAtoms::aria_describedby,
|
||||
&nsGkAtoms::aria_details,
|
||||
&nsGkAtoms::aria_owns,
|
||||
&nsGkAtoms::aria_controls,
|
||||
&nsGkAtoms::aria_flowto,
|
||||
&nsGkAtoms::aria_errormessage,
|
||||
&nsGkAtoms::_for,
|
||||
&nsGkAtoms::control
|
||||
nsGkAtoms::aria_labelledby,
|
||||
nsGkAtoms::aria_describedby,
|
||||
nsGkAtoms::aria_details,
|
||||
nsGkAtoms::aria_owns,
|
||||
nsGkAtoms::aria_controls,
|
||||
nsGkAtoms::aria_flowto,
|
||||
nsGkAtoms::aria_errormessage,
|
||||
nsGkAtoms::_for,
|
||||
nsGkAtoms::control
|
||||
};
|
||||
|
||||
static const uint32_t kRelationAttrsLen = ArrayLength(kRelationAttrs);
|
||||
|
@ -1557,7 +1557,7 @@ DocAccessible::AddDependentIDsFor(Accessible* aRelProvider, nsAtom* aRelAttr)
|
|||
return;
|
||||
|
||||
for (uint32_t idx = 0; idx < kRelationAttrsLen; idx++) {
|
||||
nsAtom* relAttr = *kRelationAttrs[idx];
|
||||
nsStaticAtom* relAttr = kRelationAttrs[idx];
|
||||
if (aRelAttr && aRelAttr != relAttr)
|
||||
continue;
|
||||
|
||||
|
@ -1629,8 +1629,8 @@ DocAccessible::RemoveDependentIDsFor(Accessible* aRelProvider,
|
|||
return;
|
||||
|
||||
for (uint32_t idx = 0; idx < kRelationAttrsLen; idx++) {
|
||||
nsAtom* relAttr = *kRelationAttrs[idx];
|
||||
if (aRelAttr && aRelAttr != *kRelationAttrs[idx])
|
||||
nsStaticAtom* relAttr = kRelationAttrs[idx];
|
||||
if (aRelAttr && aRelAttr != kRelationAttrs[idx])
|
||||
continue;
|
||||
|
||||
IDRefsIterator iter(this, relProviderElm, relAttr);
|
||||
|
|
|
@ -311,8 +311,8 @@ HTMLTableHeaderCellAccessible::NativeRole()
|
|||
{
|
||||
// Check value of @scope attribute.
|
||||
static Element::AttrValuesArray scopeValues[] =
|
||||
{ &nsGkAtoms::col, &nsGkAtoms::colgroup,
|
||||
&nsGkAtoms::row, &nsGkAtoms::rowgroup, nullptr };
|
||||
{ nsGkAtoms::col, nsGkAtoms::colgroup,
|
||||
nsGkAtoms::row, nsGkAtoms::rowgroup, nullptr };
|
||||
int32_t valueIdx =
|
||||
mContent->AsElement()->FindAttrValueIn(kNameSpaceID_None, nsGkAtoms::scope,
|
||||
scopeValues, eCaseMatters);
|
||||
|
|
|
@ -62,7 +62,7 @@ bool IsSearchbox() const;
|
|||
|
||||
nsAtom* LandmarkRole() const;
|
||||
|
||||
nsAtom* ARIARoleAtom() const;
|
||||
nsStaticAtom* ARIARoleAtom() const;
|
||||
|
||||
int32_t GetLevelInternal();
|
||||
void ScrollTo(uint32_t aScrollType);
|
||||
|
|
|
@ -293,7 +293,7 @@ DocAccessibleChild::RecvARIARoleAtom(const uint64_t& aID, nsString* aRole)
|
|||
}
|
||||
|
||||
if (const nsRoleMapEntry* roleMap = acc->ARIARoleMap()) {
|
||||
if (nsAtom* roleAtom = *(roleMap->roleAtom)) {
|
||||
if (nsStaticAtom* roleAtom = roleMap->roleAtom) {
|
||||
roleAtom->ToString(*aRole);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -127,7 +127,7 @@ ProxyAccessible::LandmarkRole() const
|
|||
return NS_GetStaticAtom(landmark);
|
||||
}
|
||||
|
||||
nsAtom*
|
||||
nsStaticAtom*
|
||||
ProxyAccessible::ARIARoleAtom() const
|
||||
{
|
||||
nsString role;
|
||||
|
|
|
@ -770,10 +770,10 @@ ConvertToNSArray(nsTArray<ProxyAccessible*>& aArray)
|
|||
return @"AXLandmarkRegion";
|
||||
|
||||
// Now, deal with widget roles
|
||||
nsAtom* roleAtom = nullptr;
|
||||
nsStaticAtom* roleAtom = nullptr;
|
||||
if (accWrap && accWrap->HasARIARole()) {
|
||||
const nsRoleMapEntry* roleMap = accWrap->ARIARoleMap();
|
||||
roleAtom = *roleMap->roleAtom;
|
||||
roleAtom = roleMap->roleAtom;
|
||||
}
|
||||
if (proxy)
|
||||
roleAtom = proxy->ARIARoleAtom();
|
||||
|
|
|
@ -193,7 +193,7 @@ bool
|
|||
XULButtonAccessible::ContainsMenu() const
|
||||
{
|
||||
static Element::AttrValuesArray strings[] =
|
||||
{&nsGkAtoms::menu, &nsGkAtoms::menuButton, nullptr};
|
||||
{nsGkAtoms::menu, nsGkAtoms::menuButton, nullptr};
|
||||
|
||||
return mContent->AsElement()->FindAttrValueIn(kNameSpaceID_None,
|
||||
nsGkAtoms::type,
|
||||
|
|
|
@ -60,7 +60,7 @@ XULMenuitemAccessible::NativeState()
|
|||
|
||||
// Checkable/checked?
|
||||
static Element::AttrValuesArray strings[] =
|
||||
{ &nsGkAtoms::radio, &nsGkAtoms::checkbox, nullptr };
|
||||
{ nsGkAtoms::radio, nsGkAtoms::checkbox, nullptr };
|
||||
|
||||
if (mContent->AsElement()->FindAttrValueIn(kNameSpaceID_None, nsGkAtoms::type,
|
||||
strings, eCaseMatters) >= 0) {
|
||||
|
|
|
@ -369,6 +369,9 @@
|
|||
// set the checkbox
|
||||
checkbox.checked = !!options.automatic;
|
||||
}
|
||||
if (options && options.hideAddExceptionButton) {
|
||||
document.querySelector(".exceptionDialogButtonContainer").hidden = true;
|
||||
}
|
||||
}, true, true);
|
||||
|
||||
let event = new CustomEvent("AboutNetErrorLoad", {bubbles: true});
|
||||
|
|
|
@ -543,6 +543,8 @@ var LightWeightThemeWebInstaller = {
|
|||
mm.addMessageListener("LightWeightThemeWebInstaller:Install", this);
|
||||
mm.addMessageListener("LightWeightThemeWebInstaller:Preview", this);
|
||||
mm.addMessageListener("LightWeightThemeWebInstaller:ResetPreview", this);
|
||||
|
||||
XPCOMUtils.defineLazyPreferenceGetter(this, "_apiTesting", "extensions.webapi.testing", false);
|
||||
},
|
||||
|
||||
receiveMessage(message) {
|
||||
|
@ -555,15 +557,15 @@ var LightWeightThemeWebInstaller = {
|
|||
|
||||
switch (message.name) {
|
||||
case "LightWeightThemeWebInstaller:Install": {
|
||||
this._installRequest(data.themeData, data.baseURI);
|
||||
this._installRequest(data.themeData, data.principal, data.baseURI);
|
||||
break;
|
||||
}
|
||||
case "LightWeightThemeWebInstaller:Preview": {
|
||||
this._preview(data.themeData, data.baseURI);
|
||||
this._preview(data.themeData, data.principal, data.baseURI);
|
||||
break;
|
||||
}
|
||||
case "LightWeightThemeWebInstaller:ResetPreview": {
|
||||
this._resetPreview(data && data.baseURI);
|
||||
this._resetPreview(data && data.principal);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -585,33 +587,24 @@ var LightWeightThemeWebInstaller = {
|
|||
return this._manager = temp.LightweightThemeManager;
|
||||
},
|
||||
|
||||
_installRequest(dataString, baseURI) {
|
||||
_installRequest(dataString, principal, baseURI) {
|
||||
// Don't allow installing off null principals.
|
||||
if (!principal.URI) {
|
||||
return;
|
||||
}
|
||||
|
||||
let data = this._manager.parseTheme(dataString, baseURI);
|
||||
|
||||
if (!data) {
|
||||
return;
|
||||
}
|
||||
|
||||
let uri = makeURI(baseURI);
|
||||
|
||||
// A notification bar with the option to undo is normally shown after a
|
||||
// theme is installed. But the discovery pane served from the url(s)
|
||||
// below has its own toggle switch for quick undos, so don't show the
|
||||
// notification in that case.
|
||||
let notify = uri.prePath != "https://discovery.addons.mozilla.org";
|
||||
if (notify) {
|
||||
try {
|
||||
if (Services.prefs.getBoolPref("extensions.webapi.testing")
|
||||
&& (uri.prePath == "https://discovery.addons.allizom.org"
|
||||
|| uri.prePath == "https://discovery.addons-dev.allizom.org")) {
|
||||
notify = false;
|
||||
}
|
||||
} catch (e) {
|
||||
// getBoolPref() throws if the testing pref isn't set. ignore it.
|
||||
}
|
||||
}
|
||||
|
||||
if (this._isAllowed(baseURI)) {
|
||||
let notify = this._shouldShowUndoPrompt(principal);
|
||||
if (this._isAllowed(principal)) {
|
||||
this._install(data, notify);
|
||||
return;
|
||||
}
|
||||
|
@ -620,7 +613,7 @@ var LightWeightThemeWebInstaller = {
|
|||
header: gNavigatorBundle.getFormattedString("webextPerms.header", ["<>"]),
|
||||
addonName: data.name,
|
||||
text: gNavigatorBundle.getFormattedString("lwthemeInstallRequest.message2",
|
||||
[uri.host]),
|
||||
[principal.URI.host]),
|
||||
acceptText: gNavigatorBundle.getString("lwthemeInstallRequest.allowButton2"),
|
||||
acceptKey: gNavigatorBundle.getString("lwthemeInstallRequest.allowButton.accesskey2"),
|
||||
cancelText: gNavigatorBundle.getString("webextPerms.cancel.label"),
|
||||
|
@ -649,8 +642,8 @@ var LightWeightThemeWebInstaller = {
|
|||
AddonManager.removeAddonListener(listener);
|
||||
},
|
||||
|
||||
_preview(dataString, baseURI) {
|
||||
if (!this._isAllowed(baseURI))
|
||||
_preview(dataString, principal, baseURI) {
|
||||
if (!this._isAllowed(principal))
|
||||
return;
|
||||
|
||||
let data = this._manager.parseTheme(dataString, baseURI);
|
||||
|
@ -662,27 +655,37 @@ var LightWeightThemeWebInstaller = {
|
|||
this._manager.previewTheme(data);
|
||||
},
|
||||
|
||||
_resetPreview(baseURI) {
|
||||
if (baseURI && !this._isAllowed(baseURI))
|
||||
_resetPreview(principal) {
|
||||
if (!this._isAllowed(principal))
|
||||
return;
|
||||
gBrowser.tabContainer.removeEventListener("TabSelect", this);
|
||||
this._manager.resetPreview();
|
||||
},
|
||||
|
||||
_isAllowed(srcURIString) {
|
||||
let uri;
|
||||
try {
|
||||
uri = makeURI(srcURIString);
|
||||
} catch (e) {
|
||||
// makeURI fails if srcURIString is a nonsense URI
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!uri.schemeIs("https")) {
|
||||
_isAllowed(principal) {
|
||||
if (!principal || !principal.URI || !principal.URI.schemeIs("https")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let pm = Services.perms;
|
||||
return pm.testPermission(uri, "install") == pm.ALLOW_ACTION;
|
||||
}
|
||||
return pm.testPermission(principal.URI, "install") == pm.ALLOW_ACTION;
|
||||
},
|
||||
|
||||
_shouldShowUndoPrompt(principal) {
|
||||
if (!principal || !principal.URI) {
|
||||
return true;
|
||||
}
|
||||
|
||||
let prePath = principal.URI.prePath;
|
||||
if (prePath == "https://discovery.addons.mozilla.org") {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this._apiTesting && (prePath == "https://discovery.addons.allizom.org" ||
|
||||
prePath == "https://discovery.addons-dev.allizom.org")) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
|
||||
};
|
||||
|
|
|
@ -653,8 +653,12 @@ var AboutNetAndCertErrorListener = {
|
|||
// Values for telemtery bins: see TLS_ERROR_REPORT_UI in Histograms.json
|
||||
const TLS_ERROR_REPORT_TELEMETRY_UI_SHOWN = 0;
|
||||
|
||||
let hideAddExceptionButton = false;
|
||||
|
||||
if (this.isAboutCertError(win.document)) {
|
||||
ClickEventHandler.onCertError(originalTarget, win);
|
||||
hideAddExceptionButton =
|
||||
Services.prefs.getBoolPref("security.certerror.hideAddException", false);
|
||||
}
|
||||
if (this.isAboutNetError(win.document)) {
|
||||
let docShell = win.document.docShell;
|
||||
|
@ -676,7 +680,8 @@ var AboutNetAndCertErrorListener = {
|
|||
detail: JSON.stringify({
|
||||
enabled: Services.prefs.getBoolPref("security.ssl.errorReporting.enabled"),
|
||||
changedCertPrefs: this.changedCertPrefs(),
|
||||
automatic
|
||||
automatic,
|
||||
hideAddExceptionButton,
|
||||
})
|
||||
}));
|
||||
|
||||
|
@ -1003,6 +1008,7 @@ var LightWeightThemeWebInstallListener = {
|
|||
case "InstallBrowserTheme": {
|
||||
sendAsyncMessage("LightWeightThemeWebInstaller:Install", {
|
||||
baseURI: event.target.baseURI,
|
||||
principal: event.target.nodePrincipal,
|
||||
themeData: event.target.getAttribute("data-browsertheme"),
|
||||
});
|
||||
break;
|
||||
|
@ -1010,6 +1016,7 @@ var LightWeightThemeWebInstallListener = {
|
|||
case "PreviewBrowserTheme": {
|
||||
sendAsyncMessage("LightWeightThemeWebInstaller:Preview", {
|
||||
baseURI: event.target.baseURI,
|
||||
principal: event.target.nodePrincipal,
|
||||
themeData: event.target.getAttribute("data-browsertheme"),
|
||||
});
|
||||
this._previewWindow = event.target.ownerGlobal;
|
||||
|
@ -1024,7 +1031,7 @@ var LightWeightThemeWebInstallListener = {
|
|||
case "ResetBrowserThemePreview": {
|
||||
if (this._previewWindow) {
|
||||
sendAsyncMessage("LightWeightThemeWebInstaller:ResetPreview",
|
||||
{baseURI: event.target.baseURI});
|
||||
{principal: event.target.nodePrincipal});
|
||||
this._resetPreviewWindow();
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -290,6 +290,9 @@ add_task(async function checkAdvancedDetails() {
|
|||
ok(shortDescText.textContent.includes("expired.example.com"),
|
||||
"Should list hostname in error message.");
|
||||
|
||||
let exceptionButton = doc.getElementById("exceptionDialogButton");
|
||||
ok(!exceptionButton.disabled, "Exception button is not disabled by default.");
|
||||
|
||||
let advancedButton = doc.getElementById("advancedButton");
|
||||
advancedButton.click();
|
||||
let el = doc.getElementById("errorCode");
|
||||
|
@ -334,6 +337,27 @@ add_task(async function checkAdvancedDetails() {
|
|||
}
|
||||
});
|
||||
|
||||
add_task(async function checkhideAddExceptionButton() {
|
||||
info("Loading a bad cert page and verifying the pref security.certerror.hideAddException");
|
||||
Services.prefs.setBoolPref("security.certerror.hideAddException", true);
|
||||
|
||||
for (let useFrame of [false, true]) {
|
||||
let tab = await openErrorPage(BAD_CERT, useFrame);
|
||||
let browser = tab.linkedBrowser;
|
||||
|
||||
await ContentTask.spawn(browser, {frame: useFrame}, async function({frame}) {
|
||||
let doc = frame ? content.document.querySelector("iframe").contentDocument : content.document;
|
||||
|
||||
let exceptionButton = doc.querySelector(".exceptionDialogButtonContainer");
|
||||
ok(exceptionButton.hidden, "Exception button is hidden.");
|
||||
});
|
||||
|
||||
BrowserTestUtils.removeTab(gBrowser.selectedTab);
|
||||
}
|
||||
|
||||
Services.prefs.clearUserPref("security.certerror.hideAddException");
|
||||
});
|
||||
|
||||
add_task(async function checkAdvancedDetailsForHSTS() {
|
||||
info("Loading a bad STS cert page and verifying the advanced details section");
|
||||
for (let useFrame of [false, true]) {
|
||||
|
|
|
@ -804,7 +804,6 @@ if (Services.prefs.getBoolPref("privacy.panicButton.enabled")) {
|
|||
id: "panic-button",
|
||||
type: "view",
|
||||
viewId: "PanelUI-panicView",
|
||||
disabled: !Services.policies.isAllowed("panicButton"),
|
||||
|
||||
forgetButtonCalled(aEvent) {
|
||||
let doc = aEvent.target.ownerDocument;
|
||||
|
|
|
@ -260,7 +260,7 @@ var Policies = {
|
|||
"DisableForgetButton": {
|
||||
onProfileAfterChange(manager, param) {
|
||||
if (param) {
|
||||
manager.disallowFeature("panicButton");
|
||||
setAndLockPref("privacy.panicButton.enabled", false);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -310,6 +310,10 @@ var Policies = {
|
|||
|
||||
"DisableSecurityBypass": {
|
||||
onBeforeUIStartup(manager, param) {
|
||||
if ("InvalidCertificate" in param) {
|
||||
setAndLockPref("security.certerror.hideAddException", param.InvalidCertificate);
|
||||
}
|
||||
|
||||
if ("SafeBrowsing" in param) {
|
||||
setAndLockPref("browser.safebrowsing.allowOverride", !param.SafeBrowsing);
|
||||
}
|
||||
|
@ -519,6 +523,9 @@ var Policies = {
|
|||
}
|
||||
if ("Default" in param) {
|
||||
setAndLockPref("xpinstall.enabled", param.Default);
|
||||
if (!param.Default) {
|
||||
manager.disallowFeature("about:debugging");
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -582,6 +589,22 @@ var Policies = {
|
|||
}
|
||||
},
|
||||
|
||||
"SanitizeOnShutdown": {
|
||||
onBeforeUIStartup(manager, param) {
|
||||
setAndLockPref("privacy.sanitize.sanitizeOnShutdown", param);
|
||||
if (param) {
|
||||
setAndLockPref("privacy.clearOnShutdown.cache", true);
|
||||
setAndLockPref("privacy.clearOnShutdown.cookies", true);
|
||||
setAndLockPref("privacy.clearOnShutdown.downloads", true);
|
||||
setAndLockPref("privacy.clearOnShutdown.formdata", true);
|
||||
setAndLockPref("privacy.clearOnShutdown.history", true);
|
||||
setAndLockPref("privacy.clearOnShutdown.sessions", true);
|
||||
setAndLockPref("privacy.clearOnShutdown.siteSettings", true);
|
||||
setAndLockPref("privacy.clearOnShutdown.offlineApps", true);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"SearchBar": {
|
||||
onAllWindowsRestored(manager, param) {
|
||||
// This policy is meant to change the default behavior, not to force it.
|
||||
|
|
|
@ -254,6 +254,10 @@
|
|||
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"InvalidCertificate": {
|
||||
"type": "boolean"
|
||||
},
|
||||
|
||||
"SafeBrowsing": {
|
||||
"type": "boolean"
|
||||
}
|
||||
|
@ -523,6 +527,13 @@
|
|||
"type": "boolean"
|
||||
},
|
||||
|
||||
"SanitizeOnShutdown": {
|
||||
"description": "Clears ALL browser data on shutdown.",
|
||||
"first_available": "60.0",
|
||||
|
||||
"type": "boolean"
|
||||
},
|
||||
|
||||
"SearchBar": {
|
||||
"description": "Sets the default location of the search bar. Only applies on firtrun, but can be changed.",
|
||||
"first_available": "60.0",
|
||||
|
|
|
@ -43,10 +43,14 @@ const POLICIES_TESTS = [
|
|||
{
|
||||
policies: {
|
||||
"DisableSecurityBypass": {
|
||||
"InvalidCertificate": true,
|
||||
"SafeBrowsing": true
|
||||
}
|
||||
},
|
||||
lockedPrefs: { "browser.safebrowsing.allowOverride": false },
|
||||
lockedPrefs: {
|
||||
"security.certerror.hideAddException": true,
|
||||
"browser.safebrowsing.allowOverride": false,
|
||||
},
|
||||
},
|
||||
|
||||
|
||||
|
@ -126,6 +130,24 @@ const POLICIES_TESTS = [
|
|||
"xpinstall.enabled": false,
|
||||
}
|
||||
},
|
||||
|
||||
// POLICY: SanitizeOnShutdown
|
||||
{
|
||||
policies: {
|
||||
"SanitizeOnShutdown": true,
|
||||
},
|
||||
lockedPrefs: {
|
||||
"privacy.sanitize.sanitizeOnShutdown": true,
|
||||
"privacy.clearOnShutdown.cache": true,
|
||||
"privacy.clearOnShutdown.cookies": true,
|
||||
"privacy.clearOnShutdown.downloads": true,
|
||||
"privacy.clearOnShutdown.formdata": true,
|
||||
"privacy.clearOnShutdown.history": true,
|
||||
"privacy.clearOnShutdown.sessions": true,
|
||||
"privacy.clearOnShutdown.siteSettings": true,
|
||||
"privacy.clearOnShutdown.offlineApps": true,
|
||||
}
|
||||
},
|
||||
];
|
||||
|
||||
add_task(async function test_policy_remember_passwords() {
|
||||
|
|
|
@ -5,5 +5,5 @@
|
|||
|
||||
add_task(async function test_policy_disable_forget_button() {
|
||||
let widget = CustomizableUI.getWidget("panic-button");
|
||||
is(widget.disabled, true, "Forget Button is disabled");
|
||||
isnot(widget.type, "view", "Forget Button was not created");
|
||||
});
|
||||
|
|
|
@ -11,7 +11,7 @@ this.devtools_inspectedWindow = class extends ExtensionAPI {
|
|||
// Lazily retrieved inspectedWindow actor front per child context.
|
||||
let waitForInspectedWindowFront;
|
||||
|
||||
// TODO - Bug 1448878: retrive a more detailed callerInfo object,
|
||||
// TODO - Bug 1448878: retrieve a more detailed callerInfo object,
|
||||
// like the filename and lineNumber of the actual extension called
|
||||
// in the child process.
|
||||
const callerInfo = {
|
||||
|
|
|
@ -505,7 +505,7 @@ this.devtools_panels = class extends ExtensionAPI {
|
|||
// (used by Sidebar.setExpression).
|
||||
let waitForInspectedWindowFront;
|
||||
|
||||
// TODO - Bug 1448878: retrive a more detailed callerInfo object,
|
||||
// TODO - Bug 1448878: retrieve a more detailed callerInfo object,
|
||||
// like the filename and lineNumber of the actual extension called
|
||||
// in the child process.
|
||||
const callerInfo = {
|
||||
|
|
|
@ -98,7 +98,7 @@ this.find = class extends ExtensionAPI {
|
|||
|
||||
/**
|
||||
* browser.find.removeHighlighting
|
||||
* Removes all hightlighting from previous search.
|
||||
* Removes all highlighting from previous search.
|
||||
*
|
||||
* @param {number} tabId optional
|
||||
* Tab to clear highlighting in. Defaults to the active tab.
|
||||
|
|
|
@ -73,10 +73,10 @@ add_task(async function test_overrides_update_removal() {
|
|||
|
||||
equal(extension.version, "1.0", "The installed addon has the expected version.");
|
||||
ok(getHomePageURL().endsWith(HOMEPAGE_URI),
|
||||
"Home page url is overriden by the extension.");
|
||||
"Home page url is overridden by the extension.");
|
||||
equal(Services.search.currentEngine.name,
|
||||
"DuckDuckGo",
|
||||
"Default engine is overriden by the extension");
|
||||
"Default engine is overridden by the extension");
|
||||
|
||||
extensionInfo.manifest = {
|
||||
"version": "2.0",
|
||||
|
|
|
@ -111,7 +111,7 @@ add_task(async function test_multiple_extensions_overriding_newtab_page() {
|
|||
|
||||
await ext2.startup();
|
||||
ok(aboutNewTabService.newTabURL.endsWith(NEWTAB_URI_2),
|
||||
"newTabURL is overriden by the second extension.");
|
||||
"newTabURL is overridden by the second extension.");
|
||||
await checkNewTabPageOverride(ext1, NEWTAB_URI_2, CONTROLLED_BY_OTHER);
|
||||
|
||||
// Verify that calling set and clear do nothing.
|
||||
|
@ -137,17 +137,17 @@ add_task(async function test_multiple_extensions_overriding_newtab_page() {
|
|||
addon.userDisabled = false;
|
||||
await enabledPromise;
|
||||
ok(aboutNewTabService.newTabURL.endsWith(NEWTAB_URI_2),
|
||||
"newTabURL is overriden by the second extension.");
|
||||
"newTabURL is overridden by the second extension.");
|
||||
await checkNewTabPageOverride(ext2, NEWTAB_URI_2, CONTROLLED_BY_THIS);
|
||||
|
||||
await ext1.unload();
|
||||
ok(aboutNewTabService.newTabURL.endsWith(NEWTAB_URI_2),
|
||||
"newTabURL is still overriden by the second extension.");
|
||||
"newTabURL is still overridden by the second extension.");
|
||||
await checkNewTabPageOverride(ext2, NEWTAB_URI_2, CONTROLLED_BY_THIS);
|
||||
|
||||
await ext3.startup();
|
||||
ok(aboutNewTabService.newTabURL.endsWith(NEWTAB_URI_3),
|
||||
"newTabURL is overriden by the third extension.");
|
||||
"newTabURL is overridden by the third extension.");
|
||||
await checkNewTabPageOverride(ext2, NEWTAB_URI_3, CONTROLLED_BY_OTHER);
|
||||
|
||||
// Disable the second extension.
|
||||
|
@ -155,7 +155,7 @@ add_task(async function test_multiple_extensions_overriding_newtab_page() {
|
|||
addon.userDisabled = true;
|
||||
await disabledPromise;
|
||||
ok(aboutNewTabService.newTabURL.endsWith(NEWTAB_URI_3),
|
||||
"newTabURL is still overriden by the third extension.");
|
||||
"newTabURL is still overridden by the third extension.");
|
||||
await checkNewTabPageOverride(ext3, NEWTAB_URI_3, CONTROLLED_BY_THIS);
|
||||
|
||||
// Re-enable the second extension.
|
||||
|
@ -163,12 +163,12 @@ add_task(async function test_multiple_extensions_overriding_newtab_page() {
|
|||
addon.userDisabled = false;
|
||||
await enabledPromise;
|
||||
ok(aboutNewTabService.newTabURL.endsWith(NEWTAB_URI_3),
|
||||
"newTabURL is still overriden by the third extension.");
|
||||
"newTabURL is still overridden by the third extension.");
|
||||
await checkNewTabPageOverride(ext3, NEWTAB_URI_3, CONTROLLED_BY_THIS);
|
||||
|
||||
await ext3.unload();
|
||||
ok(aboutNewTabService.newTabURL.endsWith(NEWTAB_URI_2),
|
||||
"newTabURL reverts to being overriden by the second extension.");
|
||||
"newTabURL reverts to being overridden by the second extension.");
|
||||
await checkNewTabPageOverride(ext2, NEWTAB_URI_2, CONTROLLED_BY_THIS);
|
||||
|
||||
await ext2.unload();
|
||||
|
|
|
@ -97,7 +97,7 @@ add_task(async function test_url_overrides_newtab_update() {
|
|||
|
||||
equal(extension.version, "1.0", "The installed addon has the expected version.");
|
||||
ok(aboutNewTabService.newTabURL.endsWith(NEWTAB_URI),
|
||||
"Newtab url is overriden by the extension.");
|
||||
"Newtab url is overridden by the extension.");
|
||||
|
||||
let update = await promiseFindAddonUpdates(extension.addon);
|
||||
let install = update.updateAvailable;
|
||||
|
|
|
@ -213,9 +213,6 @@ function openBrowserWindow(cmdLine, urlOrUrlList, postData = null,
|
|||
win.document.documentElement.removeAttribute("windowtype");
|
||||
|
||||
if (forcePrivate) {
|
||||
// This causes a "Only internal code is allowed to set the
|
||||
// usePrivateBrowsing attribute" warning in the Browser Console.
|
||||
// Still better than having a white window that flickers.
|
||||
win.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIWebNavigation)
|
||||
.QueryInterface(Ci.nsILoadContext)
|
||||
|
@ -418,6 +415,15 @@ nsBrowserContentHandler.prototype = {
|
|||
// PB builds.
|
||||
if (cmdLine.handleFlag("private", false) && PrivateBrowsingUtils.enabled) {
|
||||
PrivateBrowsingUtils.enterTemporaryAutoStartMode();
|
||||
if (cmdLine.state == Ci.nsICommandLine.STATE_INITIAL_LAUNCH) {
|
||||
let win = Services.wm.getMostRecentWindow("navigator:blank");
|
||||
if (win) {
|
||||
win.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIWebNavigation)
|
||||
.QueryInterface(Ci.nsILoadContext)
|
||||
.usePrivateBrowsing = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cmdLine.handleFlag("setDefaultBrowser", false)) {
|
||||
ShellService.setDefaultBrowser(true, true);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
This is the PDF.js project output, https://github.com/mozilla/pdf.js
|
||||
|
||||
Current extension version is: 2.0.466
|
||||
Current extension version is: 2.0.480
|
||||
|
||||
Taken from upstream commit: a8e9f6cc
|
||||
Taken from upstream commit: a7a034d8
|
||||
|
|
|
@ -1650,8 +1650,8 @@ exports.GlobalWorkerOptions = GlobalWorkerOptions;
|
|||
"use strict";
|
||||
|
||||
|
||||
var pdfjsVersion = '2.0.466';
|
||||
var pdfjsBuild = 'a8e9f6cc';
|
||||
var pdfjsVersion = '2.0.480';
|
||||
var pdfjsBuild = 'a7a034d8';
|
||||
var pdfjsSharedUtil = __w_pdfjs_require__(0);
|
||||
var pdfjsDisplayAPI = __w_pdfjs_require__(9);
|
||||
var pdfjsDisplayTextLayer = __w_pdfjs_require__(17);
|
||||
|
@ -4929,7 +4929,7 @@ function _fetchDocument(worker, source, pdfDataRangeTransport, docId) {
|
|||
}
|
||||
return worker.messageHandler.sendWithPromise('GetDocRequest', {
|
||||
docId,
|
||||
apiVersion: '2.0.466',
|
||||
apiVersion: '2.0.480',
|
||||
source: {
|
||||
data: source.data,
|
||||
url: source.url,
|
||||
|
@ -6252,8 +6252,8 @@ var InternalRenderTask = function InternalRenderTaskClosure() {
|
|||
}();
|
||||
var version, build;
|
||||
{
|
||||
exports.version = version = '2.0.466';
|
||||
exports.build = build = 'a8e9f6cc';
|
||||
exports.version = version = '2.0.480';
|
||||
exports.build = build = 'a7a034d8';
|
||||
}
|
||||
exports.getDocument = getDocument;
|
||||
exports.LoopbackPort = LoopbackPort;
|
||||
|
@ -8013,7 +8013,7 @@ var CanvasGraphics = function CanvasGraphicsClosure() {
|
|||
d = currentTransform[3];
|
||||
var heightScale = Math.max(Math.sqrt(c * c + d * d), 1);
|
||||
var imgToPaint, tmpCanvas;
|
||||
if (imgData instanceof HTMLElement || !imgData.data) {
|
||||
if (typeof HTMLElement === 'function' && imgData instanceof HTMLElement || !imgData.data) {
|
||||
imgToPaint = imgData;
|
||||
} else {
|
||||
tmpCanvas = this.cachedCanvases.getCanvas('inlineImage', width, height);
|
||||
|
|
|
@ -12939,7 +12939,7 @@ var JpxImage = function JpxImageClosure() {
|
|||
cod.selectiveArithmeticCodingBypass = !!(blockStyle & 1);
|
||||
cod.resetContextProbabilities = !!(blockStyle & 2);
|
||||
cod.terminationOnEachCodingPass = !!(blockStyle & 4);
|
||||
cod.verticalyStripe = !!(blockStyle & 8);
|
||||
cod.verticallyStripe = !!(blockStyle & 8);
|
||||
cod.predictableTermination = !!(blockStyle & 16);
|
||||
cod.segmentationSymbolUsed = !!(blockStyle & 32);
|
||||
cod.reversibleTransformation = data[j++];
|
||||
|
@ -12964,8 +12964,8 @@ var JpxImage = function JpxImageClosure() {
|
|||
if (cod.terminationOnEachCodingPass) {
|
||||
unsupported.push('terminationOnEachCodingPass');
|
||||
}
|
||||
if (cod.verticalyStripe) {
|
||||
unsupported.push('verticalyStripe');
|
||||
if (cod.verticallyStripe) {
|
||||
unsupported.push('verticallyStripe');
|
||||
}
|
||||
if (cod.predictableTermination) {
|
||||
unsupported.push('predictableTermination');
|
||||
|
@ -21112,8 +21112,8 @@ exports.PostScriptCompiler = PostScriptCompiler;
|
|||
"use strict";
|
||||
|
||||
|
||||
var pdfjsVersion = '2.0.466';
|
||||
var pdfjsBuild = 'a8e9f6cc';
|
||||
var pdfjsVersion = '2.0.480';
|
||||
var pdfjsBuild = 'a7a034d8';
|
||||
var pdfjsCoreWorker = __w_pdfjs_require__(20);
|
||||
exports.WorkerMessageHandler = pdfjsCoreWorker.WorkerMessageHandler;
|
||||
|
||||
|
@ -21314,7 +21314,7 @@ var WorkerMessageHandler = {
|
|||
var cancelXHRs = null;
|
||||
var WorkerTasks = [];
|
||||
let apiVersion = docParams.apiVersion;
|
||||
let workerVersion = '2.0.466';
|
||||
let workerVersion = '2.0.480';
|
||||
if (apiVersion !== null && apiVersion !== workerVersion) {
|
||||
throw new Error(`The API version "${apiVersion}" does not match ` + `the Worker version "${workerVersion}".`);
|
||||
}
|
||||
|
@ -32357,7 +32357,7 @@ var CMapFactory = function CMapFactoryClosure() {
|
|||
}
|
||||
function parseCMap(cMap, lexer, fetchBuiltInCMap, useCMap) {
|
||||
var previous;
|
||||
var embededUseCMap;
|
||||
var embeddedUseCMap;
|
||||
objLoop: while (true) {
|
||||
try {
|
||||
var obj = lexer.getObj();
|
||||
|
@ -32376,7 +32376,7 @@ var CMapFactory = function CMapFactoryClosure() {
|
|||
break objLoop;
|
||||
case 'usecmap':
|
||||
if ((0, _primitives.isName)(previous)) {
|
||||
embededUseCMap = previous.name;
|
||||
embeddedUseCMap = previous.name;
|
||||
}
|
||||
break;
|
||||
case 'begincodespacerange':
|
||||
|
@ -32404,8 +32404,8 @@ var CMapFactory = function CMapFactoryClosure() {
|
|||
continue;
|
||||
}
|
||||
}
|
||||
if (!useCMap && embededUseCMap) {
|
||||
useCMap = embededUseCMap;
|
||||
if (!useCMap && embeddedUseCMap) {
|
||||
useCMap = embeddedUseCMap;
|
||||
}
|
||||
if (useCMap) {
|
||||
return extendCMap(cMap, fetchBuiltInCMap, useCMap);
|
||||
|
|
|
@ -426,7 +426,7 @@ const WaitOnType = {
|
|||
};
|
||||
function waitOnEventOrTimeout({ target, name, delay = 0 }) {
|
||||
if (typeof target !== 'object' || !(name && typeof name === 'string') || !(Number.isInteger(delay) && delay >= 0)) {
|
||||
return Promise.reject(new Error('waitOnEventOrTimeout - invalid paramaters.'));
|
||||
return Promise.reject(new Error('waitOnEventOrTimeout - invalid parameters.'));
|
||||
}
|
||||
let capability = (0, _pdfjsLib.createPromiseCapability)();
|
||||
function handler(type) {
|
||||
|
|
|
@ -161,6 +161,10 @@ span#hostname {
|
|||
padding: 10px;
|
||||
}
|
||||
|
||||
.exceptionDialogButtonContainer[hidden] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.illustrated #errorPageContainer {
|
||||
min-height: 300px;
|
||||
display: flex;
|
||||
|
|
|
@ -22,11 +22,11 @@ function getValue(dbg, index) {
|
|||
}
|
||||
|
||||
async function addExpression(dbg, input) {
|
||||
info("Adding an expression");
|
||||
const evaluation = waitForDispatch(dbg, "EVALUATE_EXPRESSION");
|
||||
findElementWithSelector(dbg, expressionSelectors.input).focus();
|
||||
type(dbg, input);
|
||||
pressKey(dbg, "Enter");
|
||||
await waitForDispatch(dbg, "EVALUATE_EXPRESSION");
|
||||
await evaluation;
|
||||
}
|
||||
|
||||
async function editExpression(dbg, input) {
|
||||
|
@ -40,37 +40,17 @@ async function editExpression(dbg, input) {
|
|||
await evaluation;
|
||||
}
|
||||
|
||||
/*
|
||||
* When we add a bad expression, we'll pause,
|
||||
* resume, and wait for the expression to finish being evaluated.
|
||||
*/
|
||||
async function addBadExpression(dbg, input) {
|
||||
const evaluation = waitForDispatch(dbg, "EVALUATE_EXPRESSION");
|
||||
|
||||
findElementWithSelector(dbg, expressionSelectors.input).focus();
|
||||
type(dbg, input);
|
||||
pressKey(dbg, "Enter");
|
||||
|
||||
await waitForPaused(dbg);
|
||||
|
||||
ok(dbg.selectors.isEvaluatingExpression(dbg.getState()));
|
||||
await resume(dbg);
|
||||
await evaluation;
|
||||
}
|
||||
|
||||
add_task(async function() {
|
||||
const dbg = await initDebugger("doc-script-switching.html");
|
||||
|
||||
const onPausedOnException = togglePauseOnExceptions(dbg, true, false);
|
||||
await togglePauseOnExceptions(dbg, true, false);
|
||||
|
||||
// add a good expression, 2 bad expressions, and another good one
|
||||
await addExpression(dbg, "location");
|
||||
await addBadExpression(dbg, "foo.bar");
|
||||
await addBadExpression(dbg, "foo.batt");
|
||||
await addExpression(dbg, "foo.bar");
|
||||
await addExpression(dbg, "foo.batt");
|
||||
await addExpression(dbg, "2");
|
||||
|
||||
await onPausedOnException;
|
||||
|
||||
// check the value of
|
||||
is(getValue(dbg, 2), "(unavailable)");
|
||||
is(getValue(dbg, 3), "(unavailable)");
|
||||
|
|
|
@ -1537,7 +1537,9 @@ const ThreadActor = ActorClassWithSpec(threadSpec, {
|
|||
this.sources.getOriginalLocation(generatedLocation));
|
||||
const url = originalSourceActor ? originalSourceActor.url : null;
|
||||
|
||||
if (this.sources.isBlackBoxed(url)) {
|
||||
// We ignore sources without a url because we do not
|
||||
// want to pause at console evaluations or watch expressions.
|
||||
if (!url || this.sources.isBlackBoxed(url)) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
|
|
|
@ -11,46 +11,52 @@
|
|||
|
||||
var gDebuggee;
|
||||
var gClient;
|
||||
var gThreadClient;
|
||||
|
||||
function run_test() {
|
||||
initTestDebuggerServer();
|
||||
gDebuggee = addTestGlobal("test-stack");
|
||||
gClient = new DebuggerClient(DebuggerServer.connectPipe());
|
||||
gClient.connect().then(function() {
|
||||
attachTestTabAndResume(gClient, "test-stack",
|
||||
function(response, tabClient, threadClient) {
|
||||
gThreadClient = threadClient;
|
||||
test_pause_frame();
|
||||
});
|
||||
});
|
||||
do_test_pending();
|
||||
}
|
||||
|
||||
function test_pause_frame() {
|
||||
gThreadClient.addOneTimeListener("paused", function(event, packet) {
|
||||
gThreadClient.addOneTimeListener("paused", function(event, packet) {
|
||||
Assert.equal(packet.why.type, "exception");
|
||||
Assert.equal(packet.why.exception, "bar");
|
||||
gThreadClient.resume(function() {
|
||||
finishClient(gClient);
|
||||
});
|
||||
});
|
||||
gThreadClient.pauseOnExceptions(true, true);
|
||||
gThreadClient.resume();
|
||||
run_test_with_server(DebuggerServer, function() {
|
||||
run_test_with_server(WorkerDebuggerServer, do_test_finished);
|
||||
});
|
||||
|
||||
try {
|
||||
/* eslint-disable */
|
||||
gDebuggee.eval("(" + function () {
|
||||
debugger;
|
||||
try {
|
||||
throw "foo";
|
||||
} catch (e) {}
|
||||
throw "bar";
|
||||
} + ")()");
|
||||
/* eslint-enable */
|
||||
} catch (e) {
|
||||
/* Empty */
|
||||
}
|
||||
}
|
||||
|
||||
function run_test_with_server(server, callback) {
|
||||
initTestDebuggerServer(server);
|
||||
gDebuggee = addTestGlobal("test-pausing", server);
|
||||
gClient = new DebuggerClient(server.connectPipe());
|
||||
gClient.connect(test_pause_frame);
|
||||
}
|
||||
|
||||
async function test_pause_frame() {
|
||||
const [,, threadClient] = await attachTestTabAndResume(gClient, "test-pausing");
|
||||
await executeOnNextTickAndWaitForPause(evaluateTestCode, gClient);
|
||||
|
||||
evaluateTestCode();
|
||||
|
||||
threadClient.pauseOnExceptions(true, true);
|
||||
await resume(threadClient);
|
||||
const paused = await waitForPause(gClient);
|
||||
Assert.equal(paused.why.type, "exception");
|
||||
equal(paused.frame.where.line, 6, "paused at throw");
|
||||
|
||||
await resume(threadClient);
|
||||
finishClient(gClient);
|
||||
}
|
||||
|
||||
function evaluateTestCode() {
|
||||
/* eslint-disable */
|
||||
try {
|
||||
Cu.evalInSandbox(` // 1
|
||||
debugger; // 2
|
||||
try { // 3
|
||||
throw "foo"; // 4
|
||||
} catch (e) {} // 5
|
||||
throw "bar"; // 6
|
||||
`, // 7
|
||||
gDebuggee,
|
||||
"1.8",
|
||||
"test_pause_exceptions-03.js",
|
||||
1
|
||||
);
|
||||
} catch (e) {}
|
||||
/* eslint-disable */
|
||||
}
|
||||
|
|
|
@ -10,47 +10,55 @@
|
|||
|
||||
var gDebuggee;
|
||||
var gClient;
|
||||
var gThreadClient;
|
||||
|
||||
function run_test() {
|
||||
initTestDebuggerServer();
|
||||
gDebuggee = addTestGlobal("test-no-interface");
|
||||
gClient = new DebuggerClient(DebuggerServer.connectPipe());
|
||||
gClient.connect().then(function() {
|
||||
attachTestTabAndResume(gClient, "test-no-interface",
|
||||
function(response, tabClient, threadClient) {
|
||||
gThreadClient = threadClient;
|
||||
test_pause_frame();
|
||||
});
|
||||
});
|
||||
do_test_pending();
|
||||
}
|
||||
|
||||
function test_pause_frame() {
|
||||
gThreadClient.pauseOnExceptions(true, false, function() {
|
||||
gThreadClient.addOneTimeListener("paused", function(event, packet) {
|
||||
Assert.equal(packet.why.type, "exception");
|
||||
Assert.equal(packet.why.exception, 42);
|
||||
gThreadClient.resume(function() {
|
||||
finishClient(gClient);
|
||||
});
|
||||
});
|
||||
|
||||
/* eslint-disable */
|
||||
gDebuggee.eval("(" + function () {
|
||||
function QueryInterface() {
|
||||
throw Cr.NS_ERROR_NO_INTERFACE;
|
||||
}
|
||||
function stopMe() {
|
||||
throw 42;
|
||||
}
|
||||
try {
|
||||
QueryInterface();
|
||||
} catch (e) {}
|
||||
try {
|
||||
stopMe();
|
||||
} catch (e) {}
|
||||
} + ")()");
|
||||
/* eslint-enable */
|
||||
run_test_with_server(DebuggerServer, function() {
|
||||
run_test_with_server(WorkerDebuggerServer, do_test_finished);
|
||||
});
|
||||
}
|
||||
|
||||
function run_test_with_server(server, callback) {
|
||||
initTestDebuggerServer(server);
|
||||
gDebuggee = addTestGlobal("test-pausing", server);
|
||||
gClient = new DebuggerClient(server.connectPipe());
|
||||
gClient.connect(test_pause_frame);
|
||||
}
|
||||
|
||||
async function test_pause_frame() {
|
||||
const [,, threadClient] = await attachTestTabAndResume(gClient, "test-pausing");
|
||||
|
||||
await threadClient.pauseOnExceptions(true, false);
|
||||
await executeOnNextTickAndWaitForPause(evaluateTestCode, gClient);
|
||||
|
||||
await resume(threadClient);
|
||||
const paused = await waitForPause(gClient);
|
||||
Assert.equal(paused.why.type, "exception");
|
||||
equal(paused.frame.where.line, 12, "paused at throw");
|
||||
|
||||
await resume(threadClient);
|
||||
finishClient(gClient);
|
||||
}
|
||||
|
||||
function evaluateTestCode() {
|
||||
/* eslint-disable */
|
||||
Cu.evalInSandbox(` // 1
|
||||
function QueryInterface() { // 2
|
||||
throw Cr.NS_ERROR_NO_INTERFACE; // 3
|
||||
} // 4
|
||||
function stopMe() { // 5
|
||||
throw 42; // 6
|
||||
} // 7
|
||||
try { // 8
|
||||
QueryInterface(); // 9
|
||||
} catch (e) {} // 10
|
||||
try { // 11
|
||||
stopMe(); // 12
|
||||
} catch (e) {}`, // 13
|
||||
gDebuggee,
|
||||
"1.8",
|
||||
"test_ignore_no_interface_exceptions.js",
|
||||
1
|
||||
);
|
||||
/* eslint-disable */
|
||||
}
|
||||
|
|
|
@ -30,12 +30,11 @@ function run_test() {
|
|||
function test_pause_frame() {
|
||||
gThreadClient.addOneTimeListener("paused", function(event, packet) {
|
||||
gThreadClient.addOneTimeListener("paused", function(event, packet) {
|
||||
Assert.equal(packet.why.type, "exception");
|
||||
Assert.equal(packet.why.exception, 42);
|
||||
gThreadClient.resume(function() {
|
||||
finishClient(gClient);
|
||||
});
|
||||
Assert.equal(packet.why.type, "debuggerStatement");
|
||||
Assert.equal(packet.frame.where.line, 9);
|
||||
gThreadClient.resume(() => finishClient(gClient));
|
||||
});
|
||||
|
||||
gThreadClient.pauseOnExceptions(true);
|
||||
gThreadClient.resume();
|
||||
});
|
||||
|
@ -48,7 +47,9 @@ function test_pause_frame() {
|
|||
}
|
||||
try {
|
||||
stopMe();
|
||||
} catch (e) {}
|
||||
} catch (e) {
|
||||
debugger
|
||||
}
|
||||
} + ")()");
|
||||
/* eslint-enable */
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
/**
|
||||
* Test that setting pauseOnExceptions to true when the debugger isn't in a
|
||||
* paused state will cause the debuggee to pause when an exceptions is thrown.
|
||||
* paused state will not cause the debuggee to pause when an exceptions is thrown.
|
||||
*/
|
||||
|
||||
var gDebuggee;
|
||||
|
@ -29,21 +29,21 @@ function run_test() {
|
|||
function test_pause_frame() {
|
||||
gThreadClient.pauseOnExceptions(true, false, function() {
|
||||
gThreadClient.addOneTimeListener("paused", function(event, packet) {
|
||||
Assert.equal(packet.why.type, "exception");
|
||||
Assert.equal(packet.why.exception, 42);
|
||||
gThreadClient.resume(function() {
|
||||
finishClient(gClient);
|
||||
});
|
||||
Assert.equal(packet.why.type, "debuggerStatement");
|
||||
Assert.equal(packet.frame.where.line, 8);
|
||||
gThreadClient.resume(() => finishClient(gClient));
|
||||
});
|
||||
|
||||
/* eslint-disable */
|
||||
gDebuggee.eval("(" + function () {
|
||||
function stopMe() {
|
||||
throw 42;
|
||||
}
|
||||
try {
|
||||
stopMe();
|
||||
} catch (e) {}
|
||||
gDebuggee.eval("(" + function () { // 1
|
||||
function stopMe() { // 2
|
||||
throw 42; // 3
|
||||
} // 4
|
||||
try { // 5
|
||||
stopMe(); // 6
|
||||
} catch (e) { // 7
|
||||
debugger; // 8
|
||||
} // 9
|
||||
} + ")()");
|
||||
/* eslint-enable */
|
||||
});
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
/* eslint-disable no-shadow */
|
||||
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* Test that setting pauseOnExceptions to true will cause the debuggee to pause
|
||||
* when an exception is thrown.
|
||||
*/
|
||||
|
||||
var gDebuggee;
|
||||
var gClient;
|
||||
|
||||
function run_test() {
|
||||
do_test_pending();
|
||||
run_test_with_server(DebuggerServer, function() {
|
||||
run_test_with_server(WorkerDebuggerServer, do_test_finished);
|
||||
});
|
||||
}
|
||||
|
||||
function run_test_with_server(server, callback) {
|
||||
initTestDebuggerServer(server);
|
||||
gDebuggee = addTestGlobal("test-pausing", server);
|
||||
gClient = new DebuggerClient(server.connectPipe());
|
||||
gClient.connect(test_pause_frame);
|
||||
}
|
||||
|
||||
async function test_pause_frame() {
|
||||
const [,, threadClient] = await attachTestTabAndResume(gClient, "test-pausing");
|
||||
await executeOnNextTickAndWaitForPause(evaluateTestCode, gClient);
|
||||
|
||||
threadClient.pauseOnExceptions(true);
|
||||
await resume(threadClient);
|
||||
const paused = await waitForPause(gClient);
|
||||
Assert.equal(paused.why.type, "exception");
|
||||
equal(paused.frame.where.line, 4, "paused at throw");
|
||||
|
||||
await resume(threadClient);
|
||||
finishClient(gClient);
|
||||
}
|
||||
|
||||
function evaluateTestCode() {
|
||||
/* eslint-disable */
|
||||
Cu.evalInSandbox(
|
||||
` // 1
|
||||
function stopMe() { // 2
|
||||
debugger; // 3
|
||||
throw 42; // 4
|
||||
} // 5
|
||||
try { // 6
|
||||
stopMe(); // 7
|
||||
} catch (e) {}`, // 8
|
||||
gDebuggee,
|
||||
"1.8",
|
||||
"test_pause_exceptions-03.js",
|
||||
1
|
||||
);
|
||||
/* eslint-disable */
|
||||
}
|
|
@ -198,6 +198,7 @@ reason = bug 1104838
|
|||
[test_framebindings-07.js]
|
||||
[test_pause_exceptions-01.js]
|
||||
[test_pause_exceptions-02.js]
|
||||
[test_pause_exceptions-03.js]
|
||||
[test_longstringactor.js]
|
||||
[test_longstringgrips-01.js]
|
||||
[test_longstringgrips-02.js]
|
||||
|
|
|
@ -112,7 +112,6 @@
|
|||
#include "nsIPromptFactory.h"
|
||||
#include "nsIReflowObserver.h"
|
||||
#include "nsIScriptChannel.h"
|
||||
#include "nsIScriptError.h"
|
||||
#include "nsIScriptObjectPrincipal.h"
|
||||
#include "nsIScriptSecurityManager.h"
|
||||
#include "nsIScrollableFrame.h"
|
||||
|
@ -1732,12 +1731,6 @@ nsDocShell::GetUsePrivateBrowsing(bool* aUsePrivateBrowsing)
|
|||
NS_IMETHODIMP
|
||||
nsDocShell::SetUsePrivateBrowsing(bool aUsePrivateBrowsing)
|
||||
{
|
||||
nsContentUtils::ReportToConsoleNonLocalized(
|
||||
NS_LITERAL_STRING("Only internal code is allowed to set the usePrivateBrowsing attribute"),
|
||||
nsIScriptError::warningFlag,
|
||||
NS_LITERAL_CSTRING("Internal API Used"),
|
||||
mContentViewer ? mContentViewer->GetDocument() : nullptr);
|
||||
|
||||
if (!CanSetOriginAttributes()) {
|
||||
bool changed = aUsePrivateBrowsing != (mPrivateBrowsingId > 0);
|
||||
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
support-files =
|
||||
worker_abort_controller_fetch.js
|
||||
slow.sjs
|
||||
!/dom/events/test/event_leak_utils.js
|
||||
|
||||
[test_abort_controller.html]
|
||||
[test_abort_controller_fetch.html]
|
||||
[test_event_listener_leaks.html]
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Bug 1450271 - Test AbortSignal event listener leak conditions</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="text/javascript" src="/tests/dom/events/test/event_leak_utils.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<p id="display"></p>
|
||||
<script class="testbody" type="text/javascript">
|
||||
// Manipulate AbortSignal. Its important here that we create a
|
||||
// listener callback from the DOM objects back to the frame's global
|
||||
// in order to exercise the leak condition.
|
||||
async function useAbortSignal(contentWindow) {
|
||||
let controller = new contentWindow.AbortController();
|
||||
let signal = controller.signal;
|
||||
signal.onabort = _ => {
|
||||
contentWindow.abortCount += 1;
|
||||
};
|
||||
}
|
||||
|
||||
async function runTest() {
|
||||
try {
|
||||
await checkForEventListenerLeaks("AbortSignal", useAbortSignal);
|
||||
} catch (e) {
|
||||
ok(false, e);
|
||||
} finally {
|
||||
SimpleTest.finish();
|
||||
}
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addEventListener("load", runTest, { once: true });
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -13,6 +13,7 @@ support-files =
|
|||
mozilla/file_transition_finish_on_compositor.html
|
||||
../../../layout/style/test/property_database.js
|
||||
testcommon.js
|
||||
!/dom/events/test/event_leak_utils.js
|
||||
|
||||
[css-animations/test_animations-dynamic-changes.html]
|
||||
[css-animations/test_animation-cancel.html]
|
||||
|
@ -73,6 +74,7 @@ skip-if = webrender # bug 1424752
|
|||
[mozilla/test_transition_finish_on_compositor.html]
|
||||
skip-if = toolkit == 'android' || webrender # bug 1424752 for webrender
|
||||
[mozilla/test_underlying_discrete_value.html]
|
||||
[mozilla/test_event_listener_leaks.html]
|
||||
[style/test_animation-seeking-with-current-time.html]
|
||||
[style/test_animation-seeking-with-start-time.html]
|
||||
[style/test_animation-setting-effect.html]
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Bug 1450271 - Test Animation event listener leak conditions</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="text/javascript" src="/tests/dom/events/test/event_leak_utils.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<script class="testbody" type="text/javascript">
|
||||
// Manipulate Animation. Its important here that we create a
|
||||
// listener callback from the DOM objects back to the frame's global
|
||||
// in order to exercise the leak condition.
|
||||
async function useAnimation(contentWindow) {
|
||||
let div = contentWindow.document.createElement("div");
|
||||
contentWindow.document.body.appendChild(div);
|
||||
let animation = div.animate({}, 100 * 1000);
|
||||
is(animation.playState, "running", "animation should be running");
|
||||
animation.onfinish = _ => {
|
||||
contentWindow.finishCount += 1;
|
||||
};
|
||||
}
|
||||
|
||||
async function runTest() {
|
||||
try {
|
||||
await checkForEventListenerLeaks("Animation", useAnimation);
|
||||
} catch (e) {
|
||||
ok(false, e);
|
||||
} finally {
|
||||
SimpleTest.finish();
|
||||
}
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addEventListener("load", runTest, { once: true });
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -2166,7 +2166,7 @@ Element::FindAttributeDependence(const nsAtom* aAttribute,
|
|||
for (uint32_t mapindex = 0; mapindex < aMapCount; ++mapindex) {
|
||||
for (const MappedAttributeEntry* map = aMaps[mapindex];
|
||||
map->attribute; ++map) {
|
||||
if (aAttribute == *map->attribute) {
|
||||
if (aAttribute == map->attribute) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -2908,7 +2908,7 @@ Element::FindAttrValueIn(int32_t aNameSpaceID,
|
|||
const nsAttrValue* val = mAttrsAndChildren.GetAttr(aName, aNameSpaceID);
|
||||
if (val) {
|
||||
for (int32_t i = 0; aValues[i]; ++i) {
|
||||
if (val->Equals(*aValues[i], aCaseSensitive)) {
|
||||
if (val->Equals(aValues[i], aCaseSensitive)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
@ -3423,16 +3423,16 @@ nsDOMTokenListPropertyDestructor(void *aObject, nsAtom *aProperty,
|
|||
NS_RELEASE(list);
|
||||
}
|
||||
|
||||
static nsStaticAtom** sPropertiesToTraverseAndUnlink[] =
|
||||
static nsStaticAtom* const sPropertiesToTraverseAndUnlink[] =
|
||||
{
|
||||
&nsGkAtoms::sandbox,
|
||||
&nsGkAtoms::sizes,
|
||||
&nsGkAtoms::dirAutoSetBy,
|
||||
nsGkAtoms::sandbox,
|
||||
nsGkAtoms::sizes,
|
||||
nsGkAtoms::dirAutoSetBy,
|
||||
nullptr
|
||||
};
|
||||
|
||||
// static
|
||||
nsStaticAtom***
|
||||
nsStaticAtom* const*
|
||||
Element::HTMLSVGPropertiesToTraverseAndUnlink()
|
||||
{
|
||||
return sPropertiesToTraverseAndUnlink;
|
||||
|
@ -3443,10 +3443,10 @@ Element::GetTokenList(nsAtom* aAtom,
|
|||
const DOMTokenListSupportedTokenArray aSupportedTokens)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
nsStaticAtom*** props = HTMLSVGPropertiesToTraverseAndUnlink();
|
||||
const nsStaticAtom* const* props = HTMLSVGPropertiesToTraverseAndUnlink();
|
||||
bool found = false;
|
||||
for (uint32_t i = 0; props[i]; ++i) {
|
||||
if (*props[i] == aAtom) {
|
||||
if (props[i] == aAtom) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -803,7 +803,7 @@ public:
|
|||
* @return ATTR_MISSING, ATTR_VALUE_NO_MATCH or the non-negative index
|
||||
* indicating the first value of aValues that matched
|
||||
*/
|
||||
typedef nsStaticAtom* const* const AttrValuesArray;
|
||||
typedef nsStaticAtom* const AttrValuesArray;
|
||||
int32_t FindAttrValueIn(int32_t aNameSpaceID,
|
||||
nsAtom* aName,
|
||||
AttrValuesArray* aValues,
|
||||
|
@ -964,7 +964,7 @@ public:
|
|||
* Attribute Mapping Helpers
|
||||
*/
|
||||
struct MappedAttributeEntry {
|
||||
nsStaticAtom** attribute;
|
||||
const nsStaticAtom* const attribute;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -981,7 +981,7 @@ public:
|
|||
return FindAttributeDependence(aAttribute, aMaps, N);
|
||||
}
|
||||
|
||||
static nsStaticAtom*** HTMLSVGPropertiesToTraverseAndUnlink();
|
||||
static nsStaticAtom* const* HTMLSVGPropertiesToTraverseAndUnlink();
|
||||
|
||||
private:
|
||||
void DescribeAttribute(uint32_t index, nsAString& aOutDescription) const;
|
||||
|
|
|
@ -1469,9 +1469,10 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(FragmentOrElement)
|
|||
}
|
||||
|
||||
if (tmp->IsHTMLElement() || tmp->IsSVGElement()) {
|
||||
nsStaticAtom*** props = Element::HTMLSVGPropertiesToTraverseAndUnlink();
|
||||
nsStaticAtom* const* props =
|
||||
Element::HTMLSVGPropertiesToTraverseAndUnlink();
|
||||
for (uint32_t i = 0; props[i]; ++i) {
|
||||
tmp->DeleteProperty(*props[i]);
|
||||
tmp->DeleteProperty(props[i]);
|
||||
}
|
||||
if (tmp->MayHaveAnimations()) {
|
||||
nsAtom** effectProps = EffectSet::GetEffectSetPropertyAtoms();
|
||||
|
@ -2034,10 +2035,11 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(FragmentOrElement)
|
|||
}
|
||||
}
|
||||
if (tmp->IsHTMLElement() || tmp->IsSVGElement()) {
|
||||
nsStaticAtom*** props = Element::HTMLSVGPropertiesToTraverseAndUnlink();
|
||||
nsStaticAtom* const* props =
|
||||
Element::HTMLSVGPropertiesToTraverseAndUnlink();
|
||||
for (uint32_t i = 0; props[i]; ++i) {
|
||||
nsISupports* property =
|
||||
static_cast<nsISupports*>(tmp->GetProperty(*props[i]));
|
||||
static_cast<nsISupports*>(tmp->GetProperty(props[i]));
|
||||
cb.NoteXPCOMChild(property);
|
||||
}
|
||||
if (tmp->MayHaveAnimations()) {
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
<html>
|
||||
<head>
|
||||
<script>
|
||||
function go () {
|
||||
try { o1 = document.getElementById('x') } catch(e) { }
|
||||
try { o1.src = '=' } catch(e) { }
|
||||
try { o2 = document.cloneNode(false) } catch(e) { }
|
||||
try { o3 = new XMLHttpRequest({mozAnon: true}) } catch(e) { }
|
||||
try { o3.open('GET', 1, false) } catch(e) { }
|
||||
try { o3.send() } catch(e) { }
|
||||
try { o2.prepend('', o1, '', o2) } catch(e) { }
|
||||
}
|
||||
document.addEventListener('DOMContentLoaded', go)
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<picture>
|
||||
<img id='x' src='data:image/png;base64,R0lGODlhAQABAAD/ACH/C05FVFNDQVBFMi4wAwEAAAAsAAAAAEAAQAAAgA'/>
|
||||
</body>
|
||||
</html>
|
|
@ -238,3 +238,4 @@ pref(dom.webcomponents.shadowdom.enabled,false) load 1422931.html
|
|||
pref(dom.webcomponents.shadowdom.enabled,true) load 1419799.html
|
||||
skip-if(!browserIsRemote) pref(dom.webcomponents.customelements.enabled,true) pref(dom.disable_open_during_load,false) load 1419902.html # skip on non e10s loads, Bug 1419902
|
||||
pref(dom.webcomponents.shadowdom.enabled,true) load 1428053.html
|
||||
load 1445670.html
|
||||
|
|
|
@ -16,7 +16,6 @@ XPIDL_SOURCES += [
|
|||
'mozIDOMWindow.idl',
|
||||
'nsIContentPolicy.idl',
|
||||
'nsIDocumentEncoder.idl',
|
||||
'nsIDOMDataChannel.idl',
|
||||
'nsIDOMDOMCursor.idl',
|
||||
'nsIDOMDOMRequest.idl',
|
||||
'nsIDOMParser.idl',
|
||||
|
|
|
@ -4664,7 +4664,7 @@ nsContentUtils::HasNonEmptyAttr(const nsIContent* aContent,
|
|||
int32_t aNameSpaceID,
|
||||
nsAtom* aName)
|
||||
{
|
||||
static Element::AttrValuesArray strings[] = {&nsGkAtoms::_empty, nullptr};
|
||||
static Element::AttrValuesArray strings[] = {nsGkAtoms::_empty, nullptr};
|
||||
return aContent->IsElement() &&
|
||||
aContent->AsElement()->FindAttrValueIn(aNameSpaceID, aName, strings, eCaseMatters)
|
||||
== Element::ATTR_VALUE_NO_MATCH;
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
|
||||
#include "nsDOMDataChannelDeclarations.h"
|
||||
#include "nsDOMDataChannel.h"
|
||||
#include "nsIDOMDataChannel.h"
|
||||
#include "mozilla/DOMEventTargetHelper.h"
|
||||
#include "mozilla/dom/File.h"
|
||||
#include "mozilla/dom/MessageEvent.h"
|
||||
|
@ -69,7 +68,6 @@ NS_IMPL_ADDREF_INHERITED(nsDOMDataChannel, DOMEventTargetHelper)
|
|||
NS_IMPL_RELEASE_INHERITED(nsDOMDataChannel, DOMEventTargetHelper)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsDOMDataChannel)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMDataChannel)
|
||||
NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
|
||||
|
||||
nsDOMDataChannel::nsDOMDataChannel(already_AddRefed<mozilla::DataChannel>& aDataChannel,
|
||||
|
@ -535,7 +533,7 @@ nsDOMDataChannel::EventListenerRemoved(nsAtom* aType)
|
|||
nsresult
|
||||
NS_NewDOMDataChannel(already_AddRefed<mozilla::DataChannel>&& aDataChannel,
|
||||
nsPIDOMWindowInner* aWindow,
|
||||
nsIDOMDataChannel** aDomDataChannel)
|
||||
nsDOMDataChannel** aDomDataChannel)
|
||||
{
|
||||
RefPtr<nsDOMDataChannel> domdc =
|
||||
new nsDOMDataChannel(aDataChannel, aWindow);
|
||||
|
@ -543,12 +541,6 @@ NS_NewDOMDataChannel(already_AddRefed<mozilla::DataChannel>&& aDataChannel,
|
|||
nsresult rv = domdc->Init(aWindow);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
|
||||
return CallQueryInterface(domdc, aDomDataChannel);
|
||||
}
|
||||
|
||||
/* static */
|
||||
void
|
||||
NS_DataChannelAppReady(nsIDOMDataChannel* aDomDataChannel)
|
||||
{
|
||||
((nsDOMDataChannel *)aDomDataChannel)->AppReady();
|
||||
domdc.forget(aDomDataChannel);
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
#include "mozilla/dom/RTCDataChannelBinding.h"
|
||||
#include "mozilla/dom/TypedArray.h"
|
||||
#include "mozilla/net/DataChannelListener.h"
|
||||
#include "nsIDOMDataChannel.h"
|
||||
#include "nsIInputStream.h"
|
||||
|
||||
|
||||
|
@ -25,7 +24,6 @@ class DataChannel;
|
|||
};
|
||||
|
||||
class nsDOMDataChannel final : public mozilla::DOMEventTargetHelper,
|
||||
public nsIDOMDataChannel,
|
||||
public mozilla::DataChannelListener
|
||||
{
|
||||
public:
|
||||
|
@ -35,7 +33,6 @@ public:
|
|||
nsresult Init(nsPIDOMWindowInner* aDOMWindow);
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_NSIDOMDATACHANNEL
|
||||
|
||||
NS_REALLY_FORWARD_NSIDOMEVENTTARGET(mozilla::DOMEventTargetHelper)
|
||||
|
||||
|
|
|
@ -11,20 +11,17 @@
|
|||
// gets used with MOZ_INTERNAL_API not set for media/webrtc/signaling/testing
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIDOMDataChannel.h"
|
||||
|
||||
namespace mozilla {
|
||||
class DataChannel;
|
||||
}
|
||||
|
||||
class nsDOMDataChannel;
|
||||
class nsPIDOMWindowInner;
|
||||
|
||||
nsresult
|
||||
NS_NewDOMDataChannel(already_AddRefed<mozilla::DataChannel>&& dataChannel,
|
||||
nsPIDOMWindowInner* aWindow,
|
||||
nsIDOMDataChannel** domDataChannel);
|
||||
|
||||
// Tell DataChannel it's ok to deliver open and message events
|
||||
void NS_DataChannelAppReady(nsIDOMDataChannel* domDataChannel);
|
||||
nsDOMDataChannel** domDataChannel);
|
||||
|
||||
#endif // nsDOMDataChannelDeclarations_h
|
||||
|
|
|
@ -2848,10 +2848,8 @@ const InterfaceShimEntry kInterfaceShimMap[] =
|
|||
{ "nsIDOMMouseEvent", "MouseEvent" },
|
||||
{ "nsIDOMMouseScrollEvent", "MouseScrollEvent" },
|
||||
{ "nsIDOMMutationEvent", "MutationEvent" },
|
||||
{ "nsIDOMSimpleGestureEvent", "SimpleGestureEvent" },
|
||||
{ "nsIDOMUIEvent", "UIEvent" },
|
||||
{ "nsIDOMHTMLMediaElement", "HTMLMediaElement" },
|
||||
{ "nsIDOMOfflineResourceList", "OfflineResourceList" },
|
||||
{ "nsIDOMRange", "Range" },
|
||||
{ "nsIDOMSVGLength", "SVGLength" },
|
||||
// Think about whether Ci.nsINodeFilter can just go away for websites!
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsIDOMEventTarget.idl"
|
||||
|
||||
[builtinclass, uuid(b00a4ca7-312e-4926-84f6-8ebb43e53d83)]
|
||||
interface nsIDOMDataChannel : nsIDOMEventTarget
|
||||
{
|
||||
};
|
|
@ -927,6 +927,11 @@ nsImageLoadingContent::LoadImage(nsIURI* aNewURI,
|
|||
|
||||
// Data documents, or documents from DOMParser shouldn't perform image loading.
|
||||
if (aDocument->IsLoadedAsData()) {
|
||||
// This is the only codepath on which we can reach SetBlockedRequest while
|
||||
// our pending request exists. Just clear it out here if we do have one.
|
||||
ClearPendingRequest(NS_BINDING_ABORTED,
|
||||
Some(OnNonvisible::DISCARD_IMAGES));
|
||||
|
||||
SetBlockedRequest(nsIContentPolicy::REJECT_REQUEST);
|
||||
|
||||
FireEvent(NS_LITERAL_STRING("error"));
|
||||
|
|
|
@ -343,7 +343,9 @@ protected:
|
|||
private:
|
||||
// Friend declarations for things that need to be able to call
|
||||
// SetIsNotDOMBinding(). The goal is to get rid of all of these, and
|
||||
// SetIsNotDOMBinding() too.
|
||||
// SetIsNotDOMBinding() too. Once that's done, we can remove the
|
||||
// couldBeDOMBinding bits in DoGetOrCreateDOMReflector, as well as any other
|
||||
// consumers of IsDOMBinding().
|
||||
friend class SandboxPrivate;
|
||||
void SetIsNotDOMBinding()
|
||||
{
|
||||
|
|
|
@ -238,6 +238,7 @@ support-files =
|
|||
file4_setting_opener.html
|
||||
PASS.html
|
||||
FAIL.html
|
||||
!/dom/events/test/event_leak_utils.js
|
||||
|
||||
[test_anchor_area_referrer.html]
|
||||
[test_anchor_area_referrer_changing.html]
|
||||
|
@ -647,6 +648,7 @@ skip-if = toolkit == 'android' #bug 904183
|
|||
[test_encodeToStringWithRequiresReinitAfterOutput.html]
|
||||
[test_error.html]
|
||||
[test_EventSource_redirects.html]
|
||||
[test_eventsource_event_listener_leaks.html]
|
||||
[test_explicit_user_agent.html]
|
||||
skip-if = (toolkit == 'android') # Android: Bug 775227
|
||||
[test_getAttribute_after_createAttribute.html]
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Bug 1450358 - Test EventSource event listener leak conditions</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="text/javascript" src="/tests/dom/events/test/event_leak_utils.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<script class="testbody" type="text/javascript">
|
||||
// Manipulate EventSource. Its important here that we create a
|
||||
// listener callback from the DOM objects back to the frame's global
|
||||
// in order to exercise the leak condition.
|
||||
async function useEventSource(contentWindow) {
|
||||
let es = new contentWindow.EventSource("delayedServerEvents.sjs");
|
||||
es.onmessage = _ => {
|
||||
contentWindow.messageCount += 1;
|
||||
};
|
||||
}
|
||||
|
||||
async function runTest() {
|
||||
try {
|
||||
await checkForEventListenerLeaks("EventSource", useEventSource);
|
||||
} catch (e) {
|
||||
ok(false, e);
|
||||
} finally {
|
||||
SimpleTest.finish();
|
||||
}
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addEventListener("load", runTest, { once: true });
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -1231,10 +1231,7 @@ QueryInterface(JSContext* cx, unsigned argc, JS::Value* vp)
|
|||
return false;
|
||||
}
|
||||
|
||||
// Switch this to UnwrapDOMObjectToISupports once our global objects are
|
||||
// using new bindings.
|
||||
nsCOMPtr<nsISupports> native;
|
||||
UnwrapArg<nsISupports>(cx, obj, getter_AddRefs(native));
|
||||
nsCOMPtr<nsISupports> native = UnwrapDOMObjectToISupports(obj);
|
||||
if (!native) {
|
||||
return Throw(cx, NS_ERROR_FAILURE);
|
||||
}
|
||||
|
@ -3265,40 +3262,6 @@ UnwrapArgImpl(JSContext* cx,
|
|||
return wrappedJS->QueryInterface(iid, ppArg);
|
||||
}
|
||||
|
||||
nsresult
|
||||
UnwrapXPConnectImpl(JSContext* cx,
|
||||
JS::MutableHandle<JS::Value> src,
|
||||
const nsIID &iid,
|
||||
void **ppArg)
|
||||
{
|
||||
if (!NS_IsMainThread()) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(src.isObject());
|
||||
// Unwrap ourselves, because we're going to want access to the unwrapped
|
||||
// object.
|
||||
JS::Rooted<JSObject*> obj(cx,
|
||||
js::CheckedUnwrap(&src.toObject(),
|
||||
/* stopAtWindowProxy = */ false));
|
||||
if (!obj) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsISupports> iface = xpc::UnwrapReflectorToISupports(obj);
|
||||
if (!iface) {
|
||||
return NS_ERROR_XPC_BAD_CONVERT_JS;
|
||||
}
|
||||
|
||||
if (NS_FAILED(iface->QueryInterface(iid, ppArg))) {
|
||||
return NS_ERROR_XPC_BAD_CONVERT_JS;
|
||||
}
|
||||
|
||||
// Now update our source to keep rooting our object.
|
||||
src.setObject(*obj);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
UnwrapWindowProxyImpl(JSContext* cx,
|
||||
JS::Handle<JSObject*> src,
|
||||
|
|
|
@ -80,29 +80,6 @@ UnwrapArg<nsPIDOMWindowOuter>(JSContext* cx, JS::Handle<JSObject*> src,
|
|||
return UnwrapWindowProxyImpl(cx, src, ppArg);
|
||||
}
|
||||
|
||||
nsresult
|
||||
UnwrapXPConnectImpl(JSContext* cx, JS::MutableHandle<JS::Value> src,
|
||||
const nsIID& iid, void** ppArg);
|
||||
|
||||
/*
|
||||
* Convert a jsval being used as a Web IDL interface implementation to an XPCOM
|
||||
* pointer; this is only used for Web IDL interfaces that specify
|
||||
* hasXPConnectImpls. This is not the same as UnwrapArg because caller _can_
|
||||
* assume that if unwrapping succeeds "val" will be updated so it's rooting the
|
||||
* XPCOM pointer. Also, UnwrapXPConnect doesn't need to worry about doing
|
||||
* XPCWrappedJS things.
|
||||
*
|
||||
* val must be an ObjectValue.
|
||||
*/
|
||||
template<class Interface>
|
||||
inline nsresult
|
||||
UnwrapXPConnect(JSContext* cx, JS::MutableHandle<JS::Value> val,
|
||||
Interface** ppThis)
|
||||
{
|
||||
return UnwrapXPConnectImpl(cx, val, NS_GET_TEMPLATE_IID(Interface),
|
||||
reinterpret_cast<void**>(ppThis));
|
||||
}
|
||||
|
||||
bool
|
||||
ThrowInvalidThis(JSContext* aCx, const JS::CallArgs& aArgs,
|
||||
bool aSecurityError, const char* aInterfaceName);
|
||||
|
@ -1093,7 +1070,8 @@ DoGetOrCreateDOMReflector(JSContext* cx, T* value,
|
|||
{
|
||||
MOZ_ASSERT(value);
|
||||
MOZ_ASSERT_IF(givenProto, js::IsObjectInContextCompartment(givenProto, cx));
|
||||
// We can get rid of this when we remove support for hasXPConnectImpls.
|
||||
// We can get rid of this when we remove support for
|
||||
// nsWrapperCache::SetIsNotDOMBinding.
|
||||
bool couldBeDOMBinding = CouldBeDOMBinding(value);
|
||||
JSObject* obj = value->GetWrapper();
|
||||
if (obj) {
|
||||
|
@ -3335,7 +3313,7 @@ template<class T, class S>
|
|||
inline RefPtr<T>
|
||||
StrongOrRawPtr(already_AddRefed<S>&& aPtr)
|
||||
{
|
||||
return aPtr.template downcast<T>();
|
||||
return Move(aPtr);
|
||||
}
|
||||
|
||||
template<class T,
|
||||
|
|
|
@ -298,12 +298,6 @@ DOMInterfaces = {
|
|||
},
|
||||
|
||||
'EventTarget': {
|
||||
# When we get rid of hasXPConnectImpls, we can get rid of the
|
||||
# couldBeDOMBinding stuff in GetOrCreateDOMReflector.
|
||||
#
|
||||
# We can also get rid of the UnwrapArg bits in
|
||||
# the dom QueryInterface (in BindingUtils.cpp) at that point.
|
||||
'hasXPConnectImpls': True,
|
||||
'jsImplParent': 'mozilla::DOMEventTargetHelper',
|
||||
},
|
||||
|
||||
|
|
|
@ -23,7 +23,6 @@ FINALIZE_HOOK_NAME = '_finalize'
|
|||
OBJECT_MOVED_HOOK_NAME = '_objectMoved'
|
||||
CONSTRUCT_HOOK_NAME = '_constructor'
|
||||
LEGACYCALLER_HOOK_NAME = '_legacycaller'
|
||||
HASINSTANCE_HOOK_NAME = '_hasInstance'
|
||||
RESOLVE_HOOK_NAME = '_resolve'
|
||||
MAY_RESOLVE_HOOK_NAME = '_mayResolve'
|
||||
NEW_ENUMERATE_HOOK_NAME = '_newEnumerate'
|
||||
|
@ -686,11 +685,6 @@ class CGPrototypeJSClass(CGThing):
|
|||
protoGetter=protoGetter)
|
||||
|
||||
|
||||
def NeedsGeneratedHasInstance(descriptor):
|
||||
assert descriptor.interface.hasInterfaceObject()
|
||||
return descriptor.hasXPConnectImpls
|
||||
|
||||
|
||||
def InterfaceObjectProtoGetter(descriptor, forXrays=False):
|
||||
"""
|
||||
Returns a tuple with two elements:
|
||||
|
@ -741,9 +735,7 @@ class CGInterfaceObjectJSClass(CGThing):
|
|||
ctorname = "nullptr"
|
||||
else:
|
||||
ctorname = "ThrowingConstructor"
|
||||
needsHasInstance = (
|
||||
not NeedsGeneratedHasInstance(self.descriptor) and
|
||||
self.descriptor.interface.hasInterfacePrototypeObject())
|
||||
needsHasInstance = self.descriptor.interface.hasInterfacePrototypeObject()
|
||||
|
||||
prototypeID, depth = PrototypeIDAndDepth(self.descriptor)
|
||||
slotCount = "DOM_INTERFACE_SLOTS_BASE"
|
||||
|
@ -1106,15 +1098,6 @@ class CGHeaders(CGWrapper):
|
|||
implementationIncludes |= set(self.getDeclarationFilename(i) for i in
|
||||
interfacesImplementingSelf)
|
||||
|
||||
# Grab the includes for the things that involve XPCOM interfaces
|
||||
hasInstanceIncludes = set(self.getDeclarationFilename(d.interface) for d
|
||||
in descriptors if
|
||||
d.interface.hasInterfaceObject() and
|
||||
NeedsGeneratedHasInstance(d) and
|
||||
d.interface.hasInterfacePrototypeObject())
|
||||
if len(hasInstanceIncludes) > 0:
|
||||
hasInstanceIncludes.add("nsContentUtils.h")
|
||||
|
||||
# Now find all the things we'll need as arguments because we
|
||||
# need to wrap or unwrap them.
|
||||
bindingHeaders = set()
|
||||
|
@ -1298,7 +1281,6 @@ class CGHeaders(CGWrapper):
|
|||
definePre=_includeString(sorted(set(defineIncludes) |
|
||||
bindingIncludes |
|
||||
bindingHeaders |
|
||||
hasInstanceIncludes |
|
||||
implementationIncludes)))
|
||||
|
||||
@staticmethod
|
||||
|
@ -1980,52 +1962,6 @@ class CGNamedConstructors(CGThing):
|
|||
namedConstructors=namedConstructors)
|
||||
|
||||
|
||||
class CGHasInstanceHook(CGAbstractStaticMethod):
|
||||
def __init__(self, descriptor):
|
||||
args = [Argument('JSContext*', 'cx'),
|
||||
Argument('unsigned', 'argc'),
|
||||
Argument('JS::Value*', 'vp')]
|
||||
assert descriptor.interface.hasInterfaceObject()
|
||||
assert NeedsGeneratedHasInstance(descriptor)
|
||||
CGAbstractStaticMethod.__init__(self, descriptor, HASINSTANCE_HOOK_NAME,
|
||||
'bool', args)
|
||||
|
||||
def define(self):
|
||||
return CGAbstractStaticMethod.define(self)
|
||||
|
||||
def definition_body(self):
|
||||
return self.generate_code()
|
||||
|
||||
def generate_code(self):
|
||||
return fill(
|
||||
"""
|
||||
JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
|
||||
if (!args.get(0).isObject()) {
|
||||
args.rval().setBoolean(false);
|
||||
return true;
|
||||
}
|
||||
|
||||
JS::Rooted<JSObject*> instance(cx, &args[0].toObject());
|
||||
|
||||
static_assert(IsBaseOf<nsISupports, ${nativeType}>::value,
|
||||
"HasInstance only works for nsISupports-based classes.");
|
||||
|
||||
bool ok = InterfaceHasInstance(cx, argc, vp);
|
||||
if (!ok || args.rval().toBoolean()) {
|
||||
return ok;
|
||||
}
|
||||
|
||||
// FIXME Limit this to chrome by checking xpc::AccessCheck::isChrome(obj).
|
||||
nsCOMPtr<nsISupports> native =
|
||||
xpc::UnwrapReflectorToISupports(js::UncheckedUnwrap(instance, /* stopAtWindowProxy = */ false));
|
||||
nsCOMPtr<nsIDOM${name}> qiResult = do_QueryInterface(native);
|
||||
args.rval().setBoolean(!!qiResult);
|
||||
return true;
|
||||
""",
|
||||
nativeType=self.descriptor.nativeType,
|
||||
name=self.descriptor.interface.identifier.name)
|
||||
|
||||
|
||||
def isChromeOnly(m):
|
||||
return m.getExtendedAttribute("ChromeOnly")
|
||||
|
||||
|
@ -2442,20 +2378,6 @@ class MethodDefiner(PropertyDefiner):
|
|||
"condition": MemberCondition()
|
||||
})
|
||||
|
||||
if (static and
|
||||
not unforgeable and
|
||||
descriptor.interface.hasInterfaceObject() and
|
||||
NeedsGeneratedHasInstance(descriptor)):
|
||||
self.regular.append({
|
||||
"name": "@@hasInstance",
|
||||
"methodInfo": False,
|
||||
"nativeName": HASINSTANCE_HOOK_NAME,
|
||||
"length": 1,
|
||||
# Flags match those of Function[Symbol.hasInstance]
|
||||
"flags": "JSPROP_READONLY | JSPROP_PERMANENT",
|
||||
"condition": MemberCondition()
|
||||
})
|
||||
|
||||
# Generate the keys/values/entries aliases for value iterables.
|
||||
maplikeOrSetlikeOrIterable = descriptor.interface.maplikeOrSetlikeOrIterable
|
||||
if (not static and
|
||||
|
@ -3474,38 +3396,6 @@ class CGGetNamedPropertiesObjectMethod(CGAbstractStaticMethod):
|
|||
nativeType=self.descriptor.nativeType)
|
||||
|
||||
|
||||
class CGDefineDOMInterfaceMethod(CGAbstractMethod):
|
||||
"""
|
||||
A method for resolve hooks to try to lazily define the interface object for
|
||||
a given interface.
|
||||
"""
|
||||
def __init__(self, descriptor):
|
||||
args = [Argument('JSContext*', 'aCx'),
|
||||
Argument('JS::Handle<JSObject*>', 'aGlobal'),
|
||||
Argument('JS::Handle<jsid>', 'id'),
|
||||
Argument('bool', 'aDefineOnGlobal')]
|
||||
CGAbstractMethod.__init__(self, descriptor, 'DefineDOMInterface', 'JSObject*', args)
|
||||
|
||||
def definition_body(self):
|
||||
if len(self.descriptor.interface.namedConstructors) > 0:
|
||||
getConstructor = dedent("""
|
||||
JSObject* interfaceObject = GetConstructorObjectHandle(aCx, aDefineOnGlobal);
|
||||
if (!interfaceObject) {
|
||||
return nullptr;
|
||||
}
|
||||
for (unsigned slot = DOM_INTERFACE_SLOTS_BASE; slot < JSCLASS_RESERVED_SLOTS(&sInterfaceObjectClass.mBase); ++slot) {
|
||||
JSObject* constructor = &js::GetReservedSlot(interfaceObject, slot).toObject();
|
||||
if (JS_GetFunctionId(JS_GetObjectFunction(constructor)) == JSID_TO_STRING(id)) {
|
||||
return constructor;
|
||||
}
|
||||
}
|
||||
return interfaceObject;
|
||||
""")
|
||||
else:
|
||||
getConstructor = "return GetConstructorObjectHandle(aCx, aDefineOnGlobal);\n"
|
||||
return getConstructor
|
||||
|
||||
|
||||
def getConditionList(idlobj, cxName, objName):
|
||||
"""
|
||||
Get the list of conditions for idlobj (to be used in "is this enabled"
|
||||
|
@ -4340,14 +4230,6 @@ class CastableObjectUnwrapper():
|
|||
"target": target,
|
||||
"codeOnFailure": codeOnFailure,
|
||||
}
|
||||
# Supporting both the "cross origin object" case and the "has
|
||||
# XPConnect impls" case at the same time is a pain, so let's
|
||||
# not do that. That allows us to assume that our source is
|
||||
# always a Handle or MutableHandle.
|
||||
if allowCrossOriginObj and descriptor.hasXPConnectImpls:
|
||||
raise TypeError("Interface %s both allows a cross-origin 'this' "
|
||||
"and has XPConnect impls. We don't support that" %
|
||||
descriptor.name)
|
||||
if allowCrossOriginObj:
|
||||
self.substitution["uncheckedObjDecl"] = fill(
|
||||
"""
|
||||
|
@ -4368,30 +4250,14 @@ class CastableObjectUnwrapper():
|
|||
codeOnFailure=(codeOnFailure % { 'securityError': 'true'}))
|
||||
self.substitution["source"] = "maybeUncheckedObj"
|
||||
self.substitution["mutableSource"] = "&maybeUncheckedObj"
|
||||
# No need to set up xpconnectUnwrap, since it won't be
|
||||
# used in the allowCrossOriginObj case.
|
||||
else:
|
||||
self.substitution["uncheckedObjDecl"] = ""
|
||||
self.substitution["uncheckedObjGet"] = ""
|
||||
self.substitution["source"] = source
|
||||
self.substitution["mutableSource"] = mutableSource
|
||||
xpconnectUnwrap = (
|
||||
"nsresult rv = UnwrapXPConnect<${type}>(cx, ${mutableSource}, getter_AddRefs(objPtr));\n")
|
||||
|
||||
if descriptor.hasXPConnectImpls:
|
||||
self.substitution["codeOnFailure"] = string.Template(
|
||||
"RefPtr<${type}> objPtr;\n" +
|
||||
xpconnectUnwrap +
|
||||
"if (NS_FAILED(rv)) {\n"
|
||||
"${indentedCodeOnFailure}"
|
||||
"}\n"
|
||||
"// We should have an object\n"
|
||||
"MOZ_ASSERT(objPtr);\n"
|
||||
"${target} = objPtr;\n"
|
||||
).substitute(self.substitution,
|
||||
indentedCodeOnFailure=indent(codeOnFailure))
|
||||
elif (isCallbackReturnValue == "JSImpl" and
|
||||
descriptor.interface.isJSImplemented()):
|
||||
if (isCallbackReturnValue == "JSImpl" and
|
||||
descriptor.interface.isJSImplemented()):
|
||||
exceptionCode = exceptionCode or codeOnFailure
|
||||
self.substitution["codeOnFailure"] = fill(
|
||||
"""
|
||||
|
@ -6835,18 +6701,10 @@ def getWrapTemplateForType(type, descriptorProvider, result, successCode,
|
|||
if isConstructorRetval:
|
||||
wrapArgs += ", desiredProto"
|
||||
wrap = "%s(%s)" % (wrapMethod, wrapArgs)
|
||||
if not descriptor.hasXPConnectImpls:
|
||||
# Can only fail to wrap as a new-binding object
|
||||
# if they already threw an exception.
|
||||
failed = ("MOZ_ASSERT(JS_IsExceptionPending(cx));\n" +
|
||||
exceptionCode)
|
||||
else:
|
||||
if descriptor.notflattened:
|
||||
raise TypeError("%s has XPConnect impls but not flattened; "
|
||||
"fallback won't work correctly" %
|
||||
descriptor.interface.identifier.name)
|
||||
# Try old-style wrapping for bindings which might be XPConnect impls.
|
||||
failed = wrapAndSetPtr("HandleNewBindingWrappingFailure(cx, ${obj}, %s, ${jsvalHandle})" % result)
|
||||
# Can only fail to wrap as a new-binding object if they already
|
||||
# threw an exception.
|
||||
failed = ("MOZ_ASSERT(JS_IsExceptionPending(cx));\n" +
|
||||
exceptionCode)
|
||||
else:
|
||||
if descriptor.notflattened:
|
||||
getIID = "&NS_GET_IID(%s), " % descriptor.nativeType
|
||||
|
@ -9226,12 +9084,6 @@ class CGSpecializedGetter(CGAbstractStaticMethod):
|
|||
nativeName = CGSpecializedGetter.makeNativeName(self.descriptor,
|
||||
self.attr)
|
||||
if self.attr.slotIndices is not None:
|
||||
if self.descriptor.hasXPConnectImpls:
|
||||
raise TypeError("Interface '%s' has XPConnect impls, so we "
|
||||
"can't use our slot for property '%s'!" %
|
||||
(self.descriptor.interface.identifier.name,
|
||||
self.attr.identifier.name))
|
||||
|
||||
# We're going to store this return value in a slot on some object,
|
||||
# to cache it. The question is, which object? For dictionary and
|
||||
# sequence return values, we want to use a slot on the Xray expando
|
||||
|
@ -12863,12 +12715,6 @@ class CGDescriptor(CGThing):
|
|||
for m in clearableCachedAttrs(descriptor):
|
||||
cgThings.append(CGJSImplClearCachedValueMethod(descriptor, m))
|
||||
|
||||
# Need to output our generated hasinstance bits before
|
||||
# PropertyArrays tries to use them.
|
||||
if (descriptor.interface.hasInterfaceObject() and
|
||||
NeedsGeneratedHasInstance(descriptor)):
|
||||
cgThings.append(CGHasInstanceHook(descriptor))
|
||||
|
||||
properties = PropertyArrays(descriptor)
|
||||
cgThings.append(CGGeneric(define=str(properties)))
|
||||
cgThings.append(CGNativeProperties(descriptor, properties))
|
||||
|
@ -12896,9 +12742,6 @@ class CGDescriptor(CGThing):
|
|||
descriptor.isExposedConditionally()):
|
||||
cgThings.append(CGConstructorEnabled(descriptor))
|
||||
|
||||
if descriptor.registersGlobalNamesOnWindow:
|
||||
cgThings.append(CGDefineDOMInterfaceMethod(descriptor))
|
||||
|
||||
if (descriptor.interface.hasMembersInSlots() and
|
||||
descriptor.interface.hasChildInterfaces()):
|
||||
raise TypeError("We don't support members in slots on "
|
||||
|
@ -14031,7 +13874,7 @@ class CGRegisterGlobalNames(CGAbstractMethod):
|
|||
currentOffset = 0
|
||||
for (name, desc) in getGlobalNames(self.config):
|
||||
length = len(name)
|
||||
define += "WebIDLGlobalNameHash::Register(%i, %i, %sBinding::DefineDOMInterface, %s, constructors::id::%s);\n" % (
|
||||
define += "WebIDLGlobalNameHash::Register(%i, %i, %sBinding::CreateInterfaceObjects, %s, constructors::id::%s);\n" % (
|
||||
currentOffset, length, desc.name, getCheck(desc), desc.name)
|
||||
currentOffset += length + 1 # Add trailing null.
|
||||
return define
|
||||
|
@ -15423,13 +15266,6 @@ class CGJSImplMethod(CGJSImplMember):
|
|||
interface.
|
||||
"""
|
||||
def __init__(self, descriptor, method, signature, isConstructor, breakAfter=True):
|
||||
virtual = False
|
||||
override = False
|
||||
if (method.identifier.name == "eventListenerWasAdded" or
|
||||
method.identifier.name == "eventListenerWasRemoved"):
|
||||
virtual = True
|
||||
override = True
|
||||
|
||||
self.signature = signature
|
||||
self.descriptor = descriptor
|
||||
self.isConstructor = isConstructor
|
||||
|
@ -15440,9 +15276,7 @@ class CGJSImplMethod(CGJSImplMember):
|
|||
descriptor.getExtendedAttributes(method),
|
||||
breakAfter=breakAfter,
|
||||
variadicIsSequence=True,
|
||||
passJSBitsAsNeeded=False,
|
||||
virtual=virtual,
|
||||
override=override)
|
||||
passJSBitsAsNeeded=False)
|
||||
|
||||
def getArgs(self, returnType, argList):
|
||||
if self.isConstructor:
|
||||
|
@ -15662,6 +15496,15 @@ class CGJSImplClass(CGBindingImplClass):
|
|||
ccDecl=ccDecl,
|
||||
jsImplName=jsImplName(descriptor.name))
|
||||
|
||||
if descriptor.interface.getExtendedAttribute("WantsEventListenerHooks"):
|
||||
# No need to do too much sanity checking here; the
|
||||
# generated code will fail to compile if the methods we
|
||||
# try to overrid aren't on a superclass.
|
||||
self.methodDecls.extend(
|
||||
self.getEventHookMethod(parentClass, "EventListenerAdded"))
|
||||
self.methodDecls.extend(
|
||||
self.getEventHookMethod(parentClass, "EventListenerRemoved"))
|
||||
|
||||
if descriptor.interface.hasChildInterfaces():
|
||||
decorators = ""
|
||||
# We need a protected virtual destructor our subclasses can use
|
||||
|
@ -15790,6 +15633,22 @@ class CGJSImplClass(CGBindingImplClass):
|
|||
ifaceName=self.descriptor.interface.identifier.name,
|
||||
implName=self.descriptor.name)
|
||||
|
||||
def getEventHookMethod(self, parentClass, methodName):
|
||||
body = fill(
|
||||
"""
|
||||
${parentClass}::${methodName}(aType);
|
||||
mImpl->${methodName}(Substring(nsDependentAtomString(aType), 2), IgnoreErrors());
|
||||
""",
|
||||
parentClass=parentClass,
|
||||
methodName=methodName)
|
||||
return [ClassMethod(methodName,
|
||||
"void",
|
||||
[Argument("nsAtom*", "aType")],
|
||||
virtual=True,
|
||||
override=True,
|
||||
body=body),
|
||||
ClassUsingDeclaration(parentClass, methodName)]
|
||||
|
||||
|
||||
def isJSImplementedDescriptor(descriptorProvider):
|
||||
return (isinstance(descriptorProvider, Descriptor) and
|
||||
|
@ -16102,6 +15961,16 @@ class CGCallbackInterface(CGCallback):
|
|||
idlist.append("__init")
|
||||
if needOnGetId:
|
||||
idlist.append("__onget")
|
||||
|
||||
if (iface.isJSImplemented() and
|
||||
iface.getExtendedAttribute("WantsEventListenerHooks")):
|
||||
methods.append(CGJSImplEventHookOperation(descriptor,
|
||||
"eventListenerAdded"))
|
||||
methods.append(CGJSImplEventHookOperation(descriptor,
|
||||
"eventListenerRemoved"))
|
||||
idlist.append("eventListenerAdded")
|
||||
idlist.append("eventListenerRemoved")
|
||||
|
||||
if len(idlist) != 0:
|
||||
methods.append(initIdsClassMethod(idlist,
|
||||
iface.identifier.name + "Atoms"))
|
||||
|
@ -16647,6 +16516,27 @@ class CGJSImplOnGetOperation(CallbackOperationBase):
|
|||
def getPrettyName(self):
|
||||
return "__onget"
|
||||
|
||||
class CGJSImplEventHookOperation(CallbackOperationBase):
|
||||
"""
|
||||
Codegen the hooks on a JS impl for adding/removing event listeners.
|
||||
"""
|
||||
def __init__(self, descriptor, name):
|
||||
self.name = name
|
||||
|
||||
CallbackOperationBase.__init__(
|
||||
self,
|
||||
(BuiltinTypes[IDLBuiltinType.Types.void],
|
||||
[FakeArgument(BuiltinTypes[IDLBuiltinType.Types.domstring],
|
||||
None,
|
||||
"aType")]),
|
||||
name, MakeNativeName(name),
|
||||
descriptor,
|
||||
singleOperation=False,
|
||||
rethrowContentException=False,
|
||||
spiderMonkeyInterfacesAreStructs=True)
|
||||
|
||||
def getPrettyName(self):
|
||||
return self.name
|
||||
|
||||
def getMaplikeOrSetlikeErrorReturn(helperImpl):
|
||||
"""
|
||||
|
@ -17249,6 +17139,10 @@ class GlobalGenRoots():
|
|||
d.interface.maplikeOrSetlikeOrIterable.isMaplike()):
|
||||
# We'll have an __onget() method.
|
||||
members.append(FakeMember('__onget'))
|
||||
if (d.interface.isJSImplemented() and
|
||||
d.interface.getExtendedAttribute("WantsEventListenerHooks")):
|
||||
members.append(FakeMember('eventListenerAdded'))
|
||||
members.append(FakeMember('eventListenerRemoved'))
|
||||
if len(members) == 0:
|
||||
continue
|
||||
|
||||
|
|
|
@ -399,8 +399,6 @@ class Descriptor(DescriptorProvider):
|
|||
self.notflattened = desc.get('notflattened', False)
|
||||
self.register = desc.get('register', True)
|
||||
|
||||
self.hasXPConnectImpls = desc.get('hasXPConnectImpls', False)
|
||||
|
||||
# If we're concrete, we need to crawl our ancestor interfaces and mark
|
||||
# them as having a concrete descendant.
|
||||
self.concrete = (not self.interface.isExternal() and
|
||||
|
@ -762,10 +760,10 @@ class Descriptor(DescriptorProvider):
|
|||
Returns true if this descriptor requires generic ops other than
|
||||
GenericBindingMethod/GenericBindingGetter/GenericBindingSetter.
|
||||
|
||||
In practice we need to do this if our this value might be an XPConnect
|
||||
object or if we need to coerce null/undefined to the global.
|
||||
In practice we need to do this if we need to coerce null/undefined
|
||||
to the global.
|
||||
"""
|
||||
return self.hasXPConnectImpls or self.interface.isOnGlobalProtoChain()
|
||||
return self.interface.isOnGlobalProtoChain()
|
||||
|
||||
def isGlobal(self):
|
||||
"""
|
||||
|
|
|
@ -5,13 +5,18 @@
|
|||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "WebIDLGlobalNameHash.h"
|
||||
#include "js/Class.h"
|
||||
#include "js/GCAPI.h"
|
||||
#include "js/Id.h"
|
||||
#include "js/Wrapper.h"
|
||||
#include "jsapi.h"
|
||||
#include "jsfriendapi.h"
|
||||
#include "mozilla/ErrorResult.h"
|
||||
#include "mozilla/HashFunctions.h"
|
||||
#include "mozilla/Maybe.h"
|
||||
#include "mozilla/dom/DOMJSClass.h"
|
||||
#include "mozilla/dom/DOMJSProxyHandler.h"
|
||||
#include "mozilla/dom/JSSlots.h"
|
||||
#include "mozilla/dom/PrototypeList.h"
|
||||
#include "mozilla/dom/RegisterBindings.h"
|
||||
#include "nsGlobalWindow.h"
|
||||
|
@ -65,14 +70,14 @@ struct WebIDLNameTableEntry : public PLDHashEntryHdr
|
|||
: mNameOffset(0),
|
||||
mNameLength(0),
|
||||
mConstructorId(constructors::id::_ID_Count),
|
||||
mDefine(nullptr),
|
||||
mCreate(nullptr),
|
||||
mEnabled(nullptr)
|
||||
{}
|
||||
WebIDLNameTableEntry(WebIDLNameTableEntry&& aEntry)
|
||||
: mNameOffset(aEntry.mNameOffset),
|
||||
mNameLength(aEntry.mNameLength),
|
||||
mConstructorId(aEntry.mConstructorId),
|
||||
mDefine(aEntry.mDefine),
|
||||
mCreate(aEntry.mCreate),
|
||||
mEnabled(aEntry.mEnabled)
|
||||
{}
|
||||
~WebIDLNameTableEntry()
|
||||
|
@ -109,7 +114,7 @@ struct WebIDLNameTableEntry : public PLDHashEntryHdr
|
|||
uint16_t mNameOffset;
|
||||
uint16_t mNameLength;
|
||||
constructors::id::ID mConstructorId;
|
||||
WebIDLGlobalNameHash::DefineGlobalName mDefine;
|
||||
CreateInterfaceObjectsMethod mCreate;
|
||||
// May be null if enabled unconditionally
|
||||
WebIDLGlobalNameHash::ConstructorEnabled mEnabled;
|
||||
};
|
||||
|
@ -162,7 +167,7 @@ WebIDLGlobalNameHash::Shutdown()
|
|||
/* static */
|
||||
void
|
||||
WebIDLGlobalNameHash::Register(uint16_t aNameOffset, uint16_t aNameLength,
|
||||
DefineGlobalName aDefine,
|
||||
CreateInterfaceObjectsMethod aCreate,
|
||||
ConstructorEnabled aEnabled,
|
||||
constructors::id::ID aConstructorId)
|
||||
{
|
||||
|
@ -171,7 +176,7 @@ WebIDLGlobalNameHash::Register(uint16_t aNameOffset, uint16_t aNameLength,
|
|||
WebIDLNameTableEntry* entry = sWebIDLGlobalNames->PutEntry(key);
|
||||
entry->mNameOffset = aNameOffset;
|
||||
entry->mNameLength = aNameLength;
|
||||
entry->mDefine = aDefine;
|
||||
entry->mCreate = aCreate;
|
||||
entry->mEnabled = aEnabled;
|
||||
entry->mConstructorId = aConstructorId;
|
||||
}
|
||||
|
@ -184,6 +189,35 @@ WebIDLGlobalNameHash::Remove(const char* aName, uint32_t aLength)
|
|||
sWebIDLGlobalNames->RemoveEntry(key);
|
||||
}
|
||||
|
||||
static JSObject*
|
||||
FindNamedConstructorForXray(JSContext* aCx, JS::Handle<jsid> aId,
|
||||
const WebIDLNameTableEntry* aEntry)
|
||||
{
|
||||
JSObject* interfaceObject =
|
||||
GetPerInterfaceObjectHandle(aCx, aEntry->mConstructorId,
|
||||
aEntry->mCreate,
|
||||
/* aDefineOnGlobal = */ false);
|
||||
if (!interfaceObject) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// This is a call over Xrays, so we will actually use the return value
|
||||
// (instead of just having it defined on the global now). Check for named
|
||||
// constructors with this id, in case that's what the caller is asking for.
|
||||
for (unsigned slot = DOM_INTERFACE_SLOTS_BASE;
|
||||
slot < JSCLASS_RESERVED_SLOTS(js::GetObjectClass(interfaceObject));
|
||||
++slot) {
|
||||
JSObject* constructor = &js::GetReservedSlot(interfaceObject, slot).toObject();
|
||||
if (JS_GetFunctionId(JS_GetObjectFunction(constructor)) == JSID_TO_STRING(aId)) {
|
||||
return constructor;
|
||||
}
|
||||
}
|
||||
|
||||
// None of the named constructors match, so the caller must want the
|
||||
// interface object itself.
|
||||
return interfaceObject;
|
||||
}
|
||||
|
||||
/* static */
|
||||
bool
|
||||
WebIDLGlobalNameHash::DefineIfEnabled(JSContext* aCx,
|
||||
|
@ -272,24 +306,26 @@ WebIDLGlobalNameHash::DefineIfEnabled(JSContext* aCx,
|
|||
// This all could use some grand refactoring, but for now we just limp
|
||||
// along.
|
||||
if (xpc::WrapperFactory::IsXrayWrapper(aObj)) {
|
||||
JS::Rooted<JSObject*> interfaceObject(aCx);
|
||||
JS::Rooted<JSObject*> constructor(aCx);
|
||||
{
|
||||
JSAutoCompartment ac(aCx, global);
|
||||
interfaceObject = entry->mDefine(aCx, global, aId, false);
|
||||
constructor = FindNamedConstructorForXray(aCx, aId, entry);
|
||||
}
|
||||
if (NS_WARN_IF(!interfaceObject)) {
|
||||
if (NS_WARN_IF(!constructor)) {
|
||||
return Throw(aCx, NS_ERROR_FAILURE);
|
||||
}
|
||||
if (!JS_WrapObject(aCx, &interfaceObject)) {
|
||||
if (!JS_WrapObject(aCx, &constructor)) {
|
||||
return Throw(aCx, NS_ERROR_FAILURE);
|
||||
}
|
||||
|
||||
FillPropertyDescriptor(aDesc, aObj, 0, JS::ObjectValue(*interfaceObject));
|
||||
FillPropertyDescriptor(aDesc, aObj, 0, JS::ObjectValue(*constructor));
|
||||
return true;
|
||||
}
|
||||
|
||||
JS::Rooted<JSObject*> interfaceObject(aCx,
|
||||
entry->mDefine(aCx, aObj, aId, true));
|
||||
GetPerInterfaceObjectHandle(aCx, entry->mConstructorId,
|
||||
entry->mCreate,
|
||||
/* aDefineOnGlobal = */ true));
|
||||
if (NS_WARN_IF(!interfaceObject)) {
|
||||
return Throw(aCx, NS_ERROR_FAILURE);
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include "js/RootingAPI.h"
|
||||
#include "nsTArray.h"
|
||||
#include "mozilla/dom/BindingDeclarations.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
@ -27,10 +28,6 @@ public:
|
|||
static void Init();
|
||||
static void Shutdown();
|
||||
|
||||
typedef JSObject*
|
||||
(*DefineGlobalName)(JSContext* cx, JS::Handle<JSObject*> global,
|
||||
JS::Handle<jsid> id, bool defineOnGlobal);
|
||||
|
||||
// Check whether a constructor should be enabled for the given object.
|
||||
// Note that the object should NOT be an Xray, since Xrays will end up
|
||||
// defining constructors on the underlying object.
|
||||
|
@ -41,7 +38,8 @@ public:
|
|||
(*ConstructorEnabled)(JSContext* cx, JS::Handle<JSObject*> obj);
|
||||
|
||||
static void Register(uint16_t aNameOffset, uint16_t aNameLength,
|
||||
DefineGlobalName aDefine, ConstructorEnabled aEnabled,
|
||||
CreateInterfaceObjectsMethod aCreate,
|
||||
ConstructorEnabled aEnabled,
|
||||
constructors::id::ID aConstructorId);
|
||||
|
||||
static void Remove(const char* aName, uint32_t aLength);
|
||||
|
|
|
@ -1744,6 +1744,7 @@ class IDLInterface(IDLInterfaceOrNamespace):
|
|||
identifier == "ProbablyShortLivingWrapper" or
|
||||
identifier == "LegacyUnenumerableNamedProperties" or
|
||||
identifier == "RunConstructorInCallerCompartment" or
|
||||
identifier == "WantsEventListenerHooks" or
|
||||
identifier == "NonOrdinaryGetPrototypeOf"):
|
||||
# Known extended attributes that do not take values
|
||||
if not attr.noArguments():
|
||||
|
|
|
@ -5,6 +5,7 @@ support-files =
|
|||
broadcastchannel_worker.js
|
||||
broadcastchannel_worker_alive.js
|
||||
broadcastchannel_worker_any.js
|
||||
!/dom/events/test/event_leak_utils.js
|
||||
file_mozbrowser.html
|
||||
file_mozbrowser2.html
|
||||
iframe_mozbrowser.html
|
||||
|
@ -21,6 +22,7 @@ support-files =
|
|||
[test_broadcastchannel_worker.html]
|
||||
[test_broadcastchannel_worker_alive.html]
|
||||
[test_bfcache.html]
|
||||
[test_event_listener_leaks.html]
|
||||
[test_invalidState.html]
|
||||
[test_ordering.html]
|
||||
[test_dataCloning.html]
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Bug 1450358 - Test BroadcastChannel event listener leak conditions</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="text/javascript" src="/tests/dom/events/test/event_leak_utils.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<script class="testbody" type="text/javascript">
|
||||
// Manipulate BroadcastChannel objects in the frame's context.
|
||||
// Its important here that we create a listener callback from
|
||||
// the DOM objects back to the frame's global in order to
|
||||
// exercise the leak condition.
|
||||
let count = 0;
|
||||
async function useBroadcastChannel(contentWindow) {
|
||||
contentWindow.messageCount = 0;
|
||||
|
||||
count += 1;
|
||||
const name = `test_event_listener_leaks-${count}`;
|
||||
|
||||
let outer = new BroadcastChannel(name);
|
||||
outer.postMessage('foo');
|
||||
|
||||
let bc = new contentWindow.BroadcastChannel(name);
|
||||
await new Promise(resolve => {
|
||||
bc.onmessage = e => {
|
||||
contentWindow.messageCount += 1;
|
||||
resolve();
|
||||
};
|
||||
});
|
||||
|
||||
is(contentWindow.messageCount, 1, "message should be received");
|
||||
}
|
||||
|
||||
async function runTest() {
|
||||
try {
|
||||
await checkForEventListenerLeaks("BroadcastChannel", useBroadcastChannel);
|
||||
} catch (e) {
|
||||
ok(false, e);
|
||||
} finally {
|
||||
SimpleTest.finish();
|
||||
}
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addEventListener("load", runTest, { once: true });
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -347,30 +347,24 @@ DOMEventTargetHelper::WantsUntrusted(bool* aRetVal)
|
|||
void
|
||||
DOMEventTargetHelper::EventListenerAdded(nsAtom* aType)
|
||||
{
|
||||
EventListenerWasAdded(Substring(nsDependentAtomString(aType), 2),
|
||||
IgnoreErrors());
|
||||
MaybeUpdateKeepAlive();
|
||||
}
|
||||
|
||||
void
|
||||
DOMEventTargetHelper::EventListenerAdded(const nsAString& aType)
|
||||
{
|
||||
EventListenerWasAdded(aType, IgnoreErrors());
|
||||
MaybeUpdateKeepAlive();
|
||||
}
|
||||
|
||||
void
|
||||
DOMEventTargetHelper::EventListenerRemoved(nsAtom* aType)
|
||||
{
|
||||
EventListenerWasRemoved(Substring(nsDependentAtomString(aType), 2),
|
||||
IgnoreErrors());
|
||||
MaybeUpdateKeepAlive();
|
||||
}
|
||||
|
||||
void
|
||||
DOMEventTargetHelper::EventListenerRemoved(const nsAString& aType)
|
||||
{
|
||||
EventListenerWasRemoved(aType, IgnoreErrors());
|
||||
MaybeUpdateKeepAlive();
|
||||
}
|
||||
|
||||
|
|
|
@ -156,13 +156,6 @@ public:
|
|||
virtual void EventListenerRemoved(nsAtom* aType) override;
|
||||
virtual void EventListenerRemoved(const nsAString& aType) override;
|
||||
|
||||
virtual void EventListenerWasAdded(const nsAString& aType,
|
||||
ErrorResult& aRv,
|
||||
JSCompartment* aCompartment = nullptr) {}
|
||||
virtual void EventListenerWasRemoved(const nsAString& aType,
|
||||
ErrorResult& aRv,
|
||||
JSCompartment* aCompartment = nullptr) {}
|
||||
|
||||
// Dispatch a trusted, non-cancellable and non-bubbling event to |this|.
|
||||
nsresult DispatchTrustedEvent(const nsAString& aEventName);
|
||||
protected:
|
||||
|
|
|
@ -690,15 +690,32 @@ void
|
|||
EventListenerManager::AddEventListenerByType(
|
||||
EventListenerHolder aListenerHolder,
|
||||
const nsAString& aType,
|
||||
const EventListenerFlags& aFlags)
|
||||
const EventListenerFlags& aFlags,
|
||||
const Optional<bool>& aPassive)
|
||||
{
|
||||
RefPtr<nsAtom> atom;
|
||||
EventMessage message = mIsMainThreadELM ?
|
||||
nsContentUtils::GetEventMessageAndAtomForListener(aType,
|
||||
getter_AddRefs(atom)) :
|
||||
eUnidentifiedEvent;
|
||||
|
||||
EventListenerFlags flags = aFlags;
|
||||
if (aPassive.WasPassed()) {
|
||||
flags.mPassive = aPassive.Value();
|
||||
} else if (message == eTouchStart || message == eTouchMove) {
|
||||
nsCOMPtr<nsINode> node;
|
||||
nsCOMPtr<nsPIDOMWindowInner> win;
|
||||
if ((win = GetTargetAsInnerWindow()) ||
|
||||
((node = do_QueryInterface(mTarget)) &&
|
||||
(node == node->OwnerDoc() ||
|
||||
node == node->OwnerDoc()->GetRootElement() ||
|
||||
node == node->OwnerDoc()->GetBody()))) {
|
||||
flags.mPassive = true;
|
||||
}
|
||||
}
|
||||
|
||||
AddEventListenerInternal(Move(aListenerHolder),
|
||||
message, atom, aType, aFlags);
|
||||
message, atom, aType, flags);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1365,17 +1382,20 @@ EventListenerManager::AddEventListener(
|
|||
bool aWantsUntrusted)
|
||||
{
|
||||
EventListenerFlags flags;
|
||||
Optional<bool> passive;
|
||||
if (aOptions.IsBoolean()) {
|
||||
flags.mCapture = aOptions.GetAsBoolean();
|
||||
} else {
|
||||
const auto& options = aOptions.GetAsAddEventListenerOptions();
|
||||
flags.mCapture = options.mCapture;
|
||||
flags.mInSystemGroup = options.mMozSystemGroup;
|
||||
flags.mPassive = options.mPassive;
|
||||
flags.mOnce = options.mOnce;
|
||||
if (options.mPassive.WasPassed()) {
|
||||
passive.Construct(options.mPassive.Value());
|
||||
}
|
||||
}
|
||||
flags.mAllowUntrustedEvents = aWantsUntrusted;
|
||||
return AddEventListenerByType(Move(aListenerHolder), aType, flags);
|
||||
return AddEventListenerByType(Move(aListenerHolder), aType, flags, passive);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -317,7 +317,9 @@ public:
|
|||
}
|
||||
void AddEventListenerByType(EventListenerHolder aListener,
|
||||
const nsAString& type,
|
||||
const EventListenerFlags& aFlags);
|
||||
const EventListenerFlags& aFlags,
|
||||
const dom::Optional<bool>& aPassive =
|
||||
dom::Optional<bool>());
|
||||
void RemoveEventListenerByType(nsIDOMEventListener *aListener,
|
||||
const nsAString& type,
|
||||
const EventListenerFlags& aFlags)
|
||||
|
|
|
@ -2963,7 +2963,7 @@ NodeAllowsClickThrough(nsINode* aNode)
|
|||
if (aNode->IsXULElement()) {
|
||||
mozilla::dom::Element* element = aNode->AsElement();
|
||||
static Element::AttrValuesArray strings[] =
|
||||
{&nsGkAtoms::always, &nsGkAtoms::never, nullptr};
|
||||
{nsGkAtoms::always, nsGkAtoms::never, nullptr};
|
||||
switch (element->FindAttrValueIn(kNameSpaceID_None, nsGkAtoms::clickthrough,
|
||||
strings, eCaseMatters)) {
|
||||
case 0:
|
||||
|
|
|
@ -76,10 +76,19 @@ public:
|
|||
void SetEventHandler(const nsAString& aType, EventHandlerNonNull* aHandler,
|
||||
ErrorResult& rv);
|
||||
|
||||
// Note, for an event 'foo' aType will be 'onfoo'.
|
||||
// The nsAtom version of EventListenerAdded is called on the main
|
||||
// thread. The string version is called on workers.
|
||||
//
|
||||
// For an event 'foo' aType will be 'onfoo' when it's an atom and
|
||||
// 'foo' when it's a string..
|
||||
virtual void EventListenerAdded(nsAtom* aType) {}
|
||||
virtual void EventListenerAdded(const nsAString& aType) {}
|
||||
|
||||
// The nsAtom version of EventListenerRemoved is called on the main
|
||||
// thread. The string version is called on workers.
|
||||
//
|
||||
// For an event 'foo' aType will be 'onfoo' when it's an atom and
|
||||
// 'foo' when it's a string..
|
||||
virtual void EventListenerRemoved(nsAtom* aType) {}
|
||||
virtual void EventListenerRemoved(const nsAString& aType) {}
|
||||
|
||||
|
|
|
@ -244,7 +244,7 @@ TouchEvent::PrefEnabled(nsIDocShell* aDocShell)
|
|||
}
|
||||
|
||||
// static
|
||||
already_AddRefed<Event>
|
||||
already_AddRefed<TouchEvent>
|
||||
TouchEvent::Constructor(const GlobalObject& aGlobal,
|
||||
const nsAString& aType,
|
||||
const TouchEventInit& aParam,
|
||||
|
|
|
@ -120,10 +120,10 @@ public:
|
|||
static bool PrefEnabled(JSContext* aCx, JSObject* aGlobal);
|
||||
static bool PrefEnabled(nsIDocShell* aDocShell);
|
||||
|
||||
static already_AddRefed<Event> Constructor(const GlobalObject& aGlobal,
|
||||
const nsAString& aType,
|
||||
const TouchEventInit& aParam,
|
||||
ErrorResult& aRv);
|
||||
static already_AddRefed<TouchEvent> Constructor(const GlobalObject& aGlobal,
|
||||
const nsAString& aType,
|
||||
const TouchEventInit& aParam,
|
||||
ErrorResult& aRv);
|
||||
|
||||
protected:
|
||||
~TouchEvent() {}
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
// Any copyright is dedicated to the Public Domain.
|
||||
// http://creativecommons.org/publicdomain/zero/1.0/
|
||||
"use strict"
|
||||
|
||||
// This function runs a number of tests where:
|
||||
//
|
||||
// 1. An iframe is created
|
||||
// 2. The target callback is executed with the iframe's contentWindow as
|
||||
// an argument.
|
||||
// 3. The iframe is destroyed and GC is forced.
|
||||
// 4. Verifies that the iframe's contentWindow has been GC'd.
|
||||
//
|
||||
// Different ways of destroying the iframe are checked. Simple
|
||||
// remove(), destruction via bfcache, or replacement by document.open().
|
||||
//
|
||||
// Please pass a target callback that exercises the API under
|
||||
// test using the given window. The callback should try to leave the
|
||||
// API active to increase the liklihood of provoking an API. Any activity
|
||||
// should be canceled by the destruction of the window.
|
||||
async function checkForEventListenerLeaks(name, target) {
|
||||
// Test if we leak in the case where we do nothing special to
|
||||
// the frame before removing it from the DOM.
|
||||
await _eventListenerLeakStep(target, `${name} default`);
|
||||
|
||||
// Test the case where we navigate the frame before removing it
|
||||
// from the DOM so that the window using the target API ends up
|
||||
// in bfcache.
|
||||
await _eventListenerLeakStep(target, `${name} bfcache`, frame => {
|
||||
frame.src = "about:blank";
|
||||
return new Promise(resolve => frame.onload = resolve);
|
||||
});
|
||||
|
||||
// Test the case where we document.open() the frame before removing
|
||||
// it from the DOM so that the window using the target API ends
|
||||
// up getting replaced.
|
||||
await _eventListenerLeakStep(target, `${name} document.open()`, frame => {
|
||||
frame.contentDocument.open();
|
||||
frame.contentDocument.close();
|
||||
});
|
||||
}
|
||||
|
||||
// ----------------
|
||||
// Internal helpers
|
||||
// ----------------
|
||||
|
||||
// Utility function to create a loaded iframe.
|
||||
async function _withFrame(doc, url) {
|
||||
let frame = doc.createElement('iframe');
|
||||
frame.src = url;
|
||||
doc.body.appendChild(frame);
|
||||
await new Promise(resolve => frame.onload = resolve);
|
||||
return frame;
|
||||
}
|
||||
|
||||
// This function defines the basic form of the test cases. We create an
|
||||
// iframe, execute the target callback to manipulate the DOM, remove the frame
|
||||
// from the DOM, and then check to see if the frame was GC'd. The caller
|
||||
// may optionally pass in a callback that will be executed with the
|
||||
// frame as an argument before removing it from the DOM.
|
||||
async function _eventListenerLeakStep(target, name, extra) {
|
||||
let frame = await _withFrame(document, "empty.html");
|
||||
|
||||
await target(frame.contentWindow);
|
||||
|
||||
let weakRef = SpecialPowers.Cu.getWeakReference(frame.contentWindow);
|
||||
ok(weakRef.get(), `should be able to create a weak reference - ${name}`);
|
||||
|
||||
if (extra) {
|
||||
await extra(frame);
|
||||
}
|
||||
|
||||
frame.remove();
|
||||
frame = null;
|
||||
|
||||
// Perform two GC'd to avoid intermittent delayed collection.
|
||||
await new Promise(resolve => SpecialPowers.exactGC(resolve));
|
||||
await new Promise(resolve => SpecialPowers.exactGC(resolve));
|
||||
|
||||
ok(!weakRef.get(), `iframe content window should be garbage collected - ${name}`);
|
||||
}
|
||||
|
|
@ -15,6 +15,7 @@ support-files =
|
|||
bug418986-3.js
|
||||
error_event_worker.js
|
||||
empty.js
|
||||
event_leak_utils.js
|
||||
window_bug493251.html
|
||||
window_bug659071.html
|
||||
window_wheel_default_action.html
|
||||
|
|
|
@ -67,7 +67,7 @@ NS_IMETHODIMP_(bool)
|
|||
HTMLBRElement::IsAttributeMapped(const nsAtom* aAttribute) const
|
||||
{
|
||||
static const MappedAttributeEntry attributes[] = {
|
||||
{ &nsGkAtoms::clear },
|
||||
{ nsGkAtoms::clear },
|
||||
{ nullptr }
|
||||
};
|
||||
|
||||
|
|
|
@ -232,16 +232,16 @@ NS_IMETHODIMP_(bool)
|
|||
HTMLBodyElement::IsAttributeMapped(const nsAtom* aAttribute) const
|
||||
{
|
||||
static const MappedAttributeEntry attributes[] = {
|
||||
{ &nsGkAtoms::link },
|
||||
{ &nsGkAtoms::vlink },
|
||||
{ &nsGkAtoms::alink },
|
||||
{ &nsGkAtoms::text },
|
||||
{ &nsGkAtoms::marginwidth },
|
||||
{ &nsGkAtoms::marginheight },
|
||||
{ &nsGkAtoms::topmargin },
|
||||
{ &nsGkAtoms::rightmargin },
|
||||
{ &nsGkAtoms::bottommargin },
|
||||
{ &nsGkAtoms::leftmargin },
|
||||
{ nsGkAtoms::link },
|
||||
{ nsGkAtoms::vlink },
|
||||
{ nsGkAtoms::alink },
|
||||
{ nsGkAtoms::text },
|
||||
{ nsGkAtoms::marginwidth },
|
||||
{ nsGkAtoms::marginheight },
|
||||
{ nsGkAtoms::topmargin },
|
||||
{ nsGkAtoms::rightmargin },
|
||||
{ nsGkAtoms::bottommargin },
|
||||
{ nsGkAtoms::leftmargin },
|
||||
{ nullptr },
|
||||
};
|
||||
|
||||
|
|
|
@ -98,9 +98,9 @@ NS_IMETHODIMP_(bool)
|
|||
HTMLFontElement::IsAttributeMapped(const nsAtom* aAttribute) const
|
||||
{
|
||||
static const MappedAttributeEntry attributes[] = {
|
||||
{ &nsGkAtoms::face },
|
||||
{ &nsGkAtoms::size },
|
||||
{ &nsGkAtoms::color },
|
||||
{ nsGkAtoms::face },
|
||||
{ nsGkAtoms::size },
|
||||
{ nsGkAtoms::color },
|
||||
{ nullptr }
|
||||
};
|
||||
|
||||
|
|
|
@ -171,11 +171,11 @@ NS_IMETHODIMP_(bool)
|
|||
HTMLHRElement::IsAttributeMapped(const nsAtom* aAttribute) const
|
||||
{
|
||||
static const MappedAttributeEntry attributes[] = {
|
||||
{ &nsGkAtoms::align },
|
||||
{ &nsGkAtoms::width },
|
||||
{ &nsGkAtoms::size },
|
||||
{ &nsGkAtoms::color },
|
||||
{ &nsGkAtoms::noshade },
|
||||
{ nsGkAtoms::align },
|
||||
{ nsGkAtoms::width },
|
||||
{ nsGkAtoms::size },
|
||||
{ nsGkAtoms::color },
|
||||
{ nsGkAtoms::noshade },
|
||||
{ nullptr },
|
||||
};
|
||||
|
||||
|
|
|
@ -109,9 +109,9 @@ NS_IMETHODIMP_(bool)
|
|||
HTMLIFrameElement::IsAttributeMapped(const nsAtom* aAttribute) const
|
||||
{
|
||||
static const MappedAttributeEntry attributes[] = {
|
||||
{ &nsGkAtoms::width },
|
||||
{ &nsGkAtoms::height },
|
||||
{ &nsGkAtoms::frameborder },
|
||||
{ nsGkAtoms::width },
|
||||
{ nsGkAtoms::height },
|
||||
{ nsGkAtoms::frameborder },
|
||||
{ nullptr },
|
||||
};
|
||||
|
||||
|
|
|
@ -5819,8 +5819,8 @@ NS_IMETHODIMP_(bool)
|
|||
HTMLInputElement::IsAttributeMapped(const nsAtom* aAttribute) const
|
||||
{
|
||||
static const MappedAttributeEntry attributes[] = {
|
||||
{ &nsGkAtoms::align },
|
||||
{ &nsGkAtoms::type },
|
||||
{ nsGkAtoms::align },
|
||||
{ nsGkAtoms::type },
|
||||
{ nullptr },
|
||||
};
|
||||
|
||||
|
|
|
@ -83,7 +83,7 @@ NS_IMETHODIMP_(bool)
|
|||
HTMLLIElement::IsAttributeMapped(const nsAtom* aAttribute) const
|
||||
{
|
||||
static const MappedAttributeEntry attributes[] = {
|
||||
{ &nsGkAtoms::type },
|
||||
{ nsGkAtoms::type },
|
||||
{ nullptr },
|
||||
};
|
||||
|
||||
|
|
|
@ -235,7 +235,7 @@ HTMLLinkElement::CreateAndDispatchEvent(nsIDocument* aDoc,
|
|||
// doing the "right" thing costs virtually nothing here, even if it doesn't
|
||||
// make much sense.
|
||||
static Element::AttrValuesArray strings[] =
|
||||
{&nsGkAtoms::_empty, &nsGkAtoms::stylesheet, nullptr};
|
||||
{nsGkAtoms::_empty, nsGkAtoms::stylesheet, nullptr};
|
||||
|
||||
if (!nsContentUtils::HasNonEmptyAttr(this, kNameSpaceID_None,
|
||||
nsGkAtoms::rev) &&
|
||||
|
|
|
@ -62,7 +62,7 @@ HTMLPreElement::IsAttributeMapped(const nsAtom* aAttribute) const
|
|||
}
|
||||
|
||||
static const MappedAttributeEntry attributes[] = {
|
||||
{ &nsGkAtoms::wrap },
|
||||
{ nsGkAtoms::wrap },
|
||||
{ nullptr },
|
||||
};
|
||||
|
||||
|
|
|
@ -101,8 +101,8 @@ HTMLSharedElement::IsAttributeMapped(const nsAtom* aAttribute) const
|
|||
{
|
||||
if (mNodeInfo->Equals(nsGkAtoms::dir)) {
|
||||
static const MappedAttributeEntry attributes[] = {
|
||||
{ &nsGkAtoms::type },
|
||||
// { &nsGkAtoms::compact }, // XXX
|
||||
{ nsGkAtoms::type },
|
||||
// { nsGkAtoms::compact }, // XXX
|
||||
{ nullptr}
|
||||
};
|
||||
|
||||
|
|
|
@ -100,7 +100,7 @@ HTMLSharedListElement::IsAttributeMapped(const nsAtom* aAttribute) const
|
|||
if (mNodeInfo->Equals(nsGkAtoms::ol) ||
|
||||
mNodeInfo->Equals(nsGkAtoms::ul)) {
|
||||
static const MappedAttributeEntry attributes[] = {
|
||||
{ &nsGkAtoms::type },
|
||||
{ nsGkAtoms::type },
|
||||
{ nullptr }
|
||||
};
|
||||
|
||||
|
|
|
@ -68,7 +68,7 @@ NS_IMETHODIMP_(bool)
|
|||
HTMLTableCaptionElement::IsAttributeMapped(const nsAtom* aAttribute) const
|
||||
{
|
||||
static const MappedAttributeEntry attributes[] = {
|
||||
{ &nsGkAtoms::align },
|
||||
{ nsGkAtoms::align },
|
||||
{ nullptr }
|
||||
};
|
||||
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче