add editor accessibility

This commit is contained in:
MathuraMG 2016-08-11 13:24:02 -04:00
parent ea2ed435ba
commit 57f39d5a64
7 changed files with 99 additions and 16 deletions

View file

@ -43,8 +43,10 @@ export const CONSOLE_EVENT = 'CONSOLE_EVENT';
export const EXPAND_CONSOLE = 'EXPAND_CONSOLE'; export const EXPAND_CONSOLE = 'EXPAND_CONSOLE';
export const COLLAPSE_CONSOLE = 'COLLAPSE_CONSOLE'; export const COLLAPSE_CONSOLE = 'COLLAPSE_CONSOLE';
export const TOGGLE_BEEP = 'TOGGLE_BEEP'; export const TOGGLE_BEEP = 'TOGGLE_BEEP';
export const UPDATE_LINTMESSAGE = 'UPDATE_LINTMESSAGE';
export const CLEAR_LINTMESSAGE = 'CLEAR_LINTMESSAGE';
export const UPDATE_LINENUMBER = 'UPDATE_LINENUMBER';
export const SHOW_FILE_OPTIONS = 'SHOW_FILE_OPTIONS'; export const SHOW_FILE_OPTIONS = 'SHOW_FILE_OPTIONS';
export const HIDE_FILE_OPTIONS = 'HIDE_FILE_OPTIONS'; export const HIDE_FILE_OPTIONS = 'HIDE_FILE_OPTIONS';

View file

@ -5,3 +5,25 @@ export function toggleBeep() {
type: ActionTypes.TOGGLE_BEEP type: ActionTypes.TOGGLE_BEEP
}; };
} }
export function updateLintMessage(severity, line, message) {
return {
type: ActionTypes.UPDATE_LINTMESSAGE,
severity,
line,
message
};
}
export function clearLintMessage() {
return {
type: ActionTypes.CLEAR_LINTMESSAGE
};
}
export function updateLineNumber(lineNo) {
return {
type: ActionTypes.UPDATE_LINENUMBER,
lineNo
};
}

View file

