Backed out 2 changesets (bug 1590493, bug 1592300) for causing ES Lint failure in test_accessible_row_context_menu.html CLOSED TREE
Backed out changeset 1a5752d4bceb (bug 1592300) Backed out changeset 51eac37a4bbf (bug 1590493)
This commit is contained in:
@@ -47,12 +47,29 @@ class AccessibilityStartup {
|
|||||||
try {
|
try {
|
||||||
this._walker = await this._accessibility.getWalker();
|
this._walker = await this._accessibility.getWalker();
|
||||||
this._supports = {};
|
this._supports = {};
|
||||||
[this._supports.simulation] = await Promise.all([
|
// Only works with FF61+ targets
|
||||||
// Added in Firefox 70.
|
this._supports.enableDisable = await this.target.actorHasMethod(
|
||||||
this.target.actorHasMethod("accessibility", "getSimulator"),
|
"accessibility",
|
||||||
]);
|
"enable"
|
||||||
|
);
|
||||||
|
|
||||||
await this._accessibility.bootstrap();
|
if (this._supports.enableDisable) {
|
||||||
|
[
|
||||||
|
this._supports.relations,
|
||||||
|
this._supports.snapshot,
|
||||||
|
this._supports.audit,
|
||||||
|
this._supports.hydration,
|
||||||
|
this._supports.simulation,
|
||||||
|
] = await Promise.all([
|
||||||
|
this.target.actorHasMethod("accessible", "getRelations"),
|
||||||
|
this.target.actorHasMethod("accessible", "snapshot"),
|
||||||
|
this.target.actorHasMethod("accessible", "audit"),
|
||||||
|
this.target.actorHasMethod("accessible", "hydrate"),
|
||||||
|
this.target.actorHasMethod("accessibility", "getSimulator"),
|
||||||
|
]);
|
||||||
|
|
||||||
|
await this._accessibility.bootstrap();
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|||||||
@@ -17,6 +17,9 @@ const { Provider } = require("devtools/client/shared/vendor/react-redux");
|
|||||||
|
|
||||||
// Accessibility Panel
|
// Accessibility Panel
|
||||||
const MainFrame = createFactory(require("./components/MainFrame"));
|
const MainFrame = createFactory(require("./components/MainFrame"));
|
||||||
|
const OldVersionDescription = createFactory(
|
||||||
|
require("./components/Description").OldVersionDescription
|
||||||
|
);
|
||||||
|
|
||||||
// Store
|
// Store
|
||||||
const createStore = require("devtools/client/shared/redux/create-store");
|
const createStore = require("devtools/client/shared/redux/create-store");
|
||||||
@@ -62,8 +65,8 @@ AccessibilityView.prototype = {
|
|||||||
* - simulator {Object}
|
* - simulator {Object}
|
||||||
* front for simulator actor responsible for setting
|
* front for simulator actor responsible for setting
|
||||||
* color matrices in docShell
|
* color matrices in docShell
|
||||||
* - toolbox {Object}
|
* - toolboxDoc {Document}
|
||||||
* devtools toolbox.
|
* toolbox document that will used by menus.
|
||||||
*/
|
*/
|
||||||
async initialize({
|
async initialize({
|
||||||
front,
|
front,
|
||||||
@@ -71,17 +74,23 @@ AccessibilityView.prototype = {
|
|||||||
supports,
|
supports,
|
||||||
fluentBundles,
|
fluentBundles,
|
||||||
simulator,
|
simulator,
|
||||||
toolbox,
|
toolboxDoc,
|
||||||
}) {
|
}) {
|
||||||
// Make sure state is reset every time accessibility panel is initialized.
|
// Make sure state is reset every time accessibility panel is initialized.
|
||||||
await this.store.dispatch(reset(front, supports));
|
await this.store.dispatch(reset(front, supports));
|
||||||
const container = document.getElementById("content");
|
const container = document.getElementById("content");
|
||||||
|
|
||||||
|
if (!supports.enableDisable) {
|
||||||
|
ReactDOM.render(OldVersionDescription(), container);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const mainFrame = MainFrame({
|
const mainFrame = MainFrame({
|
||||||
accessibility: front,
|
accessibility: front,
|
||||||
accessibilityWalker: walker,
|
accessibilityWalker: walker,
|
||||||
fluentBundles,
|
fluentBundles,
|
||||||
simulator,
|
simulator,
|
||||||
toolbox,
|
toolboxDoc,
|
||||||
});
|
});
|
||||||
// Render top level component
|
// Render top level component
|
||||||
const provider = createElement(Provider, { store: this.store }, mainFrame);
|
const provider = createElement(Provider, { store: this.store }, mainFrame);
|
||||||
@@ -98,9 +107,9 @@ AccessibilityView.prototype = {
|
|||||||
window.emit(EVENTS.NEW_ACCESSIBLE_FRONT_HIGHLIGHTED);
|
window.emit(EVENTS.NEW_ACCESSIBLE_FRONT_HIGHLIGHTED);
|
||||||
},
|
},
|
||||||
|
|
||||||
async selectNodeAccessible(walker, node) {
|
async selectNodeAccessible(walker, node, supports) {
|
||||||
let accessible = await walker.getAccessibleFor(node);
|
let accessible = await walker.getAccessibleFor(node);
|
||||||
if (accessible) {
|
if (accessible && supports.hydration) {
|
||||||
await accessible.hydrate();
|
await accessible.hydrate();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -115,7 +124,7 @@ AccessibilityView.prototype = {
|
|||||||
accessible = await walker.getAccessibleFor(child);
|
accessible = await walker.getAccessibleFor(child);
|
||||||
// indexInParent property is only available with additional request
|
// indexInParent property is only available with additional request
|
||||||
// for data (hydration) about the accessible object.
|
// for data (hydration) about the accessible object.
|
||||||
if (accessible) {
|
if (accessible && supports.hydration) {
|
||||||
await accessible.hydrate();
|
await accessible.hydrate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,16 +10,17 @@ const { UPDATE_DETAILS } = require("../constants");
|
|||||||
*
|
*
|
||||||
* @param {Object} dom walker front
|
* @param {Object} dom walker front
|
||||||
* @param {Object} accessible front
|
* @param {Object} accessible front
|
||||||
|
* @param {Object} list of supported serverside features.
|
||||||
*/
|
*/
|
||||||
exports.updateDetails = (domWalker, accessible) => dispatch =>
|
exports.updateDetails = (domWalker, accessible, supports) => dispatch =>
|
||||||
Promise.all([
|
Promise.all([
|
||||||
domWalker.getNodeFromActor(accessible.actorID, [
|
domWalker.getNodeFromActor(accessible.actorID, [
|
||||||
"rawAccessible",
|
"rawAccessible",
|
||||||
"DOMNode",
|
"DOMNode",
|
||||||
]),
|
]),
|
||||||
accessible.getRelations(),
|
supports.relations ? accessible.getRelations() : [],
|
||||||
accessible.audit(),
|
supports.audit ? accessible.audit() : {},
|
||||||
accessible.hydrate(),
|
supports.hydration ? accessible.hydrate() : null,
|
||||||
])
|
])
|
||||||
.then(response => dispatch({ accessible, type: UPDATE_DETAILS, response }))
|
.then(response => dispatch({ accessible, type: UPDATE_DETAILS, response }))
|
||||||
.catch(error => dispatch({ accessible, type: UPDATE_DETAILS, error }));
|
.catch(error => dispatch({ accessible, type: UPDATE_DETAILS, error }));
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
/* global gTelemetry, EVENTS */
|
/* global gTelemetry, gToolbox, EVENTS */
|
||||||
|
|
||||||
// React & Redux
|
// React & Redux
|
||||||
const {
|
const {
|
||||||
@@ -80,9 +80,10 @@ class AccessibilityRow extends Component {
|
|||||||
static get propTypes() {
|
static get propTypes() {
|
||||||
return {
|
return {
|
||||||
...TreeRow.propTypes,
|
...TreeRow.propTypes,
|
||||||
|
hasContextMenu: PropTypes.bool.isRequired,
|
||||||
dispatch: PropTypes.func.isRequired,
|
dispatch: PropTypes.func.isRequired,
|
||||||
toolboxDoc: PropTypes.object.isRequired,
|
|
||||||
scrollContentNodeIntoView: PropTypes.bool.isRequired,
|
scrollContentNodeIntoView: PropTypes.bool.isRequired,
|
||||||
|
supports: PropTypes.object,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -150,13 +151,14 @@ class AccessibilityRow extends Component {
|
|||||||
const {
|
const {
|
||||||
dispatch,
|
dispatch,
|
||||||
member: { object },
|
member: { object },
|
||||||
|
supports,
|
||||||
} = this.props;
|
} = this.props;
|
||||||
if (!object.actorID) {
|
if (!object.actorID) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const domWalker = (await object.targetFront.getFront("inspector")).walker;
|
const domWalker = (await object.targetFront.getFront("inspector")).walker;
|
||||||
dispatch(updateDetails(domWalker, object));
|
dispatch(updateDetails(domWalker, object, supports));
|
||||||
window.emit(EVENTS.NEW_ACCESSIBLE_FRONT_SELECTED, object);
|
window.emit(EVENTS.NEW_ACCESSIBLE_FRONT_SELECTED, object);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -251,6 +253,12 @@ class AccessibilityRow extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async printToJSON() {
|
async printToJSON() {
|
||||||
|
const { member, supports } = this.props;
|
||||||
|
if (!supports.snapshot) {
|
||||||
|
// Debugger server does not support Accessible actor snapshots.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (gTelemetry) {
|
if (gTelemetry) {
|
||||||
gTelemetry.keyedScalarAdd(
|
gTelemetry.keyedScalarAdd(
|
||||||
TELEMETRY_ACCESSIBLE_CONTEXT_MENU_ITEM_ACTIVATED,
|
TELEMETRY_ACCESSIBLE_CONTEXT_MENU_ITEM_ACTIVATED,
|
||||||
@@ -259,7 +267,7 @@ class AccessibilityRow extends Component {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const snapshot = await this.props.member.object.snapshot();
|
const snapshot = await member.object.snapshot();
|
||||||
openDocLink(
|
openDocLink(
|
||||||
`${JSON_URL_PREFIX}${encodeURIComponent(JSON.stringify(snapshot))}`
|
`${JSON_URL_PREFIX}${encodeURIComponent(JSON.stringify(snapshot))}`
|
||||||
);
|
);
|
||||||
@@ -269,20 +277,24 @@ class AccessibilityRow extends Component {
|
|||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
if (!this.props.toolboxDoc) {
|
if (!gToolbox) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const menu = new Menu({ id: "accessibility-row-contextmenu" });
|
const menu = new Menu({ id: "accessibility-row-contextmenu" });
|
||||||
menu.append(
|
const { supports } = this.props;
|
||||||
new MenuItem({
|
|
||||||
id: "menu-printtojson",
|
|
||||||
label: L10N.getStr("accessibility.tree.menu.printToJSON"),
|
|
||||||
click: () => this.printToJSON(),
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
menu.popup(e.screenX, e.screenY, this.props.toolboxDoc);
|
if (supports.snapshot) {
|
||||||
|
menu.append(
|
||||||
|
new MenuItem({
|
||||||
|
id: "menu-printtojson",
|
||||||
|
label: L10N.getStr("accessibility.tree.menu.printToJSON"),
|
||||||
|
click: () => this.printToJSON(),
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
menu.popup(e.screenX, e.screenY, gToolbox.doc);
|
||||||
|
|
||||||
if (gTelemetry) {
|
if (gTelemetry) {
|
||||||
gTelemetry.scalarAdd(TELEMETRY_ACCESSIBLE_CONTEXT_MENU_OPENED, 1);
|
gTelemetry.scalarAdd(TELEMETRY_ACCESSIBLE_CONTEXT_MENU_OPENED, 1);
|
||||||
@@ -297,7 +309,7 @@ class AccessibilityRow extends Component {
|
|||||||
const { member } = this.props;
|
const { member } = this.props;
|
||||||
const props = {
|
const props = {
|
||||||
...this.props,
|
...this.props,
|
||||||
onContextMenu: e => this.onContextMenu(e),
|
onContextMenu: this.props.hasContextMenu && (e => this.onContextMenu(e)),
|
||||||
onMouseOver: () => this.highlight(member.object),
|
onMouseOver: () => this.highlight(member.object),
|
||||||
onMouseOut: () => this.unhighlight(member.object),
|
onMouseOut: () => this.unhighlight(member.object),
|
||||||
key: `${member.path}-${member.active ? "active" : "inactive"}`,
|
key: `${member.path}-${member.active ? "active" : "inactive"}`,
|
||||||
@@ -313,8 +325,9 @@ class AccessibilityRow extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const mapStateToProps = ({
|
const mapStateToProps = ({
|
||||||
ui: { [PREFS.SCROLL_INTO_VIEW]: scrollContentNodeIntoView },
|
ui: { supports, [PREFS.SCROLL_INTO_VIEW]: scrollContentNodeIntoView },
|
||||||
}) => ({
|
}) => ({
|
||||||
|
supports,
|
||||||
scrollContentNodeIntoView,
|
scrollContentNodeIntoView,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ const {
|
|||||||
const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
|
const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
|
||||||
const { span } = require("devtools/client/shared/vendor/react-dom-factories");
|
const { span } = require("devtools/client/shared/vendor/react-dom-factories");
|
||||||
|
|
||||||
|
const { connect } = require("devtools/client/shared/vendor/react-redux");
|
||||||
|
|
||||||
const Badges = createFactory(require("./Badges"));
|
const Badges = createFactory(require("./Badges"));
|
||||||
const AuditController = createFactory(require("./AuditController"));
|
const AuditController = createFactory(require("./AuditController"));
|
||||||
|
|
||||||
@@ -24,10 +26,16 @@ class AccessibilityRowValue extends Component {
|
|||||||
member: PropTypes.shape({
|
member: PropTypes.shape({
|
||||||
object: PropTypes.object,
|
object: PropTypes.object,
|
||||||
}).isRequired,
|
}).isRequired,
|
||||||
|
supports: PropTypes.object.isRequired,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
const {
|
||||||
|
member,
|
||||||
|
supports: { audit },
|
||||||
|
} = this.props;
|
||||||
|
|
||||||
return span(
|
return span(
|
||||||
{
|
{
|
||||||
role: "presentation",
|
role: "presentation",
|
||||||
@@ -37,14 +45,19 @@ class AccessibilityRowValue extends Component {
|
|||||||
defaultRep: Grip,
|
defaultRep: Grip,
|
||||||
cropLimit: 50,
|
cropLimit: 50,
|
||||||
}),
|
}),
|
||||||
AuditController(
|
audit &&
|
||||||
{
|
AuditController(
|
||||||
accessibleFront: this.props.member.object,
|
{
|
||||||
},
|
accessibleFront: member.object,
|
||||||
Badges()
|
},
|
||||||
)
|
Badges()
|
||||||
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = AccessibilityRowValue;
|
const mapStateToProps = ({ ui: { supports } }) => {
|
||||||
|
return { supports };
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = connect(mapStateToProps)(AccessibilityRowValue);
|
||||||
|
|||||||
@@ -36,12 +36,12 @@ class AccessibilityTree extends Component {
|
|||||||
static get propTypes() {
|
static get propTypes() {
|
||||||
return {
|
return {
|
||||||
accessibilityWalker: PropTypes.object,
|
accessibilityWalker: PropTypes.object,
|
||||||
toolboxDoc: PropTypes.object.isRequired,
|
|
||||||
dispatch: PropTypes.func.isRequired,
|
dispatch: PropTypes.func.isRequired,
|
||||||
accessibles: PropTypes.object,
|
accessibles: PropTypes.object,
|
||||||
expanded: PropTypes.object,
|
expanded: PropTypes.object,
|
||||||
selected: PropTypes.string,
|
selected: PropTypes.string,
|
||||||
highlighted: PropTypes.object,
|
highlighted: PropTypes.object,
|
||||||
|
supports: PropTypes.object,
|
||||||
filtered: PropTypes.bool,
|
filtered: PropTypes.bool,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -167,17 +167,21 @@ class AccessibilityTree extends Component {
|
|||||||
expanded,
|
expanded,
|
||||||
selected,
|
selected,
|
||||||
highlighted: highlightedItem,
|
highlighted: highlightedItem,
|
||||||
|
supports,
|
||||||
accessibilityWalker,
|
accessibilityWalker,
|
||||||
toolboxDoc,
|
|
||||||
filtered,
|
filtered,
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
|
// Historically, the first context menu item is snapshot function and it is available
|
||||||
|
// for all accessible object.
|
||||||
|
const hasContextMenu = supports.snapshot;
|
||||||
|
|
||||||
const renderRow = rowProps => {
|
const renderRow = rowProps => {
|
||||||
const { object } = rowProps.member;
|
const { object } = rowProps.member;
|
||||||
const highlighted = object === highlightedItem;
|
const highlighted = object === highlightedItem;
|
||||||
return AccessibilityRow(
|
return AccessibilityRow(
|
||||||
Object.assign({}, rowProps, {
|
Object.assign({}, rowProps, {
|
||||||
toolboxDoc,
|
hasContextMenu,
|
||||||
highlighted,
|
highlighted,
|
||||||
decorator: {
|
decorator: {
|
||||||
getRowClass: function() {
|
getRowClass: function() {
|
||||||
@@ -213,29 +217,32 @@ class AccessibilityTree extends Component {
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
onContextMenuTree: function(e) {
|
onContextMenuTree:
|
||||||
// If context menu event is triggered on (or bubbled to) the TreeView, it was
|
hasContextMenu &&
|
||||||
// done via keyboard. Open context menu for currently selected row.
|
function(e) {
|
||||||
let row = this.getSelectedRow();
|
// If context menu event is triggered on (or bubbled to) the TreeView, it was
|
||||||
if (!row) {
|
// done via keyboard. Open context menu for currently selected row.
|
||||||
return;
|
let row = this.getSelectedRow();
|
||||||
}
|
if (!row) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
row = row.getWrappedInstance();
|
row = row.getWrappedInstance();
|
||||||
row.onContextMenu(e);
|
row.onContextMenu(e);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const mapStateToProps = ({
|
const mapStateToProps = ({
|
||||||
accessibles,
|
accessibles,
|
||||||
ui: { expanded, selected, highlighted },
|
ui: { expanded, selected, supports, highlighted },
|
||||||
audit: { filters },
|
audit: { filters },
|
||||||
}) => ({
|
}) => ({
|
||||||
accessibles,
|
accessibles,
|
||||||
expanded,
|
expanded,
|
||||||
selected,
|
selected,
|
||||||
|
supports,
|
||||||
highlighted,
|
highlighted,
|
||||||
filtered: isFiltered(filters),
|
filtered: isFiltered(filters),
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
/* global EVENTS, gTelemetry */
|
/* global EVENTS, gTelemetry, gToolbox */
|
||||||
|
|
||||||
// React & Redux
|
// React & Redux
|
||||||
const {
|
const {
|
||||||
@@ -112,7 +112,7 @@ class Accessible extends Component {
|
|||||||
labelledby: PropTypes.string.isRequired,
|
labelledby: PropTypes.string.isRequired,
|
||||||
parents: PropTypes.object,
|
parents: PropTypes.object,
|
||||||
relations: PropTypes.object,
|
relations: PropTypes.object,
|
||||||
toolbox: PropTypes.object.isRequired,
|
supports: PropTypes.object,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -181,7 +181,7 @@ class Accessible extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async update() {
|
async update() {
|
||||||
const { dispatch, accessibleFront } = this.props;
|
const { dispatch, accessibleFront, supports } = this.props;
|
||||||
if (!accessibleFront.actorID) {
|
if (!accessibleFront.actorID) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -189,7 +189,7 @@ class Accessible extends Component {
|
|||||||
const domWalker = (await accessibleFront.targetFront.getFront("inspector"))
|
const domWalker = (await accessibleFront.targetFront.getFront("inspector"))
|
||||||
.walker;
|
.walker;
|
||||||
|
|
||||||
dispatch(updateDetails(domWalker, accessibleFront));
|
dispatch(updateDetails(domWalker, accessibleFront, supports));
|
||||||
}
|
}
|
||||||
|
|
||||||
setExpanded(item, isExpanded) {
|
setExpanded(item, isExpanded) {
|
||||||
@@ -205,7 +205,7 @@ class Accessible extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async showHighlighter(nodeFront) {
|
async showHighlighter(nodeFront) {
|
||||||
if (!this.props.toolbox) {
|
if (!gToolbox) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -214,7 +214,7 @@ class Accessible extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async hideHighlighter(nodeFront) {
|
async hideHighlighter(nodeFront) {
|
||||||
if (!this.props.toolbox) {
|
if (!gToolbox) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -238,7 +238,7 @@ class Accessible extends Component {
|
|||||||
.catch(error => {
|
.catch(error => {
|
||||||
// Only report an error where there's still a toolbox. Ignore cases
|
// Only report an error where there's still a toolbox. Ignore cases
|
||||||
// where toolbox is already destroyed.
|
// where toolbox is already destroyed.
|
||||||
if (this.props.toolbox) {
|
if (gToolbox) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -258,23 +258,24 @@ class Accessible extends Component {
|
|||||||
accessibilityWalkerFront.unhighlight().catch(error => {
|
accessibilityWalkerFront.unhighlight().catch(error => {
|
||||||
// Only report an error where there's still a toolbox. Ignore cases where
|
// Only report an error where there's still a toolbox. Ignore cases where
|
||||||
// toolbox is already destroyed.
|
// toolbox is already destroyed.
|
||||||
if (this.props.toolbox) {
|
if (gToolbox) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async selectNode(nodeFront, reason = "accessibility") {
|
selectNode(nodeFront, reason = "accessibility") {
|
||||||
if (gTelemetry) {
|
if (gTelemetry) {
|
||||||
gTelemetry.scalarAdd(TELEMETRY_NODE_INSPECTED_COUNT, 1);
|
gTelemetry.scalarAdd(TELEMETRY_NODE_INSPECTED_COUNT, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.props.toolbox) {
|
if (!gToolbox) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const inspector = await this.props.toolbox.selectTool("inspector");
|
gToolbox
|
||||||
inspector.selection.setNodeFront(nodeFront, reason);
|
.selectTool("inspector")
|
||||||
|
.then(() => gToolbox.selection.setNodeFront(nodeFront, reason));
|
||||||
}
|
}
|
||||||
|
|
||||||
async selectAccessible(accessibleFront) {
|
async selectAccessible(accessibleFront) {
|
||||||
@@ -539,12 +540,13 @@ const makeParentMap = items => {
|
|||||||
return map;
|
return map;
|
||||||
};
|
};
|
||||||
|
|
||||||
const mapStateToProps = ({ details }) => {
|
const mapStateToProps = ({ details, ui }) => {
|
||||||
const {
|
const {
|
||||||
accessible: accessibleFront,
|
accessible: accessibleFront,
|
||||||
DOMNode: nodeFront,
|
DOMNode: nodeFront,
|
||||||
relations,
|
relations,
|
||||||
} = details;
|
} = details;
|
||||||
|
const { supports } = ui;
|
||||||
if (!accessibleFront || !nodeFront) {
|
if (!accessibleFront || !nodeFront) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
@@ -554,7 +556,9 @@ const mapStateToProps = ({ details }) => {
|
|||||||
if (key === "DOMNode") {
|
if (key === "DOMNode") {
|
||||||
props.nodeFront = nodeFront;
|
props.nodeFront = nodeFront;
|
||||||
} else if (key === "relations") {
|
} else if (key === "relations") {
|
||||||
props.relations = relations;
|
if (supports.relations) {
|
||||||
|
props.relations = relations;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
props[key] = accessibleFront[key];
|
props[key] = accessibleFront[key];
|
||||||
}
|
}
|
||||||
@@ -565,7 +569,7 @@ const mapStateToProps = ({ details }) => {
|
|||||||
);
|
);
|
||||||
const parents = makeParentMap(items);
|
const parents = makeParentMap(items);
|
||||||
|
|
||||||
return { accessibleFront, nodeFront, items, parents, relations };
|
return { accessibleFront, nodeFront, items, parents, relations, supports };
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = connect(mapStateToProps)(Accessible);
|
module.exports = connect(mapStateToProps)(Accessible);
|
||||||
|
|||||||
@@ -93,6 +93,10 @@ class Checks extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const mapStateToProps = ({ details, ui }) => {
|
const mapStateToProps = ({ details, ui }) => {
|
||||||
|
if (!ui.supports.audit) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
const { audit } = details;
|
const { audit } = details;
|
||||||
if (!audit) {
|
if (!audit) {
|
||||||
return {};
|
return {};
|
||||||
|
|||||||
@@ -30,6 +30,22 @@ const {
|
|||||||
A11Y_SERVICE_ENABLED_COUNT,
|
A11Y_SERVICE_ENABLED_COUNT,
|
||||||
} = require("../constants");
|
} = require("../constants");
|
||||||
|
|
||||||
|
class OldVersionDescription extends Component {
|
||||||
|
render() {
|
||||||
|
return div(
|
||||||
|
{ className: "description" },
|
||||||
|
p(
|
||||||
|
{ className: "general" },
|
||||||
|
img({
|
||||||
|
src: "chrome://devtools/skin/images/accessibility.svg",
|
||||||
|
alt: L10N.getStr("accessibility.logo"),
|
||||||
|
}),
|
||||||
|
L10N.getStr("accessibility.description.oldVersion")
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Landing UI for the accessibility panel when Accessibility features are
|
* Landing UI for the accessibility panel when Accessibility features are
|
||||||
* deactivated.
|
* deactivated.
|
||||||
@@ -144,3 +160,4 @@ const mapStateToProps = ({ ui }) => ({
|
|||||||
|
|
||||||
// Exports from this module
|
// Exports from this module
|
||||||
exports.Description = connect(mapStateToProps)(Description);
|
exports.Description = connect(mapStateToProps)(Description);
|
||||||
|
exports.OldVersionDescription = OldVersionDescription;
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ class MainFrame extends Component {
|
|||||||
auditing: PropTypes.array.isRequired,
|
auditing: PropTypes.array.isRequired,
|
||||||
supports: PropTypes.object,
|
supports: PropTypes.object,
|
||||||
simulator: PropTypes.object,
|
simulator: PropTypes.object,
|
||||||
toolbox: PropTypes.object.isRequired,
|
toolboxDoc: PropTypes.object.isRequired,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -118,7 +118,7 @@ class MainFrame extends Component {
|
|||||||
enabled,
|
enabled,
|
||||||
auditing,
|
auditing,
|
||||||
simulator,
|
simulator,
|
||||||
toolbox,
|
toolboxDoc,
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
if (!enabled) {
|
if (!enabled) {
|
||||||
@@ -132,12 +132,7 @@ class MainFrame extends Component {
|
|||||||
{ bundles: fluentBundles },
|
{ bundles: fluentBundles },
|
||||||
div(
|
div(
|
||||||
{ className: "mainFrame", role: "presentation" },
|
{ className: "mainFrame", role: "presentation" },
|
||||||
Toolbar({
|
Toolbar({ accessibility, accessibilityWalker, simulator, toolboxDoc }),
|
||||||
accessibility,
|
|
||||||
accessibilityWalker,
|
|
||||||
simulator,
|
|
||||||
toolboxDoc: toolbox.doc,
|
|
||||||
}),
|
|
||||||
isAuditing && AuditProgressOverlay(),
|
isAuditing && AuditProgressOverlay(),
|
||||||
span(
|
span(
|
||||||
{
|
{
|
||||||
@@ -157,12 +152,9 @@ class MainFrame extends Component {
|
|||||||
className: "main-panel",
|
className: "main-panel",
|
||||||
role: "presentation",
|
role: "presentation",
|
||||||
},
|
},
|
||||||
AccessibilityTree({
|
AccessibilityTree({ accessibilityWalker })
|
||||||
accessibilityWalker,
|
|
||||||
toolboxDoc: toolbox.doc,
|
|
||||||
})
|
|
||||||
),
|
),
|
||||||
endPanel: RightSidebar({ toolbox }),
|
endPanel: RightSidebar(),
|
||||||
vert: this.useLandscapeMode,
|
vert: this.useLandscapeMode,
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ const Accordion = createFactory(
|
|||||||
const Checks = createFactory(require("./Checks"));
|
const Checks = createFactory(require("./Checks"));
|
||||||
|
|
||||||
// Component that is responsible for rendering accessible panel's sidebar.
|
// Component that is responsible for rendering accessible panel's sidebar.
|
||||||
function RightSidebar({ toolbox }) {
|
function RightSidebar() {
|
||||||
const propertiesID = "accessibility-properties";
|
const propertiesID = "accessibility-properties";
|
||||||
const checksID = "accessibility-checks";
|
const checksID = "accessibility-checks";
|
||||||
|
|
||||||
@@ -38,7 +38,6 @@ function RightSidebar({ toolbox }) {
|
|||||||
className: "accessible",
|
className: "accessible",
|
||||||
component: Accessible,
|
component: Accessible,
|
||||||
componentProps: {
|
componentProps: {
|
||||||
toolbox,
|
|
||||||
labelledby: `${propertiesID}-header`,
|
labelledby: `${propertiesID}-header`,
|
||||||
},
|
},
|
||||||
header: L10N.getStr("accessibility.properties"),
|
header: L10N.getStr("accessibility.properties"),
|
||||||
|
|||||||
@@ -86,10 +86,17 @@ AccessibilityPanel.prototype = {
|
|||||||
);
|
);
|
||||||
|
|
||||||
this.shouldRefresh = true;
|
this.shouldRefresh = true;
|
||||||
|
this.panelWin.gToolbox = this._toolbox;
|
||||||
|
|
||||||
await this.startup.initAccessibility();
|
await this.startup.initAccessibility();
|
||||||
this.picker = new Picker(this);
|
if (this.supports.enableDisable) {
|
||||||
this.simulator = await this.front.getSimulator();
|
this.picker = new Picker(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.supports.simulation) {
|
||||||
|
this.simulator = await this.front.getSimulator();
|
||||||
|
}
|
||||||
|
|
||||||
this.fluentBundles = await this.createFluentBundles();
|
this.fluentBundles = await this.createFluentBundles();
|
||||||
|
|
||||||
this.updateA11YServiceDurationTimer();
|
this.updateA11YServiceDurationTimer();
|
||||||
@@ -170,7 +177,7 @@ AccessibilityPanel.prototype = {
|
|||||||
supports: this.supports,
|
supports: this.supports,
|
||||||
fluentBundles: this.fluentBundles,
|
fluentBundles: this.fluentBundles,
|
||||||
simulator: this.simulator,
|
simulator: this.simulator,
|
||||||
toolbox: this._toolbox,
|
toolboxDoc: this._toolbox.doc,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -195,7 +202,12 @@ AccessibilityPanel.prototype = {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.postContentMessage("selectNodeAccessible", this.walker, nodeFront);
|
this.postContentMessage(
|
||||||
|
"selectNodeAccessible",
|
||||||
|
this.walker,
|
||||||
|
nodeFront,
|
||||||
|
this.supports
|
||||||
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
highlightAccessible(accessibleFront) {
|
highlightAccessible(accessibleFront) {
|
||||||
@@ -299,6 +311,7 @@ AccessibilityPanel.prototype = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this._telemetry = null;
|
this._telemetry = null;
|
||||||
|
this.panelWin.gToolbox = null;
|
||||||
this.panelWin.gTelemetry = null;
|
this.panelWin.gTelemetry = null;
|
||||||
|
|
||||||
this.emit("destroyed");
|
this.emit("destroyed");
|
||||||
|
|||||||
@@ -185,8 +185,10 @@ function onReset(state, { accessibility, supports }) {
|
|||||||
enabled,
|
enabled,
|
||||||
canBeDisabled,
|
canBeDisabled,
|
||||||
canBeEnabled,
|
canBeEnabled,
|
||||||
supports,
|
|
||||||
};
|
};
|
||||||
|
if (supports) {
|
||||||
|
newState.supports = supports;
|
||||||
|
}
|
||||||
|
|
||||||
return newState;
|
return newState;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -142,7 +142,7 @@ async function addTestTab(url) {
|
|||||||
|
|
||||||
// Wait for inspector load here to avoid protocol errors on shutdown, since
|
// Wait for inspector load here to avoid protocol errors on shutdown, since
|
||||||
// accessibility panel test can be too fast.
|
// accessibility panel test can be too fast.
|
||||||
await panel._toolbox.loadTool("inspector");
|
await win.gToolbox.loadTool("inspector");
|
||||||
|
|
||||||
return {
|
return {
|
||||||
tab,
|
tab,
|
||||||
|
|||||||
@@ -43,7 +43,9 @@ window.onload = async function() {
|
|||||||
off: () => {},
|
off: () => {},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
ui: { supports: {} }
|
ui: {
|
||||||
|
supports: {},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const mockStore = createStore((state, action) =>
|
const mockStore = createStore((state, action) =>
|
||||||
@@ -51,13 +53,28 @@ window.onload = async function() {
|
|||||||
const provider = createElement(Provider, { store: mockStore }, a);
|
const provider = createElement(Provider, { store: mockStore }, a);
|
||||||
const accessible = ReactDOM.render(provider, window.document.body);
|
const accessible = ReactDOM.render(provider, window.document.body);
|
||||||
ok(accessible, "Should be able to mount Accessible instances");
|
ok(accessible, "Should be able to mount Accessible instances");
|
||||||
|
|
||||||
|
info("Render accessible object when relations are not supported.");
|
||||||
let relationsNode = document.getElementById("/relations");
|
let relationsNode = document.getElementById("/relations");
|
||||||
|
ok(!relationsNode, "Relations are not rendered when not supported.");
|
||||||
|
|
||||||
|
info("Render accessible object when relations are supported but are empty.");
|
||||||
|
let state = {
|
||||||
|
...mockState,
|
||||||
|
ui: {
|
||||||
|
supports: {
|
||||||
|
relations: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
await mockStore.dispatch({ type: "update", ...state });
|
||||||
|
relationsNode = document.getElementById("/relations");
|
||||||
ok(relationsNode, "Relations are rendered when supported.");
|
ok(relationsNode, "Relations are rendered when supported.");
|
||||||
let arrow = relationsNode.querySelector(".arrow.theme-twisty");
|
let arrow = relationsNode.querySelector(".arrow.theme-twisty");
|
||||||
is(arrow.style.visibility, "hidden", "Relations are empty.");
|
is(arrow.style.visibility, "hidden", "Relations are empty.");
|
||||||
|
|
||||||
info("Render accessible object with relations.");
|
info("Render accessible object with relations.");
|
||||||
const state = {
|
state = {
|
||||||
details: {
|
details: {
|
||||||
...mockState.details,
|
...mockState.details,
|
||||||
relations: {
|
relations: {
|
||||||
@@ -69,6 +86,11 @@ window.onload = async function() {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
ui: {
|
||||||
|
supports: {
|
||||||
|
relations: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
await mockStore.dispatch({ type: "update", ...state });
|
await mockStore.dispatch({ type: "update", ...state });
|
||||||
relationsNode = document.getElementById("/relations");
|
relationsNode = document.getElementById("/relations");
|
||||||
|
|||||||
@@ -36,11 +36,13 @@ window.onload = async function() {
|
|||||||
const { FILTERS } = browserRequire("devtools/client/accessibility/constants");
|
const { FILTERS } = browserRequire("devtools/client/accessibility/constants");
|
||||||
|
|
||||||
async function withMockEnv(func) {
|
async function withMockEnv(func) {
|
||||||
const { gTelemetry: originalTelemetry } = window;
|
const { gToolbox: originalToolbox, gTelemetry: originalTelemetry } = window;
|
||||||
|
window.gToolbox = { doc: document };
|
||||||
window.gTelemetry = null;
|
window.gTelemetry = null;
|
||||||
|
|
||||||
await func();
|
await func();
|
||||||
|
|
||||||
|
window.gToolbox = originalToolbox;
|
||||||
window.gTelemetry = originalTelemetry;
|
window.gTelemetry = originalTelemetry;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,13 +88,21 @@ window.onload = async function() {
|
|||||||
getValue: (object, id) => object[id],
|
getValue: (object, id) => object[id],
|
||||||
},
|
},
|
||||||
hasContextMenu: true,
|
hasContextMenu: true,
|
||||||
toolboxDoc: document,
|
};
|
||||||
|
|
||||||
|
const mockProps = {
|
||||||
|
...defaultProps,
|
||||||
|
hasContextMenu: null,
|
||||||
};
|
};
|
||||||
|
|
||||||
const auditState = { audit: { filters: { [FILTERS.CONTRAST]: false }}};
|
const auditState = { audit: { filters: { [FILTERS.CONTRAST]: false }}};
|
||||||
|
|
||||||
const defaultState = {
|
const defaultState = {
|
||||||
ui: { supports: {} },
|
ui: { supports: { snapshot: true }},
|
||||||
|
...auditState,
|
||||||
|
};
|
||||||
|
const mockState = {
|
||||||
|
ui: { supports: {}},
|
||||||
...auditState,
|
...auditState,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -134,6 +144,23 @@ window.onload = async function() {
|
|||||||
browserWindow.openWebLinkIn = defaultOpenWebLinkIn;
|
browserWindow.openWebLinkIn = defaultOpenWebLinkIn;
|
||||||
menu.remove();
|
menu.remove();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
info("Check accessibility row when context menu is not supported.");
|
||||||
|
renderAccessibilityRow(defaultProps, mockState);
|
||||||
|
row = document.getElementById(ROW_ID);
|
||||||
|
|
||||||
|
info("Check contextmenu listener is not called when context menu is not supported.");
|
||||||
|
Simulate.contextMenu(row);
|
||||||
|
let menu = menuDoc.getElementById("accessibility-row-contextmenu");
|
||||||
|
ok(!menu, "contextmenu event handler was never called.");
|
||||||
|
|
||||||
|
info("Check accessibility row when no context menu is available.");
|
||||||
|
renderAccessibilityRow(mockProps, defaultState);
|
||||||
|
row = document.getElementById(ROW_ID);
|
||||||
|
|
||||||
|
Simulate.contextMenu(row);
|
||||||
|
menu = menuDoc.getElementById("accessibility-row-contextmenu");
|
||||||
|
ok(!menu, "contextmenu event handler was never called.");
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
ok(false, "Got an error: " + DevToolsUtils.safeErrorString(e));
|
ok(false, "Got an error: " + DevToolsUtils.safeErrorString(e));
|
||||||
} finally {
|
} finally {
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`AccessibilityRowValue component: audit not supported 1`] = `"<span role=\\"presentation\\"><span class=\\"objectBox objectBox-undefined\\">undefined</span></span>"`;
|
||||||
|
|
||||||
exports[`AccessibilityRowValue component: basic render 1`] = `"<span role=\\"presentation\\"><span class=\\"objectBox objectBox-undefined\\">undefined</span></span>"`;
|
exports[`AccessibilityRowValue component: basic render 1`] = `"<span role=\\"presentation\\"><span class=\\"objectBox objectBox-undefined\\">undefined</span></span>"`;
|
||||||
|
|||||||
@@ -21,11 +21,15 @@ const {
|
|||||||
} = require("devtools/client/shared/components/reps/reps");
|
} = require("devtools/client/shared/components/reps/reps");
|
||||||
const AuditController = require("devtools/client/accessibility/components/AuditController");
|
const AuditController = require("devtools/client/accessibility/components/AuditController");
|
||||||
|
|
||||||
const AccessibilityRowValueClass = require("devtools/client/accessibility/components/AccessibilityRowValue");
|
const ConnectedAccessibilityRowValueClass = require("devtools/client/accessibility/components/AccessibilityRowValue");
|
||||||
const AccessibilityRowValue = createFactory(AccessibilityRowValueClass);
|
const AccessibilityRowValueClass =
|
||||||
|
ConnectedAccessibilityRowValueClass.WrappedComponent;
|
||||||
|
const AccessibilityRowValue = createFactory(
|
||||||
|
ConnectedAccessibilityRowValueClass
|
||||||
|
);
|
||||||
|
|
||||||
describe("AccessibilityRowValue component:", () => {
|
describe("AccessibilityRowValue component:", () => {
|
||||||
it("basic render", () => {
|
it("audit not supported", () => {
|
||||||
const store = setupStore({
|
const store = setupStore({
|
||||||
preloadedState: { ui: { supports: {} } },
|
preloadedState: { ui: { supports: {} } },
|
||||||
});
|
});
|
||||||
@@ -38,6 +42,29 @@ describe("AccessibilityRowValue component:", () => {
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
expect(wrapper.html()).toMatchSnapshot();
|
||||||
|
const rowValue = wrapper.find(AccessibilityRowValueClass);
|
||||||
|
expect(rowValue.children().length).toBe(1);
|
||||||
|
const container = rowValue.childAt(0);
|
||||||
|
expect(container.type()).toBe("span");
|
||||||
|
expect(container.prop("role")).toBe("presentation");
|
||||||
|
expect(container.children().length).toBe(1);
|
||||||
|
expect(container.childAt(0).type()).toBe(Rep);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("basic render", () => {
|
||||||
|
const store = setupStore({
|
||||||
|
preloadedState: { ui: { supports: { audit: true } } },
|
||||||
|
});
|
||||||
|
const wrapper = mount(
|
||||||
|
Provider(
|
||||||
|
{ store },
|
||||||
|
AccessibilityRowValue({
|
||||||
|
member: { object: mockAccessible() },
|
||||||
|
})
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
expect(wrapper.html()).toMatchSnapshot();
|
expect(wrapper.html()).toMatchSnapshot();
|
||||||
const rowValue = wrapper.find(AccessibilityRowValueClass);
|
const rowValue = wrapper.find(AccessibilityRowValueClass);
|
||||||
expect(rowValue.children().length).toBe(1);
|
expect(rowValue.children().length).toBe(1);
|
||||||
|
|||||||
Reference in New Issue
Block a user