add editor accessibility
This commit is contained in:
parent
ea2ed435ba
commit
57f39d5a64
7 changed files with 99 additions and 16 deletions
|
@ -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';
|
||||||
|
|
|
@ -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
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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;
|
|
@ -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,
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,4 +41,4 @@ module.exports = {
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue