From 1a54f050752b82183b6ff862c1ce27157040de84 Mon Sep 17 00:00:00 2001 From: Peter Xiao Date: Thu, 15 Aug 2013 17:18:07 -0700 Subject: [PATCH] Play earcon on empty or whitespace rows. Add support for selection. --- lib/ace/ext/chromevox.js | 41 ++++++++++++++++++++++++++++++++-------- 1 file changed, 33 insertions(+), 8 deletions(-) diff --git a/lib/ace/ext/chromevox.js b/lib/ace/ext/chromevox.js index b7632123..055a96dd 100644 --- a/lib/ace/ext/chromevox.js +++ b/lib/ace/ext/chromevox.js @@ -381,6 +381,17 @@ var mergeLikeTokens = function(tokens) { return newTokens; }; +/** + * Returns if given row is a whitespace row. + * @param {number} row Row. + * @return {boolean} True if row is whitespaces. + */ +var isRowWhiteSpace = function(row) { + var line = cvoxAce.editor.getSession().getLine(row); + var whiteSpaceRegexp = /^\s*$/; + return whiteSpaceRegexp.exec(line) !== null; +}; + /** * Speak the line with syntax properties. * @param {number} row Row to speak. @@ -388,7 +399,8 @@ var mergeLikeTokens = function(tokens) { */ var speakLine = function(row, queue) { var tokens = cvoxAce.editor.getSession().getTokens(row); - if (tokens.length === 0) { + if (tokens.length === 0 || isRowWhiteSpace(row)) { + cvox.Api.playEarcon('EDITABLE_TEXT'); return; } tokens = mergeLikeTokens(tokens); @@ -480,10 +492,7 @@ var speakDisplacement = function(lastCursor, currCursor) { /* Get the text that we jumped past. */ var displace = line.substring(lastCursor.column, currCursor.column); - /* When going forward one space, we speak where we land instead. */ - if (currCursor.column - lastCursor.column === 1) { - displace = line.substring(lastCursor.column + 1, currCursor.column + 1); - } + /* Speak out loud spaces. */ displace = displace.replace(/ /g, ' space '); cvox.Api.speak(displace, 1); @@ -522,7 +531,11 @@ var speakCharOrWordOrLine = function(lastCursor, currCursor) { * @param {!cvoxAce.Cursor} currCursor Current cursor position. */ var onColumnChange = function(lastCursor, currCursor) { - if (shouldSpeakDisplacement) { + if (!cvoxAce.editor.selection.isEmpty()) { + speakDisplacement(lastCursor, currCursor); + cvox.Api.speak('selected', 1); + } + else if (shouldSpeakDisplacement) { speakDisplacement(lastCursor, currCursor); } else { speakCharOrWordOrLine(lastCursor, currCursor); @@ -550,6 +563,17 @@ var onCursorChange = function(evt) { lastCursor = currCursor; }; +/** + * Event handler for selection changes. + * @param {!Event} evt The event. + */ +var onSelectionChange = function(evt) { + /* Assumes that when selection changes to empty, the user has unselected. */ + if (cvoxAce.editor.selection.isEmpty()) { + cvox.Api.speak('unselected'); + } +}; + /** * Event handler for source changes. We want auditory feedback for inserting * and deleting text. @@ -695,9 +719,9 @@ var toggleSpeakRowLocation = function() { * Toggle speak displacement. */ var toggleSpeakDisplacement = function() { - speakDisplacement = !speakDisplacement; + shouldSpeakDisplacement = !shouldSpeakDisplacement; /* Auditory feedback of the change. */ - if (speakDisplacement) { + if (shouldSpeakDisplacement) { cvox.Api.speak('Speak displacement on column changes.'); } else { cvox.Api.speak('Speak current character or word on column changes.'); @@ -874,6 +898,7 @@ var onFocus = function() { /* Set up listeners. */ editor.getSession().selection.on('changeCursor', onCursorChange); + editor.getSession().selection.on('changeSelection', onSelectionChange); editor.getSession().on('change', onChange); editor.getSession().on('changeAnnotation', onAnnotationChange); editor.on('changeStatus', onChangeStatus);