@ -36,15 +36,13 @@ class Editor extends React.Component {
keyMap: 'sublime', keyMap: 'sublime',
lint: { lint: {
onUpdateLinting: debounce(2000, (annotations) => { onUpdateLinting: debounce(2000, (annotations) => {
let isVisible = false; this.props.clearLintMessage();
document.getElementById('editor-lintmessages').innerHTML = '';
annotations.forEach((x) => { annotations.forEach((x) => {
if (x.from.line > -1) { if (x.from.line > -1) {
document.getElementById('editor-lintmessages').innerHTML += (x.severity + ' in line number ' + (x.from.line + 1) + ' : ' + x.message); // eslint-disable-line this.props.updateLintMessage(x.severity, (x.from.line + 1), x.message);
isVisible = true;
} }
}); });
if (isVisible && this.props.enableBeep) { if (this.props.lintMessages.length > 0 && this.props.enableBeep) {
this.beep.play(); this.beep.play();
} }
}) })
@ -55,7 +53,7 @@ class Editor extends React.Component {
this.props.updateFileContent(this.props.file.name, this._cm.getValue()); this.props.updateFileContent(this.props.file.name, this._cm.getValue());
})); }));
this._cm.on('keyup', () => { this._cm.on('keyup', () => {
document.getElementById('editor-linenumber').innerHTML = 'line ' + parseInt((this._cm.getCursor().line) + 1, 10); this.props.updateLineNumber(parseInt((this._cm.getCursor().line) + 1, 10));
}); });
// this._cm.on('change', () => { // eslint-disable-line // this._cm.on('change', () => { // eslint-disable-line
// // this.props.updateFileContent('sketch.js', this._cm.getValue()); // // this.props.updateFileContent('sketch.js', this._cm.getValue());
@ -68,8 +66,6 @@ class Editor extends React.Component {
} }
componentDidUpdate(prevProps) { componentDidUpdate(prevProps) {
const annotations = this._cm.state.lint.marked;
annotations.forEach(function (x) { console.log(x.__annotation.severity + ' in line number ' + (x.__annotation.from.line + 1) + ' : ' + x.__annotation.message); }); // eslint-disable-line
if (this.props.file.content !== prevProps.file.content && if (this.props.file.content !== prevProps.file.content &&
this.props.file.content !== this._cm.getValue()) { this.props.file.content !== this._cm.getValue()) {
this._cm.setValue(this.props.file.content); // eslint-disable-line no-underscore-dangle this._cm.setValue(this.props.file.content); // eslint-disable-line no-underscore-dangle
@ -110,6 +106,10 @@ class Editor extends React.Component {
Editor.propTypes = { Editor.propTypes = {
enableBeep: PropTypes.bool.isRequired, enableBeep: PropTypes.bool.isRequired,
lintMessages: PropTypes.array.isRequired,
updateLintMessage: PropTypes.func.isRequired,
clearLintMessage: PropTypes.func.isRequired,
updateLineNumber: PropTypes.func.isRequired,
indentationAmount: PropTypes.number.isRequired, indentationAmount: PropTypes.number.isRequired,
isTabIndent: PropTypes.bool.isRequired, isTabIndent: PropTypes.bool.isRequired,
updateFileContent: PropTypes.func.isRequired, updateFileContent: PropTypes.func.isRequired,

View file

@ -0,0 +1,36 @@
import React, { PropTypes } from 'react';
class EditorHidden extends React.Component {
componentDidMount() {
}
render() {
let messages = [];
for (let i = 0; i < this.props.lintMessages.length; i++) {
messages.push(
<li>
{this.props.lintMessages[i].severity} in line
{this.props.lintMessages[i].line} :
{this.props.lintMessages[i].message}
</li>
);
}
return (
<div>
<p className="editor-linenumber" aria-live="assertive" id="editor-linenumber">line - {this.props.lineNo}</p>
<ul className="editor-lintmessages" id="editor-lintmessages" title="lint messages">
{messages}
</ul>
<button className="editor-lintbutton" onClick={this.props.toggleBeep}>Beep</button>
</div>
);
}
}
EditorHidden.propTypes = {
toggleBeep: PropTypes.func.isRequired,
lintMessages: PropTypes.array.isRequired,
lineNo: PropTypes.number.isRequired,
};
export default EditorHidden;

View file

@ -1,5 +1,6 @@
import React, { PropTypes } from 'react'; import React, { PropTypes } from 'react';
import Editor from '../components/Editor'; import Editor from '../components/Editor';
import EditorHidden from '../components/EditorHidden';
import Sidebar from '../components/Sidebar'; import Sidebar from '../components/Sidebar';
import PreviewFrame from '../components/PreviewFrame'; import PreviewFrame from '../components/PreviewFrame';
import Toolbar from '../components/Toolbar'; import Toolbar from '../components/Toolbar';
@ -103,11 +104,17 @@ class IDEView extends React.Component {
updateFileName={this.props.updateFileName} updateFileName={this.props.updateFileName}
/> />
<div className="editor-console-container"> <div className="editor-console-container">
<div className="editor-linenumber" aria-live="assertive" id="editor-linenumber"></div> <EditorHidden
<div className="editor-lintmessages" id="editor-lintmessages"></div> toggleBeep={this.props.toggleBeep}
<button className="editor-lintbutton" onClick={this.props.toggleBeep}>Beep</button> lintMessages={this.props.editorHidden.lintMessages}
lineNo={this.props.editorHidden.lineNo}
/>
<Editor <Editor
enableBeep={this.props.editorHidden.enableBeep} enableBeep={this.props.editorHidden.enableBeep}
lintMessages={this.props.editorHidden.lintMessages}
updateLineNumber={this.props.updateLineNumber}
updateLintMessage={this.props.updateLintMessage}
clearLintMessage={this.props.clearLintMessage}
file={this.props.selectedFile} file={this.props.selectedFile}
updateFileContent={this.props.updateFileContent} updateFileContent={this.props.updateFileContent}
fontSize={this.props.preferences.fontSize} fontSize={this.props.preferences.fontSize}
@ -185,9 +192,14 @@ IDEView.propTypes = {
setProjectName: PropTypes.func.isRequired, setProjectName: PropTypes.func.isRequired,
openPreferences: PropTypes.func.isRequired, openPreferences: PropTypes.func.isRequired,
editorHidden: PropTypes.shape({ editorHidden: PropTypes.shape({
enableBeep: PropTypes.bool.isRequired enableBeep: PropTypes.bool.isRequired,
lintMessages: PropTypes.array.isRequired,
lineNo: PropTypes.number.isRequired
}).isRequired, }).isRequired,
toggleBeep: PropTypes.func.isRequired, toggleBeep: PropTypes.func.isRequired,
updateLintMessage: PropTypes.func.isRequired,
clearLintMessage: PropTypes.func.isRequired,
updateLineNumber: PropTypes.func.isRequired,
preferences: PropTypes.shape({ preferences: PropTypes.shape({
fontSize: PropTypes.number.isRequired, fontSize: PropTypes.number.isRequired,
indentationAmount: PropTypes.number.isRequired, indentationAmount: PropTypes.number.isRequired,

View file

@ -1,13 +1,24 @@
import * as ActionTypes from '../../../constants'; import * as ActionTypes from '../../../constants';
const initialState = { const initialState = {
enableBeep: false enableBeep: false,
lineNo: 0,
lintMessages: []
}; };
const editorHidden = (state = initialState, action) => { const editorHidden = (state = initialState, action) => {
switch (action.type) { switch (action.type) {
case ActionTypes.TOGGLE_BEEP: case ActionTypes.TOGGLE_BEEP:
return Object.assign({}, state, { enableBeep: !state.enableBeep }); return Object.assign({}, state, { enableBeep: !state.enableBeep });
case ActionTypes.UPDATE_LINTMESSAGE:
return Object.assign({}, state, {
lintMessages: state.lintMessages.concat(
{ severity: action.severity, line: action.line, message: action.message })
});
case ActionTypes.CLEAR_LINTMESSAGE:
return Object.assign({}, state, { lintMessages: [] });
case ActionTypes.UPDATE_LINENUMBER:
return Object.assign({}, state, { lineNo: action.lineNo });
default: default:
return state; return state;
} }

View file

@ -41,4 +41,4 @@ module.exports = {
} }
], ],
}, },
}; };